@anna-ai/cli 0.1.30 → 0.1.32

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 (59) hide show
  1. package/dist/{account-B6n0XkpV.js → account-bqao7Gp5.js} +1 -1
  2. package/dist/{agent-J2bELWfv.js → agent-CzPryLi6.js} +1 -1
  3. package/dist/{app-bundle-upload-CPf_nGou.js → app-bundle-upload-CqT9KUOl.js} +2 -2
  4. package/dist/{apps-73pdBAFE.js → apps-DlVsVHQ5.js} +30 -1
  5. package/dist/{apps-cut-C5SH9qZN.js → apps-cut-8870xpk-.js} +6 -6
  6. package/dist/{apps-destructive-PY0wKjqu.js → apps-destructive-B6RFjokU.js} +1 -1
  7. package/dist/{apps-discard-CfdkwUZ_.js → apps-discard-hVZxAQyj.js} +6 -6
  8. package/dist/{apps-BpJ-TvHP.js → apps-dvknZYI2.js} +1 -1
  9. package/dist/{apps-grants-BtXXiuJt.js → apps-grants-DnXCnkH5.js} +1 -1
  10. package/dist/{apps-publish-B-ZVNmgn.js → apps-publish-BKqVsS1W.js} +10 -4
  11. package/dist/apps-publish-Djpw5cfG.js +15 -0
  12. package/dist/{apps-push-Bh8zwT--.js → apps-push-B3wZr9B4.js} +13 -7
  13. package/dist/{apps-release-DNlN_8gz.js → apps-release-DZK30eF_.js} +2 -2
  14. package/dist/{apps-rename-slug-Bp-nQ_6I.js → apps-rename-slug-D2BrWasG.js} +2 -2
  15. package/dist/{apps-status-5DV9cY4A.js → apps-status-Ca6MdXZd.js} +1 -1
  16. package/dist/{apps-submit-review-DH-bzbDZ.js → apps-submit-review-DMFQI8JZ.js} +1 -1
  17. package/dist/{apps-sync-meta-DdPnXuIU.js → apps-sync-meta-BOb6J_wz.js} +25 -16
  18. package/dist/{apps-versions-vGihRRje.js → apps-versions-D1lixrmM.js} +1 -1
  19. package/dist/{bridge-DXH59CmP.js → bridge-CbjqAm0H.js} +1 -1
  20. package/dist/bridge-CzHB_IsQ.js +3 -0
  21. package/dist/cli.js +42 -41
  22. package/dist/dev-C3yWhzAp.js +4 -0
  23. package/dist/{dev-aWkfWGLD.js → dev-Re6NyNDS.js} +4 -4
  24. package/dist/{doctor-DnCYaREu.js → doctor-VrfEkedz.js} +1 -1
  25. package/dist/{executa-dev-0XdBPTDy.js → executa-dev-B5Uz982M.js} +8 -8
  26. package/dist/{executa-install-A-BgavhA.js → executa-install-BW9jjY7u.js} +1 -1
  27. package/dist/executa-install-Cyid8R7r.js +7 -0
  28. package/dist/{executa-publish-Xmm4DMO9.js → executa-publish-Ah6J7jYd.js} +1 -1
  29. package/dist/{executa-publish-9XQRncyN.js → executa-publish-DI_6M_ea.js} +2 -2
  30. package/dist/listing-meta-BlY7XMrw.js +117 -0
  31. package/dist/{manifest-CMc7RM57.js → manifest-DOMrcdCK.js} +16 -1
  32. package/dist/{publish-NTT1Libd.js → publish-GpvkaBIx.js} +6 -5
  33. package/dist/{runner-DVu-o_U8.js → runner-BxYjAmih.js} +9 -3
  34. package/dist/{server-DtnMLKQS.js → server-BMcGaUTy.js} +229 -5
  35. package/dist/{storage-C95wApr2.js → storage-BkF4XyI0.js} +3 -3
  36. package/dist/{working-orchestration-CX0ONKIq.js → working-orchestration-1jzRuk34.js} +4 -4
  37. package/package.json +3 -3
  38. package/templates/executa/go/main.go +1 -1
  39. package/templates/executa/node/plugin.mjs +1 -1
  40. package/templates/executa/python/__SLUG_PY___plugin.py +1 -1
  41. package/templates/minimal/executas/__SLUG__/__SLUG_PY___plugin.py +1 -1
  42. package/dist/apps-publish-3wbhXfAg.js +0 -14
  43. package/dist/bridge-CmoKMMcG.js +0 -3
  44. package/dist/dev-C9VpI_AL.js +0 -4
  45. package/dist/executa-install-Bc1WRrWu.js +0 -7
  46. /package/dist/{dev-account-WXEjIE16.js → dev-account-DqEFCmVg.js} +0 -0
  47. /package/dist/{dev-app-cache-CP2P8SCZ.js → dev-app-cache-Dv1dZ_bw.js} +0 -0
  48. /package/dist/{executa-destructive-8iSnfmcn.js → executa-destructive-Bz7vWxEO.js} +0 -0
  49. /package/dist/{executa-init-BCqJUZXT.js → executa-init-D-kWINZ3.js} +0 -0
  50. /package/dist/{executa-reads-CjIr8BuD.js → executa-reads-BXDJWWw6.js} +0 -0
  51. /package/dist/{executa-register-CMmlKyKB.js → executa-register-D5kvSSz_.js} +0 -0
  52. /package/dist/{fixture-BJqc1IfX.js → fixture-BUKQYR5e.js} +0 -0
  53. /package/dist/{host_upload-sfo4UHlR.js → host_upload-BVzAqvX1.js} +0 -0
  54. /package/dist/{image-Bdi4Hu0m.js → image-BLPyUbGQ.js} +0 -0
  55. /package/dist/{login-CslsHbsq.js → login-DhgBgsfx.js} +0 -0
  56. /package/dist/{logout-B4_b9ZL0.js → logout-VYDkLYAx.js} +0 -0
  57. /package/dist/{sampling-Cc0qaj8a.js → sampling-XBIEYU4A.js} +0 -0
  58. /package/dist/{token-hGGfoge2.js → token-uedeaAy7.js} +0 -0
  59. /package/dist/{whoami-ChzwOaN2.js → whoami-C_x26b_k.js} +0 -0
