yaml-flow 6.0.0 → 7.1.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 (166) hide show
  1. package/board-live-cards-cli.js +4 -4
  2. package/browser/asset-integrity.json +3 -3
  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 -2
  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 +264 -151
  13. package/card-store.js +4 -4
  14. package/dist/{board-live-cards-public-CltXYgaY.d.cts → board-live-cards-public-5n1-syA3.d.cts} +8 -5
  15. package/dist/{board-live-cards-public-f-E-FAyp.d.ts → board-live-cards-public-CK_J8uv0.d.ts} +8 -5
  16. package/dist/board-livegraph-runtime/index.cjs +2 -2
  17. package/dist/board-livegraph-runtime/index.cjs.map +1 -1
  18. package/dist/board-livegraph-runtime/index.d.cts +11 -9
  19. package/dist/board-livegraph-runtime/index.d.ts +11 -9
  20. package/dist/board-livegraph-runtime/index.js +2 -2
  21. package/dist/board-livegraph-runtime/index.js.map +1 -1
  22. package/dist/board-livegraph-runtime/jsonata-sync.cjs +37 -1
  23. package/dist/card-compute/index.cjs +4 -4
  24. package/dist/card-compute/index.cjs.map +1 -1
  25. package/dist/card-compute/index.d.cts +5 -1
  26. package/dist/card-compute/index.d.ts +5 -1
  27. package/dist/card-compute/index.js +4 -4
  28. package/dist/card-compute/index.js.map +1 -1
  29. package/dist/card-compute/jsonata-sync.cjs +37 -1
  30. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs +2 -1
  31. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs.map +1 -1
  32. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.cts +27 -14
  33. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.ts +27 -14
  34. package/dist/cli/browser-api/board-live-cards-browser-adapter.js +2 -1
  35. package/dist/cli/browser-api/board-live-cards-browser-adapter.js.map +1 -1
  36. package/dist/cli/browser-api/card-store-browser-api.cjs +1 -1
  37. package/dist/cli/browser-api/card-store-browser-api.cjs.map +1 -1
  38. package/dist/cli/browser-api/card-store-browser-api.js +1 -1
  39. package/dist/cli/browser-api/card-store-browser-api.js.map +1 -1
  40. package/dist/cli/browser-api/jsonata-sync.cjs +37 -1
  41. package/dist/cli/node/artifacts-store-cli.cjs +8 -8
  42. package/dist/cli/node/artifacts-store-cli.cjs.map +1 -1
  43. package/dist/cli/node/artifacts-store-cli.js +8 -8
  44. package/dist/cli/node/artifacts-store-cli.js.map +1 -1
  45. package/dist/cli/node/board-live-cards-cli.cjs +7 -7
  46. package/dist/cli/node/board-live-cards-cli.cjs.map +1 -1
  47. package/dist/cli/node/board-live-cards-cli.js +7 -7
  48. package/dist/cli/node/board-live-cards-cli.js.map +1 -1
  49. package/dist/cli/node/card-store-cli.cjs +5 -5
  50. package/dist/cli/node/card-store-cli.cjs.map +1 -1
  51. package/dist/cli/node/card-store-cli.js +5 -5
  52. package/dist/cli/node/card-store-cli.js.map +1 -1
  53. package/dist/cli/node/execution-adapter.cjs +3 -0
  54. package/dist/cli/node/execution-adapter.cjs.map +1 -0
  55. package/dist/cli/node/execution-adapter.d.cts +174 -0
  56. package/dist/cli/node/execution-adapter.d.ts +174 -0
  57. package/dist/cli/node/execution-adapter.js +3 -0
  58. package/dist/cli/node/execution-adapter.js.map +1 -0
  59. package/dist/cli/node/fs-board-adapter.cjs +7 -7
  60. package/dist/cli/node/fs-board-adapter.cjs.map +1 -1
  61. package/dist/cli/node/fs-board-adapter.d.cts +2 -2
  62. package/dist/cli/node/fs-board-adapter.d.ts +2 -2
  63. package/dist/cli/node/fs-board-adapter.js +7 -7
  64. package/dist/cli/node/fs-board-adapter.js.map +1 -1
  65. package/dist/cli/node/jsonata-sync.cjs +37 -1
  66. package/dist/cli/node/source-cli-task-executor.cjs +4 -4
  67. package/dist/cli/node/source-cli-task-executor.cjs.map +1 -1
  68. package/dist/cli/node/source-cli-task-executor.js +4 -4
  69. package/dist/cli/node/source-cli-task-executor.js.map +1 -1
  70. package/dist/continuous-event-graph/index.cjs +2 -2
  71. package/dist/continuous-event-graph/index.cjs.map +1 -1
  72. package/dist/continuous-event-graph/index.js +2 -2
  73. package/dist/continuous-event-graph/index.js.map +1 -1
  74. package/dist/continuous-event-graph/jsonata-sync.cjs +37 -1
  75. package/dist/execution-refs.cjs +2 -1
  76. package/dist/execution-refs.cjs.map +1 -1
  77. package/dist/execution-refs.d.cts +55 -12
  78. package/dist/execution-refs.d.ts +55 -12
  79. package/dist/execution-refs.js +2 -1
  80. package/dist/execution-refs.js.map +1 -1
  81. package/dist/index.cjs +10 -10
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.js +10 -10
  84. package/dist/index.js.map +1 -1
  85. package/dist/jsonata-sync.cjs +37 -1
  86. package/dist/server-runtime/index.cjs +9 -0
  87. package/dist/server-runtime/index.cjs.map +1 -0
  88. package/dist/server-runtime/index.d.cts +31 -0
  89. package/dist/server-runtime/index.d.ts +31 -0
  90. package/dist/server-runtime/index.js +9 -0
  91. package/dist/server-runtime/index.js.map +1 -0
  92. package/dist/server-runtime/jsonata-sync.cjs +7623 -0
  93. package/dist/step-machine-public/index.cjs +3 -0
  94. package/dist/step-machine-public/index.cjs.map +1 -0
  95. package/dist/step-machine-public/index.d.cts +166 -0
  96. package/dist/step-machine-public/index.d.ts +166 -0
  97. package/dist/step-machine-public/index.js +3 -0
  98. package/dist/step-machine-public/index.js.map +1 -0
  99. package/dist/step-machine-public/jsonata-sync.cjs +7623 -0
  100. package/dist/storage-refs.cjs +2 -2
  101. package/dist/storage-refs.cjs.map +1 -1
  102. package/dist/storage-refs.d.cts +6 -6
  103. package/dist/storage-refs.d.ts +6 -6
  104. package/dist/storage-refs.js +2 -2
  105. package/dist/storage-refs.js.map +1 -1
  106. package/dist/types-CU3DjTKL.d.cts +147 -0
  107. package/dist/types-HGDTWIun.d.ts +147 -0
  108. package/examples/browser/boards/portfolio-tracker/portfolio-t4.js +9 -10
  109. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-http-test.js +370 -0
  110. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-http-test.py +398 -0
  111. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-public.js +9 -10
  112. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-server.js +300 -0
  113. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-server.py +617 -0
  114. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-sse-worker.js +48 -0
  115. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.py +11 -10
  116. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +19 -4
  117. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +4 -8
  118. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/init-board-cli.js +6 -10
  119. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/poll-status-cli.js +8 -16
  120. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/reset-board-dir-cli.js +2 -6
  121. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/retrigger-cli.js +4 -8
  122. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/status-cli.js +3 -7
  123. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +4 -8
  124. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/wait-completed-cli.js +7 -16
  125. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/write-prices-cli.js +2 -6
  126. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/_board_pycli.py +13 -3
  127. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/add-cards.py +2 -1
  128. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/init-board.py +2 -1
  129. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/poll-status.py +2 -1
  130. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +20 -24
  131. package/examples/cli/step-machine-cli/portfolio-tracker/run-inline-python-demo-pycli.py +0 -3
  132. package/examples/cli/step-machine-demo/jsonata-init-board-cli.js +8 -13
  133. package/examples/cli/step-machine-demo/jsonata-init-board.flow.yaml +33 -9
  134. package/examples/cli/step-machine-demo/one-step-cli-only.flow.yaml +3 -1
  135. package/examples/cli/step-machine-demo/step2-double-cli.js +6 -12
  136. package/examples/cli/step-machine-demo/two-step-math.flow.yaml +66 -4
  137. package/examples/cli/step-machine-demo/two-step-mixed.flow.yaml +13 -5
  138. package/examples/example-board/agent-instructions.md +1 -1
  139. package/examples/example-board/cards/card-my-identity.json +30 -6
  140. package/examples/example-board/cards/card-portfolio-action.json +24 -6
  141. package/examples/example-board/cards/card-portfolio-intelligence.json +97 -0
  142. package/examples/example-board/cards/card-portfolio-risks.json +24 -6
  143. package/examples/example-board/cards/card-rebalance-impact.json +22 -6
  144. package/examples/example-board/cards/card-rebalance-sim.json +66 -15
  145. package/examples/example-board/cards/cardT-market-prices.json +80 -0
  146. package/examples/example-board/cards/{card-portfolio-value.json → cardT-portfolio-value.json} +38 -10
  147. package/examples/example-board/cards/cardT-portfolio.json +78 -0
  148. package/examples/example-board/demo-server-config.json +1 -1
  149. package/examples/example-board/demo-server.js +383 -69
  150. package/examples/example-board/demo-shell-localstorage.html +774 -0
  151. package/examples/example-board/demo-shell-with-server.html +18 -36
  152. package/examples/example-board/demo-shell.html +5 -4
  153. package/examples/example-board/demo-task-executor.js +213 -265
  154. package/package.json +15 -13
  155. package/step-machine-cli.js +43 -310
  156. package/board-livecards-server-runtime.js +0 -1513
  157. package/browser/board-livecards-runtime-client.js +0 -263
  158. package/dist/pycli/quickjs-board-runtime.global.js +0 -9
  159. package/dist/pycli/quickjs-board-runtime.global.js.map +0 -1
  160. package/dist/pycli/quickjs-step-machine-runtime.global.js +0 -5
  161. package/dist/pycli/quickjs-step-machine-runtime.global.js.map +0 -1
  162. package/examples/cli/step-machine-demo/two-step-math-handlers.js +0 -32
  163. package/examples/cli/step-machine-demo/two-step-mixed-handlers.js +0 -24
  164. package/examples/example-board/cards/card-market-prices.json +0 -56
  165. package/examples/example-board/cards/card-portfolio.json +0 -44
  166. package/examples/example-board/demo-shell-browser.html +0 -675
