@anna-ai/cli 0.1.22 → 0.1.26

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 (67) hide show
  1. package/dist/{_lifecycle-shared-sbea9HtH.js → _lifecycle-shared-BpSOfVCP.js} +1 -1
  2. package/dist/{agent-Br6zY2qw.js → agent-CaZVCPs6.js} +1 -1
  3. package/dist/{app-bundle-upload-DuLalcSt.js → app-bundle-upload-BhAYo6yj.js} +3 -3
  4. package/dist/{apps-BTn9EN0x.js → apps-3VcdHIBK.js} +3 -3
  5. package/dist/{apps-cut-DtEkddIk.js → apps-cut-BCicQFRY.js} +13 -10
  6. package/dist/{apps-destructive-DSTrcFUP.js → apps-destructive-DWF4eTHn.js} +4 -4
  7. package/dist/{apps-discard-y3_IwcbQ.js → apps-discard-BoY4zMJw.js} +13 -10
  8. package/dist/{apps-grants-BGWlpee0.js → apps-grants-DgvymPBT.js} +3 -3
  9. package/dist/{apps-publish-CaTCanDu.js → apps-publish-Dgi4lBlu.js} +8 -8
  10. package/dist/apps-publish-Do7M5je3.js +14 -0
  11. package/dist/{apps-push-B9XT2uwF.js → apps-push-CixatuQG.js} +27 -12
  12. package/dist/{apps-release-BLH9XSxB.js → apps-release-DJFG4BV3.js} +5 -5
  13. package/dist/{apps-status-DQ9RvlME.js → apps-status-F6aVlzDW.js} +3 -3
  14. package/dist/{apps-submit-review-DLwCxeAs.js → apps-submit-review-BVmZlhmB.js} +4 -4
  15. package/dist/{apps-sync-meta-D9eKMMUp.js → apps-sync-meta-CQQC_Heb.js} +5 -5
  16. package/dist/{apps-versions-2Tmk0nsx.js → apps-versions-BIKsJzIT.js} +3 -3
  17. package/dist/{bridge-BuklhzeE.js → bridge-DxBd0Fl9.js} +1 -1
  18. package/dist/bridge-hzqNFm9-.js +3 -0
  19. package/dist/{bundled-executas-BNOKw4kv.js → bundled-executas-B6b8gIfp.js} +1 -1
  20. package/dist/{bundled-executas-CNaV2C_O.js → bundled-executas-DeBhDjd8.js} +2 -2
  21. package/dist/cli.js +70 -48
  22. package/dist/{confirm-DxHkk9Wn.js → confirm-h_qMrx0I.js} +1 -1
  23. package/dist/{dev-E7mqXj5S.js → dev-3okZmzNM.js} +19 -22
  24. package/dist/dev-C5r439wM.js +4 -0
  25. package/dist/{doctor-DKrt-Kda.js → doctor-giNqYnla.js} +10 -22
  26. package/dist/{executa-cache-WBkCLic7.js → executa-cache-Kx3rfQD-.js} +1 -1
  27. package/dist/{executa-destructive-COQE4Xqi.js → executa-destructive-PL2ooHpZ.js} +4 -4
  28. package/dist/{executa-dev-BvS9zTpO.js → executa-dev-Cr9Yepph.js} +10 -9
  29. package/dist/executa-install-DQIhVHPT.js +90 -0
  30. package/dist/executa-install-DjXE_-U-.js +7 -0
  31. package/dist/{executa-publish-Ca5V7MyA.js → executa-publish-CkPAB34b.js} +5 -5
  32. package/dist/executa-publish-IXWSwva0.js +9 -0
  33. package/dist/{executa-reads-CQ6S8gHY.js → executa-reads-CjGZq1yP.js} +3 -3
  34. package/dist/{manifest-DGwRap2i.js → manifest-Bljz8Y6T.js} +74 -15
  35. package/dist/nexus-root-BlPwOusj.js +49 -0
  36. package/dist/{publish-C1wcf-qI.js → publish-BYWuujP3.js} +11 -11
  37. package/dist/{server-_IG8Igje.js → server-Cp7mYV9t.js} +50 -8
  38. package/dist/{storage-CTkApNQ9.js → storage-CKTmE87u.js} +1 -1
  39. package/dist/test/index.js +3 -0
  40. package/dist/{token-B9JUPelx.js → token-Cg7BZGp6.js} +2 -2
  41. package/dist/{working-orchestration-Dw9u1Vq0.js → working-orchestration-Dd1ETQ3c.js} +54 -7
  42. package/package.json +5 -4
  43. package/templates/executa/go/main.go +4 -2
  44. package/templates/executa/node/plugin.mjs +4 -2
  45. package/templates/executa/python/__SLUG_PY___plugin.py +4 -2
  46. package/dist/apps-publish-DfZTOxBJ.js +0 -14
  47. package/dist/bridge-Id8K8gr-.js +0 -3
  48. package/dist/dev-BS_8yoSm.js +0 -3
  49. package/dist/executa-publish-B88_9gbp.js +0 -9
  50. /package/dist/{app-cache-BEM653Th.js → app-cache-Bl7cE5fm.js} +0 -0
  51. /package/dist/{apps-B1Nd8l_t.js → apps-CCdtLmxQ.js} +0 -0
  52. /package/dist/{client-Dn9zThOd.js → client-D-_z1ALk.js} +0 -0
  53. /package/dist/{credentials-DklPMD22.js → credentials-Chkoidh5.js} +0 -0
  54. /package/dist/{dev-account-qRaET1Cp.js → dev-account-CGo8k9_2.js} +0 -0
  55. /package/dist/{dev-app-cache-D-r6ZpEk.js → dev-app-cache-TSjL4D4n.js} +0 -0
  56. /package/dist/{executa-cache-BFoUtb4J.js → executa-cache-CXiEgFZY.js} +0 -0
  57. /package/dist/{executa-init-Jp-h9OI7.js → executa-init-DXea7yRN.js} +0 -0
  58. /package/dist/{executa-register-CulDtwYZ.js → executa-register-BUiPzPIU.js} +0 -0
  59. /package/dist/{executas-Cep6KEo0.js → executas-CK3er6f9.js} +0 -0
  60. /package/dist/{fixture-CYwxbiQD.js → fixture-BvP5umlN.js} +0 -0
  61. /package/dist/{host_upload-GXVkDM5M.js → host_upload-BXeHTgJs.js} +0 -0
  62. /package/dist/{image-DduR91n5.js → image-CSEXEfD-.js} +0 -0
  63. /package/dist/{login-BGqFjQwH.js → login-BGZjMAlh.js} +0 -0
  64. /package/dist/{logout-CGIRKH3y.js → logout-mh2_QlyM.js} +0 -0
  65. /package/dist/{runner-B-hIqx5L.js → runner-BuYbm-ex.js} +0 -0
  66. /package/dist/{sampling-CXke7hq1.js → sampling-BcML4teS.js} +0 -0
  67. /package/dist/{whoami-BoFLEUcp.js → whoami-l_kIkfbI.js} +0 -0
