@rubytech/create-realagent 1.0.831 → 1.0.833
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +131 -9
- package/package.json +1 -1
- package/payload/platform/lib/admins-write/dist/index.d.ts +87 -0
- package/payload/platform/lib/admins-write/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/admins-write/dist/index.js +248 -0
- package/payload/platform/lib/admins-write/dist/index.js.map +1 -0
- package/payload/platform/lib/admins-write/src/index.ts +311 -0
- package/payload/platform/lib/admins-write/tsconfig.json +8 -0
- package/payload/platform/neo4j/migrations/004-project-admin-agent.ts +36 -3
- package/payload/platform/neo4j/migrations/009-conversation-archive-title.ts +197 -0
- package/payload/platform/neo4j/schema.cypher +1 -1
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/admin/PLUGIN.md +1 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +37 -44
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/docs/references/internals.md +4 -3
- package/payload/platform/plugins/memory/bin/conversation-archive-ingest.mjs +455 -140
- package/payload/platform/plugins/memory/bin/conversation-archive-ingest.sh +47 -15
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js +75 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts +16 -10
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js +155 -100
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.d.ts +13 -5
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js +53 -59
- package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/uuid.d.ts +3 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/uuid.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/uuid.js +12 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/uuid.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +28 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +35 -9
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +64 -12
- package/payload/platform/scripts/lib/resolve-account-dir.sh +22 -2
- package/payload/platform/scripts/migrate-import.sh +3 -1
- package/payload/platform/scripts/seed-neo4j.sh +13 -3
- package/payload/server/chunk-25QDCOE5.js +1116 -0
- package/payload/server/chunk-35YZS3KL.js +328 -0
- package/payload/server/chunk-7CBRZKZS.js +654 -0
- package/payload/server/chunk-CRAIGEXY.js +654 -0
- package/payload/server/chunk-I2NOLBQA.js +2123 -0
- package/payload/server/chunk-IVTESKFR.js +9961 -0
- package/payload/server/chunk-IXOPV36P.js +2305 -0
- package/payload/server/chunk-KD3XP4IK.js +1116 -0
- package/payload/server/chunk-OJZPS4BL.js +367 -0
- package/payload/server/chunk-ZKGAYLAK.js +10097 -0
- package/payload/server/client-pool-J5BCVVI2.js +32 -0
- package/payload/server/client-pool-NBVGONQL.js +32 -0
- package/payload/server/cloudflare-task-tracker-R4FIORFL.js +19 -0
- package/payload/server/cloudflare-task-tracker-XCUO4N74.js +19 -0
- package/payload/server/maxy-edge.js +6 -5
- package/payload/server/neo4j-migrations-3A6K2EB5.js +552 -0
- package/payload/server/neo4j-migrations-5AN2U3YO.js +664 -0
- package/payload/server/public/assets/{admin-BNwPsMhJ.js → admin-CgGQafDG.js} +1 -1
- package/payload/server/public/assets/{graph-N_Bw-8oT.js → graph-BlrcvwWP.js} +1 -1
- package/payload/server/public/assets/{page-BKLGP-th.js → page-ClTUYMK8.js} +1 -1
- package/payload/server/public/graph.html +2 -2
- package/payload/server/public/index.html +2 -2
- package/payload/server/server.js +385 -167
- package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.d.ts +0 -31
- package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.d.ts.map +0 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.js +0 -666
- package/payload/platform/plugins/admin/mcp/dist/lib/review-tools.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.d.ts +0 -61
- package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.js +0 -266
- package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.d.ts +0 -27
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.js +0 -477
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-pass.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.d.ts +0 -27
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.js +0 -160
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-insight-write.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.d.ts +0 -10
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.js +0 -29
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-parse.js.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.d.ts +0 -28
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.d.ts.map +0 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.js +0 -34
- package/payload/platform/plugins/memory/mcp/dist/tools/whatsapp-export-preview.js.map +0 -1
package/payload/server/server.js
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
COMMERCIAL_MODE,
|
|
3
2
|
Hono,
|
|
4
|
-
LOG_DIR,
|
|
5
|
-
MAXY_DIR,
|
|
6
|
-
TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE,
|
|
7
|
-
TELEGRAM_WEBHOOK_SECRET_FILE,
|
|
8
|
-
USERS_FILE,
|
|
9
3
|
autoDeliverPremiumPlugins,
|
|
10
4
|
buildX11Env,
|
|
11
5
|
callOauthLlm,
|
|
@@ -51,7 +45,7 @@ import {
|
|
|
51
45
|
vncLog,
|
|
52
46
|
waitForExit,
|
|
53
47
|
writeChromiumWrapper
|
|
54
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-IVTESKFR.js";
|
|
55
49
|
import {
|
|
56
50
|
agentLogStream,
|
|
57
51
|
clearSessionHistory,
|
|
@@ -79,17 +73,24 @@ import {
|
|
|
79
73
|
sigtermFlushStreamLogs,
|
|
80
74
|
unregisterSession,
|
|
81
75
|
validateSession
|
|
82
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-KD3XP4IK.js";
|
|
83
77
|
import {
|
|
84
78
|
ACCOUNTS_DIR,
|
|
79
|
+
COMMERCIAL_MODE,
|
|
80
|
+
LOG_DIR,
|
|
81
|
+
MAXY_DIR,
|
|
85
82
|
PLATFORM_ROOT,
|
|
83
|
+
TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE,
|
|
84
|
+
TELEGRAM_WEBHOOK_SECRET_FILE,
|
|
85
|
+
USERS_FILE,
|
|
86
86
|
getDefaultAccountId,
|
|
87
|
+
hasStubAccountDir,
|
|
87
88
|
resolveAccount,
|
|
88
89
|
resolveAgentConfig,
|
|
89
90
|
resolveDefaultAgentSlug,
|
|
90
91
|
resolveUserAccounts,
|
|
91
92
|
validateAgentSlug
|
|
92
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-OJZPS4BL.js";
|
|
93
94
|
import {
|
|
94
95
|
CLOUDFLARE_TASK_DIAGNOSTICS,
|
|
95
96
|
appendCloudflareSteps,
|
|
@@ -97,7 +98,7 @@ import {
|
|
|
97
98
|
openCloudflareTask,
|
|
98
99
|
readTunnelState,
|
|
99
100
|
resolveUnitGoneVerdict
|
|
100
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-CRAIGEXY.js";
|
|
101
102
|
import {
|
|
102
103
|
GREETING_DIRECTIVE,
|
|
103
104
|
HAIKU_MODEL,
|
|
@@ -129,7 +130,7 @@ import {
|
|
|
129
130
|
verifyAndGetConversationUpdatedAt,
|
|
130
131
|
verifyConversationOwnership,
|
|
131
132
|
writeAdminUserAndPerson
|
|
132
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-I2NOLBQA.js";
|
|
133
134
|
|
|
134
135
|
// ../lib/graph-trash/dist/index.js
|
|
135
136
|
var require_dist = __commonJS({
|
|
@@ -628,8 +629,8 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
628
629
|
};
|
|
629
630
|
|
|
630
631
|
// server/index.ts
|
|
631
|
-
import { readFileSync as
|
|
632
|
-
import { resolve as resolve22, join as
|
|
632
|
+
import { readFileSync as readFileSync17, existsSync as existsSync23, watchFile } from "fs";
|
|
633
|
+
import { resolve as resolve22, join as join12, basename as basename5 } from "path";
|
|
633
634
|
import { homedir as homedir2 } from "os";
|
|
634
635
|
|
|
635
636
|
// app/lib/agent-slug-pattern.ts
|
|
@@ -6391,16 +6392,164 @@ var whatsapp_default = app7;
|
|
|
6391
6392
|
|
|
6392
6393
|
// server/routes/onboarding.ts
|
|
6393
6394
|
import { spawn, execFileSync } from "child_process";
|
|
6394
|
-
import { openSync, closeSync, writeFileSync as
|
|
6395
|
-
import { resolve as resolve8, dirname as
|
|
6395
|
+
import { openSync, closeSync, writeFileSync as writeFileSync5, writeSync, existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync9, unlinkSync } from "fs";
|
|
6396
|
+
import { resolve as resolve8, dirname as dirname3 } from "path";
|
|
6396
6397
|
import { createHash, randomUUID as randomUUID6 } from "crypto";
|
|
6398
|
+
|
|
6399
|
+
// ../lib/admins-write/src/index.ts
|
|
6400
|
+
import { existsSync as existsSync8, readFileSync as readFileSync8, writeFileSync as writeFileSync4, renameSync, mkdirSync as mkdirSync3, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
|
|
6401
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
6402
|
+
function logLine(input, result) {
|
|
6403
|
+
const userIdShort = input.userId.slice(0, 8);
|
|
6404
|
+
console.error(
|
|
6405
|
+
`[admins-write] caller=${input.caller} userId=${userIdShort} usersJsonResult=${result.usersJsonResult} accountJsonResult=${result.accountJsonResult}` + (result.usersError ? ` usersError=${result.usersError}` : "") + (result.accountError ? ` accountError=${result.accountError}` : "")
|
|
6406
|
+
);
|
|
6407
|
+
}
|
|
6408
|
+
function writeFileAtomic(filePath, contents, mode) {
|
|
6409
|
+
mkdirSync3(dirname2(filePath), { recursive: true });
|
|
6410
|
+
const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
6411
|
+
writeFileSync4(tempPath, contents, mode !== void 0 ? { mode } : void 0);
|
|
6412
|
+
renameSync(tempPath, filePath);
|
|
6413
|
+
}
|
|
6414
|
+
function writeAdminEntry(input) {
|
|
6415
|
+
const result = { usersJsonResult: "noop", accountJsonResult: "noop" };
|
|
6416
|
+
try {
|
|
6417
|
+
let users = [];
|
|
6418
|
+
if (existsSync8(input.usersFile)) {
|
|
6419
|
+
const raw = readFileSync8(input.usersFile, "utf-8").trim();
|
|
6420
|
+
if (raw) {
|
|
6421
|
+
const parsed = JSON.parse(raw);
|
|
6422
|
+
if (!Array.isArray(parsed)) {
|
|
6423
|
+
throw new Error("users.json is not an array");
|
|
6424
|
+
}
|
|
6425
|
+
users = parsed;
|
|
6426
|
+
}
|
|
6427
|
+
}
|
|
6428
|
+
const existing = users.findIndex((u) => u.userId === input.userId);
|
|
6429
|
+
if (existing === -1) {
|
|
6430
|
+
users.push({ userId: input.userId, pin: input.pin });
|
|
6431
|
+
} else {
|
|
6432
|
+
const merged = { ...users[existing], pin: input.pin };
|
|
6433
|
+
delete merged.name;
|
|
6434
|
+
users[existing] = merged;
|
|
6435
|
+
}
|
|
6436
|
+
writeFileAtomic(input.usersFile, JSON.stringify(users, null, 2) + "\n", 384);
|
|
6437
|
+
result.usersJsonResult = "ok";
|
|
6438
|
+
} catch (err) {
|
|
6439
|
+
result.usersJsonResult = "fail";
|
|
6440
|
+
result.usersError = err instanceof Error ? err.message : String(err);
|
|
6441
|
+
logLine(input, result);
|
|
6442
|
+
return result;
|
|
6443
|
+
}
|
|
6444
|
+
try {
|
|
6445
|
+
const accountJsonPath = join6(input.accountDir, "account.json");
|
|
6446
|
+
if (!existsSync8(accountJsonPath)) {
|
|
6447
|
+
throw new Error(`account.json not found at ${accountJsonPath}`);
|
|
6448
|
+
}
|
|
6449
|
+
const config = JSON.parse(readFileSync8(accountJsonPath, "utf-8"));
|
|
6450
|
+
const admins = config.admins ?? [];
|
|
6451
|
+
if (admins.some((a) => a.userId === input.userId)) {
|
|
6452
|
+
result.accountJsonResult = "noop";
|
|
6453
|
+
} else {
|
|
6454
|
+
admins.push({ userId: input.userId, role: input.role });
|
|
6455
|
+
config.admins = admins;
|
|
6456
|
+
writeFileAtomic(accountJsonPath, JSON.stringify(config, null, 2) + "\n");
|
|
6457
|
+
result.accountJsonResult = "ok";
|
|
6458
|
+
}
|
|
6459
|
+
} catch (err) {
|
|
6460
|
+
result.accountJsonResult = "fail";
|
|
6461
|
+
result.accountError = err instanceof Error ? err.message : String(err);
|
|
6462
|
+
}
|
|
6463
|
+
logLine(input, result);
|
|
6464
|
+
return result;
|
|
6465
|
+
}
|
|
6466
|
+
function checkAdminAuthInvariant(input) {
|
|
6467
|
+
const result = {
|
|
6468
|
+
divergences: 0,
|
|
6469
|
+
accountWithoutUsers: [],
|
|
6470
|
+
usersWithoutAccount: []
|
|
6471
|
+
};
|
|
6472
|
+
const usersUserIds = /* @__PURE__ */ new Set();
|
|
6473
|
+
if (existsSync8(input.usersFile)) {
|
|
6474
|
+
try {
|
|
6475
|
+
const raw = readFileSync8(input.usersFile, "utf-8").trim();
|
|
6476
|
+
if (raw) {
|
|
6477
|
+
const users = JSON.parse(raw);
|
|
6478
|
+
for (const u of users) {
|
|
6479
|
+
if (typeof u.userId === "string") usersUserIds.add(u.userId);
|
|
6480
|
+
}
|
|
6481
|
+
}
|
|
6482
|
+
} catch (err) {
|
|
6483
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6484
|
+
console.error(`[${input.tag}] users.json unreadable usersFile=${input.usersFile} error=${msg}`);
|
|
6485
|
+
}
|
|
6486
|
+
}
|
|
6487
|
+
const accountUserIds = /* @__PURE__ */ new Set();
|
|
6488
|
+
if (existsSync8(input.accountsDir)) {
|
|
6489
|
+
let entries;
|
|
6490
|
+
try {
|
|
6491
|
+
entries = readdirSync3(input.accountsDir);
|
|
6492
|
+
} catch (err) {
|
|
6493
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6494
|
+
console.error(`[${input.tag}] accounts-dir unreadable accountsDir=${input.accountsDir} error=${msg}`);
|
|
6495
|
+
console.error(`[${input.tag}] check complete divergences=0 (accounts-dir unreadable)`);
|
|
6496
|
+
return result;
|
|
6497
|
+
}
|
|
6498
|
+
for (const entry of entries) {
|
|
6499
|
+
if (entry.startsWith(".")) continue;
|
|
6500
|
+
const accountDir = join6(input.accountsDir, entry);
|
|
6501
|
+
try {
|
|
6502
|
+
if (!statSync2(accountDir).isDirectory()) continue;
|
|
6503
|
+
} catch {
|
|
6504
|
+
continue;
|
|
6505
|
+
}
|
|
6506
|
+
const accountJsonPath = join6(accountDir, "account.json");
|
|
6507
|
+
if (!existsSync8(accountJsonPath)) continue;
|
|
6508
|
+
let admins = [];
|
|
6509
|
+
try {
|
|
6510
|
+
const config = JSON.parse(readFileSync8(accountJsonPath, "utf-8"));
|
|
6511
|
+
admins = config.admins ?? [];
|
|
6512
|
+
} catch (err) {
|
|
6513
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6514
|
+
console.error(`[${input.tag}] account.json unreadable source=${accountJsonPath} error=${msg}`);
|
|
6515
|
+
continue;
|
|
6516
|
+
}
|
|
6517
|
+
for (const a of admins) {
|
|
6518
|
+
if (typeof a.userId !== "string") continue;
|
|
6519
|
+
accountUserIds.add(a.userId);
|
|
6520
|
+
if (!usersUserIds.has(a.userId)) {
|
|
6521
|
+
const userIdShort = a.userId.slice(0, 8);
|
|
6522
|
+
console.error(
|
|
6523
|
+
`[${input.tag}] direction=account-without-users userId=${userIdShort} source=${accountJsonPath}`
|
|
6524
|
+
);
|
|
6525
|
+
result.accountWithoutUsers.push({ userId: a.userId, source: accountJsonPath });
|
|
6526
|
+
result.divergences += 1;
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6529
|
+
}
|
|
6530
|
+
}
|
|
6531
|
+
for (const uid of usersUserIds) {
|
|
6532
|
+
if (!accountUserIds.has(uid)) {
|
|
6533
|
+
const userIdShort = uid.slice(0, 8);
|
|
6534
|
+
console.error(
|
|
6535
|
+
`[${input.tag}] direction=users-without-account userId=${userIdShort} source=${input.usersFile}`
|
|
6536
|
+
);
|
|
6537
|
+
result.usersWithoutAccount.push({ userId: uid });
|
|
6538
|
+
result.divergences += 1;
|
|
6539
|
+
}
|
|
6540
|
+
}
|
|
6541
|
+
console.error(`[${input.tag}] check complete divergences=${result.divergences}`);
|
|
6542
|
+
return result;
|
|
6543
|
+
}
|
|
6544
|
+
|
|
6545
|
+
// server/routes/onboarding.ts
|
|
6397
6546
|
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
6398
6547
|
function hashPin(pin) {
|
|
6399
6548
|
return createHash("sha256").update(pin).digest("hex");
|
|
6400
6549
|
}
|
|
6401
6550
|
function readUsersFile() {
|
|
6402
|
-
if (!
|
|
6403
|
-
const raw =
|
|
6551
|
+
if (!existsSync9(USERS_FILE)) return null;
|
|
6552
|
+
const raw = readFileSync9(USERS_FILE, "utf-8").trim();
|
|
6404
6553
|
if (!raw) return [];
|
|
6405
6554
|
return JSON.parse(raw);
|
|
6406
6555
|
}
|
|
@@ -6466,7 +6615,7 @@ app8.post("/claude-auth", async (c) => {
|
|
|
6466
6615
|
if (!vncReady) return c.json({ error: "VNC display failed to start" }, 500);
|
|
6467
6616
|
}
|
|
6468
6617
|
await ensureCdp(transport);
|
|
6469
|
-
|
|
6618
|
+
writeFileSync5(logPath("claude-auth"), "");
|
|
6470
6619
|
const chromiumWrapper = writeChromiumWrapper();
|
|
6471
6620
|
const x11Env = buildX11Env(chromiumWrapper, transport);
|
|
6472
6621
|
vncLog("claude-auth", { action: "start", transport });
|
|
@@ -6494,6 +6643,17 @@ app8.post("/set-pin", async (c) => {
|
|
|
6494
6643
|
if (existingUsers !== null && existingUsers.length > 0) {
|
|
6495
6644
|
return c.json({ error: "PIN is already configured." }, 409);
|
|
6496
6645
|
}
|
|
6646
|
+
const stubCheck = hasStubAccountDir();
|
|
6647
|
+
if (stubCheck.stub) {
|
|
6648
|
+
console.error(
|
|
6649
|
+
`[onboarding] set-pin REFUSED reason=stub-account-dirs dirs=${stubCheck.dirs.join(",")}`
|
|
6650
|
+
);
|
|
6651
|
+
return c.json({
|
|
6652
|
+
error: `Onboarding refused: data/accounts/ contains ${stubCheck.dirs.length} directory/ies without account.json (${stubCheck.dirs.join(", ")}). Resolve the stub before setting up.`,
|
|
6653
|
+
code: "STUB_ACCOUNT_DIR",
|
|
6654
|
+
dirs: stubCheck.dirs
|
|
6655
|
+
}, 409);
|
|
6656
|
+
}
|
|
6497
6657
|
let body;
|
|
6498
6658
|
try {
|
|
6499
6659
|
body = await c.req.json();
|
|
@@ -6516,36 +6676,41 @@ app8.post("/set-pin", async (c) => {
|
|
|
6516
6676
|
} else {
|
|
6517
6677
|
console.log(`[set-pin] minted new userId=${userId.slice(0, 8)}\u2026 (first-time install)`);
|
|
6518
6678
|
}
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
}
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6679
|
+
if (!account) {
|
|
6680
|
+
console.error(`[set-pin] no account resolvable at set-pin time \u2014 refusing to write users.json without account binding`);
|
|
6681
|
+
return c.json({ error: "No account is configured on this device. Re-run the installer." }, 503);
|
|
6682
|
+
}
|
|
6683
|
+
const result = writeAdminEntry({
|
|
6684
|
+
userId,
|
|
6685
|
+
pin: hash,
|
|
6686
|
+
role: "owner",
|
|
6687
|
+
usersFile: USERS_FILE,
|
|
6688
|
+
accountDir: account.accountDir,
|
|
6689
|
+
caller: "set-pin"
|
|
6690
|
+
});
|
|
6691
|
+
if (result.usersJsonResult !== "ok") {
|
|
6692
|
+
console.error(`[set-pin] users.json write failed: ${result.usersError ?? "unknown"}`);
|
|
6693
|
+
return c.json({ error: "Failed to write user configuration. See server log." }, 500);
|
|
6694
|
+
}
|
|
6695
|
+
if (result.accountJsonResult === "fail") {
|
|
6696
|
+
console.error(`[set-pin] account.json write failed after users.json succeeded: ${result.accountError ?? "unknown"}`);
|
|
6697
|
+
return c.json({ error: "PIN saved but admin role could not be recorded. See server log." }, 500);
|
|
6698
|
+
}
|
|
6699
|
+
console.log(`[set-pin] wrote users.json + account.json admins: userId=${userId.slice(0, 8)}\u2026 role=owner`);
|
|
6700
|
+
try {
|
|
6701
|
+
const adminBind = await writeAdminUserAndPerson({
|
|
6702
|
+
userId,
|
|
6703
|
+
fullName,
|
|
6704
|
+
accountId: account.accountId
|
|
6705
|
+
});
|
|
6706
|
+
console.log(
|
|
6707
|
+
`[admin-identity] adminuser-bound userId=${userId.slice(0, 8)} givenName=${adminBind.givenName} familyName=${adminBind.familyName ?? "null"} personReused=${adminBind.personReused}`
|
|
6708
|
+
);
|
|
6709
|
+
} catch (err) {
|
|
6710
|
+
console.error(
|
|
6711
|
+
`[admin-identity] adminuser-bind-failed userId=${userId.slice(0, 8)} accountId=${account.accountId.slice(0, 8)} error=${err instanceof Error ? err.message : String(err)}`
|
|
6712
|
+
);
|
|
6713
|
+
return c.json({ error: "Failed to write admin identity to graph. Check Neo4j connectivity and retry." }, 500);
|
|
6549
6714
|
}
|
|
6550
6715
|
return c.json({ ok: true });
|
|
6551
6716
|
});
|
|
@@ -6578,7 +6743,7 @@ app8.delete("/set-pin", async (c) => {
|
|
|
6578
6743
|
unlinkSync(USERS_FILE);
|
|
6579
6744
|
console.log(`[set-pin] cleared users.json (last entry removed): userId=${matchedUser.userId.slice(0, 8)}\u2026`);
|
|
6580
6745
|
} else {
|
|
6581
|
-
|
|
6746
|
+
writeFileSync5(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
|
|
6582
6747
|
console.log(`[set-pin] removed entry from users.json: userId=${matchedUser.userId.slice(0, 8)}\u2026 remaining=${remaining.length}`);
|
|
6583
6748
|
}
|
|
6584
6749
|
return c.json({ ok: true });
|
|
@@ -6598,9 +6763,9 @@ app8.post("/skip", async (c) => {
|
|
|
6598
6763
|
const { accountId, accountDir } = account;
|
|
6599
6764
|
let agentName = "Maxy";
|
|
6600
6765
|
const brandPath = PLATFORM_ROOT5 ? resolve8(PLATFORM_ROOT5, "config", "brand.json") : "";
|
|
6601
|
-
if (brandPath &&
|
|
6766
|
+
if (brandPath && existsSync9(brandPath)) {
|
|
6602
6767
|
try {
|
|
6603
|
-
const brand = JSON.parse(
|
|
6768
|
+
const brand = JSON.parse(readFileSync9(brandPath, "utf-8"));
|
|
6604
6769
|
if (brand.productName) agentName = brand.productName;
|
|
6605
6770
|
} catch (err) {
|
|
6606
6771
|
console.error(`[onboarding-skip] brand.json read failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -6608,8 +6773,8 @@ app8.post("/skip", async (c) => {
|
|
|
6608
6773
|
}
|
|
6609
6774
|
const soulPath = resolve8(accountDir, "agents", "admin", "SOUL.md");
|
|
6610
6775
|
try {
|
|
6611
|
-
|
|
6612
|
-
|
|
6776
|
+
mkdirSync4(dirname3(soulPath), { recursive: true });
|
|
6777
|
+
writeFileSync5(soulPath, `You are ${agentName}, an AI operations manager.
|
|
6613
6778
|
`);
|
|
6614
6779
|
console.log(`[onboarding-skip] wrote SOUL.md: ${soulPath}`);
|
|
6615
6780
|
} catch (err) {
|
|
@@ -6653,9 +6818,9 @@ app8.post("/skip", async (c) => {
|
|
|
6653
6818
|
var onboarding_default = app8;
|
|
6654
6819
|
|
|
6655
6820
|
// server/routes/client-error.ts
|
|
6656
|
-
import { appendFileSync, existsSync as
|
|
6657
|
-
import { join as
|
|
6658
|
-
var CLIENT_ERRORS_LOG =
|
|
6821
|
+
import { appendFileSync, existsSync as existsSync10, renameSync as renameSync2, statSync as statSync3 } from "fs";
|
|
6822
|
+
import { join as join7 } from "path";
|
|
6823
|
+
var CLIENT_ERRORS_LOG = join7(LOG_DIR, "client-errors.log");
|
|
6659
6824
|
var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
6660
6825
|
var MAX_BODY_SIZE = 8 * 1024;
|
|
6661
6826
|
var MAX_STACK_LEN = 2e3;
|
|
@@ -6698,10 +6863,10 @@ function stackHead(stack) {
|
|
|
6698
6863
|
}
|
|
6699
6864
|
function rotateIfNeeded() {
|
|
6700
6865
|
try {
|
|
6701
|
-
if (!
|
|
6702
|
-
const stats =
|
|
6866
|
+
if (!existsSync10(CLIENT_ERRORS_LOG)) return;
|
|
6867
|
+
const stats = statSync3(CLIENT_ERRORS_LOG);
|
|
6703
6868
|
if (stats.size < MAX_LOG_SIZE) return;
|
|
6704
|
-
|
|
6869
|
+
renameSync2(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
|
|
6705
6870
|
} catch (err) {
|
|
6706
6871
|
console.error(`[client-error] log rotation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6707
6872
|
}
|
|
@@ -6812,18 +6977,53 @@ app9.post("/", async (c) => {
|
|
|
6812
6977
|
var client_error_default = app9;
|
|
6813
6978
|
|
|
6814
6979
|
// server/routes/admin/session.ts
|
|
6815
|
-
import { readFileSync as
|
|
6980
|
+
import { readFileSync as readFileSync10, readdirSync as readdirSync4, statSync as statSync4, writeFileSync as writeFileSync6, existsSync as existsSync11 } from "fs";
|
|
6981
|
+
import { join as join8 } from "path";
|
|
6816
6982
|
import { createHash as createHash2 } from "crypto";
|
|
6817
6983
|
var deprecationLogged = /* @__PURE__ */ new Set();
|
|
6818
6984
|
function hashPin2(pin) {
|
|
6819
6985
|
return createHash2("sha256").update(pin).digest("hex");
|
|
6820
6986
|
}
|
|
6821
6987
|
function readUsersFile2() {
|
|
6822
|
-
if (!
|
|
6823
|
-
const raw =
|
|
6988
|
+
if (!existsSync11(USERS_FILE)) return null;
|
|
6989
|
+
const raw = readFileSync10(USERS_FILE, "utf-8").trim();
|
|
6824
6990
|
if (!raw) return [];
|
|
6825
6991
|
return JSON.parse(raw);
|
|
6826
6992
|
}
|
|
6993
|
+
function scanForOrphanedAccountAdmins(users) {
|
|
6994
|
+
const usersUserIds = new Set(users.map((u) => u.userId));
|
|
6995
|
+
const orphans = [];
|
|
6996
|
+
if (!existsSync11(ACCOUNTS_DIR)) return orphans;
|
|
6997
|
+
let entries;
|
|
6998
|
+
try {
|
|
6999
|
+
entries = readdirSync4(ACCOUNTS_DIR);
|
|
7000
|
+
} catch {
|
|
7001
|
+
return orphans;
|
|
7002
|
+
}
|
|
7003
|
+
for (const entry of entries) {
|
|
7004
|
+
if (entry.startsWith(".")) continue;
|
|
7005
|
+
const accountDir = join8(ACCOUNTS_DIR, entry);
|
|
7006
|
+
try {
|
|
7007
|
+
if (!statSync4(accountDir).isDirectory()) continue;
|
|
7008
|
+
} catch {
|
|
7009
|
+
continue;
|
|
7010
|
+
}
|
|
7011
|
+
const accountJsonPath = join8(accountDir, "account.json");
|
|
7012
|
+
if (!existsSync11(accountJsonPath)) continue;
|
|
7013
|
+
try {
|
|
7014
|
+
const config = JSON.parse(readFileSync10(accountJsonPath, "utf-8"));
|
|
7015
|
+
const admins = config.admins ?? [];
|
|
7016
|
+
for (const a of admins) {
|
|
7017
|
+
if (typeof a.userId === "string" && !usersUserIds.has(a.userId)) {
|
|
7018
|
+
orphans.push(a.userId);
|
|
7019
|
+
}
|
|
7020
|
+
}
|
|
7021
|
+
} catch {
|
|
7022
|
+
continue;
|
|
7023
|
+
}
|
|
7024
|
+
}
|
|
7025
|
+
return orphans;
|
|
7026
|
+
}
|
|
6827
7027
|
function stripLegacyNameField(users) {
|
|
6828
7028
|
const dirty = users.some((u) => "name" in u && u.name !== void 0);
|
|
6829
7029
|
if (!dirty) return;
|
|
@@ -6837,7 +7037,7 @@ function stripLegacyNameField(users) {
|
|
|
6837
7037
|
}
|
|
6838
7038
|
}
|
|
6839
7039
|
try {
|
|
6840
|
-
|
|
7040
|
+
writeFileSync6(USERS_FILE, JSON.stringify(users), { mode: 384 });
|
|
6841
7041
|
} catch (err) {
|
|
6842
7042
|
console.error(`[admin-identity] users-json strip failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6843
7043
|
}
|
|
@@ -6957,7 +7157,15 @@ app10.post("/", async (c) => {
|
|
|
6957
7157
|
}
|
|
6958
7158
|
const matchedUser = users.find((u) => u.pin === inputHash);
|
|
6959
7159
|
if (!matchedUser) {
|
|
6960
|
-
|
|
7160
|
+
const orphanUserIds = scanForOrphanedAccountAdmins(users);
|
|
7161
|
+
if (orphanUserIds.length > 0) {
|
|
7162
|
+
const prefix = orphanUserIds[0].slice(0, 8);
|
|
7163
|
+
console.log(
|
|
7164
|
+
`[session] PIN auth failed: no matching user; account.json admins[] contains userId=${prefix} with no users.json row \u2014 three-store divergence`
|
|
7165
|
+
);
|
|
7166
|
+
} else {
|
|
7167
|
+
console.log(`[session] PIN auth failed: no matching user`);
|
|
7168
|
+
}
|
|
6961
7169
|
return c.json({ error: "Invalid PIN" }, 401);
|
|
6962
7170
|
}
|
|
6963
7171
|
stripLegacyNameField(users);
|
|
@@ -6999,8 +7207,8 @@ import { appendFileSync as appendFileSync3 } from "fs";
|
|
|
6999
7207
|
|
|
7000
7208
|
// app/lib/script-stream-tailer.ts
|
|
7001
7209
|
import * as childProcess from "child_process";
|
|
7002
|
-
import { appendFileSync as appendFileSync2, createReadStream as createReadStream2, mkdirSync as
|
|
7003
|
-
import { dirname as
|
|
7210
|
+
import { appendFileSync as appendFileSync2, createReadStream as createReadStream2, mkdirSync as mkdirSync5, statSync as statSync5 } from "fs";
|
|
7211
|
+
import { dirname as dirname4 } from "path";
|
|
7004
7212
|
import { StringDecoder } from "string_decoder";
|
|
7005
7213
|
var SCRIPT_STREAM_RE = /^\[([^\]]+)\] \[script:([a-z][a-z0-9-]*)((?::[a-z0-9:_-]+)?)\] (.*)$/;
|
|
7006
7214
|
function parseLine(line) {
|
|
@@ -7018,7 +7226,7 @@ function startScriptStreamTailer(opts) {
|
|
|
7018
7226
|
const { path: path2, onEvent, onError } = opts;
|
|
7019
7227
|
let offset;
|
|
7020
7228
|
try {
|
|
7021
|
-
offset =
|
|
7229
|
+
offset = statSync5(path2).size;
|
|
7022
7230
|
} catch {
|
|
7023
7231
|
offset = 0;
|
|
7024
7232
|
}
|
|
@@ -7037,7 +7245,7 @@ function startScriptStreamTailer(opts) {
|
|
|
7037
7245
|
try {
|
|
7038
7246
|
let size;
|
|
7039
7247
|
try {
|
|
7040
|
-
size =
|
|
7248
|
+
size = statSync5(path2).size;
|
|
7041
7249
|
} catch {
|
|
7042
7250
|
return;
|
|
7043
7251
|
}
|
|
@@ -7109,7 +7317,7 @@ function writeRouteMilestone(streamLogPath, scope, line) {
|
|
|
7109
7317
|
}
|
|
7110
7318
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
7111
7319
|
try {
|
|
7112
|
-
|
|
7320
|
+
mkdirSync5(dirname4(streamLogPath), { recursive: true });
|
|
7113
7321
|
appendFileSync2(streamLogPath, `[${ts}] [script:${scope}] ${line}
|
|
7114
7322
|
`);
|
|
7115
7323
|
} catch (err) {
|
|
@@ -7285,7 +7493,7 @@ var app11 = new Hono();
|
|
|
7285
7493
|
app11.post("/cancel", requireAdminSession, async (c) => {
|
|
7286
7494
|
const session_key = c.var.sessionKey;
|
|
7287
7495
|
try {
|
|
7288
|
-
const { interruptClient: interruptClient2 } = await import("./client-pool-
|
|
7496
|
+
const { interruptClient: interruptClient2 } = await import("./client-pool-J5BCVVI2.js");
|
|
7289
7497
|
await interruptClient2(session_key);
|
|
7290
7498
|
return c.json({ ok: true });
|
|
7291
7499
|
} catch (err) {
|
|
@@ -7680,22 +7888,22 @@ app12.post("/", requireAdminSession, async (c) => {
|
|
|
7680
7888
|
var compact_default = app12;
|
|
7681
7889
|
|
|
7682
7890
|
// server/routes/admin/logs.ts
|
|
7683
|
-
import { existsSync as
|
|
7891
|
+
import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync11, statSync as statSync6 } from "fs";
|
|
7684
7892
|
import { resolve as resolve10, basename as basename3 } from "path";
|
|
7685
7893
|
|
|
7686
7894
|
// app/lib/logs-read-resolve.ts
|
|
7687
|
-
import { existsSync as
|
|
7688
|
-
import { join as
|
|
7895
|
+
import { existsSync as existsSync12 } from "fs";
|
|
7896
|
+
import { join as join9 } from "path";
|
|
7689
7897
|
function resolveConversationLogPaths(fullFilename, preflushFilename, logDirs) {
|
|
7690
7898
|
const tried = [fullFilename, preflushFilename];
|
|
7691
7899
|
const hits = [];
|
|
7692
7900
|
const stalePreflushPaths = [];
|
|
7693
7901
|
for (const dir of logDirs) {
|
|
7694
|
-
const fullPath =
|
|
7695
|
-
if (
|
|
7902
|
+
const fullPath = join9(dir, fullFilename);
|
|
7903
|
+
if (existsSync12(fullPath)) {
|
|
7696
7904
|
hits.push({ path: fullPath, shape: "full", dir });
|
|
7697
|
-
const preflushSibling =
|
|
7698
|
-
if (
|
|
7905
|
+
const preflushSibling = join9(dir, preflushFilename);
|
|
7906
|
+
if (existsSync12(preflushSibling)) {
|
|
7699
7907
|
stalePreflushPaths.push(preflushSibling);
|
|
7700
7908
|
}
|
|
7701
7909
|
}
|
|
@@ -7704,8 +7912,8 @@ function resolveConversationLogPaths(fullFilename, preflushFilename, logDirs) {
|
|
|
7704
7912
|
return { hits, stalePreflushPaths, tried };
|
|
7705
7913
|
}
|
|
7706
7914
|
for (const dir of logDirs) {
|
|
7707
|
-
const preflushPath =
|
|
7708
|
-
if (
|
|
7915
|
+
const preflushPath = join9(dir, preflushFilename);
|
|
7916
|
+
if (existsSync12(preflushPath)) {
|
|
7709
7917
|
hits.push({ path: preflushPath, shape: "preflush", dir });
|
|
7710
7918
|
}
|
|
7711
7919
|
}
|
|
@@ -7736,8 +7944,8 @@ app13.get("/", async (c) => {
|
|
|
7736
7944
|
const filePath = resolve10(dir, safe);
|
|
7737
7945
|
searched.push(filePath);
|
|
7738
7946
|
try {
|
|
7739
|
-
const buffer =
|
|
7740
|
-
const onDiskBytes =
|
|
7947
|
+
const buffer = readFileSync11(filePath);
|
|
7948
|
+
const onDiskBytes = statSync6(filePath).size;
|
|
7741
7949
|
const headers = {
|
|
7742
7950
|
"Content-Type": "text/plain; charset=utf-8",
|
|
7743
7951
|
"Content-Length": String(buffer.byteLength)
|
|
@@ -7822,7 +8030,7 @@ app13.get("/", async (c) => {
|
|
|
7822
8030
|
try {
|
|
7823
8031
|
const filename = basename3(hit.path);
|
|
7824
8032
|
if (stalePreflushCount > 0 && !download) {
|
|
7825
|
-
const content =
|
|
8033
|
+
const content = readFileSync11(hit.path, "utf-8");
|
|
7826
8034
|
return c.json({
|
|
7827
8035
|
log: content,
|
|
7828
8036
|
filename,
|
|
@@ -7830,8 +8038,8 @@ app13.get("/", async (c) => {
|
|
|
7830
8038
|
warnings: stalePreflushPaths.map((path2) => ({ kind: "stale-preflush", path: path2 }))
|
|
7831
8039
|
});
|
|
7832
8040
|
}
|
|
7833
|
-
const buffer =
|
|
7834
|
-
const onDiskBytes =
|
|
8041
|
+
const buffer = readFileSync11(hit.path);
|
|
8042
|
+
const onDiskBytes = statSync6(hit.path).size;
|
|
7835
8043
|
const headers = {
|
|
7836
8044
|
"Content-Type": "text/plain; charset=utf-8",
|
|
7837
8045
|
"Content-Length": String(buffer.byteLength)
|
|
@@ -7864,19 +8072,19 @@ app13.get("/", async (c) => {
|
|
|
7864
8072
|
const seen = /* @__PURE__ */ new Set();
|
|
7865
8073
|
const logs = {};
|
|
7866
8074
|
for (const dir of logDirs) {
|
|
7867
|
-
if (!
|
|
8075
|
+
if (!existsSync13(dir)) continue;
|
|
7868
8076
|
let files;
|
|
7869
8077
|
try {
|
|
7870
|
-
files =
|
|
8078
|
+
files = readdirSync5(dir).filter((f) => f.endsWith(".log"));
|
|
7871
8079
|
} catch (err) {
|
|
7872
8080
|
const reason = err instanceof Error ? err.message : String(err);
|
|
7873
8081
|
console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
|
|
7874
8082
|
continue;
|
|
7875
8083
|
}
|
|
7876
|
-
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime:
|
|
8084
|
+
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync6(resolve10(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
|
|
7877
8085
|
seen.add(name);
|
|
7878
8086
|
try {
|
|
7879
|
-
const content =
|
|
8087
|
+
const content = readFileSync11(resolve10(dir, name));
|
|
7880
8088
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
7881
8089
|
logs[name] = tail.trim() || "(empty)";
|
|
7882
8090
|
} catch (err) {
|
|
@@ -7915,7 +8123,7 @@ var claude_info_default = app14;
|
|
|
7915
8123
|
|
|
7916
8124
|
// server/routes/admin/attachment.ts
|
|
7917
8125
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
7918
|
-
import { existsSync as
|
|
8126
|
+
import { existsSync as existsSync14 } from "fs";
|
|
7919
8127
|
import { resolve as resolve11 } from "path";
|
|
7920
8128
|
var app15 = new Hono();
|
|
7921
8129
|
app15.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
@@ -7929,11 +8137,11 @@ app15.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
7929
8137
|
return new Response("Not found", { status: 404 });
|
|
7930
8138
|
}
|
|
7931
8139
|
const dir = resolve11(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
7932
|
-
if (!
|
|
8140
|
+
if (!existsSync14(dir)) {
|
|
7933
8141
|
return new Response("Not found", { status: 404 });
|
|
7934
8142
|
}
|
|
7935
8143
|
const metaPath = resolve11(dir, `${attachmentId}.meta.json`);
|
|
7936
|
-
if (!
|
|
8144
|
+
if (!existsSync14(metaPath)) {
|
|
7937
8145
|
return new Response("Not found", { status: 404 });
|
|
7938
8146
|
}
|
|
7939
8147
|
let meta;
|
|
@@ -7961,23 +8169,23 @@ var attachment_default = app15;
|
|
|
7961
8169
|
|
|
7962
8170
|
// server/routes/admin/agents.ts
|
|
7963
8171
|
import { resolve as resolve12 } from "path";
|
|
7964
|
-
import { readdirSync as
|
|
8172
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync12, existsSync as existsSync15, rmSync } from "fs";
|
|
7965
8173
|
var app16 = new Hono();
|
|
7966
8174
|
app16.get("/", (c) => {
|
|
7967
8175
|
const account = resolveAccount();
|
|
7968
8176
|
if (!account) return c.json({ agents: [] });
|
|
7969
8177
|
const agentsDir = resolve12(account.accountDir, "agents");
|
|
7970
|
-
if (!
|
|
8178
|
+
if (!existsSync15(agentsDir)) return c.json({ agents: [] });
|
|
7971
8179
|
const agents = [];
|
|
7972
8180
|
try {
|
|
7973
|
-
const entries =
|
|
8181
|
+
const entries = readdirSync6(agentsDir, { withFileTypes: true });
|
|
7974
8182
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
7975
8183
|
if (!entry.isDirectory()) continue;
|
|
7976
8184
|
if (entry.name === "admin") continue;
|
|
7977
8185
|
const configPath2 = resolve12(agentsDir, entry.name, "config.json");
|
|
7978
|
-
if (!
|
|
8186
|
+
if (!existsSync15(configPath2)) continue;
|
|
7979
8187
|
try {
|
|
7980
|
-
const config = JSON.parse(
|
|
8188
|
+
const config = JSON.parse(readFileSync12(configPath2, "utf-8"));
|
|
7981
8189
|
agents.push({
|
|
7982
8190
|
slug: entry.name,
|
|
7983
8191
|
displayName: config.displayName ?? entry.name,
|
|
@@ -8004,7 +8212,7 @@ app16.delete("/:slug", async (c) => {
|
|
|
8004
8212
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
8005
8213
|
}
|
|
8006
8214
|
const agentDir = resolve12(account.accountDir, "agents", slug);
|
|
8007
|
-
if (!
|
|
8215
|
+
if (!existsSync15(agentDir)) {
|
|
8008
8216
|
return c.json({ error: "Agent not found" }, 404);
|
|
8009
8217
|
}
|
|
8010
8218
|
try {
|
|
@@ -8034,7 +8242,7 @@ app16.post("/:slug/project", async (c) => {
|
|
|
8034
8242
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
8035
8243
|
}
|
|
8036
8244
|
const agentDir = resolve12(account.accountDir, "agents", slug);
|
|
8037
|
-
if (!
|
|
8245
|
+
if (!existsSync15(agentDir)) {
|
|
8038
8246
|
return c.json({ error: "Agent not found on disk" }, 404);
|
|
8039
8247
|
}
|
|
8040
8248
|
try {
|
|
@@ -8050,7 +8258,7 @@ var agents_default = app16;
|
|
|
8050
8258
|
// server/routes/admin/sessions.ts
|
|
8051
8259
|
import crypto2 from "crypto";
|
|
8052
8260
|
import { resolve as resolvePath } from "path";
|
|
8053
|
-
import { appendFileSync as appendFileSync4, existsSync as
|
|
8261
|
+
import { appendFileSync as appendFileSync4, existsSync as existsSync16 } from "fs";
|
|
8054
8262
|
|
|
8055
8263
|
// app/lib/synthetic-marker.ts
|
|
8056
8264
|
var CLOUDFLARE_MARKER_PREFIX = "Cloudflare setup completed (actionId: ";
|
|
@@ -8070,7 +8278,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, conversationId
|
|
|
8070
8278
|
let reason = null;
|
|
8071
8279
|
if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
|
|
8072
8280
|
else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
|
|
8073
|
-
else if (!
|
|
8281
|
+
else if (!existsSync16(a.storagePath)) reason = "missing-file";
|
|
8074
8282
|
if (reason) {
|
|
8075
8283
|
invalid++;
|
|
8076
8284
|
try {
|
|
@@ -8641,7 +8849,7 @@ var events_default = app20;
|
|
|
8641
8849
|
// server/routes/admin/cloudflare.ts
|
|
8642
8850
|
import { homedir } from "os";
|
|
8643
8851
|
import { resolve as resolve14 } from "path";
|
|
8644
|
-
import { readFileSync as
|
|
8852
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
8645
8853
|
|
|
8646
8854
|
// app/lib/dns-label.ts
|
|
8647
8855
|
var VALID_LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
@@ -8657,14 +8865,14 @@ function isValidDomain(value) {
|
|
|
8657
8865
|
}
|
|
8658
8866
|
|
|
8659
8867
|
// app/lib/alias-domains.ts
|
|
8660
|
-
import { existsSync as
|
|
8661
|
-
import { dirname as
|
|
8868
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync6, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "fs";
|
|
8869
|
+
import { dirname as dirname5 } from "path";
|
|
8662
8870
|
import { resolve as resolve13 } from "path";
|
|
8663
8871
|
var ALIAS_DOMAINS_PATH = resolve13(MAXY_DIR, "alias-domains.json");
|
|
8664
8872
|
function readExisting() {
|
|
8665
|
-
if (!
|
|
8873
|
+
if (!existsSync17(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
|
|
8666
8874
|
try {
|
|
8667
|
-
const parsed = JSON.parse(
|
|
8875
|
+
const parsed = JSON.parse(readFileSync13(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
8668
8876
|
if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
|
|
8669
8877
|
return new Set(parsed.filter((h) => typeof h === "string"));
|
|
8670
8878
|
} catch {
|
|
@@ -8675,8 +8883,8 @@ function addAliasDomain(hostname2) {
|
|
|
8675
8883
|
const existing = readExisting();
|
|
8676
8884
|
if (existing.has(hostname2)) return;
|
|
8677
8885
|
existing.add(hostname2);
|
|
8678
|
-
|
|
8679
|
-
|
|
8886
|
+
mkdirSync6(dirname5(ALIAS_DOMAINS_PATH), { recursive: true });
|
|
8887
|
+
writeFileSync7(ALIAS_DOMAINS_PATH, JSON.stringify([...existing], null, 2) + "\n", "utf-8");
|
|
8680
8888
|
}
|
|
8681
8889
|
|
|
8682
8890
|
// app/lib/cloudflare-setup-types.ts
|
|
@@ -8691,7 +8899,7 @@ function loadBrandInfo() {
|
|
|
8691
8899
|
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
|
|
8692
8900
|
const brandPath = resolve14(platformRoot2, "config", "brand.json");
|
|
8693
8901
|
try {
|
|
8694
|
-
const parsed = JSON.parse(
|
|
8902
|
+
const parsed = JSON.parse(readFileSync14(brandPath, "utf-8"));
|
|
8695
8903
|
const hostname2 = typeof parsed.hostname === "string" && parsed.hostname ? parsed.hostname : "maxy";
|
|
8696
8904
|
const configDir2 = typeof parsed.configDir === "string" && parsed.configDir ? parsed.configDir : ".maxy";
|
|
8697
8905
|
return { hostname: hostname2, configDir: configDir2 };
|
|
@@ -8905,8 +9113,8 @@ app21.get("/tunnels", requireAdminSession, async (c) => {
|
|
|
8905
9113
|
if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
|
|
8906
9114
|
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
8907
9115
|
const certPath = resolve14(homedir(), brand.configDir, "cloudflared", "cert.pem");
|
|
8908
|
-
const { existsSync:
|
|
8909
|
-
if (!
|
|
9116
|
+
const { existsSync: existsSync24 } = await import("fs");
|
|
9117
|
+
if (!existsSync24(certPath)) {
|
|
8910
9118
|
return err("cert", `Cloudflare origin certificate is not on disk yet (${certPath}). Complete the Cloudflare login first by submitting the form once \u2014 the OAuth flow writes cert.pem.`);
|
|
8911
9119
|
}
|
|
8912
9120
|
const result = await runFormSpawn({
|
|
@@ -9196,7 +9404,7 @@ var cloudflare_default = app21;
|
|
|
9196
9404
|
import { createReadStream as createReadStream3 } from "fs";
|
|
9197
9405
|
import { readdir as readdir2, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
|
|
9198
9406
|
import { realpathSync as realpathSync4 } from "fs";
|
|
9199
|
-
import { basename as basename4, dirname as
|
|
9407
|
+
import { basename as basename4, dirname as dirname6, join as join10, resolve as resolve16, sep as sep2 } from "path";
|
|
9200
9408
|
import { Readable as Readable2 } from "stream";
|
|
9201
9409
|
|
|
9202
9410
|
// app/lib/data-path.ts
|
|
@@ -9554,7 +9762,7 @@ async function cascadeDeleteDocument(params) {
|
|
|
9554
9762
|
var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
9555
9763
|
async function readMeta(absDir, baseName) {
|
|
9556
9764
|
try {
|
|
9557
|
-
const raw = await readFile4(
|
|
9765
|
+
const raw = await readFile4(join10(absDir, `${baseName}.meta.json`), "utf8");
|
|
9558
9766
|
const parsed = JSON.parse(raw);
|
|
9559
9767
|
if (typeof parsed?.filename === "string") {
|
|
9560
9768
|
return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
|
|
@@ -9592,7 +9800,7 @@ async function readAccountNames() {
|
|
|
9592
9800
|
}
|
|
9593
9801
|
async function enrich(absolute, entry, accountNames) {
|
|
9594
9802
|
if (entry.kind === "directory" && UUID_RE4.test(entry.name)) {
|
|
9595
|
-
const meta = await readMeta(
|
|
9803
|
+
const meta = await readMeta(join10(absolute, entry.name), entry.name);
|
|
9596
9804
|
if (meta?.filename) {
|
|
9597
9805
|
entry.displayName = meta.filename;
|
|
9598
9806
|
entry.mimeType = meta.mimeType;
|
|
@@ -9651,7 +9859,7 @@ app22.get("/", requireAdminSession, async (c) => {
|
|
|
9651
9859
|
continue;
|
|
9652
9860
|
}
|
|
9653
9861
|
try {
|
|
9654
|
-
const entryPath =
|
|
9862
|
+
const entryPath = join10(absolute, name);
|
|
9655
9863
|
const s = await stat4(entryPath);
|
|
9656
9864
|
entries.push({
|
|
9657
9865
|
name,
|
|
@@ -9824,7 +10032,7 @@ app22.delete("/", requireAdminSession, async (c) => {
|
|
|
9824
10032
|
}
|
|
9825
10033
|
const dot = base.lastIndexOf(".");
|
|
9826
10034
|
const stem = dot === -1 ? base : base.slice(0, dot);
|
|
9827
|
-
const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ?
|
|
10035
|
+
const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ? join10(dirname6(absolute), `${stem}.meta.json`) : null;
|
|
9828
10036
|
await unlink2(absolute);
|
|
9829
10037
|
if (sidecarPath) {
|
|
9830
10038
|
try {
|
|
@@ -11446,7 +11654,7 @@ var adherence_default = app30;
|
|
|
11446
11654
|
import neo4j3 from "neo4j-driver";
|
|
11447
11655
|
import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
|
|
11448
11656
|
import { resolve as resolve17, relative as relative2, isAbsolute } from "path";
|
|
11449
|
-
import { existsSync as
|
|
11657
|
+
import { existsSync as existsSync18 } from "fs";
|
|
11450
11658
|
var LIMIT = 50;
|
|
11451
11659
|
var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
|
|
11452
11660
|
var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
|
|
@@ -11594,7 +11802,7 @@ async function fetchAgentTemplateRows(accountDir) {
|
|
|
11594
11802
|
async function unionSpecialistFilenames(overrideDir, bundledDir) {
|
|
11595
11803
|
const names = /* @__PURE__ */ new Set();
|
|
11596
11804
|
for (const dir of [overrideDir, bundledDir]) {
|
|
11597
|
-
if (!
|
|
11805
|
+
if (!existsSync18(dir)) continue;
|
|
11598
11806
|
try {
|
|
11599
11807
|
const entries = await readdir3(dir);
|
|
11600
11808
|
for (const entry of entries) {
|
|
@@ -11609,7 +11817,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
|
|
|
11609
11817
|
}
|
|
11610
11818
|
async function readAgentTemplateRow(inp) {
|
|
11611
11819
|
let chosenPath = null;
|
|
11612
|
-
if (
|
|
11820
|
+
if (existsSync18(inp.overridePath)) {
|
|
11613
11821
|
try {
|
|
11614
11822
|
validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
|
|
11615
11823
|
chosenPath = inp.overridePath;
|
|
@@ -11620,7 +11828,7 @@ async function readAgentTemplateRow(inp) {
|
|
|
11620
11828
|
);
|
|
11621
11829
|
return null;
|
|
11622
11830
|
}
|
|
11623
|
-
} else if (
|
|
11831
|
+
} else if (existsSync18(inp.bundledPath)) {
|
|
11624
11832
|
if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
|
|
11625
11833
|
console.error(
|
|
11626
11834
|
`[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
|
|
@@ -11662,7 +11870,7 @@ var sidebar_artefacts_default = app31;
|
|
|
11662
11870
|
// server/routes/admin/sidebar-artefact-save.ts
|
|
11663
11871
|
import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
|
|
11664
11872
|
import { resolve as resolve18 } from "path";
|
|
11665
|
-
import { existsSync as
|
|
11873
|
+
import { existsSync as existsSync19 } from "fs";
|
|
11666
11874
|
var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
|
|
11667
11875
|
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
11668
11876
|
var app32 = new Hono();
|
|
@@ -11726,7 +11934,7 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
11726
11934
|
}
|
|
11727
11935
|
if (UUID_RE5.test(id)) {
|
|
11728
11936
|
const dir = resolve18(ATTACHMENTS_ROOT, accountId, id);
|
|
11729
|
-
if (!
|
|
11937
|
+
if (!existsSync19(dir)) {
|
|
11730
11938
|
return { kind: "reject", status: 400, reason: "not-found" };
|
|
11731
11939
|
}
|
|
11732
11940
|
try {
|
|
@@ -11750,7 +11958,7 @@ var sidebar_artefact_save_default = app32;
|
|
|
11750
11958
|
|
|
11751
11959
|
// server/routes/admin/sidebar-artefact-content.ts
|
|
11752
11960
|
import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
|
|
11753
|
-
import { existsSync as
|
|
11961
|
+
import { existsSync as existsSync20 } from "fs";
|
|
11754
11962
|
import { resolve as resolve19 } from "path";
|
|
11755
11963
|
var UUID_RE6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
11756
11964
|
var app33 = new Hono();
|
|
@@ -11764,7 +11972,7 @@ app33.get("/", requireAdminSession, async (c) => {
|
|
|
11764
11972
|
return new Response("Not found", { status: 404 });
|
|
11765
11973
|
}
|
|
11766
11974
|
const dir = resolve19(ATTACHMENTS_ROOT, accountId, id);
|
|
11767
|
-
if (!
|
|
11975
|
+
if (!existsSync20(dir)) {
|
|
11768
11976
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
11769
11977
|
return new Response("Not found", { status: 404 });
|
|
11770
11978
|
}
|
|
@@ -11798,14 +12006,14 @@ app33.get("/", requireAdminSession, async (c) => {
|
|
|
11798
12006
|
var sidebar_artefact_content_default = app33;
|
|
11799
12007
|
|
|
11800
12008
|
// server/routes/admin/health.ts
|
|
11801
|
-
import { existsSync as
|
|
11802
|
-
import { resolve as resolve20, join as
|
|
12009
|
+
import { existsSync as existsSync21, readFileSync as readFileSync15 } from "fs";
|
|
12010
|
+
import { resolve as resolve20, join as join11 } from "path";
|
|
11803
12011
|
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
|
|
11804
12012
|
var brandHostname = "maxy";
|
|
11805
|
-
var brandJsonPath =
|
|
11806
|
-
if (
|
|
12013
|
+
var brandJsonPath = join11(PLATFORM_ROOT7, "config", "brand.json");
|
|
12014
|
+
if (existsSync21(brandJsonPath)) {
|
|
11807
12015
|
try {
|
|
11808
|
-
const brand = JSON.parse(
|
|
12016
|
+
const brand = JSON.parse(readFileSync15(brandJsonPath, "utf-8"));
|
|
11809
12017
|
if (brand.hostname) brandHostname = brand.hostname;
|
|
11810
12018
|
} catch {
|
|
11811
12019
|
}
|
|
@@ -11814,8 +12022,8 @@ var VERSION_FILE = resolve20(PLATFORM_ROOT7, `config/.${brandHostname}-version`)
|
|
|
11814
12022
|
var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
11815
12023
|
var PROBE_TIMEOUT_MS = 1e3;
|
|
11816
12024
|
function readVersion() {
|
|
11817
|
-
if (!
|
|
11818
|
-
return
|
|
12025
|
+
if (!existsSync21(VERSION_FILE)) return "unknown";
|
|
12026
|
+
return readFileSync15(VERSION_FILE, "utf-8").trim() || "unknown";
|
|
11819
12027
|
}
|
|
11820
12028
|
async function probeConversationDb() {
|
|
11821
12029
|
let session;
|
|
@@ -11895,7 +12103,7 @@ app35.route("/health-brand", health_default2);
|
|
|
11895
12103
|
var admin_default = app35;
|
|
11896
12104
|
|
|
11897
12105
|
// server/routes/sites.ts
|
|
11898
|
-
import { existsSync as
|
|
12106
|
+
import { existsSync as existsSync22, readFileSync as readFileSync16, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
|
|
11899
12107
|
import { resolve as resolve21 } from "path";
|
|
11900
12108
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
11901
12109
|
var MIME = {
|
|
@@ -11962,7 +12170,7 @@ app36.get("/:rel{.*}", (c) => {
|
|
|
11962
12170
|
}
|
|
11963
12171
|
let stat7;
|
|
11964
12172
|
try {
|
|
11965
|
-
stat7 =
|
|
12173
|
+
stat7 = existsSync22(filePath) ? statSync7(filePath) : null;
|
|
11966
12174
|
} catch {
|
|
11967
12175
|
stat7 = null;
|
|
11968
12176
|
}
|
|
@@ -11975,7 +12183,7 @@ app36.get("/:rel{.*}", (c) => {
|
|
|
11975
12183
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
11976
12184
|
return c.text("Forbidden", 403);
|
|
11977
12185
|
}
|
|
11978
|
-
if (!
|
|
12186
|
+
if (!existsSync22(filePath)) {
|
|
11979
12187
|
console.error(`[sites] not-found path=${reqPath} status=404`);
|
|
11980
12188
|
return c.text("Not found", 404);
|
|
11981
12189
|
}
|
|
@@ -11994,7 +12202,7 @@ app36.get("/:rel{.*}", (c) => {
|
|
|
11994
12202
|
}
|
|
11995
12203
|
let body;
|
|
11996
12204
|
try {
|
|
11997
|
-
body =
|
|
12205
|
+
body = readFileSync16(realPath);
|
|
11998
12206
|
} catch (err) {
|
|
11999
12207
|
const code = err?.code;
|
|
12000
12208
|
if (code === "EISDIR") {
|
|
@@ -12126,14 +12334,14 @@ function clientFrom(c) {
|
|
|
12126
12334
|
);
|
|
12127
12335
|
}
|
|
12128
12336
|
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
12129
|
-
var BRAND_JSON_PATH = PLATFORM_ROOT8 ?
|
|
12337
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join12(PLATFORM_ROOT8, "config", "brand.json") : "";
|
|
12130
12338
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
|
|
12131
|
-
if (BRAND_JSON_PATH && !
|
|
12339
|
+
if (BRAND_JSON_PATH && !existsSync23(BRAND_JSON_PATH)) {
|
|
12132
12340
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
12133
12341
|
}
|
|
12134
|
-
if (BRAND_JSON_PATH &&
|
|
12342
|
+
if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
|
|
12135
12343
|
try {
|
|
12136
|
-
const parsed = JSON.parse(
|
|
12344
|
+
const parsed = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
|
|
12137
12345
|
BRAND = { ...BRAND, ...parsed };
|
|
12138
12346
|
} catch (err) {
|
|
12139
12347
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -12152,11 +12360,11 @@ var brandLoginOpts = {
|
|
|
12152
12360
|
bodyFont: BRAND.defaultFonts?.body,
|
|
12153
12361
|
logoContainsName: !!BRAND.logoContainsName
|
|
12154
12362
|
};
|
|
12155
|
-
var ALIAS_DOMAINS_PATH2 =
|
|
12363
|
+
var ALIAS_DOMAINS_PATH2 = join12(homedir2(), BRAND.configDir, "alias-domains.json");
|
|
12156
12364
|
function loadAliasDomains() {
|
|
12157
12365
|
try {
|
|
12158
|
-
if (!
|
|
12159
|
-
const parsed = JSON.parse(
|
|
12366
|
+
if (!existsSync23(ALIAS_DOMAINS_PATH2)) return null;
|
|
12367
|
+
const parsed = JSON.parse(readFileSync17(ALIAS_DOMAINS_PATH2, "utf-8"));
|
|
12160
12368
|
if (!Array.isArray(parsed)) {
|
|
12161
12369
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
12162
12370
|
return null;
|
|
@@ -12502,14 +12710,14 @@ app37.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
12502
12710
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
12503
12711
|
return c.text("Forbidden", 403);
|
|
12504
12712
|
}
|
|
12505
|
-
if (!
|
|
12713
|
+
if (!existsSync23(filePath)) {
|
|
12506
12714
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
12507
12715
|
return c.text("Not found", 404);
|
|
12508
12716
|
}
|
|
12509
12717
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
12510
12718
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
12511
12719
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
12512
|
-
const body =
|
|
12720
|
+
const body = readFileSync17(filePath);
|
|
12513
12721
|
return c.body(body, 200, {
|
|
12514
12722
|
"Content-Type": contentType,
|
|
12515
12723
|
"Cache-Control": "public, max-age=3600"
|
|
@@ -12532,14 +12740,14 @@ app37.get("/generated/:filename", (c) => {
|
|
|
12532
12740
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
12533
12741
|
return c.text("Forbidden", 403);
|
|
12534
12742
|
}
|
|
12535
|
-
if (!
|
|
12743
|
+
if (!existsSync23(filePath)) {
|
|
12536
12744
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
12537
12745
|
return c.text("Not found", 404);
|
|
12538
12746
|
}
|
|
12539
12747
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
12540
12748
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
12541
12749
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
12542
|
-
const body =
|
|
12750
|
+
const body = readFileSync17(filePath);
|
|
12543
12751
|
return c.body(body, 200, {
|
|
12544
12752
|
"Content-Type": contentType,
|
|
12545
12753
|
"Cache-Control": "public, max-age=86400"
|
|
@@ -12549,9 +12757,9 @@ app37.route("/sites", sites_default);
|
|
|
12549
12757
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
12550
12758
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
12551
12759
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
12552
|
-
if (BRAND_JSON_PATH &&
|
|
12760
|
+
if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
|
|
12553
12761
|
try {
|
|
12554
|
-
const fullBrand = JSON.parse(
|
|
12762
|
+
const fullBrand = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
|
|
12555
12763
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
12556
12764
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
12557
12765
|
} catch {
|
|
@@ -12568,9 +12776,9 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
12568
12776
|
function readInstalledVersion() {
|
|
12569
12777
|
try {
|
|
12570
12778
|
if (!PLATFORM_ROOT8) return "unknown";
|
|
12571
|
-
const versionFile =
|
|
12572
|
-
if (!
|
|
12573
|
-
const content =
|
|
12779
|
+
const versionFile = join12(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
|
|
12780
|
+
if (!existsSync23(versionFile)) return "unknown";
|
|
12781
|
+
const content = readFileSync17(versionFile, "utf-8").trim();
|
|
12574
12782
|
return content || "unknown";
|
|
12575
12783
|
} catch {
|
|
12576
12784
|
return "unknown";
|
|
@@ -12611,7 +12819,7 @@ var clientErrorReporterScript = `<script>
|
|
|
12611
12819
|
function cachedHtml(file) {
|
|
12612
12820
|
let html = htmlCache.get(file);
|
|
12613
12821
|
if (!html) {
|
|
12614
|
-
html =
|
|
12822
|
+
html = readFileSync17(resolve22(process.cwd(), "public", file), "utf-8");
|
|
12615
12823
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
12616
12824
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
12617
12825
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -12627,26 +12835,26 @@ ${clientErrorReporterScript}
|
|
|
12627
12835
|
}
|
|
12628
12836
|
var brandedHtmlCache = /* @__PURE__ */ new Map();
|
|
12629
12837
|
function loadBrandingCache(agentSlug) {
|
|
12630
|
-
const configDir2 =
|
|
12838
|
+
const configDir2 = join12(homedir2(), BRAND.configDir);
|
|
12631
12839
|
try {
|
|
12632
|
-
const accountJsonPath =
|
|
12633
|
-
if (!
|
|
12634
|
-
const account = JSON.parse(
|
|
12840
|
+
const accountJsonPath = join12(configDir2, "account.json");
|
|
12841
|
+
if (!existsSync23(accountJsonPath)) return null;
|
|
12842
|
+
const account = JSON.parse(readFileSync17(accountJsonPath, "utf-8"));
|
|
12635
12843
|
const accountId = account.accountId;
|
|
12636
12844
|
if (!accountId) return null;
|
|
12637
|
-
const cachePath =
|
|
12638
|
-
if (!
|
|
12639
|
-
return JSON.parse(
|
|
12845
|
+
const cachePath = join12(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
12846
|
+
if (!existsSync23(cachePath)) return null;
|
|
12847
|
+
return JSON.parse(readFileSync17(cachePath, "utf-8"));
|
|
12640
12848
|
} catch {
|
|
12641
12849
|
return null;
|
|
12642
12850
|
}
|
|
12643
12851
|
}
|
|
12644
12852
|
function resolveDefaultSlug() {
|
|
12645
12853
|
try {
|
|
12646
|
-
const configDir2 =
|
|
12647
|
-
const accountJsonPath =
|
|
12648
|
-
if (!
|
|
12649
|
-
const account = JSON.parse(
|
|
12854
|
+
const configDir2 = join12(homedir2(), BRAND.configDir);
|
|
12855
|
+
const accountJsonPath = join12(configDir2, "account.json");
|
|
12856
|
+
if (!existsSync23(accountJsonPath)) return null;
|
|
12857
|
+
const account = JSON.parse(readFileSync17(accountJsonPath, "utf-8"));
|
|
12650
12858
|
return account.defaultAgent || null;
|
|
12651
12859
|
} catch {
|
|
12652
12860
|
return null;
|
|
@@ -12719,7 +12927,7 @@ app37.use("/vnc-popout.html", logViewerFetch);
|
|
|
12719
12927
|
app37.get("/vnc-popout.html", (c) => {
|
|
12720
12928
|
let html = htmlCache.get("vnc-popout.html");
|
|
12721
12929
|
if (!html) {
|
|
12722
|
-
html =
|
|
12930
|
+
html = readFileSync17(resolve22(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
12723
12931
|
const name = escapeHtml(BRAND.productName);
|
|
12724
12932
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
12725
12933
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -12777,6 +12985,7 @@ var port = parseInt(process.env.MAXY_UI_INTERNAL_PORT ?? process.env.PORT ?? "19
|
|
|
12777
12985
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
12778
12986
|
var httpServer = serve({ fetch: app37.fetch, port, hostname });
|
|
12779
12987
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
12988
|
+
console.log("[boot] auth-mode summary: oauth=8 api-key=1 (api-key consumer: invokePublicAgent only)");
|
|
12780
12989
|
var SUBAPP_MANIFEST = [
|
|
12781
12990
|
{ prefix: "/api/health", file: "server/routes/health.ts", subapp: health_default },
|
|
12782
12991
|
{ prefix: "/api/session", file: "server/routes/session.ts", subapp: session_default },
|
|
@@ -12806,11 +13015,20 @@ try {
|
|
|
12806
13015
|
} catch (err) {
|
|
12807
13016
|
console.error(`[route-shadow] introspection unavailable: ${err instanceof Error ? err.message : String(err)}`);
|
|
12808
13017
|
}
|
|
13018
|
+
try {
|
|
13019
|
+
checkAdminAuthInvariant({
|
|
13020
|
+
usersFile: USERS_FILE,
|
|
13021
|
+
accountsDir: ACCOUNTS_DIR,
|
|
13022
|
+
tag: "admin-invariant"
|
|
13023
|
+
});
|
|
13024
|
+
} catch (err) {
|
|
13025
|
+
console.error(`[admin-invariant] check threw \u2014 proceeding with boot: ${err instanceof Error ? err.message : String(err)}`);
|
|
13026
|
+
}
|
|
12809
13027
|
(async () => {
|
|
12810
13028
|
try {
|
|
12811
13029
|
let userId = "";
|
|
12812
|
-
if (
|
|
12813
|
-
const users = JSON.parse(
|
|
13030
|
+
if (existsSync23(USERS_FILE)) {
|
|
13031
|
+
const users = JSON.parse(readFileSync17(USERS_FILE, "utf-8").trim() || "[]");
|
|
12814
13032
|
userId = users[0]?.userId ?? "";
|
|
12815
13033
|
}
|
|
12816
13034
|
await backfillNullUserIdConversations(userId);
|
|
@@ -12843,7 +13061,7 @@ autoDeliverPremiumPlugins(bootEntitlement?.purchasedPlugins ?? void 0);
|
|
|
12843
13061
|
(async () => {
|
|
12844
13062
|
if (!bootAccount) return;
|
|
12845
13063
|
try {
|
|
12846
|
-
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-
|
|
13064
|
+
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-XCUO4N74.js");
|
|
12847
13065
|
const result = await recoverRunningCloudflareTasks(
|
|
12848
13066
|
bootAccount.accountId,
|
|
12849
13067
|
configDirForWhatsApp,
|
|
@@ -12893,7 +13111,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
12893
13111
|
}
|
|
12894
13112
|
init({
|
|
12895
13113
|
configDir: configDirForWhatsApp,
|
|
12896
|
-
platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ??
|
|
13114
|
+
platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ?? join12(__dirname, "..")),
|
|
12897
13115
|
accountConfig: bootAccountConfig,
|
|
12898
13116
|
onMessage: async (msg) => {
|
|
12899
13117
|
try {
|