forge-workflow 0.0.4 → 0.0.6

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.
Files changed (248) hide show
  1. package/.claude/commands/dev.md +345 -340
  2. package/.claude/commands/plan.md +566 -521
  3. package/.claude/commands/premerge.md +186 -176
  4. package/.claude/commands/research.md +42 -42
  5. package/.claude/commands/review.md +448 -442
  6. package/.claude/commands/rollback.md +721 -721
  7. package/.claude/commands/ship.md +212 -164
  8. package/.claude/commands/sonarcloud.md +152 -152
  9. package/.claude/commands/status.md +90 -48
  10. package/.claude/commands/validate.md +288 -282
  11. package/.claude/commands/verify.md +269 -221
  12. package/.claude/rules/greptile-review-process.md +285 -285
  13. package/.claude/rules/workflow.md +121 -105
  14. package/.claude/scripts/greptile-resolve.sh +558 -526
  15. package/.claude/scripts/load-env.sh +32 -32
  16. package/.cline/workflows/dev.md +342 -337
  17. package/.cline/workflows/plan.md +563 -518
  18. package/.cline/workflows/premerge.md +183 -173
  19. package/.cline/workflows/research.md +39 -39
  20. package/.cline/workflows/review.md +445 -439
  21. package/.cline/workflows/rollback.md +718 -718
  22. package/.cline/workflows/ship.md +209 -161
  23. package/.cline/workflows/sonarcloud.md +146 -146
  24. package/.cline/workflows/status.md +87 -45
  25. package/.cline/workflows/validate.md +285 -279
  26. package/.cline/workflows/verify.md +266 -218
  27. package/.codex/config.toml +11 -11
  28. package/.codex/skills/dev/SKILL.md +345 -340
  29. package/.codex/skills/plan/SKILL.md +566 -521
  30. package/.codex/skills/premerge/SKILL.md +186 -176
  31. package/.codex/skills/research/SKILL.md +42 -42
  32. package/.codex/skills/review/SKILL.md +448 -442
  33. package/.codex/skills/rollback/SKILL.md +721 -721
  34. package/.codex/skills/ship/SKILL.md +212 -164
  35. package/.codex/skills/sonarcloud/SKILL.md +149 -149
  36. package/.codex/skills/status/SKILL.md +90 -48
  37. package/.codex/skills/validate/SKILL.md +288 -282
  38. package/.codex/skills/verify/SKILL.md +269 -221
  39. package/.cursor/commands/dev.md +342 -337
  40. package/.cursor/commands/plan.md +563 -518
  41. package/.cursor/commands/premerge.md +183 -173
  42. package/.cursor/commands/research.md +39 -39
  43. package/.cursor/commands/review.md +445 -439
  44. package/.cursor/commands/rollback.md +718 -718
  45. package/.cursor/commands/ship.md +209 -161
  46. package/.cursor/commands/sonarcloud.md +146 -146
  47. package/.cursor/commands/status.md +87 -45
  48. package/.cursor/commands/validate.md +285 -279
  49. package/.cursor/commands/verify.md +266 -218
  50. package/.cursor/rules/permissions-guidance.mdc +37 -37
  51. package/.forge/hooks/check-tdd.js +240 -240
  52. package/.github/PLUGIN_TEMPLATE.json +32 -32
  53. package/.github/prompts/dev.prompt.md +347 -342
  54. package/.github/prompts/plan.prompt.md +568 -523
  55. package/.github/prompts/premerge.prompt.md +188 -178
  56. package/.github/prompts/research.prompt.md +44 -44
  57. package/.github/prompts/review.prompt.md +450 -444
  58. package/.github/prompts/rollback.prompt.md +723 -723
  59. package/.github/prompts/ship.prompt.md +214 -166
  60. package/.github/prompts/sonarcloud.prompt.md +151 -151
  61. package/.github/prompts/status.prompt.md +92 -50
  62. package/.github/prompts/validate.prompt.md +290 -284
  63. package/.github/prompts/verify.prompt.md +271 -223
  64. package/.github/workflows/beads-to-github.yml +56 -0
  65. package/.github/workflows/github-to-beads.yml +97 -0
  66. package/.kilocode/workflows/dev.md +346 -341
  67. package/.kilocode/workflows/plan.md +567 -522
  68. package/.kilocode/workflows/premerge.md +187 -177
  69. package/.kilocode/workflows/research.md +43 -43
  70. package/.kilocode/workflows/review.md +449 -443
  71. package/.kilocode/workflows/rollback.md +722 -722
  72. package/.kilocode/workflows/ship.md +213 -165
  73. package/.kilocode/workflows/sonarcloud.md +150 -150
  74. package/.kilocode/workflows/status.md +91 -49
  75. package/.kilocode/workflows/validate.md +289 -283
  76. package/.kilocode/workflows/verify.md +270 -222
  77. package/.mcp.json.example +12 -12
  78. package/.opencode/commands/dev.md +345 -340
  79. package/.opencode/commands/plan.md +566 -521
  80. package/.opencode/commands/premerge.md +186 -176
  81. package/.opencode/commands/research.md +42 -42
  82. package/.opencode/commands/review.md +448 -442
  83. package/.opencode/commands/rollback.md +721 -721
  84. package/.opencode/commands/ship.md +212 -164
  85. package/.opencode/commands/sonarcloud.md +149 -149
  86. package/.opencode/commands/status.md +90 -48
  87. package/.opencode/commands/validate.md +288 -282
  88. package/.opencode/commands/verify.md +269 -221
  89. package/.roo/commands/dev.md +346 -341
  90. package/.roo/commands/plan.md +567 -522
  91. package/.roo/commands/premerge.md +187 -177
  92. package/.roo/commands/research.md +43 -43
  93. package/.roo/commands/review.md +449 -443
  94. package/.roo/commands/rollback.md +722 -722
  95. package/.roo/commands/ship.md +213 -165
  96. package/.roo/commands/sonarcloud.md +150 -150
  97. package/.roo/commands/status.md +91 -49
  98. package/.roo/commands/validate.md +289 -283
  99. package/.roo/commands/verify.md +270 -222
  100. package/AGENTS.md +272 -175
  101. package/CLAUDE.md +110 -100
  102. package/README.md +429 -416
  103. package/bin/forge-cmd.js +317 -313
  104. package/bin/forge-preflight.js +322 -309
  105. package/bin/forge.js +4765 -4303
  106. package/docs/AGENT_INSTALL_PROMPT.md +342 -342
  107. package/docs/BEADS_GITHUB_SYNC.md +251 -251
  108. package/docs/ENHANCED_ONBOARDING.md +612 -602
  109. package/docs/EXAMPLES.md +482 -482
  110. package/docs/GREPTILE_SETUP.md +400 -400
  111. package/docs/MANUAL_REVIEW_GUIDE.md +106 -106
  112. package/docs/ROADMAP.md +359 -359
  113. package/docs/SETUP.md +663 -631
  114. package/docs/TOOLCHAIN.md +653 -630
  115. package/docs/VALIDATION.md +363 -363
  116. package/install.sh +40 -1056
  117. package/lefthook.yml +50 -39
  118. package/lib/agents/README.md +198 -198
  119. package/lib/agents/claude.plugin.json +28 -28
  120. package/lib/agents/cline.plugin.json +22 -22
  121. package/lib/agents/codex.plugin.json +19 -19
  122. package/lib/agents/copilot.plugin.json +24 -24
  123. package/lib/agents/cursor.plugin.json +25 -25
  124. package/lib/agents/kilocode.plugin.json +22 -22
  125. package/lib/agents/opencode.plugin.json +20 -20
  126. package/lib/agents/roo.plugin.json +23 -23
  127. package/lib/agents-config.js +2112 -2112
  128. package/lib/beads-health-check.js +143 -0
  129. package/lib/beads-setup.js +341 -0
  130. package/lib/beads-sync-scaffold.js +260 -0
  131. package/lib/commands/_registry.js +134 -0
  132. package/lib/commands/clean.js +181 -0
  133. package/lib/commands/dev.js +571 -513
  134. package/lib/commands/plan.js +692 -692
  135. package/lib/commands/push.js +196 -0
  136. package/lib/commands/recommend.js +119 -119
  137. package/lib/commands/ship.js +377 -377
  138. package/lib/commands/status.js +378 -378
  139. package/lib/commands/sync.js +55 -0
  140. package/lib/commands/team.js +37 -0
  141. package/lib/commands/test.js +207 -0
  142. package/lib/commands/validate.js +602 -602
  143. package/lib/commands/worktree.js +310 -0
  144. package/lib/context-merge.js +359 -359
  145. package/lib/dep-guard/analyzer.js +294 -294
  146. package/lib/dep-guard/behavior-detector.js +98 -98
  147. package/lib/dep-guard/contract-detector.js +162 -162
  148. package/lib/dep-guard/import-detector.js +498 -498
  149. package/lib/dep-guard/path-utils.js +13 -13
  150. package/lib/dep-guard/rubric.js +120 -120
  151. package/lib/dep-guard/task-parser.js +318 -318
  152. package/lib/detect-agent.js +191 -191
  153. package/lib/detect-worktree.js +47 -47
  154. package/lib/docs-command.js +51 -0
  155. package/lib/docs-copy.js +50 -0
  156. package/lib/file-hash.js +26 -26
  157. package/lib/freshness-token.js +148 -0
  158. package/lib/greptile-match.js +80 -0
  159. package/lib/husky-migration.js +450 -0
  160. package/lib/lefthook-check.js +65 -0
  161. package/lib/pat-setup.js +207 -0
  162. package/lib/plugin-catalog.js +350 -350
  163. package/lib/plugin-manager.js +166 -166
  164. package/lib/plugin-recommender.js +141 -141
  165. package/lib/project-discovery.js +491 -491
  166. package/lib/reset.js +309 -0
  167. package/lib/setup-action-log.js +139 -139
  168. package/lib/setup-summary-renderer.js +106 -106
  169. package/lib/setup-utils.js +96 -0
  170. package/lib/setup.js +192 -192
  171. package/lib/smart-merge.js +64 -0
  172. package/lib/symlink-utils.js +81 -0
  173. package/lib/task-ownership.js +117 -0
  174. package/lib/workflow-profiles.js +197 -197
  175. package/package.json +131 -128
  176. package/scripts/beads-context.sh +426 -0
  177. package/scripts/beads-context.test.js +567 -0
  178. package/scripts/behavioral-judge.sh +378 -0
  179. package/scripts/benchmark.js +85 -0
  180. package/scripts/branch-protection.js +183 -0
  181. package/scripts/check-agents.js +172 -0
  182. package/scripts/check-forge-token.js +98 -0
  183. package/scripts/commitlint.js +42 -0
  184. package/scripts/conflict-detect.sh +323 -0
  185. package/scripts/dep-guard-analyze.js +71 -0
  186. package/scripts/dep-guard.sh +789 -0
  187. package/scripts/eval_win.py +249 -0
  188. package/scripts/file-index.sh +493 -0
  189. package/scripts/forge-team/index.sh +86 -0
  190. package/scripts/forge-team/lib/agent-prompt.sh +52 -0
  191. package/scripts/forge-team/lib/claim.sh +256 -0
  192. package/scripts/forge-team/lib/dashboard.sh +341 -0
  193. package/scripts/forge-team/lib/epic.sh +332 -0
  194. package/scripts/forge-team/lib/hooks.sh +253 -0
  195. package/scripts/forge-team/lib/identity.sh +235 -0
  196. package/scripts/forge-team/lib/sync-github.sh +317 -0
  197. package/scripts/forge-team/lib/verify.sh +284 -0
  198. package/scripts/forge-team/lib/workload.sh +296 -0
  199. package/scripts/forge-team/tests/agent-prompt.test.sh +72 -0
  200. package/scripts/forge-team/tests/claim.test.sh +179 -0
  201. package/scripts/forge-team/tests/dashboard.test.sh +170 -0
  202. package/scripts/forge-team/tests/dispatcher.test.sh +79 -0
  203. package/scripts/forge-team/tests/epic.test.sh +176 -0
  204. package/scripts/forge-team/tests/hooks.test.sh +239 -0
  205. package/scripts/forge-team/tests/identity.test.sh +176 -0
  206. package/scripts/forge-team/tests/integration.test.sh +371 -0
  207. package/scripts/forge-team/tests/sync-github.test.sh +209 -0
  208. package/scripts/forge-team/tests/verify.test.sh +314 -0
  209. package/scripts/forge-team/tests/workflow-integration.test.sh +43 -0
  210. package/scripts/forge-team/tests/workload.test.sh +209 -0
  211. package/scripts/github-beads-sync/comment.mjs +64 -0
  212. package/scripts/github-beads-sync/config.mjs +148 -0
  213. package/scripts/github-beads-sync/github-api.mjs +131 -0
  214. package/scripts/github-beads-sync/index.mjs +332 -0
  215. package/scripts/github-beads-sync/label-mapper.mjs +54 -0
  216. package/scripts/github-beads-sync/mapping.mjs +78 -0
  217. package/scripts/github-beads-sync/reverse-sync-cli.mjs +31 -0
  218. package/scripts/github-beads-sync/reverse-sync.mjs +138 -0
  219. package/scripts/github-beads-sync/run-bd.mjs +159 -0
  220. package/scripts/github-beads-sync/sanitize.mjs +121 -0
  221. package/scripts/github-beads-sync.config.json +26 -0
  222. package/scripts/improve-command.js +375 -0
  223. package/scripts/lib/eval-runner.js +268 -0
  224. package/scripts/lib/eval-schema.js +135 -0
  225. package/scripts/lib/eval-storage.js +78 -0
  226. package/scripts/lib/grading.js +203 -0
  227. package/scripts/lib/jsonl-lock.sh +48 -0
  228. package/scripts/lib/sanitize.sh +116 -0
  229. package/scripts/lib/transcript-parser.js +63 -0
  230. package/scripts/lint.js +47 -0
  231. package/scripts/migrate-to-bun-test.js +412 -0
  232. package/scripts/pr-coordinator.sh +706 -0
  233. package/scripts/run-command-eval.js +236 -0
  234. package/scripts/smart-status.sh +809 -0
  235. package/scripts/sync-commands.js +571 -0
  236. package/scripts/sync-utils.sh +455 -0
  237. package/scripts/test-dashboard.js +123 -0
  238. package/scripts/test.js +46 -0
  239. package/scripts/validate.sh +94 -0
  240. package/skills/parallel-deep-research/SKILL.md +108 -108
  241. package/skills/parallel-deep-research/evals/README.md +27 -27
  242. package/skills/parallel-deep-research/evals/evals.json +62 -62
  243. package/skills/sonarcloud-analysis/SKILL.md +171 -171
  244. package/skills/sonarcloud-analysis/evals/README.md +27 -27
  245. package/skills/sonarcloud-analysis/evals/evals.json +50 -50
  246. package/skills/sonarcloud-analysis/references/api-reference.md +466 -466
  247. package/.cursor/hooks/state/continual-learning-index.json +0 -19
  248. package/.cursor/hooks/state/continual-learning.json +0 -8
