@anna-ai/cli 0.1.23 → 0.1.27

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 (64) hide show
  1. package/dist/{_lifecycle-shared-sbea9HtH.js → _lifecycle-shared-BpSOfVCP.js} +1 -1
  2. package/dist/{agent-DyXJhaZ0.js → agent-CaZVCPs6.js} +1 -1
  3. package/dist/{app-bundle-upload-Cd4ci4rB.js → app-bundle-upload-BhAYo6yj.js} +3 -3
  4. package/dist/{apps-B57i8xeb.js → apps-3VcdHIBK.js} +3 -3
  5. package/dist/{apps-cut-BG6Ib3x4.js → apps-cut-DKl5I9bf.js} +13 -12
  6. package/dist/{apps-destructive-DQIFqYE2.js → apps-destructive-DWF4eTHn.js} +4 -4
  7. package/dist/{apps-discard-BveXHAgF.js → apps-discard-zg1nu2HN.js} +13 -12
  8. package/dist/{apps-grants-D3i6GxX_.js → apps-grants-DgvymPBT.js} +3 -3
  9. package/dist/{apps-publish-U_Y7svJw.js → apps-publish-Dgi4lBlu.js} +8 -8
  10. package/dist/apps-publish-Do7M5je3.js +14 -0
  11. package/dist/{apps-push-x5reIQHx.js → apps-push-C1-QDzF8.js} +14 -13
  12. package/dist/{apps-release-ByIgz6lx.js → apps-release-DJFG4BV3.js} +5 -5
  13. package/dist/{apps-status-BYo97Nh5.js → apps-status-F6aVlzDW.js} +3 -3
  14. package/dist/{apps-submit-review-D-cPtZtc.js → apps-submit-review-BVmZlhmB.js} +4 -4
  15. package/dist/{apps-sync-meta-CTHwGlzI.js → apps-sync-meta-CQQC_Heb.js} +5 -5
  16. package/dist/{apps-versions-Ca-AAMLL.js → apps-versions-BIKsJzIT.js} +3 -3
  17. package/dist/bridge-6GIQG63S.js +3 -0
  18. package/dist/{bridge-CBew_Ytl.js → bridge-DAY7bsje.js} +1 -1
  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 +51 -46
  22. package/dist/{confirm-C-4haiIg.js → confirm-h_qMrx0I.js} +1 -1
  23. package/dist/{dev-CyFATq6R.js → dev-DGTtVCNj.js} +19 -22
  24. package/dist/dev-DVCIv8mJ.js +4 -0
  25. package/dist/{doctor-oqYeEjLv.js → doctor-DCsBgyRg.js} +10 -22
  26. package/dist/{executa-cache-WBkCLic7.js → executa-cache-Kx3rfQD-.js} +1 -1
  27. package/dist/{executa-destructive-Dpo58lxI.js → executa-destructive-PL2ooHpZ.js} +4 -4
  28. package/dist/{executa-dev-DFp1ckAn.js → executa-dev-BOo6xpVy.js} +10 -9
  29. package/dist/{executa-install-DnBG8UJA.js → executa-install-BGirXLX5.js} +2 -2
  30. package/dist/executa-install-Cuq0Y_H4.js +7 -0
  31. package/dist/{executa-publish-BKFq6Hz9.js → executa-publish-CkPAB34b.js} +5 -5
  32. package/dist/executa-publish-IXWSwva0.js +9 -0
  33. package/dist/{executa-reads-cd-8ZRjI.js → executa-reads-CjGZq1yP.js} +3 -3
  34. package/dist/{manifest-hXWnNFHE.js → manifest-Bljz8Y6T.js} +1 -1
  35. package/dist/nexus-root-BlPwOusj.js +49 -0
  36. package/dist/{publish-R3JAl9Hm.js → publish-BYWuujP3.js} +11 -11
  37. package/dist/{server-BzfmXVJD.js → server-D7zabdJY.js} +211 -41
  38. package/dist/{storage-BCj754in.js → storage-CKTmE87u.js} +1 -1
  39. package/dist/{token-BGjbb2aU.js → token-Cg7BZGp6.js} +2 -2
  40. package/dist/{working-orchestration-CIpQ_JMY.js → working-orchestration-Dh1gCwGg.js} +7 -7
  41. package/package.json +5 -4
  42. package/dist/apps-publish-D403z305.js +0 -14
  43. package/dist/bridge-DZmZIWG0.js +0 -3
  44. package/dist/dev-DdjwQzJ2.js +0 -3
  45. package/dist/executa-install-viq3kiV7.js +0 -6
  46. package/dist/executa-publish-DaYvxbbW.js +0 -9
  47. /package/dist/{app-cache-TcmbIIuL.js → app-cache-Bl7cE5fm.js} +0 -0
  48. /package/dist/{apps-B1Nd8l_t.js → apps-CCdtLmxQ.js} +0 -0
  49. /package/dist/{client-Dn9zThOd.js → client-D-_z1ALk.js} +0 -0
  50. /package/dist/{credentials-DklPMD22.js → credentials-Chkoidh5.js} +0 -0
  51. /package/dist/{dev-account-CD6hTr7M.js → dev-account-CGo8k9_2.js} +0 -0
  52. /package/dist/{dev-app-cache-DMQLQ93-.js → dev-app-cache-TSjL4D4n.js} +0 -0
  53. /package/dist/{executa-cache-BFoUtb4J.js → executa-cache-CXiEgFZY.js} +0 -0
  54. /package/dist/{executa-init-By0kMPaF.js → executa-init-DXea7yRN.js} +0 -0
  55. /package/dist/{executa-register-BX29VfcD.js → executa-register-BUiPzPIU.js} +0 -0
  56. /package/dist/{executas-Cep6KEo0.js → executas-CK3er6f9.js} +0 -0
  57. /package/dist/{fixture-C9VLX3os.js → fixture-BvP5umlN.js} +0 -0
  58. /package/dist/{host_upload-wKM0jQoL.js → host_upload-BXeHTgJs.js} +0 -0
  59. /package/dist/{image-CBSlNb-9.js → image-CSEXEfD-.js} +0 -0
  60. /package/dist/{login-D4cU2Jcp.js → login-BGZjMAlh.js} +0 -0
  61. /package/dist/{logout-DOpL3vXX.js → logout-mh2_QlyM.js} +0 -0
  62. /package/dist/{runner-4-ugGH5e.js → runner-BuYbm-ex.js} +0 -0
  63. /package/dist/{sampling-finZ8aNJ.js → sampling-BcML4teS.js} +0 -0
  64. /package/dist/{whoami-DarmijoA.js → whoami-l_kIkfbI.js} +0 -0
