yaml-flow 5.3.0 → 5.4.2

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.
@@ -79,14 +79,14 @@ function cliCommand() {
79
79
 
80
80
  function runCli(args, capture = false) {
81
81
  const { cmd, prefixArgs } = cliCommand();
82
+ const env = { ...process.env };
83
+ // This demo needs real worker dispatch; suppressing spawn keeps source/inference tasks in running state.
84
+ delete env.BOARD_LIVE_CARDS_NO_SPAWN;
82
85
  const result = spawnSync(cmd, [...prefixArgs, ...args], {
83
86
  stdio: capture ? 'pipe' : 'inherit',
84
87
  shell: false,
85
88
  windowsHide: true,
86
- env: {
87
- ...process.env,
88
- BOARD_LIVE_CARDS_NO_SPAWN: '1',
89
- },
89
+ env,
90
90
  encoding: capture ? 'utf-8' : undefined,
91
91
  });
92
92
 
@@ -113,7 +113,7 @@ function statusText() {
113
113
  return runCli(['status', '--rg', BOARD], true) ?? '';
114
114
  }
115
115
 
116
- async function waitForAllCompleted(label, timeoutMs = 30000, pollMs = 500) {
116
+ async function waitForAllCompleted(label, timeoutMs = 90000, pollMs = 500) {
117
117
  const start = Date.now();
118
118
  const includeInferenceCards = fs.existsSync(path.join(CARDS, 'portfolio-risk-assessment.json'))
119
119
  && fs.existsSync(path.join(CARDS, 'rebalancing-strategy.json'));
@@ -509,11 +509,10 @@ The optional `projections` map lets a source definition declare which upstream d
509
509
  "outputFile": "quotes.json",
510
510
  "projections": {
511
511
  "holdings": "requires.holdings",
512
- "topHoldings": "requires.holdings[weight > 0.05]",
513
- "threshold": "card_data.threshold"
512
+ "url_list": "requires.holdings.ticker.('https://query1.finance.yahoo.com/v8/finance/chart/' & $ & '?interval=1d&range=1d')"
514
513
  },
515
- "chartApi": {
516
- "tickersFrom": "holdings.ticker"
514
+ "url-list": {
515
+ "cacheTimeout": 3600
517
516
  }
518
517
  }
519
518
  ]
@@ -538,7 +537,7 @@ node board-live-cards-cli.js describe-task-executor-capabilities --rg <boardDir>
538
537
  ```
539
538
 
540
539
  This invokes the executor's `describe-capabilities` subcommand and prints its capabilities JSON to stdout. The output includes:
541
- - **`sourceKinds`** — every source kind the executor handles (e.g. `mock`, `copilot`, `http`, `chartApi`), each with:
540
+ - **`sourceKinds`** — every source kind the executor handles (e.g. `mock`, `copilot`, `workiq`, `url`, `url-list`), each with:
542
541
  - `description` — what the kind does
543
542
  - `inputSchema` — the exact `customFields` the executor expects on the source entry
544
543
  - `outputShape` — the shape of the JSON written to `--out`
@@ -126,13 +126,45 @@ function jsonReply(res, status, payload) {
126
126
  res.end(body);
127
127
  }
128
128
 
129
+ // ---------------------------------------------------------------------------
130
+ // Card preparation — host-level concern, not a reusable runtime concern.
131
+ // Writes the concatenated copilot-instructions.md at the board setup root.
132
+ // Cards are served directly from cardsDir (no tmp copy needed).
133
+ // ---------------------------------------------------------------------------
134
+
135
+ const _demoPrepSetupDone = new Map(); // boardId → true
136
+
137
+ function isDemoSetupDone(boardId, service) {
138
+ return _demoPrepSetupDone.get(boardId) === true && fs.existsSync(service.cardsDir);
139
+ }
140
+
141
+ function demoPrepSetup(boardId, service) {
142
+ const { cardsDir, gandalfCardsDir, boardDir } = service;
143
+
144
+ // Concatenate agent-instructions*.md into copilot-instructions.md at boardSetupRoot.
145
+ const boardSetupRoot = path.dirname(boardDir);
146
+ fs.mkdirSync(boardSetupRoot, { recursive: true });
147
+ const srcDir = path.dirname(cardsDir);
148
+ const agentInstructionFiles = ['agent-instructions.md', 'agent-instructions-cardlayout.md'];
149
+ const parts = [];
150
+ for (const fname of agentInstructionFiles) {
151
+ const fpath = path.join(srcDir, fname);
152
+ if (fs.existsSync(fpath)) parts.push(fs.readFileSync(fpath, 'utf-8').trimEnd());
153
+ }
154
+ if (parts.length > 0) {
155
+ fs.writeFileSync(path.join(boardSetupRoot, 'copilot-instructions.md'), parts.join('\n\n') + '\n', 'utf-8');
156
+ }
157
+
158
+ _demoPrepSetupDone.set(boardId, true);
159
+ }
160
+
129
161
  async function handleDemoSetup(req, res, boardId) {
130
162
  try {
131
- const { service, boardRoot } = runtime.requireBoardService(boardId);
163
+ const { service } = runtime.requireBoardService(boardId);
132
164
  let setupPerformed = false;
133
165
 
134
- if (!service.isDemoSetupDone()) {
135
- service.ensureDemoSetup();
166
+ if (!isDemoSetupDone(boardId, service)) {
167
+ demoPrepSetup(boardId, service);
136
168
  setupPerformed = true;
137
169
  }
138
170
 
@@ -6,9 +6,9 @@
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.3.0/browser/card-compute.js"></script>
10
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/live-cards.js"></script>
11
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/board-livegraph-engine.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.2/browser/card-compute.js"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.2/browser/live-cards.js"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.2/browser/board-livegraph-engine.js"></script>
12
12
  </head>
13
13
  <body class="bg-light">
14
14
  <div class="container-fluid py-3">
@@ -378,7 +378,7 @@
378
378
 
379
379
  return {
380
380
  fetchSource: async function (card, sourceDef) {
381
- // chartApi source with mock="quotes" → return mock quote data
381
+ // mock source with mock="quotes" → return mock quote data
382
382
  if (sourceDef && sourceDef.mock === 'quotes') return clone(quoteData);
383
383
  // copilot source → return mock analysis object
384
384
  if (sourceDef && sourceDef.copilot) return clone(mockAnalysis);
@@ -16,10 +16,10 @@
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.3.0/browser/card-compute.js"></script>
20
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/live-cards.js"></script>
21
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/board-livegraph-engine.js"></script>
22
- <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.3.0/browser/board-livecards-runtime-client.js"></script>
19
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.2/browser/card-compute.js"></script>
20
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.2/browser/live-cards.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.2/browser/board-livegraph-engine.js"></script>
22
+ <script src="https://cdn.jsdelivr.net/npm/yaml-flow@5.4.2/browser/board-livecards-runtime-client.js"></script>
23
23
  </head>
24
24
  <body class="bg-light">
25
25
  <div class="container-fluid py-3">
@@ -192,11 +192,14 @@
192
192
  document.getElementById('boardTitle').textContent = bid + ' (Server Runtime)';
193
193
  document.getElementById('boardDesc').textContent = '';
194
194
 
195
+ // Demo-setup is a host-level concern; call it explicitly before bootstrapping.
196
+ const setupRes = await fetch(boardPaths(bid).demoSetup);
197
+ if (!setupRes.ok) throw new Error(`demo-setup failed (${setupRes.status})`);
198
+
195
199
  await runtimeClient.bootstrapBoard({
196
200
  boardId: bid,
197
201
  taskExecutorPath: resolveTaskExecutorPathParam(),
198
202
  rootElement: document.getElementById('boardRoot'),
199
- runDemoSetup: true,
200
203
  mode: currentMode,
201
204
  });
202
205
 
@@ -45,8 +45,7 @@
45
45
  * - { "url-list": { method?, headers?, cacheTimeout? } }
46
46
  * → fan-out over _projections.url_list (string[]); returns array of responses.
47
47
  * Build url_list in projections: e.g. `requires.holdings.ticker.('https://host/' & $ & '?q=1')`
48
- * - { chartApi: { url, headers? }, tickersFrom } → removed; use url-list instead
49
- * prefer url-list for new sources
48
+ * Prefer url-list for multi-URL fan-out sources.
50
49
  * A real executor can also handle: graphapi, teams, mail, incidentdb, script, etc.
51
50
  *
52
51
  * url / url-list notes:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yaml-flow",
3
- "version": "5.3.0",
3
+ "version": "5.4.2",
4
4
  "description": "Unified workflow engine: step-machine (sequential) + event-graph (stateless DAG) with pluggable storage",
5
5
  "author": "",
6
6
  "license": "MIT",