From 681cc2b09099428c00201255bbbc36a14a4d3e0a Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Fri, 23 Oct 2026 18:36:11 -0700 Subject: [PATCH] Fix wording, docs and style inconsistencies per audit of 0139564 --- api/openapi.yaml | 27 +- cmd/byre/clientexec.go | 1 + cmd/byre/grep.go | 1 + cmd/byre/list.go | 4 +- docs/antigravity-protocol.md | 2 +- docs/claude-protocol.md | 4 +- docs/operations.md | 2 +- hands/Sources/byre-hands/Tools.swift | 4 +- internal/agents/audit.go | 2 +- internal/agents/clients.go | 3 +- internal/agents/codex.go | 3 +- internal/agents/hands.go | 3 +- internal/agents/imagegen.go | 7 +- internal/agents/inbox.go | 2 +- internal/agents/kb/client-exec.md | 2 +- internal/agents/lead.go | 2 +- internal/agents/workflows.go | 2 +- internal/api/api.gen.go | 751 ++++++++++++++------------- internal/claude/session.go | 2 +- internal/codex/session.go | 2 +- internal/git/changes.go | 5 +- internal/hookcmd/hookcmd.go | 2 +- internal/server/lead.go | 8 +- internal/server/server.go | 2 +- internal/store/blob.go | 3 +- internal/store/leadnotes.go | 4 +- internal/store/savedcommands.go | 6 +- internal/store/schedule.go | 4 +- internal/store/summaryreads.go | 2 +- internal/workflow/parse.go | 2 +- mac/Sources/Byre/Composer.swift | 2 +- mac/Sources/Byre/Files.swift | 2 +- mac/Sources/Byre/MarkdownView.swift | 2 +- mac/Sources/Byre/Questions.swift | 2 +- mac/Sources/Byre/QuickRun.swift | 4 +- mac/Sources/Byre/Startup.swift | 11 +- mac/Sources/Byre/Store.swift | 2 +- mac/Sources/Byre/Switcher.swift | 2 +- mac/Sources/Byre/Updater.swift | 8 +- mac/Sources/Byre/Workflow.swift | 13 +- mac/bundle.sh | 2 +- site/index.html | 8 +- 42 files changed, 469 insertions(+), 453 deletions(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index 59fa9b7..7550b9c 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -30,7 +30,7 @@ paths: /api/me/notifications: put: operationId: updateNotificationPrefs - description: Sets which new questions, finished turns, errors and rate limits notify the calling user in their open byre pages. + description: "Sets which task events notify the calling user in the app: questions, turn summaries, errors, rate limits, ready to merge, discard suggestions, merge problems and finished workflows." requestBody: required: true content: @@ -588,7 +588,7 @@ paths: post: operationId: mergeTask description: > - Sets the task's merge_title to the confirmed title, then starts the same agent turn as merge-in, without + Sets the task's merge_title to the confirmed title, then starts the same agent turn as mergeIn, without its invitation to revise the title. When that turn ends normally, byre squashes the task's worktree into one commit titled with the task's merge_title on the project's default branch, authored by the caller with a Co-authored-by trailer for each of the task's co-authors, pushes it to origin, fast-forwards the project's @@ -982,8 +982,9 @@ paths: description: > Creates a new task whose branch and worktree start from the snapshot's commit, with an idle agent session that continues the snapshot's agent conversation as it stood at the snapshot (the vendor's own session fork). The - new session's first turn is the first message sent to it. Refused while the task is closed, and for a snapshot - with no recorded agent message at or before it. + new session's first turn is the first message sent to it. Refused while the task is closed, for a snapshot + with no recorded agent message at or before it, and for a snapshot of an Antigravity session (agy can't fork + a conversation). responses: "201": description: The new task. @@ -1079,7 +1080,7 @@ paths: schema: { $ref: "#/components/schemas/MessageCreate" } responses: "202": - description: The turn has started. + description: The session the message started a turn in or is queued for. content: application/json: schema: { $ref: "#/components/schemas/AgentSession" } @@ -1226,7 +1227,7 @@ paths: get: operationId: connectClient description: > - A WebSocket over which task agents use this Mac: the server sends ClientRequest text messages and the client + A WebSocket over which task agents use the connecting Mac: the server sends ClientRequest text messages and the client answers each with a ClientReply text message carrying the same id, in any order. The Byre-Host header names the client, percent-encoded since device names hold characters such as ’ that headers can't carry; a newer connection from the same host replaces the older one. @@ -1532,7 +1533,7 @@ components: NotificationPrefs: type: object - description: Which task events notify this user in the macOS app. + description: Which task events notify this user in the app. required: [questions, reports, errors, rate_limits, ready, discard, merge_problems, workflows] properties: questions: { type: boolean, description: Questions. On by default. } @@ -1598,7 +1599,7 @@ components: workflow: { type: string, description: "For a workflow run's task: the name of the workflow it froze at creation (getWorkflowRun has its copy). A run's task has no agent, worktree or branch (branch, worktree_path and base_ref are empty); its stage tasks are its subtasks, and it closes once they all have, as merged when any of them merged. Absent for other tasks." } workflow_stage: { type: string, description: "For a stage task of a workflow run: the name of the stage it runs; parent_task_id is the run's task. Absent for other tasks." } audit: { type: string, description: "The default branch commit an audit audits, on the task of a run of its project's audit workflow; absent for other tasks." } - background: { type: boolean, description: "Whether the task is an audit's run or stage task that hasn't asked for attention yet: no question, ready_for_merge or error so far (for a run, from any of its stage tasks). The app keeps it out of the task switcher and shows it muted on the project's dashboard, and the lead gets no signals about it." } + background: { type: boolean, description: "Whether the task is an audit's run or stage task that hasn't asked for attention yet: no question, ready_for_merge, suggest_discard (unless its workflow has auto_discard), error or rate limit so far (for a run, from any of its stage tasks). The app keeps it out of the task switcher and shows it muted on the project's dashboard, and the lead gets no signals about it." } state: type: string description: "The one state the task is in, kept by the store in the same transaction as every change to it (a task.state event carries each change). The first that holds: merged or discarded once closed; for a workflow run's task, finished once the run finished, running while one of its stage tasks is running, else idle; discarding; asking while it has an open question; pushing once a Merge's turn has ended and byre is pushing its squash commit to the remote (a task.pushing event names the commit); merging while a Merge or a merge into its parent is otherwise under way; merge_held while its Merge waits for another merge in the project; merge_after_review while a Merge with after_review waits for its review; running while one of its agents is mid-turn or has subagents running; reviewing while a review runs; review_pending between a turn's end and its snapshot's review starting or being skipped; ready_to_merge or discard_suggested when the agent's latest ready_for_merge or suggest_discard still stands; finished when it runs a workflow stage whose finish_stage has taken; idle; no_agent when it has no live agent." @@ -1654,7 +1655,7 @@ components: required: [unmerged_commits, unmerged_files, unreviewed_changes, review_snapshot, review_count, review_running, review_failed, review_findings, participants] properties: unmerged_commits: { type: integer, description: Commits on the task branch that aren't on the default branch. } - unmerged_files: { type: integer, description: "Files that differ from the merge base, uncommitted changes included." } + unmerged_files: { type: integer, description: "Files that differ from the merge-base, uncommitted changes included." } unreviewed_changes: { type: boolean, description: Whether the worktree differs from the latest reviewable snapshot. } review_snapshot: { type: integer, description: "The n of the latest snapshot that isn't a cut point (answer, fork, ask_human); 0 when there is none." } review_count: { type: integer, description: The number of reviews of review_snapshot. } @@ -1779,7 +1780,7 @@ components: title: { type: string } brief: { type: string } definition: { $ref: "#/components/schemas/WorkflowDefinition" } - finished: { type: boolean, description: "Whether the final stage finished, which ends the run." } + finished: { type: boolean, description: "Whether every stage finished, which ends the run." } stages: type: array description: In the definition's order. @@ -1823,7 +1824,7 @@ components: description: > running: its agent is mid-turn. idle: active, and finish_stage hasn't taken. finished: active, its output recorded. merged. discarded: discarded before finishing. cleaned_up: discarded after finishing, as byre - does to the run's other tasks when the final stage finishes. + does to the run's other tasks once every stage has finished. discarding: { type: boolean, description: "Whether a Discard was started and the task isn't closed yet." } forked_from: { type: string, description: "The task this attempt was forked from; absent for the stage's first attempt." } output: { type: string, description: "The finish_stage output the stages after it get; absent until it finishes." } @@ -1955,7 +1956,7 @@ components: type: string enum: [running, done, failed, skipped] x-enum-varnames: [ReviewStateRunning, ReviewStateDone, ReviewStateFailed, ReviewStateSkipped] - description: "skipped: the snapshot's step changed no files, so no reviewer ran." + description: "skipped: the snapshot has no changes from the default branch (a subtask's from its parent's branch), so no reviewer ran." result: { type: object, description: "done: the reviewer's submit_review arguments: summary (Markdown) and findings, each with severity, category, title, detail, path and line." } error: { type: string, description: "failed: why." } created_at: { type: string, format: date-time } @@ -2386,7 +2387,7 @@ components: type: object required: [id, login, host, device, commit, build, connected_at] properties: - id: { type: string, description: The ID the app made up when it started, from its Byre-Client header. } + id: { type: string, description: The id the app made up when it started, from its Byre-Client header. } login: { type: string } host: { type: string, description: The device's name from its Byre-Host header. } device: { type: string, description: "The kind of device the app runs on (Mac or iPhone), from its Byre-Device header." } diff --git a/cmd/byre/clientexec.go b/cmd/byre/clientexec.go index 3a9fdeb..98822f3 100644 --- a/cmd/byre/clientexec.go +++ b/cmd/byre/clientexec.go @@ -24,6 +24,7 @@ const ( func clientExecCmd(args []string) { fs := flag.NewFlagSet("client-exec", flag.ExitOnError) + fs.Usage = usage client := fs.String("client", "", "the client's name or id; the most recently active one when absent") timeout := fs.Int("timeout", 30, "kill the command after this many seconds") fs.Parse(args) diff --git a/cmd/byre/grep.go b/cmd/byre/grep.go index bdc6bbd..1a50fce 100644 --- a/cmd/byre/grep.go +++ b/cmd/byre/grep.go @@ -10,6 +10,7 @@ import ( func grepCmd(args []string) { fs := flag.NewFlagSet("grep", flag.ExitOnError) + fs.Usage = usage opts := grep.Options{} fs.StringVar(&opts.Glob, "glob", "", "search only files whose names match this glob") fs.BoolVar(&opts.IgnoreCase, "ignore-case", false, "match case-insensitively") diff --git a/cmd/byre/list.go b/cmd/byre/list.go index 9f815a3..d29e420 100644 --- a/cmd/byre/list.go +++ b/cmd/byre/list.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "os" "g.fc.run/ai/byre/internal/dirlist" ) @@ -13,8 +12,7 @@ func listCmd(args []string) { } out, err := dirlist.List(args[0]) if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) + fatal("list", "err", err) } fmt.Print(out) } diff --git a/docs/antigravity-protocol.md b/docs/antigravity-protocol.md index 46d6f25..3835b5a 100644 --- a/docs/antigravity-protocol.md +++ b/docs/antigravity-protocol.md @@ -22,7 +22,7 @@ There is no flag for a system prompt or MCP servers, so byre hands them over as - `plugin.json`: `{"name": "byre"}`. - `rules/AGENTS.md`: always-on guidance. `rules/notes.md` uses `trigger: always_on` frontmatter. The CLI cuts each rule file at 24,000 bytes, so longer guidance or notes must be refused before launch. - `mcp_config.json`: one entry per server, with a Streamable HTTP `url` or a stdio `command` and `args`. The CLI namespaces plugin servers as `_`, so byre's own server is `byre_byre`. -- `hooks.json`: handlers keyed by hook event, each a command that reads the hook's JSON from stdin and prints its reply, with a `timeout` in seconds (default 30). Flat events (`SessionStart`, `PreInvocation`, `PostInvocation`, `Stop`) list handlers directly; tool events (`PreToolUse`, `PostToolUse`) wrap them in groups, `[{"matcher": "*", "hooks": [...]}]`, where `matcher` is a regex on the tool name. +- `hooks.json`: one top-level object named `byre`, holding handlers keyed by hook event, each a command that reads the hook's JSON from stdin and prints its reply, with a `timeout` in seconds (default 30). Flat events (`SessionStart`, `PreInvocation`, `PostInvocation`, `Stop`) list handlers directly; tool events (`PreToolUse`, `PostToolUse`) wrap them in groups, `[{"matcher": "*", "hooks": [...]}]`, where `matcher` is a regex on the tool name. ## The session's listener diff --git a/docs/claude-protocol.md b/docs/claude-protocol.md index deeea48..92bc22a 100644 --- a/docs/claude-protocol.md +++ b/docs/claude-protocol.md @@ -10,7 +10,7 @@ claude --output-format stream-json --input-format stream-json --verbose \ --permission-mode bypassPermissions --allow-dangerously-skip-permissions \ --settings '{"attribution":{"commit":"","pr":""}}' \ --mcp-config '{"mcpServers":{"byre":{"type":"sdk","name":"byre","alwaysLoad":true}}}' \ - [--model M] [--effort E] [--session-id=ID] [--resume=SESSION_ID] [--resume-session-at=UUID] [--fork-session] + [--model M] [--effort E] [--append-system-prompt GUIDANCE] [--session-id=ID] [--resume=SESSION_ID] [--resume-session-at=UUID] [--fork-session] ``` - No `--print`; stream-json input implies non-interactive. @@ -39,7 +39,7 @@ Either side sends `{"type":"control_request","request_id":ID,"request":{"subtype Host → CLI: -- `initialize` must be first. It carries hook registrations: `{"hooks":{"Stop":[{"matcher":null,"hookCallbackIds":["hook_0"],"timeout":}],...}}`. Without `timeout` the CLI abandons a hook callback after its default; the timer is a JavaScript `setTimeout`, so values past about 24 days (2^31 ms) fire at once. +- `initialize` must be first. It carries hook registrations: `{"hooks":{"Stop":[{"matcher":"","hookCallbackIds":["hook_0"],"timeout":}],...}}`. Without `timeout` the CLI abandons a hook callback after its default; the timer is a JavaScript `setTimeout`, so values past about 24 days (2^31 ms) fire at once. - `interrupt` ends the current turn; the turn's `result` follows almost immediately and a running Bash tool is killed. The session stays usable. - `set_model` (`{"subtype":"set_model","model":M}`) switches the running process's model for later turns. - `apply_flag_settings` (`{"subtype":"apply_flag_settings","settings":{"effortLevel":E}}`) switches its effort; `null` returns to the default. It answers success for any value, an unknown level included. diff --git a/docs/operations.md b/docs/operations.md index 666e0d8..6a5c2c0 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -125,7 +125,7 @@ byre never signs with a key on the Mac it runs on: every git command it runs the - **Orion.** Orion ignores key events that carry only a Unicode string, so typing posts each ASCII character as its key code. Some apps list `confirm` but ignore it, Orion's address bar among them; send Return instead. `do JavaScript` needs Orion's Develop → "Allow JavaScript from Apple Events". - **Chrome.** Chrome refuses remote debugging on its default profile, so byre's Chrome is its own profile (`~/Library/Application Support/byre/chrome`), a separate Chrome beside any the human runs, and it keeps its logins: the human signs in there once. Chrome comes from `brew install --cask google-chrome`; macOS's "downloaded from the Internet" prompt on its first launch must be answered Open (or `osascript -e 'tell application "System Events" to tell process "CoreServicesUIAgent" to click button "Open" of window 1'`), and until it is, Chrome cannot accept debugging commands. - **Chrome's trust boundary.** Use Chrome's loopback debugging port with byre's separate persistent profile and Chrome's default browser-origin checks; never add `--remote-allow-origins=*`. Other local OS accounts can reach that debugger and control its logged-in sessions. This is an accepted risk on the personal Macs byre runs on, as is access to the app's local preview forwards; do not add account-isolating brokers for these listeners. Chrome must be launched with `--remote-debugging-port=0` so it records its port and browser WebSocket path in the profile’s `DevToolsActivePort` file. After switching from the pipe or fixed-port transport, quit the old byre-profile Chrome once so the next tool call can start it with that discovery file. The saved profile and logins stay in place. -- **Permissions.** Agents' processes run as byre's descendants, so macOS privacy controls (TCC) hold byre responsible for them: the Screen Recording, Device Control and Data Access (macOS 27's name for Accessibility) and Automation grants in System Settings → Privacy & Security are byre's, made by clicking at the Mac's screen, and each app scripted for the first time asks for its own Automation grant. Without Device Control and Data Access an untrusted process just sees no windows and no menu bar. A Mac running a server lists byre twice: the server's helper, a bare executable shown by its file name `byre` with a terminal icon, and the app, `Byre` with its icon; `byre-hands` names the app when the app is among its ancestor processes, and the server otherwise. Device Control and Data Access can list byre switched off; only its switch being on counts. TCC keys grants on the signing identifier and team, and every build is signed with Developer ID, so grants carry over from build to build. On a client Mac the grants belong to byre's app; `NSAppleEventsUsageDescription` in `mac/Info.plist` is what lets macOS ask for the Automation grant. The Desktop, Documents, Downloads and iCloud Drive folders each ask for their own Files & Folders grant the first time a process byre is responsible for reads them. `byre-hands check` prints the grants of the process that runs it, listing each of those folders so their prompts come up during the check rather than mid-turn; the Server and Settings tabs run it. +- **Permissions.** Agents' processes run as byre's descendants, so macOS privacy controls (TCC) hold byre responsible for them: the Screen Recording, Device Control and Data Access (macOS 27's name for Accessibility) and Automation grants in System Settings → Privacy & Security are byre's, made by clicking at the Mac's screen, and each app scripted for the first time asks for its own Automation grant. Without Device Control and Data Access an untrusted process just sees no windows and no menu bar. A Mac running a server lists byre twice in Device Control and Data Access and in Automation: the server's helper, a bare executable shown by its file name `byre` with a terminal icon, and the app, `Byre` with its icon; Screen Recording lists only `Byre`, and switching it on covers the server too. `byre-hands` names the app when the app is among its ancestor processes, and the server otherwise. Device Control and Data Access can list byre switched off; only its switch being on counts. TCC keys grants on the signing identifier and team, and every build is signed with Developer ID, so grants carry over from build to build. On a client Mac the grants belong to byre's app; `NSAppleEventsUsageDescription` in `mac/Info.plist` is what lets macOS ask for the Automation grant. The Desktop, Documents, Downloads and iCloud Drive folders each ask for their own Files & Folders grant the first time a process byre is responsible for reads them. `byre-hands check` prints the grants of the process that runs it, listing each of those folders so their prompts come up during the check rather than mid-turn; the Server and Settings tabs run it. ## Terminals diff --git a/hands/Sources/byre-hands/Tools.swift b/hands/Sources/byre-hands/Tools.swift index 5577ab1..30d10c1 100644 --- a/hands/Sources/byre-hands/Tools.swift +++ b/hands/Sources/byre-hands/Tools.swift @@ -77,7 +77,7 @@ let tools: [Tool] = [ ), Tool( name: "browser", - description: "Drive Orion, the logged-in browser on this Mac, through AppleScript; for web work, prefer this to clicking. " + description: "Drive Orion, the signed-in browser on this Mac, through AppleScript; for web work, prefer this to clicking. " + "ops: tabs (list every window's tabs: window, tab, title, url), navigate (url, optionally new_tab; waits for the page to load), " + "js (run code in the tab and return its value: the value of the last expression, synchronously, so return strings, JSON.stringify objects, and don't return promises), select (tab), close (tab). " + "window is Orion's window index (1 is the front one) and tab the tab index from tabs; without tab, the window's current tab. " @@ -99,7 +99,7 @@ let tools: [Tool] = [ Tool( name: "chrome", description: "Drive Chrome on this Mac through its DevTools protocol: pages, DOM, network, console and performance traces. " - + "It is Chrome with byre's own profile, started on first use and kept between calls, so a site the human has logged into there (passkeys included) stays logged in; when a site needs a login, ask the human to sign in in that Chrome window. " + + "It is Chrome with byre's own profile, started on first use and kept between calls, so a site the human has signed in to there (passkeys included) stays signed in; when a site needs a sign-in, ask the human to sign in in that Chrome window. " + "ops: tabs (list tabs: id, title, url), navigate (url, optionally new_tab; waits for the page to load and clears the tab's network and console logs), " + "js (run code in the tab and return its value: the last expression's, promises awaited, objects as JSON; use it to explore the DOM), select (tab), close (tab), " + "network (the tab's requests since this tool first touched the tab or its last navigate: number, status, type, start and duration in ms, bytes, method, url; with request, one request's headers and bodies; filter keeps urls containing the text), " diff --git a/internal/agents/audit.go b/internal/agents/audit.go index 9c10995..6c0c611 100644 --- a/internal/agents/audit.go +++ b/internal/agents/audit.go @@ -107,7 +107,7 @@ func (m *Manager) auditError(ctx context.Context, task api.Task, msg string) { func auditBrief(branch, commit string) string { return fmt.Sprintf("Audit of %s at %s. This isn't a review of a change: check the whole codebase as it stands against the project's standards and expectations, and fix what falls short. "+ - "byre runs this task in the background: the human doesn't see it until you ask a question, call ready_for_merge or hit an error. "+ + "byre runs this task in the background: the human doesn't see it until you ask a question, call ready_for_merge, hit an error or rate limit, or call suggest_discard in a workflow without auto_discard. "+ "Finish your stage with finish_stage as usual, even when you found nothing. Once your stage has finished and its review has come back, byre asks whether the task is ready to merge; "+ "if nothing needed changing, answer with suggest_discard.", branch, commit) } diff --git a/internal/agents/clients.go b/internal/agents/clients.go index 9bb569a..6be8dc9 100644 --- a/internal/agents/clients.go +++ b/internal/agents/clients.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "encoding/base64" "encoding/json" + "errors" "fmt" "net/url" "os" @@ -399,7 +400,7 @@ type showPageArgs struct { func (m *Manager) showPage(ctx context.Context, l *live, args showPageArgs) (string, error) { if (args.Path == "") == (args.URL == "") { - return "", fmt.Errorf("show_page takes path or url, not both or neither") + return "", errors.New("show_page takes path or url, not both or neither") } if args.Path != "" { return m.show(ctx, l, clientOpenArgs{Client: args.Client, Path: args.Path}, api.OpenPage) diff --git a/internal/agents/codex.go b/internal/agents/codex.go index 14cf3ff..adbd4e7 100644 --- a/internal/agents/codex.go +++ b/internal/agents/codex.go @@ -3,6 +3,7 @@ package agents import ( "context" "encoding/json" + "errors" "fmt" "log/slog" "os" @@ -239,7 +240,7 @@ func codexToolResult(item codex.ThreadItem) (any, bool, error) { } mime, data, ok := strings.Cut(strings.TrimPrefix(c.ImageURL, "data:"), ";base64,") if !ok { - return nil, false, fmt.Errorf("dynamic tool image is not a base64 data url") + return nil, false, errors.New("dynamic tool image is not a base64 data url") } blocks = append(blocks, imageBlock(mime, data)) } diff --git a/internal/agents/hands.go b/internal/agents/hands.go index 2a6f3bd..0996f2d 100644 --- a/internal/agents/hands.go +++ b/internal/agents/hands.go @@ -3,6 +3,7 @@ package agents import ( "context" "encoding/json" + "errors" "fmt" "os" "os/exec" @@ -77,7 +78,7 @@ func (m *Manager) CheckPermissions(ctx context.Context) ([]api.Permission, error cmd.Stderr = &stderr out, err := cmd.Output() if ctx.Err() == context.DeadlineExceeded { - return nil, fmt.Errorf("byre-hands check didn't finish within 2 minutes; answer macOS's prompts on the Mac byre runs on and check again") + return nil, errors.New("byre-hands check didn't finish within 2 minutes; answer macOS's prompts on the Mac byre runs on and check again") } if err != nil { return nil, fmt.Errorf("byre-hands check: %w: %s", err, strings.TrimSpace(stderr.String())) diff --git a/internal/agents/imagegen.go b/internal/agents/imagegen.go index a95491f..be2f356 100644 --- a/internal/agents/imagegen.go +++ b/internal/agents/imagegen.go @@ -3,6 +3,7 @@ package agents import ( "context" "encoding/json" + "errors" "fmt" "os" "path/filepath" @@ -37,7 +38,7 @@ func (m *Manager) generateImageTool(l *live) mcp.Tool { func (m *Manager) generateImage(ctx context.Context, l *live, prompt string) (string, error) { if strings.TrimSpace(prompt) == "" { - return "", fmt.Errorf("generate_image needs a prompt") + return "", errors.New("generate_image needs a prompt") } media := MediaDir(l.dir) @@ -68,7 +69,7 @@ func (m *Manager) generateImage(ctx context.Context, l *live, prompt string) (st return "", fmt.Errorf("no image after %s", mcp.Timeout(ctx)) case ev, ok := <-s.Events(): if !ok { - return "", fmt.Errorf("codex exited before the image was made") + return "", errors.New("codex exited before the image was made") } switch ev.Method { case codex.MethodItemCompleted: @@ -94,7 +95,7 @@ func (m *Manager) generateImage(ctx context.Context, l *live, prompt string) (st return "", fmt.Errorf("codex: %s", n.Turn.Error.Message) } if saved == "" { - return "", fmt.Errorf("codex finished without making an image") + return "", errors.New("codex finished without making an image") } path, err := copyToMedia(media, saved) if err != nil { diff --git a/internal/agents/inbox.go b/internal/agents/inbox.go index a31677a..f681535 100644 --- a/internal/agents/inbox.go +++ b/internal/agents/inbox.go @@ -346,7 +346,7 @@ func (m *Manager) Deliver(ctx context.Context, sessionID string) error { return nil } if err != nil { - slog.Error("deliver failed", "session", sessionID, "err", err, "responses", ids) + slog.Error("deliver inbox responses", "session", sessionID, "err", err, "responses", ids) return err } diff --git a/internal/agents/kb/client-exec.md b/internal/agents/kb/client-exec.md index bfa0a97..1c61e68 100644 --- a/internal/agents/kb/client-exec.md +++ b/internal/agents/kb/client-exec.md @@ -32,7 +32,7 @@ client-exec calls byre's API at `http://127.0.0.1:8270`. When `HTTP_PROXY` (or ` ## Screen lock -`byre screen` prints `unlocked`, `locked` or `no-session` (no GUI login for this user) for the Mac it runs on, and exits 0. Check the server Mac with `byre screen` and the client with: +`byre screen` prints `unlocked`, `locked` or `no-session` (no GUI login for this user) for the Mac it runs on, and exits 0. Check the Mac byre runs on with `byre screen` and the client with: ``` byre client-exec -- /Applications/Byre.app/Contents/Helpers/byre screen diff --git a/internal/agents/lead.go b/internal/agents/lead.go index 4457f21..35fc6d1 100644 --- a/internal/agents/lead.go +++ b/internal/agents/lead.go @@ -15,7 +15,7 @@ import ( ) 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. -- Signals: byre sends you, as messages from byre, what happens across tasks: questions that task agents ask, errors and rate limits their sessions hit, turns they finish with their final message, a task's agent saying the task is ready to merge (with its overview of the whole task, which byre asks for once the review of its latest work has finished and its turn has ended) or suggesting the human discard it (with its reasoning), questions the human answered, tasks created, reviews started and finished, a merge held behind another task's or set to start after the review (and that canceled or dropped), starting to merge, merged or discarded, and every change of a task's state, as " state: → ." listed first among what happened at the same moment. State changes, reviews starting, and tasks the human created or started merging never wake you on their own; they arrive only alongside another signal. A task merged or discarded always wakes you, whoever closed it. The states are running, idle, finished (a workflow stage's task once its finish_stage has taken), review_pending, reviewing, asking (it has an open question), ready_to_merge and discard_suggested (the agent's ready_for_merge or suggest_discard still stands), merge_held (its Merge waits for another merge in the project), merge_after_review (its Merge waits for the running review), merging, pushing (byre is pushing the merge's squash commit), discarding, merged, discarded and no_agent (it has no live agent). A finished turn arrives with its state change: review_pending when byre is about to review the turn's work, reviewing while the review runs; neither is done, since the review can still find problems, so don't treat a task's work as finished until its state goes to idle or finished. Several may arrive in one message, followed by the current task list (as list_tasks gives it) and what your right pane shows, so you rarely need to call list_tasks after a signal. The human doesn't see signals. Messages from the human arrive separately. +- Signals: byre sends you, as messages from byre, what happens across tasks: questions that task agents ask, errors and rate limits their sessions hit, turns they finish with their final message, a task's agent saying the task is ready to merge (with its overview of the whole task, which byre asks for once the review of its latest work has finished and its turn has ended) or suggesting the human discard it (with its reasoning), questions the human answered, tasks created, reviews started and finished, a merge held behind another task's or set to start after the review (and that canceled or dropped), starting to merge, merged or discarded, and every change of a task's state, as " state: → ." listed first among what happened at the same moment. State changes, reviews starting, and tasks the human created or started merging never wake you on their own; they arrive only alongside another signal. A task merged or discarded always wakes you, whoever closed it. The states are running, idle, finished (a workflow stage's task once its finish_stage has taken, or a workflow run's task once the run finished), review_pending, reviewing, asking (it has an open question), ready_to_merge and discard_suggested (the agent's ready_for_merge or suggest_discard still stands), merge_held (its Merge waits for another merge in the project), merge_after_review (its Merge waits for the running review), merging, pushing (byre is pushing the merge's squash commit), discarding, merged, discarded and no_agent (it has no live agent). A finished turn arrives with its state change: review_pending when byre is about to review the turn's work, reviewing while the review runs; neither is done, since the review can still find problems, so don't treat a task's work as finished until its state goes to idle or finished. Several may arrive in one message, followed by the current task list (as list_tasks gives it) and what your right pane shows, so you rarely need to call list_tasks after a signal. The human doesn't see signals. Messages from the human arrive separately. - Don't respond to what the human just did. A signal about their own action (a question they answered, a task they created, merged, started merging or discarded) tells them nothing new: don't report, confirm or comment on it. Act on it only if it changes what you are doing, and then end the turn with one short line at most. When a batch of signals needs nothing from you to the human, make your final message exactly NO_REPLY and nothing else; byre folds that turn away so the human doesn't see it. - "Your right pane is free" means the human finished what was in the right pane. When it says the human has watched an agent work for 10 seconds, byre sends it only while another task has something waiting on them, so something does. Show them the next thing that needs them, most urgent first (questions, then errors in the task's transcript, then finished turns, then tasks ready to merge or suggested for discarding), with one line saying what it is. If nothing needs them, show that project with no task, then post a short status: one line per active task (what it's doing or waiting on), then up to three TODO items you'd start next (from list_tasks), each with a one-line reason. Write each item as a link to #/todo//, for example [Fix login redirect](#/todo/prj3f2a9C1b7dQ/Fix%20login%20redirect): byre draws it with a Start button the human can click, and once the task exists, its state. Start one with start_todo only when the human picks it. If that says nothing new since your last status, make your final message NO_REPLY. - Whenever you suggest new work that isn't in TODO.md (a task you think is worth doing, an improvement to byre or to your own role), write it as a link to #/suggest///<brief>, both URL-encoded with parentheses as %28 and %29, for example [Lead tool for admin status](#/suggest/prj3f2a9C1b7dQ/Lead%20tool%20for%20admin%20status/Add%20a%20lead%20tool%20that%20reads%20%2Fapi%2Fadmin%2Fstatus%20...). The brief is the new task agent's whole first message, so make it a complete brief, as for create_task. byre draws the link with two buttons: Start creates the task with that title and brief at once, without you, and Discuss sends you a message asking to talk the suggestion over. Once an active task has that title, it shows the task's state instead. Don't ask whether to start a suggestion; the buttons do that. diff --git a/internal/agents/workflows.go b/internal/agents/workflows.go index b9e5b92..4fa4c61 100644 --- a/internal/agents/workflows.go +++ b/internal/agents/workflows.go @@ -879,7 +879,7 @@ func (m *Manager) workflowTools(l *live) []mcp.Tool { leadTool(m, l, "set_audit_workflow", "Set the audit workflow (any saved workflow) that byre runs in the background on a project's default branch: one run at a time, started whenever the branch's newest commit hasn't had one, to check the whole codebase against its standards rather than one change. "+ - "An audit's tasks stay out of list_tasks and your signals until one asks a question, calls ready_for_merge, hits an error, or suggests discarding in a workflow without auto_discard. An empty workflow turns audits off. Only when the human asks.", + "An audit's tasks stay out of list_tasks and your signals until one asks a question, calls ready_for_merge, hits an error or rate limit, or suggests discarding in a workflow without auto_discard. An empty workflow turns audits off. Only when the human asks.", `{"type": "object", "properties": { "project_id": {"type": "string"}, "workflow": {"type": "string"} diff --git a/internal/api/api.gen.go b/internal/api/api.gen.go index 8d8ed12..5b6f378 100644 --- a/internal/api/api.gen.go +++ b/internal/api/api.gen.go @@ -897,7 +897,7 @@ type ConnectedClient struct { // Host The device's name from its Byre-Host header. Host string `json:"host"` - // Id The ID the app made up when it started + // Id The id the app made up when it started Id string `json:"id"` // LastActionAt When byre last received a request the human made from this client since byre started; absent when none. @@ -1127,7 +1127,7 @@ type MergeFacts struct { // UnmergedCommits Commits on the task branch that aren't on the default branch. UnmergedCommits int `json:"unmerged_commits"` - // UnmergedFiles Files that differ from the merge base, uncommitted changes included. + // UnmergedFiles Files that differ from the merge-base, uncommitted changes included. UnmergedFiles int `json:"unmerged_files"` // UnreviewedChanges Whether the worktree differs from the latest reviewable snapshot. @@ -1152,7 +1152,7 @@ type MessageCreate struct { Text string `json:"text"` } -// NotificationPrefs Which task events notify this user in the macOS app. +// NotificationPrefs Which task events notify this user in the app. type NotificationPrefs struct { // Discard task.discard_suggested events. Discard bool `json:"discard"` @@ -1304,7 +1304,7 @@ type Review struct { // Stage The review workflow's stage this reviewer ran; empty when skipped. Stage string `json:"stage"` - // State skipped: the snapshot's step changed no files, so no reviewer ran. + // State skipped: the snapshot has no changes from the default branch (a subtask's from its parent's branch), so no reviewer ran. State ReviewState `json:"state"` TaskId string `json:"task_id"` @@ -1312,7 +1312,7 @@ type Review struct { Vendor string `json:"vendor"` } -// ReviewState skipped: the snapshot's step changed no files, so no reviewer ran. +// ReviewState skipped: the snapshot has no changes from the default branch (a subtask's from its parent's branch), so no reviewer ran. type ReviewState string // SavedCommand defines model for SavedCommand. @@ -1435,13 +1435,13 @@ type StageAttempt struct { // Output The finish_stage output the stages after it get; absent until it finishes. Output *string `json:"output,omitempty"` - // State running: its agent is mid-turn. idle: active, and finish_stage hasn't taken. finished: active, its output recorded. merged. discarded: discarded before finishing. cleaned_up: discarded after finishing, as byre does to the run's other tasks when the final stage finishes. + // State running: its agent is mid-turn. idle: active, and finish_stage hasn't taken. finished: active, its output recorded. merged. discarded: discarded before finishing. cleaned_up: discarded after finishing, as byre does to the run's other tasks once every stage has finished. State StageAttemptState `json:"state"` TaskId string `json:"task_id"` Title string `json:"title"` } -// StageAttemptState running: its agent is mid-turn. idle: active, and finish_stage hasn't taken. finished: active, its output recorded. merged. discarded: discarded before finishing. cleaned_up: discarded after finishing, as byre does to the run's other tasks when the final stage finishes. +// StageAttemptState running: its agent is mid-turn. idle: active, and finish_stage hasn't taken. finished: active, its output recorded. merged. discarded: discarded before finishing. cleaned_up: discarded after finishing, as byre does to the run's other tasks once every stage has finished. type StageAttemptState string // StageInput defines model for StageInput. @@ -1511,7 +1511,7 @@ type Task struct { // Audit The default branch commit an audit audits, on the task of a run of its project's audit workflow; absent for other tasks. Audit *string `json:"audit,omitempty"` - // Background Whether the task is an audit's run or stage task that hasn't asked for attention yet: no question, ready_for_merge or error so far (for a run, from any of its stage tasks). The app keeps it out of the task switcher and shows it muted on the project's dashboard, and the lead gets no signals about it. + // Background Whether the task is an audit's run or stage task that hasn't asked for attention yet: no question, ready_for_merge, suggest_discard (unless its workflow has auto_discard), error or rate limit so far (for a run, from any of its stage tasks). The app keeps it out of the task switcher and shows it muted on the project's dashboard, and the lead gets no signals about it. Background bool `json:"background"` BaseRef string `json:"base_ref"` Branch string `json:"branch"` @@ -1757,7 +1757,7 @@ type User struct { GitName string `json:"git_name"` Login string `json:"login"` - // NotificationPrefs Which task events notify this user in the macOS app. + // NotificationPrefs Which task events notify this user in the app. NotificationPrefs NotificationPrefs `json:"notification_prefs"` // QuickRun The workflow the iPhone's Action button starts with a typed prompt, and the project it runs in; both empty when none is set. @@ -1791,7 +1791,7 @@ type WorkflowRun struct { // Definition A workflow's definition, which holds everything but its name: its steps, run in order. Run on a brief, each stage runs as its own task once the steps before it have finished; as a project's review workflow, each stage is a reviewer of a snapshot and gets the earlier stages' reviews. Definition WorkflowDefinition `json:"definition"` - // Finished Whether the final stage finished, which ends the run. + // Finished Whether every stage finished, which ends the run. Finished bool `json:"finished"` Name string `json:"name"` @@ -4885,371 +4885,372 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "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", - "jx///wEA", + "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", + "/CqAKbT9crWKRiSwfGp8wAC5RNa/MbXsx4///wA=", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/claude/session.go b/internal/claude/session.go index 7990e74..eedd4b0 100644 --- a/internal/claude/session.go +++ b/internal/claude/session.go @@ -605,7 +605,7 @@ func (s *Session) handleControlRequest(ctx context.Context, cancel context.Cance result, err := s.dispatchControl(ctx, raw) if err != nil { - slog.Error("control request failed", "request_id", id, "err", err) + slog.Error("answer control request", "request_id", id, "err", err) s.write(map[string]any{ "type": "control_response", "response": map[string]any{ diff --git a/internal/codex/session.go b/internal/codex/session.go index 8dec58f..7f3ab2b 100644 --- a/internal/codex/session.go +++ b/internal/codex/session.go @@ -686,7 +686,7 @@ func (s *Session) handleResponse(line []byte, m message) { func (s *Session) handleServerRequest(m message) { result, err := s.answerServerRequest(m) if err != nil { - slog.Error("codex server request failed", "method", m.Method, "err", err) + slog.Error("answer codex server request", "method", m.Method, "err", err) s.write(message{ID: m.ID, Error: &RPCError{Code: -32601, Message: err.Error()}}, time.Now().Add(rpcTimeout)) return } diff --git a/internal/git/changes.go b/internal/git/changes.go index 61669e1..ae03e62 100644 --- a/internal/git/changes.go +++ b/internal/git/changes.go @@ -2,6 +2,7 @@ package git import ( "context" + "errors" "fmt" "os" "strconv" @@ -148,7 +149,7 @@ func stats(ctx context.Context, dir, base, tree string) ([]api.FileChange, error f := api.FileChange{Status: status} if status == api.Renamed { if i+2 >= len(tokens) { - return nil, fmt.Errorf("truncated rename in name-status output") + return nil, errors.New("truncated rename in name-status output") } old := tokens[i+1] f.OldPath = &old @@ -156,7 +157,7 @@ func stats(ctx context.Context, dir, base, tree string) ([]api.FileChange, error i += 2 } else { if i+1 >= len(tokens) { - return nil, fmt.Errorf("truncated name-status output") + return nil, errors.New("truncated name-status output") } f.Path = tokens[i+1] i++ diff --git a/internal/hookcmd/hookcmd.go b/internal/hookcmd/hookcmd.go index f2978ab..dbaddb8 100644 --- a/internal/hookcmd/hookcmd.go +++ b/internal/hookcmd/hookcmd.go @@ -31,7 +31,7 @@ func Handler(hooks map[string]Func) http.HandlerFunc { } out, err := fn(r.Context(), body) if err != nil { - slog.Error("hook failed", "event", event, "err", err) + slog.Error("run hook", "event", event, "err", err) out = map[string]any{} } w.Header().Set("Content-Type", "application/json") diff --git a/internal/server/lead.go b/internal/server/lead.go index 7272193..759cd8f 100644 --- a/internal/server/lead.go +++ b/internal/server/lead.go @@ -63,8 +63,8 @@ func (s *Server) ListLeadNotes(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, notes) } -func (s *Server) DeleteLeadNote(w http.ResponseWriter, r *http.Request, noteId string) { - err := s.agents.DeleteLeadNote(r.Context(), actor(r), noteId) +func (s *Server) DeleteLeadNote(w http.ResponseWriter, r *http.Request, noteID string) { + err := s.agents.DeleteLeadNote(r.Context(), actor(r), noteID) if err != nil { writeAgentError(w, err) return @@ -110,7 +110,7 @@ func (s *Server) GetSummaryReads(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, reads) } -func (s *Server) MarkSummaryRead(w http.ResponseWriter, r *http.Request, taskId string) { +func (s *Server) MarkSummaryRead(w http.ResponseWriter, r *http.Request, taskID string) { body := api.SummaryRead{} if !readJSON(w, r, &body) { return @@ -119,7 +119,7 @@ func (s *Server) MarkSummaryRead(w http.ResponseWriter, r *http.Request, taskId writeError(w, http.StatusBadRequest, errors.New("seq must be positive")) return } - err := s.store.MarkSummaryRead(r.Context(), actor(r), taskId, body.Seq) + err := s.store.MarkSummaryRead(r.Context(), actor(r), taskID, body.Seq) if err != nil { writeStoreError(w, err) return diff --git a/internal/server/server.go b/internal/server/server.go index 0f53dd8..88da3cb 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -147,7 +147,7 @@ func (s *Server) LoopbackHandler() http.Handler { mux.HandleFunc("POST /api/clients/exec", s.ExecClient) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !s.bearer(r) { - http.Error(w, "unauthorized", http.StatusUnauthorized) + writeError(w, http.StatusUnauthorized, errors.New("unauthorized")) return } w.Header().Set("Cache-Control", "no-store") diff --git a/internal/store/blob.go b/internal/store/blob.go index 2adb734..2a21709 100644 --- a/internal/store/blob.go +++ b/internal/store/blob.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "errors" + "fmt" "os" "path/filepath" "time" @@ -50,7 +51,7 @@ func (s *Store) GetBlob(ctx context.Context, id string) (api.Blob, string, error err := s.db.QueryRowContext(ctx, `SELECT id, content_type, created_by, created_at FROM blobs WHERE id = ?`, id). Scan(&b.Id, &b.ContentType, &b.CreatedBy, &createdAt) if errors.Is(err, sql.ErrNoRows) { - return b, "", errors.Join(ErrNotFound, errors.New("no blob "+id)) + return b, "", fmt.Errorf("%w: no blob %s", ErrNotFound, id) } if err != nil { return b, "", err diff --git a/internal/store/leadnotes.go b/internal/store/leadnotes.go index 7af49b8..dfaf06c 100644 --- a/internal/store/leadnotes.go +++ b/internal/store/leadnotes.go @@ -63,7 +63,7 @@ func (s *Store) SaveLeadNote(ctx context.Context, owner, id, projectID, text, ac err := tx.QueryRowContext(ctx, `UPDATE lead_notes SET text = ?, project_id = ?, updated_at = ? WHERE id = ? AND owner = ? RETURNING created_at`, text, projectID, formatTime(at), id, owner).Scan(&createdAt) if errors.Is(err, sql.ErrNoRows) { - return fmt.Errorf("note %s: %w", id, ErrNotFound) + return fmt.Errorf("%w: no note %s", ErrNotFound, id) } if err != nil { return err @@ -83,7 +83,7 @@ func (s *Store) DeleteLeadNote(ctx context.Context, owner, id, actor string) (st err := s.write(ctx, func(tx *sql.Tx, emit emitFunc) error { err := tx.QueryRowContext(ctx, `DELETE FROM lead_notes WHERE id = ? AND owner = ? RETURNING text`, id, owner).Scan(&text) if errors.Is(err, sql.ErrNoRows) { - return fmt.Errorf("note %s: %w", id, ErrNotFound) + return fmt.Errorf("%w: no note %s", ErrNotFound, id) } if err != nil { return err diff --git a/internal/store/savedcommands.go b/internal/store/savedcommands.go index 98181ed..eeddf5c 100644 --- a/internal/store/savedcommands.go +++ b/internal/store/savedcommands.go @@ -33,7 +33,7 @@ func (s *Store) SavedCommand(ctx context.Context, owner, id string) (api.SavedCo c := api.SavedCommand{Id: id} err := s.db.QueryRowContext(ctx, `SELECT name, command FROM saved_commands WHERE id = ? AND owner = ?`, id, owner).Scan(&c.Name, &c.Command) if errors.Is(err, sql.ErrNoRows) { - return c, fmt.Errorf("saved command %s: %w", id, ErrNotFound) + return c, fmt.Errorf("%w: no saved command %s", ErrNotFound, id) } return c, err } @@ -57,7 +57,7 @@ func (s *Store) SaveSavedCommand(ctx context.Context, owner, id, name, command, return err } if n == 0 { - return fmt.Errorf("saved command %s: %w", id, ErrNotFound) + return fmt.Errorf("%w: no saved command %s", ErrNotFound, id) } } return emit(api.Event{Kind: "command.saved", Owner: &owner, Actor: actor, Payload: ToPayload(c)}) @@ -76,7 +76,7 @@ func (s *Store) DeleteSavedCommand(ctx context.Context, owner, id, actor string) return err } if n == 0 { - return fmt.Errorf("saved command %s: %w", id, ErrNotFound) + return fmt.Errorf("%w: no saved command %s", ErrNotFound, id) } return emit(api.Event{Kind: "command.deleted", Owner: &owner, Actor: actor, Payload: map[string]any{"id": id}}) }) diff --git a/internal/store/schedule.go b/internal/store/schedule.go index bc7dce9..b00711c 100644 --- a/internal/store/schedule.go +++ b/internal/store/schedule.go @@ -71,7 +71,7 @@ func (s *Store) GetSchedule(ctx context.Context, id string) (api.Schedule, error return api.Schedule{}, err } if len(list) == 0 { - return api.Schedule{}, fmt.Errorf("schedule %s: %w", id, ErrNotFound) + return api.Schedule{}, fmt.Errorf("%w: no schedule %s", ErrNotFound, id) } return list[0], nil } @@ -121,7 +121,7 @@ func (s *Store) DeleteSchedule(ctx context.Context, id, actor string) error { projectID := "" err := tx.QueryRowContext(ctx, `SELECT project_id FROM schedules WHERE id = ?`, id).Scan(&projectID) if errors.Is(err, sql.ErrNoRows) { - return fmt.Errorf("schedule %s: %w", id, ErrNotFound) + return fmt.Errorf("%w: no schedule %s", ErrNotFound, id) } if err != nil { return err diff --git a/internal/store/summaryreads.go b/internal/store/summaryreads.go index b79448c..c5e74a8 100644 --- a/internal/store/summaryreads.go +++ b/internal/store/summaryreads.go @@ -37,7 +37,7 @@ func (s *Store) MarkSummaryRead(ctx context.Context, login, taskID string, seq i return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error { err := tx.QueryRowContext(ctx, `SELECT id FROM tasks WHERE id = ?`, taskID).Scan(&taskID) if errors.Is(err, sql.ErrNoRows) { - return fmt.Errorf("task %s: %w", taskID, ErrNotFound) + return fmt.Errorf("%w: no task %s", ErrNotFound, taskID) } if err != nil { return err diff --git a/internal/workflow/parse.go b/internal/workflow/parse.go index fd203c2..de57b99 100644 --- a/internal/workflow/parse.go +++ b/internal/workflow/parse.go @@ -14,7 +14,7 @@ func Parse(data []byte) (api.WorkflowDefinition, error) { dec.DisallowUnknownFields() err := dec.Decode(&def) if err != nil { - return api.WorkflowDefinition{}, fmt.Errorf("%w: %v", ErrInvalid, err) + return api.WorkflowDefinition{}, fmt.Errorf("%w: %w", ErrInvalid, err) } return def, Validate(def) } diff --git a/mac/Sources/Byre/Composer.swift b/mac/Sources/Byre/Composer.swift index 64a6f17..3a5ff28 100644 --- a/mac/Sources/Byre/Composer.swift +++ b/mac/Sources/Byre/Composer.swift @@ -650,7 +650,7 @@ private struct ComposerBar: View, Equatable { .frame(height: 14) } .buttonStyle(WebButtonStyle()) - .help(shown ? "Hide the message box" : "Show the message box") + .help(shown ? "Hide the composer" : "Show the composer") #if os(macOS) if !chat.team { menu diff --git a/mac/Sources/Byre/Files.swift b/mac/Sources/Byre/Files.swift index 8e1ccd8..b2eff7b 100644 --- a/mac/Sources/Byre/Files.swift +++ b/mac/Sources/Byre/Files.swift @@ -331,7 +331,7 @@ private struct FilesHead: View { .lineLimit(1) .fixedSize() if let file = p.file, model.content != nil { - Button("Save Copy…") { + Button("Save copy…") { model.save(file) } .buttonStyle(WebButtonStyle()) diff --git a/mac/Sources/Byre/MarkdownView.swift b/mac/Sources/Byre/MarkdownView.swift index 178e344..cacd3e6 100644 --- a/mac/Sources/Byre/MarkdownView.swift +++ b/mac/Sources/Byre/MarkdownView.swift @@ -407,7 +407,7 @@ struct InlineRenderer { render(inner, s, &out) append(run(" ", style), &out) let state = store.taskBusy(task.id) ? .running : store.currentSession(task.id)?.state - var dot = Style(link: AppLink.task(task.id), color: state == .running ? Palette.ok : Palette.muted, small: true, tip: state?.rawValue ?? "no session") + var dot = Style(link: AppLink.task(task.id), color: state == .running ? Palette.ok : Palette.muted, small: true, tip: state?.rawValue ?? "no agent") append(run(state == .running ? "●" : "○", dot), &out) dot.color = Palette.muted dot.tip = nil diff --git a/mac/Sources/Byre/Questions.swift b/mac/Sources/Byre/Questions.swift index 21776bf..6f11c44 100644 --- a/mac/Sources/Byre/Questions.swift +++ b/mac/Sources/Byre/Questions.swift @@ -433,7 +433,7 @@ private struct CardActions: View { } .buttonStyle(WebButtonStyle()) } else { - Button("Ignore") { + Button("Dismiss") { model.dismiss() } .buttonStyle(WebButtonStyle()) diff --git a/mac/Sources/Byre/QuickRun.swift b/mac/Sources/Byre/QuickRun.swift index cb3f4d5..7184e78 100644 --- a/mac/Sources/Byre/QuickRun.swift +++ b/mac/Sources/Byre/QuickRun.swift @@ -8,8 +8,8 @@ struct QuickRunSetting: View { var body: some View { let current = store.me?.quickRun ?? .init(projectId: "", workflow: "") HStack(spacing: 6) { - DropdownMenu(label: current.workflow.isEmpty ? "None" : current.workflow, boxed: true) { - Button("None") { + DropdownMenu(label: current.workflow.isEmpty ? "Off" : current.workflow, boxed: true) { + Button("Off") { save(.init(projectId: "", workflow: "")) } ForEach(store.workflows, id: \.name) { w in diff --git a/mac/Sources/Byre/Startup.swift b/mac/Sources/Byre/Startup.swift index 10697a4..6d48feb 100644 --- a/mac/Sources/Byre/Startup.swift +++ b/mac/Sources/Byre/Startup.swift @@ -367,7 +367,7 @@ final class ConnectForm { return origin } if info == nil, Date().timeIntervalSince(started) > 10 { - throw ProcessFailure(errorDescription: "byre was installed but \(loopback.absoluteString) didn't answer within 10 s.") + throw ProcessFailure(errorDescription: "byre was installed but \(loopback.absoluteString) didn't answer within 10s.") } try await Task.sleep(for: .milliseconds(500)) } @@ -795,8 +795,13 @@ private struct ServerChip: View { .fill(store == nil ? .clear : servers.color(origin)) .stroke(servers.color(origin)) .frame(width: 8, height: 8) - Text(serverName(origin)) - .fontWeight(current ? .bold : .regular) + ZStack { + Text(serverName(origin)) + .font(Fonts.font(13, weight: 700)) + .hidden() + Text(serverName(origin)) + .font(Fonts.font(13, weight: current ? 700 : 400)) + } if questions > 0 { Badge(count: questions) .help("Open questions") diff --git a/mac/Sources/Byre/Store.swift b/mac/Sources/Byre/Store.swift index 85176bf..d52bb97 100644 --- a/mac/Sources/Byre/Store.swift +++ b/mac/Sources/Byre/Store.swift @@ -56,7 +56,7 @@ private let stateTitles: [ByreTask.StatePayload: TaskState] = [ .readyToMerge: TaskState(kind: .ready, label: "Ready to merge", title: "The agent says the task is ready to merge"), .discardSuggested: TaskState(kind: .ready, label: "Suggests discard", title: "The agent suggests discarding the task"), .idle: TaskState(kind: .idle, label: "Idle", title: "Waiting for a message"), - .finished: TaskState(kind: .idle, label: "Finished", title: "The workflow stage finished"), + .finished: TaskState(kind: .idle, label: "Finished", title: "The workflow stage or run finished"), .noAgent: TaskState(kind: .idle, label: "Idle", title: "Waiting for a message"), .merged: TaskState(kind: .idle, label: "Merged", title: "The task was merged"), .discarded: TaskState(kind: .idle, label: "Discarded", title: "The task was discarded"), diff --git a/mac/Sources/Byre/Switcher.swift b/mac/Sources/Byre/Switcher.swift index e8e3609..2ff3b6e 100644 --- a/mac/Sources/Byre/Switcher.swift +++ b/mac/Sources/Byre/Switcher.swift @@ -86,7 +86,7 @@ private let shortcuts: [(String, [(String, String)])] = [ ("⌘P", "Show the current project's dashboard"), ("⌘L", "Open the Lead tab and its composer, closing any view opened over a pane"), ("⌘S", "Merge the right pane's task, or discard it when the agent suggests discarding or there is nothing to merge"), - ("⌘F", "Filter the TODO items on a project's page"), + ("⌘F", "Filter the TODO items on a project's dashboard"), ("⌘[ ⌘]", "Bring the previous or next server's window forward"), ("⌘/", "Show these shortcuts"), ("Esc", "Close the switcher, a dialog, or a view opened over a pane"), diff --git a/mac/Sources/Byre/Updater.swift b/mac/Sources/Byre/Updater.swift index 79c7b6d..3068aa2 100644 --- a/mac/Sources/Byre/Updater.swift +++ b/mac/Sources/Byre/Updater.swift @@ -80,7 +80,7 @@ final class Updater: NSObject, SPUUserDriver, SPUUpdaterDelegate { version = item.displayVersionString let current = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "" let alert = NSAlert() - alert.messageText = "Byre \(item.displayVersionString) is available" + alert.messageText = "byre \(item.displayVersionString) is available" alert.informativeText = "You have \(current)." alert.addButton(withTitle: "Update Now") alert.addButton(withTitle: "Update on Quit") @@ -163,7 +163,7 @@ final class Updater: NSObject, SPUUserDriver, SPUUpdaterDelegate { guard now else { return } - showProgress("Downloading Byre \(version)", total: nil) { [weak self] in + showProgress("Downloading byre \(version)", total: nil) { [weak self] in self?.now = false self?.hideProgress() cancellation() @@ -190,7 +190,7 @@ final class Updater: NSObject, SPUUserDriver, SPUUpdaterDelegate { guard now else { return } - showProgress("Extracting Byre \(version)", total: 1) + showProgress("Extracting byre \(version)", total: 1) } func showExtractionReceivedProgress(_ progress: Double) { @@ -205,7 +205,7 @@ final class Updater: NSObject, SPUUserDriver, SPUUpdaterDelegate { guard now else { return } - showProgress("Installing Byre \(version)", total: nil) + showProgress("Installing byre \(version)", total: nil) } func showUpdateInstalledAndRelaunched(_ relaunched: Bool, acknowledgement: @escaping () -> Void) { diff --git a/mac/Sources/Byre/Workflow.swift b/mac/Sources/Byre/Workflow.swift index 9f7cdbb..33d0f4f 100644 --- a/mac/Sources/Byre/Workflow.swift +++ b/mac/Sources/Byre/Workflow.swift @@ -43,7 +43,7 @@ private func stageLabel(_ s: RunStage) -> String { return attemptLabel(s.attempts.last { $0.output != nil } ?? s.attempts.last!) } if !s.waitingOn.isEmpty { - return "waiting on \(s.waitingOn.map { "“\($0)”" }.joined(separator: ", "))" + return "waiting on \(s.waitingOn.map { "\"\($0)\"" }.joined(separator: ", "))" } return "waiting to start" } @@ -211,12 +211,12 @@ private struct StageCard: View { } } if let only, only.title.caseInsensitiveCompare(stage.name) != .orderedSame { - Text("task “\(only.title)”") + Text("task \"\(only.title)\"") .font(Fonts.font(11)) .foregroundStyle(Palette.muted) } if !stage.after.isEmpty { - Text("after \(stage.after.map { "“\($0)”" }.joined(separator: ", "))") + Text("after \(stage.after.map { "\"\($0)\"" }.joined(separator: ", "))") .font(Fonts.font(11)) .foregroundStyle(Palette.muted) } @@ -254,7 +254,10 @@ private struct AttemptRow: View { if !solo { HStack(alignment: .firstTextBaseline, spacing: 10) { Text("#\(index + 1)").foregroundStyle(Palette.muted) - Text(taskLink(a.taskId, a.title, bold: a.taskId == store.selectedTaskId)) + ZStack(alignment: .leading) { + Text(taskLink(a.taskId, a.title, bold: true)).hidden() + Text(taskLink(a.taskId, a.title, bold: a.taskId == store.selectedTaskId)) + } Text(attemptLabel(a)) .font(Fonts.font(11)) .foregroundStyle(stateColor(a.state.rawValue)) @@ -313,7 +316,7 @@ private struct AttemptRow: View { private func attemptName(_ taskId: String) -> String { for s in run.stages { if let i = s.attempts.firstIndex(where: { $0.taskId == taskId }) { - return s.attempts.count > 1 ? "“\(s.name)” attempt \(i + 1)" : "“\(s.name)”" + return s.attempts.count > 1 ? "\"\(s.name)\" attempt \(i + 1)" : "\"\(s.name)\"" } } return store.findTask(taskId)?.title ?? taskId diff --git a/mac/bundle.sh b/mac/bundle.sh index 2ca1a6b..f0a3583 100755 --- a/mac/bundle.sh +++ b/mac/bundle.sh @@ -25,7 +25,7 @@ rm -rf "$5" "$8" ditto "$2/mac/.build/release/Sparkle.framework" "$5" ditto "$2/mac/.build/release/TailscaleKit.framework" "$7" ' sh "$root" "$shared" "$build/Byre" "$build/byre-hands" "$build/Sparkle.framework" "$build/byre-update" "$build/TailscaleKit.framework" -go -C "$root" build -trimpath -o "$build/server/byre" ./cmd/byre +go -C "$root" build --trimpath -o "$build/server/byre" ./cmd/byre if [ ! "$icns" -nt "$svg" ]; then iconset=$build/byre.iconset rm -rf "$iconset" diff --git a/site/index.html b/site/index.html index 1fb4735..e89c28f 100644 --- a/site/index.html +++ b/site/index.html @@ -16,7 +16,7 @@ <meta property="og:image" content="https://byre.run/card.png"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630"> -<meta property="og:image:alt" content="byre: A crew of coding agents, on all your Macs."> +<meta property="og:image:alt" content="byre: a crew of coding agents, on all your Macs"> <meta name="twitter:card" content="summary_large_image"> <style> @font-face { @@ -1142,7 +1142,7 @@ footer { <li class="row green"><i class="live"></i>fix-login<span class="end">working</span></li> <li class="row green"><i class="live"></i>website<span class="end">working</span></li> <li class="row red"><i></i>deploy<span class="end">needs you</span></li> -<li class="row cyan"><i></i>search<span class="end">in review</span></li> +<li class="row cyan"><i></i>search<span class="end">reviewing</span></li> </ul> </div> <svg class="wires" viewBox="0 0 100 300" preserveAspectRatio="none"> @@ -1292,7 +1292,7 @@ footer { <div class="bar"><i></i><i></i><i></i>byre</div> <div class="app"> <div class="pane behind"> -<div class="tabs"><span class="chip on">Lead</span><span class="chip">Notes</span><span class="chip">Status</span></div> +<div class="tabs"><span class="chip on">Lead</span><span class="chip">Status</span><span class="chip">Notes</span></div> <div class="msg">search has two review findings; it's fixing one.</div> <div class="msg you">show me what changed</div> </div> @@ -1414,7 +1414,7 @@ footer { <div class="bar"><i></i><i></i><i></i>search · review of snapshot #3</div> <div class="body"> <div class="finding red"><i></i><b>A quote in the query breaks the search</b><span class="chip">medium</span><div class="reply"><span class="chip green on">fixing</span>Escaping the query before it reaches the index.</div></div> -<div class="finding orange"><i></i><b>Rename cfg to config</b><span class="chip">low</span><div class="reply"><span class="chip">ignoring</span>Matches the surrounding code.<span class="btn ghost">Fix it anyway</span></div></div> +<div class="finding orange"><i></i><b>Rename cfg to config</b><span class="chip">low</span><div class="reply"><span class="chip">ignoring</span>Matches the surrounding code.<span class="btn ghost">Fix</span></div></div> </div> </div> </div>