-
Run .specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute. For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'''m Groot' (or double-quote if possible: "I'm Groot").
-
Check checklists status (if FEATURE_DIR/checklists/ exists):
-
Scan all checklist files in the checklists/ directory
-
For each checklist, count:
- Total items: All lines matching
- [ ] or - [X] or - [x]
- Completed items: Lines matching
- [X] or - [x]
- Incomplete items: Lines matching
- [ ]
-
Create a status table:
| Checklist | Total | Completed | Incomplete | Status |
|-----------|-------|-----------|------------|--------|
| ux.md | 12 | 12 | 0 | ✓ PASS |
| test.md | 8 | 5 | 3 | ✗ FAIL |
| security.md | 6 | 6 | 0 | ✓ PASS |
-
Calculate overall status:
- PASS: All checklists have 0 incomplete items
- FAIL: One or more checklists have incomplete items
-
If any checklist is incomplete:
- Display the table with incomplete item counts
- STOP and ask: "Some checklists are incomplete. Do you want to proceed with implementation anyway? (yes/no)"
- Wait for user response before continuing
- If user says "no" or "wait" or "stop", halt execution
- If user says "yes" or "proceed" or "continue", proceed to step 3
-
If all checklists are complete:
- Display the table showing all checklists passed
- Automatically proceed to step 3
-
Load and analyze the implementation context:
- REQUIRED: Read tasks.md for the complete task list and execution plan
- REQUIRED: Read plan.md for tech stack, architecture, and file structure
- IF EXISTS: Read data-model.md for entities and relationships
- IF EXISTS: Read contracts/ for API specifications and test requirements
- IF EXISTS: Read research.md for technical decisions and constraints
- IF EXISTS: Read quickstart.md for integration scenarios
-
Project Setup Verification:
- REQUIRED: Create/verify ignore files based on actual project setup:
Detection & Creation Logic:
-
Check if the following command succeeds to determine if the repository is a git repo (create/verify .gitignore if so):
git rev-parse --git-dir 2>/dev/null
-
Check if Dockerfile* exists or Docker in plan.md → create/verify .dockerignore
-
Check if .eslintrc* exists → create/verify .eslintignore
-
Check if eslint.config.* exists → ensure the config's ignores entries cover required patterns
-
Check if .prettierrc* exists → create/verify .prettierignore
-
Check if .npmrc or package.json exists → create/verify .npmignore (if publishing)
-
Check if terraform files (*.tf) exist → create/verify .terraformignore
-
Check if .helmignore needed (helm charts present) → create/verify .helmignore
If ignore file already exists: Verify it contains essential patterns, append missing critical patterns only
If ignore file missing: Create with full pattern set for detected technology
Common Patterns by Technology (from plan.md tech stack):
- Node.js/JavaScript/TypeScript:
node_modules/, dist/, build/, *.log, .env*
- Python:
__pycache__/, *.pyc, .venv/, venv/, dist/, *.egg-info/
- Java:
target/, *.class, *.jar, .gradle/, build/
- C#/.NET:
bin/, obj/, *.user, *.suo, packages/
- Go:
*.exe, *.test, vendor/, *.out
- Ruby:
.bundle/, log/, tmp/, *.gem, vendor/bundle/
- PHP:
vendor/, *.log, *.cache, *.env
- Rust:
target/, debug/, release/, *.rs.bk, *.rlib, *.prof*, .idea/, *.log, .env*
- Kotlin:
build/, out/, .gradle/, .idea/, *.class, *.jar, *.iml, *.log, .env*
- C++:
build/, bin/, obj/, out/, *.o, *.so, *.a, *.exe, *.dll, .idea/, *.log, .env*
- C:
build/, bin/, obj/, out/, *.o, *.a, *.so, *.exe, *.dll, autom4te.cache/, config.status, config.log, .idea/, *.log, .env*
- Swift:
.build/, DerivedData/, *.swiftpm/, Packages/
- R:
.Rproj.user/, .Rhistory, .RData, .Ruserdata, *.Rproj, packrat/, renv/
- Universal:
.DS_Store, Thumbs.db, *.tmp, *.swp, .vscode/, .idea/
Tool-Specific Patterns:
- Docker:
node_modules/, .git/, Dockerfile*, .dockerignore, *.log*, .env*, coverage/
- ESLint:
node_modules/, dist/, build/, coverage/, *.min.js
- Prettier:
node_modules/, dist/, build/, coverage/, package-lock.json, yarn.lock, pnpm-lock.yaml
- Terraform:
.terraform/, *.tfstate*, *.tfvars, .terraform.lock.hcl
- Kubernetes/k8s:
*.secret.yaml, secrets/, .kube/, kubeconfig*, *.key, *.crt
-
Parse tasks.md structure and extract:
- Task phases: Setup, Tests, Core, Integration, Polish
- Task dependencies: Sequential vs parallel execution rules
- Task details: ID, description, file paths, parallel markers [P]
- Execution flow: Order and dependency requirements
-
Execute implementation following the task plan:
- Phase-by-phase execution: Complete each phase before moving to the next
- Respect dependencies: Run sequential tasks in order, parallel tasks [P] can run together
- Follow TDD approach: Execute test tasks before their corresponding implementation tasks
- File-based coordination: Tasks affecting the same files must run sequentially
- Validation checkpoints: Verify each phase completion before proceeding
-
Implementation execution rules:
- Setup first: Initialize project structure, dependencies, configuration
- Tests before code: If you need to write tests for contracts, entities, and integration scenarios
- Core development: Implement models, services, CLI commands, endpoints
- Integration work: Database connections, middleware, logging, external services
- Polish and validation: Unit tests, performance optimization, documentation
-
Progress tracking and error handling:
- Report progress after each completed task
- Halt execution if any non-parallel task fails
- For parallel tasks [P], continue with successful tasks, report failed ones
- Provide clear error messages with context for debugging
- Suggest next steps if implementation cannot proceed
- IMPORTANT For completed tasks, make sure to mark the task off as [X] in the tasks file.
-
Completion validation:
- Verify all required tasks are completed
- Check that implemented features match the original specification
- Validate that tests pass and coverage meets requirements
- Confirm the implementation follows the technical plan
- Report final status with summary of completed work
Note: This command assumes a complete task breakdown exists in tasks.md. If tasks are incomplete or missing, suggest running /speckit-tasks first to regenerate the task list.
These rules apply to every Companion profile command. The extension records lifecycle timing with its own scripts wherever it can; these rules keep anything you append consistent with that and accurate for any dispatcher (terminal, IDE chat, or the GUI). The model is finish-only: each task and each substep records a single finish event, and its duration is the gap to the previous finish (or the step's start). Never a start+complete pair for a task or substep — a pair stamped at one instant is what produces 0s ticks and bursts.
-
Never hand-edit .spec-context.json. Record every finish by running the writer script, never by editing the JSON file yourself — a hand-authored edit is what corrupts the file (a duplicated status key). The script stamps the real clock, writes atomically, and is idempotent. The commands below are the only way you touch timing.
-
Self-close — but not specify or implement. When your own work for plan, tasks, clarify, or analyze ends, record the step finish (feature dir from .specify/feature.json):
python3 .specify/extensions/companion/scripts/write-context.py --feature-dir <feature_dir> --step <this step> --finish --by ai
--finish appends a single step-level complete and touches nothing else (it leaves status/currentStep to the lifecycle hooks). Do NOT self-close specify or implement: the extension closes those itself (specify from its own command, implement from the end-of-step hook), so an ai complete there would duplicate it.
-
Substeps — one finish each, via the script. For each substep boundary (plan: research, design; tasks: generate), the moment that substep ends, run:
python3 .specify/extensions/companion/scripts/write-context.py --feature-dir <feature_dir> --step <step> --substep <name> --finish --by ai
One call per substep, each stamped with its own real clock at the moment it finishes — never two substeps in one batch, never a separate start. The delta between consecutive finishes is each substep's duration.
-
Implement — finishing a task is logging it (finish-only). Recording a task's finish is the closing action of that task, done the instant its work is complete and before you start the next one — not a bookkeeping pass you batch at the end of a phase. The closing action is a single append (feature dir from .specify/feature.json):
python3 .specify/extensions/companion/scripts/write-context.py --feature-dir <feature_dir> --task <TaskID> --kind complete --by ai --did "<one-line summary of what this task did>" --files "<comma,separated,files,touched>" --append
--append writes one line to .spec-context.events.jsonl and does not read or rewrite the shared .spec-context.json, so it never hits the "read the file first" retry and parallel workers can each append their own finish at the same time without contending — the line carries its own real timestamp (date -u is stamped by the script). The --did/--files flags ride along so the Activity panel's Tasks card is populated from the script. Do NOT hand-edit the - [ ] checkbox in tasks.md — the script owns it: materialize flips it to - [x] from your appended finish, so a fanned-out subagent only appends and never touches the shared tasks.md. Do NOT hand-author per-task JSON and do NOT write a per-task start.
Then fold the appended lines into .spec-context.json — run this once per wave (after the wave reconciles) and again when the step ends:
python3 .specify/extensions/companion/scripts/write-context.py --feature-dir <feature_dir> --materialize
--materialize is the one read-modify-write: it folds the finishes into the panel and checks off the matching tasks.md boxes for every journaled task, idempotently (re-folding never double-counts), so running it per wave keeps the GUI current without re-serializing the work. The end-of-step hook is a backstop that materializes anything you didn't fold and fills any task you didn't journal. What's trustworthy here is the per-task summary (did/files) and the order tasks completed, plus the step-level start→complete span, which the scripts stamp exactly. The per-task timestamps are best-effort — a single agent logs a task right after building it, so they reflect when you recorded it, not a precisely measured duration; that's fine, the summaries are the point. Still, record each finish as you go, wave by wave rather than dumping every task at the very end — a per-wave cadence keeps the panel live and the ordering true.
-
Never write the next step's start. Only the next command appends the next step's start entry; writing it here makes the viewer render a phantom "Generating …".