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
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.3.13] - 2026-02-25
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Strengthened steering defect-repair governance with post-fix cleanup hard rule:
|
|
14
|
+
- After bug fixes are validated, temporary debug logs, ad-hoc probes, one-off scripts, and temporary debug switches must be removed.
|
|
15
|
+
- Any retained diagnostic logging must be converted to configurable observability controls and default to disabled.
|
|
16
|
+
- Synced the same steering hard rule to both runtime and template steering baselines:
|
|
17
|
+
- `.sce/steering/CORE_PRINCIPLES.md`
|
|
18
|
+
- `template/.sce/steering/CORE_PRINCIPLES.md`
|
|
19
|
+
|
|
10
20
|
## [3.3.12] - 2026-02-25
|
|
11
21
|
|
|
12
22
|
### Changed
|
package/README.md
CHANGED
|
@@ -341,7 +341,7 @@ Structure your work with Requirements → Design → Tasks workflow
|
|
|
341
341
|
### Multi-Workspace Management 🚀
|
|
342
342
|
- **Workspace Registry**: Manage multiple sce projects from a single location
|
|
343
343
|
- **Quick Switching**: Switch between projects without directory navigation
|
|
344
|
-
- **Data Atomicity**: Single source of truth (`~/.
|
|
344
|
+
- **Data Atomicity**: Single source of truth (`~/.sce/workspace-state.json`)
|
|
345
345
|
- **Cross-Platform**: Consistent path handling across Windows/Linux/macOS
|
|
346
346
|
- **Auto Migration**: Seamless upgrade from legacy workspace format
|
|
347
347
|
|
|
@@ -570,6 +570,12 @@ sce spec gate run --specs "<spec-a,spec-b>" --max-parallel <N> # Multi-Spec
|
|
|
570
570
|
sce context export <spec-name> # Export context for AI tools
|
|
571
571
|
sce prompt generate <spec> <task> # Generate task-specific prompt
|
|
572
572
|
|
|
573
|
+
# Template registry
|
|
574
|
+
sce templates list --type <spec-scaffold|capability-template|runtime-playbook> --compatible-with <semver> --risk <low|medium|high|critical>
|
|
575
|
+
sce templates search <keyword> --type <spec-scaffold|capability-template|runtime-playbook> --compatible-with <semver>
|
|
576
|
+
sce templates show <template-path> # Show template metadata and compatibility contract
|
|
577
|
+
sce templates update [--source <name>]
|
|
578
|
+
|
|
573
579
|
# KPI automation and observability
|
|
574
580
|
sce value metrics sample --out <path> --json # Generate sample KPI input JSON
|
|
575
581
|
sce value metrics snapshot --input <path> --json # Generate weekly KPI snapshot + gate summary
|
|
@@ -769,6 +775,6 @@ A deep conversation about AI development trends, Neo-Confucian philosophy, and s
|
|
|
769
775
|
|
|
770
776
|
---
|
|
771
777
|
|
|
772
|
-
**Version**: 3.3.
|
|
773
|
-
**Last Updated**: 2026-02-
|
|
778
|
+
**Version**: 3.3.14
|
|
779
|
+
**Last Updated**: 2026-02-26
|
|
774
780
|
|
package/README.zh.md
CHANGED
|
@@ -307,7 +307,7 @@ sequenceDiagram
|
|
|
307
307
|
### 多工作区管理 🚀
|
|
308
308
|
- **工作区注册表**:从单一位置管理多个 sce 项目
|
|
309
309
|
- **快速切换**:无需目录导航即可在项目间切换
|
|
310
|
-
- **数据原子性**:单一数据源(`~/.
|
|
310
|
+
- **数据原子性**:单一数据源(`~/.sce/workspace-state.json`)
|
|
311
311
|
- **跨平台**:Windows/Linux/macOS 一致的路径处理
|
|
312
312
|
- **自动迁移**:从旧版工作区格式无缝升级
|
|
313
313
|
|
|
@@ -484,6 +484,12 @@ sce spec gate run --specs "<spec-a,spec-b>" --max-parallel <N> # 多 Spec
|
|
|
484
484
|
sce context export <spec-name> # 为 AI 工具导出上下文
|
|
485
485
|
sce prompt generate <spec> <task> # 生成任务特定提示
|
|
486
486
|
|
|
487
|
+
# 模板注册表
|
|
488
|
+
sce templates list --type <spec-scaffold|capability-template|runtime-playbook> --compatible-with <semver> --risk <low|medium|high|critical>
|
|
489
|
+
sce templates search <keyword> --type <spec-scaffold|capability-template|runtime-playbook> --compatible-with <semver>
|
|
490
|
+
sce templates show <template-path> # 查看模板元数据与兼容契约
|
|
491
|
+
sce templates update [--source <name>]
|
|
492
|
+
|
|
487
493
|
# KPI 自动化与可观测
|
|
488
494
|
sce value metrics sample --out <path> --json # 生成 KPI 输入样例 JSON
|
|
489
495
|
sce value metrics snapshot --input <path> --json # 生成周度 KPI 快照 + gate 摘要
|
|
@@ -630,7 +636,7 @@ sce spec bootstrap --name 01-00-my-first-feature --non-interactive
|
|
|
630
636
|
|
|
631
637
|
---
|
|
632
638
|
|
|
633
|
-
**版本**:3.3.
|
|
634
|
-
**最后更新**:2026-02-
|
|
639
|
+
**版本**:3.3.14
|
|
640
|
+
**最后更新**:2026-02-26
|
|
635
641
|
|
|
636
642
|
|
|
@@ -311,7 +311,6 @@ program
|
|
|
311
311
|
console.log(chalk.yellow('💡 Tip:'));
|
|
312
312
|
console.log(' Use a template: ' + chalk.cyan(`sce spec create ${specName} --template <template-id>`));
|
|
313
313
|
console.log(' Browse templates: ' + chalk.cyan('sce templates list'));
|
|
314
|
-
console.log(' Legacy alias (still works): ' + chalk.cyan('kse templates list'));
|
|
315
314
|
}
|
|
316
315
|
} catch (error) {
|
|
317
316
|
console.error(chalk.red('❌ Error creating spec:'), error.message);
|
|
@@ -830,13 +829,16 @@ const templatesCommand = require('../lib/commands/templates');
|
|
|
830
829
|
|
|
831
830
|
const templatesCmd = program
|
|
832
831
|
.command('templates')
|
|
833
|
-
.description('Manage
|
|
832
|
+
.description('Manage SCE templates from official and custom sources');
|
|
834
833
|
|
|
835
834
|
templatesCmd
|
|
836
835
|
.command('list')
|
|
837
836
|
.description('List all available templates')
|
|
838
837
|
.option('--category <category>', 'Filter by category')
|
|
839
838
|
.option('--source <source>', 'Filter by source')
|
|
839
|
+
.option('--type <template-type>', 'Filter by template type (spec-scaffold|capability-template|runtime-playbook)')
|
|
840
|
+
.option('--compatible-with <version>', 'Filter templates compatible with target SCE version (semver)')
|
|
841
|
+
.option('--risk <risk-level>', 'Filter by risk level (low|medium|high|critical)')
|
|
840
842
|
.action(async (options) => {
|
|
841
843
|
await templatesCommand.listTemplates(options);
|
|
842
844
|
});
|
|
@@ -845,6 +847,10 @@ templatesCmd
|
|
|
845
847
|
.command('search <keyword>')
|
|
846
848
|
.description('Search templates by keyword')
|
|
847
849
|
.option('--category <category>', 'Filter by category')
|
|
850
|
+
.option('--source <source>', 'Filter by source')
|
|
851
|
+
.option('--type <template-type>', 'Filter by template type (spec-scaffold|capability-template|runtime-playbook)')
|
|
852
|
+
.option('--compatible-with <version>', 'Filter templates compatible with target SCE version (semver)')
|
|
853
|
+
.option('--risk <risk-level>', 'Filter by risk level (low|medium|high|critical)')
|
|
848
854
|
.action(async (keyword, options) => {
|
|
849
855
|
await templatesCommand.searchTemplates(keyword, options);
|
|
850
856
|
});
|
|
@@ -1291,6 +1291,12 @@ Codex sub-agent permission defaults:
|
|
|
1291
1291
|
### Scene Template Engine
|
|
1292
1292
|
|
|
1293
1293
|
```bash
|
|
1294
|
+
# Template registry (typed templates + compatibility filters)
|
|
1295
|
+
sce templates list --type <spec-scaffold|capability-template|runtime-playbook> --compatible-with <semver> --risk <low|medium|high|critical>
|
|
1296
|
+
sce templates search <keyword> --type <spec-scaffold|capability-template|runtime-playbook> --compatible-with <semver>
|
|
1297
|
+
sce templates show <template-path>
|
|
1298
|
+
sce templates update [--source <name>]
|
|
1299
|
+
|
|
1294
1300
|
# Validate template variable schema in a scene package
|
|
1295
1301
|
sce scene template-validate --package <path>
|
|
1296
1302
|
sce scene template-validate --package ./my-package --json
|
|
@@ -1345,6 +1351,10 @@ sce scene package-publish-batch --manifest docs/handoffs/handoff-manifest.json -
|
|
|
1345
1351
|
sce scene package-publish-batch --manifest docs/handoffs/handoff-manifest.json --dry-run --ontology-task-queue-out .sce/auto/ontology-remediation.lines --json
|
|
1346
1352
|
```
|
|
1347
1353
|
|
|
1354
|
+
Compatibility contract note:
|
|
1355
|
+
- Scene package compatibility uses `compatibility.min_sce_version` as canonical field.
|
|
1356
|
+
- Legacy `compatibility.kse_version` remains readable but is deprecated.
|
|
1357
|
+
|
|
1348
1358
|
### Scene Package Ontology Backfill Batch
|
|
1349
1359
|
|
|
1350
1360
|
```bash
|
package/lib/commands/scene.js
CHANGED
|
@@ -3631,9 +3631,23 @@ function buildScenePackageCoordinate(contract = {}) {
|
|
|
3631
3631
|
return `${group}/${name}@${version}`;
|
|
3632
3632
|
}
|
|
3633
3633
|
|
|
3634
|
+
function resolveSceneCompatibilityMinSceVersion(compatibility = {}) {
|
|
3635
|
+
if (!isPlainObject(compatibility)) {
|
|
3636
|
+
return '';
|
|
3637
|
+
}
|
|
3638
|
+
|
|
3639
|
+
const minSceVersion = String(compatibility.min_sce_version || '').trim();
|
|
3640
|
+
if (minSceVersion.length > 0) {
|
|
3641
|
+
return minSceVersion;
|
|
3642
|
+
}
|
|
3643
|
+
|
|
3644
|
+
return String(compatibility.kse_version || '').trim();
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3634
3647
|
function buildScenePackagePublishTemplateManifest(packageContract = {}, context = {}) {
|
|
3635
3648
|
const artifacts = isPlainObject(packageContract.artifacts) ? packageContract.artifacts : {};
|
|
3636
3649
|
const compatibility = isPlainObject(packageContract.compatibility) ? packageContract.compatibility : {};
|
|
3650
|
+
const minSceVersion = resolveSceneCompatibilityMinSceVersion(compatibility);
|
|
3637
3651
|
|
|
3638
3652
|
return {
|
|
3639
3653
|
apiVersion: SCENE_PACKAGE_TEMPLATE_API_VERSION,
|
|
@@ -3646,6 +3660,7 @@ function buildScenePackagePublishTemplateManifest(packageContract = {}, context
|
|
|
3646
3660
|
published_at: context.publishedAt || new Date().toISOString()
|
|
3647
3661
|
},
|
|
3648
3662
|
compatibility: {
|
|
3663
|
+
min_sce_version: minSceVersion || '>=1.24.0',
|
|
3649
3664
|
scene_api_version: String(compatibility.scene_api_version || '').trim() || 'sce.scene/v0.2'
|
|
3650
3665
|
},
|
|
3651
3666
|
parameters: Array.isArray(packageContract.parameters)
|
|
@@ -3680,7 +3695,7 @@ function createScenePackageTemplate(options = {}) {
|
|
|
3680
3695
|
summary: `Template contract for ${packageName || 'scene-template'}`
|
|
3681
3696
|
},
|
|
3682
3697
|
compatibility: {
|
|
3683
|
-
|
|
3698
|
+
min_sce_version: '>=1.24.0',
|
|
3684
3699
|
scene_api_version: 'sce.scene/v0.2',
|
|
3685
3700
|
moqui_model_version: '3.x',
|
|
3686
3701
|
adapter_api_version: 'v1'
|
|
@@ -4215,9 +4230,21 @@ function validateScenePackageContract(contract = {}) {
|
|
|
4215
4230
|
if (!compatibility) {
|
|
4216
4231
|
errors.push('compatibility object is required');
|
|
4217
4232
|
} else {
|
|
4218
|
-
|
|
4219
|
-
|
|
4233
|
+
const minSceVersion = String(compatibility.min_sce_version || '').trim();
|
|
4234
|
+
const legacyKseVersion = String(compatibility.kse_version || '').trim();
|
|
4235
|
+
|
|
4236
|
+
if (!minSceVersion && !legacyKseVersion) {
|
|
4237
|
+
errors.push('compatibility.min_sce_version is required');
|
|
4238
|
+
}
|
|
4239
|
+
|
|
4240
|
+
if (!minSceVersion && legacyKseVersion) {
|
|
4241
|
+
warnings.push('compatibility.kse_version is deprecated; use compatibility.min_sce_version');
|
|
4220
4242
|
}
|
|
4243
|
+
|
|
4244
|
+
if (minSceVersion && legacyKseVersion && minSceVersion !== legacyKseVersion) {
|
|
4245
|
+
warnings.push('compatibility.min_sce_version takes precedence over compatibility.kse_version when both are defined');
|
|
4246
|
+
}
|
|
4247
|
+
|
|
4221
4248
|
if (!String(compatibility.scene_api_version || '').trim()) {
|
|
4222
4249
|
errors.push('compatibility.scene_api_version is required');
|
|
4223
4250
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Templates Command
|
|
3
3
|
*
|
|
4
|
-
* Manages
|
|
4
|
+
* Manages SCE templates from official and custom sources
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const chalk = require('chalk');
|
|
@@ -18,12 +18,12 @@ const { TemplateError } = require('../templates/template-error');
|
|
|
18
18
|
* @returns {void}
|
|
19
19
|
*/
|
|
20
20
|
function displayTemplateList(templates, options = {}) {
|
|
21
|
-
const { source = null, category = null } = options;
|
|
21
|
+
const { source = null, category = null, type = null, compatibleWith = null } = options;
|
|
22
22
|
|
|
23
23
|
if (templates.length === 0) {
|
|
24
24
|
console.log(chalk.yellow('No templates found'));
|
|
25
25
|
|
|
26
|
-
if (source || category) {
|
|
26
|
+
if (source || category || type || compatibleWith) {
|
|
27
27
|
console.log(chalk.gray('Try removing filters or updating templates'));
|
|
28
28
|
} else {
|
|
29
29
|
console.log(chalk.gray('Run'), chalk.cyan('sce templates update'), chalk.gray('to download templates'));
|
|
@@ -62,7 +62,10 @@ function displayTemplateList(templates, options = {}) {
|
|
|
62
62
|
console.log(` ${sourcePrefix}${chalk.cyan(template.id)}`);
|
|
63
63
|
console.log(` ${template.name}`);
|
|
64
64
|
console.log(` ${chalk.gray(template.description)}`);
|
|
65
|
+
const templateType = template.template_type || 'spec-scaffold';
|
|
66
|
+
const compatibility = formatCompatibilityRange(template);
|
|
65
67
|
console.log(` ${difficultyColor(template.difficulty)} • ${chalk.gray(template.tags.join(', '))}`);
|
|
68
|
+
console.log(` ${chalk.gray(`type=${templateType} compatibility=${compatibility}`)}`);
|
|
66
69
|
console.log();
|
|
67
70
|
});
|
|
68
71
|
});
|
|
@@ -91,6 +94,12 @@ function displayTemplateDetails(template) {
|
|
|
91
94
|
}[template.difficulty] || chalk.gray;
|
|
92
95
|
|
|
93
96
|
console.log(chalk.gray('Difficulty:'), difficultyColor(template.difficulty));
|
|
97
|
+
console.log(chalk.gray('Type:'), template.template_type || 'spec-scaffold');
|
|
98
|
+
console.log(chalk.gray('Compatibility:'), formatCompatibilityRange(template));
|
|
99
|
+
|
|
100
|
+
if (template.risk_level) {
|
|
101
|
+
console.log(chalk.gray('Risk Level:'), template.risk_level);
|
|
102
|
+
}
|
|
94
103
|
|
|
95
104
|
if (template.source) {
|
|
96
105
|
console.log(chalk.gray('Source:'), template.source);
|
|
@@ -121,6 +130,24 @@ function displayTemplateDetails(template) {
|
|
|
121
130
|
});
|
|
122
131
|
console.log();
|
|
123
132
|
}
|
|
133
|
+
|
|
134
|
+
if (template.ontology_scope) {
|
|
135
|
+
console.log(chalk.gray('Ontology Scope:'));
|
|
136
|
+
const scopeKeys = ['domains', 'entities', 'relations', 'business_rules', 'decisions'];
|
|
137
|
+
scopeKeys.forEach((key) => {
|
|
138
|
+
const values = template.ontology_scope[key];
|
|
139
|
+
if (Array.isArray(values) && values.length > 0) {
|
|
140
|
+
console.log(` • ${key}: ${values.join(', ')}`);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
console.log();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (template.rollback_contract) {
|
|
147
|
+
const strategy = template.rollback_contract.strategy || 'n/a';
|
|
148
|
+
console.log(chalk.gray('Rollback Contract:'), `${template.rollback_contract.supported ? 'supported' : 'not-supported'} (strategy=${strategy})`);
|
|
149
|
+
console.log();
|
|
150
|
+
}
|
|
124
151
|
|
|
125
152
|
if (template.author) {
|
|
126
153
|
console.log(chalk.gray('Author:'), template.author);
|
|
@@ -136,7 +163,11 @@ function displayTemplateDetails(template) {
|
|
|
136
163
|
|
|
137
164
|
console.log();
|
|
138
165
|
console.log(chalk.blue('Usage:'));
|
|
139
|
-
|
|
166
|
+
if ((template.template_type || 'spec-scaffold') === 'spec-scaffold') {
|
|
167
|
+
console.log(` ${chalk.cyan(`sce spec create my-feature --template ${template.id}`)}`);
|
|
168
|
+
} else {
|
|
169
|
+
console.log(` ${chalk.cyan(`sce templates show ${template.id}`)} ${chalk.gray('# inspect contract and owning workflow')}`);
|
|
170
|
+
}
|
|
140
171
|
console.log();
|
|
141
172
|
}
|
|
142
173
|
|
|
@@ -147,15 +178,32 @@ function displayTemplateDetails(template) {
|
|
|
147
178
|
* @returns {Promise<void>}
|
|
148
179
|
*/
|
|
149
180
|
async function listTemplates(options = {}) {
|
|
150
|
-
const {
|
|
181
|
+
const {
|
|
182
|
+
category = null,
|
|
183
|
+
source = null,
|
|
184
|
+
type = null,
|
|
185
|
+
compatibleWith = null,
|
|
186
|
+
risk = null
|
|
187
|
+
} = options;
|
|
151
188
|
|
|
152
|
-
console.log(chalk.red('🔥') + '
|
|
189
|
+
console.log(chalk.red('🔥') + ' SCE Templates');
|
|
153
190
|
|
|
154
191
|
try {
|
|
155
192
|
const manager = new TemplateManager();
|
|
156
|
-
const templates = await manager.listTemplates({
|
|
193
|
+
const templates = await manager.listTemplates({
|
|
194
|
+
category,
|
|
195
|
+
source,
|
|
196
|
+
templateType: type,
|
|
197
|
+
compatibleWith,
|
|
198
|
+
riskLevel: risk
|
|
199
|
+
});
|
|
157
200
|
|
|
158
|
-
displayTemplateList(templates, {
|
|
201
|
+
displayTemplateList(templates, {
|
|
202
|
+
category,
|
|
203
|
+
source,
|
|
204
|
+
type,
|
|
205
|
+
compatibleWith
|
|
206
|
+
});
|
|
159
207
|
|
|
160
208
|
} catch (error) {
|
|
161
209
|
console.log();
|
|
@@ -183,15 +231,32 @@ async function listTemplates(options = {}) {
|
|
|
183
231
|
* @returns {Promise<void>}
|
|
184
232
|
*/
|
|
185
233
|
async function searchTemplates(keyword, options = {}) {
|
|
186
|
-
const {
|
|
234
|
+
const {
|
|
235
|
+
category = null,
|
|
236
|
+
source = null,
|
|
237
|
+
type = null,
|
|
238
|
+
compatibleWith = null,
|
|
239
|
+
risk = null
|
|
240
|
+
} = options;
|
|
187
241
|
|
|
188
242
|
console.log(chalk.red('🔥') + ` Searching templates for: ${chalk.cyan(keyword)}`);
|
|
189
243
|
|
|
190
244
|
try {
|
|
191
245
|
const manager = new TemplateManager();
|
|
192
|
-
const templates = await manager.searchTemplates(keyword, {
|
|
246
|
+
const templates = await manager.searchTemplates(keyword, {
|
|
247
|
+
source,
|
|
248
|
+
category,
|
|
249
|
+
templateType: type,
|
|
250
|
+
compatibleWith,
|
|
251
|
+
riskLevel: risk
|
|
252
|
+
});
|
|
193
253
|
|
|
194
|
-
displayTemplateList(templates, {
|
|
254
|
+
displayTemplateList(templates, {
|
|
255
|
+
category,
|
|
256
|
+
source,
|
|
257
|
+
type,
|
|
258
|
+
compatibleWith
|
|
259
|
+
});
|
|
195
260
|
|
|
196
261
|
} catch (error) {
|
|
197
262
|
console.log();
|
|
@@ -525,6 +590,18 @@ async function cacheCommand(options = {}) {
|
|
|
525
590
|
}
|
|
526
591
|
}
|
|
527
592
|
|
|
593
|
+
/**
|
|
594
|
+
* Format compatibility range for display
|
|
595
|
+
*
|
|
596
|
+
* @param {Object} template - Template metadata
|
|
597
|
+
* @returns {string} Compatibility text
|
|
598
|
+
*/
|
|
599
|
+
function formatCompatibilityRange(template) {
|
|
600
|
+
const min = template.min_sce_version || '*';
|
|
601
|
+
const max = template.max_sce_version || '*';
|
|
602
|
+
return `${min}..${max}`;
|
|
603
|
+
}
|
|
604
|
+
|
|
528
605
|
/**
|
|
529
606
|
* Format bytes to human-readable string
|
|
530
607
|
*
|
|
@@ -547,21 +624,20 @@ function formatBytes(bytes) {
|
|
|
547
624
|
* @returns {Promise<void>}
|
|
548
625
|
*/
|
|
549
626
|
async function displayGuide() {
|
|
550
|
-
console.log(chalk.red('🔥') + '
|
|
627
|
+
console.log(chalk.red('🔥') + ' SCE Template Guide');
|
|
551
628
|
console.log();
|
|
552
629
|
|
|
553
|
-
console.log(chalk.blue.bold('What are
|
|
630
|
+
console.log(chalk.blue.bold('What are SCE Templates?'));
|
|
554
631
|
console.log();
|
|
555
|
-
console.log('
|
|
556
|
-
console.log('They provide
|
|
557
|
-
console.log('to help you get started quickly with best practices.');
|
|
632
|
+
console.log('SCE templates include spec scaffolds, capability templates, and runtime playbooks.');
|
|
633
|
+
console.log('They provide reusable contracts for generation, execution, and verification workflows.');
|
|
558
634
|
console.log();
|
|
559
635
|
|
|
560
636
|
console.log(chalk.blue.bold('Quick Start:'));
|
|
561
637
|
console.log();
|
|
562
638
|
console.log(`1. ${chalk.cyan('sce templates list')} - Browse available templates`);
|
|
563
639
|
console.log(`2. ${chalk.cyan('sce templates show <template-id>')} - View template details`);
|
|
564
|
-
console.log(`3. ${chalk.cyan('sce spec create my-feature --template <template-id>')} -
|
|
640
|
+
console.log(`3. ${chalk.cyan('sce spec create my-feature --template <template-id>')} - Apply scaffold template`);
|
|
565
641
|
console.log();
|
|
566
642
|
|
|
567
643
|
console.log(chalk.blue.bold('Common Commands:'));
|
|
@@ -1643,7 +1643,7 @@ function generatePackageContract(match) {
|
|
|
1643
1643
|
description: `${summary}. Includes ontology graph hints, lineage tracing, and AI execution metadata.`
|
|
1644
1644
|
},
|
|
1645
1645
|
compatibility: {
|
|
1646
|
-
|
|
1646
|
+
min_sce_version: '>=1.39.0',
|
|
1647
1647
|
scene_api_version: SCENE_API_VERSION
|
|
1648
1648
|
},
|
|
1649
1649
|
parameters: [
|
|
@@ -11,8 +11,8 @@ const { FileSystemError } = require('./template-error');
|
|
|
11
11
|
|
|
12
12
|
class CacheManager {
|
|
13
13
|
constructor(cacheDir = null) {
|
|
14
|
-
// Default cache directory: ~/.
|
|
15
|
-
this.cacheDir = cacheDir || path.join(os.homedir(), '.
|
|
14
|
+
// Default cache directory: ~/.sce/templates/
|
|
15
|
+
this.cacheDir = cacheDir || path.join(os.homedir(), '.sce', 'templates');
|
|
16
16
|
this.metadataFile = path.join(this.cacheDir, '.cache-metadata.json');
|
|
17
17
|
this.sourcesFile = path.join(this.cacheDir, '.sources.json');
|
|
18
18
|
}
|
|
@@ -215,7 +215,7 @@ class CacheManager {
|
|
|
215
215
|
} else {
|
|
216
216
|
// Get info for all sources
|
|
217
217
|
const metadata = await this.getMetadata();
|
|
218
|
-
const totalSize = await getTotalCacheSize();
|
|
218
|
+
const totalSize = await this.getTotalCacheSize();
|
|
219
219
|
|
|
220
220
|
return {
|
|
221
221
|
cacheDir: this.cacheDir,
|
|
@@ -22,7 +22,8 @@ class FrontmatterGenerator {
|
|
|
22
22
|
created_at: metadata.created_at,
|
|
23
23
|
updated_at: metadata.updated_at,
|
|
24
24
|
version: metadata.version,
|
|
25
|
-
|
|
25
|
+
template_type: metadata.template_type,
|
|
26
|
+
min_sce_version: metadata.min_sce_version
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
// Add optional fields if present
|
|
@@ -32,6 +33,15 @@ class FrontmatterGenerator {
|
|
|
32
33
|
if (metadata.applicable_scenarios) {
|
|
33
34
|
frontmatterData.applicable_scenarios = metadata.applicable_scenarios;
|
|
34
35
|
}
|
|
36
|
+
if (metadata.max_sce_version) {
|
|
37
|
+
frontmatterData.max_sce_version = metadata.max_sce_version;
|
|
38
|
+
}
|
|
39
|
+
if (metadata.risk_level) {
|
|
40
|
+
frontmatterData.risk_level = metadata.risk_level;
|
|
41
|
+
}
|
|
42
|
+
if (metadata.rollback_contract) {
|
|
43
|
+
frontmatterData.rollback_contract = metadata.rollback_contract;
|
|
44
|
+
}
|
|
35
45
|
|
|
36
46
|
try {
|
|
37
47
|
const yamlContent = yaml.dump(frontmatterData, {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
const inquirer = require('inquirer');
|
|
6
6
|
const { execSync } = require('child_process');
|
|
7
|
+
const semver = require('semver');
|
|
7
8
|
|
|
8
9
|
class MetadataCollector {
|
|
9
10
|
constructor(options = {}) {
|
|
@@ -50,8 +51,19 @@ class MetadataCollector {
|
|
|
50
51
|
// Version
|
|
51
52
|
metadata.version = await this.promptVersion();
|
|
52
53
|
|
|
53
|
-
//
|
|
54
|
-
metadata.
|
|
54
|
+
// Template type and compatibility
|
|
55
|
+
metadata.template_type = 'spec-scaffold';
|
|
56
|
+
metadata.min_sce_version = await this.promptMinSceVersion();
|
|
57
|
+
metadata.max_sce_version = null;
|
|
58
|
+
|
|
59
|
+
// Default typed metadata for scaffold templates
|
|
60
|
+
metadata.difficulty = 'intermediate';
|
|
61
|
+
metadata.applicable_scenarios = [];
|
|
62
|
+
metadata.risk_level = 'medium';
|
|
63
|
+
metadata.rollback_contract = {
|
|
64
|
+
supported: true,
|
|
65
|
+
strategy: 'git-revert'
|
|
66
|
+
};
|
|
55
67
|
|
|
56
68
|
// Timestamps
|
|
57
69
|
const now = new Date().toISOString().split('T')[0];
|
|
@@ -214,17 +226,17 @@ class MetadataCollector {
|
|
|
214
226
|
* Prompts for sce version
|
|
215
227
|
* @returns {Promise<string>} sce version
|
|
216
228
|
*/
|
|
217
|
-
async
|
|
218
|
-
const currentVersion = this.
|
|
219
|
-
const {
|
|
229
|
+
async promptMinSceVersion() {
|
|
230
|
+
const currentVersion = this.getCurrentSceVersion();
|
|
231
|
+
const { minSceVersion } = await inquirer.prompt([
|
|
220
232
|
{
|
|
221
233
|
type: 'input',
|
|
222
|
-
name: '
|
|
234
|
+
name: 'minSceVersion',
|
|
223
235
|
message: 'Minimum sce version required:',
|
|
224
236
|
default: currentVersion
|
|
225
237
|
}
|
|
226
238
|
]);
|
|
227
|
-
return
|
|
239
|
+
return minSceVersion;
|
|
228
240
|
}
|
|
229
241
|
|
|
230
242
|
/**
|
|
@@ -234,7 +246,7 @@ class MetadataCollector {
|
|
|
234
246
|
*/
|
|
235
247
|
validateMetadata(metadata) {
|
|
236
248
|
const errors = [];
|
|
237
|
-
const requiredFields = ['name', 'description', 'category', 'tags', 'author', 'version', '
|
|
249
|
+
const requiredFields = ['name', 'description', 'category', 'tags', 'author', 'version', 'template_type', 'min_sce_version'];
|
|
238
250
|
|
|
239
251
|
for (const field of requiredFields) {
|
|
240
252
|
if (!metadata[field]) {
|
|
@@ -252,11 +264,28 @@ class MetadataCollector {
|
|
|
252
264
|
errors.push('Version must follow semver format');
|
|
253
265
|
}
|
|
254
266
|
|
|
267
|
+
if (metadata.min_sce_version && !semver.valid(metadata.min_sce_version)) {
|
|
268
|
+
errors.push('min_sce_version must be a valid semver version');
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (metadata.max_sce_version) {
|
|
272
|
+
if (!semver.valid(metadata.max_sce_version)) {
|
|
273
|
+
errors.push('max_sce_version must be a valid semver version');
|
|
274
|
+
} else if (metadata.min_sce_version && semver.gt(metadata.min_sce_version, metadata.max_sce_version)) {
|
|
275
|
+
errors.push('min_sce_version must be less than or equal to max_sce_version');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
255
279
|
// Validate category
|
|
256
280
|
if (metadata.category && !this.categories.includes(metadata.category)) {
|
|
257
281
|
errors.push(`Category must be one of: ${this.categories.join(', ')}`);
|
|
258
282
|
}
|
|
259
283
|
|
|
284
|
+
const validTemplateTypes = ['spec-scaffold', 'capability-template', 'runtime-playbook'];
|
|
285
|
+
if (metadata.template_type && !validTemplateTypes.includes(metadata.template_type)) {
|
|
286
|
+
errors.push(`template_type must be one of: ${validTemplateTypes.join(', ')}`);
|
|
287
|
+
}
|
|
288
|
+
|
|
260
289
|
return {
|
|
261
290
|
valid: errors.length === 0,
|
|
262
291
|
errors
|
|
@@ -293,7 +322,16 @@ class MetadataCollector {
|
|
|
293
322
|
tags: [],
|
|
294
323
|
author: specMetadata.author || this.getGitUser(),
|
|
295
324
|
version: '1.0.0',
|
|
296
|
-
|
|
325
|
+
template_type: 'spec-scaffold',
|
|
326
|
+
min_sce_version: this.getCurrentSceVersion(),
|
|
327
|
+
max_sce_version: null,
|
|
328
|
+
difficulty: 'intermediate',
|
|
329
|
+
applicable_scenarios: [],
|
|
330
|
+
risk_level: 'medium',
|
|
331
|
+
rollback_contract: {
|
|
332
|
+
supported: true,
|
|
333
|
+
strategy: 'git-revert'
|
|
334
|
+
},
|
|
297
335
|
created_at: now,
|
|
298
336
|
updated_at: now
|
|
299
337
|
};
|
|
@@ -315,7 +353,7 @@ class MetadataCollector {
|
|
|
315
353
|
* Gets current sce version
|
|
316
354
|
* @returns {string} sce version
|
|
317
355
|
*/
|
|
318
|
-
|
|
356
|
+
getCurrentSceVersion() {
|
|
319
357
|
try {
|
|
320
358
|
const packageJson = require('../../package.json');
|
|
321
359
|
return packageJson.version;
|
|
@@ -51,7 +51,7 @@ function expandHome(filePath) {
|
|
|
51
51
|
* @returns {string} Path to cache directory
|
|
52
52
|
*/
|
|
53
53
|
function getDefaultCacheDir() {
|
|
54
|
-
return normalize(path.join(os.homedir(), '.
|
|
54
|
+
return normalize(path.join(os.homedir(), '.sce', 'templates'));
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/**
|