scene-capability-engine 3.3.5 → 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 +130 -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 +4 -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/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 +192 -153
- 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/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 +6 -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 +27 -2
- package/lib/orchestrator/bootstrap-prompt-builder.js +6 -6
- package/lib/orchestrator/orchestration-engine.js +1 -1
- 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 +9 -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
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const yaml = require('js-yaml');
|
|
4
|
+
const semver = require('semver');
|
|
5
|
+
|
|
6
|
+
const CONTRACT_SCHEMA_VERSION = '1.0';
|
|
7
|
+
const SCE_STEERING_DIR = path.join('.sce', 'steering');
|
|
8
|
+
const MANIFEST_FILENAME = 'manifest.yaml';
|
|
9
|
+
|
|
10
|
+
const DEFAULT_LAYER_FILES = Object.freeze({
|
|
11
|
+
core_principles: 'CORE_PRINCIPLES.md',
|
|
12
|
+
environment: 'ENVIRONMENT.md',
|
|
13
|
+
current_context: 'CURRENT_CONTEXT.md',
|
|
14
|
+
rules_guide: 'RULES_GUIDE.md',
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const DEFAULT_MANIFEST = Object.freeze({
|
|
18
|
+
schema_version: CONTRACT_SCHEMA_VERSION,
|
|
19
|
+
engine: 'sce',
|
|
20
|
+
profile: 'default',
|
|
21
|
+
description: 'SCE universal steering contract for cross-agent orchestration',
|
|
22
|
+
layers: { ...DEFAULT_LAYER_FILES },
|
|
23
|
+
compatibility: {
|
|
24
|
+
codex: '>=0.0.0',
|
|
25
|
+
claude: '>=0.0.0',
|
|
26
|
+
cursor: '>=0.0.0',
|
|
27
|
+
generic: '*',
|
|
28
|
+
},
|
|
29
|
+
session: {
|
|
30
|
+
root: '.sce/sessions',
|
|
31
|
+
default_status: 'active',
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const TOOL_RUNTIME_PROFILES = Object.freeze({
|
|
36
|
+
codex: {
|
|
37
|
+
recommended_command: 'codex exec --sandbox danger-full-access --ask-for-approval never',
|
|
38
|
+
default_permission_args: ['--sandbox', 'danger-full-access', '--ask-for-approval', 'never'],
|
|
39
|
+
notes: 'Full runtime permissions with no approval prompts.',
|
|
40
|
+
},
|
|
41
|
+
claude: {
|
|
42
|
+
recommended_command: 'claude --dangerously-skip-permission',
|
|
43
|
+
default_permission_args: ['--dangerously-skip-permission'],
|
|
44
|
+
notes: 'Recommended full permission mode for SCE-driven autonomous tasks.',
|
|
45
|
+
},
|
|
46
|
+
'claude-code': {
|
|
47
|
+
recommended_command: 'claude --dangerously-skip-permission',
|
|
48
|
+
default_permission_args: ['--dangerously-skip-permission'],
|
|
49
|
+
notes: 'Alias of claude profile.',
|
|
50
|
+
},
|
|
51
|
+
cursor: {
|
|
52
|
+
recommended_command: 'cursor',
|
|
53
|
+
default_permission_args: [],
|
|
54
|
+
notes: 'Permission handling depends on Cursor runtime policy.',
|
|
55
|
+
},
|
|
56
|
+
generic: {
|
|
57
|
+
recommended_command: '',
|
|
58
|
+
default_permission_args: [],
|
|
59
|
+
notes: 'Provide runtime permission args in the target agent adapter.',
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
function normalizeToolName(value) {
|
|
64
|
+
const raw = `${value || ''}`.trim().toLowerCase();
|
|
65
|
+
if (!raw) {
|
|
66
|
+
return 'generic';
|
|
67
|
+
}
|
|
68
|
+
if (raw === 'claude-code') {
|
|
69
|
+
return 'claude';
|
|
70
|
+
}
|
|
71
|
+
if (raw === 'codex' || raw === 'claude' || raw === 'cursor') {
|
|
72
|
+
return raw;
|
|
73
|
+
}
|
|
74
|
+
return 'generic';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function toRelativePosix(workspaceRoot, absolutePath) {
|
|
78
|
+
return path.relative(workspaceRoot, absolutePath).replace(/\\/g, '/');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
class SteeringContract {
|
|
82
|
+
constructor(workspaceRoot) {
|
|
83
|
+
this._workspaceRoot = workspaceRoot;
|
|
84
|
+
this._sceSteeringDir = path.join(workspaceRoot, SCE_STEERING_DIR);
|
|
85
|
+
this._manifestPath = path.join(this._sceSteeringDir, MANIFEST_FILENAME);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
get manifestPath() {
|
|
89
|
+
return this._manifestPath;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
get sceSteeringDir() {
|
|
93
|
+
return this._sceSteeringDir;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async ensureContract() {
|
|
97
|
+
await fs.ensureDir(this._sceSteeringDir);
|
|
98
|
+
|
|
99
|
+
let createdManifest = false;
|
|
100
|
+
if (!await fs.pathExists(this._manifestPath)) {
|
|
101
|
+
await fs.writeFile(this._manifestPath, yaml.dump(DEFAULT_MANIFEST, { lineWidth: 120 }), 'utf8');
|
|
102
|
+
createdManifest = true;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const manifest = await this.loadManifest();
|
|
106
|
+
const preparedLayers = [];
|
|
107
|
+
for (const [layerName, filename] of Object.entries(manifest.layers)) {
|
|
108
|
+
const targetPath = path.join(this._sceSteeringDir, filename);
|
|
109
|
+
if (await fs.pathExists(targetPath)) {
|
|
110
|
+
preparedLayers.push({ layer: layerName, file: filename, source: 'sce' });
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
await fs.writeFile(targetPath, this._buildDefaultLayerContent(layerName, filename), 'utf8');
|
|
115
|
+
preparedLayers.push({ layer: layerName, file: filename, source: 'template' });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
createdManifest,
|
|
120
|
+
manifestPath: toRelativePosix(this._workspaceRoot, this._manifestPath),
|
|
121
|
+
preparedLayers,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async loadManifest() {
|
|
126
|
+
let raw = {};
|
|
127
|
+
try {
|
|
128
|
+
if (await fs.pathExists(this._manifestPath)) {
|
|
129
|
+
raw = yaml.load(await fs.readFile(this._manifestPath, 'utf8')) || {};
|
|
130
|
+
}
|
|
131
|
+
} catch (_error) {
|
|
132
|
+
raw = {};
|
|
133
|
+
}
|
|
134
|
+
return this._normalizeManifest(raw);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async resolveLayerFile(filename) {
|
|
138
|
+
const scePath = path.join(this._sceSteeringDir, filename);
|
|
139
|
+
if (await fs.pathExists(scePath)) {
|
|
140
|
+
return { source: 'sce', path: scePath };
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async loadLayerBundle() {
|
|
146
|
+
const manifest = await this.loadManifest();
|
|
147
|
+
const layers = {};
|
|
148
|
+
const sourceSet = new Set();
|
|
149
|
+
|
|
150
|
+
for (const [layerName, filename] of Object.entries(manifest.layers)) {
|
|
151
|
+
const resolved = await this.resolveLayerFile(filename);
|
|
152
|
+
if (!resolved) {
|
|
153
|
+
layers[layerName] = {
|
|
154
|
+
file: filename,
|
|
155
|
+
source: 'missing',
|
|
156
|
+
path: null,
|
|
157
|
+
content: null,
|
|
158
|
+
};
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const content = await fs.readFile(resolved.path, 'utf8');
|
|
163
|
+
sourceSet.add(resolved.source);
|
|
164
|
+
layers[layerName] = {
|
|
165
|
+
file: filename,
|
|
166
|
+
source: resolved.source,
|
|
167
|
+
path: toRelativePosix(this._workspaceRoot, resolved.path),
|
|
168
|
+
content: content.trim(),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
manifest,
|
|
174
|
+
layers,
|
|
175
|
+
source_mode: this._resolveSourceMode(sourceSet),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async buildCompilePayload(tool, agentVersion = null) {
|
|
180
|
+
const normalizedTool = normalizeToolName(tool);
|
|
181
|
+
const runtime = TOOL_RUNTIME_PROFILES[normalizedTool] || TOOL_RUNTIME_PROFILES.generic;
|
|
182
|
+
const bundle = await this.loadLayerBundle();
|
|
183
|
+
const compatibility = this._evaluateCompatibility(bundle.manifest, normalizedTool, agentVersion);
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
schema_version: CONTRACT_SCHEMA_VERSION,
|
|
187
|
+
generated_at: new Date().toISOString(),
|
|
188
|
+
tool: normalizedTool,
|
|
189
|
+
agent_version: agentVersion ? `${agentVersion}` : null,
|
|
190
|
+
source_mode: bundle.source_mode,
|
|
191
|
+
manifest: bundle.manifest,
|
|
192
|
+
runtime,
|
|
193
|
+
compatibility,
|
|
194
|
+
layers: bundle.layers,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
renderMarkdown(payload) {
|
|
199
|
+
const sections = [];
|
|
200
|
+
sections.push('# SCE Steering Compile');
|
|
201
|
+
sections.push('');
|
|
202
|
+
sections.push(`- schema_version: ${payload.schema_version}`);
|
|
203
|
+
sections.push(`- generated_at: ${payload.generated_at}`);
|
|
204
|
+
sections.push(`- tool: ${payload.tool}`);
|
|
205
|
+
sections.push(`- agent_version: ${payload.agent_version || '(not provided)'}`);
|
|
206
|
+
sections.push(`- source_mode: ${payload.source_mode}`);
|
|
207
|
+
sections.push('');
|
|
208
|
+
sections.push('## Runtime Permission Profile');
|
|
209
|
+
sections.push('');
|
|
210
|
+
sections.push(`- recommended_command: ${payload.runtime.recommended_command || '(none)'}`);
|
|
211
|
+
sections.push(`- default_permission_args: ${payload.runtime.default_permission_args.join(' ') || '(none)'}`);
|
|
212
|
+
sections.push(`- notes: ${payload.runtime.notes}`);
|
|
213
|
+
sections.push('');
|
|
214
|
+
sections.push('## Compatibility');
|
|
215
|
+
sections.push('');
|
|
216
|
+
sections.push(`- rule: ${payload.compatibility.rule}`);
|
|
217
|
+
sections.push(`- supported: ${payload.compatibility.supported === null ? 'unknown' : payload.compatibility.supported}`);
|
|
218
|
+
sections.push(`- reason: ${payload.compatibility.reason}`);
|
|
219
|
+
sections.push('');
|
|
220
|
+
sections.push('## Layers');
|
|
221
|
+
sections.push('');
|
|
222
|
+
|
|
223
|
+
for (const [layerName, layer] of Object.entries(payload.layers)) {
|
|
224
|
+
sections.push(`### ${layerName} (${layer.file})`);
|
|
225
|
+
sections.push(`- source: ${layer.source}`);
|
|
226
|
+
sections.push(`- path: ${layer.path || '(missing)'}`);
|
|
227
|
+
sections.push('');
|
|
228
|
+
if (layer.content) {
|
|
229
|
+
sections.push(layer.content);
|
|
230
|
+
} else {
|
|
231
|
+
sections.push('(missing)');
|
|
232
|
+
}
|
|
233
|
+
sections.push('');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return sections.join('\n').trim() + '\n';
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
_normalizeManifest(raw) {
|
|
240
|
+
const layers = (raw && raw.layers && typeof raw.layers === 'object')
|
|
241
|
+
? raw.layers
|
|
242
|
+
: {};
|
|
243
|
+
const normalizedLayers = {};
|
|
244
|
+
for (const [key, filename] of Object.entries(DEFAULT_LAYER_FILES)) {
|
|
245
|
+
normalizedLayers[key] = typeof layers[key] === 'string' && layers[key].trim()
|
|
246
|
+
? layers[key].trim()
|
|
247
|
+
: filename;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
schema_version: `${raw.schema_version || DEFAULT_MANIFEST.schema_version}`,
|
|
252
|
+
engine: `${raw.engine || DEFAULT_MANIFEST.engine}`,
|
|
253
|
+
profile: `${raw.profile || DEFAULT_MANIFEST.profile}`,
|
|
254
|
+
description: `${raw.description || DEFAULT_MANIFEST.description}`,
|
|
255
|
+
layers: normalizedLayers,
|
|
256
|
+
compatibility: this._normalizeCompatibility(raw.compatibility),
|
|
257
|
+
session: {
|
|
258
|
+
root: raw.session && typeof raw.session.root === 'string'
|
|
259
|
+
? raw.session.root
|
|
260
|
+
: DEFAULT_MANIFEST.session.root,
|
|
261
|
+
default_status: raw.session && typeof raw.session.default_status === 'string'
|
|
262
|
+
? raw.session.default_status
|
|
263
|
+
: DEFAULT_MANIFEST.session.default_status,
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
_resolveSourceMode(sourceSet) {
|
|
269
|
+
if (sourceSet.has('sce')) {
|
|
270
|
+
return 'sce';
|
|
271
|
+
}
|
|
272
|
+
return 'empty';
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
_normalizeCompatibility(rawCompatibility) {
|
|
276
|
+
const input = rawCompatibility && typeof rawCompatibility === 'object'
|
|
277
|
+
? rawCompatibility
|
|
278
|
+
: {};
|
|
279
|
+
const normalized = {};
|
|
280
|
+
for (const [tool, defaultRange] of Object.entries(DEFAULT_MANIFEST.compatibility)) {
|
|
281
|
+
const value = input[tool];
|
|
282
|
+
normalized[tool] = typeof value === 'string' && value.trim() ? value.trim() : defaultRange;
|
|
283
|
+
}
|
|
284
|
+
return normalized;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
_evaluateCompatibility(manifest, tool, agentVersion) {
|
|
288
|
+
const rule = manifest.compatibility && manifest.compatibility[tool]
|
|
289
|
+
? manifest.compatibility[tool]
|
|
290
|
+
: (manifest.compatibility && manifest.compatibility.generic) || '*';
|
|
291
|
+
if (!agentVersion || `${agentVersion}`.trim() === '') {
|
|
292
|
+
return {
|
|
293
|
+
rule,
|
|
294
|
+
supported: null,
|
|
295
|
+
reason: 'agent version not provided',
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
const coerced = semver.coerce(`${agentVersion}`.trim());
|
|
299
|
+
if (!coerced) {
|
|
300
|
+
return {
|
|
301
|
+
rule,
|
|
302
|
+
supported: null,
|
|
303
|
+
reason: `unable to parse version: ${agentVersion}`,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
const parsedVersion = semver.valid(coerced.version);
|
|
307
|
+
const supported = rule === '*' ? true : semver.satisfies(parsedVersion, rule, { includePrerelease: true });
|
|
308
|
+
return {
|
|
309
|
+
rule,
|
|
310
|
+
supported,
|
|
311
|
+
reason: supported
|
|
312
|
+
? `version ${parsedVersion} satisfies ${rule}`
|
|
313
|
+
: `version ${parsedVersion} does not satisfy ${rule}`,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
_buildDefaultLayerContent(layerName, filename) {
|
|
318
|
+
return [
|
|
319
|
+
`# ${filename}`,
|
|
320
|
+
'',
|
|
321
|
+
`Managed by SCE universal steering contract.`,
|
|
322
|
+
`Layer: ${layerName}`,
|
|
323
|
+
'',
|
|
324
|
+
'- Fill this file with project-specific constraints and guidance.',
|
|
325
|
+
].join('\n');
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
module.exports = {
|
|
330
|
+
SteeringContract,
|
|
331
|
+
CONTRACT_SCHEMA_VERSION,
|
|
332
|
+
DEFAULT_LAYER_FILES,
|
|
333
|
+
DEFAULT_MANIFEST,
|
|
334
|
+
MANIFEST_FILENAME,
|
|
335
|
+
SCE_STEERING_DIR,
|
|
336
|
+
TOOL_RUNTIME_PROFILES,
|
|
337
|
+
normalizeToolName,
|
|
338
|
+
};
|
|
@@ -9,7 +9,7 @@ function createId(prefix) {
|
|
|
9
9
|
class AuditEmitter {
|
|
10
10
|
constructor(projectRoot = process.cwd(), options = {}) {
|
|
11
11
|
this.projectRoot = projectRoot;
|
|
12
|
-
this.auditFile = options.auditFile || path.join(projectRoot, '.
|
|
12
|
+
this.auditFile = options.auditFile || path.join(projectRoot, '.sce', 'audit', 'scene-runtime-events.jsonl');
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
async emit(eventType, payload = {}) {
|
|
@@ -2,10 +2,10 @@ const path = require('path');
|
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
3
|
|
|
4
4
|
const DEFAULT_BINDING_PLUGIN_DIRS = [
|
|
5
|
-
'.
|
|
6
|
-
'.
|
|
5
|
+
'.sce/plugins/scene-bindings',
|
|
6
|
+
'.sce/config/scene-bindings'
|
|
7
7
|
];
|
|
8
|
-
const DEFAULT_BINDING_PLUGIN_MANIFEST = '.
|
|
8
|
+
const DEFAULT_BINDING_PLUGIN_MANIFEST = '.sce/config/scene-binding-plugins.json';
|
|
9
9
|
|
|
10
10
|
function isPlainObject(value) {
|
|
11
11
|
return value && typeof value === 'object' && !Array.isArray(value);
|
|
@@ -1838,7 +1838,7 @@ async function discoverResources(client, options = {}) {
|
|
|
1838
1838
|
/**
|
|
1839
1839
|
* Default output directory for extracted templates.
|
|
1840
1840
|
*/
|
|
1841
|
-
const DEFAULT_OUT_DIR = '.
|
|
1841
|
+
const DEFAULT_OUT_DIR = '.sce/templates/extracted';
|
|
1842
1842
|
|
|
1843
1843
|
/**
|
|
1844
1844
|
* Run the full extraction pipeline.
|
|
@@ -11,7 +11,7 @@ class SceneLoader {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
async loadFromSpec(specName, relativePath = 'custom/scene.yaml') {
|
|
14
|
-
const filePath = path.join(this.projectPath, '.
|
|
14
|
+
const filePath = path.join(this.projectPath, '.sce', 'specs', specName, relativePath);
|
|
15
15
|
return this.loadFromFile(filePath);
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -7,7 +7,7 @@ class ContextCollector {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
async collect() {
|
|
10
|
-
const kiroDir = path.join(this.projectPath, '.
|
|
10
|
+
const kiroDir = path.join(this.projectPath, '.sce');
|
|
11
11
|
const specsDir = path.join(kiroDir, 'specs');
|
|
12
12
|
const hasKiro = await fs.pathExists(kiroDir);
|
|
13
13
|
const existingSpecs = await this._listSpecs(specsDir);
|
|
@@ -6,7 +6,7 @@ const { runSpecGate } = require('../../commands/spec-gate');
|
|
|
6
6
|
function createDefaultStageAdapters(projectPath = process.cwd()) {
|
|
7
7
|
return {
|
|
8
8
|
requirements: async context => {
|
|
9
|
-
const specDir = path.join(projectPath, '.
|
|
9
|
+
const specDir = path.join(projectPath, '.sce', 'specs', context.specId);
|
|
10
10
|
const requirementsPath = path.join(specDir, 'requirements.md');
|
|
11
11
|
|
|
12
12
|
if (!await fs.pathExists(requirementsPath)) {
|
|
@@ -37,7 +37,7 @@ function createDefaultStageAdapters(projectPath = process.cwd()) {
|
|
|
37
37
|
},
|
|
38
38
|
|
|
39
39
|
design: async context => {
|
|
40
|
-
const designPath = path.join(projectPath, '.
|
|
40
|
+
const designPath = path.join(projectPath, '.sce', 'specs', context.specId, 'design.md');
|
|
41
41
|
const exists = await fs.pathExists(designPath);
|
|
42
42
|
|
|
43
43
|
if (!exists) {
|
|
@@ -62,7 +62,7 @@ function createDefaultStageAdapters(projectPath = process.cwd()) {
|
|
|
62
62
|
},
|
|
63
63
|
|
|
64
64
|
tasks: async context => {
|
|
65
|
-
const tasksPath = path.join(projectPath, '.
|
|
65
|
+
const tasksPath = path.join(projectPath, '.sce', 'specs', context.specId, 'tasks.md');
|
|
66
66
|
const exists = await fs.pathExists(tasksPath);
|
|
67
67
|
|
|
68
68
|
if (!exists) {
|
|
@@ -31,7 +31,7 @@ class PolicyLoader {
|
|
|
31
31
|
: path.join(this.projectPath, explicitPath);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const projectPolicy = path.join(this.projectPath, '.
|
|
34
|
+
const projectPolicy = path.join(this.projectPath, '.sce', 'config', 'spec-gate-policy.json');
|
|
35
35
|
if (fs.existsSync(projectPolicy)) {
|
|
36
36
|
return projectPolicy;
|
|
37
37
|
}
|
|
@@ -8,7 +8,7 @@ function createDefaultRules(projectPath = process.cwd()) {
|
|
|
8
8
|
id: 'mandatory',
|
|
9
9
|
description: 'Verify mandatory Spec files exist',
|
|
10
10
|
async execute(context) {
|
|
11
|
-
const specPath = path.join(projectPath, '.
|
|
11
|
+
const specPath = path.join(projectPath, '.sce', 'specs', context.specId);
|
|
12
12
|
const requiredFiles = ['requirements.md', 'design.md', 'tasks.md'];
|
|
13
13
|
const checks = await Promise.all(requiredFiles.map(async fileName => {
|
|
14
14
|
const filePath = path.join(specPath, fileName);
|
|
@@ -34,7 +34,7 @@ function createDefaultRules(projectPath = process.cwd()) {
|
|
|
34
34
|
id: 'tests',
|
|
35
35
|
description: 'Verify tasks include explicit validation intent',
|
|
36
36
|
async execute(context) {
|
|
37
|
-
const tasksPath = path.join(projectPath, '.
|
|
37
|
+
const tasksPath = path.join(projectPath, '.sce', 'specs', context.specId, 'tasks.md');
|
|
38
38
|
if (!await fs.pathExists(tasksPath)) {
|
|
39
39
|
return {
|
|
40
40
|
passed: false,
|
|
@@ -79,7 +79,7 @@ function createDefaultRules(projectPath = process.cwd()) {
|
|
|
79
79
|
id: 'config_consistency',
|
|
80
80
|
description: 'Verify project-level sce config baseline exists',
|
|
81
81
|
async execute() {
|
|
82
|
-
const kiroDir = path.join(projectPath, '.
|
|
82
|
+
const kiroDir = path.join(projectPath, '.sce');
|
|
83
83
|
const configDir = path.join(kiroDir, 'config');
|
|
84
84
|
const hasKiro = await fs.pathExists(kiroDir);
|
|
85
85
|
const hasConfig = await fs.pathExists(configDir);
|
|
@@ -87,10 +87,10 @@ function createDefaultRules(projectPath = process.cwd()) {
|
|
|
87
87
|
const ratio = hasKiro && hasConfig ? 1 : hasKiro ? 0.5 : 0;
|
|
88
88
|
const warnings = [];
|
|
89
89
|
if (!hasKiro) {
|
|
90
|
-
warnings.push('.
|
|
90
|
+
warnings.push('.sce directory missing');
|
|
91
91
|
}
|
|
92
92
|
if (hasKiro && !hasConfig) {
|
|
93
|
-
warnings.push('.
|
|
93
|
+
warnings.push('.sce/config directory missing');
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
return {
|
|
@@ -108,7 +108,7 @@ function createDefaultRules(projectPath = process.cwd()) {
|
|
|
108
108
|
id: 'traceability',
|
|
109
109
|
description: 'Verify requirement-design-task traceability hints',
|
|
110
110
|
async execute(context) {
|
|
111
|
-
const specPath = path.join(projectPath, '.
|
|
111
|
+
const specPath = path.join(projectPath, '.sce', 'specs', context.specId);
|
|
112
112
|
const designPath = path.join(specPath, 'design.md');
|
|
113
113
|
const tasksPath = path.join(specPath, 'tasks.md');
|
|
114
114
|
|
|
@@ -9,7 +9,7 @@ const path = require('path');
|
|
|
9
9
|
class AdoptionConfig {
|
|
10
10
|
constructor(projectPath) {
|
|
11
11
|
this.projectPath = projectPath;
|
|
12
|
-
this.configPath = path.join(projectPath, '.
|
|
12
|
+
this.configPath = path.join(projectPath, '.sce', 'adoption-config.json');
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -19,7 +19,7 @@ class ComplianceErrorReporter {
|
|
|
19
19
|
|
|
20
20
|
let message = '\n';
|
|
21
21
|
message += chalk.red.bold('❌ Steering Directory Compliance Check Failed') + '\n\n';
|
|
22
|
-
message += 'The .
|
|
22
|
+
message += 'The .sce/steering/ directory contains files or subdirectories that are not allowed.\n';
|
|
23
23
|
message += 'This directory is automatically loaded in every AI session, so keeping it clean is critical.\n\n';
|
|
24
24
|
|
|
25
25
|
message += chalk.yellow.bold('Violations Found:') + '\n';
|
|
@@ -45,8 +45,8 @@ class ComplianceErrorReporter {
|
|
|
45
45
|
message += ' ✓ RULES_GUIDE.md\n';
|
|
46
46
|
|
|
47
47
|
message += '\n' + chalk.cyan.bold('Fix Suggestions:') + '\n';
|
|
48
|
-
message += ' • Move analysis reports to: .
|
|
49
|
-
message += ' • Move historical data to: .
|
|
48
|
+
message += ' • Move analysis reports to: .sce/specs/{spec-name}/reports/\n';
|
|
49
|
+
message += ' • Move historical data to: .sce/specs/{spec-name}/\n';
|
|
50
50
|
message += ' • Move detailed docs to: docs/\n';
|
|
51
51
|
message += ' • Delete temporary files\n';
|
|
52
52
|
|
|
@@ -13,9 +13,9 @@ const fs = require('fs-extra');
|
|
|
13
13
|
const fsUtils = require('../utils/fs-utils');
|
|
14
14
|
const { MultiAgentConfig } = require('../collab/multi-agent-config');
|
|
15
15
|
|
|
16
|
-
const STEERING_DIR = '.
|
|
16
|
+
const STEERING_DIR = '.sce/steering';
|
|
17
17
|
const CONTEXT_FILENAME = 'CURRENT_CONTEXT.md';
|
|
18
|
-
const SPECS_DIR = '.
|
|
18
|
+
const SPECS_DIR = '.sce/specs';
|
|
19
19
|
|
|
20
20
|
class ContextSyncManager {
|
|
21
21
|
/**
|
package/lib/steering/index.js
CHANGED
|
@@ -44,7 +44,7 @@ async function runSteeringComplianceCheck(options = {}) {
|
|
|
44
44
|
|
|
45
45
|
// Perform compliance check with performance measurement
|
|
46
46
|
const startTime = Date.now();
|
|
47
|
-
const steeringPath = path.join(projectPath, '.
|
|
47
|
+
const steeringPath = path.join(projectPath, '.sce', 'steering');
|
|
48
48
|
const result = checker.check(steeringPath);
|
|
49
49
|
const duration = Date.now() - startTime;
|
|
50
50
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SpecSteering - Spec 级 steering.md 管理
|
|
3
3
|
*
|
|
4
|
-
* 负责 `.
|
|
4
|
+
* 负责 `.sce/specs/{spec-name}/steering.md` 的 CRUD 操作和模板管理。
|
|
5
5
|
* 在单 Agent 模式下 createTemplate 为 no-op。
|
|
6
6
|
*
|
|
7
7
|
* Requirements: 1.1, 1.3, 1.4, 7.1, 7.2, 7.3
|
|
@@ -13,7 +13,7 @@ const fsUtils = require('../utils/fs-utils');
|
|
|
13
13
|
const { MultiAgentConfig } = require('../collab/multi-agent-config');
|
|
14
14
|
|
|
15
15
|
const STEERING_FILENAME = 'steering.md';
|
|
16
|
-
const SPECS_DIR = '.
|
|
16
|
+
const SPECS_DIR = '.sce/specs';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Section headers used in steering.md template.
|
|
@@ -4,7 +4,7 @@ const path = require('path');
|
|
|
4
4
|
/**
|
|
5
5
|
* SteeringComplianceChecker - Validates steering directory compliance
|
|
6
6
|
*
|
|
7
|
-
* Ensures the .
|
|
7
|
+
* Ensures the .sce/steering/ directory contains only allowed files
|
|
8
8
|
* and no subdirectories to prevent context pollution and excessive
|
|
9
9
|
* token consumption in AI sessions.
|
|
10
10
|
*/
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* L1: CORE_PRINCIPLES.md (通用约束)
|
|
5
5
|
* L2: ENVIRONMENT.md (环境约束)
|
|
6
6
|
* L3: CURRENT_CONTEXT.md (全局上下文)
|
|
7
|
-
* L4: .
|
|
7
|
+
* L4: .sce/specs/{spec-name}/steering.md (Spec 级约束, via SpecSteering)
|
|
8
8
|
*
|
|
9
9
|
* 单 Agent 模式下跳过 L4。
|
|
10
10
|
*
|
|
@@ -16,7 +16,7 @@ const fs = require('fs-extra');
|
|
|
16
16
|
const { SpecSteering } = require('./spec-steering');
|
|
17
17
|
const { MultiAgentConfig } = require('../collab/multi-agent-config');
|
|
18
18
|
|
|
19
|
-
const STEERING_DIR = '.
|
|
19
|
+
const STEERING_DIR = '.sce/steering';
|
|
20
20
|
|
|
21
21
|
const LAYER_FILES = {
|
|
22
22
|
l1: 'CORE_PRINCIPLES.md',
|
|
@@ -104,7 +104,6 @@ class SteeringLoader {
|
|
|
104
104
|
async _loadLayerFile(layerKey) {
|
|
105
105
|
const filename = LAYER_FILES[layerKey];
|
|
106
106
|
const filePath = path.join(this._workspaceRoot, STEERING_DIR, filename);
|
|
107
|
-
|
|
108
107
|
try {
|
|
109
108
|
const exists = await fs.pathExists(filePath);
|
|
110
109
|
if (!exists) {
|
|
@@ -112,9 +111,9 @@ class SteeringLoader {
|
|
|
112
111
|
}
|
|
113
112
|
return await fs.readFile(filePath, 'utf8');
|
|
114
113
|
} catch (err) {
|
|
115
|
-
console.warn(`[SteeringLoader] Failed to read ${layerKey} (${filename}): ${err.message}`);
|
|
116
|
-
return null;
|
|
114
|
+
console.warn(`[SteeringLoader] Failed to read ${layerKey} (${filename}) from ${STEERING_DIR}: ${err.message}`);
|
|
117
115
|
}
|
|
116
|
+
return null;
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
/**
|