package/dist/cli.js CHANGED
@@ -470,7 +470,7 @@ program.command("validate").description("Run schema + ACL checks on a manifest+b
470
470
  process.exit(code);
471
471
  });
472
472
  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) => {
473
- const { runDev, parseExecutaSpec } = await import("./dev-C9VpI_AL.js");
473
+ const { runDev, parseExecutaSpec } = await import("./dev-C3yWhzAp.js");
474
474
  const cwd = opts.cwd ?? process.cwd();
475
475
  let executas;
476
476
  if (opts.executa && opts.executa.length > 0) {
@@ -505,7 +505,7 @@ program.command("dev").description("Run a local harness (in-process dispatcher +
505
505
  });
506
506
  const fixture = program.command("fixture").description("Inspect / replay harness recordings (Phase 6)");
507
507
  fixture.command("verify <file>").description("Schema + invariant checks on a harness JSONL recording").option("--json", "Emit machine-readable JSON", false).action(async (file, opts) => {
508
- const { runFixtureVerify } = await import("./fixture-BJqc1IfX.js");
508
+ const { runFixtureVerify } = await import("./fixture-BUKQYR5e.js");
509
509
  const code = await runFixtureVerify({
510
510
  file,
511
511
  json: opts.json
@@ -513,7 +513,7 @@ fixture.command("verify <file>").description("Schema + invariant checks on a har
513
513
  process.exit(code);
514
514
  });
515
515
  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) => {
516
- const { runFixtureSummarize } = await import("./fixture-BJqc1IfX.js");
516
+ const { runFixtureSummarize } = await import("./fixture-BUKQYR5e.js");
517
517
  const code = await runFixtureSummarize({
518
518
  file,
519
519
  json: opts.json
@@ -521,7 +521,7 @@ fixture.command("summarize <file>").description("Print a human-readable digest o
521
521
  process.exit(code);
522
522
  });
523
523
  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) => {
524
- const { runFixtureReplay } = await import("./fixture-BJqc1IfX.js");
524
+ const { runFixtureReplay } = await import("./fixture-BUKQYR5e.js");
525
525
  const code = await runFixtureReplay({
526
526
  file,
527
527
  manifest: opts.manifest
@@ -529,12 +529,12 @@ fixture.command("replay <file>").description("Dry-run replay of a harness record
529
529
  process.exit(code);
530
530
  });
531
531
  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) => {
532
- const { runDoctor } = await import("./doctor-DnCYaREu.js");
532
+ const { runDoctor } = await import("./doctor-VrfEkedz.js");
533
533
  const code = await runDoctor({ matrixNexusRoot: opts.matrixNexusRoot });
534
534
  process.exit(code);
535
535
  });
536
536
  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) => {
537
- const { runLogin } = await import("./login-CslsHbsq.js");
537
+ const { runLogin } = await import("./login-DhgBgsfx.js");
538
538
  const code = await runLogin({
539
539
  host: opts.host,
540
540
  noBrowser: opts.browser === false
@@ -542,7 +542,7 @@ program.command("login").description("Device-flow login against a nexus host; sa
542
542
  process.exit(code);
543
543
  });
544
544
  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) => {
545
- const { runLogout } = await import("./logout-B4_b9ZL0.js");
545
+ const { runLogout } = await import("./logout-VYDkLYAx.js");
546
546
  const code = await runLogout({
547
547
  host: opts.host,
548
548
  all: opts.all
@@ -550,13 +550,13 @@ program.command("logout").description("Remove a saved PAT entry").option("--host
550
550
  process.exit(code);
551
551
  });
552
552
  program.command("whoami").description("Show the current account (and any others)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
553
- const { runWhoami } = await import("./whoami-ChzwOaN2.js");
553
+ const { runWhoami } = await import("./whoami-C_x26b_k.js");
554
554
  const code = await runWhoami({ json: opts.json });
555
555
  process.exit(code);
556
556
  });
557
557
  const account = program.command("account").description("Manage your developer account (handle / namespace)");
558
558
  account.command("set-handle <handle>").description("Set or rename your developer handle — the @handle namespace your apps publish under (@handle/slug). Required before creating your first app.").option("--host <url>", "Account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (handle, opts) => {
559
- const { runAccountSetHandle } = await import("./account-B6n0XkpV.js");
559
+ const { runAccountSetHandle } = await import("./account-bqao7Gp5.js");
560
560
  const code = await runAccountSetHandle({
561
561
  handle,
562
562
  account: opts.host,
@@ -576,7 +576,7 @@ executa.command("init <dir>").description("Scaffold a standalone Executa plugin
576
576
  console.error(`✗ unknown template "${opts.template}" — expected python | node | go`);
577
577
  process.exit(2);
578
578
  }
579
- const { runExecutaInit } = await import("./executa-init-BCqJUZXT.js");
579
+ const { runExecutaInit } = await import("./executa-init-D-kWINZ3.js");
580
580
  const code = runExecutaInit({
581
581
  targetDir: dir,
582
582
  slug,
@@ -587,12 +587,12 @@ executa.command("init <dir>").description("Scaffold a standalone Executa plugin
587
587
  process.exit(code);
588
588
  });
589
589
  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 executa.json tool_id / executable_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) => {
590
- const { runExecutaRegister } = await import("./executa-register-CMmlKyKB.js");
590
+ const { runExecutaRegister } = await import("./executa-register-D5kvSSz_.js");
591
591
  const code = await runExecutaRegister(opts);
592
592
  process.exit(code);
593
593
  });
594
594
  executa.command("install").description("Install a local-dev shim for an Executa under its minted tool_id so the Agent can discover it via 'Rediscover Local' (for distribution_type: local). Resolves the tool_id from .anna/executa.json (written by `executa publish` / `apps push`) unless --tool-id is given.").option("--dir <path>", "Executa project dir (default: CWD)").option("--tool-id <id>", "Install the shim under this exact id (default: minted id from .anna/executa.json, else executa.json tool_id)").option("--bin-dir <path>", "Install dir for the shim (default: ~/.anna/executa/bin)").option("--force", "Overwrite an existing shim of the same name", false).option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
595
- const { runExecutaInstall } = await import("./executa-install-Bc1WRrWu.js");
595
+ const { runExecutaInstall } = await import("./executa-install-Cyid8R7r.js");
596
596
  const code = await runExecutaInstall({
597
597
  dir: opts.dir,
598
598
  toolId: opts.toolId,
@@ -603,7 +603,7 @@ executa.command("install").description("Install a local-dev shim for an Executa
603
603
  process.exit(code);
604
604
  });
605
605
  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("--sampling-unsupported-format", "Simulate a model without json_schema support — exercises responseFormat onUnsupported branches (-32010 / downgrade)").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) => {
606
- const { runExecutaDev } = await import("./executa-dev-0XdBPTDy.js");
606
+ const { runExecutaDev } = await import("./executa-dev-B5Uz982M.js");
607
607
  const storageMode = opts.storage === void 0 ? void 0 : (() => {
608
608
  const m = opts.storage;
609
609
  if (m === "off" || m === "memory" || m === "mock" || m === "real") return m;
@@ -641,14 +641,14 @@ executa.command("dev").description("Run one Executa plugin in isolation (REPL or
641
641
  });
642
642
  const apps = program.command("apps").description("Anna App publish lifecycle commands");
643
643
  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) => {
644
- const { runAppsList } = await import("./apps-BpJ-TvHP.js");
644
+ const { runAppsList } = await import("./apps-dvknZYI2.js");
645
645
  process.exit(await runAppsList({
646
646
  account: opts.account,
647
647
  json: opts.json
648
648
  }));
649
649
  });
650
650
  apps.command("rename-slug <new-slug>").description("Rename an app's public slug (DRAFT/REJECTED, never-published, zero installs only). Updates local app.json + .anna/app.json on success.").option("--cwd <dir>", "Project root (default: cwd)").option("--manifest <path>", "manifest.json path", "manifest.json").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (newSlug, opts) => {
651
- const { runAppsRenameSlug } = await import("./apps-rename-slug-Bp-nQ_6I.js");
651
+ const { runAppsRenameSlug } = await import("./apps-rename-slug-D2BrWasG.js");
652
652
  process.exit(await runAppsRenameSlug({
653
653
  newSlug,
654
654
  cwd: opts.cwd,
@@ -666,7 +666,7 @@ apps.command("publish").description("Publish or update an Anna App (manifest.jso
666
666
  console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
667
667
  process.exit(2);
668
668
  }
669
- const { runAppsPublish } = await import("./apps-publish-3wbhXfAg.js");
669
+ const { runAppsPublish } = await import("./apps-publish-Djpw5cfG.js");
670
670
  process.exit(await runAppsPublish({
671
671
  cwd: opts.cwd,
672
672
  manifest: opts.manifest,
@@ -699,7 +699,7 @@ apps.command("push").description("Upsert the mutable working draft (manifest + b
699
699
  process.exit(2);
700
700
  }
701
701
  }
702
- const { runAppsPush } = await import("./apps-push-Bh8zwT--.js");
702
+ const { runAppsPush } = await import("./apps-push-B3wZr9B4.js");
703
703
  process.exit(await runAppsPush({
704
704
  cwd: opts.cwd,
705
705
  manifest: opts.manifest,
@@ -718,7 +718,7 @@ apps.command("push").description("Upsert the mutable working draft (manifest + b
718
718
  }));
719
719
  });
720
720
  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) => {
721
- const { runAppsCut } = await import("./apps-cut-C5SH9qZN.js");
721
+ const { runAppsCut } = await import("./apps-cut-8870xpk-.js");
722
722
  process.exit(await runAppsCut({
723
723
  version,
724
724
  changelog: opts.changelog,
@@ -730,7 +730,7 @@ apps.command("cut <version>").description("Snapshot the working draft into an im
730
730
  }));
731
731
  });
732
732
  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) => {
733
- const { runAppsDiscard } = await import("./apps-discard-CfdkwUZ_.js");
733
+ const { runAppsDiscard } = await import("./apps-discard-hVZxAQyj.js");
734
734
  process.exit(await runAppsDiscard({
735
735
  slug: opts.slug,
736
736
  cwd: opts.cwd,
@@ -740,7 +740,7 @@ apps.command("discard").description("Drop the mutable working draft (leaves cut
740
740
  }));
741
741
  });
742
742
  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) => {
743
- const { runAppsRelease } = await import("./apps-release-DNlN_8gz.js");
743
+ const { runAppsRelease } = await import("./apps-release-DZK30eF_.js");
744
744
  process.exit(await runAppsRelease({
745
745
  version,
746
746
  slug: opts.slug,
@@ -751,18 +751,19 @@ apps.command("release <version>").description("Freeze & publish an existing remo
751
751
  json: opts.json
752
752
  }));
753
753
  });
754
- 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) => {
755
- const { runAppsSyncMeta } = await import("./apps-sync-meta-DdPnXuIU.js");
754
+ 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("--logo <path>", "Local logo file to upload (overrides app.json logo_file)").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) => {
755
+ const { runAppsSyncMeta } = await import("./apps-sync-meta-BOb6J_wz.js");
756
756
  process.exit(await runAppsSyncMeta({
757
757
  cwd: opts.cwd,
758
758
  manifest: opts.manifest,
759
+ logo: opts.logo,
759
760
  dryRun: opts.dryRun,
760
761
  account: opts.account,
761
762
  json: opts.json
762
763
  }));
763
764
  });
764
765
  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) => {
765
- const { runAppsSubmitReview } = await import("./apps-submit-review-DH-bzbDZ.js");
766
+ const { runAppsSubmitReview } = await import("./apps-submit-review-DMFQI8JZ.js");
766
767
  process.exit(await runAppsSubmitReview({
767
768
  slug,
768
769
  cwd: opts.cwd,
@@ -771,7 +772,7 @@ apps.command("submit-review [slug]").description("Move an app into review (DRAFT
771
772
  }));
772
773
  });
773
774
  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) => {
774
- const { runAppsStatus } = await import("./apps-status-5DV9cY4A.js");
775
+ const { runAppsStatus } = await import("./apps-status-Ca6MdXZd.js");
775
776
  process.exit(await runAppsStatus({
776
777
  slug,
777
778
  account: opts.account,
@@ -779,7 +780,7 @@ apps.command("status <slug>").description("Show server-known state for one Anna
779
780
  }));
780
781
  });
781
782
  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) => {
782
- const { runAppsVersions } = await import("./apps-versions-vGihRRje.js");
783
+ const { runAppsVersions } = await import("./apps-versions-D1lixrmM.js");
783
784
  process.exit(await runAppsVersions({
784
785
  slug,
785
786
  account: opts.account,
@@ -787,7 +788,7 @@ apps.command("versions <slug>").description("List all server versions of one Ann
787
788
  }));
788
789
  });
789
790
  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) => {
790
- const { runAppsGrants } = await import("./apps-grants-BtXXiuJt.js");
791
+ const { runAppsGrants } = await import("./apps-grants-DnXCnkH5.js");
791
792
  process.exit(await runAppsGrants({
792
793
  slug,
793
794
  account: opts.account,
@@ -795,7 +796,7 @@ apps.command("grants <slug>").description("Show currently granted scopes/quota f
795
796
  }));
796
797
  });
797
798
  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) => {
798
- const { runAppsUnpublish } = await import("./apps-destructive-PY0wKjqu.js");
799
+ const { runAppsUnpublish } = await import("./apps-destructive-B6RFjokU.js");
799
800
  process.exit(await runAppsUnpublish({
800
801
  slug,
801
802
  yes: opts.yes,
@@ -805,7 +806,7 @@ apps.command("unpublish <slug>").description("Flip a PUBLISHED app back to APPRO
805
806
  }));
806
807
  });
807
808
  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) => {
808
- const { runAppsArchive } = await import("./apps-destructive-PY0wKjqu.js");
809
+ const { runAppsArchive } = await import("./apps-destructive-B6RFjokU.js");
809
810
  process.exit(await runAppsArchive({
810
811
  slug,
811
812
  yes: opts.yes,
@@ -815,7 +816,7 @@ apps.command("archive <slug>").description("Archive an Anna App (hides it from e
815
816
  }));
816
817
  });
817
818
  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) => {
818
- const { runAppsUnarchive } = await import("./apps-destructive-PY0wKjqu.js");
819
+ const { runAppsUnarchive } = await import("./apps-destructive-B6RFjokU.js");
819
820
  process.exit(await runAppsUnarchive({
820
821
  slug,
821
822
  yes: opts.yes,
@@ -824,7 +825,7 @@ apps.command("unarchive <slug>").description("Restore an archived Anna App back
824
825
  }));
825
826
  });
