yaml-flow 5.1.0 → 5.2.1

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 (105) hide show
  1. package/{examples/example-board/reusable-server-runtime.js → board-livecards-server-runtime.js} +42 -20
  2. package/{examples/example-board/reusable-board-runtime-client.js → browser/board-livecards-runtime-client.js} +6 -2
  3. package/browser/{board-livegraph-runtime.js → board-livegraph-engine.js} +212 -16
  4. package/browser/board-livegraph-engine.js.map +1 -0
  5. package/browser/live-cards.js +362 -38
  6. package/browser/live-cards.schema.json +20 -4
  7. package/dist/board-livegraph-runtime/index.cjs +210 -14
  8. package/dist/board-livegraph-runtime/index.cjs.map +1 -1
  9. package/dist/board-livegraph-runtime/index.d.cts +49 -5
  10. package/dist/board-livegraph-runtime/index.d.ts +49 -5
  11. package/dist/board-livegraph-runtime/index.js +209 -15
  12. package/dist/board-livegraph-runtime/index.js.map +1 -1
  13. package/dist/card-compute/index.cjs +63 -7
  14. package/dist/card-compute/index.cjs.map +1 -1
  15. package/dist/card-compute/index.d.cts +2 -2
  16. package/dist/card-compute/index.d.ts +2 -2
  17. package/dist/card-compute/index.js +63 -7
  18. package/dist/card-compute/index.js.map +1 -1
  19. package/dist/cli/board-live-cards-cli.cjs +664 -75
  20. package/dist/cli/board-live-cards-cli.cjs.map +1 -1
  21. package/dist/cli/board-live-cards-cli.d.cts +33 -5
  22. package/dist/cli/board-live-cards-cli.d.ts +33 -5
  23. package/dist/cli/board-live-cards-cli.js +661 -76
  24. package/dist/cli/board-live-cards-cli.js.map +1 -1
  25. package/dist/{constants-ozjf1Ejw.d.cts → constants-BzZUyYlp.d.cts} +1 -1
  26. package/dist/{constants-DuzE5n03.d.ts → constants-oCEbNpul.d.ts} +1 -1
  27. package/dist/continuous-event-graph/index.cjs +47 -14
  28. package/dist/continuous-event-graph/index.cjs.map +1 -1
  29. package/dist/continuous-event-graph/index.d.cts +9 -9
  30. package/dist/continuous-event-graph/index.d.ts +9 -9
  31. package/dist/continuous-event-graph/index.js +47 -14
  32. package/dist/continuous-event-graph/index.js.map +1 -1
  33. package/dist/event-graph/index.cjs +29 -12
  34. package/dist/event-graph/index.cjs.map +1 -1
  35. package/dist/event-graph/index.d.cts +5 -5
  36. package/dist/event-graph/index.d.ts +5 -5
  37. package/dist/event-graph/index.js +29 -12
  38. package/dist/event-graph/index.js.map +1 -1
  39. package/dist/index.cjs +93 -20
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +7 -7
  42. package/dist/index.d.ts +7 -7
  43. package/dist/index.js +93 -20
  44. package/dist/index.js.map +1 -1
  45. package/dist/inference/index.cjs +29 -12
  46. package/dist/inference/index.cjs.map +1 -1
  47. package/dist/inference/index.d.cts +2 -2
  48. package/dist/inference/index.d.ts +2 -2
  49. package/dist/inference/index.js +29 -12
  50. package/dist/inference/index.js.map +1 -1
  51. package/dist/{journal-NLYuqege.d.ts → journal-9HEgs7dU.d.ts} +1 -1
  52. package/dist/{journal-DRfJiheM.d.cts → journal-B-JCfQnh.d.cts} +1 -1
  53. package/dist/{live-cards-bridge-Or7fdEJV.d.ts → live-cards-bridge-CeNxiVcm.d.ts} +6 -2
  54. package/dist/{live-cards-bridge-vGJ6tMzN.d.cts → live-cards-bridge-z_rJCSbi.d.cts} +6 -2
  55. package/dist/{schedule-CMcZe5Ny.d.ts → schedule-Cszq9LYY.d.ts} +1 -1
  56. package/dist/{schedule-CiucyCan.d.cts → schedule-qWNL0RQh.d.cts} +1 -1
  57. package/dist/{types-CMFSIjpc.d.cts → types-BBhqYGhE.d.cts} +4 -0
  58. package/dist/{types-CMFSIjpc.d.ts → types-BBhqYGhE.d.ts} +4 -0
  59. package/dist/{types-BzLD8bjb.d.cts → types-CHSdoAAA.d.cts} +1 -1
  60. package/dist/{types-C2eJ7DAV.d.ts → types-CoW0gQl3.d.ts} +1 -1
  61. package/dist/{validate-DJQTQ6bP.d.ts → validate-BAVzUJWa.d.ts} +1 -1
  62. package/dist/{validate-ke92Cleg.d.cts → validate-Dbu7ygys.d.cts} +1 -1
  63. package/examples/browser/boards/portfolio-tracker/cards/portfolio-risk-assessment.json +28 -0
  64. package/examples/browser/boards/portfolio-tracker/cards/rebalancing-strategy.json +28 -0
  65. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-inference-adapter.js +187 -0
  66. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.js +139 -5
  67. package/examples/example-board/agent-instructions-cardlayout.md +28 -0
  68. package/examples/example-board/agent-instructions.md +603 -0
  69. package/examples/example-board/cards/card-concentration.json +42 -0
  70. package/examples/example-board/cards/card-market-prices.json +51 -0
  71. package/examples/example-board/cards/card-portfolio-action.json +19 -0
  72. package/examples/example-board/cards/card-portfolio-risks.json +19 -0
  73. package/examples/example-board/cards/card-portfolio-value.json +62 -0
  74. package/examples/example-board/cards/card-portfolio.json +44 -0
  75. package/examples/example-board/demo-chat-handler.js +373 -33
  76. package/examples/example-board/demo-server-config.json +0 -2
  77. package/examples/example-board/demo-server.js +46 -7
  78. package/examples/example-board/demo-shell-browser.html +75 -207
  79. package/examples/example-board/demo-shell-with-server.html +15 -9
  80. package/examples/example-board/demo-shell.html +1 -1
  81. package/examples/example-board/demo-task-executor.js +259 -41
  82. package/package.json +6 -2
  83. package/schema/live-cards.schema.json +20 -4
  84. package/browser/board-livegraph-runtime.js.map +0 -1
  85. package/examples/example-board/board.yaml +0 -23
  86. package/examples/example-board/bootstrap_payload.json +0 -1
  87. package/examples/example-board/cards/card-chain-region-alert.json +0 -39
  88. package/examples/example-board/cards/card-chain-region-totals.json +0 -26
  89. package/examples/example-board/cards/card-chain-top-region.json +0 -24
  90. package/examples/example-board/cards/card-ex-actions.json +0 -32
  91. package/examples/example-board/cards/card-ex-chart.json +0 -30
  92. package/examples/example-board/cards/card-ex-filter.json +0 -36
  93. package/examples/example-board/cards/card-ex-filtered-by-preference.json +0 -59
  94. package/examples/example-board/cards/card-ex-form.json +0 -91
  95. package/examples/example-board/cards/card-ex-list.json +0 -22
  96. package/examples/example-board/cards/card-ex-markdown.json +0 -17
  97. package/examples/example-board/cards/card-ex-metric.json +0 -19
  98. package/examples/example-board/cards/card-ex-narrative.json +0 -36
  99. package/examples/example-board/cards/card-ex-source-http.json +0 -28
  100. package/examples/example-board/cards/card-ex-source.json +0 -21
  101. package/examples/example-board/cards/card-ex-status.json +0 -35
  102. package/examples/example-board/cards/card-ex-table.json +0 -30
  103. package/examples/example-board/cards/card-ex-todo.json +0 -29
  104. package/examples/example-board/mock.db +0 -15
  105. package/examples/example-board/reusable-runtime-artifacts-adapter.js +0 -233
