@anna-ai/cli 0.1.26 → 0.1.28

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.
@@ -8,10 +8,10 @@ import "./executa-cache-CXiEgFZY.js";
8
8
  import "./executa-publish-CkPAB34b.js";
9
9
  import "./manifest-Bljz8Y6T.js";
10
10
  import { resolveClient, withErrorHandling } from "./_lifecycle-shared-BpSOfVCP.js";
11
- import "./dev-3okZmzNM.js";
12
- import "./executa-install-DQIhVHPT.js";
11
+ import "./dev-DXODERsf.js";
12
+ import "./executa-install-BHQpOskj.js";
13
13
  import "./app-cache-Bl7cE5fm.js";
14
- import { resolveAppBySlugOrCache } from "./working-orchestration-Dd1ETQ3c.js";
14
+ import { resolveAppBySlugOrCache } from "./working-orchestration-Pjm4YC_U.js";
15
15
  import { resolve } from "node:path";
16
16
  import { bold, cyan, dim, green, yellow } from "kleur/colors";
17
17
 
@@ -8,10 +8,10 @@ import "./executa-cache-CXiEgFZY.js";
8
8
  import "./executa-publish-CkPAB34b.js";
9
9
  import "./manifest-Bljz8Y6T.js";
10
10
  import { resolveClient, withErrorHandling } from "./_lifecycle-shared-BpSOfVCP.js";
11
- import "./dev-3okZmzNM.js";
12
- import "./executa-install-DQIhVHPT.js";
11
+ import "./dev-DXODERsf.js";
12
+ import "./executa-install-BHQpOskj.js";
13
13
  import "./app-cache-Bl7cE5fm.js";
14
- import { resolveAppBySlugOrCache } from "./working-orchestration-Dd1ETQ3c.js";
14
+ import { resolveAppBySlugOrCache } from "./working-orchestration-Pjm4YC_U.js";
15
15
  import { dim, green, yellow } from "kleur/colors";
16
16
 
17
17
  //#region src/commands/apps-discard.ts
@@ -8,10 +8,10 @@ import "./executa-cache-CXiEgFZY.js";
8
8
  import { bumpVersion, bundleHash, manifestHash, rewriteVersion } from "./executa-publish-CkPAB34b.js";
9
9
  import { loadAppManifest } from "./manifest-Bljz8Y6T.js";
10
10
  import { resolveClient, withErrorHandling } from "./_lifecycle-shared-BpSOfVCP.js";
11
- import "./dev-3okZmzNM.js";
12
- import "./executa-install-DQIhVHPT.js";
11
+ import "./dev-DXODERsf.js";
12
+ import "./executa-install-BHQpOskj.js";
13
13
  import "./app-cache-Bl7cE5fm.js";
14
- import { installLocalBundledShims, resolveAppIdentity, resolveBundledExecutas } from "./working-orchestration-Dd1ETQ3c.js";
14
+ import { installLocalBundledShims, resolveAppIdentity, resolveBundledExecutas } from "./working-orchestration-Pjm4YC_U.js";
15
15
  import { isExistingDir, uploadWorkingBundle } from "./app-bundle-upload-BhAYo6yj.js";
16
16
  import { resolve } from "node:path";
17
17
  import { bold, cyan, dim, green, yellow } from "kleur/colors";
@@ -0,0 +1,3 @@
1
+ import { BridgeRequestError, PINNED_RUNTIME_VERSION, PythonBridge } from "./bridge-DAY7bsje.js";
2
+
3
+ export { PINNED_RUNTIME_VERSION, PythonBridge };
@@ -9,7 +9,7 @@ import { createInterface } from "node:readline";
9
9
  * `uvx <pkg>@<version>` so end users always run the dispatcher version
10
10
  * the CLI was tested against.
11
11
  */
