yaml-flow 5.4.2 → 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 (199) hide show
  1. package/board-live-cards-cli.js +2 -2
  2. package/board-livecards-server-runtime.js +486 -547
  3. package/browser/asset-integrity.json +10 -0
  4. package/browser/board-livegraph-engine.js +2 -1676
  5. package/browser/board-livegraph-engine.js.map +1 -1
  6. package/browser/live-cards.js +347 -26
  7. package/browser/live-cards.schema.json +418 -132
  8. package/card-store.js +37 -0
  9. package/dist/batch/index.cjs +1 -108
  10. package/dist/batch/index.cjs.map +1 -1
  11. package/dist/batch/index.js +1 -106
  12. package/dist/batch/index.js.map +1 -1
  13. package/dist/board-live-cards-lib-Bg6EvCo5.d.cts +136 -0
  14. package/dist/board-live-cards-lib-jM2uYG1v.d.ts +136 -0
  15. package/dist/board-live-cards-public-CltXYgaY.d.cts +314 -0
  16. package/dist/board-live-cards-public-f-E-FAyp.d.ts +314 -0
  17. package/dist/board-livegraph-runtime/index.cjs +2 -1671
  18. package/dist/board-livegraph-runtime/index.cjs.map +1 -1
  19. package/dist/board-livegraph-runtime/index.d.cts +1 -2
  20. package/dist/board-livegraph-runtime/index.d.ts +1 -2
  21. package/dist/board-livegraph-runtime/index.js +2 -1662
  22. package/dist/board-livegraph-runtime/index.js.map +1 -1
  23. package/dist/board-livegraph-runtime/jsonata-sync.cjs +7587 -0
  24. package/dist/card-compute/index.cjs +9 -7159
  25. package/dist/card-compute/index.cjs.map +1 -1
  26. package/dist/card-compute/index.d.cts +22 -0
  27. package/dist/card-compute/index.d.ts +22 -0
  28. package/dist/card-compute/index.js +9 -7145
  29. package/dist/card-compute/index.js.map +1 -1
  30. package/dist/card-compute/jsonata-sync.cjs +7587 -0
  31. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs +2 -0
  32. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs.map +1 -0
  33. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.cts +24 -0
  34. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.ts +24 -0
  35. package/dist/cli/browser-api/board-live-cards-browser-adapter.js +2 -0
  36. package/dist/cli/browser-api/board-live-cards-browser-adapter.js.map +1 -0
  37. package/dist/cli/browser-api/card-store-browser-api.cjs +2 -0
  38. package/dist/cli/browser-api/card-store-browser-api.cjs.map +1 -0
  39. package/dist/cli/browser-api/card-store-browser-api.d.cts +26 -0
  40. package/dist/cli/browser-api/card-store-browser-api.d.ts +26 -0
  41. package/dist/cli/browser-api/card-store-browser-api.js +2 -0
  42. package/dist/cli/browser-api/card-store-browser-api.js.map +1 -0
  43. package/dist/cli/browser-api/jsonata-sync.cjs +7587 -0
  44. package/dist/cli/node/artifacts-store-cli.cjs +11 -0
  45. package/dist/cli/node/artifacts-store-cli.cjs.map +1 -0
  46. package/dist/cli/node/artifacts-store-cli.d.cts +8 -0
  47. package/dist/cli/node/artifacts-store-cli.d.ts +8 -0
  48. package/dist/cli/node/artifacts-store-cli.js +11 -0
  49. package/dist/cli/node/artifacts-store-cli.js.map +1 -0
  50. package/dist/cli/node/board-live-cards-cli.cjs +15 -0
  51. package/dist/cli/node/board-live-cards-cli.cjs.map +1 -0
  52. package/dist/cli/node/board-live-cards-cli.d.cts +20 -0
  53. package/dist/cli/node/board-live-cards-cli.d.ts +20 -0
  54. package/dist/cli/node/board-live-cards-cli.js +15 -0
  55. package/dist/cli/node/board-live-cards-cli.js.map +1 -0
  56. package/dist/cli/node/card-store-cli.cjs +8 -0
  57. package/dist/cli/node/card-store-cli.cjs.map +1 -0
  58. package/dist/cli/node/card-store-cli.d.cts +15 -0
  59. package/dist/cli/node/card-store-cli.d.ts +15 -0
  60. package/dist/cli/node/card-store-cli.js +8 -0
  61. package/dist/cli/node/card-store-cli.js.map +1 -0
  62. package/dist/cli/node/fs-board-adapter.cjs +14 -0
  63. package/dist/cli/node/fs-board-adapter.cjs.map +1 -0
  64. package/dist/cli/node/fs-board-adapter.d.cts +204 -0
  65. package/dist/cli/node/fs-board-adapter.d.ts +204 -0
  66. package/dist/cli/node/fs-board-adapter.js +14 -0
  67. package/dist/cli/node/fs-board-adapter.js.map +1 -0
  68. package/dist/cli/node/jsonata-sync.cjs +7587 -0
  69. package/dist/cli/node/source-cli-task-executor.cjs +11 -0
  70. package/dist/cli/node/source-cli-task-executor.cjs.map +1 -0
  71. package/dist/cli/node/source-cli-task-executor.d.cts +1 -0
  72. package/dist/cli/node/source-cli-task-executor.d.ts +1 -0
  73. package/dist/cli/node/source-cli-task-executor.js +11 -0
  74. package/dist/cli/node/source-cli-task-executor.js.map +1 -0
  75. package/dist/config/index.cjs +1 -79
  76. package/dist/config/index.cjs.map +1 -1
  77. package/dist/config/index.js +1 -76
  78. package/dist/config/index.js.map +1 -1
  79. package/dist/continuous-event-graph/index.cjs +2 -2129
  80. package/dist/continuous-event-graph/index.cjs.map +1 -1
  81. package/dist/continuous-event-graph/index.d.cts +81 -5
  82. package/dist/continuous-event-graph/index.d.ts +81 -5
  83. package/dist/continuous-event-graph/index.js +2 -2088
  84. package/dist/continuous-event-graph/index.js.map +1 -1
  85. package/dist/continuous-event-graph/jsonata-sync.cjs +7587 -0
  86. package/dist/event-graph/index.cjs +22 -8292
  87. package/dist/event-graph/index.cjs.map +1 -1
  88. package/dist/event-graph/index.js +22 -8237
  89. package/dist/event-graph/index.js.map +1 -1
  90. package/dist/execution-refs.cjs +2 -0
  91. package/dist/execution-refs.cjs.map +1 -0
  92. package/dist/execution-refs.d.cts +222 -0
  93. package/dist/execution-refs.d.ts +222 -0
  94. package/dist/execution-refs.js +2 -0
  95. package/dist/execution-refs.js.map +1 -0
  96. package/dist/index.cjs +29 -13221
  97. package/dist/index.cjs.map +1 -1
  98. package/dist/index.d.cts +2 -4
  99. package/dist/index.d.ts +2 -4
  100. package/dist/index.js +29 -13112
  101. package/dist/index.js.map +1 -1
  102. package/dist/inference/index.cjs +5 -617
  103. package/dist/inference/index.cjs.map +1 -1
  104. package/dist/inference/index.js +5 -610
  105. package/dist/inference/index.js.map +1 -1
  106. package/dist/jsonata-sync.cjs +7587 -0
  107. package/dist/{live-cards-bridge-x5XREkXm.d.cts → live-cards-bridge-BXbVTsna.d.cts} +27 -4
  108. package/dist/{live-cards-bridge-EQjytzI_.d.ts → live-cards-bridge-Ds28XR15.d.ts} +27 -4
  109. package/dist/pycli/quickjs-board-runtime.global.js +9 -0
  110. package/dist/pycli/quickjs-board-runtime.global.js.map +1 -0
  111. package/dist/pycli/quickjs-step-machine-runtime.global.js +5 -0
  112. package/dist/pycli/quickjs-step-machine-runtime.global.js.map +1 -0
  113. package/dist/step-machine/index.cjs +11 -7129
  114. package/dist/step-machine/index.cjs.map +1 -1
  115. package/dist/step-machine/index.js +11 -7113
  116. package/dist/step-machine/index.js.map +1 -1
  117. package/dist/storage-refs.cjs +10 -0
  118. package/dist/storage-refs.cjs.map +1 -0
  119. package/dist/storage-refs.d.cts +92 -0
  120. package/dist/storage-refs.d.ts +92 -0
  121. package/dist/storage-refs.js +10 -0
  122. package/dist/storage-refs.js.map +1 -0
  123. package/dist/stores/file.cjs +1 -114
  124. package/dist/stores/file.cjs.map +1 -1
  125. package/dist/stores/file.js +1 -112
  126. package/dist/stores/file.js.map +1 -1
  127. package/dist/stores/index.cjs +1 -231
  128. package/dist/stores/index.cjs.map +1 -1
  129. package/dist/stores/index.js +1 -227
  130. package/dist/stores/index.js.map +1 -1
  131. package/dist/stores/localStorage.cjs +1 -76
  132. package/dist/stores/localStorage.cjs.map +1 -1
  133. package/dist/stores/localStorage.js +1 -74
  134. package/dist/stores/localStorage.js.map +1 -1
  135. package/dist/stores/memory.cjs +1 -47
  136. package/dist/stores/memory.cjs.map +1 -1
  137. package/dist/stores/memory.js +1 -45
  138. package/dist/stores/memory.js.map +1 -1
  139. package/examples/browser/boards/portfolio-tracker/portfolio-t4.js +292 -0
  140. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.js +218 -0
  141. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.py +201 -0
  142. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-inference-adapter.js +25 -16
  143. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-public.js +553 -0
  144. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.py +365 -0
  145. package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/.runtime-out +1 -0
  146. package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/board-graph.json +32 -0
  147. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +53 -1
  148. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +15 -6
  149. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/init-board-cli.js +6 -1
  150. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/poll-status-cli.js +57 -0
  151. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/retrigger-cli.js +1 -1
  152. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/status-cli.js +1 -1
  153. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +7 -2
  154. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/wait-completed-cli.js +6 -2
  155. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/_board_pycli.py +97 -0
  156. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/add-cards.py +50 -0
  157. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/init-board.py +44 -0
  158. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/poll-status.py +70 -0
  159. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/reset-board-dir.py +36 -0
  160. package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-demo.flow.yaml +26 -0
  161. package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-handlers.py +39 -0
  162. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker-pycli.flow.yaml +80 -0
  163. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +25 -172
  164. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.input.json +40 -34
  165. package/examples/cli/step-machine-cli/portfolio-tracker/run-inline-python-demo-pycli.py +46 -0
  166. package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker-pycli.py +77 -0
  167. package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
  168. package/examples/example-board/agent-instructions.md +11 -5
  169. package/examples/example-board/demo-chat-handler.js +14 -4
  170. package/examples/example-board/demo-server-config.json +1 -0
  171. package/examples/example-board/demo-server.js +14 -7
  172. package/examples/example-board/demo-shell-browser.html +5 -4
  173. package/examples/example-board/demo-shell-with-server.html +6 -5
  174. package/examples/example-board/demo-task-executor.js +81 -35
  175. package/examples/index.html +0 -14
  176. package/examples/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +0 -1
  177. package/examples/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
  178. package/package.json +39 -3
  179. package/schema/live-cards.schema.json +418 -132
  180. package/dist/cli/board-live-cards-cli.cjs +0 -10650
  181. package/dist/cli/board-live-cards-cli.cjs.map +0 -1
  182. package/dist/cli/board-live-cards-cli.d.cts +0 -179
  183. package/dist/cli/board-live-cards-cli.d.ts +0 -179
  184. package/dist/cli/board-live-cards-cli.js +0 -10598
  185. package/dist/cli/board-live-cards-cli.js.map +0 -1
  186. package/dist/journal-9HEgs7dU.d.ts +0 -28
  187. package/dist/journal-B-JCfQnh.d.cts +0 -28
  188. package/dist/schedule-Cszq9LYY.d.ts +0 -21
  189. package/dist/schedule-qWNL0RQh.d.cts +0 -21
  190. package/examples/browser/boards/portfolio-tracker/cards/holdings-table.json +0 -22
  191. package/examples/browser/boards/portfolio-tracker/cards/portfolio-form.json +0 -16
  192. package/examples/browser/boards/portfolio-tracker/cards/portfolio-risk-assessment.json +0 -28
  193. package/examples/browser/boards/portfolio-tracker/cards/portfolio-value.json +0 -15
  194. package/examples/browser/boards/portfolio-tracker/cards/price-fetch.json +0 -15
  195. package/examples/browser/boards/portfolio-tracker/cards/rebalancing-strategy.json +0 -28
  196. package/examples/browser/boards/portfolio-tracker/fetch-prices.js +0 -43
  197. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-task-executor.cjs +0 -96
  198. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.bat +0 -7
  199. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.js +0 -351
