5-phase-workflow 2.0.2 → 2.0.4

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 CHANGED
@@ -93,6 +93,7 @@ Verification runs at the end of `/5:implement` and records concise results in `s
93
93
  | `/5:split` / `$5-split` | Split an existing plan into smaller linked plans for separate implementation |
94
94
  | `/5:implement` / `$5-implement` | Derive `state.json`, execute steps with agents, and verify inline |
95
95
  | `/5:review` / `$5-review` | Review code changes and save findings |
96
+ | `/5:commit` / `$5-commit` | Create a git commit using the configured commit message template |
96
97
  | `/5:address-review-findings` / `$5-address-review-findings` | Decide on review findings interactively, then apply approved fixes and PR comments |
97
98
  | `/5:reconfigure` / `$5-reconfigure` | Refresh docs, index, skills, and rules |
98
99
  | `/5:update` / `$5-update` | Upgrade installed workflow files |
package/bin/install.js CHANGED
@@ -882,11 +882,25 @@ function writeVersionJson(dataDir, isGlobal, version) {
882
882
  const runtimeVersions = Object.values(runtimes).map(r => r.packageVersion).filter(Boolean);
883
883
  const minVersion = runtimeVersions.reduce((min, v) => compareVersions(v, min) < 0 ? v : min, version);
884
884
 
885
+ // Backfill configuredAt from config.json mtime for projects that predate the field
886
+ let configuredAt = existing.configuredAt;
887
+ let configuredAtCommit = existing.configuredAtCommit;
888
+ if (!configuredAt) {
889
+ const configFile = path.join(dataDir, 'config.json');
890
+ if (fs.existsSync(configFile)) {
891
+ try {
892
+ configuredAt = fs.statSync(configFile).mtime.toISOString();
893
+ } catch (e) {}
894
+ }
895
+ }
896
+
885
897
  const versionData = {
886
898
  packageVersion: minVersion,
887
899
  installedAt: existing.installedAt || now,
888
900
  lastUpdated: now,
889
901
  installationType: existing.installationType || (isGlobal ? 'global' : 'local'),
902
+ ...(configuredAt && { configuredAt }),
903
+ ...(configuredAtCommit && { configuredAtCommit }),
890
904
  manifest: runtimes[activeRuntime].manifest,
891
905
  runtimes
892
906
  };
@@ -1012,6 +1026,7 @@ function showCommandsHelp(isGlobal) {
1012
1026
  log.info(' $5-split - Split plan into smaller plans');
1013
1027
  log.info(' $5-implement - Execute implementation + verification');
1014
1028
  log.info(' $5-review - Code review');
1029
+ log.info(' $5-commit - Create a templated git commit');
1015
1030
  log.info(' $5-address-review-findings - Decide review findings & PR comments');
1016
1031
  log.info(' $5-configure - Interactive project setup');
1017
1032
  log.info(' $5-reconfigure - Refresh docs/skills (no Q&A)');
@@ -1024,6 +1039,7 @@ function showCommandsHelp(isGlobal) {
1024
1039
  log.info(' /5:split - Split plan into smaller plans');
1025
1040
  log.info(' /5:implement - Execute implementation + verification');
1026
1041
  log.info(' /5:review - Code review');
1042
+ log.info(' /5:commit - Create a templated git commit');
1027
1043
  log.info(' /5:address-review-findings - Decide review findings & PR comments');
1028
1044
  log.info(' /5:configure - Interactive project setup');
1029
1045
  log.info(' /5:reconfigure - Refresh docs/skills (no Q&A)');
@@ -178,6 +178,7 @@ v2.0.0 removes old commands during upgrade:
178
178
  | `/5:discuss-feature` | Refine existing plan |
179
179
  | `/5:implement` | Implement and verify |
180
180
  | `/5:review` | Review changes |
181
+ | `/5:commit` | Create a templated git commit |
181
182
  | `/5:address-review-findings` | Apply approved findings |
182
183
  | `/5:configure` | Create project config and CONFIGURE plan |
183
184
  | `/5:reconfigure` | Refresh generated project context |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "5-phase-workflow",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "A dev-workflow for Claude Code and Codex",
5
5
  "bin": {
6
6
  "foifi": "bin/install.js"
@@ -45,7 +45,14 @@ This is the stable entrypoint after `/5:review`.
45
45
  - Ask the user for decisions on actionable/manual comments.
46
46
  - Invoke `/5:apply-review-findings {feature} --pr-approved` for approved PR fixes.
47
47
  - Invoke `/5:reply-pr-comments {feature}` to post PR replies.
48
- 4. Run configured build/test/lint skills if available, or the narrowest configured commands.
48
+ 4. Run post-fix verification. This is mandatory after any approved fix is applied.
49
+ - Read `.5/config.json`, project run skills, and common project manifests such as `package.json`, `Makefile`, `pyproject.toml`, `Cargo.toml`, and Gradle files only as needed to identify configured commands.
50
+ - Run every available configured command in these categories: `build`, `test`, `e2e`/`test:e2e`, and `lint`.
51
+ - Prefer generated run skills when present (`run-build`, `run-tests`, `run-lint`, and any e2e/test-e2e variant). Otherwise run the exact configured command from `.5/config.json` or the project manifest.
52
+ - Do not skip a category because another category passed. Skip only when no command exists or the command is explicitly configured as `none`; record the reason.
53
+ - If any command fails, continue running remaining independent categories so the user gets a complete verification picture.
54
+ - Do not claim the review findings are fully addressed unless every discovered post-fix verification command passes or is explicitly skipped because no command exists.
55
+ - Store compact results for each category in the summary: command, status (`passed`, `failed`, or `skipped`), and a one-line reason.
49
56
  5. Write `.5/features/{feature}/review-summary-{YYYYMMDD-HHmmss}.md` using `.claude/templates/workflow/REVIEW-SUMMARY.md`.
50
57
 
51
58
  Keep all intermediate summaries compact. Do not paste raw diffs, raw PR JSON, or command logs unless a failure needs exact evidence.
@@ -80,11 +87,14 @@ Allowed `decision` values are `fix`, `wont_fix`, and `wait`.
80
87
  Output:
81
88
 
82
89
  ```text
