abtars 0.2.1-alpha.8 → 0.2.1-alpha.9
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/README.md +15 -18
- package/bundle/abtars-cli.js +198 -104
- package/bundle/abtars-cli.js.map +3 -3
- package/bundle/abtars.js +20 -3
- package/bundle/abtars.js.map +2 -2
- package/bundle/meta.json +50 -20
- package/bundle/restore-MFSW3EBL.js +151 -0
- package/bundle/restore-MFSW3EBL.js.map +7 -0
- package/core/skills/tools/gmail/SKILL.md +14 -5
- package/package.json +2 -3
- package/scripts/daily-backup.sh +1 -79
- package/CHANGELOG.md +0 -64
- package/bundle/chunk-RJJWPMUZ.js +0 -411
- package/bundle/chunk-RJJWPMUZ.js.map +0 -7
- package/bundle/chunk-RVERPUHT.js +0 -289
- package/bundle/chunk-RVERPUHT.js.map +0 -7
- package/bundle/deploy-lib-import-HCMZCKZD.js +0 -50
- package/bundle/deploy-lib-import-HCMZCKZD.js.map +0 -7
- package/bundle/install-GEXWJYJC.js +0 -13
- package/bundle/install-GEXWJYJC.js.map +0 -7
- package/bundle/restore-ROJF22R2.js +0 -47
- package/bundle/restore-ROJF22R2.js.map +0 -7
package/README.md
CHANGED
|
@@ -29,31 +29,28 @@ abTARS (agent brain)
|
|
|
29
29
|
## Quick Start
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
npm install -g abtars
|
|
33
|
-
|
|
32
|
+
npm install -g abtars@alpha abmind@alpha
|
|
33
|
+
abmind install
|
|
34
|
+
abtars install
|
|
35
|
+
abtars update
|
|
36
|
+
abtars onboard
|
|
37
|
+
sudo $(which abtars) daemon install
|
|
34
38
|
```
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
1. Telegram bot token (from [@BotFather](https://t.me/BotFather))
|
|
38
|
-
2. Model provider (kiro-cli, gemini-cli, ollama, or OpenRouter)
|
|
39
|
-
3. Your user ID
|
|
40
|
-
|
|
41
|
-
Then start:
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
abtars start
|
|
45
|
-
```
|
|
40
|
+
Full installation guide: **[docs/wiki/install.md](docs/wiki/install.md)**
|
|
46
41
|
|
|
47
42
|
## Documentation
|
|
48
43
|
|
|
49
|
-
|
|
44
|
+
Docs live in the repo at **[docs/wiki/](docs/wiki/)** — always up to date with the code.
|
|
50
45
|
|
|
51
|
-
- [Installation](
|
|
52
|
-
- [Configuration](
|
|
53
|
-
- [Commands](
|
|
46
|
+
- [Installation](docs/wiki/install.md)
|
|
47
|
+
- [Configuration](docs/wiki/commands.md)
|
|
48
|
+
- [Commands](docs/wiki/cli.md)
|
|
54
49
|
- [Memory System (abmind)](https://github.com/aksika/abmind)
|
|
55
|
-
- [Skills & Extensions](
|
|
56
|
-
- [Deployment &
|
|
50
|
+
- [Skills & Extensions](docs/wiki/skills.md)
|
|
51
|
+
- [Deployment & Supervision](docs/wiki/supervision.md)
|
|
52
|
+
|
|
53
|
+
> **Note:** The [aksika.github.io](https://aksika.github.io/abtars/) site may be outdated. Always refer to the docs in this repo.
|
|
57
54
|
|
|
58
55
|
## Supported Transports
|
|
59
56
|
|
package/bundle/abtars-cli.js
CHANGED
|
@@ -301,112 +301,198 @@ async function uninstall(opts) {
|
|
|
301
301
|
|
|
302
302
|
// src/cli/commands/backup.ts
|
|
303
303
|
init_paths();
|
|
304
|
-
import { existsSync as existsSync3, mkdirSync, readdirSync as readdirSync2, statSync, renameSync,
|
|
305
|
-
import { join as join4, dirname } from "node:path";
|
|
304
|
+
import { existsSync as existsSync3, mkdirSync, readdirSync as readdirSync2, statSync, unlinkSync as unlinkSync3, renameSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
|
|
305
|
+
import { join as join4, dirname, basename } from "node:path";
|
|
306
306
|
import { spawnSync } from "node:child_process";
|
|
307
|
-
|
|
307
|
+
import { createCipheriv, hkdfSync, randomBytes } from "node:crypto";
|
|
308
308
|
var DEFAULT_PRUNE_DAYS = 7;
|
|
309
|
-
|
|
309
|
+
var ABTARS_EXCLUDE = [
|
|
310
|
+
"releases",
|
|
311
|
+
"current",
|
|
312
|
+
"bin",
|
|
313
|
+
"app",
|
|
314
|
+
"logs",
|
|
315
|
+
"node_modules",
|
|
316
|
+
"overflow",
|
|
317
|
+
"browser-socket",
|
|
318
|
+
"bridge.lock",
|
|
319
|
+
"watchdog.lock",
|
|
320
|
+
"browse-spawn.sock",
|
|
321
|
+
"*.sock"
|
|
322
|
+
];
|
|
323
|
+
var ABMIND_EXCLUDE = [
|
|
324
|
+
"memory/memory.db",
|
|
325
|
+
"lib",
|
|
326
|
+
"node_modules",
|
|
327
|
+
"backups",
|
|
328
|
+
"*.sock",
|
|
329
|
+
"*.db-wal",
|
|
330
|
+
"*.db-shm"
|
|
331
|
+
];
|
|
332
|
+
var CONFIG_DIRS = ["config", "secret", "tasks", "skills", "core", "agents"];
|
|
333
|
+
async function backup(opts = {}) {
|
|
310
334
|
const abHome = abtarsHome();
|
|
335
|
+
const abmindHome = process.env["ABMIND_HOME"] ?? join4(dirname(abHome), ".abmind");
|
|
311
336
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
312
|
-
const destDir = outputDir ?? join4(dirname(abHome), ".backup-abtars");
|
|
337
|
+
const destDir = opts.outputDir ?? join4(dirname(abHome), ".backup-abtars");
|
|
313
338
|
mkdirSync(destDir, { recursive: true });
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
const abmindBin = abmindPaths.find((p) => existsSync3(p));
|
|
319
|
-
let abmResult;
|
|
320
|
-
if (abmindBin) {
|
|
321
|
-
abmResult = spawnSync("node", [abmindBin], { encoding: "utf-8", env: { ...process.env } });
|
|
322
|
-
} else {
|
|
323
|
-
abmResult = spawnSync("abmind", ["backup"], { encoding: "utf-8", env: { ...process.env } });
|
|
324
|
-
}
|
|
325
|
-
if (abmResult.status !== 0) {
|
|
326
|
-
process.stderr.write(`\u26A0\uFE0F abmind backup failed: ${abmResult.stderr || abmResult.stdout}
|
|
327
|
-
`);
|
|
328
|
-
return 1;
|
|
329
|
-
}
|
|
330
|
-
const abmindBackupsDir = join4(dirname(abHome), ".abmind", "backups");
|
|
331
|
-
let abmFile;
|
|
332
|
-
if (existsSync3(abmindBackupsDir)) {
|
|
333
|
-
const abmFiles = readdirSync2(abmindBackupsDir).filter((f) => f.endsWith(".abm")).sort().reverse();
|
|
334
|
-
if (abmFiles.length > 0) abmFile = abmFiles[0];
|
|
335
|
-
}
|
|
336
|
-
if (abmFile) {
|
|
337
|
-
const src = join4(abmindBackupsDir, abmFile);
|
|
338
|
-
const dest = join4(destDir, `abmind-${date}.abm`);
|
|
339
|
-
renameSync(src, dest);
|
|
340
|
-
const size = (statSync(dest).size / 1024).toFixed(0);
|
|
341
|
-
process.stdout.write(`\u2713 abmind-${date}.abm (${size}KB, encrypted)
|
|
342
|
-
`);
|
|
339
|
+
const isConfig = opts.config === true;
|
|
340
|
+
const prefix = isConfig ? `abtars-config-${date}` : `abtars-${date}`;
|
|
341
|
+
const zipExcludes = [];
|
|
342
|
+
if (isConfig) {
|
|
343
343
|
} else {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
for (const dir of AB_SAVE) {
|
|
349
|
-
const abs = join4(abHome, dir);
|
|
350
|
-
if (existsSync3(abs)) collectDir(abs, dir, files);
|
|
351
|
-
}
|
|
352
|
-
if (files.length === 0) {
|
|
353
|
-
process.stderr.write("Nothing to zip from abtars.\n");
|
|
354
|
-
return 1;
|
|
355
|
-
}
|
|
356
|
-
const tmpDir = join4(process.env["TMPDIR"] ?? "/tmp", `abtars-backup-${Date.now()}`);
|
|
357
|
-
mkdirSync(tmpDir, { recursive: true });
|
|
358
|
-
for (const f of files) {
|
|
359
|
-
const dest = join4(tmpDir, f.zipPath);
|
|
360
|
-
mkdirSync(dirname(dest), { recursive: true });
|
|
361
|
-
copyFileSync(f.absPath, dest);
|
|
344
|
+
for (const ex of ABTARS_EXCLUDE) {
|
|
345
|
+
zipExcludes.push(`${ex}/*`, ex);
|
|
346
|
+
}
|
|
347
|
+
zipExcludes.push("*.db-wal", "*.db-shm", "*.sock");
|
|
362
348
|
}
|
|
363
|
-
const zipPath = join4(destDir, `abtars-${date}.zip`);
|
|
364
349
|
const has7z = spawnSync("which", ["7z"], { encoding: "utf-8" }).status === 0;
|
|
350
|
+
const zipExt = has7z ? ".7z" : ".zip";
|
|
351
|
+
let zipPath = join4(destDir, prefix + zipExt);
|
|
365
352
|
let zipOk;
|
|
366
|
-
if (
|
|
367
|
-
const
|
|
368
|
-
|
|
353
|
+
if (isConfig) {
|
|
354
|
+
const existingDirs = CONFIG_DIRS.filter((d) => existsSync3(join4(abHome, d)));
|
|
355
|
+
if (existingDirs.length === 0) {
|
|
356
|
+
process.stderr.write("Nothing to backup \u2014 no config dirs found\n");
|
|
357
|
+
return 1;
|
|
358
|
+
}
|
|
359
|
+
if (has7z) {
|
|
360
|
+
const r = spawnSync("7z", ["a", zipPath, ...existingDirs], { cwd: abHome, encoding: "utf-8" });
|
|
361
|
+
zipOk = r.status === 0;
|
|
362
|
+
} else {
|
|
363
|
+
const r = spawnSync("zip", ["-qr", zipPath, ...existingDirs], { cwd: abHome, encoding: "utf-8" });
|
|
364
|
+
zipOk = r.status === 0;
|
|
365
|
+
}
|
|
369
366
|
} else {
|
|
370
|
-
|
|
371
|
-
|
|
367
|
+
if (has7z) {
|
|
368
|
+
const excludeArgs = ABTARS_EXCLUDE.flatMap((ex) => ["-xr!" + ex]);
|
|
369
|
+
excludeArgs.push("-xr!*.db-wal", "-xr!*.db-shm", "-xr!*.sock");
|
|
370
|
+
const r = spawnSync("7z", ["a", zipPath, ".", ...excludeArgs], { cwd: abHome, encoding: "utf-8" });
|
|
371
|
+
zipOk = r.status === 0;
|
|
372
|
+
} else {
|
|
373
|
+
const excludeArgs = ABTARS_EXCLUDE.flatMap((ex) => ["-x", `${ex}/*`, "-x", ex]);
|
|
374
|
+
excludeArgs.push("-x", "*.db-wal", "-x", "*.db-shm", "-x", "*.sock");
|
|
375
|
+
const r = spawnSync("zip", ["-qr", zipPath, ".", ...excludeArgs], { cwd: abHome, encoding: "utf-8" });
|
|
376
|
+
zipOk = r.status === 0;
|
|
377
|
+
}
|
|
378
|
+
if (zipOk && existsSync3(abmindHome)) {
|
|
379
|
+
if (has7z) {
|
|
380
|
+
const excludeArgs = ABMIND_EXCLUDE.flatMap((ex) => ["-xr!" + ex]);
|
|
381
|
+
const r = spawnSync("7z", ["a", zipPath, ".", ...excludeArgs], { cwd: abmindHome, encoding: "utf-8" });
|
|
382
|
+
zipOk = r.status === 0;
|
|
383
|
+
} else {
|
|
384
|
+
const excludeArgs = ABMIND_EXCLUDE.flatMap((ex) => ["-x", `${ex}/*`, "-x", ex]);
|
|
385
|
+
const r = spawnSync("zip", ["-qr", zipPath, "-g", ".", ...excludeArgs], { cwd: abmindHome, encoding: "utf-8" });
|
|
386
|
+
zipOk = r.status === 0;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const dbPath = join4(abmindHome, "memory", "memory.db");
|
|
390
|
+
if (zipOk && existsSync3(dbPath)) {
|
|
391
|
+
const tmpDb = join4(process.env["TMPDIR"] ?? "/tmp", `abtars-backup-memory-${Date.now()}.db`);
|
|
392
|
+
const sqliteResult = spawnSync("sqlite3", [dbPath, `.backup '${tmpDb}'`], { encoding: "utf-8" });
|
|
393
|
+
if (sqliteResult.status === 0 && existsSync3(tmpDb)) {
|
|
394
|
+
if (has7z) {
|
|
395
|
+
spawnSync("7z", ["a", zipPath, tmpDb], { encoding: "utf-8" });
|
|
396
|
+
} else {
|
|
397
|
+
spawnSync("zip", ["-qj", zipPath, tmpDb], { encoding: "utf-8" });
|
|
398
|
+
}
|
|
399
|
+
try {
|
|
400
|
+
unlinkSync3(tmpDb);
|
|
401
|
+
} catch {
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
372
405
|
}
|
|
373
|
-
spawnSync("rm", ["-rf", tmpDir]);
|
|
374
406
|
if (!zipOk) {
|
|
375
|
-
process.stderr.write(
|
|
376
|
-
`);
|
|
407
|
+
process.stderr.write("Backup zip failed\n");
|
|
377
408
|
return 1;
|
|
378
409
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
410
|
+
if (!isConfig) {
|
|
411
|
+
const actual = statSync(zipPath).size;
|
|
412
|
+
if (actual < 1e5) {
|
|
413
|
+
process.stderr.write(`\u26A0\uFE0F Backup suspiciously small (${actual} bytes)
|
|
382
414
|
`);
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
if (!(f.endsWith(".zip") || f.endsWith(".7z") || f.endsWith(".abm"))) continue;
|
|
388
|
-
const fPath = join4(destDir, f);
|
|
389
|
-
try {
|
|
390
|
-
if (now - statSync(fPath).mtimeMs > maxAge) {
|
|
391
|
-
unlinkSync3(fPath);
|
|
392
|
-
process.stdout.write(` \u{1F5D1} pruned ${f}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
const zipSize = (statSync(zipPath).size / 1024 / 1024).toFixed(1);
|
|
418
|
+
process.stdout.write(`\u2713 ${basename(zipPath)} (${zipSize}MB)
|
|
393
419
|
`);
|
|
420
|
+
if (opts.encrypt) {
|
|
421
|
+
const encPath = zipPath + ".enc";
|
|
422
|
+
const ok = encryptFile(zipPath, encPath, abmindHome);
|
|
423
|
+
if (!ok) return 1;
|
|
424
|
+
unlinkSync3(zipPath);
|
|
425
|
+
zipPath = encPath;
|
|
426
|
+
process.stdout.write(`\u2713 encrypted \u2192 ${basename(encPath)}
|
|
427
|
+
`);
|
|
428
|
+
}
|
|
429
|
+
if (!isConfig) {
|
|
430
|
+
const abmResult = runAbmindBackup(abHome, abmindHome);
|
|
431
|
+
if (abmResult) {
|
|
432
|
+
const dest = join4(destDir, `abmind-${date}.abm`);
|
|
433
|
+
renameSync(abmResult, dest);
|
|
434
|
+
const size = (statSync(dest).size / 1024).toFixed(0);
|
|
435
|
+
process.stdout.write(`\u2713 abmind-${date}.abm (${size}KB, encrypted)
|
|
436
|
+
`);
|
|
437
|
+
} else {
|
|
438
|
+
process.stderr.write("\u26A0\uFE0F abmind backup failed or produced no .abm\n");
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
const pruneDays = opts.pruneDays ?? DEFAULT_PRUNE_DAYS;
|
|
442
|
+
if (pruneDays > 0) {
|
|
443
|
+
const maxAge = pruneDays * 864e5;
|
|
444
|
+
const now = Date.now();
|
|
445
|
+
for (const f of readdirSync2(destDir)) {
|
|
446
|
+
if (!(f.startsWith("abtars-") || f.startsWith("abmind-"))) continue;
|
|
447
|
+
if (!(f.endsWith(".zip") || f.endsWith(".7z") || f.endsWith(".abm") || f.endsWith(".enc"))) continue;
|
|
448
|
+
const fPath = join4(destDir, f);
|
|
449
|
+
try {
|
|
450
|
+
if (now - statSync(fPath).mtimeMs > maxAge) {
|
|
451
|
+
unlinkSync3(fPath);
|
|
452
|
+
process.stdout.write(` \u{1F5D1} pruned ${f}
|
|
453
|
+
`);
|
|
454
|
+
}
|
|
455
|
+
} catch {
|
|
394
456
|
}
|
|
395
|
-
} catch {
|
|
396
457
|
}
|
|
397
458
|
}
|
|
398
459
|
return 0;
|
|
399
460
|
}
|
|
400
|
-
function
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
}
|
|
461
|
+
function runAbmindBackup(abHome, abmindHome) {
|
|
462
|
+
const abmindPaths = [
|
|
463
|
+
join4(dirname(abHome), "workspace", "ab", "abmind", "dist", "cli", "abmind-backup.js"),
|
|
464
|
+
join4(abmindHome, "lib", "node_modules", "abmind", "dist", "cli", "abmind-backup.js")
|
|
465
|
+
];
|
|
466
|
+
const abmindBin = abmindPaths.find((p) => existsSync3(p));
|
|
467
|
+
let result;
|
|
468
|
+
if (abmindBin) {
|
|
469
|
+
result = spawnSync("node", [abmindBin], { encoding: "utf-8", env: { ...process.env } });
|
|
470
|
+
} else {
|
|
471
|
+
result = spawnSync("abmind", ["backup"], { encoding: "utf-8", env: { ...process.env } });
|
|
409
472
|
}
|
|
473
|
+
if (result.status !== 0) return null;
|
|
474
|
+
const backupsDir = join4(abmindHome, "backups");
|
|
475
|
+
if (!existsSync3(backupsDir)) return null;
|
|
476
|
+
const abmFiles = readdirSync2(backupsDir).filter((f) => f.endsWith(".abm")).sort().reverse();
|
|
477
|
+
return abmFiles[0] ? join4(backupsDir, abmFiles[0]) : null;
|
|
478
|
+
}
|
|
479
|
+
function encryptFile(inputPath, outputPath, abmindHome) {
|
|
480
|
+
const keyPath = join4(abmindHome, "secret", "abmind.key");
|
|
481
|
+
if (!existsSync3(keyPath)) {
|
|
482
|
+
process.stderr.write(`\u26A0\uFE0F --encrypt requires ${keyPath}
|
|
483
|
+
`);
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
const master = Buffer.from(readFileSync2(keyPath, "utf-8").trim(), "hex");
|
|
487
|
+
const key = Buffer.from(hkdfSync("sha256", master, "", "abtars-backup-v1", 32));
|
|
488
|
+
const iv = randomBytes(12);
|
|
489
|
+
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
490
|
+
const input = readFileSync2(inputPath);
|
|
491
|
+
const encrypted = Buffer.concat([cipher.update(input), cipher.final()]);
|
|
492
|
+
const tag = cipher.getAuthTag();
|
|
493
|
+
const out = Buffer.concat([iv, encrypted, tag]);
|
|
494
|
+
writeFileSync(outputPath, out);
|
|
495
|
+
return true;
|
|
410
496
|
}
|
|
411
497
|
|
|
412
498
|
// src/cli/commands/onboard.ts
|
|
@@ -417,7 +503,7 @@ import { homedir as homedir2 } from "node:os";
|
|
|
417
503
|
import { fileURLToPath } from "node:url";
|
|
418
504
|
|
|
419
505
|
// src/components/hints.ts
|
|
420
|
-
import { existsSync as existsSync4, readFileSync as
|
|
506
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2, renameSync as renameSync2 } from "node:fs";
|
|
421
507
|
import { join as join5 } from "node:path";
|
|
422
508
|
function manifestPath() {
|
|
423
509
|
const home = process.env["ABTARS_HOME"] ?? join5(process.env["HOME"] ?? "", ".abtars");
|
|
@@ -427,7 +513,7 @@ function readManifest2() {
|
|
|
427
513
|
const path = manifestPath();
|
|
428
514
|
if (!existsSync4(path)) return {};
|
|
429
515
|
try {
|
|
430
|
-
return JSON.parse(
|
|
516
|
+
return JSON.parse(readFileSync3(path, "utf-8"));
|
|
431
517
|
} catch {
|
|
432
518
|
return {};
|
|
433
519
|
}
|
|
@@ -435,7 +521,7 @@ function readManifest2() {
|
|
|
435
521
|
function writeManifestAtomic(data) {
|
|
436
522
|
const path = manifestPath();
|
|
437
523
|
const tmp = path + ".tmp";
|
|
438
|
-
|
|
524
|
+
writeFileSync2(tmp, JSON.stringify(data, null, 2) + "\n");
|
|
439
525
|
renameSync2(tmp, path);
|
|
440
526
|
}
|
|
441
527
|
function showHintOnce(id, text) {
|
|
@@ -1209,7 +1295,7 @@ Rollback complete.
|
|
|
1209
1295
|
|
|
1210
1296
|
// src/cli/commands/status.ts
|
|
1211
1297
|
import { existsSync as existsSync6 } from "node:fs";
|
|
1212
|
-
import { readFileSync as
|
|
1298
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
1213
1299
|
import { join as join8 } from "node:path";
|
|
1214
1300
|
async function status() {
|
|
1215
1301
|
const paths = packagePaths("abtars");
|
|
@@ -1239,7 +1325,7 @@ Run 'abtars install' to set up.
|
|
|
1239
1325
|
` host: ${manifest.host}`
|
|
1240
1326
|
];
|
|
1241
1327
|
try {
|
|
1242
|
-
const bridgeLock = JSON.parse(
|
|
1328
|
+
const bridgeLock = JSON.parse(readFileSync4(join8(paths.home, "bridge.lock"), "utf-8"));
|
|
1243
1329
|
if (bridgeLock.pid) {
|
|
1244
1330
|
const alive = (() => {
|
|
1245
1331
|
try {
|
|
@@ -1280,7 +1366,7 @@ Run 'abtars install' to set up.
|
|
|
1280
1366
|
// src/cli/commands/update.ts
|
|
1281
1367
|
import { hostname } from "node:os";
|
|
1282
1368
|
import { join as join11 } from "node:path";
|
|
1283
|
-
import { readFileSync as
|
|
1369
|
+
import { readFileSync as readFileSync6, existsSync as existsSync9 } from "node:fs";
|
|
1284
1370
|
import { copyFile as copyFile2, mkdir as mkdir4, chmod, readdir } from "node:fs/promises";
|
|
1285
1371
|
import { rmSync as rmSync3, cpSync, readdirSync as readdirSync3, mkdirSync as mkdirSync2 } from "node:fs";
|
|
1286
1372
|
|
|
@@ -1411,7 +1497,7 @@ function makeLocalBuildSource(opts = {}) {
|
|
|
1411
1497
|
|
|
1412
1498
|
// src/cli/update-sources/npm.ts
|
|
1413
1499
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
1414
|
-
import { existsSync as existsSync8, readFileSync as
|
|
1500
|
+
import { existsSync as existsSync8, readFileSync as readFileSync5, unlinkSync as unlinkSync4 } from "node:fs";
|
|
1415
1501
|
import { mkdir as mkdir3, rm as rm2 } from "node:fs/promises";
|
|
1416
1502
|
import { join as join10 } from "node:path";
|
|
1417
1503
|
var TIMEOUT_MS = 6e4;
|
|
@@ -1423,7 +1509,7 @@ function run(cmd, args, cwd) {
|
|
|
1423
1509
|
}
|
|
1424
1510
|
function readLocalVersion(home) {
|
|
1425
1511
|
try {
|
|
1426
|
-
const pkg = JSON.parse(
|
|
1512
|
+
const pkg = JSON.parse(readFileSync5(join10(home, "app", "package.json"), "utf-8"));
|
|
1427
1513
|
return pkg.version ?? null;
|
|
1428
1514
|
} catch {
|
|
1429
1515
|
return null;
|
|
@@ -1455,7 +1541,7 @@ function makeNpmSource(packageName) {
|
|
|
1455
1541
|
// src/cli/commands/update.ts
|
|
1456
1542
|
function readJsonField2(file, field) {
|
|
1457
1543
|
try {
|
|
1458
|
-
return JSON.parse(
|
|
1544
|
+
return JSON.parse(readFileSync6(file, "utf-8"))[field];
|
|
1459
1545
|
} catch {
|
|
1460
1546
|
return void 0;
|
|
1461
1547
|
}
|
|
@@ -1522,12 +1608,12 @@ Use --source local (default) or --source npm.
|
|
|
1522
1608
|
{
|
|
1523
1609
|
const pkgPath = join11(staged.stagedPath, "package.json");
|
|
1524
1610
|
try {
|
|
1525
|
-
const pkg = JSON.parse(
|
|
1611
|
+
const pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
|
|
1526
1612
|
const externals = { patchright: "^1.59.4", "rettiwt-api": "^4.1.3" };
|
|
1527
1613
|
pkg.dependencies = { ...pkg.dependencies, ...externals };
|
|
1528
1614
|
if (pkg.dependencies?.abmind?.startsWith("file:")) delete pkg.dependencies.abmind;
|
|
1529
|
-
const { writeFileSync:
|
|
1530
|
-
|
|
1615
|
+
const { writeFileSync: writeFileSync3 } = await import("node:fs");
|
|
1616
|
+
writeFileSync3(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
1531
1617
|
const { execSync } = await import("node:child_process");
|
|
1532
1618
|
execSync("npm install --omit=dev --ignore-scripts 2>/dev/null", { cwd: staged.stagedPath, timeout: 6e4 });
|
|
1533
1619
|
process.stdout.write(`\u2713 external deps installed
|
|
@@ -1700,7 +1786,7 @@ async function postSwapHousekeeping(paths, repoRoot, _staged) {
|
|
|
1700
1786
|
const transportJson = join11(paths.home, "config", "transport.json");
|
|
1701
1787
|
if (existsSync9(transportJson)) {
|
|
1702
1788
|
try {
|
|
1703
|
-
const tc = JSON.parse(
|
|
1789
|
+
const tc = JSON.parse(readFileSync6(transportJson, "utf-8"));
|
|
1704
1790
|
let cleared = false;
|
|
1705
1791
|
for (const agent of Object.values(tc.agents ?? {})) {
|
|
1706
1792
|
if (agent.demoted) {
|
|
@@ -1719,8 +1805,8 @@ async function postSwapHousekeeping(paths, repoRoot, _staged) {
|
|
|
1719
1805
|
}
|
|
1720
1806
|
}
|
|
1721
1807
|
if (cleared) {
|
|
1722
|
-
const { writeFileSync:
|
|
1723
|
-
|
|
1808
|
+
const { writeFileSync: writeFileSync3 } = await import("node:fs");
|
|
1809
|
+
writeFileSync3(transportJson, JSON.stringify(tc, null, 2) + "\n");
|
|
1724
1810
|
}
|
|
1725
1811
|
} catch {
|
|
1726
1812
|
}
|
|
@@ -1858,8 +1944,8 @@ Usage:
|
|
|
1858
1944
|
abtars uninstall [--yes]
|
|
1859
1945
|
abtars update [--source local|npm|github] [--from-local]
|
|
1860
1946
|
abtars rollback [--to <version>]
|
|
1861
|
-
abtars backup
|
|
1862
|
-
abtars restore <file.zip|.7z>
|
|
1947
|
+
abtars backup [--config] [--encrypt] [--output <dir>] [--prune-days N]
|
|
1948
|
+
abtars restore <file.zip|.7z|.abm|.enc> [--config] [--passphrase <p>]
|
|
1863
1949
|
abtars doctor [<args passed to doctor.sh>...]
|
|
1864
1950
|
abtars onboard [--non-interactive --accept-risk --telegram-token ... --telegram-chat-id ...]
|
|
1865
1951
|
abtars restart [--cold]
|
|
@@ -1893,10 +1979,18 @@ async function main(argv) {
|
|
|
1893
1979
|
case "rollback":
|
|
1894
1980
|
return await rollback();
|
|
1895
1981
|
case "backup":
|
|
1896
|
-
return await backup(
|
|
1982
|
+
return await backup({
|
|
1983
|
+
config: flags.get("config") === true,
|
|
1984
|
+
encrypt: flags.get("encrypt") === true,
|
|
1985
|
+
outputDir: typeof flags.get("output") === "string" ? flags.get("output") : void 0,
|
|
1986
|
+
pruneDays: typeof flags.get("prune-days") === "string" ? Number(flags.get("prune-days")) : void 0
|
|
1987
|
+
});
|
|
1897
1988
|
case "restore": {
|
|
1898
|
-
const { restore } = await import("./restore-
|
|
1899
|
-
return await restore(argv[1] ?? ""
|
|
1989
|
+
const { restore } = await import("./restore-MFSW3EBL.js");
|
|
1990
|
+
return await restore(argv[1] ?? "", {
|
|
1991
|
+
config: flags.get("config") === true,
|
|
1992
|
+
passphrase: typeof flags.get("passphrase") === "string" ? flags.get("passphrase") : void 0
|
|
1993
|
+
});
|
|
1900
1994
|
}
|
|
1901
1995
|
case "doctor":
|
|
1902
1996
|
return await doctor(argv.slice(1).filter((a) => a !== ""));
|