@anna-ai/cli 0.1.19 → 0.1.21

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 (63) hide show
  1. package/dist/_lifecycle-shared-sbea9HtH.js +65 -0
  2. package/dist/{agent-DUmINbo4.js → agent-Br6zY2qw.js} +1 -1
  3. package/dist/app-bundle-upload-DuLalcSt.js +213 -0
  4. package/dist/app-cache-BEM653Th.js +53 -0
  5. package/dist/apps-B1Nd8l_t.js +221 -0
  6. package/dist/apps-BTn9EN0x.js +53 -0
  7. package/dist/apps-cut-DtEkddIk.js +83 -0
  8. package/dist/apps-destructive-DSTrcFUP.js +104 -0
  9. package/dist/apps-discard-y3_IwcbQ.js +44 -0
  10. package/dist/apps-grants-BGWlpee0.js +34 -0
  11. package/dist/apps-publish-CaTCanDu.js +265 -0
  12. package/dist/apps-publish-DfZTOxBJ.js +14 -0
  13. package/dist/apps-push-B9XT2uwF.js +127 -0
  14. package/dist/apps-release-BLH9XSxB.js +135 -0
  15. package/dist/apps-status-DQ9RvlME.js +58 -0
  16. package/dist/apps-submit-review-DLwCxeAs.js +45 -0
  17. package/dist/apps-sync-meta-D9eKMMUp.js +72 -0
  18. package/dist/apps-versions-2Tmk0nsx.js +43 -0
  19. package/dist/bridge-Id8K8gr-.js +3 -0
  20. package/dist/bundled-executas-BNOKw4kv.js +161 -0
  21. package/dist/bundled-executas-CNaV2C_O.js +5 -0
  22. package/dist/cli.js +334 -20
  23. package/dist/client-Dn9zThOd.js +150 -0
  24. package/dist/confirm-DxHkk9Wn.js +37 -0
  25. package/dist/dev-BS_8yoSm.js +3 -0
  26. package/dist/{dev-b1j-dEM2.js → dev-E7mqXj5S.js} +95 -26
  27. package/dist/{dev-app-cache-3Pfesngr.js → dev-app-cache-D-r6ZpEk.js} +11 -2
  28. package/dist/{doctor-CgJYokiR.js → doctor-DKrt-Kda.js} +1 -1
  29. package/dist/executa-cache-BFoUtb4J.js +86 -0
  30. package/dist/executa-cache-WBkCLic7.js +4 -0
  31. package/dist/executa-destructive-COQE4Xqi.js +104 -0
  32. package/dist/{executa-dev-BeC6a8S8.js → executa-dev-BvS9zTpO.js} +11 -11
  33. package/dist/executa-publish-B88_9gbp.js +9 -0
  34. package/dist/executa-publish-Ca5V7MyA.js +258 -0
  35. package/dist/executa-reads-CQ6S8gHY.js +107 -0
  36. package/dist/executas-Cep6KEo0.js +109 -0
  37. package/dist/manifest-DGwRap2i.js +188 -0
  38. package/dist/publish-C1wcf-qI.js +58 -0
  39. package/dist/{server-BgJGmEpv.js → server-_IG8Igje.js} +200 -2
  40. package/dist/{storage-EQJA_0UW.js → storage-CTkApNQ9.js} +1 -1
  41. package/dist/token-B9JUPelx.js +87 -0
  42. package/dist/working-orchestration-Dw9u1Vq0.js +190 -0
  43. package/package.json +3 -3
  44. package/templates/executa/go/executa.json +5 -0
  45. package/templates/executa/node/executa.json +5 -0
  46. package/templates/executa/python/executa.json +5 -0
  47. package/dist/apps-ClgEOdKD.js +0 -44
  48. package/dist/bridge-B3Vwr4cg.js +0 -3
  49. package/dist/dev-D8o7xi0W.js +0 -3
  50. package/dist/dev-app-cache-CZ1UjMz0.js +0 -4
  51. /package/dist/{bridge-mkb_EM-y.js → bridge-BuklhzeE.js} +0 -0
  52. /package/dist/{credentials-DDqx6XMQ.js → credentials-DklPMD22.js} +0 -0
  53. /package/dist/{dev-account-DCyjamBa.js → dev-account-qRaET1Cp.js} +0 -0
  54. /package/dist/{executa-init-COEmKDOE.js → executa-init-Jp-h9OI7.js} +0 -0
  55. /package/dist/{executa-register-66WKIwQQ.js → executa-register-CulDtwYZ.js} +0 -0
  56. /package/dist/{fixture-CATHyLLI.js → fixture-CYwxbiQD.js} +0 -0
  57. /package/dist/{host_upload-C_pGOS6p.js → host_upload-GXVkDM5M.js} +0 -0
  58. /package/dist/{image-bwolX7pa.js → image-DduR91n5.js} +0 -0
  59. /package/dist/{login-CsIVbrmf.js → login-BGqFjQwH.js} +0 -0
  60. /package/dist/{logout-gfmKQxMj.js → logout-CGIRKH3y.js} +0 -0
  61. /package/dist/{runner-DmGLdat0.js → runner-B-hIqx5L.js} +0 -0
  62. /package/dist/{sampling-CJUDG-mf.js → sampling-CXke7hq1.js} +0 -0
  63. /package/dist/{whoami-BS5wy-Nh.js → whoami-BoFLEUcp.js} +0 -0
package/dist/cli.js CHANGED
@@ -451,7 +451,7 @@ program.command("validate").description("Run schema + ACL checks on a manifest+b
451
451
  process.exit(code);
452
452
  });
