yaml-flow 5.4.2 → 7.0.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 (252) hide show
  1. package/board-live-cards-cli.js +6 -6
  2. package/browser/asset-integrity.json +10 -0
  3. package/browser/board-livecards-client.js +2 -0
  4. package/browser/board-livecards-client.js.map +1 -0
  5. package/browser/board-livecards-localstorage.js +10 -0
  6. package/browser/board-livecards-localstorage.js.map +1 -0
  7. package/browser/board-livegraph-engine.js +2 -1676
  8. package/browser/board-livegraph-engine.js.map +1 -1
  9. package/browser/card-compute.js +28 -28
  10. package/browser/compute-jsonata.js +5 -0
  11. package/browser/compute-jsonata.js.map +1 -0
  12. package/browser/live-cards.js +561 -129
  13. package/browser/live-cards.schema.json +418 -132
  14. package/card-store.js +37 -0
  15. package/dist/batch/index.cjs +1 -108
  16. package/dist/batch/index.cjs.map +1 -1
  17. package/dist/batch/index.js +1 -106
  18. package/dist/batch/index.js.map +1 -1
  19. package/dist/board-live-cards-lib-Bg6EvCo5.d.cts +136 -0
  20. package/dist/board-live-cards-lib-jM2uYG1v.d.ts +136 -0
  21. package/dist/board-live-cards-public-CW5074xr.d.cts +318 -0
  22. package/dist/board-live-cards-public-hnZo0mAf.d.ts +318 -0
  23. package/dist/board-livegraph-runtime/index.cjs +2 -1671
  24. package/dist/board-livegraph-runtime/index.cjs.map +1 -1
  25. package/dist/board-livegraph-runtime/index.d.cts +12 -11
  26. package/dist/board-livegraph-runtime/index.d.ts +12 -11
  27. package/dist/board-livegraph-runtime/index.js +2 -1662
  28. package/dist/board-livegraph-runtime/index.js.map +1 -1
  29. package/dist/board-livegraph-runtime/jsonata-sync.cjs +7623 -0
  30. package/dist/card-compute/index.cjs +9 -7159
  31. package/dist/card-compute/index.cjs.map +1 -1
  32. package/dist/card-compute/index.d.cts +27 -1
  33. package/dist/card-compute/index.d.ts +27 -1
  34. package/dist/card-compute/index.js +9 -7145
  35. package/dist/card-compute/index.js.map +1 -1
  36. package/dist/card-compute/jsonata-sync.cjs +7623 -0
  37. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs +3 -0
  38. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs.map +1 -0
  39. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.cts +37 -0
  40. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.ts +37 -0
  41. package/dist/cli/browser-api/board-live-cards-browser-adapter.js +3 -0
  42. package/dist/cli/browser-api/board-live-cards-browser-adapter.js.map +1 -0
  43. package/dist/cli/browser-api/card-store-browser-api.cjs +2 -0
  44. package/dist/cli/browser-api/card-store-browser-api.cjs.map +1 -0
  45. package/dist/cli/browser-api/card-store-browser-api.d.cts +26 -0
  46. package/dist/cli/browser-api/card-store-browser-api.d.ts +26 -0
  47. package/dist/cli/browser-api/card-store-browser-api.js +2 -0
  48. package/dist/cli/browser-api/card-store-browser-api.js.map +1 -0
  49. package/dist/cli/browser-api/jsonata-sync.cjs +7623 -0
  50. package/dist/cli/node/artifacts-store-cli.cjs +11 -0
  51. package/dist/cli/node/artifacts-store-cli.cjs.map +1 -0
  52. package/dist/cli/node/artifacts-store-cli.d.cts +8 -0
  53. package/dist/cli/node/artifacts-store-cli.d.ts +8 -0
  54. package/dist/cli/node/artifacts-store-cli.js +11 -0
  55. package/dist/cli/node/artifacts-store-cli.js.map +1 -0
  56. package/dist/cli/node/board-live-cards-cli.cjs +15 -0
  57. package/dist/cli/node/board-live-cards-cli.cjs.map +1 -0
  58. package/dist/cli/node/board-live-cards-cli.d.cts +20 -0
  59. package/dist/cli/node/board-live-cards-cli.d.ts +20 -0
  60. package/dist/cli/node/board-live-cards-cli.js +15 -0
  61. package/dist/cli/node/board-live-cards-cli.js.map +1 -0
  62. package/dist/cli/node/card-store-cli.cjs +8 -0
  63. package/dist/cli/node/card-store-cli.cjs.map +1 -0
  64. package/dist/cli/node/card-store-cli.d.cts +15 -0
  65. package/dist/cli/node/card-store-cli.d.ts +15 -0
  66. package/dist/cli/node/card-store-cli.js +8 -0
  67. package/dist/cli/node/card-store-cli.js.map +1 -0
  68. package/dist/cli/node/execution-adapter.cjs +3 -0
  69. package/dist/cli/node/execution-adapter.cjs.map +1 -0
  70. package/dist/cli/node/execution-adapter.d.cts +174 -0
  71. package/dist/cli/node/execution-adapter.d.ts +174 -0
  72. package/dist/cli/node/execution-adapter.js +3 -0
  73. package/dist/cli/node/execution-adapter.js.map +1 -0
  74. package/dist/cli/node/fs-board-adapter.cjs +14 -0
  75. package/dist/cli/node/fs-board-adapter.cjs.map +1 -0
  76. package/dist/cli/node/fs-board-adapter.d.cts +204 -0
  77. package/dist/cli/node/fs-board-adapter.d.ts +204 -0
  78. package/dist/cli/node/fs-board-adapter.js +14 -0
  79. package/dist/cli/node/fs-board-adapter.js.map +1 -0
  80. package/dist/cli/node/jsonata-sync.cjs +7623 -0
  81. package/dist/cli/node/source-cli-task-executor.cjs +11 -0
  82. package/dist/cli/node/source-cli-task-executor.cjs.map +1 -0
  83. package/dist/cli/node/source-cli-task-executor.d.cts +1 -0
  84. package/dist/cli/node/source-cli-task-executor.d.ts +1 -0
  85. package/dist/cli/node/source-cli-task-executor.js +11 -0
  86. package/dist/cli/node/source-cli-task-executor.js.map +1 -0
  87. package/dist/config/index.cjs +1 -79
  88. package/dist/config/index.cjs.map +1 -1
  89. package/dist/config/index.js +1 -76
  90. package/dist/config/index.js.map +1 -1
  91. package/dist/continuous-event-graph/index.cjs +2 -2129
  92. package/dist/continuous-event-graph/index.cjs.map +1 -1
  93. package/dist/continuous-event-graph/index.d.cts +81 -5
  94. package/dist/continuous-event-graph/index.d.ts +81 -5
  95. package/dist/continuous-event-graph/index.js +2 -2088
  96. package/dist/continuous-event-graph/index.js.map +1 -1
  97. package/dist/continuous-event-graph/jsonata-sync.cjs +7623 -0
  98. package/dist/event-graph/index.cjs +22 -8292
  99. package/dist/event-graph/index.cjs.map +1 -1
  100. package/dist/event-graph/index.js +22 -8237
  101. package/dist/event-graph/index.js.map +1 -1
  102. package/dist/execution-refs.cjs +3 -0
  103. package/dist/execution-refs.cjs.map +1 -0
  104. package/dist/execution-refs.d.cts +260 -0
  105. package/dist/execution-refs.d.ts +260 -0
  106. package/dist/execution-refs.js +3 -0
  107. package/dist/execution-refs.js.map +1 -0
  108. package/dist/index.cjs +29 -13221
  109. package/dist/index.cjs.map +1 -1
  110. package/dist/index.d.cts +2 -4
  111. package/dist/index.d.ts +2 -4
  112. package/dist/index.js +29 -13112
  113. package/dist/index.js.map +1 -1
  114. package/dist/inference/index.cjs +5 -617
  115. package/dist/inference/index.cjs.map +1 -1
  116. package/dist/inference/index.js +5 -610
  117. package/dist/inference/index.js.map +1 -1
  118. package/dist/jsonata-sync.cjs +7623 -0
  119. package/dist/{live-cards-bridge-x5XREkXm.d.cts → live-cards-bridge-BXbVTsna.d.cts} +27 -4
  120. package/dist/{live-cards-bridge-EQjytzI_.d.ts → live-cards-bridge-Ds28XR15.d.ts} +27 -4
  121. package/dist/server-runtime/index.cjs +9 -0
  122. package/dist/server-runtime/index.cjs.map +1 -0
  123. package/dist/server-runtime/index.d.cts +31 -0
  124. package/dist/server-runtime/index.d.ts +31 -0
  125. package/dist/server-runtime/index.js +9 -0
  126. package/dist/server-runtime/index.js.map +1 -0
  127. package/dist/server-runtime/jsonata-sync.cjs +7623 -0
  128. package/dist/step-machine/index.cjs +11 -7129
  129. package/dist/step-machine/index.cjs.map +1 -1
  130. package/dist/step-machine/index.js +11 -7113
  131. package/dist/step-machine/index.js.map +1 -1
  132. package/dist/step-machine-public/index.cjs +2 -0
  133. package/dist/step-machine-public/index.cjs.map +1 -0
  134. package/dist/step-machine-public/index.d.cts +159 -0
  135. package/dist/step-machine-public/index.d.ts +159 -0
  136. package/dist/step-machine-public/index.js +2 -0
  137. package/dist/step-machine-public/index.js.map +1 -0
  138. package/dist/step-machine-public/jsonata-sync.cjs +7623 -0
  139. package/dist/storage-refs.cjs +10 -0
  140. package/dist/storage-refs.cjs.map +1 -0
  141. package/dist/storage-refs.d.cts +93 -0
  142. package/dist/storage-refs.d.ts +93 -0
  143. package/dist/storage-refs.js +10 -0
  144. package/dist/storage-refs.js.map +1 -0
  145. package/dist/stores/file.cjs +1 -114
  146. package/dist/stores/file.cjs.map +1 -1
  147. package/dist/stores/file.js +1 -112
  148. package/dist/stores/file.js.map +1 -1
  149. package/dist/stores/index.cjs +1 -231
  150. package/dist/stores/index.cjs.map +1 -1
  151. package/dist/stores/index.js +1 -227
  152. package/dist/stores/index.js.map +1 -1
  153. package/dist/stores/localStorage.cjs +1 -76
  154. package/dist/stores/localStorage.cjs.map +1 -1
  155. package/dist/stores/localStorage.js +1 -74
  156. package/dist/stores/localStorage.js.map +1 -1
  157. package/dist/stores/memory.cjs +1 -47
  158. package/dist/stores/memory.cjs.map +1 -1
  159. package/dist/stores/memory.js +1 -45
  160. package/dist/stores/memory.js.map +1 -1
  161. package/dist/types-B1ZRa4aI.d.ts +147 -0
  162. package/dist/types-BxEFcVK9.d.cts +147 -0
  163. package/examples/browser/boards/portfolio-tracker/portfolio-t4.js +291 -0
  164. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.js +218 -0
  165. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.py +201 -0
  166. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-http-test.js +357 -0
  167. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-inference-adapter.js +25 -16
  168. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-public.js +552 -0
  169. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-server.js +300 -0
  170. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-server.py +617 -0
  171. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-sse-worker.js +48 -0
  172. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.py +366 -0
  173. package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/.runtime-out +1 -0
  174. package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/board-graph.json +32 -0
  175. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +70 -3
  176. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +16 -11
  177. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/init-board-cli.js +9 -8
  178. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/poll-status-cli.js +49 -0
  179. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/reset-board-dir-cli.js +2 -6
  180. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/retrigger-cli.js +4 -8
  181. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/status-cli.js +3 -7
  182. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +9 -8
  183. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/wait-completed-cli.js +12 -17
  184. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/write-prices-cli.js +2 -6
  185. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/_board_pycli.py +107 -0
  186. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/add-cards.py +51 -0
  187. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/init-board.py +45 -0
  188. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/poll-status.py +71 -0
  189. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/reset-board-dir.py +36 -0
  190. package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-demo.flow.yaml +26 -0
  191. package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-handlers.py +39 -0
  192. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker-pycli.flow.yaml +80 -0
  193. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +36 -187
  194. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.input.json +40 -34
  195. package/examples/cli/step-machine-cli/portfolio-tracker/run-inline-python-demo-pycli.py +43 -0
  196. package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker-pycli.py +77 -0
  197. package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
  198. package/examples/cli/step-machine-demo/jsonata-init-board-cli.js +8 -13
  199. package/examples/cli/step-machine-demo/jsonata-init-board.flow.yaml +33 -9
  200. package/examples/cli/step-machine-demo/one-step-cli-only.flow.yaml +3 -1
  201. package/examples/cli/step-machine-demo/step2-double-cli.js +6 -12
  202. package/examples/cli/step-machine-demo/two-step-math.flow.yaml +66 -4
  203. package/examples/cli/step-machine-demo/two-step-mixed.flow.yaml +13 -5
  204. package/examples/example-board/agent-instructions.md +11 -5
  205. package/examples/example-board/cards/_index.json +47 -0
  206. package/examples/example-board/cards/card-market-prices.json +33 -9
  207. package/examples/example-board/cards/card-my-identity.json +30 -6
  208. package/examples/example-board/cards/card-portfolio-action.json +24 -6
  209. package/examples/example-board/cards/card-portfolio-intelligence.json +97 -0
  210. package/examples/example-board/cards/card-portfolio-risks.json +24 -6
  211. package/examples/example-board/cards/card-portfolio-value.json +38 -10
  212. package/examples/example-board/cards/card-portfolio.json +57 -13
  213. package/examples/example-board/cards/card-rebalance-impact.json +22 -6
  214. package/examples/example-board/cards/card-rebalance-sim.json +66 -15
  215. package/examples/example-board/demo-chat-handler.js +14 -4
  216. package/examples/example-board/demo-server-config.json +1 -0
  217. package/examples/example-board/demo-server.js +366 -68
  218. package/examples/example-board/demo-shell-localstorage.html +774 -0
  219. package/examples/example-board/demo-shell-with-server.html +20 -37
  220. package/examples/example-board/demo-shell.html +5 -4
  221. package/examples/example-board/demo-task-executor.js +273 -275
  222. package/examples/index.html +0 -14
  223. package/examples/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +0 -1
  224. package/examples/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
  225. package/package.json +46 -8
  226. package/schema/live-cards.schema.json +418 -132
  227. package/step-machine-cli.js +43 -310
  228. package/board-livecards-server-runtime.js +0 -1574
  229. package/browser/board-livecards-runtime-client.js +0 -263
  230. package/dist/cli/board-live-cards-cli.cjs +0 -10650
  231. package/dist/cli/board-live-cards-cli.cjs.map +0 -1
  232. package/dist/cli/board-live-cards-cli.d.cts +0 -179
  233. package/dist/cli/board-live-cards-cli.d.ts +0 -179
  234. package/dist/cli/board-live-cards-cli.js +0 -10598
  235. package/dist/cli/board-live-cards-cli.js.map +0 -1
  236. package/dist/journal-9HEgs7dU.d.ts +0 -28
  237. package/dist/journal-B-JCfQnh.d.cts +0 -28
  238. package/dist/schedule-Cszq9LYY.d.ts +0 -21
  239. package/dist/schedule-qWNL0RQh.d.cts +0 -21
  240. package/examples/browser/boards/portfolio-tracker/cards/holdings-table.json +0 -22
  241. package/examples/browser/boards/portfolio-tracker/cards/portfolio-form.json +0 -16
  242. package/examples/browser/boards/portfolio-tracker/cards/portfolio-risk-assessment.json +0 -28
  243. package/examples/browser/boards/portfolio-tracker/cards/portfolio-value.json +0 -15
  244. package/examples/browser/boards/portfolio-tracker/cards/price-fetch.json +0 -15
  245. package/examples/browser/boards/portfolio-tracker/cards/rebalancing-strategy.json +0 -28
  246. package/examples/browser/boards/portfolio-tracker/fetch-prices.js +0 -43
  247. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-task-executor.cjs +0 -96
  248. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.bat +0 -7
  249. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.js +0 -351
  250. package/examples/cli/step-machine-demo/two-step-math-handlers.js +0 -32
  251. package/examples/cli/step-machine-demo/two-step-mixed-handlers.js +0 -24
  252. package/examples/example-board/demo-shell-browser.html +0 -674
