scene-capability-engine 3.6.18 → 3.6.20

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 CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.6.20] - 2026-03-06
11
+
12
+ ### Added
13
+ - Capability catalog entries now expose pre-publish readiness UI fields for badge rendering and sorting.
14
+ - Magicball capability library guide now documents list-level publish readiness fields.
15
+
16
+ ## [3.6.19] - 2026-03-06
17
+
18
+ ### Added
19
+ - Capability map/register payloads now expose `release_readiness` with structured blocking reasons for publish UI.
20
+ - Capability catalog payloads now expose `release_readiness_ui` for pre-publish status badges and sorting.
21
+ - Magicball capability docs now define release blocker rendering for capability publish pages.
22
+
10
23
  ## [3.6.18] - 2026-03-06
11
24
 
12
25
  ### Added
package/README.md CHANGED
@@ -218,5 +218,5 @@ MIT. See [LICENSE](LICENSE).
218
218
 
219
219
  ---
220
220
 
221
- **Version**: 3.6.18
221
+ **Version**: 3.6.20
222
222
  **Last Updated**: 2026-03-05
package/README.zh.md CHANGED
@@ -218,5 +218,5 @@ MIT,见 [LICENSE](LICENSE)。
218
218
 
219
219
  ---
220
220
 
221
- **版本**:3.6.18
221
+ **版本**:3.6.20
222
222
  **最后更新**:2026-03-05
@@ -1897,6 +1897,8 @@ Schema references:
1897
1897
  ### Capability Library Reuse (query -> match -> use)
1898
1898
 
1899
1899
  `catalog/list/search/show/match/use` responses now include `ontology_core` and `ontology_core_ui` so UI can render triad readiness directly.
1900
+ `capability map/register` responses now include `release_readiness` so UI can render blocking reasons before publish.
1901
+ Catalog payloads also expose `release_readiness_ui` for pre-publish sorting and status badges.
1900
1902
 
1901
1903
  ```bash
1902
1904
  # List capability templates
@@ -87,7 +87,7 @@ sce capability map --input <candidate_file> --mapping <ontology_file> \
87
87
  ```
88
88
 
89
89
  响应:
90
- - 返回 `capability-map` payload,重点消费 `template.ontology_core`
90
+ - 返回 `capability-map` payload,重点消费 `template.ontology_core` 与 `release_readiness`
91
91
 
92
92
  ---
93
93
 
