@rubytech/create-maxy-code 0.1.0 → 0.1.1
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/server/server.js +211 -74
package/package.json
CHANGED
package/payload/server/server.js
CHANGED
|
@@ -644,8 +644,8 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
644
644
|
};
|
|
645
645
|
|
|
646
646
|
// server/index.ts
|
|
647
|
-
import { readFileSync as
|
|
648
|
-
import { resolve as
|
|
647
|
+
import { readFileSync as readFileSync23, existsSync as existsSync26, watchFile } from "fs";
|
|
648
|
+
import { resolve as resolve26, join as join14, basename as basename5 } from "path";
|
|
649
649
|
import { homedir as homedir5 } from "os";
|
|
650
650
|
|
|
651
651
|
// app/lib/agent-slug-pattern.ts
|
|
@@ -1627,7 +1627,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
1627
1627
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
1628
1628
|
console.error(`${TAG3} draining credential save queue\u2026`);
|
|
1629
1629
|
const timer2 = new Promise(
|
|
1630
|
-
(
|
|
1630
|
+
(resolve27) => setTimeout(() => resolve27("timeout"), timeoutMs)
|
|
1631
1631
|
);
|
|
1632
1632
|
const result = await Promise.race([
|
|
1633
1633
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -1755,11 +1755,11 @@ async function createWaSocket(opts) {
|
|
|
1755
1755
|
return sock;
|
|
1756
1756
|
}
|
|
1757
1757
|
async function waitForConnection(sock) {
|
|
1758
|
-
return new Promise((
|
|
1758
|
+
return new Promise((resolve27, reject) => {
|
|
1759
1759
|
const handler = (update) => {
|
|
1760
1760
|
if (update.connection === "open") {
|
|
1761
1761
|
sock.ev.off("connection.update", handler);
|
|
1762
|
-
|
|
1762
|
+
resolve27();
|
|
1763
1763
|
}
|
|
1764
1764
|
if (update.connection === "close") {
|
|
1765
1765
|
sock.ev.off("connection.update", handler);
|
|
@@ -1873,14 +1873,14 @@ ${inspected}`;
|
|
|
1873
1873
|
return inspect2(err, INSPECT_OPTS2);
|
|
1874
1874
|
}
|
|
1875
1875
|
function withTimeout(label, promise, timeoutMs) {
|
|
1876
|
-
return new Promise((
|
|
1876
|
+
return new Promise((resolve27, reject) => {
|
|
1877
1877
|
const timer2 = setTimeout(() => {
|
|
1878
1878
|
reject(new Error(`${label} timed out after ${timeoutMs}ms`));
|
|
1879
1879
|
}, timeoutMs);
|
|
1880
1880
|
promise.then(
|
|
1881
1881
|
(value) => {
|
|
1882
1882
|
clearTimeout(timer2);
|
|
1883
|
-
|
|
1883
|
+
resolve27(value);
|
|
1884
1884
|
},
|
|
1885
1885
|
(err) => {
|
|
1886
1886
|
clearTimeout(timer2);
|
|
@@ -2415,8 +2415,8 @@ async function persistWhatsAppMessage(input) {
|
|
|
2415
2415
|
const { givenName, familyName } = splitName(input.pushName);
|
|
2416
2416
|
const prev = sessionWriteLocks.get(input.cacheKey);
|
|
2417
2417
|
let release;
|
|
2418
|
-
const mine = new Promise((
|
|
2419
|
-
release =
|
|
2418
|
+
const mine = new Promise((resolve27) => {
|
|
2419
|
+
release = resolve27;
|
|
2420
2420
|
});
|
|
2421
2421
|
const chained = (prev ?? Promise.resolve()).then(() => mine);
|
|
2422
2422
|
sessionWriteLocks.set(input.cacheKey, chained);
|
|
@@ -3458,11 +3458,11 @@ async function connectWithReconnect(conn) {
|
|
|
3458
3458
|
console.error(
|
|
3459
3459
|
`${TAG13} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
3460
3460
|
);
|
|
3461
|
-
await new Promise((
|
|
3462
|
-
const timer2 = setTimeout(
|
|
3461
|
+
await new Promise((resolve27) => {
|
|
3462
|
+
const timer2 = setTimeout(resolve27, delay);
|
|
3463
3463
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
3464
3464
|
clearTimeout(timer2);
|
|
3465
|
-
|
|
3465
|
+
resolve27();
|
|
3466
3466
|
}, { once: true });
|
|
3467
3467
|
});
|
|
3468
3468
|
}
|
|
@@ -3470,16 +3470,16 @@ async function connectWithReconnect(conn) {
|
|
|
3470
3470
|
}
|
|
3471
3471
|
}
|
|
3472
3472
|
function waitForDisconnectEvent(conn) {
|
|
3473
|
-
return new Promise((
|
|
3473
|
+
return new Promise((resolve27) => {
|
|
3474
3474
|
if (!conn.sock) {
|
|
3475
|
-
|
|
3475
|
+
resolve27();
|
|
3476
3476
|
return;
|
|
3477
3477
|
}
|
|
3478
3478
|
const sock = conn.sock;
|
|
3479
3479
|
const handler = (update) => {
|
|
3480
3480
|
if (update.connection === "close") {
|
|
3481
3481
|
sock.ev.off("connection.update", handler);
|
|
3482
|
-
|
|
3482
|
+
resolve27();
|
|
3483
3483
|
}
|
|
3484
3484
|
};
|
|
3485
3485
|
sock.ev.on("connection.update", handler);
|
|
@@ -3741,8 +3741,8 @@ async function handleInboundMessage(conn, msg) {
|
|
|
3741
3741
|
const conversationKey = isGroup ? remoteJid : senderPhone;
|
|
3742
3742
|
const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
|
|
3743
3743
|
let resolvePending;
|
|
3744
|
-
const sttPending = new Promise((
|
|
3745
|
-
resolvePending =
|
|
3744
|
+
const sttPending = new Promise((resolve27) => {
|
|
3745
|
+
resolvePending = resolve27;
|
|
3746
3746
|
});
|
|
3747
3747
|
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
|
|
3748
3748
|
try {
|
|
@@ -4159,20 +4159,20 @@ async function probeApiKey() {
|
|
|
4159
4159
|
return result.status;
|
|
4160
4160
|
}
|
|
4161
4161
|
function checkPort(port2, timeoutMs = 500) {
|
|
4162
|
-
return new Promise((
|
|
4162
|
+
return new Promise((resolve27) => {
|
|
4163
4163
|
const socket = createConnection2(port2, "127.0.0.1");
|
|
4164
4164
|
socket.setTimeout(timeoutMs);
|
|
4165
4165
|
socket.once("connect", () => {
|
|
4166
4166
|
socket.destroy();
|
|
4167
|
-
|
|
4167
|
+
resolve27(true);
|
|
4168
4168
|
});
|
|
4169
4169
|
socket.once("error", () => {
|
|
4170
4170
|
socket.destroy();
|
|
4171
|
-
|
|
4171
|
+
resolve27(false);
|
|
4172
4172
|
});
|
|
4173
4173
|
socket.once("timeout", () => {
|
|
4174
4174
|
socket.destroy();
|
|
4175
|
-
|
|
4175
|
+
resolve27(false);
|
|
4176
4176
|
});
|
|
4177
4177
|
});
|
|
4178
4178
|
}
|
|
@@ -6699,8 +6699,8 @@ async function startLogin(opts) {
|
|
|
6699
6699
|
resetActiveLogin(accountId);
|
|
6700
6700
|
let resolveQr = null;
|
|
6701
6701
|
let rejectQr = null;
|
|
6702
|
-
const qrPromise = new Promise((
|
|
6703
|
-
resolveQr =
|
|
6702
|
+
const qrPromise = new Promise((resolve27, reject) => {
|
|
6703
|
+
resolveQr = resolve27;
|
|
6704
6704
|
rejectQr = reject;
|
|
6705
6705
|
});
|
|
6706
6706
|
const qrTimer = setTimeout(
|
|
@@ -10338,8 +10338,8 @@ app27.get("/tunnels", requireAdminSession, async (c) => {
|
|
|
10338
10338
|
if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
|
|
10339
10339
|
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
10340
10340
|
const certPath = resolve16(homedir4(), brand.configDir, "cloudflared", "cert.pem");
|
|
10341
|
-
const { existsSync:
|
|
10342
|
-
if (!
|
|
10341
|
+
const { existsSync: existsSync27 } = await import("fs");
|
|
10342
|
+
if (!existsSync27(certPath)) {
|
|
10343
10343
|
return err("cert", `Cloudflare origin certificate is not on disk yet (${certPath}). Complete the Cloudflare login first by submitting the form once \u2014 the OAuth flow writes cert.pem.`);
|
|
10344
10344
|
}
|
|
10345
10345
|
const result = await runFormSpawn({
|
|
@@ -13695,14 +13695,151 @@ function startGraphHealthTimer() {
|
|
|
13695
13695
|
}
|
|
13696
13696
|
|
|
13697
13697
|
// app/lib/claude-agent/plugin-manifest.ts
|
|
13698
|
-
|
|
13699
|
-
|
|
13700
|
-
|
|
13698
|
+
import { resolve as resolve24, join as join13 } from "path";
|
|
13699
|
+
import {
|
|
13700
|
+
readFileSync as readFileSync21,
|
|
13701
|
+
writeFileSync as writeFileSync12,
|
|
13702
|
+
readdirSync as readdirSync7,
|
|
13703
|
+
existsSync as existsSync24,
|
|
13704
|
+
statSync as statSync8,
|
|
13705
|
+
cpSync
|
|
13706
|
+
} from "fs";
|
|
13707
|
+
function readBundleSubPlugins(bundlePath) {
|
|
13708
|
+
if (!existsSync24(bundlePath)) return [];
|
|
13709
|
+
let raw;
|
|
13710
|
+
try {
|
|
13711
|
+
raw = readFileSync21(bundlePath, "utf-8");
|
|
13712
|
+
} catch {
|
|
13713
|
+
return [];
|
|
13714
|
+
}
|
|
13715
|
+
const fm = raw.match(/^---\n([\s\S]*?)\n---/);
|
|
13716
|
+
if (!fm) return [];
|
|
13717
|
+
const subs = [];
|
|
13718
|
+
let inPlugins = false;
|
|
13719
|
+
for (const line of fm[1].split("\n")) {
|
|
13720
|
+
if (/^plugins:/.test(line)) {
|
|
13721
|
+
inPlugins = true;
|
|
13722
|
+
continue;
|
|
13723
|
+
}
|
|
13724
|
+
if (inPlugins) {
|
|
13725
|
+
const m = line.match(/^\s+- (.+)/);
|
|
13726
|
+
if (m) subs.push(m[1].trim());
|
|
13727
|
+
else break;
|
|
13728
|
+
}
|
|
13729
|
+
}
|
|
13730
|
+
return subs;
|
|
13731
|
+
}
|
|
13732
|
+
function walkPremiumBundles() {
|
|
13733
|
+
if (BRAND_NAME === "maxy") return [];
|
|
13734
|
+
const stagingRoot = resolve24(PLATFORM_ROOT, "../premium-plugins");
|
|
13735
|
+
if (!existsSync24(stagingRoot)) return [];
|
|
13736
|
+
let entries;
|
|
13737
|
+
try {
|
|
13738
|
+
entries = readdirSync7(stagingRoot);
|
|
13739
|
+
} catch {
|
|
13740
|
+
return [];
|
|
13741
|
+
}
|
|
13742
|
+
const result = [];
|
|
13743
|
+
for (const bundle of entries) {
|
|
13744
|
+
const bundleDir = resolve24(stagingRoot, bundle);
|
|
13745
|
+
try {
|
|
13746
|
+
if (!statSync8(bundleDir).isDirectory()) continue;
|
|
13747
|
+
} catch {
|
|
13748
|
+
continue;
|
|
13749
|
+
}
|
|
13750
|
+
const declared = readBundleSubPlugins(join13(bundleDir, "BUNDLE.md"));
|
|
13751
|
+
result.push({ bundle, subs: declared.length > 0 ? declared : [bundle] });
|
|
13752
|
+
}
|
|
13753
|
+
return result;
|
|
13754
|
+
}
|
|
13755
|
+
function autoDeliverPremiumPlugins() {
|
|
13756
|
+
const TAG20 = "[premium-auto-deliver]";
|
|
13757
|
+
const bundles = walkPremiumBundles();
|
|
13758
|
+
if (bundles.length === 0) return;
|
|
13759
|
+
const stagingRoot = resolve24(PLATFORM_ROOT, "../premium-plugins");
|
|
13760
|
+
const pluginsDir = resolve24(PLATFORM_ROOT, "plugins");
|
|
13761
|
+
for (const { bundle, subs } of bundles) {
|
|
13762
|
+
const stagingDir = resolve24(stagingRoot, bundle);
|
|
13763
|
+
const bundlePath = join13(stagingDir, "BUNDLE.md");
|
|
13764
|
+
const isBundle = existsSync24(bundlePath);
|
|
13765
|
+
if (isBundle) {
|
|
13766
|
+
let delivered = 0;
|
|
13767
|
+
let skipped = 0;
|
|
13768
|
+
for (const sub of subs) {
|
|
13769
|
+
const target = resolve24(pluginsDir, sub);
|
|
13770
|
+
if (existsSync24(resolve24(target, "PLUGIN.md"))) {
|
|
13771
|
+
skipped++;
|
|
13772
|
+
continue;
|
|
13773
|
+
}
|
|
13774
|
+
const source = resolve24(stagingDir, "plugins", sub);
|
|
13775
|
+
if (!existsSync24(source)) {
|
|
13776
|
+
console.log(`${TAG20} ${bundle}/${sub}: source missing in staging, skipping`);
|
|
13777
|
+
continue;
|
|
13778
|
+
}
|
|
13779
|
+
try {
|
|
13780
|
+
cpSync(source, target, { recursive: true });
|
|
13781
|
+
delivered++;
|
|
13782
|
+
} catch (err) {
|
|
13783
|
+
console.log(`${TAG20} ${bundle}/${sub}: copy failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13784
|
+
}
|
|
13785
|
+
}
|
|
13786
|
+
console.log(`${TAG20} ${bundle} (bundle): ${delivered} delivered, ${skipped} already present`);
|
|
13787
|
+
} else {
|
|
13788
|
+
const target = resolve24(pluginsDir, bundle);
|
|
13789
|
+
if (existsSync24(resolve24(target, "PLUGIN.md"))) {
|
|
13790
|
+
console.log(`${TAG20} ${bundle}: already present, skipping`);
|
|
13791
|
+
} else {
|
|
13792
|
+
try {
|
|
13793
|
+
cpSync(stagingDir, target, { recursive: true });
|
|
13794
|
+
console.log(`${TAG20} ${bundle} (standalone): delivered`);
|
|
13795
|
+
} catch (err) {
|
|
13796
|
+
console.log(`${TAG20} ${bundle}: copy failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13797
|
+
}
|
|
13798
|
+
}
|
|
13799
|
+
}
|
|
13800
|
+
}
|
|
13801
|
+
}
|
|
13802
|
+
function reconcileEnabledPlugins(accountDir, config) {
|
|
13803
|
+
const TAG20 = "[premium-auto-deliver]";
|
|
13804
|
+
if (!accountDir || !config) return;
|
|
13805
|
+
const bundles = walkPremiumBundles();
|
|
13806
|
+
const pluginsDir = resolve24(PLATFORM_ROOT, "plugins");
|
|
13807
|
+
const bundleNames = [];
|
|
13808
|
+
const allSubs = [];
|
|
13809
|
+
for (const { bundle, subs } of bundles) {
|
|
13810
|
+
bundleNames.push(bundle);
|
|
13811
|
+
for (const sub of subs) {
|
|
13812
|
+
if (!existsSync24(resolve24(pluginsDir, sub, "PLUGIN.md"))) continue;
|
|
13813
|
+
allSubs.push(sub);
|
|
13814
|
+
}
|
|
13815
|
+
}
|
|
13816
|
+
const current = Array.isArray(config.enabledPlugins) ? config.enabledPlugins : [];
|
|
13817
|
+
const currentSet = new Set(current);
|
|
13818
|
+
const added = [];
|
|
13819
|
+
for (const sub of allSubs) {
|
|
13820
|
+
if (currentSet.has(sub)) continue;
|
|
13821
|
+
currentSet.add(sub);
|
|
13822
|
+
added.push(sub);
|
|
13823
|
+
}
|
|
13824
|
+
console.log(`${TAG20} brand=${BRAND_NAME} bundles=[${bundleNames.join(",")}] subs=[${allSubs.join(",")}] stamped=${added.length}`);
|
|
13825
|
+
if (added.length === 0) return;
|
|
13826
|
+
const merged = [...currentSet];
|
|
13827
|
+
const configPath2 = resolve24(accountDir, "account.json");
|
|
13828
|
+
try {
|
|
13829
|
+
const raw = readFileSync21(configPath2, "utf-8");
|
|
13830
|
+
const parsed = JSON.parse(raw);
|
|
13831
|
+
parsed.enabledPlugins = merged;
|
|
13832
|
+
writeFileSync12(configPath2, JSON.stringify(parsed, null, 2) + "\n");
|
|
13833
|
+
config.enabledPlugins = merged;
|
|
13834
|
+
} catch (err) {
|
|
13835
|
+
console.error(`${TAG20} enabled-stamp write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13836
|
+
}
|
|
13837
|
+
}
|
|
13701
13838
|
|
|
13702
13839
|
// ../lib/entitlement/src/index.ts
|
|
13703
13840
|
import { createPublicKey, createHash as createHash3, verify as cryptoVerify } from "crypto";
|
|
13704
|
-
import { existsSync as
|
|
13705
|
-
import { resolve as
|
|
13841
|
+
import { existsSync as existsSync25, readFileSync as readFileSync22, statSync as statSync9 } from "fs";
|
|
13842
|
+
import { resolve as resolve25 } from "path";
|
|
13706
13843
|
|
|
13707
13844
|
// ../lib/entitlement/src/canonicalize.ts
|
|
13708
13845
|
function canonicalize(value) {
|
|
@@ -13737,7 +13874,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
|
|
|
13737
13874
|
var GRACE_DAYS = 7;
|
|
13738
13875
|
var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
|
|
13739
13876
|
function pubkeyPath(brand) {
|
|
13740
|
-
return
|
|
13877
|
+
return resolve25(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
|
|
13741
13878
|
}
|
|
13742
13879
|
var memo = null;
|
|
13743
13880
|
function memoKey(mtimeMs, account) {
|
|
@@ -13749,11 +13886,11 @@ function resolveEntitlement(brand, account) {
|
|
|
13749
13886
|
if (brand.commercialMode !== true) {
|
|
13750
13887
|
return logResolved(implicitTrust(account), null);
|
|
13751
13888
|
}
|
|
13752
|
-
const entitlementPath =
|
|
13753
|
-
if (!
|
|
13889
|
+
const entitlementPath = resolve25(brand.configDir, "entitlement.json");
|
|
13890
|
+
if (!existsSync25(entitlementPath)) {
|
|
13754
13891
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
13755
13892
|
}
|
|
13756
|
-
const stat7 =
|
|
13893
|
+
const stat7 = statSync9(entitlementPath);
|
|
13757
13894
|
const key = memoKey(stat7.mtimeMs, account);
|
|
13758
13895
|
if (memo && memo.key === key) {
|
|
13759
13896
|
return memo.result;
|
|
@@ -13765,7 +13902,7 @@ function resolveEntitlement(brand, account) {
|
|
|
13765
13902
|
function verifyAndResolve(brand, entitlementPath, account) {
|
|
13766
13903
|
let pubkeyPem;
|
|
13767
13904
|
try {
|
|
13768
|
-
pubkeyPem =
|
|
13905
|
+
pubkeyPem = readFileSync22(pubkeyPath(brand), "utf-8");
|
|
13769
13906
|
} catch (err) {
|
|
13770
13907
|
return logResolved(anonymousFallback("pubkey-missing"), {
|
|
13771
13908
|
reason: "pubkey-missing"
|
|
@@ -13779,7 +13916,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
|
|
|
13779
13916
|
}
|
|
13780
13917
|
let envelope;
|
|
13781
13918
|
try {
|
|
13782
|
-
envelope = JSON.parse(
|
|
13919
|
+
envelope = JSON.parse(readFileSync22(entitlementPath, "utf-8"));
|
|
13783
13920
|
} catch {
|
|
13784
13921
|
return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
|
|
13785
13922
|
}
|
|
@@ -13940,14 +14077,14 @@ function clientFrom(c) {
|
|
|
13940
14077
|
);
|
|
13941
14078
|
}
|
|
13942
14079
|
var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
13943
|
-
var BRAND_JSON_PATH = PLATFORM_ROOT9 ?
|
|
14080
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join14(PLATFORM_ROOT9, "config", "brand.json") : "";
|
|
13944
14081
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
|
|
13945
|
-
if (BRAND_JSON_PATH && !
|
|
14082
|
+
if (BRAND_JSON_PATH && !existsSync26(BRAND_JSON_PATH)) {
|
|
13946
14083
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
13947
14084
|
}
|
|
13948
|
-
if (BRAND_JSON_PATH &&
|
|
14085
|
+
if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
|
|
13949
14086
|
try {
|
|
13950
|
-
const parsed = JSON.parse(
|
|
14087
|
+
const parsed = JSON.parse(readFileSync23(BRAND_JSON_PATH, "utf-8"));
|
|
13951
14088
|
BRAND = { ...BRAND, ...parsed };
|
|
13952
14089
|
} catch (err) {
|
|
13953
14090
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -13966,11 +14103,11 @@ var brandLoginOpts = {
|
|
|
13966
14103
|
bodyFont: BRAND.defaultFonts?.body,
|
|
13967
14104
|
logoContainsName: !!BRAND.logoContainsName
|
|
13968
14105
|
};
|
|
13969
|
-
var ALIAS_DOMAINS_PATH2 =
|
|
14106
|
+
var ALIAS_DOMAINS_PATH2 = join14(homedir5(), BRAND.configDir, "alias-domains.json");
|
|
13970
14107
|
function loadAliasDomains() {
|
|
13971
14108
|
try {
|
|
13972
|
-
if (!
|
|
13973
|
-
const parsed = JSON.parse(
|
|
14109
|
+
if (!existsSync26(ALIAS_DOMAINS_PATH2)) return null;
|
|
14110
|
+
const parsed = JSON.parse(readFileSync23(ALIAS_DOMAINS_PATH2, "utf-8"));
|
|
13974
14111
|
if (!Array.isArray(parsed)) {
|
|
13975
14112
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
13976
14113
|
return null;
|
|
@@ -14344,20 +14481,20 @@ app42.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
14344
14481
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
14345
14482
|
return c.text("Not found", 404);
|
|
14346
14483
|
}
|
|
14347
|
-
const filePath =
|
|
14348
|
-
const expectedDir =
|
|
14484
|
+
const filePath = resolve26(account.accountDir, "agents", slug, "assets", filename);
|
|
14485
|
+
const expectedDir = resolve26(account.accountDir, "agents", slug, "assets");
|
|
14349
14486
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
14350
14487
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
14351
14488
|
return c.text("Forbidden", 403);
|
|
14352
14489
|
}
|
|
14353
|
-
if (!
|
|
14490
|
+
if (!existsSync26(filePath)) {
|
|
14354
14491
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
14355
14492
|
return c.text("Not found", 404);
|
|
14356
14493
|
}
|
|
14357
14494
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
14358
14495
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
14359
14496
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
14360
|
-
const body =
|
|
14497
|
+
const body = readFileSync23(filePath);
|
|
14361
14498
|
return c.body(body, 200, {
|
|
14362
14499
|
"Content-Type": contentType,
|
|
14363
14500
|
"Cache-Control": "public, max-age=3600"
|
|
@@ -14374,20 +14511,20 @@ app42.get("/generated/:filename", (c) => {
|
|
|
14374
14511
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
14375
14512
|
return c.text("Not found", 404);
|
|
14376
14513
|
}
|
|
14377
|
-
const filePath =
|
|
14378
|
-
const expectedDir =
|
|
14514
|
+
const filePath = resolve26(account.accountDir, "generated", filename);
|
|
14515
|
+
const expectedDir = resolve26(account.accountDir, "generated");
|
|
14379
14516
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
14380
14517
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
14381
14518
|
return c.text("Forbidden", 403);
|
|
14382
14519
|
}
|
|
14383
|
-
if (!
|
|
14520
|
+
if (!existsSync26(filePath)) {
|
|
14384
14521
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
14385
14522
|
return c.text("Not found", 404);
|
|
14386
14523
|
}
|
|
14387
14524
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
14388
14525
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
14389
14526
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
14390
|
-
const body =
|
|
14527
|
+
const body = readFileSync23(filePath);
|
|
14391
14528
|
return c.body(body, 200, {
|
|
14392
14529
|
"Content-Type": contentType,
|
|
14393
14530
|
"Cache-Control": "public, max-age=86400"
|
|
@@ -14397,9 +14534,9 @@ app42.route("/sites", sites_default);
|
|
|
14397
14534
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
14398
14535
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
14399
14536
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
14400
|
-
if (BRAND_JSON_PATH &&
|
|
14537
|
+
if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
|
|
14401
14538
|
try {
|
|
14402
|
-
const fullBrand = JSON.parse(
|
|
14539
|
+
const fullBrand = JSON.parse(readFileSync23(BRAND_JSON_PATH, "utf-8"));
|
|
14403
14540
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
14404
14541
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
14405
14542
|
} catch {
|
|
@@ -14416,9 +14553,9 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
14416
14553
|
function readInstalledVersion() {
|
|
14417
14554
|
try {
|
|
14418
14555
|
if (!PLATFORM_ROOT9) return "unknown";
|
|
14419
|
-
const versionFile =
|
|
14420
|
-
if (!
|
|
14421
|
-
const content =
|
|
14556
|
+
const versionFile = join14(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
|
|
14557
|
+
if (!existsSync26(versionFile)) return "unknown";
|
|
14558
|
+
const content = readFileSync23(versionFile, "utf-8").trim();
|
|
14422
14559
|
return content || "unknown";
|
|
14423
14560
|
} catch {
|
|
14424
14561
|
return "unknown";
|
|
@@ -14459,7 +14596,7 @@ var clientErrorReporterScript = `<script>
|
|
|
14459
14596
|
function cachedHtml(file) {
|
|
14460
14597
|
let html = htmlCache.get(file);
|
|
14461
14598
|
if (!html) {
|
|
14462
|
-
html =
|
|
14599
|
+
html = readFileSync23(resolve26(process.cwd(), "public", file), "utf-8");
|
|
14463
14600
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
14464
14601
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
14465
14602
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -14475,26 +14612,26 @@ ${clientErrorReporterScript}
|
|
|
14475
14612
|
}
|
|
14476
14613
|
var brandedHtmlCache = /* @__PURE__ */ new Map();
|
|
14477
14614
|
function loadBrandingCache(agentSlug) {
|
|
14478
|
-
const configDir2 =
|
|
14615
|
+
const configDir2 = join14(homedir5(), BRAND.configDir);
|
|
14479
14616
|
try {
|
|
14480
|
-
const accountJsonPath =
|
|
14481
|
-
if (!
|
|
14482
|
-
const account = JSON.parse(
|
|
14617
|
+
const accountJsonPath = join14(configDir2, "account.json");
|
|
14618
|
+
if (!existsSync26(accountJsonPath)) return null;
|
|
14619
|
+
const account = JSON.parse(readFileSync23(accountJsonPath, "utf-8"));
|
|
14483
14620
|
const accountId = account.accountId;
|
|
14484
14621
|
if (!accountId) return null;
|
|
14485
|
-
const cachePath =
|
|
14486
|
-
if (!
|
|
14487
|
-
return JSON.parse(
|
|
14622
|
+
const cachePath = join14(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
14623
|
+
if (!existsSync26(cachePath)) return null;
|
|
14624
|
+
return JSON.parse(readFileSync23(cachePath, "utf-8"));
|
|
14488
14625
|
} catch {
|
|
14489
14626
|
return null;
|
|
14490
14627
|
}
|
|
14491
14628
|
}
|
|
14492
14629
|
function resolveDefaultSlug() {
|
|
14493
14630
|
try {
|
|
14494
|
-
const configDir2 =
|
|
14495
|
-
const accountJsonPath =
|
|
14496
|
-
if (!
|
|
14497
|
-
const account = JSON.parse(
|
|
14631
|
+
const configDir2 = join14(homedir5(), BRAND.configDir);
|
|
14632
|
+
const accountJsonPath = join14(configDir2, "account.json");
|
|
14633
|
+
if (!existsSync26(accountJsonPath)) return null;
|
|
14634
|
+
const account = JSON.parse(readFileSync23(accountJsonPath, "utf-8"));
|
|
14498
14635
|
return account.defaultAgent || null;
|
|
14499
14636
|
} catch {
|
|
14500
14637
|
return null;
|
|
@@ -14567,7 +14704,7 @@ app42.use("/vnc-popout.html", logViewerFetch);
|
|
|
14567
14704
|
app42.get("/vnc-popout.html", (c) => {
|
|
14568
14705
|
let html = htmlCache.get("vnc-popout.html");
|
|
14569
14706
|
if (!html) {
|
|
14570
|
-
html =
|
|
14707
|
+
html = readFileSync23(resolve26(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
14571
14708
|
const name = escapeHtml(BRAND.productName);
|
|
14572
14709
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
14573
14710
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -14673,8 +14810,8 @@ try {
|
|
|
14673
14810
|
(async () => {
|
|
14674
14811
|
try {
|
|
14675
14812
|
let userId = "";
|
|
14676
|
-
if (
|
|
14677
|
-
const users = JSON.parse(
|
|
14813
|
+
if (existsSync26(USERS_FILE)) {
|
|
14814
|
+
const users = JSON.parse(readFileSync23(USERS_FILE, "utf-8").trim() || "[]");
|
|
14678
14815
|
userId = users[0]?.userId ?? "";
|
|
14679
14816
|
}
|
|
14680
14817
|
await backfillNullUserIdConversations(userId);
|
|
@@ -14691,8 +14828,8 @@ try {
|
|
|
14691
14828
|
})();
|
|
14692
14829
|
(async () => {
|
|
14693
14830
|
try {
|
|
14694
|
-
if (!
|
|
14695
|
-
const usersRaw =
|
|
14831
|
+
if (!existsSync26(USERS_FILE)) return;
|
|
14832
|
+
const usersRaw = readFileSync23(USERS_FILE, "utf-8").trim();
|
|
14696
14833
|
if (!usersRaw) return;
|
|
14697
14834
|
const users = JSON.parse(usersRaw);
|
|
14698
14835
|
const userId = users[0]?.userId;
|
|
@@ -14818,7 +14955,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
14818
14955
|
}
|
|
14819
14956
|
init({
|
|
14820
14957
|
configDir: configDirForWhatsApp,
|
|
14821
|
-
platformRoot:
|
|
14958
|
+
platformRoot: resolve26(process.env.MAXY_PLATFORM_ROOT ?? join14(__dirname, "..")),
|
|
14822
14959
|
accountConfig: bootAccountConfig,
|
|
14823
14960
|
onMessage: async (msg) => {
|
|
14824
14961
|
try {
|