@x12i/memorix-service 3.0.6 → 3.2.0

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 (178) hide show
  1. package/README.md +8 -1
  2. package/dist/ai-services/associate-prep.d.ts +37 -0
  3. package/dist/ai-services/associate-prep.d.ts.map +1 -0
  4. package/dist/ai-services/associate-prep.js +208 -0
  5. package/dist/ai-services/associate-prep.js.map +1 -0
  6. package/dist/ai-services/chunk-markdown.d.ts +22 -0
  7. package/dist/ai-services/chunk-markdown.d.ts.map +1 -0
  8. package/dist/ai-services/chunk-markdown.js +159 -0
  9. package/dist/ai-services/chunk-markdown.js.map +1 -0
  10. package/dist/ai-services/client.d.ts +31 -0
  11. package/dist/ai-services/client.d.ts.map +1 -0
  12. package/dist/ai-services/client.js +104 -0
  13. package/dist/ai-services/client.js.map +1 -0
  14. package/dist/ai-services/config.d.ts +17 -0
  15. package/dist/ai-services/config.d.ts.map +1 -0
  16. package/dist/ai-services/config.js +44 -0
  17. package/dist/ai-services/config.js.map +1 -0
  18. package/dist/ai-services/normalize-output.d.ts +29 -0
  19. package/dist/ai-services/normalize-output.d.ts.map +1 -0
  20. package/dist/ai-services/normalize-output.js +428 -0
  21. package/dist/ai-services/normalize-output.js.map +1 -0
  22. package/dist/ai-services/skill-execution.d.ts +24 -0
  23. package/dist/ai-services/skill-execution.d.ts.map +1 -0
  24. package/dist/ai-services/skill-execution.js +74 -0
  25. package/dist/ai-services/skill-execution.js.map +1 -0
  26. package/dist/ai-services/types.d.ts +62 -0
  27. package/dist/ai-services/types.d.ts.map +1 -0
  28. package/dist/ai-services/types.js +3 -0
  29. package/dist/ai-services/types.js.map +1 -0
  30. package/dist/app.d.ts.map +1 -1
  31. package/dist/app.js +41 -6
  32. package/dist/app.js.map +1 -1
  33. package/dist/assist/ask.d.ts +35 -0
  34. package/dist/assist/ask.d.ts.map +1 -0
  35. package/dist/assist/ask.js +346 -0
  36. package/dist/assist/ask.js.map +1 -0
  37. package/dist/assist/facts.d.ts +5 -0
  38. package/dist/assist/facts.d.ts.map +1 -0
  39. package/dist/assist/facts.js +237 -0
  40. package/dist/assist/facts.js.map +1 -0
  41. package/dist/assist/merge-ask-proposal.d.ts +9 -0
  42. package/dist/assist/merge-ask-proposal.d.ts.map +1 -0
  43. package/dist/assist/merge-ask-proposal.js +57 -0
  44. package/dist/assist/merge-ask-proposal.js.map +1 -0
  45. package/dist/assist/types.d.ts +60 -0
  46. package/dist/assist/types.d.ts.map +1 -0
  47. package/dist/assist/types.js +57 -0
  48. package/dist/assist/types.js.map +1 -0
  49. package/dist/assist/validate.d.ts +4 -0
  50. package/dist/assist/validate.d.ts.map +1 -0
  51. package/dist/assist/validate.js +319 -0
  52. package/dist/assist/validate.js.map +1 -0
  53. package/dist/cli.js +29 -6
  54. package/dist/cli.js.map +1 -1
  55. package/dist/connector-catalog.d.ts +68 -0
  56. package/dist/connector-catalog.d.ts.map +1 -0
  57. package/dist/connector-catalog.js +258 -0
  58. package/dist/connector-catalog.js.map +1 -0
  59. package/dist/connector-role.d.ts +22 -0
  60. package/dist/connector-role.d.ts.map +1 -0
  61. package/dist/connector-role.js +71 -0
  62. package/dist/connector-role.js.map +1 -0
  63. package/dist/destination-runtime.d.ts +8 -0
  64. package/dist/destination-runtime.d.ts.map +1 -0
  65. package/dist/destination-runtime.js +11 -0
  66. package/dist/destination-runtime.js.map +1 -0
  67. package/dist/execution-target.d.ts +141 -0
  68. package/dist/execution-target.d.ts.map +1 -0
  69. package/dist/execution-target.js +853 -0
  70. package/dist/execution-target.js.map +1 -0
  71. package/dist/generic-connectors.d.ts +41 -0
  72. package/dist/generic-connectors.d.ts.map +1 -0
  73. package/dist/generic-connectors.js +158 -0
  74. package/dist/generic-connectors.js.map +1 -0
  75. package/dist/isolation.d.ts +1 -1
  76. package/dist/isolation.d.ts.map +1 -1
  77. package/dist/jobs-scope.d.ts +21 -0
  78. package/dist/jobs-scope.d.ts.map +1 -0
  79. package/dist/jobs-scope.js +83 -0
  80. package/dist/jobs-scope.js.map +1 -0
  81. package/dist/journey/collect.js +2 -2
  82. package/dist/journey/collect.js.map +1 -1
  83. package/dist/journey/coverage.js +3 -3
  84. package/dist/journey/coverage.js.map +1 -1
  85. package/dist/known-packs.d.ts +1 -1
  86. package/dist/known-packs.d.ts.map +1 -1
  87. package/dist/known-packs.js +1 -1
  88. package/dist/known-packs.js.map +1 -1
  89. package/dist/live.d.ts +13 -1
  90. package/dist/live.d.ts.map +1 -1
  91. package/dist/live.js +866 -2
  92. package/dist/live.js.map +1 -1
  93. package/dist/magit/magit-pack-service.d.ts +112 -0
  94. package/dist/magit/magit-pack-service.d.ts.map +1 -1
  95. package/dist/magit/magit-pack-service.js +494 -12
  96. package/dist/magit/magit-pack-service.js.map +1 -1
  97. package/dist/magit/pack-to-patchset.d.ts +20 -1
  98. package/dist/magit/pack-to-patchset.d.ts.map +1 -1
  99. package/dist/magit/pack-to-patchset.js +82 -9
  100. package/dist/magit/pack-to-patchset.js.map +1 -1
  101. package/dist/magit/package-catalog-bridge.d.ts +58 -0
  102. package/dist/magit/package-catalog-bridge.d.ts.map +1 -0
  103. package/dist/magit/package-catalog-bridge.js +220 -0
  104. package/dist/magit/package-catalog-bridge.js.map +1 -0
  105. package/dist/magit/proposal-to-pack.d.ts +22 -0
  106. package/dist/magit/proposal-to-pack.d.ts.map +1 -0
  107. package/dist/magit/proposal-to-pack.js +68 -0
  108. package/dist/magit/proposal-to-pack.js.map +1 -0
  109. package/dist/mongo-metadata-store.d.ts.map +1 -1
  110. package/dist/mongo-metadata-store.js +9 -3
  111. package/dist/mongo-metadata-store.js.map +1 -1
  112. package/dist/openapi/openapi.json +6262 -3139
  113. package/dist/org-sources.d.ts +14 -0
  114. package/dist/org-sources.d.ts.map +1 -0
  115. package/dist/org-sources.js +31 -0
  116. package/dist/org-sources.js.map +1 -0
  117. package/dist/pipeline-compile.d.ts +67 -1
  118. package/dist/pipeline-compile.d.ts.map +1 -1
  119. package/dist/pipeline-compile.js +455 -29
  120. package/dist/pipeline-compile.js.map +1 -1
  121. package/dist/pipeline-invoke.d.ts +63 -0
  122. package/dist/pipeline-invoke.d.ts.map +1 -0
  123. package/dist/pipeline-invoke.js +114 -0
  124. package/dist/pipeline-invoke.js.map +1 -0
  125. package/dist/pipeline-ports.d.ts +13 -0
  126. package/dist/pipeline-ports.d.ts.map +1 -0
  127. package/dist/pipeline-ports.js +104 -0
  128. package/dist/pipeline-ports.js.map +1 -0
  129. package/dist/platform.d.ts +47 -3
  130. package/dist/platform.d.ts.map +1 -1
  131. package/dist/platform.js +309 -26
  132. package/dist/platform.js.map +1 -1
  133. package/dist/routes/ai-services.d.ts +4 -0
  134. package/dist/routes/ai-services.d.ts.map +1 -0
  135. package/dist/routes/ai-services.js +239 -0
  136. package/dist/routes/ai-services.js.map +1 -0
  137. package/dist/routes/assist.d.ts +4 -0
  138. package/dist/routes/assist.d.ts.map +1 -0
  139. package/dist/routes/assist.js +75 -0
  140. package/dist/routes/assist.js.map +1 -0
  141. package/dist/routes/connector-invocations.d.ts.map +1 -1
  142. package/dist/routes/connector-invocations.js +18 -21
  143. package/dist/routes/connector-invocations.js.map +1 -1
  144. package/dist/routes/data-journey.js +11 -11
  145. package/dist/routes/data-journey.js.map +1 -1
  146. package/dist/routes/intelligence.d.ts.map +1 -1
  147. package/dist/routes/intelligence.js +19 -1
  148. package/dist/routes/intelligence.js.map +1 -1
  149. package/dist/routes/jobs.d.ts +4 -0
  150. package/dist/routes/jobs.d.ts.map +1 -0
  151. package/dist/routes/jobs.js +888 -0
  152. package/dist/routes/jobs.js.map +1 -0
  153. package/dist/routes/memory.d.ts.map +1 -1
  154. package/dist/routes/memory.js +278 -80
  155. package/dist/routes/memory.js.map +1 -1
  156. package/dist/routes/metadata.d.ts.map +1 -1
  157. package/dist/routes/metadata.js +770 -21
  158. package/dist/routes/metadata.js.map +1 -1
  159. package/dist/routes/pipelines.d.ts.map +1 -1
  160. package/dist/routes/pipelines.js +98 -22
  161. package/dist/routes/pipelines.js.map +1 -1
  162. package/dist/routes/relationships.d.ts.map +1 -1
  163. package/dist/routes/relationships.js +109 -2
  164. package/dist/routes/relationships.js.map +1 -1
  165. package/dist/routes/simulation.d.ts +7 -0
  166. package/dist/routes/simulation.d.ts.map +1 -0
  167. package/dist/routes/simulation.js +22 -0
  168. package/dist/routes/simulation.js.map +1 -0
  169. package/dist/runx/client.d.ts +18 -0
  170. package/dist/runx/client.d.ts.map +1 -0
  171. package/dist/runx/client.js +59 -0
  172. package/dist/runx/client.js.map +1 -0
  173. package/dist/simulation.d.ts +26 -0
  174. package/dist/simulation.d.ts.map +1 -0
  175. package/dist/simulation.js +46 -0
  176. package/dist/simulation.js.map +1 -0
  177. package/openapi/openapi.json +6262 -3139
  178. package/package.json +18 -8
