diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 73cbbea..ce0d8e2 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -12,7 +12,7 @@ "name": "bmad-loop", "source": "./src/bmad_loop/data/skills", "description": "Automation-mode skills driven by the bmad-loop orchestrator: interactive escalation resolution (bmad-loop-resolve) and deferred-work sweep triage (bmad-loop-sweep) — the inner dev primitive (which self-reviews and commits) is the upstream bmad-dev-auto skill", - "version": "0.8.0", + "version": "0.8.1", "author": { "name": "pinkyd" }, diff --git a/CHANGELOG.md b/CHANGELOG.md index e3f91e4..2ff2b2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,50 @@ All notable changes to `bmad-loop` 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.8.1] — 2026-07-05 + +### Fixed + +- **A session that finished its work but crashed before the run recorded it no longer loses that work + to a restart-and-rollback.** The engine now records a completed dev/review session behind a + durability barrier _before_ running post-session hooks (usage is folded in afterward as best-effort + metadata); on resume it consumes that durably-recorded result straight into verify/decide instead of + restarting the attempt from baseline. A raw `KeyboardInterrupt` now records a controlled stop, and + replay preserves the attempt/cycle/baseline. (#62, closes #57) +- **Several narrower resume-replay edges opened by that durability work are closed.** A host death in + the post-session window of the _last_ allowed review cycle no longer drops a recorded clean review to + a defer; a reconcile early-return no longer persists a pre-reconcile dict that could silently skip a + recommended follow-up review; and triage/sweep and labeled plugin-workflow sessions no longer persist + large, never-consumed result payloads into `state.json`. (#63) +- **A dev session is now completed only on a real Stop or window death, never on a terminal artifact + glimpsed while the agent window is still alive.** The idle-tick and grace-expiry shortcuts could + return "completed" mid-turn and let the run's cleanup kill a working agent, handing the engine + half-written state. Both shortcuts are removed, liveness is re-probed immediately before the + grace-expiry stall verdict, and a re-driven spec has its stale `## Auto Run Result` section stripped + on both re-arm paths so a resolved re-drive can't be misread as its own terminal result. Result scans + are now fence-aware, so an `## Auto Run Result` heading quoted inside a fenced code block is never + mistaken for a real section (nor destructively stripped). (#53, closes #48 #52) +- **Long journal fields in the TUI now wrap with a hanging indent instead of spilling back under the + timestamp and kind columns.** Each row renders as a fixed-width grid whose fields cell folds within + its own column. + +### Added + +- **Attempt-preserve recovery refs are now bounded.** With `scm.rollback_on_failure` on, auto-rollback + parks a failed attempt's committed work under `attempt-preserve/*` and its dirty worktree snapshot + under `attempt-preserve-dirty/*`; nothing pruned them, so they grew unbounded. Run start now keeps + only the newest `scm.preserve_keep` (default 20, `0` = never prune) per family by committer date and + best-effort-deletes the tail — a stuck ref never wedges the ones behind it, and prune failures are + journaled but never block the run. (#50 #54, closes #32 #49) + +### Changed + +- **The adapter shell-dialect seam is now an explicit, documented contract.** `new_window` / + `new_parked_window` factor their shell-dialect fragments into overridable hooks (POSIX output stays + byte-identical), and the `command` parameter's semantics are pinned in the ABC docstring + (shlex-joined argv; operator handling is backend-defined). Relevant only to authors porting the + adapter to a non-POSIX backend. (#47 #60) + ## [0.8.0] — 2026-07-03 ### Changed @@ -945,6 +989,7 @@ enforced in CI. implementation phase, driven by a Python control loop with hook-based session transport and resumable on-disk run state. +[0.8.1]: https://github.com/bmad-code-org/bmad-loop/releases/tag/v0.8.1 [0.8.0]: https://github.com/bmad-code-org/bmad-loop/releases/tag/v0.8.0 [0.7.12]: https://github.com/bmad-code-org/bmad-auto/releases/tag/v0.7.12 [0.7.11]: https://github.com/bmad-code-org/bmad-auto/releases/tag/v0.7.11 diff --git a/docs/images/dashboard.png b/docs/images/dashboard.png index 3fea92d..001d629 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 0a13265..822ef21 100644 --- a/docs/images/dashboard.svg +++ b/docs/images/dashboard.svg @@ -19,228 +19,228 @@ font-weight: 700; } - .terminal-2618510671-matrix { + .terminal-1304272949-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2618510671-title { + .terminal-1304272949-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2618510671-r1 { fill: #c5c8c6 } -.terminal-2618510671-r2 { fill: #e0e0e0 } -.terminal-2618510671-r3 { fill: #a0a3a6 } -.terminal-2618510671-r4 { fill: #0053aa } -.terminal-2618510671-r5 { fill: #e2e2e2;font-weight: bold } -.terminal-2618510671-r6 { fill: #e0e0e0;font-weight: bold } -.terminal-2618510671-r7 { fill: #98e024 } -.terminal-2618510671-r8 { fill: #9d9d9d } -.terminal-2618510671-r9 { fill: #fd971f } -.terminal-2618510671-r10 { fill: #a1a1a1 } -.terminal-2618510671-r11 { fill: #ddedf9;font-weight: bold } -.terminal-2618510671-r12 { fill: #1e1e1e } -.terminal-2618510671-r13 { fill: #003054 } -.terminal-2618510671-r14 { fill: #797979 } -.terminal-2618510671-r15 { fill: #e1e1e1;font-weight: bold } -.terminal-2618510671-r16 { fill: #262626 } -.terminal-2618510671-r17 { fill: #0178d4 } -.terminal-2618510671-r18 { fill: #121212 } -.terminal-2618510671-r19 { fill: #191919 } -.terminal-2618510671-r20 { fill: #3e3e3e } -.terminal-2618510671-r21 { fill: #9e9e9e } -.terminal-2618510671-r22 { fill: #58d1eb } -.terminal-2618510671-r23 { fill: #f4005f } -.terminal-2618510671-r24 { fill: #f4005f;font-weight: bold } -.terminal-2618510671-r25 { fill: #ffa62b;font-weight: bold } -.terminal-2618510671-r26 { fill: #495259 } + .terminal-1304272949-r1 { fill: #c5c8c6 } +.terminal-1304272949-r2 { fill: #e0e0e0 } +.terminal-1304272949-r3 { fill: #a0a3a6 } +.terminal-1304272949-r4 { fill: #0053aa } +.terminal-1304272949-r5 { fill: #e2e2e2;font-weight: bold } +.terminal-1304272949-r6 { fill: #e0e0e0;font-weight: bold } +.terminal-1304272949-r7 { fill: #98e024 } +.terminal-1304272949-r8 { fill: #9d9d9d } +.terminal-1304272949-r9 { fill: #fd971f } +.terminal-1304272949-r10 { fill: #a1a1a1 } +.terminal-1304272949-r11 { fill: #ddedf9;font-weight: bold } +.terminal-1304272949-r12 { fill: #1e1e1e } +.terminal-1304272949-r13 { fill: #003054 } +.terminal-1304272949-r14 { fill: #797979 } +.terminal-1304272949-r15 { fill: #e1e1e1;font-weight: bold } +.terminal-1304272949-r16 { fill: #262626 } +.terminal-1304272949-r17 { fill: #0178d4 } +.terminal-1304272949-r18 { fill: #121212 } +.terminal-1304272949-r19 { fill: #191919 } +.terminal-1304272949-r20 { fill: #3e3e3e } +.terminal-1304272949-r21 { fill: #9e9e9e } +.terminal-1304272949-r22 { fill: #58d1eb } +.terminal-1304272949-r23 { fill: #f4005f } +.terminal-1304272949-r24 { fill: #f4005f;font-weight: bold } +.terminal-1304272949-r25 { fill: #ffa62b;font-weight: bold } +.terminal-1304272949-r26 { fill: #495259 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-loop + bmad-loop - - - - bmad-loop — ~/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  1,059,100 tokens (2,473,900 raw) - 20260610-090000-a1b2  story ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - 20260611-101500-c3d4  sweep  story                           phase             dev    review  tokens        info                               r - ▶   20260612-141000-e5f6  story  2-1-search-index                done              ×1     ×1      338,400       a1b2c3d4e5f6                       8 - 2-2-typeahead                   done              ×1     ×2      283,200       b2c3d4e5f607                       6 - 2-3-search-ranking              review-running    ×1     ×1      224,300       5 - 2-4-saved-searches              dev-running       ×1     ×0      81,900        1 - 2-5-search-analytics            deferred          ×2     ×1      131,300       dev budget exhausted (2 attempts)  2 - -JournalLogAttention -Sprint──────────────────────────━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -▼ Epic 1 · 3/3 ✓▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -├ ✓ 1-auth11:32:21 session-start            task_id=2-1-search-index  role=dev  story_key=2-1-search-index -├ ✓ 2-session-tokens11:32:21 story-done               story_key=2-1-search-index  commit=a1b2c3d4e5f6 -├ ✓ 3-password-reset11:32:21 session-start            task_id=2-2-typeahead  role=dev  story_key=2-2-typeahead -└ ✓ retrospective11:32:21 review-cycle             story_key=2-2-typeahead  cycle=2  findings=3 -▼ Epic 2 · 2/511:32:21 story-done               story_key=2-2-typeahead  commit=b2c3d4e5f607 -├ ✓ 1-search-index11:32:21 story-start              story_key=2-3-search-ranking  epic=2 -├ ✓ 2-typeahead11:32:21 spec-approved            story_key=2-3-search-ranking  tokens=1834 -├ ▶ 3-search-ranking11:32:21 dev-done                 story_key=2-3-search-ranking  tasks_done=3  tasks_total=3 -├ ◆ 4-saved-searches11:32:21 verify-ok                story_key=2-3-search-ranking  commands=pytest -q, ruff check . -└ ○ 5-search-analytics11:32:21 review-start             story_key=2-3-search-ranking  role=review -▼ Epic 3 · 0/211:32:21 escalation-preference    story_key=2-3-search-ranking  detail=reviewer used codex for the scoring math -├ · 1-billing-portal11:32:21 story-deferred           story_key=2-5-search-analytics  reason=dev budget exhausted -└ · 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… - - - - - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - y copy  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 setting^p palette + + + + bmad-loop — ~/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  1,059,100 tokens (2,473,900 raw) + 20260610-090000-a1b2  story ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + 20260611-101500-c3d4  sweep  story                           phase             dev    review  tokens        info                               r + ▶   20260612-141000-e5f6  story  2-1-search-index                done              ×1     ×1      338,400       a1b2c3d4e5f6                       8 + 2-2-typeahead                   done              ×1     ×2      283,200       b2c3d4e5f607                       6 + 2-3-search-ranking              review-running    ×1     ×1      224,300       5 + 2-4-saved-searches              dev-running       ×1     ×0      81,900        1 + 2-5-search-analytics            deferred          ×2     ×1      131,300       dev budget exhausted (2 attempts)  2 + +JournalLogAttention +Sprint──────────────────────────━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +▼ Epic 1 · 3/3 ✓▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +├ ✓ 1-auth22:45:10session-start           task_id=2-1-search-index  role=dev  story_key=2-1-search-index +├ ✓ 2-session-tokens22:45:10story-done              story_key=2-1-search-index  commit=a1b2c3d4e5f6 +├ ✓ 3-password-reset22:45:10session-start           task_id=2-2-typeahead  role=dev  story_key=2-2-typeahead +└ ✓ retrospective22:45:10review-cycle            story_key=2-2-typeahead  cycle=2  findings=3 +▼ Epic 2 · 2/522:45:10story-done              story_key=2-2-typeahead  commit=b2c3d4e5f607 +├ ✓ 1-search-index22:45:10story-start             story_key=2-3-search-ranking  epic=2 +├ ✓ 2-typeahead22:45:10spec-approved           story_key=2-3-search-ranking  tokens=1834 +├ ▶ 3-search-ranking22:45:10dev-done                story_key=2-3-search-ranking  tasks_done=3  tasks_total=3 +├ ◆ 4-saved-searches22:45:10verify-ok               story_key=2-3-search-ranking  commands=pytest -q, ruff check . +└ ○ 5-search-analytics22:45:10review-start            story_key=2-3-search-ranking  role=review +▼ Epic 3 · 0/222:45:10escalation-preference   story_key=2-3-search-ranking  detail=reviewer used codex for the scoring math +├ · 1-billing-portal22:45:10story-deferred          story_key=2-5-search-analytics  reason=dev budget exhausted +└ · 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… + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + y copy  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 setting^p palette diff --git a/docs/images/decision-answer.png b/docs/images/decision-answer.png index de374cf..0af3282 100644 Binary files a/docs/images/decision-answer.png and b/docs/images/decision-answer.png differ diff --git a/docs/images/decision-answer.svg b/docs/images/decision-answer.svg index fb5cc61..3ce83c9 100644 --- a/docs/images/decision-answer.svg +++ b/docs/images/decision-answer.svg @@ -19,234 +19,234 @@ font-weight: 700; } - .terminal-3169928090-matrix { + .terminal-3357278493-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3169928090-title { + .terminal-3357278493-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3169928090-r1 { fill: #e0e0e0 } -.terminal-3169928090-r2 { fill: #646464 } -.terminal-3169928090-r3 { fill: #4a4c4d } -.terminal-3169928090-r4 { fill: #c5c8c6 } -.terminal-3169928090-r5 { fill: #0a2c4e } -.terminal-3169928090-r6 { fill: #646464;font-weight: bold } -.terminal-3169928090-r7 { fill: #476419 } -.terminal-3169928090-r8 { fill: #494949 } -.terminal-3169928090-r9 { fill: #704717 } -.terminal-3169928090-r10 { fill: #4a4a4a } -.terminal-3169928090-r11 { fill: #704717;font-weight: bold } -.terminal-3169928090-r12 { fill: #0053aa } -.terminal-3169928090-r13 { fill: #e0e0e0;font-weight: bold } -.terminal-3169928090-r14 { fill: #161616 } -.terminal-3169928090-r15 { fill: #0a1e2c } -.terminal-3169928090-r16 { fill: #9e9e9e } -.terminal-3169928090-r17 { fill: #1a1a1a } -.terminal-3169928090-r18 { fill: #141414 } -.terminal-3169928090-r19 { fill: #58d1eb } -.terminal-3169928090-r20 { fill: #98e024 } -.terminal-3169928090-r21 { fill: #232323 } -.terminal-3169928090-r22 { fill: #2d2d2d } -.terminal-3169928090-r23 { fill: #0d0d0d } -.terminal-3169928090-r24 { fill: #2e5e68 } -.terminal-3169928090-r25 { fill: #6c0a30 } -.terminal-3169928090-r26 { fill: #656565;font-weight: bold } -.terminal-3169928090-r27 { fill: #455969;font-weight: bold } -.terminal-3169928090-r28 { fill: #6c0a30;font-weight: bold } -.terminal-3169928090-r29 { fill: #4b4b4b } -.terminal-3169928090-r30 { fill: #121212 } -.terminal-3169928090-r31 { fill: #704d1c;font-weight: bold } -.terminal-3169928090-r32 { fill: #282b2e } + .terminal-3357278493-r1 { fill: #e0e0e0 } +.terminal-3357278493-r2 { fill: #646464 } +.terminal-3357278493-r3 { fill: #4a4c4d } +.terminal-3357278493-r4 { fill: #c5c8c6 } +.terminal-3357278493-r5 { fill: #0a2c4e } +.terminal-3357278493-r6 { fill: #646464;font-weight: bold } +.terminal-3357278493-r7 { fill: #476419 } +.terminal-3357278493-r8 { fill: #494949 } +.terminal-3357278493-r9 { fill: #704717 } +.terminal-3357278493-r10 { fill: #4a4a4a } +.terminal-3357278493-r11 { fill: #704717;font-weight: bold } +.terminal-3357278493-r12 { fill: #0053aa } +.terminal-3357278493-r13 { fill: #e0e0e0;font-weight: bold } +.terminal-3357278493-r14 { fill: #161616 } +.terminal-3357278493-r15 { fill: #0a1e2c } +.terminal-3357278493-r16 { fill: #9e9e9e } +.terminal-3357278493-r17 { fill: #1a1a1a } +.terminal-3357278493-r18 { fill: #141414 } +.terminal-3357278493-r19 { fill: #58d1eb } +.terminal-3357278493-r20 { fill: #98e024 } +.terminal-3357278493-r21 { fill: #232323 } +.terminal-3357278493-r22 { fill: #2d2d2d } +.terminal-3357278493-r23 { fill: #0d0d0d } +.terminal-3357278493-r24 { fill: #2e5e68 } +.terminal-3357278493-r25 { fill: #6c0a30 } +.terminal-3357278493-r26 { fill: #656565;font-weight: bold } +.terminal-3357278493-r27 { fill: #455969;font-weight: bold } +.terminal-3357278493-r28 { fill: #6c0a30;font-weight: bold } +.terminal-3357278493-r29 { fill: #4b4b4b } +.terminal-3357278493-r30 { fill: #121212 } +.terminal-3357278493-r31 { fill: #704d1c;font-weight: bold } +.terminal-3357278493-r32 { fill: #282b2e } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-loop + bmad-loop - - - - bmad-loop — ~/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  153,300 tokens (369,300 raw) - 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▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀──────────────────────────────── - r -DW-1 — answer this decision0a91c440                       3 - -Harden the OAuth refresh race now, or hold it for the auth-hardening epic? -Two concurrent requests can both refresh the token. A single-flight lock fixes━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -it now, but the upcoming auth-hardening epic reworks this module anyway.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -Sprint───────────────────────── -▼ Epic 1 · 3/3 ✓[1] Add a single-flight lock now  · build  (recommended) -├ ✓ 1-auth    Guard the refresh path with a single-flight lock so only one refresh runs. -├ ✓ 2-session-tokensce now, or hold it for the -├ ✓ 3-password-reset▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -└ ✓ retrospective choose 1  -▼ Epic 2 · 2/5▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -├ ✓ 1-search-index -├ ✓ 2-typeahead[2] Hold for the auth-hardening epic  · keep-open -├ ▶ 3-search-ranking▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -├ ◆ 4-saved-searches choose 2  -└ ○ 5-search-analytics▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -▼ Epic 3 · 0/2 -├ · 1-billing-portal[3] Won't fix — refresh is idempotent  · close -└ · 2-invoices    A double refresh is harmless; the second result is discarded. - -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -Deferred Work — 2 to answer (d) choose 3  -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  skip  -DW-5 ✓ Polish the empty-state co▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ - - - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - y copy  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 setting^p palette + + + + bmad-loop — ~/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  153,300 tokens (369,300 raw) + 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▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀──────────────────────────────── + r +DW-1 — answer this decision0a91c440                       3 + +Harden the OAuth refresh race now, or hold it for the auth-hardening epic? +Two concurrent requests can both refresh the token. A single-flight lock fixes━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +it now, but the upcoming auth-hardening epic reworks this module anyway.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Sprint───────────────────────── +▼ Epic 1 · 3/3 ✓[1] Add a single-flight lock now  · build  (recommended) +├ ✓ 1-auth    Guard the refresh path with a single-flight lock so only one refresh runs. +├ ✓ 2-session-tokensce now, or hold it for the     +├ ✓ 3-password-reset▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +└ ✓ retrospective choose 1  +▼ Epic 2 · 2/5▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +├ ✓ 1-search-index +├ ✓ 2-typeahead[2] Hold for the auth-hardening epic  · keep-open +├ ▶ 3-search-ranking▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +├ ◆ 4-saved-searches choose 2  +└ ○ 5-search-analytics▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▼ Epic 3 · 0/2 +├ · 1-billing-portal[3] Won't fix — refresh is idempotent  · close +└ · 2-invoices    A double refresh is harmless; the second result is discarded. + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Deferred Work — 2 to answer (d) choose 3  +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  skip  +DW-5 ✓ Polish the empty-state co▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + y copy  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 setting^p palette diff --git a/docs/images/deferred-modal.png b/docs/images/deferred-modal.png index 58a1121..953ccd0 100644 Binary files a/docs/images/deferred-modal.png and b/docs/images/deferred-modal.png differ diff --git a/docs/images/deferred-modal.svg b/docs/images/deferred-modal.svg index 0303e87..11e94b7 100644 --- a/docs/images/deferred-modal.svg +++ b/docs/images/deferred-modal.svg @@ -19,232 +19,232 @@ font-weight: 700; } - .terminal-2838225026-matrix { + .terminal-1045143045-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2838225026-title { + .terminal-1045143045-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2838225026-r1 { fill: #e0e0e0 } -.terminal-2838225026-r2 { fill: #646464 } -.terminal-2838225026-r3 { fill: #4a4c4d } -.terminal-2838225026-r4 { fill: #c5c8c6 } -.terminal-2838225026-r5 { fill: #0a2c4e } -.terminal-2838225026-r6 { fill: #646464;font-weight: bold } -.terminal-2838225026-r7 { fill: #476419 } -.terminal-2838225026-r8 { fill: #494949 } -.terminal-2838225026-r9 { fill: #704717 } -.terminal-2838225026-r10 { fill: #4a4a4a } -.terminal-2838225026-r11 { fill: #704717;font-weight: bold } -.terminal-2838225026-r12 { fill: #0053aa } -.terminal-2838225026-r13 { fill: #e0e0e0;font-weight: bold } -.terminal-2838225026-r14 { fill: #161616 } -.terminal-2838225026-r15 { fill: #0a1e2c } -.terminal-2838225026-r16 { fill: #1a1a1a } -.terminal-2838225026-r17 { fill: #141414 } -.terminal-2838225026-r18 { fill: #232323 } -.terminal-2838225026-r19 { fill: #2e5e68 } -.terminal-2838225026-r20 { fill: #6c0a30 } -.terminal-2838225026-r21 { fill: #656565;font-weight: bold } -.terminal-2838225026-r22 { fill: #455969;font-weight: bold } -.terminal-2838225026-r23 { fill: #6c0a30;font-weight: bold } -.terminal-2838225026-r24 { fill: #4b4b4b } -.terminal-2838225026-r25 { fill: #6db2ff } -.terminal-2838225026-r26 { fill: #ddedf9;font-weight: bold } -.terminal-2838225026-r27 { fill: #004295 } -.terminal-2838225026-r28 { fill: #121212 } -.terminal-2838225026-r29 { fill: #704d1c;font-weight: bold } -.terminal-2838225026-r30 { fill: #282b2e } + .terminal-1045143045-r1 { fill: #e0e0e0 } +.terminal-1045143045-r2 { fill: #646464 } +.terminal-1045143045-r3 { fill: #4a4c4d } +.terminal-1045143045-r4 { fill: #c5c8c6 } +.terminal-1045143045-r5 { fill: #0a2c4e } +.terminal-1045143045-r6 { fill: #646464;font-weight: bold } +.terminal-1045143045-r7 { fill: #476419 } +.terminal-1045143045-r8 { fill: #494949 } +.terminal-1045143045-r9 { fill: #704717 } +.terminal-1045143045-r10 { fill: #4a4a4a } +.terminal-1045143045-r11 { fill: #704717;font-weight: bold } +.terminal-1045143045-r12 { fill: #0053aa } +.terminal-1045143045-r13 { fill: #e0e0e0;font-weight: bold } +.terminal-1045143045-r14 { fill: #161616 } +.terminal-1045143045-r15 { fill: #0a1e2c } +.terminal-1045143045-r16 { fill: #1a1a1a } +.terminal-1045143045-r17 { fill: #141414 } +.terminal-1045143045-r18 { fill: #232323 } +.terminal-1045143045-r19 { fill: #2e5e68 } +.terminal-1045143045-r20 { fill: #6c0a30 } +.terminal-1045143045-r21 { fill: #656565;font-weight: bold } +.terminal-1045143045-r22 { fill: #455969;font-weight: bold } +.terminal-1045143045-r23 { fill: #6c0a30;font-weight: bold } +.terminal-1045143045-r24 { fill: #4b4b4b } +.terminal-1045143045-r25 { fill: #6db2ff } +.terminal-1045143045-r26 { fill: #ddedf9;font-weight: bold } +.terminal-1045143045-r27 { fill: #004295 } +.terminal-1045143045-r28 { fill: #121212 } +.terminal-1045143045-r29 { fill: #704d1c;font-weight: bold } +.terminal-1045143045-r30 { fill: #282b2e } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-loop + bmad-loop - - - - bmad-loop — ~/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  153,300 tokens (369,300 raw) - 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 ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ - 20260612-141000-e5f6 ─────────────────────────── -DW-1 — Harden the OAuth token refresh race r -440                       3 -### DW-1: Harden the OAuth token refresh race - -origin: epic 1 review, 2026-06-02━━━━━━━━━━━━━━━━━━━━━━━━━━━ -location: src/auth/tokens.py:184▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -Sprint────────────────────severity: high -▼ Epic 1 · 3/3 ✓reason: Two concurrent requests can both refresh; needs a single-flight lock. -├ ✓ 1-authstatus: open -├ ✓ 2-session-tokensw, or hold it for the -├ ✓ 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 answe -DW-1 Harden the OAuth token -DW-2 Add pagination to the  -DW-3 Replace the ad-hoc ran▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -DW-4 Flaky retry in the ind close  -DW-5 ✓ Polish the empty-sta▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ - - - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - y copy  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 setting^p palette + + + + bmad-loop — ~/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  153,300 tokens (369,300 raw) + 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 ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ + 20260612-141000-e5f6 ─────────────────────────── +DW-1 — Harden the OAuth token refresh race r +440                       3 +### DW-1: Harden the OAuth token refresh race + +origin: epic 1 review, 2026-06-02━━━━━━━━━━━━━━━━━━━━━━━━━━━ +location: src/auth/tokens.py:184▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Sprint────────────────────severity: high +▼ Epic 1 · 3/3 ✓reason: Two concurrent requests can both refresh; needs a single-flight lock. +├ ✓ 1-authstatus: open +├ ✓ 2-session-tokensw, or hold it for the     +├ ✓ 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 answe +DW-1 Harden the OAuth token +DW-2 Add pagination to the  +DW-3 Replace the ad-hoc ran▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +DW-4 Flaky retry in the ind close  +DW-5 ✓ Polish the empty-sta▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + y copy  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 setting^p palette diff --git a/docs/images/demo.gif b/docs/images/demo.gif index 6918567..8a4d4a3 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 76b2baa..6fd4b31 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 156f49b..3b0194f 100644 --- a/docs/images/settings-scm.svg +++ b/docs/images/settings-scm.svg @@ -19,216 +19,216 @@ font-weight: 700; } - .terminal-639115204-matrix { + .terminal-2298416402-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-639115204-title { + .terminal-2298416402-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-639115204-r1 { fill: #c5c8c6 } -.terminal-639115204-r2 { fill: #e0e0e0 } -.terminal-639115204-r3 { fill: #a0a3a6 } -.terminal-639115204-r4 { fill: #1e1e1e } -.terminal-639115204-r5 { fill: #191919 } -.terminal-639115204-r6 { fill: #a5a5a5 } -.terminal-639115204-r7 { fill: #737373 } -.terminal-639115204-r8 { fill: #a5a5a5;font-style: italic; } -.terminal-639115204-r9 { fill: #7f7f7f } -.terminal-639115204-r10 { fill: #003054 } -.terminal-639115204-r11 { fill: #121212 } -.terminal-639115204-r12 { fill: #000000 } -.terminal-639115204-r13 { fill: #ffa62b;font-weight: bold } -.terminal-639115204-r14 { fill: #495259 } + .terminal-2298416402-r1 { fill: #c5c8c6 } +.terminal-2298416402-r2 { fill: #e0e0e0 } +.terminal-2298416402-r3 { fill: #a0a3a6 } +.terminal-2298416402-r4 { fill: #a5a5a5 } +.terminal-2298416402-r5 { fill: #1e1e1e } +.terminal-2298416402-r6 { fill: #7f7f7f } +.terminal-2298416402-r7 { fill: #191919 } +.terminal-2298416402-r8 { fill: #a5a5a5;font-style: italic; } +.terminal-2298416402-r9 { fill: #003054 } +.terminal-2298416402-r10 { fill: #121212 } +.terminal-2298416402-r11 { fill: #737373 } +.terminal-2298416402-r12 { fill: #000000 } +.terminal-2298416402-r13 { fill: #ffa62b;font-weight: bold } +.terminal-2298416402-r14 { fill: #495259 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-loop + bmad-loop - - - - bmad-loop — ~/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. Governs unattended/stopped -attempts only: a resolved escalation's re-drive always auto-recovers regardless (reverts the failed source, -keeps the corrected spec). 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-loop — ~/code/acme-search +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. Governs unattended/stopped +attempts only: a resolved escalation's re-drive always auto-recovers regardless (reverts the failed source, +keeps the corrected spec). Prefer isolation=worktree to keep failures off your main checkout. + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +preserve-ref retentiondefault: 20 +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +attempt-preserve/* recovery branches and attempt-preserve-dirty/* worktree snapshots kept at each run start +(per family) · the newest by committer date survive and the tail is deleted (0 = never prune)▁▁ + +▔▔▔▔▔▔▔▔ +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 6f721a6..7d2025d 100644 --- a/docs/images/settings.svg +++ b/docs/images/settings.svg @@ -19,209 +19,209 @@ font-weight: 700; } - .terminal-3457620312-matrix { + .terminal-3186694558-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3457620312-title { + .terminal-3186694558-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3457620312-r1 { fill: #c5c8c6 } -.terminal-3457620312-r2 { fill: #e0e0e0 } -.terminal-3457620312-r3 { fill: #a0a3a6 } -.terminal-3457620312-r4 { fill: #121212 } -.terminal-3457620312-r5 { fill: #6f6f6f } -.terminal-3457620312-r6 { fill: #ffa62b;font-weight: bold } -.terminal-3457620312-r7 { fill: #495259 } + .terminal-3186694558-r1 { fill: #c5c8c6 } +.terminal-3186694558-r2 { fill: #e0e0e0 } +.terminal-3186694558-r3 { fill: #a0a3a6 } +.terminal-3186694558-r4 { fill: #121212 } +.terminal-3186694558-r5 { fill: #6f6f6f } +.terminal-3186694558-r6 { fill: #ffa62b;font-weight: bold } +.terminal-3186694558-r7 { fill: #495259 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-loop + bmad-loop - + - - bmad-loop — ~/code/acme-search - -~/code/acme-search/.bmad-loop/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 .bmad-loop/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-loop — ~/code/acme-search + +~/code/acme-search/.bmad-loop/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 .bmad-loop/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 efe87a1..d846434 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 3bf2706..dec641c 100644 --- a/docs/images/start-run-modal.svg +++ b/docs/images/start-run-modal.svg @@ -19,243 +19,243 @@ font-weight: 700; } - .terminal-1593462663-matrix { + .terminal-3417491320-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1593462663-title { + .terminal-3417491320-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1593462663-r1 { fill: #e0e0e0 } -.terminal-1593462663-r2 { fill: #646464 } -.terminal-1593462663-r3 { fill: #4a4c4d } -.terminal-1593462663-r4 { fill: #c5c8c6 } -.terminal-1593462663-r5 { fill: #0a2c4e } -.terminal-1593462663-r6 { fill: #646464;font-weight: bold } -.terminal-1593462663-r7 { fill: #476419 } -.terminal-1593462663-r8 { fill: #494949 } -.terminal-1593462663-r9 { fill: #704717 } -.terminal-1593462663-r10 { fill: #4a4a4a } -.terminal-1593462663-r11 { fill: #704717;font-weight: bold } -.terminal-1593462663-r12 { fill: #161616 } -.terminal-1593462663-r13 { fill: #0a1e2c } -.terminal-1593462663-r14 { fill: #3b3b3b } -.terminal-1593462663-r15 { fill: #1a1a1a } -.terminal-1593462663-r16 { fill: #0b3a5f } -.terminal-1593462663-r17 { fill: #0053aa } -.terminal-1593462663-r18 { fill: #121212 } -.terminal-1593462663-r19 { fill: #141414 } -.terminal-1593462663-r20 { fill: #e0e0e0;font-weight: bold } -.terminal-1593462663-r21 { fill: #232323 } -.terminal-1593462663-r22 { fill: #1e1e1e } -.terminal-1593462663-r23 { fill: #0178d4 } -.terminal-1593462663-r24 { fill: #797979 } -.terminal-1593462663-r25 { fill: #191919 } -.terminal-1593462663-r26 { fill: #737373 } -.terminal-1593462663-r27 { fill: #2e5e68 } -.terminal-1593462663-r28 { fill: #6c0a30 } -.terminal-1593462663-r29 { fill: #242f38 } -.terminal-1593462663-r30 { fill: #000f18 } -.terminal-1593462663-r31 { fill: #6db2ff } -.terminal-1593462663-r32 { fill: #2d2d2d } -.terminal-1593462663-r33 { fill: #ddedf9;font-weight: bold } -.terminal-1593462663-r34 { fill: #656565;font-weight: bold } -.terminal-1593462663-r35 { fill: #004295 } -.terminal-1593462663-r36 { fill: #0d0d0d } -.terminal-1593462663-r37 { fill: #455969;font-weight: bold } -.terminal-1593462663-r38 { fill: #6c0a30;font-weight: bold } -.terminal-1593462663-r39 { fill: #4b4b4b } -.terminal-1593462663-r40 { fill: #704d1c;font-weight: bold } -.terminal-1593462663-r41 { fill: #282b2e } + .terminal-3417491320-r1 { fill: #e0e0e0 } +.terminal-3417491320-r2 { fill: #646464 } +.terminal-3417491320-r3 { fill: #4a4c4d } +.terminal-3417491320-r4 { fill: #c5c8c6 } +.terminal-3417491320-r5 { fill: #0a2c4e } +.terminal-3417491320-r6 { fill: #646464;font-weight: bold } +.terminal-3417491320-r7 { fill: #476419 } +.terminal-3417491320-r8 { fill: #494949 } +.terminal-3417491320-r9 { fill: #704717 } +.terminal-3417491320-r10 { fill: #4a4a4a } +.terminal-3417491320-r11 { fill: #704717;font-weight: bold } +.terminal-3417491320-r12 { fill: #161616 } +.terminal-3417491320-r13 { fill: #0a1e2c } +.terminal-3417491320-r14 { fill: #3b3b3b } +.terminal-3417491320-r15 { fill: #1a1a1a } +.terminal-3417491320-r16 { fill: #0b3a5f } +.terminal-3417491320-r17 { fill: #0053aa } +.terminal-3417491320-r18 { fill: #121212 } +.terminal-3417491320-r19 { fill: #141414 } +.terminal-3417491320-r20 { fill: #e0e0e0;font-weight: bold } +.terminal-3417491320-r21 { fill: #232323 } +.terminal-3417491320-r22 { fill: #1e1e1e } +.terminal-3417491320-r23 { fill: #0178d4 } +.terminal-3417491320-r24 { fill: #797979 } +.terminal-3417491320-r25 { fill: #191919 } +.terminal-3417491320-r26 { fill: #737373 } +.terminal-3417491320-r27 { fill: #2e5e68 } +.terminal-3417491320-r28 { fill: #6c0a30 } +.terminal-3417491320-r29 { fill: #242f38 } +.terminal-3417491320-r30 { fill: #000f18 } +.terminal-3417491320-r31 { fill: #6db2ff } +.terminal-3417491320-r32 { fill: #2d2d2d } +.terminal-3417491320-r33 { fill: #ddedf9;font-weight: bold } +.terminal-3417491320-r34 { fill: #656565;font-weight: bold } +.terminal-3417491320-r35 { fill: #004295 } +.terminal-3417491320-r36 { fill: #0d0d0d } +.terminal-3417491320-r37 { fill: #455969;font-weight: bold } +.terminal-3417491320-r38 { fill: #6c0a30;font-weight: bold } +.terminal-3417491320-r39 { fill: #4b4b4b } +.terminal-3417491320-r40 { fill: #704d1c;font-weight: bold } +.terminal-3417491320-r41 { fill: #282b2e } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-loop + bmad-loop - - - - bmad-loop — ~/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  153,300 tokens (369,300 raw) - 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                               r - dw-search-pagination            done              ×1     ×1      153,300       2b7f0a91c440                       3 - -JournalLogAttention -━━━━━━━▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -Sprint──────────────────────────11:32:2start run -▼ Epic 1 · 3/3 ✓11:32:2ons=2 -├ ✓ 1-auth11:32:2▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -├ ✓ 2-session-tokens11:32:2epic — blank for all refresh race now, or hold it for the -├ ✓ 3-password-resetauth …▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -└ ✓ 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… - - - - - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - y copy  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 setting^p palette + + + + bmad-loop — ~/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  153,300 tokens (369,300 raw) + 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                               r + dw-search-pagination            done              ×1     ×1      153,300       2b7f0a91c440                       3 + +JournalLogAttention +━━━━━━━▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Sprint──────────────────────────22:45:1start run +▼ Epic 1 · 3/3 ✓22:45:1ons=2 +├ ✓ 1-auth22:45:1▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +├ ✓ 2-session-tokens22:45:1epic — blank for all refresh race now, or hold it for the     +├ ✓ 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… + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + y copy  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 setting^p palette diff --git a/docs/images/sweep-decision.png b/docs/images/sweep-decision.png index 417946e..8f491b2 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 be13a6b..68af14e 100644 --- a/docs/images/sweep-decision.svg +++ b/docs/images/sweep-decision.svg @@ -19,229 +19,229 @@ font-weight: 700; } - .terminal-2638274601-matrix { + .terminal-2260530837-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2638274601-title { + .terminal-2260530837-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2638274601-r1 { fill: #c5c8c6 } -.terminal-2638274601-r2 { fill: #e0e0e0 } -.terminal-2638274601-r3 { fill: #a0a3a6 } -.terminal-2638274601-r4 { fill: #0053aa } -.terminal-2638274601-r5 { fill: #e2e2e2;font-weight: bold } -.terminal-2638274601-r6 { fill: #e0e0e0;font-weight: bold } -.terminal-2638274601-r7 { fill: #98e024 } -.terminal-2638274601-r8 { fill: #9d9d9d } -.terminal-2638274601-r9 { fill: #fd971f } -.terminal-2638274601-r10 { fill: #a1a1a1 } -.terminal-2638274601-r11 { fill: #fd971f;font-weight: bold } -.terminal-2638274601-r12 { fill: #ddedf9;font-weight: bold } -.terminal-2638274601-r13 { fill: #1e1e1e } -.terminal-2638274601-r14 { fill: #003054 } -.terminal-2638274601-r15 { fill: #797979 } -.terminal-2638274601-r16 { fill: #262626 } -.terminal-2638274601-r17 { fill: #0178d4 } -.terminal-2638274601-r18 { fill: #121212 } -.terminal-2638274601-r19 { fill: #191919 } -.terminal-2638274601-r20 { fill: #e1e1e1;font-weight: bold } -.terminal-2638274601-r21 { fill: #9e9e9e } -.terminal-2638274601-r22 { fill: #58d1eb } -.terminal-2638274601-r23 { fill: #3e3e3e } -.terminal-2638274601-r24 { fill: #f4005f } -.terminal-2638274601-r25 { fill: #f4005f;font-weight: bold } -.terminal-2638274601-r26 { fill: #ffa62b;font-weight: bold } -.terminal-2638274601-r27 { fill: #495259 } + .terminal-2260530837-r1 { fill: #c5c8c6 } +.terminal-2260530837-r2 { fill: #e0e0e0 } +.terminal-2260530837-r3 { fill: #a0a3a6 } +.terminal-2260530837-r4 { fill: #0053aa } +.terminal-2260530837-r5 { fill: #e2e2e2;font-weight: bold } +.terminal-2260530837-r6 { fill: #e0e0e0;font-weight: bold } +.terminal-2260530837-r7 { fill: #98e024 } +.terminal-2260530837-r8 { fill: #9d9d9d } +.terminal-2260530837-r9 { fill: #fd971f } +.terminal-2260530837-r10 { fill: #a1a1a1 } +.terminal-2260530837-r11 { fill: #fd971f;font-weight: bold } +.terminal-2260530837-r12 { fill: #ddedf9;font-weight: bold } +.terminal-2260530837-r13 { fill: #1e1e1e } +.terminal-2260530837-r14 { fill: #003054 } +.terminal-2260530837-r15 { fill: #797979 } +.terminal-2260530837-r16 { fill: #262626 } +.terminal-2260530837-r17 { fill: #0178d4 } +.terminal-2260530837-r18 { fill: #121212 } +.terminal-2260530837-r19 { fill: #191919 } +.terminal-2260530837-r20 { fill: #e1e1e1;font-weight: bold } +.terminal-2260530837-r21 { fill: #9e9e9e } +.terminal-2260530837-r22 { fill: #58d1eb } +.terminal-2260530837-r23 { fill: #3e3e3e } +.terminal-2260530837-r24 { fill: #f4005f } +.terminal-2260530837-r25 { fill: #f4005f;font-weight: bold } +.terminal-2260530837-r26 { fill: #ffa62b;font-weight: bold } +.terminal-2260530837-r27 { fill: #495259 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - bmad-loop + bmad-loop - - - - bmad-loop — ~/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  153,300 tokens (369,300 raw) - 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                               r - dw-search-pagination            done              ×1     ×1      153,300       2b7f0a91c440                       3 - -JournalLogAttention -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -Sprint──────────────────────────11:32:21 sweep-start              cycle=1 -▼ Epic 1 · 3/3 ✓11:32:21 triage-done              bundles=1  already_resolved=1  decisions=2 -├ ✓ 1-auth11:32:21 bundle-done              bundle=search-pagination  dw_ids=DW-2 -├ ✓ 2-session-tokens11:32:21 decision-pending         dw_id=DW-1  question=Reopen the OAuth refresh race now, or hold it for the -├ ✓ 3-password-resetauth … -└ ✓ 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… - - - - - -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - y copy  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 setting^p palette + + + + bmad-loop — ~/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  153,300 tokens (369,300 raw) + 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                               r + dw-search-pagination            done              ×1     ×1      153,300       2b7f0a91c440                       3 + +JournalLogAttention +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Sprint──────────────────────────22:45:10sweep-start             cycle=1 +▼ Epic 1 · 3/3 ✓22:45:10triage-done             bundles=1  already_resolved=1  decisions=2 +├ ✓ 1-auth22:45:10bundle-done             bundle=search-pagination  dw_ids=DW-2 +├ ✓ 2-session-tokens22:45:10decision-pending        dw_id=DW-1  question=Reopen the OAuth refresh race now, or hold it for the     +├ ✓ 3-password-resetauth …                                                                         +└ ✓ 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… + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + y copy  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 setting^p palette diff --git a/module.yaml b/module.yaml index c91c12f..684c354 100644 --- a/module.yaml +++ b/module.yaml @@ -1,7 +1,7 @@ code: bmad-loop name: BMAD Loop Skills description: "Automation-mode skills driven by the bmad-loop orchestrator: interactive escalation resolution (bmad-loop-resolve) and deferred-work sweep triage (bmad-loop-sweep) — the inner dev primitive (which self-reviews and commits) is the upstream bmad-dev-auto skill" -module_version: 0.8.0 +module_version: 0.8.1 default_selected: false module_greeting: > BMAD Loop installed — both the automation skills and the diff --git a/pyproject.toml b/pyproject.toml index 18a9553..2302cdc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "bmad-loop" -version = "0.8.0" +version = "0.8.1" description = "Deterministic ralph-loop orchestrator for the BMAD implementation phase" readme = "README.md" license = "MIT" diff --git a/src/bmad_loop/__init__.py b/src/bmad_loop/__init__.py index 77218c8..f9f12a2 100644 --- a/src/bmad_loop/__init__.py +++ b/src/bmad_loop/__init__.py @@ -6,4 +6,4 @@ spec files, and the per-run directory under .bmad-loop/runs/. """ -__version__ = "0.8.0" +__version__ = "0.8.1" diff --git a/src/bmad_loop/data/skills/bmad-loop-setup/assets/module.yaml b/src/bmad_loop/data/skills/bmad-loop-setup/assets/module.yaml index c91c12f..684c354 100644 --- a/src/bmad_loop/data/skills/bmad-loop-setup/assets/module.yaml +++ b/src/bmad_loop/data/skills/bmad-loop-setup/assets/module.yaml @@ -1,7 +1,7 @@ code: bmad-loop name: BMAD Loop Skills description: "Automation-mode skills driven by the bmad-loop orchestrator: interactive escalation resolution (bmad-loop-resolve) and deferred-work sweep triage (bmad-loop-sweep) — the inner dev primitive (which self-reviews and commits) is the upstream bmad-dev-auto skill" -module_version: 0.8.0 +module_version: 0.8.1 default_selected: false module_greeting: > BMAD Loop installed — both the automation skills and the diff --git a/src/bmad_loop/tui/widgets.py b/src/bmad_loop/tui/widgets.py index 4fa72fe..6c4df70 100644 --- a/src/bmad_loop/tui/widgets.py +++ b/src/bmad_loop/tui/widgets.py @@ -11,6 +11,7 @@ from pathlib import Path from typing import Any +from rich.table import Table from rich.text import Text from textual.selection import Selection from textual.widgets import RichLog, Static, Tree @@ -166,23 +167,34 @@ def show_run( # the journal -> log jump, not the human _JOURNAL_HIDDEN_FIELDS = ("ts", "kind", "log_task", "log_pos") +# Row-grid geometry. The fields column's left edge sits at +# _JOURNAL_CLOCK_WIDTH + _JOURNAL_COL_PAD + _JOURNAL_KIND_WIDTH + _JOURNAL_COL_PAD; +# the hanging-indent test derives its indent from the same constants so the two +# can't silently drift apart. +_JOURNAL_CLOCK_WIDTH = 8 +_JOURNAL_KIND_WIDTH = 24 +_JOURNAL_COL_PAD = 1 # per-column right pad in the row grid -def journal_line(entry: dict[str, Any]) -> Text: + +def journal_line(entry: dict[str, Any]) -> Table: kind = str(entry.get("kind", "?")) style = next((s for sub, s in _JOURNAL_STYLES if sub in kind), "dim") ts = entry.get("ts") clock = "" if isinstance(ts, (int, float)): clock = time.strftime("%H:%M:%S", time.localtime(ts)) - text = Text() - text.append(f"{clock:8s} ", style="dim") - text.append(f"{kind:24s}", style=style) fields = " ".join( f"{k}={_short(v)}" for k, v in entry.items() if k not in _JOURNAL_HIDDEN_FIELDS ) - if fields: - text.append(" " + fields) - return text + # A grid per row so the fields cell folds within its own column (hanging + # indent) instead of wrapping back under the clock/kind columns. A long kind + # likewise folds within its own column rather than spilling into the fields. + grid = Table.grid(padding=(0, _JOURNAL_COL_PAD, 0, 0)) + grid.add_column(width=_JOURNAL_CLOCK_WIDTH) + grid.add_column(width=_JOURNAL_KIND_WIDTH, overflow="fold") + grid.add_column(overflow="fold") + grid.add_row(Text(clock, style="dim"), Text(kind, style=style), Text(fields)) + return grid class JournalEntryOption(Option): diff --git a/tests/test_tui_app.py b/tests/test_tui_app.py index 5fe7c63..c515a64 100644 --- a/tests/test_tui_app.py +++ b/tests/test_tui_app.py @@ -12,6 +12,7 @@ import pytest from conftest import install_bmad_config, write_sprint +from rich.console import Console from rich.text import Text from textual.geometry import Offset from textual.selection import Selection @@ -39,7 +40,15 @@ StartSweepModal, TextOutputModal, ) -from bmad_loop.tui.widgets import RunHeader, SelectableRichLog, SprintTree +from bmad_loop.tui.widgets import ( + _JOURNAL_CLOCK_WIDTH, + _JOURNAL_COL_PAD, + _JOURNAL_KIND_WIDTH, + RunHeader, + SelectableRichLog, + SprintTree, + journal_line, +) def make_run( @@ -270,7 +279,14 @@ async def test_token_weight_falls_back_to_default(project): def journal_rows(journal: OptionList) -> list[str]: - return [str(journal.get_option_at_index(i).prompt) for i in range(journal.option_count)] + # Journal prompts are Rich Table grids, so render them to plain text. + console = Console(width=400) + rows = [] + for i in range(journal.option_count): + with console.capture() as capture: + console.print(journal.get_option_at_index(i).prompt) + rows.append(capture.get()) + return rows def log_text(screen: DashboardScreen) -> str: @@ -296,6 +312,30 @@ def has_entry() -> bool: assert any("1-2-search" in row for row in journal_rows(journal)) +def test_journal_line_wraps_fields_with_hanging_indent(): + entry = { + "ts": 1_750_000_000, + "kind": "session-start", + "task_id": "6-1-sound-as-information-audio-layer-dev-1", + "role": "dev", + "prompt": "/bmad-dev-auto 6-1-sound-as-information-audio-layer", + } + console = Console(width=60) + with console.capture() as capture: + console.print(journal_line(entry)) + lines = capture.get().splitlines() + assert len(lines) > 1 # fields are long enough to wrap at width 60 + assert "session-start" in lines[0] + # continuation lines stay in the fields column, never spilling back under + # the clock/kind columns. The fields column's left edge is derived from the + # same width constants journal_line lays the grid out with. + indent = _JOURNAL_CLOCK_WIDTH + _JOURNAL_COL_PAD + _JOURNAL_KIND_WIDTH + _JOURNAL_COL_PAD + for line in lines[1:]: + assert line[:indent] == " " * indent + # and the wrapped fields carry real content past the indent + assert any(line[indent:].strip() for line in lines[1:]) + + async def test_log_pane_shows_emulated_content(project): from test_tui_data import ink_stream diff --git a/uv.lock b/uv.lock index bc0ecb1..908e843 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.11" [[package]] name = "bmad-loop" -version = "0.8.0" +version = "0.8.1" source = { editable = "." } dependencies = [ { name = "pyyaml" },