83
- Review findings addressed.
90
+ Review findings addressed: {yes/no}
84
91
 
85
92
  Local findings: {summary}
86
93
  PR comments: {summary}
94
+ Post-fix verification: {passed/failed}
87
95
  Build: {passed/failed/skipped}
88
96
  Tests: {passed/failed/skipped}
97
+ E2E: {passed/failed/skipped}
98
+ Lint: {passed/failed/skipped}
89
99
  Summary saved at .5/features/{feature}/review-summary-{timestamp}.md
90
100
  ```
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: 5:commit
3
+ description: Create a git commit using the configured commit message template from .5/config.json.
4
+ allowed-tools: Bash, Read, AskUserQuestion
5
+ user-invocable: true
6
+ model: haiku
7
+ argument-hint: [short-description]
8
+ ---
9
+
10
+ <role>
11
+ You are a Commit Assistant. You create exactly one git commit using the project's configured commit message template.
12
+ You do NOT modify files. You do NOT stage unrelated changes. After reporting the commit result, you are DONE.
13
+ </role>
14
+
15
+ # Commit
16
+
17
+ ## Inputs
18
+
19
+ - Optional short description from the command argument.
20
+ - Configuration from `.5/config.json`:
21
+ - `ticket.pattern`
22
+ - `ticket.extractFromBranch`
23
+ - `git.commitMessage.pattern` (default: `{ticket-id} {short-description}`)
24
+
25
+ Current branch: !`git branch --show-current 2>/dev/null || echo ""`
26
+
27
+ ## Step 1: Inspect Changes
28
+
29
+ Run:
30
+
31
+ ```bash
32
+ git status --short
33
+ ```
34
+
35
+ If there are no changed files, tell the user "No changes to commit." and stop.
36
+
37
+ If there are staged changes, ask whether to commit the currently staged changes or adjust the staged set.
38
+
39
+ If there are unstaged or untracked changes, show a concise file list and ask which files should be included. Stage only the selected files with explicit paths. Never use `git add .` or `git add -A`.
40
+
41
+ After staging, run:
42
+
43
+ ```bash
44
+ git diff --cached --stat
45
+ git diff --cached --name-only
46
+ ```
47
+
48
+ If nothing is staged, tell the user "No staged changes to commit." and stop.
49
+
50
+ ## Step 2: Load Commit Template
51
+
52
+ Read `.5/config.json` if it exists.
53
+
54
+ Determine:
55
+
56
+ 1. `pattern` = `git.commitMessage.pattern`, defaulting to `{ticket-id} {short-description}`.
57
+ 2. `ticketPattern` = `ticket.pattern`, defaulting to null.
58
+ 3. `extractFromBranch` = `ticket.extractFromBranch`, defaulting to true.
59
+
60
+ If `extractFromBranch` is true and `ticketPattern` is set, match `ticketPattern` against the current branch to get `{ticket-id}`. If no ticket is found, use an empty string.
61
+
62
+ ## Step 3: Get Short Description
63
+
64
+ If the user provided a command argument, use it as `{short-description}`.
65
+
66
+ Otherwise propose a short description from the staged file names and diff stat, then ask the user to confirm or replace it.
67
+
68
+ Keep `{short-description}`:
69
+
70
+ - Lowercase unless the project pattern clearly uses another style.
71
+ - Under 72 characters when possible.
72
+ - Written as an imperative or concise noun phrase, matching existing project commits if obvious.
73
+
74
+ ## Step 4: Build Commit Message
75
+
76
+ Apply the configured pattern:
77
+
78
+ - Replace `{ticket-id}` with the extracted ticket ID or an empty string.
79
+ - Replace `{short-description}` with the confirmed short description.
80
+ - Trim redundant whitespace.
81
+ - If `{ticket-id}` is empty, remove empty conventional wrappers such as `()` and tidy punctuation:
82
+ - `feat({ticket-id}): {short-description}` -> `feat: {short-description}`
83
+ - `{ticket-id}: {short-description}` -> `{short-description}`
84
+ - `{ticket-id} {short-description}` -> `{short-description}`
85
+
86
+ Build a commit body from the staged diff when useful:
87
+
88
+ - Include 1-5 bullet points summarizing meaningful changes.
89
+ - Skip the body for very small or self-explanatory commits.
90
+ - Do not include raw diff excerpts.
91
+
92
+ Show the final commit message and ask for confirmation before committing.
93
+
94
+ ## Step 5: Commit
95
+
96
+ Create the commit using the final subject and optional body.
97
+
98
+ Use a command form that preserves newlines, for example:
99
+
100
+ ```bash
101
+ git commit -m "{subject}" -m "{body}"
102
+ ```
103
+
104
+ If there is no body:
105
+
106
+ ```bash
107
+ git commit -m "{subject}"
108
+ ```
109
+
110
+ After committing, run:
111
+
112
+ ```bash
113
+ git rev-parse --short HEAD
114
+ ```
115
+
116
+ Report the commit SHA and subject.
@@ -403,7 +403,7 @@ Analyze the codebase and generate focused documentation capturing only non-deriv
403
403
  - Fill `{PROJECT_DOCUMENTATION_LINKS}` with whichever `.5/` documentation files were created
404
404
  - Fill `{CODEBASE_INDEX_LINKS}` with `.5/index/README.md`, generated index files, and `.5/index/rebuild-index.sh`
405
405
  - Fill `{CUSTOM_DOCUMENTATION}` with preserved user-authored sections under `## Custom Documentation`; remove the placeholder if there is no custom content
