@integrity-labs/agt-cli 0.15.22 → 0.15.27
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/bin/agt.js +7 -3
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-ZUQ7SIVT.js → chunk-4DJTQWSS.js} +79 -2
- package/dist/{chunk-ZUQ7SIVT.js.map → chunk-4DJTQWSS.js.map} +1 -1
- package/dist/{claude-pair-runtime-QS2WC6XZ.js → claude-pair-runtime-VXNC2VEX.js} +11 -48
- package/dist/claude-pair-runtime-VXNC2VEX.js.map +1 -0
- package/dist/lib/manager-worker.js +2 -5
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/manager-supervisor-HKN2GL7L.js +314 -0
- package/dist/manager-supervisor-HKN2GL7L.js.map +1 -0
- package/mcp/slack-channel.js +383 -208
- package/mcp/telegram-channel.js +359 -206
- package/package.json +1 -1
- package/dist/claude-pair-runtime-QS2WC6XZ.js.map +0 -1
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
// src/lib/manager-supervisor.ts
|
|
2
|
+
import { execFileSync } from "child_process";
|
|
3
|
+
import {
|
|
4
|
+
existsSync,
|
|
5
|
+
mkdirSync,
|
|
6
|
+
readFileSync,
|
|
7
|
+
unlinkSync,
|
|
8
|
+
writeFileSync,
|
|
9
|
+
chmodSync
|
|
10
|
+
} from "fs";
|
|
11
|
+
import { homedir, platform } from "os";
|
|
12
|
+
import { dirname, join } from "path";
|
|
13
|
+
var MACOS_LABEL = "team.augmented.agt-manager";
|
|
14
|
+
var MACOS_PLIST = join(homedir(), "Library", "LaunchAgents", `${MACOS_LABEL}.plist`);
|
|
15
|
+
var LINUX_UNIT_NAME = "agt-manager.service";
|
|
16
|
+
var LINUX_UNIT_PATH = join(homedir(), ".config", "systemd", "user", LINUX_UNIT_NAME);
|
|
17
|
+
async function installSupervisor(opts) {
|
|
18
|
+
switch (platform()) {
|
|
19
|
+
case "darwin":
|
|
20
|
+
return installMacos(opts);
|
|
21
|
+
case "linux":
|
|
22
|
+
return installLinux(opts);
|
|
23
|
+
default:
|
|
24
|
+
return { ok: false, error: `Unsupported platform: ${platform()}. Supervisor install is macOS / Linux only.` };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function uninstallSupervisor() {
|
|
28
|
+
switch (platform()) {
|
|
29
|
+
case "darwin":
|
|
30
|
+
return uninstallMacos();
|
|
31
|
+
case "linux":
|
|
32
|
+
return uninstallLinux();
|
|
33
|
+
default:
|
|
34
|
+
return { ok: false, error: `Unsupported platform: ${platform()}. Supervisor uninstall is macOS / Linux only.` };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function supervisorStatus() {
|
|
38
|
+
switch (platform()) {
|
|
39
|
+
case "darwin":
|
|
40
|
+
return statusMacos();
|
|
41
|
+
case "linux":
|
|
42
|
+
return statusLinux();
|
|
43
|
+
default:
|
|
44
|
+
return { kind: "unsupported-platform", platform: platform() };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function installMacos(opts) {
|
|
48
|
+
if (!existsSync(opts.agtBin)) {
|
|
49
|
+
return { ok: false, error: `agt binary not found at ${opts.agtBin}` };
|
|
50
|
+
}
|
|
51
|
+
if (opts.intervalSec < 5) {
|
|
52
|
+
return { ok: false, error: "intervalSec must be >= 5" };
|
|
53
|
+
}
|
|
54
|
+
if (!opts.env.AGT_HOST || !opts.env.AGT_API_KEY) {
|
|
55
|
+
return { ok: false, error: "AGT_HOST and AGT_API_KEY must be set in the calling shell so the supervisor can pass them to the manager. Run `agt setup <token>` first." };
|
|
56
|
+
}
|
|
57
|
+
bestEffort(() => execFileSync("launchctl", ["unload", "-w", MACOS_PLIST], { stdio: "ignore" }));
|
|
58
|
+
mkdirSync(dirname(MACOS_PLIST), { recursive: true });
|
|
59
|
+
writeFileSync(MACOS_PLIST, renderMacosPlist(opts), { mode: 384 });
|
|
60
|
+
chmodSync(MACOS_PLIST, 384);
|
|
61
|
+
try {
|
|
62
|
+
execFileSync("launchctl", ["load", "-w", MACOS_PLIST], { stdio: "pipe" });
|
|
63
|
+
} catch (err) {
|
|
64
|
+
return { ok: false, error: `launchctl load failed: ${err.message}` };
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const out = execFileSync("launchctl", ["list", MACOS_LABEL], { encoding: "utf-8" });
|
|
68
|
+
return {
|
|
69
|
+
ok: true,
|
|
70
|
+
details: `Loaded launchd LaunchAgent ${MACOS_LABEL}. Logs: ${join(opts.configDir, "manager.log")}.
|
|
71
|
+
${out.trim().split("\n").slice(0, 10).join("\n")}`
|
|
72
|
+
};
|
|
73
|
+
} catch (err) {
|
|
74
|
+
return { ok: false, error: `Plist written but launchctl list reported nothing for ${MACOS_LABEL}: ${err.message}` };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function uninstallMacos() {
|
|
78
|
+
bestEffort(() => execFileSync("launchctl", ["unload", "-w", MACOS_PLIST], { stdio: "ignore" }));
|
|
79
|
+
let removed = false;
|
|
80
|
+
if (existsSync(MACOS_PLIST)) {
|
|
81
|
+
try {
|
|
82
|
+
unlinkSync(MACOS_PLIST);
|
|
83
|
+
removed = true;
|
|
84
|
+
} catch (err) {
|
|
85
|
+
return { ok: false, error: `Failed to remove ${MACOS_PLIST}: ${err.message}` };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
ok: true,
|
|
90
|
+
details: removed ? `Removed ${MACOS_LABEL} from launchd and deleted ${MACOS_PLIST}.` : `${MACOS_LABEL} was already uninstalled (no plist at ${MACOS_PLIST}).`
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function statusMacos() {
|
|
94
|
+
if (!existsSync(MACOS_PLIST)) return { kind: "not-installed" };
|
|
95
|
+
try {
|
|
96
|
+
const out = execFileSync("launchctl", ["list", MACOS_LABEL], { encoding: "utf-8" });
|
|
97
|
+
const pidMatch = /"PID"\s*=\s*(\d+);/.exec(out);
|
|
98
|
+
const pid = pidMatch ? Number(pidMatch[1]) : null;
|
|
99
|
+
return { kind: "installed", pid, details: `Plist: ${MACOS_PLIST}` };
|
|
100
|
+
} catch {
|
|
101
|
+
return { kind: "not-installed" };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function renderMacosPlist(opts) {
|
|
105
|
+
const envEntries = Object.entries(opts.env).filter(([k, v]) => k.length > 0 && v != null).map(([k, v]) => ` <key>${escapeXml(k)}</key>
|
|
106
|
+
<string>${escapeXml(v)}</string>`).join("\n");
|
|
107
|
+
const args = [
|
|
108
|
+
"manager",
|
|
109
|
+
"start",
|
|
110
|
+
"--interval",
|
|
111
|
+
String(opts.intervalSec),
|
|
112
|
+
"--config-dir",
|
|
113
|
+
opts.configDir
|
|
114
|
+
];
|
|
115
|
+
const argsXml = args.map((a) => ` <string>${escapeXml(a)}</string>`).join("\n");
|
|
116
|
+
const logPath = join(opts.configDir, "manager.log");
|
|
117
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
118
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
119
|
+
<plist version="1.0">
|
|
120
|
+
<dict>
|
|
121
|
+
<key>Label</key>
|
|
122
|
+
<string>${MACOS_LABEL}</string>
|
|
123
|
+
|
|
124
|
+
<key>ProgramArguments</key>
|
|
125
|
+
<array>
|
|
126
|
+
<string>${escapeXml(opts.agtBin)}</string>
|
|
127
|
+
${argsXml}
|
|
128
|
+
</array>
|
|
129
|
+
|
|
130
|
+
<key>RunAtLoad</key>
|
|
131
|
+
<true/>
|
|
132
|
+
|
|
133
|
+
<key>KeepAlive</key>
|
|
134
|
+
<true/>
|
|
135
|
+
|
|
136
|
+
<!-- Throttle restarts so a crashloop doesn't peg the CPU. 10 seconds
|
|
137
|
+
between launches is enough room for transient API blips while
|
|
138
|
+
still recovering quickly from a real crash. -->
|
|
139
|
+
<key>ThrottleInterval</key>
|
|
140
|
+
<integer>10</integer>
|
|
141
|
+
|
|
142
|
+
<!-- Where the manager's stdout / stderr land. The manager's logger
|
|
143
|
+
redirects stderr into manager.log itself, but launchd needs an
|
|
144
|
+
explicit destination at the OS level for any pre-logger output
|
|
145
|
+
(e.g., Node startup errors before the watchdog wires up). -->
|
|
146
|
+
<key>StandardOutPath</key>
|
|
147
|
+
<string>${escapeXml(logPath)}</string>
|
|
148
|
+
<key>StandardErrorPath</key>
|
|
149
|
+
<string>${escapeXml(logPath)}</string>
|
|
150
|
+
|
|
151
|
+
<key>WorkingDirectory</key>
|
|
152
|
+
<string>${escapeXml(opts.configDir)}</string>
|
|
153
|
+
|
|
154
|
+
<key>EnvironmentVariables</key>
|
|
155
|
+
<dict>
|
|
156
|
+
${envEntries}
|
|
157
|
+
</dict>
|
|
158
|
+
</dict>
|
|
159
|
+
</plist>
|
|
160
|
+
`;
|
|
161
|
+
}
|
|
162
|
+
function bestEffort(fn) {
|
|
163
|
+
try {
|
|
164
|
+
fn();
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function escapeXml(s) {
|
|
169
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
170
|
+
}
|
|
171
|
+
function installLinux(opts) {
|
|
172
|
+
if (!existsSync(opts.agtBin)) {
|
|
173
|
+
return { ok: false, error: `agt binary not found at ${opts.agtBin}` };
|
|
174
|
+
}
|
|
175
|
+
if (opts.intervalSec < 5) {
|
|
176
|
+
return { ok: false, error: "intervalSec must be >= 5" };
|
|
177
|
+
}
|
|
178
|
+
if (!opts.env.AGT_HOST || !opts.env.AGT_API_KEY) {
|
|
179
|
+
return { ok: false, error: "AGT_HOST and AGT_API_KEY must be set in the calling shell so the supervisor can pass them to the unit. Run `agt setup <token>` first." };
|
|
180
|
+
}
|
|
181
|
+
bestEffort(() => execFileSync("systemctl", ["--user", "stop", LINUX_UNIT_NAME], { stdio: "ignore" }));
|
|
182
|
+
mkdirSync(dirname(LINUX_UNIT_PATH), { recursive: true, mode: 448 });
|
|
183
|
+
writeFileSync(LINUX_UNIT_PATH, renderLinuxUnit(opts), { mode: 384 });
|
|
184
|
+
chmodSync(LINUX_UNIT_PATH, 384);
|
|
185
|
+
try {
|
|
186
|
+
execFileSync("systemctl", ["--user", "daemon-reload"], { stdio: "pipe" });
|
|
187
|
+
} catch (err) {
|
|
188
|
+
return { ok: false, error: `systemctl --user daemon-reload failed: ${err.message}` };
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
execFileSync("systemctl", ["--user", "enable", "--now", LINUX_UNIT_NAME], { stdio: "pipe" });
|
|
192
|
+
} catch (err) {
|
|
193
|
+
return { ok: false, error: `systemctl --user enable --now failed: ${err.message}. (Hint: 'systemctl --user' requires a per-user dbus session; on a fresh SSH login try 'export XDG_RUNTIME_DIR=/run/user/$(id -u)' first.)` };
|
|
194
|
+
}
|
|
195
|
+
let isActive = "";
|
|
196
|
+
try {
|
|
197
|
+
isActive = execFileSync("systemctl", ["--user", "is-active", LINUX_UNIT_NAME], { encoding: "utf-8" }).trim();
|
|
198
|
+
} catch (err) {
|
|
199
|
+
isActive = (err.stdout?.toString() ?? "").trim() || "unknown";
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
ok: true,
|
|
203
|
+
details: `Loaded systemd --user unit ${LINUX_UNIT_NAME} (status: ${isActive}). Logs: ${join(opts.configDir, "manager.log")}.
|
|
204
|
+
For reboot survival on a headless host run as root: 'loginctl enable-linger ${process.env["USER"] ?? "<your-user>"}'`
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function uninstallLinux() {
|
|
208
|
+
bestEffort(() => execFileSync("systemctl", ["--user", "disable", "--now", LINUX_UNIT_NAME], { stdio: "ignore" }));
|
|
209
|
+
let removed = false;
|
|
210
|
+
if (existsSync(LINUX_UNIT_PATH)) {
|
|
211
|
+
try {
|
|
212
|
+
unlinkSync(LINUX_UNIT_PATH);
|
|
213
|
+
removed = true;
|
|
214
|
+
} catch (err) {
|
|
215
|
+
return { ok: false, error: `Failed to remove ${LINUX_UNIT_PATH}: ${err.message}` };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
bestEffort(() => execFileSync("systemctl", ["--user", "daemon-reload"], { stdio: "ignore" }));
|
|
219
|
+
return {
|
|
220
|
+
ok: true,
|
|
221
|
+
details: removed ? `Disabled systemd --user unit ${LINUX_UNIT_NAME} and deleted ${LINUX_UNIT_PATH}.` : `${LINUX_UNIT_NAME} was already uninstalled (no unit file at ${LINUX_UNIT_PATH}).`
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function statusLinux() {
|
|
225
|
+
if (!existsSync(LINUX_UNIT_PATH)) return { kind: "not-installed" };
|
|
226
|
+
let pid = null;
|
|
227
|
+
let activeState = "unknown";
|
|
228
|
+
try {
|
|
229
|
+
const out = execFileSync(
|
|
230
|
+
"systemctl",
|
|
231
|
+
["--user", "show", LINUX_UNIT_NAME, "--property=MainPID,ActiveState"],
|
|
232
|
+
{ encoding: "utf-8" }
|
|
233
|
+
);
|
|
234
|
+
const pidMatch = /^MainPID=(\d+)/m.exec(out);
|
|
235
|
+
if (pidMatch && pidMatch[1] !== "0") pid = Number(pidMatch[1]);
|
|
236
|
+
const stateMatch = /^ActiveState=(\S+)/m.exec(out);
|
|
237
|
+
if (stateMatch) activeState = stateMatch[1] ?? "unknown";
|
|
238
|
+
} catch {
|
|
239
|
+
return { kind: "not-installed" };
|
|
240
|
+
}
|
|
241
|
+
return { kind: "installed", pid, details: `Unit: ${LINUX_UNIT_PATH} (${activeState})` };
|
|
242
|
+
}
|
|
243
|
+
function renderLinuxUnit(opts) {
|
|
244
|
+
const envLines = Object.entries(opts.env).filter(([k, v]) => k.length > 0 && v != null).map(([k, v]) => `Environment="${k}=${escapeForSystemdEnv(v)}"`).join("\n");
|
|
245
|
+
const execArgs = [
|
|
246
|
+
opts.agtBin,
|
|
247
|
+
"manager",
|
|
248
|
+
"start",
|
|
249
|
+
"--interval",
|
|
250
|
+
String(opts.intervalSec),
|
|
251
|
+
"--config-dir",
|
|
252
|
+
opts.configDir
|
|
253
|
+
].map(shellQuoteForSystemd).join(" ");
|
|
254
|
+
const logPath = join(opts.configDir, "manager.log");
|
|
255
|
+
return `# agt manager supervisor (ENG-4593)
|
|
256
|
+
# Managed by \`agt manager install\` \u2014 edits will be overwritten.
|
|
257
|
+
|
|
258
|
+
[Unit]
|
|
259
|
+
Description=Augmented host manager daemon
|
|
260
|
+
After=network-online.target
|
|
261
|
+
Wants=network-online.target
|
|
262
|
+
|
|
263
|
+
[Service]
|
|
264
|
+
Type=simple
|
|
265
|
+
WorkingDirectory=${opts.configDir}
|
|
266
|
+
${envLines}
|
|
267
|
+
ExecStart=${execArgs}
|
|
268
|
+
|
|
269
|
+
# Restart policy \u2014 always come back, with throttling so a crashloop
|
|
270
|
+
# can't peg the CPU. StartLimitBurst/IntervalSec follow systemd's
|
|
271
|
+
# defaults but are stated explicitly so future operators don't have
|
|
272
|
+
# to read the man page to understand the recovery envelope.
|
|
273
|
+
Restart=always
|
|
274
|
+
RestartSec=5
|
|
275
|
+
StartLimitBurst=5
|
|
276
|
+
StartLimitIntervalSec=60
|
|
277
|
+
|
|
278
|
+
# stdout/stderr \u2192 manager.log. journalctl --user -u agt-manager
|
|
279
|
+
# still captures everything; this just gives operators a single file
|
|
280
|
+
# to tail without learning systemd plumbing.
|
|
281
|
+
StandardOutput=append:${logPath}
|
|
282
|
+
StandardError=append:${logPath}
|
|
283
|
+
|
|
284
|
+
[Install]
|
|
285
|
+
WantedBy=default.target
|
|
286
|
+
`;
|
|
287
|
+
}
|
|
288
|
+
function escapeForSystemdEnv(value) {
|
|
289
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
290
|
+
}
|
|
291
|
+
function shellQuoteForSystemd(arg) {
|
|
292
|
+
if (/^[A-Za-z0-9_./:=-]+$/.test(arg)) return arg;
|
|
293
|
+
return `"${arg.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
294
|
+
}
|
|
295
|
+
var _internals = {
|
|
296
|
+
MACOS_LABEL,
|
|
297
|
+
MACOS_PLIST,
|
|
298
|
+
LINUX_UNIT_NAME,
|
|
299
|
+
LINUX_UNIT_PATH,
|
|
300
|
+
renderMacosPlist,
|
|
301
|
+
renderLinuxUnit,
|
|
302
|
+
escapeXml,
|
|
303
|
+
escapeForSystemdEnv,
|
|
304
|
+
shellQuoteForSystemd,
|
|
305
|
+
readPlist: () => existsSync(MACOS_PLIST) ? readFileSync(MACOS_PLIST, "utf-8") : null,
|
|
306
|
+
readUnit: () => existsSync(LINUX_UNIT_PATH) ? readFileSync(LINUX_UNIT_PATH, "utf-8") : null
|
|
307
|
+
};
|
|
308
|
+
export {
|
|
309
|
+
_internals,
|
|
310
|
+
installSupervisor,
|
|
311
|
+
supervisorStatus,
|
|
312
|
+
uninstallSupervisor
|
|
313
|
+
};
|
|
314
|
+
//# sourceMappingURL=manager-supervisor-HKN2GL7L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/manager-supervisor.ts"],"sourcesContent":["/**\n * OS-level supervision for the agt manager daemon (ENG-4593).\n *\n * Hands manager lifecycle off to the OS so a missing process is the OS's\n * problem, not ours. Replaces the in-process `agt manager start\n * --supervise` wrapper from ENG-4488.\n *\n * macOS: launchd LaunchAgent (KeepAlive=true + ThrottleInterval=10)\n * Linux: systemd --user unit (Restart=always + RestartSec=5) [Phase 2]\n *\n * Public surface:\n * - installSupervisor(opts) — write the unit, load/enable it, verify\n * - uninstallSupervisor() — unload/disable + remove the unit (idempotent)\n * - supervisorStatus() — quick readout of whether the OS knows about us\n *\n * Each platform implementation lives in its own helper. The dispatcher\n * picks one based on `process.platform` and rejects unsupported OSes\n * with a clear error rather than silently no-oping.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n unlinkSync,\n writeFileSync,\n chmodSync,\n} from 'node:fs';\nimport { homedir, platform } from 'node:os';\nimport { dirname, join } from 'node:path';\n\n// macOS LaunchAgent label and on-disk path. Stable so install/uninstall\n// can find each other without a state file.\nconst MACOS_LABEL = 'team.augmented.agt-manager';\nconst MACOS_PLIST = join(homedir(), 'Library', 'LaunchAgents', `${MACOS_LABEL}.plist`);\n\n// Linux systemd --user unit. Lives under the operator's XDG config so it\n// survives reboot only after `loginctl enable-linger` (we surface that as\n// a follow-up step rather than running it ourselves — needs root).\nconst LINUX_UNIT_NAME = 'agt-manager.service';\nconst LINUX_UNIT_PATH = join(homedir(), '.config', 'systemd', 'user', LINUX_UNIT_NAME);\n\nexport interface InstallOpts {\n /** Absolute path to the agt binary the supervisor should launch. */\n agtBin: string;\n /** Poll interval passed to `agt manager start`. Min 5 seconds. */\n intervalSec: number;\n /** Manager config directory (where pid/log/state files live). */\n configDir: string;\n /**\n * Environment variables the supervised manager needs at launch time.\n * AGT_HOST and AGT_API_KEY are required for the manager to call the\n * API; AGT_TEAM is optional but typical.\n */\n env: Record<string, string>;\n}\n\nexport type SupervisorPresence =\n | { kind: 'installed'; pid: number | null; details: string }\n | { kind: 'not-installed' }\n | { kind: 'unsupported-platform'; platform: string };\n\n// ---------------------------------------------------------------------------\n// Public dispatcher\n// ---------------------------------------------------------------------------\n\nexport async function installSupervisor(opts: InstallOpts): Promise<{ ok: true; details: string } | { ok: false; error: string }> {\n switch (platform()) {\n case 'darwin':\n return installMacos(opts);\n case 'linux':\n return installLinux(opts);\n default:\n return { ok: false, error: `Unsupported platform: ${platform()}. Supervisor install is macOS / Linux only.` };\n }\n}\n\nexport async function uninstallSupervisor(): Promise<{ ok: true; details: string } | { ok: false; error: string }> {\n switch (platform()) {\n case 'darwin':\n return uninstallMacos();\n case 'linux':\n return uninstallLinux();\n default:\n return { ok: false, error: `Unsupported platform: ${platform()}. Supervisor uninstall is macOS / Linux only.` };\n }\n}\n\nexport function supervisorStatus(): SupervisorPresence {\n switch (platform()) {\n case 'darwin':\n return statusMacos();\n case 'linux':\n return statusLinux();\n default:\n return { kind: 'unsupported-platform', platform: platform() };\n }\n}\n\n// ---------------------------------------------------------------------------\n// macOS — launchd LaunchAgent\n// ---------------------------------------------------------------------------\n\nfunction installMacos(opts: InstallOpts): { ok: true; details: string } | { ok: false; error: string } {\n if (!existsSync(opts.agtBin)) {\n return { ok: false, error: `agt binary not found at ${opts.agtBin}` };\n }\n if (opts.intervalSec < 5) {\n return { ok: false, error: 'intervalSec must be >= 5' };\n }\n if (!opts.env.AGT_HOST || !opts.env.AGT_API_KEY) {\n return { ok: false, error: 'AGT_HOST and AGT_API_KEY must be set in the calling shell so the supervisor can pass them to the manager. Run `agt setup <token>` first.' };\n }\n\n // If a previous version is already loaded, unload it before rewriting\n // the plist — otherwise launchctl bootstrap will fail with EALREADY.\n bestEffort(() => execFileSync('launchctl', ['unload', '-w', MACOS_PLIST], { stdio: 'ignore' }));\n\n // Ensure the LaunchAgents directory exists. macOS creates it on first\n // login, but freshly-installed admin users may not have it yet.\n mkdirSync(dirname(MACOS_PLIST), { recursive: true });\n // 0o600 — plist embeds AGT_API_KEY in EnvironmentVariables. World-\n // readable would expose the host's tlk_ token to every local user.\n writeFileSync(MACOS_PLIST, renderMacosPlist(opts), { mode: 0o600 });\n chmodSync(MACOS_PLIST, 0o600);\n\n try {\n execFileSync('launchctl', ['load', '-w', MACOS_PLIST], { stdio: 'pipe' });\n } catch (err) {\n return { ok: false, error: `launchctl load failed: ${(err as Error).message}` };\n }\n\n // Verify launchd actually picked it up. `list <label>` returns 0 with\n // a plist of the loaded job's metadata; non-zero if not loaded.\n try {\n const out = execFileSync('launchctl', ['list', MACOS_LABEL], { encoding: 'utf-8' });\n return {\n ok: true,\n details: `Loaded launchd LaunchAgent ${MACOS_LABEL}. Logs: ${join(opts.configDir, 'manager.log')}.\\n${out.trim().split('\\n').slice(0, 10).join('\\n')}`,\n };\n } catch (err) {\n return { ok: false, error: `Plist written but launchctl list reported nothing for ${MACOS_LABEL}: ${(err as Error).message}` };\n }\n}\n\nfunction uninstallMacos(): { ok: true; details: string } | { ok: false; error: string } {\n // Both steps are idempotent — unload reports an error if nothing's\n // loaded, removing the file errors if it doesn't exist. Swallow both;\n // the desired end state is \"no LaunchAgent for this label\".\n bestEffort(() => execFileSync('launchctl', ['unload', '-w', MACOS_PLIST], { stdio: 'ignore' }));\n let removed = false;\n if (existsSync(MACOS_PLIST)) {\n try {\n unlinkSync(MACOS_PLIST);\n removed = true;\n } catch (err) {\n return { ok: false, error: `Failed to remove ${MACOS_PLIST}: ${(err as Error).message}` };\n }\n }\n return {\n ok: true,\n details: removed\n ? `Removed ${MACOS_LABEL} from launchd and deleted ${MACOS_PLIST}.`\n : `${MACOS_LABEL} was already uninstalled (no plist at ${MACOS_PLIST}).`,\n };\n}\n\nfunction statusMacos(): SupervisorPresence {\n if (!existsSync(MACOS_PLIST)) return { kind: 'not-installed' };\n // launchctl list emits a 3-column line: PID Status Label. PID is \"-\"\n // when the job is loaded but not currently running.\n try {\n const out = execFileSync('launchctl', ['list', MACOS_LABEL], { encoding: 'utf-8' });\n const pidMatch = /\"PID\"\\s*=\\s*(\\d+);/.exec(out);\n const pid = pidMatch ? Number(pidMatch[1]) : null;\n return { kind: 'installed', pid, details: `Plist: ${MACOS_PLIST}` };\n } catch {\n // File exists but launchctl can't find the label → user removed it\n // out-of-band. Surface as \"not installed\" so re-install just works.\n return { kind: 'not-installed' };\n }\n}\n\nfunction renderMacosPlist(opts: InstallOpts): string {\n // Load the operator's env into the plist so the manager has the same\n // AGT_HOST / AGT_API_KEY / AGT_TEAM the shell session does. launchd\n // does NOT inherit env from the user's shell — anything we don't bake\n // in here won't be visible to the process.\n const envEntries = Object.entries(opts.env)\n .filter(([k, v]) => k.length > 0 && v != null)\n .map(([k, v]) => ` <key>${escapeXml(k)}</key>\\n <string>${escapeXml(v)}</string>`)\n .join('\\n');\n\n const args = [\n 'manager',\n 'start',\n '--interval',\n String(opts.intervalSec),\n '--config-dir',\n opts.configDir,\n ];\n const argsXml = args.map((a) => ` <string>${escapeXml(a)}</string>`).join('\\n');\n\n const logPath = join(opts.configDir, 'manager.log');\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${MACOS_LABEL}</string>\n\n <key>ProgramArguments</key>\n <array>\n <string>${escapeXml(opts.agtBin)}</string>\n${argsXml}\n </array>\n\n <key>RunAtLoad</key>\n <true/>\n\n <key>KeepAlive</key>\n <true/>\n\n <!-- Throttle restarts so a crashloop doesn't peg the CPU. 10 seconds\n between launches is enough room for transient API blips while\n still recovering quickly from a real crash. -->\n <key>ThrottleInterval</key>\n <integer>10</integer>\n\n <!-- Where the manager's stdout / stderr land. The manager's logger\n redirects stderr into manager.log itself, but launchd needs an\n explicit destination at the OS level for any pre-logger output\n (e.g., Node startup errors before the watchdog wires up). -->\n <key>StandardOutPath</key>\n <string>${escapeXml(logPath)}</string>\n <key>StandardErrorPath</key>\n <string>${escapeXml(logPath)}</string>\n\n <key>WorkingDirectory</key>\n <string>${escapeXml(opts.configDir)}</string>\n\n <key>EnvironmentVariables</key>\n <dict>\n${envEntries}\n </dict>\n</dict>\n</plist>\n`;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction bestEffort(fn: () => void): void {\n try { fn(); } catch { /* swallow */ }\n}\n\nfunction escapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n// ---------------------------------------------------------------------------\n// Linux — systemd --user unit\n// ---------------------------------------------------------------------------\n\nfunction installLinux(opts: InstallOpts): { ok: true; details: string } | { ok: false; error: string } {\n if (!existsSync(opts.agtBin)) {\n return { ok: false, error: `agt binary not found at ${opts.agtBin}` };\n }\n if (opts.intervalSec < 5) {\n return { ok: false, error: 'intervalSec must be >= 5' };\n }\n if (!opts.env.AGT_HOST || !opts.env.AGT_API_KEY) {\n return { ok: false, error: 'AGT_HOST and AGT_API_KEY must be set in the calling shell so the supervisor can pass them to the unit. Run `agt setup <token>` first.' };\n }\n\n // Stop any previous instance before rewriting the unit — saves a\n // restart loop while daemon-reload picks up the new file.\n bestEffort(() => execFileSync('systemctl', ['--user', 'stop', LINUX_UNIT_NAME], { stdio: 'ignore' }));\n\n // ~/.config/systemd/user/ is the canonical user-unit path. Create it\n // recursively in case this is a fresh user with no XDG layout yet.\n // 0o700 — the unit body contains AGT_API_KEY in Environment= lines.\n mkdirSync(dirname(LINUX_UNIT_PATH), { recursive: true, mode: 0o700 });\n writeFileSync(LINUX_UNIT_PATH, renderLinuxUnit(opts), { mode: 0o600 });\n chmodSync(LINUX_UNIT_PATH, 0o600);\n\n try {\n execFileSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' });\n } catch (err) {\n return { ok: false, error: `systemctl --user daemon-reload failed: ${(err as Error).message}` };\n }\n\n // `enable --now` enables the unit at boot AND starts it immediately.\n // Surviving reboot on a headless host additionally requires\n // `loginctl enable-linger <user>` (root-only); we surface that as a\n // post-install hint rather than running it ourselves.\n try {\n execFileSync('systemctl', ['--user', 'enable', '--now', LINUX_UNIT_NAME], { stdio: 'pipe' });\n } catch (err) {\n return { ok: false, error: `systemctl --user enable --now failed: ${(err as Error).message}. (Hint: 'systemctl --user' requires a per-user dbus session; on a fresh SSH login try 'export XDG_RUNTIME_DIR=/run/user/$(id -u)' first.)` };\n }\n\n let isActive = '';\n try {\n isActive = execFileSync('systemctl', ['--user', 'is-active', LINUX_UNIT_NAME], { encoding: 'utf-8' }).trim();\n } catch (err) {\n // is-active exits non-zero for inactive/failed states. Capture its\n // output so the operator sees the real status.\n isActive = ((err as { stdout?: Buffer; stderr?: Buffer }).stdout?.toString() ?? '').trim() || 'unknown';\n }\n\n return {\n ok: true,\n details: `Loaded systemd --user unit ${LINUX_UNIT_NAME} (status: ${isActive}). Logs: ${join(opts.configDir, 'manager.log')}.\\nFor reboot survival on a headless host run as root: 'loginctl enable-linger ${process.env['USER'] ?? '<your-user>'}'`,\n };\n}\n\nfunction uninstallLinux(): { ok: true; details: string } | { ok: false; error: string } {\n // disable --now stops + un-enables in one shot. Both legs are idempotent\n // — disable on a non-existent unit returns 0 with a notice on stderr.\n bestEffort(() => execFileSync('systemctl', ['--user', 'disable', '--now', LINUX_UNIT_NAME], { stdio: 'ignore' }));\n\n let removed = false;\n if (existsSync(LINUX_UNIT_PATH)) {\n try {\n unlinkSync(LINUX_UNIT_PATH);\n removed = true;\n } catch (err) {\n return { ok: false, error: `Failed to remove ${LINUX_UNIT_PATH}: ${(err as Error).message}` };\n }\n }\n\n // Reload so a future install with the same path doesn't reuse the\n // stale unit metadata systemd cached in memory.\n bestEffort(() => execFileSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'ignore' }));\n\n return {\n ok: true,\n details: removed\n ? `Disabled systemd --user unit ${LINUX_UNIT_NAME} and deleted ${LINUX_UNIT_PATH}.`\n : `${LINUX_UNIT_NAME} was already uninstalled (no unit file at ${LINUX_UNIT_PATH}).`,\n };\n}\n\nfunction statusLinux(): SupervisorPresence {\n if (!existsSync(LINUX_UNIT_PATH)) return { kind: 'not-installed' };\n let pid: number | null = null;\n let activeState = 'unknown';\n try {\n const out = execFileSync(\n 'systemctl',\n ['--user', 'show', LINUX_UNIT_NAME, '--property=MainPID,ActiveState'],\n { encoding: 'utf-8' },\n );\n const pidMatch = /^MainPID=(\\d+)/m.exec(out);\n if (pidMatch && pidMatch[1] !== '0') pid = Number(pidMatch[1]);\n const stateMatch = /^ActiveState=(\\S+)/m.exec(out);\n if (stateMatch) activeState = stateMatch[1] ?? 'unknown';\n } catch {\n return { kind: 'not-installed' };\n }\n return { kind: 'installed', pid, details: `Unit: ${LINUX_UNIT_PATH} (${activeState})` };\n}\n\nfunction renderLinuxUnit(opts: InstallOpts): string {\n // systemd parses Environment= lines with a peculiar grammar — quotes\n // are optional but values can't contain literal newlines. We trust\n // the env values we forward (AGT_HOST/AGT_API_KEY/PATH etc. are\n // never multi-line) and quote everything to be safe with spaces.\n const envLines = Object.entries(opts.env)\n .filter(([k, v]) => k.length > 0 && v != null)\n .map(([k, v]) => `Environment=\"${k}=${escapeForSystemdEnv(v)}\"`)\n .join('\\n');\n\n // ExecStart cannot use shell metacharacters; pass the args explicitly\n // via systemd's array-of-args style (newline-separated wouldn't\n // parse — systemd splits on whitespace within ExecStart). So we\n // shell-quote each arg and join.\n const execArgs = [\n opts.agtBin,\n 'manager',\n 'start',\n '--interval',\n String(opts.intervalSec),\n '--config-dir',\n opts.configDir,\n ]\n .map(shellQuoteForSystemd)\n .join(' ');\n\n const logPath = join(opts.configDir, 'manager.log');\n\n return `# agt manager supervisor (ENG-4593)\n# Managed by \\`agt manager install\\` — edits will be overwritten.\n\n[Unit]\nDescription=Augmented host manager daemon\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nWorkingDirectory=${opts.configDir}\n${envLines}\nExecStart=${execArgs}\n\n# Restart policy — always come back, with throttling so a crashloop\n# can't peg the CPU. StartLimitBurst/IntervalSec follow systemd's\n# defaults but are stated explicitly so future operators don't have\n# to read the man page to understand the recovery envelope.\nRestart=always\nRestartSec=5\nStartLimitBurst=5\nStartLimitIntervalSec=60\n\n# stdout/stderr → manager.log. journalctl --user -u agt-manager\n# still captures everything; this just gives operators a single file\n# to tail without learning systemd plumbing.\nStandardOutput=append:${logPath}\nStandardError=append:${logPath}\n\n[Install]\nWantedBy=default.target\n`;\n}\n\nfunction escapeForSystemdEnv(value: string): string {\n // Inside an Environment=\"K=V\" line, \" and \\\\ need escaping. Newlines\n // would terminate the directive — reject them upstream.\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\nfunction shellQuoteForSystemd(arg: string): string {\n // systemd's ExecStart parser supports double-quoted strings with\n // backslash escapes, similar to a POSIX shell but no command\n // substitution. Wrap any arg containing whitespace or shell metas.\n if (/^[A-Za-z0-9_./:=-]+$/.test(arg)) return arg;\n return `\"${arg.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n}\n\n// Exposed for unit tests / introspection.\nexport const _internals = {\n MACOS_LABEL,\n MACOS_PLIST,\n LINUX_UNIT_NAME,\n LINUX_UNIT_PATH,\n renderMacosPlist,\n renderLinuxUnit,\n escapeXml,\n escapeForSystemdEnv,\n shellQuoteForSystemd,\n readPlist: () => (existsSync(MACOS_PLIST) ? readFileSync(MACOS_PLIST, 'utf-8') : null),\n readUnit: () => (existsSync(LINUX_UNIT_PATH) ? readFileSync(LINUX_UNIT_PATH, 'utf-8') : null),\n};\n"],"mappings":"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","names":[]}
|