12
- const PINNED_RUNTIME_VERSION = "0.2.0a8";
12
+ const PINNED_RUNTIME_VERSION = "0.2.0a9";
13
13
  /**
14
14
  * Throwable from a {@link RequestHandler} to send a structured JSON-RPC
15
15
  * error back to the python bridge with a stable string ``code`` (e.g.
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-C5r439wM.js");
473
+ const { runDev, parseExecutaSpec } = await import("./dev-CQkCFVXu.js");
474
474
  const cwd = opts.cwd ?? process.cwd();
475
475
  let executas;
476
476
  if (opts.executa && opts.executa.length > 0) {
@@ -529,7 +529,7 @@ 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-giNqYnla.js");
532
+ const { runDoctor } = await import("./doctor-DCsBgyRg.js");
533
533
  const code = await runDoctor({ matrixNexusRoot: opts.matrixNexusRoot });
534
534
  process.exit(code);
535
535
  });
@@ -582,7 +582,7 @@ executa.command("register").description("Register a HARNESS AnnaApp(kind=executa
582
582
  process.exit(code);
583
583
  });
584
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");
585
+ const { runExecutaInstall } = await import("./executa-install-Bvf_Lvvg.js");
586
586
  const code = await runExecutaInstall({
587
587
  dir: opts.dir,
588
588
  toolId: opts.toolId,
@@ -593,7 +593,7 @@ executa.command("install").description("Install a local-dev shim for an Executa
593
593
  process.exit(code);
594
594
  });
595
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) => {
596
- const { runExecutaDev } = await import("./executa-dev-Cr9Yepph.js");
596
+ const { runExecutaDev } = await import("./executa-dev-Deo8ag5o.js");
597
597
  const storageMode = opts.storage === void 0 ? void 0 : (() => {
598
598
  const m = opts.storage;
599
599
  if (m === "off" || m === "memory" || m === "mock" || m === "real") return m;
@@ -678,7 +678,7 @@ apps.command("push").description("Upsert the mutable working draft (manifest + b
678
678
  process.exit(2);
679
679
  }
680
680
  }
681
- const { runAppsPush } = await import("./apps-push-CixatuQG.js");
681
+ const { runAppsPush } = await import("./apps-push-DbUEFdCK.js");
682
682
  process.exit(await runAppsPush({
683
683
  cwd: opts.cwd,
684
684
  manifest: opts.manifest,
@@ -697,7 +697,7 @@ apps.command("push").description("Upsert the mutable working draft (manifest + b
697
697
  }));
698
698
  });
699
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) => {
700
- const { runAppsCut } = await import("./apps-cut-BCicQFRY.js");
700
+ const { runAppsCut } = await import("./apps-cut-BOhg9RHy.js");
701
701
  process.exit(await runAppsCut({
702
702
  version,
703
703
  changelog: opts.changelog,
@@ -709,7 +709,7 @@ apps.command("cut <version>").description("Snapshot the working draft into an im
709
709
  }));
710
710
  });
711
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) => {
712
- const { runAppsDiscard } = await import("./apps-discard-BoY4zMJw.js");
712
+ const { runAppsDiscard } = await import("./apps-discard-Dy3vzpCM.js");
713
713
  process.exit(await runAppsDiscard({
714
714
  slug: opts.slug,
715
715
  cwd: opts.cwd,
@@ -0,0 +1,4 @@
1
+ import "./nexus-root-BlPwOusj.js";
2
+ import { parseExecutaSpec, runDev } from "./dev-DXODERsf.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-hzqNFm9-.js");
53
- const { HarnessServer } = await import("./server-Cp7mYV9t.js");
52
+ const { PythonBridge, PINNED_RUNTIME_VERSION } = await import("./bridge-6GIQG63S.js");
53
+ const { HarnessServer } = await import("./server-F_VA-5tS.js");
54
54
  const bridge = new PythonBridge({
55
55
  mode,
56
56
  matrixNexusRoot: matrixNexusRoot ?? void 0,
@@ -1,5 +1,5 @@
1
1
  import { findMatrixNexusRoot, nexusSchemaDir } from "./nexus-root-BlPwOusj.js";
2
- import { PINNED_RUNTIME_VERSION } from "./bridge-DxBd0Fl9.js";
2
+ import { PINNED_RUNTIME_VERSION } from "./bridge-DAY7bsje.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-3okZmzNM.js";
2
+ import { parseExecutaSpec } from "./dev-DXODERsf.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";
@@ -1,5 +1,5 @@
1
1
  import { readExecutaIdentity } from "./executa-cache-CXiEgFZY.js";
2
- import { parseExecutaSpec } from "./dev-3okZmzNM.js";
2
+ import { parseExecutaSpec } from "./dev-DXODERsf.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-DXODERsf.js";
5
+ import { runExecutaInstall } from "./executa-install-BHQpOskj.js";
6
+
7
+ export { runExecutaInstall };
@@ -1,5 +1,5 @@
1
1
  import { canonicalHost, getAccount } from "./credentials-BTv2IfUZ.js";
2
- import { BridgeRequestError } from "./bridge-DxBd0Fl9.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";
@@ -187,7 +187,8 @@ var LlmBridge = class {
187
187
  fixed_client_id: args.fixed_client_id ?? args.fixedClientId ?? null,
188
188
  app_slug: slug,
189
189
  label: args.label ?? "anna-app dev",
190
- quota_caps: args.quotaCaps ?? null
190
+ quota_caps: args.quotaCaps ?? null,
191
+ system_prompt: args.systemPrompt ?? args.system_prompt ?? null
191
192
  };
192
193
  const minted = await this.callMint(acc.host, body);
193
194
  const ms = {
@@ -200,6 +201,80 @@ var LlmBridge = class {
200
201
  this.mintedAgent.set(ms.appSessionUuid, ms);
201
202
  return ms;
202
203
  }
204
+ /** Re-mint an agent session token by ``app_session_uuid`` via the dev
205
+ * ``/dev/session/refresh`` endpoint (PAT + uuid — NO stale token needed).
206
+ *
207
+ * This is the harness's token-free recovery path: even after the CLI
208
+ * process restarted (so ``mintedAgent`` is empty) or the previous token
209
+ * expired, the underlying ``AnnaAppSession`` row is still alive and the
210
+ * app remembers its ``app_session_uuid``. ``refresh`` slides the idle
211
+ * window and hands back a fresh short-lived token, fixing the forum
212
+ * report "uuid unusable after dev restart". Throws on 404/410 (the row
213
+ * is genuinely gone / revoked / idle-expired). */
214
+ async callRefresh(apsUuid) {
215
+ const acc = this.account();
216
+ const url = `${canonicalHost(acc.host)}/api/v1/anna-apps/dev/session/refresh`;
217
+ const res = await fetch(url, {
218
+ method: "POST",
219
+ headers: { "content-type": "application/json" },
220
+ body: JSON.stringify({
221
+ pat: acc.pat,
222
+ app_session_uuid: apsUuid
223
+ })
224
+ });
225
+ if (!res.ok) {
226
+ const text = await res.text().catch(() => "");
227
+ throw new Error(`session.refresh failed: HTTP ${res.status} ${text}`);
228
+ }
229
+ const payload = await res.json();
230
+ return {
231
+ token: payload.app_session_token,
232
+ expiresIn: payload.expires_in || 600,
233
+ submode: payload.submode ?? null
234
+ };
235
+ }
236
+ /** Revoke an agent session by uuid via ``/dev/session/revoke`` (PAT-auth).
237
+ *
238
+ * Token-free: works even when the session token is long expired (which
239
+ * used to make the session impossible to release → quota leak). */
240
+ async callRevoke(apsUuid) {
241
+ const acc = this.account();
242
+ const url = `${canonicalHost(acc.host)}/api/v1/anna-apps/dev/session/revoke`;
243
+ const res = await fetch(url, {
244
+ method: "POST",
245
+ headers: { "content-type": "application/json" },
246
+ body: JSON.stringify({
247
+ pat: acc.pat,
248
+ app_session_uuid: apsUuid
249
+ })
250
+ });
251
+ if (!res.ok) {
252
+ const text = await res.text().catch(() => "");
253
+ throw new Error(`session.revoke failed: HTTP ${res.status} ${text}`);
254
+ }
255
+ }
256
+ /** Return a live agent session token for ``apsUuid``, re-minting via
257
+ * ``/dev/session/refresh`` on cache-miss or near-expiry.
258
+ *
259
+ * Centralises the "is my token still good?" decision for every operation
260
+ * that needs an ``app_session_token`` (run / cancel / delete). On success
261
+ * the freshly-minted session is cached in ``mintedAgent`` so subsequent
262
+ * calls in the same process reuse it until the next near-expiry check. */
263
+ async ensureLiveToken(apsUuid) {
264
+ const now = Math.floor(Date.now() / 1e3);
265
+ const cached = this.mintedAgent.get(apsUuid);
266
+ if (cached && cached.expiresAt - 30 > now) return cached;
267
+ const refreshed = await this.callRefresh(apsUuid);
268
+ const ms = {
269
+ appSessionToken: refreshed.token,
270
+ appSessionUuid: apsUuid,
271
+ expiresAt: Math.floor(Date.now() / 1e3) + refreshed.expiresIn,
272
+ isAgent: true,
273
+ submode: refreshed.submode ?? cached?.submode ?? null
274
+ };
275
+ this.mintedAgent.set(apsUuid, ms);
276
+ return ms;
277
+ }
203
278
  /** Mint (or reuse) a storage_token for APS forwarding.
204
279
  *
205
280
  * Server-side ``/dev/storage/mint`` issues a JWT scoped to
@@ -394,14 +469,18 @@ var LlmBridge = class {
394
469
  }
395
470
  case "session.run": {
396
471
  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
- };
472
+ let ms;
473
+ try {
474
+ ms = await this.ensureLiveToken(apsUuid);
475
+ } catch (e) {
476
+ return {
477
+ ok: false,
478
+ error: {
479
+ code: "session_expired",
480
+ message: e.message || "session expired or revoked"
481
+ }
482
+ };
483
+ }
405
484
  const sid = `dev-${++this.streamCounter}`;
406
485
  this.pumpAgentRun({
407
486
  host: acc.host,
@@ -422,16 +501,42 @@ var LlmBridge = class {
422
501
  }
423
502
  };
424
503
  }
504
+ case "session.refresh": {
505
+ const apsUuid = String(args.args.app_session_uuid ?? "");
506
+ try {
507
+ const ms = await this.ensureLiveToken(apsUuid);
508
+ return {
509
+ ok: true,
510
+ result: {
511
+ app_session_uuid: ms.appSessionUuid,
512
+ expires_in: Math.max(0, ms.expiresAt - Math.floor(Date.now() / 1e3)),
513
+ submode: ms.submode
514
+ }
515
+ };
516
+ } catch (e) {
517
+ return {
518
+ ok: false,
519
+ error: {
520
+ code: "session_expired",
521
+ message: e.message || "session expired or revoked"
522
+ }
523
+ };
524
+ }
525
+ }
425
526
  case "session.cancel": {
426
527
  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
- };
528
+ let ms;
529
+ try {
530
+ ms = await this.ensureLiveToken(apsUuid);
531
+ } catch (e) {
532
+ return {
533
+ ok: false,
534
+ error: {
535
+ code: "session_expired",
536
+ message: e.message || "session expired or revoked"
537
+ }
538
+ };
539
+ }
435
540
  const out = await this.postJson(`${canonicalHost(acc.host)}/api/v1/copilot/app/agent/cancel`, ms.appSessionToken, args.args);
436
541
  return {
437
542
  ok: true,
@@ -449,6 +554,22 @@ var LlmBridge = class {
449
554
  const includeExpired = Boolean(args.args?.include_expired);
450
555
  const rawLimit = Number(args.args?.limit ?? 50);
451
556
  const limit = Math.max(1, Math.min(100, Number.isFinite(rawLimit) ? rawLimit : 50));
557
+ if (this.opts.appSlug) try {
558
+ const acc2 = this.account();
559
+ const url = new URL(`${canonicalHost(acc2.host)}/api/v1/anna-apps/dev/sessions`);
560
+ url.searchParams.set("pat", acc2.pat);
561
+ url.searchParams.set("app_slug", this.opts.appSlug);
562
+ url.searchParams.set("include_expired", String(includeExpired));
563
+ url.searchParams.set("limit", String(limit));
564
+ const res = await fetch(url, { method: "GET" });
565
+ if (res.ok) {
566
+ const body = await res.json();
567
+ return {
568
+ ok: true,
569
+ result: { sessions: body.sessions ?? [] }
570
+ };
571
+ }
572
+ } catch {}
452
573
  const now = Math.floor(Date.now() / 1e3);
453
574
  const sessions = [...this.mintedAgent.values()].filter((ms) => includeExpired || ms.expiresAt > now).slice(0, limit).map((ms) => ({
454
575
  app_session_uuid: ms.appSessionUuid,
@@ -467,31 +588,34 @@ var LlmBridge = class {
467
588
  }
468
589
  case "session.delete": {
469
590
  const apsUuid = String(args.args.app_session_uuid ?? "");
470
- const ms = this.mintedAgent.get(apsUuid);
591
+ const cached = this.mintedAgent.get(apsUuid);
471
592
  this.mintedAgent.delete(apsUuid);
472
- if (!ms) return {
473
- ok: true,
474
- result: { deleted: true }
475
- };
476
- const url = `${canonicalHost(acc.host)}/api/v1/copilot/app/sessions/${encodeURIComponent(apsUuid)}`;
477
- const res = await fetch(url, {
478
- method: "DELETE",
479
- headers: { authorization: `Bearer ${ms.appSessionToken}` }
480
- });
481
- if (!res.ok) {
482
- const text = await res.text().catch(() => "");
593
+ if (cached && cached.expiresAt - 5 > Math.floor(Date.now() / 1e3)) {
594
+ const url = `${canonicalHost(acc.host)}/api/v1/copilot/app/sessions/${encodeURIComponent(apsUuid)}`;
595
+ const res = await fetch(url, {
596
+ method: "DELETE",
597
+ headers: { authorization: `Bearer ${cached.appSessionToken}` }
598
+ });
599
+ if (res.ok) return {
600
+ ok: true,
601
+ result: { deleted: true }
602
+ };
603
+ }
604
+ try {
605
+ await this.callRevoke(apsUuid);
606
+ return {
607
+ ok: true,
608
+ result: { deleted: true }
609
+ };
610
+ } catch (e) {
483
611
  return {
484
612
  ok: false,
485
613
  error: {
486
614
  code: "transport",
487
- message: `HTTP ${res.status}: ${text}`
615
+ message: e.message
488
616
  }
489
617
  };
490
618
  }
491
- return {
492
- ok: true,
493
- result: { deleted: true }
494
- };
495
619
  }
496
620
  }
497
621
  if (args.ns === "image" && (args.method === "generate" || args.method === "edit")) {
@@ -872,6 +996,11 @@ var HarnessServer = class {
872
996
  "agent",
873
997
  "session.history"
874
998
  ],
999
+ [
1000
+ "host.agent.session.refresh",
1001
+ "agent",
1002
+ "session.refresh"
1003
+ ],
875
1004
  [
876
1005
  "host.agent.session.delete",
877
1006
  "agent",
@@ -4,7 +4,7 @@ import { CliError } from "./client-D-_z1ALk.js";
4
4
  import { parseExecutaIdOverrides, readExecutasLock, substituteBundledRefs, validateBundledHandles, writeBundleToolIdSidecar, writeExecutasLock } from "./bundled-executas-B6b8gIfp.js";
5
5
  import { runExecutaPublish } from "./executa-publish-CkPAB34b.js";
6
6
  import { loadExecutaManifest } from "./manifest-Bljz8Y6T.js";
7
- import { runExecutaInstall } from "./executa-install-DQIhVHPT.js";
7
+ import { runExecutaInstall } from "./executa-install-BHQpOskj.js";
8
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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anna-ai/cli",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "Anna App developer CLI: scaffold, validate, harness (Phase 2 MVP: init + validate).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -33,8 +33,8 @@
33
33
  "prepublishOnly": "pnpm lint && pnpm test && pnpm build && node scripts/check-runtime-pin.mjs && node scripts/check-sdk-pin.mjs"
34
34
  },
35
35
  "dependencies": {
36
- "@anna-ai/app-runtime": "^0.7.0",
37
- "@anna-ai/app-schema": "^0.9.0",
36
+ "@anna-ai/app-runtime": "^0.8.0",
37
+ "@anna-ai/app-schema": "^0.10.0",
38
38
  "ajv": "^8.17.1",
39
39
  "ajv-formats": "^3.0.1",
40
40
  "commander": "^12.1.0",
@@ -1,3 +0,0 @@
1
- import { BridgeRequestError, PINNED_RUNTIME_VERSION, PythonBridge } from "./bridge-DxBd0Fl9.js";
2
-
3
- export { PINNED_RUNTIME_VERSION, PythonBridge };
@@ -1,4 +0,0 @@
1
- import "./nexus-root-BlPwOusj.js";
2
- import { parseExecutaSpec, runDev } from "./dev-3okZmzNM.js";
3
-
4
- export { parseExecutaSpec, runDev };
@@ -1,7 +0,0 @@
1
- import "./credentials-BTv2IfUZ.js";
2
- import "./nexus-root-BlPwOusj.js";
3
- import "./executa-cache-CXiEgFZY.js";
4
- import "./dev-3okZmzNM.js";
5
- import { runExecutaInstall } from "./executa-install-DQIhVHPT.js";
6
-
7
- export { runExecutaInstall };