diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 0123f12..09c2cfe 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -11,15 +11,14 @@ { "name": "bauto", "source": "./src/automator/data/skills", - "description": "Automation-mode skills driven by the bmad-auto orchestrator: unattended dev (bmad-auto-dev), adversarial review (bmad-auto-review), and deferred-work sweep triage (bmad-auto-sweep)", - "version": "0.6.4", + "description": "Automation-mode skills driven by the bmad-auto orchestrator: interactive escalation resolution (bmad-auto-resolve) and deferred-work sweep triage (bmad-auto-sweep) — the inner dev primitive (which self-reviews and commits) is the upstream bmad-dev-auto skill", + "version": "0.7.0", "author": { "name": "pinkyd" }, "skills": [ "./src/automator/data/skills/bmad-auto-setup", - "./src/automator/data/skills/bmad-auto-dev", - "./src/automator/data/skills/bmad-auto-review", + "./src/automator/data/skills/bmad-auto-resolve", "./src/automator/data/skills/bmad-auto-sweep" ] } diff --git a/.gitignore b/.gitignore index cf586a7..ab50408 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ dist/ _bmad/ dev/skills/bmad-release/ RELEASING.md +_bmad-output/ diff --git a/CHANGELOG.md b/CHANGELOG.md index ceb1403..3708e60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,113 @@ All notable changes to `bmad-auto` are documented here. The format is based on [Semantic Versioning](https://semver.org/spec/v2.0.0.html). While the project is pre-1.0, breaking changes may land in a minor release. +## [0.7.0] — 2026-06-24 + +### Changed + +- **Retired the `bmad-auto-dev` fork; the orchestrator now drives the upstream `bmad-dev-auto` + skill unmodified** (bmad-code-org/BMAD-METHOD#2500, merged upstream) as its sole dev primitive. + The skill is the inner autonomous coding session; everything automator-specific — escalation, + sprint/ledger bookkeeping, repair-resume — stays in the orchestrator, which synthesizes + `result.json` from the spec the skill leaves on disk. There is no fork to keep in sync with upstream. + +- **Review is now a re-invocation of `bmad-dev-auto` on the done spec, not a separate skill.** + `bmad-dev-auto` routes a `status: done` spec to a fresh step-04 review pass (BMAD-METHOD#2508), so + the orchestrator's follow-up review just re-runs `/bmad-dev-auto ` in a fresh context. + `review.enabled` still gates whether that follow-up pass runs at all; the new `review.trigger` knob + (see Added) decides when it fires. The loop converges when a pass finishes `done` without the skill + setting `followup_review_recommended`, still bounded by `limits.max_review_cycles` (default 3). + +- **The skill commits each iteration; the orchestrator squashes to one commit per story.** + `bmad-dev-auto` now commits its own work at the end of a successful run (BMAD-METHOD#2506). At + finalize the orchestrator collapses that chain plus its own sprint/ledger writes back onto the + pre-dev baseline into a single commit carrying the configured message — `pre_commit`/`post_commit` + hooks and `scm.commit_message_template` stay authoritative. + +### Added + +- **Skill-recommended review (`review.trigger`).** `bmad-dev-auto` self-reviews inline and sets + `followup_review_recommended` on a `done` spec when its changes warrant an independent pass + (BMAD-METHOD#2505). The orchestrator consumes it: `review.trigger = "recommended"` (new default) + runs the follow-up `bmad-dev-auto` review pass only when flagged; `"always"` keeps the old + run-every-story behavior. Adjustable in the TUI and `policy.toml`. The follow-up loop stays bounded + by `limits.max_review_cycles` (default 3) — the oscillation guard — so a skill-recommended review + can never loop indefinitely. + +- **Non-bundled-skill preflight.** `bmad-auto validate` and run/sweep/resume start verify that + `bmad-dev-auto` and the two adversarial review hunters (`bmad-review-adversarial-general`, + `bmad-review-edge-case-hunter`) — which `bmad-dev-auto`'s step-04 invokes inline on every run — are + installed in each active CLI skill tree, failing loudly with remediation instead of stalling mid-run + on an `Unknown command`. Worktree provisioning copies these upstream skills from the main repo, + since they are not bundled in the wheel. + +- **`result.json` `workflow` is now an enforced contract on the dev path.** `verify_dev` / + `verify_dev_bundle` reject a mismatch against `verify.DEV_WORKFLOW` (`"auto-dev"`); the synthesized + result carries `"auto-dev"`. Review re-runs the same skill, so it carries the same tag, and + `verify_review` stays purely disk-derived — it is never handed the result.json. + +- **Pluggable terminal-multiplexer seam (groundwork for native Windows).** All tmux usage now goes + through a `TerminalMultiplexer` ABC (`get_multiplexer()`); `TmuxMultiplexer` is the only code that + shells out to `tmux` and the only place the POSIX `sh -c` parked-window trailer lives. The generic + adapter (renamed `generic_tmux.py` → `generic.py`), `runs.py`, `tui/launch.py`, `probe.py`, and + `tui/data.py` all route through it, so a future non-tmux backend slots in with no engine changes. + Behavior on Linux/macOS/WSL is byte-identical; **no native-Windows backend ships yet** (see [ROADMAP](docs/ROADMAP.md)). + +- **POSIX portability hardening + CI guard.** Scattered POSIX-only primitives are guarded behind a + platform seam — `SIGKILL` fallback, detach kwargs, `terminate_pid`, `os.devnull` — and the Unity + plugin degrades off Linux (`/proc` → `psutil` via a new optional `windows` extra, `/tmp`, `cp -a` + CoW, symlinks, `start_new_session`), keeping every Linux fast path unchanged. A new + `tests/test_portability_guard.py` AST/byte scan blocks new POSIX-only patterns from creeping back, + with sanctioned exceptions carrying `# portability:` acks. + +- **Adapter & profile authoring guide.** `docs/adapter-authoring-guide.md` now carries the complete + `CLIProfile` / `HookSpec` field reference (the single canonical schema home) and a "writing a new + adapter class" section for non-tmux transports — linked from the README documentation index. + +### Removed + +- **Retired the bundled `bmad-auto-dev` and `bmad-auto-review` skills.** `bmad-auto init` now installs + three bundled skills — `bmad-auto-resolve`, `bmad-auto-sweep`, `bmad-auto-setup` — and the upstream + `bmad-dev-auto` skill (from a recent bmm module) is a hard prerequisite. `bmad-auto-review`'s + adversarial review is fully covered by `bmad-dev-auto`'s inline step-04 (Blind + Edge-Case hunters); + the independent Acceptance Auditor layer is dropped, and the two hunters are now always-required base + skills rather than gated on `review.enabled`. The canonical `deferred-work-format.md` moved into + `bmad-auto-sweep`, its remaining owner. + +### Fixed + +- **Resolving a CRITICAL escalation no longer loops on a manual-rollback prompt.** Re-arming an + escalation requests a clean rebuild, which in non-worktree (in-place) runs means resetting to the + story baseline. With the default `scm.rollback_on_failure = false` the orchestrator paused for a + manual reset — but never cleared `baseline_commit`, so following the instructions (`git reset --hard`, + then `resume`) re-paused on the next resume, an endless loop. `_rollback_or_pause` now no-ops when the + tree is already at baseline (nothing this attempt touched), so a clean tree — including one the + operator just reset — proceeds straight to the re-drive. The same guard suppresses the spurious prompt + when an escalation left no changes at all. +- **Manual-recovery notice wording.** The prompt no longer claims the story "failed" — it now reflects + the real cause ("escalation was resolved; re-driving needs a clean baseline" vs. "attempt was stopped"). +- **Resolved escalations now actually re-drive instead of HALTing on a stale `blocked` spec.** `verify_dev` + only recorded `task.spec_file` on a fully successful session, so a dev session that escalated with a + `blocked` spec (the common escalation case) left it unset. `rearm_escalation` then had no spec path to + flip to `ready-for-dev`, so on resume `bmad-dev-auto`'s step-01 routing re-HALTed on the still-`blocked` + frontmatter — a second loop. The orchestrator now captures the spec the session produced when it + escalates or defers (the synthesized result names it even on a HALT), so re-arm flips the status and + the re-drive proceeds, and a deferred story's spec is stashed as intended. +- **Copilot dev stage no longer stalls on a subagent `agentStop`.** Copilot fires `agentStop` for + every subagent turn too — with an empty `transcriptPath` and a tool-use session id, not the main + session's turn-end. With dev decoupled to `bmad-dev-auto` (which implements via subagents), that + premature Stop reached the dev stage, where 0 nudges made the orchestrator declare an outright stall + before the skill wrote its terminal spec (same root cause as the 0.6.4 review stall). A new + per-profile `subagent_stop_without_transcript` (true for `copilot`) ignores a `Stop` carrying no + transcript, so the main session's real turn-end drives completion — and restores usage tallying, + since that Stop carries the transcript. +- **Process liveness/termination no longer risks signaling the wrong process.** A corrupt + `engine.pid` read as `0` or negative would make `os.kill` target a process group — for `0`, the + orchestrator's own — so `pid_alive`/`terminate_pid` now reject non-positive PIDs before signaling. + The remaining liveness checks (`runs.py`, `tui/data.py`) that called `os.kill(pid, 0)` directly now + route through `pid_alive`, since on Windows `os.kill(pid, 0)` maps to `TerminateProcess` and is + destructive; a CI guard blocks bare `os.kill(_, 0)` from regressing. + ## [0.6.4] — 2026-06-21 ### Fixed @@ -491,6 +598,7 @@ enforced in CI. implementation phase, driven by a Python control loop with hook-based session transport and resumable on-disk run state. +[0.7.0]: https://github.com/bmad-code-org/bmad-auto/releases/tag/v0.7.0 [0.6.4]: https://github.com/bmad-code-org/bmad-auto/releases/tag/v0.6.4 [0.6.3]: https://github.com/bmad-code-org/bmad-auto/releases/tag/v0.6.3 [0.6.2]: https://github.com/bmad-code-org/bmad-auto/releases/tag/v0.6.2 diff --git a/README.md b/README.md index 7067a9a..ba426bf 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,8 @@ Inspired by the original [bmad-automator](https://github.com/bmad-code-org/bmad- ## Requirements - **Python 3.11+**, **tmux**, and a supported coding CLI — `claude` by default; `codex` and `gemini` via [profiles](#other-coding-clis). -- A **BMAD v6 project** (`_bmad/bmm/config.yaml`, a `sprint-status.yaml` from `bmad-sprint-planning`) with the automator skill module from this repo installed (`bmad-auto-dev`, `bmad-auto-review`, `bmad-auto-sweep` — see [Installing the skill module](#installing-the-skill-module)). Standard BMAD skills stay untouched. +- **Linux or macOS** (or **Windows via WSL**, which _is_ Linux — it runs as-is). tmux is the one terminal-multiplexer backend today, but it now sits behind a pluggable seam (`TerminalMultiplexer`), so a native-Windows backend can slot in later without touching the engine — see the [adapter authoring guide](docs/adapter-authoring-guide.md#two-axes-cli-vs-transport). Native Windows is not yet shipped. +- A **BMAD v6 project** (`_bmad/bmm/config.yaml`, a `sprint-status.yaml` from `bmad-sprint-planning`) with the upstream `bmad-dev-auto` skill and the automator skill module from this repo installed (`bmad-auto-resolve`, `bmad-auto-sweep` — see [Installing the skill module](#installing-the-skill-module)). Standard BMAD skills stay untouched. ## Quick start @@ -157,23 +158,24 @@ Press **`g`** to edit `.automator/policy.toml` in a form grouped by section — ```text sprint-status.yaml: 1-2-account-mgmt: ready-for-dev │ - ├─ DEV tmux window: claude "/bmad-auto-dev 1-2-account-mgmt" - │ bmad-auto-dev: plans a 1.5–4k-token spec, - │ auto-approves it, implements, syncs sprint → review, - │ writes result.json … Stop hook signals the orchestrator - ├─ VERIFY spec exists · status in-review · baseline matches · diff non-empty + ├─ DEV tmux window: claude "/bmad-dev-auto 1-2-account-mgmt" + │ bmad-dev-auto: plans a 1.5–4k-token spec, auto-approves it, + │ implements, self-reviews inline (Blind + Edge-Case hunters), + │ commits, finalizes spec → done … Stop hook signals the orchestrator + ├─ VERIFY spec exists · status done · baseline matches · diff non-empty │ · run [verify].commands (pytest, ruff…) — a broken build never │ reaches review; a failure spawns a fix session fed the output - ├─ REVIEW fresh window: claude "/bmad-auto-review " - │ static prefilter → 3 layers (Blind Hunter / Edge Case Hunter / - │ Acceptance Auditor) → verify findings against code → triage → - │ auto-apply patches → ledger → defer ambiguity → done when clean - │ (bounded loop, default 3 cycles) + ├─ REVIEW fresh window: claude "/bmad-dev-auto " — re-invoking on a + │ (gated) done spec runs a fresh independent step-04 review pass (Blind + Edge-Case + │ hunters → triage → auto-apply patches → ledger → defer ambiguity → + │ commit). Gated on the skill's `followup_review_recommended` flag + │ (review.trigger = "recommended") or every story ("always"); bounded + │ loop, default 3 cycles ├─ VERIFY spec done · sprint done · run [verify].commands again — a failure │ routes a feedback-driven dev fix session, then a fresh review cycle - └─ COMMIT orchestrator commits (then, under [scm] isolation = "worktree", - merges the unit branch back into the target branch locally); - epic boundary → gate / retro notification + └─ COMMIT orchestrator squashes the iteration's commits into one story commit + (then, under [scm] isolation = "worktree", merges the unit branch + back into the target branch locally); epic boundary → gate / retro ``` **Failure handling:** bounded dev retries (verify-command failures keep the tree and feed the failing output to the next session via `--feedback`; other failures roll back to baseline), **plateau-defer** when review won't converge (story skipped, spec stashed into the run dir, `deferred-work.md` additions preserved, run continues), and typed escalations — `CRITICAL` pauses the run and notifies you (desktop + `ATTENTION` file), `PREFERENCE` is journaled and the run continues. @@ -197,9 +199,10 @@ bmad-auto sweep [--no-prompt] [--decisions-only] [--max-bundles N] [--repeat] [- │ terminal (build / close / keep-open per option, with a │ recommendation); answers land in the ledger as `decision:` │ lines. Unattended runs skip this and leave decisions open. - └─ BUNDLES each bundle runs the normal pipeline: bmad-auto-dev (--dw-bundle) - → bmad-auto-review → verify commands → commit. The review gate also - checks every bundle entry is `status: done` in the ledger. + └─ BUNDLES each bundle runs the normal pipeline: bmad-dev-auto (on the bundle + spec, then re-invoked on the done spec for review) → verify commands + → commit. The review gate also checks every bundle entry is + `status: done` in the ledger. ``` **Answering missed decisions later.** An unattended sweep (`--no-prompt`) skips decisions, and an interactive one can be abandoned before you answer them all — those answers would otherwise be lost, since triage re-derives the decision set from the ledger every run. `bmad-auto decisions` (or press `d` in the TUI) surfaces every decision past sweeps left unanswered, reconstructed from their triage output, and lets you answer them out of band. A `close` is applied immediately; a `build`/`keep-open` is saved to `.automator/decisions.json` and consumed by the next sweep (build → bundle, keep-open → recorded) with no re-prompt. `--list` shows them without answering; `bmad-auto status` reports the outstanding count. @@ -210,15 +213,14 @@ Bundle dev sessions can themselves append new deferred entries (split-off goals, ## Installing the skill module -The orchestrator drives its own forks of the BMAD dev/review skills — your standard BMAD install is never modified. The five skills are bundled in the `bmad-auto` wheel (canonical source: `src/automator/data/skills/`, BMAD module code `bauto`) so `bmad-auto init` lays them down for you: +The orchestrator drives the upstream `bmad-dev-auto` skill as its inner dev primitive — unmodified, so there is no fork to keep in sync; it both implements and (re-invoked on the done spec) runs the follow-up review — plus its own bundled `bmad-auto-*` skills for escalation, sweep, and setup. Your standard BMAD install is never modified. The three bundled skills ship in the `bmad-auto` wheel (canonical source: `src/automator/data/skills/`, BMAD module code `bauto`) so `bmad-auto init` lays them down for you; `bmad-dev-auto` is a prerequisite installed by the BMad Method (bmm) module: -| Skill | Role | -| ------------------- | ------------------------------------------------------------------------- | -| `bmad-auto-dev` | unattended implementation (fork of `bmad-quick-dev`) | -| `bmad-auto-review` | unattended adversarial review (fork of `bmad-code-review`) | -| `bmad-auto-resolve` | interactive CRITICAL-escalation resolution (`/bmad-auto-resolve `) | -| `bmad-auto-sweep` | deferred-work ledger triage (automation-only) | -| `bmad-auto-setup` | registers the module in `_bmad/` config + help | +| Skill | Role | +| ------------------- | ------------------------------------------------------------------------------------------- | +| `bmad-dev-auto` | unattended implementation + follow-up review (**upstream** — bmm prerequisite, not bundled) | +| `bmad-auto-resolve` | interactive CRITICAL-escalation resolution (`/bmad-auto-resolve `) | +| `bmad-auto-sweep` | deferred-work ledger triage (automation-only) | +| `bmad-auto-setup` | registers the module in `_bmad/` config + help | **Via uv + `bmad-auto init` (self-sufficient).** Installing the tool and running `init` is all you need — `init` installs the `bmad-auto-*` skills into `.claude/skills/` (claude) and/or `.agents/skills/` (codex/gemini) for the CLIs you select, alongside the hooks and policy: @@ -260,7 +262,7 @@ Your `.automator/policy.toml` is left untouched on upgrade — new keys are opti To remove bmad-auto from a project, see [Uninstalling](docs/setup-guide.md#uninstalling) — it reverses what `init` laid down (state, skills, hooks, gitignore) and uninstalls the tool. -**Via the BMAD-method installer.** The installer also copies the five `bmad-auto-*` skills into your project (but not the orchestrator tool). Finish setup with `/bmad-auto-setup`, which installs the tool from Git, asks which coding CLIs to drive, registers their hooks (`init` skips the already-present skills), and runs the preflight: +**Via the BMAD-method installer.** The installer copies the bundled `bmad-auto-*` skills into your project (but not the orchestrator tool), alongside the upstream `bmad-dev-auto` skill the orchestrator drives. Finish setup with `/bmad-auto-setup`, which installs the tool from Git, asks which coding CLIs to drive, registers their hooks (`init` skips the already-present skills), and runs the preflight: ```bash claude "/bmad-auto-setup accept all defaults" @@ -268,9 +270,7 @@ claude "/bmad-auto-setup accept all defaults" See **[docs/setup-guide.md](docs/setup-guide.md)** for the full walkthrough — choosing CLIs, installing the tool and TUI together or separately, and initializing codex/gemini. -The skills must be installed together: `bmad-auto-review` writes deferred-work entries per `bmad-auto-dev/deferred-work-format.md` (sibling skill directory). If you carry `_bmad/custom/bmad-quick-dev.toml` or `bmad-code-review.toml` customization overrides, duplicate them as `bmad-auto-dev.toml` / `bmad-auto-review.toml` — overrides are keyed by skill directory name. - -To pull in upstream BMAD improvements, diff the upstream skill against the fork (`diff -r /bmad-quick-dev src/automator/data/skills/bmad-auto-dev`) and merge manually; the forks keep the upstream file structure to make this easy. +The bundled skills must be installed together with the upstream `bmad-dev-auto` dev session: `bmad-auto-sweep` owns the canonical `deferred-work-format.md` that the orchestrator normalizes the ledger to, and `bmad-dev-auto` appends the flat deferred-work entries it normalizes. The `bmad-dev-auto` skill is driven unmodified, so its own `customize.toml` applies as-is; it needs no merge — it is consumed directly from the bmm module. There is no review fork to keep in sync: review is just a re-invocation of `bmad-dev-auto` on the done spec. ## Policy (`.automator/policy.toml`) @@ -299,6 +299,9 @@ file = true # append the same alerts to the run's ATTENTION file [review] enabled = true # false = skip the separate review session; the dev pass # runs quick-dev's own internal triple-review and finalizes to done +trigger = "recommended" # when enabled: "recommended" runs the separate review only when + # bmad-dev-auto flags followup_review_recommended; "always" = every story + # (the loop is bounded by limits.max_review_cycles either way) [adapter] name = "claude" # CLI profile: claude | codex | gemini | custom @@ -355,7 +358,7 @@ low_frame_rate = false # true = cap to 15fps + disable animations (= bmad-au **Gate modes:** `none` runs everything unattended; `per-epic` (default) pauses at epic boundaries; `per-story-spec-approval` pauses after each spec is written so you approve it before implementation is reviewed. -**Review:** `[review].enabled = false` drops the separate fresh-context review session; the dev pass instead runs `bmad-quick-dev`'s own internal triple-review (Blind Hunter / Edge Case Hunter / Acceptance Auditor) and finalizes the story straight to `done` — one session per story instead of two, verify commands still gating the commit. Governs deferred-work sweeps too. +**Review:** `[review].enabled = false` drops the separate fresh-context review session; the dev pass instead runs `bmad-dev-auto`'s own internal two-layer review (Blind Hunter / Edge Case Hunter) and finalizes the story straight to `done` — one session per story instead of two, verify commands still gating the commit. Governs deferred-work sweeps too. When review is enabled, `[review].trigger` decides _when_ that separate pass runs: `recommended` (default) only when the `bmad-dev-auto` session flags `followup_review_recommended` — it already triple-reviews inline and recommends an independent pass only when its changes were significant; `always` runs it every story. The follow-up loop is bounded by `limits.max_review_cycles` (default 3), which caps oscillation. `bmad-auto init` (without `--cli`) registers hooks for every CLI profile the policy references, so a dual-client setup needs no extra flags. @@ -437,7 +440,7 @@ Each run drives its agents inside a dedicated tmux session, `bmad-auto-` ## Other coding CLIs -One generic driver (`adapters/generic_tmux.py`) runs any coding CLI that fits the tmux-injection + hook-signal transport; everything CLI-specific lives in a declarative **profile** (`adapters/profile.py`). Built-in profiles ship as TOML in `automator/data/profiles/`: +One generic driver (`adapters/generic.py`) runs any coding CLI that fits the injection + hook-signal transport; everything CLI-specific lives in a declarative **profile** (`adapters/profile.py`), and the terminal transport itself sits behind a pluggable `TerminalMultiplexer` seam (tmux is the only backend today). Built-in profiles ship as TOML in `automator/data/profiles/`: | Profile | Status | Notes | | --------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -452,7 +455,7 @@ One generic driver (`adapters/generic_tmux.py`) runs any coding CLI that fits th **Shared prerequisites:** the `bmad-auto-*` skills must be present in `.agents/skills/` (codex and gemini read it; Claude Code reads `.claude/skills/`), and each CLI must have been run once interactively in the project for auth/trust — `bmad-auto init --cli codex --cli gemini` installs the skills into `.agents/skills/`, registers the hook relay, and prints the per-CLI first-run steps. -**Adding a CLI without touching Python:** drop a TOML file in `/.automator/profiles/.toml` (same fields as the built-ins: binary, `prompt_template`, bypass flags, a `[hooks]` block picking one of the config dialects `claude-settings-json` / `codex-hooks-json` / `gemini-settings-json` / `copilot-settings-json`, and a native→canonical event map). The hook relay script and orchestrator are CLI-agnostic — each registration passes the canonical event name as the script argument. A CLI whose hook config clones one of the existing dialects (the ecosystem trend) needs nothing else; a genuinely different transport gets its own adapter class instead (see the opencode HTTP+SSE design stub in `adapters/opencode_http.py`). +**Adding a CLI without touching Python:** drop a TOML file in `/.automator/profiles/.toml` with at minimum a binary, `prompt_template`, bypass flags, and a `[hooks]` block picking one of the config dialects (`claude-settings-json` / `codex-hooks-json` / `gemini-settings-json` / `copilot-settings-json`) plus a native→canonical event map. The full profile schema — every `CLIProfile` / `HookSpec` field and its default — lives in the **[Profile field reference](docs/adapter-authoring-guide.md#profile-field-reference)** of the adapter authoring guide, the single canonical home for it. The hook relay script and orchestrator are CLI-agnostic — each registration passes the canonical event name as the script argument. A CLI whose hook config clones one of the existing dialects (the ecosystem trend) needs nothing else; a genuinely different transport gets its own adapter class instead (see [Writing a new adapter class](docs/adapter-authoring-guide.md#writing-a-new-adapter-class) and the opencode HTTP+SSE design stub in `adapters/opencode_http.py`). **Finalizing a profile:** the facts a profile needs that live in no doc — the CLI's exact hook payload shape, its transcript location/format, and the token schema a `usage_parser` reads — are collected and sanitized by `bmad-auto probe-adapter ` (a zero-launch scan by default, or `--probe` for a live capture). The [adapter authoring guide](docs/adapter-authoring-guide.md) walks through using it end to end. @@ -483,6 +486,9 @@ The hero **demo GIF** (`docs/images/demo.gif`) is generated the same headless wa - **[docs/tui-guide.md](docs/tui-guide.md)** — the complete TUI reference. - **[src/automator/data/skills/README.md](src/automator/data/skills/README.md)** — the `bauto` skill module overview. - **[docs/ROADMAP.md](docs/ROADMAP.md)** — planned/deferred orchestrator work and the rationale behind it. +- **[docs/adapter-authoring-guide.md](docs/adapter-authoring-guide.md)** — authoring CLI adapters & profiles (and transport backends). +- **[docs/plugin-authoring-guide.md](docs/plugin-authoring-guide.md)** — authoring plugins (hooks, workflows, settings). +- **[docs/game-engine-plugin-guide.md](docs/game-engine-plugin-guide.md)** — the game-engine plugin shape (Unity reference). ## Contributing diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 4d24bea..d574274 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -12,13 +12,13 @@ See [README.md](../README.md) for the narrative overview and [setup-guide.md](se | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- | | Deterministic control loop | Story selection, retries, gates, completion checks run in plain Python | LLM-as-orchestrator is nondeterministic, hard to debug, and costs tokens for control flow | | Trust-nothing verification | Checks on-disk artifacts (spec status, baseline-commit match, non-empty diff, sprint sync) + runs your test/lint commands before commit | Agents claim success without working code; broken builds slip through | -| Fresh-context adversarial review | Dev and review are separate sessions; review uses 3 parallel layers | Self-review anchoring bias; implementer marks own work correct | +| Fresh-context adversarial review | Dev and review are separate sessions; review uses 2 parallel layers (Blind Hunter / Edge Case Hunter) | Self-review anchoring bias; implementer marks own work correct | | Hook-based transport | Coding-agent hooks write structured event files; skills write `result.json` | Brittle terminal pane-scraping | | Resumable state machine | Every run is on-disk state, resumable after gate/escalation/crash | Long unattended runs lost to interruptions | | Plateau-defer | Stuck stories are skipped, stashed, and the run continues | One unconvergeable story blocking a whole sprint | | Typed escalations + resolve workflow | CRITICAL pauses + notifies; interactive resolve agent re-arms the story | Ambiguous specs silently producing wrong code | | Deferred-work sweeps | Triages an append-only ledger against real code, bundles + executes | Split-off goals and review findings get lost | -| Multi-CLI adapter + profiles | Generic tmux driver runs claude/codex/gemini; per-stage overrides; TOML profiles | Vendor lock-in; no way to mix models per stage | +| Multi-CLI adapter + profiles | Generic driver runs claude/codex/gemini; per-stage overrides; TOML profiles; transport behind a pluggable multiplexer seam (tmux today) | Vendor lock-in; no way to mix models per stage; future non-tmux/Windows transport | | Cost-weighted token budgets | Per-story budget counts cache reads at ~0.1x; raw totals displayed | Naive token caps misjudge real cost (cache reads dominate) | | Non-invasive skill forks | Drives its own `bmad-auto-*` skill forks; reads `sprint-status.yaml` only | Modifying a user's standard BMAD install | | Read-only TUI + launcher | Live dashboard over run-dir artifacts; launches detached runs | No visibility into what an unattended run is doing | @@ -37,7 +37,7 @@ See [README.md](../README.md) for the narrative overview and [setup-guide.md](se ### Spec + implementation (dev stage) -- Drives `bmad-auto-dev` (fork of `bmad-quick-dev`) in a fresh tmux session: plans a 1.5–4k-token spec, auto-approves it, implements, syncs `sprint-status` to `in-review`, writes `result.json`. +- Drives the upstream `bmad-dev-auto` skill (unmodified) in a fresh tmux session: it plans a 1.5–4k-token spec, auto-approves it, implements, and self-finalizes the spec; the orchestrator syncs `sprint-status` and synthesizes `result.json` from the spec the skill leaves on disk. - Spec-only contract between stages — review consumes the frozen spec, not the dev session's context. ### Verification (trust-nothing gate) @@ -47,10 +47,11 @@ See [README.md](../README.md) for the narrative overview and [setup-guide.md](se ### Adversarial review (review stage) -- Drives `bmad-auto-review` (fork of `bmad-code-review`) in a separate, fresh-context session — no anchoring bias from the implementer. -- Static prefilter → 3 parallel layers (Blind Hunter / Edge Case Hunter / Acceptance Auditor) → verify findings against code → triage → auto-apply patches → log → defer ambiguity. -- Bounded review loop (default 3 cycles); done when clean. -- Optional (`[review].enabled`, default `true`): set `false` to skip the separate review session. The dev pass then runs `bmad-quick-dev`'s own internal triple-review (same three layers, in-context) and finalizes the story to `done` — one session per story instead of two. Verify commands still gate the commit. Applies to story runs and deferred-work sweeps alike. +- The follow-up review is a re-invocation of `bmad-dev-auto` on the `done` spec — a fresh-context session with no anchoring bias from the implementer (BMAD-METHOD#2508 routes a `done` spec to a fresh step-04 review pass), so there is no separate review skill. +- Two parallel adversarial layers (Blind Hunter / Edge Case Hunter) → verify findings against code → triage → auto-apply patches → log → defer ambiguity → commit. +- Bounded review loop (`limits.max_review_cycles`, default 3 cycles); done when the pass finishes `done` and no longer recommends a follow-up. This bound is also the oscillation guard for skill-recommended follow-up review. +- Optional (`[review].enabled`, default `true`): set `false` to skip the follow-up review session. The dev pass's own inline review (same two layers, in-context) is then the only review and it finalizes the story to `done` — one session per story instead of two. Verify commands still gate the commit. Applies to story runs and deferred-work sweeps alike. +- Trigger (`[review].trigger`, default `recommended`): when review is enabled, decides _when_ the follow-up pass runs. `recommended` runs it only when `bmad-dev-auto` sets `followup_review_recommended` on a `done` spec (it self-reviews inline and flags an independent pass only when its review-driven changes were significant — BMAD-METHOD#2505). `always` runs it on every story (pre-0.7.0 behavior). ### Failure handling & resilience @@ -111,7 +112,7 @@ See [README.md](../README.md) for the narrative overview and [setup-guide.md](se ### Multi-CLI / multi-agent support -- Generic tmux adapter drives any CLI fitting the tmux-injection + hook-signal transport; CLI specifics live in declarative TOML profiles. +- Generic adapter drives any CLI fitting the injection + hook-signal transport; CLI specifics live in declarative TOML profiles. Two independent axes: the **CLI** (`CodingCLIAdapter` + profile) and the **terminal transport** (`TerminalMultiplexer`) — tmux is the only backend today, behind a pluggable seam so a native-Windows backend can be added without touching the engine (see the [adapter authoring guide](adapter-authoring-guide.md#two-axes-cli-vs-transport)). - Supported, E2E-verified: `claude` (reference), `codex` (≥ 0.139), `gemini` (≥ 0.46), `copilot` (GitHub Copilot CLI ≥ 2026-02 — the `copilot` binary, not the VS Code extension; `agentStop` turn-end, `-i` interactive launch, `--allow-all-tools`; pin a capable model — the free GPT-5 mini default is unreliable for multi-step skills). - Per-stage CLI/model overrides: run dev on one CLI/model, review on another (`[adapter.dev]`, `[adapter.review]`, `[adapter.triage]`). - Add a CLI without touching Python: drop a TOML profile in `.automator/profiles/.toml` (binary, prompt template, bypass flags, hook dialect, native→canonical event map). @@ -151,7 +152,7 @@ See [README.md](../README.md) for the narrative overview and [setup-guide.md](se - `bmad-auto init` installs the five `bmad-auto-*` skills (`.claude/skills/` and/or `.agents/skills/`), the hook relay, `.automator/policy.toml`, and a runs-dir gitignore. Flags: `--cli` (repeatable), `--no-skills`, `--force-skills`. - `bmad-auto validate` preflights every prerequisite: BMAD config, sprint-status, git, tmux, CLI binary, hook registration. -- Non-invasive: drives its own forks of the dev/review skills — your standard BMAD install is never modified. Upstream improvements are merged by diffing fork vs. upstream (forks keep the upstream file structure). +- Non-invasive: drives the upstream `bmad-dev-auto` skill unmodified — there is no fork to keep in sync — and review is just a re-invocation of it on the `done` spec. Your standard BMAD install is never modified. ### Command reference diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index fbb374f..20082d0 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -7,6 +7,35 @@ Status legend: **planned** (agreed, not started) · **exploring** (shape still o --- +## Native Windows multiplexer backend + +**Status:** planned · **Foundation:** multiplexer seam + portability hardening landed (v0.7.0) + +The orchestrator no longer fuses tmux into the engine. All session/window/pane operations +go through a single `TerminalMultiplexer` ABC (`src/automator/adapters/multiplexer.py`), +obtained from `get_multiplexer()`; `TmuxMultiplexer` (`adapters/tmux_backend.py`) is the +**only** file allowed to shell out to `tmux`, and it quarantines the POSIX `sh -c` +parked-window trailer. Alongside it, the scattered POSIX-isms were guarded behind a +platform-util seam (`terminate_pid`, detach kwargs, `SIGKILL` fallback, `os.devnull`) and +the Unity plugin's `/proc`/`/tmp`/`cp -a`/symlink primitives now degrade off Linux (with +`psutil` from the optional `windows` extra), all verified by a CI portability guard +(`tests/test_portability_guard.py`). **WSL already works today** — it _is_ Linux, so it +takes every fast path unchanged; this is purely about a future _native_ Windows host. + +The remaining work is a real non-tmux backend (a "psmux"-style multiplexer) that implements +the `TerminalMultiplexer` contract on native Windows and is returned from `get_multiplexer()` +behind a platform/policy check. The seam is designed so this slots in with **no change to +the adapters, `runs.py`, `tui/launch.py`, `probe.py`, or `tui/data.py`** — a backend author +reads `multiplexer.py` for the contract and `tmux_backend.py` for the reference +implementation (see the [adapter authoring guide](adapter-authoring-guide.md#the-transport-contract-for-a-backend-author)). + +**Open questions:** what hosts the windows on native Windows (Windows Terminal panes, a +ConPTY-based manager, a headless process supervisor?); how attach/detach and the parked +exit-status window map without a POSIX shell; and the Windows-Unity cache-path correctness +left as a documented follow-up in Phase 4. + +--- + ## Parallel unit execution (`[scm] max_parallel`) **Status:** planned · **Foundation:** landed with worktree isolation (v0.4.0) @@ -40,8 +69,8 @@ the same way deferred-work sweeps already run. **Approach (designed, not built):** a separate `bmad-auto retro` run type that mirrors the `SweepEngine` (`src/automator/sweep.py`) end-to-end — `RetroEngine`, a `retro` CLI command + resume -branch, a `--retro-item ` mode on `bmad-auto-dev`, and `verify` helpers paralleling the -bundle verifiers. Story runs stay untouched. +branch, a retro-item intent fed to the `bmad-dev-auto` primitive, and `verify` helpers paralleling +the bundle verifiers. Story runs stay untouched. **Why blocked:** retro-item _detail_ is scattered — some lives in the epic retro-doc Action-Items table (`epic-N-retro-YYYY-MM-DD.md`), some in `deferred-work.md` (DW-N) entries, some in ad-hoc diff --git a/docs/adapter-authoring-guide.md b/docs/adapter-authoring-guide.md index 191d033..3f2a46a 100644 --- a/docs/adapter-authoring-guide.md +++ b/docs/adapter-authoring-guide.md @@ -1,10 +1,79 @@ -# Finalizing a CLI adapter profile with `probe-adapter` +# Authoring CLI adapters & profiles bmad-auto drives any coding CLI that fits the **tmux-injection + hook-signal** -transport through one generic adapter (`adapters/generic_tmux.py`); everything -CLI-specific lives in a declarative **TOML profile** (`adapters/profile.py`). The -[README adapter section](../README.md#other-coding-clis) covers the profile fields -and how to drop one in without touching Python. +transport through one generic adapter (`adapters/generic.py`); everything +CLI-specific lives in a declarative **TOML profile** (`adapters/profile.py`). This +guide is the canonical home for the profile schema and the two ways to teach +bmad-auto a new CLI: + +- **The common case — a TOML profile.** If the CLI fits tmux + hook-signal, you + write no Python. The [Profile field reference](#profile-field-reference) is the + complete `CLIProfile` / `HookSpec` schema; the + [walkthrough below](#walkthrough-finalizing-a-profile) shows how `probe-adapter` + finalizes one against a real run. +- **The advanced case — a new adapter class.** If the CLI does _not_ fit that + transport (e.g. an HTTP/SSE service), see + [Writing a new adapter class](#writing-a-new-adapter-class) for the + `CodingCLIAdapter` ABC. + +## Two axes: CLI vs transport + +These are independent and abstracted separately: + +- **CLI axis** — `CodingCLIAdapter` (`adapters/base.py`): _which_ binary to launch, + how the prompt is rendered, the hook dialect, where the transcript lives. The + generic adapter + a TOML profile cover this; the rest of this guide is about it. +- **Transport axis** — `TerminalMultiplexer` (`adapters/multiplexer.py`): how + sessions, windows, and panes are created, observed, and torn down. The generic + adapter never shells out itself — it goes through `self.mux`, obtained from + `get_multiplexer()`. The one backend today is tmux + (`adapters/tmux_backend.py`), which is the **only** file allowed to invoke + `tmux` (and the only place POSIX-shell trailers live). A future non-POSIX + backend (e.g. a native-Windows "psmux") implements the `TerminalMultiplexer` + contract and slots in behind `get_multiplexer()` with no change to the adapters. + A backend author reads `multiplexer.py` for the contract and `tmux_backend.py` + for the reference implementation. + +### The transport contract (for a backend author) + +Every part of the codebase that touches sessions, windows, or clients now goes +through `get_multiplexer()` — not just the generic adapter but also `runs.py` +(session listing/tagging, kill, attach argv), `tui/launch.py` (the control +session and its parked orchestrator windows), `probe.py` (the throwaway probe +session), and `tui/data.py` (legacy-run liveness). A grep for `"tmux"` outside +`adapters/tmux_backend.py` should turn up only `shutil.which("tmux")` presence +checks, never an invocation. + +To add a backend, implement `TerminalMultiplexer` (`adapters/multiplexer.py`) and +return it from `get_multiplexer()`. The contract groups into: + +- **Sessions** — `has_session`, `new_session` (geometry is optional: agent + sessions pin a fixed pane size because they are observed while detached; the + control session omits it), `kill_session`, `list_sessions`, `session_options` + (read a user option across all sessions), `set_session_option`. +- **Windows** — `new_window` (run a command in a fresh window), `new_parked_window` + (run a command, then _park_ on a keypress so the exit status stays inspectable, + then return any attached client to its origin — this is where the POSIX `sh -c` + trailer is quarantined; a non-POSIX backend reimplements the same behavior in + its own terms), `list_window_ids`, `list_windows` (selected fields per window), + `window_alive`, `kill_window`, `select_window`, `set_window_option`, + `unset_window_option`, `show_window_option`, `pipe_pane` (tee a pane to a log), + `send_text`. +- **Client / attach** — `attach_target_argv` (argv that reaches a target, nesting- + aware), `current_pane_id` / `current_window_id` / `current_session`, + `detach_client`, `switch_client` (with an optional last-client fallback), + `available` (is this backend usable on the current host). + +Operations that can race a window dying (`pipe_pane`) or a session already being +gone (`kill_session`) must tolerate it rather than raise; everything else raises a +`MultiplexerError` subclass on failure, which call sites catch at the seam (e.g. +`tui/launch.start_detached` turns it into a `LaunchError`) without importing the +backend. `window_alive` uses `list-windows` membership, not `display-message`, because +`display-message -t ` exits 0 on tmux. + +`tmux_backend.py` is the reference implementation; reading it alongside the ABC is +the fastest way to see exactly what a `new_parked_window` or `session_options` must +produce. The hard part of a new profile isn't the TOML — it's the **facts that live in no doc**: the CLI's exact hook payload shape (field names and casing, whether @@ -79,10 +148,8 @@ loud **"raw retained — do not share"** warning; never paste a `--keep-temp` ru ### 1. Draft a profile Drop a TOML file in `/.automator/profiles/.toml` with the fields -described in the [README adapter section](../README.md#other-coding-clis). The -contract is the `CLIProfile` / `HookSpec` dataclasses in -[`src/automator/adapters/profile.py`](../src/automator/adapters/profile.py): a -`binary`, a `prompt_template`, bypass flags, a `[hooks]` block picking one of the +from the [Profile field reference](#profile-field-reference) below. The minimum is +a `binary`, a `prompt_template`, bypass flags, a `[hooks]` block picking one of the config dialects (`claude-settings-json` / `codex-hooks-json` / `gemini-settings-json` / `copilot-settings-json`) and a native→canonical event map, and a `usage_parser` (start with `"none"` until you've written one). @@ -172,3 +239,141 @@ On Copilot CLI 1.0.63 this surfaced three corrections: to it instead of `"none"`. Confirm the `mkdtemp` dir is gone afterward. + +--- + +## Profile field reference + +A profile is the `CLIProfile` dataclass in +[`src/automator/adapters/profile.py`](../src/automator/adapters/profile.py), +loaded from TOML. **Built-ins** ship as packaged TOML +(`automator/data/profiles/*.toml`); **project overrides** in +`/.automator/profiles/*.toml` overlay them — same `name` overrides a +built-in, a new `name` extends the set. The legacy alias `claude-code-tmux` +resolves to `claude`. + +### `CLIProfile` + +| Field | Required | Default | Meaning | +| ---------------------------------- | -------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | ✅ | — | Profile id, also the `--cli` value and override key. | +| `binary` | ✅ | — | Executable to launch (resolved on `PATH`). | +| `[hooks]` | ✅ | — | The `HookSpec` table (see below). | +| `skill_tree` | | `.claude/skills` | Project-relative tree this CLI reads skills from (`.agents/skills` for codex/gemini); `bmad-auto init` installs the `bmad-auto-*` skills here. Must be relative. | +| `prompt_template` | | `{prompt}` | How the canonical `/skill args` prompt is rendered. Placeholders: `{prompt}` (whole string), `{skill}` (leading slash-command name, no `/`), `{args}` (the remainder). | +| `launch_args` | | `()` | Extra argv passed at launch, e.g. `["-i"]` to stay interactive (gemini/copilot). | +| `bypass_args` | | `()` | Flags that bypass permission/approval prompts for unattended runs (e.g. `--allow-all-tools`). | +| `model_flag` | | `--model` | Flag used to pass the model name when one is configured. | +| `env` | | `{}` | Extra environment variables for the session. | +| `usage_parser` | | `none` | Which transcript token parser to use — one of `claude-jsonl`, `codex-rollout`, `gemini-chat`, `copilot-events`, `none`. | +| `usage_grace_s` | | `0.0` | Seconds to keep polling the transcript for token totals after the session ends. `0` = read once. Raise it for CLIs that flush totals only on shutdown (copilot writes `modelMetrics` ~1s after the turn-end hook). Must be ≥ 0. | +| `stop_without_result_nudges` | | unset (use global) | Per-adapter floor for Stop-without-result nudges. Leave unset to inherit `limits.stop_without_result_nudges`. Raise it for CLIs that fire a turn-end hook _per response turn_ (copilot's `agentStop`), where the global default of 1 declares them stalled too early. Must be ≥ 0 if set. | +| `subagent_stop_without_transcript` | | `false` | Set `true` for CLIs that fire the turn-end hook for _subagent_ turns too, with an empty `transcriptPath` and a tool-use session id (copilot's `agentStop`). A `Stop` carrying no transcript is then treated as a subagent stop and ignored, so the main session's real turn-end drives completion. Leave `false` and every `Stop` is the main turn-end. | +| `first_run_note` | | `""` | Human note printed by `init` about a manual first-run/auth step this CLI needs. | +| `seed_files` | | `()` | Project-relative gitignored configs (MCP/CLI settings) a `git worktree add` checkout omits; `provision_worktree` copies them into isolated dev/review worktrees. Must be relative. | + +### `HookSpec` (the `[hooks]` table) + +| Field | Required | Meaning | +| ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `dialect` | ✅ | The CLI's hook-config format — one of `claude-settings-json`, `codex-hooks-json`, `gemini-settings-json`, `copilot-settings-json`. | +| `config_path` | ✅ | Project-relative path the hook config is written to (e.g. `.claude/settings.json`). Absolute paths are rejected. | +| `events` | ✅ | Map of **native** event name → **canonical** event name. The canonical side must be one of `SessionStart`, `Stop`, `SessionEnd`, `PreCompact`; the native side is whatever the CLI emits (e.g. `agentStop = "Stop"`). At least one entry. | + +### Worked TOML — copilot + +The shipped `copilot` profile exercises the non-default tuning knobs +(`usage_grace_s`, `stop_without_result_nudges`, `subagent_stop_without_transcript`) +and a camelCase event map — all discovered by the +[copilot probe walkthrough](#worked-example-copilot) above: + +```toml +name = "copilot" +binary = "copilot" +skill_tree = ".agents/skills" +launch_args = ["-i"] +bypass_args = ["--allow-all-tools", "--allow-all-paths"] +usage_parser = "copilot-events" +usage_grace_s = 8.0 # token totals land ~1s after agentStop, on session.shutdown +stop_without_result_nudges = 5 # agentStop fires per response turn +subagent_stop_without_transcript = true # ignore subagent agentStops (empty transcriptPath) +seed_files = [".github/copilot/settings.json"] + +[hooks] +dialect = "copilot-settings-json" +config_path = ".github/copilot/settings.json" +events = { agentStop = "Stop", sessionStart = "SessionStart", sessionEnd = "SessionEnd" } +``` + +(The shipped profile under `automator/data/profiles/copilot.toml` also carries a +`prompt_template` and `first_run_note`, trimmed here for focus — read it for the +exact shipped values.) + +--- + +## Writing a new adapter class + +Reach for this **only** when a CLI does not fit the tmux-injection + hook-signal +transport — for example an HTTP/SSE service with no terminal. A CLI that _does_ +fit (a binary you launch in a pane that fires lifecycle hooks) needs no Python: +reuse `generic.py` with a [profile](#profile-field-reference) instead of +subclassing. + +The contract is the `CodingCLIAdapter` ABC in +[`src/automator/adapters/base.py`](../src/automator/adapters/base.py). + +### Declare the three capability axes + +Set these class attributes so the engine can reason about transport quality +instead of treating every CLI as a dumb terminal: + +- `injection` — how a prompt reaches the CLI: `tmux-initial-prompt` | `launch-flag` | `http`. +- `observation` — how completion is detected: `hook-signal` | `sse` | `transcript-poll`. +- `state` — where session state is readable: `local-jsonl` | `local-json-tree` | `remote`. + +### The data contracts + +Three frozen dataclasses cross the seam: + +- **`SessionSpec`** (engine → adapter) — `task_id`, `role` (`"dev"` / `"review"` / + `"retro"`), `prompt`, `cwd`, `env`, `model` (empty = CLI default), + `timeout_s`. +- **`SessionHandle`** (returned by `start_session`) — `task_id`, `native_id` (tmux + window id, HTTP session id, …), `launched_ns` (wall-clock ns just before launch; + the floor for hook events). +- **`SessionResult`** (returned by `wait_for_completion`) — `status` (one of + `completed`, `stalled`, `timeout`, `crashed`), `result_json`, `session_id`, + `transcript_path`. + +### Methods + +Required (abstract): + +- `start_session(spec) -> SessionHandle` — launch the session. +- `wait_for_completion(handle, spec) -> SessionResult` — block until the session + ends (or stalls/times out), then report status. + +The base class provides `run(spec)`, the template that chains +`start_session` → `wait_for_completion` → `kill` (the kill runs in a `finally`). +You normally don't override it. + +Optional capabilities (default to "unsupported" / no-op): + +- `send_text(handle, text)` — nudge a running session. Raises `NotImplementedError` + by default (an HTTP adapter that can't inject mid-turn leaves it). +- `interactive_argv(spec)` / `interactive_env(spec)` — argv + env that launch the + CLI **attached** to the caller's terminal, seeded with the prompt, for the + interactive escalation-resolution flow. HTTP adapters have no terminal and leave + `interactive_argv` raising. +- `kill(handle)` — tear down the session (no-op default). +- `read_usage(result) -> TokenUsage | None` — parse token usage from the result + (returns `None` by default). + +### References + +- [`adapters/opencode_http.py`](../src/automator/adapters/opencode_http.py) — the + worked **design stub** for a non-tmux (HTTP/SSE) transport. +- [`adapters/mock.py`](../src/automator/adapters/mock.py) — the test-only reference + implementation. +- [`adapters/generic.py`](../src/automator/adapters/generic.py) — the tmux + + hook-signal adapter to reuse with a profile rather than subclass. diff --git a/docs/game-engine-plugin-guide.md b/docs/game-engine-plugin-guide.md index 161e175..ad616ec 100644 --- a/docs/game-engine-plugin-guide.md +++ b/docs/game-engine-plugin-guide.md @@ -221,3 +221,37 @@ Each script's module docstring documents every env knob it reads — the authoritative source if a default ever changes. The [Game Engine MCP guide](game-engine-mcp-guide.md) distills those into a single reference table and explains the IvanMurzak vs CoplayDev differences. + +## Platform behavior (Linux fast paths, Windows fallbacks) + +The Unity plugin's helper scripts are stdlib-only and run identically on Linux, +macOS, and WSL (which **is** Linux — it takes every fast path unchanged). Each +POSIX-only primitive is guarded behind a `sys.platform` branch so a future +native-Windows multiplexer backend can slot in; those Windows branches are +best-effort and **not yet exercised** (no Windows backend ships today). The +guards, by script: + +- **`unity_teardown.py` — process discovery.** Linux uses a zero-dependency + `/proc` scan to find the worktree-bound Editor/MCP-server; non-Linux falls back + to the same scan over **`psutil`**, imported lazily from the optional `non-linux` + extra (`pip install 'bmad-auto[non-linux]'`) with a clear error if missing. The + hard-kill uses `signal.SIGKILL` where present, degrading to `SIGTERM`/`taskkill` + on Windows. Liveness uses `os.kill(pid, 0)` on POSIX but `psutil.pid_exists` on + Windows (where `os.kill(pid, 0)` would _terminate_ the process). +- **`unity_setup.py` — Library priming + launch.** The warm-Library copy keeps the + `cp -a --reflink` CoW fast path on POSIX (near-free on btrfs/xfs) and falls back + to `shutil.copytree` where `cp` is absent. The empty-cache symlink fallback wraps + `symlink_to` in `try/except OSError`, dropping to a real per-worktree dir (cold, + no cross-run cache) where symlinks need privilege (Windows). Editor detach uses + `start_new_session` on POSIX, `CREATE_NEW_PROCESS_GROUP` on Windows. +- **`unity_cleanup.py` — temp-cache scrub.** Unity's `temporaryCachePath` base is + exactly `/tmp` on Linux (kept byte-for-byte); other platforms derive it from + `tempfile.gettempdir()`. **Caveat:** native Windows Unity actually uses + `%USERPROFILE%\AppData\Local\Temp\\`, which `gettempdir()` does + not always resolve to — getting that cache root exactly right is a documented + follow-up for when a Windows backend lands. + +When authoring your own engine plugin, mirror this discipline: stdlib-only scripts, +optional extras imported lazily, and every POSIX-ism behind a `sys.platform` branch +with a `# portability:` comment. See the [plugin authoring guide](plugin-authoring-guide.md#platform-portability) +for the general rule. diff --git a/docs/images/dashboard.png b/docs/images/dashboard.png index cc501ac..9bf44c6 100644 Binary files a/docs/images/dashboard.png and b/docs/images/dashboard.png differ diff --git a/docs/images/dashboard.svg b/docs/images/dashboard.svg index aa986bd..b4f5da3 100644 --- a/docs/images/dashboard.svg +++ b/docs/images/dashboard.svg @@ -19,226 +19,226 @@ font-weight: 700; } - .terminal-569538889-matrix { + .terminal-973633829-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-569538889-title { + .terminal-973633829-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-569538889-r1 { fill: #c5c8c6 } -.terminal-569538889-r2 { fill: #e0e0e0 } -.terminal-569538889-r3 { fill: #a0a3a6 } -.terminal-569538889-r4 { fill: #0053aa } -.terminal-569538889-r5 { fill: #e2e2e2;font-weight: bold } -.terminal-569538889-r6 { fill: #e0e0e0;font-weight: bold } -.terminal-569538889-r7 { fill: #98e024 } -.terminal-569538889-r8 { fill: #9d9d9d } -.terminal-569538889-r9 { fill: #fd971f } -.terminal-569538889-r10 { fill: #a1a1a1 } -.terminal-569538889-r11 { fill: #ddedf9;font-weight: bold } -.terminal-569538889-r12 { fill: #797979 } -.terminal-569538889-r13 { fill: #262626 } -.terminal-569538889-r14 { fill: #0178d4 } -.terminal-569538889-r15 { fill: #e1e1e1;font-weight: bold } -.terminal-569538889-r16 { fill: #121212 } -.terminal-569538889-r17 { fill: #191919 } -.terminal-569538889-r18 { fill: #9e9e9e } -.terminal-569538889-r19 { fill: #58d1eb } -.terminal-569538889-r20 { fill: #3e3e3e } -.terminal-569538889-r21 { fill: #f4005f } -.terminal-569538889-r22 { fill: #f4005f;font-weight: bold } -.terminal-569538889-r23 { fill: #ffa62b;font-weight: bold } -.terminal-569538889-r24 { fill: #495259 } + .terminal-973633829-r1 { fill: #c5c8c6 } +.terminal-973633829-r2 { fill: #e0e0e0 } +.terminal-973633829-r3 { fill: #a0a3a6 } +.terminal-973633829-r4 { fill: #0053aa } +.terminal-973633829-r5 { fill: #e2e2e2;font-weight: bold } +.terminal-973633829-r6 { fill: #e0e0e0;font-weight: bold } +.terminal-973633829-r7 { fill: #98e024 } +.terminal-973633829-r8 { fill: #9d9d9d } +.terminal-973633829-r9 { fill: #fd971f } +.terminal-973633829-r10 { fill: #a1a1a1 } +.terminal-973633829-r11 { fill: #ddedf9;font-weight: bold } +.terminal-973633829-r12 { fill: #797979 } +.terminal-973633829-r13 { fill: #262626 } +.terminal-973633829-r14 { fill: #0178d4 } +.terminal-973633829-r15 { fill: #e1e1e1;font-weight: bold } +.terminal-973633829-r16 { fill: #121212 } +.terminal-973633829-r17 { fill: #191919 } +.terminal-973633829-r18 { fill: #9e9e9e } +.terminal-973633829-r19 { fill: #58d1eb } +.terminal-973633829-r20 { fill: #3e3e3e } +.terminal-973633829-r21 { fill: #f4005f } +.terminal-973633829-r22 { fill: #f4005f;font-weight: bold } +.terminal-973633829-r23 { fill: #ffa62b;font-weight: bold } +.terminal-973633829-r24 { fill: #495259 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-auto + bmad-auto - + - - bmad-auto — ~/code/acme-search -Runs────────────────────────────20260612-141000-e5f6▶ running  started 2026-06-12T14:10:00  epic 2 - st  run                   type  tasks 5  done 2  deferred 1  escalated 0  2,473,900 tokens - 20260610-090000-a1b2  story ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - 20260611-101500-c3d4  sweep  story                           phase             dev    review  tokens        info                               - ▶   20260612-141000-e5f6  story  2-1-search-index                done              ×1     ×1      824,400       a1b2c3d4e5f6                       - 2-2-typeahead                   done              ×1     ×2      699,900       b2c3d4e5f607                       - 2-3-search-ranking              review-running    ×1     ×1      504,200       - 2-4-saved-searches              dev-running       ×1     ×0      168,300       - 2-5-search-analytics            deferred          ×2     ×1      277,100       dev budget exhausted (2 attempts)  -JournalLogAttention -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Sprint──────────────────────────▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▼ Epic 1 · 3/3 ✓15:09:35 session-start            task_id=2-1-search-index  role=dev  story_key=2-1-search-index -├ ✓ 1-auth15:09:35 story-done               story_key=2-1-search-index  commit=a1b2c3d4e5f6 -├ ✓ 2-session-tokens15:09:35 session-start            task_id=2-2-typeahead  role=dev  story_key=2-2-typeahead -├ ✓ 3-password-reset15:09:35 review-cycle             story_key=2-2-typeahead  cycle=2  findings=3 -└ ✓ retrospective15:09:35 story-done               story_key=2-2-typeahead  commit=b2c3d4e5f607 -▼ Epic 2 · 2/515:09:35 story-start              story_key=2-3-search-ranking  epic=2 -├ ✓ 1-search-index15:09:35 spec-approved            story_key=2-3-search-ranking  tokens=1834 -├ ✓ 2-typeahead15:09:35 dev-done                 story_key=2-3-search-ranking  tasks_done=3  tasks_total=3 -├ ▶ 3-search-ranking15:09:35 verify-ok                story_key=2-3-search-ranking  commands=pytest -q, ruff check . -├ ◆ 4-saved-searches15:09:35 review-start             story_key=2-3-search-ranking  role=review -└ ○ 5-search-analytics15:09:35 escalation-preference    story_key=2-3-search-ranking  detail=reviewer used codex for the scoring math -▼ Epic 3 · 0/215:09:35 story-deferred           story_key=2-5-search-analytics  reason=dev budget exhausted -├ · 1-billing-portal -└ · 2-invoices - - -Deferred Work — 2 to answer (d) -DW-1 Harden the OAuth token refr… -DW-2 Add pagination to the searc… -DW-3 Replace the ad-hoc ranking … -DW-4 Flaky retry in the indexer … -DW-5 ✓ Polish the empty-state co… - - - - - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archive  c cleanup  v validate  g settings  M mod^p palette + + bmad-auto — ~/code/acme-search +Runs────────────────────────────20260612-141000-e5f6▶ running  started 2026-06-12T14:10:00  epic 2 + st  run                   type  tasks 5  done 2  deferred 1  escalated 0  2,473,900 tokens + 20260610-090000-a1b2  story ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + 20260611-101500-c3d4  sweep  story                           phase             dev    review  tokens        info                               + ▶   20260612-141000-e5f6  story  2-1-search-index                done              ×1     ×1      824,400       a1b2c3d4e5f6                       + 2-2-typeahead                   done              ×1     ×2      699,900       b2c3d4e5f607                       + 2-3-search-ranking              review-running    ×1     ×1      504,200       + 2-4-saved-searches              dev-running       ×1     ×0      168,300       + 2-5-search-analytics            deferred          ×2     ×1      277,100       dev budget exhausted (2 attempts)  +JournalLogAttention +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Sprint──────────────────────────▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▼ Epic 1 · 3/3 ✓20:25:29 session-start            task_id=2-1-search-index  role=dev  story_key=2-1-search-index +├ ✓ 1-auth20:25:29 story-done               story_key=2-1-search-index  commit=a1b2c3d4e5f6 +├ ✓ 2-session-tokens20:25:29 session-start            task_id=2-2-typeahead  role=dev  story_key=2-2-typeahead +├ ✓ 3-password-reset20:25:29 review-cycle             story_key=2-2-typeahead  cycle=2  findings=3 +└ ✓ retrospective20:25:29 story-done               story_key=2-2-typeahead  commit=b2c3d4e5f607 +▼ Epic 2 · 2/520:25:29 story-start              story_key=2-3-search-ranking  epic=2 +├ ✓ 1-search-index20:25:29 spec-approved            story_key=2-3-search-ranking  tokens=1834 +├ ✓ 2-typeahead20:25:29 dev-done                 story_key=2-3-search-ranking  tasks_done=3  tasks_total=3 +├ ▶ 3-search-ranking20:25:29 verify-ok                story_key=2-3-search-ranking  commands=pytest -q, ruff check . +├ ◆ 4-saved-searches20:25:29 review-start             story_key=2-3-search-ranking  role=review +└ ○ 5-search-analytics20:25:29 escalation-preference    story_key=2-3-search-ranking  detail=reviewer used codex for the scoring math +▼ Epic 3 · 0/220:25:29 story-deferred           story_key=2-5-search-analytics  reason=dev budget exhausted +├ · 1-billing-portal +└ · 2-invoices + + +Deferred Work — 2 to answer (d) +DW-1 Harden the OAuth token refr… +DW-2 Add pagination to the searc… +DW-3 Replace the ad-hoc ranking … +DW-4 Flaky retry in the indexer … +DW-5 ✓ Polish the empty-state co… + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archive  c cleanup  v validate  g settings  M mod^p palette diff --git a/docs/images/demo.gif b/docs/images/demo.gif index 0956e78..fc7f5d4 100644 Binary files a/docs/images/demo.gif and b/docs/images/demo.gif differ diff --git a/docs/images/settings-scm.png b/docs/images/settings-scm.png index 7c41fe1..adf4b11 100644 Binary files a/docs/images/settings-scm.png and b/docs/images/settings-scm.png differ diff --git a/docs/images/settings-scm.svg b/docs/images/settings-scm.svg index afb691c..19013ba 100644 --- a/docs/images/settings-scm.svg +++ b/docs/images/settings-scm.svg @@ -19,216 +19,216 @@ font-weight: 700; } - .terminal-2360967870-matrix { + .terminal-505119418-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2360967870-title { + .terminal-505119418-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2360967870-r1 { fill: #c5c8c6 } -.terminal-2360967870-r2 { fill: #e0e0e0 } -.terminal-2360967870-r3 { fill: #a0a3a6 } -.terminal-2360967870-r4 { fill: #1e1e1e } -.terminal-2360967870-r5 { fill: #191919 } -.terminal-2360967870-r6 { fill: #a5a5a5 } -.terminal-2360967870-r7 { fill: #737373 } -.terminal-2360967870-r8 { fill: #a5a5a5;font-style: italic; } -.terminal-2360967870-r9 { fill: #7f7f7f } -.terminal-2360967870-r10 { fill: #003054 } -.terminal-2360967870-r11 { fill: #121212 } -.terminal-2360967870-r12 { fill: #000000 } -.terminal-2360967870-r13 { fill: #ffa62b;font-weight: bold } -.terminal-2360967870-r14 { fill: #495259 } + .terminal-505119418-r1 { fill: #c5c8c6 } +.terminal-505119418-r2 { fill: #e0e0e0 } +.terminal-505119418-r3 { fill: #a0a3a6 } +.terminal-505119418-r4 { fill: #1e1e1e } +.terminal-505119418-r5 { fill: #191919 } +.terminal-505119418-r6 { fill: #a5a5a5 } +.terminal-505119418-r7 { fill: #737373 } +.terminal-505119418-r8 { fill: #a5a5a5;font-style: italic; } +.terminal-505119418-r9 { fill: #7f7f7f } +.terminal-505119418-r10 { fill: #003054 } +.terminal-505119418-r11 { fill: #121212 } +.terminal-505119418-r12 { fill: #000000 } +.terminal-505119418-r13 { fill: #ffa62b;font-weight: bold } +.terminal-505119418-r14 { fill: #495259 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-auto + bmad-auto - + - - bmad-auto — ~/code/acme-search - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -target_branchdefault: the branch checked out at run start -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -worktree mode: branch all units merge back into (created if missing) - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -merge_strategydefault: merge -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -worktree mode: how a unit branch lands on the target — ff, merge, or squash - -▔▔▔▔▔▔▔▔ -delete_branch -▁▁▁▁▁▁▁▁ -worktree mode: delete the unit branch after a successful merge -▇▇ -▔▔▔▔▔▔▔▔ -keep_failed -▁▁▁▁▁▁▁▁ -worktree mode: keep a failed unit's worktree + branch mounted for inspection - -▔▔▔▔▔▔▔▔ -auto-rollback failed -attempts▁▁▁▁▁▁▁▁ - -⚠ in-place mode (isolation=none): when ON, a failed attempt's tracked changes are auto-reverted and the -untracked files this run created are deleted (its uncommitted work is lost). When OFF (default), the -orchestrator never touches your tree — it pauses with manual recovery steps. Prefer isolation=worktree to -keep failures off your main checkout.▆▆ - -▔▔▔▔▔▔▔▔ -seed adapter configs -▁▁▁▁▁▁▁▁ -worktree mode: copy each loaded adapter's gitignored MCP/CLI configs (.mcp.json, .claude/settings.json, -.codex/config.toml …) into the worktree so isolated sessions can reach their MCP server - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -extra worktree seed files - - - esc back  ^s save  ^e expand/collapse all  q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archiv^p palette + + bmad-auto — ~/code/acme-search + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +target_branchdefault: the branch checked out at run start +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +worktree mode: branch all units merge back into (created if missing) + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +merge_strategydefault: merge +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +worktree mode: how a unit branch lands on the target — ff, merge, or squash + +▔▔▔▔▔▔▔▔ +delete_branch +▁▁▁▁▁▁▁▁ +worktree mode: delete the unit branch after a successful merge +▆▆ +▔▔▔▔▔▔▔▔ +keep_failed +▁▁▁▁▁▁▁▁ +worktree mode: keep a failed unit's worktree + branch mounted for inspection + +▔▔▔▔▔▔▔▔ +auto-rollback failed +attempts▁▁▁▁▁▁▁▁ + +⚠ in-place mode (isolation=none): when ON, a failed attempt's tracked changes are auto-reverted and the +untracked files this run created are deleted (its uncommitted work is lost). When OFF (default), the +orchestrator never touches your tree — it pauses with manual recovery steps. Prefer isolation=worktree to +keep failures off your main checkout.▅▅ + +▔▔▔▔▔▔▔▔ +seed adapter configs +▁▁▁▁▁▁▁▁ +worktree mode: copy each loaded adapter's gitignored MCP/CLI configs (.mcp.json, .claude/settings.json, +.codex/config.toml …) into the worktree so isolated sessions can reach their MCP server + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +extra worktree seed files + + + esc back  ^s save  ^e expand/collapse all  q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archiv^p palette diff --git a/docs/images/settings.svg b/docs/images/settings.svg index 5575199..4c99668 100644 --- a/docs/images/settings.svg +++ b/docs/images/settings.svg @@ -19,209 +19,209 @@ font-weight: 700; } - .terminal-3686799903-matrix { + .terminal-1590434456-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3686799903-title { + .terminal-1590434456-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3686799903-r1 { fill: #c5c8c6 } -.terminal-3686799903-r2 { fill: #e0e0e0 } -.terminal-3686799903-r3 { fill: #a0a3a6 } -.terminal-3686799903-r4 { fill: #121212 } -.terminal-3686799903-r5 { fill: #6f6f6f } -.terminal-3686799903-r6 { fill: #ffa62b;font-weight: bold } -.terminal-3686799903-r7 { fill: #495259 } + .terminal-1590434456-r1 { fill: #c5c8c6 } +.terminal-1590434456-r2 { fill: #e0e0e0 } +.terminal-1590434456-r3 { fill: #a0a3a6 } +.terminal-1590434456-r4 { fill: #121212 } +.terminal-1590434456-r5 { fill: #6f6f6f } +.terminal-1590434456-r6 { fill: #ffa62b;font-weight: bold } +.terminal-1590434456-r7 { fill: #495259 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-auto + bmad-auto - + - - bmad-auto — ~/code/acme-search - -~/code/acme-search/.automator/policy.toml -running engines snapshot policy at start — changes apply to new runs and resumes -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ gates — approval gates, escalation & retrospective behavior - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ review — separate adversarial review session toggle - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ limits — cycle/attempt caps, timeout & token budget - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ verify — post-implementation verification commands - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ notify — desktop & file notifications - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ adapter — CLI client, model & bypass flags (base for all stages) - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ adapter.dev — dev-stage adapter overrides - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ adapter.review — review-stage adapter overrides - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ adapter.triage — triage-stage adapter overrides - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ sweep — deferred-work sweep automation - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ scm — git isolation, branching & merge-back - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▶ cleanup — disk reclamation for .automator/runs (terminal runs only) - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - esc back  ^s save  ^e expand/collapse all  q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archiv^p palette + + bmad-auto — ~/code/acme-search + +~/code/acme-search/.automator/policy.toml +running engines snapshot policy at start — changes apply to new runs and resumes +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ gates — approval gates, escalation & retrospective behavior + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ review — separate adversarial review session toggle + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ limits — cycle/attempt caps, timeout & token budget + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ verify — post-implementation verification commands + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ notify — desktop & file notifications + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ adapter — CLI client, model & bypass flags (base for all stages) + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ adapter.dev — dev-stage adapter overrides + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ adapter.review — review-stage adapter overrides + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ adapter.triage — triage-stage adapter overrides + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ sweep — deferred-work sweep automation + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ scm — git isolation, branching & merge-back + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ cleanup — disk reclamation for .automator/runs (terminal runs only) + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + esc back  ^s save  ^e expand/collapse all  q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archiv^p palette diff --git a/docs/images/start-run-modal.png b/docs/images/start-run-modal.png index b43be17..9006740 100644 Binary files a/docs/images/start-run-modal.png and b/docs/images/start-run-modal.png differ diff --git a/docs/images/start-run-modal.svg b/docs/images/start-run-modal.svg index b714562..1b74390 100644 --- a/docs/images/start-run-modal.svg +++ b/docs/images/start-run-modal.svg @@ -19,241 +19,241 @@ font-weight: 700; } - .terminal-3221216088-matrix { + .terminal-723573564-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3221216088-title { + .terminal-723573564-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3221216088-r1 { fill: #e0e0e0 } -.terminal-3221216088-r2 { fill: #646464 } -.terminal-3221216088-r3 { fill: #4a4c4d } -.terminal-3221216088-r4 { fill: #c5c8c6 } -.terminal-3221216088-r5 { fill: #0a2c4e } -.terminal-3221216088-r6 { fill: #646464;font-weight: bold } -.terminal-3221216088-r7 { fill: #476419 } -.terminal-3221216088-r8 { fill: #494949 } -.terminal-3221216088-r9 { fill: #704717 } -.terminal-3221216088-r10 { fill: #4a4a4a } -.terminal-3221216088-r11 { fill: #704717;font-weight: bold } -.terminal-3221216088-r12 { fill: #3b3b3b } -.terminal-3221216088-r13 { fill: #1a1a1a } -.terminal-3221216088-r14 { fill: #0b3a5f } -.terminal-3221216088-r15 { fill: #121212 } -.terminal-3221216088-r16 { fill: #141414 } -.terminal-3221216088-r17 { fill: #0053aa } -.terminal-3221216088-r18 { fill: #e0e0e0;font-weight: bold } -.terminal-3221216088-r19 { fill: #232323 } -.terminal-3221216088-r20 { fill: #1e1e1e } -.terminal-3221216088-r21 { fill: #0178d4 } -.terminal-3221216088-r22 { fill: #797979 } -.terminal-3221216088-r23 { fill: #191919 } -.terminal-3221216088-r24 { fill: #737373 } -.terminal-3221216088-r25 { fill: #2e5e68 } -.terminal-3221216088-r26 { fill: #6c0a30 } -.terminal-3221216088-r27 { fill: #242f38 } -.terminal-3221216088-r28 { fill: #000f18 } -.terminal-3221216088-r29 { fill: #6db2ff } -.terminal-3221216088-r30 { fill: #2d2d2d } -.terminal-3221216088-r31 { fill: #ddedf9;font-weight: bold } -.terminal-3221216088-r32 { fill: #656565;font-weight: bold } -.terminal-3221216088-r33 { fill: #004295 } -.terminal-3221216088-r34 { fill: #0d0d0d } -.terminal-3221216088-r35 { fill: #455969;font-weight: bold } -.terminal-3221216088-r36 { fill: #6c0a30;font-weight: bold } -.terminal-3221216088-r37 { fill: #4b4b4b } -.terminal-3221216088-r38 { fill: #704d1c;font-weight: bold } -.terminal-3221216088-r39 { fill: #282b2e } + .terminal-723573564-r1 { fill: #e0e0e0 } +.terminal-723573564-r2 { fill: #646464 } +.terminal-723573564-r3 { fill: #4a4c4d } +.terminal-723573564-r4 { fill: #c5c8c6 } +.terminal-723573564-r5 { fill: #0a2c4e } +.terminal-723573564-r6 { fill: #646464;font-weight: bold } +.terminal-723573564-r7 { fill: #476419 } +.terminal-723573564-r8 { fill: #494949 } +.terminal-723573564-r9 { fill: #704717 } +.terminal-723573564-r10 { fill: #4a4a4a } +.terminal-723573564-r11 { fill: #704717;font-weight: bold } +.terminal-723573564-r12 { fill: #3b3b3b } +.terminal-723573564-r13 { fill: #1a1a1a } +.terminal-723573564-r14 { fill: #0b3a5f } +.terminal-723573564-r15 { fill: #121212 } +.terminal-723573564-r16 { fill: #141414 } +.terminal-723573564-r17 { fill: #0053aa } +.terminal-723573564-r18 { fill: #e0e0e0;font-weight: bold } +.terminal-723573564-r19 { fill: #232323 } +.terminal-723573564-r20 { fill: #1e1e1e } +.terminal-723573564-r21 { fill: #0178d4 } +.terminal-723573564-r22 { fill: #797979 } +.terminal-723573564-r23 { fill: #191919 } +.terminal-723573564-r24 { fill: #737373 } +.terminal-723573564-r25 { fill: #2e5e68 } +.terminal-723573564-r26 { fill: #6c0a30 } +.terminal-723573564-r27 { fill: #242f38 } +.terminal-723573564-r28 { fill: #000f18 } +.terminal-723573564-r29 { fill: #6db2ff } +.terminal-723573564-r30 { fill: #2d2d2d } +.terminal-723573564-r31 { fill: #ddedf9;font-weight: bold } +.terminal-723573564-r32 { fill: #656565;font-weight: bold } +.terminal-723573564-r33 { fill: #004295 } +.terminal-723573564-r34 { fill: #0d0d0d } +.terminal-723573564-r35 { fill: #455969;font-weight: bold } +.terminal-723573564-r36 { fill: #6c0a30;font-weight: bold } +.terminal-723573564-r37 { fill: #4b4b4b } +.terminal-723573564-r38 { fill: #704d1c;font-weight: bold } +.terminal-723573564-r39 { fill: #282b2e } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-auto + bmad-auto - + - - bmad-auto — ~/code/acme-search -Runs────────────────────────────20260611-101500-c3d4 [sweep]  ▶ running  started 2026-06-11T10:15:00  epic 2 - st  run                   type  tasks 1  done 1  deferred 0  escalated 0  369,300 tokens - 20260610-090000-a1b2  story ⚑ decision needed: DW-1 — Reopen the OAuth refresh race now, or hold it for the auth hardening epic? - ▶   20260611-101500-c3d4  sweep   press a to attach and answer - 20260612-141000-e5f6  story ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - story                           phase             dev    review  tokens        info                               - dw-search-pagination            done              ×1     ×1      369,300       2b7f0a91c440                       -JournalLogAttention -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -▔▔▔▔▔▔▔▔▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -15:09:3 -Sprint──────────────────────────15:09:3start runons=2 -▼ Epic 1 · 3/3 ✓15:09:3 -├ ✓ 1-auth15:09:3▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ refresh race now, or hold it for the -├ ✓ 2-session-tokensauth …epic — blank for all -├ ✓ 3-password-reset▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -└ ✓ retrospective▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▼ Epic 2 · 2/5story — 3-1, 3.1, slug, or full key (blank for all) -├ ✓ 1-search-index▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -├ ✓ 2-typeahead▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -├ ▶ 3-search-rankingmax stories — blank for no limit -├ ◆ 4-saved-searches▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -└ ○ 5-search-analytics▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -▼ Epic 3 · 0/2X dry run (print the plan, spawn nothing)  -├ · 1-billing-portal▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -└ · 2-invoices -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - start  cancel  -Deferred Work — 2 to answer (d)▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -DW-1 Harden the OAuth token refr… -DW-2 Add pagination to the searc…▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ -DW-3 Replace the ad-hoc ranking … -DW-4 Flaky retry in the indexer … -DW-5 ✓ Polish the empty-state co… - - - - - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archive  c cleanup  v validate  g settings  M mod^p palette + + bmad-auto — ~/code/acme-search +Runs────────────────────────────20260611-101500-c3d4 [sweep]  ▶ running  started 2026-06-11T10:15:00  epic 2 + st  run                   type  tasks 1  done 1  deferred 0  escalated 0  369,300 tokens + 20260610-090000-a1b2  story ⚑ decision needed: DW-1 — Reopen the OAuth refresh race now, or hold it for the auth hardening epic? + ▶   20260611-101500-c3d4  sweep   press a to attach and answer + 20260612-141000-e5f6  story ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + story                           phase             dev    review  tokens        info                               + dw-search-pagination            done              ×1     ×1      369,300       2b7f0a91c440                       +JournalLogAttention +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +▔▔▔▔▔▔▔▔▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +20:25:2 +Sprint──────────────────────────20:25:2start runons=2 +▼ Epic 1 · 3/3 ✓20:25:2 +├ ✓ 1-auth20:25:2▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ refresh race now, or hold it for the +├ ✓ 2-session-tokensauth …epic — blank for all +├ ✓ 3-password-reset▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +└ ✓ retrospective▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▼ Epic 2 · 2/5story — 3-1, 3.1, slug, or full key (blank for all) +├ ✓ 1-search-index▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +├ ✓ 2-typeahead▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +├ ▶ 3-search-rankingmax stories — blank for no limit +├ ◆ 4-saved-searches▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +└ ○ 5-search-analytics▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▼ Epic 3 · 0/2X dry run (print the plan, spawn nothing)  +├ · 1-billing-portal▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +└ · 2-invoices +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + start  cancel  +Deferred Work — 2 to answer (d)▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +DW-1 Harden the OAuth token refr… +DW-2 Add pagination to the searc…▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ +DW-3 Replace the ad-hoc ranking … +DW-4 Flaky retry in the indexer … +DW-5 ✓ Polish the empty-state co… + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archive  c cleanup  v validate  g settings  M mod^p palette diff --git a/docs/images/sweep-decision.png b/docs/images/sweep-decision.png index 2493e6b..ab5b2ae 100644 Binary files a/docs/images/sweep-decision.png and b/docs/images/sweep-decision.png differ diff --git a/docs/images/sweep-decision.svg b/docs/images/sweep-decision.svg index f5decf5..981834c 100644 --- a/docs/images/sweep-decision.svg +++ b/docs/images/sweep-decision.svg @@ -19,227 +19,227 @@ font-weight: 700; } - .terminal-3147164668-matrix { + .terminal-3165711344-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3147164668-title { + .terminal-3165711344-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3147164668-r1 { fill: #c5c8c6 } -.terminal-3147164668-r2 { fill: #e0e0e0 } -.terminal-3147164668-r3 { fill: #a0a3a6 } -.terminal-3147164668-r4 { fill: #0053aa } -.terminal-3147164668-r5 { fill: #e2e2e2;font-weight: bold } -.terminal-3147164668-r6 { fill: #e0e0e0;font-weight: bold } -.terminal-3147164668-r7 { fill: #98e024 } -.terminal-3147164668-r8 { fill: #9d9d9d } -.terminal-3147164668-r9 { fill: #fd971f } -.terminal-3147164668-r10 { fill: #a1a1a1 } -.terminal-3147164668-r11 { fill: #fd971f;font-weight: bold } -.terminal-3147164668-r12 { fill: #ddedf9;font-weight: bold } -.terminal-3147164668-r13 { fill: #797979 } -.terminal-3147164668-r14 { fill: #262626 } -.terminal-3147164668-r15 { fill: #0178d4 } -.terminal-3147164668-r16 { fill: #121212 } -.terminal-3147164668-r17 { fill: #191919 } -.terminal-3147164668-r18 { fill: #9e9e9e } -.terminal-3147164668-r19 { fill: #58d1eb } -.terminal-3147164668-r20 { fill: #e1e1e1;font-weight: bold } -.terminal-3147164668-r21 { fill: #3e3e3e } -.terminal-3147164668-r22 { fill: #f4005f } -.terminal-3147164668-r23 { fill: #f4005f;font-weight: bold } -.terminal-3147164668-r24 { fill: #ffa62b;font-weight: bold } -.terminal-3147164668-r25 { fill: #495259 } + .terminal-3165711344-r1 { fill: #c5c8c6 } +.terminal-3165711344-r2 { fill: #e0e0e0 } +.terminal-3165711344-r3 { fill: #a0a3a6 } +.terminal-3165711344-r4 { fill: #0053aa } +.terminal-3165711344-r5 { fill: #e2e2e2;font-weight: bold } +.terminal-3165711344-r6 { fill: #e0e0e0;font-weight: bold } +.terminal-3165711344-r7 { fill: #98e024 } +.terminal-3165711344-r8 { fill: #9d9d9d } +.terminal-3165711344-r9 { fill: #fd971f } +.terminal-3165711344-r10 { fill: #a1a1a1 } +.terminal-3165711344-r11 { fill: #fd971f;font-weight: bold } +.terminal-3165711344-r12 { fill: #ddedf9;font-weight: bold } +.terminal-3165711344-r13 { fill: #797979 } +.terminal-3165711344-r14 { fill: #262626 } +.terminal-3165711344-r15 { fill: #0178d4 } +.terminal-3165711344-r16 { fill: #121212 } +.terminal-3165711344-r17 { fill: #191919 } +.terminal-3165711344-r18 { fill: #9e9e9e } +.terminal-3165711344-r19 { fill: #58d1eb } +.terminal-3165711344-r20 { fill: #e1e1e1;font-weight: bold } +.terminal-3165711344-r21 { fill: #3e3e3e } +.terminal-3165711344-r22 { fill: #f4005f } +.terminal-3165711344-r23 { fill: #f4005f;font-weight: bold } +.terminal-3165711344-r24 { fill: #ffa62b;font-weight: bold } +.terminal-3165711344-r25 { fill: #495259 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-auto + bmad-auto - + - - bmad-auto — ~/code/acme-search -Runs────────────────────────────20260611-101500-c3d4 [sweep]  ▶ running  started 2026-06-11T10:15:00  epic 2 - st  run                   type  tasks 1  done 1  deferred 0  escalated 0  369,300 tokens - 20260610-090000-a1b2  story ⚑ decision needed: DW-1 — Reopen the OAuth refresh race now, or hold it for the auth hardening epic? - ▶   20260611-101500-c3d4  sweep   press a to attach and answer - 20260612-141000-e5f6  story ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - story                           phase             dev    review  tokens        info                               - dw-search-pagination            done              ×1     ×1      369,300       2b7f0a91c440                       -JournalLogAttention -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -15:09:35 sweep-start              cycle=1 -Sprint──────────────────────────15:09:35 triage-done              bundles=1  already_resolved=1  decisions=2 -▼ Epic 1 · 3/3 ✓15:09:35 bundle-done              bundle=search-pagination  dw_ids=DW-2 -├ ✓ 1-auth15:09:35 decision-pending         dw_id=DW-1  question=Reopen the OAuth refresh race now, or hold it for the -├ ✓ 2-session-tokensauth … -├ ✓ 3-password-reset -└ ✓ retrospective -▼ Epic 2 · 2/5 -├ ✓ 1-search-index -├ ✓ 2-typeahead -├ ▶ 3-search-ranking -├ ◆ 4-saved-searches -└ ○ 5-search-analytics -▼ Epic 3 · 0/2 -├ · 1-billing-portal -└ · 2-invoices - - -Deferred Work — 2 to answer (d) -DW-1 Harden the OAuth token refr… -DW-2 Add pagination to the searc… -DW-3 Replace the ad-hoc ranking … -DW-4 Flaky retry in the indexer … -DW-5 ✓ Polish the empty-state co… - - - - - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archive  c cleanup  v validate  g settings  M mod^p palette + + bmad-auto — ~/code/acme-search +Runs────────────────────────────20260611-101500-c3d4 [sweep]  ▶ running  started 2026-06-11T10:15:00  epic 2 + st  run                   type  tasks 1  done 1  deferred 0  escalated 0  369,300 tokens + 20260610-090000-a1b2  story ⚑ decision needed: DW-1 — Reopen the OAuth refresh race now, or hold it for the auth hardening epic? + ▶   20260611-101500-c3d4  sweep   press a to attach and answer + 20260612-141000-e5f6  story ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + story                           phase             dev    review  tokens        info                               + dw-search-pagination            done              ×1     ×1      369,300       2b7f0a91c440                       +JournalLogAttention +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +20:25:29 sweep-start              cycle=1 +Sprint──────────────────────────20:25:29 triage-done              bundles=1  already_resolved=1  decisions=2 +▼ Epic 1 · 3/3 ✓20:25:29 bundle-done              bundle=search-pagination  dw_ids=DW-2 +├ ✓ 1-auth20:25:29 decision-pending         dw_id=DW-1  question=Reopen the OAuth refresh race now, or hold it for the +├ ✓ 2-session-tokensauth … +├ ✓ 3-password-reset +└ ✓ retrospective +▼ Epic 2 · 2/5 +├ ✓ 1-search-index +├ ✓ 2-typeahead +├ ▶ 3-search-ranking +├ ◆ 4-saved-searches +└ ○ 5-search-analytics +▼ Epic 3 · 0/2 +├ · 1-billing-portal +└ · 2-invoices + + +Deferred Work — 2 to answer (d) +DW-1 Harden the OAuth token refr… +DW-2 Add pagination to the searc… +DW-3 Replace the ad-hoc ranking … +DW-4 Flaky retry in the indexer … +DW-5 ✓ Polish the empty-state co… + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + q quit  r run  s sweep  e resume  R resolve  d decisions  a attach  x stop  D delete  A archive  c cleanup  v validate  g settings  M mod^p palette diff --git a/docs/plugin-authoring-guide.md b/docs/plugin-authoring-guide.md index a646241..e9ba28e 100644 --- a/docs/plugin-authoring-guide.md +++ b/docs/plugin-authoring-guide.md @@ -598,6 +598,31 @@ goes completely inert — proof of the trust gate. --- +## Platform portability + +bmad-auto's core is portable Python and the tmux dependency is quarantined behind +the multiplexer seam (see the [adapter authoring guide](adapter-authoring-guide.md)). +Plugin **helper scripts** run as standalone `python3