@rubytech/create-maxy-code 0.1.614 → 0.1.616
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/aeo-llms-txt-writer/dist/__tests__/write-llms-txt.test.d.ts +2 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/__tests__/write-llms-txt.test.d.ts.map +1 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/__tests__/write-llms-txt.test.js +291 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/__tests__/write-llms-txt.test.js.map +1 -0
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.d.ts +13 -1
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.js +127 -18
- package/payload/platform/lib/aeo-llms-txt-writer/dist/index.js.map +1 -1
- package/payload/platform/lib/aeo-llms-txt-writer/src/__tests__/write-llms-txt.test.ts +391 -0
- package/payload/platform/lib/aeo-llms-txt-writer/src/index.ts +156 -19
- package/payload/platform/lib/aeo-llms-txt-writer/vitest.config.ts +10 -0
- package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts +15 -1
- package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/mcp-spawn-tee/dist/index.js +129 -7
- package/payload/platform/lib/mcp-spawn-tee/dist/index.js.map +1 -1
- package/payload/platform/lib/mcp-spawn-tee/src/__tests__/spawn-tee.test.ts +227 -0
- package/payload/platform/lib/mcp-spawn-tee/src/index.ts +133 -6
- package/payload/platform/plugins/admin/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/admin/mcp/dist/index.js +11 -3
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.d.ts +3 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.d.ts.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.js +38 -20
- package/payload/platform/plugins/admin/mcp/dist/tools/publish-site.js.map +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +6 -5
- package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +3 -0
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +13 -0
- package/payload/platform/plugins/aeo/PLUGIN.md +1 -1
- package/payload/platform/plugins/aeo/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/aeo/mcp/dist/index.js +17 -10
- package/payload/platform/plugins/aeo/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/browser/PLUGIN.md +1 -1
- package/payload/platform/plugins/browser/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/connector/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/contacts/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/dispatch/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/docs/references/aeo.md +4 -3
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/email/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/filesystem/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/google/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/graph-viewer/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/inventory/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/ledger/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/memory/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/outlook/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/quickbooks/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/replicate/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/scheduling/PLUGIN.md +3 -4
- package/payload/platform/plugins/scheduling/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +0 -6
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +65 -20
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-classification.test.js +20 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-classification.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +12 -4
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +39 -6
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js +21 -6
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +26 -5
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-waiver.test.js +17 -51
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-waiver.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js +6 -4
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-gate-write.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +113 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +8 -18
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +14 -27
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +125 -56
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
- package/payload/platform/plugins/storage-broker/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/telegram/PLUGIN.md +2 -2
- package/payload/platform/plugins/telegram/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/webhook-register.test.js +12 -5
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/webhook-register.test.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/tools/webhook-register.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/tools/webhook-register.js +14 -6
- package/payload/platform/plugins/telegram/mcp/dist/tools/webhook-register.js.map +1 -1
- package/payload/platform/plugins/telegram/skills/configure/SKILL.md +1 -1
- package/payload/platform/plugins/url-get/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/voice-mirror/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/whatsapp/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/work/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/plugins/workflows/lib/mcp-spawn-tee/index.js +129 -7
- package/payload/platform/scripts/__tests__/vnc-cdp-liveness.test.sh +270 -19
- package/payload/platform/scripts/vnc.sh +174 -71
- package/payload/platform/services/claude-session-manager/dist/index.js +17 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/mcp-helper-census.d.ts +80 -0
- package/payload/platform/services/claude-session-manager/dist/mcp-helper-census.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/mcp-helper-census.js +201 -0
- package/payload/platform/services/claude-session-manager/dist/mcp-helper-census.js.map +1 -0
- package/payload/server/public/operator.html +1 -1
- package/payload/server/server.js +422 -251
package/payload/server/server.js
CHANGED
|
@@ -3220,11 +3220,11 @@ var require_dist10 = __commonJS({
|
|
|
3220
3220
|
});
|
|
3221
3221
|
|
|
3222
3222
|
// server/index.ts
|
|
3223
|
-
import { readFileSync as
|
|
3223
|
+
import { readFileSync as readFileSync65, existsSync as existsSync64, watchFile, readdirSync as readdirSync39, statSync as statSync35 } from "fs";
|
|
3224
3224
|
import { spawn as spawn3 } from "child_process";
|
|
3225
3225
|
import { createHash as createHash8 } from "crypto";
|
|
3226
|
-
import { resolve as
|
|
3227
|
-
import { homedir as
|
|
3226
|
+
import { resolve as resolve56, join as join79, basename as basename20 } from "path";
|
|
3227
|
+
import { homedir as homedir6 } from "os";
|
|
3228
3228
|
|
|
3229
3229
|
// server/lib/route-cache-watchers.ts
|
|
3230
3230
|
import { watch } from "fs";
|
|
@@ -5660,20 +5660,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
|
|
|
5660
5660
|
|
|
5661
5661
|
// server/routes/health.ts
|
|
5662
5662
|
function checkPort(port2, timeoutMs = 500) {
|
|
5663
|
-
return new Promise((
|
|
5663
|
+
return new Promise((resolve57) => {
|
|
5664
5664
|
const socket = createConnection2(port2, "127.0.0.1");
|
|
5665
5665
|
socket.setTimeout(timeoutMs);
|
|
5666
5666
|
socket.once("connect", () => {
|
|
5667
5667
|
socket.destroy();
|
|
5668
|
-
|
|
5668
|
+
resolve57(true);
|
|
5669
5669
|
});
|
|
5670
5670
|
socket.once("error", () => {
|
|
5671
5671
|
socket.destroy();
|
|
5672
|
-
|
|
5672
|
+
resolve57(false);
|
|
5673
5673
|
});
|
|
5674
5674
|
socket.once("timeout", () => {
|
|
5675
5675
|
socket.destroy();
|
|
5676
|
-
|
|
5676
|
+
resolve57(false);
|
|
5677
5677
|
});
|
|
5678
5678
|
});
|
|
5679
5679
|
}
|
|
@@ -6590,11 +6590,11 @@ function findExistingJsonlForSessionId(claudeConfigDir2, sessionId) {
|
|
|
6590
6590
|
} catch {
|
|
6591
6591
|
return null;
|
|
6592
6592
|
}
|
|
6593
|
-
const
|
|
6593
|
+
const basename21 = `${sessionId}.jsonl`;
|
|
6594
6594
|
for (const slug of slugs) {
|
|
6595
|
-
const live = join9(projectsRoot, slug,
|
|
6595
|
+
const live = join9(projectsRoot, slug, basename21);
|
|
6596
6596
|
if (existsSync4(live)) return live;
|
|
6597
|
-
const archived = join9(projectsRoot, slug, "archive",
|
|
6597
|
+
const archived = join9(projectsRoot, slug, "archive", basename21);
|
|
6598
6598
|
if (existsSync4(archived)) return archived;
|
|
6599
6599
|
}
|
|
6600
6600
|
return null;
|
|
@@ -8082,7 +8082,7 @@ async function defaultResolve(accountId) {
|
|
|
8082
8082
|
return resolveSocket2(accountId);
|
|
8083
8083
|
}
|
|
8084
8084
|
async function fetchAvatar(accountId, jid, deps = {}) {
|
|
8085
|
-
const
|
|
8085
|
+
const resolve57 = deps.resolve;
|
|
8086
8086
|
const httpGet = deps.httpGet ?? defaultHttpGet;
|
|
8087
8087
|
const maxAgeMs = deps.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
|
|
8088
8088
|
const cached3 = readAvatar(accountId, jid);
|
|
@@ -8092,7 +8092,7 @@ async function fetchAvatar(accountId, jid, deps = {}) {
|
|
|
8092
8092
|
return "fresh";
|
|
8093
8093
|
}
|
|
8094
8094
|
console.log(`${TAG10} op=cache jid=${jid} hit=false ageMs=${ageMs2}`);
|
|
8095
|
-
const res =
|
|
8095
|
+
const res = resolve57 ? resolve57(accountId) : await defaultResolve(accountId);
|
|
8096
8096
|
if (!res.ok) {
|
|
8097
8097
|
console.log(`${TAG10} op=no-socket jid=${jid} account=${accountId.slice(0, 8)} reason=${res.reason}`);
|
|
8098
8098
|
return "no-socket";
|
|
@@ -9867,8 +9867,8 @@ async function startLogin(opts) {
|
|
|
9867
9867
|
await clearAuth(authDir);
|
|
9868
9868
|
let resolveCode = null;
|
|
9869
9869
|
let rejectCode = null;
|
|
9870
|
-
const codePromise = new Promise((
|
|
9871
|
-
resolveCode =
|
|
9870
|
+
const codePromise = new Promise((resolve57, reject) => {
|
|
9871
|
+
resolveCode = resolve57;
|
|
9872
9872
|
rejectCode = reject;
|
|
9873
9873
|
});
|
|
9874
9874
|
const codeTimer = setTimeout(
|
|
@@ -23625,15 +23625,15 @@ function operatorRoleFor(config, userId) {
|
|
|
23625
23625
|
async function buildAccountOptionList(accounts, userId) {
|
|
23626
23626
|
const houseAccount = accounts.find((a) => a.config.role === "house");
|
|
23627
23627
|
console.log(`[admin-accounts] op=list count=${accounts.length} house=${houseAccount?.accountId ?? "none"}`);
|
|
23628
|
-
const
|
|
23628
|
+
const resolve57 = async (a) => {
|
|
23629
23629
|
const businessName = await fetchAccountName(a.accountId) || void 0;
|
|
23630
23630
|
return { accountId: a.accountId, businessName, role: operatorRoleFor(a.config, userId), isHouse: a.config.role === "house" };
|
|
23631
23631
|
};
|
|
23632
23632
|
const houseOptions = await Promise.all(
|
|
23633
|
-
accounts.filter((a) => a.config.role === "house").map(
|
|
23633
|
+
accounts.filter((a) => a.config.role === "house").map(resolve57)
|
|
23634
23634
|
);
|
|
23635
23635
|
const nonHouseOptions = await Promise.all(
|
|
23636
|
-
accounts.filter((a) => a.config.role !== "house").map(
|
|
23636
|
+
accounts.filter((a) => a.config.role !== "house").map(resolve57)
|
|
23637
23637
|
);
|
|
23638
23638
|
const sortKey = (o) => (o.businessName || o.accountId).toLowerCase();
|
|
23639
23639
|
nonHouseOptions.sort((x, y) => {
|
|
@@ -26562,18 +26562,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
26562
26562
|
]);
|
|
26563
26563
|
var app27 = new Hono();
|
|
26564
26564
|
app27.post("/", async (c) => {
|
|
26565
|
-
const
|
|
26565
|
+
const TAG84 = "[admin:events]";
|
|
26566
26566
|
let body;
|
|
26567
26567
|
try {
|
|
26568
26568
|
body = await c.req.json();
|
|
26569
26569
|
} catch (err) {
|
|
26570
26570
|
const detail = err instanceof Error ? err.message : String(err);
|
|
26571
|
-
console.error(`${
|
|
26571
|
+
console.error(`${TAG84} reject reason=body-not-json detail=${detail}`);
|
|
26572
26572
|
return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
|
|
26573
26573
|
}
|
|
26574
26574
|
const event = typeof body.event === "string" ? body.event : "";
|
|
26575
26575
|
if (!ALLOWED_EVENTS.has(event)) {
|
|
26576
|
-
console.error(`${
|
|
26576
|
+
console.error(`${TAG84} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
|
|
26577
26577
|
return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
|
|
26578
26578
|
}
|
|
26579
26579
|
const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
|
|
@@ -38163,12 +38163,174 @@ function startSharedFolderCensus() {
|
|
|
38163
38163
|
});
|
|
38164
38164
|
}
|
|
38165
38165
|
|
|
38166
|
+
// app/lib/browser-orphan-census.ts
|
|
38167
|
+
import { readFileSync as readFileSync59, readdirSync as readdirSync34, statSync as statSync31, existsSync as existsSync56 } from "fs";
|
|
38168
|
+
import { join as join69, basename as basename18, dirname as dirname18, resolve as resolve48 } from "path";
|
|
38169
|
+
import { homedir as homedir4 } from "os";
|
|
38170
|
+
var TAG70 = "[browser-census]";
|
|
38171
|
+
var BROWSER_BINARIES = /* @__PURE__ */ new Set([
|
|
38172
|
+
"chrome",
|
|
38173
|
+
"chromium",
|
|
38174
|
+
"chromium-browser",
|
|
38175
|
+
"google-chrome",
|
|
38176
|
+
"google-chrome-stable"
|
|
38177
|
+
]);
|
|
38178
|
+
function readProcess(procRoot, pid) {
|
|
38179
|
+
try {
|
|
38180
|
+
const raw = readFileSync59(join69(procRoot, String(pid), "cmdline"), "utf8");
|
|
38181
|
+
const argv = raw.split("\0").filter((a) => a.length > 0);
|
|
38182
|
+
if (argv.length === 0) return null;
|
|
38183
|
+
const stat11 = readFileSync59(join69(procRoot, String(pid), "stat"), "utf8");
|
|
38184
|
+
const close = stat11.lastIndexOf(")");
|
|
38185
|
+
if (close === -1) return null;
|
|
38186
|
+
const after = stat11.slice(close + 1).trim().split(/\s+/);
|
|
38187
|
+
const ppid = Number(after[1]);
|
|
38188
|
+
if (!Number.isInteger(ppid)) return null;
|
|
38189
|
+
return { pid, ppid, argv, comm: stat11.slice(stat11.indexOf("(") + 1, close) };
|
|
38190
|
+
} catch {
|
|
38191
|
+
return null;
|
|
38192
|
+
}
|
|
38193
|
+
}
|
|
38194
|
+
function readProcSnapshot(procRoot) {
|
|
38195
|
+
let entries2;
|
|
38196
|
+
try {
|
|
38197
|
+
entries2 = readdirSync34(procRoot, { withFileTypes: true });
|
|
38198
|
+
} catch {
|
|
38199
|
+
return [];
|
|
38200
|
+
}
|
|
38201
|
+
const out = [];
|
|
38202
|
+
for (const e of entries2) {
|
|
38203
|
+
if (!e.isDirectory()) continue;
|
|
38204
|
+
const pid = Number(e.name);
|
|
38205
|
+
if (!Number.isInteger(pid) || pid <= 0) continue;
|
|
38206
|
+
const p = readProcess(procRoot, pid);
|
|
38207
|
+
if (p) out.push(p);
|
|
38208
|
+
}
|
|
38209
|
+
return out.sort((a, b) => a.pid - b.pid);
|
|
38210
|
+
}
|
|
38211
|
+
function userDataDir(argv) {
|
|
38212
|
+
const FLAG = "--user-data-dir";
|
|
38213
|
+
for (let i = 0; i < argv.length; i++) {
|
|
38214
|
+
if (argv[i].startsWith(FLAG + "=")) return argv[i].slice(FLAG.length + 1);
|
|
38215
|
+
if (argv[i] === FLAG && i + 1 < argv.length) return argv[i + 1];
|
|
38216
|
+
}
|
|
38217
|
+
return null;
|
|
38218
|
+
}
|
|
38219
|
+
function isTopLevelBrowser(argv) {
|
|
38220
|
+
if (argv.length === 0) return false;
|
|
38221
|
+
if (!BROWSER_BINARIES.has(basename18(argv[0]))) return false;
|
|
38222
|
+
return !argv.some((a) => a.startsWith("--type="));
|
|
38223
|
+
}
|
|
38224
|
+
function isBrandProfile(dir, home) {
|
|
38225
|
+
const path = resolve48(dir);
|
|
38226
|
+
if (basename18(path) !== "chromium-profile") return false;
|
|
38227
|
+
const parent = dirname18(path);
|
|
38228
|
+
if (dirname18(parent) !== resolve48(home)) return false;
|
|
38229
|
+
return basename18(parent).startsWith(".");
|
|
38230
|
+
}
|
|
38231
|
+
function isReparented(p, byPid) {
|
|
38232
|
+
if (p.ppid === 1) return true;
|
|
38233
|
+
const parent = byPid.get(p.ppid);
|
|
38234
|
+
if (!parent) return true;
|
|
38235
|
+
return parent.comm === "systemd" && parent.argv.includes("--user");
|
|
38236
|
+
}
|
|
38237
|
+
var PROFILE_PREFIXES = ["cdp-", "playwright"];
|
|
38238
|
+
function dirBytes(dir) {
|
|
38239
|
+
let total = 0;
|
|
38240
|
+
let entries2;
|
|
38241
|
+
try {
|
|
38242
|
+
entries2 = readdirSync34(dir, { withFileTypes: true });
|
|
38243
|
+
} catch {
|
|
38244
|
+
return total;
|
|
38245
|
+
}
|
|
38246
|
+
for (const e of entries2) {
|
|
38247
|
+
const p = join69(dir, e.name);
|
|
38248
|
+
if (e.isDirectory()) {
|
|
38249
|
+
total += dirBytes(p);
|
|
38250
|
+
} else if (e.isFile()) {
|
|
38251
|
+
try {
|
|
38252
|
+
total += statSync31(p).size;
|
|
38253
|
+
} catch {
|
|
38254
|
+
}
|
|
38255
|
+
}
|
|
38256
|
+
}
|
|
38257
|
+
return total;
|
|
38258
|
+
}
|
|
38259
|
+
function scanProfileDirs(tmpRoot, nowMs) {
|
|
38260
|
+
let entries2;
|
|
38261
|
+
try {
|
|
38262
|
+
entries2 = readdirSync34(tmpRoot, { withFileTypes: true });
|
|
38263
|
+
} catch {
|
|
38264
|
+
return { dirs: [], scanned: 0 };
|
|
38265
|
+
}
|
|
38266
|
+
const dirs = [];
|
|
38267
|
+
for (const e of entries2) {
|
|
38268
|
+
if (!e.isDirectory()) continue;
|
|
38269
|
+
if (!PROFILE_PREFIXES.some((p) => e.name.startsWith(p))) continue;
|
|
38270
|
+
const path = join69(tmpRoot, e.name);
|
|
38271
|
+
let ageSec;
|
|
38272
|
+
try {
|
|
38273
|
+
ageSec = Math.max(0, Math.floor((nowMs - statSync31(path).birthtimeMs) / 1e3));
|
|
38274
|
+
} catch {
|
|
38275
|
+
continue;
|
|
38276
|
+
}
|
|
38277
|
+
dirs.push({ name: e.name, path, ageSec, bytes: dirBytes(path) });
|
|
38278
|
+
}
|
|
38279
|
+
return { dirs, scanned: entries2.length };
|
|
38280
|
+
}
|
|
38281
|
+
function runBrowserOrphanCensus(deps) {
|
|
38282
|
+
const { procRoot, tmpRoot, home, nowMs } = deps;
|
|
38283
|
+
if (!existsSync56(procRoot)) {
|
|
38284
|
+
console.error(`${TAG70} op=browser-orphan-census unsupported=no-proc scanned=0`);
|
|
38285
|
+
return "no /proc \u2014 process census unavailable on this platform";
|
|
38286
|
+
}
|
|
38287
|
+
const procs = readProcSnapshot(procRoot);
|
|
38288
|
+
const byPid = new Map(procs.map((p) => [p.pid, p]));
|
|
38289
|
+
const browsers = procs.filter((p) => isTopLevelBrowser(p.argv));
|
|
38290
|
+
const foreign = browsers.filter((p) => {
|
|
38291
|
+
const dir = userDataDir(p.argv);
|
|
38292
|
+
return dir === null || !isBrandProfile(dir, home);
|
|
38293
|
+
});
|
|
38294
|
+
const reparented = foreign.filter((p) => isReparented(p, byPid));
|
|
38295
|
+
const ownerByDir = /* @__PURE__ */ new Map();
|
|
38296
|
+
for (const b of browsers) {
|
|
38297
|
+
const dir = userDataDir(b.argv);
|
|
38298
|
+
if (dir) ownerByDir.set(resolve48(dir), b);
|
|
38299
|
+
}
|
|
38300
|
+
const { dirs, scanned: tmpScanned } = scanProfileDirs(tmpRoot, nowMs);
|
|
38301
|
+
const dirBytesTotal = dirs.reduce((s, d) => s + d.bytes, 0);
|
|
38302
|
+
const oldestDirAgeSec = dirs.reduce((m, d) => Math.max(m, d.ageSec), 0);
|
|
38303
|
+
console.error(
|
|
38304
|
+
`${TAG70} op=browser-orphan-census scanned=${procs.length} chrome=${browsers.length} brandBound=${browsers.length - foreign.length} foreign=${foreign.length} reparented=${reparented.length} dirs=${dirs.length} dirBytes=${dirBytesTotal} oldestDirAgeSec=${oldestDirAgeSec} tmpScanned=${tmpScanned}`
|
|
38305
|
+
);
|
|
38306
|
+
for (const d of dirs) {
|
|
38307
|
+
const owner = ownerByDir.get(resolve48(d.path));
|
|
38308
|
+
console.error(
|
|
38309
|
+
`${TAG70} op=browser-orphan-profile dir=${d.name} ageSec=${d.ageSec} bytes=${d.bytes} owner=${owner ? owner.pid : "none"} ppid=${owner ? owner.ppid : "-"} parent=${owner ? byPid.get(owner.ppid)?.comm ?? "-" : "-"} reparented=${owner ? isReparented(owner, byPid) : "-"}`
|
|
38310
|
+
);
|
|
38311
|
+
}
|
|
38312
|
+
return `${foreign.length} foreign browser(s), ${dirs.length} profile dir(s), ${dirBytesTotal} bytes`;
|
|
38313
|
+
}
|
|
38314
|
+
function startBrowserOrphanCensus() {
|
|
38315
|
+
registerLoop({
|
|
38316
|
+
name: "browser-orphan-census",
|
|
38317
|
+
intervalMs: 60 * 60 * 1e3,
|
|
38318
|
+
firstRunDelayMs: 6e4,
|
|
38319
|
+
run: () => runBrowserOrphanCensus({
|
|
38320
|
+
procRoot: "/proc",
|
|
38321
|
+
tmpRoot: "/tmp",
|
|
38322
|
+
home: homedir4(),
|
|
38323
|
+
nowMs: Date.now()
|
|
38324
|
+
})
|
|
38325
|
+
});
|
|
38326
|
+
}
|
|
38327
|
+
|
|
38166
38328
|
// app/lib/accounts-state-census.ts
|
|
38167
|
-
var
|
|
38329
|
+
var TAG71 = "[accounts-state]";
|
|
38168
38330
|
function runAccountsStateCensus(accountsDir, nowMs) {
|
|
38169
38331
|
const { dirs, provisioning, abandoned } = censusAccountDirs(accountsDir, nowMs);
|
|
38170
38332
|
console.error(
|
|
38171
|
-
`${
|
|
38333
|
+
`${TAG71} op=stub-census dirs=${dirs} provisioning=${provisioning.length} abandoned=${abandoned.length} abandonedIds=${abandoned.length > 0 ? abandoned.join(",") : "none"}`
|
|
38172
38334
|
);
|
|
38173
38335
|
return `${dirs} account dir(s), ${abandoned.length} abandoned`;
|
|
38174
38336
|
}
|
|
@@ -38182,10 +38344,10 @@ function startAccountsStateCensus() {
|
|
|
38182
38344
|
}
|
|
38183
38345
|
|
|
38184
38346
|
// app/lib/cred-refresh-census.ts
|
|
38185
|
-
import { readdirSync as
|
|
38186
|
-
import { homedir as
|
|
38187
|
-
import { join as
|
|
38188
|
-
var
|
|
38347
|
+
import { readdirSync as readdirSync35, readFileSync as readFileSync60 } from "fs";
|
|
38348
|
+
import { homedir as homedir5 } from "os";
|
|
38349
|
+
import { join as join70 } from "path";
|
|
38350
|
+
var TAG72 = "[claude-auth]";
|
|
38189
38351
|
function refreshTokenLength(raw) {
|
|
38190
38352
|
let data;
|
|
38191
38353
|
try {
|
|
@@ -38200,7 +38362,7 @@ function refreshTokenLength(raw) {
|
|
|
38200
38362
|
function surveyBrandCredentials(home) {
|
|
38201
38363
|
let entries2;
|
|
38202
38364
|
try {
|
|
38203
|
-
entries2 =
|
|
38365
|
+
entries2 = readdirSync35(home);
|
|
38204
38366
|
} catch {
|
|
38205
38367
|
return [];
|
|
38206
38368
|
}
|
|
@@ -38209,7 +38371,7 @@ function surveyBrandCredentials(home) {
|
|
|
38209
38371
|
if (!entry3.startsWith(".")) continue;
|
|
38210
38372
|
let raw;
|
|
38211
38373
|
try {
|
|
38212
|
-
raw =
|
|
38374
|
+
raw = readFileSync60(join70(home, entry3, ".claude", ".credentials.json"), "utf-8");
|
|
38213
38375
|
} catch {
|
|
38214
38376
|
continue;
|
|
38215
38377
|
}
|
|
@@ -38224,12 +38386,12 @@ function censusResult(rows) {
|
|
|
38224
38386
|
if (rows.length === 0) return "no-brands-found";
|
|
38225
38387
|
return rows.some(isBlank) ? "blank-tokens" : "ok";
|
|
38226
38388
|
}
|
|
38227
|
-
function runCredRefreshCensus(home =
|
|
38389
|
+
function runCredRefreshCensus(home = homedir5()) {
|
|
38228
38390
|
const rows = surveyBrandCredentials(home);
|
|
38229
38391
|
const blank = rows.filter(isBlank).length;
|
|
38230
38392
|
const detail = rows.map((r) => `${r.brand}:${r.refreshTokenLen === null ? "unreadable" : r.refreshTokenLen}`).join(",");
|
|
38231
38393
|
console.log(
|
|
38232
|
-
`${
|
|
38394
|
+
`${TAG72} op=cred-refresh-census result=${censusResult(rows)} brands=${rows.length} blank=${blank} detail=${detail}`
|
|
38233
38395
|
);
|
|
38234
38396
|
return `${rows.length} brand(s), ${blank} blank`;
|
|
38235
38397
|
}
|
|
@@ -38244,7 +38406,7 @@ function startCredRefreshCensus() {
|
|
|
38244
38406
|
|
|
38245
38407
|
// app/lib/file-watcher.ts
|
|
38246
38408
|
import * as fsp2 from "fs/promises";
|
|
38247
|
-
import { resolve as
|
|
38409
|
+
import { resolve as resolve49, sep as sep12 } from "path";
|
|
38248
38410
|
var ACCOUNT_UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
38249
38411
|
var DEFAULT_COALESCE_MS = 500;
|
|
38250
38412
|
var ROOTS = ["accounts"];
|
|
@@ -38263,7 +38425,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
38263
38425
|
const dropFn = opts.drop ?? dropFileIndex;
|
|
38264
38426
|
for (const r of ROOTS) {
|
|
38265
38427
|
try {
|
|
38266
|
-
await fsp2.mkdir(
|
|
38428
|
+
await fsp2.mkdir(resolve49(dataRoot, r), { recursive: true });
|
|
38267
38429
|
} catch (err) {
|
|
38268
38430
|
console.error(
|
|
38269
38431
|
`[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
|
|
@@ -38284,7 +38446,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
38284
38446
|
timers.set(relativePath, t);
|
|
38285
38447
|
}
|
|
38286
38448
|
async function runHook(relativePath, accountId) {
|
|
38287
|
-
const absolute =
|
|
38449
|
+
const absolute = resolve49(dataRoot, relativePath);
|
|
38288
38450
|
let exists = false;
|
|
38289
38451
|
try {
|
|
38290
38452
|
const st = await fsp2.stat(absolute);
|
|
@@ -38308,7 +38470,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
38308
38470
|
}
|
|
38309
38471
|
}
|
|
38310
38472
|
async function watchRoot(rootName) {
|
|
38311
|
-
const absRoot =
|
|
38473
|
+
const absRoot = resolve49(dataRoot, rootName);
|
|
38312
38474
|
try {
|
|
38313
38475
|
const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
|
|
38314
38476
|
for await (const event of iter) {
|
|
@@ -38347,7 +38509,7 @@ async function startFileWatcher(opts = {}) {
|
|
|
38347
38509
|
|
|
38348
38510
|
// app/lib/migrate-uploads.ts
|
|
38349
38511
|
import { mkdir as mkdir4, readdir as readdir6, rename as rename4, rm as rm3 } from "fs/promises";
|
|
38350
|
-
import { dirname as
|
|
38512
|
+
import { dirname as dirname19, relative as relative8, resolve as resolve50 } from "path";
|
|
38351
38513
|
var ACCOUNT_UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
38352
38514
|
async function walkFiles(dir) {
|
|
38353
38515
|
const out = [];
|
|
@@ -38358,7 +38520,7 @@ async function walkFiles(dir) {
|
|
|
38358
38520
|
return out;
|
|
38359
38521
|
}
|
|
38360
38522
|
for (const e of entries2) {
|
|
38361
|
-
const abs =
|
|
38523
|
+
const abs = resolve50(dir, e.name);
|
|
38362
38524
|
if (e.isDirectory()) {
|
|
38363
38525
|
out.push(...await walkFiles(abs));
|
|
38364
38526
|
} else if (e.isFile()) {
|
|
@@ -38378,8 +38540,8 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
|
|
|
38378
38540
|
let moved = 0;
|
|
38379
38541
|
for (const oldAbs of files) {
|
|
38380
38542
|
const suffix = relative8(srcDir, oldAbs);
|
|
38381
|
-
const newAbs =
|
|
38382
|
-
await mkdir4(
|
|
38543
|
+
const newAbs = resolve50(destDir, suffix);
|
|
38544
|
+
await mkdir4(dirname19(newAbs), { recursive: true });
|
|
38383
38545
|
await rename4(oldAbs, newAbs);
|
|
38384
38546
|
moved++;
|
|
38385
38547
|
const oldRel = relative8(dataRoot, oldAbs);
|
|
@@ -38405,7 +38567,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
|
|
|
38405
38567
|
}
|
|
38406
38568
|
async function migrateUploads(opts = {}) {
|
|
38407
38569
|
const dataRoot = opts.dataRoot ?? DATA_ROOT;
|
|
38408
|
-
const oldRoot =
|
|
38570
|
+
const oldRoot = resolve50(dataRoot, "uploads");
|
|
38409
38571
|
let topEntries;
|
|
38410
38572
|
try {
|
|
38411
38573
|
topEntries = await readdir6(oldRoot, { withFileTypes: true });
|
|
@@ -38426,8 +38588,8 @@ async function migrateUploads(opts = {}) {
|
|
|
38426
38588
|
const name = entry3.name;
|
|
38427
38589
|
if (ACCOUNT_UUID_RE4.test(name)) {
|
|
38428
38590
|
moved += await relocateTree(
|
|
38429
|
-
|
|
38430
|
-
|
|
38591
|
+
resolve50(oldRoot, name),
|
|
38592
|
+
resolve50(dataRoot, "accounts", name, "uploads"),
|
|
38431
38593
|
dataRoot,
|
|
38432
38594
|
name,
|
|
38433
38595
|
session
|
|
@@ -38439,8 +38601,8 @@ async function migrateUploads(opts = {}) {
|
|
|
38439
38601
|
continue;
|
|
38440
38602
|
}
|
|
38441
38603
|
moved += await relocateTree(
|
|
38442
|
-
|
|
38443
|
-
|
|
38604
|
+
resolve50(oldRoot, "public"),
|
|
38605
|
+
resolve50(dataRoot, "accounts", installAccountId, "uploads", "public"),
|
|
38444
38606
|
dataRoot,
|
|
38445
38607
|
null,
|
|
38446
38608
|
// public uploads carry no graph nodes
|
|
@@ -38470,8 +38632,8 @@ async function migrateUploads(opts = {}) {
|
|
|
38470
38632
|
|
|
38471
38633
|
// app/lib/migrate-admin-webchat-sidecars.ts
|
|
38472
38634
|
import { readdir as readdir7, readFile as readFile13, rename as rename5, writeFile as writeFile4, unlink as unlink4 } from "fs/promises";
|
|
38473
|
-
import { existsSync as
|
|
38474
|
-
import { join as
|
|
38635
|
+
import { existsSync as existsSync57 } from "fs";
|
|
38636
|
+
import { join as join71 } from "path";
|
|
38475
38637
|
var ADMIN_ROLE2 = "admin";
|
|
38476
38638
|
var WEBCHAT_CHANNEL2 = "webchat";
|
|
38477
38639
|
var SESSION_META_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
|
|
@@ -38500,7 +38662,7 @@ async function writeRaw(path, obj) {
|
|
|
38500
38662
|
await rename5(tmp, path);
|
|
38501
38663
|
} catch (err) {
|
|
38502
38664
|
try {
|
|
38503
|
-
if (
|
|
38665
|
+
if (existsSync57(tmp)) await unlink4(tmp);
|
|
38504
38666
|
} catch {
|
|
38505
38667
|
}
|
|
38506
38668
|
throw err;
|
|
@@ -38516,7 +38678,7 @@ async function collectLiveSidecars(projectsRoot) {
|
|
|
38516
38678
|
}
|
|
38517
38679
|
for (const slug of slugs) {
|
|
38518
38680
|
if (!slug.isDirectory()) continue;
|
|
38519
|
-
const slugDir =
|
|
38681
|
+
const slugDir = join71(projectsRoot, slug.name);
|
|
38520
38682
|
let entries2;
|
|
38521
38683
|
try {
|
|
38522
38684
|
entries2 = await readdir7(slugDir, { withFileTypes: true });
|
|
@@ -38525,9 +38687,9 @@ async function collectLiveSidecars(projectsRoot) {
|
|
|
38525
38687
|
}
|
|
38526
38688
|
for (const entry3 of entries2) {
|
|
38527
38689
|
if (entry3.isFile() && SESSION_META_RE.test(entry3.name)) {
|
|
38528
|
-
out.push(
|
|
38690
|
+
out.push(join71(slugDir, entry3.name));
|
|
38529
38691
|
} else if (entry3.isDirectory() && entry3.name === "subagents") {
|
|
38530
|
-
const subDir =
|
|
38692
|
+
const subDir = join71(slugDir, entry3.name);
|
|
38531
38693
|
let subs;
|
|
38532
38694
|
try {
|
|
38533
38695
|
subs = await readdir7(subDir, { withFileTypes: true });
|
|
@@ -38535,7 +38697,7 @@ async function collectLiveSidecars(projectsRoot) {
|
|
|
38535
38697
|
continue;
|
|
38536
38698
|
}
|
|
38537
38699
|
for (const s of subs) {
|
|
38538
|
-
if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(
|
|
38700
|
+
if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join71(subDir, s.name));
|
|
38539
38701
|
}
|
|
38540
38702
|
}
|
|
38541
38703
|
}
|
|
@@ -38547,7 +38709,7 @@ function shortId(path) {
|
|
|
38547
38709
|
return base.slice(0, 8);
|
|
38548
38710
|
}
|
|
38549
38711
|
async function migrateAdminWebchatSidecars(opts = {}) {
|
|
38550
|
-
const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ?
|
|
38712
|
+
const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join71(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
|
|
38551
38713
|
const usersFile = opts.usersFile ?? USERS_FILE;
|
|
38552
38714
|
const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
|
|
38553
38715
|
const resolveName = opts.resolveName ?? defaultResolveName;
|
|
@@ -38623,8 +38785,8 @@ async function migrateAdminWebchatSidecars(opts = {}) {
|
|
|
38623
38785
|
|
|
38624
38786
|
// app/lib/migrate-sidecar-account-ids.ts
|
|
38625
38787
|
import { readdir as readdir8, readFile as readFile14, rename as rename6, writeFile as writeFile5, unlink as unlink5 } from "fs/promises";
|
|
38626
|
-
import { existsSync as
|
|
38627
|
-
import { join as
|
|
38788
|
+
import { existsSync as existsSync58 } from "fs";
|
|
38789
|
+
import { join as join72 } from "path";
|
|
38628
38790
|
var SESSION_META_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
|
|
38629
38791
|
function projectSlugForCwd(cwd) {
|
|
38630
38792
|
return cwd.replace(/\//g, "-");
|
|
@@ -38650,7 +38812,7 @@ async function writeRaw2(path, obj) {
|
|
|
38650
38812
|
await rename6(tmp, path);
|
|
38651
38813
|
} catch (err) {
|
|
38652
38814
|
try {
|
|
38653
|
-
if (
|
|
38815
|
+
if (existsSync58(tmp)) await unlink5(tmp);
|
|
38654
38816
|
} catch {
|
|
38655
38817
|
}
|
|
38656
38818
|
throw err;
|
|
@@ -38670,7 +38832,7 @@ async function collectSidecars(projectsRoot) {
|
|
|
38670
38832
|
}
|
|
38671
38833
|
for (const slug of slugs) {
|
|
38672
38834
|
if (!slug.isDirectory()) continue;
|
|
38673
|
-
const slugDir =
|
|
38835
|
+
const slugDir = join72(projectsRoot, slug.name);
|
|
38674
38836
|
let entries2;
|
|
38675
38837
|
try {
|
|
38676
38838
|
entries2 = await readdir8(slugDir, { withFileTypes: true });
|
|
@@ -38679,9 +38841,9 @@ async function collectSidecars(projectsRoot) {
|
|
|
38679
38841
|
}
|
|
38680
38842
|
for (const entry3 of entries2) {
|
|
38681
38843
|
if (entry3.isFile() && SESSION_META_RE2.test(entry3.name)) {
|
|
38682
|
-
out.push({ path:
|
|
38844
|
+
out.push({ path: join72(slugDir, entry3.name), slug: slug.name });
|
|
38683
38845
|
} else if (entry3.isDirectory() && (entry3.name === "subagents" || entry3.name === "archive")) {
|
|
38684
|
-
const subDir =
|
|
38846
|
+
const subDir = join72(slugDir, entry3.name);
|
|
38685
38847
|
let subs;
|
|
38686
38848
|
try {
|
|
38687
38849
|
subs = await readdir8(subDir, { withFileTypes: true });
|
|
@@ -38690,7 +38852,7 @@ async function collectSidecars(projectsRoot) {
|
|
|
38690
38852
|
}
|
|
38691
38853
|
for (const s of subs) {
|
|
38692
38854
|
if (s.isFile() && SESSION_META_RE2.test(s.name)) {
|
|
38693
|
-
out.push({ path:
|
|
38855
|
+
out.push({ path: join72(subDir, s.name), slug: slug.name });
|
|
38694
38856
|
}
|
|
38695
38857
|
}
|
|
38696
38858
|
}
|
|
@@ -38699,7 +38861,7 @@ async function collectSidecars(projectsRoot) {
|
|
|
38699
38861
|
return out;
|
|
38700
38862
|
}
|
|
38701
38863
|
async function migrateSidecarAccountIds(opts = {}) {
|
|
38702
|
-
const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ?
|
|
38864
|
+
const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join72(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
|
|
38703
38865
|
const accounts = opts.accounts ?? listValidAccounts();
|
|
38704
38866
|
const result = {
|
|
38705
38867
|
scanned: 0,
|
|
@@ -40322,8 +40484,8 @@ function createWebchatChannelRoutes(deps) {
|
|
|
40322
40484
|
}
|
|
40323
40485
|
|
|
40324
40486
|
// app/lib/webchat/gateway/resolve-turn-answer.ts
|
|
40325
|
-
import { existsSync as
|
|
40326
|
-
import { join as
|
|
40487
|
+
import { existsSync as existsSync59, openSync as openSync10, readSync as readSync9, closeSync as closeSync10, readdirSync as readdirSync36 } from "fs";
|
|
40488
|
+
import { join as join73 } from "path";
|
|
40327
40489
|
|
|
40328
40490
|
// app/lib/channel-delivery/outbound-guard.ts
|
|
40329
40491
|
var INTERNAL_LEAK_PATTERNS = [
|
|
@@ -40384,16 +40546,16 @@ function resolveTurnAnswer(p) {
|
|
|
40384
40546
|
return segmentText(guardOutbound(p.senderId, parts.join("\n\n"))).join("\n\n");
|
|
40385
40547
|
}
|
|
40386
40548
|
function findJsonl(projectsRoot, sessionId) {
|
|
40387
|
-
if (!
|
|
40549
|
+
if (!existsSync59(projectsRoot)) return null;
|
|
40388
40550
|
let slugs;
|
|
40389
40551
|
try {
|
|
40390
|
-
slugs =
|
|
40552
|
+
slugs = readdirSync36(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
40391
40553
|
} catch {
|
|
40392
40554
|
return null;
|
|
40393
40555
|
}
|
|
40394
40556
|
for (const slug of slugs) {
|
|
40395
|
-
const live =
|
|
40396
|
-
if (
|
|
40557
|
+
const live = join73(projectsRoot, slug, `${sessionId}.jsonl`);
|
|
40558
|
+
if (existsSync59(live)) return live;
|
|
40397
40559
|
}
|
|
40398
40560
|
return null;
|
|
40399
40561
|
}
|
|
@@ -40460,16 +40622,16 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
40460
40622
|
* The public /api/chat route awaits this to return the reply on the same SSE
|
|
40461
40623
|
* response, preserving the pre-756 POST→single-blob browser contract. */
|
|
40462
40624
|
awaitReply(key2, timeoutMs) {
|
|
40463
|
-
return new Promise((
|
|
40625
|
+
return new Promise((resolve57) => {
|
|
40464
40626
|
const timer = setTimeout(() => {
|
|
40465
40627
|
this.replyAwaiters.delete(key2);
|
|
40466
|
-
|
|
40628
|
+
resolve57({ timeout: true });
|
|
40467
40629
|
}, timeoutMs);
|
|
40468
40630
|
if (timer.unref) timer.unref();
|
|
40469
40631
|
this.replyAwaiters.set(key2, (r) => {
|
|
40470
40632
|
clearTimeout(timer);
|
|
40471
40633
|
this.replyAwaiters.delete(key2);
|
|
40472
|
-
|
|
40634
|
+
resolve57(r);
|
|
40473
40635
|
});
|
|
40474
40636
|
});
|
|
40475
40637
|
}
|
|
@@ -40480,11 +40642,11 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
40480
40642
|
* terminal dialog stays answerable). */
|
|
40481
40643
|
awaitPermissionVerdict(p, timeoutMs) {
|
|
40482
40644
|
const k = _WebchatGateway.promptKey(p.key, p.requestId);
|
|
40483
|
-
return new Promise((
|
|
40645
|
+
return new Promise((resolve57) => {
|
|
40484
40646
|
this.pendingPrompts.get(k)?.resolve({ timeout: true });
|
|
40485
40647
|
const timer = setTimeout(() => {
|
|
40486
40648
|
this.pendingPrompts.delete(k);
|
|
40487
|
-
|
|
40649
|
+
resolve57({ timeout: true });
|
|
40488
40650
|
}, timeoutMs);
|
|
40489
40651
|
if (timer.unref) timer.unref();
|
|
40490
40652
|
this.pendingPrompts.set(k, {
|
|
@@ -40494,7 +40656,7 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
40494
40656
|
clearTimeout(timer);
|
|
40495
40657
|
this.pendingPrompts.delete(k);
|
|
40496
40658
|
this.deps.onPointerChange?.(p.key);
|
|
40497
|
-
|
|
40659
|
+
resolve57(r);
|
|
40498
40660
|
}
|
|
40499
40661
|
});
|
|
40500
40662
|
console.error(`[webchat:perm] op=open key=${keyDisplay(p.key)} id=${p.requestId} tool=${p.toolName}`);
|
|
@@ -41339,7 +41501,7 @@ function parityCensusLines() {
|
|
|
41339
41501
|
|
|
41340
41502
|
// app/lib/webchat/file-delivery.ts
|
|
41341
41503
|
import { realpathSync as realpathSync9 } from "fs";
|
|
41342
|
-
import { resolve as
|
|
41504
|
+
import { resolve as resolve51 } from "path";
|
|
41343
41505
|
|
|
41344
41506
|
// app/lib/channel-pty-bridge/file-delivery.ts
|
|
41345
41507
|
var SEND_USER_FILE = "SendUserFile";
|
|
@@ -41430,29 +41592,29 @@ function makeFileDelivery(opts) {
|
|
|
41430
41592
|
}
|
|
41431
41593
|
|
|
41432
41594
|
// app/lib/webchat/file-delivery.ts
|
|
41433
|
-
var
|
|
41595
|
+
var TAG73 = "[webchat-adaptor]";
|
|
41434
41596
|
function platformRoot2() {
|
|
41435
41597
|
return process.env.MAXY_PLATFORM_ROOT || "";
|
|
41436
41598
|
}
|
|
41437
41599
|
function makeWebchatSendFile(entry3) {
|
|
41438
41600
|
return async (filePath) => {
|
|
41439
41601
|
if (!entry3.accountId) {
|
|
41440
|
-
console.error(`${
|
|
41602
|
+
console.error(`${TAG73} file-delivery reject reason=no-account sender=${entry3.senderId}`);
|
|
41441
41603
|
return { ok: false, error: "no-account" };
|
|
41442
41604
|
}
|
|
41443
|
-
const accountDir =
|
|
41605
|
+
const accountDir = resolve51(platformRoot2(), "..", "data/accounts", entry3.accountId);
|
|
41444
41606
|
try {
|
|
41445
41607
|
const resolved = realpathSync9(filePath);
|
|
41446
41608
|
const accountResolved = realpathSync9(accountDir);
|
|
41447
41609
|
if (!resolved.startsWith(accountResolved + "/")) {
|
|
41448
|
-
console.error(`${
|
|
41610
|
+
console.error(`${TAG73} file-delivery reject reason=outside_account_directory sender=${entry3.senderId}`);
|
|
41449
41611
|
return { ok: false, error: "outside-account" };
|
|
41450
41612
|
}
|
|
41451
41613
|
return { ok: true };
|
|
41452
41614
|
} catch (err) {
|
|
41453
41615
|
const code = err.code;
|
|
41454
41616
|
console.error(
|
|
41455
|
-
`${
|
|
41617
|
+
`${TAG73} file-delivery reject reason=${code === "ENOENT" ? "not-found" : "path-error"} sender=${entry3.senderId}`
|
|
41456
41618
|
);
|
|
41457
41619
|
return { ok: false, error: code === "ENOENT" ? "not-found" : "path-error" };
|
|
41458
41620
|
}
|
|
@@ -41461,7 +41623,7 @@ function makeWebchatSendFile(entry3) {
|
|
|
41461
41623
|
function makeWebchatFileDelivery(entry3) {
|
|
41462
41624
|
return makeFileDelivery({
|
|
41463
41625
|
entry: entry3,
|
|
41464
|
-
tag:
|
|
41626
|
+
tag: TAG73,
|
|
41465
41627
|
channel: "webchat",
|
|
41466
41628
|
sendFile: makeWebchatSendFile(entry3),
|
|
41467
41629
|
deferUntilVerdict: true
|
|
@@ -41540,7 +41702,7 @@ function buildPublicWebchatSpawnRequest(input) {
|
|
|
41540
41702
|
}
|
|
41541
41703
|
|
|
41542
41704
|
// app/lib/whatsapp/inbound/file-delivery-bridge.ts
|
|
41543
|
-
var
|
|
41705
|
+
var TAG74 = "[whatsapp-adaptor]";
|
|
41544
41706
|
var SEND_USER_FILE2 = "SendUserFile";
|
|
41545
41707
|
var WHATSAPP_SEND_DOCUMENT = "whatsapp-send-document";
|
|
41546
41708
|
function platformRoot3() {
|
|
@@ -41558,7 +41720,7 @@ function makeWhatsAppSendFile(entry3, maxyAccountId) {
|
|
|
41558
41720
|
});
|
|
41559
41721
|
if (result.ok) return { ok: true };
|
|
41560
41722
|
console.error(
|
|
41561
|
-
`${
|
|
41723
|
+
`${TAG74} file-delivery reject reason=send-failed sender=${entry3.senderId} status=${result.status} message=${result.error}`
|
|
41562
41724
|
);
|
|
41563
41725
|
return { ok: false, error: result.error };
|
|
41564
41726
|
};
|
|
@@ -41566,7 +41728,7 @@ function makeWhatsAppSendFile(entry3, maxyAccountId) {
|
|
|
41566
41728
|
function makeWhatsAppFileDelivery(entry3, maxyAccountId) {
|
|
41567
41729
|
const shared = makeFileDelivery({
|
|
41568
41730
|
entry: entry3,
|
|
41569
|
-
tag:
|
|
41731
|
+
tag: TAG74,
|
|
41570
41732
|
channel: "whatsapp",
|
|
41571
41733
|
sendFile: makeWhatsAppSendFile(entry3, maxyAccountId)
|
|
41572
41734
|
});
|
|
@@ -41601,7 +41763,7 @@ function makeWhatsAppFileDelivery(entry3, maxyAccountId) {
|
|
|
41601
41763
|
if (!delivered) {
|
|
41602
41764
|
const fileField = call2.filePath !== void 0 ? ` file=${call2.filePath}` : "";
|
|
41603
41765
|
console.error(
|
|
41604
|
-
`${
|
|
41766
|
+
`${TAG74} file-delivery-unreconciled sender=${entry3.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
|
|
41605
41767
|
);
|
|
41606
41768
|
}
|
|
41607
41769
|
}
|
|
@@ -41767,7 +41929,7 @@ function whatsappDoorLabel(doorId) {
|
|
|
41767
41929
|
}
|
|
41768
41930
|
|
|
41769
41931
|
// app/lib/channel-delivery/refusal-notice.ts
|
|
41770
|
-
var
|
|
41932
|
+
var TAG75 = "[channel-delivery]";
|
|
41771
41933
|
var notified = /* @__PURE__ */ new Set();
|
|
41772
41934
|
function refusalNoticeText(reason) {
|
|
41773
41935
|
return reason === "claude-auth-dead" ? "Your message arrived but no assistant could be started: the Claude sign-in on this install is not active. An operator has to sign in again; send this again once they have." : `Your message arrived but no assistant could be started (${reason}). Nothing was lost; try again shortly.`;
|
|
@@ -41776,19 +41938,19 @@ async function sendRefusalNotice(input) {
|
|
|
41776
41938
|
if (notified.has(input.doorId)) return;
|
|
41777
41939
|
const fields2 = `channel=${input.channel} sender=${input.sender} reason=${input.reason}`;
|
|
41778
41940
|
if (!input.send) {
|
|
41779
|
-
console.error(`${
|
|
41941
|
+
console.error(`${TAG75} op=refusal-notice-failed ${fields2} error=no-target`);
|
|
41780
41942
|
return;
|
|
41781
41943
|
}
|
|
41782
41944
|
try {
|
|
41783
41945
|
await input.send(guardOutbound(input.sender, refusalNoticeText(input.reason)));
|
|
41784
41946
|
} catch (e) {
|
|
41785
41947
|
console.error(
|
|
41786
|
-
`${
|
|
41948
|
+
`${TAG75} op=refusal-notice-failed ${fields2} error=${e instanceof Error ? e.message : String(e)}`
|
|
41787
41949
|
);
|
|
41788
41950
|
return;
|
|
41789
41951
|
}
|
|
41790
41952
|
notified.add(input.doorId);
|
|
41791
|
-
console.error(`${
|
|
41953
|
+
console.error(`${TAG75} op=refusal-notice ${fields2} status=${input.status}`);
|
|
41792
41954
|
}
|
|
41793
41955
|
function clearRefusalNotice(doorId) {
|
|
41794
41956
|
notified.delete(doorId);
|
|
@@ -42498,10 +42660,10 @@ function buildTelegramSpawnRequest(input) {
|
|
|
42498
42660
|
}
|
|
42499
42661
|
|
|
42500
42662
|
// server/telegram-ensure-session.ts
|
|
42501
|
-
var
|
|
42663
|
+
var TAG76 = "[telegram-inbound]";
|
|
42502
42664
|
function reportReused(botId, channelKey, result) {
|
|
42503
42665
|
if (!result.reused) return;
|
|
42504
|
-
console.error(`${
|
|
42666
|
+
console.error(`${TAG76} op=spawn-reused botId=${botId} key=${channelKey} sessionId=${result.sessionId}`);
|
|
42505
42667
|
}
|
|
42506
42668
|
function buildTelegramEnsureSession(deps) {
|
|
42507
42669
|
return async (input) => {
|
|
@@ -42565,10 +42727,10 @@ function buildTelegramEnsureSession(deps) {
|
|
|
42565
42727
|
return;
|
|
42566
42728
|
}
|
|
42567
42729
|
console.error(
|
|
42568
|
-
`${
|
|
42730
|
+
`${TAG76} op=telegram-spawn-door botId=${input.botId} role=specialist door=rc specialist=${input.specialist}`
|
|
42569
42731
|
);
|
|
42570
42732
|
console.error(
|
|
42571
|
-
`${
|
|
42733
|
+
`${TAG76} op=spawn botId=${input.botId} sessionId=${req.sessionId} targetAccountId=${input.accountId} role=specialist specialist=${input.specialist}`
|
|
42572
42734
|
);
|
|
42573
42735
|
reportReused(input.botId, req.channelKey, result2);
|
|
42574
42736
|
noteSpawnOk2(input.botId);
|
|
@@ -42603,10 +42765,10 @@ function buildTelegramEnsureSession(deps) {
|
|
|
42603
42765
|
return;
|
|
42604
42766
|
}
|
|
42605
42767
|
console.error(
|
|
42606
|
-
`${
|
|
42768
|
+
`${TAG76} op=telegram-spawn-door botId=${input.botId} role=public door=rc agent=${input.agentSlug}`
|
|
42607
42769
|
);
|
|
42608
42770
|
console.error(
|
|
42609
|
-
`${
|
|
42771
|
+
`${TAG76} op=spawn botId=${input.botId} sessionId=${result2.sessionId} targetAccountId=${input.accountId} role=public`
|
|
42610
42772
|
);
|
|
42611
42773
|
reportReused(input.botId, req.channelKey, result2);
|
|
42612
42774
|
noteSpawnOk2(input.botId);
|
|
@@ -42630,7 +42792,7 @@ function buildTelegramEnsureSession(deps) {
|
|
|
42630
42792
|
return;
|
|
42631
42793
|
}
|
|
42632
42794
|
console.error(
|
|
42633
|
-
`${
|
|
42795
|
+
`${TAG76} op=spawn botId=${input.botId} sessionId=${req.sessionId} targetAccountId=${input.accountId} role=admin`
|
|
42634
42796
|
);
|
|
42635
42797
|
reportReused(input.botId, req.channelKey, result);
|
|
42636
42798
|
noteSpawnOk2(input.botId);
|
|
@@ -42648,8 +42810,8 @@ function buildTelegramEnsureSession(deps) {
|
|
|
42648
42810
|
// app/lib/telegram/outbound/send-document.ts
|
|
42649
42811
|
import { realpathSync as realpathSync10 } from "fs";
|
|
42650
42812
|
import { readFile as readFile15, stat as stat10 } from "fs/promises";
|
|
42651
|
-
import { resolve as
|
|
42652
|
-
var
|
|
42813
|
+
import { resolve as resolve52, basename as basename19 } from "path";
|
|
42814
|
+
var TAG77 = "[telegram:outbound]";
|
|
42653
42815
|
var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
|
|
42654
42816
|
async function sendTelegramDocument(input) {
|
|
42655
42817
|
const { botToken, chatId, filePath, caption, maxyAccountId, platformRoot: platformRoot5 } = input;
|
|
@@ -42659,17 +42821,17 @@ async function sendTelegramDocument(input) {
|
|
|
42659
42821
|
if (!maxyAccountId || !platformRoot5) {
|
|
42660
42822
|
return { ok: false, status: 400, error: "Cannot validate file path: missing account or platform context" };
|
|
42661
42823
|
}
|
|
42662
|
-
const accountDir =
|
|
42824
|
+
const accountDir = resolve52(platformRoot5, "..", "data/accounts", maxyAccountId);
|
|
42663
42825
|
let accountResolved;
|
|
42664
42826
|
try {
|
|
42665
42827
|
accountResolved = realpathSync10(accountDir);
|
|
42666
42828
|
} catch (err) {
|
|
42667
42829
|
const code = err.code;
|
|
42668
42830
|
if (code === "ENOENT") {
|
|
42669
|
-
console.error(`${
|
|
42831
|
+
console.error(`${TAG77} document ENOENT scope=account-dir accountDir=${accountDir} maxyAccountId=${maxyAccountId}`);
|
|
42670
42832
|
return { ok: false, status: 500, error: `Account directory not resolvable for ${maxyAccountId}` };
|
|
42671
42833
|
}
|
|
42672
|
-
console.error(`${
|
|
42834
|
+
console.error(`${TAG77} document path error scope=account-dir maxyAccountId=${maxyAccountId}: ${String(err)}`);
|
|
42673
42835
|
return { ok: false, status: 500, error: String(err) };
|
|
42674
42836
|
}
|
|
42675
42837
|
let resolvedPath;
|
|
@@ -42678,14 +42840,14 @@ async function sendTelegramDocument(input) {
|
|
|
42678
42840
|
} catch (err) {
|
|
42679
42841
|
const code = err.code;
|
|
42680
42842
|
if (code === "ENOENT") {
|
|
42681
|
-
console.error(`${
|
|
42843
|
+
console.error(`${TAG77} document ENOENT scope=file path=${filePath} maxyAccountId=${maxyAccountId}`);
|
|
42682
42844
|
return { ok: false, status: 404, error: `File not found: ${filePath}` };
|
|
42683
42845
|
}
|
|
42684
|
-
console.error(`${
|
|
42846
|
+
console.error(`${TAG77} document path error scope=file maxyAccountId=${maxyAccountId}: ${String(err)}`);
|
|
42685
42847
|
return { ok: false, status: 500, error: String(err) };
|
|
42686
42848
|
}
|
|
42687
42849
|
if (!resolvedPath.startsWith(accountResolved + "/")) {
|
|
42688
|
-
console.error(`${
|
|
42850
|
+
console.error(`${TAG77} document REJECTED reason=outside_account_directory maxyAccountId=${maxyAccountId}`);
|
|
42689
42851
|
return { ok: false, status: 403, error: "Access denied: file is outside the account directory" };
|
|
42690
42852
|
}
|
|
42691
42853
|
const fileStat = await stat10(resolvedPath);
|
|
@@ -42696,7 +42858,7 @@ async function sendTelegramDocument(input) {
|
|
|
42696
42858
|
error: `File exceeds 50 MB limit (${(fileStat.size / 1024 / 1024).toFixed(1)} MB)`
|
|
42697
42859
|
};
|
|
42698
42860
|
}
|
|
42699
|
-
const filename =
|
|
42861
|
+
const filename = basename19(resolvedPath);
|
|
42700
42862
|
const buffer = Buffer.from(await readFile15(resolvedPath));
|
|
42701
42863
|
const form = new FormData();
|
|
42702
42864
|
form.append("chat_id", String(chatId));
|
|
@@ -42718,24 +42880,24 @@ async function sendTelegramDocument(input) {
|
|
|
42718
42880
|
error = e instanceof Error ? e.message : String(e);
|
|
42719
42881
|
}
|
|
42720
42882
|
console.error(
|
|
42721
|
-
`${
|
|
42883
|
+
`${TAG77} sent document to=${chatId} file=${filename} bytes=${fileStat.size} ok=${ok2}` + (messageId !== void 0 ? ` id=${messageId}` : "")
|
|
42722
42884
|
);
|
|
42723
42885
|
return ok2 ? { ok: true, messageId } : { ok: false, status: 500, error };
|
|
42724
42886
|
}
|
|
42725
42887
|
|
|
42726
42888
|
// app/lib/telegram/outbound/file-delivery.ts
|
|
42727
|
-
var
|
|
42889
|
+
var TAG78 = "[telegram:outbound]";
|
|
42728
42890
|
function platformRoot4() {
|
|
42729
42891
|
return process.env.MAXY_PLATFORM_ROOT || "";
|
|
42730
42892
|
}
|
|
42731
42893
|
function makeTelegramSendFile(entry3, botToken) {
|
|
42732
42894
|
return async (filePath, caption) => {
|
|
42733
42895
|
if (!botToken) {
|
|
42734
|
-
console.error(`${
|
|
42896
|
+
console.error(`${TAG78} file-delivery reject reason=no-bot-token sender=${entry3.senderId} role=${entry3.role}`);
|
|
42735
42897
|
return { ok: false, error: "no-bot-token" };
|
|
42736
42898
|
}
|
|
42737
42899
|
if (entry3.replyTarget == null) {
|
|
42738
|
-
console.error(`${
|
|
42900
|
+
console.error(`${TAG78} file-delivery reject reason=no-reply-target sender=${entry3.senderId} role=${entry3.role}`);
|
|
42739
42901
|
return { ok: false, error: "no-reply-target" };
|
|
42740
42902
|
}
|
|
42741
42903
|
const result = await sendTelegramDocument({
|
|
@@ -42752,7 +42914,7 @@ function makeTelegramSendFile(entry3, botToken) {
|
|
|
42752
42914
|
function makeTelegramFileDelivery(entry3, botToken) {
|
|
42753
42915
|
return makeFileDelivery({
|
|
42754
42916
|
entry: entry3,
|
|
42755
|
-
tag:
|
|
42917
|
+
tag: TAG78,
|
|
42756
42918
|
channel: "telegram",
|
|
42757
42919
|
sendFile: makeTelegramSendFile(entry3, botToken)
|
|
42758
42920
|
});
|
|
@@ -42982,15 +43144,15 @@ function startTelegramNativeFileFollower(input) {
|
|
|
42982
43144
|
}
|
|
42983
43145
|
|
|
42984
43146
|
// server/telegram-background-active.ts
|
|
42985
|
-
import { join as
|
|
42986
|
-
import { readdirSync as
|
|
43147
|
+
import { join as join74, resolve as resolve53 } from "path";
|
|
43148
|
+
import { readdirSync as readdirSync37, statSync as statSync32 } from "fs";
|
|
42987
43149
|
var SUBAGENT_STALE_WINDOW_MS = 6e4;
|
|
42988
43150
|
var AGENT_JSONL_RE2 = /^agent-([0-9a-f]+)\.jsonl$/;
|
|
42989
43151
|
function makeBackgroundActive(sessionId, deps = {}) {
|
|
42990
43152
|
const findProjectDir = deps.findProjectDir ?? findSessionProjectDir;
|
|
42991
|
-
const readDir = deps.readDir ?? ((d) =>
|
|
43153
|
+
const readDir = deps.readDir ?? ((d) => readdirSync37(d));
|
|
42992
43154
|
const statFile = deps.statFile ?? ((p) => {
|
|
42993
|
-
const st =
|
|
43155
|
+
const st = statSync32(p);
|
|
42994
43156
|
return { size: st.size, mtimeMs: st.mtimeMs };
|
|
42995
43157
|
});
|
|
42996
43158
|
const now = deps.now ?? (() => Date.now());
|
|
@@ -43001,7 +43163,7 @@ function makeBackgroundActive(sessionId, deps = {}) {
|
|
|
43001
43163
|
if (subagentsDir === null) {
|
|
43002
43164
|
const projectDir = findProjectDir(sessionId);
|
|
43003
43165
|
if (projectDir === null) return false;
|
|
43004
|
-
subagentsDir =
|
|
43166
|
+
subagentsDir = resolve53(join74(projectDir, sessionId, "subagents"));
|
|
43005
43167
|
}
|
|
43006
43168
|
let names;
|
|
43007
43169
|
try {
|
|
@@ -43015,7 +43177,7 @@ function makeBackgroundActive(sessionId, deps = {}) {
|
|
|
43015
43177
|
let size;
|
|
43016
43178
|
let mtimeMs;
|
|
43017
43179
|
try {
|
|
43018
|
-
const st = statFile(
|
|
43180
|
+
const st = statFile(join74(subagentsDir, name));
|
|
43019
43181
|
size = st.size;
|
|
43020
43182
|
mtimeMs = st.mtimeMs;
|
|
43021
43183
|
} catch {
|
|
@@ -43095,7 +43257,7 @@ function adminFanTargets(p) {
|
|
|
43095
43257
|
|
|
43096
43258
|
// app/lib/channel-pty-bridge/public-session-end-review.ts
|
|
43097
43259
|
import { randomUUID as randomUUID15 } from "crypto";
|
|
43098
|
-
var
|
|
43260
|
+
var TAG79 = "[public-session-review]";
|
|
43099
43261
|
var CONSUMED_CAP = 500;
|
|
43100
43262
|
var consumed = /* @__PURE__ */ new Set();
|
|
43101
43263
|
function consumeOnce(sessionId) {
|
|
@@ -43122,7 +43284,7 @@ async function fetchJsonl(sessionId) {
|
|
|
43122
43284
|
return await res.text();
|
|
43123
43285
|
} catch (err) {
|
|
43124
43286
|
console.error(
|
|
43125
|
-
`${
|
|
43287
|
+
`${TAG79} jsonl-fetch-failed sessionId=${sessionId} err="${err instanceof Error ? err.message : String(err)}"`
|
|
43126
43288
|
);
|
|
43127
43289
|
return null;
|
|
43128
43290
|
}
|
|
@@ -43146,7 +43308,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
|
|
|
43146
43308
|
const res = await fetch(url);
|
|
43147
43309
|
if (!res.ok) {
|
|
43148
43310
|
console.error(
|
|
43149
|
-
`${
|
|
43311
|
+
`${TAG79} prior-writes-fetch-failed sliceToken=${sliceToken.slice(0, 8)} status=${res.status}`
|
|
43150
43312
|
);
|
|
43151
43313
|
return [];
|
|
43152
43314
|
}
|
|
@@ -43154,7 +43316,7 @@ async function fetchPriorWrites(sliceToken, accountId) {
|
|
|
43154
43316
|
return Array.isArray(body.writes) ? body.writes : [];
|
|
43155
43317
|
} catch (err) {
|
|
43156
43318
|
console.error(
|
|
43157
|
-
`${
|
|
43319
|
+
`${TAG79} prior-writes-fetch-threw sliceToken=${sliceToken.slice(0, 8)} err="${err instanceof Error ? err.message : String(err)}"`
|
|
43158
43320
|
);
|
|
43159
43321
|
return [];
|
|
43160
43322
|
}
|
|
@@ -43183,7 +43345,7 @@ function composeInitialMessage(input) {
|
|
|
43183
43345
|
}
|
|
43184
43346
|
async function dispatchReviewer(input, initialMessage) {
|
|
43185
43347
|
const sessionId = randomUUID15();
|
|
43186
|
-
console.log(`${
|
|
43348
|
+
console.log(`${TAG79} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
|
|
43187
43349
|
const spawned = await managerRcSpawn({
|
|
43188
43350
|
sessionId,
|
|
43189
43351
|
initialMessage,
|
|
@@ -43207,21 +43369,21 @@ async function firePublicSessionEndReview(input) {
|
|
|
43207
43369
|
const dispatchedAt = Date.now();
|
|
43208
43370
|
if (consumed.has(input.sessionId)) {
|
|
43209
43371
|
console.log(
|
|
43210
|
-
`${
|
|
43372
|
+
`${TAG79} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
|
|
43211
43373
|
);
|
|
43212
43374
|
return;
|
|
43213
43375
|
}
|
|
43214
43376
|
const jsonl = await fetchJsonl(input.sessionId);
|
|
43215
43377
|
if (!jsonl) {
|
|
43216
43378
|
console.log(
|
|
43217
|
-
`${
|
|
43379
|
+
`${TAG79} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-jsonl-missing`
|
|
43218
43380
|
);
|
|
43219
43381
|
return;
|
|
43220
43382
|
}
|
|
43221
43383
|
const operatorTurns = countOperatorTurns(jsonl);
|
|
43222
43384
|
if (operatorTurns === 0) {
|
|
43223
43385
|
console.log(
|
|
43224
|
-
`${
|
|
43386
|
+
`${TAG79} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-no-turns`
|
|
43225
43387
|
);
|
|
43226
43388
|
return;
|
|
43227
43389
|
}
|
|
@@ -43235,19 +43397,19 @@ async function firePublicSessionEndReview(input) {
|
|
|
43235
43397
|
});
|
|
43236
43398
|
if (!consumeOnce(input.sessionId)) {
|
|
43237
43399
|
console.log(
|
|
43238
|
-
`${
|
|
43400
|
+
`${TAG79} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-already-reviewed`
|
|
43239
43401
|
);
|
|
43240
43402
|
return;
|
|
43241
43403
|
}
|
|
43242
43404
|
const dispatched = await dispatchReviewer(input, initialMessage);
|
|
43243
43405
|
if (!dispatched.ok) {
|
|
43244
43406
|
console.error(
|
|
43245
|
-
`${
|
|
43407
|
+
`${TAG79} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=skipped-spawn-failed reason=${dispatched.reason}`
|
|
43246
43408
|
);
|
|
43247
43409
|
return;
|
|
43248
43410
|
}
|
|
43249
43411
|
console.log(
|
|
43250
|
-
`${
|
|
43412
|
+
`${TAG79} dispatchFor=${input.dispatchFor} sessionId=${input.sessionId} sliceToken=${sliceShort} personId=${personField} result=dispatched managerSessionId=${dispatched.managerSessionId} operatorTurns=${operatorTurns} priorWrites=${priorWrites.length} ms=${Date.now() - dispatchedAt}`
|
|
43251
43413
|
);
|
|
43252
43414
|
}
|
|
43253
43415
|
|
|
@@ -43381,8 +43543,8 @@ function runPublicAddressCollisionAudit(deps) {
|
|
|
43381
43543
|
}
|
|
43382
43544
|
|
|
43383
43545
|
// server/telegram-audit.ts
|
|
43384
|
-
import { statSync as
|
|
43385
|
-
import { join as
|
|
43546
|
+
import { statSync as statSync33 } from "fs";
|
|
43547
|
+
import { join as join75 } from "path";
|
|
43386
43548
|
function buildTelegramAuditLines(input) {
|
|
43387
43549
|
const lines = [];
|
|
43388
43550
|
const entries2 = input.accounts.flatMap(
|
|
@@ -43490,19 +43652,19 @@ function countTelegramSessionsForAccount(accountId) {
|
|
|
43490
43652
|
function* walkTelegramSidecars() {
|
|
43491
43653
|
const cfg = claudeConfigDir();
|
|
43492
43654
|
if (!cfg) return;
|
|
43493
|
-
const projectsRoot =
|
|
43655
|
+
const projectsRoot = join75(cfg, "projects");
|
|
43494
43656
|
for (const { path } of enumerateSessionSidecars(projectsRoot)) {
|
|
43495
43657
|
const meta = readSidecarMeta(path);
|
|
43496
43658
|
if (meta.channel !== "telegram" || !meta.accountId) continue;
|
|
43497
43659
|
let spawnMs;
|
|
43498
43660
|
try {
|
|
43499
|
-
spawnMs =
|
|
43661
|
+
spawnMs = statSync33(path).mtimeMs;
|
|
43500
43662
|
} catch {
|
|
43501
43663
|
continue;
|
|
43502
43664
|
}
|
|
43503
43665
|
let turnMs;
|
|
43504
43666
|
try {
|
|
43505
|
-
turnMs =
|
|
43667
|
+
turnMs = statSync33(path.replace(/\.meta\.json$/, ".jsonl")).mtimeMs;
|
|
43506
43668
|
} catch {
|
|
43507
43669
|
turnMs = null;
|
|
43508
43670
|
}
|
|
@@ -43516,13 +43678,20 @@ function* walkTelegramSidecars() {
|
|
|
43516
43678
|
}
|
|
43517
43679
|
|
|
43518
43680
|
// server/telegram-group-census.ts
|
|
43519
|
-
var
|
|
43681
|
+
var TAG80 = "[telegram-audit]";
|
|
43520
43682
|
var PRESENT_STATUSES = /* @__PURE__ */ new Set(["member", "administrator", "creator"]);
|
|
43521
43683
|
function buildGroupCensusLine(c) {
|
|
43522
|
-
return `${
|
|
43684
|
+
return `${TAG80} op=group-census bots=${c.bots} groups=${c.groups} present=${c.present} absent=${c.absent} privacyOff=${c.privacyOff} cannotJoin=${c.cannotJoin}`;
|
|
43523
43685
|
}
|
|
43524
43686
|
async function runTelegramGroupCensus(accounts, deps) {
|
|
43525
|
-
const counts = {
|
|
43687
|
+
const counts = {
|
|
43688
|
+
bots: 0,
|
|
43689
|
+
groups: 0,
|
|
43690
|
+
present: 0,
|
|
43691
|
+
absent: 0,
|
|
43692
|
+
privacyOff: 0,
|
|
43693
|
+
cannotJoin: 0
|
|
43694
|
+
};
|
|
43526
43695
|
for (const account of accounts) {
|
|
43527
43696
|
for (const entry3 of listBotEntries(account.telegram)) {
|
|
43528
43697
|
if (entry3.role !== "public") continue;
|
|
@@ -43531,6 +43700,7 @@ async function runTelegramGroupCensus(accounts, deps) {
|
|
|
43531
43700
|
try {
|
|
43532
43701
|
const me = await deps.getMe(entry3.token);
|
|
43533
43702
|
if (me.can_read_all_group_messages === true) counts.privacyOff += 1;
|
|
43703
|
+
if (me.can_join_groups === false) counts.cannotJoin += 1;
|
|
43534
43704
|
} catch {
|
|
43535
43705
|
}
|
|
43536
43706
|
for (const chatId of entry3.allowGroups ?? []) {
|
|
@@ -43550,10 +43720,10 @@ async function runTelegramGroupCensus(accounts, deps) {
|
|
|
43550
43720
|
}
|
|
43551
43721
|
|
|
43552
43722
|
// server/telegram-channel-census.ts
|
|
43553
|
-
var
|
|
43723
|
+
var TAG81 = "[telegram-audit]";
|
|
43554
43724
|
var ADMIN_STATUSES = /* @__PURE__ */ new Set(["administrator", "creator"]);
|
|
43555
43725
|
function buildChannelCensusLine(c) {
|
|
43556
|
-
return `${
|
|
43726
|
+
return `${TAG81} op=channel-census bots=${c.bots} channels=${c.channels} admin=${c.admin} notAdmin=${c.notAdmin} noPostRight=${c.noPostRight}`;
|
|
43557
43727
|
}
|
|
43558
43728
|
async function runTelegramChannelCensus(accounts, deps) {
|
|
43559
43729
|
const counts = { bots: 0, channels: 0, admin: 0, notAdmin: 0, noPostRight: 0 };
|
|
@@ -43585,7 +43755,7 @@ async function runTelegramChannelCensus(accounts, deps) {
|
|
|
43585
43755
|
}
|
|
43586
43756
|
|
|
43587
43757
|
// server/telegram-graph-duplicate-census.ts
|
|
43588
|
-
var
|
|
43758
|
+
var TAG82 = "[telegram-audit]";
|
|
43589
43759
|
var DUPLICATE_QUERY = `
|
|
43590
43760
|
MATCH (m:Message)
|
|
43591
43761
|
WHERE m.accountId = $accountId AND m.channel = 'telegram'
|
|
@@ -43612,12 +43782,12 @@ async function runTelegramGraphDuplicateCensus(accountIds, deps) {
|
|
|
43612
43782
|
const sessions4 = asSessions(Array.isArray(row.sessions) ? row.sessions : []);
|
|
43613
43783
|
const named = sessions4.length > 0 ? ` ids=${sessions4.join(",")}` : "";
|
|
43614
43784
|
lines.push(
|
|
43615
|
-
`${
|
|
43785
|
+
`${TAG82} op=graph-duplicate accountId=${accountId} messages=${messages} sessions=${sessions4.length}${named}`
|
|
43616
43786
|
);
|
|
43617
43787
|
} catch (err) {
|
|
43618
43788
|
const reason = err instanceof Error ? err.message : String(err);
|
|
43619
43789
|
lines.push(
|
|
43620
|
-
`${
|
|
43790
|
+
`${TAG82} FAIL op=graph-duplicate accountId=${accountId} reason=${reason.slice(0, 100)}`
|
|
43621
43791
|
);
|
|
43622
43792
|
}
|
|
43623
43793
|
}
|
|
@@ -43625,9 +43795,9 @@ async function runTelegramGraphDuplicateCensus(accountIds, deps) {
|
|
|
43625
43795
|
}
|
|
43626
43796
|
|
|
43627
43797
|
// server/telegram-identity-census.ts
|
|
43628
|
-
var
|
|
43798
|
+
var TAG83 = "[telegram-audit]";
|
|
43629
43799
|
function buildIdentityCensusLine(c) {
|
|
43630
|
-
return `${
|
|
43800
|
+
return `${TAG83} op=identity-census bots=${c.bots} ids=${c.ids} bound=${c.bound} unbound=${c.unbound} ambiguous=${c.ambiguous}`;
|
|
43631
43801
|
}
|
|
43632
43802
|
async function runTelegramIdentityCensus(accounts, deps) {
|
|
43633
43803
|
const counts = { bots: 0, ids: 0, bound: 0, unbound: 0, ambiguous: 0 };
|
|
@@ -43702,8 +43872,8 @@ function businessConnectionCensusLine(c) {
|
|
|
43702
43872
|
}
|
|
43703
43873
|
|
|
43704
43874
|
// app/lib/telegram/business-window-census.ts
|
|
43705
|
-
import { readdirSync as
|
|
43706
|
-
import { join as
|
|
43875
|
+
import { readdirSync as readdirSync38, existsSync as existsSync60 } from "fs";
|
|
43876
|
+
import { join as join76 } from "path";
|
|
43707
43877
|
var BUSINESS_WINDOW_CENSUS_TAG = "[telegram-audit]";
|
|
43708
43878
|
var EXPIRING_SOON_S = 3600;
|
|
43709
43879
|
function collectBusinessWindowCensus(input) {
|
|
@@ -43731,11 +43901,11 @@ function businessWindowCensusLine(c) {
|
|
|
43731
43901
|
function readBusinessChatClocks(accountIds) {
|
|
43732
43902
|
const out = [];
|
|
43733
43903
|
for (const accountId of accountIds) {
|
|
43734
|
-
const dir =
|
|
43735
|
-
if (!
|
|
43904
|
+
const dir = join76(STORE_ROOT2(), accountId);
|
|
43905
|
+
if (!existsSync60(dir)) continue;
|
|
43736
43906
|
let names;
|
|
43737
43907
|
try {
|
|
43738
|
-
names =
|
|
43908
|
+
names = readdirSync38(dir);
|
|
43739
43909
|
} catch {
|
|
43740
43910
|
continue;
|
|
43741
43911
|
}
|
|
@@ -43793,15 +43963,15 @@ async function getTelegramBusinessConnection(botToken, connectionId, opts = {})
|
|
|
43793
43963
|
}
|
|
43794
43964
|
|
|
43795
43965
|
// server/telegram-migrate.ts
|
|
43796
|
-
import { readFileSync as
|
|
43797
|
-
import { dirname as
|
|
43966
|
+
import { readFileSync as readFileSync61, writeFileSync as writeFileSync23, existsSync as existsSync61, renameSync as renameSync11, mkdirSync as mkdirSync14 } from "fs";
|
|
43967
|
+
import { dirname as dirname20, join as join77 } from "path";
|
|
43798
43968
|
function migrateTelegramTwoSlot(input) {
|
|
43799
43969
|
const out = [];
|
|
43800
43970
|
for (const account of input.accounts) {
|
|
43801
|
-
const configPath3 =
|
|
43971
|
+
const configPath3 = join77(account.accountDir, "account.json");
|
|
43802
43972
|
let config;
|
|
43803
43973
|
try {
|
|
43804
|
-
config = JSON.parse(
|
|
43974
|
+
config = JSON.parse(readFileSync61(configPath3, "utf-8"));
|
|
43805
43975
|
} catch {
|
|
43806
43976
|
console.error(`[telegram-audit] op=migrate-unreadable accountId=${account.accountId}`);
|
|
43807
43977
|
continue;
|
|
@@ -43854,22 +44024,22 @@ function migrateTelegramTwoSlot(input) {
|
|
|
43854
44024
|
return out;
|
|
43855
44025
|
}
|
|
43856
44026
|
function moveSecret(from, to) {
|
|
43857
|
-
if (!
|
|
43858
|
-
mkdirSync14(
|
|
44027
|
+
if (!existsSync61(from)) return;
|
|
44028
|
+
mkdirSync14(dirname20(to), { recursive: true, mode: 448 });
|
|
43859
44029
|
renameSync11(from, to);
|
|
43860
44030
|
}
|
|
43861
44031
|
|
|
43862
44032
|
// server/telegram-unadopt.ts
|
|
43863
|
-
import { readFileSync as
|
|
43864
|
-
import { join as
|
|
44033
|
+
import { readFileSync as readFileSync62, writeFileSync as writeFileSync24, renameSync as renameSync12 } from "fs";
|
|
44034
|
+
import { join as join78 } from "path";
|
|
43865
44035
|
var FILE3 = "channel-session-override.json";
|
|
43866
44036
|
function unadoptTelegramPointers(input) {
|
|
43867
44037
|
return input.accounts.map(({ accountId, accountDir }) => {
|
|
43868
44038
|
const out = { accountId, dropped: [], kept: 0, unknown: 0 };
|
|
43869
|
-
const path =
|
|
44039
|
+
const path = join78(accountDir, FILE3);
|
|
43870
44040
|
const bySender = {};
|
|
43871
44041
|
try {
|
|
43872
|
-
const raw = JSON.parse(
|
|
44042
|
+
const raw = JSON.parse(readFileSync62(path, "utf8"));
|
|
43873
44043
|
if (!raw.bySender || typeof raw.bySender !== "object") return out;
|
|
43874
44044
|
for (const [k, v] of Object.entries(raw.bySender)) if (typeof v === "string") bySender[k] = v;
|
|
43875
44045
|
} catch {
|
|
@@ -43940,14 +44110,14 @@ function backfillMisfiledRecords(params) {
|
|
|
43940
44110
|
}
|
|
43941
44111
|
|
|
43942
44112
|
// server/lib/booking-site-accounts.ts
|
|
43943
|
-
import { existsSync as
|
|
43944
|
-
import { resolve as
|
|
44113
|
+
import { existsSync as existsSync62, readFileSync as readFileSync63 } from "fs";
|
|
44114
|
+
import { resolve as resolve54 } from "path";
|
|
43945
44115
|
function listBookingSiteAccounts(accounts) {
|
|
43946
44116
|
return accounts.filter((a) => {
|
|
43947
|
-
const availPath =
|
|
43948
|
-
if (!
|
|
44117
|
+
const availPath = resolve54(a.accountDir, "calendar-availability.json");
|
|
44118
|
+
if (!existsSync62(availPath)) return false;
|
|
43949
44119
|
try {
|
|
43950
|
-
const cfg = JSON.parse(
|
|
44120
|
+
const cfg = JSON.parse(readFileSync63(availPath, "utf-8"));
|
|
43951
44121
|
return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
|
|
43952
44122
|
} catch {
|
|
43953
44123
|
return false;
|
|
@@ -43985,8 +44155,8 @@ function broadcastAdminShutdown(reason) {
|
|
|
43985
44155
|
|
|
43986
44156
|
// ../lib/entitlement/src/index.ts
|
|
43987
44157
|
import { createPublicKey, createHash as createHash7, verify as cryptoVerify } from "crypto";
|
|
43988
|
-
import { existsSync as
|
|
43989
|
-
import { resolve as
|
|
44158
|
+
import { existsSync as existsSync63, readFileSync as readFileSync64, statSync as statSync34 } from "fs";
|
|
44159
|
+
import { resolve as resolve55 } from "path";
|
|
43990
44160
|
|
|
43991
44161
|
// ../lib/entitlement/src/canonicalize.ts
|
|
43992
44162
|
function canonicalize(value) {
|
|
@@ -44021,7 +44191,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
|
|
|
44021
44191
|
var GRACE_DAYS = 7;
|
|
44022
44192
|
var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
|
|
44023
44193
|
function pubkeyPath(brand) {
|
|
44024
|
-
return
|
|
44194
|
+
return resolve55(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
|
|
44025
44195
|
}
|
|
44026
44196
|
var memo = null;
|
|
44027
44197
|
function memoKey(mtimeMs, account) {
|
|
@@ -44033,11 +44203,11 @@ function resolveEntitlement(brand, account) {
|
|
|
44033
44203
|
if (brand.commercialMode !== true) {
|
|
44034
44204
|
return logResolved(implicitTrust(account), null);
|
|
44035
44205
|
}
|
|
44036
|
-
const entitlementPath =
|
|
44037
|
-
if (!
|
|
44206
|
+
const entitlementPath = resolve55(brand.configDir, "entitlement.json");
|
|
44207
|
+
if (!existsSync63(entitlementPath)) {
|
|
44038
44208
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
44039
44209
|
}
|
|
44040
|
-
const stat11 =
|
|
44210
|
+
const stat11 = statSync34(entitlementPath);
|
|
44041
44211
|
const key2 = memoKey(stat11.mtimeMs, account);
|
|
44042
44212
|
if (memo && memo.key === key2) {
|
|
44043
44213
|
return memo.result;
|
|
@@ -44049,7 +44219,7 @@ function resolveEntitlement(brand, account) {
|
|
|
44049
44219
|
function verifyAndResolve(brand, entitlementPath, account) {
|
|
44050
44220
|
let pubkeyPem;
|
|
44051
44221
|
try {
|
|
44052
|
-
pubkeyPem =
|
|
44222
|
+
pubkeyPem = readFileSync64(pubkeyPath(brand), "utf-8");
|
|
44053
44223
|
} catch (err) {
|
|
44054
44224
|
return logResolved(anonymousFallback("pubkey-missing"), {
|
|
44055
44225
|
reason: "pubkey-missing"
|
|
@@ -44063,7 +44233,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
|
|
|
44063
44233
|
}
|
|
44064
44234
|
let envelope;
|
|
44065
44235
|
try {
|
|
44066
|
-
envelope = JSON.parse(
|
|
44236
|
+
envelope = JSON.parse(readFileSync64(entitlementPath, "utf-8"));
|
|
44067
44237
|
} catch {
|
|
44068
44238
|
return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
|
|
44069
44239
|
}
|
|
@@ -44225,14 +44395,14 @@ function clientFrom(c) {
|
|
|
44225
44395
|
}
|
|
44226
44396
|
installMediaDownloadGuard();
|
|
44227
44397
|
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
44228
|
-
var BRAND_JSON_PATH = PLATFORM_ROOT6 ?
|
|
44398
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT6 ? join79(PLATFORM_ROOT6, "config", "brand.json") : "";
|
|
44229
44399
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
|
|
44230
|
-
if (BRAND_JSON_PATH && !
|
|
44400
|
+
if (BRAND_JSON_PATH && !existsSync64(BRAND_JSON_PATH)) {
|
|
44231
44401
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
44232
44402
|
}
|
|
44233
|
-
if (BRAND_JSON_PATH &&
|
|
44403
|
+
if (BRAND_JSON_PATH && existsSync64(BRAND_JSON_PATH)) {
|
|
44234
44404
|
try {
|
|
44235
|
-
const parsed = JSON.parse(
|
|
44405
|
+
const parsed = JSON.parse(readFileSync65(BRAND_JSON_PATH, "utf-8"));
|
|
44236
44406
|
BRAND = { ...BRAND, ...parsed };
|
|
44237
44407
|
} catch (err) {
|
|
44238
44408
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -44264,11 +44434,11 @@ var brandLoginOpts = {
|
|
|
44264
44434
|
appleTouchIconPath: brandAppIcon512Path,
|
|
44265
44435
|
themeColor: BRAND.defaultColors?.primary
|
|
44266
44436
|
};
|
|
44267
|
-
var ALIAS_DOMAINS_PATH =
|
|
44437
|
+
var ALIAS_DOMAINS_PATH = join79(homedir6(), BRAND.configDir, "alias-domains.json");
|
|
44268
44438
|
function loadAliasDomains() {
|
|
44269
44439
|
try {
|
|
44270
|
-
if (!
|
|
44271
|
-
const parsed = JSON.parse(
|
|
44440
|
+
if (!existsSync64(ALIAS_DOMAINS_PATH)) return null;
|
|
44441
|
+
const parsed = JSON.parse(readFileSync65(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
44272
44442
|
if (!Array.isArray(parsed)) {
|
|
44273
44443
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
44274
44444
|
return null;
|
|
@@ -44410,7 +44580,7 @@ var waGateway = new WaGateway({
|
|
|
44410
44580
|
// resolver and `fanTargetsFor` is a constructor dep, not a callable method.
|
|
44411
44581
|
fanTargetsFor: whatsappFanTargets,
|
|
44412
44582
|
gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
|
|
44413
|
-
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ??
|
|
44583
|
+
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve56(process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
|
|
44414
44584
|
// Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
|
|
44415
44585
|
// path-validation scope) is the sender's effective SESSION account, resolved
|
|
44416
44586
|
// once at the inbound gate and threaded here via the gateway's per-sender doc
|
|
@@ -44425,7 +44595,7 @@ var waGateway = new WaGateway({
|
|
|
44425
44595
|
caption,
|
|
44426
44596
|
accountId,
|
|
44427
44597
|
maxyAccountId,
|
|
44428
|
-
platformRoot:
|
|
44598
|
+
platformRoot: resolve56(process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, ".."))
|
|
44429
44599
|
});
|
|
44430
44600
|
return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
|
|
44431
44601
|
},
|
|
@@ -44600,7 +44770,7 @@ function runDuplicateSenderAudit() {
|
|
|
44600
44770
|
try {
|
|
44601
44771
|
const configDir = process.env.CLAUDE_CONFIG_DIR;
|
|
44602
44772
|
if (!configDir) return;
|
|
44603
|
-
const projectsRoot =
|
|
44773
|
+
const projectsRoot = join79(configDir, "projects");
|
|
44604
44774
|
const records5 = [];
|
|
44605
44775
|
for (const { path: jsonlPath, isSubagent, archived } of enumerateJsonls(projectsRoot)) {
|
|
44606
44776
|
if (isSubagent || archived) continue;
|
|
@@ -44652,7 +44822,7 @@ var webchatGateway = new WebchatGateway({
|
|
|
44652
44822
|
// rather than hanging the POST.
|
|
44653
44823
|
publicProjectsRoot: () => {
|
|
44654
44824
|
const cfg = claudeConfigDir();
|
|
44655
|
-
return cfg ?
|
|
44825
|
+
return cfg ? join79(cfg, "projects") : "";
|
|
44656
44826
|
},
|
|
44657
44827
|
gatewayUrl: webchatGatewayUrl(),
|
|
44658
44828
|
serverPath: webchatServerPath(),
|
|
@@ -45339,20 +45509,20 @@ app80.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
45339
45509
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
45340
45510
|
return c.text("Not found", 404);
|
|
45341
45511
|
}
|
|
45342
|
-
const filePath =
|
|
45343
|
-
const expectedDir =
|
|
45512
|
+
const filePath = resolve56(account.accountDir, "agents", slug, "assets", filename);
|
|
45513
|
+
const expectedDir = resolve56(account.accountDir, "agents", slug, "assets");
|
|
45344
45514
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
45345
45515
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
45346
45516
|
return c.text("Forbidden", 403);
|
|
45347
45517
|
}
|
|
45348
|
-
if (!
|
|
45518
|
+
if (!existsSync64(filePath)) {
|
|
45349
45519
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
45350
45520
|
return c.text("Not found", 404);
|
|
45351
45521
|
}
|
|
45352
45522
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
45353
45523
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
45354
45524
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
45355
|
-
const body =
|
|
45525
|
+
const body = readFileSync65(filePath);
|
|
45356
45526
|
return c.body(body, 200, {
|
|
45357
45527
|
"Content-Type": contentType,
|
|
45358
45528
|
"Cache-Control": "public, max-age=3600"
|
|
@@ -45369,20 +45539,20 @@ app80.get("/generated/:filename", (c) => {
|
|
|
45369
45539
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
45370
45540
|
return c.text("Not found", 404);
|
|
45371
45541
|
}
|
|
45372
|
-
const filePath =
|
|
45373
|
-
const expectedDir =
|
|
45542
|
+
const filePath = resolve56(account.accountDir, "generated", filename);
|
|
45543
|
+
const expectedDir = resolve56(account.accountDir, "generated");
|
|
45374
45544
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
45375
45545
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
45376
45546
|
return c.text("Forbidden", 403);
|
|
45377
45547
|
}
|
|
45378
|
-
if (!
|
|
45548
|
+
if (!existsSync64(filePath)) {
|
|
45379
45549
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
45380
45550
|
return c.text("Not found", 404);
|
|
45381
45551
|
}
|
|
45382
45552
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
45383
45553
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
45384
45554
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
45385
|
-
const body =
|
|
45555
|
+
const body = readFileSync65(filePath);
|
|
45386
45556
|
return c.body(body, 200, {
|
|
45387
45557
|
"Content-Type": contentType,
|
|
45388
45558
|
"Cache-Control": "public, max-age=86400"
|
|
@@ -45395,9 +45565,9 @@ app80.route("/v", visitor_consent_default);
|
|
|
45395
45565
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
45396
45566
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
45397
45567
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
45398
|
-
if (BRAND_JSON_PATH &&
|
|
45568
|
+
if (BRAND_JSON_PATH && existsSync64(BRAND_JSON_PATH)) {
|
|
45399
45569
|
try {
|
|
45400
|
-
const fullBrand = JSON.parse(
|
|
45570
|
+
const fullBrand = JSON.parse(readFileSync65(BRAND_JSON_PATH, "utf-8"));
|
|
45401
45571
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
45402
45572
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
45403
45573
|
} catch {
|
|
@@ -45424,11 +45594,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
45424
45594
|
var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
|
|
45425
45595
|
var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
|
|
45426
45596
|
var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
|
|
45427
|
-
(p) =>
|
|
45597
|
+
(p) => existsSync64(resolve56(process.cwd(), "public", p.replace(/^\//, "")))
|
|
45428
45598
|
);
|
|
45429
45599
|
var SW_SOURCE = (() => {
|
|
45430
45600
|
try {
|
|
45431
|
-
return
|
|
45601
|
+
return readFileSync65(resolve56(process.cwd(), "public", "sw.js"), "utf-8");
|
|
45432
45602
|
} catch {
|
|
45433
45603
|
return null;
|
|
45434
45604
|
}
|
|
@@ -45436,9 +45606,9 @@ var SW_SOURCE = (() => {
|
|
|
45436
45606
|
function readInstalledVersion() {
|
|
45437
45607
|
try {
|
|
45438
45608
|
if (!PLATFORM_ROOT6) return "unknown";
|
|
45439
|
-
const versionFile =
|
|
45440
|
-
if (!
|
|
45441
|
-
const content =
|
|
45609
|
+
const versionFile = join79(PLATFORM_ROOT6, "config", `.${BRAND.hostname}-version`);
|
|
45610
|
+
if (!existsSync64(versionFile)) return "unknown";
|
|
45611
|
+
const content = readFileSync65(versionFile, "utf-8").trim();
|
|
45442
45612
|
return content || "unknown";
|
|
45443
45613
|
} catch {
|
|
45444
45614
|
return "unknown";
|
|
@@ -45449,7 +45619,7 @@ var versionScript = `<script>window.__MAXY_VERSION__=${JSON.stringify(INSTALLED_
|
|
|
45449
45619
|
function cachedHtml(file) {
|
|
45450
45620
|
let html = htmlCache.get(file);
|
|
45451
45621
|
if (!html) {
|
|
45452
|
-
html =
|
|
45622
|
+
html = readFileSync65(resolve56(process.cwd(), "public", file), "utf-8");
|
|
45453
45623
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
45454
45624
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
45455
45625
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -45466,14 +45636,14 @@ ${clientErrorReporterScript}
|
|
|
45466
45636
|
return html;
|
|
45467
45637
|
}
|
|
45468
45638
|
function loadBrandingCache(agentSlug) {
|
|
45469
|
-
const configDir =
|
|
45639
|
+
const configDir = join79(homedir6(), BRAND.configDir);
|
|
45470
45640
|
try {
|
|
45471
45641
|
const verdict = resolvePublicAddressFromDisk(agentSlug);
|
|
45472
45642
|
const accountId = verdict.kind === "served" ? verdict.owner.accountId : getDefaultAccountId();
|
|
45473
45643
|
if (!accountId) return null;
|
|
45474
|
-
const cachePath =
|
|
45475
|
-
if (!
|
|
45476
|
-
return JSON.parse(
|
|
45644
|
+
const cachePath = join79(configDir, "branding-cache", accountId, `${agentSlug}.json`);
|
|
45645
|
+
if (!existsSync64(cachePath)) return null;
|
|
45646
|
+
return JSON.parse(readFileSync65(cachePath, "utf-8"));
|
|
45477
45647
|
} catch {
|
|
45478
45648
|
return null;
|
|
45479
45649
|
}
|
|
@@ -45568,7 +45738,7 @@ app80.use("/vnc-popout.html", logViewerFetch);
|
|
|
45568
45738
|
app80.get("/vnc-popout.html", (c) => {
|
|
45569
45739
|
let html = htmlCache.get("vnc-popout.html");
|
|
45570
45740
|
if (!html) {
|
|
45571
|
-
html =
|
|
45741
|
+
html = readFileSync65(resolve56(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
45572
45742
|
const name = escapeHtml(BRAND.productName);
|
|
45573
45743
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
45574
45744
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -45722,10 +45892,10 @@ var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
|
45722
45892
|
var httpServer = serve({ fetch: app80.fetch, port, hostname });
|
|
45723
45893
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
45724
45894
|
{
|
|
45725
|
-
const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
45726
|
-
const reconcileScript =
|
|
45895
|
+
const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, "..");
|
|
45896
|
+
const reconcileScript = resolve56(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
|
|
45727
45897
|
const runReconcile = (ctx) => {
|
|
45728
|
-
if (!
|
|
45898
|
+
if (!existsSync64(reconcileScript)) return;
|
|
45729
45899
|
try {
|
|
45730
45900
|
const child = spawn3(process.execPath, [reconcileScript], {
|
|
45731
45901
|
env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
|
|
@@ -45745,7 +45915,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
45745
45915
|
detached: true,
|
|
45746
45916
|
run: runReconcile
|
|
45747
45917
|
});
|
|
45748
|
-
const reconcileStatePath =
|
|
45918
|
+
const reconcileStatePath = join79(MAXY_DIR, "booking-reconcile-state.json");
|
|
45749
45919
|
registerLoop({
|
|
45750
45920
|
name: "calendar-reconcile-liveness",
|
|
45751
45921
|
intervalMs: 6e5,
|
|
@@ -45763,15 +45933,15 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
45763
45933
|
}
|
|
45764
45934
|
{
|
|
45765
45935
|
const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
|
|
45766
|
-
const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
45767
|
-
const dreamSweepScript =
|
|
45936
|
+
const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, "..");
|
|
45937
|
+
const dreamSweepScript = resolve56(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
|
|
45768
45938
|
registerLoop({
|
|
45769
45939
|
name: "dream-cycle-sweep",
|
|
45770
45940
|
intervalMs: DREAM_CYCLE_SWEEP_INTERVAL_MS,
|
|
45771
45941
|
firstRunDelayMs: 3e4,
|
|
45772
45942
|
detached: true,
|
|
45773
45943
|
run: (ctx) => {
|
|
45774
|
-
if (!
|
|
45944
|
+
if (!existsSync64(dreamSweepScript)) return;
|
|
45775
45945
|
try {
|
|
45776
45946
|
const child = spawn3(process.execPath, [dreamSweepScript], {
|
|
45777
45947
|
env: { ...process.env, PLATFORM_ROOT: dreamPlatformRoot },
|
|
@@ -45787,11 +45957,11 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
45787
45957
|
});
|
|
45788
45958
|
}
|
|
45789
45959
|
{
|
|
45790
|
-
const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
45791
|
-
const outlookScript =
|
|
45960
|
+
const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, "..");
|
|
45961
|
+
const outlookScript = resolve56(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
|
|
45792
45962
|
const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
|
|
45793
45963
|
const runOutlookComplete = (ctx) => {
|
|
45794
|
-
if (!
|
|
45964
|
+
if (!existsSync64(outlookScript)) return;
|
|
45795
45965
|
try {
|
|
45796
45966
|
const child = spawn3(process.execPath, [outlookScript], {
|
|
45797
45967
|
env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
|
|
@@ -45813,20 +45983,20 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
45813
45983
|
});
|
|
45814
45984
|
}
|
|
45815
45985
|
{
|
|
45816
|
-
const auditRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
45817
|
-
const strandedAccountsDir =
|
|
45986
|
+
const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, "..");
|
|
45987
|
+
const strandedAccountsDir = resolve56(auditRoot, "..", "data/accounts");
|
|
45818
45988
|
const STRANDED_AUDIT_INTERVAL_MS = 3e5;
|
|
45819
45989
|
const STRANDED_AGE_MS = 16 * 6e4;
|
|
45820
45990
|
const STRANDED_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
45821
45991
|
const runStrandedAudit = () => {
|
|
45822
45992
|
try {
|
|
45823
|
-
if (!
|
|
45993
|
+
if (!existsSync64(strandedAccountsDir)) return;
|
|
45824
45994
|
const now = Date.now();
|
|
45825
|
-
for (const name of
|
|
45995
|
+
for (const name of readdirSync39(strandedAccountsDir)) {
|
|
45826
45996
|
if (!STRANDED_UUID_RE.test(name)) continue;
|
|
45827
|
-
const pendingPath2 =
|
|
45828
|
-
if (!
|
|
45829
|
-
const ageMs2 = now -
|
|
45997
|
+
const pendingPath2 = resolve56(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
|
|
45998
|
+
if (!existsSync64(pendingPath2)) continue;
|
|
45999
|
+
const ageMs2 = now - statSync35(pendingPath2).mtimeMs;
|
|
45830
46000
|
if (ageMs2 > STRANDED_AGE_MS) {
|
|
45831
46001
|
console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
|
|
45832
46002
|
}
|
|
@@ -45843,8 +46013,8 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
45843
46013
|
});
|
|
45844
46014
|
}
|
|
45845
46015
|
{
|
|
45846
|
-
const googleRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
45847
|
-
const googleAccountsDir =
|
|
46016
|
+
const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, "..");
|
|
46017
|
+
const googleAccountsDir = resolve56(googleRoot, "..", "data/accounts");
|
|
45848
46018
|
const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
|
|
45849
46019
|
const runGooglePendingAuditSafe = () => {
|
|
45850
46020
|
try {
|
|
@@ -45859,10 +46029,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
|
45859
46029
|
firstRunDelayMs: 27e3,
|
|
45860
46030
|
run: runGooglePendingAuditSafe
|
|
45861
46031
|
});
|
|
45862
|
-
const googleAuditScript =
|
|
46032
|
+
const googleAuditScript = resolve56(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
|
|
45863
46033
|
const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
|
|
45864
46034
|
const runGoogleAccountAudit = (ctx) => {
|
|
45865
|
-
if (!
|
|
46035
|
+
if (!existsSync64(googleAuditScript)) return;
|
|
45866
46036
|
try {
|
|
45867
46037
|
const child = spawn3(process.execPath, [googleAuditScript], {
|
|
45868
46038
|
env: { ...process.env, PLATFORM_ROOT: googleRoot },
|
|
@@ -45899,7 +46069,7 @@ registerLoop({
|
|
|
45899
46069
|
}
|
|
45900
46070
|
});
|
|
45901
46071
|
{
|
|
45902
|
-
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
46072
|
+
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, "..");
|
|
45903
46073
|
const STORAGE_AUDIT_INTERVAL_MS = 3e5;
|
|
45904
46074
|
const runStorageAuditSafe = () => runStorageAudit(auditPlatformRoot).catch((err) => {
|
|
45905
46075
|
console.error(`[storage-audit] error="${err.message}"`);
|
|
@@ -45934,8 +46104,8 @@ registerLoop({
|
|
|
45934
46104
|
for (const o of migrateTelegramTwoSlot({
|
|
45935
46105
|
accounts: listValidAccounts().map((a) => ({ accountId: a.accountId, accountDir: a.accountDir })),
|
|
45936
46106
|
secretPathFor: secretPath,
|
|
45937
|
-
legacySecretPathFor: (botType, accountId) =>
|
|
45938
|
-
|
|
46107
|
+
legacySecretPathFor: (botType, accountId) => resolve56(
|
|
46108
|
+
homedir6(),
|
|
45939
46109
|
configDirName(),
|
|
45940
46110
|
`${botType === "admin" ? ".telegram-admin-webhook-secret" : ".telegram-webhook-secret"}.${accountId}`
|
|
45941
46111
|
),
|
|
@@ -45966,15 +46136,15 @@ registerLoop({
|
|
|
45966
46136
|
const lastByBot = newestTelegramSessionByBot();
|
|
45967
46137
|
let secretFilesOnDisk = [];
|
|
45968
46138
|
try {
|
|
45969
|
-
secretFilesOnDisk =
|
|
46139
|
+
secretFilesOnDisk = readdirSync39(telegramSecretsDir());
|
|
45970
46140
|
} catch {
|
|
45971
46141
|
}
|
|
45972
46142
|
const lines = buildTelegramAuditLines({
|
|
45973
46143
|
accounts,
|
|
45974
|
-
secretFileExists: (botId) =>
|
|
46144
|
+
secretFileExists: (botId) => existsSync64(secretPath(botId)),
|
|
45975
46145
|
agentActive: isActiveAgentSlug,
|
|
45976
46146
|
// Task 2619 — the card set a specialist binding is reconciled against.
|
|
45977
|
-
specialistCards: (accountDir) => listSpecialistCardNames(
|
|
46147
|
+
specialistCards: (accountDir) => listSpecialistCardNames(join79(accountDir, "specialists", "agents")),
|
|
45978
46148
|
// Task 2619 — the doors that can be sent to right now. The same accessor
|
|
45979
46149
|
// the follower census reads (:1185), so "should have a reader" and "can be
|
|
45980
46150
|
// sent to" stay one fact.
|
|
@@ -46383,8 +46553,8 @@ registerLoop({
|
|
|
46383
46553
|
});
|
|
46384
46554
|
}
|
|
46385
46555
|
{
|
|
46386
|
-
const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
46387
|
-
const publishScript =
|
|
46556
|
+
const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, "..");
|
|
46557
|
+
const publishScript = resolve56(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
|
|
46388
46558
|
const PUBLISH_INTERVAL_MS = 3e5;
|
|
46389
46559
|
const bookingAccounts = () => {
|
|
46390
46560
|
try {
|
|
@@ -46395,7 +46565,7 @@ registerLoop({
|
|
|
46395
46565
|
}
|
|
46396
46566
|
};
|
|
46397
46567
|
const spawnPublish = (account, ctx) => {
|
|
46398
|
-
if (!
|
|
46568
|
+
if (!existsSync64(publishScript)) return;
|
|
46399
46569
|
try {
|
|
46400
46570
|
const child = spawn3(process.execPath, [publishScript], {
|
|
46401
46571
|
env: {
|
|
@@ -46414,21 +46584,21 @@ registerLoop({
|
|
|
46414
46584
|
}
|
|
46415
46585
|
};
|
|
46416
46586
|
const auditSnapshotAge = (account) => {
|
|
46417
|
-
const availPath =
|
|
46587
|
+
const availPath = resolve56(account.accountDir, "calendar-availability.json");
|
|
46418
46588
|
let hasBookingSite = false;
|
|
46419
46589
|
try {
|
|
46420
|
-
if (
|
|
46421
|
-
const cfg = JSON.parse(
|
|
46590
|
+
if (existsSync64(availPath)) {
|
|
46591
|
+
const cfg = JSON.parse(readFileSync65(availPath, "utf-8"));
|
|
46422
46592
|
hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
|
|
46423
46593
|
}
|
|
46424
46594
|
} catch {
|
|
46425
46595
|
}
|
|
46426
46596
|
if (!hasBookingSite) return;
|
|
46427
|
-
const statePath =
|
|
46597
|
+
const statePath = resolve56(account.accountDir, "state", "booking-availability", "last-publish.json");
|
|
46428
46598
|
let lastSuccessAt = null;
|
|
46429
|
-
if (
|
|
46599
|
+
if (existsSync64(statePath)) {
|
|
46430
46600
|
try {
|
|
46431
|
-
const rec = JSON.parse(
|
|
46601
|
+
const rec = JSON.parse(readFileSync65(statePath, "utf-8"));
|
|
46432
46602
|
lastSuccessAt = rec.lastSuccessAt ?? null;
|
|
46433
46603
|
} catch {
|
|
46434
46604
|
console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
|
|
@@ -46463,12 +46633,12 @@ startDispatchCensus(() => getSession());
|
|
|
46463
46633
|
startDispatchFieldCensus(() => getSession());
|
|
46464
46634
|
startDispatchTgCensus(() => getSession());
|
|
46465
46635
|
{
|
|
46466
|
-
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
46467
|
-
const auditScript =
|
|
46636
|
+
const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, "..");
|
|
46637
|
+
const auditScript = resolve56(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
|
|
46468
46638
|
const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
|
|
46469
46639
|
const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
|
|
46470
46640
|
const runConnectorAudit = (ctx) => {
|
|
46471
|
-
if (!
|
|
46641
|
+
if (!existsSync64(auditScript)) return;
|
|
46472
46642
|
try {
|
|
46473
46643
|
const child = spawn3(process.execPath, [auditScript], {
|
|
46474
46644
|
env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
|
|
@@ -46590,11 +46760,11 @@ try {
|
|
|
46590
46760
|
var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
46591
46761
|
async function runAdminUserReconcileTick() {
|
|
46592
46762
|
try {
|
|
46593
|
-
if (!
|
|
46763
|
+
if (!existsSync64(USERS_FILE)) {
|
|
46594
46764
|
console.error("[adminuser-self-heal] skip reason=no-users-file");
|
|
46595
46765
|
return;
|
|
46596
46766
|
}
|
|
46597
|
-
const usersRaw =
|
|
46767
|
+
const usersRaw = readFileSync65(USERS_FILE, "utf-8").trim();
|
|
46598
46768
|
if (!usersRaw) {
|
|
46599
46769
|
console.error("[adminuser-self-heal] skip reason=empty-users-file");
|
|
46600
46770
|
return;
|
|
@@ -46676,8 +46846,8 @@ var runIngestAuditTick = () => {
|
|
|
46676
46846
|
},
|
|
46677
46847
|
agentExists: (accountId, slug) => {
|
|
46678
46848
|
if (!house) return false;
|
|
46679
|
-
const dir = isHouseAccountKey(house.accountId, accountId) ? house.accountDir :
|
|
46680
|
-
return
|
|
46849
|
+
const dir = isHouseAccountKey(house.accountId, accountId) ? house.accountDir : join79(ACCOUNTS_DIR, accountId);
|
|
46850
|
+
return existsSync64(join79(dir, "agents", slug, "config.json"));
|
|
46681
46851
|
}
|
|
46682
46852
|
});
|
|
46683
46853
|
} catch (err) {
|
|
@@ -46725,9 +46895,9 @@ registerLoop({
|
|
|
46725
46895
|
runPublicAddressCollisionAudit({
|
|
46726
46896
|
houseAccountId: () => resolveAccount()?.accountId ?? null,
|
|
46727
46897
|
activeSlugs: () => listValidAccounts().map((a) => {
|
|
46728
|
-
const agentsRoot =
|
|
46729
|
-
if (!
|
|
46730
|
-
const slugs =
|
|
46898
|
+
const agentsRoot = join79(a.accountDir, "agents");
|
|
46899
|
+
if (!existsSync64(agentsRoot)) return { accountId: a.accountId, slugs: [] };
|
|
46900
|
+
const slugs = readdirSync39(agentsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((slug) => isActiveAgentSlug(a.accountDir, slug));
|
|
46731
46901
|
return { accountId: a.accountId, slugs };
|
|
46732
46902
|
})
|
|
46733
46903
|
});
|
|
@@ -46740,8 +46910,8 @@ registerLoop({
|
|
|
46740
46910
|
});
|
|
46741
46911
|
var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
46742
46912
|
function countUsersRows() {
|
|
46743
|
-
if (!
|
|
46744
|
-
const raw =
|
|
46913
|
+
if (!existsSync64(USERS_FILE)) return 0;
|
|
46914
|
+
const raw = readFileSync65(USERS_FILE, "utf-8").trim();
|
|
46745
46915
|
if (!raw) return 0;
|
|
46746
46916
|
const users = JSON.parse(raw);
|
|
46747
46917
|
return users.filter((u) => typeof u.userId === "string").length;
|
|
@@ -46772,6 +46942,7 @@ registerLoop({
|
|
|
46772
46942
|
});
|
|
46773
46943
|
startGraphHealthTimer();
|
|
46774
46944
|
startSharedFolderCensus();
|
|
46945
|
+
startBrowserOrphanCensus();
|
|
46775
46946
|
startAccountsStateCensus();
|
|
46776
46947
|
startCredRefreshCensus();
|
|
46777
46948
|
void migrateUploads().catch((err) => console.error(`[uploads-migrate] failed err="${err instanceof Error ? err.message : String(err)}"`)).finally(() => {
|
|
@@ -46844,16 +47015,16 @@ function sessionChannelResolver() {
|
|
|
46844
47015
|
byId = /* @__PURE__ */ new Map();
|
|
46845
47016
|
const cfg = claudeConfigDir();
|
|
46846
47017
|
if (cfg) {
|
|
46847
|
-
for (const { path } of enumerateSessionSidecars(
|
|
47018
|
+
for (const { path } of enumerateSessionSidecars(join79(cfg, "projects"))) {
|
|
46848
47019
|
const channel = readSidecarMeta(path).channel;
|
|
46849
|
-
if (channel) byId.set(
|
|
47020
|
+
if (channel) byId.set(basename20(path).replace(/\.meta\.json$/, ""), channel);
|
|
46850
47021
|
}
|
|
46851
47022
|
}
|
|
46852
47023
|
}
|
|
46853
47024
|
return byId.get(sessionId) ?? null;
|
|
46854
47025
|
};
|
|
46855
47026
|
}
|
|
46856
|
-
var configDirForWhatsApp =
|
|
47027
|
+
var configDirForWhatsApp = basename20(MAXY_DIR) || ".maxy";
|
|
46857
47028
|
var bootAccount = resolveAccount();
|
|
46858
47029
|
if (bootAccount) {
|
|
46859
47030
|
migrateRemovedConfigKeys(bootAccount.accountDir);
|
|
@@ -46919,7 +47090,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
46919
47090
|
}
|
|
46920
47091
|
init({
|
|
46921
47092
|
configDir: configDirForWhatsApp,
|
|
46922
|
-
platformRoot:
|
|
47093
|
+
platformRoot: resolve56(process.env.MAXY_PLATFORM_ROOT ?? join79(__dirname, "..")),
|
|
46923
47094
|
accountConfig: bootAccountConfig,
|
|
46924
47095
|
// Task 2074 — enrich with the sub-account name and fan out to every open
|
|
46925
47096
|
// admin SSE stream. Fire-and-forget: the manager's persist path must not
|