package/dist/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { printMascot } from "./mascot-wlYTJqMs.js";
3
+ import { findMatrixNexusRoot, nexusSchemaDir } from "./nexus-root-BlPwOusj.js";
3
4
  import { dirname, extname, join, relative, resolve } from "node:path";
4
5
  import { createRequire } from "node:module";
5
6
  import { Command } from "commander";
@@ -62,16 +63,17 @@ function runInit(opts) {
62
63
 
63
64
  //#endregion
64
65
  //#region src/schema-bundle.ts
65
- function resolveSchemaDir() {
66
+ function resolveSchemaDir(dirOverride) {
66
67
  if (process.env.ANNA_APP_SCHEMA_DIR) return process.env.ANNA_APP_SCHEMA_DIR;
68
+ if (dirOverride) return dirOverride;
67
69
  const req = createRequire(import.meta.url);
68
70
  const methodsAbs = req.resolve("@anna-ai/app-schema/methods");
69
71
  return resolve(dirname(methodsAbs), "..");
70
72
  }
71
- function loadSchemaBundle() {
73
+ function loadSchemaBundle(dirOverride) {
72
74
  let dir;
73
75
  try {
74
- dir = resolveSchemaDir();
76
+ dir = resolveSchemaDir(dirOverride);
75
77
  } catch (e) {
76
78
  throw new Error(`Could not locate @anna-ai/app-schema: ${e.message}\nRun \`pnpm install\` (or set ANNA_APP_SCHEMA_DIR to a local checkout).`);
77
79
  }
@@ -137,11 +139,16 @@ function hostApiAllows(manifest, ns, method) {
137
139
  if (!manifest.ui) return false;
138
140
  if (ns === "window") return true;
139
141
  const grants = manifest.ui.host_api ?? {};
142
+ if (ns === "tools" && (method === "invoke" || method === "list")) {
143
+ const tools = grants.tools;
144
+ if (tools && tools.length > 0) return true;
145
+ const declared = (manifest.required_executas?.length ?? 0) + (manifest.optional_executas?.length ?? 0);
146
+ return declared > 0;
147
+ }
140
148
  const methods = grants[ns];
141
149
  if (!methods || methods.length === 0) return false;
142
150
  if (methods.includes("*")) return true;
143
151
  if (methods.includes(method)) return true;
144
- if (ns === "tools" && (method === "invoke" || method === "list")) return true;
145
152
  return false;
146
153
  }
147
154
  function checkHostApiAllowance(usages, manifest, bundleMethods) {
@@ -388,8 +395,10 @@ function readBundleSources(dir) {
388
395
  function runValidate(opts) {
389
396
  const errors = [];
390
397
  const warnings = [];
391
- const bundle = loadSchemaBundle();
392
- console.log(kleur.gray(`[validate] @anna-ai/app-schema dispatcher_version=${bundle.dispatcherVersion} (${bundle.dir})`));
398
+ const nexusRoot = findMatrixNexusRoot(opts.matrixNexusRoot, opts.cwd);
399
+ const schemaOverride = nexusRoot ? nexusSchemaDir(nexusRoot) : null;
400
+ const bundle = loadSchemaBundle(schemaOverride ?? void 0);
401
+ console.log(kleur.gray(`[validate] @anna-ai/app-schema dispatcher_version=${bundle.dispatcherVersion} (${bundle.dir})` + (schemaOverride ? " [nexus-source]" : "")));
393
402
  const manifest = readManifest(opts.manifestPath);
394
403
  const schemaIssues = validateManifestSchema(bundle, manifest);
395
404
  for (const i of schemaIssues) errors.push(`schema ${i.path}: ${i.message}`);
@@ -448,19 +457,20 @@ program.command("init <dir>").description("Scaffold a new Anna App project").opt
448
457
  });
449
458
  process.exit(code);
450
459
  });
451
- program.command("validate").description("Run schema + ACL checks on a manifest+bundle").option("--manifest <path>", "manifest.json path", "manifest.json").option("--bundle <dir>", "bundle directory (default: ./bundle)").option("--strict", "Enable strict checks (host_api ACL grep)", false).action(async (opts) => {
460
+ program.command("validate").description("Run schema + ACL checks on a manifest+bundle").option("--manifest <path>", "manifest.json path", "manifest.json").option("--bundle <dir>", "bundle directory (default: ./bundle)").option("--strict", "Enable strict checks (host_api ACL grep)", false).option("--matrix-nexus-root <path>", "matrix-nexus checkout: validate against its in-tree (possibly unpublished) @anna-ai/app-schema bundle instead of the npm package (auto-detected if omitted; can also use $ANNA_NEXUS_ROOT)").action(async (opts) => {
452
461
  const cwd = process.cwd();
453
462
  const result = runValidate({
454
463
  cwd,
455
464
  manifestPath: resolve(cwd, opts.manifest),
456
465
  bundleDir: opts.bundle ? resolve(cwd, opts.bundle) : null,
457
- strict: opts.strict
466
+ strict: opts.strict,
467
+ matrixNexusRoot: opts.matrixNexusRoot
458
468
  });
459
469
  const code = printResult(result);
460
470
  process.exit(code);
461
471
  });
462
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) => {
463
- const { runDev, parseExecutaSpec } = await import("./dev-BS_8yoSm.js");
473
+ const { runDev, parseExecutaSpec } = await import("./dev-C5r439wM.js");
464
474
  const cwd = opts.cwd ?? process.cwd();
465
475
  let executas;
466
476
  if (opts.executa && opts.executa.length > 0) {
@@ -495,7 +505,7 @@ program.command("dev").description("Run a local harness (in-process dispatcher +
495
505
  });
496
506
  const fixture = program.command("fixture").description("Inspect / replay harness recordings (Phase 6)");
497
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) => {
498
- const { runFixtureVerify } = await import("./fixture-CYwxbiQD.js");
508
+ const { runFixtureVerify } = await import("./fixture-BvP5umlN.js");
499
509
  const code = await runFixtureVerify({
500
510
  file,
501
511
  json: opts.json
@@ -503,7 +513,7 @@ fixture.command("verify <file>").description("Schema + invariant checks on a har
503
513
  process.exit(code);
504
514
  });
505
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) => {
506
- const { runFixtureSummarize } = await import("./fixture-CYwxbiQD.js");
516
+ const { runFixtureSummarize } = await import("./fixture-BvP5umlN.js");
507
517
  const code = await runFixtureSummarize({
508
518
  file,
509
519
  json: opts.json
@@ -511,7 +521,7 @@ fixture.command("summarize <file>").description("Print a human-readable digest o
511
521
  process.exit(code);
512
522
  });
513
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) => {
514
- const { runFixtureReplay } = await import("./fixture-CYwxbiQD.js");
524
+ const { runFixtureReplay } = await import("./fixture-BvP5umlN.js");
515
525
  const code = await runFixtureReplay({
516
526
  file,
517
527
  manifest: opts.manifest
@@ -519,12 +529,12 @@ fixture.command("replay <file>").description("Dry-run replay of a harness record
519
529
  process.exit(code);
520
530
  });
521
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) => {
522
- const { runDoctor } = await import("./doctor-DKrt-Kda.js");
532
+ const { runDoctor } = await import("./doctor-giNqYnla.js");
523
533
  const code = await runDoctor({ matrixNexusRoot: opts.matrixNexusRoot });
524
534
  process.exit(code);
525
535
  });
526
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) => {
527
- const { runLogin } = await import("./login-BGqFjQwH.js");
537
+ const { runLogin } = await import("./login-BGZjMAlh.js");
528
538
  const code = await runLogin({
529
539
  host: opts.host,
530
540
  noBrowser: opts.browser === false
@@ -532,7 +542,7 @@ program.command("login").description("Device-flow login against a nexus host; sa
532
542
  process.exit(code);
533
543
  });
534
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) => {
535
- const { runLogout } = await import("./logout-CGIRKH3y.js");
545
+ const { runLogout } = await import("./logout-mh2_QlyM.js");
536
546
  const code = await runLogout({
537
547
  host: opts.host,
538
548
  all: opts.all
@@ -540,7 +550,7 @@ program.command("logout").description("Remove a saved PAT entry").option("--host
540
550
  process.exit(code);
541
551
  });
542
552
  program.command("whoami").description("Show the current account (and any others)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
543
- const { runWhoami } = await import("./whoami-BoFLEUcp.js");
553
+ const { runWhoami } = await import("./whoami-l_kIkfbI.js");
544
554
  const code = await runWhoami({ json: opts.json });
545
555
  process.exit(code);
546
556
  });
@@ -556,7 +566,7 @@ executa.command("init <dir>").description("Scaffold a standalone Executa plugin
556
566
  console.error(`✗ unknown template "${opts.template}" — expected python | node | go`);
557
567
  process.exit(2);
558
568
  }
559
- const { runExecutaInit } = await import("./executa-init-Jp-h9OI7.js");
569
+ const { runExecutaInit } = await import("./executa-init-DXea7yRN.js");
560
570
  const code = runExecutaInit({
561
571
  targetDir: dir,
562
572
  slug,
@@ -566,13 +576,24 @@ executa.command("init <dir>").description("Scaffold a standalone Executa plugin
566
576
  });
567
577
  process.exit(code);
568
578
  });
569
- 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) => {
570
- const { runExecutaRegister } = await import("./executa-register-CulDtwYZ.js");
579
+ 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) => {
580
+ const { runExecutaRegister } = await import("./executa-register-BUiPzPIU.js");
571
581
  const code = await runExecutaRegister(opts);
572
582
  process.exit(code);
573
583
  });
584
+ 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) => {
585
+ const { runExecutaInstall } = await import("./executa-install-DjXE_-U-.js");
586
+ const code = await runExecutaInstall({
587
+ dir: opts.dir,
588
+ toolId: opts.toolId,
589
+ binDir: opts.binDir,
590
+ force: opts.force,
591
+ json: opts.json
592
+ });
593
+ process.exit(code);
594
+ });
574
595
  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) => {
575
- const { runExecutaDev } = await import("./executa-dev-BvS9zTpO.js");
596
+ const { runExecutaDev } = await import("./executa-dev-Cr9Yepph.js");
576
597
  const storageMode = opts.storage === void 0 ? void 0 : (() => {
577
598
  const m = opts.storage;
578
599
  if (m === "off" || m === "memory" || m === "mock" || m === "real") return m;
@@ -609,7 +630,7 @@ executa.command("dev").description("Run one Executa plugin in isolation (REPL or
609
630
  });
610
631
  const apps = program.command("apps").description("Anna App publish lifecycle commands");
611
632
  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) => {
612
- const { runAppsList } = await import("./apps-BTn9EN0x.js");
633
+ const { runAppsList } = await import("./apps-3VcdHIBK.js");
613
634
  process.exit(await runAppsList({
614
635
  account: opts.account,
615
636
  json: opts.json
@@ -624,7 +645,7 @@ apps.command("publish").description("Publish or update an Anna App (manifest.jso
624
645
  console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
625
646
  process.exit(2);
626
647
  }
627
- const { runAppsPublish } = await import("./apps-publish-DfZTOxBJ.js");
648
+ const { runAppsPublish } = await import("./apps-publish-Do7M5je3.js");
628
649
  process.exit(await runAppsPublish({
629
650
  cwd: opts.cwd,
630
651
  manifest: opts.manifest,
@@ -640,7 +661,7 @@ apps.command("publish").description("Publish or update an Anna App (manifest.jso
640
661
  json: opts.json
641
662
  }));
642
663
  });
643
- 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) => {
664
+ 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("--no-install-local", "Don't install local-dev shims for bundled `local` executas (skip Rediscover-Local prep)").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) => {
644
665
  if (opts.bump && ![
645
666
  "patch",
646
667
  "minor",
@@ -657,7 +678,7 @@ apps.command("push").description("Upsert the mutable working draft (manifest + b
657
678
  process.exit(2);
658
679
  }
659
680
  }
660
- const { runAppsPush } = await import("./apps-push-B9XT2uwF.js");
681
+ const { runAppsPush } = await import("./apps-push-CixatuQG.js");
661
682
  process.exit(await runAppsPush({
662
683
  cwd: opts.cwd,
663
684
  manifest: opts.manifest,
@@ -669,13 +690,14 @@ apps.command("push").description("Upsert the mutable working draft (manifest + b
669
690
  noBundledExecutas: opts.bundledExecutas === false,
670
691
  noBundle: opts.bundle === false,
671
692
  bundleDir: opts.bundleDir,
693
+ noInstallLocal: opts.installLocal === false,
672
694
  ifMatch,
673
695
  account: opts.account,
674
696
  json: opts.json
675
697
  }));
676
698
  });
677
699
  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) => {
678
- const { runAppsCut } = await import("./apps-cut-DtEkddIk.js");
700
+ const { runAppsCut } = await import("./apps-cut-BCicQFRY.js");
679
701
  process.exit(await runAppsCut({
680
702
  version,
681
703
  changelog: opts.changelog,
@@ -687,7 +709,7 @@ apps.command("cut <version>").description("Snapshot the working draft into an im
687
709
  }));
688
710
  });
689
711
  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) => {
690
- const { runAppsDiscard } = await import("./apps-discard-y3_IwcbQ.js");
712
+ const { runAppsDiscard } = await import("./apps-discard-BoY4zMJw.js");
691
713
  process.exit(await runAppsDiscard({
692
714
  slug: opts.slug,
693
715
  cwd: opts.cwd,
@@ -697,7 +719,7 @@ apps.command("discard").description("Drop the mutable working draft (leaves cut
697
719
  }));
698
720
  });
699
721
  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) => {
700
- const { runAppsRelease } = await import("./apps-release-BLH9XSxB.js");
722
+ const { runAppsRelease } = await import("./apps-release-DJFG4BV3.js");
701
723
  process.exit(await runAppsRelease({
702
724
  version,
703
725
  slug: opts.slug,
@@ -709,7 +731,7 @@ apps.command("release <version>").description("Freeze & publish an existing remo
709
731
  }));
710
732
  });
711
733
  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) => {
712
- const { runAppsSyncMeta } = await import("./apps-sync-meta-D9eKMMUp.js");
734
+ const { runAppsSyncMeta } = await import("./apps-sync-meta-CQQC_Heb.js");
713
735
  process.exit(await runAppsSyncMeta({
714
736
  cwd: opts.cwd,
715
737
  manifest: opts.manifest,
@@ -719,7 +741,7 @@ apps.command("sync-meta").description("Push mutable store metadata (name/tagline
719
741
  }));
720
742
  });
721
743
  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) => {
722
- const { runAppsSubmitReview } = await import("./apps-submit-review-DLwCxeAs.js");
744
+ const { runAppsSubmitReview } = await import("./apps-submit-review-BVmZlhmB.js");
723
745
  process.exit(await runAppsSubmitReview({
724
746
  slug,
725
747
  cwd: opts.cwd,
@@ -728,7 +750,7 @@ apps.command("submit-review [slug]").description("Move an app into review (DRAFT
728
750
  }));
729
751
  });
