<feed xmlns='http://www.w3.org/2005/Atom'>
<title>hutch.git/Hutch, branch v3.11.0</title>
<subtitle>ios client for sourcehut. swiftui.
</subtitle>
<id>http://git.krz.sh/krz/hutch.git/atom?h=v3.11.0</id>
<link rel='self' href='http://git.krz.sh/krz/hutch.git/atom?h=v3.11.0'/>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/'/>
<updated>2026-08-07T21:51:32+00:00</updated>
<entry>
<title>Mailing list subscribe/unsubscribe toggle (v3.11.0)</title>
<updated>2026-08-07T21:51:32+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-07T21:51:32+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=039f06095cb3df072968be2f19f45bace605baeb'/>
<id>urn:sha1:039f06095cb3df072968be2f19f45bace605baeb</id>
<content type='text'>
Add a subscribe/unsubscribe toggle to the mailing-list detail toolbar
(MailingListDetailView, which backs Lookup results and ProjectMailingListView).
Hidden for lists you own and while state is unknown.

State comes from membership in the subscriptions query, not
MailingList.subscription — live testing showed that field returns null even
right after a successful mailingListSubscribe, so it is a trap (documented in
ROADMAP API traps). The numeric listID the mutations require is read from
list(rid:){ id }. Verified live against ~hutch.

Bumps to 3.11.0 (build 96); roadmap/SCOPE corrected.
</content>
</entry>
<entry>
<title>Deploy keys: manage git.sr.ht repository deploy keys (v3.10.0)</title>
<updated>2026-08-07T21:29:04+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-07T21:29:04+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=07156180789b02d4f22a87f22a37c912e7543190'/>
<id>urn:sha1:07156180789b02d4f22a87f22a37c912e7543190</id>
<content type='text'>
Wire git.sr.ht createDeployKey / deleteDeployKey and Repository.deployKeys
into an owner-only Deploy Keys sheet in the repository actions menu, next to
ACLs: list keys (fingerprint, comment, access), add an SSH public key with
RO/RW access, and delete behind a confirmation.

Verified live against the ~hutch account. The createDeployKey response
returns an empty access value, so create selects only rid and the list is
reloaded rather than decoding the partial key.

Bumps to 3.10.0 (build 95); roadmap marks deploy keys shipped.
</content>
</entry>
<entry>
<title>Projects: discovery, create, edit, manage linked resources (#12, #13, #14, #15)</title>
<updated>2026-08-07T09:12:50+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-07T09:12:50+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=1f8f651a9c2ac2d6be231ff9f71ee3bcce9936d8'/>
<id>urn:sha1:1f8f651a9c2ac2d6be231ff9f71ee3bcce9936d8</id>
<content type='text'>
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).
</content>
</entry>
<entry>
<title>Sync bundled man page catalog from man.sr.ht (#7)</title>
<updated>2026-08-07T08:27:37+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-07T08:27:37+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=89c90d11d80fde63997ca029e14806df0319a541'/>
<id>urn:sha1:89c90d11d80fde63997ca029e14806df0319a541</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Expand App Intents: dialogs, search type, mutating intents (#17)</title>
<updated>2026-08-07T08:06:34+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-07T08:06:34+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=9c11d69002d71556fea1e2a938e02d4f4d503ea5'/>
<id>urn:sha1:9c11d69002d71556fea1e2a938e02d4f4d503ea5</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Add multi-language syntax highlighting (#16)</title>
<updated>2026-08-07T07:45:31+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-07T07:45:31+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=b410fd16b76146f4116538c5b82330818dd47da9'/>
<id>urn:sha1:b410fd16b76146f4116538c5b82330818dd47da9</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Take inbox unread count off pull-to-refresh path (#9)</title>
<updated>2026-08-07T06:44:26+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-07T06:44:26+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=1c4e968c31ee451666a65e05c762c9422c768426'/>
<id>urn:sha1:1c4e968c31ee451666a65e05c762c9422c768426</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Let users clear recent activity on Home (#11)</title>
<updated>2026-08-07T06:44:17+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-07T06:44:17+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=a0ed11a3c4ddb2f532fa70884dc2829a23a5eec8'/>
<id>urn:sha1:a0ed11a3c4ddb2f532fa70884dc2829a23a5eec8</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Fix checklist rendering with inline code (#18)</title>
<updated>2026-08-07T06:44:10+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-07T06:44:10+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=5e4e259d8bfd9b062aa39af793ec3a59b70ad7f0'/>
<id>urn:sha1:5e4e259d8bfd9b062aa39af793ec3a59b70ad7f0</id>
<content type='text'>
The .task-list-item CSS used display: inline-flex, which turned each
text run and inline &lt;code&gt; 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.
</content>
</entry>
<entry>
<title>convert readme to nfo; convert docs to txt; relicense to 0bsd</title>
<updated>2026-08-02T20:35:23+00:00</updated>
<author>
<name>Christian Cleberg</name>
<email>hello@cleberg.net</email>
</author>
<published>2026-08-02T20:29:33+00:00</published>
<link rel='alternate' type='text/html' href='http://git.krz.sh/krz/hutch.git/commit/?id=fbcb4113f110a7db9cf21d18510cb59c2e90ba23'/>
<id>urn:sha1:fbcb4113f110a7db9cf21d18510cb59c2e90ba23</id>
<content type='text'>
</content>
</entry>
</feed>
