yaml-flow 5.4.2 → 7.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/board-live-cards-cli.js +6 -6
- package/browser/asset-integrity.json +10 -0
- package/browser/board-livecards-client.js +2 -0
- package/browser/board-livecards-client.js.map +1 -0
- package/browser/board-livecards-localstorage.js +10 -0
- package/browser/board-livecards-localstorage.js.map +1 -0
- package/browser/board-livegraph-engine.js +2 -1676
- package/browser/board-livegraph-engine.js.map +1 -1
- package/browser/card-compute.js +28 -28
- package/browser/compute-jsonata.js +5 -0
- package/browser/compute-jsonata.js.map +1 -0
- package/browser/live-cards.js +561 -129
- package/browser/live-cards.schema.json +418 -132
- package/card-store.js +37 -0
- package/dist/batch/index.cjs +1 -108
- package/dist/batch/index.cjs.map +1 -1
- package/dist/batch/index.js +1 -106
- package/dist/batch/index.js.map +1 -1
- package/dist/board-live-cards-lib-Bg6EvCo5.d.cts +136 -0
- package/dist/board-live-cards-lib-jM2uYG1v.d.ts +136 -0
- package/dist/board-live-cards-public-CW5074xr.d.cts +318 -0
- package/dist/board-live-cards-public-hnZo0mAf.d.ts +318 -0
- package/dist/board-livegraph-runtime/index.cjs +2 -1671
- package/dist/board-livegraph-runtime/index.cjs.map +1 -1
- package/dist/board-livegraph-runtime/index.d.cts +12 -11
- package/dist/board-livegraph-runtime/index.d.ts +12 -11
- package/dist/board-livegraph-runtime/index.js +2 -1662
- package/dist/board-livegraph-runtime/index.js.map +1 -1
- package/dist/board-livegraph-runtime/jsonata-sync.cjs +7623 -0
- package/dist/card-compute/index.cjs +9 -7159
- package/dist/card-compute/index.cjs.map +1 -1
- package/dist/card-compute/index.d.cts +27 -1
- package/dist/card-compute/index.d.ts +27 -1
- package/dist/card-compute/index.js +9 -7145
- package/dist/card-compute/index.js.map +1 -1
- package/dist/card-compute/jsonata-sync.cjs +7623 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs +3 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs.map +1 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.d.cts +37 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.d.ts +37 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.js +3 -0
- package/dist/cli/browser-api/board-live-cards-browser-adapter.js.map +1 -0
- package/dist/cli/browser-api/card-store-browser-api.cjs +2 -0
- package/dist/cli/browser-api/card-store-browser-api.cjs.map +1 -0
- package/dist/cli/browser-api/card-store-browser-api.d.cts +26 -0
- package/dist/cli/browser-api/card-store-browser-api.d.ts +26 -0
- package/dist/cli/browser-api/card-store-browser-api.js +2 -0
- package/dist/cli/browser-api/card-store-browser-api.js.map +1 -0
- package/dist/cli/browser-api/jsonata-sync.cjs +7623 -0
- package/dist/cli/node/artifacts-store-cli.cjs +11 -0
- package/dist/cli/node/artifacts-store-cli.cjs.map +1 -0
- package/dist/cli/node/artifacts-store-cli.d.cts +8 -0
- package/dist/cli/node/artifacts-store-cli.d.ts +8 -0
- package/dist/cli/node/artifacts-store-cli.js +11 -0
- package/dist/cli/node/artifacts-store-cli.js.map +1 -0
- package/dist/cli/node/board-live-cards-cli.cjs +15 -0
- package/dist/cli/node/board-live-cards-cli.cjs.map +1 -0
- package/dist/cli/node/board-live-cards-cli.d.cts +20 -0
- package/dist/cli/node/board-live-cards-cli.d.ts +20 -0
- package/dist/cli/node/board-live-cards-cli.js +15 -0
- package/dist/cli/node/board-live-cards-cli.js.map +1 -0
- package/dist/cli/node/card-store-cli.cjs +8 -0
- package/dist/cli/node/card-store-cli.cjs.map +1 -0
- package/dist/cli/node/card-store-cli.d.cts +15 -0
- package/dist/cli/node/card-store-cli.d.ts +15 -0
- package/dist/cli/node/card-store-cli.js +8 -0
- package/dist/cli/node/card-store-cli.js.map +1 -0
- package/dist/cli/node/execution-adapter.cjs +3 -0
- package/dist/cli/node/execution-adapter.cjs.map +1 -0
- package/dist/cli/node/execution-adapter.d.cts +174 -0
- package/dist/cli/node/execution-adapter.d.ts +174 -0
- package/dist/cli/node/execution-adapter.js +3 -0
- package/dist/cli/node/execution-adapter.js.map +1 -0
- package/dist/cli/node/fs-board-adapter.cjs +14 -0
- package/dist/cli/node/fs-board-adapter.cjs.map +1 -0
- package/dist/cli/node/fs-board-adapter.d.cts +204 -0
- package/dist/cli/node/fs-board-adapter.d.ts +204 -0
- package/dist/cli/node/fs-board-adapter.js +14 -0
- package/dist/cli/node/fs-board-adapter.js.map +1 -0
- package/dist/cli/node/jsonata-sync.cjs +7623 -0
- package/dist/cli/node/source-cli-task-executor.cjs +11 -0
- package/dist/cli/node/source-cli-task-executor.cjs.map +1 -0
- package/dist/cli/node/source-cli-task-executor.d.cts +1 -0
- package/dist/cli/node/source-cli-task-executor.d.ts +1 -0
- package/dist/cli/node/source-cli-task-executor.js +11 -0
- package/dist/cli/node/source-cli-task-executor.js.map +1 -0
- package/dist/config/index.cjs +1 -79
- package/dist/config/index.cjs.map +1 -1
- package/dist/config/index.js +1 -76
- package/dist/config/index.js.map +1 -1
- package/dist/continuous-event-graph/index.cjs +2 -2129
- package/dist/continuous-event-graph/index.cjs.map +1 -1
- package/dist/continuous-event-graph/index.d.cts +81 -5
- package/dist/continuous-event-graph/index.d.ts +81 -5
- package/dist/continuous-event-graph/index.js +2 -2088
- package/dist/continuous-event-graph/index.js.map +1 -1
- package/dist/continuous-event-graph/jsonata-sync.cjs +7623 -0
- package/dist/event-graph/index.cjs +22 -8292
- package/dist/event-graph/index.cjs.map +1 -1
- package/dist/event-graph/index.js +22 -8237
- package/dist/event-graph/index.js.map +1 -1
- package/dist/execution-refs.cjs +3 -0
- package/dist/execution-refs.cjs.map +1 -0
- package/dist/execution-refs.d.cts +260 -0
- package/dist/execution-refs.d.ts +260 -0
- package/dist/execution-refs.js +3 -0
- package/dist/execution-refs.js.map +1 -0
- package/dist/index.cjs +29 -13221
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -4
- package/dist/index.d.ts +2 -4
- package/dist/index.js +29 -13112
- package/dist/index.js.map +1 -1
- package/dist/inference/index.cjs +5 -617
- package/dist/inference/index.cjs.map +1 -1
- package/dist/inference/index.js +5 -610
- package/dist/inference/index.js.map +1 -1
- package/dist/jsonata-sync.cjs +7623 -0
- package/dist/{live-cards-bridge-x5XREkXm.d.cts → live-cards-bridge-BXbVTsna.d.cts} +27 -4
- package/dist/{live-cards-bridge-EQjytzI_.d.ts → live-cards-bridge-Ds28XR15.d.ts} +27 -4
- package/dist/server-runtime/index.cjs +9 -0
- package/dist/server-runtime/index.cjs.map +1 -0
- package/dist/server-runtime/index.d.cts +31 -0
- package/dist/server-runtime/index.d.ts +31 -0
- package/dist/server-runtime/index.js +9 -0
- package/dist/server-runtime/index.js.map +1 -0
- package/dist/server-runtime/jsonata-sync.cjs +7623 -0
- package/dist/step-machine/index.cjs +11 -7129
- package/dist/step-machine/index.cjs.map +1 -1
- package/dist/step-machine/index.js +11 -7113
- package/dist/step-machine/index.js.map +1 -1
- package/dist/step-machine-public/index.cjs +2 -0
- package/dist/step-machine-public/index.cjs.map +1 -0
- package/dist/step-machine-public/index.d.cts +159 -0
- package/dist/step-machine-public/index.d.ts +159 -0
- package/dist/step-machine-public/index.js +2 -0
- package/dist/step-machine-public/index.js.map +1 -0
- package/dist/step-machine-public/jsonata-sync.cjs +7623 -0
- package/dist/storage-refs.cjs +10 -0
- package/dist/storage-refs.cjs.map +1 -0
- package/dist/storage-refs.d.cts +93 -0
- package/dist/storage-refs.d.ts +93 -0
- package/dist/storage-refs.js +10 -0
- package/dist/storage-refs.js.map +1 -0
- package/dist/stores/file.cjs +1 -114
- package/dist/stores/file.cjs.map +1 -1
- package/dist/stores/file.js +1 -112
- package/dist/stores/file.js.map +1 -1
- package/dist/stores/index.cjs +1 -231
- package/dist/stores/index.cjs.map +1 -1
- package/dist/stores/index.js +1 -227
- package/dist/stores/index.js.map +1 -1
- package/dist/stores/localStorage.cjs +1 -76
- package/dist/stores/localStorage.cjs.map +1 -1
- package/dist/stores/localStorage.js +1 -74
- package/dist/stores/localStorage.js.map +1 -1
- package/dist/stores/memory.cjs +1 -47
- package/dist/stores/memory.cjs.map +1 -1
- package/dist/stores/memory.js +1 -45
- package/dist/stores/memory.js.map +1 -1
- package/dist/types-B1ZRa4aI.d.ts +147 -0
- package/dist/types-BxEFcVK9.d.cts +147 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-t4.js +291 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.js +218 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-fetch-prices.py +201 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-http-test.js +357 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-inference-adapter.js +25 -16
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-public.js +552 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-server.js +300 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-server.py +617 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-sse-worker.js +48 -0
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker.py +366 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/.runtime-out +1 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/--base-ref/board-graph.json +32 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +70 -3
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +16 -11
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/init-board-cli.js +9 -8
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/poll-status-cli.js +49 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/reset-board-dir-cli.js +2 -6
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/retrigger-cli.js +4 -8
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/status-cli.js +3 -7
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +9 -8
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/wait-completed-cli.js +12 -17
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers/write-prices-cli.js +2 -6
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/_board_pycli.py +107 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/add-cards.py +51 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/init-board.py +45 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/poll-status.py +71 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/reset-board-dir.py +36 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-demo.flow.yaml +26 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/inline-python-handlers.py +39 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker-pycli.flow.yaml +80 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +36 -187
- package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.input.json +40 -34
- package/examples/cli/step-machine-cli/portfolio-tracker/run-inline-python-demo-pycli.py +43 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker-pycli.py +77 -0
- package/examples/cli/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
- package/examples/cli/step-machine-demo/jsonata-init-board-cli.js +8 -13
- package/examples/cli/step-machine-demo/jsonata-init-board.flow.yaml +33 -9
- package/examples/cli/step-machine-demo/one-step-cli-only.flow.yaml +3 -1
- package/examples/cli/step-machine-demo/step2-double-cli.js +6 -12
- package/examples/cli/step-machine-demo/two-step-math.flow.yaml +66 -4
- package/examples/cli/step-machine-demo/two-step-mixed.flow.yaml +13 -5
- package/examples/example-board/agent-instructions.md +11 -5
- package/examples/example-board/cards/_index.json +47 -0
- package/examples/example-board/cards/card-market-prices.json +33 -9
- package/examples/example-board/cards/card-my-identity.json +30 -6
- package/examples/example-board/cards/card-portfolio-action.json +24 -6
- package/examples/example-board/cards/card-portfolio-intelligence.json +97 -0
- package/examples/example-board/cards/card-portfolio-risks.json +24 -6
- package/examples/example-board/cards/card-portfolio-value.json +38 -10
- package/examples/example-board/cards/card-portfolio.json +57 -13
- package/examples/example-board/cards/card-rebalance-impact.json +22 -6
- package/examples/example-board/cards/card-rebalance-sim.json +66 -15
- package/examples/example-board/demo-chat-handler.js +14 -4
- package/examples/example-board/demo-server-config.json +1 -0
- package/examples/example-board/demo-server.js +366 -68
- package/examples/example-board/demo-shell-localstorage.html +774 -0
- package/examples/example-board/demo-shell-with-server.html +20 -37
- package/examples/example-board/demo-shell.html +5 -4
- package/examples/example-board/demo-task-executor.js +273 -275
- package/examples/index.html +0 -14
- package/examples/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +0 -1
- package/examples/step-machine-cli/portfolio-tracker/run-portfolio-tracker.bat +1 -2
- package/package.json +46 -8
- package/schema/live-cards.schema.json +418 -132
- package/step-machine-cli.js +43 -310
- package/board-livecards-server-runtime.js +0 -1574
- package/browser/board-livecards-runtime-client.js +0 -263
- package/dist/cli/board-live-cards-cli.cjs +0 -10650
- package/dist/cli/board-live-cards-cli.cjs.map +0 -1
- package/dist/cli/board-live-cards-cli.d.cts +0 -179
- package/dist/cli/board-live-cards-cli.d.ts +0 -179
- package/dist/cli/board-live-cards-cli.js +0 -10598
- package/dist/cli/board-live-cards-cli.js.map +0 -1
- package/dist/journal-9HEgs7dU.d.ts +0 -28
- package/dist/journal-B-JCfQnh.d.cts +0 -28
- package/dist/schedule-Cszq9LYY.d.ts +0 -21
- package/dist/schedule-qWNL0RQh.d.cts +0 -21
- package/examples/browser/boards/portfolio-tracker/cards/holdings-table.json +0 -22
- package/examples/browser/boards/portfolio-tracker/cards/portfolio-form.json +0 -16
- package/examples/browser/boards/portfolio-tracker/cards/portfolio-risk-assessment.json +0 -28
- package/examples/browser/boards/portfolio-tracker/cards/portfolio-value.json +0 -15
- package/examples/browser/boards/portfolio-tracker/cards/price-fetch.json +0 -15
- package/examples/browser/boards/portfolio-tracker/cards/rebalancing-strategy.json +0 -28
- package/examples/browser/boards/portfolio-tracker/fetch-prices.js +0 -43
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker-task-executor.cjs +0 -96
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker.bat +0 -7
- package/examples/browser/boards/portfolio-tracker/portfolio-tracker.js +0 -351
- package/examples/cli/step-machine-demo/two-step-math-handlers.js +0 -32
- package/examples/cli/step-machine-demo/two-step-mixed-handlers.js +0 -24
- package/examples/example-board/demo-shell-browser.html +0 -674
|
@@ -4,15 +4,22 @@ import http from 'node:http';
|
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import os from 'node:os';
|
|
7
|
+
import net from 'node:net';
|
|
7
8
|
import { spawnSync, spawn } from 'node:child_process';
|
|
8
9
|
import { fileURLToPath } from 'node:url';
|
|
9
10
|
import { createRequire } from 'node:module';
|
|
10
11
|
|
|
11
12
|
import {
|
|
12
13
|
createMultiBoardServerRuntime,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
createSingleBoardServerRuntime,
|
|
15
|
+
} from 'yaml-flow/server-runtime';
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
createFsBoardPlatformAdapter,
|
|
19
|
+
createArtifactsStore,
|
|
20
|
+
parseRef,
|
|
21
|
+
serializeRef,
|
|
22
|
+
} from 'yaml-flow/board-live-cards-node';
|
|
16
23
|
|
|
17
24
|
const __filename = fileURLToPath(import.meta.url);
|
|
18
25
|
const __dirname = path.dirname(__filename);
|
|
@@ -27,7 +34,11 @@ function resolveYamlFlowDir() {
|
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
const _yamlFlowDir = resolveYamlFlowDir();
|
|
30
|
-
|
|
37
|
+
|
|
38
|
+
// cliDir must point to the yaml-flow root so buildBoardCliInvocation finds
|
|
39
|
+
// board-live-cards-cli.js for task-executor completion callbacks.
|
|
40
|
+
// demo-src/example-board is 2 levels below the yaml-flow root.
|
|
41
|
+
const YAML_FLOW_CLI_DIR = _yamlFlowDir || path.resolve(__dirname, '..', '..');
|
|
31
42
|
const _pkgStepMachineCli = _yamlFlowDir ? path.join(_yamlFlowDir, 'step-machine-cli.js') : null;
|
|
32
43
|
|
|
33
44
|
function loadServerConfig() {
|
|
@@ -47,8 +58,23 @@ function resolveFromConfig(configValue) {
|
|
|
47
58
|
return path.resolve(__dirname, configValue);
|
|
48
59
|
}
|
|
49
60
|
|
|
61
|
+
function resolveKindRefFromConfig(configValue) {
|
|
62
|
+
if (typeof configValue !== 'string' || !configValue.trim()) return null;
|
|
63
|
+
const trimmed = configValue.trim();
|
|
64
|
+
if (!trimmed.startsWith('b64:')) return trimmed;
|
|
65
|
+
try {
|
|
66
|
+
const parsed = parseRef(trimmed);
|
|
67
|
+
if (parsed.kind !== 'fs-path') return trimmed;
|
|
68
|
+
const rawPath = parsed.value.trim();
|
|
69
|
+
if (!rawPath) return null;
|
|
70
|
+
const resolved = path.isAbsolute(rawPath) ? rawPath : path.resolve(__dirname, rawPath);
|
|
71
|
+
return serializeRef({ kind: 'fs-path', value: resolved });
|
|
72
|
+
} catch {
|
|
73
|
+
return trimmed;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
50
77
|
const serverConfig = loadServerConfig();
|
|
51
|
-
const configuredCliJs = resolveFromConfig(serverConfig.boardLiveCardsCliJs) || _pkgCliJs;
|
|
52
78
|
const configuredCardsDir = resolveFromConfig(serverConfig.cardsDir);
|
|
53
79
|
const configuredTaskExecutorPath = resolveFromConfig(serverConfig.taskExecutorPath || serverConfig.demoTaskExecutorPath);
|
|
54
80
|
const configuredStepMachineCliPath = resolveFromConfig(serverConfig.stepMachineCliPath) || _pkgStepMachineCli;
|
|
@@ -58,10 +84,8 @@ const configuredGandalfCardsDir = resolveFromConfig(serverConfig.gandalfCardsDir
|
|
|
58
84
|
const configuredGandalfTaskExecutorPath = resolveFromConfig(serverConfig.gandalfTaskExecutorPath);
|
|
59
85
|
const configuredGandalfChatHandlerPath = resolveFromConfig(serverConfig.gandalfChatHandlerPath);
|
|
60
86
|
const configuredGandalfInferenceAdapterPath = resolveFromConfig(serverConfig.gandalfInferenceAdapterPath);
|
|
87
|
+
const configuredServerMetaStoreRef = resolveKindRefFromConfig(serverConfig.serverMetaStoreRef);
|
|
61
88
|
|
|
62
|
-
if (!process.env.BOARD_LIVE_CARDS_CLI_JS && configuredCliJs) {
|
|
63
|
-
process.env.BOARD_LIVE_CARDS_CLI_JS = configuredCliJs;
|
|
64
|
-
}
|
|
65
89
|
if (!process.env.DEMO_STEP_MACHINE_CLI_PATH && configuredStepMachineCliPath) {
|
|
66
90
|
process.env.DEMO_STEP_MACHINE_CLI_PATH = configuredStepMachineCliPath;
|
|
67
91
|
}
|
|
@@ -81,23 +105,293 @@ const CORS_HEADERS = {
|
|
|
81
105
|
'Access-Control-Allow-Methods': 'GET,POST,PATCH,OPTIONS',
|
|
82
106
|
};
|
|
83
107
|
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Setup directory & defaults
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
|
|
112
|
+
const setupDir = path.resolve(
|
|
113
|
+
process.env.DEMO_SETUP_DIR || path.join(__dirname, '.demo-setup'),
|
|
114
|
+
);
|
|
115
|
+
fs.mkdirSync(setupDir, { recursive: true });
|
|
116
|
+
|
|
117
|
+
const defaultCardsDir = path.resolve(
|
|
118
|
+
process.env.DEMO_CARDS_DIR || configuredCardsDir || path.join(__dirname, 'cards'),
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const defaultTaskExecutorPath = process.env.DEMO_TASK_EXECUTOR_PATH || configuredTaskExecutorPath || null;
|
|
122
|
+
const defaultChatHandlerPath = process.env.DEMO_CHAT_HANDLER_PATH || configuredChatHandlerPath || null;
|
|
123
|
+
const defaultInferenceAdapterPath = process.env.DEMO_INFERENCE_ADAPTER_PATH || configuredInferenceAdapterPath || null;
|
|
124
|
+
const defaultStepMachineCliPath = process.env.DEMO_STEP_MACHINE_CLI_PATH || configuredStepMachineCliPath || null;
|
|
125
|
+
const defaultGandalfCardsDir = process.env.DEMO_GANDALF_CARDS_DIR || configuredGandalfCardsDir || null;
|
|
126
|
+
const defaultGandalfTaskExecutorPath = process.env.DEMO_GANDALF_TASK_EXECUTOR_PATH || configuredGandalfTaskExecutorPath || null;
|
|
127
|
+
const defaultGandalfChatHandlerPath = process.env.DEMO_GANDALF_CHAT_HANDLER_PATH || configuredGandalfChatHandlerPath || null;
|
|
128
|
+
const defaultGandalfInferenceAdapterPath = process.env.DEMO_GANDALF_INFERENCE_ADAPTER_PATH || configuredGandalfInferenceAdapterPath || null;
|
|
129
|
+
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Host adapter factories — Node-specific implementations injected into the
|
|
132
|
+
// platform-free server runtime.
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
function createFsCardSource(cardsDir) {
|
|
136
|
+
return {
|
|
137
|
+
listCards() {
|
|
138
|
+
if (!fs.existsSync(cardsDir)) return [];
|
|
139
|
+
return fs.readdirSync(cardsDir)
|
|
140
|
+
.filter(f => f.endsWith('.json'))
|
|
141
|
+
.map(f => {
|
|
142
|
+
try { return JSON.parse(fs.readFileSync(path.join(cardsDir, f), 'utf-8')); }
|
|
143
|
+
catch { return null; }
|
|
144
|
+
})
|
|
145
|
+
.filter(Boolean);
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function namedPipePath(pipeName) {
|
|
151
|
+
if (process.platform === 'win32') return `\\\\.\\pipe\\${pipeName}`;
|
|
152
|
+
return path.join(os.tmpdir(), `${pipeName}.sock`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function makeExecutionRef(scriptPath, meta) {
|
|
156
|
+
if (!scriptPath) return undefined;
|
|
157
|
+
const resolved = path.isAbsolute(scriptPath) ? scriptPath : path.resolve(process.cwd(), scriptPath);
|
|
158
|
+
return { howToRun: 'local-node', whatToRun: serializeRef({ kind: 'fs-path', value: resolved }), meta };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function createNodeSpawnInvocationAdapter() {
|
|
162
|
+
return {
|
|
163
|
+
async invoke(ref, args) {
|
|
164
|
+
if (ref.howToRun !== 'local-node') {
|
|
165
|
+
return { dispatched: false, error: `unsupported howToRun: ${ref.howToRun}` };
|
|
166
|
+
}
|
|
167
|
+
const whatToRun = String(ref.whatToRun || '');
|
|
168
|
+
let scriptPath = '';
|
|
169
|
+
if (whatToRun.startsWith('b64:')) {
|
|
170
|
+
try {
|
|
171
|
+
const parsed = parseRef(whatToRun);
|
|
172
|
+
if (parsed.kind === 'fs-path') scriptPath = parsed.value;
|
|
173
|
+
} catch {
|
|
174
|
+
scriptPath = '';
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
scriptPath = whatToRun;
|
|
178
|
+
}
|
|
179
|
+
if (!scriptPath) {
|
|
180
|
+
return { dispatched: false, error: `no script path in whatToRun: ${whatToRun}` };
|
|
181
|
+
}
|
|
182
|
+
// Resolve chatsKeyPrefix (blob key prefix) to absolute FS chatDir for handlers
|
|
183
|
+
const finalArgs = { ...args };
|
|
184
|
+
if (finalArgs.chatsKeyPrefix && finalArgs.chatsBlobBasePath) {
|
|
185
|
+
const cardPart = String(finalArgs.chatsKeyPrefix).split('/')[0];
|
|
186
|
+
finalArgs.chatDir = path.join(String(finalArgs.chatsBlobBasePath), cardPart);
|
|
187
|
+
}
|
|
188
|
+
delete finalArgs.chatsKeyPrefix;
|
|
189
|
+
delete finalArgs.chatsBlobBasePath;
|
|
190
|
+
const extra = Buffer.from(JSON.stringify(finalArgs)).toString('base64');
|
|
191
|
+
try {
|
|
192
|
+
const proc = spawn(process.execPath, [
|
|
193
|
+
scriptPath,
|
|
194
|
+
'--boardId', String(args.boardId || ''),
|
|
195
|
+
'--cardId', String(args.cardId || ''),
|
|
196
|
+
'--extraEncJson', extra,
|
|
197
|
+
], { stdio: 'ignore', windowsHide: true });
|
|
198
|
+
proc.unref();
|
|
199
|
+
return { dispatched: true };
|
|
200
|
+
} catch (err) {
|
|
201
|
+
return { dispatched: false, error: err?.message || String(err) };
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
async describe(ref) {
|
|
205
|
+
if (ref.howToRun !== 'local-node') return null;
|
|
206
|
+
const whatToRun = String(ref.whatToRun || '');
|
|
207
|
+
let scriptPath = '';
|
|
208
|
+
if (whatToRun.startsWith('b64:')) {
|
|
209
|
+
try {
|
|
210
|
+
const parsed = parseRef(whatToRun);
|
|
211
|
+
if (parsed.kind === 'fs-path') scriptPath = parsed.value;
|
|
212
|
+
} catch {
|
|
213
|
+
scriptPath = '';
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
scriptPath = whatToRun;
|
|
217
|
+
}
|
|
218
|
+
if (!scriptPath) return null;
|
|
219
|
+
try {
|
|
220
|
+
const result = spawnSync(process.execPath, [scriptPath, 'describe'], {
|
|
221
|
+
timeout: 5000, encoding: 'utf-8', windowsHide: true,
|
|
222
|
+
});
|
|
223
|
+
if (result.status !== 0) return null;
|
|
224
|
+
return JSON.parse(String(result.stdout).trim());
|
|
225
|
+
} catch { return null; }
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function createNamedPipeNotificationTransport() {
|
|
231
|
+
return {
|
|
232
|
+
async subscribe(ref, onEvent) {
|
|
233
|
+
if (ref.kind !== 'named-pipe') {
|
|
234
|
+
console.warn(`[notification] unsupported transport kind: ${ref.kind}`);
|
|
235
|
+
return () => {};
|
|
236
|
+
}
|
|
237
|
+
const pipePath = ref.value;
|
|
238
|
+
if (process.platform !== 'win32' && fs.existsSync(pipePath)) {
|
|
239
|
+
try { fs.rmSync(pipePath, { force: true }); } catch { /* best-effort */ }
|
|
240
|
+
}
|
|
241
|
+
const server = net.createServer((socket) => {
|
|
242
|
+
let buf = '';
|
|
243
|
+
socket.on('data', (chunk) => {
|
|
244
|
+
buf += chunk.toString('utf-8');
|
|
245
|
+
while (true) {
|
|
246
|
+
const i = buf.indexOf('\n');
|
|
247
|
+
if (i < 0) break;
|
|
248
|
+
const line = buf.slice(0, i).trim();
|
|
249
|
+
buf = buf.slice(i + 1);
|
|
250
|
+
if (!line) continue;
|
|
251
|
+
try {
|
|
252
|
+
const msg = JSON.parse(line);
|
|
253
|
+
onEvent(msg?.notification ?? msg);
|
|
254
|
+
} catch { /* ignore malformed lines */ }
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
await new Promise((resolve, reject) => {
|
|
259
|
+
server.once('error', reject);
|
|
260
|
+
server.listen(pipePath, () => resolve());
|
|
261
|
+
});
|
|
262
|
+
return () => {
|
|
263
|
+
server.close();
|
|
264
|
+
if (process.platform !== 'win32') {
|
|
265
|
+
try { fs.rmSync(pipePath, { force: true }); } catch { /* best-effort */ }
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
// Server meta store (multi-board registry)
|
|
274
|
+
// ---------------------------------------------------------------------------
|
|
275
|
+
|
|
276
|
+
const serverMetaRef = process.env.DEMO_SERVER_META_STORE_REF || configuredServerMetaStoreRef || serializeRef({ kind: 'fs-path', value: setupDir });
|
|
277
|
+
const serverMetaAdapter = createFsBoardPlatformAdapter(
|
|
278
|
+
parseRef(serverMetaRef), YAML_FLOW_CLI_DIR, { suppressSpawn: true },
|
|
279
|
+
);
|
|
280
|
+
const serverMetaStore = createArtifactsStore(serverMetaAdapter.blobStorage('server-meta'));
|
|
281
|
+
|
|
282
|
+
// ---------------------------------------------------------------------------
|
|
283
|
+
// Build multi-board runtime
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
|
|
286
|
+
const apiBasePath = '/api/boards';
|
|
287
|
+
const invocationAdapter = createNodeSpawnInvocationAdapter();
|
|
288
|
+
const notificationTransport = createNamedPipeNotificationTransport();
|
|
289
|
+
const logger = { info: console.log, warn: console.warn, error: console.error };
|
|
290
|
+
|
|
291
|
+
// Track per-board host config for demo-setup (FS paths are host concerns, not runtime concerns)
|
|
292
|
+
const boardHostConfig = new Map();
|
|
293
|
+
|
|
294
|
+
function buildBoardContextConfig(label, boardDir, cardsDir, taskExecPath, chatHandlerPath, infAdapterPath, boardId) {
|
|
295
|
+
fs.mkdirSync(boardDir, { recursive: true });
|
|
296
|
+
|
|
297
|
+
const notifyChannel = `yaml-flow-server-${label}-${boardId}-${process.pid}`;
|
|
298
|
+
const baseRef = parseRef(serializeRef({ kind: 'fs-path', value: boardDir }));
|
|
299
|
+
const boardAdapter = createFsBoardPlatformAdapter(baseRef, YAML_FLOW_CLI_DIR, {
|
|
300
|
+
notifyChannel,
|
|
301
|
+
});
|
|
302
|
+
// In the server context the drain loop is driven in-process; suppress the
|
|
303
|
+
// detached CLI spawn that the FS adapter would otherwise fire as a continuation.
|
|
304
|
+
boardAdapter.requestProcessAccumulated = () => {};
|
|
305
|
+
// Separate artifacts adapter rooted at cardsDir (preserves old FS layout where
|
|
306
|
+
// chats/files live under cardsDir rather than boardDir)
|
|
307
|
+
const artifactsRef = parseRef(serializeRef({ kind: 'fs-path', value: cardsDir }));
|
|
308
|
+
const artifactsAdapter = createFsBoardPlatformAdapter(artifactsRef, YAML_FLOW_CLI_DIR, { suppressSpawn: true });
|
|
309
|
+
|
|
310
|
+
const cardStoreRef = serializeRef({ kind: 'fs-path', value: cardsDir });
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
label,
|
|
314
|
+
boardAdapter,
|
|
315
|
+
artifactsAdapter,
|
|
316
|
+
baseRef,
|
|
317
|
+
cardStoreRef,
|
|
318
|
+
outputsStoreRef: serializeRef({ kind: 'fs-path', value: path.join(path.dirname(boardDir), 'runtime-out', '.outputs') }),
|
|
319
|
+
notifyRef: { kind: 'named-pipe', value: namedPipePath(notifyChannel) },
|
|
320
|
+
taskExecutorRef: makeExecutionRef(taskExecPath, 'task-executor'),
|
|
321
|
+
chatHandlerRef: makeExecutionRef(chatHandlerPath, 'chat-handler'),
|
|
322
|
+
inferenceAdapterRef: makeExecutionRef(infAdapterPath, 'inference-adapter'),
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
84
326
|
const runtime = createMultiBoardServerRuntime({
|
|
85
|
-
apiBasePath
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
327
|
+
apiBasePath,
|
|
328
|
+
serverMetaStore,
|
|
329
|
+
logger,
|
|
330
|
+
boardRuntimeFactory: (boardId, entry) => {
|
|
331
|
+
const cardsDir = typeof entry.cardsDir === 'string' ? path.resolve(entry.cardsDir) : defaultCardsDir;
|
|
332
|
+
const boardRoot = path.join(setupDir, `board-${boardId}`);
|
|
333
|
+
const boardDir = path.join(boardRoot, 'runtime');
|
|
334
|
+
|
|
335
|
+
const taskExecPath = typeof entry.taskExecutorPath === 'string' ? entry.taskExecutorPath : defaultTaskExecutorPath;
|
|
336
|
+
const chatHandlerPath_ = typeof entry.chatHandlerPath === 'string' ? entry.chatHandlerPath : defaultChatHandlerPath;
|
|
337
|
+
const infAdapterPath = typeof entry.inferenceAdapterPath === 'string' ? entry.inferenceAdapterPath : defaultInferenceAdapterPath;
|
|
338
|
+
const stepMachinePath = typeof entry.stepMachineCliPath === 'string' ? entry.stepMachineCliPath : defaultStepMachineCliPath;
|
|
339
|
+
|
|
340
|
+
const gandalfCardsDir_ = typeof entry.gandalfCardsDir === 'string' ? path.resolve(entry.gandalfCardsDir) : defaultGandalfCardsDir;
|
|
341
|
+
const gandalfTaskExecPath = typeof entry.gandalfTaskExecutorPath === 'string' ? entry.gandalfTaskExecutorPath : defaultGandalfTaskExecutorPath;
|
|
342
|
+
const gandalfChatPath = typeof entry.gandalfChatHandlerPath === 'string' ? entry.gandalfChatHandlerPath : defaultGandalfChatHandlerPath;
|
|
343
|
+
const gandalfInfPath = typeof entry.gandalfInferenceAdapterPath === 'string' ? entry.gandalfInferenceAdapterPath : defaultGandalfInferenceAdapterPath;
|
|
344
|
+
|
|
345
|
+
const baseCfg = buildBoardContextConfig('base', boardDir, cardsDir, taskExecPath, chatHandlerPath_, infAdapterPath, boardId);
|
|
346
|
+
|
|
347
|
+
const boards = [baseCfg];
|
|
348
|
+
if (gandalfCardsDir_ && gandalfTaskExecPath) {
|
|
349
|
+
const gandalfBoardDir = path.join(boardRoot, 'gandalf-runtime');
|
|
350
|
+
const gandalfCfg = buildBoardContextConfig('gandalf', gandalfBoardDir, gandalfCardsDir_, gandalfTaskExecPath, gandalfChatPath, gandalfInfPath, boardId);
|
|
351
|
+
// Fix gandalf outputsStoreRef
|
|
352
|
+
gandalfCfg.outputsStoreRef = serializeRef({ kind: 'fs-path', value: path.join(boardRoot, 'gandalf-runtime-out', '.outputs') });
|
|
353
|
+
boards.push(gandalfCfg);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Store host config for demo-setup (FS paths are host concerns)
|
|
357
|
+
boardHostConfig.set(boardId, { cardsDir, gandalfCardsDir: gandalfCardsDir_, boardDir, boardRoot });
|
|
358
|
+
|
|
359
|
+
// Auto-run demo-setup (write copilot-instructions.md) at board init time,
|
|
360
|
+
// so clients no longer need a separate /demo-setup request before bootstrapping.
|
|
361
|
+
demoPrepSetup(boardId);
|
|
362
|
+
|
|
363
|
+
const singleBoardRuntime = createSingleBoardServerRuntime({
|
|
364
|
+
apiBasePath: `${apiBasePath}/${boardId}`,
|
|
365
|
+
boardId,
|
|
366
|
+
boards,
|
|
367
|
+
invocationAdapter,
|
|
368
|
+
notificationTransport,
|
|
369
|
+
logger,
|
|
370
|
+
serverUrl: `http://127.0.0.1:${PORT}`,
|
|
371
|
+
executionExtra: {
|
|
372
|
+
boardSetupRoot: boardRoot,
|
|
373
|
+
chatsBlobBasePath: path.join(cardsDir, 'chats'),
|
|
374
|
+
...(stepMachinePath ? { stepMachineCliPath: stepMachinePath } : {}),
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// Host concern (Part A): seed card store from FS source only if empty
|
|
379
|
+
const existing = singleBoardRuntime.cardStore.get({});
|
|
380
|
+
const isEmpty = existing.status !== 'success' || !existing.data?.cards?.length;
|
|
381
|
+
if (isEmpty) {
|
|
382
|
+
const cards = createFsCardSource(cardsDir).listCards();
|
|
383
|
+
if (cards.length) singleBoardRuntime.cardStore.set({ body: cards });
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return singleBoardRuntime;
|
|
387
|
+
},
|
|
97
388
|
});
|
|
98
389
|
|
|
390
|
+
// ---------------------------------------------------------------------------
|
|
391
|
+
// Reset
|
|
392
|
+
// ---------------------------------------------------------------------------
|
|
393
|
+
|
|
99
394
|
function resetRuntime() {
|
|
100
|
-
const setupDir = runtime.setupDir;
|
|
101
395
|
if (fs.existsSync(setupDir)) {
|
|
102
396
|
fs.rmSync(setupDir, { recursive: true, force: true });
|
|
103
397
|
console.log(`[demo-server] reset: wiped ${setupDir}`);
|
|
@@ -115,33 +409,24 @@ if (RESET_ON_START) {
|
|
|
115
409
|
resetRuntime();
|
|
116
410
|
}
|
|
117
411
|
|
|
118
|
-
const dispatch = createRuntimeRequestDispatcher(runtime);
|
|
119
|
-
|
|
120
|
-
// Board-id segment regex: /api/boards/:boardId/...
|
|
121
|
-
const BOARD_SEG_RE = /^\/api\/boards\/([^/]+)\/(.+)$/;
|
|
122
|
-
|
|
123
|
-
function jsonReply(res, status, payload) {
|
|
124
|
-
const body = JSON.stringify(payload);
|
|
125
|
-
res.writeHead(status, { ...CORS_HEADERS, 'Content-Type': 'application/json; charset=utf-8' });
|
|
126
|
-
res.end(body);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
412
|
// ---------------------------------------------------------------------------
|
|
130
|
-
//
|
|
131
|
-
// Writes
|
|
132
|
-
// Cards are served directly from cardsDir (no tmp copy needed).
|
|
413
|
+
// Demo-setup — host-level concern (not a runtime concern).
|
|
414
|
+
// Writes concatenated copilot-instructions.md at the board setup root.
|
|
133
415
|
// ---------------------------------------------------------------------------
|
|
134
416
|
|
|
135
|
-
const
|
|
417
|
+
const BOARD_SEG_RE = /^\/api\/boards\/([^/]+)\/(.+)$/;
|
|
418
|
+
const _demoPrepSetupDone = new Map();
|
|
136
419
|
|
|
137
|
-
function isDemoSetupDone(boardId
|
|
138
|
-
|
|
420
|
+
function isDemoSetupDone(boardId) {
|
|
421
|
+
const cfg = boardHostConfig.get(boardId);
|
|
422
|
+
return _demoPrepSetupDone.get(boardId) === true && cfg && fs.existsSync(cfg.cardsDir);
|
|
139
423
|
}
|
|
140
424
|
|
|
141
|
-
function demoPrepSetup(boardId
|
|
142
|
-
const
|
|
425
|
+
function demoPrepSetup(boardId) {
|
|
426
|
+
const cfg = boardHostConfig.get(boardId);
|
|
427
|
+
if (!cfg) return;
|
|
428
|
+
const { cardsDir, gandalfCardsDir, boardDir } = cfg;
|
|
143
429
|
|
|
144
|
-
// Concatenate agent-instructions*.md into copilot-instructions.md at boardSetupRoot.
|
|
145
430
|
const boardSetupRoot = path.dirname(boardDir);
|
|
146
431
|
fs.mkdirSync(boardSetupRoot, { recursive: true });
|
|
147
432
|
const srcDir = path.dirname(cardsDir);
|
|
@@ -158,22 +443,28 @@ function demoPrepSetup(boardId, service) {
|
|
|
158
443
|
_demoPrepSetupDone.set(boardId, true);
|
|
159
444
|
}
|
|
160
445
|
|
|
446
|
+
function jsonReply(res, status, payload) {
|
|
447
|
+
const body = JSON.stringify(payload);
|
|
448
|
+
res.writeHead(status, { ...CORS_HEADERS, 'Content-Type': 'application/json; charset=utf-8' });
|
|
449
|
+
res.end(body);
|
|
450
|
+
}
|
|
451
|
+
|
|
161
452
|
async function handleDemoSetup(req, res, boardId) {
|
|
162
453
|
try {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
setupPerformed = true;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
jsonReply(res, 200, { ok: true, setupPerformed });
|
|
454
|
+
// requireBoardService triggers the factory which runs demoPrepSetup automatically.
|
|
455
|
+
// This endpoint is kept for backward compatibility but setup is now done at board
|
|
456
|
+
// init time inside boardRuntimeFactory — no extra work needed here.
|
|
457
|
+
runtime.requireBoardService(boardId);
|
|
458
|
+
jsonReply(res, 200, { ok: true, setupPerformed: false });
|
|
172
459
|
} catch (err) {
|
|
173
460
|
jsonReply(res, err.statusCode || 500, { error: String((err && err.message) || err) });
|
|
174
461
|
}
|
|
175
462
|
}
|
|
176
463
|
|
|
464
|
+
// ---------------------------------------------------------------------------
|
|
465
|
+
// WorkIQ proxy — host-level concern
|
|
466
|
+
// ---------------------------------------------------------------------------
|
|
467
|
+
|
|
177
468
|
async function handleWorkiqAsk(req, res) {
|
|
178
469
|
let body = '';
|
|
179
470
|
for await (const chunk of req) body += chunk;
|
|
@@ -195,8 +486,6 @@ async function handleWorkiqAsk(req, res) {
|
|
|
195
486
|
return jsonReply(res, 503, { error: `WorkIQ CLI not found at: ${workiqJs}` });
|
|
196
487
|
}
|
|
197
488
|
|
|
198
|
-
// Server has TTY on stdin — workiq can produce output.
|
|
199
|
-
// Use async spawn (not spawnSync) to avoid blocking the event loop during the call.
|
|
200
489
|
await new Promise((resolve) => {
|
|
201
490
|
let stdout = '';
|
|
202
491
|
let stderr = '';
|
|
@@ -237,9 +526,14 @@ async function handleWorkiqAsk(req, res) {
|
|
|
237
526
|
});
|
|
238
527
|
}
|
|
239
528
|
|
|
529
|
+
// ---------------------------------------------------------------------------
|
|
530
|
+
// HTTP server
|
|
531
|
+
// ---------------------------------------------------------------------------
|
|
532
|
+
|
|
240
533
|
const server = http.createServer((req, res) => {
|
|
241
534
|
const method = req.method || 'GET';
|
|
242
|
-
const
|
|
535
|
+
const url = new URL(req.url || '/', 'http://localhost');
|
|
536
|
+
const pathname = url.pathname;
|
|
243
537
|
|
|
244
538
|
if (method === 'OPTIONS') {
|
|
245
539
|
res.writeHead(204, CORS_HEADERS);
|
|
@@ -260,25 +554,29 @@ const server = http.createServer((req, res) => {
|
|
|
260
554
|
return;
|
|
261
555
|
}
|
|
262
556
|
|
|
263
|
-
// All other /api/boards routes are handled by the
|
|
264
|
-
|
|
557
|
+
// All other /api/boards routes are handled by the platform-free runtime
|
|
558
|
+
runtime.handleApi(req, res, url).then((handled) => {
|
|
559
|
+
if (!handled) {
|
|
560
|
+
jsonReply(res, 404, { error: 'Not found' });
|
|
561
|
+
}
|
|
562
|
+
});
|
|
265
563
|
});
|
|
266
564
|
|
|
267
565
|
server.listen(PORT, '127.0.0.1', () => {
|
|
268
566
|
console.log(`[demo-server] listening on http://127.0.0.1:${PORT}`);
|
|
269
|
-
console.log(`[demo-server] setup dir: ${
|
|
270
|
-
console.log(`[demo-server]
|
|
567
|
+
console.log(`[demo-server] setup dir: ${setupDir}`);
|
|
568
|
+
console.log(`[demo-server] server-meta store: ${serverMetaRef}`);
|
|
271
569
|
console.log('[demo-server] endpoints:');
|
|
272
|
-
console.log(` GET ${
|
|
273
|
-
console.log(` POST ${
|
|
274
|
-
console.log(` GET ${
|
|
275
|
-
console.log(` GET ${
|
|
276
|
-
console.log(` GET ${
|
|
277
|
-
console.log(` GET ${
|
|
278
|
-
console.log(` PATCH ${
|
|
279
|
-
console.log(` POST ${
|
|
280
|
-
console.log(` POST ${
|
|
281
|
-
console.log(` GET ${
|
|
282
|
-
console.log(` GET ${
|
|
570
|
+
console.log(` GET ${apiBasePath} <- list boards`);
|
|
571
|
+
console.log(` POST ${apiBasePath} {id, label?} <- register board`);
|
|
572
|
+
console.log(` GET ${apiBasePath}/:boardId/demo-setup (no-op; setup now runs at board init)`);
|
|
573
|
+
console.log(` GET ${apiBasePath}/:boardId/init-board`);
|
|
574
|
+
console.log(` GET ${apiBasePath}/:boardId/sse`);
|
|
575
|
+
console.log(` GET ${apiBasePath}/:boardId/board-status`);
|
|
576
|
+
console.log(` PATCH ${apiBasePath}/:boardId/cards/:id`);
|
|
577
|
+
console.log(` POST ${apiBasePath}/:boardId/cards/:id/actions`);
|
|
578
|
+
console.log(` POST ${apiBasePath}/:boardId/cards/:id/files`);
|
|
579
|
+
console.log(` GET ${apiBasePath}/:boardId/cards/:id/files/:idx`);
|
|
580
|
+
console.log(` GET ${apiBasePath}/:boardId/cards/:id/chats`);
|
|
283
581
|
console.log(` POST /api/workiq/ask {query} <- WorkIQ (M365 Copilot) proxy`);
|
|
284
582
|
});
|