scene-capability-engine 3.3.22 → 3.3.24
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 +54 -0
- package/bin/scene-capability-engine.js +10 -0
- package/docs/adoption-guide.md +8 -0
- package/docs/autonomous-control-guide.md +8 -8
- package/docs/command-reference.md +51 -2
- package/docs/errorbook-registry.md +128 -0
- package/lib/adoption/adoption-strategy.js +2 -0
- package/lib/adoption/backup-manager.js +2 -0
- package/lib/adoption/detection-engine.js +2 -0
- package/lib/adoption/file-classifier.js +3 -1
- package/lib/adoption/smart-orchestrator.js +2 -0
- package/lib/adoption/strategy-selector.js +2 -0
- package/lib/adoption/template-sync.js +2 -0
- package/lib/auto/config-schema.js +7 -7
- package/lib/commands/auto.js +2 -2
- package/lib/commands/errorbook.js +968 -4
- package/lib/commands/spec-bootstrap.js +17 -2
- package/lib/commands/spec-domain.js +217 -0
- package/lib/commands/studio.js +314 -9
- package/lib/spec/domain-modeling.js +439 -0
- package/lib/spec-gate/policy/default-policy.js +1 -0
- package/lib/spec-gate/rules/default-rules.js +8 -0
- package/package.json +3 -2
- package/template/.sce/config/errorbook-registry.json +13 -0
- package/template/.sce/steering/CORE_PRINCIPLES.md +30 -1
|
@@ -11,6 +11,7 @@ const { ContextCollector } = require('../spec/bootstrap/context-collector');
|
|
|
11
11
|
const { QuestionnaireEngine } = require('../spec/bootstrap/questionnaire-engine');
|
|
12
12
|
const { DraftGenerator } = require('../spec/bootstrap/draft-generator');
|
|
13
13
|
const { TraceEmitter } = require('../spec/bootstrap/trace-emitter');
|
|
14
|
+
const { ensureSpecDomainArtifacts } = require('../spec/domain-modeling');
|
|
14
15
|
const { SessionStore } = require('../runtime/session-store');
|
|
15
16
|
const { resolveSpecSceneBinding } = require('../runtime/scene-session-binding');
|
|
16
17
|
const { bindMultiSpecSceneSession } = require('../runtime/multi-spec-scene-session');
|
|
@@ -114,6 +115,14 @@ async function runSpecBootstrap(options = {}, dependencies = {}) {
|
|
|
114
115
|
await fs.writeFile(files.tasks, draft.tasks, 'utf8');
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
const domainArtifacts = await ensureSpecDomainArtifacts(projectPath, specName, {
|
|
119
|
+
dryRun: !!options.dryRun,
|
|
120
|
+
sceneId: sceneBinding.scene_id,
|
|
121
|
+
problemStatement: answers.problemStatement,
|
|
122
|
+
primaryFlow: answers.primaryFlow,
|
|
123
|
+
verificationPlan: answers.verificationPlan
|
|
124
|
+
});
|
|
125
|
+
|
|
117
126
|
const result = {
|
|
118
127
|
success: true,
|
|
119
128
|
specName,
|
|
@@ -122,7 +131,10 @@ async function runSpecBootstrap(options = {}, dependencies = {}) {
|
|
|
122
131
|
files: {
|
|
123
132
|
requirements: path.relative(projectPath, files.requirements),
|
|
124
133
|
design: path.relative(projectPath, files.design),
|
|
125
|
-
tasks: path.relative(projectPath, files.tasks)
|
|
134
|
+
tasks: path.relative(projectPath, files.tasks),
|
|
135
|
+
domain_map: path.relative(projectPath, domainArtifacts.paths.domain_map),
|
|
136
|
+
scene_spec: path.relative(projectPath, domainArtifacts.paths.scene_spec),
|
|
137
|
+
domain_chain: path.relative(projectPath, domainArtifacts.paths.domain_chain)
|
|
126
138
|
},
|
|
127
139
|
trace: {
|
|
128
140
|
template: options.template || 'default',
|
|
@@ -141,7 +153,10 @@ async function runSpecBootstrap(options = {}, dependencies = {}) {
|
|
|
141
153
|
preview: {
|
|
142
154
|
requirements: draft.requirements,
|
|
143
155
|
design: draft.design,
|
|
144
|
-
tasks: draft.tasks
|
|
156
|
+
tasks: draft.tasks,
|
|
157
|
+
domain_map: domainArtifacts.preview.domain_map,
|
|
158
|
+
scene_spec: domainArtifacts.preview.scene_spec,
|
|
159
|
+
domain_chain: domainArtifacts.preview.domain_chain
|
|
145
160
|
},
|
|
146
161
|
scene_session: sceneBinding
|
|
147
162
|
? {
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const {
|
|
5
|
+
ensureSpecDomainArtifacts,
|
|
6
|
+
validateSpecDomainArtifacts
|
|
7
|
+
} = require('../spec/domain-modeling');
|
|
8
|
+
|
|
9
|
+
function normalizeText(value) {
|
|
10
|
+
if (typeof value !== 'string') {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
return value.trim();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function resolveSpecId(options = {}) {
|
|
17
|
+
return normalizeText(options.spec || options.name);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function assertSpecExists(projectPath, specId, fileSystem = fs) {
|
|
21
|
+
const specPath = path.join(projectPath, '.sce', 'specs', specId);
|
|
22
|
+
if (!await fileSystem.pathExists(specPath)) {
|
|
23
|
+
throw new Error(`Spec not found: ${specId}`);
|
|
24
|
+
}
|
|
25
|
+
return specPath;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function runSpecDomainInitCommand(options = {}, dependencies = {}) {
|
|
29
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
30
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
31
|
+
const specId = resolveSpecId(options);
|
|
32
|
+
if (!specId) {
|
|
33
|
+
throw new Error('--spec is required');
|
|
34
|
+
}
|
|
35
|
+
await assertSpecExists(projectPath, specId, fileSystem);
|
|
36
|
+
|
|
37
|
+
const result = await ensureSpecDomainArtifacts(projectPath, specId, {
|
|
38
|
+
fileSystem,
|
|
39
|
+
dryRun: options.dryRun === true,
|
|
40
|
+
force: false,
|
|
41
|
+
sceneId: options.scene,
|
|
42
|
+
problemStatement: options.problem,
|
|
43
|
+
primaryFlow: options.primaryFlow,
|
|
44
|
+
verificationPlan: options.verificationPlan
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const payload = {
|
|
48
|
+
mode: 'spec-domain-init',
|
|
49
|
+
spec_id: specId,
|
|
50
|
+
dry_run: options.dryRun === true,
|
|
51
|
+
created: result.created,
|
|
52
|
+
files: result.paths
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
if (options.json) {
|
|
56
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
57
|
+
} else if (!options.silent) {
|
|
58
|
+
console.log(chalk.green('✓ Spec domain artifacts initialized'));
|
|
59
|
+
console.log(chalk.gray(` spec: ${specId}`));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return payload;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function runSpecDomainRefreshCommand(options = {}, dependencies = {}) {
|
|
66
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
67
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
68
|
+
const specId = resolveSpecId(options);
|
|
69
|
+
if (!specId) {
|
|
70
|
+
throw new Error('--spec is required');
|
|
71
|
+
}
|
|
72
|
+
await assertSpecExists(projectPath, specId, fileSystem);
|
|
73
|
+
|
|
74
|
+
const result = await ensureSpecDomainArtifacts(projectPath, specId, {
|
|
75
|
+
fileSystem,
|
|
76
|
+
dryRun: options.dryRun === true,
|
|
77
|
+
force: true,
|
|
78
|
+
sceneId: options.scene,
|
|
79
|
+
problemStatement: options.problem,
|
|
80
|
+
primaryFlow: options.primaryFlow,
|
|
81
|
+
verificationPlan: options.verificationPlan
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const payload = {
|
|
85
|
+
mode: 'spec-domain-refresh',
|
|
86
|
+
spec_id: specId,
|
|
87
|
+
dry_run: options.dryRun === true,
|
|
88
|
+
refreshed: result.created,
|
|
89
|
+
files: result.paths
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (options.json) {
|
|
93
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
94
|
+
} else if (!options.silent) {
|
|
95
|
+
console.log(chalk.green('✓ Spec domain artifacts refreshed'));
|
|
96
|
+
console.log(chalk.gray(` spec: ${specId}`));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return payload;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function runSpecDomainValidateCommand(options = {}, dependencies = {}) {
|
|
103
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
104
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
105
|
+
const specId = resolveSpecId(options);
|
|
106
|
+
if (!specId) {
|
|
107
|
+
throw new Error('--spec is required');
|
|
108
|
+
}
|
|
109
|
+
await assertSpecExists(projectPath, specId, fileSystem);
|
|
110
|
+
|
|
111
|
+
const validation = await validateSpecDomainArtifacts(projectPath, specId, fileSystem);
|
|
112
|
+
const payload = {
|
|
113
|
+
mode: 'spec-domain-validate',
|
|
114
|
+
spec_id: specId,
|
|
115
|
+
passed: validation.passed,
|
|
116
|
+
ratio: validation.ratio,
|
|
117
|
+
details: validation.details,
|
|
118
|
+
warnings: validation.warnings
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
if (options.failOnError && !validation.passed) {
|
|
122
|
+
throw new Error(`spec domain validation failed: ${validation.warnings.join('; ')}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (options.json) {
|
|
126
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
127
|
+
} else if (!options.silent) {
|
|
128
|
+
if (validation.passed) {
|
|
129
|
+
console.log(chalk.green('✓ Spec domain validation passed'));
|
|
130
|
+
} else {
|
|
131
|
+
console.log(chalk.red('✗ Spec domain validation failed'));
|
|
132
|
+
validation.warnings.forEach((message) => {
|
|
133
|
+
console.log(chalk.gray(` - ${message}`));
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return payload;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function registerSpecDomainCommand(program) {
|
|
142
|
+
const specDomain = program
|
|
143
|
+
.command('spec-domain')
|
|
144
|
+
.description('Manage problem-domain modeling artifacts (use: sce spec domain)');
|
|
145
|
+
|
|
146
|
+
specDomain
|
|
147
|
+
.command('init')
|
|
148
|
+
.description('Create missing problem-domain artifacts for a Spec')
|
|
149
|
+
.requiredOption('--spec <name>', 'Spec identifier')
|
|
150
|
+
.option('--scene <scene-id>', 'Scene id used in generated chain/model')
|
|
151
|
+
.option('--problem <text>', 'Problem statement seed')
|
|
152
|
+
.option('--primary-flow <text>', 'Primary flow seed')
|
|
153
|
+
.option('--verification-plan <text>', 'Verification plan seed')
|
|
154
|
+
.option('--dry-run', 'Preview output without writing files')
|
|
155
|
+
.option('--json', 'Output machine-readable JSON')
|
|
156
|
+
.action(async (options) => {
|
|
157
|
+
try {
|
|
158
|
+
await runSpecDomainInitCommand(options);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (options.json) {
|
|
161
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
162
|
+
} else {
|
|
163
|
+
console.error(chalk.red('❌ spec-domain init failed:'), error.message);
|
|
164
|
+
}
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
specDomain
|
|
170
|
+
.command('refresh')
|
|
171
|
+
.description('Force-refresh problem-domain artifacts for a Spec')
|
|
172
|
+
.requiredOption('--spec <name>', 'Spec identifier')
|
|
173
|
+
.option('--scene <scene-id>', 'Scene id used in generated chain/model')
|
|
174
|
+
.option('--problem <text>', 'Problem statement seed')
|
|
175
|
+
.option('--primary-flow <text>', 'Primary flow seed')
|
|
176
|
+
.option('--verification-plan <text>', 'Verification plan seed')
|
|
177
|
+
.option('--dry-run', 'Preview output without writing files')
|
|
178
|
+
.option('--json', 'Output machine-readable JSON')
|
|
179
|
+
.action(async (options) => {
|
|
180
|
+
try {
|
|
181
|
+
await runSpecDomainRefreshCommand(options);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
if (options.json) {
|
|
184
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
185
|
+
} else {
|
|
186
|
+
console.error(chalk.red('❌ spec-domain refresh failed:'), error.message);
|
|
187
|
+
}
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
specDomain
|
|
193
|
+
.command('validate')
|
|
194
|
+
.description('Validate problem-domain artifacts for a Spec')
|
|
195
|
+
.requiredOption('--spec <name>', 'Spec identifier')
|
|
196
|
+
.option('--fail-on-error', 'Exit non-zero when validation fails')
|
|
197
|
+
.option('--json', 'Output machine-readable JSON')
|
|
198
|
+
.action(async (options) => {
|
|
199
|
+
try {
|
|
200
|
+
await runSpecDomainValidateCommand(options);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
if (options.json) {
|
|
203
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
204
|
+
} else {
|
|
205
|
+
console.error(chalk.red('❌ spec-domain validate failed:'), error.message);
|
|
206
|
+
}
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
module.exports = {
|
|
213
|
+
runSpecDomainInitCommand,
|
|
214
|
+
runSpecDomainRefreshCommand,
|
|
215
|
+
runSpecDomainValidateCommand,
|
|
216
|
+
registerSpecDomainCommand
|
|
217
|
+
};
|