scene-capability-engine 3.6.32 → 3.6.37
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 +109 -11
- package/README.md +119 -122
- package/README.zh.md +123 -121
- package/bin/scene-capability-engine.js +12 -1
- package/docs/331-poc-adaptation-roadmap.md +3 -3
- package/docs/README.md +21 -32
- package/docs/auto-refactor-index.md +384 -0
- package/docs/command-reference.md +99 -7
- package/docs/faq.md +1 -1
- package/docs/interactive-customization/331-poc-sce-integration-checklist.md +3 -3
- package/docs/interactive-customization/moqui-interactive-template-playbook.md +4 -4
- package/docs/interactive-customization/phase-acceptance-evidence.md +2 -2
- package/docs/magicball-adaptation-task-checklist-v1.md +385 -0
- package/docs/magicball-app-bundle-sqlite-and-command-draft.md +539 -0
- package/docs/magicball-capability-iteration-api.md +2 -0
- package/docs/magicball-capability-iteration-ui.md +2 -0
- package/docs/magicball-capability-library.md +2 -0
- package/docs/magicball-cli-invocation-examples.md +336 -0
- package/docs/magicball-frontend-state-and-command-mapping.md +244 -0
- package/docs/magicball-integration-doc-index.md +137 -0
- package/docs/magicball-integration-issue-tracker.md +218 -0
- package/docs/magicball-mode-home-and-ontology-empty-state-playbook.md +249 -0
- package/docs/magicball-sce-adaptation-guide.md +203 -0
- package/docs/magicball-three-mode-alignment-plan.md +551 -0
- package/docs/magicball-ui-surface-checklist.md +126 -0
- package/docs/magicball-write-auth-adaptation-guide.md +328 -0
- package/docs/moqui-standard-rebuild-guide.md +6 -6
- package/docs/moqui-template-core-library-playbook.md +1 -1
- package/docs/refactor-completion-roadmap.md +116 -0
- package/docs/release-checklist.md +50 -27
- package/docs/releases/README.md +1 -0
- package/docs/releases/v3.6.37.md +22 -0
- package/docs/steering-strategy-guide.md +7 -7
- package/docs/troubleshooting.md +1 -1
- package/docs/zh/README.md +27 -30
- package/docs/zh/refactor-completion-roadmap.md +116 -0
- package/docs/zh/release-checklist.md +40 -17
- package/docs/zh/releases/README.md +1 -0
- package/docs/zh/releases/v3.6.37.md +22 -0
- package/lib/app/registry-config.js +73 -0
- package/lib/app/registry-sync-service.js +228 -0
- package/lib/auto/archive-schema-service.js +276 -0
- package/lib/auto/archive-summary.js +60 -0
- package/lib/auto/batch-goal-input-service.js +543 -0
- package/lib/auto/batch-output.js +201 -0
- package/lib/auto/batch-summary-storage-service.js +110 -0
- package/lib/auto/close-loop-batch-service.js +116 -0
- package/lib/auto/close-loop-controller-service.js +287 -0
- package/lib/auto/close-loop-program-service.js +283 -0
- package/lib/auto/close-loop-recovery-service.js +191 -0
- package/lib/auto/close-loop-session-storage-service.js +50 -0
- package/lib/auto/controller-lock-service.js +55 -0
- package/lib/auto/controller-output.js +32 -0
- package/lib/auto/controller-queue-service.js +127 -0
- package/lib/auto/controller-session-storage-service.js +105 -0
- package/lib/auto/governance-advisory-service.js +208 -0
- package/lib/auto/governance-close-loop-service.js +411 -0
- package/lib/auto/governance-maintenance-presenter.js +162 -0
- package/lib/auto/governance-maintenance-service.js +112 -0
- package/lib/auto/governance-session-presenter.js +70 -0
- package/lib/auto/governance-session-storage-service.js +198 -0
- package/lib/auto/governance-signals.js +139 -0
- package/lib/auto/governance-stats-presenter.js +337 -0
- package/lib/auto/governance-stats-service.js +115 -0
- package/lib/auto/governance-summary.js +703 -0
- package/lib/auto/handoff-capability-matrix-service.js +281 -0
- package/lib/auto/handoff-evidence-review-service.js +251 -0
- package/lib/auto/handoff-release-evidence-service.js +190 -0
- package/lib/auto/handoff-release-gate-history-loaders-service.js +502 -0
- package/lib/auto/handoff-release-gate-history-service.js +257 -0
- package/lib/auto/handoff-reporting-service.js +1407 -0
- package/lib/auto/handoff-run-service.js +486 -0
- package/lib/auto/handoff-snapshots-service.js +645 -0
- package/lib/auto/observability-service.js +132 -0
- package/lib/auto/output-writer.js +34 -0
- package/lib/auto/program-auto-remediation-service.js +130 -0
- package/lib/auto/program-diagnostics.js +138 -0
- package/lib/auto/program-governance-helpers.js +306 -0
- package/lib/auto/program-governance-loop-service.js +413 -0
- package/lib/auto/program-output.js +106 -0
- package/lib/auto/program-summary.js +183 -0
- package/lib/auto/recovery-memory-service.js +684 -0
- package/lib/auto/recovery-selection-service.js +52 -0
- package/lib/auto/retention-policy.js +98 -0
- package/lib/auto/session-persistence-service.js +106 -0
- package/lib/auto/session-presenter.js +105 -0
- package/lib/auto/session-prune-service.js +190 -0
- package/lib/auto/session-query-service.js +249 -0
- package/lib/auto/spec-protection.js +141 -0
- package/lib/commands/adopt.js +4 -4
- package/lib/commands/app.js +911 -0
- package/lib/commands/assurance.js +212 -0
- package/lib/commands/auto.js +1093 -11065
- package/lib/commands/mode.js +321 -0
- package/lib/commands/ontology.js +415 -0
- package/lib/commands/pm.js +422 -0
- package/lib/ontology/seed-profiles.js +160 -0
- package/lib/spec/bootstrap/context-collector.js +1 -1
- package/lib/state/sce-state-store.js +3369 -1200
- package/lib/steering/adoption-config.js +2 -2
- package/lib/steering/compliance-cache.js +2 -2
- package/lib/steering/steering-manager.js +4 -4
- package/lib/task/task-claimer.js +1 -2
- package/lib/workspace/multi/workspace-context-resolver.js +3 -3
- package/lib/workspace/multi/workspace-state-manager.js +0 -164
- package/lib/workspace/sce-tracking-audit.js +1 -1
- package/lib/workspace/takeover-baseline.js +1 -1
- package/package.json +1 -1
- package/template/.sce/README.md +1 -1
- package/template/.sce/steering/CORE_PRINCIPLES.md +1 -1
- package/bin/kse.js +0 -3
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const { ensureWriteAuthorization } = require('../security/write-authorization');
|
|
4
|
+
const { getSceStateStore } = require('../state/sce-state-store');
|
|
5
|
+
const { listOntologySeedProfiles, resolveOntologySeedProfile, applyOntologySeedProfile } = require('../ontology/seed-profiles');
|
|
6
|
+
|
|
7
|
+
function normalizeString(value) {
|
|
8
|
+
if (typeof value !== 'string') {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
return value.trim();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function normalizePositiveInteger(value, fallback = 100, max = 1000) {
|
|
15
|
+
const parsed = Number.parseInt(`${value}`, 10);
|
|
16
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
17
|
+
return fallback;
|
|
18
|
+
}
|
|
19
|
+
return Math.min(parsed, max);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function createStore(dependencies = {}) {
|
|
23
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
24
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
25
|
+
const env = dependencies.env || process.env;
|
|
26
|
+
return dependencies.stateStore || getSceStateStore(projectPath, {
|
|
27
|
+
fileSystem,
|
|
28
|
+
env
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function buildStatus(statusLabel, attentionLevel, blockingSummary = '', recommendedAction = '') {
|
|
33
|
+
return {
|
|
34
|
+
attention_level: attentionLevel,
|
|
35
|
+
status_tone: attentionLevel === 'high' ? 'warning' : (attentionLevel === 'medium' ? 'info' : 'success'),
|
|
36
|
+
status_label: statusLabel,
|
|
37
|
+
blocking_summary: blockingSummary,
|
|
38
|
+
recommended_action: recommendedAction
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function countBy(items = [], key = 'status') {
|
|
43
|
+
return items.reduce((acc, item) => {
|
|
44
|
+
const value = normalizeString(item && item[key]) || 'unknown';
|
|
45
|
+
acc[value] = (acc[value] || 0) + 1;
|
|
46
|
+
return acc;
|
|
47
|
+
}, {});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function attachErViewModel(items = []) {
|
|
51
|
+
return items.map((item) => ({
|
|
52
|
+
...item,
|
|
53
|
+
relations_summary: Array.isArray(item.relations) ? item.relations.map((entry) => normalizeString(entry && entry.target)).filter(Boolean).join(' / ') : '',
|
|
54
|
+
mb_status: buildStatus(
|
|
55
|
+
item.status === 'active' ? '生效中' : '草稿',
|
|
56
|
+
item.status === 'active' ? 'low' : 'medium',
|
|
57
|
+
'',
|
|
58
|
+
Array.isArray(item.relations) && item.relations.length > 0 ? '继续补齐 relation 结构定义' : '补齐 relation 结构化定义'
|
|
59
|
+
)
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function attachBrViewModel(items = []) {
|
|
64
|
+
return items.map((item) => ({
|
|
65
|
+
...item,
|
|
66
|
+
mb_status: buildStatus(
|
|
67
|
+
item.status === 'active' ? '生效中' : '草稿',
|
|
68
|
+
item.severity === 'blocking' || item.severity === 'high' ? 'high' : (item.status === 'active' ? 'low' : 'medium'),
|
|
69
|
+
'',
|
|
70
|
+
'继续补齐 gate 映射'
|
|
71
|
+
)
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function attachDlViewModel(items = []) {
|
|
76
|
+
return items.map((item) => ({
|
|
77
|
+
...item,
|
|
78
|
+
decision_nodes_summary: Array.isArray(item.decision_nodes) ? `${item.decision_nodes.length} nodes` : '0 nodes',
|
|
79
|
+
outputs_summary: Array.isArray(item.outputs) ? item.outputs.join(' / ') : '',
|
|
80
|
+
mb_status: buildStatus(
|
|
81
|
+
item.status === 'active' ? '生效中' : '草稿',
|
|
82
|
+
item.status === 'active' ? 'low' : 'medium',
|
|
83
|
+
'',
|
|
84
|
+
'继续完善输入输出结构'
|
|
85
|
+
)
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function printPayload(payload, options = {}, title = 'Ontology') {
|
|
90
|
+
if (options.json) {
|
|
91
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
console.log(chalk.blue(title));
|
|
95
|
+
if (payload.mode) console.log(` Mode: ${payload.mode}`);
|
|
96
|
+
if (payload.summary && typeof payload.summary === 'object') {
|
|
97
|
+
for (const [key, value] of Object.entries(payload.summary)) {
|
|
98
|
+
console.log(` ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function ensureAuthorized(action, options = {}, dependencies = {}) {
|
|
104
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
105
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
106
|
+
const env = dependencies.env || process.env;
|
|
107
|
+
await ensureWriteAuthorization(action, {
|
|
108
|
+
authLease: options.authLease,
|
|
109
|
+
authPassword: options.authPassword,
|
|
110
|
+
actor: options.actor
|
|
111
|
+
}, {
|
|
112
|
+
projectPath,
|
|
113
|
+
fileSystem,
|
|
114
|
+
env
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function readInputJson(inputFile, dependencies = {}) {
|
|
119
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
120
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
121
|
+
const resolved = require('path').isAbsolute(inputFile)
|
|
122
|
+
? inputFile
|
|
123
|
+
: require('path').join(projectPath, inputFile);
|
|
124
|
+
return {
|
|
125
|
+
resolved,
|
|
126
|
+
payload: await fileSystem.readJson(resolved)
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function buildTablePayload(mode, query, items, columns) {
|
|
131
|
+
return {
|
|
132
|
+
mode,
|
|
133
|
+
query,
|
|
134
|
+
summary: {
|
|
135
|
+
total: items.length,
|
|
136
|
+
by_status: countBy(items, 'status')
|
|
137
|
+
},
|
|
138
|
+
items,
|
|
139
|
+
filters: [],
|
|
140
|
+
sort: [{ key: 'updated_at', direction: 'desc' }],
|
|
141
|
+
view_model: {
|
|
142
|
+
type: 'table',
|
|
143
|
+
columns
|
|
144
|
+
},
|
|
145
|
+
mb_status: {
|
|
146
|
+
status_label: items.length > 0 ? '有数据' : '空状态',
|
|
147
|
+
attention_level: items.length > 0 ? 'low' : 'medium'
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function runOntologyErListCommand(options = {}, dependencies = {}) {
|
|
153
|
+
const store = createStore(dependencies);
|
|
154
|
+
const items = attachErViewModel(await store.listOntologyErAssets({
|
|
155
|
+
limit: normalizePositiveInteger(options.limit, 100, 1000),
|
|
156
|
+
status: options.status,
|
|
157
|
+
query: options.query
|
|
158
|
+
}) || []);
|
|
159
|
+
const payload = buildTablePayload('ontology-er-list', { space: normalizeString(options.space) || 'engineering', resource: 'ontology-er' }, items, ['name', 'display_name', 'description', 'key_fields', 'relations_summary', 'status', 'updated_at']);
|
|
160
|
+
printPayload(payload, options, 'Ontology ER List');
|
|
161
|
+
return payload;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async function runOntologyErShowCommand(options = {}, dependencies = {}) {
|
|
165
|
+
const id = normalizeString(options.id);
|
|
166
|
+
if (!id) throw new Error('--id is required');
|
|
167
|
+
const store = createStore(dependencies);
|
|
168
|
+
const item = await store.getOntologyErAsset(id);
|
|
169
|
+
if (!item) throw new Error(`ontology er asset not found: ${id}`);
|
|
170
|
+
const payload = { mode: 'ontology-er-show', query: { id }, item: attachErViewModel([item])[0] };
|
|
171
|
+
printPayload(payload, options, 'Ontology ER Show');
|
|
172
|
+
return payload;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function runOntologyErUpsertCommand(options = {}, dependencies = {}) {
|
|
176
|
+
const input = normalizeString(options.input);
|
|
177
|
+
if (!input) throw new Error('--input is required');
|
|
178
|
+
await ensureAuthorized('ontology:er:upsert', options, dependencies);
|
|
179
|
+
const { resolved, payload } = await readInputJson(input, dependencies);
|
|
180
|
+
const store = createStore(dependencies);
|
|
181
|
+
const item = await store.upsertOntologyErAsset(payload);
|
|
182
|
+
const result = { mode: 'ontology-er-upsert', success: true, input_file: resolved, item: attachErViewModel([item])[0] };
|
|
183
|
+
printPayload(result, options, 'Ontology ER Upsert');
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async function runOntologyBrListCommand(options = {}, dependencies = {}) {
|
|
188
|
+
const store = createStore(dependencies);
|
|
189
|
+
const items = attachBrViewModel(await store.listOntologyBrRules({
|
|
190
|
+
limit: normalizePositiveInteger(options.limit, 100, 1000),
|
|
191
|
+
status: options.status,
|
|
192
|
+
query: options.query
|
|
193
|
+
}) || []);
|
|
194
|
+
const payload = buildTablePayload('ontology-br-list', { space: normalizeString(options.space) || 'engineering', resource: 'ontology-br' }, items, ['rule_id', 'title', 'scope', 'condition', 'consequence', 'status', 'updated_at']);
|
|
195
|
+
printPayload(payload, options, 'Ontology BR List');
|
|
196
|
+
return payload;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async function runOntologyBrShowCommand(options = {}, dependencies = {}) {
|
|
200
|
+
const id = normalizeString(options.id);
|
|
201
|
+
if (!id) throw new Error('--id is required');
|
|
202
|
+
const store = createStore(dependencies);
|
|
203
|
+
const item = await store.getOntologyBrRule(id);
|
|
204
|
+
if (!item) throw new Error(`ontology br rule not found: ${id}`);
|
|
205
|
+
const payload = { mode: 'ontology-br-show', query: { id }, item: attachBrViewModel([item])[0] };
|
|
206
|
+
printPayload(payload, options, 'Ontology BR Show');
|
|
207
|
+
return payload;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async function runOntologyBrUpsertCommand(options = {}, dependencies = {}) {
|
|
211
|
+
const input = normalizeString(options.input);
|
|
212
|
+
if (!input) throw new Error('--input is required');
|
|
213
|
+
await ensureAuthorized('ontology:br:upsert', options, dependencies);
|
|
214
|
+
const { resolved, payload } = await readInputJson(input, dependencies);
|
|
215
|
+
const store = createStore(dependencies);
|
|
216
|
+
const item = await store.upsertOntologyBrRule(payload);
|
|
217
|
+
const result = { mode: 'ontology-br-upsert', success: true, input_file: resolved, item: attachBrViewModel([item])[0] };
|
|
218
|
+
printPayload(result, options, 'Ontology BR Upsert');
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function runOntologyDlListCommand(options = {}, dependencies = {}) {
|
|
223
|
+
const store = createStore(dependencies);
|
|
224
|
+
const items = attachDlViewModel(await store.listOntologyDlChains({
|
|
225
|
+
limit: normalizePositiveInteger(options.limit, 100, 1000),
|
|
226
|
+
status: options.status,
|
|
227
|
+
query: options.query
|
|
228
|
+
}) || []);
|
|
229
|
+
const payload = buildTablePayload('ontology-dl-list', { space: normalizeString(options.space) || 'engineering', resource: 'ontology-dl' }, items, ['chain_id', 'title', 'trigger', 'decision_nodes_summary', 'outputs_summary', 'status', 'updated_at']);
|
|
230
|
+
printPayload(payload, options, 'Ontology DL List');
|
|
231
|
+
return payload;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function runOntologyDlShowCommand(options = {}, dependencies = {}) {
|
|
235
|
+
const id = normalizeString(options.id);
|
|
236
|
+
if (!id) throw new Error('--id is required');
|
|
237
|
+
const store = createStore(dependencies);
|
|
238
|
+
const item = await store.getOntologyDlChain(id);
|
|
239
|
+
if (!item) throw new Error(`ontology dl chain not found: ${id}`);
|
|
240
|
+
const payload = { mode: 'ontology-dl-show', query: { id }, item: attachDlViewModel([item])[0] };
|
|
241
|
+
printPayload(payload, options, 'Ontology DL Show');
|
|
242
|
+
return payload;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async function runOntologyDlUpsertCommand(options = {}, dependencies = {}) {
|
|
246
|
+
const input = normalizeString(options.input);
|
|
247
|
+
if (!input) throw new Error('--input is required');
|
|
248
|
+
await ensureAuthorized('ontology:dl:upsert', options, dependencies);
|
|
249
|
+
const { resolved, payload } = await readInputJson(input, dependencies);
|
|
250
|
+
const store = createStore(dependencies);
|
|
251
|
+
const item = await store.upsertOntologyDlChain(payload);
|
|
252
|
+
const result = { mode: 'ontology-dl-upsert', success: true, input_file: resolved, item: attachDlViewModel([item])[0] };
|
|
253
|
+
printPayload(result, options, 'Ontology DL Upsert');
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async function runOntologyTriadSummaryCommand(options = {}, dependencies = {}) {
|
|
258
|
+
const store = createStore(dependencies);
|
|
259
|
+
const summary = await store.buildOntologyTriadSummary({ limit: normalizePositiveInteger(options.limit, 1000, 5000) });
|
|
260
|
+
const availableProfiles = listOntologySeedProfiles();
|
|
261
|
+
const requestedProfile = normalizeString(options.profile);
|
|
262
|
+
const recommendedProfile = requestedProfile
|
|
263
|
+
? resolveOntologySeedProfile(requestedProfile)
|
|
264
|
+
: (resolveOntologySeedProfile('customer-order-demo') || (availableProfiles[0] ? { profile: availableProfiles[0].profile, label: availableProfiles[0].label } : null));
|
|
265
|
+
const starterSeed = summary.ontology_core_ui.ready === true
|
|
266
|
+
? null
|
|
267
|
+
: {
|
|
268
|
+
available_profiles: availableProfiles,
|
|
269
|
+
recommended_profile: recommendedProfile ? recommendedProfile.profile : null,
|
|
270
|
+
recommended_label: recommendedProfile ? recommendedProfile.label : null,
|
|
271
|
+
recommended_command: recommendedProfile
|
|
272
|
+
? `sce ontology seed apply --profile ${recommendedProfile.profile} --json`
|
|
273
|
+
: null
|
|
274
|
+
};
|
|
275
|
+
const payload = {
|
|
276
|
+
mode: 'ontology-triad-summary',
|
|
277
|
+
query: {
|
|
278
|
+
space: normalizeString(options.space) || 'engineering',
|
|
279
|
+
profile: requestedProfile || null
|
|
280
|
+
},
|
|
281
|
+
summary: summary.counts,
|
|
282
|
+
ontology_core: summary.ontology_core,
|
|
283
|
+
ontology_core_ui: summary.ontology_core_ui,
|
|
284
|
+
starter_seed: starterSeed,
|
|
285
|
+
view_model: {
|
|
286
|
+
type: 'triad-summary',
|
|
287
|
+
triads: summary.ontology_core_ui.triads,
|
|
288
|
+
missing: summary.ontology_core_ui.missing,
|
|
289
|
+
coverage_percent: summary.ontology_core_ui.coverage_percent,
|
|
290
|
+
starter_seed: starterSeed
|
|
291
|
+
},
|
|
292
|
+
mb_status: {
|
|
293
|
+
status_label: summary.ontology_core_ui.ready ? 'triad 完整' : 'triad 缺项',
|
|
294
|
+
attention_level: summary.ontology_core_ui.ready ? 'low' : 'high'
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
printPayload(payload, options, 'Ontology Triad Summary');
|
|
298
|
+
return payload;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async function runOntologySeedListCommand(options = {}, dependencies = {}) {
|
|
302
|
+
const items = listOntologySeedProfiles();
|
|
303
|
+
const payload = {
|
|
304
|
+
mode: 'ontology-seed-list',
|
|
305
|
+
summary: { total: items.length },
|
|
306
|
+
items,
|
|
307
|
+
view_model: {
|
|
308
|
+
type: 'table',
|
|
309
|
+
columns: ['profile', 'label', 'description', 'er_count', 'br_count', 'dl_count']
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
printPayload(payload, options, 'Ontology Seed List');
|
|
313
|
+
return payload;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
async function runOntologySeedShowCommand(options = {}, dependencies = {}) {
|
|
317
|
+
const profileName = normalizeString(options.profile);
|
|
318
|
+
if (!profileName) throw new Error('--profile is required');
|
|
319
|
+
const profile = resolveOntologySeedProfile(profileName);
|
|
320
|
+
if (!profile) throw new Error(`ontology seed profile not found: ${profileName}`);
|
|
321
|
+
const payload = {
|
|
322
|
+
mode: 'ontology-seed-show',
|
|
323
|
+
profile: profile.profile,
|
|
324
|
+
label: profile.label,
|
|
325
|
+
description: profile.description,
|
|
326
|
+
summary: {
|
|
327
|
+
er_count: Array.isArray(profile.er) ? profile.er.length : 0,
|
|
328
|
+
br_count: Array.isArray(profile.br) ? profile.br.length : 0,
|
|
329
|
+
dl_count: Array.isArray(profile.dl) ? profile.dl.length : 0
|
|
330
|
+
},
|
|
331
|
+
profile_payload: profile
|
|
332
|
+
};
|
|
333
|
+
printPayload(payload, options, 'Ontology Seed Show');
|
|
334
|
+
return payload;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
async function runOntologySeedApplyCommand(options = {}, dependencies = {}) {
|
|
338
|
+
const profileName = normalizeString(options.profile);
|
|
339
|
+
if (!profileName) throw new Error('--profile is required');
|
|
340
|
+
await ensureAuthorized('ontology:seed:apply', options, dependencies);
|
|
341
|
+
const store = createStore(dependencies);
|
|
342
|
+
const result = await applyOntologySeedProfile(profileName, store);
|
|
343
|
+
const payload = {
|
|
344
|
+
mode: 'ontology-seed-apply',
|
|
345
|
+
success: true,
|
|
346
|
+
profile: result.profile,
|
|
347
|
+
label: result.label,
|
|
348
|
+
summary: {
|
|
349
|
+
er_written: result.written.er.length,
|
|
350
|
+
br_written: result.written.br.length,
|
|
351
|
+
dl_written: result.written.dl.length
|
|
352
|
+
},
|
|
353
|
+
triad: result.triad
|
|
354
|
+
};
|
|
355
|
+
printPayload(payload, options, 'Ontology Seed Apply');
|
|
356
|
+
return payload;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function safeRun(handler, options = {}, context = 'ontology command') {
|
|
360
|
+
Promise.resolve(handler(options))
|
|
361
|
+
.catch((error) => {
|
|
362
|
+
if (options.json) {
|
|
363
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
364
|
+
} else {
|
|
365
|
+
console.error(chalk.red(`${context} failed:`), error.message);
|
|
366
|
+
}
|
|
367
|
+
process.exitCode = 1;
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function registerOntologyCommands(program) {
|
|
372
|
+
const ontology = program
|
|
373
|
+
.command('ontology')
|
|
374
|
+
.description('Engineering ontology data plane for MagicBall ontology mode');
|
|
375
|
+
|
|
376
|
+
const er = ontology.command('er').description('Manage ER assets');
|
|
377
|
+
er.command('list').option('--space <space>', 'Space name', 'engineering').option('--limit <n>', 'Maximum rows', '100').option('--status <status>', 'Filter by status').option('--query <text>', 'Free-text query').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyErListCommand, options, 'ontology er list'));
|
|
378
|
+
er.command('show').requiredOption('--id <entity-id>', 'Entity id').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyErShowCommand, options, 'ontology er show'));
|
|
379
|
+
er.command('upsert').requiredOption('--input <path>', 'ER JSON file').option('--auth-lease <lease-id>', 'Write authorization lease id').option('--auth-password <password>', 'Inline auth password if policy allows').option('--actor <actor>', 'Audit actor override').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyErUpsertCommand, options, 'ontology er upsert'));
|
|
380
|
+
|
|
381
|
+
const br = ontology.command('br').description('Manage BR rules');
|
|
382
|
+
br.command('list').option('--space <space>', 'Space name', 'engineering').option('--limit <n>', 'Maximum rows', '100').option('--status <status>', 'Filter by status').option('--query <text>', 'Free-text query').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyBrListCommand, options, 'ontology br list'));
|
|
383
|
+
br.command('show').requiredOption('--id <rule-id>', 'Rule id').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyBrShowCommand, options, 'ontology br show'));
|
|
384
|
+
br.command('upsert').requiredOption('--input <path>', 'BR JSON file').option('--auth-lease <lease-id>', 'Write authorization lease id').option('--auth-password <password>', 'Inline auth password if policy allows').option('--actor <actor>', 'Audit actor override').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyBrUpsertCommand, options, 'ontology br upsert'));
|
|
385
|
+
|
|
386
|
+
const dl = ontology.command('dl').description('Manage DL chains');
|
|
387
|
+
dl.command('list').option('--space <space>', 'Space name', 'engineering').option('--limit <n>', 'Maximum rows', '100').option('--status <status>', 'Filter by status').option('--query <text>', 'Free-text query').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyDlListCommand, options, 'ontology dl list'));
|
|
388
|
+
dl.command('show').requiredOption('--id <chain-id>', 'Chain id').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyDlShowCommand, options, 'ontology dl show'));
|
|
389
|
+
dl.command('upsert').requiredOption('--input <path>', 'DL JSON file').option('--auth-lease <lease-id>', 'Write authorization lease id').option('--auth-password <password>', 'Inline auth password if policy allows').option('--actor <actor>', 'Audit actor override').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyDlUpsertCommand, options, 'ontology dl upsert'));
|
|
390
|
+
|
|
391
|
+
const triad = ontology.command('triad').description('Summarize ontology triad completeness');
|
|
392
|
+
triad.command('summary').option('--space <space>', 'Space name', 'engineering').option('--limit <n>', 'Limit for source scans', '1000').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologyTriadSummaryCommand, options, 'ontology triad summary'));
|
|
393
|
+
|
|
394
|
+
const seed = ontology.command('seed').description('Manage built-in ontology starter seeds');
|
|
395
|
+
seed.command('list').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologySeedListCommand, options, 'ontology seed list'));
|
|
396
|
+
seed.command('show').requiredOption('--profile <profile>', 'Seed profile name').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologySeedShowCommand, options, 'ontology seed show'));
|
|
397
|
+
seed.command('apply').requiredOption('--profile <profile>', 'Seed profile name').option('--auth-lease <lease-id>', 'Write authorization lease id').option('--auth-password <password>', 'Inline auth password if policy allows').option('--actor <actor>', 'Audit actor override').option('--json', 'Print machine-readable JSON output').action((options) => safeRun(runOntologySeedApplyCommand, options, 'ontology seed apply'));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
module.exports = {
|
|
401
|
+
runOntologyErListCommand,
|
|
402
|
+
runOntologyErShowCommand,
|
|
403
|
+
runOntologyErUpsertCommand,
|
|
404
|
+
runOntologyBrListCommand,
|
|
405
|
+
runOntologyBrShowCommand,
|
|
406
|
+
runOntologyBrUpsertCommand,
|
|
407
|
+
runOntologyDlListCommand,
|
|
408
|
+
runOntologyDlShowCommand,
|
|
409
|
+
runOntologyDlUpsertCommand,
|
|
410
|
+
runOntologyTriadSummaryCommand,
|
|
411
|
+
runOntologySeedListCommand,
|
|
412
|
+
runOntologySeedShowCommand,
|
|
413
|
+
runOntologySeedApplyCommand,
|
|
414
|
+
registerOntologyCommands
|
|
415
|
+
};
|