scene-capability-engine 3.6.32 → 3.6.36
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 +86 -1
- package/README.md +119 -122
- package/README.zh.md +123 -121
- package/bin/scene-capability-engine.js +11 -0
- package/docs/README.md +21 -32
- package/docs/auto-refactor-index.md +384 -0
- package/docs/command-reference.md +94 -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/refactor-completion-roadmap.md +116 -0
- package/docs/zh/README.md +27 -30
- package/docs/zh/refactor-completion-roadmap.md +116 -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/app.js +911 -0
- package/lib/commands/assurance.js +212 -0
- package/lib/commands/auto.js +1091 -11063
- 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/state/sce-state-store.js +3369 -1200
- package/package.json +1 -1
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const { getSceStateStore } = require('../state/sce-state-store');
|
|
4
|
+
const { resolveOntologySeedProfile, listOntologySeedProfiles } = require('../ontology/seed-profiles');
|
|
5
|
+
|
|
6
|
+
function normalizeString(value) {
|
|
7
|
+
if (typeof value !== 'string') {
|
|
8
|
+
return '';
|
|
9
|
+
}
|
|
10
|
+
return value.trim();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function createStore(dependencies = {}) {
|
|
14
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
15
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
16
|
+
const env = dependencies.env || process.env;
|
|
17
|
+
return dependencies.stateStore || getSceStateStore(projectPath, {
|
|
18
|
+
fileSystem,
|
|
19
|
+
env
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function normalizePositiveInteger(value, fallback = 5, max = 3600) {
|
|
24
|
+
const parsed = Number.parseInt(`${value}`, 10);
|
|
25
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
26
|
+
return fallback;
|
|
27
|
+
}
|
|
28
|
+
return Math.min(parsed, max);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isFreshProjectionCache(cacheRecord, ttlSeconds) {
|
|
32
|
+
const generatedAt = cacheRecord && cacheRecord.generated_at ? Date.parse(cacheRecord.generated_at) : NaN;
|
|
33
|
+
if (!Number.isFinite(generatedAt)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const maxAgeMs = normalizePositiveInteger(ttlSeconds, 5, 3600) * 1000;
|
|
37
|
+
return (Date.now() - generatedAt) <= maxAgeMs;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function buildApplicationHome(graph = {}, dependencies = {}) {
|
|
41
|
+
const bundle = graph.bundle || {};
|
|
42
|
+
const runtimeRelease = graph.runtime_release || {};
|
|
43
|
+
const sceneBindings = Array.isArray(graph.scene_bindings) ? graph.scene_bindings : [];
|
|
44
|
+
const metadata = bundle.metadata && typeof bundle.metadata === 'object' ? bundle.metadata : {};
|
|
45
|
+
const installation = metadata.runtime_installation && typeof metadata.runtime_installation === 'object'
|
|
46
|
+
? metadata.runtime_installation
|
|
47
|
+
: {};
|
|
48
|
+
const serviceCatalog = metadata.service_catalog && typeof metadata.service_catalog === 'object'
|
|
49
|
+
? metadata.service_catalog
|
|
50
|
+
: {};
|
|
51
|
+
const releases = Array.isArray(serviceCatalog.releases) ? serviceCatalog.releases : [];
|
|
52
|
+
return {
|
|
53
|
+
mode: 'application-home',
|
|
54
|
+
query: {
|
|
55
|
+
app_id: bundle.app_id || null
|
|
56
|
+
},
|
|
57
|
+
summary: {
|
|
58
|
+
app_name: bundle.app_name || null,
|
|
59
|
+
runtime_version: runtimeRelease.runtime_version || null,
|
|
60
|
+
environment: bundle.environment || null,
|
|
61
|
+
release_status: runtimeRelease.release_status || null,
|
|
62
|
+
runtime_status: runtimeRelease.runtime_status || null,
|
|
63
|
+
install_status: installation.status || 'not-installed',
|
|
64
|
+
release_count: releases.length
|
|
65
|
+
},
|
|
66
|
+
relations: {
|
|
67
|
+
runtime_release_id: bundle.runtime_release_id || null,
|
|
68
|
+
ontology_bundle_id: bundle.ontology_bundle_id || null,
|
|
69
|
+
engineering_project_id: bundle.engineering_project_id || null,
|
|
70
|
+
default_scene_id: bundle.default_scene_id || null
|
|
71
|
+
},
|
|
72
|
+
items: releases,
|
|
73
|
+
view_model: {
|
|
74
|
+
projection: 'application',
|
|
75
|
+
app_id: bundle.app_id || null,
|
|
76
|
+
app_key: bundle.app_key || null,
|
|
77
|
+
app_name: bundle.app_name || null,
|
|
78
|
+
entrypoint: runtimeRelease.entrypoint || null,
|
|
79
|
+
current_release: installation.release_id || runtimeRelease.release_id || null,
|
|
80
|
+
current_environment: bundle.environment || installation.current_environment || null,
|
|
81
|
+
install_root: installation.install_root || null,
|
|
82
|
+
scene_binding_count: sceneBindings.length,
|
|
83
|
+
release_count: releases.length
|
|
84
|
+
},
|
|
85
|
+
mb_status: runtimeRelease.runtime_status || installation.status || bundle.status || 'unknown'
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function buildOntologyHome(graph = {}, dependencies = {}) {
|
|
90
|
+
const bundle = graph.bundle || {};
|
|
91
|
+
const ontologyBundle = graph.ontology_bundle || {};
|
|
92
|
+
const store = dependencies.store;
|
|
93
|
+
const triad = store
|
|
94
|
+
? await store.buildOntologyTriadSummary({ limit: 1000 })
|
|
95
|
+
: {
|
|
96
|
+
ontology_core: { entity_relation: [], business_rules: [], decision_strategy: [] },
|
|
97
|
+
ontology_core_ui: { ready: false, coverage_percent: 0, missing: ['entity_relation', 'business_rules', 'decision_strategy'], triads: {} },
|
|
98
|
+
counts: { entity_relation: 0, business_rules: 0, decision_strategy: 0 }
|
|
99
|
+
};
|
|
100
|
+
const recommendedSeed = resolveOntologySeedProfile(bundle.app_key || '')
|
|
101
|
+
|| resolveOntologySeedProfile('customer-order-demo')
|
|
102
|
+
|| (listOntologySeedProfiles()[0] ? { profile: listOntologySeedProfiles()[0].profile, label: listOntologySeedProfiles()[0].label } : null);
|
|
103
|
+
const starterSeed = triad.ontology_core_ui.ready === true
|
|
104
|
+
? null
|
|
105
|
+
: {
|
|
106
|
+
recommended_profile: recommendedSeed ? recommendedSeed.profile : null,
|
|
107
|
+
recommended_label: recommendedSeed ? recommendedSeed.label : null,
|
|
108
|
+
recommended_command: recommendedSeed
|
|
109
|
+
? `sce ontology seed apply --profile ${recommendedSeed.profile} --json`
|
|
110
|
+
: null
|
|
111
|
+
};
|
|
112
|
+
return {
|
|
113
|
+
mode: 'ontology-home',
|
|
114
|
+
query: {
|
|
115
|
+
app_id: bundle.app_id || null
|
|
116
|
+
},
|
|
117
|
+
summary: {
|
|
118
|
+
app_name: bundle.app_name || null,
|
|
119
|
+
ontology_version: ontologyBundle.ontology_version || null,
|
|
120
|
+
template_version: ontologyBundle.template_version || null,
|
|
121
|
+
triad_status: ontologyBundle.triad_status || null,
|
|
122
|
+
publish_readiness: ontologyBundle.publish_readiness || null,
|
|
123
|
+
triad_ready: triad.ontology_core_ui.ready === true,
|
|
124
|
+
triad_coverage_percent: triad.ontology_core_ui.coverage_percent
|
|
125
|
+
},
|
|
126
|
+
relations: {
|
|
127
|
+
ontology_bundle_id: bundle.ontology_bundle_id || null,
|
|
128
|
+
engineering_project_id: bundle.engineering_project_id || null,
|
|
129
|
+
runtime_release_id: bundle.runtime_release_id || null
|
|
130
|
+
},
|
|
131
|
+
items: [],
|
|
132
|
+
ontology_core: triad.ontology_core,
|
|
133
|
+
ontology_core_ui: triad.ontology_core_ui,
|
|
134
|
+
starter_seed: starterSeed,
|
|
135
|
+
view_model: {
|
|
136
|
+
projection: 'ontology',
|
|
137
|
+
ontology_bundle_id: ontologyBundle.ontology_bundle_id || null,
|
|
138
|
+
triad_status: ontologyBundle.triad_status || null,
|
|
139
|
+
template_source: ontologyBundle.template_source || null,
|
|
140
|
+
capability_count: Array.isArray(ontologyBundle.capability_set) ? ontologyBundle.capability_set.length : 0,
|
|
141
|
+
summary: ontologyBundle.summary || {},
|
|
142
|
+
ontology_counts: triad.counts,
|
|
143
|
+
triad_summary: triad.ontology_core_ui,
|
|
144
|
+
starter_seed: starterSeed
|
|
145
|
+
},
|
|
146
|
+
mb_status: ontologyBundle.publish_readiness || ontologyBundle.triad_status || (triad.ontology_core_ui.ready ? 'ready' : 'partial') || bundle.status || 'unknown'
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async function buildEngineeringHome(graph = {}, dependencies = {}) {
|
|
151
|
+
const bundle = graph.bundle || {};
|
|
152
|
+
const engineeringProject = graph.engineering_project || {};
|
|
153
|
+
const sceneBindings = Array.isArray(graph.scene_bindings) ? graph.scene_bindings : [];
|
|
154
|
+
const store = dependencies.store;
|
|
155
|
+
const [requirements, tracking, plans, changes, issues, resources, logs, backups, switches] = store
|
|
156
|
+
? await Promise.all([
|
|
157
|
+
store.listPmRequirements({ limit: 1000 }),
|
|
158
|
+
store.listPmTracking({ limit: 1000 }),
|
|
159
|
+
store.listPmPlans({ limit: 1000 }),
|
|
160
|
+
store.listPmChanges({ limit: 1000 }),
|
|
161
|
+
store.listPmIssues({ limit: 1000 }),
|
|
162
|
+
store.listAssuranceResourceSnapshots({ limit: 1000 }),
|
|
163
|
+
store.listAssuranceLogViews({ limit: 1000 }),
|
|
164
|
+
store.listAssuranceBackupRecords({ limit: 1000 }),
|
|
165
|
+
store.listAssuranceConfigSwitches({ limit: 1000 })
|
|
166
|
+
])
|
|
167
|
+
: [[], [], [], [], [], [], [], [], []];
|
|
168
|
+
return {
|
|
169
|
+
mode: 'engineering-home',
|
|
170
|
+
query: {
|
|
171
|
+
app_id: bundle.app_id || null
|
|
172
|
+
},
|
|
173
|
+
summary: {
|
|
174
|
+
app_name: bundle.app_name || null,
|
|
175
|
+
runtime_version: graph.runtime_release && graph.runtime_release.runtime_version ? graph.runtime_release.runtime_version : null,
|
|
176
|
+
code_version: engineeringProject.code_version || null,
|
|
177
|
+
current_branch: engineeringProject.current_branch || null,
|
|
178
|
+
dirty_state: engineeringProject.dirty_state === true,
|
|
179
|
+
scene_count: sceneBindings.length,
|
|
180
|
+
requirement_count: Array.isArray(requirements) ? requirements.length : 0,
|
|
181
|
+
issue_count: Array.isArray(issues) ? issues.length : 0,
|
|
182
|
+
plan_count: Array.isArray(plans) ? plans.length : 0,
|
|
183
|
+
assurance_resource_count: Array.isArray(resources) ? resources.length : 0
|
|
184
|
+
},
|
|
185
|
+
relations: {
|
|
186
|
+
engineering_project_id: bundle.engineering_project_id || null,
|
|
187
|
+
ontology_bundle_id: bundle.ontology_bundle_id || null,
|
|
188
|
+
runtime_release_id: bundle.runtime_release_id || null,
|
|
189
|
+
default_scene_id: bundle.default_scene_id || null
|
|
190
|
+
},
|
|
191
|
+
items: [],
|
|
192
|
+
view_model: {
|
|
193
|
+
projection: 'engineering',
|
|
194
|
+
primary_sections: ['source', 'timeline', 'diff', 'delivery', 'capability', 'assurance'],
|
|
195
|
+
project_name: engineeringProject.project_name || bundle.app_name || null,
|
|
196
|
+
repo_url: engineeringProject.repo_url || null,
|
|
197
|
+
workspace_path: engineeringProject.workspace_path || null,
|
|
198
|
+
default_scene_id: bundle.default_scene_id || null,
|
|
199
|
+
delivery_summary: {
|
|
200
|
+
requirements: Array.isArray(requirements) ? requirements.length : 0,
|
|
201
|
+
tracking: Array.isArray(tracking) ? tracking.length : 0,
|
|
202
|
+
plans: Array.isArray(plans) ? plans.length : 0,
|
|
203
|
+
changes: Array.isArray(changes) ? changes.length : 0,
|
|
204
|
+
issues: Array.isArray(issues) ? issues.length : 0
|
|
205
|
+
},
|
|
206
|
+
assurance_summary: {
|
|
207
|
+
resources: Array.isArray(resources) ? resources.length : 0,
|
|
208
|
+
logs: Array.isArray(logs) ? logs.length : 0,
|
|
209
|
+
backups: Array.isArray(backups) ? backups.length : 0,
|
|
210
|
+
config_switches: Array.isArray(switches) ? switches.length : 0
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
mb_status: engineeringProject.dirty_state === true ? 'dirty' : (bundle.status || 'unknown')
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function printPayload(payload, options = {}, title = 'Mode Home') {
|
|
218
|
+
if (options.json) {
|
|
219
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
console.log(chalk.blue(title));
|
|
223
|
+
if (payload.mode) {
|
|
224
|
+
console.log(` Mode: ${payload.mode}`);
|
|
225
|
+
}
|
|
226
|
+
if (payload.summary && typeof payload.summary === 'object') {
|
|
227
|
+
for (const [key, value] of Object.entries(payload.summary)) {
|
|
228
|
+
console.log(` ${key}: ${value}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function runModeHomeCommand(projection, options = {}, dependencies = {}) {
|
|
234
|
+
const appRef = normalizeString(options.app || options.appRef);
|
|
235
|
+
if (!appRef) {
|
|
236
|
+
throw new Error('--app is required');
|
|
237
|
+
}
|
|
238
|
+
const store = createStore(dependencies);
|
|
239
|
+
const useCache = options.cache !== false;
|
|
240
|
+
const cacheTtlSeconds = normalizePositiveInteger(options.cacheTtlSeconds, 5, 3600);
|
|
241
|
+
|
|
242
|
+
if (useCache) {
|
|
243
|
+
const cached = await store.getAppBundleProjectionCache(appRef, projection);
|
|
244
|
+
if (cached && isFreshProjectionCache(cached, cacheTtlSeconds)) {
|
|
245
|
+
const payload = cached.payload && typeof cached.payload === 'object' ? { ...cached.payload } : {};
|
|
246
|
+
payload.cache = {
|
|
247
|
+
hit: true,
|
|
248
|
+
generated_at: cached.generated_at,
|
|
249
|
+
ttl_seconds: cacheTtlSeconds
|
|
250
|
+
};
|
|
251
|
+
printPayload(payload, options, `${projection} home`);
|
|
252
|
+
return payload;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const graph = await store.getAppBundleGraph(appRef);
|
|
257
|
+
if (!graph) {
|
|
258
|
+
throw new Error(`app bundle not found: ${appRef}`);
|
|
259
|
+
}
|
|
260
|
+
let payload;
|
|
261
|
+
if (projection === 'application') {
|
|
262
|
+
payload = await buildApplicationHome(graph, { store });
|
|
263
|
+
} else if (projection === 'ontology') {
|
|
264
|
+
payload = await buildOntologyHome(graph, { store });
|
|
265
|
+
} else {
|
|
266
|
+
payload = await buildEngineeringHome(graph, { store });
|
|
267
|
+
}
|
|
268
|
+
payload.cache = {
|
|
269
|
+
hit: false,
|
|
270
|
+
ttl_seconds: cacheTtlSeconds
|
|
271
|
+
};
|
|
272
|
+
if (useCache && graph.bundle && graph.bundle.app_id) {
|
|
273
|
+
await store.saveAppBundleProjectionCache(
|
|
274
|
+
graph.bundle.app_id,
|
|
275
|
+
projection,
|
|
276
|
+
payload,
|
|
277
|
+
graph.bundle.updated_at || null
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
printPayload(payload, options, `${projection} home`);
|
|
281
|
+
return payload;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function safeRun(handler, options = {}, context = 'mode command') {
|
|
285
|
+
Promise.resolve(handler(options))
|
|
286
|
+
.catch((error) => {
|
|
287
|
+
if (options.json) {
|
|
288
|
+
console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
|
|
289
|
+
} else {
|
|
290
|
+
console.error(chalk.red(`${context} failed:`), error.message);
|
|
291
|
+
}
|
|
292
|
+
process.exitCode = 1;
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function registerModeCommands(program) {
|
|
297
|
+
const mode = program
|
|
298
|
+
.command('mode')
|
|
299
|
+
.description('Resolve MagicBall mode projections from SCE app bundle state');
|
|
300
|
+
|
|
301
|
+
['application', 'ontology', 'engineering'].forEach((projection) => {
|
|
302
|
+
const projectionCommand = mode
|
|
303
|
+
.command(projection)
|
|
304
|
+
.description(`Resolve ${projection} mode projection`);
|
|
305
|
+
|
|
306
|
+
projectionCommand
|
|
307
|
+
.command('home')
|
|
308
|
+
.description(`Build ${projection} mode home projection for one app bundle`)
|
|
309
|
+
.requiredOption('--app <app-id-or-key>', 'App id or app key')
|
|
310
|
+
.option('--json', 'Print machine-readable JSON output')
|
|
311
|
+
.action((options) => safeRun((runtimeOptions) => runModeHomeCommand(projection, runtimeOptions), options, `mode ${projection} home`));
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
module.exports = {
|
|
316
|
+
buildApplicationHome,
|
|
317
|
+
buildOntologyHome,
|
|
318
|
+
buildEngineeringHome,
|
|
319
|
+
runModeHomeCommand,
|
|
320
|
+
registerModeCommands
|
|
321
|
+
};
|