826
827
  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) => {
827
- const { runAppsDelete } = await import("./apps-destructive-PY0wKjqu.js");
828
+ const { runAppsDelete } = await import("./apps-destructive-B6RFjokU.js");
828
829
  process.exit(await runAppsDelete({
829
830
  slug,
830
831
  yes: opts.yes,
@@ -834,14 +835,14 @@ apps.command("delete <slug>").description("Hard-delete an Anna App (refused by s
834
835
  }));
835
836
  });
836
837
  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) => {
837
- const { runExecutaList } = await import("./executa-reads-CjIr8BuD.js");
838
+ const { runExecutaList } = await import("./executa-reads-BXDJWWw6.js");
838
839
  process.exit(await runExecutaList({
839
840
  account: opts.account,
840
841
  json: opts.json
841
842
  }));
842
843
  });
843
844
  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) => {
844
- const { runExecutaStatus } = await import("./executa-reads-CjIr8BuD.js");
845
+ const { runExecutaStatus } = await import("./executa-reads-BXDJWWw6.js");
845
846
  process.exit(await runExecutaStatus({
846
847
  ref,
847
848
  account: opts.account,
@@ -849,7 +850,7 @@ executa.command("status <ref>").description("Show server-known state for one Exe
849
850
  }));
850
851
  });
