@rubytech/create-maxy 1.0.623 → 1.0.625
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/lib/anthropic-key/dist/index.d.ts +1 -0
- package/payload/platform/lib/anthropic-key/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/anthropic-key/dist/index.js +30 -0
- package/payload/platform/lib/anthropic-key/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +21 -8
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +9 -12
- package/payload/platform/plugins/cloudflare/PLUGIN.md +31 -44
- package/payload/platform/plugins/cloudflare/mcp/dist/index.js +13 -875
- package/payload/platform/plugins/cloudflare/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts.map +1 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js +1 -0
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js.map +1 -1
- package/payload/platform/plugins/cloudflare/references/dashboard-guide.md +108 -0
- package/payload/platform/plugins/cloudflare/references/manual-setup.md +445 -0
- package/payload/platform/plugins/cloudflare/references/reset-guide.md +118 -0
- package/payload/platform/plugins/cloudflare/scripts/reset-tunnel.sh +65 -0
- package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +244 -0
- package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +96 -5
- package/payload/platform/plugins/docs/references/cloudflare.md +91 -34
- package/payload/platform/templates/agents/admin/IDENTITY.md +10 -4
- package/payload/platform/templates/specialists/agents/personal-assistant.md +9 -9
- package/payload/server/server.js +206 -298
- package/payload/platform/config/cloudflared.yml +0 -17
- package/payload/platform/plugins/cloudflare/references/setup-guide.md +0 -132
package/payload/server/server.js
CHANGED
|
@@ -2896,8 +2896,8 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
2896
2896
|
};
|
|
2897
2897
|
|
|
2898
2898
|
// server/index.ts
|
|
2899
|
-
import { readFileSync as
|
|
2900
|
-
import { resolve as resolve27, join as
|
|
2899
|
+
import { readFileSync as readFileSync26, existsSync as existsSync26, watchFile } from "fs";
|
|
2900
|
+
import { resolve as resolve27, join as join13, basename as basename6 } from "path";
|
|
2901
2901
|
import { homedir as homedir4 } from "os";
|
|
2902
2902
|
|
|
2903
2903
|
// app/lib/vnc-logger.ts
|
|
@@ -3829,7 +3829,7 @@ Content-Length: 0\r
|
|
|
3829
3829
|
}
|
|
3830
3830
|
|
|
3831
3831
|
// app/api/health/route.ts
|
|
3832
|
-
import { existsSync as
|
|
3832
|
+
import { existsSync as existsSync11, readFileSync as readFileSync12 } from "fs";
|
|
3833
3833
|
import { createConnection as createConnection3 } from "net";
|
|
3834
3834
|
|
|
3835
3835
|
// app/lib/claude-auth.ts
|
|
@@ -4005,6 +4005,7 @@ import {
|
|
|
4005
4005
|
existsSync as existsSync4,
|
|
4006
4006
|
mkdirSync as mkdirSync2,
|
|
4007
4007
|
readFileSync as readFileSync4,
|
|
4008
|
+
unlinkSync,
|
|
4008
4009
|
writeFileSync as writeFileSync3
|
|
4009
4010
|
} from "fs";
|
|
4010
4011
|
import { resolve as resolve3, join as join3, dirname } from "path";
|
|
@@ -4164,9 +4165,9 @@ function keyFilePath() {
|
|
|
4164
4165
|
import Anthropic2 from "@anthropic-ai/sdk";
|
|
4165
4166
|
import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
|
|
4166
4167
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
4167
|
-
import { resolve as resolve6, join as
|
|
4168
|
+
import { resolve as resolve6, join as join4 } from "path";
|
|
4168
4169
|
import { platform as osPlatform } from "os";
|
|
4169
|
-
import { readFileSync as
|
|
4170
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, readdirSync as readdirSync2, existsSync as existsSync6, mkdirSync as mkdirSync4, createWriteStream, statSync as statSync3, unlinkSync as unlinkSync2, cpSync, rmSync } from "fs";
|
|
4170
4171
|
import { lookup as dnsLookup } from "dns/promises";
|
|
4171
4172
|
import { createConnection as netConnect } from "net";
|
|
4172
4173
|
import { StringDecoder } from "string_decoder";
|
|
@@ -6037,73 +6038,6 @@ ${items}
|
|
|
6037
6038
|
</commitment-detected>`;
|
|
6038
6039
|
}
|
|
6039
6040
|
|
|
6040
|
-
// app/lib/tool-surface-filter.ts
|
|
6041
|
-
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
6042
|
-
import { join as join4 } from "path";
|
|
6043
|
-
var ALLOWED_CLOUDFLARE_DURING_SETUP = /* @__PURE__ */ new Set([
|
|
6044
|
-
"mcp__cloudflare__cloudflare-setup-run",
|
|
6045
|
-
"mcp__cloudflare__cloudflare-setup-status"
|
|
6046
|
-
]);
|
|
6047
|
-
function shouldRemoveDuringCloudflareSetup(toolName) {
|
|
6048
|
-
if (toolName.startsWith("mcp__plugin_playwright_playwright__")) return true;
|
|
6049
|
-
if (toolName.startsWith("mcp__plugin_chrome-devtools-mcp_chrome-devtools__")) return true;
|
|
6050
|
-
if (toolName.startsWith("mcp__cloudflare__")) {
|
|
6051
|
-
return !ALLOWED_CLOUDFLARE_DURING_SETUP.has(toolName);
|
|
6052
|
-
}
|
|
6053
|
-
if (toolName === "Bash") return true;
|
|
6054
|
-
if (toolName === "Write") return true;
|
|
6055
|
-
if (toolName === "Edit") return true;
|
|
6056
|
-
if (toolName === "NotebookEdit") return true;
|
|
6057
|
-
return false;
|
|
6058
|
-
}
|
|
6059
|
-
function readCloudflareSetupState() {
|
|
6060
|
-
const path2 = join4(MAXY_DIR, "cloudflared", "setup.state.json");
|
|
6061
|
-
if (!existsSync6(path2)) return null;
|
|
6062
|
-
try {
|
|
6063
|
-
const raw2 = readFileSync7(path2, "utf-8");
|
|
6064
|
-
const parsed = JSON.parse(raw2);
|
|
6065
|
-
if (typeof parsed?.phase !== "string") return null;
|
|
6066
|
-
const phase = parsed.phase;
|
|
6067
|
-
const setupActive = phase !== "idle" && phase !== "healthy" && phase !== "unhealthy";
|
|
6068
|
-
return { phase, domain: parsed.domain ?? null, setupActive };
|
|
6069
|
-
} catch {
|
|
6070
|
-
return null;
|
|
6071
|
-
}
|
|
6072
|
-
}
|
|
6073
|
-
function applyToolSurfaceFilters(tools) {
|
|
6074
|
-
const cf = readCloudflareSetupState();
|
|
6075
|
-
if (cf && cf.setupActive) {
|
|
6076
|
-
const kept = [];
|
|
6077
|
-
const removed = [];
|
|
6078
|
-
for (const t of tools) {
|
|
6079
|
-
if (shouldRemoveDuringCloudflareSetup(t)) {
|
|
6080
|
-
removed.push(t);
|
|
6081
|
-
} else {
|
|
6082
|
-
kept.push(t);
|
|
6083
|
-
}
|
|
6084
|
-
}
|
|
6085
|
-
return {
|
|
6086
|
-
tools: kept,
|
|
6087
|
-
filtered: "cloudflare-setup",
|
|
6088
|
-
phase: cf.phase,
|
|
6089
|
-
removed: removed.length,
|
|
6090
|
-
removedList: [...removed].sort().join(",")
|
|
6091
|
-
};
|
|
6092
|
-
}
|
|
6093
|
-
return {
|
|
6094
|
-
tools,
|
|
6095
|
-
filtered: "none",
|
|
6096
|
-
phase: cf?.phase ?? "idle",
|
|
6097
|
-
removed: 0,
|
|
6098
|
-
removedList: ""
|
|
6099
|
-
};
|
|
6100
|
-
}
|
|
6101
|
-
function logToolSurfaceFilter(result) {
|
|
6102
|
-
console.error(
|
|
6103
|
-
`[chat-driver:tool-surface] filtered=${result.filtered} phase=${result.phase} removed=${result.removed} removed-list=${result.removedList}`
|
|
6104
|
-
);
|
|
6105
|
-
}
|
|
6106
|
-
|
|
6107
6041
|
// app/lib/claude-agent.ts
|
|
6108
6042
|
var LOG_RETENTION_DAYS = 7;
|
|
6109
6043
|
var BROWSER_TOOL_PREFIXES = [
|
|
@@ -6270,7 +6204,7 @@ function purgeOldLogs(logDir, prefix) {
|
|
|
6270
6204
|
if (!file2.startsWith(prefix)) continue;
|
|
6271
6205
|
const filePath = resolve6(logDir, file2);
|
|
6272
6206
|
try {
|
|
6273
|
-
if (statSync3(filePath).mtimeMs < cutoff)
|
|
6207
|
+
if (statSync3(filePath).mtimeMs < cutoff) unlinkSync2(filePath);
|
|
6274
6208
|
} catch (err) {
|
|
6275
6209
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6276
6210
|
console.error(`[log-purge-err] file=${file2} reason=${msg}`);
|
|
@@ -6337,7 +6271,7 @@ function sampleProcState(pid) {
|
|
|
6337
6271
|
let sockets2 = 0;
|
|
6338
6272
|
for (const tcpFile of ["/proc/" + pid + "/net/tcp", "/proc/" + pid + "/net/tcp6"]) {
|
|
6339
6273
|
try {
|
|
6340
|
-
const raw2 =
|
|
6274
|
+
const raw2 = readFileSync7(tcpFile, "utf-8");
|
|
6341
6275
|
const lines2 = raw2.split("\n");
|
|
6342
6276
|
for (let i = 1; i < lines2.length; i++) {
|
|
6343
6277
|
const line = lines2[i].trim();
|
|
@@ -6353,7 +6287,7 @@ function sampleProcState(pid) {
|
|
|
6353
6287
|
}
|
|
6354
6288
|
let rssMb = 0;
|
|
6355
6289
|
try {
|
|
6356
|
-
const statm =
|
|
6290
|
+
const statm = readFileSync7(`/proc/${pid}/statm`, "utf-8").trim().split(/\s+/);
|
|
6357
6291
|
const rssPages = parseInt(statm[1] ?? "0", 10);
|
|
6358
6292
|
if (Number.isFinite(rssPages)) rssMb = Math.round(rssPages * 4096 / (1024 * 1024));
|
|
6359
6293
|
} catch {
|
|
@@ -6388,19 +6322,19 @@ function sampleProcState(pid) {
|
|
|
6388
6322
|
}
|
|
6389
6323
|
var PLATFORM_ROOT4 = process.env.MAXY_PLATFORM_ROOT ?? resolve6(process.cwd(), "..");
|
|
6390
6324
|
var ACCOUNTS_DIR = resolve6(PLATFORM_ROOT4, "..", "data/accounts");
|
|
6391
|
-
if (!
|
|
6325
|
+
if (!existsSync6(PLATFORM_ROOT4)) {
|
|
6392
6326
|
throw new Error(
|
|
6393
6327
|
`PLATFORM_ROOT does not exist: ${PLATFORM_ROOT4}
|
|
6394
6328
|
Set the MAXY_PLATFORM_ROOT environment variable to the absolute path of the platform directory.`
|
|
6395
6329
|
);
|
|
6396
6330
|
}
|
|
6397
6331
|
function resolveAccount() {
|
|
6398
|
-
if (!
|
|
6332
|
+
if (!existsSync6(ACCOUNTS_DIR)) return null;
|
|
6399
6333
|
const usersFilePath = resolve6(PLATFORM_ROOT4, "config", "users.json");
|
|
6400
6334
|
let usersJsonUserId = null;
|
|
6401
|
-
if (
|
|
6335
|
+
if (existsSync6(usersFilePath)) {
|
|
6402
6336
|
try {
|
|
6403
|
-
const raw2 =
|
|
6337
|
+
const raw2 = readFileSync7(usersFilePath, "utf-8").trim();
|
|
6404
6338
|
if (raw2) {
|
|
6405
6339
|
const users = JSON.parse(raw2);
|
|
6406
6340
|
if (users.length > 0) {
|
|
@@ -6415,8 +6349,8 @@ function resolveAccount() {
|
|
|
6415
6349
|
for (const entry of entries) {
|
|
6416
6350
|
if (!entry.isDirectory()) continue;
|
|
6417
6351
|
const configPath2 = resolve6(ACCOUNTS_DIR, entry.name, "account.json");
|
|
6418
|
-
if (!
|
|
6419
|
-
const raw2 =
|
|
6352
|
+
if (!existsSync6(configPath2)) continue;
|
|
6353
|
+
const raw2 = readFileSync7(configPath2, "utf-8");
|
|
6420
6354
|
let config2;
|
|
6421
6355
|
try {
|
|
6422
6356
|
config2 = JSON.parse(raw2);
|
|
@@ -6450,8 +6384,8 @@ function resolveAccount() {
|
|
|
6450
6384
|
}
|
|
6451
6385
|
function readAgentFile(accountDir, agentName, filename) {
|
|
6452
6386
|
const filePath = resolve6(accountDir, "agents", agentName, filename);
|
|
6453
|
-
if (!
|
|
6454
|
-
return
|
|
6387
|
+
if (!existsSync6(filePath)) return null;
|
|
6388
|
+
return readFileSync7(filePath, "utf-8");
|
|
6455
6389
|
}
|
|
6456
6390
|
function readIdentity(accountDir, agentName) {
|
|
6457
6391
|
return readAgentFile(accountDir, agentName, "IDENTITY.md");
|
|
@@ -6468,13 +6402,13 @@ function validateAgentSlug(slug) {
|
|
|
6468
6402
|
}
|
|
6469
6403
|
function resolveDefaultAgentSlug(accountDir) {
|
|
6470
6404
|
const configPath2 = resolve6(accountDir, "account.json");
|
|
6471
|
-
if (!
|
|
6405
|
+
if (!existsSync6(configPath2)) {
|
|
6472
6406
|
console.error("[agent-resolve] account.json not found \u2014 cannot resolve defaultAgent");
|
|
6473
6407
|
return null;
|
|
6474
6408
|
}
|
|
6475
6409
|
let config2;
|
|
6476
6410
|
try {
|
|
6477
|
-
config2 = JSON.parse(
|
|
6411
|
+
config2 = JSON.parse(readFileSync7(configPath2, "utf-8"));
|
|
6478
6412
|
} catch (err) {
|
|
6479
6413
|
console.error("[agent-resolve] failed to read account.json:", err);
|
|
6480
6414
|
return null;
|
|
@@ -6484,7 +6418,7 @@ function resolveDefaultAgentSlug(accountDir) {
|
|
|
6484
6418
|
return null;
|
|
6485
6419
|
}
|
|
6486
6420
|
const agentConfigPath = resolve6(accountDir, "agents", config2.defaultAgent, "config.json");
|
|
6487
|
-
if (!
|
|
6421
|
+
if (!existsSync6(agentConfigPath)) {
|
|
6488
6422
|
console.error(`[agent-resolve] defaultAgent="${config2.defaultAgent}" has no config.json at ${agentConfigPath}`);
|
|
6489
6423
|
return null;
|
|
6490
6424
|
}
|
|
@@ -6559,20 +6493,20 @@ function resolveAgentConfig(accountDir, agentName) {
|
|
|
6559
6493
|
const agentDir = resolve6(accountDir, "agents", agentName);
|
|
6560
6494
|
const knowledgePath = resolve6(agentDir, "KNOWLEDGE.md");
|
|
6561
6495
|
const summaryPath = resolve6(agentDir, "KNOWLEDGE-SUMMARY.md");
|
|
6562
|
-
const hasKnowledge =
|
|
6563
|
-
const hasSummary =
|
|
6496
|
+
const hasKnowledge = existsSync6(knowledgePath);
|
|
6497
|
+
const hasSummary = existsSync6(summaryPath);
|
|
6564
6498
|
if (hasKnowledge && hasSummary) {
|
|
6565
6499
|
const knowledgeMtime = statSync3(knowledgePath).mtimeMs;
|
|
6566
6500
|
const summaryMtime = statSync3(summaryPath).mtimeMs;
|
|
6567
6501
|
if (summaryMtime >= knowledgeMtime) {
|
|
6568
|
-
knowledge =
|
|
6502
|
+
knowledge = readFileSync7(summaryPath, "utf-8");
|
|
6569
6503
|
} else {
|
|
6570
6504
|
console.warn(`[agent-config] ${agentName}: KNOWLEDGE-SUMMARY.md is stale (KNOWLEDGE.md is newer) \u2014 using full knowledge`);
|
|
6571
|
-
knowledge =
|
|
6505
|
+
knowledge = readFileSync7(knowledgePath, "utf-8");
|
|
6572
6506
|
}
|
|
6573
6507
|
knowledgeBaked = true;
|
|
6574
6508
|
} else if (hasKnowledge) {
|
|
6575
|
-
knowledge =
|
|
6509
|
+
knowledge = readFileSync7(knowledgePath, "utf-8");
|
|
6576
6510
|
knowledgeBaked = true;
|
|
6577
6511
|
}
|
|
6578
6512
|
let budget = null;
|
|
@@ -6595,10 +6529,10 @@ function resolveAgentConfig(accountDir, agentName) {
|
|
|
6595
6529
|
}
|
|
6596
6530
|
function parsePluginFrontmatter(pluginDir) {
|
|
6597
6531
|
const pluginPath = resolve6(PLATFORM_ROOT4, "plugins", pluginDir, "PLUGIN.md");
|
|
6598
|
-
if (!
|
|
6532
|
+
if (!existsSync6(pluginPath)) return null;
|
|
6599
6533
|
let raw2;
|
|
6600
6534
|
try {
|
|
6601
|
-
raw2 =
|
|
6535
|
+
raw2 = readFileSync7(pluginPath, "utf-8");
|
|
6602
6536
|
} catch {
|
|
6603
6537
|
console.warn(`[plugins] cannot read ${pluginPath}`);
|
|
6604
6538
|
return null;
|
|
@@ -6659,22 +6593,22 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
|
|
|
6659
6593
|
const TAG18 = "[premium-auto-deliver]";
|
|
6660
6594
|
const stagingRoot = resolve6(PLATFORM_ROOT4, "../premium-plugins");
|
|
6661
6595
|
const pluginsDir = resolve6(PLATFORM_ROOT4, "plugins");
|
|
6662
|
-
if (!
|
|
6596
|
+
if (!existsSync6(stagingRoot)) {
|
|
6663
6597
|
console.log(`${TAG18} no staging directory \u2014 skipping`);
|
|
6664
6598
|
return;
|
|
6665
6599
|
}
|
|
6666
6600
|
for (const pluginName of purchasedPlugins) {
|
|
6667
6601
|
const stagingDir = resolve6(stagingRoot, pluginName);
|
|
6668
|
-
if (!
|
|
6602
|
+
if (!existsSync6(stagingDir)) {
|
|
6669
6603
|
console.log(`${TAG18} ${pluginName}: not in staging \u2014 skipping`);
|
|
6670
6604
|
continue;
|
|
6671
6605
|
}
|
|
6672
|
-
const bundlePath =
|
|
6673
|
-
const isBundle =
|
|
6606
|
+
const bundlePath = join4(stagingDir, "BUNDLE.md");
|
|
6607
|
+
const isBundle = existsSync6(bundlePath);
|
|
6674
6608
|
if (isBundle) {
|
|
6675
6609
|
let bundleRaw;
|
|
6676
6610
|
try {
|
|
6677
|
-
bundleRaw =
|
|
6611
|
+
bundleRaw = readFileSync7(bundlePath, "utf-8");
|
|
6678
6612
|
} catch (err) {
|
|
6679
6613
|
console.log(`${TAG18} ${pluginName}: cannot read BUNDLE.md \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
6680
6614
|
continue;
|
|
@@ -6706,12 +6640,12 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
|
|
|
6706
6640
|
let skipped = 0;
|
|
6707
6641
|
for (const sub of subPlugins) {
|
|
6708
6642
|
const target = resolve6(pluginsDir, sub);
|
|
6709
|
-
if (
|
|
6643
|
+
if (existsSync6(resolve6(target, "PLUGIN.md"))) {
|
|
6710
6644
|
skipped++;
|
|
6711
6645
|
continue;
|
|
6712
6646
|
}
|
|
6713
6647
|
const source = resolve6(stagingDir, "plugins", sub);
|
|
6714
|
-
if (!
|
|
6648
|
+
if (!existsSync6(source)) {
|
|
6715
6649
|
console.log(`${TAG18} ${pluginName}/${sub}: source missing in staging \u2014 skipping`);
|
|
6716
6650
|
continue;
|
|
6717
6651
|
}
|
|
@@ -6725,7 +6659,7 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
|
|
|
6725
6659
|
console.log(`${TAG18} ${pluginName} (bundle): ${delivered} delivered, ${skipped} already present`);
|
|
6726
6660
|
} else {
|
|
6727
6661
|
const target = resolve6(pluginsDir, pluginName);
|
|
6728
|
-
if (
|
|
6662
|
+
if (existsSync6(resolve6(target, "PLUGIN.md"))) {
|
|
6729
6663
|
console.log(`${TAG18} ${pluginName}: already present \u2014 skipping`);
|
|
6730
6664
|
continue;
|
|
6731
6665
|
}
|
|
@@ -6767,7 +6701,7 @@ function migratePluginRenames(accountDir, config2) {
|
|
|
6767
6701
|
if (!changed) return;
|
|
6768
6702
|
const configPath2 = resolve6(accountDir, "account.json");
|
|
6769
6703
|
try {
|
|
6770
|
-
const raw2 =
|
|
6704
|
+
const raw2 = readFileSync7(configPath2, "utf-8");
|
|
6771
6705
|
const parsed = JSON.parse(raw2);
|
|
6772
6706
|
parsed.enabledPlugins = migrated;
|
|
6773
6707
|
writeFileSync5(configPath2, JSON.stringify(parsed, null, 2) + "\n");
|
|
@@ -6779,7 +6713,7 @@ function migratePluginRenames(accountDir, config2) {
|
|
|
6779
6713
|
const pluginsDir = resolve6(PLATFORM_ROOT4, "plugins");
|
|
6780
6714
|
for (const oldName of Object.keys(PLUGIN_RENAMES)) {
|
|
6781
6715
|
const orphan = resolve6(pluginsDir, oldName);
|
|
6782
|
-
if (
|
|
6716
|
+
if (existsSync6(orphan)) {
|
|
6783
6717
|
try {
|
|
6784
6718
|
rmSync(orphan, { recursive: true });
|
|
6785
6719
|
console.log(`${TAG18} removed orphan: ${oldName}`);
|
|
@@ -6794,20 +6728,20 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
|
|
|
6794
6728
|
const TAG18 = "[bundle-agent-deliver]";
|
|
6795
6729
|
const stagingRoot = resolve6(PLATFORM_ROOT4, "../premium-plugins");
|
|
6796
6730
|
const specialistsDir = resolve6(accountDir, "specialists", "agents");
|
|
6797
|
-
if (!
|
|
6798
|
-
if (!
|
|
6731
|
+
if (!existsSync6(stagingRoot)) return;
|
|
6732
|
+
if (!existsSync6(specialistsDir)) {
|
|
6799
6733
|
mkdirSync4(specialistsDir, { recursive: true });
|
|
6800
6734
|
}
|
|
6801
6735
|
const agentsmdPath = resolve6(accountDir, "agents", "admin", "AGENTS.md");
|
|
6802
6736
|
let agentsmd = "";
|
|
6803
6737
|
try {
|
|
6804
|
-
agentsmd =
|
|
6738
|
+
agentsmd = existsSync6(agentsmdPath) ? readFileSync7(agentsmdPath, "utf-8") : "";
|
|
6805
6739
|
} catch {
|
|
6806
6740
|
}
|
|
6807
6741
|
let delivered = 0;
|
|
6808
6742
|
for (const pluginName of purchasedPlugins) {
|
|
6809
6743
|
const bundleAgentsDir = resolve6(stagingRoot, pluginName, "agents");
|
|
6810
|
-
if (!
|
|
6744
|
+
if (!existsSync6(bundleAgentsDir)) continue;
|
|
6811
6745
|
let entries;
|
|
6812
6746
|
try {
|
|
6813
6747
|
entries = readdirSync2(bundleAgentsDir).filter((f) => f.endsWith(".md"));
|
|
@@ -6816,7 +6750,7 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
|
|
|
6816
6750
|
}
|
|
6817
6751
|
for (const filename of entries) {
|
|
6818
6752
|
const target = resolve6(specialistsDir, filename);
|
|
6819
|
-
if (
|
|
6753
|
+
if (existsSync6(target)) continue;
|
|
6820
6754
|
const source = resolve6(bundleAgentsDir, filename);
|
|
6821
6755
|
try {
|
|
6822
6756
|
cpSync(source, target);
|
|
@@ -6825,7 +6759,7 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
|
|
|
6825
6759
|
continue;
|
|
6826
6760
|
}
|
|
6827
6761
|
try {
|
|
6828
|
-
const content =
|
|
6762
|
+
const content = readFileSync7(target, "utf-8");
|
|
6829
6763
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
6830
6764
|
if (fmMatch) {
|
|
6831
6765
|
const nameMatch = fmMatch[1].match(/^name:\s*(.+)/m);
|
|
@@ -6861,7 +6795,7 @@ function assemblePublicPluginContent(pluginDir) {
|
|
|
6861
6795
|
const pluginPath = resolve6(pluginRoot, "PLUGIN.md");
|
|
6862
6796
|
let raw2;
|
|
6863
6797
|
try {
|
|
6864
|
-
raw2 =
|
|
6798
|
+
raw2 = readFileSync7(pluginPath, "utf-8");
|
|
6865
6799
|
} catch {
|
|
6866
6800
|
return null;
|
|
6867
6801
|
}
|
|
@@ -6882,7 +6816,7 @@ function assemblePublicPluginContent(pluginDir) {
|
|
|
6882
6816
|
const skillMdPath = resolve6(skillDir, "SKILL.md");
|
|
6883
6817
|
let skillRaw;
|
|
6884
6818
|
try {
|
|
6885
|
-
skillRaw =
|
|
6819
|
+
skillRaw = readFileSync7(skillMdPath, "utf-8");
|
|
6886
6820
|
} catch {
|
|
6887
6821
|
continue;
|
|
6888
6822
|
}
|
|
@@ -6933,7 +6867,7 @@ function assemblePublicPluginContent(pluginDir) {
|
|
|
6933
6867
|
}
|
|
6934
6868
|
for (const refFile of refFiles) {
|
|
6935
6869
|
try {
|
|
6936
|
-
const refContent =
|
|
6870
|
+
const refContent = readFileSync7(resolve6(refsDir, refFile), "utf-8").trim();
|
|
6937
6871
|
if (refContent) {
|
|
6938
6872
|
parts.push(`
|
|
6939
6873
|
<!-- reference: ${refFile} -->`);
|
|
@@ -7007,7 +6941,7 @@ function loadEmbeddedPlugins(agentType, selectedPlugins, enabledPlugins) {
|
|
|
7007
6941
|
const pluginPath = resolve6(pluginsDir, dir, "PLUGIN.md");
|
|
7008
6942
|
let raw2;
|
|
7009
6943
|
try {
|
|
7010
|
-
raw2 =
|
|
6944
|
+
raw2 = readFileSync7(pluginPath, "utf-8");
|
|
7011
6945
|
} catch (err) {
|
|
7012
6946
|
console.warn(`[plugins] ${dir}: failed to read PLUGIN.md for ${agentType} embed: ${String(err)}`);
|
|
7013
6947
|
continue;
|
|
@@ -7032,7 +6966,7 @@ function fetchMcpToolsList(pluginDir) {
|
|
|
7032
6966
|
const cached2 = mcpToolsCache.get(pluginDir);
|
|
7033
6967
|
if (cached2) return Promise.resolve(cached2);
|
|
7034
6968
|
const serverPath = resolve6(PLATFORM_ROOT4, "plugins", pluginDir, "mcp/dist/index.js");
|
|
7035
|
-
if (!
|
|
6969
|
+
if (!existsSync6(serverPath)) return Promise.resolve([]);
|
|
7036
6970
|
const startMs = Date.now();
|
|
7037
6971
|
return new Promise((resolvePromise) => {
|
|
7038
6972
|
const proc = spawn2(process.execPath, [serverPath], {
|
|
@@ -7236,7 +7170,7 @@ ${specialist}: ${plugins.join(", ")}`);
|
|
|
7236
7170
|
const references = [];
|
|
7237
7171
|
const scanDir = (base, prefix, target) => {
|
|
7238
7172
|
const scanPath = resolve6(pluginRoot, base);
|
|
7239
|
-
if (!
|
|
7173
|
+
if (!existsSync6(scanPath)) return;
|
|
7240
7174
|
try {
|
|
7241
7175
|
const walk = (current, rel) => {
|
|
7242
7176
|
for (const entry of readdirSync2(current)) {
|
|
@@ -7269,7 +7203,7 @@ ${specialist}: ${plugins.join(", ")}`);
|
|
|
7269
7203
|
}
|
|
7270
7204
|
} else if (parsed.tools.length > 0) {
|
|
7271
7205
|
const serverPath = resolve6(PLATFORM_ROOT4, "plugins", dir, "mcp/dist/index.js");
|
|
7272
|
-
if (
|
|
7206
|
+
if (existsSync6(serverPath)) {
|
|
7273
7207
|
fallbackSourced++;
|
|
7274
7208
|
console.error(`[plugin-manifest] ${dir}: tools/list empty \u2014 fallback to frontmatter (${parsed.tools.length} tools)`);
|
|
7275
7209
|
}
|
|
@@ -7344,16 +7278,16 @@ function getDefaultAccountId() {
|
|
|
7344
7278
|
return resolveAccount()?.accountId ?? null;
|
|
7345
7279
|
}
|
|
7346
7280
|
function resolveUserAccounts(userId) {
|
|
7347
|
-
if (!
|
|
7281
|
+
if (!existsSync6(ACCOUNTS_DIR)) return [];
|
|
7348
7282
|
const results = [];
|
|
7349
7283
|
const entries = readdirSync2(ACCOUNTS_DIR, { withFileTypes: true });
|
|
7350
7284
|
for (const entry of entries) {
|
|
7351
7285
|
if (!entry.isDirectory()) continue;
|
|
7352
7286
|
const configPath2 = resolve6(ACCOUNTS_DIR, entry.name, "account.json");
|
|
7353
|
-
if (!
|
|
7287
|
+
if (!existsSync6(configPath2)) continue;
|
|
7354
7288
|
let config2;
|
|
7355
7289
|
try {
|
|
7356
|
-
config2 = JSON.parse(
|
|
7290
|
+
config2 = JSON.parse(readFileSync7(configPath2, "utf-8"));
|
|
7357
7291
|
} catch {
|
|
7358
7292
|
console.error(`[session] account.json corrupt at ${configPath2} \u2014 skipping`);
|
|
7359
7293
|
continue;
|
|
@@ -7673,7 +7607,7 @@ function getMcpServers(accountId, conversationId, userId, enabledPlugins) {
|
|
|
7673
7607
|
}
|
|
7674
7608
|
}
|
|
7675
7609
|
const mcpEntry = resolve6(PLATFORM_ROOT4, "plugins", dir, "mcp/dist/index.js");
|
|
7676
|
-
if (!
|
|
7610
|
+
if (!existsSync6(mcpEntry)) continue;
|
|
7677
7611
|
servers[dir] = {
|
|
7678
7612
|
command: "node",
|
|
7679
7613
|
args: [mcpEntry],
|
|
@@ -7751,16 +7685,6 @@ var ADMIN_CORE_TOOLS = [
|
|
|
7751
7685
|
"mcp__admin__action-approve",
|
|
7752
7686
|
"mcp__admin__action-reject",
|
|
7753
7687
|
"mcp__admin__action-edit",
|
|
7754
|
-
"mcp__cloudflare__tunnel-status",
|
|
7755
|
-
"mcp__cloudflare__tunnel-install",
|
|
7756
|
-
"mcp__cloudflare__tunnel-login",
|
|
7757
|
-
"mcp__cloudflare__tunnel-create",
|
|
7758
|
-
"mcp__cloudflare__tunnel-enable",
|
|
7759
|
-
"mcp__cloudflare__tunnel-disable",
|
|
7760
|
-
"mcp__cloudflare__tunnel-add-hostname",
|
|
7761
|
-
"mcp__cloudflare__cloudflare-setup-run",
|
|
7762
|
-
"mcp__cloudflare__cloudflare-setup-status",
|
|
7763
|
-
"mcp__cloudflare__dns-lookup",
|
|
7764
7688
|
"mcp__tasks__task-create",
|
|
7765
7689
|
"mcp__tasks__task-update",
|
|
7766
7690
|
"mcp__tasks__task-list",
|
|
@@ -7827,10 +7751,7 @@ function getAdminAllowedTools(enabledPlugins) {
|
|
|
7827
7751
|
return tools;
|
|
7828
7752
|
}
|
|
7829
7753
|
function assembleAllowedToolsForAdminSpawn(enabledPlugins) {
|
|
7830
|
-
|
|
7831
|
-
const result = applyToolSurfaceFilters(base);
|
|
7832
|
-
logToolSurfaceFilter(result);
|
|
7833
|
-
return result.tools;
|
|
7754
|
+
return getAdminAllowedTools(enabledPlugins);
|
|
7834
7755
|
}
|
|
7835
7756
|
var QUERY_CLASSIFIER_MODEL = HAIKU_MODEL2;
|
|
7836
7757
|
var QUERY_CLASSIFIER_TIMEOUT_MS = 3e3;
|
|
@@ -7920,7 +7841,7 @@ ${message.slice(0, QUERY_CLASSIFIER_MSG_CAP)}`
|
|
|
7920
7841
|
}
|
|
7921
7842
|
async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
7922
7843
|
const serverPath = resolve6(PLATFORM_ROOT4, "plugins/memory/mcp/dist/index.js");
|
|
7923
|
-
if (!
|
|
7844
|
+
if (!existsSync6(serverPath)) {
|
|
7924
7845
|
console.error(`[fetchMemoryContext] MCP server not found: ${serverPath}`);
|
|
7925
7846
|
return null;
|
|
7926
7847
|
}
|
|
@@ -8018,7 +7939,7 @@ async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
|
8018
7939
|
async function compactTrimmedMessages(accountId, trimmedMessages) {
|
|
8019
7940
|
if (trimmedMessages.length === 0) return true;
|
|
8020
7941
|
const serverPath = resolve6(PLATFORM_ROOT4, "plugins/memory/mcp/dist/index.js");
|
|
8021
|
-
if (!
|
|
7942
|
+
if (!existsSync6(serverPath)) return false;
|
|
8022
7943
|
const briefing = trimmedMessages.map((m) => `[${m.role.toUpperCase()}] ${m.content}`).join("\n\n");
|
|
8023
7944
|
return new Promise((resolvePromise) => {
|
|
8024
7945
|
const proc = spawn2(process.execPath, [serverPath], {
|
|
@@ -8336,7 +8257,7 @@ var COMPACTION_TIMEOUT_MS = 45e3;
|
|
|
8336
8257
|
async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSessionId, adminModel, conversationId, enabledPlugins) {
|
|
8337
8258
|
const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, conversationId, void 0, enabledPlugins) });
|
|
8338
8259
|
const specialistsDir = resolve6(accountDir, "specialists");
|
|
8339
|
-
if (!
|
|
8260
|
+
if (!existsSync6(specialistsDir)) agentLogStream("claude-agent-compaction-stream", accountDir, conversationId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
8340
8261
|
`);
|
|
8341
8262
|
const args = [
|
|
8342
8263
|
"--print",
|
|
@@ -9225,7 +9146,7 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9225
9146
|
const ccUserId = sessionKey ? getUserIdForSession(sessionKey) : void 0;
|
|
9226
9147
|
const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, spawnConvId, ccUserId, enabledPlugins) });
|
|
9227
9148
|
const specialistsDir = resolve6(accountDir, "specialists");
|
|
9228
|
-
if (!
|
|
9149
|
+
if (!existsSync6(specialistsDir)) agentLogStream("claude-agent-stream", accountDir, spawnConvId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
9229
9150
|
`);
|
|
9230
9151
|
const args = [
|
|
9231
9152
|
"--print",
|
|
@@ -9571,7 +9492,7 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
9571
9492
|
const managedUserId = getUserIdForSession(sessionKey);
|
|
9572
9493
|
const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, managedConvId, managedUserId, enabledPlugins) });
|
|
9573
9494
|
const specialistsDir = resolve6(accountDir, "specialists");
|
|
9574
|
-
if (!
|
|
9495
|
+
if (!existsSync6(specialistsDir)) streamLog.write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
9575
9496
|
`);
|
|
9576
9497
|
const fullMessage = attachments.length > 0 ? message + buildAttachmentMetaText(attachments) : message;
|
|
9577
9498
|
const args = [
|
|
@@ -10241,7 +10162,7 @@ ${sessionContext}`;
|
|
|
10241
10162
|
const skillPath = resolve6(PLATFORM_ROOT4, "plugins/admin/skills/onboarding/SKILL.md");
|
|
10242
10163
|
let skillContent = "";
|
|
10243
10164
|
try {
|
|
10244
|
-
skillContent =
|
|
10165
|
+
skillContent = readFileSync7(skillPath, "utf-8");
|
|
10245
10166
|
} catch (err) {
|
|
10246
10167
|
console.error(`[onboarding-inject] accountId=${accountId.slice(0, 8)}\u2026 error=skill-read-failed path=${skillPath} reason=${err instanceof Error ? err.message : String(err)}`);
|
|
10247
10168
|
}
|
|
@@ -10441,7 +10362,7 @@ ${block}`;
|
|
|
10441
10362
|
import { basename as basename2 } from "path";
|
|
10442
10363
|
|
|
10443
10364
|
// app/lib/review-detector/rules.ts
|
|
10444
|
-
import { readFileSync as
|
|
10365
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync7, statSync as statSync4, mkdirSync as mkdirSync5, renameSync } from "fs";
|
|
10445
10366
|
import { resolve as resolve7, dirname as dirname2 } from "path";
|
|
10446
10367
|
var DEFAULT_SCAN_INTERVAL_MS = 5e3;
|
|
10447
10368
|
var RATE_LIMIT_PATTERN = "rate[- ]?limit(?:ed| reached| hit)|(?:HTTP|status)[^a-z]{0,3}429|too many requests";
|
|
@@ -10773,36 +10694,23 @@ function defaultRules() {
|
|
|
10773
10694
|
suggestedAction: "A device-bound URL click failed to drive Chromium on the device's VNC display. Identify the `intent` and `hostname` from the log line, then check the VNC surface: read `vnc-boot.log` and confirm Chromium on :99 is responding on CDP port 9222. If CDP is unreachable, the operator needs to restart the VNC stack; if CDP is reachable but navigation errored, the URL itself may be malformed upstream \u2014 grep the stream log for the originating `[device-url:render]` line."
|
|
10774
10695
|
},
|
|
10775
10696
|
{
|
|
10776
|
-
// Task
|
|
10777
|
-
//
|
|
10778
|
-
//
|
|
10779
|
-
//
|
|
10780
|
-
//
|
|
10781
|
-
//
|
|
10782
|
-
//
|
|
10783
|
-
//
|
|
10784
|
-
//
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
// a pure `repeated-error` with the followup pattern only — accepts
|
|
10789
|
-
// the false-positive surface (other contexts where the agent asks
|
|
10790
|
-
// "Want me to X, or Y?") until 544 lands. Any such false-positive is
|
|
10791
|
-
// also caught by the pre-existing `agent-choice-fork` rule, so the
|
|
10792
|
-
// net observability cost is zero; the name and suggestedAction below
|
|
10793
|
-
// point a reader at Task 547 specifically when this rule fires
|
|
10794
|
-
// during a cloudflare setup. When 544 ships, migrate this to
|
|
10795
|
-
// `preceded-by` with triggerPattern="cloudflare-setup-run" and
|
|
10796
|
-
// followupWindow=5 lines.
|
|
10797
|
-
id: "orchestrator-mid-flow-fork",
|
|
10798
|
-
name: "Agent narration or fork during an orchestrated flow",
|
|
10799
|
-
type: "repeated-error",
|
|
10697
|
+
// Task 553: fires when `anthropic-setup` auto-resets a revoked API key.
|
|
10698
|
+
// The auto-reset is silent to the agent (the tool falls through to
|
|
10699
|
+
// awaiting_signin in the same call), but it is operator-visible — the
|
|
10700
|
+
// user's previously-stored key was just deleted because Anthropic
|
|
10701
|
+
// rejected it. Surfacing the event lets the admin agent explain on the
|
|
10702
|
+
// next turn why the user is being asked to sign in again instead of
|
|
10703
|
+
// continuing normally. The matching string is the exact stable prefix
|
|
10704
|
+
// emitted by the state machine immediately before `deleteKey()` is
|
|
10705
|
+
// invoked.
|
|
10706
|
+
id: "anthropic-setup-auth-error-auto-reset",
|
|
10707
|
+
name: "Anthropic API key auto-reset on auth_error",
|
|
10708
|
+
type: "silent-catch",
|
|
10800
10709
|
logSource: "any",
|
|
10801
|
-
pattern: "
|
|
10802
|
-
thresholdCount:
|
|
10803
|
-
thresholdWindowMinutes:
|
|
10804
|
-
|
|
10805
|
-
suggestedAction: "Review Task 547 \u2014 during an orchestrated flow (e.g. cloudflare-setup-run), the agent's only permitted output is relaying the tool's result verbatim and passing the operator's input through. Any forking or narrative prose is a deviation even though the tool-surface gate has filtered the deviating tools out of the menu. Check whether the offending turn occurred during a cloudflare setup (grep `[cloudflare:setup-run:` near this line); if so, the IDENTITY.md Tool-Surface Gates section may need a sharper reminder."
|
|
10710
|
+
pattern: "\\[anthropic-setup\\] auth_error",
|
|
10711
|
+
thresholdCount: 0,
|
|
10712
|
+
thresholdWindowMinutes: 0,
|
|
10713
|
+
suggestedAction: "The stored Anthropic API key was rejected by console.anthropic.com (invalid, revoked, or expired) and `anthropic-setup` auto-deleted it. On the next operator interaction, explain that the key was cleared and walk them through sign-in again via the onboarding skill \u2014 the tool already returned `awaiting_signin` with the correct `browser_evaluate` action on the same call."
|
|
10806
10714
|
}
|
|
10807
10715
|
];
|
|
10808
10716
|
}
|
|
@@ -10811,7 +10719,7 @@ function rulesFilePath(configDir2) {
|
|
|
10811
10719
|
}
|
|
10812
10720
|
function ensureRulesFile(configDir2) {
|
|
10813
10721
|
const path2 = rulesFilePath(configDir2);
|
|
10814
|
-
if (
|
|
10722
|
+
if (existsSync7(path2)) return { created: false, path: path2 };
|
|
10815
10723
|
mkdirSync5(dirname2(path2), { recursive: true });
|
|
10816
10724
|
const body = {
|
|
10817
10725
|
scanIntervalMs: DEFAULT_SCAN_INTERVAL_MS,
|
|
@@ -10822,10 +10730,10 @@ function ensureRulesFile(configDir2) {
|
|
|
10822
10730
|
}
|
|
10823
10731
|
function loadRules(configDir2) {
|
|
10824
10732
|
const path2 = rulesFilePath(configDir2);
|
|
10825
|
-
if (!
|
|
10733
|
+
if (!existsSync7(path2)) {
|
|
10826
10734
|
throw new Error(`rules file missing at ${path2}`);
|
|
10827
10735
|
}
|
|
10828
|
-
const raw2 =
|
|
10736
|
+
const raw2 = readFileSync8(path2, "utf-8");
|
|
10829
10737
|
let parsed;
|
|
10830
10738
|
try {
|
|
10831
10739
|
parsed = JSON.parse(raw2);
|
|
@@ -10990,16 +10898,16 @@ function validateRule(input, label, seenIds) {
|
|
|
10990
10898
|
}
|
|
10991
10899
|
|
|
10992
10900
|
// app/lib/review-detector/sources.ts
|
|
10993
|
-
import { existsSync as
|
|
10994
|
-
import { resolve as resolve8, join as
|
|
10901
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, statSync as statSync5, writeFileSync as writeFileSync7, renameSync as renameSync2, mkdirSync as mkdirSync6, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, readFileSync as readFileSync9 } from "fs";
|
|
10902
|
+
import { resolve as resolve8, join as join5, basename, dirname as dirname3 } from "path";
|
|
10995
10903
|
function tailStatePath(configDir2) {
|
|
10996
10904
|
return resolve8(configDir2, "review-state.json");
|
|
10997
10905
|
}
|
|
10998
10906
|
function loadTailState(configDir2) {
|
|
10999
10907
|
const path2 = tailStatePath(configDir2);
|
|
11000
|
-
if (!
|
|
10908
|
+
if (!existsSync8(path2)) return {};
|
|
11001
10909
|
try {
|
|
11002
|
-
const raw2 =
|
|
10910
|
+
const raw2 = readFileSync9(path2, "utf-8");
|
|
11003
10911
|
const parsed = JSON.parse(raw2);
|
|
11004
10912
|
if (!parsed || typeof parsed !== "object") return {};
|
|
11005
10913
|
const clean = {};
|
|
@@ -11025,18 +10933,18 @@ function saveTailState(configDir2, state) {
|
|
|
11025
10933
|
function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
|
|
11026
10934
|
if (logicalSource === "server") {
|
|
11027
10935
|
const p = resolve8(configDir2, "logs", "server.log");
|
|
11028
|
-
return
|
|
10936
|
+
return existsSync8(p) ? [{ logicalSource: "server", filepath: p }] : [];
|
|
11029
10937
|
}
|
|
11030
10938
|
if (logicalSource === "vnc") {
|
|
11031
10939
|
const p = resolve8(configDir2, "logs", "vnc-boot.log");
|
|
11032
|
-
return
|
|
10940
|
+
return existsSync8(p) ? [{ logicalSource: "vnc", filepath: p }] : [];
|
|
11033
10941
|
}
|
|
11034
10942
|
if (logicalSource === "cloudflared") {
|
|
11035
10943
|
const files2 = [];
|
|
11036
10944
|
const daemon = resolve8(configDir2, "logs", "cloudflared.log");
|
|
11037
|
-
if (
|
|
10945
|
+
if (existsSync8(daemon)) files2.push({ logicalSource: "cloudflared", filepath: daemon });
|
|
11038
10946
|
const login = resolve8(configDir2, "logs", "cloudflared-login.log");
|
|
11039
|
-
if (
|
|
10947
|
+
if (existsSync8(login)) files2.push({ logicalSource: "cloudflared", filepath: login });
|
|
11040
10948
|
return files2;
|
|
11041
10949
|
}
|
|
11042
10950
|
const prefix = {
|
|
@@ -11046,7 +10954,7 @@ function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
|
|
|
11046
10954
|
public: "public-agent-stream-",
|
|
11047
10955
|
mcp: "mcp-"
|
|
11048
10956
|
}[logicalSource];
|
|
11049
|
-
if (!
|
|
10957
|
+
if (!existsSync8(accountLogDir2)) return [];
|
|
11050
10958
|
const files = [];
|
|
11051
10959
|
let scanned = 0;
|
|
11052
10960
|
let skippedPrefixMismatch = 0;
|
|
@@ -11056,7 +10964,7 @@ function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
|
|
|
11056
10964
|
const matchesPrefix = entry.startsWith(prefix);
|
|
11057
10965
|
const isLog = entry.endsWith(".log");
|
|
11058
10966
|
if (matchesPrefix && isLog) {
|
|
11059
|
-
files.push({ logicalSource, filepath:
|
|
10967
|
+
files.push({ logicalSource, filepath: join5(accountLogDir2, entry) });
|
|
11060
10968
|
} else if (!matchesPrefix) {
|
|
11061
10969
|
skippedPrefixMismatch += 1;
|
|
11062
10970
|
} else {
|
|
@@ -11088,7 +10996,7 @@ function discoverAllSources(configDir2, accountLogDir2) {
|
|
|
11088
10996
|
];
|
|
11089
10997
|
}
|
|
11090
10998
|
function readNewLines(filepath, prev) {
|
|
11091
|
-
if (!
|
|
10999
|
+
if (!existsSync8(filepath)) return null;
|
|
11092
11000
|
const stat4 = statSync5(filepath);
|
|
11093
11001
|
const size = stat4.size;
|
|
11094
11002
|
const inode = stat4.ino;
|
|
@@ -11141,12 +11049,12 @@ function readNewLines(filepath, prev) {
|
|
|
11141
11049
|
}
|
|
11142
11050
|
}
|
|
11143
11051
|
function countRecentWrites(dir, sinceMs) {
|
|
11144
|
-
if (!
|
|
11052
|
+
if (!existsSync8(dir)) return 0;
|
|
11145
11053
|
let count = 0;
|
|
11146
11054
|
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
11147
11055
|
if (!entry.isFile()) continue;
|
|
11148
11056
|
try {
|
|
11149
|
-
const st = statSync5(
|
|
11057
|
+
const st = statSync5(join5(dir, entry.name));
|
|
11150
11058
|
if (st.mtimeMs >= sinceMs) count += 1;
|
|
11151
11059
|
} catch {
|
|
11152
11060
|
}
|
|
@@ -11154,7 +11062,7 @@ function countRecentWrites(dir, sinceMs) {
|
|
|
11154
11062
|
return count;
|
|
11155
11063
|
}
|
|
11156
11064
|
function fileLastWriteMs(path2) {
|
|
11157
|
-
if (!
|
|
11065
|
+
if (!existsSync8(path2)) return null;
|
|
11158
11066
|
try {
|
|
11159
11067
|
return statSync5(path2).mtimeMs;
|
|
11160
11068
|
} catch {
|
|
@@ -11169,7 +11077,7 @@ function sourceKey(file2) {
|
|
|
11169
11077
|
}
|
|
11170
11078
|
|
|
11171
11079
|
// app/lib/review-detector/writer.ts
|
|
11172
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
11080
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync8, renameSync as renameSync3, statSync as statSync6 } from "fs";
|
|
11173
11081
|
import { resolve as resolve9, dirname as dirname4 } from "path";
|
|
11174
11082
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
11175
11083
|
function reviewLogPath(configDir2) {
|
|
@@ -11307,8 +11215,8 @@ function queueAlert(configDir2, accountId, match2) {
|
|
|
11307
11215
|
}
|
|
11308
11216
|
async function drainPendingAlerts(configDir2) {
|
|
11309
11217
|
const path2 = pendingAlertsPath(configDir2);
|
|
11310
|
-
if (!
|
|
11311
|
-
const raw2 =
|
|
11218
|
+
if (!existsSync9(path2)) return { drained: 0, remaining: 0 };
|
|
11219
|
+
const raw2 = readFileSync10(path2, "utf-8");
|
|
11312
11220
|
const lines = raw2.split("\n").filter((l) => l.trim().length > 0);
|
|
11313
11221
|
if (lines.length === 0) return { drained: 0, remaining: 0 };
|
|
11314
11222
|
const remaining = [];
|
|
@@ -25738,16 +25646,16 @@ var WhatsAppConfigSchema = external_exports.object({
|
|
|
25738
25646
|
});
|
|
25739
25647
|
|
|
25740
25648
|
// app/lib/whatsapp/config-persist.ts
|
|
25741
|
-
import { readFileSync as
|
|
25742
|
-
import { resolve as resolve11, join as
|
|
25649
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync10 } from "fs";
|
|
25650
|
+
import { resolve as resolve11, join as join6 } from "path";
|
|
25743
25651
|
var TAG2 = "[whatsapp:config]";
|
|
25744
25652
|
function configPath(accountDir) {
|
|
25745
25653
|
return resolve11(accountDir, "account.json");
|
|
25746
25654
|
}
|
|
25747
25655
|
function readConfig(accountDir) {
|
|
25748
25656
|
const path2 = configPath(accountDir);
|
|
25749
|
-
if (!
|
|
25750
|
-
return JSON.parse(
|
|
25657
|
+
if (!existsSync10(path2)) throw new Error(`account.json not found at ${path2}`);
|
|
25658
|
+
return JSON.parse(readFileSync11(path2, "utf-8"));
|
|
25751
25659
|
}
|
|
25752
25660
|
function writeConfig(accountDir, config2) {
|
|
25753
25661
|
const path2 = configPath(accountDir);
|
|
@@ -25921,8 +25829,8 @@ function setPublicAgent(accountDir, slug) {
|
|
|
25921
25829
|
if (!trimmed) {
|
|
25922
25830
|
return { ok: false, error: "Agent slug cannot be empty." };
|
|
25923
25831
|
}
|
|
25924
|
-
const agentConfigPath =
|
|
25925
|
-
if (!
|
|
25832
|
+
const agentConfigPath = join6(accountDir, "agents", trimmed, "config.json");
|
|
25833
|
+
if (!existsSync10(agentConfigPath)) {
|
|
25926
25834
|
return { ok: false, error: `Agent "${trimmed}" not found \u2014 no config.json at ${agentConfigPath}. Check the agent slug and try again.` };
|
|
25927
25835
|
}
|
|
25928
25836
|
try {
|
|
@@ -26962,7 +26870,7 @@ async function sendMediaMessage(sock, to, media, opts) {
|
|
|
26962
26870
|
// app/lib/whatsapp/inbound/media.ts
|
|
26963
26871
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
26964
26872
|
import { writeFile, mkdir } from "fs/promises";
|
|
26965
|
-
import { join as
|
|
26873
|
+
import { join as join7 } from "path";
|
|
26966
26874
|
import {
|
|
26967
26875
|
downloadMediaMessage,
|
|
26968
26876
|
downloadContentFromMessage,
|
|
@@ -27048,7 +26956,7 @@ async function downloadInboundMedia(msg, sock, opts) {
|
|
|
27048
26956
|
await mkdir(MEDIA_DIR, { recursive: true });
|
|
27049
26957
|
const ext = mimeToExt(mimetype ?? "application/octet-stream");
|
|
27050
26958
|
const filename = `${randomUUID5()}.${ext}`;
|
|
27051
|
-
const filePath =
|
|
26959
|
+
const filePath = join7(MEDIA_DIR, filename);
|
|
27052
26960
|
await writeFile(filePath, buffer);
|
|
27053
26961
|
const sizeKB = (buffer.length / 1024).toFixed(0);
|
|
27054
26962
|
console.error(`${TAG8} media downloaded type=${mimetype ?? "unknown"} size=${sizeKB}KB path=${filePath}`);
|
|
@@ -28010,8 +27918,8 @@ async function GET(req, remoteAddress) {
|
|
|
28010
27918
|
const browserTransport = resolveBrowserTransport(req, remoteAddress);
|
|
28011
27919
|
let pinConfigured = false;
|
|
28012
27920
|
try {
|
|
28013
|
-
if (
|
|
28014
|
-
const raw2 =
|
|
27921
|
+
if (existsSync11(USERS_FILE)) {
|
|
27922
|
+
const raw2 = readFileSync12(USERS_FILE, "utf-8").trim();
|
|
28015
27923
|
if (raw2) {
|
|
28016
27924
|
const users = JSON.parse(raw2);
|
|
28017
27925
|
pinConfigured = Array.isArray(users) && users.length > 0;
|
|
@@ -28030,7 +27938,7 @@ async function GET(req, remoteAddress) {
|
|
|
28030
27938
|
const vncRunning = await checkPort(6080);
|
|
28031
27939
|
let apiKeyConfigured = false;
|
|
28032
27940
|
try {
|
|
28033
|
-
apiKeyConfigured =
|
|
27941
|
+
apiKeyConfigured = existsSync11(keyFilePath());
|
|
28034
27942
|
} catch {
|
|
28035
27943
|
}
|
|
28036
27944
|
let apiKeyStatus = "missing";
|
|
@@ -28098,7 +28006,7 @@ async function GET(req, remoteAddress) {
|
|
|
28098
28006
|
|
|
28099
28007
|
// app/api/session/route.ts
|
|
28100
28008
|
import { resolve as resolve12 } from "path";
|
|
28101
|
-
import { existsSync as
|
|
28009
|
+
import { existsSync as existsSync12, writeFileSync as writeFileSync10, mkdirSync as mkdirSync8 } from "fs";
|
|
28102
28010
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
28103
28011
|
async function POST(req) {
|
|
28104
28012
|
let body;
|
|
@@ -28149,7 +28057,7 @@ async function POST(req) {
|
|
|
28149
28057
|
if (account) {
|
|
28150
28058
|
const agentDir = resolve12(account.accountDir, "agents", agentSlug);
|
|
28151
28059
|
const agentConfigPath = resolve12(agentDir, "config.json");
|
|
28152
|
-
if (!
|
|
28060
|
+
if (!existsSync12(agentDir) || !existsSync12(agentConfigPath)) {
|
|
28153
28061
|
return Response.json({ error: "Agent not found" }, { status: 404 });
|
|
28154
28062
|
}
|
|
28155
28063
|
agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
|
|
@@ -28524,7 +28432,7 @@ async function storeGeneratedFile(accountId, filePath) {
|
|
|
28524
28432
|
// app/lib/stt/voice-note.ts
|
|
28525
28433
|
import { writeFile as writeFile3, mkdtemp, rm } from "fs/promises";
|
|
28526
28434
|
import { tmpdir } from "os";
|
|
28527
|
-
import { join as
|
|
28435
|
+
import { join as join8 } from "path";
|
|
28528
28436
|
var TAG13 = "[voice]";
|
|
28529
28437
|
var AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
28530
28438
|
"audio/ogg",
|
|
@@ -28562,9 +28470,9 @@ async function transcribeVoiceNote(file2, source) {
|
|
|
28562
28470
|
let tempDir;
|
|
28563
28471
|
let tempPath;
|
|
28564
28472
|
try {
|
|
28565
|
-
tempDir = await mkdtemp(
|
|
28473
|
+
tempDir = await mkdtemp(join8(tmpdir(), "voice-"));
|
|
28566
28474
|
const ext = audioExtension(mimeType);
|
|
28567
|
-
tempPath =
|
|
28475
|
+
tempPath = join8(tempDir, `recording${ext}`);
|
|
28568
28476
|
const buffer = Buffer.from(await file2.arrayBuffer());
|
|
28569
28477
|
await writeFile3(tempPath, buffer);
|
|
28570
28478
|
} catch (err) {
|
|
@@ -29115,7 +29023,7 @@ async function POST2(req) {
|
|
|
29115
29023
|
|
|
29116
29024
|
// app/lib/access-gate.ts
|
|
29117
29025
|
import neo4j2 from "neo4j-driver";
|
|
29118
|
-
import { readFileSync as
|
|
29026
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
29119
29027
|
import { resolve as resolve14 } from "path";
|
|
29120
29028
|
import { randomUUID as randomUUID7, randomInt } from "crypto";
|
|
29121
29029
|
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
|
|
@@ -29124,7 +29032,7 @@ function readPassword2() {
|
|
|
29124
29032
|
if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
|
|
29125
29033
|
const passwordFile = resolve14(PLATFORM_ROOT6, "config/.neo4j-password");
|
|
29126
29034
|
try {
|
|
29127
|
-
return
|
|
29035
|
+
return readFileSync13(passwordFile, "utf-8").trim();
|
|
29128
29036
|
} catch {
|
|
29129
29037
|
throw new Error(
|
|
29130
29038
|
`Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
|
|
@@ -29722,7 +29630,7 @@ async function POST6(req) {
|
|
|
29722
29630
|
}
|
|
29723
29631
|
|
|
29724
29632
|
// app/lib/brevo-sms.ts
|
|
29725
|
-
import { readFileSync as
|
|
29633
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, existsSync as existsSync13, chmodSync } from "fs";
|
|
29726
29634
|
import { dirname as dirname5 } from "path";
|
|
29727
29635
|
import { resolve as resolve15 } from "path";
|
|
29728
29636
|
var BREVO_API_KEY_FILE = resolve15(MAXY_DIR, ".brevo-api-key");
|
|
@@ -29733,8 +29641,8 @@ var platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
|
|
|
29733
29641
|
if (platformRoot2) {
|
|
29734
29642
|
try {
|
|
29735
29643
|
const brandPath3 = resolve15(platformRoot2, "config", "brand.json");
|
|
29736
|
-
if (
|
|
29737
|
-
const brand = JSON.parse(
|
|
29644
|
+
if (existsSync13(brandPath3)) {
|
|
29645
|
+
const brand = JSON.parse(readFileSync14(brandPath3, "utf-8"));
|
|
29738
29646
|
if (brand.productName) BREVO_SENDER = brand.productName;
|
|
29739
29647
|
}
|
|
29740
29648
|
} catch {
|
|
@@ -29742,7 +29650,7 @@ if (platformRoot2) {
|
|
|
29742
29650
|
}
|
|
29743
29651
|
function readBrevoApiKey() {
|
|
29744
29652
|
try {
|
|
29745
|
-
const key =
|
|
29653
|
+
const key = readFileSync14(BREVO_API_KEY_FILE, "utf-8").trim();
|
|
29746
29654
|
if (!key) {
|
|
29747
29655
|
throw new Error(`Brevo API key file is empty: ${BREVO_API_KEY_FILE}`);
|
|
29748
29656
|
}
|
|
@@ -29757,7 +29665,7 @@ function readBrevoApiKey() {
|
|
|
29757
29665
|
}
|
|
29758
29666
|
}
|
|
29759
29667
|
function hasBrevoApiKey() {
|
|
29760
|
-
return
|
|
29668
|
+
return existsSync13(BREVO_API_KEY_FILE);
|
|
29761
29669
|
}
|
|
29762
29670
|
async function sendSms(recipient, content, opts) {
|
|
29763
29671
|
let apiKey;
|
|
@@ -29922,15 +29830,15 @@ function checkTelegramAccess(params) {
|
|
|
29922
29830
|
}
|
|
29923
29831
|
|
|
29924
29832
|
// app/api/telegram/webhook/route.ts
|
|
29925
|
-
import { existsSync as
|
|
29833
|
+
import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
|
|
29926
29834
|
import { timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
29927
29835
|
var TAG15 = "[telegram-webhook]";
|
|
29928
29836
|
var TELEGRAM_API = "https://api.telegram.org";
|
|
29929
29837
|
function getWebhookSecret(botType) {
|
|
29930
29838
|
const filePath = botType === "admin" ? TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE : TELEGRAM_WEBHOOK_SECRET_FILE;
|
|
29931
29839
|
try {
|
|
29932
|
-
if (!
|
|
29933
|
-
const secret =
|
|
29840
|
+
if (!existsSync14(filePath)) return null;
|
|
29841
|
+
const secret = readFileSync15(filePath, "utf-8").trim();
|
|
29934
29842
|
return secret || null;
|
|
29935
29843
|
} catch {
|
|
29936
29844
|
return null;
|
|
@@ -30087,7 +29995,7 @@ async function POST8(req) {
|
|
|
30087
29995
|
}
|
|
30088
29996
|
|
|
30089
29997
|
// app/api/whatsapp/login/start/route.ts
|
|
30090
|
-
import { join as
|
|
29998
|
+
import { join as join9 } from "path";
|
|
30091
29999
|
|
|
30092
30000
|
// app/lib/whatsapp/login.ts
|
|
30093
30001
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
@@ -30317,7 +30225,7 @@ async function POST9(req) {
|
|
|
30317
30225
|
const body = await req.json().catch(() => ({}));
|
|
30318
30226
|
const accountId = validateAccountId(body.accountId);
|
|
30319
30227
|
const force = body.force ?? false;
|
|
30320
|
-
const authDir =
|
|
30228
|
+
const authDir = join9(MAXY_DIR, "credentials", "whatsapp", accountId);
|
|
30321
30229
|
const result = await startLogin({ accountId, authDir, force });
|
|
30322
30230
|
console.error(`[whatsapp:api] login/start result account=${accountId} hasQr=${!!result.qrRaw}${result.selfPhone ? ` phone=${result.selfPhone}` : ""}`);
|
|
30323
30231
|
return Response.json(result);
|
|
@@ -30531,7 +30439,7 @@ function serializeWhatsAppSchema() {
|
|
|
30531
30439
|
|
|
30532
30440
|
// app/api/whatsapp/config/route.ts
|
|
30533
30441
|
import { resolve as resolve16 } from "path";
|
|
30534
|
-
import { readdirSync as readdirSync4, readFileSync as
|
|
30442
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync16, existsSync as existsSync15 } from "fs";
|
|
30535
30443
|
async function POST14(req) {
|
|
30536
30444
|
try {
|
|
30537
30445
|
const body = await req.json().catch(() => ({}));
|
|
@@ -30581,15 +30489,15 @@ async function POST14(req) {
|
|
|
30581
30489
|
case "list-public-agents": {
|
|
30582
30490
|
const agentsDir = resolve16(account.accountDir, "agents");
|
|
30583
30491
|
const agents = [];
|
|
30584
|
-
if (
|
|
30492
|
+
if (existsSync15(agentsDir)) {
|
|
30585
30493
|
try {
|
|
30586
30494
|
const entries = readdirSync4(agentsDir, { withFileTypes: true });
|
|
30587
30495
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
30588
30496
|
if (!entry.isDirectory() || entry.name === "admin") continue;
|
|
30589
30497
|
const configPath2 = resolve16(agentsDir, entry.name, "config.json");
|
|
30590
|
-
if (!
|
|
30498
|
+
if (!existsSync15(configPath2)) continue;
|
|
30591
30499
|
try {
|
|
30592
|
-
const config2 = JSON.parse(
|
|
30500
|
+
const config2 = JSON.parse(readFileSync16(configPath2, "utf-8"));
|
|
30593
30501
|
agents.push({ slug: entry.name, displayName: config2.displayName ?? entry.name });
|
|
30594
30502
|
} catch {
|
|
30595
30503
|
console.error(`[whatsapp:api] config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
|
|
@@ -31005,15 +30913,15 @@ async function POST17(req, remoteAddress) {
|
|
|
31005
30913
|
}
|
|
31006
30914
|
|
|
31007
30915
|
// app/api/onboarding/set-pin/route.ts
|
|
31008
|
-
import { existsSync as
|
|
30916
|
+
import { existsSync as existsSync16, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync17, unlinkSync as unlinkSync3 } from "fs";
|
|
31009
30917
|
import { createHash, randomUUID as randomUUID9 } from "crypto";
|
|
31010
30918
|
import { dirname as dirname6 } from "path";
|
|
31011
30919
|
function hashPin(pin) {
|
|
31012
30920
|
return createHash("sha256").update(pin).digest("hex");
|
|
31013
30921
|
}
|
|
31014
30922
|
function readUsersFile() {
|
|
31015
|
-
if (!
|
|
31016
|
-
const raw2 =
|
|
30923
|
+
if (!existsSync16(USERS_FILE)) return null;
|
|
30924
|
+
const raw2 = readFileSync17(USERS_FILE, "utf-8").trim();
|
|
31017
30925
|
if (!raw2) return [];
|
|
31018
30926
|
return JSON.parse(raw2);
|
|
31019
30927
|
}
|
|
@@ -31051,7 +30959,7 @@ async function POST18(req) {
|
|
|
31051
30959
|
const account = resolveAccount();
|
|
31052
30960
|
if (account) {
|
|
31053
30961
|
try {
|
|
31054
|
-
const config2 = JSON.parse(
|
|
30962
|
+
const config2 = JSON.parse(readFileSync17(`${account.accountDir}/account.json`, "utf-8"));
|
|
31055
30963
|
if (!config2.admins) config2.admins = [];
|
|
31056
30964
|
if (!config2.admins.some((a) => a.userId === userId)) {
|
|
31057
30965
|
config2.admins.push({ userId, role: "owner" });
|
|
@@ -31092,7 +31000,7 @@ async function DELETE(req) {
|
|
|
31092
31000
|
}
|
|
31093
31001
|
const remaining = users.filter((u) => u.userId !== matchedUser.userId);
|
|
31094
31002
|
if (remaining.length === 0) {
|
|
31095
|
-
|
|
31003
|
+
unlinkSync3(USERS_FILE);
|
|
31096
31004
|
console.log(`[set-pin] cleared users.json (last entry removed): userId=${matchedUser.userId.slice(0, 8)}\u2026`);
|
|
31097
31005
|
} else {
|
|
31098
31006
|
writeFileSync13(USERS_FILE, JSON.stringify(remaining), { mode: 384 });
|
|
@@ -31102,7 +31010,7 @@ async function DELETE(req) {
|
|
|
31102
31010
|
}
|
|
31103
31011
|
|
|
31104
31012
|
// app/api/onboarding/skip/route.ts
|
|
31105
|
-
import { existsSync as
|
|
31013
|
+
import { existsSync as existsSync17, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync18 } from "fs";
|
|
31106
31014
|
import { resolve as resolve18, dirname as dirname7 } from "path";
|
|
31107
31015
|
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
31108
31016
|
async function POST19() {
|
|
@@ -31114,9 +31022,9 @@ async function POST19() {
|
|
|
31114
31022
|
const { accountId, accountDir } = account;
|
|
31115
31023
|
let agentName = "Maxy";
|
|
31116
31024
|
const brandPath3 = PLATFORM_ROOT8 ? resolve18(PLATFORM_ROOT8, "config", "brand.json") : "";
|
|
31117
|
-
if (brandPath3 &&
|
|
31025
|
+
if (brandPath3 && existsSync17(brandPath3)) {
|
|
31118
31026
|
try {
|
|
31119
|
-
const brand = JSON.parse(
|
|
31027
|
+
const brand = JSON.parse(readFileSync18(brandPath3, "utf-8"));
|
|
31120
31028
|
if (brand.productName) agentName = brand.productName;
|
|
31121
31029
|
} catch (err) {
|
|
31122
31030
|
console.error(`[onboarding-skip] brand.json read failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -31162,14 +31070,14 @@ async function POST19() {
|
|
|
31162
31070
|
}
|
|
31163
31071
|
|
|
31164
31072
|
// app/api/admin/session/route.ts
|
|
31165
|
-
import { readFileSync as
|
|
31073
|
+
import { readFileSync as readFileSync19, existsSync as existsSync18 } from "fs";
|
|
31166
31074
|
import { createHash as createHash2 } from "crypto";
|
|
31167
31075
|
function hashPin2(pin) {
|
|
31168
31076
|
return createHash2("sha256").update(pin).digest("hex");
|
|
31169
31077
|
}
|
|
31170
31078
|
function readUsersFile2() {
|
|
31171
|
-
if (!
|
|
31172
|
-
const raw2 =
|
|
31079
|
+
if (!existsSync18(USERS_FILE)) return null;
|
|
31080
|
+
const raw2 = readFileSync19(USERS_FILE, "utf-8").trim();
|
|
31173
31081
|
if (!raw2) return [];
|
|
31174
31082
|
return JSON.parse(raw2);
|
|
31175
31083
|
}
|
|
@@ -31570,7 +31478,7 @@ async function POST22(req) {
|
|
|
31570
31478
|
}
|
|
31571
31479
|
|
|
31572
31480
|
// app/api/admin/logs/route.ts
|
|
31573
|
-
import { existsSync as
|
|
31481
|
+
import { existsSync as existsSync19, readdirSync as readdirSync5, readFileSync as readFileSync20, statSync as statSync7 } from "fs";
|
|
31574
31482
|
import { resolve as resolve19, basename as basename5 } from "path";
|
|
31575
31483
|
var TAIL_BYTES = 8192;
|
|
31576
31484
|
async function GET9(request) {
|
|
@@ -31589,7 +31497,7 @@ async function GET9(request) {
|
|
|
31589
31497
|
const filePath = resolve19(dir, safe);
|
|
31590
31498
|
searched.push(filePath);
|
|
31591
31499
|
try {
|
|
31592
|
-
const content =
|
|
31500
|
+
const content = readFileSync20(filePath, "utf-8");
|
|
31593
31501
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
31594
31502
|
if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
|
|
31595
31503
|
return new Response(content, { headers });
|
|
@@ -31631,7 +31539,7 @@ async function GET9(request) {
|
|
|
31631
31539
|
const filePath = resolve19(dir, fileName);
|
|
31632
31540
|
searched.push(filePath);
|
|
31633
31541
|
try {
|
|
31634
|
-
const content =
|
|
31542
|
+
const content = readFileSync20(filePath, "utf-8");
|
|
31635
31543
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
31636
31544
|
if (download) headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
|
|
31637
31545
|
return new Response(content, { headers });
|
|
@@ -31646,7 +31554,7 @@ async function GET9(request) {
|
|
|
31646
31554
|
const seen = /* @__PURE__ */ new Set();
|
|
31647
31555
|
const logs = {};
|
|
31648
31556
|
for (const dir of [accountLogDir2, LOG_DIR]) {
|
|
31649
|
-
if (!dir || !
|
|
31557
|
+
if (!dir || !existsSync19(dir)) continue;
|
|
31650
31558
|
let files;
|
|
31651
31559
|
try {
|
|
31652
31560
|
files = readdirSync5(dir).filter((f) => f.endsWith(".log"));
|
|
@@ -31658,7 +31566,7 @@ async function GET9(request) {
|
|
|
31658
31566
|
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync7(resolve19(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
|
|
31659
31567
|
seen.add(name);
|
|
31660
31568
|
try {
|
|
31661
|
-
const content =
|
|
31569
|
+
const content = readFileSync20(resolve19(dir, name));
|
|
31662
31570
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
31663
31571
|
logs[name] = tail.trim() || "(empty)";
|
|
31664
31572
|
} catch (err) {
|
|
@@ -31695,7 +31603,7 @@ async function GET10() {
|
|
|
31695
31603
|
|
|
31696
31604
|
// app/api/admin/attachment/[attachmentId]/route.ts
|
|
31697
31605
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
31698
|
-
import { existsSync as
|
|
31606
|
+
import { existsSync as existsSync20 } from "fs";
|
|
31699
31607
|
import { resolve as resolve20 } from "path";
|
|
31700
31608
|
async function GET11(req, attachmentId) {
|
|
31701
31609
|
const sessionKey = new URL(req.url).searchParams.get("session_key") ?? "";
|
|
@@ -31710,11 +31618,11 @@ async function GET11(req, attachmentId) {
|
|
|
31710
31618
|
return new Response("Not found", { status: 404 });
|
|
31711
31619
|
}
|
|
31712
31620
|
const dir = resolve20(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
31713
|
-
if (!
|
|
31621
|
+
if (!existsSync20(dir)) {
|
|
31714
31622
|
return new Response("Not found", { status: 404 });
|
|
31715
31623
|
}
|
|
31716
31624
|
const metaPath = resolve20(dir, `${attachmentId}.meta.json`);
|
|
31717
|
-
if (!
|
|
31625
|
+
if (!existsSync20(metaPath)) {
|
|
31718
31626
|
return new Response("Not found", { status: 404 });
|
|
31719
31627
|
}
|
|
31720
31628
|
let meta3;
|
|
@@ -31740,7 +31648,7 @@ async function GET11(req, attachmentId) {
|
|
|
31740
31648
|
}
|
|
31741
31649
|
|
|
31742
31650
|
// app/api/admin/account/route.ts
|
|
31743
|
-
import { readFileSync as
|
|
31651
|
+
import { readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "fs";
|
|
31744
31652
|
import { resolve as resolve21 } from "path";
|
|
31745
31653
|
var VALID_CONTEXT_MODES = ["managed", "claude-code"];
|
|
31746
31654
|
async function PATCH(req) {
|
|
@@ -31766,7 +31674,7 @@ async function PATCH(req) {
|
|
|
31766
31674
|
}
|
|
31767
31675
|
const configPath2 = resolve21(account.accountDir, "account.json");
|
|
31768
31676
|
try {
|
|
31769
|
-
const raw2 =
|
|
31677
|
+
const raw2 = readFileSync21(configPath2, "utf-8");
|
|
31770
31678
|
const config2 = JSON.parse(raw2);
|
|
31771
31679
|
config2.contextMode = contextMode;
|
|
31772
31680
|
writeFileSync15(configPath2, JSON.stringify(config2, null, 2) + "\n", "utf-8");
|
|
@@ -31780,14 +31688,14 @@ async function PATCH(req) {
|
|
|
31780
31688
|
|
|
31781
31689
|
// app/api/admin/agents/route.ts
|
|
31782
31690
|
import { resolve as resolve22 } from "path";
|
|
31783
|
-
import { readdirSync as readdirSync6, readFileSync as
|
|
31691
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync22, existsSync as existsSync21 } from "fs";
|
|
31784
31692
|
async function GET12() {
|
|
31785
31693
|
const account = resolveAccount();
|
|
31786
31694
|
if (!account) {
|
|
31787
31695
|
return Response.json({ agents: [] });
|
|
31788
31696
|
}
|
|
31789
31697
|
const agentsDir = resolve22(account.accountDir, "agents");
|
|
31790
|
-
if (!
|
|
31698
|
+
if (!existsSync21(agentsDir)) {
|
|
31791
31699
|
return Response.json({ agents: [] });
|
|
31792
31700
|
}
|
|
31793
31701
|
const agents = [];
|
|
@@ -31797,9 +31705,9 @@ async function GET12() {
|
|
|
31797
31705
|
if (!entry.isDirectory()) continue;
|
|
31798
31706
|
if (entry.name === "admin") continue;
|
|
31799
31707
|
const configPath2 = resolve22(agentsDir, entry.name, "config.json");
|
|
31800
|
-
if (!
|
|
31708
|
+
if (!existsSync21(configPath2)) continue;
|
|
31801
31709
|
try {
|
|
31802
|
-
const config2 = JSON.parse(
|
|
31710
|
+
const config2 = JSON.parse(readFileSync22(configPath2, "utf-8"));
|
|
31803
31711
|
agents.push({
|
|
31804
31712
|
slug: entry.name,
|
|
31805
31713
|
displayName: config2.displayName ?? entry.name,
|
|
@@ -31818,7 +31726,7 @@ async function GET12() {
|
|
|
31818
31726
|
|
|
31819
31727
|
// app/api/admin/agents/[slug]/route.ts
|
|
31820
31728
|
import { resolve as resolve23 } from "path";
|
|
31821
|
-
import { existsSync as
|
|
31729
|
+
import { existsSync as existsSync22, rmSync as rmSync2 } from "fs";
|
|
31822
31730
|
async function DELETE2(_req, { params }) {
|
|
31823
31731
|
const { slug } = await params;
|
|
31824
31732
|
const account = resolveAccount();
|
|
@@ -31832,7 +31740,7 @@ async function DELETE2(_req, { params }) {
|
|
|
31832
31740
|
return Response.json({ error: "Invalid agent slug" }, { status: 400 });
|
|
31833
31741
|
}
|
|
31834
31742
|
const agentDir = resolve23(account.accountDir, "agents", slug);
|
|
31835
|
-
if (!
|
|
31743
|
+
if (!existsSync22(agentDir)) {
|
|
31836
31744
|
return Response.json({ error: "Agent not found" }, { status: 404 });
|
|
31837
31745
|
}
|
|
31838
31746
|
try {
|
|
@@ -31846,15 +31754,15 @@ async function DELETE2(_req, { params }) {
|
|
|
31846
31754
|
}
|
|
31847
31755
|
|
|
31848
31756
|
// app/api/admin/version/route.ts
|
|
31849
|
-
import { readFileSync as
|
|
31850
|
-
import { resolve as resolve24, join as
|
|
31757
|
+
import { readFileSync as readFileSync23, existsSync as existsSync23 } from "fs";
|
|
31758
|
+
import { resolve as resolve24, join as join10 } from "path";
|
|
31851
31759
|
var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
|
|
31852
31760
|
var brandHostname = "maxy";
|
|
31853
31761
|
var brandNpmPackage = "@rubytech/create-maxy";
|
|
31854
|
-
var brandJsonPath =
|
|
31855
|
-
if (
|
|
31762
|
+
var brandJsonPath = join10(PLATFORM_ROOT9, "config", "brand.json");
|
|
31763
|
+
if (existsSync23(brandJsonPath)) {
|
|
31856
31764
|
try {
|
|
31857
|
-
const brand = JSON.parse(
|
|
31765
|
+
const brand = JSON.parse(readFileSync23(brandJsonPath, "utf-8"));
|
|
31858
31766
|
if (brand.hostname) brandHostname = brand.hostname;
|
|
31859
31767
|
if (brand.npm?.packageName) brandNpmPackage = brand.npm.packageName;
|
|
31860
31768
|
} catch {
|
|
@@ -31865,8 +31773,8 @@ var NPM_PACKAGE = brandNpmPackage;
|
|
|
31865
31773
|
var REGISTRY_URL = `https://registry.npmjs.org/${NPM_PACKAGE}/latest`;
|
|
31866
31774
|
var FETCH_TIMEOUT_MS = 5e3;
|
|
31867
31775
|
function readInstalled() {
|
|
31868
|
-
if (!
|
|
31869
|
-
const content =
|
|
31776
|
+
if (!existsSync23(VERSION_FILE)) return "unknown";
|
|
31777
|
+
const content = readFileSync23(VERSION_FILE, "utf-8").trim();
|
|
31870
31778
|
return content || "unknown";
|
|
31871
31779
|
}
|
|
31872
31780
|
async function fetchLatest() {
|
|
@@ -31917,15 +31825,15 @@ async function GET13() {
|
|
|
31917
31825
|
|
|
31918
31826
|
// app/api/admin/version/upgrade/route.ts
|
|
31919
31827
|
import { spawn as spawn4 } from "child_process";
|
|
31920
|
-
import { existsSync as
|
|
31921
|
-
import { resolve as resolve25, join as
|
|
31828
|
+
import { existsSync as existsSync24, statSync as statSync8, writeFileSync as writeFileSync16, readFileSync as readFileSync24, openSync as openSync4, closeSync as closeSync4 } from "fs";
|
|
31829
|
+
import { resolve as resolve25, join as join11 } from "path";
|
|
31922
31830
|
var PLATFORM_ROOT10 = process.env.MAXY_PLATFORM_ROOT ?? resolve25(process.cwd(), "..");
|
|
31923
31831
|
var upgradePkg = "@rubytech/create-maxy";
|
|
31924
31832
|
var upgradeHostname = "maxy";
|
|
31925
|
-
var brandPath =
|
|
31926
|
-
if (
|
|
31833
|
+
var brandPath = join11(PLATFORM_ROOT10, "config", "brand.json");
|
|
31834
|
+
if (existsSync24(brandPath)) {
|
|
31927
31835
|
try {
|
|
31928
|
-
const brand = JSON.parse(
|
|
31836
|
+
const brand = JSON.parse(readFileSync24(brandPath, "utf-8"));
|
|
31929
31837
|
if (brand.npm?.packageName) upgradePkg = brand.npm.packageName;
|
|
31930
31838
|
if (brand.hostname) upgradeHostname = brand.hostname;
|
|
31931
31839
|
} catch {
|
|
@@ -31935,7 +31843,7 @@ var LOCK_FILE = `/tmp/${upgradeHostname}-upgrade.lock`;
|
|
|
31935
31843
|
var LOG_FILE = `/tmp/${upgradeHostname}-upgrade.log`;
|
|
31936
31844
|
var LOCK_MAX_AGE_MS = 20 * 60 * 1e3;
|
|
31937
31845
|
function isLockFresh() {
|
|
31938
|
-
if (!
|
|
31846
|
+
if (!existsSync24(LOCK_FILE)) return false;
|
|
31939
31847
|
try {
|
|
31940
31848
|
const stat4 = statSync8(LOCK_FILE);
|
|
31941
31849
|
return Date.now() - stat4.mtimeMs < LOCK_MAX_AGE_MS;
|
|
@@ -31995,14 +31903,14 @@ async function POST23(req) {
|
|
|
31995
31903
|
}
|
|
31996
31904
|
|
|
31997
31905
|
// app/api/admin/version/upgrade/progress/route.ts
|
|
31998
|
-
import { existsSync as
|
|
31999
|
-
import { resolve as resolve26, join as
|
|
31906
|
+
import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
|
|
31907
|
+
import { resolve as resolve26, join as join12 } from "path";
|
|
32000
31908
|
var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
|
|
32001
31909
|
var upgradeHostname2 = "maxy";
|
|
32002
|
-
var brandPath2 =
|
|
32003
|
-
if (
|
|
31910
|
+
var brandPath2 = join12(PLATFORM_ROOT11, "config", "brand.json");
|
|
31911
|
+
if (existsSync25(brandPath2)) {
|
|
32004
31912
|
try {
|
|
32005
|
-
const brand = JSON.parse(
|
|
31913
|
+
const brand = JSON.parse(readFileSync25(brandPath2, "utf-8"));
|
|
32006
31914
|
if (brand.hostname) upgradeHostname2 = brand.hostname;
|
|
32007
31915
|
} catch {
|
|
32008
31916
|
}
|
|
@@ -32010,12 +31918,12 @@ if (existsSync26(brandPath2)) {
|
|
|
32010
31918
|
var LOG_FILE2 = `/tmp/${upgradeHostname2}-upgrade.log`;
|
|
32011
31919
|
var STEP_RE = /\[(\d+)\/(\d+)\]\s+(.+)/;
|
|
32012
31920
|
async function GET14() {
|
|
32013
|
-
if (!
|
|
31921
|
+
if (!existsSync25(LOG_FILE2)) {
|
|
32014
31922
|
return Response.json({ step: 0, total: 0, label: "", started: false });
|
|
32015
31923
|
}
|
|
32016
31924
|
let content;
|
|
32017
31925
|
try {
|
|
32018
|
-
content =
|
|
31926
|
+
content = readFileSync25(LOG_FILE2, "utf-8");
|
|
32019
31927
|
} catch {
|
|
32020
31928
|
return Response.json({ step: 0, total: 0, label: "", started: false });
|
|
32021
31929
|
}
|
|
@@ -32481,14 +32389,14 @@ async function POST29(req) {
|
|
|
32481
32389
|
|
|
32482
32390
|
// server/index.ts
|
|
32483
32391
|
var PLATFORM_ROOT12 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
32484
|
-
var BRAND_JSON_PATH = PLATFORM_ROOT12 ?
|
|
32392
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT12 ? join13(PLATFORM_ROOT12, "config", "brand.json") : "";
|
|
32485
32393
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
|
|
32486
|
-
if (BRAND_JSON_PATH && !
|
|
32394
|
+
if (BRAND_JSON_PATH && !existsSync26(BRAND_JSON_PATH)) {
|
|
32487
32395
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
32488
32396
|
}
|
|
32489
|
-
if (BRAND_JSON_PATH &&
|
|
32397
|
+
if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
|
|
32490
32398
|
try {
|
|
32491
|
-
const parsed = JSON.parse(
|
|
32399
|
+
const parsed = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
|
|
32492
32400
|
BRAND = { ...BRAND, ...parsed };
|
|
32493
32401
|
} catch (err) {
|
|
32494
32402
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -32507,11 +32415,11 @@ var brandLoginOpts = {
|
|
|
32507
32415
|
bodyFont: BRAND.defaultFonts?.body,
|
|
32508
32416
|
logoContainsName: !!BRAND.logoContainsName
|
|
32509
32417
|
};
|
|
32510
|
-
var ALIAS_DOMAINS_PATH =
|
|
32418
|
+
var ALIAS_DOMAINS_PATH = join13(homedir4(), BRAND.configDir, "alias-domains.json");
|
|
32511
32419
|
function loadAliasDomains() {
|
|
32512
32420
|
try {
|
|
32513
|
-
if (!
|
|
32514
|
-
const parsed = JSON.parse(
|
|
32421
|
+
if (!existsSync26(ALIAS_DOMAINS_PATH)) return null;
|
|
32422
|
+
const parsed = JSON.parse(readFileSync26(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
32515
32423
|
if (!Array.isArray(parsed)) {
|
|
32516
32424
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
32517
32425
|
return null;
|
|
@@ -32929,14 +32837,14 @@ app.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
32929
32837
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
32930
32838
|
return c.text("Forbidden", 403);
|
|
32931
32839
|
}
|
|
32932
|
-
if (!
|
|
32840
|
+
if (!existsSync26(filePath)) {
|
|
32933
32841
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
32934
32842
|
return c.text("Not found", 404);
|
|
32935
32843
|
}
|
|
32936
32844
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
32937
32845
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
32938
32846
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
32939
|
-
const body =
|
|
32847
|
+
const body = readFileSync26(filePath);
|
|
32940
32848
|
return c.body(body, 200, {
|
|
32941
32849
|
"Content-Type": contentType,
|
|
32942
32850
|
"Cache-Control": "public, max-age=3600"
|
|
@@ -32959,14 +32867,14 @@ app.get("/generated/:filename", (c) => {
|
|
|
32959
32867
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
32960
32868
|
return c.text("Forbidden", 403);
|
|
32961
32869
|
}
|
|
32962
|
-
if (!
|
|
32870
|
+
if (!existsSync26(filePath)) {
|
|
32963
32871
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
32964
32872
|
return c.text("Not found", 404);
|
|
32965
32873
|
}
|
|
32966
32874
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
32967
32875
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
32968
32876
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
32969
|
-
const body =
|
|
32877
|
+
const body = readFileSync26(filePath);
|
|
32970
32878
|
return c.body(body, 200, {
|
|
32971
32879
|
"Content-Type": contentType,
|
|
32972
32880
|
"Cache-Control": "public, max-age=86400"
|
|
@@ -32975,9 +32883,9 @@ app.get("/generated/:filename", (c) => {
|
|
|
32975
32883
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
32976
32884
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
32977
32885
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
32978
|
-
if (BRAND_JSON_PATH &&
|
|
32886
|
+
if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
|
|
32979
32887
|
try {
|
|
32980
|
-
const fullBrand = JSON.parse(
|
|
32888
|
+
const fullBrand = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
|
|
32981
32889
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
32982
32890
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
32983
32891
|
} catch {
|
|
@@ -32994,7 +32902,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
32994
32902
|
function cachedHtml(file2) {
|
|
32995
32903
|
let html = htmlCache.get(file2);
|
|
32996
32904
|
if (!html) {
|
|
32997
|
-
html =
|
|
32905
|
+
html = readFileSync26(resolve27(process.cwd(), "public", file2), "utf-8");
|
|
32998
32906
|
html = html.replace("<title>Maxy</title>", `<title>${escapeHtml2(BRAND.productName)}</title>`);
|
|
32999
32907
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml2(brandFaviconPath)}"`);
|
|
33000
32908
|
html = html.replace("</head>", `${brandScript}
|
|
@@ -33005,26 +32913,26 @@ function cachedHtml(file2) {
|
|
|
33005
32913
|
}
|
|
33006
32914
|
var brandedHtmlCache = /* @__PURE__ */ new Map();
|
|
33007
32915
|
function loadBrandingCache(agentSlug) {
|
|
33008
|
-
const configDir2 =
|
|
32916
|
+
const configDir2 = join13(homedir4(), BRAND.configDir);
|
|
33009
32917
|
try {
|
|
33010
|
-
const accountJsonPath =
|
|
33011
|
-
if (!
|
|
33012
|
-
const account = JSON.parse(
|
|
32918
|
+
const accountJsonPath = join13(configDir2, "account.json");
|
|
32919
|
+
if (!existsSync26(accountJsonPath)) return null;
|
|
32920
|
+
const account = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
|
|
33013
32921
|
const accountId = account.accountId;
|
|
33014
32922
|
if (!accountId) return null;
|
|
33015
|
-
const cachePath =
|
|
33016
|
-
if (!
|
|
33017
|
-
return JSON.parse(
|
|
32923
|
+
const cachePath = join13(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
32924
|
+
if (!existsSync26(cachePath)) return null;
|
|
32925
|
+
return JSON.parse(readFileSync26(cachePath, "utf-8"));
|
|
33018
32926
|
} catch {
|
|
33019
32927
|
return null;
|
|
33020
32928
|
}
|
|
33021
32929
|
}
|
|
33022
32930
|
function resolveDefaultSlug() {
|
|
33023
32931
|
try {
|
|
33024
|
-
const configDir2 =
|
|
33025
|
-
const accountJsonPath =
|
|
33026
|
-
if (!
|
|
33027
|
-
const account = JSON.parse(
|
|
32932
|
+
const configDir2 = join13(homedir4(), BRAND.configDir);
|
|
32933
|
+
const accountJsonPath = join13(configDir2, "account.json");
|
|
32934
|
+
if (!existsSync26(accountJsonPath)) return null;
|
|
32935
|
+
const account = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
|
|
33028
32936
|
return account.defaultAgent || null;
|
|
33029
32937
|
} catch {
|
|
33030
32938
|
return null;
|
|
@@ -33097,7 +33005,7 @@ app.use("/vnc-popout.html", logViewerFetch);
|
|
|
33097
33005
|
app.get("/vnc-popout.html", (c) => {
|
|
33098
33006
|
let html = htmlCache.get("vnc-popout.html");
|
|
33099
33007
|
if (!html) {
|
|
33100
|
-
html =
|
|
33008
|
+
html = readFileSync26(resolve27(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
33101
33009
|
const name = escapeHtml2(BRAND.productName);
|
|
33102
33010
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
33103
33011
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -33151,8 +33059,8 @@ console.log(`${BRAND.productName} listening on http://${hostname3}:${port}`);
|
|
|
33151
33059
|
(async () => {
|
|
33152
33060
|
try {
|
|
33153
33061
|
let userId = "";
|
|
33154
|
-
if (
|
|
33155
|
-
const users = JSON.parse(
|
|
33062
|
+
if (existsSync26(USERS_FILE)) {
|
|
33063
|
+
const users = JSON.parse(readFileSync26(USERS_FILE, "utf-8").trim() || "[]");
|
|
33156
33064
|
userId = users[0]?.userId ?? "";
|
|
33157
33065
|
}
|
|
33158
33066
|
await backfillNullUserIdConversations(userId);
|
|
@@ -33178,7 +33086,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
33178
33086
|
}
|
|
33179
33087
|
init({
|
|
33180
33088
|
configDir: configDirForWhatsApp,
|
|
33181
|
-
platformRoot: resolve27(process.env.MAXY_PLATFORM_ROOT ??
|
|
33089
|
+
platformRoot: resolve27(process.env.MAXY_PLATFORM_ROOT ?? join13(__dirname, "..")),
|
|
33182
33090
|
accountConfig: bootAccountConfig,
|
|
33183
33091
|
onMessage: async (msg) => {
|
|
33184
33092
|
try {
|