@@ -1,4 +1,5 @@
1
- import { parseExecutaSpec } from "./dev-CyFATq6R.js";
1
+ import "./nexus-root-BlPwOusj.js";
2
+ import { parseExecutaSpec } from "./dev-DGTtVCNj.js";
2
3
  import { isAbsolute, resolve } from "node:path";
3
4
  import { existsSync } from "node:fs";
4
5
  import { bold, cyan, dim, green, red, yellow } from "kleur/colors";
@@ -33,8 +34,8 @@ async function runExecutaDev(opts) {
33
34
  }
34
35
  const oneShot = !!(opts.describe || opts.health || opts.invoke);
35
36
  const quiet = oneShot && (opts.json ?? false);
36
- const { getAccount } = await import("./credentials-DklPMD22.js");
37
- const { ensureDevExecutaRegistered } = await import("./dev-app-cache-DMQLQ93-.js");
37
+ const { getAccount } = await import("./credentials-Chkoidh5.js");
38
+ const { ensureDevExecutaRegistered } = await import("./dev-app-cache-TSjL4D4n.js");
38
39
  const needsRealMint = !opts.noSampling && !opts.mockSampling || !opts.noAgent && !opts.mockAgent || !opts.noImage && !opts.mockImage || !opts.noUpload && !opts.mockUpload || opts.storage === "real";
39
40
  let effectiveAppSlug = opts.appSlug;
40
41
  let autoRegistered = false;
@@ -56,7 +57,7 @@ async function runExecutaDev(opts) {
56
57
  }
57
58
  }
58
59
  }
