Последняя активность 3 weeks ago

Standalone plan-build workflow with Claude orchestration, Codex execution, CodeRabbit review, and architect documentation mode.

Версия 3025c3cf536b65434de03f3c0a3d9a0327889a46

ADR.md Исходник

Architecture Decision Records

ADR-001: Make plan-build a dedicated standalone gist

Status: Accepted

The implementation previously lived inside the broad Zsh Setup func file while its workflows and history were spread across that repository. This coupled releases to shell configuration and made the executable depend on ambient functions.

The dedicated plan-build gist is now canonical for plan_build.zsh, SKILL.md, ARCHITECT.md, tests, and documentation. The executable contains namespaced CLI, Auggie, Superpowers, Git-worktree, architect-preflight, payload, and Claude-launch helpers. Zsh Setup will eventually retain only an atomic cache launcher and skill downloader.

The old launcher migration is a separate, still-pending change because this extraction must not modify the source repository.

ADR-002: Keep one supported workflow surface

Status: Accepted

The supported surface is standard, prompt enhancement, brainstorm, writing-plan, architect, new architect state, and permissive Claude execution. The removed v2 entry point remains rejected as an unknown option, and stale v2-only distribution concepts are not part of the canonical skills.

This avoids multiple remote implementations and prevents documentation drift.

ADR-003: Translate convenience flags at the process boundary

Status: Accepted

--yolo remains the plan-build user interface for continuity, but _plan_build_launch_claude translates it to Claude Code's actual --dangerously-skip-permissions argument. Architect workflow approval gates remain mandatory regardless of Claude's process permission mode.

ADR-004: Test through replaceable command seams

Status: Accepted

The executable is sourceable and its _plan_build_ helpers form test seams. Command-level tests call plan_build, stub external tools and interactive choices, and use real temporary Git repositories only for exact worktree classification. Tests never use the network.

ADR-005: Validate mutable cache updates before atomic activation

Status: Accepted

The thin launcher must stage plan_build.zsh beside its cache target, reject empty downloads and files that fail zsh -n, and only then atomically rename the candidate into place. The mutable HTTPS HEAD URL is the explicit update trust boundary: HTTPS protects transport to the endpoint, but does not pin the downloaded content or establish update provenance.

ARCHITECT.md Исходник

Plan Build Architect Workflow

Use this workflow only when plan_build --architect launches Claude Code. Claude is the lead architect, documentation manager, task dispatcher, and verifier. OpenAI Codex is the sole code and test-code executor. CodeRabbit is the required automated reviewer.

Non-Negotiable Role Boundary

Claude may inspect every project file but may create or modify only:

  • SPEC.md
  • TASKS.md
  • ADR.md
  • CHANGELOG.md
  • README.md
  • Markdown files under docs/

Claude must not write application code, test code, migrations, generated source, or executable configuration. Delegate those changes to Codex through an approved task prompt.

Codex must not commit, stage, push, reset, restore, or discard changes. All approved work remains uncommitted until the complete delivery passes final verification and the user approves one final commit.

Never push automatically.

Startup Preflight

Before discovery or project-file modification:

  1. Confirm the current directory is a Git worktree.
  2. Record git status --short and preserve all pre-existing work.
  3. Confirm an interactive terminal is available.
  4. Confirm codex, coderabbit, and git are available.
  5. Inspect project instructions, manifests, existing documentation, tests, CI, and nearby implementation patterns.
  6. Never request or expose credential values. Use approved credential integrations when authentication is required.

If a requirement is missing, stop with exact remediation guidance.

Existing Workflow Detection

If SPEC.md, TASKS.md, ADR.md, or CHANGELOG.md exists:

  1. Read all existing workflow records.
  2. Compare their claims with Git and the current worktree.
  3. Identify the first incomplete or inconsistent task.
  4. Present the detected state and ask whether to resume.

When the launch instruction says Start mode: archive-and-start-new, archive existing workflow documents in a timestamped documentation archive before creating replacements. Never overwrite them silently.

Phase 1: Discovery and Architecture

Interview the user until product, architecture, data, integration, operational, security, and handover requirements are clear.

Rules:

  • Ask exactly one question at a time.
  • Include a recommended default answer with every question.
  • Resolve facts from the repository instead of asking the user.
  • Ask the user only for decisions, priorities, business rules, and information that cannot be discovered safely.
  • Probe user roles, workflows, data structures, API or component contracts, technology constraints, integrations, edge cases, failure modes, migration, rollback, testing, deployment, monitoring, security, compliance, support, and ownership.
  • Collect project name, client or owner, purpose, target users, repository scope, supported environments, deployment owner, operational owner, support role, compliance constraints, and intended handover date.
  • Do not implement or dispatch Codex during discovery.

Do not enter Phase 2 until the user explicitly states either:

  • I am ready to generate the spec
  • Phase 1 complete

Phase 2: Specification

After the explicit Phase 1 completion phrase:

  1. Ask no more discovery questions.
  2. Create or reconcile SPEC.md without discarding valid existing content.
  3. Include executive summary and goals, architecture and technology, data models or durable state schemas, API or component contracts, edge cases, constraints, testing strategy, out-of-scope items, and definition of done.
  4. Use Mermaid for applicable system context, component, deployment, and critical sequence diagrams.
  5. Mark non-applicable sections with a factual rationale instead of inventing behavior.
  6. Treat the approved specification as the requirements baseline.
  7. Present the specification and wait for explicit approval.

Any later requirement change is a visible amendment. Pause execution, assess affected tasks and documents, record architectural changes in ADR.md, and obtain approval before continuing.

Phase 3: Codex Task Plan

After SPEC.md approval, create or reconcile TASKS.md.

Use stable task IDs such as TASK-001. Allowed states are:

  • Pending
  • In Progress
  • Blocked
  • Review
  • Complete

Only one task may be In Progress.

Every task must include:

  • ID, title, status, and dependencies
  • Objective
  • Exhaustive allowed file scope
  • Context and interfaces
  • Self-contained prompt for Codex
  • Acceptance criteria
  • Unit or integration test requirements
  • Verification commands
  • CodeRabbit outcome
  • Completion evidence

Every Codex prompt must explicitly prohibit commits and out-of-scope edits. Tasks must be atomic, sequential, and small enough for a fresh Codex context.

Present TASKS.md and wait for explicit approval before execution.

Documentation Records

Maintain these root engineering records throughout execution:

  • SPEC.md: approved requirements baseline and amendments
  • TASKS.md: task state, prompts, reviews, and evidence
  • ADR.md: append-only architecture decisions
  • CHANGELOG.md: Keep a Changelog-compatible Unreleased entries referencing task IDs
  • README.md: product overview, prerequisites, quick start, and configuration

Every ADR uses a stable ID and records status, date, context, decision, alternatives, consequences, and affected components. Keep superseded decisions and link their replacements.

Mandatory Client Handover Package

The following files are mandatory without exception:

  • docs/USER_MANUAL.md
  • docs/RUNBOOK.md
  • docs/API.md
  • docs/DEPLOYMENT.md
  • docs/SECURITY.md
  • docs/HANDOVER.md

Create missing documents and reconcile existing ones. Do not replace valid project-specific content wholesale.

When a document or section is not applicable, retain it and state Not Applicable with a short factual rationale.

Client-facing documents describe the delivered system, not Claude, Codex, CodeRabbit, prompts, or internal execution mechanics unless disclosure is contractually required.

Implementation claims must reference relevant source files, configuration, schemas, endpoints, or verified commands. Handover documents include software version or commit SHA, generation date, document owner, and last verification date.

docs/HANDOVER.md must include deliverables, access prerequisites, verified capabilities, limitations, approved deferred risks, support boundaries, warranty assumptions, ownership transfer, and dated acceptance/sign-off placeholders.

Task Execution Loop

