diff options
| -rw-r--r-- | Hutch.xcodeproj/project.pbxproj | 24 | ||||
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | ROADMAP.md | 50 | ||||
| -rw-r--r-- | SCOPE.md | 21 |
4 files changed, 71 insertions, 29 deletions
diff --git a/Hutch.xcodeproj/project.pbxproj b/Hutch.xcodeproj/project.pbxproj index 8f71248..32da475 100644 --- a/Hutch.xcodeproj/project.pbxproj +++ b/Hutch.xcodeproj/project.pbxproj @@ -597,7 +597,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 89; + CURRENT_PROJECT_VERSION = 90; DEVELOPMENT_TEAM = ZCNAX3VL9D; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; @@ -614,7 +614,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.7.0; + MARKETING_VERSION = 3.8.0; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; @@ -634,7 +634,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 89; + CURRENT_PROJECT_VERSION = 90; DEVELOPMENT_TEAM = ZCNAX3VL9D; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; @@ -651,7 +651,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.7.0; + MARKETING_VERSION = 3.8.0; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; @@ -714,7 +714,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 89; + CURRENT_PROJECT_VERSION = 90; DEVELOPMENT_TEAM = ZCNAX3VL9D; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HutchWidgetExtension/Info.plist; @@ -724,7 +724,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.7.0; + MARKETING_VERSION = 3.8.0; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -743,7 +743,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 89; + CURRENT_PROJECT_VERSION = 90; DEVELOPMENT_TEAM = ZCNAX3VL9D; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HutchWidgetExtension/Info.plist; @@ -753,7 +753,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.7.0; + MARKETING_VERSION = 3.8.0; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -772,7 +772,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 89; + CURRENT_PROJECT_VERSION = 90; DEVELOPMENT_TEAM = ZCNAX3VL9D; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HutchSafariExtension/Info.plist; @@ -782,7 +782,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.7.0; + MARKETING_VERSION = 3.8.0; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchSafariExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -801,7 +801,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 89; + CURRENT_PROJECT_VERSION = 90; DEVELOPMENT_TEAM = ZCNAX3VL9D; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HutchSafariExtension/Info.plist; @@ -811,7 +811,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.7.0; + MARKETING_VERSION = 3.8.0; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchSafariExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -14,13 +14,16 @@ The app currently includes: - Home dashboard with assigned tickets, recent builds, and projects - Repository browsing for Git and Mercurial repositories - Repository details including README, references, commits, diffs, files, artifacts, and settings +- Artifact upload and deletion on release tags - Tracker and ticket browsing, ticket detail views, and tracker creation - Ticket editing and deletion, with subscriptions for tickets and trackers - Build job browsing, build detail views, and build submission - Inbox and mailing list reading flows - Patchset review: cover letters, per-patch diffs, checks, version chains, and status changes +- Mailing list creation, settings, and deletion +- Ticket activity feed across every tracker you follow - Paste browsing, creation, and detail views -- Profile and account settings, including SSH keys, PGP keys, and personal access token management +- Profile and account settings, including SSH keys, PGP keys, personal access token management, and the audit log - Email preferences for todo.sr.ht and lists.sr.ht - Deep links for repositories, tickets, and build jobs @@ -131,22 +131,40 @@ GraphQL mutation. Treat that boundary as explicit rather than half-building it. ## Phase 3: Polish and reach -- **Localization.** The project sets `LOCALIZATION_PREFERS_STRING_CATALOGS = - YES` but ships no string catalog, so every user-facing string is hardcoded - English. -- **Accessibility.** Labels and hints appear in only 16 of roughly 130 view - files. -- `uploadArtifact` / `deleteArtifact` — artifacts are read-only today. -- Webhook management. Zero calls to any `create*Webhook` across every service. - Push notifications are out of scope because they need a relay server (see - [SCOPE.md](SCOPE.md)), but webhook management is client-side only and is a - prerequisite if that relay ever ships. -- `auditLog` (meta.sr.ht) — unused security surface. -- Build groups (`createGroup`, `startGroup`) and secret management - (`shareSecret`, the `secrets` query). Today `secrets` is only a submit toggle. -- Mailing list creation and settings (`createMailingList`, `updateMailingList`, - `deleteMailingList`). -- `events` feed (todo.sr.ht) and `archiveMessage` (lists.sr.ht). +Unlike Phases 1 and 2, this is not one shippable thing. It is several, and they +are sized very differently — measure before committing to one. + +### API features — done (v3.8.0) + +- ~~`uploadArtifact` / `deleteArtifact`~~ — artifacts were read-only. +- ~~`auditLog` (meta.sr.ht)~~ — surfaced under the tokens in Profile. +- ~~Mailing list creation and settings~~ (`createMailingList`, + `updateMailingList`, `deleteMailingList`). +- ~~`events` feed (todo.sr.ht)~~ — a ticket activity feed under More. + +Four of the six planned. The other two did not survive contact: + +- `archiveMessage` is `@internal` and inaccessible. +- Webhook management, `shareSecret`, and build groups are reachable but declined + on judgement — see [SCOPE.md](SCOPE.md) for the reasoning, so they do not get + re-proposed. + +### Localization + +The project sets `LOCALIZATION_PREFERS_STRING_CATALOGS = YES` but ships no +string catalog, so every user-facing string is hardcoded English. Roughly 634 +literals: 239 `Text(`, 150 `Label(`, 117 `Button(`, 77 `Section(`, 51 +`navigationTitle(`. + +Worth knowing before starting: a catalog containing only English changes nothing +for users until translations exist. It is groundwork, and it is the largest diff +in the roadmap — it touches nearly every view, with the regression risk that +implies. + +### Accessibility + +Labels and hints appear in 17 of 89 view files. Mechanical and low-risk, but it +cannot be verified from a build — it needs VoiceOver driven on a device. ### Swift 6 language mode @@ -7,3 +7,24 @@ - Explore / search (hub.sr.ht) (no public discovery API) - Pronouns on profile (not in GraphQL schema) - Revoke personal access tokens (`@internal` in schema, inaccessible) +- Archive a message to a list (`archiveMessage` is `@internal`, inaccessible) +- Subscribe to a mailing list (`mailingListSubscribe` exists, but `MailingList` + has no `subscription` field and sr.ht has no discovery API, so there is no way + to find a list you are not already subscribed to — see hub.sr.ht above) +- Submitting patches (a `git send-email` flow, not a GraphQL mutation; Hutch + reviews patchsets but cannot send them) + +## Declined rather than blocked + +These are reachable in the API. They are left out on judgement, not capability. + +- **Webhook management** (24 fields across five services). A webhook needs an + HTTPS endpoint you control to receive POSTs. Without the relay above, this + only serves someone already running their own endpoint, and that person is not + managing it from a phone. Reconsider if `hutch-notify` ever ships. +- **`shareSecret`.** Shares a build secret — an SSH key or PAT — with another + user. A mistap grants someone else a credential, and nothing in the app can + take it back. That belongs on the web behind a full-size confirmation. The + read-only `secrets` list would be fine on its own. +- **Build groups** (`createGroup`, `startGroup`). Multi-job pipelines are + authored in `.build.yml`, not composed on a phone. |