@@ -1,7 +1,7 @@
1
- import { G as GraphConfig, f as GraphEvent } from '../types-CMFSIjpc.cjs';
2
- import { L as LiveGraph } from '../types-BzLD8bjb.cjs';
3
- import { s as schedule } from '../schedule-CiucyCan.cjs';
4
- import { R as ReactiveGraph, a as LiveCard, e as TaskHandlerInput, d as ReactiveGraphOptions, L as LiveBoard } from '../live-cards-bridge-vGJ6tMzN.cjs';
1
+ import { G as GraphConfig, f as GraphEvent } from '../types-BBhqYGhE.cjs';
2
+ import { L as LiveGraph } from '../types-CHSdoAAA.cjs';
3
+ import { s as schedule } from '../schedule-qWNL0RQh.cjs';
4
+ import { R as ReactiveGraph, a as LiveCard, e as TaskHandlerInput, d as ReactiveGraphOptions, L as LiveBoard } from '../live-cards-bridge-z_rJCSbi.cjs';
5
5
 
6
6
  interface BrowserSourceAdapterContext {
7
7
  card: LiveCard;
@@ -97,5 +97,49 @@ declare const LocalStorageService: {
97
97
  clear(): void;
98
98
  };
99
99
  declare function createBoardLiveGraphRuntime(input: LiveCard[] | LiveBoard, options?: BoardLiveGraphRuntimeOptions): BoardLiveGraphRuntime;
100
+ interface CardRuntimeArtifact {
101
+ schema_version?: string;
102
+ card_id?: string;
103
+ card_data?: Record<string, unknown>;
104
+ computed_values?: Record<string, unknown>;
105
+ fetched_sources?: Record<string, unknown>;
106
+ requires?: Record<string, unknown>;
107
+ }
108
+ interface BoardRuntimeArtifactsPayload {
109
+ cardDefinitions: LiveCard[];
110
+ cardRuntimeById?: Record<string, CardRuntimeArtifact>;
111
+ dataObjectsByToken?: Record<string, unknown>;
112
+ statusSnapshot?: {
113
+ cards?: Array<{
114
+ name: string;
115
+ status?: string;
116
+ error?: {
117
+ message?: string;
118
+ } | null;
119
+ runtime?: {
120
+ last_transition_at?: string | null;
121
+ };
122
+ blocked_by?: string[];
123
+ requires_missing?: string[];
124
+ }>;
125
+ };
126
+ }
127
+ /**
128
+ * Converts a server bootstrap payload (cardDefinitions + cardRuntimeById + statusSnapshot)
129
+ * into an array of LiveCardRuntimeModel ready for rendering.
130
+ */
131
+ declare function buildLiveCardModelsFromArtifacts(payload: BoardRuntimeArtifactsPayload): LiveCardRuntimeModel[];
132
+ interface BuildBrowserArtifactsOptions {
133
+ boardPath?: string;
134
+ cardDefinitions: LiveCard[];
135
+ runtimeModels: LiveCardRuntimeModel[];
136
+ graphState: LiveGraph;
137
+ }
138
+ /**
139
+ * Converts browser-runtime state (LiveCardRuntimeModel[] + LiveGraph) back into
140
+ * the server-payload format expected by buildLiveCardModelsFromArtifacts.
141
+ * Used by the browser-only shell to keep the same rendering path as the server shell.
142
+ */
143
+ declare function buildBrowserArtifactsFromRuntime({ boardPath, cardDefinitions, runtimeModels, graphState, }: BuildBrowserArtifactsOptions): BoardRuntimeArtifactsPayload;
100
144
 
101
- export { type BoardLiveGraphRuntime, type BoardLiveGraphRuntimeOptions, type BoardLiveGraphRuntimeUpdate, type BoardRuntimeView, type BoardTaskExecutor, type BoardTaskExecutorContext, type BrowserSourceAdapter, type BrowserSourceAdapterContext, type LiveCardRuntimeModel, LocalStorageService, createBoardLiveGraphRuntime };
145
+ export { type BoardLiveGraphRuntime, type BoardLiveGraphRuntimeOptions, type BoardLiveGraphRuntimeUpdate, type BoardRuntimeArtifactsPayload, type BoardRuntimeView, type BoardTaskExecutor, type BoardTaskExecutorContext, type BrowserSourceAdapter, type BrowserSourceAdapterContext, type BuildBrowserArtifactsOptions, type CardRuntimeArtifact, type LiveCardRuntimeModel, LocalStorageService, buildBrowserArtifactsFromRuntime, buildLiveCardModelsFromArtifacts, createBoardLiveGraphRuntime };
@@ -1,7 +1,7 @@
1
- import { G as GraphConfig, f as GraphEvent } from '../types-CMFSIjpc.js';
2
- import { L as LiveGraph } from '../types-C2eJ7DAV.js';
3
- import { s as schedule } from '../schedule-CMcZe5Ny.js';
4
- import { R as ReactiveGraph, a as LiveCard, e as TaskHandlerInput, d as ReactiveGraphOptions, L as LiveBoard } from '../live-cards-bridge-Or7fdEJV.js';
1
+ import { G as GraphConfig, f as GraphEvent } from '../types-BBhqYGhE.js';
2
+ import { L as LiveGraph } from '../types-CoW0gQl3.js';
3
+ import { s as schedule } from '../schedule-Cszq9LYY.js';
4
+ import { R as ReactiveGraph, a as LiveCard, e as TaskHandlerInput, d as ReactiveGraphOptions, L as LiveBoard } from '../live-cards-bridge-CeNxiVcm.js';
5
5
 
6
6
  interface BrowserSourceAdapterContext {
7
7
  card: LiveCard;
@@ -97,5 +97,49 @@ declare const LocalStorageService: {
97
97
  clear(): void;
98
98
  };
99
99
  declare function createBoardLiveGraphRuntime(input: LiveCard[] | LiveBoard, options?: BoardLiveGraphRuntimeOptions): BoardLiveGraphRuntime;
100
+ interface CardRuntimeArtifact {
101
+ schema_version?: string;
102
+ card_id?: string;
103
+ card_data?: Record<string, unknown>;
104
+ computed_values?: Record<string, unknown>;
105
+ fetched_sources?: Record<string, unknown>;
106
+ requires?: Record<string, unknown>;
107
+ }
108
+ interface BoardRuntimeArtifactsPayload {
109
+ cardDefinitions: LiveCard[];
110
+ cardRuntimeById?: Record<string, CardRuntimeArtifact>;
111
+ dataObjectsByToken?: Record<string, unknown>;
112
+ statusSnapshot?: {
113
+ cards?: Array<{
114
+ name: string;
115
+ status?: string;
116
+ error?: {
117
+ message?: string;
118
+ } | null;
119
+ runtime?: {
120
+ last_transition_at?: string | null;
121
+ };
122
+ blocked_by?: string[];
123
+ requires_missing?: string[];
124
+ }>;
125
+ };
126
+ }
127
+ /**
128
+ * Converts a server bootstrap payload (cardDefinitions + cardRuntimeById + statusSnapshot)
129
+ * into an array of LiveCardRuntimeModel ready for rendering.
130
+ */
131
+ declare function buildLiveCardModelsFromArtifacts(payload: BoardRuntimeArtifactsPayload): LiveCardRuntimeModel[];
132
+ interface BuildBrowserArtifactsOptions {
133
+ boardPath?: string;
134
+ cardDefinitions: LiveCard[];
135
+ runtimeModels: LiveCardRuntimeModel[];
136
+ graphState: LiveGraph;
137
+ }
138
+ /**
139
+ * Converts browser-runtime state (LiveCardRuntimeModel[] + LiveGraph) back into
140
+ * the server-payload format expected by buildLiveCardModelsFromArtifacts.
141
+ * Used by the browser-only shell to keep the same rendering path as the server shell.
142
+ */
143
+ declare function buildBrowserArtifactsFromRuntime({ boardPath, cardDefinitions, runtimeModels, graphState, }: BuildBrowserArtifactsOptions): BoardRuntimeArtifactsPayload;
100
144
 
101
- export { type BoardLiveGraphRuntime, type BoardLiveGraphRuntimeOptions, type BoardLiveGraphRuntimeUpdate, type BoardRuntimeView, type BoardTaskExecutor, type BoardTaskExecutorContext, type BrowserSourceAdapter, type BrowserSourceAdapterContext, type LiveCardRuntimeModel, LocalStorageService, createBoardLiveGraphRuntime };
145
+ export { type BoardLiveGraphRuntime, type BoardLiveGraphRuntimeOptions, type BoardLiveGraphRuntimeUpdate, type BoardRuntimeArtifactsPayload, type BoardRuntimeView, type BoardTaskExecutor, type BoardTaskExecutorContext, type BrowserSourceAdapter, type BrowserSourceAdapterContext, type BuildBrowserArtifactsOptions, type CardRuntimeArtifact, type LiveCardRuntimeModel, LocalStorageService, buildBrowserArtifactsFromRuntime, buildLiveCardModelsFromArtifacts, createBoardLiveGraphRuntime };
@@ -135,13 +135,29 @@ function validateNode(node) {
135
135
  if (!Array.isArray(n.sources)) {
136
136
  errors.push("sources: must be an array");
137
137
  } else {
138
+ const bindTos = /* @__PURE__ */ new Set();
139
+ const outputFiles = /* @__PURE__ */ new Set();
138
140
  n.sources.forEach((src, i) => {
139
141
  if (!src || typeof src !== "object" || Array.isArray(src)) {
140
142
  errors.push(`sources[${i}]: must be an object`);
141
143
  } else {
142
144
  const s = src;
143
- if (typeof s.bindTo !== "string" || !s.bindTo) errors.push(`sources[${i}]: missing required "bindTo" property`);
144
- if (s.outputFile != null && typeof s.outputFile !== "string") errors.push(`sources[${i}]: outputFile must be a string`);
145
+ if (typeof s.bindTo !== "string" || !s.bindTo) {
146
+ errors.push(`sources[${i}]: missing required "bindTo" property`);
147
+ } else {
148
+ if (bindTos.has(s.bindTo)) {
149
+ errors.push(`sources[${i}]: bindTo "${s.bindTo}" is not unique across sources`);
150
+ }
151
+ bindTos.add(s.bindTo);
152
+ }
153
+ if (typeof s.outputFile !== "string" || !s.outputFile) {
154
+ errors.push(`sources[${i}]: missing required "outputFile" property`);
155
+ } else {
156
+ if (outputFiles.has(s.outputFile)) {
157
+ errors.push(`sources[${i}]: outputFile "${s.outputFile}" is not unique across sources`);
158
+ }
159
+ outputFiles.add(s.outputFile);
160
+ }
145
161
  if (s.optionalForCompletionGating != null && typeof s.optionalForCompletionGating !== "boolean") {
146
162
  errors.push(`sources[${i}]: optionalForCompletionGating must be a boolean`);
147
163
  }
@@ -257,15 +273,30 @@ function groupTasksByProvides(candidateTaskNames, tasks) {
257
273
  }
258
274
 
259
275
  // src/event-graph/task-transitions.ts
260
- function applyTaskStart(state, taskName) {
276
+ function applyTaskStart(state, taskName, graph) {
261
277
  const existingTask = state.tasks[taskName] ?? createDefaultGraphEngineStore();
278
+ const startConsumedHashes = {};
279
+ if (graph) {
280
+ const taskConfig = graph.tasks[taskName];
281
+ const requires = getRequires(taskConfig);
282
+ for (const token of requires) {
283
+ for (const [otherName, otherConfig] of Object.entries(graph.tasks)) {
284
+ if (getProvides(otherConfig).includes(token)) {
285
+ const otherState = state.tasks[otherName];
286
+ if (otherState?.lastDataHash) startConsumedHashes[token] = otherState.lastDataHash;
287
+ break;
288
+ }
289
+ }
290
+ }
291
+ }
262
292
  const updatedTask = {
263
293
  ...existingTask,
264
294
  status: "running",
265
295
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
266
296
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
267
297
  progress: 0,
268
- error: void 0
298
+ error: void 0,
299
+ startConsumedHashes
269
300
  };
270
301
  return {
271
302
  ...state,
@@ -285,16 +316,18 @@ function applyTaskCompletion(state, graph, taskName, result, dataHash, data) {
285
316
  } else {
286
317
  outputTokens = getProvides(taskConfig);
287
318
  }
288
- const lastConsumedHashes = { ...existingTask.lastConsumedHashes };
289
- const requires = taskConfig.requires ?? [];
290
- for (const token of requires) {
291
- for (const [otherName, otherConfig] of Object.entries(graph.tasks)) {
292
- if (getProvides(otherConfig).includes(token)) {
293
- const otherState = state.tasks[otherName];
294
- if (otherState?.lastDataHash) {
295
- lastConsumedHashes[token] = otherState.lastDataHash;
319
+ const lastConsumedHashes = existingTask.startConsumedHashes ? { ...existingTask.startConsumedHashes } : { ...existingTask.lastConsumedHashes };
320
+ if (!existingTask.startConsumedHashes) {
321
+ const requires = taskConfig.requires ?? [];
322
+ for (const token of requires) {
323
+ for (const [otherName, otherConfig] of Object.entries(graph.tasks)) {
324
+ if (getProvides(otherConfig).includes(token)) {
325
+ const otherState = state.tasks[otherName];
326
+ if (otherState?.lastDataHash) {
327
+ lastConsumedHashes[token] = otherState.lastDataHash;
328
+ }
329
+ break;
296
330
  }
297
- break;
298
331
  }
299
332
  }
300
333
  }
@@ -439,7 +472,7 @@ function applyEvent(live, event) {
439
472
  switch (event.type) {
440
473
  // --- Execution state transitions ---
441
474
  case "task-started":
442
- return { config, state: applyTaskStart(state, event.taskName) };
475
+ return { config, state: applyTaskStart(state, event.taskName, config) };
443
476
  case "task-completed":
444
477
  return { config, state: applyTaskCompletion(state, config, event.taskName, event.result, event.dataHash, event.data) };
445
478
  case "task-failed":
@@ -1435,7 +1468,168 @@ function createBoardLiveGraphRuntime(input, options = {}) {
1435
1468
  };
1436
1469
  return runtime;
1437
1470
  }
1471
+ function taskStatusToCardStatus(taskStatus) {
1472
+ if (taskStatus === "running" || taskStatus === "in-progress") return "loading";
1473
+ if (taskStatus === "failed") return "error";
1474
+ if (taskStatus === "completed") return "fresh";
1475
+ return "fresh";
1476
+ }
1477
+ function cardStatusToTaskStatus(cardStatus) {
1478
+ if (cardStatus === "loading") return "in-progress";
1479
+ if (cardStatus === "error") return "failed";
1480
+ if (cardStatus === "stale") return "pending";
1481
+ if (cardStatus === "fresh") return "completed";
1482
+ return "pending";
1483
+ }
1484
+ function normalizeCardRuntimeArtifact(cardId, artifact) {
1485
+ const safe = artifact && typeof artifact === "object" && !Array.isArray(artifact) ? artifact : {};
1486
+ return {
1487
+ schema_version: safe.schema_version || "v1",
1488
+ card_id: typeof safe.card_id === "string" ? safe.card_id : cardId,
1489
+ card_data: safe.card_data && typeof safe.card_data === "object" && !Array.isArray(safe.card_data) ? structuredClone(safe.card_data) : {},
1490
+ computed_values: safe.computed_values && typeof safe.computed_values === "object" && !Array.isArray(safe.computed_values) ? structuredClone(safe.computed_values) : {},
1491
+ fetched_sources: safe.fetched_sources && typeof safe.fetched_sources === "object" && !Array.isArray(safe.fetched_sources) ? structuredClone(safe.fetched_sources) : {},
1492
+ requires: safe.requires && typeof safe.requires === "object" && !Array.isArray(safe.requires) ? structuredClone(safe.requires) : {}
1493
+ };
1494
+ }
1495
+ function buildLiveCardModelsFromArtifacts(payload) {
1496
+ if (!payload || typeof payload !== "object") throw new Error("payload must be an object");
1497
+ const cardDefinitions = Array.isArray(payload.cardDefinitions) ? payload.cardDefinitions : [];
1498
+ const statusSnapshot = payload.statusSnapshot && typeof payload.statusSnapshot === "object" ? payload.statusSnapshot : {};
1499
+ const cardRuntimeById = payload.cardRuntimeById && typeof payload.cardRuntimeById === "object" ? payload.cardRuntimeById : {};
1500
+ const dataObjectsByToken = payload.dataObjectsByToken && typeof payload.dataObjectsByToken === "object" ? payload.dataObjectsByToken : {};
1501
+ const statusCards = Array.isArray(statusSnapshot.cards) ? statusSnapshot.cards : [];
1502
+ const statusById = new Map(statusCards.map((c) => [c.name, c]));
1503
+ return cardDefinitions.map((cardDefinition) => {
1504
+ const card = structuredClone(cardDefinition);
1505
+ const cardId = card.id;
1506
+ if (!cardId) throw new Error("cardDefinitions entry missing id");
1507
+ const statusCard = statusById.get(cardId);
1508
+ const runtimeArtifact = normalizeCardRuntimeArtifact(cardId, cardRuntimeById[cardId]);
1509
+ const baseCardData = card.card_data && typeof card.card_data === "object" && !Array.isArray(card.card_data) ? card.card_data : {};
1510
+ const card_data = {
1511
+ ...baseCardData,
1512
+ ...runtimeArtifact.card_data || {},
1513
+ status: taskStatusToCardStatus(statusCard?.status),
1514
+ lastRun: statusCard?.runtime?.last_transition_at ?? null
1515
+ };
1516
+ if (statusCard?.error?.message) card_data["error"] = statusCard.error.message;
1517
+ const runtime_state = statusCard ? {
1518
+ task_status: statusCard.status ?? null,
1519
+ card_status: taskStatusToCardStatus(statusCard.status),
1520
+ runtime: structuredClone(statusCard.runtime ?? {}),
1521
+ error: statusCard.error ? structuredClone(statusCard.error) : null,
1522
+ blocked_by: Array.isArray(statusCard.blocked_by) ? structuredClone(statusCard.blocked_by) : [],
1523
+ requires_missing: Array.isArray(statusCard.requires_missing) ? structuredClone(statusCard.requires_missing) : []
1524
+ } : {
1525
+ task_status: null,
1526
+ card_status: card_data["status"] ?? "fresh",
1527
+ runtime: { last_transition_at: card_data["lastRun"] ?? null },
1528
+ error: card_data["error"] ? { message: card_data["error"] } : null,
1529
+ blocked_by: [],
1530
+ requires_missing: []
1531
+ };
1532
+ const requiresTokens = Array.isArray(card.requires) ? card.requires : [];
1533
+ const requires = {};
1534
+ for (const token of requiresTokens) {
1535
+ if (Object.prototype.hasOwnProperty.call(dataObjectsByToken, token)) {
1536
+ requires[token] = structuredClone(dataObjectsByToken[token]);
1537
+ }
1538
+ }
1539
+ return {
1540
+ id: cardId,
1541
+ card,
1542
+ card_data,
1543
+ fetched_sources: runtimeArtifact.fetched_sources,
1544
+ requires,
1545
+ computed_values: runtimeArtifact.computed_values,
1546
+ runtime_state
1547
+ };
1548
+ });
1549
+ }
1550
+ function buildBrowserArtifactsFromRuntime({
1551
+ boardPath,
1552
+ cardDefinitions,
1553
+ runtimeModels,
1554
+ graphState
1555
+ }) {
1556
+ const safeCardDefs = Array.isArray(cardDefinitions) ? cardDefinitions : [];
1557
+ const safeModels = Array.isArray(runtimeModels) ? runtimeModels : [];
1558
+ const runtimeModelById = new Map(safeModels.map((m) => [m.id, m]));
1559
+ const graphStateAny = graphState;
1560
+ const taskStates = graphStateAny.state?.tasks ?? {};
1561
+ const cardRuntimeById = {};
1562
+ for (const model of safeModels) {
1563
+ if (!model?.id) continue;
1564
+ cardRuntimeById[model.id] = {
1565
+ schema_version: "v1",
1566
+ card_id: model.id,
1567
+ card_data: structuredClone(model.card_data ?? {}),
1568
+ computed_values: structuredClone(model.computed_values ?? {}),
1569
+ fetched_sources: structuredClone(model.fetched_sources ?? {}),
1570
+ requires: structuredClone(model.requires ?? {})
1571
+ };
1572
+ }
1573
+ const dataObjectsByToken = {};
1574
+ for (const taskName of Object.keys(taskStates)) {
1575
+ const providesData = taskStates[taskName]?.data?.provides_data;
1576
+ if (providesData && typeof providesData === "object") {
1577
+ for (const token of Object.keys(providesData)) {
1578
+ dataObjectsByToken[token] = structuredClone(providesData[token]);
1579
+ }
1580
+ }
1581
+ }
1582
+ const statusCards = safeCardDefs.map((cardDef) => {
1583
+ const model = runtimeModelById.get(cardDef.id) ?? {};
1584
+ const taskState = taskStates[cardDef.id];
1585
+ const taskStatus = typeof taskState?.status === "string" ? taskState.status : cardStatusToTaskStatus(model.card_data?.["status"]);
1586
+ const errorMessage = typeof taskState?.error === "string" ? taskState.error : typeof model.card_data?.["error"] === "string" ? model.card_data["error"] : null;
1587
+ return {
1588
+ name: cardDef.id,
1589
+ status: taskStatus,
1590
+ ...errorMessage ? { error: { message: errorMessage, code: "TASK_FAILED", at: taskState?.failedAt ?? null, source: "browser-runtime" } } : {},
1591
+ requires: Array.isArray(cardDef.requires) ? cardDef.requires : [],
1592
+ requires_satisfied: [],
1593
+ requires_missing: [],
1594
+ provides_declared: Array.isArray(cardDef.provides) ? cardDef.provides.map((e) => e.bindTo) : [cardDef.id],
1595
+ provides_runtime: Object.keys(taskState?.data?.provides_data ?? {}).sort(),
1596
+ blocked_by: [],
1597
+ unblocks: [],
1598
+ runtime: {
1599
+ attempt_count: taskState?.executionCount ?? 0,
1600
+ restart_count: taskState?.retryCount ?? 0,
1601
+ in_progress_since: taskStatus === "in-progress" ? taskState?.startedAt ?? null : null,
1602
+ last_transition_at: taskState?.lastUpdated ?? model.card_data?.["lastRun"] ?? null,
1603
+ last_completed_at: taskState?.completedAt ?? null,
1604
+ last_restarted_at: taskState?.startedAt ?? null,
1605
+ status_age_ms: null
1606
+ }
1607
+ };
1608
+ });
1609
+ return {
1610
+ cardDefinitions: structuredClone(safeCardDefs),
1611
+ cardRuntimeById,
1612
+ dataObjectsByToken,
1613
+ statusSnapshot: {
1614
+ schema_version: "v1",
1615
+ meta: { board: { path: boardPath ?? "browser-runtime" } },
1616
+ summary: {
1617
+ card_count: statusCards.length,
1618
+ completed: statusCards.filter((c) => c.status === "completed").length,
1619
+ eligible: 0,
1620
+ pending: statusCards.filter((c) => c.status === "pending").length,
1621
+ blocked: 0,
1622
+ unresolved: 0,
1623
+ failed: statusCards.filter((c) => c.status === "failed").length,
1624
+ in_progress: statusCards.filter((c) => c.status === "in-progress").length,
1625
+ orphan_cards: 0,
1626
+ topology: { edge_count: 0, max_fan_out_card: null, max_fan_out: 0 }
1627
+ },
1628
+ cards: statusCards
1629
+ }
1630
+ };
1631
+ }
1438
1632
 
1439
- export { LocalStorageService, createBoardLiveGraphRuntime };
1633
+ export { LocalStorageService, buildBrowserArtifactsFromRuntime, buildLiveCardModelsFromArtifacts, createBoardLiveGraphRuntime };
1440
1634
  //# sourceMappingURL=index.js.map
1441
1635
  //# sourceMappingURL=index.js.map