@rubytech/create-maxy-code 0.1.88 → 0.1.90
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/dist/__tests__/entitlement-flag.test.js +43 -0
- package/dist/__tests__/tier-flag.test.js +53 -0
- package/dist/index.js +68 -0
- package/dist/tier-flag.js +85 -0
- package/package.json +1 -1
- package/payload/platform/lib/admin-conversation-purge/dist/index.d.ts +54 -0
- package/payload/platform/lib/admin-conversation-purge/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/admin-conversation-purge/dist/index.js +84 -0
- package/payload/platform/lib/admin-conversation-purge/dist/index.js.map +1 -0
- package/payload/platform/lib/admin-conversation-purge/src/index.ts +120 -0
- package/payload/platform/lib/admin-conversation-purge/tsconfig.json +8 -0
- package/payload/platform/lib/graph-trash/dist/index.d.ts +12 -1
- package/payload/platform/lib/graph-trash/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-trash/dist/index.js +8 -1
- package/payload/platform/lib/graph-trash/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-trash/src/index.ts +20 -2
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
- package/payload/platform/plugins/admin/PLUGIN.md +1 -0
- package/payload/platform/plugins/admin/hooks/__tests__/askuserquestion-investigate-gate.test.sh +176 -0
- package/payload/platform/plugins/admin/hooks/askuserquestion-investigate-gate.sh +257 -0
- package/payload/platform/plugins/admin/skills/admin-user-management/SKILL.md +2 -0
- package/payload/platform/plugins/docs/references/admin-session.md +5 -1
- package/payload/platform/plugins/docs/references/linkedin-extension.md +49 -0
- package/payload/platform/plugins/linkedin-extension/.claude-plugin/plugin.json +8 -0
- package/payload/platform/plugins/linkedin-extension/PLUGIN.md +58 -0
- package/payload/platform/plugins/linkedin-extension/extension/README.md +44 -0
- package/payload/platform/plugins/linkedin-extension/extension/__tests__/fixtures/profile.html +34 -0
- package/payload/platform/plugins/linkedin-extension/extension/__tests__/fixtures/thread.html +36 -0
- package/payload/platform/plugins/linkedin-extension/extension/assets/pill.css +52 -0
- package/payload/platform/plugins/linkedin-extension/extension/background/sw.js +60 -0
- package/payload/platform/plugins/linkedin-extension/extension/content/extractors.js +127 -0
- package/payload/platform/plugins/linkedin-extension/extension/content/profile.js +82 -0
- package/payload/platform/plugins/linkedin-extension/extension/content/thread.js +84 -0
- package/payload/platform/plugins/linkedin-extension/extension/manifest.json +32 -0
- package/payload/platform/plugins/linkedin-extension/extension/options/options.html +33 -0
- package/payload/platform/plugins/linkedin-extension/extension/options/options.js +30 -0
- package/payload/platform/plugins/linkedin-extension/skills/linkedin-extension/SKILL.md +91 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.d.ts +14 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.js +28 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-admin-conversation.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-admin-conversation.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-admin-conversation.test.js +168 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-empty-trash-admin-conversation.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.d.ts +22 -3
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js +61 -13
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js.map +1 -1
- package/payload/platform/scripts/seed-neo4j.sh +12 -0
- package/payload/platform/templates/agents/admin/IDENTITY.md +3 -1
- package/payload/platform/templates/specialists/agents/database-operator.md +6 -2
- package/payload/server/public/assets/{ChatInput-BzjU6OoA.css → ChatInput-dLWJ0Q8I.css} +1 -1
- package/payload/server/public/assets/{Checkbox-BWLS5Isf.js → Checkbox-Bx8mRHQ3.js} +1 -1
- package/payload/server/public/assets/{admin-DjU0q63n.js → admin-C57bDUgs.js} +6 -6
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-lcncWUol.js → architectureDiagram-Q4EWVU46-BEW_bD50.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-SqlxCp6m.js → blockDiagram-DXYQGD6D-DFLT98C3.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DWzvXvDc.js → c4Diagram-AHTNJAMY-BemKtROA.js} +1 -1
- package/payload/server/public/assets/channel-CfpByn-m.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-Bz-tPZhS.js → chunk-336JU56O-BL8fGJ7_.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-MYkbqx1u.js → chunk-426QAEUC-BD6by0MP.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-DfZRQtaZ.js → chunk-4TB4RGXK-DX-cb6Nd.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-BFMrOiNe.js → chunk-5FUZZQ4R-B2QqtIZS.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-64laDovl.js → chunk-5PVQY5BW-CzJWmsmd.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-dClAHBNd.js → chunk-EDXVE4YY-DP9vcvEU.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-Bz4gXG1p.js → chunk-ENJZ2VHE-D5xWEjF0.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-D5pWrJcN.js → chunk-ICPOFSXX-AKduf9o4.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-BCiWtqaK.js → chunk-OYMX7WX6-D6jsVNyQ.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-Brql314T.js → chunk-U2HBQHQK-BNAnTYh8.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-C-79tMym.js → chunk-X2U36JSP-UdQhYDnh.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-G4idHEoZ.js → chunk-YZCP3GAM-DSSmSGmS.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-DyHGASIn.js → chunk-ZZ45TVLE-Czm7IDMC.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DNc9R1IX.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DM1DQh8N.js +1 -0
- package/payload/server/public/assets/clone-BSrNdvLW.js +1 -0
- package/payload/server/public/assets/{dagre-KV5264BT--Bba_VRf.js → dagre-KV5264BT-CBuRCJE7.js} +1 -1
- package/payload/server/public/assets/{dagre-DfJ8a8tG.js → dagre-hSIMHJcO.js} +1 -1
- package/payload/server/public/assets/data-3n20lir5.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-CfUotMr9.js → diagram-5BDNPKRD-dbMrH0le.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BWZJChPS.js → diagram-G4DWMVQ6-DBc6hs9a.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-BExS6IWb.js → diagram-MMDJMWI5-ubSGybUk.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-DQ4t_wIt.js → diagram-TYMM5635-WxL3cv-9.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-f1sfB-AQ.js → erDiagram-SMLLAGMA-CrBBOAN8.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CZexxT3v.js → flowDiagram-DWJPFMVM-CXUq5Hzt.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BNcFUX4K.js → ganttDiagram-T4ZO3ILL-vTCBnYVS.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-soyylUaR.js → gitGraphDiagram-UUTBAWPF-BHrj_bRa.js} +1 -1
- package/payload/server/public/assets/graph-ChwMpxn_.js +1 -0
- package/payload/server/public/assets/graph-labels-CUgJgIwl.js +1 -0
- package/payload/server/public/assets/{graphlib-B2ezMQY4.js → graphlib-CDO75l2X.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-4xmenbOP.js → infoDiagram-42DDH7IO-CcQdaOhi.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-C_D6CqVq.js → ishikawaDiagram-UXIWVN3A-3KvltFgV.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-DUDx0c35.js → journeyDiagram-VCZTEJTY-DZCXaGFE.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BNr7ErhZ.js → kanban-definition-6JOO6SKY-DAIAKy1-.js} +1 -1
- package/payload/server/public/assets/{lib-iKom7FFe.js → lib-CCLURO3E.js} +1 -1
- package/payload/server/public/assets/{line-Dvs5wrj5.js → line-C8iCE2Wx.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-D0ksZQlW.js → mermaid-parser.core-ElvUhnV9.js} +1 -1
- package/payload/server/public/assets/{mermaid.core--Btu4mYy.js → mermaid.core-7dSH31Ao.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DfyZTghB.js → mindmap-definition-QFDTVHPH-FZ0rcfac.js} +1 -1
- package/payload/server/public/assets/{page-BnBmdRbo.js → page-D3bFmqF4.js} +1 -1
- package/payload/server/public/assets/{page-x6ZXWwMx.js → page-DNjUtT5q.js} +18 -17
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-BiG9YoLj.js → pieDiagram-DEJITSTG-CDuvMZbO.js} +1 -1
- package/payload/server/public/assets/{public-DW7yINk7.js → public-g_2skbnY.js} +3 -3
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CVufUsie.js → quadrantDiagram-34T5L4WZ-xDjhkqNc.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-UKCptCPk.js → requirementDiagram-MS252O5E-BPKpyT0n.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-e8iZYL5P.js → sankeyDiagram-XADWPNL6-BvFIrihC.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CfZqVRxe.js → sequenceDiagram-FGHM5R23-C6G1oAE0.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DrWX8OY8.js → stateDiagram-FHFEXIEX-DbOJT_Xh.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Ce4GFk-H.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Blec2Yhc.js → timeline-definition-GMOUNBTQ-D1DSxHh6.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BtACuGgu.js → vennDiagram-DHZGUBPP-BYoSeMdo.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BWT7orYV.js → wardleyDiagram-NUSXRM2D-DH3kZdea.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DBzoIRiJ.js → xychartDiagram-5P7HB3ND-C6MROMLG.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +531 -118
- package/payload/server/public/assets/channel-dZdJT-Ou.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CP8AWLB9.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-bUe6tAo9.js +0 -1
- package/payload/server/public/assets/clone-gXHQCPU0.js +0 -1
- package/payload/server/public/assets/data-Bt6BTjvP.js +0 -1
- package/payload/server/public/assets/graph-labels-BeDsoEVY.js +0 -1
- package/payload/server/public/assets/graph-szVcmw8D.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CvKXSO97.js +0 -1
- /package/payload/server/public/assets/{ChatInput-AR8ym-HW.js → ChatInput-DoS80kaC.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -344,8 +344,11 @@ var require_dist = __commonJS({
|
|
|
344
344
|
try {
|
|
345
345
|
await onEmpty(c);
|
|
346
346
|
} catch (err) {
|
|
347
|
-
|
|
347
|
+
const id8 = c.elementId.slice(0, 8);
|
|
348
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
349
|
+
process.stderr.write(`[trash:empty-run] reason=onEmpty-failed elementId=${id8} labels=${c.labels.join(",")} message=${message}
|
|
348
350
|
`);
|
|
351
|
+
continue;
|
|
349
352
|
}
|
|
350
353
|
}
|
|
351
354
|
await session.run(`MATCH (n) WHERE elementId(n) = $eid DETACH DELETE n`, { eid: c.elementId });
|
|
@@ -7191,29 +7194,22 @@ import crypto from "crypto";
|
|
|
7191
7194
|
import { resolve as resolvePath } from "path";
|
|
7192
7195
|
import { existsSync as existsSync13, mkdirSync as mkdirSync3, createWriteStream } from "fs";
|
|
7193
7196
|
|
|
7194
|
-
//
|
|
7195
|
-
async function
|
|
7196
|
-
const started = Date.now();
|
|
7197
|
+
// ../lib/admin-conversation-purge/src/index.ts
|
|
7198
|
+
async function purgeAdminConversationJsonls(args) {
|
|
7197
7199
|
const fetchImpl = args.fetchImpl ?? fetch;
|
|
7198
7200
|
const log = args.logger ?? ((line) => console.log(line));
|
|
7199
7201
|
const id8 = args.conversationId.slice(0, 8);
|
|
7200
|
-
let claudeSessionIds;
|
|
7201
|
-
try {
|
|
7202
|
-
claudeSessionIds = args.claudeSessionIds ?? await getConversationClaudeSessionIds(args.conversationId, args.accountId);
|
|
7203
|
-
} catch (err) {
|
|
7204
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
7205
|
-
log(`[admin-conversation-delete] conversationId=${id8} reason=graph-delete-failed claudeSessionIds-purged= message=transcript-resolve:${message}`);
|
|
7206
|
-
return { ok: false, reason: "graph-delete-failed", claudeSessionIdsPurged: [], message };
|
|
7207
|
-
}
|
|
7208
7202
|
const purged = [];
|
|
7209
|
-
for (const sessionId of claudeSessionIds) {
|
|
7203
|
+
for (const sessionId of args.claudeSessionIds) {
|
|
7210
7204
|
const url = `${args.managerBase}/${encodeURIComponent(sessionId)}`;
|
|
7211
7205
|
let res;
|
|
7212
7206
|
try {
|
|
7213
7207
|
res = await fetchImpl(url, { method: "DELETE" });
|
|
7214
7208
|
} catch (err) {
|
|
7215
7209
|
const message2 = err instanceof Error ? err.message : String(err);
|
|
7216
|
-
log(
|
|
7210
|
+
log(
|
|
7211
|
+
`[admin-conversation-delete] conversationId=${id8} reason=jsonl-purge-failed claudeSessionId=${sessionId.slice(0, 8)} message=${message2}`
|
|
7212
|
+
);
|
|
7217
7213
|
return {
|
|
7218
7214
|
ok: false,
|
|
7219
7215
|
reason: "jsonl-purge-failed",
|
|
@@ -7228,8 +7224,15 @@ async function cascadeAdminConversationDelete(args) {
|
|
|
7228
7224
|
continue;
|
|
7229
7225
|
}
|
|
7230
7226
|
if (res.status === 409) {
|
|
7231
|
-
log(
|
|
7232
|
-
|
|
7227
|
+
log(
|
|
7228
|
+
`[admin-conversation-delete] conversationId=${id8} reason=pty-still-alive claudeSessionId=${sessionId.slice(0, 8)}`
|
|
7229
|
+
);
|
|
7230
|
+
return {
|
|
7231
|
+
ok: false,
|
|
7232
|
+
reason: "pty-still-alive",
|
|
7233
|
+
claudeSessionId: sessionId,
|
|
7234
|
+
claudeSessionIdsPurged: purged
|
|
7235
|
+
};
|
|
7233
7236
|
}
|
|
7234
7237
|
let message = `manager returned ${res.status}`;
|
|
7235
7238
|
try {
|
|
@@ -7238,7 +7241,9 @@ async function cascadeAdminConversationDelete(args) {
|
|
|
7238
7241
|
else if (typeof body.error === "string") message = body.error;
|
|
7239
7242
|
} catch {
|
|
7240
7243
|
}
|
|
7241
|
-
log(
|
|
7244
|
+
log(
|
|
7245
|
+
`[admin-conversation-delete] conversationId=${id8} reason=jsonl-purge-failed claudeSessionId=${sessionId.slice(0, 8)} message=${message}`
|
|
7246
|
+
);
|
|
7242
7247
|
return {
|
|
7243
7248
|
ok: false,
|
|
7244
7249
|
reason: "jsonl-purge-failed",
|
|
@@ -7248,6 +7253,45 @@ async function cascadeAdminConversationDelete(args) {
|
|
|
7248
7253
|
message
|
|
7249
7254
|
};
|
|
7250
7255
|
}
|
|
7256
|
+
return { ok: true, claudeSessionIdsPurged: purged };
|
|
7257
|
+
}
|
|
7258
|
+
|
|
7259
|
+
// app/lib/admin-conversation-cascade.ts
|
|
7260
|
+
async function cascadeAdminConversationDelete(args) {
|
|
7261
|
+
const started = Date.now();
|
|
7262
|
+
const fetchImpl = args.fetchImpl ?? fetch;
|
|
7263
|
+
const log = args.logger ?? ((line) => console.log(line));
|
|
7264
|
+
const id8 = args.conversationId.slice(0, 8);
|
|
7265
|
+
let claudeSessionIds;
|
|
7266
|
+
try {
|
|
7267
|
+
claudeSessionIds = args.claudeSessionIds ?? await getConversationClaudeSessionIds(args.conversationId, args.accountId);
|
|
7268
|
+
} catch (err) {
|
|
7269
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7270
|
+
log(`[admin-conversation-delete] conversationId=${id8} reason=graph-delete-failed claudeSessionIds-purged= message=transcript-resolve:${message}`);
|
|
7271
|
+
return { ok: false, reason: "graph-delete-failed", claudeSessionIdsPurged: [], message };
|
|
7272
|
+
}
|
|
7273
|
+
const purgeOutcome = await purgeAdminConversationJsonls({
|
|
7274
|
+
conversationId: args.conversationId,
|
|
7275
|
+
accountId: args.accountId,
|
|
7276
|
+
managerBase: args.managerBase,
|
|
7277
|
+
claudeSessionIds,
|
|
7278
|
+
fetchImpl,
|
|
7279
|
+
logger: log
|
|
7280
|
+
});
|
|
7281
|
+
if (!purgeOutcome.ok) {
|
|
7282
|
+
if (purgeOutcome.reason === "pty-still-alive") {
|
|
7283
|
+
return { ok: false, reason: "pty-still-alive", claudeSessionId: purgeOutcome.claudeSessionId };
|
|
7284
|
+
}
|
|
7285
|
+
return {
|
|
7286
|
+
ok: false,
|
|
7287
|
+
reason: "jsonl-purge-failed",
|
|
7288
|
+
claudeSessionId: purgeOutcome.claudeSessionId,
|
|
7289
|
+
claudeSessionIdsPurged: purgeOutcome.claudeSessionIdsPurged,
|
|
7290
|
+
status: purgeOutcome.status,
|
|
7291
|
+
message: purgeOutcome.message
|
|
7292
|
+
};
|
|
7293
|
+
}
|
|
7294
|
+
const purged = purgeOutcome.claudeSessionIdsPurged;
|
|
7251
7295
|
let found;
|
|
7252
7296
|
try {
|
|
7253
7297
|
({ found } = await deleteConversation(args.conversationId));
|
|
@@ -8695,13 +8739,13 @@ async function cdpNavigateNewTab(url, opts = {}) {
|
|
|
8695
8739
|
// server/routes/admin/device-browser.ts
|
|
8696
8740
|
var app18 = new Hono();
|
|
8697
8741
|
app18.post("/navigate", async (c) => {
|
|
8698
|
-
const
|
|
8742
|
+
const TAG22 = "[device-url:click]";
|
|
8699
8743
|
let body;
|
|
8700
8744
|
try {
|
|
8701
8745
|
body = await c.req.json();
|
|
8702
8746
|
} catch (err) {
|
|
8703
8747
|
const detail = err instanceof Error ? err.message : String(err);
|
|
8704
|
-
console.error(`${
|
|
8748
|
+
console.error(`${TAG22} reject reason=body-not-json detail=${detail} browser=fallback navigateResult=error`);
|
|
8705
8749
|
return c.json(
|
|
8706
8750
|
{ ok: false, navigateResult: "error", browser: "fallback", detail: "Request body was not valid JSON" },
|
|
8707
8751
|
400
|
|
@@ -8711,7 +8755,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8711
8755
|
const intent = typeof body.intent === "string" ? body.intent : "";
|
|
8712
8756
|
const hostname2 = typeof body.hostname === "string" ? body.hostname : "";
|
|
8713
8757
|
if (!url) {
|
|
8714
|
-
console.error(`${
|
|
8758
|
+
console.error(`${TAG22} reject reason=missing-url intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`);
|
|
8715
8759
|
return c.json(
|
|
8716
8760
|
{ ok: false, navigateResult: "error", browser: "fallback", detail: "url field is required" },
|
|
8717
8761
|
400
|
|
@@ -8721,7 +8765,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8721
8765
|
try {
|
|
8722
8766
|
parsed = new URL(url);
|
|
8723
8767
|
} catch {
|
|
8724
|
-
console.error(`${
|
|
8768
|
+
console.error(`${TAG22} reject reason=url-malformed intent=${JSON.stringify(intent)} url=${url} browser=fallback navigateResult=error`);
|
|
8725
8769
|
return c.json(
|
|
8726
8770
|
{ ok: false, navigateResult: "error", browser: "fallback", detail: "url is not a valid URL" },
|
|
8727
8771
|
400
|
|
@@ -8729,7 +8773,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8729
8773
|
}
|
|
8730
8774
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
8731
8775
|
console.error(
|
|
8732
|
-
`${
|
|
8776
|
+
`${TAG22} reject reason=scheme-not-allowed scheme=${parsed.protocol} intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`
|
|
8733
8777
|
);
|
|
8734
8778
|
return c.json(
|
|
8735
8779
|
{
|
|
@@ -8745,7 +8789,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8745
8789
|
const cdpOk = await ensureCdp(transport);
|
|
8746
8790
|
if (!cdpOk) {
|
|
8747
8791
|
console.error(
|
|
8748
|
-
`${
|
|
8792
|
+
`${TAG22} intent=${JSON.stringify(intent)} browser=fallback navigateResult=cdp-unreachable hostname=${JSON.stringify(hostname2)}`
|
|
8749
8793
|
);
|
|
8750
8794
|
return c.json(
|
|
8751
8795
|
{
|
|
@@ -8761,7 +8805,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8761
8805
|
const browser = outcome.result === "ok" ? "vnc" : "fallback";
|
|
8762
8806
|
const detailStr = outcome.detail ? ` detail=${JSON.stringify(outcome.detail.length > 230 ? outcome.detail.slice(0, 227) + "..." : outcome.detail)}` : "";
|
|
8763
8807
|
console.error(
|
|
8764
|
-
`${
|
|
8808
|
+
`${TAG22} intent=${JSON.stringify(intent)} browser=${browser} navigateResult=${outcome.result} hostname=${JSON.stringify(hostname2)} targetId=${outcome.targetId ?? "none"}${detailStr}`
|
|
8765
8809
|
);
|
|
8766
8810
|
if (outcome.result !== "ok") {
|
|
8767
8811
|
return c.json(
|
|
@@ -8792,18 +8836,18 @@ var ALLOWED_EVENTS2 = /* @__PURE__ */ new Set([
|
|
|
8792
8836
|
]);
|
|
8793
8837
|
var app19 = new Hono();
|
|
8794
8838
|
app19.post("/", async (c) => {
|
|
8795
|
-
const
|
|
8839
|
+
const TAG22 = "[admin:events]";
|
|
8796
8840
|
let body;
|
|
8797
8841
|
try {
|
|
8798
8842
|
body = await c.req.json();
|
|
8799
8843
|
} catch (err) {
|
|
8800
8844
|
const detail = err instanceof Error ? err.message : String(err);
|
|
8801
|
-
console.error(`${
|
|
8845
|
+
console.error(`${TAG22} reject reason=body-not-json detail=${detail}`);
|
|
8802
8846
|
return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
|
|
8803
8847
|
}
|
|
8804
8848
|
const event = typeof body.event === "string" ? body.event : "";
|
|
8805
8849
|
if (!ALLOWED_EVENTS2.has(event)) {
|
|
8806
|
-
console.error(`${
|
|
8850
|
+
console.error(`${TAG22} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
|
|
8807
8851
|
return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
|
|
8808
8852
|
}
|
|
8809
8853
|
const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
|
|
@@ -11633,7 +11677,7 @@ function pruneNode(node, warnedClasses, conversationWarnings) {
|
|
|
11633
11677
|
var graph_subgraph_default = app23;
|
|
11634
11678
|
|
|
11635
11679
|
// server/routes/admin/graph-delete.ts
|
|
11636
|
-
var ALLOWED_BY = ["graph-page", "graph-drag-trash"];
|
|
11680
|
+
var ALLOWED_BY = ["graph-page", "graph-drag-trash", "graph-side-panel-trash"];
|
|
11637
11681
|
var app24 = new Hono();
|
|
11638
11682
|
app24.post("/", requireAdminSession, async (c) => {
|
|
11639
11683
|
const cacheKey = c.var.cacheKey;
|
|
@@ -11663,17 +11707,108 @@ app24.post("/", requireAdminSession, async (c) => {
|
|
|
11663
11707
|
const lookup = await session.run(
|
|
11664
11708
|
`MATCH (n)
|
|
11665
11709
|
WHERE elementId(n) = $elementId AND n.accountId = $accountId
|
|
11666
|
-
RETURN labels(n) AS labels LIMIT 1`,
|
|
11710
|
+
RETURN labels(n) AS labels, n.conversationId AS conversationId LIMIT 1`,
|
|
11667
11711
|
{ elementId, accountId }
|
|
11668
11712
|
);
|
|
11669
11713
|
if (lookup.records.length === 0) {
|
|
11670
11714
|
const elapsed2 = Date.now() - started;
|
|
11671
11715
|
console.error(
|
|
11672
|
-
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels= result=not-found ms=${elapsed2}`
|
|
11716
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels= route=trash result=not-found ms=${elapsed2}`
|
|
11673
11717
|
);
|
|
11674
11718
|
return c.json({ error: "Node not found" }, 404);
|
|
11675
11719
|
}
|
|
11676
11720
|
const preflightLabels = lookup.records[0].get("labels") ?? [];
|
|
11721
|
+
const conversationId = lookup.records[0].get("conversationId");
|
|
11722
|
+
if (preflightLabels.includes("AdminConversation")) {
|
|
11723
|
+
if (!conversationId) {
|
|
11724
|
+
const elapsed3 = Date.now() - started;
|
|
11725
|
+
console.error(
|
|
11726
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${preflightLabels.join(",")} route=cascade result=error ms=${elapsed3} err="AdminConversation node has no conversationId"`
|
|
11727
|
+
);
|
|
11728
|
+
return c.json({ error: "AdminConversation node is missing conversationId" }, 500);
|
|
11729
|
+
}
|
|
11730
|
+
const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "graph-page-cascade" });
|
|
11731
|
+
const managerBase3 = `http://127.0.0.1:${managerPort}`;
|
|
11732
|
+
try {
|
|
11733
|
+
await session.close();
|
|
11734
|
+
} catch {
|
|
11735
|
+
}
|
|
11736
|
+
const outcome = await cascadeAdminConversationDelete({
|
|
11737
|
+
conversationId,
|
|
11738
|
+
accountId,
|
|
11739
|
+
managerBase: managerBase3
|
|
11740
|
+
});
|
|
11741
|
+
const elapsed2 = Date.now() - started;
|
|
11742
|
+
const labelSummary2 = preflightLabels.join(",");
|
|
11743
|
+
if (outcome.ok) {
|
|
11744
|
+
console.error(
|
|
11745
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary2} route=cascade result=ok ms=${elapsed2}`
|
|
11746
|
+
);
|
|
11747
|
+
const response2 = {
|
|
11748
|
+
route: "cascade",
|
|
11749
|
+
elementId,
|
|
11750
|
+
conversationId,
|
|
11751
|
+
labels: preflightLabels,
|
|
11752
|
+
claudeSessionIds: outcome.claudeSessionIds
|
|
11753
|
+
};
|
|
11754
|
+
return c.json(response2);
|
|
11755
|
+
}
|
|
11756
|
+
if (outcome.reason === "pty-still-alive") {
|
|
11757
|
+
console.error(
|
|
11758
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary2} route=cascade result=pty-still-alive claudeSessionId=${outcome.claudeSessionId.slice(0, 8)} ms=${elapsed2}`
|
|
11759
|
+
);
|
|
11760
|
+
return c.json(
|
|
11761
|
+
{
|
|
11762
|
+
error: "pty-still-alive",
|
|
11763
|
+
detail: "stop the session before deleting",
|
|
11764
|
+
claudeSessionId: outcome.claudeSessionId,
|
|
11765
|
+
conversationId
|
|
11766
|
+
},
|
|
11767
|
+
409
|
|
11768
|
+
);
|
|
11769
|
+
}
|
|
11770
|
+
if (outcome.reason === "conversation-not-found") {
|
|
11771
|
+
console.error(
|
|
11772
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary2} route=cascade result=ok-already-gone ms=${elapsed2}`
|
|
11773
|
+
);
|
|
11774
|
+
const response2 = {
|
|
11775
|
+
route: "cascade",
|
|
11776
|
+
elementId,
|
|
11777
|
+
conversationId,
|
|
11778
|
+
labels: preflightLabels,
|
|
11779
|
+
claudeSessionIds: []
|
|
11780
|
+
};
|
|
11781
|
+
return c.json(response2);
|
|
11782
|
+
}
|
|
11783
|
+
if (outcome.reason === "jsonl-purge-failed") {
|
|
11784
|
+
console.error(
|
|
11785
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary2} route=cascade result=jsonl-purge-failed claudeSessionId=${outcome.claudeSessionId.slice(0, 8)} ms=${elapsed2} err="${outcome.message}"`
|
|
11786
|
+
);
|
|
11787
|
+
const status = outcome.status >= 400 && outcome.status < 600 ? outcome.status : 502;
|
|
11788
|
+
return c.json(
|
|
11789
|
+
{
|
|
11790
|
+
error: "jsonl-purge-failed",
|
|
11791
|
+
detail: outcome.message,
|
|
11792
|
+
claudeSessionId: outcome.claudeSessionId,
|
|
11793
|
+
conversationId,
|
|
11794
|
+
claudeSessionIdsPurged: outcome.claudeSessionIdsPurged
|
|
11795
|
+
},
|
|
11796
|
+
status
|
|
11797
|
+
);
|
|
11798
|
+
}
|
|
11799
|
+
console.error(
|
|
11800
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary2} route=cascade result=graph-delete-failed ms=${elapsed2} err="${outcome.message}"`
|
|
11801
|
+
);
|
|
11802
|
+
return c.json(
|
|
11803
|
+
{
|
|
11804
|
+
error: "graph-delete-failed",
|
|
11805
|
+
detail: outcome.message,
|
|
11806
|
+
conversationId,
|
|
11807
|
+
claudeSessionIdsPurged: outcome.claudeSessionIdsPurged
|
|
11808
|
+
},
|
|
11809
|
+
500
|
|
11810
|
+
);
|
|
11811
|
+
}
|
|
11677
11812
|
const result = await trashNode({
|
|
11678
11813
|
session,
|
|
11679
11814
|
accountId,
|
|
@@ -11683,9 +11818,10 @@ app24.post("/", requireAdminSession, async (c) => {
|
|
|
11683
11818
|
const elapsed = Date.now() - started;
|
|
11684
11819
|
const labelSummary = (result.labels.length > 0 ? result.labels : preflightLabels).join(",");
|
|
11685
11820
|
console.error(
|
|
11686
|
-
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary} result=ok ms=${elapsed}`
|
|
11821
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary} route=trash result=ok ms=${elapsed}`
|
|
11687
11822
|
);
|
|
11688
11823
|
const response = {
|
|
11824
|
+
route: "trash",
|
|
11689
11825
|
elementId: result.nodeId,
|
|
11690
11826
|
labels: result.labels.length > 0 ? result.labels : preflightLabels,
|
|
11691
11827
|
trashedAt: result.trashedAt,
|
|
@@ -11977,9 +12113,137 @@ var WRITE_CYPHER = `
|
|
|
11977
12113
|
`;
|
|
11978
12114
|
var graph_default_view_default = app27;
|
|
11979
12115
|
|
|
11980
|
-
// server/routes/admin/
|
|
12116
|
+
// server/routes/admin/session-defaults.ts
|
|
11981
12117
|
var app28 = new Hono();
|
|
11982
|
-
|
|
12118
|
+
var MODE_OPTIONS = ["default", "acceptEdits", "plan", "auto", "bypassPermissions"];
|
|
12119
|
+
var MODEL_OPTIONS = ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5"];
|
|
12120
|
+
app28.get("/", requireAdminSession, async (c) => {
|
|
12121
|
+
const cacheKey = c.var.cacheKey;
|
|
12122
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
12123
|
+
const userId = getUserIdForSession(cacheKey);
|
|
12124
|
+
if (!accountId || !userId) {
|
|
12125
|
+
console.error('[session-defaults] rejected op=load reason="missing account or user context"');
|
|
12126
|
+
return c.json({ error: "Account and user context required for session defaults" }, 401);
|
|
12127
|
+
}
|
|
12128
|
+
const started = Date.now();
|
|
12129
|
+
const session = getSession();
|
|
12130
|
+
try {
|
|
12131
|
+
const result = await session.executeRead(async (tx) => {
|
|
12132
|
+
return await tx.run(READ_CYPHER2, { accountId, userId });
|
|
12133
|
+
});
|
|
12134
|
+
const record = result.records[0];
|
|
12135
|
+
const rawMode = record?.get("permissionMode");
|
|
12136
|
+
const rawModel = record?.get("model");
|
|
12137
|
+
const permissionMode = MODE_OPTIONS.includes(rawMode ?? "") ? rawMode : "default";
|
|
12138
|
+
const model = MODEL_OPTIONS.includes(rawModel ?? "") ? rawModel : null;
|
|
12139
|
+
const elapsed = Date.now() - started;
|
|
12140
|
+
console.error(
|
|
12141
|
+
`[session-defaults] load account=${accountId} user=${userId} permissionMode=${permissionMode} model=${model ?? "null"} ms=${elapsed}`
|
|
12142
|
+
);
|
|
12143
|
+
return c.json({ permissionMode, model });
|
|
12144
|
+
} catch (err) {
|
|
12145
|
+
const elapsed = Date.now() - started;
|
|
12146
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
12147
|
+
console.error(
|
|
12148
|
+
`[session-defaults] rejected op=load account=${accountId} reason="${message}" ms=${elapsed}`
|
|
12149
|
+
);
|
|
12150
|
+
return c.json({ error: `Session defaults unavailable: ${message}` }, 503);
|
|
12151
|
+
} finally {
|
|
12152
|
+
try {
|
|
12153
|
+
await session.close();
|
|
12154
|
+
} catch {
|
|
12155
|
+
}
|
|
12156
|
+
}
|
|
12157
|
+
});
|
|
12158
|
+
app28.put("/", requireAdminSession, async (c) => {
|
|
12159
|
+
const cacheKey = c.var.cacheKey;
|
|
12160
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
12161
|
+
const userId = getUserIdForSession(cacheKey);
|
|
12162
|
+
if (!accountId || !userId) {
|
|
12163
|
+
console.error('[session-defaults] rejected op=save reason="missing account or user context"');
|
|
12164
|
+
return c.json({ error: "Account and user context required for session defaults" }, 401);
|
|
12165
|
+
}
|
|
12166
|
+
const body = await safeJson(c);
|
|
12167
|
+
if (!body) {
|
|
12168
|
+
return c.json({ error: "Request body must be JSON" }, 400);
|
|
12169
|
+
}
|
|
12170
|
+
const validation = validateBody3(body);
|
|
12171
|
+
if (!validation.ok) {
|
|
12172
|
+
console.error(
|
|
12173
|
+
`[session-defaults] rejected op=save account=${accountId} reason="${validation.reason}"`
|
|
12174
|
+
);
|
|
12175
|
+
return c.json({ error: validation.reason }, 400);
|
|
12176
|
+
}
|
|
12177
|
+
const { permissionMode, model } = validation;
|
|
12178
|
+
const started = Date.now();
|
|
12179
|
+
const session = getSession();
|
|
12180
|
+
try {
|
|
12181
|
+
await session.executeWrite(async (tx) => {
|
|
12182
|
+
return await tx.run(WRITE_CYPHER2, {
|
|
12183
|
+
accountId,
|
|
12184
|
+
userId,
|
|
12185
|
+
permissionMode,
|
|
12186
|
+
model,
|
|
12187
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12188
|
+
});
|
|
12189
|
+
});
|
|
12190
|
+
const elapsed = Date.now() - started;
|
|
12191
|
+
console.error(
|
|
12192
|
+
`[session-defaults] save account=${accountId} user=${userId} permissionMode=${permissionMode} model=${model ?? "null"} ms=${elapsed}`
|
|
12193
|
+
);
|
|
12194
|
+
return c.json({ permissionMode, model });
|
|
12195
|
+
} catch (err) {
|
|
12196
|
+
const elapsed = Date.now() - started;
|
|
12197
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
12198
|
+
console.error(
|
|
12199
|
+
`[session-defaults] rejected op=save account=${accountId} reason="${message}" ms=${elapsed}`
|
|
12200
|
+
);
|
|
12201
|
+
return c.json({ error: `Failed to save session defaults: ${message}` }, 503);
|
|
12202
|
+
} finally {
|
|
12203
|
+
try {
|
|
12204
|
+
await session.close();
|
|
12205
|
+
} catch {
|
|
12206
|
+
}
|
|
12207
|
+
}
|
|
12208
|
+
});
|
|
12209
|
+
function validateBody3(body) {
|
|
12210
|
+
if (typeof body.permissionMode !== "string") {
|
|
12211
|
+
return { ok: false, reason: "permissionMode must be a string" };
|
|
12212
|
+
}
|
|
12213
|
+
if (!MODE_OPTIONS.includes(body.permissionMode)) {
|
|
12214
|
+
return { ok: false, reason: `permissionMode "${body.permissionMode}" is not one of ${MODE_OPTIONS.join(", ")}` };
|
|
12215
|
+
}
|
|
12216
|
+
if (!("model" in body)) {
|
|
12217
|
+
return { ok: false, reason: "model is required (use null for no override)" };
|
|
12218
|
+
}
|
|
12219
|
+
if (body.model !== null && typeof body.model !== "string") {
|
|
12220
|
+
return { ok: false, reason: "model must be a string or null" };
|
|
12221
|
+
}
|
|
12222
|
+
if (body.model !== null && !MODEL_OPTIONS.includes(body.model)) {
|
|
12223
|
+
return { ok: false, reason: `model "${body.model}" is not one of ${MODEL_OPTIONS.join(", ")} (or null)` };
|
|
12224
|
+
}
|
|
12225
|
+
return {
|
|
12226
|
+
ok: true,
|
|
12227
|
+
permissionMode: body.permissionMode,
|
|
12228
|
+
model: body.model
|
|
12229
|
+
};
|
|
12230
|
+
}
|
|
12231
|
+
var READ_CYPHER2 = `
|
|
12232
|
+
OPTIONAL MATCH (p:SpawnPreference {accountId: $accountId, userId: $userId})
|
|
12233
|
+
RETURN p.permissionMode AS permissionMode, p.model AS model
|
|
12234
|
+
`;
|
|
12235
|
+
var WRITE_CYPHER2 = `
|
|
12236
|
+
MERGE (p:SpawnPreference {accountId: $accountId, userId: $userId})
|
|
12237
|
+
SET p.permissionMode = $permissionMode,
|
|
12238
|
+
p.model = $model,
|
|
12239
|
+
p.updatedAt = $updatedAt
|
|
12240
|
+
RETURN p.permissionMode AS permissionMode
|
|
12241
|
+
`;
|
|
12242
|
+
var session_defaults_default = app28;
|
|
12243
|
+
|
|
12244
|
+
// server/routes/admin/file-attach.ts
|
|
12245
|
+
var app29 = new Hono();
|
|
12246
|
+
app29.post("/", async (c) => {
|
|
11983
12247
|
try {
|
|
11984
12248
|
const body = await c.req.json();
|
|
11985
12249
|
const { filePath, accountId } = body;
|
|
@@ -12002,7 +12266,7 @@ app28.post("/", async (c) => {
|
|
|
12002
12266
|
return c.json({ error: message }, 500);
|
|
12003
12267
|
}
|
|
12004
12268
|
});
|
|
12005
|
-
var file_attach_default =
|
|
12269
|
+
var file_attach_default = app29;
|
|
12006
12270
|
|
|
12007
12271
|
// server/routes/admin/sidebar-artefacts.ts
|
|
12008
12272
|
import neo4j2 from "neo4j-driver";
|
|
@@ -12012,8 +12276,8 @@ import { existsSync as existsSync16 } from "fs";
|
|
|
12012
12276
|
var LIMIT = 50;
|
|
12013
12277
|
var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
|
|
12014
12278
|
var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
|
|
12015
|
-
var
|
|
12016
|
-
|
|
12279
|
+
var app30 = new Hono();
|
|
12280
|
+
app30.get("/", requireAdminSession, async (c) => {
|
|
12017
12281
|
const cacheKey = c.var.cacheKey;
|
|
12018
12282
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12019
12283
|
if (!accountId) {
|
|
@@ -12219,7 +12483,7 @@ function isWithin(target, root) {
|
|
|
12219
12483
|
const rel = relative2(root, target);
|
|
12220
12484
|
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
12221
12485
|
}
|
|
12222
|
-
var sidebar_artefacts_default =
|
|
12486
|
+
var sidebar_artefacts_default = app30;
|
|
12223
12487
|
|
|
12224
12488
|
// server/routes/admin/sidebar-artefact-save.ts
|
|
12225
12489
|
import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
|
|
@@ -12227,8 +12491,8 @@ import { resolve as resolve18 } from "path";
|
|
|
12227
12491
|
import { existsSync as existsSync17 } from "fs";
|
|
12228
12492
|
var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
|
|
12229
12493
|
var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
12230
|
-
var
|
|
12231
|
-
|
|
12494
|
+
var app31 = new Hono();
|
|
12495
|
+
app31.post("/", requireAdminSession, async (c) => {
|
|
12232
12496
|
const cacheKey = c.var.cacheKey;
|
|
12233
12497
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12234
12498
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -12340,15 +12604,15 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
12340
12604
|
function relPath(absPath, root) {
|
|
12341
12605
|
return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
|
|
12342
12606
|
}
|
|
12343
|
-
var sidebar_artefact_save_default =
|
|
12607
|
+
var sidebar_artefact_save_default = app31;
|
|
12344
12608
|
|
|
12345
12609
|
// server/routes/admin/sidebar-artefact-content.ts
|
|
12346
12610
|
import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
|
|
12347
12611
|
import { existsSync as existsSync18 } from "fs";
|
|
12348
12612
|
import { resolve as resolve19 } from "path";
|
|
12349
12613
|
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
12350
|
-
var
|
|
12351
|
-
|
|
12614
|
+
var app32 = new Hono();
|
|
12615
|
+
app32.get("/", requireAdminSession, async (c) => {
|
|
12352
12616
|
const cacheKey = c.var.cacheKey;
|
|
12353
12617
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12354
12618
|
if (!accountId) return new Response("Unauthorized", { status: 401 });
|
|
@@ -12389,7 +12653,7 @@ app31.get("/", requireAdminSession, async (c) => {
|
|
|
12389
12653
|
}
|
|
12390
12654
|
});
|
|
12391
12655
|
});
|
|
12392
|
-
var sidebar_artefact_content_default =
|
|
12656
|
+
var sidebar_artefact_content_default = app32;
|
|
12393
12657
|
|
|
12394
12658
|
// server/routes/admin/health.ts
|
|
12395
12659
|
import { existsSync as existsSync19, readFileSync as readFileSync17 } from "fs";
|
|
@@ -12434,8 +12698,8 @@ async function probeConversationDb() {
|
|
|
12434
12698
|
});
|
|
12435
12699
|
}
|
|
12436
12700
|
}
|
|
12437
|
-
var
|
|
12438
|
-
|
|
12701
|
+
var app33 = new Hono();
|
|
12702
|
+
app33.get("/", async (c) => {
|
|
12439
12703
|
const version = readVersion();
|
|
12440
12704
|
const probe = await probeConversationDb();
|
|
12441
12705
|
const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
|
|
@@ -12457,38 +12721,187 @@ app32.get("/", async (c) => {
|
|
|
12457
12721
|
uptimeMs
|
|
12458
12722
|
});
|
|
12459
12723
|
});
|
|
12460
|
-
var health_default2 =
|
|
12724
|
+
var health_default2 = app33;
|
|
12725
|
+
|
|
12726
|
+
// server/routes/admin/linkedin-ingest.ts
|
|
12727
|
+
var TAG20 = "[linkedin-ingest-route]";
|
|
12728
|
+
var UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
12729
|
+
var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
12730
|
+
var LINKEDIN_URL = /^https:\/\/www\.linkedin\.com\//;
|
|
12731
|
+
function rejectSchema(reason, missing = []) {
|
|
12732
|
+
return { ok: false, status: 400, error: "schema", reason, missing };
|
|
12733
|
+
}
|
|
12734
|
+
function validate(body) {
|
|
12735
|
+
if (!body || typeof body !== "object") return rejectSchema("not-object");
|
|
12736
|
+
const b = body;
|
|
12737
|
+
const missing = [];
|
|
12738
|
+
if (b.source !== "linkedin") missing.push("source");
|
|
12739
|
+
if (b.kind !== "profile" && b.kind !== "thread") missing.push("kind");
|
|
12740
|
+
if (typeof b.capturedAt !== "string" || !ISO.test(b.capturedAt)) missing.push("capturedAt");
|
|
12741
|
+
if (typeof b.pageUrl !== "string" || !LINKEDIN_URL.test(b.pageUrl)) missing.push("pageUrl");
|
|
12742
|
+
if (typeof b.dispatchId !== "string" || !UUID.test(b.dispatchId)) missing.push("dispatchId");
|
|
12743
|
+
if (missing.length) return rejectSchema("envelope", missing);
|
|
12744
|
+
if (b.kind === "profile") {
|
|
12745
|
+
const p = b.profile;
|
|
12746
|
+
if (!p || typeof p !== "object") return rejectSchema("profile-shape", ["profile"]);
|
|
12747
|
+
const pMissing = [];
|
|
12748
|
+
if (typeof p.name !== "string" || !p.name.trim()) pMissing.push("profile.name");
|
|
12749
|
+
if (typeof p.headline !== "string") pMissing.push("profile.headline");
|
|
12750
|
+
if (typeof p.bodyText !== "string" || !p.bodyText.trim()) pMissing.push("profile.bodyText");
|
|
12751
|
+
if (pMissing.length) return rejectSchema("profile-shape", pMissing);
|
|
12752
|
+
} else {
|
|
12753
|
+
const t = b.thread;
|
|
12754
|
+
if (!t || typeof t !== "object") return rejectSchema("thread-shape", ["thread"]);
|
|
12755
|
+
const tMissing = [];
|
|
12756
|
+
if (!Array.isArray(t.participants) || t.participants.length === 0) tMissing.push("thread.participants");
|
|
12757
|
+
if (typeof t.bodyText !== "string" || !t.bodyText.trim()) tMissing.push("thread.bodyText");
|
|
12758
|
+
if (tMissing.length) return rejectSchema("thread-shape", tMissing);
|
|
12759
|
+
}
|
|
12760
|
+
return { ok: true, envelope: b };
|
|
12761
|
+
}
|
|
12762
|
+
function buildInitialMessage(env) {
|
|
12763
|
+
const header = [
|
|
12764
|
+
"LinkedIn ingest \u2014 dispatchId=" + env.dispatchId,
|
|
12765
|
+
"kind=" + env.kind,
|
|
12766
|
+
"sourceUrl=" + env.pageUrl,
|
|
12767
|
+
"capturedAt=" + env.capturedAt
|
|
12768
|
+
].join(" \xB7 ");
|
|
12769
|
+
if (env.kind === "profile" && env.profile) {
|
|
12770
|
+
const p = env.profile;
|
|
12771
|
+
return [
|
|
12772
|
+
header,
|
|
12773
|
+
"",
|
|
12774
|
+
"Surface: LinkedIn profile. Run the document-ingest skill in document mode against the body below, anchored to a Person subject for this profile.",
|
|
12775
|
+
"",
|
|
12776
|
+
"Conservative-extraction rules apply (see Task 234 spec):",
|
|
12777
|
+
"- One :KnowledgeDocument MERGE keyed on sourceUrl=" + env.pageUrl + " with the verbatim body as body, plus one :Section:Note child with the summary.",
|
|
12778
|
+
"- MERGE :Person on canonical key (name + sourceUrl). When the body assertively states currentCompany, MERGE :Organization and create (:Person)-[:WORKS_AT]->(:Organization).",
|
|
12779
|
+
"- MERGE any other derived entities only when assertively stated in the body. Use whatever ontology label fits (:Event, :Task, :Service, :PriceSpecification, \u2026). Each carries sourceUrl=" + env.pageUrl + ".",
|
|
12780
|
+
"- (:KD)-[:MENTIONS]->(:Person) for the subject, (:KD)-[:MENTIONS]->(:Organization) for the employer, (:KD)-[:MENTIONS]->(<derived entity>) for each.",
|
|
12781
|
+
"- No :Communication, :ConversationArchive, or :Message nodes \u2014 those belong to other flows.",
|
|
12782
|
+
"",
|
|
12783
|
+
"Subject (assertive):",
|
|
12784
|
+
"- name=" + p.name,
|
|
12785
|
+
"- headline=" + p.headline,
|
|
12786
|
+
"- location=" + (p.location || "(none)"),
|
|
12787
|
+
"- currentTitle=" + (p.currentTitle || "(none)"),
|
|
12788
|
+
"- currentCompany=" + (p.currentCompany || "(none)"),
|
|
12789
|
+
"",
|
|
12790
|
+
"Body (verbatim, write to :KnowledgeDocument.body):",
|
|
12791
|
+
p.bodyText
|
|
12792
|
+
].join("\n");
|
|
12793
|
+
}
|
|
12794
|
+
if (env.kind === "thread" && env.thread) {
|
|
12795
|
+
const t = env.thread;
|
|
12796
|
+
const participantList = t.participants.map(function(p) {
|
|
12797
|
+
return p.name + (p.profileUrl ? " (" + p.profileUrl + ")" : "");
|
|
12798
|
+
}).join(", ");
|
|
12799
|
+
return [
|
|
12800
|
+
header,
|
|
12801
|
+
"",
|
|
12802
|
+
"Surface: LinkedIn DM thread. Run the document-ingest skill in document mode against the transcript below.",
|
|
12803
|
+
"",
|
|
12804
|
+
"Conservative-extraction rules apply (see Task 234 spec):",
|
|
12805
|
+
"- One :KnowledgeDocument MERGE keyed on sourceUrl=" + env.pageUrl + " with the verbatim transcript as body, plus one :Section:Note child with the summary.",
|
|
12806
|
+
"- (:KD)-[:PARTICIPANT]->(:Person) for each participant. MERGE :Person on (name, profileUrl) where present.",
|
|
12807
|
+
"- MERGE any derived entity only when assertively stated. Whatever ontology label fits: :Event {startDate, endDate} with ATTENDED_BY edges for scheduled meetings; :Task {kind, name, status} with RAISED_BY/ABOUT edges for actions without a scheduled time; :Service/:PriceSpecification when an offer or price is discussed. Each carries sourceUrl=" + env.pageUrl + ".",
|
|
12808
|
+
"- (:KD)-[:MENTIONS]->(<derived entity>) for every derived entity. Person-attached insights stay in the :Section:Note body plus a (:KD)-[:MENTIONS]->(:Person) edge \u2014 no standalone insight node.",
|
|
12809
|
+
"- No :Communication, :ConversationArchive, or :Message nodes \u2014 those belong to other flows.",
|
|
12810
|
+
"",
|
|
12811
|
+
"Participants:",
|
|
12812
|
+
participantList,
|
|
12813
|
+
"",
|
|
12814
|
+
"Transcript (verbatim, write to :KnowledgeDocument.body):",
|
|
12815
|
+
t.bodyText
|
|
12816
|
+
].join("\n");
|
|
12817
|
+
}
|
|
12818
|
+
return header;
|
|
12819
|
+
}
|
|
12820
|
+
var app34 = new Hono();
|
|
12821
|
+
app34.post("/", requireAdminSession, async (c) => {
|
|
12822
|
+
let body;
|
|
12823
|
+
try {
|
|
12824
|
+
body = await c.req.json();
|
|
12825
|
+
} catch {
|
|
12826
|
+
console.error(TAG20 + " rejected status=400 reason=schema:body-not-json");
|
|
12827
|
+
return c.json({ ok: false, error: "schema", reason: "body-not-json" }, 400);
|
|
12828
|
+
}
|
|
12829
|
+
const v = validate(body);
|
|
12830
|
+
if (!v.ok) {
|
|
12831
|
+
console.error(TAG20 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
|
|
12832
|
+
return c.json({ ok: false, error: v.error, reason: v.reason, missing: v.missing }, v.status);
|
|
12833
|
+
}
|
|
12834
|
+
const envelope = v.envelope;
|
|
12835
|
+
const cacheKey = c.var.cacheKey ?? "";
|
|
12836
|
+
const senderId = getAccountIdForSession(cacheKey) ?? "";
|
|
12837
|
+
if (!senderId) {
|
|
12838
|
+
console.error(TAG20 + " rejected status=500 reason=admin-account-not-resolved");
|
|
12839
|
+
return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
|
|
12840
|
+
}
|
|
12841
|
+
const userId = getUserIdForSession(cacheKey) ?? void 0;
|
|
12842
|
+
const payloadBytes = JSON.stringify(envelope).length;
|
|
12843
|
+
console.log(
|
|
12844
|
+
TAG20 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
|
|
12845
|
+
);
|
|
12846
|
+
const initialMessage = buildInitialMessage(envelope);
|
|
12847
|
+
const spawnStart = Date.now();
|
|
12848
|
+
const { response, claudeSessionId } = await performSpawnWithInitialMessage({
|
|
12849
|
+
senderId,
|
|
12850
|
+
userId,
|
|
12851
|
+
role: "admin",
|
|
12852
|
+
channel: "linkedin-extension",
|
|
12853
|
+
permissionMode: void 0,
|
|
12854
|
+
hidden: true,
|
|
12855
|
+
specialist: "database-operator",
|
|
12856
|
+
model: void 0,
|
|
12857
|
+
initialMessage
|
|
12858
|
+
});
|
|
12859
|
+
if (!response.ok) {
|
|
12860
|
+
const detail = await response.text().catch(() => "");
|
|
12861
|
+
console.error(
|
|
12862
|
+
TAG20 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + response.status + " ms=" + (Date.now() - spawnStart) + " detail=" + detail.slice(0, 200)
|
|
12863
|
+
);
|
|
12864
|
+
return c.json({ ok: false, error: "dispatch-failed", upstreamStatus: response.status, detail: detail.slice(0, 500) }, 502);
|
|
12865
|
+
}
|
|
12866
|
+
console.log(
|
|
12867
|
+
TAG20 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + (claudeSessionId ?? "unknown") + " ms=" + (Date.now() - spawnStart)
|
|
12868
|
+
);
|
|
12869
|
+
return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: claudeSessionId }, 202);
|
|
12870
|
+
});
|
|
12871
|
+
var linkedin_ingest_default = app34;
|
|
12461
12872
|
|
|
12462
12873
|
// server/routes/admin/index.ts
|
|
12463
|
-
var
|
|
12464
|
-
|
|
12465
|
-
|
|
12466
|
-
|
|
12467
|
-
|
|
12468
|
-
|
|
12469
|
-
|
|
12470
|
-
|
|
12471
|
-
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
|
|
12476
|
-
|
|
12477
|
-
|
|
12478
|
-
|
|
12479
|
-
|
|
12480
|
-
|
|
12481
|
-
|
|
12482
|
-
|
|
12483
|
-
|
|
12484
|
-
|
|
12485
|
-
|
|
12486
|
-
|
|
12487
|
-
|
|
12488
|
-
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
|
|
12874
|
+
var app35 = new Hono();
|
|
12875
|
+
app35.route("/session", session_default);
|
|
12876
|
+
app35.route("/new-session-failure", new_session_failure_default);
|
|
12877
|
+
app35.route("/new-session-submit", new_session_submit_default);
|
|
12878
|
+
app35.route("/logs", logs_default);
|
|
12879
|
+
app35.route("/claude-info", claude_info_default);
|
|
12880
|
+
app35.route("/attachment", attachment_default);
|
|
12881
|
+
app35.route("/agents", agents_default);
|
|
12882
|
+
app35.route("/sessions", sessions_default);
|
|
12883
|
+
app35.route("/claude-sessions", claude_sessions_default);
|
|
12884
|
+
app35.route("/log-ingest", log_ingest_default);
|
|
12885
|
+
app35.route("/browser", browser_default);
|
|
12886
|
+
app35.route("/browser-iframe", browser_iframe_default);
|
|
12887
|
+
app35.route("/device-browser", device_browser_default);
|
|
12888
|
+
app35.route("/events", events_default);
|
|
12889
|
+
app35.route("/cloudflare", cloudflare_default);
|
|
12890
|
+
app35.route("/files", files_default);
|
|
12891
|
+
app35.route("/graph-search", graph_search_default);
|
|
12892
|
+
app35.route("/graph-subgraph", graph_subgraph_default);
|
|
12893
|
+
app35.route("/graph-delete", graph_delete_default);
|
|
12894
|
+
app35.route("/graph-restore", graph_restore_default);
|
|
12895
|
+
app35.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
12896
|
+
app35.route("/graph-default-view", graph_default_view_default);
|
|
12897
|
+
app35.route("/session-defaults", session_defaults_default);
|
|
12898
|
+
app35.route("/file-attach", file_attach_default);
|
|
12899
|
+
app35.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
12900
|
+
app35.route("/sidebar-artefact-save", sidebar_artefact_save_default);
|
|
12901
|
+
app35.route("/sidebar-artefact-content", sidebar_artefact_content_default);
|
|
12902
|
+
app35.route("/health-brand", health_default2);
|
|
12903
|
+
app35.route("/linkedin-ingest", linkedin_ingest_default);
|
|
12904
|
+
var admin_default = app35;
|
|
12492
12905
|
|
|
12493
12906
|
// server/routes/sites.ts
|
|
12494
12907
|
import { existsSync as existsSync20, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
|
|
@@ -12523,8 +12936,8 @@ function getExt(p) {
|
|
|
12523
12936
|
if (idx < p.lastIndexOf("/")) return "";
|
|
12524
12937
|
return p.slice(idx).toLowerCase();
|
|
12525
12938
|
}
|
|
12526
|
-
var
|
|
12527
|
-
|
|
12939
|
+
var app36 = new Hono();
|
|
12940
|
+
app36.get("/:rel{.*}", (c) => {
|
|
12528
12941
|
const reqPath = c.req.path;
|
|
12529
12942
|
const rawRel = c.req.param("rel") ?? "";
|
|
12530
12943
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -12627,7 +13040,7 @@ app34.get("/:rel{.*}", (c) => {
|
|
|
12627
13040
|
"X-Content-Type-Options": "nosniff"
|
|
12628
13041
|
});
|
|
12629
13042
|
});
|
|
12630
|
-
var sites_default =
|
|
13043
|
+
var sites_default = app36;
|
|
12631
13044
|
|
|
12632
13045
|
// app/lib/graph-health.ts
|
|
12633
13046
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -12711,7 +13124,7 @@ function startGraphHealthTimer() {
|
|
|
12711
13124
|
}
|
|
12712
13125
|
|
|
12713
13126
|
// app/lib/whatsapp/inbound/claude-bridge.ts
|
|
12714
|
-
var
|
|
13127
|
+
var TAG21 = "[whatsapp-adaptor]";
|
|
12715
13128
|
function whatsappTurnTimeoutMs() {
|
|
12716
13129
|
return Number(process.env.WHATSAPP_PTY_TURN_TIMEOUT_MS ?? String(5 * 6e4));
|
|
12717
13130
|
}
|
|
@@ -12732,7 +13145,7 @@ async function dispatchToClaude(input) {
|
|
|
12732
13145
|
await input.reply(result.turnText);
|
|
12733
13146
|
} catch (err) {
|
|
12734
13147
|
const m = err instanceof Error ? err.message : String(err);
|
|
12735
|
-
console.error(`${
|
|
13148
|
+
console.error(`${TAG21} reject reason=reply-failed senderId=${input.senderId} message=${m}`);
|
|
12736
13149
|
}
|
|
12737
13150
|
}
|
|
12738
13151
|
function startReaper2() {
|
|
@@ -13034,9 +13447,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
|
|
|
13034
13447
|
function isPublicHost(host) {
|
|
13035
13448
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
13036
13449
|
}
|
|
13037
|
-
var
|
|
13038
|
-
|
|
13039
|
-
|
|
13450
|
+
var app37 = new Hono();
|
|
13451
|
+
app37.use("*", clientIpMiddleware);
|
|
13452
|
+
app37.use("*", async (c, next) => {
|
|
13040
13453
|
await next();
|
|
13041
13454
|
c.header("X-Content-Type-Options", "nosniff");
|
|
13042
13455
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -13046,7 +13459,7 @@ app35.use("*", async (c, next) => {
|
|
|
13046
13459
|
);
|
|
13047
13460
|
});
|
|
13048
13461
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
13049
|
-
|
|
13462
|
+
app37.use("*", async (c, next) => {
|
|
13050
13463
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
13051
13464
|
await next();
|
|
13052
13465
|
return;
|
|
@@ -13079,7 +13492,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
13079
13492
|
"/sites/"
|
|
13080
13493
|
];
|
|
13081
13494
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
13082
|
-
|
|
13495
|
+
app37.use("*", async (c, next) => {
|
|
13083
13496
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13084
13497
|
if (!isPublicHost(host)) {
|
|
13085
13498
|
await next();
|
|
@@ -13119,7 +13532,7 @@ function resolveRemoteAuthOpts() {
|
|
|
13119
13532
|
return brandLoginOpts;
|
|
13120
13533
|
}
|
|
13121
13534
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
13122
|
-
|
|
13535
|
+
app37.post("/__remote-auth/login", async (c) => {
|
|
13123
13536
|
const client = clientFrom(c);
|
|
13124
13537
|
const clientIp = client.ip || "unknown";
|
|
13125
13538
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -13164,7 +13577,7 @@ app35.post("/__remote-auth/login", async (c) => {
|
|
|
13164
13577
|
}
|
|
13165
13578
|
});
|
|
13166
13579
|
});
|
|
13167
|
-
|
|
13580
|
+
app37.get("/__remote-auth/logout", (c) => {
|
|
13168
13581
|
const client = clientFrom(c);
|
|
13169
13582
|
const clientIp = client.ip || "unknown";
|
|
13170
13583
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -13177,7 +13590,7 @@ app35.get("/__remote-auth/logout", (c) => {
|
|
|
13177
13590
|
}
|
|
13178
13591
|
});
|
|
13179
13592
|
});
|
|
13180
|
-
|
|
13593
|
+
app37.post("/__remote-auth/change-password", async (c) => {
|
|
13181
13594
|
const client = clientFrom(c);
|
|
13182
13595
|
const clientIp = client.ip || "unknown";
|
|
13183
13596
|
const rateLimited = checkRateLimit(client);
|
|
@@ -13228,13 +13641,13 @@ app35.post("/__remote-auth/change-password", async (c) => {
|
|
|
13228
13641
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
13229
13642
|
}
|
|
13230
13643
|
});
|
|
13231
|
-
|
|
13644
|
+
app37.get("/__remote-auth/setup", (c) => {
|
|
13232
13645
|
if (isRemoteAuthConfigured()) {
|
|
13233
13646
|
return c.redirect("/");
|
|
13234
13647
|
}
|
|
13235
13648
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
13236
13649
|
});
|
|
13237
|
-
|
|
13650
|
+
app37.post("/__remote-auth/set-initial-password", async (c) => {
|
|
13238
13651
|
if (isRemoteAuthConfigured()) {
|
|
13239
13652
|
return c.redirect("/");
|
|
13240
13653
|
}
|
|
@@ -13272,10 +13685,10 @@ app35.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
13272
13685
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
13273
13686
|
}
|
|
13274
13687
|
});
|
|
13275
|
-
|
|
13688
|
+
app37.get("/api/remote-auth/status", (c) => {
|
|
13276
13689
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
13277
13690
|
});
|
|
13278
|
-
|
|
13691
|
+
app37.post("/api/remote-auth/set-password", async (c) => {
|
|
13279
13692
|
let body;
|
|
13280
13693
|
try {
|
|
13281
13694
|
body = await c.req.json();
|
|
@@ -13306,9 +13719,9 @@ app35.post("/api/remote-auth/set-password", async (c) => {
|
|
|
13306
13719
|
return c.json({ error: "Failed to save password" }, 500);
|
|
13307
13720
|
}
|
|
13308
13721
|
});
|
|
13309
|
-
|
|
13722
|
+
app37.route("/api/_client-error", client_error_default);
|
|
13310
13723
|
console.log("[client-error-route] mounted");
|
|
13311
|
-
|
|
13724
|
+
app37.use("*", async (c, next) => {
|
|
13312
13725
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13313
13726
|
const path2 = c.req.path;
|
|
13314
13727
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -13348,11 +13761,11 @@ app35.use("*", async (c, next) => {
|
|
|
13348
13761
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
13349
13762
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
13350
13763
|
});
|
|
13351
|
-
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
|
|
13355
|
-
|
|
13764
|
+
app37.route("/api/health", health_default);
|
|
13765
|
+
app37.route("/api/chat", chat_default);
|
|
13766
|
+
app37.route("/api/whatsapp", whatsapp_default);
|
|
13767
|
+
app37.route("/api/onboarding", onboarding_default);
|
|
13768
|
+
app37.route("/api/admin", admin_default);
|
|
13356
13769
|
var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
|
|
13357
13770
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
13358
13771
|
var IMAGE_MIME = {
|
|
@@ -13364,7 +13777,7 @@ var IMAGE_MIME = {
|
|
|
13364
13777
|
".svg": "image/svg+xml",
|
|
13365
13778
|
".ico": "image/x-icon"
|
|
13366
13779
|
};
|
|
13367
|
-
|
|
13780
|
+
app37.get("/agent-assets/:slug/:filename", (c) => {
|
|
13368
13781
|
const slug = c.req.param("slug");
|
|
13369
13782
|
const filename = c.req.param("filename");
|
|
13370
13783
|
if (!SAFE_SLUG_RE.test(slug)) {
|
|
@@ -13399,7 +13812,7 @@ app35.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
13399
13812
|
"Cache-Control": "public, max-age=3600"
|
|
13400
13813
|
});
|
|
13401
13814
|
});
|
|
13402
|
-
|
|
13815
|
+
app37.get("/generated/:filename", (c) => {
|
|
13403
13816
|
const filename = c.req.param("filename");
|
|
13404
13817
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
13405
13818
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -13429,7 +13842,7 @@ app35.get("/generated/:filename", (c) => {
|
|
|
13429
13842
|
"Cache-Control": "public, max-age=86400"
|
|
13430
13843
|
});
|
|
13431
13844
|
});
|
|
13432
|
-
|
|
13845
|
+
app37.route("/sites", sites_default);
|
|
13433
13846
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
13434
13847
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
13435
13848
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -13566,7 +13979,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
13566
13979
|
function escapeHtml(s) {
|
|
13567
13980
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
13568
13981
|
}
|
|
13569
|
-
|
|
13982
|
+
app37.get("/", (c) => {
|
|
13570
13983
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13571
13984
|
if (isPublicHost(host)) {
|
|
13572
13985
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -13574,12 +13987,12 @@ app35.get("/", (c) => {
|
|
|
13574
13987
|
}
|
|
13575
13988
|
return c.html(cachedHtml("index.html"));
|
|
13576
13989
|
});
|
|
13577
|
-
|
|
13990
|
+
app37.get("/public", (c) => {
|
|
13578
13991
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13579
13992
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13580
13993
|
return c.html(cachedHtml("public.html"));
|
|
13581
13994
|
});
|
|
13582
|
-
|
|
13995
|
+
app37.get("/chat", (c) => {
|
|
13583
13996
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13584
13997
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13585
13998
|
return c.html(cachedHtml("public.html"));
|
|
@@ -13598,9 +14011,9 @@ async function logViewerFetch(c, next) {
|
|
|
13598
14011
|
duration_ms: Date.now() - start
|
|
13599
14012
|
});
|
|
13600
14013
|
}
|
|
13601
|
-
|
|
13602
|
-
|
|
13603
|
-
|
|
14014
|
+
app37.use("/vnc-viewer.html", logViewerFetch);
|
|
14015
|
+
app37.use("/vnc-popout.html", logViewerFetch);
|
|
14016
|
+
app37.get("/vnc-popout.html", (c) => {
|
|
13604
14017
|
let html = htmlCache.get("vnc-popout.html");
|
|
13605
14018
|
if (!html) {
|
|
13606
14019
|
html = readFileSync20(resolve23(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -13613,7 +14026,7 @@ app35.get("/vnc-popout.html", (c) => {
|
|
|
13613
14026
|
}
|
|
13614
14027
|
return c.html(html);
|
|
13615
14028
|
});
|
|
13616
|
-
|
|
14029
|
+
app37.post("/api/vnc/client-event", async (c) => {
|
|
13617
14030
|
let body;
|
|
13618
14031
|
try {
|
|
13619
14032
|
body = await c.req.json();
|
|
@@ -13634,25 +14047,25 @@ app35.post("/api/vnc/client-event", async (c) => {
|
|
|
13634
14047
|
});
|
|
13635
14048
|
return c.json({ ok: true });
|
|
13636
14049
|
});
|
|
13637
|
-
|
|
14050
|
+
app37.get("/g/:slug", (c) => {
|
|
13638
14051
|
return c.html(brandedPublicHtml());
|
|
13639
14052
|
});
|
|
13640
|
-
|
|
14053
|
+
app37.get("/graph", (c) => {
|
|
13641
14054
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13642
14055
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13643
14056
|
return c.html(cachedHtml("graph.html"));
|
|
13644
14057
|
});
|
|
13645
|
-
|
|
14058
|
+
app37.get("/sessions", (c) => {
|
|
13646
14059
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13647
14060
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13648
14061
|
return c.html(cachedHtml("sessions.html"));
|
|
13649
14062
|
});
|
|
13650
|
-
|
|
14063
|
+
app37.get("/data", (c) => {
|
|
13651
14064
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13652
14065
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13653
14066
|
return c.html(cachedHtml("data.html"));
|
|
13654
14067
|
});
|
|
13655
|
-
|
|
14068
|
+
app37.get("/:slug", async (c, next) => {
|
|
13656
14069
|
const slug = c.req.param("slug");
|
|
13657
14070
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
13658
14071
|
const branding = loadBrandingCache(slug);
|
|
@@ -13662,15 +14075,15 @@ app35.get("/:slug", async (c, next) => {
|
|
|
13662
14075
|
await next();
|
|
13663
14076
|
});
|
|
13664
14077
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
13665
|
-
|
|
14078
|
+
app37.get("/favicon.ico", (c) => {
|
|
13666
14079
|
c.header("Cache-Control", "public, max-age=300");
|
|
13667
14080
|
return c.redirect(brandFaviconPath, 302);
|
|
13668
14081
|
});
|
|
13669
14082
|
}
|
|
13670
|
-
|
|
14083
|
+
app37.use("/*", serveStatic({ root: "./public" }));
|
|
13671
14084
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
13672
14085
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
13673
|
-
var httpServer = serve({ fetch:
|
|
14086
|
+
var httpServer = serve({ fetch: app37.fetch, port, hostname });
|
|
13674
14087
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
13675
14088
|
console.log("[boot] auth-mode summary: oauth=8 api-key=1 (api-key consumer: invokePublicAgent only)");
|
|
13676
14089
|
var SUBAPP_MANIFEST = [
|
|
@@ -13687,7 +14100,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
13687
14100
|
}
|
|
13688
14101
|
try {
|
|
13689
14102
|
const registered = [];
|
|
13690
|
-
for (const r of
|
|
14103
|
+
for (const r of app37.routes ?? []) {
|
|
13691
14104
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
13692
14105
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
13693
14106
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|