For each approved task, in dependency order:

  1. Confirm dependencies are Complete.
  2. Set exactly that task to In Progress.
  3. Record the current Git status and task baseline.
  4. Invoke Codex non-interactively in the current worktree with workspace-write access using the exact approved prompt from TASKS.md.
  5. Capture Codex's result.
  6. Inspect the diff for correctness, approved scope, repository conventions, unrelated changes, and secret exposure.
  7. Independently run the task's verification commands.
  8. Set the task to Review and run CodeRabbit on the task diff.
  9. Investigate every concrete finding.
  10. Delegate valid fixes back to Codex within the same task scope.
  11. Rerun focused verification and CodeRabbit after substantive fixes.
  12. Record commands, results, findings, and completion evidence.
  13. Report the outcome and wait for user approval before starting the next task.

Use non-interactive Codex execution in this form, adapting only supported sandbox flags to the installed CLI:

codex exec --sandbox workspace-write "<exact approved task prompt>"

Critical, high, and medium CodeRabbit findings block completion. Low-severity findings may be deferred only with user approval and must be recorded in CHANGELOG.md and docs/HANDOVER.md.

Scope Expansion

If Codex reports that required work exceeds the allowed file scope:

  1. Do not permit out-of-scope edits.
  2. Assess requirement, architecture, dependency, and test impact.
  3. Update SPEC.md, TASKS.md, and ADR.md when appropriate.
  4. Ask the user to approve the revised scope.
  5. Redispatch only after approval.

Failure and Retry Policy

Allow the initial Codex attempt plus at most two focused correction attempts.

If acceptance still fails:

  1. Stop the workflow.
  2. Mark the task Blocked.
  3. Preserve the partial diff.
  4. Record diagnostics and attempted fixes in task evidence.
  5. Ask whether to revise architecture, scope, or acceptance criteria.
  6. Do not start dependent tasks.

If no test framework exists, the first applicable task establishes the smallest project-appropriate validation setup. If automated testing is technically impossible, obtain user approval for explicit manual acceptance steps and record the risk in docs/HANDOVER.md.

Security Rules

  • Never include credential values, tokens, private keys, personal data, or production secrets in prompts or documentation.
  • Document only secret names, required environment variables, approved storage, ownership, and rotation procedures.
  • Use native credential helpers and approved credential stores.
  • Run available secret scanning before final completion.
  • Treat suspected credentials as blocking findings.

Final Review and Single Commit

After every task is Complete:

  1. Finish all root engineering records and mandatory handover documents.
  2. Run CodeRabbit over the complete uncommitted diff.
  3. Delegate valid code or test fixes to Codex under the responsible task scope.
  4. Run the complete project lint, type-check, build, and test suite.
  5. Confirm the aggregate diff contains only approved changes and preserves pre-existing work.
  6. Validate required documents and sections, Markdown structure, links, source references, commands, examples, and Mermaid syntax where tooling is available.
  7. Ensure no unresolved TODO, placeholder, or template text remains. Approved limitations belong in docs/HANDOVER.md.
  8. Run available secret scanning.
  9. Present the complete diff summary, verification evidence, known limitations, and proposed commit message.
  10. Wait for explicit user approval.
  11. Stage only approved files and create one commit.
  12. Do not push.

Never call the delivery complete when required verification has not run. Report environmental or unrelated failures with evidence.

CHANGELOG.md Исходник

Changelog

Unreleased

Added

  • Standalone executable plan_build.zsh.
  • Canonical standard and architect Claude skills.
  • Standard, prompt-enhanced, brainstorm, writing-plan, and architect workflows.
  • Architect safe-resume and archive-and-start-new launch modes.
  • Command-level, network-free Zsh regression tests.
  • Dedicated installation, integration, architecture, task, and troubleshooting documentation.

Changed

  • Plan-build-specific implementation and documentation now belong to the dedicated plan-build gist rather than the Zsh Setup repository.
  • --yolo is translated to Claude Code's --dangerously-skip-permissions argument.
  • Active workflow documentation no longer describes removed v2 or distribution modes.
  • Prompt enhancement now uses valid, immediately flushed platform script invocations, propagates natural child failures, and cleans up temporary state and child processes on return or interruption.
  • The cache contract now rejects empty or syntactically invalid downloads before atomic activation and identifies mutable HTTPS HEAD as the update trust boundary.

Removed

  • Dependence on ~/.func and ambient shell functions.
  • The obsolete v2 downloader and its former workflow variants.

Pending

  • The Zsh Setup repository still needs a separate migration to the thin atomic-cache launcher. This extraction does not claim that migration is complete.
README.md Исходник

plan-build

plan-build is a standalone Zsh tool that launches Claude Code with a structured multi-agent implementation workflow. Claude orchestrates, Codex provides independent implementation review, and CodeRabbit reviews the resulting changes. Architect mode instead keeps Claude within a documentation-first architecture and task-dispatch role while Codex performs implementation.

Prerequisites

  • Zsh
  • Claude Code CLI (claude)
  • OpenAI Codex CLI (codex)
  • CodeRabbit CLI (coderabbit)
  • Git
  • The installed plan-build skills described below

--prompt also requires Auggie (auggie), an authenticated ~/.augment/session.json, Perl, and the platform script utility.

--brainstorm and --writing-plan require the enabled Claude Code plugin superpowers@claude-plugins-official. Claude Code safe mode must be disabled for those modes.

Architect mode additionally requires an interactive terminal and a normal Git worktree. Bare repositories are rejected.

Installation

Install the executable somewhere on PATH:

mkdir -p "$HOME/.local/bin"
curl -fsSL \
  https://opengist.resetrix.work/weehong/plan-build/raw/HEAD/plan_build.zsh \
  -o "$HOME/.local/bin/plan_build"
chmod +x "$HOME/.local/bin/plan_build"

Then install both skills:

mkdir -p \
  "$HOME/.claude/skills/plan-build" \
  "$HOME/.claude/skills/plan-build-architect"
curl -fsSL \
  https://opengist.resetrix.work/weehong/plan-build/raw/HEAD/SKILL.md \
  -o "$HOME/.claude/skills/plan-build/SKILL.md"
curl -fsSL \
  https://opengist.resetrix.work/weehong/plan-build/raw/HEAD/ARCHITECT.md \
  -o "$HOME/.claude/skills/plan-build-architect/SKILL.md"

For production automation, download to a temporary file in the destination directory and rename it atomically after a successful transfer.

Usage

Run the command in the project you want to change, enter the payload, then put EOF alone on a line:

plan_build
Implement pagination for the audit log.
Preserve existing API compatibility.
EOF

Available modes:

plan_build                                      Standard short-plan workflow
plan_build --prompt                             Enhance with Auggie and approve
plan_build --brainstorm                         Superpowers design and plan
plan_build --writing-plan                       Superpowers implementation plan
plan_build --prompt --brainstorm                Enhance, design, plan, and build
plan_build --yolo --writing-plan                Permissive Claude process mode
plan_build --architect                          Safely resume architect state
plan_build --architect --new                    Archive state and start fresh
plan_build --architect --yolo                   Architect with permissive process mode

--brainstorm and --writing-plan are mutually exclusive. --prompt can combine with either. --architect can combine only with --new and --yolo; --new is invalid without --architect. Duplicate flags and all other flags fail. --v2 is intentionally unsupported.

The user-facing --yolo option is translated to Claude Code's --dangerously-skip-permissions argument. It never bypasses approval gates defined by either workflow.

Cache-launcher integration contract

The future thin Zsh Setup launcher must download:

https://opengist.resetrix.work/weehong/plan-build/raw/HEAD/plan_build.zsh

It must download into a temporary file beside the cache target, validate that the download succeeded, is non-empty, and passes zsh -n, then atomically rename it into place. It invokes the cached program exactly as:

zsh <cache> "$@"

This mutable HTTPS HEAD download is the explicit update trust boundary: transport security authenticates the server, but the URL provides neither immutable-version pinning nor content-integrity verification. Atomic activation and syntax validation prevent partial or syntactically invalid cache entries; they do not establish provenance for changed remote content.

