Skip to content

feat(cli): add stack command options and destruction - #6576

Merged
jgoux merged 8 commits into
developfrom
feat/stack-options-develop
Sep 11, 2026
Merged

feat(cli): add stack command options and destruction#6576
jgoux merged 8 commits into
developfrom
feat/stack-options-develop

Conversation

@jgoux

@jgoux jgoux commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Add service selection, bulk stopping, and explicit destruction to experimental local stacks directly on develop. The existing config-selected top-level start and stop aliases inherit the new options.

  • start --exclude / -x accepts comma-separated or repeated service names, preserves the project file, and records the effective configuration in stack state. Dependent services are also disabled: excluding REST or Analytics disables Studio.
  • stop --all preserves data and attempts every readable registered stack. It reports per-stack error details and stopped/failed/skipped counts after processing every readable stack, returning nonzero when any stack could not be verifiably stopped.
  • stack destroy permanently removes one selected stack after confirmation, with --yes for unattended execution.

This extracts the non-status work from the earlier PR. Status and credential-export changes are excluded because the new status command has not landed on develop.

Supersedes #6517

@jgoux
jgoux requested a review from a team as a code owner September 11, 2026 13:16
@jgoux jgoux self-assigned this Sep 11, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Superseded by a newer AI review

🤖 AI Review

Adjudicated 10 Claude findings and 1 Codex finding against the checked-out code. The major Codex finding is confirmed: excluding REST or Analytics while Studio remains enabled produces a configuration rejected by the stack compiler. Six lower-severity findings are also confirmed, chiefly around corrupt-registry recovery, duplicated routing knowledge, validation precedence, and error construction. Four Claude findings are refuted by concrete code or trusted documentation. No critical issues were found.

Findings

Severity Location Category Sources Claim
🟠 MAJOR apps/cli/src/commands/experimental/stack/start/start.handler.ts:104 correctness codex Excluding REST or Analytics while Studio remains enabled creates an invalid capability graph, causing otherwise documented --exclude invocations to fail during start.
🟡 MINOR apps/cli/src/commands/experimental/stack/stop/stop.handler.ts:104 error-handling claude Bulk stop permanently exits nonzero for each unreadable registry entry, while the CLI provides no command capable of removing such an entry.
⚪ NIT apps/cli/src/commands/experimental/stack/start/start.handler.ts:89 maintainability claude The CLI duplicates package-internal knowledge of which capabilities use the API listener even though the supervisor already disables listeners with no usable routes.
⚪ NIT apps/cli/src/commands/experimental/stack/start/start.options.ts:2 maintainability claude The CLI manually duplicates the package capability-name list, so newly added optional capabilities will remain unavailable to --exclude until this separate list is updated.
⚪ NIT apps/cli/src/commands/experimental/stack/start/start.handler.ts:141 validation-order claude Exclusion validation now masks the established legacy output-flag rejection when both inputs are invalid.
⚪ NIT apps/cli/src/commands/experimental/stack/stop/stop.handler.ts:105 error-handling claude Bulk stop concatenates every failure into one unbounded line and stores an untyped aggregate object as the error cause.
⚪ NIT apps/cli/src/commands/experimental/stack/destroy/destroy.handler.ts:19 consistency claude Destroy materializes suggestion: undefined instead of conditionally omitting the optional property like the sibling handlers.
Refuted findings (kept for transparency, not posted as review comments)
  • apps/cli/src/commands/experimental/stack/start/start.handler.ts:66 (compatibility): The stack-backed top-level start alias incompatibly rejects legacy service names accepted by legacy start.
    Refuted: Trusted apps/cli/docs/stack-commands.md:25-27 explicitly states that the selected backend determines accepted flags and that selecting the stack backend makes top-level start an alias of the unstable stack command. The trusted document also states at lines 3-5 that this interface is outside the compatibility promise. Different service vocabulary is therefore documented backend behavior, not a compatibility regression.
  • apps/cli/src/commands/experimental/stack/destroy/destroy.command.ts:22 (service-wiring): Destroy can reach promptYesNo's Stdin-dependent branch without providing stdinLayer, making piped confirmation fail with a missing service.
    Refuted: destroy.handler.ts:101-106 rejects non-TTY invocations unless yes is already true. With yes=true, prompt-yes-no.ts:39-41 returns before requesting Tty or Stdin; otherwise the guard guarantees text output on a TTY, which uses promptConfirm at lines 64-66. The Stdin branch is unreachable in the implemented command.
  • apps/cli/src/command-internal/db-bootstrap/shadow-cache.unit.test.ts:64 (test-configuration): A 30-second timeout was unnecessarily added to a pure SHA-256 test.
    Refuted: shadowCacheKey is not a simple SHA-256 operation: shadow-cache.ts:246 calls synchronous scryptSync. The test computes a base key and then recomputes it for 21 mutations, so the explicit timeout covers deliberately expensive password-hardening work.
  • apps/cli/src/commands/experimental/stack/destroy/destroy.integration.test.ts:78 (test-coverage): The destroy tests inherit ambient SUPABASE_YES, allowing that environment variable to invert confirmation assertions.
    Refuted: The cited helper does the opposite of the claim: mocks.ts:651-663 deletes every current environment variable before applying the supplied map. processEnvLayer({}) therefore clears SUPABASE_YES for each test and restores the environment afterward. Command-specific environment cases are absent, but the asserted ambient-environment flakiness does not exist.