@@ -4,19 +4,81 @@ settings:
4
4
  max_total_steps: 10
5
5
  timeout_ms: 10000
6
6
 
7
+ # Demonstrates three compute-jsonata techniques:
8
+ # 1. Basic arithmetic with data.* output and explicit result=
9
+ # 2. Chained ternary with local $var binding ($c :=) — range classification and conditional routing
10
+ # 3. $lookup object-switch — route result directly from a map (see switch test in step-machine-cli.test.ts)
11
+ # NOTE: expr items containing ': ' or '{key: value}' must be single-quoted in YAML.
12
+
7
13
  steps:
8
14
  step1_add:
9
15
  description: Compute c = a + b
10
16
  expects_data: [a, b]
11
17
  produces_data: [c]
18
+ input_validations:
19
+ - $type(a) = "number"
20
+ - $type(b) = "number"
21
+ handler:
22
+ type: compute-jsonata
23
+ expr:
24
+ - data.c = expects_data.a + expects_data.b
25
+ - result = "success"
26
+ transitions:
27
+ success: step2_classify
28
+ failure: failed_state
29
+
30
+ step2_classify:
31
+ description: |
32
+ Classify c using an object-lookup switch.
33
+ Routes to low_track / mid_track / high_track based on magnitude.
34
+ expects_data: [c]
35
+ produces_data: [band]
36
+ handler:
37
+ type: compute-jsonata
38
+ expr:
39
+ - 'data.band = ($c := expects_data.c; $c < 10 ? "low" : $c < 100 ? "mid" : "high")'
40
+ - result = data.band
12
41
  transitions:
13
- success: step2_double
42
+ low: low_track
43
+ mid: mid_track
44
+ high: high_track
45
+ failure: failed_state
46
+
47
+ low_track:
48
+ description: Small result — multiply by 3
49
+ expects_data: [c]
50
+ produces_data: [d]
51
+ handler:
52
+ type: compute-jsonata
53
+ expr:
54
+ - data.d = expects_data.c * 3
55
+ - result = "success"
56
+ transitions:
57
+ success: success_state
58
+ failure: failed_state
59
+
60
+ mid_track:
61
+ description: Medium result — multiply by 2
62
+ expects_data: [c]
63
+ produces_data: [d]
64
+ handler:
65
+ type: compute-jsonata
66
+ expr:
67
+ - data.d = expects_data.c * 2
68
+ - result = "success"
69
+ transitions:
70
+ success: success_state
14
71
  failure: failed_state
15
72
 
16
- step2_double:
17
- description: Compute d = c * 2
73
+ high_track:
74
+ description: Large result keep as-is (already big enough)
18
75
  expects_data: [c]
19
76
  produces_data: [d]
77
+ handler:
78
+ type: compute-jsonata
79
+ expr:
80
+ - data.d = expects_data.c
81
+ - result = "success"
20
82
  transitions:
21
83
  success: success_state