730
752
  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) => {
731
- const { runAppsStatus } = await import("./apps-status-DQ9RvlME.js");
753
+ const { runAppsStatus } = await import("./apps-status-F6aVlzDW.js");
732
754
  process.exit(await runAppsStatus({
733
755
  slug,
734
756
  account: opts.account,
@@ -736,7 +758,7 @@ apps.command("status <slug>").description("Show server-known state for one Anna
736
758
  }));
737
759
  });
738
760
  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) => {
739
- const { runAppsVersions } = await import("./apps-versions-2Tmk0nsx.js");
761
+ const { runAppsVersions } = await import("./apps-versions-BIKsJzIT.js");
740
762
  process.exit(await runAppsVersions({
741
763
  slug,
742
764
  account: opts.account,
@@ -744,7 +766,7 @@ apps.command("versions <slug>").description("List all server versions of one Ann
744
766
  }));
745
767
  });
746
768
  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) => {
747
- const { runAppsGrants } = await import("./apps-grants-BGWlpee0.js");
769
+ const { runAppsGrants } = await import("./apps-grants-DgvymPBT.js");
748
770
  process.exit(await runAppsGrants({
749
771
  slug,
750
772
  account: opts.account,
@@ -752,7 +774,7 @@ apps.command("grants <slug>").description("Show currently granted scopes/quota f
752
774
  }));
753
775
  });