851
852
  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) => {
852
- const { runExecutaVersions } = await import("./executa-reads-CjIr8BuD.js");
853
+ const { runExecutaVersions } = await import("./executa-reads-BXDJWWw6.js");
853
854
  process.exit(await runExecutaVersions({
854
855
  ref,
855
856
  account: opts.account,
@@ -865,7 +866,7 @@ executa.command("publish").description("Mint or update an Executa (executa.json
865
866
  console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
866
867
  process.exit(2);
867
868
  }
868
- const { runExecutaPublish } = await import("./executa-publish-9XQRncyN.js");
869
+ const { runExecutaPublish } = await import("./executa-publish-DI_6M_ea.js");
869
870
  process.exit(await runExecutaPublish({
870
871
  cwd: opts.cwd,
871
872
  manifest: opts.manifest,
@@ -878,7 +879,7 @@ executa.command("publish").description("Mint or update an Executa (executa.json
878
879
  }));
879
880
  });
880
881
  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) => {
881
- const { runExecutaUnpublish } = await import("./executa-destructive-8iSnfmcn.js");
882
+ const { runExecutaUnpublish } = await import("./executa-destructive-Bz7vWxEO.js");
882
883
  process.exit(await runExecutaUnpublish({
883
884
  slug,
884
885
  yes: opts.yes,
@@ -888,7 +889,7 @@ executa.command("unpublish <slug>").description("Flip an Executa's visibility ba
888
889
  }));
889
890
  });
890
891
  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) => {
891
- const { runExecutaYank } = await import("./executa-destructive-8iSnfmcn.js");
892
+ const { runExecutaYank } = await import("./executa-destructive-Bz7vWxEO.js");
892
893
  process.exit(await runExecutaYank({
893
894
  ref,
894
895
  yes: opts.yes,
@@ -898,7 +899,7 @@ executa.command("yank <ref>").description("Hard-delete one Executa version (<slu
898
899
  }));
899
900
  });
900
901
  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) => {
901
- const { runExecutaDelete } = await import("./executa-destructive-8iSnfmcn.js");
902
+ const { runExecutaDelete } = await import("./executa-destructive-Bz7vWxEO.js");
902
903
  process.exit(await runExecutaDelete({
903
904
  slug,
904
905
  yes: opts.yes,
@@ -923,7 +924,7 @@ executa.command("cache-clear").description("Delete the local `.anna/executa.json
923
924
  });
924
925
  const token = program.command("token").description("Manage developer PATs (list / revoke / scopes)");
925
926
  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) => {
926
- const { runTokenList } = await import("./token-hGGfoge2.js");
927
+ const { runTokenList } = await import("./token-uedeaAy7.js");
927
928
  process.exit(await runTokenList({
928
929
  includeRevoked: opts.includeRevoked,
929
930
  account: opts.account,
@@ -936,7 +937,7 @@ token.command("revoke <id>").description("Revoke one of the caller's PATs by id"
936
937
  console.error(`✗ token id must be a positive integer (got: ${id})`);
937
938
  process.exit(2);
938
939
  }
939
- const { runTokenRevoke } = await import("./token-hGGfoge2.js");
940
+ const { runTokenRevoke } = await import("./token-uedeaAy7.js");
940
941
  process.exit(await runTokenRevoke({
941
942
  id: idNum,
942
943
  account: opts.account,
@@ -944,7 +945,7 @@ token.command("revoke <id>").description("Revoke one of the caller's PATs by id"
944
945
  }));
945
946
  });
946
947
  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) => {
947
- const { runTokenScopes } = await import("./token-hGGfoge2.js");
948
+ const { runTokenScopes } = await import("./token-uedeaAy7.js");
948
949
  process.exit(await runTokenScopes({
949
950
  account: opts.account,
950
951
  json: opts.json
@@ -959,7 +960,7 @@ program.command("publish").description("Auto-detect cwd and publish (apps publis
959
960
  console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
960
961
  process.exit(2);
961
962
  }
962
- const { runTopLevelPublish } = await import("./publish-NTT1Libd.js");
963
+ const { runTopLevelPublish } = await import("./publish-GpvkaBIx.js");
963
964
  process.exit(await runTopLevelPublish({
964
965
  cwd: opts.cwd,
965
966
  bump: opts.bump,
@@ -0,0 +1,4 @@
1
+ import "./nexus-root-BlPwOusj.js";
2
+ import { parseExecutaSpec, runDev } from "./dev-Re6NyNDS.js";
3
+
4
+ export { parseExecutaSpec, runDev };
@@ -49,8 +49,8 @@ async function runDev(opts) {
49
49
  }
50
50
  process.env.ANNA_APP_RUNTIME_STORAGE_MODE = "aps";
51
51
  }
52
- const { PythonBridge, PINNED_RUNTIME_VERSION } = await import("./bridge-CmoKMMcG.js");
53
- const { HarnessServer } = await import("./server-DtnMLKQS.js");
52
+ const { PythonBridge, PINNED_RUNTIME_VERSION } = await import("./bridge-CzHB_IsQ.js");
53
+ const { HarnessServer } = await import("./server-BMcGaUTy.js");
54
54
  const bridge = new PythonBridge({
55
55
  mode,
56
56
  matrixNexusRoot: matrixNexusRoot ?? void 0,
@@ -161,7 +161,7 @@ async function runDev(opts) {
161
161
  */
162
162
  async function resolveRealLlm(args) {
163
163
  const { getAccount } = await import("./credentials-Chkoidh5.js");
164
- const { ensureDevAppRegistered } = await import("./dev-app-cache-CP2P8SCZ.js");
164
+ const { ensureDevAppRegistered } = await import("./dev-app-cache-Dv1dZ_bw.js");
165
165
  const acc = getAccount(args.account);
166
166
  if (!acc) {
167
167
  console.error(red("✗ no developer PAT on disk — run `anna-app login --host <nexus-url>` first.\n (or use `--no-llm` / `--mock-llm <fixture>` to develop offline.)"));
@@ -190,7 +190,7 @@ async function resolveRealLlm(args) {
190
190
  account: args.account,
191
191
  appSlug: entry.slug,
192
192
  onAppSlugNotFound: async () => {
193
- const { invalidateDevAppCache } = await import("./dev-app-cache-CP2P8SCZ.js");
193
+ const { invalidateDevAppCache } = await import("./dev-app-cache-Dv1dZ_bw.js");
194
194
  invalidateDevAppCache(args.cwd);
195
195
  const fresh = getAccount(args.account);
196
196
  if (!fresh) throw new Error("PAT not found while re-registering dev app — run `anna-app login` again");
@@ -1,5 +1,5 @@
1
1
  import { findMatrixNexusRoot, nexusSchemaDir } from "./nexus-root-BlPwOusj.js";
2
- import { PINNED_RUNTIME_VERSION } from "./bridge-DXH59CmP.js";
2
+ import { PINNED_RUNTIME_VERSION } from "./bridge-CbjqAm0H.js";
3
3
  import { resolve } from "node:path";
4
4
  import { existsSync, statSync } from "node:fs";
5
5
  import { spawnSync } from "node:child_process";
@@ -1,5 +1,5 @@
1
1
  import "./nexus-root-BlPwOusj.js";
2
- import { parseExecutaSpec } from "./dev-aWkfWGLD.js";
2
+ import { parseExecutaSpec } from "./dev-Re6NyNDS.js";
3
3
  import { isAbsolute, resolve } from "node:path";
4
4
  import { existsSync } from "node:fs";
5
5
  import { bold, cyan, dim, green, red, yellow } from "kleur/colors";
@@ -35,7 +35,7 @@ async function runExecutaDev(opts) {
35
35
  const oneShot = !!(opts.describe || opts.health || opts.invoke);
36
36
  const quiet = oneShot && (opts.json ?? false);
37
37
  const { getAccount } = await import("./credentials-Chkoidh5.js");
38
- const { ensureDevExecutaRegistered } = await import("./dev-app-cache-CP2P8SCZ.js");
38
+ const { ensureDevExecutaRegistered } = await import("./dev-app-cache-Dv1dZ_bw.js");
39
39
  const needsRealMint = !opts.noSampling && !opts.mockSampling || !opts.noAgent && !opts.mockAgent || !opts.noImage && !opts.mockImage || !opts.noUpload && !opts.mockUpload || opts.storage === "real";
40
40
  let effectiveAppSlug = opts.appSlug;
41
41
  let autoRegistered = false;
@@ -57,7 +57,7 @@ async function runExecutaDev(opts) {
57
57
  }
58
58
  }
59
59
  }
60
- const { SamplingBridge } = await import("./sampling-Cc0qaj8a.js");
60
+ const { SamplingBridge } = await import("./sampling-XBIEYU4A.js");
61
61
  const simulateUnsupportedResponseFormat = opts.samplingUnsupportedFormat;
62
62
  const sampling = opts.noSampling ? new SamplingBridge({ mode: "off" }) : opts.mockSampling ? new SamplingBridge({
63
63
  mode: "mock",
@@ -69,7 +69,7 @@ async function runExecutaDev(opts) {
69
69
  appSlug: effectiveAppSlug,
70
70
  simulateUnsupportedResponseFormat
71
71
  }) : new SamplingBridge({ mode: "off" });
72
- const { AgentBridge } = await import("./agent-J2bELWfv.js");
72
+ const { AgentBridge } = await import("./agent-CzPryLi6.js");
73
73
  const agent = opts.noAgent ? new AgentBridge({ mode: "off" }) : opts.mockAgent ? new AgentBridge({
74
74
  mode: "mock",
75
75
  mockFile: opts.mockAgent
@@ -78,7 +78,7 @@ async function runExecutaDev(opts) {
78
78
  account: opts.agentAccount ?? opts.samplingAccount,
79
79
  appSlug: effectiveAppSlug
80
80
  }) : new AgentBridge({ mode: "off" });
81
- const { StorageBridge } = await import("./storage-C95wApr2.js");
81
+ const { StorageBridge } = await import("./storage-BkF4XyI0.js");
82
82
  const storageMode = opts.storage ?? (opts.mockStorage ? "mock" : "memory");
83
83
  const storage = new StorageBridge({
84
84
  mode: storageMode,
@@ -88,8 +88,8 @@ async function runExecutaDev(opts) {
88
88
  scopes: opts.storageScopes ? opts.storageScopes.split(",").map((s) => s.trim()).filter(Boolean) : void 0,
89
89
  pluginName: parsed.tool_id
90
90
  });
91
- const { ExecutaRunner } = await import("./runner-DVu-o_U8.js");
92
- const { ImageBridge } = await import("./image-Bdi4Hu0m.js");
91
+ const { ExecutaRunner } = await import("./runner-BxYjAmih.js");
92
+ const { ImageBridge } = await import("./image-BLPyUbGQ.js");
93
93
  const image = opts.noImage ? new ImageBridge({ mode: "off" }) : opts.mockImage ? new ImageBridge({
94
94
  mode: "mock",
95
95
  mockFile: opts.mockImage
@@ -98,7 +98,7 @@ async function runExecutaDev(opts) {
98
98
  account: opts.imageAccount ?? opts.samplingAccount,
99
99
  appSlug: effectiveAppSlug
100
100
  }) : new ImageBridge({ mode: "off" });
101
- const { HostUploadBridge } = await import("./host_upload-sfo4UHlR.js");
101
+ const { HostUploadBridge } = await import("./host_upload-BVzAqvX1.js");
102
102
  const hostUpload = opts.noUpload ? new HostUploadBridge({ mode: "off" }) : opts.mockUpload ? new HostUploadBridge({
103
103
  mode: "mock",
104
104
  mockFile: opts.mockUpload
@@ -1,5 +1,5 @@
1
1
  import { readExecutaIdentity } from "./executa-cache-Do1D7xC0.js";
2
- import { parseExecutaSpec } from "./dev-aWkfWGLD.js";
2
+ import { parseExecutaSpec } from "./dev-Re6NyNDS.js";
3
3
  import { isAbsolute, join, resolve } from "node:path";
4
4
  import { chmodSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
5
5
  import { bold, cyan, dim, green, red, yellow } from "kleur/colors";
@@ -0,0 +1,7 @@
1
+ import "./credentials-BTv2IfUZ.js";
2
+ import "./nexus-root-BlPwOusj.js";
3
+ import "./executa-cache-Do1D7xC0.js";
4
+ import "./dev-Re6NyNDS.js";
5
+ import { runExecutaInstall } from "./executa-install-BW9jjY7u.js";
6
+
7
+ export { runExecutaInstall };
@@ -3,7 +3,7 @@ import { CliError } from "./client-D-_z1ALk.js";
3
3
  import { resolveClient, withErrorHandling } from "./_lifecycle-shared-CUK2CE76.js";
4
4
  import { commitDraft, createDraft, getMySkill, getMyTool, listToolVersions, publishToolVersion, setSkillVisibility, setToolVisibility, updateMySkill, updateMyTool } from "./executas-BhFed1B-.js";
5
5
  import { executaCacheMatches, invalidateExecutaCache, mintIdempotencyKey, readExecutaIdentity, writeExecutaIdentity } from "./executa-cache-Do1D7xC0.js";
6
- import { loadExecutaManifest } from "./manifest-CMc7RM57.js";
6
+ import { loadExecutaManifest } from "./manifest-DOMrcdCK.js";
7
7
  import { join, relative, resolve, sep } from "node:path";
8
8
  import { readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
9
9
  import { bold, cyan, dim, green, yellow } from "kleur/colors";
@@ -3,7 +3,7 @@ import "./client-D-_z1ALk.js";
3
3
  import "./_lifecycle-shared-CUK2CE76.js";
4
4
  import "./executas-BhFed1B-.js";
5
5
  import "./executa-cache-Do1D7xC0.js";
6
- import { runExecutaPublish } from "./executa-publish-Xmm4DMO9.js";
7
- import "./manifest-CMc7RM57.js";
6
+ import { runExecutaPublish } from "./executa-publish-Ah6J7jYd.js";
7
+ import "./manifest-DOMrcdCK.js";
8
8
 
9
9
  export { runExecutaPublish };
@@ -0,0 +1,117 @@
1
+ import { patchApp, uploadAppLogo, uploadAppScreenshot } from "./apps-DlVsVHQ5.js";
2
+ import { CliError } from "./client-D-_z1ALk.js";
3
+ import { extname, resolve } from "node:path";
4
+ import { existsSync, readFileSync } from "node:fs";
5
+
6
+ //#region src/publish/listing-meta.ts
7
+ const IMAGE_CONTENT_TYPES = {
8
+ ".svg": "image/svg+xml",
9
+ ".png": "image/png",
10
+ ".jpg": "image/jpeg",
11
+ ".jpeg": "image/jpeg",
12
+ ".webp": "image/webp",
13
+ ".gif": "image/gif"
14
+ };
15
+ function imageContentType(path) {
16
+ return IMAGE_CONTENT_TYPES[extname(path).toLowerCase()] ?? "application/octet-stream";
17
+ }
18
+ /**
19
+ * A listing asset is "remote" (forwarded verbatim) when it's an absolute
20
+ * http(s) URL or an inline `data:` URI. Anything else is treated as a
21
+ * project-relative local file to be uploaded to the CDN — same split the logo
22
+ * uses between `logoUrl` and `logoFile`.
23
+ */
24
+ function isRemoteAsset(src) {
25
+ return /^https?:\/\//i.test(src) || src.startsWith("data:");
26
+ }
27
+ /**
28
+ * Build the metadata payload from the manifest (only defined fields). The
29
+ * logo is handled separately and never appears here when sourced from a file.
30
+ */
31
+ function buildMeta(manifest) {
32
+ const meta = {};
33
+ const add = (key, value) => {
34
+ if (value !== void 0 && value !== null && value !== "") meta[key] = value;
35
+ };
36
+ add("name", manifest.name);
37
+ add("category", manifest.category);
38
+ add("tagline", manifest.tagline);
39
+ add("description", manifest.description);
40
+ add("cover_url", manifest.coverUrl);
41
+ add("homepage_url", manifest.homepageUrl);
42
+ add("support_url", manifest.supportUrl);
43
+ add("privacy_url", manifest.privacyUrl);
44
+ add("pricing_model", manifest.pricingModel);
45
+ return meta;
46
+ }
47
+ /**
48
+ * Sync the app's store-listing metadata (and logo) from the local manifest.
49
+ *
50
+ * Returns a plan/result. When `dryRun` is set, no network calls are made and
51
+ * the returned object reflects what *would* be sent.
52
+ */
53
+ async function syncAppListingMeta(client, appId, manifest, opts) {
54
+ const meta = buildMeta(manifest);
55
+ const localLogo = opts.logoOverride ?? manifest.logoFile;
56
+ let logoUpload;
57
+ if (localLogo) {
58
+ const logoPath = resolve(opts.cwd, localLogo);
59
+ if (!existsSync(logoPath)) throw new CliError(`logo file not found: ${logoPath}`, 4);
60
+ logoUpload = { source: localLogo };
61
+ } else if (manifest.logoUrl) meta.logo_url = manifest.logoUrl;
62
+ const screenshotSources = manifest.screenshots ?? [];
63
+ const screenshotPlan = screenshotSources.map((src) => {
64
+ const remote = isRemoteAsset(src);
65
+ if (!remote && !existsSync(resolve(opts.cwd, src))) throw new CliError(`screenshot file not found: ${resolve(opts.cwd, src)}`, 4);
66
+ return {
67
+ source: src,
68
+ remote
69
+ };
70
+ });
71
+ const localScreenshots = screenshotPlan.filter((s) => !s.remote);
72
+ const noop = Object.keys(meta).length === 0 && !logoUpload && screenshotSources.length === 0;
73
+ if (opts.dryRun || noop) {
74
+ if (screenshotSources.length > 0) meta.screenshots = screenshotSources;
75
+ return {
76
+ meta,
77
+ logoUpload,
78
+ screenshotUploads: localScreenshots.length > 0 ? localScreenshots.map((s) => ({ source: s.source })) : void 0,
79
+ noop
80
+ };
81
+ }
82
+ const screenshotUploads = [];
83
+ const finalScreenshots = [];
84
+ for (const item of screenshotPlan) {
85
+ if (item.remote) {
86
+ finalScreenshots.push(item.source);
87
+ continue;
88
+ }
89
+ const shotPath = resolve(opts.cwd, item.source);
90
+ const bytes = readFileSync(shotPath);
91
+ const blob = new Blob([new Uint8Array(bytes)], { type: imageContentType(shotPath) });
92
+ const res = await uploadAppScreenshot(client, appId, blob);
93
+ finalScreenshots.push(res.screenshot_url);
94
+ screenshotUploads.push({
95
+ source: item.source,
96
+ screenshot_url: res.screenshot_url
97
+ });
98
+ }
99
+ if (finalScreenshots.length > 0) meta.screenshots = finalScreenshots;
100
+ if (Object.keys(meta).length > 0) await patchApp(client, appId, meta);
101
+ if (logoUpload) {
102
+ const logoPath = resolve(opts.cwd, logoUpload.source);
103
+ const bytes = readFileSync(logoPath);
104
+ const blob = new Blob([new Uint8Array(bytes)], { type: imageContentType(logoPath) });
105
+ const res = await uploadAppLogo(client, appId, blob);
106
+ logoUpload.logo_url = res.logo_url;
107
+ }
108
+ return {
109
+ meta,
110
+ logoUpload,
111
+ screenshotUploads: screenshotUploads.length > 0 ? screenshotUploads : void 0,
112
+ noop
113
+ };
114
+ }
115
+
116
+ //#endregion
117
+ export { syncAppListingMeta };