Commit 5d64fcf7f4
Unsigned
Layout: unified · split
Hutch.xcodeproj/project.pbxproj −4
| @@ -7,7 +7,6 @@ | |||
| 7 | objects = { | 7 | objects = { |
| 8 | 8 | ||
| 9 | /* Begin PBXBuildFile section */ | 9 | /* Begin PBXBuildFile section */ |
| 10 | 8B2F89622F69DEA900FC0253 /* TODO.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89612F69DEA900FC0253 /* TODO.md */; }; | ||
| 11 | 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89632F69DEB900FC0253 /* LICENSE */; }; | 10 | 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89632F69DEB900FC0253 /* LICENSE */; }; |
| 12 | 8B2F89672F69DEB900FC0253 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89642F69DEB900FC0253 /* README.md */; }; | 11 | 8B2F89672F69DEB900FC0253 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89642F69DEB900FC0253 /* README.md */; }; |
| 13 | 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89652F69DEB900FC0253 /* SECURITY.md */; }; | 12 | 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */ = {isa = PBXBuildFile; fileRef = 8B2F89652F69DEB900FC0253 /* SECURITY.md */; }; |
| @@ -24,7 +23,6 @@ | |||
| 24 | /* End PBXContainerItemProxy section */ | 23 | /* End PBXContainerItemProxy section */ |
| 25 | 24 | ||
| 26 | /* Begin PBXFileReference section */ | 25 | /* Begin PBXFileReference section */ |
| 27 | 8B2F89612F69DEA900FC0253 /* TODO.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = TODO.md; sourceTree = "<group>"; }; | ||
| 28 | 8B2F89632F69DEB900FC0253 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; }; | 26 | 8B2F89632F69DEB900FC0253 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; }; |
| 29 | 8B2F89642F69DEB900FC0253 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; }; | 27 | 8B2F89642F69DEB900FC0253 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; }; |
| 30 | 8B2F89652F69DEB900FC0253 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; }; | 28 | 8B2F89652F69DEB900FC0253 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; }; |
| @@ -86,7 +84,6 @@ | |||
| 86 | 8B2F89632F69DEB900FC0253 /* LICENSE */, | 84 | 8B2F89632F69DEB900FC0253 /* LICENSE */, |
| 87 | 8B2F89642F69DEB900FC0253 /* README.md */, | 85 | 8B2F89642F69DEB900FC0253 /* README.md */, |
| 88 | 8B2F89652F69DEB900FC0253 /* SECURITY.md */, | 86 | 8B2F89652F69DEB900FC0253 /* SECURITY.md */, |
| 89 | 8B2F89612F69DEA900FC0253 /* TODO.md */, | ||
| 90 | 8B4B28D32F6704280045FA19 /* Hutch */, | 87 | 8B4B28D32F6704280045FA19 /* Hutch */, |
| 91 | 8B8182B82F6B73F3000AE049 /* HutchTests */, | 88 | 8B8182B82F6B73F3000AE049 /* HutchTests */, |
| 92 | 8B4B28D22F6704280045FA19 /* Products */, | 89 | 8B4B28D22F6704280045FA19 /* Products */, |
| @@ -194,7 +191,6 @@ | |||
| 194 | isa = PBXResourcesBuildPhase; | 191 | isa = PBXResourcesBuildPhase; |
| 195 | buildActionMask = 2147483647; | 192 | buildActionMask = 2147483647; |
| 196 | files = ( | 193 | files = ( |
| 197 | 8B2F89622F69DEA900FC0253 /* TODO.md in Resources */, | ||
| 198 | 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */, | 194 | 8B2F89662F69DEB900FC0253 /* LICENSE in Resources */, |
| 199 | 8B2F89672F69DEB900FC0253 /* README.md in Resources */, | 195 | 8B2F89672F69DEB900FC0253 /* README.md in Resources */, |
| 200 | 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */, | 196 | 8B2F89682F69DEB900FC0253 /* SECURITY.md in Resources */, |
README.md +65 −35
| @@ -1,58 +1,88 @@ | |||
| 1 | # Hutch for Sourcehut | 1 | # Hutch |
| 2 | Sourcehut on iOS | 2 | iOS client for SourceHut. |
| 3 | 3 | ||
| 4 | [](https://builds.sr.ht/~ccleberg/Hutch?) | 4 | [](https://builds.sr.ht/~ccleberg/Hutch?) |
| 5 | 5 | ||
| 6 | ## Table of Contents | 6 | ## Overview |
| 7 | 7 | ||
| 8 | - [Introduction](#introduction) | 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. |
| 9 | - [Installation](#installation) | ||
| 10 | - [Usage](#usage) | ||
| 11 | - [Contributing](#contributing) | ||
| 12 | - [License](#license) | ||
| 13 | - [Contact](#contact) | ||
| 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 | 2. Open the project in Xcode. | 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: | 59 | - Hutch validates the token against `meta.sr.ht` before saving it |
| 33 | https://meta.sr.ht/oauth2/personal-token | 60 | - The token is stored in the iOS keychain |
| 34 | - **Step 2**: Navigate the app the same way you'd navigate Sourcehut. | 61 | - `Reset App Data` removes saved token data, caches, cookies, and local web data from the device |
| 35 | - **Step 3**: If something doesn't work as expected, send us an email! | 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 | ## Contributing | 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. | 78 | ## Security |
| 42 | 2. Create a new branch for your feature (`git checkout -b feature-xyz`). | 79 | |
| 43 | 3. Make your changes. | 80 | If you discover a security issue, see [SECURITY.md](SECURITY.md). |
| 44 | 4. Commit your changes and push to the branch. | ||
| 45 | 5. Open a pull request. | ||
| 46 | 81 | ||
| 47 | ## License | 82 | ## License |
| 48 | 83 | ||
| 49 | This project is licensed under the GPL 3.0 or later License. See the | 84 | This project is licensed under the GPL 3.0 or later. See [LICENSE](LICENSE). |
| 50 | [LICENSE](LICENSE) file for more information. | ||
| 51 | 85 | ||
| 52 | ## Contact | 86 | ## Contact |
| 53 | 87 | ||
| 54 | For questions or feedback, please reach out to [hello@cleberg.net]. | 88 | Questions or feedback: hello@cleberg.net |
| 55 | |||
| 56 | --- | ||
| 57 | |||
| 58 | Thank you for checking out **Hutch**! We hope you find it useful and enjoyable. | ||
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) | ||