22
84
  failure: failed_state
@@ -24,7 +86,7 @@ steps:
24
86
  terminal_states:
25
87
  success_state:
26
88
  return_intent: success
27
- return_artifacts: [a, b, c, d]
89
+ return_artifacts: [a, b, c, band, d]
28
90
 
29
91
  failed_state:
30
92
  return_intent: failure
@@ -6,21 +6,29 @@ settings:
6
6
 
7
7
  steps:
8
8
  step1_add:
9
- description: Inline handler computes c = a + b
9
+ description: Compute step computes c = a + b
10
10
  expects_data: [a, b]
11
- produces_data: [c, e]
11
+ produces_data: [c]
12
+ input_validations:
13
+ - $type(a) = "number"
14
+ - $type(b) = "number"
12
15
  handler:
13
- inline: step1_add
16
+ type: compute-jsonata
17
+ expr:
18
+ - data.c = expects_data.a + expects_data.b
19
+ - result = "success"
14
20
  transitions:
15
21
  success: step2_double
16
22
  failure: failed_state
17
23
 
18
24
  step2_double:
19
- description: CLI handler computes d = c * 2
25
+ description: Ref handler computes d = c * 2
20
26
  expects_data: [c]
21
27
  produces_data: [d, e]
22
28
  handler:
23
- cli: node ./step2-double-cli.js
29
+ type: ref
30
+ howToRun: local-node
31
+ whatToRun: "::fs-path::./step2-double-cli.js"
24
32
  transitions:
25
33
  success: success_state
26
34
  failure: failed_state
@@ -780,10 +780,15 @@ node <handler.js> --boardId <id> --cardId <id> --extraEncJson <base64json>
780
780
 
781
781
  - **`--boardId`** — board identifier
782
782
  - **`--cardId`** — the specific card where the user clicked the chat button
783
- - **`--extraEncJson`** — base64-encoded JSON: `{ chatDir, boardDir, lastChatFile }`
783
+ - **`--extraEncJson`** — base64-encoded JSON: `{ boardSetupRoot, boardRuntimeDir, runtimeStatusDir, cardsDir, chatDir, chatProcessingMarkerKey, lastChatFile, serverUrl? }`
784
+ - `boardSetupRoot` — absolute board setup root (parent of runtime/surface/runtime-out)
785
+ - `boardRuntimeDir` — relative runtime path (for example `runtime`)
786
+ - `runtimeStatusDir` — relative runtime-out path
787
+ - `cardsDir` — relative cards root path (for example `surface/tmp-cards`)
784
788
  - `chatDir` — absolute path to the directory holding all chat message files for this card
785
- - `boardDir` — absolute path to the board runtime directory
789
+ - `chatProcessingMarkerKey` — relative key for `.processing` marker under cardsDir (for example `card-portfolio/.processing`)
786
790
  - `lastChatFile` — filename of the user message just written (e.g. `007_user.txt`)
791
+ - `serverUrl` — optional base URL of the hosting server
787
792
 
788
793
  ### Chat message files
789
794
 
@@ -795,8 +800,9 @@ Messages are stored as serial-numbered `.txt` files in `chatDir`:
795
800
 
796
801
  1. Read all `*_user.txt` / `*-assistant.txt` files from `chatDir` (sorted) → conversation history
797
802
  2. Build a system prompt scoped to `cardId` / `boardId` as grounding context
798
- 3. Call the LLM directly (e.g. Copilot CLI) with `cwd: boardDir` — running from `boardDir` gives the LLM natural file context
803
+ 3. Call the LLM directly (e.g. Copilot CLI) with `cwd: boardSetupRoot` — running from board setup root gives natural file context for runtime, cards, and outputs
799
804
  4. Write the response to `<nextSerial>-assistant.txt` in `chatDir`
805
+ 5. Remove `.processing` marker using `chatProcessingMarkerKey` (fallback: `chatDir/.processing`)
800
806
 
801
807
  ### System prompt guidance
802
808
 
@@ -815,12 +821,12 @@ Be concise. Ground answers in the card's data context.`
815
821
 
816
822
  ### LLM invocation
817
823
 
818
- Call Copilot CLI directly from `boardDir` — same pattern as `demo-task-executor.js`:
824
+ Call Copilot CLI directly from `boardSetupRoot` — same pattern as `demo-task-executor.js`:
819
825
  ```javascript
820
826
  execFileSync(copilotBin, ['--allow-all'], {
821
827
  input: fullPrompt,
822
828
  encoding: 'utf-8',
823
- cwd: boardDir, // ← run from boardDir for natural file context
829
+ cwd: boardSetupRoot, // ← run from setup root for natural file context
824
830
  stdio: ['pipe', 'pipe', 'pipe'],
825
831
  });
826
832
  ```