406
- - Preserve static template sections exactly as written, including skill usage, workflow rules, coding guidelines, simplicity, testing, surgical changes, goal-driven execution, and index freshness
406
+ - Preserve static template sections exactly as written, including skill usage, commit messages, workflow rules, coding guidelines, simplicity, testing, surgical changes, goal-driven execution, and index freshness
407
407
 
408
408
  **Create CLAUDE.md shim:**
409
409
  - Contains only `@AGENTS.md` (Claude Code include syntax)
@@ -38,11 +38,19 @@ function checkReconfigure(workspaceDir) {
38
38
  process.exit(0);
39
39
  }
40
40
 
41
- const { configuredAt, configuredAtCommit } = versionData;
41
+ let { configuredAt, configuredAtCommit } = versionData;
42
42
 
43
- // No configure data yet - skip (user hasn't run /5:configure)
43
+ // Fall back to config.json mtime when configuredAt was never recorded
44
44
  if (!configuredAt) {
45
- process.exit(0);
45
+ const configFile = path.join(workspaceDir, '.5', 'config.json');
46
+ if (!fs.existsSync(configFile)) {
47
+ process.exit(0);
48
+ }
49
+ try {
50
+ configuredAt = fs.statSync(configFile).mtime.toISOString();
51
+ } catch (e) {
52
+ process.exit(0);
53
+ }
46
54
  }
