~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

An iOS app reads the inbox, pulls, diffs, repositories and profiles

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:feature/ios-app

What changes

An iOS app, under ios/. SwiftUI, iOS 18 and up, no dependencies, its project generated from ios/project.yml. It has Home (starred and own repositories), Inbox, Explore (the activity feed) and Profile tabs, a repository's page with its README and files, its pulls and issues, a pull with its checks, reviews and comments, and its diff, highlighted from the ranges the server already sends. It reads the existing XRPC queries and writes nothing.

An ios check. It compiles the app's models on Linux and reads the answers in harness/shots/fixtures.json with them. It runs only on pulls that change ios/, the lexicons or those answers, and no deploy waits for it.

The app can't sign in yet. Until the pulls above this one land, the inbox and private repositories work only with service tokens that ios/run.sh mints with goat, which aren't in the repository or the app.

Why

The pages work on a phone, but reading an inbox and reviewing a pull is what people do away from a desk, and a native app does it better. The layout follows GitHub's iOS app, as those are the same jobs.

The ios check exists because a model that misreads a field fails a whole screen: two did while this was built (language and skipped), and each broke several screens. Xcode needs macOS, and knotless-run runs pulls under docker alone, so building the app in CI would take a Mac and a new executor. The models need only Foundation, which is the part most likely to drift from the server.

How it was checked

Run in the iPhone 17 Pro simulator on iOS 26.5 against knotless.dev, signed in with service tokens: every screen looked at in light mode, and the inbox, pull and diff in dark. KnotlessUITests passes, 3 of 3, tapping from the inbox into a private repository's pull and its diff, and from Home to a repository's files. ios/check-models.sh reads all 31 recorded answers of the kinds the app uses.

Shortcomings

  • CI doesn't build the app: ios/README.md has the commands to run by hand.
  • No answer of listNotifications is recorded, so the ios check doesn't cover the inbox's model.
  • Not run on a real device or iPad. The signed-out inbox and opening a single file weren't looked at.
  • No app icon, search, or view of work across repositories. Code wraps rather than scrolling sideways, and Markdown images show as their alt text.

🤖 Generated with Claude Code

Approved

This adds a read-only SwiftUI iOS app under ios/, plus an ios workflow. The workflow compiles Models.swift on Linux and decodes the recorded answers in harness/shots/fixtures.json with it. I read the workflow, check-models.sh, ModelCheck, the client, the models, the highlighter, the Markdown parser, App.swift, CodeViews.swift and run.sh. I didn't read the other views, the UI tests, the asset SVGs or project.yml. I found nothing that has to change before it merges.

  • Models and check: the checker picks answers by their /xrpc/dev.knotless.<name> key and requires status == 200. It fails if it reads none, so a moved fixture shape can't pass silently.
  • Highlighting: the range arithmetic is bounds-checked, and an out-of-range or invalid range is skipped rather than crashing.
  • Dev tokens: DevAccount reads service tokens only from an environment path that ios/run.sh sets. The tokens are not in the repository or the app, and .tokens* and build/ are git-ignored. Before sign-in ships, make sure nothing like this stays reachable in a release build.
  • Checks: when I looked, ios, check and test were still running. The others had passed or skipped. This isn't a gate on the approval.
  • Docs: AGENTS.md now describes ios.yml. The change adds no crates/ code, so no changeset is needed.

Two gaps, both already in the body: nothing records a listNotifications answer, so the inbox model isn't covered, and the app itself isn't built in CI.

Merged as e0c925b