@aarmos/cli 0.2.2 → 0.3.0

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.
Files changed (2) hide show
  1. package/dist/index.js +122 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { Command as Command9 } from "commander";
4
+ import { Command as Command10 } from "commander";
5
5
 
6
6
  // src/commands/init.ts
7
7
  import { Command } from "commander";
@@ -1483,8 +1483,127 @@ AARMOS_POLICY_PRIVATE_KEY (keep secret):
1483
1483
  return cmd;
1484
1484
  }
1485
1485
 
1486
+ // src/commands/backup.ts
1487
+ import { Command as Command9 } from "commander";
1488
+ import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
1489
+ function verifyBundle2(bytes) {
1490
+ let parsed;
1491
+ try {
1492
+ parsed = JSON.parse(bytes.toString("utf8"));
1493
+ } catch (e) {
1494
+ return {
1495
+ ok: false,
1496
+ code: "BUNDLE_INVALID_JSON",
1497
+ error: `invalid JSON: ${e instanceof Error ? e.message : String(e)}`
1498
+ };
1499
+ }
1500
+ if (!parsed || typeof parsed !== "object") {
1501
+ return { ok: false, code: "BUNDLE_INVALID_SHAPE", error: "bundle must be a JSON object" };
1502
+ }
1503
+ if (parsed.kind !== "aarmos-ledger-bundle") {
1504
+ return {
1505
+ ok: false,
1506
+ code: "BUNDLE_WRONG_KIND",
1507
+ error: `expected kind "aarmos-ledger-bundle", got ${JSON.stringify(parsed.kind)}`
1508
+ };
1509
+ }
1510
+ if (parsed.version !== 1) {
1511
+ return {
1512
+ ok: false,
1513
+ code: "BUNDLE_UNSUPPORTED_VERSION",
1514
+ error: `unsupported bundle version ${parsed.version}`
1515
+ };
1516
+ }
1517
+ if (!parsed.workspaceId || typeof parsed.workspaceId !== "string") {
1518
+ return { ok: false, code: "BUNDLE_MISSING_WORKSPACE", error: "workspaceId missing" };
1519
+ }
1520
+ if (!parsed.exportedAt || Number.isNaN(Date.parse(parsed.exportedAt))) {
1521
+ return { ok: false, code: "BUNDLE_BAD_TIMESTAMP", error: "exportedAt is not a valid ISO date" };
1522
+ }
1523
+ const settings = Array.isArray(parsed.settings) ? parsed.settings : null;
1524
+ const traces = Array.isArray(parsed.traces) ? parsed.traces : null;
1525
+ if (!settings || !traces) {
1526
+ return {
1527
+ ok: false,
1528
+ code: "BUNDLE_MISSING_ARRAYS",
1529
+ error: "settings and traces must both be arrays"
1530
+ };
1531
+ }
1532
+ const warnings = [];
1533
+ const declared = parsed.counts ?? {};
1534
+ if (typeof declared.settings === "number" && declared.settings !== settings.length) {
1535
+ warnings.push(
1536
+ `counts.settings=${declared.settings} but bundle contains ${settings.length} entries`
1537
+ );
1538
+ }
1539
+ if (typeof declared.traces === "number" && declared.traces !== traces.length) {
1540
+ warnings.push(
1541
+ `counts.traces=${declared.traces} but bundle contains ${traces.length} entries`
1542
+ );
1543
+ }
1544
+ if (settings.length === 0 && traces.length === 0) {
1545
+ warnings.push("bundle is empty \u2014 nothing to restore from");
1546
+ }
1547
+ return {
1548
+ ok: true,
1549
+ workspaceId: parsed.workspaceId,
1550
+ exportedAt: parsed.exportedAt,
1551
+ counts: { settings: settings.length, traces: traces.length },
1552
+ warnings
1553
+ };
1554
+ }
1555
+ function runBackupVerify(opts) {
1556
+ const { file, json = false, quiet = false } = opts;
1557
+ if (!existsSync9(file)) {
1558
+ if (json) {
1559
+ process.stdout.write(
1560
+ JSON.stringify({ ok: false, code: "FILE_NOT_FOUND", error: `not found: ${file}` }) + "\n"
1561
+ );
1562
+ } else if (!quiet) {
1563
+ process.stderr.write(`\u2717 file not found: ${file}
1564
+ `);
1565
+ }
1566
+ return 2;
1567
+ }
1568
+ const result = verifyBundle2(readFileSync9(file));
1569
+ if (json) {
1570
+ process.stdout.write(JSON.stringify(result) + "\n");
1571
+ return result.ok ? 0 : 1;
1572
+ }
1573
+ if (!result.ok) {
1574
+ if (!quiet) process.stderr.write(`\u2717 [${result.code}] ${result.error}
1575
+ `);
1576
+ return 1;
1577
+ }
1578
+ if (!quiet) {
1579
+ process.stdout.write(`\u2713 ledger bundle valid
1580
+ `);
1581
+ process.stdout.write(` workspace: ${result.workspaceId}
1582
+ `);
1583
+ process.stdout.write(` exported: ${result.exportedAt}
1584
+ `);
1585
+ process.stdout.write(` settings: ${result.counts.settings}
1586
+ `);
1587
+ process.stdout.write(` traces: ${result.counts.traces}
1588
+ `);
1589
+ for (const w of result.warnings) process.stdout.write(` ! ${w}
1590
+ `);
1591
+ process.stdout.write("\nverified locally \u2014 no Aarmos service was contacted.\n");
1592
+ }
1593
+ return 0;
1594
+ }
1595
+ function backupCommand() {
1596
+ const cmd = new Command9("backup").description(
1597
+ "Inspect and verify Aarmos ledger backup bundles exported from the app (Settings \u2192 Ledger backup)."
1598
+ );
1599
+ cmd.command("verify").description("Verify a ledger bundle JSON offline (schema + counts).").argument("<bundle>", "Path to aarmos-ledger-*.json exported from the app").option("--json", "Emit machine-readable JSON on stdout").option("--quiet", "Suppress non-error output; exit code carries the verdict").action((bundle, opts) => {
1600
+ process.exit(runBackupVerify({ file: bundle, json: opts.json, quiet: opts.quiet }));
1601
+ });
1602
+ return cmd;
1603
+ }
1604
+
1486
1605
  // src/index.ts
1487
- var program = new Command9();
1606
+ var program = new Command10();
1488
1607
  program.name("aarmos").description(
1489
1608
  "Run your agent locally, across any protocol, with a signed receipt \u2014 in 60 seconds."
1490
1609
  ).version("0.1.0");
@@ -1496,6 +1615,7 @@ program.addCommand(verifyCommand());
1496
1615
  program.addCommand(lintCommand());
1497
1616
  program.addCommand(testCommand());
1498
1617
  program.addCommand(policyCommand());
1618
+ program.addCommand(backupCommand());
1499
1619
  program.parseAsync(process.argv).catch((err) => {
1500
1620
  console.error(err instanceof Error ? err.message : String(err));
1501
1621
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aarmos/cli",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Aarmos CLI — run any agent locally, across any protocol (MCP, OpenAPI, deep-link), with a signed AVAR receipt on every execution. Sovereign runtime, universal tool gateway, verifiable governance.",
5
5
  "keywords": [
6
6
  "aarmos",