abtars 0.1.0-alpha.3 → 0.1.0-alpha.4
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/bundle/abtars-cli.js +3 -3
- package/bundle/chunk-7K5ISJT4.js +519 -0
- package/bundle/chunk-7K5ISJT4.js.map +7 -0
- package/bundle/chunk-ZVWISISU.js +511 -0
- package/bundle/chunk-ZVWISISU.js.map +7 -0
- package/bundle/ensure-invariants-K2ZUZ6NR.js +50 -0
- package/bundle/ensure-invariants-K2ZUZ6NR.js.map +7 -0
- package/bundle/install-AL5RLP2R.js +16 -0
- package/bundle/install-AL5RLP2R.js.map +7 -0
- package/bundle/install-manifest-MCJCAYSR.js +104 -0
- package/bundle/install-manifest-MCJCAYSR.js.map +7 -0
- package/bundle/meta.json +38 -28
- package/bundle/update-HRAAW2LK.js +14 -0
- package/bundle/update-HRAAW2LK.js.map +7 -0
- package/package.json +1 -1
package/bundle/abtars-cli.js
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import {
|
|
4
4
|
showHintOnce,
|
|
5
5
|
update
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZVWISISU.js";
|
|
7
7
|
import {
|
|
8
8
|
install
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7K5ISJT4.js";
|
|
10
10
|
import {
|
|
11
11
|
acquireLock,
|
|
12
12
|
activate,
|
|
@@ -1036,7 +1036,7 @@ Next: cd into the abtars repo and run 'abtars update' to build and activate.
|
|
|
1036
1036
|
process.stdout.write(`
|
|
1037
1037
|
\u2500\u2500 Running 'abtars update' \u2500\u2500
|
|
1038
1038
|
`);
|
|
1039
|
-
const { update: update2 } = await import("./update-
|
|
1039
|
+
const { update: update2 } = await import("./update-HRAAW2LK.js");
|
|
1040
1040
|
const updRc = await update2({ source: "local", fromLocal: true, allowAbmindMismatch: false });
|
|
1041
1041
|
if (updRc !== 0) {
|
|
1042
1042
|
process.stderr.write(`
|
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
|
|
3
|
+
import {
|
|
4
|
+
emptyManifest,
|
|
5
|
+
packagePaths,
|
|
6
|
+
readManifest,
|
|
7
|
+
resolveUserBinDir,
|
|
8
|
+
writeManifest
|
|
9
|
+
} from "./chunk-HXJRZWKA.js";
|
|
10
|
+
import {
|
|
11
|
+
init_log_and_swallow,
|
|
12
|
+
logAndSwallow
|
|
13
|
+
} from "./chunk-EX2SRTUE.js";
|
|
14
|
+
|
|
15
|
+
// src/cli/commands/install.ts
|
|
16
|
+
init_log_and_swallow();
|
|
17
|
+
import { mkdir, readFile, stat, symlink, writeFile } from "node:fs/promises";
|
|
18
|
+
import { existsSync, readFileSync, readdirSync, copyFileSync, mkdirSync } from "node:fs";
|
|
19
|
+
import { hostname, homedir } from "node:os";
|
|
20
|
+
import { basename, dirname, join } from "node:path";
|
|
21
|
+
async function exists(p) {
|
|
22
|
+
try {
|
|
23
|
+
await stat(p);
|
|
24
|
+
return true;
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function existsAny(p) {
|
|
30
|
+
try {
|
|
31
|
+
const { lstat } = await import("node:fs/promises");
|
|
32
|
+
await lstat(p);
|
|
33
|
+
return true;
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function isSymlink(p) {
|
|
39
|
+
try {
|
|
40
|
+
const { lstat } = await import("node:fs/promises");
|
|
41
|
+
const s = await lstat(p);
|
|
42
|
+
return s.isSymbolicLink();
|
|
43
|
+
} catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function createSkeleton(home, dryRun) {
|
|
48
|
+
const { loadManifest } = await import("./install-manifest-MCJCAYSR.js");
|
|
49
|
+
const manifest = loadManifest();
|
|
50
|
+
const dirs = manifest.directories.map((d) => join(home, d.path));
|
|
51
|
+
if (dryRun) {
|
|
52
|
+
process.stdout.write(`[dry-run] mkdir -p:
|
|
53
|
+
${dirs.join("\n ")}
|
|
54
|
+
`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
for (const d of manifest.directories) {
|
|
58
|
+
await mkdir(join(home, d.path), { recursive: true, mode: d.mode ? parseInt(d.mode, 8) : void 0 });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function seedConfig(repoRoot, _configDir, dryRun, home) {
|
|
62
|
+
const { loadManifest } = await import("./install-manifest-MCJCAYSR.js");
|
|
63
|
+
const manifest = loadManifest(repoRoot);
|
|
64
|
+
const seeded = [];
|
|
65
|
+
for (const seed of manifest.configSeeds) {
|
|
66
|
+
const src = join(repoRoot, seed.source);
|
|
67
|
+
const dst = join(home, seed.dest);
|
|
68
|
+
if (!await exists(src)) continue;
|
|
69
|
+
if (await exists(dst)) continue;
|
|
70
|
+
if (dryRun) {
|
|
71
|
+
seeded.push(`[dry-run] cp ${src} ${dst}`);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const content = await readFile(src, "utf-8");
|
|
75
|
+
await mkdir(dirname(dst), { recursive: true });
|
|
76
|
+
await writeFile(dst, content, { mode: seed.mode ? parseInt(seed.mode, 8) : 420 });
|
|
77
|
+
seeded.push(basename(dst));
|
|
78
|
+
}
|
|
79
|
+
return seeded;
|
|
80
|
+
}
|
|
81
|
+
async function reconcilePathLink(binDir, userBinDir, name, force, dryRun) {
|
|
82
|
+
const linkPath = join(userBinDir, name);
|
|
83
|
+
const targetPath = join(binDir, name);
|
|
84
|
+
const linkExists = await existsAny(linkPath);
|
|
85
|
+
if (!linkExists) {
|
|
86
|
+
if (dryRun) return { action: `[dry-run] ln -s ${targetPath} ${linkPath}` };
|
|
87
|
+
await symlink(targetPath, linkPath);
|
|
88
|
+
return { action: `created ${linkPath}` };
|
|
89
|
+
}
|
|
90
|
+
if (await isSymlink(linkPath)) {
|
|
91
|
+
const { readlink, unlink } = await import("node:fs/promises");
|
|
92
|
+
const current = await readlink(linkPath);
|
|
93
|
+
const ownsIt = current === targetPath;
|
|
94
|
+
if (ownsIt) {
|
|
95
|
+
if (dryRun) return { action: `[dry-run] overwrite ${linkPath} (we own it)` };
|
|
96
|
+
await unlink(linkPath);
|
|
97
|
+
await symlink(targetPath, linkPath);
|
|
98
|
+
return { action: `updated ${linkPath}` };
|
|
99
|
+
}
|
|
100
|
+
if (force) {
|
|
101
|
+
if (dryRun) return { action: `[dry-run] --force overwrite ${linkPath} (currently -> ${current})` };
|
|
102
|
+
await unlink(linkPath);
|
|
103
|
+
await symlink(targetPath, linkPath);
|
|
104
|
+
return { action: `forced overwrite ${linkPath} (was -> ${current})` };
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
action: "refused",
|
|
108
|
+
message: `${linkPath} is a symlink to ${current} (not ours). Pass --force to overwrite.`
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (force) {
|
|
112
|
+
if (dryRun) return { action: `[dry-run] --force overwrite ${linkPath} (regular file)` };
|
|
113
|
+
const { unlink } = await import("node:fs/promises");
|
|
114
|
+
await unlink(linkPath);
|
|
115
|
+
await symlink(targetPath, linkPath);
|
|
116
|
+
return { action: `forced overwrite ${linkPath} (was regular file)` };
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
action: "refused",
|
|
120
|
+
message: `${linkPath} exists as a regular file (not our symlink). Pass --force to overwrite.`
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async function writeWrapper(binDir, name, currentLink, dryRun) {
|
|
124
|
+
const bundleFile = name === "abtars" ? "abtars-cli.js" : `${name}.js`;
|
|
125
|
+
const target = join(currentLink, "bundle", bundleFile);
|
|
126
|
+
const distFile = name === "abtars" ? "abtars.js" : `${name}.js`;
|
|
127
|
+
const fallback = join(currentLink, "dist", "cli", distFile);
|
|
128
|
+
const content = `#!/usr/bin/env bash
|
|
129
|
+
if [ -f "${target}" ]; then
|
|
130
|
+
exec node "${target}" "$@"
|
|
131
|
+
elif [ -f "${fallback}" ]; then
|
|
132
|
+
exec node "${fallback}" "$@"
|
|
133
|
+
else
|
|
134
|
+
echo "abtars: no release staged yet. Run 'abtars update' or 'npm run bundle' in the repo checkout." >&2
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
`;
|
|
138
|
+
const path = join(binDir, name);
|
|
139
|
+
if (dryRun) {
|
|
140
|
+
process.stdout.write(`[dry-run] write wrapper ${path} -> node ${target} (fallback: ${fallback})
|
|
141
|
+
`);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
await writeFile(path, content, { mode: 493 });
|
|
145
|
+
}
|
|
146
|
+
function isPathOnPATH(userBinDir) {
|
|
147
|
+
const PATH = process.env["PATH"] ?? "";
|
|
148
|
+
return PATH.split(":").some((p) => p === userBinDir);
|
|
149
|
+
}
|
|
150
|
+
function isWSL() {
|
|
151
|
+
try {
|
|
152
|
+
return existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || /microsoft/i.test(readFileSync("/proc/version", "utf-8"));
|
|
153
|
+
} catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function installSupervisedDaemon(home, repoRoot, dryRun) {
|
|
158
|
+
const platform = process.platform;
|
|
159
|
+
if (platform === "linux" && isWSL()) {
|
|
160
|
+
process.stderr.write(`\u2139\uFE0F WSL detected \u2014 ensure systemd is enabled (wsl.conf: [boot] systemd=true)
|
|
161
|
+
`);
|
|
162
|
+
}
|
|
163
|
+
const sudoUser = process.env["SUDO_USER"];
|
|
164
|
+
if (process.getuid?.() !== 0) {
|
|
165
|
+
process.stderr.write(
|
|
166
|
+
`supervised-daemon requires sudo for system-scope service install.
|
|
167
|
+
Run: sudo -k abtars install --mode=supervised-daemon
|
|
168
|
+
`
|
|
169
|
+
);
|
|
170
|
+
return 2;
|
|
171
|
+
}
|
|
172
|
+
if (!sudoUser) {
|
|
173
|
+
process.stderr.write(
|
|
174
|
+
`Cannot determine target user \u2014 $SUDO_USER is not set.
|
|
175
|
+
Run via: sudo -k abtars install --mode=supervised-daemon
|
|
176
|
+
(Do not use 'su -' \u2014 it doesn't set SUDO_USER.)
|
|
177
|
+
`
|
|
178
|
+
);
|
|
179
|
+
return 2;
|
|
180
|
+
}
|
|
181
|
+
const currentLink = join(home, "current");
|
|
182
|
+
if (!existsSync(currentLink)) {
|
|
183
|
+
process.stderr.write(
|
|
184
|
+
`No release staged at ${currentLink}.
|
|
185
|
+
Run 'abtars install' and 'abtars update' as ${sudoUser} first,
|
|
186
|
+
then re-run with sudo for supervised-daemon.
|
|
187
|
+
`
|
|
188
|
+
);
|
|
189
|
+
return 2;
|
|
190
|
+
}
|
|
191
|
+
const userGroup = sudoUser;
|
|
192
|
+
if (platform === "darwin") {
|
|
193
|
+
const { execSync } = await import("node:child_process");
|
|
194
|
+
let group = userGroup;
|
|
195
|
+
try {
|
|
196
|
+
group = execSync(`id -gn ${sudoUser}`, { encoding: "utf-8" }).trim();
|
|
197
|
+
} catch (err) {
|
|
198
|
+
logAndSwallow("install", "op", err);
|
|
199
|
+
}
|
|
200
|
+
const plistSrc = join(repoRoot, "scripts", "com.abtars.daemon.plist");
|
|
201
|
+
if (!existsSync(plistSrc)) {
|
|
202
|
+
process.stderr.write(`Template not found: ${plistSrc}
|
|
203
|
+
`);
|
|
204
|
+
return 1;
|
|
205
|
+
}
|
|
206
|
+
let content = readFileSync(plistSrc, "utf-8");
|
|
207
|
+
content = content.replaceAll("{{USER}}", sudoUser).replaceAll("{{GROUP}}", group);
|
|
208
|
+
const dst = "/Library/LaunchDaemons/com.abtars.daemon.plist";
|
|
209
|
+
if (dryRun) {
|
|
210
|
+
process.stdout.write(`[dry-run] write ${dst}
|
|
211
|
+
[dry-run] launchctl bootstrap system ${dst}
|
|
212
|
+
`);
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
const userAgent = join("/Users", sudoUser, "Library", "LaunchAgents", "com.abtars.watchdog.plist");
|
|
216
|
+
if (existsSync(userAgent)) {
|
|
217
|
+
const { execFileSync: execFileSync2 } = await import("node:child_process");
|
|
218
|
+
try {
|
|
219
|
+
execFileSync2("launchctl", ["bootout", `gui/${process.env["SUDO_UID"] ?? ""}`, userAgent]);
|
|
220
|
+
} catch (err) {
|
|
221
|
+
logAndSwallow("install", "op", err);
|
|
222
|
+
}
|
|
223
|
+
process.stdout.write(`\u2713 disabled user-scope LaunchAgent
|
|
224
|
+
`);
|
|
225
|
+
}
|
|
226
|
+
const { writeFileSync, chmodSync } = await import("node:fs");
|
|
227
|
+
writeFileSync(dst, content);
|
|
228
|
+
chmodSync(dst, 420);
|
|
229
|
+
const { execFileSync } = await import("node:child_process");
|
|
230
|
+
try {
|
|
231
|
+
execFileSync("launchctl", ["bootstrap", "system", dst]);
|
|
232
|
+
} catch (err) {
|
|
233
|
+
logAndSwallow("install", "op", err);
|
|
234
|
+
}
|
|
235
|
+
process.stdout.write(`\u2713 LaunchDaemon installed at ${dst}
|
|
236
|
+
`);
|
|
237
|
+
process.stdout.write(`\u2713 supervised-daemon active \u2014 bridge runs as ${sudoUser}, survives logout + reboot
|
|
238
|
+
`);
|
|
239
|
+
return 0;
|
|
240
|
+
}
|
|
241
|
+
if (platform === "linux") {
|
|
242
|
+
const { execSync } = await import("node:child_process");
|
|
243
|
+
try {
|
|
244
|
+
execSync("systemctl --version", { stdio: "ignore" });
|
|
245
|
+
} catch {
|
|
246
|
+
process.stderr.write(`systemctl not found \u2014 supervised-daemon requires systemd.
|
|
247
|
+
`);
|
|
248
|
+
return 2;
|
|
249
|
+
}
|
|
250
|
+
const unitSrc = join(repoRoot, "scripts", "abtars-daemon.service");
|
|
251
|
+
if (!existsSync(unitSrc)) {
|
|
252
|
+
process.stderr.write(`Template not found: ${unitSrc}
|
|
253
|
+
`);
|
|
254
|
+
return 1;
|
|
255
|
+
}
|
|
256
|
+
let content = readFileSync(unitSrc, "utf-8");
|
|
257
|
+
content = content.replaceAll("{{USER}}", sudoUser);
|
|
258
|
+
const dst = "/etc/systemd/system/abtars.service";
|
|
259
|
+
if (dryRun) {
|
|
260
|
+
process.stdout.write(`[dry-run] write ${dst}
|
|
261
|
+
[dry-run] systemctl enable --now abtars
|
|
262
|
+
`);
|
|
263
|
+
return 0;
|
|
264
|
+
}
|
|
265
|
+
const { writeFileSync } = await import("node:fs");
|
|
266
|
+
writeFileSync(dst, content);
|
|
267
|
+
const { execFileSync } = await import("node:child_process");
|
|
268
|
+
execFileSync("systemctl", ["daemon-reload"]);
|
|
269
|
+
execFileSync("systemctl", ["enable", "--now", "abtars"]);
|
|
270
|
+
process.stdout.write(`\u2713 systemd unit installed at ${dst}
|
|
271
|
+
`);
|
|
272
|
+
process.stdout.write(`\u2713 supervised-daemon active \u2014 bridge runs as ${sudoUser}, survives logout + reboot
|
|
273
|
+
`);
|
|
274
|
+
return 0;
|
|
275
|
+
}
|
|
276
|
+
process.stderr.write(`supervised-daemon is not supported on ${platform}.
|
|
277
|
+
`);
|
|
278
|
+
return 2;
|
|
279
|
+
}
|
|
280
|
+
async function install(opts) {
|
|
281
|
+
const paths = packagePaths("abtars");
|
|
282
|
+
const home = paths.home;
|
|
283
|
+
const userBinDir = resolveUserBinDir();
|
|
284
|
+
const repoRoot = process.cwd();
|
|
285
|
+
const { initInstallLog, logInstall, logInstallHeader } = await import("./install-log-Q6RUHKWC.js");
|
|
286
|
+
initInstallLog(home);
|
|
287
|
+
logInstallHeader("install");
|
|
288
|
+
const _origWrite = process.stdout.write.bind(process.stdout);
|
|
289
|
+
process.stdout.write = (chunk, ...args) => {
|
|
290
|
+
if (typeof chunk === "string" && (chunk.startsWith("\u2713") || chunk.startsWith("\u26A0"))) logInstall(chunk.trimEnd());
|
|
291
|
+
return _origWrite(chunk, ...args);
|
|
292
|
+
};
|
|
293
|
+
const homeExists = await exists(home);
|
|
294
|
+
const manifest = homeExists ? await readManifest(paths.manifest) : null;
|
|
295
|
+
if (homeExists && manifest && !opts.force && !opts.restore) {
|
|
296
|
+
process.stderr.write(
|
|
297
|
+
`~/.abtars already installed at version ${manifest.version || "(unset)"}.
|
|
298
|
+
Use 'abtars update' to upgrade, or --force to re-seed missing config.
|
|
299
|
+
`
|
|
300
|
+
);
|
|
301
|
+
return 2;
|
|
302
|
+
}
|
|
303
|
+
await createSkeleton(home, opts.dryRun);
|
|
304
|
+
process.stdout.write(`\u2713 skeleton at ${home}
|
|
305
|
+
`);
|
|
306
|
+
const kiroAgentsDir = join(homedir(), ".kiro", "agents");
|
|
307
|
+
const professorJson = join(kiroAgentsDir, "professor.json");
|
|
308
|
+
if (!opts.dryRun) {
|
|
309
|
+
await mkdir(kiroAgentsDir, { recursive: true });
|
|
310
|
+
if (!await exists(professorJson)) {
|
|
311
|
+
await writeFile(professorJson, JSON.stringify({
|
|
312
|
+
name: "professor",
|
|
313
|
+
description: "Abtars bridge agent",
|
|
314
|
+
tools: ["*"],
|
|
315
|
+
allowedTools: ["@builtin"],
|
|
316
|
+
toolsSettings: { shell: { autoAllowReadonly: true } },
|
|
317
|
+
includeMcpJson: true
|
|
318
|
+
}, null, 2) + "\n");
|
|
319
|
+
process.stdout.write(`\u2713 kiro agent: ${professorJson}
|
|
320
|
+
`);
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
process.stdout.write(`[dry-run] create ${professorJson}
|
|
324
|
+
`);
|
|
325
|
+
}
|
|
326
|
+
const identityKey = join(paths.config, "identity.key");
|
|
327
|
+
const identityPub = join(paths.config, "identity.pub");
|
|
328
|
+
if (!opts.dryRun && !await exists(identityKey)) {
|
|
329
|
+
const { generateKeyPairSync } = await import("node:crypto");
|
|
330
|
+
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
331
|
+
await writeFile(identityKey, privateKey.export({ format: "der", type: "pkcs8" }).toString("base64"));
|
|
332
|
+
await writeFile(identityPub, publicKey.export({ format: "der", type: "spki" }).toString("base64"));
|
|
333
|
+
const { chmodSync } = await import("node:fs");
|
|
334
|
+
chmodSync(identityKey, 384);
|
|
335
|
+
process.stdout.write(`\u2713 identity keypair generated
|
|
336
|
+
`);
|
|
337
|
+
}
|
|
338
|
+
const identityCrt = join(paths.config, "identity.crt");
|
|
339
|
+
const identityTlsKey = join(paths.config, "identity.tls.key");
|
|
340
|
+
if (!opts.dryRun && !await exists(identityCrt)) {
|
|
341
|
+
const { execSync } = await import("node:child_process");
|
|
342
|
+
const { chmodSync } = await import("node:fs");
|
|
343
|
+
const agentName = hostname();
|
|
344
|
+
try {
|
|
345
|
+
execSync(`openssl req -x509 -newkey ed25519 -keyout identity.tls.key -out identity.crt -days 3650 -nodes -subj "/CN=${agentName}"`, { cwd: paths.config, stdio: "ignore" });
|
|
346
|
+
chmodSync(identityTlsKey, 384);
|
|
347
|
+
process.stdout.write(`\u2713 TLS certificate generated (Ed25519, 10yr)
|
|
348
|
+
`);
|
|
349
|
+
} catch (err) {
|
|
350
|
+
process.stderr.write(`\u26A0 TLS cert generation failed (openssl not found?). Agent-api will start without TLS.
|
|
351
|
+
`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
const seeded = await seedConfig(repoRoot, paths.config, opts.dryRun, home);
|
|
355
|
+
if (seeded.length > 0) {
|
|
356
|
+
process.stdout.write(`\u2713 seeded config: ${seeded.join(", ")}
|
|
357
|
+
`);
|
|
358
|
+
}
|
|
359
|
+
const { loadManifest: loadInstallManifest } = await import("./install-manifest-MCJCAYSR.js");
|
|
360
|
+
const installManifest = loadInstallManifest(repoRoot);
|
|
361
|
+
if (!opts.dryRun) {
|
|
362
|
+
await mkdir(paths.bin, { recursive: true });
|
|
363
|
+
}
|
|
364
|
+
for (const name of installManifest.cliWrappers) {
|
|
365
|
+
await writeWrapper(paths.bin, name, paths.current, opts.dryRun);
|
|
366
|
+
}
|
|
367
|
+
process.stdout.write(`\u2713 wrappers in ${paths.bin}
|
|
368
|
+
`);
|
|
369
|
+
if (!opts.dryRun) await mkdir(userBinDir, { recursive: true });
|
|
370
|
+
const refused = [];
|
|
371
|
+
for (const name of installManifest.cliWrappers) {
|
|
372
|
+
const r = await reconcilePathLink(paths.bin, userBinDir, name, opts.force, opts.dryRun);
|
|
373
|
+
if (r.action === "refused") {
|
|
374
|
+
refused.push(r.message ?? name);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (refused.length > 0) {
|
|
378
|
+
process.stderr.write(`
|
|
379
|
+
PATH symlink conflicts:
|
|
380
|
+
${refused.join("\n ")}
|
|
381
|
+
`);
|
|
382
|
+
return 4;
|
|
383
|
+
}
|
|
384
|
+
process.stdout.write(`\u2713 PATH symlinks in ${userBinDir}
|
|
385
|
+
`);
|
|
386
|
+
if (!isPathOnPATH(userBinDir)) {
|
|
387
|
+
process.stderr.write(
|
|
388
|
+
`
|
|
389
|
+
Warning: ${userBinDir} is not on $PATH. Add to your shell config:
|
|
390
|
+
export PATH="${userBinDir}:$PATH"
|
|
391
|
+
`
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
const manifestAfter = await readManifest(paths.manifest);
|
|
395
|
+
if (manifestAfter === null && !opts.dryRun) {
|
|
396
|
+
await writeManifest(paths.manifest, {
|
|
397
|
+
...emptyManifest("abtars", hostname()),
|
|
398
|
+
version: "",
|
|
399
|
+
preMigrationBackup: null
|
|
400
|
+
});
|
|
401
|
+
process.stdout.write(`\u2713 manifest initialized at ${paths.manifest}
|
|
402
|
+
`);
|
|
403
|
+
}
|
|
404
|
+
const manifestForMode = await readManifest(paths.manifest);
|
|
405
|
+
const existingMode = manifestForMode?.installMode;
|
|
406
|
+
const mode = opts.mode ?? existingMode ?? "supervised";
|
|
407
|
+
if (manifestForMode) {
|
|
408
|
+
await writeManifest(paths.manifest, { ...manifestForMode, installMode: mode });
|
|
409
|
+
}
|
|
410
|
+
process.stdout.write(`\u2713 install mode: ${mode}
|
|
411
|
+
`);
|
|
412
|
+
if (mode === "supervised-daemon") {
|
|
413
|
+
return installSupervisedDaemon(home, repoRoot, opts.dryRun);
|
|
414
|
+
}
|
|
415
|
+
if (opts.restore) {
|
|
416
|
+
const { spawnSync } = await import("node:child_process");
|
|
417
|
+
const { existsSync: fileExists } = await import("node:fs");
|
|
418
|
+
const zipPath = opts.restore;
|
|
419
|
+
if (!fileExists(zipPath)) {
|
|
420
|
+
process.stderr.write(`error: backup file not found: ${zipPath}
|
|
421
|
+
`);
|
|
422
|
+
return 1;
|
|
423
|
+
}
|
|
424
|
+
const tmpDir = join(process.env["TMPDIR"] ?? "/tmp", `abtars-restore-${Date.now()}`);
|
|
425
|
+
const unzip = spawnSync("unzip", ["-o", zipPath, "-d", tmpDir], { encoding: "utf-8" });
|
|
426
|
+
if (unzip.status !== 0) {
|
|
427
|
+
process.stderr.write(`error: unzip failed: ${unzip.stderr}
|
|
428
|
+
`);
|
|
429
|
+
return 1;
|
|
430
|
+
}
|
|
431
|
+
const abSrc = join(tmpDir, "abtars");
|
|
432
|
+
if (fileExists(abSrc)) {
|
|
433
|
+
spawnSync("cp", ["-r", ...readdirSync(abSrc).map((f) => join(abSrc, f)), home], { stdio: "inherit" });
|
|
434
|
+
process.stdout.write(`\u2713 restored abtars config
|
|
435
|
+
`);
|
|
436
|
+
}
|
|
437
|
+
const abmindHome = process.env["ABMIND_HOME"] ?? join(dirname(home), ".abmind");
|
|
438
|
+
const abmindSrc = join(tmpDir, "abmind");
|
|
439
|
+
if (fileExists(abmindSrc)) {
|
|
440
|
+
spawnSync("cp", ["-r", ...readdirSync(abmindSrc).map((f) => join(abmindSrc, f)), abmindHome], { stdio: "inherit" });
|
|
441
|
+
process.stdout.write(`\u2713 restored abmind data
|
|
442
|
+
`);
|
|
443
|
+
}
|
|
444
|
+
spawnSync("rm", ["-rf", tmpDir]);
|
|
445
|
+
process.stdout.write(`
|
|
446
|
+
Restore complete.
|
|
447
|
+
`);
|
|
448
|
+
process.stdout.write(`Next: 'abtars update' to build and activate.
|
|
449
|
+
`);
|
|
450
|
+
return 0;
|
|
451
|
+
}
|
|
452
|
+
if (mode === "supervised") {
|
|
453
|
+
const { execSync } = await import("node:child_process");
|
|
454
|
+
if (process.platform === "darwin") {
|
|
455
|
+
const plistSrc = join(home, "scripts", "com.abtars.watchdog.plist");
|
|
456
|
+
const plistDst = join(homedir(), "Library", "LaunchAgents", "com.abtars.watchdog.plist");
|
|
457
|
+
if (existsSync(plistSrc)) {
|
|
458
|
+
const content = readFileSync(plistSrc, "utf-8").replaceAll("{{HOME}}", homedir());
|
|
459
|
+
const { writeFileSync } = await import("node:fs");
|
|
460
|
+
writeFileSync(plistDst, content);
|
|
461
|
+
try {
|
|
462
|
+
execSync(`launchctl load "${plistDst}"`, { stdio: "ignore" });
|
|
463
|
+
} catch {
|
|
464
|
+
}
|
|
465
|
+
process.stdout.write(`\u2713 watchdog LaunchAgent loaded
|
|
466
|
+
`);
|
|
467
|
+
}
|
|
468
|
+
} else if (process.platform === "linux") {
|
|
469
|
+
const unitSrc = join(home, "scripts", "abtars-watchdog.service");
|
|
470
|
+
const unitDir = join(homedir(), ".config", "systemd", "user");
|
|
471
|
+
if (existsSync(unitSrc)) {
|
|
472
|
+
mkdirSync(unitDir, { recursive: true });
|
|
473
|
+
copyFileSync(unitSrc, join(unitDir, "abtars-watchdog.service"));
|
|
474
|
+
try {
|
|
475
|
+
execSync("systemctl --user daemon-reload && systemctl --user enable --now abtars-watchdog", { stdio: "ignore" });
|
|
476
|
+
} catch {
|
|
477
|
+
}
|
|
478
|
+
process.stdout.write(`\u2713 watchdog systemd user service enabled
|
|
479
|
+
`);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
process.stdout.write(`
|
|
484
|
+
Install complete.
|
|
485
|
+
`);
|
|
486
|
+
if (!manifestAfter || manifestAfter.version === "") {
|
|
487
|
+
process.stdout.write(`Next: 'abtars update' to build and activate the first release.
|
|
488
|
+
`);
|
|
489
|
+
} else {
|
|
490
|
+
process.stdout.write(`
|
|
491
|
+
\u2500\u2500 Next steps \u2500\u2500
|
|
492
|
+
`);
|
|
493
|
+
process.stdout.write(` 1. Run 'abtars onboard' to configure Telegram token + model provider
|
|
494
|
+
`);
|
|
495
|
+
process.stdout.write(` 2. (Optional) Install Ollama for memory embeddings: curl -fsSL https://ollama.com/install.sh | sh
|
|
496
|
+
`);
|
|
497
|
+
process.stdout.write(` 3. Start the bridge: 'abtars restart' or use the watchdog
|
|
498
|
+
|
|
499
|
+
`);
|
|
500
|
+
}
|
|
501
|
+
const { printHealthSummary } = await import("./health-check-RJ2SUJYL.js");
|
|
502
|
+
printHealthSummary(paths.home);
|
|
503
|
+
if (!opts.dryRun && opts.restore) {
|
|
504
|
+
const { validateMinimumViability, formatValidationError } = await import("./install-validate-H74LUCE2.js");
|
|
505
|
+
const validation = validateMinimumViability(paths.config);
|
|
506
|
+
if (!validation.ok) {
|
|
507
|
+
const invocation = `abtars install --restore ${opts.restore}`;
|
|
508
|
+
process.stderr.write("\n" + formatValidationError(validation, invocation) + "\n");
|
|
509
|
+
return 1;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return 0;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
export {
|
|
516
|
+
writeWrapper,
|
|
517
|
+
install
|
|
518
|
+
};
|
|
519
|
+
//# sourceMappingURL=chunk-7K5ISJT4.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/cli/commands/install.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * `abtars install [--upgrade]` \u2014 first-time setup.\n *\n * Phase 1 behavior:\n * - No existing ~/.abtars: create dirs, seed config/ from .env.example,\n * create PATH symlinks. Does NOT run onboard (Phase 3).\n * - Existing ~/.abtars with flat layout (pre-158): refuse unless\n * --upgrade, then run migration 003-flat-to-releases (Phase 1c).\n * - Existing ~/.abtars with new layout: refuse unless --force (which\n * re-seeds missing config and reconciles symlinks, no code changes).\n */\n\nimport { logAndSwallow } from \"../../components/log-and-swallow.js\";\nimport { mkdir, readFile, stat, symlink, writeFile } from 'node:fs/promises';\nimport { existsSync, readFileSync, readdirSync, copyFileSync, mkdirSync } from 'node:fs';\nimport { hostname, homedir } from 'node:os';\nimport { basename, dirname, join } from 'node:path';\nimport { emptyManifest, packagePaths, readManifest, resolveUserBinDir, writeManifest } from '../deploy-lib-import.js';\n\nexport interface InstallOptions {\n readonly restore?: string;\n readonly force: boolean;\n readonly dryRun: boolean;\n readonly mode?: \"simple\" | \"supervised\" | \"supervised-daemon\";\n}\n\n// CLI wrappers are read from install-manifest.json at runtime.\n// Each is a thin wrapper that invokes `node current/dist/cli/<name>.js \"$@\"`.\n// Regenerated on every install / flat-to-releases migration.\n\nasync function exists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * True if `p` exists as any filesystem entry \u2014 regular file, directory,\n * symlink (including dangling). Use this for collision checks in\n * reconcilePathLink, where a dangling symlink still occupies the inode\n * and would cause EEXIST on symlink(). `exists()` above uses stat() which\n * follows symlinks and returns false on dangling ones; that's wrong for\n * collision detection.\n */\nasync function existsAny(p: string): Promise<boolean> {\n try {\n const { lstat } = await import('node:fs/promises');\n await lstat(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isSymlink(p: string): Promise<boolean> {\n try {\n const { lstat } = await import('node:fs/promises');\n const s = await lstat(p);\n return s.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nasync function createSkeleton(home: string, dryRun: boolean): Promise<void> {\n const { loadManifest } = await import('../install-manifest.js');\n const manifest = loadManifest();\n const dirs = manifest.directories.map(d => join(home, d.path));\n if (dryRun) {\n process.stdout.write(`[dry-run] mkdir -p:\\n ${dirs.join('\\n ')}\\n`);\n return;\n }\n for (const d of manifest.directories) {\n await mkdir(join(home, d.path), { recursive: true, mode: d.mode ? parseInt(d.mode, 8) : undefined });\n }\n}\n\nasync function seedConfig(repoRoot: string, _configDir: string, dryRun: boolean, home: string): Promise<readonly string[]> {\n const { loadManifest } = await import('../install-manifest.js');\n const manifest = loadManifest(repoRoot);\n const seeded: string[] = [];\n for (const seed of manifest.configSeeds) {\n const src = join(repoRoot, seed.source);\n const dst = join(home, seed.dest);\n if (!(await exists(src))) continue;\n if (await exists(dst)) continue;\n if (dryRun) {\n seeded.push(`[dry-run] cp ${src} ${dst}`);\n continue;\n }\n const content = await readFile(src, 'utf-8');\n await mkdir(dirname(dst), { recursive: true });\n await writeFile(dst, content, { mode: seed.mode ? parseInt(seed.mode, 8) : 0o644 });\n seeded.push(basename(dst));\n }\n return seeded;\n}\n\n/**\n * Reconcile a single PATH symlink at ~/.local/bin/<name>.\n * Policy (plan \u00A7\"PATH symlink collision\"):\n * - Missing \u2192 create\n * - Symlink pointing into our own ~/.abtars/bin/ \u2192 overwrite\n * - Anything else \u2192 refuse with message, unless force\n */\nasync function reconcilePathLink(\n binDir: string,\n userBinDir: string,\n name: string,\n force: boolean,\n dryRun: boolean,\n): Promise<{ action: string; message?: string }> {\n const linkPath = join(userBinDir, name);\n const targetPath = join(binDir, name);\n const linkExists = await existsAny(linkPath);\n if (!linkExists) {\n if (dryRun) return { action: `[dry-run] ln -s ${targetPath} ${linkPath}` };\n await symlink(targetPath, linkPath);\n return { action: `created ${linkPath}` };\n }\n if (await isSymlink(linkPath)) {\n const { readlink, unlink } = await import('node:fs/promises');\n const current = await readlink(linkPath);\n // \"We own it\" means: points at THIS install's bin dir, not a fuzzy match\n // on any path containing /.abtars/bin/. A smoke-test install at\n // ABTARS_HOME=~/.cache/ab-smoke-.../ must not clobber the real\n // ~/.abtars symlinks. Compare absolute paths directly.\n const ownsIt = current === targetPath;\n if (ownsIt) {\n if (dryRun) return { action: `[dry-run] overwrite ${linkPath} (we own it)` };\n await unlink(linkPath);\n await symlink(targetPath, linkPath);\n return { action: `updated ${linkPath}` };\n }\n if (force) {\n if (dryRun) return { action: `[dry-run] --force overwrite ${linkPath} (currently -> ${current})` };\n await unlink(linkPath);\n await symlink(targetPath, linkPath);\n return { action: `forced overwrite ${linkPath} (was -> ${current})` };\n }\n return {\n action: 'refused',\n message: `${linkPath} is a symlink to ${current} (not ours). Pass --force to overwrite.`,\n };\n }\n if (force) {\n if (dryRun) return { action: `[dry-run] --force overwrite ${linkPath} (regular file)` };\n const { unlink } = await import('node:fs/promises');\n await unlink(linkPath);\n await symlink(targetPath, linkPath);\n return { action: `forced overwrite ${linkPath} (was regular file)` };\n }\n return {\n action: 'refused',\n message: `${linkPath} exists as a regular file (not our symlink). Pass --force to overwrite.`,\n };\n}\n\nexport async function writeWrapper(binDir: string, name: string, currentLink: string, dryRun: boolean): Promise<void> {\n const bundleFile = name === 'abtars' ? 'abtars-cli.js' : `${name}.js`;\n const target = join(currentLink, 'bundle', bundleFile);\n // Fallback: pre-bundle dist/ layout (tsc build) for installs that haven't migrated yet.\n const distFile = name === 'abtars' ? 'abtars.js' : `${name}.js`;\n const fallback = join(currentLink, 'dist', 'cli', distFile);\n const content = `#!/usr/bin/env bash\nif [ -f \"${target}\" ]; then\n exec node \"${target}\" \"$@\"\nelif [ -f \"${fallback}\" ]; then\n exec node \"${fallback}\" \"$@\"\nelse\n echo \"abtars: no release staged yet. Run 'abtars update' or 'npm run bundle' in the repo checkout.\" >&2\n exit 1\nfi\n`;\n const path = join(binDir, name);\n if (dryRun) {\n process.stdout.write(`[dry-run] write wrapper ${path} -> node ${target} (fallback: ${fallback})\\n`);\n return;\n }\n await writeFile(path, content, { mode: 0o755 });\n}\n\nfunction isPathOnPATH(userBinDir: string): boolean {\n const PATH = process.env['PATH'] ?? '';\n return PATH.split(':').some((p) => p === userBinDir);\n}\n\nfunction isWSL(): boolean {\n try {\n return existsSync(\"/proc/sys/fs/binfmt_misc/WSLInterop\")\n || /microsoft/i.test(readFileSync(\"/proc/version\", \"utf-8\"));\n } catch { return false; }\n}\n\nasync function installSupervisedDaemon(home: string, repoRoot: string, dryRun: boolean): Promise<number> {\n const platform = process.platform;\n\n // WSL: warn but don't block \u2014 systemd works on WSL2 with systemd enabled\n if (platform === 'linux' && isWSL()) {\n process.stderr.write(`\u2139\uFE0F WSL detected \u2014 ensure systemd is enabled (wsl.conf: [boot] systemd=true)\\n`);\n }\n\n // Sudo check \u2014 supervised-daemon requires root for system-scope service install\n const sudoUser = process.env['SUDO_USER'];\n if (process.getuid?.() !== 0) {\n process.stderr.write(\n `supervised-daemon requires sudo for system-scope service install.\\n` +\n `Run: sudo -k abtars install --mode=supervised-daemon\\n`,\n );\n return 2;\n }\n if (!sudoUser) {\n process.stderr.write(\n `Cannot determine target user \u2014 $SUDO_USER is not set.\\n` +\n `Run via: sudo -k abtars install --mode=supervised-daemon\\n` +\n `(Do not use 'su -' \u2014 it doesn't set SUDO_USER.)\\n`,\n );\n return 2;\n }\n\n // Validate that a normal install exists\n const currentLink = join(home, 'current');\n if (!existsSync(currentLink)) {\n process.stderr.write(\n `No release staged at ${currentLink}.\\n` +\n `Run 'abtars install' and 'abtars update' as ${sudoUser} first,\\n` +\n `then re-run with sudo for supervised-daemon.\\n`,\n );\n return 2;\n }\n\n const userGroup = sudoUser; // primary group = username on most systems\n\n if (platform === 'darwin') {\n // Resolve actual primary group on macOS\n const { execSync } = await import('node:child_process');\n let group = userGroup;\n try { group = execSync(`id -gn ${sudoUser}`, { encoding: 'utf-8' }).trim(); } catch (err) { logAndSwallow(\"install\", \"op\", err); }\n\n const plistSrc = join(repoRoot, 'scripts', 'com.abtars.daemon.plist');\n if (!existsSync(plistSrc)) {\n process.stderr.write(`Template not found: ${plistSrc}\\n`);\n return 1;\n }\n let content = readFileSync(plistSrc, 'utf-8');\n content = content.replaceAll('{{USER}}', sudoUser).replaceAll('{{GROUP}}', group);\n const dst = '/Library/LaunchDaemons/com.abtars.daemon.plist';\n\n if (dryRun) {\n process.stdout.write(`[dry-run] write ${dst}\\n[dry-run] launchctl bootstrap system ${dst}\\n`);\n return 0;\n }\n\n // Remove existing user-scope LaunchAgent if present\n const userAgent = join('/Users', sudoUser, 'Library', 'LaunchAgents', 'com.abtars.watchdog.plist');\n if (existsSync(userAgent)) {\n const { execFileSync } = await import('node:child_process');\n try { execFileSync('launchctl', ['bootout', `gui/${process.env['SUDO_UID'] ?? ''}`, userAgent]); } catch (err) { logAndSwallow(\"install\", \"op\", err); }\n process.stdout.write(`\u2713 disabled user-scope LaunchAgent\\n`);\n }\n\n const { writeFileSync, chmodSync } = await import('node:fs');\n writeFileSync(dst, content);\n chmodSync(dst, 0o644);\n const { execFileSync } = await import('node:child_process');\n try { execFileSync('launchctl', ['bootstrap', 'system', dst]); } catch (err) { logAndSwallow(\"install\", \"op\", err); }\n process.stdout.write(`\u2713 LaunchDaemon installed at ${dst}\\n`);\n process.stdout.write(`\u2713 supervised-daemon active \u2014 bridge runs as ${sudoUser}, survives logout + reboot\\n`);\n return 0;\n }\n\n if (platform === 'linux') {\n // systemd check\n const { execSync } = await import('node:child_process');\n try { execSync('systemctl --version', { stdio: 'ignore' }); } catch {\n process.stderr.write(`systemctl not found \u2014 supervised-daemon requires systemd.\\n`);\n return 2;\n }\n\n const unitSrc = join(repoRoot, 'scripts', 'abtars-daemon.service');\n if (!existsSync(unitSrc)) {\n process.stderr.write(`Template not found: ${unitSrc}\\n`);\n return 1;\n }\n let content = readFileSync(unitSrc, 'utf-8');\n content = content.replaceAll('{{USER}}', sudoUser);\n const dst = '/etc/systemd/system/abtars.service';\n\n if (dryRun) {\n process.stdout.write(`[dry-run] write ${dst}\\n[dry-run] systemctl enable --now abtars\\n`);\n return 0;\n }\n\n const { writeFileSync } = await import('node:fs');\n writeFileSync(dst, content);\n const { execFileSync } = await import('node:child_process');\n execFileSync('systemctl', ['daemon-reload']);\n execFileSync('systemctl', ['enable', '--now', 'abtars']);\n process.stdout.write(`\u2713 systemd unit installed at ${dst}\\n`);\n process.stdout.write(`\u2713 supervised-daemon active \u2014 bridge runs as ${sudoUser}, survives logout + reboot\\n`);\n return 0;\n }\n\n process.stderr.write(`supervised-daemon is not supported on ${platform}.\\n`);\n return 2;\n}\n\nexport async function install(opts: InstallOptions): Promise<number> {\n const paths = packagePaths('abtars');\n const home = paths.home;\n const userBinDir = resolveUserBinDir();\n const repoRoot = process.cwd();\n\n // Install log (#718)\n const { initInstallLog, logInstall, logInstallHeader } = await import(\"../install-log.js\");\n initInstallLog(home);\n logInstallHeader(\"install\");\n const _origWrite = process.stdout.write.bind(process.stdout);\n process.stdout.write = ((chunk: any, ...args: any[]) => {\n if (typeof chunk === \"string\" && (chunk.startsWith(\"\u2713\") || chunk.startsWith(\"\u26A0\"))) logInstall(chunk.trimEnd());\n return _origWrite(chunk, ...args);\n }) as typeof process.stdout.write;\n\n const homeExists = await exists(home);\n const manifest = homeExists ? await readManifest(paths.manifest) : null;\n\n if (homeExists && manifest && !opts.force && !opts.restore) {\n process.stderr.write(\n `~/.abtars already installed at version ${manifest.version || '(unset)'}.\\nUse 'abtars update' to upgrade, or --force to re-seed missing config.\\n`,\n );\n return 2;\n }\n\n // Create skeleton (idempotent)\n await createSkeleton(home, opts.dryRun);\n process.stdout.write(`\u2713 skeleton at ${home}\\n`);\n\n // Core templates: abmind seeds its own on first boot (#427 ensureInitialized).\n // No longer seeded by abtars install.\n\n // Create kiro-cli agent config \u2014 ACP transport needs ~/.kiro/agents/professor.json\n const kiroAgentsDir = join(homedir(), '.kiro', 'agents');\n const professorJson = join(kiroAgentsDir, 'professor.json');\n if (!opts.dryRun) {\n await mkdir(kiroAgentsDir, { recursive: true });\n if (!(await exists(professorJson))) {\n await writeFile(professorJson, JSON.stringify({\n name: \"professor\",\n description: \"Abtars bridge agent\",\n tools: [\"*\"],\n allowedTools: [\"@builtin\"],\n toolsSettings: { shell: { autoAllowReadonly: true } },\n includeMcpJson: true,\n }, null, 2) + '\\n');\n process.stdout.write(`\u2713 kiro agent: ${professorJson}\\n`);\n }\n } else {\n process.stdout.write(`[dry-run] create ${professorJson}\\n`);\n }\n\n // Generate Ed25519 identity keypair (skip if already exists)\n const identityKey = join(paths.config, 'identity.key');\n const identityPub = join(paths.config, 'identity.pub');\n if (!opts.dryRun && !(await exists(identityKey))) {\n const { generateKeyPairSync } = await import('node:crypto');\n const { privateKey, publicKey } = generateKeyPairSync('ed25519');\n await writeFile(identityKey, privateKey.export({ format: 'der', type: 'pkcs8' }).toString('base64'));\n await writeFile(identityPub, publicKey.export({ format: 'der', type: 'spki' }).toString('base64'));\n const { chmodSync } = await import('node:fs');\n chmodSync(identityKey, 0o600);\n process.stdout.write(`\u2713 identity keypair generated\\n`);\n }\n\n // Generate self-signed Ed25519 TLS certificate (skip if already exists)\n const identityCrt = join(paths.config, 'identity.crt');\n const identityTlsKey = join(paths.config, 'identity.tls.key');\n if (!opts.dryRun && !(await exists(identityCrt))) {\n const { execSync } = await import('node:child_process');\n const { chmodSync } = await import('node:fs');\n const agentName = hostname();\n try {\n execSync(`openssl req -x509 -newkey ed25519 -keyout identity.tls.key -out identity.crt -days 3650 -nodes -subj \"/CN=${agentName}\"`, { cwd: paths.config, stdio: 'ignore' });\n chmodSync(identityTlsKey, 0o600);\n process.stdout.write(`\u2713 TLS certificate generated (Ed25519, 10yr)\\n`);\n } catch (err) {\n process.stderr.write(`\u26A0 TLS cert generation failed (openssl not found?). Agent-api will start without TLS.\\n`);\n }\n }\n\n // Seed config from examples (only missing ones)\n const seeded = await seedConfig(repoRoot, paths.config, opts.dryRun, home);\n if (seeded.length > 0) {\n process.stdout.write(`\u2713 seeded config: ${seeded.join(', ')}\\n`);\n }\n\n // Write wrappers (always overwrite \u2014 they're regenerable thin shims)\n const { loadManifest: loadInstallManifest } = await import('../install-manifest.js');\n const installManifest = loadInstallManifest(repoRoot);\n if (!opts.dryRun) {\n await mkdir(paths.bin, { recursive: true });\n }\n for (const name of installManifest.cliWrappers) {\n await writeWrapper(paths.bin, name, paths.current, opts.dryRun);\n }\n process.stdout.write(`\u2713 wrappers in ${paths.bin}\\n`);\n\n // Reconcile PATH symlinks\n if (!opts.dryRun) await mkdir(userBinDir, { recursive: true });\n const refused: string[] = [];\n for (const name of installManifest.cliWrappers) {\n const r = await reconcilePathLink(paths.bin, userBinDir, name, opts.force, opts.dryRun);\n if (r.action === 'refused') {\n refused.push(r.message ?? name);\n }\n }\n if (refused.length > 0) {\n process.stderr.write(`\\nPATH symlink conflicts:\\n ${refused.join('\\n ')}\\n`);\n return 4;\n }\n process.stdout.write(`\u2713 PATH symlinks in ${userBinDir}\\n`);\n\n // Warn if ~/.local/bin not on PATH\n if (!isPathOnPATH(userBinDir)) {\n process.stderr.write(\n `\\nWarning: ${userBinDir} is not on $PATH. Add to your shell config:\\n export PATH=\"${userBinDir}:$PATH\"\\n`,\n );\n }\n\n // Initialize manifest if brand-new install AND migration didn't write one.\n // (Migration 003 writes a manifest mid-flow with version + migration record;\n // we must not clobber it here.)\n const manifestAfter = await readManifest(paths.manifest);\n if (manifestAfter === null && !opts.dryRun) {\n await writeManifest(paths.manifest, {\n ...emptyManifest('abtars', hostname()),\n version: '',\n preMigrationBackup: null,\n });\n process.stdout.write(`\u2713 manifest initialized at ${paths.manifest}\\n`);\n }\n\n // Write install mode to manifest. Priority:\n // 1. --mode flag (explicit) \u2014 always wins\n // 2. existing manifest installMode \u2014 preserved (don't clobber on --force)\n // 3. default: supervised\n const manifestForMode = await readManifest(paths.manifest);\n const existingMode = manifestForMode?.installMode;\n const mode = opts.mode ?? existingMode ?? \"supervised\";\n if (manifestForMode) {\n await writeManifest(paths.manifest, { ...manifestForMode, installMode: mode });\n }\n process.stdout.write(`\u2713 install mode: ${mode}\\n`);\n\n // --- supervised-daemon: system-scope service install (additive, does not touch simple/supervised paths) ---\n if (mode === 'supervised-daemon') {\n return installSupervisedDaemon(home, repoRoot, opts.dryRun);\n }\n\n // Restore from backup zip\n if (opts.restore) {\n const { spawnSync } = await import('node:child_process');\n const { existsSync: fileExists } = await import('node:fs');\n const zipPath = opts.restore;\n if (!fileExists(zipPath)) {\n process.stderr.write(`error: backup file not found: ${zipPath}\\n`);\n return 1;\n }\n // Extract to temp dir\n const tmpDir = join(process.env['TMPDIR'] ?? '/tmp', `abtars-restore-${Date.now()}`);\n const unzip = spawnSync('unzip', ['-o', zipPath, '-d', tmpDir], { encoding: 'utf-8' });\n if (unzip.status !== 0) {\n process.stderr.write(`error: unzip failed: ${unzip.stderr}\\n`);\n return 1;\n }\n // Copy abtars files\n const abSrc = join(tmpDir, 'abtars');\n if (fileExists(abSrc)) {\n spawnSync('cp', ['-r', ...readdirSync(abSrc).map(f => join(abSrc, f)), home], { stdio: 'inherit' });\n process.stdout.write(`\u2713 restored abtars config\\n`);\n }\n // Copy abmind files\n const abmindHome = process.env['ABMIND_HOME'] ?? join(dirname(home), '.abmind');\n const abmindSrc = join(tmpDir, 'abmind');\n if (fileExists(abmindSrc)) {\n spawnSync('cp', ['-r', ...readdirSync(abmindSrc).map(f => join(abmindSrc, f)), abmindHome], { stdio: 'inherit' });\n process.stdout.write(`\u2713 restored abmind data\\n`);\n }\n // Cleanup\n spawnSync('rm', ['-rf', tmpDir]);\n process.stdout.write(`\\nRestore complete.\\n`);\n process.stdout.write(`Next: 'abtars update' to build and activate.\\n`);\n return 0;\n }\n\n // --- supervised: load user-scope watchdog (LaunchAgent / systemd user) ---\n if (mode === 'supervised') {\n const { execSync } = await import('node:child_process');\n if (process.platform === 'darwin') {\n const plistSrc = join(home, 'scripts', 'com.abtars.watchdog.plist');\n const plistDst = join(homedir(), 'Library', 'LaunchAgents', 'com.abtars.watchdog.plist');\n if (existsSync(plistSrc)) {\n const content = readFileSync(plistSrc, 'utf-8').replaceAll('{{HOME}}', homedir());\n const { writeFileSync } = await import('node:fs');\n writeFileSync(plistDst, content);\n try { execSync(`launchctl load \"${plistDst}\"`, { stdio: 'ignore' }); } catch { /* already loaded */ }\n process.stdout.write(`\u2713 watchdog LaunchAgent loaded\\n`);\n }\n } else if (process.platform === 'linux') {\n const unitSrc = join(home, 'scripts', 'abtars-watchdog.service');\n const unitDir = join(homedir(), '.config', 'systemd', 'user');\n if (existsSync(unitSrc)) {\n mkdirSync(unitDir, { recursive: true });\n copyFileSync(unitSrc, join(unitDir, 'abtars-watchdog.service'));\n try { execSync('systemctl --user daemon-reload && systemctl --user enable --now abtars-watchdog', { stdio: 'ignore' }); } catch { /* may fail in chroot */ }\n process.stdout.write(`\u2713 watchdog systemd user service enabled\\n`);\n }\n }\n }\n\n process.stdout.write(`\\nInstall complete.\\n`);\n if (!manifestAfter || manifestAfter.version === '') {\n process.stdout.write(`Next: 'abtars update' to build and activate the first release.\\n`);\n } else {\n process.stdout.write(`\\n\u2500\u2500 Next steps \u2500\u2500\\n`);\n process.stdout.write(` 1. Run 'abtars onboard' to configure Telegram token + model provider\\n`);\n process.stdout.write(` 2. (Optional) Install Ollama for memory embeddings: curl -fsSL https://ollama.com/install.sh | sh\\n`);\n process.stdout.write(` 3. Start the bridge: 'abtars restart' or use the watchdog\\n\\n`);\n }\n\n const { printHealthSummary } = await import('./health-check.js');\n printHealthSummary(paths.home);\n\n // #334: Post-install healthcheck \u2014 validate operator channel exists (only on --restore)\n if (!opts.dryRun && opts.restore) {\n const { validateMinimumViability, formatValidationError } = await import('./install-validate.js');\n const validation = validateMinimumViability(paths.config);\n if (!validation.ok) {\n const invocation = `abtars install --restore ${opts.restore}`;\n process.stderr.write(\"\\n\" + formatValidationError(validation, invocation) + \"\\n\");\n return 1;\n }\n }\n\n return 0;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["execFileSync"]
|
|
7
|
+
}
|