@polymorphism-tech/morph-spec 4.8.19 → 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 (137) hide show
  1. package/CLAUDE.md +21 -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 +698 -176
  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/package.json +2 -6
  52. package/src/commands/agents/dispatch-agents.js +55 -4
  53. package/src/commands/project/doctor.js +16 -47
  54. package/src/commands/project/init.js +1 -1
  55. package/src/commands/project/status.js +2 -2
  56. package/src/commands/project/update.js +381 -365
  57. package/src/commands/project/worktree.js +154 -0
  58. package/src/commands/state/advance-phase.js +120 -30
  59. package/src/commands/state/approve.js +2 -2
  60. package/src/commands/state/index.js +7 -8
  61. package/src/commands/state/phase-runner.js +1 -1
  62. package/src/commands/state/state.js +61 -6
  63. package/src/commands/tasks/task.js +78 -99
  64. package/src/commands/templates/template-render.js +93 -173
  65. package/src/commands/trust/trust.js +26 -21
  66. package/src/core/paths/output-schema.js +15 -0
  67. package/src/core/state/state-manager.js +28 -54
  68. package/src/core/workflows/workflow-detector.js +9 -87
  69. package/src/lib/phase-chain/phase-validator.js +330 -0
  70. package/src/lib/stack/stack-profile.js +88 -0
  71. package/src/lib/tasks/task-classifier.js +16 -0
  72. package/src/lib/tasks/test-runner.js +77 -0
  73. package/src/lib/trust/trust-manager.js +32 -144
  74. package/src/lib/validators/spec-validator.js +58 -4
  75. package/src/lib/validators/validation-runner.js +23 -11
  76. package/src/scripts/setup-infra.js +240 -224
  77. package/src/utils/agents-installer.js +2 -2
  78. package/src/utils/banner.js +1 -1
  79. package/src/utils/claude-settings-manager.js +1 -1
  80. package/src/utils/file-copier.js +1 -0
  81. package/src/utils/hooks-installer.js +258 -8
  82. package/framework/hooks/dev/check-sync-health.js +0 -117
  83. package/framework/hooks/dev/guard-version-numbers.js +0 -57
  84. package/framework/hooks/dev/sync-standards-registry.js +0 -60
  85. package/framework/hooks/dev/sync-template-registry.js +0 -60
  86. package/framework/hooks/dev/validate-skill-format.js +0 -70
  87. package/framework/hooks/dev/validate-standard-format.js +0 -73
  88. package/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
  89. package/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
  90. package/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
  91. package/framework/workflows/configs/design-impl.json +0 -49
  92. package/framework/workflows/configs/express.json +0 -45
  93. package/framework/workflows/configs/fast-track.json +0 -42
  94. package/framework/workflows/configs/full-morph.json +0 -79
  95. package/framework/workflows/configs/fusion.json +0 -39
  96. package/framework/workflows/configs/long-running.json +0 -33
  97. package/framework/workflows/configs/spec-only.json +0 -43
  98. package/framework/workflows/configs/ui-refresh.json +0 -49
  99. package/framework/workflows/configs/zero-touch.json +0 -82
  100. package/src/commands/project/monitor.js +0 -295
  101. package/src/commands/project/tutorial.js +0 -115
  102. package/src/commands/state/validate-phase.js +0 -238
  103. package/src/commands/templates/generate-contracts.js +0 -445
  104. package/src/core/orchestrator.js +0 -171
  105. package/src/core/registry/command-registry.js +0 -28
  106. package/src/core/registry/index.js +0 -8
  107. package/src/core/registry/validator-registry.js +0 -204
  108. package/src/core/templates/template-validator.js +0 -296
  109. package/src/generator/config-generator.js +0 -206
  110. package/src/generator/templates/config.json.template +0 -40
  111. package/src/generator/templates/project.md.template +0 -67
  112. package/src/lib/agents/micro-agent-factory.js +0 -161
  113. package/src/lib/analysis/complexity-analyzer.js +0 -441
  114. package/src/lib/analysis/index.js +0 -7
  115. package/src/lib/analytics/analytics-engine.js +0 -345
  116. package/src/lib/checkpoints/checkpoint-hooks.js +0 -298
  117. package/src/lib/checkpoints/index.js +0 -7
  118. package/src/lib/context/context-bundler.js +0 -241
  119. package/src/lib/context/context-optimizer.js +0 -212
  120. package/src/lib/context/context-tracker.js +0 -273
  121. package/src/lib/context/core-four-tracker.js +0 -201
  122. package/src/lib/context/mcp-optimizer.js +0 -200
  123. package/src/lib/execution/fusion-executor.js +0 -304
  124. package/src/lib/execution/parallel-executor.js +0 -270
  125. package/src/lib/hooks/stop-hook-executor.js +0 -286
  126. package/src/lib/hops/hop-composer.js +0 -221
  127. package/src/lib/phase-chain/eligibility-checker.js +0 -243
  128. package/src/lib/threads/thread-coordinator.js +0 -238
  129. package/src/lib/threads/thread-manager.js +0 -317
  130. package/src/lib/tracking/artifact-trail.js +0 -202
  131. package/src/scanner/project-scanner.js +0 -242
  132. package/src/ui/diff-display.js +0 -91
  133. package/src/ui/interactive-wizard.js +0 -96
  134. package/src/ui/user-review.js +0 -211
  135. package/src/ui/wizard-questions.js +0 -188
  136. package/src/utils/color-utils.js +0 -70
  137. package/src/utils/process-handler.js +0 -97
