yaml-flow 5.2.6 → 5.2.8

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 (84) hide show
  1. package/README.md +6 -6
  2. package/board-livecards-server-runtime.js +260 -35
  3. package/browser/board-livegraph-engine.js +57 -32
  4. package/browser/board-livegraph-engine.js.map +1 -1
  5. package/browser/card-compute.js +17 -17
  6. package/browser/live-cards.js +139 -12
  7. package/browser/live-cards.schema.json +14 -9
  8. package/dist/board-livegraph-runtime/index.cjs +57 -32
  9. package/dist/board-livegraph-runtime/index.cjs.map +1 -1
  10. package/dist/board-livegraph-runtime/index.d.cts +1 -1
  11. package/dist/board-livegraph-runtime/index.d.ts +1 -1
  12. package/dist/board-livegraph-runtime/index.js +57 -32
  13. package/dist/board-livegraph-runtime/index.js.map +1 -1
  14. package/dist/card-compute/index.cjs +96 -38
  15. package/dist/card-compute/index.cjs.map +1 -1
  16. package/dist/card-compute/index.d.cts +13 -8
  17. package/dist/card-compute/index.d.ts +13 -8
  18. package/dist/card-compute/index.js +96 -38
  19. package/dist/card-compute/index.js.map +1 -1
  20. package/dist/cli/board-live-cards-cli.cjs +7200 -201
  21. package/dist/cli/board-live-cards-cli.cjs.map +1 -1
  22. package/dist/cli/board-live-cards-cli.d.cts +6 -6
  23. package/dist/cli/board-live-cards-cli.d.ts +6 -6
  24. package/dist/cli/board-live-cards-cli.js +7199 -201
  25. package/dist/cli/board-live-cards-cli.js.map +1 -1
  26. package/dist/continuous-event-graph/index.cjs +55 -30
  27. package/dist/continuous-event-graph/index.cjs.map +1 -1
  28. package/dist/continuous-event-graph/index.d.cts +2 -2
  29. package/dist/continuous-event-graph/index.d.ts +2 -2
  30. package/dist/continuous-event-graph/index.js +55 -30
  31. package/dist/continuous-event-graph/index.js.map +1 -1
  32. package/dist/index.cjs +121 -53
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +1 -1
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.js +121 -53
  37. package/dist/index.js.map +1 -1
  38. package/dist/{live-cards-bridge-CeNxiVcm.d.ts → live-cards-bridge-EQjytzI_.d.ts} +10 -5
  39. package/dist/{live-cards-bridge-z_rJCSbi.d.cts → live-cards-bridge-x5XREkXm.d.cts} +10 -5
  40. package/examples/browser/boards/portfolio-tracker/cards/holdings-table.json +1 -1
  41. package/examples/browser/boards/portfolio-tracker/cards/portfolio-form.json +1 -1
  42. package/examples/browser/boards/portfolio-tracker/cards/portfolio-risk-assessment.json +1 -1
  43. package/examples/browser/boards/portfolio-tracker/cards/portfolio-value.json +1 -1
  44. package/examples/browser/boards/portfolio-tracker/cards/price-fetch.json +2 -2
  45. package/examples/browser/boards/portfolio-tracker/cards/rebalancing-strategy.json +1 -1
  46. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.js +10 -10
  47. package/examples/cli/step-machine-cli/portfolio-tracker/cards/holdings-table.json +1 -1
  48. package/examples/cli/step-machine-cli/portfolio-tracker/cards/portfolio-form.json +1 -1
  49. package/examples/cli/step-machine-cli/portfolio-tracker/cards/portfolio-value.json +1 -1
  50. package/examples/cli/step-machine-cli/portfolio-tracker/cards/price-fetch.json +2 -2
  51. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +1 -1
  52. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +1 -1
  53. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +1 -1
  54. package/examples/example-board/agent-instructions-cardlayout.md +1 -1
  55. package/examples/example-board/agent-instructions.md +271 -45
  56. package/examples/example-board/cards/card-concentration.json +8 -5
  57. package/examples/example-board/cards/card-market-prices.json +14 -9
  58. package/examples/example-board/cards/card-my-identity.json +28 -0
  59. package/examples/example-board/cards/card-portfolio-value.json +1 -1
  60. package/examples/example-board/cards/card-portfolio.json +1 -1
  61. package/examples/example-board/cards/card-rebalance-impact.json +65 -0
  62. package/examples/example-board/cards/card-rebalance-sim.json +57 -0
  63. package/examples/example-board/demo-chat-handler.js +2 -1
  64. package/examples/example-board/demo-server-config.json +6 -1
  65. package/examples/example-board/demo-server.js +79 -8
  66. package/examples/example-board/demo-shell-browser.html +6 -6
  67. package/examples/example-board/demo-shell-with-server.html +4 -4
  68. package/examples/example-board/demo-task-executor.js +436 -246
  69. package/examples/example-board/scripts/copilot_wrapper.bat +16 -0
  70. package/examples/example-board/scripts/copilot_wrapper_helper.ps1 +19 -10
  71. package/examples/example-board/scripts/workiq_wrapper.mjs +66 -0
  72. package/examples/npm-libs/continuous-event-graph/live-cards-board.ts +5 -5
  73. package/examples/npm-libs/continuous-event-graph/soc-incident-board.ts +3 -3
  74. package/examples/npm-libs/event-graph/research-pipeline.ts +5 -5
  75. package/examples/npm-libs/graph-of-graphs/multi-stage-etl.ts +9 -9
  76. package/examples/step-machine-cli/portfolio-tracker/cards/holdings-table.json +1 -1
  77. package/examples/step-machine-cli/portfolio-tracker/cards/portfolio-form.json +1 -1
  78. package/examples/step-machine-cli/portfolio-tracker/cards/portfolio-value.json +1 -1
  79. package/examples/step-machine-cli/portfolio-tracker/cards/price-fetch.json +3 -3
  80. package/examples/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +1 -1
  81. package/examples/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +1 -1
  82. package/examples/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +1 -1
  83. package/package.json +2 -2
  84. package/schema/live-cards.schema.json +14 -9
