yaml-flow 5.4.0 → 6.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 (200) hide show
  1. package/board-live-cards-cli.js +2 -2
  2. package/board-livecards-server-runtime.js +488 -551
  3. package/browser/asset-integrity.json +10 -0
  4. package/browser/board-livecards-runtime-client.js +0 -6
  5. package/browser/board-livegraph-engine.js +2 -1676
  6. package/browser/board-livegraph-engine.js.map +1 -1
  7. package/browser/live-cards.js +347 -26
  8. package/browser/live-cards.schema.json +418 -132
  9. package/card-store.js +37 -0
  10. package/dist/batch/index.cjs +1 -108
  11. package/dist/batch/index.cjs.map +1 -1
  12. package/dist/batch/index.js +1 -106
  13. package/dist/batch/index.js.map +1 -1
  14. package/dist/board-live-cards-lib-Bg6EvCo5.d.cts +136 -0
  15. package/dist/board-live-cards-lib-jM2uYG1v.d.ts +136 -0
  16. package/dist/board-live-cards-public-CltXYgaY.d.cts +314 -0
  17. package/dist/board-live-cards-public-f-E-FAyp.d.ts +314 -0
  18. package/dist/board-livegraph-runtime/index.cjs +2 -1671
  19. package/dist/board-livegraph-runtime/index.cjs.map +1 -1
  20. package/dist/board-livegraph-runtime/index.d.cts +1 -2
  21. package/dist/board-livegraph-runtime/index.d.ts +1 -2
  22. package/dist/board-livegraph-runtime/index.js +2 -1662
  23. package/dist/board-livegraph-runtime/index.js.map +1 -1
  24. package/dist/board-livegraph-runtime/jsonata-sync.cjs +7587 -0
  25. package/dist/card-compute/index.cjs +9 -7159
  26. package/dist/card-compute/index.cjs.map +1 -1
  27. package/dist/card-compute/index.d.cts +22 -0
  28. package/dist/card-compute/index.d.ts +22 -0
  29. package/dist/card-compute/index.js +9 -7145
  30. package/dist/card-compute/index.js.map +1 -1
  31. package/dist/card-compute/jsonata-sync.cjs +7587 -0
  32. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs +2 -0
  33. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs.map +1 -0
  34. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.cts +24 -0
  35. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.ts +24 -0
  36. package/dist/cli/browser-api/board-live-cards-browser-adapter.js +2 -0
  37. package/dist/cli/browser-api/board-live-cards-browser-adapter.js.map +1 -0
  38. package/dist/cli/browser-api/card-store-browser-api.cjs +2 -0
  39. package/dist/cli/browser-api/card-store-browser-api.cjs.map +1 -0
  40. package/dist/cli/browser-api/card-store-browser-api.d.cts +26 -0
  41. package/dist/cli/browser-api/card-store-browser-api.d.ts +26 -0
  42. package/dist/cli/browser-api/card-store-browser-api.js +2 -0
  43. package/dist/cli/browser-api/card-store-browser-api.js.map +1 -0
  44. package/dist/cli/browser-api/jsonata-sync.cjs +7587 -0
  45. package/dist/cli/node/artifacts-store-cli.cjs +11 -0
  46. package/dist/cli/node/artifacts-store-cli.cjs.map +1 -0
  47. package/dist/cli/node/artifacts-store-cli.d.cts +8 -0
  48. package/dist/cli/node/artifacts-store-cli.d.ts +8 -0
  49. package/dist/cli/node/artifacts-store-cli.js +11 -0
  50. package/dist/cli/node/artifacts-store-cli.js.map +1 -0
  51. package/dist/cli/node/board-live-cards-cli.cjs +15 -0
  52. package/dist/cli/node/board-live-cards-cli.cjs.map +1 -0
  53. package/dist/cli/node/board-live-cards-cli.d.cts +20 -0
  54. package/dist/cli/node/board-live-cards-cli.d.ts +20 -0
  55. package/dist/cli/node/board-live-cards-cli.js +15 -0
  56. package/dist/cli/node/board-live-cards-cli.js.map +1 -0
  57. package/dist/cli/node/card-store-cli.cjs +8 -0
  58. package/dist/cli/node/card-store-cli.cjs.map +1 -0
  59. package/dist/cli/node/card-store-cli.d.cts +15 -0
  60. package/dist/cli/node/card-store-cli.d.ts +15 -0
  61. package/dist/cli/node/card-store-cli.js +8 -0
  62. package/dist/cli/node/card-store-cli.js.map +1 -0
  63. package/dist/cli/node/fs-board-adapter.cjs +14 -0
  64. package/dist/cli/node/fs-board-adapter.cjs.map +1 -0
  65. package/dist/cli/node/fs-board-adapter.d.cts +204 -0
  66. package/dist/cli/node/fs-board-adapter.d.ts +204 -0
  67. package/dist/cli/node/fs-board-adapter.js +14 -0
  68. package/dist/cli/node/fs-board-adapter.js.map +1 -0
  69. package/dist/cli/node/jsonata-sync.cjs +7587 -0
  70. package/dist/cli/node/source-cli-task-executor.cjs +11 -0
  71. package/dist/cli/node/source-cli-task-executor.cjs.map +1 -0
  72. package/dist/cli/node/source-cli-task-executor.d.cts +1 -0
  73. package/dist/cli/node/source-cli-task-executor.d.ts +1 -0
  74. package/dist/cli/node/source-cli-task-executor.js +11 -0
  75. package/dist/cli/node/source-cli-task-executor.js.map +1 -0
  76. package/dist/config/index.cjs +1 -79
  77. package/dist/config/index.cjs.map +1 -1
  78. package/dist/config/index.js +1 -76
  79. package/dist/config/index.js.map +1 -1
  80. package/dist/continuous-event-graph/index.cjs +2 -2129
  81. package/dist/continuous-event-graph/index.cjs.map +1 -1
  82. package/dist/continuous-event-graph/index.d.cts +81 -5
  83. package/dist/continuous-event-graph/index.d.ts +81 -5
  84. package/dist/continuous-event-graph/index.js +2 -2088
  85. package/dist/continuous-event-graph/index.js.map +1 -1
  86. package/dist/continuous-event-graph/jsonata-sync.cjs +7587 -0
  87. package/dist/event-graph/index.cjs +22 -8292
  88. package/dist/event-graph/index.cjs.map +1 -1
  89. package/dist/event-graph/index.js +22 -8237
  90. package/dist/event-graph/index.js.map +1 -1
  91. package/dist/execution-refs.cjs +2 -0
  92. package/dist/execution-refs.cjs.map +1 -0
  93. package/dist/execution-refs.d.cts +222 -0
  94. package/dist/execution-refs.d.ts +222 -0
  95. package/dist/execution-refs.js +2 -0
  96. package/dist/execution-refs.js.map +1 -0
  97. package/dist/index.cjs +29 -13221
  98. package/dist/index.cjs.map +1 -1
  99. package/dist/index.d.cts +2 -4
  100. package/dist/index.d.ts +2 -4
  101. package/dist/index.js +29 -13112
  102. package/dist/index.js.map +1 -1
  103. package/dist/inference/index.cjs +5 -617
  104. package/dist/inference/index.cjs.map +1 -1
  105. package/dist/inference/index.js +5 -610
  106. package/dist/inference/index.js.map +1 -1
  107. package/dist/jsonata-sync.cjs +7587 -0
  108. package/dist/{live-cards-bridge-x5XREkXm.d.cts → live-cards-bridge-BXbVTsna.d.cts} +27 -4
  109. package/dist/{live-cards-bridge-EQjytzI_.d.ts → live-cards-bridge-Ds28XR15.d.ts} +27 -4
  110. package/dist/pycli/quickjs-board-runtime.global.js +9 -0
  111. package/dist/pycli/quickjs-board-runtime.global.js.map +1 -0
  112. package/dist/pycli/quickjs-step-machine-runtime.global.js +5 -0
  113. package/dist/pycli/quickjs-step-machine-runtime.global.js.map +1 -0
  114. package/dist/step-machine/index.cjs +11 -7129
  115. package/dist/step-machine/index.cjs.map +1 -1
  116. package/dist/step-machine/index.js +11 -7113
  117. package/dist/step-machine/index.js.map +1 -1
  118. package/dist/storage-refs.cjs +10 -0
  119. package/dist/storage-refs.cjs.map +1 -0
  120. package/dist/storage-refs.d.cts +92 -0
  121. package/dist/storage-refs.d.ts +92 -0
  122. package/dist/storage-refs.js +10 -0
  123. package/dist/storage-refs.js.map +1 -0
  124. package/dist/stores/file.cjs +1 -114
  125. package/dist/stores/file.cjs.map +1 -1
  126. package/dist/stores/file.js +1 -112
  127. package/dist/stores/file.js.map +1 -1
  128. package/dist/stores/index.cjs +1 -231
  129. package/dist/stores/index.cjs.map +1 -1
  130. package/dist/stores/index.js +1 -227
  131. package/dist/stores/index.js.map +1 -1
  132. package/dist/stores/localStorage.cjs +1 -76
  133. package/dist/stores/localStorage.cjs.map +1 -1
  134. package/dist/stores/localStorage.js +1 -74
  135. package/dist/stores/localStorage.js.map +1 -1
  136. package/dist/stores/memory.cjs +1 -47
  137. package/dist/stores/memory.cjs.map +1 -1
  138. package/dist/stores/memory.js +1 -45
  139. package/dist/stores/memory.js.map +1 -1
  140. package/examples/browser/boards/portfolio-tracker/portfolio-t4.js +292 -0
  141. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.js +218 -0
  142. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.py +201 -0
  143. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-inference-adapter.js +25 -16
  144. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-public.js +553 -0
  145. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.py +365 -0
  146. package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/.runtime-out +1 -0
  147. package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/board-graph.json +32 -0
  148. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +53 -1
  149. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +15 -6
  150. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/init-board-cli.js +6 -1
  151. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/poll-status-cli.js +57 -0
  152. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/retrigger-cli.js +1 -1
  153. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/status-cli.js +1 -1
  154. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +7 -2
  155. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/wait-completed-cli.js +6 -2
  156. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/_board_pycli.py +97 -0
  157. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/add-cards.py +50 -0
  158. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/init-board.py +44 -0
  159. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/poll-status.py +70 -0
  160. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/reset-board-dir.py +36 -0
  161. package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-demo.flow.yaml +26 -0
  162. package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-handlers.py +39 -0
  163. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker-pycli.flow.yaml +80 -0
  164. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +25 -172
  165. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.input.json +40 -34
  166. package/examples/cli/step-machine-cli/portfolio-tracker/run-inline-python-demo-pycli.py +46 -0
  167. package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker-pycli.py +77 -0
  168. package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
  169. package/examples/example-board/agent-instructions.md +11 -5
  170. package/examples/example-board/demo-chat-handler.js +14 -4
  171. package/examples/example-board/demo-server-config.json +1 -0
  172. package/examples/example-board/demo-server.js +19 -34
  173. package/examples/example-board/demo-shell-browser.html +5 -4
  174. package/examples/example-board/demo-shell-with-server.html +10 -6
  175. package/examples/example-board/demo-task-executor.js +81 -35
  176. package/examples/index.html +0 -14
  177. package/examples/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +0 -1
  178. package/examples/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
  179. package/package.json +39 -3
  180. package/schema/live-cards.schema.json +418 -132
  181. package/dist/cli/board-live-cards-cli.cjs +0 -10644
  182. package/dist/cli/board-live-cards-cli.cjs.map +0 -1
  183. package/dist/cli/board-live-cards-cli.d.cts +0 -179
  184. package/dist/cli/board-live-cards-cli.d.ts +0 -179
  185. package/dist/cli/board-live-cards-cli.js +0 -10592
  186. package/dist/cli/board-live-cards-cli.js.map +0 -1
  187. package/dist/journal-9HEgs7dU.d.ts +0 -28
  188. package/dist/journal-B-JCfQnh.d.cts +0 -28
  189. package/dist/schedule-Cszq9LYY.d.ts +0 -21
  190. package/dist/schedule-qWNL0RQh.d.cts +0 -21
  191. package/examples/browser/boards/portfolio-tracker/cards/holdings-table.json +0 -22
  192. package/examples/browser/boards/portfolio-tracker/cards/portfolio-form.json +0 -16
  193. package/examples/browser/boards/portfolio-tracker/cards/portfolio-risk-assessment.json +0 -28
  194. package/examples/browser/boards/portfolio-tracker/cards/portfolio-value.json +0 -15
  195. package/examples/browser/boards/portfolio-tracker/cards/price-fetch.json +0 -15
  196. package/examples/browser/boards/portfolio-tracker/cards/rebalancing-strategy.json +0 -28
  197. package/examples/browser/boards/portfolio-tracker/fetch-prices.js +0 -43
  198. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-task-executor.cjs +0 -96
  199. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.bat +0 -7
  200. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.js +0 -351
