jdi-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/AGENTS.md +209 -0
  2. package/ARCHITECTURE.md +210 -0
  3. package/COMMANDS.md +241 -0
  4. package/CREATE-EXAMPLE.md +385 -0
  5. package/CREATE.md +315 -0
  6. package/EXTENSION.md +141 -0
  7. package/LICENSE +21 -0
  8. package/MEMORY.md +471 -0
  9. package/PORTABILITY.md +438 -0
  10. package/README.md +789 -0
  11. package/bin/git-hooks/post-commit +16 -0
  12. package/bin/git-hooks/pre-commit +21 -0
  13. package/bin/jdi-build.ps1 +381 -0
  14. package/bin/jdi-build.sh +332 -0
  15. package/bin/jdi-doctor.ps1 +403 -0
  16. package/bin/jdi-doctor.sh +400 -0
  17. package/bin/jdi-install-caveman.ps1 +97 -0
  18. package/bin/jdi-install-caveman.sh +99 -0
  19. package/bin/jdi-install-playwright.ps1 +319 -0
  20. package/bin/jdi-install-playwright.sh +284 -0
  21. package/bin/jdi-install.ps1 +154 -0
  22. package/bin/jdi-install.sh +132 -0
  23. package/bin/jdi-uninstall.ps1 +309 -0
  24. package/bin/jdi-uninstall.sh +264 -0
  25. package/bin/jdi-update.ps1 +215 -0
  26. package/bin/jdi-update.sh +209 -0
  27. package/bin/jdi.js +460 -0
  28. package/bin/lib/jdi-monitor.ps1 +66 -0
  29. package/bin/lib/jdi-monitor.sh +74 -0
  30. package/bin/lib/jdi-truncate.ps1 +96 -0
  31. package/bin/lib/jdi-truncate.sh +99 -0
  32. package/bin/lib/ui.js +197 -0
  33. package/core/agents/jdi-adopter.md +465 -0
  34. package/core/agents/jdi-architect.md +894 -0
  35. package/core/agents/jdi-asker.md +153 -0
  36. package/core/agents/jdi-bootstrap.md +247 -0
  37. package/core/agents/jdi-planner.md +254 -0
  38. package/core/agents/jdi-researcher.md +303 -0
  39. package/core/commands/jdi-adopt.md +155 -0
  40. package/core/commands/jdi-bootstrap.md +81 -0
  41. package/core/commands/jdi-create.md +80 -0
  42. package/core/commands/jdi-discuss.md +80 -0
  43. package/core/commands/jdi-do.md +200 -0
  44. package/core/commands/jdi-loop.md +315 -0
  45. package/core/commands/jdi-new.md +131 -0
  46. package/core/commands/jdi-plan.md +73 -0
  47. package/core/commands/jdi-ship.md +146 -0
  48. package/core/commands/jdi-verify.md +159 -0
  49. package/core/skills/clean-code/SKILL.md +261 -0
  50. package/core/skills/dry/SKILL.md +150 -0
  51. package/core/skills/frontend-rules/SKILL.md +386 -0
  52. package/core/skills/frontend-validator/SKILL.md +567 -0
  53. package/core/skills/kiss/SKILL.md +178 -0
  54. package/core/skills/solid/SKILL.md +281 -0
  55. package/core/skills/yagni/SKILL.md +207 -0
  56. package/core/templates/agent.md +72 -0
  57. package/core/templates/doer-specialist.md +216 -0
  58. package/core/templates/reviewer-specialist.md +405 -0
  59. package/core/templates/skill.md +66 -0
  60. package/package.json +70 -0
  61. package/runtimes/antigravity/agents.md +74 -0
  62. package/runtimes/antigravity/skills/clean-code/SKILL.md +252 -0
  63. package/runtimes/antigravity/skills/dry/SKILL.md +141 -0
  64. package/runtimes/antigravity/skills/frontend-rules/SKILL.md +376 -0
  65. package/runtimes/antigravity/skills/frontend-validator/SKILL.md +559 -0
  66. package/runtimes/antigravity/skills/jdi-adopt/SKILL.md +155 -0
  67. package/runtimes/antigravity/skills/jdi-adopter/SKILL.md +436 -0
  68. package/runtimes/antigravity/skills/jdi-architect/SKILL.md +872 -0
  69. package/runtimes/antigravity/skills/jdi-asker/SKILL.md +125 -0
  70. package/runtimes/antigravity/skills/jdi-asker/references/context-template.md +34 -0
  71. package/runtimes/antigravity/skills/jdi-asker/references/decision-format.md +19 -0
  72. package/runtimes/antigravity/skills/jdi-asker/scripts/find_phase_dir.sh +25 -0
  73. package/runtimes/antigravity/skills/jdi-bootstrap/SKILL.md +81 -0
  74. package/runtimes/antigravity/skills/jdi-create/SKILL.md +80 -0
  75. package/runtimes/antigravity/skills/jdi-discuss/SKILL.md +80 -0
  76. package/runtimes/antigravity/skills/jdi-discuss/scripts/run_command.sh +62 -0
  77. package/runtimes/antigravity/skills/jdi-do/SKILL.md +200 -0
  78. package/runtimes/antigravity/skills/jdi-loop/SKILL.md +315 -0
  79. package/runtimes/antigravity/skills/jdi-new/SKILL.md +131 -0
  80. package/runtimes/antigravity/skills/jdi-plan/SKILL.md +73 -0
  81. package/runtimes/antigravity/skills/jdi-planner/SKILL.md +225 -0
  82. package/runtimes/antigravity/skills/jdi-researcher/SKILL.md +274 -0
  83. package/runtimes/antigravity/skills/jdi-ship/SKILL.md +146 -0
  84. package/runtimes/antigravity/skills/jdi-verify/SKILL.md +159 -0
  85. package/runtimes/antigravity/skills/kiss/SKILL.md +169 -0
  86. package/runtimes/antigravity/skills/solid/SKILL.md +272 -0
  87. package/runtimes/antigravity/skills/yagni/SKILL.md +198 -0
  88. package/runtimes/claude/CLAUDE.md +91 -0
  89. package/runtimes/claude/agents/jdi-adopter.md +430 -0
  90. package/runtimes/claude/agents/jdi-architect.md +864 -0
  91. package/runtimes/claude/agents/jdi-asker.md +119 -0
  92. package/runtimes/claude/agents/jdi-bootstrap.md +213 -0
  93. package/runtimes/claude/agents/jdi-planner.md +221 -0
  94. package/runtimes/claude/agents/jdi-researcher.md +269 -0
  95. package/runtimes/claude/commands/jdi-adopt.md +155 -0
  96. package/runtimes/claude/commands/jdi-bootstrap.md +81 -0
  97. package/runtimes/claude/commands/jdi-create.md +80 -0
  98. package/runtimes/claude/commands/jdi-discuss.md +80 -0
  99. package/runtimes/claude/commands/jdi-do.md +200 -0
  100. package/runtimes/claude/commands/jdi-loop.md +315 -0
  101. package/runtimes/claude/commands/jdi-new.md +131 -0
  102. package/runtimes/claude/commands/jdi-plan.md +73 -0
  103. package/runtimes/claude/commands/jdi-ship.md +146 -0
  104. package/runtimes/claude/commands/jdi-verify.md +159 -0
  105. package/runtimes/claude/settings.example.json +132 -0
  106. package/runtimes/claude/skills/clean-code/SKILL.md +247 -0
  107. package/runtimes/claude/skills/dry/SKILL.md +136 -0
  108. package/runtimes/claude/skills/frontend-rules/SKILL.md +369 -0
  109. package/runtimes/claude/skills/frontend-validator/SKILL.md +553 -0
  110. package/runtimes/claude/skills/kiss/SKILL.md +164 -0
  111. package/runtimes/claude/skills/solid/SKILL.md +267 -0
  112. package/runtimes/claude/skills/yagni/SKILL.md +193 -0
  113. package/runtimes/copilot/agents/jdi-adopter.agent.md +430 -0
  114. package/runtimes/copilot/agents/jdi-architect.agent.md +864 -0
  115. package/runtimes/copilot/agents/jdi-asker.agent.md +119 -0
  116. package/runtimes/copilot/agents/jdi-bootstrap.agent.md +213 -0
  117. package/runtimes/copilot/agents/jdi-planner.agent.md +221 -0
  118. package/runtimes/copilot/agents/jdi-researcher.agent.md +269 -0
  119. package/runtimes/copilot/copilot-instructions.md +80 -0
  120. package/runtimes/copilot/prompts/jdi-adopt.prompt.md +155 -0
  121. package/runtimes/copilot/prompts/jdi-bootstrap.prompt.md +81 -0
  122. package/runtimes/copilot/prompts/jdi-create.prompt.md +80 -0
  123. package/runtimes/copilot/prompts/jdi-discuss.prompt.md +80 -0
  124. package/runtimes/copilot/prompts/jdi-do.prompt.md +200 -0
  125. package/runtimes/copilot/prompts/jdi-loop.prompt.md +315 -0
  126. package/runtimes/copilot/prompts/jdi-new.prompt.md +131 -0
  127. package/runtimes/copilot/prompts/jdi-plan.prompt.md +73 -0
  128. package/runtimes/copilot/prompts/jdi-ship.prompt.md +146 -0
  129. package/runtimes/copilot/prompts/jdi-verify.prompt.md +159 -0
  130. package/runtimes/opencode/AGENTS.md +87 -0
  131. package/runtimes/opencode/agents/jdi-adopter.md +434 -0
  132. package/runtimes/opencode/agents/jdi-architect.md +861 -0
  133. package/runtimes/opencode/agents/jdi-asker.md +123 -0
  134. package/runtimes/opencode/agents/jdi-bootstrap.md +217 -0
  135. package/runtimes/opencode/agents/jdi-planner.md +225 -0
  136. package/runtimes/opencode/agents/jdi-researcher.md +273 -0
  137. package/runtimes/opencode/commands/jdi-adopt.md +155 -0
  138. package/runtimes/opencode/commands/jdi-bootstrap.md +81 -0
  139. package/runtimes/opencode/commands/jdi-create.md +80 -0
  140. package/runtimes/opencode/commands/jdi-discuss.md +80 -0
  141. package/runtimes/opencode/commands/jdi-do.md +200 -0
  142. package/runtimes/opencode/commands/jdi-loop.md +315 -0
  143. package/runtimes/opencode/commands/jdi-new.md +131 -0
  144. package/runtimes/opencode/commands/jdi-plan.md +73 -0
  145. package/runtimes/opencode/commands/jdi-ship.md +146 -0
  146. package/runtimes/opencode/commands/jdi-verify.md +159 -0
  147. package/runtimes/opencode/opencode.example.jsonc +169 -0
  148. package/runtimes/opencode/skills/clean-code/SKILL.md +247 -0
  149. package/runtimes/opencode/skills/dry/SKILL.md +136 -0
  150. package/runtimes/opencode/skills/frontend-rules/SKILL.md +369 -0
  151. package/runtimes/opencode/skills/frontend-validator/SKILL.md +553 -0
  152. package/runtimes/opencode/skills/kiss/SKILL.md +164 -0
  153. package/runtimes/opencode/skills/solid/SKILL.md +267 -0
  154. package/runtimes/opencode/skills/yagni/SKILL.md +193 -0
  155. package/templates-jdi-folder/config.json +18 -0
  156. package/templates-jdi-folder/registry.md +31 -0
  157. package/templates-jdi-folder/reviewers.md +33 -0
  158. package/templates-jdi-folder/skills-registry.md +32 -0
  159. package/templates-jdi-folder/specialists.md +39 -0
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: jdi-plan
3
+ description: Generates phase PLAN.md. Decomposes into tasks with files_modified, acceptance, parallelism waves.
4
+ argument_hint: "<phase_number> [--review]"
5
+ runtime_intent:
6
+ invokes_agent: jdi-planner
7
+ runtime_overrides:
8
+ claude:
9
+ allowed-tools: [Read, Write, Bash, Grep, Glob, AskUserQuestion, Agent]
10
+ copilot:
11
+ tools: [read, write, grep, glob]
12
+ opencode:
13
+ agent: jdi-planner
14
+ subtask: true
15
+ model: anthropic/claude-sonnet-4-20250514
16
+ antigravity:
17
+ triggers:
18
+ - "/jdi-plan"
19
+ - "plan phase {N}"
20
+ ---
21
+
22
+ <objective>
23
+ Generates PLAN.md for the given phase. Decomposes into tasks (max 8), groups into parallelism waves, maps files_modified and acceptance.
24
+ </objective>
25
+
26
+ <arguments>
27
+ - `phase_number` (required): phase number, e.g. `1`, `2`
28
+ - `--review` (optional): show preview and ask for approval before saving
29
+ </arguments>
30
+
31
+ <process>
32
+
33
+ ### Step 1: Validation
34
+ ```bash
35
+ test -d .jdi/ || { echo "Not a JDI project. Run /jdi-new."; exit 1; }
36
+ test -f .jdi/PROJECT.md || { echo "PROJECT.md missing."; exit 1; }
37
+ ```
38
+
39
+ Verify phase CONTEXT.md exists:
40
+ ```bash
41
+ ls .jdi/phases/{NN}*/CONTEXT.md 2>/dev/null || { echo "CONTEXT.md missing. Run /jdi-discuss {N}"; exit 1; }
42
+
43
+ # Context budget warm-up (does not block)
44
+ JDI_LIB="$(dirname "$(command -v jdi 2>/dev/null || echo /usr/local/bin/jdi)")/../lib"
45
+ if [ -f "$JDI_LIB/jdi-monitor.sh" ]; then
46
+ bash "$JDI_LIB/jdi-monitor.sh" .jdi/PROJECT.md .jdi/DECISIONS.md .jdi/phases/{NN}*/CONTEXT.md || true
47
+ fi
48
+ # Windows: pwsh -File "$JDI_LIB/jdi-monitor.ps1" -Paths @(...)
49
+ ```
50
+
51
+ ### Step 2: Spawn planner
52
+ Invoke `jdi-planner` with phase_number. Wait.
53
+
54
+ ### Step 3: Verify
55
+ ```bash
56
+ test -f .jdi/phases/{NN}*/PLAN.md || { echo "PLAN.md not created"; exit 1; }
57
+ ```
58
+
59
+ ### Step 4: Confirm
60
+ Show plan summary + suggest `/jdi-do {N}`.
61
+
62
+ </process>
63
+
64
+ <gates>
65
+ - pre: `.jdi/PROJECT.md` + `.jdi/phases/{NN-slug}/CONTEXT.md` exist
66
+ - post: PLAN.md created + STATE.md updated + commit
67
+ </gates>
68
+
69
+ <errors>
70
+ - CONTEXT.md missing -> suggest `/jdi-discuss {N}`
71
+ - Phase does not exist in ROADMAP -> error
72
+ - Planner cancelled -> exit clean
73
+ </errors>
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: jdi-ship
3
+ description: Finalizes phase after verify. Updates ROADMAP.md, marks phase as done, advances pointer to next.
4
+ argument_hint: "<phase_number>"
5
+ runtime_intent:
6
+ invokes_agent: none
7
+ runtime_overrides:
8
+ claude:
9
+ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, AskUserQuestion]
10
+ copilot:
11
+ tools: [read, write, edit, grep, glob, terminal]
12
+ opencode:
13
+ subtask: true
14
+ antigravity:
15
+ triggers:
16
+ - "/jdi-ship"
17
+ - "finalize phase {N}"
18
+ ---
19
+
20
+ <objective>
21
+ Finalizes phase after /jdi-verify approves. Updates ROADMAP.md (phase: done), advances STATE to next phase, final commit.
22
+ </objective>
23
+
24
+ <arguments>
25
+ - `phase_number` (required)
26
+ </arguments>
27
+
28
+ <process>
29
+
30
+ ### Step 1: Validation
31
+ ```bash
32
+ test -d .jdi/ || { echo "Not a JDI project."; exit 1; }
33
+
34
+ # Verify REVIEW.md exists
35
+ ls .jdi/phases/{NN}*/REVIEW.md 2>/dev/null || {
36
+ echo "REVIEW.md missing. /jdi-verify {N}."
37
+ exit 1
38
+ }
39
+
40
+ # Read verdict
41
+ VERDICT=$(grep -oE 'Verdict:\*\* (APPROVED|APPROVED_WITH_WARNINGS|BLOCKED)' .jdi/phases/{NN}*/REVIEW.md | awk '{print $2}')
42
+
43
+ if [ "$VERDICT" = "BLOCKED" ]; then
44
+ echo "Phase {N} BLOCKED. Fix before ship."
45
+ exit 1
46
+ fi
47
+ ```
48
+
49
+ ### Step 2: Confirm with user (only if WITH_WARNINGS)
50
+
51
+ If `VERDICT=APPROVED_WITH_WARNINGS`:
52
+ ```
53
+ Phase {N} has uncorrected warnings. Ship anyway?
54
+ - Yes, ship (warnings remain in REVIEW.md)
55
+ - No, fix first
56
+ ```
57
+
58
+ If "No" -> exit clean.
59
+
60
+ ### Step 3: Update ROADMAP.md
61
+
62
+ Edit `.jdi/ROADMAP.md`:
63
+ - Phase {N}: `status: done`
64
+ - Phase {N+1}: `status: ready` (if exists)
65
+
66
+ If no phase {N+1}:
67
+ ```
68
+ All phases complete.
69
+ Project delivered.
70
+ ```
71
+
72
+ ### Step 4: Update STATE.md
73
+
74
+ ```markdown
75
+ current_phase: {N+1 or done}
76
+ phase_status: ready (if {N+1} exists) or complete
77
+ next_step: /jdi-discuss {N+1} or done
78
+ ```
79
+
80
+ ### Step 5: Archive old phases (compaction)
81
+
82
+ Read `archive_after` from `.jdi/config.json` (default 5). If current phase advances to `N+1`, and a phase exists with number `<= (N+1) - archive_after`, move to `.jdi/archive/`.
83
+
84
+ ```bash
85
+ ARCHIVE_AFTER=5
86
+ if [ -f .jdi/config.json ]; then
87
+ if command -v jq >/dev/null 2>&1; then
88
+ ARCHIVE_AFTER=$(jq -r '.compaction.archive_after // 5' .jdi/config.json)
89
+ fi
90
+ fi
91
+
92
+ NEXT=$((N + 1))
93
+ THRESHOLD=$((NEXT - ARCHIVE_AFTER))
94
+
95
+ if [ "$THRESHOLD" -ge 1 ]; then
96
+ mkdir -p .jdi/archive
97
+ test -f .jdi/archive/index.md || echo "# Archive index" > .jdi/archive/index.md
98
+
99
+ for dir in .jdi/phases/*/; do
100
+ NN=$(basename "$dir" | grep -oE '^[0-9]+' || true)
101
+ [ -z "$NN" ] && continue
102
+ NN_NUM=$((10#$NN)) # force decimal
103
+ if [ "$NN_NUM" -le "$THRESHOLD" ]; then
104
+ VERDICT_OLD=$(grep -oE 'Verdict:\*\* (APPROVED|APPROVED_WITH_WARNINGS|BLOCKED)' "$dir/REVIEW.md" 2>/dev/null | awk '{print $2}' || echo "UNKNOWN")
105
+ mv "$dir" .jdi/archive/
106
+ echo "- $(basename "$dir"): ${VERDICT_OLD} (archived $(date -u +%F))" >> .jdi/archive/index.md
107
+ fi
108
+ done
109
+ fi
110
+ # Windows: equivalent in PowerShell — Move-Item + Add-Content
111
+ ```
112
+
113
+ Archived phases remain accessible via `.jdi/archive/` but exit the default read-path. Read-depth rule (`ARCHITECTURE.md > Read-depth scaling`) treats archive as `<= current - 2`.
114
+
115
+ ### Step 6: Final commit
116
+
117
+ ```bash
118
+ git add .jdi/ROADMAP.md .jdi/STATE.md .jdi/archive/ 2>/dev/null
119
+ git commit -m "feat({NN-slug}): ship phase {N} ({VERDICT})"
120
+ ```
121
+
122
+ Optional tag (if PROJECT.md has `tag_phases: true`):
123
+ ```bash
124
+ git tag "phase-{N}-{slug}"
125
+ ```
126
+
127
+ ### Step 7: Confirm
128
+
129
+ ```
130
+ Phase {N} shipped.
131
+ {if more phases:} Next: /jdi-discuss {N+1}
132
+ {if last:} Project delivered. Tag: phase-{N}-{slug}
133
+ ```
134
+
135
+ </process>
136
+
137
+ <gates>
138
+ - pre: REVIEW.md exists + verdict != BLOCKED
139
+ - post: ROADMAP.md + STATE.md updated + old phases archived (if applicable) + commit (+ optional tag)
140
+ </gates>
141
+
142
+ <errors>
143
+ - REVIEW missing -> /jdi-verify
144
+ - Verdict BLOCKED -> abort
145
+ - Already shipped -> abort with warning
146
+ </errors>
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: jdi-verify
3
+ description: Runs phase quality gates via reviewer specialist. Build, tests, coverage, lint, security checks. Verdict APPROVED / APPROVED_WITH_WARNINGS / BLOCKED.
4
+ argument_hint: "<phase_number>"
5
+ runtime_intent:
6
+ invokes_agent: dynamic
7
+ runtime_overrides:
8
+ claude:
9
+ allowed-tools: [Read, Bash, Grep, Glob, Agent]
10
+ copilot:
11
+ tools: [read, grep, glob, terminal]
12
+ opencode:
13
+ subtask: true
14
+ model: anthropic/claude-sonnet-4-20250514
15
+ antigravity:
16
+ triggers:
17
+ - "/jdi-verify"
18
+ - "verify phase {N}"
19
+ ---
20
+
21
+ <objective>
22
+ Verifies the phase was delivered correctly. Runs gates defined in the project's reviewer specialist. Verdict blocks or releases the ship.
23
+ </objective>
24
+
25
+ <arguments>
26
+ - `phase_number` (required)
27
+ </arguments>
28
+
29
+ <process>
30
+
31
+ ### Step 1: Validation
32
+ ```bash
33
+ test -d .jdi/ || { echo "Not a JDI project."; exit 1; }
34
+
35
+ # Verify reviewer exists
36
+ ls .jdi/agents/jdi-reviewer-*.md 2>/dev/null | head -1 || {
37
+ echo "Reviewer missing. /jdi-bootstrap."
38
+ exit 1
39
+ }
40
+
41
+ # Verify phase was executed
42
+ ls .jdi/phases/{NN}*/SUMMARY.md 2>/dev/null || {
43
+ echo "Phase {N} not executed. /jdi-do {N}."
44
+ exit 1
45
+ }
46
+
47
+ # Context budget warm-up (does not block)
48
+ JDI_LIB="$(dirname "$(command -v jdi 2>/dev/null || echo /usr/local/bin/jdi)")/../lib"
49
+ if [ -f "$JDI_LIB/jdi-monitor.sh" ]; then
50
+ bash "$JDI_LIB/jdi-monitor.sh" .jdi/PROJECT.md .jdi/DECISIONS.md .jdi/phases/{NN}*/PLAN.md .jdi/phases/{NN}*/SUMMARY.md || true
51
+ fi
52
+ # Windows: pwsh -File "$JDI_LIB/jdi-monitor.ps1" -Paths @(...)
53
+ ```
54
+
55
+ ### Step 2: Resolve reviewer specialist(s)
56
+
57
+ ```bash
58
+ REVIEWERS=$(grep -oE 'jdi-reviewer-[a-z0-9-]+' .jdi/reviewers.md | sort -u)
59
+ REVIEWER_COUNT=$(echo "$REVIEWERS" | wc -l)
60
+ echo "Reviewers registered: $REVIEWER_COUNT"
61
+ ```
62
+
63
+ **Single-stack** (`REVIEWER_COUNT == 1`): one reviewer, normal flow.
64
+ **Multi-stack** (`REVIEWER_COUNT > 1`): chain reviewers in registry order. Each writes its own REVIEW segment; aggregate verdict = worst-case (1 BLOCK = overall BLOCK).
65
+
66
+ ### Step 3: Spawn reviewer(s)
67
+
68
+ **Single-stack:**
69
+ ```
70
+ Agent(
71
+ subagent_type="${REVIEWERS}",
72
+ description="Verify phase {N}",
73
+ prompt="phase={N}, mode=verify"
74
+ )
75
+ ```
76
+
77
+ **Multi-stack:** spawn each reviewer in sequence (NOT parallel — build/test commands may conflict on ports, locks, output dirs):
78
+
79
+ ```
80
+ for REVIEWER in $REVIEWERS:
81
+ Agent(
82
+ subagent_type="$REVIEWER",
83
+ description="Verify phase {N} ({REVIEWER})",
84
+ prompt="phase={N}, mode=verify, reviewer_segment=${REVIEWER}"
85
+ )
86
+ # Each reviewer appends to .jdi/phases/{NN-slug}/REVIEW.md under section
87
+ # "## Reviewer: {REVIEWER}" with its own gate results and verdict
88
+ ```
89
+
90
+ Each reviewer scopes its gates to its `file_glob` (from frontmatter `scope.file_glob`). Coverage threshold enforced only on files matching the glob.
91
+
92
+ Reviewers are read-only. Wait for completion before next.
93
+
94
+ ### Step 4: Read aggregate verdict
95
+
96
+ ```bash
97
+ test -f .jdi/phases/{NN}*/REVIEW.md || { echo "REVIEW.md not created"; exit 1; }
98
+
99
+ # Collect all per-reviewer verdicts
100
+ VERDICTS=$(grep -oE 'Verdict:\*\* (APPROVED|APPROVED_WITH_WARNINGS|BLOCKED)' .jdi/phases/{NN}*/REVIEW.md | awk '{print $2}')
101
+
102
+ # Worst-case wins: BLOCK > WARNINGS > APPROVED
103
+ if echo "$VERDICTS" | grep -q BLOCKED; then
104
+ VERDICT=BLOCKED
105
+ elif echo "$VERDICTS" | grep -q APPROVED_WITH_WARNINGS; then
106
+ VERDICT=APPROVED_WITH_WARNINGS
107
+ else
108
+ VERDICT=APPROVED
109
+ fi
110
+
111
+ # For single-stack, this collapses to the single reviewer's verdict — backward compatible.
112
+ ```
113
+
114
+ ### Step 5: Update STATE
115
+
116
+ ```markdown
117
+ current_phase: {N}
118
+ phase_status: {verified|blocked}
119
+ phase_verdict: {APPROVED|APPROVED_WITH_WARNINGS|BLOCKED}
120
+ next_step: {if APPROVED or WITH_WARNINGS: /jdi-ship {N}; if BLOCKED: fix and /jdi-do {N} again}
121
+ ```
122
+
123
+ ```bash
124
+ git add .jdi/phases/{NN-slug}/REVIEW.md .jdi/STATE.md
125
+ git commit -m "docs({NN-slug}): verify phase ({VERDICT})"
126
+ ```
127
+
128
+ ### Step 6: Confirm
129
+
130
+ **APPROVED:**
131
+ ```
132
+ Phase {N}: APPROVED. Next: /jdi-ship {N}
133
+ ```
134
+
135
+ **APPROVED_WITH_WARNINGS:**
136
+ ```
137
+ Phase {N}: APPROVED_WITH_WARNINGS ({count} warnings).
138
+ REVIEW.md: .jdi/phases/{NN-slug}/REVIEW.md
139
+ Next: /jdi-ship {N} (or fix first)
140
+ ```
141
+
142
+ **BLOCKED:**
143
+ ```
144
+ Phase {N}: BLOCKED ({count} blockers). REVIEW.md: .jdi/phases/{NN-slug}/REVIEW.md
145
+ Fix → /jdi-do {N} → /jdi-verify {N}
146
+ ```
147
+
148
+ </process>
149
+
150
+ <gates>
151
+ - pre: SUMMARY.md exists + reviewer registered in .jdi/reviewers.md
152
+ - post: REVIEW.md created + STATE updated
153
+ </gates>
154
+
155
+ <errors>
156
+ - Reviewer missing -> /jdi-bootstrap
157
+ - SUMMARY missing -> /jdi-do
158
+ - Reviewer fails -> show error, keep state, suggest retry
159
+ </errors>
@@ -0,0 +1,261 @@
1
+ ---
2
+ name: clean-code
3
+ description: Clean Code. Human-readable code, optimized for reading (read 10x more than written). Names reveal intent, small functions, no redundant comments, explicit error handling, no magic numbers. Applies in any language.
4
+ type: skill
5
+ applies_to: |
6
+ Loaded by doer when writing code (any code change).
7
+ Loaded by reviewer at gate 5 to detect code smells.
8
+ loaded_by:
9
+ - jdi-doer-{slug}
10
+ - jdi-reviewer-{slug}
11
+ runtime_overrides:
12
+ antigravity:
13
+ triggers:
14
+ - "Clean Code"
15
+ - "clean code"
16
+ - "code smells"
17
+ - "code readability"
18
+ ---
19
+
20
+ # Skill: Clean Code
21
+
22
+ > Code is read 10x more than written. Optimize for reading.
23
+
24
+ Not about pretty style. About **making reader understand in 1 pass**, without mentally simulating execution.
25
+
26
+ ## Rules
27
+
28
+ ### 1. Names reveal intent
29
+
30
+ - **Variable**: what it **is**, not how it's stored (`elapsedSeconds` > `t` > `time`)
31
+ - **Function**: what it **does**, verb + object (`calculateTax(order)`, not `tax(order)`)
32
+ - **Boolean**: yes/no question (`isActive`, `hasPermission`, `canSubmit`)
33
+ - **Class/module**: noun (`OrderRepository`, `EmailValidator`)
34
+ - **Interface**: role/capability (`Repository`, `Cacheable`) — no `I`/`Abstract` prefix if language doesn't require
35
+
36
+ ### Anti-names
37
+
38
+ | Wrong | Right |
39
+ |---|---|
40
+ | `data`, `info`, `value`, `temp`, `result` | something descriptive of the context |
41
+ | `processData()` | `parseUserPayload()`, `applyDiscount()`, etc |
42
+ | `Manager`, `Helper`, `Util` | name of the real responsibility |
43
+ | `flag`, `status` | `isComplete`, `paymentStatus` |
44
+ | `obj`, `item`, `thing` | actual type |
45
+ | Abbreviations: `usr`, `ctx`, `mgr`, `cfg` | `user`, `context` (exception: well-established domain convention) |
46
+ | Variables with `_2`, `_new`, `_old` | refactor until 1 remains |
47
+
48
+ ### 2. Small functions
49
+
50
+ - **Size**: ideally < 20 lines. If over 50, almost certainly doing too much.
51
+ - **1 abstraction level**: inside function, all operations at same level. Mixing "open connection" + "calculate tax" = no.
52
+ - **3-4 params max**: more than that signals either missing object or too much responsibility.
53
+ - **1 logical exit**: early return is OK; multiple returns mid-complex-logic is bad.
54
+
55
+ ### 3. Functions do **one** thing
56
+
57
+ If you describe function as "does X **and** Y", split into two. Function name must be precise.
58
+
59
+ Exception: orchestrators (controllers, command handlers) coordinate — OK to describe as "validates, saves, notifies" if each step is a call to another function.
60
+
61
+ ### 4. Comments
62
+
63
+ **Default: DON'T write**.
64
+
65
+ Well-named code doesn't need to explain **what** it does. If you feel like writing a comment, first attempt: rename function/variable.
66
+
67
+ ### Comments OK when:
68
+
69
+ - **Why** non-obvious: workaround for specific bug, surprising design decision, external constraint
70
+ - **Critical invariant**: "this array MUST be sorted for binary search to work"
71
+ - **TODO/FIXME marker** with ticket link: `// TODO(#1234): handle UTF-16 surrogate`
72
+ - **Pitfall warning**: "// don't call this in a loop, O(n^2)"
73
+ - **Public API doc**: contract for caller (params, returns, exceptions)
74
+
75
+ ### Comments bad when:
76
+
77
+ - Explain **what** (code already says)
78
+ - Repeat the function name in English
79
+ - Comment goes stale relative to code
80
+ - "// removed on XX/YY" left in the tree
81
+ - "// hack" without explanation
82
+ - "// not sure why this works" — investigate, don't guess
83
+
84
+ ### 5. Explicit error handling
85
+
86
+ - **Never silence exception**: `try { ... } catch {}` is **latent bug**
87
+ - **Explicit handling**: structured log + rethrow OR return Result/Either
88
+ - **Errors are part of the contract**: document what can fail
89
+ - **Boundary**: handle error at the boundary (controller, top-level handler), not at every internal call
90
+ - **Validation**: at the entry (boundary), not scattered
91
+
92
+ ### 6. No magic numbers/strings
93
+
94
+ - Number or string with meaning becomes a **named constant**
95
+ - `if (status === 3)` becomes `if (status === OrderStatus.Shipped)`
96
+ - `setTimeout(fn, 86400000)` becomes `setTimeout(fn, MS_PER_DAY)`
97
+ - Exception: 0, 1, -1, universally clear cases
98
+
99
+ ### 7. Command-Query Separation (CQS)
100
+
101
+ - **Query**: returns info, does **not** mutate state
102
+ - **Command**: mutates state, does **not** return (or returns void/minimal ack)
103
+
104
+ `function getUser(id)` that **also** updates last_access violates CQS — caller doesn't expect side-effect. Split.
105
+
106
+ ### 8. Boy Scout Rule
107
+
108
+ > Leave the campground cleaner than you found it.
109
+
110
+ Touched a file? Small cleanness improvement is OK in the same commit:
111
+ - Rename obscure variable
112
+ - Split giant function you already had to read
113
+ - Remove stale comment
114
+ - Delete dead code
115
+
116
+ No heavy unrelated refactor — atomic commit still rules.
117
+
118
+ ### 9. Formatting
119
+
120
+ - **Auto-format**: linter/formatter on the project (prettier, dotnet format, ruff format, gofmt) — no human decisions
121
+ - **Member order**: consistent convention (publics before privates, or group by feature)
122
+ - **Blank line**: separates logical blocks. Function all glued together is hard to scan.
123
+ - **Consistent indentation**: respect project convention
124
+
125
+ ### 10. Symmetry and consistency
126
+
127
+ - Functions at same "level" have similar signature
128
+ - `getUserById, getUserByEmail` — consistent param order
129
+ - Exceptions "as is" vs "throws" vs Result — pick **one** style in the project
130
+ - `null` vs `undefined` vs `Option` — pick **one**
131
+ - Consistent naming convention (camelCase, PascalCase, snake_case) following the language
132
+
133
+ ## Classic code smells
134
+
135
+ | Smell | Symptom |
136
+ |---|---|
137
+ | **Long function** | > 50 lines |
138
+ | **Long parameter list** | > 4 params |
139
+ | **God class** | 1 class does everything |
140
+ | **Feature envy** | method uses more data from **another** class than its own |
141
+ | **Data clump** | same 3-4 params bundled in multiple places -> object |
142
+ | **Primitive obsession** | everything is string/int, no value objects |
143
+ | **Scattered switch statements** | OCP violated |
144
+ | **Shotgun surgery** | simple change touches N files |
145
+ | **Divergent change** | 1 class changes for 5 different reasons (SRP) |
146
+ | **Dead code** | function/parameter/var never used |
147
+ | **Speculative generality** | flexibility without caller (YAGNI) |
148
+ | **Comments compensating bad code** | refactor code, delete comment |
149
+ | **Magic numbers** | 86400, 1024 with no name |
150
+ | **Silenced exceptions** | `catch {}`, `catch (Exception _) { }` |
151
+ | **Long if/else chains** | use polymorphism/strategy |
152
+ | **Inconsistent naming** | `getUser` here, `fetchAccount` there, `loadOrder` over there |
153
+ | **Boolean parameter** | `fn(true)` at caller — nobody knows what `true` means |
154
+
155
+ ## Procedure
156
+
157
+ ### Doer
158
+
159
+ After writing:
160
+ 1. **Name review**: does each variable/function have a name that stands without a comment? Rename if not.
161
+ 2. **Size**: any function > 30 lines? Split.
162
+ 3. **Magic**: any number/string without obvious meaning? Constant.
163
+ 4. **Redundant comments**: any comment that just repeats the code? Delete.
164
+ 5. **Error handling**: any silent `catch {}`? Log or rethrow.
165
+
166
+ ### Reviewer (gate 5)
167
+
168
+ ```bash
169
+ # Long functions
170
+ awk '/^(function|def|public |private |protected |async )/ { start=NR; name=$0 }
171
+ /^}$|^\s{0,2}}\s*$/ { if (NR-start > 50) print FILENAME":"start": function with "(NR-start)" lines: "name }' src/**/*.{ts,cs,py,go,java}
172
+
173
+ # Magic numbers (typical suspects)
174
+ grep -RnE '\b(86400|3600|1024|65535|1000000)\b' src/
175
+
176
+ # Silent catch
177
+ grep -RnE 'catch\s*(\([^)]*\))?\s*\{\s*\}' src/
178
+ grep -RnE 'except.*:\s*pass\s*$' src/
179
+ grep -RnE 'catch.*:.*ignore' src/
180
+
181
+ # TODO without ticket
182
+ grep -RnE 'TODO(?!.*#\d+)|FIXME(?!.*#\d+)' src/
183
+
184
+ # Suspect boolean params
185
+ grep -RnE 'function \w+\([^)]*: bool|: boolean' src/
186
+
187
+ # Generic name
188
+ grep -RnE '\b(data|info|value|temp|tmp|result|obj|item|thing)\b\s*[:=]' src/ | head -20
189
+
190
+ # Dead code (linter catches — confirm)
191
+
192
+ # Obvious comments
193
+ grep -RnE '^\s*//\s*(get|set|return|increment|decrement|loop|iterate)\b' src/
194
+ ```
195
+
196
+ Relevant match -> WARN or BLOCK depending on severity.
197
+
198
+ ## Inputs
199
+
200
+ - Diff/content of the file
201
+ - Project convention (linter config, naming convention from PROJECT.md)
202
+
203
+ ## Outputs
204
+
205
+ Does NOT produce a file. Modifies judgement.
206
+
207
+ ## Examples
208
+
209
+ ### Example 1: bad names
210
+
211
+ Wrong:
212
+ ```python
213
+ def calc(d, t):
214
+ r = d * t * 0.18
215
+ return r
216
+ ```
217
+
218
+ Right:
219
+ ```python
220
+ VAT_RATE = 0.18
221
+
222
+ def calculate_vat(amount: Decimal, qty: int) -> Decimal:
223
+ return amount * qty * VAT_RATE
224
+ ```
225
+
226
+ ### Example 2: giant function
227
+
228
+ Wrong: 1 function of 120 lines validating, saving, sending email, logging.
229
+
230
+ Right: 4 functions of 20 lines each + 1 orchestrator of 15 lines that coordinates.
231
+
232
+ ### Example 3: silenced exception
233
+
234
+ Wrong:
235
+ ```typescript
236
+ try {
237
+ await sendNotification(user)
238
+ } catch {}
239
+ ```
240
+
241
+ Latent bug — notification failure disappears.
242
+
243
+ Right:
244
+ ```typescript
245
+ try {
246
+ await sendNotification(user)
247
+ } catch (err) {
248
+ logger.error("notification failed", { userId: user.id, err })
249
+ // intentional: notification is best-effort, doesn't block flow
250
+ }
251
+ ```
252
+
253
+ Comment here justifies the "why" of the no-rethrow.
254
+
255
+ ### Example 4: boolean param
256
+
257
+ Wrong: `createUser("alice", "alice@x.com", true, false)`
258
+
259
+ Right: `createUser({ name: "alice", email: "alice@x.com", admin: true, sendWelcome: false })`
260
+
261
+ Caller becomes self-documented.