754
776
  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) => {
755
- const { runAppsUnpublish } = await import("./apps-destructive-DSTrcFUP.js");
777
+ const { runAppsUnpublish } = await import("./apps-destructive-DWF4eTHn.js");
756
778
  process.exit(await runAppsUnpublish({
757
779
  slug,
758
780
  yes: opts.yes,
@@ -762,7 +784,7 @@ apps.command("unpublish <slug>").description("Flip a PUBLISHED app back to APPRO
762
784
  }));
763
785
  });
764
786
  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) => {
765
- const { runAppsArchive } = await import("./apps-destructive-DSTrcFUP.js");
787
+ const { runAppsArchive } = await import("./apps-destructive-DWF4eTHn.js");
766
788
  process.exit(await runAppsArchive({
767
789
  slug,
768
790
  yes: opts.yes,
@@ -772,7 +794,7 @@ apps.command("archive <slug>").description("Archive an Anna App (hides it from e
772
794
  }));
773
795
  });
774
796
  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) => {
775
- const { runAppsUnarchive } = await import("./apps-destructive-DSTrcFUP.js");
797
+ const { runAppsUnarchive } = await import("./apps-destructive-DWF4eTHn.js");
776
798
  process.exit(await runAppsUnarchive({
777
799
  slug,
778
800
  yes: opts.yes,
@@ -781,7 +803,7 @@ apps.command("unarchive <slug>").description("Restore an archived Anna App back
781
803
  }));
782
804
  });