@@ -1,38 +1,44 @@
1
1
  {
2
2
  "runtime_root": "./runtime",
3
3
  "board_name": "portfolio-tracker-board",
4
- "cards_template_dir": "./cards",
5
- "completion_tasks": [
6
- "portfolio-form",
7
- "price-fetch",
8
- "holdings-table",
9
- "portfolio-value"
10
- ],
11
- "price_fetch_task": "price-fetch",
12
- "prices_t1": {
13
- "AAPL": 198.5,
14
- "MSFT": 425.3,
15
- "GOOG": 178.9,
16
- "AMZN": 192.4,
17
- "TSLA": 168.75
18
- },
19
- "holdings_t2": [
20
- { "symbol": "AAPL", "qty": 50 },
21
- { "symbol": "MSFT", "qty": 30 },
22
- { "symbol": "GOOG", "qty": 100 }
23
- ],
24
- "prices_t2": {
25
- "AAPL": 198.5,
26
- "MSFT": 425.3,
27
- "GOOG": 178.9,
28
- "AMZN": 192.4,
29
- "TSLA": 168.75
30
- },
31
- "prices_t3": {
32
- "AAPL": 205,
33
- "MSFT": 425.3,
34
- "GOOG": 178.9,
35
- "AMZN": 192.4,
36
- "TSLA": 168.75
37
- }
4
+ "expected_card_count": 3,
5
+ "cards": [
6
+ {
7
+ "id": "portfolio-form",
8
+ "meta": { "title": "Portfolio Holdings Form" },
9
+ "provides": [{ "bindTo": "holdings", "ref": "card_data.holdings" }],
10
+ "card_data": {
11
+ "holdings": [
12
+ { "symbol": "AAPL", "qty": 50 },
13
+ { "symbol": "MSFT", "qty": 30 },
14
+ { "symbol": "GOOG", "qty": 100 }
15
+ ]
16
+ }
17
+ },
18
+ {
19
+ "id": "prices-mock",
20
+ "meta": { "title": "Mock Market Prices" },
21
+ "provides": [{ "bindTo": "prices", "ref": "card_data.prices" }],
22
+ "card_data": {
23
+ "prices": {
24
+ "AAPL": 198.5,
25
+ "MSFT": 425.3,
26
+ "GOOG": 178.9
27
+ }
28
+ }
29
+ },
30
+ {
31
+ "id": "portfolio-value",
32
+ "meta": { "title": "Portfolio Total Value" },
33
+ "requires": ["holdings", "prices"],
34
+ "provides": [{ "bindTo": "totalValue", "ref": "computed_values.totalValue" }],
35
+ "card_data": {},
36
+ "compute": [
37
+ {
38
+ "bindTo": "totalValue",
39
+ "expr": "$sum($map(requires.holdings, function($h) { $h.qty * $lookup(requires.prices, $h.symbol) }))"
40
+ }
41
+ ]
42
+ }
43
+ ]
38
44
  }
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ import subprocess
6
+ import sys
7
+ from pathlib import Path
8
+
9
+
10
+ def main() -> int:
11
+ here = Path(__file__).resolve().parent
12
+ repo_root = here.parents[3]
13
+
14
+ pycli = repo_root / "pycli" / "main" / "step_machine_pycli.py"
15
+ flow = here / "inline-python-demo.flow.yaml"
16
+ handlers = here / "inline-python-handlers.py"
17
+
18
+ initial_data = {
19
+ "name": "Ada",
20
+ "a": 7,
21
+ "b": 5,
22
+ }
23
+
24
+ cmd = [
25
+ sys.executable,
26
+ str(pycli),
27
+ str(flow),
28
+ "--handlers",
29
+ str(handlers),
30
+ "--initial-data",
31
+ json.dumps(initial_data, ensure_ascii=True),
32
+ "--store",
33
+ "memory",
34
+ ]
35
+
36
+ proc = subprocess.run(
37
+ cmd,
38
+ cwd=str(here),
39
+ shell=False,
40
+ check=False,
41
+ )
42
+ return proc.returncode
43
+
44
+
45
+ if __name__ == "__main__":
46
+ raise SystemExit(main())
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import json
6
+ import os
7
+ import subprocess
8
+ import sys
9
+ import tempfile
10
+ from pathlib import Path
11
+
12
+
13
+ def _build_parser() -> argparse.ArgumentParser:
14
+ parser = argparse.ArgumentParser(
15
+ description="Run the step-machine portfolio tracker example via step_machine_pycli.py",
16
+ )
17
+ parser.add_argument(
18
+ "action",
19
+ nargs="?",
20
+ choices=["run", "pause", "resume", "status"],
21
+ default="run",
22
+ help="Operation to perform (default: run)",
23
+ )
24
+ return parser
25
+
26
+
27
+ def main() -> int:
28
+ args = _build_parser().parse_args()
29
+
30
+ here = Path(__file__).resolve().parent
31
+ repo_root = here.parents[3]
32
+ pycli = repo_root / "pycli" / "main" / "step_machine_pycli.py"
33
+ flow = here / "portfolio-tracker-pycli.flow.yaml"
34
+ input_json = here / "portfolio-tracker.input.json"
35
+
36
+ temp_root = Path(tempfile.gettempdir()) / "yaml-flow-step-machine-portfolio-tracker"
37
+ store_dir = temp_root / "store"
38
+ runtime_root = temp_root / "runtime"
39
+
40
+ cmd = [
41
+ sys.executable,
42
+ str(pycli),
43
+ "--store",
44
+ "file",
45
+ "--store-dir",
46
+ str(store_dir),
47
+ ]
48
+
49
+ if args.action in ("run", "resume"):
50
+ cmd.insert(2, str(flow))
51
+
52
+ if args.action == "run":
53
+ payload = json.loads(input_json.read_text(encoding="utf-8"))
54
+ payload["runtime_root"] = runtime_root.as_posix()
55
+ cmd.extend(["--initial-data", json.dumps(payload, ensure_ascii=True)])
56
+ elif args.action == "resume":
57
+ cmd.append("--resume")
58
+ elif args.action == "pause":
59
+ cmd.append("--pause")
60
+ elif args.action == "status":
61
+ cmd.append("--status")
62
+
63
+ proc = subprocess.run(
64
+ cmd,
65
+ cwd=str(here),
66
+ shell=False,
67
+ check=False,
68
+ env={
69
+ **os.environ,
70
+ "PATH": str(Path(sys.executable).parent) + os.pathsep + os.environ.get("PATH", ""),
71
+ },
72
+ )
73
+ return proc.returncode
74
+
75
+
76
+ if __name__ == "__main__":
77
+ raise SystemExit(main())
@@ -2,7 +2,6 @@
2
2
  setlocal
