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,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merge Coordinator - Manages Agent Git branches and merge operations
|
|
3
|
+
*
|
|
4
|
+
* Handles branch creation, conflict detection, auto-merge, and cleanup
|
|
5
|
+
* for multi-Agent parallel coordination. In single-Agent mode, all
|
|
6
|
+
* branch operations are skipped (agents work on the current branch).
|
|
7
|
+
*
|
|
8
|
+
* Branch naming: `agent/{agentId}/{specName}`
|
|
9
|
+
*
|
|
10
|
+
* Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.6
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { execSync } = require('child_process');
|
|
14
|
+
const { MultiAgentConfig } = require('./multi-agent-config');
|
|
15
|
+
|
|
16
|
+
/** Default options for execSync Git commands */
|
|
17
|
+
const EXEC_OPTS = Object.freeze({
|
|
18
|
+
encoding: 'utf8',
|
|
19
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
class MergeCoordinator {
|
|
23
|
+
/**
|
|
24
|
+
* @param {string} workspaceRoot - Absolute path to the project root
|
|
25
|
+
*/
|
|
26
|
+
constructor(workspaceRoot) {
|
|
27
|
+
this._workspaceRoot = workspaceRoot;
|
|
28
|
+
this._multiAgentConfig = new MultiAgentConfig(workspaceRoot);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Execute a Git command in the workspace root.
|
|
33
|
+
* @param {string} command - Git command (without the leading `git `)
|
|
34
|
+
* @returns {string} Trimmed stdout
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
_git(command) {
|
|
38
|
+
return execSync(`git ${command}`, {
|
|
39
|
+
...EXEC_OPTS,
|
|
40
|
+
cwd: this._workspaceRoot,
|
|
41
|
+
}).trim();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Whether multi-Agent mode is enabled.
|
|
46
|
+
* In single-Agent mode all branch operations are skipped (Req 4.6).
|
|
47
|
+
* @returns {Promise<boolean>}
|
|
48
|
+
*/
|
|
49
|
+
async isMultiAgentMode() {
|
|
50
|
+
return this._multiAgentConfig.isEnabled();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Create an agent-specific branch from the current HEAD.
|
|
55
|
+
* Branch name follows the format `agent/{agentId}/{specName}` (Req 4.1).
|
|
56
|
+
*
|
|
57
|
+
* In single-Agent mode, returns the current branch name without creating
|
|
58
|
+
* a new branch (Req 4.6).
|
|
59
|
+
*
|
|
60
|
+
* @param {string} agentId
|
|
61
|
+
* @param {string} specName
|
|
62
|
+
* @returns {Promise<{branchName: string, created: boolean}>}
|
|
63
|
+
*/
|
|
64
|
+
async createAgentBranch(agentId, specName) {
|
|
65
|
+
const multiAgent = await this.isMultiAgentMode();
|
|
66
|
+
if (!multiAgent) {
|
|
67
|
+
// Single-Agent mode – stay on the current branch (Req 4.6)
|
|
68
|
+
const current = this._getCurrentBranch();
|
|
69
|
+
return { branchName: current, created: false };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const branchName = `agent/${agentId}/${specName}`;
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
// Check if branch already exists
|
|
76
|
+
this._git(`rev-parse --verify refs/heads/${branchName}`);
|
|
77
|
+
// Branch exists – just switch to it
|
|
78
|
+
this._git(`checkout ${branchName}`);
|
|
79
|
+
return { branchName, created: false };
|
|
80
|
+
} catch (_err) {
|
|
81
|
+
// Branch does not exist – create it from current HEAD
|
|
82
|
+
try {
|
|
83
|
+
this._git(`checkout -b ${branchName}`);
|
|
84
|
+
return { branchName, created: true };
|
|
85
|
+
} catch (createErr) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Failed to create agent branch "${branchName}": ${createErr.message}`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Detect merge conflicts between a branch and a target branch (Req 4.2).
|
|
95
|
+
*
|
|
96
|
+
* Uses `git merge --no-commit --no-ff` followed by `git merge --abort`
|
|
97
|
+
* to perform a dry-run merge without altering the working tree permanently.
|
|
98
|
+
*
|
|
99
|
+
* @param {string} branchName - Source branch to merge
|
|
100
|
+
* @param {string} targetBranch - Target branch (e.g. "main")
|
|
101
|
+
* @returns {Promise<{hasConflicts: boolean, files: string[]}>}
|
|
102
|
+
*/
|
|
103
|
+
async detectConflicts(branchName, targetBranch) {
|
|
104
|
+
const multiAgent = await this.isMultiAgentMode();
|
|
105
|
+
if (!multiAgent) {
|
|
106
|
+
return { hasConflicts: false, files: [] };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Save current branch so we can restore it
|
|
110
|
+
const originalBranch = this._getCurrentBranch();
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
// Switch to target branch for the trial merge
|
|
114
|
+
this._git(`checkout ${targetBranch}`);
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
this._git(`merge --no-commit --no-ff ${branchName}`);
|
|
118
|
+
// Merge succeeded without conflicts – abort to undo
|
|
119
|
+
this._safeAbortMerge();
|
|
120
|
+
return { hasConflicts: false, files: [] };
|
|
121
|
+
} catch (_mergeErr) {
|
|
122
|
+
// Merge had conflicts – collect conflicting files
|
|
123
|
+
const files = this._getConflictFiles();
|
|
124
|
+
this._safeAbortMerge();
|
|
125
|
+
return { hasConflicts: true, files };
|
|
126
|
+
}
|
|
127
|
+
} finally {
|
|
128
|
+
// Always restore the original branch
|
|
129
|
+
try {
|
|
130
|
+
this._git(`checkout ${originalBranch}`);
|
|
131
|
+
} catch (_restoreErr) {
|
|
132
|
+
// Best-effort restore; nothing more we can do
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Execute a merge of branchName into targetBranch (Req 4.3, 4.4).
|
|
139
|
+
*
|
|
140
|
+
* When no conflicts exist, performs a fast-forward merge if possible,
|
|
141
|
+
* otherwise creates a merge commit. When conflicts exist, records the
|
|
142
|
+
* conflict details and returns them without modifying the target branch.
|
|
143
|
+
*
|
|
144
|
+
* @param {string} branchName - Source branch to merge
|
|
145
|
+
* @param {string} targetBranch - Target branch
|
|
146
|
+
* @returns {Promise<{success: boolean, strategy: string|null, conflicts: string[]}>}
|
|
147
|
+
*/
|
|
148
|
+
async merge(branchName, targetBranch) {
|
|
149
|
+
const multiAgent = await this.isMultiAgentMode();
|
|
150
|
+
if (!multiAgent) {
|
|
151
|
+
return { success: true, strategy: 'single-agent-noop', conflicts: [] };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const originalBranch = this._getCurrentBranch();
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
this._git(`checkout ${targetBranch}`);
|
|
158
|
+
|
|
159
|
+
// Try fast-forward first
|
|
160
|
+
try {
|
|
161
|
+
this._git(`merge --ff-only ${branchName}`);
|
|
162
|
+
return { success: true, strategy: 'fast-forward', conflicts: [] };
|
|
163
|
+
} catch (_ffErr) {
|
|
164
|
+
// Fast-forward not possible – try regular merge
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
this._git(`merge ${branchName} -m "Merge ${branchName} into ${targetBranch}"`);
|
|
169
|
+
return { success: true, strategy: 'merge-commit', conflicts: [] };
|
|
170
|
+
} catch (_mergeErr) {
|
|
171
|
+
// Conflicts detected (Req 4.4)
|
|
172
|
+
const conflicts = this._getConflictFiles();
|
|
173
|
+
this._safeAbortMerge();
|
|
174
|
+
return { success: false, strategy: null, conflicts };
|
|
175
|
+
}
|
|
176
|
+
} finally {
|
|
177
|
+
try {
|
|
178
|
+
this._git(`checkout ${originalBranch}`);
|
|
179
|
+
} catch (_restoreErr) {
|
|
180
|
+
// Best-effort restore
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Delete a branch that has already been merged (Req 4.5).
|
|
187
|
+
*
|
|
188
|
+
* Uses `git branch -d` which only succeeds if the branch is fully merged.
|
|
189
|
+
*
|
|
190
|
+
* @param {string} branchName
|
|
191
|
+
* @returns {Promise<{success: boolean, error: string|null}>}
|
|
192
|
+
*/
|
|
193
|
+
async cleanupBranch(branchName) {
|
|
194
|
+
const multiAgent = await this.isMultiAgentMode();
|
|
195
|
+
if (!multiAgent) {
|
|
196
|
+
return { success: true, error: null };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
this._git(`branch -d ${branchName}`);
|
|
201
|
+
return { success: true, error: null };
|
|
202
|
+
} catch (err) {
|
|
203
|
+
return {
|
|
204
|
+
success: false,
|
|
205
|
+
error: `Failed to delete branch "${branchName}": ${err.message}`,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// ── Private helpers ──────────────────────────────────────────────
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Get the name of the currently checked-out branch.
|
|
214
|
+
* @returns {string}
|
|
215
|
+
* @private
|
|
216
|
+
*/
|
|
217
|
+
_getCurrentBranch() {
|
|
218
|
+
try {
|
|
219
|
+
return this._git('rev-parse --abbrev-ref HEAD');
|
|
220
|
+
} catch (_err) {
|
|
221
|
+
return 'HEAD'; // detached HEAD or not a git repo
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Collect the list of files with merge conflicts from `git diff --name-only --diff-filter=U`.
|
|
227
|
+
* @returns {string[]}
|
|
228
|
+
* @private
|
|
229
|
+
*/
|
|
230
|
+
_getConflictFiles() {
|
|
231
|
+
try {
|
|
232
|
+
const output = this._git('diff --name-only --diff-filter=U');
|
|
233
|
+
return output ? output.split('\n').filter(Boolean) : [];
|
|
234
|
+
} catch (_err) {
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Safely abort a merge in progress. Swallows errors if no merge is active.
|
|
241
|
+
* @private
|
|
242
|
+
*/
|
|
243
|
+
_safeAbortMerge() {
|
|
244
|
+
try {
|
|
245
|
+
this._git('merge --abort');
|
|
246
|
+
} catch (_err) {
|
|
247
|
+
// No merge to abort – that's fine
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
module.exports = { MergeCoordinator };
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
const fs = require('fs').promises;
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* MetadataManager handles CRUD operations on collaboration.json files
|
|
6
|
+
* Provides atomic updates and schema validation
|
|
7
|
+
*/
|
|
8
|
+
class MetadataManager {
|
|
9
|
+
constructor(workspaceRoot) {
|
|
10
|
+
this.workspaceRoot = workspaceRoot;
|
|
11
|
+
this.specsDir = path.join(workspaceRoot, '.kiro', 'specs');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Read collaboration metadata for a spec
|
|
16
|
+
* @param {string} specName - Name of the spec
|
|
17
|
+
* @returns {Promise<Object|null>} Metadata object or null if not found
|
|
18
|
+
*/
|
|
19
|
+
async readMetadata(specName) {
|
|
20
|
+
const metadataPath = this._getMetadataPath(specName);
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const content = await fs.readFile(metadataPath, 'utf8');
|
|
24
|
+
return JSON.parse(content);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
if (error.code === 'ENOENT') {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`Failed to read metadata for ${specName}: ${error.message}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Write collaboration metadata for a spec
|
|
35
|
+
* @param {string} specName - Name of the spec
|
|
36
|
+
* @param {Object} metadata - Metadata object to write
|
|
37
|
+
* @returns {Promise<void>}
|
|
38
|
+
*/
|
|
39
|
+
async writeMetadata(specName, metadata) {
|
|
40
|
+
// Validate metadata before writing
|
|
41
|
+
this.validateMetadata(metadata);
|
|
42
|
+
|
|
43
|
+
const metadataPath = this._getMetadataPath(specName);
|
|
44
|
+
const specDir = path.dirname(metadataPath);
|
|
45
|
+
|
|
46
|
+
// Ensure spec directory exists
|
|
47
|
+
await fs.mkdir(specDir, { recursive: true });
|
|
48
|
+
|
|
49
|
+
// Write with pretty formatting
|
|
50
|
+
const content = JSON.stringify(metadata, null, 2);
|
|
51
|
+
await fs.writeFile(metadataPath, content, 'utf8');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Validate metadata against schema
|
|
56
|
+
* @param {Object} metadata - Metadata to validate
|
|
57
|
+
* @throws {Error} If metadata is invalid
|
|
58
|
+
*/
|
|
59
|
+
validateMetadata(metadata) {
|
|
60
|
+
if (!metadata || typeof metadata !== 'object') {
|
|
61
|
+
throw new Error('Metadata must be an object');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Required fields
|
|
65
|
+
if (!metadata.version) {
|
|
66
|
+
throw new Error('Missing required field: version');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if (!metadata.type || !['master', 'sub'].includes(metadata.type)) {
|
|
71
|
+
throw new Error('Invalid or missing type: must be "master" or "sub"');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Validate dependencies array
|
|
75
|
+
if (metadata.dependencies) {
|
|
76
|
+
if (!Array.isArray(metadata.dependencies)) {
|
|
77
|
+
throw new Error('dependencies must be an array');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
for (const dep of metadata.dependencies) {
|
|
81
|
+
if (!dep.spec || typeof dep.spec !== 'string') {
|
|
82
|
+
throw new Error('Each dependency must have a spec name');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!dep.type || !['requires-completion', 'requires-interface', 'optional'].includes(dep.type)) {
|
|
86
|
+
throw new Error(`Invalid dependency type: ${dep.type}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Validate status
|
|
92
|
+
if (metadata.status) {
|
|
93
|
+
const validStatuses = ['not-started', 'in-progress', 'completed', 'blocked'];
|
|
94
|
+
if (!metadata.status.current || !validStatuses.includes(metadata.status.current)) {
|
|
95
|
+
throw new Error(`Invalid status: ${metadata.status.current}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!metadata.status.updatedAt) {
|
|
99
|
+
throw new Error('Status must have updatedAt timestamp');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Validate interfaces
|
|
104
|
+
if (metadata.interfaces) {
|
|
105
|
+
if (!Array.isArray(metadata.interfaces.provides)) {
|
|
106
|
+
throw new Error('interfaces.provides must be an array');
|
|
107
|
+
}
|
|
108
|
+
if (!Array.isArray(metadata.interfaces.consumes)) {
|
|
109
|
+
throw new Error('interfaces.consumes must be an array');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Delete collaboration metadata for a spec
|
|
116
|
+
* @param {string} specName - Name of the spec
|
|
117
|
+
* @returns {Promise<boolean>} True if deleted, false if not found
|
|
118
|
+
*/
|
|
119
|
+
async deleteMetadata(specName) {
|
|
120
|
+
const metadataPath = this._getMetadataPath(specName);
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
await fs.unlink(metadataPath);
|
|
124
|
+
return true;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
if (error.code === 'ENOENT') {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
throw new Error(`Failed to delete metadata for ${specName}: ${error.message}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* List all specs with collaboration metadata
|
|
135
|
+
* @returns {Promise<Array<{name: string, metadata: Object}>>}
|
|
136
|
+
*/
|
|
137
|
+
async listAllMetadata() {
|
|
138
|
+
const specs = [];
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
const specDirs = await fs.readdir(this.specsDir);
|
|
142
|
+
|
|
143
|
+
for (const specName of specDirs) {
|
|
144
|
+
const metadata = await this.readMetadata(specName);
|
|
145
|
+
if (metadata) {
|
|
146
|
+
specs.push({ name: specName, metadata });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
} catch (error) {
|
|
150
|
+
if (error.code === 'ENOENT') {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return specs;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Perform atomic update on metadata
|
|
161
|
+
* @param {string} specName - Name of the spec
|
|
162
|
+
* @param {Function} updateFn - Function that receives current metadata and returns updated metadata
|
|
163
|
+
* @returns {Promise<Object>} Updated metadata
|
|
164
|
+
*/
|
|
165
|
+
async atomicUpdate(specName, updateFn) {
|
|
166
|
+
const maxRetries = 3;
|
|
167
|
+
let lastError;
|
|
168
|
+
|
|
169
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
170
|
+
try {
|
|
171
|
+
// Read current metadata
|
|
172
|
+
const current = await this.readMetadata(specName) || this._getDefaultMetadata();
|
|
173
|
+
|
|
174
|
+
// Apply update function
|
|
175
|
+
const updated = await updateFn(current);
|
|
176
|
+
|
|
177
|
+
// Write updated metadata
|
|
178
|
+
await this.writeMetadata(specName, updated);
|
|
179
|
+
|
|
180
|
+
return updated;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
lastError = error;
|
|
183
|
+
|
|
184
|
+
// Exponential backoff
|
|
185
|
+
if (attempt < maxRetries - 1) {
|
|
186
|
+
await this._sleep(Math.pow(2, attempt) * 100);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
throw new Error(`Atomic update failed after ${maxRetries} attempts: ${lastError.message}`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Get default metadata structure
|
|
196
|
+
* @returns {Object}
|
|
197
|
+
*/
|
|
198
|
+
_getDefaultMetadata() {
|
|
199
|
+
return {
|
|
200
|
+
version: '1.0.0',
|
|
201
|
+
type: 'sub',
|
|
202
|
+
dependencies: [],
|
|
203
|
+
status: {
|
|
204
|
+
current: 'not-started',
|
|
205
|
+
updatedAt: new Date().toISOString()
|
|
206
|
+
},
|
|
207
|
+
interfaces: {
|
|
208
|
+
provides: [],
|
|
209
|
+
consumes: []
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Get metadata file path for a spec
|
|
216
|
+
* @param {string} specName
|
|
217
|
+
* @returns {string}
|
|
218
|
+
*/
|
|
219
|
+
_getMetadataPath(specName) {
|
|
220
|
+
return path.join(this.specsDir, specName, 'collaboration.json');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Sleep for specified milliseconds
|
|
225
|
+
* @param {number} ms
|
|
226
|
+
* @returns {Promise<void>}
|
|
227
|
+
*/
|
|
228
|
+
_sleep(ms) {
|
|
229
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
module.exports = MetadataManager;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Agent Configuration Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages `.kiro/config/multi-agent.json` for multi-Agent parallel coordination.
|
|
5
|
+
* When the config file does not exist or is corrupted, returns a default
|
|
6
|
+
* disabled configuration so that single-Agent mode is completely unaffected.
|
|
7
|
+
*
|
|
8
|
+
* Requirements: 7.1 (no extra files when disabled), 7.4 (auto-init on first enable)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const fsUtils = require('../utils/fs-utils');
|
|
13
|
+
|
|
14
|
+
const CONFIG_FILENAME = 'multi-agent.json';
|
|
15
|
+
const CONFIG_DIR = '.kiro/config';
|
|
16
|
+
|
|
17
|
+
/** @type {import('./multi-agent-config').MultiAgentConfigData} */
|
|
18
|
+
const DEFAULT_CONFIG = Object.freeze({
|
|
19
|
+
enabled: false,
|
|
20
|
+
heartbeatIntervalMs: 60000,
|
|
21
|
+
heartbeatTimeoutMs: 180000,
|
|
22
|
+
coordinatorEnabled: false,
|
|
23
|
+
maxRetries: 5,
|
|
24
|
+
retryBaseDelayMs: 100,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
class MultiAgentConfig {
|
|
28
|
+
/**
|
|
29
|
+
* @param {string} workspaceRoot - Absolute path to the project root
|
|
30
|
+
*/
|
|
31
|
+
constructor(workspaceRoot) {
|
|
32
|
+
this._workspaceRoot = workspaceRoot;
|
|
33
|
+
this._configPath = path.join(workspaceRoot, CONFIG_DIR, CONFIG_FILENAME);
|
|
34
|
+
this._configDir = path.join(workspaceRoot, CONFIG_DIR);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Read the current configuration.
|
|
39
|
+
* Returns the default (disabled) config when the file is missing or corrupted.
|
|
40
|
+
*
|
|
41
|
+
* @returns {Promise<object>} Resolved configuration
|
|
42
|
+
*/
|
|
43
|
+
async getConfig() {
|
|
44
|
+
const exists = await fsUtils.pathExists(this._configPath);
|
|
45
|
+
if (!exists) {
|
|
46
|
+
return { ...DEFAULT_CONFIG };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const data = await fsUtils.readJSON(this._configPath);
|
|
51
|
+
return { ...DEFAULT_CONFIG, ...data };
|
|
52
|
+
} catch (_err) {
|
|
53
|
+
// Corrupted JSON – fall back to defaults with a warning
|
|
54
|
+
console.warn(
|
|
55
|
+
`[MultiAgentConfig] Failed to parse ${this._configPath}, using default config`
|
|
56
|
+
);
|
|
57
|
+
return { ...DEFAULT_CONFIG };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Whether multi-Agent mode is enabled.
|
|
63
|
+
* @returns {Promise<boolean>}
|
|
64
|
+
*/
|
|
65
|
+
async isEnabled() {
|
|
66
|
+
const config = await this.getConfig();
|
|
67
|
+
return config.enabled === true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Whether the central coordinator is enabled.
|
|
72
|
+
* Only meaningful when multi-Agent mode itself is enabled.
|
|
73
|
+
* @returns {Promise<boolean>}
|
|
74
|
+
*/
|
|
75
|
+
async isCoordinatorEnabled() {
|
|
76
|
+
const config = await this.getConfig();
|
|
77
|
+
return config.enabled === true && config.coordinatorEnabled === true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Persist a (partial) configuration update.
|
|
82
|
+
* Merges the provided values with the current config and writes atomically.
|
|
83
|
+
* Auto-initialises the config directory on first write (Requirement 7.4).
|
|
84
|
+
*
|
|
85
|
+
* @param {object} updates - Partial config values to merge
|
|
86
|
+
* @returns {Promise<object>} The full config after the update
|
|
87
|
+
*/
|
|
88
|
+
async updateConfig(updates) {
|
|
89
|
+
await fsUtils.ensureDirectory(this._configDir);
|
|
90
|
+
const current = await this.getConfig();
|
|
91
|
+
const merged = { ...current, ...updates };
|
|
92
|
+
await fsUtils.writeJSON(this._configPath, merged);
|
|
93
|
+
return merged;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Enable multi-Agent mode.
|
|
98
|
+
* Convenience wrapper that also initialises the required directory structure.
|
|
99
|
+
*
|
|
100
|
+
* @returns {Promise<object>} The full config after enabling
|
|
101
|
+
*/
|
|
102
|
+
async enable() {
|
|
103
|
+
return this.updateConfig({ enabled: true });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Disable multi-Agent mode.
|
|
108
|
+
* @returns {Promise<object>} The full config after disabling
|
|
109
|
+
*/
|
|
110
|
+
async disable() {
|
|
111
|
+
return this.updateConfig({ enabled: false });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Absolute path to the config file (useful for tests / diagnostics). */
|
|
115
|
+
get configPath() {
|
|
116
|
+
return this._configPath;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = { MultiAgentConfig, DEFAULT_CONFIG };
|