yaml-flow 5.2.6 → 5.3.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 (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 +61 -33
  4. package/browser/board-livegraph-engine.js.map +1 -1
  5. package/browser/card-compute.js +18 -18
  6. package/browser/live-cards.js +317 -156
  7. package/browser/live-cards.schema.json +15 -10
  8. package/dist/board-livegraph-runtime/index.cjs +61 -33
  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 +61 -33
  13. package/dist/board-livegraph-runtime/index.js.map +1 -1
  14. package/dist/card-compute/index.cjs +101 -39
  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 +101 -39
  19. package/dist/card-compute/index.js.map +1 -1
  20. package/dist/cli/board-live-cards-cli.cjs +7205 -202
  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 +7204 -202
  25. package/dist/cli/board-live-cards-cli.js.map +1 -1
  26. package/dist/continuous-event-graph/index.cjs +59 -31
  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 +59 -31
  31. package/dist/continuous-event-graph/index.js.map +1 -1
  32. package/dist/index.cjs +126 -54
  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 +126 -54
  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 +29 -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 +67 -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 +91 -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 +457 -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 +15 -10
package/dist/index.cjs CHANGED
@@ -10969,6 +10969,7 @@ function createReactiveGraph(configOrLive, options, executionId) {
10969
10969
  const inputQueue = new MemoryJournal();
10970
10970
  let live = "state" in configOrLive && "config" in configOrLive ? configOrLive : createLiveGraph(configOrLive, executionId);
10971
10971
  let disposed = false;
10972
+ const pendingHandlers = /* @__PURE__ */ new Set();
10972
10973
  const handlers = new Map(Object.entries(initialHandlers));
10973
10974
  const internalJournal = new MemoryJournal();
10974
10975
  let draining = false;
@@ -11011,7 +11012,7 @@ function createReactiveGraph(configOrLive, options, executionId) {
11011
11012
  const taskState = live.state.tasks[taskName];
11012
11013
  if (!taskState || taskState.status !== "running") continue;
11013
11014
  const callbackToken = encodeCallbackToken(taskName);
11014
- runPipeline(taskName, callbackToken, update).catch((error) => {
11015
+ const p = runPipeline(taskName, callbackToken, update).catch((error) => {
11015
11016
  if (disposed) return;
11016
11017
  internalJournal.append({
11017
11018
  type: "task-failed",
@@ -11020,7 +11021,10 @@ function createReactiveGraph(configOrLive, options, executionId) {
11020
11021
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11021
11022
  });
11022
11023
  drain();
11024
+ }).finally(() => {
11025
+ pendingHandlers.delete(p);
11023
11026
  });
11027
+ pendingHandlers.add(p);
11024
11028
  }
11025
11029
  }
11026
11030
  }
@@ -11080,7 +11084,7 @@ function createReactiveGraph(configOrLive, options, executionId) {
11080
11084
  });
11081
11085
  drain();
11082
11086
  const callbackToken = encodeCallbackToken(taskName);
11083
- runPipeline(taskName, callbackToken).catch((error) => {
11087
+ const p = runPipeline(taskName, callbackToken).catch((error) => {
11084
11088
  if (disposed) return;
11085
11089
  internalJournal.append({
11086
11090
  type: "task-failed",
@@ -11089,7 +11093,10 @@ function createReactiveGraph(configOrLive, options, executionId) {
11089
11093
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11090
11094
  });
11091
11095
  drain();
11096
+ }).finally(() => {
11097
+ pendingHandlers.delete(p);
11092
11098
  });
11099
+ pendingHandlers.add(p);
11093
11100
  }
11094
11101
  return {
11095
11102
  push(event) {
@@ -11203,7 +11210,10 @@ function createReactiveGraph(configOrLive, options, executionId) {
11203
11210
  getSchedule() {
11204
11211
  return schedule(live);
11205
11212
  },
11206
- dispose() {
11213
+ async dispose(options2) {
11214
+ if (options2?.wait && pendingHandlers.size > 0) {
11215
+ await Promise.allSettled([...pendingHandlers]);
11216
+ }
11207
11217
  disposed = true;
11208
11218
  }
11209
11219
  };
@@ -11670,10 +11680,10 @@ var live_cards_schema_default = {
11670
11680
  type: "array",
11671
11681
  items: {
11672
11682
  type: "object",
11673
- required: ["bindTo", "src"],
11683
+ required: ["bindTo", "ref"],
11674
11684
  properties: {
11675
11685
  bindTo: { type: "string", description: "Token name published downstream" },
11676
- src: { type: "string", description: "Path to read value from (card_data.*, requires.*, fetched_sources.*, computed_values.*)" }
11686
+ ref: { type: "string", description: "Path to read value from (card_data.*, requires.*, fetched_sources.*, computed_values.*)" }
11677
11687
  }
11678
11688
  },
11679
11689
  description: "Explicit bindings exposing computed or card_data values downstream as named tokens"
@@ -11688,14 +11698,19 @@ var live_cards_schema_default = {
11688
11698
  }
11689
11699
  },
11690
11700
  source_def: {
11691
- 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.",
11701
+ 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.",
11692
11702
  type: "object",
11693
11703
  required: ["bindTo", "outputFile"],
11694
11704
  additionalProperties: true,
11695
11705
  properties: {
11696
11706
  bindTo: { type: "string", description: "Key under fetched_sources.* available in compute expressions" },
11697
11707
  outputFile: { type: "string", description: "Board-relative path the executor writes its JSON result to. Presence of this file signals delivery." },
11698
- 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." },
11708
+ projections: {
11709
+ type: "object",
11710
+ 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.",
11711
+ additionalProperties: { type: "string" }
11712
+ },
11713
+ 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." },
11699
11714
  timeout: { type: "integer", minimum: 0, default: 12e4, description: "Executor/script timeout in ms. Default: 120 000 (2 min)." },
11700
11715
  script: { type: "string", description: "Legacy direct-run: shell command executed when no .task-executor is registered. stdout is captured as the result." }
11701
11716
  }
@@ -11721,6 +11736,7 @@ var live_cards_schema_default = {
11721
11736
  "badge",
11722
11737
  "text",
11723
11738
  "markdown",
11739
+ "ref",
11724
11740
  "custom",
11725
11741
  "actions"
11726
11742
  ]
@@ -11815,7 +11831,7 @@ var live_cards_schema_default = {
11815
11831
  }
11816
11832
  },
11817
11833
  title: "LiveCard",
11818
- description: "A unified card node. Behavior depends on which sections are present (sources, compute, view, etc.)",
11834
+ description: "A unified card node. Behavior depends on which sections are present (source_defs, compute, view, etc.)",
11819
11835
  type: "object",
11820
11836
  required: ["id"],
11821
11837
  additionalProperties: false,
@@ -11858,22 +11874,22 @@ var live_cards_schema_default = {
11858
11874
  },
11859
11875
  llm_task_completion_inference: {
11860
11876
  type: "object",
11861
- description: "Runtime state written by the inference adapter (advanced/undocumented). Prefer the standard sources \u2192 compute \u2192 provides pattern for LLM-based signals.",
11877
+ description: "Runtime state written by the inference adapter (advanced/undocumented). Prefer the standard source_defs \u2192 compute \u2192 provides pattern for LLM-based signals.",
11862
11878
  properties: {
11863
11879
  inferenceRequested: { type: "string", format: "date-time", description: "Timestamp when the latest inference request was initiated" },
11864
11880
  inferenceCompletedAt: { type: "string", format: "date-time", description: "Timestamp when the latest inference request completed" },
11865
11881
  isTaskCompleted: { type: "boolean", description: "Whether the task is considered complete by the adapter" },
11866
11882
  reasoning: { type: "string", description: "Explanation of completion decision" },
11867
- evidence: { type: "array", description: "Supporting evidence from sources/compute" }
11883
+ evidence: { type: "array", description: "Supporting evidence from source_defs/compute" }
11868
11884
  },
11869
11885
  additionalProperties: true
11870
11886
  }
11871
11887
  },
11872
11888
  additionalProperties: true
11873
11889
  },
11874
- sources: {
11890
+ source_defs: {
11875
11891
  type: "array",
11876
- 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.",
11892
+ 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.",
11877
11893
  items: { $ref: "#/definitions/source_def" }
11878
11894
  },
11879
11895
  compute: {
@@ -11891,8 +11907,8 @@ var live_cards_schema_default = {
11891
11907
  // src/card-compute/schema-validator.ts
11892
11908
  var import_ajv3 = __toESM(require_ajv());
11893
11909
  var _compiled3 = null;
11894
- var NAMESPACE_REFERENCE_RE = /\b(card_data|requires|fetched_sources|computed_values|sources)\b/g;
11895
- var ROOT_PATH_NAMESPACE_RE = /^\s*(card_data|requires|fetched_sources|computed_values|sources)(\.|$)/;
11910
+ var NAMESPACE_REFERENCE_RE = /\b(card_data|requires|fetched_sources|computed_values|source_defs)\b/g;
11911
+ var ROOT_PATH_NAMESPACE_RE = /^\s*(card_data|requires|fetched_sources|computed_values|source_defs)(\.|$)/;
11896
11912
  function referencedNamespaces(expression) {
11897
11913
  const namespaces = /* @__PURE__ */ new Set();
11898
11914
  let match;
@@ -11957,22 +11973,22 @@ function validateLiveCardSchema(node) {
11957
11973
  return `${path}: ${e.message ?? "unknown error"}`;
11958
11974
  });
11959
11975
  if (node && typeof node === "object" && !Array.isArray(node)) {
11960
- const sources = node.sources;
11961
- if (Array.isArray(sources)) {
11976
+ const source_defs = node.source_defs;
11977
+ if (Array.isArray(source_defs)) {
11962
11978
  const bindTos = /* @__PURE__ */ new Set();
11963
11979
  const outputFiles = /* @__PURE__ */ new Set();
11964
- sources.forEach((src, i) => {
11980
+ source_defs.forEach((src, i) => {
11965
11981
  if (!src || typeof src !== "object" || Array.isArray(src)) return;
11966
11982
  const s = src;
11967
11983
  if (typeof s.bindTo === "string" && s.bindTo) {
11968
11984
  if (bindTos.has(s.bindTo)) {
11969
- errors.push(`/sources/${i}/bindTo: bindTo "${s.bindTo}" must be unique across all sources`);
11985
+ errors.push(`/source_defs/${i}/bindTo: bindTo "${s.bindTo}" must be unique across all source_defs`);
11970
11986
  }
11971
11987
  bindTos.add(s.bindTo);
11972
11988
  }
11973
11989
  if (typeof s.outputFile === "string" && s.outputFile) {
11974
11990
  if (outputFiles.has(s.outputFile)) {
11975
- errors.push(`/sources/${i}/outputFile: outputFile "${s.outputFile}" must be unique across all sources`);
11991
+ errors.push(`/source_defs/${i}/outputFile: outputFile "${s.outputFile}" must be unique across all source_defs`);
11976
11992
  }
11977
11993
  outputFiles.add(s.outputFile);
11978
11994
  }
@@ -12002,10 +12018,48 @@ function validateLiveCardRuntimeExpressions(node) {
12002
12018
  );
12003
12019
  });
12004
12020
  }
12021
+ const VALID_PROVIDES_SRC_NAMESPACES = /* @__PURE__ */ new Set([
12022
+ "card_data",
12023
+ "requires",
12024
+ "fetched_sources",
12025
+ "computed_values"
12026
+ ]);
12027
+ const provides = asRecord.provides;
12028
+ if (Array.isArray(provides)) {
12029
+ provides.forEach((entry, i) => {
12030
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) return;
12031
+ const ref = entry.ref;
12032
+ if (typeof ref !== "string" || ref.trim().length === 0) return;
12033
+ const rootNamespace = parseRootPathNamespace(ref);
12034
+ if (rootNamespace === null) {
12035
+ errors.push(`/provides/${i}/ref: path "${ref}" must start with a valid namespace (${[...VALID_PROVIDES_SRC_NAMESPACES].join(", ")})`);
12036
+ } else if (!VALID_PROVIDES_SRC_NAMESPACES.has(rootNamespace)) {
12037
+ errors.push(`/provides/${i}/ref: disallowed namespace "${rootNamespace}" in path "${ref}" (valid: ${[...VALID_PROVIDES_SRC_NAMESPACES].join(", ")})`);
12038
+ }
12039
+ });
12040
+ }
12005
12041
  const view = asRecord.view;
12006
12042
  if (view && typeof view === "object" && !Array.isArray(view)) {
12007
12043
  walkViewPathReferences(view, "/view", errors);
12008
12044
  }
12045
+ const VALID_PROJECTION_NAMESPACES = /* @__PURE__ */ new Set(["card_data", "requires"]);
12046
+ const source_defs = asRecord.source_defs;
12047
+ if (Array.isArray(source_defs)) {
12048
+ source_defs.forEach((srcDef, i) => {
12049
+ if (!srcDef || typeof srcDef !== "object" || Array.isArray(srcDef)) return;
12050
+ const projections = srcDef.projections;
12051
+ if (!projections || typeof projections !== "object" || Array.isArray(projections)) return;
12052
+ for (const [key, exprVal] of Object.entries(projections)) {
12053
+ if (typeof exprVal !== "string" || exprVal.trim().length === 0) continue;
12054
+ validateJsonataExprWithNamespaces(
12055
+ exprVal,
12056
+ `/source_defs/${i}/projections/${key}`,
12057
+ VALID_PROJECTION_NAMESPACES,
12058
+ errors
12059
+ );
12060
+ }
12061
+ });
12062
+ }
12009
12063
  return { ok: errors.length === 0, errors };
12010
12064
  }
12011
12065
  function validateLiveCard(node) {
@@ -12079,6 +12133,7 @@ function resolve(node, path) {
12079
12133
  var VALID_ELEMENT_KINDS = /* @__PURE__ */ new Set([
12080
12134
  "metric",
12081
12135
  "table",
12136
+ "editable-table",
12082
12137
  "chart",
12083
12138
  "form",
12084
12139
  "filter",
@@ -12090,9 +12145,11 @@ var VALID_ELEMENT_KINDS = /* @__PURE__ */ new Set([
12090
12145
  "badge",
12091
12146
  "text",
12092
12147
  "markdown",
12093
- "custom"
12148
+ "ref",
12149
+ "custom",
12150
+ "actions"
12094
12151
  ]);
12095
- var ALLOWED_KEYS = /* @__PURE__ */ new Set(["id", "meta", "requires", "provides", "view", "card_data", "compute", "sources"]);
12152
+ var ALLOWED_KEYS = /* @__PURE__ */ new Set(["id", "meta", "requires", "provides", "view", "card_data", "compute", "source_defs"]);
12096
12153
  function validateNode(node) {
12097
12154
  const errors = [];
12098
12155
  if (!node || typeof node !== "object" || Array.isArray(node)) {
@@ -12118,15 +12175,15 @@ function validateNode(node) {
12118
12175
  if (n.requires != null && !Array.isArray(n.requires)) errors.push("requires: must be an array of strings");
12119
12176
  if (n.provides != null) {
12120
12177
  if (!Array.isArray(n.provides)) {
12121
- errors.push("provides: must be an array of { bindTo, src } bindings");
12178
+ errors.push("provides: must be an array of { bindTo, ref } bindings");
12122
12179
  } else {
12123
12180
  n.provides.forEach((p, i) => {
12124
12181
  if (!p || typeof p !== "object" || Array.isArray(p)) {
12125
- errors.push(`provides[${i}]: must be an object with bindTo and src`);
12182
+ errors.push(`provides[${i}]: must be an object with bindTo and ref`);
12126
12183
  } else {
12127
12184
  const b = p;
12128
12185
  if (typeof b.bindTo !== "string" || !b.bindTo) errors.push(`provides[${i}]: missing required "bindTo" string`);
12129
- if (typeof b.src !== "string" || !b.src) errors.push(`provides[${i}]: missing required "src" string`);
12186
+ if (typeof b.ref !== "string" || !b.ref) errors.push(`provides[${i}]: missing required "ref" string`);
12130
12187
  }
12131
12188
  });
12132
12189
  }
@@ -12146,35 +12203,35 @@ function validateNode(node) {
12146
12203
  });
12147
12204
  }
12148
12205
  }
12149
- if (n.sources != null) {
12150
- if (!Array.isArray(n.sources)) {
12151
- errors.push("sources: must be an array");
12206
+ if (n.source_defs != null) {
12207
+ if (!Array.isArray(n.source_defs)) {
12208
+ errors.push("source_defs: must be an array");
12152
12209
  } else {
12153
12210
  const bindTos = /* @__PURE__ */ new Set();
12154
12211
  const outputFiles = /* @__PURE__ */ new Set();
12155
- n.sources.forEach((src, i) => {
12212
+ n.source_defs.forEach((src, i) => {
12156
12213
  if (!src || typeof src !== "object" || Array.isArray(src)) {
12157
- errors.push(`sources[${i}]: must be an object`);
12214
+ errors.push(`source_defs[${i}]: must be an object`);
12158
12215
  } else {
12159
12216
  const s = src;
12160
12217
  if (typeof s.bindTo !== "string" || !s.bindTo) {
12161
- errors.push(`sources[${i}]: missing required "bindTo" property`);
12218
+ errors.push(`source_defs[${i}]: missing required "bindTo" property`);
12162
12219
  } else {
12163
12220
  if (bindTos.has(s.bindTo)) {
12164
- errors.push(`sources[${i}]: bindTo "${s.bindTo}" is not unique across sources`);
12221
+ errors.push(`source_defs[${i}]: bindTo "${s.bindTo}" is not unique across source_defs`);
12165
12222
  }
12166
12223
  bindTos.add(s.bindTo);
12167
12224
  }
12168
12225
  if (typeof s.outputFile !== "string" || !s.outputFile) {
12169
- errors.push(`sources[${i}]: missing required "outputFile" property`);
12226
+ errors.push(`source_defs[${i}]: missing required "outputFile" property`);
12170
12227
  } else {
12171
12228
  if (outputFiles.has(s.outputFile)) {
12172
- errors.push(`sources[${i}]: outputFile "${s.outputFile}" is not unique across sources`);
12229
+ errors.push(`source_defs[${i}]: outputFile "${s.outputFile}" is not unique across source_defs`);
12173
12230
  }
12174
12231
  outputFiles.add(s.outputFile);
12175
12232
  }
12176
12233
  if (s.optionalForCompletionGating != null && typeof s.optionalForCompletionGating !== "boolean") {
12177
- errors.push(`sources[${i}]: optionalForCompletionGating must be a boolean`);
12234
+ errors.push(`source_defs[${i}]: optionalForCompletionGating must be a boolean`);
12178
12235
  }
12179
12236
  }
12180
12237
  });
@@ -12209,14 +12266,29 @@ function validateNode(node) {
12209
12266
  }
12210
12267
  return { ok: errors.length === 0, errors };
12211
12268
  }
12212
- function enrichSources(sources, context) {
12213
- if (!sources || sources.length === 0) return [];
12214
- return sources.map((src) => ({
12215
- ...src,
12216
- _requires: context.requires ?? {},
12217
- _sourcesData: context.sourcesData ?? {},
12218
- _computed_values: context.computed_values ?? {}
12219
- }));
12269
+ async function enrichSources(source_defs, context) {
12270
+ if (!source_defs || source_defs.length === 0) return [];
12271
+ const evalCtx = {
12272
+ card_data: context.card_data ?? {},
12273
+ requires: context.requires ?? {}
12274
+ };
12275
+ return Promise.all(
12276
+ source_defs.map(async (src) => {
12277
+ const _projections = {};
12278
+ if (src.projections && typeof src.projections === "object" && !Array.isArray(src.projections)) {
12279
+ for (const [key, expr] of Object.entries(src.projections)) {
12280
+ if (typeof expr === "string" && expr.trim().length > 0) {
12281
+ try {
12282
+ _projections[key] = await jsonata2__default.default(expr).evaluate(evalCtx);
12283
+ } catch {
12284
+ _projections[key] = void 0;
12285
+ }
12286
+ }
12287
+ }
12288
+ }
12289
+ return { ...src, _projections };
12290
+ })
12291
+ );
12220
12292
  }
12221
12293
  var CardCompute = {
12222
12294
  run,
@@ -12259,7 +12331,7 @@ function liveCardsToReactiveGraph(input, options = {}) {
12259
12331
  const allTokens = /* @__PURE__ */ new Set();
12260
12332
  const tokenToCardId = /* @__PURE__ */ new Map();
12261
12333
  for (const card of cards) {
12262
- for (const binding of card.provides ?? [{ bindTo: card.id, src: "card_data" }]) {
12334
+ for (const binding of card.provides ?? [{ bindTo: card.id, ref: "card_data" }]) {
12263
12335
  allTokens.add(binding.bindTo);
12264
12336
  tokenToCardId.set(binding.bindTo, card.id);
12265
12337
  }
@@ -12273,7 +12345,7 @@ function liveCardsToReactiveGraph(input, options = {}) {
12273
12345
  }
12274
12346
  tasks[card.id] = {
12275
12347
  requires: requires.length > 0 ? requires : void 0,
12276
- provides: (card.provides ?? [{ bindTo: card.id, src: "card_data" }]).map((p) => p.bindTo),
12348
+ provides: (card.provides ?? [{ bindTo: card.id, ref: "card_data" }]).map((p) => p.bindTo),
12277
12349
  taskHandlers: [card.id],
12278
12350
  description: card.meta?.title ?? card.id
12279
12351
  };
@@ -12294,7 +12366,7 @@ function liveCardsToReactiveGraph(input, options = {}) {
12294
12366
  graphRef.resolveCallback(token, data, errors);
12295
12367
  };
12296
12368
  for (const card of cards) {
12297
- if (card.sources && card.sources.length > 0) {
12369
+ if (card.source_defs && card.source_defs.length > 0) {
12298
12370
  handlers[card.id] = buildSourceHandler(card, sourceHandlers, defaultSourceHandler, sharedState, getResolve);
12299
12371
  } else {
12300
12372
  handlers[card.id] = buildCardHandler(card, cardHandlers, sharedState, cardMap, tokenToCardId, getResolve);
@@ -12358,8 +12430,8 @@ function buildCardHandler(card, cardHandlers, sharedState, _cardMap, tokenToCard
12358
12430
  let resultData;
12359
12431
  if (card.provides && card.provides.length > 0) {
12360
12432
  resultData = {};
12361
- for (const { bindTo, src } of card.provides) {
12362
- resultData[bindTo] = CardCompute.resolve(computeNode, src);
12433
+ for (const { bindTo, ref } of card.provides) {
12434
+ resultData[bindTo] = CardCompute.resolve(computeNode, ref);
12363
12435
  }
12364
12436
  } else {
12365
12437
  resultData = { ...computeNode.card_data, ...computeNode.computed_values };
@@ -12387,7 +12459,7 @@ function toTaskConfig(card) {
12387
12459
  function buildTokenProviders(cards) {
12388
12460
  const tokenToCardId = /* @__PURE__ */ new Map();
12389
12461
  for (const [cardId, card] of cards.entries()) {
12390
- const bindings = card.provides && card.provides.length > 0 ? card.provides : [{ bindTo: cardId, src: "card_data" }];
12462
+ const bindings = card.provides && card.provides.length > 0 ? card.provides : [{ bindTo: cardId, ref: "card_data" }];
12391
12463
  for (const binding of bindings) tokenToCardId.set(binding.bindTo, cardId);
12392
12464
  }
12393
12465
  return tokenToCardId;
@@ -12443,14 +12515,14 @@ function createBoardLiveGraphRuntime(input, options = {}) {
12443
12515
  requiresData[token] = providesData2[token];
12444
12516
  }
12445
12517
  const sourcesData = {};
12446
- if (card.sources && card.sources.length > 0) {
12518
+ if (card.source_defs && card.source_defs.length > 0) {
12447
12519
  const adapter = sourceAdapters[cardId] ?? defaultSourceAdapter;
12448
12520
  const fetched = taskExecutor ? await taskExecutor({ card, input: inputArgs }) : adapter ? await adapter({ card, input: inputArgs }) : void 0;
12449
12521
  if (fetched && typeof fetched === "object") {
12450
- for (const src of card.sources) {
12522
+ for (const src of card.source_defs) {
12451
12523
  if (Object.prototype.hasOwnProperty.call(fetched, src.bindTo)) {
12452
12524
  sourcesData[src.bindTo] = fetched[src.bindTo];
12453
- } else if (card.sources.length === 1) {
12525
+ } else if (card.source_defs.length === 1) {
12454
12526
  sourcesData[src.bindTo] = fetched;
12455
12527
  }
12456
12528
  }
@@ -12460,7 +12532,7 @@ function createBoardLiveGraphRuntime(input, options = {}) {
12460
12532
  id: card.id,
12461
12533
  card_data: deepClone(card.card_data ?? {}),
12462
12534
  requires: requiresData,
12463
- sources: card.sources,
12535
+ source_defs: card.source_defs,
12464
12536
  compute: card.compute
12465
12537
  };
12466
12538
  computeNode._sourcesData = sourcesData;
@@ -12469,8 +12541,8 @@ function createBoardLiveGraphRuntime(input, options = {}) {
12469
12541
  }
12470
12542
  const providesData = {};
12471
12543
  if (card.provides && card.provides.length > 0) {
12472
- for (const { bindTo, src } of card.provides) {
12473
- providesData[bindTo] = CardCompute.resolve(computeNode, src);
12544
+ for (const { bindTo, ref } of card.provides) {
12545
+ providesData[bindTo] = CardCompute.resolve(computeNode, ref);
12474
12546
  }
12475
12547
  } else {
12476
12548
  providesData[card.id] = {