783
805
  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) => {
784
- const { runAppsDelete } = await import("./apps-destructive-DSTrcFUP.js");
806
+ const { runAppsDelete } = await import("./apps-destructive-DWF4eTHn.js");
785
807
  process.exit(await runAppsDelete({
786
808
  slug,
787
809
  yes: opts.yes,
@@ -791,14 +813,14 @@ apps.command("delete <slug>").description("Hard-delete an Anna App (refused by s
791
813
  }));
792
814
  });
793
815
  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) => {
794
- const { runExecutaList } = await import("./executa-reads-CQ6S8gHY.js");
816
+ const { runExecutaList } = await import("./executa-reads-CjGZq1yP.js");
795
817
  process.exit(await runExecutaList({
796
818
  account: opts.account,
797
819
  json: opts.json
798
820
  }));
799
821
  });
800
822
  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) => {
801
- const { runExecutaStatus } = await import("./executa-reads-CQ6S8gHY.js");
823
+ const { runExecutaStatus } = await import("./executa-reads-CjGZq1yP.js");
802
824
  process.exit(await runExecutaStatus({
803
825
  ref,
804
826
  account: opts.account,
@@ -806,7 +828,7 @@ executa.command("status <ref>").description("Show server-known state for one Exe
806
828
  }));
807
829
  });
