scene-capability-engine 3.3.12 → 3.3.14
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 +10 -0
- package/README.md +9 -3
- package/README.zh.md +9 -3
- package/bin/scene-capability-engine.js +8 -2
- package/docs/command-reference.md +10 -0
- package/lib/commands/scene.js +30 -3
- package/lib/commands/templates.js +93 -17
- package/lib/scene-runtime/moqui-extractor.js +1 -1
- package/lib/templates/cache-manager.js +3 -3
- package/lib/templates/frontmatter-generator.js +11 -1
- package/lib/templates/metadata-collector.js +48 -10
- package/lib/templates/path-utils.js +1 -1
- package/lib/templates/registry-parser.js +292 -13
- package/lib/templates/template-exporter.js +30 -10
- package/lib/templates/template-manager.js +62 -8
- package/lib/templates/template-validator.js +24 -1
- package/lib/workspace/multi/global-config.js +1 -1
- package/lib/workspace/multi/path-utils.js +3 -3
- package/lib/workspace/multi/workspace-registry.js +1 -1
- package/lib/workspace/multi/workspace-state-manager.js +64 -2
- package/package.json +1 -1
- package/template/.sce/steering/CORE_PRINCIPLES.md +3 -1
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const fs = require('fs-extra');
|
|
8
8
|
const path = require('path');
|
|
9
|
+
const semver = require('semver');
|
|
9
10
|
const { ValidationError } = require('./template-error');
|
|
10
11
|
|
|
11
12
|
class TemplateValidator {
|
|
@@ -14,7 +15,8 @@ class TemplateValidator {
|
|
|
14
15
|
this.requiredFrontmatterFields = [
|
|
15
16
|
'name', 'category', 'description', 'difficulty',
|
|
16
17
|
'tags', 'applicable_scenarios', 'author',
|
|
17
|
-
'created_at', 'updated_at', 'version'
|
|
18
|
+
'created_at', 'updated_at', 'version',
|
|
19
|
+
'template_type', 'min_sce_version'
|
|
18
20
|
];
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -251,6 +253,27 @@ class TemplateValidator {
|
|
|
251
253
|
result.errors.push(`${filename}: Invalid difficulty "${metadata.difficulty}"`);
|
|
252
254
|
}
|
|
253
255
|
|
|
256
|
+
// Validate template type
|
|
257
|
+
const validTemplateTypes = ['spec-scaffold', 'capability-template', 'runtime-playbook'];
|
|
258
|
+
if (metadata.template_type && !validTemplateTypes.includes(metadata.template_type)) {
|
|
259
|
+
result.errors.push(`${filename}: Invalid template_type "${metadata.template_type}"`);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Validate SCE compatibility semver
|
|
263
|
+
if (metadata.min_sce_version && !semver.valid(metadata.min_sce_version)) {
|
|
264
|
+
result.errors.push(`${filename}: Invalid min_sce_version "${metadata.min_sce_version}"`);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (metadata.max_sce_version && !semver.valid(metadata.max_sce_version)) {
|
|
268
|
+
result.errors.push(`${filename}: Invalid max_sce_version "${metadata.max_sce_version}"`);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (metadata.min_sce_version && metadata.max_sce_version &&
|
|
272
|
+
semver.valid(metadata.min_sce_version) && semver.valid(metadata.max_sce_version) &&
|
|
273
|
+
semver.gt(metadata.min_sce_version, metadata.max_sce_version)) {
|
|
274
|
+
result.errors.push(`${filename}: min_sce_version must be <= max_sce_version`);
|
|
275
|
+
}
|
|
276
|
+
|
|
254
277
|
return result;
|
|
255
278
|
}
|
|
256
279
|
|
|
@@ -26,7 +26,7 @@ class GlobalConfig {
|
|
|
26
26
|
/**
|
|
27
27
|
* Get the default configuration file path
|
|
28
28
|
*
|
|
29
|
-
* @returns {string} Path to ~/.
|
|
29
|
+
* @returns {string} Path to ~/.sce/workspace-state.json
|
|
30
30
|
* @deprecated Use WorkspaceStateManager.getDefaultStatePath() instead
|
|
31
31
|
*/
|
|
32
32
|
getDefaultConfigPath() {
|
|
@@ -84,16 +84,16 @@ class PathUtils {
|
|
|
84
84
|
/**
|
|
85
85
|
* Get the default sce configuration directory
|
|
86
86
|
*
|
|
87
|
-
* @returns {string} Path to ~/.
|
|
87
|
+
* @returns {string} Path to ~/.sce directory
|
|
88
88
|
*/
|
|
89
89
|
static getConfigDir() {
|
|
90
|
-
return path.join(os.homedir(), '.
|
|
90
|
+
return path.join(os.homedir(), '.sce');
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* Get the default workspace state file path
|
|
95
95
|
*
|
|
96
|
-
* @returns {string} Path to ~/.
|
|
96
|
+
* @returns {string} Path to ~/.sce/workspace-state.json
|
|
97
97
|
*/
|
|
98
98
|
static getWorkspaceStatePath() {
|
|
99
99
|
return path.join(this.getConfigDir(), 'workspace-state.json');
|
|
@@ -26,7 +26,7 @@ class WorkspaceRegistry {
|
|
|
26
26
|
/**
|
|
27
27
|
* Get the default configuration file path
|
|
28
28
|
*
|
|
29
|
-
* @returns {string} Path to ~/.
|
|
29
|
+
* @returns {string} Path to ~/.sce/workspace-state.json
|
|
30
30
|
* @deprecated Use WorkspaceStateManager.getDefaultStatePath() instead
|
|
31
31
|
*/
|
|
32
32
|
getDefaultConfigPath() {
|
|
@@ -10,7 +10,7 @@ const Workspace = require('./workspace');
|
|
|
10
10
|
* data in a single configuration file. This ensures atomic updates and
|
|
11
11
|
* eliminates data inconsistency risks.
|
|
12
12
|
*
|
|
13
|
-
* Architecture: Single file (~/.
|
|
13
|
+
* Architecture: Single file (~/.sce/workspace-state.json) contains:
|
|
14
14
|
* - All workspace entries
|
|
15
15
|
* - Active workspace selection
|
|
16
16
|
* - User preferences
|
|
@@ -41,13 +41,34 @@ class WorkspaceStateManager {
|
|
|
41
41
|
/**
|
|
42
42
|
* Get the default state file path
|
|
43
43
|
*
|
|
44
|
-
* @returns {string} Path to ~/.
|
|
44
|
+
* @returns {string} Path to ~/.sce/workspace-state.json
|
|
45
45
|
*/
|
|
46
46
|
getDefaultStatePath() {
|
|
47
|
+
const homeDir = os.homedir();
|
|
48
|
+
return path.join(homeDir, '.sce', 'workspace-state.json');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get the legacy state file path used by prior versions
|
|
53
|
+
*
|
|
54
|
+
* @returns {string} Path to ~/.kse/workspace-state.json
|
|
55
|
+
*/
|
|
56
|
+
getLegacyStatePath() {
|
|
47
57
|
const homeDir = os.homedir();
|
|
48
58
|
return path.join(homeDir, '.kse', 'workspace-state.json');
|
|
49
59
|
}
|
|
50
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Whether state manager is operating on the default state path.
|
|
63
|
+
*
|
|
64
|
+
* Automatic legacy migration should only run in this mode.
|
|
65
|
+
*
|
|
66
|
+
* @returns {boolean}
|
|
67
|
+
*/
|
|
68
|
+
isDefaultStatePath() {
|
|
69
|
+
return path.resolve(this.statePath) === path.resolve(this.getDefaultStatePath());
|
|
70
|
+
}
|
|
71
|
+
|
|
51
72
|
/**
|
|
52
73
|
* Load workspace state from disk
|
|
53
74
|
*
|
|
@@ -66,6 +87,15 @@ class WorkspaceStateManager {
|
|
|
66
87
|
return true;
|
|
67
88
|
}
|
|
68
89
|
|
|
90
|
+
// Migrate legacy single-file state from ~/.kse/workspace-state.json
|
|
91
|
+
if (await this.hasLegacyStateFile()) {
|
|
92
|
+
console.log('Migrating workspace state to new .sce directory...');
|
|
93
|
+
await this.migrateFromLegacyStateFile();
|
|
94
|
+
await this.loadNewFormat();
|
|
95
|
+
this.loaded = true;
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
|
|
69
99
|
// Check for legacy format and migrate
|
|
70
100
|
if (await this.hasLegacyFiles()) {
|
|
71
101
|
console.log('Migrating workspace configuration to new format...');
|
|
@@ -137,6 +167,10 @@ class WorkspaceStateManager {
|
|
|
137
167
|
* @returns {Promise<boolean>}
|
|
138
168
|
*/
|
|
139
169
|
async hasLegacyFiles() {
|
|
170
|
+
if (!this.isDefaultStatePath()) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
|
|
140
174
|
const homeDir = os.homedir();
|
|
141
175
|
const legacyWorkspacesPath = path.join(homeDir, '.kse', 'workspaces.json');
|
|
142
176
|
const legacyConfigPath = path.join(homeDir, '.kse', 'config.json');
|
|
@@ -147,6 +181,34 @@ class WorkspaceStateManager {
|
|
|
147
181
|
return workspacesExists || configExists;
|
|
148
182
|
}
|
|
149
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Check whether legacy single-file state exists
|
|
186
|
+
*
|
|
187
|
+
* @private
|
|
188
|
+
* @returns {Promise<boolean>}
|
|
189
|
+
*/
|
|
190
|
+
async hasLegacyStateFile() {
|
|
191
|
+
if (!this.isDefaultStatePath()) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const legacyStatePath = this.getLegacyStatePath();
|
|
196
|
+
return fs.pathExists(legacyStatePath);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Copy legacy single-file state into the new default location.
|
|
201
|
+
*
|
|
202
|
+
* @private
|
|
203
|
+
* @returns {Promise<void>}
|
|
204
|
+
*/
|
|
205
|
+
async migrateFromLegacyStateFile() {
|
|
206
|
+
const legacyStatePath = this.getLegacyStatePath();
|
|
207
|
+
const stateDir = path.dirname(this.statePath);
|
|
208
|
+
await fs.ensureDir(stateDir);
|
|
209
|
+
await fs.copy(legacyStatePath, this.statePath);
|
|
210
|
+
}
|
|
211
|
+
|
|
150
212
|
/**
|
|
151
213
|
* Migrate from legacy format (workspaces.json + config.json)
|
|
152
214
|
*
|
package/package.json
CHANGED
|
@@ -136,6 +136,8 @@
|
|
|
136
136
|
|
|
137
137
|
**复杂问题定位方法**: 优先使用 debug 日志与可观测信号定位(输入、输出、关键分支、异常栈、上下文参数),先还原执行路径再下结论
|
|
138
138
|
|
|
139
|
+
**修复后清理要求**: 问题修复并验证通过后,必须清理临时 debug 日志、临时埋点、一次性脚本和调试开关;需要长期保留的日志必须转为可配置观测项且默认关闭
|
|
140
|
+
|
|
139
141
|
**允许的临时措施**: 仅在生产止血场景可临时绕行,但必须同时给出根因修复任务、回滚条件和截止时间
|
|
140
142
|
|
|
141
143
|
**验收标准**: 必须有可复现用例、修复后回归通过、明确根因记录(不是仅现象描述)
|
|
@@ -155,4 +157,4 @@
|
|
|
155
157
|
|
|
156
158
|
---
|
|
157
159
|
|
|
158
|
-
|
|
160
|
+
v16.0 | 2026-02-25 | 新增调试日志清理硬规则
|