@@ -2,6 +2,127 @@ import { METADATA_KIND_IDS, METADATA_KIND_REGISTRY, validateMetadataPack, } from
2
2
  import { resolveScope } from "../request-scope.js";
3
3
  import { ServiceError } from "../errors.js";
4
4
  import { listKnownPackIds, loadKnownMetadataPack } from "../known-packs.js";
5
+ import { stripOrgRuntimeSourcesFromPack } from "../org-sources.js";
6
+ import { PACKAGE_CATALOG_ORG, associationsFromPack, buildPackagePayload, catalogAgentId, discoverPackageCatalog, packageVersionMessage, parsePackageMessage, releaseAssociations, resolveOwnerAgent, } from "../magit/package-catalog-bridge.js";
7
+ function requireMagit(platform) {
8
+ if (!platform.magit) {
9
+ throw new ServiceError("MAGIT_UNAVAILABLE", "metadata versioning requires a durable Mongo connection (set METADATA_MAGIT=0 to disable)", 503);
10
+ }
11
+ return platform.magit;
12
+ }
13
+ function lineageFromAgent(platform, agentId) {
14
+ const ledger = platform.metadata.getLedger();
15
+ const latest = [...ledger].reverse().find((e) => e.agentId === agentId);
16
+ if (!latest)
17
+ return null;
18
+ return {
19
+ checksum: latest.checksum,
20
+ installedAt: latest.installedAt,
21
+ magitCommit: latest.magitCommit ?? null,
22
+ magitRelease: latest.magitRelease ?? null,
23
+ source: latest.source,
24
+ message: latest.message,
25
+ environment: latest.environment,
26
+ };
27
+ }
28
+ /**
29
+ * Install packs for multiple agents from one Magit commit.
30
+ * On failure, restore already-applied agents to their prior state.
31
+ */
32
+ async function installAgentsAtomically(platform, magit, opts) {
33
+ const priors = [];
34
+ for (const agentId of opts.agentIds) {
35
+ const lineage = lineageFromAgent(platform, agentId);
36
+ const exported = platform.metadata.exportMetadata([agentId]);
37
+ priors.push({
38
+ agentId,
39
+ magitCommit: lineage?.magitCommit ?? null,
40
+ pack: exported.packs[agentId] ?? null,
41
+ });
42
+ }
43
+ const ledgerEntries = [];
44
+ const applied = [];
45
+ try {
46
+ for (const agentId of opts.agentIds) {
47
+ const loaded = await magit.packAtCommit(opts.orgId, agentId, opts.commit);
48
+ const validation = validateMetadataPack(loaded.pack);
49
+ if (!validation.ok) {
50
+ throw new ServiceError("VALIDATION", `pack at commit failed validation for ${agentId}: ${validation.issues
51
+ .map((i) => i.message)
52
+ .join("; ")}`, 400, { issues: validation.issues, agentId });
53
+ }
54
+ const result = platform.metadata.install(loaded.pack, {
55
+ reinstall: true,
56
+ magitCommit: opts.commit,
57
+ ...(opts.magitRelease ? { magitRelease: opts.magitRelease } : {}),
58
+ source: opts.source,
59
+ message: opts.message,
60
+ environment: "live",
61
+ });
62
+ if (!result.ok || !result.ledgerEntry) {
63
+ throw new ServiceError("VALIDATION", result.issues.map((i) => i.message).join("; ") ||
64
+ `bundle install failed for ${agentId}`, 400);
65
+ }
66
+ ledgerEntries.push(result.ledgerEntry);
67
+ applied.push(agentId);
68
+ }
69
+ return {
70
+ installed: true,
71
+ rolledBack: false,
72
+ commit: opts.commit,
73
+ ledgerEntries,
74
+ restoredAgentIds: [],
75
+ };
76
+ }
77
+ catch (err) {
78
+ const restoredAgentIds = [];
79
+ for (const agentId of [...applied].reverse()) {
80
+ const prior = priors.find((p) => p.agentId === agentId);
81
+ if (!prior)
82
+ continue;
83
+ try {
84
+ if (prior.magitCommit) {
85
+ const loaded = await magit.packAtCommit(opts.orgId, agentId, prior.magitCommit);
86
+ platform.metadata.install(loaded.pack, {
87
+ reinstall: true,
88
+ magitCommit: prior.magitCommit,
89
+ source: "rollback",
90
+ message: `Rollback after failed bundle install (${agentId})`,
91
+ environment: "live",
92
+ });
93
+ restoredAgentIds.push(agentId);
94
+ }
95
+ else if (prior.pack) {
96
+ platform.metadata.install(prior.pack, {
97
+ reinstall: true,
98
+ source: "rollback",
99
+ message: `Rollback after failed bundle install (${agentId})`,
100
+ environment: "live",
101
+ });
102
+ restoredAgentIds.push(agentId);
103
+ }
104
+ }
105
+ catch {
106
+ /* best-effort restore */
107
+ }
108
+ }
109
+ const message = err instanceof Error ? err.message : String(err);
110
+ if (err instanceof ServiceError) {
111
+ throw new ServiceError(err.code, `${message} (rolled back: ${restoredAgentIds.join(",") || "none"})`, err.statusCode, {
112
+ rolledBack: true,
113
+ restoredAgentIds,
114
+ });
115
+ }
116
+ return {
117
+ installed: false,
118
+ rolledBack: restoredAgentIds.length > 0,
119
+ commit: opts.commit,
120
+ ledgerEntries: [],
121
+ restoredAgentIds,
122
+ error: message,
123
+ };
124
+ }
125
+ }
5
126
  export async function registerMetadataRoutes(app, platform) {
6
127
  app.get("/api/metadata/packs", async (req) => {
7
128
  const scope = resolveScope(req);
@@ -15,13 +136,15 @@ export async function registerMetadataRoutes(app, platform) {
15
136
  const scope = resolveScope(req);
16
137
  const q = req.query;
17
138
  const agentId = (q.agentId?.trim() || scope.agentIds[0]);
18
- return { scope, agentId, raw: platform.metadata.getRaw(agentId) };
139
+ const raw = platform.metadata.getRaw(agentId);
140
+ const lineage = lineageFromAgent(platform, agentId);
141
+ const exported = platform.metadata.exportMetadata([agentId]);
142
+ const pack = exported.packs[agentId] ?? null;
143
+ return { scope, agentId, raw, lineage, pack };
19
144
  });
20
145
  app.get("/api/metadata/effective", async (req) => {
21
146
  const scope = resolveScope(req);
22
147
  const resolved = platform.metadata.resolveEffective(scope.agentIds);
23
- // Contract: `effective` is always the EffectiveDefinition[] array.
24
- // Inheritance / resolve diagnostics live beside it (never nested as the array).
25
148
  return {
26
149
  scope,
27
150
  ok: resolved.ok,
@@ -36,7 +159,6 @@ export async function registerMetadataRoutes(app, platform) {
36
159
  note: "agentIds select effective metadata only; effective is the resolved definition array",
37
160
  };
38
161
  });
39
- /** List built-in kinds + effective custom kind-declarations for the scope. */
40
162
  app.get("/api/metadata/kinds", async (req) => {
41
163
  const scope = resolveScope(req);
42
164
  const effective = platform.metadata.resolveEffective(scope.agentIds);
@@ -70,6 +192,18 @@ export async function registerMetadataRoutes(app, platform) {
70
192
  const scope = resolveScope(req);
71
193
  return { scope, result: platform.metadata.resolveAbstracts(scope.agentIds) };
72
194
  });
195
+ app.get("/api/metadata/topology", async (req) => {
196
+ const scope = resolveScope(req);
197
+ const topology = platform.metadata.buildTopology(scope.agentIds);
198
+ return {
199
+ scope,
200
+ ok: topology.ok,
201
+ nodes: topology.nodes,
202
+ edges: topology.edges,
203
+ issues: topology.issues,
204
+ note: "Projected concrete topology from effective metadata; author relationships on abstracts",
205
+ };
206
+ });
73
207
  app.post("/api/metadata/validate", async (req) => {
74
208
  const scope = resolveScope(req);
75
209
  const body = req.body;
@@ -84,17 +218,68 @@ export async function registerMetadataRoutes(app, platform) {
84
218
  if (!body?.confirm) {
85
219
  throw new ServiceError("CONFIRMATION_REQUIRED", "explicit confirm:true required for metadata install", 400);
86
220
  }
87
- const pack = body.pack ?? (body.packId ? loadKnownMetadataPack(body.packId) : undefined);
221
+ const agentHint = body.pack?.agentId?.trim() ||
222
+ body.packId?.trim() ||
223
+ scope.agentIds[0] ||
224
+ "";
225
+ let pack = body.pack;
226
+ let magitCommit = body.commit?.trim() || undefined;
227
+ const proposalId = body.proposalId?.trim();
228
+ if (magitCommit) {
229
+ const magit = requireMagit(platform);
230
+ if (!agentHint) {
231
+ throw new ServiceError("VALIDATION", "agentId required with commit", 400);
232
+ }
233
+ const loaded = await magit.packAtCommit(scope.orgId, agentHint, magitCommit);
234
+ pack = loaded.pack;
235
+ magitCommit = loaded.commit;
236
+ }
237
+ else if (!pack && body.packId) {
238
+ pack = loadKnownMetadataPack(body.packId);
239
+ }
88
240
  if (!pack)
89
- throw new ServiceError("VALIDATION", "pack or packId required", 400);
241
+ throw new ServiceError("VALIDATION", "pack, packId, or commit required", 400);
242
+ // Org folder sources are never pack/Magit content — strip before save/install.
243
+ pack = stripOrgRuntimeSourcesFromPack(pack);
90
244
  const validation = validateMetadataPack(pack);
91
245
  if (!validation.ok) {
92
246
  return { scope, result: validation, installed: false, published: false };
93
247
  }
94
- const result = platform.metadata.install(pack, { reinstall: body.reinstall });
248
+ const versionMessage = body.versionMessage?.trim() ||
249
+ (proposalId
250
+ ? `Install proposal ${proposalId}`
251
+ : magitCommit
252
+ ? `Install ${pack.agentId} @ ${magitCommit.slice(0, 12)}`
253
+ : `Install ${pack.agentId}`);
254
+ if (!magitCommit && platform.magit) {
255
+ try {
256
+ const saved = await platform.magit.saveVersion(scope.orgId, pack, {
257
+ message: versionMessage,
258
+ });
259
+ magitCommit = saved.commit;
260
+ }
261
+ catch (err) {
262
+ // Fail closed when Magit is enabled — never silent checksum-only install.
263
+ throw err instanceof ServiceError
264
+ ? err
265
+ : new ServiceError("MAGIT_UNAVAILABLE", err instanceof Error ? err.message : String(err), 503);
266
+ }
267
+ }
268
+ const source = proposalId
269
+ ? "proposal-install"
270
+ : "install";
271
+ const result = platform.metadata.install(pack, {
272
+ reinstall: body.reinstall,
273
+ source,
274
+ message: versionMessage,
275
+ environment: "live",
276
+ ...(magitCommit ? { magitCommit } : {}),
277
+ });
95
278
  return {
96
279
  scope,
97
280
  packId: body.packId ?? pack.agentId,
281
+ proposalId: proposalId || undefined,
282
+ commit: magitCommit,
98
283
  result,
99
284
  installed: Boolean(result.ok),
100
285
  published: false,
@@ -107,24 +292,221 @@ export async function registerMetadataRoutes(app, platform) {
107
292
  note: "intelligence proposals are never auto-installed",
108
293
  };
109
294
  });
295
+ app.post("/api/metadata/proposals/:id/stage", async (req) => {
296
+ const scope = resolveScope(req);
297
+ const magit = requireMagit(platform);
298
+ const { id: proposalId } = req.params;
299
+ const body = (req.body ?? {});
300
+ let proposal = body.proposal
301
+ ? {
302
+ proposalId: body.proposal.proposalId?.trim() || proposalId,
303
+ metadataKind: body.proposal.metadataKind,
304
+ metadataId: body.proposal.metadataId,
305
+ draft: body.proposal.draft,
306
+ scope: body.proposal.scope,
307
+ }
308
+ : null;
309
+ if (!proposal) {
310
+ if (!platform.client) {
311
+ throw new ServiceError("DURABLE_STORE_REQUIRED", "proposal staging requires durable intelligence store or body.proposal", 503);
312
+ }
313
+ try {
314
+ const stored = await platform
315
+ .intelligenceArtifactsFor(scope.orgId)
316
+ .getProposal(proposalId);
317
+ if (!stored) {
318
+ throw new ServiceError("NOT_FOUND", `proposal not found: ${proposalId}`, 404);
319
+ }
320
+ proposal = {
321
+ proposalId: stored.proposalId,
322
+ metadataKind: stored.metadataKind,
323
+ metadataId: stored.metadataId,
324
+ draft: stored.draft,
325
+ scope: stored.scope,
326
+ };
327
+ }
328
+ catch (err) {
329
+ if (err instanceof ServiceError)
330
+ throw err;
331
+ throw new ServiceError("VALIDATION", `failed to load proposal ${proposalId}: ${err instanceof Error ? err.message : String(err)}`, 400);
332
+ }
333
+ }
334
+ const agentId = body.agentId?.trim() ||
335
+ proposal.scope?.agentIds?.[0]?.trim() ||
336
+ scope.agentIds[0] ||
337
+ "";
338
+ if (!agentId)
339
+ throw new ServiceError("VALIDATION", "agentId required", 400);
340
+ const exported = platform.metadata.exportMetadata([agentId]);
341
+ const basePack = exported.packs[agentId] ?? null;
342
+ const staged = await magit.importProposal(scope.orgId, {
343
+ agentId,
344
+ proposal,
345
+ basePack,
346
+ });
347
+ const validation = validateMetadataPack(staged.pack);
348
+ return {
349
+ scope,
350
+ proposalId: proposal.proposalId,
351
+ agentId,
352
+ commit: staged.commit,
353
+ checksum: staged.checksum,
354
+ reused: staged.reused,
355
+ pack: staged.pack,
356
+ validation,
357
+ installed: false,
358
+ note: "stage saves a Magit version only — live metadata unchanged until explicit install",
359
+ };
360
+ });
361
+ app.post("/api/metadata/install/bundle", async (req) => {
362
+ const scope = resolveScope(req);
363
+ const magit = requireMagit(platform);
364
+ const body = req.body;
365
+ if (!body?.confirm) {
366
+ throw new ServiceError("CONFIRMATION_REQUIRED", "explicit confirm:true required for bundle install", 400);
367
+ }
368
+ const commit = body.commit?.trim();
369
+ if (!commit)
370
+ throw new ServiceError("VALIDATION", "commit required", 400);
371
+ const agentIds = body.agentIds?.map((a) => a.trim()).filter(Boolean) ?? [...scope.agentIds];
372
+ if (!agentIds.length) {
373
+ throw new ServiceError("VALIDATION", "agentIds required", 400);
374
+ }
375
+ const message = body.message?.trim() ||
376
+ `Bundle install ${agentIds.join("+")} @ ${commit.slice(0, 12)}`;
377
+ const release = body.release?.trim();
378
+ const result = await installAgentsAtomically(platform, magit, {
379
+ orgId: scope.orgId,
380
+ agentIds,
381
+ commit,
382
+ message,
383
+ source: release ? "publish" : "bundle-install",
384
+ magitRelease: release,
385
+ });
386
+ return { scope, ...result };
387
+ });
388
+ app.post("/api/metadata/publish/plan", async (req) => {
389
+ const scope = resolveScope(req);
390
+ const magit = requireMagit(platform);
391
+ const body = req.body;
392
+ const release = body.release?.trim();
393
+ const commit = body.commit?.trim();
394
+ if (!release)
395
+ throw new ServiceError("VALIDATION", "release required", 400);
396
+ if (!commit)
397
+ throw new ServiceError("VALIDATION", "commit required", 400);
398
+ const agentIds = body.agentIds?.map((a) => a.trim()).filter(Boolean) ??
399
+ (body.agentId?.trim() ? [body.agentId.trim()] : scope.agentIds);
400
+ const plan = await magit.publishPlan(scope.orgId, {
401
+ release,
402
+ commit,
403
+ agentIds,
404
+ });
405
+ return { scope, plan, note: "publish plan is read-only; confirm via POST /api/metadata/publish" };
406
+ });
110
407
  app.post("/api/metadata/publish", async (req) => {
111
408
  const scope = resolveScope(req);
112
409
  const body = req.body;
113
410
  if (!body?.confirm) {
114
411
  throw new ServiceError("CONFIRMATION_REQUIRED", "explicit confirm:true required for metadata publish", 400);
115
412
  }
116
- return { scope, published: true, note: "publish is explicit" };
413
+ const magit = requireMagit(platform);
414
+ const release = body.release?.trim();
415
+ const commit = body.commit?.trim();
416
+ if (!release)
417
+ throw new ServiceError("VALIDATION", "release required", 400);
418
+ if (!commit)
419
+ throw new ServiceError("VALIDATION", "commit required", 400);
420
+ const agentIds = body.agentIds?.map((a) => a.trim()).filter(Boolean) ??
421
+ (body.agentId?.trim() ? [body.agentId.trim()] : scope.agentIds);
422
+ if (!agentIds.length) {
423
+ throw new ServiceError("VALIDATION", "agentIds required", 400);
424
+ }
425
+ const plan = await magit.publishPlan(scope.orgId, { release, commit, agentIds });
426
+ if (body.planHash?.trim() && body.planHash.trim() !== plan.planHash) {
427
+ throw new ServiceError("VALIDATION", "planHash mismatch — re-run publish plan", 409);
428
+ }
429
+ const now = new Date().toISOString();
430
+ const message = body.message?.trim() || `Publish ${release}`;
431
+ const applied = await installAgentsAtomically(platform, magit, {
432
+ orgId: scope.orgId,
433
+ agentIds,
434
+ commit,
435
+ message,
436
+ source: agentIds.length > 1 ? "bundle-install" : "publish",
437
+ magitRelease: release,
438
+ });
439
+ if (!applied.installed) {
440
+ throw new ServiceError("VALIDATION", applied.error || "publish install failed", 400, { restoredAgentIds: applied.restoredAgentIds });
441
+ }
442
+ await magit.recordRelease(scope.orgId, {
443
+ name: release,
444
+ commit,
445
+ agentIds,
446
+ createdAt: now,
447
+ message,
448
+ });
449
+ return {
450
+ scope,
451
+ published: true,
452
+ release,
453
+ commit,
454
+ planHash: plan.planHash,
455
+ ledgerEntries: applied.ledgerEntries,
456
+ note: "publish installed packs reconstructed from Magit commit",
457
+ };
117
458
  });
118
- /** Save a pack version (Magit proposePatchset) — not live. Requires METADATA_MAGIT=1 + isolation. */
119
- app.post("/api/metadata/versions", async (req) => {
459
+ app.post("/api/metadata/rollback", async (req) => {
120
460
  const scope = resolveScope(req);
121
- if (!platform.magit) {
122
- throw new ServiceError("MAGIT_UNAVAILABLE", "metadata versioning requires METADATA_MAGIT=1 and org isolation", 503);
461
+ const magit = requireMagit(platform);
462
+ const body = req.body;
463
+ if (!body?.confirm) {
464
+ throw new ServiceError("CONFIRMATION_REQUIRED", "explicit confirm:true required for metadata rollback", 400);
123
465
  }
466
+ const agentId = (body.agentId?.trim() || scope.agentIds[0]);
467
+ const commit = body.commit?.trim();
468
+ if (!commit)
469
+ throw new ServiceError("VALIDATION", "commit required", 400);
470
+ const integrity = await magit.diff(scope.orgId, agentId, {
471
+ from: "live",
472
+ to: commit,
473
+ });
474
+ const loaded = await magit.packAtCommit(scope.orgId, agentId, commit);
475
+ const restoredPack = stripOrgRuntimeSourcesFromPack(loaded.pack);
476
+ const validation = validateMetadataPack(restoredPack);
477
+ if (!validation.ok) {
478
+ throw new ServiceError("VALIDATION", "pack at commit failed validation", 400, { issues: validation.issues });
479
+ }
480
+ const message = body.message?.trim() || `Restore ${agentId} to ${commit.slice(0, 12)}`;
481
+ const result = platform.metadata.install(restoredPack, {
482
+ reinstall: true,
483
+ magitCommit: commit,
484
+ magitRelease: undefined,
485
+ source: "rollback",
486
+ message,
487
+ environment: "live",
488
+ });
489
+ if (!result.ok) {
490
+ throw new ServiceError("VALIDATION", result.issues.map((i) => i.message).join("; ") || "restore install failed", 400);
491
+ }
492
+ return {
493
+ scope,
494
+ restored: true,
495
+ agentId,
496
+ commit,
497
+ integrity,
498
+ result,
499
+ note: "restore installed pack reconstructed from Magit commit",
500
+ };
501
+ });
502
+ app.post("/api/metadata/versions", async (req) => {
503
+ const scope = resolveScope(req);
504
+ const magit = requireMagit(platform);
124
505
  const body = req.body;
125
- const pack = body.pack ?? (body.packId ? loadKnownMetadataPack(body.packId) : undefined);
126
- if (!pack)
506
+ const rawPack = body.pack ?? (body.packId ? loadKnownMetadataPack(body.packId) : undefined);
507
+ if (!rawPack)
127
508
  throw new ServiceError("VALIDATION", "pack or packId required", 400);
509
+ const pack = stripOrgRuntimeSourcesFromPack(rawPack);
128
510
  const message = body.message?.trim();
129
511
  if (!message) {
130
512
  throw new ServiceError("VALIDATION", "message required", 400);
@@ -133,7 +515,7 @@ export async function registerMetadataRoutes(app, platform) {
133
515
  if (!validation.ok) {
134
516
  return { scope, result: validation, saved: false };
135
517
  }
136
- const saved = await platform.magit.saveVersion(scope.orgId, pack, { message });
518
+ const saved = await magit.saveVersion(scope.orgId, pack, { message });
137
519
  return {
138
520
  scope,
139
521
  saved: true,
@@ -141,23 +523,69 @@ export async function registerMetadataRoutes(app, platform) {
141
523
  checksum: saved.checksum,
142
524
  reused: saved.reused,
143
525
  agentId: pack.agentId,
144
- note: "save version is not install; live metadata unchanged",
526
+ note: "save version is not install; live metadata unchanged; org folder sources stripped",
145
527
  };
146
528
  });
147
- /** List saved pack versions for an agent (Magit proposal ledger + HEAD). */
148
529
  app.get("/api/metadata/versions", async (req) => {
149
530
  const scope = resolveScope(req);
150
- if (!platform.magit) {
151
- throw new ServiceError("MAGIT_UNAVAILABLE", "metadata versioning requires METADATA_MAGIT=1 and org isolation", 503);
152
- }
531
+ const magit = requireMagit(platform);
153
532
  const q = req.query;
154
533
  const agentId = (q.agentId?.trim() || scope.agentIds[0]);
534
+ // Lazy backfill: checksum-only installs get an initial Magit snapshot once.
535
+ const lineage = lineageFromAgent(platform, agentId);
536
+ if (lineage && !lineage.magitCommit) {
537
+ const pack = platform.metadata.exportMetadata([agentId]).packs[agentId];
538
+ if (pack) {
539
+ const saved = await magit.backfillLineage(scope.orgId, pack);
540
+ platform.stampAgentLineage(agentId, { magitCommit: saved.commit });
541
+ platform.appendInstallLedger({
542
+ agentId,
543
+ checksum: lineage.checksum,
544
+ installedAt: new Date().toISOString(),
545
+ definitionCount: 0,
546
+ noop: true,
547
+ magitCommit: saved.commit,
548
+ source: "install",
549
+ message: "backfill: initial snapshot",
550
+ environment: "live",
551
+ previousChecksum: lineage.checksum,
552
+ });
553
+ }
554
+ }
155
555
  const maxCount = q.maxCount ? Number(q.maxCount) : undefined;
156
- const versions = await platform.magit.history(scope.orgId, agentId, {
556
+ const versions = await magit.history(scope.orgId, agentId, {
157
557
  maxCount: Number.isFinite(maxCount) ? maxCount : undefined,
158
558
  });
159
559
  return { scope, agentId, versions };
160
560
  });
561
+ app.get("/api/metadata/versions/:commit", async (req) => {
562
+ const scope = resolveScope(req);
563
+ const magit = requireMagit(platform);
564
+ const { commit } = req.params;
565
+ const q = req.query;
566
+ const agentId = (q.agentId?.trim() || scope.agentIds[0]);
567
+ const loaded = await magit.packAtCommit(scope.orgId, agentId, commit);
568
+ return {
569
+ scope,
570
+ agentId,
571
+ commit: loaded.commit,
572
+ checksum: loaded.checksum,
573
+ pack: loaded.pack,
574
+ };
575
+ });
576
+ app.post("/api/metadata/diff", async (req) => {
577
+ const scope = resolveScope(req);
578
+ const magit = requireMagit(platform);
579
+ const body = req.body;
580
+ const agentId = (body.agentId?.trim() || scope.agentIds[0]);
581
+ const from = body.from?.trim();
582
+ const to = body.to?.trim();
583
+ if (!from || !to) {
584
+ throw new ServiceError("VALIDATION", "from and to required", 400);
585
+ }
586
+ const diff = await magit.diff(scope.orgId, agentId, { from, to });
587
+ return { scope, ...diff };
588
+ });
161
589
  app.get("/api/metadata/definition", async (req) => {
162
590
  const scope = resolveScope(req);
163
591
  const q = req.query;
@@ -167,5 +595,326 @@ export async function registerMetadataRoutes(app, platform) {
167
595
  const def = platform.metadata.getDefinition(scope.agentIds, q.kind, q.id);
168
596
  return { scope, definition: def };
169
597
  });
598
+ // ---------------------------------------------------------------------------
599
+ // Package catalog bridge (FR-CPS interim — org-free Pack; org required on Restore)
600
+ // Spec: .operational/magit-central-package-storage-FR.md
601
+ // ---------------------------------------------------------------------------
602
+ function installedPacks() {
603
+ return platform.metadata.exportMetadata().packs;
604
+ }
605
+ function parseKind(raw) {
606
+ const k = typeof raw === "string" ? raw.trim() : "";
607
+ if (k === "agent" || k === "connector" || k === "service")
608
+ return k;
609
+ throw new ServiceError("VALIDATION", "kind must be agent | connector | service", 400);
610
+ }
611
+ app.get("/api/metadata/packages", async (req) => {
612
+ requireMagit(platform);
613
+ const q = req.query;
614
+ const kindFilter = q.kind?.trim() && q.kind.trim() !== "all"
615
+ ? parseKind(q.kind)
616
+ : undefined;
617
+ const catalog = discoverPackageCatalog(installedPacks()).filter((e) => kindFilter ? e.kind === kindFilter : true);
618
+ return {
619
+ packages: catalog,
620
+ interim: true,
621
+ catalogOrg: PACKAGE_CATALOG_ORG,
622
+ note: "Interim local catalog from installed packs. Central org-free Magit storage: FR-CPS.",
623
+ };
624
+ });
625
+ app.get("/api/metadata/packages/:kind/:id/associations", async (req) => {
626
+ requireMagit(platform);
627
+ const kind = parseKind(req.params.kind);
628
+ const id = String(req.params.id ?? "").trim();
629
+ if (!id)
630
+ throw new ServiceError("VALIDATION", "id required", 400);
631
+ const packs = installedPacks();
632
+ const q = req.query;
633
+ const agentId = resolveOwnerAgent(packs, kind, id, q.agentId);
634
+ const pack = packs[agentId];
635
+ if (!pack) {
636
+ throw new ServiceError("NOT_FOUND", `No installed pack for agent ${agentId}`, 404);
637
+ }
638
+ return {
639
+ kind,
640
+ id,
641
+ agentId,
642
+ associations: associationsFromPack(pack),
643
+ interim: true,
644
+ };
645
+ });
646
+ app.get("/api/metadata/packages/:kind/:id/versions", async (req) => {
647
+ const magit = requireMagit(platform);
648
+ const kind = parseKind(req.params.kind);
649
+ const id = String(req.params.id ?? "").trim();
650
+ if (!id)
651
+ throw new ServiceError("VALIDATION", "id required", 400);
652
+ const q = req.query;
653
+ const packs = installedPacks();
654
+ let ownerAgentId;
655
+ try {
656
+ ownerAgentId = resolveOwnerAgent(packs, kind, id, q.agentId);
657
+ }
658
+ catch {
659
+ ownerAgentId = kind === "agent" ? id : q.agentId?.trim() || "";
660
+ }
661
+ const sliceAgentId = catalogAgentId(kind, id, ownerAgentId || undefined);
662
+ const maxCount = q.maxCount ? Number(q.maxCount) : 50;
663
+ const versions = await magit.history(PACKAGE_CATALOG_ORG, sliceAgentId, {
664
+ maxCount: Number.isFinite(maxCount) ? maxCount : 50,
665
+ });
666
+ const filtered = versions.map((v) => {
667
+ const parsed = parsePackageMessage(v.message);
668
+ return {
669
+ ...v,
670
+ packageKind: parsed.kind ?? kind,
671
+ packageId: parsed.id ?? id,
672
+ mode: parsed.mode,
673
+ displayMessage: parsed.message || v.message,
674
+ };
675
+ });
676
+ return {
677
+ kind,
678
+ id,
679
+ agentId: ownerAgentId || id,
680
+ catalogAgentId: sliceAgentId,
681
+ versions: filtered,
682
+ interim: true,
683
+ catalogOrg: PACKAGE_CATALOG_ORG,
684
+ note: "Versions from interim package catalog Magit repo (not runtime org).",
685
+ };
686
+ });
687
+ app.post("/api/metadata/packages/pack", async (req) => {
688
+ const magit = requireMagit(platform);
689
+ const body = req.body;
690
+ const kind = parseKind(body.kind);
691
+ const id = body.id?.trim();
692
+ if (!id)
693
+ throw new ServiceError("VALIDATION", "id required", 400);
694
+ const message = body.message?.trim();
695
+ if (!message)
696
+ throw new ServiceError("VALIDATION", "message required", 400);
697
+ const packs = installedPacks();
698
+ let agentId;
699
+ try {
700
+ agentId = resolveOwnerAgent(packs, kind, id, body.agentId);
701
+ }
702
+ catch (e) {
703
+ throw new ServiceError("NOT_FOUND", e instanceof Error ? e.message : String(e), 404);
704
+ }
705
+ const live = packs[agentId];
706
+ if (!live) {
707
+ throw new ServiceError("NOT_FOUND", `No installed pack for agent ${agentId}`, 404);
708
+ }
709
+ const mode = kind === "agent" ? (body.mode === "narrow" ? "narrow" : "full") : undefined;
710
+ const payload = buildPackagePayload(live, {
711
+ kind,
712
+ id,
713
+ mode,
714
+ includeConnectorIds: body.includeConnectorIds,
715
+ includeServiceIds: body.includeServiceIds,
716
+ });
717
+ const validation = validateMetadataPack(payload);
718
+ if (!validation.ok) {
719
+ return { packed: false, result: validation, interim: true };
720
+ }
721
+ const saved = await magit.saveVersion(PACKAGE_CATALOG_ORG, payload, {
722
+ message: packageVersionMessage(kind, id, message, mode),
723
+ });
724
+ const associations = kind === "agent" && mode
725
+ ? releaseAssociations(live, mode, body.includeConnectorIds, body.includeServiceIds)
726
+ : undefined;
727
+ // Full agent pack also snapshots selected connector/service packages.
728
+ const bundled = [];
729
+ if (kind === "agent" && mode === "full" && associations) {
730
+ for (const connectorId of associations.connectorIds) {
731
+ const slice = buildPackagePayload(live, { kind: "connector", id: connectorId });
732
+ const ok = validateMetadataPack(slice);
733
+ if (!ok.ok)
734
+ continue;
735
+ const b = await magit.saveVersion(PACKAGE_CATALOG_ORG, slice, {
736
+ message: packageVersionMessage("connector", connectorId, `bundled with agent ${id}: ${message}`),
737
+ });
738
+ bundled.push({ kind: "connector", id: connectorId, commit: b.commit });
739
+ }
740
+ for (const serviceId of associations.serviceIds) {
741
+ const slice = buildPackagePayload(live, { kind: "service", id: serviceId });
742
+ const ok = validateMetadataPack(slice);
743
+ if (!ok.ok)
744
+ continue;
745
+ const b = await magit.saveVersion(PACKAGE_CATALOG_ORG, slice, {
746
+ message: packageVersionMessage("service", serviceId, `bundled with agent ${id}: ${message}`),
747
+ });
748
+ bundled.push({ kind: "service", id: serviceId, commit: b.commit });
749
+ }
750
+ }
751
+ return {
752
+ packed: true,
753
+ kind,
754
+ id,
755
+ agentId,
756
+ mode: mode ?? null,
757
+ associations,
758
+ bundled,
759
+ commit: saved.commit,
760
+ version: saved.commit,
761
+ checksum: saved.checksum,
762
+ reused: saved.reused,
763
+ interim: true,
764
+ catalogOrg: PACKAGE_CATALOG_ORG,
765
+ note: "Pack stored in interim Magit catalog (not live). Central storage: FR-CPS.",
766
+ };
767
+ });
768
+ app.post("/api/metadata/packages/restore", async (req) => {
769
+ const scope = resolveScope(req);
770
+ const magit = requireMagit(platform);
771
+ const body = req.body;
772
+ if (!body?.confirm) {
773
+ throw new ServiceError("CONFIRMATION_REQUIRED", "explicit confirm:true required for package restore", 400);
774
+ }
775
+ if (!scope.orgId?.trim()) {
776
+ throw new ServiceError("VALIDATION", "x-memorix-org-id required — org is the restore target, not package identity", 400);
777
+ }
778
+ const kind = parseKind(body.kind);
779
+ const id = body.id?.trim();
780
+ if (!id)
781
+ throw new ServiceError("VALIDATION", "id required", 400);
782
+ const version = (body.version ?? body.commit)?.trim();
783
+ if (!version)
784
+ throw new ServiceError("VALIDATION", "version required", 400);
785
+ const packs = installedPacks();
786
+ let agentId;
787
+ try {
788
+ agentId = resolveOwnerAgent(packs, kind, id, body.agentId);
789
+ }
790
+ catch {
791
+ agentId = kind === "agent" ? id : body.agentId?.trim() || "";
792
+ }
793
+ if (!agentId) {
794
+ throw new ServiceError("VALIDATION", "agentId required to restore connector/service into an agent pack", 400);
795
+ }
796
+ const sliceAgentId = catalogAgentId(kind, id, agentId);
797
+ const loaded = await magit.packAtCommit(PACKAGE_CATALOG_ORG, sliceAgentId, version);
798
+ let installPack = loaded.pack;
799
+ // Connector/service restore merges slice into current live agent pack.
800
+ if (kind === "connector" || kind === "service") {
801
+ const live = packs[agentId] ?? emptyPackForRestore(agentId);
802
+ if (kind === "connector") {
803
+ const keepRefs = new Set((loaded.pack.sources ?? [])
804
+ .map((s) => s && typeof s === "object" && "connectorRef" in s
805
+ ? String(s.connectorRef ?? "")
806
+ : "")
807
+ .filter(Boolean));
808
+ const otherSources = (live.sources ?? []).filter((s) => {
809
+ const ref = s && typeof s === "object" && "connectorRef" in s
810
+ ? String(s.connectorRef ?? "")
811
+ : "";
812
+ return !keepRefs.has(ref);
813
+ });
814
+ installPack = {
815
+ ...live,
816
+ agentId,
817
+ sources: [...otherSources, ...(loaded.pack.sources ?? [])],
818
+ };
819
+ }
820
+ else {
821
+ const svcId = id;
822
+ const otherServices = (live.services ?? []).filter((s) => !(s && typeof s === "object" && "id" in s && String(s.id) === svcId));
823
+ installPack = {
824
+ ...live,
825
+ agentId,
826
+ services: [...otherServices, ...(loaded.pack.services ?? [])],
827
+ };
828
+ }
829
+ }
830
+ installPack = stripOrgRuntimeSourcesFromPack(installPack);
831
+ const validation = validateMetadataPack(installPack);
832
+ if (!validation.ok) {
833
+ throw new ServiceError("VALIDATION", "pack at version failed validation", 400, { issues: validation.issues });
834
+ }
835
+ const message = body.message?.trim() ||
836
+ `Restore ${kind}:${id} @ ${version.slice(0, 12)} into org ${scope.orgId}`;
837
+ const result = platform.metadata.install(installPack, {
838
+ reinstall: true,
839
+ magitCommit: version,
840
+ magitRelease: undefined,
841
+ source: "rollback",
842
+ message,
843
+ environment: "live",
844
+ });
845
+ if (!result.ok) {
846
+ throw new ServiceError("VALIDATION", result.issues.map((i) => i.message).join("; ") || "restore install failed", 400);
847
+ }
848
+ return {
849
+ restored: true,
850
+ kind,
851
+ id,
852
+ agentId,
853
+ version,
854
+ targetOrgId: scope.orgId,
855
+ result,
856
+ interim: true,
857
+ catalogOrg: PACKAGE_CATALOG_ORG,
858
+ note: "Restored from interim Magit catalog into this environment. Org is restore target only.",
859
+ };
860
+ });
861
+ app.post("/api/metadata/packages/diff", async (req) => {
862
+ const magit = requireMagit(platform);
863
+ const body = req.body;
864
+ const kind = parseKind(body.kind);
865
+ const id = body.id?.trim();
866
+ if (!id)
867
+ throw new ServiceError("VALIDATION", "id required", 400);
868
+ const from = body.from?.trim();
869
+ const to = body.to?.trim();
870
+ if (!from || !to) {
871
+ throw new ServiceError("VALIDATION", "from and to required", 400);
872
+ }
873
+ const packs = installedPacks();
874
+ let agentId;
875
+ try {
876
+ agentId = resolveOwnerAgent(packs, kind, id, body.agentId);
877
+ }
878
+ catch {
879
+ agentId = kind === "agent" ? id : body.agentId?.trim() || id;
880
+ }
881
+ const sliceAgentId = catalogAgentId(kind, id, agentId);
882
+ // "installed" sentinel → live for Magit diff (same Mongo metadata DB)
883
+ const fromRef = from === "installed" ? "live" : from;
884
+ const toRef = to === "installed" ? "live" : to;
885
+ const diff = await magit.diff(PACKAGE_CATALOG_ORG, sliceAgentId, {
886
+ from: fromRef,
887
+ to: toRef,
888
+ });
889
+ return {
890
+ ...diff,
891
+ kind,
892
+ id,
893
+ agentId,
894
+ catalogAgentId: sliceAgentId,
895
+ interim: true,
896
+ note: "Compare package versions or version vs installed. Not env→env copy.",
897
+ };
898
+ });
899
+ }
900
+ function emptyPackForRestore(agentId) {
901
+ return {
902
+ format: "memorix-metadata/1",
903
+ agentId,
904
+ agents: [],
905
+ objectTypes: [],
906
+ abstractTypes: [],
907
+ abstractBindings: [],
908
+ relationshipDefinitions: [],
909
+ mappings: [],
910
+ views: [],
911
+ writes: [],
912
+ sources: [],
913
+ services: [],
914
+ pipelines: [],
915
+ schedules: [],
916
+ kindDeclarations: [],
917
+ extensions: {},
918
+ };
170
919
  }
171
920
  //# sourceMappingURL=metadata.js.map