@agile-vibe-coding/avc 0.2.3 → 0.3.2
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 +475 -3
- package/cli/agents/agent-selector.md +23 -0
- package/cli/agents/code-implementer.md +117 -0
- package/cli/agents/code-validator.md +80 -0
- package/cli/agents/context-reviewer-epic.md +101 -0
- package/cli/agents/context-reviewer-story.md +92 -0
- package/cli/agents/context-writer-epic.md +145 -0
- package/cli/agents/context-writer-story.md +111 -0
- package/cli/agents/doc-writer-epic.md +42 -0
- package/cli/agents/doc-writer-story.md +43 -0
- package/cli/agents/duplicate-detector.md +110 -0
- package/cli/agents/epic-story-decomposer.md +318 -39
- package/cli/agents/mission-scope-generator.md +68 -4
- package/cli/agents/mission-scope-validator.md +40 -6
- package/cli/agents/project-context-extractor.md +21 -6
- package/cli/agents/scaffolding-generator.md +99 -0
- package/cli/agents/seed-validator.md +71 -0
- package/cli/agents/story-scope-reviewer.md +147 -0
- package/cli/agents/story-splitter.md +83 -0
- package/cli/agents/validator-documentation.json +31 -0
- package/cli/agents/validator-documentation.md +3 -1
- package/cli/api-reference-tool.js +368 -0
- package/cli/checks/catalog.json +76 -0
- package/cli/checks/code/quality.json +26 -0
- package/cli/checks/code/testing.json +14 -0
- package/cli/checks/code/traceability.json +26 -0
- package/cli/checks/cross-refs/epic.json +171 -0
- package/cli/checks/cross-refs/story.json +149 -0
- package/cli/checks/epic/api.json +114 -0
- package/cli/checks/epic/backend.json +126 -0
- package/cli/checks/epic/cloud.json +126 -0
- package/cli/checks/epic/data.json +102 -0
- package/cli/checks/epic/database.json +114 -0
- package/cli/checks/epic/developer.json +182 -0
- package/cli/checks/epic/devops.json +174 -0
- package/cli/checks/epic/frontend.json +162 -0
- package/cli/checks/epic/mobile.json +102 -0
- package/cli/checks/epic/qa.json +90 -0
- package/cli/checks/epic/security.json +184 -0
- package/cli/checks/epic/solution-architect.json +192 -0
- package/cli/checks/epic/test-architect.json +90 -0
- package/cli/checks/epic/ui.json +102 -0
- package/cli/checks/epic/ux.json +90 -0
- package/cli/checks/fixes/epic-fix-template.md +10 -0
- package/cli/checks/fixes/story-fix-template.md +10 -0
- package/cli/checks/story/api.json +186 -0
- package/cli/checks/story/backend.json +102 -0
- package/cli/checks/story/cloud.json +102 -0
- package/cli/checks/story/data.json +210 -0
- package/cli/checks/story/database.json +102 -0
- package/cli/checks/story/developer.json +168 -0
- package/cli/checks/story/devops.json +102 -0
- package/cli/checks/story/frontend.json +174 -0
- package/cli/checks/story/mobile.json +102 -0
- package/cli/checks/story/qa.json +210 -0
- package/cli/checks/story/security.json +198 -0
- package/cli/checks/story/solution-architect.json +230 -0
- package/cli/checks/story/test-architect.json +210 -0
- package/cli/checks/story/ui.json +102 -0
- package/cli/checks/story/ux.json +102 -0
- package/cli/coding-order.js +401 -0
- package/cli/dependency-checker.js +72 -0
- package/cli/epic-story-validator.js +284 -799
- package/cli/index.js +0 -0
- package/cli/init-model-config.js +17 -10
- package/cli/init.js +514 -92
- package/cli/kanban-server-manager.js +1 -2
- package/cli/llm-claude.js +98 -31
- package/cli/llm-gemini.js +29 -5
- package/cli/llm-local.js +493 -0
- package/cli/llm-openai.js +262 -41
- package/cli/llm-provider.js +147 -8
- package/cli/llm-token-limits.js +113 -4
- package/cli/llm-verifier.js +209 -1
- package/cli/llm-xiaomi.js +143 -0
- package/cli/message-constants.js +3 -12
- package/cli/messaging-api.js +6 -12
- package/cli/micro-check-fixer.js +335 -0
- package/cli/micro-check-runner.js +449 -0
- package/cli/micro-check-scorer.js +148 -0
- package/cli/micro-check-validator.js +538 -0
- package/cli/model-pricing.js +23 -0
- package/cli/model-selector.js +3 -2
- package/cli/prompt-logger.js +57 -0
- package/cli/repl-ink.js +106 -346
- package/cli/repl-old.js +1 -2
- package/cli/seed-processor.js +194 -24
- package/cli/sprint-planning-processor.js +2638 -289
- package/cli/template-processor.js +50 -3
- package/cli/token-tracker.js +50 -23
- package/cli/tools/generate-story-validators.js +1 -1
- package/cli/validation-router.js +70 -8
- package/cli/worktree-runner.js +654 -0
- package/kanban/client/dist/assets/index-D_KC5EQT.css +1 -0
- package/kanban/client/dist/assets/index-DjY5zqW7.js +351 -0
- package/kanban/client/dist/index.html +2 -2
- package/kanban/client/src/App.jsx +43 -14
- package/kanban/client/src/components/ceremony/AskArchPopup.jsx +7 -3
- package/kanban/client/src/components/ceremony/AskModelPopup.jsx +23 -10
- package/kanban/client/src/components/ceremony/CeremonyWorkflowModal.jsx +320 -133
- package/kanban/client/src/components/ceremony/ProviderSwitcherButton.jsx +290 -0
- package/kanban/client/src/components/ceremony/SponsorCallModal.jsx +80 -13
- package/kanban/client/src/components/ceremony/SprintPlanningModal.jsx +156 -22
- package/kanban/client/src/components/ceremony/steps/ArchitectureStep.jsx +11 -11
- package/kanban/client/src/components/ceremony/steps/CompleteStep.jsx +3 -21
- package/kanban/client/src/components/ceremony/steps/ReviewAnswersStep.jsx +214 -10
- package/kanban/client/src/components/ceremony/steps/RunningStep.jsx +23 -2
- package/kanban/client/src/components/kanban/CardDetailModal.jsx +97 -10
- package/kanban/client/src/components/kanban/GroupingSelector.jsx +7 -1
- package/kanban/client/src/components/kanban/KanbanCard.jsx +23 -14
- package/kanban/client/src/components/kanban/RefineWorkItemPopup.jsx +9 -14
- package/kanban/client/src/components/kanban/RunButton.jsx +162 -0
- package/kanban/client/src/components/kanban/SeedButton.jsx +176 -0
- package/kanban/client/src/components/settings/AgentsTab.jsx +103 -75
- package/kanban/client/src/components/settings/ApiKeysTab.jsx +31 -2
- package/kanban/client/src/components/settings/CeremonyModelsTab.jsx +9 -2
- package/kanban/client/src/components/settings/CheckEditorPopup.jsx +507 -0
- package/kanban/client/src/components/settings/CostThresholdsTab.jsx +3 -2
- package/kanban/client/src/components/settings/ModelPricingTab.jsx +72 -7
- package/kanban/client/src/components/settings/OpenAIAuthSection.jsx +412 -0
- package/kanban/client/src/components/settings/SettingsModal.jsx +4 -4
- package/kanban/client/src/components/stats/CostModal.jsx +34 -3
- package/kanban/client/src/hooks/useGrouping.js +59 -0
- package/kanban/client/src/lib/api.js +118 -4
- package/kanban/client/src/lib/status-grouping.js +10 -0
- package/kanban/client/src/store/kanbanStore.js +8 -0
- package/kanban/server/index.js +23 -2
- package/kanban/server/routes/ceremony.js +153 -4
- package/kanban/server/routes/costs.js +9 -3
- package/kanban/server/routes/openai-oauth.js +366 -0
- package/kanban/server/routes/settings.js +447 -14
- package/kanban/server/routes/websocket.js +7 -2
- package/kanban/server/routes/work-items.js +141 -1
- package/kanban/server/services/CeremonyService.js +275 -24
- package/kanban/server/services/TaskRunnerService.js +261 -0
- package/kanban/server/workers/run-task-worker.js +121 -0
- package/kanban/server/workers/seed-worker.js +94 -0
- package/kanban/server/workers/sponsor-call-worker.js +14 -6
- package/kanban/server/workers/sprint-planning-worker.js +94 -12
- package/package.json +2 -3
- package/cli/agents/solver-epic-api.json +0 -15
- package/cli/agents/solver-epic-api.md +0 -39
- package/cli/agents/solver-epic-backend.json +0 -15
- package/cli/agents/solver-epic-backend.md +0 -39
- package/cli/agents/solver-epic-cloud.json +0 -15
- package/cli/agents/solver-epic-cloud.md +0 -39
- package/cli/agents/solver-epic-data.json +0 -15
- package/cli/agents/solver-epic-data.md +0 -39
- package/cli/agents/solver-epic-database.json +0 -15
- package/cli/agents/solver-epic-database.md +0 -39
- package/cli/agents/solver-epic-developer.json +0 -15
- package/cli/agents/solver-epic-developer.md +0 -39
- package/cli/agents/solver-epic-devops.json +0 -15
- package/cli/agents/solver-epic-devops.md +0 -39
- package/cli/agents/solver-epic-frontend.json +0 -15
- package/cli/agents/solver-epic-frontend.md +0 -39
- package/cli/agents/solver-epic-mobile.json +0 -15
- package/cli/agents/solver-epic-mobile.md +0 -39
- package/cli/agents/solver-epic-qa.json +0 -15
- package/cli/agents/solver-epic-qa.md +0 -39
- package/cli/agents/solver-epic-security.json +0 -15
- package/cli/agents/solver-epic-security.md +0 -39
- package/cli/agents/solver-epic-solution-architect.json +0 -15
- package/cli/agents/solver-epic-solution-architect.md +0 -39
- package/cli/agents/solver-epic-test-architect.json +0 -15
- package/cli/agents/solver-epic-test-architect.md +0 -39
- package/cli/agents/solver-epic-ui.json +0 -15
- package/cli/agents/solver-epic-ui.md +0 -39
- package/cli/agents/solver-epic-ux.json +0 -15
- package/cli/agents/solver-epic-ux.md +0 -39
- package/cli/agents/solver-story-api.json +0 -15
- package/cli/agents/solver-story-api.md +0 -39
- package/cli/agents/solver-story-backend.json +0 -15
- package/cli/agents/solver-story-backend.md +0 -39
- package/cli/agents/solver-story-cloud.json +0 -15
- package/cli/agents/solver-story-cloud.md +0 -39
- package/cli/agents/solver-story-data.json +0 -15
- package/cli/agents/solver-story-data.md +0 -39
- package/cli/agents/solver-story-database.json +0 -15
- package/cli/agents/solver-story-database.md +0 -39
- package/cli/agents/solver-story-developer.json +0 -15
- package/cli/agents/solver-story-developer.md +0 -39
- package/cli/agents/solver-story-devops.json +0 -15
- package/cli/agents/solver-story-devops.md +0 -39
- package/cli/agents/solver-story-frontend.json +0 -15
- package/cli/agents/solver-story-frontend.md +0 -39
- package/cli/agents/solver-story-mobile.json +0 -15
- package/cli/agents/solver-story-mobile.md +0 -39
- package/cli/agents/solver-story-qa.json +0 -15
- package/cli/agents/solver-story-qa.md +0 -39
- package/cli/agents/solver-story-security.json +0 -15
- package/cli/agents/solver-story-security.md +0 -39
- package/cli/agents/solver-story-solution-architect.json +0 -15
- package/cli/agents/solver-story-solution-architect.md +0 -39
- package/cli/agents/solver-story-test-architect.json +0 -15
- package/cli/agents/solver-story-test-architect.md +0 -39
- package/cli/agents/solver-story-ui.json +0 -15
- package/cli/agents/solver-story-ui.md +0 -39
- package/cli/agents/solver-story-ux.json +0 -15
- package/cli/agents/solver-story-ux.md +0 -39
- package/cli/agents/validator-epic-api.json +0 -93
- package/cli/agents/validator-epic-api.md +0 -137
- package/cli/agents/validator-epic-backend.json +0 -93
- package/cli/agents/validator-epic-backend.md +0 -130
- package/cli/agents/validator-epic-cloud.json +0 -93
- package/cli/agents/validator-epic-cloud.md +0 -137
- package/cli/agents/validator-epic-data.json +0 -93
- package/cli/agents/validator-epic-data.md +0 -130
- package/cli/agents/validator-epic-database.json +0 -93
- package/cli/agents/validator-epic-database.md +0 -137
- package/cli/agents/validator-epic-developer.json +0 -74
- package/cli/agents/validator-epic-developer.md +0 -153
- package/cli/agents/validator-epic-devops.json +0 -74
- package/cli/agents/validator-epic-devops.md +0 -153
- package/cli/agents/validator-epic-frontend.json +0 -74
- package/cli/agents/validator-epic-frontend.md +0 -153
- package/cli/agents/validator-epic-mobile.json +0 -93
- package/cli/agents/validator-epic-mobile.md +0 -130
- package/cli/agents/validator-epic-qa.json +0 -93
- package/cli/agents/validator-epic-qa.md +0 -130
- package/cli/agents/validator-epic-security.json +0 -74
- package/cli/agents/validator-epic-security.md +0 -154
- package/cli/agents/validator-epic-solution-architect.json +0 -74
- package/cli/agents/validator-epic-solution-architect.md +0 -156
- package/cli/agents/validator-epic-test-architect.json +0 -93
- package/cli/agents/validator-epic-test-architect.md +0 -130
- package/cli/agents/validator-epic-ui.json +0 -93
- package/cli/agents/validator-epic-ui.md +0 -130
- package/cli/agents/validator-epic-ux.json +0 -93
- package/cli/agents/validator-epic-ux.md +0 -130
- package/cli/agents/validator-story-api.json +0 -104
- package/cli/agents/validator-story-api.md +0 -152
- package/cli/agents/validator-story-backend.json +0 -104
- package/cli/agents/validator-story-backend.md +0 -152
- package/cli/agents/validator-story-cloud.json +0 -104
- package/cli/agents/validator-story-cloud.md +0 -152
- package/cli/agents/validator-story-data.json +0 -104
- package/cli/agents/validator-story-data.md +0 -152
- package/cli/agents/validator-story-database.json +0 -104
- package/cli/agents/validator-story-database.md +0 -152
- package/cli/agents/validator-story-developer.json +0 -104
- package/cli/agents/validator-story-developer.md +0 -152
- package/cli/agents/validator-story-devops.json +0 -104
- package/cli/agents/validator-story-devops.md +0 -152
- package/cli/agents/validator-story-frontend.json +0 -104
- package/cli/agents/validator-story-frontend.md +0 -152
- package/cli/agents/validator-story-mobile.json +0 -104
- package/cli/agents/validator-story-mobile.md +0 -152
- package/cli/agents/validator-story-qa.json +0 -104
- package/cli/agents/validator-story-qa.md +0 -152
- package/cli/agents/validator-story-security.json +0 -104
- package/cli/agents/validator-story-security.md +0 -152
- package/cli/agents/validator-story-solution-architect.json +0 -104
- package/cli/agents/validator-story-solution-architect.md +0 -152
- package/cli/agents/validator-story-test-architect.json +0 -104
- package/cli/agents/validator-story-test-architect.md +0 -152
- package/cli/agents/validator-story-ui.json +0 -104
- package/cli/agents/validator-story-ui.md +0 -152
- package/cli/agents/validator-story-ux.json +0 -104
- package/cli/agents/validator-story-ux.md +0 -152
- package/kanban/client/dist/assets/index-CiD8PS2e.js +0 -306
- package/kanban/client/dist/assets/index-nLh0m82Q.css +0 -1
package/cli/seed-processor.js
CHANGED
|
@@ -136,8 +136,17 @@ class SeedProcessor {
|
|
|
136
136
|
*/
|
|
137
137
|
async getProviderForStageInstance(stageName) {
|
|
138
138
|
const stageConfig = this.stagesConfig?.[stageName] || {};
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
let provider = stageConfig.provider || this._providerName;
|
|
140
|
+
let model = stageConfig.model || this._modelName;
|
|
141
|
+
|
|
142
|
+
// Resolve to an available provider if current one has no credentials
|
|
143
|
+
const resolved = await LLMProvider.resolveAvailableProvider(provider, model);
|
|
144
|
+
if (resolved.fellBack) {
|
|
145
|
+
console.warn(`[WARN] ${provider} has no API key — falling back to ${resolved.provider} for stage "${stageName}"`);
|
|
146
|
+
provider = resolved.provider;
|
|
147
|
+
model = resolved.model;
|
|
148
|
+
}
|
|
149
|
+
|
|
141
150
|
const cacheKey = `${stageName}:${provider}:${model}`;
|
|
142
151
|
|
|
143
152
|
if (this._stageProviders[cacheKey]) return this._stageProviders[cacheKey];
|
|
@@ -397,6 +406,11 @@ Decompose this Story into:
|
|
|
397
406
|
|
|
398
407
|
Return your response as JSON following the exact structure specified in your instructions.`;
|
|
399
408
|
|
|
409
|
+
// If previous iteration had violations, include them so the LLM can fix
|
|
410
|
+
if (contextData._previousViolations?.length > 0) {
|
|
411
|
+
prompt += `\n\n## PREVIOUS VALIDATION ISSUES (FIX THESE)\n\nYour previous decomposition had these issues:\n${contextData._previousViolations.map(v => `- [${v.severity}] ${v.description}: ${v.fix || ''}`).join('\n')}\n\nPlease fix ALL issues in your new decomposition.`;
|
|
412
|
+
}
|
|
413
|
+
|
|
400
414
|
this.debug('[INFO] Calling LLM for Task/Subtask decomposition', {
|
|
401
415
|
provider: this._providerName,
|
|
402
416
|
model: this._modelName,
|
|
@@ -428,36 +442,134 @@ Return your response as JSON following the exact structure specified in your ins
|
|
|
428
442
|
return hierarchy;
|
|
429
443
|
}
|
|
430
444
|
|
|
431
|
-
// STAGE 4:
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
445
|
+
// STAGE 4: Structural validation (deterministic, no LLM)
|
|
446
|
+
// Returns issues array instead of throwing — enables retry loop
|
|
447
|
+
_validateStructure(hierarchy) {
|
|
448
|
+
const issues = [];
|
|
435
449
|
const { tasks } = hierarchy;
|
|
436
450
|
|
|
451
|
+
if (!tasks || !Array.isArray(tasks) || tasks.length === 0) {
|
|
452
|
+
issues.push({ severity: 'critical', category: 'structure', description: 'No tasks array in decomposition', fix: 'Return a tasks array with 2-5 tasks' });
|
|
453
|
+
return issues;
|
|
454
|
+
}
|
|
455
|
+
|
|
437
456
|
if (tasks.length < 2 || tasks.length > 5) {
|
|
438
|
-
|
|
439
|
-
sendWarning(`Expected 2-5 Tasks, got ${tasks.length}`);
|
|
457
|
+
issues.push({ severity: 'minor', category: 'structure', description: `Expected 2-5 tasks, got ${tasks.length}`, fix: `Adjust to 2-5 tasks` });
|
|
440
458
|
}
|
|
441
459
|
|
|
442
460
|
for (const task of tasks) {
|
|
461
|
+
// ID format
|
|
462
|
+
if (!task.id || !task.id.match(/^context-\d{4}-\d{4}-\d{4}[a-z]?$/)) {
|
|
463
|
+
issues.push({ severity: 'critical', category: 'structure', description: `Invalid Task ID: ${task.id}`, fix: `Use format context-XXXX-XXXX-XXXX` });
|
|
464
|
+
}
|
|
465
|
+
// Subtask count
|
|
443
466
|
const subtaskCount = task.subtasks?.length || 0;
|
|
444
467
|
if (subtaskCount < 1 || subtaskCount > 3) {
|
|
445
|
-
|
|
446
|
-
sendWarning(`Task ${task.name} has ${subtaskCount} Subtasks (expected 1-3)`);
|
|
468
|
+
issues.push({ severity: 'minor', category: 'structure', description: `Task "${task.name}" has ${subtaskCount} subtasks (expected 1-3)`, fix: 'Adjust subtask count' });
|
|
447
469
|
}
|
|
470
|
+
// Subtask IDs
|
|
471
|
+
for (const subtask of task.subtasks || []) {
|
|
472
|
+
if (!subtask.id || !subtask.id.match(/^context-\d{4}-\d{4}-\d{4}-\d{4}$/)) {
|
|
473
|
+
issues.push({ severity: 'critical', category: 'structure', description: `Invalid Subtask ID: ${subtask.id}`, fix: `Use format context-XXXX-XXXX-XXXX-XXXX` });
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
// Missing acceptance criteria
|
|
477
|
+
if (!task.acceptance || task.acceptance.length === 0) {
|
|
478
|
+
issues.push({ severity: 'major', category: 'quality', description: `Task "${task.name}" has no acceptance criteria`, fix: 'Add 2-5 testable acceptance criteria' });
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return issues;
|
|
483
|
+
}
|
|
448
484
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
485
|
+
// STAGE 4b: Semantic validation via LLM (optional, if provider available)
|
|
486
|
+
async _validateSemantics(hierarchy, contextData) {
|
|
487
|
+
try {
|
|
488
|
+
const agentInstructions = fs.readFileSync(
|
|
489
|
+
path.join(this.agentsPath, 'seed-validator.md'), 'utf8'
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
const { storyWork } = contextData;
|
|
493
|
+
const threshold = this.stagesConfig?.validation?.acceptanceThreshold ?? 80;
|
|
494
|
+
|
|
495
|
+
const prompt = `## Story\n\n**Name:** ${storyWork.name}\n**Description:** ${storyWork.description}\n**Acceptance Criteria:**\n${(storyWork.acceptance || []).map((ac, i) => `${i + 1}. ${ac}`).join('\n')}\n\n## Decomposition\n\n${JSON.stringify(hierarchy.tasks, null, 2)}\n\n## Acceptance Threshold\n${threshold}`;
|
|
496
|
+
|
|
497
|
+
const provider = await this.getProviderForStageInstance('validation');
|
|
498
|
+
const result = await provider.generateJSON(prompt, agentInstructions);
|
|
499
|
+
return result;
|
|
500
|
+
} catch (err) {
|
|
501
|
+
this.debug('[WARNING] Semantic validation failed — skipping', { error: err.message });
|
|
502
|
+
return { score: 100, passed: true, issues: [] };
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Decompose→Validate→Refine loop
|
|
507
|
+
async decomposeWithValidation(contextData, progressCallback = null) {
|
|
508
|
+
const maxIterations = this.stagesConfig?.decomposition?.maxIterationsSeed
|
|
509
|
+
?? this.stagesConfig?.maxValidationIterations ?? 3;
|
|
510
|
+
const threshold = this.stagesConfig?.validation?.acceptanceThreshold ?? 80;
|
|
511
|
+
|
|
512
|
+
let hierarchy = null;
|
|
513
|
+
let allIssues = [];
|
|
514
|
+
let bestHierarchy = null;
|
|
515
|
+
let bestScore = 0;
|
|
516
|
+
|
|
517
|
+
for (let iter = 1; iter <= maxIterations; iter++) {
|
|
518
|
+
progressCallback?.(`Decomposing story (iteration ${iter}/${maxIterations})...`);
|
|
519
|
+
this.debug(`[INFO] Decompose iteration ${iter}/${maxIterations}`);
|
|
520
|
+
|
|
521
|
+
// Inject violations from previous iteration into context
|
|
522
|
+
if (allIssues.length > 0) {
|
|
523
|
+
contextData._previousViolations = allIssues;
|
|
452
524
|
}
|
|
453
525
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
526
|
+
hierarchy = await this.decomposeIntoTasksSubtasks(contextData);
|
|
527
|
+
|
|
528
|
+
// Structural validation (deterministic)
|
|
529
|
+
const structuralIssues = this._validateStructure(hierarchy);
|
|
530
|
+
const hasCritical = structuralIssues.some(i => i.severity === 'critical');
|
|
531
|
+
|
|
532
|
+
if (hasCritical) {
|
|
533
|
+
this.debug(`[WARNING] Structural issues (iter ${iter})`, { issues: structuralIssues });
|
|
534
|
+
allIssues = structuralIssues;
|
|
535
|
+
if (iter === maxIterations) {
|
|
536
|
+
this.debug('[ERROR] Max iterations with critical structural issues — using best result');
|
|
537
|
+
break;
|
|
458
538
|
}
|
|
539
|
+
continue; // Retry — don't bother with semantic validation if structure is broken
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Semantic validation (LLM)
|
|
543
|
+
progressCallback?.(`Validating decomposition (iteration ${iter}/${maxIterations})...`);
|
|
544
|
+
const semanticResult = await this._validateSemantics(hierarchy, contextData);
|
|
545
|
+
const score = semanticResult?.score ?? 100;
|
|
546
|
+
|
|
547
|
+
// Track best result
|
|
548
|
+
if (score > bestScore) {
|
|
549
|
+
bestScore = score;
|
|
550
|
+
bestHierarchy = JSON.parse(JSON.stringify(hierarchy));
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
allIssues = [
|
|
554
|
+
...structuralIssues,
|
|
555
|
+
...(semanticResult?.issues || []),
|
|
556
|
+
];
|
|
557
|
+
|
|
558
|
+
this.debug(`[INFO] Validation result (iter ${iter})`, { score, issueCount: allIssues.length, passed: semanticResult?.passed });
|
|
559
|
+
|
|
560
|
+
if (semanticResult?.passed || score >= threshold) {
|
|
561
|
+
progressCallback?.(`Validation passed (score: ${score}, threshold: ${threshold})`);
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (iter === maxIterations) {
|
|
566
|
+
progressCallback?.(`Max iterations — accepting score ${score} (threshold: ${threshold})`);
|
|
567
|
+
this.debug(`[WARNING] Max iterations reached — accepting best score ${bestScore}`);
|
|
459
568
|
}
|
|
460
569
|
}
|
|
570
|
+
|
|
571
|
+
// Use best result if final iteration didn't improve
|
|
572
|
+
return bestHierarchy && bestScore > (hierarchy?._score ?? 0) ? bestHierarchy : hierarchy;
|
|
461
573
|
}
|
|
462
574
|
|
|
463
575
|
// STAGE 5-6: Generate contexts
|
|
@@ -723,13 +835,9 @@ Return your response as JSON following the exact structure specified in your ins
|
|
|
723
835
|
sendInfo('Reading Story context...');
|
|
724
836
|
const contextData = this.readStoryContext();
|
|
725
837
|
|
|
726
|
-
// Stage 3: Decompose
|
|
727
|
-
this.debug('[INFO] Stage 2b: Decomposing Story
|
|
728
|
-
let hierarchy = await this.
|
|
729
|
-
|
|
730
|
-
// Stage 4: Validate
|
|
731
|
-
this.debug('[INFO] Stage 2c: Validating decomposition structure');
|
|
732
|
-
this.validateTaskSubtaskStructure(hierarchy);
|
|
838
|
+
// Stage 3+4: Decompose with validation loop
|
|
839
|
+
this.debug('[INFO] Stage 2b: Decomposing Story with validation loop');
|
|
840
|
+
let hierarchy = await this.decomposeWithValidation(contextData);
|
|
733
841
|
|
|
734
842
|
// Stage 5-7: Generate contexts and write files
|
|
735
843
|
this.debug('[INFO] Stage 2/3: Generating context files and writing to disk');
|
|
@@ -789,4 +897,66 @@ Return your response as JSON following the exact structure specified in your ins
|
|
|
789
897
|
}
|
|
790
898
|
}
|
|
791
899
|
|
|
900
|
+
/**
|
|
901
|
+
* Worker-compatible execution — uses callbacks instead of REPL output functions.
|
|
902
|
+
* Called by seed-worker.js (forked process).
|
|
903
|
+
*
|
|
904
|
+
* @param {Function} progressCallback - (message, substep?, meta?) → void
|
|
905
|
+
* @param {Function} [itemWrittenCallback] - ({ itemId, itemType }) → void
|
|
906
|
+
* @param {Function} [cancelledCheck] - () → boolean, returns true if cancelled
|
|
907
|
+
* @returns {Promise<{ taskCount: number, subtaskCount: number, taskIds: string[] }>}
|
|
908
|
+
*/
|
|
909
|
+
async executeWithCallback(progressCallback, itemWrittenCallback = null, cancelledCheck = null) {
|
|
910
|
+
const execStartTime = Date.now();
|
|
911
|
+
this.debug('[INFO] SeedProcessor.executeWithCallback() started', {
|
|
912
|
+
storyId: this.storyId,
|
|
913
|
+
provider: this._providerName,
|
|
914
|
+
model: this._modelName,
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
// Stage 1: Validate
|
|
918
|
+
progressCallback?.('Validating prerequisites...');
|
|
919
|
+
if (cancelledCheck?.()) throw new Error('CEREMONY_CANCELLED');
|
|
920
|
+
this.validatePrerequisites();
|
|
921
|
+
|
|
922
|
+
// Stage 2a: Read context
|
|
923
|
+
progressCallback?.('Reading story context...');
|
|
924
|
+
if (cancelledCheck?.()) throw new Error('CEREMONY_CANCELLED');
|
|
925
|
+
const contextData = this.readStoryContext();
|
|
926
|
+
|
|
927
|
+
// Stage 2b+2c: Decompose with validation loop
|
|
928
|
+
if (cancelledCheck?.()) throw new Error('CEREMONY_CANCELLED');
|
|
929
|
+
let hierarchy = await this.decomposeWithValidation(contextData, progressCallback);
|
|
930
|
+
|
|
931
|
+
// Stage 3: Write files
|
|
932
|
+
progressCallback?.('Writing task and subtask files...');
|
|
933
|
+
if (cancelledCheck?.()) throw new Error('CEREMONY_CANCELLED');
|
|
934
|
+
|
|
935
|
+
// Temporarily override _itemWrittenCallback on writeTaskSubtaskFiles
|
|
936
|
+
const origCallback = this._itemWrittenCallback;
|
|
937
|
+
this._itemWrittenCallback = itemWrittenCallback;
|
|
938
|
+
const { taskCount, subtaskCount, taskIds } = await this.writeTaskSubtaskFiles(hierarchy, contextData);
|
|
939
|
+
this._itemWrittenCallback = origCallback;
|
|
940
|
+
|
|
941
|
+
// Stage 4: Update parent story
|
|
942
|
+
progressCallback?.('Updating story metadata...');
|
|
943
|
+
this.updateStoryWorkJson(taskIds);
|
|
944
|
+
|
|
945
|
+
// Finalize token tracking
|
|
946
|
+
if (this.llmProvider) {
|
|
947
|
+
this.tokenTracker.finalizeRun(this.ceremonyName);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
const duration = Date.now() - execStartTime;
|
|
951
|
+
this.debug('[INFO] SeedProcessor.executeWithCallback() complete', {
|
|
952
|
+
storyId: this.storyId,
|
|
953
|
+
duration: `${duration}ms`,
|
|
954
|
+
taskCount,
|
|
955
|
+
subtaskCount,
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
return { taskCount, subtaskCount, taskIds };
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
792
962
|
export { SeedProcessor };
|