@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.
- package/CLAUDE.md +57 -71
- package/README.md +2 -2
- package/bin/morph-spec.js +224 -491
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +55 -38
- package/framework/MORPH.md +244 -0
- package/framework/agents.json +127 -1183
- package/framework/commands/morph-apply.md +56 -240
- package/framework/commands/morph-archive.md +48 -85
- package/framework/commands/morph-preflight.md +7 -7
- package/framework/commands/morph-proposal.md +35 -191
- package/framework/commands/morph-status.md +19 -50
- package/framework/commands/morph-troubleshoot.md +2 -2
- package/framework/evals/rubrics/README.md +44 -0
- package/framework/evals/rubrics/architecture.md +46 -0
- package/framework/evals/rubrics/code-quality.md +50 -0
- package/framework/evals/rubrics/contracts.md +47 -0
- package/framework/evals/rubrics/test-coverage.md +50 -0
- package/framework/evals/scenarios/dotnet-crud.yaml +42 -0
- package/framework/evals/scenarios/nextjs-auth.yaml +38 -0
- package/framework/evals/suites/standard.yaml +5 -0
- package/framework/evals/trace-schema.md +67 -0
- package/framework/hooks/claude-code/core/README.md +3 -0
- package/framework/hooks/claude-code/core/denylist.json +14 -0
- package/framework/hooks/claude-code/{pre-tool-use → core}/enforce-phase-writes.js +5 -5
- package/framework/hooks/claude-code/core/post-edit-typecheck.js +69 -0
- package/framework/hooks/claude-code/core/pre-bash-denylist.js +29 -0
- package/framework/hooks/claude-code/{pre-tool-use → core}/protect-spec-files.js +4 -6
- package/framework/hooks/claude-code/{stop → core}/validate-completion.js +13 -82
- package/framework/hooks/shared/phase-utils.js +20 -28
- package/framework/hooks/shared/state-reader.js +4 -5
- package/framework/{skills/level-0-meta/mcp-registry.json → mcp/registry.json} +254 -210
- package/framework/phases.json +40 -114
- package/framework/rubrics/eval-rubric.json +66 -0
- package/framework/skills/README.md +39 -64
- package/framework/skills/core/README.md +3 -0
- package/framework/skills/core/morph-brainstorming/SKILL.md +102 -0
- package/framework/skills/core/morph-eval/SKILL.md +57 -0
- package/framework/skills/core/morph-implement/SKILL.md +83 -0
- package/framework/skills/core/morph-plan/SKILL.md +64 -0
- package/framework/skills/core/morph-review/SKILL.md +62 -0
- package/framework/skills/core/morph-stack-scan/SKILL.md +109 -0
- package/framework/skills/core/morph-standards/SKILL.md +49 -0
- package/framework/standards/STANDARDS.json +32 -0
- package/framework/standards/frontend/design-system/ai-image-generation.md +244 -0
- package/framework/standards/integration/mcp/mcp-tools.md +48 -0
- package/framework/templates/CLAUDE.md.core.guide.md +29 -0
- package/framework/templates/CLAUDE.md.core.template +22 -0
- package/framework/templates/REGISTRY.json +4 -4
- package/framework/workflows/configs/fast-track.json +5 -10
- package/framework/workflows/configs/full.json +4 -8
- package/framework/workflows/configs/quick.json +32 -0
- package/framework/workflows/configs/standard.json +57 -64
- package/package.json +7 -6
- package/src/commands/mcp/mcp-setup.js +58 -31
- package/src/commands/project/doctor.js +69 -70
- package/src/commands/project/init.js +26 -5
- package/src/commands/project/status.js +18 -19
- package/src/commands/state/approve.js +1 -1
- package/src/commands/validation/validate-feature.js +18 -112
- package/src/core/paths/output-schema.js +133 -151
- package/src/core/state/phase-state-machine.js +10 -24
- package/src/core/state/state-manager.js +17 -17
- package/src/core/workflows/workflow-detector.js +214 -31
- package/src/core/workflows/workflow-router.js +204 -0
- package/src/dashboard/app/pages/AgentMap.jsx +32 -33
- package/src/dashboard/app/pages/LiveState.jsx +1 -1
- package/src/dashboard/app/pages/PhasePipeline.jsx +2 -4
- package/src/dashboard/app/pages/SkillsLibrary.jsx +2 -3
- package/src/dashboard/app/pages/Workflows.jsx +2 -2
- package/src/dashboard/scanner/agents-scanner.js +30 -35
- package/src/lib/agents/metrics-aggregator.js +1 -1
- package/src/lib/agents/output-collector.js +7 -8
- package/src/lib/context/context-builder.js +289 -0
- package/src/lib/detectors/claude-config-detector.js +19 -3
- package/src/lib/generators/context-generator.js +20 -42
- package/src/lib/generators/index.js +1 -0
- package/src/lib/generators/mandate-generator.js +512 -0
- package/src/lib/generators/metadata-extractor.js +1 -1
- package/src/lib/generators/recap-generator.js +3 -4
- package/src/lib/installers/mcp-installer.js +300 -92
- package/src/lib/phase-chain/phase-validator.js +36 -40
- package/src/lib/stack/stack-profile.js +74 -91
- package/src/lib/tasks/task-parser.js +1 -1
- package/src/lib/tasks/wave-resolver.js +353 -0
- package/src/lib/validators/checkpoint-persistence.js +2 -2
- package/src/lib/validators/content/cross-phase-validator.js +281 -0
- package/src/lib/validators/content/index.js +1 -0
- package/src/lib/validators/shared/emit-validator-dispatch.js +6 -56
- package/src/scripts/global-install.js +2 -27
- package/src/utils/agents-installer.js +224 -447
- package/src/utils/claude-settings-manager.js +57 -15
- package/src/utils/file-copier.js +1 -0
- package/src/utils/hooks-installer.js +15 -117
- package/src/utils/skills-installer.js +12 -18
- package/bin/detect-agents.js +0 -226
- package/bin/task-manager.js +0 -1036
- package/framework/agents/README.md +0 -13
- package/framework/agents/ai-agents/ai-system-architect.md +0 -194
- package/framework/agents/ai-agents/vector-search-expert.md +0 -247
- package/framework/agents/architecture/architecture-expert.md +0 -98
- package/framework/agents/architecture/morph-spec-architect.md +0 -66
- package/framework/agents/architecture/packages-validator.md +0 -89
- package/framework/agents/architecture/security-expert.md +0 -79
- package/framework/agents/architecture/seo-growth-hacker.md +0 -168
- package/framework/agents/architecture/standards-architect.md +0 -153
- package/framework/agents/backend/dotnet-senior.md +0 -163
- package/framework/agents/backend/ef-modeler.md +0 -119
- package/framework/agents/backend/hangfire-orchestrator.md +0 -133
- package/framework/agents/backend/ms-agent-expert.md +0 -55
- package/framework/agents/backend/neon-expert.md +0 -379
- package/framework/agents/frontend/css-specialist.md +0 -89
- package/framework/agents/frontend/design-system-validator.md +0 -100
- package/framework/agents/frontend/gsap-animator.md +0 -131
- package/framework/agents/frontend/nextjs-component-validator.md +0 -97
- package/framework/agents/frontend/nextjs-expert.md +0 -201
- package/framework/agents/frontend/ui-designer.md +0 -259
- package/framework/agents/infrastructure/infra-architect.md +0 -215
- package/framework/agents/integrations/asaas-financial.md +0 -138
- package/framework/agents/integrations/neon-auth.md +0 -151
- package/framework/agents/integrations/resend-email.md +0 -127
- package/framework/hooks/claude-code/post-tool-use/agent-complete.js +0 -122
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +0 -363
- package/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +0 -78
- package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +0 -194
- package/framework/hooks/claude-code/pre-compact/save-morph-context.js +0 -199
- package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +0 -55
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +0 -323
- package/framework/hooks/claude-code/session-start/post-compact-restore.js +0 -41
- package/framework/hooks/claude-code/session-start/resume-context.js +0 -77
- package/framework/hooks/claude-code/teammate-idle/teammate-idle.js +0 -90
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +0 -114
- package/framework/hooks/shared/compact-restore.js +0 -123
- package/framework/hooks/shared/dispatch-helpers.js +0 -147
- package/framework/hooks/shared/skill-reminder-helpers.js +0 -79
- package/framework/hooks/shared/stale-task-reset.js +0 -57
- package/framework/hooks/shared/worktree-helpers.js +0 -75
- package/framework/skills/level-0-meta/README.md +0 -7
- package/framework/skills/level-0-meta/morph-agent-teams/SKILL.md +0 -472
- package/framework/skills/level-0-meta/morph-brainstorming/SKILL.md +0 -174
- package/framework/skills/level-0-meta/morph-brainstorming/references/proposal-example.md +0 -138
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +0 -145
- package/framework/skills/level-0-meta/morph-code-review/SKILL.md +0 -250
- package/framework/skills/level-0-meta/morph-code-review/references/review-example.md +0 -164
- package/framework/skills/level-0-meta/morph-code-review/references/review-guidelines.md +0 -100
- package/framework/skills/level-0-meta/morph-code-review/scripts/scan-csharp.mjs +0 -151
- package/framework/skills/level-0-meta/morph-code-review-nextjs/SKILL.md +0 -165
- package/framework/skills/level-0-meta/morph-code-review-nextjs/references/review-example-nextjs.md +0 -254
- package/framework/skills/level-0-meta/morph-code-review-nextjs/scripts/scan-nextjs.mjs +0 -189
- package/framework/skills/level-0-meta/morph-frontend-review/SKILL.md +0 -344
- package/framework/skills/level-0-meta/morph-frontend-review/scripts/scan-accessibility.mjs +0 -376
- package/framework/skills/level-0-meta/morph-init/SKILL.md +0 -537
- package/framework/skills/level-0-meta/morph-parallel-dispatch/SKILL.md +0 -225
- package/framework/skills/level-0-meta/morph-post-implementation/SKILL.md +0 -382
- package/framework/skills/level-0-meta/morph-post-implementation/scripts/detect-dev-server.mjs +0 -153
- package/framework/skills/level-0-meta/morph-post-implementation/scripts/detect-stack.mjs +0 -234
- package/framework/skills/level-0-meta/morph-simulation-checklist/SKILL.md +0 -106
- package/framework/skills/level-0-meta/morph-tool-usage-guide/SKILL.md +0 -243
- package/framework/skills/level-0-meta/morph-tool-usage-guide/references/tools-per-phase.md +0 -169
- package/framework/skills/level-0-meta/morph-verification-before-completion/SKILL.md +0 -148
- package/framework/skills/level-0-meta/morph-verification-before-completion/scripts/check-phase-outputs.mjs +0 -110
- package/framework/skills/level-1-workflows/README.md +0 -7
- package/framework/skills/level-1-workflows/morph-phase-codebase-analysis/SKILL.md +0 -269
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +0 -453
- package/framework/skills/level-1-workflows/morph-phase-design/references/architecture-analysis-guide.md +0 -44
- package/framework/skills/level-1-workflows/morph-phase-design/references/spec-authoring-guide.md +0 -55
- package/framework/skills/level-1-workflows/morph-phase-design/references/spec-example.md +0 -253
- package/framework/skills/level-1-workflows/morph-phase-implement/.morph/logs/activity.json +0 -38
- package/framework/skills/level-1-workflows/morph-phase-implement/SKILL.md +0 -493
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +0 -50
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +0 -46
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +0 -47
- package/framework/skills/level-1-workflows/morph-phase-implement/references/recap-example.md +0 -132
- package/framework/skills/level-1-workflows/morph-phase-implement/references/vsa-implementation-guide.md +0 -92
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +0 -257
- package/framework/skills/level-1-workflows/morph-phase-tasks/.morph/logs/activity.json +0 -14
- package/framework/skills/level-1-workflows/morph-phase-tasks/SKILL.md +0 -291
- package/framework/skills/level-1-workflows/morph-phase-tasks/references/task-planning-patterns.md +0 -143
- package/framework/skills/level-1-workflows/morph-phase-tasks/references/tasks-example.md +0 -404
- package/framework/skills/level-1-workflows/morph-phase-tasks/scripts/validate-tasks.mjs +0 -112
- package/framework/skills/level-1-workflows/morph-phase-uiux/SKILL.md +0 -788
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +0 -147
- package/framework/squad-templates/backend-only.json +0 -47
- package/framework/squad-templates/frontend-only.json +0 -56
- package/framework/squad-templates/full-stack.json +0 -74
- package/src/commands/agents/agent-metrics.js +0 -174
- package/src/commands/agents/audit-dispatch.js +0 -82
- package/src/commands/agents/detect-agents.js +0 -275
- package/src/commands/agents/dispatch-agents.js +0 -461
- package/src/commands/agents/index.js +0 -13
- package/src/commands/agents/manage-agents.js +0 -352
- package/src/commands/agents/project-metrics.js +0 -74
- package/src/commands/phase/phase-reset.js +0 -74
- package/src/commands/scope/escalate.js +0 -217
- package/src/commands/state/advance-phase.js +0 -600
- package/src/commands/state/phase-runner.js +0 -215
- package/src/commands/state/state.js +0 -444
- package/src/commands/task/expand.js +0 -100
- package/src/commands/tasks/index.js +0 -4
- package/src/commands/tasks/task.js +0 -105
- package/src/commands/templates/index.js +0 -5
- package/src/commands/templates/template-render.js +0 -93
- package/src/commands/trust/trust.js +0 -118
- package/src/lib/agents/agents-manager.js +0 -349
- package/src/lib/build/build-runner.js +0 -99
- package/src/lib/checkpoints/checkpoint-hooks.js +0 -111
- package/src/lib/contracts/sprint-contract-generator.js +0 -137
- package/src/lib/scope/impact-analyzer.js +0 -106
- package/src/lib/trust/trust-manager.js +0 -157
- package/src/utils/tier-helpers.js +0 -24
- /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,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,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
|
-
}
|