scene-capability-engine 3.3.4 → 3.3.10
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 +151 -78
- package/README.md +6 -6
- package/README.zh.md +6 -6
- package/bin/scene-capability-engine.js +129 -7
- package/docs/331-poc-adaptation-roadmap.md +3 -3
- package/docs/331-poc-dual-track-integration-guide.md +8 -8
- package/docs/331-poc-weekly-delivery-checklist.md +6 -6
- package/docs/README.md +6 -0
- package/docs/adopt-migration-guide.md +13 -13
- package/docs/adoption-guide.md +28 -28
- package/docs/agent-hooks-analysis.md +10 -10
- package/docs/agent-runtime/agent-result-summary-contract.schema.json +50 -0
- package/docs/agent-runtime/agent-result-summary.sample.json +11 -0
- package/docs/agent-runtime/capability-mapping-report.sample.json +42 -0
- package/docs/agent-runtime/capability-mapping-report.schema.json +136 -0
- package/docs/agent-runtime/failure-taxonomy-baseline.json +99 -0
- package/docs/agent-runtime/multi-agent-coordination-policy-baseline.json +38 -0
- package/docs/agent-runtime/strategy-routing-policy-baseline.json +24 -0
- package/docs/agent-runtime/symbol-evidence.sample.json +34 -0
- package/docs/agent-runtime/symbol-evidence.schema.json +128 -0
- package/docs/architecture.md +13 -13
- package/docs/articles/ai-driven-development-philosophy-and-practice.en.md +3 -3
- package/docs/articles/ai-driven-development-philosophy-and-practice.md +3 -3
- package/docs/autonomous-control-guide.md +35 -35
- package/docs/command-reference.md +254 -151
- package/docs/cross-tool-guide.md +7 -7
- package/docs/developer-guide.md +8 -8
- package/docs/document-governance.md +15 -15
- package/docs/environment-management-guide.md +6 -6
- package/docs/examples/add-export-command/design.md +1 -1
- package/docs/faq.md +13 -13
- package/docs/handoff-profile-integration-guide.md +3 -3
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.json +7 -7
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.md +1 -1
- package/docs/integration-modes.md +12 -12
- package/docs/integration-philosophy.md +11 -11
- package/docs/interactive-customization/331-poc-sce-integration-checklist.md +24 -24
- package/docs/interactive-customization/README.md +43 -43
- package/docs/interactive-customization/business-mode-policy-baseline.json +33 -0
- package/docs/interactive-customization/dual-ui-mode-integration-guide.md +1 -1
- package/docs/interactive-customization/moqui-adapter-interface.md +2 -2
- package/docs/interactive-customization/moqui-copilot-integration-guide.md +1 -1
- package/docs/interactive-customization/moqui-interactive-template-playbook.md +4 -4
- package/docs/interactive-customization/phase-acceptance-evidence.md +2 -2
- package/docs/knowledge-management-guide.md +6 -6
- package/docs/manual-workflows-guide.md +4 -4
- package/docs/moqui-capability-matrix.md +3 -3
- package/docs/moqui-standard-rebuild-guide.md +8 -8
- package/docs/moqui-template-core-library-playbook.md +27 -27
- package/docs/multi-agent-coordination-guide.md +19 -19
- package/docs/multi-repo-management-guide.md +17 -17
- package/docs/quick-start-with-ai-tools.md +7 -7
- package/docs/quick-start.md +2 -2
- package/docs/release-checklist.md +4 -4
- package/docs/sce-business-mode-map.md +103 -0
- package/docs/sce-capability-matrix-e2e-example.md +94 -0
- package/docs/sce-capability-matrix-roadmap.md +48 -0
- package/docs/security-governance-default-baseline.md +12 -12
- package/docs/spec-collaboration-guide.md +3 -3
- package/docs/spec-locking-guide.md +2 -2
- package/docs/spec-workflow.md +3 -3
- package/docs/starter-kit/README.md +4 -4
- package/docs/starter-kit/handoff-manifest.starter.json +2 -2
- package/docs/starter-kit/release.workflow.sample.yml +1 -1
- package/docs/steering-strategy-guide.md +15 -15
- package/docs/team-collaboration-guide.md +69 -69
- package/docs/testing-strategy.md +2 -2
- package/docs/tools/claude-guide.md +14 -4
- package/docs/tools/cursor-guide.md +14 -14
- package/docs/tools/generic-guide.md +9 -9
- package/docs/tools/kiro-guide.md +4 -4
- package/docs/tools/vscode-guide.md +13 -13
- package/docs/tools/windsurf-guide.md +6 -6
- package/docs/troubleshooting.md +22 -22
- package/docs/upgrade-guide.md +8 -8
- package/docs/value-observability-guide.md +3 -3
- package/docs/zh/README.md +15 -0
- package/docs/zh/quick-start.md +15 -15
- package/docs/zh/release-checklist.md +3 -3
- package/docs/zh/tools/claude-guide.md +16 -6
- package/docs/zh/tools/cursor-guide.md +11 -11
- package/docs/zh/tools/generic-guide.md +13 -13
- package/docs/zh/tools/kiro-guide.md +2 -2
- package/docs/zh/tools/vscode-guide.md +11 -11
- package/docs/zh/tools/windsurf-guide.md +11 -11
- package/docs/zh/value-observability-guide.md +3 -3
- package/lib/adoption/adoption-logger.js +1 -1
- package/lib/adoption/adoption-strategy.js +28 -28
- package/lib/adoption/backup-manager.js +3 -3
- package/lib/adoption/conflict-resolver.js +2 -2
- package/lib/adoption/detection-engine.js +8 -8
- package/lib/adoption/error-formatter.js +4 -4
- package/lib/adoption/file-classifier.js +6 -6
- package/lib/adoption/progress-reporter.js +1 -1
- package/lib/adoption/smart-orchestrator.js +10 -10
- package/lib/adoption/strategy-selector.js +6 -6
- package/lib/adoption/summary-generator.js +1 -1
- package/lib/adoption/template-sync.js +8 -8
- package/lib/auto/autonomous-engine.js +7 -7
- package/lib/auto/checkpoint-manager.js +1 -1
- package/lib/auto/close-loop-runner.js +12 -12
- package/lib/auto/error-recovery-manager.js +1 -1
- package/lib/auto/goal-decomposer.js +1 -1
- package/lib/auto/moqui-recovery-sequence.js +2 -2
- package/lib/auto/progress-tracker.js +1 -1
- package/lib/auto/state-manager.js +1 -1
- package/lib/backup/backup-system.js +10 -10
- package/lib/backup/selective-backup.js +4 -4
- package/lib/collab/agent-registry.js +2 -2
- package/lib/collab/contract-manager.js +1 -1
- package/lib/collab/coordinator.js +2 -2
- package/lib/collab/dependency-manager.js +1 -1
- package/lib/collab/integration-manager.js +1 -1
- package/lib/collab/metadata-manager.js +1 -1
- package/lib/collab/multi-agent-config.js +2 -2
- package/lib/collab/spec-lifecycle-manager.js +2 -2
- package/lib/collab/visualizer.js +1 -1
- package/lib/commands/adopt.js +6 -6
- package/lib/commands/auto.js +56 -56
- package/lib/commands/collab.js +2 -2
- package/lib/commands/docs.js +3 -3
- package/lib/commands/doctor.js +1 -1
- package/lib/commands/knowledge.js +2 -2
- package/lib/commands/lock.js +1 -1
- package/lib/commands/ops.js +1 -1
- package/lib/commands/orchestrate.js +3 -3
- package/lib/commands/rollback.js +1 -1
- package/lib/commands/scene.js +135 -93
- package/lib/commands/session.js +139 -0
- package/lib/commands/spec-bootstrap.js +1 -1
- package/lib/commands/spec-gate.js +2 -2
- package/lib/commands/spec-pipeline.js +1 -1
- package/lib/commands/status.js +4 -4
- package/lib/commands/steering.js +119 -0
- package/lib/commands/value.js +1 -1
- package/lib/commands/watch.js +9 -9
- package/lib/commands/workspace-multi.js +1 -1
- package/lib/context/context-exporter.js +5 -7
- package/lib/context/prompt-generator.js +2 -2
- package/lib/environment/backup-system.js +1 -1
- package/lib/environment/environment-manager.js +2 -2
- package/lib/gitignore/gitignore-backup.js +3 -3
- package/lib/gitignore/gitignore-detector.js +13 -13
- package/lib/gitignore/gitignore-integration.js +3 -3
- package/lib/gitignore/gitignore-transformer.js +4 -4
- package/lib/gitignore/layered-rules-template.js +16 -16
- package/lib/governance/config-manager.js +1 -1
- package/lib/governance/doc-reference-checker.js +4 -4
- package/lib/governance/execution-logger.js +1 -1
- package/lib/governance/file-scanner.js +3 -3
- package/lib/interactive-customization/moqui-interactive-adapter.js +2 -2
- package/lib/knowledge/knowledge-manager.js +1 -1
- package/lib/lock/lock-manager.js +2 -2
- package/lib/lock/steering-file-lock.js +5 -5
- package/lib/lock/task-lock-manager.js +3 -3
- package/lib/operations/audit-logger.js +1 -1
- package/lib/operations/feedback-manager.js +1 -1
- package/lib/operations/operations-manager.js +3 -3
- package/lib/operations/permission-manager.js +2 -2
- package/lib/operations/template-loader.js +1 -1
- package/lib/orchestrator/agent-spawner.js +180 -2
- package/lib/orchestrator/bootstrap-prompt-builder.js +9 -6
- package/lib/orchestrator/orchestration-engine.js +346 -2
- package/lib/orchestrator/orchestrator-config.js +2 -2
- package/lib/repo/config-manager.js +3 -3
- package/lib/repo/handlers/init-handler.js +1 -1
- package/lib/repo/repo-manager.js +2 -2
- package/lib/runtime/business-mode-resolver.js +240 -0
- package/lib/runtime/session-store.js +207 -0
- package/lib/runtime/steering-contract.js +338 -0
- package/lib/scene-runtime/audit-emitter.js +1 -1
- package/lib/scene-runtime/binding-plugin-loader.js +3 -3
- package/lib/scene-runtime/eval-bridge.js +1 -1
- package/lib/scene-runtime/index.js +1 -1
- package/lib/scene-runtime/moqui-extractor.js +1 -1
- package/lib/scene-runtime/plan-compiler.js +1 -1
- package/lib/scene-runtime/policy-gate.js +1 -1
- package/lib/scene-runtime/runtime-executor.js +1 -1
- package/lib/scene-runtime/scene-loader.js +1 -1
- package/lib/spec/bootstrap/context-collector.js +1 -1
- package/lib/spec/pipeline/stage-adapters.js +3 -3
- package/lib/spec/pipeline/state-store.js +1 -1
- package/lib/spec-gate/policy/policy-loader.js +1 -1
- package/lib/spec-gate/rules/default-rules.js +6 -6
- package/lib/steering/adoption-config.js +1 -1
- package/lib/steering/compliance-error-reporter.js +3 -3
- package/lib/steering/context-sync-manager.js +2 -2
- package/lib/steering/index.js +1 -1
- package/lib/steering/spec-steering.js +2 -2
- package/lib/steering/steering-compliance-checker.js +1 -1
- package/lib/steering/steering-loader.js +4 -5
- package/lib/steering/steering-manager.js +4 -4
- package/lib/task/task-claimer.js +5 -5
- package/lib/task/task-status-store.js +2 -2
- package/lib/templates/content-generalizer.js +1 -1
- package/lib/templates/spec-reader.js +2 -2
- package/lib/templates/template-creator.js +1 -1
- package/lib/templates/template-exporter.js +3 -3
- package/lib/templates/template-manager.js +1 -1
- package/lib/upgrade/migration-engine.js +3 -3
- package/lib/upgrade/migrations/1.0.0-to-1.1.0.js +1 -1
- package/lib/utils/file-diff.js +6 -6
- package/lib/utils/tool-detector.js +10 -10
- package/lib/utils/validation.js +5 -5
- package/lib/value/metric-contract-loader.js +1 -1
- package/lib/version/version-manager.js +1 -1
- package/lib/watch/execution-logger.js +1 -1
- package/lib/watch/presets.js +8 -8
- package/lib/watch/watch-manager.js +2 -2
- package/lib/workspace/legacy-kiro-migrator.js +275 -0
- package/lib/workspace/multi/workspace-context-resolver.js +2 -2
- package/lib/workspace/multi/workspace-registry.js +2 -2
- package/lib/workspace/multi/workspace-state-manager.js +3 -3
- package/lib/workspace/workspace-manager.js +1 -1
- package/lib/workspace/workspace-sync.js +2 -2
- package/locales/en.json +4 -4
- package/locales/zh.json +4 -4
- package/package.json +12 -9
- package/template/{.kiro → .sce}/README.md +15 -15
- package/template/{.kiro → .sce}/hooks/check-spec-on-create.kiro.hook +2 -2
- package/template/{.kiro → .sce}/steering/CORE_PRINCIPLES.md +4 -4
- package/template/{.kiro → .sce}/steering/CURRENT_CONTEXT.md +1 -1
- package/template/{.kiro → .sce}/steering/ENVIRONMENT.md +3 -3
- package/template/{.kiro → .sce}/tools/backup_manager.py +3 -3
- package/template/{.kiro → .sce}/tools/configuration_manager.py +1 -1
- package/template/README.md +12 -12
- /package/template/{.kiro → .sce}/hooks/run-tests-on-save.kiro.hook +0 -0
- /package/template/{.kiro → .sce}/hooks/sync-tasks-on-edit.kiro.hook +0 -0
- /package/template/{.kiro → .sce}/specs/SPEC_WORKFLOW_GUIDE.md +0 -0
- /package/template/{.kiro → .sce}/steering/RULES_GUIDE.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/change-impact.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/deployment.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/feedback-response.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/migration-plan.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/monitoring.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/operations.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/rollback.md +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/tools.yaml +0 -0
- /package/template/{.kiro → .sce}/templates/operations/default/troubleshooting.md +0 -0
- /package/template/{.kiro → .sce}/tools/document_evaluator.py +0 -0
- /package/template/{.kiro → .sce}/tools/enhancement_logger.py +0 -0
- /package/template/{.kiro → .sce}/tools/error_handler.py +0 -0
- /package/template/{.kiro → .sce}/tools/improvement_identifier.py +0 -0
- /package/template/{.kiro → .sce}/tools/modification_applicator.py +0 -0
- /package/template/{.kiro → .sce}/tools/quality_gate_enforcer.py +0 -0
- /package/template/{.kiro → .sce}/tools/quality_scorer.py +0 -0
- /package/template/{.kiro → .sce}/tools/report_generator.py +0 -0
- /package/template/{.kiro → .sce}/tools/ultrawork_enhancer.py +0 -0
- /package/template/{.kiro → .sce}/tools/ultrawork_enhancer_refactored.py +0 -0
- /package/template/{.kiro → .sce}/tools/ultrawork_enhancer_v2.py +0 -0
- /package/template/{.kiro → .sce}/tools/ultrawork_enhancer_v3.py +0 -0
- /package/template/{.kiro → .sce}/tools/workflow_quality_gate.py +0 -0
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Layered .gitignore rules template
|
|
3
3
|
*
|
|
4
|
-
* This template defines the layered strategy for .
|
|
4
|
+
* This template defines the layered strategy for .sce/ directory:
|
|
5
5
|
* - Commit Specs and shared content
|
|
6
6
|
* - Exclude personal state and temporary files
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const LAYERED_RULES_TEMPLATE = `# ========================================
|
|
10
|
-
# .
|
|
10
|
+
# .sce/ Directory - Layered Management
|
|
11
11
|
# ========================================
|
|
12
12
|
# Generated by sce - DO NOT EDIT THIS SECTION
|
|
13
13
|
# See: docs/team-collaboration-guide.md
|
|
14
14
|
|
|
15
15
|
# Personal state files (DO NOT commit)
|
|
16
|
-
.
|
|
17
|
-
.
|
|
18
|
-
.
|
|
16
|
+
.sce/steering/CURRENT_CONTEXT.md
|
|
17
|
+
.sce/contexts/.active
|
|
18
|
+
.sce/contexts/*/CURRENT_CONTEXT.md
|
|
19
19
|
|
|
20
20
|
# Environment configuration (DO NOT commit)
|
|
21
|
-
.
|
|
22
|
-
.
|
|
21
|
+
.sce/environments.json
|
|
22
|
+
.sce/env-backups/
|
|
23
23
|
|
|
24
24
|
# Temporary files and backups (DO NOT commit)
|
|
25
|
-
.
|
|
26
|
-
.
|
|
27
|
-
.
|
|
25
|
+
.sce/backups/
|
|
26
|
+
.sce/logs/
|
|
27
|
+
.sce/reports/
|
|
28
28
|
|
|
29
29
|
# Spec artifacts (COMMIT - but exclude temporary files)
|
|
30
|
-
.
|
|
31
|
-
.
|
|
32
|
-
.
|
|
33
|
-
.
|
|
34
|
-
.
|
|
35
|
-
.
|
|
30
|
+
.sce/specs/**/SESSION-*.md
|
|
31
|
+
.sce/specs/**/*-SUMMARY.md
|
|
32
|
+
.sce/specs/**/*-COMPLETE.md
|
|
33
|
+
.sce/specs/**/TEMP-*.md
|
|
34
|
+
.sce/specs/**/WIP-*.md
|
|
35
|
+
.sce/specs/**/MVP-*.md
|
|
36
36
|
|
|
37
37
|
# ========================================
|
|
38
38
|
# End of sce-managed section
|
|
@@ -10,7 +10,7 @@ const path = require('path');
|
|
|
10
10
|
class ConfigManager {
|
|
11
11
|
constructor(projectPath) {
|
|
12
12
|
this.projectPath = projectPath;
|
|
13
|
-
this.configPath = path.join(projectPath, '.
|
|
13
|
+
this.configPath = path.join(projectPath, '.sce/config/docs.json');
|
|
14
14
|
this.config = null;
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -30,10 +30,10 @@ class DocReferenceChecker {
|
|
|
30
30
|
|
|
31
31
|
// Files to check
|
|
32
32
|
this.filesToCheck = [
|
|
33
|
-
'.
|
|
34
|
-
'.
|
|
35
|
-
'.
|
|
36
|
-
'.
|
|
33
|
+
'.sce/specs/SPEC_WORKFLOW_GUIDE.md',
|
|
34
|
+
'.sce/steering/ENVIRONMENT.md',
|
|
35
|
+
'.sce/steering/CURRENT_CONTEXT.md',
|
|
36
|
+
'.sce/README.md',
|
|
37
37
|
'README.md',
|
|
38
38
|
'package.json'
|
|
39
39
|
];
|
|
@@ -10,7 +10,7 @@ const path = require('path');
|
|
|
10
10
|
class ExecutionLogger {
|
|
11
11
|
constructor(projectPath) {
|
|
12
12
|
this.projectPath = projectPath;
|
|
13
|
-
this.logDir = path.join(projectPath, '.
|
|
13
|
+
this.logDir = path.join(projectPath, '.sce', 'logs');
|
|
14
14
|
this.logFile = path.join(this.logDir, 'governance-history.json');
|
|
15
15
|
this.maxLogSize = 10 * 1024 * 1024; // 10MB
|
|
16
16
|
this.maxRotatedLogs = 5;
|
|
@@ -134,7 +134,7 @@ class FileScanner {
|
|
|
134
134
|
* @returns {Promise<string[]>} - Array of Spec directory paths
|
|
135
135
|
*/
|
|
136
136
|
async findSpecDirectories() {
|
|
137
|
-
const specsPath = path.join(this.projectPath, '.
|
|
137
|
+
const specsPath = path.join(this.projectPath, '.sce/specs');
|
|
138
138
|
|
|
139
139
|
try {
|
|
140
140
|
const entries = await fs.readdir(specsPath, { withFileTypes: true });
|
|
@@ -148,7 +148,7 @@ class FileScanner {
|
|
|
148
148
|
|
|
149
149
|
return specDirs;
|
|
150
150
|
} catch (error) {
|
|
151
|
-
// If .
|
|
151
|
+
// If .sce/specs doesn't exist, return empty array
|
|
152
152
|
return [];
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -160,7 +160,7 @@ class FileScanner {
|
|
|
160
160
|
* @returns {string} - Spec directory path
|
|
161
161
|
*/
|
|
162
162
|
getSpecDirectory(specName) {
|
|
163
|
-
return path.join(this.projectPath, '.
|
|
163
|
+
return path.join(this.projectPath, '.sce/specs', specName);
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
/**
|
|
@@ -13,8 +13,8 @@ const {
|
|
|
13
13
|
const ADAPTER_TYPE = 'moqui-interactive-adapter';
|
|
14
14
|
const ADAPTER_VERSION = '1.0.0';
|
|
15
15
|
|
|
16
|
-
const DEFAULT_EXECUTION_RECORD_OUT = '.
|
|
17
|
-
const DEFAULT_EXECUTION_LEDGER_OUT = '.
|
|
16
|
+
const DEFAULT_EXECUTION_RECORD_OUT = '.sce/reports/interactive-execution-record.latest.json';
|
|
17
|
+
const DEFAULT_EXECUTION_LEDGER_OUT = '.sce/reports/interactive-execution-ledger.jsonl';
|
|
18
18
|
|
|
19
19
|
const SUPPORTED_ACTION_TYPES = [
|
|
20
20
|
'analysis_only',
|
|
@@ -12,7 +12,7 @@ const TemplateManager = require('./template-manager');
|
|
|
12
12
|
class KnowledgeManager {
|
|
13
13
|
constructor(projectRoot) {
|
|
14
14
|
this.projectRoot = projectRoot;
|
|
15
|
-
this.knowledgePath = path.join(projectRoot, '.
|
|
15
|
+
this.knowledgePath = path.join(projectRoot, '.sce', 'knowledge');
|
|
16
16
|
|
|
17
17
|
this.entryManager = new EntryManager(this.knowledgePath);
|
|
18
18
|
this.indexManager = new IndexManager(this.knowledgePath);
|
package/lib/lock/lock-manager.js
CHANGED
|
@@ -19,8 +19,8 @@ class LockManager {
|
|
|
19
19
|
*/
|
|
20
20
|
constructor(workspaceRoot, machineIdentifier = null) {
|
|
21
21
|
this.workspaceRoot = workspaceRoot;
|
|
22
|
-
this.specsDir = path.join(workspaceRoot, '.
|
|
23
|
-
this.configDir = path.join(workspaceRoot, '.
|
|
22
|
+
this.specsDir = path.join(workspaceRoot, '.sce', 'specs');
|
|
23
|
+
this.configDir = path.join(workspaceRoot, '.sce', 'config');
|
|
24
24
|
this.lockFile = new LockFile(this.specsDir);
|
|
25
25
|
this.machineIdentifier = machineIdentifier || new MachineIdentifier(this.configDir);
|
|
26
26
|
}
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* SteeringFileLock - Protects concurrent writes to Steering files
|
|
3
3
|
*
|
|
4
4
|
* Uses file-level locks with exclusive create (`wx`) to serialize writes
|
|
5
|
-
* to `.
|
|
5
|
+
* to `.sce/steering/` files. When lock acquisition fails after retries,
|
|
6
6
|
* falls back to writing a pending file for later merge.
|
|
7
7
|
*
|
|
8
|
-
* Lock file path: `.
|
|
9
|
-
* Pending file path: `.
|
|
8
|
+
* Lock file path: `.sce/steering/{filename}.lock`
|
|
9
|
+
* Pending file path: `.sce/steering/{filename}.pending.{agentId}`
|
|
10
10
|
*
|
|
11
11
|
* Requirements: 5.1, 5.2, 5.3, 5.4
|
|
12
12
|
*/
|
|
@@ -26,7 +26,7 @@ class SteeringFileLock {
|
|
|
26
26
|
*/
|
|
27
27
|
constructor(workspaceRoot) {
|
|
28
28
|
this._workspaceRoot = workspaceRoot;
|
|
29
|
-
this._steeringDir = path.join(workspaceRoot, '.
|
|
29
|
+
this._steeringDir = path.join(workspaceRoot, '.sce', 'steering');
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -139,7 +139,7 @@ class SteeringFileLock {
|
|
|
139
139
|
|
|
140
140
|
/**
|
|
141
141
|
* Write content to a pending file as a fallback when lock acquisition fails.
|
|
142
|
-
* Pending file path: `.
|
|
142
|
+
* Pending file path: `.sce/steering/{filename}.pending.{agentId}`
|
|
143
143
|
* Uses atomic write for file integrity (Req 5.3, 5.4).
|
|
144
144
|
*
|
|
145
145
|
* @param {string} filename - Steering filename
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Provides per-task locking instead of per-Spec locking, allowing multiple
|
|
5
5
|
* Agents to work on different tasks within the same Spec concurrently.
|
|
6
6
|
*
|
|
7
|
-
* Lock file path: `.
|
|
7
|
+
* Lock file path: `.sce/specs/{specName}/locks/{taskId}.lock`
|
|
8
8
|
* (dots in taskId replaced with dashes for filesystem safety)
|
|
9
9
|
*
|
|
10
10
|
* In single-Agent mode, delegates to the existing LockManager (Spec-level lock).
|
|
@@ -27,7 +27,7 @@ class TaskLockManager {
|
|
|
27
27
|
constructor(workspaceRoot, machineIdentifier) {
|
|
28
28
|
this._workspaceRoot = workspaceRoot;
|
|
29
29
|
this._machineIdentifier = machineIdentifier;
|
|
30
|
-
this._specsDir = path.join(workspaceRoot, '.
|
|
30
|
+
this._specsDir = path.join(workspaceRoot, '.sce', 'specs');
|
|
31
31
|
this._multiAgentConfig = new MultiAgentConfig(workspaceRoot);
|
|
32
32
|
this._lockManager = new LockManager(workspaceRoot, machineIdentifier);
|
|
33
33
|
this._taskClaimer = new TaskClaimer();
|
|
@@ -76,7 +76,7 @@ class TaskLockManager {
|
|
|
76
76
|
/**
|
|
77
77
|
* Acquire a task-level lock.
|
|
78
78
|
*
|
|
79
|
-
* In multi-Agent mode: creates `.
|
|
79
|
+
* In multi-Agent mode: creates `.sce/specs/{specName}/locks/{taskId}.lock`
|
|
80
80
|
* In single-Agent mode: delegates to LockManager.acquireLock(specName)
|
|
81
81
|
*
|
|
82
82
|
* @param {string} specName
|
|
@@ -11,7 +11,7 @@ const crypto = require('crypto');
|
|
|
11
11
|
class AuditLogger {
|
|
12
12
|
constructor(projectRoot = process.cwd()) {
|
|
13
13
|
this.projectRoot = projectRoot;
|
|
14
|
-
this.auditPath = path.join(projectRoot, '.
|
|
14
|
+
this.auditPath = path.join(projectRoot, '.sce/audit');
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -34,7 +34,7 @@ function generateUUID() {
|
|
|
34
34
|
class FeedbackManager {
|
|
35
35
|
constructor(projectPath) {
|
|
36
36
|
this.projectPath = projectPath;
|
|
37
|
-
this.feedbackDir = path.join(projectPath, '.
|
|
37
|
+
this.feedbackDir = path.join(projectPath, '.sce/feedback');
|
|
38
38
|
this.feedbackFile = path.join(this.feedbackDir, 'feedback.json');
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -28,7 +28,7 @@ class OperationsManager {
|
|
|
28
28
|
async createOperationsSpec(projectName, version = '1.0.0', templateName = 'default') {
|
|
29
29
|
const operationsPath = path.join(
|
|
30
30
|
this.projectRoot,
|
|
31
|
-
'.
|
|
31
|
+
'.sce/specs',
|
|
32
32
|
projectName,
|
|
33
33
|
'operations'
|
|
34
34
|
);
|
|
@@ -77,7 +77,7 @@ class OperationsManager {
|
|
|
77
77
|
async loadOperationsSpec(projectName) {
|
|
78
78
|
const operationsPath = path.join(
|
|
79
79
|
this.projectRoot,
|
|
80
|
-
'.
|
|
80
|
+
'.sce/specs',
|
|
81
81
|
projectName,
|
|
82
82
|
'operations'
|
|
83
83
|
);
|
|
@@ -125,7 +125,7 @@ class OperationsManager {
|
|
|
125
125
|
* @returns {Promise<string[]>} Array of project names with operations specs
|
|
126
126
|
*/
|
|
127
127
|
async listOperationsSpecs() {
|
|
128
|
-
const specsPath = path.join(this.projectRoot, '.
|
|
128
|
+
const specsPath = path.join(this.projectRoot, '.sce/specs');
|
|
129
129
|
|
|
130
130
|
const exists = await fs.pathExists(specsPath);
|
|
131
131
|
if (!exists) {
|
|
@@ -132,7 +132,7 @@ class PermissionManager {
|
|
|
132
132
|
async loadPermissionConfig(project) {
|
|
133
133
|
const configPath = path.join(
|
|
134
134
|
this.projectRoot,
|
|
135
|
-
'.
|
|
135
|
+
'.sce/specs',
|
|
136
136
|
project,
|
|
137
137
|
'operations/permissions.json'
|
|
138
138
|
);
|
|
@@ -158,7 +158,7 @@ class PermissionManager {
|
|
|
158
158
|
async savePermissionConfig(project, config) {
|
|
159
159
|
const configPath = path.join(
|
|
160
160
|
this.projectRoot,
|
|
161
|
-
'.
|
|
161
|
+
'.sce/specs',
|
|
162
162
|
project,
|
|
163
163
|
'operations/permissions.json'
|
|
164
164
|
);
|
|
@@ -11,7 +11,7 @@ const { DocumentType } = require('./models');
|
|
|
11
11
|
class TemplateLoader {
|
|
12
12
|
constructor(templateBasePath = null) {
|
|
13
13
|
// Default to package template directory
|
|
14
|
-
this.templateBasePath = templateBasePath || path.join(__dirname, '../../template/.
|
|
14
|
+
this.templateBasePath = templateBasePath || path.join(__dirname, '../../template/.sce/templates/operations');
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -17,6 +17,8 @@ const fs = require('fs');
|
|
|
17
17
|
const path = require('path');
|
|
18
18
|
const os = require('os');
|
|
19
19
|
|
|
20
|
+
const DEFAULT_CODEX_PERMISSION_ARGS = Object.freeze(['--ask-for-approval', 'never']);
|
|
21
|
+
|
|
20
22
|
class AgentSpawner extends EventEmitter {
|
|
21
23
|
/**
|
|
22
24
|
* @param {string} workspaceRoot - Absolute path to the project root
|
|
@@ -40,7 +42,7 @@ class AgentSpawner extends EventEmitter {
|
|
|
40
42
|
*
|
|
41
43
|
* 1. Builds the bootstrap prompt via BootstrapPromptBuilder
|
|
42
44
|
* 2. Registers the agent in AgentRegistry
|
|
43
|
-
* 3. Spawns `codex exec --full-auto --json --sandbox danger-full-access "<prompt>"`
|
|
45
|
+
* 3. Spawns `codex exec --full-auto --json --sandbox danger-full-access --ask-for-approval never "<prompt>"`
|
|
44
46
|
* 4. Sets up stdout/stderr/close handlers and timeout timer
|
|
45
47
|
*
|
|
46
48
|
* @param {string} specName - Spec to execute (e.g. "96-00-agent-orchestrator")
|
|
@@ -72,12 +74,13 @@ class AgentSpawner extends EventEmitter {
|
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
// Assemble command arguments (Req 1.1, 1.3)
|
|
77
|
+
const codexArgs = this._mergeDefaultCodexPermissionArgs(config.codexArgs);
|
|
75
78
|
const args = [
|
|
76
79
|
'exec',
|
|
77
80
|
'--full-auto',
|
|
78
81
|
'--json',
|
|
79
82
|
'--sandbox', 'danger-full-access',
|
|
80
|
-
...
|
|
83
|
+
...codexArgs,
|
|
81
84
|
prompt,
|
|
82
85
|
];
|
|
83
86
|
|
|
@@ -248,10 +251,163 @@ class AgentSpawner extends EventEmitter {
|
|
|
248
251
|
return new Map(this._agents);
|
|
249
252
|
}
|
|
250
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Resolve a structured result summary emitted by a sub-agent.
|
|
256
|
+
* The summary is extracted from captured JSON events and used by
|
|
257
|
+
* orchestration merge-governance checks.
|
|
258
|
+
*
|
|
259
|
+
* @param {string} agentId
|
|
260
|
+
* @returns {object|null}
|
|
261
|
+
*/
|
|
262
|
+
getResultSummary(agentId) {
|
|
263
|
+
const agent = this._agents.get(agentId);
|
|
264
|
+
if (!agent || !Array.isArray(agent.events)) {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
return this._extractResultSummaryFromEvents(agent.events);
|
|
268
|
+
}
|
|
269
|
+
|
|
251
270
|
// ---------------------------------------------------------------------------
|
|
252
271
|
// Private helpers
|
|
253
272
|
// ---------------------------------------------------------------------------
|
|
254
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Parse known summary carriers from agent JSON events.
|
|
276
|
+
* Prefers the candidate with the most contract fields.
|
|
277
|
+
*
|
|
278
|
+
* @param {object[]} events
|
|
279
|
+
* @returns {object|null}
|
|
280
|
+
* @private
|
|
281
|
+
*/
|
|
282
|
+
_extractResultSummaryFromEvents(events) {
|
|
283
|
+
const candidates = [];
|
|
284
|
+
const collect = (value) => {
|
|
285
|
+
if (!value || typeof value !== 'object') {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (this._summaryCandidateFieldCount(value) > 0) {
|
|
289
|
+
candidates.push(value);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
for (const event of events) {
|
|
294
|
+
if (!event || typeof event !== 'object') {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
collect(event.result_summary);
|
|
298
|
+
collect(event.summary);
|
|
299
|
+
collect(event.payload && event.payload.result_summary);
|
|
300
|
+
collect(event.payload && event.payload.summary);
|
|
301
|
+
collect(event.result && event.result.summary);
|
|
302
|
+
collect(event.data && event.data.result_summary);
|
|
303
|
+
collect(event.item && event.item.result_summary);
|
|
304
|
+
|
|
305
|
+
collect(this._tryParseSummaryFromText(event.message));
|
|
306
|
+
collect(this._tryParseSummaryFromText(event.output_text));
|
|
307
|
+
collect(this._tryParseSummaryFromText(event.text));
|
|
308
|
+
collect(this._tryParseSummaryFromText(event.item && event.item.text));
|
|
309
|
+
|
|
310
|
+
const itemContent = event.item && event.item.content;
|
|
311
|
+
if (Array.isArray(itemContent)) {
|
|
312
|
+
for (const entry of itemContent) {
|
|
313
|
+
if (typeof entry === 'string') {
|
|
314
|
+
collect(this._tryParseSummaryFromText(entry));
|
|
315
|
+
} else if (entry && typeof entry === 'object') {
|
|
316
|
+
collect(entry.result_summary);
|
|
317
|
+
collect(entry.summary);
|
|
318
|
+
collect(this._tryParseSummaryFromText(entry.text));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (candidates.length === 0) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
candidates.sort((left, right) =>
|
|
329
|
+
this._summaryCandidateFieldCount(right) - this._summaryCandidateFieldCount(left));
|
|
330
|
+
return { ...candidates[0] };
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* @param {object} candidate
|
|
335
|
+
* @returns {number}
|
|
336
|
+
* @private
|
|
337
|
+
*/
|
|
338
|
+
_summaryCandidateFieldCount(candidate) {
|
|
339
|
+
if (!candidate || typeof candidate !== 'object') {
|
|
340
|
+
return 0;
|
|
341
|
+
}
|
|
342
|
+
const fields = [
|
|
343
|
+
'spec_id',
|
|
344
|
+
'changed_files',
|
|
345
|
+
'tests_run',
|
|
346
|
+
'tests_passed',
|
|
347
|
+
'risk_level',
|
|
348
|
+
'open_issues'
|
|
349
|
+
];
|
|
350
|
+
let count = 0;
|
|
351
|
+
for (const field of fields) {
|
|
352
|
+
if (Object.prototype.hasOwnProperty.call(candidate, field)) {
|
|
353
|
+
count += 1;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return count;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Attempt to parse a JSON summary object from free-form text.
|
|
361
|
+
*
|
|
362
|
+
* @param {string} text
|
|
363
|
+
* @returns {object|null}
|
|
364
|
+
* @private
|
|
365
|
+
*/
|
|
366
|
+
_tryParseSummaryFromText(text) {
|
|
367
|
+
if (typeof text !== 'string') {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
const trimmed = text.trim();
|
|
371
|
+
if (!trimmed || !trimmed.includes('spec_id')) {
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const candidates = [trimmed];
|
|
376
|
+
const fenced = /```json\s*([\s\S]*?)```/gi;
|
|
377
|
+
let match;
|
|
378
|
+
while ((match = fenced.exec(trimmed)) !== null) {
|
|
379
|
+
if (match[1]) {
|
|
380
|
+
candidates.push(match[1].trim());
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const firstBrace = trimmed.indexOf('{');
|
|
385
|
+
const lastBrace = trimmed.lastIndexOf('}');
|
|
386
|
+
if (firstBrace >= 0 && lastBrace > firstBrace) {
|
|
387
|
+
candidates.push(trimmed.slice(firstBrace, lastBrace + 1));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
for (const candidate of candidates) {
|
|
391
|
+
if (!candidate || typeof candidate !== 'string') {
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
try {
|
|
395
|
+
const parsed = JSON.parse(candidate);
|
|
396
|
+
if (parsed && typeof parsed === 'object') {
|
|
397
|
+
if (parsed.result_summary && typeof parsed.result_summary === 'object') {
|
|
398
|
+
return parsed.result_summary;
|
|
399
|
+
}
|
|
400
|
+
if (this._summaryCandidateFieldCount(parsed) > 0) {
|
|
401
|
+
return parsed;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
} catch (_err) {
|
|
405
|
+
// Ignore parse failures and continue.
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
410
|
+
|
|
255
411
|
/**
|
|
256
412
|
* Ensure bootstrap prompt is a non-empty string before using it in spawn args.
|
|
257
413
|
* @param {unknown} prompt
|
|
@@ -624,6 +780,28 @@ class AgentSpawner extends EventEmitter {
|
|
|
624
780
|
return false;
|
|
625
781
|
}
|
|
626
782
|
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Merge default Codex permission flags into configured codex args.
|
|
786
|
+
* If user explicitly sets ask-for-approval mode, keep user value.
|
|
787
|
+
*
|
|
788
|
+
* @param {string[]|undefined|null} codexArgs
|
|
789
|
+
* @returns {string[]}
|
|
790
|
+
* @private
|
|
791
|
+
*/
|
|
792
|
+
_mergeDefaultCodexPermissionArgs(codexArgs) {
|
|
793
|
+
const args = Array.isArray(codexArgs)
|
|
794
|
+
? codexArgs.map(value => `${value}`)
|
|
795
|
+
: [];
|
|
796
|
+
const hasAskForApproval = args.some((token) =>
|
|
797
|
+
token === '--ask-for-approval'
|
|
798
|
+
|| token === '-a'
|
|
799
|
+
|| token.startsWith('--ask-for-approval='));
|
|
800
|
+
if (!hasAskForApproval) {
|
|
801
|
+
return [...args, ...DEFAULT_CODEX_PERMISSION_ARGS];
|
|
802
|
+
}
|
|
803
|
+
return args;
|
|
804
|
+
}
|
|
627
805
|
}
|
|
628
806
|
|
|
629
807
|
module.exports = { AgentSpawner };
|
|
@@ -19,6 +19,7 @@ const STEERING_FILES = [
|
|
|
19
19
|
'CURRENT_CONTEXT.md',
|
|
20
20
|
'RULES_GUIDE.md',
|
|
21
21
|
];
|
|
22
|
+
const STEERING_DIR = '.sce/steering';
|
|
22
23
|
|
|
23
24
|
class BootstrapPromptBuilder {
|
|
24
25
|
/**
|
|
@@ -46,7 +47,7 @@ class BootstrapPromptBuilder {
|
|
|
46
47
|
* @returns {Promise<string>} The assembled prompt
|
|
47
48
|
*/
|
|
48
49
|
async buildPrompt(specName) {
|
|
49
|
-
const specPath = `.
|
|
50
|
+
const specPath = `.sce/specs/${specName}/`;
|
|
50
51
|
const steeringContext = await this._loadSteeringContext();
|
|
51
52
|
const taskInstructions = this._buildTaskInstructions(specName, specPath);
|
|
52
53
|
const readmeSummary = await this._loadReadmeSummary();
|
|
@@ -78,17 +79,16 @@ class BootstrapPromptBuilder {
|
|
|
78
79
|
// ---------------------------------------------------------------------------
|
|
79
80
|
|
|
80
81
|
/**
|
|
81
|
-
* Load and concatenate all steering files from `.
|
|
82
|
+
* Load and concatenate all steering files from `.sce/steering/`.
|
|
82
83
|
* Missing files are silently skipped.
|
|
83
84
|
* @returns {Promise<string>}
|
|
84
85
|
* @private
|
|
85
86
|
*/
|
|
86
87
|
async _loadSteeringContext() {
|
|
87
|
-
const steeringDir = path.join(this._workspaceRoot, '.kiro', 'steering');
|
|
88
88
|
const sections = [];
|
|
89
89
|
|
|
90
90
|
for (const filename of STEERING_FILES) {
|
|
91
|
-
const filePath = path.join(
|
|
91
|
+
const filePath = path.join(this._workspaceRoot, STEERING_DIR, filename);
|
|
92
92
|
try {
|
|
93
93
|
const content = await fs.readFile(filePath, 'utf8');
|
|
94
94
|
sections.push(`### ${filename}\n\n${content.trim()}`);
|
|
@@ -101,14 +101,14 @@ class BootstrapPromptBuilder {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
/**
|
|
104
|
-
* Load a short summary from `.
|
|
104
|
+
* Load a short summary from `.sce/README.md`.
|
|
105
105
|
* Returns the first ~40 lines (up to the first `---` separator after the
|
|
106
106
|
* opening block) to keep the prompt concise.
|
|
107
107
|
* @returns {Promise<string>}
|
|
108
108
|
* @private
|
|
109
109
|
*/
|
|
110
110
|
async _loadReadmeSummary() {
|
|
111
|
-
const readmePath = path.join(this._workspaceRoot, '.
|
|
111
|
+
const readmePath = path.join(this._workspaceRoot, '.sce', 'README.md');
|
|
112
112
|
try {
|
|
113
113
|
const content = await fs.readFile(readmePath, 'utf8');
|
|
114
114
|
// Take the first meaningful section (up to the capabilities list)
|
|
@@ -172,6 +172,9 @@ class BootstrapPromptBuilder {
|
|
|
172
172
|
'5. Mark each task as completed (change `[ ]` or `[-]` to `[x]`) after finishing.',
|
|
173
173
|
'6. Run relevant tests to verify your implementation before moving on.',
|
|
174
174
|
'7. If a task fails after multiple attempts, document the issue and continue.',
|
|
175
|
+
'8. At completion, output a final JSON object named result_summary with fields:',
|
|
176
|
+
' spec_id, changed_files, tests_run, tests_passed, risk_level, open_issues.',
|
|
177
|
+
' Keep risk_level in: low | medium | high | unknown.',
|
|
175
178
|
'',
|
|
176
179
|
'Quality requirements:',
|
|
177
180
|
'- All code must compile and pass linting.',
|