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.
Files changed (111) hide show
  1. package/CHANGELOG.md +109 -11
  2. package/README.md +119 -122
  3. package/README.zh.md +123 -121
  4. package/bin/scene-capability-engine.js +12 -1
  5. package/docs/331-poc-adaptation-roadmap.md +3 -3
  6. package/docs/README.md +21 -32
  7. package/docs/auto-refactor-index.md +384 -0
  8. package/docs/command-reference.md +99 -7
  9. package/docs/faq.md +1 -1
  10. package/docs/interactive-customization/331-poc-sce-integration-checklist.md +3 -3
  11. package/docs/interactive-customization/moqui-interactive-template-playbook.md +4 -4
  12. package/docs/interactive-customization/phase-acceptance-evidence.md +2 -2
  13. package/docs/magicball-adaptation-task-checklist-v1.md +385 -0
  14. package/docs/magicball-app-bundle-sqlite-and-command-draft.md +539 -0
  15. package/docs/magicball-capability-iteration-api.md +2 -0
  16. package/docs/magicball-capability-iteration-ui.md +2 -0
  17. package/docs/magicball-capability-library.md +2 -0
  18. package/docs/magicball-cli-invocation-examples.md +336 -0
  19. package/docs/magicball-frontend-state-and-command-mapping.md +244 -0
  20. package/docs/magicball-integration-doc-index.md +137 -0
  21. package/docs/magicball-integration-issue-tracker.md +218 -0
  22. package/docs/magicball-mode-home-and-ontology-empty-state-playbook.md +249 -0
  23. package/docs/magicball-sce-adaptation-guide.md +203 -0
  24. package/docs/magicball-three-mode-alignment-plan.md +551 -0
  25. package/docs/magicball-ui-surface-checklist.md +126 -0
  26. package/docs/magicball-write-auth-adaptation-guide.md +328 -0
  27. package/docs/moqui-standard-rebuild-guide.md +6 -6
  28. package/docs/moqui-template-core-library-playbook.md +1 -1
  29. package/docs/refactor-completion-roadmap.md +116 -0
  30. package/docs/release-checklist.md +50 -27
  31. package/docs/releases/README.md +1 -0
  32. package/docs/releases/v3.6.37.md +22 -0
  33. package/docs/steering-strategy-guide.md +7 -7
  34. package/docs/troubleshooting.md +1 -1
  35. package/docs/zh/README.md +27 -30
  36. package/docs/zh/refactor-completion-roadmap.md +116 -0
  37. package/docs/zh/release-checklist.md +40 -17
  38. package/docs/zh/releases/README.md +1 -0
  39. package/docs/zh/releases/v3.6.37.md +22 -0
  40. package/lib/app/registry-config.js +73 -0
  41. package/lib/app/registry-sync-service.js +228 -0
  42. package/lib/auto/archive-schema-service.js +276 -0
  43. package/lib/auto/archive-summary.js +60 -0
  44. package/lib/auto/batch-goal-input-service.js +543 -0
  45. package/lib/auto/batch-output.js +201 -0
  46. package/lib/auto/batch-summary-storage-service.js +110 -0
  47. package/lib/auto/close-loop-batch-service.js +116 -0
  48. package/lib/auto/close-loop-controller-service.js +287 -0
  49. package/lib/auto/close-loop-program-service.js +283 -0
  50. package/lib/auto/close-loop-recovery-service.js +191 -0
  51. package/lib/auto/close-loop-session-storage-service.js +50 -0
  52. package/lib/auto/controller-lock-service.js +55 -0
  53. package/lib/auto/controller-output.js +32 -0
  54. package/lib/auto/controller-queue-service.js +127 -0
  55. package/lib/auto/controller-session-storage-service.js +105 -0
  56. package/lib/auto/governance-advisory-service.js +208 -0
  57. package/lib/auto/governance-close-loop-service.js +411 -0
  58. package/lib/auto/governance-maintenance-presenter.js +162 -0
  59. package/lib/auto/governance-maintenance-service.js +112 -0
  60. package/lib/auto/governance-session-presenter.js +70 -0
  61. package/lib/auto/governance-session-storage-service.js +198 -0
  62. package/lib/auto/governance-signals.js +139 -0
  63. package/lib/auto/governance-stats-presenter.js +337 -0
  64. package/lib/auto/governance-stats-service.js +115 -0
  65. package/lib/auto/governance-summary.js +703 -0
  66. package/lib/auto/handoff-capability-matrix-service.js +281 -0
  67. package/lib/auto/handoff-evidence-review-service.js +251 -0
  68. package/lib/auto/handoff-release-evidence-service.js +190 -0
  69. package/lib/auto/handoff-release-gate-history-loaders-service.js +502 -0
  70. package/lib/auto/handoff-release-gate-history-service.js +257 -0
  71. package/lib/auto/handoff-reporting-service.js +1407 -0
  72. package/lib/auto/handoff-run-service.js +486 -0
  73. package/lib/auto/handoff-snapshots-service.js +645 -0
  74. package/lib/auto/observability-service.js +132 -0
  75. package/lib/auto/output-writer.js +34 -0
  76. package/lib/auto/program-auto-remediation-service.js +130 -0
  77. package/lib/auto/program-diagnostics.js +138 -0
  78. package/lib/auto/program-governance-helpers.js +306 -0
  79. package/lib/auto/program-governance-loop-service.js +413 -0
  80. package/lib/auto/program-output.js +106 -0
  81. package/lib/auto/program-summary.js +183 -0
  82. package/lib/auto/recovery-memory-service.js +684 -0
  83. package/lib/auto/recovery-selection-service.js +52 -0
  84. package/lib/auto/retention-policy.js +98 -0
  85. package/lib/auto/session-persistence-service.js +106 -0
  86. package/lib/auto/session-presenter.js +105 -0
  87. package/lib/auto/session-prune-service.js +190 -0
  88. package/lib/auto/session-query-service.js +249 -0
  89. package/lib/auto/spec-protection.js +141 -0
  90. package/lib/commands/adopt.js +4 -4
  91. package/lib/commands/app.js +911 -0
  92. package/lib/commands/assurance.js +212 -0
  93. package/lib/commands/auto.js +1093 -11065
  94. package/lib/commands/mode.js +321 -0
  95. package/lib/commands/ontology.js +415 -0
  96. package/lib/commands/pm.js +422 -0
  97. package/lib/ontology/seed-profiles.js +160 -0
  98. package/lib/spec/bootstrap/context-collector.js +1 -1
  99. package/lib/state/sce-state-store.js +3369 -1200
  100. package/lib/steering/adoption-config.js +2 -2
  101. package/lib/steering/compliance-cache.js +2 -2
  102. package/lib/steering/steering-manager.js +4 -4
  103. package/lib/task/task-claimer.js +1 -2
  104. package/lib/workspace/multi/workspace-context-resolver.js +3 -3
  105. package/lib/workspace/multi/workspace-state-manager.js +0 -164
  106. package/lib/workspace/sce-tracking-audit.js +1 -1
  107. package/lib/workspace/takeover-baseline.js +1 -1
  108. package/package.json +1 -1
  109. package/template/.sce/README.md +1 -1
  110. package/template/.sce/steering/CORE_PRINCIPLES.md +1 -1
  111. 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
+ };