Commit 5d64fcf7f4
Unsigned
Layout: unified · split
Hutch.xcodeproj/project.pbxproj −4
| @@ -7,7 +7,6 @@ | ||
| 7 | 7 | objects = { |
| 8 | 8 | |
| 9 | 9 | /* Begin PBXBuildFile section */ |
| 10 | 8B2F89622F69DEA900FC0253 /* TODO.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89612F69DEA900FC0253 /* TODO.md */; }; | |
| 11 | 10 | 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89632F69DEB900FC0253 /* LICENSE */; }; |
| 12 | 11 | 8B2F89672F69DEB900FC0253 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89642F69DEB900FC0253 /* README.md */; }; |
| 13 | 12 | 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89652F69DEB900FC0253 /* SECURITY.md */; }; |
| @@ -24,7 +23,6 @@ | ||
| 24 | 23 | /* End PBXContainerItemProxy section */ |
| 25 | 24 | |
| 26 | 25 | /* Begin PBXFileReference section */ |
| 27 | 8B2F89612F69DEA900FC0253 /* TODO.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = TODO.md; sourceTree = "<group>"; }; | |
| 28 | 26 | 8B2F89632F69DEB900FC0253 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; }; |
| 29 | 27 | 8B2F89642F69DEB900FC0253 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; }; |
| 30 | 28 | 8B2F89652F69DEB900FC0253 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; }; |
| @@ -86,7 +84,6 @@ | ||
| 86 | 84 | 8B2F89632F69DEB900FC0253 /* LICENSE */, |
| 87 | 85 | 8B2F89642F69DEB900FC0253 /* README.md */, |
| 88 | 86 | 8B2F89652F69DEB900FC0253 /* SECURITY.md */, |
| 89 | 8B2F89612F69DEA900FC0253 /* TODO.md */, | |
| 90 | 87 | 8B4B28D32F6704280045FA19 /* Hutch */, |
| 91 | 88 | 8B8182B82F6B73F3000AE049 /* HutchTests */, |
| 92 | 89 | 8B4B28D22F6704280045FA19 /* Products */, |
| @@ -194,7 +191,6 @@ | ||
| 194 | 191 | isa = PBXResourcesBuildPhase; |
| 195 | 192 | buildActionMask = 2147483647; |
| 196 | 193 | files = ( |
| 197 | 8B2F89622F69DEA900FC0253 /* TODO.md in Resources */, | |
| 198 | 194 | 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */, |
| 199 | 195 | 8B2F89672F69DEB900FC0253 /* README.md in Resources */, |
| 200 | 196 | 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */, |
README.md +65 −35
| @@ -1,58 +1,88 @@ | ||
| 1 | # Hutch for Sourcehut | |
| 2 | Sourcehut on iOS | |
| 1 | # Hutch | |
| 2 | iOS client for SourceHut. | |
| 3 | 3 | |
| 4 | 4 | [](https://builds.sr.ht/~ccleberg/Hutch?) |
| 5 | 5 | |
| 6 | ## Table of Contents | |
| 6 | ## Overview | |
| 7 | 7 | |
| 8 | - [Introduction](#introduction) | |
| 9 | - [Installation](#installation) | |
| 10 | - [Usage](#usage) | |
| 11 | - [Contributing](#contributing) | |
| 12 | - [License](#license) | |
| 13 | - [Contact](#contact) | |
| 8 | Hutch is a native SwiftUI app for browsing and managing SourceHut services on iPhone and iPad. It uses SourceHut's GraphQL APIs and stores your personal access token in the iOS keychain. | |
| 14 | 9 | |
| 15 | ## Introduction | |
| 10 | The app currently includes: | |
| 16 | 11 | |
| 17 | **Hutch** is a native Swift client on iOS for [Sourcehut](https://sr.ht). | |
| 12 | - Home dashboard with assigned tickets, recent builds, and projects | |
| 13 | - Repository browsing for Git and Mercurial repositories | |
| 14 | - Repository details including README, references, commits, diffs, files, artifacts, and settings | |
| 15 | - Tracker and ticket browsing, ticket detail views, and tracker creation | |
| 16 | - Build job browsing, build detail views, and build submission | |
| 17 | - Inbox and mailing list reading flows | |
| 18 | - Paste browsing, creation, and detail views | |
| 19 | - Profile and account settings, including SSH keys, PGP keys, and personal access token management | |
| 20 | - Deep links for repositories, tickets, and build jobs | |
| 18 | 21 | |
| 19 | ## Installation | |
| 22 | Some SourceHut services are still browser-only from within Hutch. Unsupported areas currently open in Safari instead of rendering in-app. | |
| 20 | 23 | |
| 21 | To get started with Hutch, follow these steps: | |
| 24 | ## Requirements | |
| 25 | ||
| 26 | - Xcode with current iOS SDK support | |
| 27 | - iOS Simulator or physical iOS device | |
| 28 | - A SourceHut account | |
| 29 | - A SourceHut personal access token | |
| 30 | ||
| 31 | ## Getting Started | |
| 32 | ||
| 33 | 1. Clone the repository: | |
| 34 | ||
| 35 | ```sh | |
| 36 | git clone https://git.sr.ht/~ccleberg/Hutch | |
| 37 | ``` | |
| 22 | 38 | |
| 23 | 1. Clone the repository: `git clone | |
| 24 | https://git.sr.ht/~ccleberg/Hutch` | |
| 25 | 39 | 2. Open the project in Xcode. |
| 26 | 3. Run the app on your device or simulator. | |
| 40 | 3. Build and run the app on a simulator or device. | |
| 41 | 4. On first launch, create or paste a SourceHut personal access token. | |
| 42 | ||
| 43 | You can create a token at: | |
| 44 | ||
| 45 | - `https://meta.sr.ht/oauth/personal-access-tokens` | |
| 46 | ||
| 47 | ## Using Hutch | |
| 48 | ||
| 49 | After signing in with a valid token, Hutch presents five primary areas: | |
| 27 | 50 | |
| 28 | ## Usage | |
| 51 | - `Home`: dashboard for projects, assigned tickets, recent builds, and inbox access | |
| 52 | - `Repositories`: browse, search, create, and manage repositories | |
| 53 | - `Tickets`: browse trackers, create trackers, and view ticket details | |
| 54 | - `Builds`: inspect build jobs and submit new builds | |
| 55 | - `More`: lists, pastes, settings, and external links for unsupported services | |
| 29 | 56 | |
| 30 | Provide instructions on how to use the app. You might include: | |
| 57 | Authentication notes: | |
| 31 | 58 | |
| 32 | - **Step 1**: To login, use a PAT in Sourcehut's portal: | |
| 33 | https://meta.sr.ht/oauth2/personal-token | |
| 34 | - **Step 2**: Navigate the app the same way you'd navigate Sourcehut. | |
| 35 | - **Step 3**: If something doesn't work as expected, send us an email! | |
| 59 | - Hutch validates the token against `meta.sr.ht` before saving it | |
| 60 | - The token is stored in the iOS keychain | |
| 61 | - `Reset App Data` removes saved token data, caches, cookies, and local web data from the device | |
| 62 | ||
| 63 | ## Development | |
| 64 | ||
| 65 | The project is an Xcode app with tests under `HutchTests`. | |
| 66 | ||
| 67 | Typical workflow: | |
| 68 | ||
| 69 | 1. Open the workspace or project in Xcode. | |
| 70 | 2. Select the Hutch app scheme. | |
| 71 | 3. Build the app. | |
| 72 | 4. Run the test plan in `Hutch/HutchTests.xctestplan`. | |
| 36 | 73 | |
| 37 | 74 | ## Contributing |
| 38 | 75 | |
| 39 | Contributions are welcome! Please follow these steps: | |
| 76 | Contributions are welcome. Keep changes scoped, include tests when behavior changes, and open a pull request with a clear summary of the user-facing impact. | |
| 40 | 77 | |
| 41 | 1. Fork the repository. | |
| 42 | 2. Create a new branch for your feature (`git checkout -b feature-xyz`). | |
| 43 | 3. Make your changes. | |
| 44 | 4. Commit your changes and push to the branch. | |
| 45 | 5. Open a pull request. | |
| 78 | ## Security | |
| 79 | ||
| 80 | If you discover a security issue, see [SECURITY.md](SECURITY.md). | |
| 46 | 81 | |
| 47 | 82 | ## License |
| 48 | 83 | |
| 49 | This project is licensed under the GPL 3.0 or later License. See the | |
| 50 | [LICENSE](LICENSE) file for more information. | |
| 84 | This project is licensed under the GPL 3.0 or later. See [LICENSE](LICENSE). | |
| 51 | 85 | |
| 52 | 86 | ## Contact |
| 53 | 87 | |
| 54 | For questions or feedback, please reach out to [hello@cleberg.net]. | |
| 55 | ||
| 56 | --- | |
| 57 | ||
| 58 | Thank you for checking out **Hutch**! We hope you find it useful and enjoyable. | |
| 88 | Questions or feedback: hello@cleberg.net | |
ROADMAP.md deleted −98
| @@ -1,98 +0,0 @@ | ||
| 1 | # Hutch Roadmap | |
| 2 | ||
| 3 | ## Version 1.0 Goal | |
| 4 | ||
| 5 | Ship a stable SourceHut mobile client with strong support for the most active | |
| 6 | day-to-day workflows: | |
| 7 | ||
| 8 | - Browse and manage repositories | |
| 9 | - Browse and manage tickets | |
| 10 | - Browse and manage builds | |
| 11 | - Support both Git and Mercurial repositories | |
| 12 | - Provide dependable sharing and navigation | |
| 13 | ||
| 14 | Version 1.0 does not need to cover every SourceHut service. | |
| 15 | ||
| 16 | --- | |
| 17 | ||
| 18 | ## Release Strategy | |
| 19 | ||
| 20 | ### Phase 1: Ship Readiness | |
| 21 | ||
| 22 | Focus on quality, not new surface area. | |
| 23 | ||
| 24 | #### Core release checklist | |
| 25 | ||
| 26 | - Verify authentication flow on simulator and physical device | |
| 27 | - Verify reset/sign-out/reset-app-data flow on simulator and physical device | |
| 28 | - Verify all destructive actions have confirmation and correct follow-up state | |
| 29 | - Verify all create flows succeed end-to-end: | |
| 30 | - Git repository | |
| 31 | - Mercurial repository | |
| 32 | - Tracker | |
| 33 | - Ticket | |
| 34 | - Build submission | |
| 35 | - Verify build retry and edit/resubmit flows | |
| 36 | - Verify repository sharing links for: | |
| 37 | - Repository | |
| 38 | - Commit | |
| 39 | - File | |
| 40 | - Verify sharing links for: | |
| 41 | - Build | |
| 42 | - Tracker | |
| 43 | - Ticket | |
| 44 | - Profile | |
| 45 | - Review empty/loading/error states across all main tabs | |
| 46 | - Remove any leftover temporary debug logging | |
| 47 | - Audit device-only issues: | |
| 48 | - Xcode attach quirks | |
| 49 | - On-device auth/cache behavior | |
| 50 | - WebView rendering performance | |
| 51 | ||
| 52 | #### UI/UX polish checklist | |
| 53 | ||
| 54 | - Tighten wording and error messages across create/edit flows | |
| 55 | - Confirm summary tabs feel consistent across Git and Mercurial | |
| 56 | - Confirm toolbar actions are visible and non-duplicated | |
| 57 | - Confirm README rendering is smooth on large repositories | |
| 58 | - Confirm forms behave well on iPhone-sized screens | |
| 59 | - Confirm keyboard behavior and dismissal in all creation sheets | |
| 60 | ||
| 61 | #### App Store readiness | |
| 62 | ||
| 63 | - Finalize app icon and screenshots | |
| 64 | - Finalize App Store copy | |
| 65 | - Finalize privacy details | |
| 66 | - Finalize support URL / project URL | |
| 67 | - Decide whether TestFlight comes before public launch | |
| 68 | ||
| 69 | --- | |
| 70 | ||
| 71 | ### Phase 2: Version 1.1 | |
| 72 | ||
| 73 | Add one compact new service surface after launch. | |
| 74 | ||
| 75 | #### Recommended priority | |
| 76 | ||
| 77 | 1. Exact repository lookup | |
| 78 | 2. paste.sr.ht | |
| 79 | 3. lists.sr.ht | |
| 80 | ||
| 81 | #### Why | |
| 82 | ||
| 83 | - Exact repository lookup solves a real gap created by the lack of public | |
| 84 | discovery APIs | |
| 85 | - paste.sr.ht is relatively self-contained | |
| 86 | - lists.sr.ht is valuable, but broader in UI and data model scope | |
| 87 | ||
| 88 | --- | |
| 89 | ||
| 90 | ### Phase 3: Version 1.2+ | |
| 91 | ||
| 92 | Expand only after the v1 core is stable in the wild. | |
| 93 | ||
| 94 | - lists.sr.ht tab | |
| 95 | - paste.sr.ht creation/editing polish | |
| 96 | - pages.sr.ht management | |
| 97 | - Broader deep-link/share coverage | |
| 98 | - Workflow refinements for builds and tickets | |
SCOPE.md added +10
| @@ -0,0 +1,10 @@ | ||
| 1 | # Out of Scope Features | |
| 2 | ||
| 3 | - Universal links (requires Sourcehut to host an apple-app-site-association | |
| 4 | file) | |
| 5 | - Push notifications for builds and tickets (requires a backend relay server) | |
| 6 | - Contribution activity / GitHub-style heatmap (no aggregate endpoint, | |
| 7 | impractical to compute) | |
| 8 | - Explore / search (hub.sr.ht) (no public discovery API) | |
| 9 | - Pronouns on profile (not in GraphQL schema) | |
| 10 | - Revoke personal access tokens (`@internal` in schema, inaccessible) | |
TODO.md deleted −67
| @@ -1,67 +0,0 @@ | ||
| 1 | # TODO | |
| 2 | ||
| 3 | --- | |
| 4 | ||
| 5 | ## TODO List | |
| 6 | ||
| 7 | ### Core Functionality | |
| 8 | ||
| 9 | - Implement manual `~owner/repo` lookup flow for opening git.sr.ht or hg.sr.ht | |
| 10 | repositories directly | |
| 11 | ||
| 12 | --- | |
| 13 | ||
| 14 | ### paste.sr.ht | |
| 15 | ||
| 16 | - **Endpoint:** [https://paste.sr.ht/graphql](https://paste.sr.ht/graphql) | |
| 17 | - **Scope:** `PASTES:RO` (browsing), `PASTES:RW` (creation/editing) | |
| 18 | ||
| 19 | **Tasks:** | |
| 20 | ||
| 21 | - Show the authenticated user’s pastes | |
| 22 | - Allow viewing individual pastes | |
| 23 | - Support creating new pastes | |
| 24 | ||
| 25 | --- | |
| 26 | ||
| 27 | ### lists.sr.ht | |
| 28 | ||
| 29 | - **Endpoint:** [https://lists.sr.ht/graphql](https://lists.sr.ht/graphql) | |
| 30 | - **Scope:** `LISTS:RO` | |
| 31 | ||
| 32 | **Tasks:** | |
| 33 | ||
| 34 | - Show the authenticated user’s mailing lists | |
| 35 | - Allow browsing email threads | |
| 36 | - Display individual emails as plain text | |
| 37 | ||
| 38 | --- | |
| 39 | ||
| 40 | ### pages.sr.ht | |
| 41 | ||
| 42 | - **Endpoint:** [https://pages.sr.ht/graphql](https://pages.sr.ht/graphql) | |
| 43 | ||
| 44 | **Tasks:** | |
| 45 | ||
| 46 | - Show the authenticated user’s published sites | |
| 47 | - Display site metadata, publishing status, and access control where supported | |
| 48 | - For managing Pages sites, not browsing public project discovery | |
| 49 | ||
| 50 | --- | |
| 51 | ||
| 52 | ### Donation Page / In-App Purchases | |
| 53 | ||
| 54 | - Add a donation/support page once the App Store / StoreKit setup is ready | |
| 55 | ||
| 56 | --- | |
| 57 | ||
| 58 | ## Out of Scope | |
| 59 | ||
| 60 | - Universal links (requires Sourcehut to host an apple-app-site-association | |
| 61 | file) | |
| 62 | - Push notifications for builds and tickets (requires a backend relay server) | |
| 63 | - Contribution activity / GitHub-style heatmap (no aggregate endpoint, | |
| 64 | impractical to compute) | |
| 65 | - Explore / search (hub.sr.ht) (no public discovery API) | |
| 66 | - Pronouns on profile (not in GraphQL schema) | |
| 67 | - Revoke personal access tokens (`@internal` in schema, inaccessible) | |