@polymorphism-tech/morph-spec 4.9.0 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/morph-spec.js +30 -0
- package/bin/task-manager.js +34 -22
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +99 -98
- package/framework/agents.json +37 -7
- package/framework/commands/commit.md +166 -0
- package/framework/commands/morph-apply.md +13 -2
- package/framework/commands/morph-archive.md +8 -2
- package/framework/commands/morph-infra.md +6 -0
- package/framework/commands/morph-preflight.md +6 -0
- package/framework/commands/morph-proposal.md +56 -7
- package/framework/commands/morph-status.md +6 -0
- package/framework/commands/morph-troubleshoot.md +6 -0
- package/framework/hooks/claude-code/notification/approval-reminder.js +3 -2
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +154 -31
- package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +7 -84
- package/framework/hooks/claude-code/post-tool-use/validator-feedback.js +8 -17
- package/framework/hooks/claude-code/pre-compact/save-morph-context.js +16 -3
- package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +4 -3
- package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +3 -2
- package/framework/hooks/claude-code/pre-tool-use/task-tracking-guard.js +60 -0
- package/framework/hooks/claude-code/session-start/inject-morph-context.js +55 -2
- package/framework/hooks/claude-code/session-start/post-compact-restore.js +41 -0
- package/framework/hooks/claude-code/stop/validate-completion.js +2 -15
- package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +23 -5
- package/framework/hooks/shared/compact-restore.js +100 -0
- package/framework/hooks/shared/dispatch-helpers.js +116 -0
- package/framework/hooks/shared/phase-utils.js +9 -5
- package/framework/hooks/shared/state-reader.js +27 -3
- package/framework/phases.json +30 -7
- package/framework/rules/morph-workflow.md +88 -86
- package/framework/skills/level-0-meta/mcp-registry.json +86 -51
- package/framework/skills/level-0-meta/{brainstorming → morph-brainstorming}/SKILL.md +13 -16
- package/framework/skills/level-0-meta/{code-review → morph-code-review}/SKILL.md +1 -1
- package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{frontend-review → morph-frontend-review}/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-init/SKILL.md +72 -7
- package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/SKILL.md +9 -9
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +1 -1
- package/framework/skills/level-0-meta/{terminal-title → morph-terminal-title}/SKILL.md +1 -1
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/SKILL.md +2 -3
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/references/tools-per-phase.md +1 -2
- package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/SKILL.md +1 -1
- package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/scripts/check-phase-outputs.mjs +2 -2
- package/framework/skills/level-1-workflows/morph-phase-clarify/SKILL.md +238 -0
- package/framework/skills/level-1-workflows/{phase-codebase-analysis → morph-phase-codebase-analysis}/SKILL.md +251 -251
- package/framework/skills/level-1-workflows/morph-phase-design/SKILL.md +507 -0
- package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/SKILL.md +590 -491
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/code-quality-reviewer-prompt.md +50 -0
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/implementer-prompt.md +45 -0
- package/framework/skills/level-1-workflows/morph-phase-implement/prompts/spec-reviewer-prompt.md +47 -0
- package/framework/skills/level-1-workflows/morph-phase-plan/SKILL.md +254 -0
- package/framework/skills/level-1-workflows/{phase-setup → morph-phase-setup}/SKILL.md +237 -194
- package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/SKILL.md +307 -270
- package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/scripts/validate-tasks.mjs +3 -3
- package/framework/skills/level-1-workflows/{phase-uiux → morph-phase-uiux}/SKILL.md +320 -285
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +97 -0
- package/framework/standards/integration/mcp/mcp-tools.md +25 -7
- package/framework/templates/docs/onboarding.md +2 -2
- package/package.json +1 -2
- package/src/commands/agents/dispatch-agents.js +50 -3
- package/src/commands/mcp/mcp-setup.js +39 -2
- package/src/commands/phase/phase-reset.js +74 -0
- package/src/commands/project/doctor.js +19 -5
- package/src/commands/scope/escalate.js +215 -0
- package/src/commands/state/advance-phase.js +27 -53
- package/src/commands/state/state.js +1 -1
- package/src/commands/task/expand.js +100 -0
- package/src/core/paths/output-schema.js +4 -3
- package/src/core/state/phase-state-machine.js +7 -4
- package/src/core/state/state-manager.js +4 -3
- package/src/lib/detectors/claude-config-detector.js +93 -347
- package/src/lib/detectors/design-system-detector.js +189 -189
- package/src/lib/detectors/index.js +155 -57
- package/src/lib/generators/context-generator.js +2 -2
- package/src/lib/installers/mcp-installer.js +37 -5
- package/src/lib/phase-chain/phase-validator.js +22 -16
- package/src/lib/scope/impact-analyzer.js +106 -0
- package/src/lib/tasks/task-parser.js +1 -1
- package/src/lib/validators/shared/emit-validator-dispatch.js +64 -0
- package/src/scripts/setup-infra.js +15 -0
- package/src/utils/agents-installer.js +32 -12
- package/src/utils/file-copier.js +0 -1
- package/src/utils/hooks-installer.js +15 -1
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +0 -216
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +0 -383
- package/src/commands/project/index.js +0 -8
- package/src/core/index.js +0 -10
- package/src/core/state/index.js +0 -8
- package/src/core/templates/index.js +0 -9
- package/src/core/templates/template-data-sources.js +0 -325
- package/src/core/workflows/index.js +0 -7
- package/src/lib/detectors/config-detector.js +0 -223
- package/src/lib/detectors/standards-generator.js +0 -335
- package/src/lib/detectors/structure-detector.js +0 -275
- package/src/lib/monitor/agent-resolver.js +0 -144
- package/src/lib/monitor/renderer.js +0 -230
- package/src/lib/orchestration/index.js +0 -7
- package/src/lib/orchestration/team-orchestrator.js +0 -404
- package/src/sanitizer/context-sanitizer.js +0 -221
- package/src/sanitizer/patterns.js +0 -163
- package/src/writer/file-writer.js +0 -86
- /package/framework/skills/level-0-meta/{brainstorming → morph-brainstorming}/references/proposal-example.md +0 -0
- /package/framework/skills/level-0-meta/{code-review → morph-code-review}/references/review-example.md +0 -0
- /package/framework/skills/level-0-meta/{code-review → morph-code-review}/references/review-guidelines.md +0 -0
- /package/framework/skills/level-0-meta/{code-review → morph-code-review}/scripts/scan-csharp.mjs +0 -0
- /package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/references/review-example-nextjs.md +0 -0
- /package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/scripts/scan-nextjs.mjs +0 -0
- /package/framework/skills/level-0-meta/{frontend-review → morph-frontend-review}/scripts/scan-accessibility.mjs +0 -0
- /package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/scripts/detect-dev-server.mjs +0 -0
- /package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/scripts/detect-stack.mjs +0 -0
- /package/framework/skills/level-0-meta/{simulation-checklist → morph-simulation-checklist}/SKILL.md +0 -0
- /package/framework/skills/level-0-meta/{terminal-title → morph-terminal-title}/scripts/set_title.sh +0 -0
- /package/framework/skills/level-1-workflows/{phase-clarify → morph-phase-clarify}/references/clarifications-example.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/architecture-analysis-guide.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/spec-authoring-guide.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-design → morph-phase-design}/references/spec-example.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/references/recap-example.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-implement → morph-phase-implement}/references/vsa-implementation-guide.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/references/task-planning-patterns.md +0 -0
- /package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/references/tasks-example.md +0 -0
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> Spec-driven development framework for multi-stack projects. Turns feature requests into implementation-ready code through structured, AI-orchestrated phases.
|
|
4
4
|
|
|
5
5
|
**Package:** `@polymorphism-tech/morph-spec`
|
|
6
|
-
**Version:** 4.
|
|
6
|
+
**Version:** 4.10.0
|
|
7
7
|
**Requires:** Node.js 18+, Claude Code
|
|
8
8
|
|
|
9
9
|
---
|
|
@@ -376,4 +376,4 @@ Code generated by morph-spec (contracts, templates, implementation output) belon
|
|
|
376
376
|
|
|
377
377
|
---
|
|
378
378
|
|
|
379
|
-
*morph-spec v4.
|
|
379
|
+
*morph-spec v4.10.0 by [Polymorphism Tech](https://polymorphism.tech)*
|
package/bin/morph-spec.js
CHANGED
|
@@ -22,6 +22,7 @@ import { stateCommand } from '../src/commands/state/state.js';
|
|
|
22
22
|
import { advancePhaseCommand } from '../src/commands/state/advance-phase.js';
|
|
23
23
|
import { approveCommand, approvalStatusCommand, unapproveCommand } from '../src/commands/state/approve.js';
|
|
24
24
|
import { phaseRunCommand } from '../src/commands/state/phase-runner.js';
|
|
25
|
+
import { phaseResetCommand } from '../src/commands/phase/phase-reset.js';
|
|
25
26
|
|
|
26
27
|
// Agent commands
|
|
27
28
|
import { dispatchAgentsCommand } from '../src/commands/agents/dispatch-agents.js';
|
|
@@ -29,6 +30,10 @@ import { dispatchAgentsCommand } from '../src/commands/agents/dispatch-agents.js
|
|
|
29
30
|
// Task commands
|
|
30
31
|
import { taskDoneCommand, taskStartCommand, taskNextCommand } from '../src/commands/tasks/task.js';
|
|
31
32
|
|
|
33
|
+
// Scope escalation commands
|
|
34
|
+
import { scopeEscalateCommand } from '../src/commands/scope/escalate.js';
|
|
35
|
+
import { taskExpandCommand } from '../src/commands/task/expand.js';
|
|
36
|
+
|
|
32
37
|
// Validation commands
|
|
33
38
|
import { validateCommand } from './validate.js';
|
|
34
39
|
import { validateFeatureCommand } from '../src/commands/validation/validate-feature.js';
|
|
@@ -146,6 +151,12 @@ taskCommand
|
|
|
146
151
|
.description('Show next suggested task')
|
|
147
152
|
.action((feature, options) => taskNextCommand(feature, options));
|
|
148
153
|
|
|
154
|
+
taskCommand
|
|
155
|
+
.command('expand <feature> <task-id>')
|
|
156
|
+
.description('Expand a task into sub-tasks (low-impact scope escalation)')
|
|
157
|
+
.option('--into <subtasks...>', 'Sub-task definitions ("T017a: Title")')
|
|
158
|
+
.action((feature, taskId, options) => taskExpandCommand(feature, taskId, options));
|
|
159
|
+
|
|
149
160
|
// Generation commands
|
|
150
161
|
const generateCommand = program
|
|
151
162
|
.command('generate')
|
|
@@ -196,6 +207,11 @@ phaseCommand
|
|
|
196
207
|
.option('--skip-approval', 'Skip approval gate checks')
|
|
197
208
|
.action((feature, options) => phaseRunCommand(feature, options));
|
|
198
209
|
|
|
210
|
+
phaseCommand
|
|
211
|
+
.command('reset <feature> <phase>')
|
|
212
|
+
.description('Reset feature phase (recovery tool — bypasses approval gates)')
|
|
213
|
+
.action((feature, phase) => phaseResetCommand(feature, phase));
|
|
214
|
+
|
|
199
215
|
// Feature validation command (content-aware)
|
|
200
216
|
program
|
|
201
217
|
.command('validate-feature <feature>')
|
|
@@ -285,4 +301,18 @@ program
|
|
|
285
301
|
.option('-v, --verbose', 'Show stack trace on error')
|
|
286
302
|
.action((feature, phase, options) => dispatchAgentsCommand(feature, phase, options));
|
|
287
303
|
|
|
304
|
+
// Scope escalation commands
|
|
305
|
+
const scopeCommand = program
|
|
306
|
+
.command('scope')
|
|
307
|
+
.description('Scope management (escalate)');
|
|
308
|
+
|
|
309
|
+
scopeCommand
|
|
310
|
+
.command('escalate <feature>')
|
|
311
|
+
.description('Escalate scope when implementation reveals unexpected complexity')
|
|
312
|
+
.option('--task <id>', 'Trigger task ID (required)')
|
|
313
|
+
.option('--reason <text>', 'Reason for escalation (required)')
|
|
314
|
+
.option('--target <phase>', 'Override target phase (tasks | design)')
|
|
315
|
+
.option('--dry-run', 'Show recommendation without executing')
|
|
316
|
+
.action((feature, options) => scopeEscalateCommand(feature, options));
|
|
317
|
+
|
|
288
318
|
program.parse();
|
package/bin/task-manager.js
CHANGED
|
@@ -17,6 +17,7 @@ import { loadState, saveState } from '../src/core/state/state-manager.js';
|
|
|
17
17
|
import { parseTasksMd, ensureTaskList, syncCounters } from '../src/lib/tasks/task-parser.js';
|
|
18
18
|
import { isTestTask } from '../src/lib/tasks/task-classifier.js';
|
|
19
19
|
import { runTestSuite } from '../src/lib/tasks/test-runner.js';
|
|
20
|
+
import { STALE_MS, isStaleTask } from '../framework/hooks/shared/stale-task-reset.js';
|
|
20
21
|
|
|
21
22
|
const __filename = fileURLToPath(import.meta.url);
|
|
22
23
|
const __dirname = dirname(__filename);
|
|
@@ -112,7 +113,7 @@ class TaskManager {
|
|
|
112
113
|
const taskList = await ensureTaskList(feature, featureName);
|
|
113
114
|
|
|
114
115
|
if (taskList.length === 0) {
|
|
115
|
-
const tasksPath = join(process.cwd(), `.morph/features/${featureName}/
|
|
116
|
+
const tasksPath = join(process.cwd(), `.morph/features/${featureName}/4-tasks/tasks.md`);
|
|
116
117
|
const tasksExist = await access(tasksPath).then(() => true).catch(() => false);
|
|
117
118
|
if (!tasksExist) {
|
|
118
119
|
throw new Error(`No tasks found for '${featureName}' — tasks.md not generated yet.\n Complete the tasks phase first: run /phase-tasks`);
|
|
@@ -290,6 +291,18 @@ class TaskManager {
|
|
|
290
291
|
// Display progress
|
|
291
292
|
this.displayProgress(feature);
|
|
292
293
|
|
|
294
|
+
// Emit VALIDATION DISPATCH for PostToolUse hook (strategy 1 parsing).
|
|
295
|
+
// Skipped when --skip-validation is active (no validators needed).
|
|
296
|
+
if (!options.skipValidation && results.length > 0) {
|
|
297
|
+
try {
|
|
298
|
+
const { emitValidatorDispatch } = await import('../src/lib/validators/shared/emit-validator-dispatch.js');
|
|
299
|
+
const phase = feature.phase || 'implement';
|
|
300
|
+
await emitValidatorDispatch(featureName, phase, process.cwd());
|
|
301
|
+
} catch {
|
|
302
|
+
// Non-blocking
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
293
306
|
// Suggest next task
|
|
294
307
|
const nextTask = this.getNextTask(taskList);
|
|
295
308
|
if (nextTask) {
|
|
@@ -407,10 +420,12 @@ class TaskManager {
|
|
|
407
420
|
* Calculate progress
|
|
408
421
|
*/
|
|
409
422
|
calculateProgress(tasks) {
|
|
410
|
-
|
|
411
|
-
const
|
|
412
|
-
const
|
|
413
|
-
const
|
|
423
|
+
// Exclude expanded tasks — they are replaced by their sub-tasks
|
|
424
|
+
const activeTasks = tasks.filter(t => t.status !== 'expanded');
|
|
425
|
+
const total = activeTasks.length;
|
|
426
|
+
const completed = activeTasks.filter(t => t.status === 'completed').length;
|
|
427
|
+
const inProgress = activeTasks.filter(t => t.status === 'in_progress').length;
|
|
428
|
+
const pending = activeTasks.filter(t => t.status === 'pending').length;
|
|
414
429
|
const percentage = total > 0 ? Math.round((completed / total) * 100) : 0;
|
|
415
430
|
|
|
416
431
|
return { total, completed, inProgress, pending, percentage };
|
|
@@ -565,16 +580,11 @@ class TaskManager {
|
|
|
565
580
|
* treated as effectively pending and included as candidates.
|
|
566
581
|
*/
|
|
567
582
|
getNextTask(tasks) {
|
|
568
|
-
const STALE_MS = 60 * 60 * 1000;
|
|
569
|
-
const now = Date.now();
|
|
570
|
-
|
|
571
583
|
// Include stale in_progress tasks as effectively pending candidates
|
|
572
584
|
const isEffectivelyAvailable = (t) => {
|
|
585
|
+
if (t.status === 'expanded') return false;
|
|
573
586
|
if (t.status === 'pending') return true;
|
|
574
|
-
if (t.status === 'in_progress')
|
|
575
|
-
const age = t.startedAt ? now - new Date(t.startedAt).getTime() : Infinity;
|
|
576
|
-
return age > STALE_MS;
|
|
577
|
-
}
|
|
587
|
+
if (t.status === 'in_progress') return isStaleTask(t);
|
|
578
588
|
return false;
|
|
579
589
|
};
|
|
580
590
|
|
|
@@ -603,6 +613,13 @@ class TaskManager {
|
|
|
603
613
|
const filledLength = Math.round((percentage / 100) * barLength);
|
|
604
614
|
const bar = '█'.repeat(filledLength) + '░'.repeat(barLength - filledLength);
|
|
605
615
|
console.log(chalk.cyan(` [${bar}] ${percentage}%`));
|
|
616
|
+
|
|
617
|
+
// Warn about tasks flagged for review (from scope escalation)
|
|
618
|
+
const taskList = feature.taskList || [];
|
|
619
|
+
const needsReviewTasks = taskList.filter(t => t.needsReview && (t.status === 'done' || t.status === 'completed'));
|
|
620
|
+
if (needsReviewTasks.length > 0) {
|
|
621
|
+
console.log(chalk.yellow(`\n ⚠ ${needsReviewTasks.length} completed task(s) flagged for review (scope escalation)`));
|
|
622
|
+
}
|
|
606
623
|
}
|
|
607
624
|
|
|
608
625
|
/**
|
|
@@ -619,7 +636,7 @@ class TaskManager {
|
|
|
619
636
|
const taskList = await ensureTaskList(feature, featureName);
|
|
620
637
|
|
|
621
638
|
if (taskList.length === 0) {
|
|
622
|
-
const tasksPath = join(process.cwd(), `.morph/features/${featureName}/
|
|
639
|
+
const tasksPath = join(process.cwd(), `.morph/features/${featureName}/4-tasks/tasks.md`);
|
|
623
640
|
const tasksExist = await access(tasksPath).then(() => true).catch(() => false);
|
|
624
641
|
if (!tasksExist) {
|
|
625
642
|
throw new Error(`No tasks found for '${featureName}' — tasks.md not generated yet.\n Complete the tasks phase first: run /phase-tasks`);
|
|
@@ -645,16 +662,11 @@ class TaskManager {
|
|
|
645
662
|
|
|
646
663
|
// Reset any sibling tasks stuck in in_progress from a previous session.
|
|
647
664
|
// Only tasks OTHER than the one being started, and only if stale (>1h).
|
|
648
|
-
const STALE_MS = 60 * 60 * 1000;
|
|
649
|
-
const now = Date.now();
|
|
650
665
|
for (const t of taskList) {
|
|
651
|
-
if (t.id !== taskId && t
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
delete t.startedAt;
|
|
656
|
-
console.log(chalk.yellow(`⚠️ Task ${t.id} auto-reset to pending (stale from previous session)`));
|
|
657
|
-
}
|
|
666
|
+
if (t.id !== taskId && isStaleTask(t)) {
|
|
667
|
+
t.status = 'pending';
|
|
668
|
+
delete t.startedAt;
|
|
669
|
+
console.log(chalk.yellow(`⚠️ Task ${t.id} auto-reset to pending (stale from previous session)`));
|
|
658
670
|
}
|
|
659
671
|
}
|
|
660
672
|
|
package/claude-plugin.json
CHANGED
package/docs/CHEATSHEET.md
CHANGED
package/docs/QUICKSTART.md
CHANGED
package/framework/CLAUDE.md
CHANGED
|
@@ -1,98 +1,99 @@
|
|
|
1
|
-
# MORPH-SPEC Runtime Instructions
|
|
2
|
-
|
|
3
|
-
> by Polymorphism Tech — Spec-driven development for .NET/Blazor/Next.js/Azure
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Project Context
|
|
8
|
-
|
|
9
|
-
@.morph/context/README.md
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Critical Rules
|
|
14
|
-
|
|
15
|
-
**NEVER:**
|
|
16
|
-
- Skip to code without a specification
|
|
17
|
-
- Implement without design approval
|
|
18
|
-
- Ignore standards in `.morph/framework/standards/`
|
|
19
|
-
- Create infrastructure manually
|
|
20
|
-
- Generate code without defined contracts
|
|
21
|
-
- List questions as plain text — always use the `AskUserQuestion` tool
|
|
22
|
-
|
|
23
|
-
**ALWAYS:**
|
|
24
|
-
- Follow the mandatory phases
|
|
25
|
-
- Generate outputs in `.morph/features/{feature}/`
|
|
26
|
-
- Document decisions in `decisions.md`
|
|
27
|
-
- Checkpoint every 3 implemented tasks
|
|
28
|
-
- Use Infrastructure as Code
|
|
29
|
-
- Use `AskUserQuestion` tool whenever asking the user anything (1–4 questions per call; split into sequential calls if more)
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Quick Reference
|
|
34
|
-
|
|
35
|
-
| Command | Purpose |
|
|
36
|
-
|---------|---------|
|
|
37
|
-
| `/morph-proposal {feature}` | Full spec pipeline (phases 1–4, pauses for approval) |
|
|
38
|
-
| `/morph-apply {feature}` | Implement feature (phase 5) |
|
|
39
|
-
| `/morph-status` | Feature status dashboard |
|
|
40
|
-
| `/morph-preflight` | Pre-implementation validation |
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## State & Outputs
|
|
45
|
-
|
|
46
|
-
| Path | Notes |
|
|
47
|
-
|------|-------|
|
|
48
|
-
| `.morph/state.json` | **READ-ONLY** — use `morph-spec` CLI to update |
|
|
49
|
-
| `.morph/features/{feature}/{phase}/` | Feature outputs organized by phase |
|
|
50
|
-
| `.morph/framework/` | **READ-ONLY** — framework files managed by morph-spec |
|
|
51
|
-
| `.morph/config/config.json` | Project configuration (editable) |
|
|
52
|
-
|
|
53
|
-
### mark-output types
|
|
54
|
-
|
|
55
|
-
Use `morph-spec state mark-output <feature> <type>` with one of these exact type names:
|
|
56
|
-
|
|
57
|
-
| Type | Phase | kebab alias |
|
|
58
|
-
|------|-------|-------------|
|
|
59
|
-
| `proposal` | proposal | — |
|
|
60
|
-
| `schemaAnalysis` | design | `schema-analysis` |
|
|
61
|
-
| `spec` | design | — |
|
|
62
|
-
| `contracts` | design | — |
|
|
63
|
-
| `contractsVsa` | design | `contracts-vsa` |
|
|
64
|
-
| `decisions` | design | — |
|
|
65
|
-
| `clarifications` | clarify | — |
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
1
|
+
# MORPH-SPEC Runtime Instructions
|
|
2
|
+
|
|
3
|
+
> by Polymorphism Tech — Spec-driven development for .NET/Blazor/Next.js/Azure
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Project Context
|
|
8
|
+
|
|
9
|
+
@.morph/context/README.md
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Critical Rules
|
|
14
|
+
|
|
15
|
+
**NEVER:**
|
|
16
|
+
- Skip to code without a specification
|
|
17
|
+
- Implement without design approval
|
|
18
|
+
- Ignore standards in `.morph/framework/standards/`
|
|
19
|
+
- Create infrastructure manually
|
|
20
|
+
- Generate code without defined contracts
|
|
21
|
+
- List questions as plain text — always use the `AskUserQuestion` tool
|
|
22
|
+
|
|
23
|
+
**ALWAYS:**
|
|
24
|
+
- Follow the mandatory phases
|
|
25
|
+
- Generate outputs in `.morph/features/{feature}/`
|
|
26
|
+
- Document decisions in `decisions.md`
|
|
27
|
+
- Checkpoint every 3 implemented tasks
|
|
28
|
+
- Use Infrastructure as Code
|
|
29
|
+
- Use `AskUserQuestion` tool whenever asking the user anything (1–4 questions per call; split into sequential calls if more)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Quick Reference
|
|
34
|
+
|
|
35
|
+
| Command | Purpose |
|
|
36
|
+
|---------|---------|
|
|
37
|
+
| `/morph-proposal {feature}` | Full spec pipeline (phases 1–4, pauses for approval) |
|
|
38
|
+
| `/morph-apply {feature}` | Implement feature (phase 5) |
|
|
39
|
+
| `/morph-status` | Feature status dashboard |
|
|
40
|
+
| `/morph-preflight` | Pre-implementation validation |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## State & Outputs
|
|
45
|
+
|
|
46
|
+
| Path | Notes |
|
|
47
|
+
|------|-------|
|
|
48
|
+
| `.morph/state.json` | **READ-ONLY** — use `morph-spec` CLI to update |
|
|
49
|
+
| `.morph/features/{feature}/{phase}/` | Feature outputs organized by phase |
|
|
50
|
+
| `.morph/framework/` | **READ-ONLY** — framework files managed by morph-spec |
|
|
51
|
+
| `.morph/config/config.json` | Project configuration (editable) |
|
|
52
|
+
|
|
53
|
+
### mark-output types
|
|
54
|
+
|
|
55
|
+
Use `morph-spec state mark-output <feature> <type>` with one of these exact type names:
|
|
56
|
+
|
|
57
|
+
| Type | Phase | kebab alias |
|
|
58
|
+
|------|-------|-------------|
|
|
59
|
+
| `proposal` | proposal | — |
|
|
60
|
+
| `schemaAnalysis` | design | `schema-analysis` |
|
|
61
|
+
| `spec` | design | — |
|
|
62
|
+
| `contracts` | design | — |
|
|
63
|
+
| `contractsVsa` | design | `contracts-vsa` |
|
|
64
|
+
| `decisions` | design | — |
|
|
65
|
+
| `clarifications` | clarify | — |
|
|
66
|
+
| `plan` | plan | — |
|
|
67
|
+
| `tasks` | tasks | — |
|
|
68
|
+
| `uiDesignSystem` | uiux | `ui-design-system` |
|
|
69
|
+
| `uiMockups` | uiux | `ui-mockups` |
|
|
70
|
+
| `uiComponents` | uiux | `ui-components` |
|
|
71
|
+
| `uiFlows` | uiux | `ui-flows` |
|
|
72
|
+
| `recap` | implement | — |
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Phase Sequence
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
proposal → setup → [uiux] → design → clarify → plan → tasks → implement → [sync]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Use `morph-spec status {feature}` to see current phase and pending approval gates.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Agents
|
|
86
|
+
|
|
87
|
+
Tier-1 and tier-2 MORPH agents are available as native subagents in `.claude/agents/`.
|
|
88
|
+
They can be invoked directly by Claude Code during multi-agent workflows.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Context Window Tip
|
|
93
|
+
|
|
94
|
+
When using 3+ MCPs, add `"experimental": { "mcpCliMode": true }` to `.claude/settings.json`.
|
|
95
|
+
MCP tools load on-demand instead of all at startup — keeps context clean for actual work.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
*MORPH-SPEC by Polymorphism Tech*
|
package/framework/agents.json
CHANGED
|
@@ -2144,7 +2144,11 @@
|
|
|
2144
2144
|
"priority": "required"
|
|
2145
2145
|
}
|
|
2146
2146
|
],
|
|
2147
|
-
"teammate":
|
|
2147
|
+
"teammate": {
|
|
2148
|
+
"icon": "🛡️",
|
|
2149
|
+
"role": "Security Validator (read-only)",
|
|
2150
|
+
"spawn_prompt": "You are the Security Validator (Tier 4, READ-ONLY). Scan ALL source files (.cs, .razor, .tsx, .ts, .js) in the project for security vulnerabilities:\n\n1. SQL injection — string concatenation in queries (look for $\"...{var}...\" inside SQL/EF raw queries)\n2. Hardcoded secrets — API keys, passwords, connection strings in source code (not in appsettings)\n3. XSS — @Html.Raw usage in Razor/Blazor without sanitization\n4. Insecure deserialization — BinaryFormatter usage\n5. CSRF — POST forms/endpoints missing anti-forgery tokens ([ValidateAntiForgeryToken] or @Html.AntiForgeryToken)\n\nUse Grep and Glob to scan. Do NOT modify any files.\n\nOutput a JSON object: { \"passed\": boolean, \"issues\": [{ \"file\": string, \"line\": number, \"message\": string, \"severity\": \"error\" }] }"
|
|
2151
|
+
},
|
|
2148
2152
|
"hook_behavior": {
|
|
2149
2153
|
"validates": [
|
|
2150
2154
|
"SQL injection (string concatenation in queries)",
|
|
@@ -2196,7 +2200,11 @@
|
|
|
2196
2200
|
"priority": "required"
|
|
2197
2201
|
}
|
|
2198
2202
|
],
|
|
2199
|
-
"teammate":
|
|
2203
|
+
"teammate": {
|
|
2204
|
+
"icon": "🏗️",
|
|
2205
|
+
"role": "Architecture Validator (read-only)",
|
|
2206
|
+
"spawn_prompt": "You are the Architecture Validator (Tier 4, READ-ONLY). Scan the project for architectural violations:\n\n1. DbContext injection — look for direct DbContext injection instead of IDbContextFactory in Blazor components (.razor, .razor.cs)\n2. Async/await anti-patterns — search for .Result, .Wait(), .GetAwaiter().GetResult() in async code\n3. DI registration order — in Program.cs, verify services are registered before middleware (app.Use*/Map*)\n4. Blazor render mode — verify InteractiveServer/InteractiveWebAssembly components don't use incompatible patterns\n5. Layer violations — Domain/Application projects must not reference Infrastructure or Web projects\n\nUse Grep and Glob to scan. Do NOT modify any files.\n\nOutput a JSON object: { \"passed\": boolean, \"issues\": [{ \"file\": string, \"line\": number, \"message\": string, \"severity\": \"error\" }] }"
|
|
2207
|
+
},
|
|
2200
2208
|
"hook_behavior": {
|
|
2201
2209
|
"validates": [
|
|
2202
2210
|
"DbContext injection (IDbContextFactory required)",
|
|
@@ -2241,7 +2249,11 @@
|
|
|
2241
2249
|
"priority": "required"
|
|
2242
2250
|
}
|
|
2243
2251
|
],
|
|
2244
|
-
"teammate":
|
|
2252
|
+
"teammate": {
|
|
2253
|
+
"icon": "📦",
|
|
2254
|
+
"role": "Packages Validator (read-only)",
|
|
2255
|
+
"spawn_prompt": "You are the Packages Validator (Tier 4, READ-ONLY). Scan all project files for package issues:\n\n1. NuGet version conflicts — search *.csproj files for the same PackageReference appearing with different versions across projects\n2. Incompatible .NET 10 packages — check that major package versions are compatible with the target framework\n3. Security vulnerabilities — look for known outdated packages (Newtonsoft.Json < 13.0.1, System.Text.Json < 8.0.5, etc.)\n4. For npm projects: check package.json for duplicate dependencies, outdated major versions\n\nUse Grep and Glob to scan. Do NOT modify any files.\n\nOutput a JSON object: { \"passed\": boolean, \"issues\": [{ \"file\": string, \"message\": string, \"severity\": \"error\" }] }"
|
|
2256
|
+
},
|
|
2245
2257
|
"hook_behavior": {
|
|
2246
2258
|
"validates": [
|
|
2247
2259
|
"NuGet version conflicts (same package, different versions)",
|
|
@@ -2290,7 +2302,11 @@
|
|
|
2290
2302
|
"priority": "required"
|
|
2291
2303
|
}
|
|
2292
2304
|
],
|
|
2293
|
-
"teammate":
|
|
2305
|
+
"teammate": {
|
|
2306
|
+
"icon": "🎨",
|
|
2307
|
+
"role": "Design System Validator (read-only)",
|
|
2308
|
+
"spawn_prompt": "You are the Design System Validator (Tier 4, READ-ONLY). Scan CSS/SCSS and component files for design system compliance:\n\n1. Color palette — look for hardcoded hex/rgb colors instead of CSS variables (var(--color-primary), var(--color-secondary), etc.)\n2. Spacing — look for hardcoded px/rem values instead of spacing variables (var(--spacing-*))\n3. Typography — look for hardcoded font-size/font-family instead of typography variables (var(--font-*))\n4. Component naming — verify PascalCase for Blazor components (.razor) and kebab-case for CSS classes\n5. Check .morph/context/design-system.md if it exists for project-specific design tokens\n\nUse Grep and Glob to scan. Do NOT modify any files.\n\nOutput a JSON object: { \"passed\": boolean, \"issues\": [{ \"file\": string, \"line\": number, \"message\": string, \"severity\": \"warning\" }] }"
|
|
2309
|
+
},
|
|
2294
2310
|
"hook_behavior": {
|
|
2295
2311
|
"validates": [
|
|
2296
2312
|
"CSS color palette compliance (primary, secondary, accent)",
|
|
@@ -2346,7 +2362,11 @@
|
|
|
2346
2362
|
"priority": "required"
|
|
2347
2363
|
}
|
|
2348
2364
|
],
|
|
2349
|
-
"teammate":
|
|
2365
|
+
"teammate": {
|
|
2366
|
+
"icon": "⚡",
|
|
2367
|
+
"role": "Blazor Concurrency Validator (read-only)",
|
|
2368
|
+
"spawn_prompt": "You are the Blazor Concurrency Validator (Tier 4, READ-ONLY). Scan all Blazor component files (.razor, .razor.cs) for concurrency and lifecycle violations:\n\n1. DbContext lifecycle — look for injected DbContext (not IDbContextFactory), disposed context usage, scope issues\n2. Async void — search for 'async void' methods (must be 'async Task' except event handlers)\n3. JSInterop in OnInitialized — look for IJSRuntime calls in OnInitialized/OnInitializedAsync (must be in OnAfterRender/OnAfterRenderAsync)\n4. State mutation — look for property changes without calling StateHasChanged() or InvokeAsync(StateHasChanged)\n5. Thread safety — look for shared mutable state without synchronization in Blazor Server components\n\nUse Grep and Glob to scan. Do NOT modify any files.\n\nOutput a JSON object: { \"passed\": boolean, \"issues\": [{ \"file\": string, \"line\": number, \"message\": string, \"severity\": \"error\" }] }"
|
|
2369
|
+
},
|
|
2350
2370
|
"hook_behavior": {
|
|
2351
2371
|
"validates": [
|
|
2352
2372
|
"DbContext lifecycle violations (dispose, scope issues)",
|
|
@@ -2386,7 +2406,13 @@
|
|
|
2386
2406
|
]
|
|
2387
2407
|
},
|
|
2388
2408
|
"standards": [],
|
|
2389
|
-
"teammate":
|
|
2409
|
+
"teammate": {
|
|
2410
|
+
"icon": "🔬",
|
|
2411
|
+
"role": "Morph-Spec Validator (read-only)",
|
|
2412
|
+
"tools": "Read, Glob, Grep, Bash",
|
|
2413
|
+
"maxTurns": 12,
|
|
2414
|
+
"spawn_prompt": "You are the Morph-Spec Validator (Tier 4, READ-ONLY). Scan the morph-spec framework codebase for standards compliance:\n\n1. ESM imports — all relative imports must use .js extensions (e.g., './foo.js' not './foo')\n2. Command registration — new commands in src/commands/ must be imported and registered in bin/morph-spec.js\n3. Test coverage — each module in src/ should have a corresponding test file in tests/\n4. No CommonJS — search for require() or module.exports (must use import/export)\n5. Hook fail-open — all hooks in framework/hooks/ must have try/catch with exit(0) fallback\n6. Run 'npm test' to verify all tests pass\n\nUse Grep, Glob, and Bash to scan. Do NOT modify any files.\n\nOutput a JSON object: { \"passed\": boolean, \"issues\": [{ \"file\": string, \"line\": number, \"message\": string, \"severity\": \"error\" }] }"
|
|
2415
|
+
},
|
|
2390
2416
|
"hook_behavior": {
|
|
2391
2417
|
"validates": [
|
|
2392
2418
|
"ESM imports use .js extensions on relative paths",
|
|
@@ -2424,7 +2450,11 @@
|
|
|
2424
2450
|
"file naming"
|
|
2425
2451
|
]
|
|
2426
2452
|
},
|
|
2427
|
-
"
|
|
2453
|
+
"teammate": {
|
|
2454
|
+
"icon": "⚛️",
|
|
2455
|
+
"role": "Next.js Component Validator (read-only)",
|
|
2456
|
+
"spawn_prompt": "You are the Next.js Component Validator (Tier 4, READ-ONLY). Scan all .tsx/.ts files under src/ and validate:\n\n1. \"use client\" directive — must be present when React hooks (useState, useEffect, etc.) are used\n2. Server Components — \"use client\" must be absent for pure Server Components (no hooks, no event handlers)\n3. File naming — component files must use kebab-case naming convention\n4. Import patterns — client components should not import server-only modules\n\nUse Grep and Glob to scan. Do NOT modify any files.\n\nOutput a JSON object: { \"passed\": boolean, \"issues\": [{ \"file\": string, \"message\": string, \"suggestion\": string, \"severity\": \"warning\" }] }"
|
|
2457
|
+
}
|
|
2428
2458
|
}
|
|
2429
2459
|
},
|
|
2430
2460
|
"squads": {
|