Skip to content

FE-878: Brunch serve — one-shot plan-then-cook capstone#222

Open
kostandinang wants to merge 13 commits into
ka/fe-877-brownfield-promotionfrom
ka/fe-878-brunch-serve
Open

FE-878: Brunch serve — one-shot plan-then-cook capstone#222
kostandinang wants to merge 13 commits into
ka/fe-877-brownfield-promotionfrom
ka/fe-878-brunch-serve

Conversation

@kostandinang

@kostandinang kostandinang commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Stacks on FE-877. The Arc-1 capstone -- one shot from a completed spec to a promoted cook result, no manual steps (closes Arc 1) -- plus the CLI presentation seam the cook/plan/serve surfaces now render through.

What?

Serve capstone. brunch serve <specId> = brunch plan <specId> then brunch cook --spec=<specId>.

  • Sequencer (runServe, serve-runner.ts): emit the plan, then cook it. Cook reads the plan just emitted (--spec=<id>), not an auto-picked older one. A failed plan short-circuits -- nothing is cooked.
  • Arg/flag mapping (parseServeArgs / serveCookOptions): serve's --out is the greenfield promote target -> cook (brownfield auto-promotes via FE-877 regardless); --profile stamps the plan; petrinaut / --policy / --max-retries forward to cook; --verbose to both. Launch cwd is threaded into cook's stage.
  • cli.ts serve branch reuses the existing plan db/snapshot wiring (spec existence + completeness), then hands the two stages to runServe. A shared completed-spec gate is extracted for plan + serve.

Presentation seam. Plan and cook output migrate off ad-hoc console.error onto an event-driven presenter (presenter/).

  • selectPresenter(command, isTTY, ci, --reporter) picks the renderer: ink (interactive full-screen TUI), plain (line-oriented for CI / non-TTY / piped), silent (keeps stdout clean for the agent JSONL protocol).
  • Ink TUI: egg logo + brigade tracker + live waiting-state (pending panel + wait brackets). An event bus owns its own lifecycle so the TUI tears down cleanly.

Why?

The Arc-1 chain (detect -> plan -> cook -> verify -> promote) was already built across FE-867..877; serve is the no-manual-steps entry point -- pure glue, the heavy side effects already live in runPlan/runCook, and the two stages are injected so sequencing + flag mapping stay unit-testable. The presenter seam replaces scattered stdout writes with one testable decision (renderer choice is pure) so plan/cook/serve share consistent output and CI vs TTY vs agent each get the right surface.

Command surface

serve is one of the three real commands -- brunch plan, brunch cook, brunch serve. The kitchen-brigade names (prep / recipe / taste / plate) are phase labels, not commands: detect runs inside plan; verify (probe + oracle) and promotion run inside cook. serve chains those phases end to end -- no new verbs beyond itself.

Tests

parseServeArgs / serveCookOptions / runServe (plans-then-cooks, fresh-plan read, --out mapping, failing plan never cooks); selectPresenter env matrix; plain + Ink presenter rendering; bus lifecycle teardown; golden tests pinning the cook banner + summary strings. Includes a SPEC reconcile of Arc-1 invariant drift.

Co-authored-by: Amp amp@ampcode.com

@kostandinang kostandinang force-pushed the ka/fe-877-brownfield-promotion branch from e9a6f5e to cd5ef22 Compare June 16, 2026 12:49
@kostandinang kostandinang force-pushed the ka/fe-878-brunch-serve branch from 593bf7f to c4101d7 Compare June 16, 2026 12:49
@kostandinang kostandinang force-pushed the ka/fe-877-brownfield-promotion branch from cd5ef22 to e7a2007 Compare June 16, 2026 12:53
@kostandinang kostandinang force-pushed the ka/fe-878-brunch-serve branch 2 times, most recently from dabcac5 to d8f61cd Compare June 16, 2026 13:24
@kostandinang kostandinang force-pushed the ka/fe-877-brownfield-promotion branch from e7a2007 to b59e71f Compare June 16, 2026 13:24
@kostandinang kostandinang force-pushed the ka/fe-878-brunch-serve branch from d8f61cd to 7c7bfdf Compare June 16, 2026 13:38
@kostandinang kostandinang force-pushed the ka/fe-877-brownfield-promotion branch from b59e71f to 58d7775 Compare June 16, 2026 13:38
@kostandinang kostandinang marked this pull request as ready for review June 16, 2026 14:18
@cursor

cursor Bot commented Jun 16, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes primary CLI entry points and all stderr UX, but plain output is byte-identical under tests and serve is thin glue over existing plan/cook orchestration.