package/dist/index.d.cts CHANGED
@@ -10,7 +10,7 @@ export { BatchItemResult, BatchOptions, BatchProgress, BatchResult, batch } from
10
10
  export { ConfigTemplates, Variables, resolveConfigTemplates, resolveVariables } from './config/index.cjs';
11
11
  export { GraphMutation, ReactiveGraphValidationInput, ResolveCallbackFn, ScriptHandlerOptions, ShellHandlerOptions, WebhookHandlerOptions, addNode, addProvides, addRequires, applyEvent, applyEvents, createCallbackHandler, createFireAndForgetHandler, createLiveGraph, createNoopHandler, createScriptHandler, createShellHandler, createWebhookHandler, disableNode, drainTokens, enableNode, getDownstream, getNode, getUnreachableNodes, getUnreachableTokens, getUpstream, injectTokens, inspect, mutateGraph, removeNode, removeProvides, removeRequires, resetNode, restore, snapshot, validateLiveGraph, validateReactiveGraph } from './continuous-event-graph/index.cjs';
12
12
  export { s as schedule } from './schedule-qWNL0RQh.cjs';
13
- export { L as LiveBoard, a as LiveCard, b as LiveCardsToReactiveOptions, c as LiveCardsToReactiveResult, R as ReactiveGraph, d as ReactiveGraphOptions, T as TaskHandlerFn, e as TaskHandlerInput, f as TaskHandlerReturn, g as createReactiveGraph, l as liveCardsToReactiveGraph } from './live-cards-bridge-z_rJCSbi.cjs';
13
+ export { L as LiveBoard, a as LiveCard, b as LiveCardsToReactiveOptions, c as LiveCardsToReactiveResult, R as ReactiveGraph, d as ReactiveGraphOptions, T as TaskHandlerFn, e as TaskHandlerInput, f as TaskHandlerReturn, g as createReactiveGraph, l as liveCardsToReactiveGraph } from './live-cards-bridge-x5XREkXm.cjs';
14
14
  export { J as Journal, M as MemoryJournal } from './journal-B-JCfQnh.cjs';
15
15
  export { B as BlockedTask, D as DownstreamResult, L as LiveGraph, a as LiveGraphHealth, b as LiveGraphSnapshot, N as NodeInfo, P as PendingTask, S as ScheduleResult, U as UnreachableNodesResult, c as UnreachableTokensResult, d as UnresolvedDependency, e as UpstreamResult } from './types-CHSdoAAA.cjs';
16
16
  export { BoardLiveGraphRuntime, BoardLiveGraphRuntimeOptions, BoardLiveGraphRuntimeUpdate, BoardRuntimeView, BoardTaskExecutor, BoardTaskExecutorContext, BrowserSourceAdapter, BrowserSourceAdapterContext, LiveCardRuntimeModel, createBoardLiveGraphRuntime } from './board-livegraph-runtime/index.cjs';
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export { BatchItemResult, BatchOptions, BatchProgress, BatchResult, batch } from
10
10
  export { ConfigTemplates, Variables, resolveConfigTemplates, resolveVariables } from './config/index.js';