3
3
  cd /d "%~dp0"
4
4
 
5
- set "BOARD_LIVE_CARDS_NO_SPAWN=1"
6
5
  set "EXAMPLE_TEMP_ROOT=%TEMP%\yaml-flow-step-machine-portfolio-tracker"
7
6
  set "STORE_DIR=%EXAMPLE_TEMP_ROOT%\store"
8
7
  set "RUNTIME_ROOT=%EXAMPLE_TEMP_ROOT%\runtime"
@@ -25,5 +24,5 @@ node ..\..\..\..\step-machine-cli.js --store file --store-dir "%STORE_DIR%" --st
25
24
  exit /b %ERRORLEVEL%
26
25
 
27
26
  :run
28
- node -e "const fs=require('fs');const cp=require('child_process');const raw=JSON.parse(fs.readFileSync('portfolio-tracker.input.json','utf8'));raw.runtime_root=(process.env.RUNTIME_ROOT||'').replace(/\\/g,'/');const input=JSON.stringify(raw);const r=cp.spawnSync(process.execPath,['..\\..\\..\\..\\step-machine-cli.js','portfolio-tracker.flow.yaml','--store','file','--store-dir',process.env.STORE_DIR,'--initial-data',input],{stdio:'inherit',windowsHide:true,env:{...process.env,BOARD_LIVE_CARDS_NO_SPAWN:'1'}});process.exit(r.status??1);"
27
+ node -e "const fs=require('fs');const cp=require('child_process');const raw=JSON.parse(fs.readFileSync('portfolio-tracker.input.json','utf8'));raw.runtime_root=(process.env.RUNTIME_ROOT||'').replace(/\\/g,'/');const r=cp.spawnSync(process.execPath,['..\\..\\..\\..\\step-machine-cli.js','portfolio-tracker.flow.yaml','--initial-data',JSON.stringify(raw)],{stdio:'inherit',windowsHide:true,cwd:__dirname});process.exit(r.status??1);"
29
28
  exit /b %ERRORLEVEL%