The same launcher or installer downloads SKILL.md and ARCHITECT.md from the same gist to:

~/.claude/skills/plan-build/SKILL.md
~/.claude/skills/plan-build-architect/SKILL.md

The launcher migration in the Zsh Setup repository is not part of this extraction and is not yet complete.

Testing

The suite is self-contained and never accesses the network or launches real agent CLIs:

zsh -n plan_build.zsh test_plan_build.zsh
zsh test_plan_build.zsh
git diff --check

Troubleshooting

  • CLI is missing: install the named program and ensure its executable is on PATH.
  • Superpowers is missing: in Claude Code run /plugin install superpowers@claude-plugins-official.
  • Superpowers is disabled: run claude plugin enable superpowers@claude-plugins-official.
  • Safe mode blocks planning: unset CLAUDE_CODE_SAFE_MODE.
  • Auggie cannot authenticate: run auggie login and confirm ~/.augment/session.json is non-empty.
  • Prompt enhancement does not continue: --prompt requires an interactive terminal to approve both optional project indexing and the final enhanced prompt.
  • Architect preflight fails in Git: change to a checked-out worktree rather than the .git directory or a bare repository.
  • Architect skill is missing: install ARCHITECT.md at the exact skill path shown above.
SKILL.md Исходник

Plan-Build Orchestrate Loop

Use this workflow when plan_build hands Claude Code an implementation task. The goal is to keep Claude as the orchestrator while using Codex and CodeRabbit as independent review and validation agents.

Operating Rules

  • Run from the project root. Treat the current working directory as the project to modify.
  • Preserve user work. Check git status before edits and do not revert unrelated changes.
  • Keep implementation scoped to the payload unless repository context proves a wider change is required.
  • Prefer existing project conventions, scripts, test commands, and dependency managers.
  • Do not call the task complete until validation has run or the reason it cannot run is documented.
  • If any agent reports a plausible correctness, security, data-loss, migration, or test risk, resolve it or explicitly document why it is not applicable.

The 8-Step Workflow

1. Intake

Read the user payload fully. Identify:

  • Objective and expected user-visible behavior.
  • Files, modules, commands, and frameworks likely involved.
  • Constraints from repository docs, package scripts, CI config, and existing patterns.
  • Any ambiguity that blocks safe execution.

Only ask the user a question when no reasonable project-local assumption is safe.

2. Baseline

Inspect the repository before changing files:

git status --short
rg --files

Then read the smallest useful set of files. Prefer rg, package manifests, tests, routing files, and nearby implementations over broad file dumps.

3. Plan

Follow the planning mode supplied by plan_build:

  • standard: Create a short implementation plan with concrete steps and validation commands.
  • brainstorm: Invoke superpowers:brainstorming, honor its design and written-spec approval gates, and let it transition to superpowers:writing-plans after approval.
  • writing-plan: Invoke superpowers:writing-plans directly, treating the payload as the requirements or specification.

For either Superpowers mode, save the artifacts at the paths selected by the skills. When writing-plans reaches its execution handoff, return to this workflow instead of starting implementation: Codex must review the plan first. If the user rejects or cancels a required approval, stop cleanly without modifying implementation files.

If the task touches behavior, data, auth, payments, destructive actions, or shared infrastructure, include a rollback or compatibility note.

4. Codex Plan Review

Run this step only for brainstorm and writing-plan modes. Ask Codex for an independent, read-only review of the approved spec, when present, and the implementation plan before touching implementation files. Provide the original payload and artifact paths. Ask it to focus on requirement coverage, incorrect assumptions, unsafe migrations, missing edge cases, inadequate tests, and steps that are too vague to execute.

Recommended prompt shape:

Review these planning artifacts before implementation. Check requirement coverage, technical correctness, repository fit, edge cases, migration or rollback risk, test coverage, and whether every step is executable. Report concrete findings only; do not modify files.

Task:
<payload>

Spec:
<spec path, if present>

Implementation plan:
<plan path>

Use a read-only, ephemeral Codex invocation. Resolve every valid finding in the artifacts and repeat the review if revisions are substantial. If an artifact is missing or empty, or Codex cannot complete the review, stop before implementation and report the failure.

In standard mode, skip this step and continue directly to implementation.

5. Implement

Make the change in small, reviewable edits:

  • Follow existing style and abstractions.
  • Add or update tests when behavior changes.
  • Update docs only when user-facing usage changes.
  • Avoid unrelated refactors and formatting churn.

After each meaningful edit group, re-check the diff for accidental changes.

6. Codex Code Review Pass

Ask Codex for an independent review of the local diff before finalizing. Provide the task, constraints, and current diff. Ask it to focus on bugs, edge cases, missing tests, regressions, and simpler project-native alternatives.

Recommended prompt shape:

Review this change for correctness and risk. Prioritize bugs, regressions, missing tests, and mismatches with existing project patterns. Do not rewrite the whole solution unless a specific issue requires it.

Task:
<payload>

Diff:
<git diff>

Apply fixes for valid findings, then repeat this review pass if the fixes are non-trivial.

7. CodeRabbit Review Pass

Run CodeRabbit on the branch or diff when available. Treat its output as advisory but investigate every concrete finding.

If CodeRabbit cannot run locally, record the command attempted and the failure. Continue with manual validation rather than blocking indefinitely.

8. Validate And Close

Run the planned validation commands, such as:

npm test
npm run lint
pytest
cargo test
go test ./...

Use the commands that actually exist in the project. If validation fails, fix the issue and rerun the relevant command. If a failure is unrelated or environmental, capture the evidence.

Before final response:

  • Confirm git diff contains only intended changes.
  • Summarize what changed.
  • Report validation run and result.
  • Note any remaining risks or commands that could not run.
SPEC.md Исходник

Plan-Build Specification

Purpose

Plan-build is a self-contained Zsh launcher for Claude Code multi-agent implementation workflows. This repository is the canonical boundary for the executable, both Claude skills, command tests, and project documentation. It does not depend on the Zsh Setup repository or on functions from ~/.func.

Public interface

plan_build [--yolo] [--prompt] [--brainstorm | --writing-plan]
plan_build --architect [--new] [--yolo]

The executable reads standard input until a line exactly equal to EOF. Empty payloads fail. Unknown and duplicate options fail with usage text. --v2 is intentionally unknown.

Standard modes

  • No planning flag: use the normal short-plan eight-step workflow.
  • --prompt: enhance the payload through Auggie, display the result, and require interactive approval before Claude launches.
  • --brainstorm: require enabled Claude Superpowers, then use brainstorming and writing-plans approval gates.
  • --writing-plan: require enabled Claude Superpowers and create the implementation plan directly.
  • --yolo: launch Claude Code with --dangerously-skip-permissions.

--brainstorm and --writing-plan are mutually exclusive. --prompt may be combined with either.

Architect mode

--architect makes Claude the documentation-first architect and dispatcher. It may combine only with --new and --yolo.

  • Default: safely detect and resume existing planning state.
  • --new: archive existing planning documents as directed by the architect skill and start fresh.
  • --yolo: changes Claude Code permissions only; every workflow approval gate remains mandatory.

Architect preflight happens before payload input and verifies an interactive terminal, Claude Code, Codex, CodeRabbit, Git, an exact normal Git worktree, and a readable non-empty architect skill.

Installed skills

The executable expects:

~/.claude/skills/plan-build/SKILL.md
~/.claude/skills/plan-build-architect/SKILL.md

The canonical repository sources are SKILL.md and ARCHITECT.md.

Standalone constraints

  • Zsh on macOS, Ubuntu, and WSL.
  • No sourcing of user shell configuration.
  • All internal helpers use the _plan_build_ namespace.
  • External command boundaries remain replaceable for tests.
  • Tests use no network and do not launch real agent CLIs.
  • The program remains sourceable and runs main only when executed directly.

Thin-launcher integration