Overview
Arc-1 capstone: new brunch serve <specId> runs plan then cook --spec=<id> via injectable runServe / serveCookOptions — a failed plan never cooks; --out, profile, and cook flags forward; launch cwd is threaded into cook because runCook reads opts.dir raw. cli.ts adds a shared withCompletedSpec gate for plan and serve.

Presentation seam (I136-K): plan, cook, and pi-actions emit **CookEvent**s on a CookBus instead of direct console.error. selectPresenter picks plain (CI/non-TTY), ink (brigade tracker + pending spinner), or silent (agent). withCookBus always disposes (unmounts Ink). Cook banner/summary strings move to cook-report.ts for golden tests; long waits use activity-start/progress/end (including promotion in cook-cli).

Adds ink / ink-testing-library; memory/PLAN.md and memory/SPEC.md record FE-878 landing and the presentation invariant.

Reviewed by Cursor Bugbot for commit 89e7850. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread src/server/serve-runner.ts Outdated
Comment thread src/server/serve-runner.ts
@kostandinang kostandinang force-pushed the ka/fe-877-brownfield-promotion branch from 58d7775 to d8ee639 Compare June 16, 2026 18:05
@kostandinang kostandinang force-pushed the ka/fe-878-brunch-serve branch from 90bb5ef to 40a9d88 Compare June 16, 2026 18:05
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

Dependency Review

The following issues were found:
  • ❌ 1 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 1 package(s) with unknown licenses.
  • ⚠️ 3 packages with OpenSSF Scorecard issues.
See the Details below.

Vulnerabilities

package-lock.json

NameVersionVulnerabilitySeverityPatched Version
ws8.20.0ws: Memory exhaustion DoS from tiny fragments and data chunkshigh8.21.0
ws: Uninitialized memory disclosuremoderate8.20.1

License Issues

package-lock.json

PackageVersionLicenseIssue Type
slice-ansi9.0.0NullUnknown License

OpenSSF Scorecard