808
830
  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) => {
809
- const { runExecutaVersions } = await import("./executa-reads-CQ6S8gHY.js");
831
+ const { runExecutaVersions } = await import("./executa-reads-CjGZq1yP.js");
810
832
  process.exit(await runExecutaVersions({
811
833
  ref,
812
834
  account: opts.account,
@@ -822,7 +844,7 @@ executa.command("publish").description("Mint or update an Executa (executa.json
822
844
  console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
823
845
  process.exit(2);
824
846
  }
825
- const { runExecutaPublish } = await import("./executa-publish-B88_9gbp.js");
847
+ const { runExecutaPublish } = await import("./executa-publish-IXWSwva0.js");
826
848
  process.exit(await runExecutaPublish({
827
849
  cwd: opts.cwd,
828
850
  manifest: opts.manifest,
@@ -835,7 +857,7 @@ executa.command("publish").description("Mint or update an Executa (executa.json
835
857
  }));
836
858
  });
837
859
  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) => {
838
- const { runExecutaUnpublish } = await import("./executa-destructive-COQE4Xqi.js");
860
+ const { runExecutaUnpublish } = await import("./executa-destructive-PL2ooHpZ.js");
839
861
  process.exit(await runExecutaUnpublish({
840
862
  slug,
841
863
  yes: opts.yes,
@@ -845,7 +867,7 @@ executa.command("unpublish <slug>").description("Flip an Executa's visibility ba
845
867
  }));
846
868
  });
847
869
  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) => {
848
- const { runExecutaYank } = await import("./executa-destructive-COQE4Xqi.js");
870
+ const { runExecutaYank } = await import("./executa-destructive-PL2ooHpZ.js");
849
871
  process.exit(await runExecutaYank({
850
872
  ref,
851
873
  yes: opts.yes,
@@ -855,7 +877,7 @@ executa.command("yank <ref>").description("Hard-delete one Executa version (<slu
855
877
  }));
856
878
  });
857
879
  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) => {
858
- const { runExecutaDelete } = await import("./executa-destructive-COQE4Xqi.js");
880
+ const { runExecutaDelete } = await import("./executa-destructive-PL2ooHpZ.js");
859
881
  process.exit(await runExecutaDelete({
860
882
  slug,
861
883
  yes: opts.yes,
@@ -867,7 +889,7 @@ executa.command("delete <slug>").description("Hard-delete an Executa").option("-
867
889
  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) => {
868
890
  const { resolve: resolve$1 } = await import("node:path");
869
891
  const { existsSync: existsSync$1 } = await import("node:fs");
870
- const { executaCachePath, invalidateExecutaCache } = await import("./executa-cache-WBkCLic7.js");
892
+ const { executaCachePath, invalidateExecutaCache } = await import("./executa-cache-Kx3rfQD-.js");
871
893
  const cwd = resolve$1(opts.cwd ?? process.cwd());
872
894
  const p = executaCachePath(cwd);
873
895
  if (!existsSync$1(p)) {
@@ -880,7 +902,7 @@ executa.command("cache-clear").description("Delete the local `.anna/executa.json
880
902
  });
881
903
  const token = program.command("token").description("Manage developer PATs (list / revoke / scopes)");
882
904
  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) => {
883
- const { runTokenList } = await import("./token-B9JUPelx.js");
905
+ const { runTokenList } = await import("./token-Cg7BZGp6.js");
884
906
  process.exit(await runTokenList({
885
907
  includeRevoked: opts.includeRevoked,
886
908
  account: opts.account,
@@ -893,7 +915,7 @@ token.command("revoke <id>").description("Revoke one of the caller's PATs by id"
893
915
  console.error(`✗ token id must be a positive integer (got: ${id})`);
894
916
  process.exit(2);
895
917
  }
896
- const { runTokenRevoke } = await import("./token-B9JUPelx.js");
918
+ const { runTokenRevoke } = await import("./token-Cg7BZGp6.js");
897
919
  process.exit(await runTokenRevoke({
898
920
  id: idNum,
899
921
  account: opts.account,
@@ -901,7 +923,7 @@ token.command("revoke <id>").description("Revoke one of the caller's PATs by id"
901
923
  }));
902
924
  });
903
925
  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) => {
904
- const { runTokenScopes } = await import("./token-B9JUPelx.js");
926
+ const { runTokenScopes } = await import("./token-Cg7BZGp6.js");
905
927
  process.exit(await runTokenScopes({
906
928
  account: opts.account,
907
929
  json: opts.json
@@ -916,7 +938,7 @@ program.command("publish").description("Auto-detect cwd and publish (apps publis
916
938
  console.error(`✗ --bump must be patch|minor|major (got: ${opts.bump})`);
917
939
  process.exit(2);
918
940
  }
919
- const { runTopLevelPublish } = await import("./publish-C1wcf-qI.js");
941
+ const { runTopLevelPublish } = await import("./publish-BYWuujP3.js");
920
942
  process.exit(await runTopLevelPublish({
921
943
  cwd: opts.cwd,
922
944
  bump: opts.bump,
@@ -1,4 +1,4 @@
1
- import { CliError } from "./client-Dn9zThOd.js";
1
+ import { CliError } from "./client-D-_z1ALk.js";
2
2
  import { yellow } from "kleur/colors";
3
3
  import { createInterface } from "node:readline/promises";
4
4
 
@@ -1,3 +1,4 @@
1
+ import { findMatrixNexusRoot, nexusSchemaDir } from "./nexus-root-BlPwOusj.js";
1
2
  import { dirname, isAbsolute, resolve } from "node:path";
2
3
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
3
4
  import { bold, cyan, dim, green, red, yellow } from "kleur/colors";
@@ -31,6 +32,11 @@ async function runDev(opts) {
31
32
  }
32
33
  const matrixNexusRoot = await resolveMatrixNexusRoot(opts.matrixNexusRoot, cwd);
33
34
  const mode = matrixNexusRoot ? "nexus-source" : "uvx";
35
+ let schemaSource = null;
36
+ if (matrixNexusRoot && !process.env.ANNA_APP_SCHEMA_DIR) {
37
+ schemaSource = nexusSchemaDir(matrixNexusRoot);
38
+ if (schemaSource) process.env.ANNA_APP_SCHEMA_DIR = schemaSource;
39
+ }
34
40
  const storageMode = opts.storageMode === "aps" ? "aps" : "legacy";
35
41
  if (opts.storageMode && opts.storageMode !== "legacy" && opts.storageMode !== "aps") {
36
42
  console.error(red(`✗ --storage must be "legacy" or "aps", got "${opts.storageMode}"`));
@@ -43,8 +49,8 @@ async function runDev(opts) {
43
49
  }
44
50
  process.env.ANNA_APP_RUNTIME_STORAGE_MODE = "aps";
45
51
  }
46
- const { PythonBridge, PINNED_RUNTIME_VERSION } = await import("./bridge-Id8K8gr-.js");
47
- const { HarnessServer } = await import("./server-_IG8Igje.js");
52
+ const { PythonBridge, PINNED_RUNTIME_VERSION } = await import("./bridge-hzqNFm9-.js");
53
+ const { HarnessServer } = await import("./server-Cp7mYV9t.js");
48
54
  const bridge = new PythonBridge({
49
55
  mode,
50
56
  matrixNexusRoot: matrixNexusRoot ?? void 0,
@@ -56,7 +62,12 @@ async function runDev(opts) {
56
62
  if (mode === "nexus-source") {
57
63
  console.log(` matrix-nexus root ${dim(matrixNexusRoot)}`);
58
64
  console.log(` runtime ${dim("nexus-source (uv run)")}`);
59
- } else console.log(` runtime ${dim(`uvx anna-app-runtime-local@${PINNED_RUNTIME_VERSION}`)}`);
65
+ console.log(` browser sdk ${dim("in-tree packages/anna-app-runtime/dist")}`);
66
+ console.log(` schema ${dim(schemaSource ? "in-tree packages/anna-app-schema" : process.env.ANNA_APP_SCHEMA_DIR ? `override ${process.env.ANNA_APP_SCHEMA_DIR}` : "npm @anna-ai/app-schema")}`);
67
+ } else {
68
+ console.log(` runtime ${dim(`uvx anna-app-runtime-local@${PINNED_RUNTIME_VERSION}`)}`);
69
+ console.log(` browser sdk ${dim("npm @anna-ai/app-runtime")}`);
70
+ }
60
71
  console.log(` spawning python bridge…`);
61
72
  try {
62
73
  await bridge.start();
@@ -79,7 +90,7 @@ async function runDev(opts) {
79
90
  if (executas.length > 0) console.log(` executas ${dim(executas.map((e) => e.tool_id).join(", "))}`);
80
91
  const bundledResolved = resolveBundledHandles(dirname(manifestPath), executas);
81
92
  if (Object.keys(bundledResolved).length > 0) {
82
- const { substituteBundledRefs, writeBundleToolIdSidecar } = await import("./bundled-executas-CNaV2C_O.js");
93
+ const { substituteBundledRefs, writeBundleToolIdSidecar } = await import("./bundled-executas-DeBhDjd8.js");
83
94
  try {
84
95
  manifest = substituteBundledRefs(manifest, bundledResolved);
85
96
  writeBundleToolIdSidecar(bundleDir, bundledResolved);
@@ -149,8 +160,8 @@ async function runDev(opts) {
149
160
  * registered `appSlug`.
150
161
  */
151
162
  async function resolveRealLlm(args) {
152
- const { getAccount } = await import("./credentials-DklPMD22.js");
153
- const { ensureDevAppRegistered } = await import("./dev-app-cache-D-r6ZpEk.js");
163
+ const { getAccount } = await import("./credentials-Chkoidh5.js");
164
+ const { ensureDevAppRegistered } = await import("./dev-app-cache-TSjL4D4n.js");
154
165
  const acc = getAccount(args.account);
155
166
  if (!acc) {
156
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.)"));
@@ -179,7 +190,7 @@ async function resolveRealLlm(args) {
179
190
  account: args.account,
180
191
  appSlug: entry.slug,
181
192
  onAppSlugNotFound: async () => {
182
- const { invalidateDevAppCache } = await import("./dev-app-cache-D-r6ZpEk.js");
193
+ const { invalidateDevAppCache } = await import("./dev-app-cache-TSjL4D4n.js");
183
194
  invalidateDevAppCache(args.cwd);
184
195
  const fresh = getAccount(args.account);
185
196
  if (!fresh) throw new Error("PAT not found while re-registering dev app — run `anna-app login` again");
@@ -486,21 +497,7 @@ function parseExecutaSpec(spec, cwd) {
486
497
  };
487
498
  }
488
499
  async function resolveMatrixNexusRoot(explicit, cwd) {
489
- const candidates = [explicit, process.env.ANNA_NEXUS_ROOT];
490
- let dir = cwd;
491
- while (true) {
492
- candidates.push(dir);
493
- const parent = dirname(dir);
494
- if (parent === dir) break;
495
- dir = parent;
496
- }
497
- candidates.push(resolve(cwd, "..", "matrix-nexus"));
498
- for (const c of candidates) {
499
- if (!c) continue;
500
- const abs = isAbsolute(c) ? c : resolve(cwd, c);
501
- if (existsSync(resolve(abs, "packages/anna-app-runtime-local/pyproject.toml"))) return abs;
502
- }
503
- return null;
500
+ return findMatrixNexusRoot(explicit, cwd);
504
501
  }
505
502
 
506
503
  //#endregion
@@ -0,0 +1,4 @@
1
+ import "./nexus-root-BlPwOusj.js";
2
+ import { parseExecutaSpec, runDev } from "./dev-3okZmzNM.js";
3
+
4
+ export { parseExecutaSpec, runDev };
@@ -1,5 +1,6 @@
1
- import { PINNED_RUNTIME_VERSION } from "./bridge-BuklhzeE.js";
2
- import { dirname, isAbsolute, resolve } from "node:path";
1
+ import { findMatrixNexusRoot, nexusSchemaDir } from "./nexus-root-BlPwOusj.js";
2
+ import { PINNED_RUNTIME_VERSION } from "./bridge-DxBd0Fl9.js";
3
+ import { resolve } from "node:path";
3
4
  import { existsSync, statSync } from "node:fs";
4
5
  import { spawnSync } from "node:child_process";
5
6
  import { bold, dim, green, red, yellow } from "kleur/colors";
@@ -26,9 +27,13 @@ async function runDoctor(opts) {
26
27
  console.log(dim(` first 'anna-app dev' will install via 'uvx anna-app-runtime-local@${PINNED_RUNTIME_VERSION}' (one-time)`));
27
28
  }
28
29
  }
29
- const nexus = await resolveNexusRoot(opts.matrixNexusRoot, process.cwd());
30
- if (nexus) console.log(` ${green("✓")} nexus ${dim(nexus)} ${dim("(contributor mode)")}`);
31
- else console.log(` ${yellow("·")} nexus ${dim("not found")} ${dim("(uvx mode will be used)")}`);
30
+ const nexus = findMatrixNexusRoot(opts.matrixNexusRoot, process.cwd());
31
+ if (nexus) {
32
+ console.log(` ${green("")} nexus ${dim(nexus)} ${dim("(contributor mode)")}`);
33
+ const schemaDir = nexusSchemaDir(nexus);
34
+ if (schemaDir) console.log(` ${green("✓")} schema ${dim(schemaDir)} ${dim("(in-tree; used by dev/validate)")}`);
35
+ else console.log(` ${yellow("·")} schema ${yellow("in-tree packages/anna-app-schema not found")} ${dim("(npm bundle will be used)")}`);
36
+ } else console.log(` ${yellow("·")} nexus ${dim("not found")} ${dim("(uvx mode will be used)")}`);
32
37
  const keyPath = resolve(homedir(), ".anna-app", "dev.key");
33
38
  if (!existsSync(keyPath)) console.log(` ${yellow("·")} key ${dim(keyPath)} ${yellow("(missing — will be auto-created on first run)")}`);
34
39
  else {
@@ -47,23 +52,6 @@ async function runDoctor(opts) {
47
52
  console.log(red(`\n ${failed} required check(s) failed`));
48
53
  return 1;
49
54
  }
50
- async function resolveNexusRoot(explicit, cwd) {
51
- const candidates = [explicit, process.env.ANNA_NEXUS_ROOT];
52
- let dir = cwd;
53
- while (true) {
54
- candidates.push(dir);
55
- const parent = dirname(dir);
56
- if (parent === dir) break;
57
- dir = parent;
58
- }
59
- candidates.push(resolve(cwd, "..", "matrix-nexus"));
60
- for (const c of candidates) {
61
- if (!c) continue;
62
- const abs = isAbsolute(c) ? c : resolve(cwd, c);
63
- if (existsSync(resolve(abs, "packages/anna-app-runtime-local/pyproject.toml"))) return abs;
64
- }
65
- return null;
66
- }
67
55
 
68
56
  //#endregion
69
57
  export { runDoctor };
@@ -1,4 +1,4 @@
1
1
  import "./credentials-BTv2IfUZ.js";
2
- import { executaCacheMatches, executaCachePath, invalidateExecutaCache, mintIdempotencyKey, readExecutaIdentity, writeExecutaIdentity } from "./executa-cache-BFoUtb4J.js";
2
+ import { executaCacheMatches, executaCachePath, invalidateExecutaCache, mintIdempotencyKey, readExecutaIdentity, writeExecutaIdentity } from "./executa-cache-CXiEgFZY.js";
3
3
 
4
4
  export { executaCachePath, invalidateExecutaCache };
@@ -1,8 +1,8 @@
1
1
  import "./credentials-BTv2IfUZ.js";
2
- import { CliError } from "./client-Dn9zThOd.js";
3
- import { deleteMyTool, listMyTools, listToolVersions, unpublishTool, yankToolVersion } from "./executas-Cep6KEo0.js";
4
- import { resolveClient, withErrorHandling } from "./_lifecycle-shared-sbea9HtH.js";
5
- import { ensureDestructiveAllowed } from "./confirm-DxHkk9Wn.js";
2
+ import { CliError } from "./client-D-_z1ALk.js";
3
+ import { deleteMyTool, listMyTools, listToolVersions, unpublishTool, yankToolVersion } from "./executas-CK3er6f9.js";
4
+ import { resolveClient, withErrorHandling } from "./_lifecycle-shared-BpSOfVCP.js";
5
+ import { ensureDestructiveAllowed } from "./confirm-h_qMrx0I.js";
6
6
  import { dim, green, yellow } from "kleur/colors";
7
7
 
8
8
  //#region src/commands/executa-destructive.ts