@agenticmail/core 0.9.5 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +270 -188
- package/dist/index.d.cts +124 -1
- package/dist/index.d.ts +124 -1
- package/dist/index.js +254 -178
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -716,6 +716,7 @@ __export(index_exports, {
|
|
|
716
716
|
CloudflareClient: () => CloudflareClient,
|
|
717
717
|
DEFAULT_AGENT_NAME: () => DEFAULT_AGENT_NAME,
|
|
718
718
|
DEFAULT_AGENT_ROLE: () => DEFAULT_AGENT_ROLE,
|
|
719
|
+
DEFAULT_SESSION_MAX_AGE_MS: () => DEFAULT_SESSION_MAX_AGE_MS,
|
|
719
720
|
DNSConfigurator: () => DNSConfigurator,
|
|
720
721
|
DependencyChecker: () => DependencyChecker,
|
|
721
722
|
DependencyInstaller: () => DependencyInstaller,
|
|
@@ -752,9 +753,13 @@ __export(index_exports, {
|
|
|
752
753
|
ensureDataDir: () => ensureDataDir,
|
|
753
754
|
extractVerificationCode: () => extractVerificationCode,
|
|
754
755
|
flushTelemetry: () => flushTelemetry,
|
|
756
|
+
forgetHostSession: () => forgetHostSession,
|
|
755
757
|
getDatabase: () => getDatabase,
|
|
758
|
+
hostSessionStoragePath: () => hostSessionStoragePath,
|
|
756
759
|
isInternalEmail: () => isInternalEmail,
|
|
760
|
+
isSessionFresh: () => isSessionFresh,
|
|
757
761
|
isValidPhoneNumber: () => isValidPhoneNumber,
|
|
762
|
+
loadHostSession: () => loadHostSession,
|
|
758
763
|
normalizeAddress: () => normalizeAddress,
|
|
759
764
|
normalizePhoneNumber: () => normalizePhoneNumber,
|
|
760
765
|
normalizeSubject: () => normalizeSubject,
|
|
@@ -767,6 +772,7 @@ __export(index_exports, {
|
|
|
767
772
|
safeJoin: () => safeJoin,
|
|
768
773
|
sanitizeEmail: () => sanitizeEmail,
|
|
769
774
|
saveConfig: () => saveConfig,
|
|
775
|
+
saveHostSession: () => saveHostSession,
|
|
770
776
|
scanOutboundEmail: () => scanOutboundEmail,
|
|
771
777
|
scoreEmail: () => scoreEmail,
|
|
772
778
|
setTelemetryVersion: () => setTelemetryVersion,
|
|
@@ -1862,14 +1868,14 @@ var StalwartAdmin = class {
|
|
|
1862
1868
|
if (!isValidDomain(domain)) {
|
|
1863
1869
|
throw new Error(`Invalid domain format: "${domain}"`);
|
|
1864
1870
|
}
|
|
1865
|
-
const { readFileSync:
|
|
1866
|
-
const { homedir:
|
|
1867
|
-
const { join:
|
|
1868
|
-
const configPath =
|
|
1871
|
+
const { readFileSync: readFileSync8, writeFileSync: writeFileSync9 } = await import("fs");
|
|
1872
|
+
const { homedir: homedir12 } = await import("os");
|
|
1873
|
+
const { join: join14 } = await import("path");
|
|
1874
|
+
const configPath = join14(homedir12(), ".agenticmail", "stalwart.toml");
|
|
1869
1875
|
try {
|
|
1870
|
-
let config =
|
|
1876
|
+
let config = readFileSync8(configPath, "utf-8");
|
|
1871
1877
|
config = config.replace(/^hostname\s*=\s*"[^"]*"/m, `hostname = "${escapeTomlString(domain)}"`);
|
|
1872
|
-
|
|
1878
|
+
writeFileSync9(configPath, config);
|
|
1873
1879
|
console.log(`[Stalwart] Updated hostname to "${domain}" in stalwart.toml`);
|
|
1874
1880
|
} catch (err) {
|
|
1875
1881
|
throw new Error(`Failed to set config server.hostname=${domain}`);
|
|
@@ -1878,15 +1884,15 @@ var StalwartAdmin = class {
|
|
|
1878
1884
|
// --- DKIM ---
|
|
1879
1885
|
/** Path to the host-side stalwart.toml (mounted read-only into container) */
|
|
1880
1886
|
get configPath() {
|
|
1881
|
-
const { homedir:
|
|
1882
|
-
const { join:
|
|
1883
|
-
return
|
|
1887
|
+
const { homedir: homedir12 } = require("os");
|
|
1888
|
+
const { join: join14 } = require("path");
|
|
1889
|
+
return join14(homedir12(), ".agenticmail", "stalwart.toml");
|
|
1884
1890
|
}
|
|
1885
1891
|
/** Path to host-side DKIM key directory */
|
|
1886
1892
|
get dkimDir() {
|
|
1887
|
-
const { homedir:
|
|
1888
|
-
const { join:
|
|
1889
|
-
return
|
|
1893
|
+
const { homedir: homedir12 } = require("os");
|
|
1894
|
+
const { join: join14 } = require("path");
|
|
1895
|
+
return join14(homedir12(), ".agenticmail");
|
|
1890
1896
|
}
|
|
1891
1897
|
/**
|
|
1892
1898
|
* Create/reuse a DKIM signing key for a domain.
|
|
@@ -1987,12 +1993,12 @@ var StalwartAdmin = class {
|
|
|
1987
1993
|
* This bypasses the need for a PTR record on the sending IP.
|
|
1988
1994
|
*/
|
|
1989
1995
|
async configureOutboundRelay(config) {
|
|
1990
|
-
const { readFileSync:
|
|
1991
|
-
const { homedir:
|
|
1992
|
-
const { join:
|
|
1996
|
+
const { readFileSync: readFileSync8, writeFileSync: writeFileSync9 } = await import("fs");
|
|
1997
|
+
const { homedir: homedir12 } = await import("os");
|
|
1998
|
+
const { join: join14 } = await import("path");
|
|
1993
1999
|
const routeName = config.routeName ?? "gmail";
|
|
1994
|
-
const tomlPath =
|
|
1995
|
-
let toml =
|
|
2000
|
+
const tomlPath = join14(homedir12(), ".agenticmail", "stalwart.toml");
|
|
2001
|
+
let toml = readFileSync8(tomlPath, "utf-8");
|
|
1996
2002
|
toml = toml.replace(/\n\[queue\.route\.gmail\][\s\S]*?(?=\n\[|$)/, "");
|
|
1997
2003
|
toml = toml.replace(/\n\[queue\.strategy\][\s\S]*?(?=\n\[|$)/, "");
|
|
1998
2004
|
const safeRouteName = routeName.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
@@ -2012,7 +2018,7 @@ auth.secret = "${escapeTomlString(config.password)}"
|
|
|
2012
2018
|
route = [ { if = "is_local_domain('', rcpt_domain)", then = "'local'" },
|
|
2013
2019
|
{ else = "'${safeRouteName}'" } ]
|
|
2014
2020
|
`;
|
|
2015
|
-
|
|
2021
|
+
writeFileSync9(tomlPath, toml, "utf-8");
|
|
2016
2022
|
await this.restartContainer();
|
|
2017
2023
|
}
|
|
2018
2024
|
};
|
|
@@ -5013,9 +5019,9 @@ var TunnelManager = class {
|
|
|
5013
5019
|
throw new Error(`Failed to download cloudflared: ${response.statusText}`);
|
|
5014
5020
|
}
|
|
5015
5021
|
const buffer = Buffer.from(await response.arrayBuffer());
|
|
5016
|
-
const { writeFile:
|
|
5022
|
+
const { writeFile: writeFile3, rename: rename2 } = await import("fs/promises");
|
|
5017
5023
|
const tmpPath = this.binPath + ".tmp";
|
|
5018
|
-
await
|
|
5024
|
+
await writeFile3(tmpPath, buffer);
|
|
5019
5025
|
await (0, import_promises.chmod)(tmpPath, 493);
|
|
5020
5026
|
await rename2(tmpPath, this.binPath);
|
|
5021
5027
|
return this.binPath;
|
|
@@ -5923,12 +5929,12 @@ var GatewayManager = class {
|
|
|
5923
5929
|
zone = await this.cfClient.createZone(domain);
|
|
5924
5930
|
}
|
|
5925
5931
|
const existingRecords = await this.cfClient.listDnsRecords(zone.id);
|
|
5926
|
-
const { homedir:
|
|
5927
|
-
const backupDir = (0, import_node_path4.join)(
|
|
5932
|
+
const { homedir: homedir12 } = await import("os");
|
|
5933
|
+
const backupDir = (0, import_node_path4.join)(homedir12(), ".agenticmail");
|
|
5928
5934
|
const backupPath = (0, import_node_path4.join)(backupDir, `dns-backup-${domain}-${Date.now()}.json`);
|
|
5929
|
-
const { writeFileSync:
|
|
5930
|
-
|
|
5931
|
-
|
|
5935
|
+
const { writeFileSync: writeFileSync9, mkdirSync: mkdirSync10 } = await import("fs");
|
|
5936
|
+
mkdirSync10(backupDir, { recursive: true });
|
|
5937
|
+
writeFileSync9(backupPath, JSON.stringify({
|
|
5932
5938
|
domain,
|
|
5933
5939
|
zoneId: zone.id,
|
|
5934
5940
|
backedUpAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -6870,6 +6876,76 @@ function redactObject(input, _depth = 0) {
|
|
|
6870
6876
|
return out;
|
|
6871
6877
|
}
|
|
6872
6878
|
|
|
6879
|
+
// src/host-sessions.ts
|
|
6880
|
+
var import_node_fs4 = require("fs");
|
|
6881
|
+
var import_node_path6 = require("path");
|
|
6882
|
+
var import_node_os4 = require("os");
|
|
6883
|
+
function storageDir() {
|
|
6884
|
+
return (0, import_node_path6.join)((0, import_node_os4.homedir)(), ".agenticmail");
|
|
6885
|
+
}
|
|
6886
|
+
function storagePath() {
|
|
6887
|
+
return (0, import_node_path6.join)(storageDir(), "host-sessions.json");
|
|
6888
|
+
}
|
|
6889
|
+
var DEFAULT_SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
6890
|
+
function readFile() {
|
|
6891
|
+
const p = storagePath();
|
|
6892
|
+
if (!(0, import_node_fs4.existsSync)(p)) return { version: 1, sessions: {} };
|
|
6893
|
+
try {
|
|
6894
|
+
const raw = (0, import_node_fs4.readFileSync)(p, "utf-8");
|
|
6895
|
+
if (!raw.trim()) return { version: 1, sessions: {} };
|
|
6896
|
+
const parsed = JSON.parse(raw);
|
|
6897
|
+
return {
|
|
6898
|
+
version: 1,
|
|
6899
|
+
sessions: parsed.sessions && typeof parsed.sessions === "object" ? parsed.sessions : {}
|
|
6900
|
+
};
|
|
6901
|
+
} catch {
|
|
6902
|
+
return { version: 1, sessions: {} };
|
|
6903
|
+
}
|
|
6904
|
+
}
|
|
6905
|
+
function writeFile(shape) {
|
|
6906
|
+
const dir = storageDir();
|
|
6907
|
+
const p = storagePath();
|
|
6908
|
+
if (!(0, import_node_fs4.existsSync)(dir)) (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
6909
|
+
const tmp = `${p}.agenticmail-tmp-${process.pid}`;
|
|
6910
|
+
(0, import_node_fs4.writeFileSync)(tmp, JSON.stringify(shape, null, 2), "utf-8");
|
|
6911
|
+
(0, import_node_fs4.renameSync)(tmp, p);
|
|
6912
|
+
}
|
|
6913
|
+
function saveHostSession(host, session) {
|
|
6914
|
+
if (!session.sessionId) return;
|
|
6915
|
+
try {
|
|
6916
|
+
const shape = readFile();
|
|
6917
|
+
shape.sessions[host] = {
|
|
6918
|
+
...session,
|
|
6919
|
+
lastSeenMs: Date.now()
|
|
6920
|
+
};
|
|
6921
|
+
writeFile(shape);
|
|
6922
|
+
} catch {
|
|
6923
|
+
}
|
|
6924
|
+
}
|
|
6925
|
+
function loadHostSession(host, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
|
|
6926
|
+
const shape = readFile();
|
|
6927
|
+
const record = shape.sessions[host];
|
|
6928
|
+
if (!record) return null;
|
|
6929
|
+
if (!isSessionFresh(record, maxAgeMs)) return null;
|
|
6930
|
+
return record;
|
|
6931
|
+
}
|
|
6932
|
+
function isSessionFresh(session, maxAgeMs = DEFAULT_SESSION_MAX_AGE_MS) {
|
|
6933
|
+
if (!session || !Number.isFinite(session.lastSeenMs)) return false;
|
|
6934
|
+
return Date.now() - session.lastSeenMs <= maxAgeMs;
|
|
6935
|
+
}
|
|
6936
|
+
function forgetHostSession(host) {
|
|
6937
|
+
try {
|
|
6938
|
+
const shape = readFile();
|
|
6939
|
+
if (!shape.sessions[host]) return;
|
|
6940
|
+
delete shape.sessions[host];
|
|
6941
|
+
writeFile(shape);
|
|
6942
|
+
} catch {
|
|
6943
|
+
}
|
|
6944
|
+
}
|
|
6945
|
+
function hostSessionStoragePath() {
|
|
6946
|
+
return storagePath();
|
|
6947
|
+
}
|
|
6948
|
+
|
|
6873
6949
|
// src/util/safe-url.ts
|
|
6874
6950
|
var UnsafeApiUrlError = class extends Error {
|
|
6875
6951
|
constructor(raw, reason) {
|
|
@@ -6918,15 +6994,15 @@ function buildApiUrl(baseOrigin, pathAndQuery) {
|
|
|
6918
6994
|
|
|
6919
6995
|
// src/setup/index.ts
|
|
6920
6996
|
var import_node_crypto3 = require("crypto");
|
|
6921
|
-
var
|
|
6922
|
-
var
|
|
6923
|
-
var
|
|
6997
|
+
var import_node_fs8 = require("fs");
|
|
6998
|
+
var import_node_path10 = require("path");
|
|
6999
|
+
var import_node_os8 = require("os");
|
|
6924
7000
|
|
|
6925
7001
|
// src/setup/deps.ts
|
|
6926
7002
|
var import_node_child_process2 = require("child_process");
|
|
6927
|
-
var
|
|
6928
|
-
var
|
|
6929
|
-
var
|
|
7003
|
+
var import_node_fs5 = require("fs");
|
|
7004
|
+
var import_node_path7 = require("path");
|
|
7005
|
+
var import_node_os5 = require("os");
|
|
6930
7006
|
var DependencyChecker = class {
|
|
6931
7007
|
async checkAll() {
|
|
6932
7008
|
return Promise.all([
|
|
@@ -6976,8 +7052,8 @@ var DependencyChecker = class {
|
|
|
6976
7052
|
}
|
|
6977
7053
|
}
|
|
6978
7054
|
async checkCloudflared() {
|
|
6979
|
-
const binPath = (0,
|
|
6980
|
-
if ((0,
|
|
7055
|
+
const binPath = (0, import_node_path7.join)((0, import_node_os5.homedir)(), ".agenticmail", "bin", "cloudflared");
|
|
7056
|
+
if ((0, import_node_fs5.existsSync)(binPath)) {
|
|
6981
7057
|
let version;
|
|
6982
7058
|
try {
|
|
6983
7059
|
const output = (0, import_node_child_process2.execFileSync)(binPath, ["--version"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
@@ -6999,10 +7075,10 @@ var DependencyChecker = class {
|
|
|
6999
7075
|
|
|
7000
7076
|
// src/setup/installer.ts
|
|
7001
7077
|
var import_node_child_process3 = require("child_process");
|
|
7002
|
-
var
|
|
7078
|
+
var import_node_fs6 = require("fs");
|
|
7003
7079
|
var import_promises2 = require("fs/promises");
|
|
7004
|
-
var
|
|
7005
|
-
var
|
|
7080
|
+
var import_node_path8 = require("path");
|
|
7081
|
+
var import_node_os6 = require("os");
|
|
7006
7082
|
function runShellWithRollingOutput(cmd, opts = {}) {
|
|
7007
7083
|
const maxLines = opts.maxLines ?? 20;
|
|
7008
7084
|
const timeout = opts.timeout ?? 3e5;
|
|
@@ -7112,7 +7188,7 @@ var DependencyInstaller = class {
|
|
|
7112
7188
|
*/
|
|
7113
7189
|
async installDocker() {
|
|
7114
7190
|
if (this.isDockerReady()) return;
|
|
7115
|
-
const os = (0,
|
|
7191
|
+
const os = (0, import_node_os6.platform)();
|
|
7116
7192
|
if (os === "darwin") {
|
|
7117
7193
|
await this.installDockerMac();
|
|
7118
7194
|
} else if (os === "linux") {
|
|
@@ -7178,15 +7254,15 @@ var DependencyInstaller = class {
|
|
|
7178
7254
|
try {
|
|
7179
7255
|
const composeBin = (0, import_node_child_process3.execFileSync)("which", ["docker-compose"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
7180
7256
|
if (!composeBin) return;
|
|
7181
|
-
const pluginDir = (0,
|
|
7182
|
-
const pluginPath = (0,
|
|
7183
|
-
if ((0,
|
|
7257
|
+
const pluginDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".docker", "cli-plugins");
|
|
7258
|
+
const pluginPath = (0, import_node_path8.join)(pluginDir, "docker-compose");
|
|
7259
|
+
if ((0, import_node_fs6.existsSync)(pluginPath)) return;
|
|
7184
7260
|
try {
|
|
7185
|
-
(0,
|
|
7261
|
+
(0, import_node_fs6.mkdirSync)(pluginDir, { recursive: true });
|
|
7186
7262
|
} catch {
|
|
7187
7263
|
}
|
|
7188
7264
|
try {
|
|
7189
|
-
(0,
|
|
7265
|
+
(0, import_node_fs6.symlinkSync)(composeBin, pluginPath);
|
|
7190
7266
|
} catch {
|
|
7191
7267
|
}
|
|
7192
7268
|
} catch {
|
|
@@ -7245,9 +7321,9 @@ var DependencyInstaller = class {
|
|
|
7245
7321
|
return;
|
|
7246
7322
|
}
|
|
7247
7323
|
this.onProgress("__progress__:5:Installing Docker Engine...");
|
|
7248
|
-
const tmpDir = (0,
|
|
7324
|
+
const tmpDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "tmp");
|
|
7249
7325
|
await (0, import_promises2.mkdir)(tmpDir, { recursive: true });
|
|
7250
|
-
const scriptPath = (0,
|
|
7326
|
+
const scriptPath = (0, import_node_path8.join)(tmpDir, "install-docker.sh");
|
|
7251
7327
|
const dlResult = await runShellWithRollingOutput(
|
|
7252
7328
|
`curl -fsSL https://get.docker.com -o "${scriptPath}" && sudo sh "${scriptPath}"`,
|
|
7253
7329
|
{ timeout: 3e5 }
|
|
@@ -7315,8 +7391,8 @@ var DependencyInstaller = class {
|
|
|
7315
7391
|
}
|
|
7316
7392
|
try {
|
|
7317
7393
|
const programFiles = process.env["ProgramFiles"] || "C:\\Program Files";
|
|
7318
|
-
const dockerExe = (0,
|
|
7319
|
-
if ((0,
|
|
7394
|
+
const dockerExe = (0, import_node_path8.join)(programFiles, "Docker", "Docker", "Docker Desktop.exe");
|
|
7395
|
+
if ((0, import_node_fs6.existsSync)(dockerExe)) {
|
|
7320
7396
|
(0, import_node_child_process3.execSync)(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
|
|
7321
7397
|
}
|
|
7322
7398
|
} catch {
|
|
@@ -7366,8 +7442,8 @@ var DependencyInstaller = class {
|
|
|
7366
7442
|
this.onProgress("__progress__:70:Docker Desktop installed. Starting...");
|
|
7367
7443
|
try {
|
|
7368
7444
|
const programFiles = process.env["ProgramFiles"] || "C:\\Program Files";
|
|
7369
|
-
const dockerExe = (0,
|
|
7370
|
-
if ((0,
|
|
7445
|
+
const dockerExe = (0, import_node_path8.join)(programFiles, "Docker", "Docker", "Docker Desktop.exe");
|
|
7446
|
+
if ((0, import_node_fs6.existsSync)(dockerExe)) {
|
|
7371
7447
|
(0, import_node_child_process3.execSync)(`start "" "${dockerExe}"`, { timeout: 1e4, stdio: "ignore", shell: "cmd.exe" });
|
|
7372
7448
|
}
|
|
7373
7449
|
} catch {
|
|
@@ -7404,12 +7480,12 @@ var DependencyInstaller = class {
|
|
|
7404
7480
|
* Start the Stalwart mail server Docker container.
|
|
7405
7481
|
*/
|
|
7406
7482
|
async startStalwart(composePath) {
|
|
7407
|
-
if (!(0,
|
|
7483
|
+
if (!(0, import_node_fs6.existsSync)(composePath)) {
|
|
7408
7484
|
throw new Error(`docker-compose.yml not found at: ${composePath}`);
|
|
7409
7485
|
}
|
|
7410
7486
|
if (!this.isDockerReady()) {
|
|
7411
7487
|
this.onProgress("Starting Docker...");
|
|
7412
|
-
const os = (0,
|
|
7488
|
+
const os = (0, import_node_os6.platform)();
|
|
7413
7489
|
if (os === "darwin") {
|
|
7414
7490
|
await this.startColima();
|
|
7415
7491
|
} else if (os === "win32") {
|
|
@@ -7427,7 +7503,7 @@ var DependencyInstaller = class {
|
|
|
7427
7503
|
}
|
|
7428
7504
|
}
|
|
7429
7505
|
this.onProgress("__progress__:10:Pulling mail server image...");
|
|
7430
|
-
if ((0,
|
|
7506
|
+
if ((0, import_node_os6.platform)() === "darwin") this.linkComposePlugin();
|
|
7431
7507
|
let composeResult = await runSilent("docker", ["compose", "-f", composePath, "up", "-d"], { timeout: 12e4 });
|
|
7432
7508
|
if (composeResult.exitCode !== 0 && hasCommand("docker-compose")) {
|
|
7433
7509
|
composeResult = await runSilent("docker-compose", ["-f", composePath, "up", "-d"], { timeout: 12e4 });
|
|
@@ -7462,22 +7538,22 @@ var DependencyInstaller = class {
|
|
|
7462
7538
|
* Returns the path to the installed binary.
|
|
7463
7539
|
*/
|
|
7464
7540
|
async installCloudflared() {
|
|
7465
|
-
const os = (0,
|
|
7466
|
-
const binDir = (0,
|
|
7541
|
+
const os = (0, import_node_os6.platform)();
|
|
7542
|
+
const binDir = (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".agenticmail", "bin");
|
|
7467
7543
|
const binName = os === "win32" ? "cloudflared.exe" : "cloudflared";
|
|
7468
|
-
const binPath = (0,
|
|
7469
|
-
if ((0,
|
|
7544
|
+
const binPath = (0, import_node_path8.join)(binDir, binName);
|
|
7545
|
+
if ((0, import_node_fs6.existsSync)(binPath)) {
|
|
7470
7546
|
return binPath;
|
|
7471
7547
|
}
|
|
7472
7548
|
try {
|
|
7473
7549
|
const whichCmd = os === "win32" ? "where" : "which";
|
|
7474
7550
|
const sysPath = (0, import_node_child_process3.execFileSync)(whichCmd, ["cloudflared"], { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim().split("\n")[0];
|
|
7475
|
-
if (sysPath && (0,
|
|
7551
|
+
if (sysPath && (0, import_node_fs6.existsSync)(sysPath)) return sysPath;
|
|
7476
7552
|
} catch {
|
|
7477
7553
|
}
|
|
7478
7554
|
this.onProgress("Downloading cloudflared...");
|
|
7479
7555
|
await (0, import_promises2.mkdir)(binDir, { recursive: true });
|
|
7480
|
-
const cpu = (0,
|
|
7556
|
+
const cpu = (0, import_node_os6.arch)();
|
|
7481
7557
|
const archName = cpu === "arm64" ? "arm64" : "amd64";
|
|
7482
7558
|
let downloadUrl;
|
|
7483
7559
|
if (os === "darwin") {
|
|
@@ -7495,7 +7571,7 @@ var DependencyInstaller = class {
|
|
|
7495
7571
|
}
|
|
7496
7572
|
const buffer = Buffer.from(await response.arrayBuffer());
|
|
7497
7573
|
if (os === "darwin") {
|
|
7498
|
-
const tgzPath = (0,
|
|
7574
|
+
const tgzPath = (0, import_node_path8.join)(binDir, "cloudflared.tgz");
|
|
7499
7575
|
await (0, import_promises2.writeFile)(tgzPath, buffer);
|
|
7500
7576
|
try {
|
|
7501
7577
|
(0, import_node_child_process3.execFileSync)("tar", ["-xzf", tgzPath, "-C", binDir, "cloudflared"], { timeout: 15e3, stdio: "ignore" });
|
|
@@ -7512,7 +7588,7 @@ var DependencyInstaller = class {
|
|
|
7512
7588
|
if (os !== "win32") await (0, import_promises2.chmod)(tmpPath, 493);
|
|
7513
7589
|
await (0, import_promises2.rename)(tmpPath, binPath);
|
|
7514
7590
|
}
|
|
7515
|
-
if (!(0,
|
|
7591
|
+
if (!(0, import_node_fs6.existsSync)(binPath)) {
|
|
7516
7592
|
throw new Error("cloudflared download succeeded but binary not found after extraction");
|
|
7517
7593
|
}
|
|
7518
7594
|
this.onProgress("cloudflared installed");
|
|
@@ -7530,23 +7606,23 @@ var DependencyInstaller = class {
|
|
|
7530
7606
|
|
|
7531
7607
|
// src/setup/service.ts
|
|
7532
7608
|
var import_node_child_process4 = require("child_process");
|
|
7533
|
-
var
|
|
7534
|
-
var
|
|
7535
|
-
var
|
|
7609
|
+
var import_node_fs7 = require("fs");
|
|
7610
|
+
var import_node_path9 = require("path");
|
|
7611
|
+
var import_node_os7 = require("os");
|
|
7536
7612
|
var import_node_module2 = require("module");
|
|
7537
7613
|
var import_meta2 = {};
|
|
7538
7614
|
var PLIST_LABEL = "com.agenticmail.server";
|
|
7539
7615
|
var SYSTEMD_UNIT = "agenticmail.service";
|
|
7540
7616
|
var ServiceManager = class {
|
|
7541
|
-
os = (0,
|
|
7617
|
+
os = (0, import_node_os7.platform)();
|
|
7542
7618
|
/**
|
|
7543
7619
|
* Get the path to the service file.
|
|
7544
7620
|
*/
|
|
7545
7621
|
getServicePath() {
|
|
7546
7622
|
if (this.os === "darwin") {
|
|
7547
|
-
return (0,
|
|
7623
|
+
return (0, import_node_path9.join)((0, import_node_os7.homedir)(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
|
|
7548
7624
|
} else {
|
|
7549
|
-
return (0,
|
|
7625
|
+
return (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".config", "systemd", "user", SYSTEMD_UNIT);
|
|
7550
7626
|
}
|
|
7551
7627
|
}
|
|
7552
7628
|
/**
|
|
@@ -7580,40 +7656,40 @@ var ServiceManager = class {
|
|
|
7580
7656
|
try {
|
|
7581
7657
|
const req = (0, import_node_module2.createRequire)(import_meta2.url);
|
|
7582
7658
|
const resolved = req.resolve("@agenticmail/api");
|
|
7583
|
-
if ((0,
|
|
7659
|
+
if ((0, import_node_fs7.existsSync)(resolved)) return resolved;
|
|
7584
7660
|
} catch {
|
|
7585
7661
|
}
|
|
7586
7662
|
const parentPackages = [
|
|
7587
|
-
(0,
|
|
7663
|
+
(0, import_node_path9.join)("@agenticmail", "cli"),
|
|
7588
7664
|
// current scoped package
|
|
7589
7665
|
"agenticmail"
|
|
7590
7666
|
// legacy unscoped package
|
|
7591
7667
|
];
|
|
7592
7668
|
const baseDirs = [
|
|
7593
7669
|
// user-local install
|
|
7594
|
-
(0,
|
|
7670
|
+
(0, import_node_path9.join)((0, import_node_os7.homedir)(), "node_modules")
|
|
7595
7671
|
];
|
|
7596
7672
|
try {
|
|
7597
7673
|
const prefix = (0, import_node_child_process4.execSync)("npm prefix -g", { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
7598
|
-
baseDirs.push((0,
|
|
7599
|
-
baseDirs.push((0,
|
|
7674
|
+
baseDirs.push((0, import_node_path9.join)(prefix, "lib", "node_modules"));
|
|
7675
|
+
baseDirs.push((0, import_node_path9.join)(prefix, "node_modules"));
|
|
7600
7676
|
} catch {
|
|
7601
7677
|
}
|
|
7602
7678
|
baseDirs.push("/opt/homebrew/lib/node_modules");
|
|
7603
7679
|
baseDirs.push("/usr/local/lib/node_modules");
|
|
7604
7680
|
for (const base of baseDirs) {
|
|
7605
|
-
const sibling = (0,
|
|
7606
|
-
if ((0,
|
|
7681
|
+
const sibling = (0, import_node_path9.join)(base, "@agenticmail", "api", "dist", "index.js");
|
|
7682
|
+
if ((0, import_node_fs7.existsSync)(sibling)) return sibling;
|
|
7607
7683
|
for (const parent of parentPackages) {
|
|
7608
|
-
const nested = (0,
|
|
7609
|
-
if ((0,
|
|
7684
|
+
const nested = (0, import_node_path9.join)(base, parent, "node_modules", "@agenticmail", "api", "dist", "index.js");
|
|
7685
|
+
if ((0, import_node_fs7.existsSync)(nested)) return nested;
|
|
7610
7686
|
}
|
|
7611
7687
|
}
|
|
7612
|
-
const dataDir = (0,
|
|
7613
|
-
const entryCache = (0,
|
|
7614
|
-
if ((0,
|
|
7615
|
-
const cached = (0,
|
|
7616
|
-
if (cached && (0,
|
|
7688
|
+
const dataDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail");
|
|
7689
|
+
const entryCache = (0, import_node_path9.join)(dataDir, "api-entry.path");
|
|
7690
|
+
if ((0, import_node_fs7.existsSync)(entryCache)) {
|
|
7691
|
+
const cached = (0, import_node_fs7.readFileSync)(entryCache, "utf-8").trim();
|
|
7692
|
+
if (cached && (0, import_node_fs7.existsSync)(cached)) return cached;
|
|
7617
7693
|
}
|
|
7618
7694
|
throw new Error("Could not find @agenticmail/api entry point. Run `agenticmail start` first to populate the cache.");
|
|
7619
7695
|
}
|
|
@@ -7621,9 +7697,9 @@ var ServiceManager = class {
|
|
|
7621
7697
|
* Cache the API entry path so the service can find it later.
|
|
7622
7698
|
*/
|
|
7623
7699
|
cacheApiEntryPath(entryPath) {
|
|
7624
|
-
const dataDir = (0,
|
|
7625
|
-
if (!(0,
|
|
7626
|
-
(0,
|
|
7700
|
+
const dataDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail");
|
|
7701
|
+
if (!(0, import_node_fs7.existsSync)(dataDir)) (0, import_node_fs7.mkdirSync)(dataDir, { recursive: true });
|
|
7702
|
+
(0, import_node_fs7.writeFileSync)((0, import_node_path9.join)(dataDir, "api-entry.path"), entryPath);
|
|
7627
7703
|
}
|
|
7628
7704
|
/**
|
|
7629
7705
|
* Get the current package version.
|
|
@@ -7636,36 +7712,36 @@ var ServiceManager = class {
|
|
|
7636
7712
|
try {
|
|
7637
7713
|
const req = (0, import_node_module2.createRequire)(import_meta2.url);
|
|
7638
7714
|
const pkgJson = req.resolve("@agenticmail/cli/package.json");
|
|
7639
|
-
if ((0,
|
|
7640
|
-
const pkg = JSON.parse((0,
|
|
7715
|
+
if ((0, import_node_fs7.existsSync)(pkgJson)) {
|
|
7716
|
+
const pkg = JSON.parse((0, import_node_fs7.readFileSync)(pkgJson, "utf-8"));
|
|
7641
7717
|
if (pkg.version) return pkg.version;
|
|
7642
7718
|
}
|
|
7643
7719
|
} catch {
|
|
7644
7720
|
}
|
|
7645
7721
|
try {
|
|
7646
7722
|
const apiEntry = this.getApiEntryPath();
|
|
7647
|
-
const apiPkg = (0,
|
|
7648
|
-
if ((0,
|
|
7649
|
-
const pkg = JSON.parse((0,
|
|
7723
|
+
const apiPkg = (0, import_node_path9.join)(apiEntry, "..", "..", "package.json");
|
|
7724
|
+
if ((0, import_node_fs7.existsSync)(apiPkg)) {
|
|
7725
|
+
const pkg = JSON.parse((0, import_node_fs7.readFileSync)(apiPkg, "utf-8"));
|
|
7650
7726
|
if (pkg.version) return pkg.version;
|
|
7651
7727
|
}
|
|
7652
7728
|
} catch {
|
|
7653
7729
|
}
|
|
7654
7730
|
const candidates = [
|
|
7655
|
-
(0,
|
|
7656
|
-
(0,
|
|
7657
|
-
(0,
|
|
7731
|
+
(0, import_node_path9.join)((0, import_node_os7.homedir)(), "node_modules", "@agenticmail", "cli", "package.json"),
|
|
7732
|
+
(0, import_node_path9.join)((0, import_node_os7.homedir)(), "node_modules", "agenticmail", "package.json"),
|
|
7733
|
+
(0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "package-version.json")
|
|
7658
7734
|
];
|
|
7659
7735
|
try {
|
|
7660
7736
|
const prefix = (0, import_node_child_process4.execSync)("npm prefix -g", { timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
|
|
7661
|
-
candidates.push((0,
|
|
7662
|
-
candidates.push((0,
|
|
7737
|
+
candidates.push((0, import_node_path9.join)(prefix, "lib", "node_modules", "@agenticmail", "cli", "package.json"));
|
|
7738
|
+
candidates.push((0, import_node_path9.join)(prefix, "lib", "node_modules", "agenticmail", "package.json"));
|
|
7663
7739
|
} catch {
|
|
7664
7740
|
}
|
|
7665
7741
|
for (const p of candidates) {
|
|
7666
7742
|
try {
|
|
7667
|
-
if ((0,
|
|
7668
|
-
const pkg = JSON.parse((0,
|
|
7743
|
+
if ((0, import_node_fs7.existsSync)(p)) {
|
|
7744
|
+
const pkg = JSON.parse((0, import_node_fs7.readFileSync)(p, "utf-8"));
|
|
7669
7745
|
if (pkg.version) return pkg.version;
|
|
7670
7746
|
}
|
|
7671
7747
|
} catch {
|
|
@@ -7678,9 +7754,9 @@ var ServiceManager = class {
|
|
|
7678
7754
|
* This ensures AgenticMail doesn't fail on boot when Docker is still loading.
|
|
7679
7755
|
*/
|
|
7680
7756
|
generateStartScript(nodePath, apiEntry) {
|
|
7681
|
-
const scriptPath = (0,
|
|
7682
|
-
const scriptDir = (0,
|
|
7683
|
-
if (!(0,
|
|
7757
|
+
const scriptPath = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "bin", "start-server.sh");
|
|
7758
|
+
const scriptDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "bin");
|
|
7759
|
+
if (!(0, import_node_fs7.existsSync)(scriptDir)) (0, import_node_fs7.mkdirSync)(scriptDir, { recursive: true });
|
|
7684
7760
|
const script = [
|
|
7685
7761
|
"#!/bin/bash",
|
|
7686
7762
|
"# AgenticMail auto-start script",
|
|
@@ -7731,7 +7807,7 @@ var ServiceManager = class {
|
|
|
7731
7807
|
`log "Starting API server: ${nodePath} ${apiEntry}"`,
|
|
7732
7808
|
`exec "${nodePath}" "${apiEntry}"`
|
|
7733
7809
|
].join("\n") + "\n";
|
|
7734
|
-
(0,
|
|
7810
|
+
(0, import_node_fs7.writeFileSync)(scriptPath, script, { mode: 493 });
|
|
7735
7811
|
return scriptPath;
|
|
7736
7812
|
}
|
|
7737
7813
|
/**
|
|
@@ -7744,9 +7820,9 @@ var ServiceManager = class {
|
|
|
7744
7820
|
* - Service version tracking in env vars
|
|
7745
7821
|
*/
|
|
7746
7822
|
generatePlist(nodePath, apiEntry, configPath) {
|
|
7747
|
-
const config = JSON.parse((0,
|
|
7748
|
-
const logDir = (0,
|
|
7749
|
-
if (!(0,
|
|
7823
|
+
const config = JSON.parse((0, import_node_fs7.readFileSync)(configPath, "utf-8"));
|
|
7824
|
+
const logDir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "logs");
|
|
7825
|
+
if (!(0, import_node_fs7.existsSync)(logDir)) (0, import_node_fs7.mkdirSync)(logDir, { recursive: true });
|
|
7750
7826
|
const version = this.getVersion();
|
|
7751
7827
|
const startScript = this.generateStartScript(nodePath, apiEntry);
|
|
7752
7828
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -7767,9 +7843,9 @@ var ServiceManager = class {
|
|
|
7767
7843
|
<key>EnvironmentVariables</key>
|
|
7768
7844
|
<dict>
|
|
7769
7845
|
<key>HOME</key>
|
|
7770
|
-
<string>${(0,
|
|
7846
|
+
<string>${(0, import_node_os7.homedir)()}</string>
|
|
7771
7847
|
<key>AGENTICMAIL_DATA_DIR</key>
|
|
7772
|
-
<string>${config.dataDir || (0,
|
|
7848
|
+
<string>${config.dataDir || (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail")}</string>
|
|
7773
7849
|
<key>PATH</key>
|
|
7774
7850
|
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
7775
7851
|
<key>AGENTICMAIL_SERVICE_VERSION</key>
|
|
@@ -7822,8 +7898,8 @@ var ServiceManager = class {
|
|
|
7822
7898
|
* - Proper dependency ordering
|
|
7823
7899
|
*/
|
|
7824
7900
|
generateSystemdUnit(nodePath, apiEntry, configPath) {
|
|
7825
|
-
const config = JSON.parse((0,
|
|
7826
|
-
const dataDir = config.dataDir || (0,
|
|
7901
|
+
const config = JSON.parse((0, import_node_fs7.readFileSync)(configPath, "utf-8"));
|
|
7902
|
+
const dataDir = config.dataDir || (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail");
|
|
7827
7903
|
const version = this.getVersion();
|
|
7828
7904
|
const startScript = this.generateStartScript(nodePath, apiEntry);
|
|
7829
7905
|
return `[Unit]
|
|
@@ -7840,7 +7916,7 @@ Restart=always
|
|
|
7840
7916
|
RestartSec=15
|
|
7841
7917
|
TimeoutStartSec=660
|
|
7842
7918
|
LimitNOFILE=8192
|
|
7843
|
-
Environment=HOME=${(0,
|
|
7919
|
+
Environment=HOME=${(0, import_node_os7.homedir)()}
|
|
7844
7920
|
Environment=AGENTICMAIL_DATA_DIR=${dataDir}
|
|
7845
7921
|
Environment=PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin
|
|
7846
7922
|
Environment=AGENTICMAIL_SERVICE_VERSION=${version}
|
|
@@ -7853,8 +7929,8 @@ WantedBy=default.target
|
|
|
7853
7929
|
* Install the auto-start service.
|
|
7854
7930
|
*/
|
|
7855
7931
|
install() {
|
|
7856
|
-
const configPath = (0,
|
|
7857
|
-
if (!(0,
|
|
7932
|
+
const configPath = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "config.json");
|
|
7933
|
+
if (!(0, import_node_fs7.existsSync)(configPath)) {
|
|
7858
7934
|
return { installed: false, message: "Config not found. Run agenticmail setup first." };
|
|
7859
7935
|
}
|
|
7860
7936
|
const nodePath = this.getNodePath();
|
|
@@ -7866,17 +7942,17 @@ WantedBy=default.target
|
|
|
7866
7942
|
}
|
|
7867
7943
|
const servicePath = this.getServicePath();
|
|
7868
7944
|
if (this.os === "darwin") {
|
|
7869
|
-
const dir = (0,
|
|
7870
|
-
if (!(0,
|
|
7871
|
-
if ((0,
|
|
7945
|
+
const dir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), "Library", "LaunchAgents");
|
|
7946
|
+
if (!(0, import_node_fs7.existsSync)(dir)) (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
|
|
7947
|
+
if ((0, import_node_fs7.existsSync)(servicePath)) {
|
|
7872
7948
|
try {
|
|
7873
7949
|
(0, import_node_child_process4.execFileSync)("launchctl", ["unload", servicePath], { timeout: 1e4, stdio: "ignore" });
|
|
7874
7950
|
} catch {
|
|
7875
7951
|
}
|
|
7876
7952
|
}
|
|
7877
7953
|
const plist = this.generatePlist(nodePath, apiEntry, configPath);
|
|
7878
|
-
(0,
|
|
7879
|
-
(0,
|
|
7954
|
+
(0, import_node_fs7.writeFileSync)(servicePath, plist);
|
|
7955
|
+
(0, import_node_fs7.chmodSync)(servicePath, 384);
|
|
7880
7956
|
try {
|
|
7881
7957
|
(0, import_node_child_process4.execFileSync)("launchctl", ["load", servicePath], { timeout: 1e4, stdio: "ignore" });
|
|
7882
7958
|
} catch (err) {
|
|
@@ -7884,11 +7960,11 @@ WantedBy=default.target
|
|
|
7884
7960
|
}
|
|
7885
7961
|
return { installed: true, message: `Service installed at ${servicePath}` };
|
|
7886
7962
|
} else if (this.os === "linux") {
|
|
7887
|
-
const dir = (0,
|
|
7888
|
-
if (!(0,
|
|
7963
|
+
const dir = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".config", "systemd", "user");
|
|
7964
|
+
if (!(0, import_node_fs7.existsSync)(dir)) (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
|
|
7889
7965
|
const unit = this.generateSystemdUnit(nodePath, apiEntry, configPath);
|
|
7890
|
-
(0,
|
|
7891
|
-
(0,
|
|
7966
|
+
(0, import_node_fs7.writeFileSync)(servicePath, unit);
|
|
7967
|
+
(0, import_node_fs7.chmodSync)(servicePath, 384);
|
|
7892
7968
|
try {
|
|
7893
7969
|
(0, import_node_child_process4.execFileSync)("systemctl", ["--user", "daemon-reload"], { timeout: 1e4, stdio: "ignore" });
|
|
7894
7970
|
(0, import_node_child_process4.execFileSync)("systemctl", ["--user", "enable", SYSTEMD_UNIT], { timeout: 1e4, stdio: "ignore" });
|
|
@@ -7910,7 +7986,7 @@ WantedBy=default.target
|
|
|
7910
7986
|
*/
|
|
7911
7987
|
uninstall() {
|
|
7912
7988
|
const servicePath = this.getServicePath();
|
|
7913
|
-
if (!(0,
|
|
7989
|
+
if (!(0, import_node_fs7.existsSync)(servicePath)) {
|
|
7914
7990
|
return { removed: false, message: "Service is not installed." };
|
|
7915
7991
|
}
|
|
7916
7992
|
if (this.os === "darwin") {
|
|
@@ -7919,7 +7995,7 @@ WantedBy=default.target
|
|
|
7919
7995
|
} catch {
|
|
7920
7996
|
}
|
|
7921
7997
|
try {
|
|
7922
|
-
(0,
|
|
7998
|
+
(0, import_node_fs7.unlinkSync)(servicePath);
|
|
7923
7999
|
} catch {
|
|
7924
8000
|
}
|
|
7925
8001
|
return { removed: true, message: "Service removed." };
|
|
@@ -7930,7 +8006,7 @@ WantedBy=default.target
|
|
|
7930
8006
|
} catch {
|
|
7931
8007
|
}
|
|
7932
8008
|
try {
|
|
7933
|
-
(0,
|
|
8009
|
+
(0, import_node_fs7.unlinkSync)(servicePath);
|
|
7934
8010
|
} catch {
|
|
7935
8011
|
}
|
|
7936
8012
|
try {
|
|
@@ -7948,7 +8024,7 @@ WantedBy=default.target
|
|
|
7948
8024
|
status() {
|
|
7949
8025
|
const servicePath = this.getServicePath();
|
|
7950
8026
|
const plat = this.os === "darwin" ? "launchd" : this.os === "linux" ? "systemd" : "unsupported";
|
|
7951
|
-
const installed = (0,
|
|
8027
|
+
const installed = (0, import_node_fs7.existsSync)(servicePath);
|
|
7952
8028
|
let running = false;
|
|
7953
8029
|
if (installed) {
|
|
7954
8030
|
if (this.os === "darwin") {
|
|
@@ -8003,34 +8079,34 @@ WantedBy=default.target
|
|
|
8003
8079
|
needsRepair() {
|
|
8004
8080
|
if (this.os !== "darwin" && this.os !== "linux") return null;
|
|
8005
8081
|
const servicePath = this.getServicePath();
|
|
8006
|
-
if (!(0,
|
|
8082
|
+
if (!(0, import_node_fs7.existsSync)(servicePath)) return null;
|
|
8007
8083
|
let serviceContent = "";
|
|
8008
8084
|
try {
|
|
8009
|
-
serviceContent = (0,
|
|
8085
|
+
serviceContent = (0, import_node_fs7.readFileSync)(servicePath, "utf-8");
|
|
8010
8086
|
} catch {
|
|
8011
8087
|
return { reason: "Service file unreadable" };
|
|
8012
8088
|
}
|
|
8013
|
-
const startScript = (0,
|
|
8089
|
+
const startScript = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "bin", "start-server.sh");
|
|
8014
8090
|
if (serviceContent.includes(startScript)) {
|
|
8015
|
-
if (!(0,
|
|
8091
|
+
if (!(0, import_node_fs7.existsSync)(startScript)) {
|
|
8016
8092
|
return { reason: "start-server.sh is missing" };
|
|
8017
8093
|
}
|
|
8018
8094
|
let scriptContent = "";
|
|
8019
8095
|
try {
|
|
8020
|
-
scriptContent = (0,
|
|
8096
|
+
scriptContent = (0, import_node_fs7.readFileSync)(startScript, "utf-8");
|
|
8021
8097
|
} catch {
|
|
8022
8098
|
return { reason: "start-server.sh unreadable" };
|
|
8023
8099
|
}
|
|
8024
8100
|
const apiPathMatch = scriptContent.match(/(\/[^"\s]+@agenticmail\/api\/dist\/index\.js)/);
|
|
8025
8101
|
if (apiPathMatch) {
|
|
8026
8102
|
const referenced = apiPathMatch[1];
|
|
8027
|
-
if (!(0,
|
|
8103
|
+
if (!(0, import_node_fs7.existsSync)(referenced)) {
|
|
8028
8104
|
return { reason: `start-server.sh references missing path: ${referenced}` };
|
|
8029
8105
|
}
|
|
8030
8106
|
}
|
|
8031
8107
|
if (/node_modules\/agenticmail\/(?!.*@agenticmail\/cli)/.test(scriptContent)) {
|
|
8032
8108
|
const stale = /(\S*node_modules\/agenticmail\/\S*)/.exec(scriptContent)?.[1];
|
|
8033
|
-
if (stale && !(0,
|
|
8109
|
+
if (stale && !(0, import_node_fs7.existsSync)(stale)) {
|
|
8034
8110
|
return { reason: `start-server.sh references legacy unscoped path: ${stale}` };
|
|
8035
8111
|
}
|
|
8036
8112
|
}
|
|
@@ -8043,11 +8119,11 @@ WantedBy=default.target
|
|
|
8043
8119
|
return { reason: `Service version drift (current CLI is v${currentVersion})` };
|
|
8044
8120
|
}
|
|
8045
8121
|
}
|
|
8046
|
-
const entryCache = (0,
|
|
8047
|
-
if ((0,
|
|
8122
|
+
const entryCache = (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".agenticmail", "api-entry.path");
|
|
8123
|
+
if ((0, import_node_fs7.existsSync)(entryCache)) {
|
|
8048
8124
|
try {
|
|
8049
|
-
const cached = (0,
|
|
8050
|
-
if (cached && !(0,
|
|
8125
|
+
const cached = (0, import_node_fs7.readFileSync)(entryCache, "utf-8").trim();
|
|
8126
|
+
if (cached && !(0, import_node_fs7.existsSync)(cached)) {
|
|
8051
8127
|
return { reason: `Cached API entry path no longer exists: ${cached}` };
|
|
8052
8128
|
}
|
|
8053
8129
|
} catch {
|
|
@@ -8098,13 +8174,13 @@ var SetupManager = class {
|
|
|
8098
8174
|
* falls back to monorepo location.
|
|
8099
8175
|
*/
|
|
8100
8176
|
getComposePath() {
|
|
8101
|
-
const standalonePath = (0,
|
|
8102
|
-
if ((0,
|
|
8177
|
+
const standalonePath = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "docker-compose.yml");
|
|
8178
|
+
if ((0, import_node_fs8.existsSync)(standalonePath)) return standalonePath;
|
|
8103
8179
|
const cwd = process.cwd();
|
|
8104
|
-
const candidates = [cwd, (0,
|
|
8180
|
+
const candidates = [cwd, (0, import_node_path10.join)(cwd, "..")];
|
|
8105
8181
|
for (const dir of candidates) {
|
|
8106
|
-
const p = (0,
|
|
8107
|
-
if ((0,
|
|
8182
|
+
const p = (0, import_node_path10.join)(dir, "docker-compose.yml");
|
|
8183
|
+
if ((0, import_node_fs8.existsSync)(p)) return p;
|
|
8108
8184
|
}
|
|
8109
8185
|
return standalonePath;
|
|
8110
8186
|
}
|
|
@@ -8114,19 +8190,19 @@ var SetupManager = class {
|
|
|
8114
8190
|
* Always regenerates Docker files to keep passwords in sync.
|
|
8115
8191
|
*/
|
|
8116
8192
|
initConfig() {
|
|
8117
|
-
const dataDir = (0,
|
|
8118
|
-
const configPath = (0,
|
|
8119
|
-
const envPath = (0,
|
|
8120
|
-
if ((0,
|
|
8193
|
+
const dataDir = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail");
|
|
8194
|
+
const configPath = (0, import_node_path10.join)(dataDir, "config.json");
|
|
8195
|
+
const envPath = (0, import_node_path10.join)(dataDir, ".env");
|
|
8196
|
+
if ((0, import_node_fs8.existsSync)(configPath)) {
|
|
8121
8197
|
try {
|
|
8122
|
-
const existing = JSON.parse((0,
|
|
8198
|
+
const existing = JSON.parse((0, import_node_fs8.readFileSync)(configPath, "utf-8"));
|
|
8123
8199
|
this.generateDockerFiles(existing);
|
|
8124
8200
|
return { configPath, envPath, config: existing, isNew: false };
|
|
8125
8201
|
} catch {
|
|
8126
8202
|
}
|
|
8127
8203
|
}
|
|
8128
|
-
if (!(0,
|
|
8129
|
-
(0,
|
|
8204
|
+
if (!(0, import_node_fs8.existsSync)(dataDir)) {
|
|
8205
|
+
(0, import_node_fs8.mkdirSync)(dataDir, { recursive: true });
|
|
8130
8206
|
}
|
|
8131
8207
|
const masterKey = `mk_${(0, import_node_crypto3.randomBytes)(24).toString("hex")}`;
|
|
8132
8208
|
const stalwartPassword = (0, import_node_crypto3.randomBytes)(16).toString("hex");
|
|
@@ -8142,8 +8218,8 @@ var SetupManager = class {
|
|
|
8142
8218
|
api: { port: 3829, host: "127.0.0.1" },
|
|
8143
8219
|
dataDir
|
|
8144
8220
|
};
|
|
8145
|
-
(0,
|
|
8146
|
-
(0,
|
|
8221
|
+
(0, import_node_fs8.writeFileSync)(configPath, JSON.stringify(config, null, 2));
|
|
8222
|
+
(0, import_node_fs8.chmodSync)(configPath, 384);
|
|
8147
8223
|
const envContent = `# Auto-generated by agenticmail setup
|
|
8148
8224
|
STALWART_ADMIN_USER=admin
|
|
8149
8225
|
STALWART_ADMIN_PASSWORD=${stalwartPassword}
|
|
@@ -8158,8 +8234,8 @@ SMTP_PORT=587
|
|
|
8158
8234
|
IMAP_HOST=localhost
|
|
8159
8235
|
IMAP_PORT=143
|
|
8160
8236
|
`;
|
|
8161
|
-
(0,
|
|
8162
|
-
(0,
|
|
8237
|
+
(0, import_node_fs8.writeFileSync)(envPath, envContent);
|
|
8238
|
+
(0, import_node_fs8.chmodSync)(envPath, 384);
|
|
8163
8239
|
this.generateDockerFiles(config);
|
|
8164
8240
|
return { configPath, envPath, config, isNew: true };
|
|
8165
8241
|
}
|
|
@@ -8168,13 +8244,13 @@ IMAP_PORT=143
|
|
|
8168
8244
|
* with the correct admin password from config.
|
|
8169
8245
|
*/
|
|
8170
8246
|
generateDockerFiles(config) {
|
|
8171
|
-
const dataDir = config.dataDir || (0,
|
|
8172
|
-
if (!(0,
|
|
8173
|
-
(0,
|
|
8247
|
+
const dataDir = config.dataDir || (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail");
|
|
8248
|
+
if (!(0, import_node_fs8.existsSync)(dataDir)) {
|
|
8249
|
+
(0, import_node_fs8.mkdirSync)(dataDir, { recursive: true });
|
|
8174
8250
|
}
|
|
8175
8251
|
const password = config.stalwart?.adminPassword || "changeme";
|
|
8176
|
-
const composePath = (0,
|
|
8177
|
-
(0,
|
|
8252
|
+
const composePath = (0, import_node_path10.join)(dataDir, "docker-compose.yml");
|
|
8253
|
+
(0, import_node_fs8.writeFileSync)(composePath, `services:
|
|
8178
8254
|
stalwart:
|
|
8179
8255
|
# Pinned to v0.15.5 \u2014 Stalwart 0.16+ moved its config to JSON
|
|
8180
8256
|
# at /etc/stalwart/config.json (hardcoded into the container
|
|
@@ -8203,9 +8279,9 @@ IMAP_PORT=143
|
|
|
8203
8279
|
volumes:
|
|
8204
8280
|
stalwart-data:
|
|
8205
8281
|
`);
|
|
8206
|
-
(0,
|
|
8207
|
-
const tomlPath = (0,
|
|
8208
|
-
(0,
|
|
8282
|
+
(0, import_node_fs8.chmodSync)(composePath, 384);
|
|
8283
|
+
const tomlPath = (0, import_node_path10.join)(dataDir, "stalwart.toml");
|
|
8284
|
+
(0, import_node_fs8.writeFileSync)(tomlPath, `# Stalwart Mail Server \u2014 AgenticMail Configuration
|
|
8209
8285
|
|
|
8210
8286
|
[server]
|
|
8211
8287
|
hostname = "localhost"
|
|
@@ -8255,14 +8331,14 @@ enable = true
|
|
|
8255
8331
|
user = "admin"
|
|
8256
8332
|
secret = "${password}"
|
|
8257
8333
|
`);
|
|
8258
|
-
(0,
|
|
8334
|
+
(0, import_node_fs8.chmodSync)(tomlPath, 384);
|
|
8259
8335
|
}
|
|
8260
8336
|
/**
|
|
8261
8337
|
* Check if config has already been initialized.
|
|
8262
8338
|
*/
|
|
8263
8339
|
isInitialized() {
|
|
8264
|
-
const configPath = (0,
|
|
8265
|
-
return (0,
|
|
8340
|
+
const configPath = (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".agenticmail", "config.json");
|
|
8341
|
+
return (0, import_node_fs8.existsSync)(configPath);
|
|
8266
8342
|
}
|
|
8267
8343
|
};
|
|
8268
8344
|
|
|
@@ -8300,10 +8376,10 @@ function threadIdFor(input) {
|
|
|
8300
8376
|
}
|
|
8301
8377
|
|
|
8302
8378
|
// src/threading/thread-cache.ts
|
|
8303
|
-
var
|
|
8304
|
-
var
|
|
8305
|
-
var
|
|
8306
|
-
var CACHE_DIR_DEFAULT = (0,
|
|
8379
|
+
var import_node_fs9 = require("fs");
|
|
8380
|
+
var import_node_os9 = require("os");
|
|
8381
|
+
var import_node_path11 = require("path");
|
|
8382
|
+
var CACHE_DIR_DEFAULT = (0, import_node_path11.join)((0, import_node_os9.homedir)(), ".agenticmail", "thread-cache");
|
|
8307
8383
|
var DEFAULT_K_MESSAGES = 10;
|
|
8308
8384
|
var DEFAULT_LRU_CAP = 5e3;
|
|
8309
8385
|
var PREVIEW_MAX_CHARS = 240;
|
|
@@ -8316,22 +8392,22 @@ var ThreadCache = class {
|
|
|
8316
8392
|
this.k = opts.k ?? DEFAULT_K_MESSAGES;
|
|
8317
8393
|
this.lruCap = opts.lruCap ?? DEFAULT_LRU_CAP;
|
|
8318
8394
|
try {
|
|
8319
|
-
(0,
|
|
8395
|
+
(0, import_node_fs9.mkdirSync)(this.dir, { recursive: true });
|
|
8320
8396
|
} catch {
|
|
8321
8397
|
}
|
|
8322
8398
|
}
|
|
8323
8399
|
pathFor(threadId) {
|
|
8324
|
-
return (0,
|
|
8400
|
+
return (0, import_node_path11.join)(this.dir, `${threadId}.json`);
|
|
8325
8401
|
}
|
|
8326
8402
|
read(threadId) {
|
|
8327
8403
|
const p = this.pathFor(threadId);
|
|
8328
|
-
if (!(0,
|
|
8404
|
+
if (!(0, import_node_fs9.existsSync)(p)) return null;
|
|
8329
8405
|
try {
|
|
8330
|
-
const raw = (0,
|
|
8406
|
+
const raw = (0, import_node_fs9.readFileSync)(p, "utf-8");
|
|
8331
8407
|
return JSON.parse(raw);
|
|
8332
8408
|
} catch {
|
|
8333
8409
|
try {
|
|
8334
|
-
(0,
|
|
8410
|
+
(0, import_node_fs9.rmSync)(p, { force: true });
|
|
8335
8411
|
} catch {
|
|
8336
8412
|
}
|
|
8337
8413
|
return null;
|
|
@@ -8372,7 +8448,7 @@ var ThreadCache = class {
|
|
|
8372
8448
|
/** Permanently remove a thread's cache (called on [FINAL] / [DONE] / [CLOSED] / [WRAP]). */
|
|
8373
8449
|
delete(threadId) {
|
|
8374
8450
|
try {
|
|
8375
|
-
(0,
|
|
8451
|
+
(0, import_node_fs9.rmSync)(this.pathFor(threadId), { force: true });
|
|
8376
8452
|
} catch {
|
|
8377
8453
|
}
|
|
8378
8454
|
}
|
|
@@ -8392,8 +8468,8 @@ var ThreadCache = class {
|
|
|
8392
8468
|
writeAtomic(threadId, entry) {
|
|
8393
8469
|
const p = this.pathFor(threadId);
|
|
8394
8470
|
const tmp = `${p}.tmp`;
|
|
8395
|
-
(0,
|
|
8396
|
-
(0,
|
|
8471
|
+
(0, import_node_fs9.writeFileSync)(tmp, JSON.stringify(entry), "utf-8");
|
|
8472
|
+
(0, import_node_fs9.renameSync)(tmp, p);
|
|
8397
8473
|
}
|
|
8398
8474
|
/**
|
|
8399
8475
|
* Best-effort LRU eviction. Runs at most every 256 writes (we
|
|
@@ -8405,15 +8481,15 @@ var ThreadCache = class {
|
|
|
8405
8481
|
if (Math.random() > 1 / 256) return;
|
|
8406
8482
|
let files;
|
|
8407
8483
|
try {
|
|
8408
|
-
files = (0,
|
|
8484
|
+
files = (0, import_node_fs9.readdirSync)(this.dir).filter((f) => f.endsWith(".json"));
|
|
8409
8485
|
} catch {
|
|
8410
8486
|
return;
|
|
8411
8487
|
}
|
|
8412
8488
|
if (files.length <= this.lruCap) return;
|
|
8413
8489
|
const stats = files.map((f) => {
|
|
8414
|
-
const p = (0,
|
|
8490
|
+
const p = (0, import_node_path11.join)(this.dir, f);
|
|
8415
8491
|
try {
|
|
8416
|
-
return { p, mtime: (0,
|
|
8492
|
+
return { p, mtime: (0, import_node_fs9.statSync)(p).mtimeMs };
|
|
8417
8493
|
} catch {
|
|
8418
8494
|
return { p, mtime: 0 };
|
|
8419
8495
|
}
|
|
@@ -8422,7 +8498,7 @@ var ThreadCache = class {
|
|
|
8422
8498
|
const dropCount = Math.max(1, Math.floor(this.lruCap * 0.1));
|
|
8423
8499
|
for (let i = 0; i < dropCount; i++) {
|
|
8424
8500
|
try {
|
|
8425
|
-
(0,
|
|
8501
|
+
(0, import_node_fs9.rmSync)(stats[i].p, { force: true });
|
|
8426
8502
|
} catch {
|
|
8427
8503
|
}
|
|
8428
8504
|
}
|
|
@@ -8441,30 +8517,30 @@ function dedupAndCap(messages, k) {
|
|
|
8441
8517
|
}
|
|
8442
8518
|
|
|
8443
8519
|
// src/threading/agent-memory.ts
|
|
8444
|
-
var
|
|
8445
|
-
var
|
|
8446
|
-
var
|
|
8447
|
-
var MEMORY_DIR_DEFAULT = (0,
|
|
8520
|
+
var import_node_fs10 = require("fs");
|
|
8521
|
+
var import_node_os10 = require("os");
|
|
8522
|
+
var import_node_path12 = require("path");
|
|
8523
|
+
var MEMORY_DIR_DEFAULT = (0, import_node_path12.join)((0, import_node_os10.homedir)(), ".agenticmail", "agent-memory");
|
|
8448
8524
|
var AgentMemoryStore = class {
|
|
8449
8525
|
dir;
|
|
8450
8526
|
constructor(opts = {}) {
|
|
8451
8527
|
this.dir = opts.memoryDir ?? MEMORY_DIR_DEFAULT;
|
|
8452
8528
|
try {
|
|
8453
|
-
(0,
|
|
8529
|
+
(0, import_node_fs10.mkdirSync)(this.dir, { recursive: true });
|
|
8454
8530
|
} catch {
|
|
8455
8531
|
}
|
|
8456
8532
|
}
|
|
8457
8533
|
dirFor(agentId) {
|
|
8458
|
-
return (0,
|
|
8534
|
+
return (0, import_node_path12.join)(this.dir, sanitizeId(agentId));
|
|
8459
8535
|
}
|
|
8460
8536
|
pathFor(agentId, threadId) {
|
|
8461
|
-
return (0,
|
|
8537
|
+
return (0, import_node_path12.join)(this.dirFor(agentId), `${sanitizeId(threadId)}.md`);
|
|
8462
8538
|
}
|
|
8463
8539
|
read(agentId, threadId) {
|
|
8464
8540
|
const p = this.pathFor(agentId, threadId);
|
|
8465
|
-
if (!(0,
|
|
8541
|
+
if (!(0, import_node_fs10.existsSync)(p)) return null;
|
|
8466
8542
|
try {
|
|
8467
|
-
const raw = (0,
|
|
8543
|
+
const raw = (0, import_node_fs10.readFileSync)(p, "utf-8");
|
|
8468
8544
|
const parsed = parse(raw);
|
|
8469
8545
|
return { ...parsed, raw };
|
|
8470
8546
|
} catch {
|
|
@@ -8474,18 +8550,18 @@ var AgentMemoryStore = class {
|
|
|
8474
8550
|
write(agentId, threadId, fields) {
|
|
8475
8551
|
const agentDir = this.dirFor(agentId);
|
|
8476
8552
|
try {
|
|
8477
|
-
(0,
|
|
8553
|
+
(0, import_node_fs10.mkdirSync)(agentDir, { recursive: true });
|
|
8478
8554
|
} catch {
|
|
8479
8555
|
}
|
|
8480
8556
|
const body = render({ ...fields, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
8481
8557
|
const p = this.pathFor(agentId, threadId);
|
|
8482
8558
|
const tmp = `${p}.tmp`;
|
|
8483
|
-
(0,
|
|
8484
|
-
(0,
|
|
8559
|
+
(0, import_node_fs10.writeFileSync)(tmp, body, "utf-8");
|
|
8560
|
+
(0, import_node_fs10.renameSync)(tmp, p);
|
|
8485
8561
|
}
|
|
8486
8562
|
delete(agentId, threadId) {
|
|
8487
8563
|
try {
|
|
8488
|
-
(0,
|
|
8564
|
+
(0, import_node_fs10.rmSync)(this.pathFor(agentId, threadId), { force: true });
|
|
8489
8565
|
} catch {
|
|
8490
8566
|
}
|
|
8491
8567
|
}
|
|
@@ -8550,6 +8626,7 @@ function parse(raw) {
|
|
|
8550
8626
|
CloudflareClient,
|
|
8551
8627
|
DEFAULT_AGENT_NAME,
|
|
8552
8628
|
DEFAULT_AGENT_ROLE,
|
|
8629
|
+
DEFAULT_SESSION_MAX_AGE_MS,
|
|
8553
8630
|
DNSConfigurator,
|
|
8554
8631
|
DependencyChecker,
|
|
8555
8632
|
DependencyInstaller,
|
|
@@ -8586,9 +8663,13 @@ function parse(raw) {
|
|
|
8586
8663
|
ensureDataDir,
|
|
8587
8664
|
extractVerificationCode,
|
|
8588
8665
|
flushTelemetry,
|
|
8666
|
+
forgetHostSession,
|
|
8589
8667
|
getDatabase,
|
|
8668
|
+
hostSessionStoragePath,
|
|
8590
8669
|
isInternalEmail,
|
|
8670
|
+
isSessionFresh,
|
|
8591
8671
|
isValidPhoneNumber,
|
|
8672
|
+
loadHostSession,
|
|
8592
8673
|
normalizeAddress,
|
|
8593
8674
|
normalizePhoneNumber,
|
|
8594
8675
|
normalizeSubject,
|
|
@@ -8601,6 +8682,7 @@ function parse(raw) {
|
|
|
8601
8682
|
safeJoin,
|
|
8602
8683
|
sanitizeEmail,
|
|
8603
8684
|
saveConfig,
|
|
8685
|
+
saveHostSession,
|
|
8604
8686
|
scanOutboundEmail,
|
|
8605
8687
|
scoreEmail,
|
|
8606
8688
|
setTelemetryVersion,
|