Scorecard details
PackageVersionScoreDetails
npm/ws 8.20.0 🟢 5.5
Details
CheckScoreReason
Code-Review⚠️ 0Found 1/29 approved changesets -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 1014 commit(s) and 4 issue activity found in the last 90 days -- score normalized to 10
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Binary-Artifacts🟢 10no binaries found in the repo
Security-Policy🟢 10security policy file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/@alcalzone/ansi-tokenize 0.3.0 UnknownUnknown
npm/ansi-escapes 7.3.0 🟢 3.7
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review⚠️ 2Found 7/30 approved changesets -- score normalized to 2
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Packaging⚠️ -1packaging workflow not detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/ansi-regex 6.2.2 🟢 3.8
Details
CheckScoreReason
Code-Review🟢 3Found 9/30 approved changesets -- score normalized to 3
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Security-Policy🟢 10security policy file detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/ansi-styles 6.2.3 🟢 3.9
Details
CheckScoreReason
Packaging⚠️ -1packaging workflow not detected
Code-Review🟢 4Found 13/30 approved changesets -- score normalized to 4
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Security-Policy🟢 10security policy file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/auto-bind 5.0.1 🟢 3.6
Details
CheckScoreReason
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Code-Review⚠️ 1Found 5/30 approved changesets -- score normalized to 1
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Security-Policy🟢 10security policy file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/cli-boxes 4.0.1 🟢 3.8
Details
CheckScoreReason
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 3Found 8/23 approved changesets -- score normalized to 3
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Security-Policy🟢 10security policy file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/cli-cursor 4.0.0 🟢 3.6
Details
CheckScoreReason
Code-Review⚠️ 1Found 5/30 approved changesets -- score normalized to 1
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Security-Policy🟢 10security policy file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/cli-truncate 6.0.0 🟢 3.8
Details
CheckScoreReason
Code-Review⚠️ 2Found 7/30 approved changesets -- score normalized to 2
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained⚠️ 12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Security-Policy🟢 10security policy file detected
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/code-excerpt 4.0.0 ⚠️ 2.8
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Packaging⚠️ -1packaging workflow not detected
Code-Review⚠️ 0Found 1/29 approved changesets -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Security-Policy⚠️ 0security policy file not detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/convert-to-spaces 2.0.1 ⚠️ 2.8
Details
CheckScoreReason
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Code-Review⚠️ 0Found 0/10 approved changesets -- score normalized to 0
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Packaging⚠️ -1packaging workflow not detected
SAST⚠️ 0no SAST tool detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Security-Policy⚠️ 0security policy file not detected
npm/environment 1.1.0 UnknownUnknown
npm/es-toolkit 1.47.1 🟢 7.9
Details
CheckScoreReason
Dependency-Update-Tool🟢 10update tool detected
Security-Policy🟢 10security policy file detected
Code-Review🟢 8Found 22/26 approved changesets -- score normalized to 8
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Maintained🟢 1030 commit(s) and 11 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Pinned-Dependencies🟢 10all dependencies are pinned
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
SAST🟢 9SAST tool detected but not run on all commits
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
Packaging🟢 10packaging workflow detected
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
License🟢 10license file detected
Fuzzing🟢 10project is fuzzed
Vulnerabilities⚠️ 28 existing vulnerabilities detected
CI-Tests🟢 1027 out of 27 merged PRs checked by a CI test -- score normalized to 10
Contributors🟢 10project has 59 contributing companies or organizations
npm/escape-string-regexp 2.0.0 🟢 3.7
Details
CheckScoreReason
Code-Review⚠️ 2Found 6/30 approved changesets -- score normalized to 2
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/indent-string 5.0.0 🟢 3.7
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Code-Review⚠️ 2Found 8/30 approved changesets -- score normalized to 2
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/ink 7.0.6 🟢 4.2
Details
CheckScoreReason
Code-Review🟢 4Found 12/30 approved changesets -- score normalized to 4
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Maintained🟢 1030 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Security-Policy⚠️ 0security policy file not detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/ink-testing-library 4.0.0 🟢 3
Details
CheckScoreReason
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Code-Review⚠️ 2Found 6/28 approved changesets -- score normalized to 2
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Security-Policy⚠️ 0security policy file not detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/is-fullwidth-code-point 5.1.0 🟢 3.8
Details
CheckScoreReason
Code-Review🟢 3Found 9/26 approved changesets -- score normalized to 3
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Security-Policy🟢 10security policy file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/is-in-ci 2.0.0 UnknownUnknown
npm/mimic-fn 2.1.0 UnknownUnknown
npm/onetime 5.1.2 🟢 3.7
Details
CheckScoreReason
Code-Review⚠️ 2Found 8/30 approved changesets -- score normalized to 2
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/patch-console 2.0.0 ⚠️ 2.8
Details
CheckScoreReason
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review⚠️ 0Found 0/11 approved changesets -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
SAST⚠️ 0no SAST tool detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Security-Policy⚠️ 0security policy file not detected
npm/react-reconciler 0.33.0 UnknownUnknown
npm/restore-cursor 4.0.0 🟢 3.7
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Code-Review⚠️ 2Found 5/23 approved changesets -- score normalized to 2
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Security-Policy🟢 10security policy file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/slice-ansi 9.0.0 🟢 4
Details
CheckScoreReason
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review⚠️ 2Found 6/30 approved changesets -- score normalized to 2
Maintained🟢 33 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 3
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Security-Policy🟢 10security policy file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/stack-utils 2.0.6 🟢 3.4
Details
CheckScoreReason
Code-Review⚠️ 0Found 1/30 approved changesets -- score normalized to 0
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Security-Policy🟢 10security policy file detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/string-width 8.2.1 🟢 3.9
Details
CheckScoreReason
Code-Review🟢 3Found 9/30 approved changesets -- score normalized to 3
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained⚠️ 12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Security-Policy🟢 10security policy file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/strip-ansi 7.2.0 🟢 3.7
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Code-Review⚠️ 2Found 6/30 approved changesets -- score normalized to 2
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/tagged-tag 1.0.0 UnknownUnknown
npm/terminal-size 4.0.1 UnknownUnknown
npm/type-fest 5.5.0 🟢 5.3
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 15 issue activity found in the last 90 days -- score normalized to 10
Packaging⚠️ -1packaging workflow not detected
Code-Review🟢 8Found 25/30 approved changesets -- score normalized to 8
Security-Policy🟢 10security policy file detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/widest-line 6.0.0 🟢 3.7
Details
CheckScoreReason
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Packaging⚠️ -1packaging workflow not detected
Code-Review⚠️ 2Found 6/26 approved changesets -- score normalized to 2
Security-Policy🟢 10security policy file detected
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/wrap-ansi 10.0.0 🟢 3.7
Details
CheckScoreReason
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review⚠️ 2Found 7/30 approved changesets -- score normalized to 2
Security-Policy🟢 10security policy file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Signed-Releases⚠️ -1no releases found
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
npm/yoga-layout 3.2.1 🟢 5.5
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 9Found 28/30 approved changesets -- score normalized to 9
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
Packaging⚠️ -1packaging workflow not detected
SAST⚠️ 0no SAST tool detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Binary-Artifacts🟢 8binaries present in source code
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Branch-Protection🟢 3branch protection is not maximal on development and all release branches
Fuzzing🟢 10project is fuzzed

