@axlsdk/studio 0.9.1 → 0.10.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/README.md +225 -7
- package/dist/{chunk-EG74VI3M.js → chunk-GKIPF45K.js} +206 -101
- package/dist/chunk-GKIPF45K.js.map +1 -0
- package/dist/cli.cjs +220 -116
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/client/assets/{index-DDlRZgfC.js → index-jeUeToM_.js} +13 -13
- package/dist/client/index.html +2 -2
- package/dist/connection-manager-DbOgO_gK.d.cts +75 -0
- package/dist/connection-manager-DbOgO_gK.d.ts +75 -0
- package/dist/middleware.cjs +1243 -0
- package/dist/middleware.cjs.map +1 -0
- package/dist/middleware.d.cts +131 -0
- package/dist/middleware.d.ts +131 -0
- package/dist/middleware.js +346 -0
- package/dist/middleware.js.map +1 -0
- package/dist/server/index.cjs +204 -100
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +12 -62
- package/dist/server/index.d.ts +12 -62
- package/dist/server/index.js +1 -1
- package/package.json +16 -4
- package/dist/chunk-EG74VI3M.js.map +0 -1
package/dist/server/index.cjs
CHANGED
|
@@ -25,6 +25,8 @@ __export(server_exports, {
|
|
|
25
25
|
createServer: () => createServer
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(server_exports);
|
|
28
|
+
var import_node_fs = require("fs");
|
|
29
|
+
var import_node_path = require("path");
|
|
28
30
|
var import_hono12 = require("hono");
|
|
29
31
|
var import_cors = require("hono/cors");
|
|
30
32
|
var import_serve_static = require("@hono/node-server/serve-static");
|
|
@@ -61,8 +63,13 @@ var ConnectionManager = class {
|
|
|
61
63
|
channels = /* @__PURE__ */ new Map();
|
|
62
64
|
/** ws -> set of subscribed channels (for cleanup) */
|
|
63
65
|
connections = /* @__PURE__ */ new Map();
|
|
66
|
+
maxConnections = 100;
|
|
64
67
|
/** Register a new WS connection. */
|
|
65
68
|
add(ws) {
|
|
69
|
+
if (this.connections.size >= this.maxConnections) {
|
|
70
|
+
ws.close?.();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
66
73
|
this.connections.set(ws, /* @__PURE__ */ new Set());
|
|
67
74
|
}
|
|
68
75
|
/** Remove a WS connection and all its subscriptions. */
|
|
@@ -78,15 +85,16 @@ var ConnectionManager = class {
|
|
|
78
85
|
}
|
|
79
86
|
this.connections.delete(ws);
|
|
80
87
|
}
|
|
81
|
-
/** Subscribe a connection to a channel. */
|
|
88
|
+
/** Subscribe a connection to a channel. No-op if the connection was not added. */
|
|
82
89
|
subscribe(ws, channel) {
|
|
90
|
+
if (!this.connections.has(ws)) return;
|
|
83
91
|
let subs = this.channels.get(channel);
|
|
84
92
|
if (!subs) {
|
|
85
93
|
subs = /* @__PURE__ */ new Set();
|
|
86
94
|
this.channels.set(channel, subs);
|
|
87
95
|
}
|
|
88
96
|
subs.add(ws);
|
|
89
|
-
this.connections.get(ws)
|
|
97
|
+
this.connections.get(ws).add(channel);
|
|
90
98
|
}
|
|
91
99
|
/** Unsubscribe a connection from a channel. */
|
|
92
100
|
unsubscribe(ws, channel) {
|
|
@@ -127,6 +135,14 @@ var ConnectionManager = class {
|
|
|
127
135
|
}
|
|
128
136
|
}
|
|
129
137
|
}
|
|
138
|
+
/** Close all connections and clear all state. Used during shutdown. */
|
|
139
|
+
closeAll() {
|
|
140
|
+
for (const ws of this.connections.keys()) {
|
|
141
|
+
ws.close?.();
|
|
142
|
+
}
|
|
143
|
+
this.connections.clear();
|
|
144
|
+
this.channels.clear();
|
|
145
|
+
}
|
|
130
146
|
/** Get the number of active connections. */
|
|
131
147
|
get connectionCount() {
|
|
132
148
|
return this.connections.size;
|
|
@@ -137,6 +153,52 @@ var ConnectionManager = class {
|
|
|
137
153
|
}
|
|
138
154
|
};
|
|
139
155
|
|
|
156
|
+
// src/server/ws/protocol.ts
|
|
157
|
+
var VALID_CHANNEL_PREFIXES = ["execution:", "trace:"];
|
|
158
|
+
var VALID_EXACT_CHANNELS = ["costs", "decisions"];
|
|
159
|
+
var MAX_CHANNEL_LENGTH = 256;
|
|
160
|
+
function handleWsMessage(raw, socket, connMgr) {
|
|
161
|
+
if (raw.length > 65536) {
|
|
162
|
+
return JSON.stringify({ type: "error", message: "Message too large" });
|
|
163
|
+
}
|
|
164
|
+
let msg;
|
|
165
|
+
try {
|
|
166
|
+
msg = JSON.parse(raw);
|
|
167
|
+
} catch {
|
|
168
|
+
return JSON.stringify({ type: "error", message: "Invalid JSON" });
|
|
169
|
+
}
|
|
170
|
+
switch (msg.type) {
|
|
171
|
+
case "subscribe": {
|
|
172
|
+
const error = validateChannel(msg.channel);
|
|
173
|
+
if (error) return JSON.stringify({ type: "error", message: error });
|
|
174
|
+
connMgr.subscribe(socket, msg.channel);
|
|
175
|
+
return JSON.stringify({ type: "subscribed", channel: msg.channel });
|
|
176
|
+
}
|
|
177
|
+
case "unsubscribe": {
|
|
178
|
+
const error = validateChannel(msg.channel);
|
|
179
|
+
if (error) return JSON.stringify({ type: "error", message: error });
|
|
180
|
+
connMgr.unsubscribe(socket, msg.channel);
|
|
181
|
+
return JSON.stringify({ type: "unsubscribed", channel: msg.channel });
|
|
182
|
+
}
|
|
183
|
+
case "ping":
|
|
184
|
+
return JSON.stringify({ type: "pong" });
|
|
185
|
+
default:
|
|
186
|
+
return JSON.stringify({ type: "error", message: "Unknown message type" });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function validateChannel(channel) {
|
|
190
|
+
if (typeof channel !== "string" || !channel) {
|
|
191
|
+
return "Missing or invalid channel";
|
|
192
|
+
}
|
|
193
|
+
if (channel.length > MAX_CHANNEL_LENGTH) {
|
|
194
|
+
return `Channel name exceeds ${MAX_CHANNEL_LENGTH} characters`;
|
|
195
|
+
}
|
|
196
|
+
if (!VALID_EXACT_CHANNELS.includes(channel) && !VALID_CHANNEL_PREFIXES.some((p) => channel.startsWith(p))) {
|
|
197
|
+
return `Invalid channel: ${channel}`;
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
|
|
140
202
|
// src/server/ws/handler.ts
|
|
141
203
|
function createWsHandlers(connMgr) {
|
|
142
204
|
return {
|
|
@@ -144,37 +206,8 @@ function createWsHandlers(connMgr) {
|
|
|
144
206
|
connMgr.add(ws);
|
|
145
207
|
},
|
|
146
208
|
onMessage(event, ws) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
msg = JSON.parse(String(event.data));
|
|
150
|
-
} catch {
|
|
151
|
-
const err = { type: "error", message: "Invalid JSON" };
|
|
152
|
-
ws.send(JSON.stringify(err));
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
switch (msg.type) {
|
|
156
|
-
case "subscribe": {
|
|
157
|
-
connMgr.subscribe(ws, msg.channel);
|
|
158
|
-
const reply = { type: "subscribed", channel: msg.channel };
|
|
159
|
-
ws.send(JSON.stringify(reply));
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
case "unsubscribe": {
|
|
163
|
-
connMgr.unsubscribe(ws, msg.channel);
|
|
164
|
-
const reply = { type: "unsubscribed", channel: msg.channel };
|
|
165
|
-
ws.send(JSON.stringify(reply));
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
168
|
-
case "ping": {
|
|
169
|
-
const reply = { type: "pong" };
|
|
170
|
-
ws.send(JSON.stringify(reply));
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
default: {
|
|
174
|
-
const err = { type: "error", message: `Unknown message type` };
|
|
175
|
-
ws.send(JSON.stringify(err));
|
|
176
|
-
}
|
|
177
|
-
}
|
|
209
|
+
const reply = handleWsMessage(String(event.data), ws, connMgr);
|
|
210
|
+
if (reply) ws.send(reply);
|
|
178
211
|
},
|
|
179
212
|
onClose(_event, ws) {
|
|
180
213
|
connMgr.remove(ws);
|
|
@@ -269,8 +302,8 @@ var health_default = app;
|
|
|
269
302
|
var import_hono2 = require("hono");
|
|
270
303
|
var import_axl = require("@axlsdk/axl");
|
|
271
304
|
function createWorkflowRoutes(connMgr) {
|
|
272
|
-
const
|
|
273
|
-
|
|
305
|
+
const app7 = new import_hono2.Hono();
|
|
306
|
+
app7.get("/workflows", (c) => {
|
|
274
307
|
const runtime = c.get("runtime");
|
|
275
308
|
const workflows = runtime.getWorkflows().map((w) => ({
|
|
276
309
|
name: w.name,
|
|
@@ -279,7 +312,7 @@ function createWorkflowRoutes(connMgr) {
|
|
|
279
312
|
}));
|
|
280
313
|
return c.json({ ok: true, data: workflows });
|
|
281
314
|
});
|
|
282
|
-
|
|
315
|
+
app7.get("/workflows/:name", (c) => {
|
|
283
316
|
const runtime = c.get("runtime");
|
|
284
317
|
const name = c.req.param("name");
|
|
285
318
|
const workflow = runtime.getWorkflow(name);
|
|
@@ -298,7 +331,7 @@ function createWorkflowRoutes(connMgr) {
|
|
|
298
331
|
}
|
|
299
332
|
});
|
|
300
333
|
});
|
|
301
|
-
|
|
334
|
+
app7.post("/workflows/:name/execute", async (c) => {
|
|
302
335
|
const runtime = c.get("runtime");
|
|
303
336
|
const name = c.req.param("name");
|
|
304
337
|
const workflow = runtime.getWorkflow(name);
|
|
@@ -329,7 +362,7 @@ function createWorkflowRoutes(connMgr) {
|
|
|
329
362
|
const result = await runtime.execute(name, body.input ?? {}, { metadata: body.metadata });
|
|
330
363
|
return c.json({ ok: true, data: { result } });
|
|
331
364
|
});
|
|
332
|
-
return
|
|
365
|
+
return app7;
|
|
333
366
|
}
|
|
334
367
|
|
|
335
368
|
// src/server/routes/executions.ts
|
|
@@ -363,8 +396,8 @@ var executions_default = app2;
|
|
|
363
396
|
// src/server/routes/sessions.ts
|
|
364
397
|
var import_hono4 = require("hono");
|
|
365
398
|
function createSessionRoutes(connMgr) {
|
|
366
|
-
const
|
|
367
|
-
|
|
399
|
+
const app7 = new import_hono4.Hono();
|
|
400
|
+
app7.get("/sessions", async (c) => {
|
|
368
401
|
const runtime = c.get("runtime");
|
|
369
402
|
const store = runtime.getStateStore();
|
|
370
403
|
if (!store.listSessions) {
|
|
@@ -378,7 +411,7 @@ function createSessionRoutes(connMgr) {
|
|
|
378
411
|
}
|
|
379
412
|
return c.json({ ok: true, data: sessions });
|
|
380
413
|
});
|
|
381
|
-
|
|
414
|
+
app7.get("/sessions/:id", async (c) => {
|
|
382
415
|
const runtime = c.get("runtime");
|
|
383
416
|
const store = runtime.getStateStore();
|
|
384
417
|
const id = c.req.param("id");
|
|
@@ -386,7 +419,7 @@ function createSessionRoutes(connMgr) {
|
|
|
386
419
|
const handoffHistory = await store.getSessionMeta(id, "handoffHistory");
|
|
387
420
|
return c.json({ ok: true, data: { id, history, handoffHistory: handoffHistory ?? [] } });
|
|
388
421
|
});
|
|
389
|
-
|
|
422
|
+
app7.post("/sessions/:id/send", async (c) => {
|
|
390
423
|
const runtime = c.get("runtime");
|
|
391
424
|
const id = c.req.param("id");
|
|
392
425
|
const body = await c.req.json();
|
|
@@ -394,7 +427,7 @@ function createSessionRoutes(connMgr) {
|
|
|
394
427
|
const result = await session.send(body.workflow, body.message);
|
|
395
428
|
return c.json({ ok: true, data: { result } });
|
|
396
429
|
});
|
|
397
|
-
|
|
430
|
+
app7.post("/sessions/:id/stream", async (c) => {
|
|
398
431
|
const runtime = c.get("runtime");
|
|
399
432
|
const id = c.req.param("id");
|
|
400
433
|
const body = await c.req.json();
|
|
@@ -415,14 +448,14 @@ function createSessionRoutes(connMgr) {
|
|
|
415
448
|
})();
|
|
416
449
|
return c.json({ ok: true, data: { executionId, streaming: true } });
|
|
417
450
|
});
|
|
418
|
-
|
|
451
|
+
app7.delete("/sessions/:id", async (c) => {
|
|
419
452
|
const runtime = c.get("runtime");
|
|
420
453
|
const store = runtime.getStateStore();
|
|
421
454
|
const id = c.req.param("id");
|
|
422
455
|
await store.deleteSession(id);
|
|
423
456
|
return c.json({ ok: true, data: { deleted: true } });
|
|
424
457
|
});
|
|
425
|
-
return
|
|
458
|
+
return app7;
|
|
426
459
|
}
|
|
427
460
|
|
|
428
461
|
// src/server/routes/agents.ts
|
|
@@ -655,61 +688,65 @@ var decisions_default = app6;
|
|
|
655
688
|
// src/server/routes/costs.ts
|
|
656
689
|
var import_hono9 = require("hono");
|
|
657
690
|
function createCostRoutes(costAggregator) {
|
|
658
|
-
const
|
|
659
|
-
|
|
691
|
+
const app7 = new import_hono9.Hono();
|
|
692
|
+
app7.get("/costs", (c) => {
|
|
660
693
|
return c.json({ ok: true, data: costAggregator.getData() });
|
|
661
694
|
});
|
|
662
|
-
|
|
695
|
+
app7.post("/costs/reset", (c) => {
|
|
663
696
|
costAggregator.reset();
|
|
664
697
|
return c.json({ ok: true, data: { reset: true } });
|
|
665
698
|
});
|
|
666
|
-
return
|
|
699
|
+
return app7;
|
|
667
700
|
}
|
|
668
701
|
|
|
669
702
|
// src/server/routes/evals.ts
|
|
670
703
|
var import_hono10 = require("hono");
|
|
671
|
-
|
|
672
|
-
app7
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
704
|
+
function createEvalRoutes(evalLoader) {
|
|
705
|
+
const app7 = new import_hono10.Hono();
|
|
706
|
+
app7.get("/evals", async (c) => {
|
|
707
|
+
if (evalLoader) await evalLoader();
|
|
708
|
+
const runtime = c.get("runtime");
|
|
709
|
+
const evals = runtime.getRegisteredEvals();
|
|
710
|
+
return c.json({ ok: true, data: evals });
|
|
711
|
+
});
|
|
712
|
+
app7.post("/evals/:name/run", async (c) => {
|
|
713
|
+
if (evalLoader) await evalLoader();
|
|
714
|
+
const runtime = c.get("runtime");
|
|
715
|
+
const name = c.req.param("name");
|
|
716
|
+
const entry = runtime.getRegisteredEval(name);
|
|
717
|
+
if (!entry) {
|
|
718
|
+
return c.json(
|
|
719
|
+
{ ok: false, error: { code: "NOT_FOUND", message: `Eval "${name}" not found` } },
|
|
720
|
+
404
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
try {
|
|
724
|
+
const result = await runtime.runRegisteredEval(name);
|
|
725
|
+
return c.json({ ok: true, data: result });
|
|
726
|
+
} catch (err) {
|
|
727
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
728
|
+
return c.json({ ok: false, error: { code: "EVAL_ERROR", message } }, 400);
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
app7.post("/evals/compare", async (c) => {
|
|
732
|
+
const runtime = c.get("runtime");
|
|
733
|
+
const body = await c.req.json();
|
|
734
|
+
try {
|
|
735
|
+
const result = await runtime.evalCompare(body.baseline, body.candidate);
|
|
736
|
+
return c.json({ ok: true, data: result });
|
|
737
|
+
} catch (err) {
|
|
738
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
739
|
+
return c.json({ ok: false, error: { code: "EVAL_ERROR", message } }, 400);
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
return app7;
|
|
743
|
+
}
|
|
707
744
|
|
|
708
745
|
// src/server/routes/playground.ts
|
|
709
746
|
var import_hono11 = require("hono");
|
|
710
747
|
function createPlaygroundRoutes(connMgr) {
|
|
711
|
-
const
|
|
712
|
-
|
|
748
|
+
const app7 = new import_hono11.Hono();
|
|
749
|
+
app7.post("/playground/chat", async (c) => {
|
|
713
750
|
const runtime = c.get("runtime");
|
|
714
751
|
const body = await c.req.json();
|
|
715
752
|
const workflowName = body.workflow ?? runtime.getWorkflowNames()[0];
|
|
@@ -740,21 +777,53 @@ function createPlaygroundRoutes(connMgr) {
|
|
|
740
777
|
data: { sessionId, executionId, streaming: true }
|
|
741
778
|
});
|
|
742
779
|
});
|
|
743
|
-
return
|
|
780
|
+
return app7;
|
|
744
781
|
}
|
|
745
782
|
|
|
746
783
|
// src/server/index.ts
|
|
747
784
|
function createServer(options) {
|
|
748
|
-
const { runtime, staticRoot } = options;
|
|
749
|
-
const
|
|
785
|
+
const { runtime, staticRoot, basePath = "", readOnly = false } = options;
|
|
786
|
+
const app7 = new import_hono12.Hono();
|
|
750
787
|
const connMgr = new ConnectionManager();
|
|
751
788
|
const costAggregator = new CostAggregator(connMgr);
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
789
|
+
if (options.cors !== false) {
|
|
790
|
+
app7.use("*", (0, import_cors.cors)());
|
|
791
|
+
}
|
|
792
|
+
app7.use("*", errorHandler);
|
|
793
|
+
app7.use("*", async (c, next) => {
|
|
755
794
|
c.set("runtime", runtime);
|
|
756
795
|
await next();
|
|
757
796
|
});
|
|
797
|
+
if (readOnly) {
|
|
798
|
+
const blocked = [
|
|
799
|
+
"POST /api/workflows",
|
|
800
|
+
"POST /api/executions",
|
|
801
|
+
"POST /api/sessions",
|
|
802
|
+
"DELETE /api/sessions",
|
|
803
|
+
"PUT /api/memory",
|
|
804
|
+
"DELETE /api/memory",
|
|
805
|
+
"POST /api/decisions",
|
|
806
|
+
"POST /api/costs",
|
|
807
|
+
"POST /api/tools",
|
|
808
|
+
"POST /api/evals",
|
|
809
|
+
"POST /api/playground"
|
|
810
|
+
];
|
|
811
|
+
app7.use("/api/*", async (c, next) => {
|
|
812
|
+
const apiIdx = c.req.path.indexOf("/api/");
|
|
813
|
+
const apiPath = apiIdx >= 0 ? c.req.path.slice(apiIdx) : c.req.path;
|
|
814
|
+
const key = `${c.req.method} ${apiPath}`;
|
|
815
|
+
if (blocked.some((b) => key.startsWith(b))) {
|
|
816
|
+
return c.json(
|
|
817
|
+
{
|
|
818
|
+
ok: false,
|
|
819
|
+
error: { code: "READ_ONLY", message: "Studio is mounted in read-only mode" }
|
|
820
|
+
},
|
|
821
|
+
405
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
await next();
|
|
825
|
+
});
|
|
826
|
+
}
|
|
758
827
|
const api = new import_hono12.Hono();
|
|
759
828
|
api.route("/", health_default);
|
|
760
829
|
api.route("/", createWorkflowRoutes(connMgr));
|
|
@@ -765,10 +834,10 @@ function createServer(options) {
|
|
|
765
834
|
api.route("/", memory_default);
|
|
766
835
|
api.route("/", decisions_default);
|
|
767
836
|
api.route("/", createCostRoutes(costAggregator));
|
|
768
|
-
api.route("/",
|
|
837
|
+
api.route("/", createEvalRoutes(options.evalLoader));
|
|
769
838
|
api.route("/", createPlaygroundRoutes(connMgr));
|
|
770
|
-
|
|
771
|
-
|
|
839
|
+
app7.route("/api", api);
|
|
840
|
+
const traceListener = (event) => {
|
|
772
841
|
const traceEvent = event;
|
|
773
842
|
if (traceEvent.executionId) {
|
|
774
843
|
connMgr.broadcastWithWildcard(`trace:${traceEvent.executionId}`, traceEvent);
|
|
@@ -777,12 +846,47 @@ function createServer(options) {
|
|
|
777
846
|
if (traceEvent.type === "await_human") {
|
|
778
847
|
connMgr.broadcast("decisions", traceEvent);
|
|
779
848
|
}
|
|
780
|
-
}
|
|
849
|
+
};
|
|
850
|
+
runtime.on("trace", traceListener);
|
|
781
851
|
if (staticRoot) {
|
|
782
|
-
|
|
783
|
-
|
|
852
|
+
app7.use(
|
|
853
|
+
"/*",
|
|
854
|
+
(0, import_serve_static.serveStatic)({
|
|
855
|
+
root: staticRoot,
|
|
856
|
+
rewriteRequestPath: basePath ? (path) => path.startsWith(basePath) ? path.slice(basePath.length) || "/" : path : void 0
|
|
857
|
+
})
|
|
858
|
+
);
|
|
859
|
+
if (basePath) {
|
|
860
|
+
const indexPath = (0, import_node_path.resolve)(staticRoot, "index.html");
|
|
861
|
+
if (!(0, import_node_fs.existsSync)(indexPath)) {
|
|
862
|
+
console.warn(`[axl-studio] index.html not found at ${indexPath}`);
|
|
863
|
+
} else {
|
|
864
|
+
const indexHtml = (0, import_node_fs.readFileSync)(indexPath, "utf-8");
|
|
865
|
+
const safeBasePath = JSON.stringify(basePath).replace(/</g, "\\u003c");
|
|
866
|
+
const injectedHtml = indexHtml.replace(
|
|
867
|
+
"</head>",
|
|
868
|
+
`<base href="${basePath}/">
|
|
869
|
+
<script>window.__AXL_STUDIO_BASE__=${safeBasePath}</script>
|
|
870
|
+
</head>`
|
|
871
|
+
);
|
|
872
|
+
if (injectedHtml === indexHtml) {
|
|
873
|
+
console.warn(
|
|
874
|
+
"[axl-studio] Could not inject basePath into index.html \u2014 </head> tag not found. The SPA may not route correctly."
|
|
875
|
+
);
|
|
876
|
+
}
|
|
877
|
+
app7.get("*", (c) => c.html(injectedHtml));
|
|
878
|
+
}
|
|
879
|
+
} else {
|
|
880
|
+
app7.get("*", (0, import_serve_static.serveStatic)({ root: staticRoot, path: "/index.html" }));
|
|
881
|
+
}
|
|
784
882
|
}
|
|
785
|
-
return {
|
|
883
|
+
return {
|
|
884
|
+
app: app7,
|
|
885
|
+
connMgr,
|
|
886
|
+
costAggregator,
|
|
887
|
+
createWsHandlers: () => createWsHandlers(connMgr),
|
|
888
|
+
traceListener
|
|
889
|
+
};
|
|
786
890
|
}
|
|
787
891
|
// Annotate the CommonJS export names for ESM import in node:
|
|
788
892
|
0 && (module.exports = {
|