From c0c514e28e782382495beb949a5c2a822feb2350 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sun, 18 Oct 2026 15:32:07 -0700 Subject: [PATCH] Move to g.fc.run/ai/byre and tag v0.1.0 --- AGENTS.md | 2 +- README.md | 4 ++-- TODO.md | 2 -- cmd/byre/install.go | 2 +- cmd/byre/run.go | 2 +- cmd/byre/serve.go | 4 ++-- docs/macos.md | 2 +- docs/operations.md | 14 +++++++------- go.mod | 2 +- internal/agents/afterreview.go | 4 ++-- internal/agents/clients.go | 8 ++++---- internal/agents/codex.go | 4 ++-- internal/agents/compact.go | 4 ++-- internal/agents/critical.go | 4 ++-- internal/agents/fork.go | 4 ++-- internal/agents/guidance.go | 8 ++++---- internal/agents/hands.go | 2 +- internal/agents/health.go | 2 +- internal/agents/inbox.go | 6 +++--- internal/agents/lead.go | 6 +++--- internal/agents/leadnotes.go | 6 +++--- internal/agents/leadtools.go | 10 +++++----- internal/agents/manager.go | 16 ++++++++-------- internal/agents/mergein.go | 8 ++++---- internal/agents/notes.go | 4 ++-- internal/agents/preview.go | 8 ++++---- internal/agents/process.go | 10 +++++----- internal/agents/queue.go | 4 ++-- internal/agents/respond.go | 4 ++-- internal/agents/review.go | 8 ++++---- internal/agents/snapshots.go | 10 +++++----- internal/agents/subtasks.go | 8 ++++---- internal/agents/summary.go | 6 +++--- internal/agents/tasks.go | 8 ++++---- internal/agents/team.go | 8 ++++---- internal/agents/terminal.go | 6 +++--- internal/agents/workflows.go | 10 +++++----- internal/claude/session.go | 2 +- internal/clients/clients.go | 2 +- internal/codex/session.go | 2 +- internal/git/changes.go | 2 +- internal/server/blobs.go | 2 +- internal/server/changes.go | 4 ++-- internal/server/files.go | 4 ++-- internal/server/hub.go | 2 +- internal/server/images.go | 4 ++-- internal/server/inbox.go | 4 ++-- internal/server/lead.go | 2 +- internal/server/notifications.go | 2 +- internal/server/reviews.go | 2 +- internal/server/server.go | 16 ++++++++-------- internal/server/sse.go | 2 +- internal/server/terminal.go | 4 ++-- internal/server/workflows.go | 2 +- internal/store/blob.go | 2 +- internal/store/discard.go | 2 +- internal/store/inbox.go | 2 +- internal/store/lead.go | 2 +- internal/store/leadnotes.go | 2 +- internal/store/notifications.go | 2 +- internal/store/preview.go | 2 +- internal/store/review.go | 2 +- internal/store/snapshot.go | 2 +- internal/store/store.go | 2 +- internal/store/summaryreads.go | 2 +- internal/store/workflow.go | 2 +- internal/terminal/terminal.go | 2 +- internal/todo/todo.go | 2 +- internal/workflow/file.go | 2 +- internal/workflow/workflow.go | 2 +- mac/Info.plist | 4 ++-- mac/bundle.sh | 2 +- mac/release.sh | 6 +++--- 73 files changed, 160 insertions(+), 162 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 9c8b0f3..4fcd806 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,7 +14,7 @@ When asked to deploy, do exactly this, from the worktree root: 1. `go install ./cmd/byre && codesign --force --sign "Apple Development" --identifier run.fc.byre ~/bin/byre && swift build --package-path hands --configuration release && install hands/.build/release/byre-hands ~/bin/ && launchctl kickstart -k gui/$(id -u)/run.fc.byre`, always as that one command, never `go install` on its own, and always the last action of the turn. The signature gives byre a stable identity, so the macOS privacy grants it holds (Screen Recording, Accessibility, Automation) survive the rebuild; `go install`'s own ad-hoc signature changes with every build and loses them. `install` replaces `byre-hands` with a new file rather than writing over the one running agents have open. 2. When you resume, confirm it came up: read the tail of `~/Library/Logs/byre.log`, and `GET /api/admin/status` through the `tailscale serve` URL (`tailscale serve status` shows it). Report what you deployed and what you checked. -3. Once the service is confirmed healthy, rebuild and relaunch the macOS app: run `mac/bundle.sh`, then update every Mac whose app is running: on iso, `pkill -x Byre` and `open mac/.build/byre.app`, only when an app was running there (never start one that wasn't); on each client Mac, replace and relaunch the installed app through the client tools without asking first. The app reads its server address from its iCloud-synced SwiftData store, shared by every build, so the new build reconnects to prod with no setup. Report each Mac's app commit. +3. Once the service is confirmed healthy, rebuild and relaunch the macOS app: run `mac/bundle.sh`, then update every Mac whose app is running: on iso, `pkill -x Byre` and `open mac/.build/Byre.app`, only when an app was running there (never start one that wasn't); on each client Mac, replace and relaunch the installed app through the client tools without asking first. The app reads its server address from its iCloud-synced SwiftData store, shared by every build, so the new build reconnects to prod with no setup. Report each Mac's app commit. What to expect: diff --git a/README.md b/README.md index 4fe74b4..98aecf3 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,11 @@ macOS, [Tailscale](https://tailscale.com) on every Mac, and on the Mac that runs ## Installing -1. Download the latest `byre-.dmg` from [the releases page](https://g.fc.run/misc/byre/releases) and drag `byre.app` to Applications, on every Mac you'll use byre from. +1. Download the latest `byre-.dmg` from [the releases page](https://g.fc.run/ai/byre/releases) and drag `Byre.app` to Applications, on every Mac you'll use byre from. 2. On the Mac that runs the server, from a terminal whose `PATH` finds `claude`, `codex`, `git` and `npx`: ``` - /Applications/byre.app/Contents/Helpers/byre install + /Applications/Byre.app/Contents/Helpers/byre install ``` It installs the server as a launchd service and serves it through `tailscale serve`, printing the URL. diff --git a/TODO.md b/TODO.md index abee194..e3159c5 100644 --- a/TODO.md +++ b/TODO.md @@ -26,7 +26,5 @@ - Phone app A native client for the phone over the same API, sharing the macOS client's SwiftUI code where it can. Every surveyed tool has one (Claude, Codex, Cursor and Conductor apps, GitHub Mobile, Superset for iPhone); it needs its own layout, since two half-width panes don't fit a phone. -- Move to g.fc.run/ai/byre - Before tagging v0.1.0, since the update feed URL is baked into every installed app. The owner creates the `ai` org on g.fc.run and transfers the repo (Settings → Danger Zone → Transfer ownership). Then rename all the way down: `go.mod`'s module and every import, `SUFeedURL` in `mac/Info.plist`, `repo=` in `mac/release.sh`, README and docs links, and the service checkout's `origin` (`git@g.fc.run:ai/byre.git`). - Server setup in the app Setting up the server's Mac from the app instead of a terminal: on the connection screen, a choice to run the server on this Mac, which does what `Contents/Helpers/byre install` does (the launch agent, `tailscale serve`), checks that `claude`, `codex`, `git` and Tailscale are there, and connects to the URL it set up. diff --git a/cmd/byre/install.go b/cmd/byre/install.go index e13f69a..396b0d9 100644 --- a/cmd/byre/install.go +++ b/cmd/byre/install.go @@ -9,7 +9,7 @@ import ( "path/filepath" "strings" - "g.fc.run/misc/byre/internal/tailscale" + "g.fc.run/ai/byre/internal/tailscale" ) const serviceLabel = "run.fc.byre" diff --git a/cmd/byre/run.go b/cmd/byre/run.go index 72eaee9..fed7139 100644 --- a/cmd/byre/run.go +++ b/cmd/byre/run.go @@ -12,7 +12,7 @@ import ( "os/signal" "strings" - "g.fc.run/misc/byre/internal/claude" + "g.fc.run/ai/byre/internal/claude" ) func runCmd(args []string) { diff --git a/cmd/byre/serve.go b/cmd/byre/serve.go index b0551d0..1ad51fe 100644 --- a/cmd/byre/serve.go +++ b/cmd/byre/serve.go @@ -13,8 +13,8 @@ import ( "syscall" "time" - "g.fc.run/misc/byre/internal/server" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/server" + "g.fc.run/ai/byre/internal/store" ) const defaultListen = "127.0.0.1:8270" diff --git a/docs/macos.md b/docs/macos.md index 8b29de1..fd4a4f0 100644 --- a/docs/macos.md +++ b/docs/macos.md @@ -16,7 +16,7 @@ The app connects to byre's `tailscale serve` HTTPS URL, so its requests get the - `UserNotifications` for notifications. - Third-party code: Apple's `swift-openapi-generator` (with `swift-openapi-runtime` and `swift-openapi-urlsession`) for the API types and client, SwiftTerm for the terminal, and Sparkle for updates (its framework is a binary target, loaded from `Contents/Frameworks` through the `@executable_path/../Frameworks` rpath set in `mac/Package.swift`). -The project is a Swift package under `mac/`, built with `swift build`, not an Xcode project. It builds with Xcode's toolchain: `xcode-select --print-path` must print `/Applications/Xcode.app/Contents/Developer`. With the Command Line Tools selected while Xcode is installed, Swift Build finds two toolchains for the Command Line Tools path and picks one at random on each run; the pick is part of the build request, so every change of pick rebuilds every target. `mac/bundle.sh` builds the release configuration in one directory shared by every worktree, `~/Library/Caches/byre/build`: SwiftPM keys a build on the package's absolute path, so a build in a fresh worktree, or one sharing a `--scratch-path`, recompiles every dependency. Under a `lockf` lock on `~/Library/Caches/byre/build.lock`, so builds from different worktrees take turns, it copies the worktree's `mac/`, `api/` and `hands/` there with `rsync --checksum`, which rewrites only files whose contents differ and leaves the rest's modification times alone, builds both packages, and copies the executables and Sparkle's framework out to `mac/.build/Byre`, `mac/.build/byre-hands` and `mac/.build/Sparkle.framework`. The server is built outside the lock with `go build -o mac/.build/server/byre`, since Go's own cache is shared and safe to use concurrently. It passes `--no-color-diagnostics` because `COLOR_DIAGNOSTICS` otherwise follows whether output is a terminal and is part of the build request, so agents whose shells differ would each rebuild every target in turn; `build-request.json` under `.build/out/Intermediates.noindex/XCBuildData/` shows what a build was keyed on. It then assembles `mac/.build/byre.app` (`Byre` in `Contents/MacOS`, the server and `byre-hands` in `Contents/Helpers`, Sparkle in `Contents/Frameworks`, `mac/Info.plist` with the fixed bundle identifier `run.fc.byre.mac` and a `ByreCommit` key added holding the worktree's `git rev-parse HEAD`, which `API` sends as the `Byre-Commit` header on every request beside `Byre-Host`, the Mac's name, `CFBundleShortVersionString` from `git describe --tags --always` and `CFBundleVersion` from `git rev-list --count HEAD`, the `mac/fonts/` files and an `.icns` rendered from `mac/icon.svg`, cached as `mac/.build/byre.icns` until the SVG changes) and signs it; notification permission needs the bundle identifier. `docs/operations.md`, "macOS app", lists the signing order. +The project is a Swift package under `mac/`, built with `swift build`, not an Xcode project. It builds with Xcode's toolchain: `xcode-select --print-path` must print `/Applications/Xcode.app/Contents/Developer`. With the Command Line Tools selected while Xcode is installed, Swift Build finds two toolchains for the Command Line Tools path and picks one at random on each run; the pick is part of the build request, so every change of pick rebuilds every target. `mac/bundle.sh` builds the release configuration in one directory shared by every worktree, `~/Library/Caches/byre/build`: SwiftPM keys a build on the package's absolute path, so a build in a fresh worktree, or one sharing a `--scratch-path`, recompiles every dependency. Under a `lockf` lock on `~/Library/Caches/byre/build.lock`, so builds from different worktrees take turns, it copies the worktree's `mac/`, `api/` and `hands/` there with `rsync --checksum`, which rewrites only files whose contents differ and leaves the rest's modification times alone, builds both packages, and copies the executables and Sparkle's framework out to `mac/.build/Byre`, `mac/.build/byre-hands` and `mac/.build/Sparkle.framework`. The server is built outside the lock with `go build -o mac/.build/server/byre`, since Go's own cache is shared and safe to use concurrently. It passes `--no-color-diagnostics` because `COLOR_DIAGNOSTICS` otherwise follows whether output is a terminal and is part of the build request, so agents whose shells differ would each rebuild every target in turn; `build-request.json` under `.build/out/Intermediates.noindex/XCBuildData/` shows what a build was keyed on. It then assembles `mac/.build/Byre.app` (`Byre` in `Contents/MacOS`, the server and `byre-hands` in `Contents/Helpers`, Sparkle in `Contents/Frameworks`, `mac/Info.plist` with the fixed bundle identifier `run.fc.byre.mac` and a `ByreCommit` key added holding the worktree's `git rev-parse HEAD`, which `API` sends as the `Byre-Commit` header on every request beside `Byre-Host`, the Mac's name, `CFBundleShortVersionString` from `git describe --tags --always` and `CFBundleVersion` from `git rev-list --count HEAD`, the `mac/fonts/` files and an `.icns` rendered from `mac/icon.svg`, cached as `mac/.build/byre.icns` until the SVG changes) and signs it; notification permission needs the bundle identifier. `docs/operations.md`, "macOS app", lists the signing order. ## Signing diff --git a/docs/operations.md b/docs/operations.md index ecb4b2f..7fbaa9f 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -112,7 +112,7 @@ A team task has several agents working at once in its one worktree, branch and p The listen address is `byre serve --listen`, whose default is `defaultListen` in `cmd/byre/serve.go` (`go run ./cmd/byre serve --help` prints it); keep it on loopback, since identity relies on requests arriving from `tailscale serve`. -`byre install` (`cmd/byre/install.go`) sets the service up for the binary it is run as, with `byre-hands` beside it: it writes `~/Library/LaunchAgents/run.fc.byre.plist` running ` serve`, with a `PATH` of that binary's directory (so `byre-hands` beside it is found) followed by the `PATH` of the shell it was run from (which must find `claude`, `codex`, `git` and `npx`, the last for the Playwright MCP server, which also needs Google Chrome) and logs to `~/Library/Logs/byre.log`; boots out the service if it is loaded, so the new plist is read; bootstraps it; and runs `tailscale serve --bg --https=443 http://` through the Tailscale app's CLI (`tailscale.ServeRoot`, see "Previews"), printing `byre is at https://..ts.net`. Running it again after an update restarts the service on the new binary. From a release, that is `/Applications/byre.app/Contents/Helpers/byre install`. From a checkout: +`byre install` (`cmd/byre/install.go`) sets the service up for the binary it is run as, with `byre-hands` beside it: it writes `~/Library/LaunchAgents/run.fc.byre.plist` running ` serve`, with a `PATH` of that binary's directory (so `byre-hands` beside it is found) followed by the `PATH` of the shell it was run from (which must find `claude`, `codex`, `git` and `npx`, the last for the Playwright MCP server, which also needs Google Chrome) and logs to `~/Library/Logs/byre.log`; boots out the service if it is loaded, so the new plist is read; bootstraps it; and runs `tailscale serve --bg --https=443 http://` through the Tailscale app's CLI (`tailscale.ServeRoot`, see "Previews"), printing `byre is at https://..ts.net`. Running it again after an update restarts the service on the new binary. From a release, that is `/Applications/Byre.app/Contents/Helpers/byre install`. From a checkout: ``` go install ./cmd/byre @@ -128,9 +128,9 @@ After rebuilding from a checkout: step 1 of "Deploying" in `AGENTS.md`, which re ## Releases -A release is one notarized disk image, `byre-.dmg`, holding `byre.app`: the macOS app, with the server (`Contents/Helpers/byre`) and `byre-hands` (`Contents/Helpers/byre-hands`) inside it. Every Mac installs the same app; the server's Mac also runs `byre install` from it (see "Running as a service"). Releases are on the repo's releases page on g.fc.run, `https://g.fc.run/misc/byre/releases`. +A release is one notarized disk image, `byre-.dmg`, holding `Byre.app`: the macOS app, with the server (`Contents/Helpers/byre`) and `byre-hands` (`Contents/Helpers/byre-hands`) inside it. Every Mac installs the same app; the server's Mac also runs `byre install` from it (see "Running as a service"). Releases are on the repo's releases page on g.fc.run, `https://g.fc.run/ai/byre/releases`. -`mac/release.sh` makes one, run on byre's host from a checkout whose `HEAD` carries a `v` tag already pushed to `origin`, with a clean tree; it fetches the tag from `origin` and stops unless it names `HEAD`. It builds with `mac/bundle.sh` (signed with Developer ID, see `docs/macos.md`), zips the app and notarizes it with `xcrun notarytool submit --keychain-profile byre-notary --wait`, staples the ticket, builds the disk image with `hdiutil` (the app and an `/Applications` link), signs, notarizes and staples that too, and writes its SHA-256 beside it. It then signs the image for Sparkle with `sign_update --account byre` and writes `appcast.xml`, a feed with that one release. Last, it creates the release as a draft through the Gitea API (`POST /api/v1/repos/misc/byre/releases`, notes the commit subjects since the previous tag), uploads the image, its `.sha256` and `appcast.xml` as assets, and only then publishes it (`PATCH` with `draft: false`), so the `latest` release always has its appcast. A run that fails part way leaves the draft on the releases page; delete it there before running again. Everything lands in `mac/.build/release//`, and the script prints the release page. +`mac/release.sh` makes one, run on byre's host from a checkout whose `HEAD` carries a `v` tag already pushed to `origin`, with a clean tree; it fetches the tag from `origin` and stops unless it names `HEAD`. It builds with `mac/bundle.sh` (signed with Developer ID, see `docs/macos.md`), zips the app and notarizes it with `xcrun notarytool submit --keychain-profile byre-notary --wait`, staples the ticket, builds the disk image with `hdiutil` (the app and an `/Applications` link), signs, notarizes and staples that too, and writes its SHA-256 beside it. It then signs the image for Sparkle with `sign_update --account byre` and writes `appcast.xml`, a feed with that one release. Last, it creates the release as a draft through the Gitea API (`POST /api/v1/repos/ai/byre/releases`, notes the commit subjects since the previous tag), uploads the image, its `.sha256` and `appcast.xml` as assets, and only then publishes it (`PATCH` with `draft: false`), so the `latest` release always has its appcast. A run that fails part way leaves the draft on the releases page; delete it there before running again. Everything lands in `mac/.build/release//`, and the script prints the release page. It needs, on that Mac: @@ -139,15 +139,15 @@ It needs, on that Mac: - the Sparkle signing key in the login keychain under account `byre` (`~/Library/Caches/byre/sparkle-/bin/generate_keys --account byre -p` prints its public key, which must match `SUPublicEDKey` in `mac/Info.plist`; `-x ` exports it for safekeeping). The script downloads Sparkle's tools to that cache directory when they are missing; - a g.fc.run token that can write the repo's releases, as the generic password with service `byre-release` (`security add-generic-password -s byre-release -a g.fc.run -w `). -The app checks `https://g.fc.run/misc/byre/releases/download/latest/appcast.xml` for updates (see "Updates" in `docs/macos.md`); Gitea serves the `latest` name from the newest release, so each release's appcast replaces the last. +The app checks `https://g.fc.run/ai/byre/releases/download/latest/appcast.xml` for updates (see "Updates" in `docs/macos.md`); Gitea serves the `latest` name from the newest release, so each release's appcast replaces the last. Clients reach `tailscale serve` over HTTP/2; it proxies to byre over HTTP/1.1 and passes SSE through unbuffered. ## macOS app -**Building.** `mac/bundle.sh`, from any directory, builds the release configuration with `swift build` in `~/Library/Caches/byre/build`, one build directory every worktree shares and takes turns in (`docs/macos.md`, "Stack", says why), and assembles `mac/.build/byre.app`: the `Byre` executable in `Contents/MacOS`; the server, built with `go build ./cmd/byre`, and `byre-hands`, built from `hands/`, in `Contents/Helpers` (not beside `Byre`: the default APFS volume ignores case, so `byre` and `Byre` would be one file); Sparkle's framework in `Contents/Frameworks`; `mac/Info.plist` with a `ByreCommit` key added holding the worktree's `git rev-parse HEAD`, `CFBundleShortVersionString` its `git describe --tags --always` without the leading `v` (`0.1.0` on a release tag, `0.1.0-12-gabc1234` after it) and `CFBundleVersion` its `git rev-list --count HEAD` (the About panel shows them as "Version ()", and Sparkle compares the count); the `mac/fonts/` woff2 files, an icon rendered from `mac/icon.svg` with `rsvg-convert` and `iconutil` (cached as `mac/.build/byre.icns` until the SVG changes) and `mac/byre.provisionprofile`. It signs each piece with the Developer ID Application certificate, a secure timestamp and the hardened runtime, innermost first: `byre-hands` as `run.fc.byre.hands` and the server as `run.fc.byre`, both with `mac/automation.entitlements` (Apple Events, which the hardened runtime otherwise refuses), Sparkle's `Autoupdate`, `Updater.app` and framework (its XPC services, only needed by sandboxed apps, are removed), then the bundle with `mac/byre.entitlements`. It prints the bundle's path. It needs Xcode selected (`xcode-select --print-path` prints `/Applications/Xcode.app/Contents/Developer`), Go, `rsvg-convert` (Homebrew's `librsvg`), the team's Developer ID Application certificate and network access for the timestamp, and it stops first unless `mac/byre.provisionprofile` has `ProvisionsAllDevices` (a Developer ID profile; a development profile can't authorize the Developer ID signature); `docs/macos.md`, "Signing", covers the certificate and profile. Debug builds are refused by an `#error` in `ByreApp.swift`. The first build on a Mac fetches the Swift packages pinned in `mac/Package.resolved` and compiles them and the generated API client; later builds, from any worktree, recompile only the targets whose sources differ from the last build's, usually just `Byre`. The API client is generated from `api/openapi.yaml` at build time. The palette is `mac/Sources/Byre/Palette.swift`, one light and one dark value per colour. +**Building.** `mac/bundle.sh`, from any directory, builds the release configuration with `swift build` in `~/Library/Caches/byre/build`, one build directory every worktree shares and takes turns in (`docs/macos.md`, "Stack", says why), and assembles `mac/.build/Byre.app`: the `Byre` executable in `Contents/MacOS`; the server, built with `go build ./cmd/byre`, and `byre-hands`, built from `hands/`, in `Contents/Helpers` (not beside `Byre`: the default APFS volume ignores case, so `byre` and `Byre` would be one file); Sparkle's framework in `Contents/Frameworks`; `mac/Info.plist` with a `ByreCommit` key added holding the worktree's `git rev-parse HEAD`, `CFBundleShortVersionString` its `git describe --tags --always` without the leading `v` (`0.1.0` on a release tag, `0.1.0-12-gabc1234` after it) and `CFBundleVersion` its `git rev-list --count HEAD` (the About panel shows them as "Version ()", and Sparkle compares the count); the `mac/fonts/` woff2 files, an icon rendered from `mac/icon.svg` with `rsvg-convert` and `iconutil` (cached as `mac/.build/byre.icns` until the SVG changes) and `mac/byre.provisionprofile`. It signs each piece with the Developer ID Application certificate, a secure timestamp and the hardened runtime, innermost first: `byre-hands` as `run.fc.byre.hands` and the server as `run.fc.byre`, both with `mac/automation.entitlements` (Apple Events, which the hardened runtime otherwise refuses), Sparkle's `Autoupdate`, `Updater.app` and framework (its XPC services, only needed by sandboxed apps, are removed), then the bundle with `mac/byre.entitlements`. It prints the bundle's path. It needs Xcode selected (`xcode-select --print-path` prints `/Applications/Xcode.app/Contents/Developer`), Go, `rsvg-convert` (Homebrew's `librsvg`), the team's Developer ID Application certificate and network access for the timestamp, and it stops first unless `mac/byre.provisionprofile` has `ProvisionsAllDevices` (a Developer ID profile; a development profile can't authorize the Developer ID signature); `docs/macos.md`, "Signing", covers the certificate and profile. Debug builds are refused by an `#error` in `ByreApp.swift`. The first build on a Mac fetches the Swift packages pinned in `mac/Package.resolved` and compiles them and the generated API client; later builds, from any worktree, recompile only the targets whose sources differ from the last build's, usually just `Byre`. The API client is generated from `api/openapi.yaml` at build time. The palette is `mac/Sources/Byre/Palette.swift`, one light and one dark value per colour. -**Installing.** A release is installed from its disk image into `/Applications` (see "Releases") and updates itself (`docs/macos.md`, "Updates"). A build from a checkout runs from where it was built: `open mac/.build/byre.app` in the worktree that built it. A new build replaces the bundle, so quit the running app first (`pkill -x Byre` quits every running copy, whichever worktree built it) and open the new one; step 4 of "Deploying" in `AGENTS.md` does this after a deploy. Every build shares the bundle identifier `run.fc.byre.mac` and the same store, so any build reconnects to the server the last one used. Closing the window leaves the app running for notifications; ⌘Q quits it. +**Installing.** A release is installed from its disk image into `/Applications` (see "Releases") and updates itself (`docs/macos.md`, "Updates"). A build from a checkout runs from where it was built: `open mac/.build/Byre.app` in the worktree that built it. A new build replaces the bundle, so quit the running app first (`pkill -x Byre` quits every running copy, whichever worktree built it) and open the new one; step 4 of "Deploying" in `AGENTS.md` does this after a deploy. Every build shares the bundle identifier `run.fc.byre.mac` and the same store, so any build reconnects to the server the last one used. Closing the window leaves the app running for notifications; ⌘Q quits it. **Storage.** The app keeps three kinds of record in SwiftData (`mac/Sources/Byre/Persistence.swift`): the server origin, when each task was last selected, and composer and answer drafts as JSON, one record per server and login (`docs/macos.md`, "Persistence" and "Drafts"). The store is `~/Library/Application Support/run.fc.byre.mac/byre.store`, with its `-shm` and `-wal` files and CloudKit's working files beside it in that directory; the app isn't sandboxed, so it names its own file rather than SwiftData's default `default.store`, which every unsandboxed app shares. The store syncs through the iCloud private database of container `iCloud.run.fc.byre.mac`, in CloudKit's Production environment (`com.apple.developer.icloud-container-environment` in `mac/byre.entitlements`), whose schema is deployed from Development in the CloudKit console before a release that changes the SwiftData models; the CloudKit console (icloud.developer.apple.com, the container, Production, Private Database, zone `com.apple.coredata.cloudkit.zone`) shows the records. Deleting the local files while the app isn't running makes the next launch download the records again from iCloud; deleting the records in the console as well starts from the connection screen. Pasted images stay in memory and are dropped on Change Server… and quit. The app logs through `os.Logger`: `log show --last 10m --predicate 'subsystem == "run.fc.byre.mac"'` prints it. @@ -351,7 +351,7 @@ Implementer sessions get eight MCP tools for it (`internal/agents/clients.go`). `client_read`, `client_write` and `client_edit` wait at most 2 minutes for each reply, and their paths, like `client_download`'s `path`, are absolute or start with `~/`, which the app expands. - `client_hands`: `op: hands`, with `tool` and `arguments` as the `hands` tools take them (see "Screen and app control"). The app runs one `byre-hands`, bundled at `Contents/Helpers/byre-hands`, started on first use and again after it exits, writes each call to its stdin as a `tools/call` line and replies with the line's `result`, which byre returns to the agent as the tool's result, images included (`mcp.Tool.Rich`; Codex gets them as `inputImage` data URLs). The macOS privacy grants it needs (Screen Recording, Accessibility, Automation of Orion) belong to byre's app on that Mac, since the app is the responsible process; `NSAppleEventsUsageDescription` in `mac/Info.plist` is what lets macOS ask for the Automation grant. Each `byre-hands` process has its own pending calls, so one that exits fails only the calls sent to it. -A byre restart drops every connection; each app reconnects 2s later, and calls in flight at the restart fail as disconnected. Updating a client's app goes through the tools themselves: `client_upload` the new `byre.app`, then `client_bash` a command that quits the old app and opens the new one, which outlives the app and reconnects. An app that doesn't know the `upload` op can't be updated this way, so its update is by hand. +A byre restart drops every connection; each app reconnects 2s later, and calls in flight at the restart fail as disconnected. Updating a client's app goes through the tools themselves: `client_upload` the new `Byre.app`, then `client_bash` a command that quits the old app and opens the new one, which outlives the app and reconnects. An app that doesn't know the `upload` op can't be updated this way, so its update is by hand. `log show --info --last 10m --predicate 'subsystem == "run.fc.byre.mac"'` on a client shows `client request : ` lines and `byre-hands` starts and exits, which are info level and kept only in memory, so they cover the last few minutes at most; connection drops (`client connection closed`, `client connection got no pong`) are notices, which macOS keeps on disk, so `log show --start` reaches much further back for them; byre's log shows `client connected` and `client disconnected`. diff --git a/go.mod b/go.mod index a415803..fc5e5e1 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module g.fc.run/misc/byre +module g.fc.run/ai/byre go 1.26.0 diff --git a/internal/agents/afterreview.go b/internal/agents/afterreview.go index 645b446..2823a29 100644 --- a/internal/agents/afterreview.go +++ b/internal/agents/afterreview.go @@ -6,8 +6,8 @@ import ( "fmt" "log/slog" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/store" ) func (m *Manager) MergeAfterReview(ctx context.Context, task api.Task, user api.User, target api.MergeTaskJSONBodyTarget, title string) (api.Task, error) { diff --git a/internal/agents/clients.go b/internal/agents/clients.go index ca87feb..269fd2e 100644 --- a/internal/agents/clients.go +++ b/internal/agents/clients.go @@ -15,9 +15,9 @@ import ( "time" "unicode/utf8" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/clients" - "g.fc.run/misc/byre/internal/mcp" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/clients" + "g.fc.run/ai/byre/internal/mcp" ) const ( @@ -69,7 +69,7 @@ func (m *Manager) clientTools(l *live) []mcp.Tool { "properties": { "client": {"type": "string", "description": "The client's name from list_clients, or its id when several are connected from that Mac."}, "path": {"type": "string", "description": "The file or directory, relative to your worktree."}, - "dest": {"type": "string", "description": "Its new path on the client, absolute or starting with ~/, e.g. ~/Applications/byre.app."} + "dest": {"type": "string", "description": "Its new path on the client, absolute or starting with ~/, e.g. ~/Applications/Byre.app."} }, "required": ["client", "path", "dest"] }`), diff --git a/internal/agents/codex.go b/internal/agents/codex.go index 8080be4..2eb5bd1 100644 --- a/internal/agents/codex.go +++ b/internal/agents/codex.go @@ -8,8 +8,8 @@ import ( "strings" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/codex" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/codex" ) var codexToolItems = map[string]bool{ diff --git a/internal/agents/compact.go b/internal/agents/compact.go index 5b9faf0..85ed24a 100644 --- a/internal/agents/compact.go +++ b/internal/agents/compact.go @@ -6,8 +6,8 @@ import ( "log/slog" "strings" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/store" ) const handoffPrompt = `Write a handoff for a fresh agent that will continue this task with none of your context. ` + diff --git a/internal/agents/critical.go b/internal/agents/critical.go index 4fe266f..363fb65 100644 --- a/internal/agents/critical.go +++ b/internal/agents/critical.go @@ -4,8 +4,8 @@ import ( "context" "log/slog" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/git" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/git" ) type mergeTurn struct { diff --git a/internal/agents/fork.go b/internal/agents/fork.go index 576c6bc..40561e8 100644 --- a/internal/agents/fork.go +++ b/internal/agents/fork.go @@ -5,8 +5,8 @@ import ( "fmt" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/store" ) func (m *Manager) Fork(ctx context.Context, src api.Task, project api.Project, n int, creator api.User) (api.Task, error) { diff --git a/internal/agents/guidance.go b/internal/agents/guidance.go index b124a52..5e58777 100644 --- a/internal/agents/guidance.go +++ b/internal/agents/guidance.go @@ -8,10 +8,10 @@ import ( "strings" "unicode/utf8" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/claude" - "g.fc.run/misc/byre/internal/store" - "g.fc.run/misc/byre/internal/todo" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/claude" + "g.fc.run/ai/byre/internal/store" + "g.fc.run/ai/byre/internal/todo" ) const guidance = `You are running inside byre. The human reads your work in byre's app, not a terminal. diff --git a/internal/agents/hands.go b/internal/agents/hands.go index a48e595..5fe3c97 100644 --- a/internal/agents/hands.go +++ b/internal/agents/hands.go @@ -5,7 +5,7 @@ import ( "os/exec" "path/filepath" - "g.fc.run/misc/byre/internal/mcp" + "g.fc.run/ai/byre/internal/mcp" ) const screenshotGuidance = "\n- When a turn changes something you can see, you can show it in your final message: save screenshots with the Playwright tools (pages you serve on this task's ports) or hands' capture with save (apps on this Mac), and embed each as a Markdown image, ![what it shows](), with the path the tool returned. They go to the task's media folder, outside the worktree, so they are never committed, and are deleted when the task closes. Leave out a screenshot that adds nothing to the text." diff --git a/internal/agents/health.go b/internal/agents/health.go index 3bc1872..b0d3e53 100644 --- a/internal/agents/health.go +++ b/internal/agents/health.go @@ -18,7 +18,7 @@ import ( "syscall" "time" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) const ( diff --git a/internal/agents/inbox.go b/internal/agents/inbox.go index 27078e7..eca515e 100644 --- a/internal/agents/inbox.go +++ b/internal/agents/inbox.go @@ -10,9 +10,9 @@ import ( "strings" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" ) var attachmentKinds = []api.AttachmentKind{ diff --git a/internal/agents/lead.go b/internal/agents/lead.go index 9ef1261..6e6637d 100644 --- a/internal/agents/lead.go +++ b/internal/agents/lead.go @@ -9,9 +9,9 @@ import ( "strings" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/store" - "g.fc.run/misc/byre/internal/workflow" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/store" + "g.fc.run/ai/byre/internal/workflow" ) const leadGuidance = `You are the human's lead agent in byre, shown in the left pane of byre's app. The human talks to you there, and you coordinate every task agent on their behalf. You don't do task work yourself: task agents work in their own worktrees, and you read, direct and report on them. diff --git a/internal/agents/leadnotes.go b/internal/agents/leadnotes.go index 3cedd74..e547348 100644 --- a/internal/agents/leadnotes.go +++ b/internal/agents/leadnotes.go @@ -7,9 +7,9 @@ import ( "fmt" "strings" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" ) func (m *Manager) noteTools(tool func(name, description, schema string, run func(ctx context.Context, user api.User, raw json.RawMessage) (string, error)) mcp.Tool) []mcp.Tool { diff --git a/internal/agents/leadtools.go b/internal/agents/leadtools.go index 7ee2396..4290a7b 100644 --- a/internal/agents/leadtools.go +++ b/internal/agents/leadtools.go @@ -10,11 +10,11 @@ import ( "strings" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/git" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" - "g.fc.run/misc/byre/internal/todo" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/git" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" + "g.fc.run/ai/byre/internal/todo" ) func (m *Manager) leadTools(l *live) []mcp.Tool { diff --git a/internal/agents/manager.go b/internal/agents/manager.go index 91fdb56..3e9ef2d 100644 --- a/internal/agents/manager.go +++ b/internal/agents/manager.go @@ -14,14 +14,14 @@ import ( "sync" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/claude" - "g.fc.run/misc/byre/internal/clients" - "g.fc.run/misc/byre/internal/git" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" - "g.fc.run/misc/byre/internal/terminal" - "g.fc.run/misc/byre/internal/workflow" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/claude" + "g.fc.run/ai/byre/internal/clients" + "g.fc.run/ai/byre/internal/git" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" + "g.fc.run/ai/byre/internal/terminal" + "g.fc.run/ai/byre/internal/workflow" ) var ( diff --git a/internal/agents/mergein.go b/internal/agents/mergein.go index c4d4470..653ee0a 100644 --- a/internal/agents/mergein.go +++ b/internal/agents/mergein.go @@ -12,10 +12,10 @@ import ( "sync" "unicode/utf8" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/git" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/git" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" ) const maxMergeTitle = 72 diff --git a/internal/agents/notes.go b/internal/agents/notes.go index 6c32588..d132272 100644 --- a/internal/agents/notes.go +++ b/internal/agents/notes.go @@ -6,8 +6,8 @@ import ( "strings" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/store" ) func (m *Manager) mergeNote(ctx context.Context, task api.Task, login string) (string, error) { diff --git a/internal/agents/preview.go b/internal/agents/preview.go index f170f18..5a0adfa 100644 --- a/internal/agents/preview.go +++ b/internal/agents/preview.go @@ -12,10 +12,10 @@ import ( "time" "unicode/utf8" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" - "g.fc.run/misc/byre/internal/tailscale" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" + "g.fc.run/ai/byre/internal/tailscale" ) const maxPreviewName = 40 diff --git a/internal/agents/process.go b/internal/agents/process.go index 5cdc80a..6389ae0 100644 --- a/internal/agents/process.go +++ b/internal/agents/process.go @@ -7,11 +7,11 @@ import ( "os" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/claude" - "g.fc.run/misc/byre/internal/codex" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/workflow" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/claude" + "g.fc.run/ai/byre/internal/codex" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/workflow" ) type image struct { diff --git a/internal/agents/queue.go b/internal/agents/queue.go index 55fb0d9..18879a0 100644 --- a/internal/agents/queue.go +++ b/internal/agents/queue.go @@ -8,8 +8,8 @@ import ( "strings" "sync" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/store" ) type sessionLock struct { diff --git a/internal/agents/respond.go b/internal/agents/respond.go index 280b5a9..b8921a4 100644 --- a/internal/agents/respond.go +++ b/internal/agents/respond.go @@ -9,8 +9,8 @@ import ( "strings" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/store" ) func (m *Manager) Respond(ctx context.Context, user string, creates []api.InboxResponseCreate) ([]api.InboxItem, error) { diff --git a/internal/agents/review.go b/internal/agents/review.go index 90fbf3e..b2b85a3 100644 --- a/internal/agents/review.go +++ b/internal/agents/review.go @@ -12,10 +12,10 @@ import ( "strings" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/git" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/git" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" ) const maxReviewFiles = 200 diff --git a/internal/agents/snapshots.go b/internal/agents/snapshots.go index 6143b91..bd2b9d7 100644 --- a/internal/agents/snapshots.go +++ b/internal/agents/snapshots.go @@ -9,11 +9,11 @@ import ( "sync" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/claude" - "g.fc.run/misc/byre/internal/git" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/claude" + "g.fc.run/ai/byre/internal/git" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" ) type snapRequest struct { diff --git a/internal/agents/subtasks.go b/internal/agents/subtasks.go index 907169a..8f4b7f8 100644 --- a/internal/agents/subtasks.go +++ b/internal/agents/subtasks.go @@ -8,10 +8,10 @@ import ( "log/slog" "strings" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/git" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/git" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" ) func (m *Manager) subtaskTools(l *live) []mcp.Tool { diff --git a/internal/agents/summary.go b/internal/agents/summary.go index 3f14d09..0b923e0 100644 --- a/internal/agents/summary.go +++ b/internal/agents/summary.go @@ -9,9 +9,9 @@ import ( "strings" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" ) const summaryRequest = "Call set_task_summary with a summary of the whole task, not just this turn, for whoever searches closed tasks later: what it set out to do, what was built or tried, the key decisions and why, and what was deliberately left out." diff --git a/internal/agents/tasks.go b/internal/agents/tasks.go index 78eeb58..4e15b59 100644 --- a/internal/agents/tasks.go +++ b/internal/agents/tasks.go @@ -8,10 +8,10 @@ import ( "path/filepath" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/git" - "g.fc.run/misc/byre/internal/store" - "g.fc.run/misc/byre/internal/todo" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/git" + "g.fc.run/ai/byre/internal/store" + "g.fc.run/ai/byre/internal/todo" ) func (m *Manager) CreateTask(ctx context.Context, project api.Project, title, createdBy, base, actor string) (api.Task, error) { diff --git a/internal/agents/team.go b/internal/agents/team.go index e7a7fbc..24f082b 100644 --- a/internal/agents/team.go +++ b/internal/agents/team.go @@ -8,10 +8,10 @@ import ( "log/slog" "strings" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" - "g.fc.run/misc/byre/internal/workflow" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" + "g.fc.run/ai/byre/internal/workflow" ) const boardActor = "board" diff --git a/internal/agents/terminal.go b/internal/agents/terminal.go index 1acf749..32f37a8 100644 --- a/internal/agents/terminal.go +++ b/internal/agents/terminal.go @@ -8,9 +8,9 @@ import ( "sync/atomic" "time" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/terminal" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/terminal" ) const ( diff --git a/internal/agents/workflows.go b/internal/agents/workflows.go index 0ec830f..6bc4956 100644 --- a/internal/agents/workflows.go +++ b/internal/agents/workflows.go @@ -8,11 +8,11 @@ import ( "log/slog" "strings" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/git" - "g.fc.run/misc/byre/internal/mcp" - "g.fc.run/misc/byre/internal/store" - "g.fc.run/misc/byre/internal/workflow" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/git" + "g.fc.run/ai/byre/internal/mcp" + "g.fc.run/ai/byre/internal/store" + "g.fc.run/ai/byre/internal/workflow" ) func (m *Manager) SaveWorkflow(ctx context.Context, name string, file []byte, actor string) (api.WorkflowSummary, error) { diff --git a/internal/claude/session.go b/internal/claude/session.go index 989f155..59e0bbf 100644 --- a/internal/claude/session.go +++ b/internal/claude/session.go @@ -18,7 +18,7 @@ import ( "sync/atomic" "time" - "g.fc.run/misc/byre/internal/mcp" + "g.fc.run/ai/byre/internal/mcp" ) type HookFunc func(ctx context.Context, input json.RawMessage) (map[string]any, error) diff --git a/internal/clients/clients.go b/internal/clients/clients.go index 6797713..927031f 100644 --- a/internal/clients/clients.go +++ b/internal/clients/clients.go @@ -15,7 +15,7 @@ import ( "github.com/coder/websocket" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) const ( diff --git a/internal/codex/session.go b/internal/codex/session.go index 6affc8c..d2db3ef 100644 --- a/internal/codex/session.go +++ b/internal/codex/session.go @@ -18,7 +18,7 @@ import ( "sync/atomic" "time" - "g.fc.run/misc/byre/internal/mcp" + "g.fc.run/ai/byre/internal/mcp" ) type Options struct { diff --git a/internal/git/changes.go b/internal/git/changes.go index 2621dac..0193300 100644 --- a/internal/git/changes.go +++ b/internal/git/changes.go @@ -6,7 +6,7 @@ import ( "strconv" "strings" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) var statuses = map[byte]api.FileChangeStatus{ diff --git a/internal/server/blobs.go b/internal/server/blobs.go index a05e594..ad5081a 100644 --- a/internal/server/blobs.go +++ b/internal/server/blobs.go @@ -7,7 +7,7 @@ import ( "net/http" "os" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/store" ) func (s *Server) UploadBlob(w http.ResponseWriter, r *http.Request) { diff --git a/internal/server/changes.go b/internal/server/changes.go index e6d7127..f9b0b26 100644 --- a/internal/server/changes.go +++ b/internal/server/changes.go @@ -6,8 +6,8 @@ import ( "net/http" "regexp" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/git" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/git" ) var objectID = regexp.MustCompile(`^[0-9a-f]{40}([0-9a-f]{24})?$`) diff --git a/internal/server/files.go b/internal/server/files.go index ddb3123..3400e5c 100644 --- a/internal/server/files.go +++ b/internal/server/files.go @@ -14,8 +14,8 @@ import ( "strings" "unicode/utf8" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/git" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/git" ) const ( diff --git a/internal/server/hub.go b/internal/server/hub.go index b92be50..288a54e 100644 --- a/internal/server/hub.go +++ b/internal/server/hub.go @@ -3,7 +3,7 @@ package server import ( "sync" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) type hub struct { diff --git a/internal/server/images.go b/internal/server/images.go index 9944760..98f6487 100644 --- a/internal/server/images.go +++ b/internal/server/images.go @@ -9,8 +9,8 @@ import ( "path/filepath" "strings" - "g.fc.run/misc/byre/internal/agents" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/agents" + "g.fc.run/ai/byre/internal/api" ) var worktreeImageTypes = map[string]string{ diff --git a/internal/server/inbox.go b/internal/server/inbox.go index 9acc9ac..78152f8 100644 --- a/internal/server/inbox.go +++ b/internal/server/inbox.go @@ -3,8 +3,8 @@ package server import ( "net/http" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/store" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/store" ) func (s *Server) ListInbox(w http.ResponseWriter, r *http.Request, params api.ListInboxParams) { diff --git a/internal/server/lead.go b/internal/server/lead.go index d4fc039..f39879f 100644 --- a/internal/server/lead.go +++ b/internal/server/lead.go @@ -6,7 +6,7 @@ import ( "net/http" "strings" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) func (s *Server) ListLeadSessions(w http.ResponseWriter, r *http.Request) { diff --git a/internal/server/notifications.go b/internal/server/notifications.go index 2ba6848..c267712 100644 --- a/internal/server/notifications.go +++ b/internal/server/notifications.go @@ -5,7 +5,7 @@ import ( "net/http" "strings" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) func (s *Server) UpdateNotificationPrefs(w http.ResponseWriter, r *http.Request) { diff --git a/internal/server/reviews.go b/internal/server/reviews.go index cfb5d9c..4a66384 100644 --- a/internal/server/reviews.go +++ b/internal/server/reviews.go @@ -4,7 +4,7 @@ import ( "errors" "net/http" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) func (s *Server) ListReviews(w http.ResponseWriter, r *http.Request, taskID string) { diff --git a/internal/server/server.go b/internal/server/server.go index 0fc8620..aa566db 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -14,14 +14,14 @@ import ( "sync" "time" - "g.fc.run/misc/byre/internal/agents" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/clients" - "g.fc.run/misc/byre/internal/git" - "g.fc.run/misc/byre/internal/store" - "g.fc.run/misc/byre/internal/terminal" - "g.fc.run/misc/byre/internal/todo" - "g.fc.run/misc/byre/internal/workflow" + "g.fc.run/ai/byre/internal/agents" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/clients" + "g.fc.run/ai/byre/internal/git" + "g.fc.run/ai/byre/internal/store" + "g.fc.run/ai/byre/internal/terminal" + "g.fc.run/ai/byre/internal/todo" + "g.fc.run/ai/byre/internal/workflow" ) type Server struct { diff --git a/internal/server/sse.go b/internal/server/sse.go index 5529c86..6a1703a 100644 --- a/internal/server/sse.go +++ b/internal/server/sse.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) const backfillPage = 500 diff --git a/internal/server/terminal.go b/internal/server/terminal.go index d0a215d..a539d62 100644 --- a/internal/server/terminal.go +++ b/internal/server/terminal.go @@ -9,8 +9,8 @@ import ( "github.com/coder/websocket" - "g.fc.run/misc/byre/internal/api" - "g.fc.run/misc/byre/internal/terminal" + "g.fc.run/ai/byre/internal/api" + "g.fc.run/ai/byre/internal/terminal" ) const ( diff --git a/internal/server/workflows.go b/internal/server/workflows.go index 04da247..7a46a5f 100644 --- a/internal/server/workflows.go +++ b/internal/server/workflows.go @@ -6,7 +6,7 @@ import ( "net/http" "net/url" - "g.fc.run/misc/byre/internal/workflow" + "g.fc.run/ai/byre/internal/workflow" ) const maxWorkflowFileBytes = 1 << 20 diff --git a/internal/store/blob.go b/internal/store/blob.go index 7595ead..262ff49 100644 --- a/internal/store/blob.go +++ b/internal/store/blob.go @@ -8,7 +8,7 @@ import ( "path/filepath" "time" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) const MaxBlobBytes = 5 << 20 diff --git a/internal/store/discard.go b/internal/store/discard.go index 903f2d6..e99ef9b 100644 --- a/internal/store/discard.go +++ b/internal/store/discard.go @@ -6,7 +6,7 @@ import ( "errors" "fmt" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) type DiscardState string diff --git a/internal/store/inbox.go b/internal/store/inbox.go index ab0f5cc..6a73031 100644 --- a/internal/store/inbox.go +++ b/internal/store/inbox.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) func (s *Store) CreateInboxItem(ctx context.Context, item api.InboxItem) error { diff --git a/internal/store/lead.go b/internal/store/lead.go index fcbd7fc..73cb5b9 100644 --- a/internal/store/lead.go +++ b/internal/store/lead.go @@ -7,7 +7,7 @@ import ( "errors" "time" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) type LeadInputKind string diff --git a/internal/store/leadnotes.go b/internal/store/leadnotes.go index 4dca113..33486da 100644 --- a/internal/store/leadnotes.go +++ b/internal/store/leadnotes.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) func (s *Store) LeadNotes(ctx context.Context, owner string) ([]api.LeadNote, error) { diff --git a/internal/store/notifications.go b/internal/store/notifications.go index 57cd5bc..0accfb8 100644 --- a/internal/store/notifications.go +++ b/internal/store/notifications.go @@ -5,7 +5,7 @@ import ( "database/sql" "encoding/json" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) func (s *Store) UpdateNotificationPrefs(ctx context.Context, login string, prefs api.NotificationPrefs) (api.User, error) { diff --git a/internal/store/preview.go b/internal/store/preview.go index 1680003..240cbfb 100644 --- a/internal/store/preview.go +++ b/internal/store/preview.go @@ -5,7 +5,7 @@ import ( "database/sql" "errors" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) const previewColumns = `task_id, name, port, created_at` diff --git a/internal/store/review.go b/internal/store/review.go index 4bc88c6..9ee0cb6 100644 --- a/internal/store/review.go +++ b/internal/store/review.go @@ -7,7 +7,7 @@ import ( "errors" "time" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) const reviewColumns = `id, task_id, snapshot_n, coalesce(agent_session_id, ''), vendor, model, state, result, error, created_at, finished_at, finding_states` diff --git a/internal/store/snapshot.go b/internal/store/snapshot.go index e48fbd2..2589513 100644 --- a/internal/store/snapshot.go +++ b/internal/store/snapshot.go @@ -5,7 +5,7 @@ import ( "database/sql" "errors" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) const snapshotColumns = `id, task_id, agent_session_id, n, commit_sha, tree_sha, event_seq, trigger, created_at` diff --git a/internal/store/store.go b/internal/store/store.go index 19e4116..8e5f2bf 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -14,7 +14,7 @@ import ( _ "modernc.org/sqlite" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) var ErrNotFound = errors.New("not found") diff --git a/internal/store/summaryreads.go b/internal/store/summaryreads.go index 89bd14f..b79448c 100644 --- a/internal/store/summaryreads.go +++ b/internal/store/summaryreads.go @@ -6,7 +6,7 @@ import ( "errors" "fmt" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) func (s *Store) SummaryReads(ctx context.Context, login string) (map[string]int64, error) { diff --git a/internal/store/workflow.go b/internal/store/workflow.go index 2a85d8e..0dbcf0d 100644 --- a/internal/store/workflow.go +++ b/internal/store/workflow.go @@ -7,7 +7,7 @@ import ( "errors" "fmt" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) type FrozenWorkflow struct { diff --git a/internal/terminal/terminal.go b/internal/terminal/terminal.go index 5f6b328..4d4c9f4 100644 --- a/internal/terminal/terminal.go +++ b/internal/terminal/terminal.go @@ -12,7 +12,7 @@ import ( "github.com/creack/pty" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) const ( diff --git a/internal/todo/todo.go b/internal/todo/todo.go index 4c2b960..f0a4dca 100644 --- a/internal/todo/todo.go +++ b/internal/todo/todo.go @@ -4,7 +4,7 @@ import ( "regexp" "strings" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) const File = "TODO.md" diff --git a/internal/workflow/file.go b/internal/workflow/file.go index 4719b00..6bd2515 100644 --- a/internal/workflow/file.go +++ b/internal/workflow/file.go @@ -9,7 +9,7 @@ import ( "go.yaml.in/yaml/v3" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) var keyOrder = []string{"description", "stages", "name", "after", "base", "model", "prompt"} diff --git a/internal/workflow/workflow.go b/internal/workflow/workflow.go index 9ee6708..f7ea86f 100644 --- a/internal/workflow/workflow.go +++ b/internal/workflow/workflow.go @@ -7,7 +7,7 @@ import ( "unicode" "unicode/utf8" - "g.fc.run/misc/byre/internal/api" + "g.fc.run/ai/byre/internal/api" ) var ErrInvalid = errors.New("invalid workflow") diff --git a/mac/Info.plist b/mac/Info.plist index 5e05fdd..dbe647b 100644 --- a/mac/Info.plist +++ b/mac/Info.plist @@ -5,7 +5,7 @@ CFBundleIdentifier run.fc.byre.mac CFBundleName - byre + Byre CFBundleExecutable Byre CFBundlePackageType @@ -17,7 +17,7 @@ NSHighResolutionCapable SUFeedURL - https://g.fc.run/misc/byre/releases/download/latest/appcast.xml + https://g.fc.run/ai/byre/releases/download/latest/appcast.xml SUPublicEDKey 350+qbxFCpm+LhbRlCxtBHST+FTz6o19jhGOSs8D0XU= SUEnableAutomaticChecks diff --git a/mac/bundle.sh b/mac/bundle.sh index 2798fe5..401d2d3 100755 --- a/mac/bundle.sh +++ b/mac/bundle.sh @@ -4,7 +4,7 @@ mac=$(cd "$(dirname "$0")" && pwd) root=$(dirname "$mac") shared=$HOME/Library/Caches/byre/build build=$mac/.build -app=$build/byre.app +app=$build/Byre.app svg=$mac/icon.svg icns=$build/byre.icns identity="Developer ID Application" diff --git a/mac/release.sh b/mac/release.sh index f393e25..174e2c9 100755 --- a/mac/release.sh +++ b/mac/release.sh @@ -2,7 +2,7 @@ set -eu mac=$(cd "$(dirname "$0")" && pwd) root=$(dirname "$mac") -repo=misc/byre +repo=ai/byre api=https://g.fc.run/api/v1/repos/$repo sparkle_version=2.10.0 sparkle=$HOME/Library/Caches/byre/sparkle-$sparkle_version @@ -27,7 +27,7 @@ if [ ! -x "$sparkle/bin/sign_update" ]; then fi "$mac/bundle.sh" -app=$mac/.build/byre.app +app=$mac/.build/Byre.app out=$mac/.build/release/$version rm -rf "$out" mkdir -p "$out" @@ -40,7 +40,7 @@ rm "$out/byre.zip" dmg=byre-$version.dmg stage=$out/stage mkdir "$stage" -ditto "$app" "$stage/byre.app" +ditto "$app" "$stage/Byre.app" ln -s /Applications "$stage/Applications" hdiutil create -volname byre -srcfolder "$stage" -format UDZO "$out/$dmg" rm -rf "$stage"