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.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
  }
@@ -11714,6 +11729,7 @@ var live_cards_schema_default = {
11714
11729
  "badge",
11715
11730
  "text",
11716
11731
  "markdown",
11732
+ "ref",
11717
11733
  "custom",
11718
11734
  "actions"
11719
11735
  ]
@@ -11808,7 +11824,7 @@ var live_cards_schema_default = {
11808
11824
  }
11809
11825
  },
11810
11826
  title: "LiveCard",
11811
- description: "A unified card node. Behavior depends on which sections are present (sources, compute, view, etc.)",
11827
+ description: "A unified card node. Behavior depends on which sections are present (source_defs, compute, view, etc.)",
11812
11828
  type: "object",
11813
11829
  required: ["id"],
11814
11830
  additionalProperties: false,
@@ -11851,22 +11867,22 @@ var live_cards_schema_default = {
11851
11867
  },
11852
11868
  llm_task_completion_inference: {
11853
11869
  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.",
11870
+ 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
11871
  properties: {
11856
11872
  inferenceRequested: { type: "string", format: "date-time", description: "Timestamp when the latest inference request was initiated" },
11857
11873
  inferenceCompletedAt: { type: "string", format: "date-time", description: "Timestamp when the latest inference request completed" },
11858
11874
  isTaskCompleted: { type: "boolean", description: "Whether the task is considered complete by the adapter" },
11859
11875
  reasoning: { type: "string", description: "Explanation of completion decision" },
11860
- evidence: { type: "array", description: "Supporting evidence from sources/compute" }
11876
+ evidence: { type: "array", description: "Supporting evidence from source_defs/compute" }
11861
11877
  },
11862
11878
  additionalProperties: true
11863
11879
  }
11864
11880
  },
11865
11881
  additionalProperties: true
11866
11882
  },
