@polymorphism-tech/morph-spec 4.21.0 → 5.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.
Files changed (213) hide show
  1. package/CLAUDE.md +57 -71
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +224 -491
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +1 -1
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/CLAUDE.md +55 -38
  8. package/framework/MORPH.md +244 -0
  9. package/framework/agents.json +127 -1183
  10. package/framework/commands/morph-apply.md +56 -240
  11. package/framework/commands/morph-archive.md +48 -85
  12. package/framework/commands/morph-preflight.md +7 -7
  13. package/framework/commands/morph-proposal.md +35 -191
  14. package/framework/commands/morph-status.md +19 -50
  15. package/framework/commands/morph-troubleshoot.md +2 -2
  16. package/framework/evals/rubrics/README.md +44 -0
  17. package/framework/evals/rubrics/architecture.md +46 -0
  18. package/framework/evals/rubrics/code-quality.md +50 -0
  19. package/framework/evals/rubrics/contracts.md +47 -0
  20. package/framework/evals/rubrics/test-coverage.md +50 -0
  21. package/framework/evals/scenarios/dotnet-crud.yaml +42 -0
  22. package/framework/evals/scenarios/nextjs-auth.yaml +38 -0
  23. package/framework/evals/suites/standard.yaml +5 -0
  24. package/framework/evals/trace-schema.md +67 -0
  25. package/framework/hooks/claude-code/core/README.md +3 -0
  26. package/framework/hooks/claude-code/core/denylist.json +14 -0
  27. package/framework/hooks/claude-code/{pre-tool-use → core}/enforce-phase-writes.js +5 -5
  28. package/framework/hooks/claude-code/core/post-edit-typecheck.js +69 -0
  29. package/framework/hooks/claude-code/core/pre-bash-denylist.js +29 -0
  30. package/framework/hooks/claude-code/{pre-tool-use → core}/protect-spec-files.js +4 -6
  31. package/framework/hooks/claude-code/{stop → core}/validate-completion.js +13 -82
  32. package/framework/hooks/shared/phase-utils.js +20 -28
  33. package/framework/hooks/shared/state-reader.js +4 -5
  34. package/framework/{skills/level-0-meta/mcp-registry.json → mcp/registry.json} +254 -210
  35. package/framework/phases.json +40 -114
  36. package/framework/rubrics/eval-rubric.json +66 -0
  37. package/framework/skills/README.md +39 -64
  38. package/framework/skills/core/README.md +3 -0
  39. package/framework/skills/core/morph-brainstorming/SKILL.md +102 -0
  40. package/framework/skills/core/morph-eval/SKILL.md +57 -0
  41. package/framework/skills/core/morph-implement/SKILL.md +83 -0
  42. package/framework/skills/core/morph-plan/SKILL.md +64 -0
  43. package/framework/skills/core/morph-review/SKILL.md +62 -0
  44. package/framework/skills/core/morph-stack-scan/SKILL.md +109 -0
  45. package/framework/skills/core/morph-standards/SKILL.md +49 -0
  46. package/framework/standards/STANDARDS.json +32 -0
  47. package/framework/standards/frontend/design-system/ai-image-generation.md +244 -0
  48. package/framework/standards/integration/mcp/mcp-tools.md +48 -0
  49. package/framework/templates/CLAUDE.md.core.guide.md +29 -0
  50. package/framework/templates/CLAUDE.md.core.template +22 -0
  51. package/framework/templates/REGISTRY.json +4 -4
  52. package/framework/workflows/configs/fast-track.json +5 -10
  53. package/framework/workflows/configs/full.json +4 -8
  54. package/framework/workflows/configs/quick.json +32 -0
  55. package/framework/workflows/configs/standard.json +57 -64
  56. package/package.json +7 -6
  57. package/src/commands/mcp/mcp-setup.js +58 -31
  58. package/src/commands/project/doctor.js +69 -70
  59. package/src/commands/project/init.js +26 -5
  60. package/src/commands/project/status.js +18 -19
  61. package/src/commands/state/approve.js +1 -1
  62. package/src/commands/validation/validate-feature.js +18 -112
  63. package/src/core/paths/output-schema.js +133 -151
  64. package/src/core/state/phase-state-machine.js +10 -24
  65. package/src/core/state/state-manager.js +17 -17
  66. package/src/core/workflows/workflow-detector.js +214 -31
  67. package/src/core/workflows/workflow-router.js +204 -0
  68. package/src/dashboard/app/pages/AgentMap.jsx +32 -33
  69. package/src/dashboard/app/pages/LiveState.jsx +1 -1
  70. package/src/dashboard/app/pages/PhasePipeline.jsx +2 -4
  71. package/src/dashboard/app/pages/SkillsLibrary.jsx +2 -3
  72. package/src/dashboard/app/pages/Workflows.jsx +2 -2
  73. package/src/dashboard/scanner/agents-scanner.js +30 -35
  74. package/src/lib/agents/metrics-aggregator.js +1 -1
  75. package/src/lib/agents/output-collector.js +7 -8
  76. package/src/lib/context/context-builder.js +289 -0
  77. package/src/lib/detectors/claude-config-detector.js +19 -3
  78. package/src/lib/generators/context-generator.js +20 -42
  79. package/src/lib/generators/index.js +1 -0
  80. package/src/lib/generators/mandate-generator.js +512 -0
  81. package/src/lib/generators/metadata-extractor.js +1 -1
  82. package/src/lib/generators/recap-generator.js +3 -4
  83. package/src/lib/installers/mcp-installer.js +300 -92
  84. package/src/lib/phase-chain/phase-validator.js +36 -40
  85. package/src/lib/stack/stack-profile.js +74 -91
  86. package/src/lib/tasks/task-parser.js +1 -1
  87. package/src/lib/tasks/wave-resolver.js +353 -0
  88. package/src/lib/validators/checkpoint-persistence.js +2 -2
  89. package/src/lib/validators/content/cross-phase-validator.js +281 -0
  90. package/src/lib/validators/content/index.js +1 -0
  91. package/src/lib/validators/shared/emit-validator-dispatch.js +6 -56
  92. package/src/scripts/global-install.js +2 -27
  93. package/src/utils/agents-installer.js +224 -447
  94. package/src/utils/claude-settings-manager.js +57 -15
  95. package/src/utils/file-copier.js +1 -0
  96. package/src/utils/hooks-installer.js +15 -117
  97. package/src/utils/skills-installer.js +12 -18
  98. package/bin/detect-agents.js +0 -226
  99. package/bin/task-manager.js +0 -1036
  100. package/framework/agents/README.md +0 -13
  101. package/framework/agents/ai-agents/ai-system-architect.md +0 -194
  102. package/framework/agents/ai-agents/vector-search-expert.md +0 -247
  103. package/framework/agents/architecture/architecture-expert.md +0 -98
  104. package/framework/agents/architecture/morph-spec-architect.md +0 -66
  105. package/framework/agents/architecture/packages-validator.md +0 -89
  106. package/framework/agents/architecture/security-expert.md +0 -79
  107. package/framework/agents/architecture/seo-growth-hacker.md +0 -168
  108. package/framework/agents/architecture/standards-architect.md +0 -153
  109. package/framework/agents/backend/dotnet-senior.md +0 -163
  110. package/framework/agents/backend/ef-modeler.md +0 -119
  111. package/framework/agents/backend/hangfire-orchestrator.md +0 -133
  112. package/framework/agents/backend/ms-agent-expert.md +0 -55
  113. package/framework/agents/backend/neon-expert.md +0 -379
  114. package/framework/agents/frontend/css-specialist.md +0 -89
  115. package/framework/agents/frontend/design-system-validator.md +0 -100
  116. package/framework/agents/frontend/gsap-animator.md +0 -131
  117. package/framework/agents/frontend/nextjs-component-validator.md +0 -97
  118. package/framework/agents/frontend/nextjs-expert.md +0 -201
  119. package/framework/agents/frontend/ui-designer.md +0 -259
  120. package/framework/agents/infrastructure/infra-architect.md +0 -215
  121. package/framework/agents/integrations/asaas-financial.md +0 -138
  122. package/framework/agents/integrations/neon-auth.md +0 -151
  123. package/framework/agents/integrations/resend-email.md +0 -127
  124. package/framework/hooks/claude-code/post-tool-use/agent-complete.js +0 -122
  125. package/framework/hooks/claude-code/post-tool-use/dispatch.js +0 -363
  126. package/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +0 -78
  127. package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +0 -194
  128. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +0 -199
  129. package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +0 -55
  130. package/framework/hooks/claude-code/session-start/inject-morph-context.js +0 -323
  131. package/framework/hooks/claude-code/session-start/post-compact-restore.js +0 -41
  132. package/framework/hooks/claude-code/session-start/resume-context.js +0 -77
  133. package/framework/hooks/claude-code/teammate-idle/teammate-idle.js +0 -90
  134. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +0 -114
  135. package/framework/hooks/shared/compact-restore.js +0 -123
  136. package/framework/hooks/shared/dispatch-helpers.js +0 -147
  137. package/framework/hooks/shared/skill-reminder-helpers.js +0 -79
  138. package/framework/hooks/shared/stale-task-reset.js +0 -57
  139. package/framework/hooks/shared/worktree-helpers.js +0 -75
  140. package/framework/skills/level-0-meta/README.md +0 -7
  141. package/framework/skills/level-0-meta/morph-agent-teams/SKILL.md +0 -472
  142. package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +0 -174
  143. package/framework/skills/level-0-meta/morph-brainstorming/references/proposal-example.md +0 -138
  144. package/framework/skills/level-0-meta/morph-checklist/SKILL.md +0 -145
  145. package/framework/skills/level-0-meta/morph-code-review/SKILL.md +0 -250
  146. package/framework/skills/level-0-meta/morph-code-review/references/review-example.md +0 -164
  147. package/framework/skills/level-0-meta/morph-code-review/references/review-guidelines.md +0 -100
  148. package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +0 -151
  149. package/framework/skills/level-0-meta/morph-code-review-nextjs/SKILL.md +0 -165
  150. package/framework/skills/level-0-meta/morph-code-review-nextjs/references/review-example-nextjs.md +0 -254
  151. package/framework/skills/level-0-meta/morph-code-review-nextjs/scripts/scan-nextjs.mjs +0 -189
  152. package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +0 -344
  153. package/framework/skills/level-0-meta/morph-frontend-review/scripts/scan-accessibility.mjs +0 -376
  154. package/framework/skills/level-0-meta/morph-init/SKILL.md +0 -537
  155. package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +0 -225
  156. package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +0 -382
  157. package/framework/skills/level-0-meta/morph-post-implementation/scripts/detect-dev-server.mjs +0 -153
  158. package/framework/skills/level-0-meta/morph-post-implementation/scripts/detect-stack.mjs +0 -234
  159. package/framework/skills/level-0-meta/morph-simulation-checklist/SKILL.md +0 -106
  160. package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +0 -243
  161. package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +0 -169
  162. package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +0 -148
  163. package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +0 -110
  164. package/framework/skills/level-1-workflows/README.md +0 -7
  165. package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +0 -269
  166. package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +0 -453
  167. package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +0 -44
  168. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-authoring-guide.md +0 -55
  169. package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +0 -253
  170. package/framework/skills/level-1-workflows/morph-phase-implement/.morph/logs/activity.json +0 -38
  171. package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +0 -493
  172. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +0 -50
  173. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +0 -46
  174. package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +0 -47
  175. package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +0 -132
  176. package/framework/skills/level-1-workflows/morph-phase-implement/references/vsa-implementation-guide.md +0 -92
  177. package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +0 -257
  178. package/framework/skills/level-1-workflows/morph-phase-tasks/.morph/logs/activity.json +0 -14
  179. package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +0 -291
  180. package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +0 -143
  181. package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +0 -404
  182. package/framework/skills/level-1-workflows/morph-phase-tasks/scripts/validate-tasks.mjs +0 -112
  183. package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +0 -788
  184. package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +0 -147
  185. package/framework/squad-templates/backend-only.json +0 -47
  186. package/framework/squad-templates/frontend-only.json +0 -56
  187. package/framework/squad-templates/full-stack.json +0 -74
  188. package/src/commands/agents/agent-metrics.js +0 -174
  189. package/src/commands/agents/audit-dispatch.js +0 -82
  190. package/src/commands/agents/detect-agents.js +0 -275
  191. package/src/commands/agents/dispatch-agents.js +0 -461
  192. package/src/commands/agents/index.js +0 -13
  193. package/src/commands/agents/manage-agents.js +0 -352
  194. package/src/commands/agents/project-metrics.js +0 -74
  195. package/src/commands/phase/phase-reset.js +0 -74
  196. package/src/commands/scope/escalate.js +0 -217
  197. package/src/commands/state/advance-phase.js +0 -600
  198. package/src/commands/state/phase-runner.js +0 -215
  199. package/src/commands/state/state.js +0 -444
  200. package/src/commands/task/expand.js +0 -100
  201. package/src/commands/tasks/index.js +0 -4
  202. package/src/commands/tasks/task.js +0 -105
  203. package/src/commands/templates/index.js +0 -5
  204. package/src/commands/templates/template-render.js +0 -93
  205. package/src/commands/trust/trust.js +0 -118
  206. package/src/lib/agents/agents-manager.js +0 -349
  207. package/src/lib/build/build-runner.js +0 -99
  208. package/src/lib/checkpoints/checkpoint-hooks.js +0 -111
  209. package/src/lib/contracts/sprint-contract-generator.js +0 -137
  210. package/src/lib/scope/impact-analyzer.js +0 -106
  211. package/src/lib/trust/trust-manager.js +0 -157
  212. package/src/utils/tier-helpers.js +0 -24
  213. /package/framework/hooks/claude-code/{post-tool-use → core}/loop-detect.js +0 -0
