@polymorphism-tech/morph-spec 4.2.0 → 4.3.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/morph-spec.js +283 -8
- package/bin/validate.js +4 -4
- package/docs/{v3.0 → next-generation}/AGENTS.md +1 -1
- package/docs/next-generation/CONTEXT-OPTIMIZATION.md +267 -0
- package/docs/next-generation/EXECUTION-FLOW.md +274 -0
- package/docs/next-generation/META-PROMPTS.md +235 -0
- package/docs/next-generation/MIGRATION-GUIDE.md +253 -0
- package/docs/next-generation/THREAD-MANAGEMENT.md +240 -0
- package/package.json +5 -5
- package/src/commands/agents/agents-fuse.js +96 -0
- package/src/commands/agents/micro-agent.js +112 -0
- package/src/commands/agents/spawn-team.js +69 -4
- package/src/commands/agents/squad-template.js +146 -0
- package/src/commands/analytics/analytics.js +176 -0
- package/src/commands/context/context-prime.js +63 -0
- package/src/commands/context/core-four.js +54 -0
- package/src/commands/mcp/mcp.js +102 -0
- package/src/commands/project/detect-agents.js +1 -1
- package/src/commands/project/doctor.js +573 -356
- package/src/commands/project/init.js +1 -1
- package/src/commands/project/update.js +1 -1
- package/src/commands/state/advance-phase.js +433 -416
- package/src/commands/templates/template-render.js +80 -1
- package/src/commands/threads/thread-template.js +103 -0
- package/src/commands/threads/threads.js +261 -0
- package/src/commands/trust/trust.js +205 -0
- package/src/{orchestrator.js → core/orchestrator.js} +8 -8
- package/src/core/state/state-manager.js +18 -2
- package/src/core/workflows/workflow-detector.js +100 -2
- package/src/lib/agents/micro-agent-factory.js +161 -0
- package/src/lib/analytics/analytics-engine.js +345 -0
- package/src/lib/checkpoints/checkpoint-hooks.js +293 -258
- package/src/lib/context/context-bundler.js +240 -0
- package/src/lib/context/context-optimizer.js +212 -0
- package/src/lib/context/context-tracker.js +273 -0
- package/src/lib/context/core-four-tracker.js +201 -0
- package/src/lib/context/mcp-optimizer.js +200 -0
- package/src/lib/execution/fusion-executor.js +304 -0
- package/src/lib/execution/parallel-executor.js +270 -0
- package/src/lib/generators/context-generator.js +3 -3
- package/src/lib/generators/recap-generator.js +2 -2
- package/src/lib/hooks/hook-executor.js +169 -0
- package/src/lib/hooks/stop-hook-executor.js +286 -0
- package/src/lib/hops/hop-composer.js +221 -0
- package/src/lib/threads/thread-coordinator.js +238 -0
- package/src/lib/threads/thread-manager.js +317 -0
- package/src/lib/tracking/artifact-trail.js +202 -0
- package/src/lib/trust/trust-manager.js +269 -0
- package/src/lib/validators/design-system/design-system-validator.js +2 -2
- package/src/lib/validators/validation-runner.js +6 -6
- package/stacks/blazor-azure/.morph/config/agents.json +72 -3
- package/stacks/nextjs-supabase/.morph/config/agents.json +3 -3
- package/CLAUDE.md +0 -993
- package/docs/llm-interaction-config.md +0 -735
- package/docs/v3.0/EXECUTION-FLOW.md +0 -1304
- package/src/commands/utils/migrate-state.js +0 -158
- package/src/commands/utils/upgrade.js +0 -346
- package/src/lib/validators/architecture-validator.js +0 -60
- package/src/lib/validators/content-validator.js +0 -164
- package/src/lib/validators/package-validator.js +0 -61
- package/src/lib/validators/ui-contrast-validator.js +0 -44
- package/stacks/blazor-azure/.claude/commands/morph-apply.md +0 -221
- package/stacks/blazor-azure/.claude/commands/morph-archive.md +0 -79
- package/stacks/blazor-azure/.claude/commands/morph-deploy.md +0 -529
- package/stacks/blazor-azure/.claude/commands/morph-infra.md +0 -209
- package/stacks/blazor-azure/.claude/commands/morph-preflight.md +0 -227
- package/stacks/blazor-azure/.claude/commands/morph-proposal.md +0 -122
- package/stacks/blazor-azure/.claude/commands/morph-status.md +0 -86
- package/stacks/blazor-azure/.claude/commands/morph-troubleshoot.md +0 -122
- package/stacks/blazor-azure/.claude/skills/level-0-meta/README.md +0 -7
- package/stacks/blazor-azure/.claude/skills/level-0-meta/code-review.md +0 -226
- package/stacks/blazor-azure/.claude/skills/level-0-meta/morph-checklist.md +0 -117
- package/stacks/blazor-azure/.claude/skills/level-0-meta/simulation-checklist.md +0 -77
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/README.md +0 -7
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/morph-replicate.md +0 -213
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-clarify.md +0 -131
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-design.md +0 -213
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-setup.md +0 -106
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-tasks.md +0 -164
- package/stacks/blazor-azure/.claude/skills/level-1-workflows/phase-uiux.md +0 -169
- package/stacks/blazor-azure/.claude/skills/level-2-domains/README.md +0 -14
- package/stacks/blazor-azure/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +0 -192
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/po-pm-advisor.md +0 -197
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/prompt-engineer.md +0 -189
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/seo-growth-hacker.md +0 -320
- package/stacks/blazor-azure/.claude/skills/level-2-domains/architecture/standards-architect.md +0 -156
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/api-designer.md +0 -59
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/dotnet-senior.md +0 -77
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ef-modeler.md +0 -58
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/hangfire-orchestrator.md +0 -126
- package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ms-agent-expert.md +0 -45
- package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/blazor-builder.md +0 -210
- package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/nextjs-expert.md +0 -154
- package/stacks/blazor-azure/.claude/skills/level-2-domains/frontend/ui-ux-designer.md +0 -191
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/azure-architect.md +0 -142
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +0 -699
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/bicep-architect.md +0 -126
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/container-specialist.md +0 -131
- package/stacks/blazor-azure/.claude/skills/level-2-domains/infrastructure/devops-engineer.md +0 -119
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/asaas-financial.md +0 -130
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/azure-identity.md +0 -142
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/clerk-auth.md +0 -108
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/hangfire-orchestrator.md +0 -64
- package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/resend-email.md +0 -119
- package/stacks/blazor-azure/.claude/skills/level-2-domains/quality/code-analyzer.md +0 -235
- package/stacks/blazor-azure/.claude/skills/level-2-domains/quality/testing-specialist.md +0 -126
- package/stacks/blazor-azure/.claude/skills/level-3-technologies/README.md +0 -7
- package/stacks/blazor-azure/.claude/skills/level-4-patterns/README.md +0 -7
- package/stacks/blazor-azure/.morph/archive/.gitkeep +0 -25
- package/stacks/blazor-azure/.morph/features/.gitkeep +0 -25
- package/stacks/blazor-azure/.morph/schemas/agent.schema.json +0 -296
- package/stacks/blazor-azure/.morph/schemas/tasks.schema.json +0 -220
- package/stacks/blazor-azure/.morph/specs/.gitkeep +0 -20
- package/stacks/blazor-azure/.morph/test-infra/example.bicep +0 -59
- package/stacks/nextjs-supabase/.claude/commands/morph-apply.md +0 -221
- package/stacks/nextjs-supabase/.claude/commands/morph-archive.md +0 -79
- package/stacks/nextjs-supabase/.claude/commands/morph-deploy.md +0 -529
- package/stacks/nextjs-supabase/.claude/commands/morph-infra.md +0 -209
- package/stacks/nextjs-supabase/.claude/commands/morph-preflight.md +0 -227
- package/stacks/nextjs-supabase/.claude/commands/morph-proposal.md +0 -122
- package/stacks/nextjs-supabase/.claude/commands/morph-status.md +0 -86
- package/stacks/nextjs-supabase/.claude/commands/morph-troubleshoot.md +0 -122
- package/stacks/nextjs-supabase/.claude/settings.local.json +0 -6
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/backend/dotnet-supabase.md +0 -244
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/frontend/nextjs-supabase.md +0 -335
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/infrastructure/easypanel-deployer.md +0 -189
- package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +0 -50
- /package/docs/{v3.0 → next-generation}/ANALYSIS.md +0 -0
- /package/docs/{v3.0 → next-generation}/ARCHITECTURE.md +0 -0
- /package/docs/{v3.0 → next-generation}/FEATURES.md +0 -0
- /package/docs/{v3.0 → next-generation}/README.md +0 -0
- /package/docs/{v3.0 → next-generation}/ROADMAP.md +0 -0
|
@@ -1,258 +1,293 @@
|
|
|
1
|
-
import { readFileSync, existsSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { execSync } from 'child_process';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
*
|
|
50
|
-
* @
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
*
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
*
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
*
|
|
139
|
-
* @
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
console.log(
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
console.log('
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
console.log('
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
console.log(
|
|
208
|
-
console.log(
|
|
209
|
-
console.log(`
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { executeStopHooks, isMaxRetriesExceeded, incrementRetryCount } from '../hooks/stop-hook-executor.js';
|
|
5
|
+
import { recordEvent } from '../analytics/analytics-engine.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Checkpoint Hooks - Automated validation orchestration
|
|
9
|
+
*
|
|
10
|
+
* Runs validators, tests, and linters at checkpoint milestones (every N tasks).
|
|
11
|
+
* Blocks progress if critical validations fail.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Load LLM interaction configuration
|
|
16
|
+
* @returns {Object} Configuration object
|
|
17
|
+
*/
|
|
18
|
+
function loadLLMInteractionConfig() {
|
|
19
|
+
const configPath = join(process.cwd(), '.morph/config/llm-interaction.json');
|
|
20
|
+
|
|
21
|
+
if (!existsSync(configPath)) {
|
|
22
|
+
// Return defaults if config doesn't exist
|
|
23
|
+
return {
|
|
24
|
+
checkpoints: {
|
|
25
|
+
frequency: 3,
|
|
26
|
+
autoValidate: true,
|
|
27
|
+
validators: {
|
|
28
|
+
enabled: ['architecture', 'packages', 'design-system', 'security'],
|
|
29
|
+
optional: []
|
|
30
|
+
},
|
|
31
|
+
hooks: {
|
|
32
|
+
runTests: false,
|
|
33
|
+
runLinters: true,
|
|
34
|
+
buildCheck: false
|
|
35
|
+
},
|
|
36
|
+
onFailure: {
|
|
37
|
+
blockProgress: true,
|
|
38
|
+
maxRetries: 3,
|
|
39
|
+
escalateAfter: 3
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return JSON.parse(readFileSync(configPath, 'utf8'));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Run a single validator
|
|
50
|
+
* @param {string} validatorName - Validator to run (architecture, packages, etc.)
|
|
51
|
+
* @param {string} featureName - Feature being validated
|
|
52
|
+
* @returns {Promise<Object>} Validation result
|
|
53
|
+
*/
|
|
54
|
+
async function runValidator(validatorName, featureName) {
|
|
55
|
+
try {
|
|
56
|
+
// Use existing validate command
|
|
57
|
+
const result = execSync(
|
|
58
|
+
`node bin/validate.js ${validatorName} --feature=${featureName} --json`,
|
|
59
|
+
{ encoding: 'utf8', stdio: 'pipe' }
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const parsed = JSON.parse(result);
|
|
63
|
+
return {
|
|
64
|
+
validator: validatorName,
|
|
65
|
+
passed: parsed.errors === 0,
|
|
66
|
+
errors: parsed.errors || 0,
|
|
67
|
+
warnings: parsed.warnings || 0,
|
|
68
|
+
details: parsed.issues || []
|
|
69
|
+
};
|
|
70
|
+
} catch (error) {
|
|
71
|
+
return {
|
|
72
|
+
validator: validatorName,
|
|
73
|
+
passed: false,
|
|
74
|
+
errors: 1,
|
|
75
|
+
warnings: 0,
|
|
76
|
+
details: [{ message: error.message, severity: 'error' }]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Run tests if configured
|
|
83
|
+
* @param {string} featureName - Feature being tested
|
|
84
|
+
* @returns {Promise<Object>} Test result
|
|
85
|
+
*/
|
|
86
|
+
async function runTests(featureName) {
|
|
87
|
+
try {
|
|
88
|
+
execSync('npm test --passWithNoTests', { encoding: 'utf8', stdio: 'pipe' });
|
|
89
|
+
return {
|
|
90
|
+
validator: 'tests',
|
|
91
|
+
passed: true,
|
|
92
|
+
errors: 0,
|
|
93
|
+
warnings: 0,
|
|
94
|
+
details: []
|
|
95
|
+
};
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
validator: 'tests',
|
|
99
|
+
passed: false,
|
|
100
|
+
errors: 1,
|
|
101
|
+
warnings: 0,
|
|
102
|
+
details: [{ message: 'Test suite failed', severity: 'error' }]
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Run linters if configured
|
|
109
|
+
* @param {string} featureName - Feature being linted
|
|
110
|
+
* @returns {Promise<Object>} Linter result
|
|
111
|
+
*/
|
|
112
|
+
async function runLinters(featureName) {
|
|
113
|
+
try {
|
|
114
|
+
// Check if eslint exists
|
|
115
|
+
if (existsSync(join(process.cwd(), 'node_modules/.bin/eslint'))) {
|
|
116
|
+
execSync('npm run lint --if-present', { encoding: 'utf8', stdio: 'pipe' });
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
validator: 'linters',
|
|
121
|
+
passed: true,
|
|
122
|
+
errors: 0,
|
|
123
|
+
warnings: 0,
|
|
124
|
+
details: []
|
|
125
|
+
};
|
|
126
|
+
} catch (error) {
|
|
127
|
+
return {
|
|
128
|
+
validator: 'linters',
|
|
129
|
+
passed: false,
|
|
130
|
+
errors: 0,
|
|
131
|
+
warnings: 1,
|
|
132
|
+
details: [{ message: 'Linting warnings detected', severity: 'warning' }]
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Run checkpoint hooks - orchestrates all validation
|
|
139
|
+
* @param {string} featureName - Feature name
|
|
140
|
+
* @param {number} checkpointNum - Checkpoint number (1, 2, 3, etc.)
|
|
141
|
+
* @returns {Promise<Object>} Checkpoint result
|
|
142
|
+
*/
|
|
143
|
+
export async function runCheckpointHooks(featureName, checkpointNum) {
|
|
144
|
+
const config = loadLLMInteractionConfig();
|
|
145
|
+
const checkpointConfig = config.checkpoints;
|
|
146
|
+
|
|
147
|
+
if (!checkpointConfig.autoValidate) {
|
|
148
|
+
return {
|
|
149
|
+
passed: true,
|
|
150
|
+
skipped: true,
|
|
151
|
+
message: 'Auto-validation disabled in config'
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
console.log(`\n🔍 Running CHECKPOINT ${checkpointNum} for feature: ${featureName}`);
|
|
156
|
+
console.log('━'.repeat(60));
|
|
157
|
+
|
|
158
|
+
const results = [];
|
|
159
|
+
|
|
160
|
+
// 1. Run enabled validators
|
|
161
|
+
console.log('\n📋 Running validators...');
|
|
162
|
+
for (const validatorName of checkpointConfig.validators.enabled) {
|
|
163
|
+
process.stdout.write(` • ${validatorName}... `);
|
|
164
|
+
const result = await runValidator(validatorName, featureName);
|
|
165
|
+
results.push(result);
|
|
166
|
+
|
|
167
|
+
if (result.passed) {
|
|
168
|
+
console.log('✅ PASSED');
|
|
169
|
+
} else {
|
|
170
|
+
console.log(`❌ FAILED (${result.errors} errors, ${result.warnings} warnings)`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 2. Run tests (if configured)
|
|
175
|
+
if (checkpointConfig.hooks.runTests) {
|
|
176
|
+
console.log('\n🧪 Running tests...');
|
|
177
|
+
process.stdout.write(' • test suite... ');
|
|
178
|
+
const testResult = await runTests(featureName);
|
|
179
|
+
results.push(testResult);
|
|
180
|
+
|
|
181
|
+
if (testResult.passed) {
|
|
182
|
+
console.log('✅ PASSED');
|
|
183
|
+
} else {
|
|
184
|
+
console.log('❌ FAILED');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// 3. Run linters (if configured)
|
|
189
|
+
if (checkpointConfig.hooks.runLinters) {
|
|
190
|
+
console.log('\n🎨 Running linters...');
|
|
191
|
+
process.stdout.write(' • code style... ');
|
|
192
|
+
const lintResult = await runLinters(featureName);
|
|
193
|
+
results.push(lintResult);
|
|
194
|
+
|
|
195
|
+
if (lintResult.passed) {
|
|
196
|
+
console.log('✅ PASSED');
|
|
197
|
+
} else {
|
|
198
|
+
console.log('⚠️ WARNINGS');
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Calculate overall pass/fail
|
|
203
|
+
const errorCount = results.reduce((sum, r) => sum + r.errors, 0);
|
|
204
|
+
const warningCount = results.reduce((sum, r) => sum + r.warnings, 0);
|
|
205
|
+
const passed = errorCount === 0;
|
|
206
|
+
|
|
207
|
+
console.log('\n' + '━'.repeat(60));
|
|
208
|
+
console.log(`\n📊 Checkpoint ${checkpointNum} Summary:`);
|
|
209
|
+
console.log(` Errors: ${errorCount}`);
|
|
210
|
+
console.log(` Warnings: ${warningCount}`);
|
|
211
|
+
console.log(` Status: ${passed ? '✅ PASSED' : '❌ FAILED'}`);
|
|
212
|
+
|
|
213
|
+
if (!passed) {
|
|
214
|
+
console.log('\n⚠️ Checkpoint failed! Fix violations before proceeding.');
|
|
215
|
+
|
|
216
|
+
// Show details of failures
|
|
217
|
+
results.filter(r => r.errors > 0).forEach(r => {
|
|
218
|
+
console.log(`\n❌ ${r.validator} errors:`);
|
|
219
|
+
r.details.forEach(d => {
|
|
220
|
+
if (d.severity === 'error') {
|
|
221
|
+
console.log(` - ${d.message}`);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
console.log('\n' + '━'.repeat(60) + '\n');
|
|
228
|
+
|
|
229
|
+
// Run stop hooks for L-Thread support
|
|
230
|
+
let stopHookResult = null;
|
|
231
|
+
if (featureName) {
|
|
232
|
+
try {
|
|
233
|
+
// Use feature name as pseudo thread ID for stop hook feedback
|
|
234
|
+
const pseudoThreadId = `checkpoint-${featureName}-${checkpointNum}`;
|
|
235
|
+
stopHookResult = await executeStopHooks(pseudoThreadId, 'on-stop', { feature: featureName });
|
|
236
|
+
|
|
237
|
+
if (!stopHookResult.passed) {
|
|
238
|
+
// Check retry count
|
|
239
|
+
if (isMaxRetriesExceeded(pseudoThreadId)) {
|
|
240
|
+
console.log(chalk.red('\n❌ Stop hooks failed 5+ times. Escalating to user.'));
|
|
241
|
+
} else {
|
|
242
|
+
const retryCount = incrementRetryCount(pseudoThreadId);
|
|
243
|
+
console.log(chalk.yellow(`\n⚠ Stop hooks failed (attempt ${retryCount}/5). Feedback saved.`));
|
|
244
|
+
if (stopHookResult.feedback?.suggestions?.length > 0) {
|
|
245
|
+
stopHookResult.feedback.suggestions.forEach(s => console.log(` → ${s}`));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Record to analytics
|
|
250
|
+
recordEvent({
|
|
251
|
+
type: 'stop_hook_failed_at_checkpoint',
|
|
252
|
+
feature: featureName,
|
|
253
|
+
data: { checkpointNum, retryCount: getRetryCount ? undefined : undefined }
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
} catch {
|
|
257
|
+
// Stop hooks are non-critical — don't block checkpoint if they error
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
passed,
|
|
263
|
+
checkpointNum,
|
|
264
|
+
timestamp: new Date().toISOString(),
|
|
265
|
+
results,
|
|
266
|
+
stopHookResult,
|
|
267
|
+
summary: {
|
|
268
|
+
errors: errorCount,
|
|
269
|
+
warnings: warningCount,
|
|
270
|
+
validatorsRun: results.length
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Check if checkpoint should run based on task count
|
|
277
|
+
* @param {number} tasksCompleted - Number of tasks completed
|
|
278
|
+
* @param {number} frequency - Checkpoint frequency (default: 3)
|
|
279
|
+
* @returns {boolean} True if checkpoint should run
|
|
280
|
+
*/
|
|
281
|
+
export function shouldRunCheckpoint(tasksCompleted, frequency = 3) {
|
|
282
|
+
return tasksCompleted > 0 && tasksCompleted % frequency === 0;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Get checkpoint number from task count
|
|
287
|
+
* @param {number} tasksCompleted - Number of tasks completed
|
|
288
|
+
* @param {number} frequency - Checkpoint frequency (default: 3)
|
|
289
|
+
* @returns {number} Checkpoint number
|
|
290
|
+
*/
|
|
291
|
+
export function getCheckpointNumber(tasksCompleted, frequency = 3) {
|
|
292
|
+
return Math.floor(tasksCompleted / frequency);
|
|
293
|
+
}
|