11867
- sources: {
11883
+ source_defs: {
11868
11884
  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.",
11885
+ 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
11886
  items: { $ref: "#/definitions/source_def" }
11871
11887
  },
11872
11888
  compute: {
@@ -11884,8 +11900,8 @@ var live_cards_schema_default = {
11884
11900
  // src/card-compute/schema-validator.ts
11885
11901
  var import_ajv3 = __toESM(require_ajv());
11886
11902
  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)(\.|$)/;
11903
+ var NAMESPACE_REFERENCE_RE = /\b(card_data|requires|fetched_sources|computed_values|source_defs)\b/g;
11904
+ var ROOT_PATH_NAMESPACE_RE = /^\s*(card_data|requires|fetched_sources|computed_values|source_defs)(\.|$)/;
11889
11905
  function referencedNamespaces(expression) {
11890
11906
  const namespaces = /* @__PURE__ */ new Set();
11891
11907
  let match;
@@ -11950,22 +11966,22 @@ function validateLiveCardSchema(node) {
11950
11966
  return `${path}: ${e.message ?? "unknown error"}`;
11951
11967
  });
11952
11968
  if (node && typeof node === "object" && !Array.isArray(node)) {
11953
- const sources = node.sources;
11954
- if (Array.isArray(sources)) {
11969
+ const source_defs = node.source_defs;
11970
+ if (Array.isArray(source_defs)) {
11955
11971
  const bindTos = /* @__PURE__ */ new Set();
11956
11972
  const outputFiles = /* @__PURE__ */ new Set();
11957
- sources.forEach((src, i) => {
11973
+ source_defs.forEach((src, i) => {
11958
11974
  if (!src || typeof src !== "object" || Array.isArray(src)) return;
11959
11975
  const s = src;
11960
11976
  if (typeof s.bindTo === "string" && s.bindTo) {
11961
11977
  if (bindTos.has(s.bindTo)) {
11962
- errors.push(`/sources/${i}/bindTo: bindTo "${s.bindTo}" must be unique across all sources`);
11978
+ errors.push(`/source_defs/${i}/bindTo: bindTo "${s.bindTo}" must be unique across all source_defs`);
11963
11979
  }
11964
11980
  bindTos.add(s.bindTo);
11965
11981
  }
11966
11982
  if (typeof s.outputFile === "string" && s.outputFile) {
11967
11983
  if (outputFiles.has(s.outputFile)) {
11968
- errors.push(`/sources/${i}/outputFile: outputFile "${s.outputFile}" must be unique across all sources`);
11984
+ errors.push(`/source_defs/${i}/outputFile: outputFile "${s.outputFile}" must be unique across all source_defs`);
11969
11985
  }
11970
11986
  outputFiles.add(s.outputFile);
11971
11987
  }
@@ -11995,10 +12011,48 @@ function validateLiveCardRuntimeExpressions(node) {
11995
12011
  );
11996
12012
  });
11997
12013
  }
12014
+ const VALID_PROVIDES_SRC_NAMESPACES = /* @__PURE__ */ new Set([
12015
+ "card_data",
12016
+ "requires",
12017
+ "fetched_sources",
12018
+ "computed_values"
12019
+ ]);
12020
+ const provides = asRecord.provides;
12021
+ if (Array.isArray(provides)) {
12022
+ provides.forEach((entry, i) => {
12023
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) return;
12024
+ const ref = entry.ref;
12025
+ if (typeof ref !== "string" || ref.trim().length === 0) return;
12026
+ const rootNamespace = parseRootPathNamespace(ref);
12027
+ if (rootNamespace === null) {
12028
+ errors.push(`/provides/${i}/ref: path "${ref}" must start with a valid namespace (${[...VALID_PROVIDES_SRC_NAMESPACES].join(", ")})`);
12029
+ } else if (!VALID_PROVIDES_SRC_NAMESPACES.has(rootNamespace)) {
12030
+ errors.push(`/provides/${i}/ref: disallowed namespace "${rootNamespace}" in path "${ref}" (valid: ${[...VALID_PROVIDES_SRC_NAMESPACES].join(", ")})`);
12031
+ }
12032
+ });
12033
+ }
11998
12034
  const view = asRecord.view;
11999
12035
  if (view && typeof view === "object" && !Array.isArray(view)) {
12000
12036
  walkViewPathReferences(view, "/view", errors);
12001
12037
  }
12038
+ const VALID_PROJECTION_NAMESPACES = /* @__PURE__ */ new Set(["card_data", "requires"]);
12039
+ const source_defs = asRecord.source_defs;
12040
+ if (Array.isArray(source_defs)) {
12041
+ source_defs.forEach((srcDef, i) => {
12042
+ if (!srcDef || typeof srcDef !== "object" || Array.isArray(srcDef)) return;
12043
+ const projections = srcDef.projections;
12044
+ if (!projections || typeof projections !== "object" || Array.isArray(projections)) return;
12045
+ for (const [key, exprVal] of Object.entries(projections)) {
12046
+ if (typeof exprVal !== "string" || exprVal.trim().length === 0) continue;
12047
+ validateJsonataExprWithNamespaces(
12048
+ exprVal,
12049
+ `/source_defs/${i}/projections/${key}`,
12050
+ VALID_PROJECTION_NAMESPACES,
12051
+ errors
12052
+ );
12053
+ }
12054
+ });
12055
+ }
12002
12056
  return { ok: errors.length === 0, errors };
12003
12057
  }
12004
12058
  function validateLiveCard(node) {
@@ -12072,6 +12126,7 @@ function resolve(node, path) {
12072
12126
  var VALID_ELEMENT_KINDS = /* @__PURE__ */ new Set([
12073
12127
  "metric",
12074
12128
  "table",
12129
+ "editable-table",
12075
12130
  "chart",
12076
12131
  "form",
12077
12132
  "filter",
@@ -12083,9 +12138,11 @@ var VALID_ELEMENT_KINDS = /* @__PURE__ */ new Set([
12083
12138
  "badge",
12084
12139
  "text",
12085
12140
  "markdown",
12086
- "custom"
12141
+ "ref",
12142
+ "custom",
12143
+ "actions"
12087
12144
  ]);
12088
- var ALLOWED_KEYS = /* @__PURE__ */ new Set(["id", "meta", "requires", "provides", "view", "card_data", "compute", "sources"]);
12145
+ var ALLOWED_KEYS = /* @__PURE__ */ new Set(["id", "meta", "requires", "provides", "view", "card_data", "compute", "source_defs"]);
12089
12146
  function validateNode(node) {
12090
12147
  const errors = [];
12091
12148
  if (!node || typeof node !== "object" || Array.isArray(node)) {
@@ -12111,15 +12168,15 @@ function validateNode(node) {
12111
12168
  if (n.requires != null && !Array.isArray(n.requires)) errors.push("requires: must be an array of strings");
12112
12169
  if (n.provides != null) {
12113
12170
  if (!Array.isArray(n.provides)) {
12114
- errors.push("provides: must be an array of { bindTo, src } bindings");
12171
+ errors.push("provides: must be an array of { bindTo, ref } bindings");
12115
12172
  } else {
12116
12173
  n.provides.forEach((p, i) => {
12117
12174
  if (!p || typeof p !== "object" || Array.isArray(p)) {
12118
- errors.push(`provides[${i}]: must be an object with bindTo and src`);
12175
+ errors.push(`provides[${i}]: must be an object with bindTo and ref`);
12119
12176
  } else {
12120
12177
  const b = p;
12121
12178
  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`);
12179
+ if (typeof b.ref !== "string" || !b.ref) errors.push(`provides[${i}]: missing required "ref" string`);
12123
12180
  }
12124
12181
  });
12125
12182
  }
@@ -12139,35 +12196,35 @@ function validateNode(node) {
12139
12196
  });
12140
12197
  }
12141
12198
  }
12142
- if (n.sources != null) {
12143
- if (!Array.isArray(n.sources)) {
12144
- errors.push("sources: must be an array");
12199
+ if (n.source_defs != null) {
12200
+ if (!Array.isArray(n.source_defs)) {
12201
+ errors.push("source_defs: must be an array");
12145
12202
  } else {
12146
12203
  const bindTos = /* @__PURE__ */ new Set();
12147
12204
  const outputFiles = /* @__PURE__ */ new Set();
12148
- n.sources.forEach((src, i) => {
12205
+ n.source_defs.forEach((src, i) => {
12149
12206
  if (!src || typeof src !== "object" || Array.isArray(src)) {
12150
- errors.push(`sources[${i}]: must be an object`);
12207
+ errors.push(`source_defs[${i}]: must be an object`);
12151
12208
  } else {
12152
12209
  const s = src;
12153
12210
  if (typeof s.bindTo !== "string" || !s.bindTo) {
12154
- errors.push(`sources[${i}]: missing required "bindTo" property`);
12211
+ errors.push(`source_defs[${i}]: missing required "bindTo" property`);
12155
12212
  } else {
12156
12213
  if (bindTos.has(s.bindTo)) {
12157
- errors.push(`sources[${i}]: bindTo "${s.bindTo}" is not unique across sources`);
12214
+ errors.push(`source_defs[${i}]: bindTo "${s.bindTo}" is not unique across source_defs`);
12158
12215
  }
12159
12216
  bindTos.add(s.bindTo);
12160
12217
  }
12161
12218
  if (typeof s.outputFile !== "string" || !s.outputFile) {
12162
- errors.push(`sources[${i}]: missing required "outputFile" property`);
12219
+ errors.push(`source_defs[${i}]: missing required "outputFile" property`);
12163
12220
  } else {
12164
12221
  if (outputFiles.has(s.outputFile)) {
12165
- errors.push(`sources[${i}]: outputFile "${s.outputFile}" is not unique across sources`);
12222
+ errors.push(`source_defs[${i}]: outputFile "${s.outputFile}" is not unique across source_defs`);
12166
12223
  }
12167
12224
  outputFiles.add(s.outputFile);
12168
12225
  }
12169
12226
  if (s.optionalForCompletionGating != null && typeof s.optionalForCompletionGating !== "boolean") {
12170
- errors.push(`sources[${i}]: optionalForCompletionGating must be a boolean`);
12227
+ errors.push(`source_defs[${i}]: optionalForCompletionGating must be a boolean`);
12171
12228
  }
12172
12229
  }
12173
12230
  });
@@ -12202,14 +12259,29 @@ function validateNode(node) {
12202
12259
  }
12203
12260
  return { ok: errors.length === 0, errors };
12204
12261
  }
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
- }));
12262
+ async function enrichSources(source_defs, context) {
12263
+ if (!source_defs || source_defs.length === 0) return [];
12264
+ const evalCtx = {
12265
+ card_data: context.card_data ?? {},
12266
+ requires: context.requires ?? {}
12267
+ };
12268
+ return Promise.all(
12269
+ source_defs.map(async (src) => {
12270
+ const _projections = {};
12271
+ if (src.projections && typeof src.projections === "object" && !Array.isArray(src.projections)) {
12272
+ for (const [key, expr] of Object.entries(src.projections)) {
12273
+ if (typeof expr === "string" && expr.trim().length > 0) {
12274
+ try {
12275
+ _projections[key] = await jsonata2(expr).evaluate(evalCtx);
12276
+ } catch {
12277
+ _projections[key] = void 0;
12278
+ }
12279
+ }
12280
+ }
12281
+ }
12282
+ return { ...src, _projections };
12283
+ })
12284
+ );
12213
12285
  }
12214
12286
  var CardCompute = {
12215
12287
  run,
@@ -12252,7 +12324,7 @@ function liveCardsToReactiveGraph(input, options = {}) {
12252
12324
  const allTokens = /* @__PURE__ */ new Set();
12253
12325
  const tokenToCardId = /* @__PURE__ */ new Map();
12254
12326
  for (const card of cards) {
12255
- for (const binding of card.provides ?? [{ bindTo: card.id, src: "card_data" }]) {
12327
+ for (const binding of card.provides ?? [{ bindTo: card.id, ref: "card_data" }]) {
12256
12328
  allTokens.add(binding.bindTo);
12257
12329
  tokenToCardId.set(binding.bindTo, card.id);
12258
12330
  }
@@ -12266,7 +12338,7 @@ function liveCardsToReactiveGraph(input, options = {}) {
12266
12338
  }
12267
12339
  tasks[card.id] = {
12268
12340
  requires: requires.length > 0 ? requires : void 0,
12269
- provides: (card.provides ?? [{ bindTo: card.id, src: "card_data" }]).map((p) => p.bindTo),
12341
+ provides: (card.provides ?? [{ bindTo: card.id, ref: "card_data" }]).map((p) => p.bindTo),
12270
12342
  taskHandlers: [card.id],
12271
12343
  description: card.meta?.title ?? card.id
12272
12344
  };
@@ -12287,7 +12359,7 @@ function liveCardsToReactiveGraph(input, options = {}) {
12287
12359
  graphRef.resolveCallback(token, data, errors);
12288
12360
  };
12289
12361
  for (const card of cards) {
12290
- if (card.sources && card.sources.length > 0) {
12362
+ if (card.source_defs && card.source_defs.length > 0) {
12291
12363
  handlers[card.id] = buildSourceHandler(card, sourceHandlers, defaultSourceHandler, sharedState, getResolve);
12292
12364
  } else {
12293
12365
  handlers[card.id] = buildCardHandler(card, cardHandlers, sharedState, cardMap, tokenToCardId, getResolve);
@@ -12351,8 +12423,8 @@ function buildCardHandler(card, cardHandlers, sharedState, _cardMap, tokenToCard
12351
12423
  let resultData;
12352
12424
  if (card.provides && card.provides.length > 0) {
12353
12425
  resultData = {};
12354
- for (const { bindTo, src } of card.provides) {
12355
- resultData[bindTo] = CardCompute.resolve(computeNode, src);
12426
+ for (const { bindTo, ref } of card.provides) {
12427
+ resultData[bindTo] = CardCompute.resolve(computeNode, ref);
12356
12428
  }
12357
12429
  } else {
12358
12430
  resultData = { ...computeNode.card_data, ...computeNode.computed_values };
@@ -12380,7 +12452,7 @@ function toTaskConfig(card) {
12380
12452
  function buildTokenProviders(cards) {
12381
12453
  const tokenToCardId = /* @__PURE__ */ new Map();
12382
12454
  for (const [cardId, card] of cards.entries()) {
12383
- const bindings = card.provides && card.provides.length > 0 ? card.provides : [{ bindTo: cardId, src: "card_data" }];
12455
+ const bindings = card.provides && card.provides.length > 0 ? card.provides : [{ bindTo: cardId, ref: "card_data" }];
12384
12456
  for (const binding of bindings) tokenToCardId.set(binding.bindTo, cardId);
12385
12457
  }
12386
12458
  return tokenToCardId;
@@ -12436,14 +12508,14 @@ function createBoardLiveGraphRuntime(input, options = {}) {
12436
12508
  requiresData[token] = providesData2[token];
12437
12509
  }
12438
12510
  const sourcesData = {};
12439
- if (card.sources && card.sources.length > 0) {
12511
+ if (card.source_defs && card.source_defs.length > 0) {
12440
12512
  const adapter = sourceAdapters[cardId] ?? defaultSourceAdapter;
12441
12513
  const fetched = taskExecutor ? await taskExecutor({ card, input: inputArgs }) : adapter ? await adapter({ card, input: inputArgs }) : void 0;
12442
12514
  if (fetched && typeof fetched === "object") {
12443
- for (const src of card.sources) {
12515
+ for (const src of card.source_defs) {
12444
12516
  if (Object.prototype.hasOwnProperty.call(fetched, src.bindTo)) {
12445
12517
  sourcesData[src.bindTo] = fetched[src.bindTo];
12446
- } else if (card.sources.length === 1) {
12518
+ } else if (card.source_defs.length === 1) {
12447
12519
  sourcesData[src.bindTo] = fetched;
12448
12520
  }
12449
12521
  }
@@ -12453,7 +12525,7 @@ function createBoardLiveGraphRuntime(input, options = {}) {
12453
12525
  id: card.id,
12454
12526
  card_data: deepClone(card.card_data ?? {}),
12455
12527
  requires: requiresData,
12456
- sources: card.sources,
12528
+ source_defs: card.source_defs,
12457
12529
  compute: card.compute
12458
12530
  };
12459
12531
  computeNode._sourcesData = sourcesData;
@@ -12462,8 +12534,8 @@ function createBoardLiveGraphRuntime(input, options = {}) {
12462
12534
  }
12463
12535
  const providesData = {};
12464
12536
  if (card.provides && card.provides.length > 0) {
12465
- for (const { bindTo, src } of card.provides) {
12466
- providesData[bindTo] = CardCompute.resolve(computeNode, src);
12537
+ for (const { bindTo, ref } of card.provides) {
12538
+ providesData[bindTo] = CardCompute.resolve(computeNode, ref);
12467
12539
  }
12468
12540
  } else {
12469
12541
  providesData[card.id] = {