@polymorphism-tech/morph-spec 4.8.18 → 4.9.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/CLAUDE.md +98 -0
- package/README.md +2 -2
- package/bin/morph-spec.js +15 -56
- package/bin/task-manager.js +115 -14
- package/bin/validate.js +67 -33
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +201 -203
- package/docs/QUICKSTART.md +2 -2
- package/framework/CLAUDE.md +21 -0
- package/framework/agents.json +758 -164
- package/framework/hooks/claude-code/post-tool-use/context-refresh.js +1 -1
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +2 -2
- package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +155 -0
- package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +1 -1
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +71 -2
- package/framework/hooks/claude-code/statusline.py +76 -30
- package/framework/hooks/claude-code/user-prompt/set-terminal-title.js +14 -6
- package/framework/hooks/shared/activity-logger.js +0 -24
- package/framework/hooks/shared/phase-utils.js +3 -0
- package/framework/hooks/shared/skill-reminder-helpers.js +79 -0
- package/framework/hooks/shared/stale-task-reset.js +57 -0
- package/framework/hooks/shared/state-reader.js +2 -2
- package/framework/hooks/shared/worktree-helpers.js +53 -0
- package/framework/phases.json +40 -8
- package/framework/skills/level-0-meta/brainstorming/SKILL.md +1 -1
- package/framework/skills/level-0-meta/code-review/SKILL.md +1 -1
- package/framework/skills/level-0-meta/code-review-nextjs/SKILL.md +163 -163
- package/framework/skills/level-0-meta/frontend-review/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
- package/framework/skills/level-0-meta/morph-init/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +4 -4
- package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +1 -1
- package/framework/skills/level-0-meta/post-implementation/SKILL.md +59 -12
- package/framework/skills/level-0-meta/simulation-checklist/SKILL.md +1 -1
- package/framework/skills/level-0-meta/terminal-title/SKILL.md +1 -1
- package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +1 -1
- package/framework/skills/level-0-meta/tool-usage-guide/references/tools-per-phase.md +6 -5
- package/framework/skills/level-0-meta/verification-before-completion/SKILL.md +1 -1
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +215 -189
- package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +251 -251
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +382 -365
- package/framework/skills/level-1-workflows/phase-implement/SKILL.md +492 -450
- package/framework/skills/level-1-workflows/phase-setup/SKILL.md +194 -190
- package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +270 -270
- package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +285 -285
- package/framework/standards/STANDARDS.json +640 -88
- package/framework/standards/infrastructure/vercel/vercel-database.md +106 -0
- package/framework/templates/REGISTRY.json +1825 -1909
- package/framework/templates/context/CONTEXT-FEATURE.md +276 -276
- package/framework/templates/docs/onboarding.md +1 -5
- package/framework/workflows/configs/nodejs-cli.json +40 -0
- package/package.json +2 -6
- package/src/commands/agents/dispatch-agents.js +55 -4
- package/src/commands/project/doctor.js +16 -47
- package/src/commands/project/init.js +1 -1
- package/src/commands/project/status.js +2 -2
- package/src/commands/project/update.js +381 -365
- package/src/commands/project/worktree.js +154 -0
- package/src/commands/state/advance-phase.js +120 -30
- package/src/commands/state/approve.js +2 -2
- package/src/commands/state/index.js +7 -8
- package/src/commands/state/phase-runner.js +1 -1
- package/src/commands/state/state.js +61 -6
- package/src/commands/tasks/task.js +78 -99
- package/src/commands/templates/template-render.js +93 -173
- package/src/commands/trust/trust.js +26 -21
- package/src/core/paths/output-schema.js +15 -0
- package/src/core/state/state-manager.js +28 -54
- package/src/core/workflows/workflow-detector.js +9 -87
- package/src/lib/phase-chain/phase-validator.js +330 -0
- package/src/lib/stack/stack-profile.js +88 -0
- package/src/lib/tasks/task-classifier.js +16 -0
- package/src/lib/tasks/test-runner.js +77 -0
- package/src/lib/trust/trust-manager.js +32 -144
- package/src/lib/validators/spec-validator.js +58 -4
- package/src/lib/validators/validation-runner.js +23 -11
- package/src/scripts/setup-infra.js +240 -224
- package/src/utils/agents-installer.js +2 -2
- package/src/utils/banner.js +1 -1
- package/src/utils/claude-settings-manager.js +1 -1
- package/src/utils/file-copier.js +1 -0
- package/src/utils/hooks-installer.js +258 -8
- package/framework/hooks/dev/check-sync-health.js +0 -117
- package/framework/hooks/dev/guard-version-numbers.js +0 -57
- package/framework/hooks/dev/sync-standards-registry.js +0 -60
- package/framework/hooks/dev/sync-template-registry.js +0 -60
- package/framework/hooks/dev/validate-skill-format.js +0 -70
- package/framework/hooks/dev/validate-standard-format.js +0 -73
- package/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
- package/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
- package/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
- package/framework/workflows/configs/design-impl.json +0 -49
- package/framework/workflows/configs/express.json +0 -45
- package/framework/workflows/configs/fast-track.json +0 -42
- package/framework/workflows/configs/full-morph.json +0 -79
- package/framework/workflows/configs/fusion.json +0 -39
- package/framework/workflows/configs/long-running.json +0 -33
- package/framework/workflows/configs/spec-only.json +0 -43
- package/framework/workflows/configs/ui-refresh.json +0 -49
- package/framework/workflows/configs/zero-touch.json +0 -82
- package/src/commands/project/monitor.js +0 -295
- package/src/commands/project/tutorial.js +0 -115
- package/src/commands/state/validate-phase.js +0 -238
- package/src/commands/templates/generate-contracts.js +0 -445
- package/src/core/orchestrator.js +0 -171
- package/src/core/registry/command-registry.js +0 -28
- package/src/core/registry/index.js +0 -8
- package/src/core/registry/validator-registry.js +0 -204
- package/src/core/templates/template-validator.js +0 -296
- package/src/generator/config-generator.js +0 -206
- package/src/generator/templates/config.json.template +0 -40
- package/src/generator/templates/project.md.template +0 -67
- package/src/lib/agents/micro-agent-factory.js +0 -161
- package/src/lib/analysis/complexity-analyzer.js +0 -441
- package/src/lib/analysis/index.js +0 -7
- package/src/lib/analytics/analytics-engine.js +0 -345
- package/src/lib/checkpoints/checkpoint-hooks.js +0 -298
- package/src/lib/checkpoints/index.js +0 -7
- package/src/lib/context/context-bundler.js +0 -241
- package/src/lib/context/context-optimizer.js +0 -212
- package/src/lib/context/context-tracker.js +0 -273
- package/src/lib/context/core-four-tracker.js +0 -201
- package/src/lib/context/mcp-optimizer.js +0 -200
- package/src/lib/execution/fusion-executor.js +0 -304
- package/src/lib/execution/parallel-executor.js +0 -270
- package/src/lib/hooks/stop-hook-executor.js +0 -286
- package/src/lib/hops/hop-composer.js +0 -221
- package/src/lib/phase-chain/eligibility-checker.js +0 -243
- package/src/lib/threads/thread-coordinator.js +0 -238
- package/src/lib/threads/thread-manager.js +0 -317
- package/src/lib/tracking/artifact-trail.js +0 -202
- package/src/scanner/project-scanner.js +0 -242
- package/src/ui/diff-display.js +0 -91
- package/src/ui/interactive-wizard.js +0 -96
- package/src/ui/user-review.js +0 -211
- package/src/ui/wizard-questions.js +0 -188
- package/src/utils/color-utils.js +0 -70
- package/src/utils/process-handler.js +0 -97
|
@@ -28,6 +28,9 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
28
28
|
/** Path to agents.json in the installed package */
|
|
29
29
|
const AGENTS_JSON_PATH = join(__dirname, '../../../framework/agents.json');
|
|
30
30
|
|
|
31
|
+
/** Path to phases.json in the installed package */
|
|
32
|
+
const PHASES_JSON_PATH = join(__dirname, '../../../framework/phases.json');
|
|
33
|
+
|
|
31
34
|
/** Phases where agent dispatch is meaningful */
|
|
32
35
|
const DISPATCHABLE_PHASES = ['design', 'tasks', 'implement'];
|
|
33
36
|
|
|
@@ -87,6 +90,40 @@ const TASK_CATEGORY_TO_GROUP = {
|
|
|
87
90
|
'docs': 'docs',
|
|
88
91
|
};
|
|
89
92
|
|
|
93
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
94
|
+
// Required Skills Injection
|
|
95
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Build a mandatory skills block for the given phase.
|
|
99
|
+
* Reads requiredSkills from phases.json data and formats them as instructions for subagents.
|
|
100
|
+
* Returns null if no required skills for this phase.
|
|
101
|
+
*
|
|
102
|
+
* @param {string} phase - Phase id (e.g. 'implement')
|
|
103
|
+
* @param {Object|null} phasesData - Parsed phases.json content
|
|
104
|
+
* @returns {string|null}
|
|
105
|
+
*/
|
|
106
|
+
export function buildSkillsBlock(phase, phasesData) {
|
|
107
|
+
try {
|
|
108
|
+
const skills = phasesData?.phases?.[phase]?.requiredSkills;
|
|
109
|
+
if (!skills || skills.length === 0) return null;
|
|
110
|
+
|
|
111
|
+
const triggerLabel = trigger =>
|
|
112
|
+
trigger.replace(/([A-Z])/g, ' $1').toUpperCase().trim();
|
|
113
|
+
|
|
114
|
+
const lines = skills.map(s => `- ${triggerLabel(s.trigger)}: Invoke Skill(${s.skill})`);
|
|
115
|
+
|
|
116
|
+
return [
|
|
117
|
+
'Mandatory Skills (non-negotiable — invoke at the specified trigger points):',
|
|
118
|
+
...lines,
|
|
119
|
+
'',
|
|
120
|
+
'Do NOT skip these skills. They are required by MORPH-SPEC for this phase.',
|
|
121
|
+
].join('\n');
|
|
122
|
+
} catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
90
127
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
91
128
|
// Helpers
|
|
92
129
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -248,6 +285,17 @@ export async function buildDispatchConfig(projectPath, featureName, phase, opts
|
|
|
248
285
|
const agentsData = JSON.parse(readFileSync(agentsPath, 'utf8'));
|
|
249
286
|
const allAgents = agentsData.agents || {};
|
|
250
287
|
|
|
288
|
+
// Load phases.json for required skills injection (opts.phasesJsonPath allows override for testing)
|
|
289
|
+
const phasesPath = opts.phasesJsonPath || PHASES_JSON_PATH;
|
|
290
|
+
let phasesData = null;
|
|
291
|
+
try {
|
|
292
|
+
if (existsSync(phasesPath)) {
|
|
293
|
+
phasesData = JSON.parse(readFileSync(phasesPath, 'utf8'));
|
|
294
|
+
}
|
|
295
|
+
} catch {
|
|
296
|
+
// Non-blocking — fail silent, skills block will be omitted
|
|
297
|
+
}
|
|
298
|
+
|
|
251
299
|
// Active agents from state (keyword-detected during setup phase)
|
|
252
300
|
const activeAgentIds = new Set(feature.activeAgents || []);
|
|
253
301
|
|
|
@@ -296,11 +344,14 @@ export async function buildDispatchConfig(projectPath, featureName, phase, opts
|
|
|
296
344
|
rawPrompt = agentData.teammate.spawn_prompt;
|
|
297
345
|
}
|
|
298
346
|
|
|
299
|
-
// Append standards digest as Constraints block
|
|
347
|
+
// Append standards digest as Constraints block, then required skills block
|
|
300
348
|
const briefing = buildAgentBriefing(agentId, phase);
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
349
|
+
const skillsBlock = buildSkillsBlock(phase, phasesData);
|
|
350
|
+
const fullTaskPrompt = [
|
|
351
|
+
rawPrompt,
|
|
352
|
+
briefing ? `\n\nConstraints:\n${briefing}` : '',
|
|
353
|
+
skillsBlock ? `\n\n${skillsBlock}` : '',
|
|
354
|
+
].join('');
|
|
304
355
|
|
|
305
356
|
dispatchableAgents.push({
|
|
306
357
|
id: agentId,
|
|
@@ -67,20 +67,6 @@ function getNpmGlobalPrefix() {
|
|
|
67
67
|
|
|
68
68
|
// lib files
|
|
69
69
|
const REQUIRED_LIB_FILES = [
|
|
70
|
-
'src/lib/analytics/analytics-engine.js',
|
|
71
|
-
'src/lib/tracking/artifact-trail.js',
|
|
72
|
-
'src/lib/context/context-bundler.js',
|
|
73
|
-
'src/lib/context/context-optimizer.js',
|
|
74
|
-
'src/lib/context/context-tracker.js',
|
|
75
|
-
'src/lib/context/core-four-tracker.js',
|
|
76
|
-
'src/lib/execution/fusion-executor.js',
|
|
77
|
-
'src/lib/hops/hop-composer.js',
|
|
78
|
-
'src/lib/context/mcp-optimizer.js',
|
|
79
|
-
'src/lib/agents/micro-agent-factory.js',
|
|
80
|
-
'src/lib/execution/parallel-executor.js',
|
|
81
|
-
'src/lib/hooks/stop-hook-executor.js', // Legacy — retained for backward compat
|
|
82
|
-
'src/lib/threads/thread-coordinator.js',
|
|
83
|
-
'src/lib/threads/thread-manager.js',
|
|
84
70
|
'src/lib/trust/trust-manager.js'
|
|
85
71
|
];
|
|
86
72
|
|
|
@@ -90,7 +76,6 @@ const REQUIRED_COMMAND_FILES = [
|
|
|
90
76
|
'src/commands/project/update.js',
|
|
91
77
|
'src/commands/project/doctor.js',
|
|
92
78
|
'src/commands/project/status.js',
|
|
93
|
-
'src/commands/project/tutorial.js',
|
|
94
79
|
'src/commands/state/state.js',
|
|
95
80
|
'src/commands/state/advance-phase.js',
|
|
96
81
|
'src/commands/state/approve.js',
|
|
@@ -99,23 +84,7 @@ const REQUIRED_COMMAND_FILES = [
|
|
|
99
84
|
'src/commands/validation/validate-feature.js',
|
|
100
85
|
'src/commands/templates/template-render.js',
|
|
101
86
|
'src/commands/agents/dispatch-agents.js',
|
|
102
|
-
'src/commands/
|
|
103
|
-
];
|
|
104
|
-
|
|
105
|
-
// HOP templates (meta-prompts)
|
|
106
|
-
const HOP_TEMPLATES = [
|
|
107
|
-
'framework/templates/meta-prompts/squad-leaders/backend-squad.md',
|
|
108
|
-
'framework/templates/meta-prompts/squad-leaders/frontend-squad.md',
|
|
109
|
-
'framework/templates/meta-prompts/parallel-workers/parallel-worker.md',
|
|
110
|
-
'framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md',
|
|
111
|
-
'framework/templates/meta-prompts/hops/hop-wrapper.md',
|
|
112
|
-
'framework/templates/meta-prompts/hops/hop-retry.md',
|
|
113
|
-
'framework/templates/meta-prompts/hops/hop-validation.md',
|
|
114
|
-
'framework/templates/meta-prompts/validators/checkpoint-validator.md',
|
|
115
|
-
'framework/templates/meta-prompts/validators/pre-commit-validator.md',
|
|
116
|
-
'framework/templates/meta-prompts/fusion/fusion-agent.md',
|
|
117
|
-
'framework/templates/meta-prompts/fusion/fusion-aggregator.md',
|
|
118
|
-
'framework/templates/REGISTRY.json'
|
|
87
|
+
'src/commands/project/worktree.js'
|
|
119
88
|
];
|
|
120
89
|
|
|
121
90
|
// framework standards
|
|
@@ -195,17 +164,7 @@ async function doctorFullCommand(frameworkRoot) {
|
|
|
195
164
|
missingCmds.length === 0, false,
|
|
196
165
|
missingCmds.length > 0 ? `missing: ${missingCmds.join(', ')}` : '');
|
|
197
166
|
|
|
198
|
-
// ── 3.
|
|
199
|
-
console.log(chalk.cyan(`\n framework/templates/meta-prompts/ — HOP Templates (${HOP_TEMPLATES.length})`));
|
|
200
|
-
const missingHOPs = [];
|
|
201
|
-
for (const f of HOP_TEMPLATES) {
|
|
202
|
-
if (!(await pathExists(join(frameworkRoot, f)))) missingHOPs.push(f.split('/').pop());
|
|
203
|
-
}
|
|
204
|
-
check(`HOP Templates (${HOP_TEMPLATES.length - missingHOPs.length}/${HOP_TEMPLATES.length})`,
|
|
205
|
-
missingHOPs.length === 0, false,
|
|
206
|
-
missingHOPs.length > 0 ? `missing: ${missingHOPs.join(', ')}` : '');
|
|
207
|
-
|
|
208
|
-
// ── 4. Framework Standards ───────────────────────────────────────────────
|
|
167
|
+
// ── 3. Framework Standards ───────────────────────────────────────────────
|
|
209
168
|
console.log(chalk.cyan(`\n framework/standards/ — Framework Standards (${FRAMEWORK_STANDARDS.length} files)`));
|
|
210
169
|
const missingStds = [];
|
|
211
170
|
for (const f of FRAMEWORK_STANDARDS) {
|
|
@@ -233,10 +192,10 @@ async function doctorFullCommand(frameworkRoot) {
|
|
|
233
192
|
check('agents.json', false, false, 'file not found');
|
|
234
193
|
}
|
|
235
194
|
|
|
236
|
-
// ── 7.
|
|
237
|
-
console.log(chalk.cyan('\n framework/workflows/ —
|
|
238
|
-
const
|
|
239
|
-
check('
|
|
195
|
+
// ── 7. Workflow Configs ──────────────────────────────────────────────────
|
|
196
|
+
console.log(chalk.cyan('\n framework/workflows/ — Workflow Configs'));
|
|
197
|
+
const stdPath = join(frameworkRoot, 'framework/workflows/configs/standard.json');
|
|
198
|
+
check('standard.json workflow config', await pathExists(stdPath));
|
|
240
199
|
|
|
241
200
|
// ── 8. state.json schema version ────────────────────────────────────────
|
|
242
201
|
console.log(chalk.cyan('\n .morph/state.json — Schema Version'));
|
|
@@ -454,6 +413,16 @@ export async function doctorCommand(options = {}) {
|
|
|
454
413
|
let hasErrors = false;
|
|
455
414
|
let hasWarnings = false;
|
|
456
415
|
|
|
416
|
+
const check = (name, passed, warnOnly = false, msg = '') => {
|
|
417
|
+
if (passed) {
|
|
418
|
+
checks.push({ name, status: 'ok' });
|
|
419
|
+
} else {
|
|
420
|
+
checks.push({ name, status: warnOnly ? 'warn' : 'missing', msg });
|
|
421
|
+
if (warnOnly) hasWarnings = true;
|
|
422
|
+
else hasErrors = true;
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
|
|
457
426
|
// Check versions first
|
|
458
427
|
const cliCheck = await checkCLIOutdated();
|
|
459
428
|
const projectCheck = await checkProjectOutdated(targetPath);
|
|
@@ -385,7 +385,7 @@ export async function initCommand(options) {
|
|
|
385
385
|
// Suggest tutorial for first-time users
|
|
386
386
|
if (integrationsCreated) {
|
|
387
387
|
logger.blank();
|
|
388
|
-
logger.info('First time using morph-spec? Run
|
|
388
|
+
logger.info('First time using morph-spec? Run `/morph-proposal <feature>` to start a new feature.');
|
|
389
389
|
}
|
|
390
390
|
|
|
391
391
|
logger.blank();
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import chalk from 'chalk';
|
|
16
16
|
import { loadState, getFeature, derivePhase, deriveOutputs } from '../../core/state/state-manager.js';
|
|
17
|
-
import { PHASES } from '
|
|
17
|
+
import { PHASES } from '../../lib/phase-chain/phase-validator.js';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Phase symbols for visual representation
|
|
@@ -243,7 +243,7 @@ export async function statusCommand(featureName, options = {}) {
|
|
|
243
243
|
process.exit(1);
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
// Derive phase and outputs from filesystem if not stored in state
|
|
246
|
+
// Derive phase and outputs from filesystem if not stored in state
|
|
247
247
|
const { join } = await import('path');
|
|
248
248
|
const featurePath = join(process.cwd(), '.morph', 'features', featureName);
|
|
249
249
|
if (!feature.phase) {
|