@@ -0,0 +1,97 @@
1
+ """Shared helpers for step-machine portfolio-tracker pycli handlers.
2
+
3
+ Each handler reads a JSON object from stdin and writes a JSON object to stdout.
4
+ Result schema: {"result": "success" | "failure" | "timeout", "data"?: {...}, "error"?: "..."}
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import json
9
+ import os
10
+ import subprocess
11
+ import sys
12
+ from pathlib import Path
13
+ from typing import Any
14
+
15
+ # Repo root layout (standalone or source tree):
16
+ # <root>/pycli/main/board_live_cards_pycli.py
17
+ # <root>/pycli/main/card_store_pycli.py
18
+ # <root>/dist/pycli/quickjs-board-runtime.global.js
19
+ _HERE = Path(__file__).resolve().parent
20
+ _REPO_ROOT = _HERE.parents[4]
21
+
22
+ BOARD_PYCLI = _REPO_ROOT / "pycli" / "main" / "board_live_cards_pycli.py"
23
+ CARD_STORE_PYCLI = _REPO_ROOT / "pycli" / "main" / "card_store_pycli.py"
24
+ QUICKJS_BUNDLE = _REPO_ROOT / "dist" / "pycli" / "quickjs-board-runtime.global.js"
25
+
26
+
27
+ def read_stdin_json() -> dict[str, Any]:
28
+ raw = sys.stdin.read()
29
+ if not raw.strip():
30
+ return {}
31
+ return json.loads(raw)
32
+
33
+
34
+ def write_result(payload: dict[str, Any]) -> None:
35
+ sys.stdout.write(json.dumps(payload, ensure_ascii=True))
36
+ sys.stdout.flush()
37
+
38
+
39
+ def write_failure(message: str) -> None:
40
+ write_result({"result": "failure", "error": message})
41
+
42
+
43
+ def _hidden_kwargs() -> dict[str, Any]:
44
+ kwargs: dict[str, Any] = {}
45
+ if os.name == "nt":
46
+ startupinfo = subprocess.STARTUPINFO()
47
+ startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
48
+ kwargs["startupinfo"] = startupinfo
49
+ kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
50
+ return kwargs
51
+
52
+
53
+ def run_board_pycli(args: list[str], *, capture: bool = False) -> str:
54
+ cmd = [sys.executable, str(BOARD_PYCLI), *args, "--bundle", str(QUICKJS_BUNDLE)]
55
+ proc = subprocess.run(
56
+ cmd,
57
+ capture_output=True,
58
+ text=True,
59
+ check=False,
60
+ **_hidden_kwargs(),
61
+ )
62
+ if proc.returncode != 0:
63
+ msg = (proc.stderr or proc.stdout or "no output").strip()
64
+ raise RuntimeError(f"board_live_cards_pycli failed ({proc.returncode}): {msg}")
65
+ return proc.stdout if capture else ""
66
+
67
+
68
+ def run_board_pycli_with_input(args: list[str], input_json: str) -> str:
69
+ cmd = [sys.executable, str(BOARD_PYCLI), *args, "--bundle", str(QUICKJS_BUNDLE)]
70
+ proc = subprocess.run(
71
+ cmd,
72
+ input=input_json,
73
+ capture_output=True,
74
+ text=True,
75
+ check=False,
76
+ **_hidden_kwargs(),
77
+ )
78
+ if proc.returncode != 0:
79
+ msg = (proc.stderr or proc.stdout or "no output").strip()
80
+ raise RuntimeError(f"board_live_cards_pycli failed ({proc.returncode}): {msg}")
81
+ return proc.stdout
82
+
83
+
84
+ def run_card_store_pycli_with_input(args: list[str], input_json: str) -> str:
85
+ cmd = [sys.executable, str(CARD_STORE_PYCLI), *args]
86
+ proc = subprocess.run(
87
+ cmd,
88
+ input=input_json,
89
+ capture_output=True,
90
+ text=True,
91
+ check=False,
92
+ **_hidden_kwargs(),
93
+ )
94
+ if proc.returncode != 0:
95
+ msg = (proc.stderr or proc.stdout or "no output").strip()
96
+ raise RuntimeError(f"card_store_pycli failed ({proc.returncode}): {msg}")
97
+ return proc.stdout
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env python3
2
+ """Write all cards to card-store and upsert them onto the board (pycli)."""
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
10
+ from _board_pycli import ( # noqa: E402
11
+ read_stdin_json,
12
+ run_board_pycli,
13
+ run_card_store_pycli_with_input,
14
+ write_failure,
15
+ write_result,
16
+ )
17
+
18
+
19
+ def main() -> int:
20
+ try:
21
+ payload = read_stdin_json()
22
+ board_dir = str(payload.get("BOARD_DIR", "")).strip()
23
+ cards = payload.get("CARDS")
24
+ if not isinstance(cards, list):
25
+ cards = []
26
+
27
+ if not board_dir or not cards:
28
+ write_failure("BOARD_DIR and CARDS (array) are required")
29
+ return 0
30
+
31
+ base_ref = f"::fs-path::{board_dir}"
32
+
33
+ run_card_store_pycli_with_input(
34
+ ["set", "--store-ref", base_ref],
35
+ json.dumps(cards, ensure_ascii=True),
36
+ )
37
+ run_board_pycli(["upsert-card", "--base-ref", base_ref, "--all"])
38
+
39
+ write_result({
40
+ "result": "success",
41
+ "data": {"board_dir": board_dir, "count": len(cards)},
42
+ })
43
+ return 0
44
+ except Exception as exc:
45
+ write_failure(str(exc))
46
+ return 0
47
+
48
+
49
+ if __name__ == "__main__":
50
+ raise SystemExit(main())
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env python3
2
+ """Initialize the board with card-store and outputs-store refs (pycli)."""
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
9
+ from _board_pycli import ( # noqa: E402
10
+ read_stdin_json,
11
+ run_board_pycli,
12
+ write_failure,
13
+ write_result,
14
+ )
15
+
16
+
17
+ def main() -> int:
18
+ try:
19
+ payload = read_stdin_json()
20
+ board_dir = str(payload.get("BOARD_DIR", "")).strip()
21
+ if not board_dir:
22
+ write_failure("BOARD_DIR is required")
23
+ return 0
24
+
25
+ base_ref = f"::fs-path::{board_dir}"
26
+ run_board_pycli([
27
+ "init",
28
+ "--base-ref", base_ref,
29
+ "--card-store-ref", base_ref,
30
+ "--outputs-store-ref", base_ref,
31
+ ])
32
+
33
+ write_result({
34
+ "result": "success",
35
+ "data": {"board_dir": board_dir, "message": f"initialized {board_dir}"},
36
+ })
37
+ return 0
38
+ except Exception as exc:
39
+ write_failure(str(exc))
40
+ return 0
41
+
42
+
43
+ if __name__ == "__main__":
44
+ raise SystemExit(main())
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env python3
2
+ """Poll board status until all expected cards reach `completed` (pycli)."""
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import sys
7
+ import time
8
+ from pathlib import Path
9
+
10
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
11
+ from _board_pycli import ( # noqa: E402
12
+ read_stdin_json,
13
+ run_board_pycli,
14
+ write_failure,
15
+ write_result,
16
+ )
17
+
18
+
19
+ def main() -> int:
20
+ try:
21
+ payload = read_stdin_json()
22
+ board_dir = str(payload.get("BOARD_DIR", "")).strip()
23
+ expected = int(payload.get("EXPECTED_CARD_COUNT") or 0)
24
+ timeout_ms = int(payload.get("TIMEOUT_MS") or 30_000)
25
+ poll_ms = int(payload.get("POLL_MS") or 500)
26
+
27
+ if not board_dir or expected <= 0:
28
+ write_failure("BOARD_DIR and EXPECTED_CARD_COUNT are required")
29
+ return 0
30
+
31
+ base_ref = f"::fs-path::{board_dir}"
32
+ deadline = time.monotonic() + (timeout_ms / 1000)
33
+
34
+ while time.monotonic() < deadline:
35
+ raw = run_board_pycli(["status", "--base-ref", base_ref], capture=True)
36
+ cards = []
37
+ try:
38
+ cards = json.loads(raw).get("data", {}).get("cards", []) or []
39
+ except Exception:
40
+ cards = []
41
+
42
+ completed = [c for c in cards if c.get("status") == "completed"]
43
+ if len(cards) >= expected and len(completed) >= expected:
44
+ write_result({
45
+ "result": "success",
46
+ "data": {
47
+ "completed": True,
48
+ "card_count": len(cards),
49
+ "completed_count": len(completed),
50
+ },
51
+ })
52
+ return 0
53
+
54
+ time.sleep(poll_ms / 1000)
55
+
56
+ write_result({
57
+ "result": "timeout",
58
+ "data": {
59
+ "completed": False,
60
+ "error": f"timed out waiting for {expected} cards to complete",
61
+ },
62
+ })
63
+ return 0
64
+ except Exception as exc:
65
+ write_failure(str(exc))
66
+ return 0
67
+
68
+
69
+ if __name__ == "__main__":
70
+ raise SystemExit(main())
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env python3
2
+ """Reset (rm -rf) the board runtime directory."""
3
+ from __future__ import annotations
4
+
5
+ import shutil
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
10
+ from _board_pycli import read_stdin_json, write_failure, write_result # noqa: E402
11
+
12
+
13
+ def main() -> int:
14
+ try:
15
+ payload = read_stdin_json()
16
+ board_dir_input = str(payload.get("BOARD_DIR", "")).strip()
17
+ if not board_dir_input:
18
+ write_failure("BOARD_DIR is required")
19
+ return 0
20
+
21
+ board_dir = Path(board_dir_input).resolve()
22
+ if board_dir.exists():
23
+ shutil.rmtree(board_dir, ignore_errors=True)
24
+
25
+ write_result({
26
+ "result": "success",
27
+ "data": {"board_dir": str(board_dir), "reset": True},
28
+ })
29
+ return 0
30
+ except Exception as exc:
31
+ write_failure(str(exc))
32
+ return 0
33
+
34
+
35
+ if __name__ == "__main__":
36
+ raise SystemExit(main())
@@ -0,0 +1,26 @@
1
+ id: inline-python-demo
2
+ settings:
3
+ start_step: greet
4
+ max_total_steps: 5
5
+
6
+ steps:
7
+ greet:
8
+ description: Build a greeting message using Python inline handler
9
+ handler:
10
+ inline: greet_user
11
+ transitions:
12
+ success: add
13
+
14
+ add:
15
+ description: Add two numbers with Python inline handler
16
+ expects_data: [a, b]
17
+ produces_data: [total]
18
+ handler:
19
+ inline: add_numbers
20
+ transitions:
21
+ success: done
22
+
23
+ terminal_states:
24
+ done:
25
+ return_intent: success
26
+ return_artifacts: [message, total]
@@ -0,0 +1,39 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ def greet_user(input_obj, ctx=None):
5
+ payload = input_obj if isinstance(input_obj, dict) else {}
6
+ name = payload.get("name", "world")
7
+ return {
8
+ "result": "success",
9
+ "data": {
10
+ "message": f"Hello, {name}!",
11
+ },
12
+ }
13
+
14
+
15
+ def add_numbers(input_obj, ctx=None):
16
+ payload = input_obj if isinstance(input_obj, dict) else {}
17
+ a = payload.get("a", 0)
18
+ b = payload.get("b", 0)
19
+ try:
20
+ total = float(a) + float(b)
21
+ except Exception:
22
+ return {
23
+ "result": "failure",
24
+ "data": {"error": f"Cannot add values: a={a!r}, b={b!r}"},
25
+ }
26
+
27
+ if total.is_integer():
28
+ total = int(total)
29
+
30
+ return {
31
+ "result": "success",
32
+ "data": {"total": total},
33
+ }
34
+
35
+
36
+ handlers = {
37
+ "greet_user": greet_user,
38
+ "add_numbers": add_numbers,
39
+ }
@@ -0,0 +1,80 @@
1
+ id: portfolio-tracker-step-machine-pycli
2
+ settings:
3
+ start_step: t0_reset_board
4
+ max_total_steps: 30
5
+ timeout_ms: 120000
6
+
7
+ steps:
8
+ t0_reset_board:
9
+ description: Reset board runtime directory for idempotent reruns
10
+ expects_data: [runtime_root, board_name]
11
+ produces_data: [board_dir]
12
+ handler:
13
+ cli: python ./handlers-py/reset-board-dir.py
14
+ input-transforms:
15
+ BOARD_DIR: runtime_root & "/" & board_name
16
+ output-transforms:
17
+ board_dir: data.board_dir
18
+ transitions:
19
+ success: t0_init_board
20
+ failure_transitions:
21
+ failure: failed_state
22
+
23
+ t0_init_board:
24
+ description: Initialize board with card-store and outputs-store refs (pycli)
25
+ expects_data: [board_dir]
26
+ produces_data: [board_dir]
27
+ handler:
28
+ cli: python ./handlers-py/init-board.py
29
+ input-transforms:
30
+ BOARD_DIR: board_dir
31
+ output-transforms:
32
+ board_dir: data.board_dir
33
+ transitions:
34
+ success: t1_add_cards
35
+ failure_transitions:
36
+ failure: failed_state
37
+
38
+ t1_add_cards:
39
+ description: Add cards via card-store set and upsert-card --all (pycli)
40
+ expects_data: [board_dir, cards]
41
+ produces_data: [cards_added]
42
+ handler:
43
+ cli: python ./handlers-py/add-cards.py
44
+ input-transforms:
45
+ BOARD_DIR: board_dir
46
+ CARDS: cards
47
+ output-transforms:
48
+ cards_added: data.count
49
+ transitions:
50
+ success: t2_poll_status
51
+ failure_transitions:
52
+ failure: failed_state
53
+
54
+ t2_poll_status:
55
+ description: Poll board status until all cards are completed (pycli)
56
+ expects_data: [board_dir, expected_card_count]
57
+ produces_data: [all_completed]
58
+ handler:
59
+ cli: python ./handlers-py/poll-status.py
60
+ input-transforms:
61
+ BOARD_DIR: board_dir
62
+ EXPECTED_CARD_COUNT: expected_card_count
63
+ TIMEOUT_MS: "30000"
64
+ POLL_MS: "500"
65
+ output-transforms:
66
+ all_completed: data.completed
67
+ transitions:
68
+ success: success_state
69
+ failure_transitions:
70
+ timeout: failed_state
71
+ failure: failed_state
72
+
73
+ terminal_states:
74
+ success_state:
75
+ return_intent: success
76
+ return_artifacts: [board_dir, cards_added, all_completed]
77
+
78
+ failed_state:
79
+ return_intent: failure
80
+ return_artifacts: [error, board_dir]
@@ -1,11 +1,8 @@
1
1
  id: portfolio-tracker-step-machine
2
- handler_vars:
3
- BOARDCLI_CMD: ../../../../board-live-cards-cli.js
4
- TMP_FILE_NAME: tmp_file1
5
2
  settings:
6
3
  start_step: t0_reset_board
7
- max_total_steps: 150
8
- timeout_ms: 300000
4
+ max_total_steps: 30
5
+ timeout_ms: 120000
9
6
 
10
7
  steps:
11
8
  t0_reset_board:
@@ -24,204 +21,60 @@ steps:
24
21
  failure: failed_state
25
22
 
26
23
  t0_init_board:
27
- description: Initialize board runtime directory
24
+ description: Initialize board with card-store and outputs-store refs
28
25
  expects_data: [board_dir]
29
26
  produces_data: [board_dir]
30
27
  handler:
31
- cli: node %%BOARDCLI_CMD%% init "%%BOARD_DIR%%"
32
- result-mode: exit-code
28
+ cli: node ./handlers/init-board-cli.js
33
29
  input-transforms:
34
30
  BOARD_DIR: board_dir
35
31
  output-transforms:
36
- board_dir: BOARD_DIR
37
- transitions:
38
- success: t0_add_cards
39
- failure_transitions:
40
- failure: failed_state
41
-
42
- t0_add_cards:
43
- description: Add local portfolio cards
44
- expects_data: [board_dir, cards_template_dir]
45
- produces_data: [cards_dir]
46
- handler:
47
- cli: node %%BOARDCLI_CMD%% upsert-card --rg "%%BOARD_DIR%%" --card-glob "%%CARDS_GLOB%%"
48
- result-mode: exit-code
49
- input-transforms:
50
- BOARD_DIR: board_dir
51
- CARDS_GLOB: cards_template_dir & "/*.json"
52
- output-transforms:
53
- cards_dir: cards_template_dir
54
- transitions:
55
- success: t1_write_prices
56
- failure_transitions:
57
- failure: failed_state
58
-
59
- t1_write_prices:
60
- description: Write baseline prices
61
- expects_data: [board_dir, prices_t1]
62
- produces_data: [prices_written_t1]
63
- handler:
64
- cli: node ./handlers/write-prices-cli.js
65
- input-transforms:
66
- BOARD_DIR: board_dir
67
- TMP_FILE_NAME: TMP_FILE_NAME
68
- PRICES: prices_t1
69
- output-transforms:
70
- prices_written_t1: data.wrote
71
- transitions:
72
- success: t1_wait
73
- failure_transitions:
74
- failure: failed_state
75
-
76
- t1_wait:
77
- description: Wait for cards to complete after T1
78
- expects_data: [board_dir, completion_tasks]
79
- produces_data: [t1_done]
80
- handler:
81
- cli: node ./handlers/wait-completed-cli.js
82
- input-transforms:
83
- BOARD_DIR: board_dir
84
- COMPLETION_TASKS: completion_tasks
85
- LABEL: "'T1'"
86
- TIMEOUT_MS: "60000"
87
- POLL_MS: "500"
88
- output-transforms:
89
- t1_done: data.completed
90
- transitions:
91
- success: t2_update_holdings
92
- failure_transitions:
93
- timeout: failed_state
94
- failure: failed_state
95
-
96
- t2_update_holdings:
97
- description: Add GOOG position to holdings
98
- expects_data: [board_dir, cards_dir, holdings_t2]
99
- produces_data: [t2_holdings_saved]
100
- handler:
101
- cli: node ./handlers/update-holdings-cli.js
102
- input-transforms:
103
- BOARD_DIR: board_dir
104
- CARDS_DIR: cards_dir
105
- HOLDINGS: holdings_t2
106
- output-transforms:
107
- t2_holdings_saved: data.saved
108
- transitions:
109
- success: t2_write_prices
110
- failure_transitions:
111
- failure: failed_state
112
-
113
- t2_write_prices:
114
- description: Write prices after T2 holdings update
115
- expects_data: [board_dir, prices_t2]
116
- produces_data: [prices_written_t2]
117
- handler:
118
- cli: node ./handlers/write-prices-cli.js
119
- input-transforms:
120
- BOARD_DIR: board_dir
121
- TMP_FILE_NAME: TMP_FILE_NAME
122
- PRICES: prices_t2
123
- output-transforms:
124
- prices_written_t2: data.wrote
125
- transitions:
126
- success: t2_wait
127
- failure_transitions:
128
- failure: failed_state
129
-
130
- t2_wait:
131
- description: Wait for cards to complete after T2
132
- expects_data: [board_dir, completion_tasks]
133
- produces_data: [t2_done]
134
- handler:
135
- cli: node ./handlers/wait-completed-cli.js
136
- input-transforms:
137
- BOARD_DIR: board_dir
138
- COMPLETION_TASKS: completion_tasks
139
- LABEL: "'T2'"
140
- TIMEOUT_MS: "60000"
141
- POLL_MS: "500"
142
- output-transforms:
143
- t2_done: data.completed
144
- transitions:
145
- success: t3_retrigger
146
- failure_transitions:
147
- timeout: failed_state
148
- failure: failed_state
149
-
150
- t3_retrigger:
151
- description: Retrigger price-fetch task
152
- expects_data: [board_dir, price_fetch_task]
153
- produces_data: [t3_retriggered]
154
- handler:
155
- cli: node %%BOARDCLI_CMD%% retrigger --rg "%%BOARD_DIR%%" --task "%%TASK%%"
156
- result-mode: exit-code
157
- input-transforms:
158
- BOARD_DIR: board_dir
159
- TASK: price_fetch_task
160
- output-transforms:
161
- t3_retriggered: true
32
+ board_dir: data.board_dir
162
33
  transitions:
163
- success: t3_write_prices
34
+ success: t1_add_cards
164
35
  failure_transitions:
165
36
  failure: failed_state
166
37
 
167
- t3_write_prices:
168
- description: Write final refreshed prices
169
- expects_data: [board_dir, prices_t3]
170
- produces_data: [prices_written_t3]
38
+ t1_add_cards:
39
+ description: Add 3 cards via card-store set and upsert-card --all
40
+ expects_data: [board_dir, cards]
41
+ produces_data: [cards_added]
171
42
  handler:
172
- cli: node ./handlers/write-prices-cli.js
43
+ cli: node ./handlers/add-cards-cli.js
173
44
  input-transforms:
174
45
  BOARD_DIR: board_dir
175
- TMP_FILE_NAME: TMP_FILE_NAME
176
- PRICES: prices_t3
46
+ CARDS: cards
177
47
  output-transforms:
178
- prices_written_t3: data.wrote
48
+ cards_added: data.count
179
49
  transitions:
180
- success: t3_wait
50
+ success: t2_poll_status
181
51
  failure_transitions:
182
52
  failure: failed_state
183
53
 
184
- t3_wait:
185
- description: Wait for cards to complete after T3
186
- expects_data: [board_dir, completion_tasks]
187
- produces_data: [t3_done]
54
+ t2_poll_status:
55
+ description: Poll board status until all 3 cards are completed
56
+ expects_data: [board_dir, expected_card_count]
57
+ produces_data: [all_completed]
188
58
  handler:
189
- cli: node ./handlers/wait-completed-cli.js
59
+ cli: node ./handlers/poll-status-cli.js
190
60
  input-transforms:
191
61
  BOARD_DIR: board_dir
192
- COMPLETION_TASKS: completion_tasks
193
- LABEL: "'T3'"
194
- TIMEOUT_MS: "60000"
62
+ EXPECTED_CARD_COUNT: expected_card_count
63
+ TIMEOUT_MS: "30000"
195
64
  POLL_MS: "500"
196
65
  output-transforms:
197
- t3_done: data.completed
198
- transitions:
199
- success: t4_status
200
- failure_transitions:
201
- timeout: failed_state
202
- failure: failed_state
203
-
204
- t4_status:
205
- description: Capture final board status
206
- expects_data: [board_dir]
207
- produces_data: [final_status]
208
- handler:
209
- cli: node %%BOARDCLI_CMD%% status --rg "%%BOARD_DIR%%"
210
- result-mode: exit-code
211
- input-transforms:
212
- BOARD_DIR: board_dir
213
- output-transforms:
214
- final_status: stdout
66
+ all_completed: data.completed
215
67
  transitions:
216
68
  success: success_state
217
69
  failure_transitions:
70
+ timeout: failed_state
218
71
  failure: failed_state
219
72
 
220
73
  terminal_states:
221
74
  success_state:
222
75
  return_intent: success
223
- return_artifacts: [board_dir, t1_done, t2_done, t3_done, final_status]
76
+ return_artifacts: [board_dir, cards_added, all_completed]
224
77
 
225
78
  failed_state:
226
79
  return_intent: failure
227
- return_artifacts: [error, board_dir, final_status]
80
+ return_artifacts: [error, board_dir]