yaml-flow 3.1.1 → 4.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.
- package/README.md +81 -20
- package/board-live-cards-cli.js +37 -0
- package/browser/card-compute.js +132 -431
- package/browser/live-cards.js +41 -27
- package/browser/live-cards.schema.json +59 -77
- package/dist/card-compute/index.cjs +135 -415
- package/dist/card-compute/index.cjs.map +1 -1
- package/dist/card-compute/index.d.cts +52 -49
- package/dist/card-compute/index.d.ts +52 -49
- package/dist/card-compute/index.js +134 -415
- package/dist/card-compute/index.js.map +1 -1
- package/dist/cli/board-live-cards-cli.cjs +2379 -0
- package/dist/cli/board-live-cards-cli.cjs.map +1 -0
- package/dist/cli/board-live-cards-cli.d.cts +213 -0
- package/dist/cli/board-live-cards-cli.d.ts +213 -0
- package/dist/cli/board-live-cards-cli.js +2332 -0
- package/dist/cli/board-live-cards-cli.js.map +1 -0
- package/dist/{constants-B2zqu10b.d.ts → constants-DuzE5n03.d.ts} +2 -2
- package/dist/{constants-DJZU1pwJ.d.cts → constants-ozjf1Ejw.d.cts} +2 -2
- package/dist/continuous-event-graph/index.cjs +201 -448
- package/dist/continuous-event-graph/index.cjs.map +1 -1
- package/dist/continuous-event-graph/index.d.cts +16 -340
- package/dist/continuous-event-graph/index.d.ts +16 -340
- package/dist/continuous-event-graph/index.js +198 -448
- package/dist/continuous-event-graph/index.js.map +1 -1
- package/dist/event-graph/index.cjs +4 -4
- package/dist/event-graph/index.cjs.map +1 -1
- package/dist/event-graph/index.d.cts +5 -5
- package/dist/event-graph/index.d.ts +5 -5
- package/dist/event-graph/index.js +4 -4
- package/dist/event-graph/index.js.map +1 -1
- package/dist/index.cjs +278 -533
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +278 -533
- package/dist/index.js.map +1 -1
- package/dist/inference/index.cjs +138 -19
- package/dist/inference/index.cjs.map +1 -1
- package/dist/inference/index.d.cts +2 -2
- package/dist/inference/index.d.ts +2 -2
- package/dist/inference/index.js +138 -19
- package/dist/inference/index.js.map +1 -1
- package/dist/journal-BJDjWb5Q.d.cts +343 -0
- package/dist/journal-B_2JnBMF.d.ts +343 -0
- package/dist/step-machine/index.cjs +18 -1
- package/dist/step-machine/index.cjs.map +1 -1
- package/dist/step-machine/index.d.cts +2 -2
- package/dist/step-machine/index.d.ts +2 -2
- package/dist/step-machine/index.js +18 -1
- package/dist/step-machine/index.js.map +1 -1
- package/dist/stores/file.d.cts +1 -1
- package/dist/stores/file.d.ts +1 -1
- package/dist/stores/index.d.cts +1 -1
- package/dist/stores/index.d.ts +1 -1
- package/dist/stores/localStorage.d.cts +1 -1
- package/dist/stores/localStorage.d.ts +1 -1
- package/dist/stores/memory.d.cts +1 -1
- package/dist/stores/memory.d.ts +1 -1
- package/dist/{types-BwvgvlOO.d.cts → types-BzLD8bjb.d.cts} +1 -1
- package/dist/{types-ClRA8hzC.d.ts → types-C2eJ7DAV.d.ts} +1 -1
- package/dist/{types-DEj7OakX.d.cts → types-CMFSIjpc.d.cts} +39 -4
- package/dist/{types-DEj7OakX.d.ts → types-CMFSIjpc.d.ts} +39 -4
- package/dist/{types-FZ_eyErS.d.cts → types-ycun84cq.d.cts} +1 -0
- package/dist/{types-FZ_eyErS.d.ts → types-ycun84cq.d.ts} +1 -0
- package/dist/{validate-DEZ2Ymdb.d.ts → validate-DJQTQ6bP.d.ts} +1 -1
- package/dist/{validate-DqKTZg_o.d.cts → validate-ke92Cleg.d.cts} +1 -1
- package/examples/browser/boards/portfolio-tracker/cards/holdings-table.json +22 -0
- package/examples/browser/boards/portfolio-tracker/cards/portfolio-form.json +16 -0
- package/examples/browser/boards/portfolio-tracker/cards/portfolio-value.json +15 -0
- package/examples/browser/boards/portfolio-tracker/cards/price-fetch.json +15 -0
- package/examples/browser/boards/portfolio-tracker/fetch-prices.js +43 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker.bat +7 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker.js +189 -0
- package/examples/browser/livecards-browser/index.html +688 -0
- package/examples/browser/{index.html → step-machine-browser/index.html} +53 -53
- package/examples/cli/step-machine-cli/portfolio-tracker/cards/holdings-table.json +22 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/cards/portfolio-form.json +43 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/cards/portfolio-value.json +15 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/cards/price-fetch.json +15 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/fetch-prices.js +48 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +58 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +27 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/init-board-cli.js +25 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/reset-board-dir-cli.js +29 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/retrigger-cli.js +27 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/status-cli.js +25 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +37 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/wait-completed-cli.js +53 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/write-prices-cli.js +35 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +227 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.input.json +38 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +29 -0
- package/examples/cli/step-machine-demo/jsonata-init-board-cli.js +36 -0
- package/examples/cli/step-machine-demo/jsonata-init-board.flow.yaml +30 -0
- package/examples/cli/step-machine-demo/one-step-cli-only.flow.yaml +19 -0
- package/examples/cli/step-machine-demo/step-cli-echo-y.js +15 -0
- package/examples/cli/step-machine-demo/step2-double-cli.js +39 -0
- package/examples/cli/step-machine-demo/two-step-math-handlers.js +32 -0
- package/examples/cli/step-machine-demo/two-step-math.flow.yaml +31 -0
- package/examples/cli/step-machine-demo/two-step-mixed-handlers.js +24 -0
- package/examples/cli/step-machine-demo/two-step-mixed.flow.yaml +35 -0
- package/examples/index.html +792 -0
- package/examples/{batch → npm-libs/batch}/batch-step-machine.ts +1 -1
- package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/live-cards-board.ts +1 -1
- package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/live-portfolio-dashboard.ts +1 -1
- package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/portfolio-tracker.ts +1 -1
- package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/reactive-monitoring.ts +1 -1
- package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/reactive-pipeline.ts +1 -1
- package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/soc-incident-board.ts +1 -1
- package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/stock-dashboard.ts +1 -1
- package/examples/{event-graph → npm-libs/event-graph}/ci-cd-pipeline.ts +1 -1
- package/examples/{event-graph → npm-libs/event-graph}/executor-diamond.ts +1 -1
- package/examples/{event-graph → npm-libs/event-graph}/executor-pipeline.ts +1 -1
- package/examples/{event-graph → npm-libs/event-graph}/research-pipeline.ts +1 -1
- package/examples/{graph-of-graphs → npm-libs/graph-of-graphs}/multi-stage-etl.ts +1 -1
- package/examples/{graph-of-graphs → npm-libs/graph-of-graphs}/url-processing-pipeline.ts +1 -1
- package/examples/{inference → npm-libs/inference}/azure-deployment.ts +1 -1
- package/examples/{inference → npm-libs/inference}/copilot-cli.ts +1 -1
- package/examples/{inference → npm-libs/inference}/data-pipeline.ts +1 -1
- package/examples/{inference → npm-libs/inference}/pluggable-adapters.ts +1 -1
- package/examples/{node → npm-libs/node}/ai-conversation.ts +1 -1
- package/examples/{node → npm-libs/node}/simple-greeting.ts +2 -2
- package/examples/step-machine-cli/portfolio-tracker/cards/holdings-table.json +22 -0
- package/examples/step-machine-cli/portfolio-tracker/cards/portfolio-form.json +43 -0
- package/examples/step-machine-cli/portfolio-tracker/cards/portfolio-value.json +15 -0
- package/examples/step-machine-cli/portfolio-tracker/cards/price-fetch.json +15 -0
- package/examples/step-machine-cli/portfolio-tracker/fetch-prices.js +48 -0
- package/examples/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +58 -0
- package/examples/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +27 -0
- package/examples/step-machine-cli/portfolio-tracker/handlers/init-board-cli.js +25 -0
- package/examples/step-machine-cli/portfolio-tracker/handlers/reset-board-dir-cli.js +29 -0
- package/examples/step-machine-cli/portfolio-tracker/handlers/retrigger-cli.js +27 -0
- package/examples/step-machine-cli/portfolio-tracker/handlers/status-cli.js +25 -0
- package/examples/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +37 -0
- package/examples/step-machine-cli/portfolio-tracker/handlers/wait-completed-cli.js +53 -0
- package/examples/step-machine-cli/portfolio-tracker/handlers/write-prices-cli.js +35 -0
- package/examples/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +227 -0
- package/examples/step-machine-cli/portfolio-tracker/portfolio-tracker.input.json +38 -0
- package/examples/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +29 -0
- package/package.json +12 -1
- package/schema/board-status.schema.json +118 -0
- package/schema/flow.schema.json +5 -0
- package/schema/live-cards.schema.json +59 -77
- package/step-machine-cli.js +674 -0
- /package/examples/{flows → npm-libs/flows}/ai-conversation.yaml +0 -0
- /package/examples/{flows → npm-libs/flows}/order-processing.yaml +0 -0
- /package/examples/{flows → npm-libs/flows}/simple-greeting.yaml +0 -0
package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/live-cards-board.ts
RENAMED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* - LiveBoard overload — board.id, board.settings forwarded to GraphConfig
|
|
17
17
|
* - validateReactiveGraph on the resulting graph
|
|
18
18
|
*
|
|
19
|
-
* Run with: npx tsx examples/continuous-event-graph/live-cards-board.ts
|
|
19
|
+
* Run with: npx tsx examples/npm-libs/continuous-event-graph/live-cards-board.ts
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* Dynamically added: allocation-chart, risk-score, daily-pnl,
|
|
23
23
|
* value-alert, summary, correlation, combined-view
|
|
24
24
|
*
|
|
25
|
-
* Run with: npx tsx examples/continuous-event-graph/live-portfolio-dashboard.ts
|
|
25
|
+
* Run with: npx tsx examples/npm-libs/continuous-event-graph/live-portfolio-dashboard.ts
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
import * as fs from 'node:fs';
|
package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/portfolio-tracker.ts
RENAMED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* T3: Force price refresh without form change → retrigger('price-fetch')
|
|
30
30
|
* T4: Quiescent
|
|
31
31
|
*
|
|
32
|
-
* Run with: npx tsx examples/continuous-event-graph/portfolio-tracker.ts
|
|
32
|
+
* Run with: npx tsx examples/npm-libs/continuous-event-graph/portfolio-tracker.ts
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
35
|
import type { GraphConfig } from '../../src/event-graph/types.js';
|
package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/reactive-monitoring.ts
RENAMED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* Scenario: A monitoring system that collects metrics, evaluates alerts,
|
|
16
16
|
* and dynamically adds notification channels at runtime.
|
|
17
17
|
*
|
|
18
|
-
* Run with: npx tsx examples/continuous-event-graph/reactive-monitoring.ts
|
|
18
|
+
* Run with: npx tsx examples/npm-libs/continuous-event-graph/reactive-monitoring.ts
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import {
|
package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/reactive-pipeline.ts
RENAMED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* - validateLiveGraph for runtime state-consistency checks
|
|
10
10
|
* - validateReactiveGraph for handler/dispatch checks
|
|
11
11
|
*
|
|
12
|
-
* Run with: npx tsx examples/continuous-event-graph/reactive-pipeline.ts
|
|
12
|
+
* Run with: npx tsx examples/npm-libs/continuous-event-graph/reactive-pipeline.ts
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import {
|
package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/soc-incident-board.ts
RENAMED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* T1: New intel arrives → retrigger threat-intel → data-changed cascade
|
|
32
32
|
* create-ticket skipped (once) — slack re-fires
|
|
33
33
|
*
|
|
34
|
-
* Run with: npx tsx examples/continuous-event-graph/soc-incident-board.ts
|
|
34
|
+
* Run with: npx tsx examples/npm-libs/continuous-event-graph/soc-incident-board.ts
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
37
|
import type { GraphConfig } from '../../src/event-graph/types.js';
|
package/examples/{continuous-event-graph → npm-libs/continuous-event-graph}/stock-dashboard.ts
RENAMED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - Scheduling adapts as the graph evolves
|
|
11
11
|
* - Snapshots allow persistence and restore
|
|
12
12
|
*
|
|
13
|
-
* Run with: npx tsx examples/continuous-event-graph/stock-dashboard.ts
|
|
13
|
+
* Run with: npx tsx examples/npm-libs/continuous-event-graph/stock-dashboard.ts
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* Inner transform flow (step-machine, per record):
|
|
22
22
|
* parse → validate → normalize → enrich → (accept | reject)
|
|
23
23
|
*
|
|
24
|
-
* Run with: npx tsx examples/graph-of-graphs/multi-stage-etl.ts
|
|
24
|
+
* Run with: npx tsx examples/npm-libs/graph-of-graphs/multi-stage-etl.ts
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* - resolveConfigTemplates() for DRY task configs
|
|
20
20
|
* - Parallel fan-out inside inner graph
|
|
21
21
|
*
|
|
22
|
-
* Run with: npx tsx examples/graph-of-graphs/url-processing-pipeline.ts
|
|
22
|
+
* Run with: npx tsx examples/npm-libs/graph-of-graphs/url-processing-pipeline.ts
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - GitHub Copilot CLI installed (comes with VS Code / GitHub Copilot extension)
|
|
9
9
|
* - `copilot` available on PATH
|
|
10
10
|
*
|
|
11
|
-
* Run with: npx tsx examples/inference/copilot-cli.ts
|
|
11
|
+
* Run with: npx tsx examples/npm-libs/inference/copilot-cli.ts
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { createLiveGraph, schedule } from '../../src/continuous-event-graph/index.js';
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Demonstrates iterative inference — run the LLM multiple times as
|
|
5
5
|
* new evidence arrives. Each round may unlock more tasks.
|
|
6
6
|
*
|
|
7
|
-
* Run with: npx tsx examples/inference/data-pipeline.ts
|
|
7
|
+
* Run with: npx tsx examples/npm-libs/inference/data-pipeline.ts
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Shows how to create adapters for different LLM providers.
|
|
5
5
|
* Each adapter implements InferenceAdapter.analyze(prompt) → string.
|
|
6
6
|
*
|
|
7
|
-
* Run with: npx tsx examples/inference/pluggable-adapters.ts
|
|
7
|
+
* Run with: npx tsx examples/npm-libs/inference/pluggable-adapters.ts
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Demonstrates basic usage with file-based persistence.
|
|
5
5
|
*
|
|
6
|
-
* Run with: npx ts-node examples/node/simple-greeting.ts
|
|
7
|
-
* Or after build: node examples/node/simple-greeting.js
|
|
6
|
+
* Run with: npx ts-node examples/npm-libs/node/simple-greeting.ts
|
|
7
|
+
* Or after build: node examples/npm-libs/node/simple-greeting.js
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { createEngine, loadFlow, FileStore } from '../../src/index.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "holdings-table",
|
|
3
|
+
"meta": { "title": "Holdings Table" },
|
|
4
|
+
"requires": ["holdings", "prices"],
|
|
5
|
+
"provides": [{ "bindTo": "table", "src": "computed_values.table" }],
|
|
6
|
+
"state": {},
|
|
7
|
+
"compute": [
|
|
8
|
+
{
|
|
9
|
+
"bindTo": "table",
|
|
10
|
+
"expr": "{ \"rows\": $map(requires.holdings, function($h) { { \"symbol\": $h.symbol, \"qty\": $h.qty, \"price\": $lookup(requires.prices, $h.symbol), \"value\": $h.qty * $lookup(requires.prices, $h.symbol) } }) }"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"view": {
|
|
14
|
+
"elements": [
|
|
15
|
+
{
|
|
16
|
+
"kind": "table",
|
|
17
|
+
"label": "Portfolio Positions",
|
|
18
|
+
"data": { "bind": "computed_values.table.rows", "columns": ["symbol", "qty", "price", "value"] }
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "portfolio-form",
|
|
3
|
+
"meta": {
|
|
4
|
+
"title": "Portfolio Holdings Form"
|
|
5
|
+
},
|
|
6
|
+
"provides": [
|
|
7
|
+
{
|
|
8
|
+
"bindTo": "holdings",
|
|
9
|
+
"src": "state.holdings"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"state": {
|
|
13
|
+
"holdings": [
|
|
14
|
+
{
|
|
15
|
+
"symbol": "AAPL",
|
|
16
|
+
"qty": 50
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"symbol": "MSFT",
|
|
20
|
+
"qty": 30
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"symbol": "GOOG",
|
|
24
|
+
"qty": 100
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
"view": {
|
|
29
|
+
"elements": [
|
|
30
|
+
{
|
|
31
|
+
"kind": "table",
|
|
32
|
+
"label": "Holdings",
|
|
33
|
+
"data": {
|
|
34
|
+
"bind": "state.holdings",
|
|
35
|
+
"columns": [
|
|
36
|
+
"symbol",
|
|
37
|
+
"qty"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "portfolio-value",
|
|
3
|
+
"meta": { "title": "Portfolio Total Value" },
|
|
4
|
+
"requires": ["table"],
|
|
5
|
+
"provides": [{ "bindTo": "totalValue", "src": "computed_values.totalValue" }],
|
|
6
|
+
"state": {},
|
|
7
|
+
"compute": [
|
|
8
|
+
{ "bindTo": "totalValue", "expr": "$sum(requires.table.rows.value)" }
|
|
9
|
+
],
|
|
10
|
+
"view": {
|
|
11
|
+
"elements": [
|
|
12
|
+
{ "kind": "metric", "label": "Total Portfolio Value", "data": { "bind": "computed_values.totalValue" } }
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "price-fetch",
|
|
3
|
+
"meta": { "title": "Fetch Market Prices" },
|
|
4
|
+
"requires": ["holdings"],
|
|
5
|
+
"provides": [{ "bindTo": "prices", "src": "sources.prices" }],
|
|
6
|
+
"state": {},
|
|
7
|
+
"sources": [
|
|
8
|
+
{ "cli": "node ../fetch-prices.js --tmp-file-name tmp_file1", "bindTo": "prices", "outputFile": "prices.json" }
|
|
9
|
+
],
|
|
10
|
+
"view": {
|
|
11
|
+
"elements": [
|
|
12
|
+
{ "kind": "table", "label": "Market Prices", "data": { "bind": "sources.prices" } }
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fetch-prices.js
|
|
3
|
+
* Polls for tmp_file1 payload and outputs JSON to stdout once available.
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'node:fs';
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
|
|
8
|
+
function getArgValue(flagName) {
|
|
9
|
+
const idx = process.argv.indexOf(flagName);
|
|
10
|
+
if (idx < 0) return undefined;
|
|
11
|
+
return process.argv[idx + 1];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const envBoardDir = (process.env.BOARD_DIR ?? '').trim();
|
|
15
|
+
const tmpFileName = String(getArgValue('--tmp-file-name') ?? process.env.TMP_FILE_NAME ?? 'tmp_file1').trim();
|
|
16
|
+
const tmpFilePath = envBoardDir ? path.join(envBoardDir, tmpFileName) : '';
|
|
17
|
+
|
|
18
|
+
if (!tmpFilePath) {
|
|
19
|
+
console.error('BOARD_DIR environment variable is required for fetch-prices.js');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getReadableTmpFile() {
|
|
24
|
+
if (!fs.existsSync(tmpFilePath)) return undefined;
|
|
25
|
+
const content = fs.readFileSync(tmpFilePath, 'utf-8').trim();
|
|
26
|
+
if (!content) return undefined;
|
|
27
|
+
return { tmpFile: tmpFilePath, content };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function waitForFile(timeoutMs = 120000) {
|
|
31
|
+
const started = Date.now();
|
|
32
|
+
const interval = setInterval(() => {
|
|
33
|
+
if (Date.now() - started > timeoutMs) {
|
|
34
|
+
clearInterval(interval);
|
|
35
|
+
console.error('Timed out waiting for tmp_file1 market prices input.');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const ready = getReadableTmpFile();
|
|
40
|
+
if (!ready) return;
|
|
41
|
+
|
|
42
|
+
clearInterval(interval);
|
|
43
|
+
fs.writeFileSync(ready.tmpFile, '', 'utf-8');
|
|
44
|
+
process.stdout.write(`${ready.content}\n`);
|
|
45
|
+
}, 250);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
waitForFile();
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
const repoRoot = path.resolve(__dirname, '..', '..', '..', '..');
|
|
8
|
+
const boardCliPath = path.join(repoRoot, 'board-live-cards-cli.js');
|
|
9
|
+
|
|
10
|
+
export function runBoardCli(args, options = {}) {
|
|
11
|
+
const { capture = false, cwd = process.cwd() } = options;
|
|
12
|
+
const result = spawnSync(process.execPath, [boardCliPath, ...args], {
|
|
13
|
+
cwd,
|
|
14
|
+
encoding: 'utf-8',
|
|
15
|
+
windowsHide: true,
|
|
16
|
+
stdio: capture ? 'pipe' : 'pipe',
|
|
17
|
+
env: {
|
|
18
|
+
...process.env,
|
|
19
|
+
BOARD_LIVE_CARDS_NO_SPAWN: process.env.BOARD_LIVE_CARDS_NO_SPAWN ?? '1',
|
|
20
|
+
BOARD_DIR: process.env.BOARD_DIR ?? '',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (result.error) {
|
|
25
|
+
throw new Error(`Failed to launch board-live-cards-cli: ${result.error.message}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if ((result.status ?? 1) !== 0) {
|
|
29
|
+
const stderr = (result.stderr ?? '').trim();
|
|
30
|
+
const stdout = (result.stdout ?? '').trim();
|
|
31
|
+
throw new Error(`board-live-cards-cli failed (${result.status}): ${stderr || stdout || 'no output'}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return capture ? (result.stdout ?? '') : '';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function readStdinJson() {
|
|
38
|
+
let raw = '';
|
|
39
|
+
process.stdin.setEncoding('utf-8');
|
|
40
|
+
|
|
41
|
+
for await (const chunk of process.stdin) {
|
|
42
|
+
raw += chunk;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!raw.trim()) {
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return JSON.parse(raw);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function writeResult(payload) {
|
|
53
|
+
process.stdout.write(JSON.stringify(payload));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function writeFailure(message) {
|
|
57
|
+
writeResult({ result: 'failure', error: message });
|
|
58
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readStdinJson, runBoardCli, writeFailure, writeResult } from './_board-cli.js';
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
const input = await readStdinJson();
|
|
7
|
+
const boardDir = String(input.BOARD_DIR ?? '').trim();
|
|
8
|
+
const cardsGlob = String(input.CARDS_GLOB ?? '').trim();
|
|
9
|
+
|
|
10
|
+
if (!boardDir || !cardsGlob) {
|
|
11
|
+
writeFailure('BOARD_DIR and CARDS_GLOB are required');
|
|
12
|
+
process.exit(0);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
runBoardCli(['add-cards', '--rg', boardDir, '--card-glob', cardsGlob]);
|
|
16
|
+
|
|
17
|
+
writeResult({
|
|
18
|
+
result: 'success',
|
|
19
|
+
data: {
|
|
20
|
+
board_dir: boardDir,
|
|
21
|
+
cards_glob: cardsGlob,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
} catch (error) {
|
|
25
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
26
|
+
writeFailure(message);
|
|
27
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readStdinJson, runBoardCli, writeFailure, writeResult } from './_board-cli.js';
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
const input = await readStdinJson();
|
|
7
|
+
const boardDir = String(input.BOARD_DIR ?? '').trim();
|
|
8
|
+
|
|
9
|
+
if (!boardDir) {
|
|
10
|
+
writeFailure('BOARD_DIR is required');
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
runBoardCli(['init', boardDir]);
|
|
15
|
+
writeResult({
|
|
16
|
+
result: 'success',
|
|
17
|
+
data: {
|
|
18
|
+
board_dir: boardDir,
|
|
19
|
+
message: `initialized ${boardDir}`,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
} catch (error) {
|
|
23
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
24
|
+
writeFailure(message);
|
|
25
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { readStdinJson, writeFailure, writeResult } from './_board-cli.js';
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
const input = await readStdinJson();
|
|
9
|
+
const boardDirInput = String(input.BOARD_DIR ?? '').trim();
|
|
10
|
+
|
|
11
|
+
if (!boardDirInput) {
|
|
12
|
+
writeFailure('BOARD_DIR is required');
|
|
13
|
+
process.exit(0);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const boardDir = path.resolve(boardDirInput);
|
|
17
|
+
fs.rmSync(boardDir, { recursive: true, force: true });
|
|
18
|
+
|
|
19
|
+
writeResult({
|
|
20
|
+
result: 'success',
|
|
21
|
+
data: {
|
|
22
|
+
board_dir: boardDir,
|
|
23
|
+
reset: true,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
} catch (error) {
|
|
27
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
28
|
+
writeFailure(message);
|
|
29
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readStdinJson, runBoardCli, writeFailure, writeResult } from './_board-cli.js';
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
const input = await readStdinJson();
|
|
7
|
+
const boardDir = String(input.BOARD_DIR ?? '').trim();
|
|
8
|
+
const task = String(input.TASK ?? '').trim();
|
|
9
|
+
|
|
10
|
+
if (!boardDir || !task) {
|
|
11
|
+
writeFailure('BOARD_DIR and TASK are required');
|
|
12
|
+
process.exit(0);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
runBoardCli(['retrigger', '--rg', boardDir, '--task', task]);
|
|
16
|
+
|
|
17
|
+
writeResult({
|
|
18
|
+
result: 'success',
|
|
19
|
+
data: {
|
|
20
|
+
task,
|
|
21
|
+
retriggered: true,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
} catch (error) {
|
|
25
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
26
|
+
writeFailure(message);
|
|
27
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readStdinJson, runBoardCli, writeFailure, writeResult } from './_board-cli.js';
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
const input = await readStdinJson();
|
|
7
|
+
const boardDir = String(input.BOARD_DIR ?? '').trim();
|
|
8
|
+
|
|
9
|
+
if (!boardDir) {
|
|
10
|
+
writeFailure('BOARD_DIR is required');
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const status = runBoardCli(['status', '--rg', boardDir], { capture: true });
|
|
15
|
+
|
|
16
|
+
writeResult({
|
|
17
|
+
result: 'success',
|
|
18
|
+
data: {
|
|
19
|
+
status,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
} catch (error) {
|
|
23
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
24
|
+
writeFailure(message);
|
|
25
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { readStdinJson, runBoardCli, writeFailure, writeResult } from './_board-cli.js';
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
const input = await readStdinJson();
|
|
9
|
+
const boardDir = String(input.BOARD_DIR ?? '').trim();
|
|
10
|
+
const cardsDir = String(input.CARDS_DIR ?? '').trim();
|
|
11
|
+
const holdings = input.HOLDINGS;
|
|
12
|
+
|
|
13
|
+
if (!boardDir || !cardsDir || !Array.isArray(holdings)) {
|
|
14
|
+
writeFailure('BOARD_DIR, CARDS_DIR and HOLDINGS array are required');
|
|
15
|
+
process.exit(0);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const cardPath = path.join(cardsDir, 'portfolio-form.json');
|
|
19
|
+
const raw = fs.readFileSync(cardPath, 'utf-8');
|
|
20
|
+
const card = JSON.parse(raw);
|
|
21
|
+
card.state = card.state ?? {};
|
|
22
|
+
card.state.holdings = holdings;
|
|
23
|
+
fs.writeFileSync(cardPath, `${JSON.stringify(card, null, 2)}\n`, 'utf-8');
|
|
24
|
+
|
|
25
|
+
runBoardCli(['update-card', '--rg', boardDir, '--card-id', 'portfolio-form', '--restart']);
|
|
26
|
+
|
|
27
|
+
writeResult({
|
|
28
|
+
result: 'success',
|
|
29
|
+
data: {
|
|
30
|
+
saved: true,
|
|
31
|
+
holdings_count: holdings.length,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
} catch (error) {
|
|
35
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
+
writeFailure(message);
|
|
37
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readStdinJson, runBoardCli, writeFailure, writeResult } from './_board-cli.js';
|
|
4
|
+
|
|
5
|
+
function sleep(ms) {
|
|
6
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
const input = await readStdinJson();
|
|
11
|
+
const boardDir = String(input.BOARD_DIR ?? '').trim();
|
|
12
|
+
const tasks = Array.isArray(input.COMPLETION_TASKS) ? input.COMPLETION_TASKS : [];
|
|
13
|
+
const label = String(input.LABEL ?? 'WAIT');
|
|
14
|
+
const timeoutMs = Number(input.TIMEOUT_MS ?? 30000);
|
|
15
|
+
const pollMs = Number(input.POLL_MS ?? 500);
|
|
16
|
+
|
|
17
|
+
if (!boardDir || tasks.length === 0) {
|
|
18
|
+
writeFailure('BOARD_DIR and COMPLETION_TASKS are required');
|
|
19
|
+
process.exit(0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const started = Date.now();
|
|
23
|
+
|
|
24
|
+
while (Date.now() - started < timeoutMs) {
|
|
25
|
+
const status = runBoardCli(['status', '--rg', boardDir], { capture: true });
|
|
26
|
+
const complete = tasks.every((task) => new RegExp(`\\bcompleted\\s+${task}\\b`).test(status));
|
|
27
|
+
|
|
28
|
+
if (complete) {
|
|
29
|
+
writeResult({
|
|
30
|
+
result: 'success',
|
|
31
|
+
data: {
|
|
32
|
+
label,
|
|
33
|
+
completed: true,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
await sleep(pollMs);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
writeResult({
|
|
43
|
+
result: 'timeout',
|
|
44
|
+
data: {
|
|
45
|
+
label,
|
|
46
|
+
completed: false,
|
|
47
|
+
error: `${label}: timed out waiting for completion`,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
} catch (error) {
|
|
51
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
52
|
+
writeFailure(message);
|
|
53
|
+
}
|