scene-capability-engine 3.6.20 → 3.6.22
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 +13 -0
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/docs/command-reference.md +9 -0
- package/docs/magicball-capability-iteration-api.md +33 -8
- package/docs/magicball-capability-iteration-ui.md +7 -1
- package/docs/magicball-capability-library.md +3 -1
- package/lib/commands/capability.js +209 -48
- package/package.json +1 -1
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.22] - 2026-03-06
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- New `sce capability inventory` command provides scene-level triad/readiness aggregation for homepage views.
|
|
14
|
+
- Magicball capability iteration docs now define homepage inventory API and triage usage.
|
|
15
|
+
|
|
16
|
+
## [3.6.21] - 2026-03-06
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- New `sce capability inventory` command provides scene-level triad/readiness aggregation for homepage views.
|
|
20
|
+
- Capability catalog list/search now supports `--release-ready` and `--missing-triad` filters for pre-publish triage.
|
|
21
|
+
- Magicball capability library docs now show list-level triage filter examples.
|
|
22
|
+
|
|
10
23
|
## [3.6.20] - 2026-03-06
|
|
11
24
|
|
|
12
25
|
### Added
|
package/README.md
CHANGED
package/README.zh.md
CHANGED
|
@@ -1869,6 +1869,13 @@ sce scene template-render --package scene-erp --values '{"entity_name":"Order"}'
|
|
|
1869
1869
|
|
|
1870
1870
|
### Capability Iteration (scene -> template -> ontology)
|
|
1871
1871
|
|
|
1872
|
+
```bash
|
|
1873
|
+
# 0) Build scene-level homepage inventory
|
|
1874
|
+
sce capability inventory --json
|
|
1875
|
+
sce capability inventory --release-ready false --missing-triad decision_strategy --json
|
|
1876
|
+
```
|
|
1877
|
+
|
|
1878
|
+
|
|
1872
1879
|
Capability candidates are now evaluated against the ontology core triad by default:
|
|
1873
1880
|
- entity + relation
|
|
1874
1881
|
- business rule
|
|
@@ -1903,6 +1910,8 @@ Catalog payloads also expose `release_readiness_ui` for pre-publish sorting and
|
|
|
1903
1910
|
```bash
|
|
1904
1911
|
# List capability templates
|
|
1905
1912
|
sce capability catalog list --json
|
|
1913
|
+
sce capability catalog list --release-ready true --json
|
|
1914
|
+
sce capability catalog list --missing-triad decision_strategy --json
|
|
1906
1915
|
|
|
1907
1916
|
# Search capability templates
|
|
1908
1917
|
sce capability catalog search "customer order" --json
|
|
@@ -15,7 +15,31 @@
|
|
|
15
15
|
|
|
16
16
|
## 2. 建议 API 列表
|
|
17
17
|
|
|
18
|
-
### 2.1
|
|
18
|
+
### 2.1 Inventory
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
POST /api/capability/inventory
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
请求:
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"release_ready": false,
|
|
28
|
+
"missing_triad": "decision_strategy"
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
执行 CLI:
|
|
33
|
+
```bash
|
|
34
|
+
sce capability inventory --release-ready false --missing-triad decision_strategy --json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
响应:
|
|
38
|
+
- 返回 `capability-inventory` payload,重点消费 `scenes[].ontology_core_ui` 与 `scenes[].release_readiness_ui`
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
### 2.2 Extract
|
|
19
43
|
|
|
20
44
|
```
|
|
21
45
|
POST /api/capability/extract
|
|
@@ -40,7 +64,7 @@ sce capability extract --scene <scene_id> --specs <specs> --sample-limit <n> --j
|
|
|
40
64
|
|
|
41
65
|
---
|
|
42
66
|
|
|
43
|
-
### 2.
|
|
67
|
+
### 2.3 Score
|
|
44
68
|
|
|
45
69
|
```
|
|
46
70
|
POST /api/capability/score
|
|
@@ -63,7 +87,7 @@ sce capability score --input <candidate_file> --json
|
|
|
63
87
|
|
|
64
88
|
---
|
|
65
89
|
|
|
66
|
-
### 2.
|
|
90
|
+
### 2.4 Map
|
|
67
91
|
|
|
68
92
|
```
|
|
69
93
|
POST /api/capability/map
|
|
@@ -91,7 +115,7 @@ sce capability map --input <candidate_file> --mapping <ontology_file> \
|
|
|
91
115
|
|
|
92
116
|
---
|
|
93
117
|
|
|
94
|
-
### 2.
|
|
118
|
+
### 2.5 Register
|
|
95
119
|
|
|
96
120
|
```
|
|
97
121
|
POST /api/capability/register
|
|
@@ -147,8 +171,9 @@ sce capability register --input <template_file> --risk-level <level> --difficult
|
|
|
147
171
|
|
|
148
172
|
## 5. 推荐顺序
|
|
149
173
|
|
|
150
|
-
1. `/api/capability/
|
|
151
|
-
2. `/api/capability/
|
|
152
|
-
3. `/api/capability/
|
|
153
|
-
4. `/api/capability/
|
|
174
|
+
1. `/api/capability/inventory`
|
|
175
|
+
2. `/api/capability/extract`
|
|
176
|
+
3. `/api/capability/score`
|
|
177
|
+
4. `/api/capability/map`
|
|
178
|
+
5. `/api/capability/register`
|
|
154
179
|
|
|
@@ -98,7 +98,13 @@
|
|
|
98
98
|
|
|
99
99
|
## 4. SCE 接口参数(CLI 可封装)
|
|
100
100
|
|
|
101
|
-
### 4.1
|
|
101
|
+
### 4.1 Scene 盘点首页聚合
|
|
102
|
+
```bash
|
|
103
|
+
sce capability inventory --json
|
|
104
|
+
sce capability inventory --release-ready false --missing-triad decision_strategy --json
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 4.2 提取候选能力
|
|
102
108
|
```bash
|
|
103
109
|
sce capability extract --scene <sceneId> --json
|
|
104
110
|
```
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
sce capability catalog list --json
|
|
23
|
-
sce capability catalog
|
|
23
|
+
sce capability catalog list --release-ready true --json
|
|
24
|
+
sce capability catalog list --missing-triad decision_strategy --json
|
|
25
|
+
sce capability catalog search "customer order" --release-ready false --json
|
|
24
26
|
sce capability catalog show <template-id> --json
|
|
25
27
|
```
|
|
26
28
|
|
|
@@ -723,46 +723,10 @@ function buildTemplateCandidate(candidate, mapping, options) {
|
|
|
723
723
|
};
|
|
724
724
|
}
|
|
725
725
|
|
|
726
|
-
function
|
|
727
|
-
const riskLevel = normalizeText(options && options.risk_level) || 'medium';
|
|
728
|
-
const difficulty = normalizeText(options && options.difficulty) || 'intermediate';
|
|
729
|
-
const applicable = normalizeStringArray(options && options.applicable_scenarios);
|
|
730
|
-
const tags = normalizeStringArray(options && options.tags);
|
|
731
|
-
const sceneId = buildSceneIdFromCandidate(templateCandidate);
|
|
732
|
-
const safeTags = tags.length > 0 ? tags : ['capability', sceneId];
|
|
733
|
-
const safeApplicable = applicable.length > 0 ? applicable : [sceneId];
|
|
734
|
-
|
|
735
|
-
return {
|
|
736
|
-
id: templateCandidate.template_id,
|
|
737
|
-
name: templateCandidate.name,
|
|
738
|
-
category: templateCandidate.category,
|
|
739
|
-
description: templateCandidate.description,
|
|
740
|
-
difficulty,
|
|
741
|
-
tags: safeTags,
|
|
742
|
-
applicable_scenarios: safeApplicable,
|
|
743
|
-
files: ['capability-template.json'],
|
|
744
|
-
template_type: 'capability-template',
|
|
745
|
-
min_sce_version: packageJson.version,
|
|
746
|
-
max_sce_version: null,
|
|
747
|
-
risk_level: riskLevel,
|
|
748
|
-
rollback_contract: {
|
|
749
|
-
supported: false,
|
|
750
|
-
strategy: 'n/a'
|
|
751
|
-
},
|
|
752
|
-
ontology_scope: templateCandidate.ontology_scope
|
|
753
|
-
};
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
async function runCapabilityExtractCommand(options = {}, dependencies = {}) {
|
|
726
|
+
async function buildCapabilityCandidatePayload(sceneId, options = {}, dependencies = {}) {
|
|
757
727
|
const projectPath = dependencies.projectPath || process.cwd();
|
|
758
728
|
const fileSystem = dependencies.fileSystem || fs;
|
|
759
729
|
const env = dependencies.env || process.env;
|
|
760
|
-
const sceneId = normalizeText(options.scene || options.sceneId || options.scene_id);
|
|
761
|
-
const writeOutput = normalizeBoolean(options.write, true);
|
|
762
|
-
|
|
763
|
-
if (!sceneId) {
|
|
764
|
-
throw new Error('scene is required for capability extract');
|
|
765
|
-
}
|
|
766
730
|
|
|
767
731
|
const specResolution = await resolveSceneSpecs(sceneId, {
|
|
768
732
|
specs: options.specs
|
|
@@ -816,7 +780,7 @@ async function runCapabilityExtractCommand(options = {}, dependencies = {}) {
|
|
|
816
780
|
|
|
817
781
|
const ontologyScope = mergeOntologyScopes(ontologyScopes);
|
|
818
782
|
const ontologyCore = buildCoreOntologySummary(ontologyScope);
|
|
819
|
-
|
|
783
|
+
return {
|
|
820
784
|
mode: 'capability-extract',
|
|
821
785
|
scene_id: sceneId,
|
|
822
786
|
generated_at: new Date().toISOString(),
|
|
@@ -835,7 +799,138 @@ async function runCapabilityExtractCommand(options = {}, dependencies = {}) {
|
|
|
835
799
|
ontology_missing_triads: ontologyCore.missing
|
|
836
800
|
}
|
|
837
801
|
};
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
async function listCapabilityInventorySceneIds(options = {}, dependencies = {}) {
|
|
805
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
806
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
807
|
+
const env = dependencies.env || process.env;
|
|
808
|
+
const explicitScene = normalizeText(options.scene || options.sceneId || options.scene_id);
|
|
809
|
+
if (explicitScene) {
|
|
810
|
+
return [explicitScene];
|
|
811
|
+
}
|
|
812
|
+
const fromFile = await loadSceneIndexFromFile(projectPath, fileSystem);
|
|
813
|
+
if (fromFile && fromFile.data && fromFile.data.scenes) {
|
|
814
|
+
return Object.keys(fromFile.data.scenes).sort();
|
|
815
|
+
}
|
|
816
|
+
const fromState = await loadSceneIndexFromState(projectPath, fileSystem, env);
|
|
817
|
+
if (fromState && fromState.data && fromState.data.scenes) {
|
|
818
|
+
return Object.keys(fromState.data.scenes).sort();
|
|
819
|
+
}
|
|
820
|
+
return [];
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
function filterCapabilityInventoryEntries(entries, options = {}) {
|
|
824
|
+
const normalizedMissingTriad = normalizeText(options.missingTriad || options.missing_triad).toLowerCase();
|
|
825
|
+
const releaseReadyFilter = normalizeText(options.releaseReady || options.release_ready).toLowerCase();
|
|
826
|
+
return (Array.isArray(entries) ? entries : []).filter((entry) => {
|
|
827
|
+
if (releaseReadyFilter) {
|
|
828
|
+
const expected = ['1', 'true', 'yes', 'ready'].includes(releaseReadyFilter);
|
|
829
|
+
if (Boolean(entry.release_readiness_ui && entry.release_readiness_ui.publish_ready) !== expected) {
|
|
830
|
+
return false;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
if (normalizedMissingTriad) {
|
|
834
|
+
const missing = Array.isArray(entry.release_readiness_ui && entry.release_readiness_ui.blocking_missing)
|
|
835
|
+
? entry.release_readiness_ui.blocking_missing
|
|
836
|
+
: [];
|
|
837
|
+
if (!missing.includes(normalizedMissingTriad)) {
|
|
838
|
+
return false;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return true;
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
async function runCapabilityInventoryCommand(options = {}, dependencies = {}) {
|
|
846
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
847
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
848
|
+
const env = dependencies.env || process.env;
|
|
849
|
+
const sceneIds = await listCapabilityInventorySceneIds(options, { projectPath, fileSystem, env });
|
|
850
|
+
const limit = toPositiveInteger(options.limit, sceneIds.length || 20);
|
|
851
|
+
const scenes = [];
|
|
852
|
+
|
|
853
|
+
for (const sceneId of sceneIds.slice(0, limit)) {
|
|
854
|
+
const candidate = await buildCapabilityCandidatePayload(sceneId, {
|
|
855
|
+
specs: options.specs,
|
|
856
|
+
sample_limit: options.sample_limit
|
|
857
|
+
}, dependencies);
|
|
858
|
+
const score = buildScoreFromCandidate(candidate);
|
|
859
|
+
const releaseReadiness = buildCapabilityReleaseReadiness({
|
|
860
|
+
scene_id: sceneId,
|
|
861
|
+
ontology_scope: candidate.ontology_scope,
|
|
862
|
+
ontology_core: candidate.ontology_core
|
|
863
|
+
});
|
|
864
|
+
scenes.push({
|
|
865
|
+
scene_id: sceneId,
|
|
866
|
+
summary: candidate.summary,
|
|
867
|
+
source: candidate.source,
|
|
868
|
+
ontology_scope: candidate.ontology_scope,
|
|
869
|
+
ontology_core: candidate.ontology_core,
|
|
870
|
+
ontology_core_ui: buildOntologyCoreUiState(candidate.ontology_core),
|
|
871
|
+
release_readiness: releaseReadiness,
|
|
872
|
+
release_readiness_ui: buildCapabilityReleaseReadinessUi(releaseReadiness),
|
|
873
|
+
score_preview: score
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
const filteredScenes = filterCapabilityInventoryEntries(scenes, options);
|
|
878
|
+
const payload = {
|
|
879
|
+
mode: 'capability-inventory',
|
|
880
|
+
generated_at: new Date().toISOString(),
|
|
881
|
+
scene_count: filteredScenes.length,
|
|
882
|
+
scenes: filteredScenes
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
if (normalizeBoolean(options.json, false)) {
|
|
886
|
+
return payload;
|
|
887
|
+
}
|
|
888
|
+
console.log(chalk.green('✅ Capability inventory generated'));
|
|
889
|
+
console.log(chalk.gray(' Scenes: ' + filteredScenes.length));
|
|
890
|
+
return payload;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
function buildRegistryEntry(templateCandidate, options) {
|
|
894
|
+
const riskLevel = normalizeText(options && options.risk_level) || 'medium';
|
|
895
|
+
const difficulty = normalizeText(options && options.difficulty) || 'intermediate';
|
|
896
|
+
const applicable = normalizeStringArray(options && options.applicable_scenarios);
|
|
897
|
+
const tags = normalizeStringArray(options && options.tags);
|
|
898
|
+
const sceneId = buildSceneIdFromCandidate(templateCandidate);
|
|
899
|
+
const safeTags = tags.length > 0 ? tags : ['capability', sceneId];
|
|
900
|
+
const safeApplicable = applicable.length > 0 ? applicable : [sceneId];
|
|
901
|
+
|
|
902
|
+
return {
|
|
903
|
+
id: templateCandidate.template_id,
|
|
904
|
+
name: templateCandidate.name,
|
|
905
|
+
category: templateCandidate.category,
|
|
906
|
+
description: templateCandidate.description,
|
|
907
|
+
difficulty,
|
|
908
|
+
tags: safeTags,
|
|
909
|
+
applicable_scenarios: safeApplicable,
|
|
910
|
+
files: ['capability-template.json'],
|
|
911
|
+
template_type: 'capability-template',
|
|
912
|
+
min_sce_version: packageJson.version,
|
|
913
|
+
max_sce_version: null,
|
|
914
|
+
risk_level: riskLevel,
|
|
915
|
+
rollback_contract: {
|
|
916
|
+
supported: false,
|
|
917
|
+
strategy: 'n/a'
|
|
918
|
+
},
|
|
919
|
+
ontology_scope: templateCandidate.ontology_scope
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
async function runCapabilityExtractCommand(options = {}, dependencies = {}) {
|
|
924
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
925
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
926
|
+
const sceneId = normalizeText(options.scene || options.sceneId || options.scene_id);
|
|
927
|
+
const writeOutput = normalizeBoolean(options.write, true);
|
|
928
|
+
|
|
929
|
+
if (!sceneId) {
|
|
930
|
+
throw new Error('scene is required for capability extract');
|
|
931
|
+
}
|
|
838
932
|
|
|
933
|
+
const payload = await buildCapabilityCandidatePayload(sceneId, options, dependencies);
|
|
839
934
|
const outputPath = normalizeText(options.out) || buildDefaultCandidatePath(sceneId);
|
|
840
935
|
if (writeOutput) {
|
|
841
936
|
await fileSystem.ensureDir(path.dirname(path.join(projectPath, outputPath)));
|
|
@@ -845,17 +940,16 @@ async function runCapabilityExtractCommand(options = {}, dependencies = {}) {
|
|
|
845
940
|
|
|
846
941
|
if (!normalizeBoolean(options.json, false)) {
|
|
847
942
|
console.log(chalk.green('✅ Capability candidate extracted'));
|
|
848
|
-
console.log(chalk.gray(
|
|
849
|
-
console.log(chalk.gray(
|
|
850
|
-
console.log(chalk.gray(
|
|
943
|
+
console.log(chalk.gray(' Scene: ' + sceneId));
|
|
944
|
+
console.log(chalk.gray(' Specs: ' + payload.summary.spec_count));
|
|
945
|
+
console.log(chalk.gray(' Tasks: ' + payload.summary.task_total));
|
|
851
946
|
if (payload.output_file) {
|
|
852
|
-
console.log(chalk.gray(
|
|
947
|
+
console.log(chalk.gray(' Output: ' + payload.output_file));
|
|
853
948
|
}
|
|
854
949
|
}
|
|
855
950
|
|
|
856
951
|
return payload;
|
|
857
952
|
}
|
|
858
|
-
|
|
859
953
|
async function runCapabilityScoreCommand(options = {}, dependencies = {}) {
|
|
860
954
|
const projectPath = dependencies.projectPath || process.cwd();
|
|
861
955
|
const fileSystem = dependencies.fileSystem || fs;
|
|
@@ -1001,6 +1095,34 @@ async function runCapabilityRegisterCommand(options = {}, dependencies = {}) {
|
|
|
1001
1095
|
return result;
|
|
1002
1096
|
}
|
|
1003
1097
|
|
|
1098
|
+
function filterCapabilityCatalogEntries(templates, options = {}) {
|
|
1099
|
+
const entries = Array.isArray(templates) ? templates : [];
|
|
1100
|
+
const normalizedMissingTriad = normalizeText(options.missingTriad || options.missing_triad).toLowerCase();
|
|
1101
|
+
const releaseReadyFilter = normalizeText(options.releaseReady || options.release_ready).toLowerCase();
|
|
1102
|
+
|
|
1103
|
+
return entries.filter((entry) => {
|
|
1104
|
+
const template = enrichCapabilityTemplateForUi(entry);
|
|
1105
|
+
|
|
1106
|
+
if (releaseReadyFilter) {
|
|
1107
|
+
const expected = ['1', 'true', 'yes', 'ready'].includes(releaseReadyFilter);
|
|
1108
|
+
if (template.release_readiness_ui.publish_ready !== expected) {
|
|
1109
|
+
return false;
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
if (normalizedMissingTriad) {
|
|
1114
|
+
const missing = Array.isArray(template.release_readiness_ui.blocking_missing)
|
|
1115
|
+
? template.release_readiness_ui.blocking_missing
|
|
1116
|
+
: [];
|
|
1117
|
+
if (!missing.includes(normalizedMissingTriad)) {
|
|
1118
|
+
return false;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
return true;
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1004
1126
|
function displayCapabilityCatalog(templates, options = {}) {
|
|
1005
1127
|
const total = Array.isArray(templates) ? templates.length : 0;
|
|
1006
1128
|
console.log(chalk.red('🔥') + ' Capability Library');
|
|
@@ -1026,13 +1148,13 @@ function displayCapabilityCatalog(templates, options = {}) {
|
|
|
1026
1148
|
|
|
1027
1149
|
async function listCapabilityCatalog(options = {}) {
|
|
1028
1150
|
const manager = new TemplateManager();
|
|
1029
|
-
const templates = (await manager.listTemplates({
|
|
1151
|
+
const templates = filterCapabilityCatalogEntries((await manager.listTemplates({
|
|
1030
1152
|
category: options.category,
|
|
1031
1153
|
source: options.source,
|
|
1032
1154
|
templateType: 'capability-template',
|
|
1033
1155
|
compatibleWith: options.compatibleWith,
|
|
1034
1156
|
riskLevel: options.risk
|
|
1035
|
-
})).map((template) => enrichCapabilityTemplateForUi(template));
|
|
1157
|
+
})).map((template) => enrichCapabilityTemplateForUi(template)), options);
|
|
1036
1158
|
if (normalizeBoolean(options.json, false)) {
|
|
1037
1159
|
return {
|
|
1038
1160
|
mode: 'capability-catalog-list',
|
|
@@ -1045,13 +1167,13 @@ async function listCapabilityCatalog(options = {}) {
|
|
|
1045
1167
|
|
|
1046
1168
|
async function searchCapabilityCatalog(keyword, options = {}) {
|
|
1047
1169
|
const manager = new TemplateManager();
|
|
1048
|
-
const templates = (await manager.searchTemplates(keyword, {
|
|
1170
|
+
const templates = filterCapabilityCatalogEntries((await manager.searchTemplates(keyword, {
|
|
1049
1171
|
category: options.category,
|
|
1050
1172
|
source: options.source,
|
|
1051
1173
|
templateType: 'capability-template',
|
|
1052
1174
|
compatibleWith: options.compatibleWith,
|
|
1053
1175
|
riskLevel: options.risk
|
|
1054
|
-
})).map((template) => enrichCapabilityTemplateForUi(template));
|
|
1176
|
+
})).map((template) => enrichCapabilityTemplateForUi(template)), options);
|
|
1055
1177
|
if (normalizeBoolean(options.json, false)) {
|
|
1056
1178
|
return {
|
|
1057
1179
|
mode: 'capability-catalog-search',
|
|
@@ -1291,6 +1413,34 @@ function registerCapabilityCommands(program) {
|
|
|
1291
1413
|
});
|
|
1292
1414
|
});
|
|
1293
1415
|
|
|
1416
|
+
capabilityCmd
|
|
1417
|
+
.command('inventory')
|
|
1418
|
+
.description('Build scene-level capability inventory for homepage views')
|
|
1419
|
+
.option('--scene <scene-id>', 'Single scene identifier')
|
|
1420
|
+
.option('--sample-limit <n>', 'Max tasks per spec in sample', '5')
|
|
1421
|
+
.option('--limit <n>', 'Max scenes to include')
|
|
1422
|
+
.option('--release-ready <bool>', 'Filter by publish readiness')
|
|
1423
|
+
.option('--missing-triad <name>', 'Filter by missing triad (entity_relation|business_rules|decision_strategy)')
|
|
1424
|
+
.option('--json', 'Output JSON to stdout')
|
|
1425
|
+
.action(async (options) => {
|
|
1426
|
+
try {
|
|
1427
|
+
const payload = await runCapabilityInventoryCommand({
|
|
1428
|
+
scene: options.scene,
|
|
1429
|
+
sample_limit: options.sampleLimit,
|
|
1430
|
+
limit: options.limit,
|
|
1431
|
+
releaseReady: options.releaseReady,
|
|
1432
|
+
missingTriad: options.missingTriad,
|
|
1433
|
+
json: options.json
|
|
1434
|
+
});
|
|
1435
|
+
if (options.json) {
|
|
1436
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
1437
|
+
}
|
|
1438
|
+
} catch (error) {
|
|
1439
|
+
console.log();
|
|
1440
|
+
console.log(chalk.red('❌ Error:'), error.message);
|
|
1441
|
+
process.exit(1);
|
|
1442
|
+
}
|
|
1443
|
+
});
|
|
1294
1444
|
capabilityCmd
|
|
1295
1445
|
.command('score')
|
|
1296
1446
|
.description('Score a capability candidate')
|
|
@@ -1361,6 +1511,8 @@ function registerCapabilityCommands(program) {
|
|
|
1361
1511
|
.option('--category <name>', 'Template category filter')
|
|
1362
1512
|
.option('--compatible-with <semver>', 'SCE version compatibility')
|
|
1363
1513
|
.option('--risk <level>', 'Risk level filter')
|
|
1514
|
+
.option('--release-ready <bool>', 'Filter by publish readiness')
|
|
1515
|
+
.option('--missing-triad <name>', 'Filter by missing triad (entity_relation|business_rules|decision_strategy)')
|
|
1364
1516
|
.option('--json', 'Output JSON to stdout')
|
|
1365
1517
|
.action(async (options) => {
|
|
1366
1518
|
try {
|
|
@@ -1369,6 +1521,8 @@ function registerCapabilityCommands(program) {
|
|
|
1369
1521
|
category: options.category,
|
|
1370
1522
|
compatibleWith: options.compatibleWith,
|
|
1371
1523
|
risk: options.risk,
|
|
1524
|
+
releaseReady: options.releaseReady,
|
|
1525
|
+
missingTriad: options.missingTriad,
|
|
1372
1526
|
json: options.json
|
|
1373
1527
|
});
|
|
1374
1528
|
if (options.json) {
|
|
@@ -1393,6 +1547,8 @@ function registerCapabilityCommands(program) {
|
|
|
1393
1547
|
.option('--category <name>', 'Template category filter')
|
|
1394
1548
|
.option('--compatible-with <semver>', 'SCE version compatibility')
|
|
1395
1549
|
.option('--risk <level>', 'Risk level filter')
|
|
1550
|
+
.option('--release-ready <bool>', 'Filter by publish readiness')
|
|
1551
|
+
.option('--missing-triad <name>', 'Filter by missing triad (entity_relation|business_rules|decision_strategy)')
|
|
1396
1552
|
.option('--json', 'Output JSON to stdout')
|
|
1397
1553
|
.action(async (keyword, options) => {
|
|
1398
1554
|
try {
|
|
@@ -1401,6 +1557,8 @@ function registerCapabilityCommands(program) {
|
|
|
1401
1557
|
category: options.category,
|
|
1402
1558
|
compatibleWith: options.compatibleWith,
|
|
1403
1559
|
risk: options.risk,
|
|
1560
|
+
releaseReady: options.releaseReady,
|
|
1561
|
+
missingTriad: options.missingTriad,
|
|
1404
1562
|
json: options.json
|
|
1405
1563
|
});
|
|
1406
1564
|
if (options.json) {
|
|
@@ -1494,11 +1652,14 @@ module.exports = {
|
|
|
1494
1652
|
runCapabilityScoreCommand,
|
|
1495
1653
|
runCapabilityMapCommand,
|
|
1496
1654
|
runCapabilityRegisterCommand,
|
|
1655
|
+
runCapabilityInventoryCommand,
|
|
1497
1656
|
listCapabilityCatalog,
|
|
1498
1657
|
searchCapabilityCatalog,
|
|
1499
1658
|
showCapabilityTemplate,
|
|
1500
1659
|
matchCapabilityTemplates,
|
|
1501
1660
|
useCapabilityTemplate,
|
|
1502
1661
|
enrichCapabilityTemplateForUi,
|
|
1503
|
-
buildCapabilityReleaseReadinessUi
|
|
1662
|
+
buildCapabilityReleaseReadinessUi,
|
|
1663
|
+
filterCapabilityCatalogEntries,
|
|
1664
|
+
filterCapabilityInventoryEntries
|
|
1504
1665
|
};
|
package/package.json
CHANGED