Commit ab77dbf977

ab77dbf977d020d14ba351ba926385c345693daf

parent: 023f46c63e

Unsigned

cmc <hello@cleberg.net> · 2026-07-16 02:50 UTC

chore: bump to 3.7.0 and record Phase 2

MARKETING_VERSION 3.6.0 -> 3.7.0, build 88 -> 89.

The README feature list also picks up Phase 1's ticket editing, subscriptions,
and email preferences, which it never gained.

Layout: unified · split

Hutch.xcodeproj/project.pbxproj +12 −12
@@ -597,7 +597,7 @@
597 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 597 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
598 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements; 598 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
599 CODE_SIGN_STYLE = Automatic; 599 CODE_SIGN_STYLE = Automatic;
600 CURRENT_PROJECT_VERSION = 88; 600 CURRENT_PROJECT_VERSION = 89;
601 DEVELOPMENT_TEAM = ZCNAX3VL9D; 601 DEVELOPMENT_TEAM = ZCNAX3VL9D;
602 ENABLE_PREVIEWS = YES; 602 ENABLE_PREVIEWS = YES;
603 GENERATE_INFOPLIST_FILE = YES; 603 GENERATE_INFOPLIST_FILE = YES;
@@ -614,7 +614,7 @@
614 "$(inherited)", 614 "$(inherited)",
615 "@executable_path/Frameworks", 615 "@executable_path/Frameworks",
616 ); 616 );
617 MARKETING_VERSION = 3.6.0; 617 MARKETING_VERSION = 3.7.0;
618 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch; 618 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
619 PRODUCT_NAME = "$(TARGET_NAME)"; 619 PRODUCT_NAME = "$(TARGET_NAME)";
620 STRING_CATALOG_GENERATE_SYMBOLS = YES; 620 STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -634,7 +634,7 @@
634 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 634 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
635 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements; 635 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
636 CODE_SIGN_STYLE = Automatic; 636 CODE_SIGN_STYLE = Automatic;
637 CURRENT_PROJECT_VERSION = 88; 637 CURRENT_PROJECT_VERSION = 89;
638 DEVELOPMENT_TEAM = ZCNAX3VL9D; 638 DEVELOPMENT_TEAM = ZCNAX3VL9D;
639 ENABLE_PREVIEWS = YES; 639 ENABLE_PREVIEWS = YES;
640 GENERATE_INFOPLIST_FILE = YES; 640 GENERATE_INFOPLIST_FILE = YES;
@@ -651,7 +651,7 @@
651 "$(inherited)", 651 "$(inherited)",
652 "@executable_path/Frameworks", 652 "@executable_path/Frameworks",
653 ); 653 );
654 MARKETING_VERSION = 3.6.0; 654 MARKETING_VERSION = 3.7.0;
655 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch; 655 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
656 PRODUCT_NAME = "$(TARGET_NAME)"; 656 PRODUCT_NAME = "$(TARGET_NAME)";
657 STRING_CATALOG_GENERATE_SYMBOLS = YES; 657 STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -714,7 +714,7 @@
714 APPLICATION_EXTENSION_API_ONLY = YES; 714 APPLICATION_EXTENSION_API_ONLY = YES;
715 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements; 715 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
716 CODE_SIGN_STYLE = Automatic; 716 CODE_SIGN_STYLE = Automatic;
717 CURRENT_PROJECT_VERSION = 88; 717 CURRENT_PROJECT_VERSION = 89;
718 DEVELOPMENT_TEAM = ZCNAX3VL9D; 718 DEVELOPMENT_TEAM = ZCNAX3VL9D;
719 GENERATE_INFOPLIST_FILE = NO; 719 GENERATE_INFOPLIST_FILE = NO;
720 INFOPLIST_FILE = HutchWidgetExtension/Info.plist; 720 INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -724,7 +724,7 @@
724 "@executable_path/Frameworks", 724 "@executable_path/Frameworks",
725 "@executable_path/../../Frameworks", 725 "@executable_path/../../Frameworks",
726 ); 726 );
727 MARKETING_VERSION = 3.6.0; 727 MARKETING_VERSION = 3.7.0;
728 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension; 728 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
729 PRODUCT_NAME = "$(TARGET_NAME)"; 729 PRODUCT_NAME = "$(TARGET_NAME)";
730 SKIP_INSTALL = YES; 730 SKIP_INSTALL = YES;
@@ -743,7 +743,7 @@
743 APPLICATION_EXTENSION_API_ONLY = YES; 743 APPLICATION_EXTENSION_API_ONLY = YES;
744 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements; 744 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
745 CODE_SIGN_STYLE = Automatic; 745 CODE_SIGN_STYLE = Automatic;
746 CURRENT_PROJECT_VERSION = 88; 746 CURRENT_PROJECT_VERSION = 89;
747 DEVELOPMENT_TEAM = ZCNAX3VL9D; 747 DEVELOPMENT_TEAM = ZCNAX3VL9D;
748 GENERATE_INFOPLIST_FILE = NO; 748 GENERATE_INFOPLIST_FILE = NO;
749 INFOPLIST_FILE = HutchWidgetExtension/Info.plist; 749 INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -753,7 +753,7 @@
753 "@executable_path/Frameworks", 753 "@executable_path/Frameworks",
754 "@executable_path/../../Frameworks", 754 "@executable_path/../../Frameworks",
755 ); 755 );
756 MARKETING_VERSION = 3.6.0; 756 MARKETING_VERSION = 3.7.0;
757 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension; 757 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
758 PRODUCT_NAME = "$(TARGET_NAME)"; 758 PRODUCT_NAME = "$(TARGET_NAME)";
759 SKIP_INSTALL = YES; 759 SKIP_INSTALL = YES;
@@ -772,7 +772,7 @@
772 APPLICATION_EXTENSION_API_ONLY = YES; 772 APPLICATION_EXTENSION_API_ONLY = YES;
773 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 773 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
774 CODE_SIGN_STYLE = Automatic; 774 CODE_SIGN_STYLE = Automatic;
775 CURRENT_PROJECT_VERSION = 88; 775 CURRENT_PROJECT_VERSION = 89;
776 DEVELOPMENT_TEAM = ZCNAX3VL9D; 776 DEVELOPMENT_TEAM = ZCNAX3VL9D;
777 GENERATE_INFOPLIST_FILE = NO; 777 GENERATE_INFOPLIST_FILE = NO;
778 INFOPLIST_FILE = HutchSafariExtension/Info.plist; 778 INFOPLIST_FILE = HutchSafariExtension/Info.plist;
@@ -782,7 +782,7 @@
782 "@executable_path/Frameworks", 782 "@executable_path/Frameworks",
783 "@executable_path/../../Frameworks", 783 "@executable_path/../../Frameworks",
784 ); 784 );
785 MARKETING_VERSION = 3.6.0; 785 MARKETING_VERSION = 3.7.0;
786 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchSafariExtension; 786 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchSafariExtension;
787 PRODUCT_NAME = "$(TARGET_NAME)"; 787 PRODUCT_NAME = "$(TARGET_NAME)";
788 SKIP_INSTALL = YES; 788 SKIP_INSTALL = YES;
@@ -801,7 +801,7 @@
801 APPLICATION_EXTENSION_API_ONLY = YES; 801 APPLICATION_EXTENSION_API_ONLY = YES;
802 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 802 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
803 CODE_SIGN_STYLE = Automatic; 803 CODE_SIGN_STYLE = Automatic;
804 CURRENT_PROJECT_VERSION = 88; 804 CURRENT_PROJECT_VERSION = 89;
805 DEVELOPMENT_TEAM = ZCNAX3VL9D; 805 DEVELOPMENT_TEAM = ZCNAX3VL9D;
806 GENERATE_INFOPLIST_FILE = NO; 806 GENERATE_INFOPLIST_FILE = NO;
807 INFOPLIST_FILE = HutchSafariExtension/Info.plist; 807 INFOPLIST_FILE = HutchSafariExtension/Info.plist;
@@ -811,7 +811,7 @@
811 "@executable_path/Frameworks", 811 "@executable_path/Frameworks",
812 "@executable_path/../../Frameworks", 812 "@executable_path/../../Frameworks",
813 ); 813 );
814 MARKETING_VERSION = 3.6.0; 814 MARKETING_VERSION = 3.7.0;
815 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchSafariExtension; 815 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchSafariExtension;
816 PRODUCT_NAME = "$(TARGET_NAME)"; 816 PRODUCT_NAME = "$(TARGET_NAME)";
817 SKIP_INSTALL = YES; 817 SKIP_INSTALL = YES;
README.md +3
@@ -15,10 +15,13 @@ The app currently includes:
15- Repository browsing for Git and Mercurial repositories 15- Repository browsing for Git and Mercurial repositories
16- Repository details including README, references, commits, diffs, files, artifacts, and settings 16- Repository details including README, references, commits, diffs, files, artifacts, and settings
17- Tracker and ticket browsing, ticket detail views, and tracker creation 17- Tracker and ticket browsing, ticket detail views, and tracker creation
18- Ticket editing and deletion, with subscriptions for tickets and trackers
18- Build job browsing, build detail views, and build submission 19- Build job browsing, build detail views, and build submission
19- Inbox and mailing list reading flows 20- Inbox and mailing list reading flows
21- Patchset review: cover letters, per-patch diffs, checks, version chains, and status changes
20- Paste browsing, creation, and detail views 22- Paste browsing, creation, and detail views
21- Profile and account settings, including SSH keys, PGP keys, and personal access token management 23- Profile and account settings, including SSH keys, PGP keys, and personal access token management
24- Email preferences for todo.sr.ht and lists.sr.ht
22- Deep links for repositories, tickets, and build jobs 25- Deep links for repositories, tickets, and build jobs
23 26
24Some SourceHut services are still browser-only from within Hutch. Unsupported areas currently open in Safari instead of rendering in-app. 27Some SourceHut services are still browser-only from within Hutch. Unsupported areas currently open in Safari instead of rendering in-app.
ROADMAP.md +23 −14
@@ -74,24 +74,33 @@ Known follow-up: `BuildListViewModel`, `RepositoryListViewModel`, and
74two different cache keys. That predates `APICacheKeys` and should be folded into 74two different cache keys. That predates `APICacheKeys` and should be folded into
75`cachedPayload`. 75`cachedPayload`.
76 76
77## Phase 2: Patchsets 77## Phase 2: Patchsets — done (v3.7.0)
78 78
79The flagship gap. There is currently no reference to `patchset` anywhere in the 79The flagship gap. Sending and reviewing patches over email is the SourceHut
80Swift source, yet lists.sr.ht exposes a full `Patchset` type (subject, version, 80contribution model, and Hutch had no reference to `patchset` anywhere.
81prefix, status, coverLetter, patches, tools, mbox), a `patchset` query, and an
82`updatePatchset` mutation. Sending and reviewing patches over email is the
83SourceHut contribution model, and Hutch cannot currently participate in it.
84 81
85Scope this as review-and-triage, not submission: 82Scoped as review-and-triage, not submission:
86 83
87- Patchset list per mailing list. 84- ~~Patchset list per mailing list~~ — see the caveat below.
88- Patchset detail: cover letter, per-patch diffs (reuse the existing 85- ~~Patchset detail~~: cover letter, per-patch diffs (via the existing
89 `DiffView`), version and superseded-by chain. 86 `DiffView`), checks, and the version / superseded-by chain.
90- Status transitions via `updatePatchset`. 87- ~~Status transitions via `updatePatchset`~~.
91 88
92Patch *submission* is an email / `git send-email` flow and is likely out of 89Two schema facts shaped the result, and are worth knowing before extending this:
93reach from the app. Treat that boundary as explicit rather than half-building 90
94it. 91- **`MailingList` has no `patchsets` field.** A list's patchsets cannot be
92 queried directly; they are reachable only through thread roots. The existing
93 threads query now also selects `root.patchset`, so the Patches tab costs no
94 extra request — but it also means patchsets cannot be filtered by status
95 server-side, and only patchsets whose thread appears in the current page are
96 listed.
97- **`Patch` carries no diff.** It has only `index`, `count`, `version`,
98 `prefix`, `subject`, and `trailers`. The diff exists solely inside the email
99 body, so it is recovered with `InboxThreadUtilities.segmentMessageBody` — the
100 same splitter the inbox thread view uses.
101
102Patch *submission* remains out of reach: it is a `git send-email` flow, not a
103GraphQL mutation. Treat that boundary as explicit rather than half-building it.
95 104
96## Phase 3: Polish and reach 105## Phase 3: Polish and reach
97 106