jdi
npx skills add https://github.com/craftell/agent-skills --skill jdi
Agent 安装分布
Skill 文档
just-do-it Workflow Orchestrator
CRITICAL RULE â Task Completion
NEVER mark a task as complete unless the workflow has fully finished for that task. Premature completion corrupts the task queue and causes subsequent /task-management next calls to skip unfinished work.
Mandatory Checklist â Before calling /task-management complete
You MUST answer all three questions YES. If ANY answer is NO â write CONTINUE, do NOT complete.
- Did the guard script in step 11 return
COMPLETE? (Not CONTINUE, not ABORT) - Is the current step’s
endfield set totruein the workflow YAML, OR didTASK_DONEappear in the matched keywords? - Did NO condition in the current step redirect to another step?
Common Mistakes to Avoid
- The sub-agent says “Done! Task complete.” â This does NOT mean the workflow is complete. The agent is reporting its step output. Only the workflow structure (
end: true/TASK_DONE) determines completion. - You finished executing step “implement” and it succeeded â The workflow has more steps (review, finalize). Write
CONTINUE. - You are executing inline (no agent) and finished the work â You finished the STEP, not the workflow. Check the workflow structure.
When executing inline (no agent), be especially careful: the orchestrator must NOT use its own task management tools (TaskUpdate, TaskCreate, etc.) to alter task status outside of the workflow’s explicit completion path in step 15.
CRITICAL RULE â Lock Cleanup
ALWAYS release the lock file before exiting. A leftover lock file permanently blocks all subsequent loop iterations, killing the entire workflow. This is never acceptable.
Once the lock is acquired (step 7), step 16 (release lock) is a mandatory finally block â it MUST execute regardless of success, failure, abort, or any error in steps 8â15. There are no exceptions. Every code path after step 7 must reach step 16.
When any step in 8â15 encounters an error:
- Perform the error handling for that step (write ABORT, log error, etc.)
- Then unconditionally proceed to step 16 to release the lock
- Only after the lock is deleted may the orchestrator exit
Never exit, abort, or return between steps 7 and 16 without deleting the lock file.
Argument Parsing
The subcommand is $0 (first argument). Parse $ARGUMENTS to extract command and options:
| Command | Usage | Description |
|---|---|---|
run |
/jdi run [--workflow NAME] [--task ID] [--human] |
Execute one workflow step |
init |
/jdi init |
Interactive setup |
status |
/jdi status |
Show current state |
apply-lessons |
/jdi apply-lessons |
Promote lessons to rules |
Parsing flags from $ARGUMENTS:
--workflow NAME: Extract workflow name/path after--workflow--task ID: Extract task ID after--task--human: Boolean flag, true if present. Approves the next human-gated step.
If $0 is empty or unrecognized, show usage help.
run Command
Execute one workflow step, then exit. Caller handles looping.
Execution Flow
-
Check prerequisites
- Verify
task-managementskill exists (fail fast if not) - Verify
CLAUDE_CODE_TASK_LIST_IDis set (check environment variable). If not set, warn:â CLAUDE_CODE_TASK_LIST_ID is not set. Task list will not persist across sessions. Add it to .claude/settings.json â see init command. - Resolve config (first file found wins â no merging between layers):
.jdi/config.local.yamlâ use it.jdi/config.yamlâ use it~/.config/jdi/config.yamlâ use it- No file found â use all hardcoded defaults
- Parse the active file as YAML. If invalid YAML, error immediately (do NOT fall through).
- Apply hardcoded defaults for any missing keys:
task_skill: task-management default_workflow: default.yaml - Unknown keys are silently ignored.
- CLI flags (
--workflow,--task) override the resolved values.
- Verify
-
Load workflow
- If
--workflowspecified: try as file path, then lookup in.jdi/workflows/ - Otherwise: use
default_workflowfrom config (default:default.yaml) - Parse YAML, validate structure (see references/workflow-schema.md)
- If
-
Get current task
- If
--task IDspecified: use that task - Otherwise: invoke
/task-management next - If
NO_TASKS_AVAILABLEor task already complete: writeWORKFLOW_COMPLETEto status, exit
- If
-
Get task context
- Invoke
/task-management context - Parse current step from subject prefix (e.g.,
[review]â step isreview) - If no prefix or prefix doesn’t match a step name: use first step
- Invoke
-
Initialize orchestrator log
- Create
.jdi/reports/{task_id}/directory if needed - If
.jdi/reports/{task_id}/orchestrator.mddoes not exist:- Use
Writetool to create it with the preamble (see Orchestrator Log Format below) - This is the only time
Writeis used on this file â all later writes useBashwith>>to preserve the inode fortail -f
- Use
- If it already exists: skip (content from prior steps in the same task is preserved)
- Print:
Orchestrator log: .jdi/reports/{task_id}/orchestrator.md
- Create
-
Human gate check
- If
step.human === trueAND--humanflag is NOT present:- Write
HUMAN_REQUIREDto.jdi/status - Append a
⸠PAUSEDentry to the orchestrator log usingBashwith a heredoc and>>(preserves inode fortail -f) - Print:
ABORT: Step "{step_name}" requires --human flag. Run: /jdi run --human - Exit immediately. No lock acquired. No lock to release.
- Write
- If
step.human === trueAND--humanIS present: proceed normally - If
step.humanis not set orfalse: proceed normally regardless of--humanflag - Validation: If a parallel step has
human: trueon individual agents within theparallelblock, that is an invalid configuration â writeABORT, print validation error, exit (no lock held at this point)
- If
-
Acquire lock
- Check
.jdi/locks/{task_id}.lock - If the lock file exists:
- Read its contents (it contains a timestamp â see below)
- If the lock is older than 10 minutes: it is stale (the previous session likely crashed). Force-remove it, print
â Removed stale lock (created {timestamp}, age {N}m), and continue to acquire - If the lock is 10 minutes old or less: abort with lock error (another session is likely active)
- Create lock file containing the current ISO-8601 timestamp:
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > .jdi/locks/{task_id}.lock - From this point forward, step 16 (release lock) is mandatory. Every code path â success, error, or abort â must reach step 16 before exiting.
- Check
-
Execute step
- Find step definition in workflow
- Build prompt: task context + step prompt
- Append to every agent/inline prompt:
Include a "## Summary" section (2-4 sentences) at the end of your response summarizing what you did and the outcome. - If parallel step: use Task tool for each agent (run concurrently)
- Else if
agentis specified: use Task tool with step’s agent type - Else (no
agent): execute the prompt directly in the orchestrator context â do NOT use the Task tool. The orchestrator itself processes the prompt using its own tools and capabilities. Capture the result as the step output. CRITICAL: During inline execution, do NOT call/task-management completeor otherwise alter task status â task lifecycle is handled exclusively in step 15. REMINDER: Executing a step’s prompt inline means YOU are doing the step’s work. When you finish, you have completed THE STEP â not the workflow. Proceed to step 9 (validation) next. Do NOT call/task-management completehere. - Capture output
-
Validate output
- Write output to temp file
- Run
scripts/validate_output.py <pattern> <temp_file> - If validation fails (exit code 1): write ABORT status, log error entry, then proceed to step 16 (release lock)
- Capture matched keywords from stdout
-
Write report
- Create
.jdi/reports/{task_id}/directory if needed - Append output with a timestamp heading to preserve history across loops (e.g., review â revise â review):
- First run (file does not exist): use
Writetool to create the file - Subsequent runs (file already exists): use
Bashwith heredoc>>to append (preserves inode fortail -f)
- First run (file does not exist): use
- Each entry uses this format:
## YYYY-MM-DD HH:MM:SS {agent output} --- - Target file:
{step_name}.md(or{step_name}_{index}.mdfor parallel)
-
Evaluate conditions
-
Re-read the workflow file and find the current step definition. Check its
endfield andconditionsarray. Do NOT rely on memory or inference â read the actual YAML. -
Check matched keywords against step’s conditions
-
If multiple keywords match different conditions: write ABORT status, log error entry, then proceed to step 16 (release lock)
-
If
TASK_DONEin keywords: skip to completion -
Determine next step via conditions or
nextfield -
If
end: trueand no condition matches: workflow complete -
Completion vs continuation decision table:
Current step has end: true?Condition redirects to another step? TASK_DONEin keywords?Decision Yes No â COMPLETE Yes Yes â CONTINUE (condition wins) No â Yes COMPLETE No â No CONTINUE
-
-
Update task
- If transitioning to different step: invoke
/task-management update --step "new-step" - If rejected or error with feedback: invoke
/task-management update --feedback "..."
- If transitioning to different step: invoke
-
Record lessons (REJECTED only)
- Append to
.jdi/LESSONS.md:
## {date} - Task #{id}, Step: {step_name} **Trigger:** REJECTED **Lesson:** {rejection reason from output}- Note:
HUMAN_REQUIREDis expected control flow, not a failure. No lesson is recorded.
- Append to
-
Append to orchestrator log
- Target file:
.jdi/reports/{task_id}/orchestrator.md(already created in step 5) - Use
Bashwith a heredoc and>>to append. This preserves the file’s inode sotail -fcontinues to work. Example:cat >> .jdi/reports/{task_id}/orchestrator.md << 'ENTRY'\n{content}\nENTRY - For error/abort scenarios, use the error entry format instead
- Extract the
## Summarysection from the agent output for the entry’s summary block. If the agent did not include one, write> (no summary provided)instead. - Include the full agent output in a collapsible
<details>block after the summary blockquote (see Step Entry format below). This preserves complete context for debugging without cluttering thetail -fview.
- Target file:
-
Determine status and write
- CRITICAL: Only treat the workflow as “complete” when step 11 determined completion
(i.e.,
end: truewith no matching condition, orTASK_DONEkeyword matched). Do NOT infer completion from any other signal. When in doubt, writeCONTINUE. - If workflow complete (and ONLY then):
- Before invoking
/task-management complete, print:â Completing: step={step_name} end={true/false} keywords={matched} reason={end:true with no redirect / TASK_DONE} - Invoke
/task-management complete - Append the completion entry to the orchestrator log using
Bashwith heredoc>>(same inode-preserving pattern as step 14) - Write summary to
.jdi/reports/{task_id}/summary.md - Write
STEP_COMPLETE step={step_name}â this signals that one task’s workflow finished. The caller (bash loop) decides whether to continue to the next task or stop.
- Before invoking
- If error/abort: write
ABORT(the error entry was already written in step 14) - If more steps remain: write
CONTINUEâ do NOT invoke/task-management complete
- CRITICAL: Only treat the workflow as “complete” when step 11 determined completion
(i.e.,
-
Release lock (MANDATORY â always runs)
- This step is a finally block: it MUST execute after step 7, regardless of outcome.
- Delete
.jdi/locks/{task_id}.lock - If the delete fails, retry once. If it still fails, print
â FAILED TO RELEASE LOCK: .jdi/locks/{task_id}.lock â manual removal requiredso the operator can intervene. - Never exit the run command with the lock file still present. A leftover lock permanently blocks all subsequent iterations of the bash loop.
Parallel Step Handling
For steps with parallel key:
- Launch all agents concurrently via Task tool
- Collect all outputs
- Validate each output
- Determine combined result:
check: all: Any failure/rejection keyword winscheck: any: First pass keyword wins
- Write separate reports:
{step_name}_0.md,{step_name}_1.md, etc.
Error Handling
Lock guarantee: Every scenario that occurs after step 7 (lock acquired) MUST reach step 16 (release lock). The “release lock” column below is a reminder, not optional.
| Scenario | Action |
|---|---|
| No output from sub-agent | Write ABORT, log error, release lock (step 16) |
| Validation fails | Write ABORT, log error, release lock (step 16) |
| Multiple ambiguous keyword matches | Write ABORT, log error, release lock (step 16) |
| Invalid goto target | Write ABORT, log error, release lock (step 16) |
| Lock file exists (â¤10 min old) | Fail immediately with lock error (no lock acquired) |
| Lock file exists (>10 min old) | Remove stale lock, print warning, proceed normally |
| Workflow file not found | Fail with instructions (no lock acquired) |
| Prefix update fails | Write ABORT, log error, release lock (step 16) |
Human step without --human flag |
Write HUMAN_REQUIRED status, print message, exit (no lock held â step 6 runs before step 7) |
human property on parallel sub-agent |
Write ABORT, print validation error, exit (no lock held â step 6 runs before step 7) |
Orchestrator Log Format
The orchestrator log (.jdi/reports/{task_id}/orchestrator.md) is a human-readable, append-only markdown file designed for tail -f. It records every step execution so a human can follow the workflow in real time.
Preamble (written once when file is created)
# Workflow Log â Task #{id}
| Field | Value |
|-------|-------|
| **Task** | #{id} â {task title} |
| **Workflow** | {workflow name} |
| **Config** | {config file path, or "defaults"} |
| **Started** | {YYYY-MM-DD HH:MM:SS} |
---
Step entry (appended after each step)
## [{HH:MM:SS}] {previous_step} â {next_step}
| | |
|---|---|
| **Agent** | {agent type, or "inline"} |
| **Duration** | {N.N}s |
| **Keywords** | {matched keywords, e.g. APPROVED} |
| **Transition** | {step_name} â {next_step} (condition: {keyword}) |
> {Summary extracted from agent's ## Summary section}
<details>
<summary>Full output</summary>
{complete agent output}
</details>
---
- The heading uses
âto show the transition. For the first step (no previous), use:## [{HH:MM:SS}] â {step_name}(start). - For end steps with no next step:
## [{HH:MM:SS}] {step_name} â DONE. - The
Transitionrow shows the condition that triggered the transition. If no condition (defaultnext), write(default). If end step, write(end). - For parallel steps, list each agent on its own row in the table and include each agent’s summary as a separate blockquote, prefixed with the agent type. Each agent gets its own
<details>block:
> **{agent-type-1}:** {summary}
<details>
<summary>Full output ({agent-type-1})</summary>
{agent-type-1 full output}
</details>
> **{agent-type-2}:** {summary}
<details>
<summary>Full output ({agent-type-2})</summary>
{agent-type-2 full output}
</details>
Error entry (used for abort/error scenarios)
## [{HH:MM:SS}] â ABORT â {step_name}
**Error:** {description of what went wrong}
> {Any available context or agent output summary}
<details>
<summary>Agent output (if any)</summary>
{agent output, or "(no output)" if agent produced nothing}
</details>
---
- Use
â ABORTin the heading so errors are immediately visible when tailing. - For human-gate halts, use
⸠PAUSEDinstead:## [{HH:MM:SS}] ⸠PAUSED â {step_name}with the message about requiring--human.
Completion entry (appended when workflow finishes for this task)
## [{HH:MM:SS}] â COMPLETE
**Task #{id}** finished in {N} steps.
---
init Command
Interactive setup for new projects.
- Copy
assets/templates/jdi_template/directory tree to./.jdi/ - Ask for task management skill name (default:
task-management) â updateconfig.yamlvalue - Ask for default workflow name â update
config.yamlvalue - Configure task list persistence â Generate a UUID and add
CLAUDE_CODE_TASK_LIST_IDto.claude/settings.jsonso the task list is shared across all sessions (required for the bash loop runner):- Read
.claude/settings.json(create if it doesn’t exist) - Add or update the
envobject with"CLAUDE_CODE_TASK_LIST_ID": "<generated-uuid>" - Preserve any existing settings in the file
- Example result:
{ "env": { "CLAUDE_CODE_TASK_LIST_ID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" } } - Print:
Task list ID configured: <uuid>
- Read
- Display path to task-management template:
Show user: assets/task-management.skill - Instruct user to copy and customize the template
jdi init does NOT:
- Create or manage
~/.config/jdi/config.yaml(user does this manually) - Create
.jdi/config.local.yaml(user does this manually when needed)
status Command
Display current workflow state.
- Read
.jdi/statusfile - Invoke
/task-management context - Read workflow file from config
- Output:
Config line shows the path of the active config file, orConfig: .jdi/config.local.yaml Status: {CONTINUE|STEP_COMPLETE|WORKFLOW_COMPLETE|ABORT|HUMAN_REQUIRED} Task: #{id} - {title} Workflow: {workflow name} Current Step: {step name}defaultsif no file was found.
apply-lessons Command
Extract root causes from LESSONS.md and create rules that prevent the fundamental problem, not just the specific symptom.
Core principle: Specific lessons describe what went wrong. Good rules address why it went wrong. A lesson like “forgot to check for null return from getUserById” should not become a rule about getUserById â it should become a rule about defensive handling of fallible lookups. Always ask: “What is the category of mistake, and what habit or constraint eliminates the entire category?”
Execution Flow
- Read
.jdi/LESSONS.md - If empty, inform user and exit
- Cluster â Group lessons by underlying cause, not by surface similarity. Two lessons about different functions may share the same root cause (e.g., missing error handling at boundaries). Two lessons about the same file may have completely different root causes.
- Abstract â For each cluster, perform root-cause analysis:
- Identify the specific incident: What exactly happened?
- Ask “why” repeatedly until you reach a structural or habitual cause (not just “I forgot”):
- Why did the agent produce wrong output? â It didn’t validate assumptions.
- Why didn’t it validate assumptions? â No step in the workflow enforces validation before proceeding.
- Root cause: The workflow lacks a validation gate for assumptions.
- Name the category of mistake: e.g., “boundary assumption errors”, “missing state checks”, “implicit coupling between steps”
- Formulate a rule that eliminates the category, not just the instance. The rule should be actionable, testable, and apply broadly.
- Discard â Drop lessons that are:
- Too specific to be useful beyond a single incident (e.g., “task #42 had a typo in the config”)
- Already covered by an existing rule (check target file first)
- One-off environmental issues (e.g., “network was down”)
- Draft rules â Each rule must include:
- A clear, imperative statement of what to do or not do
- A one-line rationale linking it to the root cause
- The scope: when the rule applies (always? only at boundaries? only in specific step types?)
- Present to user â Show the drafted rules alongside the original lessons they were derived from, so the user can verify the abstraction is correct.
- Ask user where to save:
- CLAUDE.md
- .claude/rules/*.md
- Other location
- Append rules to chosen file
- Archive to
.jdi/lessons_archive/lessons_{date}.md - Clear
.jdi/LESSONS.md
Abstraction Quality Check
Before finalizing, verify each rule passes these tests:
- Scope test: Does the rule apply to more than just the original incident? If you can only imagine it triggering once, abstract further.
- Actionability test: Can an agent unambiguously follow this rule? Vague rules like “be more careful” fail this test.
- Root-cause test: If the agent follows this rule perfectly, would the original incident still have happened through a different path? If yes, the rule targets a symptom, not the cause â dig deeper.
Directory Structure
Auto-create directories as needed:
.jdi/
âââ config.yaml # Team config (git-tracked)
âââ config.local.yaml # Personal overrides (gitignored, user-created)
âââ .gitignore # Ignores config.local.yaml and runtime artifacts
âââ status
âââ workflows/
â âââ default.yaml
âââ reports/{task_id}/
â âââ orchestrator.md # Human-readable workflow log (tail this!)
â âââ {step_name}.md
â âââ summary.md
âââ locks/{task_id}.lock
âââ lessons_archive/
âââ LESSONS.md
Resources
- scripts/validate_output.py: Validates sub-agent output against regex patterns
- references/workflow-schema.md: Complete workflow YAML schema reference
- assets/templates/jdi_template/: Scaffolding template copied as
.jdi/byjdi init - assets/task-management.skill: Template for task-management skill (user must copy)
- assets/sample-workflow.yaml: Complete example workflow (plan â implement â review â finalize)
- assets/just-do-it.sh: Bash loop runner with configurable max iterations
Bash Loop Usage
Prerequisite: The bash loop spawns a new claude -p session per iteration. Without a shared task list, each session starts with an empty task list and cannot track workflow state. Ensure CLAUDE_CODE_TASK_LIST_ID is set in .claude/settings.json before running the loop (this is done automatically by /jdi init).
Use assets/just-do-it.sh for production loop execution:
# Copy to project root
cp /path/to/just-do-it/assets/just-do-it.sh ./
# Run with defaults (max 10 iterations)
./just-do-it.sh
# Run with custom max iterations
./just-do-it.sh -m 50
# Run unlimited until WORKFLOW_COMPLETE/ABORT
./just-do-it.sh -m 0
# Run specific workflow and task
./just-do-it.sh -w code-review -t 123
# Stop after current task completes (don't continue to next)
./just-do-it.sh -s
# Show verbose output
./just-do-it.sh -v
Exit codes: 0 = WORKFLOW_COMPLETE (or STEP_COMPLETE with -s), 1 = ABORT, 2 = max iterations reached, 3 = HUMAN_REQUIRED