@tiangong-lca/cli 0.0.6 → 0.0.7

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 (58) hide show
  1. package/README.md +73 -30
  2. package/dist/src/cli.js +912 -113
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/lib/dataset-local.js +231 -0
  5. package/dist/src/lib/dataset-local.js.map +1 -0
  6. package/dist/src/lib/dataset-references-rewrite.js +214 -0
  7. package/dist/src/lib/dataset-references-rewrite.js.map +1 -0
  8. package/dist/src/lib/dataset-validate.js +191 -0
  9. package/dist/src/lib/dataset-validate.js.map +1 -0
  10. package/dist/src/lib/flow-regen-product.js +2 -10
  11. package/dist/src/lib/flow-regen-product.js.map +1 -1
  12. package/dist/src/lib/flow-remediate.js +4 -8
  13. package/dist/src/lib/flow-remediate.js.map +1 -1
  14. package/dist/src/lib/lifecyclemodel-auto-build.js +11 -8
  15. package/dist/src/lib/lifecyclemodel-auto-build.js.map +1 -1
  16. package/dist/src/lib/lifecyclemodel-graph.js +248 -0
  17. package/dist/src/lib/lifecyclemodel-graph.js.map +1 -0
  18. package/dist/src/lib/lifecyclemodel-publish-build.js +1 -1
  19. package/dist/src/lib/lifecyclemodel-publish-build.js.map +1 -1
  20. package/dist/src/lib/lifecyclemodel-save-draft-run.js +245 -0
  21. package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -0
  22. package/dist/src/lib/lifecyclemodel-validate-build.js +1 -1
  23. package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
  24. package/dist/src/lib/process-auto-build.js +11 -8
  25. package/dist/src/lib/process-auto-build.js.map +1 -1
  26. package/dist/src/lib/process-batch-build.js +6 -3
  27. package/dist/src/lib/process-batch-build.js.map +1 -1
  28. package/dist/src/lib/process-dedup-review.js +870 -0
  29. package/dist/src/lib/process-dedup-review.js.map +1 -0
  30. package/dist/src/lib/process-payload-validation.js +50 -0
  31. package/dist/src/lib/process-payload-validation.js.map +1 -0
  32. package/dist/src/lib/process-publish-build.js +4 -6
  33. package/dist/src/lib/process-publish-build.js.map +1 -1
  34. package/dist/src/lib/process-refresh-references.js +1028 -0
  35. package/dist/src/lib/process-refresh-references.js.map +1 -0
  36. package/dist/src/lib/process-resume-build.js +4 -6
  37. package/dist/src/lib/process-resume-build.js.map +1 -1
  38. package/dist/src/lib/process-save-draft-run.js +31 -12
  39. package/dist/src/lib/process-save-draft-run.js.map +1 -1
  40. package/dist/src/lib/process-scope-statistics.js +859 -0
  41. package/dist/src/lib/process-scope-statistics.js.map +1 -0
  42. package/dist/src/lib/process-verify-rows.js +250 -0
  43. package/dist/src/lib/process-verify-rows.js.map +1 -0
  44. package/dist/src/lib/publish.js +1 -1
  45. package/dist/src/lib/publish.js.map +1 -1
  46. package/dist/src/lib/remote.js +4 -4
  47. package/dist/src/lib/remote.js.map +1 -1
  48. package/dist/src/lib/review-lifecyclemodel.js +2 -2
  49. package/dist/src/lib/review-lifecyclemodel.js.map +1 -1
  50. package/dist/src/lib/tidas-sdk-package-validator.js +28 -9
  51. package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
  52. package/dist/src/lib/tidas-sdk-validation.js +96 -0
  53. package/dist/src/lib/tidas-sdk-validation.js.map +1 -0
  54. package/dist/src/lib/user-api-key.js +1 -1
  55. package/dist/src/lib/user-api-key.js.map +1 -1
  56. package/package.json +4 -4
  57. /package/bin/{tiangong.d.ts → tiangong-lca.d.ts} +0 -0
  58. /package/bin/{tiangong.js → tiangong-lca.js} +0 -0
