@polymorphism-tech/morph-spec 4.8.19 → 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/CLAUDE.md +21 -0
- package/README.md +2 -2
- package/bin/morph-spec.js +44 -55
- package/bin/task-manager.js +133 -20
- package/bin/validate.js +67 -33
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +201 -203
- package/docs/QUICKSTART.md +2 -2
- package/framework/CLAUDE.md +99 -77
- package/framework/agents.json +734 -182
- 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/context-refresh.js +1 -1
- package/framework/hooks/claude-code/post-tool-use/dispatch.js +155 -32
- package/framework/hooks/claude-code/post-tool-use/skill-reminder.js +78 -0
- 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 +4 -3
- 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 +124 -2
- package/framework/hooks/claude-code/session-start/post-compact-restore.js +41 -0
- package/framework/hooks/claude-code/statusline.py +76 -30
- 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/claude-code/user-prompt/set-terminal-title.js +14 -6
- package/framework/hooks/shared/activity-logger.js +0 -24
- 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 +12 -5
- package/framework/hooks/shared/skill-reminder-helpers.js +79 -0
- package/framework/hooks/shared/stale-task-reset.js +57 -0
- package/framework/hooks/shared/state-reader.js +29 -5
- package/framework/hooks/shared/worktree-helpers.js +53 -0
- package/framework/phases.json +69 -14
- 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 +14 -17
- package/framework/skills/level-0-meta/morph-checklist/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{code-review → morph-code-review}/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{code-review-nextjs → morph-code-review-nextjs}/SKILL.md +163 -163
- package/framework/skills/level-0-meta/{frontend-review → morph-frontend-review}/SKILL.md +9 -9
- package/framework/skills/level-0-meta/morph-init/SKILL.md +77 -12
- package/framework/skills/level-0-meta/{post-implementation → morph-post-implementation}/SKILL.md +62 -15
- package/framework/skills/level-0-meta/morph-replicate/SKILL.md +5 -5
- package/framework/skills/level-0-meta/morph-replicate/references/blazor-html-mapping.md +1 -1
- package/framework/skills/level-0-meta/{simulation-checklist → morph-simulation-checklist}/SKILL.md +1 -1
- package/framework/skills/level-0-meta/{terminal-title → morph-terminal-title}/SKILL.md +2 -2
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/SKILL.md +3 -4
- package/framework/skills/level-0-meta/{tool-usage-guide → morph-tool-usage-guide}/references/tools-per-phase.md +7 -7
- package/framework/skills/level-0-meta/{verification-before-completion → morph-verification-before-completion}/SKILL.md +2 -2
- 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 +3 -3
- 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 +168 -27
- 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 +50 -3
- package/framework/skills/level-1-workflows/{phase-tasks → morph-phase-tasks}/SKILL.md +48 -11
- 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 +46 -11
- package/framework/skills/level-1-workflows/morph-scope-escalation/SKILL.md +97 -0
- package/framework/standards/STANDARDS.json +640 -88
- package/framework/standards/infrastructure/vercel/vercel-database.md +106 -0
- package/framework/standards/integration/mcp/mcp-tools.md +25 -7
- package/framework/templates/REGISTRY.json +1825 -1909
- package/framework/templates/context/CONTEXT-FEATURE.md +276 -276
- package/framework/templates/docs/onboarding.md +3 -7
- package/package.json +2 -7
- package/src/commands/agents/dispatch-agents.js +104 -6
- package/src/commands/mcp/mcp-setup.js +39 -2
- package/src/commands/phase/phase-reset.js +74 -0
- package/src/commands/project/doctor.js +34 -51
- package/src/commands/project/init.js +1 -1
- package/src/commands/project/status.js +2 -2
- package/src/commands/project/update.js +381 -365
- package/src/commands/project/worktree.js +154 -0
- package/src/commands/scope/escalate.js +215 -0
- package/src/commands/state/advance-phase.js +132 -68
- package/src/commands/state/approve.js +2 -2
- package/src/commands/state/index.js +7 -8
- package/src/commands/state/phase-runner.js +1 -1
- package/src/commands/state/state.js +61 -6
- package/src/commands/task/expand.js +100 -0
- package/src/commands/tasks/task.js +78 -99
- package/src/commands/templates/template-render.js +93 -173
- package/src/commands/trust/trust.js +26 -21
- package/src/core/paths/output-schema.js +19 -3
- package/src/core/state/phase-state-machine.js +7 -4
- package/src/core/state/state-manager.js +32 -57
- package/src/core/workflows/workflow-detector.js +9 -87
- 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 +336 -0
- package/src/lib/scope/impact-analyzer.js +106 -0
- package/src/lib/stack/stack-profile.js +88 -0
- package/src/lib/tasks/task-classifier.js +16 -0
- package/src/lib/tasks/task-parser.js +1 -1
- package/src/lib/tasks/test-runner.js +77 -0
- package/src/lib/trust/trust-manager.js +32 -144
- package/src/lib/validators/shared/emit-validator-dispatch.js +64 -0
- package/src/lib/validators/spec-validator.js +58 -4
- package/src/lib/validators/validation-runner.js +23 -11
- package/src/scripts/setup-infra.js +255 -224
- package/src/utils/agents-installer.js +34 -14
- package/src/utils/banner.js +1 -1
- package/src/utils/claude-settings-manager.js +1 -1
- package/src/utils/file-copier.js +1 -1
- package/src/utils/hooks-installer.js +272 -8
- package/framework/hooks/dev/check-sync-health.js +0 -117
- package/framework/hooks/dev/guard-version-numbers.js +0 -57
- package/framework/hooks/dev/sync-standards-registry.js +0 -60
- package/framework/hooks/dev/sync-template-registry.js +0 -60
- package/framework/hooks/dev/validate-skill-format.js +0 -70
- package/framework/hooks/dev/validate-standard-format.js +0 -73
- package/framework/skills/level-1-workflows/phase-clarify/SKILL.md +0 -190
- package/framework/skills/level-1-workflows/phase-design/SKILL.md +0 -366
- package/framework/templates/meta-prompts/hops/hop-retry.md +0 -78
- package/framework/templates/meta-prompts/hops/hop-validation.md +0 -97
- package/framework/templates/meta-prompts/hops/hop-wrapper.md +0 -36
- package/framework/workflows/configs/design-impl.json +0 -49
- package/framework/workflows/configs/express.json +0 -45
- package/framework/workflows/configs/fast-track.json +0 -42
- package/framework/workflows/configs/full-morph.json +0 -79
- package/framework/workflows/configs/fusion.json +0 -39
- package/framework/workflows/configs/long-running.json +0 -33
- package/framework/workflows/configs/spec-only.json +0 -43
- package/framework/workflows/configs/ui-refresh.json +0 -49
- package/framework/workflows/configs/zero-touch.json +0 -82
- package/src/commands/project/index.js +0 -8
- package/src/commands/project/monitor.js +0 -295
- package/src/commands/project/tutorial.js +0 -115
- package/src/commands/state/validate-phase.js +0 -238
- package/src/commands/templates/generate-contracts.js +0 -445
- package/src/core/index.js +0 -10
- package/src/core/orchestrator.js +0 -171
- package/src/core/registry/command-registry.js +0 -28
- package/src/core/registry/index.js +0 -8
- package/src/core/registry/validator-registry.js +0 -204
- 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/templates/template-validator.js +0 -296
- package/src/core/workflows/index.js +0 -7
- package/src/generator/config-generator.js +0 -206
- package/src/generator/templates/config.json.template +0 -40
- package/src/generator/templates/project.md.template +0 -67
- package/src/lib/agents/micro-agent-factory.js +0 -161
- package/src/lib/analysis/complexity-analyzer.js +0 -441
- package/src/lib/analysis/index.js +0 -7
- package/src/lib/analytics/analytics-engine.js +0 -345
- package/src/lib/checkpoints/checkpoint-hooks.js +0 -298
- package/src/lib/checkpoints/index.js +0 -7
- package/src/lib/context/context-bundler.js +0 -241
- package/src/lib/context/context-optimizer.js +0 -212
- package/src/lib/context/context-tracker.js +0 -273
- package/src/lib/context/core-four-tracker.js +0 -201
- package/src/lib/context/mcp-optimizer.js +0 -200
- 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/execution/fusion-executor.js +0 -304
- package/src/lib/execution/parallel-executor.js +0 -270
- package/src/lib/hooks/stop-hook-executor.js +0 -286
- package/src/lib/hops/hop-composer.js +0 -221
- 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/lib/phase-chain/eligibility-checker.js +0 -243
- package/src/lib/threads/thread-coordinator.js +0 -238
- package/src/lib/threads/thread-manager.js +0 -317
- package/src/lib/tracking/artifact-trail.js +0 -202
- package/src/sanitizer/context-sanitizer.js +0 -221
- package/src/sanitizer/patterns.js +0 -163
- package/src/scanner/project-scanner.js +0 -242
- package/src/ui/diff-display.js +0 -91
- package/src/ui/interactive-wizard.js +0 -96
- package/src/ui/user-review.js +0 -211
- package/src/ui/wizard-questions.js +0 -188
- package/src/utils/color-utils.js +0 -70
- package/src/utils/process-handler.js +0 -97
- 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/{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
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Micro Agent Factory — Create ultra-specialized agents
|
|
3
|
-
*
|
|
4
|
-
* Micro-agents are stripped-down versions of base agents with:
|
|
5
|
-
* - Only the standards they need (1-3 files max)
|
|
6
|
-
* - A single focused mission
|
|
7
|
-
* - Minimal context overhead (~2-5K tokens vs 20-50K for full agent)
|
|
8
|
-
*
|
|
9
|
-
* Saved to: .morph/micro-agents/{name}.json
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from 'fs';
|
|
13
|
-
import { join } from 'path';
|
|
14
|
-
|
|
15
|
-
const MICRO_AGENTS_DIR = join(process.cwd(), '.morph/micro-agents');
|
|
16
|
-
const AGENTS_CONFIG = join(process.cwd(), '.morph/framework/agents.json');
|
|
17
|
-
|
|
18
|
-
// ============================================================================
|
|
19
|
-
// Agent Creation
|
|
20
|
-
// ============================================================================
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Create a micro-agent from a base agent with a standards subset
|
|
24
|
-
* @param {Object} opts
|
|
25
|
-
* @param {string} opts.name - Micro-agent name (e.g., 'jwt-validator')
|
|
26
|
-
* @param {string} opts.baseAgent - Base agent ID (e.g., 'security-expert')
|
|
27
|
-
* @param {string[]} opts.standards - Relevant standards file paths (1-3 files)
|
|
28
|
-
* @param {string} opts.mission - Focused mission description
|
|
29
|
-
* @param {string[]} [opts.tools] - Tools this micro-agent uses (default: minimal set)
|
|
30
|
-
* @param {Object} [opts.constraints] - Additional constraints
|
|
31
|
-
* @returns {Object} Micro-agent config object
|
|
32
|
-
*/
|
|
33
|
-
export function createMicroAgent({ name, baseAgent, standards, mission, tools = null, constraints = {} }) {
|
|
34
|
-
if (!name || !baseAgent || !mission) {
|
|
35
|
-
throw new Error('name, baseAgent, and mission are required');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (standards && standards.length > 5) {
|
|
39
|
-
throw new Error('Micro-agents should load at most 5 standards files (ideally 1-3)');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const baseAgentConfig = loadBaseAgent(baseAgent);
|
|
43
|
-
|
|
44
|
-
const microAgent = {
|
|
45
|
-
id: name,
|
|
46
|
-
type: 'micro-agent',
|
|
47
|
-
baseAgent,
|
|
48
|
-
createdAt: new Date().toISOString(),
|
|
49
|
-
mission,
|
|
50
|
-
tier: (baseAgentConfig?.tier || 3) + 1, // micro-agents are tier+1 (more specialized)
|
|
51
|
-
domain: baseAgentConfig?.domain || 'general',
|
|
52
|
-
standards: standards || [],
|
|
53
|
-
tools: tools || ['Read', 'Write', 'Edit'],
|
|
54
|
-
constraints: {
|
|
55
|
-
maxStandards: 3,
|
|
56
|
-
maxFiles: 10,
|
|
57
|
-
focusOnly: mission,
|
|
58
|
-
...constraints
|
|
59
|
-
},
|
|
60
|
-
contextEstimate: {
|
|
61
|
-
standards: (standards || []).length * 2000,
|
|
62
|
-
overhead: 1500,
|
|
63
|
-
total: ((standards || []).length * 2000) + 1500
|
|
64
|
-
},
|
|
65
|
-
prompt: generateMicroAgentPrompt({ name, baseAgent, standards, mission, constraints, baseAgentConfig })
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
return microAgent;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Save a micro-agent to disk
|
|
73
|
-
* @param {Object} microAgent - Micro-agent config (from createMicroAgent)
|
|
74
|
-
* @returns {string} Path to saved file
|
|
75
|
-
*/
|
|
76
|
-
export function saveMicroAgent(microAgent) {
|
|
77
|
-
if (!existsSync(MICRO_AGENTS_DIR)) {
|
|
78
|
-
mkdirSync(MICRO_AGENTS_DIR, { recursive: true });
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const filePath = join(MICRO_AGENTS_DIR, `${microAgent.id}.json`);
|
|
82
|
-
writeFileSync(filePath, JSON.stringify(microAgent, null, 2), 'utf8');
|
|
83
|
-
return filePath;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* List all micro-agents
|
|
88
|
-
* @returns {Array} Array of micro-agent summaries
|
|
89
|
-
*/
|
|
90
|
-
export function listMicroAgents() {
|
|
91
|
-
if (!existsSync(MICRO_AGENTS_DIR)) return [];
|
|
92
|
-
|
|
93
|
-
return readdirSync(MICRO_AGENTS_DIR)
|
|
94
|
-
.filter(f => f.endsWith('.json'))
|
|
95
|
-
.map(f => {
|
|
96
|
-
try {
|
|
97
|
-
const agent = JSON.parse(readFileSync(join(MICRO_AGENTS_DIR, f), 'utf8'));
|
|
98
|
-
return {
|
|
99
|
-
id: agent.id,
|
|
100
|
-
baseAgent: agent.baseAgent,
|
|
101
|
-
mission: agent.mission,
|
|
102
|
-
standards: agent.standards?.length || 0,
|
|
103
|
-
contextEstimate: agent.contextEstimate?.total || 0,
|
|
104
|
-
createdAt: agent.createdAt
|
|
105
|
-
};
|
|
106
|
-
} catch {
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
})
|
|
110
|
-
.filter(Boolean);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Get a specific micro-agent
|
|
115
|
-
* @param {string} name - Micro-agent name
|
|
116
|
-
* @returns {Object|null} Micro-agent config or null
|
|
117
|
-
*/
|
|
118
|
-
export function getMicroAgent(name) {
|
|
119
|
-
const filePath = join(MICRO_AGENTS_DIR, `${name}.json`);
|
|
120
|
-
if (!existsSync(filePath)) return null;
|
|
121
|
-
try {
|
|
122
|
-
return JSON.parse(readFileSync(filePath, 'utf8'));
|
|
123
|
-
} catch {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// ============================================================================
|
|
129
|
-
// Helpers
|
|
130
|
-
// ============================================================================
|
|
131
|
-
|
|
132
|
-
function loadBaseAgent(agentId) {
|
|
133
|
-
if (!existsSync(AGENTS_CONFIG)) return null;
|
|
134
|
-
try {
|
|
135
|
-
const config = JSON.parse(readFileSync(AGENTS_CONFIG, 'utf8'));
|
|
136
|
-
return config.agents?.find(a => a.id === agentId) || null;
|
|
137
|
-
} catch {
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function generateMicroAgentPrompt({ name, baseAgent, standards, mission, constraints, baseAgentConfig }) {
|
|
143
|
-
const standardsList = standards?.map(s => `- framework/standards/${s}`).join('\n') || '(none)';
|
|
144
|
-
|
|
145
|
-
return `You are a MICRO-AGENT: ${name}
|
|
146
|
-
Base: ${baseAgent} (${baseAgentConfig?.description || 'specialist'})
|
|
147
|
-
|
|
148
|
-
MISSION (single focus):
|
|
149
|
-
${mission}
|
|
150
|
-
|
|
151
|
-
STANDARDS TO LOAD (${standards?.length || 0} files):
|
|
152
|
-
${standardsList}
|
|
153
|
-
|
|
154
|
-
CONSTRAINTS:
|
|
155
|
-
- Focus ONLY on your mission above
|
|
156
|
-
- Do NOT load additional standards or context
|
|
157
|
-
- Maximum ${constraints.maxFiles || 10} files to read/write
|
|
158
|
-
- Report completion when done — do NOT start new tasks
|
|
159
|
-
|
|
160
|
-
This is a minimal-context agent. Stay focused.`;
|
|
161
|
-
}
|
|
@@ -1,441 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MORPH-SPEC Complexity Analyzer Library
|
|
3
|
-
*
|
|
4
|
-
* Analyzes user requests and classifies them into workflows:
|
|
5
|
-
* - fast-track: Trivial changes (bug fixes, small adjustments)
|
|
6
|
-
* - standard: Medium features (simple additions, improvements)
|
|
7
|
-
* - full-morph: Complex features (new subsystems, architecture)
|
|
8
|
-
*
|
|
9
|
-
* Used both by CLI commands and internal automation.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
// ============================================================================
|
|
13
|
-
// COMPLEXITY THRESHOLDS
|
|
14
|
-
// ============================================================================
|
|
15
|
-
|
|
16
|
-
export const COMPLEXITY_THRESHOLDS = {
|
|
17
|
-
'fast-track': {
|
|
18
|
-
maxFiles: 3,
|
|
19
|
-
maxLines: 50,
|
|
20
|
-
maxComponents: 0,
|
|
21
|
-
requiresInfrastructure: false,
|
|
22
|
-
requiresArchitecturalDecisions: false,
|
|
23
|
-
description: 'Bug fixes, small adjustments, edge cases, hotfixes'
|
|
24
|
-
},
|
|
25
|
-
'standard': {
|
|
26
|
-
maxFiles: 10,
|
|
27
|
-
maxLines: 500,
|
|
28
|
-
maxComponents: 2,
|
|
29
|
-
requiresInfrastructure: false,
|
|
30
|
-
requiresArchitecturalDecisions: false, // Only tactical decisions
|
|
31
|
-
description: 'Simple features, refactorings, incremental improvements'
|
|
32
|
-
},
|
|
33
|
-
'full-morph': {
|
|
34
|
-
maxFiles: Infinity,
|
|
35
|
-
maxLines: Infinity,
|
|
36
|
-
maxComponents: Infinity,
|
|
37
|
-
requiresInfrastructure: true, // Can have infrastructure
|
|
38
|
-
requiresArchitecturalDecisions: true, // Strategic decisions
|
|
39
|
-
description: 'Complex features, new subsystems, architectural changes'
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// ============================================================================
|
|
44
|
-
// KEYWORD DETECTION
|
|
45
|
-
// ============================================================================
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Keywords that indicate different complexity levels
|
|
49
|
-
*/
|
|
50
|
-
const COMPLEXITY_KEYWORDS = {
|
|
51
|
-
trivial: [
|
|
52
|
-
'bug', 'fix', 'corrigir', 'ajustar', 'typo', 'correção',
|
|
53
|
-
'edge case', 'hotfix', 'urgente', 'rápido', 'quick',
|
|
54
|
-
'cor', 'color', 'texto', 'text', 'label', 'validação',
|
|
55
|
-
'mensagem', 'message', 'css', 'style', 'espaçamento'
|
|
56
|
-
],
|
|
57
|
-
|
|
58
|
-
infrastructure: [
|
|
59
|
-
'azure', 'bicep', 'deploy', 'infra', 'infrastructure',
|
|
60
|
-
'container', 'kubernetes', 'k8s', 'database', 'sql',
|
|
61
|
-
'storage', 'queue', 'service bus', 'redis', 'cosmos'
|
|
62
|
-
],
|
|
63
|
-
|
|
64
|
-
architectural: [
|
|
65
|
-
'sistema', 'system', 'arquitetura', 'architecture',
|
|
66
|
-
'pattern', 'cqrs', 'event sourcing', 'microservice',
|
|
67
|
-
'subsistema', 'subsystem', 'integração', 'integration',
|
|
68
|
-
'autenticação', 'authentication', 'autorização', 'authorization'
|
|
69
|
-
],
|
|
70
|
-
|
|
71
|
-
newComponents: [
|
|
72
|
-
'novo', 'new', 'criar', 'create', 'adicionar', 'add',
|
|
73
|
-
'implementar', 'implement', 'desenvolver', 'develop',
|
|
74
|
-
'componente', 'component', 'serviço', 'service',
|
|
75
|
-
'tela', 'screen', 'página', 'page', 'formulário', 'form'
|
|
76
|
-
],
|
|
77
|
-
|
|
78
|
-
// UI Refresh workflow - visual only changes
|
|
79
|
-
uiRefresh: [
|
|
80
|
-
'redesign', 'redesenhar', 'bonito', 'bonitas', 'visual',
|
|
81
|
-
'estetica', 'aesthetics', 'modernizar', 'modernize',
|
|
82
|
-
'melhorar visual', 'mais bonito', 'prettier', 'beautiful',
|
|
83
|
-
'refresh', 'design system'
|
|
84
|
-
],
|
|
85
|
-
|
|
86
|
-
// Design Implementation workflow - prototype to code
|
|
87
|
-
designImplementation: [
|
|
88
|
-
'prototipo', 'prototype', 'figma', 'html para',
|
|
89
|
-
'converter design', 'replicar', 'from design',
|
|
90
|
-
'based on mockup', 'mockup', 'wireframe', 'implementar tela'
|
|
91
|
-
]
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Hidden complexity indicators for Blazor Server
|
|
96
|
-
* These keyword combinations indicate complexity that isn't obvious at first glance.
|
|
97
|
-
* When detected together, they should force full-morph workflow.
|
|
98
|
-
*
|
|
99
|
-
* See: framework/standards/backend/database/ef-core.md, frontend/blazor/state.md
|
|
100
|
-
*/
|
|
101
|
-
const HIDDEN_COMPLEXITY_INDICATORS = {
|
|
102
|
-
// Session + Blazor = complex circuit/state management
|
|
103
|
-
session: {
|
|
104
|
-
primary: ['session', 'sessão', 'estado', 'state'],
|
|
105
|
-
context: ['blazor', 'persist', 'persistir', 'circuit', 'scoped']
|
|
106
|
-
},
|
|
107
|
-
// Background operations = DbContext concurrency issues
|
|
108
|
-
background: {
|
|
109
|
-
primary: ['task.run', 'background', 'segundo plano', 'job', 'hangfire'],
|
|
110
|
-
context: ['concurrent', 'concorrente', 'async', 'parallel', 'paralelo', 'dbcontext', 'ef core']
|
|
111
|
-
},
|
|
112
|
-
// Navigation = potential state loss
|
|
113
|
-
navigation: {
|
|
114
|
-
primary: ['redirect', 'navigate', 'navegar', 'navegação'],
|
|
115
|
-
context: ['circuit', 'signalr', 'forceload', 'refresh', 'reload']
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
// ============================================================================
|
|
120
|
-
// ANALYSIS FUNCTIONS
|
|
121
|
-
// ============================================================================
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Detect keywords in user input
|
|
125
|
-
* @param {string} userInput - User request
|
|
126
|
-
* @param {Array<string>} keywords - Keywords to search for
|
|
127
|
-
* @returns {number} Count of keyword matches
|
|
128
|
-
*/
|
|
129
|
-
function detectKeywords(userInput, keywords) {
|
|
130
|
-
const lowerInput = userInput.toLowerCase();
|
|
131
|
-
return keywords.filter(keyword => lowerInput.includes(keyword)).length;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Estimate code impact from user input
|
|
136
|
-
* @param {string} userInput - User request
|
|
137
|
-
* @returns {Object} Estimated impact
|
|
138
|
-
*/
|
|
139
|
-
export function estimateCodeImpact(userInput) {
|
|
140
|
-
const lowerInput = userInput.toLowerCase();
|
|
141
|
-
|
|
142
|
-
// Trivial indicators
|
|
143
|
-
const trivialCount = detectKeywords(lowerInput, COMPLEXITY_KEYWORDS.trivial);
|
|
144
|
-
if (trivialCount > 0) {
|
|
145
|
-
return {
|
|
146
|
-
estimatedFiles: 1,
|
|
147
|
-
estimatedLines: 10,
|
|
148
|
-
estimatedComponents: 0,
|
|
149
|
-
confidence: 'high'
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Count indicators of new components
|
|
154
|
-
const newComponentCount = detectKeywords(lowerInput, COMPLEXITY_KEYWORDS.newComponents);
|
|
155
|
-
|
|
156
|
-
// Multiple components/features mentioned (separated by "e", "and", or commas)
|
|
157
|
-
const separators = [' e ', ' and ', ','];
|
|
158
|
-
const hasSeparator = separators.some(sep => lowerInput.includes(sep));
|
|
159
|
-
|
|
160
|
-
if (hasSeparator) {
|
|
161
|
-
// Split by any separator
|
|
162
|
-
let parts = [lowerInput];
|
|
163
|
-
for (const sep of separators) {
|
|
164
|
-
parts = parts.flatMap(part => part.split(sep));
|
|
165
|
-
}
|
|
166
|
-
parts = parts.filter(p => p.trim().length > 0);
|
|
167
|
-
|
|
168
|
-
// If we found multiple parts, estimate high complexity
|
|
169
|
-
if (parts.length > 1) {
|
|
170
|
-
return {
|
|
171
|
-
estimatedFiles: Math.min(parts.length * 3, 15),
|
|
172
|
-
estimatedLines: Math.min(parts.length * 200, 1000),
|
|
173
|
-
estimatedComponents: Math.min(parts.length, 5),
|
|
174
|
-
confidence: 'medium'
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// New component indicators
|
|
180
|
-
if (newComponentCount > 0) {
|
|
181
|
-
return {
|
|
182
|
-
estimatedFiles: 5,
|
|
183
|
-
estimatedLines: 200,
|
|
184
|
-
estimatedComponents: 1,
|
|
185
|
-
confidence: 'medium'
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Default to standard complexity
|
|
190
|
-
return {
|
|
191
|
-
estimatedFiles: 5,
|
|
192
|
-
estimatedLines: 150,
|
|
193
|
-
estimatedComponents: 1,
|
|
194
|
-
confidence: 'low'
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Detect if request involves infrastructure
|
|
200
|
-
* @param {string} userInput - User request
|
|
201
|
-
* @returns {boolean} True if infrastructure is involved
|
|
202
|
-
*/
|
|
203
|
-
export function detectInfrastructure(userInput) {
|
|
204
|
-
const infraCount = detectKeywords(userInput, COMPLEXITY_KEYWORDS.infrastructure);
|
|
205
|
-
return infraCount > 0;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Detect if request involves architectural decisions
|
|
210
|
-
* @param {string} userInput - User request
|
|
211
|
-
* @returns {boolean} True if architectural decisions are involved
|
|
212
|
-
*/
|
|
213
|
-
export function detectArchitecturalDecisions(userInput) {
|
|
214
|
-
const archCount = detectKeywords(userInput, COMPLEXITY_KEYWORDS.architectural);
|
|
215
|
-
return archCount > 0;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Detect if request is a UI refresh (visual redesign only)
|
|
220
|
-
* @param {string} userInput - User request
|
|
221
|
-
* @returns {boolean} True if UI refresh is detected
|
|
222
|
-
*/
|
|
223
|
-
export function detectUiRefresh(userInput) {
|
|
224
|
-
const refreshCount = detectKeywords(userInput, COMPLEXITY_KEYWORDS.uiRefresh);
|
|
225
|
-
// Need at least one refresh keyword AND no infrastructure/architectural keywords
|
|
226
|
-
const hasInfra = detectKeywords(userInput, COMPLEXITY_KEYWORDS.infrastructure) > 0;
|
|
227
|
-
const hasArch = detectKeywords(userInput, COMPLEXITY_KEYWORDS.architectural) > 0;
|
|
228
|
-
return refreshCount > 0 && !hasInfra && !hasArch;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Detect if request is a design implementation (prototype to code)
|
|
233
|
-
* @param {string} userInput - User request
|
|
234
|
-
* @returns {boolean} True if design implementation is detected
|
|
235
|
-
*/
|
|
236
|
-
export function detectDesignImplementation(userInput) {
|
|
237
|
-
const designCount = detectKeywords(userInput, COMPLEXITY_KEYWORDS.designImplementation);
|
|
238
|
-
return designCount > 0;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Detect hidden complexity in Blazor Server requests
|
|
243
|
-
* These are keyword combinations that indicate non-obvious complexity.
|
|
244
|
-
* @param {string} userInput - User request
|
|
245
|
-
* @returns {Object} Detection result with matched indicators
|
|
246
|
-
*/
|
|
247
|
-
export function detectHiddenComplexity(userInput) {
|
|
248
|
-
const lowerInput = userInput.toLowerCase();
|
|
249
|
-
const matchedIndicators = [];
|
|
250
|
-
|
|
251
|
-
for (const [indicatorName, indicator] of Object.entries(HIDDEN_COMPLEXITY_INDICATORS)) {
|
|
252
|
-
const hasPrimary = indicator.primary.some(keyword => lowerInput.includes(keyword));
|
|
253
|
-
const hasContext = indicator.context.some(keyword => lowerInput.includes(keyword));
|
|
254
|
-
|
|
255
|
-
if (hasPrimary && hasContext) {
|
|
256
|
-
matchedIndicators.push({
|
|
257
|
-
name: indicatorName,
|
|
258
|
-
reason: `Detected ${indicatorName} complexity: primary keywords + context keywords found`
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return {
|
|
264
|
-
hasHiddenComplexity: matchedIndicators.length > 0,
|
|
265
|
-
indicators: matchedIndicators
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Classify workflow based on analysis
|
|
271
|
-
* @param {Object} impact - Code impact estimation
|
|
272
|
-
* @param {boolean} hasInfrastructure - Has infrastructure
|
|
273
|
-
* @param {boolean} hasArchitecturalDecisions - Has architectural decisions
|
|
274
|
-
* @returns {string} Workflow type: "fast-track" | "standard" | "full-morph"
|
|
275
|
-
*/
|
|
276
|
-
export function classifyWorkflow(impact, hasInfrastructure, hasArchitecturalDecisions) {
|
|
277
|
-
const { estimatedFiles, estimatedLines, estimatedComponents } = impact;
|
|
278
|
-
|
|
279
|
-
// Full MORPH: Infrastructure or architectural decisions
|
|
280
|
-
if (hasInfrastructure || hasArchitecturalDecisions) {
|
|
281
|
-
return 'full-morph';
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Full MORPH: Large code impact
|
|
285
|
-
if (estimatedFiles > COMPLEXITY_THRESHOLDS.standard.maxFiles ||
|
|
286
|
-
estimatedLines > COMPLEXITY_THRESHOLDS.standard.maxLines ||
|
|
287
|
-
estimatedComponents > COMPLEXITY_THRESHOLDS.standard.maxComponents) {
|
|
288
|
-
return 'full-morph';
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// Fast Track: Trivial changes
|
|
292
|
-
if (estimatedFiles <= COMPLEXITY_THRESHOLDS['fast-track'].maxFiles &&
|
|
293
|
-
estimatedLines <= COMPLEXITY_THRESHOLDS['fast-track'].maxLines &&
|
|
294
|
-
estimatedComponents <= COMPLEXITY_THRESHOLDS['fast-track'].maxComponents) {
|
|
295
|
-
return 'fast-track';
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Default: Standard workflow
|
|
299
|
-
return 'standard';
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Analyze request complexity - Main entry point
|
|
304
|
-
* @param {string} userInput - User request
|
|
305
|
-
* @param {Object} options - Options
|
|
306
|
-
* @param {string} options.forceWorkflow - Force specific workflow
|
|
307
|
-
* @returns {Object} Complete analysis
|
|
308
|
-
*/
|
|
309
|
-
export function analyzeRequestComplexity(userInput, options = {}) {
|
|
310
|
-
// Check for forced workflow
|
|
311
|
-
if (options.forceWorkflow) {
|
|
312
|
-
return {
|
|
313
|
-
workflow: options.forceWorkflow,
|
|
314
|
-
forced: true,
|
|
315
|
-
reason: 'Manually overridden by user'
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Check for special workflows first (UI Refresh, Design Implementation)
|
|
320
|
-
const isUiRefresh = detectUiRefresh(userInput);
|
|
321
|
-
const isDesignImplementation = detectDesignImplementation(userInput);
|
|
322
|
-
|
|
323
|
-
if (isUiRefresh) {
|
|
324
|
-
return {
|
|
325
|
-
workflow: 'ui-refresh',
|
|
326
|
-
forced: false,
|
|
327
|
-
impact: { estimatedFiles: 5, estimatedLines: 200, estimatedComponents: 0 },
|
|
328
|
-
hasInfrastructure: false,
|
|
329
|
-
hasArchitecturalDecisions: false,
|
|
330
|
-
hasHiddenComplexity: false,
|
|
331
|
-
hiddenComplexityIndicators: [],
|
|
332
|
-
confidence: 'high',
|
|
333
|
-
reason: 'UI refresh detected: visual-only changes, no infrastructure or architecture',
|
|
334
|
-
thresholds: COMPLEXITY_THRESHOLDS.standard // Uses standard thresholds
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
if (isDesignImplementation) {
|
|
339
|
-
return {
|
|
340
|
-
workflow: 'design-implementation',
|
|
341
|
-
forced: false,
|
|
342
|
-
impact: { estimatedFiles: 8, estimatedLines: 400, estimatedComponents: 2 },
|
|
343
|
-
hasInfrastructure: false,
|
|
344
|
-
hasArchitecturalDecisions: false,
|
|
345
|
-
hasHiddenComplexity: false,
|
|
346
|
-
hiddenComplexityIndicators: [],
|
|
347
|
-
confidence: 'high',
|
|
348
|
-
reason: 'Design implementation detected: prototype to code conversion',
|
|
349
|
-
thresholds: COMPLEXITY_THRESHOLDS.standard // Uses standard thresholds
|
|
350
|
-
};
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// Analyze request
|
|
354
|
-
const impact = estimateCodeImpact(userInput);
|
|
355
|
-
const hasInfrastructure = detectInfrastructure(userInput);
|
|
356
|
-
const hasArchitecturalDecisions = detectArchitecturalDecisions(userInput);
|
|
357
|
-
const hiddenComplexity = detectHiddenComplexity(userInput);
|
|
358
|
-
|
|
359
|
-
// Hidden complexity forces full-morph (Blazor Server specific concerns)
|
|
360
|
-
let workflow;
|
|
361
|
-
if (hiddenComplexity.hasHiddenComplexity) {
|
|
362
|
-
workflow = 'full-morph';
|
|
363
|
-
} else {
|
|
364
|
-
workflow = classifyWorkflow(impact, hasInfrastructure, hasArchitecturalDecisions);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Build reason
|
|
368
|
-
let reason = `Estimated ${impact.estimatedFiles} files, ${impact.estimatedLines} lines, ${impact.estimatedComponents} components`;
|
|
369
|
-
if (hasInfrastructure) reason += ', requires infrastructure';
|
|
370
|
-
if (hasArchitecturalDecisions) reason += ', requires architectural decisions';
|
|
371
|
-
if (hiddenComplexity.hasHiddenComplexity) {
|
|
372
|
-
reason += `, hidden complexity detected: ${hiddenComplexity.indicators.map(i => i.name).join(', ')}`;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return {
|
|
376
|
-
workflow,
|
|
377
|
-
forced: false,
|
|
378
|
-
impact,
|
|
379
|
-
hasInfrastructure,
|
|
380
|
-
hasArchitecturalDecisions,
|
|
381
|
-
hasHiddenComplexity: hiddenComplexity.hasHiddenComplexity,
|
|
382
|
-
hiddenComplexityIndicators: hiddenComplexity.indicators,
|
|
383
|
-
confidence: impact.confidence,
|
|
384
|
-
reason,
|
|
385
|
-
thresholds: COMPLEXITY_THRESHOLDS[workflow]
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Get workflow phases
|
|
391
|
-
* @param {string} workflow - Workflow type
|
|
392
|
-
* @returns {Array<string>} List of phases to execute
|
|
393
|
-
*/
|
|
394
|
-
export function getWorkflowPhases(workflow) {
|
|
395
|
-
switch (workflow) {
|
|
396
|
-
case 'fast-track':
|
|
397
|
-
return ['quick-analysis', 'implement'];
|
|
398
|
-
|
|
399
|
-
case 'standard':
|
|
400
|
-
return ['proposal', 'design', 'tasks', 'implement'];
|
|
401
|
-
|
|
402
|
-
case 'full-morph':
|
|
403
|
-
return ['context', 'proposal', 'setup', 'uiux', 'design', 'clarify', 'tasks', 'implement', 'sync'];
|
|
404
|
-
|
|
405
|
-
case 'ui-refresh':
|
|
406
|
-
return ['visual-analysis', 'design-system', 'implement'];
|
|
407
|
-
|
|
408
|
-
case 'design-implementation':
|
|
409
|
-
return ['prototype-analysis', 'tasks', 'implement'];
|
|
410
|
-
|
|
411
|
-
default:
|
|
412
|
-
return ['context', 'proposal', 'setup', 'uiux', 'design', 'clarify', 'tasks', 'implement', 'sync'];
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* Get workflow description
|
|
418
|
-
* @param {string} workflow - Workflow type
|
|
419
|
-
* @returns {string} Human-readable description
|
|
420
|
-
*/
|
|
421
|
-
export function getWorkflowDescription(workflow) {
|
|
422
|
-
switch (workflow) {
|
|
423
|
-
case 'fast-track':
|
|
424
|
-
return 'Fast Track: Quick fixes without formal spec (1 pause, no outputs)';
|
|
425
|
-
|
|
426
|
-
case 'standard':
|
|
427
|
-
return 'Standard: Medium complexity with simplified workflow (2-3 pauses, minimal outputs)';
|
|
428
|
-
|
|
429
|
-
case 'full-morph':
|
|
430
|
-
return 'Full MORPH: Complete 8-phase workflow with all outputs';
|
|
431
|
-
|
|
432
|
-
case 'ui-refresh':
|
|
433
|
-
return 'UI Refresh: Visual redesign only (3 phases: Visual Analysis → Design System → Implement)';
|
|
434
|
-
|
|
435
|
-
case 'design-implementation':
|
|
436
|
-
return 'Design Implementation: Prototype to code conversion (3 phases: Prototype Analysis → Tasks → Implement)';
|
|
437
|
-
|
|
438
|
-
default:
|
|
439
|
-
return 'Unknown workflow';
|
|
440
|
-
}
|
|
441
|
-
}
|