@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.
Files changed (138) hide show
  1. package/CLAUDE.md +98 -0
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +15 -56
  4. package/bin/task-manager.js +115 -14
  5. package/bin/validate.js +67 -33
  6. package/claude-plugin.json +1 -1
  7. package/docs/CHEATSHEET.md +201 -203
  8. package/docs/QUICKSTART.md +2 -2
  9. package/framework/CLAUDE.md +21 -0
  10. package/framework/agents.json +758 -164
  11. package/framework/hooks/claude-code/post-tool-use/context-refresh.js +1 -1
  12. package/framework/hooks/claude-code/post-tool-use/dispatch.js +2 -2
  13. package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +155 -0
  14. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +1 -1
  15. package/framework/hooks/claude-code/session-start/inject-morph-context.js +71 -2
  16. package/framework/hooks/claude-code/statusline.py +76 -30
  17. package/framework/hooks/claude-code/user-prompt/set-terminal-title.js +14 -6
  18. package/framework/hooks/shared/activity-logger.js +0 -24
  19. package/framework/hooks/shared/phase-utils.js +3 -0
  20. package/framework/hooks/shared/skill-reminder-helpers.js +79 -0
  21. package/framework/hooks/shared/stale-task-reset.js +57 -0
  22. package/framework/hooks/shared/state-reader.js +2 -2
  23. package/framework/hooks/shared/worktree-helpers.js +53 -0
  24. package/framework/phases.json +40 -8
  25. package/framework/skills/level-0-meta/brainstorming/SKILL.md +1 -1
  26. package/framework/skills/level-0-meta/code-review/SKILL.md +1 -1
  27. package/framework/skills/level-0-meta/code-review-nextjs/SKILL.md +163 -163
  28. package/framework/skills/level-0-meta/frontend-review/SKILL.md +5 -5
  29. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
  30. package/framework/skills/level-0-meta/morph-init/SKILL.md +5 -5
  31. package/framework/skills/level-0-meta/morph-replicate/SKILL.md +4 -4
  32. package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +1 -1
  33. package/framework/skills/level-0-meta/post-implementation/SKILL.md +59 -12
  34. package/framework/skills/level-0-meta/simulation-checklist/SKILL.md +1 -1
  35. package/framework/skills/level-0-meta/terminal-title/SKILL.md +1 -1
  36. package/framework/skills/level-0-meta/tool-usage-guide/SKILL.md +1 -1
  37. package/framework/skills/level-0-meta/tool-usage-guide/references/tools-per-phase.md +6 -5
  38. package/framework/skills/level-0-meta/verification-before-completion/SKILL.md +1 -1
  39. package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +215 -189
  40. package/framework/skills/level-1-workflows/phase-codebase-analysis/SKILL.md +251 -251
  41. package/framework/skills/level-1-workflows/phase-design/SKILL.md +382 -365
  42. package/framework/skills/level-1-workflows/phase-implement/SKILL.md +492 -450
  43. package/framework/skills/level-1-workflows/phase-setup/SKILL.md +194 -190
  44. package/framework/skills/level-1-workflows/phase-tasks/SKILL.md +270 -270
  45. package/framework/skills/level-1-workflows/phase-uiux/SKILL.md +285 -285
  46. package/framework/standards/STANDARDS.json +640 -88
  47. package/framework/standards/infrastructure/vercel/vercel-database.md +106 -0
  48. package/framework/templates/REGISTRY.json +1825 -1909
  49. package/framework/templates/context/CONTEXT-FEATURE.md +276 -276
  50. package/framework/templates/docs/onboarding.md +1 -5
  51. package/framework/workflows/configs/nodejs-cli.json +40 -0
  52. package/package.json +2 -6
  53. package/src/commands/agents/dispatch-agents.js +55 -4
  54. package/src/commands/project/doctor.js +16 -47
  55. package/src/commands/project/init.js +1 -1
  56. package/src/commands/project/status.js +2 -2
  57. package/src/commands/project/update.js +381 -365
  58. package/src/commands/project/worktree.js +154 -0
  59. package/src/commands/state/advance-phase.js +120 -30
  60. package/src/commands/state/approve.js +2 -2
  61. package/src/commands/state/index.js +7 -8
  62. package/src/commands/state/phase-runner.js +1 -1
  63. package/src/commands/state/state.js +61 -6
  64. package/src/commands/tasks/task.js +78 -99
  65. package/src/commands/templates/template-render.js +93 -173
  66. package/src/commands/trust/trust.js +26 -21
  67. package/src/core/paths/output-schema.js +15 -0
  68. package/src/core/state/state-manager.js +28 -54
  69. package/src/core/workflows/workflow-detector.js +9 -87
  70. package/src/lib/phase-chain/phase-validator.js +330 -0
  71. package/src/lib/stack/stack-profile.js +88 -0
  72. package/src/lib/tasks/task-classifier.js +16 -0
  73. package/src/lib/tasks/test-runner.js +77 -0
  74. package/src/lib/trust/trust-manager.js +32 -144
  75. package/src/lib/validators/spec-validator.js +58 -4
  76. package/src/lib/validators/validation-runner.js +23 -11
  77. package/src/scripts/setup-infra.js +240 -224
  78. package/src/utils/agents-installer.js +2 -2
  79. package/src/utils/banner.js +1 -1
  80. package/src/utils/claude-settings-manager.js +1 -1
  81. package/src/utils/file-copier.js +1 -0
  82. package/src/utils/hooks-installer.js +258 -8
  83. package/framework/hooks/dev/check-sync-health.js +0 -117
  84. package/framework/hooks/dev/guard-version-numbers.js +0 -57
  85. package/framework/hooks/dev/sync-standards-registry.js +0 -60
  86. package/framework/hooks/dev/sync-template-registry.js +0 -60
  87. package/framework/hooks/dev/validate-skill-format.js +0 -70
  88. package/framework/hooks/dev/validate-standard-format.js +0 -73
  89. package/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
  90. package/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
  91. package/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
  92. package/framework/workflows/configs/design-impl.json +0 -49
  93. package/framework/workflows/configs/express.json +0 -45
  94. package/framework/workflows/configs/fast-track.json +0 -42
  95. package/framework/workflows/configs/full-morph.json +0 -79
  96. package/framework/workflows/configs/fusion.json +0 -39
  97. package/framework/workflows/configs/long-running.json +0 -33
  98. package/framework/workflows/configs/spec-only.json +0 -43
  99. package/framework/workflows/configs/ui-refresh.json +0 -49
  100. package/framework/workflows/configs/zero-touch.json +0 -82
  101. package/src/commands/project/monitor.js +0 -295
  102. package/src/commands/project/tutorial.js +0 -115
  103. package/src/commands/state/validate-phase.js +0 -238
  104. package/src/commands/templates/generate-contracts.js +0 -445
  105. package/src/core/orchestrator.js +0 -171
  106. package/src/core/registry/command-registry.js +0 -28
  107. package/src/core/registry/index.js +0 -8
  108. package/src/core/registry/validator-registry.js +0 -204
  109. package/src/core/templates/template-validator.js +0 -296
  110. package/src/generator/config-generator.js +0 -206
  111. package/src/generator/templates/config.json.template +0 -40
  112. package/src/generator/templates/project.md.template +0 -67
  113. package/src/lib/agents/micro-agent-factory.js +0 -161
  114. package/src/lib/analysis/complexity-analyzer.js +0 -441
  115. package/src/lib/analysis/index.js +0 -7
  116. package/src/lib/analytics/analytics-engine.js +0 -345
  117. package/src/lib/checkpoints/checkpoint-hooks.js +0 -298
  118. package/src/lib/checkpoints/index.js +0 -7
  119. package/src/lib/context/context-bundler.js +0 -241
  120. package/src/lib/context/context-optimizer.js +0 -212
  121. package/src/lib/context/context-tracker.js +0 -273
  122. package/src/lib/context/core-four-tracker.js +0 -201
  123. package/src/lib/context/mcp-optimizer.js +0 -200
  124. package/src/lib/execution/fusion-executor.js +0 -304
  125. package/src/lib/execution/parallel-executor.js +0 -270
  126. package/src/lib/hooks/stop-hook-executor.js +0 -286
  127. package/src/lib/hops/hop-composer.js +0 -221
  128. package/src/lib/phase-chain/eligibility-checker.js +0 -243
  129. package/src/lib/threads/thread-coordinator.js +0 -238
  130. package/src/lib/threads/thread-manager.js +0 -317
  131. package/src/lib/tracking/artifact-trail.js +0 -202
  132. package/src/scanner/project-scanner.js +0 -242
  133. package/src/ui/diff-display.js +0 -91
  134. package/src/ui/interactive-wizard.js +0 -96
  135. package/src/ui/user-review.js +0 -211
  136. package/src/ui/wizard-questions.js +0 -188
  137. package/src/utils/color-utils.js +0 -70
  138. 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 fullTaskPrompt = briefing
302
- ? `${rawPrompt}\n\nConstraints:\n${briefing}`
303
- : rawPrompt;
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/templates/generate-contracts.js'
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. HOP Templates ────────────────────────────────────────────────────
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. Zero-Touch Workflow Config ───────────────────────────────────────
237
- console.log(chalk.cyan('\n framework/workflows/ — Zero-Touch Config'));
238
- const ztPath = join(frameworkRoot, 'framework/workflows/configs/zero-touch.json');
239
- check('zero-touch.json workflow config', await pathExists(ztPath));
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 `morph-spec tutorial` to get started.');
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 '../state/validate-phase.js';
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 (v5.0.0+)
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) {