@rubytech/create-maxy 1.0.623 → 1.0.624
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +1 -1
- 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 +187 -299
- 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
|
|
@@ -4164,9 +4164,9 @@ function keyFilePath() {
|
|
|
4164
4164
|
import Anthropic2 from "@anthropic-ai/sdk";
|
|
4165
4165
|
import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
|
|
4166
4166
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
4167
|
-
import { resolve as resolve6, join as
|
|
4167
|
+
import { resolve as resolve6, join as join4 } from "path";
|
|
4168
4168
|
import { platform as osPlatform } from "os";
|
|
4169
|
-
import { readFileSync as
|
|
4169
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, readdirSync as readdirSync2, existsSync as existsSync6, mkdirSync as mkdirSync4, createWriteStream, statSync as statSync3, unlinkSync, cpSync, rmSync } from "fs";
|
|
4170
4170
|
import { lookup as dnsLookup } from "dns/promises";
|
|
4171
4171
|
import { createConnection as netConnect } from "net";
|
|
4172
4172
|
import { StringDecoder } from "string_decoder";
|
|
@@ -6037,73 +6037,6 @@ ${items}
|
|
|
6037
6037
|
</commitment-detected>`;
|
|
6038
6038
|
}
|
|
6039
6039
|
|
|
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
6040
|
// app/lib/claude-agent.ts
|
|
6108
6041
|
var LOG_RETENTION_DAYS = 7;
|
|
6109
6042
|
var BROWSER_TOOL_PREFIXES = [
|
|
@@ -6337,7 +6270,7 @@ function sampleProcState(pid) {
|
|
|
6337
6270
|
let sockets2 = 0;
|
|
6338
6271
|
for (const tcpFile of ["/proc/" + pid + "/net/tcp", "/proc/" + pid + "/net/tcp6"]) {
|
|
6339
6272
|
try {
|
|
6340
|
-
const raw2 =
|
|
6273
|
+
const raw2 = readFileSync7(tcpFile, "utf-8");
|
|
6341
6274
|
const lines2 = raw2.split("\n");
|
|
6342
6275
|
for (let i = 1; i < lines2.length; i++) {
|
|
6343
6276
|
const line = lines2[i].trim();
|
|
@@ -6353,7 +6286,7 @@ function sampleProcState(pid) {
|
|
|
6353
6286
|
}
|
|
6354
6287
|
let rssMb = 0;
|
|
6355
6288
|
try {
|
|
6356
|
-
const statm =
|
|
6289
|
+
const statm = readFileSync7(`/proc/${pid}/statm`, "utf-8").trim().split(/\s+/);
|
|
6357
6290
|
const rssPages = parseInt(statm[1] ?? "0", 10);
|
|
6358
6291
|
if (Number.isFinite(rssPages)) rssMb = Math.round(rssPages * 4096 / (1024 * 1024));
|
|
6359
6292
|
} catch {
|
|
@@ -6388,19 +6321,19 @@ function sampleProcState(pid) {
|
|
|
6388
6321
|
}
|
|
6389
6322
|
var PLATFORM_ROOT4 = process.env.MAXY_PLATFORM_ROOT ?? resolve6(process.cwd(), "..");
|
|
6390
6323
|
var ACCOUNTS_DIR = resolve6(PLATFORM_ROOT4, "..", "data/accounts");
|
|
6391
|
-
if (!
|
|
6324
|
+
if (!existsSync6(PLATFORM_ROOT4)) {
|
|
6392
6325
|
throw new Error(
|
|
6393
6326
|
`PLATFORM_ROOT does not exist: ${PLATFORM_ROOT4}
|
|
6394
6327
|
Set the MAXY_PLATFORM_ROOT environment variable to the absolute path of the platform directory.`
|
|
6395
6328
|
);
|
|
6396
6329
|
}
|
|
6397
6330
|
function resolveAccount() {
|
|
6398
|
-
if (!
|
|
6331
|
+
if (!existsSync6(ACCOUNTS_DIR)) return null;
|
|
6399
6332
|
const usersFilePath = resolve6(PLATFORM_ROOT4, "config", "users.json");
|
|
6400
6333
|
let usersJsonUserId = null;
|
|
6401
|
-
if (
|
|
6334
|
+
if (existsSync6(usersFilePath)) {
|
|
6402
6335
|
try {
|
|
6403
|
-
const raw2 =
|
|
6336
|
+
const raw2 = readFileSync7(usersFilePath, "utf-8").trim();
|
|
6404
6337
|
if (raw2) {
|
|
6405
6338
|
const users = JSON.parse(raw2);
|
|
6406
6339
|
if (users.length > 0) {
|
|
@@ -6415,8 +6348,8 @@ function resolveAccount() {
|
|
|
6415
6348
|
for (const entry of entries) {
|
|
6416
6349
|
if (!entry.isDirectory()) continue;
|
|
6417
6350
|
const configPath2 = resolve6(ACCOUNTS_DIR, entry.name, "account.json");
|
|
6418
|
-
if (!
|
|
6419
|
-
const raw2 =
|
|
6351
|
+
if (!existsSync6(configPath2)) continue;
|
|
6352
|
+
const raw2 = readFileSync7(configPath2, "utf-8");
|
|
6420
6353
|
let config2;
|
|
6421
6354
|
try {
|
|
6422
6355
|
config2 = JSON.parse(raw2);
|
|
@@ -6450,8 +6383,8 @@ function resolveAccount() {
|
|
|
6450
6383
|
}
|
|
6451
6384
|
function readAgentFile(accountDir, agentName, filename) {
|
|
6452
6385
|
const filePath = resolve6(accountDir, "agents", agentName, filename);
|
|
6453
|
-
if (!
|
|
6454
|
-
return
|
|
6386
|
+
if (!existsSync6(filePath)) return null;
|
|
6387
|
+
return readFileSync7(filePath, "utf-8");
|
|
6455
6388
|
}
|
|
6456
6389
|
function readIdentity(accountDir, agentName) {
|
|
6457
6390
|
return readAgentFile(accountDir, agentName, "IDENTITY.md");
|
|
@@ -6468,13 +6401,13 @@ function validateAgentSlug(slug) {
|
|
|
6468
6401
|
}
|
|
6469
6402
|
function resolveDefaultAgentSlug(accountDir) {
|
|
6470
6403
|
const configPath2 = resolve6(accountDir, "account.json");
|
|
6471
|
-
if (!
|
|
6404
|
+
if (!existsSync6(configPath2)) {
|
|
6472
6405
|
console.error("[agent-resolve] account.json not found \u2014 cannot resolve defaultAgent");
|
|
6473
6406
|
return null;
|
|
6474
6407
|
}
|
|
6475
6408
|
let config2;
|
|
6476
6409
|
try {
|
|
6477
|
-
config2 = JSON.parse(
|
|
6410
|
+
config2 = JSON.parse(readFileSync7(configPath2, "utf-8"));
|
|
6478
6411
|
} catch (err) {
|
|
6479
6412
|
console.error("[agent-resolve] failed to read account.json:", err);
|
|
6480
6413
|
return null;
|
|
@@ -6484,7 +6417,7 @@ function resolveDefaultAgentSlug(accountDir) {
|
|
|
6484
6417
|
return null;
|
|
6485
6418
|
}
|
|
6486
6419
|
const agentConfigPath = resolve6(accountDir, "agents", config2.defaultAgent, "config.json");
|
|
6487
|
-
if (!
|
|
6420
|
+
if (!existsSync6(agentConfigPath)) {
|
|
6488
6421
|
console.error(`[agent-resolve] defaultAgent="${config2.defaultAgent}" has no config.json at ${agentConfigPath}`);
|
|
6489
6422
|
return null;
|
|
6490
6423
|
}
|
|
@@ -6559,20 +6492,20 @@ function resolveAgentConfig(accountDir, agentName) {
|
|
|
6559
6492
|
const agentDir = resolve6(accountDir, "agents", agentName);
|
|
6560
6493
|
const knowledgePath = resolve6(agentDir, "KNOWLEDGE.md");
|
|
6561
6494
|
const summaryPath = resolve6(agentDir, "KNOWLEDGE-SUMMARY.md");
|
|
6562
|
-
const hasKnowledge =
|
|
6563
|
-
const hasSummary =
|
|
6495
|
+
const hasKnowledge = existsSync6(knowledgePath);
|
|
6496
|
+
const hasSummary = existsSync6(summaryPath);
|
|
6564
6497
|
if (hasKnowledge && hasSummary) {
|
|
6565
6498
|
const knowledgeMtime = statSync3(knowledgePath).mtimeMs;
|
|
6566
6499
|
const summaryMtime = statSync3(summaryPath).mtimeMs;
|
|
6567
6500
|
if (summaryMtime >= knowledgeMtime) {
|
|
6568
|
-
knowledge =
|
|
6501
|
+
knowledge = readFileSync7(summaryPath, "utf-8");
|
|
6569
6502
|
} else {
|
|
6570
6503
|
console.warn(`[agent-config] ${agentName}: KNOWLEDGE-SUMMARY.md is stale (KNOWLEDGE.md is newer) \u2014 using full knowledge`);
|
|
6571
|
-
knowledge =
|
|
6504
|
+
knowledge = readFileSync7(knowledgePath, "utf-8");
|
|
6572
6505
|
}
|
|
6573
6506
|
knowledgeBaked = true;
|
|
6574
6507
|
} else if (hasKnowledge) {
|
|
6575
|
-
knowledge =
|
|
6508
|
+
knowledge = readFileSync7(knowledgePath, "utf-8");
|
|
6576
6509
|
knowledgeBaked = true;
|
|
6577
6510
|
}
|
|
6578
6511
|
let budget = null;
|
|
@@ -6595,10 +6528,10 @@ function resolveAgentConfig(accountDir, agentName) {
|
|
|
6595
6528
|
}
|
|
6596
6529
|
function parsePluginFrontmatter(pluginDir) {
|
|
6597
6530
|
const pluginPath = resolve6(PLATFORM_ROOT4, "plugins", pluginDir, "PLUGIN.md");
|
|
6598
|
-
if (!
|
|
6531
|
+
if (!existsSync6(pluginPath)) return null;
|
|
6599
6532
|
let raw2;
|
|
6600
6533
|
try {
|
|
6601
|
-
raw2 =
|
|
6534
|
+
raw2 = readFileSync7(pluginPath, "utf-8");
|
|
6602
6535
|
} catch {
|
|
6603
6536
|
console.warn(`[plugins] cannot read ${pluginPath}`);
|
|
6604
6537
|
return null;
|
|
@@ -6659,22 +6592,22 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
|
|
|
6659
6592
|
const TAG18 = "[premium-auto-deliver]";
|
|
6660
6593
|
const stagingRoot = resolve6(PLATFORM_ROOT4, "../premium-plugins");
|
|
6661
6594
|
const pluginsDir = resolve6(PLATFORM_ROOT4, "plugins");
|
|
6662
|
-
if (!
|
|
6595
|
+
if (!existsSync6(stagingRoot)) {
|
|
6663
6596
|
console.log(`${TAG18} no staging directory \u2014 skipping`);
|
|
6664
6597
|
return;
|
|
6665
6598
|
}
|
|
6666
6599
|
for (const pluginName of purchasedPlugins) {
|
|
6667
6600
|
const stagingDir = resolve6(stagingRoot, pluginName);
|
|
6668
|
-
if (!
|
|
6601
|
+
if (!existsSync6(stagingDir)) {
|
|
6669
6602
|
console.log(`${TAG18} ${pluginName}: not in staging \u2014 skipping`);
|
|
6670
6603
|
continue;
|
|
6671
6604
|
}
|
|
6672
|
-
const bundlePath =
|
|
6673
|
-
const isBundle =
|
|
6605
|
+
const bundlePath = join4(stagingDir, "BUNDLE.md");
|
|
6606
|
+
const isBundle = existsSync6(bundlePath);
|
|
6674
6607
|
if (isBundle) {
|
|
6675
6608
|
let bundleRaw;
|
|
6676
6609
|
try {
|
|
6677
|
-
bundleRaw =
|
|
6610
|
+
bundleRaw = readFileSync7(bundlePath, "utf-8");
|
|
6678
6611
|
} catch (err) {
|
|
6679
6612
|
console.log(`${TAG18} ${pluginName}: cannot read BUNDLE.md \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
6680
6613
|
continue;
|
|
@@ -6706,12 +6639,12 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
|
|
|
6706
6639
|
let skipped = 0;
|
|
6707
6640
|
for (const sub of subPlugins) {
|
|
6708
6641
|
const target = resolve6(pluginsDir, sub);
|
|
6709
|
-
if (
|
|
6642
|
+
if (existsSync6(resolve6(target, "PLUGIN.md"))) {
|
|
6710
6643
|
skipped++;
|
|
6711
6644
|
continue;
|
|
6712
6645
|
}
|
|
6713
6646
|
const source = resolve6(stagingDir, "plugins", sub);
|
|
6714
|
-
if (!
|
|
6647
|
+
if (!existsSync6(source)) {
|
|
6715
6648
|
console.log(`${TAG18} ${pluginName}/${sub}: source missing in staging \u2014 skipping`);
|
|
6716
6649
|
continue;
|
|
6717
6650
|
}
|
|
@@ -6725,7 +6658,7 @@ function autoDeliverPremiumPlugins(purchasedPlugins) {
|
|
|
6725
6658
|
console.log(`${TAG18} ${pluginName} (bundle): ${delivered} delivered, ${skipped} already present`);
|
|
6726
6659
|
} else {
|
|
6727
6660
|
const target = resolve6(pluginsDir, pluginName);
|
|
6728
|
-
if (
|
|
6661
|
+
if (existsSync6(resolve6(target, "PLUGIN.md"))) {
|
|
6729
6662
|
console.log(`${TAG18} ${pluginName}: already present \u2014 skipping`);
|
|
6730
6663
|
continue;
|
|
6731
6664
|
}
|
|
@@ -6767,7 +6700,7 @@ function migratePluginRenames(accountDir, config2) {
|
|
|
6767
6700
|
if (!changed) return;
|
|
6768
6701
|
const configPath2 = resolve6(accountDir, "account.json");
|
|
6769
6702
|
try {
|
|
6770
|
-
const raw2 =
|
|
6703
|
+
const raw2 = readFileSync7(configPath2, "utf-8");
|
|
6771
6704
|
const parsed = JSON.parse(raw2);
|
|
6772
6705
|
parsed.enabledPlugins = migrated;
|
|
6773
6706
|
writeFileSync5(configPath2, JSON.stringify(parsed, null, 2) + "\n");
|
|
@@ -6779,7 +6712,7 @@ function migratePluginRenames(accountDir, config2) {
|
|
|
6779
6712
|
const pluginsDir = resolve6(PLATFORM_ROOT4, "plugins");
|
|
6780
6713
|
for (const oldName of Object.keys(PLUGIN_RENAMES)) {
|
|
6781
6714
|
const orphan = resolve6(pluginsDir, oldName);
|
|
6782
|
-
if (
|
|
6715
|
+
if (existsSync6(orphan)) {
|
|
6783
6716
|
try {
|
|
6784
6717
|
rmSync(orphan, { recursive: true });
|
|
6785
6718
|
console.log(`${TAG18} removed orphan: ${oldName}`);
|
|
@@ -6794,20 +6727,20 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
|
|
|
6794
6727
|
const TAG18 = "[bundle-agent-deliver]";
|
|
6795
6728
|
const stagingRoot = resolve6(PLATFORM_ROOT4, "../premium-plugins");
|
|
6796
6729
|
const specialistsDir = resolve6(accountDir, "specialists", "agents");
|
|
6797
|
-
if (!
|
|
6798
|
-
if (!
|
|
6730
|
+
if (!existsSync6(stagingRoot)) return;
|
|
6731
|
+
if (!existsSync6(specialistsDir)) {
|
|
6799
6732
|
mkdirSync4(specialistsDir, { recursive: true });
|
|
6800
6733
|
}
|
|
6801
6734
|
const agentsmdPath = resolve6(accountDir, "agents", "admin", "AGENTS.md");
|
|
6802
6735
|
let agentsmd = "";
|
|
6803
6736
|
try {
|
|
6804
|
-
agentsmd =
|
|
6737
|
+
agentsmd = existsSync6(agentsmdPath) ? readFileSync7(agentsmdPath, "utf-8") : "";
|
|
6805
6738
|
} catch {
|
|
6806
6739
|
}
|
|
6807
6740
|
let delivered = 0;
|
|
6808
6741
|
for (const pluginName of purchasedPlugins) {
|
|
6809
6742
|
const bundleAgentsDir = resolve6(stagingRoot, pluginName, "agents");
|
|
6810
|
-
if (!
|
|
6743
|
+
if (!existsSync6(bundleAgentsDir)) continue;
|
|
6811
6744
|
let entries;
|
|
6812
6745
|
try {
|
|
6813
6746
|
entries = readdirSync2(bundleAgentsDir).filter((f) => f.endsWith(".md"));
|
|
@@ -6816,7 +6749,7 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
|
|
|
6816
6749
|
}
|
|
6817
6750
|
for (const filename of entries) {
|
|
6818
6751
|
const target = resolve6(specialistsDir, filename);
|
|
6819
|
-
if (
|
|
6752
|
+
if (existsSync6(target)) continue;
|
|
6820
6753
|
const source = resolve6(bundleAgentsDir, filename);
|
|
6821
6754
|
try {
|
|
6822
6755
|
cpSync(source, target);
|
|
@@ -6825,7 +6758,7 @@ function autoDeliverBundleAgents(accountDir, purchasedPlugins) {
|
|
|
6825
6758
|
continue;
|
|
6826
6759
|
}
|
|
6827
6760
|
try {
|
|
6828
|
-
const content =
|
|
6761
|
+
const content = readFileSync7(target, "utf-8");
|
|
6829
6762
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
6830
6763
|
if (fmMatch) {
|
|
6831
6764
|
const nameMatch = fmMatch[1].match(/^name:\s*(.+)/m);
|
|
@@ -6861,7 +6794,7 @@ function assemblePublicPluginContent(pluginDir) {
|
|
|
6861
6794
|
const pluginPath = resolve6(pluginRoot, "PLUGIN.md");
|
|
6862
6795
|
let raw2;
|
|
6863
6796
|
try {
|
|
6864
|
-
raw2 =
|
|
6797
|
+
raw2 = readFileSync7(pluginPath, "utf-8");
|
|
6865
6798
|
} catch {
|
|
6866
6799
|
return null;
|
|
6867
6800
|
}
|
|
@@ -6882,7 +6815,7 @@ function assemblePublicPluginContent(pluginDir) {
|
|
|
6882
6815
|
const skillMdPath = resolve6(skillDir, "SKILL.md");
|
|
6883
6816
|
let skillRaw;
|
|
6884
6817
|
try {
|
|
6885
|
-
skillRaw =
|
|
6818
|
+
skillRaw = readFileSync7(skillMdPath, "utf-8");
|
|
6886
6819
|
} catch {
|
|
6887
6820
|
continue;
|
|
6888
6821
|
}
|
|
@@ -6933,7 +6866,7 @@ function assemblePublicPluginContent(pluginDir) {
|
|
|
6933
6866
|
}
|
|
6934
6867
|
for (const refFile of refFiles) {
|
|
6935
6868
|
try {
|
|
6936
|
-
const refContent =
|
|
6869
|
+
const refContent = readFileSync7(resolve6(refsDir, refFile), "utf-8").trim();
|
|
6937
6870
|
if (refContent) {
|
|
6938
6871
|
parts.push(`
|
|
6939
6872
|
<!-- reference: ${refFile} -->`);
|
|
@@ -7007,7 +6940,7 @@ function loadEmbeddedPlugins(agentType, selectedPlugins, enabledPlugins) {
|
|
|
7007
6940
|
const pluginPath = resolve6(pluginsDir, dir, "PLUGIN.md");
|
|
7008
6941
|
let raw2;
|
|
7009
6942
|
try {
|
|
7010
|
-
raw2 =
|
|
6943
|
+
raw2 = readFileSync7(pluginPath, "utf-8");
|
|
7011
6944
|
} catch (err) {
|
|
7012
6945
|
console.warn(`[plugins] ${dir}: failed to read PLUGIN.md for ${agentType} embed: ${String(err)}`);
|
|
7013
6946
|
continue;
|
|
@@ -7032,7 +6965,7 @@ function fetchMcpToolsList(pluginDir) {
|
|
|
7032
6965
|
const cached2 = mcpToolsCache.get(pluginDir);
|
|
7033
6966
|
if (cached2) return Promise.resolve(cached2);
|
|
7034
6967
|
const serverPath = resolve6(PLATFORM_ROOT4, "plugins", pluginDir, "mcp/dist/index.js");
|
|
7035
|
-
if (!
|
|
6968
|
+
if (!existsSync6(serverPath)) return Promise.resolve([]);
|
|
7036
6969
|
const startMs = Date.now();
|
|
7037
6970
|
return new Promise((resolvePromise) => {
|
|
7038
6971
|
const proc = spawn2(process.execPath, [serverPath], {
|
|
@@ -7236,7 +7169,7 @@ ${specialist}: ${plugins.join(", ")}`);
|
|
|
7236
7169
|
const references = [];
|
|
7237
7170
|
const scanDir = (base, prefix, target) => {
|
|
7238
7171
|
const scanPath = resolve6(pluginRoot, base);
|
|
7239
|
-
if (!
|
|
7172
|
+
if (!existsSync6(scanPath)) return;
|
|
7240
7173
|
try {
|
|
7241
7174
|
const walk = (current, rel) => {
|
|
7242
7175
|
for (const entry of readdirSync2(current)) {
|
|
@@ -7269,7 +7202,7 @@ ${specialist}: ${plugins.join(", ")}`);
|
|
|
7269
7202
|
}
|
|
7270
7203
|
} else if (parsed.tools.length > 0) {
|
|
7271
7204
|
const serverPath = resolve6(PLATFORM_ROOT4, "plugins", dir, "mcp/dist/index.js");
|
|
7272
|
-
if (
|
|
7205
|
+
if (existsSync6(serverPath)) {
|
|
7273
7206
|
fallbackSourced++;
|
|
7274
7207
|
console.error(`[plugin-manifest] ${dir}: tools/list empty \u2014 fallback to frontmatter (${parsed.tools.length} tools)`);
|
|
7275
7208
|
}
|
|
@@ -7344,16 +7277,16 @@ function getDefaultAccountId() {
|
|
|
7344
7277
|
return resolveAccount()?.accountId ?? null;
|
|
7345
7278
|
}
|
|
7346
7279
|
function resolveUserAccounts(userId) {
|
|
7347
|
-
if (!
|
|
7280
|
+
if (!existsSync6(ACCOUNTS_DIR)) return [];
|
|
7348
7281
|
const results = [];
|
|
7349
7282
|
const entries = readdirSync2(ACCOUNTS_DIR, { withFileTypes: true });
|
|
7350
7283
|
for (const entry of entries) {
|
|
7351
7284
|
if (!entry.isDirectory()) continue;
|
|
7352
7285
|
const configPath2 = resolve6(ACCOUNTS_DIR, entry.name, "account.json");
|
|
7353
|
-
if (!
|
|
7286
|
+
if (!existsSync6(configPath2)) continue;
|
|
7354
7287
|
let config2;
|
|
7355
7288
|
try {
|
|
7356
|
-
config2 = JSON.parse(
|
|
7289
|
+
config2 = JSON.parse(readFileSync7(configPath2, "utf-8"));
|
|
7357
7290
|
} catch {
|
|
7358
7291
|
console.error(`[session] account.json corrupt at ${configPath2} \u2014 skipping`);
|
|
7359
7292
|
continue;
|
|
@@ -7673,7 +7606,7 @@ function getMcpServers(accountId, conversationId, userId, enabledPlugins) {
|
|
|
7673
7606
|
}
|
|
7674
7607
|
}
|
|
7675
7608
|
const mcpEntry = resolve6(PLATFORM_ROOT4, "plugins", dir, "mcp/dist/index.js");
|
|
7676
|
-
if (!
|
|
7609
|
+
if (!existsSync6(mcpEntry)) continue;
|
|
7677
7610
|
servers[dir] = {
|
|
7678
7611
|
command: "node",
|
|
7679
7612
|
args: [mcpEntry],
|
|
@@ -7751,16 +7684,6 @@ var ADMIN_CORE_TOOLS = [
|
|
|
7751
7684
|
"mcp__admin__action-approve",
|
|
7752
7685
|
"mcp__admin__action-reject",
|
|
7753
7686
|
"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
7687
|
"mcp__tasks__task-create",
|
|
7765
7688
|
"mcp__tasks__task-update",
|
|
7766
7689
|
"mcp__tasks__task-list",
|
|
@@ -7827,10 +7750,7 @@ function getAdminAllowedTools(enabledPlugins) {
|
|
|
7827
7750
|
return tools;
|
|
7828
7751
|
}
|
|
7829
7752
|
function assembleAllowedToolsForAdminSpawn(enabledPlugins) {
|
|
7830
|
-
|
|
7831
|
-
const result = applyToolSurfaceFilters(base);
|
|
7832
|
-
logToolSurfaceFilter(result);
|
|
7833
|
-
return result.tools;
|
|
7753
|
+
return getAdminAllowedTools(enabledPlugins);
|
|
7834
7754
|
}
|
|
7835
7755
|
var QUERY_CLASSIFIER_MODEL = HAIKU_MODEL2;
|
|
7836
7756
|
var QUERY_CLASSIFIER_TIMEOUT_MS = 3e3;
|
|
@@ -7920,7 +7840,7 @@ ${message.slice(0, QUERY_CLASSIFIER_MSG_CAP)}`
|
|
|
7920
7840
|
}
|
|
7921
7841
|
async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
7922
7842
|
const serverPath = resolve6(PLATFORM_ROOT4, "plugins/memory/mcp/dist/index.js");
|
|
7923
|
-
if (!
|
|
7843
|
+
if (!existsSync6(serverPath)) {
|
|
7924
7844
|
console.error(`[fetchMemoryContext] MCP server not found: ${serverPath}`);
|
|
7925
7845
|
return null;
|
|
7926
7846
|
}
|
|
@@ -8018,7 +7938,7 @@ async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
|
8018
7938
|
async function compactTrimmedMessages(accountId, trimmedMessages) {
|
|
8019
7939
|
if (trimmedMessages.length === 0) return true;
|
|
8020
7940
|
const serverPath = resolve6(PLATFORM_ROOT4, "plugins/memory/mcp/dist/index.js");
|
|
8021
|
-
if (!
|
|
7941
|
+
if (!existsSync6(serverPath)) return false;
|
|
8022
7942
|
const briefing = trimmedMessages.map((m) => `[${m.role.toUpperCase()}] ${m.content}`).join("\n\n");
|
|
8023
7943
|
return new Promise((resolvePromise) => {
|
|
8024
7944
|
const proc = spawn2(process.execPath, [serverPath], {
|
|
@@ -8336,7 +8256,7 @@ var COMPACTION_TIMEOUT_MS = 45e3;
|
|
|
8336
8256
|
async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSessionId, adminModel, conversationId, enabledPlugins) {
|
|
8337
8257
|
const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, conversationId, void 0, enabledPlugins) });
|
|
8338
8258
|
const specialistsDir = resolve6(accountDir, "specialists");
|
|
8339
|
-
if (!
|
|
8259
|
+
if (!existsSync6(specialistsDir)) agentLogStream("claude-agent-compaction-stream", accountDir, conversationId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
8340
8260
|
`);
|
|
8341
8261
|
const args = [
|
|
8342
8262
|
"--print",
|
|
@@ -9225,7 +9145,7 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9225
9145
|
const ccUserId = sessionKey ? getUserIdForSession(sessionKey) : void 0;
|
|
9226
9146
|
const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, spawnConvId, ccUserId, enabledPlugins) });
|
|
9227
9147
|
const specialistsDir = resolve6(accountDir, "specialists");
|
|
9228
|
-
if (!
|
|
9148
|
+
if (!existsSync6(specialistsDir)) agentLogStream("claude-agent-stream", accountDir, spawnConvId).write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
9229
9149
|
`);
|
|
9230
9150
|
const args = [
|
|
9231
9151
|
"--print",
|
|
@@ -9571,7 +9491,7 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
9571
9491
|
const managedUserId = getUserIdForSession(sessionKey);
|
|
9572
9492
|
const mcpConfig = JSON.stringify({ mcpServers: getMcpServers(accountId, managedConvId, managedUserId, enabledPlugins) });
|
|
9573
9493
|
const specialistsDir = resolve6(accountDir, "specialists");
|
|
9574
|
-
if (!
|
|
9494
|
+
if (!existsSync6(specialistsDir)) streamLog.write(`[${isoTs()}] [warn] specialists plugin dir missing: ${specialistsDir}
|
|
9575
9495
|
`);
|
|
9576
9496
|
const fullMessage = attachments.length > 0 ? message + buildAttachmentMetaText(attachments) : message;
|
|
9577
9497
|
const args = [
|
|
@@ -10241,7 +10161,7 @@ ${sessionContext}`;
|
|
|
10241
10161
|
const skillPath = resolve6(PLATFORM_ROOT4, "plugins/admin/skills/onboarding/SKILL.md");
|
|
10242
10162
|
let skillContent = "";
|
|
10243
10163
|
try {
|
|
10244
|
-
skillContent =
|
|
10164
|
+
skillContent = readFileSync7(skillPath, "utf-8");
|
|
10245
10165
|
} catch (err) {
|
|
10246
10166
|
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
10167
|
}
|
|
@@ -10441,7 +10361,7 @@ ${block}`;
|
|
|
10441
10361
|
import { basename as basename2 } from "path";
|
|
10442
10362
|
|
|
10443
10363
|
// app/lib/review-detector/rules.ts
|
|
10444
|
-
import { readFileSync as
|
|
10364
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync7, statSync as statSync4, mkdirSync as mkdirSync5, renameSync } from "fs";
|
|
10445
10365
|
import { resolve as resolve7, dirname as dirname2 } from "path";
|
|
10446
10366
|
var DEFAULT_SCAN_INTERVAL_MS = 5e3;
|
|
10447
10367
|
var RATE_LIMIT_PATTERN = "rate[- ]?limit(?:ed| reached| hit)|(?:HTTP|status)[^a-z]{0,3}429|too many requests";
|
|
@@ -10771,38 +10691,6 @@ function defaultRules() {
|
|
|
10771
10691
|
thresholdCount: 0,
|
|
10772
10692
|
thresholdWindowMinutes: 0,
|
|
10773
10693
|
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
|
-
},
|
|
10775
|
-
{
|
|
10776
|
-
// Task 547: catches agent prose that forks or narrates during an
|
|
10777
|
-
// orchestrated flow. The tool-surface gate filters the raw tunnel-*
|
|
10778
|
-
// tools, Playwright, and Bash/Write/Edit while cloudflare-setup-run
|
|
10779
|
-
// is mid-flow, so the agent cannot *call* a deviating tool — but the
|
|
10780
|
-
// agent could still narrate ("Want me to kick off the login flow
|
|
10781
|
-
// now?", "Or would you prefer to do it manually?"). This rule catches
|
|
10782
|
-
// that narration surface.
|
|
10783
|
-
//
|
|
10784
|
-
// The task file prescribes a `preceded-by` rule type (scopes the
|
|
10785
|
-
// followup pattern to a window after a `cloudflare-setup-run` tool
|
|
10786
|
-
// result). That type is introduced by Task 544, which has not
|
|
10787
|
-
// shipped at the time of writing. The fallback named in Task 547 is
|
|
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",
|
|
10800
|
-
logSource: "any",
|
|
10801
|
-
pattern: "(Want me to|Should I|Do you want me|Or would you|Either way|Meanwhile)[^\\n]+\\?",
|
|
10802
|
-
thresholdCount: 1,
|
|
10803
|
-
thresholdWindowMinutes: 60,
|
|
10804
|
-
scope: "session",
|
|
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."
|
|
10806
10694
|
}
|
|
10807
10695
|
];
|
|
10808
10696
|
}
|
|
@@ -10811,7 +10699,7 @@ function rulesFilePath(configDir2) {
|
|
|
10811
10699
|
}
|
|
10812
10700
|
function ensureRulesFile(configDir2) {
|
|
10813
10701
|
const path2 = rulesFilePath(configDir2);
|
|
10814
|
-
if (
|
|
10702
|
+
if (existsSync7(path2)) return { created: false, path: path2 };
|
|
10815
10703
|
mkdirSync5(dirname2(path2), { recursive: true });
|
|
10816
10704
|
const body = {
|
|
10817
10705
|
scanIntervalMs: DEFAULT_SCAN_INTERVAL_MS,
|
|
@@ -10822,10 +10710,10 @@ function ensureRulesFile(configDir2) {
|
|
|
10822
10710
|
}
|
|
10823
10711
|
function loadRules(configDir2) {
|
|
10824
10712
|
const path2 = rulesFilePath(configDir2);
|
|
10825
|
-
if (!
|
|
10713
|
+
if (!existsSync7(path2)) {
|
|
10826
10714
|
throw new Error(`rules file missing at ${path2}`);
|
|
10827
10715
|
}
|
|
10828
|
-
const raw2 =
|
|
10716
|
+
const raw2 = readFileSync8(path2, "utf-8");
|
|
10829
10717
|
let parsed;
|
|
10830
10718
|
try {
|
|
10831
10719
|
parsed = JSON.parse(raw2);
|
|
@@ -10990,16 +10878,16 @@ function validateRule(input, label, seenIds) {
|
|
|
10990
10878
|
}
|
|
10991
10879
|
|
|
10992
10880
|
// app/lib/review-detector/sources.ts
|
|
10993
|
-
import { existsSync as
|
|
10994
|
-
import { resolve as resolve8, join as
|
|
10881
|
+
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";
|
|
10882
|
+
import { resolve as resolve8, join as join5, basename, dirname as dirname3 } from "path";
|
|
10995
10883
|
function tailStatePath(configDir2) {
|
|
10996
10884
|
return resolve8(configDir2, "review-state.json");
|
|
10997
10885
|
}
|
|
10998
10886
|
function loadTailState(configDir2) {
|
|
10999
10887
|
const path2 = tailStatePath(configDir2);
|
|
11000
|
-
if (!
|
|
10888
|
+
if (!existsSync8(path2)) return {};
|
|
11001
10889
|
try {
|
|
11002
|
-
const raw2 =
|
|
10890
|
+
const raw2 = readFileSync9(path2, "utf-8");
|
|
11003
10891
|
const parsed = JSON.parse(raw2);
|
|
11004
10892
|
if (!parsed || typeof parsed !== "object") return {};
|
|
11005
10893
|
const clean = {};
|
|
@@ -11025,18 +10913,18 @@ function saveTailState(configDir2, state) {
|
|
|
11025
10913
|
function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
|
|
11026
10914
|
if (logicalSource === "server") {
|
|
11027
10915
|
const p = resolve8(configDir2, "logs", "server.log");
|
|
11028
|
-
return
|
|
10916
|
+
return existsSync8(p) ? [{ logicalSource: "server", filepath: p }] : [];
|
|
11029
10917
|
}
|
|
11030
10918
|
if (logicalSource === "vnc") {
|
|
11031
10919
|
const p = resolve8(configDir2, "logs", "vnc-boot.log");
|
|
11032
|
-
return
|
|
10920
|
+
return existsSync8(p) ? [{ logicalSource: "vnc", filepath: p }] : [];
|
|
11033
10921
|
}
|
|
11034
10922
|
if (logicalSource === "cloudflared") {
|
|
11035
10923
|
const files2 = [];
|
|
11036
10924
|
const daemon = resolve8(configDir2, "logs", "cloudflared.log");
|
|
11037
|
-
if (
|
|
10925
|
+
if (existsSync8(daemon)) files2.push({ logicalSource: "cloudflared", filepath: daemon });
|
|
11038
10926
|
const login = resolve8(configDir2, "logs", "cloudflared-login.log");
|
|
11039
|
-
if (
|
|
10927
|
+
if (existsSync8(login)) files2.push({ logicalSource: "cloudflared", filepath: login });
|
|
11040
10928
|
return files2;
|
|
11041
10929
|
}
|
|
11042
10930
|
const prefix = {
|
|
@@ -11046,7 +10934,7 @@ function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
|
|
|
11046
10934
|
public: "public-agent-stream-",
|
|
11047
10935
|
mcp: "mcp-"
|
|
11048
10936
|
}[logicalSource];
|
|
11049
|
-
if (!
|
|
10937
|
+
if (!existsSync8(accountLogDir2)) return [];
|
|
11050
10938
|
const files = [];
|
|
11051
10939
|
let scanned = 0;
|
|
11052
10940
|
let skippedPrefixMismatch = 0;
|
|
@@ -11056,7 +10944,7 @@ function discoverSourceFiles(configDir2, accountLogDir2, logicalSource) {
|
|
|
11056
10944
|
const matchesPrefix = entry.startsWith(prefix);
|
|
11057
10945
|
const isLog = entry.endsWith(".log");
|
|
11058
10946
|
if (matchesPrefix && isLog) {
|
|
11059
|
-
files.push({ logicalSource, filepath:
|
|
10947
|
+
files.push({ logicalSource, filepath: join5(accountLogDir2, entry) });
|
|
11060
10948
|
} else if (!matchesPrefix) {
|
|
11061
10949
|
skippedPrefixMismatch += 1;
|
|
11062
10950
|
} else {
|
|
@@ -11088,7 +10976,7 @@ function discoverAllSources(configDir2, accountLogDir2) {
|
|
|
11088
10976
|
];
|
|
11089
10977
|
}
|
|
11090
10978
|
function readNewLines(filepath, prev) {
|
|
11091
|
-
if (!
|
|
10979
|
+
if (!existsSync8(filepath)) return null;
|
|
11092
10980
|
const stat4 = statSync5(filepath);
|
|
11093
10981
|
const size = stat4.size;
|
|
11094
10982
|
const inode = stat4.ino;
|
|
@@ -11141,12 +11029,12 @@ function readNewLines(filepath, prev) {
|
|
|
11141
11029
|
}
|
|
11142
11030
|
}
|
|
11143
11031
|
function countRecentWrites(dir, sinceMs) {
|
|
11144
|
-
if (!
|
|
11032
|
+
if (!existsSync8(dir)) return 0;
|
|
11145
11033
|
let count = 0;
|
|
11146
11034
|
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
11147
11035
|
if (!entry.isFile()) continue;
|
|
11148
11036
|
try {
|
|
11149
|
-
const st = statSync5(
|
|
11037
|
+
const st = statSync5(join5(dir, entry.name));
|
|
11150
11038
|
if (st.mtimeMs >= sinceMs) count += 1;
|
|
11151
11039
|
} catch {
|
|
11152
11040
|
}
|
|
@@ -11154,7 +11042,7 @@ function countRecentWrites(dir, sinceMs) {
|
|
|
11154
11042
|
return count;
|
|
11155
11043
|
}
|
|
11156
11044
|
function fileLastWriteMs(path2) {
|
|
11157
|
-
if (!
|
|
11045
|
+
if (!existsSync8(path2)) return null;
|
|
11158
11046
|
try {
|
|
11159
11047
|
return statSync5(path2).mtimeMs;
|
|
11160
11048
|
} catch {
|
|
@@ -11169,7 +11057,7 @@ function sourceKey(file2) {
|
|
|
11169
11057
|
}
|
|
11170
11058
|
|
|
11171
11059
|
// app/lib/review-detector/writer.ts
|
|
11172
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
11060
|
+
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
11061
|
import { resolve as resolve9, dirname as dirname4 } from "path";
|
|
11174
11062
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
11175
11063
|
function reviewLogPath(configDir2) {
|
|
@@ -11307,8 +11195,8 @@ function queueAlert(configDir2, accountId, match2) {
|
|
|
11307
11195
|
}
|
|
11308
11196
|
async function drainPendingAlerts(configDir2) {
|
|
11309
11197
|
const path2 = pendingAlertsPath(configDir2);
|
|
11310
|
-
if (!
|
|
11311
|
-
const raw2 =
|
|
11198
|
+
if (!existsSync9(path2)) return { drained: 0, remaining: 0 };
|
|
11199
|
+
const raw2 = readFileSync10(path2, "utf-8");
|
|
11312
11200
|
const lines = raw2.split("\n").filter((l) => l.trim().length > 0);
|
|
11313
11201
|
if (lines.length === 0) return { drained: 0, remaining: 0 };
|
|
11314
11202
|
const remaining = [];
|
|
@@ -25738,16 +25626,16 @@ var WhatsAppConfigSchema = external_exports.object({
|
|
|
25738
25626
|
});
|
|
25739
25627
|
|
|
25740
25628
|
// app/lib/whatsapp/config-persist.ts
|
|
25741
|
-
import { readFileSync as
|
|
25742
|
-
import { resolve as resolve11, join as
|
|
25629
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync10 } from "fs";
|
|
25630
|
+
import { resolve as resolve11, join as join6 } from "path";
|
|
25743
25631
|
var TAG2 = "[whatsapp:config]";
|
|
25744
25632
|
function configPath(accountDir) {
|
|
25745
25633
|
return resolve11(accountDir, "account.json");
|
|
25746
25634
|
}
|
|
25747
25635
|
function readConfig(accountDir) {
|
|
25748
25636
|
const path2 = configPath(accountDir);
|
|
25749
|
-
if (!
|
|
25750
|
-
return JSON.parse(
|
|
25637
|
+
if (!existsSync10(path2)) throw new Error(`account.json not found at ${path2}`);
|
|
25638
|
+
return JSON.parse(readFileSync11(path2, "utf-8"));
|
|
25751
25639
|
}
|
|
25752
25640
|
function writeConfig(accountDir, config2) {
|
|
25753
25641
|
const path2 = configPath(accountDir);
|
|
@@ -25921,8 +25809,8 @@ function setPublicAgent(accountDir, slug) {
|
|
|
25921
25809
|
if (!trimmed) {
|
|
25922
25810
|
return { ok: false, error: "Agent slug cannot be empty." };
|
|
25923
25811
|
}
|
|
25924
|
-
const agentConfigPath =
|
|
25925
|
-
if (!
|
|
25812
|
+
const agentConfigPath = join6(accountDir, "agents", trimmed, "config.json");
|
|
25813
|
+
if (!existsSync10(agentConfigPath)) {
|
|
25926
25814
|
return { ok: false, error: `Agent "${trimmed}" not found \u2014 no config.json at ${agentConfigPath}. Check the agent slug and try again.` };
|
|
25927
25815
|
}
|
|
25928
25816
|
try {
|
|
@@ -26962,7 +26850,7 @@ async function sendMediaMessage(sock, to, media, opts) {
|
|
|
26962
26850
|
// app/lib/whatsapp/inbound/media.ts
|
|
26963
26851
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
26964
26852
|
import { writeFile, mkdir } from "fs/promises";
|
|
26965
|
-
import { join as
|
|
26853
|
+
import { join as join7 } from "path";
|
|
26966
26854
|
import {
|
|
26967
26855
|
downloadMediaMessage,
|
|
26968
26856
|
downloadContentFromMessage,
|
|
@@ -27048,7 +26936,7 @@ async function downloadInboundMedia(msg, sock, opts) {
|
|
|
27048
26936
|
await mkdir(MEDIA_DIR, { recursive: true });
|
|
27049
26937
|
const ext = mimeToExt(mimetype ?? "application/octet-stream");
|
|
27050
26938
|
const filename = `${randomUUID5()}.${ext}`;
|
|
27051
|
-
const filePath =
|
|
26939
|
+
const filePath = join7(MEDIA_DIR, filename);
|
|
27052
26940
|
await writeFile(filePath, buffer);
|
|
27053
26941
|
const sizeKB = (buffer.length / 1024).toFixed(0);
|
|
27054
26942
|
console.error(`${TAG8} media downloaded type=${mimetype ?? "unknown"} size=${sizeKB}KB path=${filePath}`);
|
|
@@ -28010,8 +27898,8 @@ async function GET(req, remoteAddress) {
|
|
|
28010
27898
|
const browserTransport = resolveBrowserTransport(req, remoteAddress);
|
|
28011
27899
|
let pinConfigured = false;
|
|
28012
27900
|
try {
|
|
28013
|
-
if (
|
|
28014
|
-
const raw2 =
|
|
27901
|
+
if (existsSync11(USERS_FILE)) {
|
|
27902
|
+
const raw2 = readFileSync12(USERS_FILE, "utf-8").trim();
|
|
28015
27903
|
if (raw2) {
|
|
28016
27904
|
const users = JSON.parse(raw2);
|
|
28017
27905
|
pinConfigured = Array.isArray(users) && users.length > 0;
|
|
@@ -28030,7 +27918,7 @@ async function GET(req, remoteAddress) {
|
|
|
28030
27918
|
const vncRunning = await checkPort(6080);
|
|
28031
27919
|
let apiKeyConfigured = false;
|
|
28032
27920
|
try {
|
|
28033
|
-
apiKeyConfigured =
|
|
27921
|
+
apiKeyConfigured = existsSync11(keyFilePath());
|
|
28034
27922
|
} catch {
|
|
28035
27923
|
}
|
|
28036
27924
|
let apiKeyStatus = "missing";
|
|
@@ -28098,7 +27986,7 @@ async function GET(req, remoteAddress) {
|
|
|
28098
27986
|
|
|
28099
27987
|
// app/api/session/route.ts
|
|
28100
27988
|
import { resolve as resolve12 } from "path";
|
|
28101
|
-
import { existsSync as
|
|
27989
|
+
import { existsSync as existsSync12, writeFileSync as writeFileSync10, mkdirSync as mkdirSync8 } from "fs";
|
|
28102
27990
|
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
27991
|
async function POST(req) {
|
|
28104
27992
|
let body;
|
|
@@ -28149,7 +28037,7 @@ async function POST(req) {
|
|
|
28149
28037
|
if (account) {
|
|
28150
28038
|
const agentDir = resolve12(account.accountDir, "agents", agentSlug);
|
|
28151
28039
|
const agentConfigPath = resolve12(agentDir, "config.json");
|
|
28152
|
-
if (!
|
|
28040
|
+
if (!existsSync12(agentDir) || !existsSync12(agentConfigPath)) {
|
|
28153
28041
|
return Response.json({ error: "Agent not found" }, { status: 404 });
|
|
28154
28042
|
}
|
|
28155
28043
|
agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
|
|
@@ -28524,7 +28412,7 @@ async function storeGeneratedFile(accountId, filePath) {
|
|
|
28524
28412
|
// app/lib/stt/voice-note.ts
|
|
28525
28413
|
import { writeFile as writeFile3, mkdtemp, rm } from "fs/promises";
|
|
28526
28414
|
import { tmpdir } from "os";
|
|
28527
|
-
import { join as
|
|
28415
|
+
import { join as join8 } from "path";
|
|
28528
28416
|
var TAG13 = "[voice]";
|
|
28529
28417
|
var AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
28530
28418
|
"audio/ogg",
|
|
@@ -28562,9 +28450,9 @@ async function transcribeVoiceNote(file2, source) {
|
|
|
28562
28450
|
let tempDir;
|
|
28563
28451
|
let tempPath;
|
|
28564
28452
|
try {
|
|
28565
|
-
tempDir = await mkdtemp(
|
|
28453
|
+
tempDir = await mkdtemp(join8(tmpdir(), "voice-"));
|
|
28566
28454
|
const ext = audioExtension(mimeType);
|
|
28567
|
-
tempPath =
|
|
28455
|
+
tempPath = join8(tempDir, `recording${ext}`);
|
|
28568
28456
|
const buffer = Buffer.from(await file2.arrayBuffer());
|
|
28569
28457
|
await writeFile3(tempPath, buffer);
|
|
28570
28458
|
} catch (err) {
|
|
@@ -29115,7 +29003,7 @@ async function POST2(req) {
|
|
|
29115
29003
|
|
|
29116
29004
|
// app/lib/access-gate.ts
|
|
29117
29005
|
import neo4j2 from "neo4j-driver";
|
|
29118
|
-
import { readFileSync as
|
|
29006
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
29119
29007
|
import { resolve as resolve14 } from "path";
|
|
29120
29008
|
import { randomUUID as randomUUID7, randomInt } from "crypto";
|
|
29121
29009
|
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
|
|
@@ -29124,7 +29012,7 @@ function readPassword2() {
|
|
|
29124
29012
|
if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
|
|
29125
29013
|
const passwordFile = resolve14(PLATFORM_ROOT6, "config/.neo4j-password");
|
|
29126
29014
|
try {
|
|
29127
|
-
return
|
|
29015
|
+
return readFileSync13(passwordFile, "utf-8").trim();
|
|
29128
29016
|
} catch {
|
|
29129
29017
|
throw new Error(
|
|
29130
29018
|
`Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
|
|
@@ -29722,7 +29610,7 @@ async function POST6(req) {
|
|
|
29722
29610
|
}
|
|
29723
29611
|
|
|
29724
29612
|
// app/lib/brevo-sms.ts
|
|
29725
|
-
import { readFileSync as
|
|
29613
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, existsSync as existsSync13, chmodSync } from "fs";
|
|
29726
29614
|
import { dirname as dirname5 } from "path";
|
|
29727
29615
|
import { resolve as resolve15 } from "path";
|
|
29728
29616
|
var BREVO_API_KEY_FILE = resolve15(MAXY_DIR, ".brevo-api-key");
|
|
@@ -29733,8 +29621,8 @@ var platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
|
|
|
29733
29621
|
if (platformRoot2) {
|
|
29734
29622
|
try {
|
|
29735
29623
|
const brandPath3 = resolve15(platformRoot2, "config", "brand.json");
|
|
29736
|
-
if (
|
|
29737
|
-
const brand = JSON.parse(
|
|
29624
|
+
if (existsSync13(brandPath3)) {
|
|
29625
|
+
const brand = JSON.parse(readFileSync14(brandPath3, "utf-8"));
|
|
29738
29626
|
if (brand.productName) BREVO_SENDER = brand.productName;
|
|
29739
29627
|
}
|
|
29740
29628
|
} catch {
|
|
@@ -29742,7 +29630,7 @@ if (platformRoot2) {
|
|
|
29742
29630
|
}
|
|
29743
29631
|
function readBrevoApiKey() {
|
|
29744
29632
|
try {
|
|
29745
|
-
const key =
|
|
29633
|
+
const key = readFileSync14(BREVO_API_KEY_FILE, "utf-8").trim();
|
|
29746
29634
|
if (!key) {
|
|
29747
29635
|
throw new Error(`Brevo API key file is empty: ${BREVO_API_KEY_FILE}`);
|
|
29748
29636
|
}
|
|
@@ -29757,7 +29645,7 @@ function readBrevoApiKey() {
|
|
|
29757
29645
|
}
|
|
29758
29646
|
}
|
|
29759
29647
|
function hasBrevoApiKey() {
|
|
29760
|
-
return
|
|
29648
|
+
return existsSync13(BREVO_API_KEY_FILE);
|
|
29761
29649
|
}
|
|
29762
29650
|
async function sendSms(recipient, content, opts) {
|
|
29763
29651
|
let apiKey;
|
|
@@ -29922,15 +29810,15 @@ function checkTelegramAccess(params) {
|
|
|
29922
29810
|
}
|
|
29923
29811
|
|
|
29924
29812
|
// app/api/telegram/webhook/route.ts
|
|
29925
|
-
import { existsSync as
|
|
29813
|
+
import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
|
|
29926
29814
|
import { timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
29927
29815
|
var TAG15 = "[telegram-webhook]";
|
|
29928
29816
|
var TELEGRAM_API = "https://api.telegram.org";
|
|
29929
29817
|
function getWebhookSecret(botType) {
|
|
29930
29818
|
const filePath = botType === "admin" ? TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE : TELEGRAM_WEBHOOK_SECRET_FILE;
|
|
29931
29819
|
try {
|
|
29932
|
-
if (!
|
|
29933
|
-
const secret =
|
|
29820
|
+
if (!existsSync14(filePath)) return null;
|
|
29821
|
+
const secret = readFileSync15(filePath, "utf-8").trim();
|
|
29934
29822
|
return secret || null;
|
|
29935
29823
|
} catch {
|
|
29936
29824
|
return null;
|
|
@@ -30087,7 +29975,7 @@ async function POST8(req) {
|
|
|
30087
29975
|
}
|
|
30088
29976
|
|
|
30089
29977
|
// app/api/whatsapp/login/start/route.ts
|
|
30090
|
-
import { join as
|
|
29978
|
+
import { join as join9 } from "path";
|
|
30091
29979
|
|
|
30092
29980
|
// app/lib/whatsapp/login.ts
|
|
30093
29981
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
@@ -30317,7 +30205,7 @@ async function POST9(req) {
|
|
|
30317
30205
|
const body = await req.json().catch(() => ({}));
|
|
30318
30206
|
const accountId = validateAccountId(body.accountId);
|
|
30319
30207
|
const force = body.force ?? false;
|
|
30320
|
-
const authDir =
|
|
30208
|
+
const authDir = join9(MAXY_DIR, "credentials", "whatsapp", accountId);
|
|
30321
30209
|
const result = await startLogin({ accountId, authDir, force });
|
|
30322
30210
|
console.error(`[whatsapp:api] login/start result account=${accountId} hasQr=${!!result.qrRaw}${result.selfPhone ? ` phone=${result.selfPhone}` : ""}`);
|
|
30323
30211
|
return Response.json(result);
|
|
@@ -30531,7 +30419,7 @@ function serializeWhatsAppSchema() {
|
|
|
30531
30419
|
|
|
30532
30420
|
// app/api/whatsapp/config/route.ts
|
|
30533
30421
|
import { resolve as resolve16 } from "path";
|
|
30534
|
-
import { readdirSync as readdirSync4, readFileSync as
|
|
30422
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync16, existsSync as existsSync15 } from "fs";
|
|
30535
30423
|
async function POST14(req) {
|
|
30536
30424
|
try {
|
|
30537
30425
|
const body = await req.json().catch(() => ({}));
|
|
@@ -30581,15 +30469,15 @@ async function POST14(req) {
|
|
|
30581
30469
|
case "list-public-agents": {
|
|
30582
30470
|
const agentsDir = resolve16(account.accountDir, "agents");
|
|
30583
30471
|
const agents = [];
|
|
30584
|
-
if (
|
|
30472
|
+
if (existsSync15(agentsDir)) {
|
|
30585
30473
|
try {
|
|
30586
30474
|
const entries = readdirSync4(agentsDir, { withFileTypes: true });
|
|
30587
30475
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
30588
30476
|
if (!entry.isDirectory() || entry.name === "admin") continue;
|
|
30589
30477
|
const configPath2 = resolve16(agentsDir, entry.name, "config.json");
|
|
30590
|
-
if (!
|
|
30478
|
+
if (!existsSync15(configPath2)) continue;
|
|
30591
30479
|
try {
|
|
30592
|
-
const config2 = JSON.parse(
|
|
30480
|
+
const config2 = JSON.parse(readFileSync16(configPath2, "utf-8"));
|
|
30593
30481
|
agents.push({ slug: entry.name, displayName: config2.displayName ?? entry.name });
|
|
30594
30482
|
} catch {
|
|
30595
30483
|
console.error(`[whatsapp:api] config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
|
|
@@ -31005,15 +30893,15 @@ async function POST17(req, remoteAddress) {
|
|
|
31005
30893
|
}
|
|
31006
30894
|
|
|
31007
30895
|
// app/api/onboarding/set-pin/route.ts
|
|
31008
|
-
import { existsSync as
|
|
30896
|
+
import { existsSync as existsSync16, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync17, unlinkSync as unlinkSync2 } from "fs";
|
|
31009
30897
|
import { createHash, randomUUID as randomUUID9 } from "crypto";
|
|
31010
30898
|
import { dirname as dirname6 } from "path";
|
|
31011
30899
|
function hashPin(pin) {
|
|
31012
30900
|
return createHash("sha256").update(pin).digest("hex");
|
|
31013
30901
|
}
|
|
31014
30902
|
function readUsersFile() {
|
|
31015
|
-
if (!
|
|
31016
|
-
const raw2 =
|
|
30903
|
+
if (!existsSync16(USERS_FILE)) return null;
|
|
30904
|
+
const raw2 = readFileSync17(USERS_FILE, "utf-8").trim();
|
|
31017
30905
|
if (!raw2) return [];
|
|
31018
30906
|
return JSON.parse(raw2);
|
|
31019
30907
|
}
|
|
@@ -31051,7 +30939,7 @@ async function POST18(req) {
|
|
|
31051
30939
|
const account = resolveAccount();
|
|
31052
30940
|
if (account) {
|
|
31053
30941
|
try {
|
|
31054
|
-
const config2 = JSON.parse(
|
|
30942
|
+
const config2 = JSON.parse(readFileSync17(`${account.accountDir}/account.json`, "utf-8"));
|
|
31055
30943
|
if (!config2.admins) config2.admins = [];
|
|
31056
30944
|
if (!config2.admins.some((a) => a.userId === userId)) {
|
|
31057
30945
|
config2.admins.push({ userId, role: "owner" });
|
|
@@ -31102,7 +30990,7 @@ async function DELETE(req) {
|
|
|
31102
30990
|
}
|
|
31103
30991
|
|
|
31104
30992
|
// app/api/onboarding/skip/route.ts
|
|
31105
|
-
import { existsSync as
|
|
30993
|
+
import { existsSync as existsSync17, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync18 } from "fs";
|
|
31106
30994
|
import { resolve as resolve18, dirname as dirname7 } from "path";
|
|
31107
30995
|
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
31108
30996
|
async function POST19() {
|
|
@@ -31114,9 +31002,9 @@ async function POST19() {
|
|
|
31114
31002
|
const { accountId, accountDir } = account;
|
|
31115
31003
|
let agentName = "Maxy";
|
|
31116
31004
|
const brandPath3 = PLATFORM_ROOT8 ? resolve18(PLATFORM_ROOT8, "config", "brand.json") : "";
|
|
31117
|
-
if (brandPath3 &&
|
|
31005
|
+
if (brandPath3 && existsSync17(brandPath3)) {
|
|
31118
31006
|
try {
|
|
31119
|
-
const brand = JSON.parse(
|
|
31007
|
+
const brand = JSON.parse(readFileSync18(brandPath3, "utf-8"));
|
|
31120
31008
|
if (brand.productName) agentName = brand.productName;
|
|
31121
31009
|
} catch (err) {
|
|
31122
31010
|
console.error(`[onboarding-skip] brand.json read failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -31162,14 +31050,14 @@ async function POST19() {
|
|
|
31162
31050
|
}
|
|
31163
31051
|
|
|
31164
31052
|
// app/api/admin/session/route.ts
|
|
31165
|
-
import { readFileSync as
|
|
31053
|
+
import { readFileSync as readFileSync19, existsSync as existsSync18 } from "fs";
|
|
31166
31054
|
import { createHash as createHash2 } from "crypto";
|
|
31167
31055
|
function hashPin2(pin) {
|
|
31168
31056
|
return createHash2("sha256").update(pin).digest("hex");
|
|
31169
31057
|
}
|
|
31170
31058
|
function readUsersFile2() {
|
|
31171
|
-
if (!
|
|
31172
|
-
const raw2 =
|
|
31059
|
+
if (!existsSync18(USERS_FILE)) return null;
|
|
31060
|
+
const raw2 = readFileSync19(USERS_FILE, "utf-8").trim();
|
|
31173
31061
|
if (!raw2) return [];
|
|
31174
31062
|
return JSON.parse(raw2);
|
|
31175
31063
|
}
|
|
@@ -31570,7 +31458,7 @@ async function POST22(req) {
|
|
|
31570
31458
|
}
|
|
31571
31459
|
|
|
31572
31460
|
// app/api/admin/logs/route.ts
|
|
31573
|
-
import { existsSync as
|
|
31461
|
+
import { existsSync as existsSync19, readdirSync as readdirSync5, readFileSync as readFileSync20, statSync as statSync7 } from "fs";
|
|
31574
31462
|
import { resolve as resolve19, basename as basename5 } from "path";
|
|
31575
31463
|
var TAIL_BYTES = 8192;
|
|
31576
31464
|
async function GET9(request) {
|
|
@@ -31589,7 +31477,7 @@ async function GET9(request) {
|
|
|
31589
31477
|
const filePath = resolve19(dir, safe);
|
|
31590
31478
|
searched.push(filePath);
|
|
31591
31479
|
try {
|
|
31592
|
-
const content =
|
|
31480
|
+
const content = readFileSync20(filePath, "utf-8");
|
|
31593
31481
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
31594
31482
|
if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
|
|
31595
31483
|
return new Response(content, { headers });
|
|
@@ -31631,7 +31519,7 @@ async function GET9(request) {
|
|
|
31631
31519
|
const filePath = resolve19(dir, fileName);
|
|
31632
31520
|
searched.push(filePath);
|
|
31633
31521
|
try {
|
|
31634
|
-
const content =
|
|
31522
|
+
const content = readFileSync20(filePath, "utf-8");
|
|
31635
31523
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
31636
31524
|
if (download) headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
|
|
31637
31525
|
return new Response(content, { headers });
|
|
@@ -31646,7 +31534,7 @@ async function GET9(request) {
|
|
|
31646
31534
|
const seen = /* @__PURE__ */ new Set();
|
|
31647
31535
|
const logs = {};
|
|
31648
31536
|
for (const dir of [accountLogDir2, LOG_DIR]) {
|
|
31649
|
-
if (!dir || !
|
|
31537
|
+
if (!dir || !existsSync19(dir)) continue;
|
|
31650
31538
|
let files;
|
|
31651
31539
|
try {
|
|
31652
31540
|
files = readdirSync5(dir).filter((f) => f.endsWith(".log"));
|
|
@@ -31658,7 +31546,7 @@ async function GET9(request) {
|
|
|
31658
31546
|
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
31547
|
seen.add(name);
|
|
31660
31548
|
try {
|
|
31661
|
-
const content =
|
|
31549
|
+
const content = readFileSync20(resolve19(dir, name));
|
|
31662
31550
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
31663
31551
|
logs[name] = tail.trim() || "(empty)";
|
|
31664
31552
|
} catch (err) {
|
|
@@ -31695,7 +31583,7 @@ async function GET10() {
|
|
|
31695
31583
|
|
|
31696
31584
|
// app/api/admin/attachment/[attachmentId]/route.ts
|
|
31697
31585
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
31698
|
-
import { existsSync as
|
|
31586
|
+
import { existsSync as existsSync20 } from "fs";
|
|
31699
31587
|
import { resolve as resolve20 } from "path";
|
|
31700
31588
|
async function GET11(req, attachmentId) {
|
|
31701
31589
|
const sessionKey = new URL(req.url).searchParams.get("session_key") ?? "";
|
|
@@ -31710,11 +31598,11 @@ async function GET11(req, attachmentId) {
|
|
|
31710
31598
|
return new Response("Not found", { status: 404 });
|
|
31711
31599
|
}
|
|
31712
31600
|
const dir = resolve20(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
31713
|
-
if (!
|
|
31601
|
+
if (!existsSync20(dir)) {
|
|
31714
31602
|
return new Response("Not found", { status: 404 });
|
|
31715
31603
|
}
|
|
31716
31604
|
const metaPath = resolve20(dir, `${attachmentId}.meta.json`);
|
|
31717
|
-
if (!
|
|
31605
|
+
if (!existsSync20(metaPath)) {
|
|
31718
31606
|
return new Response("Not found", { status: 404 });
|
|
31719
31607
|
}
|
|
31720
31608
|
let meta3;
|
|
@@ -31740,7 +31628,7 @@ async function GET11(req, attachmentId) {
|
|
|
31740
31628
|
}
|
|
31741
31629
|
|
|
31742
31630
|
// app/api/admin/account/route.ts
|
|
31743
|
-
import { readFileSync as
|
|
31631
|
+
import { readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "fs";
|
|
31744
31632
|
import { resolve as resolve21 } from "path";
|
|
31745
31633
|
var VALID_CONTEXT_MODES = ["managed", "claude-code"];
|
|
31746
31634
|
async function PATCH(req) {
|
|
@@ -31766,7 +31654,7 @@ async function PATCH(req) {
|
|
|
31766
31654
|
}
|
|
31767
31655
|
const configPath2 = resolve21(account.accountDir, "account.json");
|
|
31768
31656
|
try {
|
|
31769
|
-
const raw2 =
|
|
31657
|
+
const raw2 = readFileSync21(configPath2, "utf-8");
|
|
31770
31658
|
const config2 = JSON.parse(raw2);
|
|
31771
31659
|
config2.contextMode = contextMode;
|
|
31772
31660
|
writeFileSync15(configPath2, JSON.stringify(config2, null, 2) + "\n", "utf-8");
|
|
@@ -31780,14 +31668,14 @@ async function PATCH(req) {
|
|
|
31780
31668
|
|
|
31781
31669
|
// app/api/admin/agents/route.ts
|
|
31782
31670
|
import { resolve as resolve22 } from "path";
|
|
31783
|
-
import { readdirSync as readdirSync6, readFileSync as
|
|
31671
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync22, existsSync as existsSync21 } from "fs";
|
|
31784
31672
|
async function GET12() {
|
|
31785
31673
|
const account = resolveAccount();
|
|
31786
31674
|
if (!account) {
|
|
31787
31675
|
return Response.json({ agents: [] });
|
|
31788
31676
|
}
|
|
31789
31677
|
const agentsDir = resolve22(account.accountDir, "agents");
|
|
31790
|
-
if (!
|
|
31678
|
+
if (!existsSync21(agentsDir)) {
|
|
31791
31679
|
return Response.json({ agents: [] });
|
|
31792
31680
|
}
|
|
31793
31681
|
const agents = [];
|
|
@@ -31797,9 +31685,9 @@ async function GET12() {
|
|
|
31797
31685
|
if (!entry.isDirectory()) continue;
|
|
31798
31686
|
if (entry.name === "admin") continue;
|
|
31799
31687
|
const configPath2 = resolve22(agentsDir, entry.name, "config.json");
|
|
31800
|
-
if (!
|
|
31688
|
+
if (!existsSync21(configPath2)) continue;
|
|
31801
31689
|
try {
|
|
31802
|
-
const config2 = JSON.parse(
|
|
31690
|
+
const config2 = JSON.parse(readFileSync22(configPath2, "utf-8"));
|
|
31803
31691
|
agents.push({
|
|
31804
31692
|
slug: entry.name,
|
|
31805
31693
|
displayName: config2.displayName ?? entry.name,
|
|
@@ -31818,7 +31706,7 @@ async function GET12() {
|
|
|
31818
31706
|
|
|
31819
31707
|
// app/api/admin/agents/[slug]/route.ts
|
|
31820
31708
|
import { resolve as resolve23 } from "path";
|
|
31821
|
-
import { existsSync as
|
|
31709
|
+
import { existsSync as existsSync22, rmSync as rmSync2 } from "fs";
|
|
31822
31710
|
async function DELETE2(_req, { params }) {
|
|
31823
31711
|
const { slug } = await params;
|
|
31824
31712
|
const account = resolveAccount();
|
|
@@ -31832,7 +31720,7 @@ async function DELETE2(_req, { params }) {
|
|
|
31832
31720
|
return Response.json({ error: "Invalid agent slug" }, { status: 400 });
|
|
31833
31721
|
}
|
|
31834
31722
|
const agentDir = resolve23(account.accountDir, "agents", slug);
|
|
31835
|
-
if (!
|
|
31723
|
+
if (!existsSync22(agentDir)) {
|
|
31836
31724
|
return Response.json({ error: "Agent not found" }, { status: 404 });
|
|
31837
31725
|
}
|
|
31838
31726
|
try {
|
|
@@ -31846,15 +31734,15 @@ async function DELETE2(_req, { params }) {
|
|
|
31846
31734
|
}
|
|
31847
31735
|
|
|
31848
31736
|
// app/api/admin/version/route.ts
|
|
31849
|
-
import { readFileSync as
|
|
31850
|
-
import { resolve as resolve24, join as
|
|
31737
|
+
import { readFileSync as readFileSync23, existsSync as existsSync23 } from "fs";
|
|
31738
|
+
import { resolve as resolve24, join as join10 } from "path";
|
|
31851
31739
|
var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT ?? resolve24(process.cwd(), "..");
|
|
31852
31740
|
var brandHostname = "maxy";
|
|
31853
31741
|
var brandNpmPackage = "@rubytech/create-maxy";
|
|
31854
|
-
var brandJsonPath =
|
|
31855
|
-
if (
|
|
31742
|
+
var brandJsonPath = join10(PLATFORM_ROOT9, "config", "brand.json");
|
|
31743
|
+
if (existsSync23(brandJsonPath)) {
|
|
31856
31744
|
try {
|
|
31857
|
-
const brand = JSON.parse(
|
|
31745
|
+
const brand = JSON.parse(readFileSync23(brandJsonPath, "utf-8"));
|
|
31858
31746
|
if (brand.hostname) brandHostname = brand.hostname;
|
|
31859
31747
|
if (brand.npm?.packageName) brandNpmPackage = brand.npm.packageName;
|
|
31860
31748
|
} catch {
|
|
@@ -31865,8 +31753,8 @@ var NPM_PACKAGE = brandNpmPackage;
|
|
|
31865
31753
|
var REGISTRY_URL = `https://registry.npmjs.org/${NPM_PACKAGE}/latest`;
|
|
31866
31754
|
var FETCH_TIMEOUT_MS = 5e3;
|
|
31867
31755
|
function readInstalled() {
|
|
31868
|
-
if (!
|
|
31869
|
-
const content =
|
|
31756
|
+
if (!existsSync23(VERSION_FILE)) return "unknown";
|
|
31757
|
+
const content = readFileSync23(VERSION_FILE, "utf-8").trim();
|
|
31870
31758
|
return content || "unknown";
|
|
31871
31759
|
}
|
|
31872
31760
|
async function fetchLatest() {
|
|
@@ -31917,15 +31805,15 @@ async function GET13() {
|
|
|
31917
31805
|
|
|
31918
31806
|
// app/api/admin/version/upgrade/route.ts
|
|
31919
31807
|
import { spawn as spawn4 } from "child_process";
|
|
31920
|
-
import { existsSync as
|
|
31921
|
-
import { resolve as resolve25, join as
|
|
31808
|
+
import { existsSync as existsSync24, statSync as statSync8, writeFileSync as writeFileSync16, readFileSync as readFileSync24, openSync as openSync4, closeSync as closeSync4 } from "fs";
|
|
31809
|
+
import { resolve as resolve25, join as join11 } from "path";
|
|
31922
31810
|
var PLATFORM_ROOT10 = process.env.MAXY_PLATFORM_ROOT ?? resolve25(process.cwd(), "..");
|
|
31923
31811
|
var upgradePkg = "@rubytech/create-maxy";
|
|
31924
31812
|
var upgradeHostname = "maxy";
|
|
31925
|
-
var brandPath =
|
|
31926
|
-
if (
|
|
31813
|
+
var brandPath = join11(PLATFORM_ROOT10, "config", "brand.json");
|
|
31814
|
+
if (existsSync24(brandPath)) {
|
|
31927
31815
|
try {
|
|
31928
|
-
const brand = JSON.parse(
|
|
31816
|
+
const brand = JSON.parse(readFileSync24(brandPath, "utf-8"));
|
|
31929
31817
|
if (brand.npm?.packageName) upgradePkg = brand.npm.packageName;
|
|
31930
31818
|
if (brand.hostname) upgradeHostname = brand.hostname;
|
|
31931
31819
|
} catch {
|
|
@@ -31935,7 +31823,7 @@ var LOCK_FILE = `/tmp/${upgradeHostname}-upgrade.lock`;
|
|
|
31935
31823
|
var LOG_FILE = `/tmp/${upgradeHostname}-upgrade.log`;
|
|
31936
31824
|
var LOCK_MAX_AGE_MS = 20 * 60 * 1e3;
|
|
31937
31825
|
function isLockFresh() {
|
|
31938
|
-
if (!
|
|
31826
|
+
if (!existsSync24(LOCK_FILE)) return false;
|
|
31939
31827
|
try {
|
|
31940
31828
|
const stat4 = statSync8(LOCK_FILE);
|
|
31941
31829
|
return Date.now() - stat4.mtimeMs < LOCK_MAX_AGE_MS;
|
|
@@ -31995,14 +31883,14 @@ async function POST23(req) {
|
|
|
31995
31883
|
}
|
|
31996
31884
|
|
|
31997
31885
|
// app/api/admin/version/upgrade/progress/route.ts
|
|
31998
|
-
import { existsSync as
|
|
31999
|
-
import { resolve as resolve26, join as
|
|
31886
|
+
import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
|
|
31887
|
+
import { resolve as resolve26, join as join12 } from "path";
|
|
32000
31888
|
var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
|
|
32001
31889
|
var upgradeHostname2 = "maxy";
|
|
32002
|
-
var brandPath2 =
|
|
32003
|
-
if (
|
|
31890
|
+
var brandPath2 = join12(PLATFORM_ROOT11, "config", "brand.json");
|
|
31891
|
+
if (existsSync25(brandPath2)) {
|
|
32004
31892
|
try {
|
|
32005
|
-
const brand = JSON.parse(
|
|
31893
|
+
const brand = JSON.parse(readFileSync25(brandPath2, "utf-8"));
|
|
32006
31894
|
if (brand.hostname) upgradeHostname2 = brand.hostname;
|
|
32007
31895
|
} catch {
|
|
32008
31896
|
}
|
|
@@ -32010,12 +31898,12 @@ if (existsSync26(brandPath2)) {
|
|
|
32010
31898
|
var LOG_FILE2 = `/tmp/${upgradeHostname2}-upgrade.log`;
|
|
32011
31899
|
var STEP_RE = /\[(\d+)\/(\d+)\]\s+(.+)/;
|
|
32012
31900
|
async function GET14() {
|
|
32013
|
-
if (!
|
|
31901
|
+
if (!existsSync25(LOG_FILE2)) {
|
|
32014
31902
|
return Response.json({ step: 0, total: 0, label: "", started: false });
|
|
32015
31903
|
}
|
|
32016
31904
|
let content;
|
|
32017
31905
|
try {
|
|
32018
|
-
content =
|
|
31906
|
+
content = readFileSync25(LOG_FILE2, "utf-8");
|
|
32019
31907
|
} catch {
|
|
32020
31908
|
return Response.json({ step: 0, total: 0, label: "", started: false });
|
|
32021
31909
|
}
|
|
@@ -32481,14 +32369,14 @@ async function POST29(req) {
|
|
|
32481
32369
|
|
|
32482
32370
|
// server/index.ts
|
|
32483
32371
|
var PLATFORM_ROOT12 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
32484
|
-
var BRAND_JSON_PATH = PLATFORM_ROOT12 ?
|
|
32372
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT12 ? join13(PLATFORM_ROOT12, "config", "brand.json") : "";
|
|
32485
32373
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
|
|
32486
|
-
if (BRAND_JSON_PATH && !
|
|
32374
|
+
if (BRAND_JSON_PATH && !existsSync26(BRAND_JSON_PATH)) {
|
|
32487
32375
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
32488
32376
|
}
|
|
32489
|
-
if (BRAND_JSON_PATH &&
|
|
32377
|
+
if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
|
|
32490
32378
|
try {
|
|
32491
|
-
const parsed = JSON.parse(
|
|
32379
|
+
const parsed = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
|
|
32492
32380
|
BRAND = { ...BRAND, ...parsed };
|
|
32493
32381
|
} catch (err) {
|
|
32494
32382
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -32507,11 +32395,11 @@ var brandLoginOpts = {
|
|
|
32507
32395
|
bodyFont: BRAND.defaultFonts?.body,
|
|
32508
32396
|
logoContainsName: !!BRAND.logoContainsName
|
|
32509
32397
|
};
|
|
32510
|
-
var ALIAS_DOMAINS_PATH =
|
|
32398
|
+
var ALIAS_DOMAINS_PATH = join13(homedir4(), BRAND.configDir, "alias-domains.json");
|
|
32511
32399
|
function loadAliasDomains() {
|
|
32512
32400
|
try {
|
|
32513
|
-
if (!
|
|
32514
|
-
const parsed = JSON.parse(
|
|
32401
|
+
if (!existsSync26(ALIAS_DOMAINS_PATH)) return null;
|
|
32402
|
+
const parsed = JSON.parse(readFileSync26(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
32515
32403
|
if (!Array.isArray(parsed)) {
|
|
32516
32404
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
32517
32405
|
return null;
|
|
@@ -32929,14 +32817,14 @@ app.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
32929
32817
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
32930
32818
|
return c.text("Forbidden", 403);
|
|
32931
32819
|
}
|
|
32932
|
-
if (!
|
|
32820
|
+
if (!existsSync26(filePath)) {
|
|
32933
32821
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
32934
32822
|
return c.text("Not found", 404);
|
|
32935
32823
|
}
|
|
32936
32824
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
32937
32825
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
32938
32826
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
32939
|
-
const body =
|
|
32827
|
+
const body = readFileSync26(filePath);
|
|
32940
32828
|
return c.body(body, 200, {
|
|
32941
32829
|
"Content-Type": contentType,
|
|
32942
32830
|
"Cache-Control": "public, max-age=3600"
|
|
@@ -32959,14 +32847,14 @@ app.get("/generated/:filename", (c) => {
|
|
|
32959
32847
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
32960
32848
|
return c.text("Forbidden", 403);
|
|
32961
32849
|
}
|
|
32962
|
-
if (!
|
|
32850
|
+
if (!existsSync26(filePath)) {
|
|
32963
32851
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
32964
32852
|
return c.text("Not found", 404);
|
|
32965
32853
|
}
|
|
32966
32854
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
32967
32855
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
32968
32856
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
32969
|
-
const body =
|
|
32857
|
+
const body = readFileSync26(filePath);
|
|
32970
32858
|
return c.body(body, 200, {
|
|
32971
32859
|
"Content-Type": contentType,
|
|
32972
32860
|
"Cache-Control": "public, max-age=86400"
|
|
@@ -32975,9 +32863,9 @@ app.get("/generated/:filename", (c) => {
|
|
|
32975
32863
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
32976
32864
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
32977
32865
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
32978
|
-
if (BRAND_JSON_PATH &&
|
|
32866
|
+
if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
|
|
32979
32867
|
try {
|
|
32980
|
-
const fullBrand = JSON.parse(
|
|
32868
|
+
const fullBrand = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
|
|
32981
32869
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
32982
32870
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
32983
32871
|
} catch {
|
|
@@ -32994,7 +32882,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
32994
32882
|
function cachedHtml(file2) {
|
|
32995
32883
|
let html = htmlCache.get(file2);
|
|
32996
32884
|
if (!html) {
|
|
32997
|
-
html =
|
|
32885
|
+
html = readFileSync26(resolve27(process.cwd(), "public", file2), "utf-8");
|
|
32998
32886
|
html = html.replace("<title>Maxy</title>", `<title>${escapeHtml2(BRAND.productName)}</title>`);
|
|
32999
32887
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml2(brandFaviconPath)}"`);
|
|
33000
32888
|
html = html.replace("</head>", `${brandScript}
|
|
@@ -33005,26 +32893,26 @@ function cachedHtml(file2) {
|
|
|
33005
32893
|
}
|
|
33006
32894
|
var brandedHtmlCache = /* @__PURE__ */ new Map();
|
|
33007
32895
|
function loadBrandingCache(agentSlug) {
|
|
33008
|
-
const configDir2 =
|
|
32896
|
+
const configDir2 = join13(homedir4(), BRAND.configDir);
|
|
33009
32897
|
try {
|
|
33010
|
-
const accountJsonPath =
|
|
33011
|
-
if (!
|
|
33012
|
-
const account = JSON.parse(
|
|
32898
|
+
const accountJsonPath = join13(configDir2, "account.json");
|
|
32899
|
+
if (!existsSync26(accountJsonPath)) return null;
|
|
32900
|
+
const account = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
|
|
33013
32901
|
const accountId = account.accountId;
|
|
33014
32902
|
if (!accountId) return null;
|
|
33015
|
-
const cachePath =
|
|
33016
|
-
if (!
|
|
33017
|
-
return JSON.parse(
|
|
32903
|
+
const cachePath = join13(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
32904
|
+
if (!existsSync26(cachePath)) return null;
|
|
32905
|
+
return JSON.parse(readFileSync26(cachePath, "utf-8"));
|
|
33018
32906
|
} catch {
|
|
33019
32907
|
return null;
|
|
33020
32908
|
}
|
|
33021
32909
|
}
|
|
33022
32910
|
function resolveDefaultSlug() {
|
|
33023
32911
|
try {
|
|
33024
|
-
const configDir2 =
|
|
33025
|
-
const accountJsonPath =
|
|
33026
|
-
if (!
|
|
33027
|
-
const account = JSON.parse(
|
|
32912
|
+
const configDir2 = join13(homedir4(), BRAND.configDir);
|
|
32913
|
+
const accountJsonPath = join13(configDir2, "account.json");
|
|
32914
|
+
if (!existsSync26(accountJsonPath)) return null;
|
|
32915
|
+
const account = JSON.parse(readFileSync26(accountJsonPath, "utf-8"));
|
|
33028
32916
|
return account.defaultAgent || null;
|
|
33029
32917
|
} catch {
|
|
33030
32918
|
return null;
|
|
@@ -33097,7 +32985,7 @@ app.use("/vnc-popout.html", logViewerFetch);
|
|
|
33097
32985
|
app.get("/vnc-popout.html", (c) => {
|
|
33098
32986
|
let html = htmlCache.get("vnc-popout.html");
|
|
33099
32987
|
if (!html) {
|
|
33100
|
-
html =
|
|
32988
|
+
html = readFileSync26(resolve27(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
33101
32989
|
const name = escapeHtml2(BRAND.productName);
|
|
33102
32990
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
33103
32991
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -33151,8 +33039,8 @@ console.log(`${BRAND.productName} listening on http://${hostname3}:${port}`);
|
|
|
33151
33039
|
(async () => {
|
|
33152
33040
|
try {
|
|
33153
33041
|
let userId = "";
|
|
33154
|
-
if (
|
|
33155
|
-
const users = JSON.parse(
|
|
33042
|
+
if (existsSync26(USERS_FILE)) {
|
|
33043
|
+
const users = JSON.parse(readFileSync26(USERS_FILE, "utf-8").trim() || "[]");
|
|
33156
33044
|
userId = users[0]?.userId ?? "";
|
|
33157
33045
|
}
|
|
33158
33046
|
await backfillNullUserIdConversations(userId);
|
|
@@ -33178,7 +33066,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
33178
33066
|
}
|
|
33179
33067
|
init({
|
|
33180
33068
|
configDir: configDirForWhatsApp,
|
|
33181
|
-
platformRoot: resolve27(process.env.MAXY_PLATFORM_ROOT ??
|
|
33069
|
+
platformRoot: resolve27(process.env.MAXY_PLATFORM_ROOT ?? join13(__dirname, "..")),
|
|
33182
33070
|
accountConfig: bootAccountConfig,
|
|
33183
33071
|
onMessage: async (msg) => {
|
|
33184
33072
|
try {
|