@leeovery/claude-technical-workflows 2.1.25 → 2.1.27
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 +1 -1
- package/package.json +1 -1
- package/skills/start-planning/SKILL.md +4 -176
- package/skills/start-planning/references/cross-cutting-context.md +50 -0
- package/skills/start-planning/references/display-state.md +109 -0
- package/skills/start-planning/references/invoke-skill.md +29 -0
- package/skills/status/SKILL.md +157 -43
- package/skills/status/scripts/discovery.sh +420 -0
package/README.md
CHANGED
|
@@ -291,7 +291,7 @@ Helpers for navigating and maintaining the workflow.
|
|
|
291
291
|
| Skill | Description |
|
|
292
292
|
|------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
|
293
293
|
| [**/migrate**](skills/migrate/) | Keep workflow files in sync with the current system design. Runs automatically at the start of every workflow skill. |
|
|
294
|
-
| [**/status**](skills/status/) | Show workflow status -
|
|
294
|
+
| [**/status**](skills/status/) | Show workflow status with relationship-aware display — specification sources, unlinked discussions, plan dependencies, and suggested next steps. |
|
|
295
295
|
| [**/view-plan**](skills/view-plan/) | View a plan's tasks and progress, regardless of output format. |
|
|
296
296
|
|
|
297
297
|
#### Standalone Skills
|
package/package.json
CHANGED
|
@@ -126,113 +126,9 @@ At least one specification is ready for planning, or an existing plan can be con
|
|
|
126
126
|
|
|
127
127
|
## Step 3: Present Workflow State and Options
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
Load **[display-state.md](references/display-state.md)** and follow its instructions as written.
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
> *Output the next fenced block as a code block:*
|
|
134
|
-
|
|
135
|
-
```
|
|
136
|
-
Planning Overview
|
|
137
|
-
|
|
138
|
-
{N} specifications found. {M} plans exist.
|
|
139
|
-
|
|
140
|
-
1. {topic:(titlecase)}
|
|
141
|
-
└─ Plan: @if(has_plan) {plan_status:[in-progress|concluded]} @else (no plan) @endif
|
|
142
|
-
└─ Spec: concluded
|
|
143
|
-
|
|
144
|
-
2. ...
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
**Tree rules:**
|
|
148
|
-
|
|
149
|
-
Each numbered item shows a feature specification that is actionable:
|
|
150
|
-
- Concluded spec with no plan → `Plan: (no plan)`
|
|
151
|
-
- Has a plan with `plan_status: planning` → `Plan: in-progress`
|
|
152
|
-
- Has a plan with `plan_status: concluded` → `Plan: concluded`
|
|
153
|
-
|
|
154
|
-
**If non-plannable specifications exist**, show them in a separate code block:
|
|
155
|
-
|
|
156
|
-
> *Output the next fenced block as a code block:*
|
|
157
|
-
|
|
158
|
-
```
|
|
159
|
-
Specifications not ready for planning:
|
|
160
|
-
These specifications are either still in progress or cross-cutting
|
|
161
|
-
and cannot be planned directly.
|
|
162
|
-
|
|
163
|
-
• {topic} ({type:[feature|cross-cutting]}, {status:[in-progress|concluded]})
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
**Key/Legend** — show only statuses that appear in the current display. No `---` separator before this section.
|
|
167
|
-
|
|
168
|
-
> *Output the next fenced block as a code block:*
|
|
169
|
-
|
|
170
|
-
```
|
|
171
|
-
Key:
|
|
172
|
-
|
|
173
|
-
Plan status:
|
|
174
|
-
in-progress — planning work is ongoing
|
|
175
|
-
concluded — plan is complete
|
|
176
|
-
|
|
177
|
-
Spec type:
|
|
178
|
-
cross-cutting — architectural policy, not directly plannable
|
|
179
|
-
feature — plannable feature specification
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Omit any section entirely if it has no entries.
|
|
183
|
-
|
|
184
|
-
**Then prompt based on what's actionable:**
|
|
185
|
-
|
|
186
|
-
**If multiple actionable items:**
|
|
187
|
-
|
|
188
|
-
The verb in the menu depends on the plan state:
|
|
189
|
-
- No plan exists → **Create**
|
|
190
|
-
- Plan is `in-progress` → **Continue**
|
|
191
|
-
- Plan is `concluded` → **Review**
|
|
192
|
-
|
|
193
|
-
> *Output the next fenced block as markdown (not a code block):*
|
|
194
|
-
|
|
195
|
-
```
|
|
196
|
-
· · · · · · · · · · · ·
|
|
197
|
-
1. Create "Auth Flow" — concluded spec, no plan
|
|
198
|
-
2. Continue "Data Model" — plan in-progress
|
|
199
|
-
3. Review "Billing" — plan concluded
|
|
200
|
-
|
|
201
|
-
Select an option (enter number):
|
|
202
|
-
· · · · · · · · · · · ·
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
Recreate with actual topics and states from discovery.
|
|
206
|
-
|
|
207
|
-
**STOP.** Wait for user response.
|
|
208
|
-
|
|
209
|
-
**If single actionable item (auto-select):**
|
|
210
|
-
|
|
211
|
-
> *Output the next fenced block as a code block:*
|
|
212
|
-
|
|
213
|
-
```
|
|
214
|
-
Automatically proceeding with "{topic:(titlecase)}".
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
→ Proceed directly to **Step 4**.
|
|
218
|
-
|
|
219
|
-
**If nothing actionable:**
|
|
220
|
-
|
|
221
|
-
> *Output the next fenced block as a code block:*
|
|
222
|
-
|
|
223
|
-
```
|
|
224
|
-
Planning Overview
|
|
225
|
-
|
|
226
|
-
No plannable specifications found.
|
|
227
|
-
|
|
228
|
-
The planning phase requires a concluded feature specification.
|
|
229
|
-
Complete any in-progress specifications with /start-specification,
|
|
230
|
-
or create a new specification first.
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
**STOP.** Do not proceed — terminal condition.
|
|
234
|
-
|
|
235
|
-
→ Based on user choice, proceed to **Step 4**.
|
|
131
|
+
→ Proceed to **Step 4**.
|
|
236
132
|
|
|
237
133
|
---
|
|
238
134
|
|
|
@@ -273,46 +169,7 @@ Any additional context since the specification was concluded?
|
|
|
273
169
|
|
|
274
170
|
## Step 6: Surface Cross-Cutting Context
|
|
275
171
|
|
|
276
|
-
**
|
|
277
|
-
|
|
278
|
-
Read each cross-cutting specification from `specifications.crosscutting` in the discovery output.
|
|
279
|
-
|
|
280
|
-
### 6a: Warn about in-progress cross-cutting specs
|
|
281
|
-
|
|
282
|
-
If any **in-progress** cross-cutting specifications exist, check whether they could be relevant to the feature being planned (by topic overlap — e.g., a caching strategy is relevant if the feature involves data retrieval or API calls).
|
|
283
|
-
|
|
284
|
-
If any are relevant:
|
|
285
|
-
|
|
286
|
-
> *Output the next fenced block as markdown (not a code block):*
|
|
287
|
-
|
|
288
|
-
```
|
|
289
|
-
Cross-cutting specifications still in progress:
|
|
290
|
-
These may contain architectural decisions relevant to this plan.
|
|
291
|
-
|
|
292
|
-
• {topic}
|
|
293
|
-
|
|
294
|
-
· · · · · · · · · · · ·
|
|
295
|
-
- **`c`/`continue`** — Plan without them
|
|
296
|
-
- **`s`/`stop`** — Complete them first (/start-specification)
|
|
297
|
-
· · · · · · · · · · · ·
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
**STOP.** Wait for user response.
|
|
301
|
-
|
|
302
|
-
If the user chooses to stop, end here. If they choose to continue, proceed.
|
|
303
|
-
|
|
304
|
-
### 6b: Summarize concluded cross-cutting specs
|
|
305
|
-
|
|
306
|
-
If any **concluded** cross-cutting specifications exist, identify which are relevant to the feature being planned and summarize for handoff:
|
|
307
|
-
|
|
308
|
-
> *Output the next fenced block as a code block:*
|
|
309
|
-
|
|
310
|
-
```
|
|
311
|
-
Cross-cutting specifications to reference:
|
|
312
|
-
- caching-strategy.md: [brief summary of key decisions]
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
These specifications contain validated architectural decisions that should inform the plan. The planning skill will incorporate these as a "Cross-Cutting References" section in the plan.
|
|
172
|
+
Load **[cross-cutting-context.md](references/cross-cutting-context.md)** and follow its instructions as written.
|
|
316
173
|
|
|
317
174
|
→ Proceed to **Step 7**.
|
|
318
175
|
|
|
@@ -320,33 +177,4 @@ These specifications contain validated architectural decisions that should infor
|
|
|
320
177
|
|
|
321
178
|
## Step 7: Invoke the Skill
|
|
322
179
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
Invoke the [technical-planning](../technical-planning/SKILL.md) skill for your next instructions. Do not act on the gathered information until the skill is loaded - it contains the instructions for how to proceed.
|
|
326
|
-
|
|
327
|
-
**Example handoff (fresh plan):**
|
|
328
|
-
```
|
|
329
|
-
Planning session for: {topic}
|
|
330
|
-
Specification: docs/workflow/specification/{topic}.md
|
|
331
|
-
Additional context: {summary of user's answers from Step 5}
|
|
332
|
-
Cross-cutting references: {list of applicable cross-cutting specs with brief summaries, or "none"}
|
|
333
|
-
Recommended output format: {common_format from discovery if non-empty, otherwise "none"}
|
|
334
|
-
|
|
335
|
-
Invoke the technical-planning skill.
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
**Example handoff (continue/review existing plan):**
|
|
339
|
-
```
|
|
340
|
-
Planning session for: {topic}
|
|
341
|
-
Specification: docs/workflow/specification/{topic}.md
|
|
342
|
-
Existing plan: docs/workflow/planning/{topic}.md
|
|
343
|
-
|
|
344
|
-
Invoke the technical-planning skill.
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
## Notes
|
|
348
|
-
|
|
349
|
-
- Ask questions clearly and wait for responses before proceeding
|
|
350
|
-
- The feature specification is the primary source of truth for planning
|
|
351
|
-
- Cross-cutting specifications provide supplementary context for architectural decisions
|
|
352
|
-
- Do not reference discussions - only specifications
|
|
180
|
+
Load **[invoke-skill.md](references/invoke-skill.md)** and follow its instructions as written.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Cross-Cutting Context
|
|
2
|
+
|
|
3
|
+
*Reference for **[start-planning](../SKILL.md)***
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**If no cross-cutting specifications exist**:
|
|
8
|
+
|
|
9
|
+
Skip this step.
|
|
10
|
+
|
|
11
|
+
→ Proceed to **Step 7**.
|
|
12
|
+
|
|
13
|
+
Read each cross-cutting specification from `specifications.crosscutting` in the discovery output.
|
|
14
|
+
|
|
15
|
+
### 6a: Warn about in-progress cross-cutting specs
|
|
16
|
+
|
|
17
|
+
If any **in-progress** cross-cutting specifications exist, check whether they could be relevant to the feature being planned (by topic overlap — e.g., a caching strategy is relevant if the feature involves data retrieval or API calls).
|
|
18
|
+
|
|
19
|
+
If any are relevant:
|
|
20
|
+
|
|
21
|
+
> *Output the next fenced block as markdown (not a code block):*
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Cross-cutting specifications still in progress:
|
|
25
|
+
These may contain architectural decisions relevant to this plan.
|
|
26
|
+
|
|
27
|
+
• {topic}
|
|
28
|
+
|
|
29
|
+
· · · · · · · · · · · ·
|
|
30
|
+
- **`c`/`continue`** — Plan without them
|
|
31
|
+
- **`s`/`stop`** — Complete them first (/start-specification)
|
|
32
|
+
· · · · · · · · · · · ·
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**STOP.** Wait for user response.
|
|
36
|
+
|
|
37
|
+
If the user chooses to stop, end here. If they choose to continue, proceed.
|
|
38
|
+
|
|
39
|
+
### 6b: Summarize concluded cross-cutting specs
|
|
40
|
+
|
|
41
|
+
If any **concluded** cross-cutting specifications exist, identify which are relevant to the feature being planned and summarize for handoff:
|
|
42
|
+
|
|
43
|
+
> *Output the next fenced block as a code block:*
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Cross-cutting specifications to reference:
|
|
47
|
+
- caching-strategy.md: [brief summary of key decisions]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
These specifications contain validated architectural decisions that should inform the plan. The planning skill will incorporate these as a "Cross-Cutting References" section in the plan.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Display State and Options
|
|
2
|
+
|
|
3
|
+
*Reference for **[start-planning](../SKILL.md)***
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Present everything discovered to help the user make an informed choice.
|
|
8
|
+
|
|
9
|
+
**Present the full state:**
|
|
10
|
+
|
|
11
|
+
> *Output the next fenced block as a code block:*
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Planning Overview
|
|
15
|
+
|
|
16
|
+
{N} specifications found. {M} plans exist.
|
|
17
|
+
|
|
18
|
+
1. {topic:(titlecase)}
|
|
19
|
+
└─ Plan: @if(has_plan) {plan_status:[in-progress|concluded]} @else (no plan) @endif
|
|
20
|
+
└─ Spec: concluded
|
|
21
|
+
|
|
22
|
+
2. ...
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Tree rules:**
|
|
26
|
+
|
|
27
|
+
Each numbered item shows a feature specification that is actionable:
|
|
28
|
+
- Concluded spec with no plan → `Plan: (no plan)`
|
|
29
|
+
- Has a plan with `plan_status: planning` → `Plan: in-progress`
|
|
30
|
+
- Has a plan with `plan_status: concluded` → `Plan: concluded`
|
|
31
|
+
|
|
32
|
+
**If non-plannable specifications exist**, show them in a separate code block:
|
|
33
|
+
|
|
34
|
+
> *Output the next fenced block as a code block:*
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Specifications not ready for planning:
|
|
38
|
+
These specifications are either still in progress or cross-cutting
|
|
39
|
+
and cannot be planned directly.
|
|
40
|
+
|
|
41
|
+
• {topic} ({type:[feature|cross-cutting]}, {status:[in-progress|concluded]})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Key/Legend** — show only statuses that appear in the current display. No `---` separator before this section.
|
|
45
|
+
|
|
46
|
+
> *Output the next fenced block as a code block:*
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Key:
|
|
50
|
+
|
|
51
|
+
Plan status:
|
|
52
|
+
in-progress — planning work is ongoing
|
|
53
|
+
concluded — plan is complete
|
|
54
|
+
|
|
55
|
+
Spec type:
|
|
56
|
+
cross-cutting — architectural policy, not directly plannable
|
|
57
|
+
feature — plannable feature specification
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Omit any section entirely if it has no entries.
|
|
61
|
+
|
|
62
|
+
**Then prompt based on what's actionable:**
|
|
63
|
+
|
|
64
|
+
**If multiple actionable items:**
|
|
65
|
+
|
|
66
|
+
The verb in the menu depends on the plan state:
|
|
67
|
+
- No plan exists → **Create**
|
|
68
|
+
- Plan is `in-progress` → **Continue**
|
|
69
|
+
- Plan is `concluded` → **Review**
|
|
70
|
+
|
|
71
|
+
> *Output the next fenced block as markdown (not a code block):*
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
· · · · · · · · · · · ·
|
|
75
|
+
1. Create "Auth Flow" — concluded spec, no plan
|
|
76
|
+
2. Continue "Data Model" — plan in-progress
|
|
77
|
+
3. Review "Billing" — plan concluded
|
|
78
|
+
|
|
79
|
+
Select an option (enter number):
|
|
80
|
+
· · · · · · · · · · · ·
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Recreate with actual topics and states from discovery.
|
|
84
|
+
|
|
85
|
+
**STOP.** Wait for user response.
|
|
86
|
+
|
|
87
|
+
**If single actionable item (auto-select):**
|
|
88
|
+
|
|
89
|
+
> *Output the next fenced block as a code block:*
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
Automatically proceeding with "{topic:(titlecase)}".
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**If nothing actionable:**
|
|
96
|
+
|
|
97
|
+
> *Output the next fenced block as a code block:*
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
Planning Overview
|
|
101
|
+
|
|
102
|
+
No plannable specifications found.
|
|
103
|
+
|
|
104
|
+
The planning phase requires a concluded feature specification.
|
|
105
|
+
Complete any in-progress specifications with /start-specification,
|
|
106
|
+
or create a new specification first.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**STOP.** Do not proceed — terminal condition.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Invoke the Skill
|
|
2
|
+
|
|
3
|
+
*Reference for **[start-planning](../SKILL.md)***
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
After completing the steps above, this skill's purpose is fulfilled.
|
|
8
|
+
|
|
9
|
+
Invoke the [technical-planning](../../technical-planning/SKILL.md) skill for your next instructions. Do not act on the gathered information until the skill is loaded - it contains the instructions for how to proceed.
|
|
10
|
+
|
|
11
|
+
**Example handoff (fresh plan):**
|
|
12
|
+
```
|
|
13
|
+
Planning session for: {topic}
|
|
14
|
+
Specification: docs/workflow/specification/{topic}.md
|
|
15
|
+
Additional context: {summary of user's answers from Step 5}
|
|
16
|
+
Cross-cutting references: {list of applicable cross-cutting specs with brief summaries, or "none"}
|
|
17
|
+
Recommended output format: {common_format from discovery if non-empty, otherwise "none"}
|
|
18
|
+
|
|
19
|
+
Invoke the technical-planning skill.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Example handoff (continue/review existing plan):**
|
|
23
|
+
```
|
|
24
|
+
Planning session for: {topic}
|
|
25
|
+
Specification: docs/workflow/specification/{topic}.md
|
|
26
|
+
Existing plan: docs/workflow/planning/{topic}.md
|
|
27
|
+
|
|
28
|
+
Invoke the technical-planning skill.
|
|
29
|
+
```
|
package/skills/status/SKILL.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name: status
|
|
3
3
|
description: "Show workflow status - what exists, where you are, and what to do next."
|
|
4
4
|
disable-model-invocation: true
|
|
5
|
+
allowed-tools: Bash(.claude/skills/status/scripts/discovery.sh)
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
Show the current state of the workflow for this project.
|
|
@@ -12,81 +13,194 @@ Show the current state of the workflow for this project.
|
|
|
12
13
|
|
|
13
14
|
Invoke the `/migrate` skill and assess its output.
|
|
14
15
|
|
|
15
|
-
**If files were updated**: STOP and wait for the user to review the changes (e.g., via `git diff`) and confirm before proceeding to Step 1.
|
|
16
|
+
**If files were updated**: STOP and wait for the user to review the changes (e.g., via `git diff`) and confirm before proceeding to Step 1.
|
|
16
17
|
|
|
17
18
|
**If no updates needed**: Proceed to Step 1.
|
|
18
19
|
|
|
19
20
|
---
|
|
20
21
|
|
|
21
|
-
## Step 1:
|
|
22
|
+
## Step 1: Discovery State
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
!`.claude/skills/status/scripts/discovery.sh`
|
|
24
25
|
|
|
26
|
+
If the above shows a script invocation rather than YAML output, the dynamic content preprocessor did not run. Execute the script before continuing:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
.claude/skills/status/scripts/discovery.sh
|
|
25
30
|
```
|
|
26
|
-
docs/workflow/research/
|
|
27
|
-
docs/workflow/discussion/
|
|
28
|
-
docs/workflow/specification/
|
|
29
|
-
docs/workflow/planning/
|
|
30
|
-
docs/workflow/implementation/
|
|
31
|
-
```
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
If YAML content is already displayed, it has been run on your behalf.
|
|
33
|
+
|
|
34
|
+
Parse the discovery output. **IMPORTANT**: Use ONLY this script for discovery. Do NOT run additional bash commands (ls, head, cat, etc.) to gather state.
|
|
35
|
+
|
|
36
|
+
→ Proceed to **Step 2**.
|
|
37
|
+
|
|
38
|
+
---
|
|
34
39
|
|
|
35
40
|
## Step 2: Present Status
|
|
36
41
|
|
|
37
|
-
|
|
42
|
+
Build the display from discovery data. Only show sections for phases that have content.
|
|
43
|
+
|
|
44
|
+
**CRITICAL**: Entities don't flow one-to-one across phases. Multiple discussions may combine into one specification, topic names may change between phases, and specs may be superseded. The display must make these relationships visible — primarily through the specification's `sources` array.
|
|
38
45
|
|
|
39
|
-
|
|
46
|
+
### 2a: Summary
|
|
47
|
+
|
|
48
|
+
> *Output the next fenced block as a code block:*
|
|
40
49
|
|
|
41
50
|
```
|
|
42
|
-
|
|
51
|
+
Workflow Status
|
|
43
52
|
|
|
44
|
-
|
|
53
|
+
Research: {count} file(s)
|
|
54
|
+
Discussion: {count} ({concluded} concluded, {in_progress} in-progress)
|
|
55
|
+
Specification: {active} active ({feature} feature, {crosscutting} cross-cutting)
|
|
56
|
+
Planning: {count} ({concluded} concluded, {in_progress} in-progress)
|
|
57
|
+
Implementation: {count} ({completed} completed, {in_progress} in-progress)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Only show lines for phases that have content. If a phase has zero items but a later phase has content, show the line as `(none)` to highlight the gap.
|
|
61
|
+
|
|
62
|
+
#### If no workflow content exists at all
|
|
63
|
+
|
|
64
|
+
> *Output the next fenced block as a code block:*
|
|
45
65
|
|
|
46
|
-
| Topic | Discussion | Spec | Plan | Implemented |
|
|
47
|
-
|-------|------------|------|------|-------------|
|
|
48
|
-
| {topic} | {discussion_status} | {spec_status} | {plan_status} | {impl_status} |
|
|
49
|
-
| ... | | | | |
|
|
50
66
|
```
|
|
67
|
+
Workflow Status
|
|
51
68
|
|
|
52
|
-
|
|
53
|
-
- If a directory is empty or missing, show `-`
|
|
54
|
-
- For planning, note the output format if specified in frontmatter
|
|
55
|
-
- Match topics across phases by filename
|
|
56
|
-
- For implementation, derive the Implemented column from tracking file data:
|
|
57
|
-
- No tracking file → `-`
|
|
58
|
-
- `status: not-started` → `not started`
|
|
59
|
-
- `status: in-progress` → `phase {current_phase} ({n}/{total} tasks done)` — count `completed_tasks` for n; use total task count from `completed_tasks` + remaining if available, otherwise just show completed count
|
|
60
|
-
- `status: completed` → `completed`
|
|
69
|
+
No workflow files found in docs/workflow/
|
|
61
70
|
|
|
62
|
-
|
|
71
|
+
Start with /start-research to explore ideas,
|
|
72
|
+
or /start-discussion if you already know what to build.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**STOP.** Do not proceed — terminal condition.
|
|
63
76
|
|
|
64
|
-
|
|
77
|
+
### 2b: Specifications
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
- "Start with `/start-research` to explore ideas, or `/start-discussion` if you already know what you're building."
|
|
79
|
+
Show if any specifications exist. This is the most important section — it reveals many-to-one relationships between discussions and specifications.
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
- Completed implementations can be reviewed
|
|
81
|
+
> *Output the next fenced block as a code block:*
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Specifications
|
|
74
85
|
|
|
75
|
-
|
|
86
|
+
1. {name:(titlecase)} ({status})
|
|
87
|
+
└─ Sources: @if(no_sources) (none) @else
|
|
88
|
+
├─ {src} ({src_status})
|
|
89
|
+
└─ ...
|
|
90
|
+
@endif
|
|
91
|
+
|
|
92
|
+
2. ...
|
|
93
|
+
```
|
|
76
94
|
|
|
77
|
-
|
|
95
|
+
**Rules:**
|
|
96
|
+
|
|
97
|
+
- Each numbered item is an active (non-superseded) specification
|
|
98
|
+
- Show `(cross-cutting)` after status for cross-cutting specs; omit type label for feature specs
|
|
99
|
+
- Blank line between numbered items
|
|
100
|
+
- If superseded specs exist, show after the numbered list:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
Superseded:
|
|
104
|
+
• {name} → {superseded_by}
|
|
105
|
+
```
|
|
78
106
|
|
|
79
|
-
|
|
107
|
+
### 2c: Plans
|
|
80
108
|
|
|
81
|
-
|
|
109
|
+
Show if any plans exist.
|
|
82
110
|
|
|
83
111
|
> *Output the next fenced block as a code block:*
|
|
84
112
|
|
|
85
113
|
```
|
|
86
|
-
|
|
114
|
+
Plans
|
|
115
|
+
|
|
116
|
+
1. {name:(titlecase)} ({status})
|
|
117
|
+
└─ Spec: {specification_name}
|
|
118
|
+
@if(has_unresolved_deps) └─ Blocked:
|
|
119
|
+
├─ {dep_topic}:{dep_task_id} ({dep_state})
|
|
120
|
+
└─ ...
|
|
121
|
+
@endif
|
|
122
|
+
|
|
123
|
+
2. ...
|
|
87
124
|
```
|
|
88
125
|
|
|
126
|
+
**Rules:**
|
|
127
|
+
|
|
128
|
+
- Map raw `planning` status to `in-progress` in the display
|
|
129
|
+
- Show spec name without `.md` extension
|
|
130
|
+
|
|
131
|
+
### 2d: Implementation
|
|
132
|
+
|
|
133
|
+
Show if any implementations exist.
|
|
134
|
+
|
|
135
|
+
> *Output the next fenced block as a code block:*
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
Implementation
|
|
139
|
+
|
|
140
|
+
1. {topic:(titlecase)} ({status})
|
|
141
|
+
└─ Phase {current_phase}, {completed_tasks}/{total_tasks} tasks done
|
|
142
|
+
|
|
143
|
+
2. ...
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Rules:**
|
|
147
|
+
|
|
148
|
+
- `not-started` → `└─ Not started`
|
|
149
|
+
- `in-progress` → phase and task progress; if `total_tasks` is 0, show `{completed_tasks} tasks done` without denominator
|
|
150
|
+
- `completed` → `└─ Complete`
|
|
151
|
+
|
|
152
|
+
### 2e: Unlinked Discussions
|
|
153
|
+
|
|
154
|
+
Derive which discussions are NOT referenced in any active (non-superseded) specification's `sources` array. Show only if unlinked discussions exist.
|
|
155
|
+
|
|
156
|
+
> *Output the next fenced block as a code block:*
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
Discussions not yet in a specification:
|
|
160
|
+
|
|
161
|
+
• {name} ({status})
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 2f: Key
|
|
165
|
+
|
|
166
|
+
Show if the display uses statuses that benefit from explanation. Only include statuses actually shown. No `---` separator before this section.
|
|
167
|
+
|
|
168
|
+
> *Output the next fenced block as a code block:*
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
Key:
|
|
172
|
+
|
|
173
|
+
Status:
|
|
174
|
+
in-progress — work is ongoing
|
|
175
|
+
concluded — complete, ready for next step
|
|
176
|
+
superseded — replaced by another specification
|
|
177
|
+
|
|
178
|
+
Spec type:
|
|
179
|
+
cross-cutting — architectural policy, not directly plannable
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Omit categories with no entries.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Step 3: Suggest Next Steps
|
|
187
|
+
|
|
188
|
+
Based on gaps in the workflow, briefly suggest 2-3 most relevant actions:
|
|
189
|
+
|
|
190
|
+
- Concluded discussions not in any spec → `/start-specification`
|
|
191
|
+
- In-progress specs → finish with `/start-specification`
|
|
192
|
+
- Concluded feature specs without plans → `/start-planning`
|
|
193
|
+
- Concluded plans not yet implemented → `/start-implementation`
|
|
194
|
+
- Completed implementations → `/start-review`
|
|
195
|
+
|
|
196
|
+
If plans exist, mention `/view-plan` for detailed plan viewing.
|
|
197
|
+
|
|
198
|
+
Keep suggestions brief — the user knows their project better than we do.
|
|
199
|
+
|
|
89
200
|
## Notes
|
|
90
201
|
|
|
91
|
-
- Keep output
|
|
92
|
-
-
|
|
202
|
+
- Keep output scannable — this is a status check, not a deep analysis
|
|
203
|
+
- Discussions may appear in multiple specifications' sources
|
|
204
|
+
- A discussion not appearing in any active spec's sources is "unlinked"
|
|
205
|
+
- Research files are project-wide, not topic-specific
|
|
206
|
+
- Topic names may differ across phases (e.g., discussions "auth-flow" and "session-mgmt" may combine into specification "auth-system")
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Discovers the full workflow state across all phases
|
|
4
|
+
# for the /status command.
|
|
5
|
+
#
|
|
6
|
+
# Outputs structured YAML that the command can consume directly.
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
set -eo pipefail
|
|
10
|
+
|
|
11
|
+
RESEARCH_DIR="docs/workflow/research"
|
|
12
|
+
DISCUSSION_DIR="docs/workflow/discussion"
|
|
13
|
+
SPEC_DIR="docs/workflow/specification"
|
|
14
|
+
PLAN_DIR="docs/workflow/planning"
|
|
15
|
+
IMPL_DIR="docs/workflow/implementation"
|
|
16
|
+
|
|
17
|
+
# Helper: Extract a frontmatter field value from a file
|
|
18
|
+
# Usage: extract_field <file> <field_name>
|
|
19
|
+
extract_field() {
|
|
20
|
+
local file="$1"
|
|
21
|
+
local field="$2"
|
|
22
|
+
local value=""
|
|
23
|
+
|
|
24
|
+
if head -1 "$file" 2>/dev/null | grep -q "^---$"; then
|
|
25
|
+
value=$(sed -n '2,/^---$/p' "$file" 2>/dev/null | \
|
|
26
|
+
grep -i -m1 "^${field}:" | \
|
|
27
|
+
sed -E "s/^${field}:[[:space:]]*//i" || true)
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
echo "$value"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Helper: Extract frontmatter content (between first pair of --- delimiters)
|
|
34
|
+
extract_frontmatter() {
|
|
35
|
+
local file="$1"
|
|
36
|
+
awk 'BEGIN{c=0} /^---$/{c++; if(c==2) exit; next} c==1{print}' "$file" 2>/dev/null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Helper: Extract sources from specification frontmatter
|
|
40
|
+
# Outputs: name|status per line (object format only; legacy converted by migration 004)
|
|
41
|
+
extract_sources() {
|
|
42
|
+
local file="$1"
|
|
43
|
+
local in_sources=false
|
|
44
|
+
local current_name=""
|
|
45
|
+
local current_status=""
|
|
46
|
+
|
|
47
|
+
while IFS= read -r line; do
|
|
48
|
+
if [[ "$line" =~ ^sources: ]]; then
|
|
49
|
+
in_sources=true
|
|
50
|
+
continue
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
if $in_sources && [[ "$line" =~ ^[a-z_]+: ]] && [[ ! "$line" =~ ^[[:space:]] ]]; then
|
|
54
|
+
if [ -n "$current_name" ]; then
|
|
55
|
+
echo "${current_name}|${current_status:-incorporated}"
|
|
56
|
+
fi
|
|
57
|
+
break
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
if $in_sources; then
|
|
61
|
+
if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*name:[[:space:]]*(.+)$ ]]; then
|
|
62
|
+
if [ -n "$current_name" ]; then
|
|
63
|
+
echo "${current_name}|${current_status:-incorporated}"
|
|
64
|
+
fi
|
|
65
|
+
current_name="${BASH_REMATCH[1]}"
|
|
66
|
+
current_name=$(echo "$current_name" | sed 's/^"//' | sed 's/"$//' | xargs)
|
|
67
|
+
current_status=""
|
|
68
|
+
elif [[ "$line" =~ ^[[:space:]]*status:[[:space:]]*(.+)$ ]]; then
|
|
69
|
+
current_status="${BASH_REMATCH[1]}"
|
|
70
|
+
current_status=$(echo "$current_status" | sed 's/^"//' | sed 's/"$//' | xargs)
|
|
71
|
+
fi
|
|
72
|
+
fi
|
|
73
|
+
done < <(extract_frontmatter "$file")
|
|
74
|
+
|
|
75
|
+
if [ -n "$current_name" ]; then
|
|
76
|
+
echo "${current_name}|${current_status:-incorporated}"
|
|
77
|
+
fi
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# Helper: Extract external_dependencies from plan frontmatter
|
|
81
|
+
# Outputs: topic|state|task_id per line
|
|
82
|
+
extract_external_deps() {
|
|
83
|
+
local file="$1"
|
|
84
|
+
local frontmatter
|
|
85
|
+
frontmatter=$(extract_frontmatter "$file")
|
|
86
|
+
|
|
87
|
+
if ! echo "$frontmatter" | grep -q "^external_dependencies:" 2>/dev/null; then
|
|
88
|
+
return 0
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
if echo "$frontmatter" | grep -q "^external_dependencies:[[:space:]]*\[\]" 2>/dev/null; then
|
|
92
|
+
return 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
echo "$frontmatter" | awk '
|
|
96
|
+
/^external_dependencies:/ { in_block=1; next }
|
|
97
|
+
in_block && /^[a-z_]+:/ && !/^[[:space:]]/ { exit }
|
|
98
|
+
in_block && /^[[:space:]]*- topic:/ {
|
|
99
|
+
if (topic != "") print topic "|" state "|" task_id
|
|
100
|
+
line=$0; gsub(/^[[:space:]]*- topic:[[:space:]]*/, "", line)
|
|
101
|
+
topic=line; state=""; task_id=""
|
|
102
|
+
next
|
|
103
|
+
}
|
|
104
|
+
in_block && /^[[:space:]]*state:/ {
|
|
105
|
+
line=$0; gsub(/^[[:space:]]*state:[[:space:]]*/, "", line)
|
|
106
|
+
state=line; next
|
|
107
|
+
}
|
|
108
|
+
in_block && /^[[:space:]]*task_id:/ {
|
|
109
|
+
line=$0; gsub(/^[[:space:]]*task_id:[[:space:]]*/, "", line)
|
|
110
|
+
task_id=line; next
|
|
111
|
+
}
|
|
112
|
+
END { if (topic != "") print topic "|" state "|" task_id }
|
|
113
|
+
'
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
# Helper: Count completed tasks from implementation tracking
|
|
117
|
+
count_completed_tasks() {
|
|
118
|
+
local file="$1"
|
|
119
|
+
local frontmatter
|
|
120
|
+
frontmatter=$(extract_frontmatter "$file")
|
|
121
|
+
|
|
122
|
+
if echo "$frontmatter" | grep -q "^completed_tasks:[[:space:]]*\[\]" 2>/dev/null; then
|
|
123
|
+
echo 0
|
|
124
|
+
return
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
local count
|
|
128
|
+
count=$(echo "$frontmatter" | awk '
|
|
129
|
+
/^completed_tasks:/ { in_block=1; next }
|
|
130
|
+
in_block && /^[a-z_]+:/ { exit }
|
|
131
|
+
in_block && /^[[:space:]]*-[[:space:]]/ { c++ }
|
|
132
|
+
END { print c+0 }
|
|
133
|
+
')
|
|
134
|
+
echo "$count"
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
# Helper: Count completed phases from implementation tracking
|
|
138
|
+
count_completed_phases() {
|
|
139
|
+
local file="$1"
|
|
140
|
+
local frontmatter
|
|
141
|
+
frontmatter=$(extract_frontmatter "$file")
|
|
142
|
+
|
|
143
|
+
# Handle inline array format: [1, 2, 3]
|
|
144
|
+
local inline
|
|
145
|
+
inline=$(echo "$frontmatter" | grep "^completed_phases:" | sed 's/^completed_phases:[[:space:]]*//' || true)
|
|
146
|
+
if echo "$inline" | grep -q '^\['; then
|
|
147
|
+
local items
|
|
148
|
+
items=$(echo "$inline" | tr -d '[]' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v '^$')
|
|
149
|
+
if [ -n "$items" ]; then
|
|
150
|
+
echo "$items" | wc -l | tr -d ' '
|
|
151
|
+
else
|
|
152
|
+
echo 0
|
|
153
|
+
fi
|
|
154
|
+
return
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
if echo "$frontmatter" | grep -q "^completed_phases:[[:space:]]*\[\]" 2>/dev/null; then
|
|
158
|
+
echo 0
|
|
159
|
+
return
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
local count
|
|
163
|
+
count=$(echo "$frontmatter" | awk '
|
|
164
|
+
/^completed_phases:/ { in_block=1; next }
|
|
165
|
+
in_block && /^[a-z_]+:/ { exit }
|
|
166
|
+
in_block && /^[[:space:]]*-[[:space:]]/ { c++ }
|
|
167
|
+
END { print c+0 }
|
|
168
|
+
')
|
|
169
|
+
echo "$count"
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
# Start YAML output
|
|
174
|
+
echo "# Workflow Status Discovery"
|
|
175
|
+
echo "# Generated: $(date -Iseconds)"
|
|
176
|
+
echo ""
|
|
177
|
+
|
|
178
|
+
#
|
|
179
|
+
# RESEARCH
|
|
180
|
+
#
|
|
181
|
+
echo "research:"
|
|
182
|
+
|
|
183
|
+
research_count=0
|
|
184
|
+
if [ -d "$RESEARCH_DIR" ] && [ -n "$(ls -A "$RESEARCH_DIR" 2>/dev/null)" ]; then
|
|
185
|
+
echo " exists: true"
|
|
186
|
+
echo " files:"
|
|
187
|
+
for file in "$RESEARCH_DIR"/*; do
|
|
188
|
+
[ -f "$file" ] || continue
|
|
189
|
+
name=$(basename "$file" .md)
|
|
190
|
+
echo " - \"$name\""
|
|
191
|
+
research_count=$((research_count + 1))
|
|
192
|
+
done
|
|
193
|
+
echo " count: $research_count"
|
|
194
|
+
else
|
|
195
|
+
echo " exists: false"
|
|
196
|
+
echo " files: []"
|
|
197
|
+
echo " count: 0"
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
echo ""
|
|
201
|
+
|
|
202
|
+
#
|
|
203
|
+
# DISCUSSIONS
|
|
204
|
+
#
|
|
205
|
+
echo "discussions:"
|
|
206
|
+
|
|
207
|
+
disc_count=0
|
|
208
|
+
disc_concluded=0
|
|
209
|
+
disc_in_progress=0
|
|
210
|
+
|
|
211
|
+
if [ -d "$DISCUSSION_DIR" ] && [ -n "$(ls -A "$DISCUSSION_DIR" 2>/dev/null)" ]; then
|
|
212
|
+
echo " exists: true"
|
|
213
|
+
echo " files:"
|
|
214
|
+
for file in "$DISCUSSION_DIR"/*.md; do
|
|
215
|
+
[ -f "$file" ] || continue
|
|
216
|
+
name=$(basename "$file" .md)
|
|
217
|
+
status=$(extract_field "$file" "status")
|
|
218
|
+
status=${status:-"unknown"}
|
|
219
|
+
|
|
220
|
+
echo " - name: \"$name\""
|
|
221
|
+
echo " status: \"$status\""
|
|
222
|
+
|
|
223
|
+
disc_count=$((disc_count + 1))
|
|
224
|
+
[ "$status" = "concluded" ] && disc_concluded=$((disc_concluded + 1))
|
|
225
|
+
[ "$status" = "in-progress" ] && disc_in_progress=$((disc_in_progress + 1))
|
|
226
|
+
done
|
|
227
|
+
echo " count: $disc_count"
|
|
228
|
+
echo " concluded: $disc_concluded"
|
|
229
|
+
echo " in_progress: $disc_in_progress"
|
|
230
|
+
else
|
|
231
|
+
echo " exists: false"
|
|
232
|
+
echo " files: []"
|
|
233
|
+
echo " count: 0"
|
|
234
|
+
echo " concluded: 0"
|
|
235
|
+
echo " in_progress: 0"
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
echo ""
|
|
239
|
+
|
|
240
|
+
#
|
|
241
|
+
# SPECIFICATIONS
|
|
242
|
+
#
|
|
243
|
+
echo "specifications:"
|
|
244
|
+
|
|
245
|
+
spec_count=0
|
|
246
|
+
spec_active=0
|
|
247
|
+
spec_superseded=0
|
|
248
|
+
spec_feature=0
|
|
249
|
+
spec_crosscutting=0
|
|
250
|
+
|
|
251
|
+
if [ -d "$SPEC_DIR" ] && [ -n "$(ls -A "$SPEC_DIR" 2>/dev/null)" ]; then
|
|
252
|
+
echo " exists: true"
|
|
253
|
+
echo " files:"
|
|
254
|
+
for file in "$SPEC_DIR"/*.md; do
|
|
255
|
+
[ -f "$file" ] || continue
|
|
256
|
+
name=$(basename "$file" .md)
|
|
257
|
+
status=$(extract_field "$file" "status")
|
|
258
|
+
status=${status:-"in-progress"}
|
|
259
|
+
spec_type=$(extract_field "$file" "type")
|
|
260
|
+
spec_type=${spec_type:-"feature"}
|
|
261
|
+
superseded_by=$(extract_field "$file" "superseded_by")
|
|
262
|
+
|
|
263
|
+
echo " - name: \"$name\""
|
|
264
|
+
echo " status: \"$status\""
|
|
265
|
+
echo " type: \"$spec_type\""
|
|
266
|
+
[ -n "$superseded_by" ] && echo " superseded_by: \"$superseded_by\""
|
|
267
|
+
|
|
268
|
+
# Sources
|
|
269
|
+
sources_output=$(extract_sources "$file")
|
|
270
|
+
if [ -n "$sources_output" ]; then
|
|
271
|
+
echo " sources:"
|
|
272
|
+
while IFS='|' read -r src_name src_status; do
|
|
273
|
+
[ -z "$src_name" ] && continue
|
|
274
|
+
echo " - name: \"$src_name\""
|
|
275
|
+
echo " status: \"$src_status\""
|
|
276
|
+
done <<< "$sources_output"
|
|
277
|
+
else
|
|
278
|
+
echo " sources: []"
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
spec_count=$((spec_count + 1))
|
|
282
|
+
if [ "$status" = "superseded" ]; then
|
|
283
|
+
spec_superseded=$((spec_superseded + 1))
|
|
284
|
+
else
|
|
285
|
+
spec_active=$((spec_active + 1))
|
|
286
|
+
[ "$spec_type" = "cross-cutting" ] && spec_crosscutting=$((spec_crosscutting + 1))
|
|
287
|
+
[ "$spec_type" != "cross-cutting" ] && spec_feature=$((spec_feature + 1))
|
|
288
|
+
fi
|
|
289
|
+
done
|
|
290
|
+
echo " count: $spec_count"
|
|
291
|
+
echo " active: $spec_active"
|
|
292
|
+
echo " superseded: $spec_superseded"
|
|
293
|
+
echo " feature: $spec_feature"
|
|
294
|
+
echo " crosscutting: $spec_crosscutting"
|
|
295
|
+
else
|
|
296
|
+
echo " exists: false"
|
|
297
|
+
echo " files: []"
|
|
298
|
+
echo " count: 0"
|
|
299
|
+
echo " active: 0"
|
|
300
|
+
echo " superseded: 0"
|
|
301
|
+
echo " feature: 0"
|
|
302
|
+
echo " crosscutting: 0"
|
|
303
|
+
fi
|
|
304
|
+
|
|
305
|
+
echo ""
|
|
306
|
+
|
|
307
|
+
#
|
|
308
|
+
# PLANS
|
|
309
|
+
#
|
|
310
|
+
echo "plans:"
|
|
311
|
+
|
|
312
|
+
plan_count=0
|
|
313
|
+
plan_concluded=0
|
|
314
|
+
plan_in_progress=0
|
|
315
|
+
|
|
316
|
+
if [ -d "$PLAN_DIR" ] && [ -n "$(ls -A "$PLAN_DIR" 2>/dev/null)" ]; then
|
|
317
|
+
echo " exists: true"
|
|
318
|
+
echo " files:"
|
|
319
|
+
for file in "$PLAN_DIR"/*.md; do
|
|
320
|
+
[ -f "$file" ] || continue
|
|
321
|
+
name=$(basename "$file" .md)
|
|
322
|
+
status=$(extract_field "$file" "status")
|
|
323
|
+
status=${status:-"unknown"}
|
|
324
|
+
format=$(extract_field "$file" "format")
|
|
325
|
+
format=${format:-"unknown"}
|
|
326
|
+
specification=$(extract_field "$file" "specification")
|
|
327
|
+
specification=${specification:-"${name}.md"}
|
|
328
|
+
|
|
329
|
+
echo " - name: \"$name\""
|
|
330
|
+
echo " status: \"$status\""
|
|
331
|
+
echo " format: \"$format\""
|
|
332
|
+
echo " specification: \"$specification\""
|
|
333
|
+
|
|
334
|
+
# External dependencies
|
|
335
|
+
deps_output=$(extract_external_deps "$file")
|
|
336
|
+
has_unresolved="false"
|
|
337
|
+
if [ -n "$deps_output" ]; then
|
|
338
|
+
echo " external_deps:"
|
|
339
|
+
while IFS='|' read -r dep_topic dep_state dep_task_id; do
|
|
340
|
+
[ -z "$dep_topic" ] && continue
|
|
341
|
+
echo " - topic: \"$dep_topic\""
|
|
342
|
+
echo " state: \"$dep_state\""
|
|
343
|
+
[ -n "$dep_task_id" ] && echo " task_id: \"$dep_task_id\""
|
|
344
|
+
[ "$dep_state" = "unresolved" ] && has_unresolved="true"
|
|
345
|
+
done <<< "$deps_output"
|
|
346
|
+
else
|
|
347
|
+
echo " external_deps: []"
|
|
348
|
+
fi
|
|
349
|
+
echo " has_unresolved_deps: $has_unresolved"
|
|
350
|
+
|
|
351
|
+
plan_count=$((plan_count + 1))
|
|
352
|
+
[ "$status" = "concluded" ] && plan_concluded=$((plan_concluded + 1))
|
|
353
|
+
{ [ "$status" = "planning" ] || [ "$status" = "in-progress" ]; } && plan_in_progress=$((plan_in_progress + 1))
|
|
354
|
+
done
|
|
355
|
+
echo " count: $plan_count"
|
|
356
|
+
echo " concluded: $plan_concluded"
|
|
357
|
+
echo " in_progress: $plan_in_progress"
|
|
358
|
+
else
|
|
359
|
+
echo " exists: false"
|
|
360
|
+
echo " files: []"
|
|
361
|
+
echo " count: 0"
|
|
362
|
+
echo " concluded: 0"
|
|
363
|
+
echo " in_progress: 0"
|
|
364
|
+
fi
|
|
365
|
+
|
|
366
|
+
echo ""
|
|
367
|
+
|
|
368
|
+
#
|
|
369
|
+
# IMPLEMENTATION
|
|
370
|
+
#
|
|
371
|
+
echo "implementation:"
|
|
372
|
+
|
|
373
|
+
impl_count=0
|
|
374
|
+
impl_completed=0
|
|
375
|
+
impl_in_progress=0
|
|
376
|
+
|
|
377
|
+
if [ -d "$IMPL_DIR" ] && [ -n "$(ls -A "$IMPL_DIR" 2>/dev/null)" ]; then
|
|
378
|
+
echo " exists: true"
|
|
379
|
+
echo " files:"
|
|
380
|
+
for file in "$IMPL_DIR"/*/tracking.md; do
|
|
381
|
+
[ -f "$file" ] || continue
|
|
382
|
+
topic=$(basename "$(dirname "$file")")
|
|
383
|
+
status=$(extract_field "$file" "status")
|
|
384
|
+
status=${status:-"unknown"}
|
|
385
|
+
current_phase=$(extract_field "$file" "current_phase")
|
|
386
|
+
|
|
387
|
+
completed_tasks=$(count_completed_tasks "$file")
|
|
388
|
+
completed_phases=$(count_completed_phases "$file")
|
|
389
|
+
|
|
390
|
+
# Count total tasks from plan directory (local-markdown format)
|
|
391
|
+
total_tasks=0
|
|
392
|
+
plan_file="$PLAN_DIR/${topic}.md"
|
|
393
|
+
if [ -f "$plan_file" ]; then
|
|
394
|
+
plan_format=$(extract_field "$plan_file" "format")
|
|
395
|
+
if [ "$plan_format" = "local-markdown" ] && [ -d "$PLAN_DIR/${topic}" ]; then
|
|
396
|
+
total_tasks=$(ls -1 "$PLAN_DIR/${topic}/"*.md 2>/dev/null | wc -l | tr -d ' ')
|
|
397
|
+
fi
|
|
398
|
+
fi
|
|
399
|
+
|
|
400
|
+
echo " - topic: \"$topic\""
|
|
401
|
+
echo " status: \"$status\""
|
|
402
|
+
[ -n "$current_phase" ] && [ "$current_phase" != "~" ] && echo " current_phase: $current_phase"
|
|
403
|
+
echo " completed_tasks: $completed_tasks"
|
|
404
|
+
echo " completed_phases: $completed_phases"
|
|
405
|
+
echo " total_tasks: $total_tasks"
|
|
406
|
+
|
|
407
|
+
impl_count=$((impl_count + 1))
|
|
408
|
+
[ "$status" = "completed" ] && impl_completed=$((impl_completed + 1))
|
|
409
|
+
[ "$status" = "in-progress" ] && impl_in_progress=$((impl_in_progress + 1))
|
|
410
|
+
done
|
|
411
|
+
echo " count: $impl_count"
|
|
412
|
+
echo " completed: $impl_completed"
|
|
413
|
+
echo " in_progress: $impl_in_progress"
|
|
414
|
+
else
|
|
415
|
+
echo " exists: false"
|
|
416
|
+
echo " files: []"
|
|
417
|
+
echo " count: 0"
|
|
418
|
+
echo " completed: 0"
|
|
419
|
+
echo " in_progress: 0"
|
|
420
|
+
fi
|