@rubytech/create-maxy-code 0.1.569 → 0.1.570
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/package.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +3 -3
- package/payload/platform/plugins/admin/hooks/__tests__/pdf-text-layer-inject.test.sh +177 -0
- package/payload/platform/plugins/admin/hooks/pdf-text-layer-inject.sh +137 -0
- package/payload/platform/plugins/admin/skills/a4-print-documents/SKILL.md +12 -1
- package/payload/platform/plugins/admin/skills/a4-print-documents/pdf-inspect.mjs +113 -0
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
- package/payload/platform/plugins/docs/references/admin-session.md +15 -0
- package/payload/platform/scripts/__tests__/mailbox-inject-registered.test.sh +15 -39
- package/payload/platform/scripts/__tests__/public-prompt-gate-registered.test.sh +22 -37
- package/payload/platform/scripts/__tests__/public-surface-registered.test.sh +8 -31
- package/payload/platform/scripts/setup-account.sh +7 -62
- package/payload/platform/services/claude-session-manager/dist/blocked-tool-census.d.ts +129 -0
- package/payload/platform/services/claude-session-manager/dist/blocked-tool-census.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/blocked-tool-census.js +344 -0
- package/payload/platform/services/claude-session-manager/dist/blocked-tool-census.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/index.js +20 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/templates/account-settings.json +6 -0
- package/payload/server/server.js +750 -656
- package/payload/platform/scripts/lib/__tests__/account-settings-askgate.test.sh +0 -144
- package/payload/platform/scripts/lib/__tests__/account-settings-mailbox-inject.test.sh +0 -166
- package/payload/platform/scripts/lib/__tests__/account-settings-pdf-conformance.test.sh +0 -151
- package/payload/platform/scripts/lib/__tests__/account-settings-public-surface.test.sh +0 -109
- package/payload/platform/scripts/lib/account-settings-askgate.sh +0 -98
- package/payload/platform/scripts/lib/account-settings-mailbox-inject.sh +0 -91
- package/payload/platform/scripts/lib/account-settings-pdf-conformance.sh +0 -98
- package/payload/platform/scripts/lib/account-settings-public-surface.sh +0 -109
package/payload/server/server.js
CHANGED
|
@@ -2501,8 +2501,8 @@ async function reapplyLeversViaManager() {
|
|
|
2501
2501
|
}
|
|
2502
2502
|
}
|
|
2503
2503
|
function createWebchatRoutes(deps) {
|
|
2504
|
-
const
|
|
2505
|
-
|
|
2504
|
+
const app79 = new Hono();
|
|
2505
|
+
app79.post("/send", requireAdminSession, async (c) => {
|
|
2506
2506
|
let accountId;
|
|
2507
2507
|
try {
|
|
2508
2508
|
accountId = resolvePlatformAccountId();
|
|
@@ -2705,7 +2705,7 @@ ${note}` : note;
|
|
|
2705
2705
|
if (turnTimer.unref) turnTimer.unref();
|
|
2706
2706
|
return c.json({ ok: true });
|
|
2707
2707
|
});
|
|
2708
|
-
|
|
2708
|
+
app79.post("/interrupt", requireAdminSession, async (c) => {
|
|
2709
2709
|
const cacheKey = c.get("cacheKey");
|
|
2710
2710
|
const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
|
|
2711
2711
|
const primaryUserId = resolvePrimaryAdminUserId();
|
|
@@ -2733,7 +2733,7 @@ ${note}` : note;
|
|
|
2733
2733
|
}
|
|
2734
2734
|
return c.json({ ok: true, stopped: outcome.stopped, intId: outcome.intId, deadChild: outcome.deadChild }, 200);
|
|
2735
2735
|
});
|
|
2736
|
-
|
|
2736
|
+
app79.post("/settings", requireAdminSession, async (c) => {
|
|
2737
2737
|
const body = await c.req.json().catch(() => null);
|
|
2738
2738
|
const op = body?.op;
|
|
2739
2739
|
const value = body?.value;
|
|
@@ -2769,7 +2769,7 @@ ${note}` : note;
|
|
|
2769
2769
|
console.log(`[webchat:settings] op=${op} outcome=accepted accountId=${account.accountId.slice(0, 8)} value=${value} settingsApplied=${settingsApplied}`);
|
|
2770
2770
|
return c.json({ ok: true, settingsApplied });
|
|
2771
2771
|
});
|
|
2772
|
-
|
|
2772
|
+
app79.get("/session", requireAdminSession, async (c) => {
|
|
2773
2773
|
let accountId;
|
|
2774
2774
|
try {
|
|
2775
2775
|
accountId = resolvePlatformAccountId();
|
|
@@ -2842,7 +2842,7 @@ ${note}` : note;
|
|
|
2842
2842
|
const indicators = await fetchComposerIndicators(sessionId);
|
|
2843
2843
|
return c.json({ sessionId, projectDir, source, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, deliveryFailure: deps.deliveryFailureFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
|
|
2844
2844
|
});
|
|
2845
|
-
|
|
2845
|
+
app79.post("/permission-verdict", requireAdminSession, async (c) => {
|
|
2846
2846
|
const body = await c.req.json().catch(() => null);
|
|
2847
2847
|
const sessionId = body?.sessionId;
|
|
2848
2848
|
const requestId = body?.request_id;
|
|
@@ -2859,7 +2859,7 @@ ${note}` : note;
|
|
|
2859
2859
|
const ok2 = deps.resolvePermissionVerdict?.(`session:${sessionId}`, requestId, behavior) ?? false;
|
|
2860
2860
|
return c.json({ ok: ok2 });
|
|
2861
2861
|
});
|
|
2862
|
-
return
|
|
2862
|
+
return app79;
|
|
2863
2863
|
}
|
|
2864
2864
|
var UUID_PATTERN, NO_INDICATORS, indicatorsErrorLogged, INDICATORS_TIMEOUT_MS, INTERRUPT_TIMEOUT_MS, MODEL_ID_PATTERN, REAPPLY_TIMEOUT_MS, WEBCHAT_SEND_TURN_WINDOW_MS, sendSeq;
|
|
2865
2865
|
var init_webchat = __esm({
|
|
@@ -4367,7 +4367,7 @@ init_dist();
|
|
|
4367
4367
|
import { readFileSync as readFileSync51, existsSync as existsSync54, watchFile, readdirSync as readdirSync32, statSync as statSync30 } from "fs";
|
|
4368
4368
|
import { spawn as spawn3 } from "child_process";
|
|
4369
4369
|
import { createHash as createHash8 } from "crypto";
|
|
4370
|
-
import { resolve as resolve49, join as
|
|
4370
|
+
import { resolve as resolve49, join as join60, basename as basename17 } from "path";
|
|
4371
4371
|
import { homedir as homedir5 } from "os";
|
|
4372
4372
|
|
|
4373
4373
|
// server/lib/route-cache-watchers.ts
|
|
@@ -4825,11 +4825,11 @@ function staticCacheHeaders(root) {
|
|
|
4825
4825
|
}
|
|
4826
4826
|
|
|
4827
4827
|
// server/lib/static-mounts.ts
|
|
4828
|
-
function mountStaticFiles(
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4828
|
+
function mountStaticFiles(app79, root) {
|
|
4829
|
+
app79.use("/*", staticCacheHeaders(root));
|
|
4830
|
+
app79.use("/assets/*", assetsVary);
|
|
4831
|
+
app79.use("/assets/*", serveStatic({ root, precompressed: true }));
|
|
4832
|
+
app79.use("/*", serveStatic({ root }));
|
|
4833
4833
|
}
|
|
4834
4834
|
var assetsVary = async (c, next) => {
|
|
4835
4835
|
await next();
|
|
@@ -6170,8 +6170,8 @@ function resolveServingAccount(requestedSlug) {
|
|
|
6170
6170
|
return { ok: true, account: { accountId: house.accountId, accountDir: house.accountDir }, agentSlug };
|
|
6171
6171
|
}
|
|
6172
6172
|
function createChatRoutes(deps) {
|
|
6173
|
-
const
|
|
6174
|
-
|
|
6173
|
+
const app79 = new Hono();
|
|
6174
|
+
app79.post("/", async (c) => {
|
|
6175
6175
|
console.log(`[chat-route] entered route=public method=POST`);
|
|
6176
6176
|
const contentType = c.req.header("content-type") ?? "";
|
|
6177
6177
|
let message;
|
|
@@ -6435,7 +6435,7 @@ ${result.result.text}` : result.result.text;
|
|
|
6435
6435
|
}
|
|
6436
6436
|
});
|
|
6437
6437
|
});
|
|
6438
|
-
return
|
|
6438
|
+
return app79;
|
|
6439
6439
|
}
|
|
6440
6440
|
|
|
6441
6441
|
// server/routes/channel/schedule-inject.ts
|
|
@@ -6652,8 +6652,8 @@ function transcriptBoundary(sessionKey) {
|
|
|
6652
6652
|
}
|
|
6653
6653
|
}
|
|
6654
6654
|
function createScheduleInjectRoutes(deps) {
|
|
6655
|
-
const
|
|
6656
|
-
|
|
6655
|
+
const app79 = new Hono();
|
|
6656
|
+
app79.post("/", async (c) => {
|
|
6657
6657
|
const env = c.env;
|
|
6658
6658
|
const remoteAddr = env?.incoming?.socket?.remoteAddress ?? "";
|
|
6659
6659
|
if (!isLoopbackAddr(remoteAddr)) {
|
|
@@ -6799,7 +6799,7 @@ function createScheduleInjectRoutes(deps) {
|
|
|
6799
6799
|
console.error(`${TAG6} op=inject-spawn eventId=${eventId} sessionId=${sessionId} result=ok status=-`);
|
|
6800
6800
|
return c.json({ ok: true, sessionKey: sessionId, ...transcriptBoundary(sessionId) }, 200);
|
|
6801
6801
|
});
|
|
6802
|
-
return
|
|
6802
|
+
return app79;
|
|
6803
6803
|
}
|
|
6804
6804
|
|
|
6805
6805
|
// server/index.ts
|
|
@@ -15436,9 +15436,9 @@ app11.post("/", async (c) => {
|
|
|
15436
15436
|
var telegram_default = app11;
|
|
15437
15437
|
|
|
15438
15438
|
// server/telegram-mount.ts
|
|
15439
|
-
function mountTelegramRoutes(
|
|
15440
|
-
|
|
15441
|
-
|
|
15439
|
+
function mountTelegramRoutes(app79, telegramRoutes) {
|
|
15440
|
+
app79.route("/api/telegram", telegramRoutes);
|
|
15441
|
+
app79.route("/api/telegram/", telegramRoutes);
|
|
15442
15442
|
}
|
|
15443
15443
|
|
|
15444
15444
|
// server/routes/quickbooks.ts
|
|
@@ -19349,6 +19349,99 @@ app24.post("/", async (c) => {
|
|
|
19349
19349
|
});
|
|
19350
19350
|
var log_ingest_default = app24;
|
|
19351
19351
|
|
|
19352
|
+
// server/routes/admin/session-blocked.ts
|
|
19353
|
+
init_dist();
|
|
19354
|
+
init_sidebar_sessions();
|
|
19355
|
+
init_claude_agent();
|
|
19356
|
+
init_account_scope();
|
|
19357
|
+
import { join as join40 } from "path";
|
|
19358
|
+
init_channel_key();
|
|
19359
|
+
var TAG28 = "[blocked-tool-notify]";
|
|
19360
|
+
function isLoopbackAddr3(addr) {
|
|
19361
|
+
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
19362
|
+
}
|
|
19363
|
+
function blockedNotificationText(p) {
|
|
19364
|
+
const where = p.agentId === "\u2014" ? "this session" : `background subagent ${p.agentId}`;
|
|
19365
|
+
return `A tool call is blocked awaiting approval and nothing can answer it from here.
|
|
19366
|
+
|
|
19367
|
+
Session: ${p.sessionId.slice(0, 8)}
|
|
19368
|
+
Tool: ${p.tool}
|
|
19369
|
+
Raised in: ${where}
|
|
19370
|
+
Blocked for: ${Math.round(p.blockedForMs / 1e3)}s
|
|
19371
|
+
|
|
19372
|
+
Answer the permission card in the session's PTY or in Claude Desktop. Some checks (dangerousRemoval) ignore bypass-permissions mode, so no setting will clear it.`;
|
|
19373
|
+
}
|
|
19374
|
+
async function sendWhatsApp(account, to, text) {
|
|
19375
|
+
const res = resolveSocket(account.accountId);
|
|
19376
|
+
if (!res.ok) {
|
|
19377
|
+
console.error(`${TAG28} op=socket-unavailable accountId=${account.accountId} reason=${res.reason}`);
|
|
19378
|
+
return false;
|
|
19379
|
+
}
|
|
19380
|
+
const sent = await sendTextMessage(res.sock, to, text, { accountId: res.accountId });
|
|
19381
|
+
if (!sent.success) console.error(`${TAG28} op=send-failed to=${to} error=${sent.error ?? "unknown"}`);
|
|
19382
|
+
return sent.success === true;
|
|
19383
|
+
}
|
|
19384
|
+
var app25 = new Hono();
|
|
19385
|
+
app25.post("/", async (c) => {
|
|
19386
|
+
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
19387
|
+
if (!isLoopbackAddr3(remoteAddr)) {
|
|
19388
|
+
console.error(`${TAG28} op=reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
19389
|
+
return c.json({ error: "session-blocked-loopback-only" }, 403);
|
|
19390
|
+
}
|
|
19391
|
+
let body = {};
|
|
19392
|
+
try {
|
|
19393
|
+
body = await c.req.json();
|
|
19394
|
+
} catch {
|
|
19395
|
+
return c.json({ error: "body-not-json" }, 400);
|
|
19396
|
+
}
|
|
19397
|
+
const sessionId = typeof body.sessionId === "string" ? body.sessionId : "";
|
|
19398
|
+
const agentId = typeof body.agentId === "string" ? body.agentId : "\u2014";
|
|
19399
|
+
const tool = typeof body.tool === "string" ? body.tool : "";
|
|
19400
|
+
const blockedForMs = typeof body.blockedForMs === "number" ? body.blockedForMs : 0;
|
|
19401
|
+
if (!sessionId) return c.json({ error: "sessionId-required" }, 400);
|
|
19402
|
+
if (!tool) return c.json({ error: "tool-required" }, 400);
|
|
19403
|
+
const text = blockedNotificationText({ sessionId, agentId, tool, blockedForMs });
|
|
19404
|
+
const projectDir = findSessionProjectDir(sessionId);
|
|
19405
|
+
const meta = projectDir ? readSidecarMeta(join40(projectDir, `${sessionId}.meta.json`)) : { role: null, channel: null, senderId: null, accountId: null };
|
|
19406
|
+
const account = validateAccountId2(meta.accountId ?? "");
|
|
19407
|
+
if (!account) {
|
|
19408
|
+
console.error(
|
|
19409
|
+
`${TAG28} op=account-unresolved sessionId=${sessionId.slice(0, 8)} sidecarAccountId=${meta.accountId ?? "none"}`
|
|
19410
|
+
);
|
|
19411
|
+
return c.json({ delivered: false, channel: "none" }, 200);
|
|
19412
|
+
}
|
|
19413
|
+
if (meta.role === "admin" && meta.channel === "whatsapp" && meta.senderId) {
|
|
19414
|
+
const delivered2 = await sendWhatsApp(account, meta.senderId, text);
|
|
19415
|
+
console.error(`${TAG28} op=notify sessionId=${sessionId.slice(0, 8)} channel=whatsapp delivered=${delivered2}`);
|
|
19416
|
+
return c.json({ delivered: delivered2, channel: "whatsapp" }, 200);
|
|
19417
|
+
}
|
|
19418
|
+
if (meta.role === "admin" && meta.channel === "telegram" && meta.senderId) {
|
|
19419
|
+
const parsed = parseTelegramChannelKey(meta.senderId);
|
|
19420
|
+
if (parsed) {
|
|
19421
|
+
const resolved = resolveBotEntry(listValidAccounts(), parsed.botId);
|
|
19422
|
+
const chatId = Number(parsed.senderId);
|
|
19423
|
+
if (resolved.kind === "one" && Number.isFinite(chatId)) {
|
|
19424
|
+
const res = await sendTelegramText(resolved.entry.token, chatId, text);
|
|
19425
|
+
console.error(`${TAG28} op=notify sessionId=${sessionId.slice(0, 8)} channel=telegram delivered=${res.ok}`);
|
|
19426
|
+
return c.json({ delivered: res.ok, channel: "telegram" }, 200);
|
|
19427
|
+
}
|
|
19428
|
+
console.error(
|
|
19429
|
+
`${TAG28} op=telegram-unresolved sessionId=${sessionId.slice(0, 8)} botId=${parsed.botId} kind=${resolved.kind}`
|
|
19430
|
+
);
|
|
19431
|
+
}
|
|
19432
|
+
}
|
|
19433
|
+
const phones = readAdminPhones(account.accountDir);
|
|
19434
|
+
let delivered = false;
|
|
19435
|
+
for (const phone of phones) {
|
|
19436
|
+
if (await sendWhatsApp(account, phone, text)) delivered = true;
|
|
19437
|
+
}
|
|
19438
|
+
console.error(
|
|
19439
|
+
`${TAG28} op=notify sessionId=${sessionId.slice(0, 8)} channel=house-admin phones=${phones.length} delivered=${delivered}`
|
|
19440
|
+
);
|
|
19441
|
+
return c.json({ delivered, channel: "house-admin" }, 200);
|
|
19442
|
+
});
|
|
19443
|
+
var session_blocked_default = app25;
|
|
19444
|
+
|
|
19352
19445
|
// server/routes/admin/events.ts
|
|
19353
19446
|
init_dist();
|
|
19354
19447
|
init_helpers();
|
|
@@ -19380,20 +19473,20 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
19380
19473
|
"channel-notify:desktop-capability",
|
|
19381
19474
|
"channel-notify:desktop-outcome"
|
|
19382
19475
|
]);
|
|
19383
|
-
var
|
|
19384
|
-
|
|
19385
|
-
const
|
|
19476
|
+
var app26 = new Hono();
|
|
19477
|
+
app26.post("/", async (c) => {
|
|
19478
|
+
const TAG60 = "[admin:events]";
|
|
19386
19479
|
let body;
|
|
19387
19480
|
try {
|
|
19388
19481
|
body = await c.req.json();
|
|
19389
19482
|
} catch (err) {
|
|
19390
19483
|
const detail = err instanceof Error ? err.message : String(err);
|
|
19391
|
-
console.error(`${
|
|
19484
|
+
console.error(`${TAG60} reject reason=body-not-json detail=${detail}`);
|
|
19392
19485
|
return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
|
|
19393
19486
|
}
|
|
19394
19487
|
const event = typeof body.event === "string" ? body.event : "";
|
|
19395
19488
|
if (!ALLOWED_EVENTS.has(event)) {
|
|
19396
|
-
console.error(`${
|
|
19489
|
+
console.error(`${TAG60} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
|
|
19397
19490
|
return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
|
|
19398
19491
|
}
|
|
19399
19492
|
const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
|
|
@@ -19426,7 +19519,7 @@ data: ${JSON.stringify(frame)}
|
|
|
19426
19519
|
function shouldDeliver(eventAccountId, subscriberAccountId) {
|
|
19427
19520
|
return eventAccountId === null || eventAccountId === subscriberAccountId;
|
|
19428
19521
|
}
|
|
19429
|
-
|
|
19522
|
+
app26.get("/", requireAdminSession, async (c) => {
|
|
19430
19523
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
19431
19524
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
19432
19525
|
const encoder = new TextEncoder();
|
|
@@ -19507,7 +19600,7 @@ app25.get("/", requireAdminSession, async (c) => {
|
|
|
19507
19600
|
}
|
|
19508
19601
|
});
|
|
19509
19602
|
});
|
|
19510
|
-
var events_default =
|
|
19603
|
+
var events_default = app26;
|
|
19511
19604
|
|
|
19512
19605
|
// server/routes/admin/files.ts
|
|
19513
19606
|
init_dist();
|
|
@@ -19519,7 +19612,7 @@ import { createReadStream as createReadStream2, createWriteStream as createWrite
|
|
|
19519
19612
|
import { readdir as readdir4, readFile as readFile9, stat as stat6, mkdir as mkdir2, unlink as unlink3, rename as rename3, rmdir } from "fs/promises";
|
|
19520
19613
|
import { realpathSync as realpathSync7 } from "fs";
|
|
19521
19614
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
19522
|
-
import { basename as basename13, dirname as dirname15, join as
|
|
19615
|
+
import { basename as basename13, dirname as dirname15, join as join42, relative as relative6, resolve as resolve28, sep as sep9 } from "path";
|
|
19523
19616
|
import { Readable as Readable2 } from "stream";
|
|
19524
19617
|
init_attachments();
|
|
19525
19618
|
|
|
@@ -19843,7 +19936,7 @@ async function cascadeDeleteDocument(params) {
|
|
|
19843
19936
|
init_data_path();
|
|
19844
19937
|
init_neo4j_store();
|
|
19845
19938
|
import * as fsp from "fs/promises";
|
|
19846
|
-
import { resolve as resolve27, relative as relative5, join as
|
|
19939
|
+
import { resolve as resolve27, relative as relative5, join as join41, basename as basename12, extname, sep as sep8 } from "path";
|
|
19847
19940
|
import { tmpdir as tmpdir3 } from "os";
|
|
19848
19941
|
import { execFile } from "child_process";
|
|
19849
19942
|
import { promisify } from "util";
|
|
@@ -19925,7 +20018,7 @@ async function extractPdf(absolute) {
|
|
|
19925
20018
|
return stdout.trim();
|
|
19926
20019
|
}
|
|
19927
20020
|
async function ocrPdf(absolute) {
|
|
19928
|
-
const outPdf =
|
|
20021
|
+
const outPdf = join41(tmpdir3(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
|
|
19929
20022
|
try {
|
|
19930
20023
|
await execFileAsync(
|
|
19931
20024
|
"ocrmypdf",
|
|
@@ -19987,7 +20080,7 @@ async function readDisplayName(absolute) {
|
|
|
19987
20080
|
const stem = dot === -1 ? base : base.slice(0, dot);
|
|
19988
20081
|
if (base === `${stem}.meta.json`) return null;
|
|
19989
20082
|
try {
|
|
19990
|
-
const raw = await fsp.readFile(
|
|
20083
|
+
const raw = await fsp.readFile(join41(dir, `${stem}.meta.json`), "utf-8");
|
|
19991
20084
|
const meta = JSON.parse(raw);
|
|
19992
20085
|
const dn = meta.displayName ?? meta.filename;
|
|
19993
20086
|
return typeof dn === "string" && dn.length > 0 ? dn : null;
|
|
@@ -20008,7 +20101,7 @@ async function walkSubtree(root, dataRoot, out) {
|
|
|
20008
20101
|
for (const entry of entries2) {
|
|
20009
20102
|
if (entry.isSymbolicLink()) continue;
|
|
20010
20103
|
if (entry.isDirectory() && entry.name === ".uploads-tmp") continue;
|
|
20011
|
-
const abs =
|
|
20104
|
+
const abs = join41(root, entry.name);
|
|
20012
20105
|
if (entry.isDirectory()) {
|
|
20013
20106
|
const sub = await walkSubtree(abs, dataRoot, out);
|
|
20014
20107
|
if (!sub.clean) clean = false;
|
|
@@ -20384,7 +20477,7 @@ var UPLOAD_TMP_DIR = ".uploads-tmp";
|
|
|
20384
20477
|
var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
20385
20478
|
async function readMeta2(absDir, baseName) {
|
|
20386
20479
|
try {
|
|
20387
|
-
const raw = await readFile9(
|
|
20480
|
+
const raw = await readFile9(join42(absDir, `${baseName}.meta.json`), "utf8");
|
|
20388
20481
|
const parsed = JSON.parse(raw);
|
|
20389
20482
|
if (typeof parsed?.filename === "string") {
|
|
20390
20483
|
return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
|
|
@@ -20439,7 +20532,7 @@ async function servableFilesIn(dirAbs, uuid) {
|
|
|
20439
20532
|
}
|
|
20440
20533
|
async function enrich(absolute, entry, accountNames) {
|
|
20441
20534
|
if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
|
|
20442
|
-
const dirAbs =
|
|
20535
|
+
const dirAbs = join42(absolute, entry.name);
|
|
20443
20536
|
const meta = await readMeta2(dirAbs, entry.name);
|
|
20444
20537
|
if (meta?.filename) {
|
|
20445
20538
|
const servable = await servableFilesIn(dirAbs, entry.name);
|
|
@@ -20448,7 +20541,7 @@ async function enrich(absolute, entry, accountNames) {
|
|
|
20448
20541
|
let size = null;
|
|
20449
20542
|
let modifiedAt = entry.modifiedAt;
|
|
20450
20543
|
try {
|
|
20451
|
-
const st = await stat6(
|
|
20544
|
+
const st = await stat6(join42(dirAbs, innerName));
|
|
20452
20545
|
size = st.size;
|
|
20453
20546
|
modifiedAt = st.mtime.toISOString();
|
|
20454
20547
|
} catch {
|
|
@@ -20616,8 +20709,8 @@ async function knowledgeDocOwnedByAccount(accountId, attachmentId) {
|
|
|
20616
20709
|
await session.close();
|
|
20617
20710
|
}
|
|
20618
20711
|
}
|
|
20619
|
-
var
|
|
20620
|
-
|
|
20712
|
+
var app27 = new Hono();
|
|
20713
|
+
app27.get("/", requireAdminSession, async (c) => {
|
|
20621
20714
|
const cacheKey = c.var.cacheKey;
|
|
20622
20715
|
const accountId = getAccountIdForSession(cacheKey);
|
|
20623
20716
|
if (!accountId) {
|
|
@@ -20657,7 +20750,7 @@ app26.get("/", requireAdminSession, async (c) => {
|
|
|
20657
20750
|
const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
|
|
20658
20751
|
const protectedEntry = isProtectedFromDeletion(childRel).protected;
|
|
20659
20752
|
try {
|
|
20660
|
-
const entryPath =
|
|
20753
|
+
const entryPath = join42(absolute, name);
|
|
20661
20754
|
const s = await stat6(entryPath);
|
|
20662
20755
|
entries2.push({
|
|
20663
20756
|
name,
|
|
@@ -20686,7 +20779,7 @@ app26.get("/", requireAdminSession, async (c) => {
|
|
|
20686
20779
|
const displayPath = buildDisplayPath(relPath, accountNames);
|
|
20687
20780
|
if (groupReq || isAccountRoot(relPath)) {
|
|
20688
20781
|
const acctId = relPath.split("/")[1] ?? accountId;
|
|
20689
|
-
const schemaMd = await readFile9(
|
|
20782
|
+
const schemaMd = await readFile9(join42(absolute, "SCHEMA.md"), "utf8").catch(() => null);
|
|
20690
20783
|
const groups = classifyAccountRoot(schemaMd, entries2.map((e) => e.name));
|
|
20691
20784
|
console.error(
|
|
20692
20785
|
`[data-schema] op=classify account=${acctId} status=${groups.parsed ? "ok" : "parse-failed"} reason=${groups.reason} entries=${entries2.length} home=${groups.home.join(",") || "none"} system=${groups.system.length} unknown=${groups.unknown.join(",") || "none"}`
|
|
@@ -20724,7 +20817,7 @@ app26.get("/", requireAdminSession, async (c) => {
|
|
|
20724
20817
|
for (const name of homeDirs) {
|
|
20725
20818
|
const base = byName.get(name);
|
|
20726
20819
|
try {
|
|
20727
|
-
const dirents = await readdir4(
|
|
20820
|
+
const dirents = await readdir4(join42(absolute, name), { withFileTypes: true });
|
|
20728
20821
|
const visible = dirents.filter((d) => !d.name.startsWith("."));
|
|
20729
20822
|
visible.sort((a, b) => {
|
|
20730
20823
|
const ad = a.isDirectory() ? 0 : 1;
|
|
@@ -20766,7 +20859,7 @@ app26.get("/", requireAdminSession, async (c) => {
|
|
|
20766
20859
|
return c.json({ error: message }, 500);
|
|
20767
20860
|
}
|
|
20768
20861
|
});
|
|
20769
|
-
|
|
20862
|
+
app27.get("/download", requireAdminSession, async (c) => {
|
|
20770
20863
|
const cacheKey = c.var.cacheKey;
|
|
20771
20864
|
const accountId = getAccountIdForSession(cacheKey);
|
|
20772
20865
|
if (!accountId) {
|
|
@@ -20789,7 +20882,7 @@ app26.get("/download", requireAdminSession, async (c) => {
|
|
|
20789
20882
|
console.error(`[data] op=scratchpad-no-session sessionId="${sessionId.slice(0, 8)}\u2026"`);
|
|
20790
20883
|
return c.json({ error: "Not found" }, 404);
|
|
20791
20884
|
}
|
|
20792
|
-
const meta = readSidecarMeta(
|
|
20885
|
+
const meta = readSidecarMeta(join42(projectDir, `${sessionId}.meta.json`));
|
|
20793
20886
|
if (!meta.accountId || meta.accountId !== accountId) {
|
|
20794
20887
|
console.error(`[data] account-scope-blocked root="scratchpad" sessionId="${sessionId.slice(0, 8)}\u2026" account=${accountId.slice(0, 8)}\u2026`);
|
|
20795
20888
|
return c.json({ error: "Not found" }, 404);
|
|
@@ -20884,7 +20977,7 @@ async function* walkRegularFiles(dirAbsolute) {
|
|
|
20884
20977
|
const dirents = await readdir4(dirAbsolute, { withFileTypes: true });
|
|
20885
20978
|
for (const d of dirents) {
|
|
20886
20979
|
if (d.isSymbolicLink()) continue;
|
|
20887
|
-
const child =
|
|
20980
|
+
const child = join42(dirAbsolute, d.name);
|
|
20888
20981
|
if (d.isDirectory()) {
|
|
20889
20982
|
yield* walkRegularFiles(child);
|
|
20890
20983
|
continue;
|
|
@@ -20892,7 +20985,7 @@ async function* walkRegularFiles(dirAbsolute) {
|
|
|
20892
20985
|
if (d.isFile()) yield child;
|
|
20893
20986
|
}
|
|
20894
20987
|
}
|
|
20895
|
-
|
|
20988
|
+
app27.get("/download-zip", requireAdminSession, async (c) => {
|
|
20896
20989
|
const cacheKey = c.var.cacheKey;
|
|
20897
20990
|
const accountId = getAccountIdForSession(cacheKey);
|
|
20898
20991
|
if (!accountId) {
|
|
@@ -20994,7 +21087,7 @@ async function resolveUploadTarget(c, accountId, uid) {
|
|
|
20994
21087
|
const base = resolveSharedOrOwnAccountWrite(rawDir, accountId, "POST /api/admin/files/upload");
|
|
20995
21088
|
if (!base.ok) return { ok: false, status: base.status, error: base.error };
|
|
20996
21089
|
const relDir = relpath ? dirname15(relpath) : ".";
|
|
20997
|
-
const destRel = relDir === "." ? base.relative :
|
|
21090
|
+
const destRel = relDir === "." ? base.relative : join42(base.relative, relDir);
|
|
20998
21091
|
if ((0, import_dist.isSharedPath)(destRel)) {
|
|
20999
21092
|
const gate = gateSharedWrite(base.absolute, destRel, accountId, "POST /api/admin/files/upload");
|
|
21000
21093
|
if (!gate.ok) return { ok: false, status: gate.status, error: gate.error };
|
|
@@ -21034,7 +21127,7 @@ async function logUploadsTmpCensus(accountId) {
|
|
|
21034
21127
|
}
|
|
21035
21128
|
console.error(`[uploads-tmp-census] dir=${accountId} live=${live}`);
|
|
21036
21129
|
}
|
|
21037
|
-
|
|
21130
|
+
app27.post("/upload", requireAdminSession, async (c) => {
|
|
21038
21131
|
const cacheKey = c.var.cacheKey;
|
|
21039
21132
|
const accountId = getAccountIdForSession(cacheKey);
|
|
21040
21133
|
if (!accountId) {
|
|
@@ -21338,7 +21431,7 @@ async function sweepStaleUploadTemps() {
|
|
|
21338
21431
|
if (removed > 0) console.error(`[data-upload] op=sweep removed=${removed}`);
|
|
21339
21432
|
return removed;
|
|
21340
21433
|
}
|
|
21341
|
-
|
|
21434
|
+
app27.delete("/", requireAdminSession, async (c) => {
|
|
21342
21435
|
const cacheKey = c.var.cacheKey;
|
|
21343
21436
|
const accountId = getAccountIdForSession(cacheKey);
|
|
21344
21437
|
if (!accountId) {
|
|
@@ -21380,7 +21473,7 @@ app26.delete("/", requireAdminSession, async (c) => {
|
|
|
21380
21473
|
const dot = base.lastIndexOf(".");
|
|
21381
21474
|
const stem = dot === -1 ? base : base.slice(0, dot);
|
|
21382
21475
|
const containerDir = dirname15(absolute);
|
|
21383
|
-
const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ?
|
|
21476
|
+
const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join42(containerDir, `${stem}.meta.json`) : null;
|
|
21384
21477
|
const isAttachmentContainer = UUID_RE3.test(stem) && basename13(containerDir) === stem;
|
|
21385
21478
|
await unlink3(absolute);
|
|
21386
21479
|
if (sidecarPath) {
|
|
@@ -21390,7 +21483,7 @@ app26.delete("/", requireAdminSession, async (c) => {
|
|
|
21390
21483
|
}
|
|
21391
21484
|
}
|
|
21392
21485
|
if (isAttachmentContainer) {
|
|
21393
|
-
await unlink3(
|
|
21486
|
+
await unlink3(join42(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
|
|
21394
21487
|
});
|
|
21395
21488
|
await rmdir(containerDir).catch(() => {
|
|
21396
21489
|
});
|
|
@@ -21426,7 +21519,7 @@ app26.delete("/", requireAdminSession, async (c) => {
|
|
|
21426
21519
|
return c.json({ error: message }, 500);
|
|
21427
21520
|
}
|
|
21428
21521
|
});
|
|
21429
|
-
|
|
21522
|
+
app27.post("/folder", requireAdminSession, async (c) => {
|
|
21430
21523
|
const cacheKey = c.var.cacheKey;
|
|
21431
21524
|
const accountId = getAccountIdForSession(cacheKey);
|
|
21432
21525
|
if (!accountId) {
|
|
@@ -21461,7 +21554,7 @@ app26.post("/folder", requireAdminSession, async (c) => {
|
|
|
21461
21554
|
console.error(`[data] folder-create path="${newRel}"`);
|
|
21462
21555
|
return c.json({ path: newRel });
|
|
21463
21556
|
});
|
|
21464
|
-
|
|
21557
|
+
app27.post("/rename", requireAdminSession, async (c) => {
|
|
21465
21558
|
const cacheKey = c.var.cacheKey;
|
|
21466
21559
|
const accountId = getAccountIdForSession(cacheKey);
|
|
21467
21560
|
if (!accountId) {
|
|
@@ -21511,7 +21604,7 @@ app26.post("/rename", requireAdminSession, async (c) => {
|
|
|
21511
21604
|
});
|
|
21512
21605
|
return c.json({ path: newRel });
|
|
21513
21606
|
});
|
|
21514
|
-
var files_default =
|
|
21607
|
+
var files_default = app27;
|
|
21515
21608
|
|
|
21516
21609
|
// server/routes/admin/graph-search.ts
|
|
21517
21610
|
init_dist();
|
|
@@ -22275,8 +22368,8 @@ var DEFAULT_LIMIT = 20;
|
|
|
22275
22368
|
var MAX_LIMIT = 2e3;
|
|
22276
22369
|
var MESSAGE_FAMILY_LABELS = ["Message", "UserMessage", "AssistantMessage"];
|
|
22277
22370
|
var CONVERSATION_PARENT_LABELS = /* @__PURE__ */ new Set(["AdminConversation", "PublicConversation"]);
|
|
22278
|
-
var
|
|
22279
|
-
|
|
22371
|
+
var app28 = new Hono();
|
|
22372
|
+
app28.get("/", requireAdminSession, async (c) => {
|
|
22280
22373
|
const cacheKey = c.var.cacheKey;
|
|
22281
22374
|
const q2 = (c.req.query("q") ?? "").trim();
|
|
22282
22375
|
const rawLimit = c.req.query("limit");
|
|
@@ -22412,7 +22505,7 @@ app27.get("/", requireAdminSession, async (c) => {
|
|
|
22412
22505
|
await session.close();
|
|
22413
22506
|
}
|
|
22414
22507
|
});
|
|
22415
|
-
var graph_search_default =
|
|
22508
|
+
var graph_search_default = app28;
|
|
22416
22509
|
|
|
22417
22510
|
// server/routes/admin/graph-subgraph.ts
|
|
22418
22511
|
init_dist();
|
|
@@ -22516,7 +22609,7 @@ function isHiddenByDefault(label) {
|
|
|
22516
22609
|
// server/lib/top-level-labels.ts
|
|
22517
22610
|
var import_dist6 = __toESM(require_dist5(), 1);
|
|
22518
22611
|
import { readdirSync as readdirSync24, readFileSync as readFileSync36 } from "fs";
|
|
22519
|
-
import { join as
|
|
22612
|
+
import { join as join43, resolve as resolve29 } from "path";
|
|
22520
22613
|
var STATIC_TOP_LEVEL_LABELS = Object.freeze(
|
|
22521
22614
|
/* @__PURE__ */ new Set([
|
|
22522
22615
|
// Base-schema infra (schema-base.md has no top-level section).
|
|
@@ -22620,7 +22713,7 @@ function parseTopLevelLabels(content) {
|
|
|
22620
22713
|
}
|
|
22621
22714
|
function resolveReferencesDir() {
|
|
22622
22715
|
if (process.env.MAXY_PLATFORM_ROOT) {
|
|
22623
|
-
return
|
|
22716
|
+
return join43(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
|
|
22624
22717
|
}
|
|
22625
22718
|
return resolve29(import.meta.dirname, "../../../plugins/memory/references");
|
|
22626
22719
|
}
|
|
@@ -22630,7 +22723,7 @@ function parseTableTopLevelLabels(referencesDir) {
|
|
|
22630
22723
|
try {
|
|
22631
22724
|
const fileNames = readdirSync24(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
|
|
22632
22725
|
for (const fileName of fileNames) {
|
|
22633
|
-
const content = readFileSync36(
|
|
22726
|
+
const content = readFileSync36(join43(referencesDir, fileName), "utf-8");
|
|
22634
22727
|
const parsed = parseTopLevelLabels(content);
|
|
22635
22728
|
if (parsed.length > 0) contributingFiles.push(fileName);
|
|
22636
22729
|
for (const label of parsed) labels.add(label);
|
|
@@ -22675,8 +22768,8 @@ var STRIPPED_PROPERTIES = /* @__PURE__ */ new Set([
|
|
|
22675
22768
|
"otpCode",
|
|
22676
22769
|
"cacheKey"
|
|
22677
22770
|
]);
|
|
22678
|
-
var
|
|
22679
|
-
|
|
22771
|
+
var app29 = new Hono();
|
|
22772
|
+
app29.get("/", requireAdminSession, async (c) => {
|
|
22680
22773
|
const cacheKey = c.var.cacheKey;
|
|
22681
22774
|
const accountId = getAccountIdForSession(cacheKey);
|
|
22682
22775
|
if (!accountId) {
|
|
@@ -23347,7 +23440,7 @@ function pruneNode(node, warnedClasses, conversationWarnings) {
|
|
|
23347
23440
|
}
|
|
23348
23441
|
return trashed ? { id: node.id, labels, properties, trashed: true } : { id: node.id, labels, properties };
|
|
23349
23442
|
}
|
|
23350
|
-
var graph_subgraph_default =
|
|
23443
|
+
var graph_subgraph_default = app29;
|
|
23351
23444
|
|
|
23352
23445
|
// server/routes/admin/graph-delete.ts
|
|
23353
23446
|
init_dist();
|
|
@@ -23355,8 +23448,8 @@ init_helpers();
|
|
|
23355
23448
|
init_claude_agent();
|
|
23356
23449
|
init_neo4j_store();
|
|
23357
23450
|
var ALLOWED_BY = ["graph-page", "graph-drag-trash", "graph-side-panel-trash"];
|
|
23358
|
-
var
|
|
23359
|
-
|
|
23451
|
+
var app30 = new Hono();
|
|
23452
|
+
app30.post("/", requireAdminSession, async (c) => {
|
|
23360
23453
|
const cacheKey = c.var.cacheKey;
|
|
23361
23454
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23362
23455
|
if (!accountId) {
|
|
@@ -23518,15 +23611,15 @@ app29.post("/", requireAdminSession, async (c) => {
|
|
|
23518
23611
|
}
|
|
23519
23612
|
}
|
|
23520
23613
|
});
|
|
23521
|
-
var graph_delete_default =
|
|
23614
|
+
var graph_delete_default = app30;
|
|
23522
23615
|
|
|
23523
23616
|
// server/routes/admin/graph-restore.ts
|
|
23524
23617
|
init_dist();
|
|
23525
23618
|
init_helpers();
|
|
23526
23619
|
init_claude_agent();
|
|
23527
23620
|
init_neo4j_store();
|
|
23528
|
-
var
|
|
23529
|
-
|
|
23621
|
+
var app31 = new Hono();
|
|
23622
|
+
app31.post("/", requireAdminSession, async (c) => {
|
|
23530
23623
|
const cacheKey = c.var.cacheKey;
|
|
23531
23624
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23532
23625
|
if (!accountId) {
|
|
@@ -23590,15 +23683,15 @@ app30.post("/", requireAdminSession, async (c) => {
|
|
|
23590
23683
|
}
|
|
23591
23684
|
}
|
|
23592
23685
|
});
|
|
23593
|
-
var graph_restore_default =
|
|
23686
|
+
var graph_restore_default = app31;
|
|
23594
23687
|
|
|
23595
23688
|
// server/routes/admin/graph-labels-in-graph.ts
|
|
23596
23689
|
init_dist();
|
|
23597
23690
|
init_helpers();
|
|
23598
23691
|
init_claude_agent();
|
|
23599
23692
|
init_neo4j_store();
|
|
23600
|
-
var
|
|
23601
|
-
|
|
23693
|
+
var app32 = new Hono();
|
|
23694
|
+
app32.get("/", requireAdminSession, async (c) => {
|
|
23602
23695
|
const cacheKey = c.var.cacheKey;
|
|
23603
23696
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23604
23697
|
if (!accountId) {
|
|
@@ -23664,15 +23757,15 @@ var LABELS_IN_GRAPH_CYPHER = `
|
|
|
23664
23757
|
sum(halfEdges) AS relDegree
|
|
23665
23758
|
RETURN label, nodeCount, relDegree
|
|
23666
23759
|
`;
|
|
23667
|
-
var graph_labels_in_graph_default =
|
|
23760
|
+
var graph_labels_in_graph_default = app32;
|
|
23668
23761
|
|
|
23669
23762
|
// server/routes/admin/graph-default-view.ts
|
|
23670
23763
|
init_dist();
|
|
23671
23764
|
init_helpers();
|
|
23672
23765
|
init_claude_agent();
|
|
23673
23766
|
init_neo4j_store();
|
|
23674
|
-
var
|
|
23675
|
-
|
|
23767
|
+
var app33 = new Hono();
|
|
23768
|
+
app33.get("/", requireAdminSession, async (c) => {
|
|
23676
23769
|
const cacheKey = c.var.cacheKey;
|
|
23677
23770
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23678
23771
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -23710,7 +23803,7 @@ app32.get("/", requireAdminSession, async (c) => {
|
|
|
23710
23803
|
}
|
|
23711
23804
|
}
|
|
23712
23805
|
});
|
|
23713
|
-
|
|
23806
|
+
app33.put("/", requireAdminSession, async (c) => {
|
|
23714
23807
|
const cacheKey = c.var.cacheKey;
|
|
23715
23808
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23716
23809
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -23799,7 +23892,7 @@ var WRITE_CYPHER = `
|
|
|
23799
23892
|
p.updatedAt = $updatedAt
|
|
23800
23893
|
RETURN p.labels AS labels
|
|
23801
23894
|
`;
|
|
23802
|
-
var graph_default_view_default =
|
|
23895
|
+
var graph_default_view_default = app33;
|
|
23803
23896
|
|
|
23804
23897
|
// server/routes/admin/sidebar-artefacts.ts
|
|
23805
23898
|
init_dist();
|
|
@@ -23819,8 +23912,8 @@ function toDataRootRelPath(absPath) {
|
|
|
23819
23912
|
if (absPath !== DATA_ROOT && !absPath.startsWith(DATA_ROOT + sep10)) return null;
|
|
23820
23913
|
return relative7(DATA_ROOT, absPath);
|
|
23821
23914
|
}
|
|
23822
|
-
var
|
|
23823
|
-
|
|
23915
|
+
var app34 = new Hono();
|
|
23916
|
+
app34.get("/", requireAdminSession, async (c) => {
|
|
23824
23917
|
const cacheKey = c.var.cacheKey;
|
|
23825
23918
|
const accountId = getAccountIdForSession(cacheKey);
|
|
23826
23919
|
if (!accountId) {
|
|
@@ -23989,7 +24082,7 @@ function isWithin(target, root) {
|
|
|
23989
24082
|
const rel = relative7(root, target);
|
|
23990
24083
|
return !rel.startsWith("..") && !isAbsolute4(rel);
|
|
23991
24084
|
}
|
|
23992
|
-
var sidebar_artefacts_default =
|
|
24085
|
+
var sidebar_artefacts_default = app34;
|
|
23993
24086
|
|
|
23994
24087
|
// server/routes/admin/index.ts
|
|
23995
24088
|
init_sidebar_sessions();
|
|
@@ -24014,8 +24107,8 @@ function clearForwardPointers(sessionId) {
|
|
|
24014
24107
|
}
|
|
24015
24108
|
|
|
24016
24109
|
// server/routes/admin/session-delete.ts
|
|
24017
|
-
var
|
|
24018
|
-
|
|
24110
|
+
var app35 = new Hono();
|
|
24111
|
+
app35.post("/", requireAdminSession, async (c) => {
|
|
24019
24112
|
let body;
|
|
24020
24113
|
try {
|
|
24021
24114
|
body = await c.req.json();
|
|
@@ -24054,13 +24147,13 @@ app34.post("/", requireAdminSession, async (c) => {
|
|
|
24054
24147
|
console.error(`[session-delete] sessionId=${sessionId} delete-status=${del.status}`);
|
|
24055
24148
|
return c.json({ error: `manager-status-${del.status}` }, 502);
|
|
24056
24149
|
});
|
|
24057
|
-
var session_delete_default =
|
|
24150
|
+
var session_delete_default = app35;
|
|
24058
24151
|
|
|
24059
24152
|
// server/routes/admin/session-stop.ts
|
|
24060
24153
|
init_dist();
|
|
24061
24154
|
init_helpers();
|
|
24062
|
-
var
|
|
24063
|
-
|
|
24155
|
+
var app36 = new Hono();
|
|
24156
|
+
app36.post("/", requireAdminSession, async (c) => {
|
|
24064
24157
|
let body;
|
|
24065
24158
|
try {
|
|
24066
24159
|
body = await c.req.json();
|
|
@@ -24085,13 +24178,13 @@ app35.post("/", requireAdminSession, async (c) => {
|
|
|
24085
24178
|
console.error(`[session-stop] sessionId=${sessionId} manager-status=${res.status}`);
|
|
24086
24179
|
return c.json({ error: `manager-status-${res.status}` }, 502);
|
|
24087
24180
|
});
|
|
24088
|
-
var session_stop_default =
|
|
24181
|
+
var session_stop_default = app36;
|
|
24089
24182
|
|
|
24090
24183
|
// server/routes/admin/session-archive.ts
|
|
24091
24184
|
init_dist();
|
|
24092
24185
|
init_helpers();
|
|
24093
|
-
var
|
|
24094
|
-
|
|
24186
|
+
var app37 = new Hono();
|
|
24187
|
+
app37.post("/", requireAdminSession, async (c) => {
|
|
24095
24188
|
let body;
|
|
24096
24189
|
try {
|
|
24097
24190
|
body = await c.req.json();
|
|
@@ -24140,13 +24233,13 @@ app36.post("/", requireAdminSession, async (c) => {
|
|
|
24140
24233
|
console.error(`[session-archive] sessionId=${sessionId.slice(0, 8)} manager-status=${res.status}`);
|
|
24141
24234
|
return c.json({ error: `manager-status-${res.status}` }, 502);
|
|
24142
24235
|
});
|
|
24143
|
-
var session_archive_default =
|
|
24236
|
+
var session_archive_default = app37;
|
|
24144
24237
|
|
|
24145
24238
|
// server/routes/admin/session-rename.ts
|
|
24146
24239
|
init_dist();
|
|
24147
24240
|
init_helpers();
|
|
24148
|
-
var
|
|
24149
|
-
|
|
24241
|
+
var app38 = new Hono();
|
|
24242
|
+
app38.post("/", requireAdminSession, async (c) => {
|
|
24150
24243
|
let body;
|
|
24151
24244
|
try {
|
|
24152
24245
|
body = await c.req.json();
|
|
@@ -24185,13 +24278,13 @@ app37.post("/", requireAdminSession, async (c) => {
|
|
|
24185
24278
|
console.error(`[session-rename] sessionId=${sessionId.slice(0, 8)} manager-status=${res.status}`);
|
|
24186
24279
|
return c.json({ error: `manager-status-${res.status}` }, 502);
|
|
24187
24280
|
});
|
|
24188
|
-
var session_rename_default =
|
|
24281
|
+
var session_rename_default = app38;
|
|
24189
24282
|
|
|
24190
24283
|
// server/routes/admin/session-usage.ts
|
|
24191
24284
|
init_dist();
|
|
24192
24285
|
init_helpers();
|
|
24193
|
-
var
|
|
24194
|
-
|
|
24286
|
+
var app39 = new Hono();
|
|
24287
|
+
app39.get("/", requireAdminSession, async (c) => {
|
|
24195
24288
|
const sessionId = c.req.query("sessionId") ?? "";
|
|
24196
24289
|
if (!SESSION_ID_RE2.test(sessionId)) {
|
|
24197
24290
|
return c.json({ error: "sessionId must be a v4 UUID" }, 400);
|
|
@@ -24217,7 +24310,7 @@ app38.get("/", requireAdminSession, async (c) => {
|
|
|
24217
24310
|
console.error(`[session-usage] sessionId=${sessionId.slice(0, 8)} manager-status=${res.status}`);
|
|
24218
24311
|
return c.json({ error: `manager-status-${res.status}` }, 502);
|
|
24219
24312
|
});
|
|
24220
|
-
var session_usage_default =
|
|
24313
|
+
var session_usage_default = app39;
|
|
24221
24314
|
|
|
24222
24315
|
// server/routes/admin/session-rc-spawn.ts
|
|
24223
24316
|
init_dist();
|
|
@@ -24284,8 +24377,8 @@ function shapeWebchatResponse(sessionId, manager, titleSource = "none") {
|
|
|
24284
24377
|
const landed = redirected ? manager.sessionId : sessionId;
|
|
24285
24378
|
return { sessionId: landed, outcome, target: `/chat?session=${landed}`, titleSource };
|
|
24286
24379
|
}
|
|
24287
|
-
var
|
|
24288
|
-
|
|
24380
|
+
var app40 = new Hono();
|
|
24381
|
+
app40.post("/", requireAdminSession, async (c) => {
|
|
24289
24382
|
let body;
|
|
24290
24383
|
try {
|
|
24291
24384
|
body = await c.req.json();
|
|
@@ -24401,7 +24494,7 @@ app39.post("/", requireAdminSession, async (c) => {
|
|
|
24401
24494
|
}
|
|
24402
24495
|
return c.json(parsed ?? {});
|
|
24403
24496
|
});
|
|
24404
|
-
var session_rc_spawn_default =
|
|
24497
|
+
var session_rc_spawn_default = app40;
|
|
24405
24498
|
|
|
24406
24499
|
// server/routes/admin/session-reseat.ts
|
|
24407
24500
|
init_dist();
|
|
@@ -24410,24 +24503,24 @@ init_session_store();
|
|
|
24410
24503
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
24411
24504
|
|
|
24412
24505
|
// server/wa-descriptor.ts
|
|
24413
|
-
import { resolve as resolve31, join as
|
|
24506
|
+
import { resolve as resolve31, join as join44 } from "path";
|
|
24414
24507
|
function waGatewayUrl() {
|
|
24415
24508
|
return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
|
|
24416
24509
|
}
|
|
24417
24510
|
function waServerPath() {
|
|
24418
|
-
return process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve31(process.env.MAXY_PLATFORM_ROOT ??
|
|
24511
|
+
return process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve31(process.env.MAXY_PLATFORM_ROOT ?? join44(__dirname, ".."), "services/whatsapp-channel/dist/server.js");
|
|
24419
24512
|
}
|
|
24420
24513
|
function waChannelDescriptor(senderId) {
|
|
24421
24514
|
return { senderId, gatewayUrl: waGatewayUrl(), serverPath: waServerPath() };
|
|
24422
24515
|
}
|
|
24423
24516
|
|
|
24424
24517
|
// server/telegram-descriptor.ts
|
|
24425
|
-
import { resolve as resolve32, join as
|
|
24518
|
+
import { resolve as resolve32, join as join45 } from "path";
|
|
24426
24519
|
function telegramGatewayUrl() {
|
|
24427
24520
|
return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
|
|
24428
24521
|
}
|
|
24429
24522
|
function telegramServerPath() {
|
|
24430
|
-
return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve32(process.env.MAXY_PLATFORM_ROOT ??
|
|
24523
|
+
return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve32(process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, ".."), "services/telegram-channel/dist/server.js");
|
|
24431
24524
|
}
|
|
24432
24525
|
function telegramChannelDescriptor(senderId) {
|
|
24433
24526
|
return { senderId, gatewayUrl: telegramGatewayUrl(), serverPath: telegramServerPath() };
|
|
@@ -24477,9 +24570,9 @@ function resolveReseatPlan(body, mintId = randomUUID8, adminUserId, authenticate
|
|
|
24477
24570
|
if (authenticatedName) payload.authenticatedName = authenticatedName;
|
|
24478
24571
|
return { sessionId, payload };
|
|
24479
24572
|
}
|
|
24480
|
-
var
|
|
24573
|
+
var app41 = new Hono();
|
|
24481
24574
|
var reseatsInFlight = /* @__PURE__ */ new Set();
|
|
24482
|
-
|
|
24575
|
+
app41.post("/", requireAdminSession, async (c) => {
|
|
24483
24576
|
let body;
|
|
24484
24577
|
try {
|
|
24485
24578
|
body = await c.req.json();
|
|
@@ -24596,7 +24689,7 @@ app40.post("/", requireAdminSession, async (c) => {
|
|
|
24596
24689
|
reseatsInFlight.delete(fromSessionId);
|
|
24597
24690
|
}
|
|
24598
24691
|
});
|
|
24599
|
-
var session_reseat_default =
|
|
24692
|
+
var session_reseat_default = app41;
|
|
24600
24693
|
|
|
24601
24694
|
// server/routes/admin/system-stats.ts
|
|
24602
24695
|
init_dist();
|
|
@@ -24694,8 +24787,8 @@ async function sample() {
|
|
|
24694
24787
|
if (process.platform === "linux") return sampleLinux();
|
|
24695
24788
|
return sampleOsFallback();
|
|
24696
24789
|
}
|
|
24697
|
-
var
|
|
24698
|
-
|
|
24790
|
+
var app42 = new Hono();
|
|
24791
|
+
app42.get("/", async (c) => {
|
|
24699
24792
|
const started2 = Date.now();
|
|
24700
24793
|
if (!inflight) {
|
|
24701
24794
|
inflight = sample().finally(() => {
|
|
@@ -24718,16 +24811,16 @@ app41.get("/", async (c) => {
|
|
|
24718
24811
|
return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
|
|
24719
24812
|
}
|
|
24720
24813
|
});
|
|
24721
|
-
var system_stats_default =
|
|
24814
|
+
var system_stats_default = app42;
|
|
24722
24815
|
|
|
24723
24816
|
// server/routes/admin/health.ts
|
|
24724
24817
|
init_dist();
|
|
24725
24818
|
init_neo4j_store();
|
|
24726
24819
|
import { existsSync as existsSync38, readFileSync as readFileSync37 } from "fs";
|
|
24727
|
-
import { resolve as resolve33, join as
|
|
24820
|
+
import { resolve as resolve33, join as join46 } from "path";
|
|
24728
24821
|
var PLATFORM_ROOT4 = process.env.MAXY_PLATFORM_ROOT ?? resolve33(process.cwd(), "..");
|
|
24729
24822
|
var brandHostname = "maxy";
|
|
24730
|
-
var brandJsonPath =
|
|
24823
|
+
var brandJsonPath = join46(PLATFORM_ROOT4, "config", "brand.json");
|
|
24731
24824
|
if (existsSync38(brandJsonPath)) {
|
|
24732
24825
|
try {
|
|
24733
24826
|
const brand = JSON.parse(readFileSync37(brandJsonPath, "utf-8"));
|
|
@@ -24765,8 +24858,8 @@ async function probeConversationDb() {
|
|
|
24765
24858
|
});
|
|
24766
24859
|
}
|
|
24767
24860
|
}
|
|
24768
|
-
var
|
|
24769
|
-
|
|
24861
|
+
var app43 = new Hono();
|
|
24862
|
+
app43.get("/", async (c) => {
|
|
24770
24863
|
const version = readVersion();
|
|
24771
24864
|
const probe = await probeConversationDb();
|
|
24772
24865
|
const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
|
|
@@ -24788,7 +24881,7 @@ app42.get("/", async (c) => {
|
|
|
24788
24881
|
uptimeMs
|
|
24789
24882
|
});
|
|
24790
24883
|
});
|
|
24791
|
-
var health_default2 =
|
|
24884
|
+
var health_default2 = app43;
|
|
24792
24885
|
|
|
24793
24886
|
// server/routes/admin/linkedin-ingest.ts
|
|
24794
24887
|
init_dist();
|
|
@@ -24989,7 +25082,7 @@ function managerLogFollowUrl(sessionId, opts) {
|
|
|
24989
25082
|
}
|
|
24990
25083
|
|
|
24991
25084
|
// server/routes/admin/linkedin-ingest.ts
|
|
24992
|
-
var
|
|
25085
|
+
var TAG29 = "[linkedin-ingest-route]";
|
|
24993
25086
|
var UUID4 = /^[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}$/;
|
|
24994
25087
|
var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
24995
25088
|
var LINKEDIN_URL = /^https:\/\/www\.linkedin\.com\//;
|
|
@@ -25108,34 +25201,34 @@ var requireIngestToken = async (c, next) => {
|
|
|
25108
25201
|
console.log(`${AUTH_TAG} outcome=accept accountId=${accountId.slice(0, 8)} path=${c.req.path}`);
|
|
25109
25202
|
await next();
|
|
25110
25203
|
};
|
|
25111
|
-
var
|
|
25112
|
-
|
|
25204
|
+
var app44 = new Hono();
|
|
25205
|
+
app44.post("/", requireIngestToken, async (c) => {
|
|
25113
25206
|
let body;
|
|
25114
25207
|
try {
|
|
25115
25208
|
body = await c.req.json();
|
|
25116
25209
|
} catch {
|
|
25117
|
-
console.error(
|
|
25210
|
+
console.error(TAG29 + " rejected status=400 reason=schema:body-not-json");
|
|
25118
25211
|
return c.json({ ok: false, error: "schema", reason: "body-not-json" }, 400);
|
|
25119
25212
|
}
|
|
25120
25213
|
const v = validate2(body);
|
|
25121
25214
|
if (!v.ok) {
|
|
25122
|
-
console.error(
|
|
25215
|
+
console.error(TAG29 + " rejected status=" + v.status + " reason=" + v.reason + " missing=" + v.missing.join(","));
|
|
25123
25216
|
return c.json({ ok: false, error: v.error, reason: v.reason, missing: v.missing }, v.status);
|
|
25124
25217
|
}
|
|
25125
25218
|
const envelope = v.envelope;
|
|
25126
25219
|
const senderId = c.var.ingestAccountId ?? "";
|
|
25127
25220
|
if (!senderId) {
|
|
25128
|
-
console.error(
|
|
25221
|
+
console.error(TAG29 + " rejected status=500 reason=admin-account-not-resolved");
|
|
25129
25222
|
return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
|
|
25130
25223
|
}
|
|
25131
25224
|
const payloadBytes = JSON.stringify(envelope).length;
|
|
25132
25225
|
console.log(
|
|
25133
|
-
|
|
25226
|
+
TAG29 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
|
|
25134
25227
|
);
|
|
25135
25228
|
const initialMessage = buildInitialMessage(envelope);
|
|
25136
25229
|
const spawnStart = Date.now();
|
|
25137
25230
|
const sessionId = randomUUID9();
|
|
25138
|
-
console.log(
|
|
25231
|
+
console.log(TAG29 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
|
|
25139
25232
|
const spawned = await managerRcSpawn({
|
|
25140
25233
|
sessionId,
|
|
25141
25234
|
initialMessage,
|
|
@@ -25148,22 +25241,22 @@ app43.post("/", requireIngestToken, async (c) => {
|
|
|
25148
25241
|
});
|
|
25149
25242
|
if ("error" in spawned) {
|
|
25150
25243
|
console.error(
|
|
25151
|
-
|
|
25244
|
+
TAG29 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + spawned.status + " ms=" + (Date.now() - spawnStart) + " message=" + spawned.error
|
|
25152
25245
|
);
|
|
25153
25246
|
return c.json({ ok: false, error: "dispatch-failed", upstreamStatus: spawned.status, detail: spawned.error }, 502);
|
|
25154
25247
|
}
|
|
25155
25248
|
console.log(
|
|
25156
|
-
|
|
25249
|
+
TAG29 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + spawned.sessionId + " ms=" + (Date.now() - spawnStart)
|
|
25157
25250
|
);
|
|
25158
25251
|
return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
|
|
25159
25252
|
});
|
|
25160
|
-
var linkedin_ingest_default =
|
|
25253
|
+
var linkedin_ingest_default = app44;
|
|
25161
25254
|
|
|
25162
25255
|
// server/routes/admin/post-turn-context.ts
|
|
25163
25256
|
init_dist();
|
|
25164
25257
|
init_neo4j_store();
|
|
25165
25258
|
import neo4j2 from "neo4j-driver";
|
|
25166
|
-
var
|
|
25259
|
+
var TAG30 = "[post-turn-context]";
|
|
25167
25260
|
var STRIPPED_PROPERTIES2 = /* @__PURE__ */ new Set([
|
|
25168
25261
|
"embedding",
|
|
25169
25262
|
"passwordHash",
|
|
@@ -25171,7 +25264,7 @@ var STRIPPED_PROPERTIES2 = /* @__PURE__ */ new Set([
|
|
|
25171
25264
|
"otpCode",
|
|
25172
25265
|
"cacheKey"
|
|
25173
25266
|
]);
|
|
25174
|
-
function
|
|
25267
|
+
function isLoopbackAddr4(addr) {
|
|
25175
25268
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
25176
25269
|
}
|
|
25177
25270
|
function convertValue(value) {
|
|
@@ -25201,20 +25294,20 @@ function pruneProperties(raw) {
|
|
|
25201
25294
|
}
|
|
25202
25295
|
return out;
|
|
25203
25296
|
}
|
|
25204
|
-
var
|
|
25205
|
-
|
|
25297
|
+
var app45 = new Hono();
|
|
25298
|
+
app45.get("/", async (c) => {
|
|
25206
25299
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
25207
|
-
if (!
|
|
25208
|
-
console.error(`${
|
|
25300
|
+
if (!isLoopbackAddr4(remoteAddr)) {
|
|
25301
|
+
console.error(`${TAG30} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
25209
25302
|
return c.json({ error: "post-turn-context-loopback-only" }, 403);
|
|
25210
25303
|
}
|
|
25211
25304
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
25212
25305
|
const xffRaw = Array.isArray(xffHeader) ? xffHeader.join(",") : typeof xffHeader === "string" ? xffHeader : "";
|
|
25213
25306
|
if (xffRaw.length > 0) {
|
|
25214
25307
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
25215
|
-
const offender = tokens.find((t) => !
|
|
25308
|
+
const offender = tokens.find((t) => !isLoopbackAddr4(t));
|
|
25216
25309
|
if (offender !== void 0) {
|
|
25217
|
-
console.error(`${
|
|
25310
|
+
console.error(`${TAG30} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
25218
25311
|
return c.json({ error: "post-turn-context-loopback-only" }, 403);
|
|
25219
25312
|
}
|
|
25220
25313
|
}
|
|
@@ -25246,7 +25339,7 @@ app44.get("/", async (c) => {
|
|
|
25246
25339
|
writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
|
|
25247
25340
|
const total = Date.now() - started2;
|
|
25248
25341
|
console.log(
|
|
25249
|
-
`${
|
|
25342
|
+
`${TAG30} sessionId=${sessionId} accountId=${accountId} writes=${writes.length} ms=${total}`
|
|
25250
25343
|
);
|
|
25251
25344
|
return c.json({
|
|
25252
25345
|
writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
|
|
@@ -25255,14 +25348,14 @@ app44.get("/", async (c) => {
|
|
|
25255
25348
|
const elapsed = Date.now() - started2;
|
|
25256
25349
|
const message = err instanceof Error ? err.message : String(err);
|
|
25257
25350
|
console.error(
|
|
25258
|
-
`${
|
|
25351
|
+
`${TAG30} neo4j-unreachable sessionId=${sessionId} ms=${elapsed} err="${message}"`
|
|
25259
25352
|
);
|
|
25260
25353
|
return c.json({ error: `post-turn-context unavailable: ${message}` }, 503);
|
|
25261
25354
|
} finally {
|
|
25262
25355
|
await session.close();
|
|
25263
25356
|
}
|
|
25264
25357
|
});
|
|
25265
|
-
var post_turn_context_default =
|
|
25358
|
+
var post_turn_context_default = app45;
|
|
25266
25359
|
|
|
25267
25360
|
// server/routes/admin/public-session-context.ts
|
|
25268
25361
|
init_dist();
|
|
@@ -25372,24 +25465,24 @@ function formatPreviousContext(writes) {
|
|
|
25372
25465
|
}
|
|
25373
25466
|
|
|
25374
25467
|
// server/routes/admin/public-session-context.ts
|
|
25375
|
-
var
|
|
25376
|
-
function
|
|
25468
|
+
var TAG31 = "[public-session-context]";
|
|
25469
|
+
function isLoopbackAddr5(addr) {
|
|
25377
25470
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
25378
25471
|
}
|
|
25379
|
-
var
|
|
25380
|
-
|
|
25472
|
+
var app46 = new Hono();
|
|
25473
|
+
app46.get("/", async (c) => {
|
|
25381
25474
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
25382
|
-
if (!
|
|
25383
|
-
console.error(`${
|
|
25475
|
+
if (!isLoopbackAddr5(remoteAddr)) {
|
|
25476
|
+
console.error(`${TAG31} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
25384
25477
|
return c.json({ error: "public-session-context-loopback-only" }, 403);
|
|
25385
25478
|
}
|
|
25386
25479
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
25387
25480
|
const xffRaw = Array.isArray(xffHeader) ? xffHeader.join(",") : typeof xffHeader === "string" ? xffHeader : "";
|
|
25388
25481
|
if (xffRaw.length > 0) {
|
|
25389
25482
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
25390
|
-
const offender = tokens.find((t) => !
|
|
25483
|
+
const offender = tokens.find((t) => !isLoopbackAddr5(t));
|
|
25391
25484
|
if (offender !== void 0) {
|
|
25392
|
-
console.error(`${
|
|
25485
|
+
console.error(`${TAG31} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
25393
25486
|
return c.json({ error: "public-session-context-loopback-only" }, 403);
|
|
25394
25487
|
}
|
|
25395
25488
|
}
|
|
@@ -25403,21 +25496,21 @@ app45.get("/", async (c) => {
|
|
|
25403
25496
|
const writes = await fetchSliceWrites(session, sliceToken, accountId);
|
|
25404
25497
|
const total = Date.now() - started2;
|
|
25405
25498
|
console.log(
|
|
25406
|
-
`${
|
|
25499
|
+
`${TAG31} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
|
|
25407
25500
|
);
|
|
25408
25501
|
return c.json({ writes });
|
|
25409
25502
|
} catch (err) {
|
|
25410
25503
|
const elapsed = Date.now() - started2;
|
|
25411
25504
|
const message = err instanceof Error ? err.message : String(err);
|
|
25412
25505
|
console.error(
|
|
25413
|
-
`${
|
|
25506
|
+
`${TAG31} neo4j-unreachable sliceToken=${sliceToken.slice(0, 8)} ms=${elapsed} err="${message}"`
|
|
25414
25507
|
);
|
|
25415
25508
|
return c.json({ error: `public-session-context unavailable: ${message}` }, 503);
|
|
25416
25509
|
} finally {
|
|
25417
25510
|
await session.close();
|
|
25418
25511
|
}
|
|
25419
25512
|
});
|
|
25420
|
-
var public_session_context_default =
|
|
25513
|
+
var public_session_context_default = app46;
|
|
25421
25514
|
|
|
25422
25515
|
// server/routes/admin/public-session-exit.ts
|
|
25423
25516
|
init_dist();
|
|
@@ -25432,24 +25525,24 @@ function getWebchatGateway() {
|
|
|
25432
25525
|
}
|
|
25433
25526
|
|
|
25434
25527
|
// server/routes/admin/public-session-exit.ts
|
|
25435
|
-
var
|
|
25436
|
-
function
|
|
25528
|
+
var TAG32 = "[public-session-exit-route]";
|
|
25529
|
+
function isLoopbackAddr6(addr) {
|
|
25437
25530
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
25438
25531
|
}
|
|
25439
|
-
var
|
|
25440
|
-
|
|
25532
|
+
var app47 = new Hono();
|
|
25533
|
+
app47.post("/", async (c) => {
|
|
25441
25534
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
25442
|
-
if (!
|
|
25443
|
-
console.error(`${
|
|
25535
|
+
if (!isLoopbackAddr6(remoteAddr)) {
|
|
25536
|
+
console.error(`${TAG32} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
25444
25537
|
return c.json({ error: "public-session-exit-loopback-only" }, 403);
|
|
25445
25538
|
}
|
|
25446
25539
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
25447
25540
|
const xffRaw = Array.isArray(xffHeader) ? xffHeader.join(",") : typeof xffHeader === "string" ? xffHeader : "";
|
|
25448
25541
|
if (xffRaw.length > 0) {
|
|
25449
25542
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
25450
|
-
const offender = tokens.find((t) => !
|
|
25543
|
+
const offender = tokens.find((t) => !isLoopbackAddr6(t));
|
|
25451
25544
|
if (offender !== void 0) {
|
|
25452
|
-
console.error(`${
|
|
25545
|
+
console.error(`${TAG32} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
25453
25546
|
return c.json({ error: "public-session-exit-loopback-only" }, 403);
|
|
25454
25547
|
}
|
|
25455
25548
|
}
|
|
@@ -25463,34 +25556,34 @@ app46.post("/", async (c) => {
|
|
|
25463
25556
|
if (!sessionId) return c.json({ error: "sessionId required" }, 400);
|
|
25464
25557
|
const gateway = getWebchatGateway();
|
|
25465
25558
|
if (!gateway) {
|
|
25466
|
-
console.error(`${
|
|
25559
|
+
console.error(`${TAG32} reject reason=gateway-unset sessionId=${sessionId.slice(0, 8)}`);
|
|
25467
25560
|
return c.json({ error: "webchat-gateway-unset" }, 503);
|
|
25468
25561
|
}
|
|
25469
25562
|
gateway.handlePublicSessionExit(sessionId);
|
|
25470
25563
|
return c.json({ ok: true });
|
|
25471
25564
|
});
|
|
25472
|
-
var public_session_exit_default =
|
|
25565
|
+
var public_session_exit_default = app47;
|
|
25473
25566
|
|
|
25474
25567
|
// server/routes/admin/access-session-evict.ts
|
|
25475
25568
|
init_dist();
|
|
25476
|
-
var
|
|
25477
|
-
function
|
|
25569
|
+
var TAG33 = "[access-session-evict]";
|
|
25570
|
+
function isLoopbackAddr7(addr) {
|
|
25478
25571
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
25479
25572
|
}
|
|
25480
|
-
var
|
|
25481
|
-
|
|
25573
|
+
var app48 = new Hono();
|
|
25574
|
+
app48.post("/", async (c) => {
|
|
25482
25575
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
25483
|
-
if (!
|
|
25484
|
-
console.error(`${
|
|
25576
|
+
if (!isLoopbackAddr7(remoteAddr)) {
|
|
25577
|
+
console.error(`${TAG33} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
25485
25578
|
return c.json({ error: "access-session-evict-loopback-only" }, 403);
|
|
25486
25579
|
}
|
|
25487
25580
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
25488
25581
|
const xffRaw = Array.isArray(xffHeader) ? xffHeader.join(",") : typeof xffHeader === "string" ? xffHeader : "";
|
|
25489
25582
|
if (xffRaw.length > 0) {
|
|
25490
25583
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
25491
|
-
const offender = tokens.find((t) => !
|
|
25584
|
+
const offender = tokens.find((t) => !isLoopbackAddr7(t));
|
|
25492
25585
|
if (offender !== void 0) {
|
|
25493
|
-
console.error(`${
|
|
25586
|
+
console.error(`${TAG33} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
25494
25587
|
return c.json({ error: "access-session-evict-loopback-only" }, 403);
|
|
25495
25588
|
}
|
|
25496
25589
|
}
|
|
@@ -25503,33 +25596,33 @@ app47.post("/", async (c) => {
|
|
|
25503
25596
|
const grantId = typeof body.grantId === "string" ? body.grantId.trim() : "";
|
|
25504
25597
|
if (!grantId) return c.json({ error: "grantId required" }, 400);
|
|
25505
25598
|
const dropped = evictAccessSessionsByGrant(grantId);
|
|
25506
|
-
console.log(`${
|
|
25599
|
+
console.log(`${TAG33} grantId=${grantId} dropped=${dropped}`);
|
|
25507
25600
|
return c.json({ ok: true, dropped });
|
|
25508
25601
|
});
|
|
25509
|
-
var access_session_evict_default =
|
|
25602
|
+
var access_session_evict_default = app48;
|
|
25510
25603
|
|
|
25511
25604
|
// server/routes/admin/enrol-person.ts
|
|
25512
25605
|
init_dist();
|
|
25513
25606
|
init_normalize();
|
|
25514
|
-
var
|
|
25515
|
-
function
|
|
25607
|
+
var TAG34 = "[enrol]";
|
|
25608
|
+
function isLoopbackAddr8(addr) {
|
|
25516
25609
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
25517
25610
|
}
|
|
25518
25611
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
25519
|
-
var
|
|
25520
|
-
|
|
25612
|
+
var app49 = new Hono();
|
|
25613
|
+
app49.post("/", async (c) => {
|
|
25521
25614
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
25522
|
-
if (!
|
|
25523
|
-
console.error(`${
|
|
25615
|
+
if (!isLoopbackAddr8(remoteAddr)) {
|
|
25616
|
+
console.error(`${TAG34} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
25524
25617
|
return c.json({ error: "enrol-person-loopback-only" }, 403);
|
|
25525
25618
|
}
|
|
25526
25619
|
const xffHeader = c.env?.incoming?.headers?.["x-forwarded-for"];
|
|
25527
25620
|
const xffRaw = Array.isArray(xffHeader) ? xffHeader.join(",") : typeof xffHeader === "string" ? xffHeader : "";
|
|
25528
25621
|
if (xffRaw.length > 0) {
|
|
25529
25622
|
const tokens = xffRaw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
25530
|
-
const offender = tokens.find((t) => !
|
|
25623
|
+
const offender = tokens.find((t) => !isLoopbackAddr8(t));
|
|
25531
25624
|
if (offender !== void 0) {
|
|
25532
|
-
console.error(`${
|
|
25625
|
+
console.error(`${TAG34} reject reason=xff-non-loopback xff=${JSON.stringify(xffRaw)}`);
|
|
25533
25626
|
return c.json({ error: "enrol-person-loopback-only" }, 403);
|
|
25534
25627
|
}
|
|
25535
25628
|
}
|
|
@@ -25554,7 +25647,7 @@ app48.post("/", async (c) => {
|
|
|
25554
25647
|
}
|
|
25555
25648
|
const accountId = process.env.ACCOUNT_ID ?? "";
|
|
25556
25649
|
if (!accountId) {
|
|
25557
|
-
console.error(`${
|
|
25650
|
+
console.error(`${TAG34} op=person result=no-account-id`);
|
|
25558
25651
|
return c.json({ error: "no-account-id" }, 500);
|
|
25559
25652
|
}
|
|
25560
25653
|
let personId;
|
|
@@ -25562,7 +25655,7 @@ app48.post("/", async (c) => {
|
|
|
25562
25655
|
personId = await enrolPerson({ accountId, phone, email, agentSlug });
|
|
25563
25656
|
} catch (err) {
|
|
25564
25657
|
console.error(
|
|
25565
|
-
`${
|
|
25658
|
+
`${TAG34} op=person result=write-failed agentSlug=${agentSlug} contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
|
|
25566
25659
|
);
|
|
25567
25660
|
return c.json({ error: "enrol-failed" }, 500);
|
|
25568
25661
|
}
|
|
@@ -25572,22 +25665,22 @@ app48.post("/", async (c) => {
|
|
|
25572
25665
|
if (g) grant = { grantId: g.grantId, status: g.status, contactValue: g.contactValue };
|
|
25573
25666
|
} catch (err) {
|
|
25574
25667
|
console.error(
|
|
25575
|
-
`${
|
|
25668
|
+
`${TAG34} op=person result=grant-lookup-failed contact=${maskContact(email)} err="${err instanceof Error ? err.message : String(err)}"`
|
|
25576
25669
|
);
|
|
25577
25670
|
}
|
|
25578
25671
|
console.log(
|
|
25579
|
-
`${
|
|
25672
|
+
`${TAG34} op=person personId=${personId} account=${accountId} agentSlug=${agentSlug} contact=${maskContact(email)}`
|
|
25580
25673
|
);
|
|
25581
25674
|
return c.json({ personId, grant }, 200);
|
|
25582
25675
|
});
|
|
25583
|
-
var enrol_person_default =
|
|
25676
|
+
var enrol_person_default = app49;
|
|
25584
25677
|
|
|
25585
25678
|
// server/routes/admin/browser.ts
|
|
25586
25679
|
init_dist();
|
|
25587
25680
|
init_helpers();
|
|
25588
25681
|
init_paths();
|
|
25589
|
-
var
|
|
25590
|
-
|
|
25682
|
+
var app50 = new Hono();
|
|
25683
|
+
app50.post("/launch", requireAdminSession, async (c) => {
|
|
25591
25684
|
try {
|
|
25592
25685
|
if (process.platform !== "linux") {
|
|
25593
25686
|
console.error("[admin/browser/launch] op=skipped platform=darwin reason=no-display-stack");
|
|
@@ -25622,7 +25715,7 @@ app49.post("/launch", requireAdminSession, async (c) => {
|
|
|
25622
25715
|
);
|
|
25623
25716
|
}
|
|
25624
25717
|
});
|
|
25625
|
-
|
|
25718
|
+
app50.get("/screencast-targets", requireAdminSession, async (c) => {
|
|
25626
25719
|
const result = await fetchPageTargets({
|
|
25627
25720
|
fetchImpl: fetch,
|
|
25628
25721
|
cdpPort: CDP_PORT,
|
|
@@ -25635,7 +25728,7 @@ app49.get("/screencast-targets", requireAdminSession, async (c) => {
|
|
|
25635
25728
|
screencastLog("targets", { count: result.targets.length, cdpPort: CDP_PORT });
|
|
25636
25729
|
return c.json({ ok: true, targets: result.targets });
|
|
25637
25730
|
});
|
|
25638
|
-
|
|
25731
|
+
app50.post("/screencast-event", requireAdminSession, async (c) => {
|
|
25639
25732
|
let body;
|
|
25640
25733
|
try {
|
|
25641
25734
|
body = await c.req.json();
|
|
@@ -25649,7 +25742,7 @@ app49.post("/screencast-event", requireAdminSession, async (c) => {
|
|
|
25649
25742
|
screencastLog(parsed.op, parsed.detail);
|
|
25650
25743
|
return c.json({ ok: true });
|
|
25651
25744
|
});
|
|
25652
|
-
|
|
25745
|
+
app50.post("/tabs", requireAdminSession, async (c) => {
|
|
25653
25746
|
tabsLog("create");
|
|
25654
25747
|
const result = await createPageTarget({ fetchImpl: fetch, cdpPort: CDP_PORT, platform: process.platform });
|
|
25655
25748
|
if (!result.ok) {
|
|
@@ -25659,7 +25752,7 @@ app49.post("/tabs", requireAdminSession, async (c) => {
|
|
|
25659
25752
|
tabsLog("created", { targetId: result.id });
|
|
25660
25753
|
return c.json({ ok: true, id: result.id });
|
|
25661
25754
|
});
|
|
25662
|
-
|
|
25755
|
+
app50.delete("/tabs/:id", requireAdminSession, async (c) => {
|
|
25663
25756
|
const targetId = c.req.param("id");
|
|
25664
25757
|
tabsLog("close", { targetId });
|
|
25665
25758
|
const result = await closePageTarget(
|
|
@@ -25673,7 +25766,7 @@ app49.delete("/tabs/:id", requireAdminSession, async (c) => {
|
|
|
25673
25766
|
tabsLog("closed", { targetId });
|
|
25674
25767
|
return c.json({ ok: true });
|
|
25675
25768
|
});
|
|
25676
|
-
var browser_default =
|
|
25769
|
+
var browser_default = app50;
|
|
25677
25770
|
|
|
25678
25771
|
// server/routes/admin/calendar.ts
|
|
25679
25772
|
init_dist();
|
|
@@ -25683,7 +25776,7 @@ init_account_scope();
|
|
|
25683
25776
|
init_neo4j_store();
|
|
25684
25777
|
import { existsSync as existsSync40 } from "fs";
|
|
25685
25778
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
25686
|
-
import { join as
|
|
25779
|
+
import { join as join48 } from "path";
|
|
25687
25780
|
|
|
25688
25781
|
// server/lib/calendar-ics.ts
|
|
25689
25782
|
var CRLF = "\r\n";
|
|
@@ -25784,7 +25877,7 @@ function countVEvents(ics) {
|
|
|
25784
25877
|
|
|
25785
25878
|
// server/lib/calendar-availability.ts
|
|
25786
25879
|
import { readFileSync as readFileSync39 } from "fs";
|
|
25787
|
-
import { join as
|
|
25880
|
+
import { join as join47 } from "path";
|
|
25788
25881
|
var AVAILABILITY_FILENAME = "calendar-availability.json";
|
|
25789
25882
|
var REQUIRED_KEYS = [
|
|
25790
25883
|
"timezone",
|
|
@@ -25793,7 +25886,7 @@ var REQUIRED_KEYS = [
|
|
|
25793
25886
|
"weekly"
|
|
25794
25887
|
];
|
|
25795
25888
|
function readAvailabilityConfig(accountDir) {
|
|
25796
|
-
const path =
|
|
25889
|
+
const path = join47(accountDir, AVAILABILITY_FILENAME);
|
|
25797
25890
|
let raw;
|
|
25798
25891
|
try {
|
|
25799
25892
|
raw = readFileSync39(path, "utf-8");
|
|
@@ -25906,7 +25999,7 @@ function computeOpenSlots(config, busy, fromISO, toISO) {
|
|
|
25906
25999
|
}
|
|
25907
26000
|
|
|
25908
26001
|
// server/routes/admin/calendar.ts
|
|
25909
|
-
var
|
|
26002
|
+
var app51 = new Hono();
|
|
25910
26003
|
function normalizeAttendees(raw) {
|
|
25911
26004
|
if (!Array.isArray(raw)) return [];
|
|
25912
26005
|
return raw.map((a) => {
|
|
@@ -25987,7 +26080,7 @@ var GET_UNION = `MATCH (m:Meeting {accountId: $accountId})
|
|
|
25987
26080
|
'task' AS kind, null AS privateNote,
|
|
25988
26081
|
t.description AS description, null AS timezone,
|
|
25989
26082
|
[] AS attendees`;
|
|
25990
|
-
|
|
26083
|
+
app51.get("/meetings", requireAdminSession, async (c) => {
|
|
25991
26084
|
const cacheKey = c.var.cacheKey;
|
|
25992
26085
|
const accountId = getAccountIdForSession(cacheKey);
|
|
25993
26086
|
if (!accountId) {
|
|
@@ -26015,7 +26108,7 @@ app50.get("/meetings", requireAdminSession, async (c) => {
|
|
|
26015
26108
|
await session.close();
|
|
26016
26109
|
}
|
|
26017
26110
|
});
|
|
26018
|
-
|
|
26111
|
+
app51.get("/free-busy", requireAdminSession, async (c) => {
|
|
26019
26112
|
const cacheKey = c.var.cacheKey;
|
|
26020
26113
|
const account = accountDirForSession(cacheKey);
|
|
26021
26114
|
if (!account) {
|
|
@@ -26065,7 +26158,7 @@ app50.get("/free-busy", requireAdminSession, async (c) => {
|
|
|
26065
26158
|
await session.close();
|
|
26066
26159
|
}
|
|
26067
26160
|
});
|
|
26068
|
-
|
|
26161
|
+
app51.post("/meetings", requireAdminSession, async (c) => {
|
|
26069
26162
|
const cacheKey = c.var.cacheKey;
|
|
26070
26163
|
const accountId = getAccountIdForSession(cacheKey);
|
|
26071
26164
|
if (!accountId) {
|
|
@@ -26114,7 +26207,7 @@ function icsFilename(title) {
|
|
|
26114
26207
|
const slug = (title ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
|
|
26115
26208
|
return `${slug || "meeting"}.ics`;
|
|
26116
26209
|
}
|
|
26117
|
-
|
|
26210
|
+
app51.get("/meetings/:id/ics", requireAdminSession, async (c) => {
|
|
26118
26211
|
const cacheKey = c.var.cacheKey;
|
|
26119
26212
|
const accountId = getAccountIdForSession(cacheKey);
|
|
26120
26213
|
if (!accountId) {
|
|
@@ -26173,7 +26266,7 @@ app50.get("/meetings/:id/ics", requireAdminSession, async (c) => {
|
|
|
26173
26266
|
await session.close();
|
|
26174
26267
|
}
|
|
26175
26268
|
});
|
|
26176
|
-
|
|
26269
|
+
app51.patch("/meetings/:id", requireAdminSession, async (c) => {
|
|
26177
26270
|
const cacheKey = c.var.cacheKey;
|
|
26178
26271
|
const accountId = getAccountIdForSession(cacheKey);
|
|
26179
26272
|
if (!accountId) {
|
|
@@ -26217,7 +26310,7 @@ app50.patch("/meetings/:id", requireAdminSession, async (c) => {
|
|
|
26217
26310
|
await session.close();
|
|
26218
26311
|
}
|
|
26219
26312
|
});
|
|
26220
|
-
|
|
26313
|
+
app51.post("/meetings/:id/attendees", requireAdminSession, async (c) => {
|
|
26221
26314
|
const cacheKey = c.var.cacheKey;
|
|
26222
26315
|
const accountId = getAccountIdForSession(cacheKey);
|
|
26223
26316
|
if (!accountId) {
|
|
@@ -26267,7 +26360,7 @@ app50.post("/meetings/:id/attendees", requireAdminSession, async (c) => {
|
|
|
26267
26360
|
await session.close();
|
|
26268
26361
|
}
|
|
26269
26362
|
});
|
|
26270
|
-
|
|
26363
|
+
app51.delete("/meetings/:id/attendees", requireAdminSession, async (c) => {
|
|
26271
26364
|
const cacheKey = c.var.cacheKey;
|
|
26272
26365
|
const accountId = getAccountIdForSession(cacheKey);
|
|
26273
26366
|
if (!accountId) {
|
|
@@ -26313,7 +26406,7 @@ app50.delete("/meetings/:id/attendees", requireAdminSession, async (c) => {
|
|
|
26313
26406
|
await session.close();
|
|
26314
26407
|
}
|
|
26315
26408
|
});
|
|
26316
|
-
|
|
26409
|
+
app51.delete("/meetings/:id", requireAdminSession, async (c) => {
|
|
26317
26410
|
const cacheKey = c.var.cacheKey;
|
|
26318
26411
|
const accountId = getAccountIdForSession(cacheKey);
|
|
26319
26412
|
if (!accountId) {
|
|
@@ -26343,7 +26436,7 @@ app50.delete("/meetings/:id", requireAdminSession, async (c) => {
|
|
|
26343
26436
|
await session.close();
|
|
26344
26437
|
}
|
|
26345
26438
|
});
|
|
26346
|
-
|
|
26439
|
+
app51.get("/booking-link", requireAdminSession, (c) => {
|
|
26347
26440
|
const account = accountDirForSession(c.var.cacheKey);
|
|
26348
26441
|
if (!account) {
|
|
26349
26442
|
console.error("[calendar] op=booking-link auth-rejected reason=no-account-for-session accountId=none");
|
|
@@ -26351,7 +26444,7 @@ app50.get("/booking-link", requireAdminSession, (c) => {
|
|
|
26351
26444
|
}
|
|
26352
26445
|
const id82 = account.accountId.slice(0, 8);
|
|
26353
26446
|
try {
|
|
26354
|
-
if (!existsSync40(
|
|
26447
|
+
if (!existsSync40(join48(account.accountDir, AVAILABILITY_FILENAME))) {
|
|
26355
26448
|
console.log(`[calendar] op=booking-link accountId=${id82} bookingDomain=none source=availability-config`);
|
|
26356
26449
|
return c.json({ bookingDomain: null });
|
|
26357
26450
|
}
|
|
@@ -26367,17 +26460,17 @@ app50.get("/booking-link", requireAdminSession, (c) => {
|
|
|
26367
26460
|
return c.json({ bookingDomain: null });
|
|
26368
26461
|
}
|
|
26369
26462
|
});
|
|
26370
|
-
var calendar_default =
|
|
26463
|
+
var calendar_default = app51;
|
|
26371
26464
|
|
|
26372
26465
|
// server/routes/admin/data-portal.ts
|
|
26373
26466
|
init_dist();
|
|
26374
26467
|
init_helpers();
|
|
26375
26468
|
init_account_scope();
|
|
26376
26469
|
import { existsSync as existsSync41, readFileSync as readFileSync40 } from "fs";
|
|
26377
|
-
import { join as
|
|
26378
|
-
var
|
|
26470
|
+
import { join as join49 } from "path";
|
|
26471
|
+
var app52 = new Hono();
|
|
26379
26472
|
var PORTAL_FILENAME = "data-portal.json";
|
|
26380
|
-
|
|
26473
|
+
app52.get("/portal-link", requireAdminSession, (c) => {
|
|
26381
26474
|
const account = accountDirForSession(c.var.cacheKey);
|
|
26382
26475
|
if (!account) {
|
|
26383
26476
|
console.error("[data-portal] op=portal-link auth-rejected reason=no-account-for-session accountId=none");
|
|
@@ -26385,7 +26478,7 @@ app51.get("/portal-link", requireAdminSession, (c) => {
|
|
|
26385
26478
|
}
|
|
26386
26479
|
const id82 = account.accountId.slice(0, 8);
|
|
26387
26480
|
try {
|
|
26388
|
-
const path =
|
|
26481
|
+
const path = join49(account.accountDir, PORTAL_FILENAME);
|
|
26389
26482
|
if (!existsSync41(path)) {
|
|
26390
26483
|
console.log(`[data-portal] op=portal-link accountId=${id82} portalDomain=none source=data-portal-config`);
|
|
26391
26484
|
return c.json({ portalDomain: null });
|
|
@@ -26400,7 +26493,7 @@ app51.get("/portal-link", requireAdminSession, (c) => {
|
|
|
26400
26493
|
return c.json({ portalDomain: null });
|
|
26401
26494
|
}
|
|
26402
26495
|
});
|
|
26403
|
-
var data_portal_default =
|
|
26496
|
+
var data_portal_default = app52;
|
|
26404
26497
|
|
|
26405
26498
|
// server/routes/admin/routines.ts
|
|
26406
26499
|
init_dist();
|
|
@@ -26558,7 +26651,7 @@ function dispatchGapReason(fields) {
|
|
|
26558
26651
|
|
|
26559
26652
|
// server/routes/admin/routines.ts
|
|
26560
26653
|
var { parseExpression } = cronParser;
|
|
26561
|
-
var
|
|
26654
|
+
var app53 = new Hono();
|
|
26562
26655
|
var AUTOMATION_WHERE = "(e.recurrence IS NOT NULL OR e.agentChannel IS NOT NULL OR e.actionPlugin IS NOT NULL)";
|
|
26563
26656
|
var DISPATCH_CHANNELS2 = /* @__PURE__ */ new Set(["whatsapp", "telegram"]);
|
|
26564
26657
|
var ROUTINE_COLS = `e.eventId AS eventId, e.name AS name, e.eventStatus AS eventStatus,
|
|
@@ -26681,7 +26774,7 @@ function planResume(row, now) {
|
|
|
26681
26774
|
}
|
|
26682
26775
|
return { ok: true, nextRun: null };
|
|
26683
26776
|
}
|
|
26684
|
-
|
|
26777
|
+
app53.get("/", requireAdminSession, async (c) => {
|
|
26685
26778
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
26686
26779
|
if (!accountId) {
|
|
26687
26780
|
console.error('[admin:routines] op=list auth-rejected reason="no account for session"');
|
|
@@ -26831,7 +26924,7 @@ function runsCsvFilename(name, eventId, date) {
|
|
|
26831
26924
|
const slug = clean(name ?? "").slice(0, 48).replace(/-+$/, "");
|
|
26832
26925
|
return `${slug || clean(eventId.slice(0, 8)) || "routine"}-runs-${date}.csv`;
|
|
26833
26926
|
}
|
|
26834
|
-
|
|
26927
|
+
app53.get("/:eventId/runs", requireAdminSession, async (c) => {
|
|
26835
26928
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
26836
26929
|
if (!accountId) {
|
|
26837
26930
|
console.error('[admin:routines] op=runs auth-rejected reason="no account for session"');
|
|
@@ -26866,7 +26959,7 @@ app52.get("/:eventId/runs", requireAdminSession, async (c) => {
|
|
|
26866
26959
|
await session.close();
|
|
26867
26960
|
}
|
|
26868
26961
|
});
|
|
26869
|
-
|
|
26962
|
+
app53.get("/:eventId/runs.csv", requireAdminSession, async (c) => {
|
|
26870
26963
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
26871
26964
|
const eventId = c.req.param("eventId");
|
|
26872
26965
|
if (!accountId) {
|
|
@@ -26913,7 +27006,7 @@ app52.get("/:eventId/runs.csv", requireAdminSession, async (c) => {
|
|
|
26913
27006
|
await session.close();
|
|
26914
27007
|
}
|
|
26915
27008
|
});
|
|
26916
|
-
|
|
27009
|
+
app53.get("/:eventId", requireAdminSession, async (c) => {
|
|
26917
27010
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
26918
27011
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
26919
27012
|
const eventId = c.req.param("eventId");
|
|
@@ -26937,7 +27030,7 @@ app52.get("/:eventId", requireAdminSession, async (c) => {
|
|
|
26937
27030
|
await session.close();
|
|
26938
27031
|
}
|
|
26939
27032
|
});
|
|
26940
|
-
|
|
27033
|
+
app53.patch("/:eventId", requireAdminSession, async (c) => {
|
|
26941
27034
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
26942
27035
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
26943
27036
|
const eventId = c.req.param("eventId");
|
|
@@ -27140,7 +27233,7 @@ app52.patch("/:eventId", requireAdminSession, async (c) => {
|
|
|
27140
27233
|
await session.close();
|
|
27141
27234
|
}
|
|
27142
27235
|
});
|
|
27143
|
-
|
|
27236
|
+
app53.post("/suspend-all", requireAdminSession, async (c) => {
|
|
27144
27237
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
27145
27238
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
27146
27239
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -27168,7 +27261,7 @@ app52.post("/suspend-all", requireAdminSession, async (c) => {
|
|
|
27168
27261
|
await session.close();
|
|
27169
27262
|
}
|
|
27170
27263
|
});
|
|
27171
|
-
|
|
27264
|
+
app53.post("/resume-all", requireAdminSession, async (c) => {
|
|
27172
27265
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
27173
27266
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
27174
27267
|
const session = getSession();
|
|
@@ -27235,7 +27328,7 @@ app52.post("/resume-all", requireAdminSession, async (c) => {
|
|
|
27235
27328
|
await session.close();
|
|
27236
27329
|
}
|
|
27237
27330
|
});
|
|
27238
|
-
|
|
27331
|
+
app53.post("/:eventId/suspend", requireAdminSession, async (c) => {
|
|
27239
27332
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
27240
27333
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
27241
27334
|
const eventId = c.req.param("eventId");
|
|
@@ -27267,7 +27360,7 @@ app52.post("/:eventId/suspend", requireAdminSession, async (c) => {
|
|
|
27267
27360
|
await session.close();
|
|
27268
27361
|
}
|
|
27269
27362
|
});
|
|
27270
|
-
|
|
27363
|
+
app53.post("/:eventId/resume", requireAdminSession, async (c) => {
|
|
27271
27364
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
27272
27365
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
27273
27366
|
const eventId = c.req.param("eventId");
|
|
@@ -27345,7 +27438,7 @@ app52.post("/:eventId/resume", requireAdminSession, async (c) => {
|
|
|
27345
27438
|
await session.close();
|
|
27346
27439
|
}
|
|
27347
27440
|
});
|
|
27348
|
-
|
|
27441
|
+
app53.delete("/:eventId", requireAdminSession, async (c) => {
|
|
27349
27442
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
27350
27443
|
if (!accountId) {
|
|
27351
27444
|
console.error('[admin:routines] op=delete auth-rejected reason="no account for session"');
|
|
@@ -27378,7 +27471,7 @@ app52.delete("/:eventId", requireAdminSession, async (c) => {
|
|
|
27378
27471
|
await session.close();
|
|
27379
27472
|
}
|
|
27380
27473
|
});
|
|
27381
|
-
var routines_default =
|
|
27474
|
+
var routines_default = app53;
|
|
27382
27475
|
|
|
27383
27476
|
// server/routes/admin/skills.ts
|
|
27384
27477
|
init_dist();
|
|
@@ -27387,7 +27480,7 @@ init_account_scope();
|
|
|
27387
27480
|
init_route_cache();
|
|
27388
27481
|
import { existsSync as existsSync42, readdirSync as readdirSync26, readFileSync as readFileSync42, rmSync as rmSync6 } from "fs";
|
|
27389
27482
|
import { resolve as resolve36 } from "path";
|
|
27390
|
-
var
|
|
27483
|
+
var app54 = new Hono();
|
|
27391
27484
|
var NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
27392
27485
|
function splitSkillMd(text) {
|
|
27393
27486
|
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
|
|
@@ -27416,7 +27509,7 @@ function subdirs2(dir) {
|
|
|
27416
27509
|
return [];
|
|
27417
27510
|
}
|
|
27418
27511
|
}
|
|
27419
|
-
|
|
27512
|
+
app54.get("/", requireAdminSession, async (c) => {
|
|
27420
27513
|
const acct = accountDirForSession(c.var.cacheKey);
|
|
27421
27514
|
if (!acct) {
|
|
27422
27515
|
console.error('[admin:skills] op=list auth-rejected reason="no account for session"');
|
|
@@ -27449,7 +27542,7 @@ app53.get("/", requireAdminSession, async (c) => {
|
|
|
27449
27542
|
console.log(`[admin:skills] op=list accountId=${acct.accountId.slice(0, 8)} plugins=${value.pluginCount} skills=${value.skills.length} cache=${state}`);
|
|
27450
27543
|
return c.json({ skills: value.skills });
|
|
27451
27544
|
});
|
|
27452
|
-
|
|
27545
|
+
app54.get("/:plugin/:skill", requireAdminSession, async (c) => {
|
|
27453
27546
|
const acct = accountDirForSession(c.var.cacheKey);
|
|
27454
27547
|
if (!acct) return c.json({ error: "Account not found for session" }, 401);
|
|
27455
27548
|
const plugin = c.req.param("plugin");
|
|
@@ -27474,7 +27567,7 @@ app53.get("/:plugin/:skill", requireAdminSession, async (c) => {
|
|
|
27474
27567
|
return c.json({ error: `Skill unavailable: ${message}` }, 503);
|
|
27475
27568
|
}
|
|
27476
27569
|
});
|
|
27477
|
-
|
|
27570
|
+
app54.delete("/:plugin/:skill", requireAdminSession, async (c) => {
|
|
27478
27571
|
const acct = accountDirForSession(c.var.cacheKey);
|
|
27479
27572
|
if (!acct) return c.json({ error: "Account not found for session" }, 401);
|
|
27480
27573
|
const plugin = c.req.param("plugin");
|
|
@@ -27507,7 +27600,7 @@ app53.delete("/:plugin/:skill", requireAdminSession, async (c) => {
|
|
|
27507
27600
|
return c.json({ error: `Delete failed: ${message}` }, 503);
|
|
27508
27601
|
}
|
|
27509
27602
|
});
|
|
27510
|
-
var skills_default =
|
|
27603
|
+
var skills_default = app54;
|
|
27511
27604
|
|
|
27512
27605
|
// server/routes/admin/tasks-list.ts
|
|
27513
27606
|
init_dist();
|
|
@@ -27515,7 +27608,7 @@ init_helpers();
|
|
|
27515
27608
|
init_claude_agent();
|
|
27516
27609
|
init_route_cache();
|
|
27517
27610
|
init_neo4j_store();
|
|
27518
|
-
import { basename as basename15, join as
|
|
27611
|
+
import { basename as basename15, join as join50 } from "path";
|
|
27519
27612
|
|
|
27520
27613
|
// app/lib/time-entry-format.ts
|
|
27521
27614
|
function secondsBetween(startIso, endIso) {
|
|
@@ -27536,20 +27629,20 @@ function toNum(v) {
|
|
|
27536
27629
|
|
|
27537
27630
|
// server/routes/admin/tasks-list.ts
|
|
27538
27631
|
init_sidebar_sessions();
|
|
27539
|
-
var
|
|
27632
|
+
var TAG35 = "[task-timer]";
|
|
27540
27633
|
var COMPLETED = /* @__PURE__ */ new Set(["completed"]);
|
|
27541
27634
|
var HIDDEN_FROM_OPEN = /* @__PURE__ */ new Set(["completed", "cancelled"]);
|
|
27542
|
-
var
|
|
27543
|
-
|
|
27635
|
+
var app55 = new Hono();
|
|
27636
|
+
app55.get("/", requireAdminSession, async (c) => {
|
|
27544
27637
|
const cacheKey = c.var.cacheKey;
|
|
27545
27638
|
const accountId = getAccountIdForSession(cacheKey);
|
|
27546
27639
|
if (!accountId) {
|
|
27547
|
-
console.error(`${
|
|
27640
|
+
console.error(`${TAG35} op=list auth-rejected reason="no account for session"`);
|
|
27548
27641
|
return c.json({ error: "Account not found for session" }, 401);
|
|
27549
27642
|
}
|
|
27550
27643
|
const cacheStart = Date.now();
|
|
27551
27644
|
const cached3 = await getOrCompute("tasks-list", accountId, () => computeTaskList(accountId));
|
|
27552
|
-
console.log(`${
|
|
27645
|
+
console.log(`${TAG35} op=list-cache cache=${cached3.state} account=${accountId} ms=${Date.now() - cacheStart}`);
|
|
27553
27646
|
if (cached3.value === null) {
|
|
27554
27647
|
return c.json({ error: "tasks-list-failed" }, 500);
|
|
27555
27648
|
}
|
|
@@ -27650,13 +27743,13 @@ async function computeTaskList(accountId) {
|
|
|
27650
27743
|
orphans = orphanResult.records.length > 0 ? toNum(orphanResult.records[0].get("orphans")) : 0;
|
|
27651
27744
|
} catch (err) {
|
|
27652
27745
|
console.error(
|
|
27653
|
-
`${
|
|
27746
|
+
`${TAG35} op=session-orphans-census-failed account=${accountId} error="${err instanceof Error ? err.message : String(err)}"`
|
|
27654
27747
|
);
|
|
27655
27748
|
orphans = -1;
|
|
27656
27749
|
}
|
|
27657
27750
|
if (orphans > 0) {
|
|
27658
27751
|
console.error(
|
|
27659
|
-
`${
|
|
27752
|
+
`${TAG35} op=session-orphans account=${accountId} orphans=${orphans} detail="task marked for a session spawn that never linked; the spawned session is unreachable from its row"`
|
|
27660
27753
|
);
|
|
27661
27754
|
}
|
|
27662
27755
|
let orphanEntries = 0;
|
|
@@ -27675,14 +27768,14 @@ async function computeTaskList(accountId) {
|
|
|
27675
27768
|
orphanAdjustments = orphanTime.records.length > 0 ? toNum(orphanTime.records[0].get("orphanAdjustments")) : 0;
|
|
27676
27769
|
} catch (err) {
|
|
27677
27770
|
console.error(
|
|
27678
|
-
`${
|
|
27771
|
+
`${TAG35} op=orphan-time-records-census-failed account=${accountId} error="${err instanceof Error ? err.message : String(err)}"`
|
|
27679
27772
|
);
|
|
27680
27773
|
orphanEntries = -1;
|
|
27681
27774
|
orphanAdjustments = -1;
|
|
27682
27775
|
}
|
|
27683
27776
|
if (orphanEntries > 0 || orphanAdjustments > 0) {
|
|
27684
27777
|
console.error(
|
|
27685
|
-
`${
|
|
27778
|
+
`${TAG35} op=orphan-time-records account=${accountId} orphanEntries=${orphanEntries} orphanAdjustments=${orphanAdjustments} detail="time records whose task no longer exists; something removed the task without its records"`
|
|
27686
27779
|
);
|
|
27687
27780
|
}
|
|
27688
27781
|
const linkedIds = [...open3, ...completed].map((r) => r.sessionId).filter((s) => s !== null);
|
|
@@ -27692,10 +27785,10 @@ async function computeTaskList(accountId) {
|
|
|
27692
27785
|
dangling = 0;
|
|
27693
27786
|
} else if (cfg !== null) {
|
|
27694
27787
|
try {
|
|
27695
|
-
const walk = enumerateJsonlsWithSkips(
|
|
27788
|
+
const walk = enumerateJsonlsWithSkips(join50(cfg, "projects"));
|
|
27696
27789
|
if (walk.skipped > 0) {
|
|
27697
27790
|
console.error(
|
|
27698
|
-
`${
|
|
27791
|
+
`${TAG35} op=session-dangling-census-incomplete account=${accountId} skipped=${walk.skipped} detail="a slug the walk could not read contributes no session ids, so its links cannot be judged"`
|
|
27699
27792
|
);
|
|
27700
27793
|
dangling = null;
|
|
27701
27794
|
} else {
|
|
@@ -27704,34 +27797,34 @@ async function computeTaskList(accountId) {
|
|
|
27704
27797
|
}
|
|
27705
27798
|
} catch (err) {
|
|
27706
27799
|
console.error(
|
|
27707
|
-
`${
|
|
27800
|
+
`${TAG35} op=session-dangling-census-failed account=${accountId} error="${err instanceof Error ? err.message : String(err)}"`
|
|
27708
27801
|
);
|
|
27709
27802
|
dangling = null;
|
|
27710
27803
|
}
|
|
27711
27804
|
}
|
|
27712
27805
|
if (dangling !== null && dangling > 0) {
|
|
27713
27806
|
console.error(
|
|
27714
|
-
`${
|
|
27807
|
+
`${TAG35} op=session-dangling account=${accountId} dangling=${dangling} linked=${linkedIds.length} detail="a task links a session with no JSONL on disk; clicking it will not resume"`
|
|
27715
27808
|
);
|
|
27716
27809
|
}
|
|
27717
27810
|
const returned = result.records.length;
|
|
27718
27811
|
if (returned < graphTotal) {
|
|
27719
27812
|
console.error(
|
|
27720
|
-
`${
|
|
27813
|
+
`${TAG35} op=list row-count-shortfall account=${accountId} returned=${returned} graphTotal=${graphTotal} missing=${graphTotal - returned}`
|
|
27721
27814
|
);
|
|
27722
27815
|
}
|
|
27723
27816
|
console.log(
|
|
27724
|
-
`${
|
|
27817
|
+
`${TAG35} op=list account=${accountId} returned=${returned} graphTotal=${graphTotal} open=${open3.length} completed=${completed.length} missingTaskId=${missingTaskId} missingCreatedAt=${missingCreatedAt} assigned=${assigned} sessionLinked=${sessionLinked} sessionOrphans=${orphans < 0 ? "n/a" : orphans} sessionDangling=${dangling === null ? "n/a" : dangling}`
|
|
27725
27818
|
);
|
|
27726
27819
|
return { open: open3, completed };
|
|
27727
27820
|
} catch (err) {
|
|
27728
|
-
console.error(`${
|
|
27821
|
+
console.error(`${TAG35} op=list error="${err instanceof Error ? err.message : String(err)}"`);
|
|
27729
27822
|
return null;
|
|
27730
27823
|
} finally {
|
|
27731
27824
|
await session.close();
|
|
27732
27825
|
}
|
|
27733
27826
|
}
|
|
27734
|
-
var tasks_list_default =
|
|
27827
|
+
var tasks_list_default = app55;
|
|
27735
27828
|
|
|
27736
27829
|
// server/routes/admin/task-timer-start.ts
|
|
27737
27830
|
init_dist();
|
|
@@ -27740,9 +27833,9 @@ init_claude_agent();
|
|
|
27740
27833
|
init_route_cache();
|
|
27741
27834
|
init_neo4j_store();
|
|
27742
27835
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
27743
|
-
var
|
|
27744
|
-
var
|
|
27745
|
-
|
|
27836
|
+
var TAG36 = "[task-timer]";
|
|
27837
|
+
var app56 = new Hono();
|
|
27838
|
+
app56.post("/", requireAdminSession, async (c) => {
|
|
27746
27839
|
const cacheKey = c.var.cacheKey;
|
|
27747
27840
|
const accountId = getAccountIdForSession(cacheKey);
|
|
27748
27841
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -27755,7 +27848,7 @@ app55.post("/", requireAdminSession, async (c) => {
|
|
|
27755
27848
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
27756
27849
|
if (!taskId) {
|
|
27757
27850
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
27758
|
-
console.error(`${
|
|
27851
|
+
console.error(`${TAG36} op=timer-start rejected reason=${reason} account=${accountId}`);
|
|
27759
27852
|
return c.json({ error: "taskId required" }, 400);
|
|
27760
27853
|
}
|
|
27761
27854
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -27766,7 +27859,7 @@ app55.post("/", requireAdminSession, async (c) => {
|
|
|
27766
27859
|
{ taskId, accountId }
|
|
27767
27860
|
);
|
|
27768
27861
|
if (target.records.length === 0) {
|
|
27769
|
-
console.error(`${
|
|
27862
|
+
console.error(`${TAG36} op=start taskId=${taskId} accountId=${accountId} result=task-not-found`);
|
|
27770
27863
|
return c.json({ error: "task-not-found" }, 404);
|
|
27771
27864
|
}
|
|
27772
27865
|
const open3 = await session.run(
|
|
@@ -27778,7 +27871,7 @@ app55.post("/", requireAdminSession, async (c) => {
|
|
|
27778
27871
|
const priorEntryId = open3.records[0]?.get("entryId");
|
|
27779
27872
|
const priorStartedAt = open3.records[0]?.get("startedAt");
|
|
27780
27873
|
if (priorEntryId) {
|
|
27781
|
-
console.log(`${
|
|
27874
|
+
console.log(`${TAG36} op=start taskId=${taskId} accountId=${accountId} result=already-running`);
|
|
27782
27875
|
invalidate("tasks-list", accountId);
|
|
27783
27876
|
return c.json({ ok: true, running: true, entryId: priorEntryId, startedAt: priorStartedAt });
|
|
27784
27877
|
}
|
|
@@ -27789,17 +27882,17 @@ app55.post("/", requireAdminSession, async (c) => {
|
|
|
27789
27882
|
CREATE (te)-[:LOGGED_AGAINST]->(t)`,
|
|
27790
27883
|
{ taskId, accountId, entryId, now }
|
|
27791
27884
|
);
|
|
27792
|
-
console.log(`${
|
|
27885
|
+
console.log(`${TAG36} op=opened taskId=${taskId} entryId=${entryId} startedAt=${now}`);
|
|
27793
27886
|
invalidate("tasks-list", accountId);
|
|
27794
27887
|
return c.json({ ok: true, running: true, entryId, startedAt: now });
|
|
27795
27888
|
} catch (err) {
|
|
27796
|
-
console.error(`${
|
|
27889
|
+
console.error(`${TAG36} op=start error="${err instanceof Error ? err.message : String(err)}"`);
|
|
27797
27890
|
return c.json({ error: "task-timer-start-failed" }, 500);
|
|
27798
27891
|
} finally {
|
|
27799
27892
|
await session.close();
|
|
27800
27893
|
}
|
|
27801
27894
|
});
|
|
27802
|
-
var task_timer_start_default =
|
|
27895
|
+
var task_timer_start_default = app56;
|
|
27803
27896
|
|
|
27804
27897
|
// server/routes/admin/task-timer-stop.ts
|
|
27805
27898
|
init_dist();
|
|
@@ -27808,9 +27901,9 @@ init_claude_agent();
|
|
|
27808
27901
|
init_route_cache();
|
|
27809
27902
|
init_neo4j_store();
|
|
27810
27903
|
import neo4j4 from "neo4j-driver";
|
|
27811
|
-
var
|
|
27812
|
-
var
|
|
27813
|
-
|
|
27904
|
+
var TAG37 = "[task-timer]";
|
|
27905
|
+
var app57 = new Hono();
|
|
27906
|
+
app57.post("/", requireAdminSession, async (c) => {
|
|
27814
27907
|
const cacheKey = c.var.cacheKey;
|
|
27815
27908
|
const accountId = getAccountIdForSession(cacheKey);
|
|
27816
27909
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -27823,7 +27916,7 @@ app56.post("/", requireAdminSession, async (c) => {
|
|
|
27823
27916
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
27824
27917
|
if (!taskId) {
|
|
27825
27918
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
27826
|
-
console.error(`${
|
|
27919
|
+
console.error(`${TAG37} op=timer-stop rejected reason=${reason} account=${accountId}`);
|
|
27827
27920
|
return c.json({ error: "taskId required" }, 400);
|
|
27828
27921
|
}
|
|
27829
27922
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -27844,7 +27937,7 @@ app56.post("/", requireAdminSession, async (c) => {
|
|
|
27844
27937
|
{ taskId, accountId }
|
|
27845
27938
|
);
|
|
27846
27939
|
const secondsLogged2 = toNum(cur.records[0]?.get("secondsLogged"));
|
|
27847
|
-
console.log(`${
|
|
27940
|
+
console.log(`${TAG37} op=stop taskId=${taskId} entryId=none seconds=0 totalAfter=${secondsLogged2}`);
|
|
27848
27941
|
invalidate("tasks-list", accountId);
|
|
27849
27942
|
return c.json({ ok: true, running: false, seconds: 0, secondsLogged: secondsLogged2 });
|
|
27850
27943
|
}
|
|
@@ -27868,18 +27961,18 @@ app56.post("/", requireAdminSession, async (c) => {
|
|
|
27868
27961
|
const sumEntries = toNum(verify.records[0]?.get("sumEntries"));
|
|
27869
27962
|
const sumAdjustments = toNum(verify.records[0]?.get("sumAdjustments"));
|
|
27870
27963
|
const secondsLogged = toNum(verify.records[0]?.get("secondsLogged"));
|
|
27871
|
-
console.log(`${
|
|
27872
|
-
console.log(`${
|
|
27964
|
+
console.log(`${TAG37} op=stop taskId=${taskId} entryId=${entryId} seconds=${seconds} totalAfter=${secondsLogged}`);
|
|
27965
|
+
console.log(`${TAG37} op=persisted taskId=${taskId} entryId=${entryId} sumEntries=${sumEntries} sumAdjustments=${sumAdjustments} secondsLogged=${secondsLogged}`);
|
|
27873
27966
|
invalidate("tasks-list", accountId);
|
|
27874
27967
|
return c.json({ ok: true, running: false, seconds, secondsLogged });
|
|
27875
27968
|
} catch (err) {
|
|
27876
|
-
console.error(`${
|
|
27969
|
+
console.error(`${TAG37} op=stop error="${err instanceof Error ? err.message : String(err)}"`);
|
|
27877
27970
|
return c.json({ error: "task-timer-stop-failed" }, 500);
|
|
27878
27971
|
} finally {
|
|
27879
27972
|
await session.close();
|
|
27880
27973
|
}
|
|
27881
27974
|
});
|
|
27882
|
-
var task_timer_stop_default =
|
|
27975
|
+
var task_timer_stop_default = app57;
|
|
27883
27976
|
|
|
27884
27977
|
// server/routes/admin/task-complete.ts
|
|
27885
27978
|
init_dist();
|
|
@@ -27887,9 +27980,9 @@ init_helpers();
|
|
|
27887
27980
|
init_claude_agent();
|
|
27888
27981
|
init_route_cache();
|
|
27889
27982
|
init_neo4j_store();
|
|
27890
|
-
var
|
|
27891
|
-
var
|
|
27892
|
-
|
|
27983
|
+
var TAG38 = "[task-timer]";
|
|
27984
|
+
var app58 = new Hono();
|
|
27985
|
+
app58.post("/", requireAdminSession, async (c) => {
|
|
27893
27986
|
const cacheKey = c.var.cacheKey;
|
|
27894
27987
|
const accountId = getAccountIdForSession(cacheKey);
|
|
27895
27988
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -27902,7 +27995,7 @@ app57.post("/", requireAdminSession, async (c) => {
|
|
|
27902
27995
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
27903
27996
|
if (!taskId) {
|
|
27904
27997
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
27905
|
-
console.error(`${
|
|
27998
|
+
console.error(`${TAG38} op=complete rejected reason=${reason} account=${accountId}`);
|
|
27906
27999
|
return c.json({ error: "taskId required" }, 400);
|
|
27907
28000
|
}
|
|
27908
28001
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -27918,17 +28011,17 @@ app57.post("/", requireAdminSession, async (c) => {
|
|
|
27918
28011
|
return c.json({ error: "task-not-found" }, 404);
|
|
27919
28012
|
}
|
|
27920
28013
|
const secondsLogged = toNum(result.records[0].get("secondsLogged"));
|
|
27921
|
-
console.log(`${
|
|
28014
|
+
console.log(`${TAG38} op=complete taskId=${taskId} status=completed secondsLogged=${secondsLogged}`);
|
|
27922
28015
|
invalidate("tasks-list", accountId);
|
|
27923
28016
|
return c.json({ ok: true, status: "completed", secondsLogged });
|
|
27924
28017
|
} catch (err) {
|
|
27925
|
-
console.error(`${
|
|
28018
|
+
console.error(`${TAG38} op=complete error="${err instanceof Error ? err.message : String(err)}"`);
|
|
27926
28019
|
return c.json({ error: "task-complete-failed" }, 500);
|
|
27927
28020
|
} finally {
|
|
27928
28021
|
await session.close();
|
|
27929
28022
|
}
|
|
27930
28023
|
});
|
|
27931
|
-
var task_complete_default =
|
|
28024
|
+
var task_complete_default = app58;
|
|
27932
28025
|
|
|
27933
28026
|
// server/routes/admin/task-time-adjust.ts
|
|
27934
28027
|
init_dist();
|
|
@@ -27938,9 +28031,9 @@ init_route_cache();
|
|
|
27938
28031
|
init_neo4j_store();
|
|
27939
28032
|
import { randomUUID as randomUUID12 } from "crypto";
|
|
27940
28033
|
import neo4j5 from "neo4j-driver";
|
|
27941
|
-
var
|
|
27942
|
-
var
|
|
27943
|
-
|
|
28034
|
+
var TAG39 = "[task-time-adjust]";
|
|
28035
|
+
var app59 = new Hono();
|
|
28036
|
+
app59.post("/", requireAdminSession, async (c) => {
|
|
27944
28037
|
const cacheKey = c.var.cacheKey;
|
|
27945
28038
|
const accountId = getAccountIdForSession(cacheKey);
|
|
27946
28039
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -27948,23 +28041,23 @@ app58.post("/", requireAdminSession, async (c) => {
|
|
|
27948
28041
|
try {
|
|
27949
28042
|
body = await c.req.json();
|
|
27950
28043
|
} catch {
|
|
27951
|
-
console.error(`${
|
|
28044
|
+
console.error(`${TAG39} op=reject reason=bad-json`);
|
|
27952
28045
|
return c.json({ error: "invalid-json" }, 400);
|
|
27953
28046
|
}
|
|
27954
28047
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
27955
28048
|
if (!taskId) {
|
|
27956
28049
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
27957
|
-
console.error(`${
|
|
28050
|
+
console.error(`${TAG39} op=time-adjust rejected reason=${reason} account=${accountId}`);
|
|
27958
28051
|
return c.json({ error: "taskId required" }, 400);
|
|
27959
28052
|
}
|
|
27960
28053
|
const newSeconds = body.newSeconds;
|
|
27961
28054
|
if (typeof newSeconds !== "number" || !Number.isInteger(newSeconds) || newSeconds < 0) {
|
|
27962
|
-
console.error(`${
|
|
28055
|
+
console.error(`${TAG39} op=reject reason=invalid-seconds taskId=${taskId} accountId=${accountId}`);
|
|
27963
28056
|
return c.json({ error: "newSeconds must be a non-negative integer" }, 400);
|
|
27964
28057
|
}
|
|
27965
28058
|
const adjustmentId = randomUUID12();
|
|
27966
28059
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
27967
|
-
console.log(`${
|
|
28060
|
+
console.log(`${TAG39} op=request adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId} newSeconds=${newSeconds}`);
|
|
27968
28061
|
const session = getSession();
|
|
27969
28062
|
try {
|
|
27970
28063
|
const guard = await session.run(
|
|
@@ -27974,12 +28067,12 @@ app58.post("/", requireAdminSession, async (c) => {
|
|
|
27974
28067
|
{ taskId, accountId }
|
|
27975
28068
|
);
|
|
27976
28069
|
if (guard.records.length === 0) {
|
|
27977
|
-
console.error(`${
|
|
28070
|
+
console.error(`${TAG39} op=reject reason=no-task adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId}`);
|
|
27978
28071
|
return c.json({ error: "task-not-found" }, 404);
|
|
27979
28072
|
}
|
|
27980
28073
|
const openCount = toNum(guard.records[0].get("openCount"));
|
|
27981
28074
|
if (openCount > 0) {
|
|
27982
|
-
console.error(`${
|
|
28075
|
+
console.error(`${TAG39} op=reject reason=running adjustmentId=${adjustmentId} taskId=${taskId} accountId=${accountId}`);
|
|
27983
28076
|
return c.json({ error: "task-timer-running" }, 409);
|
|
27984
28077
|
}
|
|
27985
28078
|
const previousSeconds = toNum(guard.records[0].get("previousSeconds"));
|
|
@@ -28005,17 +28098,17 @@ app58.post("/", requireAdminSession, async (c) => {
|
|
|
28005
28098
|
}
|
|
28006
28099
|
);
|
|
28007
28100
|
const secondsLoggedAfter = toNum(write.records[0]?.get("secondsLoggedAfter"));
|
|
28008
|
-
console.log(`${
|
|
28101
|
+
console.log(`${TAG39} op=persisted adjustmentId=${adjustmentId} previousSeconds=${previousSeconds} newSeconds=${newSeconds} delta=${delta} secondsLoggedAfter=${secondsLoggedAfter}`);
|
|
28009
28102
|
invalidate("tasks-list", accountId);
|
|
28010
28103
|
return c.json({ ok: true, secondsLogged: secondsLoggedAfter });
|
|
28011
28104
|
} catch (err) {
|
|
28012
|
-
console.error(`${
|
|
28105
|
+
console.error(`${TAG39} op=error adjustmentId=${adjustmentId} taskId=${taskId} error="${err instanceof Error ? err.message : String(err)}"`);
|
|
28013
28106
|
return c.json({ error: "task-time-adjust-failed" }, 500);
|
|
28014
28107
|
} finally {
|
|
28015
28108
|
await session.close();
|
|
28016
28109
|
}
|
|
28017
28110
|
});
|
|
28018
|
-
var task_time_adjust_default =
|
|
28111
|
+
var task_time_adjust_default = app59;
|
|
28019
28112
|
|
|
28020
28113
|
// server/routes/admin/task-delete.ts
|
|
28021
28114
|
init_dist();
|
|
@@ -28024,9 +28117,9 @@ init_claude_agent();
|
|
|
28024
28117
|
init_route_cache();
|
|
28025
28118
|
init_neo4j_store();
|
|
28026
28119
|
import { randomUUID as randomUUID13 } from "crypto";
|
|
28027
|
-
var
|
|
28028
|
-
var
|
|
28029
|
-
|
|
28120
|
+
var TAG40 = "[task-delete]";
|
|
28121
|
+
var app60 = new Hono();
|
|
28122
|
+
app60.post("/", requireAdminSession, async (c) => {
|
|
28030
28123
|
const cacheKey = c.var.cacheKey;
|
|
28031
28124
|
const accountId = getAccountIdForSession(cacheKey);
|
|
28032
28125
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -28034,18 +28127,18 @@ app59.post("/", requireAdminSession, async (c) => {
|
|
|
28034
28127
|
try {
|
|
28035
28128
|
body = await c.req.json();
|
|
28036
28129
|
} catch {
|
|
28037
|
-
console.error(`${
|
|
28130
|
+
console.error(`${TAG40} op=reject reason=bad-json`);
|
|
28038
28131
|
return c.json({ error: "invalid-json" }, 400);
|
|
28039
28132
|
}
|
|
28040
28133
|
const deletionId = randomUUID13();
|
|
28041
28134
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
28042
28135
|
if (!taskId) {
|
|
28043
28136
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
28044
|
-
console.error(`${
|
|
28137
|
+
console.error(`${TAG40} op=reject reason=${reason} deletionId=${deletionId} accountId=${accountId}`);
|
|
28045
28138
|
return c.json({ error: "taskId required" }, 400);
|
|
28046
28139
|
}
|
|
28047
28140
|
console.log(
|
|
28048
|
-
`${
|
|
28141
|
+
`${TAG40} op=request deletionId=${deletionId} taskId=${taskId} accountId=${accountId} confirmed=${body.confirmed === true}`
|
|
28049
28142
|
);
|
|
28050
28143
|
const session = getSession();
|
|
28051
28144
|
try {
|
|
@@ -28061,18 +28154,18 @@ app59.post("/", requireAdminSession, async (c) => {
|
|
|
28061
28154
|
{ taskId, accountId }
|
|
28062
28155
|
);
|
|
28063
28156
|
if (guard.records.length === 0) {
|
|
28064
|
-
console.error(`${
|
|
28157
|
+
console.error(`${TAG40} op=reject reason=no-task deletionId=${deletionId} taskId=${taskId} accountId=${accountId}`);
|
|
28065
28158
|
return c.json({ error: "task-not-found" }, 404);
|
|
28066
28159
|
}
|
|
28067
28160
|
const timeEntries = toNum(guard.records[0].get("timeEntries"));
|
|
28068
28161
|
const openCount = toNum(guard.records[0].get("openCount"));
|
|
28069
28162
|
const adjustments = toNum(guard.records[0].get("adjustments"));
|
|
28070
28163
|
console.log(
|
|
28071
|
-
`${
|
|
28164
|
+
`${TAG40} op=guard deletionId=${deletionId} taskId=${taskId} openCount=${openCount} timeEntries=${timeEntries} adjustments=${adjustments}`
|
|
28072
28165
|
);
|
|
28073
28166
|
if (openCount > 0) {
|
|
28074
28167
|
console.error(
|
|
28075
|
-
`${
|
|
28168
|
+
`${TAG40} op=reject reason=running deletionId=${deletionId} taskId=${taskId} openCount=${openCount}`
|
|
28076
28169
|
);
|
|
28077
28170
|
return c.json({ error: "task-timer-running" }, 409);
|
|
28078
28171
|
}
|
|
@@ -28108,25 +28201,25 @@ app59.post("/", requireAdminSession, async (c) => {
|
|
|
28108
28201
|
const adjustmentsLeft = toNum(after.records[0]?.get("adjustmentsLeft"));
|
|
28109
28202
|
const remaining = taskLeft + entriesLeft + adjustmentsLeft;
|
|
28110
28203
|
console.log(
|
|
28111
|
-
`${
|
|
28204
|
+
`${TAG40} op=persisted deletionId=${deletionId} taskId=${taskId} tasksDeleted=${tasksDeleted} timeEntriesDeleted=${timeEntriesDeleted} adjustmentsDeleted=${adjustmentsDeleted} remaining=${remaining}`
|
|
28112
28205
|
);
|
|
28113
28206
|
if (remaining > 0) {
|
|
28114
28207
|
console.error(
|
|
28115
|
-
`${
|
|
28208
|
+
`${TAG40} op=incomplete deletionId=${deletionId} taskId=${taskId} taskLeft=${taskLeft} entriesLeft=${entriesLeft} adjustmentsLeft=${adjustmentsLeft} detail="the delete returned but rows for this taskId survive"`
|
|
28116
28209
|
);
|
|
28117
28210
|
}
|
|
28118
28211
|
invalidate("tasks-list", accountId);
|
|
28119
28212
|
return c.json({ ok: true, tasksDeleted, timeEntriesDeleted, adjustmentsDeleted, remaining });
|
|
28120
28213
|
} catch (err) {
|
|
28121
28214
|
console.error(
|
|
28122
|
-
`${
|
|
28215
|
+
`${TAG40} op=error deletionId=${deletionId} taskId=${taskId} error="${err instanceof Error ? err.message : String(err)}"`
|
|
28123
28216
|
);
|
|
28124
28217
|
return c.json({ error: "task-delete-failed" }, 500);
|
|
28125
28218
|
} finally {
|
|
28126
28219
|
await session.close();
|
|
28127
28220
|
}
|
|
28128
28221
|
});
|
|
28129
|
-
var task_delete_default =
|
|
28222
|
+
var task_delete_default = app60;
|
|
28130
28223
|
|
|
28131
28224
|
// server/routes/admin/task-assign.ts
|
|
28132
28225
|
init_dist();
|
|
@@ -28222,9 +28315,9 @@ async function resolveAssignableAdmins(accountId, accountsDir = ACCOUNTS_DIR) {
|
|
|
28222
28315
|
}
|
|
28223
28316
|
|
|
28224
28317
|
// server/routes/admin/task-assign.ts
|
|
28225
|
-
var
|
|
28226
|
-
var
|
|
28227
|
-
|
|
28318
|
+
var TAG41 = "[task-assign]";
|
|
28319
|
+
var app61 = new Hono();
|
|
28320
|
+
app61.post("/", requireAdminSession, async (c) => {
|
|
28228
28321
|
const cacheKey = c.var.cacheKey;
|
|
28229
28322
|
const accountId = getAccountIdForSession(cacheKey);
|
|
28230
28323
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -28237,7 +28330,7 @@ app60.post("/", requireAdminSession, async (c) => {
|
|
|
28237
28330
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
28238
28331
|
if (!taskId) {
|
|
28239
28332
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
28240
|
-
console.error(`${
|
|
28333
|
+
console.error(`${TAG41} op=assign rejected reason=${reason} account=${accountId}`);
|
|
28241
28334
|
return c.json({ error: "taskId required" }, 400);
|
|
28242
28335
|
}
|
|
28243
28336
|
const rawAssignee = body.assigneeUserId;
|
|
@@ -28249,7 +28342,7 @@ app60.post("/", requireAdminSession, async (c) => {
|
|
|
28249
28342
|
const { ids } = await resolveAllowedAssigneeIds(accountId);
|
|
28250
28343
|
if (!ids.has(assigneeUserId)) {
|
|
28251
28344
|
console.error(
|
|
28252
|
-
`${
|
|
28345
|
+
`${TAG41} op=assign taskId=${taskId.slice(0, 8)} assigneeUserId=${assigneeUserId.slice(0, 8)} assigned=false source=route reason=not-in-roster`
|
|
28253
28346
|
);
|
|
28254
28347
|
return c.json({ error: "assignee-not-in-roster" }, 403);
|
|
28255
28348
|
}
|
|
@@ -28271,7 +28364,7 @@ app60.post("/", requireAdminSession, async (c) => {
|
|
|
28271
28364
|
`MATCH (t:Task {taskId: $taskId, accountId: $accountId}) SET t.updatedAt = $now`,
|
|
28272
28365
|
{ taskId, accountId, now }
|
|
28273
28366
|
);
|
|
28274
|
-
console.log(`${
|
|
28367
|
+
console.log(`${TAG41} op=assign taskId=${taskId.slice(0, 8)} assigneeUserId=none assigned=false source=route`);
|
|
28275
28368
|
invalidate("tasks-list", accountId);
|
|
28276
28369
|
return c.json({ ok: true, assigneeUserId: null, assigneeName: null });
|
|
28277
28370
|
}
|
|
@@ -28287,7 +28380,7 @@ app60.post("/", requireAdminSession, async (c) => {
|
|
|
28287
28380
|
);
|
|
28288
28381
|
if (set.records.length === 0) {
|
|
28289
28382
|
console.error(
|
|
28290
|
-
`${
|
|
28383
|
+
`${TAG41} op=assign taskId=${taskId.slice(0, 8)} assigneeUserId=${assigneeUserId.slice(0, 8)} assigned=false source=route reason=no-adminuser-node`
|
|
28291
28384
|
);
|
|
28292
28385
|
return c.json({ error: "assignee-no-admin-node" }, 409);
|
|
28293
28386
|
}
|
|
@@ -28295,31 +28388,31 @@ app60.post("/", requireAdminSession, async (c) => {
|
|
|
28295
28388
|
const family = set.records[0].get("familyName") ?? null;
|
|
28296
28389
|
const assigneeName = given && given.trim().length > 0 ? family && family.trim().length > 0 ? `${given.trim()} ${family.trim()}` : given.trim() : null;
|
|
28297
28390
|
console.log(
|
|
28298
|
-
`${
|
|
28391
|
+
`${TAG41} op=assign taskId=${taskId.slice(0, 8)} assigneeUserId=${assigneeUserId.slice(0, 8)} assigned=true source=route`
|
|
28299
28392
|
);
|
|
28300
28393
|
invalidate("tasks-list", accountId);
|
|
28301
28394
|
return c.json({ ok: true, assigneeUserId, assigneeName });
|
|
28302
28395
|
} catch (err) {
|
|
28303
|
-
console.error(`${
|
|
28396
|
+
console.error(`${TAG41} op=assign error="${err instanceof Error ? err.message : String(err)}"`);
|
|
28304
28397
|
return c.json({ error: "task-assign-failed" }, 500);
|
|
28305
28398
|
} finally {
|
|
28306
28399
|
await session.close();
|
|
28307
28400
|
}
|
|
28308
28401
|
});
|
|
28309
|
-
var task_assign_default =
|
|
28402
|
+
var task_assign_default = app61;
|
|
28310
28403
|
|
|
28311
28404
|
// server/routes/admin/task-session-open.ts
|
|
28312
28405
|
init_dist();
|
|
28313
28406
|
init_helpers();
|
|
28314
28407
|
init_claude_agent();
|
|
28315
28408
|
init_neo4j_store();
|
|
28316
|
-
var
|
|
28317
|
-
var
|
|
28318
|
-
|
|
28409
|
+
var TAG42 = "[task-session]";
|
|
28410
|
+
var app62 = new Hono();
|
|
28411
|
+
app62.post("/", requireAdminSession, async (c) => {
|
|
28319
28412
|
const cacheKey = c.var.cacheKey;
|
|
28320
28413
|
const accountId = getAccountIdForSession(cacheKey);
|
|
28321
28414
|
if (!accountId) {
|
|
28322
|
-
console.error(`${
|
|
28415
|
+
console.error(`${TAG42} op=request auth-rejected reason="no account for session"`);
|
|
28323
28416
|
return c.json({ error: "Account not found for session" }, 401);
|
|
28324
28417
|
}
|
|
28325
28418
|
let body;
|
|
@@ -28331,7 +28424,7 @@ app61.post("/", requireAdminSession, async (c) => {
|
|
|
28331
28424
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
28332
28425
|
if (!taskId) {
|
|
28333
28426
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
28334
|
-
console.error(`${
|
|
28427
|
+
console.error(`${TAG42} op=request rejected reason=${reason} account=${accountId}`);
|
|
28335
28428
|
return c.json({ error: "taskId required" }, 400);
|
|
28336
28429
|
}
|
|
28337
28430
|
const session = getSession();
|
|
@@ -28345,14 +28438,14 @@ app61.post("/", requireAdminSession, async (c) => {
|
|
|
28345
28438
|
{ taskId, accountId }
|
|
28346
28439
|
);
|
|
28347
28440
|
if (found.records.length === 0) {
|
|
28348
|
-
console.error(`${
|
|
28441
|
+
console.error(`${TAG42} op=request taskId=${taskId} account=${accountId} result=task-not-found`);
|
|
28349
28442
|
return c.json({ error: "task-not-found" }, 404);
|
|
28350
28443
|
}
|
|
28351
28444
|
const title = found.records[0].get("name") ?? "";
|
|
28352
28445
|
const sessionId = found.records[0].get("sessionId") ?? null;
|
|
28353
28446
|
const description = found.records[0].get("description") ?? "";
|
|
28354
28447
|
const notes = found.records[0].get("notes") ?? "";
|
|
28355
|
-
console.log(`${
|
|
28448
|
+
console.log(`${TAG42} op=request taskId=${taskId} account=${accountId} linked=${sessionId ?? "none"}`);
|
|
28356
28449
|
if (sessionId !== null) return c.json({ sessionId, title, description, notes });
|
|
28357
28450
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
28358
28451
|
const stamped = await session.run(
|
|
@@ -28362,16 +28455,16 @@ app61.post("/", requireAdminSession, async (c) => {
|
|
|
28362
28455
|
{ taskId, accountId, now }
|
|
28363
28456
|
);
|
|
28364
28457
|
const at = stamped.records[0]?.get("at") ?? void 0;
|
|
28365
|
-
console.log(`${
|
|
28458
|
+
console.log(`${TAG42} op=marker taskId=${taskId} stamped=${at !== void 0}`);
|
|
28366
28459
|
return c.json({ sessionId: null, title, description, notes });
|
|
28367
28460
|
} catch (err) {
|
|
28368
|
-
console.error(`${
|
|
28461
|
+
console.error(`${TAG42} op=request taskId=${taskId} error="${err instanceof Error ? err.message : String(err)}"`);
|
|
28369
28462
|
return c.json({ error: "task-session-open-failed" }, 500);
|
|
28370
28463
|
} finally {
|
|
28371
28464
|
await session.close();
|
|
28372
28465
|
}
|
|
28373
28466
|
});
|
|
28374
|
-
var task_session_open_default =
|
|
28467
|
+
var task_session_open_default = app62;
|
|
28375
28468
|
|
|
28376
28469
|
// server/routes/admin/task-session-link.ts
|
|
28377
28470
|
init_dist();
|
|
@@ -28379,13 +28472,13 @@ init_helpers();
|
|
|
28379
28472
|
init_claude_agent();
|
|
28380
28473
|
init_neo4j_store();
|
|
28381
28474
|
init_route_cache();
|
|
28382
|
-
var
|
|
28383
|
-
var
|
|
28384
|
-
|
|
28475
|
+
var TAG43 = "[task-session]";
|
|
28476
|
+
var app63 = new Hono();
|
|
28477
|
+
app63.post("/", requireAdminSession, async (c) => {
|
|
28385
28478
|
const cacheKey = c.var.cacheKey;
|
|
28386
28479
|
const accountId = getAccountIdForSession(cacheKey);
|
|
28387
28480
|
if (!accountId) {
|
|
28388
|
-
console.error(`${
|
|
28481
|
+
console.error(`${TAG43} op=link auth-rejected reason="no account for session"`);
|
|
28389
28482
|
return c.json({ error: "Account not found for session" }, 401);
|
|
28390
28483
|
}
|
|
28391
28484
|
let body;
|
|
@@ -28397,12 +28490,12 @@ app62.post("/", requireAdminSession, async (c) => {
|
|
|
28397
28490
|
const taskId = typeof body.taskId === "string" ? body.taskId : "";
|
|
28398
28491
|
if (!taskId) {
|
|
28399
28492
|
const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
|
|
28400
|
-
console.error(`${
|
|
28493
|
+
console.error(`${TAG43} op=link rejected reason=${reason} account=${accountId}`);
|
|
28401
28494
|
return c.json({ error: "taskId required" }, 400);
|
|
28402
28495
|
}
|
|
28403
28496
|
const sessionId = typeof body.sessionId === "string" && body.sessionId.length > 0 ? body.sessionId : "";
|
|
28404
28497
|
if (!sessionId) {
|
|
28405
|
-
console.error(`${
|
|
28498
|
+
console.error(`${TAG43} op=link rejected reason=missing-sessionId taskId=${taskId} account=${accountId}`);
|
|
28406
28499
|
return c.json({ error: "sessionId required" }, 400);
|
|
28407
28500
|
}
|
|
28408
28501
|
const session = getSession();
|
|
@@ -28416,13 +28509,13 @@ app62.post("/", requireAdminSession, async (c) => {
|
|
|
28416
28509
|
{ taskId, accountId, sessionId }
|
|
28417
28510
|
);
|
|
28418
28511
|
if (state.records.length === 0) {
|
|
28419
|
-
console.error(`${
|
|
28512
|
+
console.error(`${TAG43} op=link taskId=${taskId} account=${accountId} result=task-not-found`);
|
|
28420
28513
|
return c.json({ error: "task-not-found" }, 404);
|
|
28421
28514
|
}
|
|
28422
28515
|
const conversationExists = state.records[0].get("conversationExists") === true;
|
|
28423
28516
|
const priorSessionIds = (state.records[0].get("priorSessionIds") ?? []).filter((s) => typeof s === "string");
|
|
28424
28517
|
if (!conversationExists) {
|
|
28425
|
-
console.error(`${
|
|
28518
|
+
console.error(`${TAG43} op=link-failed taskId=${taskId} sessionId=${sessionId} reason=conversation-absent`);
|
|
28426
28519
|
return c.json({ linked: false, created: false, repointedFrom: null });
|
|
28427
28520
|
}
|
|
28428
28521
|
const stale = priorSessionIds.filter((s) => s !== sessionId);
|
|
@@ -28448,49 +28541,49 @@ app62.post("/", requireAdminSession, async (c) => {
|
|
|
28448
28541
|
const repointedFrom = stale.length > 0 ? stale[0] : null;
|
|
28449
28542
|
if (!linked) {
|
|
28450
28543
|
console.error(
|
|
28451
|
-
`${
|
|
28544
|
+
`${TAG43} op=link-failed taskId=${taskId} sessionId=${sessionId} reason=edge-absent-after-merge linkedTo=${linkedTo ?? "none"}`
|
|
28452
28545
|
);
|
|
28453
28546
|
return c.json({ linked: false, created: false, repointedFrom });
|
|
28454
28547
|
}
|
|
28455
28548
|
console.log(
|
|
28456
|
-
`${
|
|
28549
|
+
`${TAG43} op=link taskId=${taskId} sessionId=${sessionId} created=${created} repointedFrom=${repointedFrom ?? "none"}`
|
|
28457
28550
|
);
|
|
28458
28551
|
invalidate("tasks-list", accountId);
|
|
28459
28552
|
return c.json({ linked: true, created, repointedFrom });
|
|
28460
28553
|
} catch (err) {
|
|
28461
28554
|
console.error(
|
|
28462
|
-
`${
|
|
28555
|
+
`${TAG43} op=link-failed taskId=${taskId} sessionId=${sessionId} reason="${err instanceof Error ? err.message : String(err)}"`
|
|
28463
28556
|
);
|
|
28464
28557
|
return c.json({ error: "task-session-link-failed" }, 500);
|
|
28465
28558
|
} finally {
|
|
28466
28559
|
await session.close();
|
|
28467
28560
|
}
|
|
28468
28561
|
});
|
|
28469
|
-
var task_session_link_default =
|
|
28562
|
+
var task_session_link_default = app63;
|
|
28470
28563
|
|
|
28471
28564
|
// server/routes/admin/admin-users-list.ts
|
|
28472
28565
|
init_dist();
|
|
28473
28566
|
init_helpers();
|
|
28474
28567
|
init_claude_agent();
|
|
28475
|
-
var
|
|
28476
|
-
var
|
|
28477
|
-
|
|
28568
|
+
var TAG44 = "[admin-users]";
|
|
28569
|
+
var app64 = new Hono();
|
|
28570
|
+
app64.get("/", requireAdminSession, async (c) => {
|
|
28478
28571
|
const cacheKey = c.var.cacheKey;
|
|
28479
28572
|
const accountId = getAccountIdForSession(cacheKey);
|
|
28480
28573
|
if (!accountId) {
|
|
28481
|
-
console.error(`${
|
|
28574
|
+
console.error(`${TAG44} op=list auth-rejected reason="no account for session"`);
|
|
28482
28575
|
return c.json({ error: "Account not found for session" }, 401);
|
|
28483
28576
|
}
|
|
28484
28577
|
try {
|
|
28485
28578
|
const users = await resolveAssignableAdmins(accountId);
|
|
28486
|
-
console.log(`${
|
|
28579
|
+
console.log(`${TAG44} op=list account=${accountId} count=${users.length}`);
|
|
28487
28580
|
return c.json({ ok: true, users });
|
|
28488
28581
|
} catch (err) {
|
|
28489
|
-
console.error(`${
|
|
28582
|
+
console.error(`${TAG44} op=list error="${err instanceof Error ? err.message : String(err)}"`);
|
|
28490
28583
|
return c.json({ error: "admin-users-list-failed" }, 500);
|
|
28491
28584
|
}
|
|
28492
28585
|
});
|
|
28493
|
-
var admin_users_list_default =
|
|
28586
|
+
var admin_users_list_default = app64;
|
|
28494
28587
|
|
|
28495
28588
|
// server/routes/admin/dispatch-destinations.ts
|
|
28496
28589
|
init_dist();
|
|
@@ -28500,7 +28593,7 @@ init_account();
|
|
|
28500
28593
|
init_neo4j_store();
|
|
28501
28594
|
init_src2();
|
|
28502
28595
|
import { resolve as resolve38 } from "path";
|
|
28503
|
-
var
|
|
28596
|
+
var TAG45 = "[admin:routines]";
|
|
28504
28597
|
function scopeFor(d, houseDir, houseAccountId) {
|
|
28505
28598
|
if (d.channel !== "whatsapp") return null;
|
|
28506
28599
|
if (d.label === "Account manager") return boundSubAccountFor(houseDir, d.destination);
|
|
@@ -28514,11 +28607,11 @@ function telephoneVariants(destination) {
|
|
|
28514
28607
|
function scrubDigitRuns(message) {
|
|
28515
28608
|
return message.replace(/\d{7,}/g, "<redacted>");
|
|
28516
28609
|
}
|
|
28517
|
-
var
|
|
28518
|
-
|
|
28610
|
+
var app65 = new Hono();
|
|
28611
|
+
app65.get("/", requireAdminSession, async (c) => {
|
|
28519
28612
|
const accountId = getAccountIdForSession(c.var.cacheKey);
|
|
28520
28613
|
if (!accountId) {
|
|
28521
|
-
console.error(`${
|
|
28614
|
+
console.error(`${TAG45} op=destinations auth-rejected reason="no account for session"`);
|
|
28522
28615
|
return c.json({ error: "Account not found for session" }, 401);
|
|
28523
28616
|
}
|
|
28524
28617
|
let houseAccountId = null;
|
|
@@ -28526,7 +28619,7 @@ app64.get("/", requireAdminSession, async (c) => {
|
|
|
28526
28619
|
houseAccountId = resolveHouseOrSoleAccountId(ACCOUNTS_DIR);
|
|
28527
28620
|
} catch (err) {
|
|
28528
28621
|
const message = err instanceof Error ? err.message : String(err);
|
|
28529
|
-
console.error(`${
|
|
28622
|
+
console.error(`${TAG45} op=destinations account=${accountId.slice(0, 8)} outcome=house-unresolved reason="${message}"`);
|
|
28530
28623
|
}
|
|
28531
28624
|
const destinations = listDispatchDestinations({ accountsDir: ACCOUNTS_DIR, houseAccountId, accountId });
|
|
28532
28625
|
const houseDir = houseAccountId === null ? null : resolve38(ACCOUNTS_DIR, houseAccountId);
|
|
@@ -28577,11 +28670,11 @@ app64.get("/", requireAdminSession, async (c) => {
|
|
|
28577
28670
|
const scopes = [...byScope.keys()];
|
|
28578
28671
|
const nameScope = scopes.length === 0 ? "none" : scopes.every((s) => s === houseAccountId) ? "house" : scopes.some((s) => s === houseAccountId) ? "mixed" : "account";
|
|
28579
28672
|
console.log(
|
|
28580
|
-
`${
|
|
28673
|
+
`${TAG45} op=destinations account=${accountId.slice(0, 8)} count=${destinations.length} named=${named} unnamed=${destinations.length - named} nameScope=${nameScope}` + (houseAccountId === null ? " outcome=house-unresolved" : "") + (namesUnresolved === null ? "" : ` outcome=names-unresolved reason="${namesUnresolved}"`)
|
|
28581
28674
|
);
|
|
28582
28675
|
return c.json({ destinations });
|
|
28583
28676
|
});
|
|
28584
|
-
var dispatch_destinations_default =
|
|
28677
|
+
var dispatch_destinations_default = app65;
|
|
28585
28678
|
|
|
28586
28679
|
// server/routes/admin/activity.ts
|
|
28587
28680
|
init_dist();
|
|
@@ -28591,8 +28684,8 @@ init_account();
|
|
|
28591
28684
|
import { readdirSync as readdirSync28 } from "fs";
|
|
28592
28685
|
init_neo4j_store();
|
|
28593
28686
|
init_loop_registry();
|
|
28594
|
-
var
|
|
28595
|
-
var
|
|
28687
|
+
var app66 = new Hono();
|
|
28688
|
+
var TAG46 = "[activity]";
|
|
28596
28689
|
function resolveHouseAccountId2(accounts) {
|
|
28597
28690
|
const houses = accounts.filter((a) => a.config.role === "house");
|
|
28598
28691
|
if (houses.length === 1) return { accountId: houses[0].accountId, reason: "house" };
|
|
@@ -28613,7 +28706,7 @@ function countAccountDirsOnDisk() {
|
|
|
28613
28706
|
return null;
|
|
28614
28707
|
}
|
|
28615
28708
|
}
|
|
28616
|
-
|
|
28709
|
+
app66.get("/", requireAdminSession, async (c) => {
|
|
28617
28710
|
const req = requestToken();
|
|
28618
28711
|
const cacheKey = c.var.cacheKey;
|
|
28619
28712
|
const caller2 = getAccountIdForSession(cacheKey) ?? null;
|
|
@@ -28621,19 +28714,19 @@ app65.get("/", requireAdminSession, async (c) => {
|
|
|
28621
28714
|
const house = resolveHouseAccountId2(valid);
|
|
28622
28715
|
const isHouse = caller2 !== null && house.accountId !== null && caller2 === house.accountId;
|
|
28623
28716
|
console.log(
|
|
28624
|
-
`${
|
|
28717
|
+
`${TAG46} op=request req=${req} caller=${short(caller2)} house=${isHouse} houseVia=${house.reason}`
|
|
28625
28718
|
);
|
|
28626
28719
|
if (!isHouse) {
|
|
28627
28720
|
const reason = house.accountId === null ? house.reason : "not-house";
|
|
28628
28721
|
console.error(
|
|
28629
|
-
`${
|
|
28722
|
+
`${TAG46} op=gate req=${req} decision=deny reason=${reason} caller=${short(caller2)} houseAcct=${short(house.accountId)} accounts=${valid.length}`
|
|
28630
28723
|
);
|
|
28631
28724
|
return c.json({ error: "house-only" }, 403);
|
|
28632
28725
|
}
|
|
28633
|
-
console.log(`${
|
|
28726
|
+
console.log(`${TAG46} op=gate req=${req} decision=allow caller=${short(caller2)} via=${house.reason}`);
|
|
28634
28727
|
const onDisk = countAccountDirsOnDisk();
|
|
28635
28728
|
console.log(
|
|
28636
|
-
`${
|
|
28729
|
+
`${TAG46} op=accounts req=${req} onDisk=${onDisk ?? "unknown"} valid=${valid.length} ids=${valid.map((a) => short(a.accountId)).join(",")}`
|
|
28637
28730
|
);
|
|
28638
28731
|
const start = Date.now();
|
|
28639
28732
|
let res;
|
|
@@ -28649,17 +28742,17 @@ app65.get("/", requireAdminSession, async (c) => {
|
|
|
28649
28742
|
});
|
|
28650
28743
|
} catch (err) {
|
|
28651
28744
|
console.error(
|
|
28652
|
-
`${
|
|
28745
|
+
`${TAG46} op=manager-fail req=${req} reason=unreachable err=${err instanceof Error ? err.message : String(err)}`
|
|
28653
28746
|
);
|
|
28654
28747
|
return c.json({ error: "manager-unreachable" }, 502);
|
|
28655
28748
|
}
|
|
28656
28749
|
if (res.status !== 200) {
|
|
28657
|
-
console.error(`${
|
|
28750
|
+
console.error(`${TAG46} op=manager-fail req=${req} reason=status status=${res.status}`);
|
|
28658
28751
|
return c.json({ error: `manager-status-${res.status}` }, 502);
|
|
28659
28752
|
}
|
|
28660
28753
|
const body = await res.json().catch(() => null);
|
|
28661
28754
|
if (!body || !Array.isArray(body.rows)) {
|
|
28662
|
-
console.error(`${
|
|
28755
|
+
console.error(`${TAG46} op=manager-fail req=${req} reason=bad-json`);
|
|
28663
28756
|
return c.json({ error: "manager-bad-json" }, 502);
|
|
28664
28757
|
}
|
|
28665
28758
|
const rows = body.rows;
|
|
@@ -28670,10 +28763,10 @@ app65.get("/", requireAdminSession, async (c) => {
|
|
|
28670
28763
|
const ageNull = rows.filter((r) => r.ageMs === null).length;
|
|
28671
28764
|
const sidecarNull = rows.filter((r) => r.sidecarMissing).length;
|
|
28672
28765
|
console.log(
|
|
28673
|
-
`${
|
|
28766
|
+
`${TAG46} op=census req=${req} ageMs=${censusAgeMs ?? "none"} live=${census?.live ?? "none"} cpuNull=${census?.cpuNull ?? "none"} rows=${rows.length} ageNull=${ageNull} sidecarNull=${sidecarNull}`
|
|
28674
28767
|
);
|
|
28675
28768
|
console.log(
|
|
28676
|
-
`${
|
|
28769
|
+
`${TAG46} op=response req=${req} rows=${rows.length} accounts=${valid.length} untagged=${untaggedCount} meteringFailed=${meteringFailed} ms=${Date.now() - start}`
|
|
28677
28770
|
);
|
|
28678
28771
|
const names = {};
|
|
28679
28772
|
await Promise.all(
|
|
@@ -28692,7 +28785,7 @@ app65.get("/", requireAdminSession, async (c) => {
|
|
|
28692
28785
|
return acc;
|
|
28693
28786
|
}, {});
|
|
28694
28787
|
console.log(
|
|
28695
|
-
`${
|
|
28788
|
+
`${TAG46} op=loops req=${req} armed=${armed2} rendered=${loopRows.length} procPct=${cpu.processPct?.toFixed(1) ?? "null"} attributedPct=${cpu.attributedPct?.toFixed(1) ?? "null"} ` + Object.entries(byState).map(([s, n]) => `${s}=${n}`).join(" ")
|
|
28696
28789
|
);
|
|
28697
28790
|
return c.json({
|
|
28698
28791
|
rows,
|
|
@@ -28722,74 +28815,75 @@ app65.get("/", requireAdminSession, async (c) => {
|
|
|
28722
28815
|
}
|
|
28723
28816
|
});
|
|
28724
28817
|
});
|
|
28725
|
-
var activity_default =
|
|
28818
|
+
var activity_default = app66;
|
|
28726
28819
|
|
|
28727
28820
|
// server/routes/admin/index.ts
|
|
28728
|
-
var
|
|
28729
|
-
|
|
28730
|
-
|
|
28731
|
-
|
|
28732
|
-
|
|
28733
|
-
|
|
28734
|
-
|
|
28735
|
-
|
|
28736
|
-
|
|
28737
|
-
|
|
28738
|
-
|
|
28739
|
-
|
|
28740
|
-
|
|
28741
|
-
|
|
28742
|
-
|
|
28743
|
-
|
|
28744
|
-
|
|
28745
|
-
|
|
28746
|
-
|
|
28747
|
-
|
|
28748
|
-
|
|
28749
|
-
|
|
28750
|
-
|
|
28751
|
-
|
|
28752
|
-
|
|
28753
|
-
|
|
28754
|
-
|
|
28755
|
-
|
|
28756
|
-
|
|
28757
|
-
|
|
28758
|
-
|
|
28759
|
-
|
|
28760
|
-
|
|
28761
|
-
|
|
28762
|
-
|
|
28763
|
-
|
|
28764
|
-
|
|
28765
|
-
|
|
28766
|
-
|
|
28767
|
-
|
|
28768
|
-
|
|
28769
|
-
|
|
28770
|
-
|
|
28771
|
-
|
|
28772
|
-
|
|
28773
|
-
|
|
28774
|
-
|
|
28775
|
-
|
|
28776
|
-
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
|
|
28780
|
-
|
|
28781
|
-
|
|
28821
|
+
var app67 = new Hono();
|
|
28822
|
+
app67.route("/session", session_default);
|
|
28823
|
+
app67.route("/accounts", accounts_default);
|
|
28824
|
+
app67.route("/logs", logs_default);
|
|
28825
|
+
app67.route("/claude-info", claude_info_default);
|
|
28826
|
+
app67.route("/attachment", attachment_default);
|
|
28827
|
+
app67.route("/session-upload", session_upload_default);
|
|
28828
|
+
app67.route("/agents", agents_default);
|
|
28829
|
+
app67.route("/sessions", sessions_default);
|
|
28830
|
+
app67.route("/claude-sessions", claude_sessions_default);
|
|
28831
|
+
app67.route("/log-ingest", log_ingest_default);
|
|
28832
|
+
app67.route("/session-blocked", session_blocked_default);
|
|
28833
|
+
app67.route("/events", events_default);
|
|
28834
|
+
app67.route("/files", files_default);
|
|
28835
|
+
app67.route("/graph-search", graph_search_default);
|
|
28836
|
+
app67.route("/graph-subgraph", graph_subgraph_default);
|
|
28837
|
+
app67.route("/graph-delete", graph_delete_default);
|
|
28838
|
+
app67.route("/graph-restore", graph_restore_default);
|
|
28839
|
+
app67.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
28840
|
+
app67.route("/graph-default-view", graph_default_view_default);
|
|
28841
|
+
app67.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
28842
|
+
app67.route("/sidebar-sessions", sidebar_sessions_default);
|
|
28843
|
+
app67.route("/session-delete", session_delete_default);
|
|
28844
|
+
app67.route("/session-stop", session_stop_default);
|
|
28845
|
+
app67.route("/session-archive", session_archive_default);
|
|
28846
|
+
app67.route("/session-rename", session_rename_default);
|
|
28847
|
+
app67.route("/session-usage", session_usage_default);
|
|
28848
|
+
app67.route("/browser", browser_default);
|
|
28849
|
+
app67.route("/session-rc-spawn", session_rc_spawn_default);
|
|
28850
|
+
app67.route("/session-reseat", session_reseat_default);
|
|
28851
|
+
app67.route("/system-stats", system_stats_default);
|
|
28852
|
+
app67.route("/health-brand", health_default2);
|
|
28853
|
+
app67.route("/linkedin-ingest", linkedin_ingest_default);
|
|
28854
|
+
app67.route("/post-turn-context", post_turn_context_default);
|
|
28855
|
+
app67.route("/public-session-context", public_session_context_default);
|
|
28856
|
+
app67.route("/public-session-exit", public_session_exit_default);
|
|
28857
|
+
app67.route("/access-session-evict", access_session_evict_default);
|
|
28858
|
+
app67.route("/enrol-person", enrol_person_default);
|
|
28859
|
+
app67.route("/calendar", calendar_default);
|
|
28860
|
+
app67.route("/data-portal", data_portal_default);
|
|
28861
|
+
app67.route("/routines", routines_default);
|
|
28862
|
+
app67.route("/skills", skills_default);
|
|
28863
|
+
app67.route("/tasks-list", tasks_list_default);
|
|
28864
|
+
app67.route("/task-timer-start", task_timer_start_default);
|
|
28865
|
+
app67.route("/task-timer-stop", task_timer_stop_default);
|
|
28866
|
+
app67.route("/task-complete", task_complete_default);
|
|
28867
|
+
app67.route("/task-time-adjust", task_time_adjust_default);
|
|
28868
|
+
app67.route("/task-delete", task_delete_default);
|
|
28869
|
+
app67.route("/task-assign", task_assign_default);
|
|
28870
|
+
app67.route("/task-session-open", task_session_open_default);
|
|
28871
|
+
app67.route("/task-session-link", task_session_link_default);
|
|
28872
|
+
app67.route("/admin-users-list", admin_users_list_default);
|
|
28873
|
+
app67.route("/dispatch-destinations", dispatch_destinations_default);
|
|
28874
|
+
app67.route("/activity", activity_default);
|
|
28875
|
+
var admin_default = app67;
|
|
28782
28876
|
|
|
28783
28877
|
// server/routes/access/index.ts
|
|
28784
28878
|
init_dist();
|
|
28785
28879
|
|
|
28786
28880
|
// server/routes/access/verify-token.ts
|
|
28787
28881
|
init_dist();
|
|
28788
|
-
var
|
|
28882
|
+
var TAG47 = "[access-verify]";
|
|
28789
28883
|
var MINT_TAG = "[access-session-mint]";
|
|
28790
28884
|
var COOKIE_NAME = "__access_session";
|
|
28791
|
-
var
|
|
28792
|
-
|
|
28885
|
+
var app68 = new Hono();
|
|
28886
|
+
app68.post("/", async (c) => {
|
|
28793
28887
|
const ip = c.var.clientIp || "unknown";
|
|
28794
28888
|
let body;
|
|
28795
28889
|
try {
|
|
@@ -28804,39 +28898,39 @@ app67.post("/", async (c) => {
|
|
|
28804
28898
|
}
|
|
28805
28899
|
const rateMsg = checkAccessRateLimit(ip, agentSlug);
|
|
28806
28900
|
if (rateMsg) {
|
|
28807
|
-
console.error(`${
|
|
28901
|
+
console.error(`${TAG47} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
|
|
28808
28902
|
return c.json({ error: rateMsg }, 429);
|
|
28809
28903
|
}
|
|
28810
28904
|
const grant = await findGrantByMagicToken(token);
|
|
28811
28905
|
if (!grant) {
|
|
28812
28906
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
28813
|
-
console.error(`${
|
|
28907
|
+
console.error(`${TAG47} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
|
|
28814
28908
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
28815
28909
|
}
|
|
28816
28910
|
if (grant.agentSlug !== agentSlug) {
|
|
28817
28911
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
28818
28912
|
console.error(
|
|
28819
|
-
`${
|
|
28913
|
+
`${TAG47} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
|
|
28820
28914
|
);
|
|
28821
28915
|
return c.json({ error: "invalid-or-expired-link" }, 401);
|
|
28822
28916
|
}
|
|
28823
28917
|
if (grant.status === "expired" || grant.status === "revoked") {
|
|
28824
28918
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
28825
28919
|
console.error(
|
|
28826
|
-
`${
|
|
28920
|
+
`${TAG47} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
|
|
28827
28921
|
);
|
|
28828
28922
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
28829
28923
|
}
|
|
28830
28924
|
if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
|
|
28831
28925
|
recordAccessFailedAttempt(ip, agentSlug);
|
|
28832
28926
|
console.error(
|
|
28833
|
-
`${
|
|
28927
|
+
`${TAG47} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
|
|
28834
28928
|
);
|
|
28835
28929
|
return c.json({ error: "access-no-longer-valid" }, 401);
|
|
28836
28930
|
}
|
|
28837
28931
|
if (!grant.sliceToken) {
|
|
28838
28932
|
console.error(
|
|
28839
|
-
`${
|
|
28933
|
+
`${TAG47} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
|
|
28840
28934
|
);
|
|
28841
28935
|
return c.json({ error: "grant-misconfigured" }, 500);
|
|
28842
28936
|
}
|
|
@@ -28852,12 +28946,12 @@ app67.post("/", async (c) => {
|
|
|
28852
28946
|
await consumeMagicTokenAndActivate(grant.grantId);
|
|
28853
28947
|
} catch (err) {
|
|
28854
28948
|
console.error(
|
|
28855
|
-
`${
|
|
28949
|
+
`${TAG47} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
28856
28950
|
);
|
|
28857
28951
|
return c.json({ error: "verification-failed" }, 500);
|
|
28858
28952
|
}
|
|
28859
28953
|
clearAccessRateLimit(ip, agentSlug);
|
|
28860
|
-
console.log(`${
|
|
28954
|
+
console.log(`${TAG47} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
|
|
28861
28955
|
console.log(
|
|
28862
28956
|
`${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
|
|
28863
28957
|
);
|
|
@@ -28871,7 +28965,7 @@ app67.post("/", async (c) => {
|
|
|
28871
28965
|
displayName: grant.displayName
|
|
28872
28966
|
});
|
|
28873
28967
|
});
|
|
28874
|
-
var verify_token_default =
|
|
28968
|
+
var verify_token_default = app68;
|
|
28875
28969
|
|
|
28876
28970
|
// server/routes/access/request-magic-link.ts
|
|
28877
28971
|
init_dist();
|
|
@@ -28936,10 +29030,10 @@ async function sendMagicLinkEmail(payload) {
|
|
|
28936
29030
|
}
|
|
28937
29031
|
|
|
28938
29032
|
// server/routes/access/request-magic-link.ts
|
|
28939
|
-
var
|
|
28940
|
-
var
|
|
29033
|
+
var TAG48 = "[access-request-link]";
|
|
29034
|
+
var app69 = new Hono();
|
|
28941
29035
|
var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
|
|
28942
|
-
|
|
29036
|
+
app69.post("/", async (c) => {
|
|
28943
29037
|
let body;
|
|
28944
29038
|
try {
|
|
28945
29039
|
body = await c.req.json();
|
|
@@ -28953,18 +29047,18 @@ app68.post("/", async (c) => {
|
|
|
28953
29047
|
}
|
|
28954
29048
|
const rateMsg = checkRequestLinkRateLimit(contactValue);
|
|
28955
29049
|
if (rateMsg) {
|
|
28956
|
-
console.error(`${
|
|
29050
|
+
console.error(`${TAG48} contactValue=${maskContact(contactValue)} result=rate-limited`);
|
|
28957
29051
|
return c.json({ error: rateMsg }, 429);
|
|
28958
29052
|
}
|
|
28959
29053
|
recordRequestLinkAttempt(contactValue);
|
|
28960
29054
|
const accountId = process.env.ACCOUNT_ID ?? "";
|
|
28961
29055
|
if (!accountId) {
|
|
28962
|
-
console.error(`${
|
|
29056
|
+
console.error(`${TAG48} contactValue=${maskContact(contactValue)} result=no-account-id`);
|
|
28963
29057
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
28964
29058
|
}
|
|
28965
29059
|
const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
|
|
28966
29060
|
if (!grant) {
|
|
28967
|
-
console.log(`${
|
|
29061
|
+
console.log(`${TAG48} contactValue=${maskContact(contactValue)} result=notfound`);
|
|
28968
29062
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
28969
29063
|
}
|
|
28970
29064
|
let token;
|
|
@@ -28972,7 +29066,7 @@ app68.post("/", async (c) => {
|
|
|
28972
29066
|
token = await generateNewMagicToken(grant.grantId);
|
|
28973
29067
|
} catch (err) {
|
|
28974
29068
|
console.error(
|
|
28975
|
-
`${
|
|
29069
|
+
`${TAG48} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
|
|
28976
29070
|
);
|
|
28977
29071
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
28978
29072
|
}
|
|
@@ -29004,22 +29098,22 @@ app68.post("/", async (c) => {
|
|
|
29004
29098
|
});
|
|
29005
29099
|
if (!sendResult.ok) {
|
|
29006
29100
|
console.error(
|
|
29007
|
-
`${
|
|
29101
|
+
`${TAG48} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
|
|
29008
29102
|
);
|
|
29009
29103
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
29010
29104
|
}
|
|
29011
29105
|
console.log(
|
|
29012
|
-
`${
|
|
29106
|
+
`${TAG48} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
|
|
29013
29107
|
);
|
|
29014
29108
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
29015
29109
|
});
|
|
29016
|
-
var request_magic_link_default =
|
|
29110
|
+
var request_magic_link_default = app69;
|
|
29017
29111
|
|
|
29018
29112
|
// server/routes/access/index.ts
|
|
29019
|
-
var
|
|
29020
|
-
|
|
29021
|
-
|
|
29022
|
-
var access_default =
|
|
29113
|
+
var app70 = new Hono();
|
|
29114
|
+
app70.route("/verify-token", verify_token_default);
|
|
29115
|
+
app70.route("/request-magic-link", request_magic_link_default);
|
|
29116
|
+
var access_default = app70;
|
|
29023
29117
|
|
|
29024
29118
|
// server/routes/sites.ts
|
|
29025
29119
|
init_dist();
|
|
@@ -29056,8 +29150,8 @@ function getExt(p) {
|
|
|
29056
29150
|
if (idx < p.lastIndexOf("/")) return "";
|
|
29057
29151
|
return p.slice(idx).toLowerCase();
|
|
29058
29152
|
}
|
|
29059
|
-
var
|
|
29060
|
-
|
|
29153
|
+
var app71 = new Hono();
|
|
29154
|
+
app71.get("/:rel{.*}", (c) => {
|
|
29061
29155
|
const reqPath = c.req.path;
|
|
29062
29156
|
const rawRel = c.req.param("rel") ?? "";
|
|
29063
29157
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -29160,7 +29254,7 @@ app70.get("/:rel{.*}", (c) => {
|
|
|
29160
29254
|
"X-Content-Type-Options": "nosniff"
|
|
29161
29255
|
});
|
|
29162
29256
|
});
|
|
29163
|
-
var sites_default =
|
|
29257
|
+
var sites_default = app71;
|
|
29164
29258
|
|
|
29165
29259
|
// server/routes/listings.ts
|
|
29166
29260
|
init_dist();
|
|
@@ -29250,7 +29344,7 @@ init_dist();
|
|
|
29250
29344
|
|
|
29251
29345
|
// app/lib/brand-config.ts
|
|
29252
29346
|
import { existsSync as existsSync45, readFileSync as readFileSync46 } from "fs";
|
|
29253
|
-
import { join as
|
|
29347
|
+
import { join as join51 } from "path";
|
|
29254
29348
|
var cached2 = null;
|
|
29255
29349
|
var cachedAttempted = false;
|
|
29256
29350
|
function readBrandConfig() {
|
|
@@ -29258,7 +29352,7 @@ function readBrandConfig() {
|
|
|
29258
29352
|
cachedAttempted = true;
|
|
29259
29353
|
const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
|
|
29260
29354
|
if (!platformRoot5) return null;
|
|
29261
|
-
const brandPath =
|
|
29355
|
+
const brandPath = join51(platformRoot5, "config", "brand.json");
|
|
29262
29356
|
if (!existsSync45(brandPath)) return null;
|
|
29263
29357
|
try {
|
|
29264
29358
|
cached2 = JSON.parse(readFileSync46(brandPath, "utf-8"));
|
|
@@ -29269,7 +29363,7 @@ function readBrandConfig() {
|
|
|
29269
29363
|
}
|
|
29270
29364
|
|
|
29271
29365
|
// server/routes/visitor-consent.ts
|
|
29272
|
-
var
|
|
29366
|
+
var app72 = new Hono();
|
|
29273
29367
|
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
29274
29368
|
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
29275
29369
|
var DEFAULT_CONSENT_COPY = {
|
|
@@ -29314,17 +29408,17 @@ function siteSlugFromReferer(referer) {
|
|
|
29314
29408
|
return "";
|
|
29315
29409
|
}
|
|
29316
29410
|
}
|
|
29317
|
-
|
|
29411
|
+
app72.options("/consent", (c) => {
|
|
29318
29412
|
const origin = getOrigin(c);
|
|
29319
29413
|
setCorsHeaders(c, origin);
|
|
29320
29414
|
return c.body(null, 204);
|
|
29321
29415
|
});
|
|
29322
|
-
|
|
29416
|
+
app72.options("/brand-config", (c) => {
|
|
29323
29417
|
const origin = getOrigin(c);
|
|
29324
29418
|
setCorsHeaders(c, origin);
|
|
29325
29419
|
return c.body(null, 204);
|
|
29326
29420
|
});
|
|
29327
|
-
|
|
29421
|
+
app72.post("/consent", async (c) => {
|
|
29328
29422
|
const origin = getOrigin(c);
|
|
29329
29423
|
setCorsHeaders(c, origin);
|
|
29330
29424
|
let raw;
|
|
@@ -29364,7 +29458,7 @@ app71.post("/consent", async (c) => {
|
|
|
29364
29458
|
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
29365
29459
|
return c.body(null, 204);
|
|
29366
29460
|
});
|
|
29367
|
-
|
|
29461
|
+
app72.get("/brand-config", (c) => {
|
|
29368
29462
|
const origin = getOrigin(c);
|
|
29369
29463
|
setCorsHeaders(c, origin);
|
|
29370
29464
|
const brand = readBrandConfig();
|
|
@@ -29374,7 +29468,7 @@ app71.get("/brand-config", (c) => {
|
|
|
29374
29468
|
c.header("Cache-Control", "public, max-age=300");
|
|
29375
29469
|
return c.json({ consent: { copy, palette } });
|
|
29376
29470
|
});
|
|
29377
|
-
var visitor_consent_default =
|
|
29471
|
+
var visitor_consent_default = app72;
|
|
29378
29472
|
|
|
29379
29473
|
// server/routes/listings.ts
|
|
29380
29474
|
function getCookie(headerValue, name) {
|
|
@@ -29401,8 +29495,8 @@ function appendConsentParams(pageUrl, token) {
|
|
|
29401
29495
|
}
|
|
29402
29496
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
29403
29497
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
29404
|
-
var
|
|
29405
|
-
|
|
29498
|
+
var app73 = new Hono();
|
|
29499
|
+
app73.get("/:slug/click", async (c) => {
|
|
29406
29500
|
const slug = c.req.param("slug") ?? "";
|
|
29407
29501
|
const rawSession = c.req.query("session") ?? "";
|
|
29408
29502
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -29466,14 +29560,14 @@ app72.get("/:slug/click", async (c) => {
|
|
|
29466
29560
|
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
29467
29561
|
return c.redirect(redirectUrl, 302);
|
|
29468
29562
|
});
|
|
29469
|
-
var listings_default =
|
|
29563
|
+
var listings_default = app73;
|
|
29470
29564
|
|
|
29471
29565
|
// server/routes/visitor-event.ts
|
|
29472
29566
|
init_dist();
|
|
29473
29567
|
init_claude_agent();
|
|
29474
29568
|
init_neo4j_store();
|
|
29475
29569
|
init_loop_registry();
|
|
29476
|
-
var
|
|
29570
|
+
var app74 = new Hono();
|
|
29477
29571
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
29478
29572
|
var buckets = /* @__PURE__ */ new Map();
|
|
29479
29573
|
var RATE_LIMIT = 60;
|
|
@@ -29549,12 +29643,12 @@ function originAllowed(origin, allowlist) {
|
|
|
29549
29643
|
return false;
|
|
29550
29644
|
}
|
|
29551
29645
|
}
|
|
29552
|
-
|
|
29646
|
+
app74.options("/event", (c) => {
|
|
29553
29647
|
const origin = getOrigin2(c);
|
|
29554
29648
|
setCorsHeaders2(c, origin);
|
|
29555
29649
|
return c.body(null, 204);
|
|
29556
29650
|
});
|
|
29557
|
-
|
|
29651
|
+
app74.post("/event", async (c) => {
|
|
29558
29652
|
const origin = getOrigin2(c);
|
|
29559
29653
|
setCorsHeaders2(c, origin);
|
|
29560
29654
|
const ua = c.req.header("user-agent") ?? "";
|
|
@@ -29759,7 +29853,7 @@ async function writeEvent(opts) {
|
|
|
29759
29853
|
);
|
|
29760
29854
|
}
|
|
29761
29855
|
}
|
|
29762
|
-
var visitor_event_default =
|
|
29856
|
+
var visitor_event_default = app74;
|
|
29763
29857
|
|
|
29764
29858
|
// server/routes/session.ts
|
|
29765
29859
|
init_dist();
|
|
@@ -29809,8 +29903,8 @@ function withVisitorCookie(response, visitorId) {
|
|
|
29809
29903
|
headers
|
|
29810
29904
|
});
|
|
29811
29905
|
}
|
|
29812
|
-
var
|
|
29813
|
-
|
|
29906
|
+
var app75 = new Hono();
|
|
29907
|
+
app75.post("/", async (c) => {
|
|
29814
29908
|
let body;
|
|
29815
29909
|
try {
|
|
29816
29910
|
body = await c.req.json();
|
|
@@ -29961,23 +30055,23 @@ app74.post("/", async (c) => {
|
|
|
29961
30055
|
newVisitorId
|
|
29962
30056
|
);
|
|
29963
30057
|
});
|
|
29964
|
-
var session_default2 =
|
|
30058
|
+
var session_default2 = app75;
|
|
29965
30059
|
|
|
29966
30060
|
// server/routes/calendar-public.ts
|
|
29967
30061
|
init_dist();
|
|
29968
30062
|
init_claude_agent();
|
|
29969
30063
|
init_neo4j_store();
|
|
29970
|
-
var
|
|
30064
|
+
var app76 = new Hono();
|
|
29971
30065
|
function setCors(c) {
|
|
29972
30066
|
c.header("Access-Control-Allow-Origin", "*");
|
|
29973
30067
|
c.header("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
29974
30068
|
c.header("Access-Control-Allow-Headers", "content-type");
|
|
29975
30069
|
}
|
|
29976
|
-
|
|
30070
|
+
app76.options("/free-busy", (c) => {
|
|
29977
30071
|
setCors(c);
|
|
29978
30072
|
return c.body(null, 204);
|
|
29979
30073
|
});
|
|
29980
|
-
|
|
30074
|
+
app76.get("/free-busy", async (c) => {
|
|
29981
30075
|
setCors(c);
|
|
29982
30076
|
const from = c.req.query("from");
|
|
29983
30077
|
const to = c.req.query("to");
|
|
@@ -30033,18 +30127,18 @@ app75.get("/free-busy", async (c) => {
|
|
|
30033
30127
|
await session.close();
|
|
30034
30128
|
}
|
|
30035
30129
|
});
|
|
30036
|
-
var calendar_public_default =
|
|
30130
|
+
var calendar_public_default = app76;
|
|
30037
30131
|
|
|
30038
30132
|
// server/routes/portal-fetch.ts
|
|
30039
30133
|
init_dist();
|
|
30040
30134
|
import { createReadStream as createReadStream3 } from "fs";
|
|
30041
30135
|
import { stat as stat8, readFile as readFile11, realpath } from "fs/promises";
|
|
30042
|
-
import { join as
|
|
30136
|
+
import { join as join52, resolve as resolve42, sep as sep11 } from "path";
|
|
30043
30137
|
import { Readable as Readable3 } from "stream";
|
|
30044
30138
|
init_data_path();
|
|
30045
30139
|
init_attachments();
|
|
30046
|
-
var
|
|
30047
|
-
var
|
|
30140
|
+
var app77 = new Hono();
|
|
30141
|
+
var TAG49 = "[portal-fetch]";
|
|
30048
30142
|
async function verifySignature(secret, accountId, relPath, expiresAtMs, signature, nowMs) {
|
|
30049
30143
|
if (!secret || !signature) return false;
|
|
30050
30144
|
if (!Number.isFinite(expiresAtMs) || expiresAtMs <= nowMs) return false;
|
|
@@ -30099,14 +30193,14 @@ async function readAccountSecret(accountId) {
|
|
|
30099
30193
|
try {
|
|
30100
30194
|
text = await readFile11(path, "utf8");
|
|
30101
30195
|
} catch {
|
|
30102
|
-
console.error(`${
|
|
30196
|
+
console.error(`${TAG49} op=no-secret account="${accountId}" path="${path}"`);
|
|
30103
30197
|
return "";
|
|
30104
30198
|
}
|
|
30105
30199
|
for (const line of text.split("\n")) {
|
|
30106
30200
|
const m = line.match(/^PORTAL_FETCH_SECRET=(.*)$/);
|
|
30107
30201
|
if (m) return m[1].trim();
|
|
30108
30202
|
}
|
|
30109
|
-
console.error(`${
|
|
30203
|
+
console.error(`${TAG49} op=no-secret account="${accountId}" reason=key-absent path="${path}"`);
|
|
30110
30204
|
return "";
|
|
30111
30205
|
}
|
|
30112
30206
|
function isValidAccountId2(value) {
|
|
@@ -30114,7 +30208,7 @@ function isValidAccountId2(value) {
|
|
|
30114
30208
|
}
|
|
30115
30209
|
async function readExposeFolders2(accountDir) {
|
|
30116
30210
|
try {
|
|
30117
|
-
const cfg = JSON.parse(await readFile11(
|
|
30211
|
+
const cfg = JSON.parse(await readFile11(join52(accountDir, "data-portal.json"), "utf8"));
|
|
30118
30212
|
return Array.isArray(cfg?.exposeFolders) ? cfg.exposeFolders.filter((f) => typeof f === "string") : [];
|
|
30119
30213
|
} catch {
|
|
30120
30214
|
return [];
|
|
@@ -30123,7 +30217,7 @@ async function readExposeFolders2(accountDir) {
|
|
|
30123
30217
|
async function resolveFetchTarget(accountDir, relPath, ownerId) {
|
|
30124
30218
|
let schemaText = null;
|
|
30125
30219
|
try {
|
|
30126
|
-
schemaText = await readFile11(
|
|
30220
|
+
schemaText = await readFile11(join52(accountDir, "SCHEMA.md"), "utf8");
|
|
30127
30221
|
} catch {
|
|
30128
30222
|
schemaText = null;
|
|
30129
30223
|
}
|
|
@@ -30166,16 +30260,16 @@ async function handle(c, headOnly) {
|
|
|
30166
30260
|
const sig = c.req.query("sig") ?? "";
|
|
30167
30261
|
const owner = c.req.query("owner") ?? "";
|
|
30168
30262
|
console.log(
|
|
30169
|
-
`${
|
|
30263
|
+
`${TAG49} op=request account=${q(accountId)} path=${q(relPath)} owner=${q(owner)} head=${headOnly}`
|
|
30170
30264
|
);
|
|
30171
30265
|
if (!isValidAccountId2(accountId)) {
|
|
30172
|
-
console.error(`${
|
|
30266
|
+
console.error(`${TAG49} op=denied account=${q(accountId)} reason=account-id`);
|
|
30173
30267
|
return c.json({ ok: false, error: "denied" }, 401);
|
|
30174
30268
|
}
|
|
30175
30269
|
const secret = await readAccountSecret(accountId);
|
|
30176
30270
|
const verified = owner ? await verifyOwnUploadSignature(secret, accountId, owner, relPath, exp, sig, Date.now()) : await verifySignature(secret, accountId, relPath, exp, sig, Date.now());
|
|
30177
30271
|
if (!verified) {
|
|
30178
|
-
console.error(`${
|
|
30272
|
+
console.error(`${TAG49} op=denied account=${q(accountId)} reason=secret`);
|
|
30179
30273
|
return c.json({ ok: false, error: "denied" }, 401);
|
|
30180
30274
|
}
|
|
30181
30275
|
const target = await resolveFetchTarget(
|
|
@@ -30185,14 +30279,14 @@ async function handle(c, headOnly) {
|
|
|
30185
30279
|
);
|
|
30186
30280
|
if (!target.ok) {
|
|
30187
30281
|
const op = target.reason === "enoent" ? "miss" : "denied";
|
|
30188
|
-
console.error(`${
|
|
30282
|
+
console.error(`${TAG49} op=${op} account=${accountId} reason=${target.reason}`);
|
|
30189
30283
|
return c.json({ ok: false, error: "not found" }, 404);
|
|
30190
30284
|
}
|
|
30191
30285
|
if (headOnly) {
|
|
30192
|
-
console.log(`${
|
|
30286
|
+
console.log(`${TAG49} op=served account=${accountId} bytes=${target.sizeBytes} head=true`);
|
|
30193
30287
|
return c.body(null, 200);
|
|
30194
30288
|
}
|
|
30195
|
-
console.log(`${
|
|
30289
|
+
console.log(`${TAG49} op=served account=${accountId} bytes=${target.sizeBytes}`);
|
|
30196
30290
|
return new Response(Readable3.toWeb(createReadStream3(target.absolute)), {
|
|
30197
30291
|
status: 200,
|
|
30198
30292
|
headers: {
|
|
@@ -30206,16 +30300,16 @@ async function handle(c, headOnly) {
|
|
|
30206
30300
|
}
|
|
30207
30301
|
});
|
|
30208
30302
|
}
|
|
30209
|
-
|
|
30210
|
-
|
|
30211
|
-
var portal_fetch_default =
|
|
30303
|
+
app77.get("/fetch", (c) => handle(c, false));
|
|
30304
|
+
app77.on("HEAD", "/fetch", (c) => handle(c, true));
|
|
30305
|
+
var portal_fetch_default = app77;
|
|
30212
30306
|
|
|
30213
30307
|
// server/index.ts
|
|
30214
30308
|
init_remote_auth();
|
|
30215
30309
|
|
|
30216
30310
|
// app/lib/timeentry-census.ts
|
|
30217
30311
|
init_loop_registry();
|
|
30218
|
-
var
|
|
30312
|
+
var TAG50 = "[timeentry-census]";
|
|
30219
30313
|
function reconcileTimeEntries(rows, now, horizonMs) {
|
|
30220
30314
|
const openEntries = rows.openEntries.length;
|
|
30221
30315
|
let oldestOpenAgeMs = 0;
|
|
@@ -30255,12 +30349,12 @@ async function runTimeEntryCensusOnce(session, now, horizonMs) {
|
|
|
30255
30349
|
sumAdjustments: toNum(r.get("sumAdjustments"))
|
|
30256
30350
|
}));
|
|
30257
30351
|
const finding = reconcileTimeEntries({ openEntries, taskSums }, now, horizonMs);
|
|
30258
|
-
const line = `${
|
|
30352
|
+
const line = `${TAG50} openEntries=${finding.openEntries} oldestOpenAgeMin=${finding.oldestOpenAgeMin} maxOpenPerAccount=${finding.maxOpenPerAccount} driftTasks=${finding.driftTasks}`;
|
|
30259
30353
|
if (finding.alarm) console.error(`${line} alarm=true`);
|
|
30260
30354
|
else console.log(line);
|
|
30261
30355
|
return finding;
|
|
30262
30356
|
} catch (err) {
|
|
30263
|
-
console.error(`${
|
|
30357
|
+
console.error(`${TAG50} error="${err instanceof Error ? err.message : String(err)}"`);
|
|
30264
30358
|
return null;
|
|
30265
30359
|
}
|
|
30266
30360
|
}
|
|
@@ -30274,13 +30368,13 @@ function startTimeEntryCensus(openSession, opts = {}) {
|
|
|
30274
30368
|
try {
|
|
30275
30369
|
session = openSession();
|
|
30276
30370
|
} catch (err) {
|
|
30277
|
-
console.error(`${
|
|
30371
|
+
console.error(`${TAG50} open-session-failed error="${err instanceof Error ? err.message : String(err)}"`);
|
|
30278
30372
|
return;
|
|
30279
30373
|
}
|
|
30280
30374
|
try {
|
|
30281
30375
|
await runTimeEntryCensusOnce(session, Date.now(), horizonMs);
|
|
30282
30376
|
} catch (err) {
|
|
30283
|
-
console.error(`${
|
|
30377
|
+
console.error(`${TAG50} tick-failed error="${err instanceof Error ? err.message : String(err)}"`);
|
|
30284
30378
|
} finally {
|
|
30285
30379
|
try {
|
|
30286
30380
|
await session.close();
|
|
@@ -30302,7 +30396,7 @@ init_neo4j_store();
|
|
|
30302
30396
|
// app/lib/ledger-census.ts
|
|
30303
30397
|
init_loop_registry();
|
|
30304
30398
|
import { readdirSync as readdirSync29, readFileSync as readFileSync47, statSync as statSync26 } from "fs";
|
|
30305
|
-
import { join as
|
|
30399
|
+
import { join as join53 } from "path";
|
|
30306
30400
|
|
|
30307
30401
|
// ../lib/ledger-core/dist/reconcile.js
|
|
30308
30402
|
var LEDGER_INDEX_NAMES = [
|
|
@@ -30345,7 +30439,7 @@ function formatCensusLine(f) {
|
|
|
30345
30439
|
}
|
|
30346
30440
|
|
|
30347
30441
|
// app/lib/ledger-census.ts
|
|
30348
|
-
var
|
|
30442
|
+
var TAG51 = "[ledger-census]";
|
|
30349
30443
|
var DAY_MS = 864e5;
|
|
30350
30444
|
function countWriteRejects24h(logDir, now) {
|
|
30351
30445
|
let entries2;
|
|
@@ -30356,7 +30450,7 @@ function countWriteRejects24h(logDir, now) {
|
|
|
30356
30450
|
}
|
|
30357
30451
|
let total = 0;
|
|
30358
30452
|
for (const name of entries2) {
|
|
30359
|
-
const path =
|
|
30453
|
+
const path = join53(logDir, name);
|
|
30360
30454
|
try {
|
|
30361
30455
|
if (now - statSync26(path).mtimeMs > DAY_MS) continue;
|
|
30362
30456
|
for (const line of readFileSync47(path, "utf8").split("\n")) {
|
|
@@ -30421,7 +30515,7 @@ async function runLedgerCensusOnce(session, now) {
|
|
|
30421
30515
|
else console.log(line);
|
|
30422
30516
|
return finding;
|
|
30423
30517
|
} catch (err) {
|
|
30424
|
-
console.error(`${
|
|
30518
|
+
console.error(`${TAG51} error="${err instanceof Error ? err.message : String(err)}"`);
|
|
30425
30519
|
return null;
|
|
30426
30520
|
}
|
|
30427
30521
|
}
|
|
@@ -30434,7 +30528,7 @@ function startLedgerCensus(openSession, opts = {}) {
|
|
|
30434
30528
|
session = openSession();
|
|
30435
30529
|
} catch (err) {
|
|
30436
30530
|
console.error(
|
|
30437
|
-
`${
|
|
30531
|
+
`${TAG51} open-session-failed error="${err instanceof Error ? err.message : String(err)}"`
|
|
30438
30532
|
);
|
|
30439
30533
|
return;
|
|
30440
30534
|
}
|
|
@@ -30442,7 +30536,7 @@ function startLedgerCensus(openSession, opts = {}) {
|
|
|
30442
30536
|
await runLedgerCensusOnce(session, Date.now());
|
|
30443
30537
|
} catch (err) {
|
|
30444
30538
|
console.error(
|
|
30445
|
-
`${
|
|
30539
|
+
`${TAG51} tick-failed error="${err instanceof Error ? err.message : String(err)}"`
|
|
30446
30540
|
);
|
|
30447
30541
|
} finally {
|
|
30448
30542
|
try {
|
|
@@ -30465,7 +30559,7 @@ init_neo4j_store();
|
|
|
30465
30559
|
|
|
30466
30560
|
// app/lib/conversation-audit.ts
|
|
30467
30561
|
init_neo4j_store();
|
|
30468
|
-
var
|
|
30562
|
+
var TAG52 = "[conversation-audit]";
|
|
30469
30563
|
async function runConversationAudit() {
|
|
30470
30564
|
const session = getSession();
|
|
30471
30565
|
try {
|
|
@@ -30502,12 +30596,12 @@ async function runConversationAudit() {
|
|
|
30502
30596
|
multiAnchored: Number(multiRec?.get("multiAnchored") ?? 0)
|
|
30503
30597
|
};
|
|
30504
30598
|
console.error(
|
|
30505
|
-
`${
|
|
30599
|
+
`${TAG52} channel=whatsapp total=${result.total} senders=${result.senders} multiAnchored=${result.multiAnchored} unreconciled=${result.unreconciled} unpairable=${result.unpairable}`
|
|
30506
30600
|
);
|
|
30507
30601
|
return result;
|
|
30508
30602
|
} catch (err) {
|
|
30509
30603
|
const reason = err instanceof Error ? `${err.name}:${err.message.slice(0, 200)}` : String(err).slice(0, 200);
|
|
30510
|
-
console.error(`${
|
|
30604
|
+
console.error(`${TAG52} op=failed reason=${reason}`);
|
|
30511
30605
|
return null;
|
|
30512
30606
|
} finally {
|
|
30513
30607
|
await session.close();
|
|
@@ -30642,8 +30736,8 @@ init_loop_registry();
|
|
|
30642
30736
|
init_data_path();
|
|
30643
30737
|
var import_dist9 = __toESM(require_dist(), 1);
|
|
30644
30738
|
import { existsSync as existsSync47, statSync as statSync27, readdirSync as readdirSync30 } from "fs";
|
|
30645
|
-
import { join as
|
|
30646
|
-
var
|
|
30739
|
+
import { join as join54 } from "path";
|
|
30740
|
+
var TAG53 = "[shared-census]";
|
|
30647
30741
|
var WIRED_SURFACES = 3;
|
|
30648
30742
|
function countFiles(dir) {
|
|
30649
30743
|
let n = 0;
|
|
@@ -30654,7 +30748,7 @@ function countFiles(dir) {
|
|
|
30654
30748
|
return 0;
|
|
30655
30749
|
}
|
|
30656
30750
|
for (const e of entries2) {
|
|
30657
|
-
if (e.isDirectory()) n += countFiles(
|
|
30751
|
+
if (e.isDirectory()) n += countFiles(join54(dir, e.name));
|
|
30658
30752
|
else if (e.isFile()) n++;
|
|
30659
30753
|
}
|
|
30660
30754
|
return n;
|
|
@@ -30671,8 +30765,8 @@ function runSharedFolderCensus(dataRoot = DATA_ROOT) {
|
|
|
30671
30765
|
}
|
|
30672
30766
|
}
|
|
30673
30767
|
const files = isDir ? countFiles(root) : 0;
|
|
30674
|
-
console.error(`${
|
|
30675
|
-
console.error(`${
|
|
30768
|
+
console.error(`${TAG53} op=root exists=${exists} isDir=${isDir} files=${files}`);
|
|
30769
|
+
console.error(`${TAG53} op=wiring surfaces=${WIRED_SURFACES}/3`);
|
|
30676
30770
|
return `shared root ${exists ? "present" : "ABSENT"}, ${files} file(s)`;
|
|
30677
30771
|
}
|
|
30678
30772
|
function startSharedFolderCensus() {
|
|
@@ -30921,7 +31015,7 @@ init_account();
|
|
|
30921
31015
|
init_neo4j_store();
|
|
30922
31016
|
import { readdir as readdir7, readFile as readFile12, rename as rename5, writeFile as writeFile4, unlink as unlink4 } from "fs/promises";
|
|
30923
31017
|
import { existsSync as existsSync48 } from "fs";
|
|
30924
|
-
import { join as
|
|
31018
|
+
import { join as join55 } from "path";
|
|
30925
31019
|
var ADMIN_ROLE2 = "admin";
|
|
30926
31020
|
var WEBCHAT_CHANNEL2 = "webchat";
|
|
30927
31021
|
var SESSION_META_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
|
|
@@ -30966,7 +31060,7 @@ async function collectLiveSidecars(projectsRoot) {
|
|
|
30966
31060
|
}
|
|
30967
31061
|
for (const slug of slugs) {
|
|
30968
31062
|
if (!slug.isDirectory()) continue;
|
|
30969
|
-
const slugDir =
|
|
31063
|
+
const slugDir = join55(projectsRoot, slug.name);
|
|
30970
31064
|
let entries2;
|
|
30971
31065
|
try {
|
|
30972
31066
|
entries2 = await readdir7(slugDir, { withFileTypes: true });
|
|
@@ -30975,9 +31069,9 @@ async function collectLiveSidecars(projectsRoot) {
|
|
|
30975
31069
|
}
|
|
30976
31070
|
for (const entry of entries2) {
|
|
30977
31071
|
if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
|
|
30978
|
-
out.push(
|
|
31072
|
+
out.push(join55(slugDir, entry.name));
|
|
30979
31073
|
} else if (entry.isDirectory() && entry.name === "subagents") {
|
|
30980
|
-
const subDir =
|
|
31074
|
+
const subDir = join55(slugDir, entry.name);
|
|
30981
31075
|
let subs;
|
|
30982
31076
|
try {
|
|
30983
31077
|
subs = await readdir7(subDir, { withFileTypes: true });
|
|
@@ -30985,7 +31079,7 @@ async function collectLiveSidecars(projectsRoot) {
|
|
|
30985
31079
|
continue;
|
|
30986
31080
|
}
|
|
30987
31081
|
for (const s of subs) {
|
|
30988
|
-
if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(
|
|
31082
|
+
if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join55(subDir, s.name));
|
|
30989
31083
|
}
|
|
30990
31084
|
}
|
|
30991
31085
|
}
|
|
@@ -30997,7 +31091,7 @@ function shortId(path) {
|
|
|
30997
31091
|
return base.slice(0, 8);
|
|
30998
31092
|
}
|
|
30999
31093
|
async function migrateAdminWebchatSidecars(opts = {}) {
|
|
31000
|
-
const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ?
|
|
31094
|
+
const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join55(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
|
|
31001
31095
|
const usersFile = opts.usersFile ?? USERS_FILE;
|
|
31002
31096
|
const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
|
|
31003
31097
|
const resolveName = opts.resolveName ?? defaultResolveName;
|
|
@@ -31075,7 +31169,7 @@ async function migrateAdminWebchatSidecars(opts = {}) {
|
|
|
31075
31169
|
init_account();
|
|
31076
31170
|
import { readdir as readdir8, readFile as readFile13, rename as rename6, writeFile as writeFile5, unlink as unlink5 } from "fs/promises";
|
|
31077
31171
|
import { existsSync as existsSync49 } from "fs";
|
|
31078
|
-
import { join as
|
|
31172
|
+
import { join as join56 } from "path";
|
|
31079
31173
|
var SESSION_META_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
|
|
31080
31174
|
function projectSlugForCwd(cwd) {
|
|
31081
31175
|
return cwd.replace(/\//g, "-");
|
|
@@ -31121,7 +31215,7 @@ async function collectSidecars(projectsRoot) {
|
|
|
31121
31215
|
}
|
|
31122
31216
|
for (const slug of slugs) {
|
|
31123
31217
|
if (!slug.isDirectory()) continue;
|
|
31124
|
-
const slugDir =
|
|
31218
|
+
const slugDir = join56(projectsRoot, slug.name);
|
|
31125
31219
|
let entries2;
|
|
31126
31220
|
try {
|
|
31127
31221
|
entries2 = await readdir8(slugDir, { withFileTypes: true });
|
|
@@ -31130,9 +31224,9 @@ async function collectSidecars(projectsRoot) {
|
|
|
31130
31224
|
}
|
|
31131
31225
|
for (const entry of entries2) {
|
|
31132
31226
|
if (entry.isFile() && SESSION_META_RE2.test(entry.name)) {
|
|
31133
|
-
out.push({ path:
|
|
31227
|
+
out.push({ path: join56(slugDir, entry.name), slug: slug.name });
|
|
31134
31228
|
} else if (entry.isDirectory() && (entry.name === "subagents" || entry.name === "archive")) {
|
|
31135
|
-
const subDir =
|
|
31229
|
+
const subDir = join56(slugDir, entry.name);
|
|
31136
31230
|
let subs;
|
|
31137
31231
|
try {
|
|
31138
31232
|
subs = await readdir8(subDir, { withFileTypes: true });
|
|
@@ -31141,7 +31235,7 @@ async function collectSidecars(projectsRoot) {
|
|
|
31141
31235
|
}
|
|
31142
31236
|
for (const s of subs) {
|
|
31143
31237
|
if (s.isFile() && SESSION_META_RE2.test(s.name)) {
|
|
31144
|
-
out.push({ path:
|
|
31238
|
+
out.push({ path: join56(subDir, s.name), slug: slug.name });
|
|
31145
31239
|
}
|
|
31146
31240
|
}
|
|
31147
31241
|
}
|
|
@@ -31150,7 +31244,7 @@ async function collectSidecars(projectsRoot) {
|
|
|
31150
31244
|
return out;
|
|
31151
31245
|
}
|
|
31152
31246
|
async function migrateSidecarAccountIds(opts = {}) {
|
|
31153
|
-
const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ?
|
|
31247
|
+
const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join56(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
|
|
31154
31248
|
const accounts = opts.accounts ?? listValidAccounts();
|
|
31155
31249
|
const result = {
|
|
31156
31250
|
scanned: 0,
|
|
@@ -31617,8 +31711,8 @@ function runDeliveryCensus(now) {
|
|
|
31617
31711
|
// app/lib/whatsapp/gateway/routes.ts
|
|
31618
31712
|
var PARTY_PHONE_PATTERN = /^[+0-9][0-9 ()\-.]{4,31}$/;
|
|
31619
31713
|
function createWaChannelRoutes(deps) {
|
|
31620
|
-
const
|
|
31621
|
-
|
|
31714
|
+
const app79 = new Hono();
|
|
31715
|
+
app79.get("/wa-channel/inbound", (c) => {
|
|
31622
31716
|
const senderId = c.req.query("senderId");
|
|
31623
31717
|
const accountId = c.req.query("accountId");
|
|
31624
31718
|
if (!senderId) return c.json({ error: "senderId required" }, 400);
|
|
@@ -31641,7 +31735,7 @@ function createWaChannelRoutes(deps) {
|
|
|
31641
31735
|
}
|
|
31642
31736
|
});
|
|
31643
31737
|
});
|
|
31644
|
-
|
|
31738
|
+
app79.post("/wa-channel/ready", async (c) => {
|
|
31645
31739
|
const body = await c.req.json().catch(() => null);
|
|
31646
31740
|
const senderId = body?.senderId;
|
|
31647
31741
|
const accountId = body?.accountId;
|
|
@@ -31655,7 +31749,7 @@ function createWaChannelRoutes(deps) {
|
|
|
31655
31749
|
deps.onReady?.(accountId, senderId);
|
|
31656
31750
|
return c.json({ ok: true });
|
|
31657
31751
|
});
|
|
31658
|
-
|
|
31752
|
+
app79.post("/wa-channel/received", async (c) => {
|
|
31659
31753
|
const body = await c.req.json().catch(() => null);
|
|
31660
31754
|
const senderId = body?.senderId;
|
|
31661
31755
|
const accountId = body?.accountId;
|
|
@@ -31672,7 +31766,7 @@ function createWaChannelRoutes(deps) {
|
|
|
31672
31766
|
deps.onReceived?.(accountId, senderId, waMessageId, { provenance, source });
|
|
31673
31767
|
return c.json({ ok: true });
|
|
31674
31768
|
});
|
|
31675
|
-
|
|
31769
|
+
app79.post("/wa-channel/turn-observed", async (c) => {
|
|
31676
31770
|
const body = await c.req.json().catch(() => null);
|
|
31677
31771
|
const senderId = body?.senderId;
|
|
31678
31772
|
const accountId = body?.accountId;
|
|
@@ -31688,7 +31782,7 @@ function createWaChannelRoutes(deps) {
|
|
|
31688
31782
|
deps.onTurnObserved?.(accountId, senderId, waMessageId, observed);
|
|
31689
31783
|
return c.json({ ok: true });
|
|
31690
31784
|
});
|
|
31691
|
-
|
|
31785
|
+
app79.post("/wa-channel/turn-end", async (c) => {
|
|
31692
31786
|
const body = await c.req.json().catch(() => null);
|
|
31693
31787
|
const senderId = body?.senderId;
|
|
31694
31788
|
const sessionId = body?.sessionId;
|
|
@@ -31770,7 +31864,7 @@ function createWaChannelRoutes(deps) {
|
|
|
31770
31864
|
noteTurnEnd("whatsapp", role, "record", Date.now());
|
|
31771
31865
|
return c.json({ ok: true, delivered: "record", segments: segments.length, reached, notReached });
|
|
31772
31866
|
});
|
|
31773
|
-
|
|
31867
|
+
app79.post("/wa-channel/send-party", async (c) => {
|
|
31774
31868
|
const body = await c.req.json().catch(() => null);
|
|
31775
31869
|
const senderId = body?.senderId;
|
|
31776
31870
|
const accountId = body?.accountId;
|
|
@@ -31822,7 +31916,7 @@ function createWaChannelRoutes(deps) {
|
|
|
31822
31916
|
log2("sent", party.party);
|
|
31823
31917
|
return c.json({ ok: true });
|
|
31824
31918
|
});
|
|
31825
|
-
return
|
|
31919
|
+
return app79;
|
|
31826
31920
|
}
|
|
31827
31921
|
|
|
31828
31922
|
// app/lib/whatsapp/gateway/wa-gateway.ts
|
|
@@ -32574,8 +32668,8 @@ var InboundHub2 = class {
|
|
|
32574
32668
|
// app/lib/webchat/gateway/routes.ts
|
|
32575
32669
|
init_dist();
|
|
32576
32670
|
function createWebchatChannelRoutes(deps) {
|
|
32577
|
-
const
|
|
32578
|
-
|
|
32671
|
+
const app79 = new Hono();
|
|
32672
|
+
app79.get("/webchat-channel/inbound", (c) => {
|
|
32579
32673
|
const key2 = c.req.query("key");
|
|
32580
32674
|
if (!key2) return c.json({ error: "key required" }, 400);
|
|
32581
32675
|
const role = c.req.query("role");
|
|
@@ -32600,7 +32694,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
32600
32694
|
}
|
|
32601
32695
|
});
|
|
32602
32696
|
});
|
|
32603
|
-
|
|
32697
|
+
app79.post("/webchat-channel/connector-auth", async (c) => {
|
|
32604
32698
|
const body = await c.req.json().catch(() => null);
|
|
32605
32699
|
const key2 = body?.key;
|
|
32606
32700
|
const sessionId = body?.sessionId;
|
|
@@ -32613,7 +32707,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
32613
32707
|
const result = await deps.onConnectorAuth({ key: key2, sessionId, name, completed });
|
|
32614
32708
|
return c.json(result);
|
|
32615
32709
|
});
|
|
32616
|
-
|
|
32710
|
+
app79.post("/webchat-channel/ready", async (c) => {
|
|
32617
32711
|
const body = await c.req.json().catch(() => null);
|
|
32618
32712
|
const key2 = body?.key;
|
|
32619
32713
|
if (typeof key2 !== "string") {
|
|
@@ -32622,7 +32716,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
32622
32716
|
deps.onReady?.(key2);
|
|
32623
32717
|
return c.json({ ok: true });
|
|
32624
32718
|
});
|
|
32625
|
-
|
|
32719
|
+
app79.post("/webchat-channel/permission-request", async (c) => {
|
|
32626
32720
|
const body = await c.req.json().catch(() => null);
|
|
32627
32721
|
const key2 = body?.key;
|
|
32628
32722
|
const requestId = body?.request_id;
|
|
@@ -32636,7 +32730,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
32636
32730
|
const verdict = await deps.awaitPermissionVerdict({ key: key2, requestId, toolName, description, inputPreview });
|
|
32637
32731
|
return c.json(verdict);
|
|
32638
32732
|
});
|
|
32639
|
-
|
|
32733
|
+
app79.post("/webchat-channel/received", async (c) => {
|
|
32640
32734
|
const body = await c.req.json().catch(() => null);
|
|
32641
32735
|
const key2 = body?.key;
|
|
32642
32736
|
const messageId = body?.messageId;
|
|
@@ -32646,7 +32740,7 @@ function createWebchatChannelRoutes(deps) {
|
|
|
32646
32740
|
deps.onReceived?.(key2, messageId);
|
|
32647
32741
|
return c.json({ ok: true });
|
|
32648
32742
|
});
|
|
32649
|
-
|
|
32743
|
+
app79.post("/webchat-channel/turn-end", async (c) => {
|
|
32650
32744
|
const body = await c.req.json().catch(() => null);
|
|
32651
32745
|
const key2 = body?.key;
|
|
32652
32746
|
const sessionId = body?.sessionId;
|
|
@@ -32671,12 +32765,12 @@ function createWebchatChannelRoutes(deps) {
|
|
|
32671
32765
|
}
|
|
32672
32766
|
return c.json({ ok: true });
|
|
32673
32767
|
});
|
|
32674
|
-
return
|
|
32768
|
+
return app79;
|
|
32675
32769
|
}
|
|
32676
32770
|
|
|
32677
32771
|
// app/lib/webchat/gateway/resolve-turn-answer.ts
|
|
32678
32772
|
import { existsSync as existsSync50, openSync as openSync9, readSync as readSync8, closeSync as closeSync9, readdirSync as readdirSync31 } from "fs";
|
|
32679
|
-
import { join as
|
|
32773
|
+
import { join as join57 } from "path";
|
|
32680
32774
|
function resolveTurnAnswer(p) {
|
|
32681
32775
|
if (!SESSION_ID_RE2.test(p.sessionId)) return "";
|
|
32682
32776
|
const path = findJsonl(p.projectsRoot, p.sessionId);
|
|
@@ -32712,7 +32806,7 @@ function findJsonl(projectsRoot, sessionId) {
|
|
|
32712
32806
|
return null;
|
|
32713
32807
|
}
|
|
32714
32808
|
for (const slug of slugs) {
|
|
32715
|
-
const live =
|
|
32809
|
+
const live = join57(projectsRoot, slug, `${sessionId}.jsonl`);
|
|
32716
32810
|
if (existsSync50(live)) return live;
|
|
32717
32811
|
}
|
|
32718
32812
|
return null;
|
|
@@ -33510,14 +33604,14 @@ function makeFileDelivery(opts) {
|
|
|
33510
33604
|
}
|
|
33511
33605
|
|
|
33512
33606
|
// app/lib/webchat/file-delivery.ts
|
|
33513
|
-
var
|
|
33607
|
+
var TAG54 = "[webchat-adaptor]";
|
|
33514
33608
|
function platformRoot2() {
|
|
33515
33609
|
return process.env.MAXY_PLATFORM_ROOT || "";
|
|
33516
33610
|
}
|
|
33517
33611
|
function makeWebchatSendFile(entry) {
|
|
33518
33612
|
return async (filePath) => {
|
|
33519
33613
|
if (!entry.accountId) {
|
|
33520
|
-
console.error(`${
|
|
33614
|
+
console.error(`${TAG54} file-delivery reject reason=no-account sender=${entry.senderId}`);
|
|
33521
33615
|
return { ok: false, error: "no-account" };
|
|
33522
33616
|
}
|
|
33523
33617
|
const accountDir = resolve45(platformRoot2(), "..", "data/accounts", entry.accountId);
|
|
@@ -33525,14 +33619,14 @@ function makeWebchatSendFile(entry) {
|
|
|
33525
33619
|
const resolved = realpathSync9(filePath);
|
|
33526
33620
|
const accountResolved = realpathSync9(accountDir);
|
|
33527
33621
|
if (!resolved.startsWith(accountResolved + "/")) {
|
|
33528
|
-
console.error(`${
|
|
33622
|
+
console.error(`${TAG54} file-delivery reject reason=outside_account_directory sender=${entry.senderId}`);
|
|
33529
33623
|
return { ok: false, error: "outside-account" };
|
|
33530
33624
|
}
|
|
33531
33625
|
return { ok: true };
|
|
33532
33626
|
} catch (err) {
|
|
33533
33627
|
const code = err.code;
|
|
33534
33628
|
console.error(
|
|
33535
|
-
`${
|
|
33629
|
+
`${TAG54} file-delivery reject reason=${code === "ENOENT" ? "not-found" : "path-error"} sender=${entry.senderId}`
|
|
33536
33630
|
);
|
|
33537
33631
|
return { ok: false, error: code === "ENOENT" ? "not-found" : "path-error" };
|
|
33538
33632
|
}
|
|
@@ -33541,7 +33635,7 @@ function makeWebchatSendFile(entry) {
|
|
|
33541
33635
|
function makeWebchatFileDelivery(entry) {
|
|
33542
33636
|
return makeFileDelivery({
|
|
33543
33637
|
entry,
|
|
33544
|
-
tag:
|
|
33638
|
+
tag: TAG54,
|
|
33545
33639
|
channel: "webchat",
|
|
33546
33640
|
sendFile: makeWebchatSendFile(entry),
|
|
33547
33641
|
deferUntilVerdict: true
|
|
@@ -33605,7 +33699,7 @@ function buildPublicWebchatSpawnRequest(input) {
|
|
|
33605
33699
|
}
|
|
33606
33700
|
|
|
33607
33701
|
// app/lib/whatsapp/inbound/file-delivery-bridge.ts
|
|
33608
|
-
var
|
|
33702
|
+
var TAG55 = "[whatsapp-adaptor]";
|
|
33609
33703
|
var SEND_USER_FILE2 = "SendUserFile";
|
|
33610
33704
|
var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
|
|
33611
33705
|
function platformRoot3() {
|
|
@@ -33623,7 +33717,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
|
|
|
33623
33717
|
});
|
|
33624
33718
|
if (result.ok) return { ok: true };
|
|
33625
33719
|
console.error(
|
|
33626
|
-
`${
|
|
33720
|
+
`${TAG55} file-delivery reject reason=send-failed sender=${entry.senderId} status=${result.status} message=${result.error}`
|
|
33627
33721
|
);
|
|
33628
33722
|
return { ok: false, error: result.error };
|
|
33629
33723
|
};
|
|
@@ -33631,7 +33725,7 @@ function makeWhatsAppSendFile(entry, maxyAccountId) {
|
|
|
33631
33725
|
function makeWhatsAppFileDelivery(entry, maxyAccountId) {
|
|
33632
33726
|
const shared = makeFileDelivery({
|
|
33633
33727
|
entry,
|
|
33634
|
-
tag:
|
|
33728
|
+
tag: TAG55,
|
|
33635
33729
|
channel: "whatsapp",
|
|
33636
33730
|
sendFile: makeWhatsAppSendFile(entry, maxyAccountId)
|
|
33637
33731
|
});
|
|
@@ -33666,7 +33760,7 @@ function makeWhatsAppFileDelivery(entry, maxyAccountId) {
|
|
|
33666
33760
|
if (!delivered) {
|
|
33667
33761
|
const fileField = call.filePath !== void 0 ? ` file=${call.filePath}` : "";
|
|
33668
33762
|
console.error(
|
|
33669
|
-
`${
|
|
33763
|
+
`${TAG55} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
|
|
33670
33764
|
);
|
|
33671
33765
|
}
|
|
33672
33766
|
}
|
|
@@ -33855,8 +33949,8 @@ var InboundHub3 = class {
|
|
|
33855
33949
|
// app/lib/telegram/gateway/routes.ts
|
|
33856
33950
|
init_dist();
|
|
33857
33951
|
function createTelegramChannelRoutes(deps) {
|
|
33858
|
-
const
|
|
33859
|
-
|
|
33952
|
+
const app79 = new Hono();
|
|
33953
|
+
app79.get("/tg-channel/inbound", (c) => {
|
|
33860
33954
|
const key2 = c.req.query("key");
|
|
33861
33955
|
if (!key2) return c.json({ error: "key required" }, 400);
|
|
33862
33956
|
return streamSSE(c, async (stream2) => {
|
|
@@ -33874,7 +33968,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
33874
33968
|
}
|
|
33875
33969
|
});
|
|
33876
33970
|
});
|
|
33877
|
-
|
|
33971
|
+
app79.post("/tg-channel/ready", async (c) => {
|
|
33878
33972
|
const body = await c.req.json().catch(() => null);
|
|
33879
33973
|
const key2 = body?.key;
|
|
33880
33974
|
if (typeof key2 !== "string") {
|
|
@@ -33883,7 +33977,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
33883
33977
|
deps.onReady?.(key2);
|
|
33884
33978
|
return c.json({ ok: true });
|
|
33885
33979
|
});
|
|
33886
|
-
|
|
33980
|
+
app79.post("/tg-channel/received", async (c) => {
|
|
33887
33981
|
const body = await c.req.json().catch(() => null);
|
|
33888
33982
|
const key2 = body?.key;
|
|
33889
33983
|
const messageId = body?.messageId;
|
|
@@ -33893,7 +33987,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
33893
33987
|
deps.onReceived?.(key2, messageId);
|
|
33894
33988
|
return c.json({ ok: true });
|
|
33895
33989
|
});
|
|
33896
|
-
|
|
33990
|
+
app79.post("/tg-channel/turn-end", async (c) => {
|
|
33897
33991
|
const body = await c.req.json().catch(() => null);
|
|
33898
33992
|
const key2 = body?.key;
|
|
33899
33993
|
const sessionId = body?.sessionId;
|
|
@@ -33964,7 +34058,7 @@ function createTelegramChannelRoutes(deps) {
|
|
|
33964
34058
|
noteTurnEnd("telegram", role, "record", Date.now());
|
|
33965
34059
|
return c.json({ ok: true, delivered: "record", segments: segments.length, reached, notReached });
|
|
33966
34060
|
});
|
|
33967
|
-
return
|
|
34061
|
+
return app79;
|
|
33968
34062
|
}
|
|
33969
34063
|
|
|
33970
34064
|
// app/lib/telegram/gateway/telegram-gateway.ts
|
|
@@ -34268,7 +34362,7 @@ function buildTelegramSpawnRequest(input) {
|
|
|
34268
34362
|
}
|
|
34269
34363
|
|
|
34270
34364
|
// server/telegram-ensure-session.ts
|
|
34271
|
-
var
|
|
34365
|
+
var TAG56 = "[telegram-inbound]";
|
|
34272
34366
|
function buildTelegramEnsureSession(deps) {
|
|
34273
34367
|
return async (input) => {
|
|
34274
34368
|
const req = buildTelegramSpawnRequest({
|
|
@@ -34302,10 +34396,10 @@ function buildTelegramEnsureSession(deps) {
|
|
|
34302
34396
|
return;
|
|
34303
34397
|
}
|
|
34304
34398
|
console.error(
|
|
34305
|
-
`${
|
|
34399
|
+
`${TAG56} op=telegram-spawn-door botId=${input.botId} role=public door=rc agent=${input.agentSlug}`
|
|
34306
34400
|
);
|
|
34307
34401
|
console.error(
|
|
34308
|
-
`${
|
|
34402
|
+
`${TAG56} op=spawn botId=${input.botId} sessionId=${result2.sessionId} targetAccountId=${input.accountId} role=public`
|
|
34309
34403
|
);
|
|
34310
34404
|
noteSpawnOk2(input.botId);
|
|
34311
34405
|
return;
|
|
@@ -34319,7 +34413,7 @@ function buildTelegramEnsureSession(deps) {
|
|
|
34319
34413
|
return;
|
|
34320
34414
|
}
|
|
34321
34415
|
console.error(
|
|
34322
|
-
`${
|
|
34416
|
+
`${TAG56} op=spawn botId=${input.botId} sessionId=${req.sessionId} targetAccountId=${input.accountId} role=admin`
|
|
34323
34417
|
);
|
|
34324
34418
|
noteSpawnOk2(input.botId);
|
|
34325
34419
|
deps.followers.get(req.channelKey)?.abort();
|
|
@@ -34345,7 +34439,7 @@ init_attachments();
|
|
|
34345
34439
|
import { realpathSync as realpathSync10 } from "fs";
|
|
34346
34440
|
import { readFile as readFile14, stat as stat10 } from "fs/promises";
|
|
34347
34441
|
import { resolve as resolve46, basename as basename16 } from "path";
|
|
34348
|
-
var
|
|
34442
|
+
var TAG57 = "[telegram:outbound]";
|
|
34349
34443
|
var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
|
|
34350
34444
|
async function sendTelegramDocument(input) {
|
|
34351
34445
|
const { botToken, chatId, filePath, caption, maxyAccountId, platformRoot: platformRoot5 } = input;
|
|
@@ -34362,10 +34456,10 @@ async function sendTelegramDocument(input) {
|
|
|
34362
34456
|
} catch (err) {
|
|
34363
34457
|
const code = err.code;
|
|
34364
34458
|
if (code === "ENOENT") {
|
|
34365
|
-
console.error(`${
|
|
34459
|
+
console.error(`${TAG57} document ENOENT scope=account-dir accountDir=${accountDir} maxyAccountId=${maxyAccountId}`);
|
|
34366
34460
|
return { ok: false, status: 500, error: `Account directory not resolvable for ${maxyAccountId}` };
|
|
34367
34461
|
}
|
|
34368
|
-
console.error(`${
|
|
34462
|
+
console.error(`${TAG57} document path error scope=account-dir maxyAccountId=${maxyAccountId}: ${String(err)}`);
|
|
34369
34463
|
return { ok: false, status: 500, error: String(err) };
|
|
34370
34464
|
}
|
|
34371
34465
|
let resolvedPath;
|
|
@@ -34374,14 +34468,14 @@ async function sendTelegramDocument(input) {
|
|
|
34374
34468
|
} catch (err) {
|
|
34375
34469
|
const code = err.code;
|
|
34376
34470
|
if (code === "ENOENT") {
|
|
34377
|
-
console.error(`${
|
|
34471
|
+
console.error(`${TAG57} document ENOENT scope=file path=${filePath} maxyAccountId=${maxyAccountId}`);
|
|
34378
34472
|
return { ok: false, status: 404, error: `File not found: ${filePath}` };
|
|
34379
34473
|
}
|
|
34380
|
-
console.error(`${
|
|
34474
|
+
console.error(`${TAG57} document path error scope=file maxyAccountId=${maxyAccountId}: ${String(err)}`);
|
|
34381
34475
|
return { ok: false, status: 500, error: String(err) };
|
|
34382
34476
|
}
|
|
34383
34477
|
if (!resolvedPath.startsWith(accountResolved + "/")) {
|
|
34384
|
-
console.error(`${
|
|
34478
|
+
console.error(`${TAG57} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
|
|
34385
34479
|
return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
|
|
34386
34480
|
}
|
|
34387
34481
|
const fileStat = await stat10(resolvedPath);
|
|
@@ -34414,24 +34508,24 @@ async function sendTelegramDocument(input) {
|
|
|
34414
34508
|
error = e instanceof Error ? e.message : String(e);
|
|
34415
34509
|
}
|
|
34416
34510
|
console.error(
|
|
34417
|
-
`${
|
|
34511
|
+
`${TAG57} sent document to=${chatId} file=${filename} bytes=${fileStat.size} ok=${ok2}` + (messageId !== void 0 ? ` id=${messageId}` : "")
|
|
34418
34512
|
);
|
|
34419
34513
|
return ok2 ? { ok: true, messageId } : { ok: false, status: 500, error };
|
|
34420
34514
|
}
|
|
34421
34515
|
|
|
34422
34516
|
// app/lib/telegram/outbound/file-delivery.ts
|
|
34423
|
-
var
|
|
34517
|
+
var TAG58 = "[telegram:outbound]";
|
|
34424
34518
|
function platformRoot4() {
|
|
34425
34519
|
return process.env.MAXY_PLATFORM_ROOT || "";
|
|
34426
34520
|
}
|
|
34427
34521
|
function makeTelegramSendFile(entry, botToken) {
|
|
34428
34522
|
return async (filePath, caption) => {
|
|
34429
34523
|
if (!botToken) {
|
|
34430
|
-
console.error(`${
|
|
34524
|
+
console.error(`${TAG58} file-delivery reject reason=no-bot-token sender=${entry.senderId} role=${entry.role}`);
|
|
34431
34525
|
return { ok: false, error: "no-bot-token" };
|
|
34432
34526
|
}
|
|
34433
34527
|
if (entry.replyTarget == null) {
|
|
34434
|
-
console.error(`${
|
|
34528
|
+
console.error(`${TAG58} file-delivery reject reason=no-reply-target sender=${entry.senderId} role=${entry.role}`);
|
|
34435
34529
|
return { ok: false, error: "no-reply-target" };
|
|
34436
34530
|
}
|
|
34437
34531
|
const result = await sendTelegramDocument({
|
|
@@ -34448,7 +34542,7 @@ function makeTelegramSendFile(entry, botToken) {
|
|
|
34448
34542
|
function makeTelegramFileDelivery(entry, botToken) {
|
|
34449
34543
|
return makeFileDelivery({
|
|
34450
34544
|
entry,
|
|
34451
|
-
tag:
|
|
34545
|
+
tag: TAG58,
|
|
34452
34546
|
channel: "telegram",
|
|
34453
34547
|
sendFile: makeTelegramSendFile(entry, botToken)
|
|
34454
34548
|
});
|
|
@@ -34537,7 +34631,7 @@ init_webchat();
|
|
|
34537
34631
|
// app/lib/channel-pty-bridge/public-session-end-review.ts
|
|
34538
34632
|
init_src3();
|
|
34539
34633
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
34540
|
-
var
|
|
34634
|
+
var TAG59 = "[public-session-review]";
|
|
34541
34635
|
var CONSUMED_CAP = 500;
|
|
34542
34636
|
var consumed = /* @__PURE__ */ new Set();
|
|
34543
34637
|
function consumeOnce(sessionId) {
|
|
@@ -34564,7 +34658,7 @@ async function fetchJsonl(sessionId) {
|
|
|
34564
34658
|
return await res.text();
|
|
34565
34659
|
} catch (err) {
|
|
34566
34660
|
console.error(
|
|
34567
|
-
`${
|
|
34661
|
+
`${TAG59} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
|
|
34568
34662
|
);
|
|
34569
34663
|
return null;
|
|
34570
34664
|
}
|
|
@@ -34588,7 +34682,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
|
|
|
34588
34682
|
const res = await fetch(url);
|
|
34589
34683
|
if (!res.ok) {
|
|
34590
34684
|
console.error(
|
|
34591
|
-
`${
|
|
34685
|
+
`${TAG59} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
|
|
34592
34686
|
);
|
|
34593
34687
|
return [];
|
|
34594
34688
|
}
|
|
@@ -34596,7 +34690,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
|
|
|
34596
34690
|
return Array.isArray(body.writes) ? body.writes : [];
|
|
34597
34691
|
} catch (err) {
|
|
34598
34692
|
console.error(
|
|
34599
|
-
`${
|
|
34693
|
+
`${TAG59} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
|
|
34600
34694
|
);
|
|
34601
34695
|
return [];
|
|
34602
34696
|
}
|
|
@@ -34625,7 +34719,7 @@ function composeInitialMessage(input) {
|
|
|
34625
34719
|
}
|
|
34626
34720
|
async function dispatchReviewer(input, initialMessage) {
|
|
34627
34721
|
const sessionId = randomUUID14();
|
|
34628
|
-
console.log(`${
|
|
34722
|
+
console.log(`${TAG59} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
|
|
34629
34723
|
const spawned = await managerRcSpawn({
|
|
34630
34724
|
sessionId,
|
|
34631
34725
|
initialMessage,
|
|
@@ -34649,21 +34743,21 @@ async function firePublicSessionEndReview(input) {
|
|
|
34649
34743
|
const dispatchedAt = Date.now();
|
|
34650
34744
|
if (consumed.has(input.sessionId)) {
|
|
34651
34745
|
console.log(
|
|
34652
|
-
`${
|
|
34746
|
+
`${TAG59} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
|
|
34653
34747
|
);
|
|
34654
34748
|
return;
|
|
34655
34749
|
}
|
|
34656
34750
|
const jsonl = await fetchJsonl(input.sessionId);
|
|
34657
34751
|
if (!jsonl) {
|
|
34658
34752
|
console.log(
|
|
34659
|
-
`${
|
|
34753
|
+
`${TAG59} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
|
|
34660
34754
|
);
|
|
34661
34755
|
return;
|
|
34662
34756
|
}
|
|
34663
34757
|
const operatorTurns = countOperatorTurns(jsonl);
|
|
34664
34758
|
if (operatorTurns === 0) {
|
|
34665
34759
|
console.log(
|
|
34666
|
-
`${
|
|
34760
|
+
`${TAG59} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
|
|
34667
34761
|
);
|
|
34668
34762
|
return;
|
|
34669
34763
|
}
|
|
@@ -34677,19 +34771,19 @@ async function firePublicSessionEndReview(input) {
|
|
|
34677
34771
|
});
|
|
34678
34772
|
if (!consumeOnce(input.sessionId)) {
|
|
34679
34773
|
console.log(
|
|
34680
|
-
`${
|
|
34774
|
+
`${TAG59} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
|
|
34681
34775
|
);
|
|
34682
34776
|
return;
|
|
34683
34777
|
}
|
|
34684
34778
|
const dispatched = await dispatchReviewer(input, initialMessage);
|
|
34685
34779
|
if (!dispatched.ok) {
|
|
34686
34780
|
console.error(
|
|
34687
|
-
`${
|
|
34781
|
+
`${TAG59} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
|
|
34688
34782
|
);
|
|
34689
34783
|
return;
|
|
34690
34784
|
}
|
|
34691
34785
|
console.log(
|
|
34692
|
-
`${
|
|
34786
|
+
`${TAG59} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
|
|
34693
34787
|
);
|
|
34694
34788
|
}
|
|
34695
34789
|
|
|
@@ -34841,7 +34935,7 @@ init_account();
|
|
|
34841
34935
|
|
|
34842
34936
|
// server/telegram-audit.ts
|
|
34843
34937
|
import { statSync as statSync28 } from "fs";
|
|
34844
|
-
import { join as
|
|
34938
|
+
import { join as join58 } from "path";
|
|
34845
34939
|
init_channel_key();
|
|
34846
34940
|
init_sidebar_sessions();
|
|
34847
34941
|
function buildTelegramAuditLines(input) {
|
|
@@ -34907,7 +35001,7 @@ function countTelegramSessionsForAccount(accountId) {
|
|
|
34907
35001
|
function* walkTelegramSidecars() {
|
|
34908
35002
|
const cfg = claudeConfigDir();
|
|
34909
35003
|
if (!cfg) return;
|
|
34910
|
-
const projectsRoot =
|
|
35004
|
+
const projectsRoot = join58(cfg, "projects");
|
|
34911
35005
|
for (const { path } of enumerateSessionSidecars(projectsRoot)) {
|
|
34912
35006
|
const meta = readSidecarMeta(path);
|
|
34913
35007
|
if (meta.channel !== "telegram" || !meta.accountId) continue;
|
|
@@ -34934,11 +35028,11 @@ function* walkTelegramSidecars() {
|
|
|
34934
35028
|
|
|
34935
35029
|
// server/telegram-migrate.ts
|
|
34936
35030
|
import { readFileSync as readFileSync48, writeFileSync as writeFileSync19, existsSync as existsSync51, renameSync as renameSync11, mkdirSync as mkdirSync11 } from "fs";
|
|
34937
|
-
import { dirname as dirname18, join as
|
|
35031
|
+
import { dirname as dirname18, join as join59 } from "path";
|
|
34938
35032
|
function migrateTelegramTwoSlot(input) {
|
|
34939
35033
|
const out = [];
|
|
34940
35034
|
for (const account of input.accounts) {
|
|
34941
|
-
const configPath3 =
|
|
35035
|
+
const configPath3 = join59(account.accountDir, "account.json");
|
|
34942
35036
|
let config;
|
|
34943
35037
|
try {
|
|
34944
35038
|
config = JSON.parse(readFileSync48(configPath3, "utf-8"));
|
|
@@ -35335,7 +35429,7 @@ function clientFrom(c) {
|
|
|
35335
35429
|
}
|
|
35336
35430
|
installMediaDownloadGuard();
|
|
35337
35431
|
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
35338
|
-
var BRAND_JSON_PATH = PLATFORM_ROOT6 ?
|
|
35432
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT6 ? join60(PLATFORM_ROOT6, "config", "brand.json") : "";
|
|
35339
35433
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
|
|
35340
35434
|
if (BRAND_JSON_PATH && !existsSync54(BRAND_JSON_PATH)) {
|
|
35341
35435
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
@@ -35374,7 +35468,7 @@ var brandLoginOpts = {
|
|
|
35374
35468
|
appleTouchIconPath: brandAppIcon512Path,
|
|
35375
35469
|
themeColor: BRAND.defaultColors?.primary
|
|
35376
35470
|
};
|
|
35377
|
-
var ALIAS_DOMAINS_PATH =
|
|
35471
|
+
var ALIAS_DOMAINS_PATH = join60(homedir5(), BRAND.configDir, "alias-domains.json");
|
|
35378
35472
|
function loadAliasDomains() {
|
|
35379
35473
|
try {
|
|
35380
35474
|
if (!existsSync54(ALIAS_DOMAINS_PATH)) return null;
|
|
@@ -35404,7 +35498,7 @@ startManagerEventsSubscriber();
|
|
|
35404
35498
|
function isPublicHost(host) {
|
|
35405
35499
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
35406
35500
|
}
|
|
35407
|
-
var
|
|
35501
|
+
var app78 = new Hono();
|
|
35408
35502
|
function resolveChannelOverride(accountId, channel, senderId) {
|
|
35409
35503
|
try {
|
|
35410
35504
|
const dir = listValidAccounts().find((a) => a.accountId === accountId)?.accountDir;
|
|
@@ -35479,7 +35573,7 @@ var waGateway = new WaGateway({
|
|
|
35479
35573
|
deps: adminFanDeps("whatsapp", accountId)
|
|
35480
35574
|
}),
|
|
35481
35575
|
gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
|
|
35482
|
-
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve49(process.env.MAXY_PLATFORM_ROOT ??
|
|
35576
|
+
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve49(process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
|
|
35483
35577
|
// Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
|
|
35484
35578
|
// path-validation scope) is the sender's effective SESSION account, resolved
|
|
35485
35579
|
// once at the inbound gate and threaded here via the gateway's per-sender doc
|
|
@@ -35494,7 +35588,7 @@ var waGateway = new WaGateway({
|
|
|
35494
35588
|
caption,
|
|
35495
35589
|
accountId,
|
|
35496
35590
|
maxyAccountId,
|
|
35497
|
-
platformRoot: resolve49(process.env.MAXY_PLATFORM_ROOT ??
|
|
35591
|
+
platformRoot: resolve49(process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, ".."))
|
|
35498
35592
|
});
|
|
35499
35593
|
return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
|
|
35500
35594
|
},
|
|
@@ -35648,7 +35742,7 @@ var waGateway = new WaGateway({
|
|
|
35648
35742
|
nativeFileFollowers.set(senderId, ac);
|
|
35649
35743
|
}
|
|
35650
35744
|
});
|
|
35651
|
-
|
|
35745
|
+
app78.route("/", waGateway.routes());
|
|
35652
35746
|
waGateway.startSweeper();
|
|
35653
35747
|
registerLoop({
|
|
35654
35748
|
name: "whatsapp-link-census",
|
|
@@ -35661,7 +35755,7 @@ function runDuplicateSenderAudit() {
|
|
|
35661
35755
|
try {
|
|
35662
35756
|
const configDir = process.env.CLAUDE_CONFIG_DIR;
|
|
35663
35757
|
if (!configDir) return;
|
|
35664
|
-
const projectsRoot =
|
|
35758
|
+
const projectsRoot = join60(configDir, "projects");
|
|
35665
35759
|
const records2 = [];
|
|
35666
35760
|
for (const { path: jsonlPath, isSubagent, archived } of enumerateJsonls(projectsRoot)) {
|
|
35667
35761
|
if (isSubagent || archived) continue;
|
|
@@ -35713,7 +35807,7 @@ var webchatGateway = new WebchatGateway({
|
|
|
35713
35807
|
// rather than hanging the POST.
|
|
35714
35808
|
publicProjectsRoot: () => {
|
|
35715
35809
|
const cfg = claudeConfigDir();
|
|
35716
|
-
return cfg ?
|
|
35810
|
+
return cfg ? join60(cfg, "projects") : "";
|
|
35717
35811
|
},
|
|
35718
35812
|
gatewayUrl: webchatGatewayUrl(),
|
|
35719
35813
|
serverPath: webchatServerPath(),
|
|
@@ -35809,7 +35903,7 @@ var webchatGateway = new WebchatGateway({
|
|
|
35809
35903
|
firePublicSessionEndReview: (input) => firePublicSessionEndReview(input)
|
|
35810
35904
|
});
|
|
35811
35905
|
setWebchatGateway(webchatGateway);
|
|
35812
|
-
|
|
35906
|
+
app78.route("/", webchatGateway.routes());
|
|
35813
35907
|
webchatGateway.startSweeper();
|
|
35814
35908
|
webchatGateway.startPublicReaper();
|
|
35815
35909
|
var telegramFileFollowers = /* @__PURE__ */ new Map();
|
|
@@ -35856,7 +35950,7 @@ var telegramGateway = new TelegramGateway({
|
|
|
35856
35950
|
})
|
|
35857
35951
|
});
|
|
35858
35952
|
setTelegramGateway(telegramGateway);
|
|
35859
|
-
|
|
35953
|
+
app78.route("/", telegramGateway.routes());
|
|
35860
35954
|
telegramGateway.startSweeper();
|
|
35861
35955
|
var chatRoutes = createChatRoutes({
|
|
35862
35956
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
@@ -35925,19 +36019,19 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
|
|
|
35925
36019
|
// which is the split this task removes.
|
|
35926
36020
|
resolveTelegramAdminUserId: (accountId, chatId) => resolveTelegramAdminUserId({ accountId, chatId })
|
|
35927
36021
|
});
|
|
35928
|
-
|
|
35929
|
-
|
|
36022
|
+
app78.route("/api/channel/schedule-inject", scheduleInjectRoutes);
|
|
36023
|
+
app78.use("*", clientIpMiddleware);
|
|
35930
36024
|
function allowsSameOriginFraming(path) {
|
|
35931
36025
|
return path === "/vnc-viewer.html" || path.startsWith("/api/admin/attachment/") || path.startsWith("/api/public-reader/attachment/") || path === "/api/admin/files/download" || path === "/api/admin/session-upload";
|
|
35932
36026
|
}
|
|
35933
|
-
|
|
36027
|
+
app78.use("*", async (c, next) => {
|
|
35934
36028
|
await next();
|
|
35935
36029
|
c.header("X-Content-Type-Options", "nosniff");
|
|
35936
36030
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
35937
36031
|
c.header("X-Frame-Options", allowsSameOriginFraming(c.req.path) ? "SAMEORIGIN" : "DENY");
|
|
35938
36032
|
});
|
|
35939
36033
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
35940
|
-
|
|
36034
|
+
app78.use("*", async (c, next) => {
|
|
35941
36035
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
35942
36036
|
await next();
|
|
35943
36037
|
return;
|
|
@@ -35955,7 +36049,7 @@ app77.use("*", async (c, next) => {
|
|
|
35955
36049
|
});
|
|
35956
36050
|
}
|
|
35957
36051
|
});
|
|
35958
|
-
|
|
36052
|
+
app78.use("*", async (c, next) => {
|
|
35959
36053
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
35960
36054
|
if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
|
|
35961
36055
|
await next();
|
|
@@ -35993,7 +36087,7 @@ function resolveRemoteAuthOpts(c) {
|
|
|
35993
36087
|
return { ...brandLoginOpts, origin };
|
|
35994
36088
|
}
|
|
35995
36089
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
35996
|
-
|
|
36090
|
+
app78.post("/__remote-auth/login", async (c) => {
|
|
35997
36091
|
const client = clientFrom(c);
|
|
35998
36092
|
const clientIp = client.ip || "unknown";
|
|
35999
36093
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -36038,7 +36132,7 @@ app77.post("/__remote-auth/login", async (c) => {
|
|
|
36038
36132
|
}
|
|
36039
36133
|
});
|
|
36040
36134
|
});
|
|
36041
|
-
|
|
36135
|
+
app78.get("/__remote-auth/logout", (c) => {
|
|
36042
36136
|
const client = clientFrom(c);
|
|
36043
36137
|
const clientIp = client.ip || "unknown";
|
|
36044
36138
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -36051,7 +36145,7 @@ app77.get("/__remote-auth/logout", (c) => {
|
|
|
36051
36145
|
}
|
|
36052
36146
|
});
|
|
36053
36147
|
});
|
|
36054
|
-
|
|
36148
|
+
app78.post("/__remote-auth/change-password", async (c) => {
|
|
36055
36149
|
const client = clientFrom(c);
|
|
36056
36150
|
const clientIp = client.ip || "unknown";
|
|
36057
36151
|
const rateLimited = checkRateLimit(client);
|
|
@@ -36110,13 +36204,13 @@ app77.post("/__remote-auth/change-password", async (c) => {
|
|
|
36110
36204
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
36111
36205
|
}
|
|
36112
36206
|
});
|
|
36113
|
-
|
|
36207
|
+
app78.get("/__remote-auth/setup", (c) => {
|
|
36114
36208
|
if (isRemoteAuthConfigured()) {
|
|
36115
36209
|
return c.redirect("/");
|
|
36116
36210
|
}
|
|
36117
36211
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup" }), 200);
|
|
36118
36212
|
});
|
|
36119
|
-
|
|
36213
|
+
app78.post("/__remote-auth/set-initial-password", async (c) => {
|
|
36120
36214
|
if (isRemoteAuthConfigured()) {
|
|
36121
36215
|
return c.redirect("/");
|
|
36122
36216
|
}
|
|
@@ -36154,10 +36248,10 @@ app77.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
36154
36248
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
36155
36249
|
}
|
|
36156
36250
|
});
|
|
36157
|
-
|
|
36251
|
+
app78.get("/api/remote-auth/status", (c) => {
|
|
36158
36252
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
36159
36253
|
});
|
|
36160
|
-
|
|
36254
|
+
app78.post("/api/remote-auth/set-password", async (c) => {
|
|
36161
36255
|
let body;
|
|
36162
36256
|
try {
|
|
36163
36257
|
body = await c.req.json();
|
|
@@ -36196,9 +36290,9 @@ app77.post("/api/remote-auth/set-password", async (c) => {
|
|
|
36196
36290
|
return c.json({ error: "Failed to save password" }, 500);
|
|
36197
36291
|
}
|
|
36198
36292
|
});
|
|
36199
|
-
|
|
36293
|
+
app78.route("/api/_client-error", client_error_default);
|
|
36200
36294
|
console.log("[client-error-route] mounted");
|
|
36201
|
-
|
|
36295
|
+
app78.use("*", async (c, next) => {
|
|
36202
36296
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36203
36297
|
const path = c.req.path;
|
|
36204
36298
|
if (isRemoteAuthBypassPath(path)) {
|
|
@@ -36238,31 +36332,31 @@ app77.use("*", async (c, next) => {
|
|
|
36238
36332
|
}
|
|
36239
36333
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(c), redirect: path }), 200);
|
|
36240
36334
|
});
|
|
36241
|
-
|
|
36242
|
-
|
|
36243
|
-
|
|
36244
|
-
|
|
36245
|
-
|
|
36246
|
-
|
|
36247
|
-
|
|
36248
|
-
|
|
36249
|
-
|
|
36250
|
-
|
|
36335
|
+
app78.route("/api/health", health_default);
|
|
36336
|
+
app78.route("/api/chat", chatRoutes);
|
|
36337
|
+
app78.route("/api/whatsapp", whatsapp_default);
|
|
36338
|
+
app78.route("/api/storage", storage_broker_default);
|
|
36339
|
+
app78.route("/api/whatsapp-reader", whatsapp_reader_default);
|
|
36340
|
+
app78.route("/api/telegram-reader", telegram_reader_default);
|
|
36341
|
+
app78.route("/api/session-reader", session_reader_default);
|
|
36342
|
+
app78.route("/api/operator-conversations", operator_conversations_default);
|
|
36343
|
+
app78.route("/api/public-reader", public_reader_default);
|
|
36344
|
+
app78.route("/api/webchat", createWebchatRoutes({
|
|
36251
36345
|
handleInbound: (input) => webchatGateway.handleInbound(input),
|
|
36252
36346
|
// Task 940 — the permission relay's pointer read + verdict write.
|
|
36253
36347
|
pendingPromptFor: (key2) => webchatGateway.pendingPromptFor(key2),
|
|
36254
36348
|
deliveryFailureFor: (key2) => webchatGateway.deliveryFailureFor(key2),
|
|
36255
36349
|
resolvePermissionVerdict: (key2, requestId, behavior) => webchatGateway.resolvePermissionVerdict(key2, requestId, behavior)
|
|
36256
36350
|
}));
|
|
36257
|
-
|
|
36258
|
-
mountTelegramRoutes(
|
|
36259
|
-
|
|
36260
|
-
|
|
36261
|
-
|
|
36262
|
-
|
|
36263
|
-
|
|
36264
|
-
|
|
36265
|
-
|
|
36351
|
+
app78.route("/api/webchat/greeting", webchat_greeting_default);
|
|
36352
|
+
mountTelegramRoutes(app78, telegram_default);
|
|
36353
|
+
app78.route("/api/quickbooks", quickbooks_default);
|
|
36354
|
+
app78.route("/api/onboarding", onboarding_default);
|
|
36355
|
+
app78.route("/api/admin", admin_default);
|
|
36356
|
+
app78.route("/api/access", access_default);
|
|
36357
|
+
app78.route("/api/session", session_default2);
|
|
36358
|
+
app78.route("/api/calendar", calendar_public_default);
|
|
36359
|
+
app78.route("/api/portal", portal_fetch_default);
|
|
36266
36360
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
36267
36361
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
36268
36362
|
var IMAGE_MIME = {
|
|
@@ -36274,7 +36368,7 @@ var IMAGE_MIME = {
|
|
|
36274
36368
|
".svg": "image/svg+xml",
|
|
36275
36369
|
".ico": "image/x-icon"
|
|
36276
36370
|
};
|
|
36277
|
-
|
|
36371
|
+
app78.get("/agent-assets/:slug/:filename", (c) => {
|
|
36278
36372
|
const slug = c.req.param("slug");
|
|
36279
36373
|
const filename = c.req.param("filename");
|
|
36280
36374
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -36309,7 +36403,7 @@ app77.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
36309
36403
|
"Cache-Control": "public, max-age=3600"
|
|
36310
36404
|
});
|
|
36311
36405
|
});
|
|
36312
|
-
|
|
36406
|
+
app78.get("/generated/:filename", (c) => {
|
|
36313
36407
|
const filename = c.req.param("filename");
|
|
36314
36408
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
36315
36409
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -36339,10 +36433,10 @@ app77.get("/generated/:filename", (c) => {
|
|
|
36339
36433
|
"Cache-Control": "public, max-age=86400"
|
|
36340
36434
|
});
|
|
36341
36435
|
});
|
|
36342
|
-
|
|
36343
|
-
|
|
36344
|
-
|
|
36345
|
-
|
|
36436
|
+
app78.route("/sites", sites_default);
|
|
36437
|
+
app78.route("/listings", listings_default);
|
|
36438
|
+
app78.route("/v", visitor_event_default);
|
|
36439
|
+
app78.route("/v", visitor_consent_default);
|
|
36346
36440
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
36347
36441
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
36348
36442
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
@@ -36387,7 +36481,7 @@ var SW_SOURCE = (() => {
|
|
|
36387
36481
|
function readInstalledVersion() {
|
|
36388
36482
|
try {
|
|
36389
36483
|
if (!PLATFORM_ROOT6) return "unknown";
|
|
36390
|
-
const versionFile =
|
|
36484
|
+
const versionFile = join60(PLATFORM_ROOT6, "config", `.${BRAND.hostname}-version`);
|
|
36391
36485
|
if (!existsSync54(versionFile)) return "unknown";
|
|
36392
36486
|
const content = readFileSync51(versionFile, "utf-8").trim();
|
|
36393
36487
|
return content || "unknown";
|
|
@@ -36417,12 +36511,12 @@ ${clientErrorReporterScript}
|
|
|
36417
36511
|
return html;
|
|
36418
36512
|
}
|
|
36419
36513
|
function loadBrandingCache(agentSlug) {
|
|
36420
|
-
const configDir =
|
|
36514
|
+
const configDir = join60(homedir5(), BRAND.configDir);
|
|
36421
36515
|
try {
|
|
36422
36516
|
const verdict = resolvePublicAddressFromDisk(agentSlug);
|
|
36423
36517
|
const accountId = verdict.kind === "served" ? verdict.owner.accountId : getDefaultAccountId();
|
|
36424
36518
|
if (!accountId) return null;
|
|
36425
|
-
const cachePath =
|
|
36519
|
+
const cachePath = join60(configDir, "branding-cache", accountId, `${agentSlug}.json`);
|
|
36426
36520
|
if (!existsSync54(cachePath)) return null;
|
|
36427
36521
|
return JSON.parse(readFileSync51(cachePath, "utf-8"));
|
|
36428
36522
|
} catch {
|
|
@@ -36468,7 +36562,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
36468
36562
|
function agentUnavailableHtml() {
|
|
36469
36563
|
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
|
|
36470
36564
|
}
|
|
36471
|
-
|
|
36565
|
+
app78.get("/", (c) => {
|
|
36472
36566
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36473
36567
|
const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
|
|
36474
36568
|
if (klass === "operator") {
|
|
@@ -36490,12 +36584,12 @@ app77.get("/", (c) => {
|
|
|
36490
36584
|
console.log(`[host-class] host=${host} class=admin served=index.html`);
|
|
36491
36585
|
return c.html(cachedHtml("index.html"));
|
|
36492
36586
|
});
|
|
36493
|
-
|
|
36587
|
+
app78.get("/public", (c) => {
|
|
36494
36588
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36495
36589
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36496
36590
|
return c.html(cachedHtml("public.html"));
|
|
36497
36591
|
});
|
|
36498
|
-
|
|
36592
|
+
app78.get("/public-chat", (c) => {
|
|
36499
36593
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36500
36594
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36501
36595
|
return c.html(cachedHtml("public.html"));
|
|
@@ -36514,9 +36608,9 @@ async function logViewerFetch(c, next) {
|
|
|
36514
36608
|
duration_ms: Date.now() - start
|
|
36515
36609
|
});
|
|
36516
36610
|
}
|
|
36517
|
-
|
|
36518
|
-
|
|
36519
|
-
|
|
36611
|
+
app78.use("/vnc-viewer.html", logViewerFetch);
|
|
36612
|
+
app78.use("/vnc-popout.html", logViewerFetch);
|
|
36613
|
+
app78.get("/vnc-popout.html", (c) => {
|
|
36520
36614
|
let html = htmlCache.get("vnc-popout.html");
|
|
36521
36615
|
if (!html) {
|
|
36522
36616
|
html = readFileSync51(resolve49(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -36529,7 +36623,7 @@ app77.get("/vnc-popout.html", (c) => {
|
|
|
36529
36623
|
}
|
|
36530
36624
|
return c.html(html);
|
|
36531
36625
|
});
|
|
36532
|
-
|
|
36626
|
+
app78.post("/api/vnc/client-event", async (c) => {
|
|
36533
36627
|
let body;
|
|
36534
36628
|
try {
|
|
36535
36629
|
body = await c.req.json();
|
|
@@ -36550,11 +36644,11 @@ app77.post("/api/vnc/client-event", async (c) => {
|
|
|
36550
36644
|
});
|
|
36551
36645
|
return c.json({ ok: true });
|
|
36552
36646
|
});
|
|
36553
|
-
|
|
36647
|
+
app78.get("/g/:slug", (c) => {
|
|
36554
36648
|
return c.html(brandedPublicHtml(resolveDefaultSlug() ?? void 0));
|
|
36555
36649
|
});
|
|
36556
36650
|
for (const pwa of PWA_SURFACES) {
|
|
36557
|
-
|
|
36651
|
+
app78.get(pwa.manifestPath, (c) => {
|
|
36558
36652
|
const manifest = buildManifest(pwa, {
|
|
36559
36653
|
productName: BRAND.productName,
|
|
36560
36654
|
appIcon192: brandAppIcon192Path,
|
|
@@ -36570,7 +36664,7 @@ for (const pwa of PWA_SURFACES) {
|
|
|
36570
36664
|
return c.body(JSON.stringify(manifest));
|
|
36571
36665
|
});
|
|
36572
36666
|
}
|
|
36573
|
-
|
|
36667
|
+
app78.get("/sw.js", (c) => {
|
|
36574
36668
|
if (SW_SOURCE == null) {
|
|
36575
36669
|
console.error("[pwa] op=sw status=500 reason=sw-source-missing");
|
|
36576
36670
|
return c.text("Service worker unavailable", 500);
|
|
@@ -36579,12 +36673,12 @@ app77.get("/sw.js", (c) => {
|
|
|
36579
36673
|
console.log(`[pwa] op=sw status=200 ct=${SW_CONTENT_TYPE}`);
|
|
36580
36674
|
return c.body(SW_SOURCE);
|
|
36581
36675
|
});
|
|
36582
|
-
|
|
36676
|
+
app78.get("/graph", (c) => {
|
|
36583
36677
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36584
36678
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
36585
36679
|
return c.html(cachedHtml("graph.html"));
|
|
36586
36680
|
});
|
|
36587
|
-
|
|
36681
|
+
app78.get("/chat", (c) => {
|
|
36588
36682
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36589
36683
|
if (isOperatorHost(host, getOperatorDomains())) {
|
|
36590
36684
|
console.log(`[host-class] host=${host} class=operator served=operator.html`);
|
|
@@ -36593,47 +36687,47 @@ app77.get("/chat", (c) => {
|
|
|
36593
36687
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36594
36688
|
return c.html(cachedHtml("chat.html"));
|
|
36595
36689
|
});
|
|
36596
|
-
|
|
36690
|
+
app78.get("/data", (c) => {
|
|
36597
36691
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36598
36692
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36599
36693
|
return c.html(cachedHtml("data.html"));
|
|
36600
36694
|
});
|
|
36601
|
-
|
|
36695
|
+
app78.get("/tasks", (c) => {
|
|
36602
36696
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36603
36697
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36604
36698
|
return c.html(cachedHtml("tasks.html"));
|
|
36605
36699
|
});
|
|
36606
|
-
|
|
36700
|
+
app78.get("/activity", (c) => {
|
|
36607
36701
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36608
36702
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36609
36703
|
return c.html(cachedHtml("activity.html"));
|
|
36610
36704
|
});
|
|
36611
|
-
|
|
36705
|
+
app78.get("/calendar", (c) => {
|
|
36612
36706
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36613
36707
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36614
36708
|
return c.html(cachedHtml("calendar.html"));
|
|
36615
36709
|
});
|
|
36616
|
-
|
|
36710
|
+
app78.get("/routines", (c) => {
|
|
36617
36711
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36618
36712
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36619
36713
|
return c.html(cachedHtml("routines.html"));
|
|
36620
36714
|
});
|
|
36621
|
-
|
|
36715
|
+
app78.get("/skills", (c) => {
|
|
36622
36716
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36623
36717
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36624
36718
|
return c.html(cachedHtml("skills.html"));
|
|
36625
36719
|
});
|
|
36626
|
-
|
|
36720
|
+
app78.get("/agents", (c) => {
|
|
36627
36721
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36628
36722
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
36629
36723
|
return c.html(cachedHtml("agents.html"));
|
|
36630
36724
|
});
|
|
36631
|
-
|
|
36725
|
+
app78.get("/browser", (c) => {
|
|
36632
36726
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36633
36727
|
if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
|
|
36634
36728
|
return c.html(cachedHtml("browser.html"));
|
|
36635
36729
|
});
|
|
36636
|
-
|
|
36730
|
+
app78.get("/:slug", async (c, next) => {
|
|
36637
36731
|
const slug = c.req.param("slug");
|
|
36638
36732
|
if (AGENT_SLUG_PATTERN2.test(`/${slug}`)) {
|
|
36639
36733
|
const verdict = validateAgentSlug(slug) ? resolvePublicAddressFromDisk(slug) : { kind: "none" };
|
|
@@ -36649,13 +36743,13 @@ app77.get("/:slug", async (c, next) => {
|
|
|
36649
36743
|
await next();
|
|
36650
36744
|
});
|
|
36651
36745
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
36652
|
-
|
|
36746
|
+
app78.get("/favicon.ico", (c) => {
|
|
36653
36747
|
c.header("Cache-Control", "public, max-age=300");
|
|
36654
36748
|
return c.redirect(brandFaviconPath, 302);
|
|
36655
36749
|
});
|
|
36656
36750
|
}
|
|
36657
|
-
mountStaticFiles(
|
|
36658
|
-
|
|
36751
|
+
mountStaticFiles(app78, "./public");
|
|
36752
|
+
app78.all("*", (c) => {
|
|
36659
36753
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
36660
36754
|
const path = c.req.path;
|
|
36661
36755
|
if (isPublicHost(host)) {
|
|
@@ -36669,10 +36763,10 @@ app77.all("*", (c) => {
|
|
|
36669
36763
|
});
|
|
36670
36764
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
36671
36765
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
36672
|
-
var httpServer = serve({ fetch:
|
|
36766
|
+
var httpServer = serve({ fetch: app78.fetch, port, hostname });
|
|
36673
36767
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
36674
36768
|
{
|
|
36675
|
-
const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
36769
|
+
const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, "..");
|
|
36676
36770
|
const reconcileScript = resolve49(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
|
|
36677
36771
|
const runReconcile = (ctx) => {
|
|
36678
36772
|
if (!existsSync54(reconcileScript)) return;
|
|
@@ -36695,7 +36789,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
36695
36789
|
detached: true,
|
|
36696
36790
|
run: runReconcile
|
|
36697
36791
|
});
|
|
36698
|
-
const reconcileStatePath =
|
|
36792
|
+
const reconcileStatePath = join60(MAXY_DIR, "booking-reconcile-state.json");
|
|
36699
36793
|
registerLoop({
|
|
36700
36794
|
name: "calendar-reconcile-liveness",
|
|
36701
36795
|
intervalMs: 6e5,
|
|
@@ -36713,7 +36807,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
36713
36807
|
}
|
|
36714
36808
|
{
|
|
36715
36809
|
const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
|
|
36716
|
-
const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
36810
|
+
const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, "..");
|
|
36717
36811
|
const dreamSweepScript = resolve49(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
|
|
36718
36812
|
registerLoop({
|
|
36719
36813
|
name: "dream-cycle-sweep",
|
|
@@ -36737,7 +36831,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
36737
36831
|
});
|
|
36738
36832
|
}
|
|
36739
36833
|
{
|
|
36740
|
-
const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
36834
|
+
const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, "..");
|
|
36741
36835
|
const outlookScript = resolve49(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
|
|
36742
36836
|
const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
|
|
36743
36837
|
const runOutlookComplete = (ctx) => {
|
|
@@ -36763,7 +36857,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
36763
36857
|
});
|
|
36764
36858
|
}
|
|
36765
36859
|
{
|
|
36766
|
-
const auditRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
36860
|
+
const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, "..");
|
|
36767
36861
|
const strandedAccountsDir = resolve49(auditRoot, "..", "data/accounts");
|
|
36768
36862
|
const STRANDED_AUDIT_INTERVAL_MS = 3e5;
|
|
36769
36863
|
const STRANDED_AGE_MS = 16 * 6e4;
|
|
@@ -36793,7 +36887,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
36793
36887
|
});
|
|
36794
36888
|
}
|
|
36795
36889
|
{
|
|
36796
|
-
const googleRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
36890
|
+
const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, "..");
|
|
36797
36891
|
const googleAccountsDir = resolve49(googleRoot, "..", "data/accounts");
|
|
36798
36892
|
const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
|
|
36799
36893
|
const runGooglePendingAuditSafe = () => {
|
|
@@ -36837,7 +36931,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
36837
36931
|
});
|
|
36838
36932
|
}
|
|
36839
36933
|
{
|
|
36840
|
-
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
36934
|
+
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, "..");
|
|
36841
36935
|
const STORAGE_AUDIT_INTERVAL_MS = 3e5;
|
|
36842
36936
|
const runStorageAuditSafe = () => runStorageAudit(auditPlatformRoot).catch((err) => {
|
|
36843
36937
|
console.error(`[storage-audit] error="${err.message}"`);
|
|
@@ -37039,7 +37133,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
37039
37133
|
});
|
|
37040
37134
|
}
|
|
37041
37135
|
{
|
|
37042
|
-
const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
37136
|
+
const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, "..");
|
|
37043
37137
|
const publishScript = resolve49(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
|
|
37044
37138
|
const PUBLISH_INTERVAL_MS = 3e5;
|
|
37045
37139
|
const bookingAccounts = () => {
|
|
@@ -37116,7 +37210,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
37116
37210
|
startTimeEntryCensus(() => getSession());
|
|
37117
37211
|
startLedgerCensus(() => getSession());
|
|
37118
37212
|
{
|
|
37119
|
-
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
37213
|
+
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, "..");
|
|
37120
37214
|
const auditScript = resolve49(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
|
|
37121
37215
|
const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
|
|
37122
37216
|
const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
|
|
@@ -37202,7 +37296,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
37202
37296
|
}
|
|
37203
37297
|
try {
|
|
37204
37298
|
const registered = [];
|
|
37205
|
-
for (const r of
|
|
37299
|
+
for (const r of app78.routes ?? []) {
|
|
37206
37300
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
37207
37301
|
if (AGENT_SLUG_PATTERN2.test(r.path)) {
|
|
37208
37302
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
@@ -37328,8 +37422,8 @@ var runIngestAuditTick = () => {
|
|
|
37328
37422
|
},
|
|
37329
37423
|
agentExists: (accountId, slug) => {
|
|
37330
37424
|
if (!house) return false;
|
|
37331
|
-
const dir = isHouseAccountKey(house.accountId, accountId) ? house.accountDir :
|
|
37332
|
-
return existsSync54(
|
|
37425
|
+
const dir = isHouseAccountKey(house.accountId, accountId) ? house.accountDir : join60(ACCOUNTS_DIR, accountId);
|
|
37426
|
+
return existsSync54(join60(dir, "agents", slug, "config.json"));
|
|
37333
37427
|
}
|
|
37334
37428
|
});
|
|
37335
37429
|
} catch (err) {
|
|
@@ -37377,7 +37471,7 @@ registerLoop({
|
|
|
37377
37471
|
runPublicAddressCollisionAudit({
|
|
37378
37472
|
houseAccountId: () => resolveAccount()?.accountId ?? null,
|
|
37379
37473
|
activeSlugs: () => listValidAccounts().map((a) => {
|
|
37380
|
-
const agentsRoot =
|
|
37474
|
+
const agentsRoot = join60(a.accountDir, "agents");
|
|
37381
37475
|
if (!existsSync54(agentsRoot)) return { accountId: a.accountId, slugs: [] };
|
|
37382
37476
|
const slugs = readdirSync32(agentsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((slug) => isActiveAgentSlug(a.accountDir, slug));
|
|
37383
37477
|
return { accountId: a.accountId, slugs };
|
|
@@ -37561,7 +37655,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
37561
37655
|
}
|
|
37562
37656
|
init({
|
|
37563
37657
|
configDir: configDirForWhatsApp,
|
|
37564
|
-
platformRoot: resolve49(process.env.MAXY_PLATFORM_ROOT ??
|
|
37658
|
+
platformRoot: resolve49(process.env.MAXY_PLATFORM_ROOT ?? join60(__dirname, "..")),
|
|
37565
37659
|
accountConfig: bootAccountConfig,
|
|
37566
37660
|
// Task 2074 — enrich with the sub-account name and fan out to every open
|
|
37567
37661
|
// admin SSE stream. Fire-and-forget: the manager's persist path must not
|