spec-while
v0.0.1
Published
Git-first task orchestrator for Spec Kit workspaces
Maintainers
Readme
spec-while
spec-while is a git-first task orchestrator built around a task source protocol.
It reads workflow settings from while.yaml, opens the configured task source, executes one task at a time, reviews the result, integrates approved work, and creates one git commit per completed task. The built-in task sources are spec-kit, which consumes spec.md, plan.md, and tasks.md under specs/<feature>/, and openspec, which consumes an OpenSpec change under openspec/changes/<change>/.
It also provides a standalone batch command for YAML-driven file processing that is independent from the feature/task orchestration workflow.
Requirements
- Node.js 18 or newer
- For
run: a git repository with an initial commit - For
run: a workspace with the directory layout required by the selected task source - For
run: the files required by the selected task source - For
run: a clean worktree beforerun
Current built-in source requirements:
task.source: spec-kitspecs/<feature>/spec.mdspecs/<feature>/plan.mdspecs/<feature>/tasks.mdtask.source: openspecopenspec/changes/<change>/proposal.mdopenspec/changes/<change>/design.mdopenspec/changes/<change>/tasks.md- At least one file under
openspec/changes/<change>/specs/**/*.md
Install
pnpm add -D spec-whileRun it with:
pnpm exec spec-while runConfiguration
while.yaml configures the run workflow only. When it is absent, the CLI runs task.source: spec-kit, task.maxIterations: 5, and workflow.mode: direct with codex for both roles.
task:
source: spec-kit
maxIterations: 5
workflow:
mode: direct
roles:
implementer:
provider: codex
reviewer:
provider: codexCurrent status:
workflow.mode: directuses a local reviewerworkflow.mode: pull-requestpushes a task branch, polls GitHub PR review fromchatgpt-codex-connector[bot], then squash-merges on approvaltask.maxIterationsapplies globally to every task in the selected source session
Example pull-request mode:
workflow:
mode: pull-request
roles:
implementer:
provider: codex
reviewer:
provider: codexCommands
spec-while run
Runs the current feature workflow from the existing .while state or initializes a new one. Run it from the workspace root so the current directory contains the source-specific root, such as specs/ for spec-kit or openspec/changes/ for openspec.
cd /path/to/workspace
pnpm exec spec-while run --feature 001-demoUseful flags:
--feature <featureId>: select the feature explicitly- For
task.source: openspec,--feature <featureId>selects the OpenSpec change id --until-task <taskSelector>: stop after the target task reachesdone--verbose: stream agent events tostderr
spec-while batch
Runs a standalone YAML-driven batch job. This command does not read while.yaml, does not require specs/, and does not use the task-source workflow.
cd /path/to/workspace
pnpm exec spec-while batch --config ./batch.yamlBatch config example:
provider: codex
workdir: ./src
prompt: |
Read the target file and return structured output for it.
schema:
type: object
properties:
summary:
type: string
tags:
type: array
items:
type: string
required:
- summaryBatch behavior:
workdirdefaults to the current working directory when omittedprovider,prompt, andschemaare required- each run scans the configured working directory for files
- execution state is written beside the YAML file in
state.json - structured results are written beside the YAML file in
results.json --verboseprints per-file failure reasons tostderr- rerunning the command resumes unfinished work and skips files that already have accepted results
- when the current
pendingqueue is exhausted andfailedis non-empty, the command persists a recycle transition that movesfailedback intopendingfor the next round - the command exits only when both
pendingandfailedare empty - there is no retry limit for file-level failures; failed files continue to be retried round by round
claudeis accepted as a provider value, but no batch adapter is configured by default in CLI mode
Task Lifecycle
Each task follows this lifecycle:
- The implement role receives a task-source-built prompt for the current task.
- The reviewer evaluates the task-source-built review prompt plus changed-file context and overall risk.
- If review is approved,
spec-whileasks the task source to apply its completion marker, creates the final integration commit, and records integrate artifacts under.while.
In pull-request mode:
- review creates or reuses
task/<slug>and an open PR againstmain - if an open PR exists but the local task branch is missing, review restores the branch from
origin/task/<slug> - review creates a checkpoint commit with
checkpoint: Task <taskId>: <title> (attempt <n>) - review polls every minute with no default timeout
- review evaluates approval from a fully paginated live GraphQL PR snapshot
- approval is driven by the freshest
chatgpt-codex-connector[bot]signal after the checkpoint commit - process restart re-enters
revieworintegrateand continues the same PR flow - integrate checks the task source completion marker, creates the final task commit when needed, squash-merges, returns to
main, and deletes the local task branch
Completion is git-first:
- one completed task = one git commit
.whileis runtime state and is not committed
Built-in spec-kit Expectations
The built-in spec-kit task source parses raw Spec Kit task lines in file order. It does not require enhanced per-task metadata blocks.
Example:
## Phase 1: Core
- [ ] T001 Implement greeting
- [ ] T002 [P] Implement farewell
- [ ] T010 [P] [US1] Add scenario coverageCurrent built-in spec-kit behavior:
- task ordering follows the order in
tasks.md - explicit task dependencies are not extracted from raw task lines
- implement/review prompts include the current task line, the current phase,
spec.md,plan.md, and the fulltasks.md - completion is still written back through
tasks.mdcheckboxes
Built-in openspec Expectations
The built-in openspec task source consumes an existing OpenSpec change directory and aligns implement/review prompts with openspec instructions apply --json.
Example configuration:
task:
source: openspec
maxIterations: 5Example run:
pnpm exec spec-while run --feature example-changeCurrent built-in openspec behavior:
--featuremaps toopenspec/changes/<change>- stable task handles come from explicit numbering in
tasks.md, such as1.1and2.3 - implement/review prompts include the current task, task group,
proposal.md,design.md, expandedspecs/**/*.md, fulltasks.md, and the OpenSpec apply instruction/state/progress - completion is still written by
spec-whileafter review/integrate success; it does not adopt/opsx:apply's immediate checkbox update behavior spec-whileconsumes OpenSpec artifacts and CLI JSON, but it does not run/opsx:propose
Task retry budget is configured globally in while.yaml:
task:
maxIterations: 2What spec-while Does Not Do
spec-while does not replace Spec Kit's project-level workflow. It does not run Spec Kit commands, checklists, hooks, or preset-installed skills.
Its contract with the selected task source is simple:
- the task source parses source artifacts and provides prompts plus completion operations
spec-whileorchestrates implement, review, integrate, and persistence around that protocol
The standalone batch command is separate from this contract. It does not use task sources, task graphs, review/integrate stages, or git-first completion.
Runtime Layout
run keeps runtime state under:
<source-entry>/<id>/.while/Important files:
state.jsongraph.jsonreport.jsonevents.jsonltasks/<taskHandle>/g<generation>/a<attempt>/implement.jsontasks/<taskHandle>/g<generation>/a<attempt>/review.jsontasks/<taskHandle>/g<generation>/a<attempt>/integrate.json
batch keeps runtime files beside the YAML config:
<config-dir>/
├── batch.yaml
├── state.json
└── results.jsonstate.json contains:
pendinginProgressfailed
failed is the current round's failure buffer. When pending becomes empty, those paths are persisted back into pending and retried in the next round. Historical state entries whose files no longer exist are dropped when a new run starts.
results.json maps file paths relative to workdir to accepted structured output.
Publishing
Before publishing:
pnpm lint
pnpm typecheck
AI_AGENT=1 pnpm test
AI_AGENT=1 pnpm tsx fixtures/smoke/codex-e2e.ts
npm pack --dry-run