@@ -1,21 +1,45 @@
1
1
  id: jsonata-init-board-demo
2
2
  settings:
3
- start_step: t0_init_board
3
+ start_step: t0_prepare
4
4
  max_total_steps: 10
5
5
  timeout_ms: 30000
6
6
 
7
7
  steps:
8
- t0_init_board:
9
- description: Build board path with JSONata and invoke CLI with command templating
8
+ t0_prepare:
9
+ description: Build board path from runtime_root and board_name
10
10
  expects_data: [runtime_root, board_name]
11
+ produces_data: [BOARD_DIR]
12
+ handler:
13
+ type: compute-jsonata
14
+ expr:
15
+ - data.BOARD_DIR = expects_data.runtime_root & "/" & expects_data.board_name
16
+ - result = "success"
17
+ transitions:
18
+ success: t1_init_board
19
+ failure: failed_state
20
+
21
+ t1_init_board:
22
+ description: Invoke init-board CLI with BOARD_DIR
23
+ expects_data: [BOARD_DIR]
24
+ produces_data: [board_dir, message]
25
+ handler:
26
+ type: ref
27
+ howToRun: local-node
28
+ whatToRun: {kind: fs-path, value: ./jsonata-init-board-cli.js}
29
+ transitions:
30
+ success: t2_map_output
31
+ failure: failed_state
32
+
33
+ t2_map_output:
34
+ description: Map CLI output to final field names
35
+ expects_data: [BOARD_DIR, message]
11
36
  produces_data: [board_dir, init_message]
