5-phase-workflow 1.5.4 → 1.6.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.
- package/bin/install.js +2 -0
- package/package.json +1 -1
- package/src/commands/5/configure.md +31 -0
- package/src/commands/5/reconfigure.md +155 -0
- package/src/hooks/check-reconfig.js +88 -0
- package/src/hooks/statusline.js +12 -3
- package/src/settings.json +10 -0
- package/src/skills/configure-project/SKILL.md +23 -0
package/bin/install.js
CHANGED
|
@@ -273,6 +273,7 @@ function getWorkflowManagedFiles() {
|
|
|
273
273
|
hooks: [
|
|
274
274
|
'statusline.js',
|
|
275
275
|
'check-updates.js',
|
|
276
|
+
'check-reconfig.js',
|
|
276
277
|
'plan-guard.js',
|
|
277
278
|
'config-guard.js'
|
|
278
279
|
],
|
|
@@ -491,6 +492,7 @@ function showCommandsHelp(isGlobal) {
|
|
|
491
492
|
log.info(' /5:verify-implementation - Verify implementation (Phase 4)');
|
|
492
493
|
log.info(' /5:review-code - Code review (Phase 5)');
|
|
493
494
|
log.info(' /5:configure - Interactive project setup');
|
|
495
|
+
log.info(' /5:reconfigure - Refresh docs/skills (no Q&A)');
|
|
494
496
|
log.info(' /5:unlock - Remove planning guard lock');
|
|
495
497
|
log.info('');
|
|
496
498
|
log.info(`Config file: ${path.join(getDataPath(isGlobal), 'config.json')}`);
|
package/package.json
CHANGED
|
@@ -279,6 +279,12 @@ If no patterns/commands detected:
|
|
|
279
279
|
- Inform user: "No common patterns detected. Would you like to specify patterns manually?"
|
|
280
280
|
- Allow manual entry of pattern names/locations or command names
|
|
281
281
|
|
|
282
|
+
**2l. Git-ignore `.5/features/` folder:**
|
|
283
|
+
- "The `.5/features/` folder will contain feature specs, implementation plans, and state files. Would you like to add it to `.gitignore`?"
|
|
284
|
+
- Options:
|
|
285
|
+
1. "Yes, add to .gitignore (recommended)" — workflow artifacts stay local, not tracked in version control
|
|
286
|
+
2. "No, track in git" — useful if you want to share specs and plans with your team
|
|
287
|
+
|
|
282
288
|
### Step 2.5: Write config.json
|
|
283
289
|
|
|
284
290
|
Using the values gathered from Steps 1 and 2, write `.5/config.json` directly.
|
|
@@ -330,12 +336,37 @@ mkdir -p .5
|
|
|
330
336
|
"commitMessage": {
|
|
331
337
|
"pattern": "{ticket-id} {short-description}"
|
|
332
338
|
}
|
|
339
|
+
},
|
|
340
|
+
"dotFiveFolder": {
|
|
341
|
+
"gitignore": true
|
|
333
342
|
}
|
|
334
343
|
}
|
|
335
344
|
```
|
|
336
345
|
|
|
337
346
|
Fill all values from user responses. Write with pretty-printed JSON. Read back to verify correctness.
|
|
338
347
|
|
|
348
|
+
**Update `.5/version.json` with configure timestamp:**
|
|
349
|
+
|
|
350
|
+
After writing config.json, update `.5/version.json` so the reconfigure reminder can track staleness:
|
|
351
|
+
1. Read `.5/version.json` (if it exists)
|
|
352
|
+
2. Set `configuredAt` to the current ISO timestamp (`new Date().toISOString()`)
|
|
353
|
+
3. Set `configuredAtCommit` to the current short commit hash (run `git rev-parse --short HEAD`)
|
|
354
|
+
4. Write back `.5/version.json` preserving all other fields
|
|
355
|
+
|
|
356
|
+
**Apply `.gitignore` if selected:**
|
|
357
|
+
|
|
358
|
+
If the user chose to gitignore the `.5/features/` folder:
|
|
359
|
+
1. Check if `.gitignore` exists in the project root
|
|
360
|
+
2. If it exists, check if `.5/features/` is already listed — if not, append `.5/features/` on a new line
|
|
361
|
+
3. If `.gitignore` does not exist, create it with `.5/features/` as the first entry
|
|
362
|
+
4. Inform the user: "Added `.5/features/` to `.gitignore`"
|
|
363
|
+
|
|
364
|
+
**Always gitignore `.5/.reconfig-reminder`:**
|
|
365
|
+
|
|
366
|
+
Ensure `.5/.reconfig-reminder` is gitignored (it's a transient runtime flag that should never be committed):
|
|
367
|
+
1. Check if `.gitignore` exists in the project root — create it if not
|
|
368
|
+
2. Check if `.5/.reconfig-reminder` is already listed — if not, append `.5/.reconfig-reminder` on a new line
|
|
369
|
+
|
|
339
370
|
### Step 3: Create Feature Spec
|
|
340
371
|
|
|
341
372
|
Write `.5/features/CONFIGURE/feature.md` containing all gathered data:
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 5:reconfigure
|
|
3
|
+
description: Lightweight refresh of project documentation and skills without full Q&A. Re-detects codebase changes, regenerates .5/*.md docs, updates CLAUDE.md, and refreshes all skills.
|
|
4
|
+
allowed-tools: Read, Write, Bash, Glob, Grep, Task, AskUserQuestion
|
|
5
|
+
context: fork
|
|
6
|
+
user-invocable: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Reconfigure (Lightweight Refresh)
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
Single-command refresh that skips the full Q&A of `/5:configure`. Re-detects codebase state, regenerates documentation and skills based on existing `config.json` preferences.
|
|
14
|
+
|
|
15
|
+
**When to use which:**
|
|
16
|
+
|
|
17
|
+
| Scenario | Command |
|
|
18
|
+
|----------|---------|
|
|
19
|
+
| First-time setup | `/5:configure` |
|
|
20
|
+
| Change preferences (ticket pattern, review tool, etc.) | `/5:configure` |
|
|
21
|
+
| Codebase evolved, refresh docs/skills | **`/5:reconfigure`** |
|
|
22
|
+
| Add new skill patterns | `/5:configure` |
|
|
23
|
+
|
|
24
|
+
## ⚠️ CRITICAL SCOPE CONSTRAINT
|
|
25
|
+
|
|
26
|
+
**THIS COMMAND REGENERATES DOCS AND SKILLS. IT DOES NOT CHANGE USER PREFERENCES.**
|
|
27
|
+
|
|
28
|
+
Your job:
|
|
29
|
+
✅ Validate that config.json exists
|
|
30
|
+
✅ Re-detect codebase patterns and commands (same as configure Steps 1b-1h)
|
|
31
|
+
✅ Compare detected state with config.json skill selections
|
|
32
|
+
✅ Show summary and ask for confirmation
|
|
33
|
+
✅ Invoke configure-project skill in refresh mode
|
|
34
|
+
✅ Update version.json with artifacts and timestamps
|
|
35
|
+
✅ Clean up .reconfig-reminder flag
|
|
36
|
+
✅ Report what was updated
|
|
37
|
+
|
|
38
|
+
Your job is NOT:
|
|
39
|
+
❌ Ask preference questions (ticket pattern, branch convention, review tool, etc.)
|
|
40
|
+
❌ Modify config.json preferences (only the `skills` section may be updated if user confirms new patterns)
|
|
41
|
+
❌ Skip confirmation — always show what will be regenerated
|
|
42
|
+
|
|
43
|
+
## Process
|
|
44
|
+
|
|
45
|
+
### Step 1: Validate Config
|
|
46
|
+
|
|
47
|
+
Read `.5/config.json`. If it does not exist:
|
|
48
|
+
- Tell the user: "No configuration found. Please run `/5:configure` first to set up your project."
|
|
49
|
+
- **EXIT IMMEDIATELY**
|
|
50
|
+
|
|
51
|
+
Read `.5/version.json` for current state (configuredAt, configuredAtCommit).
|
|
52
|
+
|
|
53
|
+
### Step 2: Re-detect Codebase State
|
|
54
|
+
|
|
55
|
+
Perform the same detection as configure Steps 1b-1h:
|
|
56
|
+
|
|
57
|
+
**2a. Detect project type** — same table as configure Step 1b (package.json deps, build files, etc.)
|
|
58
|
+
|
|
59
|
+
**2b. Detect build/test commands** — same as configure Step 1c
|
|
60
|
+
|
|
61
|
+
**2c. Detect codebase patterns** — same as configure Step 1g:
|
|
62
|
+
- Scan for architectural patterns (Controllers, Services, Components, etc.)
|
|
63
|
+
- Use both suffix-based and directory-based globs
|
|
64
|
+
- For each pattern: count files, identify location, sample filename
|
|
65
|
+
|
|
66
|
+
**2d. Detect runnable commands** — same as configure Step 1h:
|
|
67
|
+
- Scan package.json scripts, Makefile targets, etc.
|
|
68
|
+
- Categorize: Build, Test, Lint, Format, Type Check, etc.
|
|
69
|
+
|
|
70
|
+
**2e. Scan existing skills** — list ALL skills in `.claude/skills/`:
|
|
71
|
+
- Read each skill's SKILL.md frontmatter
|
|
72
|
+
- Categorize as workflow-generated (create-*, run-*) or user-created
|
|
73
|
+
|
|
74
|
+
### Step 3: Compare and Prepare Summary
|
|
75
|
+
|
|
76
|
+
Use the existing skills in `.claude/skills/` (from Step 2e) as the source of truth — not config.json. Compare what's installed with what's detected in the codebase:
|
|
77
|
+
|
|
78
|
+
- **Existing `create-*` skills** — extract the pattern name from each (e.g., `create-controller` → `controller`)
|
|
79
|
+
- **Existing `run-*` skills** — extract the command name from each (e.g., `run-tests` → `tests`)
|
|
80
|
+
- **New patterns**: detected in codebase (Step 2c) but no matching `create-*` skill exists → offer to create
|
|
81
|
+
- **Stale patterns**: a `create-*` skill exists but the pattern is no longer detected in the codebase → offer to remove or keep
|
|
82
|
+
- **New commands**: detected (Step 2d) but no matching `run-*` skill exists → offer to create
|
|
83
|
+
- **Stale commands**: a `run-*` skill exists but the command is no longer detected → offer to remove or keep
|
|
84
|
+
- **User-created skills** (not matching `create-*` or `run-*` naming) → always refresh with current conventions, never remove
|
|
85
|
+
|
|
86
|
+
### Step 4: Confirm with User
|
|
87
|
+
|
|
88
|
+
Use `AskUserQuestion` to show a summary and get confirmation. Present:
|
|
89
|
+
|
|
90
|
+
1. **Documentation files that will be rewritten** — list all 7 `.5/*.md` files + CLAUDE.md
|
|
91
|
+
2. **Skills that will be refreshed** — list ALL skills found in `.claude/skills/` (both workflow-generated and user-created)
|
|
92
|
+
3. **New patterns detected** (if any) — "These patterns were found in your codebase but don't have skills yet: [list]. Create skills for them?"
|
|
93
|
+
4. **Stale patterns** (if any) — "These patterns are in your config but weren't found in the codebase: [list]. Remove them?"
|
|
94
|
+
|
|
95
|
+
Options:
|
|
96
|
+
- "Proceed with refresh" — regenerate everything as shown
|
|
97
|
+
- "Cancel" — exit without changes
|
|
98
|
+
|
|
99
|
+
If there are new or stale patterns, use additional `AskUserQuestion` calls with multiSelect to let the user pick which new patterns to add and which stale patterns to remove.
|
|
100
|
+
|
|
101
|
+
New skills will be created and stale skills removed based on the user's choices.
|
|
102
|
+
|
|
103
|
+
### Step 5: Regenerate
|
|
104
|
+
|
|
105
|
+
Invoke the `configure-project` skill in **refresh mode** via the Task tool:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
Task prompt: "Run configure-project skill in REFRESH MODE.
|
|
109
|
+
|
|
110
|
+
Refresh ALL existing skills in .claude/skills/:
|
|
111
|
+
- Existing create-* skills: [list from Step 2e]
|
|
112
|
+
- Existing run-* skills: [list from Step 2e]
|
|
113
|
+
- User-created skills: [list from Step 2e]
|
|
114
|
+
- New skills to create: [list from user confirmation, if any]
|
|
115
|
+
- Skills to remove: [list from user confirmation, if any]
|
|
116
|
+
|
|
117
|
+
Re-analyze the entire codebase (A1 analysis) and:
|
|
118
|
+
1. Rewrite all 7 .5/*.md documentation files
|
|
119
|
+
2. Update CLAUDE.md (preserve user-written sections)
|
|
120
|
+
3. Refresh ALL skills in .claude/skills/ — read current conventions from codebase and update each skill
|
|
121
|
+
4. Create new skills for newly-added patterns
|
|
122
|
+
5. Remove skills the user chose to drop"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Use `subagent_type: "general-purpose"` for the Task.
|
|
126
|
+
|
|
127
|
+
### Step 6: Track
|
|
128
|
+
|
|
129
|
+
After the skill completes, update `.5/version.json`:
|
|
130
|
+
|
|
131
|
+
1. Read current version.json
|
|
132
|
+
2. Set `configuredAt` to current ISO timestamp
|
|
133
|
+
3. Set `configuredAtCommit` to current short commit hash (`git rev-parse --short HEAD`)
|
|
134
|
+
4. Write back version.json preserving all other fields
|
|
135
|
+
|
|
136
|
+
### Step 7: Clean Up
|
|
137
|
+
|
|
138
|
+
Remove the `.5/.reconfig-reminder` flag file if it exists:
|
|
139
|
+
```bash
|
|
140
|
+
rm -f .5/.reconfig-reminder
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Step 8: Report
|
|
144
|
+
|
|
145
|
+
Show the user a summary:
|
|
146
|
+
- List of documentation files updated
|
|
147
|
+
- List of skills refreshed
|
|
148
|
+
- List of new skills created (if any)
|
|
149
|
+
- List of skills removed (if any)
|
|
150
|
+
- Timestamp of reconfiguration
|
|
151
|
+
- Suggest running `/clear` to reset context
|
|
152
|
+
|
|
153
|
+
## Related Documentation
|
|
154
|
+
- [configure command](./configure.md) — full Q&A configuration
|
|
155
|
+
- [configure-project skill](../../skills/configure-project/SKILL.md) — the skill that does the heavy lifting
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
// Read JSON from stdin
|
|
8
|
+
let input = '';
|
|
9
|
+
process.stdin.setEncoding('utf8');
|
|
10
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
11
|
+
process.stdin.on('end', () => {
|
|
12
|
+
try {
|
|
13
|
+
let workspaceDir = process.cwd();
|
|
14
|
+
if (input.trim()) {
|
|
15
|
+
const data = JSON.parse(input);
|
|
16
|
+
workspaceDir = data.cwd || data.workspace?.current_dir || workspaceDir;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
checkReconfigure(workspaceDir);
|
|
20
|
+
} catch (e) {
|
|
21
|
+
// Silent failure - don't block on errors
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
function checkReconfigure(workspaceDir) {
|
|
27
|
+
const versionFile = path.join(workspaceDir, '.5', 'version.json');
|
|
28
|
+
const flagFile = path.join(workspaceDir, '.5', '.reconfig-reminder');
|
|
29
|
+
|
|
30
|
+
if (!fs.existsSync(versionFile)) {
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let versionData;
|
|
35
|
+
try {
|
|
36
|
+
versionData = JSON.parse(fs.readFileSync(versionFile, 'utf8'));
|
|
37
|
+
} catch (e) {
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const { configuredAt, configuredAtCommit } = versionData;
|
|
42
|
+
|
|
43
|
+
// No configure data yet - skip (user hasn't run /5:configure)
|
|
44
|
+
if (!configuredAt) {
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Calculate days elapsed
|
|
49
|
+
let daysElapsed = 0;
|
|
50
|
+
try {
|
|
51
|
+
daysElapsed = Math.floor((Date.now() - new Date(configuredAt).getTime()) / (1000 * 60 * 60 * 24));
|
|
52
|
+
} catch (e) {
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Count commits since configured
|
|
57
|
+
let commitCount = 0;
|
|
58
|
+
if (configuredAtCommit) {
|
|
59
|
+
try {
|
|
60
|
+
const result = execSync(`git rev-list --count ${configuredAtCommit}..HEAD`, {
|
|
61
|
+
cwd: workspaceDir,
|
|
62
|
+
timeout: 3000,
|
|
63
|
+
encoding: 'utf8',
|
|
64
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
65
|
+
});
|
|
66
|
+
commitCount = parseInt(result.trim(), 10) || 0;
|
|
67
|
+
} catch (e) {
|
|
68
|
+
// Git command failed (commit not found, not a repo, etc.) - skip
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Write or remove temp flag file (never touches version.json)
|
|
73
|
+
const COMMIT_THRESHOLD = 50;
|
|
74
|
+
const DAYS_THRESHOLD = 30;
|
|
75
|
+
const shouldRemind = daysElapsed >= DAYS_THRESHOLD || commitCount >= COMMIT_THRESHOLD;
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
if (shouldRemind) {
|
|
79
|
+
fs.writeFileSync(flagFile, '1');
|
|
80
|
+
} else if (fs.existsSync(flagFile)) {
|
|
81
|
+
fs.unlinkSync(flagFile);
|
|
82
|
+
}
|
|
83
|
+
} catch (e) {
|
|
84
|
+
// Can't write/delete temp file - skip
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
package/src/hooks/statusline.js
CHANGED
|
@@ -43,22 +43,31 @@ process.stdin.on('end', () => {
|
|
|
43
43
|
// Shorten directory path for display
|
|
44
44
|
const shortDir = dir.replace(os.homedir(), '~');
|
|
45
45
|
|
|
46
|
-
// Check for available update
|
|
46
|
+
// Check for available update and reconfigure reminder
|
|
47
47
|
let updateIndicator = '';
|
|
48
|
+
let reconfigIndicator = '';
|
|
48
49
|
try {
|
|
49
50
|
const versionFile = path.join(dir, '.5', 'version.json');
|
|
50
51
|
const versionData = JSON.parse(fs.readFileSync(versionFile, 'utf8'));
|
|
52
|
+
|
|
53
|
+
// Update check
|
|
51
54
|
const latest = versionData.latestAvailableVersion;
|
|
52
55
|
const installed = versionData.installedVersion;
|
|
53
56
|
if (latest && installed && compareVersions(installed, latest) < 0) {
|
|
54
57
|
updateIndicator = ` | \x1b[33m↑${latest} → /5:update\x1b[0m`;
|
|
55
58
|
}
|
|
59
|
+
|
|
60
|
+
// Reconfigure check (reads flag file in .5/, gitignored)
|
|
61
|
+
const flagFile = path.join(dir, '.5', '.reconfig-reminder');
|
|
62
|
+
if (fs.existsSync(flagFile)) {
|
|
63
|
+
reconfigIndicator = ` | \x1b[35m↻ /5:reconfigure\x1b[0m`;
|
|
64
|
+
}
|
|
56
65
|
} catch (e) {
|
|
57
66
|
// No version file or parse error — no indicator
|
|
58
67
|
}
|
|
59
68
|
|
|
60
|
-
// Build and output statusline: model | directory | context | update
|
|
61
|
-
const statusline = `\x1b[36m${model}\x1b[0m | \x1b[90m${shortDir}\x1b[0m${ctx}${updateIndicator}`;
|
|
69
|
+
// Build and output statusline: model | directory | context | update | reconfig
|
|
70
|
+
const statusline = `\x1b[36m${model}\x1b[0m | \x1b[90m${shortDir}\x1b[0m${ctx}${updateIndicator}${reconfigIndicator}`;
|
|
62
71
|
process.stdout.write(statusline);
|
|
63
72
|
|
|
64
73
|
} catch (e) {
|
package/src/settings.json
CHANGED
|
@@ -22,6 +22,29 @@ Note: config.json is written directly by `/5:configure` during the Q&A phase.
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
## Modes
|
|
26
|
+
|
|
27
|
+
This skill supports two modes. The analysis (A1), template filling (A2-A3), CLAUDE.md update (A4-A5), and skill generation (B) logic is the same in both modes — only the **input source** changes.
|
|
28
|
+
|
|
29
|
+
### Full Mode (default)
|
|
30
|
+
|
|
31
|
+
Used by `/5:configure` → `/5:implement-feature CONFIGURE` flow.
|
|
32
|
+
|
|
33
|
+
- **Input:** Pattern/command selections from feature spec (`.5/features/CONFIGURE/feature.md`)
|
|
34
|
+
- **Behavior:** Creates everything from scratch based on feature spec requirements
|
|
35
|
+
|
|
36
|
+
### Refresh Mode
|
|
37
|
+
|
|
38
|
+
Used by `/5:reconfigure` for lightweight refresh.
|
|
39
|
+
|
|
40
|
+
- **Input:** The Task prompt lists which skills to refresh, create, and remove (determined by `/5:reconfigure` after scanning `.claude/skills/` and comparing with detected codebase patterns)
|
|
41
|
+
- **Behavior:** Re-analyzes codebase, overwrites docs and refreshes/creates/removes skills as specified
|
|
42
|
+
- **Trigger:** Task prompt includes "REFRESH MODE"
|
|
43
|
+
|
|
44
|
+
In both modes, the analysis and generation logic is identical — only where the skill list comes from differs.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
25
48
|
## A. Analyze Codebase and Create/Update CLAUDE.md
|
|
26
49
|
|
|
27
50
|
**Process:**
|