@@ -112,7 +112,7 @@ sce capability register --input <template_file> --risk-level <level> --difficult
112
112
  ```
113
113
 
114
114
  响应:
115
- - 返回 `capability-register` payload,重点消费 `ontology_core`(入库 triad 审核结果)
115
+ - 返回 `capability-register` payload,重点消费 `ontology_core` 与 `release_readiness`(入库 triad 审核结果)
116
116
 
117
117
  ---
118
118
 
@@ -180,3 +180,9 @@ sce capability register --input <template.json> --json
180
180
  - `ontology_core_ui.missing`
181
181
  - `summary.ontology_triads_ready`
182
182
  - `summary.ontology_missing_triads`
183
+
184
+ ## 9. 发布阻断提示
185
+
186
+ - 发布页直接消费 `release_readiness.ready`
187
+ - 若为 `false`,展示 `blockers[].reason`、`blockers[].missing`、`blockers[].remediation`
188
+ - 默认阻断文案:`能力模板未达到发布条件`
@@ -145,3 +145,35 @@ sce capability use --template <template-id> --spec <spec-id> --apply --json
145
145
  ---
146
146
 
147
147
  若需要“自动落地写入 spec 任务”的强制执行模式,可以在后续版本加 `--apply` 开关。
148
+
149
+ ### release_readiness_ui(列表状态)
150
+ ```json
151
+ {
152
+ "publish_ready": false,
153
+ "blocking_count": 1,
154
+ "blocking_ids": ["ontology-core-triads"],
155
+ "blocking_reasons": ["missing required ontology triads"],
156
+ "blocking_missing": ["decision_strategy"]
157
+ }
158
+ ```
159
+
160
+ ### release_readiness(发布阻断原因)
161
+ ```json
162
+ {
163
+ "ready": false,
164
+ "blockers": [
165
+ {
166
+ "id": "ontology-core-triads",
167
+ "severity": "blocking",
168
+ "reason": "missing required ontology triads",
169
+ "missing": ["decision_strategy"],
170
+ "missing_labels": ["decision_strategy"],
171
+ "remediation": [
172
+ "补齐实体关系(entities + relations)",
173
+ "补齐业务规则(business_rules)",
174
+ "补齐决策策略(decisions)"
175
+ ]
176
+ }
177
+ ]
178
+ }
179
+ ```
@@ -432,10 +432,66 @@ function enrichCapabilityTemplateForUi(template) {
432
432
  const ontologyCore = template && template.ontology_core
433
433
  ? template.ontology_core
434
434
  : buildCoreOntologySummary(template && template.ontology_scope ? template.ontology_scope : createEmptyOntologyScope());
435
+ const releaseReadiness = template && template.release_readiness
436
+ ? template.release_readiness
437
+ : {
438
+ ready: ontologyCore.ready === true,
439
+ blockers: ontologyCore.ready === true
440
+ ? []
441
+ : [{
442
+ id: 'ontology-core-triads',
443
+ severity: 'blocking',
444
+ reason: 'missing required ontology triads',
445
+ missing: Array.isArray(ontologyCore.missing) ? ontologyCore.missing : []
446
+ }],
447
+ ontology_core: ontologyCore,
448
+ ontology_core_ui: buildOntologyCoreUiState(ontologyCore)
449
+ };
435
450
  return {
436
451
  ...template,
437
452
  ontology_core: ontologyCore,
438
- ontology_core_ui: buildOntologyCoreUiState(ontologyCore)
453
+ ontology_core_ui: buildOntologyCoreUiState(ontologyCore),
454
+ release_readiness: releaseReadiness,
455
+ release_readiness_ui: buildCapabilityReleaseReadinessUi(releaseReadiness)
456
+ };
457
+ }
458
+
459
+ function buildCapabilityReleaseReadiness(templateCandidate) {
460
+ const enriched = enrichCapabilityTemplateForUi(templateCandidate || {});
461
+ const blockers = [];
462
+ if (!enriched.ontology_core.ready) {
463
+ blockers.push({
464
+ id: 'ontology-core-triads',
465
+ severity: 'blocking',
466
+ reason: 'missing required ontology triads',
467
+ missing: enriched.ontology_core.missing,
468
+ missing_labels: enriched.ontology_core_ui.missing_labels,
469
+ remediation: [
470
+ '补齐实体关系(entities + relations)',
471
+ '补齐业务规则(business_rules)',
472
+ '补齐决策策略(decisions)'
473
+ ]
474
+ });
475
+ }
476
+ return {
477
+ ready: blockers.length === 0,
478
+ blockers,
479
+ ontology_core: enriched.ontology_core,
480
+ ontology_core_ui: enriched.ontology_core_ui
481
+ };
482
+ }
483
+
484
+ function buildCapabilityReleaseReadinessUi(readiness) {
485
+ const details = readiness && typeof readiness === 'object'
486
+ ? readiness
487
+ : { ready: true, blockers: [] };
488
+ const blockers = Array.isArray(details.blockers) ? details.blockers : [];
489
+ return {
490
+ publish_ready: details.ready === true,
491
+ blocking_count: blockers.length,
492
+ blocking_ids: blockers.map((item) => item && item.id).filter(Boolean),
493
+ blocking_reasons: blockers.map((item) => item && item.reason).filter(Boolean),
494
+ blocking_missing: blockers.flatMap((item) => Array.isArray(item && item.missing) ? item.missing : [])
439
495
  };
440
496
  }
441
497
 
@@ -861,7 +917,8 @@ async function runCapabilityMapCommand(options = {}, dependencies = {}) {
861
917
  generated_at: new Date().toISOString(),
862
918
  input: inputPath,
863
919
  mapping: mappingPath || null,
864
- template: templateCandidate
920
+ template: templateCandidate,
921
+ release_readiness: buildCapabilityReleaseReadiness(templateCandidate)
865
922
  };
866
923
 
867
924
  const outputPath = normalizeText(options.out) || buildDefaultTemplatePath(sceneId);
@@ -895,6 +952,15 @@ async function runCapabilityRegisterCommand(options = {}, dependencies = {}) {
895
952
  if (!templateCandidate || !templateCandidate.template_id) {
896
953
  throw new Error('template_id missing in capability template candidate');
897
954
  }
955
+ const releaseReadiness = buildCapabilityReleaseReadiness(templateCandidate);
956
+ if (!releaseReadiness.ready) {
957
+ const error = new Error(`capability register blocked: ${releaseReadiness.blockers.map((item) => item.reason).join('; ')}`);
958
+ error.code = 'CAPABILITY_REGISTER_BLOCKED';
959
+ error.details = {
960
+ release_readiness: releaseReadiness
961
+ };
962
+ throw error;
963
+ }
898
964
  const ontologySummary = assertCoreOntologySummary(
899
965
  buildCoreOntologySummary(templateCandidate.ontology_scope),
900
966
  'capability template'
@@ -919,6 +985,7 @@ async function runCapabilityRegisterCommand(options = {}, dependencies = {}) {
919
985
  template_id: templateCandidate.template_id,
920
986
  output_dir: exportDir,
921
987
  ontology_core: ontologySummary,
988
+ release_readiness: releaseReadiness,
922
989
  files: [
923
990
  path.join(exportDir, 'capability-template.json'),
924
991
  path.join(exportDir, 'template-registry.json')
@@ -1426,5 +1493,12 @@ module.exports = {
1426
1493
  runCapabilityExtractCommand,
1427
1494
  runCapabilityScoreCommand,
1428
1495
  runCapabilityMapCommand,
1429
- runCapabilityRegisterCommand
1496
+ runCapabilityRegisterCommand,
1497
+ listCapabilityCatalog,
1498
+ searchCapabilityCatalog,
1499
+ showCapabilityTemplate,
1500
+ matchCapabilityTemplates,
1501
+ useCapabilityTemplate,
1502
+ enrichCapabilityTemplateForUi,
1503
+ buildCapabilityReleaseReadinessUi
1430
1504
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scene-capability-engine",
3
- "version": "3.6.18",
3
+ "version": "3.6.20",
4
4
  "description": "SCE (Scene Capability Engine) - A CLI tool and npm package for spec-driven development with AI coding assistants.",
5
5
  "main": "index.js",
6
6
  "bin": {