@@ -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
  ```
@@ -10,6 +10,7 @@
10
10
  * runtimeStatusDir— relative subdir: 'runtime-out'
11
11
  * cardsDir — relative subdir: 'surface/tmp-cards'
12
12
  * chatDir — absolute path to the card's chats directory
13
+ * chatProcessingMarkerKey — relative marker key in chats artifacts store (e.g. 'card-portfolio/.processing')
13
14
  * lastChatFile — filename of the just-written user message, e.g. '001_user.txt'
14
15
  * serverUrl — base URL of hosting server (e.g. http://127.0.0.1:7799), optional
15
16
  *
@@ -37,13 +38,12 @@ function getArg(name) {
37
38
  const boardId = getArg('--boardId') || '';
38
39
  const cardId = getArg('--cardId') || '';
39
40
  const extraStr = getArg('--extraEncJson') || '';
40
- const cleanOnExit = getArg('--cleanOnExit') || '';
41
41
 
42
42
  let extra = {};
43
43
  try { extra = JSON.parse(Buffer.from(extraStr, 'base64').toString('utf-8')); }
44
44
  catch { console.error('[demo-chat-handler] bad --extraEncJson'); process.exit(0); }
45
45
 
46
- const { boardSetupRoot, boardRuntimeDir, runtimeStatusDir, cardsDir, chatDir, lastChatFile, serverUrl } = extra;
46
+ const { boardSetupRoot, boardRuntimeDir, runtimeStatusDir, cardsDir, chatDir, chatProcessingMarkerKey, lastChatFile, serverUrl } = extra;
47
47
  if (!boardSetupRoot || !chatDir || !lastChatFile) {
48
48
  console.error('[demo-chat-handler] missing boardSetupRoot/chatDir/lastChatFile');
49
49
  process.exit(0);
@@ -153,7 +153,17 @@ try {
153
153
  } catch (err) {
154
154
  console.error('[demo-chat-handler] wrapper failed: ' + (err?.message ?? err));
155
155
  } finally {
156
- if (cleanOnExit) {
157
- try { fs.unlinkSync(cleanOnExit); } catch {}
156
+ cleanupProcessingMarker();
157
+ }
158
+ function cleanupProcessingMarker() {
159
+ // Prefer artifacts-style marker key from extra payload so runtime/handler contract
160
+ // does not rely on passing an absolute file path argument.
161
+ if (chatProcessingMarkerKey) {
162
+ try {
163
+ const markerPath = path.join(cardsDirAbs, chatProcessingMarkerKey);
164
+ fs.unlinkSync(markerPath);
165
+ return;
166
+ } catch {}
158
167
  }
168
+ try { fs.unlinkSync(path.join(chatDirAbs, '.processing')); } catch {}
159
169
  }
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "port": 7799,
3
+ "serverMetaStoreRef": "::fs-path::./.server-meta",
3
4
  "cardsDir": "./cards",
4
5
  "taskExecutorPath": "./demo-task-executor.js",
5
6
  "chatHandlerPath": "./demo-chat-handler.js",
@@ -27,7 +27,6 @@ function resolveYamlFlowDir() {
27
27
  }
28
28
 
29
29
  const _yamlFlowDir = resolveYamlFlowDir();
30
- const _pkgCliJs = _yamlFlowDir ? path.join(_yamlFlowDir, 'board-live-cards-cli.js') : null;
31
30
  const _pkgStepMachineCli = _yamlFlowDir ? path.join(_yamlFlowDir, 'step-machine-cli.js') : null;
32
31
 
33
32
  function loadServerConfig() {
@@ -47,8 +46,17 @@ function resolveFromConfig(configValue) {
47
46
  return path.resolve(__dirname, configValue);
48
47
  }
49
48
 
49
+ function resolveKindRefFromConfig(configValue) {
50
+ if (typeof configValue !== 'string' || !configValue.trim()) return null;
51
+ const trimmed = configValue.trim();
52
+ if (!trimmed.startsWith('::fs-path::')) return trimmed;
53
+ const rawPath = trimmed.slice('::fs-path::'.length).trim();
54
+ if (!rawPath) return null;
55
+ const resolved = path.isAbsolute(rawPath) ? rawPath : path.resolve(__dirname, rawPath);
56
+ return `::fs-path::${resolved}`;
57
+ }
58
+
50
59
  const serverConfig = loadServerConfig();
51
- const configuredCliJs = resolveFromConfig(serverConfig.boardLiveCardsCliJs) || _pkgCliJs;
52
60
  const configuredCardsDir = resolveFromConfig(serverConfig.cardsDir);
53
61
  const configuredTaskExecutorPath = resolveFromConfig(serverConfig.taskExecutorPath || serverConfig.demoTaskExecutorPath);
54
62
  const configuredStepMachineCliPath = resolveFromConfig(serverConfig.stepMachineCliPath) || _pkgStepMachineCli;
@@ -58,10 +66,8 @@ const configuredGandalfCardsDir = resolveFromConfig(serverConfig.gandalfCardsDir
58
66
  const configuredGandalfTaskExecutorPath = resolveFromConfig(serverConfig.gandalfTaskExecutorPath);
59
67
  const configuredGandalfChatHandlerPath = resolveFromConfig(serverConfig.gandalfChatHandlerPath);
60
68
  const configuredGandalfInferenceAdapterPath = resolveFromConfig(serverConfig.gandalfInferenceAdapterPath);
69
+ const configuredServerMetaStoreRef = resolveKindRefFromConfig(serverConfig.serverMetaStoreRef);
61
70
 
62
- if (!process.env.BOARD_LIVE_CARDS_CLI_JS && configuredCliJs) {
63
- process.env.BOARD_LIVE_CARDS_CLI_JS = configuredCliJs;
64
- }
65
71
  if (!process.env.DEMO_STEP_MACHINE_CLI_PATH && configuredStepMachineCliPath) {
66
72
  process.env.DEMO_STEP_MACHINE_CLI_PATH = configuredStepMachineCliPath;
67
73
  }
@@ -93,7 +99,7 @@ const runtime = createMultiBoardServerRuntime({
93
99
  defaultGandalfTaskExecutorPath: process.env.DEMO_GANDALF_TASK_EXECUTOR_PATH || configuredGandalfTaskExecutorPath || null,
94
100
  defaultGandalfChatHandlerPath: process.env.DEMO_GANDALF_CHAT_HANDLER_PATH || configuredGandalfChatHandlerPath || null,
95
101
  defaultGandalfInferenceAdapterPath: process.env.DEMO_GANDALF_INFERENCE_ADAPTER_PATH || configuredGandalfInferenceAdapterPath || null,
96
- boardLiveCardsCliJs: process.env.BOARD_LIVE_CARDS_CLI_JS || configuredCliJs,
102
+ serverMetaStoreRef: process.env.DEMO_SERVER_META_STORE_REF || configuredServerMetaStoreRef || null,
97
103
  });
98
104
 
99
105
  function resetRuntime() {
@@ -128,44 +134,22 @@ function jsonReply(res, status, payload) {
128
134
 
129
135
  // ---------------------------------------------------------------------------
130
136
  // Card preparation — host-level concern, not a reusable runtime concern.
131
- // Copies source card JSON files into the runtime's tmpCardsDir and writes
132
- // the concatenated copilot-instructions.md at the board setup root.
133
- // The runtime's bootstrap operations assume cards are already in tmpCardsDir;
134
- // the host (this file) decides how and when they get there.
137
+ // Writes the concatenated copilot-instructions.md at the board setup root.
138
+ // Cards are served directly from cardsDir (no tmp copy needed).
135
139
  // ---------------------------------------------------------------------------
136
140
 
137
141
  const _demoPrepSetupDone = new Map(); // boardId → true
138
142
 
139
143
  function isDemoSetupDone(boardId, service) {
140
- return _demoPrepSetupDone.get(boardId) === true && fs.existsSync(service.tmpCardsDir);
144
+ return _demoPrepSetupDone.get(boardId) === true && fs.existsSync(service.cardsDir);
141
145
  }
142
146
 
143
147
  function demoPrepSetup(boardId, service) {
144
- const { tmpSurfaceDir, tmpCardsDir, cardsDir, gandalfCardsDir, tmpGandalfCardsDir, boardDir } = service;
145
-
146
- fs.mkdirSync(tmpSurfaceDir, { recursive: true });
147
- fs.rmSync(tmpCardsDir, { recursive: true, force: true });
148
- fs.mkdirSync(tmpCardsDir, { recursive: true });
149
-
150
- const entries = fs.readdirSync(cardsDir, { withFileTypes: true });
151
- for (const entry of entries) {
152
- if (!entry.isFile()) continue;
153
- if (!entry.name.toLowerCase().endsWith('.json')) continue;
154
- fs.copyFileSync(path.join(cardsDir, entry.name), path.join(tmpCardsDir, entry.name));
155
- }
156
-
157
- // Copy gandalf-card templates if gandalfCardsDir is configured.
158
- if (gandalfCardsDir && fs.existsSync(gandalfCardsDir)) {
159
- fs.rmSync(tmpGandalfCardsDir, { recursive: true, force: true });
160
- fs.mkdirSync(tmpGandalfCardsDir, { recursive: true });
161
- for (const entry of fs.readdirSync(gandalfCardsDir, { withFileTypes: true })) {
162
- if (!entry.isFile() || !entry.name.toLowerCase().endsWith('.json')) continue;
163
- fs.copyFileSync(path.join(gandalfCardsDir, entry.name), path.join(tmpGandalfCardsDir, entry.name));
164
- }
165
- }
148
+ const { cardsDir, gandalfCardsDir, boardDir } = service;
166
149
 
167
150
  // Concatenate agent-instructions*.md into copilot-instructions.md at boardSetupRoot.
168
151
  const boardSetupRoot = path.dirname(boardDir);
152
+ fs.mkdirSync(boardSetupRoot, { recursive: true });
169
153
  const srcDir = path.dirname(cardsDir);
170
154
  const agentInstructionFiles = ['agent-instructions.md', 'agent-instructions-cardlayout.md'];
171
155
  const parts = [];
@@ -289,7 +273,8 @@ const server = http.createServer((req, res) => {
289
273
  server.listen(PORT, '127.0.0.1', () => {
290
274
  console.log(`[demo-server] listening on http://127.0.0.1:${PORT}`);
