@rubytech/create-maxy-code 0.1.88 → 0.1.91
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 +99 -0
- package/dist/port-resolution.js +1 -1
- 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/premium-plugins/real-agent/plugins/brochures/skills/make-brochure/SKILL.md +1 -1
- 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-init.cjs +35 -3
- package/payload/server/server.js +547 -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 });
|
|
@@ -598,6 +601,7 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
598
601
|
import { readFileSync as readFileSync20, existsSync as existsSync22, watchFile } from "fs";
|
|
599
602
|
import { resolve as resolve23, join as join13, basename as basename5 } from "path";
|
|
600
603
|
import { homedir as homedir4 } from "os";
|
|
604
|
+
import { monitorEventLoopDelay } from "perf_hooks";
|
|
601
605
|
|
|
602
606
|
// app/lib/agent-slug-pattern.ts
|
|
603
607
|
var AGENT_SLUG_PATTERN = /^\/([a-z][a-z0-9-]{2,49})$/;
|
|
@@ -7191,29 +7195,22 @@ import crypto from "crypto";
|
|
|
7191
7195
|
import { resolve as resolvePath } from "path";
|
|
7192
7196
|
import { existsSync as existsSync13, mkdirSync as mkdirSync3, createWriteStream } from "fs";
|
|
7193
7197
|
|
|
7194
|
-
//
|
|
7195
|
-
async function
|
|
7196
|
-
const started = Date.now();
|
|
7198
|
+
// ../lib/admin-conversation-purge/src/index.ts
|
|
7199
|
+
async function purgeAdminConversationJsonls(args) {
|
|
7197
7200
|
const fetchImpl = args.fetchImpl ?? fetch;
|
|
7198
7201
|
const log = args.logger ?? ((line) => console.log(line));
|
|
7199
7202
|
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
7203
|
const purged = [];
|
|
7209
|
-
for (const sessionId of claudeSessionIds) {
|
|
7204
|
+
for (const sessionId of args.claudeSessionIds) {
|
|
7210
7205
|
const url = `${args.managerBase}/${encodeURIComponent(sessionId)}`;
|
|
7211
7206
|
let res;
|
|
7212
7207
|
try {
|
|
7213
7208
|
res = await fetchImpl(url, { method: "DELETE" });
|
|
7214
7209
|
} catch (err) {
|
|
7215
7210
|
const message2 = err instanceof Error ? err.message : String(err);
|
|
7216
|
-
log(
|
|
7211
|
+
log(
|
|
7212
|
+
`[admin-conversation-delete] conversationId=${id8} reason=jsonl-purge-failed claudeSessionId=${sessionId.slice(0, 8)} message=${message2}`
|
|
7213
|
+
);
|
|
7217
7214
|
return {
|
|
7218
7215
|
ok: false,
|
|
7219
7216
|
reason: "jsonl-purge-failed",
|
|
@@ -7228,8 +7225,15 @@ async function cascadeAdminConversationDelete(args) {
|
|
|
7228
7225
|
continue;
|
|
7229
7226
|
}
|
|
7230
7227
|
if (res.status === 409) {
|
|
7231
|
-
log(
|
|
7232
|
-
|
|
7228
|
+
log(
|
|
7229
|
+
`[admin-conversation-delete] conversationId=${id8} reason=pty-still-alive claudeSessionId=${sessionId.slice(0, 8)}`
|
|
7230
|
+
);
|
|
7231
|
+
return {
|
|
7232
|
+
ok: false,
|
|
7233
|
+
reason: "pty-still-alive",
|
|
7234
|
+
claudeSessionId: sessionId,
|
|
7235
|
+
claudeSessionIdsPurged: purged
|
|
7236
|
+
};
|
|
7233
7237
|
}
|
|
7234
7238
|
let message = `manager returned ${res.status}`;
|
|
7235
7239
|
try {
|
|
@@ -7238,7 +7242,9 @@ async function cascadeAdminConversationDelete(args) {
|
|
|
7238
7242
|
else if (typeof body.error === "string") message = body.error;
|
|
7239
7243
|
} catch {
|
|
7240
7244
|
}
|
|
7241
|
-
log(
|
|
7245
|
+
log(
|
|
7246
|
+
`[admin-conversation-delete] conversationId=${id8} reason=jsonl-purge-failed claudeSessionId=${sessionId.slice(0, 8)} message=${message}`
|
|
7247
|
+
);
|
|
7242
7248
|
return {
|
|
7243
7249
|
ok: false,
|
|
7244
7250
|
reason: "jsonl-purge-failed",
|
|
@@ -7248,6 +7254,45 @@ async function cascadeAdminConversationDelete(args) {
|
|
|
7248
7254
|
message
|
|
7249
7255
|
};
|
|
7250
7256
|
}
|
|
7257
|
+
return { ok: true, claudeSessionIdsPurged: purged };
|
|
7258
|
+
}
|
|
7259
|
+
|
|
7260
|
+
// app/lib/admin-conversation-cascade.ts
|
|
7261
|
+
async function cascadeAdminConversationDelete(args) {
|
|
7262
|
+
const started = Date.now();
|
|
7263
|
+
const fetchImpl = args.fetchImpl ?? fetch;
|
|
7264
|
+
const log = args.logger ?? ((line) => console.log(line));
|
|
7265
|
+
const id8 = args.conversationId.slice(0, 8);
|
|
7266
|
+
let claudeSessionIds;
|
|
7267
|
+
try {
|
|
7268
|
+
claudeSessionIds = args.claudeSessionIds ?? await getConversationClaudeSessionIds(args.conversationId, args.accountId);
|
|
7269
|
+
} catch (err) {
|
|
7270
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7271
|
+
log(`[admin-conversation-delete] conversationId=${id8} reason=graph-delete-failed claudeSessionIds-purged= message=transcript-resolve:${message}`);
|
|
7272
|
+
return { ok: false, reason: "graph-delete-failed", claudeSessionIdsPurged: [], message };
|
|
7273
|
+
}
|
|
7274
|
+
const purgeOutcome = await purgeAdminConversationJsonls({
|
|
7275
|
+
conversationId: args.conversationId,
|
|
7276
|
+
accountId: args.accountId,
|
|
7277
|
+
managerBase: args.managerBase,
|
|
7278
|
+
claudeSessionIds,
|
|
7279
|
+
fetchImpl,
|
|
7280
|
+
logger: log
|
|
7281
|
+
});
|
|
7282
|
+
if (!purgeOutcome.ok) {
|
|
7283
|
+
if (purgeOutcome.reason === "pty-still-alive") {
|
|
7284
|
+
return { ok: false, reason: "pty-still-alive", claudeSessionId: purgeOutcome.claudeSessionId };
|
|
7285
|
+
}
|
|
7286
|
+
return {
|
|
7287
|
+
ok: false,
|
|
7288
|
+
reason: "jsonl-purge-failed",
|
|
7289
|
+
claudeSessionId: purgeOutcome.claudeSessionId,
|
|
7290
|
+
claudeSessionIdsPurged: purgeOutcome.claudeSessionIdsPurged,
|
|
7291
|
+
status: purgeOutcome.status,
|
|
7292
|
+
message: purgeOutcome.message
|
|
7293
|
+
};
|
|
7294
|
+
}
|
|
7295
|
+
const purged = purgeOutcome.claudeSessionIdsPurged;
|
|
7251
7296
|
let found;
|
|
7252
7297
|
try {
|
|
7253
7298
|
({ found } = await deleteConversation(args.conversationId));
|
|
@@ -8695,13 +8740,13 @@ async function cdpNavigateNewTab(url, opts = {}) {
|
|
|
8695
8740
|
// server/routes/admin/device-browser.ts
|
|
8696
8741
|
var app18 = new Hono();
|
|
8697
8742
|
app18.post("/navigate", async (c) => {
|
|
8698
|
-
const
|
|
8743
|
+
const TAG22 = "[device-url:click]";
|
|
8699
8744
|
let body;
|
|
8700
8745
|
try {
|
|
8701
8746
|
body = await c.req.json();
|
|
8702
8747
|
} catch (err) {
|
|
8703
8748
|
const detail = err instanceof Error ? err.message : String(err);
|
|
8704
|
-
console.error(`${
|
|
8749
|
+
console.error(`${TAG22} reject reason=body-not-json detail=${detail} browser=fallback navigateResult=error`);
|
|
8705
8750
|
return c.json(
|
|
8706
8751
|
{ ok: false, navigateResult: "error", browser: "fallback", detail: "Request body was not valid JSON" },
|
|
8707
8752
|
400
|
|
@@ -8711,7 +8756,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8711
8756
|
const intent = typeof body.intent === "string" ? body.intent : "";
|
|
8712
8757
|
const hostname2 = typeof body.hostname === "string" ? body.hostname : "";
|
|
8713
8758
|
if (!url) {
|
|
8714
|
-
console.error(`${
|
|
8759
|
+
console.error(`${TAG22} reject reason=missing-url intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`);
|
|
8715
8760
|
return c.json(
|
|
8716
8761
|
{ ok: false, navigateResult: "error", browser: "fallback", detail: "url field is required" },
|
|
8717
8762
|
400
|
|
@@ -8721,7 +8766,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8721
8766
|
try {
|
|
8722
8767
|
parsed = new URL(url);
|
|
8723
8768
|
} catch {
|
|
8724
|
-
console.error(`${
|
|
8769
|
+
console.error(`${TAG22} reject reason=url-malformed intent=${JSON.stringify(intent)} url=${url} browser=fallback navigateResult=error`);
|
|
8725
8770
|
return c.json(
|
|
8726
8771
|
{ ok: false, navigateResult: "error", browser: "fallback", detail: "url is not a valid URL" },
|
|
8727
8772
|
400
|
|
@@ -8729,7 +8774,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8729
8774
|
}
|
|
8730
8775
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
8731
8776
|
console.error(
|
|
8732
|
-
`${
|
|
8777
|
+
`${TAG22} reject reason=scheme-not-allowed scheme=${parsed.protocol} intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`
|
|
8733
8778
|
);
|
|
8734
8779
|
return c.json(
|
|
8735
8780
|
{
|
|
@@ -8745,7 +8790,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8745
8790
|
const cdpOk = await ensureCdp(transport);
|
|
8746
8791
|
if (!cdpOk) {
|
|
8747
8792
|
console.error(
|
|
8748
|
-
`${
|
|
8793
|
+
`${TAG22} intent=${JSON.stringify(intent)} browser=fallback navigateResult=cdp-unreachable hostname=${JSON.stringify(hostname2)}`
|
|
8749
8794
|
);
|
|
8750
8795
|
return c.json(
|
|
8751
8796
|
{
|
|
@@ -8761,7 +8806,7 @@ app18.post("/navigate", async (c) => {
|
|
|
8761
8806
|
const browser = outcome.result === "ok" ? "vnc" : "fallback";
|
|
8762
8807
|
const detailStr = outcome.detail ? ` detail=${JSON.stringify(outcome.detail.length > 230 ? outcome.detail.slice(0, 227) + "..." : outcome.detail)}` : "";
|
|
8763
8808
|
console.error(
|
|
8764
|
-
`${
|
|
8809
|
+
`${TAG22} intent=${JSON.stringify(intent)} browser=${browser} navigateResult=${outcome.result} hostname=${JSON.stringify(hostname2)} targetId=${outcome.targetId ?? "none"}${detailStr}`
|
|
8765
8810
|
);
|
|
8766
8811
|
if (outcome.result !== "ok") {
|
|
8767
8812
|
return c.json(
|
|
@@ -8792,18 +8837,18 @@ var ALLOWED_EVENTS2 = /* @__PURE__ */ new Set([
|
|
|
8792
8837
|
]);
|
|
8793
8838
|
var app19 = new Hono();
|
|
8794
8839
|
app19.post("/", async (c) => {
|
|
8795
|
-
const
|
|
8840
|
+
const TAG22 = "[admin:events]";
|
|
8796
8841
|
let body;
|
|
8797
8842
|
try {
|
|
8798
8843
|
body = await c.req.json();
|
|
8799
8844
|
} catch (err) {
|
|
8800
8845
|
const detail = err instanceof Error ? err.message : String(err);
|
|
8801
|
-
console.error(`${
|
|
8846
|
+
console.error(`${TAG22} reject reason=body-not-json detail=${detail}`);
|
|
8802
8847
|
return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
|
|
8803
8848
|
}
|
|
8804
8849
|
const event = typeof body.event === "string" ? body.event : "";
|
|
8805
8850
|
if (!ALLOWED_EVENTS2.has(event)) {
|
|
8806
|
-
console.error(`${
|
|
8851
|
+
console.error(`${TAG22} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
|
|
8807
8852
|
return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
|
|
8808
8853
|
}
|
|
8809
8854
|
const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
|
|
@@ -11633,7 +11678,7 @@ function pruneNode(node, warnedClasses, conversationWarnings) {
|
|
|
11633
11678
|
var graph_subgraph_default = app23;
|
|
11634
11679
|
|
|
11635
11680
|
// server/routes/admin/graph-delete.ts
|
|
11636
|
-
var ALLOWED_BY = ["graph-page", "graph-drag-trash"];
|
|
11681
|
+
var ALLOWED_BY = ["graph-page", "graph-drag-trash", "graph-side-panel-trash"];
|
|
11637
11682
|
var app24 = new Hono();
|
|
11638
11683
|
app24.post("/", requireAdminSession, async (c) => {
|
|
11639
11684
|
const cacheKey = c.var.cacheKey;
|
|
@@ -11663,17 +11708,108 @@ app24.post("/", requireAdminSession, async (c) => {
|
|
|
11663
11708
|
const lookup = await session.run(
|
|
11664
11709
|
`MATCH (n)
|
|
11665
11710
|
WHERE elementId(n) = $elementId AND n.accountId = $accountId
|
|
11666
|
-
RETURN labels(n) AS labels LIMIT 1`,
|
|
11711
|
+
RETURN labels(n) AS labels, n.conversationId AS conversationId LIMIT 1`,
|
|
11667
11712
|
{ elementId, accountId }
|
|
11668
11713
|
);
|
|
11669
11714
|
if (lookup.records.length === 0) {
|
|
11670
11715
|
const elapsed2 = Date.now() - started;
|
|
11671
11716
|
console.error(
|
|
11672
|
-
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels= result=not-found ms=${elapsed2}`
|
|
11717
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels= route=trash result=not-found ms=${elapsed2}`
|
|
11673
11718
|
);
|
|
11674
11719
|
return c.json({ error: "Node not found" }, 404);
|
|
11675
11720
|
}
|
|
11676
11721
|
const preflightLabels = lookup.records[0].get("labels") ?? [];
|
|
11722
|
+
const conversationId = lookup.records[0].get("conversationId");
|
|
11723
|
+
if (preflightLabels.includes("AdminConversation")) {
|
|
11724
|
+
if (!conversationId) {
|
|
11725
|
+
const elapsed3 = Date.now() - started;
|
|
11726
|
+
console.error(
|
|
11727
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${preflightLabels.join(",")} route=cascade result=error ms=${elapsed3} err="AdminConversation node has no conversationId"`
|
|
11728
|
+
);
|
|
11729
|
+
return c.json({ error: "AdminConversation node is missing conversationId" }, 500);
|
|
11730
|
+
}
|
|
11731
|
+
const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "graph-page-cascade" });
|
|
11732
|
+
const managerBase3 = `http://127.0.0.1:${managerPort}`;
|
|
11733
|
+
try {
|
|
11734
|
+
await session.close();
|
|
11735
|
+
} catch {
|
|
11736
|
+
}
|
|
11737
|
+
const outcome = await cascadeAdminConversationDelete({
|
|
11738
|
+
conversationId,
|
|
11739
|
+
accountId,
|
|
11740
|
+
managerBase: managerBase3
|
|
11741
|
+
});
|
|
11742
|
+
const elapsed2 = Date.now() - started;
|
|
11743
|
+
const labelSummary2 = preflightLabels.join(",");
|
|
11744
|
+
if (outcome.ok) {
|
|
11745
|
+
console.error(
|
|
11746
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary2} route=cascade result=ok ms=${elapsed2}`
|
|
11747
|
+
);
|
|
11748
|
+
const response2 = {
|
|
11749
|
+
route: "cascade",
|
|
11750
|
+
elementId,
|
|
11751
|
+
conversationId,
|
|
11752
|
+
labels: preflightLabels,
|
|
11753
|
+
claudeSessionIds: outcome.claudeSessionIds
|
|
11754
|
+
};
|
|
11755
|
+
return c.json(response2);
|
|
11756
|
+
}
|
|
11757
|
+
if (outcome.reason === "pty-still-alive") {
|
|
11758
|
+
console.error(
|
|
11759
|
+
`[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}`
|
|
11760
|
+
);
|
|
11761
|
+
return c.json(
|
|
11762
|
+
{
|
|
11763
|
+
error: "pty-still-alive",
|
|
11764
|
+
detail: "stop the session before deleting",
|
|
11765
|
+
claudeSessionId: outcome.claudeSessionId,
|
|
11766
|
+
conversationId
|
|
11767
|
+
},
|
|
11768
|
+
409
|
|
11769
|
+
);
|
|
11770
|
+
}
|
|
11771
|
+
if (outcome.reason === "conversation-not-found") {
|
|
11772
|
+
console.error(
|
|
11773
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary2} route=cascade result=ok-already-gone ms=${elapsed2}`
|
|
11774
|
+
);
|
|
11775
|
+
const response2 = {
|
|
11776
|
+
route: "cascade",
|
|
11777
|
+
elementId,
|
|
11778
|
+
conversationId,
|
|
11779
|
+
labels: preflightLabels,
|
|
11780
|
+
claudeSessionIds: []
|
|
11781
|
+
};
|
|
11782
|
+
return c.json(response2);
|
|
11783
|
+
}
|
|
11784
|
+
if (outcome.reason === "jsonl-purge-failed") {
|
|
11785
|
+
console.error(
|
|
11786
|
+
`[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}"`
|
|
11787
|
+
);
|
|
11788
|
+
const status = outcome.status >= 400 && outcome.status < 600 ? outcome.status : 502;
|
|
11789
|
+
return c.json(
|
|
11790
|
+
{
|
|
11791
|
+
error: "jsonl-purge-failed",
|
|
11792
|
+
detail: outcome.message,
|
|
11793
|
+
claudeSessionId: outcome.claudeSessionId,
|
|
11794
|
+
conversationId,
|
|
11795
|
+
claudeSessionIdsPurged: outcome.claudeSessionIdsPurged
|
|
11796
|
+
},
|
|
11797
|
+
status
|
|
11798
|
+
);
|
|
11799
|
+
}
|
|
11800
|
+
console.error(
|
|
11801
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary2} route=cascade result=graph-delete-failed ms=${elapsed2} err="${outcome.message}"`
|
|
11802
|
+
);
|
|
11803
|
+
return c.json(
|
|
11804
|
+
{
|
|
11805
|
+
error: "graph-delete-failed",
|
|
11806
|
+
detail: outcome.message,
|
|
11807
|
+
conversationId,
|
|
11808
|
+
claudeSessionIdsPurged: outcome.claudeSessionIdsPurged
|
|
11809
|
+
},
|
|
11810
|
+
500
|
|
11811
|
+
);
|
|
11812
|
+
}
|
|
11677
11813
|
const result = await trashNode({
|
|
11678
11814
|
session,
|
|
11679
11815
|
accountId,
|
|
@@ -11683,9 +11819,10 @@ app24.post("/", requireAdminSession, async (c) => {
|
|
|
11683
11819
|
const elapsed = Date.now() - started;
|
|
11684
11820
|
const labelSummary = (result.labels.length > 0 ? result.labels : preflightLabels).join(",");
|
|
11685
11821
|
console.error(
|
|
11686
|
-
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary} result=ok ms=${elapsed}`
|
|
11822
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} by=${by} labels=${labelSummary} route=trash result=ok ms=${elapsed}`
|
|
11687
11823
|
);
|
|
11688
11824
|
const response = {
|
|
11825
|
+
route: "trash",
|
|
11689
11826
|
elementId: result.nodeId,
|
|
11690
11827
|
labels: result.labels.length > 0 ? result.labels : preflightLabels,
|
|
11691
11828
|
trashedAt: result.trashedAt,
|
|
@@ -11977,9 +12114,137 @@ var WRITE_CYPHER = `
|
|
|
11977
12114
|
`;
|
|
11978
12115
|
var graph_default_view_default = app27;
|
|
11979
12116
|
|
|
11980
|
-
// server/routes/admin/
|
|
12117
|
+
// server/routes/admin/session-defaults.ts
|
|
11981
12118
|
var app28 = new Hono();
|
|
11982
|
-
|
|
12119
|
+
var MODE_OPTIONS = ["default", "acceptEdits", "plan", "auto", "bypassPermissions"];
|
|
12120
|
+
var MODEL_OPTIONS = ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5"];
|
|
12121
|
+
app28.get("/", requireAdminSession, async (c) => {
|
|
12122
|
+
const cacheKey = c.var.cacheKey;
|
|
12123
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
12124
|
+
const userId = getUserIdForSession(cacheKey);
|
|
12125
|
+
if (!accountId || !userId) {
|
|
12126
|
+
console.error('[session-defaults] rejected op=load reason="missing account or user context"');
|
|
12127
|
+
return c.json({ error: "Account and user context required for session defaults" }, 401);
|
|
12128
|
+
}
|
|
12129
|
+
const started = Date.now();
|
|
12130
|
+
const session = getSession();
|
|
12131
|
+
try {
|
|
12132
|
+
const result = await session.executeRead(async (tx) => {
|
|
12133
|
+
return await tx.run(READ_CYPHER2, { accountId, userId });
|
|
12134
|
+
});
|
|
12135
|
+
const record = result.records[0];
|
|
12136
|
+
const rawMode = record?.get("permissionMode");
|
|
12137
|
+
const rawModel = record?.get("model");
|
|
12138
|
+
const permissionMode = MODE_OPTIONS.includes(rawMode ?? "") ? rawMode : "default";
|
|
12139
|
+
const model = MODEL_OPTIONS.includes(rawModel ?? "") ? rawModel : null;
|
|
12140
|
+
const elapsed = Date.now() - started;
|
|
12141
|
+
console.error(
|
|
12142
|
+
`[session-defaults] load account=${accountId} user=${userId} permissionMode=${permissionMode} model=${model ?? "null"} ms=${elapsed}`
|
|
12143
|
+
);
|
|
12144
|
+
return c.json({ permissionMode, model });
|
|
12145
|
+
} catch (err) {
|
|
12146
|
+
const elapsed = Date.now() - started;
|
|
12147
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
12148
|
+
console.error(
|
|
12149
|
+
`[session-defaults] rejected op=load account=${accountId} reason="${message}" ms=${elapsed}`
|
|
12150
|
+
);
|
|
12151
|
+
return c.json({ error: `Session defaults unavailable: ${message}` }, 503);
|
|
12152
|
+
} finally {
|
|
12153
|
+
try {
|
|
12154
|
+
await session.close();
|
|
12155
|
+
} catch {
|
|
12156
|
+
}
|
|
12157
|
+
}
|
|
12158
|
+
});
|
|
12159
|
+
app28.put("/", requireAdminSession, async (c) => {
|
|
12160
|
+
const cacheKey = c.var.cacheKey;
|
|
12161
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
12162
|
+
const userId = getUserIdForSession(cacheKey);
|
|
12163
|
+
if (!accountId || !userId) {
|
|
12164
|
+
console.error('[session-defaults] rejected op=save reason="missing account or user context"');
|
|
12165
|
+
return c.json({ error: "Account and user context required for session defaults" }, 401);
|
|
12166
|
+
}
|
|
12167
|
+
const body = await safeJson(c);
|
|
12168
|
+
if (!body) {
|
|
12169
|
+
return c.json({ error: "Request body must be JSON" }, 400);
|
|
12170
|
+
}
|
|
12171
|
+
const validation = validateBody3(body);
|
|
12172
|
+
if (!validation.ok) {
|
|
12173
|
+
console.error(
|
|
12174
|
+
`[session-defaults] rejected op=save account=${accountId} reason="${validation.reason}"`
|
|
12175
|
+
);
|
|
12176
|
+
return c.json({ error: validation.reason }, 400);
|
|
12177
|
+
}
|
|
12178
|
+
const { permissionMode, model } = validation;
|
|
12179
|
+
const started = Date.now();
|
|
12180
|
+
const session = getSession();
|
|
12181
|
+
try {
|
|
12182
|
+
await session.executeWrite(async (tx) => {
|
|
12183
|
+
return await tx.run(WRITE_CYPHER2, {
|
|
12184
|
+
accountId,
|
|
12185
|
+
userId,
|
|
12186
|
+
permissionMode,
|
|
12187
|
+
model,
|
|
12188
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12189
|
+
});
|
|
12190
|
+
});
|
|
12191
|
+
const elapsed = Date.now() - started;
|
|
12192
|
+
console.error(
|
|
12193
|
+
`[session-defaults] save account=${accountId} user=${userId} permissionMode=${permissionMode} model=${model ?? "null"} ms=${elapsed}`
|
|
12194
|
+
);
|
|
12195
|
+
return c.json({ permissionMode, model });
|
|
12196
|
+
} catch (err) {
|
|
12197
|
+
const elapsed = Date.now() - started;
|
|
12198
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
12199
|
+
console.error(
|
|
12200
|
+
`[session-defaults] rejected op=save account=${accountId} reason="${message}" ms=${elapsed}`
|
|
12201
|
+
);
|
|
12202
|
+
return c.json({ error: `Failed to save session defaults: ${message}` }, 503);
|
|
12203
|
+
} finally {
|
|
12204
|
+
try {
|
|
12205
|
+
await session.close();
|
|
12206
|
+
} catch {
|
|
12207
|
+
}
|
|
12208
|
+
}
|
|
12209
|
+
});
|
|
12210
|
+
function validateBody3(body) {
|
|
12211
|
+
if (typeof body.permissionMode !== "string") {
|
|
12212
|
+
return { ok: false, reason: "permissionMode must be a string" };
|
|
12213
|
+
}
|
|
12214
|
+
if (!MODE_OPTIONS.includes(body.permissionMode)) {
|
|
12215
|
+
return { ok: false, reason: `permissionMode "${body.permissionMode}" is not one of ${MODE_OPTIONS.join(", ")}` };
|
|
12216
|
+
}
|
|
12217
|
+
if (!("model" in body)) {
|
|
12218
|
+
return { ok: false, reason: "model is required (use null for no override)" };
|
|
12219
|
+
}
|
|
12220
|
+
if (body.model !== null && typeof body.model !== "string") {
|
|
12221
|
+
return { ok: false, reason: "model must be a string or null" };
|
|
12222
|
+
}
|
|
12223
|
+
if (body.model !== null && !MODEL_OPTIONS.includes(body.model)) {
|
|
12224
|
+
return { ok: false, reason: `model "${body.model}" is not one of ${MODEL_OPTIONS.join(", ")} (or null)` };
|
|
12225
|
+
}
|
|
12226
|
+
return {
|
|
12227
|
+
ok: true,
|
|
12228
|
+
permissionMode: body.permissionMode,
|
|
12229
|
+
model: body.model
|
|
12230
|
+
};
|
|
12231
|
+
}
|
|
12232
|
+
var READ_CYPHER2 = `
|
|
12233
|
+
OPTIONAL MATCH (p:SpawnPreference {accountId: $accountId, userId: $userId})
|
|
12234
|
+
RETURN p.permissionMode AS permissionMode, p.model AS model
|
|
12235
|
+
`;
|
|
12236
|
+
var WRITE_CYPHER2 = `
|
|
12237
|
+
MERGE (p:SpawnPreference {accountId: $accountId, userId: $userId})
|
|
12238
|
+
SET p.permissionMode = $permissionMode,
|
|
12239
|
+
p.model = $model,
|
|
12240
|
+
p.updatedAt = $updatedAt
|
|
12241
|
+
RETURN p.permissionMode AS permissionMode
|
|
12242
|
+
`;
|
|
12243
|
+
var session_defaults_default = app28;
|
|
12244
|
+
|
|
12245
|
+
// server/routes/admin/file-attach.ts
|
|
12246
|
+
var app29 = new Hono();
|
|
12247
|
+
app29.post("/", async (c) => {
|
|
11983
12248
|
try {
|
|
11984
12249
|
const body = await c.req.json();
|
|
11985
12250
|
const { filePath, accountId } = body;
|
|
@@ -12002,7 +12267,7 @@ app28.post("/", async (c) => {
|
|
|
12002
12267
|
return c.json({ error: message }, 500);
|
|
12003
12268
|
}
|
|
12004
12269
|
});
|
|
12005
|
-
var file_attach_default =
|
|
12270
|
+
var file_attach_default = app29;
|
|
12006
12271
|
|
|
12007
12272
|
// server/routes/admin/sidebar-artefacts.ts
|
|
12008
12273
|
import neo4j2 from "neo4j-driver";
|
|
@@ -12012,8 +12277,8 @@ import { existsSync as existsSync16 } from "fs";
|
|
|
12012
12277
|
var LIMIT = 50;
|
|
12013
12278
|
var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
|
|
12014
12279
|
var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
|
|
12015
|
-
var
|
|
12016
|
-
|
|
12280
|
+
var app30 = new Hono();
|
|
12281
|
+
app30.get("/", requireAdminSession, async (c) => {
|
|
12017
12282
|
const cacheKey = c.var.cacheKey;
|
|
12018
12283
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12019
12284
|
if (!accountId) {
|
|
@@ -12219,7 +12484,7 @@ function isWithin(target, root) {
|
|
|
12219
12484
|
const rel = relative2(root, target);
|
|
12220
12485
|
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
12221
12486
|
}
|
|
12222
|
-
var sidebar_artefacts_default =
|
|
12487
|
+
var sidebar_artefacts_default = app30;
|
|
12223
12488
|
|
|
12224
12489
|
// server/routes/admin/sidebar-artefact-save.ts
|
|
12225
12490
|
import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
|
|
@@ -12227,8 +12492,8 @@ import { resolve as resolve18 } from "path";
|
|
|
12227
12492
|
import { existsSync as existsSync17 } from "fs";
|
|
12228
12493
|
var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
|
|
12229
12494
|
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
|
-
|
|
12495
|
+
var app31 = new Hono();
|
|
12496
|
+
app31.post("/", requireAdminSession, async (c) => {
|
|
12232
12497
|
const cacheKey = c.var.cacheKey;
|
|
12233
12498
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12234
12499
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -12340,15 +12605,15 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
12340
12605
|
function relPath(absPath, root) {
|
|
12341
12606
|
return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
|
|
12342
12607
|
}
|
|
12343
|
-
var sidebar_artefact_save_default =
|
|
12608
|
+
var sidebar_artefact_save_default = app31;
|
|
12344
12609
|
|
|
12345
12610
|
// server/routes/admin/sidebar-artefact-content.ts
|
|
12346
12611
|
import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
|
|
12347
12612
|
import { existsSync as existsSync18 } from "fs";
|
|
12348
12613
|
import { resolve as resolve19 } from "path";
|
|
12349
12614
|
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
|
-
|
|
12615
|
+
var app32 = new Hono();
|
|
12616
|
+
app32.get("/", requireAdminSession, async (c) => {
|
|
12352
12617
|
const cacheKey = c.var.cacheKey;
|
|
12353
12618
|
const accountId = getAccountIdForSession(cacheKey);
|
|
12354
12619
|
if (!accountId) return new Response("Unauthorized", { status: 401 });
|
|
@@ -12389,7 +12654,7 @@ app31.get("/", requireAdminSession, async (c) => {
|
|
|
12389
12654
|
}
|
|
12390
12655
|
});
|
|
12391
12656
|
});
|
|
12392
|
-
var sidebar_artefact_content_default =
|
|
12657
|
+
var sidebar_artefact_content_default = app32;
|
|
12393
12658
|
|
|
12394
12659
|
// server/routes/admin/health.ts
|
|
12395
12660
|
import { existsSync as existsSync19, readFileSync as readFileSync17 } from "fs";
|
|
@@ -12434,8 +12699,8 @@ async function probeConversationDb() {
|
|
|
12434
12699
|
});
|
|
12435
12700
|
}
|
|
12436
12701
|
}
|
|
12437
|
-
var
|
|
12438
|
-
|
|
12702
|
+
var app33 = new Hono();
|
|
12703
|
+
app33.get("/", async (c) => {
|
|
12439
12704
|
const version = readVersion();
|
|
12440
12705
|
const probe = await probeConversationDb();
|
|
12441
12706
|
const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
|
|
@@ -12457,38 +12722,187 @@ app32.get("/", async (c) => {
|
|
|
12457
12722
|
uptimeMs
|
|
12458
12723
|
});
|
|
12459
12724
|
});
|
|
12460
|
-
var health_default2 =
|
|
12725
|
+
var health_default2 = app33;
|
|
12726
|
+
|
|
12727
|
+
// server/routes/admin/linkedin-ingest.ts
|
|
12728
|
+
var TAG20 = "[linkedin-ingest-route]";
|
|
12729
|
+
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}$/;
|
|
12730
|
+
var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
12731
|
+
var LINKEDIN_URL = /^https:\/\/www\.linkedin\.com\//;
|
|
12732
|
+
function rejectSchema(reason, missing = []) {
|
|
12733
|
+
return { ok: false, status: 400, error: "schema", reason, missing };
|
|
12734
|
+
}
|
|
12735
|
+
function validate(body) {
|
|
12736
|
+
if (!body || typeof body !== "object") return rejectSchema("not-object");
|
|
12737
|
+
const b = body;
|
|
12738
|
+
const missing = [];
|
|
12739
|
+
if (b.source !== "linkedin") missing.push("source");
|
|
12740
|
+
if (b.kind !== "profile" && b.kind !== "thread") missing.push("kind");
|
|
12741
|
+
if (typeof b.capturedAt !== "string" || !ISO.test(b.capturedAt)) missing.push("capturedAt");
|
|
12742
|
+
if (typeof b.pageUrl !== "string" || !LINKEDIN_URL.test(b.pageUrl)) missing.push("pageUrl");
|
|
12743
|
+
if (typeof b.dispatchId !== "string" || !UUID.test(b.dispatchId)) missing.push("dispatchId");
|
|
12744
|
+
if (missing.length) return rejectSchema("envelope", missing);
|
|
12745
|
+
if (b.kind === "profile") {
|
|
12746
|
+
const p = b.profile;
|
|
12747
|
+
if (!p || typeof p !== "object") return rejectSchema("profile-shape", ["profile"]);
|
|
12748
|
+
const pMissing = [];
|
|
12749
|
+
if (typeof p.name !== "string" || !p.name.trim()) pMissing.push("profile.name");
|
|
12750
|
+
if (typeof p.headline !== "string") pMissing.push("profile.headline");
|
|
12751
|
+
if (typeof p.bodyText !== "string" || !p.bodyText.trim()) pMissing.push("profile.bodyText");
|
|
12752
|
+
if (pMissing.length) return rejectSchema("profile-shape", pMissing);
|
|
12753
|
+
} else {
|
|
12754
|
+
const t = b.thread;
|
|
12755
|
+
if (!t || typeof t !== "object") return rejectSchema("thread-shape", ["thread"]);
|
|
12756
|
+
const tMissing = [];
|
|
12757
|
+
if (!Array.isArray(t.participants) || t.participants.length === 0) tMissing.push("thread.participants");
|
|
12758
|
+
if (typeof t.bodyText !== "string" || !t.bodyText.trim()) tMissing.push("thread.bodyText");
|
|
12759
|
+
if (tMissing.length) return rejectSchema("thread-shape", tMissing);
|
|
12760
|
+
}
|
|
12761
|
+
return { ok: true, envelope: b };
|
|
12762
|
+
}
|
|
12763
|
+
function buildInitialMessage(env) {
|
|
12764
|
+
const header = [
|
|
12765
|
+
"LinkedIn ingest \u2014 dispatchId=" + env.dispatchId,
|
|
12766
|
+
"kind=" + env.kind,
|
|
12767
|
+
"sourceUrl=" + env.pageUrl,
|
|
12768
|
+
"capturedAt=" + env.capturedAt
|
|
12769
|
+
].join(" \xB7 ");
|
|
12770
|
+
if (env.kind === "profile" && env.profile) {
|
|
12771
|
+
const p = env.profile;
|
|
12772
|
+
return [
|
|
12773
|
+
header,
|
|
12774
|
+
"",
|
|
12775
|
+
"Surface: LinkedIn profile. Run the document-ingest skill in document mode against the body below, anchored to a Person subject for this profile.",
|
|
12776
|
+
"",
|
|
12777
|
+
"Conservative-extraction rules apply (see Task 234 spec):",
|
|
12778
|
+
"- One :KnowledgeDocument MERGE keyed on sourceUrl=" + env.pageUrl + " with the verbatim body as body, plus one :Section:Note child with the summary.",
|
|
12779
|
+
"- MERGE :Person on canonical key (name + sourceUrl). When the body assertively states currentCompany, MERGE :Organization and create (:Person)-[:WORKS_AT]->(:Organization).",
|
|
12780
|
+
"- 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 + ".",
|
|
12781
|
+
"- (:KD)-[:MENTIONS]->(:Person) for the subject, (:KD)-[:MENTIONS]->(:Organization) for the employer, (:KD)-[:MENTIONS]->(<derived entity>) for each.",
|
|
12782
|
+
"- No :Communication, :ConversationArchive, or :Message nodes \u2014 those belong to other flows.",
|
|
12783
|
+
"",
|
|
12784
|
+
"Subject (assertive):",
|
|
12785
|
+
"- name=" + p.name,
|
|
12786
|
+
"- headline=" + p.headline,
|
|
12787
|
+
"- location=" + (p.location || "(none)"),
|
|
12788
|
+
"- currentTitle=" + (p.currentTitle || "(none)"),
|
|
12789
|
+
"- currentCompany=" + (p.currentCompany || "(none)"),
|
|
12790
|
+
"",
|
|
12791
|
+
"Body (verbatim, write to :KnowledgeDocument.body):",
|
|
12792
|
+
p.bodyText
|
|
12793
|
+
].join("\n");
|
|
12794
|
+
}
|
|
12795
|
+
if (env.kind === "thread" && env.thread) {
|
|
12796
|
+
const t = env.thread;
|
|
12797
|
+
const participantList = t.participants.map(function(p) {
|
|
12798
|
+
return p.name + (p.profileUrl ? " (" + p.profileUrl + ")" : "");
|
|
12799
|
+
}).join(", ");
|
|
12800
|
+
return [
|
|
12801
|
+
header,
|
|
12802
|
+
"",
|
|
12803
|
+
"Surface: LinkedIn DM thread. Run the document-ingest skill in document mode against the transcript below.",
|
|
12804
|
+
"",
|
|
12805
|
+
"Conservative-extraction rules apply (see Task 234 spec):",
|
|
12806
|
+
"- One :KnowledgeDocument MERGE keyed on sourceUrl=" + env.pageUrl + " with the verbatim transcript as body, plus one :Section:Note child with the summary.",
|
|
12807
|
+
"- (:KD)-[:PARTICIPANT]->(:Person) for each participant. MERGE :Person on (name, profileUrl) where present.",
|
|
12808
|
+
"- 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 + ".",
|
|
12809
|
+
"- (: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.",
|
|
12810
|
+
"- No :Communication, :ConversationArchive, or :Message nodes \u2014 those belong to other flows.",
|
|
12811
|
+
"",
|
|
12812
|
+
"Participants:",
|
|
12813
|
+
participantList,
|
|
12814
|
+
"",
|
|
12815
|
+
"Transcript (verbatim, write to :KnowledgeDocument.body):",
|
|
12816
|
+
t.bodyText
|
|
12817
|
+
].join("\n");
|
|
12818
|
+
}
|
|
12819
|
+
return header;
|
|
12820
|
+
}
|
|
12821
|
+
var app34 = new Hono();
|
|
12822
|
+
app34.post("/", requireAdminSession, async (c) => {
|
|
12823
|
+
let body;
|
|
12824
|
+
try {
|
|
12825
|
+
body = await c.req.json();
|
|
12826
|
+
} catch {
|
|
12827
|
+
console.error(TAG20 + " rejected status=400 reason=schema:body-not-json");
|
|
12828
|
+
return c.json({ ok: false, error: "schema", reason: "body-not-json" }, 400);
|
|
12829
|
+
}
|
|
12830
|
+
const v = validate(body);
|
|
12831
|
+
if (!v.ok) {
|
|
12832
|
+
console.error(TAG20 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
|
|
12833
|
+
return c.json({ ok: false, error: v.error, reason: v.reason, missing: v.missing }, v.status);
|
|
12834
|
+
}
|
|
12835
|
+
const envelope = v.envelope;
|
|
12836
|
+
const cacheKey = c.var.cacheKey ?? "";
|
|
12837
|
+
const senderId = getAccountIdForSession(cacheKey) ?? "";
|
|
12838
|
+
if (!senderId) {
|
|
12839
|
+
console.error(TAG20 + " rejected status=500 reason=admin-account-not-resolved");
|
|
12840
|
+
return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
|
|
12841
|
+
}
|
|
12842
|
+
const userId = getUserIdForSession(cacheKey) ?? void 0;
|
|
12843
|
+
const payloadBytes = JSON.stringify(envelope).length;
|
|
12844
|
+
console.log(
|
|
12845
|
+
TAG20 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
|
|
12846
|
+
);
|
|
12847
|
+
const initialMessage = buildInitialMessage(envelope);
|
|
12848
|
+
const spawnStart = Date.now();
|
|
12849
|
+
const { response, claudeSessionId } = await performSpawnWithInitialMessage({
|
|
12850
|
+
senderId,
|
|
12851
|
+
userId,
|
|
12852
|
+
role: "admin",
|
|
12853
|
+
channel: "linkedin-extension",
|
|
12854
|
+
permissionMode: void 0,
|
|
12855
|
+
hidden: true,
|
|
12856
|
+
specialist: "database-operator",
|
|
12857
|
+
model: void 0,
|
|
12858
|
+
initialMessage
|
|
12859
|
+
});
|
|
12860
|
+
if (!response.ok) {
|
|
12861
|
+
const detail = await response.text().catch(() => "");
|
|
12862
|
+
console.error(
|
|
12863
|
+
TAG20 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + response.status + " ms=" + (Date.now() - spawnStart) + " detail=" + detail.slice(0, 200)
|
|
12864
|
+
);
|
|
12865
|
+
return c.json({ ok: false, error: "dispatch-failed", upstreamStatus: response.status, detail: detail.slice(0, 500) }, 502);
|
|
12866
|
+
}
|
|
12867
|
+
console.log(
|
|
12868
|
+
TAG20 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + (claudeSessionId ?? "unknown") + " ms=" + (Date.now() - spawnStart)
|
|
12869
|
+
);
|
|
12870
|
+
return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: claudeSessionId }, 202);
|
|
12871
|
+
});
|
|
12872
|
+
var linkedin_ingest_default = app34;
|
|
12461
12873
|
|
|
12462
12874
|
// 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
|
-
|
|
12875
|
+
var app35 = new Hono();
|
|
12876
|
+
app35.route("/session", session_default);
|
|
12877
|
+
app35.route("/new-session-failure", new_session_failure_default);
|
|
12878
|
+
app35.route("/new-session-submit", new_session_submit_default);
|
|
12879
|
+
app35.route("/logs", logs_default);
|
|
12880
|
+
app35.route("/claude-info", claude_info_default);
|
|
12881
|
+
app35.route("/attachment", attachment_default);
|
|
12882
|
+
app35.route("/agents", agents_default);
|
|
12883
|
+
app35.route("/sessions", sessions_default);
|
|
12884
|
+
app35.route("/claude-sessions", claude_sessions_default);
|
|
12885
|
+
app35.route("/log-ingest", log_ingest_default);
|
|
12886
|
+
app35.route("/browser", browser_default);
|
|
12887
|
+
app35.route("/browser-iframe", browser_iframe_default);
|
|
12888
|
+
app35.route("/device-browser", device_browser_default);
|
|
12889
|
+
app35.route("/events", events_default);
|
|
12890
|
+
app35.route("/cloudflare", cloudflare_default);
|
|
12891
|
+
app35.route("/files", files_default);
|
|
12892
|
+
app35.route("/graph-search", graph_search_default);
|
|
12893
|
+
app35.route("/graph-subgraph", graph_subgraph_default);
|
|
12894
|
+
app35.route("/graph-delete", graph_delete_default);
|
|
12895
|
+
app35.route("/graph-restore", graph_restore_default);
|
|
12896
|
+
app35.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
12897
|
+
app35.route("/graph-default-view", graph_default_view_default);
|
|
12898
|
+
app35.route("/session-defaults", session_defaults_default);
|
|
12899
|
+
app35.route("/file-attach", file_attach_default);
|
|
12900
|
+
app35.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
12901
|
+
app35.route("/sidebar-artefact-save", sidebar_artefact_save_default);
|
|
12902
|
+
app35.route("/sidebar-artefact-content", sidebar_artefact_content_default);
|
|
12903
|
+
app35.route("/health-brand", health_default2);
|
|
12904
|
+
app35.route("/linkedin-ingest", linkedin_ingest_default);
|
|
12905
|
+
var admin_default = app35;
|
|
12492
12906
|
|
|
12493
12907
|
// server/routes/sites.ts
|
|
12494
12908
|
import { existsSync as existsSync20, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
|
|
@@ -12523,8 +12937,8 @@ function getExt(p) {
|
|
|
12523
12937
|
if (idx < p.lastIndexOf("/")) return "";
|
|
12524
12938
|
return p.slice(idx).toLowerCase();
|
|
12525
12939
|
}
|
|
12526
|
-
var
|
|
12527
|
-
|
|
12940
|
+
var app36 = new Hono();
|
|
12941
|
+
app36.get("/:rel{.*}", (c) => {
|
|
12528
12942
|
const reqPath = c.req.path;
|
|
12529
12943
|
const rawRel = c.req.param("rel") ?? "";
|
|
12530
12944
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -12627,7 +13041,7 @@ app34.get("/:rel{.*}", (c) => {
|
|
|
12627
13041
|
"X-Content-Type-Options": "nosniff"
|
|
12628
13042
|
});
|
|
12629
13043
|
});
|
|
12630
|
-
var sites_default =
|
|
13044
|
+
var sites_default = app36;
|
|
12631
13045
|
|
|
12632
13046
|
// app/lib/graph-health.ts
|
|
12633
13047
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -12711,7 +13125,7 @@ function startGraphHealthTimer() {
|
|
|
12711
13125
|
}
|
|
12712
13126
|
|
|
12713
13127
|
// app/lib/whatsapp/inbound/claude-bridge.ts
|
|
12714
|
-
var
|
|
13128
|
+
var TAG21 = "[whatsapp-adaptor]";
|
|
12715
13129
|
function whatsappTurnTimeoutMs() {
|
|
12716
13130
|
return Number(process.env.WHATSAPP_PTY_TURN_TIMEOUT_MS ?? String(5 * 6e4));
|
|
12717
13131
|
}
|
|
@@ -12732,7 +13146,7 @@ async function dispatchToClaude(input) {
|
|
|
12732
13146
|
await input.reply(result.turnText);
|
|
12733
13147
|
} catch (err) {
|
|
12734
13148
|
const m = err instanceof Error ? err.message : String(err);
|
|
12735
|
-
console.error(`${
|
|
13149
|
+
console.error(`${TAG21} reject reason=reply-failed senderId=${input.senderId} message=${m}`);
|
|
12736
13150
|
}
|
|
12737
13151
|
}
|
|
12738
13152
|
function startReaper2() {
|
|
@@ -13034,9 +13448,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
|
|
|
13034
13448
|
function isPublicHost(host) {
|
|
13035
13449
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
13036
13450
|
}
|
|
13037
|
-
var
|
|
13038
|
-
|
|
13039
|
-
|
|
13451
|
+
var app37 = new Hono();
|
|
13452
|
+
app37.use("*", clientIpMiddleware);
|
|
13453
|
+
app37.use("*", async (c, next) => {
|
|
13040
13454
|
await next();
|
|
13041
13455
|
c.header("X-Content-Type-Options", "nosniff");
|
|
13042
13456
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -13046,7 +13460,7 @@ app35.use("*", async (c, next) => {
|
|
|
13046
13460
|
);
|
|
13047
13461
|
});
|
|
13048
13462
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
13049
|
-
|
|
13463
|
+
app37.use("*", async (c, next) => {
|
|
13050
13464
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
13051
13465
|
await next();
|
|
13052
13466
|
return;
|
|
@@ -13079,7 +13493,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
13079
13493
|
"/sites/"
|
|
13080
13494
|
];
|
|
13081
13495
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
13082
|
-
|
|
13496
|
+
app37.use("*", async (c, next) => {
|
|
13083
13497
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13084
13498
|
if (!isPublicHost(host)) {
|
|
13085
13499
|
await next();
|
|
@@ -13119,7 +13533,7 @@ function resolveRemoteAuthOpts() {
|
|
|
13119
13533
|
return brandLoginOpts;
|
|
13120
13534
|
}
|
|
13121
13535
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
13122
|
-
|
|
13536
|
+
app37.post("/__remote-auth/login", async (c) => {
|
|
13123
13537
|
const client = clientFrom(c);
|
|
13124
13538
|
const clientIp = client.ip || "unknown";
|
|
13125
13539
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -13164,7 +13578,7 @@ app35.post("/__remote-auth/login", async (c) => {
|
|
|
13164
13578
|
}
|
|
13165
13579
|
});
|
|
13166
13580
|
});
|
|
13167
|
-
|
|
13581
|
+
app37.get("/__remote-auth/logout", (c) => {
|
|
13168
13582
|
const client = clientFrom(c);
|
|
13169
13583
|
const clientIp = client.ip || "unknown";
|
|
13170
13584
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -13177,7 +13591,7 @@ app35.get("/__remote-auth/logout", (c) => {
|
|
|
13177
13591
|
}
|
|
13178
13592
|
});
|
|
13179
13593
|
});
|
|
13180
|
-
|
|
13594
|
+
app37.post("/__remote-auth/change-password", async (c) => {
|
|
13181
13595
|
const client = clientFrom(c);
|
|
13182
13596
|
const clientIp = client.ip || "unknown";
|
|
13183
13597
|
const rateLimited = checkRateLimit(client);
|
|
@@ -13228,13 +13642,13 @@ app35.post("/__remote-auth/change-password", async (c) => {
|
|
|
13228
13642
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
13229
13643
|
}
|
|
13230
13644
|
});
|
|
13231
|
-
|
|
13645
|
+
app37.get("/__remote-auth/setup", (c) => {
|
|
13232
13646
|
if (isRemoteAuthConfigured()) {
|
|
13233
13647
|
return c.redirect("/");
|
|
13234
13648
|
}
|
|
13235
13649
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
13236
13650
|
});
|
|
13237
|
-
|
|
13651
|
+
app37.post("/__remote-auth/set-initial-password", async (c) => {
|
|
13238
13652
|
if (isRemoteAuthConfigured()) {
|
|
13239
13653
|
return c.redirect("/");
|
|
13240
13654
|
}
|
|
@@ -13272,10 +13686,10 @@ app35.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
13272
13686
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
13273
13687
|
}
|
|
13274
13688
|
});
|
|
13275
|
-
|
|
13689
|
+
app37.get("/api/remote-auth/status", (c) => {
|
|
13276
13690
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
13277
13691
|
});
|
|
13278
|
-
|
|
13692
|
+
app37.post("/api/remote-auth/set-password", async (c) => {
|
|
13279
13693
|
let body;
|
|
13280
13694
|
try {
|
|
13281
13695
|
body = await c.req.json();
|
|
@@ -13306,9 +13720,9 @@ app35.post("/api/remote-auth/set-password", async (c) => {
|
|
|
13306
13720
|
return c.json({ error: "Failed to save password" }, 500);
|
|
13307
13721
|
}
|
|
13308
13722
|
});
|
|
13309
|
-
|
|
13723
|
+
app37.route("/api/_client-error", client_error_default);
|
|
13310
13724
|
console.log("[client-error-route] mounted");
|
|
13311
|
-
|
|
13725
|
+
app37.use("*", async (c, next) => {
|
|
13312
13726
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13313
13727
|
const path2 = c.req.path;
|
|
13314
13728
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -13348,11 +13762,11 @@ app35.use("*", async (c, next) => {
|
|
|
13348
13762
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
13349
13763
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
13350
13764
|
});
|
|
13351
|
-
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
|
|
13355
|
-
|
|
13765
|
+
app37.route("/api/health", health_default);
|
|
13766
|
+
app37.route("/api/chat", chat_default);
|
|
13767
|
+
app37.route("/api/whatsapp", whatsapp_default);
|
|
13768
|
+
app37.route("/api/onboarding", onboarding_default);
|
|
13769
|
+
app37.route("/api/admin", admin_default);
|
|
13356
13770
|
var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
|
|
13357
13771
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
13358
13772
|
var IMAGE_MIME = {
|
|
@@ -13364,7 +13778,7 @@ var IMAGE_MIME = {
|
|
|
13364
13778
|
".svg": "image/svg+xml",
|
|
13365
13779
|
".ico": "image/x-icon"
|
|
13366
13780
|
};
|
|
13367
|
-
|
|
13781
|
+
app37.get("/agent-assets/:slug/:filename", (c) => {
|
|
13368
13782
|
const slug = c.req.param("slug");
|
|
13369
13783
|
const filename = c.req.param("filename");
|
|
13370
13784
|
if (!SAFE_SLUG_RE.test(slug)) {
|
|
@@ -13399,7 +13813,7 @@ app35.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
13399
13813
|
"Cache-Control": "public, max-age=3600"
|
|
13400
13814
|
});
|
|
13401
13815
|
});
|
|
13402
|
-
|
|
13816
|
+
app37.get("/generated/:filename", (c) => {
|
|
13403
13817
|
const filename = c.req.param("filename");
|
|
13404
13818
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
13405
13819
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -13429,7 +13843,7 @@ app35.get("/generated/:filename", (c) => {
|
|
|
13429
13843
|
"Cache-Control": "public, max-age=86400"
|
|
13430
13844
|
});
|
|
13431
13845
|
});
|
|
13432
|
-
|
|
13846
|
+
app37.route("/sites", sites_default);
|
|
13433
13847
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
13434
13848
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
13435
13849
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -13566,7 +13980,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
13566
13980
|
function escapeHtml(s) {
|
|
13567
13981
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
13568
13982
|
}
|
|
13569
|
-
|
|
13983
|
+
app37.get("/", (c) => {
|
|
13570
13984
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13571
13985
|
if (isPublicHost(host)) {
|
|
13572
13986
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -13574,12 +13988,12 @@ app35.get("/", (c) => {
|
|
|
13574
13988
|
}
|
|
13575
13989
|
return c.html(cachedHtml("index.html"));
|
|
13576
13990
|
});
|
|
13577
|
-
|
|
13991
|
+
app37.get("/public", (c) => {
|
|
13578
13992
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13579
13993
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13580
13994
|
return c.html(cachedHtml("public.html"));
|
|
13581
13995
|
});
|
|
13582
|
-
|
|
13996
|
+
app37.get("/chat", (c) => {
|
|
13583
13997
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13584
13998
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13585
13999
|
return c.html(cachedHtml("public.html"));
|
|
@@ -13598,9 +14012,9 @@ async function logViewerFetch(c, next) {
|
|
|
13598
14012
|
duration_ms: Date.now() - start
|
|
13599
14013
|
});
|
|
13600
14014
|
}
|
|
13601
|
-
|
|
13602
|
-
|
|
13603
|
-
|
|
14015
|
+
app37.use("/vnc-viewer.html", logViewerFetch);
|
|
14016
|
+
app37.use("/vnc-popout.html", logViewerFetch);
|
|
14017
|
+
app37.get("/vnc-popout.html", (c) => {
|
|
13604
14018
|
let html = htmlCache.get("vnc-popout.html");
|
|
13605
14019
|
if (!html) {
|
|
13606
14020
|
html = readFileSync20(resolve23(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -13613,7 +14027,7 @@ app35.get("/vnc-popout.html", (c) => {
|
|
|
13613
14027
|
}
|
|
13614
14028
|
return c.html(html);
|
|
13615
14029
|
});
|
|
13616
|
-
|
|
14030
|
+
app37.post("/api/vnc/client-event", async (c) => {
|
|
13617
14031
|
let body;
|
|
13618
14032
|
try {
|
|
13619
14033
|
body = await c.req.json();
|
|
@@ -13634,25 +14048,25 @@ app35.post("/api/vnc/client-event", async (c) => {
|
|
|
13634
14048
|
});
|
|
13635
14049
|
return c.json({ ok: true });
|
|
13636
14050
|
});
|
|
13637
|
-
|
|
14051
|
+
app37.get("/g/:slug", (c) => {
|
|
13638
14052
|
return c.html(brandedPublicHtml());
|
|
13639
14053
|
});
|
|
13640
|
-
|
|
14054
|
+
app37.get("/graph", (c) => {
|
|
13641
14055
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13642
14056
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13643
14057
|
return c.html(cachedHtml("graph.html"));
|
|
13644
14058
|
});
|
|
13645
|
-
|
|
14059
|
+
app37.get("/sessions", (c) => {
|
|
13646
14060
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13647
14061
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13648
14062
|
return c.html(cachedHtml("sessions.html"));
|
|
13649
14063
|
});
|
|
13650
|
-
|
|
14064
|
+
app37.get("/data", (c) => {
|
|
13651
14065
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
13652
14066
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
13653
14067
|
return c.html(cachedHtml("data.html"));
|
|
13654
14068
|
});
|
|
13655
|
-
|
|
14069
|
+
app37.get("/:slug", async (c, next) => {
|
|
13656
14070
|
const slug = c.req.param("slug");
|
|
13657
14071
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
13658
14072
|
const branding = loadBrandingCache(slug);
|
|
@@ -13662,16 +14076,31 @@ app35.get("/:slug", async (c, next) => {
|
|
|
13662
14076
|
await next();
|
|
13663
14077
|
});
|
|
13664
14078
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
13665
|
-
|
|
14079
|
+
app37.get("/favicon.ico", (c) => {
|
|
13666
14080
|
c.header("Cache-Control", "public, max-age=300");
|
|
13667
14081
|
return c.redirect(brandFaviconPath, 302);
|
|
13668
14082
|
});
|
|
13669
14083
|
}
|
|
13670
|
-
|
|
14084
|
+
app37.use("/*", serveStatic({ root: "./public" }));
|
|
13671
14085
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
13672
14086
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
13673
|
-
var httpServer = serve({ fetch:
|
|
14087
|
+
var httpServer = serve({ fetch: app37.fetch, port, hostname });
|
|
13674
14088
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
14089
|
+
{
|
|
14090
|
+
const loopHist = monitorEventLoopDelay({ resolution: 50 });
|
|
14091
|
+
loopHist.enable();
|
|
14092
|
+
const LOG_THRESHOLD_MS = 1e3;
|
|
14093
|
+
const WINDOW_MS2 = 3e4;
|
|
14094
|
+
const lagTimer = setInterval(() => {
|
|
14095
|
+
const maxMs = loopHist.max / 1e6;
|
|
14096
|
+
const p99Ms = loopHist.percentile(99) / 1e6;
|
|
14097
|
+
loopHist.reset();
|
|
14098
|
+
if (maxMs >= LOG_THRESHOLD_MS) {
|
|
14099
|
+
console.error(`[event-loop] lag p99=${Math.round(p99Ms)} max=${Math.round(maxMs)} window=${WINDOW_MS2 / 1e3}s`);
|
|
14100
|
+
}
|
|
14101
|
+
}, WINDOW_MS2);
|
|
14102
|
+
lagTimer.unref();
|
|
14103
|
+
}
|
|
13675
14104
|
console.log("[boot] auth-mode summary: oauth=8 api-key=1 (api-key consumer: invokePublicAgent only)");
|
|
13676
14105
|
var SUBAPP_MANIFEST = [
|
|
13677
14106
|
{ prefix: "/api/health", file: "server/routes/health.ts", subapp: health_default },
|
|
@@ -13687,7 +14116,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
13687
14116
|
}
|
|
13688
14117
|
try {
|
|
13689
14118
|
const registered = [];
|
|
13690
|
-
for (const r of
|
|
14119
|
+
for (const r of app37.routes ?? []) {
|
|
13691
14120
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
13692
14121
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
13693
14122
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|