@@ -1,197 +1,197 @@
1
- /**
2
- * Workflow Profiles
3
- *
4
- * Implements hybrid approach: 4 user-facing types (Feature/Fix/Refactor/Chore)
5
- * map to 6 internal profiles (Critical/Standard/Simple/Hotfix/Docs/Refactor)
6
- * with keyword-based auto-escalation.
7
- */
8
-
9
- /**
10
- * Internal workflow profiles aligned with AGENTS.md specification
11
- */
12
- const PROFILES = {
13
- critical: {
14
- name: 'Critical (Maximum Rigor)',
15
- stages: ['/status', '/plan', '/dev', '/validate', '/ship', '/review', '/premerge', '/verify'],
16
- tdd: 'strict',
17
- research: 'required',
18
- description: 'Security, auth, payments, data integrity, breaking changes',
19
- keywords: ['auth', 'security', 'payment', 'crypto', 'password', 'token', 'session', 'data-migration', 'breaking']
20
- },
21
-
22
- standard: {
23
- name: 'Standard (Full Workflow)',
24
- stages: ['/status', '/plan', '/dev', '/validate', '/ship', '/review', '/premerge'],
25
- tdd: 'required',
26
- research: 'optional',
27
- description: 'Most features and non-critical enhancements'
28
- },
29
-
30
- simple: {
31
- name: 'Simple (Streamlined)',
32
- stages: ['/dev', '/validate', '/ship', '/premerge'],
33
- tdd: 'recommended',
34
- research: 'skip',
35
- description: 'UI tweaks, small improvements, minor fixes'
36
- },
37
-
38
- hotfix: {
39
- name: 'Hotfix (Emergency)',
40
- stages: ['/dev', '/validate', '/ship'],
41
- tdd: 'required', // Must reproduce bug
42
- research: 'skip',
43
- description: 'Production bugs, urgent fixes',
44
- keywords: ['urgent', 'production', 'emergency', 'hotfix', 'critical']
45
- },
46
-
47
- docs: {
48
- name: 'Docs (Documentation Only)',
49
- stages: ['/verify', '/ship', '/premerge'],
50
- tdd: 'no',
51
- research: 'no',
52
- description: 'Documentation updates, README changes'
53
- },
54
-
55
- refactor: {
56
- name: 'Refactor (Behavior-Preserving)',
57
- stages: ['/plan', '/dev', '/validate', '/ship', '/premerge'],
58
- tdd: 'strict', // Must preserve behavior
59
- research: 'optional',
60
- description: 'Code cleanup, optimization, behavior-preserving improvements'
61
- }
62
- };
63
-
64
- /**
65
- * Generic keyword detection helper (DRY utility)
66
- * @param {string} text - Text to analyze
67
- * @param {string[]} keywords - Keywords to search for
68
- * @returns {boolean} - True if any keyword found
69
- */
70
- function containsKeywords(text, keywords) {
71
- if (!text || typeof text !== 'string') return false;
72
- const lowerText = text.toLowerCase();
73
- return keywords.some(keyword => lowerText.includes(keyword));
74
- }
75
-
76
- /**
77
- * Detects if text contains critical keywords (auth, security, payment, etc.)
78
- * @param {string} text - Text to analyze (branch name, commit message, etc.)
79
- * @returns {boolean} - True if critical keywords found
80
- */
81
- function containsCriticalKeywords(text) {
82
- const keywords = ['auth', 'security', 'payment', 'crypto', 'password', 'token', 'session', 'migration', 'breaking'];
83
- return containsKeywords(text, keywords);
84
- }
85
-
86
- /**
87
- * Detects if text contains hotfix keywords (urgent, production, emergency, etc.)
88
- * @param {string} text - Text to analyze (branch name, commit message, etc.)
89
- * @returns {boolean} - True if hotfix keywords found
90
- */
91
- function containsHotfixKeywords(text) {
92
- const keywords = ['urgent', 'production', 'emergency', 'hotfix', 'critical'];
93
- return containsKeywords(text, keywords);
94
- }
95
-
96
- /**
97
- * Detects user-facing work type from context (4 simple types)
98
- * @param {Object} context - Detection context
99
- * @param {string} context.branch - Git branch name
100
- * @returns {string} - User type: 'feature' | 'fix' | 'refactor' | 'chore'
101
- */
102
- function getUserType(context) {
103
- const branch = context.branch || '';
104
- const branchLower = branch.toLowerCase();
105
-
106
- // Detect from branch prefix
107
- if (branchLower.startsWith('feat/')) return 'feature';
108
- if (branchLower.startsWith('fix/')) return 'fix';
109
- if (branchLower.startsWith('hotfix/')) return 'fix';
110
- if (branchLower.startsWith('refactor/')) return 'refactor';
111
- if (branchLower.startsWith('docs/')) return 'chore';
112
- if (branchLower.startsWith('chore/')) return 'chore';
113
-
114
- // Default: feature (safest - full workflow)
115
- return 'feature';
116
- }
117
-
118
- /**
119
- * Maps user type to internal profile with keyword-based escalation (6 granular profiles)
120
- * @param {string} userType - User-facing type: 'feature' | 'fix' | 'refactor' | 'chore'
121
- * @param {Object} context - Detection context
122
- * @param {string[]} context.keywords - Keywords from branch/commit
123
- * @param {string[]} context.files - Modified files
124
- * @returns {string} - Internal profile: 'critical' | 'standard' | 'simple' | 'hotfix' | 'docs' | 'refactor'
125
- */
126
- function getInternalProfile(userType, context) {
127
- const keywords = context.keywords || [];
128
- const files = context.files || [];
129
-
130
- // Combine all keywords into a single string for analysis
131
- const keywordText = keywords.join(' ');
132
-
133
- switch (userType) {
134
- case 'feature':
135
- // Auto-escalate to Critical if security-sensitive
136
- return containsCriticalKeywords(keywordText) ? 'critical' : 'standard';
137
-
138
- case 'fix':
139
- // Auto-escalate to Hotfix if urgent/production
140
- return containsHotfixKeywords(keywordText) ? 'hotfix' : 'simple';
141
-
142
- case 'refactor':
143
- // 1:1 mapping
144
- return 'refactor';
145
-
146
- case 'chore':
147
- // Docs if only markdown files, otherwise Simple
148
- if (files.length > 0 && files.every(f => f.endsWith('.md'))) {
149
- return 'docs';
150
- }
151
- return 'simple';
152
-
153
- default:
154
- return 'standard';
155
- }
156
- }
157
-
158
- /**
159
- * Main detection function - detects work type and selects appropriate profile
160
- * @param {Object} context - Detection context
161
- * @param {string} context.manualProfile - Manual profile override (optional)
162
- * @param {string} context.branch - Git branch name
163
- * @param {string[]} context.keywords - Keywords from branch/commit
164
- * @param {string[]} context.files - Modified files
165
- * @returns {Object} - { userType, profile, source }
166
- */
167
- function detectWorkType(context) {
168
- // Priority 1: Manual override (power users)
169
- if (context.manualProfile) {
170
- return {
171
- userType: null,
172
- profile: context.manualProfile,
173
- source: 'manual'
174
- };
175
- }
176
-
177
- // Priority 2: Detect simple user type (4 options)
178
- const userType = getUserType(context);
179
-
180
- // Priority 3: Auto-select granular internal profile (6 options)
181
- const profile = getInternalProfile(userType, context);
182
-
183
- return {
184
- userType,
185
- profile,
186
- source: 'auto'
187
- };
188
- }
189
-
190
- module.exports = {
191
- PROFILES,
192
- containsCriticalKeywords,
193
- containsHotfixKeywords,
194
- getUserType,
195
- getInternalProfile,
196
- detectWorkType
197
- };
1
+ /**
2
+ * Workflow Profiles
3
+ *
4
+ * Implements hybrid approach: 4 user-facing types (Feature/Fix/Refactor/Chore)
5
+ * map to 6 internal profiles (Critical/Standard/Simple/Hotfix/Docs/Refactor)
6
+ * with keyword-based auto-escalation.
7
+ */
8
+
9
+ /**
10
+ * Internal workflow profiles aligned with AGENTS.md specification
11
+ */
12
+ const PROFILES = {
13
+ critical: {
14
+ name: 'Critical (Maximum Rigor)',
15
+ stages: ['/status', '/plan', '/dev', '/validate', '/ship', '/review', '/premerge', '/verify'],
16
+ tdd: 'strict',
17
+ research: 'required',
18
+ description: 'Security, auth, payments, data integrity, breaking changes',
19
+ keywords: ['auth', 'security', 'payment', 'crypto', 'password', 'token', 'session', 'data-migration', 'breaking']
20
+ },
21
+
22
+ standard: {
23
+ name: 'Standard (Full Workflow)',
24
+ stages: ['/status', '/plan', '/dev', '/validate', '/ship', '/review', '/premerge'],
25
+ tdd: 'required',
26
+ research: 'optional',
27
+ description: 'Most features and non-critical enhancements'
28
+ },
29
+
30
+ simple: {
31
+ name: 'Simple (Streamlined)',
32
+ stages: ['/dev', '/validate', '/ship', '/premerge'],
33
+ tdd: 'recommended',
34
+ research: 'skip',
35
+ description: 'UI tweaks, small improvements, minor fixes'
36
+ },
37
+
38
+ hotfix: {
39
+ name: 'Hotfix (Emergency)',
40
+ stages: ['/dev', '/validate', '/ship'],
41
+ tdd: 'required', // Must reproduce bug
42
+ research: 'skip',
43
+ description: 'Production bugs, urgent fixes',
44
+ keywords: ['urgent', 'production', 'emergency', 'hotfix', 'critical']
45
+ },
46
+
47
+ docs: {
48
+ name: 'Docs (Documentation Only)',
49
+ stages: ['/verify', '/ship', '/premerge'],
50
+ tdd: 'no',
51
+ research: 'no',
52
+ description: 'Documentation updates, README changes'
53
+ },
54
+
55
+ refactor: {
56
+ name: 'Refactor (Behavior-Preserving)',
57
+ stages: ['/plan', '/dev', '/validate', '/ship', '/premerge'],
58
+ tdd: 'strict', // Must preserve behavior
59
+ research: 'optional',
60
+ description: 'Code cleanup, optimization, behavior-preserving improvements'
61
+ }
62
+ };
63
+
64
+ /**
65
+ * Generic keyword detection helper (DRY utility)
66
+ * @param {string} text - Text to analyze
67
+ * @param {string[]} keywords - Keywords to search for
68
+ * @returns {boolean} - True if any keyword found
69
+ */
70
+ function containsKeywords(text, keywords) {
71
+ if (!text || typeof text !== 'string') return false;
72
+ const lowerText = text.toLowerCase();
73
+ return keywords.some(keyword => lowerText.includes(keyword));
74
+ }
75
+
76
+ /**
77
+ * Detects if text contains critical keywords (auth, security, payment, etc.)
78
+ * @param {string} text - Text to analyze (branch name, commit message, etc.)
79
+ * @returns {boolean} - True if critical keywords found
80
+ */
81
+ function containsCriticalKeywords(text) {
82
+ const keywords = ['auth', 'security', 'payment', 'crypto', 'password', 'token', 'session', 'migration', 'breaking'];
83
+ return containsKeywords(text, keywords);
84
+ }
85
+
86
+ /**
87
+ * Detects if text contains hotfix keywords (urgent, production, emergency, etc.)
88
+ * @param {string} text - Text to analyze (branch name, commit message, etc.)
89
+ * @returns {boolean} - True if hotfix keywords found
90
+ */
91
+ function containsHotfixKeywords(text) {
92
+ const keywords = ['urgent', 'production', 'emergency', 'hotfix', 'critical'];
93
+ return containsKeywords(text, keywords);
94
+ }
95
+
96
+ /**
97
+ * Detects user-facing work type from context (4 simple types)
98
+ * @param {Object} context - Detection context
99
+ * @param {string} context.branch - Git branch name
100
+ * @returns {string} - User type: 'feature' | 'fix' | 'refactor' | 'chore'
101
+ */
102
+ function getUserType(context) {
103
+ const branch = context.branch || '';
104
+ const branchLower = branch.toLowerCase();
105
+
106
+ // Detect from branch prefix
107
+ if (branchLower.startsWith('feat/')) return 'feature';
108
+ if (branchLower.startsWith('fix/')) return 'fix';
109
+ if (branchLower.startsWith('hotfix/')) return 'fix';
110
+ if (branchLower.startsWith('refactor/')) return 'refactor';
111
+ if (branchLower.startsWith('docs/')) return 'chore';
112
+ if (branchLower.startsWith('chore/')) return 'chore';
113
+
114
+ // Default: feature (safest - full workflow)
115
+ return 'feature';
116
+ }
117
+
118
+ /**
119
+ * Maps user type to internal profile with keyword-based escalation (6 granular profiles)
120
+ * @param {string} userType - User-facing type: 'feature' | 'fix' | 'refactor' | 'chore'
121
+ * @param {Object} context - Detection context
122
+ * @param {string[]} context.keywords - Keywords from branch/commit
123
+ * @param {string[]} context.files - Modified files
124
+ * @returns {string} - Internal profile: 'critical' | 'standard' | 'simple' | 'hotfix' | 'docs' | 'refactor'
125
+ */
126
+ function getInternalProfile(userType, context) {
127
+ const keywords = context.keywords || [];
128
+ const files = context.files || [];
129
+
130
+ // Combine all keywords into a single string for analysis
131
+ const keywordText = keywords.join(' ');
132
+
133
+ switch (userType) {
134
+ case 'feature':
135
+ // Auto-escalate to Critical if security-sensitive
136
+ return containsCriticalKeywords(keywordText) ? 'critical' : 'standard';
137
+
138
+ case 'fix':
139
+ // Auto-escalate to Hotfix if urgent/production
140
+ return containsHotfixKeywords(keywordText) ? 'hotfix' : 'simple';
141
+
142
+ case 'refactor':
143
+ // 1:1 mapping
144
+ return 'refactor';
145
+
146
+ case 'chore':
147
+ // Docs if only markdown files, otherwise Simple
148
+ if (files.length > 0 && files.every(f => f.endsWith('.md'))) {
149
+ return 'docs';
150
+ }
151
+ return 'simple';
152
+
153
+ default:
154
+ return 'standard';
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Main detection function - detects work type and selects appropriate profile
160
+ * @param {Object} context - Detection context
161
+ * @param {string} context.manualProfile - Manual profile override (optional)
162
+ * @param {string} context.branch - Git branch name
163
+ * @param {string[]} context.keywords - Keywords from branch/commit
164
+ * @param {string[]} context.files - Modified files
165
+ * @returns {Object} - { userType, profile, source }
166
+ */
167
+ function detectWorkType(context) {
168
+ // Priority 1: Manual override (power users)
169
+ if (context.manualProfile) {
170
+ return {
171
+ userType: null,
172
+ profile: context.manualProfile,
173
+ source: 'manual'
174
+ };
175
+ }
176
+
177
+ // Priority 2: Detect simple user type (4 options)
178
+ const userType = getUserType(context);
179
+
180
+ // Priority 3: Auto-select granular internal profile (6 options)
181
+ const profile = getInternalProfile(userType, context);
182
+
183
+ return {
184
+ userType,
185
+ profile,
186
+ source: 'auto'
187
+ };
188
+ }
189
+
190
+ module.exports = {
191
+ PROFILES,
192
+ containsCriticalKeywords,
193
+ containsHotfixKeywords,
194
+ getUserType,
195
+ getInternalProfile,
196
+ detectWorkType
197
+ };
package/package.json CHANGED
@@ -1,128 +1,131 @@
1
- {
2
- "name": "forge-workflow",
3
- "version": "0.0.4",
4
- "description": "7-stage TDD workflow for ALL AI coding agents (Claude, Cursor, Cline, OpenCode, Copilot, Kilo Code, Roo Code, Codex)",
5
- "bin": {
6
- "forge": "bin/forge.js",
7
- "forge-preflight": "bin/forge-preflight.js"
8
- },
9
- "workspaces": [
10
- "packages/*"
11
- ],
12
- "scripts": {
13
- "test": "bun test",
14
- "test:setup": "bash test-env/automation/setup-fixtures.sh",
15
- "test:all": "bun run test:setup && bun test",
16
- "test:coverage": "c8 --check-coverage bun test",
17
- "typecheck": "echo 'No TypeScript in project - skipping type check'",
18
- "lint": "eslint . --max-warnings 0",
19
- "check": "bash scripts/validate.sh",
20
- "prepare": "lefthook install || echo 'Note: lefthook not installed. Git hooks disabled. Run: bun add -d lefthook'",
21
- "setup": "node ./bin/forge.js setup",
22
- "help": "node ./bin/forge.js --help",
23
- "validate:yaml": "find . \\( -name '*.yml' -o -name '*.yaml' \\) | grep -v node_modules | while IFS= read -r file; do echo \"Checking $file...\" && bun x js-yaml \"$file\" > /dev/null || exit 1; done",
24
- "test:mutation": "npx stryker run",
25
- "test:benchmark": "node scripts/benchmark.js",
26
- "test:dashboard": "node scripts/test-dashboard.js"
27
- },
28
- "peerDependencies": {
29
- "lefthook": "^1.0.0"
30
- },
31
- "peerDependenciesMeta": {
32
- "lefthook": {
33
- "optional": true
34
- }
35
- },
36
- "devDependencies": {
37
- "@commitlint/cli": "^20.4.1",
38
- "@commitlint/config-conventional": "^20.4.1",
39
- "@eslint/js": "^10.0.1",
40
- "@microsoft/eslint-formatter-sarif": "^3.1.0",
41
- "@stryker-mutator/core": "^9.6.0",
42
- "c8": "^11.0.0",
43
- "eslint": "^10.0.2",
44
- "globals": "^17.3.0",
45
- "js-yaml": "^4.1.1",
46
- "lefthook": "^1.10.1",
47
- "yaml": "^2.8.2"
48
- },
49
- "keywords": [
50
- "ai",
51
- "workflow",
52
- "tdd",
53
- "agents-md",
54
- "claude-code",
55
- "cursor",
56
- "kilo-code",
57
- "opencode",
58
- "copilot",
59
- "cline",
60
- "roo-code",
61
- "codex",
62
- "development",
63
- "testing"
64
- ],
65
- "author": "Harsha Nandak",
66
- "license": "MIT",
67
- "repository": {
68
- "type": "git",
69
- "url": "git+https://github.com/harshanandak/forge.git"
70
- },
71
- "homepage": "https://github.com/harshanandak/forge#readme",
72
- "bugs": {
73
- "url": "https://github.com/harshanandak/forge/issues"
74
- },
75
- "files": [
76
- "bin/",
77
- "lib/",
78
- "skills/",
79
- ".claude/commands/",
80
- ".claude/rules/",
81
- ".claude/scripts/",
82
- ".claude/skills/",
83
- ".cursor/",
84
- ".cline/",
85
- ".roo/",
86
- ".codex/",
87
- ".kilocode/",
88
- ".opencode/",
89
- ".github/prompts/",
90
- ".github/PLUGIN_TEMPLATE.json",
91
- ".forge/hooks/",
92
- "docs/*.md",
93
- "install.sh",
94
- "lefthook.yml",
95
- "AGENTS.md",
96
- "CLAUDE.md",
97
- ".mcp.json.example"
98
- ],
99
- "dependencies": {
100
- "@babel/parser": "^7.29.2",
101
- "fastest-levenshtein": "^1.0.16"
102
- },
103
- "overrides": {
104
- "eslint": "^10.0.2",
105
- "flatted": "3.4.2",
106
- "minimatch": "10.2.4"
107
- },
108
- "c8": {
109
- "lines": 80,
110
- "branches": 80,
111
- "functions": 80,
112
- "statements": 80,
113
- "exclude": [
114
- "test/**",
115
- "test-env/**",
116
- "**/*.test.js",
117
- "**/*.spec.js",
118
- "coverage/**",
119
- ".forge/hooks/**",
120
- "bin/forge.js"
121
- ],
122
- "reporter": [
123
- "text",
124
- "lcov",
125
- "html"
126
- ]
127
- }
128
- }
1
+ {
2
+ "name": "forge-workflow",
3
+ "version": "0.0.6",
4
+ "description": "7-stage TDD workflow for ALL AI coding agents (Claude, Cursor, Cline, OpenCode, Copilot, Kilo Code, Roo Code, Codex)",
5
+ "bin": {
6
+ "forge": "bin/forge.js",
7
+ "forge-preflight": "bin/forge-preflight.js"
8
+ },
9
+ "workspaces": [
10
+ "packages/*"
11
+ ],
12
+ "scripts": {
13
+ "test": "bun test --timeout 15000",
14
+ "test:setup": "bash test-env/automation/setup-fixtures.sh",
15
+ "test:all": "bun run test:setup && bun test",
16
+ "test:coverage": "c8 --check-coverage bun test",
17
+ "typecheck": "echo 'No TypeScript in project - skipping type check'",
18
+ "lint": "eslint . --max-warnings 0",
19
+ "check": "bash scripts/validate.sh",
20
+ "prepare": "lefthook install || echo 'Note: lefthook not installed. Git hooks disabled. Run: bun add -d lefthook'",
21
+ "setup": "node ./bin/forge.js setup",
22
+ "help": "node ./bin/forge.js --help",
23
+ "validate:yaml": "find . \\( -name '*.yml' -o -name '*.yaml' \\) | grep -v node_modules | while IFS= read -r file; do echo \"Checking $file...\" && bun x js-yaml \"$file\" > /dev/null || exit 1; done",
24
+ "test:mutation": "npx stryker run",
25
+ "test:benchmark": "node scripts/benchmark.js",
26
+ "test:dashboard": "node scripts/test-dashboard.js"
27
+ },
28
+ "peerDependencies": {
29
+ "lefthook": "^1.0.0"
30
+ },
31
+ "peerDependenciesMeta": {
32
+ "lefthook": {
33
+ "optional": true
34
+ }
35
+ },
36
+ "devDependencies": {
37
+ "@commitlint/cli": "^20.4.1",
38
+ "@commitlint/config-conventional": "^20.4.1",
39
+ "@eslint/js": "^10.0.1",
40
+ "@microsoft/eslint-formatter-sarif": "^3.1.0",
41
+ "@stryker-mutator/core": "^9.6.0",
42
+ "c8": "^11.0.0",
43
+ "eslint": "^10.0.2",
44
+ "globals": "^17.3.0",
45
+ "js-yaml": "^4.1.1",
46
+ "lefthook": "^1.10.1",
47
+ "yaml": "^2.8.2"
48
+ },
49
+ "keywords": [
50
+ "ai",
51
+ "workflow",
52
+ "tdd",
53
+ "agents-md",
54
+ "claude-code",
55
+ "cursor",
56
+ "kilo-code",
57
+ "opencode",
58
+ "copilot",
59
+ "cline",
60
+ "roo-code",
61
+ "codex",
62
+ "development",
63
+ "testing"
64
+ ],
65
+ "author": "Harsha Nandak",
66
+ "license": "MIT",
67
+ "repository": {
68
+ "type": "git",
69
+ "url": "git+https://github.com/harshanandak/forge.git"
70
+ },
71
+ "homepage": "https://github.com/harshanandak/forge#readme",
72
+ "bugs": {
73
+ "url": "https://github.com/harshanandak/forge/issues"
74
+ },
75
+ "files": [
76
+ "bin/",
77
+ "lib/",
78
+ "skills/",
79
+ ".claude/commands/",
80
+ ".claude/rules/",
81
+ ".claude/scripts/",
82
+ ".claude/skills/",
83
+ ".cursor/",
84
+ ".cline/",
85
+ ".roo/",
86
+ ".codex/",
87
+ ".kilocode/",
88
+ ".opencode/",
89
+ "scripts/",
90
+ ".github/prompts/",
91
+ ".github/PLUGIN_TEMPLATE.json",
92
+ ".github/workflows/github-to-beads.yml",
93
+ ".github/workflows/beads-to-github.yml",
94
+ ".forge/hooks/",
95
+ "docs/*.md",
96
+ "install.sh",
97
+ "lefthook.yml",
98
+ "AGENTS.md",
99
+ "CLAUDE.md",
100
+ ".mcp.json.example"
101
+ ],
102
+ "dependencies": {
103
+ "@babel/parser": "^7.29.2",
104
+ "fastest-levenshtein": "^1.0.16"
105
+ },
106
+ "overrides": {
107
+ "eslint": "^10.0.2",
108
+ "flatted": "3.4.2",
109
+ "minimatch": "10.2.4"
110
+ },
111
+ "c8": {
112
+ "lines": 80,
113
+ "branches": 80,
114
+ "functions": 80,
115
+ "statements": 80,
116
+ "exclude": [
117
+ "test/**",
118
+ "test-env/**",
119
+ "**/*.test.js",
120
+ "**/*.spec.js",
121
+ "coverage/**",
122
+ ".forge/hooks/**",
123
+ "bin/forge.js"
124
+ ],
125
+ "reporter": [
126
+ "text",
127
+ "lcov",
128
+ "html"
129
+ ]
130
+ }
131
+ }