jdi
just-do-it Workflow Orchestrator
Core Rules
- ONE STEP PER INVOCATION — NEVER LOOP. Each
/jdi runexecutes exactly ONE workflow step, writes status, and STOPS. Do NOT proceed to the next step. Do NOT execute multiple steps. The caller (user or external loop) is responsible for invoking/jdi runagain. This is the fundamental design contract — violating it defeats the entire purpose of the orchestrator (context isolation, human oversight, resumability). After writing.jdi/statusin step 11, you are DONE. Return immediately. - Task completion is controlled exclusively by the Finalize phase. Never set
status: completedanywhere else. Premature completion corrupts the task queue. - Always delegate to sub-agents via Agent tool. Default agent:
general-purpose. The orchestrator never performs task work itself. - Archive completed tasks. Move from
.jdi/tasks/to.jdi/archived/. - Write status to
.jdi/status. Every exit path must write one of:CONTINUE,STEP_COMPLETE step={name},WORKFLOW_COMPLETE,ABORT,HUMAN_REQUIRED.
Task File Format
Each task is .jdi/tasks/NNN-slug.yaml:
title: Set up database schema
description: |
Create the initial database schema...
status: pending # pending | in_progress | completed
depends_on: [] # task filenames, e.g. ["001-setup.yaml"]
current_step: null # workflow step name, or null
feedback: null # review feedback
Commands
| Command | Usage | Description |
|---|---|---|
run |
/jdi run [--workflow NAME] [--task ID] [--human] |
Execute one workflow step |
init |
/jdi init |
Interactive setup |
add |
/jdi add <spec-path> [--depends-on FILE1,FILE2] |
Create task from spec |
Parse $ARGUMENTS — $0 is the subcommand. Empty/unrecognized → show usage.
run Command
Execute exactly ONE workflow step, then exit. NEVER execute a second step. Caller handles looping. After writing .jdi/status, STOP and return control to the caller immediately.
Execution Flow
-
Load config — first file found wins (no merging):
.jdi/config.local.yaml→.jdi/config.yaml→~/.config/jdi/config.yaml→ defaults (default_workflow: default.yaml). CLI flags override. -
Load workflow
--workflow: try as path, then.jdi/workflows/- Otherwise:
default_workflowfrom config - Validate (see references/workflow-schema.md). Record
workflow_dirfor resolvingprompt_file/format_file.
-
Get current task
--task ID: read.jdi/tasks/{ID}directly- Otherwise: first
status: pendingtask whosedepends_onfiles all exist in.jdi/archived/. Set toin_progress. in_progresstasks are valid — resume from prior session- No tasks → write
WORKFLOW_COMPLETEto.jdi/status, exit - Define
{task_id}: The task's filename without the.yamlextension (e.g.,001-add-goal.yaml→task_id = 001-add-goal). All references to{task_id}in subsequent steps use this value. Do NOT use a run counter or numeric ID.
-
Determine current step
- Read task's
current_step nullor unknown → default to first workflow step, update task file. This is normal, not an error.
- Read task's
-
Initialize orchestrator log
- Create
.jdi/reports/{task_id}/orchestrator.mdwith preamble if it doesn't exist (useWrite). See references/orchestrator-log-format.md. - Print:
Orchestrator log: .jdi/reports/{task_id}/orchestrator.md
- Create
-
Human gate
step.human === trueAND no--human→ writeHUMAN_REQUIREDto.jdi/status, append⏸ PAUSEDto log, exit
-
Execute step
- Resolve file references (
prompt_file,format_file— relative toworkflow_dir). Both inline and file present → ABORT. - Standard step (has
prompt/prompt_file, noparallel):- Build prompt: task context (title, description, feedback) + step prompt
- Append:
Include a "## Summary" section (2-4 sentences) at the end summarizing what you did and the outcome. - If
report.format: appendWrite your report strictly following this template's structure AND language:\n\n{format} - Agent: step's
agentfield, defaultgeneral-purpose - Execute via Agent tool, capture output. No output → ABORT.
- Parallel step (has
parallelarray):- For each branch in
parallel: resolve itsprompt/prompt_file, build prompt with task context + branch prompt + summary/format instructions (same as standard step). - Dispatch all branches concurrently via parallel Agent tool calls, each with its branch's agent (default
general-purpose). - Collect all outputs. Any branch returning no output → ABORT.
- Concatenate all branch outputs (separated by
\n\n---\n\n) into a single combined output for subsequent steps (validation, report, conditions). checkfield determines pass/fail:all= every branch must pass.
- For each branch in
- Resolve file references (
-
Validate output (only if
report.validationexists)- Run
scripts/validate_output.py <pattern> <temp_file>(script path relative to skill install directory) - Fail → ABORT
- Capture matched keywords
- Run
-
Write report (only if
reportexists)- Write in the same natural language as the format template (e.g., Japanese template → Japanese report). First run →
Write; subsequent →Bashwith>>append - Format:
## YYYY-MM-DD HH:MM:SS\n\n{output}\n\n--- - Target:
.jdi/reports/{task_id}/{report.name}.md
- Write in the same natural language as the format template (e.g., Japanese template → Japanese report). First run →
-
Evaluate & update
-
Re-read workflow YAML. Check step's
endandconditions. -
Multiple keywords → different conditions = ABORT. Invalid goto target → ABORT.
-
Determine decision:
end: true?Condition redirects? TASK_DONE?Decision Yes No — COMPLETE Yes Yes — CONTINUE No — Yes COMPLETE No — No CONTINUE -
If CONTINUE: update
current_stepto next step. If a condition redirected (goto fired): append agent output to task'sfeedback. -
After write: re-read and verify
status: in_progress+ correctcurrent_step. Fail → ABORT. -
Append step entry to orchestrator log —
Bashwith>>heredoc (preserves inode fortail -f). Extract## Summaryfrom output (or(no summary provided)). See references/orchestrator-log-format.md.
-
-
Finalize
- COMPLETE (only when step 10 determined COMPLETE):
- Print:
✓ Completing: step={name} end={true/false} keywords={matched} reason={reason} - Set
status: completed, clearcurrent_step, move task to.jdi/archived/ - Append completion entry to log
- Write
.jdi/reports/{task_id}/summary.md(same language as templates) - Write
STEP_COMPLETE step={name}to.jdi/status
- Print:
- ABORT: write
ABORTto.jdi/status - CONTINUE: write
CONTINUEto.jdi/status
- COMPLETE (only when step 10 determined COMPLETE):
init Command
- Copy
assets/templates/jdi_template/to./.jdi/ - Create
.jdi/tasks/and.jdi/archived/ - Ask for default workflow name → update
config.yaml
add Command
/jdi add <spec-path> [--depends-on FILE1,FILE2]
- Read spec file, extract title from first heading/line
- Read the full spec to generate an accurate task description:
- Summarize what the spec covers (backend API, frontend UI, or both)
- Reference the spec file path
- Do NOT narrow the scope — if the spec includes UI/frontend sections, mention them. The description must reflect the spec's full scope, not just one aspect.
- Example: "Implement the AddGoal feature: backend command slice (events, handler, route, tests) and frontend UI (quick-add bar, full form with validation). Spec: path/to/spec.md"
- Next number: max prefix in
.jdi/tasks/*.yaml+ 1, zero-padded to 3 digits - Slug: lowercase, hyphenated, alphanumeric
- Create
.jdi/tasks/NNN-slug.yamlwithstatus: pending - Set
depends_onif--depends-onprovided - Print:
Created task: NNN-slug.yaml