forge-workflow 0.0.1
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/.claude/commands/dev.md +314 -0
- package/.claude/commands/plan.md +389 -0
- package/.claude/commands/premerge.md +179 -0
- package/.claude/commands/research.md +42 -0
- package/.claude/commands/review.md +442 -0
- package/.claude/commands/rollback.md +721 -0
- package/.claude/commands/ship.md +134 -0
- package/.claude/commands/sonarcloud.md +152 -0
- package/.claude/commands/status.md +77 -0
- package/.claude/commands/validate.md +237 -0
- package/.claude/commands/verify.md +221 -0
- package/.claude/rules/greptile-review-process.md +285 -0
- package/.claude/rules/workflow.md +105 -0
- package/.claude/scripts/greptile-resolve.sh +526 -0
- package/.claude/scripts/load-env.sh +32 -0
- package/.forge/hooks/check-tdd.js +240 -0
- package/.github/PLUGIN_TEMPLATE.json +32 -0
- package/.mcp.json.example +12 -0
- package/AGENTS.md +169 -0
- package/CLAUDE.md +99 -0
- package/LICENSE +21 -0
- package/README.md +414 -0
- package/bin/forge-cmd.js +313 -0
- package/bin/forge-validate.js +303 -0
- package/bin/forge.js +4228 -0
- package/docs/AGENT_INSTALL_PROMPT.md +342 -0
- package/docs/ENHANCED_ONBOARDING.md +602 -0
- package/docs/EXAMPLES.md +482 -0
- package/docs/GREPTILE_SETUP.md +400 -0
- package/docs/MANUAL_REVIEW_GUIDE.md +106 -0
- package/docs/ROADMAP.md +359 -0
- package/docs/SETUP.md +632 -0
- package/docs/TOOLCHAIN.md +849 -0
- package/docs/VALIDATION.md +363 -0
- package/docs/WORKFLOW.md +400 -0
- package/docs/planning/PROGRESS.md +396 -0
- package/docs/plans/.gitkeep +0 -0
- package/docs/plans/2026-02-27-forge-test-suite-v2-decisions.md +21 -0
- package/docs/plans/2026-02-27-forge-test-suite-v2-design.md +362 -0
- package/docs/plans/2026-02-27-forge-test-suite-v2-tasks.md +343 -0
- package/docs/plans/2026-03-02-superpowers-gaps-decisions.md +26 -0
- package/docs/plans/2026-03-02-superpowers-gaps-design.md +239 -0
- package/docs/plans/2026-03-02-superpowers-gaps-tasks.md +260 -0
- package/docs/plans/2026-03-04-agent-command-parity-design.md +163 -0
- package/docs/plans/2026-03-04-verify-worktree-cleanup-decisions.md +7 -0
- package/docs/plans/2026-03-04-verify-worktree-cleanup-design.md +165 -0
- package/docs/plans/2026-03-05-forge-uto-decisions.md +6 -0
- package/docs/plans/2026-03-05-forge-uto-design.md +116 -0
- package/docs/plans/2026-03-05-forge-uto-tasks.md +244 -0
- package/docs/plans/2026-03-10-command-creator-and-eval-decisions.md +52 -0
- package/docs/plans/2026-03-10-command-creator-and-eval-design.md +350 -0
- package/docs/plans/2026-03-10-command-creator-and-eval-tasks.md +426 -0
- package/docs/plans/2026-03-10-stale-workflow-refs-decisions.md +8 -0
- package/docs/plans/2026-03-10-stale-workflow-refs-design.md +80 -0
- package/docs/plans/2026-03-10-stale-workflow-refs-tasks.md +90 -0
- package/docs/plans/2026-03-14-beads-plan-context-decisions.md +9 -0
- package/docs/plans/2026-03-14-beads-plan-context-design.md +171 -0
- package/docs/plans/2026-03-14-beads-plan-context-tasks.md +160 -0
- package/docs/plans/2026-03-14-skill-eval-loop-decisions.md +33 -0
- package/docs/plans/2026-03-14-skill-eval-loop-design.md +118 -0
- package/docs/plans/2026-03-14-skill-eval-loop-results.md +78 -0
- package/docs/plans/2026-03-14-skill-eval-loop-tasks.md +160 -0
- package/docs/plans/2026-03-15-agent-command-parity-v2-decisions.md +11 -0
- package/docs/plans/2026-03-15-agent-command-parity-v2-design.md +145 -0
- package/docs/plans/2026-03-15-agent-command-parity-v2-tasks.md +211 -0
- package/docs/research/TEMPLATE.md +292 -0
- package/docs/research/advanced-testing.md +297 -0
- package/docs/research/agent-permissions.md +167 -0
- package/docs/research/dependency-chain.md +328 -0
- package/docs/research/forge-workflow-v2.md +550 -0
- package/docs/research/plugin-architecture.md +772 -0
- package/docs/research/pr4-cli-automation.md +326 -0
- package/docs/research/premerge-verify-restructure.md +205 -0
- package/docs/research/skills-restructure.md +508 -0
- package/docs/research/sonarcloud-perfection-plan.md +166 -0
- package/docs/research/sonarcloud-quality-gate.md +184 -0
- package/docs/research/superpowers-integration.md +403 -0
- package/docs/research/superpowers.md +319 -0
- package/docs/research/test-environment.md +519 -0
- package/install.sh +1062 -0
- package/lefthook.yml +39 -0
- package/lib/agents/README.md +198 -0
- package/lib/agents/claude.plugin.json +28 -0
- package/lib/agents/cline.plugin.json +22 -0
- package/lib/agents/codex.plugin.json +19 -0
- package/lib/agents/copilot.plugin.json +24 -0
- package/lib/agents/cursor.plugin.json +25 -0
- package/lib/agents/kilocode.plugin.json +22 -0
- package/lib/agents/opencode.plugin.json +20 -0
- package/lib/agents/roo.plugin.json +23 -0
- package/lib/agents-config.js +2112 -0
- package/lib/commands/dev.js +513 -0
- package/lib/commands/plan.js +696 -0
- package/lib/commands/recommend.js +119 -0
- package/lib/commands/ship.js +377 -0
- package/lib/commands/status.js +378 -0
- package/lib/commands/validate.js +602 -0
- package/lib/context-merge.js +359 -0
- package/lib/plugin-catalog.js +360 -0
- package/lib/plugin-manager.js +166 -0
- package/lib/plugin-recommender.js +141 -0
- package/lib/project-discovery.js +491 -0
- package/lib/setup.js +118 -0
- package/lib/workflow-profiles.js +203 -0
- package/package.json +115 -0
|
@@ -0,0 +1,203 @@
|
|
|
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', '/research', '/plan', '/dev', '/validate', '/ship', '/review', '/merge', '/verify'],
|
|
16
|
+
tdd: 'strict',
|
|
17
|
+
research: 'required',
|
|
18
|
+
openspec: 'required-strategic',
|
|
19
|
+
description: 'Security, auth, payments, data integrity, breaking changes',
|
|
20
|
+
keywords: ['auth', 'security', 'payment', 'crypto', 'password', 'token', 'session', 'data-migration', 'breaking']
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
standard: {
|
|
24
|
+
name: 'Standard (Full Workflow)',
|
|
25
|
+
stages: ['/status', '/plan', '/dev', '/validate', '/ship', '/merge'],
|
|
26
|
+
tdd: 'required',
|
|
27
|
+
research: 'optional',
|
|
28
|
+
openspec: 'strategic',
|
|
29
|
+
description: 'Most features and non-critical enhancements'
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
simple: {
|
|
33
|
+
name: 'Simple (Streamlined)',
|
|
34
|
+
stages: ['/dev', '/validate', '/ship', '/merge'],
|
|
35
|
+
tdd: 'recommended',
|
|
36
|
+
research: 'skip',
|
|
37
|
+
openspec: 'no',
|
|
38
|
+
description: 'UI tweaks, small improvements, minor fixes'
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
hotfix: {
|
|
42
|
+
name: 'Hotfix (Emergency)',
|
|
43
|
+
stages: ['/dev', '/validate', '/ship'],
|
|
44
|
+
tdd: 'required', // Must reproduce bug
|
|
45
|
+
research: 'skip',
|
|
46
|
+
openspec: 'no',
|
|
47
|
+
description: 'Production bugs, urgent fixes',
|
|
48
|
+
keywords: ['urgent', 'production', 'emergency', 'hotfix', 'critical']
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
docs: {
|
|
52
|
+
name: 'Docs (Documentation Only)',
|
|
53
|
+
stages: ['/verify', '/ship', '/merge'],
|
|
54
|
+
tdd: 'no',
|
|
55
|
+
research: 'no',
|
|
56
|
+
openspec: 'no',
|
|
57
|
+
description: 'Documentation updates, README changes'
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
refactor: {
|
|
61
|
+
name: 'Refactor (Behavior-Preserving)',
|
|
62
|
+
stages: ['/plan', '/dev', '/validate', '/ship', '/merge'],
|
|
63
|
+
tdd: 'strict', // Must preserve behavior
|
|
64
|
+
research: 'optional',
|
|
65
|
+
openspec: 'architectural',
|
|
66
|
+
description: 'Code cleanup, optimization, behavior-preserving improvements'
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Generic keyword detection helper (DRY utility)
|
|
72
|
+
* @param {string} text - Text to analyze
|
|
73
|
+
* @param {string[]} keywords - Keywords to search for
|
|
74
|
+
* @returns {boolean} - True if any keyword found
|
|
75
|
+
*/
|
|
76
|
+
function containsKeywords(text, keywords) {
|
|
77
|
+
if (!text || typeof text !== 'string') return false;
|
|
78
|
+
const lowerText = text.toLowerCase();
|
|
79
|
+
return keywords.some(keyword => lowerText.includes(keyword));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Detects if text contains critical keywords (auth, security, payment, etc.)
|
|
84
|
+
* @param {string} text - Text to analyze (branch name, commit message, etc.)
|
|
85
|
+
* @returns {boolean} - True if critical keywords found
|
|
86
|
+
*/
|
|
87
|
+
function containsCriticalKeywords(text) {
|
|
88
|
+
const keywords = ['auth', 'security', 'payment', 'crypto', 'password', 'token', 'session', 'migration', 'breaking'];
|
|
89
|
+
return containsKeywords(text, keywords);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Detects if text contains hotfix keywords (urgent, production, emergency, etc.)
|
|
94
|
+
* @param {string} text - Text to analyze (branch name, commit message, etc.)
|
|
95
|
+
* @returns {boolean} - True if hotfix keywords found
|
|
96
|
+
*/
|
|
97
|
+
function containsHotfixKeywords(text) {
|
|
98
|
+
const keywords = ['urgent', 'production', 'emergency', 'hotfix', 'critical'];
|
|
99
|
+
return containsKeywords(text, keywords);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Detects user-facing work type from context (4 simple types)
|
|
104
|
+
* @param {Object} context - Detection context
|
|
105
|
+
* @param {string} context.branch - Git branch name
|
|
106
|
+
* @returns {string} - User type: 'feature' | 'fix' | 'refactor' | 'chore'
|
|
107
|
+
*/
|
|
108
|
+
function getUserType(context) {
|
|
109
|
+
const branch = context.branch || '';
|
|
110
|
+
const branchLower = branch.toLowerCase();
|
|
111
|
+
|
|
112
|
+
// Detect from branch prefix
|
|
113
|
+
if (branchLower.startsWith('feat/')) return 'feature';
|
|
114
|
+
if (branchLower.startsWith('fix/')) return 'fix';
|
|
115
|
+
if (branchLower.startsWith('hotfix/')) return 'fix';
|
|
116
|
+
if (branchLower.startsWith('refactor/')) return 'refactor';
|
|
117
|
+
if (branchLower.startsWith('docs/')) return 'chore';
|
|
118
|
+
if (branchLower.startsWith('chore/')) return 'chore';
|
|
119
|
+
|
|
120
|
+
// Default: feature (safest - full workflow)
|
|
121
|
+
return 'feature';
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Maps user type to internal profile with keyword-based escalation (6 granular profiles)
|
|
126
|
+
* @param {string} userType - User-facing type: 'feature' | 'fix' | 'refactor' | 'chore'
|
|
127
|
+
* @param {Object} context - Detection context
|
|
128
|
+
* @param {string[]} context.keywords - Keywords from branch/commit
|
|
129
|
+
* @param {string[]} context.files - Modified files
|
|
130
|
+
* @returns {string} - Internal profile: 'critical' | 'standard' | 'simple' | 'hotfix' | 'docs' | 'refactor'
|
|
131
|
+
*/
|
|
132
|
+
function getInternalProfile(userType, context) {
|
|
133
|
+
const keywords = context.keywords || [];
|
|
134
|
+
const files = context.files || [];
|
|
135
|
+
|
|
136
|
+
// Combine all keywords into a single string for analysis
|
|
137
|
+
const keywordText = keywords.join(' ');
|
|
138
|
+
|
|
139
|
+
switch (userType) {
|
|
140
|
+
case 'feature':
|
|
141
|
+
// Auto-escalate to Critical if security-sensitive
|
|
142
|
+
return containsCriticalKeywords(keywordText) ? 'critical' : 'standard';
|
|
143
|
+
|
|
144
|
+
case 'fix':
|
|
145
|
+
// Auto-escalate to Hotfix if urgent/production
|
|
146
|
+
return containsHotfixKeywords(keywordText) ? 'hotfix' : 'simple';
|
|
147
|
+
|
|
148
|
+
case 'refactor':
|
|
149
|
+
// 1:1 mapping
|
|
150
|
+
return 'refactor';
|
|
151
|
+
|
|
152
|
+
case 'chore':
|
|
153
|
+
// Docs if only markdown files, otherwise Simple
|
|
154
|
+
if (files.length > 0 && files.every(f => f.endsWith('.md'))) {
|
|
155
|
+
return 'docs';
|
|
156
|
+
}
|
|
157
|
+
return 'simple';
|
|
158
|
+
|
|
159
|
+
default:
|
|
160
|
+
return 'standard';
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Main detection function - detects work type and selects appropriate profile
|
|
166
|
+
* @param {Object} context - Detection context
|
|
167
|
+
* @param {string} context.manualProfile - Manual profile override (optional)
|
|
168
|
+
* @param {string} context.branch - Git branch name
|
|
169
|
+
* @param {string[]} context.keywords - Keywords from branch/commit
|
|
170
|
+
* @param {string[]} context.files - Modified files
|
|
171
|
+
* @returns {Object} - { userType, profile, source }
|
|
172
|
+
*/
|
|
173
|
+
function detectWorkType(context) {
|
|
174
|
+
// Priority 1: Manual override (power users)
|
|
175
|
+
if (context.manualProfile) {
|
|
176
|
+
return {
|
|
177
|
+
userType: null,
|
|
178
|
+
profile: context.manualProfile,
|
|
179
|
+
source: 'manual'
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Priority 2: Detect simple user type (4 options)
|
|
184
|
+
const userType = getUserType(context);
|
|
185
|
+
|
|
186
|
+
// Priority 3: Auto-select granular internal profile (6 options)
|
|
187
|
+
const profile = getInternalProfile(userType, context);
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
userType,
|
|
191
|
+
profile,
|
|
192
|
+
source: 'auto'
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
module.exports = {
|
|
197
|
+
PROFILES,
|
|
198
|
+
containsCriticalKeywords,
|
|
199
|
+
containsHotfixKeywords,
|
|
200
|
+
getUserType,
|
|
201
|
+
getInternalProfile,
|
|
202
|
+
detectWorkType
|
|
203
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "forge-workflow",
|
|
3
|
+
"version": "0.0.1",
|
|
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-validate": "bin/forge-validate.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "bun test",
|
|
11
|
+
"test:setup": "bash test-env/automation/setup-fixtures.sh",
|
|
12
|
+
"test:all": "bun run test:setup && bun test",
|
|
13
|
+
"test:coverage": "c8 --check-coverage bun test",
|
|
14
|
+
"typecheck": "echo 'No TypeScript in project - skipping type check'",
|
|
15
|
+
"lint": "eslint .",
|
|
16
|
+
"check": "bash scripts/validate.sh",
|
|
17
|
+
"postinstall": "node ./bin/forge.js",
|
|
18
|
+
"prepare": "lefthook install || echo 'Note: lefthook not installed. Git hooks disabled. Run: bun add -d lefthook'",
|
|
19
|
+
"setup": "node ./bin/forge.js setup",
|
|
20
|
+
"help": "node ./bin/forge.js --help",
|
|
21
|
+
"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",
|
|
22
|
+
"test:mutation": "npx stryker run",
|
|
23
|
+
"test:benchmark": "node scripts/benchmark.js",
|
|
24
|
+
"test:dashboard": "node scripts/test-dashboard.js"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"lefthook": "^1.0.0"
|
|
28
|
+
},
|
|
29
|
+
"peerDependenciesMeta": {
|
|
30
|
+
"lefthook": {
|
|
31
|
+
"optional": true
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@commitlint/cli": "^20.4.1",
|
|
36
|
+
"@commitlint/config-conventional": "^20.4.1",
|
|
37
|
+
"@eslint/js": "^10.0.1",
|
|
38
|
+
"@microsoft/eslint-formatter-sarif": "^3.1.0",
|
|
39
|
+
"@stryker-mutator/core": "^9.5.1",
|
|
40
|
+
"c8": "^11.0.0",
|
|
41
|
+
"eslint": "^10.0.2",
|
|
42
|
+
"globals": "^17.3.0",
|
|
43
|
+
"js-yaml": "^4.1.1",
|
|
44
|
+
"lefthook": "^1.10.1",
|
|
45
|
+
"yaml": "^2.8.2"
|
|
46
|
+
},
|
|
47
|
+
"keywords": [
|
|
48
|
+
"ai",
|
|
49
|
+
"workflow",
|
|
50
|
+
"tdd",
|
|
51
|
+
"agents-md",
|
|
52
|
+
"claude-code",
|
|
53
|
+
"cursor",
|
|
54
|
+
"kilo-code",
|
|
55
|
+
"opencode",
|
|
56
|
+
"copilot",
|
|
57
|
+
"cline",
|
|
58
|
+
"roo-code",
|
|
59
|
+
"codex",
|
|
60
|
+
"development",
|
|
61
|
+
"testing"
|
|
62
|
+
],
|
|
63
|
+
"author": "Harsha Nandak",
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"repository": {
|
|
66
|
+
"type": "git",
|
|
67
|
+
"url": "git+https://github.com/harshanandak/forge.git"
|
|
68
|
+
},
|
|
69
|
+
"homepage": "https://github.com/harshanandak/forge#readme",
|
|
70
|
+
"bugs": {
|
|
71
|
+
"url": "https://github.com/harshanandak/forge/issues"
|
|
72
|
+
},
|
|
73
|
+
"files": [
|
|
74
|
+
"bin/",
|
|
75
|
+
"lib/",
|
|
76
|
+
".claude/commands/",
|
|
77
|
+
".claude/rules/",
|
|
78
|
+
".claude/scripts/",
|
|
79
|
+
".forge/hooks/",
|
|
80
|
+
".github/PLUGIN_TEMPLATE.json",
|
|
81
|
+
"docs/",
|
|
82
|
+
"install.sh",
|
|
83
|
+
"lefthook.yml",
|
|
84
|
+
"AGENTS.md",
|
|
85
|
+
"CLAUDE.md",
|
|
86
|
+
".mcp.json.example"
|
|
87
|
+
],
|
|
88
|
+
"dependencies": {
|
|
89
|
+
"fastest-levenshtein": "^1.0.16"
|
|
90
|
+
},
|
|
91
|
+
"overrides": {
|
|
92
|
+
"eslint": "^10.0.2",
|
|
93
|
+
"minimatch": "10.2.4"
|
|
94
|
+
},
|
|
95
|
+
"c8": {
|
|
96
|
+
"lines": 80,
|
|
97
|
+
"branches": 80,
|
|
98
|
+
"functions": 80,
|
|
99
|
+
"statements": 80,
|
|
100
|
+
"exclude": [
|
|
101
|
+
"test/**",
|
|
102
|
+
"test-env/**",
|
|
103
|
+
"**/*.test.js",
|
|
104
|
+
"**/*.spec.js",
|
|
105
|
+
"coverage/**",
|
|
106
|
+
".forge/hooks/**",
|
|
107
|
+
"bin/forge.js"
|
|
108
|
+
],
|
|
109
|
+
"reporter": [
|
|
110
|
+
"text",
|
|
111
|
+
"lcov",
|
|
112
|
+
"html"
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
}
|