A future Zsh Setup launcher will download:

https://opengist.resetrix.work/weehong/plan-build/raw/HEAD/plan_build.zsh

It must write to a temporary file in the cache directory, require the download to be non-empty and pass zsh -n, make the validated file atomically visible, then execute:

zsh <cache> "$@"

The mutable HTTPS HEAD URL is the explicit update trust boundary. HTTPS authenticates the transport endpoint, but without an immutable version or pinned digest it does not provide content-integrity or provenance guarantees for updates.

It will download SKILL.md and ARCHITECT.md from the same gist into the installed skill paths above. Migration of that old launcher is deliberately outside this repository and is not yet complete.

Acceptance criteria

  • Every documented mode has command-level coverage.
  • Invalid combinations, duplicate flags, empty payloads, and --v2 rejection are covered.
  • Superpowers checks precede Auggie and payload input.
  • Architect preflight precedes payload input and distinguishes normal worktrees from bare repositories.
  • Prompt enhancement cannot launch Claude without explicit approval.
  • --yolo reaches the Claude binary only as --dangerously-skip-permissions.
  • Syntax checks, command tests, and git diff --check pass.
TASKS.md Исходник

Plan-Build Tasks

Completed

PB-001: Establish the dedicated project boundary

  • Extract the executable from Zsh Setup into plan_build.zsh.
  • Remove dependencies on ~/.func and unrelated shell helpers.
  • Make the executable directly runnable and safely sourceable.

PB-002: Preserve supported workflows

  • Preserve standard, prompt enhancement, brainstorm, and writing-plan behavior.
  • Preserve architect safe-resume and archive-and-start-new modes.
  • Preserve EOF-terminated payload input and interactive enhanced-prompt approval.
  • Translate --yolo to Claude Code's real --dangerously-skip-permissions option.
  • Keep --v2 rejected through the unknown-option path.

PB-003: Canonicalize skills and documentation

  • Publish the standard workflow as SKILL.md.
  • Publish the architect workflow as ARCHITECT.md.
  • Remove obsolete v2-only and distribution workflow claims from the active standard skill.
  • Document installation, prerequisites, cache integration, compatibility, testing, and troubleshooting.

PB-004: Add standalone regression coverage

  • Stub external CLIs, Claude launch, Auggie enhancement, and interactive approval.
  • Cover all modes, invalid combinations, preflight ordering, safe-resume/new architect prompts, and normal versus bare Git repositories.
  • Keep the suite network-free.

Pending outside this repository

ZS-001: Migrate the Zsh Setup launcher

Replace the old in-repository function with a thin atomic-cache launcher that downloads the canonical executable and skills from the plan-build gist. This task belongs to the Zsh Setup repository and is not complete.

Required launcher contract:

zsh <cache> "$@"

Required remote files:

https://opengist.resetrix.work/weehong/plan-build/raw/HEAD/plan_build.zsh
https://opengist.resetrix.work/weehong/plan-build/raw/HEAD/SKILL.md
https://opengist.resetrix.work/weehong/plan-build/raw/HEAD/ARCHITECT.md
plan_build.zsh Исходник
1#!/usr/bin/env zsh
2
3# Standalone plan-build launcher. This file is intentionally sourceable so its
4# command seams can be replaced by the test suite.
5
6_plan_build_usage() {
7 print -r -- "Usage: plan_build [--yolo] [--prompt] [--brainstorm | --writing-plan]
8 plan_build --architect [--new] [--yolo]"
9}
10
11_plan_build_require_cli() {
12 local binary="$1"
13 local label="$2"
14 local resolved
15
16 resolved="$(command -v "$binary" 2>/dev/null)" || resolved=""
17 if [[ -n "$resolved" && -x "$resolved" ]]; then
18 return 0
19 fi
20
21 print -u2 -r -- "Error: ${label} ('${binary}') is not installed or not in your PATH."
22 return 1
23}
24
25_plan_build_confirm_indexing() {
26 local project_root="$1"
27 local reply
28
29 if ! (: </dev/tty) 2>/dev/null; then
30 print -u2 -r -- "Notice: No interactive terminal available; enhancing without project indexing."
31 return 1
32 fi
33
34 printf "Allow Auggie to index and use project context from '%s'? (y/N) " "$project_root" >/dev/tty
35 if ! IFS= read -r reply </dev/tty; then
36 print -u2 -r -- "\nNotice: Unable to read confirmation; enhancing without project indexing."
37 return 1
38 fi
39
40 [[ "$reply" == (y|Y|yes|YES|Yes) ]]
41}
42
43_plan_build_parse_auggie_output() {
44 local log_file="$1"
45 local output_file="$2"
46
47 perl -ne '
48 s/\r$//;
49 s/.*\r//;
50 1 while s/[^\x08]\x08//g;
51 s/\x08//g;
52 s/\e\][^\a]*(?:\a|\e\\)//g;
53 s/\e\[[0-?]*[ -\/]*[@-~]//g;
54 next if /Script started on/ || /Script done on/;
55 if (/^(?:✨\s*)?Enhanced prompt:\s*(.*)$/) {
56 $capturing = 1;
57 $output .= "$1\n" if length $1;
58 next;
59 }
60 next unless $capturing;
61 exit if /^🤖/ || /Tool call:/ || /Session terminated/;
62 $output .= $_;
63 END {
64 $output =~ s/^\s*\n//;
65 $output =~ s/\s+\z//;
66 print "$output\n" if length $output;
67 }
68 ' "$log_file" >| "$output_file"
69}
70
71_plan_build_platform() {
72 command uname -s
73}
74
75_plan_build_start_auggie_script() {
76 local platform="$1" log_file="$2" workspace="$3" cache_dir="$4"
77 local auth_file="$5" prompt_file="$6" use_project_context="$7"
78 shift 7
79
80 if [[ "$platform" == Darwin ]]; then
81 command script -q -t 0 "$log_file" auggie "$@" </dev/null >/dev/null 2>&1 &
82 else
83 AUGGIE_WORKSPACE="$workspace" AUGGIE_CACHE_DIR="$cache_dir" \
84 AUGGIE_AUTH_FILE="$auth_file" AUGGIE_PROMPT_FILE="$prompt_file" \
85 AUGGIE_INDEXING="$use_project_context" \
86 command script -q -f -O "$log_file" -c '
87 if [ "$AUGGIE_INDEXING" = 1 ]; then
88 exec auggie --print --enhance-prompt --workspace-root "$AUGGIE_WORKSPACE" --augment-cache-dir "$AUGGIE_CACHE_DIR" --augment-session-json "$AUGGIE_AUTH_FILE" --allow-indexing --wait-for-indexing --dont-save-session --instruction-file "$AUGGIE_PROMPT_FILE"
89 else
90 exec auggie --print --enhance-prompt --no-discover-workspaces --workspace-root "$AUGGIE_WORKSPACE" --augment-cache-dir "$AUGGIE_CACHE_DIR" --augment-session-json "$AUGGIE_AUTH_FILE" --dont-save-session --instruction-file "$AUGGIE_PROMPT_FILE"
91 fi
92 ' </dev/null >/dev/null 2>&1 &
93 fi
94 REPLY=$!
95}
96
97_plan_build_enhance_prompt() {
98 emulate -L zsh
99 setopt localtraps
100 local prompt="$1"
101 local output_file="$2"
102 local run_dir prompt_file workspace cache_dir auth_file log_file parsed_file
103 local project_root use_project_context timeout_seconds script_pid= waited child_status=0
104 local -a auggie_args
105
106 trap 'return 130' INT
107 trap 'return 143' TERM
108 trap 'return 129' HUP
109
110 if [[ -z "$prompt" ]]; then
111 print -u2 -r -- "Error: Prompt was empty."
112 return 1
113 fi
114 if [[ ! -s "$HOME/.augment/session.json" ]]; then
115 print -u2 -r -- "Error: Auggie session file not found. Run 'auggie login' first."
116 return 1
117 fi
118
119 run_dir="$(mktemp -d "${TMPDIR:-/tmp}/plan-build-auggie.XXXXXX")" || return 1
120 trap "rm -rf -- ${(q)run_dir}" EXIT
121 prompt_file="$run_dir/prompt.txt"
122 workspace="$run_dir/workspace"
123 cache_dir="$run_dir/cache"
124 auth_file="$HOME/.augment/session.json"
125 log_file="$run_dir/auggie.log"
126 parsed_file="$run_dir/enhanced.txt"
127 mkdir -p "$workspace" "$cache_dir" || {
128 return 1
129 }
130 print -r -- "$prompt" >| "$prompt_file" || return 1
131
132 project_root="$(command git rev-parse --show-toplevel 2>/dev/null)" || project_root="$PWD"
133 use_project_context=0
134 timeout_seconds=90
135 if _plan_build_confirm_indexing "$project_root"; then
136 use_project_context=1
137 timeout_seconds=300
138 workspace="$project_root"
139 cache_dir="$HOME/.augment"
140 print -u2 -r -- "Indexing approved; enhancing with project context from '${project_root}'."
141 else
142 print -u2 -r -- "Enhancing without project indexing."
143 fi
144
145 auggie_args=(--print --enhance-prompt --workspace-root "$workspace"
146 --augment-cache-dir "$cache_dir" --augment-session-json "$auth_file"
147 --dont-save-session --instruction-file "$prompt_file")
148 if (( use_project_context )); then
149 auggie_args+=(--allow-indexing --wait-for-indexing)
150 else
151 auggie_args+=(--no-discover-workspaces)
152 fi
153
154 _plan_build_start_auggie_script "$(_plan_build_platform)" "$log_file" \
155 "$workspace" "$cache_dir" "$auth_file" "$prompt_file" \
156 "$use_project_context" "${auggie_args[@]}" || return 1
157 script_pid="$REPLY"
158 trap "kill ${(q)script_pid} >/dev/null 2>&1
159 wait ${(q)script_pid} >/dev/null 2>&1
160 rm -rf -- ${(q)run_dir}" EXIT
161 waited=0
162 while kill -0 "$script_pid" >/dev/null 2>&1; do
163 if command grep -aq "🤖" "$log_file" 2>/dev/null ||
164 command grep -aq "Tool call:" "$log_file" 2>/dev/null; then
165 kill "$script_pid" >/dev/null 2>&1 || true
166 wait "$script_pid" >/dev/null 2>&1 || true
167 script_pid=
168 trap "rm -rf -- ${(q)run_dir}" EXIT
169 child_status=0
170 break
171 fi
172 if (( waited >= timeout_seconds )); then
173 kill "$script_pid" >/dev/null 2>&1 || true
174 wait "$script_pid" >/dev/null 2>&1 || true
175 script_pid=
176 trap "rm -rf -- ${(q)run_dir}" EXIT
177 print -u2 -r -- "Error: Timed out waiting for Auggie to enhance the prompt."
178 return 124
179 fi
180 sleep 1
181 waited=$((waited + 1))
182 done
183 if [[ -n "$script_pid" ]]; then
184 wait "$script_pid"
185 child_status=$?
186 script_pid=
187 trap "rm -rf -- ${(q)run_dir}" EXIT
188 fi
189 if (( child_status != 0 )); then
190 print -u2 -r -- "Error: Auggie process failed with status ${child_status}."
191 return "$child_status"
192 fi
193
194 _plan_build_parse_auggie_output "$log_file" "$parsed_file"
195 if [[ ! -s "$parsed_file" ]]; then
196 print -u2 -r -- "Error: Auggie did not return an enhanced prompt."
197 return 1
198 fi
199 command cp "$parsed_file" "$output_file" || {
200 print -u2 -r -- "Error: Unable to save the enhanced prompt."
201 return 1
202 }
203}
204
205_plan_build_confirm_enhanced_prompt() {
206 local reply
207
208 if ! (: </dev/tty) 2>/dev/null; then
209 print -r -- "❌ Error: Cannot review the enhanced prompt without an interactive terminal; Claude was not launched."
210 return 2
211 fi
212 printf "Proceed with this enhanced prompt? (y/N) " >/dev/tty
213 if ! IFS= read -r reply </dev/tty; then
214 printf '\n' >/dev/tty
215 print -r -- "🛑 Review cancelled; Claude was not launched."
216 return 2
217 fi
218 [[ "$reply" == (y|Y|yes|YES|Yes) ]]
219}
220
221_plan_build_superpowers_state() {
222 awk '
223 BEGIN { RS = "}"; state = "missing"; printed = 0 }
224 /"id"[[:space:]]*:[[:space:]]*"superpowers@claude-plugins-official"/ {
225 state = "installed"
226 if ($0 ~ /"enabled"[[:space:]]*:[[:space:]]*true/) state = "enabled"
227 else if ($0 ~ /"enabled"[[:space:]]*:[[:space:]]*false/) state = "disabled"
228 print state
229 printed = 1
230 exit
231 }
232 END { if (!printed) print state }
233 '
234}
235
236_plan_build_superpowers_preflight() {
237 local plugin_json plugin_state
238
239 case "${CLAUDE_CODE_SAFE_MODE:-}" in
240 1|true|TRUE|yes|YES|on|ON)
241 print -r -- "❌ Error: Claude Code safe mode disables Superpowers."
242 print -r -- "Unset CLAUDE_CODE_SAFE_MODE before using --brainstorm or --writing-plan."
243 return 1
244 ;;
245 esac
246 if ! plugin_json="$(command claude plugin list --json 2>/dev/null)"; then
247 print -r -- "❌ Error: Unable to inspect Claude Code plugins."
248 print -r -- "Run 'claude plugin list' to diagnose the problem."
249 return 1
250 fi
251 plugin_state="$(print -r -- "$plugin_json" | _plan_build_superpowers_state)"
252 case "$plugin_state" in
253 enabled) return 0 ;;
254 disabled)
255 print -r -- "❌ Error: Claude Code Superpowers is installed but disabled."
256 print -r -- "Enable it with: claude plugin enable superpowers@claude-plugins-official"
257 ;;
258 missing)
259 print -r -- "❌ Error: Claude Code Superpowers is required for --brainstorm and --writing-plan."
260 print -r -- "Install it in Claude Code with: /plugin install superpowers@claude-plugins-official"
261 ;;
262 *)
263 print -r -- "❌ Error: Unable to determine Claude Code Superpowers status."
264 print -r -- "Run 'claude plugin list' to diagnose the problem."
265 ;;
266 esac
267 return 1
268}
269
270_plan_build_is_worktree() {
271 local inside_work_tree
272 inside_work_tree="$(command git rev-parse --is-inside-work-tree 2>/dev/null)" || return 1
273 [[ "$inside_work_tree" == true ]]
274}
275
276_plan_build_has_tty() {
277 (: </dev/tty) 2>/dev/null
278}
279
280_plan_build_architect_preflight() {
281 local skill_path="$HOME/.claude/skills/plan-build-architect/SKILL.md"
282
283 if ! _plan_build_has_tty; then
284 print -r -- "❌ Error: Architect mode requires an interactive terminal."
285 print -r -- "Run plan_build --architect from an interactive terminal."
286 return 1
287 fi
288 _plan_build_require_cli claude "Claude Code CLI" || return 1
289 _plan_build_require_cli codex "Codex CLI" || return 1
290 _plan_build_require_cli coderabbit "CodeRabbit CLI" || return 1
291 _plan_build_require_cli git "Git CLI" || return 1
292 if ! _plan_build_is_worktree; then
293 print -r -- "❌ Error: Architect mode must run inside a Git worktree."
294 print -r -- "Change to a Git worktree, then retry plan_build --architect."
295 return 1
296 fi
297 if [[ ! -r "$skill_path" || ! -s "$skill_path" ]]; then
298 print -r -- "❌ Error: Architect skill is missing, unreadable, or empty: $skill_path"
299 print -r -- "Install a readable, non-empty plan-build-architect skill at that path."
300 return 1
301 fi
302}
303
304_plan_build_launch_claude() {
305 local use_yolo="$1"
306 shift
307 if (( use_yolo )); then
308 command claude --dangerously-skip-permissions "$@"
309 else
310 command claude "$@"
311 fi
312}
313
314_plan_build_read_payload() {
315 local line payload=""
316 while IFS= read -r line; do
317 [[ "$line" == EOF ]] && break
318 if [[ -z "$payload" ]]; then
319 payload="$line"
320 else
321 payload+=$'\n'"$line"
322 fi
323 done
324 print -r -- "$payload"
325}
326
327plan_build() {
328 emulate -L zsh
329 setopt localtraps
330 local use_yolo=0 use_architect=0 use_new=0 enhance_payload=0
331 local planning_mode="standard"
332 local payload enhanced_file= confirm_status enhance_status planning_instruction architect_start_mode
333
334 trap 'return 130' INT
335 trap 'return 143' TERM
336 trap 'return 129' HUP
337
338 while (( $# )); do
339 case "$1" in
340 --yolo)
341 (( use_yolo )) && {
342 print -r -- "Error: Duplicate argument: --yolo"
343 _plan_build_usage
344 return 1
345 }
346 use_yolo=1
347 ;;
348 --architect)
349 (( use_architect )) && {
350 print -r -- "Error: Duplicate argument: --architect"
351 _plan_build_usage
352 return 1
353 }
354 use_architect=1
355 ;;
356 --new)
357 (( use_new )) && {
358 print -r -- "Error: Duplicate argument: --new"
359 _plan_build_usage
360 return 1
361 }
362 use_new=1
363 ;;
364 --prompt)
365 (( enhance_payload )) && {
366 print -r -- "Error: Duplicate argument: --prompt"
367 _plan_build_usage
368 return 1
369 }
370 enhance_payload=1
371 ;;
372 --brainstorm)
373 [[ "$planning_mode" == brainstorm ]] && {
374 print -r -- "Error: Duplicate argument: --brainstorm"
375 _plan_build_usage
376 return 1
377 }
378 [[ "$planning_mode" != standard ]] && {
379 print -r -- "Error: --brainstorm and --writing-plan are mutually exclusive."
380 _plan_build_usage
381 return 1
382 }
383 planning_mode="brainstorm"
384 ;;
385 --writing-plan)
386 [[ "$planning_mode" == writing-plan ]] && {
387 print -r -- "Error: Duplicate argument: --writing-plan"
388 _plan_build_usage
389 return 1
390 }
391 [[ "$planning_mode" != standard ]] && {
392 print -r -- "Error: --brainstorm and --writing-plan are mutually exclusive."
393 _plan_build_usage
394 return 1
395 }
396 planning_mode="writing-plan"
397 ;;
398 *)
399 print -r -- "Error: Unknown argument: $1"
400 _plan_build_usage
401 return 1
402 ;;
403 esac
404 shift
405 done
406
407 if (( use_new && ! use_architect )); then
408 print -r -- "Error: --new requires --architect."
409 _plan_build_usage
410 return 1
411 fi
412 if (( use_architect && enhance_payload )) ||
413 { (( use_architect )) && [[ "$planning_mode" != standard ]]; }; then
414 print -r -- "Error: --architect may combine only with --new and --yolo."
415 _plan_build_usage
416 return 1
417 fi
418
419 if (( use_architect )); then
420 _plan_build_architect_preflight || return 1
421 else
422 _plan_build_require_cli claude "Claude Code CLI" || return 1
423 if [[ "$planning_mode" != standard ]]; then
424 _plan_build_superpowers_preflight || return 1
425 fi
426 _plan_build_require_cli codex "Codex CLI" || return 1
427 _plan_build_require_cli coderabbit "CodeRabbit CLI" || return 1
428 if (( enhance_payload )); then
429 _plan_build_require_cli auggie "Auggie CLI" || return 1
430 _plan_build_require_cli script "script utility" || return 1
431 _plan_build_require_cli perl "Perl" || return 1
432 fi
433 fi
434
435 print -r -- "📥 Reading payload... Type 'EOF' on a new line and press Enter when finished."
436 payload="$(_plan_build_read_payload)"
437 if [[ -z "$payload" ]]; then
438 print -r -- "❌ Error: Payload was empty."
439 return 1
440 fi
441
442 if (( enhance_payload )); then
443 enhanced_file="$(mktemp "${TMPDIR:-/tmp}/plan-build-enhanced.XXXXXX")" || return 1
444 trap "rm -f -- ${(q)enhanced_file}" EXIT
445 print -r -- "✨ Enhancing payload with Auggie..."
446 _plan_build_enhance_prompt "$payload" "$enhanced_file"
447 enhance_status=$?
448 if (( enhance_status != 0 )); then
449 print -r -- "❌ Error: Prompt enhancement failed; Claude was not launched."
450 return "$enhance_status"
451 fi
452 payload="$(<"$enhanced_file")"
453 rm -f -- "$enhanced_file"
454 enhanced_file=
455 trap - EXIT
456 if [[ -z "$payload" ]]; then
457 print -r -- "❌ Error: Enhanced payload was empty; Claude was not launched."
458 return 1
459 fi
460 printf '\n%s\n%s\n%s\n\n' \
461 "━━━━━━━━━━━━━━━━ Auggie enhanced prompt ━━━━━━━━━━━━━━━━" \
462 "$payload" \
463 "━━━━━━━━━━━━━━━━ End enhanced prompt ━━━━━━━━━━━━━━━━━"
464 _plan_build_confirm_enhanced_prompt
465 confirm_status=$?
466 if (( confirm_status == 2 )); then
467 return 1
468 elif (( confirm_status != 0 )); then
469 print -r -- "🛑 Enhanced prompt not approved; Claude was not launched."
470 return 0
471 fi
472 print -r -- "✅ Enhanced prompt approved."
473 fi
474
475 if (( use_architect )); then
476 if (( use_new )); then
477 architect_start_mode="Start mode: archive-and-start-new. Explicitly archive the prior planning state as the skill directs, then begin a new architecture plan."
478 else
479 architect_start_mode="Start mode: safe-resume-detection. Safely detect whether an existing architecture planning session should be resumed; do not archive or replace it automatically."
480 fi
481 print -r -- "🚀 Launching Claude Code in architect mode..."
482 _plan_build_launch_claude "$use_yolo" "Read \`~/.claude/skills/plan-build-architect/SKILL.md\` and follow it strictly, including every gate even when permissive Claude execution is active. Stay in the documentation-first architect/orchestrator role: produce and coordinate documentation and planning only, and do not implement the requirement.
483
484$architect_start_mode
485
486Use the following payload as the initial requirement:
487
488$payload"
489 return $?
490 fi
491
492 case "$planning_mode" in
493 brainstorm)
494 planning_instruction="Planning mode: brainstorm. Use the superpowers:brainstorming skill, including its approval gates and transition to superpowers:writing-plans. After the implementation plan is saved, return to the plan-build workflow for Codex plan review before implementation."
495 ;;
496 writing-plan)
497 planning_instruction="Planning mode: writing-plan. Use the superpowers:writing-plans skill with the payload as the requirements. After the implementation plan is saved, return to the plan-build workflow for Codex plan review before implementation."
498 ;;
499 *)
500 planning_instruction="Planning mode: standard. Create the workflow's normal short implementation plan."
501 ;;
502 esac
503
504 print -r -- "🚀 Launching Claude Code with your multi-agent workflow (${planning_mode} planning)..."
505 _plan_build_launch_claude "$use_yolo" "Please read \`~/.claude/skills/plan-build/SKILL.md\` and strictly follow the 8-step multi-agent workflow to implement the following task.
506
507$planning_instruction
508
509$payload"
510}
511
512_plan_build_main() {
513 plan_build "$@"
514}
515
516if [[ "${ZSH_EVAL_CONTEXT:-}" == toplevel ]]; then
517 _plan_build_main "$@"
518fi
519
test_plan_build.zsh Исходник
1#!/usr/bin/env zsh
2
3set -u
4
5typeset -r repo_dir="${0:A:h}"
6source "$repo_dir/plan_build.zsh"
7
8typeset -gi failures=0
9functions[_plan_build_real_launch_claude]="${functions[_plan_build_launch_claude]}"
10functions[_plan_build_real_enhance_prompt]="${functions[_plan_build_enhance_prompt]}"
11functions[_plan_build_real_start_auggie_script]="${functions[_plan_build_start_auggie_script]}"
12
13fail() {
14 print -u2 -r -- "FAIL: $1"
15 failures=$((failures + 1))
16}
17
18assert_equal() {
19 local expected="$1" actual="$2" label="$3"
20 [[ "$actual" == "$expected" ]] || fail "$label (expected '$expected', got '$actual')"
21}
22
23assert_contains() {
24 local output="$1" expected="$2" label="$3"
25 [[ "$output" == *"$expected"* ]] || fail "$label (missing '$expected')"
26}
27
28assert_not_contains() {
29 local output="$1" unexpected="$2" label="$3"
30 [[ "$output" != *"$unexpected"* ]] || fail "$label (unexpected '$unexpected')"
31}
32
33run_plan() {
34 local args="$1" input="${2:-EOF\n}"
35 output="$(printf '%b' "$input" | plan_build ${(z)args} 2>&1)"
36 rc=$?
37}
38
39seam_events() {
40 print -r -- "$1" | sed -n 's/^SEAM://p' | paste -sd ' ' -
41}
42
43count_matches() {
44 local directory="$1" prefix="$2"
45 local -a matches
46 matches=("$directory"/"$prefix".*(N))
47 print -r -- "$#matches"
48}
49
50typeset fixture_dir
51fixture_dir="$(mktemp -d "${TMPDIR:-/tmp}/plan-build-tests.XXXXXX")" || exit 1
52trap 'rm -rf -- "$fixture_dir"' EXIT
53mkdir -p "$fixture_dir/tmp"
54export TMPDIR="$fixture_dir/tmp"
55
56command git init -q "$fixture_dir/worktree"
57command git init -q --bare "$fixture_dir/bare.git"
58
59(cd "$fixture_dir/worktree" && _plan_build_is_worktree)
60assert_equal 0 "$?" "normal Git worktree accepted"
61(cd "$fixture_dir/bare.git" && _plan_build_is_worktree)
62assert_equal 1 "$?" "bare Git repository rejected"
63(cd "$fixture_dir" && _plan_build_is_worktree)
64assert_equal 1 "$?" "non-repository rejected"
65
66plugin_state() {
67 print -r -- "$1" | _plan_build_superpowers_state
68}
69
70assert_equal enabled "$(plugin_state '[{"id":"superpowers@claude-plugins-official","enabled":true}]')" "enabled plugin JSON"
71assert_equal disabled "$(plugin_state $'[\n{"enabled":false,\n"id":"superpowers@claude-plugins-official"}\n]')" "reordered disabled plugin JSON"
72assert_equal missing "$(plugin_state '[{"id":"other@market","enabled":true}]')" "missing plugin JSON"
73assert_equal installed "$(plugin_state '[{"id":"superpowers@claude-plugins-official"}]')" "installed plugin JSON"
74
75typeset args expected label
76for args expected label in \
77 "--v2" "Unknown argument: --v2" "v2 rejection" \
78 "--unknown" "Unknown argument: --unknown" "unknown option" \
79 "--yolo --yolo" "Duplicate argument: --yolo" "duplicate yolo" \
80 "--prompt --prompt" "Duplicate argument: --prompt" "duplicate prompt" \
81 "--brainstorm --brainstorm" "Duplicate argument: --brainstorm" "duplicate brainstorm" \
82 "--writing-plan --writing-plan" "Duplicate argument: --writing-plan" "duplicate writing plan" \
83 "--architect --architect" "Duplicate argument: --architect" "duplicate architect" \
84 "--architect --new --new" "Duplicate argument: --new" "duplicate new" \
85 "--brainstorm --writing-plan" "mutually exclusive" "planning mode conflict" \
86 "--new" "--new requires --architect" "orphan new" \
87 "--architect --prompt" "may combine only with --new and --yolo" "architect prompt conflict" \
88 "--architect --brainstorm" "may combine only with --new and --yolo" "architect brainstorm conflict" \
89 "--architect --writing-plan" "may combine only with --new and --yolo" "architect writing conflict"; do
90 run_plan "$args"
91 assert_equal 1 "$rc" "$label status"
92 assert_contains "$output" "$expected" "$label message"
93done
94
95export CLAUDE_CODE_SAFE_MODE=1
96output="$(_plan_build_superpowers_preflight 2>&1)"
97rc=$?
98unset CLAUDE_CODE_SAFE_MODE
99assert_equal 1 "$rc" "safe mode failure"
100assert_contains "$output" "safe mode disables Superpowers" "safe mode guidance"
101
102mkdir -p "$fixture_dir/bin" "$fixture_dir/home/.augment" "$fixture_dir/enhance-tmp"
103print -r -- '{}' >| "$fixture_dir/home/.augment/session.json"
104print -r -- '#!/bin/sh' >| "$fixture_dir/bin/script"
105print -r -- 'printf "%s\n" "$@" > "$PLAN_BUILD_SCRIPT_ARGS"' >> "$fixture_dir/bin/script"
106print -r -- 'if [ "$1" = -q ] && [ "$2" = -t ]; then log_file=$4; shift 4; "$@" > "$log_file"; exit $?; fi' >> "$fixture_dir/bin/script"
107print -r -- 'log_file=$4; printf "Enhanced prompt: linux result\n" > "$log_file"; exit "${PLAN_BUILD_SCRIPT_STATUS:-0}"' >> "$fixture_dir/bin/script"
108print -r -- '#!/bin/sh' >| "$fixture_dir/bin/auggie"
109print -r -- 'printf "Enhanced prompt: mac result\n"; exit "${PLAN_BUILD_AUGGIE_STATUS:-0}"' >> "$fixture_dir/bin/auggie"
110chmod +x "$fixture_dir/bin/script" "$fixture_dir/bin/auggie"
111
112_plan_build_confirm_indexing() { return 1 }
113
114typeset platform script_args enhance_output
115trap 'print -u2 -r -- "test INT trap"' INT
116typeset caller_int_trap="$(trap -p INT)"
117for platform in Darwin Linux; do
118 _plan_build_platform() { print -r -- "$platform" }
119 : >| "$fixture_dir/script-args"
120 enhance_output="$fixture_dir/enhanced-$platform"
121 HOME="$fixture_dir/home" TMPDIR="$fixture_dir/enhance-tmp" \
122 PATH="$fixture_dir/bin:$PATH" PLAN_BUILD_SCRIPT_ARGS="$fixture_dir/script-args" \
123 _plan_build_real_enhance_prompt "raw prompt" "$enhance_output"
124 rc=$?
125 assert_equal 0 "$rc" "$platform script enhancement status"
126 script_args="$(<"$fixture_dir/script-args")"
127 if [[ "$platform" == Darwin ]]; then
128 assert_contains "$script_args" $'-t\n0' "macOS script immediate flushing"
129 assert_contains "$script_args" $'auggie\n--print' "macOS script direct executable dispatch"
130 assert_not_contains "$script_args" $'\ncommand\n' "macOS script excludes shell builtin"
131 assert_equal "mac result" "$(<"$enhance_output")" "macOS parsed enhancement"
132 else
133 assert_contains "$script_args" $'-f\n-O' "Linux script immediate flushing"
134 assert_contains "$script_args" "-c" "Linux script command mode"
135 assert_equal "linux result" "$(<"$enhance_output")" "Linux parsed enhancement"
136 fi
137 assert_equal 0 "$(count_matches "$fixture_dir/enhance-tmp" plan-build-auggie)" "$platform run directory cleanup"
138done
139assert_equal "$caller_int_trap" "$(trap -p INT)" "enhancement traps remain local to caller"
140trap - INT
141
142platform=Darwin
143_plan_build_platform() { print -r -- "$platform" }
144PLAN_BUILD_AUGGIE_STATUS=7 HOME="$fixture_dir/home" TMPDIR="$fixture_dir/enhance-tmp" \
145 PATH="$fixture_dir/bin:$PATH" PLAN_BUILD_SCRIPT_ARGS="$fixture_dir/script-args" \
146 _plan_build_real_enhance_prompt "partial prompt" "$fixture_dir/failed-enhancement" >/dev/null 2>&1
147rc=$?
148assert_equal 7 "$rc" "nonzero Auggie status propagated"
149[[ ! -e "$fixture_dir/failed-enhancement" ]] || fail "failed Auggie output was accepted"
150assert_equal 0 "$(count_matches "$fixture_dir/enhance-tmp" plan-build-auggie)" "failed run directory cleanup"
151
152print -r -- $'noise\r\n\e[32m✨ Enhanced prompt: first\e[0m\r\nsecond\r\n🤖 tool' >| "$fixture_dir/parser.log"
153_plan_build_parse_auggie_output "$fixture_dir/parser.log" "$fixture_dir/parser.out"
154assert_equal $'first\nsecond' "$(<"$fixture_dir/parser.out")" "parser strips terminal output and stops at marker"
155print -r -- "no enhanced prompt" >| "$fixture_dir/parser-empty.log"
156_plan_build_parse_auggie_output "$fixture_dir/parser-empty.log" "$fixture_dir/parser-empty.out"
157[[ ! -s "$fixture_dir/parser-empty.out" ]] || fail "parser accepted output without marker"
158
159typeset -g enhanced_text="enhanced payload"
160typeset -gi enhanced_approval=0
161typeset -gi architect_preflight_result=0
162typeset -gi enhancement_result=0
163
164_plan_build_require_cli() {
165 print -r -- "SEAM:cli:$1"
166 return 0
167}
168_plan_build_superpowers_preflight() {
169 print -r -- "SEAM:superpowers"
170 return 0
171}
172_plan_build_architect_preflight() {
173 print -r -- "SEAM:architect-preflight"
174 return "$architect_preflight_result"
175}
176_plan_build_enhance_prompt() {
177 print -r -- "SEAM:auggie:$1"
178 print -r -- "$enhanced_text" >| "$2"
179 return "$enhancement_result"
180}
181_plan_build_confirm_enhanced_prompt() {
182 print -r -- "SEAM:enhanced-approval"
183 return "$enhanced_approval"
184}
185_plan_build_launch_claude() {
186 print -r -- "SEAM:claude"
187 printf 'CLAUDE_YOLO=<%s>\nCLAUDE_PROMPT=<%s>\n' "$1" "$2"
188}
189
190run_plan "" "first line\nsecond line\nEOF\nignored line\n"
191assert_equal 0 "$rc" "standard mode status"
192assert_contains "$output" "Planning mode: standard" "standard planning prompt"
193assert_contains "$output" $'first line\nsecond line' "multiline payload"
194assert_not_contains "$output" "ignored line" "EOF terminates payload"
195
196run_plan "--brainstorm" "build feature\nEOF\n"
197assert_equal 0 "$rc" "brainstorm status"
198assert_contains "$output" "Planning mode: brainstorm" "brainstorm prompt"
199assert_equal "cli:claude superpowers cli:codex cli:coderabbit claude" "$(seam_events "$output")" "brainstorm preflight ordering"
200
201run_plan "--writing-plan" "build feature\nEOF\n"
202assert_equal 0 "$rc" "writing-plan status"
203assert_contains "$output" "Planning mode: writing-plan" "writing-plan prompt"
204
205enhanced_approval=0
206run_plan "--prompt" "raw payload\nEOF\n"
207assert_equal 0 "$rc" "prompt mode approved status"
208assert_contains "$output" "enhanced payload" "enhanced prompt used"
209assert_contains "$output" "Enhanced prompt approved" "enhanced approval reported"
210assert_equal "cli:claude cli:codex cli:coderabbit cli:auggie cli:script cli:perl auggie:raw payload enhanced-approval claude" "$(seam_events "$output")" "prompt seams ordering"
211
212enhancement_result=9
213run_plan "--prompt" "failed child\nEOF\n"
214assert_equal 9 "$rc" "prompt child failure status propagated"
215assert_not_contains "$output" "enhanced-approval" "failed enhancement is never parsed or approved"
216assert_not_contains "$output" "SEAM:claude" "failed enhancement prevents launch"
217assert_equal 0 "$(count_matches "$TMPDIR" plan-build-enhanced)" "enhanced temporary file cleanup"
218enhancement_result=0
219
220run_plan "--prompt --brainstorm" "raw combination\nEOF\n"
221assert_equal 0 "$rc" "prompt brainstorm status"
222assert_contains "$output" "Planning mode: brainstorm" "prompt brainstorm planning"
223
224enhanced_approval=1
225run_plan "--prompt" "declined\nEOF\n"
226assert_equal 0 "$rc" "prompt rejection exits cleanly"
227assert_contains "$output" "not approved" "prompt rejection message"
228assert_equal "cli:claude cli:codex cli:coderabbit cli:auggie cli:script cli:perl auggie:declined enhanced-approval" "$(seam_events "$output")" "prompt rejection prevents launch"
229enhanced_approval=0
230
231run_plan "--architect" "design feature\nEOF\n"
232assert_equal 0 "$rc" "architect safe-resume status"
233assert_contains "$output" "Start mode: safe-resume-detection" "architect safe-resume mode"
234assert_contains "$output" "documentation-first architect/orchestrator role" "architect role boundary"
235assert_equal "architect-preflight claude" "$(seam_events "$output")" "architect preflight before launch"
236
237run_plan "--architect --new" "fresh design\nEOF\n"
238assert_equal 0 "$rc" "architect new status"
239assert_contains "$output" "Start mode: archive-and-start-new" "architect new mode"
240
241run_plan "--architect --yolo" "fast design\nEOF\n"
242assert_equal 0 "$rc" "architect yolo status"
243assert_contains "$output" "CLAUDE_YOLO=<1>" "architect yolo reaches launch seam"
244assert_contains "$output" "including every gate" "architect yolo retains gates"
245
246architect_preflight_result=1
247run_plan "--architect" "must not be read\nEOF\n"
248assert_equal 1 "$rc" "architect preflight failure status"
249assert_not_contains "$output" "Reading payload" "architect preflight precedes payload"
250assert_equal "architect-preflight" "$(seam_events "$output")" "architect failure stops processing"
251architect_preflight_result=0
252
253run_plan "" "EOF\n"
254assert_equal 1 "$rc" "empty payload status"
255assert_contains "$output" "Payload was empty" "empty payload message"
256
257print -r -- '#!/bin/sh' >| "$fixture_dir/bin/claude"
258print -r -- 'printf "REAL_CLAUDE:"; printf " <%s>" "$@"; printf "\n"' >> "$fixture_dir/bin/claude"
259chmod +x "$fixture_dir/bin/claude"
260output="$(PATH="$fixture_dir/bin:$PATH" _plan_build_real_launch_claude 1 "payload")"
261assert_contains "$output" "<--dangerously-skip-permissions>" "yolo translates to real Claude argument"
262assert_not_contains "$output" "<--yolo>" "yolo alias not forwarded"
263
264if (( failures )); then
265 print -u2 -r -- "FAIL: $failures plan_build test(s)"
266 exit 1
267fi
268
269print -r -- "PASS: plan_build tests"
270