Scanned Files

  • package-lock.json

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 40a9d88. Configure here.

Comment thread src/orchestrator/src/cook-cli.ts
@kostandinang kostandinang force-pushed the ka/fe-877-brownfield-promotion branch from d8ee639 to a0ebbda Compare June 16, 2026 23:45
@kostandinang kostandinang force-pushed the ka/fe-878-brunch-serve branch from 40a9d88 to 05b471a Compare June 16, 2026 23:45
kostandinang and others added 12 commits June 17, 2026 00:51
runCook reads opts.dir raw — the launch-cwd default lives only in
parseCookArgs, which serve bypasses. With dir:'' cook resolved the
just-emitted plan path against process.cwd() and would clone '' for
brownfield, so serve only worked when greenfield and
process.cwd()===launchCwd===project root.

serveCookOptions/runServe now take the resolved cook dir; cli passes
launchCwd (the same dir plan writes the plan to). Corrects the stale
test that asserted cook.dir===''.

Amp-Thread-ID: https://ampcode.com/threads/T-019ecb9a-9a08-733b-833d-76885fc8243a
Co-authored-by: Amp <amp@ampcode.com>
- I126-K: name the shared runVerification seam (FE-872); evaluateVerificationTargets is deleted
- decision 166: brownfield promotion is no longer a follow-on — landed as decision 168 (FE-877)
- decision 168 (new): brownfield auto-promotion (plumbing-only) + brunch serve capstone (FE-877/878)
- I128-K: --out is greenfield-only (brownfield auto-promotes)
- I135-K (new): brownfield promotion never touches the user's checkout

Amp-Thread-ID: https://ampcode.com/threads/T-019ecb9a-9a08-733b-833d-76885fc8243a
Co-authored-by: Amp <amp@ampcode.com>
The serve and plan branches duplicated the spec gate verbatim
(resolveBrunchProject -> createDb -> existence check -> snapshot ->
completeness assert -> db close + uniform error). withCompletedSpec now
owns it; parsing is a thunk so parse errors report through the same
'Failed to run brunch <command>' channel. Pure refactor — cli.test.ts
green.

Amp-Thread-ID: https://ampcode.com/threads/T-019ecb9a-9a08-733b-833d-76885fc8243a
Co-authored-by: Amp <amp@ampcode.com>
Introduces a single emit(CookEvent) presentation boundary so terminal
output stops being smeared across console.error/log() in the orchestrator
CLI. Foundation: presenter.ts root + presenter/{events,bus,select,plain,
silent}.ts.

- selectPresenter(command,isTTY,ci,reporterFlag): pure decision table →
  plain (CI/non-TTY/default) | silent (agent, keeps stdout JSONL-clean) |
  ink (interactive TTY; falls back to plain until slice 2).
- CookBus: synchronous fan-out; a thrown presenter is downgraded to a
  process warning so presentation can never abort a run.
- PlainPresenter: CookEvent → stderr, byte-exact for the plan arms; sink
  injectable for the golden differential.
- plan-runner migrated to emit CookEvents; cli.ts plan/serve wired through
  createCookBus. cook left untouched (still behavior-preserving).

Oracle per SPEC I136-K: plan-runner.test.ts now drives a capturing bus and
asserts the same stderr; npm run verify green.

Slice 1b (cook surface + injected-clock elapsed timer) queued in
memory/CARDS.md.

Co-Authored-By: Claude <noreply@anthropic.com>
Routes cook/serve terminal output through the emit(CookEvent) boundary,
completing the seam across all three commands.

- cook-cli: banner / completion summary / promotion / petrinaut blocks and
  the early-exit diagnostics now emit {kind:'line'} through the bus; the
  petrinaut-setup log is bus-backed. runCook takes a bus (defaults to
  createCookBus('cook')); serve shares one bus across plan+cook.
- pi-actions: per-action log()/logVerbose() become structured action/
  verbose CookEvents; the module is now console-free. The module-level
  Date.now() elapsed timer is gone — the presenter owns it.
- PlainPresenter: gains an injected clock (I136-K). A cook-start event
  seeds runStart; the elapsed prefix is computed at render time, so the
  cook surface now has a deterministic byte-exact golden.

Verified: presenter goldens (plan + cook arms incl. fake clock),
brownfield-smoke runs cook end-to-end through the bus, npm run verify green.
ink still falls back to plain — that's slice 2.