12
37
  handler:
13
- cli: node ./jsonata-init-board-cli.js "%%BOARD_DIR%%"
14
- input-transforms:
15
- BOARD_DIR: runtime_root & "/" & board_name
16
- output-transforms:
17
- board_dir: BOARD_DIR
18
- init_message: data.message
38
+ type: compute-jsonata
39
+ expr:
40
+ - data.board_dir = expects_data.BOARD_DIR
41
+ - data.init_message = expects_data.message
42
+ - result = "success"
19
43
  transitions:
20
44
  success: success_state
21
45
  failure: failed_state
@@ -6,7 +6,9 @@ steps:
6
6
  expects_data: [x]
7
7
  produces_data: [y]
8
8
  handler:
9
- cli: node ./step-cli-echo-y.js
9
+ type: ref
10
+ howToRun: local-node
11
+ whatToRun: {kind: fs-path, value: ./step-cli-echo-y.js}
10
12
  transitions:
11
13
  success: success_state
12
14
  failure: failed_state
@@ -13,26 +13,20 @@ process.stdin.on('end', () => {
13
13
  const c = Number(input.c);
14
14
 
15
15
  if (!Number.isFinite(c)) {
16
- process.stdout.write(JSON.stringify({
17
- result: 'failure',
18
- error: 'step2_double requires numeric c',
19
- }));
20
- process.exit(0);
16
+ process.stderr.write('step2_double requires numeric c');
17
+ process.exit(1);
21
18
  return;
22
19
  }
23
20
 
24
21
  const d = c * 2;
25
22
  process.stdout.write(JSON.stringify({
26
- status: 'success',
27
- data: {
28
- a: 123,
29
- d,
30
- },
23
+ a: 123,
24
+ d,
31
25
  }));
32
26
  } catch (error) {
33
27
  const message = error instanceof Error ? error.message : String(error);
34
- process.stdout.write(JSON.stringify({ result: 'failure', error: message }));
35
- process.exit(0);
28
+ process.stderr.write(message);
29
+ process.exit(1);
36
30
  }
37
31
  });