291
275
  console.log(`[demo-server] setup dir: ${runtime.setupDir}`);
292
- console.log(`[demo-server] boards config: ${runtime.setupDir}/boards-config.json`);
276
+ console.log(`[demo-server] server-meta store: ${runtime.serverMetaStoreRef}`);
277
+ console.log(`[demo-server] boards registry key: server-meta/${runtime.boardsRegistryKey}`);
293
278
  console.log('[demo-server] endpoints:');
294
279
  console.log(` GET ${runtime.apiBasePath} <- list boards`);
295
280
  console.log(` POST ${runtime.apiBasePath} {id, label?} <- register board`);
@@ -6,9 +6,10 @@
6
6
  <title>Example Board Demo (Browser Runtime)</title>
7
7
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
8
8
  <script src="https://cdn.jsdelivr.net/npm/jsonata/jsonata.min.js"></script>
9
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.0/browser/card-compute.js"></script>
10
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.0/browser/live-cards.js"></script>
11
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.0/browser/board-livegraph-engine.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/leader-line/leader-line.min.js"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@6.0.0/browser/card-compute.js"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@6.0.0/browser/live-cards.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@6.0.0/browser/board-livegraph-engine.js"></script>
12
13
  </head>
13
14
  <body class="bg-light">
14
15
  <div class="container-fluid py-3">
