yaml-flow 8.5.3 → 8.6.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.
Files changed (176) hide show
  1. package/browser/asset-integrity.json +3 -3
  2. package/examples/board/demo-shell-with-server.html +2 -2
  3. package/examples/board/doc.html +2 -2
  4. package/examples/board/server/board-server.js +773 -13
  5. package/examples/board/server/board-worker/task-executor.js +166 -51
  6. package/examples/board/server/chat-flow/copilot-chat/assistant.js +25 -12
  7. package/examples/board/server/chat-flow/copilot-chat/probe.js +7 -0
  8. package/examples/board/server/chat-flow/copilot-chat/shared.js +97 -0
  9. package/examples/board/server/chat-flow/flow-steps.json +109 -51
  10. package/examples/board/server-config.json +2 -0
  11. package/examples/board/test/server-http-test.js +878 -67
  12. package/examples/board-local/demo-shell-localstorage.html +3 -3
  13. package/lib/{artifacts-store-lib-CVgtQrNZ.d.cts → artifacts-store-lib-BR-Samty.d.cts} +1 -1
  14. package/lib/{artifacts-store-lib-D-k-E8Vy.d.ts → artifacts-store-lib-DT7XlWUL.d.ts} +1 -1
  15. package/lib/artifacts-store-public.cjs +1 -1
  16. package/lib/artifacts-store-public.d.cts +3 -3
  17. package/lib/artifacts-store-public.d.ts +3 -3
  18. package/lib/artifacts-store-public.js +1 -1
  19. package/lib/batch/index.cjs +1 -1
  20. package/lib/batch/index.js +1 -1
  21. package/lib/board-live-cards-mcp.cjs +1 -1
  22. package/lib/board-live-cards-mcp.d.cts +87 -34
  23. package/lib/board-live-cards-mcp.d.ts +87 -34
  24. package/lib/board-live-cards-mcp.js +1 -1
  25. package/lib/board-live-cards-node.cjs +8 -16
  26. package/lib/board-live-cards-node.d.cts +52 -14
  27. package/lib/board-live-cards-node.d.ts +52 -14
  28. package/lib/board-live-cards-node.js +8 -16
  29. package/lib/{board-live-cards-public-BGS22cMb.d.ts → board-live-cards-public-BMUIPOrc.d.ts} +90 -30
  30. package/lib/board-live-cards-public-async-DKZqbJVU.d.ts +256 -0
  31. package/lib/board-live-cards-public-async-dMWNbWq6.d.cts +256 -0
  32. package/lib/{board-live-cards-public-B13InXhC.d.cts → board-live-cards-public-wkNmBIRC.d.cts} +90 -30
  33. package/lib/board-live-cards-public.cjs +1 -2
  34. package/lib/board-live-cards-public.d.cts +2 -2
  35. package/lib/board-live-cards-public.d.ts +2 -2
  36. package/lib/board-live-cards-public.js +1 -2
  37. package/lib/board-live-cards-server-runtime.cjs +1 -7
  38. package/lib/board-live-cards-server-runtime.d.cts +7 -6
  39. package/lib/board-live-cards-server-runtime.d.ts +7 -6
  40. package/lib/board-live-cards-server-runtime.js +1 -7
  41. package/lib/board-livegraph-runtime/index.cjs +1 -2
  42. package/lib/board-livegraph-runtime/index.js +1 -2
  43. package/lib/board-worker-adapter.cjs +22 -7
  44. package/lib/board-worker-adapter.d.cts +28 -3
  45. package/lib/board-worker-adapter.d.ts +28 -3
  46. package/lib/board-worker-adapter.js +22 -7
  47. package/lib/card-compute/index.cjs +1 -9
  48. package/lib/card-compute/index.js +1 -9
  49. package/lib/card-store-public.cjs +1 -1
  50. package/lib/card-store-public.d.cts +2 -2
  51. package/lib/card-store-public.d.ts +2 -2
  52. package/lib/card-store-public.js +1 -1
  53. package/lib/card-validation.cjs +1 -9
  54. package/lib/card-validation.js +1 -9
  55. package/lib/{chat-storage-lib-0imhRX3l.d.cts → chat-storage-lib-BIUbE-fM.d.cts} +1 -1
  56. package/lib/{chat-storage-lib-CJn7a6OH.d.ts → chat-storage-lib-BlG-sobS.d.ts} +1 -1
  57. package/lib/chat-store-public.cjs +1 -1
  58. package/lib/chat-store-public.d.cts +3 -3
  59. package/lib/chat-store-public.d.ts +3 -3
  60. package/lib/chat-store-public.js +1 -1
  61. package/lib/chunk-2MZUYY65.cjs +2 -0
  62. package/lib/chunk-5EA2ESS4.cjs +16 -0
  63. package/lib/chunk-76ON3V7R.js +2 -0
  64. package/lib/chunk-7BKNHFNH.js +2 -0
  65. package/lib/chunk-BQS3EIEK.js +3 -0
  66. package/lib/chunk-CIAJNUR4.js +2 -0
  67. package/lib/chunk-DAXACY63.js +2 -0
  68. package/lib/chunk-FW4363Y4.js +2 -0
  69. package/lib/chunk-FZ2SBU5M.js +3 -0
  70. package/lib/chunk-G4XXRHL2.cjs +3 -0
  71. package/lib/chunk-GJJMEAVN.cjs +2 -0
  72. package/lib/chunk-GNFE24S7.cjs +2 -0
  73. package/lib/chunk-GYQXDNNI.cjs +2 -0
  74. package/lib/chunk-H5HBXPOI.cjs +3 -0
  75. package/lib/chunk-H5KD3JPY.cjs +2 -0
  76. package/lib/chunk-HEEDJEKM.js +2 -0
  77. package/lib/chunk-HLJH7LGW.js +16 -0
  78. package/lib/chunk-IXZG74EW.cjs +2 -0
  79. package/lib/chunk-JAL25FGA.cjs +2 -0
  80. package/lib/chunk-JM5EKT57.js +2 -0
  81. package/lib/chunk-JMDHDY6M.js +2 -0
  82. package/lib/chunk-KBELAKIY.js +2 -0
  83. package/lib/chunk-KHJABJ45.cjs +3 -0
  84. package/lib/chunk-KLRUISRY.cjs +2 -0
  85. package/lib/chunk-KQX6R4PV.cjs +8 -0
  86. package/lib/chunk-LODXIALE.cjs +2 -0
  87. package/lib/chunk-MLVTJASJ.js +2 -0
  88. package/lib/chunk-MNEOJWPS.js +10 -0
  89. package/lib/chunk-N6P2JW4W.js +3 -0
  90. package/lib/chunk-NMZ6XNLB.cjs +3 -0
  91. package/lib/chunk-OEFTOO47.cjs +3 -0
  92. package/lib/chunk-OPNGCSXJ.js +2 -0
  93. package/lib/chunk-OSWJKJLB.js +8 -0
  94. package/lib/chunk-P7ZCDICS.cjs +2 -0
  95. package/lib/chunk-PBCDDO4V.cjs +2 -0
  96. package/lib/chunk-PMUSJQSR.cjs +2 -0
  97. package/lib/chunk-Q6H7NINN.cjs +5 -0
  98. package/lib/chunk-QWBNDVUA.js +5 -0
  99. package/lib/chunk-S6DRP2HX.cjs +2 -0
  100. package/lib/chunk-SCWHDI3I.js +2 -0
  101. package/lib/chunk-SFVO2LB2.cjs +3 -0
  102. package/lib/chunk-U2N6MCD5.cjs +2 -0
  103. package/lib/chunk-UJ7ZTV4J.cjs +10 -0
  104. package/lib/chunk-VGT3TRQG.js +3 -0
  105. package/lib/chunk-VLBB3D6B.js +3 -0
  106. package/lib/chunk-VMW4Z6EF.js +3 -0
  107. package/lib/chunk-WDPOGXTY.js +2 -0
  108. package/lib/chunk-WOALA3V5.cjs +2 -0
  109. package/lib/chunk-X3LC4LII.js +2 -0
  110. package/lib/chunk-XQRNDX4Q.js +2 -0
  111. package/lib/chunk-YGKDQLYP.js +2 -0
  112. package/lib/chunk-YMEIPKLW.cjs +2 -0
  113. package/lib/cloud-storage.cjs +2 -0
  114. package/lib/cloud-storage.d.cts +177 -0
  115. package/lib/cloud-storage.d.ts +177 -0
  116. package/lib/cloud-storage.js +2 -0
  117. package/lib/config/index.cjs +1 -1
  118. package/lib/config/index.js +1 -1
  119. package/lib/continuous-event-graph/index.cjs +1 -2
  120. package/lib/continuous-event-graph/index.js +1 -2
  121. package/lib/event-graph/index.cjs +1 -22
  122. package/lib/event-graph/index.js +1 -22
  123. package/lib/execution-refs.cjs +1 -2
  124. package/lib/execution-refs.d.cts +3 -2
  125. package/lib/execution-refs.d.ts +3 -2
  126. package/lib/execution-refs.js +1 -2
  127. package/lib/index.cjs +2 -24
  128. package/lib/index.d.cts +1 -1
  129. package/lib/index.d.ts +1 -1
  130. package/lib/index.js +2 -24
  131. package/lib/{types-CIgsh56O.d.cts → queue-lane-registry-BPKWWgd4.d.cts} +66 -14
  132. package/lib/{types-30R357js.d.ts → queue-lane-registry-Be6c0ftj.d.ts} +66 -14
  133. package/lib/server-runtime/index.cjs +1 -7
  134. package/lib/server-runtime/index.d.cts +18 -7
  135. package/lib/server-runtime/index.d.ts +18 -7
  136. package/lib/server-runtime/index.js +1 -7
  137. package/lib/step-machine/index.cjs +1 -11
  138. package/lib/step-machine/index.js +1 -11
  139. package/lib/step-machine-public/index.cjs +1 -4
  140. package/lib/step-machine-public/index.d.cts +1 -1
  141. package/lib/step-machine-public/index.d.ts +1 -1
  142. package/lib/step-machine-public/index.js +1 -4
  143. package/lib/{storage-interface-B2WD9D5n.d.cts → storage-interface-BFiD3kyB.d.cts} +38 -1
  144. package/lib/{storage-interface-B2WD9D5n.d.ts → storage-interface-BFiD3kyB.d.ts} +38 -1
  145. package/lib/stores/index.cjs +1 -2
  146. package/lib/stores/index.d.cts +1 -1
  147. package/lib/stores/index.d.ts +1 -1
  148. package/lib/stores/index.js +1 -2
  149. package/lib/stores/kv.cjs +1 -2
  150. package/lib/stores/kv.d.cts +1 -1
  151. package/lib/stores/kv.d.ts +1 -1
  152. package/lib/stores/kv.js +1 -2
  153. package/lib/stores/memory.cjs +1 -1
  154. package/lib/stores/memory.js +1 -1
  155. package/package.json +7 -16
  156. package/cli/board-live-cards-lib-COi4bSpk.d.ts +0 -322
  157. package/cli/browser-api/board-live-cards-browser-adapter.d.ts +0 -36
  158. package/cli/browser-api/board-live-cards-browser-adapter.js +0 -4
  159. package/cli/browser-api/card-store-browser-api.d.ts +0 -25
  160. package/cli/browser-api/card-store-browser-api.js +0 -2
  161. package/cli/browser-api/jsonata-sync.cjs +0 -7623
  162. package/cli/bundled/artifacts-store-cli.mjs +0 -12
  163. package/cli/bundled/batch-runner-cli.mjs +0 -3
  164. package/cli/bundled/board-live-cards-cli.mjs +0 -29
  165. package/cli/bundled/card-store-cli.mjs +0 -154
  166. package/cli/bundled/chat-store-cli.mjs +0 -16
  167. package/cli/bundled/jsonata-sync.cjs +0 -7623
  168. package/cli/bundled/step-machine-cli.mjs +0 -150
  169. package/cli/execution-interface-BCIhu1gO.d.ts +0 -442
  170. package/cli/types-H3EMBPY2.d.ts +0 -398
  171. package/examples/board/server/README-mcp-api.md +0 -690
  172. package/examples/board/test/server-http-mcp-test.js +0 -1280
  173. package/lib/board-livegraph-runtime/jsonata-sync.cjs +0 -7623
  174. package/lib/card-compute/jsonata-sync.cjs +0 -7623
  175. package/lib/continuous-event-graph/jsonata-sync.cjs +0 -7623
  176. package/lib/server-runtime/jsonata-sync.cjs +0 -7623
