diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ca9481..ac2781e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,61 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +Backfill of merged PRs since the 0.1.0 release, grouped by theme. + +### Automation + +- #137 — Session analytics emitted via Claude Code's OpenTelemetry exporter (configure via `CLAUDE_CODE_ENABLE_TELEMETRY` and `OTEL_EXPORTER_OTLP_ENDPOINT`). +- #163 / #165 — Add `remoteControlEnabled` setting; new sessions launch with `--rc` so they can be driven from claude.ai or the mobile app. The `/crow-workspace` skill honors the setting. +- #182 — Auto-complete now requires positive evidence that the session was worked before flipping to Completed; prevents idle sessions being marked done by an unrelated PR merge. +- #189 — Manager terminal launches in `--permission-mode auto` by default so orchestration commands (`crow`, `gh`, `git`) skip per-call approval. Toggle at Settings → Automation → Manager Terminal. +- #209 — Per-workspace opt-in to auto-start review sessions when a PR becomes reviewable. +- #211 — Auto-create a workspace when an issue assigned to you carries the `crow:auto` label. +- #213 — Auto-suggest opening a PR when a session completes its work but no PR is linked yet. +- #214 — Optional auto-respond toggles: when enabled, Crow types an instruction into the session's Claude Code terminal in response to changes-requested reviews and failed CI checks. Off by default. +- #222 — PRs opened from a Crow session are auto-labeled `crow:auto`. +- #228 — Settings split into discrete tabs; every automation toggle lives under Settings → Automation. New `docs/automation.md` covers the full lifecycle. + +### Review Board & Sessions + +- #153 — Fix PR review status not reflecting the actual review state. +- #174 — Ticket card issue and PR chips are now clickable. +- #188 — "Move to Active" button on completed sessions returns them to active without deletion. +- #205 — PR link reconciliation for sessions that missed reactive detection — `gh pr list` is consulted on the next polling cycle. +- #206 — Rename terminals via the UI and via `crow rename-terminal`. +- #207 — `defaults.excludeReviewRepos` filters repos from the review board, badge counts, and notifications. Wildcards supported. +- #210 — Bulk delete for sessions in the sidebar. +- #212 — Multi-select + batch Start Review on the review board. +- #220 — Filtering for the tickets list. +- #226 — Per-section select all and icon-only cancel button in selection mode. +- #231 — Quick action buttons on the session detail header. + +### Terminal Runtime + +- #159 — Fix diagonal window resize and content-driven window growth. +- #161 — Fix batch "Work on" sending a malformed `/crow-batch-workspace` line. +- #218 — Recover from failed Ghostty surface creation by retrying. +- #229 — New tmux backend behind the `CROW_TMUX_BACKEND` feature flag (or Settings → Experimental). Off by default; opt in for a headless-PTY runtime that decouples terminal lifecycle from view rendering. + +### GitLab + +- #215 — Fix GitLab fetch failing when `GITLAB_HOST` did not match the workspace host; reconcile now silently skips GitLab candidates whose host can't be determined. +- #233 — Fix `glab` fetch failures from a non-repo cwd and slug truncation on nested groups (`big-bang/product/packages/elasticsearch-kibana` is no longer truncated to `big-bang/product`). + +### Tooling & Misc + +- #152 — Replace dock icon with the Corveil Brandmark. +- #155 — Docs refresh: README, `make build` promotion, GitHub project scope wording. +- #162 — Silence noisy console logs from Ghostty and IssueTracker. +- #172 — Log `gh` stderr on IssueTracker shell failures. +- #175 — Consolidate IssueTracker `gh` calls into a single GraphQL query. +- #176 — Open-source readiness: license, code of conduct, CI, doc cleanup. +- #178 — CI warms the Ghostty cache on `main` so PRs share it. +- #180 — Fix IssueTracker duplicate-key crash on PR status refresh. +- #185 — Replace the Corveil Brandmark PNG with an SVG for crisper rendering. +- #208 — Ignore subagent hook events fired after a turn's `Stop` so the sidebar dot doesn't get stuck "working". +- #234 — `crow hook-event` is a silent no-op when the Crow app is not running, so non-Crow `claude` sessions don't log noise. + ## [0.1.0] - 2025-04-05 Initial open-source release of Crow. diff --git a/README.md b/README.md index 10aa16b..c8dcf03 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ On first launch, a setup wizard guides you through choosing your development roo - [**CLI Reference**](docs/cli-reference.md) — Every `crow` subcommand and its flags - [**Architecture**](docs/architecture.md) — Packages, key components, data flow - [**Configuration**](docs/configuration.md) — File locations, workspace config, directory layout, session lifecycle +- [**Automation**](docs/automation.md) — Auto-create, auto-respond, auto-complete, and the Settings → Automation tab - [**Troubleshooting**](docs/troubleshooting.md) — Build and runtime errors ## Usage @@ -68,7 +69,7 @@ On first launch, a setup wizard guides you through choosing your development roo ### The Sidebar - **Tickets** — Assigned issues grouped by project board status (Backlog, Ready, In Progress, In Review, Done in last 24h). Click a status to filter. -- **Manager** — A persistent Claude Code terminal for orchestrating work. Use `/crow-workspace` here to create new sessions. Launches in `--permission-mode auto` by default so orchestration commands (`crow`, `gh`, `git`) run without per-call approval; opt out via Settings → General → Manager Terminal. +- **Manager** — A persistent Claude Code terminal for orchestrating work. Use `/crow-workspace` here to create new sessions. Launches in `--permission-mode auto` by default so orchestration commands (`crow`, `gh`, `git`) run without per-call approval; opt out via Settings → Automation → Manager Terminal. - **Active Sessions** — One per work context. Shows repo, branch, issue/PR badges with pipeline and review status. - **Completed Sessions** — Sessions whose PRs have been merged or issues closed. @@ -113,6 +114,31 @@ This will: - Sessions automatically move to "Completed" when their linked PR is merged or issue is closed - Checked every 60 seconds during the issue polling cycle +- Requires positive evidence the session was worked, so an unrelated PR merge can't flip an idle session + +### Automation Suite + +Crow can drive a ticket from assignment to merged with minimal manual steps. Toggles live under **Settings → Automation**; full walkthrough in [docs/automation.md](docs/automation.md). + +- **Auto-create workspace** when an issue assigned to you is labeled `crow:auto` +- **Auto-label PRs** opened from a Crow session with `crow:auto` +- **Auto-suggest opening a PR** if a session completes with no PR linked +- **Auto-start review sessions** for opted-in workspaces when a PR becomes reviewable +- **Auto-respond** to changes-requested reviews and failed CI checks (off by default) + +### Review Board + +- Multi-select with batch Start Review +- Bulk delete sessions +- Filter projects out via `excludeReviewRepos` +- Quick action buttons on the session detail header (open PR, mark in review, copy branch) +- Move completed sessions back to active + +### Terminals + +- Rename tabs from the UI or via `crow rename-terminal` +- Default Ghostty backend with GPU-accelerated rendering +- Opt-in tmux backend (experimental) behind `CROW_TMUX_BACKEND` or Settings → Experimental — see [docs/architecture.md#terminal-backends](docs/architecture.md#terminal-backends) ### Orphan Recovery diff --git a/docs/architecture.md b/docs/architecture.md index 9ec8fb8..faaf998 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -49,6 +49,9 @@ There are two `CrowCLI` directories: | **IssueTracker** | `Sources/Crow/App/IssueTracker.swift` | Polls GitHub/GitLab every 60 seconds for assigned issues, PR status, project board status, auto-completes merged sessions | | **Scaffolder** | `Sources/Crow/App/Scaffolder.swift` | First-run devRoot scaffold: `.claude/` + bundled skills + settings.json | | **TerminalManager** | `Packages/CrowTerminal/.../TerminalManager.swift` | Manages Ghostty `ghostty_surface_t` lifecycle; emits state transitions consumed by `TerminalReadiness` | +| **TmuxBackend** | `Packages/CrowTerminal/.../TmuxBackend.swift` | Headless-PTY backend introduced in #229; opt-in via `CROW_TMUX_BACKEND` or Settings → Experimental | +| **TerminalRouter** | `Sources/Crow/App/TerminalRouter.swift` | Per-terminal dispatch — routes `send` / `destroy` / `trackReadiness` to either Ghostty or tmux based on `SessionTerminal.backend` | +| **AutoRespondCoordinator**| `Sources/Crow/App/AutoRespondCoordinator.swift` | Watches PR review / CI signals and types follow-up instructions into the linked Claude Code terminal (#214) | | **TerminalReadiness** | `Packages/CrowCore/Sources/CrowCore/Models/Enums.swift:41` | Four-state enum (uninitialized → surfaceCreated → shellReady → claudeLaunched) driving the sidebar status dot | | **SocketServer** | `Packages/CrowIPC/` | Unix socket server at `~/.local/share/crow/crow.sock` — receives JSON-RPC commands from the `crow` CLI | | **CrowCommand** | `Packages/CrowCLI/.../CrowCommand.swift` | ArgumentParser root command registering every subcommand | @@ -103,3 +106,44 @@ See `Sources/Crow/App/IssueTracker.swift:636-774` for the full `markInReview` im ## Why Ghostty? Crow embeds [Ghostty](https://ghostty.org) as a terminal emulator via a compiled `libghostty` XCFramework. Ghostty gives each session tab a real GPU-accelerated terminal surface with the same behavior as the standalone Ghostty app, and its C API exposes the `ghostty_surface_t` lifecycle so Crow can track when the shell is ready and auto-launch `claude --continue`. The framework is built from the vendored submodule by `scripts/build-ghostty.sh` (invoked by `make ghostty`). + +## Terminal Backends + +PR #229 introduced a second backend behind the `CROW_TMUX_BACKEND` feature flag. Crow now supports two terminal runtimes side-by-side: + +- **Ghostty (default)** — per-tab `ghostty_surface_t` driven by `TerminalManager`. Each session terminal owns a real `NSView` with GPU-accelerated rendering. This is the original path and remains the default for everyone who has not opted in. +- **tmux (opt-in)** — headless PTY plus a tmux server, driven by `TmuxBackend`. Each session terminal corresponds to a tmux window; rendering is decoupled from the surface so terminals can spin up before any view is materialized. Opt in via either: + - Environment variable `CROW_TMUX_BACKEND=1` (or `true`/`yes`/`on`). + - **Settings → Experimental → Use tmux for managed terminals** (persists in `AppConfig.experimentalTmuxBackend`). + - The two sources are OR-merged. Toggle is decided once at app launch by `FeatureFlags.tmuxBackend` and frozen for the process lifetime — flipping the toggle in Settings requires a relaunch. + +Per-terminal dispatch happens in `Sources/Crow/App/TerminalRouter.swift`. Each `SessionTerminal` carries a `backend: .ghostty | .tmux` discriminator captured at create time, and `TerminalRouter.send` / `destroy` / `trackReadiness` switch on it. This keeps the rest of the app backend-agnostic. + +The tmux backend requires `tmux ≥ 3.3` on `PATH` (typical Homebrew install). If the flag is on but tmux is missing or too old, Crow surfaces an alert at launch with a `brew install tmux` hint and silently falls back to Ghostty for the session. + +The original motivation and full alternative analysis are in [terminal-runtime-research.md](terminal-runtime-research.md). + +## Settings + +PR #228 split Settings into discrete tabs. Each tab maps to a SwiftUI view in `Packages/CrowUI/Sources/CrowUI/`: + +- **General** — devRoot, sidebar density, notifications, sounds. +- **Workspaces** — per-workspace provider, host, branch prefix, and per-workspace auto-review opt-in (#209). +- **Automation** — every automation toggle in one place. See [automation.md](automation.md) for a per-toggle walkthrough. Source: `AutomationSettingsView.swift`. +- **Experimental** — feature flags including the tmux backend toggle. + +Tab state is persisted in `{devRoot}/.claude/config.json` via `CrowPersistence`. + +## Review Board + +The review board is the surface for triaging PRs that have been queued for AI review. Recent PRs added these capabilities: + +- **Exclude list** (#207) — repos in `defaults.excludeReviewRepos` are filtered from the board, badge counts, and notifications. Wildcards supported. +- **Auto-start** (#209) — per-workspace toggle that auto-creates a review session when a PR becomes reviewable. +- **PR link reconciliation** (#205) — sessions whose hook events missed a PR open are reconciled against `gh pr list` on the next polling cycle so the session detail surface still shows the correct PR. +- **Bulk delete** (#210) — sidebar selection mode that lets you remove multiple sessions at once. +- **Multi-select + batch Start Review** (#212) — review-board selection mode for kicking off several reviews in one click. +- **Filtering** (#220) — inline filter on the tickets list, mirrored across the review board. +- **Per-section select all + icon-only cancel** (#226) — UX polish on selection mode. +- **Quick action buttons on session detail header** (#231) — surface the most-used session actions (open PR, mark in review, copy branch) directly on the detail view. +- **Move to Active** (#188) — return a completed session to active without deleting it. diff --git a/docs/automation.md b/docs/automation.md new file mode 100644 index 0000000..f294e8b --- /dev/null +++ b/docs/automation.md @@ -0,0 +1,103 @@ +# Automation + +Crow automates the boring parts of moving a ticket from "assigned" to "merged". This page is the single source of truth for what each automation does, how to turn it on or off, and where the toggles live. + +## Lifecycle + +A fully automated ticket walks through these stages: + +1. **Assignment** — an issue is assigned to you. If it carries the `crow:auto` label, Crow auto-creates a workspace for it (#211). +2. **Workspace** — a git worktree is created, ticket metadata is captured, and the issue is moved to "In Progress" on the project board. +3. **Session** — Claude Code launches in plan mode with the issue context. Worker sessions inherit the configured permission mode; the Manager terminal can launch with `--permission-mode auto` (#189). +4. **PR open** — when Claude pushes the branch and you open a PR, Crow auto-suggests opening one if you forget (#213) and auto-applies the `crow:auto` label so the PR is recognizable downstream (#222). +5. **Review** — repos that opt in get a review session auto-started when the PR turns reviewable (#209). The review board lets you batch-start, bulk-delete, and filter sessions (#207, #210, #212, #220, #226, #231). +6. **Status response** — Crow can prompt Claude to fix changes-requested reviews and failing CI runs without you typing anything (#214). +7. **Completion** — the session moves to Completed once the PR is merged or the issue is closed *and* the session shows positive evidence the work was attempted (#182). Session analytics are emitted via Claude Code's OpenTelemetry pipeline (#137). + +## Settings → Automation tab + +PR #228 split every automation toggle out of General into its own tab. Open **Settings → Automation** to find: + +### Reviews + +- **Excluded Repos** — comma-separated list of repos to hide from the review board, sidebar badge counts, and review notifications. Supports `*` wildcards: `zarf-dev/*` hides every repo in the org; `bmlt-enabled/yap` hides one. Backed by `defaults.excludeReviewRepos` in `{devRoot}/.claude/config.json`. Per-workspace auto-review opt-ins (#209) are configured separately in **Workspaces → edit workspace**. + +### Tickets + +- **Excluded Repos** — comma-separated, wildcard-aware list of repos to hide from the ticket board, pipeline counts, and auto-create candidates. Backed by `defaults.excludeTicketRepos`. An issue in an excluded repo will not be considered for auto-create even if it carries the `crow:auto` label. + +### Remote Control + +- **Enable remote control for new sessions** — when on, new Claude Code sessions launch with `--rc` so you can drive them from claude.ai or the Claude mobile app. Each session's remote name matches its Crow session name. Backed by `remoteControlEnabled`. Off by default. + +### Manager Terminal + +- **Launch in auto permission mode** — passes `--permission-mode auto` to the Manager's `claude` invocation so orchestration commands (`crow`, `gh`, `git`) run without per-call approval prompts. Default **on**. Requires: + - Claude Code **2.1.83+** + - **Max / Team / Enterprise / API** plan + - **Anthropic** API provider (not Bedrock / Vertex / Foundry) + - A supported model: **Sonnet 4.6**, **Opus 4.6**, or **Opus 4.7** + - On Team / Enterprise plans, an admin must enable auto mode in Claude Code admin settings. + + Turn this off if your account reports auto mode as unavailable. Worker sessions and CLI-spawned terminals are unaffected. Takes effect on next app launch — the Manager's stored command is rebuilt on hydration. + +### Auto-respond + +PR #214 added two opt-in toggles that let Crow type a follow-up instruction into a session's Claude Code terminal when a PR signal arrives. Both are off by default — typing into a running terminal unprompted is intrusive. + +- **Respond to "changes requested" reviews** — when a PR review requests changes, Crow types an instruction into the linked session's Claude Code terminal asking Claude to read the review and address each comment. +- **Respond to failed CI checks** — when CI checks transition to failure, Crow types an instruction asking Claude to investigate the logs and push a fix. + +Both toggles read from `AutoRespondSettings` in `AppConfig`. The session must have an active Claude Code terminal for the instruction to land. + +## Per-PR feature notes + +Short descriptions of each shipped automation, in roughly the order they fire during the lifecycle. + +### #211 — Auto-create workspace on `crow:auto` label + +When an issue assigned to you carries the `crow:auto` label, the issue tracker auto-creates a workspace for it on the next polling cycle (every 60s). It picks the right repo, opens a worktree, captures ticket metadata, and launches Claude Code in plan mode with the issue context. Issues in `excludeTicketRepos` are skipped. + +### #189 — Manager auto permission mode + +The Manager terminal launches in `--permission-mode auto` by default so orchestration commands run without prompts. Toggle is at **Settings → Automation → Manager Terminal**. See above for plan / model requirements. + +### #182 — Positive-evidence auto-complete + +Auto-complete (PR merged / issue closed) no longer fires solely on the GitHub signal. The session must also show positive evidence that work was attempted — at minimum a started Claude Code terminal with non-empty activity. This prevents idle sessions from being marked completed when an unrelated PR lands. + +### #213 — Auto-suggest opening a PR + +When a session completes its work locally but no PR is linked, Crow surfaces a "Open PR" suggestion on the session detail surface. Clicking it walks Claude Code through `gh pr create` against the session's branch. + +### #222 — Auto-label PRs with `crow:auto` + +When a PR is opened from a Crow session, the PR is automatically labeled `crow:auto` so it's distinguishable from PRs you opened manually. This is the same label that drives auto-creation (#211) and is used by downstream tooling (review filters, status responders). + +### #209 — Auto-start review sessions for opted-in repos + +A per-workspace setting (Workspaces → edit workspace → Auto-review). When on, any reviewable PR in that workspace's repos triggers a review session in the background — Crow clones into `{devRoot}/crow-reviews/`, launches Claude Code with the review prompt, and surfaces it on the review board when ready. + +### #214 — Auto-respond to PR status changes + +See the **Auto-respond** toggles in the Settings tab section above. Crow watches the PR for review-changed and check-failed transitions on the standard 60-second polling cycle. + +### #137 — Session analytics via OpenTelemetry + +Claude Code's OpenTelemetry exporter is wired up so each session emits standard OTLP metrics for token counts, tool-call latency, and turn duration. Configuration follows Claude Code's own env vars (e.g. `CLAUDE_CODE_ENABLE_TELEMETRY`, `OTEL_EXPORTER_OTLP_ENDPOINT`); Crow does not collect telemetry itself. + +## Where it lives + +| Concern | File | +| -------------------------------- | ------------------------------------------------------------------------------------------------- | +| Settings tab UI | `Packages/CrowUI/Sources/CrowUI/AutomationSettingsView.swift` | +| Persisted toggles | `Packages/CrowCore/Sources/CrowCore/Models/AppConfig.swift` (`ConfigDefaults`, `AutoRespondSettings`) | +| Manager auto-permission decision | `Sources/Crow/App/AppDelegate.swift` (Manager command rebuild) | +| Auto-create / auto-respond loop | `Sources/Crow/App/IssueTracker.swift` (60s polling cycle) | +| Review session auto-start | `Sources/Crow/App/IssueTracker.swift` + per-workspace flag in `AppConfig` | + +## See also + +- [Configuration](configuration.md) — full schema for `{devRoot}/.claude/config.json`, including `excludeReviewRepos`, `excludeTicketRepos`, `remoteControlEnabled`, and `managerAutoPermissionMode`. +- [Getting Started](getting-started.md) — first-launch setup that creates the config file these toggles write to. +- [Troubleshooting](troubleshooting.md) — what to do when an automation does not fire as expected. diff --git a/docs/cli-reference.md b/docs/cli-reference.md index 9e26bde..9bf505d 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -212,6 +212,22 @@ Close a terminal tab in a session. crow close-terminal --session --terminal ``` +### `crow rename-terminal` + +Rename a terminal tab. The new name is positional. + +```bash +crow rename-terminal --session --terminal "Build watcher" +``` + +| Arg / Flag | Required | Description | +| ----------------------- | -------- | ----------------- | +| `--session` | yes | Session UUID | +| `--terminal` | yes | Terminal UUID | +| *(positional)* `NAME` | yes | New terminal name | + +Returns `{"session_id": "...", "terminal_id": "...", "name": "..."}`. + ### `crow send` Write text to a terminal. Newlines in `TEXT` are converted to Enter keypresses; include a trailing newline to submit a command. diff --git a/docs/configuration.md b/docs/configuration.md index a158ec6..be81a04 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -59,8 +59,10 @@ All persistent state lives under `~/Library/Application Support/crow/` (see `Pac - **`host`** — set for self-hosted GitLab; exported as `GITLAB_HOST` when invoking `glab`. - **`branchPrefix`** — used by the `/crow-workspace` skill when creating new branches. - **`excludeDirs`** — ignored when scanning repos for git worktrees. -- **`excludeReviewRepos`** — repos to hide from the review board (e.g., `["zarf-dev/zarf"]`). Supports `*` wildcards (e.g., `"zarf-dev/*"`). Matching reviews are filtered out from the board, sidebar badge count, and notifications. -- **`excludeTicketRepos`** — repos to hide from the ticket board (e.g., `["zarf-dev/zarf"]`). Supports `*` wildcards (e.g., `"zarf-dev/*"`). Matching issues are filtered out from the board, pipeline counts, and auto-create candidates. +- **`excludeReviewRepos`** — repos to hide from the review board (e.g., `["zarf-dev/zarf"]`). Supports `*` wildcards (e.g., `"zarf-dev/*"`). Matching reviews are filtered out from the board, sidebar badge count, and notifications. Editable in Settings → Automation → Reviews. +- **`excludeTicketRepos`** — repos to hide from the ticket board (e.g., `["zarf-dev/zarf"]`). Supports `*` wildcards (e.g., `"zarf-dev/*"`). Matching issues are filtered out from the board, pipeline counts, and auto-create candidates. Editable in Settings → Automation → Tickets. + +For the full set of automation toggles backed by this config, see [automation.md](automation.md). ## Manager Terminal @@ -90,11 +92,13 @@ Worktrees are created **at the same level as the main repo**, not in a `worktree ## Environment Variables -| Variable | Purpose | Default | -| ------------- | ---------------------------------------------------------------- | ------------------------------ | -| `CROW_SOCKET` | Override the Unix socket path for CLI ↔ app IPC | `~/.local/share/crow/crow.sock` | -| `TMPDIR` | Temporary file directory (used by the terminal subsystem) | System default | -| `GITLAB_HOST` | GitLab instance hostname (set automatically per workspace) | — | +| Variable | Purpose | Default | +| --------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------ | +| `CROW_SOCKET` | Override the Unix socket path for CLI ↔ app IPC | `~/.local/share/crow/crow.sock` | +| `TMPDIR` | Temporary file directory (used by the terminal subsystem) | System default | +| `GITLAB_HOST` | GitLab instance hostname (set automatically per workspace from `host` in `config.json`) | — | +| `CROW_TMUX_BACKEND` | Set to `1`/`true`/`yes`/`on` to opt into the tmux terminal backend (#229). OR-merged with the Settings → Experimental toggle. Frozen at app launch — relaunch to flip. | unset (Ghostty backend) | +| `CROW_HOOK_DEBUG` | Set to `1` to enable `[hook-event]` debug logging | unset | ## Session Lifecycle diff --git a/docs/getting-started.md b/docs/getting-started.md index edb18c3..741ee9d 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -170,5 +170,6 @@ Alternatively, you can scaffold without launching the GUI by running the CLI set - [CLI reference](cli-reference.md) — every `crow` subcommand and its flags - [Configuration](configuration.md) — file locations, workspace config schema, directory layout +- [Automation](automation.md) — Settings → Automation toggles for auto-create, auto-respond, and the rest of the auto-flow - [Architecture](architecture.md) — packages, key components, data flow - [Troubleshooting](troubleshooting.md) — common errors and fixes diff --git a/docs/terminal-runtime-research.md b/docs/terminal-runtime-research.md index d400600..5c1700f 100644 --- a/docs/terminal-runtime-research.md +++ b/docs/terminal-runtime-research.md @@ -747,3 +747,18 @@ write(masterfd, text, length); // Send input to shell - [macOS Metal + NSView Setup](https://metashapes.com/blog/advanced-nsview-setup-opengl-metal-macos/) - [Apple Developer Forums — Swift PTY](https://developer.apple.com/forums/thread/688534) - [Apple Developer Forums — forkpty in sandbox](https://developer.apple.com/forums/thread/685544) + +--- + +## Implementation Status (2026-05) + +The "long-term" recommendation in this document — a headless PTY backend that decouples terminal lifecycle from view rendering — landed in PR #229 as the **tmux backend**, behind the `CROW_TMUX_BACKEND` feature flag. tmux's control-mode protocol gives Crow a stable PTY supervisor without writing one from scratch, while a Swift `TmuxBackend` wraps the per-window operations Crow needs (spawn, send text via paste-buffer route, destroy). + +- Default backend remains Ghostty (`TerminalManager`). +- Opt in via `CROW_TMUX_BACKEND=1` or **Settings → Experimental → Use tmux for managed terminals**. The two sources are OR-merged at launch and frozen for the process lifetime. +- Per-terminal dispatch happens in `Sources/Crow/App/TerminalRouter.swift` based on `SessionTerminal.backend`. +- Requires `tmux ≥ 3.3`; missing-tmux is detected at launch and surfaced via a one-shot alert with a `brew install tmux` hint. + +The short-term recommendation (offscreen `NSWindow` to unblock surface creation, see PR #105) was implemented earlier and is in production today. PR #218 added retry on Ghostty surface creation failure as a follow-up reliability fix. + +See [architecture.md › Terminal Backends](architecture.md#terminal-backends) for the integration layer and [troubleshooting.md](troubleshooting.md) for common tmux-backend failure modes. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 2682a12..13b326d 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -15,15 +15,18 @@ | Problem | Solution | | -------------------------------------------------------- | ------------------------------------------------------------------------ | -| `crow` CLI: "Connection refused" | The Crow app must be running — the CLI communicates via Unix socket at `~/.local/share/crow/crow.sock` | +| `crow` CLI: "Connection refused" | The Crow app must be running — the CLI communicates via Unix socket at `~/.local/share/crow/crow.sock`. As of #234, `crow hook-event` is a silent no-op when the app is not running, so non-Crow `claude` sessions no longer log noise. | | GitHub API errors / empty issue list | Check auth: `gh auth status`. Ensure scopes include `repo`, `read:org`, `project`. If missing, run `gh auth refresh -s project,read:org,repo`. | | `INSUFFICIENT_SCOPES` in `[IssueTracker]` stderr | Run `gh auth refresh -s project`. **`read:project` is NOT sufficient** — the write `project` scope is required to update ticket status via `updateProjectV2ItemFieldValue`. See `Sources/Crow/App/IssueTracker.swift:691-692,768-769`. | | Ticket stays "Backlog" when starting a session | Same as above — the `markInReview` code path requires the write `project` scope | -| Terminal not starting | Check stderr for `[TerminalManager]` or `[Ghostty]` messages | +| Terminal not starting | Check stderr for `[TerminalManager]` or `[Ghostty]` messages. As of #218, Crow retries failed Ghostty surface creation; if a terminal is stuck, close and reopen it from the session detail header. | +| tmux backend not starting | If `CROW_TMUX_BACKEND=1` (or Settings → Experimental → tmux toggle) is set but tmux is missing, Crow surfaces a launch alert with a `brew install tmux` hint and falls back to Ghostty. Verify with `tmux -V`; tmux ≥ 3.3 is required. The flag is frozen at launch — relaunch the app after toggling. | | Issue tracker shows no tickets | Verify `gh auth status` shows `repo`, `read:org`, `project` scopes | -| GitLab tickets missing | Run `glab auth status --hostname `; ensure `GITLAB_HOST` matches what's in `{devRoot}/.claude/config.json` | +| GitLab tickets missing | Run `glab auth status --hostname `; ensure `GITLAB_HOST` matches what's in `{devRoot}/.claude/config.json`. After #215, Crow silently skips GitLab candidates whose host can't be determined instead of failing the whole reconcile pass — check the workspace's `host` field if a repo isn't being polled. | +| GitLab nested-group repo fails to fetch | Slug parsing was widened in #233 to preserve nested paths like `big-bang/product/packages/elasticsearch-kibana`. If a fetch still fails, run `glab repo view ` from inside the worktree to confirm the slug, and check `glab auth status --hostname `. | | Sidebar status dot stuck gray | Terminal never initialized — click the session tab to trigger `createSurface()` | | Sidebar status dot stuck yellow | Shell is spawning but the probe file never appeared. Check `[TerminalManager]` logs for shell-startup errors | +| Auto-respond didn't fire on a failed CI run | Toggle is at **Settings → Automation → Auto-respond**, off by default. The session must have an active Claude Code terminal that `TerminalRouter.canSend` accepts; a torn-down terminal won't receive the prompt. See [automation.md](automation.md) for full coverage. | | Sidebar shows "working" forever after a `※ recap:` line | The Claude Code session recap (`awaySummaryEnabled`, on by default in v2.1.108+) fires hook events after a turn's `Stop`. Crow now ignores those — if you're on an older build, disable the recap by setting `"awaySummaryEnabled": false` in `~/.claude/settings.json`, toggling "Session recap" off via `/config` inside Claude Code, or exporting `CLAUDE_CODE_ENABLE_AWAY_SUMMARY=0`. | ## Debugging @@ -35,6 +38,7 @@ The app logs diagnostic information to stderr with component tags: - `[IssueTracker]` — GitHub/GitLab API errors, scope issues, project status queries - `[JSONStore]` — Decode failures (store data loss prevention) - `[Ghostty]` — Surface creation success/failure +- `[TerminalRouter]` — tmux send/destroy errors when the tmux backend is enabled (#229) - `[AppSupportDirectory]` — One-time `rm-ai-ide` → `crow` migration events - `[Scaffolder]` — Template file loading (development builds) - `[hook-event]` — Claude Code hook event arrivals and `ClaudeState` transitions. Off by default. Set `CROW_HOOK_DEBUG=1` before launching to enable; useful when diagnosing why the sidebar status dot is in the wrong state.