@@ -398,7 +399,7 @@
398
399
  let board = null;
399
400
  let runtime = null;
400
401
  let runtimeUnsub = null;
401
- let currentMode = 'board';
402
+ let currentMode = 'canvas';
402
403
  const nodesById = {};
403
404
 
404
405
  function setDebugPanelVisibility(isDevModeOn) {
@@ -16,10 +16,11 @@
16
16
  </style>
17
17
  <script src="https://cdn.jsdelivr.net/npm/jsonata/jsonata.min.js"></script>
18
18
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
19
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.0/browser/card-compute.js"></script>
20
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.0/browser/live-cards.js"></script>
21
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.0/browser/board-livegraph-engine.js"></script>
22
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.0/browser/board-livecards-runtime-client.js"></script>
19
+ <script src="https://cdn.jsdelivr.net/npm/leader-line/leader-line.min.js"></script>
20
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@6.0.0/browser/card-compute.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@6.0.0/browser/live-cards.js"></script>
22
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@6.0.0/browser/board-livegraph-engine.js"></script>
23
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@6.0.0/browser/board-livecards-runtime-client.js"></script>
23
24
  </head>
24
25
  <body class="bg-light">
25
26
  <div class="container-fluid py-3">
@@ -68,7 +69,7 @@
68
69
  <script>
69
70
  (function () {
70
71
  const { buildLiveCardModelsFromArtifacts } = window.BoardLiveGraph || {};
71
- let currentMode = 'board';
72
+ let currentMode = 'canvas';
72
73
  let bootstrapCompleted = false;
73
74
  let activeBoardId = 'default';
74
75
  let runtimeClient = null;
@@ -192,11 +193,14 @@
192
193
  document.getElementById('boardTitle').textContent = bid + ' (Server Runtime)';
193
194
  document.getElementById('boardDesc').textContent = '';
194
195
 
196
+ // Demo-setup is a host-level concern; call it explicitly before bootstrapping.
197
+ const setupRes = await fetch(boardPaths(bid).demoSetup);
198
+ if (!setupRes.ok) throw new Error(`demo-setup failed (${setupRes.status})`);
199
+
195
200
  await runtimeClient.bootstrapBoard({
196
201
  boardId: bid,
197
202
  taskExecutorPath: resolveTaskExecutorPathParam(),
198
203
  rootElement: document.getElementById('boardRoot'),
199
- runDemoSetup: true,
200
204
  mode: currentMode,
201
205
  });
202
206