Repository navigation
Releases: vankhangfet/orca-sdlc-kit
Release list
v3.3.0 - Artifact viewer
Artifact viewer on the status page
Every step row and artifact chip on the live status page is now a link to the
Markdown file it produced. Click one and the right pane switches to a
preformatted viewer — styled <pre>, no Markdown engine — showing the text
with file size, freshness and the owning step's status. Still zero-dependency:
no server, no ports, nothing to refresh.
Full changelog: v3.2.0...v3.3.0
v3.2.0 — Worktree auto-create
v3.2.0 — Worktree auto-create
Running the flow from outside an Orca worktree no longer dead-ends. When no worktree is pinned and orca worktree current fails on a real run, the flow now offers to create a fresh Orca-managed worktree and continues the pipeline inside it.
Highlights
- Interactive ask, or explicit opt-in. Interactive terminals get a [y/N] confirm showing the worktree name, short HEAD SHA, and a warning that uncommitted changes will not follow. CI/non-interactive runs create only with --create-worktree or "defaults": { "autoCreateWorktree": true } — otherwise the original hard-fail (with fix hint) is preserved exactly.
- Predictable naming. flow-- — e.g. "Thêm trang đăng nhập" → flow-them-trang-dang-nhap-20260924-101530. Diacritic-safe slugs (NFD mark strip + đ→d, 24-char cap).
- Based on your current HEAD. Created via orca worktree create --repo path: --base-branch --no-parent; the run banner reports "created this run" and the end-of-run summary prints the exact orca worktree rm cleanup command (the worktree is kept — artifacts, status page, and run history live inside it).
- Safe by default. Never fires when a worktree is pinned, when auto-detect succeeds, or during --dry-run / --status-preview. A new hard gate dies cleanly (instead of silently degrading) if a created worktree's path can't be resolved — this also fixes a latent silent "."-fallback hole.
New in configuration
| Key / flag | Default | Effect |
|---|---|---|
| --create-worktree | — | One-off: create the worktree without asking |
| defaults.autoCreateWorktree | false | Same, persisted — in all six shipped configs |
Quality
- E2E suite grew 529 → 552 assertions (all passing): E1a (flag path — name scheme, exact repo selector, HEAD base, --no-parent, agents dispatched into the created worktree, cleanup hint, đ slug), E1b (no-consent keeps the old die + new hint), E1c (config consent).
- Docs: CONFIGURATION.md (defaults + flags tables), usage header, //autoCreateWorktree comment keys in every shipped config.
Full changelog: compare v3.1.0...v3.2.0
v3.1.0 — Agent skills & MCP configuration
v3.1.0 — Agent skills & MCP configuration
Give any workflow agent extra capabilities without hard-coding them in its spec:
declare reusable skills and MCP servers in the pipeline config, and the
flow delivers them to each agent harness in its own native format — writing
standard config files into the worktree before the step runs and cleaning them
up afterwards.
What's new
Two top-level registries + two per-step reference fields:
{
"skills": {
"commit-style": { "path": "skills/commit-style" }, // SKILL.md folder or single .md
"review-checklist": { "description": "...", "prompt": "..." } // or fully inline
},
"mcpServers": {
"github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "${env:GITHUB_TOKEN}" } }, // stdio
"docs": { "url": "https://mcp.example.com/sse",
"headers": { "Authorization": "Bearer ${env:MCP_TOKEN}" } } // remote
},
"pipeline": [
{ "id": "coding", "agent": "claude", "spec": "...",
"skills": ["commit-style"], "mcp": ["github"] }
]
}
Per-harness delivery (written into the worktree before the group runs,
removed after — a crashed run is cleaned up by the next one):
| agent | MCP | skills |
|----------|---------------------------------|--------------------------------|
| claude | .mcp.json | .claude/skills/<name>/SKILL.md |
| cursor | .cursor/mcp.json | .cursor/rules/<name>.mdc |
| gemini | .gemini/settings.json (merged) | GEMINI.md (marked section) |
| opencode | opencode.json (merged, mcp key) | AGENTS.md (marked section) |
| codex | not supported (warn + skip) | AGENTS.md (marked section) |
## Behavior highlights
- Validated at load (12 die-rules) — schema XOR rules, registry refs, path
and type guards. Typos die in --dry-run, never mid-pipeline.
- Secrets stay out of the config — ${env:VAR} expands at write time in
command/args/env/url/headers; an unset variable warns and becomes
an empty string.
- Parallel-safe — parallel steps share the worktree, so their refs are
unioned into one file.
- Never clobbers your files — pre-existing configs are merged (JSON) or
appended to (markdown, between <!-- orca-agent-config BEGIN/END -->
markers) and restored verbatim afterwards; a pre-existing skill folder is
kept, never overwritten (warn + skip).
- --agent overrides honored — --agent coding=codex switches the
materialized harness along with the launched one.
- Crash-safe and contained — everything written is tracked in a manifest
(.orca-agent-config.json, flushed on every touch), restored after every
step group, self-healed at startup after crashes, and hard-contained to the
worktree (hostile manifests can never touch paths outside it).
- Unknown agents get a warn and no files — the run is never killed for it.
## Upgrade notes
- Fully backward compatible — configs without skills/mcpServers behave
exactly as before.
- npx github:vankhangfet/orca-sdlc-kit now ships .orca/agent-config.mjs
(used by existing installs only after --force or when the file is missing).
- Docs: see .orca/CONFIGURATION.md → "Skills & MCP servers".v3.0.0 — Workflow Designer: build and edit pipelines in the browser
The kit grows from a terminal-only engine into engine + browser UI. One command opens a local web app where the whole workflow is configured visually — no JSON hand-editing, no code:
node .orca/designer.mjs # opens http://127.0.0.1:7887/?t=
Highlights
- Visual pipeline editor — every step as a card in run order (drag to reorder), a full form per step: agent, model, writes, spec, reads, timeouts, nudge, onFailGoto, parallelWith, flags. Advisory validation mirrors flow.mjs load-time checks (unknown/chained/non-contiguous parallelWith, forward reads, disabled targets, id-less steps, nudge ranges) and shows issues as badges on the cards — advisory only, never blocking.
- Creates AND edits — every *.config.json in .orca/ and .orca/workflow-template/, from blank, from any shipped template, or by duplicating the current one. // comment keys in existing files survive every save.
- Dry-run button — runs flow.mjs --dry-run against the file on disk and shows the plan (or the exact validation error) in place.
- Run-command bar — the exact node .orca/flow.mjs ... command for the workflow being edited, with your objective filled in; click to copy. Real runs stay in your terminal.
- Configure defaults tab — pipeline-wide knobs (maxRetries, autoRun, model, timeouts, readiness, nudge, openStatus) edited next to the steps.
- New project tab — scaffolds a fresh workspace in any folder: copies the kit, drops in your first workflow config, prints the commands to run.
- Redesigned UI — token-based theme, restructured toolbar with the run command in its own zone, a dismissible 3-step guide (Pipeline → Configure defaults → New project), Comfortable/Compact density toggle (auto-tightens for 8+ step pipelines), and keyboard shortcuts: S save · R dry-run · D density · ? legend.
Safety model
Binds 127.0.0.1 only; every request guarded by a per-launch token; saves are atomic and jailed to .orca/; zero dependencies; flow.mjs itself never serves anything — the engine and the shipped configs are untouched.
v2.3.1 — Per-step retry budgets
A step that loops back via onFailGoto can now declare its own "maxRetries" — that step's fix loop uses the step's budget instead of the pipeline-wide default. One long loop no longer inflates every other edge's retry budget.
Why
Loop-controller pipelines (Planning → Development → Review → back to Planning) need many rounds on one edge — but the pipeline-wide maxRetries: 2 capped every loop alike, and raising it globally inflated every other fix loop (review→coding, security→coding, test→coding).
Usage
{ "maxRetries": 2, // pipeline-wide default, unchanged
"pipeline": [
{ "id": "planning", "onFailGoto": "development", "maxRetries": 20, ... },
{ "id": "review", "onFailGoto": "coding", ... } // keeps the global 2
] }
- Resolution: step.maxRetries ?? global maxRetries ?? 2. The budget belongs to the step declaring onFailGoto (the failing step), matching the edge-keyed retry counter.
- 0 is legal — fail fast, never loop (first failure stops the run).
- Validated at load: a negative or fractional value (step-level or top-level) dies before any agent starts, with the offending value in the message.
- Visible in --dry-run: a declared budget renders as onFail-> xN (e.g. onFail->development x20).
Compatibility
Configs that don't set a per-step maxRetries behave exactly as before — byte-identical logs, same default budget. All shipped pipelines are untouched.
Tests
New E2E pins: E32 (step budget 3 over global 1 — attempts n/3, exhaustion at 3, bounded 8 worker-starts), F13/F13b (load-time validation), F14 (dry-run xN rendering + no global-budget leak). Existing retry pins E7/E8/E31 unchanged. Full suite: 347/347.
Full changelog: README What's new + ROADMAP.md (Shipped, v2.3.1 row).
v2.3.0 — Support Parallel reviews ( Code review, Security review)
v2.3.0 — Parallel reviews
Code review and security review now run at the same time. Both shipped SDLC pipelines (flow.config.json + workflow-template/sdlc.config.json) launch the two reviewers concurrently off the same coding output — the happy path pays one review round instead of two.
What changed
- One line per config: "parallelWith": "code-review" on security-review — the existing parallelWith mechanism (v1.3.0), engine untouched
- Both review workers start together; testing stays the join barrier (reads both verdicts, readiness-gated ≥ 200 bytes each)
- Failure semantics: either review FAILing loops back to coding with a fix note; after the fix the whole review group re-runs — a fix can disturb either aspect, so both look again (previously a security fail already re-ran code-review; now the doctrine is symmetric). Bounded by maxRetries (default 2)
- Docs updated: README (What's new, feature line, Mermaid), CONFIGURATION.md §3.9 (second shipped pair + how to skip one member), ROADMAP v2.3.0 row
Upgrading
npx re-init keeps your existing configs unless --force — to get parallel reviews on an existing install, add "parallelWith": "code-review" to security-review in your flow.config.json (and workflow-template/sdlc.config.json if you use it). To skip one member of a parallel pair, also remove the parallelWith line.
Known edge (queued engine follow-up)
A definite FAIL in a parallel group currently preempts the stop for a hard-capped still-running sibling (pre-existing outcome ordering, first reachable now that reviews run ∥ with onFailGoto members). Hardening queued in the roadmap: still-running outranks the jump. Rare trigger, recoverable.
Testing
New E2E E31 pins the group semantics (concurrent launch, fix note, whole-group re-dispatch on retry, join barrier). Suite 328/328 (315 from v2.2.0 + 13 new), fully offline.
Includes
v2.2.0 — Run history + startup resume chooser
v2.2.0 — Run history + startup resume chooser
Features
- Run history — per-run artifact snapshots. Every NEW run copies the previous run's flat artifacts into
.orca/artifacts/runs/<seq>-<timestamp>/before its own steps write anything — a COPY, so the flat layout and its readiness/--fromresume semantics are exactly what they always were. Each folder keeps the run's artifacts plus itsstatus.js(objective, per-step outcomes, token usage), so any two runs compare side by side long after the second one overwrote the first. Copy failures warn and never block a run; the folder is gitignored; nothing is pruned automatically. - Startup resume chooser. When previous runs exist and none of
--from/--only/--newwas passed, the flow lists the 10 newest runs (newest first, the current flat state labeled(current); objective, steps-succeeded and overall verdict per line) and asks before starting:<n>— resume that run. Archived entries archive the current flat state FIRST, then restore the chosen run's artifacts (copy-over, non-destructive); the resume point is the first enabled step not recordedsucceeded— an automatic--fromreusing all existing resume machinery.0, Enter, or EOF — start a NEW run. Piped stdin (scripts, CI) closes with EOF, so automated invocations never block on the prompt.- Picking a completed run starts a fresh run instead (noted in the log).
--newflag — skip the chooser, always start a new run (the snapshot of the previous run still happens).- Dry-run now lists the worktree's previous runs read-only above the plan.
Bug fixes
- Chooser input is strictly validated (
/^\d+$/): garbage like1x,+1, or an out-of-range number starts a NEW run — never silently resumes the wrong entry (prefix-parsing would have picked entry 1). - The E2E harness no longer silently runs the FULL suite on an empty or zero-match
--onlyfilter — both now fail fast with a clear message. - A failed snapshot no longer consumes a sequence number (the empty folder is removed).
Documentation
.orca/CONFIGURATION.md: new "Run history (per-run snapshots)" subsection; section 5.5 "The startup run chooser (resume a previous run)" (trigger, listing, selection semantics incl. copy-over restore and the chooser-before-config-error note);--newrow in the flags table.README.md: run-snapshot sentence on the "Everything is left on disk" bullet; "Resuming runs" note; troubleshooting entry for picking the wrong run.ROADMAP.md: v2.2.0 shipped row; the queued status-page run selector remains open (disk side shipped).
v2.1.0 - Nudge: auto-retry for missing artifacts
v2.1.0 — Nudge: auto-retry for missing artifacts
Features
- Nudge — auto-retry for missing artifacts. A worker that reports completion (or stalls mid-run) without writing its declared artifact now gets its own terminal nudged to write the file — reusing the warm session's context instead of paying a full re-dispatch.
- Mid-run trigger: preview frozen ≥
nudgeTimeoutMsAND dispatch heartbeat stale ≥nudgeTimeoutMs(fallback: frozen preview alone when the host reports no heartbeat), artifact missing, noworker_doneyet. - Post-settlement trigger:
worker_donearrived but the artifact file is missing — the flow keeps the terminal open, nudges, and polls for the file. - One shared budget per step per dispatch — both triggers draw from
nudgeRetries(default2;0disables the feature for that step).nudgeTimeoutMs(default120000) is dual-role: the mid-run idle threshold and the per-attempt post-nudge wait. - Cold-path workers included — the terminal id is resolved via
orchestration worker-showand cached, so cold-started workers can be nudged and their terminal closed at settlement. - Delivery reuses the start ladder's paste-chip defense —
terminal send, then a bare Enter 3 s later.
- Mid-run trigger: preview frozen ≥
- New config fields:
nudgeRetries/nudgeTimeoutMsatdefaultsand per step, validated at load time (non-negative integers; timeout must be positive). All six shipped pipelines declare both tunables explicitly. - Ground-truth outcomes (the artifact file, not
worker_done, decides):- file recovered → the step settles with the worker's original outcome, note
artifact recovered via nudge (N sent); - budget exhausted or hard cap during the post-done wait →
failed(artifact missing after N nudge(s)), flowing intoonFailGotofix loops or the--fromresume hint; - structurally-remedyless paths (disabled / undeliverable / send failed / no terminal / terminal parked) keep the original outcome with a named note — the consumer-side readiness gate remains the safety net;
- mid-run nudges never fail a step by themselves.
- file recovered → the step settles with the worker's original outcome, note
- Parked-dialog safety: a terminal parked on a human-only dialog (permission rule, folder trust, CLI update) is NEVER typed into — a live preview check precedes every send: mid-run attempts, the first post-done nudge, and every re-nudge.
Bug fixes
- A failed mid-run nudge send no longer corrupts the settlement verdict: the budget-closed-without-delivery case (
nudge undeliverable) keeps the worker's original outcome instead of failing the step with a self-contradictory "after 0 nudge(s)" note. - A dialog that parks between post-done nudges no longer receives the re-nudge (and its bare Enter could submit the dialog's default) — the re-nudge is suppressed and the step settles with the original outcome plus a
(terminal parked on …)note. - E2E suite fixture (manual-path green run) now leaves the artifact behind on
worker_donelike a real worker would, matching the fake-orca contract the default handler already follows. - E22 hard-cap scenario gained a
still-runningstatus discriminator (a crash no longer passes as a hard-cap stop) and a watchdog margin in line with the suite's hard-cap norm.
Documentation
.orca/CONFIGURATION.md: new "Nudge (auto-retry for missing artifacts)" section — field table, both triggers, outcome rules with the engine's exact status-note literals (all 8 variants), parked-dialog safety, and manual-mode interactive-step guidance (raisenudgeTimeoutMsor setnudgeRetries: 0); plusdefaults.nudgeRetries/defaults.nudgeTimeoutMsrows in the field-reference table.README.md: feature bullet ("Nudge (auto-retry)") and a troubleshooting entry forartifact missing after N nudge(s).ROADMAP.md: current release bumped to v2.1.0; Shipped row with the full summary.
v2.0.0 -Readiness Gate: never launch a step on unready inputs
What's new
Readiness Gate: never launch a step on unready inputs
Why
The coding step could be dispatched while its inputs — detailed-design /
uiux-design — were missing or empty. The engine only injected artifact paths
into the prompt and never checked the files, so the agent ran blind, stalled,
and burned the 2-hour hard cap. Two root causes:
- Resume hole:
--from/--onlysilently dropped a read whose artifact
file was missing, so the consumer launched with "(no prior input)". - Lying success: a step could report
outcome=succeededwhile writing an
empty/truncated artifact — nothing validated the file before consumers ran.
Pre-flight readiness check
Before each run-order group launches, every member's declared reads are
verified on disk: the artifact must exist and be at least
defaults.readinessMinBytes (200 bytes).
Ask, then repair — retry default 3
When an input is unready, the flow prints the list and asks at the terminal:
Missing or incomplete input artifact(s):
- Detailed Design (`.orca/artifacts/DETAILED_DESIGN.md`) — missing — needed by "Coding"
Run the producing step(s) now to (re)generate missing inputs? [y/N]
- Asked even in auto-run — input safety is not agent autonomy.
Piped/CI stdin (EOF) counts as "no". - Decline stops the run immediately with the exact
node .orca/flow.mjs --from <producer> "<objective>"command to resume. - Accept re-runs ONLY the missing producers — singleton groups (parallel
siblings are not re-run), transitively up the read chain in pipeline
order — up todefaults.readinessRetries(3 default) attempts.
The artifact file is ground truth; a worker's claimed outcome doesn't count. - No blind re-dispatch: an indefinite outcome (unknown) during repair stops
the run instead of risking a double dispatch.
Config (2 new defaults fields)
| Field | Default | Meaning |
|---|---|---|
readinessRetries |
3 | Repair attempts per missing producer before aborting |
readinessMinBytes |
200 | Minimum artifact size to count as ready input |
Stricter config validation (load time, every mode)
- Reads pointing at a later in-run step die: "reorder the pipeline".
- Reads of a step with no
writesdie fast (previously a raw TypeError
crash at dispatch time).
Exemptions
- Reads of
enabled: falsesteps (e.g. the optionalgrillinterview) are
optional inputs — never gated, matching the config contract. - Dry-run and
--status-previeware untouched.
Breaking / behavioral (why the major bump)
- A run now stops (with a resume hint) where it previously launched a
consumer against missing/empty inputs. - Previously-accepted configs with forward reads or writes-less reads are
rejected at load.
Tests
15 new E2E scenarios (E12–E18, F10/F11) covering decline-abort, repair,
transitive chains, retry exhaustion, unknown-outcome safety, undersized
artifacts, repair hangs, and disabled-producer exemption — including E18,
the suite's first real run of the shipped default config on a fresh worktree.
Full suite: 216/216 (merged with the v1.7.0 notifications line).
Docs
.orca/CONFIGURATION.md— new fields + "Readiness gate" subsectionTROUBLESHOOTING.md— "Missing or incomplete input artifact(s)" entry
Install fix (re-tag, 2026-09-18)
The original v2.0.0 tag shipped a broken npx install: bin/init.mjs
created only the top-level .orca/ directory, so the newly added
.orca/workflow-template/* files failed with copy failed: ENOENT ... .orca\workflow-template\README.md on a fresh install (after a partial
copy of seven files). The tag is re-pointed to the fix (ad5845f): the
installer now creates each file's parent directory before writing.
If npx github:vankhangfet/orca-sdlc-kit failed with that error, simply
re-run the same command — it fills in whatever is missing (existing files
are kept; --force overwrites). Pinned by new E2E scenarios I1 (real
installer run into an empty project) and I2 (FILES ↔ package.json files
sync guard); suite 233/233.
v1.7.0- Support push notification
What's new
The pipeline now reports itself
Every step settlement and the final run verdict can be pushed straight to your chat while the pipeline runs. Configure it in .orca/notify.json — shipped empty, meaning off until you fill it in:
{ "enabled": true, "provider": "slack",
"url": "https://hooks.slack.com/services/...",
"token": "", "chatId": "", "to": "", "events": ["step", "run"] }
What you get
- Step + run events — every settlement (succeeded / failed / still-running / unknown; retries notify per attempt) plus one run-end summary with overall status, objective, duration and — on failure — the exact safe --from resume command. "events" toggles them ([] = off; slow endpoints → ["run"]).
- Four bundled providers + escape hatch — Slack, Telegram (bot URL + chatId), MS Teams (Workflows webhook, Adaptive Card), WhatsApp (Graph API + token/to), or any generic JSON webhook with the full structured payload.
- Never blocks, never alters the run — delivery runs in a timeout-guarded child process (9s abort / 12s hard cap per event). The first hard failure warns once with a secrets-free reason (HTTP 401, connect ECONNREFUSED, …) and disables further attempts for that run; exit codes and settlement semantics are untouched, and the final message of a dying run is still attempted.
- Safe resume hints — a failed step resumes from itself; a worker still alive in its terminal resumes from the next step (re-dispatching a live worker is forbidden — including the mixed parallel-group corner). Mirrors the console's advice exactly.
- Secrets hygiene — webhook URLs and tokens travel via stdin, never in argv or logs. Gitignore the file after filling it in; the empty template is safe to commit.
- --dry-run prints the resolved state (Notifications: on (slack, events: step,run)) and sends nothing. ORCA_FLOW_NOTIFY_FILE overrides the config path.