47
55
 
48
56
  // Calculate days elapsed
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // Claude Code Statusline
3
- // Shows: model | folder | branch | off-peak | 5hr-usage | cost | context | reset-time
3
+ // Shows: model | folder | branch | 5hr-usage | cost | context | reset-time
4
4
 
5
5
  const fs = require('fs');
6
6
  const path = require('path');
@@ -37,17 +37,6 @@ process.stdin.on('end', () => {
37
37
  parts.push(`\x1b[32m🌿 ${branch}\x1b[0m`);
38
38
  }
39
39
 
40
- // 🚀 Off-peak indicator (weekdays before 5 AM or after 11 AM PT; all weekends)
41
- // PT = UTC-8 (PST) or UTC-7 (PDT). Use UTC-7 as approximation (covers PDT/PST conservatively).
42
- const nowUtc = new Date();
43
- const ptHour = (nowUtc.getUTCHours() - 7 + 24) % 24; // approximate PT
44
- const ptDay = new Date(nowUtc.getTime() - 7 * 3600 * 1000).getUTCDay(); // 0=Sun,6=Sat
45
- const isWeekend = ptDay === 0 || ptDay === 6;
46
- const isPeak = !isWeekend && ptHour >= 5 && ptHour < 11;
47
- if (!isPeak) {
48
- parts.push('\x1b[32m🚀 off-peak\x1b[0m');
49
- }
50
-
51
40
  // ⚡ 5-hour session usage
52
41
  const fiveHrUsed = data.rate_limits?.five_hour?.used_percentage;
53
42
  if (fiveHrUsed != null) {
@@ -151,7 +151,7 @@ Placeholder mapping:
151
151
  - `{CODEBASE_INDEX_LINKS}` → links to `.5/index/README.md`, generated index files, and `.5/index/rebuild-index.sh`
152
152
  - `{CUSTOM_DOCUMENTATION}` → preserved user-authored sections under `## Custom Documentation`; remove the placeholder entirely if there is no custom content
153
153
 
154
- Preserve the static template sections exactly as written, including skill usage, workflow rules, coding guidelines, simplicity, testing, surgical changes, goal-driven execution, and index freshness.
154
+ Preserve the static template sections exactly as written, including skill usage, commit messages, workflow rules, coding guidelines, simplicity, testing, surgical changes, goal-driven execution, and index freshness.
155
155
 
156
156
  ### A5. Migrate and Preserve Existing Content
157
157
 
@@ -12,6 +12,10 @@ Before implementing changes, always check the available skills for relevant impl
12
12
 
13
13
  Use skills to understand project-specific workflows, commands, testing expectations, and implementation conventions before editing code.
14
14
 
15
+ ## Commit Messages
16
+
17
+ Use the `/5:commit` command or `$5-commit` skill when creating commits. It reads `.5/config.json` and applies the configured `git.commitMessage.pattern`, including ticket IDs from branch names when configured.
18
+
15
19
  ## Workflow Rules
16
20
 
17
21
  When running `/5:` workflow commands, follow the command instructions exactly as written.
@@ -37,4 +37,10 @@
37
37
  ## Files Modified
38
38
 
39
39
  - {file-path} ({N} fixes applied)
40
- - {file-path} ({N} fixes applied)
40
+
41
+ ## Post-Fix Verification
42
+
43
+ - **Build:** {passed/failed/skipped} - `{command-or-none}` - {one-line summary}
44
+ - **Tests:** {passed/failed/skipped} - `{command-or-none}` - {one-line summary}
45
+ - **E2E:** {passed/failed/skipped} - `{command-or-none}` - {one-line summary}
46
+ - **Lint:** {passed/failed/skipped} - `{command-or-none}` - {one-line summary}