@agenticmail/enterprise 0.5.328 → 0.5.329
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/agent-tools-F3CYENMK.js +13949 -0
- package/dist/browser-tool-P57PLVW2.js +4002 -0
- package/dist/chunk-3RI3AIJN.js +1519 -0
- package/dist/chunk-AD4DFKHR.js +4928 -0
- package/dist/chunk-UQXPVWXG.js +5101 -0
- package/dist/cli-agent-K6UFZRXC.js +2473 -0
- package/dist/cli-serve-4MT7RDEL.js +260 -0
- package/dist/cli.js +3 -3
- package/dist/dashboard/HELP-TOOLTIPS-GUIDE.md +45 -0
- package/dist/dashboard/components/transport-encryption.js +0 -62
- package/dist/dashboard/pages/agent-detail/index.js +5 -2
- package/dist/dashboard/pages/agent-detail/manager.js +1 -1
- package/dist/dashboard/pages/agent-detail/overview.js +4 -2
- package/dist/dashboard/pages/agent-detail/tool-security.js +1 -1
- package/dist/dashboard/pages/domain-status.js +3 -6
- package/dist/dashboard/pages/memory-transfer.js +1 -1
- package/dist/dashboard/pages/messages.js +0 -1
- package/dist/dashboard/pages/roles.js +0 -2
- package/dist/dashboard/pages/workforce.js +0 -1
- package/dist/index.js +3 -3
- package/dist/runtime-L5ADJORP.js +45 -0
- package/dist/server-KSN56EZQ.js +28 -0
- package/dist/setup-UUNBBOQH.js +20 -0
- package/logs/cloudflared-error.log +36 -0
- package/logs/enterprise-out.log +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import "./chunk-KFQGP6VL.js";
|
|
2
|
+
|
|
3
|
+
// src/cli-serve.ts
|
|
4
|
+
import { existsSync, readFileSync } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { homedir } from "os";
|
|
7
|
+
function loadEnvFile() {
|
|
8
|
+
const candidates = [
|
|
9
|
+
join(process.cwd(), ".env"),
|
|
10
|
+
join(homedir(), ".agenticmail", ".env")
|
|
11
|
+
];
|
|
12
|
+
for (const envPath of candidates) {
|
|
13
|
+
if (!existsSync(envPath)) continue;
|
|
14
|
+
try {
|
|
15
|
+
const content = readFileSync(envPath, "utf8");
|
|
16
|
+
for (const line of content.split("\n")) {
|
|
17
|
+
const trimmed = line.trim();
|
|
18
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
19
|
+
const eq = trimmed.indexOf("=");
|
|
20
|
+
if (eq < 0) continue;
|
|
21
|
+
const key = trimmed.slice(0, eq).trim();
|
|
22
|
+
let val = trimmed.slice(eq + 1).trim();
|
|
23
|
+
if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
|
|
24
|
+
val = val.slice(1, -1);
|
|
25
|
+
}
|
|
26
|
+
if (!process.env[key]) process.env[key] = val;
|
|
27
|
+
}
|
|
28
|
+
console.log(`Loaded config from ${envPath}`);
|
|
29
|
+
return;
|
|
30
|
+
} catch {
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function ensureSecrets() {
|
|
35
|
+
const { randomUUID } = await import("crypto");
|
|
36
|
+
const envDir = join(homedir(), ".agenticmail");
|
|
37
|
+
const envPath = join(envDir, ".env");
|
|
38
|
+
let dirty = false;
|
|
39
|
+
if (!process.env.JWT_SECRET) {
|
|
40
|
+
process.env.JWT_SECRET = randomUUID() + randomUUID();
|
|
41
|
+
dirty = true;
|
|
42
|
+
console.log("[startup] Generated new JWT_SECRET (existing sessions will need to re-login)");
|
|
43
|
+
}
|
|
44
|
+
if (!process.env.AGENTICMAIL_VAULT_KEY) {
|
|
45
|
+
process.env.AGENTICMAIL_VAULT_KEY = randomUUID() + randomUUID();
|
|
46
|
+
dirty = true;
|
|
47
|
+
console.log("[startup] Generated new AGENTICMAIL_VAULT_KEY");
|
|
48
|
+
console.log("[startup] \u26A0\uFE0F Previously encrypted credentials will need to be re-entered in the dashboard");
|
|
49
|
+
}
|
|
50
|
+
if (dirty) {
|
|
51
|
+
try {
|
|
52
|
+
if (!existsSync(envDir)) {
|
|
53
|
+
const { mkdirSync } = await import("fs");
|
|
54
|
+
mkdirSync(envDir, { recursive: true });
|
|
55
|
+
}
|
|
56
|
+
const { appendFileSync } = await import("fs");
|
|
57
|
+
const lines = [];
|
|
58
|
+
let existing = "";
|
|
59
|
+
if (existsSync(envPath)) {
|
|
60
|
+
existing = readFileSync(envPath, "utf8");
|
|
61
|
+
}
|
|
62
|
+
if (!existing.includes("JWT_SECRET=")) {
|
|
63
|
+
lines.push(`JWT_SECRET=${process.env.JWT_SECRET}`);
|
|
64
|
+
}
|
|
65
|
+
if (!existing.includes("AGENTICMAIL_VAULT_KEY=")) {
|
|
66
|
+
lines.push(`AGENTICMAIL_VAULT_KEY=${process.env.AGENTICMAIL_VAULT_KEY}`);
|
|
67
|
+
}
|
|
68
|
+
if (lines.length) {
|
|
69
|
+
appendFileSync(envPath, "\n" + lines.join("\n") + "\n", { mode: 384 });
|
|
70
|
+
console.log(`[startup] Saved secrets to ${envPath}`);
|
|
71
|
+
}
|
|
72
|
+
} catch (e) {
|
|
73
|
+
console.warn(`[startup] Could not save secrets to ${envPath}: ${e.message}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function runServe(_args) {
|
|
78
|
+
loadEnvFile();
|
|
79
|
+
const DATABASE_URL = process.env.DATABASE_URL;
|
|
80
|
+
const PORT = parseInt(process.env.PORT || "8080", 10);
|
|
81
|
+
await ensureSecrets();
|
|
82
|
+
const JWT_SECRET = process.env.JWT_SECRET;
|
|
83
|
+
const _VAULT_KEY = process.env.AGENTICMAIL_VAULT_KEY;
|
|
84
|
+
if (!DATABASE_URL) {
|
|
85
|
+
console.error("ERROR: DATABASE_URL is required.");
|
|
86
|
+
console.error("");
|
|
87
|
+
console.error("Set it via environment variable or .env file:");
|
|
88
|
+
console.error(" DATABASE_URL=postgresql://user:pass@host:5432/db npx @agenticmail/enterprise start");
|
|
89
|
+
console.error("");
|
|
90
|
+
console.error("Or create a .env file (in cwd or ~/.agenticmail/.env):");
|
|
91
|
+
console.error(" DATABASE_URL=postgresql://user:pass@host:5432/db");
|
|
92
|
+
console.error(" JWT_SECRET=your-secret-here");
|
|
93
|
+
console.error(" PORT=3200");
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
const { createAdapter, smartDbConfig } = await import("./factory-4V2W4BSV.js");
|
|
97
|
+
const { createServer } = await import("./server-KSN56EZQ.js");
|
|
98
|
+
const db = await createAdapter(smartDbConfig(DATABASE_URL));
|
|
99
|
+
await db.migrate();
|
|
100
|
+
const server = createServer({
|
|
101
|
+
port: PORT,
|
|
102
|
+
db,
|
|
103
|
+
jwtSecret: JWT_SECRET,
|
|
104
|
+
corsOrigins: ["*"]
|
|
105
|
+
});
|
|
106
|
+
await server.start();
|
|
107
|
+
console.log(`AgenticMail Enterprise server running on :${PORT}`);
|
|
108
|
+
try {
|
|
109
|
+
const { startPreventSleep } = await import("./screen-unlock-4RPZBHOI.js");
|
|
110
|
+
const adminDb = server.getAdminDb?.() || server.adminDb;
|
|
111
|
+
if (adminDb) {
|
|
112
|
+
const settings = await adminDb.getSettings?.().catch(() => null);
|
|
113
|
+
const screenAccess = settings?.securityConfig?.screenAccess;
|
|
114
|
+
if (screenAccess?.enabled && screenAccess?.preventSleep) {
|
|
115
|
+
startPreventSleep();
|
|
116
|
+
console.log("[startup] Prevent-sleep enabled \u2014 system will stay awake while agents are active");
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
} catch {
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
await setupSystemPersistence();
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.warn("[startup] System persistence setup skipped: " + e.message);
|
|
125
|
+
}
|
|
126
|
+
const tunnelToken = process.env.CLOUDFLARED_TOKEN;
|
|
127
|
+
if (tunnelToken) {
|
|
128
|
+
try {
|
|
129
|
+
const { execSync, spawn } = await import("child_process");
|
|
130
|
+
try {
|
|
131
|
+
execSync("which cloudflared", { timeout: 3e3 });
|
|
132
|
+
} catch {
|
|
133
|
+
console.log("[startup] cloudflared not found \u2014 skipping tunnel auto-start");
|
|
134
|
+
console.log("[startup] Install cloudflared to enable tunnel: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/");
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
execSync('pgrep -f "cloudflared.*tunnel.*run"', { timeout: 3e3 });
|
|
139
|
+
console.log("[startup] cloudflared tunnel already running");
|
|
140
|
+
return;
|
|
141
|
+
} catch {
|
|
142
|
+
}
|
|
143
|
+
const subdomain = process.env.AGENTICMAIL_SUBDOMAIN || process.env.AGENTICMAIL_DOMAIN || "";
|
|
144
|
+
console.log(`[startup] Starting cloudflared tunnel${subdomain ? ` for ${subdomain}.agenticmail.io` : ""}...`);
|
|
145
|
+
const child = spawn("cloudflared", ["tunnel", "--no-autoupdate", "run", "--token", tunnelToken], {
|
|
146
|
+
detached: true,
|
|
147
|
+
stdio: "ignore"
|
|
148
|
+
});
|
|
149
|
+
child.unref();
|
|
150
|
+
console.log("[startup] cloudflared tunnel started (pid " + child.pid + ")");
|
|
151
|
+
} catch (e) {
|
|
152
|
+
console.warn("[startup] Could not auto-start cloudflared: " + e.message);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function setupSystemPersistence() {
|
|
157
|
+
const { execSync, spawnSync } = await import("child_process");
|
|
158
|
+
const { existsSync: exists, writeFileSync, mkdirSync } = await import("fs");
|
|
159
|
+
const { join: pathJoin } = await import("path");
|
|
160
|
+
const platform = process.platform;
|
|
161
|
+
if (!process.env.PM2_HOME && !process.env.pm_id) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const markerDir = pathJoin(homedir(), ".agenticmail");
|
|
165
|
+
const markerFile = pathJoin(markerDir, ".persistence-configured");
|
|
166
|
+
if (exists(markerFile)) {
|
|
167
|
+
try {
|
|
168
|
+
execSync("pm2 save --silent", { timeout: 1e4, stdio: "ignore" });
|
|
169
|
+
} catch {
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
console.log("[startup] Configuring system persistence (one-time setup)...");
|
|
174
|
+
try {
|
|
175
|
+
if (platform === "darwin") {
|
|
176
|
+
const result = spawnSync("pm2", ["startup", "launchd", "--silent"], {
|
|
177
|
+
timeout: 15e3,
|
|
178
|
+
stdio: "pipe",
|
|
179
|
+
encoding: "utf-8"
|
|
180
|
+
});
|
|
181
|
+
const output = (result.stdout || "") + (result.stderr || "");
|
|
182
|
+
const sudoMatch = output.match(/sudo\s+env\s+.*pm2\s+startup.*/);
|
|
183
|
+
if (sudoMatch) {
|
|
184
|
+
console.log("[startup] PM2 startup requires sudo. Run this once:");
|
|
185
|
+
console.log(" " + sudoMatch[0]);
|
|
186
|
+
} else {
|
|
187
|
+
console.log("[startup] PM2 startup configured (launchd)");
|
|
188
|
+
}
|
|
189
|
+
const plistPath = pathJoin(homedir(), "Library", "LaunchAgents", `pm2.${process.env.USER || "user"}.plist`);
|
|
190
|
+
if (exists(plistPath)) {
|
|
191
|
+
try {
|
|
192
|
+
execSync(`launchctl load -w "${plistPath}"`, { timeout: 5e3, stdio: "ignore" });
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
} else if (platform === "linux") {
|
|
197
|
+
const result = spawnSync("pm2", ["startup", "systemd", "--silent"], {
|
|
198
|
+
timeout: 15e3,
|
|
199
|
+
stdio: "pipe",
|
|
200
|
+
encoding: "utf-8"
|
|
201
|
+
});
|
|
202
|
+
const output = (result.stdout || "") + (result.stderr || "");
|
|
203
|
+
const sudoMatch = output.match(/sudo\s+env\s+.*pm2\s+startup.*/);
|
|
204
|
+
if (sudoMatch) {
|
|
205
|
+
try {
|
|
206
|
+
execSync(sudoMatch[0], { timeout: 15e3, stdio: "ignore" });
|
|
207
|
+
console.log("[startup] PM2 startup configured (systemd)");
|
|
208
|
+
} catch {
|
|
209
|
+
console.log("[startup] PM2 startup requires root. Run this once:");
|
|
210
|
+
console.log(" " + sudoMatch[0]);
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
console.log("[startup] PM2 startup configured (systemd)");
|
|
214
|
+
}
|
|
215
|
+
} else if (platform === "win32") {
|
|
216
|
+
try {
|
|
217
|
+
execSync("npm list -g pm2-windows-startup", { timeout: 1e4, stdio: "ignore" });
|
|
218
|
+
} catch {
|
|
219
|
+
console.log("[startup] Installing pm2-windows-startup...");
|
|
220
|
+
try {
|
|
221
|
+
execSync("npm install -g pm2-windows-startup", { timeout: 6e4, stdio: "ignore" });
|
|
222
|
+
execSync("pm2-startup install", { timeout: 15e3, stdio: "ignore" });
|
|
223
|
+
console.log("[startup] PM2 startup configured (Windows Service)");
|
|
224
|
+
} catch (e) {
|
|
225
|
+
console.warn("[startup] Could not install pm2-windows-startup: " + e.message);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
} catch (e) {
|
|
230
|
+
console.warn("[startup] PM2 startup setup: " + e.message);
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
const moduleList = execSync("pm2 ls --silent 2>/dev/null || true", { timeout: 1e4, encoding: "utf-8" });
|
|
234
|
+
if (!moduleList.includes("pm2-logrotate")) {
|
|
235
|
+
console.log("[startup] Installing pm2-logrotate...");
|
|
236
|
+
execSync("pm2 install pm2-logrotate --silent", { timeout: 6e4, stdio: "ignore" });
|
|
237
|
+
execSync("pm2 set pm2-logrotate:max_size 10M --silent", { timeout: 5e3, stdio: "ignore" });
|
|
238
|
+
execSync("pm2 set pm2-logrotate:retain 5 --silent", { timeout: 5e3, stdio: "ignore" });
|
|
239
|
+
execSync("pm2 set pm2-logrotate:compress true --silent", { timeout: 5e3, stdio: "ignore" });
|
|
240
|
+
console.log("[startup] Log rotation configured (10MB, 5 files)");
|
|
241
|
+
}
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
execSync("pm2 save --silent", { timeout: 1e4, stdio: "ignore" });
|
|
246
|
+
console.log("[startup] Process list saved");
|
|
247
|
+
} catch {
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
if (!exists(markerDir)) mkdirSync(markerDir, { recursive: true });
|
|
251
|
+
writeFileSync(markerFile, (/* @__PURE__ */ new Date()).toISOString() + `
|
|
252
|
+
platform=${platform}
|
|
253
|
+
`, { mode: 384 });
|
|
254
|
+
console.log("[startup] System persistence configured successfully");
|
|
255
|
+
} catch {
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
export {
|
|
259
|
+
runServe
|
|
260
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -57,14 +57,14 @@ Skill Development:
|
|
|
57
57
|
break;
|
|
58
58
|
case "serve":
|
|
59
59
|
case "start":
|
|
60
|
-
import("./cli-serve-
|
|
60
|
+
import("./cli-serve-4MT7RDEL.js").then((m) => m.runServe(args.slice(1))).catch(fatal);
|
|
61
61
|
break;
|
|
62
62
|
case "agent":
|
|
63
|
-
import("./cli-agent-
|
|
63
|
+
import("./cli-agent-K6UFZRXC.js").then((m) => m.runAgent(args.slice(1))).catch(fatal);
|
|
64
64
|
break;
|
|
65
65
|
case "setup":
|
|
66
66
|
default:
|
|
67
|
-
import("./setup-
|
|
67
|
+
import("./setup-UUNBBOQH.js").then((m) => m.runSetupWizard()).catch(fatal);
|
|
68
68
|
break;
|
|
69
69
|
}
|
|
70
70
|
function fatal(err) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Help Tooltips Implementation Guide
|
|
2
|
+
|
|
3
|
+
## Pattern
|
|
4
|
+
Use the existing `HelpButton` component from `../components/help-button.js` (or `../../components/help-button.js` for agent-detail).
|
|
5
|
+
|
|
6
|
+
### Import
|
|
7
|
+
```js
|
|
8
|
+
import { HelpButton } from '../components/help-button.js';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Usage
|
|
12
|
+
Add HelpButton next to section titles, card headers, stat labels, and tab headers:
|
|
13
|
+
```js
|
|
14
|
+
h('h3', { style: { display: 'flex', alignItems: 'center' } },
|
|
15
|
+
'Section Title',
|
|
16
|
+
h(HelpButton, { label: 'Section Title' },
|
|
17
|
+
h('p', null, 'Main explanation of what this section does.'),
|
|
18
|
+
h('h4', { style: _h4 }, 'Key Concepts'),
|
|
19
|
+
h('ul', { style: _ul },
|
|
20
|
+
h('li', null, 'Concept 1 explanation'),
|
|
21
|
+
h('li', null, 'Concept 2 explanation'),
|
|
22
|
+
),
|
|
23
|
+
h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Helpful tip here.')
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Style Variables (define at top of render function)
|
|
29
|
+
```js
|
|
30
|
+
var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
|
|
31
|
+
var _ul = { paddingLeft: 20, margin: '4px 0 8px' };
|
|
32
|
+
var _tip = { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 };
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Rules
|
|
36
|
+
1. Add HelpButton to EVERY card header, section title, and stat label
|
|
37
|
+
2. Keep help text concise but useful — explain what it is, why it matters, and how to use it
|
|
38
|
+
3. Include "Tip:" boxes for actionable advice
|
|
39
|
+
4. Use h4 for sub-headings within help modals
|
|
40
|
+
5. Use ul/li for lists of concepts
|
|
41
|
+
6. Don't repeat obvious UI labels — explain the WHY
|
|
42
|
+
7. Reference the existing knowledge-contributions.js page for the gold standard example
|
|
43
|
+
8. Make sure to import HelpButton at the top of each file
|
|
44
|
+
9. DO NOT change any existing functionality — only ADD help tooltips
|
|
45
|
+
10. Test that the file is valid JS after changes (no syntax errors)
|
|
@@ -210,68 +210,6 @@ function isSensitive(url) {
|
|
|
210
210
|
*/
|
|
211
211
|
export function installFetchInterceptor() {
|
|
212
212
|
// No-op — encryption is now handled directly in apiCall
|
|
213
|
-
return;
|
|
214
|
-
if (window.__teInstalled) return;
|
|
215
|
-
window.__teInstalled = true;
|
|
216
|
-
var originalFetch = window.fetch;
|
|
217
|
-
|
|
218
|
-
window.fetch = async function(input, init) {
|
|
219
|
-
if (!_enabled) return originalFetch(input, init);
|
|
220
|
-
|
|
221
|
-
var url = typeof input === 'string' ? input : input.url;
|
|
222
|
-
if (!isSensitive(url)) return originalFetch(input, init);
|
|
223
|
-
|
|
224
|
-
// Add encryption header
|
|
225
|
-
init = init || {};
|
|
226
|
-
init.headers = init.headers || {};
|
|
227
|
-
if (init.headers instanceof Headers) {
|
|
228
|
-
init.headers.set('x-transport-encryption', '1');
|
|
229
|
-
} else {
|
|
230
|
-
init.headers['x-transport-encryption'] = '1';
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// Encrypt request body
|
|
234
|
-
var method = (init.method || 'GET').toUpperCase();
|
|
235
|
-
if ((method === 'POST' || method === 'PUT' || method === 'PATCH') && init.body) {
|
|
236
|
-
try {
|
|
237
|
-
var bodyData = typeof init.body === 'string' ? JSON.parse(init.body) : init.body;
|
|
238
|
-
var encrypted = await encryptPayload(bodyData);
|
|
239
|
-
if (encrypted) {
|
|
240
|
-
init.body = JSON.stringify({ _enc: encrypted });
|
|
241
|
-
if (init.headers instanceof Headers) {
|
|
242
|
-
init.headers.set('content-type', 'application/json');
|
|
243
|
-
} else {
|
|
244
|
-
init.headers['content-type'] = 'application/json';
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
} catch(e) {
|
|
248
|
-
// Fall through — send unencrypted
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
var response = await originalFetch(input, init);
|
|
253
|
-
|
|
254
|
-
// Decrypt response if encrypted
|
|
255
|
-
if (response.headers.get('x-transport-encrypted') === '1') {
|
|
256
|
-
try {
|
|
257
|
-
var resBody = await response.json();
|
|
258
|
-
if (resBody && resBody._enc) {
|
|
259
|
-
var decrypted = await decryptPayload(resBody._enc);
|
|
260
|
-
// Return a new Response with decrypted data
|
|
261
|
-
return new Response(JSON.stringify(decrypted), {
|
|
262
|
-
status: response.status,
|
|
263
|
-
statusText: response.statusText,
|
|
264
|
-
headers: response.headers,
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
} catch(e) {
|
|
268
|
-
// Decryption failed — return original
|
|
269
|
-
return response;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return response;
|
|
274
|
-
};
|
|
275
213
|
}
|
|
276
214
|
|
|
277
215
|
export function isEnabled() { return _enabled; }
|
|
@@ -105,15 +105,17 @@ export function AgentDetailPage(props) {
|
|
|
105
105
|
|
|
106
106
|
// ─── Real-Time Status from Agent Process ────────────────
|
|
107
107
|
var [liveStatus, setLiveStatus] = useState(null);
|
|
108
|
+
var [sseConnected, setSseConnected] = useState(false);
|
|
108
109
|
useEffect(function() {
|
|
109
110
|
var es = new EventSource('/api/engine/agent-status-stream?agentId=' + encodeURIComponent(agentId));
|
|
111
|
+
es.onopen = function() { setSseConnected(true); };
|
|
110
112
|
es.onmessage = function(ev) {
|
|
111
113
|
try {
|
|
112
114
|
var d = JSON.parse(ev.data);
|
|
113
115
|
if (d.type === 'status' && d.agentId === agentId) { setLiveStatus(d); }
|
|
114
116
|
} catch(e) {}
|
|
115
117
|
};
|
|
116
|
-
es.onerror = function() {
|
|
118
|
+
es.onerror = function() { setSseConnected(false); };
|
|
117
119
|
return function() { es.close(); };
|
|
118
120
|
}, [agentId]);
|
|
119
121
|
|
|
@@ -126,7 +128,8 @@ export function AgentDetailPage(props) {
|
|
|
126
128
|
// Prefer live process status over DB state
|
|
127
129
|
var liveState = liveStatus ? liveStatus.status : null;
|
|
128
130
|
var dbState = ea.state || ea.status || a.status || 'unknown';
|
|
129
|
-
|
|
131
|
+
// If SSE connected but no live status yet, show idle instead of DB's stale "running"
|
|
132
|
+
var state = liveState || (sseConnected && dbState === 'running' ? 'idle' : dbState);
|
|
130
133
|
// Map live statuses: online→running, idle→idle, offline→stopped, error→error
|
|
131
134
|
if (state === 'online') state = 'running';
|
|
132
135
|
if (state === 'idle') state = 'idle';
|
|
@@ -264,7 +264,7 @@ export function ManagerCatchUpSection(props) {
|
|
|
264
264
|
)
|
|
265
265
|
),
|
|
266
266
|
|
|
267
|
-
form.catchUpEnabled &&
|
|
267
|
+
form.catchUpEnabled && form.managerType === 'none' && h('div', {
|
|
268
268
|
style: { padding: '10px 14px', background: 'var(--warning-soft, #fff3cd)', borderRadius: 6, fontSize: 13, color: 'var(--warning-text, #856404)', marginTop: 12 }
|
|
269
269
|
}, 'Note: Catch-up is enabled but no manager is assigned. The agent won\'t have anyone to report to.')
|
|
270
270
|
)
|
|
@@ -165,8 +165,10 @@ export function OverviewSection(props) {
|
|
|
165
165
|
var agentModel = typeof config.model === 'string' ? config.model : (config.model ? (config.model.modelId || config.model.provider || 'unknown') : 'unknown');
|
|
166
166
|
var agentDesc = identity.description || config.description || '';
|
|
167
167
|
var createdAt = engineAgent?.createdAt || engineAgent?.created_at || agent?.createdAt;
|
|
168
|
-
var
|
|
169
|
-
|
|
168
|
+
var dbState = engineAgent?.state || engineAgent?.status || agent?.status || 'unknown';
|
|
169
|
+
// Prefer live SSE status over stale DB state
|
|
170
|
+
var agentState = rtStatus ? (rtStatus.status === 'online' ? 'running' : rtStatus.status === 'idle' ? 'idle' : rtStatus.status === 'offline' ? 'stopped' : rtStatus.status) : dbState;
|
|
171
|
+
var stateColor = { running: 'success', active: 'success', idle: 'info', deploying: 'info', starting: 'info', ready: 'primary', degraded: 'warning', error: 'danger', stopped: 'neutral', draft: 'neutral' }[agentState] || 'neutral';
|
|
170
172
|
var resolvedMgr = resolveManager(config, props.agents);
|
|
171
173
|
var managerName = resolvedMgr ? resolvedMgr.name : null;
|
|
172
174
|
var managerEmail = resolvedMgr && resolvedMgr.type === 'external' ? resolvedMgr.email : null;
|
|
@@ -200,7 +200,7 @@ export function ToolSecuritySection(props) {
|
|
|
200
200
|
};
|
|
201
201
|
|
|
202
202
|
var resetAll = function() {
|
|
203
|
-
showConfirm('Reset to Org Defaults', 'This will remove all agent-level tool security overrides and revert to the organization defaults. Continue?'
|
|
203
|
+
showConfirm({title: 'Reset to Org Defaults', message: 'This will remove all agent-level tool security overrides and revert to the organization defaults. Continue?'}).then(function() {
|
|
204
204
|
setSaving(true);
|
|
205
205
|
engineCall('/agents/' + agentId + '/tool-security', {
|
|
206
206
|
method: 'PATCH',
|
|
@@ -87,7 +87,7 @@ export function DomainStatusPage() {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
if (data && data.domain && data.status === 'verified') {
|
|
90
|
-
showConfirm('Change Domain', 'You are changing your verified domain from "' + data.domain + '" to "' + d + '". You will need to re-verify DNS. Continue?').then(function(ok) { if (ok) doRegister(); });
|
|
90
|
+
showConfirm({title: 'Change Domain', message: 'You are changing your verified domain from "' + data.domain + '" to "' + d + '". You will need to re-verify DNS. Continue?'}).then(function(ok) { if (ok) doRegister(); });
|
|
91
91
|
} else {
|
|
92
92
|
doRegister();
|
|
93
93
|
}
|
|
@@ -127,10 +127,7 @@ export function DomainStatusPage() {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
if (isActive) {
|
|
130
|
-
showConfirm(
|
|
131
|
-
'Change Active Subdomain',
|
|
132
|
-
'You are currently accessing this dashboard from "' + oldSub + '.agenticmail.io". Changing the subdomain will NOT automatically redirect traffic to the new URL.\n\nYou will need to:\n1. Update DNS records to point "' + s + '.agenticmail.io" to your server\n2. Update any bookmarks, integrations, or agent configs that reference the old URL\n3. Access the dashboard from the new URL after DNS propagates\n\nThe old URL will stop working once DNS is updated. Continue?'
|
|
133
|
-
).then(function(ok) { if (ok) doSave(); });
|
|
130
|
+
showConfirm({title: 'Change Active Subdomain', message: 'You are currently accessing this dashboard from "' + oldSub + '.agenticmail.io". Changing the subdomain will NOT automatically redirect traffic to the new URL.\n\nYou will need to:\n1. Update DNS records to point "' + s + '.agenticmail.io" to your server\n2. Update any bookmarks, integrations, or agent configs that reference the old URL\n3. Access the dashboard from the new URL after DNS propagates\n\nThe old URL will stop working once DNS is updated. Continue?'}).then(function(ok) { if (ok) doSave(); });
|
|
134
131
|
} else {
|
|
135
132
|
doSave();
|
|
136
133
|
}
|
|
@@ -138,7 +135,7 @@ export function DomainStatusPage() {
|
|
|
138
135
|
|
|
139
136
|
// ─── Remove Domain ─────────────────────────────────
|
|
140
137
|
var removeDomain = useCallback(function() {
|
|
141
|
-
showConfirm('Remove Custom Domain', 'This will remove "' + data.domain + '" from your deployment. Your domain registration and DNS verification will be cleared. Continue?').then(function(ok) {
|
|
138
|
+
showConfirm({title: 'Remove Custom Domain', message: 'This will remove "' + data.domain + '" from your deployment. Your domain registration and DNS verification will be cleared. Continue?'}).then(function(ok) {
|
|
142
139
|
if (!ok) return;
|
|
143
140
|
apiCall('/domain', { method: 'DELETE' })
|
|
144
141
|
.then(function() {
|
|
@@ -235,7 +235,7 @@ export function MemoryTransferPage() {
|
|
|
235
235
|
|
|
236
236
|
// ─── Render ──────────────────────────────────────────
|
|
237
237
|
|
|
238
|
-
var tabStyle = function(t) { return { padding: '8px 16px', fontSize: 13, fontWeight: 600, cursor: 'pointer',
|
|
238
|
+
var tabStyle = function(t) { return { padding: '8px 16px', fontSize: 13, fontWeight: 600, cursor: 'pointer', color: tab === t ? 'var(--accent)' : 'var(--text-secondary)', background: 'none', border: 'none', borderBottom: tab === t ? '2px solid var(--accent)' : '2px solid transparent' }; };
|
|
239
239
|
|
|
240
240
|
return h('div', { style: { padding: 0 } },
|
|
241
241
|
// Header
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { h, useState, useEffect, useRef, Fragment, useApp, engineCall, buildAgentEmailMap, resolveAgentEmail, buildAgentDataMap, renderAgentBadge, getOrgId , apiCall } from '../components/utils.js';
|
|
2
1
|
import { I } from '../components/icons.js';
|
|
3
2
|
import { E } from '../assets/icons/emoji-icons.js';
|
|
4
3
|
import { HelpButton } from '../components/help-button.js';
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall } from '../components/utils.js';
|
|
2
2
|
import { I } from '../components/icons.js';
|
|
3
|
-
import { E } from '../assets/icons/emoji-icons.js';
|
|
4
3
|
import { Modal } from '../components/modal.js';
|
|
5
4
|
import { HelpButton } from '../components/help-button.js';
|
|
6
5
|
import { KnowledgeLink } from '../components/knowledge-link.js';
|
|
7
6
|
import { useOrgContext } from '../components/org-switcher.js';
|
|
8
|
-
import { LANGUAGES, getLanguageName, LanguageSelect, ROLE_TAGS, TagPicker } from '../components/persona-fields.js';
|
|
9
7
|
|
|
10
8
|
var engineCall = function(path, opts) { return apiCall('/engine' + path, opts); };
|
|
11
9
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { h, useState, useEffect, useCallback, Fragment, useApp, engineCall, buildAgentEmailMap, resolveAgentEmail, buildAgentDataMap, renderAgentBadge, getOrgId , apiCall } from '../components/utils.js';
|
|
2
1
|
import { I } from '../components/icons.js';
|
|
3
2
|
import { TimezoneSelect } from '../components/timezones.js';
|
|
4
3
|
import { DetailModal } from '../components/modal.js';
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
provision,
|
|
15
15
|
runSetupWizard
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-3RI3AIJN.js";
|
|
17
17
|
import {
|
|
18
18
|
AgentRuntime,
|
|
19
19
|
EmailChannel,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
executeTool,
|
|
29
29
|
runAgentLoop,
|
|
30
30
|
toolsToDefinitions
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-AD4DFKHR.js";
|
|
32
32
|
import {
|
|
33
33
|
ValidationError,
|
|
34
34
|
auditLogger,
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
requireRole,
|
|
43
43
|
securityHeaders,
|
|
44
44
|
validate
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-UQXPVWXG.js";
|
|
46
46
|
import "./chunk-DJBCRQTD.js";
|
|
47
47
|
import {
|
|
48
48
|
PROVIDER_REGISTRY,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentRuntime,
|
|
3
|
+
EmailChannel,
|
|
4
|
+
FollowUpScheduler,
|
|
5
|
+
SessionManager,
|
|
6
|
+
SubAgentManager,
|
|
7
|
+
ToolRegistry,
|
|
8
|
+
callLLM,
|
|
9
|
+
createAgentRuntime,
|
|
10
|
+
createNoopHooks,
|
|
11
|
+
createRuntimeHooks,
|
|
12
|
+
estimateMessageTokens,
|
|
13
|
+
estimateTokens,
|
|
14
|
+
executeTool,
|
|
15
|
+
runAgentLoop,
|
|
16
|
+
toolsToDefinitions
|
|
17
|
+
} from "./chunk-AD4DFKHR.js";
|
|
18
|
+
import {
|
|
19
|
+
PROVIDER_REGISTRY,
|
|
20
|
+
listAllProviders,
|
|
21
|
+
resolveApiKeyForProvider,
|
|
22
|
+
resolveProvider
|
|
23
|
+
} from "./chunk-UF3ZJMJO.js";
|
|
24
|
+
import "./chunk-KFQGP6VL.js";
|
|
25
|
+
export {
|
|
26
|
+
AgentRuntime,
|
|
27
|
+
EmailChannel,
|
|
28
|
+
FollowUpScheduler,
|
|
29
|
+
PROVIDER_REGISTRY,
|
|
30
|
+
SessionManager,
|
|
31
|
+
SubAgentManager,
|
|
32
|
+
ToolRegistry,
|
|
33
|
+
callLLM,
|
|
34
|
+
createAgentRuntime,
|
|
35
|
+
createNoopHooks,
|
|
36
|
+
createRuntimeHooks,
|
|
37
|
+
estimateMessageTokens,
|
|
38
|
+
estimateTokens,
|
|
39
|
+
executeTool,
|
|
40
|
+
listAllProviders,
|
|
41
|
+
resolveApiKeyForProvider,
|
|
42
|
+
resolveProvider,
|
|
43
|
+
runAgentLoop,
|
|
44
|
+
toolsToDefinitions
|
|
45
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createServer
|
|
3
|
+
} from "./chunk-UQXPVWXG.js";
|
|
4
|
+
import "./chunk-DJBCRQTD.js";
|
|
5
|
+
import "./chunk-UF3ZJMJO.js";
|
|
6
|
+
import "./chunk-DWHJYAV6.js";
|
|
7
|
+
import "./chunk-Z7NVD3OQ.js";
|
|
8
|
+
import "./chunk-VSBC4SWO.js";
|
|
9
|
+
import "./chunk-AF3WSNVX.js";
|
|
10
|
+
import "./chunk-74ZCQKYU.js";
|
|
11
|
+
import "./chunk-Z6K5FKAB.js";
|
|
12
|
+
import "./chunk-C6JP5NR6.js";
|
|
13
|
+
import "./chunk-WYDVMFGJ.js";
|
|
14
|
+
import "./chunk-3UAFHUEC.js";
|
|
15
|
+
import "./chunk-NOAQG5CY.js";
|
|
16
|
+
import "./chunk-LHQP7QRX.js";
|
|
17
|
+
import "./chunk-YDD5TC5Q.js";
|
|
18
|
+
import "./chunk-37ABTUFU.js";
|
|
19
|
+
import "./chunk-NU657BBQ.js";
|
|
20
|
+
import "./chunk-PGAU3W3M.js";
|
|
21
|
+
import "./chunk-FLQ5FLHW.js";
|
|
22
|
+
import "./chunk-WUAWWKTN.js";
|
|
23
|
+
import "./chunk-ZGYVXYQQ.js";
|
|
24
|
+
import "./chunk-22U7TZPN.js";
|
|
25
|
+
import "./chunk-KFQGP6VL.js";
|
|
26
|
+
export {
|
|
27
|
+
createServer
|
|
28
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
promptCompanyInfo,
|
|
3
|
+
promptDatabase,
|
|
4
|
+
promptDeployment,
|
|
5
|
+
promptDomain,
|
|
6
|
+
promptRegistration,
|
|
7
|
+
provision,
|
|
8
|
+
runSetupWizard
|
|
9
|
+
} from "./chunk-3RI3AIJN.js";
|
|
10
|
+
import "./chunk-PAHT4ABL.js";
|
|
11
|
+
import "./chunk-KFQGP6VL.js";
|
|
12
|
+
export {
|
|
13
|
+
promptCompanyInfo,
|
|
14
|
+
promptDatabase,
|
|
15
|
+
promptDeployment,
|
|
16
|
+
promptDomain,
|
|
17
|
+
promptRegistration,
|
|
18
|
+
provision,
|
|
19
|
+
runSetupWizard
|
|
20
|
+
};
|