scene-capability-engine 3.0.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/CHANGELOG.md +2513 -0
- package/LICENSE +21 -0
- package/README.md +765 -0
- package/README.zh.md +630 -0
- package/bin/kiro-spec-engine.js +796 -0
- package/bin/kse.js +3 -0
- package/bin/sce.js +3 -0
- package/bin/sco.js +3 -0
- package/docs/331-poc-adaptation-roadmap.md +156 -0
- package/docs/331-poc-dual-track-integration-guide.md +120 -0
- package/docs/331-poc-weekly-delivery-checklist.md +52 -0
- package/docs/OFFLINE_INSTALL.md +96 -0
- package/docs/README.md +279 -0
- package/docs/adopt-migration-guide.md +599 -0
- package/docs/adoption-guide.md +616 -0
- package/docs/agent-hooks-analysis.md +815 -0
- package/docs/architecture.md +733 -0
- package/docs/articles/ai-driven-development-philosophy-and-practice-review.md +208 -0
- package/docs/articles/ai-driven-development-philosophy-and-practice.en.md +459 -0
- package/docs/articles/ai-driven-development-philosophy-and-practice.md +492 -0
- package/docs/autonomous-control-guide.md +851 -0
- package/docs/command-reference.md +1368 -0
- package/docs/community.md +115 -0
- package/docs/cross-tool-guide.md +555 -0
- package/docs/developer-guide.md +619 -0
- package/docs/document-governance.md +865 -0
- package/docs/environment-management-guide.md +526 -0
- package/docs/examples/add-export-command/design.md +194 -0
- package/docs/examples/add-export-command/requirements.md +110 -0
- package/docs/examples/add-export-command/tasks.md +88 -0
- package/docs/examples/add-rest-api/design.md +855 -0
- package/docs/examples/add-rest-api/requirements.md +323 -0
- package/docs/examples/add-rest-api/tasks.md +355 -0
- package/docs/examples/add-user-dashboard/design.md +192 -0
- package/docs/examples/add-user-dashboard/requirements.md +143 -0
- package/docs/examples/add-user-dashboard/tasks.md +91 -0
- package/docs/faq.md +697 -0
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.json +156 -0
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.md +24 -0
- package/docs/images/wechat-qr.png +0 -0
- package/docs/integration-modes.md +529 -0
- package/docs/integration-philosophy.md +313 -0
- package/docs/knowledge-management-guide.md +263 -0
- package/docs/manual-workflows-guide.md +418 -0
- package/docs/moqui-capability-matrix.md +73 -0
- package/docs/moqui-template-core-library-playbook.md +109 -0
- package/docs/multi-agent-coordination-guide.md +553 -0
- package/docs/multi-repo-management-guide.md +1344 -0
- package/docs/quick-start-with-ai-tools.md +375 -0
- package/docs/quick-start.md +146 -0
- package/docs/release-checklist.md +121 -0
- package/docs/releases/README.md +13 -0
- package/docs/releases/v1.46.2-validation.md +45 -0
- package/docs/releases/v1.46.2.md +50 -0
- package/docs/scene-runtime-guide.md +347 -0
- package/docs/spec-collaboration-guide.md +369 -0
- package/docs/spec-locking-guide.md +225 -0
- package/docs/spec-numbering-guide.md +348 -0
- package/docs/spec-workflow.md +519 -0
- package/docs/steering-strategy-guide.md +196 -0
- package/docs/team-collaboration-guide.md +465 -0
- package/docs/testing-strategy.md +272 -0
- package/docs/tools/claude-guide.md +654 -0
- package/docs/tools/cursor-guide.md +706 -0
- package/docs/tools/generic-guide.md +446 -0
- package/docs/tools/kiro-guide.md +308 -0
- package/docs/tools/vscode-guide.md +445 -0
- package/docs/tools/windsurf-guide.md +391 -0
- package/docs/troubleshooting.md +1135 -0
- package/docs/upgrade-guide.md +639 -0
- package/docs/value-observability-guide.md +127 -0
- package/docs/zh/README.md +341 -0
- package/docs/zh/quick-start.md +764 -0
- package/docs/zh/release-checklist.md +121 -0
- package/docs/zh/releases/README.md +13 -0
- package/docs/zh/releases/v1.46.2-validation.md +45 -0
- package/docs/zh/releases/v1.46.2.md +50 -0
- package/docs/zh/spec-numbering-guide.md +348 -0
- package/docs/zh/tools/claude-guide.md +349 -0
- package/docs/zh/tools/cursor-guide.md +281 -0
- package/docs/zh/tools/generic-guide.md +499 -0
- package/docs/zh/tools/kiro-guide.md +342 -0
- package/docs/zh/tools/vscode-guide.md +449 -0
- package/docs/zh/tools/windsurf-guide.md +378 -0
- package/docs/zh/value-observability-guide.md +127 -0
- package/docs//344/272/244/344/273/230/346/270/205/345/215/225.md +75 -0
- package/lib/adoption/adoption-logger.js +487 -0
- package/lib/adoption/adoption-strategy.js +538 -0
- package/lib/adoption/backup-manager.js +420 -0
- package/lib/adoption/conflict-resolver.js +410 -0
- package/lib/adoption/detection-engine.js +275 -0
- package/lib/adoption/diff-viewer.js +226 -0
- package/lib/adoption/error-formatter.js +509 -0
- package/lib/adoption/file-classifier.js +385 -0
- package/lib/adoption/progress-reporter.js +534 -0
- package/lib/adoption/smart-orchestrator.js +470 -0
- package/lib/adoption/strategy-selector.js +218 -0
- package/lib/adoption/summary-generator.js +493 -0
- package/lib/adoption/template-sync.js +605 -0
- package/lib/auto/autonomous-engine.js +485 -0
- package/lib/auto/checkpoint-manager.js +300 -0
- package/lib/auto/close-loop-runner.js +2476 -0
- package/lib/auto/config-schema.js +176 -0
- package/lib/auto/decision-engine.js +344 -0
- package/lib/auto/error-recovery-manager.js +580 -0
- package/lib/auto/goal-decomposer.js +278 -0
- package/lib/auto/progress-tracker.js +502 -0
- package/lib/auto/safety-manager.js +186 -0
- package/lib/auto/semantic-decomposer.js +137 -0
- package/lib/auto/state-manager.js +126 -0
- package/lib/auto/task-queue-manager.js +340 -0
- package/lib/backup/backup-system.js +372 -0
- package/lib/backup/selective-backup.js +207 -0
- package/lib/collab/agent-registry.js +240 -0
- package/lib/collab/collab-manager.js +285 -0
- package/lib/collab/contract-manager.js +320 -0
- package/lib/collab/coordinator.js +370 -0
- package/lib/collab/dependency-manager.js +280 -0
- package/lib/collab/index.js +20 -0
- package/lib/collab/integration-manager.js +202 -0
- package/lib/collab/merge-coordinator.js +252 -0
- package/lib/collab/metadata-manager.js +233 -0
- package/lib/collab/multi-agent-config.js +120 -0
- package/lib/collab/spec-lifecycle-manager.js +304 -0
- package/lib/collab/sync-barrier.js +88 -0
- package/lib/collab/visualizer.js +208 -0
- package/lib/commands/adopt.js +749 -0
- package/lib/commands/auto.js +19559 -0
- package/lib/commands/collab.js +275 -0
- package/lib/commands/context.js +99 -0
- package/lib/commands/docs.js +808 -0
- package/lib/commands/doctor.js +273 -0
- package/lib/commands/env.js +420 -0
- package/lib/commands/knowledge.js +309 -0
- package/lib/commands/lock.js +235 -0
- package/lib/commands/ops.js +409 -0
- package/lib/commands/orchestrate.js +446 -0
- package/lib/commands/prompt.js +105 -0
- package/lib/commands/repo.js +118 -0
- package/lib/commands/rollback.js +219 -0
- package/lib/commands/scene.js +15549 -0
- package/lib/commands/spec-bootstrap.js +147 -0
- package/lib/commands/spec-gate.js +157 -0
- package/lib/commands/spec-pipeline.js +205 -0
- package/lib/commands/status.js +321 -0
- package/lib/commands/task.js +199 -0
- package/lib/commands/templates.js +654 -0
- package/lib/commands/upgrade.js +231 -0
- package/lib/commands/value.js +569 -0
- package/lib/commands/watch.js +684 -0
- package/lib/commands/workflows.js +240 -0
- package/lib/commands/workspace-multi.js +325 -0
- package/lib/commands/workspace.js +189 -0
- package/lib/context/context-exporter.js +378 -0
- package/lib/context/prompt-generator.js +482 -0
- package/lib/data/moqui-capability-lexicon.json +45 -0
- package/lib/environment/backup-system.js +189 -0
- package/lib/environment/environment-manager.js +379 -0
- package/lib/environment/environment-registry.js +168 -0
- package/lib/gitignore/gitignore-backup.js +229 -0
- package/lib/gitignore/gitignore-detector.js +239 -0
- package/lib/gitignore/gitignore-integration.js +267 -0
- package/lib/gitignore/gitignore-transformer.js +193 -0
- package/lib/gitignore/layered-rules-template.js +42 -0
- package/lib/governance/archive-tool.js +284 -0
- package/lib/governance/cleanup-tool.js +237 -0
- package/lib/governance/config-manager.js +186 -0
- package/lib/governance/diagnostic-engine.js +271 -0
- package/lib/governance/doc-reference-checker.js +200 -0
- package/lib/governance/execution-logger.js +243 -0
- package/lib/governance/file-scanner.js +285 -0
- package/lib/governance/hooks-manager.js +333 -0
- package/lib/governance/reporter.js +337 -0
- package/lib/governance/validation-engine.js +181 -0
- package/lib/i18n.js +79 -0
- package/lib/knowledge/entry-manager.js +208 -0
- package/lib/knowledge/index-manager.js +261 -0
- package/lib/knowledge/knowledge-manager.js +273 -0
- package/lib/knowledge/template-manager.js +191 -0
- package/lib/lock/index.js +21 -0
- package/lib/lock/lock-file.js +192 -0
- package/lib/lock/lock-manager.js +321 -0
- package/lib/lock/machine-identifier.js +135 -0
- package/lib/lock/steering-file-lock.js +207 -0
- package/lib/lock/task-lock-manager.js +345 -0
- package/lib/operations/audit-logger.js +293 -0
- package/lib/operations/feedback-manager.js +1147 -0
- package/lib/operations/index.js +23 -0
- package/lib/operations/models/index.js +170 -0
- package/lib/operations/operations-manager.js +151 -0
- package/lib/operations/operations-validator.js +280 -0
- package/lib/operations/permission-manager.js +354 -0
- package/lib/operations/template-loader.js +143 -0
- package/lib/orchestrator/agent-spawner.js +629 -0
- package/lib/orchestrator/bootstrap-prompt-builder.js +236 -0
- package/lib/orchestrator/index.js +19 -0
- package/lib/orchestrator/orchestration-engine.js +1270 -0
- package/lib/orchestrator/orchestrator-config.js +173 -0
- package/lib/orchestrator/status-monitor.js +591 -0
- package/lib/python-checker.js +209 -0
- package/lib/repo/config-manager.js +580 -0
- package/lib/repo/errors/config-error.js +13 -0
- package/lib/repo/errors/git-error.js +15 -0
- package/lib/repo/errors/repo-error.js +14 -0
- package/lib/repo/git-operations.js +181 -0
- package/lib/repo/handlers/.gitkeep +1 -0
- package/lib/repo/handlers/exec-handler.js +155 -0
- package/lib/repo/handlers/health-handler.js +169 -0
- package/lib/repo/handlers/init-handler.js +197 -0
- package/lib/repo/handlers/status-handler.js +176 -0
- package/lib/repo/output-formatter.js +184 -0
- package/lib/repo/path-resolver.js +178 -0
- package/lib/repo/repo-manager.js +514 -0
- package/lib/scene-runtime/audit-emitter.js +59 -0
- package/lib/scene-runtime/binding-plugin-loader.js +351 -0
- package/lib/scene-runtime/binding-registry.js +349 -0
- package/lib/scene-runtime/eval-bridge.js +44 -0
- package/lib/scene-runtime/index.js +19 -0
- package/lib/scene-runtime/moqui-adapter.js +620 -0
- package/lib/scene-runtime/moqui-client.js +606 -0
- package/lib/scene-runtime/moqui-extractor.js +2029 -0
- package/lib/scene-runtime/plan-compiler.js +208 -0
- package/lib/scene-runtime/policy-gate.js +58 -0
- package/lib/scene-runtime/runtime-executor.js +358 -0
- package/lib/scene-runtime/scene-loader.js +96 -0
- package/lib/scene-runtime/scene-ontology.js +959 -0
- package/lib/scene-runtime/scene-template-linter.js +852 -0
- package/lib/scene-runtime/templates/scene-template-erp-query-v0.1.yaml +28 -0
- package/lib/scene-runtime/templates/scene-template-hybrid-shadow-v0.1.yaml +34 -0
- package/lib/spec/bootstrap/context-collector.js +48 -0
- package/lib/spec/bootstrap/draft-generator.js +158 -0
- package/lib/spec/bootstrap/questionnaire-engine.js +70 -0
- package/lib/spec/bootstrap/trace-emitter.js +59 -0
- package/lib/spec/multi-spec-orchestrate.js +93 -0
- package/lib/spec/pipeline/constants.js +6 -0
- package/lib/spec/pipeline/stage-adapters.js +118 -0
- package/lib/spec/pipeline/stage-runner.js +146 -0
- package/lib/spec/pipeline/state-store.js +119 -0
- package/lib/spec-gate/engine/gate-engine.js +165 -0
- package/lib/spec-gate/policy/default-policy.js +22 -0
- package/lib/spec-gate/policy/policy-loader.js +103 -0
- package/lib/spec-gate/result-emitter.js +81 -0
- package/lib/spec-gate/rules/default-rules.js +156 -0
- package/lib/spec-gate/rules/rule-registry.js +51 -0
- package/lib/steering/adoption-config.js +164 -0
- package/lib/steering/compliance-auto-fixer.js +204 -0
- package/lib/steering/compliance-cache.js +99 -0
- package/lib/steering/compliance-error-reporter.js +70 -0
- package/lib/steering/context-sync-manager.js +273 -0
- package/lib/steering/index.js +92 -0
- package/lib/steering/spec-steering.js +230 -0
- package/lib/steering/steering-compliance-checker.js +73 -0
- package/lib/steering/steering-loader.js +144 -0
- package/lib/steering/steering-manager.js +289 -0
- package/lib/task/index.js +12 -0
- package/lib/task/task-claimer.js +489 -0
- package/lib/task/task-status-store.js +418 -0
- package/lib/templates/cache-manager.js +440 -0
- package/lib/templates/content-generalizer.js +247 -0
- package/lib/templates/frontmatter-generator.js +128 -0
- package/lib/templates/git-handler.js +471 -0
- package/lib/templates/metadata-collector.js +328 -0
- package/lib/templates/path-utils.js +144 -0
- package/lib/templates/registry-parser.js +505 -0
- package/lib/templates/spec-reader.js +216 -0
- package/lib/templates/template-applicator.js +249 -0
- package/lib/templates/template-creator.js +256 -0
- package/lib/templates/template-error.js +143 -0
- package/lib/templates/template-exporter.js +502 -0
- package/lib/templates/template-manager.js +782 -0
- package/lib/templates/template-validator.js +361 -0
- package/lib/upgrade/migration-engine.js +382 -0
- package/lib/upgrade/migrations/.gitkeep +52 -0
- package/lib/upgrade/migrations/1.0.0-to-1.1.0.js +78 -0
- package/lib/utils/file-diff.js +177 -0
- package/lib/utils/fs-utils.js +274 -0
- package/lib/utils/tool-detector.js +383 -0
- package/lib/utils/validation.js +324 -0
- package/lib/value/gate-summary-emitter.js +99 -0
- package/lib/value/metric-contract-loader.js +210 -0
- package/lib/value/risk-evaluator.js +117 -0
- package/lib/value/weekly-snapshot-builder.js +61 -0
- package/lib/version/version-checker.js +156 -0
- package/lib/version/version-manager.js +327 -0
- package/lib/watch/action-executor.js +458 -0
- package/lib/watch/event-debouncer.js +323 -0
- package/lib/watch/execution-logger.js +550 -0
- package/lib/watch/file-watcher.js +499 -0
- package/lib/watch/presets.js +266 -0
- package/lib/watch/watch-manager.js +533 -0
- package/lib/workspace/multi/global-config.js +150 -0
- package/lib/workspace/multi/index.js +22 -0
- package/lib/workspace/multi/path-utils.js +173 -0
- package/lib/workspace/multi/workspace-context-resolver.js +244 -0
- package/lib/workspace/multi/workspace-registry.js +196 -0
- package/lib/workspace/multi/workspace-state-manager.js +537 -0
- package/lib/workspace/multi/workspace.js +90 -0
- package/lib/workspace/workspace-manager.js +370 -0
- package/lib/workspace/workspace-sync.js +356 -0
- package/locales/en.json +114 -0
- package/locales/zh.json +114 -0
- package/package.json +102 -0
- package/template/.kiro/README.md +247 -0
- package/template/.kiro/hooks/check-spec-on-create.kiro.hook +17 -0
- package/template/.kiro/hooks/run-tests-on-save.kiro.hook +13 -0
- package/template/.kiro/hooks/sync-tasks-on-edit.kiro.hook +16 -0
- package/template/.kiro/specs/SPEC_WORKFLOW_GUIDE.md +134 -0
- package/template/.kiro/steering/CORE_PRINCIPLES.md +133 -0
- package/template/.kiro/steering/CURRENT_CONTEXT.md +30 -0
- package/template/.kiro/steering/ENVIRONMENT.md +35 -0
- package/template/.kiro/steering/RULES_GUIDE.md +46 -0
- package/template/.kiro/templates/operations/default/change-impact.md +112 -0
- package/template/.kiro/templates/operations/default/deployment.md +91 -0
- package/template/.kiro/templates/operations/default/feedback-response.md +269 -0
- package/template/.kiro/templates/operations/default/migration-plan.md +172 -0
- package/template/.kiro/templates/operations/default/monitoring.md +135 -0
- package/template/.kiro/templates/operations/default/operations.md +135 -0
- package/template/.kiro/templates/operations/default/rollback.md +143 -0
- package/template/.kiro/templates/operations/default/tools.yaml +364 -0
- package/template/.kiro/templates/operations/default/troubleshooting.md +123 -0
- package/template/.kiro/tools/backup_manager.py +295 -0
- package/template/.kiro/tools/configuration_manager.py +218 -0
- package/template/.kiro/tools/document_evaluator.py +550 -0
- package/template/.kiro/tools/enhancement_logger.py +168 -0
- package/template/.kiro/tools/error_handler.py +335 -0
- package/template/.kiro/tools/improvement_identifier.py +444 -0
- package/template/.kiro/tools/modification_applicator.py +737 -0
- package/template/.kiro/tools/quality_gate_enforcer.py +207 -0
- package/template/.kiro/tools/quality_scorer.py +305 -0
- package/template/.kiro/tools/report_generator.py +154 -0
- package/template/.kiro/tools/ultrawork_enhancer.py +676 -0
- package/template/.kiro/tools/ultrawork_enhancer_refactored.py +0 -0
- package/template/.kiro/tools/ultrawork_enhancer_v2.py +463 -0
- package/template/.kiro/tools/ultrawork_enhancer_v3.py +606 -0
- package/template/.kiro/tools/workflow_quality_gate.py +100 -0
- package/template/README.md +111 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DependencyManager handles dependency graph analysis and validation
|
|
3
|
+
*/
|
|
4
|
+
class DependencyManager {
|
|
5
|
+
constructor(metadataManager) {
|
|
6
|
+
this.metadataManager = metadataManager;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Build dependency graph from specs
|
|
11
|
+
* @param {Array<string>} specNames - Optional list of spec names (defaults to all)
|
|
12
|
+
* @returns {Promise<Object>} Graph with nodes and edges
|
|
13
|
+
*/
|
|
14
|
+
async buildDependencyGraph(specNames = null) {
|
|
15
|
+
const allSpecs = await this.metadataManager.listAllMetadata();
|
|
16
|
+
const specsToInclude = specNames
|
|
17
|
+
? allSpecs.filter(s => specNames.includes(s.name))
|
|
18
|
+
: allSpecs;
|
|
19
|
+
|
|
20
|
+
const nodes = [];
|
|
21
|
+
const edges = [];
|
|
22
|
+
|
|
23
|
+
for (const { name, metadata } of specsToInclude) {
|
|
24
|
+
// Add node
|
|
25
|
+
nodes.push({
|
|
26
|
+
id: name,
|
|
27
|
+
status: metadata.status?.current || 'not-started',
|
|
28
|
+
kiroInstance: metadata.assignment?.kiroInstance || null,
|
|
29
|
+
type: metadata.type
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Add edges from dependencies
|
|
33
|
+
if (metadata.dependencies) {
|
|
34
|
+
for (const dep of metadata.dependencies) {
|
|
35
|
+
edges.push({
|
|
36
|
+
from: name,
|
|
37
|
+
to: dep.spec,
|
|
38
|
+
type: dep.type,
|
|
39
|
+
reason: dep.reason
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return { nodes, edges };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Detect circular dependencies in graph
|
|
50
|
+
* @param {Object} graph - Graph with nodes and edges
|
|
51
|
+
* @returns {Array<string>|null} Cycle path if found, null otherwise
|
|
52
|
+
*/
|
|
53
|
+
detectCircularDependencies(graph) {
|
|
54
|
+
const visited = new Set();
|
|
55
|
+
const recursionStack = new Set();
|
|
56
|
+
const path = [];
|
|
57
|
+
|
|
58
|
+
const hasCycle = (nodeId) => {
|
|
59
|
+
visited.add(nodeId);
|
|
60
|
+
recursionStack.add(nodeId);
|
|
61
|
+
path.push(nodeId);
|
|
62
|
+
|
|
63
|
+
// Get outgoing edges
|
|
64
|
+
const outgoing = graph.edges.filter(e => e.from === nodeId);
|
|
65
|
+
|
|
66
|
+
for (const edge of outgoing) {
|
|
67
|
+
if (!visited.has(edge.to)) {
|
|
68
|
+
if (hasCycle(edge.to)) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
} else if (recursionStack.has(edge.to)) {
|
|
72
|
+
// Found cycle
|
|
73
|
+
path.push(edge.to);
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
recursionStack.delete(nodeId);
|
|
79
|
+
path.pop();
|
|
80
|
+
return false;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
for (const node of graph.nodes) {
|
|
84
|
+
if (!visited.has(node.id)) {
|
|
85
|
+
if (hasCycle(node.id)) {
|
|
86
|
+
return path;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get specs that are ready to start (all dependencies satisfied)
|
|
96
|
+
* @param {Object} graph - Graph with nodes and edges
|
|
97
|
+
* @returns {Array<string>} List of ready spec names
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
getReadySpecs(graph) {
|
|
101
|
+
const ready = [];
|
|
102
|
+
|
|
103
|
+
for (const node of graph.nodes) {
|
|
104
|
+
// Skip if already completed or in progress
|
|
105
|
+
if (node.status === 'completed' || node.status === 'in-progress') {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Skip if blocked
|
|
110
|
+
if (node.status === 'blocked') {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Get dependencies for this node
|
|
115
|
+
const dependencies = graph.edges.filter(e => e.from === node.id);
|
|
116
|
+
|
|
117
|
+
// Check if all required dependencies are satisfied
|
|
118
|
+
const allSatisfied = dependencies.every(dep => {
|
|
119
|
+
// Optional dependencies don't block
|
|
120
|
+
if (dep.type === 'optional') {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Find the dependency node
|
|
125
|
+
const depNode = graph.nodes.find(n => n.id === dep.to);
|
|
126
|
+
|
|
127
|
+
if (!depNode) {
|
|
128
|
+
// Dependency not found - not ready
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// For requires-completion, dependency must be completed
|
|
133
|
+
if (dep.type === 'requires-completion') {
|
|
134
|
+
return depNode.status === 'completed';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// For requires-interface, dependency must have interface defined
|
|
138
|
+
// (we'll check this in contract manager)
|
|
139
|
+
if (dep.type === 'requires-interface') {
|
|
140
|
+
return depNode.status === 'completed' || depNode.status === 'in-progress';
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return false;
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
if (allSatisfied) {
|
|
147
|
+
ready.push(node.id);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return ready;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get critical path (longest dependency chain)
|
|
156
|
+
* @param {Object} graph - Graph with nodes and edges
|
|
157
|
+
* @returns {Array<string>} Spec names in critical path
|
|
158
|
+
*/
|
|
159
|
+
getCriticalPath(graph) {
|
|
160
|
+
const memo = new Map();
|
|
161
|
+
|
|
162
|
+
const getLongestPath = (nodeId) => {
|
|
163
|
+
if (memo.has(nodeId)) {
|
|
164
|
+
return memo.get(nodeId);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Get incoming edges (dependencies)
|
|
168
|
+
const incoming = graph.edges.filter(e => e.to === nodeId);
|
|
169
|
+
|
|
170
|
+
if (incoming.length === 0) {
|
|
171
|
+
memo.set(nodeId, [nodeId]);
|
|
172
|
+
return [nodeId];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let longestPath = [];
|
|
176
|
+
for (const edge of incoming) {
|
|
177
|
+
const path = getLongestPath(edge.from);
|
|
178
|
+
if (path.length > longestPath.length) {
|
|
179
|
+
longestPath = path;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const result = [...longestPath, nodeId];
|
|
184
|
+
memo.set(nodeId, result);
|
|
185
|
+
return result;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
let criticalPath = [];
|
|
189
|
+
for (const node of graph.nodes) {
|
|
190
|
+
const path = getLongestPath(node.id);
|
|
191
|
+
if (path.length > criticalPath.length) {
|
|
192
|
+
criticalPath = path;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return criticalPath;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Validate a dependency relationship
|
|
201
|
+
* @param {string} fromSpec - Spec that depends on another
|
|
202
|
+
* @param {string} toSpec - Spec being depended on
|
|
203
|
+
* @param {string} type - Dependency type
|
|
204
|
+
* @returns {Promise<Object>} Validation result
|
|
205
|
+
*/
|
|
206
|
+
async validateDependency(fromSpec, toSpec, type) {
|
|
207
|
+
// Check if specs exist
|
|
208
|
+
const fromMetadata = await this.metadataManager.readMetadata(fromSpec);
|
|
209
|
+
const toMetadata = await this.metadataManager.readMetadata(toSpec);
|
|
210
|
+
|
|
211
|
+
if (!fromMetadata) {
|
|
212
|
+
return {
|
|
213
|
+
valid: false,
|
|
214
|
+
error: `Spec '${fromSpec}' not found`
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (!toMetadata) {
|
|
219
|
+
return {
|
|
220
|
+
valid: false,
|
|
221
|
+
error: `Dependency '${toSpec}' not found`
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Check for self-dependency
|
|
226
|
+
if (fromSpec === toSpec) {
|
|
227
|
+
return {
|
|
228
|
+
valid: false,
|
|
229
|
+
error: 'Spec cannot depend on itself'
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Build graph with new dependency and check for cycles
|
|
234
|
+
const graph = await this.buildDependencyGraph();
|
|
235
|
+
|
|
236
|
+
// Add the new edge temporarily
|
|
237
|
+
graph.edges.push({ from: fromSpec, to: toSpec, type });
|
|
238
|
+
|
|
239
|
+
const cycle = this.detectCircularDependencies(graph);
|
|
240
|
+
if (cycle) {
|
|
241
|
+
return {
|
|
242
|
+
valid: false,
|
|
243
|
+
error: `Circular dependency detected: ${cycle.join(' → ')}`
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return { valid: true };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Update dependent specs when a spec is completed
|
|
252
|
+
* @param {string} completedSpec - Name of completed spec
|
|
253
|
+
* @returns {Promise<Array<string>>} List of specs that became ready
|
|
254
|
+
*/
|
|
255
|
+
async updateDependentSpecs(completedSpec) {
|
|
256
|
+
const graph = await this.buildDependencyGraph();
|
|
257
|
+
|
|
258
|
+
// Find specs that depend on the completed spec
|
|
259
|
+
const dependents = graph.edges
|
|
260
|
+
.filter(e => e.to === completedSpec)
|
|
261
|
+
.map(e => e.from);
|
|
262
|
+
|
|
263
|
+
// Check which dependents are now ready
|
|
264
|
+
const nowReady = [];
|
|
265
|
+
for (const depSpec of dependents) {
|
|
266
|
+
const depMetadata = await this.metadataManager.readMetadata(depSpec);
|
|
267
|
+
if (depMetadata && depMetadata.status.current === 'not-started') {
|
|
268
|
+
// Check if all dependencies are satisfied
|
|
269
|
+
const ready = this.getReadySpecs(graph);
|
|
270
|
+
if (ready.includes(depSpec)) {
|
|
271
|
+
nowReady.push(depSpec);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return nowReady;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
module.exports = DependencyManager;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collab module exports
|
|
3
|
+
* @module lib/collab
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { AgentRegistry } = require('./agent-registry');
|
|
7
|
+
const { Coordinator } = require('./coordinator');
|
|
8
|
+
const { MergeCoordinator } = require('./merge-coordinator');
|
|
9
|
+
const { MultiAgentConfig } = require('./multi-agent-config');
|
|
10
|
+
const { SpecLifecycleManager } = require('./spec-lifecycle-manager');
|
|
11
|
+
const { SyncBarrier } = require('./sync-barrier');
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
AgentRegistry,
|
|
15
|
+
Coordinator,
|
|
16
|
+
MergeCoordinator,
|
|
17
|
+
MultiAgentConfig,
|
|
18
|
+
SpecLifecycleManager,
|
|
19
|
+
SyncBarrier
|
|
20
|
+
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
const fs = require('fs').promises;
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* IntegrationManager handles cross-Spec integration testing
|
|
6
|
+
*/
|
|
7
|
+
class IntegrationManager {
|
|
8
|
+
constructor(workspaceRoot, metadataManager) {
|
|
9
|
+
this.workspaceRoot = workspaceRoot;
|
|
10
|
+
this.metadataManager = metadataManager;
|
|
11
|
+
this.specsDir = path.join(workspaceRoot, '.kiro', 'specs');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Discover integration tests for a spec
|
|
16
|
+
* @param {string} specName - Name of the spec
|
|
17
|
+
* @returns {Promise<Array<string>>} List of test file paths
|
|
18
|
+
*/
|
|
19
|
+
async discoverTests(specName) {
|
|
20
|
+
const testsDir = path.join(this.specsDir, specName, 'integration-tests');
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const files = await fs.readdir(testsDir);
|
|
24
|
+
return files
|
|
25
|
+
.filter(f => f.endsWith('.js'))
|
|
26
|
+
.map(f => path.join(testsDir, f));
|
|
27
|
+
} catch (error) {
|
|
28
|
+
if (error.code === 'ENOENT') {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Run a single integration test
|
|
37
|
+
* @param {string} testPath - Path to test file
|
|
38
|
+
* @returns {Promise<Object>} Test result
|
|
39
|
+
*/
|
|
40
|
+
async runTest(testPath) {
|
|
41
|
+
try {
|
|
42
|
+
// Load test module
|
|
43
|
+
const test = require(testPath);
|
|
44
|
+
|
|
45
|
+
// Validate test structure
|
|
46
|
+
if (!test.name || !test.specs || !test.test) {
|
|
47
|
+
return {
|
|
48
|
+
success: false,
|
|
49
|
+
error: 'Invalid test structure: must have name, specs, and test function'
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Validate dependencies
|
|
54
|
+
const validation = await this.validateTestDependencies(test);
|
|
55
|
+
if (!validation.valid) {
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
error: validation.error,
|
|
59
|
+
blocked: true
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Run setup if provided
|
|
64
|
+
if (test.setup) {
|
|
65
|
+
await test.setup();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Run test
|
|
69
|
+
await test.test();
|
|
70
|
+
|
|
71
|
+
// Run teardown if provided
|
|
72
|
+
if (test.teardown) {
|
|
73
|
+
await test.teardown();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
success: true,
|
|
78
|
+
name: test.name,
|
|
79
|
+
specs: test.specs
|
|
80
|
+
};
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
error: error.message,
|
|
85
|
+
stack: error.stack
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Run all integration tests for specified specs
|
|
92
|
+
* @param {Array<string>} specNames - Specs to test
|
|
93
|
+
* @returns {Promise<Object>} Test results
|
|
94
|
+
*/
|
|
95
|
+
async runAllTests(specNames) {
|
|
96
|
+
const results = [];
|
|
97
|
+
|
|
98
|
+
for (const specName of specNames) {
|
|
99
|
+
const tests = await this.discoverTests(specName);
|
|
100
|
+
|
|
101
|
+
for (const testPath of tests) {
|
|
102
|
+
const result = await this.runTest(testPath);
|
|
103
|
+
results.push({
|
|
104
|
+
spec: specName,
|
|
105
|
+
testPath,
|
|
106
|
+
...result
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const passed = results.filter(r => r.success).length;
|
|
112
|
+
const failed = results.filter(r => !r.success && !r.blocked).length;
|
|
113
|
+
const blocked = results.filter(r => r.blocked).length;
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
total: results.length,
|
|
117
|
+
passed,
|
|
118
|
+
failed,
|
|
119
|
+
blocked,
|
|
120
|
+
results
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Generate integration test report
|
|
126
|
+
* @param {Object} results - Test results from runAllTests
|
|
127
|
+
* @returns {string} Formatted report
|
|
128
|
+
*/
|
|
129
|
+
generateReport(results) {
|
|
130
|
+
const lines = [];
|
|
131
|
+
|
|
132
|
+
lines.push('Integration Test Report');
|
|
133
|
+
lines.push('======================');
|
|
134
|
+
lines.push('');
|
|
135
|
+
lines.push(`Total: ${results.total}`);
|
|
136
|
+
lines.push(`Passed: ${results.passed}`);
|
|
137
|
+
lines.push(`Failed: ${results.failed}`);
|
|
138
|
+
lines.push(`Blocked: ${results.blocked}`);
|
|
139
|
+
lines.push('');
|
|
140
|
+
|
|
141
|
+
if (results.failed > 0) {
|
|
142
|
+
lines.push('Failed Tests:');
|
|
143
|
+
lines.push('-------------');
|
|
144
|
+
for (const result of results.results) {
|
|
145
|
+
if (!result.success && !result.blocked) {
|
|
146
|
+
lines.push(` ${result.name || path.basename(result.testPath)}`);
|
|
147
|
+
lines.push(` Spec: ${result.spec}`);
|
|
148
|
+
lines.push(` Error: ${result.error}`);
|
|
149
|
+
lines.push('');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (results.blocked > 0) {
|
|
155
|
+
lines.push('Blocked Tests:');
|
|
156
|
+
lines.push('--------------');
|
|
157
|
+
for (const result of results.results) {
|
|
158
|
+
if (result.blocked) {
|
|
159
|
+
lines.push(` ${result.name || path.basename(result.testPath)}`);
|
|
160
|
+
lines.push(` Reason: ${result.error}`);
|
|
161
|
+
lines.push('');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return lines.join('\n');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Validate that all required specs for a test are available
|
|
171
|
+
* @param {Object} test - Test definition
|
|
172
|
+
* @returns {Promise<Object>} Validation result
|
|
173
|
+
*/
|
|
174
|
+
async validateTestDependencies(test) {
|
|
175
|
+
if (!test.specs || !Array.isArray(test.specs)) {
|
|
176
|
+
return {
|
|
177
|
+
valid: false,
|
|
178
|
+
error: 'Test must specify required specs'
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const missing = [];
|
|
183
|
+
|
|
184
|
+
for (const specName of test.specs) {
|
|
185
|
+
const metadata = await this.metadataManager.readMetadata(specName);
|
|
186
|
+
if (!metadata) {
|
|
187
|
+
missing.push(specName);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (missing.length > 0) {
|
|
192
|
+
return {
|
|
193
|
+
valid: false,
|
|
194
|
+
error: `Missing required specs: ${missing.join(', ')}`
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return { valid: true };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
module.exports = IntegrationManager;
|