@@ -1,82 +0,0 @@
1
- {
2
- "id": "zero-touch",
3
- "name": "Zero-Touch Execution",
4
- "description": "Fully autonomous execution with auto-approval gates. Requires maximum trust level (>95% checkpoint pass rate).",
5
- "version": "3.0.0",
6
-
7
- "eligibility": {
8
- "trustLevel": "maximum",
9
- "minCheckpoints": 10,
10
- "minPassRate": 0.95,
11
- "requiredPhases": ["proposal", "design", "tasks"],
12
- "blockedIfHas": ["manual_override_pending", "escalation_required"]
13
- },
14
-
15
- "autoApproval": {
16
- "design": true,
17
- "tasks": true,
18
- "proposal": true,
19
- "enabled": true,
20
- "auditLog": true
21
- },
22
-
23
- "autoCommit": {
24
- "enabled": true,
25
- "convention": "conventional-commits",
26
- "signOff": "morph-spec-agent",
27
- "requirePassingCheckpoints": true
28
- },
29
-
30
- "rollback": {
31
- "enabled": true,
32
- "onCheckpointFailure": true,
33
- "strategy": "git-revert",
34
- "maxRollbackDepth": 3
35
- },
36
-
37
- "escalation": {
38
- "triggers": [
39
- "checkpoint_failed_3_times",
40
- "architecture_error",
41
- "security_error",
42
- "circular_dependency_detected",
43
- "out_of_scope_change"
44
- ],
45
- "action": "pause_and_notify"
46
- },
47
-
48
- "phases": {
49
- "run": ["proposal", "design", "clarify", "tasks", "implement", "sync"],
50
- "skip": ["uiux"],
51
- "pauses": []
52
- },
53
-
54
- "monitoring": {
55
- "checkpointFrequency": 3,
56
- "stopHooks": {
57
- "enabled": true,
58
- "interval": 30,
59
- "hooks": ["validate-and-continue", "validate-checkpoints"]
60
- },
61
- "analyticsTracking": true
62
- },
63
-
64
- "restrictions": {
65
- "maxFilesPerSession": 50,
66
- "noInfraChanges": false,
67
- "noDatabaseMigrations": false,
68
- "requireHumanForBreakingChanges": true,
69
- "requireHumanForSchemaChanges": false
70
- },
71
-
72
- "phaseChain": {
73
- "enabled": true,
74
- "pauseOn": ["blocked_tasks", "escalation_required", "low_pass_rate"],
75
- "continueOn": ["missing_optional_outputs"],
76
- "maxAutoPhases": 6
77
- },
78
-
79
- "keywords": ["zero-touch", "autonomous", "fully automated", "hands-off", "auto-pilot"],
80
-
81
- "priority": 5
82
- }
@@ -1,295 +0,0 @@
1
- /**
2
- * morph-spec monitor — Live TUI Dashboard
3
- *
4
- * Opens a live-updating terminal UI showing:
5
- * - Active agents by tier
6
- * - Hook events (chronological feed)
7
- * - Skills invoked this session
8
- * - Rules in effect
9
- * - Overview summary
10
- *
11
- * Reads .morph/logs/activity.json (written by hooks via activity-logger.js).
12
- * Uses fs.watch for live updates (no polling, no chokidar).
13
- *
14
- * Usage:
15
- * morph-spec monitor [feature]
16
- * morph-spec monitor --compact
17
- * morph-spec monitor --mode hooks
18
- */
19
-
20
- import { watch, existsSync, readFileSync, readdirSync, statSync } from 'fs';
21
- import { join, basename } from 'path';
22
- import chalk from 'chalk';
23
-
24
- import {
25
- renderBox,
26
- renderFeed,
27
- renderAgents,
28
- renderSkills,
29
- renderRules,
30
- renderOverview,
31
- renderStatusBar,
32
- renderHeader,
33
- } from '../../lib/monitor/renderer.js';
34
-
35
- import { getActiveAgents } from '../../lib/monitor/agent-resolver.js';
36
- import { readActivity } from '../../../framework/hooks/shared/activity-logger.js';
37
- import { loadState, getActiveFeature, derivePhaseForFeature } from '../../../framework/hooks/shared/state-reader.js';
38
-
39
- const MODES = ['overview', 'hooks', 'agents', 'skills', 'rules'];
40
- const ACTIVITY_FILE = '.morph/logs/activity.json';
41
- const RULES_DIR_PROJECT = '.claude/rules';
42
- const RULES_DIR_FRAMEWORK = '.morph/framework/rules';
43
-
44
- // ─────────────────────────────────────────────────────────
45
- // Rules loading
46
- // ─────────────────────────────────────────────────────────
47
-
48
- function loadRules(cwd) {
49
- const rules = [];
50
- const dirs = [
51
- join(cwd, RULES_DIR_PROJECT),
52
- join(cwd, RULES_DIR_FRAMEWORK),
53
- join(cwd, 'framework/rules'),
54
- ];
55
-
56
- for (const dir of dirs) {
57
- if (!existsSync(dir)) continue;
58
- try {
59
- const files = readdirSync(dir).filter(f => f.endsWith('.md'));
60
- for (const file of files) {
61
- // Parse front-matter paths glob if present
62
- let glob = '*';
63
- try {
64
- const content = readFileSync(join(dir, file), 'utf-8');
65
- const match = content.match(/paths:\s*\n((?:\s*-\s*.+\n?)+)/);
66
- if (match) {
67
- const paths = match[1].match(/- (.+)/g);
68
- if (paths) glob = paths.map(p => p.replace('- ', '').trim()).join(', ');
69
- }
70
- } catch { /* skip */ }
71
- rules.push({ name: basename(file, '.md'), glob });
72
- }
73
- } catch { /* skip */ }
74
- }
75
- return rules;
76
- }
77
-
78
- // ─────────────────────────────────────────────────────────
79
- // Available skills loading
80
- // ─────────────────────────────────────────────────────────
81
-
82
- function loadAvailableSkills(cwd) {
83
- const skillDirs = [
84
- join(cwd, '.claude/skills'),
85
- join(cwd, 'framework/skills'),
86
- ];
87
- const names = [];
88
- for (const dir of skillDirs) {
89
- if (!existsSync(dir)) continue;
90
- try {
91
- const entries = readdirSync(dir, { withFileTypes: true });
92
- for (const entry of entries) {
93
- if (entry.isDirectory()) {
94
- // Level-N-meta/skill-name or direct skill dirs
95
- const sub = readdirSync(join(dir, entry.name), { withFileTypes: true });
96
- for (const s of sub) {
97
- if (s.isDirectory()) names.push(s.name);
98
- }
99
- }
100
- }
101
- } catch { /* skip */ }
102
- }
103
- return [...new Set(names)];
104
- }
105
-
106
- // ─────────────────────────────────────────────────────────
107
- // Screen rendering
108
- // ─────────────────────────────────────────────────────────
109
-
110
- function render(state) {
111
- const { feature, phase, tasks, agentsByTier, activity, rules, availableSkills, mode, compact } = state;
112
-
113
- const hooks = activity?.hooks || [];
114
- const skills = activity?.skills || [];
115
-
116
- // Clear screen
117
- process.stdout.write('\x1Bc');
118
-
119
- // Header
120
- process.stdout.write(renderHeader(feature, phase, tasks) + '\n');
121
-
122
- if (compact) {
123
- // Compact: just show overview
124
- const overviewData = { feature, phase, agentsByTier, hooks, skills, rules };
125
- process.stdout.write(renderOverview(overviewData) + '\n');
126
- } else {
127
- switch (mode) {
128
- case 'hooks':
129
- process.stdout.write(renderFeed(hooks) + '\n');
130
- break;
131
-
132
- case 'agents':
133
- process.stdout.write(renderAgents(agentsByTier, phase) + '\n');
134
- break;
135
-
136
- case 'skills':
137
- process.stdout.write(renderSkills(skills, availableSkills) + '\n');
138
- break;
139
-
140
- case 'rules':
141
- process.stdout.write(renderRules(rules) + '\n');
142
- break;
143
-
144
- case 'overview':
145
- default: {
146
- const overviewData = { feature, phase, agentsByTier, hooks, skills, rules };
147
- process.stdout.write(renderOverview(overviewData) + '\n');
148
- break;
149
- }
150
- }
151
- }
152
-
153
- // Status bar
154
- process.stdout.write(renderStatusBar(mode, MODES) + '\n');
155
- }
156
-
157
- // ─────────────────────────────────────────────────────────
158
- // State loading
159
- // ─────────────────────────────────────────────────────────
160
-
161
- function loadMonitorState(cwd, featureArg) {
162
- let feature = featureArg || '';
163
- let phase = '';
164
- let tasks = null;
165
-
166
- try {
167
- const morphState = loadState(cwd);
168
- if (!feature && morphState) {
169
- const active = getActiveFeature(cwd);
170
- if (active) {
171
- feature = active.name;
172
- tasks = active.feature.tasks || null;
173
- }
174
- }
175
- if (feature) {
176
- phase = derivePhaseForFeature(feature, cwd);
177
- }
178
- } catch { /* fail-open */ }
179
-
180
- const agentsByTier = getActiveAgents(cwd, phase);
181
- const activity = readActivity(cwd);
182
- const rules = loadRules(cwd);
183
- const availableSkills = loadAvailableSkills(cwd);
184
-
185
- return { feature, phase, tasks, agentsByTier, activity, rules, availableSkills };
186
- }
187
-
188
- // ─────────────────────────────────────────────────────────
189
- // Main command
190
- // ─────────────────────────────────────────────────────────
191
-
192
- /**
193
- * @param {string|undefined} featureArg
194
- * @param {{ compact: boolean, mode: string }} opts
195
- */
196
- export function monitorCommand(featureArg, opts = {}) {
197
- const cwd = process.cwd();
198
- const compact = !!opts.compact;
199
- const startMode = MODES.includes(opts.mode) ? opts.mode : 'overview';
200
-
201
- let modeIndex = MODES.indexOf(startMode);
202
- let currentMode = startMode;
203
-
204
- // Initial render
205
- let monitorState = loadMonitorState(cwd, featureArg);
206
- render({ ...monitorState, mode: currentMode, compact });
207
-
208
- // Watch activity.json for changes
209
- const activityPath = join(cwd, ACTIVITY_FILE);
210
- let watcher = null;
211
-
212
- function startWatcher() {
213
- if (!existsSync(activityPath)) {
214
- // Retry watch setup when file is created
215
- setTimeout(startWatcher, 2000);
216
- return;
217
- }
218
-
219
- try {
220
- watcher = watch(activityPath, { persistent: true }, () => {
221
- try {
222
- monitorState = loadMonitorState(cwd, featureArg);
223
- render({ ...monitorState, mode: currentMode, compact });
224
- } catch { /* fail-open */ }
225
- });
226
- } catch {
227
- // fs.watch not supported — fall back to polling
228
- setInterval(() => {
229
- try {
230
- monitorState = loadMonitorState(cwd, featureArg);
231
- render({ ...monitorState, mode: currentMode, compact });
232
- } catch { /* fail-open */ }
233
- }, 2000);
234
- }
235
- }
236
-
237
- startWatcher();
238
-
239
- // Keyboard input: raw mode
240
- if (process.stdin.isTTY) {
241
- process.stdin.setRawMode(true);
242
- process.stdin.resume();
243
- process.stdin.setEncoding('utf8');
244
-
245
- process.stdin.on('data', (key) => {
246
- // q or Ctrl-C → quit
247
- if (key === 'q' || key === '\u0003') {
248
- if (watcher) watcher.close();
249
- process.stdin.setRawMode(false);
250
- process.stdout.write('\n' + chalk.gray('morph-spec monitor closed.\n'));
251
- process.exit(0);
252
- }
253
-
254
- // shift+tab → cycle modes (forward)
255
- // \x1b[Z is the standard escape for shift+tab
256
- if (key === '\x1b[Z' || key === '\t') {
257
- modeIndex = (modeIndex + 1) % MODES.length;
258
- currentMode = MODES[modeIndex];
259
- render({ ...monitorState, mode: currentMode, compact });
260
- }
261
-
262
- // Arrow keys: left/right also cycle
263
- if (key === '\x1b[C') { // right arrow
264
- modeIndex = (modeIndex + 1) % MODES.length;
265
- currentMode = MODES[modeIndex];
266
- render({ ...monitorState, mode: currentMode, compact });
267
- }
268
- if (key === '\x1b[D') { // left arrow
269
- modeIndex = (modeIndex - 1 + MODES.length) % MODES.length;
270
- currentMode = MODES[modeIndex];
271
- render({ ...monitorState, mode: currentMode, compact });
272
- }
273
-
274
- // r → force refresh
275
- if (key === 'r') {
276
- monitorState = loadMonitorState(cwd, featureArg);
277
- render({ ...monitorState, mode: currentMode, compact });
278
- }
279
- });
280
- } else {
281
- // Non-TTY: just render once and exit (useful for scripting/piping)
282
- process.stdout.write('\n' + chalk.gray('(non-interactive mode — run in a real terminal for live updates)\n'));
283
- }
284
-
285
- // Handle process signals
286
- process.on('SIGINT', () => {
287
- if (watcher) watcher.close();
288
- process.stdout.write('\n' + chalk.gray('morph-spec monitor closed.\n'));
289
- process.exit(0);
290
- });
291
- process.on('SIGTERM', () => {
292
- if (watcher) watcher.close();
293
- process.exit(0);
294
- });
295
- }
@@ -1,115 +0,0 @@
1
- /**
2
- * Tutorial Command
3
- *
4
- * Prints the MORPH-SPEC workflow pipeline and getting-started steps.
5
- * Pure stdout — no file I/O, no network, no side effects.
6
- *
7
- * Usage: morph-spec tutorial
8
- */
9
-
10
- import chalk from 'chalk';
11
-
12
- const PHASES = [
13
- {
14
- label: 'FASE 0 · PROPOSAL',
15
- what: 'Captures user story + acceptance criteria.',
16
- produces: '0-proposal/proposal.md',
17
- how: '/morph-proposal <feature> (in Claude Code)',
18
- },
19
- {
20
- label: 'FASE 1 · SETUP',
21
- what: 'Detects stack, activates agents, confirms environment.',
22
- produces: '.morph/state.json initialized',
23
- how: 'auto-triggered inside /morph-proposal',
24
- },
25
- {
26
- label: 'FASE 1.5 · UI/UX',
27
- what: 'Design system, mockups, component specs, user flows.',
28
- produces: '2-ui/{design-system,mockups,components,flows}.md',
29
- how: '/phase-uiux <feature> (in Claude Code)',
30
- optional: true,
31
- },
32
- {
33
- label: 'FASE 2 · DESIGN',
34
- what: 'Technical spec + C# contracts + architecture decisions.',
35
- produces: '1-design/{spec.md, contracts-level{N}.cs, decisions.md}',
36
- how: '/phase-design <feature> (in Claude Code)',
37
- },
38
- {
39
- label: 'FASE 3 · CLARIFY',
40
- what: 'Reviews spec for ambiguities, adds edge cases.',
41
- produces: '1-design/spec.md (updated with clarifications)',
42
- how: '/phase-clarify <feature> (in Claude Code)',
43
- },
44
- {
45
- label: 'FASE 4 · TASKS',
46
- what: 'Atomic task breakdown, DDD-aware.',
47
- produces: '3-tasks/tasks.md',
48
- how: 'auto-generated during /morph-proposal, or /phase-tasks <feature>',
49
- },
50
- {
51
- label: 'FASE 5 · IMPLEMENT',
52
- what: 'Code implementation with checkpoints every 3 tasks.',
53
- produces: '4-implement/recap.md + source code',
54
- how: '/morph-apply <feature> (in Claude Code)',
55
- },
56
- {
57
- label: 'FASE 6 · SYNC',
58
- what: 'Syncs decisions back to project standards.',
59
- produces: '.morph/framework/standards/ (updated)',
60
- how: 'morph-spec sync <feature>',
61
- optional: true,
62
- },
63
- ];
64
-
65
- const SEP = chalk.dim('─'.repeat(58));
66
-
67
- export function tutorialCommand() {
68
- console.log('');
69
- console.log(chalk.cyan.bold(' MORPH-SPEC Workflow Tutorial'));
70
- console.log(SEP);
71
- console.log('');
72
- console.log(
73
- chalk.white(
74
- ' MORPH-SPEC is spec-first: every feature goes through phases\n' +
75
- ' before any code is written. Each phase produces structured\n' +
76
- ' outputs that feed the next.'
77
- )
78
- );
79
- console.log('');
80
- console.log(SEP);
81
- console.log(chalk.cyan.bold(' PIPELINE'));
82
- console.log(SEP);
83
- console.log('');
84
- console.log(
85
- chalk.white(' proposal → setup → ') +
86
- chalk.dim('[uiux]') +
87
- chalk.white(' → design → clarify → tasks → implement → ') +
88
- chalk.dim('[sync]')
89
- );
90
- console.log(chalk.dim(' (phases in brackets are optional)'));
91
- console.log('');
92
-
93
- for (const phase of PHASES) {
94
- console.log(SEP);
95
- const label = phase.optional
96
- ? chalk.cyan.bold(` ${phase.label}`) + chalk.dim(' [optional]')
97
- : chalk.cyan.bold(` ${phase.label}`);
98
- console.log(label);
99
- console.log(chalk.white(` What: ${phase.what}`));
100
- console.log(chalk.dim(` Produces: ${phase.produces}`));
101
- console.log(chalk.green(` How: ${phase.how}`));
102
- console.log('');
103
- }
104
-
105
- console.log(SEP);
106
- console.log(chalk.cyan.bold(' GETTING STARTED'));
107
- console.log(SEP);
108
- console.log('');
109
- console.log(chalk.white(' 1. Open Claude Code in your project'));
110
- console.log(chalk.white(' 2. Run: ') + chalk.green('/morph-proposal <your-feature-name>'));
111
- console.log(chalk.white(' 3. Answer the questions — morph-spec handles the rest'));
112
- console.log('');
113
- console.log(chalk.dim(' Tip: run `morph-spec doctor` to verify your installation first.'));
114
- console.log('');
115
- }