11
11
  export { GraphMutation, ReactiveGraphValidationInput, ResolveCallbackFn, ScriptHandlerOptions, ShellHandlerOptions, WebhookHandlerOptions, addNode, addProvides, addRequires, applyEvent, applyEvents, createCallbackHandler, createFireAndForgetHandler, createLiveGraph, createNoopHandler, createScriptHandler, createShellHandler, createWebhookHandler, disableNode, drainTokens, enableNode, getDownstream, getNode, getUnreachableNodes, getUnreachableTokens, getUpstream, injectTokens, inspect, mutateGraph, removeNode, removeProvides, removeRequires, resetNode, restore, snapshot, validateLiveGraph, validateReactiveGraph } from './continuous-event-graph/index.js';
12
12
  export { s as schedule } from './schedule-Cszq9LYY.js';
13
- export { L as LiveBoard, a as LiveCard, b as LiveCardsToReactiveOptions, c as LiveCardsToReactiveResult, R as ReactiveGraph, d as ReactiveGraphOptions, T as TaskHandlerFn, e as TaskHandlerInput, f as TaskHandlerReturn, g as createReactiveGraph, l as liveCardsToReactiveGraph } from './live-cards-bridge-CeNxiVcm.js';
13
+ export { L as LiveBoard, a as LiveCard, b as LiveCardsToReactiveOptions, c as LiveCardsToReactiveResult, R as ReactiveGraph, d as ReactiveGraphOptions, T as TaskHandlerFn, e as TaskHandlerInput, f as TaskHandlerReturn, g as createReactiveGraph, l as liveCardsToReactiveGraph } from './live-cards-bridge-EQjytzI_.js';
14
14
  export { J as Journal, M as MemoryJournal } from './journal-9HEgs7dU.js';
15
15
  export { B as BlockedTask, D as DownstreamResult, L as LiveGraph, a as LiveGraphHealth, b as LiveGraphSnapshot, N as NodeInfo, P as PendingTask, S as ScheduleResult, U as UnreachableNodesResult, c as UnreachableTokensResult, d as UnresolvedDependency, e as UpstreamResult } from './types-CoW0gQl3.js';
16
16
  export { BoardLiveGraphRuntime, BoardLiveGraphRuntimeOptions, BoardLiveGraphRuntimeUpdate, BoardRuntimeView, BoardTaskExecutor, BoardTaskExecutorContext, BrowserSourceAdapter, BrowserSourceAdapterContext, LiveCardRuntimeModel, createBoardLiveGraphRuntime } from './board-livegraph-runtime/index.js';