@@ -283,6 +283,60 @@ async function runSourceFetchSubcommand(argv) {
283
283
 
284
284
  }
285
285
 
286
+ async function executeLogicalSourceFetchRequest(request) {
287
+ const sourceDef = request?.source_def;
288
+ const callback = request?.callback;
289
+ const outputRefStr = typeof request?.output?.ref === 'string' ? request.output.ref : undefined;
290
+ const diagnosticsRefStr = typeof request?.diagnostics?.ref === 'string' ? request.diagnostics.ref : undefined;
291
+ const extra = request?.extra && typeof request.extra === 'object' && !Array.isArray(request.extra) ? request.extra : {};
292
+
293
+ if (!sourceDef || typeof sourceDef !== 'object' || Array.isArray(sourceDef)) {
294
+ throw new Error('executeBoardWorkerRequest requires source_def');
295
+ }
296
+ if (!outputRefStr) {
297
+ throw new Error('executeBoardWorkerRequest requires output.ref');
298
+ }
299
+
300
+ const outRef = parseRef(outputRefStr);
301
+ const errRef = diagnosticsRefStr ? parseRef(diagnosticsRefStr) : undefined;
302
+ const outStorage = blobStorageForRef(outRef);
303
+ const errStorage = errRef ? blobStorageForRef(errRef) : undefined;
304
+
305
+ const reportHostedFailure = (msg) => {
306
+ if (errStorage && errRef) { try { errStorage.write(errRef.value, msg); } catch {} }
307
+ console.error(`${LOG_PREFIX} ${msg}`);
308
+ if (callback) { try { reportFailed(callback, msg); } catch {} }
309
+ };
310
+
311
+ let flowResult;
312
+ try {
313
+ const resolved = await resolveAndExecuteSourceFlow(sourceDef, extra, { outRef, errRef });
314
+ flowResult = resolved.flowResult;
315
+ } catch (err) {
316
+ const detail = (err && (err.stderr || err.stdout)) ? `\n${err.stderr || err.stdout}`.trimEnd() : '';
317
+ reportHostedFailure(`source invocation failed: ${String(err && err.message || err)}${detail}`);
318
+ return;
319
+ }
320
+
321
+ if (!flowResult?.wroteOutputDirectly) {
322
+ try {
323
+ outStorage.write(outRef.value, JSON.stringify(flowResult?.resultValue, null, 2));
324
+ } catch (err) {
325
+ const msg = `Cannot write output: ${String(err && err.message || err)}`;
326
+ reportHostedFailure(msg);
327
+ throw new Error(msg);
328
+ }
329
+ }
330
+
331
+ if (callback) {
332
+ try {
333
+ reportComplete(callback, outRef);
334
+ } catch (err) {
335
+ throw new Error(`reportComplete failed: ${String(err && err.message || err)}`);
336
+ }
337
+ }
338
+ }
339
+
286
340
  async function probeSourcePreflightSubcommand(argv) {
287
341
  const extraIdx = argv.indexOf('--extra');
288
342
  const extraB64 = extraIdx !== -1 ? argv[extraIdx + 1] : undefined;
@@ -293,24 +347,27 @@ async function probeSourcePreflightSubcommand(argv) {
293
347
  catch { /* ignore malformed extra */ }
294
348
  }
295
349
 
350
+ const chunks = [];
351
+ for await (const chunk of process.stdin) {
352
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
353
+ }
354
+ const result = await probeSourcePreflightRequest(Buffer.concat(chunks).toString('utf-8').trim(), extra);
355
+ console.log(JSON.stringify(result));
356
+ }
357
+
358
+ async function probeSourcePreflightRequest(raw, extra = {}) {
359
+
296
360
  const startedAt = Date.now();
297
361
  try {
298
- const chunks = [];
299
- for await (const chunk of process.stdin) {
300
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
301
- }
302
- const raw = Buffer.concat(chunks).toString('utf-8').trim();
303
362
  if (!raw) {
304
- console.log(JSON.stringify({ ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: 'Missing probe input JSON on stdin' }));
305
- return;
363
+ return { ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: 'Missing probe input JSON on stdin' };
306
364
  }
307
365
 
308
366
  let sourceDef;
309
367
  try {
310
368
  sourceDef = JSON.parse(raw);
311
369
  } catch (err) {
312
- console.log(JSON.stringify({ ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: `Invalid probe JSON: ${String(err && err.message || err)}` }));
313
- return;
370
+ return { ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: `Invalid probe JSON: ${String(err && err.message || err)}` };
314
371
  }
315
372
 
316
373
  const projections = sourceDef?._projections;
@@ -320,18 +377,16 @@ async function probeSourcePreflightSubcommand(argv) {
320
377
  : undefined;
321
378
 
322
379
  const { flowResult } = await resolveAndExecuteSourceFlow(sourceDef, extra);
323
- console.log(JSON.stringify({
380
+ return {
324
381
  ok: true,
325
382
  reachable: true,
326
383
  latencyMs: Date.now() - startedAt,
327
384
  ...(mockProjectionWarning ? { note: mockProjectionWarning } : {}),
328
385
  ...(!mockProjectionWarning ? { resultValue: flowResult?.resultValue } : {}),
329
- }));
330
- return;
386
+ };
331
387
  } catch (err) {
332
388
  const detail = (err && (err.stderr || err.stdout)) ? `\n${err.stderr || err.stdout}`.trimEnd() : '';
333
- console.log(JSON.stringify({ ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: `source invocation failed: ${String(err && err.message || err)}${detail}` }));
334
- return;
389
+ return { ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: `source invocation failed: ${String(err && err.message || err)}${detail}` };
335
390
  }
336
391
  }
337
392
 
@@ -364,26 +419,29 @@ async function runSourcePreflightSubcommand(argv) {
364
419
  catch { /* ignore malformed extra */ }
365
420
  }
366
421
 
422
+ const chunks = [];
423
+ for await (const chunk of process.stdin) {
424
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
425
+ }
426
+ const result = await runSourcePreflightRequest(Buffer.concat(chunks).toString('utf-8').trim(), extra);
427
+ console.log(JSON.stringify(result));
428
+ }
429
+
430
+ async function runSourcePreflightRequest(raw, extra = {}) {
431
+
367
432
  const startedAt = Date.now();
368
433
  let bindTo;
369
434
  let kind;
370
435
  try {
371
- const chunks = [];
372
- for await (const chunk of process.stdin) {
373
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
374
- }
375
- const raw = Buffer.concat(chunks).toString('utf-8').trim();
376
436
  if (!raw) {
377
- console.log(JSON.stringify({ ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: 'Missing run-source-preflight input JSON on stdin' }));
378
- return;
437
+ return { ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: 'Missing run-source-preflight input JSON on stdin' };
379
438
  }
380
439
 
381
440
  let sourceDef;
382
441
  try {
383
442
  sourceDef = JSON.parse(raw);
384
443
  } catch (err) {
385
- console.log(JSON.stringify({ ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: `Invalid run-source-preflight JSON: ${String(err && err.message || err)}` }));
386
- return;
444
+ return { ok: false, reachable: false, latencyMs: Date.now() - startedAt, error: `Invalid run-source-preflight JSON: ${String(err && err.message || err)}` };
387
445
  }
388
446
 
389
447
  bindTo = typeof sourceDef?.bindTo === 'string' ? sourceDef.bindTo : undefined;
@@ -391,7 +449,7 @@ async function runSourcePreflightSubcommand(argv) {
391
449
 
392
450
  const resolved = await resolveAndExecuteSourceFlow(sourceDef, extra);
393
451
  kind = resolved.kind;
394
- console.log(JSON.stringify({
452
+ return {
395
453
  ok: true,
396
454
  reachable: true,
397
455
  latencyMs: Date.now() - startedAt,
@@ -399,19 +457,17 @@ async function runSourcePreflightSubcommand(argv) {
399
457
  ...(kind ? { kind } : {}),
400
458
  resultValue: resolved.flowResult?.resultValue,
401
459
  note: 'Actual fetch preflight passed',
402
- }));
403
- return;
460
+ };
404
461
  } catch (err) {
405
462
  const detail = (err && (err.stderr || err.stdout)) ? `\n${err.stderr || err.stdout}`.trimEnd() : '';
406
- console.log(JSON.stringify({
463
+ return {
407
464
  ok: false,
408
465
  reachable: false,
409
466
  latencyMs: Date.now() - startedAt,
410
467
  ...(bindTo ? { bindTo } : {}),
411
468
  ...(kind ? { kind } : {}),
412
469
  error: `${String(err && err.message || err)}${detail}`,
413
- }));
414
- return;
470
+ };
415
471
  }
416
472
  }
417
473
 
@@ -455,26 +511,16 @@ function matchesValidateRule(sourceDef, rule) {
455
511
  // ---------------------------------------------------------------------------
456
512
  // validate-source-def — registry-driven validation of a source definition
457
513
  // ---------------------------------------------------------------------------
458
- function validateSourceDefSubcommand() {
459
- let rawInput = '';
460
- try {
461
- rawInput = fs.readFileSync(0, 'utf-8').trim();
462
- } catch (err) {
463
- console.log(JSON.stringify({ ok: false, errors: [`Cannot read stdin: ${err && err.message || err}`] }));
464
- process.exit(1);
465
- }
466
-
514
+ function validateSourceDefPayload(rawInput) {
467
515
  if (!rawInput) {
468
- console.error(`${LOG_PREFIX} Usage: validate-source-def < source.json`);
469
- process.exit(1);
516
+ return { ok: false, errors: ['Missing source JSON on stdin'] };
470
517
  }
471
518
 
472
519
  let sourceDef;
473
520
  try {
474
521
  sourceDef = JSON.parse(rawInput);
475
522
  } catch (err) {
476
- console.log(JSON.stringify({ ok: false, errors: [`Cannot parse source JSON from stdin: ${err && err.message || err}`] }));
477
- process.exit(1);
523
+ return { ok: false, errors: [`Cannot parse source JSON from stdin: ${err && err.message || err}`] };
478
524
  }
479
525
 
480
526
  const errors = [];
@@ -500,12 +546,23 @@ function validateSourceDefSubcommand() {
500
546
  }
501
547
  }
502
548
 
503
- const result = { ok: errors.length === 0, errors };
549
+ return { ok: errors.length === 0, errors };
550
+ }
551
+
552
+ function validateSourceDefSubcommand() {
553
+ let rawInput = '';
554
+ try {
555
+ rawInput = fs.readFileSync(0, 'utf-8').trim();
556
+ } catch (err) {
557
+ console.log(JSON.stringify({ ok: false, errors: [`Cannot read stdin: ${err && err.message || err}`] }));
558
+ process.exit(1);
559
+ }
560
+ const result = validateSourceDefPayload(rawInput);
504
561
  console.log(JSON.stringify(result));
505
- process.exit(errors.length === 0 ? 0 : 1);
562
+ process.exit(result.ok ? 0 : 1);
506
563
  }
507
564
 
508
- function describeCapabilities() {
565
+ function describeCapabilitiesPayload() {
509
566
  const registry = loadSourceDefFlowsConfig();
510
567
  const sourceKinds = Object.fromEntries(
511
568
  Object.entries(registry?.kinds || {}).map(([kind, spec]) => [
@@ -516,7 +573,7 @@ function describeCapabilities() {
516
573
  },
517
574
  ]),
518
575
  );
519
- const payload = {
576
+ return {
520
577
  version: registry?.version || '1.0',
521
578
  executor: registry?.executor || EXECUTOR_NAME,
522
579
  subcommands: Array.isArray(registry?.subcommands)
@@ -525,7 +582,63 @@ function describeCapabilities() {
525
582
  sourceKinds,
526
583
  ...(registry?.extraSchema ? { extraSchema: registry.extraSchema } : {}),
527
584
  };
528
- console.log(JSON.stringify(payload, null, 2));
585
+ }
586
+
587
+ function describeCapabilities() {
588
+ console.log(JSON.stringify(describeCapabilitiesPayload(), null, 2));
589
+ }
590
+
591
+ function buildTaskExecutorArgvFromRequest(request) {
592
+ const subcommand = typeof request?.subcommand === 'string' ? request.subcommand.trim() : '';
593
+ if (!subcommand) {
594
+ throw new Error('executeTaskExecutorRequest requires subcommand');
595
+ }
596
+
597
+ const argv = [];
598
+ if (typeof request?.inRef === 'string' && request.inRef.trim()) argv.push('--in-ref', request.inRef.trim());
599
+ if (typeof request?.outRef === 'string' && request.outRef.trim()) argv.push('--out-ref', request.outRef.trim());
600
+ if (typeof request?.errRef === 'string' && request.errRef.trim()) argv.push('--err-ref', request.errRef.trim());
601
+ if (request?.extra && typeof request.extra === 'object' && !Array.isArray(request.extra)) {
602
+ argv.push('--extra', Buffer.from(JSON.stringify(request.extra)).toString('base64'));
603
+ }
604
+ return { subcommand, argv };
605
+ }
606
+
607
+ export async function executeBoardWorkerRequest(request) {
608
+ if (request?.source_def) {
609
+ await executeLogicalSourceFetchRequest(request);
610
+ return { ok: true };
611
+ }
612
+ const { subcommand, argv } = buildTaskExecutorArgvFromRequest(request);
613
+ const inlineInput = typeof request?.input === 'string'
614
+ ? request.input
615
+ : request?.input !== undefined
616
+ ? JSON.stringify(request.input)
617
+ : '';
618
+ const inlineExtra = request?.extra && typeof request.extra === 'object' && !Array.isArray(request.extra) ? request.extra : {};
619
+
620
+ if (subcommand === 'run-source-fetch') {
621
+ await runSourceFetchSubcommand(argv);
622
+ return { ok: true };
623
+ }
624
+ if (subcommand === 'probe-source-preflight') {
625
+ return await probeSourcePreflightRequest(inlineInput, inlineExtra);
626
+ }
627
+ if (subcommand === 'run-source-preflight') {
628
+ return await runSourcePreflightRequest(inlineInput, inlineExtra);
629
+ }
630
+ if (subcommand === 'describe' || subcommand === 'describe-capabilities') {
631
+ return describeCapabilitiesPayload();
632
+ }
633
+ if (subcommand === 'validate-source-def') {
634
+ return validateSourceDefPayload(inlineInput);
635
+ }
636
+
637
+ throw new Error(`Unknown subcommand: ${subcommand}`);
638
+ }
639
+
640
+ export async function executeTaskExecutorRequest(request) {
641
+ return executeBoardWorkerRequest(request);
529
642
  }
530
643
 
531
644
  async function main() {
@@ -555,7 +668,9 @@ async function main() {
555
668
  process.exit(0);
556
669
  }
557
670
 
558
- main().catch(err => {
559
- console.error(`${LOG_PREFIX} fatal: ${err && err.message || err}`);
560
- process.exit(1);
561
- });
671
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
672
+ main().catch(err => {
673
+ console.error(`${LOG_PREFIX} fatal: ${err && err.message || err}`);
674
+ process.exit(1);
675
+ });
676
+ }
@@ -5,23 +5,24 @@ import * as path from 'node:path';
5
5
  import * as os from 'node:os';
6
6
  import { execFileSync } from 'node:child_process';
7
7
  import { fileURLToPath } from 'node:url';
8
+ import { readJsonStdin } from './shared.js';
8
9
 
9
10
  const HANDLER_DIR = path.dirname(fileURLToPath(import.meta.url));
10
11
  const WRAPPER_BAT = path.join(HANDLER_DIR, 'copilot_wrapper.bat');
12
+ const DBG_LOG = path.join(HANDLER_DIR, 'assistant-debug.log');
13
+ const DBG_ENABLED = String(process.env.YAML_FLOW_CHAT_DEBUG || '').toLowerCase() === 'true';
11
14
 
12
- function readJsonStdin() {
13
- if (process.stdin.isTTY) return {};
14
- try {
15
- const raw = fs.readFileSync(0, 'utf-8').trim();
16
- if (!raw) return {};
17
- const parsed = JSON.parse(raw);
18
- return parsed && typeof parsed === 'object' ? parsed : {};
19
- } catch {
20
- return {};
21
- }
22
- }
15
+ const dbg = DBG_ENABLED
16
+ ? (msg) => {
17
+ try {
18
+ fs.appendFileSync(DBG_LOG, `[assistant.DBG ${new Date().toISOString()} pid=${process.pid}] ${msg}\n`);
19
+ } catch {}
20
+ }
21
+ : () => {};
23
22
 
23
+ dbg('startup: reading JSON stdin');
24
24
  const extra = readJsonStdin();
25
+ dbg(`startup: stdin parsed (keys=${Object.keys(extra || {}).join(',')})`);
25
26
  const {
26
27
  cardId = '',
27
28
  boardSetupRoot = '',
@@ -74,8 +75,10 @@ function runCopilot(prompt, workingDir) {
74
75
  const ts = Date.now();
75
76
  const promptFile = path.join(os.tmpdir(), `asst-prompt-${ts}.txt`);
76
77
  const outFile = path.join(os.tmpdir(), `asst-out-${ts}.txt`);
78
+ dbg(`runCopilot: writing prompt (${prompt.length} chars) to ${promptFile}`);
77
79
  fs.writeFileSync(promptFile, prompt, 'utf-8');
78
80
  try {
81
+ dbg(`runCopilot: spawning wrapper ${WRAPPER_BAT} (timeout=${chatCopilotTimeoutMs}ms, cwd=${workingDir || process.cwd()})`);
79
82
  execFileSync('cmd.exe', [
80
83
  '/d', '/c', WRAPPER_BAT,
81
84
  outFile,
@@ -91,7 +94,11 @@ function runCopilot(prompt, workingDir) {
91
94
  timeout: chatCopilotTimeoutMs,
92
95
  windowsHide: true,
93
96
  });
94
- return fs.existsSync(outFile) ? fs.readFileSync(outFile, 'utf-8').trim() : '';
97
+ const hasOut = fs.existsSync(outFile);
98
+ const out = hasOut ? fs.readFileSync(outFile, 'utf-8').trim() : '';
99
+ dbg(`runCopilot: wrapper returned (outFileExists=${hasOut}, replyLen=${out.length})`);
100
+ dbg(`runCopilot: reply snippet: ${JSON.stringify(out.slice(0, 400))}`);
101
+ return out;
95
102
  } finally {
96
103
  try { fs.unlinkSync(promptFile); } catch {}
97
104
  try { fs.unlinkSync(outFile); } catch {}
@@ -100,15 +107,21 @@ function runCopilot(prompt, workingDir) {
100
107
 
101
108
  const historyDump = JSON.stringify(chatMessages, null, 2);
102
109
  const workingDir = boardSetupRoot;
110
+ dbg(`main: cardId=${cardId} turnId=${turnId} userTextLen=${String(userText).length} history=${chatMessages.length} workingDir=${workingDir}`);
103
111
  const prompt = buildPrompt(cardId, historyDump, userText.trim(), String(turnId || '').trim());
112
+ dbg(`main: prompt built (${prompt.length} chars)`);
104
113
 
105
114
  try {
106
115
  const replyText = runCopilot(prompt, workingDir).trim();
116
+ dbg(`main: runCopilot returned replyLen=${replyText.length}`);
107
117
  if (!replyText) {
118
+ dbg('main: empty reply, throwing');
108
119
  throw new Error('Copilot returned an empty response');
109
120
  }
110
121
  process.stdout.write(JSON.stringify({ replyText }));
122
+ dbg('main: reply written to stdout, exiting 0');
111
123
  } catch (err) {
124
+ dbg(`main: error caught: ${err?.message ?? String(err)}`);
112
125
  process.stderr.write((err?.message ?? String(err)) + '\n');
113
126
  process.exit(1);
114
127
  }
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readJsonStdin } from './shared.js';
4
+
5
+ const input = readJsonStdin();
6
+ const userText = typeof input.userText === 'string' ? input.userText : '';
7
+ process.stdout.write(JSON.stringify({ replyText: `Echo: ${userText}` }));
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+
3
+ import * as fs from 'node:fs';
4
+ import * as http from 'node:http';
5
+
6
+ export function readJsonStdin() {
7
+ if (process.stdin.isTTY) return {};
8
+ try {
9
+ const raw = fs.readFileSync(0, 'utf-8').trim();
10
+ if (!raw) return {};
11
+ const parsed = JSON.parse(raw);
12
+ return parsed && typeof parsed === 'object' ? parsed : {};
13
+ } catch {
14
+ return {};
15
+ }
16
+ }
17
+
18
+ function httpJson(method, targetUrl, payload) {
19
+ return new Promise((resolve, reject) => {
20
+ const target = new URL(targetUrl);
21
+ const data = Buffer.from(JSON.stringify(payload), 'utf-8');
22
+ const req = http.request({
23
+ hostname: target.hostname,
24
+ port: target.port,
25
+ path: target.pathname + target.search,
26
+ method,
27
+ headers: {
28
+ 'Content-Type': 'application/json',
29
+ 'Content-Length': data.length,
30
+ },
31
+ }, (res) => {
32
+ const chunks = [];
33
+ res.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
34
+ res.on('end', () => {
35
+ const bodyText = Buffer.concat(chunks).toString('utf-8');
36
+ let body = null;
37
+ try { body = bodyText ? JSON.parse(bodyText) : null; } catch { body = bodyText; }
38
+ resolve({ status: res.statusCode || 0, body });
39
+ });
40
+ });
41
+ req.on('error', reject);
42
+ req.write(data);
43
+ req.end();
44
+ });
45
+ }
46
+
47
+ export async function invokeControlplaneTool({ serverUrl, boardId, tool, args }) {
48
+ const trimmedServerUrl = String(serverUrl || '').trim().replace(/\/+$/, '');
49
+ const trimmedBoardId = String(boardId || '').trim();
50
+ const trimmedTool = String(tool || '').trim();
51
+ if (!trimmedServerUrl) throw new Error('serverUrl is required');
52
+ if (!trimmedBoardId) throw new Error('boardId is required');
53
+ if (!trimmedTool) throw new Error('tool is required');
54
+
55
+ const result = await httpJson('POST', `${trimmedServerUrl}/api/boards/${encodeURIComponent(trimmedBoardId)}/mcp-controlplane`, {
56
+ tool: trimmedTool,
57
+ args,
58
+ });
59
+
60
+ if (result.status !== 200) {
61
+ const message = result.body && typeof result.body === 'object' && typeof result.body.error === 'string'
62
+ ? result.body.error
63
+ : `controlplane tool failed with status ${result.status}`;
64
+ throw new Error(message);
65
+ }
66
+
67
+ return result.body;
68
+ }
69
+
70
+ async function main() {
71
+ const input = readJsonStdin();
72
+ const action = typeof input.action === 'string' ? input.action.trim() : '';
73
+ if (action !== 'set-chat-processing-done') {
74
+ throw new Error('shared.js requires action="set-chat-processing-done"');
75
+ }
76
+ const serverUrl = typeof input.serverUrl === 'string' ? input.serverUrl : '';
77
+ const boardId = typeof input.boardId === 'string' ? input.boardId : '';
78
+ const cardId = typeof input.cardId === 'string' ? input.cardId : '';
79
+ if (!cardId) throw new Error('cardId is required');
80
+
81
+ const result = await invokeControlplaneTool({
82
+ serverUrl,
83
+ boardId,
84
+ tool: 'setstate.chat-processing-done',
85
+ args: { board_id: boardId, card_id: cardId },
86
+ });
87
+
88
+ process.stdout.write(JSON.stringify(result));
89
+ }
90
+
91
+ const isMain = process.argv[1] && fs.realpathSync(process.argv[1]) === fs.realpathSync(new URL(import.meta.url));
92
+ if (isMain) {
93
+ main().catch((err) => {
94
+ process.stderr.write(`${err?.message ?? String(err)}\n`);
95
+ process.exit(1);
96
+ });
97
+ }