yaml-flow 8.5.2 → 8.6.1
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/browser/asset-integrity.json +3 -3
- package/examples/board/demo-shell-with-server.html +2 -2
- package/examples/board/doc.html +2 -2
- package/examples/board/server/board-server.js +266 -5
- package/examples/board/server/board-worker/task-executor.js +166 -51
- package/examples/board/server/chat-flow/copilot-chat/assistant.js +25 -12
- package/examples/board/server/chat-flow/copilot-chat/probe.js +7 -0
- package/examples/board/server/chat-flow/copilot-chat/shared.js +97 -0
- package/examples/board/server/chat-flow/flow-steps.json +109 -51
- package/examples/board/server-config.json +1 -0
- package/examples/board/test/server-http-test.js +870 -67
- package/examples/board-local/demo-shell-localstorage.html +3 -3
- package/lib/{artifacts-store-lib-D-k-E8Vy.d.ts → artifacts-store-lib-C1rtrkxm.d.ts} +1 -1
- package/lib/{artifacts-store-lib-CVgtQrNZ.d.cts → artifacts-store-lib-CLOtsiav.d.cts} +1 -1
- package/lib/artifacts-store-public.cjs +1 -1
- package/lib/artifacts-store-public.d.cts +3 -3
- package/lib/artifacts-store-public.d.ts +3 -3
- package/lib/artifacts-store-public.js +1 -1
- package/lib/batch/index.cjs +1 -1
- package/lib/batch/index.js +1 -1
- package/lib/board-live-cards-mcp.cjs +1 -1
- package/lib/board-live-cards-mcp.d.cts +36 -16
- package/lib/board-live-cards-mcp.d.ts +36 -16
- package/lib/board-live-cards-mcp.js +1 -1
- package/lib/board-live-cards-node.cjs +8 -16
- package/lib/board-live-cards-node.d.cts +32 -12
- package/lib/board-live-cards-node.d.ts +32 -12
- package/lib/board-live-cards-node.js +8 -16
- package/lib/{board-live-cards-public-BGS22cMb.d.ts → board-live-cards-public-CBVjm327.d.ts} +59 -24
- package/lib/{board-live-cards-public-B13InXhC.d.cts → board-live-cards-public-CPJy-aGW.d.cts} +59 -24
- package/lib/board-live-cards-public.cjs +1 -2
- package/lib/board-live-cards-public.d.cts +2 -2
- package/lib/board-live-cards-public.d.ts +2 -2
- package/lib/board-live-cards-public.js +1 -2
- package/lib/board-live-cards-server-runtime.cjs +1 -7
- package/lib/board-live-cards-server-runtime.d.cts +5 -5
- package/lib/board-live-cards-server-runtime.d.ts +5 -5
- package/lib/board-live-cards-server-runtime.js +1 -7
- package/lib/board-livegraph-runtime/index.cjs +1 -2
- package/lib/board-livegraph-runtime/index.js +1 -2
- package/lib/board-worker-adapter.cjs +21 -7
- package/lib/board-worker-adapter.d.cts +17 -2
- package/lib/board-worker-adapter.d.ts +17 -2
- package/lib/board-worker-adapter.js +21 -7
- package/lib/card-compute/index.cjs +1 -9
- package/lib/card-compute/index.js +1 -9
- package/lib/card-store-public.cjs +1 -1
- package/lib/card-store-public.d.cts +2 -2
- package/lib/card-store-public.d.ts +2 -2
- package/lib/card-store-public.js +1 -1
- package/lib/card-validation.cjs +1 -9
- package/lib/card-validation.js +1 -9
- package/lib/{chat-storage-lib-CJn7a6OH.d.ts → chat-storage-lib-Bce-xx6l.d.ts} +1 -1
- package/lib/{chat-storage-lib-0imhRX3l.d.cts → chat-storage-lib-CKylihjm.d.cts} +1 -1
- package/lib/chat-store-public.cjs +1 -1
- package/lib/chat-store-public.d.cts +3 -3
- package/lib/chat-store-public.d.ts +3 -3
- package/lib/chat-store-public.js +1 -1
- package/lib/chunk-2MZUYY65.cjs +2 -0
- package/lib/chunk-5DB54ZX2.cjs +2 -0
- package/lib/chunk-5EA2ESS4.cjs +16 -0
- package/lib/chunk-6APH25VI.js +2 -0
- package/lib/chunk-76ON3V7R.js +2 -0
- package/lib/chunk-7BKNHFNH.js +2 -0
- package/lib/chunk-CWREBRXS.js +3 -0
- package/lib/chunk-DAXACY63.js +2 -0
- package/lib/chunk-FW4363Y4.js +2 -0
- package/lib/chunk-FZ2SBU5M.js +3 -0
- package/lib/chunk-G4XXRHL2.cjs +3 -0
- package/lib/chunk-GNFE24S7.cjs +2 -0
- package/lib/chunk-GYQXDNNI.cjs +2 -0
- package/lib/chunk-H5KD3JPY.cjs +2 -0
- package/lib/chunk-HLJH7LGW.js +16 -0
- package/lib/chunk-I4WH5U5D.cjs +2 -0
- package/lib/chunk-IXZG74EW.cjs +2 -0
- package/lib/chunk-JAL25FGA.cjs +2 -0
- package/lib/chunk-JM5EKT57.js +2 -0
- package/lib/chunk-JMDHDY6M.js +2 -0
- package/lib/chunk-KBELAKIY.js +2 -0
- package/lib/chunk-KHJABJ45.cjs +3 -0
- package/lib/chunk-KLRUISRY.cjs +2 -0
- package/lib/chunk-KNFFDVLD.cjs +2 -0
- package/lib/chunk-LBMEVV4U.js +2 -0
- package/lib/chunk-LDAP75GN.js +2 -0
- package/lib/chunk-LODXIALE.cjs +2 -0
- package/lib/chunk-LVNQCE5X.cjs +3 -0
- package/lib/chunk-M7EQRS6W.js +3 -0
- package/lib/chunk-MNEOJWPS.js +10 -0
- package/lib/chunk-NJJ7WEDT.cjs +2 -0
- package/lib/chunk-NMZ6XNLB.cjs +3 -0
- package/lib/chunk-OPNGCSXJ.js +2 -0
- package/lib/chunk-P64UKI3L.cjs +8 -0
- package/lib/chunk-P7ZCDICS.cjs +2 -0
- package/lib/chunk-Q6H7NINN.cjs +5 -0
- package/lib/chunk-Q6VSL327.js +8 -0
- package/lib/chunk-QWBNDVUA.js +5 -0
- package/lib/chunk-S6DRP2HX.cjs +2 -0
- package/lib/chunk-UJ7ZTV4J.cjs +10 -0
- package/lib/chunk-UVE65IPR.cjs +3 -0
- package/lib/chunk-VCCTAUIG.js +2 -0
- package/lib/chunk-VGT3TRQG.js +3 -0
- package/lib/chunk-VLBB3D6B.js +3 -0
- package/lib/chunk-WDPOGXTY.js +2 -0
- package/lib/chunk-X3LC4LII.js +2 -0
- package/lib/chunk-YGKDQLYP.js +2 -0
- package/lib/chunk-YMEIPKLW.cjs +2 -0
- package/lib/config/index.cjs +1 -1
- package/lib/config/index.js +1 -1
- package/lib/continuous-event-graph/index.cjs +1 -2
- package/lib/continuous-event-graph/index.js +1 -2
- package/lib/event-graph/index.cjs +1 -22
- package/lib/event-graph/index.js +1 -22
- package/lib/execution-refs.cjs +1 -2
- package/lib/execution-refs.d.cts +3 -2
- package/lib/execution-refs.d.ts +3 -2
- package/lib/execution-refs.js +1 -2
- package/lib/index.cjs +2 -24
- package/lib/index.d.cts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -24
- package/lib/server-runtime/index.cjs +1 -7
- package/lib/server-runtime/index.d.cts +6 -6
- package/lib/server-runtime/index.d.ts +6 -6
- package/lib/server-runtime/index.js +1 -7
- package/lib/step-machine/index.cjs +1 -11
- package/lib/step-machine/index.js +1 -11
- package/lib/step-machine-public/index.cjs +1 -4
- package/lib/step-machine-public/index.d.cts +1 -1
- package/lib/step-machine-public/index.d.ts +1 -1
- package/lib/step-machine-public/index.js +1 -4
- package/lib/{storage-interface-B2WD9D5n.d.cts → storage-interface-Ct-C4tlz.d.cts} +28 -1
- package/lib/{storage-interface-B2WD9D5n.d.ts → storage-interface-Ct-C4tlz.d.ts} +28 -1
- package/lib/stores/index.cjs +1 -2
- package/lib/stores/index.d.cts +1 -1
- package/lib/stores/index.d.ts +1 -1
- package/lib/stores/index.js +1 -2
- package/lib/stores/kv.cjs +1 -2
- package/lib/stores/kv.d.cts +1 -1
- package/lib/stores/kv.d.ts +1 -1
- package/lib/stores/kv.js +1 -2
- package/lib/stores/memory.cjs +1 -1
- package/lib/stores/memory.js +1 -1
- package/lib/{types-30R357js.d.ts → types-BuK2UMxk.d.ts} +4 -4
- package/lib/{types-CIgsh56O.d.cts → types-DRl0Hy_p.d.cts} +4 -4
- package/package.json +2 -16
- package/cli/board-live-cards-lib-COi4bSpk.d.ts +0 -322
- package/cli/browser-api/board-live-cards-browser-adapter.d.ts +0 -36
- package/cli/browser-api/board-live-cards-browser-adapter.js +0 -4
- package/cli/browser-api/card-store-browser-api.d.ts +0 -25
- package/cli/browser-api/card-store-browser-api.js +0 -2
- package/cli/browser-api/jsonata-sync.cjs +0 -7623
- package/cli/bundled/artifacts-store-cli.mjs +0 -12
- package/cli/bundled/batch-runner-cli.mjs +0 -3
- package/cli/bundled/board-live-cards-cli.mjs +0 -29
- package/cli/bundled/card-store-cli.mjs +0 -154
- package/cli/bundled/chat-store-cli.mjs +0 -16
- package/cli/bundled/jsonata-sync.cjs +0 -7623
- package/cli/bundled/step-machine-cli.mjs +0 -150
- package/cli/execution-interface-BCIhu1gO.d.ts +0 -442
- package/cli/types-H3EMBPY2.d.ts +0 -398
- package/examples/board/server/README-mcp-api.md +0 -680
- package/examples/board/test/server-http-mcp-test.js +0 -1163
- package/lib/board-livegraph-runtime/jsonata-sync.cjs +0 -7623
- package/lib/card-compute/jsonata-sync.cjs +0 -7623
- package/lib/continuous-event-graph/jsonata-sync.cjs +0 -7623
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
562
|
+
process.exit(result.ok ? 0 : 1);
|
|
506
563
|
}
|
|
507
564
|
|
|
508
|
-
function
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
559
|
-
|
|
560
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
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,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
|
+
}
|