@@ -0,0 +1,47 @@
1
+ {
2
+ "card-portfolio-intelligence": {
3
+ "key": "card-portfolio-intelligence",
4
+ "checksum": "card-portfolio-intelligence",
5
+ "updatedAt": "2026-05-10T09:38:02.181Z"
6
+ },
7
+ "card-market-prices": {
8
+ "key": "card-market-prices",
9
+ "checksum": "card-market-prices",
10
+ "updatedAt": "2026-05-10T09:38:02.161Z"
11
+ },
12
+ "card-my-identity": {
13
+ "key": "card-my-identity",
14
+ "checksum": "card-my-identity",
15
+ "updatedAt": "2026-05-10T09:38:02.168Z"
16
+ },
17
+ "card-portfolio-action": {
18
+ "key": "card-portfolio-action",
19
+ "checksum": "card-portfolio-action",
20
+ "updatedAt": "2026-05-10T09:38:02.174Z"
21
+ },
22
+ "card-portfolio-risks": {
23
+ "key": "card-portfolio-risks",
24
+ "checksum": "card-portfolio-risks",
25
+ "updatedAt": "2026-05-10T09:38:02.187Z"
26
+ },
27
+ "card-portfolio-value": {
28
+ "key": "card-portfolio-value",
29
+ "checksum": "card-portfolio-value",
30
+ "updatedAt": "2026-05-10T09:38:02.195Z"
31
+ },
32
+ "card-portfolio": {
33
+ "key": "card-portfolio",
34
+ "checksum": "card-portfolio",
35
+ "updatedAt": "2026-05-10T09:38:02.201Z"
36
+ },
37
+ "card-rebalance-impact": {
38
+ "key": "card-rebalance-impact",
39
+ "checksum": "card-rebalance-impact",
40
+ "updatedAt": "2026-05-10T09:38:02.208Z"
41
+ },
42
+ "card-rebalance-sim": {
43
+ "key": "card-rebalance-sim",
44
+ "checksum": "card-rebalance-sim",
45
+ "updatedAt": "2026-05-10T09:38:02.214Z"
46
+ }
47
+ }
@@ -2,10 +2,15 @@
2
2
  "id": "card-market-prices",
3
3
  "meta": {
4
4
  "title": "Market Prices",
5
- "tags": ["prices", "market"],
5
+ "tags": [
6
+ "prices",
7
+ "market"
8
+ ],
6
9
  "desc": "Fetches live prices for portfolio tickers. Publishes enriched quote data for downstream portfolio value calculations."
7
10
  },
8
- "requires": ["holdings"],
11
+ "requires": [
12
+ "holdings"
13
+ ],
9
14
  "source_defs": [
10
15
  {
11
16
  "bindTo": "quotes",
@@ -24,7 +29,7 @@
24
29
  "compute": [
25
30
  {
26
31
  "bindTo": "normalizedQuotes",
27
- "expr": "{ \"quoteResponse\": { \"result\": $map(fetched_sources.quotes, function($r) { $r.chart.result[0].meta.{ \"symbol\": symbol, \"shortName\": longName, \"regularMarketPrice\": regularMarketPrice, \"regularMarketChange\": regularMarketChange, \"regularMarketChangePercent\": regularMarketChangePercent } }), \"error\": null } }"
32
+ "expr": "{ \"quoteResponse\": { \"result\": $map(fetched_sources.quotes, function($r) { ($m := $r.chart.result[0].meta; $prev := $m.chartPreviousClose; $chg := $m.regularMarketPrice - $prev; { \"symbol\": $m.symbol, \"shortName\": $m.shortName ? $m.shortName : $m.longName, \"regularMarketPrice\": $m.regularMarketPrice, \"regularMarketChange\": $chg, \"regularMarketChangePercent\": $chg / $prev * 100 }) }), \"error\": null } }"
28
33
  },
29
34
  {
30
35
  "bindTo": "prices",
@@ -32,7 +37,10 @@
32
37
  }
33
38
  ],
34
39
  "provides": [
35
- { "bindTo": "quotes", "ref": "computed_values.normalizedQuotes" }
40
+ {
41
+ "bindTo": "quotes",
42
+ "ref": "computed_values.normalizedQuotes"
43
+ }
36
44
  ],
37
45
  "view": {
38
46
  "elements": [
@@ -41,16 +49,32 @@
41
49
  "label": "Prices",
42
50
  "data": {
43
51
  "bind": "computed_values.prices",
44
- "columns": ["ticker", "name", "price", "change", "chg_pct"],
52
+ "columns": [
53
+ "ticker",
54
+ "name",
55
+ "price",
56
+ "change",
57
+ "chg_pct"
58
+ ],
45
59
  "sortable": true
46
60
  }
47
61
  }
48
62
  ],
49
63
  "layout": {
50
- "board": { "col": 4, "order": 2 },
51
- "canvas": { "x": 400, "y": 50, "w": 400, "h": 340 }
64
+ "board": {
65
+ "col": 4,
66
+ "order": 2
67
+ },
68
+ "canvas": {
69
+ "x": 400,
70
+ "y": 50,
71
+ "w": 400,
72
+ "h": 340
73
+ }
52
74
  },
53
- "features": { "refresh": true }
75
+ "features": {
76
+ "refresh": true
77
+ }
54
78
  },
55
79
  "card_data": {}
56
- }
80
+ }
@@ -2,7 +2,10 @@
2
2
  "id": "card-my-identity",
3
3
  "meta": {
4
4
  "title": "My Identity",
5
- "tags": ["m365", "workiq"],
5
+ "tags": [
6
+ "m365",
7
+ "workiq"
8
+ ],
6
9
  "desc": "Displays your M365 display name via WorkIQ (Microsoft 365 Copilot)."
7
10
  },
8
11
  "source_defs": [
@@ -14,15 +17,36 @@
14
17
  }
15
18
  }
16
19
  ],