Co-Authored-By: Claude <noreply@anthropic.com>
Makes the `ink` backend real (it no longer falls back to plain on a TTY).

- format.ts + clock.ts: line formatting + the elapsed clock extracted from
  PlainPresenter so the plain and Ink backends share one formatter and can't
  drift. PlainPresenter is now a thin sink over formatCookEvent.
- phase.ts: nextPhase — a pure, monotonic brigade tracker
  (prep→recipe→cook→taste→plate→serve) projected from the event stream.
  Coarse for now (post-hoc events); precise in-flight transitions are 2b.
- run-store.ts: folds CookEvents into { phase, lines } with a stable
  snapshot for useSyncExternalStore.
- ink/: egg-logo.ts (ANSI mark), app.tsx (egg header + brigade strip +
  bounded activity log), ink-presenter.tsx (renders to STDERR; stdout stays
  reserved). makePresenter('ink') now returns InkPresenter.

Adds ink@^7 + ink-testing-library@^4 (React 19.2 satisfies the peer dep).
Verified: phase/run-store units, ink-testing-library frame (egg + active
phase + activity line), non-TTY path still plain (brownfield-smoke), full
build bundles the tsx. Real-terminal walkthrough is outer-loop debt; the
dead-air waiting fix is slice 2b.

Co-Authored-By: Claude <noreply@anthropic.com>
Closes the dead-air problem: long waits now show what brunch is doing.

- events: activity-start / activity-progress / activity-end.
- pi-actions: runPi self-brackets every agent session (start → finally end)
  with a throttled KB heartbeat off its token stream; the test-run and probe
  waits bracket via a small withActivity helper. All close in finally, so a
  spinner can't hang — covered by a test that fails the session mid-wait.
- cook-cli: promotion brackets via a `promoting` helper.
- run-store: a pending map (start adds, progress updates detail, end removes);
  activity events stay out of the scrolling log.
- ink: PendingPanel renders a live spinner + label + elapsed + detail, with a
  tick interval that runs only while something is pending. Plain/CI prints one
  `⋯` start line per wait.

Known limit: test-runner uses blocking spawnSync, so the spinner freezes (but
stays labeled) during a test run; the async pi session animates. Real-terminal
walkthrough is outer-loop debt.

Verified: run-store pending units, ink frame (panel shows/clears), balanced
brackets incl. on session failure, npm run verify green.

Co-Authored-By: Claude <noreply@anthropic.com>
ln-review caught that nothing ever called bus.dispose() — harmless for
plain/silent, but on a real TTY the Ink app was never unmounted, so
`brunch cook`/`serve` would hang after the run.

- withCookBus(command, fn): builds the bus, runs the work, and disposes it
  (→ unmounts Ink) in finally. One owner, no split ownership.
- runCook takes a required bus (drops the in-cook createCookBus default).
- cli.ts cook/plan/serve paths run through withCookBus; serve's single
  shared bus is disposed once after the cook stage.

Verified: withCookBus disposes on success and on throw (spy); CookBus.dispose
fan-out test stands; npm run verify green. Remaining real-terminal debt is now
purely visual.

Co-Authored-By: Claude <noreply@anthropic.com>
)

The cook banner/summary text had no oracle (the migration preserved it
verbatim but nothing guarded against drift). Extract cookBannerLines /
cookSummaryLines as pure functions and golden-test them; runCook feeds their
output to the bus. Covers completed + halted runs incl. the epic/slice tree.

npm run verify green.

Co-Authored-By: Claude <noreply@anthropic.com>
…arks

Per feedback: drop the egg, use the "brunch" wordmark tinted with the
brunch.ai brand gradient (HASH blue→indigo→violet, one hex per letter), and
keep the brigade/status glyphs as the original monochrome marks (✓ ◐ ○)
rather than emoji. egg-logo.ts → wordmark.ts. Plain/CI backend stays
untinted. Ink frame tests updated.

Co-Authored-By: Claude <noreply@anthropic.com>
The panel re-rendered every 120ms recomputing toFixed(1) elapsed, so the
number jittered at the decimal. Add formatElapsed (whole seconds under a
minute, m:ss above), use it in the panel, and slow the spinner tick to 250ms.
The static action-log prefix (a fixed record) keeps its one-decimal form.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@kostandinang kostandinang force-pushed the ka/fe-878-brunch-serve branch from 05b471a to 89e7850 Compare June 16, 2026 23:55
@kostandinang kostandinang force-pushed the ka/fe-877-brownfield-promotion branch from a0ebbda to 17ae900 Compare June 16, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant