@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.
- package/dist/{_lifecycle-shared-sbea9HtH.js → _lifecycle-shared-BpSOfVCP.js} +1 -1
- package/dist/{agent-DyXJhaZ0.js → agent-CaZVCPs6.js} +1 -1
- package/dist/{app-bundle-upload-Cd4ci4rB.js → app-bundle-upload-BhAYo6yj.js} +3 -3
- package/dist/{apps-B57i8xeb.js → apps-3VcdHIBK.js} +3 -3
- package/dist/{apps-cut-BG6Ib3x4.js → apps-cut-DKl5I9bf.js} +13 -12
- package/dist/{apps-destructive-DQIFqYE2.js → apps-destructive-DWF4eTHn.js} +4 -4
- package/dist/{apps-discard-BveXHAgF.js → apps-discard-zg1nu2HN.js} +13 -12
- package/dist/{apps-grants-D3i6GxX_.js → apps-grants-DgvymPBT.js} +3 -3
- package/dist/{apps-publish-U_Y7svJw.js → apps-publish-Dgi4lBlu.js} +8 -8
- package/dist/apps-publish-Do7M5je3.js +14 -0
- package/dist/{apps-push-x5reIQHx.js → apps-push-C1-QDzF8.js} +14 -13
- package/dist/{apps-release-ByIgz6lx.js → apps-release-DJFG4BV3.js} +5 -5
- package/dist/{apps-status-BYo97Nh5.js → apps-status-F6aVlzDW.js} +3 -3
- package/dist/{apps-submit-review-D-cPtZtc.js → apps-submit-review-BVmZlhmB.js} +4 -4
- package/dist/{apps-sync-meta-CTHwGlzI.js → apps-sync-meta-CQQC_Heb.js} +5 -5
- package/dist/{apps-versions-Ca-AAMLL.js → apps-versions-BIKsJzIT.js} +3 -3
- package/dist/bridge-6GIQG63S.js +3 -0
- package/dist/{bridge-CBew_Ytl.js → bridge-DAY7bsje.js} +1 -1
- package/dist/{bundled-executas-BNOKw4kv.js → bundled-executas-B6b8gIfp.js} +1 -1
- package/dist/{bundled-executas-CNaV2C_O.js → bundled-executas-DeBhDjd8.js} +2 -2
- package/dist/cli.js +51 -46
- package/dist/{confirm-C-4haiIg.js → confirm-h_qMrx0I.js} +1 -1
- package/dist/{dev-CyFATq6R.js → dev-DGTtVCNj.js} +19 -22
- package/dist/dev-DVCIv8mJ.js +4 -0
- package/dist/{doctor-oqYeEjLv.js → doctor-DCsBgyRg.js} +10 -22
- package/dist/{executa-cache-WBkCLic7.js → executa-cache-Kx3rfQD-.js} +1 -1
- package/dist/{executa-destructive-Dpo58lxI.js → executa-destructive-PL2ooHpZ.js} +4 -4
- package/dist/{executa-dev-DFp1ckAn.js → executa-dev-BOo6xpVy.js} +10 -9
- package/dist/{executa-install-DnBG8UJA.js → executa-install-BGirXLX5.js} +2 -2
- package/dist/executa-install-Cuq0Y_H4.js +7 -0
- package/dist/{executa-publish-BKFq6Hz9.js → executa-publish-CkPAB34b.js} +5 -5
- package/dist/executa-publish-IXWSwva0.js +9 -0
- package/dist/{executa-reads-cd-8ZRjI.js → executa-reads-CjGZq1yP.js} +3 -3
- package/dist/{manifest-hXWnNFHE.js → manifest-Bljz8Y6T.js} +1 -1
- package/dist/nexus-root-BlPwOusj.js +49 -0
- package/dist/{publish-R3JAl9Hm.js → publish-BYWuujP3.js} +11 -11
- package/dist/{server-BzfmXVJD.js → server-D7zabdJY.js} +211 -41
- package/dist/{storage-BCj754in.js → storage-CKTmE87u.js} +1 -1
- package/dist/{token-BGjbb2aU.js → token-Cg7BZGp6.js} +2 -2
- package/dist/{working-orchestration-CIpQ_JMY.js → working-orchestration-Dh1gCwGg.js} +7 -7
- package/package.json +5 -4
- package/dist/apps-publish-D403z305.js +0 -14
- package/dist/bridge-DZmZIWG0.js +0 -3
- package/dist/dev-DdjwQzJ2.js +0 -3
- package/dist/executa-install-viq3kiV7.js +0 -6
- package/dist/executa-publish-DaYvxbbW.js +0 -9
- /package/dist/{app-cache-TcmbIIuL.js → app-cache-Bl7cE5fm.js} +0 -0
- /package/dist/{apps-B1Nd8l_t.js → apps-CCdtLmxQ.js} +0 -0
- /package/dist/{client-Dn9zThOd.js → client-D-_z1ALk.js} +0 -0
- /package/dist/{credentials-DklPMD22.js → credentials-Chkoidh5.js} +0 -0
- /package/dist/{dev-account-CD6hTr7M.js → dev-account-CGo8k9_2.js} +0 -0
- /package/dist/{dev-app-cache-DMQLQ93-.js → dev-app-cache-TSjL4D4n.js} +0 -0
- /package/dist/{executa-cache-BFoUtb4J.js → executa-cache-CXiEgFZY.js} +0 -0
- /package/dist/{executa-init-By0kMPaF.js → executa-init-DXea7yRN.js} +0 -0
- /package/dist/{executa-register-BX29VfcD.js → executa-register-BUiPzPIU.js} +0 -0
- /package/dist/{executas-Cep6KEo0.js → executas-CK3er6f9.js} +0 -0
- /package/dist/{fixture-C9VLX3os.js → fixture-BvP5umlN.js} +0 -0
- /package/dist/{host_upload-wKM0jQoL.js → host_upload-BXeHTgJs.js} +0 -0
- /package/dist/{image-CBSlNb-9.js → image-CSEXEfD-.js} +0 -0
- /package/dist/{login-D4cU2Jcp.js → login-BGZjMAlh.js} +0 -0
- /package/dist/{logout-DOpL3vXX.js → logout-mh2_QlyM.js} +0 -0
- /package/dist/{runner-4-ugGH5e.js → runner-BuYbm-ex.js} +0 -0
- /package/dist/{sampling-finZ8aNJ.js → sampling-BcML4teS.js} +0 -0
- /package/dist/{whoami-DarmijoA.js → whoami-l_kIkfbI.js} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
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-
|
|
37
|
-
const { ensureDevExecutaRegistered } = await import("./dev-app-cache-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
88
|
-
const { ImageBridge } = await import("./image-
|
|
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-
|
|
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-
|
|
2
|
-
import { parseExecutaSpec } from "./dev-
|
|
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";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { canonicalHost } from "./credentials-BTv2IfUZ.js";
|
|
2
|
-
import { CliError } from "./client-
|
|
3
|
-
import { commitDraft, createDraft, getMySkill, getMyTool, listToolVersions, publishToolVersion, setSkillVisibility, setToolVisibility, updateMySkill, updateMyTool } from "./executas-
|
|
4
|
-
import { executaCacheMatches, invalidateExecutaCache, mintIdempotencyKey, readExecutaIdentity, writeExecutaIdentity } from "./executa-cache-
|
|
5
|
-
import { loadExecutaManifest } from "./manifest-
|
|
6
|
-
import { resolveClient, withErrorHandling } from "./_lifecycle-shared-
|
|
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-
|
|
3
|
-
import { getMyTool, listMyTools, listToolVersions } from "./executas-
|
|
4
|
-
import { resolveClient, withErrorHandling } from "./_lifecycle-shared-
|
|
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
|
|
@@ -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-
|
|
3
|
-
import { CliError } from "./client-
|
|
4
|
-
import "./bundled-executas-
|
|
5
|
-
import "./executas-
|
|
6
|
-
import "./executa-cache-
|
|
7
|
-
import { runExecutaPublish } from "./executa-publish-
|
|
8
|
-
import "./manifest-
|
|
9
|
-
import { withErrorHandling } from "./_lifecycle-shared-
|
|
10
|
-
import "./app-cache-
|
|
11
|
-
import "./app-bundle-upload-
|
|
12
|
-
import { runAppsPublish } from "./apps-publish-
|
|
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-
|
|
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
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
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
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
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
|
|
590
|
+
const cached = this.mintedAgent.get(apsUuid);
|
|
451
591
|
this.mintedAgent.delete(apsUuid);
|
|
452
|
-
if (
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
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:
|
|
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
|
-
|
|
1137
|
-
|
|
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-
|
|
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-
|
|
3
|
-
import { resolveClient, withErrorHandling } from "./_lifecycle-shared-
|
|
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-
|
|
3
|
-
import { CliError } from "./client-
|
|
4
|
-
import { parseExecutaIdOverrides, readExecutasLock, substituteBundledRefs, validateBundledHandles, writeBundleToolIdSidecar, writeExecutasLock } from "./bundled-executas-
|
|
5
|
-
import { runExecutaPublish } from "./executa-publish-
|
|
6
|
-
import { loadExecutaManifest } from "./manifest-
|
|
7
|
-
import { runExecutaInstall } from "./executa-install-
|
|
8
|
-
import { appCacheMatches, readAppIdentity, writeAppIdentity } from "./app-cache-
|
|
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.
|
|
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
|
-
"
|
|
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.
|
|
36
|
-
"@anna-ai/app-schema": "^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 };
|
package/dist/bridge-DZmZIWG0.js
DELETED
package/dist/dev-DdjwQzJ2.js
DELETED
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|