59
- const { SamplingBridge } = await import("./sampling-finZ8aNJ.js");
60
+ const { SamplingBridge } = await import("./sampling-BcML4teS.js");
60
61
  const sampling = opts.noSampling ? new SamplingBridge({ mode: "off" }) : opts.mockSampling ? new SamplingBridge({
61
62
  mode: "mock",
62
63
  mockFile: opts.mockSampling
@@ -65,7 +66,7 @@ async function runExecutaDev(opts) {
65
66
  account: opts.samplingAccount,
66
67
  appSlug: effectiveAppSlug
67
68
  }) : new SamplingBridge({ mode: "off" });
68
- const { AgentBridge } = await import("./agent-DyXJhaZ0.js");
69
+ const { AgentBridge } = await import("./agent-CaZVCPs6.js");
69
70
  const agent = opts.noAgent ? new AgentBridge({ mode: "off" }) : opts.mockAgent ? new AgentBridge({
70
71
  mode: "mock",
71
72
  mockFile: opts.mockAgent
@@ -74,7 +75,7 @@ async function runExecutaDev(opts) {
74
75
  account: opts.agentAccount ?? opts.samplingAccount,
75
76
  appSlug: effectiveAppSlug
76
77
  }) : new AgentBridge({ mode: "off" });
77
- const { StorageBridge } = await import("./storage-BCj754in.js");
78
+ const { StorageBridge } = await import("./storage-CKTmE87u.js");
78
79
  const storageMode = opts.storage ?? (opts.mockStorage ? "mock" : "memory");
79
80
  const storage = new StorageBridge({
80
81
  mode: storageMode,
@@ -84,8 +85,8 @@ async function runExecutaDev(opts) {
84
85
  scopes: opts.storageScopes ? opts.storageScopes.split(",").map((s) => s.trim()).filter(Boolean) : void 0,
85
86
  pluginName: parsed.tool_id
86
87
  });
87
- const { ExecutaRunner } = await import("./runner-4-ugGH5e.js");
88
- const { ImageBridge } = await import("./image-CBSlNb-9.js");
88
+ const { ExecutaRunner } = await import("./runner-BuYbm-ex.js");
89
+ const { ImageBridge } = await import("./image-CSEXEfD-.js");
89
90
  const image = opts.noImage ? new ImageBridge({ mode: "off" }) : opts.mockImage ? new ImageBridge({
90
91
  mode: "mock",
91
92
  mockFile: opts.mockImage
@@ -94,7 +95,7 @@ async function runExecutaDev(opts) {
94
95
  account: opts.imageAccount ?? opts.samplingAccount,
95
96
  appSlug: effectiveAppSlug
96
97
  }) : new ImageBridge({ mode: "off" });
97
- const { HostUploadBridge } = await import("./host_upload-wKM0jQoL.js");
98
+ const { HostUploadBridge } = await import("./host_upload-BXeHTgJs.js");
98
99
  const hostUpload = opts.noUpload ? new HostUploadBridge({ mode: "off" }) : opts.mockUpload ? new HostUploadBridge({
99
100
  mode: "mock",
100
101
  mockFile: opts.mockUpload
@@ -1,5 +1,5 @@
1
- import { readExecutaIdentity } from "./executa-cache-BFoUtb4J.js";
2
- import { parseExecutaSpec } from "./dev-CyFATq6R.js";
1
+ import { readExecutaIdentity } from "./executa-cache-CXiEgFZY.js";
2
+ import { parseExecutaSpec } from "./dev-DGTtVCNj.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-CXiEgFZY.js";
4
+ import "./dev-DGTtVCNj.js";
5
+ import { runExecutaInstall } from "./executa-install-BGirXLX5.js";
6
+
7
+ export { runExecutaInstall };
@@ -1,9 +1,9 @@
1
1
  import { canonicalHost } from "./credentials-BTv2IfUZ.js";
2
- import { CliError } from "./client-Dn9zThOd.js";
3
- import { commitDraft, createDraft, getMySkill, getMyTool, listToolVersions, publishToolVersion, setSkillVisibility, setToolVisibility, updateMySkill, updateMyTool } from "./executas-Cep6KEo0.js";
4
- import { executaCacheMatches, invalidateExecutaCache, mintIdempotencyKey, readExecutaIdentity, writeExecutaIdentity } from "./executa-cache-BFoUtb4J.js";
5
- import { loadExecutaManifest } from "./manifest-hXWnNFHE.js";
6
- import { resolveClient, withErrorHandling } from "./_lifecycle-shared-sbea9HtH.js";
2
+ import { CliError } from "./client-D-_z1ALk.js";
3
+ import { commitDraft, createDraft, getMySkill, getMyTool, listToolVersions, publishToolVersion, setSkillVisibility, setToolVisibility, updateMySkill, updateMyTool } from "./executas-CK3er6f9.js";
4
+ import { executaCacheMatches, invalidateExecutaCache, mintIdempotencyKey, readExecutaIdentity, writeExecutaIdentity } from "./executa-cache-CXiEgFZY.js";
5
+ import { loadExecutaManifest } from "./manifest-Bljz8Y6T.js";
6
+ import { resolveClient, withErrorHandling } from "./_lifecycle-shared-BpSOfVCP.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";
@@ -0,0 +1,9 @@
1
+ import "./credentials-BTv2IfUZ.js";
2
+ import "./client-D-_z1ALk.js";
3
+ import "./executas-CK3er6f9.js";
4
+ import "./executa-cache-CXiEgFZY.js";
5
+ import { runExecutaPublish } from "./executa-publish-CkPAB34b.js";
6
+ import "./manifest-Bljz8Y6T.js";
7
+ import "./_lifecycle-shared-BpSOfVCP.js";
8
+
9
+ export { runExecutaPublish };
@@ -1,7 +1,7 @@
1
1
  import "./credentials-BTv2IfUZ.js";
2
- import { CliError } from "./client-Dn9zThOd.js";
3
- import { getMyTool, listMyTools, listToolVersions } from "./executas-Cep6KEo0.js";
4
- import { resolveClient, withErrorHandling } from "./_lifecycle-shared-sbea9HtH.js";
2
+ import { CliError } from "./client-D-_z1ALk.js";
3
+ import { getMyTool, listMyTools, listToolVersions } from "./executas-CK3er6f9.js";
4
+ import { resolveClient, withErrorHandling } from "./_lifecycle-shared-BpSOfVCP.js";
5
5
  import { bold, cyan, dim, green } from "kleur/colors";
6
6
 
7
7
  //#region src/commands/executa-reads.ts
@@ -1,4 +1,4 @@
1
- import { CliError } from "./client-Dn9zThOd.js";
1
+ import { CliError } from "./client-D-_z1ALk.js";
2
2
  import { resolve } from "node:path";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
 
@@ -0,0 +1,49 @@
1
+ import { dirname, isAbsolute, resolve } from "node:path";
2
+ import { existsSync } from "node:fs";
3
+
4
+ //#region src/nexus-root.ts
5
+ /**
6
+ * Resolve an absolute matrix-nexus root, or null if none is found.
7
+ *
8
+ * Search order (first hit wins):
9
+ * 1. `explicit` (the `--matrix-nexus-root` flag).
10
+ * 2. `$ANNA_NEXUS_ROOT`.
11
+ * 3. Walk up from `cwd`.
12
+ * 4. Sibling `../matrix-nexus`.
13
+ *
14
+ * A candidate qualifies only if it contains
15
+ * `packages/anna-app-runtime-local/pyproject.toml` (the marker that also
16
+ * gates `nexus-source` runtime mode), so the three escape hatches can
17
+ * never disagree on what counts as "a matrix-nexus checkout".
18
+ */
19
+ function findMatrixNexusRoot(explicit, cwd) {
20
+ const candidates = [explicit, process.env.ANNA_NEXUS_ROOT];
21
+ let dir = cwd;
22
+ while (true) {
23
+ candidates.push(dir);
24
+ const parent = dirname(dir);
25
+ if (parent === dir) break;
26
+ dir = parent;
27
+ }
28
+ candidates.push(resolve(cwd, "..", "matrix-nexus"));
29
+ for (const c of candidates) {
30
+ if (!c) continue;
31
+ const abs = isAbsolute(c) ? c : resolve(cwd, c);
32
+ if (existsSync(resolve(abs, "packages/anna-app-runtime-local/pyproject.toml"))) return abs;
33
+ }
34
+ return null;
35
+ }
36
+ /**
37
+ * Locate the in-tree `@anna-ai/app-schema` bundle inside a matrix-nexus
38
+ * root, or null if it is absent / not built. The returned dir is suitable
39
+ * for `ANNA_APP_SCHEMA_DIR` / `loadSchemaBundle`'s override so contributors
40
+ * can `validate` against an UNPUBLISHED schema bump without waiting for the
41
+ * npm push — parity with the runtime/SDK nexus-source hatches.
42
+ */
43
+ function nexusSchemaDir(root) {
44
+ const dir = resolve(root, "packages", "anna-app-schema");
45
+ return existsSync(resolve(dir, "dispatcher_version.txt")) ? dir : null;
46
+ }
47
+
48
+ //#endregion
49
+ export { findMatrixNexusRoot, nexusSchemaDir };
@@ -1,15 +1,15 @@
1
1
  import "./credentials-BTv2IfUZ.js";
2
- import "./apps-B1Nd8l_t.js";
3
- import { CliError } from "./client-Dn9zThOd.js";
4
- import "./bundled-executas-BNOKw4kv.js";
5
- import "./executas-Cep6KEo0.js";
6
- import "./executa-cache-BFoUtb4J.js";
7
- import { runExecutaPublish } from "./executa-publish-BKFq6Hz9.js";
8
- import "./manifest-hXWnNFHE.js";
9
- import { withErrorHandling } from "./_lifecycle-shared-sbea9HtH.js";
10
- import "./app-cache-TcmbIIuL.js";
11
- import "./app-bundle-upload-Cd4ci4rB.js";
12
- import { runAppsPublish } from "./apps-publish-U_Y7svJw.js";
2
+ import "./apps-CCdtLmxQ.js";
3
+ import { CliError } from "./client-D-_z1ALk.js";
4
+ import "./bundled-executas-B6b8gIfp.js";
5
+ import "./executas-CK3er6f9.js";
6
+ import "./executa-cache-CXiEgFZY.js";
7
+ import { runExecutaPublish } from "./executa-publish-CkPAB34b.js";
8
+ import "./manifest-Bljz8Y6T.js";
9
+ import { withErrorHandling } from "./_lifecycle-shared-BpSOfVCP.js";
10
+ import "./app-cache-Bl7cE5fm.js";
11
+ import "./app-bundle-upload-BhAYo6yj.js";
12
+ import { runAppsPublish } from "./apps-publish-Dgi4lBlu.js";
13
13
  import { resolve } from "node:path";
14
14
  import { existsSync } from "node:fs";
15
15
  import { red, yellow } from "kleur/colors";
@@ -1,5 +1,5 @@
1
1
  import { canonicalHost, getAccount } from "./credentials-BTv2IfUZ.js";
2
- import { BridgeRequestError } from "./bridge-CBew_Ytl.js";
2
+ import { BridgeRequestError } from "./bridge-DAY7bsje.js";
3
3
  import { dirname, join, normalize, resolve } from "node:path";
4
4
  import { createRequire } from "node:module";
5
5
  import { createReadStream, existsSync, readFileSync, statSync, watch } from "node:fs";
@@ -200,6 +200,80 @@ var LlmBridge = class {
200
200
  this.mintedAgent.set(ms.appSessionUuid, ms);
201
201
  return ms;
202
202
  }
203
+ /** Re-mint an agent session token by ``app_session_uuid`` via the dev
204
+ * ``/dev/session/refresh`` endpoint (PAT + uuid — NO stale token needed).
205
+ *
206
+ * This is the harness's token-free recovery path: even after the CLI
207
+ * process restarted (so ``mintedAgent`` is empty) or the previous token
208
+ * expired, the underlying ``AnnaAppSession`` row is still alive and the
209
+ * app remembers its ``app_session_uuid``. ``refresh`` slides the idle
210
+ * window and hands back a fresh short-lived token, fixing the forum
211
+ * report "uuid unusable after dev restart". Throws on 404/410 (the row
212
+ * is genuinely gone / revoked / idle-expired). */
213
+ async callRefresh(apsUuid) {
214
+ const acc = this.account();
215
+ const url = `${canonicalHost(acc.host)}/api/v1/anna-apps/dev/session/refresh`;
216
+ const res = await fetch(url, {
217
+ method: "POST",
218
+ headers: { "content-type": "application/json" },
219
+ body: JSON.stringify({
220
+ pat: acc.pat,
221
+ app_session_uuid: apsUuid
222
+ })
223
+ });
224
+ if (!res.ok) {
225
+ const text = await res.text().catch(() => "");
226
+ throw new Error(`session.refresh failed: HTTP ${res.status} ${text}`);
227
+ }
228
+ const payload = await res.json();
229
+ return {
230
+ token: payload.app_session_token,
231
+ expiresIn: payload.expires_in || 600,
232
+ submode: payload.submode ?? null
233
+ };
234
+ }
235
+ /** Revoke an agent session by uuid via ``/dev/session/revoke`` (PAT-auth).
236
+ *
237
+ * Token-free: works even when the session token is long expired (which
238
+ * used to make the session impossible to release → quota leak). */
239
+ async callRevoke(apsUuid) {
240
+ const acc = this.account();
241
+ const url = `${canonicalHost(acc.host)}/api/v1/anna-apps/dev/session/revoke`;
242
+ const res = await fetch(url, {
243
+ method: "POST",
244
+ headers: { "content-type": "application/json" },
245
+ body: JSON.stringify({
246
+ pat: acc.pat,
247
+ app_session_uuid: apsUuid
248
+ })
249
+ });
250
+ if (!res.ok) {
251
+ const text = await res.text().catch(() => "");
252
+ throw new Error(`session.revoke failed: HTTP ${res.status} ${text}`);
253
+ }
254
+ }
255
+ /** Return a live agent session token for ``apsUuid``, re-minting via
256
+ * ``/dev/session/refresh`` on cache-miss or near-expiry.
257
+ *
258
+ * Centralises the "is my token still good?" decision for every operation
259
+ * that needs an ``app_session_token`` (run / cancel / delete). On success
260
+ * the freshly-minted session is cached in ``mintedAgent`` so subsequent
261
+ * calls in the same process reuse it until the next near-expiry check. */
262
+ async ensureLiveToken(apsUuid) {
263
+ const now = Math.floor(Date.now() / 1e3);
264
+ const cached = this.mintedAgent.get(apsUuid);
265
+ if (cached && cached.expiresAt - 30 > now) return cached;
266
+ const refreshed = await this.callRefresh(apsUuid);
267
+ const ms = {
268
+ appSessionToken: refreshed.token,
269
+ appSessionUuid: apsUuid,
270
+ expiresAt: Math.floor(Date.now() / 1e3) + refreshed.expiresIn,
271
+ isAgent: true,
272
+ submode: refreshed.submode ?? cached?.submode ?? null
273
+ };
274
+ this.mintedAgent.set(apsUuid, ms);
275
+ return ms;
276
+ }
203
277
  /** Mint (or reuse) a storage_token for APS forwarding.
204
278
  *
205
279
  * Server-side ``/dev/storage/mint`` issues a JWT scoped to
@@ -394,14 +468,18 @@ var LlmBridge = class {
394
468
  }
395
469
  case "session.run": {
396
470
  const apsUuid = String(args.args.app_session_uuid ?? "");
397
- const ms = this.mintedAgent.get(apsUuid);
398
- if (!ms) return {
399
- ok: false,
400
- error: {
401
- code: "session_expired",
402
- message: "no cached session"
403
- }
404
- };
471
+ let ms;
472
+ try {
473
+ ms = await this.ensureLiveToken(apsUuid);
474
+ } catch (e) {
475
+ return {
476
+ ok: false,
477
+ error: {
478
+ code: "session_expired",
479
+ message: e.message || "session expired or revoked"
480
+ }
481
+ };
482
+ }
405
483
  const sid = `dev-${++this.streamCounter}`;
406
484
  this.pumpAgentRun({
407
485
  host: acc.host,
@@ -422,16 +500,42 @@ var LlmBridge = class {
422
500
  }
423
501
  };
424
502
  }
503
+ case "session.refresh": {
504
+ const apsUuid = String(args.args.app_session_uuid ?? "");
505
+ try {
506
+ const ms = await this.ensureLiveToken(apsUuid);
507
+ return {
508
+ ok: true,
509
+ result: {
510
+ app_session_uuid: ms.appSessionUuid,
511
+ expires_in: Math.max(0, ms.expiresAt - Math.floor(Date.now() / 1e3)),
512
+ submode: ms.submode
513
+ }
514
+ };
515
+ } catch (e) {
516
+ return {
517
+ ok: false,
518
+ error: {
519
+ code: "session_expired",
520
+ message: e.message || "session expired or revoked"
521
+ }
522
+ };
523
+ }
524
+ }
425
525
  case "session.cancel": {
426
526
  const apsUuid = String(args.args.app_session_uuid ?? "");
427
- const ms = this.mintedAgent.get(apsUuid);
428
- if (!ms) return {
429
- ok: false,
430
- error: {
431
- code: "session_expired",
432
- message: "no cached session"
433
- }
434
- };
527
+ let ms;
528
+ try {
529
+ ms = await this.ensureLiveToken(apsUuid);
530
+ } catch (e) {
531
+ return {
532
+ ok: false,
533
+ error: {
534
+ code: "session_expired",
535
+ message: e.message || "session expired or revoked"
536
+ }
537
+ };
538
+ }
435
539
  const out = await this.postJson(`${canonicalHost(acc.host)}/api/v1/copilot/app/agent/cancel`, ms.appSessionToken, args.args);
436
540
  return {
437
541
  ok: true,
@@ -445,33 +549,72 @@ var LlmBridge = class {
445
549
  message: "agent.session.history is not exposed over HTTP; available only via in-process store"
446
550
  }
447
551
  };
552
+ case "session.list": {
553
+ const includeExpired = Boolean(args.args?.include_expired);
554
+ const rawLimit = Number(args.args?.limit ?? 50);
555
+ const limit = Math.max(1, Math.min(100, Number.isFinite(rawLimit) ? rawLimit : 50));
556
+ if (this.opts.appSlug) try {
557
+ const acc2 = this.account();
558
+ const url = new URL(`${canonicalHost(acc2.host)}/api/v1/anna-apps/dev/sessions`);
559
+ url.searchParams.set("pat", acc2.pat);
560
+ url.searchParams.set("app_slug", this.opts.appSlug);
561
+ url.searchParams.set("include_expired", String(includeExpired));
562
+ url.searchParams.set("limit", String(limit));
563
+ const res = await fetch(url, { method: "GET" });
564
+ if (res.ok) {
565
+ const body = await res.json();
566
+ return {
567
+ ok: true,
568
+ result: { sessions: body.sessions ?? [] }
569
+ };
570
+ }
571
+ } catch {}
572
+ const now = Math.floor(Date.now() / 1e3);
573
+ const sessions = [...this.mintedAgent.values()].filter((ms) => includeExpired || ms.expiresAt > now).slice(0, limit).map((ms) => ({
574
+ app_session_uuid: ms.appSessionUuid,
575
+ kind: "agent",
576
+ submode: ms.submode,
577
+ fixed_client_id: null,
578
+ label: "anna-app dev",
579
+ created_at: null,
580
+ last_active_at: null,
581
+ expires_at: new Date(ms.expiresAt * 1e3).toISOString()
582
+ }));
583
+ return {
584
+ ok: true,
585
+ result: { sessions }
586
+ };
587
+ }
448
588
  case "session.delete": {
449
589
  const apsUuid = String(args.args.app_session_uuid ?? "");
450
- const ms = this.mintedAgent.get(apsUuid);
590
+ const cached = this.mintedAgent.get(apsUuid);
451
591
  this.mintedAgent.delete(apsUuid);
452
- if (!ms) return {
453
- ok: true,
454
- result: { deleted: true }
455
- };
456
- const url = `${canonicalHost(acc.host)}/api/v1/copilot/app/sessions/${encodeURIComponent(apsUuid)}`;
457
- const res = await fetch(url, {
458
- method: "DELETE",
459
- headers: { authorization: `Bearer ${ms.appSessionToken}` }
460
- });
461
- if (!res.ok) {
462
- const text = await res.text().catch(() => "");
592
+ if (cached && cached.expiresAt - 5 > Math.floor(Date.now() / 1e3)) {
593
+ const url = `${canonicalHost(acc.host)}/api/v1/copilot/app/sessions/${encodeURIComponent(apsUuid)}`;
594
+ const res = await fetch(url, {
595
+ method: "DELETE",
596
+ headers: { authorization: `Bearer ${cached.appSessionToken}` }
597
+ });
598
+ if (res.ok) return {
599
+ ok: true,
600
+ result: { deleted: true }
601
+ };
602
+ }
603
+ try {
604
+ await this.callRevoke(apsUuid);
605
+ return {
606
+ ok: true,
607
+ result: { deleted: true }
608
+ };
609
+ } catch (e) {
463
610
  return {
464
611
  ok: false,
465
612
  error: {
466
613
  code: "transport",
467
- message: `HTTP ${res.status}: ${text}`
614
+ message: e.message
468
615
  }
469
616
  };
470
617
  }
471
- return {
472
- ok: true,
473
- result: { deleted: true }
474
- };
475
618
  }
476
619
  }
477
620
  if (args.ns === "image" && (args.method === "generate" || args.method === "edit")) {
@@ -852,11 +995,21 @@ var HarnessServer = class {
852
995
  "agent",
853
996
  "session.history"
854
997
  ],
998
+ [
999
+ "host.agent.session.refresh",
1000
+ "agent",
1001
+ "session.refresh"
1002
+ ],
855
1003
  [
856
1004
  "host.agent.session.delete",
857
1005
  "agent",
858
1006
  "session.delete"
859
1007
  ],
1008
+ [
1009
+ "host.agent.session.list",
1010
+ "agent",
1011
+ "session.list"
1012
+ ],
860
1013
  [
861
1014
  "host.image.generate",
862
1015
  "image",
@@ -1133,17 +1286,34 @@ var HarnessServer = class {
1133
1286
  }
1134
1287
  async serveSdk(pathname, res) {
1135
1288
  const sdkRel = pathname.replace(/^\/static\/anna-apps\/_sdk\/[^/]+\//, "");
1136
- let distRoot;
1137
- try {
1138
- const req = createRequire(import.meta.url);
1139
- distRoot = dirname(req.resolve("@anna-ai/app-runtime"));
1140
- } catch (e) {
1141
- return this.text(res, 500, `@anna-ai/app-runtime is not installed: ${e.message}`);
1142
- }
1289
+ const distRoot = this.resolveSdkDistRoot();
1290
+ if (!distRoot) return this.text(res, 500, "@anna-ai/app-runtime is not installed and no in-tree packages/anna-app-runtime/dist was found.");
1143
1291
  const abs = resolve(distRoot, sdkRel);
1144
1292
  if (!abs.startsWith(distRoot)) return this.text(res, 403, "forbidden");
1145
1293
  return this.serveFile(abs, res);
1146
1294
  }
1295
+ /**
1296
+ * Resolve the directory the browser SDK (`index.js` + friends) is served
1297
+ * from. When `--matrix-nexus-root` is set we prefer the in-tree
1298
+ * `packages/anna-app-runtime/dist/` so contributors run byte-identical
1299
+ * with the unpublished workspace SDK (parity with the Python bridge, which
1300
+ * already runs in-tree in `nexus-source` mode). Falls back to the
1301
+ * published npm package resolved from anna-app-cli's own node_modules.
1302
+ * Returns null if neither is available.
1303
+ */
1304
+ resolveSdkDistRoot() {
1305
+ const root = this.cfg.matrixNexusRoot;
1306
+ if (root) {
1307
+ const inTree = resolve(root, "packages", "anna-app-runtime", "dist");
1308
+ if (existsSync(join(inTree, "index.js"))) return inTree;
1309
+ }
1310
+ try {
1311
+ const req = createRequire(import.meta.url);
1312
+ return dirname(req.resolve("@anna-ai/app-runtime"));
1313
+ } catch {
1314
+ return null;
1315
+ }
1316
+ }
1147
1317
  async serveBundleAsset(rel, res) {
1148
1318
  const abs = resolve(this.cfg.bundleDir, normalize(rel));
1149
1319
  if (!abs.startsWith(resolve(this.cfg.bundleDir))) return this.text(res, 403, "forbidden");
@@ -1,5 +1,5 @@
1
1
  import { canonicalHost } from "./credentials-BTv2IfUZ.js";
2
- import { hostOf, requireAccount, withCode } from "./dev-account-CD6hTr7M.js";
2
+ import { hostOf, requireAccount, withCode } from "./dev-account-CGo8k9_2.js";
3
3
  import { resolve } from "node:path";
4
4
  import { existsSync, readFileSync } from "node:fs";
5
5
 
@@ -1,6 +1,6 @@
1
1
  import "./credentials-BTv2IfUZ.js";
2
- import "./client-Dn9zThOd.js";
3
- import { resolveClient, withErrorHandling } from "./_lifecycle-shared-sbea9HtH.js";
2
+ import "./client-D-_z1ALk.js";
3
+ import { resolveClient, withErrorHandling } from "./_lifecycle-shared-BpSOfVCP.js";
4
4
  import { bold, cyan, dim, green, red, yellow } from "kleur/colors";
5
5
 
6
6
  //#region src/api/tokens.ts
@@ -1,11 +1,11 @@
1
1
  import { canonicalHost } from "./credentials-BTv2IfUZ.js";
2
- import { createApp, findAppBySlug, getApp } from "./apps-B1Nd8l_t.js";
3
- import { CliError } from "./client-Dn9zThOd.js";
4
- import { parseExecutaIdOverrides, readExecutasLock, substituteBundledRefs, validateBundledHandles, writeBundleToolIdSidecar, writeExecutasLock } from "./bundled-executas-BNOKw4kv.js";
5
- import { runExecutaPublish } from "./executa-publish-BKFq6Hz9.js";
6
- import { loadExecutaManifest } from "./manifest-hXWnNFHE.js";
7
- import { runExecutaInstall } from "./executa-install-DnBG8UJA.js";
8
- import { appCacheMatches, readAppIdentity, writeAppIdentity } from "./app-cache-TcmbIIuL.js";
2
+ import { createApp, findAppBySlug, getApp } from "./apps-CCdtLmxQ.js";
3
+ import { CliError } from "./client-D-_z1ALk.js";
4
+ import { parseExecutaIdOverrides, readExecutasLock, substituteBundledRefs, validateBundledHandles, writeBundleToolIdSidecar, writeExecutasLock } from "./bundled-executas-B6b8gIfp.js";
5
+ import { runExecutaPublish } from "./executa-publish-CkPAB34b.js";
6
+ import { loadExecutaManifest } from "./manifest-Bljz8Y6T.js";
7
+ import { runExecutaInstall } from "./executa-install-BGirXLX5.js";
8
+ import { appCacheMatches, readAppIdentity, writeAppIdentity } from "./app-cache-Bl7cE5fm.js";
9
9
  import { join, resolve } from "node:path";
10
10
  import { dim, green, yellow } from "kleur/colors";
11
11
  import { homedir } from "node:os";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anna-ai/cli",
3
- "version": "0.1.23",
3
+ "version": "0.1.27",
4
4
  "description": "Anna App developer CLI: scaffold, validate, harness (Phase 2 MVP: init + validate).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -29,11 +29,12 @@
29
29
  "test:watch": "vitest",
30
30
  "lint": "tsc --noEmit",
31
31
  "check:runtime-pin": "node scripts/check-runtime-pin.mjs",
32
- "prepublishOnly": "pnpm lint && pnpm test && pnpm build"
32
+ "check:sdk-pin": "node scripts/check-sdk-pin.mjs",
33
+ "prepublishOnly": "pnpm lint && pnpm test && pnpm build && node scripts/check-runtime-pin.mjs && node scripts/check-sdk-pin.mjs"
33
34
  },
34
35
  "dependencies": {
35
- "@anna-ai/app-runtime": "^0.5.0",
36
- "@anna-ai/app-schema": "^0.8.0",
36
+ "@anna-ai/app-runtime": "^0.8.0",
37
+ "@anna-ai/app-schema": "^0.10.0",
37
38
  "ajv": "^8.17.1",
38
39
  "ajv-formats": "^3.0.1",
39
40
  "commander": "^12.1.0",
@@ -1,14 +0,0 @@
1
- import "./credentials-BTv2IfUZ.js";
2
- import "./apps-B1Nd8l_t.js";
3
- import "./client-Dn9zThOd.js";
4
- import "./bundled-executas-BNOKw4kv.js";
5
- import "./executas-Cep6KEo0.js";
6
- import "./executa-cache-BFoUtb4J.js";
7
- import "./executa-publish-BKFq6Hz9.js";
8
- import "./manifest-hXWnNFHE.js";
9
- import "./_lifecycle-shared-sbea9HtH.js";
10
- import "./app-cache-TcmbIIuL.js";
11
- import "./app-bundle-upload-Cd4ci4rB.js";
12
- import { runAppsPublish } from "./apps-publish-U_Y7svJw.js";
13
-
14
- export { runAppsPublish };
@@ -1,3 +0,0 @@
1
- import { BridgeRequestError, PINNED_RUNTIME_VERSION, PythonBridge } from "./bridge-CBew_Ytl.js";
2
-
3
- export { PINNED_RUNTIME_VERSION, PythonBridge };
@@ -1,3 +0,0 @@
1
- import { parseExecutaSpec, runDev } from "./dev-CyFATq6R.js";
2
-
3
- export { parseExecutaSpec, runDev };
@@ -1,6 +0,0 @@
1
- import "./credentials-BTv2IfUZ.js";
2
- import "./executa-cache-BFoUtb4J.js";
3
- import "./dev-CyFATq6R.js";
4
- import { runExecutaInstall } from "./executa-install-DnBG8UJA.js";
5
-
6
- export { runExecutaInstall };
@@ -1,9 +0,0 @@
1
- import "./credentials-BTv2IfUZ.js";
2
- import "./client-Dn9zThOd.js";
3
- import "./executas-Cep6KEo0.js";
4
- import "./executa-cache-BFoUtb4J.js";
5
- import { runExecutaPublish } from "./executa-publish-BKFq6Hz9.js";
6
- import "./manifest-hXWnNFHE.js";
7
- import "./_lifecycle-shared-sbea9HtH.js";
8
-
9
- export { runExecutaPublish };
File without changes
File without changes