20
+ "compute": [
21
+ {
22
+ "bindTo": "identity",
23
+ "expr": "fetched_sources.identity"
24
+ }
25
+ ],
17
26
  "view": {
18
27
  "elements": [
19
- { "kind": "markdown", "data": { "bind": "fetched_sources.identity" } }
28
+ {
29
+ "kind": "markdown",
30
+ "data": {
31
+ "bind": "computed_values.identity"
32
+ }
33
+ }
20
34
  ],
21
35
  "layout": {
22
- "board": { "col": 4, "order": 10 },
23
- "canvas": { "x": 50, "y": 450, "w": 420, "h": 260 }
36
+ "board": {
37
+ "col": 4,
38
+ "order": 10
39
+ },
40
+ "canvas": {
41
+ "x": 50,
42
+ "y": 450,
43
+ "w": 420,
44
+ "h": 260
45
+ }
24
46
  },
25
- "features": { "refresh": true }
47
+ "features": {
48
+ "refresh": true
49
+ }
26
50
  },
27
51
  "card_data": {}
28
- }
52
+ }
@@ -2,18 +2,36 @@
2
2
  "id": "card-portfolio-action",
3
3
  "meta": {
4
4
  "title": "Action Signal",
5
- "tags": ["portfolio", "action"],
5
+ "tags": [
6
+ "portfolio",
7
+ "action"
8
+ ],
6
9
  "desc": "Actionable recommendation sourced from Portfolio Intelligence."
7
10
  },
8
- "requires": ["portfolio_action"],
11
+ "requires": [
12
+ "portfolio_action"
13
+ ],
9
14
  "view": {
10
15
  "elements": [
11
- { "kind": "markdown", "data": { "bind": "requires.portfolio_action" } }
16
+ {
17
+ "kind": "markdown",
18
+ "data": {
19
+ "bind": "requires.portfolio_action"
20
+ }
21
+ }
12
22
  ],
13
23
  "layout": {
14
- "board": { "col": 4, "order": 6 },
15
- "canvas": { "x": 1660, "y": 50, "w": 300, "h": 160 }
24
+ "board": {
25
+ "col": 4,
26
+ "order": 6
27
+ },
28
+ "canvas": {
29
+ "x": 1660,
30
+ "y": 50,
31
+ "w": 300,
32
+ "h": 160
33
+ }
16
34
  }
17
35
  },
18
36
  "card_data": {}
19
- }
37
+ }
@@ -0,0 +1,97 @@
1
+ {
2
+ "id": "card-portfolio-intelligence",
3
+ "meta": {
4
+ "title": "Portfolio Intelligence",
5
+ "tags": [
6
+ "portfolio",
7
+ "analysis"
8
+ ],
9
+ "desc": "AI analysis of portfolio mix and P&L. Publishes structured insights as tokens for downstream risk and action cards."
10
+ },
11
+ "requires": [
12
+ "positions"
13
+ ],
14
+ "source_defs": [
15
+ {
16
+ "bindTo": "analysis",
17
+ "outputFile": "card-concentration-analysis.json",
18
+ "projections": {
19
+ "positions": "requires.positions"
20
+ },
21
+ "copilot": {
22
+ "prompt_template": "You are a concise equity analyst. Use web search to get today's news and upcoming events for each ticker before answering.\n\nPortfolio positions:\n{{positions}}\n\nFields: ticker, quantity, cost_basis ($), price ($), value ($), gain_$ (unrealised P&L), gain_% (unrealised return), chg_$ (today's position P&L $), chg_pct (today's % move).\n\nIMPORTANT OUTPUT RULES:\n- Return ONLY a valid JSON object. No markdown code fences, no preamble, no trailing text.\n- Start your response with { and end with }.\n- No emojis anywhere.\n- Each value is a Markdown string using - bullet points. No sub-headings inside values.\n- Maximum 40 words per section.\n\n{\n \"mix\": \"- <dominant holding ticker, % of total, and whether that is a risk>\\n- <sector clustering in one line>\",\n \"pnl\": \"- Best: <ticker> +X% (+$Y)\\n- Worst: <ticker> +X% (+$Y)\",\n \"risks\": \"- <TICKER>: <one specific current risk with event name or date>\\n- <TICKER>: ...\\n- (one bullet per position from today's news)\",\n \"action\": \"- <one sentence: specific action and reason grounded in today's market>\"\n}"
23
+ }
24
+ }
25
+ ],
26
+ "compute": [
27
+ {
28
+ "bindTo": "mix",
29
+ "expr": "fetched_sources.analysis.mix"
30
+ },
31
+ {
32
+ "bindTo": "pnl",
33
+ "expr": "fetched_sources.analysis.pnl"
34
+ },
35
+ {
36
+ "bindTo": "risks",
37
+ "expr": "fetched_sources.analysis.risks"
38
+ },
39
+ {
40
+ "bindTo": "action",
41
+ "expr": "fetched_sources.analysis.action"
42
+ }
43
+ ],
44
+ "provides": [
45
+ {
46
+ "bindTo": "portfolio_mix",
47
+ "ref": "computed_values.mix"
48
+ },
49
+ {
50
+ "bindTo": "portfolio_pnl",
51
+ "ref": "computed_values.pnl"
52
+ },
53
+ {
54
+ "bindTo": "portfolio_risks",
55
+ "ref": "computed_values.risks"
56
+ },
57
+ {
58
+ "bindTo": "portfolio_action",
59
+ "ref": "computed_values.action"
60
+ }
61
+ ],
62
+ "view": {
63
+ "elements": [
64
+ {
65
+ "kind": "markdown",
66
+ "label": "Mix",
67
+ "data": {
68
+ "bind": "computed_values.mix"
69
+ }
70
+ },
71
+ {
72
+ "kind": "markdown",
73
+ "label": "P&L",
74
+ "data": {
75
+ "bind": "computed_values.pnl"
76
+ }
77
+ }
78
+ ],
79
+ "layout": {
80
+ "board": {
81
+ "col": 3,
82
+ "order": 4
83
+ },
84
+ "canvas": {
85
+ "x": 1300,
86
+ "y": 50,
87
+ "w": 340,
88
+ "h": 200
89
+ }
90
+ },
91
+ "features": {
92
+ "refresh": true,
93
+ "chat": true
94
+ }
95
+ },
96
+ "card_data": {}
97
+ }
@@ -2,18 +2,36 @@
2
2
  "id": "card-portfolio-risks",