@@ -1,100 +0,0 @@
1
- /**
2
- * MORPH-SPEC Task Expand Command
3
- *
4
- * Expands a task into sub-tasks for low-impact scope escalation.
5
- * The original task gets status "expanded" and sub-tasks are appended to taskList.
6
- *
7
- * Usage:
8
- * morph-spec task expand <feature> <task-id> --into "T017a: Title" "T017b: Title"
9
- */
10
-
11
- import chalk from 'chalk';
12
- import { loadState, saveState } from '../../core/state/state-manager.js';
13
-
14
- /**
15
- * Parse a sub-task string "T017a: Title" into { id, title }.
16
- */
17
- function parseSubTask(str) {
18
- const match = str.match(/^(T\w+)\s*[:\-\u2014]\s*(.+)$/);
19
- if (match) return { id: match[1], title: match[2].trim() };
20
- // Fallback: use entire string as title, no id parseable
21
- return { id: str.split(/\s/)[0], title: str };
22
- }
23
-
24
- /**
25
- * Core expansion logic — exported for testing.
26
- *
27
- * @param {string} featureName
28
- * @param {string} taskId - ID of the task to expand
29
- * @param {string[]} subTaskStrings - Sub-task definitions ("T017a: Title")
30
- * @returns {{ success: boolean, error?: string }}
31
- */
32
- export function expandTask(featureName, taskId, subTaskStrings) {
33
- const state = loadState();
34
- const feature = state.features[featureName];
35
-
36
- if (!feature) {
37
- return { success: false, error: `Feature "${featureName}" not found` };
38
- }
39
-
40
- if (!feature.taskList) {
41
- return { success: false, error: `No taskList found for "${featureName}"` };
42
- }
43
-
44
- const task = feature.taskList.find(t => t.id === taskId);
45
- if (!task) {
46
- return { success: false, error: `Task "${taskId}" not found in taskList` };
47
- }
48
-
49
- if (task.status === 'done' || task.status === 'completed') {
50
- return { success: false, error: `Task "${taskId}" is already completed — cannot expand` };
51
- }
52
-
53
- // Parse sub-tasks
54
- const subTasks = subTaskStrings.map(parseSubTask);
55
- const subTaskIds = subTasks.map(s => s.id);
56
-
57
- // Mark original as expanded
58
- task.status = 'expanded';
59
- task.subTasks = subTaskIds;
60
- task.expandedAt = new Date().toISOString();
61
-
62
- // Append sub-tasks to taskList
63
- for (const sub of subTasks) {
64
- feature.taskList.push({
65
- id: sub.id,
66
- title: sub.title,
67
- status: 'pending',
68
- dependencies: [],
69
- files: [],
70
- checkpoint: null,
71
- parentTask: taskId
72
- });
73
- }
74
-
75
- feature.updatedAt = new Date().toISOString();
76
- saveState(state);
77
-
78
- return { success: true, subTaskIds };
79
- }
80
-
81
- /**
82
- * CLI command handler
83
- */
84
- export async function taskExpandCommand(feature, taskId, options) {
85
- if (!options.into || options.into.length === 0) {
86
- console.error(chalk.red('--into is required with at least one sub-task'));
87
- process.exit(1);
88
- }
89
-
90
- const result = expandTask(feature, taskId, options.into);
91
-
92
- if (!result.success) {
93
- console.error(chalk.red(`\n ${result.error}`));
94
- process.exit(1);
95
- }
96
-
97
- console.log(chalk.green(`\n Task ${taskId} expanded into ${result.subTaskIds.length} sub-tasks:`));
98
- result.subTaskIds.forEach(id => console.log(chalk.gray(` - ${id}`)));
99
- console.log('');
100
- }
@@ -1,4 +0,0 @@
1
- /**
2
- * Task Management Commands
3
- */
4
- export { taskCommand } from './task.js';
@@ -1,105 +0,0 @@
1
- /**
2
- * Task management commands
3
- * Spawns bin/task-manager.js (ESM) as a subprocess.
4
- */
5
-
6
- import { spawn } from 'child_process';
7
- import { fileURLToPath } from 'url';
8
- import { dirname, join } from 'path';
9
- import chalk from 'chalk';
10
-
11
- const __dirname = dirname(fileURLToPath(import.meta.url));
12
- const taskManagerPath = join(__dirname, '..', '..', '..', 'bin', 'task-manager.js');
13
-
14
- /**
15
- * Execute task-manager.js with given arguments
16
- */
17
- function executeTaskManager(args) {
18
- return new Promise((resolve, reject) => {
19
- // Note: shell: false (default) is intentional to preserve arguments with spaces
20
- const child = spawn('node', [taskManagerPath, ...args], {
21
- stdio: 'inherit'
22
- });
23
-
24
- child.on('close', (code) => {
25
- if (code === 0) {
26
- resolve();
27
- } else {
28
- reject(new Error(`Task manager exited with code ${code}`));
29
- }
30
- });
31
-
32
- child.on('error', (error) => {
33
- reject(error);
34
- });
35
- });
36
- }
37
-
38
- /**
39
- * Complete tasks command
40
- */
41
- export async function taskDoneCommand(featureName, taskIds, options) {
42
- try {
43
- const args = ['done', featureName, ...taskIds];
44
- if (options.skipValidation) args.push('--skip-validation');
45
- if (options.skipBuild) args.push('--skip-build');
46
- if (options.reason) args.push('--reason', options.reason);
47
- if (options.note) args.push('--note', options.note);
48
- if (options.dryRun) args.push('--dry-run');
49
- await executeTaskManager(args);
50
- } catch (error) {
51
- console.error(chalk.red(`Error: ${error.message}`));
52
- process.exit(1);
53
- }
54
- }
55
-
56
- /**
57
- * Start task command
58
- */
59
- export async function taskStartCommand(featureName, taskId, options) {
60
- try {
61
- const args = ['start', featureName, taskId];
62
- await executeTaskManager(args);
63
- } catch (error) {
64
- console.error(chalk.red(`Error: ${error.message}`));
65
- process.exit(1);
66
- }
67
- }
68
-
69
- /**
70
- * Bulk-done tasks command
71
- */
72
- export async function taskBulkDoneCommand(featureName, range, options) {
73
- try {
74
- const args = ['bulk-done', featureName];
75
- if (range) args.push(range);
76
- if (options.all) args.push('--all');
77
- if (options.from) args.push('--from', options.from);
78
- if (options.to) args.push('--to', options.to);
79
- if (options.skipValidation) args.push('--skip-validation');
80
- if (options.skipBuild) args.push('--skip-build');
81
- if (options.reason) args.push('--reason', options.reason);
82
- if (options.note) args.push('--note', options.note);
83
- if (options.dryRun) args.push('--dry-run');
84
- await executeTaskManager(args);
85
- } catch (error) {
86
- console.error(chalk.red(`Error: ${error.message}`));
87
- process.exit(1);
88
- }
89
- }
90
-
91
- /**
92
- * Annotate a task with a note
93
- */
94
- export async function taskAnnotateCommand(featureName, taskId, text, options) {
95
- try {
96
- const args = ['annotate', featureName, taskId, text];
97
- if (options.type) args.push('--type', options.type);
98
- if (options.markDone) args.push('--mark-done');
99
- await executeTaskManager(args);
100
- } catch (error) {
101
- console.error(chalk.red(`Error: ${error.message}`));
102
- process.exit(1);
103
- }
104
- }
105
-
@@ -1,5 +0,0 @@
1
- /**
2
- * Template Commands
3
- */
4
- export { templateRenderCommand } from './template-render.js';
5
- export { generateContractsCommand, parseSchemaAnalysisMd } from './generate-contracts.js';
@@ -1,93 +0,0 @@
1
- /**
2
- * Template Render Command - Render a template by ID with variables
3
- */
4
-
5
- import { writeFileSync, mkdirSync } from 'fs';
6
- import { dirname, join } from 'path';
7
- import chalk from 'chalk';
8
- import { logger } from '../../utils/logger.js';
9
- import { getTemplateById, resolveTemplatePathById } from '../../core/templates/template-registry.js';
10
- import { renderTemplate } from '../../core/templates/template-renderer.js';
11
- /**
12
- * Render template command
13
- */
14
- export async function templateRenderCommand(templateId, outputPath, variablesJson, options) {
15
- logger.header(`Rendering Template: ${templateId}`);
16
- logger.blank();
17
-
18
- try {
19
- // 1. Validate template exists
20
- const template = getTemplateById(templateId);
21
-
22
- if (!template) {
23
- logger.error(`Template not found: ${templateId}`);
24
- logger.dim('\n💡 Available template IDs are listed in framework/templates/ — check subdirectories code/, frontend/, meta-prompts/');
25
- process.exit(1);
26
- }
27
-
28
- // 2. Resolve template path
29
- const projectPath = options.projectPath || process.cwd();
30
- const templatePath = resolveTemplatePathById(templateId, projectPath);
31
-
32
- if (!templatePath) {
33
- logger.error(`Template file not found for ${templateId}`);
34
- logger.dim(' Searched in: .morph/framework/templates/ and framework/templates/');
35
- process.exit(1);
36
- }
37
-
38
- logger.dim(`Template: ${templatePath}`);
39
-
40
- // 3. Parse variables
41
- let variables = {};
42
- try {
43
- variables = JSON.parse(variablesJson);
44
- } catch (error) {
45
- logger.error('Invalid JSON in variables argument');
46
- logger.dim(` ${error.message}`);
47
- process.exit(1);
48
- }
49
-
50
- // 4. Add default variables
51
- const defaults = {
52
- DATE: new Date().toISOString().split('T')[0],
53
- YEAR: new Date().getFullYear().toString(),
54
- TIMESTAMP: new Date().toISOString()
55
- };
56
-
57
- const allVariables = { ...defaults, ...variables };
58
-
59
- logger.dim(`Variables: ${Object.keys(allVariables).length} provided`);
60
- logger.blank();
61
-
62
- // 5. Render template
63
- const renderedContent = renderTemplate(templatePath, allVariables);
64
-
65
- // 6. Output
66
- if (options.dryRun) {
67
- logger.info(chalk.cyan('📋 DRY RUN - Preview (file will NOT be written)'));
68
- logger.blank();
69
- console.log(renderedContent);
70
- logger.blank();
71
- logger.dim(`Would be written to: ${outputPath}`);
72
- } else {
73
- // Create output directory if needed
74
- const outputDir = dirname(outputPath);
75
- mkdirSync(outputDir, { recursive: true });
76
-
77
- // Write file
78
- writeFileSync(outputPath, renderedContent, 'utf-8');
79
-
80
- logger.success(`✅ Template rendered successfully`);
81
- logger.dim(` Output: ${chalk.cyan(outputPath)}`);
82
- }
83
-
84
- logger.blank();
85
-
86
- } catch (error) {
87
- logger.error(`Failed to render template: ${error.message}`);
88
- if (options.verbose) {
89
- console.error(error.stack);
90
- }
91
- process.exit(1);
92
- }
93
- }
@@ -1,118 +0,0 @@
1
- /**
2
- * Trust CLI — Trust level management for zero-touch execution
3
- *
4
- * Usage:
5
- * morph-spec trust status [feature]
6
- * morph-spec trust set <feature> <level> [reason]
7
- *
8
- * Levels:
9
- * manual — nothing auto-approved (default)
10
- * high — auto-approve low-risk gates (design, tasks)
11
- * auto — auto-approve all gates
12
- */
13
-
14
- import chalk from 'chalk';
15
- import {
16
- getTrust,
17
- setTrust,
18
- getTrustHistory,
19
- AUTO_APPROVE_GATES
20
- } from '../../lib/trust/trust-manager.js';
21
-
22
- const LEVEL_DESCRIPTIONS = {
23
- manual: 'manual approval required for all gates',
24
- high: 'auto-approves low-risk gates (design, tasks)',
25
- auto: 'auto-approves all gates'
26
- };
27
-
28
- /**
29
- * Trust status — current trust level for a feature or all features
30
- */
31
- export async function trustStatusCommand(featureName, options) {
32
- if (featureName) {
33
- const trust = getTrust(featureName);
34
-
35
- console.log(chalk.bold(`\n Trust Status — ${featureName}`));
36
- console.log(' ' + '─'.repeat(50));
37
-
38
- const levelColor = trust.level === 'auto' ? chalk.green
39
- : trust.level === 'high' ? chalk.cyan
40
- : chalk.yellow;
41
-
42
- console.log(` Level: ${levelColor(trust.level.toUpperCase())}`);
43
- console.log(` Description: ${LEVEL_DESCRIPTIONS[trust.level] || trust.level}`);
44
- console.log(` Source: ${trust.source || 'default'}`);
45
-
46
- if (trust.source === 'manual') {
47
- console.log(chalk.yellow(` Override: ${trust.overrideReason || 'No reason provided'}`));
48
- }
49
-
50
- console.log(`\n Auto-approved gates:`);
51
- if (trust.autoApprove.length === 0) {
52
- console.log(chalk.gray(' (none — manual approval required for all gates)'));
53
- } else {
54
- trust.autoApprove.forEach(g => console.log(chalk.green(` ✓ ${g}`)));
55
- }
56
-
57
- console.log(`\n Available trust levels:`);
58
- for (const [level, desc] of Object.entries(LEVEL_DESCRIPTIONS)) {
59
- const gates = AUTO_APPROVE_GATES[level] || [];
60
- const marker = trust.level === level ? chalk.bold(' ← current') : '';
61
- const gateList = gates.length > 0 ? gates.join(', ') : 'none';
62
- console.log(` ${level.padEnd(10)} auto-approves: ${gateList}${marker}`);
63
- }
64
-
65
- console.log();
66
- } else {
67
- // Show all features
68
- const history = getTrustHistory();
69
- if (history.length === 0) {
70
- console.log(chalk.yellow('\n No features found.\n'));
71
- return;
72
- }
73
-
74
- console.log(chalk.bold('\n Trust Overview'));
75
- console.log(' ' + '─'.repeat(60));
76
- console.log(` ${'Feature'.padEnd(25)} ${'Level'.padEnd(10)} Phase`);
77
- console.log(' ' + '─'.repeat(60));
78
-
79
- for (const f of history) {
80
- const levelColor = f.level === 'auto' ? chalk.green
81
- : f.level === 'high' ? chalk.cyan
82
- : chalk.yellow;
83
-
84
- console.log(
85
- ` ${f.feature.padEnd(25)} ` +
86
- `${levelColor(f.level.padEnd(10))} ` +
87
- `${f.phase || 'N/A'}`
88
- );
89
- }
90
- console.log();
91
- }
92
- }
93
-
94
- /**
95
- * Trust set — manually override trust level
96
- */
97
- export async function trustSetCommand(featureName, level, reason, options) {
98
- if (!featureName || !level) {
99
- console.error(chalk.red('Usage: morph-spec trust set <feature> <level> [reason]'));
100
- console.error(chalk.gray('Levels: manual, high, auto'));
101
- process.exit(1);
102
- }
103
-
104
- const effectiveReason = reason || `Manual override to ${level}`;
105
-
106
- try {
107
- const result = setTrust(featureName, level, effectiveReason);
108
-
109
- console.log(chalk.green(`\n✓ Trust updated for ${featureName}`));
110
- console.log(` Level: ${result.level}`);
111
- console.log(` Auto-approves: ${result.autoApprove.join(', ') || 'none'}`);
112
- console.log(` Reason: ${result.reason}`);
113
- console.log();
114
- } catch (err) {
115
- console.error(chalk.red(`Error: ${err.message}`));
116
- process.exit(1);
117
- }
118
- }