jdi-cli 0.1.2 → 0.1.3
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.
- package/README.md +6 -0
- package/core/commands/jdi-add-phase.md +171 -0
- package/core/commands/jdi-remove-phase.md +228 -0
- package/package.json +1 -1
- package/runtimes/antigravity/agents.md +4 -0
- package/runtimes/antigravity/skills/jdi-add-phase/SKILL.md +171 -0
- package/runtimes/antigravity/skills/jdi-remove-phase/SKILL.md +228 -0
- package/runtimes/claude/CLAUDE.md +4 -0
- package/runtimes/claude/commands/jdi-add-phase.md +171 -0
- package/runtimes/claude/commands/jdi-remove-phase.md +228 -0
- package/runtimes/copilot/copilot-instructions.md +4 -0
- package/runtimes/copilot/prompts/jdi-add-phase.prompt.md +171 -0
- package/runtimes/copilot/prompts/jdi-remove-phase.prompt.md +228 -0
- package/runtimes/opencode/AGENTS.md +4 -0
- package/runtimes/opencode/commands/jdi-add-phase.md +171 -0
- package/runtimes/opencode/commands/jdi-remove-phase.md +228 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jdi-remove-phase
|
|
3
|
+
description: Removes a phase from ROADMAP.md. Refuses to remove done phases or the current phase. Archives any existing phase artifacts. Atomic commit.
|
|
4
|
+
argument_hint: "<phase_number> [--force]"
|
|
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-remove-phase"
|
|
17
|
+
- "remove phase"
|
|
18
|
+
- "delete phase"
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
<objective>
|
|
22
|
+
Removes a phase from `.jdi/ROADMAP.md`. Refuses to remove the current phase or any phase already shipped. If the phase has artifacts under `.jdi/phases/<NN-slug>/`, moves them to `.jdi/archive/removed-<NN-slug>/` instead of deleting (preserves history).
|
|
23
|
+
</objective>
|
|
24
|
+
|
|
25
|
+
<arguments>
|
|
26
|
+
- `phase_number` (required) — number of the phase to remove (as listed in ROADMAP.md).
|
|
27
|
+
- `--force` (optional) — required when removing a phase that has any artifacts in `.jdi/phases/`. Without `--force`, the command refuses and explains.
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
- `/jdi-remove-phase 4`
|
|
31
|
+
- `/jdi-remove-phase 5 --force`
|
|
32
|
+
</arguments>
|
|
33
|
+
|
|
34
|
+
<process>
|
|
35
|
+
|
|
36
|
+
### Step 1: Validation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
test -d .jdi/ || { echo "Not a JDI project."; exit 1; }
|
|
40
|
+
test -f .jdi/ROADMAP.md || { echo "ROADMAP.md missing."; exit 1; }
|
|
41
|
+
test -f .jdi/STATE.md || { echo "STATE.md missing."; exit 1; }
|
|
42
|
+
|
|
43
|
+
# Argument required
|
|
44
|
+
[ -n "$1" ] || { echo "Phase number required. Usage: /jdi-remove-phase <N> [--force]"; exit 1; }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Parse `phase_number` (positional). Parse `--force` flag.
|
|
48
|
+
|
|
49
|
+
### Step 2: Read state
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
CURRENT=$(grep -oE 'current_phase:\s*[0-9]+' .jdi/STATE.md | grep -oE '[0-9]+')
|
|
53
|
+
TOTAL=$(grep -oE 'total_phases:\s*[0-9]+' .jdi/ROADMAP.md | grep -oE '[0-9]+')
|
|
54
|
+
PHASE_NUMBER=$1
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
PowerShell:
|
|
58
|
+
```powershell
|
|
59
|
+
$current = (Select-String -Path .jdi/STATE.md -Pattern 'current_phase:\s*([0-9]+)').Matches[0].Groups[1].Value -as [int]
|
|
60
|
+
$total = (Select-String -Path .jdi/ROADMAP.md -Pattern 'total_phases:\s*([0-9]+)').Matches[0].Groups[1].Value -as [int]
|
|
61
|
+
$phaseNumber = [int]$args[0]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Step 3: Hard refuses (no override)
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Must be in range
|
|
68
|
+
if [ "$PHASE_NUMBER" -lt 1 ] || [ "$PHASE_NUMBER" -gt "$TOTAL" ]; then
|
|
69
|
+
echo "Phase $PHASE_NUMBER does not exist. Valid: 1..$TOTAL"
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Cannot remove past phases (preserves history)
|
|
74
|
+
if [ "$PHASE_NUMBER" -lt "$CURRENT" ]; then
|
|
75
|
+
echo "Cannot remove phase $PHASE_NUMBER — already past. current_phase is $CURRENT. Past phases are immutable history."
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# Cannot remove the current phase
|
|
80
|
+
if [ "$PHASE_NUMBER" -eq "$CURRENT" ]; then
|
|
81
|
+
echo "Cannot remove the current phase ($CURRENT). Ship or abandon it first, then advance current_phase."
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Read the phase's `Status:` from ROADMAP:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
STATUS=$(awk "/### Phase $PHASE_NUMBER:/,/^### Phase /" .jdi/ROADMAP.md | grep -oE 'Status:\*\* (pending|ready|done|partial|blocked|in-progress)' | head -1 | awk '{print $2}')
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If `STATUS == done`: refuse hard.
|
|
93
|
+
```
|
|
94
|
+
Phase $PHASE_NUMBER is `done`. Cannot remove. Shipped phases are immutable history.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Step 4: Detect artifacts
|
|
98
|
+
|
|
99
|
+
Find the phase folder under `.jdi/phases/`:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
NN=$(printf '%02d' "$PHASE_NUMBER")
|
|
103
|
+
PHASE_DIR=$(ls -d .jdi/phases/${NN}-*/ 2>/dev/null | head -1 || true)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
PowerShell:
|
|
107
|
+
```powershell
|
|
108
|
+
$nn = '{0:D2}' -f $phaseNumber
|
|
109
|
+
$phaseDir = Get-ChildItem .jdi/phases/ -Directory -Filter "$nn-*" -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
If `PHASE_DIR` exists AND `--force` NOT passed: refuse.
|
|
113
|
+
```
|
|
114
|
+
Phase $PHASE_NUMBER has artifacts in $PHASE_DIR (CONTEXT/PLAN/SUMMARY/REVIEW).
|
|
115
|
+
Re-run with --force to archive these artifacts to .jdi/archive/removed-<NN-slug>/ and proceed.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Step 5: Confirm with user (irreversible-ish action)
|
|
119
|
+
|
|
120
|
+
AskUserQuestion (always run, even with --force):
|
|
121
|
+
|
|
122
|
+
> "Remove phase $PHASE_NUMBER: '$PHASE_NAME'?
|
|
123
|
+
>
|
|
124
|
+
> Status: $STATUS
|
|
125
|
+
> Artifacts: ${PHASE_DIR:-none}
|
|
126
|
+
> Action: ROADMAP section removed, total_phases decremented, artifacts (if any) moved to .jdi/archive/removed-<NN-slug>/."
|
|
127
|
+
>
|
|
128
|
+
> Options:
|
|
129
|
+
> - [Yes, remove]
|
|
130
|
+
> - [Cancel]
|
|
131
|
+
|
|
132
|
+
If "Cancel" -> exit clean.
|
|
133
|
+
|
|
134
|
+
### Step 6: Archive artifacts (if any)
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
if [ -n "$PHASE_DIR" ]; then
|
|
138
|
+
mkdir -p .jdi/archive
|
|
139
|
+
test -f .jdi/archive/index.md || echo "# Archive index" > .jdi/archive/index.md
|
|
140
|
+
|
|
141
|
+
BASENAME=$(basename "$PHASE_DIR")
|
|
142
|
+
TARGET=".jdi/archive/removed-$BASENAME"
|
|
143
|
+
mv "$PHASE_DIR" "$TARGET"
|
|
144
|
+
echo "- removed-$BASENAME (removed $(date -u +%F) via /jdi-remove-phase)" >> .jdi/archive/index.md
|
|
145
|
+
fi
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
PowerShell:
|
|
149
|
+
```powershell
|
|
150
|
+
if ($phaseDir) {
|
|
151
|
+
if (-not (Test-Path .jdi/archive)) { New-Item -ItemType Directory .jdi/archive | Out-Null }
|
|
152
|
+
if (-not (Test-Path .jdi/archive/index.md)) { Set-Content .jdi/archive/index.md "# Archive index" }
|
|
153
|
+
$basename = $phaseDir.Name
|
|
154
|
+
$target = ".jdi/archive/removed-$basename"
|
|
155
|
+
Move-Item $phaseDir.FullName $target
|
|
156
|
+
Add-Content .jdi/archive/index.md "- removed-$basename (removed $(Get-Date -Format 'yyyy-MM-dd') via /jdi-remove-phase)"
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Step 7: Edit ROADMAP.md
|
|
161
|
+
|
|
162
|
+
Remove the entire `### Phase $PHASE_NUMBER: ...` block (header + bullets) up to (but not including) the next `### Phase ` line or end of file.
|
|
163
|
+
|
|
164
|
+
Decrement `total_phases`:
|
|
165
|
+
```
|
|
166
|
+
total_phases: {TOTAL - 1}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Do NOT renumber** subsequent phases. Phases after the removed one keep their original numbers. This preserves all references in commit history, `DECISIONS.md`, and archived phase folders. The roadmap simply has a gap (e.g., 1, 2, 3, 5, 6 — 4 was removed).
|
|
170
|
+
|
|
171
|
+
### Step 8: Audit trail in DECISIONS.md
|
|
172
|
+
|
|
173
|
+
Append:
|
|
174
|
+
```markdown
|
|
175
|
+
D-{N+1} ({date}): Phase $PHASE_NUMBER removed via /jdi-remove-phase. Artifacts: ${PHASE_DIR:+archived to .jdi/archive/removed-<NN-slug>/}{none if empty}.
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Step 9: Commit
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
git add .jdi/ROADMAP.md .jdi/DECISIONS.md .jdi/archive/ 2>/dev/null
|
|
182
|
+
git commit -m "chore(jdi): remove phase {PHASE_NUMBER}"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Step 10: Confirm
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
Phase {PHASE_NUMBER} removed.
|
|
189
|
+
{if artifacts:} Artifacts archived: .jdi/archive/removed-{NN-slug}/
|
|
190
|
+
total_phases: {TOTAL - 1}
|
|
191
|
+
|
|
192
|
+
Note: phase numbers are not renumbered — references in commits, DECISIONS, and archive remain valid.
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
</process>
|
|
196
|
+
|
|
197
|
+
<gates>
|
|
198
|
+
- pre: `.jdi/ROADMAP.md` + `.jdi/STATE.md` exist
|
|
199
|
+
- pre: `phase_number` is in range `1..total_phases`
|
|
200
|
+
- pre: `phase_number > current_phase`
|
|
201
|
+
- pre: phase status != `done`
|
|
202
|
+
- pre: `--force` provided when phase has artifacts
|
|
203
|
+
- post: ROADMAP.md section removed + total_phases decremented + artifacts archived (if any) + DECISIONS.md appended + atomic commit
|
|
204
|
+
</gates>
|
|
205
|
+
|
|
206
|
+
<errors>
|
|
207
|
+
- `.jdi/` missing -> "Run /jdi-new first"
|
|
208
|
+
- `phase_number` missing -> usage hint
|
|
209
|
+
- `phase_number` out of range -> "Valid: 1..{total}"
|
|
210
|
+
- `phase_number < current_phase` -> refuse (past = history)
|
|
211
|
+
- `phase_number == current_phase` -> refuse (ship or abandon first)
|
|
212
|
+
- phase status `done` -> refuse (shipped = history)
|
|
213
|
+
- artifacts exist + no `--force` -> refuse + suggest `--force`
|
|
214
|
+
- user cancels at AskUserQuestion -> exit clean
|
|
215
|
+
</errors>
|
|
216
|
+
|
|
217
|
+
<runtime_notes>
|
|
218
|
+
|
|
219
|
+
**Claude Code:**
|
|
220
|
+
- Confirms via AskUserQuestion.
|
|
221
|
+
|
|
222
|
+
**Copilot:**
|
|
223
|
+
- AskUserQuestion not always available — require explicit `--yes` flag as fallback.
|
|
224
|
+
|
|
225
|
+
**OpenCode/Antigravity:**
|
|
226
|
+
- Same interactive confirm as Claude. Fallback to `--yes` when prompts unsupported.
|
|
227
|
+
|
|
228
|
+
</runtime_notes>
|