scene-capability-engine 3.6.64 → 3.6.67
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 +26 -0
- package/README.md +17 -6
- package/README.zh.md +18 -6
- package/bin/scene-capability-engine.js +4 -0
- package/docs/README.md +2 -2
- package/docs/command-reference.md +385 -8
- package/docs/document-governance.md +3 -2
- package/docs/integration-modes.md +62 -478
- package/docs/integration-philosophy.md +56 -263
- package/docs/magicball-cli-invocation-examples.md +1 -0
- package/docs/magicball-project-portfolio-contract.md +125 -4
- package/docs/project-management/README.md +14 -0
- package/docs/project-management/assurance/backup.md +3 -0
- package/docs/project-management/assurance/config.md +3 -0
- package/docs/project-management/assurance/evidence/README.md +3 -0
- package/docs/project-management/assurance/incidents/README.md +3 -0
- package/docs/project-management/assurance/logs.md +3 -0
- package/docs/project-management/assurance/overview.md +3 -0
- package/docs/project-management/assurance/recovery/README.md +3 -0
- package/docs/project-management/assurance/resource.md +3 -0
- package/docs/project-management/assurance/runbooks/README.md +3 -0
- package/docs/project-management/delivery/acceptance/README.md +3 -0
- package/docs/project-management/delivery/acceptance/evidence/README.md +3 -0
- package/docs/project-management/delivery/acceptance/exceptions/README.md +3 -0
- package/docs/project-management/delivery/acceptance/reports/README.md +3 -0
- package/docs/project-management/delivery/documents/changes.md +3 -0
- package/docs/project-management/delivery/documents/issues.md +3 -0
- package/docs/project-management/delivery/documents/overview.md +3 -0
- package/docs/project-management/delivery/documents/planning.md +3 -0
- package/docs/project-management/delivery/documents/requirements.md +3 -0
- package/docs/project-management/delivery/documents/tracking.md +3 -0
- package/docs/project-management/delivery/handoffs/README.md +3 -0
- package/docs/project-management/delivery/handoffs/evidence/README.md +3 -0
- package/docs/project-management/delivery/handoffs/records/README.md +3 -0
- package/docs/project-management/delivery/overview.md +10 -0
- package/docs/project-management/delivery/releases/README.md +3 -0
- package/docs/project-management/delivery/releases/baselines/README.md +3 -0
- package/docs/project-management/delivery/releases/evidence/README.md +3 -0
- package/docs/project-management/delivery/tables/changes.md +3 -0
- package/docs/project-management/delivery/tables/issues.md +3 -0
- package/docs/project-management/delivery/tables/planning.md +3 -0
- package/docs/project-management/delivery/tables/requirements.md +3 -0
- package/docs/project-management/delivery/tables/tracking.md +3 -0
- package/docs/project-management/environment/agent-discovery.md +3 -0
- package/docs/project-management/environment/development.md +3 -0
- package/docs/project-management/environment/overview.md +10 -0
- package/docs/project-management/environment/testing.md +3 -0
- package/docs/project-management/environment/version-alignment.md +3 -0
- package/docs/quick-start-with-ai-tools.md +68 -308
- package/docs/releases/README.md +3 -0
- package/docs/releases/v3.6.65.md +25 -0
- package/docs/releases/v3.6.66.md +23 -0
- package/docs/releases/v3.6.67.md +23 -0
- package/docs/steering-governance.md +64 -2
- package/docs/zh/README.md +2 -2
- package/docs/zh/releases/README.md +3 -0
- package/docs/zh/releases/v3.6.65.md +25 -0
- package/docs/zh/releases/v3.6.66.md +23 -0
- package/docs/zh/releases/v3.6.67.md +23 -0
- package/lib/commands/adopt.js +24 -0
- package/lib/commands/native.js +158 -0
- package/lib/commands/project.js +96 -0
- package/lib/commands/semantic.js +1459 -0
- package/lib/commands/session.js +74 -3
- package/lib/commands/spec-bootstrap.js +10 -1
- package/lib/commands/spec-gate.js +10 -1
- package/lib/commands/spec-pipeline.js +10 -1
- package/lib/commands/studio.js +405 -30
- package/lib/commands/task.js +141 -7
- package/lib/governance/supreme-principles.js +530 -0
- package/lib/problem/problem-evaluator.js +4 -0
- package/lib/project/candidate-inspection-service.js +24 -1
- package/lib/project/portfolio-projection-service.js +315 -5
- package/lib/project/project-channel-output.js +94 -0
- package/lib/project/project-channel-projection.js +181 -0
- package/lib/project/root-onboarding-service.js +107 -7
- package/lib/project/semantic-shared-source-projection.js +150 -0
- package/lib/project/supervision-action-model.js +277 -0
- package/lib/project/supervision-projection-service.js +305 -5
- package/lib/project/target-resolution-service.js +70 -5
- package/lib/project/visibility-policy.js +93 -0
- package/lib/runtime/multi-spec-scene-session.js +8 -1
- package/lib/runtime/project-channel-context-store.js +387 -0
- package/lib/runtime/project-channel-context.js +406 -0
- package/lib/runtime/scene-session-binding.js +46 -0
- package/lib/runtime/session-store.js +186 -0
- package/lib/runtime/steering-contract.js +7 -1
- package/lib/semantic/archive-report.js +283 -0
- package/lib/semantic/archive-routing.js +67 -0
- package/lib/semantic/backflow-report.js +245 -0
- package/lib/semantic/capability-contract.js +30 -0
- package/lib/semantic/delta-export.js +145 -0
- package/lib/semantic/interaction-observer.js +254 -0
- package/lib/semantic/kernel-loader.js +881 -0
- package/lib/semantic/native-runtime.js +359 -0
- package/lib/semantic/progress-ledger.js +433 -0
- package/lib/semantic/replay-evaluator.js +382 -0
- package/lib/semantic/shared-publication.js +592 -0
- package/lib/semantic/shared-source-config.js +183 -0
- package/lib/semantic/shared-source-connect.js +139 -0
- package/lib/semantic/shared-source-discovery.js +98 -0
- package/lib/semantic/shared-sync-export.js +413 -0
- package/lib/semantic/shared-sync-intake.js +592 -0
- package/lib/semantic/shared-sync-merge.js +547 -0
- package/lib/semantic/shared-sync-release.js +463 -0
- package/lib/semantic/supreme-intent-report.js +300 -0
- package/lib/state/sce-state-store.js +1360 -0
- package/lib/steering/context-sync-manager.js +276 -25
- package/lib/studio/spec-intake-governor.js +39 -3
- package/lib/studio/task-envelope.js +35 -2
- package/lib/workspace/takeover-baseline.js +342 -83
- package/package.json +7 -2
- package/scripts/agent-governance-baseline-audit.js +395 -0
- package/scripts/clarification-first-audit.js +9 -9
- package/scripts/deprecated-entry-audit.js +240 -0
- package/scripts/release-doc-version-audit.js +24 -0
- package/scripts/release-posture-report.js +262 -0
- package/template/.sce/README.md +62 -228
- package/template/.sce/config/semantic-shared-sources.json +5 -0
- package/template/.sce/config/supreme-principles-policy.json +105 -0
- package/template/.sce/config/takeover-baseline.json +7 -0
- package/template/.sce/steering/CORE_PRINCIPLES.md +23 -63
- package/template/.sce/steering/CURRENT_CONTEXT.md +4 -0
- package/template/.sce/steering/RULES_GUIDE.md +17 -9
- package/template/README.md +32 -96
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const {
|
|
5
|
+
SHARED_LIBRARY_ROOT,
|
|
6
|
+
resolveSharedLibraryEntryRelativePath,
|
|
7
|
+
resolveSharedLibraryIndexRelativePath
|
|
8
|
+
} = require('./shared-publication');
|
|
9
|
+
|
|
10
|
+
const SUPPORTED_TARGET_LIBRARIES = [
|
|
11
|
+
'experience-library',
|
|
12
|
+
'ontology-capability-library',
|
|
13
|
+
'application-library'
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const SEMANTIC_SHARED_SYNC_BUNDLE_API_VERSION = 'sce.semantic.shared-sync.bundle/v0.1';
|
|
17
|
+
const SEMANTIC_SHARED_SYNC_INDEX_API_VERSION = 'sce.semantic.shared-sync.index/v0.1';
|
|
18
|
+
const SEMANTIC_SHARED_SYNC_SHARD_API_VERSION = 'sce.semantic.shared-sync.shard/v0.1';
|
|
19
|
+
const SEMANTIC_SHARED_SYNC_RECEIPT_API_VERSION = 'sce.semantic.shared-sync.receipt/v0.1';
|
|
20
|
+
|
|
21
|
+
function normalizeString(value) {
|
|
22
|
+
if (typeof value !== 'string') {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
return value.trim();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function normalizeInteger(value, fallback = 0) {
|
|
29
|
+
const parsed = Number.parseInt(`${value}`, 10);
|
|
30
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
31
|
+
return fallback;
|
|
32
|
+
}
|
|
33
|
+
return parsed;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function readJsonIfExists(fileSystem, absolutePath, fallback) {
|
|
37
|
+
if (!await fileSystem.pathExists(absolutePath)) {
|
|
38
|
+
return fallback;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
return await fileSystem.readJson(absolutePath);
|
|
42
|
+
} catch (_error) {
|
|
43
|
+
return fallback;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function toProjectRelative(projectPath, targetPath) {
|
|
48
|
+
return path.relative(projectPath, targetPath).replace(/\\/g, '/');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function hashJson(value) {
|
|
52
|
+
return crypto
|
|
53
|
+
.createHash('sha256')
|
|
54
|
+
.update(JSON.stringify(value))
|
|
55
|
+
.digest('hex');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function buildSemanticSharedSyncExportId() {
|
|
59
|
+
return `sem-sync-${Date.now()}-${crypto.randomBytes(3).toString('hex')}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function resolveSemanticSharedSyncBaseDir(specId = '') {
|
|
63
|
+
const normalizedSpecId = normalizeString(specId);
|
|
64
|
+
if (!normalizedSpecId) {
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
return `.sce/specs/${normalizedSpecId}/sync/semantic-shared`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function resolveDefaultSemanticSharedSyncBundleOutFile(specId = '') {
|
|
71
|
+
const baseDir = resolveSemanticSharedSyncBaseDir(specId);
|
|
72
|
+
if (!baseDir) {
|
|
73
|
+
return '';
|
|
74
|
+
}
|
|
75
|
+
return `${baseDir}/latest.bundle.json`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function resolveDefaultSemanticSharedSyncIndexOutFile(specId = '') {
|
|
79
|
+
const baseDir = resolveSemanticSharedSyncBaseDir(specId);
|
|
80
|
+
if (!baseDir) {
|
|
81
|
+
return '';
|
|
82
|
+
}
|
|
83
|
+
return `${baseDir}/latest.index.json`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function resolveDefaultSemanticSharedSyncReceiptOutFile(specId = '') {
|
|
87
|
+
const baseDir = resolveSemanticSharedSyncBaseDir(specId);
|
|
88
|
+
if (!baseDir) {
|
|
89
|
+
return '';
|
|
90
|
+
}
|
|
91
|
+
return `${baseDir}/latest.receipt.json`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function resolveDefaultSemanticSharedSyncShardOutFile(specId = '', targetLibrary = '') {
|
|
95
|
+
const baseDir = resolveSemanticSharedSyncBaseDir(specId);
|
|
96
|
+
const normalizedLibrary = normalizeString(targetLibrary);
|
|
97
|
+
if (!baseDir || !normalizedLibrary) {
|
|
98
|
+
return '';
|
|
99
|
+
}
|
|
100
|
+
return `${baseDir}/shards/${normalizedLibrary}.json`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function deriveSiblingArtifactRelativePaths(bundleOutFile = '') {
|
|
104
|
+
const normalized = normalizeString(bundleOutFile);
|
|
105
|
+
if (!normalized) {
|
|
106
|
+
return {
|
|
107
|
+
indexFile: '',
|
|
108
|
+
receiptFile: '',
|
|
109
|
+
shardDir: ''
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const parsed = path.posix.parse(normalized.replace(/\\/g, '/'));
|
|
113
|
+
const stem = parsed.name.endsWith('.bundle')
|
|
114
|
+
? parsed.name.slice(0, -'.bundle'.length)
|
|
115
|
+
: parsed.name;
|
|
116
|
+
return {
|
|
117
|
+
indexFile: path.posix.join(parsed.dir, `${stem}.index${parsed.ext || '.json'}`),
|
|
118
|
+
receiptFile: path.posix.join(parsed.dir, `${stem}.receipt${parsed.ext || '.json'}`),
|
|
119
|
+
shardDir: path.posix.join(parsed.dir, 'shards')
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function inferSpecIdFromEntries(entries = [], fallback = '') {
|
|
124
|
+
const requestedSpecId = normalizeString(fallback);
|
|
125
|
+
if (requestedSpecId) {
|
|
126
|
+
return requestedSpecId;
|
|
127
|
+
}
|
|
128
|
+
const candidates = Array.from(new Set(entries
|
|
129
|
+
.map((entry) => normalizeString(entry && entry.spec_id))
|
|
130
|
+
.filter(Boolean)));
|
|
131
|
+
return candidates.length === 1 ? candidates[0] : '';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function exportSemanticSharedSyncBundle(options = {}, dependencies = {}) {
|
|
135
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
136
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
137
|
+
const projectId = normalizeString(options.project_id || options.projectId);
|
|
138
|
+
const specFilter = normalizeString(options.spec_id || options.specId);
|
|
139
|
+
const lessonId = normalizeString(options.lesson_id || options.lessonId);
|
|
140
|
+
const capabilityId = normalizeString(options.capability_id || options.capabilityId);
|
|
141
|
+
const targetLibraryFilter = normalizeString(options.target_library || options.targetLibrary);
|
|
142
|
+
const limit = normalizeInteger(options.limit, 100);
|
|
143
|
+
const generatedAt = new Date().toISOString();
|
|
144
|
+
const exportId = buildSemanticSharedSyncExportId();
|
|
145
|
+
|
|
146
|
+
const rootIndexRelativePath = `${SHARED_LIBRARY_ROOT}/index.json`;
|
|
147
|
+
const rootIndexAbsolutePath = path.join(projectPath, rootIndexRelativePath);
|
|
148
|
+
const rootIndex = await readJsonIfExists(fileSystem, rootIndexAbsolutePath, {
|
|
149
|
+
libraries: []
|
|
150
|
+
});
|
|
151
|
+
const indexedLibraries = Array.isArray(rootIndex.libraries)
|
|
152
|
+
? rootIndex.libraries
|
|
153
|
+
.map((item) => normalizeString(item && item.target_library))
|
|
154
|
+
.filter(Boolean)
|
|
155
|
+
: [];
|
|
156
|
+
const librariesToScan = targetLibraryFilter
|
|
157
|
+
? [targetLibraryFilter]
|
|
158
|
+
: Array.from(new Set([
|
|
159
|
+
...SUPPORTED_TARGET_LIBRARIES,
|
|
160
|
+
...indexedLibraries
|
|
161
|
+
]));
|
|
162
|
+
|
|
163
|
+
const candidateRefs = [];
|
|
164
|
+
for (const targetLibrary of librariesToScan) {
|
|
165
|
+
const sourceIndexFile = resolveSharedLibraryIndexRelativePath(targetLibrary);
|
|
166
|
+
const sourceIndexAbsolutePath = path.join(projectPath, sourceIndexFile);
|
|
167
|
+
const sourceIndex = await readJsonIfExists(fileSystem, sourceIndexAbsolutePath, {
|
|
168
|
+
entries: []
|
|
169
|
+
});
|
|
170
|
+
const entries = Array.isArray(sourceIndex.entries) ? sourceIndex.entries : [];
|
|
171
|
+
for (const item of entries) {
|
|
172
|
+
if (projectId && normalizeString(item.project_id) !== projectId) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (specFilter && normalizeString(item.spec_id) !== specFilter) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (lessonId && normalizeString(item.lesson_id) !== lessonId) {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (capabilityId && normalizeString(item.capability_id) !== capabilityId) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
candidateRefs.push({
|
|
185
|
+
target_library: targetLibrary,
|
|
186
|
+
source_index_file: sourceIndexFile,
|
|
187
|
+
capability_id: normalizeString(item.capability_id),
|
|
188
|
+
lesson_id: normalizeString(item.lesson_id),
|
|
189
|
+
project_id: normalizeString(item.project_id),
|
|
190
|
+
scene_id: normalizeString(item.scene_id),
|
|
191
|
+
spec_id: normalizeString(item.spec_id),
|
|
192
|
+
published_at: normalizeString(item.published_at),
|
|
193
|
+
entry_file: normalizeString(item.entry_file)
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
candidateRefs.sort((left, right) => {
|
|
199
|
+
const leftTime = Date.parse(left.published_at || '') || 0;
|
|
200
|
+
const rightTime = Date.parse(right.published_at || '') || 0;
|
|
201
|
+
return rightTime - leftTime;
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const limitedRefs = limit > 0
|
|
205
|
+
? candidateRefs.slice(0, limit)
|
|
206
|
+
: candidateRefs;
|
|
207
|
+
const exportedEntries = [];
|
|
208
|
+
const blocked = [];
|
|
209
|
+
|
|
210
|
+
for (const reference of limitedRefs) {
|
|
211
|
+
const entryFile = normalizeString(reference.entry_file)
|
|
212
|
+
|| resolveSharedLibraryEntryRelativePath(reference.target_library, reference.capability_id);
|
|
213
|
+
if (!entryFile) {
|
|
214
|
+
blocked.push({
|
|
215
|
+
capability_id: reference.capability_id || null,
|
|
216
|
+
lesson_id: reference.lesson_id || null,
|
|
217
|
+
target_library: reference.target_library || null,
|
|
218
|
+
reason: 'missing-entry-file'
|
|
219
|
+
});
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
const absoluteEntryPath = path.join(projectPath, entryFile);
|
|
223
|
+
const entry = await readJsonIfExists(fileSystem, absoluteEntryPath, null);
|
|
224
|
+
if (!entry) {
|
|
225
|
+
blocked.push({
|
|
226
|
+
capability_id: reference.capability_id || null,
|
|
227
|
+
lesson_id: reference.lesson_id || null,
|
|
228
|
+
target_library: reference.target_library || null,
|
|
229
|
+
reason: 'entry-not-found',
|
|
230
|
+
entry_file: entryFile
|
|
231
|
+
});
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
exportedEntries.push({
|
|
235
|
+
...entry,
|
|
236
|
+
source_entry_file: entryFile,
|
|
237
|
+
source_index_file: reference.source_index_file
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const resolvedSpecId = inferSpecIdFromEntries(exportedEntries, specFilter);
|
|
242
|
+
let bundleOutFile = normalizeString(options.out_file || options.outFile);
|
|
243
|
+
if (!bundleOutFile && resolvedSpecId) {
|
|
244
|
+
bundleOutFile = resolveDefaultSemanticSharedSyncBundleOutFile(resolvedSpecId);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let indexOutFile = '';
|
|
248
|
+
let receiptOutFile = '';
|
|
249
|
+
let shardRootDir = '';
|
|
250
|
+
if (bundleOutFile) {
|
|
251
|
+
const siblings = deriveSiblingArtifactRelativePaths(bundleOutFile);
|
|
252
|
+
indexOutFile = siblings.indexFile;
|
|
253
|
+
receiptOutFile = siblings.receiptFile;
|
|
254
|
+
shardRootDir = siblings.shardDir;
|
|
255
|
+
} else if (resolvedSpecId) {
|
|
256
|
+
indexOutFile = resolveDefaultSemanticSharedSyncIndexOutFile(resolvedSpecId);
|
|
257
|
+
receiptOutFile = resolveDefaultSemanticSharedSyncReceiptOutFile(resolvedSpecId);
|
|
258
|
+
shardRootDir = `${resolveSemanticSharedSyncBaseDir(resolvedSpecId)}/shards`;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const entriesByLibrary = new Map();
|
|
262
|
+
for (const entry of exportedEntries) {
|
|
263
|
+
const targetLibrary = normalizeString(entry.target_library);
|
|
264
|
+
if (!targetLibrary) {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (!entriesByLibrary.has(targetLibrary)) {
|
|
268
|
+
entriesByLibrary.set(targetLibrary, []);
|
|
269
|
+
}
|
|
270
|
+
entriesByLibrary.get(targetLibrary).push(entry);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const librarySummaries = [];
|
|
274
|
+
const shardIndex = {};
|
|
275
|
+
for (const [targetLibrary, entries] of entriesByLibrary.entries()) {
|
|
276
|
+
const shardEntries = [...entries]
|
|
277
|
+
.sort((left, right) => {
|
|
278
|
+
const leftTime = Date.parse(left.published_at || '') || 0;
|
|
279
|
+
const rightTime = Date.parse(right.published_at || '') || 0;
|
|
280
|
+
return rightTime - leftTime;
|
|
281
|
+
});
|
|
282
|
+
const shardPayload = {
|
|
283
|
+
api_version: SEMANTIC_SHARED_SYNC_SHARD_API_VERSION,
|
|
284
|
+
generated_at: generatedAt,
|
|
285
|
+
export_id: exportId,
|
|
286
|
+
project_id: projectId || null,
|
|
287
|
+
spec_id: resolvedSpecId || null,
|
|
288
|
+
target_library: targetLibrary,
|
|
289
|
+
mirror_root: SHARED_LIBRARY_ROOT,
|
|
290
|
+
source_index_file: resolveSharedLibraryIndexRelativePath(targetLibrary),
|
|
291
|
+
total_entries: shardEntries.length,
|
|
292
|
+
entries: shardEntries
|
|
293
|
+
};
|
|
294
|
+
const contentSha256 = hashJson(shardPayload);
|
|
295
|
+
const shardFile = shardRootDir
|
|
296
|
+
? path.posix.join(shardRootDir.replace(/\\/g, '/'), `${targetLibrary}.json`)
|
|
297
|
+
: '';
|
|
298
|
+
librarySummaries.push({
|
|
299
|
+
target_library: targetLibrary,
|
|
300
|
+
source_index_file: shardPayload.source_index_file,
|
|
301
|
+
shard_file: shardFile || null,
|
|
302
|
+
entry_count: shardEntries.length,
|
|
303
|
+
latest_published_at: normalizeString(shardEntries[0] && shardEntries[0].published_at) || null,
|
|
304
|
+
content_sha256: contentSha256
|
|
305
|
+
});
|
|
306
|
+
shardIndex[targetLibrary] = {
|
|
307
|
+
shard_file: shardFile || null,
|
|
308
|
+
source_index_file: shardPayload.source_index_file,
|
|
309
|
+
entry_count: shardEntries.length,
|
|
310
|
+
latest_published_at: normalizeString(shardEntries[0] && shardEntries[0].published_at) || null,
|
|
311
|
+
content_sha256: contentSha256
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
if (shardFile) {
|
|
315
|
+
const absoluteShardPath = path.join(projectPath, shardFile);
|
|
316
|
+
await fileSystem.ensureDir(path.dirname(absoluteShardPath));
|
|
317
|
+
await fileSystem.writeJson(absoluteShardPath, shardPayload, { spaces: 2 });
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
librarySummaries.sort((left, right) => `${left.target_library}`.localeCompare(`${right.target_library}`));
|
|
322
|
+
const success = blocked.length === 0;
|
|
323
|
+
const bundlePayload = {
|
|
324
|
+
api_version: SEMANTIC_SHARED_SYNC_BUNDLE_API_VERSION,
|
|
325
|
+
mode: 'semantic-export-shared-sync',
|
|
326
|
+
success,
|
|
327
|
+
generated_at: generatedAt,
|
|
328
|
+
export_id: exportId,
|
|
329
|
+
project_id: projectId || null,
|
|
330
|
+
spec_id: resolvedSpecId || null,
|
|
331
|
+
mirror_root: SHARED_LIBRARY_ROOT,
|
|
332
|
+
source_root_index: rootIndexRelativePath,
|
|
333
|
+
filters: {
|
|
334
|
+
project_id: projectId || null,
|
|
335
|
+
spec_id: specFilter || null,
|
|
336
|
+
lesson_id: lessonId || null,
|
|
337
|
+
capability_id: capabilityId || null,
|
|
338
|
+
target_library: targetLibraryFilter || null,
|
|
339
|
+
limit
|
|
340
|
+
},
|
|
341
|
+
totals: {
|
|
342
|
+
libraries_scanned: librariesToScan.length,
|
|
343
|
+
libraries_exported: librarySummaries.length,
|
|
344
|
+
entries_matched: limitedRefs.length,
|
|
345
|
+
entries_exported: exportedEntries.length,
|
|
346
|
+
blocked: blocked.length
|
|
347
|
+
},
|
|
348
|
+
libraries: librarySummaries,
|
|
349
|
+
blocked
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
const indexPayload = {
|
|
353
|
+
api_version: SEMANTIC_SHARED_SYNC_INDEX_API_VERSION,
|
|
354
|
+
generated_at: generatedAt,
|
|
355
|
+
export_id: exportId,
|
|
356
|
+
project_id: projectId || null,
|
|
357
|
+
spec_id: resolvedSpecId || null,
|
|
358
|
+
bundle_file: bundleOutFile || null,
|
|
359
|
+
shard_count: librarySummaries.length,
|
|
360
|
+
shards: shardIndex
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const receiptPayload = {
|
|
364
|
+
api_version: SEMANTIC_SHARED_SYNC_RECEIPT_API_VERSION,
|
|
365
|
+
mode: 'semantic-export-shared-sync',
|
|
366
|
+
success,
|
|
367
|
+
generated_at: generatedAt,
|
|
368
|
+
export_id: exportId,
|
|
369
|
+
project_id: projectId || null,
|
|
370
|
+
spec_id: resolvedSpecId || null,
|
|
371
|
+
mirror_root: SHARED_LIBRARY_ROOT,
|
|
372
|
+
source_root_index: rootIndexRelativePath,
|
|
373
|
+
totals: bundlePayload.totals,
|
|
374
|
+
filters: bundlePayload.filters,
|
|
375
|
+
libraries: librarySummaries,
|
|
376
|
+
blocked
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
if (bundleOutFile) {
|
|
380
|
+
const absoluteBundlePath = path.join(projectPath, bundleOutFile);
|
|
381
|
+
await fileSystem.ensureDir(path.dirname(absoluteBundlePath));
|
|
382
|
+
await fileSystem.writeJson(absoluteBundlePath, bundlePayload, { spaces: 2 });
|
|
383
|
+
}
|
|
384
|
+
if (indexOutFile) {
|
|
385
|
+
const absoluteIndexPath = path.join(projectPath, indexOutFile);
|
|
386
|
+
await fileSystem.ensureDir(path.dirname(absoluteIndexPath));
|
|
387
|
+
await fileSystem.writeJson(absoluteIndexPath, indexPayload, { spaces: 2 });
|
|
388
|
+
}
|
|
389
|
+
if (receiptOutFile) {
|
|
390
|
+
const absoluteReceiptPath = path.join(projectPath, receiptOutFile);
|
|
391
|
+
await fileSystem.ensureDir(path.dirname(absoluteReceiptPath));
|
|
392
|
+
await fileSystem.writeJson(absoluteReceiptPath, receiptPayload, { spaces: 2 });
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return {
|
|
396
|
+
...receiptPayload,
|
|
397
|
+
out_file: bundleOutFile || null,
|
|
398
|
+
index_file: indexOutFile || null,
|
|
399
|
+
receipt_file: receiptOutFile || null
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
module.exports = {
|
|
404
|
+
SEMANTIC_SHARED_SYNC_BUNDLE_API_VERSION,
|
|
405
|
+
SEMANTIC_SHARED_SYNC_INDEX_API_VERSION,
|
|
406
|
+
SEMANTIC_SHARED_SYNC_SHARD_API_VERSION,
|
|
407
|
+
SEMANTIC_SHARED_SYNC_RECEIPT_API_VERSION,
|
|
408
|
+
resolveDefaultSemanticSharedSyncBundleOutFile,
|
|
409
|
+
resolveDefaultSemanticSharedSyncIndexOutFile,
|
|
410
|
+
resolveDefaultSemanticSharedSyncReceiptOutFile,
|
|
411
|
+
resolveDefaultSemanticSharedSyncShardOutFile,
|
|
412
|
+
exportSemanticSharedSyncBundle
|
|
413
|
+
};
|