@@ -0,0 +1,248 @@
1
+ import path from 'node:path';
2
+ import { writeJsonArtifact, writeJsonLinesArtifact, writeTextArtifact } from './artifacts.js';
3
+ import { CliError } from './errors.js';
4
+ import { firstNonEmpty, isRecord, materializeDatasetRows, trimToken, } from './dataset-local.js';
5
+ import { deriveLifecyclemodelJsonTg } from './lifecyclemodel-bundle-save.js';
6
+ function normalizeFormat(value) {
7
+ const normalized = value?.trim().toLowerCase();
8
+ if (!normalized) {
9
+ return 'all';
10
+ }
11
+ if (normalized === 'json' ||
12
+ normalized === 'dot' ||
13
+ normalized === 'svg' ||
14
+ normalized === 'all') {
15
+ return normalized;
16
+ }
17
+ throw new CliError('Expected --format to be json, dot, svg, or all.', {
18
+ code: 'LIFECYCLEMODEL_GRAPH_FORMAT_INVALID',
19
+ exitCode: 2,
20
+ details: value,
21
+ });
22
+ }
23
+ function asArray(value) {
24
+ if (Array.isArray(value)) {
25
+ return value;
26
+ }
27
+ if (value === undefined || value === null) {
28
+ return [];
29
+ }
30
+ return [value];
31
+ }
32
+ function normalizeNodes(jsonTg) {
33
+ const xflow = isRecord(jsonTg.xflow) ? jsonTg.xflow : {};
34
+ return asArray(xflow.nodes)
35
+ .filter(isRecord)
36
+ .map((node, index) => ({
37
+ id: firstNonEmpty(node.id, `node-${index + 1}`),
38
+ x: typeof node.x === 'number' ? node.x : index * 320,
39
+ y: typeof node.y === 'number' ? node.y : 0,
40
+ width: typeof node.width === 'number' ? node.width : 260,
41
+ height: typeof node.height === 'number' ? node.height : 90,
42
+ data: isRecord(node.data) ? node.data : {},
43
+ }));
44
+ }
45
+ function normalizeEdges(jsonTg) {
46
+ const xflow = isRecord(jsonTg.xflow) ? jsonTg.xflow : {};
47
+ return asArray(xflow.edges)
48
+ .filter(isRecord)
49
+ .map((edge, index) => ({
50
+ id: firstNonEmpty(edge.id, `edge-${index + 1}`),
51
+ source: isRecord(edge.source) ? edge.source : {},
52
+ target: isRecord(edge.target) ? edge.target : {},
53
+ data: isRecord(edge.data) ? edge.data : {},
54
+ }));
55
+ }
56
+ function labelFromNode(node) {
57
+ const label = node.data.label;
58
+ if (typeof label === 'string') {
59
+ return label;
60
+ }
61
+ if (isRecord(label) && Array.isArray(label.baseName)) {
62
+ const first = label.baseName.find(isRecord);
63
+ const text = isRecord(first) ? trimToken(first['#text']) : null;
64
+ if (text) {
65
+ return text;
66
+ }
67
+ }
68
+ return firstNonEmpty(node.data.id, node.id);
69
+ }
70
+ function escapeDot(value) {
71
+ return value.replace(/\\/gu, '\\\\').replace(/"/gu, '\\"');
72
+ }
73
+ function escapeXml(value) {
74
+ return value
75
+ .replace(/&/gu, '&')
76
+ .replace(/</gu, '&lt;')
77
+ .replace(/>/gu, '&gt;')
78
+ .replace(/"/gu, '&quot;');
79
+ }
80
+ function buildDot(modelId, nodes, edges) {
81
+ const lines = ['digraph lifecyclemodel {', ' rankdir=LR;', ' node [shape=box];'];
82
+ if (modelId) {
83
+ lines.push(` label="${escapeDot(modelId)}";`);
84
+ }
85
+ nodes.forEach((node) => {
86
+ lines.push(` "${escapeDot(node.id)}" [label="${escapeDot(labelFromNode(node))}"];`);
87
+ });
88
+ edges.forEach((edge) => {
89
+ const source = firstNonEmpty(edge.source.cell, 'unknown-source');
90
+ const target = firstNonEmpty(edge.target.cell, 'unknown-target');
91
+ const connection = isRecord(edge.data.connection) ? edge.data.connection : {};
92
+ const outputExchange = isRecord(connection.outputExchange) ? connection.outputExchange : {};
93
+ const flowUuid = firstNonEmpty(outputExchange['@flowUUID'], edge.id);
94
+ lines.push(` "${escapeDot(source)}" -> "${escapeDot(target)}" [label="${escapeDot(flowUuid ?? '')}"];`);
95
+ });
96
+ lines.push('}');
97
+ return `${lines.join('\n')}\n`;
98
+ }
99
+ function buildSvg(nodes, edges) {
100
+ const padding = 32;
101
+ const maxX = Math.max(...nodes.map((node) => node.x + node.width), 320);
102
+ const maxY = Math.max(...nodes.map((node) => node.y + node.height), 180);
103
+ const nodeById = new Map(nodes.map((node) => [node.id, node]));
104
+ const lines = [
105
+ `<svg xmlns="http://www.w3.org/2000/svg" width="${maxX + padding * 2}" height="${maxY + padding * 2}" viewBox="0 0 ${maxX + padding * 2} ${maxY + padding * 2}">`,
106
+ '<defs><marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L0,6 L9,3 z" fill="#444"/></marker></defs>',
107
+ '<rect width="100%" height="100%" fill="#fff"/>',
108
+ ];
109
+ edges.forEach((edge) => {
110
+ const source = nodeById.get(firstNonEmpty(edge.source.cell, '') ?? '');
111
+ const target = nodeById.get(firstNonEmpty(edge.target.cell, '') ?? '');
112
+ if (!source || !target) {
113
+ return;
114
+ }
115
+ const x1 = padding + source.x + source.width;
116
+ const y1 = padding + source.y + source.height / 2;
117
+ const x2 = padding + target.x;
118
+ const y2 = padding + target.y + target.height / 2;
119
+ lines.push(`<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="#444" stroke-width="2" marker-end="url(#arrow)"/>`);
120
+ });
121
+ nodes.forEach((node) => {
122
+ const x = padding + node.x;
123
+ const y = padding + node.y;
124
+ lines.push(`<rect x="${x}" y="${y}" width="${node.width}" height="${node.height}" rx="4" fill="#f8fafc" stroke="#334155"/>`, `<text x="${x + 12}" y="${y + 28}" font-family="Arial, sans-serif" font-size="14" fill="#111827">${escapeXml(labelFromNode(node))}</text>`, `<text x="${x + 12}" y="${y + 52}" font-family="Arial, sans-serif" font-size="12" fill="#475569">${escapeXml(firstNonEmpty(node.data.id, node.id))}</text>`);
125
+ });
126
+ lines.push('</svg>');
127
+ return `${lines.join('\n')}\n`;
128
+ }
129
+ function checkEdges(modelIndex, modelId, nodes, edges) {
130
+ const nodeIds = new Set(nodes.map((node) => node.id));
131
+ const findings = [];
132
+ edges.forEach((edge, index) => {
133
+ const source = firstNonEmpty(edge.source.cell);
134
+ const target = firstNonEmpty(edge.target.cell);
135
+ if (!source || !nodeIds.has(source)) {
136
+ findings.push({
137
+ severity: 'error',
138
+ code: 'missing_source_process_instance',
139
+ model_index: modelIndex,
140
+ model_id: modelId,
141
+ path: `xflow.edges.${index}.source.cell`,
142
+ message: `Edge ${edge.id} references missing source process instance ${source ?? '<empty>'}.`,
143
+ });
144
+ }
145
+ if (!target || !nodeIds.has(target)) {
146
+ findings.push({
147
+ severity: 'error',
148
+ code: 'missing_target_process_instance',
149
+ model_index: modelIndex,
150
+ model_id: modelId,
151
+ path: `xflow.edges.${index}.target.cell`,
152
+ message: `Edge ${edge.id} references missing target process instance ${target ?? '<empty>'}.`,
153
+ });
154
+ }
155
+ });
156
+ return findings;
157
+ }
158
+ function safeStem(index, id) {
159
+ const base = id ? id.replace(/[^A-Za-z0-9_.-]+/gu, '_') : `model-${index + 1}`;
160
+ return `${String(index + 1).padStart(3, '0')}-${base}`;
161
+ }
162
+ function wants(format, target) {
163
+ return format === 'all' || format === target;
164
+ }
165
+ export async function runLifecyclemodelGraph(options) {
166
+ if (!options.outDir) {
167
+ throw new CliError('Missing required --out-dir value.', {
168
+ code: 'LIFECYCLEMODEL_GRAPH_OUT_DIR_REQUIRED',
169
+ exitCode: 2,
170
+ });
171
+ }
172
+ const format = normalizeFormat(options.format);
173
+ const outDir = path.resolve(options.outDir);
174
+ const rows = materializeDatasetRows(options.inputPath, options.rawInput);
175
+ const findings = [];
176
+ const models = [];
177
+ rows.forEach((row, index) => {
178
+ const graph = deriveLifecyclemodelJsonTg(row.payload);
179
+ const nodes = normalizeNodes(graph);
180
+ const edges = normalizeEdges(graph);
181
+ const modelFindings = options.checkConnections === true ? checkEdges(index, row.id, nodes, edges) : [];
182
+ findings.push(...modelFindings);
183
+ const stem = safeStem(index, row.id);
184
+ const graphJsonPath = wants(format, 'json')
185
+ ? path.join(outDir, 'graphs', `${stem}.json`)
186
+ : null;
187
+ const dotPath = wants(format, 'dot') ? path.join(outDir, 'graphs', `${stem}.dot`) : null;
188
+ const svgPath = wants(format, 'svg') ? path.join(outDir, 'graphs', `${stem}.svg`) : null;
189
+ if (graphJsonPath) {
190
+ writeJsonArtifact(graphJsonPath, graph);
191
+ }
192
+ if (dotPath) {
193
+ writeTextArtifact(dotPath, buildDot(row.id, nodes, edges));
194
+ }
195
+ if (svgPath) {
196
+ writeTextArtifact(svgPath, buildSvg(nodes, edges));
197
+ }
198
+ models.push({
199
+ index,
200
+ id: row.id,
201
+ version: row.version,
202
+ node_count: nodes.length,
203
+ edge_count: edges.length,
204
+ finding_count: modelFindings.length,
205
+ files: {
206
+ graph_json: graphJsonPath,
207
+ dot: dotPath,
208
+ svg: svgPath,
209
+ },
210
+ });
211
+ });
212
+ const files = {
213
+ report: path.join(outDir, 'outputs', 'graph-report.json'),
214
+ findings: path.join(outDir, 'outputs', 'findings.jsonl'),
215
+ };
216
+ const report = {
217
+ generated_at_utc: (options.now ?? new Date()).toISOString(),
218
+ input_path: path.resolve(options.inputPath),
219
+ out_dir: outDir,
220
+ format,
221
+ check_connections: options.checkConnections === true,
222
+ status: findings.length > 0 ? 'completed_with_findings' : 'completed',
223
+ counts: {
224
+ models: models.length,
225
+ nodes: models.reduce((sum, model) => sum + model.node_count, 0),
226
+ edges: models.reduce((sum, model) => sum + model.edge_count, 0),
227
+ findings: findings.length,
228
+ },
229
+ files,
230
+ models,
231
+ findings,
232
+ };
233
+ writeJsonArtifact(files.report, report);
234
+ writeJsonLinesArtifact(files.findings, findings);
235
+ return report;
236
+ }
237
+ export const __testInternals = {
238
+ asArray,
239
+ buildDot,
240
+ buildSvg,
241
+ checkEdges,
242
+ labelFromNode,
243
+ normalizeFormat,
244
+ normalizeNodes,
245
+ normalizeEdges,
246
+ safeStem,
247
+ };
248
+ //# sourceMappingURL=lifecyclemodel-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecyclemodel-graph.js","sourceRoot":"","sources":["../../../src/lib/lifecyclemodel-graph.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { writeJsonArtifact, writeJsonLinesArtifact, writeTextArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport {\n firstNonEmpty,\n isRecord,\n materializeDatasetRows,\n trimToken,\n type JsonObject,\n} from './dataset-local.js';\nimport { deriveLifecyclemodelJsonTg } from './lifecyclemodel-bundle-save.js';\n\nexport type LifecyclemodelGraphFormat = 'json' | 'dot' | 'svg' | 'all';\n\nexport type LifecyclemodelGraphFinding = {\n severity: 'error' | 'warning';\n code: string;\n model_index: number;\n model_id: string | null;\n path: string;\n message: string;\n};\n\nexport type LifecyclemodelGraphModelReport = {\n index: number;\n id: string | null;\n version: string | null;\n node_count: number;\n edge_count: number;\n finding_count: number;\n files: {\n graph_json: string | null;\n dot: string | null;\n svg: string | null;\n };\n};\n\nexport type LifecyclemodelGraphReport = {\n generated_at_utc: string;\n input_path: string;\n out_dir: string;\n format: LifecyclemodelGraphFormat;\n check_connections: boolean;\n status: 'completed' | 'completed_with_findings';\n counts: {\n models: number;\n nodes: number;\n edges: number;\n findings: number;\n };\n files: {\n report: string;\n findings: string;\n };\n models: LifecyclemodelGraphModelReport[];\n findings: LifecyclemodelGraphFinding[];\n};\n\nexport type RunLifecyclemodelGraphOptions = {\n inputPath: string;\n outDir: string;\n format?: string | null;\n checkConnections?: boolean | null;\n rawInput?: unknown;\n now?: Date;\n};\n\ntype XflowNode = {\n id: string;\n x: number;\n y: number;\n width: number;\n height: number;\n data: JsonObject;\n};\n\ntype XflowEdge = {\n id: string;\n source: { cell?: string };\n target: { cell?: string };\n data: JsonObject;\n};\n\nfunction normalizeFormat(value: string | null | undefined): LifecyclemodelGraphFormat {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) {\n return 'all';\n }\n if (\n normalized === 'json' ||\n normalized === 'dot' ||\n normalized === 'svg' ||\n normalized === 'all'\n ) {\n return normalized;\n }\n throw new CliError('Expected --format to be json, dot, svg, or all.', {\n code: 'LIFECYCLEMODEL_GRAPH_FORMAT_INVALID',\n exitCode: 2,\n details: value,\n });\n}\n\nfunction asArray(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value;\n }\n if (value === undefined || value === null) {\n return [];\n }\n return [value];\n}\n\nfunction normalizeNodes(jsonTg: JsonObject): XflowNode[] {\n const xflow = isRecord(jsonTg.xflow) ? jsonTg.xflow : {};\n return asArray(xflow.nodes)\n .filter(isRecord)\n .map((node, index) => ({\n id: firstNonEmpty(node.id, `node-${index + 1}`)!,\n x: typeof node.x === 'number' ? node.x : index * 320,\n y: typeof node.y === 'number' ? node.y : 0,\n width: typeof node.width === 'number' ? node.width : 260,\n height: typeof node.height === 'number' ? node.height : 90,\n data: isRecord(node.data) ? node.data : {},\n }));\n}\n\nfunction normalizeEdges(jsonTg: JsonObject): XflowEdge[] {\n const xflow = isRecord(jsonTg.xflow) ? jsonTg.xflow : {};\n return asArray(xflow.edges)\n .filter(isRecord)\n .map((edge, index) => ({\n id: firstNonEmpty(edge.id, `edge-${index + 1}`)!,\n source: isRecord(edge.source) ? edge.source : {},\n target: isRecord(edge.target) ? edge.target : {},\n data: isRecord(edge.data) ? edge.data : {},\n }));\n}\n\nfunction labelFromNode(node: XflowNode): string {\n const label = node.data.label;\n if (typeof label === 'string') {\n return label;\n }\n if (isRecord(label) && Array.isArray(label.baseName)) {\n const first = label.baseName.find(isRecord);\n const text = isRecord(first) ? trimToken(first['#text']) : null;\n if (text) {\n return text;\n }\n }\n return firstNonEmpty(node.data.id, node.id)!;\n}\n\nfunction escapeDot(value: string): string {\n return value.replace(/\\\\/gu, '\\\\\\\\').replace(/\"/gu, '\\\\\"');\n}\n\nfunction escapeXml(value: string): string {\n return value\n .replace(/&/gu, '&amp;')\n .replace(/</gu, '&lt;')\n .replace(/>/gu, '&gt;')\n .replace(/\"/gu, '&quot;');\n}\n\nfunction buildDot(modelId: string | null, nodes: XflowNode[], edges: XflowEdge[]): string {\n const lines = ['digraph lifecyclemodel {', ' rankdir=LR;', ' node [shape=box];'];\n if (modelId) {\n lines.push(` label=\"${escapeDot(modelId)}\";`);\n }\n nodes.forEach((node) => {\n lines.push(` \"${escapeDot(node.id)}\" [label=\"${escapeDot(labelFromNode(node))}\"];`);\n });\n edges.forEach((edge) => {\n const source = firstNonEmpty(edge.source.cell, 'unknown-source')!;\n const target = firstNonEmpty(edge.target.cell, 'unknown-target')!;\n const connection = isRecord(edge.data.connection) ? edge.data.connection : {};\n const outputExchange = isRecord(connection.outputExchange) ? connection.outputExchange : {};\n const flowUuid = firstNonEmpty(outputExchange['@flowUUID'], edge.id);\n lines.push(\n ` \"${escapeDot(source)}\" -> \"${escapeDot(target)}\" [label=\"${escapeDot(flowUuid ?? '')}\"];`,\n );\n });\n lines.push('}');\n return `${lines.join('\\n')}\\n`;\n}\n\nfunction buildSvg(nodes: XflowNode[], edges: XflowEdge[]): string {\n const padding = 32;\n const maxX = Math.max(...nodes.map((node) => node.x + node.width), 320);\n const maxY = Math.max(...nodes.map((node) => node.y + node.height), 180);\n const nodeById = new Map(nodes.map((node) => [node.id, node]));\n const lines = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${maxX + padding * 2}\" height=\"${\n maxY + padding * 2\n }\" viewBox=\"0 0 ${maxX + padding * 2} ${maxY + padding * 2}\">`,\n '<defs><marker id=\"arrow\" markerWidth=\"10\" markerHeight=\"10\" refX=\"8\" refY=\"3\" orient=\"auto\" markerUnits=\"strokeWidth\"><path d=\"M0,0 L0,6 L9,3 z\" fill=\"#444\"/></marker></defs>',\n '<rect width=\"100%\" height=\"100%\" fill=\"#fff\"/>',\n ];\n\n edges.forEach((edge) => {\n const source = nodeById.get(firstNonEmpty(edge.source.cell, '') ?? '');\n const target = nodeById.get(firstNonEmpty(edge.target.cell, '') ?? '');\n if (!source || !target) {\n return;\n }\n const x1 = padding + source.x + source.width;\n const y1 = padding + source.y + source.height / 2;\n const x2 = padding + target.x;\n const y2 = padding + target.y + target.height / 2;\n lines.push(\n `<line x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"#444\" stroke-width=\"2\" marker-end=\"url(#arrow)\"/>`,\n );\n });\n\n nodes.forEach((node) => {\n const x = padding + node.x;\n const y = padding + node.y;\n lines.push(\n `<rect x=\"${x}\" y=\"${y}\" width=\"${node.width}\" height=\"${node.height}\" rx=\"4\" fill=\"#f8fafc\" stroke=\"#334155\"/>`,\n `<text x=\"${x + 12}\" y=\"${y + 28}\" font-family=\"Arial, sans-serif\" font-size=\"14\" fill=\"#111827\">${escapeXml(\n labelFromNode(node),\n )}</text>`,\n `<text x=\"${x + 12}\" y=\"${y + 52}\" font-family=\"Arial, sans-serif\" font-size=\"12\" fill=\"#475569\">${escapeXml(\n firstNonEmpty(node.data.id, node.id)!,\n )}</text>`,\n );\n });\n\n lines.push('</svg>');\n return `${lines.join('\\n')}\\n`;\n}\n\nfunction checkEdges(\n modelIndex: number,\n modelId: string | null,\n nodes: XflowNode[],\n edges: XflowEdge[],\n): LifecyclemodelGraphFinding[] {\n const nodeIds = new Set(nodes.map((node) => node.id));\n const findings: LifecyclemodelGraphFinding[] = [];\n edges.forEach((edge, index) => {\n const source = firstNonEmpty(edge.source.cell);\n const target = firstNonEmpty(edge.target.cell);\n if (!source || !nodeIds.has(source)) {\n findings.push({\n severity: 'error',\n code: 'missing_source_process_instance',\n model_index: modelIndex,\n model_id: modelId,\n path: `xflow.edges.${index}.source.cell`,\n message: `Edge ${edge.id} references missing source process instance ${source ?? '<empty>'}.`,\n });\n }\n if (!target || !nodeIds.has(target)) {\n findings.push({\n severity: 'error',\n code: 'missing_target_process_instance',\n model_index: modelIndex,\n model_id: modelId,\n path: `xflow.edges.${index}.target.cell`,\n message: `Edge ${edge.id} references missing target process instance ${target ?? '<empty>'}.`,\n });\n }\n });\n return findings;\n}\n\nfunction safeStem(index: number, id: string | null): string {\n const base = id ? id.replace(/[^A-Za-z0-9_.-]+/gu, '_') : `model-${index + 1}`;\n return `${String(index + 1).padStart(3, '0')}-${base}`;\n}\n\nfunction wants(\n format: LifecyclemodelGraphFormat,\n target: Exclude<LifecyclemodelGraphFormat, 'all'>,\n): boolean {\n return format === 'all' || format === target;\n}\n\nexport async function runLifecyclemodelGraph(\n options: RunLifecyclemodelGraphOptions,\n): Promise<LifecyclemodelGraphReport> {\n if (!options.outDir) {\n throw new CliError('Missing required --out-dir value.', {\n code: 'LIFECYCLEMODEL_GRAPH_OUT_DIR_REQUIRED',\n exitCode: 2,\n });\n }\n\n const format = normalizeFormat(options.format);\n const outDir = path.resolve(options.outDir);\n const rows = materializeDatasetRows(options.inputPath, options.rawInput);\n const findings: LifecyclemodelGraphFinding[] = [];\n const models: LifecyclemodelGraphModelReport[] = [];\n\n rows.forEach((row, index) => {\n const graph = deriveLifecyclemodelJsonTg(row.payload);\n const nodes = normalizeNodes(graph);\n const edges = normalizeEdges(graph);\n const modelFindings =\n options.checkConnections === true ? checkEdges(index, row.id, nodes, edges) : [];\n findings.push(...modelFindings);\n const stem = safeStem(index, row.id);\n const graphJsonPath = wants(format, 'json')\n ? path.join(outDir, 'graphs', `${stem}.json`)\n : null;\n const dotPath = wants(format, 'dot') ? path.join(outDir, 'graphs', `${stem}.dot`) : null;\n const svgPath = wants(format, 'svg') ? path.join(outDir, 'graphs', `${stem}.svg`) : null;\n\n if (graphJsonPath) {\n writeJsonArtifact(graphJsonPath, graph);\n }\n if (dotPath) {\n writeTextArtifact(dotPath, buildDot(row.id, nodes, edges));\n }\n if (svgPath) {\n writeTextArtifact(svgPath, buildSvg(nodes, edges));\n }\n\n models.push({\n index,\n id: row.id,\n version: row.version,\n node_count: nodes.length,\n edge_count: edges.length,\n finding_count: modelFindings.length,\n files: {\n graph_json: graphJsonPath,\n dot: dotPath,\n svg: svgPath,\n },\n });\n });\n\n const files = {\n report: path.join(outDir, 'outputs', 'graph-report.json'),\n findings: path.join(outDir, 'outputs', 'findings.jsonl'),\n };\n const report: LifecyclemodelGraphReport = {\n generated_at_utc: (options.now ?? new Date()).toISOString(),\n input_path: path.resolve(options.inputPath),\n out_dir: outDir,\n format,\n check_connections: options.checkConnections === true,\n status: findings.length > 0 ? 'completed_with_findings' : 'completed',\n counts: {\n models: models.length,\n nodes: models.reduce((sum, model) => sum + model.node_count, 0),\n edges: models.reduce((sum, model) => sum + model.edge_count, 0),\n findings: findings.length,\n },\n files,\n models,\n findings,\n };\n writeJsonArtifact(files.report, report);\n writeJsonLinesArtifact(files.findings, findings);\n return report;\n}\n\nexport const __testInternals = {\n asArray,\n buildDot,\n buildSvg,\n checkEdges,\n labelFromNode,\n normalizeFormat,\n normalizeNodes,\n normalizeEdges,\n safeStem,\n};\n"]}
@@ -218,7 +218,7 @@ function buildNextActions(layout) {
218
218
  return [
219
219
  `inspect: ${layout.publishBundlePath}`,
220
220
  `inspect: ${layout.publishRequestPath}`,
221
- `run: tiangong publish run --input ${layout.publishRequestPath} # lifecyclemodels commit through save_lifecycle_model_bundle`,
221
+ `run: tiangong-lca publish run --input ${layout.publishRequestPath} # lifecyclemodels commit through save_lifecycle_model_bundle`,
222
222
  ];
223
223
  }
224
224
  export async function runLifecyclemodelPublishBuild(options) {
@@ -1 +1 @@
1
- {"version":3,"file":"lifecyclemodel-publish-build.js","sourceRoot":"","sources":["../../../src/lib/lifecyclemodel-publish-build.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync } from 'node:fs';\nimport path from 'node:path';\nimport { readJsonArtifact, writeJsonArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport { normalizePublishRequest } from './publish.js';\n\ntype JsonObject = Record<string, unknown>;\n\ntype LifecyclemodelPublishValidationSummary = {\n available: boolean;\n ok: boolean | null;\n report: string | null;\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction nonEmptyString(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n const normalized = value.trim();\n return normalized || null;\n}\n\nfunction copyJson<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction readRequiredJsonObject(\n filePath: string,\n missingCode: string,\n invalidCode: string,\n label: string,\n): JsonObject {\n if (!existsSync(filePath)) {\n throw new CliError(`Required lifecyclemodel ${label} artifact not found: ${filePath}`, {\n code: missingCode,\n exitCode: 2,\n details: { filePath, label },\n });\n }\n\n const value = readJsonArtifact(filePath);\n if (!isRecord(value)) {\n throw new CliError(`Expected lifecyclemodel ${label} artifact JSON object: ${filePath}`, {\n code: invalidCode,\n exitCode: 2,\n details: { filePath, label },\n });\n }\n\n return value;\n}\n\nexport type LifecyclemodelPublishBuildLayout = {\n runId: string;\n runRoot: string;\n modelsDir: string;\n reportsDir: string;\n manifestsDir: string;\n publishStageDir: string;\n runManifestPath: string;\n invocationIndexPath: string;\n validationReportPath: string;\n publishBundlePath: string;\n publishRequestPath: string;\n publishIntentPath: string;\n reportPath: string;\n};\n\nexport type LifecyclemodelPublishBuildReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'prepared_local_lifecyclemodel_publish_bundle';\n run_id: string;\n run_root: string;\n counts: {\n lifecyclemodels: number;\n };\n publish_defaults: {\n commit: boolean;\n publish_lifecyclemodels: boolean;\n publish_processes: boolean;\n publish_sources: boolean;\n publish_relations: boolean;\n publish_process_build_runs: boolean;\n relation_mode: 'local_manifest_only';\n };\n validation: LifecyclemodelPublishValidationSummary;\n files: {\n run_manifest: string;\n invocation_index: string;\n publish_bundle: string;\n publish_request: string;\n publish_intent: string;\n report: string;\n };\n next_actions: string[];\n};\n\nexport type RunLifecyclemodelPublishBuildOptions = {\n runDir: string;\n now?: Date;\n cwd?: string;\n};\n\nfunction buildLayout(runRoot: string): LifecyclemodelPublishBuildLayout {\n const runId = path.basename(runRoot);\n return {\n runId,\n runRoot,\n modelsDir: path.join(runRoot, 'models'),\n reportsDir: path.join(runRoot, 'reports'),\n manifestsDir: path.join(runRoot, 'manifests'),\n publishStageDir: path.join(runRoot, 'stage_outputs', '10_publish'),\n runManifestPath: path.join(runRoot, 'manifests', 'run-manifest.json'),\n invocationIndexPath: path.join(runRoot, 'manifests', 'invocation-index.json'),\n validationReportPath: path.join(\n runRoot,\n 'reports',\n 'lifecyclemodel-validate-build-report.json',\n ),\n publishBundlePath: path.join(runRoot, 'stage_outputs', '10_publish', 'publish-bundle.json'),\n publishRequestPath: path.join(runRoot, 'stage_outputs', '10_publish', 'publish-request.json'),\n publishIntentPath: path.join(runRoot, 'stage_outputs', '10_publish', 'publish-intent.json'),\n reportPath: path.join(runRoot, 'reports', 'lifecyclemodel-publish-build-report.json'),\n };\n}\n\nfunction resolveLayout(\n options: RunLifecyclemodelPublishBuildOptions,\n): LifecyclemodelPublishBuildLayout {\n const runDir = nonEmptyString(options.runDir);\n if (!runDir) {\n throw new CliError('Missing required --run-dir for lifecyclemodel publish-build.', {\n code: 'LIFECYCLEMODEL_PUBLISH_RUN_DIR_REQUIRED',\n exitCode: 2,\n });\n }\n\n return buildLayout(path.resolve(runDir));\n}\n\nfunction ensureRunRootExists(layout: LifecyclemodelPublishBuildLayout): void {\n if (!existsSync(layout.runRoot)) {\n throw new CliError(`lifecyclemodel publish-build run root not found: ${layout.runRoot}`, {\n code: 'LIFECYCLEMODEL_PUBLISH_RUN_NOT_FOUND',\n exitCode: 2,\n });\n }\n}\n\nfunction readRequiredRunManifest(layout: LifecyclemodelPublishBuildLayout): JsonObject {\n const manifest = readRequiredJsonObject(\n layout.runManifestPath,\n 'LIFECYCLEMODEL_PUBLISH_RUN_MANIFEST_MISSING',\n 'LIFECYCLEMODEL_PUBLISH_RUN_MANIFEST_INVALID',\n 'run-manifest',\n );\n\n const manifestRunId = nonEmptyString(manifest.runId);\n if (manifestRunId && manifestRunId !== layout.runId) {\n throw new CliError(\n `lifecyclemodel publish-build run manifest runId mismatch: ${layout.runManifestPath}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_RUN_MANIFEST_MISMATCH',\n exitCode: 2,\n details: {\n expected: layout.runId,\n actual: manifestRunId,\n },\n },\n );\n }\n\n return manifest;\n}\n\nfunction readInvocationIndex(layout: LifecyclemodelPublishBuildLayout): JsonObject {\n if (!existsSync(layout.invocationIndexPath)) {\n return {\n schema_version: 1,\n invocations: [],\n };\n }\n\n const value = readJsonArtifact(layout.invocationIndexPath);\n if (!isRecord(value)) {\n throw new CliError(\n `Expected lifecyclemodel publish invocation index JSON object: ${layout.invocationIndexPath}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_INVOCATION_INDEX_INVALID',\n exitCode: 2,\n },\n );\n }\n\n if (value.invocations === undefined) {\n return {\n schema_version: 1,\n invocations: [],\n };\n }\n\n if (!Array.isArray(value.invocations)) {\n throw new CliError(\n `Expected lifecyclemodel publish invocation index to contain an invocations array: ${layout.invocationIndexPath}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_INVOCATION_INDEX_INVALID',\n exitCode: 2,\n },\n );\n }\n\n return value;\n}\n\nfunction collectLifecyclemodelPayloads(layout: LifecyclemodelPublishBuildLayout): JsonObject[] {\n const runNames = existsSync(layout.modelsDir) ? readdirSync(layout.modelsDir).sort() : [];\n const payloads = runNames.flatMap((runName) => {\n const lifecyclemodelsDir = path.join(\n layout.modelsDir,\n runName,\n 'tidas_bundle',\n 'lifecyclemodels',\n );\n if (!existsSync(lifecyclemodelsDir)) {\n return [];\n }\n\n return readdirSync(lifecyclemodelsDir)\n .filter((entry) => entry.endsWith('.json'))\n .sort()\n .map((entry) => {\n const filePath = path.join(lifecyclemodelsDir, entry);\n const value = readJsonArtifact(filePath);\n if (!isRecord(value)) {\n throw new CliError(`Expected lifecyclemodel publish payload JSON object: ${filePath}`, {\n code: 'LIFECYCLEMODEL_PUBLISH_MODEL_INVALID',\n exitCode: 2,\n });\n }\n return value;\n });\n });\n\n if (payloads.length === 0) {\n throw new CliError(\n `lifecyclemodel publish-build run does not contain any lifecyclemodel payloads: ${layout.modelsDir}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_MODELS_NOT_FOUND',\n exitCode: 2,\n },\n );\n }\n\n return payloads;\n}\n\nfunction readValidationSummary(\n layout: LifecyclemodelPublishBuildLayout,\n): LifecyclemodelPublishValidationSummary {\n if (!existsSync(layout.validationReportPath)) {\n return {\n available: false,\n ok: null,\n report: null,\n };\n }\n\n const value = readJsonArtifact(layout.validationReportPath);\n if (!isRecord(value)) {\n throw new CliError(\n `Expected lifecyclemodel validate-build report JSON object: ${layout.validationReportPath}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_VALIDATION_REPORT_INVALID',\n exitCode: 2,\n },\n );\n }\n\n return {\n available: true,\n ok: typeof value.ok === 'boolean' ? value.ok : false,\n report: layout.validationReportPath,\n };\n}\n\nfunction buildPublishRequest(): JsonObject {\n return {\n inputs: {\n bundle_paths: ['./publish-bundle.json'],\n },\n publish: {\n commit: false,\n publish_lifecyclemodels: true,\n publish_processes: false,\n publish_sources: false,\n publish_relations: false,\n publish_process_build_runs: false,\n relation_mode: 'local_manifest_only',\n },\n out_dir: './publish-run',\n };\n}\n\nfunction buildPublishIntent(\n layout: LifecyclemodelPublishBuildLayout,\n lifecyclemodelCount: number,\n): JsonObject {\n return {\n ok: true,\n command: 'publish run',\n lifecyclemodel_transport: 'save_lifecycle_model_bundle',\n input_path: layout.publishRequestPath,\n run_id: layout.runId,\n run_root: layout.runRoot,\n status: 'prepared_local_lifecyclemodel_publish_bundle',\n lifecyclemodel_count: lifecyclemodelCount,\n };\n}\n\nfunction buildInvocationIndex(\n layout: LifecyclemodelPublishBuildLayout,\n invocationIndex: JsonObject,\n options: RunLifecyclemodelPublishBuildOptions,\n now: Date,\n): JsonObject {\n const priorInvocations = Array.isArray(invocationIndex.invocations)\n ? [...invocationIndex.invocations]\n : [];\n\n return {\n ...invocationIndex,\n schema_version:\n typeof invocationIndex.schema_version === 'number' ? invocationIndex.schema_version : 1,\n invocations: [\n ...priorInvocations,\n {\n command: ['lifecyclemodel', 'publish-build', '--run-dir', options.runDir],\n cwd: options.cwd ?? process.cwd(),\n created_at: now.toISOString(),\n run_id: layout.runId,\n run_root: layout.runRoot,\n report_path: layout.reportPath,\n publish_request_path: layout.publishRequestPath,\n },\n ],\n };\n}\n\nfunction buildNextActions(layout: LifecyclemodelPublishBuildLayout): string[] {\n return [\n `inspect: ${layout.publishBundlePath}`,\n `inspect: ${layout.publishRequestPath}`,\n `run: tiangong publish run --input ${layout.publishRequestPath} # lifecyclemodels commit through save_lifecycle_model_bundle`,\n ];\n}\n\nexport async function runLifecyclemodelPublishBuild(\n options: RunLifecyclemodelPublishBuildOptions,\n): Promise<LifecyclemodelPublishBuildReport> {\n const now = options.now ?? new Date();\n const layout = resolveLayout(options);\n ensureRunRootExists(layout);\n const runManifest = readRequiredRunManifest(layout);\n const invocationIndex = readInvocationIndex(layout);\n const lifecyclemodels = collectLifecyclemodelPayloads(layout);\n const validation = readValidationSummary(layout);\n const publishRequest = buildPublishRequest();\n const normalizedPublishRequest = normalizePublishRequest(publishRequest, {\n requestPath: layout.publishRequestPath,\n now,\n });\n const publishBundle = {\n generated_at_utc: now.toISOString(),\n run_id: layout.runId,\n run_root: layout.runRoot,\n status: 'prepared_local_lifecyclemodel_publish_bundle' as const,\n lifecyclemodel_transport: 'save_lifecycle_model_bundle' as const,\n source_run: {\n run_manifest: copyJson(runManifest),\n },\n validation: copyJson(validation),\n lifecyclemodels: copyJson(lifecyclemodels),\n relations: [],\n };\n const publishIntent = buildPublishIntent(layout, lifecyclemodels.length);\n const report: LifecyclemodelPublishBuildReport = {\n schema_version: 1,\n generated_at_utc: now.toISOString(),\n status: 'prepared_local_lifecyclemodel_publish_bundle',\n run_id: layout.runId,\n run_root: layout.runRoot,\n counts: {\n lifecyclemodels: lifecyclemodels.length,\n },\n publish_defaults: {\n commit: normalizedPublishRequest.publish.commit,\n publish_lifecyclemodels: normalizedPublishRequest.publish.publish_lifecyclemodels,\n publish_processes: normalizedPublishRequest.publish.publish_processes,\n publish_sources: normalizedPublishRequest.publish.publish_sources,\n publish_relations: normalizedPublishRequest.publish.publish_relations,\n publish_process_build_runs: normalizedPublishRequest.publish.publish_process_build_runs,\n relation_mode: normalizedPublishRequest.publish.relation_mode,\n },\n validation,\n files: {\n run_manifest: layout.runManifestPath,\n invocation_index: layout.invocationIndexPath,\n publish_bundle: layout.publishBundlePath,\n publish_request: layout.publishRequestPath,\n publish_intent: layout.publishIntentPath,\n report: layout.reportPath,\n },\n next_actions: buildNextActions(layout),\n };\n\n writeJsonArtifact(\n layout.invocationIndexPath,\n buildInvocationIndex(layout, invocationIndex, options, now),\n );\n writeJsonArtifact(layout.publishBundlePath, publishBundle);\n writeJsonArtifact(layout.publishRequestPath, publishRequest);\n writeJsonArtifact(layout.publishIntentPath, publishIntent);\n writeJsonArtifact(layout.reportPath, report);\n\n return report;\n}\n\nexport const __testInternals = {\n buildLayout,\n resolveLayout,\n readInvocationIndex,\n collectLifecyclemodelPayloads,\n readValidationSummary,\n buildPublishRequest,\n buildPublishIntent,\n buildInvocationIndex,\n buildNextActions,\n};\n"]}
1
+ {"version":3,"file":"lifecyclemodel-publish-build.js","sourceRoot":"","sources":["../../../src/lib/lifecyclemodel-publish-build.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync } from 'node:fs';\nimport path from 'node:path';\nimport { readJsonArtifact, writeJsonArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport { normalizePublishRequest } from './publish.js';\n\ntype JsonObject = Record<string, unknown>;\n\ntype LifecyclemodelPublishValidationSummary = {\n available: boolean;\n ok: boolean | null;\n report: string | null;\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction nonEmptyString(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n const normalized = value.trim();\n return normalized || null;\n}\n\nfunction copyJson<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction readRequiredJsonObject(\n filePath: string,\n missingCode: string,\n invalidCode: string,\n label: string,\n): JsonObject {\n if (!existsSync(filePath)) {\n throw new CliError(`Required lifecyclemodel ${label} artifact not found: ${filePath}`, {\n code: missingCode,\n exitCode: 2,\n details: { filePath, label },\n });\n }\n\n const value = readJsonArtifact(filePath);\n if (!isRecord(value)) {\n throw new CliError(`Expected lifecyclemodel ${label} artifact JSON object: ${filePath}`, {\n code: invalidCode,\n exitCode: 2,\n details: { filePath, label },\n });\n }\n\n return value;\n}\n\nexport type LifecyclemodelPublishBuildLayout = {\n runId: string;\n runRoot: string;\n modelsDir: string;\n reportsDir: string;\n manifestsDir: string;\n publishStageDir: string;\n runManifestPath: string;\n invocationIndexPath: string;\n validationReportPath: string;\n publishBundlePath: string;\n publishRequestPath: string;\n publishIntentPath: string;\n reportPath: string;\n};\n\nexport type LifecyclemodelPublishBuildReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'prepared_local_lifecyclemodel_publish_bundle';\n run_id: string;\n run_root: string;\n counts: {\n lifecyclemodels: number;\n };\n publish_defaults: {\n commit: boolean;\n publish_lifecyclemodels: boolean;\n publish_processes: boolean;\n publish_sources: boolean;\n publish_relations: boolean;\n publish_process_build_runs: boolean;\n relation_mode: 'local_manifest_only';\n };\n validation: LifecyclemodelPublishValidationSummary;\n files: {\n run_manifest: string;\n invocation_index: string;\n publish_bundle: string;\n publish_request: string;\n publish_intent: string;\n report: string;\n };\n next_actions: string[];\n};\n\nexport type RunLifecyclemodelPublishBuildOptions = {\n runDir: string;\n now?: Date;\n cwd?: string;\n};\n\nfunction buildLayout(runRoot: string): LifecyclemodelPublishBuildLayout {\n const runId = path.basename(runRoot);\n return {\n runId,\n runRoot,\n modelsDir: path.join(runRoot, 'models'),\n reportsDir: path.join(runRoot, 'reports'),\n manifestsDir: path.join(runRoot, 'manifests'),\n publishStageDir: path.join(runRoot, 'stage_outputs', '10_publish'),\n runManifestPath: path.join(runRoot, 'manifests', 'run-manifest.json'),\n invocationIndexPath: path.join(runRoot, 'manifests', 'invocation-index.json'),\n validationReportPath: path.join(\n runRoot,\n 'reports',\n 'lifecyclemodel-validate-build-report.json',\n ),\n publishBundlePath: path.join(runRoot, 'stage_outputs', '10_publish', 'publish-bundle.json'),\n publishRequestPath: path.join(runRoot, 'stage_outputs', '10_publish', 'publish-request.json'),\n publishIntentPath: path.join(runRoot, 'stage_outputs', '10_publish', 'publish-intent.json'),\n reportPath: path.join(runRoot, 'reports', 'lifecyclemodel-publish-build-report.json'),\n };\n}\n\nfunction resolveLayout(\n options: RunLifecyclemodelPublishBuildOptions,\n): LifecyclemodelPublishBuildLayout {\n const runDir = nonEmptyString(options.runDir);\n if (!runDir) {\n throw new CliError('Missing required --run-dir for lifecyclemodel publish-build.', {\n code: 'LIFECYCLEMODEL_PUBLISH_RUN_DIR_REQUIRED',\n exitCode: 2,\n });\n }\n\n return buildLayout(path.resolve(runDir));\n}\n\nfunction ensureRunRootExists(layout: LifecyclemodelPublishBuildLayout): void {\n if (!existsSync(layout.runRoot)) {\n throw new CliError(`lifecyclemodel publish-build run root not found: ${layout.runRoot}`, {\n code: 'LIFECYCLEMODEL_PUBLISH_RUN_NOT_FOUND',\n exitCode: 2,\n });\n }\n}\n\nfunction readRequiredRunManifest(layout: LifecyclemodelPublishBuildLayout): JsonObject {\n const manifest = readRequiredJsonObject(\n layout.runManifestPath,\n 'LIFECYCLEMODEL_PUBLISH_RUN_MANIFEST_MISSING',\n 'LIFECYCLEMODEL_PUBLISH_RUN_MANIFEST_INVALID',\n 'run-manifest',\n );\n\n const manifestRunId = nonEmptyString(manifest.runId);\n if (manifestRunId && manifestRunId !== layout.runId) {\n throw new CliError(\n `lifecyclemodel publish-build run manifest runId mismatch: ${layout.runManifestPath}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_RUN_MANIFEST_MISMATCH',\n exitCode: 2,\n details: {\n expected: layout.runId,\n actual: manifestRunId,\n },\n },\n );\n }\n\n return manifest;\n}\n\nfunction readInvocationIndex(layout: LifecyclemodelPublishBuildLayout): JsonObject {\n if (!existsSync(layout.invocationIndexPath)) {\n return {\n schema_version: 1,\n invocations: [],\n };\n }\n\n const value = readJsonArtifact(layout.invocationIndexPath);\n if (!isRecord(value)) {\n throw new CliError(\n `Expected lifecyclemodel publish invocation index JSON object: ${layout.invocationIndexPath}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_INVOCATION_INDEX_INVALID',\n exitCode: 2,\n },\n );\n }\n\n if (value.invocations === undefined) {\n return {\n schema_version: 1,\n invocations: [],\n };\n }\n\n if (!Array.isArray(value.invocations)) {\n throw new CliError(\n `Expected lifecyclemodel publish invocation index to contain an invocations array: ${layout.invocationIndexPath}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_INVOCATION_INDEX_INVALID',\n exitCode: 2,\n },\n );\n }\n\n return value;\n}\n\nfunction collectLifecyclemodelPayloads(layout: LifecyclemodelPublishBuildLayout): JsonObject[] {\n const runNames = existsSync(layout.modelsDir) ? readdirSync(layout.modelsDir).sort() : [];\n const payloads = runNames.flatMap((runName) => {\n const lifecyclemodelsDir = path.join(\n layout.modelsDir,\n runName,\n 'tidas_bundle',\n 'lifecyclemodels',\n );\n if (!existsSync(lifecyclemodelsDir)) {\n return [];\n }\n\n return readdirSync(lifecyclemodelsDir)\n .filter((entry) => entry.endsWith('.json'))\n .sort()\n .map((entry) => {\n const filePath = path.join(lifecyclemodelsDir, entry);\n const value = readJsonArtifact(filePath);\n if (!isRecord(value)) {\n throw new CliError(`Expected lifecyclemodel publish payload JSON object: ${filePath}`, {\n code: 'LIFECYCLEMODEL_PUBLISH_MODEL_INVALID',\n exitCode: 2,\n });\n }\n return value;\n });\n });\n\n if (payloads.length === 0) {\n throw new CliError(\n `lifecyclemodel publish-build run does not contain any lifecyclemodel payloads: ${layout.modelsDir}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_MODELS_NOT_FOUND',\n exitCode: 2,\n },\n );\n }\n\n return payloads;\n}\n\nfunction readValidationSummary(\n layout: LifecyclemodelPublishBuildLayout,\n): LifecyclemodelPublishValidationSummary {\n if (!existsSync(layout.validationReportPath)) {\n return {\n available: false,\n ok: null,\n report: null,\n };\n }\n\n const value = readJsonArtifact(layout.validationReportPath);\n if (!isRecord(value)) {\n throw new CliError(\n `Expected lifecyclemodel validate-build report JSON object: ${layout.validationReportPath}`,\n {\n code: 'LIFECYCLEMODEL_PUBLISH_VALIDATION_REPORT_INVALID',\n exitCode: 2,\n },\n );\n }\n\n return {\n available: true,\n ok: typeof value.ok === 'boolean' ? value.ok : false,\n report: layout.validationReportPath,\n };\n}\n\nfunction buildPublishRequest(): JsonObject {\n return {\n inputs: {\n bundle_paths: ['./publish-bundle.json'],\n },\n publish: {\n commit: false,\n publish_lifecyclemodels: true,\n publish_processes: false,\n publish_sources: false,\n publish_relations: false,\n publish_process_build_runs: false,\n relation_mode: 'local_manifest_only',\n },\n out_dir: './publish-run',\n };\n}\n\nfunction buildPublishIntent(\n layout: LifecyclemodelPublishBuildLayout,\n lifecyclemodelCount: number,\n): JsonObject {\n return {\n ok: true,\n command: 'publish run',\n lifecyclemodel_transport: 'save_lifecycle_model_bundle',\n input_path: layout.publishRequestPath,\n run_id: layout.runId,\n run_root: layout.runRoot,\n status: 'prepared_local_lifecyclemodel_publish_bundle',\n lifecyclemodel_count: lifecyclemodelCount,\n };\n}\n\nfunction buildInvocationIndex(\n layout: LifecyclemodelPublishBuildLayout,\n invocationIndex: JsonObject,\n options: RunLifecyclemodelPublishBuildOptions,\n now: Date,\n): JsonObject {\n const priorInvocations = Array.isArray(invocationIndex.invocations)\n ? [...invocationIndex.invocations]\n : [];\n\n return {\n ...invocationIndex,\n schema_version:\n typeof invocationIndex.schema_version === 'number' ? invocationIndex.schema_version : 1,\n invocations: [\n ...priorInvocations,\n {\n command: ['lifecyclemodel', 'publish-build', '--run-dir', options.runDir],\n cwd: options.cwd ?? process.cwd(),\n created_at: now.toISOString(),\n run_id: layout.runId,\n run_root: layout.runRoot,\n report_path: layout.reportPath,\n publish_request_path: layout.publishRequestPath,\n },\n ],\n };\n}\n\nfunction buildNextActions(layout: LifecyclemodelPublishBuildLayout): string[] {\n return [\n `inspect: ${layout.publishBundlePath}`,\n `inspect: ${layout.publishRequestPath}`,\n `run: tiangong-lca publish run --input ${layout.publishRequestPath} # lifecyclemodels commit through save_lifecycle_model_bundle`,\n ];\n}\n\nexport async function runLifecyclemodelPublishBuild(\n options: RunLifecyclemodelPublishBuildOptions,\n): Promise<LifecyclemodelPublishBuildReport> {\n const now = options.now ?? new Date();\n const layout = resolveLayout(options);\n ensureRunRootExists(layout);\n const runManifest = readRequiredRunManifest(layout);\n const invocationIndex = readInvocationIndex(layout);\n const lifecyclemodels = collectLifecyclemodelPayloads(layout);\n const validation = readValidationSummary(layout);\n const publishRequest = buildPublishRequest();\n const normalizedPublishRequest = normalizePublishRequest(publishRequest, {\n requestPath: layout.publishRequestPath,\n now,\n });\n const publishBundle = {\n generated_at_utc: now.toISOString(),\n run_id: layout.runId,\n run_root: layout.runRoot,\n status: 'prepared_local_lifecyclemodel_publish_bundle' as const,\n lifecyclemodel_transport: 'save_lifecycle_model_bundle' as const,\n source_run: {\n run_manifest: copyJson(runManifest),\n },\n validation: copyJson(validation),\n lifecyclemodels: copyJson(lifecyclemodels),\n relations: [],\n };\n const publishIntent = buildPublishIntent(layout, lifecyclemodels.length);\n const report: LifecyclemodelPublishBuildReport = {\n schema_version: 1,\n generated_at_utc: now.toISOString(),\n status: 'prepared_local_lifecyclemodel_publish_bundle',\n run_id: layout.runId,\n run_root: layout.runRoot,\n counts: {\n lifecyclemodels: lifecyclemodels.length,\n },\n publish_defaults: {\n commit: normalizedPublishRequest.publish.commit,\n publish_lifecyclemodels: normalizedPublishRequest.publish.publish_lifecyclemodels,\n publish_processes: normalizedPublishRequest.publish.publish_processes,\n publish_sources: normalizedPublishRequest.publish.publish_sources,\n publish_relations: normalizedPublishRequest.publish.publish_relations,\n publish_process_build_runs: normalizedPublishRequest.publish.publish_process_build_runs,\n relation_mode: normalizedPublishRequest.publish.relation_mode,\n },\n validation,\n files: {\n run_manifest: layout.runManifestPath,\n invocation_index: layout.invocationIndexPath,\n publish_bundle: layout.publishBundlePath,\n publish_request: layout.publishRequestPath,\n publish_intent: layout.publishIntentPath,\n report: layout.reportPath,\n },\n next_actions: buildNextActions(layout),\n };\n\n writeJsonArtifact(\n layout.invocationIndexPath,\n buildInvocationIndex(layout, invocationIndex, options, now),\n );\n writeJsonArtifact(layout.publishBundlePath, publishBundle);\n writeJsonArtifact(layout.publishRequestPath, publishRequest);\n writeJsonArtifact(layout.publishIntentPath, publishIntent);\n writeJsonArtifact(layout.reportPath, report);\n\n return report;\n}\n\nexport const __testInternals = {\n buildLayout,\n resolveLayout,\n readInvocationIndex,\n collectLifecyclemodelPayloads,\n readValidationSummary,\n buildPublishRequest,\n buildPublishIntent,\n buildInvocationIndex,\n buildNextActions,\n};\n"]}