38
32
 
@@ -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: {kind: fs-path, value: ./step2-double-cli.js}
24
32
  transitions:
25
33
  success: success_state
26
34
  failure: failed_state
@@ -706,7 +706,7 @@ Before adding a card to a running board, agents should validate that each source
706
706
 
707
707
  ```bash
708
708
  node board-live-cards-cli.js probe-source \
709
- --card cards/card-market-prices.json \
709
+ --card cards/cardT-market-prices.json \
710
710
  --source-idx 0 \
711
711
  --rg <boardRuntimeDir> \
712
712
  --mock-projections '{"holdings":[{"ticker":"AAPL","quantity":10},{"ticker":"MSFT","quantity":5}]}'
@@ -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,11 +2,17 @@
2
2
  "id": "card-rebalance-impact",
3
3
  "meta": {
4
4
  "title": "Rebalance Impact",
5
- "tags": ["portfolio", "simulation"],
5
+ "tags": [
6
+ "portfolio",
7
+ "simulation"
8
+ ],
6
9
  "simulation": true,
7
10
  "desc": "Before/after impact summary of the proposed rebalance scenario."
8
11
  },
9
- "requires": ["positions", "proposed_trades"],
12
+ "requires": [
13
+ "positions",
14
+ "proposed_trades"
15
+ ],
10
16
  "compute": [
11
17
  {
12
18
  "bindTo": "total_current_value",
@@ -53,13 +59,23 @@
53
59
  "elements": [
54
60
  {
55
61
  "kind": "markdown",
56
- "data": { "bind": "computed_values.summary_md" }
62
+ "data": {
63
+ "bind": "computed_values.summary_md"
64
+ }
57
65
  }
58
66
  ],
59
67
  "layout": {
60
- "board": { "col": 6, "order": 8 },
61
- "canvas": { "x": 1360, "y": 480, "w": 400, "h": 280 }
68
+ "board": {
69
+ "col": 6,
70
+ "order": 8
71
+ },
72
+ "canvas": {
73
+ "x": 1360,
74
+ "y": 480,
75
+ "w": 400,
76
+ "h": 280
77
+ }
62
78
  }
63
79
  },
64
80
  "card_data": {}
65
- }
81
+ }
@@ -2,11 +2,20 @@
2
2
  "id": "card-rebalance-sim",
3
3
  "meta": {
4
4
  "title": "Rebalance Proposal",
5
- "tags": ["portfolio", "simulation"],
5
+ "tags": [
6
+ "portfolio",
7
+ "simulation"
8
+ ],
6
9
  "simulation": true,
7
10
  "desc": "AI-proposed rebalance trades based on portfolio intelligence. Edit quantities before pinning."
8
11
  },
9
- "requires": ["holdings", "portfolio_mix", "portfolio_risks", "portfolio_action", "positions"],
12
+ "requires": [
13
+ "holdings",
14
+ "portfolio_mix",
15
+ "portfolio_risks",
16
+ "portfolio_action",
17
+ "positions"
18
+ ],
10
19
  "source_defs": [
11
20
  {
12
21
  "bindTo": "rebalance",
@@ -24,7 +33,20 @@
24
33
  }
25
34
  ],
26
35
  "provides": [
27
- { "bindTo": "proposed_trades", "ref": "fetched_sources.rebalance.proposed_trades" }
36
+ {
37
+ "bindTo": "proposed_trades",
38
+ "ref": "fetched_sources.rebalance.proposed_trades"
39
+ }
40
+ ],
41
+ "compute": [
42
+ {
43
+ "bindTo": "proposed_trades",
44
+ "expr": "fetched_sources.rebalance.proposed_trades"
45
+ },
46
+ {
47
+ "bindTo": "_view",
48
+ "expr": "fetched_sources.rebalance._view"
49
+ }
28
50
  ],
29
51
  "view": {
30
52
  "elements": [
@@ -32,18 +54,37 @@
32
54
  "kind": "ref",
33
55
  "label": "Proposed Trades",
34
56
  "data": {
35
- "bind": "fetched_sources.rebalance.proposed_trades",
36
- "viewBind": "fetched_sources.rebalance._view",
57
+ "bind": "computed_values.proposed_trades",
58
+ "viewBind": "computed_values._view",
37
59
  "fallbackKind": "editable-table",
38
60
  "writeTo": "card_data.proposed_trades",
39
- "columns": ["ticker", "direction", "current_qty", "change", "proposed_qty", "price", "trade_value", "reason"],
61
+ "columns": [
62
+ "ticker",
63
+ "direction",
64
+ "current_qty",
65
+ "change",
66
+ "proposed_qty",
67
+ "price",
68
+ "trade_value",
69
+ "reason"
70
+ ],
40
71
  "schema": {
41
72
  "properties": {
42
- "current_qty": { "type": "number" },
43
- "change": { "type": "number" },
44
- "proposed_qty": { "type": "number" },
45
- "price": { "type": "number" },
46
- "trade_value": { "type": "number" }
73
+ "current_qty": {
74
+ "type": "number"
75
+ },
76
+ "change": {
77
+ "type": "number"
78
+ },
79
+ "proposed_qty": {
80
+ "type": "number"
81
+ },
82
+ "price": {
83
+ "type": "number"
84
+ },
85
+ "trade_value": {
86
+ "type": "number"
87
+ }
47
88
  }
48
89
  }
49
90
  }
@@ -58,10 +99,20 @@
58
99
  }
59
100
  ],
60
101
  "layout": {
61
- "board": { "col": 6, "order": 7 },
62
- "canvas": { "x": 840, "y": 480, "w": 500, "h": 280 }
102
+ "board": {
103
+ "col": 6,
104
+ "order": 7
105
+ },
106
+ "canvas": {
107
+ "x": 840,
108
+ "y": 480,
109
+ "w": 500,
110
+ "h": 280
111
+ }
63
112
  },
64
- "features": { "refresh": true }
113
+ "features": {
114
+ "refresh": true
115
+ }
65
116
  },
66
117
  "card_data": {}
67
- }
118
+ }