Stats

Claude findings: 10 · Codex findings: 1 · Confirmed: 7 · Refuted: 4 · Uncertain: 0


Models: claude-opus-5 + gpt-5.6-sol · Trigger: auto · Workflow run

This review runs once per PR. A maintainer can request another with a /ai-review comment.

Comment thread apps/cli/src/commands/experimental/stack/stop/stop.handler.ts
Comment thread apps/cli/src/commands/experimental/stack/start/start.handler.ts Outdated
Comment thread apps/cli/src/commands/experimental/stack/start/start.options.ts Outdated
Comment thread apps/cli/src/commands/experimental/stack/start/start.handler.ts Outdated
Comment thread apps/cli/src/commands/experimental/stack/stop/stop.handler.ts Outdated
Comment thread apps/cli/src/commands/experimental/stack/destroy/destroy.handler.ts
Comment thread apps/cli/src/commands/experimental/stack/start/start.handler.ts Outdated
@jgoux

jgoux commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

/ai-review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 AI Review

Both reviews completed. All nine deduplicated findings were verified: five minor correctness concerns and four nits; no major or critical defects were found.

Findings

Severity Location Category Sources Claim
🟡 MINOR apps/cli/src/commands/experimental/stack/destroy/destroy.errors.ts:17 telemetry claude Declining the destroy confirmation is classified as actionable invalid input instead of user cancellation.
🟡 MINOR apps/cli/src/commands/experimental/stack/destroy/destroy.handler.ts:34 error-classification codex Container-engine and runtime-mismatch errors handled by the destroy command fall through to the unknown classification.
🟡 MINOR apps/cli/src/commands/experimental/stack/stop/stop.handler.ts:94 error-classification claude+codex Bulk stop replaces every per-stack failure classification and suggestion with reason lifecycle, producing misleading invalid-config telemetry.
🟡 MINOR apps/cli/src/commands/experimental/stack/stop/stop.command.ts:8 cli-compatibility claude An explicit --all=false loses presence information, allowing it alongside --stack or --stack-id unlike the legacy top-level stop command.
🟡 MINOR apps/cli/src/commands/experimental/stack/destroy/destroy.handler.ts:101 user-experience claude Destroy may open a hidden interactive prompt when stdin is a TTY but stdout is redirected.
⚪ NIT apps/cli/src/commands/experimental/stack/stop/stop.handler.ts:87 user-experience claude Bulk-stop skip messages repeat the stack ID.
⚪ NIT apps/cli/src/commands/experimental/stack/destroy/destroy.integration.test.ts:127 test-coverage claude Destroy tests omit the interactive acceptance path and rejection of the legacy -o/--output flag.
⚪ NIT apps/cli/src/commands/experimental/stack/stop/SIDE_EFFECTS.md:25 documentation claude The compatibility contract does not document bulk stop's machine-readable success payload.
⚪ NIT apps/cli/src/command-internal/db-bootstrap/shadow-cache.unit.test.ts:64 maintainability claude An unrelated pure hashing test receives a 30-second timeout without any rationale.

Stats

Claude findings: 8 · Codex findings: 2 · Confirmed: 9 · Refuted: 0 · Uncertain: 0


Models: claude-opus-5 + gpt-5.6-sol · Trigger: manual · Workflow run

This review runs once per PR. A maintainer can request another with a /ai-review comment.

Comment thread apps/cli/src/commands/experimental/stack/destroy/destroy.errors.ts
Comment thread apps/cli/src/commands/experimental/stack/destroy/destroy.handler.ts Outdated
Comment thread apps/cli/src/commands/experimental/stack/stop/stop.handler.ts
Comment thread apps/cli/src/commands/experimental/stack/stop/stop.command.ts
Comment thread apps/cli/src/commands/experimental/stack/stop/stop.handler.ts Outdated
Comment thread apps/cli/src/commands/experimental/stack/destroy/destroy.handler.ts Outdated
Comment thread apps/cli/src/commands/experimental/stack/stop/SIDE_EFFECTS.md Outdated
…-develop

# Conflicts:
#	packages/stack/src/public/EffectStack.ts
#	packages/stack/src/runtime/NativeProcess.ts
#	packages/stack/src/runtime/native-runtime.integration.test.ts
#	packages/stack/src/supervisor/handles.integration.test.ts
@jgoux
jgoux added this pull request to the merge queue Sep 11, 2026
Merged via the queue into develop with commit 166e3fa Sep 11, 2026
21 checks passed
@jgoux
jgoux deleted the feat/stack-options-develop branch September 11, 2026 17:04
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.

2 participants