@anna-ai/cli 0.1.26 → 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.
@@ -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-DGTtVCNj.js";
12
+ import "./executa-install-BGirXLX5.js";
13
13
  import "./app-cache-Bl7cE5fm.js";
14
- import { resolveAppBySlugOrCache } from "./working-orchestration-Dd1ETQ3c.js";
14
+ import { resolveAppBySlugOrCache } from "./working-orchestration-Dh1gCwGg.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-DGTtVCNj.js";
12
+ import "./executa-install-BGirXLX5.js";
13
13
  import "./app-cache-Bl7cE5fm.js";
14
- import { resolveAppBySlugOrCache } from "./working-orchestration-Dd1ETQ3c.js";
14
+ import { resolveAppBySlugOrCache } from "./working-orchestration-Dh1gCwGg.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-DGTtVCNj.js";
12
+ import "./executa-install-BGirXLX5.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-Dh1gCwGg.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-DVCIv8mJ.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-Cuq0Y_H4.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-BOo6xpVy.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-C1-QDzF8.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-DKl5I9bf.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-zg1nu2HN.js");
713
713
  process.exit(await runAppsDiscard({
714
714
  slug: opts.slug,
715
715
  cwd: opts.cwd,
@@ -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-D7zabdJY.js");
54
54
  const bridge = new PythonBridge({
55
55
  mode,
56
56
  matrixNexusRoot: matrixNexusRoot ?? void 0,
@@ -0,0 +1,4 @@
1
+ import "./nexus-root-BlPwOusj.js";
2
+ import { parseExecutaSpec, runDev } from "./dev-DGTtVCNj.js";
3
+
4
+ export { parseExecutaSpec, runDev };
@@ -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-DGTtVCNj.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-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,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";
@@ -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,
@@ -449,6 +553,22 @@ var LlmBridge = class {
449
553
  const includeExpired = Boolean(args.args?.include_expired);
450
554
  const rawLimit = Number(args.args?.limit ?? 50);
451
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 {}
452
572
  const now = Math.floor(Date.now() / 1e3);
453
573
  const sessions = [...this.mintedAgent.values()].filter((ms) => includeExpired || ms.expiresAt > now).slice(0, limit).map((ms) => ({
454
574
  app_session_uuid: ms.appSessionUuid,
@@ -467,31 +587,34 @@ var LlmBridge = class {
467
587
  }
468
588
  case "session.delete": {
469
589
  const apsUuid = String(args.args.app_session_uuid ?? "");
470
- const ms = this.mintedAgent.get(apsUuid);
590
+ const cached = this.mintedAgent.get(apsUuid);
471
591
  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(() => "");
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) {
483
610
  return {
484
611
  ok: false,
485
612
  error: {
486
613
  code: "transport",
487
- message: `HTTP ${res.status}: ${text}`
614
+ message: e.message
488
615
  }
489
616
  };
490
617
  }
491
- return {
492
- ok: true,
493
- result: { deleted: true }
494
- };
495
618
  }
496
619
  }
497
620
  if (args.ns === "image" && (args.method === "generate" || args.method === "edit")) {
@@ -872,6 +995,11 @@ var HarnessServer = class {
872
995
  "agent",
873
996
  "session.history"
874
997
  ],
998
+ [
999
+ "host.agent.session.refresh",
1000
+ "agent",
1001
+ "session.refresh"
1002
+ ],
875
1003
  [
876
1004
  "host.agent.session.delete",
877
1005
  "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-BGirXLX5.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.27",
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 };