| Commit message (Collapse) | Author | Age | Files | Lines |
| |\
| |
| | |
SCOPE.txt discovery truth-up + exclude root .txt docs from CI
|
| | | |
|
| | |
| |
| |
| |
| |
| | |
Add *.txt to the Tests workflow paths-ignore so a ROADMAP/SCOPE/SECURITY
edit no longer burns a macOS runner. Single-star (root only), matching the
existing *.md rule; a doc edit alongside code still runs the suite.
|
| |/
|
|
|
|
| |
hub.sr.ht gained a public projects discovery query, now shipped as project
discovery (#12). Strike the 'no public discovery API' entry and fix the
mailingListSubscribe rationale (hub discovery lists projects, not lists).
|
| |\
| |
| | |
Bump to 3.9.0; reflect shipped work in roadmap
|
| |/
|
|
|
|
|
| |
Cut 3.9.0 (build 94), bundling this session's features. Update ROADMAP.txt:
mark hub.sr.ht project writes + discovery (#12-#15) done, correct the Q2
ingest note and App Intent gaps, and reconcile the release plan (3.9.0 is
the shipped cut; ingest/deploy keys move to 3.10.0).
|
| |\
| |
| | |
Projects: discovery, create, edit, manage linked resources (#12, #13, #14, #15)
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
hub.sr.ht's GraphQL now exposes the project write API (create/update/
link/unlink) and a public `projects` discovery query, so these
previously-blocked issues can be built.
ProjectService gains: fetchPublicProjects (#12); createProject (#13);
updateProject with ProjectInput (#14); link/unlink for sources, trackers,
and mailing lists plus linkable-resource candidate fetches (#15); and hub
cache invalidation after every mutation.
UI: a Discover browser and a create form reached from the projects list;
an Edit form and a Manage Resources sheet on project detail, gated to
projects the user owns. Mutations degrade to a visible error if a field
isn't live yet.
Built against the master schema; live deployment on sr.ht/query is not yet
confirmed (introspection there requires a token).
|
| |\
| |
| | |
Sync bundled man page catalog from man.sr.ht (#7)
|
| | |
| |
| |
| |
| | |
SonarCloud (githubactions:S7637) flags third-party actions referenced by
mutable tag as a supply-chain risk; pin to the v7 commit SHA.
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The More tab's official man-page list was a hardcoded array, updated by
hand. Move it to a checked-in Hutch/Resources/man-pages.json (bundled via
the synchronized group) loaded by a new ManPageCatalog, with the previous
list kept as a built-in fallback.
Add scripts/sync_man_pages.py, which re-derives the catalog from the
man.sr.ht landing page, and a weekly scheduled workflow that runs it and
opens a pull request when the list diverges upstream. The script refuses to
write a suspiciously short list so a markup change can't gut the catalog.
This first sync also picks up chat.sr.ht, which upstream added since the
list was last hand-edited. Tests cover catalog loading, the fallback, and
JSON decoding.
|
| |\
| |
| | |
Expand App Intents: dialogs, search type, mutating intents (#17)
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Addresses the three open items on the App Intents ticket:
- Check Status / Check Builds now return a spoken/visible dialog alongside
their value, so they surface a result in Siri instead of appearing to do
nothing. Logic consolidated to always produce a message.
- Search Hutch gains a Search Type parameter (user, git/hg repo, mailing
list, tracker, build job) threaded through the .search route into Lookup,
which pre-selects the type. LookupType now conforms to AppEnum.
- Adds mutating intents (not just navigation): Clear Recent Activity and
Unpin Resource, backed by RecentActivityStore.clear and a new
HomePinStore.removePin. Both act on the active account's storage.
Tests cover search-type routing, the blank-query fallback, and pin removal.
|
| |\
| |
| | |
Add multi-language syntax highlighting (#16)
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Splash (Swift-only, since removed) left code rendering unhighlighted
everywhere. Add Highlightr (highlight.js) behind a small SyntaxHighlighter
service and use it on both surfaces:
- Native file viewer: highlight NSAttributedString by language inferred
from the filename, picking a light/dark theme from the trait style and
re-highlighting on style changes. Falls back to plain text for unknown
languages or very large files.
- Markdown/org code blocks in the WKWebView (READMEs, tickets, comments):
the web view disables JavaScript, so highlight server-side into inline
color-styled spans. The color scheme is now part of the render/cache
key since colors are baked into the HTML.
Covered by unit tests for language mapping and highlighted output.
|
| |\
| |
| | |
Fix checklist rendering, add clear-recent-activity, speed up pull-to-refresh
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The inbox count paginates every thread of every subscribed list (~25s),
and .refreshable binds the spinner to loadDashboard returning, so pull
held for the whole time. Refresh the count in a cancellable background
task that updates the badge when it lands, so pull returns once the fast
branches settle. The widget / App Intents snapshot refresh, which builds
from a throwaway view model, opts back into awaiting inbox so its count
stays accurate.
|
| | |
| |
| |
| |
| |
| |
| | |
Add a Clear button in the Home Recent section header to drop all
entries, plus swipe-to-delete on each row to forget a single item
(gated on the existing swipe-actions setting). Back it with
RecentActivityStore.clear and remove(id:), with unit tests.
|
| | |
| |
| |
| |
| |
| |
| |
| | |
The .task-list-item CSS used display: inline-flex, which turned each
text run and inline <code> into separate rigid flex items so a bullet
mixing code with text rendered malformed instead of flowing inline.
The checkbox is already centered via vertical-align, so switch to plain
inline display and let the fragments flow and wrap naturally.
|
| |/
|
|
|
|
|
| |
The doc-format conversion renamed README.md->README.nfo and
SECURITY.md->SECURITY.txt but left the Xcode resource references
pointing at the old filenames, breaking the app build (Ld: SECURITY.md
no such file). Point the references at the renamed files.
|
| | |
|
| | |
|
| |
|
|
|
|
| |
- Point README badges and ROADMAP query at the krazywarez_hutch SonarCloud project
- Change user-facing contact emails to [email protected] (README, SECURITY, About screen)
- Bump MARKETING_VERSION to 3.8.5 and CURRENT_PROJECT_VERSION to 93
|
| |
|
|
| |
The 3.8.3 train is closed for new submissions on App Store Connect.
|
| | |
|
| | |
|
| |\
| |
| | |
Remove Splash syntax highlighter dependency
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
| |
Splash only highlights Swift, leaving every other language unhighlighted.
Drop the dependency entirely and render file contents as plain text until a
broader-coverage highlighter is adopted.
- Remove `import Splash` and the Splash-backed theming in FileTreeView
- Simplify CodeSyntaxHighlighter to emit plain attributed text
- Remove the Splash SwiftPM package reference and product dependency
Refs https://github.com/zerolabsco/hutch/issues/16
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
| | |
|
| |
|
|
|
|
| |
The non-persistent background declares scripts without a service_worker,
so App Store validation (code 90849) requires the persistent flag to be
explicitly false on iOS/iPadOS. Add "persistent": false.
|
| |\
| |
| | |
Move Home system status into a title-bar status badge
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Replace the disruption-only banner on the Home tab with a persistent
circular status indicator in the navigation bar, next to the "Home"
title. The badge reflects the existing status logic — green/check when
operational, orange/exclamation on disruption, gray otherwise — and taps
through to System Status. SystemStatusSummaryRow is unchanged and still
used by the More tab.
Resolve the system-status result first in HomeViewModel.loadDashboard so
the badge settles from cache immediately instead of waiting on the
slower projects/jobs/tickets/inbox loads, which had left it spinning for
several seconds.
Bump MARKETING_VERSION to 3.8.2 and record it in ROADMAP.
|
| |\
| |
| | |
docs: note dual-forge issue/patch tracking in README
|
| |/
|
|
|
| |
Hutch is hosted on both GitHub and sourcehut as synced peers; tell
contributors they can file issues or send patches on either forge.
|
| |\
| |
| | |
v3.8.1: SonarCloud triage, forceRefresh fix, housekeeping
|
| | |
| |
| |
| |
| |
| |
| |
| | |
SearchHutchIntent's route-to-Lookup stopgap and the absent
OpenSavedSearchIntent are both gated on a global search/persistence
layer Hutch lacks. Promote both to ROADMAP § "App Intent gaps" and
replace the inline TODOs with plain references, clearing those two
S1135 issues without losing the design intent.
|
| | |
| |
| |
| |
| |
| | |
Trailing // comments after {} left the block lexically empty, so
SonarCloud kept flagging stopLoading (and would have re-flagged the two
Cancel buttons). S1186 wants a *nested* comment; use /* ... */ inside.
|
| | |
| |
| |
| |
| |
| | |
Update the roadmap's SonarCloud section to the live 53-issue / 10-rule
reality and mark what v3.8.1 fixed, silenced-as-bug, and left Won't Fix.
Bump MARKETING_VERSION on the app, widget, and Safari extension.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- S1871: merge the identical .home / .recentActivity deep-link cases in
RootView — recent activity is a section of Home, not its own screen.
- S1186: comment the two intentionally-empty Cancel buttons
(PatchsetDetailView, TicketDetailView) and the empty URLProtocol
stopLoading override in APICacheTests.
- S108: comment the expected-miss catch block in APICacheTests.
- S1172: rename the unused url parameter in mimeType(for:) to _.
- S4624: extract the nested template literal in the deep-link builders
(background.js, content.js) to a pathSegment variable.
Left as Won't Fix, with reasons: the 35 hardcoded-URI warnings (a
one-forge client and its literal-URL tests), executeCached's 8 params
(38 call sites, no benefit), the forceRefresh S1172 pair (fixed as a
real bug instead), S1481 on ArtifactsView (false positive — $vm.error
is used), and S7785 (top-level await would break a classic content
script).
|
| | |
| |
| |
| |
| |
| |
| |
| | |
It sat at Hutch/Hutch/App/AccountSession.swift, one level too deep. The
target is a PBXFileSystemSynchronizedRootGroup rooted at Hutch/, so the
file compiled by path with no pbxproj reference; moving it beside the
rest of App/ needs no project-file change. Also removed the emptied
Hutch/Hutch tree and the stray empty Hutch/HutchTests dir.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
loadDashboard(forceRefresh:) fanned the flag out to five loaders, but
loadProjects and loadSystemStatusSnapshot dropped it: they called
fetchProjects() and snapshotResult() with no policy, so pull-to-refresh
returned cached projects and status while the other three sections
refreshed. SonarCloud flagged both params as unused (swift:S1172).
Thread forceRefresh through ProjectService.fetchProjects into the page
policy (refreshIgnoringCache when forced), and pass it to
snapshotResult, which already accepted it. ProjectsListView carried the
same latent bug via its own .refreshable — fixed there too now that
fetchProjects can force.
|
| |\ \
| |/
|/| |
ci: drop the redundant post-merge test run
|
| |/
|
|
|
|
|
|
| |
The suite ran on push to main and on pull_request. Since merges here are
merge commits (not squash) and pull_request tests the merge result, a
green PR already validates the exact tree that lands on main — the push
run just re-confirmed it on a macOS runner. Trigger on pull_request (and
workflow_dispatch) only.
|
| | |
|
| |
|
|
|
|
| |
CLAUDE.md holds working notes for this checkout — build invocation, remote
topology, and which mistakes this codebase invites. Project facts stay in
ROADMAP.md and SCOPE.md, which are committed.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two additions to Phase 3.
SonarCloud, with the breakdown rather than the headline: 51 open issues are 0
bugs, 0 vulnerabilities and 51 code smells, and 35 of those are hardcoded-URI
warnings against a deep-link mapper's test fixtures and a one-forge client's
endpoint constants. Those want triaging as Won't Fix, not refactoring. The part
worth real thought is the 3 hotspots — the sr.ht token is stored without a
SecAccessControl, so an unlocked phone hands it over, which is a product
decision rather than a lint nit.
Ingesting sr.ht's quarterly "What's cooking" posts, because nothing here tracks
the API's evolution and this repo's assumptions rot silently. Already proven
worthwhile: SCOPE.md claimed pronouns were not in the schema while AppState
queries them and UserProfileView displays them. That entry is struck through and
kept as evidence. Q2 2026 also reports a writable hub.sr.ht API and finished
deploy keys, both of which contradict what is written here.
|
| |\
| |
| | |
Phase 3: API features
|
| | |
| |
| |
| |
| | |
It did its job: tags=1 confirmed the menu was disabled by its own tags check
while the explanation sat unreachable inside it.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Deleting a repository left it on the list, and pulling to refresh did not shift
it. Two independent reasons, both cache-related.
deleteRepository never invalidated anything. Creation invalidates the
repositories and home prefixes; deletion was written without it, so the list and
Home kept serving a repository that no longer exists.
And forceRefresh only ever reached the build statuses — its own doc comment says
so — while the repository list itself was pinned to useCache: true. So a pull to
refresh re-served the same cache it already had. fetchPage already takes
useCache and falls through to an uncached fetch; it was simply never told.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Tapping download opened Artifact.url in the browser, which answered with
"Authorization header is required". That URL is not a web page: git.sr.ht
resolves it to <api origin>/query/artifact/<checksum>/<filename>, which demands
a bearer token. Safari has none and no way to get one, so the download could
never have worked — this predates the upload work.
Fetch it with the client that already holds the token and hand the user the file
through a share sheet. fetchData mirrors fetchText, including its host guard, so
an authenticated request still cannot be aimed anywhere but *.sr.ht over https.
Also guards zero-byte uploads. sr.ht streams into S3, which rejects a zero-part
multipart completion with "MalformedXML: UnknownError" — an error that says
nothing about the cause and cost a round of testing to identify. Empty files are
now refused by name before the request is made.
|