453
453
  program.command("dev").description("Run a local harness (in-process dispatcher + iframe + SSE relay)").option("--manifest <path>", "manifest.json path", "manifest.json").option("--bundle <dir>", "bundle directory (default: ./bundle)").option("--slug <slug>", "App slug (overrides manifest.slug/name)").option("--view <name>", "View name to open (default: manifest default)").option("--matrix-nexus-root <path>", "matrix-nexus checkout (auto-detected if omitted; can also use $ANNA_NEXUS_ROOT)").option("--port <number>", "HTTP port", "5180").option("--user-id <id>", "Harness user_id", "1").option("--cwd <dir>", "Project root (default: cwd)").option("--no-watch", "Disable bundle file watcher (default: enabled)").option("--executa <spec>", "Explicit executa registration; repeatable. Spec: comma-separated key=value (dir=<path>[,tool_id=<id>][,type=python|node|go|binary][,command=\"<argv>\"]). When only `dir=` is given, the executa is auto-detected from executa.json / pyproject.toml / package.json / go.mod. Overrides directory auto-discovery under <manifest-dir>/executas/.", (val, prev) => prev ? [...prev, val] : [val]).option("--no-llm", "Disable LLM bridge (anna.llm/agent return llm_disabled)").option("--mock-llm <fixture>", "Serve canned LLM responses from a JSONL fixture").option("--llm-account <host>", "Saved account host to use (default: current)").option("--llm-app-slug <slug>", "Override the manifest slug used to register / look up the dev AnnaApp (default: manifest.slug)").option("--storage <mode>", "Storage backend: \"legacy\" (in-memory runtime_state, default) or \"aps\" (real nexus APS via /api/v1/storage/* — requires `anna-app login`).", "legacy").action(async (opts) => {
454
- const { runDev, parseExecutaSpec } = await import("./dev-D8o7xi0W.js");
454
+ const { runDev, parseExecutaSpec } = await import("./dev-BS_8yoSm.js");
455
455
  const cwd = opts.cwd ?? process.cwd();
456
456
  let executas;
457
457
  if (opts.executa && opts.executa.length > 0) {
@@ -486,7 +486,7 @@ program.command("dev").description("Run a local harness (in-process dispatcher +
486
486
  });
487
487
  const fixture = program.command("fixture").description("Inspect / replay harness recordings (Phase 6)");
488
488
  fixture.command("verify <file>").description("Schema + invariant checks on a harness JSONL recording").option("--json", "Emit machine-readable JSON", false).action(async (file, opts) => {
489
- const { runFixtureVerify } = await import("./fixture-CATHyLLI.js");
489
+ const { runFixtureVerify } = await import("./fixture-CYwxbiQD.js");
490
490
  const code = await runFixtureVerify({
491
491
  file,
492
492
  json: opts.json
@@ -494,7 +494,7 @@ fixture.command("verify <file>").description("Schema + invariant checks on a har
494
494
  process.exit(code);
495
495
  });
496
496
  fixture.command("summarize <file>").description("Print a human-readable digest of a harness recording").option("--json", "Emit machine-readable JSON", false).action(async (file, opts) => {
497
- const { runFixtureSummarize } = await import("./fixture-CATHyLLI.js");
497
+ const { runFixtureSummarize } = await import("./fixture-CYwxbiQD.js");
498
498
  const code = await runFixtureSummarize({
499
499
  file,
500
500
  json: opts.json
@@ -502,7 +502,7 @@ fixture.command("summarize <file>").description("Print a human-readable digest o
502
502
  process.exit(code);
503
503
  });
504
504
  fixture.command("replay <file>").description("Dry-run replay of a harness recording (Phase 6 MVP)").option("--manifest <path>", "manifest.json path", "manifest.json").action(async (file, opts) => {
505
- const { runFixtureReplay } = await import("./fixture-CATHyLLI.js");
505
+ const { runFixtureReplay } = await import("./fixture-CYwxbiQD.js");
506
506
  const code = await runFixtureReplay({
507
507
  file,
508
508
  manifest: opts.manifest
@@ -510,12 +510,12 @@ fixture.command("replay <file>").description("Dry-run replay of a harness record
510
510
  process.exit(code);
511
511
  });
512
512
  program.command("doctor").description("Check environment for `anna-app dev` (uv, matrix-nexus, dev key)").option("--matrix-nexus-root <path>", "matrix-nexus checkout (optional)").action(async (opts) => {
513
- const { runDoctor } = await import("./doctor-CgJYokiR.js");
513
+ const { runDoctor } = await import("./doctor-DKrt-Kda.js");
514
514
  const code = await runDoctor({ matrixNexusRoot: opts.matrixNexusRoot });
515
515
  process.exit(code);
516
516
  });
517
517
  program.command("login").description("Device-flow login against a nexus host; saves a PAT to ~/.config/anna/credentials.json").requiredOption("--host <url>", "nexus base URL, e.g. https://nexus.example.com").option("--no-browser", "Do not open a browser window automatically", false).action(async (opts) => {
518
- const { runLogin } = await import("./login-CsIVbrmf.js");
518
+ const { runLogin } = await import("./login-BGqFjQwH.js");
519
519
  const code = await runLogin({
520
520
  host: opts.host,
521
521
  noBrowser: opts.browser === false
@@ -523,7 +523,7 @@ program.command("login").description("Device-flow login against a nexus host; sa
523
523
  process.exit(code);
524
524
  });
525
525
  program.command("logout").description("Remove a saved PAT entry").option("--host <url>", "Account to remove (default: current)").option("--all", "Remove every saved account", false).action(async (opts) => {
526
- const { runLogout } = await import("./logout-gfmKQxMj.js");
526
+ const { runLogout } = await import("./logout-CGIRKH3y.js");
527
527
  const code = await runLogout({
528
528
  host: opts.host,
529
529
  all: opts.all
@@ -531,18 +531,10 @@ program.command("logout").description("Remove a saved PAT entry").option("--host
531
531
  process.exit(code);
532
532
  });
533
533
  program.command("whoami").description("Show the current account (and any others)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
534
- const { runWhoami } = await import("./whoami-BS5wy-Nh.js");
534
+ const { runWhoami } = await import("./whoami-BoFLEUcp.js");
535
535
  const code = await runWhoami({ json: opts.json });
536
536
  process.exit(code);
537
537
  });
538
- program.command("apps:list").description("List dev apps installed for the current PAT").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
539
- const { runAppsList } = await import("./apps-ClgEOdKD.js");
540
- const code = await runAppsList({
541
- account: opts.account,
542
- json: opts.json
543
- });
544
- process.exit(code);
545
- });
546
538
  const executa = program.command("executa").description("Standalone Executa plugin scaffolding + local runner");
547
539
  executa.command("init <dir>").description("Scaffold a standalone Executa plugin (python | node | go)").option("--slug <slug>", "Plugin slug (lowercase, hyphens)", "").option("--template <name>", "Language template: python | node | go", "python").option("--tool-id <id>", "Override the minted tool_id (default: tool-dev-<slug>)").option("--force", "Overwrite existing dir if non-empty", false).action(async (dir, opts) => {
548
540
  const slug = opts.slug || dir.split(/[\\/]/).pop() || "my-executa";
@@ -555,7 +547,7 @@ executa.command("init <dir>").description("Scaffold a standalone Executa plugin
555
547
  console.error(`✗ unknown template "${opts.template}" — expected python | node | go`);
556
548
  process.exit(2);
557
549
  }
558
- const { runExecutaInit } = await import("./executa-init-COEmKDOE.js");
550
+ const { runExecutaInit } = await import("./executa-init-Jp-h9OI7.js");
559
551
  const code = runExecutaInit({
560
552
  targetDir: dir,
561
553
  slug,
@@ -565,13 +557,13 @@ executa.command("init <dir>").description("Scaffold a standalone Executa plugin
565
557
  });
566
558
  process.exit(code);
567
559
  });
568
- executa.command("register").description("Register a standalone executa with nexus so `executa dev --storage real` (and future agent / sampling real-mode flows) can mint tokens for it").requiredOption("--tool-id <id>", "Executa tool_id (matches manifest.name)").option("--slug <slug>", "App slug (default: executa-<tool_id>; must be lowercase + hyphens)").option("--name <name>", "Human-readable display name (default: <tool_id>)").option("--account <host>", "Saved account host (default: current)").action(async (opts) => {
569
- const { runExecutaRegister } = await import("./executa-register-66WKIwQQ.js");
560
+ executa.command("register").description("Register a HARNESS AnnaApp(kind=executa) so `executa dev --storage real` (and agent / sampling / image / upload real-mode flows) can mint tokens for a local executa subprocess. Does NOT publish the executa itself — use `executa publish` for that. Lists/deletes via `apps list` / `apps delete`.").requiredOption("--tool-id <id>", "Executa tool_id (matches manifest.name)").option("--slug <slug>", "App slug (default: executa-<tool_id>; must be lowercase + hyphens)").option("--name <name>", "Human-readable display name (default: <tool_id>)").option("--account <host>", "Saved account host (default: current)").action(async (opts) => {
561
+ const { runExecutaRegister } = await import("./executa-register-CulDtwYZ.js");
570
562
  const code = await runExecutaRegister(opts);
571
563
  process.exit(code);
572
564
  });
573
565
  executa.command("dev").description("Run one Executa plugin in isolation (REPL or one-shot describe/invoke)").option("--dir <path>", "Executa project dir (default: CWD)").option("--spec <spec>", "Override discovery: comma-separated key=value (tool_id=...,type=...,command=\"...\")").option("--describe", "Print MANIFEST and exit", false).option("--health", "Print health and exit", false).option("--invoke <tool>", "Invoke one tool and exit").option("--args <json>", "JSON object passed as tool arguments", "{}").option("--json", "One-shot: emit compact JSON (no banners)", false).option("--no-sampling", "Hard-disable sampling reverse RPC (returns sampling_disabled)").option("--mock-sampling <fixture>", "Serve canned sampling responses from a JSONL fixture (offline)").option("--app-slug <slug>", "Forward sampling to nexus on behalf of this dev AnnaApp slug").option("--sampling-account <host>", "Saved account host for nexus sampling (default: current)").option("--no-agent", "Hard-disable agent reverse RPC (returns agent_not_granted)").option("--mock-agent <fixture>", "Serve canned agent/* responses from a JSONL fixture (offline)").option("--agent-account <host>", "Saved account host for nexus agent (default: --sampling-account or current)").option("--storage <mode>", "Storage backend: off | memory | mock | real (default: memory)").option("--mock-storage <fixture>", "Serve canned storage/* + files/* responses from a JSONL fixture").option("--storage-account <host>", "Saved account host for nexus storage (default: --sampling-account or current)").option("--storage-scopes <list>", "Comma-separated scopes for real storage tokens (default: user,app,tool)").option("--no-image", "Hard-disable image reverse RPC (returns image_not_granted)").option("--mock-image <fixture>", "Serve canned image/generate + image/edit responses from a JSONL fixture").option("--image-account <host>", "Saved account host for nexus image (default: --sampling-account or current)").option("--no-upload", "Hard-disable host/uploadFile reverse RPC (returns upload_not_granted)").option("--mock-upload <fixture>", "Serve canned host/uploadFile responses from a JSONL fixture").option("--upload-account <host>", "Saved account host for nexus uploads (default: --sampling-account or current)").action(async (opts) => {
574
- const { runExecutaDev } = await import("./executa-dev-BeC6a8S8.js");
566
+ const { runExecutaDev } = await import("./executa-dev-BvS9zTpO.js");
575
567
  const storageMode = opts.storage === void 0 ? void 0 : (() => {
576
568
  const m = opts.storage;
577
569
  if (m === "off" || m === "memory" || m === "mock" || m === "real") return m;
@@ -606,6 +598,328 @@ executa.command("dev").description("Run one Executa plugin in isolation (REPL or
606
598
  });
607
599
  process.exit(code);
608
600
  });
601
+ const apps = program.command("apps").description("Anna App publish lifecycle commands");
602
+ apps.command("list").description("List the Anna Apps you authored, with lifecycle status").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
603
+ const { runAppsList } = await import("./apps-BTn9EN0x.js");
604
+ process.exit(await runAppsList({
605
+ account: opts.account,
606
+ json: opts.json
607
+ }));
608
+ });
609
+ apps.command("publish").description("Publish or update an Anna App (manifest.json in cwd)").option("--cwd <dir>", "Project root (default: cwd)").option("--manifest <path>", "manifest.json path", "manifest.json").option("--bump <kind>", "Bump version: patch|minor|major").option("--no-write", "Skip writing the bumped version back to disk", false).option("--dry-run", "Resolve identity + diff but don't upload", false).option("--executa-id <handle=id>", "Override a bundled executa handle with a real tool_id (repeatable)", (val, prev) => [...prev, val], []).option("--skip-executa-publish", "Use cached/overridden tool_ids; don't recursively publish bundled executas", false).option("--no-bundled-executas", "Disable bundled-executa orchestration (legacy behaviour)").option("--no-bundle", "Skip UI bundle upload even if the manifest declares a UI").option("--bundle-dir <dir>", "UI bundle directory (default: <cwd>/bundle)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
610
+ if (opts.bump && ![
611
+ "patch",
612
+ "minor",
613
+ "major"
614
+ ].includes(opts.bump)) {
615
+ console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
616
+ process.exit(2);
617
+ }
618
+ const { runAppsPublish } = await import("./apps-publish-DfZTOxBJ.js");
619
+ process.exit(await runAppsPublish({
620
+ cwd: opts.cwd,
621
+ manifest: opts.manifest,
622
+ bump: opts.bump,
623
+ noWrite: opts.write === false,
624
+ dryRun: opts.dryRun,
625
+ executaId: opts.executaId,
626
+ skipExecutaPublish: opts.skipExecutaPublish,
627
+ noBundledExecutas: opts.bundledExecutas === false,
628
+ noBundle: opts.bundle === false,
629
+ bundleDir: opts.bundleDir,
630
+ account: opts.account,
631
+ json: opts.json
632
+ }));
633
+ });
634
+ apps.command("push").description("Upsert the mutable working draft (manifest + bundle, no freeze)").option("--cwd <dir>", "Project root (default: cwd)").option("--manifest <path>", "manifest.json path", "manifest.json").option("--bump <kind>", "Bump version: patch|minor|major").option("--no-write", "Skip writing the bumped version back to disk", false).option("--dry-run", "Resolve identity + diff but don't upsert", false).option("--executa-id <handle=id>", "Override a bundled executa handle with a real tool_id (repeatable)", (val, prev) => [...prev, val], []).option("--skip-executa-publish", "Use cached/overridden tool_ids; don't recursively register bundled executas", false).option("--no-bundled-executas", "Disable bundled-executa orchestration (legacy behaviour)").option("--no-bundle", "Skip working UI bundle upload even if the manifest declares a UI").option("--bundle-dir <dir>", "UI bundle directory (default: <cwd>/bundle)").option("--if-match <revision>", "Optimistic-lock: require this working revision").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
635
+ if (opts.bump && ![
636
+ "patch",
637
+ "minor",
638
+ "major"
639
+ ].includes(opts.bump)) {
640
+ console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
641
+ process.exit(2);
642
+ }
643
+ let ifMatch;
644
+ if (opts.ifMatch !== void 0) {
645
+ ifMatch = Number.parseInt(opts.ifMatch, 10);
646
+ if (!Number.isFinite(ifMatch)) {
647
+ console.error(`✗ --if-match must be an integer revision (got: ${opts.ifMatch})`);
648
+ process.exit(2);
649
+ }
650
+ }
651
+ const { runAppsPush } = await import("./apps-push-B9XT2uwF.js");
652
+ process.exit(await runAppsPush({
653
+ cwd: opts.cwd,
654
+ manifest: opts.manifest,
655
+ bump: opts.bump,
656
+ noWrite: opts.write === false,
657
+ dryRun: opts.dryRun,
658
+ executaId: opts.executaId,
659
+ skipExecutaPublish: opts.skipExecutaPublish,
660
+ noBundledExecutas: opts.bundledExecutas === false,
661
+ noBundle: opts.bundle === false,
662
+ bundleDir: opts.bundleDir,
663
+ ifMatch,
664
+ account: opts.account,
665
+ json: opts.json
666
+ }));
667
+ });
668
+ apps.command("cut <version>").description("Snapshot the working draft into an immutable version (freeze deps)").option("--changelog <text>", "Override the working draft changelog for this version").option("--slug <slug>", "App slug (default: resolve from .anna/app.json cache)").option("--cwd <dir>", "Project root for identity cache (default: cwd)").option("--dry-run", "Resolve target but don't cut", false).option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (version, opts) => {
669
+ const { runAppsCut } = await import("./apps-cut-DtEkddIk.js");
670
+ process.exit(await runAppsCut({
671
+ version,
672
+ changelog: opts.changelog,
673
+ slug: opts.slug,
674
+ cwd: opts.cwd,
675
+ dryRun: opts.dryRun,
676
+ account: opts.account,
677
+ json: opts.json
678
+ }));
679
+ });
680
+ apps.command("discard").description("Drop the mutable working draft (leaves cut versions intact)").option("--slug <slug>", "App slug (default: resolve from .anna/app.json cache)").option("--cwd <dir>", "Project root for identity cache (default: cwd)").option("--dry-run", "Resolve target but don't discard", false).option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
681
+ const { runAppsDiscard } = await import("./apps-discard-y3_IwcbQ.js");
682
+ process.exit(await runAppsDiscard({
683
+ slug: opts.slug,
684
+ cwd: opts.cwd,
685
+ dryRun: opts.dryRun,
686
+ account: opts.account,
687
+ json: opts.json
688
+ }));
689
+ });
690
+ apps.command("release <version>").description("Freeze & publish an existing remote version (go live)").option("--slug <slug>", "App slug (default: resolve from .anna/app.json cache)").option("--cwd <dir>", "Project root for identity cache (default: cwd)").option("--allow-create", "If the version isn't on the server, run 'apps publish' first, then release", false).option("--dry-run", "Resolve target + pre-flight but don't publish", false).option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (version, opts) => {
691
+ const { runAppsRelease } = await import("./apps-release-BLH9XSxB.js");
692
+ process.exit(await runAppsRelease({
693
+ version,
694
+ slug: opts.slug,
695
+ cwd: opts.cwd,
696
+ allowCreate: opts.allowCreate,
697
+ dryRun: opts.dryRun,
698
+ account: opts.account,
699
+ json: opts.json
700
+ }));
701
+ });
702
+ apps.command("sync-meta").description("Push mutable store metadata (name/tagline/…) from the manifest").option("--cwd <dir>", "Project root (default: cwd)").option("--manifest <path>", "manifest.json path", "manifest.json").option("--dry-run", "Print the metadata diff but don't PATCH", false).option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
703
+ const { runAppsSyncMeta } = await import("./apps-sync-meta-D9eKMMUp.js");
704
+ process.exit(await runAppsSyncMeta({
705
+ cwd: opts.cwd,
706
+ manifest: opts.manifest,
707
+ dryRun: opts.dryRun,
708
+ account: opts.account,
709
+ json: opts.json
710
+ }));
711
+ });
712
+ apps.command("submit-review [slug]").description("Move an app into review (DRAFT/REJECTED → PENDING_REVIEW)").option("--cwd <dir>", "Project root for identity cache (default: cwd)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
713
+ const { runAppsSubmitReview } = await import("./apps-submit-review-DLwCxeAs.js");
714
+ process.exit(await runAppsSubmitReview({
715
+ slug,
716
+ cwd: opts.cwd,
717
+ account: opts.account,
718
+ json: opts.json
719
+ }));
720
+ });
721
+ apps.command("status <slug>").description("Show server-known state for one Anna App").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
722
+ const { runAppsStatus } = await import("./apps-status-DQ9RvlME.js");
723
+ process.exit(await runAppsStatus({
724
+ slug,
725
+ account: opts.account,
726
+ json: opts.json
727
+ }));
728
+ });
729
+ apps.command("versions <slug>").description("List all server versions of one Anna App").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
730
+ const { runAppsVersions } = await import("./apps-versions-2Tmk0nsx.js");
731
+ process.exit(await runAppsVersions({
732
+ slug,
733
+ account: opts.account,
734
+ json: opts.json
735
+ }));
736
+ });
737
+ apps.command("grants <slug>").description("Show currently granted scopes/quota for one Anna App").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
738
+ const { runAppsGrants } = await import("./apps-grants-BGWlpee0.js");
739
+ process.exit(await runAppsGrants({
740
+ slug,
741
+ account: opts.account,
742
+ json: opts.json
743
+ }));
744
+ });
745
+ apps.command("unpublish <slug>").description("Flip a PUBLISHED app back to APPROVED (private)").option("--yes", "Acknowledge the destructive operation", false).option("--confirm <slug>", "Slug confirmation (must match target)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
746
+ const { runAppsUnpublish } = await import("./apps-destructive-DSTrcFUP.js");
747
+ process.exit(await runAppsUnpublish({
748
+ slug,
749
+ yes: opts.yes,
750
+ confirm: opts.confirm,
751
+ account: opts.account,
752
+ json: opts.json
753
+ }));
754
+ });
755
+ apps.command("archive <slug>").description("Archive an Anna App (hides it from end users)").option("--yes", "Acknowledge the destructive operation", false).option("--confirm <slug>", "Slug confirmation (must match target)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
756
+ const { runAppsArchive } = await import("./apps-destructive-DSTrcFUP.js");
757
+ process.exit(await runAppsArchive({
758
+ slug,
759
+ yes: opts.yes,
760
+ confirm: opts.confirm,
761
+ account: opts.account,
762
+ json: opts.json
763
+ }));
764
+ });
765
+ apps.command("unarchive <slug>").description("Restore an archived Anna App back to APPROVED").option("--yes", "Acknowledge the operation", false).option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
766
+ const { runAppsUnarchive } = await import("./apps-destructive-DSTrcFUP.js");
767
+ process.exit(await runAppsUnarchive({
768
+ slug,
769
+ yes: opts.yes,
770
+ account: opts.account,
771
+ json: opts.json
772
+ }));
773
+ });
774
+ apps.command("delete <slug>").description("Hard-delete an Anna App (refused by server if installs exist)").option("--yes", "Acknowledge the destructive operation", false).option("--confirm <slug>", "Slug confirmation (must match target)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
775
+ const { runAppsDelete } = await import("./apps-destructive-DSTrcFUP.js");
776
+ process.exit(await runAppsDelete({
777
+ slug,
778
+ yes: opts.yes,
779
+ confirm: opts.confirm,
780
+ account: opts.account,
781
+ json: opts.json
782
+ }));
783
+ });
784
+ executa.command("list").description("List Executas owned by the current PAT").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
785
+ const { runExecutaList } = await import("./executa-reads-CQ6S8gHY.js");
786
+ process.exit(await runExecutaList({
787
+ account: opts.account,
788
+ json: opts.json
789
+ }));
790
+ });
791
+ executa.command("status <ref>").description("Show server-known state for one Executa (slug or tool_id)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (ref, opts) => {
792
+ const { runExecutaStatus } = await import("./executa-reads-CQ6S8gHY.js");
793
+ process.exit(await runExecutaStatus({
794
+ ref,
795
+ account: opts.account,
796
+ json: opts.json
797
+ }));
798
+ });
799
+ executa.command("versions <ref>").description("List immutable version snapshots for one Executa").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (ref, opts) => {
800
+ const { runExecutaVersions } = await import("./executa-reads-CQ6S8gHY.js");
801
+ process.exit(await runExecutaVersions({
802
+ ref,
803
+ account: opts.account,
804
+ json: opts.json
805
+ }));
806
+ });
807
+ executa.command("publish").description("Mint or update an Executa (executa.json in cwd)").option("--cwd <dir>", "Project root (default: cwd)").option("--manifest <path>", "executa.json path", "executa.json").option("--bump <kind>", "Bump version: patch|minor|major").option("--no-write", "Skip writing the bumped version back to disk", false).option("--publish", "After freezing the version, flip visibility to PUBLIC", false).option("--dry-run", "Resolve identity + diff but don't upload", false).option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
808
+ if (opts.bump && ![
809
+ "patch",
810
+ "minor",
811
+ "major"
812
+ ].includes(opts.bump)) {
813
+ console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
814
+ process.exit(2);
815
+ }
816
+ const { runExecutaPublish } = await import("./executa-publish-B88_9gbp.js");
817
+ process.exit(await runExecutaPublish({
818
+ cwd: opts.cwd,
819
+ manifest: opts.manifest,
820
+ bump: opts.bump,
821
+ noWrite: opts.write === false,
822
+ publish: opts.publish,
823
+ dryRun: opts.dryRun,
824
+ account: opts.account,
825
+ json: opts.json
826
+ }));
827
+ });
828
+ executa.command("unpublish <slug>").description("Flip an Executa's visibility back to private").option("--yes", "Acknowledge the destructive operation", false).option("--confirm <slug>", "Slug confirmation (must match target)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
829
+ const { runExecutaUnpublish } = await import("./executa-destructive-COQE4Xqi.js");
830
+ process.exit(await runExecutaUnpublish({
831
+ slug,
832
+ yes: opts.yes,
833
+ confirm: opts.confirm,
834
+ account: opts.account,
835
+ json: opts.json
836
+ }));
837
+ });
838
+ executa.command("yank <ref>").description("Hard-delete one Executa version (<slug>@<version>)").option("--yes", "Acknowledge the destructive operation", false).option("--confirm <slug>", "Slug confirmation (must match target)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (ref, opts) => {
839
+ const { runExecutaYank } = await import("./executa-destructive-COQE4Xqi.js");
840
+ process.exit(await runExecutaYank({
841
+ ref,
842
+ yes: opts.yes,
843
+ confirm: opts.confirm,
844
+ account: opts.account,
845
+ json: opts.json
846
+ }));
847
+ });
848
+ executa.command("delete <slug>").description("Hard-delete an Executa").option("--yes", "Acknowledge the destructive operation", false).option("--confirm <slug>", "Slug confirmation (must match target)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (slug, opts) => {
849
+ const { runExecutaDelete } = await import("./executa-destructive-COQE4Xqi.js");
850
+ process.exit(await runExecutaDelete({
851
+ slug,
852
+ yes: opts.yes,
853
+ confirm: opts.confirm,
854
+ account: opts.account,
855
+ json: opts.json
856
+ }));
857
+ });
858
+ executa.command("cache-clear").description("Delete the local `.anna/executa.json` identity cache. Use after the server-side Executa has been deleted/recreated, or when switching host. Next `executa publish` will re-mint via the idempotency key.").option("--cwd <dir>", "Project root (default: cwd)").action(async (opts) => {
859
+ const { resolve: resolve$1 } = await import("node:path");
860
+ const { existsSync: existsSync$1 } = await import("node:fs");
861
+ const { executaCachePath, invalidateExecutaCache } = await import("./executa-cache-WBkCLic7.js");
862
+ const cwd = resolve$1(opts.cwd ?? process.cwd());
863
+ const p = executaCachePath(cwd);
864
+ if (!existsSync$1(p)) {
865
+ console.log(`(no cache at ${p})`);
866
+ process.exit(0);
867
+ }
868
+ invalidateExecutaCache(cwd);
869
+ console.log(`✓ removed ${p}`);
870
+ process.exit(0);
871
+ });
872
+ const token = program.command("token").description("Manage developer PATs (list / revoke / scopes)");
873
+ token.command("list").description("List the caller's PATs (most-recent first)").option("--include-revoked", "Also show revoked PATs", false).option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
874
+ const { runTokenList } = await import("./token-B9JUPelx.js");
875
+ process.exit(await runTokenList({
876
+ includeRevoked: opts.includeRevoked,
877
+ account: opts.account,
878
+ json: opts.json
879
+ }));
880
+ });
881
+ token.command("revoke <id>").description("Revoke one of the caller's PATs by id").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (id, opts) => {
882
+ const idNum = Number.parseInt(id, 10);
883
+ if (!Number.isFinite(idNum) || idNum <= 0) {
884
+ console.error(`✗ token id must be a positive integer (got: ${id})`);
885
+ process.exit(2);
886
+ }
887
+ const { runTokenRevoke } = await import("./token-B9JUPelx.js");
888
+ process.exit(await runTokenRevoke({
889
+ id: idNum,
890
+ account: opts.account,
891
+ json: opts.json
892
+ }));
893
+ });
894
+ token.command("scopes").description("Print the available PAT scope catalogue").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
895
+ const { runTokenScopes } = await import("./token-B9JUPelx.js");
896
+ process.exit(await runTokenScopes({
897
+ account: opts.account,
898
+ json: opts.json
899
+ }));
900
+ });
901
+ program.command("publish").description("Auto-detect cwd and publish (apps publish OR executa publish)").option("--cwd <dir>", "Project root (default: cwd)").option("--bump <kind>", "Bump version: patch|minor|major").option("--no-write", "Skip writing the bumped version back to disk", false).option("--publish", "(executa) flip visibility to PUBLIC after upload", false).option("--dry-run", "Resolve identity + diff but don't upload", false).option("--no-bundle", "(apps) skip UI bundle upload").option("--bundle-dir <dir>", "(apps) UI bundle directory (default: <cwd>/bundle)").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
902
+ if (opts.bump && ![
903
+ "patch",
904
+ "minor",
905
+ "major"
906
+ ].includes(opts.bump)) {
907
+ console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
908
+ process.exit(2);
909
+ }
910
+ const { runTopLevelPublish } = await import("./publish-C1wcf-qI.js");
911
+ process.exit(await runTopLevelPublish({
912
+ cwd: opts.cwd,
913
+ bump: opts.bump,
914
+ noWrite: opts.write === false,
915
+ publish: opts.publish,
916
+ dryRun: opts.dryRun,
917
+ noBundle: opts.bundle === false,
918
+ bundleDir: opts.bundleDir,
919
+ account: opts.account,
920
+ json: opts.json
921
+ }));
922
+ });
609
923
  program.parseAsync(process.argv).catch((e) => {
610
924
  console.error(e);
611
925
  process.exit(2);
@@ -0,0 +1,150 @@
1
+ import { canonicalHost } from "./credentials-BTv2IfUZ.js";
2
+
3
+ //#region src/api/client.ts
4
+ var CliError = class extends Error {
5
+ exitCode;
6
+ status;
7
+ body;
8
+ constructor(message, exitCode, opts) {
9
+ super(message);
10
+ this.exitCode = exitCode;
11
+ this.status = opts?.status;
12
+ this.body = opts?.body;
13
+ }
14
+ };
15
+ var ScopeError = class extends CliError {
16
+ needed;
17
+ missing;
18
+ have;
19
+ constructor(opts) {
20
+ super(`missing PAT scope(s): ${opts.missing.join(", ") || "(unknown)"}`, 3, {
21
+ status: 403,
22
+ body: opts.body
23
+ });
24
+ this.needed = opts.needed;
25
+ this.missing = opts.missing;
26
+ this.have = opts.have;
27
+ }
28
+ };
29
+ var NexusClient = class {
30
+ host;
31
+ pat;
32
+ fetchImpl;
33
+ userAgent;
34
+ constructor(opts) {
35
+ this.host = canonicalHost(opts.host);
36
+ this.pat = opts.pat;
37
+ this.fetchImpl = opts.fetchImpl ?? fetch;
38
+ this.userAgent = opts.userAgent ?? "anna-app-cli";
39
+ }
40
+ async request(opts) {
41
+ const url = new URL(this.host + opts.path);
42
+ if (opts.query) for (const [k, v] of Object.entries(opts.query)) {
43
+ if (v === void 0 || v === null) continue;
44
+ url.searchParams.set(k, String(v));
45
+ }
46
+ const headers = {
47
+ authorization: `Bearer ${this.pat}`,
48
+ "user-agent": this.userAgent,
49
+ accept: "application/json",
50
+ ...opts.headers ?? {}
51
+ };
52
+ let body;
53
+ if (opts.multipart) {
54
+ const fd = new FormData();
55
+ for (const [k, v] of Object.entries(opts.multipart.fields)) fd.append(k, v);
56
+ body = fd;
57
+ } else if (opts.body !== void 0) {
58
+ headers["content-type"] = "application/json";
59
+ body = JSON.stringify(opts.body);
60
+ }
61
+ const method = opts.method ?? "GET";
62
+ const allowed = new Set(opts.allowStatuses ?? []);
63
+ let res;
64
+ try {
65
+ res = await this.fetchImpl(url, {
66
+ method,
67
+ headers,
68
+ body
69
+ });
70
+ } catch (e) {
71
+ throw new CliError(`network error contacting ${this.host}: ${e.message}`, 6);
72
+ }
73
+ if (res.status >= 500 && !opts.noRetry && !allowed.has(res.status) && method === "GET") try {
74
+ res = await this.fetchImpl(url, {
75
+ method,
76
+ headers,
77
+ body
78
+ });
79
+ } catch (e) {
80
+ throw new CliError(`network error contacting ${this.host}: ${e.message}`, 6);
81
+ }
82
+ const idempotentHit = res.headers.get("x-anna-idempotent") === "hit";
83
+ let parsed = null;
84
+ const text = await res.text();
85
+ if (text.length > 0) try {
86
+ parsed = JSON.parse(text);
87
+ } catch {
88
+ parsed = text;
89
+ }
90
+ if (!res.ok && !allowed.has(res.status)) this.throwForStatus(res.status, parsed);
91
+ return {
92
+ data: parsed,
93
+ status: res.status,
94
+ headers: res.headers,
95
+ idempotentHit
96
+ };
97
+ }
98
+ throwForStatus(status, body) {
99
+ if (status === 401) throw new CliError("PAT rejected by server (401). Run `anna-app login --host …` to refresh.", 2, {
100
+ status,
101
+ body
102
+ });
103
+ if (status === 403) {
104
+ const det = extractDetail(body);
105
+ if (det && typeof det === "object" && det.detail === "missing_scope") {
106
+ const dd = det;
107
+ throw new ScopeError({
108
+ needed: dd.needed ?? [],
109
+ missing: dd.missing ?? [],
110
+ have: dd.have ?? [],
111
+ body
112
+ });
113
+ }
114
+ throw new CliError(`forbidden (403): ${describeBody(body)}`, 3, {
115
+ status,
116
+ body
117
+ });
118
+ }
119
+ if (status >= 500) throw new CliError(`server error (${status}): ${describeBody(body)}`, 6, {
120
+ status,
121
+ body
122
+ });
123
+ throw new CliError(`request failed (${status}): ${describeBody(body)}`, 5, {
124
+ status,
125
+ body
126
+ });
127
+ }
128
+ };
129
+ function extractDetail(body) {
130
+ if (body && typeof body === "object" && "detail" in body) {
131
+ const d = body.detail;
132
+ if (typeof d === "string") return { detail: d };
133
+ if (d && typeof d === "object") return d;
134
+ }
135
+ return null;
136
+ }
137
+ function describeBody(body) {
138
+ if (typeof body === "string") return body.slice(0, 240);
139
+ if (body && typeof body === "object") {
140
+ const det = body.detail;
141
+ if (typeof det === "string") return det;
142
+ try {
143
+ return JSON.stringify(body).slice(0, 240);
144
+ } catch {}
145
+ }
146
+ return String(body ?? "(empty body)");
147
+ }
148
+
149
+ //#endregion
150
+ export { CliError, NexusClient, ScopeError };
@@ -0,0 +1,37 @@
1
+ import { CliError } from "./client-Dn9zThOd.js";
2
+ import { yellow } from "kleur/colors";
3
+ import { createInterface } from "node:readline/promises";
4
+
5
+ //#region src/publish/confirm.ts
6
+ function isInteractive() {
7
+ return Boolean(process.stdin.isTTY && process.stdout.isTTY);
8
+ }
9
+ async function promptForSlug(verb, slug) {
10
+ const rl = createInterface({
11
+ input: process.stdin,
12
+ output: process.stdout
13
+ });
14
+ try {
15
+ process.stdout.write(yellow(`About to \`${verb}\` "${slug}" — this is irreversible.\nType the slug to confirm (or empty to abort): `));
16
+ const answer = (await rl.question("")).trim();
17
+ if (answer !== slug) throw new CliError(`\`${verb}\` aborted: typed "${answer}" does not match target slug "${slug}"`, 7);
18
+ } finally {
19
+ rl.close();
20
+ }
21
+ }
22
+ async function ensureDestructiveAllowed(opts) {
23
+ if (process.env.ANNA_CLI_NO_DESTRUCTIVE === "1") throw new CliError(`\`${opts.verb}\` refused: ANNA_CLI_NO_DESTRUCTIVE=1 is set`, 7);
24
+ if (opts.confirm !== void 0) {
25
+ if (opts.confirm !== opts.slug) throw new CliError(`\`${opts.verb}\` refused: --confirm "${opts.confirm}" does not match target slug "${opts.slug}"`, 7);
26
+ return;
27
+ }
28
+ if (opts.yes) return;
29
+ if (isInteractive()) {
30
+ await promptForSlug(opts.verb, opts.slug);
31
+ return;
32
+ }
33
+ throw new CliError(`\`${opts.verb}\` refused: non-interactive shell — pass --confirm ${opts.slug} (or --yes) to proceed`, 7);
34
+ }
35
+
36
+ //#endregion
37
+ export { ensureDestructiveAllowed };
@@ -0,0 +1,3 @@
1
+ import { parseExecutaSpec, runDev } from "./dev-E7mqXj5S.js";
2
+
3
+ export { parseExecutaSpec, runDev };