@leeovery/claude-technical-workflows 2.0.41 → 2.0.43
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/commands/workflow/start-discussion.md +162 -120
- package/commands/workflow/start-implementation.md +146 -66
- package/commands/workflow/start-planning.md +122 -43
- package/commands/workflow/start-research.md +90 -13
- package/commands/workflow/start-review.md +85 -41
- package/commands/workflow/start-specification.md +18 -11
- package/package.json +4 -2
- package/scripts/discovery-for-discussion.sh +198 -0
- package/scripts/discovery-for-implementation-and-review.sh +127 -0
- package/scripts/discovery-for-planning.sh +182 -0
- package/scripts/{specification-discovery.sh → discovery-for-specification.sh} +7 -2
- package/scripts/migrations/002-specification-frontmatter.sh +170 -0
- package/scripts/migrations/003-planning-frontmatter.sh +172 -0
- package/skills/technical-planning/references/output-local-markdown.md +17 -5
- package/skills/technical-research/SKILL.md +10 -1
- package/skills/technical-research/references/template.md +39 -0
- package/skills/technical-specification/references/specification-guide.md +20 -11
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Start a review session from an existing plan and implementation. Discovers available plans, validates implementation exists, and invokes the technical-review skill.
|
|
3
|
+
allowed-tools: Bash(.claude/scripts/discovery-for-implementation-and-review.sh)
|
|
3
4
|
---
|
|
4
5
|
|
|
5
6
|
Invoke the **technical-review** skill for this conversation.
|
|
@@ -15,7 +16,7 @@ This is **Phase 6** of the six-phase workflow:
|
|
|
15
16
|
| 3. Specification | REFINE - validate into standalone spec | |
|
|
16
17
|
| 4. Planning | HOW - phases, tasks, acceptance criteria | |
|
|
17
18
|
| 5. Implementation | DOING - tests first, then code | |
|
|
18
|
-
| **6. Review** | VALIDATING - check work against artifacts | HERE |
|
|
19
|
+
| **6. Review** | VALIDATING - check work against artifacts | ◀ HERE |
|
|
19
20
|
|
|
20
21
|
**Stay in your lane**: Verify that every plan task was implemented, tested adequately, and meets quality standards. Don't fix code - identify problems. You're reviewing, not building.
|
|
21
22
|
|
|
@@ -23,13 +24,17 @@ This is **Phase 6** of the six-phase workflow:
|
|
|
23
24
|
|
|
24
25
|
## Instructions
|
|
25
26
|
|
|
26
|
-
Follow these steps EXACTLY as written. Do not skip steps or combine them.
|
|
27
|
+
Follow these steps EXACTLY as written. Do not skip steps or combine them. Present output using the EXACT format shown in examples - do not simplify or alter the formatting.
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
**CRITICAL**: This guidance is mandatory.
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
- After each user interaction, STOP and wait for their response before proceeding
|
|
32
|
+
- Never assume or anticipate user choices
|
|
33
|
+
- Even if the user's initial prompt seems to answer a question, still confirm with them at the appropriate step
|
|
34
|
+
- Complete each step fully before moving to the next
|
|
35
|
+
- Do not act on gathered information until the skill is loaded - it contains the instructions for how to proceed
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
---
|
|
33
38
|
|
|
34
39
|
## Step 0: Run Migrations
|
|
35
40
|
|
|
@@ -39,22 +44,37 @@ Invoke the `/migrate` command and assess its output before proceeding to Step 1.
|
|
|
39
44
|
|
|
40
45
|
---
|
|
41
46
|
|
|
42
|
-
## Step 1:
|
|
47
|
+
## Step 1: Run Discovery Script
|
|
48
|
+
|
|
49
|
+
Run the discovery script to gather current state:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
.claude/scripts/discovery-for-implementation-and-review.sh
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This outputs structured YAML. Parse it to understand:
|
|
56
|
+
|
|
57
|
+
**From `plans` section:**
|
|
58
|
+
- `exists` - whether any plans exist
|
|
59
|
+
- `files` - list of plans with: name, topic, status, date, format, specification, specification_exists
|
|
60
|
+
- `count` - total number of plans
|
|
61
|
+
|
|
62
|
+
**From `state` section:**
|
|
63
|
+
- `scenario` - one of: `"no_plans"`, `"single_plan"`, `"multiple_plans"`
|
|
64
|
+
|
|
65
|
+
**IMPORTANT**: Use ONLY this script for discovery. Do NOT run additional bash commands (ls, head, cat, etc.) to gather state - the script provides everything needed.
|
|
43
66
|
|
|
44
|
-
|
|
67
|
+
→ Proceed to **Step 2**.
|
|
45
68
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Step 2: Route Based on Scenario
|
|
49
72
|
|
|
50
|
-
|
|
51
|
-
- Run `head -10 docs/workflow/planning/{topic}.md` to read the frontmatter
|
|
52
|
-
- Note the `format:` field
|
|
53
|
-
- Do NOT use bash loops - run separate `head` commands for each topic
|
|
73
|
+
Use `state.scenario` from the discovery output to determine the path:
|
|
54
74
|
|
|
55
|
-
|
|
75
|
+
#### If scenario is "no_plans"
|
|
56
76
|
|
|
57
|
-
|
|
77
|
+
No plans exist yet.
|
|
58
78
|
|
|
59
79
|
```
|
|
60
80
|
No plans found in docs/workflow/planning/
|
|
@@ -62,39 +82,68 @@ No plans found in docs/workflow/planning/
|
|
|
62
82
|
The review phase requires a completed implementation based on a plan. Please run /start-planning first to create a plan, then /start-implementation to build it.
|
|
63
83
|
```
|
|
64
84
|
|
|
65
|
-
|
|
85
|
+
**STOP.** Wait for user to acknowledge before ending.
|
|
86
|
+
|
|
87
|
+
#### If scenario is "single_plan" or "multiple_plans"
|
|
88
|
+
|
|
89
|
+
Plans exist.
|
|
90
|
+
|
|
91
|
+
→ Proceed to **Step 3** to present options.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Step 3: Present Plans and Select
|
|
66
96
|
|
|
67
|
-
|
|
97
|
+
Present all discovered plans to help the user make an informed choice.
|
|
68
98
|
|
|
69
|
-
|
|
99
|
+
**Present the full state:**
|
|
70
100
|
|
|
71
101
|
```
|
|
72
|
-
Plans
|
|
73
|
-
{topic-1} (format: {format})
|
|
74
|
-
{topic-2} (format: {format})
|
|
102
|
+
Available Plans:
|
|
75
103
|
|
|
76
|
-
|
|
104
|
+
1. {topic-1} ({status}) - format: {format}, spec: {exists|missing}
|
|
105
|
+
2. {topic-2} ({status}) - format: {format}, spec: {exists|missing}
|
|
106
|
+
|
|
107
|
+
Which plan would you like to review the implementation for? (Enter a number or name)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**If single plan exists (auto-select):**
|
|
111
|
+
```
|
|
112
|
+
Auto-selecting: {topic} (only available plan)
|
|
77
113
|
```
|
|
114
|
+
→ Proceed directly to **Step 4**.
|
|
78
115
|
|
|
79
|
-
**
|
|
116
|
+
**If multiple plans exist:**
|
|
117
|
+
|
|
118
|
+
**STOP.** Wait for user response.
|
|
119
|
+
|
|
120
|
+
→ Based on user choice, proceed to **Step 4**.
|
|
121
|
+
|
|
122
|
+
---
|
|
80
123
|
|
|
81
124
|
## Step 4: Identify Implementation Scope
|
|
82
125
|
|
|
83
|
-
|
|
126
|
+
Ask the user what code to review:
|
|
84
127
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
128
|
+
```
|
|
129
|
+
What code should I review?
|
|
130
|
+
|
|
131
|
+
1. All changes since the plan was created
|
|
132
|
+
2. Specific directories or files
|
|
133
|
+
3. Let me identify from git status
|
|
134
|
+
|
|
135
|
+
Which approach?
|
|
136
|
+
```
|
|
88
137
|
|
|
89
|
-
|
|
138
|
+
**STOP.** Wait for user response.
|
|
90
139
|
|
|
91
|
-
|
|
140
|
+
If they choose specific directories/files, ask them to specify.
|
|
92
141
|
|
|
93
|
-
|
|
94
|
-
2. **If exists**: Note the path for context
|
|
95
|
-
3. **If missing**: Proceed without - the plan is the primary review artifact
|
|
142
|
+
→ Proceed to **Step 5**.
|
|
96
143
|
|
|
97
|
-
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Step 5: Invoke the Skill
|
|
98
147
|
|
|
99
148
|
After completing the steps above, this command's purpose is fulfilled.
|
|
100
149
|
|
|
@@ -105,13 +154,8 @@ Invoke the [technical-review](../../skills/technical-review/SKILL.md) skill for
|
|
|
105
154
|
Review session for: {topic}
|
|
106
155
|
Plan: docs/workflow/planning/{topic}.md
|
|
107
156
|
Format: {format}
|
|
108
|
-
Specification:
|
|
109
|
-
Scope: {
|
|
157
|
+
Specification: {specification} (exists: {true|false})
|
|
158
|
+
Scope: {all changes | specific paths | from git status}
|
|
110
159
|
|
|
111
160
|
Invoke the technical-review skill.
|
|
112
161
|
```
|
|
113
|
-
|
|
114
|
-
## Notes
|
|
115
|
-
|
|
116
|
-
- Ask questions clearly and wait for responses before proceeding
|
|
117
|
-
- Review produces feedback (approve, request changes, or comments) - it does NOT fix code
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Start a specification session from existing discussions. Discovers available discussions, offers consolidation assessment for multiple discussions, and invokes the technical-specification skill.
|
|
3
|
-
allowed-tools: Bash(.claude/scripts/specification
|
|
3
|
+
allowed-tools: Bash(.claude/scripts/discovery-for-specification.sh), Bash(mkdir -p docs/workflow/.cache), Bash(rm docs/workflow/.cache/discussion-consolidation-analysis.md)
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Invoke the **technical-specification** skill for this conversation.
|
|
@@ -26,7 +26,13 @@ This is **Phase 3** of the six-phase workflow:
|
|
|
26
26
|
|
|
27
27
|
Follow these steps EXACTLY as written. Do not skip steps or combine them. Present output using the EXACT format shown in examples - do not simplify or alter the formatting.
|
|
28
28
|
|
|
29
|
-
**CRITICAL**:
|
|
29
|
+
**CRITICAL**: This guidance is mandatory.
|
|
30
|
+
|
|
31
|
+
- After each user interaction, STOP and wait for their response before proceeding
|
|
32
|
+
- Never assume or anticipate user choices
|
|
33
|
+
- Even if the user's initial prompt seems to answer a question, still confirm with them at the appropriate step
|
|
34
|
+
- Complete each step fully before moving to the next
|
|
35
|
+
- Do not act on gathered information until the skill is loaded - it contains the instructions for how to proceed
|
|
30
36
|
|
|
31
37
|
---
|
|
32
38
|
|
|
@@ -43,13 +49,14 @@ Invoke the `/migrate` command and assess its output before proceeding to Step 1.
|
|
|
43
49
|
Run the discovery script to gather current state:
|
|
44
50
|
|
|
45
51
|
```bash
|
|
46
|
-
.claude/scripts/specification
|
|
52
|
+
.claude/scripts/discovery-for-specification.sh
|
|
47
53
|
```
|
|
48
54
|
|
|
49
55
|
This outputs structured YAML. Parse it to understand:
|
|
50
56
|
|
|
51
57
|
**From `discussions` array:**
|
|
52
58
|
- Each discussion's name, status, and whether it has an individual specification
|
|
59
|
+
- If `has_individual_spec` is true, `spec_status` contains the spec's status (in-progress/concluded)
|
|
53
60
|
|
|
54
61
|
**From `specifications` array:**
|
|
55
62
|
- Each specification's name, status, sources, and superseded_by (if applicable)
|
|
@@ -114,7 +121,7 @@ Workflow Status: Specification Phase
|
|
|
114
121
|
Discussions:
|
|
115
122
|
✓ {topic-1} - concluded - ready
|
|
116
123
|
✓ {topic-2} - concluded - ready
|
|
117
|
-
○ {topic-3} - concluded -
|
|
124
|
+
○ {topic-3} - concluded - spec: {spec_status}
|
|
118
125
|
· {topic-4} - in-progress - not ready
|
|
119
126
|
|
|
120
127
|
Specifications:
|
|
@@ -126,7 +133,7 @@ Specifications:
|
|
|
126
133
|
|
|
127
134
|
**Legend:**
|
|
128
135
|
- `✓` = concluded, no spec yet (ready to specify)
|
|
129
|
-
- `○` = concluded, has individual spec (
|
|
136
|
+
- `○` = concluded, has individual spec (shows spec status: in-progress or concluded)
|
|
130
137
|
- `·` = in-progress (not ready)
|
|
131
138
|
|
|
132
139
|
#### Routing Based on State
|
|
@@ -137,7 +144,7 @@ This is the simple path - no choices needed.
|
|
|
137
144
|
|
|
138
145
|
```
|
|
139
146
|
Single concluded discussion found: {topic}
|
|
140
|
-
{If has spec: "An existing specification will be continued/refined."}
|
|
147
|
+
{If has spec: "An existing specification ({spec_status}) will be continued/refined."}
|
|
141
148
|
|
|
142
149
|
Proceeding with this discussion.
|
|
143
150
|
```
|
|
@@ -391,11 +398,11 @@ For each grouping, show:
|
|
|
391
398
|
|
|
392
399
|
Recommended Groupings:
|
|
393
400
|
|
|
394
|
-
### 1. {Grouping Name} {if spec exists: "(
|
|
401
|
+
### 1. {Grouping Name} {if spec exists: "(spec: {spec_status})"}
|
|
395
402
|
| Discussion | Status |
|
|
396
403
|
|------------|--------|
|
|
397
404
|
| {topic-a} | discussion only |
|
|
398
|
-
| {topic-b} |
|
|
405
|
+
| {topic-b} | spec: {spec_status} |
|
|
399
406
|
| {topic-c} | discussion only |
|
|
400
407
|
|
|
401
408
|
Coupling: {explanation}
|
|
@@ -439,7 +446,7 @@ Which would you like to start with?
|
|
|
439
446
|
|
|
440
447
|
Grouped:
|
|
441
448
|
1. {Grouping Name A} - {N} discussions
|
|
442
|
-
2. {Grouping Name B} - {N} discussions (
|
|
449
|
+
2. {Grouping Name B} - {N} discussions (spec: {spec_status})
|
|
443
450
|
3. {Grouping Name C} - {N} discussions
|
|
444
451
|
|
|
445
452
|
Independent:
|
|
@@ -523,7 +530,7 @@ Groupings confirmed. Cache updated.
|
|
|
523
530
|
|
|
524
531
|
Which grouping would you like to start with?
|
|
525
532
|
|
|
526
|
-
1. {Grouping A} - {N} discussions {if has spec: "(
|
|
533
|
+
1. {Grouping A} - {N} discussions {if has spec: "(spec: {spec_status})"}
|
|
527
534
|
2. {Grouping B} - {N} discussions
|
|
528
535
|
```
|
|
529
536
|
|
|
@@ -550,7 +557,7 @@ Proceed with unified specification? (y/n)
|
|
|
550
557
|
Which discussion would you like to specify?
|
|
551
558
|
|
|
552
559
|
1. {topic-1}
|
|
553
|
-
2. {topic-2} (
|
|
560
|
+
2. {topic-2} (spec: {spec_status})
|
|
554
561
|
3. {topic-3}
|
|
555
562
|
```
|
|
556
563
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leeovery/claude-technical-workflows",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.43",
|
|
4
4
|
"description": "Technical workflow skills & commands for Claude Code",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Lee Overy <me@leeovery.com>",
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
"type": "module",
|
|
12
12
|
"scripts": {
|
|
13
13
|
"postinstall": "claude-manager add",
|
|
14
|
-
"preuninstall": "npx --yes --package=@leeovery/claude-manager claude-manager remove"
|
|
14
|
+
"preuninstall": "npx --yes --package=@leeovery/claude-manager claude-manager remove",
|
|
15
|
+
"test:scripts:discovery": "bash tests/scripts/test-discovery-for-discussion.sh && bash tests/scripts/test-discovery-for-specification.sh && bash tests/scripts/test-discovery-for-planning.sh && bash tests/scripts/test-discovery-for-implementation-and-review.sh",
|
|
16
|
+
"test:scripts:migration": "bash tests/scripts/test-migration-001.sh && bash tests/scripts/test-migration-002.sh && bash tests/scripts/test-migration-003.sh"
|
|
15
17
|
},
|
|
16
18
|
"dependencies": {
|
|
17
19
|
"@leeovery/claude-manager": "^2.0.0"
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Discovers the current state of research, discussions, and cache
|
|
4
|
+
# for the /start-discussion 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
|
+
CACHE_FILE="docs/workflow/.cache/research-analysis.md"
|
|
14
|
+
|
|
15
|
+
# Helper: Extract a frontmatter field value from a file
|
|
16
|
+
# Usage: extract_field <file> <field_name>
|
|
17
|
+
extract_field() {
|
|
18
|
+
local file="$1"
|
|
19
|
+
local field="$2"
|
|
20
|
+
local value=""
|
|
21
|
+
|
|
22
|
+
# Extract from YAML frontmatter (file must start with ---)
|
|
23
|
+
if head -1 "$file" 2>/dev/null | grep -q "^---$"; then
|
|
24
|
+
value=$(sed -n '2,/^---$/p' "$file" 2>/dev/null | \
|
|
25
|
+
grep -i -m1 "^${field}:" | \
|
|
26
|
+
sed -E "s/^${field}:[[:space:]]*//i" || true)
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
echo "$value"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Start YAML output
|
|
33
|
+
echo "# Discussion Command State Discovery"
|
|
34
|
+
echo "# Generated: $(date -Iseconds)"
|
|
35
|
+
echo ""
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# RESEARCH FILES
|
|
39
|
+
#
|
|
40
|
+
echo "research:"
|
|
41
|
+
|
|
42
|
+
if [ -d "$RESEARCH_DIR" ] && [ -n "$(ls -A "$RESEARCH_DIR" 2>/dev/null)" ]; then
|
|
43
|
+
echo " exists: true"
|
|
44
|
+
echo " files:"
|
|
45
|
+
for file in "$RESEARCH_DIR"/*.md; do
|
|
46
|
+
[ -f "$file" ] || continue
|
|
47
|
+
|
|
48
|
+
name=$(basename "$file" .md)
|
|
49
|
+
topic=$(extract_field "$file" "topic")
|
|
50
|
+
topic=${topic:-"$name"}
|
|
51
|
+
|
|
52
|
+
echo " - name: \"$name\""
|
|
53
|
+
echo " topic: \"$topic\""
|
|
54
|
+
done
|
|
55
|
+
|
|
56
|
+
# Compute checksum of all research files (deterministic via sorted glob)
|
|
57
|
+
research_checksum=$(cat "$RESEARCH_DIR"/*.md 2>/dev/null | md5sum | cut -d' ' -f1)
|
|
58
|
+
echo " checksum: \"$research_checksum\""
|
|
59
|
+
else
|
|
60
|
+
echo " exists: false"
|
|
61
|
+
echo " files: []"
|
|
62
|
+
echo " checksum: null"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
echo ""
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# DISCUSSIONS
|
|
69
|
+
#
|
|
70
|
+
echo "discussions:"
|
|
71
|
+
|
|
72
|
+
if [ -d "$DISCUSSION_DIR" ] && [ -n "$(ls -A "$DISCUSSION_DIR" 2>/dev/null)" ]; then
|
|
73
|
+
echo " exists: true"
|
|
74
|
+
echo " files:"
|
|
75
|
+
|
|
76
|
+
in_progress_count=0
|
|
77
|
+
concluded_count=0
|
|
78
|
+
|
|
79
|
+
for file in "$DISCUSSION_DIR"/*.md; do
|
|
80
|
+
[ -f "$file" ] || continue
|
|
81
|
+
|
|
82
|
+
name=$(basename "$file" .md)
|
|
83
|
+
status=$(extract_field "$file" "status")
|
|
84
|
+
status=${status:-"unknown"}
|
|
85
|
+
date=$(extract_field "$file" "date")
|
|
86
|
+
|
|
87
|
+
echo " - name: \"$name\""
|
|
88
|
+
echo " status: \"$status\""
|
|
89
|
+
if [ -n "$date" ]; then
|
|
90
|
+
echo " date: \"$date\""
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
if [ "$status" = "in-progress" ]; then
|
|
94
|
+
in_progress_count=$((in_progress_count + 1))
|
|
95
|
+
elif [ "$status" = "concluded" ]; then
|
|
96
|
+
concluded_count=$((concluded_count + 1))
|
|
97
|
+
fi
|
|
98
|
+
done
|
|
99
|
+
|
|
100
|
+
echo " counts:"
|
|
101
|
+
echo " in_progress: $in_progress_count"
|
|
102
|
+
echo " concluded: $concluded_count"
|
|
103
|
+
else
|
|
104
|
+
echo " exists: false"
|
|
105
|
+
echo " files: []"
|
|
106
|
+
echo " counts:"
|
|
107
|
+
echo " in_progress: 0"
|
|
108
|
+
echo " concluded: 0"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
echo ""
|
|
112
|
+
|
|
113
|
+
#
|
|
114
|
+
# CACHE STATE
|
|
115
|
+
#
|
|
116
|
+
# status: "valid" | "stale" | "none"
|
|
117
|
+
# - valid: cache exists and checksums match
|
|
118
|
+
# - stale: cache exists but research has changed
|
|
119
|
+
# - none: no cache file exists
|
|
120
|
+
#
|
|
121
|
+
echo "cache:"
|
|
122
|
+
|
|
123
|
+
if [ -f "$CACHE_FILE" ]; then
|
|
124
|
+
cached_checksum=$(extract_field "$CACHE_FILE" "checksum")
|
|
125
|
+
cached_date=$(extract_field "$CACHE_FILE" "generated")
|
|
126
|
+
|
|
127
|
+
# Determine status based on checksum comparison
|
|
128
|
+
if [ -d "$RESEARCH_DIR" ] && [ -n "$(ls -A "$RESEARCH_DIR" 2>/dev/null)" ]; then
|
|
129
|
+
current_checksum=$(cat "$RESEARCH_DIR"/*.md 2>/dev/null | md5sum | cut -d' ' -f1)
|
|
130
|
+
|
|
131
|
+
if [ "$cached_checksum" = "$current_checksum" ]; then
|
|
132
|
+
echo " status: \"valid\""
|
|
133
|
+
echo " reason: \"checksums match\""
|
|
134
|
+
else
|
|
135
|
+
echo " status: \"stale\""
|
|
136
|
+
echo " reason: \"research has changed since cache was generated\""
|
|
137
|
+
fi
|
|
138
|
+
else
|
|
139
|
+
echo " status: \"stale\""
|
|
140
|
+
echo " reason: \"no research files to compare\""
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
echo " checksum: \"${cached_checksum:-unknown}\""
|
|
144
|
+
echo " generated: \"${cached_date:-unknown}\""
|
|
145
|
+
|
|
146
|
+
# Extract cached research files list
|
|
147
|
+
echo " research_files:"
|
|
148
|
+
files_found=false
|
|
149
|
+
while IFS= read -r file; do
|
|
150
|
+
file=$(echo "$file" | sed 's/^[[:space:]]*-[[:space:]]*//' | tr -d ' ')
|
|
151
|
+
if [ -n "$file" ]; then
|
|
152
|
+
echo " - \"$file\""
|
|
153
|
+
files_found=true
|
|
154
|
+
fi
|
|
155
|
+
done < <(sed -n '/^research_files:/,/^---$/p' "$CACHE_FILE" 2>/dev/null | grep "^[[:space:]]*-" || true)
|
|
156
|
+
|
|
157
|
+
if [ "$files_found" = false ]; then
|
|
158
|
+
echo " [] # No research files in cache"
|
|
159
|
+
fi
|
|
160
|
+
else
|
|
161
|
+
echo " status: \"none\""
|
|
162
|
+
echo " reason: \"no cache exists\""
|
|
163
|
+
echo " checksum: null"
|
|
164
|
+
echo " generated: null"
|
|
165
|
+
echo " research_files: []"
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
echo ""
|
|
169
|
+
|
|
170
|
+
#
|
|
171
|
+
# WORKFLOW STATE SUMMARY
|
|
172
|
+
#
|
|
173
|
+
echo "state:"
|
|
174
|
+
|
|
175
|
+
research_exists="false"
|
|
176
|
+
discussions_exist="false"
|
|
177
|
+
|
|
178
|
+
if [ -d "$RESEARCH_DIR" ] && [ -n "$(ls -A "$RESEARCH_DIR" 2>/dev/null)" ]; then
|
|
179
|
+
research_exists="true"
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
if [ -d "$DISCUSSION_DIR" ] && [ -n "$(ls -A "$DISCUSSION_DIR" 2>/dev/null)" ]; then
|
|
183
|
+
discussions_exist="true"
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
echo " has_research: $research_exists"
|
|
187
|
+
echo " has_discussions: $discussions_exist"
|
|
188
|
+
|
|
189
|
+
# Determine workflow state for routing
|
|
190
|
+
if [ "$research_exists" = "false" ] && [ "$discussions_exist" = "false" ]; then
|
|
191
|
+
echo " scenario: \"fresh\""
|
|
192
|
+
elif [ "$research_exists" = "true" ] && [ "$discussions_exist" = "false" ]; then
|
|
193
|
+
echo " scenario: \"research_only\""
|
|
194
|
+
elif [ "$research_exists" = "false" ] && [ "$discussions_exist" = "true" ]; then
|
|
195
|
+
echo " scenario: \"discussions_only\""
|
|
196
|
+
else
|
|
197
|
+
echo " scenario: \"research_and_discussions\""
|
|
198
|
+
fi
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Discovers the current state of plans for /start-implementation and /start-review commands.
|
|
4
|
+
#
|
|
5
|
+
# Outputs structured YAML that the commands can consume directly.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
set -eo pipefail
|
|
9
|
+
|
|
10
|
+
PLAN_DIR="docs/workflow/planning"
|
|
11
|
+
SPEC_DIR="docs/workflow/specification"
|
|
12
|
+
ENVIRONMENT_FILE="docs/workflow/environment-setup.md"
|
|
13
|
+
|
|
14
|
+
# Helper: Extract a frontmatter field value from a file
|
|
15
|
+
# Usage: extract_field <file> <field_name>
|
|
16
|
+
extract_field() {
|
|
17
|
+
local file="$1"
|
|
18
|
+
local field="$2"
|
|
19
|
+
local value=""
|
|
20
|
+
|
|
21
|
+
# Extract from YAML frontmatter (file must start with ---)
|
|
22
|
+
if head -1 "$file" 2>/dev/null | grep -q "^---$"; then
|
|
23
|
+
value=$(sed -n '2,/^---$/p' "$file" 2>/dev/null | \
|
|
24
|
+
grep -i -m1 "^${field}:" | \
|
|
25
|
+
sed -E "s/^${field}:[[:space:]]*//i" || true)
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
echo "$value"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# Start YAML output
|
|
32
|
+
echo "# Implementation Command State Discovery"
|
|
33
|
+
echo "# Generated: $(date -Iseconds)"
|
|
34
|
+
echo ""
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# PLANS
|
|
38
|
+
#
|
|
39
|
+
echo "plans:"
|
|
40
|
+
|
|
41
|
+
plan_count=0
|
|
42
|
+
|
|
43
|
+
if [ -d "$PLAN_DIR" ] && [ -n "$(ls -A "$PLAN_DIR" 2>/dev/null)" ]; then
|
|
44
|
+
echo " exists: true"
|
|
45
|
+
echo " files:"
|
|
46
|
+
|
|
47
|
+
for file in "$PLAN_DIR"/*.md; do
|
|
48
|
+
[ -f "$file" ] || continue
|
|
49
|
+
|
|
50
|
+
name=$(basename "$file" .md)
|
|
51
|
+
topic=$(extract_field "$file" "topic")
|
|
52
|
+
topic=${topic:-"$name"}
|
|
53
|
+
status=$(extract_field "$file" "status")
|
|
54
|
+
status=${status:-"unknown"}
|
|
55
|
+
date=$(extract_field "$file" "date")
|
|
56
|
+
date=${date:-"unknown"}
|
|
57
|
+
format=$(extract_field "$file" "format")
|
|
58
|
+
format=${format:-"local-markdown"}
|
|
59
|
+
specification=$(extract_field "$file" "specification")
|
|
60
|
+
specification=${specification:-"${name}.md"}
|
|
61
|
+
|
|
62
|
+
# Check if linked specification exists
|
|
63
|
+
spec_exists="false"
|
|
64
|
+
spec_file="$SPEC_DIR/$specification"
|
|
65
|
+
if [ -f "$spec_file" ]; then
|
|
66
|
+
spec_exists="true"
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
echo " - name: \"$name\""
|
|
70
|
+
echo " topic: \"$topic\""
|
|
71
|
+
echo " status: \"$status\""
|
|
72
|
+
echo " date: \"$date\""
|
|
73
|
+
echo " format: \"$format\""
|
|
74
|
+
echo " specification: \"$specification\""
|
|
75
|
+
echo " specification_exists: $spec_exists"
|
|
76
|
+
|
|
77
|
+
plan_count=$((plan_count + 1))
|
|
78
|
+
done
|
|
79
|
+
|
|
80
|
+
echo " count: $plan_count"
|
|
81
|
+
else
|
|
82
|
+
echo " exists: false"
|
|
83
|
+
echo " files: []"
|
|
84
|
+
echo " count: 0"
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
echo ""
|
|
88
|
+
|
|
89
|
+
#
|
|
90
|
+
# ENVIRONMENT
|
|
91
|
+
#
|
|
92
|
+
echo "environment:"
|
|
93
|
+
|
|
94
|
+
if [ -f "$ENVIRONMENT_FILE" ]; then
|
|
95
|
+
echo " setup_file_exists: true"
|
|
96
|
+
echo " setup_file: \"$ENVIRONMENT_FILE\""
|
|
97
|
+
|
|
98
|
+
# Check if it says "no special setup required" (case insensitive)
|
|
99
|
+
if grep -qi "no special setup required" "$ENVIRONMENT_FILE" 2>/dev/null; then
|
|
100
|
+
echo " requires_setup: false"
|
|
101
|
+
else
|
|
102
|
+
echo " requires_setup: true"
|
|
103
|
+
fi
|
|
104
|
+
else
|
|
105
|
+
echo " setup_file_exists: false"
|
|
106
|
+
echo " setup_file: \"$ENVIRONMENT_FILE\""
|
|
107
|
+
echo " requires_setup: unknown"
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
echo ""
|
|
111
|
+
|
|
112
|
+
#
|
|
113
|
+
# WORKFLOW STATE SUMMARY
|
|
114
|
+
#
|
|
115
|
+
echo "state:"
|
|
116
|
+
|
|
117
|
+
echo " has_plans: $([ "$plan_count" -gt 0 ] && echo "true" || echo "false")"
|
|
118
|
+
echo " plan_count: $plan_count"
|
|
119
|
+
|
|
120
|
+
# Determine workflow state for routing
|
|
121
|
+
if [ "$plan_count" -eq 0 ]; then
|
|
122
|
+
echo " scenario: \"no_plans\""
|
|
123
|
+
elif [ "$plan_count" -eq 1 ]; then
|
|
124
|
+
echo " scenario: \"single_plan\""
|
|
125
|
+
else
|
|
126
|
+
echo " scenario: \"multiple_plans\""
|
|
127
|
+
fi
|