@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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Used both by CLI commands and internal automation.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { readFileSync, writeFileSync, renameSync, existsSync, mkdirSync } from 'fs';
|
|
8
|
+
import { readFileSync, writeFileSync, renameSync, unlinkSync, existsSync, mkdirSync } from 'fs';
|
|
9
9
|
import { join, dirname } from 'path';
|
|
10
10
|
import { detectWorkflow } from '../workflows/workflow-detector.js';
|
|
11
11
|
import { getAllOutputPaths, getOutputPath } from '../paths/output-schema.js';
|
|
@@ -27,12 +27,13 @@ export function getStatePath() {
|
|
|
27
27
|
* Returns the phase corresponding to the highest-numbered folder present.
|
|
28
28
|
*
|
|
29
29
|
* @param {string} featurePath - Absolute path to .morph/features/{feature}/
|
|
30
|
-
* @returns {string} Phase name: 'implement' | 'tasks' | 'uiux' | 'design' | 'proposal' | 'setup'
|
|
30
|
+
* @returns {string} Phase name: 'implement' | 'tasks' | 'plan' | 'uiux' | 'design' | 'proposal' | 'setup'
|
|
31
31
|
*/
|
|
32
32
|
export function derivePhase(featurePath) {
|
|
33
33
|
const phaseMap = [
|
|
34
|
-
['
|
|
35
|
-
['
|
|
34
|
+
['5-implement', 'implement'],
|
|
35
|
+
['4-tasks', 'tasks'],
|
|
36
|
+
['3-plan', 'plan'],
|
|
36
37
|
['2-ui', 'uiux'],
|
|
37
38
|
['1-design', 'design'],
|
|
38
39
|
['0-proposal', 'proposal'],
|
|
@@ -137,10 +138,29 @@ export function saveState(state) {
|
|
|
137
138
|
mkdirSync(stateDir, { recursive: true });
|
|
138
139
|
}
|
|
139
140
|
|
|
140
|
-
// Atomic write: write to temp then rename
|
|
141
|
-
|
|
141
|
+
// Atomic write: write to a per-process temp file then rename.
|
|
142
|
+
// Per-process name prevents two concurrent CLI invocations (e.g. `task done && task start`)
|
|
143
|
+
// from clobbering each other's temp file on Windows.
|
|
144
|
+
const tmpPath = `${statePath}.tmp.${process.pid}`;
|
|
142
145
|
writeFileSync(tmpPath, JSON.stringify(state, null, 2), 'utf8');
|
|
143
|
-
|
|
146
|
+
|
|
147
|
+
// Retry rename on EPERM — Windows holds a brief exclusive lock on the target
|
|
148
|
+
// when another process is reading it; a short backoff resolves the contention.
|
|
149
|
+
const MAX_RETRIES = 5;
|
|
150
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
151
|
+
try {
|
|
152
|
+
renameSync(tmpPath, statePath);
|
|
153
|
+
return;
|
|
154
|
+
} catch (err) {
|
|
155
|
+
if (err.code === 'EPERM' && attempt < MAX_RETRIES) {
|
|
156
|
+
// Synchronous sleep: CPU-friendly, works on Node.js main thread (v9.4+)
|
|
157
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50 * (attempt + 1));
|
|
158
|
+
} else {
|
|
159
|
+
try { unlinkSync(tmpPath); } catch { /* ignore cleanup errors */ }
|
|
160
|
+
throw err;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
144
164
|
}
|
|
145
165
|
|
|
146
166
|
/**
|
|
@@ -241,7 +261,7 @@ async function ensureFeature(featureName, options = {}) {
|
|
|
241
261
|
|
|
242
262
|
state.features[featureName] = {
|
|
243
263
|
status: "draft",
|
|
244
|
-
workflow: workflowId, // auto |
|
|
264
|
+
workflow: workflowId, // auto | standard | nodejs-cli
|
|
245
265
|
workflowDetection,
|
|
246
266
|
createdAt: new Date().toISOString(),
|
|
247
267
|
updatedAt: new Date().toISOString(),
|
|
@@ -259,20 +279,7 @@ async function ensureFeature(featureName, options = {}) {
|
|
|
259
279
|
pending: 0
|
|
260
280
|
},
|
|
261
281
|
checkpoints: [],
|
|
262
|
-
|
|
263
|
-
totalThreads: 0,
|
|
264
|
-
parallelPeak: 0,
|
|
265
|
-
avgDuration: 0,
|
|
266
|
-
checkpointPassRate: 100
|
|
267
|
-
},
|
|
268
|
-
trustConfig: {
|
|
269
|
-
level: 'low',
|
|
270
|
-
history: [],
|
|
271
|
-
autoApprove: {
|
|
272
|
-
design: false,
|
|
273
|
-
tasks: false
|
|
274
|
-
}
|
|
275
|
-
},
|
|
282
|
+
trustConfig: {},
|
|
276
283
|
contextBundles: [],
|
|
277
284
|
fileChanges: []
|
|
278
285
|
};
|
|
@@ -515,20 +522,11 @@ export async function markOutput(featureName, outputType) {
|
|
|
515
522
|
|
|
516
523
|
const normalized = normalizeOutputType(outputType);
|
|
517
524
|
|
|
518
|
-
// Initialize outputs on demand (not pre-stored
|
|
525
|
+
// Initialize outputs on demand (not pre-stored)
|
|
519
526
|
if (!state.features[featureName].outputs) {
|
|
520
527
|
state.features[featureName].outputs = getAllOutputPaths(featureName);
|
|
521
528
|
}
|
|
522
529
|
|
|
523
|
-
// Define all valid output types (both camelCase and kebab-case alternatives)
|
|
524
|
-
const validTypes = [
|
|
525
|
-
'proposal', 'spec', 'contracts', 'tasks', 'decisions', 'recap',
|
|
526
|
-
'uiDesignSystem', 'ui-design-system',
|
|
527
|
-
'uiMockups', 'ui-mockups',
|
|
528
|
-
'uiComponents', 'ui-components',
|
|
529
|
-
'uiFlows', 'ui-flows'
|
|
530
|
-
];
|
|
531
|
-
|
|
532
530
|
if (!state.features[featureName].outputs[normalized]) {
|
|
533
531
|
// Try to find closest match for better error message
|
|
534
532
|
const validCamelCaseTypes = Object.keys(state.features[featureName].outputs);
|
|
@@ -551,9 +549,8 @@ export async function markOutput(featureName, outputType) {
|
|
|
551
549
|
}
|
|
552
550
|
|
|
553
551
|
errorMsg += `\n\nValid types:\n`;
|
|
554
|
-
errorMsg += `
|
|
555
|
-
errorMsg +=
|
|
556
|
-
errorMsg += `\nNote: UI types also accept kebab-case (e.g., 'ui-design-system')`;
|
|
552
|
+
errorMsg += ` ${validCamelCaseTypes.join(', ')}\n`;
|
|
553
|
+
errorMsg += `\nNote: UI types also accept kebab-case (e.g., 'ui-design-system', 'schema-analysis')`;
|
|
557
554
|
|
|
558
555
|
throw new Error(errorMsg);
|
|
559
556
|
}
|
|
@@ -575,31 +572,9 @@ export async function markOutput(featureName, outputType) {
|
|
|
575
572
|
});
|
|
576
573
|
}
|
|
577
574
|
|
|
578
|
-
// If marking tasks output, try to sync task count from state tasks array
|
|
579
|
-
if (normalized === 'tasks') {
|
|
580
|
-
syncTasksCount(state.features[featureName]);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
575
|
saveState(state);
|
|
584
576
|
}
|
|
585
577
|
|
|
586
|
-
/**
|
|
587
|
-
* Sync progress counters from taskList array into feature.progress
|
|
588
|
-
* @param {Object} feature - Feature object
|
|
589
|
-
*/
|
|
590
|
-
function syncTasksCount(feature) {
|
|
591
|
-
const list = feature.taskList;
|
|
592
|
-
if (!Array.isArray(list) || list.length === 0) return;
|
|
593
|
-
const completed = list.filter(t => t.status === 'completed').length;
|
|
594
|
-
feature.progress = {
|
|
595
|
-
total: list.length,
|
|
596
|
-
completed,
|
|
597
|
-
inProgress: list.filter(t => t.status === 'in_progress').length,
|
|
598
|
-
pending: list.filter(t => t.status === 'pending').length,
|
|
599
|
-
percentage: Math.round((completed / list.length) * 100)
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
|
|
603
578
|
/**
|
|
604
579
|
* Track a file change for a feature
|
|
605
580
|
* @param {string} featureName - Feature name
|
|
@@ -242,11 +242,11 @@ export async function detectWorkflow(options) {
|
|
|
242
242
|
if (workflows.length === 0) {
|
|
243
243
|
// Fallback if no configs found
|
|
244
244
|
return {
|
|
245
|
-
workflowId: '
|
|
245
|
+
workflowId: 'standard',
|
|
246
246
|
confidence: 0.5,
|
|
247
247
|
matchedKeywords: [],
|
|
248
248
|
estimatedComplexity: { files: 0, lines: 0, components: 0, hasInfra: false },
|
|
249
|
-
reasoning: 'No workflow configs found - using
|
|
249
|
+
reasoning: 'No workflow configs found - using standard as fallback',
|
|
250
250
|
alternativeWorkflows: []
|
|
251
251
|
};
|
|
252
252
|
}
|
|
@@ -286,8 +286,8 @@ export async function detectWorkflow(options) {
|
|
|
286
286
|
(priorityScore * priorityWeight) +
|
|
287
287
|
(contextScore * contextWeight);
|
|
288
288
|
|
|
289
|
-
// Penalty for workflows with no keyword matches
|
|
290
|
-
if (keywordMatch.matched.length === 0
|
|
289
|
+
// Penalty for workflows with no keyword matches
|
|
290
|
+
if (keywordMatch.matched.length === 0) {
|
|
291
291
|
totalScore *= 0.5; // 50% penalty for no keyword match
|
|
292
292
|
}
|
|
293
293
|
|
|
@@ -382,84 +382,6 @@ export function listWorkflows(projectPath = '.') {
|
|
|
382
382
|
}));
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
-
// ============================================================================
|
|
386
|
-
// Parallel, Fusion, Long-Running, Zero-Touch Detection
|
|
387
|
-
// ============================================================================
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Detect if parallel execution mode should be used for a feature.
|
|
391
|
-
* Based on dependency graph analysis: if feature has independent task squads,
|
|
392
|
-
* recommend parallel mode.
|
|
393
|
-
*
|
|
394
|
-
* @param {string} feature - Feature name
|
|
395
|
-
* @param {string} [projectPath='.'] - Project path
|
|
396
|
-
* @returns {Object} { useParallel: boolean, reason: string, squads: Array }
|
|
397
|
-
*/
|
|
398
|
-
export async function detectParallelMode(feature, projectPath = '.') {
|
|
399
|
-
try {
|
|
400
|
-
const { getExecutionPlan } = await import('../../lib/threads/thread-coordinator.js').catch(() => {
|
|
401
|
-
// thread-coordinator may not exist yet — graceful fallback
|
|
402
|
-
return { getExecutionPlan: null };
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
if (!getExecutionPlan) {
|
|
406
|
-
return { useParallel: false, reason: 'thread-coordinator not available', squads: [] };
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const plan = getExecutionPlan(feature);
|
|
410
|
-
|
|
411
|
-
if (!plan.valid) {
|
|
412
|
-
return { useParallel: false, reason: plan.error, squads: [] };
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
const parallelPhases = plan.phases.filter(p => p.canRunParallel);
|
|
416
|
-
const useParallel = parallelPhases.length > 0 && plan.stats.parallelizationRatio > 30;
|
|
417
|
-
|
|
418
|
-
return {
|
|
419
|
-
useParallel,
|
|
420
|
-
reason: useParallel
|
|
421
|
-
? `${plan.stats.parallelizationRatio}% of tasks are parallelizable across ${parallelPhases.length} phases`
|
|
422
|
-
: 'Tasks are mostly sequential — parallel mode would not improve throughput',
|
|
423
|
-
parallelizationRatio: plan.stats.parallelizationRatio,
|
|
424
|
-
parallelPhases: parallelPhases.length,
|
|
425
|
-
squads: parallelPhases.map(p => p.tasks)
|
|
426
|
-
};
|
|
427
|
-
} catch {
|
|
428
|
-
return { useParallel: false, reason: 'Dependency analysis failed', squads: [] };
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* Detect if a request needs fusion workflow (uncertainty → run N agents → best-of-N)
|
|
434
|
-
* @param {string} userRequest
|
|
435
|
-
* @returns {boolean}
|
|
436
|
-
*/
|
|
437
|
-
export function detectFusionNeed(userRequest) {
|
|
438
|
-
const fusionKeywords = [
|
|
439
|
-
'uncertain', 'uncertainty', 'critical decision', 'compare approaches',
|
|
440
|
-
'best approach', 'prototype', 'explore options', 'which is better',
|
|
441
|
-
'not sure how', 'multiple solutions', 'benchmark'
|
|
442
|
-
];
|
|
443
|
-
const req = userRequest.toLowerCase();
|
|
444
|
-
return fusionKeywords.some(kw => req.includes(kw));
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Detect if a request needs long-running workflow (L-Thread with stop hooks)
|
|
449
|
-
* @param {string} userRequest
|
|
450
|
-
* @returns {boolean}
|
|
451
|
-
*/
|
|
452
|
-
export function detectLongRunningNeed(userRequest) {
|
|
453
|
-
const longRunningKeywords = [
|
|
454
|
-
'autonomous', 'large scope', 'full system', 'end to end', 'e2e',
|
|
455
|
-
'complete implementation', 'no interruption', 'long running', 'unattended'
|
|
456
|
-
];
|
|
457
|
-
const req = userRequest.toLowerCase();
|
|
458
|
-
const fileCountMatch = req.match(/(\d+)\+?\s+files?/);
|
|
459
|
-
const fileCount = fileCountMatch ? parseInt(fileCountMatch[1]) : 0;
|
|
460
|
-
return longRunningKeywords.some(kw => req.includes(kw)) || fileCount > 10;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
385
|
/**
|
|
464
386
|
* Check zero-touch eligibility for a feature (requires trust-manager)
|
|
465
387
|
* @param {string} feature
|
|
@@ -467,14 +389,14 @@ export function detectLongRunningNeed(userRequest) {
|
|
|
467
389
|
*/
|
|
468
390
|
export async function checkZeroTouchEligibility(feature) {
|
|
469
391
|
try {
|
|
470
|
-
const {
|
|
471
|
-
|
|
392
|
+
const { getTrust } = await import('../../lib/trust/trust-manager.js').catch(() => ({
|
|
393
|
+
getTrust: null
|
|
472
394
|
}));
|
|
473
395
|
|
|
474
|
-
if (!
|
|
396
|
+
if (!getTrust) return false;
|
|
475
397
|
|
|
476
|
-
const
|
|
477
|
-
return level === '
|
|
398
|
+
const trust = getTrust(feature);
|
|
399
|
+
return trust.level === 'auto';
|
|
478
400
|
} catch {
|
|
479
401
|
return false;
|
|
480
402
|
}
|