@rubytech/create-realagent 1.0.832 → 1.0.834
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/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 +215 -43
- package/payload/platform/plugins/memory/bin/conversation-archive-ingest.sh +7 -2
- 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/tools/__tests__/memory-ingest.test.js +9 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +24 -7
- 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 +47 -11
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +45 -8
- package/payload/platform/scripts/lib/resolve-account-dir.sh +3 -1
- package/payload/platform/scripts/migrate-import.sh +3 -1
- package/payload/platform/scripts/seed-neo4j.sh +13 -3
- package/payload/server/chunk-CRAIGEXY.js +654 -0
- package/payload/server/chunk-GK4WHM3H.js +9961 -0
- package/payload/server/chunk-I2NOLBQA.js +2123 -0
- package/payload/server/chunk-IVTESKFR.js +9961 -0
- package/payload/server/chunk-KD3XP4IK.js +1116 -0
- package/payload/server/chunk-KKGGT5RH.js +654 -0
- package/payload/server/chunk-MRJGG6CS.js +2124 -0
- package/payload/server/chunk-OJZPS4BL.js +367 -0
- package/payload/server/chunk-ZVW5XKPU.js +1116 -0
- package/payload/server/client-pool-FM3YJWV5.js +32 -0
- package/payload/server/client-pool-J5BCVVI2.js +32 -0
- package/payload/server/cloudflare-task-tracker-FSPEJOTH.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-5AN2U3YO.js +664 -0
- package/payload/server/neo4j-migrations-XP7XDVPX.js +664 -0
- package/payload/server/public/assets/{Checkbox-CTGhpDKq.js → Checkbox-Bq6ORjz2.js} +1 -1
- package/payload/server/public/assets/admin-CstEkw-G.js +352 -0
- package/payload/server/public/assets/data-DwZZ7qbH.js +1 -0
- package/payload/server/public/assets/graph-DceEv42K.js +1 -0
- package/payload/server/public/assets/{jsx-runtime-D4WovFYk.css → jsx-runtime-DidQeNoZ.css} +1 -1
- package/payload/server/public/assets/page-Bpi_jPw6.js +50 -0
- package/payload/server/public/assets/{page-DkBfWy4C.js → page-CFWoVkgV.js} +1 -1
- package/payload/server/public/assets/{public-BdVIVpv8.js → public-BWMwq5Jj.js} +1 -1
- package/payload/server/public/assets/{useAdminFetch-DmHu0oCx.js → useAdminFetch-B93ig7ef.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-CSc_hxjV.js → useVoiceRecorder-Cb0nAtOo.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +376 -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/public/assets/admin-BNwPsMhJ.js +0 -352
- package/payload/server/public/assets/data-Y77FLKjs.js +0 -1
- package/payload/server/public/assets/graph-N_Bw-8oT.js +0 -1
- package/payload/server/public/assets/page-BKLGP-th.js +0 -50
- /package/payload/server/public/assets/{jsx-runtime-DkaAusaX.js → jsx-runtime-DH5S-MwB.js} +0 -0
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-GK4WHM3H.js";
|
|
55
49
|
import {
|
|
56
50
|
agentLogStream,
|
|
57
51
|
clearSessionHistory,
|
|
@@ -79,10 +73,16 @@ import {
|
|
|
79
73
|
sigtermFlushStreamLogs,
|
|
80
74
|
unregisterSession,
|
|
81
75
|
validateSession
|
|
82
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-ZVW5XKPU.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
87
|
hasStubAccountDir,
|
|
88
88
|
resolveAccount,
|
|
@@ -90,7 +90,7 @@ import {
|
|
|
90
90
|
resolveDefaultAgentSlug,
|
|
91
91
|
resolveUserAccounts,
|
|
92
92
|
validateAgentSlug
|
|
93
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-OJZPS4BL.js";
|
|
94
94
|
import {
|
|
95
95
|
CLOUDFLARE_TASK_DIAGNOSTICS,
|
|
96
96
|
appendCloudflareSteps,
|
|
@@ -98,7 +98,7 @@ import {
|
|
|
98
98
|
openCloudflareTask,
|
|
99
99
|
readTunnelState,
|
|
100
100
|
resolveUnitGoneVerdict
|
|
101
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-KKGGT5RH.js";
|
|
102
102
|
import {
|
|
103
103
|
GREETING_DIRECTIVE,
|
|
104
104
|
HAIKU_MODEL,
|
|
@@ -130,7 +130,7 @@ import {
|
|
|
130
130
|
verifyAndGetConversationUpdatedAt,
|
|
131
131
|
verifyConversationOwnership,
|
|
132
132
|
writeAdminUserAndPerson
|
|
133
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-MRJGG6CS.js";
|
|
134
134
|
|
|
135
135
|
// ../lib/graph-trash/dist/index.js
|
|
136
136
|
var require_dist = __commonJS({
|
|
@@ -629,8 +629,8 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
629
629
|
};
|
|
630
630
|
|
|
631
631
|
// server/index.ts
|
|
632
|
-
import { readFileSync as
|
|
633
|
-
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";
|
|
634
634
|
import { homedir as homedir2 } from "os";
|
|
635
635
|
|
|
636
636
|
// app/lib/agent-slug-pattern.ts
|
|
@@ -6392,16 +6392,164 @@ var whatsapp_default = app7;
|
|
|
6392
6392
|
|
|
6393
6393
|
// server/routes/onboarding.ts
|
|
6394
6394
|
import { spawn, execFileSync } from "child_process";
|
|
6395
|
-
import { openSync, closeSync, writeFileSync as
|
|
6396
|
-
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";
|
|
6397
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
|
|
6398
6546
|
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
6399
6547
|
function hashPin(pin) {
|
|
6400
6548
|
return createHash("sha256").update(pin).digest("hex");
|
|
6401
6549
|
}
|
|
6402
6550
|
function readUsersFile() {
|
|
6403
|
-
if (!
|
|
6404
|
-
const raw =
|
|
6551
|
+
if (!existsSync9(USERS_FILE)) return null;
|
|
6552
|
+
const raw = readFileSync9(USERS_FILE, "utf-8").trim();
|
|
6405
6553
|
if (!raw) return [];
|
|
6406
6554
|
return JSON.parse(raw);
|
|
6407
6555
|
}
|
|
@@ -6467,7 +6615,7 @@ app8.post("/claude-auth", async (c) => {
|
|
|
6467
6615
|
if (!vncReady) return c.json({ error: "VNC display failed to start" }, 500);
|
|
6468
6616
|
}
|
|
6469
6617
|
await ensureCdp(transport);
|
|
6470
|
-
|
|
6618
|
+
writeFileSync5(logPath("claude-auth"), "");
|
|
6471
6619
|
const chromiumWrapper = writeChromiumWrapper();
|
|
6472
6620
|
const x11Env = buildX11Env(chromiumWrapper, transport);
|
|
6473
6621
|
vncLog("claude-auth", { action: "start", transport });
|
|
@@ -6528,36 +6676,41 @@ app8.post("/set-pin", async (c) => {
|
|
|
6528
6676
|
} else {
|
|
6529
6677
|
console.log(`[set-pin] minted new userId=${userId.slice(0, 8)}\u2026 (first-time install)`);
|
|
6530
6678
|
}
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
}
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
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);
|
|
6561
6714
|
}
|
|
6562
6715
|
return c.json({ ok: true });
|
|
6563
6716
|
});
|
|
@@ -6590,7 +6743,7 @@ app8.delete("/set-pin", async (c) => {
|
|
|
6590
6743
|
unlinkSync(USERS_FILE);
|
|
6591
6744
|
console.log(`[set-pin] cleared users.json (last entry removed): userId=${matchedUser.userId.slice(0, 8)}\u2026`);
|
|
6592
6745
|
} else {
|
|
6593
|
-
|
|
6746
|
+
writeFileSync5(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
|
|
6594
6747
|
console.log(`[set-pin] removed entry from users.json: userId=${matchedUser.userId.slice(0, 8)}\u2026 remaining=${remaining.length}`);
|
|
6595
6748
|
}
|
|
6596
6749
|
return c.json({ ok: true });
|
|
@@ -6610,9 +6763,9 @@ app8.post("/skip", async (c) => {
|
|
|
6610
6763
|
const { accountId, accountDir } = account;
|
|
6611
6764
|
let agentName = "Maxy";
|
|
6612
6765
|
const brandPath = PLATFORM_ROOT5 ? resolve8(PLATFORM_ROOT5, "config", "brand.json") : "";
|
|
6613
|
-
if (brandPath &&
|
|
6766
|
+
if (brandPath && existsSync9(brandPath)) {
|
|
6614
6767
|
try {
|
|
6615
|
-
const brand = JSON.parse(
|
|
6768
|
+
const brand = JSON.parse(readFileSync9(brandPath, "utf-8"));
|
|
6616
6769
|
if (brand.productName) agentName = brand.productName;
|
|
6617
6770
|
} catch (err) {
|
|
6618
6771
|
console.error(`[onboarding-skip] brand.json read failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -6620,8 +6773,8 @@ app8.post("/skip", async (c) => {
|
|
|
6620
6773
|
}
|
|
6621
6774
|
const soulPath = resolve8(accountDir, "agents", "admin", "SOUL.md");
|
|
6622
6775
|
try {
|
|
6623
|
-
|
|
6624
|
-
|
|
6776
|
+
mkdirSync4(dirname3(soulPath), { recursive: true });
|
|
6777
|
+
writeFileSync5(soulPath, `You are ${agentName}, an AI operations manager.
|
|
6625
6778
|
`);
|
|
6626
6779
|
console.log(`[onboarding-skip] wrote SOUL.md: ${soulPath}`);
|
|
6627
6780
|
} catch (err) {
|
|
@@ -6665,9 +6818,9 @@ app8.post("/skip", async (c) => {
|
|
|
6665
6818
|
var onboarding_default = app8;
|
|
6666
6819
|
|
|
6667
6820
|
// server/routes/client-error.ts
|
|
6668
|
-
import { appendFileSync, existsSync as
|
|
6669
|
-
import { join as
|
|
6670
|
-
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");
|
|
6671
6824
|
var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
6672
6825
|
var MAX_BODY_SIZE = 8 * 1024;
|
|
6673
6826
|
var MAX_STACK_LEN = 2e3;
|
|
@@ -6710,10 +6863,10 @@ function stackHead(stack) {
|
|
|
6710
6863
|
}
|
|
6711
6864
|
function rotateIfNeeded() {
|
|
6712
6865
|
try {
|
|
6713
|
-
if (!
|
|
6714
|
-
const stats =
|
|
6866
|
+
if (!existsSync10(CLIENT_ERRORS_LOG)) return;
|
|
6867
|
+
const stats = statSync3(CLIENT_ERRORS_LOG);
|
|
6715
6868
|
if (stats.size < MAX_LOG_SIZE) return;
|
|
6716
|
-
|
|
6869
|
+
renameSync2(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
|
|
6717
6870
|
} catch (err) {
|
|
6718
6871
|
console.error(`[client-error] log rotation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6719
6872
|
}
|
|
@@ -6824,18 +6977,53 @@ app9.post("/", async (c) => {
|
|
|
6824
6977
|
var client_error_default = app9;
|
|
6825
6978
|
|
|
6826
6979
|
// server/routes/admin/session.ts
|
|
6827
|
-
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";
|
|
6828
6982
|
import { createHash as createHash2 } from "crypto";
|
|
6829
6983
|
var deprecationLogged = /* @__PURE__ */ new Set();
|
|
6830
6984
|
function hashPin2(pin) {
|
|
6831
6985
|
return createHash2("sha256").update(pin).digest("hex");
|
|
6832
6986
|
}
|
|
6833
6987
|
function readUsersFile2() {
|
|
6834
|
-
if (!
|
|
6835
|
-
const raw =
|
|
6988
|
+
if (!existsSync11(USERS_FILE)) return null;
|
|
6989
|
+
const raw = readFileSync10(USERS_FILE, "utf-8").trim();
|
|
6836
6990
|
if (!raw) return [];
|
|
6837
6991
|
return JSON.parse(raw);
|
|
6838
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
|
+
}
|
|
6839
7027
|
function stripLegacyNameField(users) {
|
|
6840
7028
|
const dirty = users.some((u) => "name" in u && u.name !== void 0);
|
|
6841
7029
|
if (!dirty) return;
|
|
@@ -6849,7 +7037,7 @@ function stripLegacyNameField(users) {
|
|
|
6849
7037
|
}
|
|
6850
7038
|
}
|
|
6851
7039
|
try {
|
|
6852
|
-
|
|
7040
|
+
writeFileSync6(USERS_FILE, JSON.stringify(users), { mode: 384 });
|
|
6853
7041
|
} catch (err) {
|
|
6854
7042
|
console.error(`[admin-identity] users-json strip failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6855
7043
|
}
|
|
@@ -6969,7 +7157,15 @@ app10.post("/", async (c) => {
|
|
|
6969
7157
|
}
|
|
6970
7158
|
const matchedUser = users.find((u) => u.pin === inputHash);
|
|
6971
7159
|
if (!matchedUser) {
|
|
6972
|
-
|
|
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
|
+
}
|
|
6973
7169
|
return c.json({ error: "Invalid PIN" }, 401);
|
|
6974
7170
|
}
|
|
6975
7171
|
stripLegacyNameField(users);
|
|
@@ -7011,8 +7207,8 @@ import { appendFileSync as appendFileSync3 } from "fs";
|
|
|
7011
7207
|
|
|
7012
7208
|
// app/lib/script-stream-tailer.ts
|
|
7013
7209
|
import * as childProcess from "child_process";
|
|
7014
|
-
import { appendFileSync as appendFileSync2, createReadStream as createReadStream2, mkdirSync as
|
|
7015
|
-
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";
|
|
7016
7212
|
import { StringDecoder } from "string_decoder";
|
|
7017
7213
|
var SCRIPT_STREAM_RE = /^\[([^\]]+)\] \[script:([a-z][a-z0-9-]*)((?::[a-z0-9:_-]+)?)\] (.*)$/;
|
|
7018
7214
|
function parseLine(line) {
|
|
@@ -7030,7 +7226,7 @@ function startScriptStreamTailer(opts) {
|
|
|
7030
7226
|
const { path: path2, onEvent, onError } = opts;
|
|
7031
7227
|
let offset;
|
|
7032
7228
|
try {
|
|
7033
|
-
offset =
|
|
7229
|
+
offset = statSync5(path2).size;
|
|
7034
7230
|
} catch {
|
|
7035
7231
|
offset = 0;
|
|
7036
7232
|
}
|
|
@@ -7049,7 +7245,7 @@ function startScriptStreamTailer(opts) {
|
|
|
7049
7245
|
try {
|
|
7050
7246
|
let size;
|
|
7051
7247
|
try {
|
|
7052
|
-
size =
|
|
7248
|
+
size = statSync5(path2).size;
|
|
7053
7249
|
} catch {
|
|
7054
7250
|
return;
|
|
7055
7251
|
}
|
|
@@ -7121,7 +7317,7 @@ function writeRouteMilestone(streamLogPath, scope, line) {
|
|
|
7121
7317
|
}
|
|
7122
7318
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
7123
7319
|
try {
|
|
7124
|
-
|
|
7320
|
+
mkdirSync5(dirname4(streamLogPath), { recursive: true });
|
|
7125
7321
|
appendFileSync2(streamLogPath, `[${ts}] [script:${scope}] ${line}
|
|
7126
7322
|
`);
|
|
7127
7323
|
} catch (err) {
|
|
@@ -7297,7 +7493,7 @@ var app11 = new Hono();
|
|
|
7297
7493
|
app11.post("/cancel", requireAdminSession, async (c) => {
|
|
7298
7494
|
const session_key = c.var.sessionKey;
|
|
7299
7495
|
try {
|
|
7300
|
-
const { interruptClient: interruptClient2 } = await import("./client-pool-
|
|
7496
|
+
const { interruptClient: interruptClient2 } = await import("./client-pool-FM3YJWV5.js");
|
|
7301
7497
|
await interruptClient2(session_key);
|
|
7302
7498
|
return c.json({ ok: true });
|
|
7303
7499
|
} catch (err) {
|
|
@@ -7692,22 +7888,22 @@ app12.post("/", requireAdminSession, async (c) => {
|
|
|
7692
7888
|
var compact_default = app12;
|
|
7693
7889
|
|
|
7694
7890
|
// server/routes/admin/logs.ts
|
|
7695
|
-
import { existsSync as
|
|
7891
|
+
import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync11, statSync as statSync6 } from "fs";
|
|
7696
7892
|
import { resolve as resolve10, basename as basename3 } from "path";
|
|
7697
7893
|
|
|
7698
7894
|
// app/lib/logs-read-resolve.ts
|
|
7699
|
-
import { existsSync as
|
|
7700
|
-
import { join as
|
|
7895
|
+
import { existsSync as existsSync12 } from "fs";
|
|
7896
|
+
import { join as join9 } from "path";
|
|
7701
7897
|
function resolveConversationLogPaths(fullFilename, preflushFilename, logDirs) {
|
|
7702
7898
|
const tried = [fullFilename, preflushFilename];
|
|
7703
7899
|
const hits = [];
|
|
7704
7900
|
const stalePreflushPaths = [];
|
|
7705
7901
|
for (const dir of logDirs) {
|
|
7706
|
-
const fullPath =
|
|
7707
|
-
if (
|
|
7902
|
+
const fullPath = join9(dir, fullFilename);
|
|
7903
|
+
if (existsSync12(fullPath)) {
|
|
7708
7904
|
hits.push({ path: fullPath, shape: "full", dir });
|
|
7709
|
-
const preflushSibling =
|
|
7710
|
-
if (
|
|
7905
|
+
const preflushSibling = join9(dir, preflushFilename);
|
|
7906
|
+
if (existsSync12(preflushSibling)) {
|
|
7711
7907
|
stalePreflushPaths.push(preflushSibling);
|
|
7712
7908
|
}
|
|
7713
7909
|
}
|
|
@@ -7716,8 +7912,8 @@ function resolveConversationLogPaths(fullFilename, preflushFilename, logDirs) {
|
|
|
7716
7912
|
return { hits, stalePreflushPaths, tried };
|
|
7717
7913
|
}
|
|
7718
7914
|
for (const dir of logDirs) {
|
|
7719
|
-
const preflushPath =
|
|
7720
|
-
if (
|
|
7915
|
+
const preflushPath = join9(dir, preflushFilename);
|
|
7916
|
+
if (existsSync12(preflushPath)) {
|
|
7721
7917
|
hits.push({ path: preflushPath, shape: "preflush", dir });
|
|
7722
7918
|
}
|
|
7723
7919
|
}
|
|
@@ -7748,8 +7944,8 @@ app13.get("/", async (c) => {
|
|
|
7748
7944
|
const filePath = resolve10(dir, safe);
|
|
7749
7945
|
searched.push(filePath);
|
|
7750
7946
|
try {
|
|
7751
|
-
const buffer =
|
|
7752
|
-
const onDiskBytes =
|
|
7947
|
+
const buffer = readFileSync11(filePath);
|
|
7948
|
+
const onDiskBytes = statSync6(filePath).size;
|
|
7753
7949
|
const headers = {
|
|
7754
7950
|
"Content-Type": "text/plain; charset=utf-8",
|
|
7755
7951
|
"Content-Length": String(buffer.byteLength)
|
|
@@ -7834,7 +8030,7 @@ app13.get("/", async (c) => {
|
|
|
7834
8030
|
try {
|
|
7835
8031
|
const filename = basename3(hit.path);
|
|
7836
8032
|
if (stalePreflushCount > 0 && !download) {
|
|
7837
|
-
const content =
|
|
8033
|
+
const content = readFileSync11(hit.path, "utf-8");
|
|
7838
8034
|
return c.json({
|
|
7839
8035
|
log: content,
|
|
7840
8036
|
filename,
|
|
@@ -7842,8 +8038,8 @@ app13.get("/", async (c) => {
|
|
|
7842
8038
|
warnings: stalePreflushPaths.map((path2) => ({ kind: "stale-preflush", path: path2 }))
|
|
7843
8039
|
});
|
|
7844
8040
|
}
|
|
7845
|
-
const buffer =
|
|
7846
|
-
const onDiskBytes =
|
|
8041
|
+
const buffer = readFileSync11(hit.path);
|
|
8042
|
+
const onDiskBytes = statSync6(hit.path).size;
|
|
7847
8043
|
const headers = {
|
|
7848
8044
|
"Content-Type": "text/plain; charset=utf-8",
|
|
7849
8045
|
"Content-Length": String(buffer.byteLength)
|
|
@@ -7876,19 +8072,19 @@ app13.get("/", async (c) => {
|
|
|
7876
8072
|
const seen = /* @__PURE__ */ new Set();
|
|
7877
8073
|
const logs = {};
|
|
7878
8074
|
for (const dir of logDirs) {
|
|
7879
|
-
if (!
|
|
8075
|
+
if (!existsSync13(dir)) continue;
|
|
7880
8076
|
let files;
|
|
7881
8077
|
try {
|
|
7882
|
-
files =
|
|
8078
|
+
files = readdirSync5(dir).filter((f) => f.endsWith(".log"));
|
|
7883
8079
|
} catch (err) {
|
|
7884
8080
|
const reason = err instanceof Error ? err.message : String(err);
|
|
7885
8081
|
console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
|
|
7886
8082
|
continue;
|
|
7887
8083
|
}
|
|
7888
|
-
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 }) => {
|
|
7889
8085
|
seen.add(name);
|
|
7890
8086
|
try {
|
|
7891
|
-
const content =
|
|
8087
|
+
const content = readFileSync11(resolve10(dir, name));
|
|
7892
8088
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
7893
8089
|
logs[name] = tail.trim() || "(empty)";
|
|
7894
8090
|
} catch (err) {
|
|
@@ -7927,7 +8123,7 @@ var claude_info_default = app14;
|
|
|
7927
8123
|
|
|
7928
8124
|
// server/routes/admin/attachment.ts
|
|
7929
8125
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
7930
|
-
import { existsSync as
|
|
8126
|
+
import { existsSync as existsSync14 } from "fs";
|
|
7931
8127
|
import { resolve as resolve11 } from "path";
|
|
7932
8128
|
var app15 = new Hono();
|
|
7933
8129
|
app15.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
@@ -7941,11 +8137,11 @@ app15.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
7941
8137
|
return new Response("Not found", { status: 404 });
|
|
7942
8138
|
}
|
|
7943
8139
|
const dir = resolve11(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
7944
|
-
if (!
|
|
8140
|
+
if (!existsSync14(dir)) {
|
|
7945
8141
|
return new Response("Not found", { status: 404 });
|
|
7946
8142
|
}
|
|
7947
8143
|
const metaPath = resolve11(dir, `${attachmentId}.meta.json`);
|
|
7948
|
-
if (!
|
|
8144
|
+
if (!existsSync14(metaPath)) {
|
|
7949
8145
|
return new Response("Not found", { status: 404 });
|
|
7950
8146
|
}
|
|
7951
8147
|
let meta;
|
|
@@ -7973,23 +8169,23 @@ var attachment_default = app15;
|
|
|
7973
8169
|
|
|
7974
8170
|
// server/routes/admin/agents.ts
|
|
7975
8171
|
import { resolve as resolve12 } from "path";
|
|
7976
|
-
import { readdirSync as
|
|
8172
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync12, existsSync as existsSync15, rmSync } from "fs";
|
|
7977
8173
|
var app16 = new Hono();
|
|
7978
8174
|
app16.get("/", (c) => {
|
|
7979
8175
|
const account = resolveAccount();
|
|
7980
8176
|
if (!account) return c.json({ agents: [] });
|
|
7981
8177
|
const agentsDir = resolve12(account.accountDir, "agents");
|
|
7982
|
-
if (!
|
|
8178
|
+
if (!existsSync15(agentsDir)) return c.json({ agents: [] });
|
|
7983
8179
|
const agents = [];
|
|
7984
8180
|
try {
|
|
7985
|
-
const entries =
|
|
8181
|
+
const entries = readdirSync6(agentsDir, { withFileTypes: true });
|
|
7986
8182
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
7987
8183
|
if (!entry.isDirectory()) continue;
|
|
7988
8184
|
if (entry.name === "admin") continue;
|
|
7989
8185
|
const configPath2 = resolve12(agentsDir, entry.name, "config.json");
|
|
7990
|
-
if (!
|
|
8186
|
+
if (!existsSync15(configPath2)) continue;
|
|
7991
8187
|
try {
|
|
7992
|
-
const config = JSON.parse(
|
|
8188
|
+
const config = JSON.parse(readFileSync12(configPath2, "utf-8"));
|
|
7993
8189
|
agents.push({
|
|
7994
8190
|
slug: entry.name,
|
|
7995
8191
|
displayName: config.displayName ?? entry.name,
|
|
@@ -8016,7 +8212,7 @@ app16.delete("/:slug", async (c) => {
|
|
|
8016
8212
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
8017
8213
|
}
|
|
8018
8214
|
const agentDir = resolve12(account.accountDir, "agents", slug);
|
|
8019
|
-
if (!
|
|
8215
|
+
if (!existsSync15(agentDir)) {
|
|
8020
8216
|
return c.json({ error: "Agent not found" }, 404);
|
|
8021
8217
|
}
|
|
8022
8218
|
try {
|
|
@@ -8046,7 +8242,7 @@ app16.post("/:slug/project", async (c) => {
|
|
|
8046
8242
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
8047
8243
|
}
|
|
8048
8244
|
const agentDir = resolve12(account.accountDir, "agents", slug);
|
|
8049
|
-
if (!
|
|
8245
|
+
if (!existsSync15(agentDir)) {
|
|
8050
8246
|
return c.json({ error: "Agent not found on disk" }, 404);
|
|
8051
8247
|
}
|
|
8052
8248
|
try {
|
|
@@ -8062,7 +8258,7 @@ var agents_default = app16;
|
|
|
8062
8258
|
// server/routes/admin/sessions.ts
|
|
8063
8259
|
import crypto2 from "crypto";
|
|
8064
8260
|
import { resolve as resolvePath } from "path";
|
|
8065
|
-
import { appendFileSync as appendFileSync4, existsSync as
|
|
8261
|
+
import { appendFileSync as appendFileSync4, existsSync as existsSync16 } from "fs";
|
|
8066
8262
|
|
|
8067
8263
|
// app/lib/synthetic-marker.ts
|
|
8068
8264
|
var CLOUDFLARE_MARKER_PREFIX = "Cloudflare setup completed (actionId: ";
|
|
@@ -8082,7 +8278,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, conversationId
|
|
|
8082
8278
|
let reason = null;
|
|
8083
8279
|
if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
|
|
8084
8280
|
else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
|
|
8085
|
-
else if (!
|
|
8281
|
+
else if (!existsSync16(a.storagePath)) reason = "missing-file";
|
|
8086
8282
|
if (reason) {
|
|
8087
8283
|
invalid++;
|
|
8088
8284
|
try {
|
|
@@ -8653,7 +8849,7 @@ var events_default = app20;
|
|
|
8653
8849
|
// server/routes/admin/cloudflare.ts
|
|
8654
8850
|
import { homedir } from "os";
|
|
8655
8851
|
import { resolve as resolve14 } from "path";
|
|
8656
|
-
import { readFileSync as
|
|
8852
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
8657
8853
|
|
|
8658
8854
|
// app/lib/dns-label.ts
|
|
8659
8855
|
var VALID_LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
@@ -8669,14 +8865,14 @@ function isValidDomain(value) {
|
|
|
8669
8865
|
}
|
|
8670
8866
|
|
|
8671
8867
|
// app/lib/alias-domains.ts
|
|
8672
|
-
import { existsSync as
|
|
8673
|
-
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";
|
|
8674
8870
|
import { resolve as resolve13 } from "path";
|
|
8675
8871
|
var ALIAS_DOMAINS_PATH = resolve13(MAXY_DIR, "alias-domains.json");
|
|
8676
8872
|
function readExisting() {
|
|
8677
|
-
if (!
|
|
8873
|
+
if (!existsSync17(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
|
|
8678
8874
|
try {
|
|
8679
|
-
const parsed = JSON.parse(
|
|
8875
|
+
const parsed = JSON.parse(readFileSync13(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
8680
8876
|
if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
|
|
8681
8877
|
return new Set(parsed.filter((h) => typeof h === "string"));
|
|
8682
8878
|
} catch {
|
|
@@ -8687,8 +8883,8 @@ function addAliasDomain(hostname2) {
|
|
|
8687
8883
|
const existing = readExisting();
|
|
8688
8884
|
if (existing.has(hostname2)) return;
|
|
8689
8885
|
existing.add(hostname2);
|
|
8690
|
-
|
|
8691
|
-
|
|
8886
|
+
mkdirSync6(dirname5(ALIAS_DOMAINS_PATH), { recursive: true });
|
|
8887
|
+
writeFileSync7(ALIAS_DOMAINS_PATH, JSON.stringify([...existing], null, 2) + "\n", "utf-8");
|
|
8692
8888
|
}
|
|
8693
8889
|
|
|
8694
8890
|
// app/lib/cloudflare-setup-types.ts
|
|
@@ -8703,7 +8899,7 @@ function loadBrandInfo() {
|
|
|
8703
8899
|
const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
|
|
8704
8900
|
const brandPath = resolve14(platformRoot2, "config", "brand.json");
|
|
8705
8901
|
try {
|
|
8706
|
-
const parsed = JSON.parse(
|
|
8902
|
+
const parsed = JSON.parse(readFileSync14(brandPath, "utf-8"));
|
|
8707
8903
|
const hostname2 = typeof parsed.hostname === "string" && parsed.hostname ? parsed.hostname : "maxy";
|
|
8708
8904
|
const configDir2 = typeof parsed.configDir === "string" && parsed.configDir ? parsed.configDir : ".maxy";
|
|
8709
8905
|
return { hostname: hostname2, configDir: configDir2 };
|
|
@@ -8917,8 +9113,8 @@ app21.get("/tunnels", requireAdminSession, async (c) => {
|
|
|
8917
9113
|
if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
|
|
8918
9114
|
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
8919
9115
|
const certPath = resolve14(homedir(), brand.configDir, "cloudflared", "cert.pem");
|
|
8920
|
-
const { existsSync:
|
|
8921
|
-
if (!
|
|
9116
|
+
const { existsSync: existsSync24 } = await import("fs");
|
|
9117
|
+
if (!existsSync24(certPath)) {
|
|
8922
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.`);
|
|
8923
9119
|
}
|
|
8924
9120
|
const result = await runFormSpawn({
|
|
@@ -9208,7 +9404,7 @@ var cloudflare_default = app21;
|
|
|
9208
9404
|
import { createReadStream as createReadStream3 } from "fs";
|
|
9209
9405
|
import { readdir as readdir2, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
|
|
9210
9406
|
import { realpathSync as realpathSync4 } from "fs";
|
|
9211
|
-
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";
|
|
9212
9408
|
import { Readable as Readable2 } from "stream";
|
|
9213
9409
|
|
|
9214
9410
|
// app/lib/data-path.ts
|
|
@@ -9566,7 +9762,7 @@ async function cascadeDeleteDocument(params) {
|
|
|
9566
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;
|
|
9567
9763
|
async function readMeta(absDir, baseName) {
|
|
9568
9764
|
try {
|
|
9569
|
-
const raw = await readFile4(
|
|
9765
|
+
const raw = await readFile4(join10(absDir, `${baseName}.meta.json`), "utf8");
|
|
9570
9766
|
const parsed = JSON.parse(raw);
|
|
9571
9767
|
if (typeof parsed?.filename === "string") {
|
|
9572
9768
|
return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
|
|
@@ -9604,7 +9800,7 @@ async function readAccountNames() {
|
|
|
9604
9800
|
}
|
|
9605
9801
|
async function enrich(absolute, entry, accountNames) {
|
|
9606
9802
|
if (entry.kind === "directory" && UUID_RE4.test(entry.name)) {
|
|
9607
|
-
const meta = await readMeta(
|
|
9803
|
+
const meta = await readMeta(join10(absolute, entry.name), entry.name);
|
|
9608
9804
|
if (meta?.filename) {
|
|
9609
9805
|
entry.displayName = meta.filename;
|
|
9610
9806
|
entry.mimeType = meta.mimeType;
|
|
@@ -9663,7 +9859,7 @@ app22.get("/", requireAdminSession, async (c) => {
|
|
|
9663
9859
|
continue;
|
|
9664
9860
|
}
|
|
9665
9861
|
try {
|
|
9666
|
-
const entryPath =
|
|
9862
|
+
const entryPath = join10(absolute, name);
|
|
9667
9863
|
const s = await stat4(entryPath);
|
|
9668
9864
|
entries.push({
|
|
9669
9865
|
name,
|
|
@@ -9836,7 +10032,7 @@ app22.delete("/", requireAdminSession, async (c) => {
|
|
|
9836
10032
|
}
|
|
9837
10033
|
const dot = base.lastIndexOf(".");
|
|
9838
10034
|
const stem = dot === -1 ? base : base.slice(0, dot);
|
|
9839
|
-
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;
|
|
9840
10036
|
await unlink2(absolute);
|
|
9841
10037
|
if (sidecarPath) {
|
|
9842
10038
|
try {
|
|
@@ -11458,7 +11654,7 @@ var adherence_default = app30;
|
|
|
11458
11654
|
import neo4j3 from "neo4j-driver";
|
|
11459
11655
|
import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
|
|
11460
11656
|
import { resolve as resolve17, relative as relative2, isAbsolute } from "path";
|
|
11461
|
-
import { existsSync as
|
|
11657
|
+
import { existsSync as existsSync18 } from "fs";
|
|
11462
11658
|
var LIMIT = 50;
|
|
11463
11659
|
var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
|
|
11464
11660
|
var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
|
|
@@ -11606,7 +11802,7 @@ async function fetchAgentTemplateRows(accountDir) {
|
|
|
11606
11802
|
async function unionSpecialistFilenames(overrideDir, bundledDir) {
|
|
11607
11803
|
const names = /* @__PURE__ */ new Set();
|
|
11608
11804
|
for (const dir of [overrideDir, bundledDir]) {
|
|
11609
|
-
if (!
|
|
11805
|
+
if (!existsSync18(dir)) continue;
|
|
11610
11806
|
try {
|
|
11611
11807
|
const entries = await readdir3(dir);
|
|
11612
11808
|
for (const entry of entries) {
|
|
@@ -11621,7 +11817,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
|
|
|
11621
11817
|
}
|
|
11622
11818
|
async function readAgentTemplateRow(inp) {
|
|
11623
11819
|
let chosenPath = null;
|
|
11624
|
-
if (
|
|
11820
|
+
if (existsSync18(inp.overridePath)) {
|
|
11625
11821
|
try {
|
|
11626
11822
|
validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
|
|
11627
11823
|
chosenPath = inp.overridePath;
|
|
@@ -11632,7 +11828,7 @@ async function readAgentTemplateRow(inp) {
|
|
|
11632
11828
|
);
|
|
11633
11829
|
return null;
|
|
11634
11830
|
}
|
|
11635
|
-
} else if (
|
|
11831
|
+
} else if (existsSync18(inp.bundledPath)) {
|
|
11636
11832
|
if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
|
|
11637
11833
|
console.error(
|
|
11638
11834
|
`[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
|
|
@@ -11674,7 +11870,7 @@ var sidebar_artefacts_default = app31;
|
|
|
11674
11870
|
// server/routes/admin/sidebar-artefact-save.ts
|
|
11675
11871
|
import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
|
|
11676
11872
|
import { resolve as resolve18 } from "path";
|
|
11677
|
-
import { existsSync as
|
|
11873
|
+
import { existsSync as existsSync19 } from "fs";
|
|
11678
11874
|
var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
|
|
11679
11875
|
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
11680
11876
|
var app32 = new Hono();
|
|
@@ -11738,7 +11934,7 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
11738
11934
|
}
|
|
11739
11935
|
if (UUID_RE5.test(id)) {
|
|
11740
11936
|
const dir = resolve18(ATTACHMENTS_ROOT, accountId, id);
|
|
11741
|
-
if (!
|
|
11937
|
+
if (!existsSync19(dir)) {
|
|
11742
11938
|
return { kind: "reject", status: 400, reason: "not-found" };
|
|
11743
11939
|
}
|
|
11744
11940
|
try {
|
|
@@ -11762,7 +11958,7 @@ var sidebar_artefact_save_default = app32;
|
|
|
11762
11958
|
|
|
11763
11959
|
// server/routes/admin/sidebar-artefact-content.ts
|
|
11764
11960
|
import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
|
|
11765
|
-
import { existsSync as
|
|
11961
|
+
import { existsSync as existsSync20 } from "fs";
|
|
11766
11962
|
import { resolve as resolve19 } from "path";
|
|
11767
11963
|
var UUID_RE6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
11768
11964
|
var app33 = new Hono();
|
|
@@ -11776,7 +11972,7 @@ app33.get("/", requireAdminSession, async (c) => {
|
|
|
11776
11972
|
return new Response("Not found", { status: 404 });
|
|
11777
11973
|
}
|
|
11778
11974
|
const dir = resolve19(ATTACHMENTS_ROOT, accountId, id);
|
|
11779
|
-
if (!
|
|
11975
|
+
if (!existsSync20(dir)) {
|
|
11780
11976
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
11781
11977
|
return new Response("Not found", { status: 404 });
|
|
11782
11978
|
}
|
|
@@ -11810,14 +12006,14 @@ app33.get("/", requireAdminSession, async (c) => {
|
|
|
11810
12006
|
var sidebar_artefact_content_default = app33;
|
|
11811
12007
|
|
|
11812
12008
|
// server/routes/admin/health.ts
|
|
11813
|
-
import { existsSync as
|
|
11814
|
-
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";
|
|
11815
12011
|
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
|
|
11816
12012
|
var brandHostname = "maxy";
|
|
11817
|
-
var brandJsonPath =
|
|
11818
|
-
if (
|
|
12013
|
+
var brandJsonPath = join11(PLATFORM_ROOT7, "config", "brand.json");
|
|
12014
|
+
if (existsSync21(brandJsonPath)) {
|
|
11819
12015
|
try {
|
|
11820
|
-
const brand = JSON.parse(
|
|
12016
|
+
const brand = JSON.parse(readFileSync15(brandJsonPath, "utf-8"));
|
|
11821
12017
|
if (brand.hostname) brandHostname = brand.hostname;
|
|
11822
12018
|
} catch {
|
|
11823
12019
|
}
|
|
@@ -11826,8 +12022,8 @@ var VERSION_FILE = resolve20(PLATFORM_ROOT7, `config/.${brandHostname}-version`)
|
|
|
11826
12022
|
var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
11827
12023
|
var PROBE_TIMEOUT_MS = 1e3;
|
|
11828
12024
|
function readVersion() {
|
|
11829
|
-
if (!
|
|
11830
|
-
return
|
|
12025
|
+
if (!existsSync21(VERSION_FILE)) return "unknown";
|
|
12026
|
+
return readFileSync15(VERSION_FILE, "utf-8").trim() || "unknown";
|
|
11831
12027
|
}
|
|
11832
12028
|
async function probeConversationDb() {
|
|
11833
12029
|
let session;
|
|
@@ -11907,7 +12103,7 @@ app35.route("/health-brand", health_default2);
|
|
|
11907
12103
|
var admin_default = app35;
|
|
11908
12104
|
|
|
11909
12105
|
// server/routes/sites.ts
|
|
11910
|
-
import { existsSync as
|
|
12106
|
+
import { existsSync as existsSync22, readFileSync as readFileSync16, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
|
|
11911
12107
|
import { resolve as resolve21 } from "path";
|
|
11912
12108
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
11913
12109
|
var MIME = {
|
|
@@ -11974,7 +12170,7 @@ app36.get("/:rel{.*}", (c) => {
|
|
|
11974
12170
|
}
|
|
11975
12171
|
let stat7;
|
|
11976
12172
|
try {
|
|
11977
|
-
stat7 =
|
|
12173
|
+
stat7 = existsSync22(filePath) ? statSync7(filePath) : null;
|
|
11978
12174
|
} catch {
|
|
11979
12175
|
stat7 = null;
|
|
11980
12176
|
}
|
|
@@ -11987,7 +12183,7 @@ app36.get("/:rel{.*}", (c) => {
|
|
|
11987
12183
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
11988
12184
|
return c.text("Forbidden", 403);
|
|
11989
12185
|
}
|
|
11990
|
-
if (!
|
|
12186
|
+
if (!existsSync22(filePath)) {
|
|
11991
12187
|
console.error(`[sites] not-found path=${reqPath} status=404`);
|
|
11992
12188
|
return c.text("Not found", 404);
|
|
11993
12189
|
}
|
|
@@ -12006,7 +12202,7 @@ app36.get("/:rel{.*}", (c) => {
|
|
|
12006
12202
|
}
|
|
12007
12203
|
let body;
|
|
12008
12204
|
try {
|
|
12009
|
-
body =
|
|
12205
|
+
body = readFileSync16(realPath);
|
|
12010
12206
|
} catch (err) {
|
|
12011
12207
|
const code = err?.code;
|
|
12012
12208
|
if (code === "EISDIR") {
|
|
@@ -12138,14 +12334,14 @@ function clientFrom(c) {
|
|
|
12138
12334
|
);
|
|
12139
12335
|
}
|
|
12140
12336
|
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
12141
|
-
var BRAND_JSON_PATH = PLATFORM_ROOT8 ?
|
|
12337
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join12(PLATFORM_ROOT8, "config", "brand.json") : "";
|
|
12142
12338
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
|
|
12143
|
-
if (BRAND_JSON_PATH && !
|
|
12339
|
+
if (BRAND_JSON_PATH && !existsSync23(BRAND_JSON_PATH)) {
|
|
12144
12340
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
12145
12341
|
}
|
|
12146
|
-
if (BRAND_JSON_PATH &&
|
|
12342
|
+
if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
|
|
12147
12343
|
try {
|
|
12148
|
-
const parsed = JSON.parse(
|
|
12344
|
+
const parsed = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
|
|
12149
12345
|
BRAND = { ...BRAND, ...parsed };
|
|
12150
12346
|
} catch (err) {
|
|
12151
12347
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -12164,11 +12360,11 @@ var brandLoginOpts = {
|
|
|
12164
12360
|
bodyFont: BRAND.defaultFonts?.body,
|
|
12165
12361
|
logoContainsName: !!BRAND.logoContainsName
|
|
12166
12362
|
};
|
|
12167
|
-
var ALIAS_DOMAINS_PATH2 =
|
|
12363
|
+
var ALIAS_DOMAINS_PATH2 = join12(homedir2(), BRAND.configDir, "alias-domains.json");
|
|
12168
12364
|
function loadAliasDomains() {
|
|
12169
12365
|
try {
|
|
12170
|
-
if (!
|
|
12171
|
-
const parsed = JSON.parse(
|
|
12366
|
+
if (!existsSync23(ALIAS_DOMAINS_PATH2)) return null;
|
|
12367
|
+
const parsed = JSON.parse(readFileSync17(ALIAS_DOMAINS_PATH2, "utf-8"));
|
|
12172
12368
|
if (!Array.isArray(parsed)) {
|
|
12173
12369
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
12174
12370
|
return null;
|
|
@@ -12514,14 +12710,14 @@ app37.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
12514
12710
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
12515
12711
|
return c.text("Forbidden", 403);
|
|
12516
12712
|
}
|
|
12517
|
-
if (!
|
|
12713
|
+
if (!existsSync23(filePath)) {
|
|
12518
12714
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
12519
12715
|
return c.text("Not found", 404);
|
|
12520
12716
|
}
|
|
12521
12717
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
12522
12718
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
12523
12719
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
12524
|
-
const body =
|
|
12720
|
+
const body = readFileSync17(filePath);
|
|
12525
12721
|
return c.body(body, 200, {
|
|
12526
12722
|
"Content-Type": contentType,
|
|
12527
12723
|
"Cache-Control": "public, max-age=3600"
|
|
@@ -12544,14 +12740,14 @@ app37.get("/generated/:filename", (c) => {
|
|
|
12544
12740
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
12545
12741
|
return c.text("Forbidden", 403);
|
|
12546
12742
|
}
|
|
12547
|
-
if (!
|
|
12743
|
+
if (!existsSync23(filePath)) {
|
|
12548
12744
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
12549
12745
|
return c.text("Not found", 404);
|
|
12550
12746
|
}
|
|
12551
12747
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
12552
12748
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
12553
12749
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
12554
|
-
const body =
|
|
12750
|
+
const body = readFileSync17(filePath);
|
|
12555
12751
|
return c.body(body, 200, {
|
|
12556
12752
|
"Content-Type": contentType,
|
|
12557
12753
|
"Cache-Control": "public, max-age=86400"
|
|
@@ -12561,9 +12757,9 @@ app37.route("/sites", sites_default);
|
|
|
12561
12757
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
12562
12758
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
12563
12759
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
12564
|
-
if (BRAND_JSON_PATH &&
|
|
12760
|
+
if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
|
|
12565
12761
|
try {
|
|
12566
|
-
const fullBrand = JSON.parse(
|
|
12762
|
+
const fullBrand = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
|
|
12567
12763
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
12568
12764
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
12569
12765
|
} catch {
|
|
@@ -12580,9 +12776,9 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
12580
12776
|
function readInstalledVersion() {
|
|
12581
12777
|
try {
|
|
12582
12778
|
if (!PLATFORM_ROOT8) return "unknown";
|
|
12583
|
-
const versionFile =
|
|
12584
|
-
if (!
|
|
12585
|
-
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();
|
|
12586
12782
|
return content || "unknown";
|
|
12587
12783
|
} catch {
|
|
12588
12784
|
return "unknown";
|
|
@@ -12623,7 +12819,7 @@ var clientErrorReporterScript = `<script>
|
|
|
12623
12819
|
function cachedHtml(file) {
|
|
12624
12820
|
let html = htmlCache.get(file);
|
|
12625
12821
|
if (!html) {
|
|
12626
|
-
html =
|
|
12822
|
+
html = readFileSync17(resolve22(process.cwd(), "public", file), "utf-8");
|
|
12627
12823
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
12628
12824
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
12629
12825
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -12639,26 +12835,26 @@ ${clientErrorReporterScript}
|
|
|
12639
12835
|
}
|
|
12640
12836
|
var brandedHtmlCache = /* @__PURE__ */ new Map();
|
|
12641
12837
|
function loadBrandingCache(agentSlug) {
|
|
12642
|
-
const configDir2 =
|
|
12838
|
+
const configDir2 = join12(homedir2(), BRAND.configDir);
|
|
12643
12839
|
try {
|
|
12644
|
-
const accountJsonPath =
|
|
12645
|
-
if (!
|
|
12646
|
-
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"));
|
|
12647
12843
|
const accountId = account.accountId;
|
|
12648
12844
|
if (!accountId) return null;
|
|
12649
|
-
const cachePath =
|
|
12650
|
-
if (!
|
|
12651
|
-
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"));
|
|
12652
12848
|
} catch {
|
|
12653
12849
|
return null;
|
|
12654
12850
|
}
|
|
12655
12851
|
}
|
|
12656
12852
|
function resolveDefaultSlug() {
|
|
12657
12853
|
try {
|
|
12658
|
-
const configDir2 =
|
|
12659
|
-
const accountJsonPath =
|
|
12660
|
-
if (!
|
|
12661
|
-
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"));
|
|
12662
12858
|
return account.defaultAgent || null;
|
|
12663
12859
|
} catch {
|
|
12664
12860
|
return null;
|
|
@@ -12731,7 +12927,7 @@ app37.use("/vnc-popout.html", logViewerFetch);
|
|
|
12731
12927
|
app37.get("/vnc-popout.html", (c) => {
|
|
12732
12928
|
let html = htmlCache.get("vnc-popout.html");
|
|
12733
12929
|
if (!html) {
|
|
12734
|
-
html =
|
|
12930
|
+
html = readFileSync17(resolve22(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
12735
12931
|
const name = escapeHtml(BRAND.productName);
|
|
12736
12932
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
12737
12933
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -12784,11 +12980,15 @@ app37.get("/:slug", async (c, next) => {
|
|
|
12784
12980
|
}
|
|
12785
12981
|
await next();
|
|
12786
12982
|
});
|
|
12983
|
+
if (brandFaviconPath !== "/favicon.ico") {
|
|
12984
|
+
app37.get("/favicon.ico", (c) => c.redirect(brandFaviconPath, 302));
|
|
12985
|
+
}
|
|
12787
12986
|
app37.use("/*", serveStatic({ root: "./public" }));
|
|
12788
12987
|
var port = parseInt(process.env.MAXY_UI_INTERNAL_PORT ?? process.env.PORT ?? "19199", 10);
|
|
12789
12988
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
12790
12989
|
var httpServer = serve({ fetch: app37.fetch, port, hostname });
|
|
12791
12990
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
12991
|
+
console.log("[boot] auth-mode summary: oauth=8 api-key=1 (api-key consumer: invokePublicAgent only)");
|
|
12792
12992
|
var SUBAPP_MANIFEST = [
|
|
12793
12993
|
{ prefix: "/api/health", file: "server/routes/health.ts", subapp: health_default },
|
|
12794
12994
|
{ prefix: "/api/session", file: "server/routes/session.ts", subapp: session_default },
|
|
@@ -12818,11 +13018,20 @@ try {
|
|
|
12818
13018
|
} catch (err) {
|
|
12819
13019
|
console.error(`[route-shadow] introspection unavailable: ${err instanceof Error ? err.message : String(err)}`);
|
|
12820
13020
|
}
|
|
13021
|
+
try {
|
|
13022
|
+
checkAdminAuthInvariant({
|
|
13023
|
+
usersFile: USERS_FILE,
|
|
13024
|
+
accountsDir: ACCOUNTS_DIR,
|
|
13025
|
+
tag: "admin-invariant"
|
|
13026
|
+
});
|
|
13027
|
+
} catch (err) {
|
|
13028
|
+
console.error(`[admin-invariant] check threw \u2014 proceeding with boot: ${err instanceof Error ? err.message : String(err)}`);
|
|
13029
|
+
}
|
|
12821
13030
|
(async () => {
|
|
12822
13031
|
try {
|
|
12823
13032
|
let userId = "";
|
|
12824
|
-
if (
|
|
12825
|
-
const users = JSON.parse(
|
|
13033
|
+
if (existsSync23(USERS_FILE)) {
|
|
13034
|
+
const users = JSON.parse(readFileSync17(USERS_FILE, "utf-8").trim() || "[]");
|
|
12826
13035
|
userId = users[0]?.userId ?? "";
|
|
12827
13036
|
}
|
|
12828
13037
|
await backfillNullUserIdConversations(userId);
|
|
@@ -12855,7 +13064,7 @@ autoDeliverPremiumPlugins(bootEntitlement?.purchasedPlugins ?? void 0);
|
|
|
12855
13064
|
(async () => {
|
|
12856
13065
|
if (!bootAccount) return;
|
|
12857
13066
|
try {
|
|
12858
|
-
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-
|
|
13067
|
+
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-FSPEJOTH.js");
|
|
12859
13068
|
const result = await recoverRunningCloudflareTasks(
|
|
12860
13069
|
bootAccount.accountId,
|
|
12861
13070
|
configDirForWhatsApp,
|
|
@@ -12905,7 +13114,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
12905
13114
|
}
|
|
12906
13115
|
init({
|
|
12907
13116
|
configDir: configDirForWhatsApp,
|
|
12908
|
-
platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ??
|
|
13117
|
+
platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ?? join12(__dirname, "..")),
|
|
12909
13118
|
accountConfig: bootAccountConfig,
|
|
12910
13119
|
onMessage: async (msg) => {
|
|
12911
13120
|
try {
|