3
3
  "meta": {
4
4
  "title": "Risk Watch",
5
- "tags": ["portfolio", "risk"],
5
+ "tags": [
6
+ "portfolio",
7
+ "risk"
8
+ ],
6
9
  "desc": "Per-ticker risk signals sourced from Portfolio Intelligence."
7
10
  },
8
- "requires": ["portfolio_risks"],
11
+ "requires": [
12
+ "portfolio_risks"
13
+ ],
9
14
  "view": {
10
15
  "elements": [
11
- { "kind": "markdown", "data": { "bind": "requires.portfolio_risks" } }
16
+ {
17
+ "kind": "markdown",
18
+ "data": {
19
+ "bind": "requires.portfolio_risks"
20
+ }
21
+ }
12
22
  ],
13
23
  "layout": {
14
- "board": { "col": 3, "order": 5 },
15
- "canvas": { "x": 1300, "y": 270, "w": 340, "h": 220 }
24
+ "board": {
25
+ "col": 3,
26
+ "order": 5
27
+ },
28
+ "canvas": {
29
+ "x": 1300,
30
+ "y": 270,
31
+ "w": 340,
32
+ "h": 220
33
+ }
16
34
  }
17
35
  },
18
36
  "card_data": {}
19
- }
37
+ }
@@ -2,12 +2,21 @@
2
2
  "id": "card-portfolio-value",
3
3
  "meta": {
4
4
  "title": "Portfolio Value",
5
- "tags": ["portfolio", "value"],
5
+ "tags": [
6
+ "portfolio",
7
+ "value"
8
+ ],
6
9
  "desc": "Computes total portfolio value, gainers/losers summary, and per-position P&L from holdings and live market quotes."
7
10
  },
8
- "requires": ["holdings", "quotes"],
11
+ "requires": [
12
+ "holdings",
13
+ "quotes"
14
+ ],
9
15
  "provides": [
10
- { "bindTo": "positions", "ref": "computed_values.positions" }
16
+ {
17
+ "bindTo": "positions",
18
+ "ref": "computed_values.positions"
19
+ }
11
20
  ],
12
21
  "compute": [
13
22
  {
@@ -36,27 +45,46 @@
36
45
  {
37
46
  "kind": "metric",
38
47
  "label": "Portfolio Value ($)",
39
- "data": { "bind": "computed_values.totalValue" }
48
+ "data": {
49
+ "bind": "computed_values.totalValue"
50
+ }
40
51
  },
41
52
  {
42
53
  "kind": "text",
43
- "data": { "bind": "computed_values.gainersLosers" }
54
+ "data": {
55
+ "bind": "computed_values.gainersLosers"
56
+ }
44
57
  },
45
58
  {
46
59
  "kind": "table",
47
60
  "label": "Positions",
48
61
  "data": {
49
62
  "bind": "computed_values.positions",
50
- "columns": ["ticker", "value", "gain_$", "gain_%"],
63
+ "columns": [
64
+ "ticker",
65
+ "value",
66
+ "gain_$",
67
+ "gain_%"
68
+ ],
51
69
  "sortable": true
52
70
  }
53
71
  }
54
72
  ],
55
73
  "layout": {
56
- "board": { "col": 4, "order": 3 },
57
- "canvas": { "x": 840, "y": 50, "w": 420, "h": 380 }
74
+ "board": {
75
+ "col": 4,
76
+ "order": 3
77
+ },
78
+ "canvas": {
79
+ "x": 840,
80
+ "y": 50,
81
+ "w": 420,
82
+ "h": 380
83
+ }
58
84
  },
59
- "features": { "chat": true }
85
+ "features": {
86
+ "chat": true
87
+ }
60
88
  },
61
89
  "card_data": {}
62
- }
90
+ }