package/dist/index.js CHANGED
@@ -10962,6 +10962,7 @@ function createReactiveGraph(configOrLive, options, executionId) {
10962
10962
  const inputQueue = new MemoryJournal();
10963
10963
  let live = "state" in configOrLive && "config" in configOrLive ? configOrLive : createLiveGraph(configOrLive, executionId);
10964
10964
  let disposed = false;
10965
+ const pendingHandlers = /* @__PURE__ */ new Set();
10965
10966
  const handlers = new Map(Object.entries(initialHandlers));
10966
10967
  const internalJournal = new MemoryJournal();
10967
10968
  let draining = false;
@@ -11004,7 +11005,7 @@ function createReactiveGraph(configOrLive, options, executionId) {
11004
11005
  const taskState = live.state.tasks[taskName];
11005
11006
  if (!taskState || taskState.status !== "running") continue;
11006
11007
  const callbackToken = encodeCallbackToken(taskName);
11007
- runPipeline(taskName, callbackToken, update).catch((error) => {
11008
+ const p = runPipeline(taskName, callbackToken, update).catch((error) => {
11008
11009
  if (disposed) return;
11009
11010
  internalJournal.append({
11010
11011
  type: "task-failed",
@@ -11013,7 +11014,10 @@ function createReactiveGraph(configOrLive, options, executionId) {
11013
11014
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11014
11015
  });
11015
11016
  drain();
11017
+ }).finally(() => {
11018
+ pendingHandlers.delete(p);
11016
11019
  });
11020
+ pendingHandlers.add(p);
11017
11021
  }
11018
11022
  }
11019
11023
  }
@@ -11073,7 +11077,7 @@ function createReactiveGraph(configOrLive, options, executionId) {
11073
11077
  });
11074
11078
  drain();
11075
11079
  const callbackToken = encodeCallbackToken(taskName);
11076
- runPipeline(taskName, callbackToken).catch((error) => {
11080
+ const p = runPipeline(taskName, callbackToken).catch((error) => {
11077
11081
  if (disposed) return;
11078
11082
  internalJournal.append({
11079
11083
  type: "task-failed",
@@ -11082,7 +11086,10 @@ function createReactiveGraph(configOrLive, options, executionId) {
11082
11086
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11083
11087
  });
11084
11088
  drain();
11089
+ }).finally(() => {
11090
+ pendingHandlers.delete(p);
11085
11091
  });
11092
+ pendingHandlers.add(p);
11086
11093
  }
11087
11094
  return {
11088
11095
  push(event) {
@@ -11196,7 +11203,10 @@ function createReactiveGraph(configOrLive, options, executionId) {
11196
11203
  getSchedule() {
11197
11204
  return schedule(live);
11198
11205
  },
11199
- dispose() {
11206
+ async dispose(options2) {
11207
+ if (options2?.wait && pendingHandlers.size > 0) {
11208
+ await Promise.allSettled([...pendingHandlers]);
11209
+ }
11200
11210
  disposed = true;
11201
11211
  }
11202
11212
  };
@@ -11663,10 +11673,10 @@ var live_cards_schema_default = {
11663
11673
  type: "array",
11664
11674
  items: {
11665
11675
  type: "object",
11666
- required: ["bindTo", "src"],
11676
+ required: ["bindTo", "ref"],
11667
11677
  properties: {
11668
11678
  bindTo: { type: "string", description: "Token name published downstream" },
11669
- src: { type: "string", description: "Path to read value from (card_data.*, requires.*, fetched_sources.*, computed_values.*)" }
11679
+ ref: { type: "string", description: "Path to read value from (card_data.*, requires.*, fetched_sources.*, computed_values.*)" }
11670
11680
  }
11671
11681
  },
11672
11682
  description: "Explicit bindings exposing computed or card_data values downstream as named tokens"
@@ -11681,14 +11691,19 @@ var live_cards_schema_default = {
11681
11691
  }
11682
11692
  },
11683
11693
  source_def: {
11684
- description: "One source entry. The engine requires 'bindTo' (compute namespace key) and 'outputFile' (delivery signal path). bindTo and outputFile must be unique across all sources in a card. Every other property is yours \u2014 add whatever your task-executor needs: kind, url, headers, mailbox, channel, model, query, etc. The full object is passed verbatim as the --in JSON to the executor.",
11694
+ description: "One source entry. The engine requires 'bindTo' (compute namespace key) and 'outputFile' (delivery signal path). bindTo and outputFile must be unique across all source_defs in a card. Every other property is yours \u2014 add whatever your task-executor needs: kind, url, headers, mailbox, channel, model, query, etc. The full object is passed verbatim as the --in JSON to the executor.",
11685
11695
  type: "object",
11686
11696
  required: ["bindTo", "outputFile"],
11687
11697
  additionalProperties: true,
11688
11698
  properties: {
11689
11699
  bindTo: { type: "string", description: "Key under fetched_sources.* available in compute expressions" },
11690
11700
  outputFile: { type: "string", description: "Board-relative path the executor writes its JSON result to. Presence of this file signals delivery." },
11691
- optionalForCompletionGating: { type: "boolean", default: false, description: "When true this source does not gate card completion. Default false when absent, so sources are completion-gating by default." },
11701
+ projections: {
11702
+ type: "object",
11703
+ description: "Named data projections from card_data or requires, evaluated before the executor is called. Each key is a ref name; each value is a JSONata expression rooted at card_data or requires. The resolved values are passed to the executor as _projections. fetched_sources, computed_values, and source_defs are not accessible here \u2014 sources run before those exist.",
11704
+ additionalProperties: { type: "string" }
11705
+ },
11706
+ optionalForCompletionGating: { type: "boolean", default: false, description: "When true this source does not gate card completion. Default false when absent, so source_defs are completion-gating by default." },
11692
11707
  timeout: { type: "integer", minimum: 0, default: 12e4, description: "Executor/script timeout in ms. Default: 120 000 (2 min)." },
11693
11708
  script: { type: "string", description: "Legacy direct-run: shell command executed when no .task-executor is registered. stdout is captured as the result." }
11694
11709
  }
@@ -11808,7 +11823,7 @@ var live_cards_schema_default = {
11808
11823
  }
11809
11824
  },
11810
11825
  title: "LiveCard",
11811
- description: "A unified card node. Behavior depends on which sections are present (sources, compute, view, etc.)",
11826
+ description: "A unified card node. Behavior depends on which sections are present (source_defs, compute, view, etc.)",
11812
11827
  type: "object",
11813
11828
  required: ["id"],
11814
11829
  additionalProperties: false,
@@ -11851,22 +11866,22 @@ var live_cards_schema_default = {
11851
11866
  },
11852
11867
  llm_task_completion_inference: {
11853
11868
  type: "object",
11854
- description: "Runtime state written by the inference adapter (advanced/undocumented). Prefer the standard sources \u2192 compute \u2192 provides pattern for LLM-based signals.",
11869
+ description: "Runtime state written by the inference adapter (advanced/undocumented). Prefer the standard source_defs \u2192 compute \u2192 provides pattern for LLM-based signals.",
11855
11870
  properties: {
11856
11871
  inferenceRequested: { type: "string", format: "date-time", description: "Timestamp when the latest inference request was initiated" },
11857
11872
  inferenceCompletedAt: { type: "string", format: "date-time", description: "Timestamp when the latest inference request completed" },
11858
11873
  isTaskCompleted: { type: "boolean", description: "Whether the task is considered complete by the adapter" },
11859
11874
  reasoning: { type: "string", description: "Explanation of completion decision" },
11860
- evidence: { type: "array", description: "Supporting evidence from sources/compute" }
11875
+ evidence: { type: "array", description: "Supporting evidence from source_defs/compute" }
11861
11876
  },
11862
11877
  additionalProperties: true
11863
11878
  }
11864
11879
  },
11865
11880
  additionalProperties: true
11866
11881
  },
11867
- sources: {
11882
+ source_defs: {
11868
11883
  type: "array",
11869
- description: "Source entries. Each entry is passed verbatim to the board's .task-executor (registered via init --task-executor) as the --in JSON file. The executor fetches/generates the data and writes JSON to --out. If no executor is registered, the built-in executor runs the entry's 'cli' command directly. Sources gate completion by default. Set optionalForCompletionGating: true for enrichment-only sources that should not block task-completed.",
11884
+ description: "Source entries. Each entry is passed verbatim to the board's .task-executor (registered via init --task-executor) as the --in JSON file. The executor fetches/generates the data and writes JSON to --out. If no executor is registered, the built-in executor runs the entry's 'cli' command directly. Sources gate completion by default. Set optionalForCompletionGating: true for enrichment-only source_defs that should not block task-completed.",
11870
11885
  items: { $ref: "#/definitions/source_def" }
11871
11886
  },
11872
11887
  compute: {
@@ -11884,8 +11899,8 @@ var live_cards_schema_default = {
11884
11899
  // src/card-compute/schema-validator.ts
11885
11900
  var import_ajv3 = __toESM(require_ajv());
11886
11901
  var _compiled3 = null;
11887
- var NAMESPACE_REFERENCE_RE = /\b(card_data|requires|fetched_sources|computed_values|sources)\b/g;
11888
- var ROOT_PATH_NAMESPACE_RE = /^\s*(card_data|requires|fetched_sources|computed_values|sources)(\.|$)/;
11902
+ var NAMESPACE_REFERENCE_RE = /\b(card_data|requires|fetched_sources|computed_values|source_defs)\b/g;
11903
+ var ROOT_PATH_NAMESPACE_RE = /^\s*(card_data|requires|fetched_sources|computed_values|source_defs)(\.|$)/;
11889
11904
  function referencedNamespaces(expression) {
11890
11905
  const namespaces = /* @__PURE__ */ new Set();
11891
11906
  let match;
@@ -11950,22 +11965,22 @@ function validateLiveCardSchema(node) {
11950
11965
  return `${path}: ${e.message ?? "unknown error"}`;
11951
11966
  });
11952
11967
  if (node && typeof node === "object" && !Array.isArray(node)) {
11953
- const sources = node.sources;
11954
- if (Array.isArray(sources)) {
11968
+ const source_defs = node.source_defs;
11969
+ if (Array.isArray(source_defs)) {
11955
11970
  const bindTos = /* @__PURE__ */ new Set();
11956
11971
  const outputFiles = /* @__PURE__ */ new Set();
11957
- sources.forEach((src, i) => {
11972
+ source_defs.forEach((src, i) => {
11958
11973
  if (!src || typeof src !== "object" || Array.isArray(src)) return;
11959
11974
  const s = src;
11960
11975
  if (typeof s.bindTo === "string" && s.bindTo) {
11961
11976
  if (bindTos.has(s.bindTo)) {
11962
- errors.push(`/sources/${i}/bindTo: bindTo "${s.bindTo}" must be unique across all sources`);
11977
+ errors.push(`/source_defs/${i}/bindTo: bindTo "${s.bindTo}" must be unique across all source_defs`);
11963
11978
  }
11964
11979
  bindTos.add(s.bindTo);
11965
11980
  }
11966
11981
  if (typeof s.outputFile === "string" && s.outputFile) {
11967
11982
  if (outputFiles.has(s.outputFile)) {
11968
- errors.push(`/sources/${i}/outputFile: outputFile "${s.outputFile}" must be unique across all sources`);
11983
+ errors.push(`/source_defs/${i}/outputFile: outputFile "${s.outputFile}" must be unique across all source_defs`);
11969
11984
  }
11970
11985
  outputFiles.add(s.outputFile);
11971
11986
  }
@@ -11995,10 +12010,48 @@ function validateLiveCardRuntimeExpressions(node) {
11995
12010
  );
11996
12011
  });
11997
12012
  }
12013
+ const VALID_PROVIDES_SRC_NAMESPACES = /* @__PURE__ */ new Set([
12014
+ "card_data",
12015
+ "requires",
12016
+ "fetched_sources",
12017
+ "computed_values"
12018
+ ]);
12019
+ const provides = asRecord.provides;
12020
+ if (Array.isArray(provides)) {
12021
+ provides.forEach((entry, i) => {
12022
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) return;
12023
+ const ref = entry.ref;
12024
+ if (typeof ref !== "string" || ref.trim().length === 0) return;
12025
+ const rootNamespace = parseRootPathNamespace(ref);
12026
+ if (rootNamespace === null) {
12027
+ errors.push(`/provides/${i}/ref: path "${ref}" must start with a valid namespace (${[...VALID_PROVIDES_SRC_NAMESPACES].join(", ")})`);
12028
+ } else if (!VALID_PROVIDES_SRC_NAMESPACES.has(rootNamespace)) {
12029
+ errors.push(`/provides/${i}/ref: disallowed namespace "${rootNamespace}" in path "${ref}" (valid: ${[...VALID_PROVIDES_SRC_NAMESPACES].join(", ")})`);
12030
+ }
12031
+ });
12032
+ }
11998
12033
  const view = asRecord.view;
11999
12034
  if (view && typeof view === "object" && !Array.isArray(view)) {
12000
12035
  walkViewPathReferences(view, "/view", errors);
12001
12036
  }
12037
+ const VALID_PROJECTION_NAMESPACES = /* @__PURE__ */ new Set(["card_data", "requires"]);
12038
+ const source_defs = asRecord.source_defs;
12039
+ if (Array.isArray(source_defs)) {
12040
+ source_defs.forEach((srcDef, i) => {
12041
+ if (!srcDef || typeof srcDef !== "object" || Array.isArray(srcDef)) return;
12042
+ const projections = srcDef.projections;
12043
+ if (!projections || typeof projections !== "object" || Array.isArray(projections)) return;
12044
+ for (const [key, exprVal] of Object.entries(projections)) {
12045
+ if (typeof exprVal !== "string" || exprVal.trim().length === 0) continue;
12046
+ validateJsonataExprWithNamespaces(
12047
+ exprVal,
12048
+ `/source_defs/${i}/projections/${key}`,
12049
+ VALID_PROJECTION_NAMESPACES,
12050
+ errors
12051
+ );
12052
+ }
12053
+ });
12054
+ }
12002
12055
  return { ok: errors.length === 0, errors };
12003
12056
  }
12004
12057
  function validateLiveCard(node) {
@@ -12085,7 +12138,7 @@ var VALID_ELEMENT_KINDS = /* @__PURE__ */ new Set([
12085
12138
  "markdown",
12086
12139
  "custom"
12087
12140
  ]);
12088
- var ALLOWED_KEYS = /* @__PURE__ */ new Set(["id", "meta", "requires", "provides", "view", "card_data", "compute", "sources"]);
12141
+ var ALLOWED_KEYS = /* @__PURE__ */ new Set(["id", "meta", "requires", "provides", "view", "card_data", "compute", "source_defs"]);
12089
12142
  function validateNode(node) {
12090
12143
  const errors = [];
12091
12144
  if (!node || typeof node !== "object" || Array.isArray(node)) {
@@ -12111,15 +12164,15 @@ function validateNode(node) {
12111
12164
  if (n.requires != null && !Array.isArray(n.requires)) errors.push("requires: must be an array of strings");
12112
12165
  if (n.provides != null) {
12113
12166
  if (!Array.isArray(n.provides)) {
12114
- errors.push("provides: must be an array of { bindTo, src } bindings");
12167
+ errors.push("provides: must be an array of { bindTo, ref } bindings");
12115
12168
  } else {
12116
12169
  n.provides.forEach((p, i) => {
12117
12170
  if (!p || typeof p !== "object" || Array.isArray(p)) {
12118
- errors.push(`provides[${i}]: must be an object with bindTo and src`);
12171
+ errors.push(`provides[${i}]: must be an object with bindTo and ref`);
12119
12172
  } else {
12120
12173
  const b = p;
12121
12174
  if (typeof b.bindTo !== "string" || !b.bindTo) errors.push(`provides[${i}]: missing required "bindTo" string`);
12122
- if (typeof b.src !== "string" || !b.src) errors.push(`provides[${i}]: missing required "src" string`);
12175
+ if (typeof b.ref !== "string" || !b.ref) errors.push(`provides[${i}]: missing required "ref" string`);
12123
12176
  }
12124
12177
  });
12125
12178
  }
@@ -12139,35 +12192,35 @@ function validateNode(node) {
12139
12192
  });
12140
12193
  }
12141
12194
  }
12142
- if (n.sources != null) {
12143
- if (!Array.isArray(n.sources)) {
12144
- errors.push("sources: must be an array");
12195
+ if (n.source_defs != null) {
12196
+ if (!Array.isArray(n.source_defs)) {
12197
+ errors.push("source_defs: must be an array");
12145
12198
  } else {
12146
12199
  const bindTos = /* @__PURE__ */ new Set();
12147
12200
  const outputFiles = /* @__PURE__ */ new Set();
12148
- n.sources.forEach((src, i) => {
12201
+ n.source_defs.forEach((src, i) => {
12149
12202
  if (!src || typeof src !== "object" || Array.isArray(src)) {
12150
- errors.push(`sources[${i}]: must be an object`);
12203
+ errors.push(`source_defs[${i}]: must be an object`);
12151
12204
  } else {
12152
12205
  const s = src;
12153
12206
  if (typeof s.bindTo !== "string" || !s.bindTo) {
12154
- errors.push(`sources[${i}]: missing required "bindTo" property`);
12207
+ errors.push(`source_defs[${i}]: missing required "bindTo" property`);
12155
12208
  } else {
12156
12209
  if (bindTos.has(s.bindTo)) {
12157
- errors.push(`sources[${i}]: bindTo "${s.bindTo}" is not unique across sources`);
12210
+ errors.push(`source_defs[${i}]: bindTo "${s.bindTo}" is not unique across source_defs`);
12158
12211
  }
12159
12212
  bindTos.add(s.bindTo);
12160
12213
  }
12161
12214
  if (typeof s.outputFile !== "string" || !s.outputFile) {
12162
- errors.push(`sources[${i}]: missing required "outputFile" property`);
12215
+ errors.push(`source_defs[${i}]: missing required "outputFile" property`);
12163
12216
  } else {
12164
12217
  if (outputFiles.has(s.outputFile)) {
12165
- errors.push(`sources[${i}]: outputFile "${s.outputFile}" is not unique across sources`);
12218
+ errors.push(`source_defs[${i}]: outputFile "${s.outputFile}" is not unique across source_defs`);
12166
12219
  }
12167
12220
  outputFiles.add(s.outputFile);
12168
12221
  }
12169
12222
  if (s.optionalForCompletionGating != null && typeof s.optionalForCompletionGating !== "boolean") {
12170
- errors.push(`sources[${i}]: optionalForCompletionGating must be a boolean`);
12223
+ errors.push(`source_defs[${i}]: optionalForCompletionGating must be a boolean`);
12171
12224
  }
12172
12225
  }
12173
12226
  });
@@ -12202,14 +12255,29 @@ function validateNode(node) {
12202
12255
  }
12203
12256
  return { ok: errors.length === 0, errors };
12204
12257
  }
12205
- function enrichSources(sources, context) {
12206
- if (!sources || sources.length === 0) return [];
12207
- return sources.map((src) => ({
12208
- ...src,
12209
- _requires: context.requires ?? {},
12210
- _sourcesData: context.sourcesData ?? {},
12211
- _computed_values: context.computed_values ?? {}
12212
- }));
12258
+ async function enrichSources(source_defs, context) {
12259
+ if (!source_defs || source_defs.length === 0) return [];
12260
+ const evalCtx = {
12261
+ card_data: context.card_data ?? {},
12262
+ requires: context.requires ?? {}
12263
+ };
12264
+ return Promise.all(
12265
+ source_defs.map(async (src) => {
12266
+ const _projections = {};
12267
+ if (src.projections && typeof src.projections === "object" && !Array.isArray(src.projections)) {
12268
+ for (const [key, expr] of Object.entries(src.projections)) {
12269
+ if (typeof expr === "string" && expr.trim().length > 0) {
12270
+ try {
12271
+ _projections[key] = await jsonata2(expr).evaluate(evalCtx);
12272
+ } catch {
12273
+ _projections[key] = void 0;
12274
+ }
12275
+ }
12276
+ }
12277
+ }
12278
+ return { ...src, _projections };
12279
+ })
12280
+ );
12213
12281
  }
12214
12282
  var CardCompute = {
12215
12283
  run,
@@ -12252,7 +12320,7 @@ function liveCardsToReactiveGraph(input, options = {}) {
12252
12320
  const allTokens = /* @__PURE__ */ new Set();
12253
12321
  const tokenToCardId = /* @__PURE__ */ new Map();
12254
12322
  for (const card of cards) {
12255
- for (const binding of card.provides ?? [{ bindTo: card.id, src: "card_data" }]) {
12323
+ for (const binding of card.provides ?? [{ bindTo: card.id, ref: "card_data" }]) {
12256
12324
  allTokens.add(binding.bindTo);
12257
12325
  tokenToCardId.set(binding.bindTo, card.id);
12258
12326
  }
@@ -12266,7 +12334,7 @@ function liveCardsToReactiveGraph(input, options = {}) {
12266
12334
  }
12267
12335
  tasks[card.id] = {
12268
12336
  requires: requires.length > 0 ? requires : void 0,
12269
- provides: (card.provides ?? [{ bindTo: card.id, src: "card_data" }]).map((p) => p.bindTo),
12337
+ provides: (card.provides ?? [{ bindTo: card.id, ref: "card_data" }]).map((p) => p.bindTo),
12270
12338
  taskHandlers: [card.id],
12271
12339
  description: card.meta?.title ?? card.id
12272
12340
  };
@@ -12287,7 +12355,7 @@ function liveCardsToReactiveGraph(input, options = {}) {
12287
12355
  graphRef.resolveCallback(token, data, errors);
12288
12356
  };
12289
12357
  for (const card of cards) {
12290
- if (card.sources && card.sources.length > 0) {
12358
+ if (card.source_defs && card.source_defs.length > 0) {
12291
12359
  handlers[card.id] = buildSourceHandler(card, sourceHandlers, defaultSourceHandler, sharedState, getResolve);
12292
12360
  } else {
12293
12361
  handlers[card.id] = buildCardHandler(card, cardHandlers, sharedState, cardMap, tokenToCardId, getResolve);
@@ -12351,8 +12419,8 @@ function buildCardHandler(card, cardHandlers, sharedState, _cardMap, tokenToCard
12351
12419
  let resultData;
12352
12420
  if (card.provides && card.provides.length > 0) {
12353
12421
  resultData = {};
12354
- for (const { bindTo, src } of card.provides) {
12355
- resultData[bindTo] = CardCompute.resolve(computeNode, src);
12422
+ for (const { bindTo, ref } of card.provides) {
12423
+ resultData[bindTo] = CardCompute.resolve(computeNode, ref);
12356
12424
  }
12357
12425
  } else {
12358
12426
  resultData = { ...computeNode.card_data, ...computeNode.computed_values };
@@ -12380,7 +12448,7 @@ function toTaskConfig(card) {
12380
12448
  function buildTokenProviders(cards) {
12381
12449
  const tokenToCardId = /* @__PURE__ */ new Map();
12382
12450
  for (const [cardId, card] of cards.entries()) {
12383
- const bindings = card.provides && card.provides.length > 0 ? card.provides : [{ bindTo: cardId, src: "card_data" }];
12451
+ const bindings = card.provides && card.provides.length > 0 ? card.provides : [{ bindTo: cardId, ref: "card_data" }];
12384
12452
  for (const binding of bindings) tokenToCardId.set(binding.bindTo, cardId);
12385
12453
  }
12386
12454
  return tokenToCardId;
@@ -12436,14 +12504,14 @@ function createBoardLiveGraphRuntime(input, options = {}) {
12436
12504
  requiresData[token] = providesData2[token];
12437
12505
  }
12438
12506
  const sourcesData = {};
12439
- if (card.sources && card.sources.length > 0) {
12507
+ if (card.source_defs && card.source_defs.length > 0) {
12440
12508
  const adapter = sourceAdapters[cardId] ?? defaultSourceAdapter;
12441
12509
  const fetched = taskExecutor ? await taskExecutor({ card, input: inputArgs }) : adapter ? await adapter({ card, input: inputArgs }) : void 0;
12442
12510
  if (fetched && typeof fetched === "object") {
12443
- for (const src of card.sources) {
12511
+ for (const src of card.source_defs) {
12444
12512
  if (Object.prototype.hasOwnProperty.call(fetched, src.bindTo)) {
12445
12513
  sourcesData[src.bindTo] = fetched[src.bindTo];
12446
- } else if (card.sources.length === 1) {
12514
+ } else if (card.source_defs.length === 1) {
12447
12515
  sourcesData[src.bindTo] = fetched;
12448
12516
  }
12449
12517
  }
@@ -12453,7 +12521,7 @@ function createBoardLiveGraphRuntime(input, options = {}) {
12453
12521
  id: card.id,
12454
12522
  card_data: deepClone(card.card_data ?? {}),
12455
12523
  requires: requiresData,
12456
- sources: card.sources,
12524
+ source_defs: card.source_defs,
12457
12525
  compute: card.compute
12458
12526
  };
12459
12527
  computeNode._sourcesData = sourcesData;
@@ -12462,8 +12530,8 @@ function createBoardLiveGraphRuntime(input, options = {}) {
12462
12530
  }
12463
12531
  const providesData = {};
12464
12532
  if (card.provides && card.provides.length > 0) {
12465
- for (const { bindTo, src } of card.provides) {
12466
- providesData[bindTo] = CardCompute.resolve(computeNode, src);
12533
+ for (const { bindTo, ref } of card.provides) {
12534
+ providesData[bindTo] = CardCompute.resolve(computeNode, ref);
12467
12535
  }
12468
12536
  } else {
12469
12537
  providesData[card.id] = {