@anna-ai/cli 0.1.29 → 0.1.32
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-BpSOfVCP.js → _lifecycle-shared-CUK2CE76.js} +1 -1
- package/dist/account-bqao7Gp5.js +30 -0
- package/dist/{agent-CaZVCPs6.js → agent-CzPryLi6.js} +1 -1
- package/dist/{app-bundle-upload-BhAYo6yj.js → app-bundle-upload-CqT9KUOl.js} +2 -2
- package/dist/{app-cache-Bl7cE5fm.js → app-cache-BqnTkxUw.js} +1 -0
- package/dist/{apps-CCdtLmxQ.js → apps-DlVsVHQ5.js} +46 -1
- package/dist/{apps-cut-BOhg9RHy.js → apps-cut-8870xpk-.js} +11 -11
- package/dist/{apps-destructive-DWF4eTHn.js → apps-destructive-B6RFjokU.js} +3 -3
- package/dist/{apps-discard-Dy3vzpCM.js → apps-discard-hVZxAQyj.js} +11 -11
- package/dist/{apps-3VcdHIBK.js → apps-dvknZYI2.js} +2 -2
- package/dist/{apps-grants-DgvymPBT.js → apps-grants-DnXCnkH5.js} +2 -2
- package/dist/{apps-publish-Dgi4lBlu.js → apps-publish-BKqVsS1W.js} +13 -7
- package/dist/apps-publish-Djpw5cfG.js +15 -0
- package/dist/{apps-push-DbUEFdCK.js → apps-push-B3wZr9B4.js} +18 -12
- package/dist/{apps-release-DJFG4BV3.js → apps-release-DZK30eF_.js} +4 -4
- package/dist/apps-rename-slug-D2BrWasG.js +62 -0
- package/dist/{apps-status-F6aVlzDW.js → apps-status-Ca6MdXZd.js} +2 -2
- package/dist/{apps-submit-review-BVmZlhmB.js → apps-submit-review-DMFQI8JZ.js} +3 -3
- package/dist/{apps-sync-meta-CQQC_Heb.js → apps-sync-meta-BOb6J_wz.js} +27 -18
- package/dist/{apps-versions-BIKsJzIT.js → apps-versions-D1lixrmM.js} +2 -2
- package/dist/{bridge-DAY7bsje.js → bridge-CbjqAm0H.js} +1 -1
- package/dist/bridge-CzHB_IsQ.js +3 -0
- package/dist/{bundled-executas-DeBhDjd8.js → bundled-executas-06keEPP_.js} +1 -1
- package/dist/cli.js +61 -40
- package/dist/dev-C3yWhzAp.js +4 -0
- package/dist/{dev-DXODERsf.js → dev-Re6NyNDS.js} +5 -5
- package/dist/{dev-app-cache-TSjL4D4n.js → dev-app-cache-Dv1dZ_bw.js} +1 -0
- package/dist/{doctor-DCsBgyRg.js → doctor-VrfEkedz.js} +1 -1
- package/dist/{executa-cache-Kx3rfQD-.js → executa-cache-B0O79Hpb.js} +1 -1
- package/dist/{executa-destructive-PL2ooHpZ.js → executa-destructive-Bz7vWxEO.js} +3 -3
- package/dist/{executa-dev-DEpBrEIH.js → executa-dev-B5Uz982M.js} +8 -8
- package/dist/{executa-install-BHQpOskj.js → executa-install-BW9jjY7u.js} +2 -2
- package/dist/executa-install-Cyid8R7r.js +7 -0
- package/dist/{executa-publish-CkPAB34b.js → executa-publish-Ah6J7jYd.js} +4 -4
- package/dist/executa-publish-DI_6M_ea.js +9 -0
- package/dist/{executa-reads-CjGZq1yP.js → executa-reads-BXDJWWw6.js} +2 -2
- package/dist/listing-meta-BlY7XMrw.js +117 -0
- package/dist/{manifest-Bljz8Y6T.js → manifest-DOMrcdCK.js} +16 -1
- package/dist/{publish-BYWuujP3.js → publish-GpvkaBIx.js} +11 -10
- package/dist/{runner-BuYbm-ex.js → runner-BxYjAmih.js} +9 -3
- package/dist/{server-F_VA-5tS.js → server-BMcGaUTy.js} +229 -5
- package/dist/{storage-CKTmE87u.js → storage-BkF4XyI0.js} +3 -3
- package/dist/{token-Cg7BZGp6.js → token-uedeaAy7.js} +1 -1
- package/dist/{working-orchestration-Pjm4YC_U.js → working-orchestration-1jzRuk34.js} +30 -13
- package/package.json +3 -3
- package/templates/executa/go/main.go +1 -1
- package/templates/executa/node/plugin.mjs +1 -1
- package/templates/executa/python/__SLUG_PY___plugin.py +1 -1
- package/templates/minimal/executas/__SLUG__/__SLUG_PY___plugin.py +1 -1
- package/dist/apps-publish-Do7M5je3.js +0 -14
- package/dist/bridge-6GIQG63S.js +0 -3
- package/dist/dev-CQkCFVXu.js +0 -4
- package/dist/executa-install-Bvf_Lvvg.js +0 -7
- package/dist/executa-publish-IXWSwva0.js +0 -9
- /package/dist/{bundled-executas-B6b8gIfp.js → bundled-executas-_H1A9M50.js} +0 -0
- /package/dist/{confirm-h_qMrx0I.js → confirm-BuT56E_B.js} +0 -0
- /package/dist/{dev-account-CGo8k9_2.js → dev-account-DqEFCmVg.js} +0 -0
- /package/dist/{executa-cache-CXiEgFZY.js → executa-cache-Do1D7xC0.js} +0 -0
- /package/dist/{executa-init-DXea7yRN.js → executa-init-D-kWINZ3.js} +0 -0
- /package/dist/{executa-register-BUiPzPIU.js → executa-register-D5kvSSz_.js} +0 -0
- /package/dist/{executas-CK3er6f9.js → executas-BhFed1B-.js} +0 -0
- /package/dist/{fixture-BvP5umlN.js → fixture-BUKQYR5e.js} +0 -0
- /package/dist/{host_upload-BXeHTgJs.js → host_upload-BVzAqvX1.js} +0 -0
- /package/dist/{image-CSEXEfD-.js → image-BLPyUbGQ.js} +0 -0
- /package/dist/{login-BGZjMAlh.js → login-DhgBgsfx.js} +0 -0
- /package/dist/{logout-mh2_QlyM.js → logout-VYDkLYAx.js} +0 -0
- /package/dist/{sampling-DwV7VPfT.js → sampling-XBIEYU4A.js} +0 -0
- /package/dist/{whoami-l_kIkfbI.js → whoami-C_x26b_k.js} +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { patchApp, uploadAppLogo, uploadAppScreenshot } from "./apps-DlVsVHQ5.js";
|
|
2
|
+
import { CliError } from "./client-D-_z1ALk.js";
|
|
3
|
+
import { extname, resolve } from "node:path";
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
|
|
6
|
+
//#region src/publish/listing-meta.ts
|
|
7
|
+
const IMAGE_CONTENT_TYPES = {
|
|
8
|
+
".svg": "image/svg+xml",
|
|
9
|
+
".png": "image/png",
|
|
10
|
+
".jpg": "image/jpeg",
|
|
11
|
+
".jpeg": "image/jpeg",
|
|
12
|
+
".webp": "image/webp",
|
|
13
|
+
".gif": "image/gif"
|
|
14
|
+
};
|
|
15
|
+
function imageContentType(path) {
|
|
16
|
+
return IMAGE_CONTENT_TYPES[extname(path).toLowerCase()] ?? "application/octet-stream";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A listing asset is "remote" (forwarded verbatim) when it's an absolute
|
|
20
|
+
* http(s) URL or an inline `data:` URI. Anything else is treated as a
|
|
21
|
+
* project-relative local file to be uploaded to the CDN — same split the logo
|
|
22
|
+
* uses between `logoUrl` and `logoFile`.
|
|
23
|
+
*/
|
|
24
|
+
function isRemoteAsset(src) {
|
|
25
|
+
return /^https?:\/\//i.test(src) || src.startsWith("data:");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build the metadata payload from the manifest (only defined fields). The
|
|
29
|
+
* logo is handled separately and never appears here when sourced from a file.
|
|
30
|
+
*/
|
|
31
|
+
function buildMeta(manifest) {
|
|
32
|
+
const meta = {};
|
|
33
|
+
const add = (key, value) => {
|
|
34
|
+
if (value !== void 0 && value !== null && value !== "") meta[key] = value;
|
|
35
|
+
};
|
|
36
|
+
add("name", manifest.name);
|
|
37
|
+
add("category", manifest.category);
|
|
38
|
+
add("tagline", manifest.tagline);
|
|
39
|
+
add("description", manifest.description);
|
|
40
|
+
add("cover_url", manifest.coverUrl);
|
|
41
|
+
add("homepage_url", manifest.homepageUrl);
|
|
42
|
+
add("support_url", manifest.supportUrl);
|
|
43
|
+
add("privacy_url", manifest.privacyUrl);
|
|
44
|
+
add("pricing_model", manifest.pricingModel);
|
|
45
|
+
return meta;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Sync the app's store-listing metadata (and logo) from the local manifest.
|
|
49
|
+
*
|
|
50
|
+
* Returns a plan/result. When `dryRun` is set, no network calls are made and
|
|
51
|
+
* the returned object reflects what *would* be sent.
|
|
52
|
+
*/
|
|
53
|
+
async function syncAppListingMeta(client, appId, manifest, opts) {
|
|
54
|
+
const meta = buildMeta(manifest);
|
|
55
|
+
const localLogo = opts.logoOverride ?? manifest.logoFile;
|
|
56
|
+
let logoUpload;
|
|
57
|
+
if (localLogo) {
|
|
58
|
+
const logoPath = resolve(opts.cwd, localLogo);
|
|
59
|
+
if (!existsSync(logoPath)) throw new CliError(`logo file not found: ${logoPath}`, 4);
|
|
60
|
+
logoUpload = { source: localLogo };
|
|
61
|
+
} else if (manifest.logoUrl) meta.logo_url = manifest.logoUrl;
|
|
62
|
+
const screenshotSources = manifest.screenshots ?? [];
|
|
63
|
+
const screenshotPlan = screenshotSources.map((src) => {
|
|
64
|
+
const remote = isRemoteAsset(src);
|
|
65
|
+
if (!remote && !existsSync(resolve(opts.cwd, src))) throw new CliError(`screenshot file not found: ${resolve(opts.cwd, src)}`, 4);
|
|
66
|
+
return {
|
|
67
|
+
source: src,
|
|
68
|
+
remote
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
const localScreenshots = screenshotPlan.filter((s) => !s.remote);
|
|
72
|
+
const noop = Object.keys(meta).length === 0 && !logoUpload && screenshotSources.length === 0;
|
|
73
|
+
if (opts.dryRun || noop) {
|
|
74
|
+
if (screenshotSources.length > 0) meta.screenshots = screenshotSources;
|
|
75
|
+
return {
|
|
76
|
+
meta,
|
|
77
|
+
logoUpload,
|
|
78
|
+
screenshotUploads: localScreenshots.length > 0 ? localScreenshots.map((s) => ({ source: s.source })) : void 0,
|
|
79
|
+
noop
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const screenshotUploads = [];
|
|
83
|
+
const finalScreenshots = [];
|
|
84
|
+
for (const item of screenshotPlan) {
|
|
85
|
+
if (item.remote) {
|
|
86
|
+
finalScreenshots.push(item.source);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const shotPath = resolve(opts.cwd, item.source);
|
|
90
|
+
const bytes = readFileSync(shotPath);
|
|
91
|
+
const blob = new Blob([new Uint8Array(bytes)], { type: imageContentType(shotPath) });
|
|
92
|
+
const res = await uploadAppScreenshot(client, appId, blob);
|
|
93
|
+
finalScreenshots.push(res.screenshot_url);
|
|
94
|
+
screenshotUploads.push({
|
|
95
|
+
source: item.source,
|
|
96
|
+
screenshot_url: res.screenshot_url
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (finalScreenshots.length > 0) meta.screenshots = finalScreenshots;
|
|
100
|
+
if (Object.keys(meta).length > 0) await patchApp(client, appId, meta);
|
|
101
|
+
if (logoUpload) {
|
|
102
|
+
const logoPath = resolve(opts.cwd, logoUpload.source);
|
|
103
|
+
const bytes = readFileSync(logoPath);
|
|
104
|
+
const blob = new Blob([new Uint8Array(bytes)], { type: imageContentType(logoPath) });
|
|
105
|
+
const res = await uploadAppLogo(client, appId, blob);
|
|
106
|
+
logoUpload.logo_url = res.logo_url;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
meta,
|
|
110
|
+
logoUpload,
|
|
111
|
+
screenshotUploads: screenshotUploads.length > 0 ? screenshotUploads : void 0,
|
|
112
|
+
noop
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//#endregion
|
|
117
|
+
export { syncAppListingMeta };
|
|
@@ -42,6 +42,7 @@ function loadAppManifest(cwd, manifestPath) {
|
|
|
42
42
|
const metadataRaw = appJsonRaw ?? raw;
|
|
43
43
|
const metadataLabel = hasAppJson ? "app.json" : "manifest.json";
|
|
44
44
|
const pickMeta = (k) => (appJsonRaw && pickString(appJsonRaw, k)) ?? pickString(raw, k);
|
|
45
|
+
const pickMetaArray = (k) => (appJsonRaw && pickStringArray(appJsonRaw, k)) ?? pickStringArray(raw, k);
|
|
45
46
|
const slug = pickMeta("slug");
|
|
46
47
|
const name = pickMeta("name") ?? slug ?? "";
|
|
47
48
|
const version = pickMeta("version") ?? "0.1.0";
|
|
@@ -63,7 +64,15 @@ function loadAppManifest(cwd, manifestPath) {
|
|
|
63
64
|
category: pickMeta("category"),
|
|
64
65
|
tagline: pickMeta("tagline"),
|
|
65
66
|
description: pickMeta("description"),
|
|
66
|
-
changelog: pickMeta("changelog")
|
|
67
|
+
changelog: pickMeta("changelog"),
|
|
68
|
+
logoUrl: pickMeta("logo_url"),
|
|
69
|
+
logoFile: pickMeta("logo_file"),
|
|
70
|
+
coverUrl: pickMeta("cover_url"),
|
|
71
|
+
screenshots: pickMetaArray("screenshots"),
|
|
72
|
+
homepageUrl: pickMeta("homepage_url"),
|
|
73
|
+
supportUrl: pickMeta("support_url"),
|
|
74
|
+
privacyUrl: pickMeta("privacy_url"),
|
|
75
|
+
pricingModel: pickMeta("pricing_model")
|
|
67
76
|
};
|
|
68
77
|
}
|
|
69
78
|
const HANDLE_RE = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
@@ -242,6 +251,12 @@ function pickString(o, k) {
|
|
|
242
251
|
const v = o[k];
|
|
243
252
|
return typeof v === "string" ? v : void 0;
|
|
244
253
|
}
|
|
254
|
+
function pickStringArray(o, k) {
|
|
255
|
+
const v = o[k];
|
|
256
|
+
if (!Array.isArray(v)) return void 0;
|
|
257
|
+
const out = v.filter((x) => typeof x === "string");
|
|
258
|
+
return out.length > 0 ? out : void 0;
|
|
259
|
+
}
|
|
245
260
|
|
|
246
261
|
//#endregion
|
|
247
262
|
export { loadAppManifest, loadExecutaManifest };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import "./credentials-BTv2IfUZ.js";
|
|
2
|
-
import "./apps-
|
|
2
|
+
import "./apps-DlVsVHQ5.js";
|
|
3
3
|
import { CliError } from "./client-D-_z1ALk.js";
|
|
4
|
-
import "./
|
|
5
|
-
import "./executas-
|
|
6
|
-
import "./
|
|
7
|
-
import
|
|
8
|
-
import "./
|
|
9
|
-
import
|
|
10
|
-
import "./app-cache-
|
|
11
|
-
import "./
|
|
12
|
-
import
|
|
4
|
+
import { withErrorHandling } from "./_lifecycle-shared-CUK2CE76.js";
|
|
5
|
+
import "./bundled-executas-_H1A9M50.js";
|
|
6
|
+
import "./executas-BhFed1B-.js";
|
|
7
|
+
import "./executa-cache-Do1D7xC0.js";
|
|
8
|
+
import { runExecutaPublish } from "./executa-publish-Ah6J7jYd.js";
|
|
9
|
+
import "./manifest-DOMrcdCK.js";
|
|
10
|
+
import "./app-cache-BqnTkxUw.js";
|
|
11
|
+
import "./listing-meta-BlY7XMrw.js";
|
|
12
|
+
import "./app-bundle-upload-CqT9KUOl.js";
|
|
13
|
+
import { runAppsPublish } from "./apps-publish-BKqVsS1W.js";
|
|
13
14
|
import { resolve } from "node:path";
|
|
14
15
|
import { existsSync } from "node:fs";
|
|
15
16
|
import { red, yellow } from "kleur/colors";
|
|
@@ -2,10 +2,16 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { createInterface } from "node:readline";
|
|
3
3
|
|
|
4
4
|
//#region src/executa/runner.ts
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Host `initialize` request params. Mirrors the production matrix Agent
|
|
7
|
+
* (`matrix/src/executa/loader.py::negotiate`), which sends camelCase
|
|
8
|
+
* `clientInfo` + `capabilities`. The CLI advertises a richer capability
|
|
9
|
+
* set because the dev runner also brokers agent/storage/image/upload
|
|
10
|
+
* reverse RPCs.
|
|
11
|
+
*/
|
|
6
12
|
const HOST_INITIALIZE_PARAMS = {
|
|
7
13
|
protocolVersion: "2.0",
|
|
8
|
-
|
|
14
|
+
capabilities: {
|
|
9
15
|
sampling: {},
|
|
10
16
|
agent: {},
|
|
11
17
|
storage: {},
|
|
@@ -13,7 +19,7 @@ const HOST_INITIALIZE_PARAMS = {
|
|
|
13
19
|
"image.edit": {},
|
|
14
20
|
upload: {}
|
|
15
21
|
},
|
|
16
|
-
|
|
22
|
+
clientInfo: {
|
|
17
23
|
name: "anna-app-cli",
|
|
18
24
|
version: "executa-dev"
|
|
19
25
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { canonicalHost, getAccount } from "./credentials-BTv2IfUZ.js";
|
|
2
|
-
import { BridgeRequestError } from "./bridge-
|
|
2
|
+
import { BridgeRequestError } from "./bridge-CbjqAm0H.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";
|
|
@@ -128,7 +128,7 @@ var LlmBridge = class {
|
|
|
128
128
|
* - ``aps``: the bridge claims storage and forwards to real nexus APS
|
|
129
129
|
* via ``/api/v1/storage/*`` with a Bearer ``storage_token``. */
|
|
130
130
|
handles(ns, method) {
|
|
131
|
-
if (ns === "llm" && (method === "complete" || method === "embed")) return true;
|
|
131
|
+
if (ns === "llm" && (method === "complete" || method === "embed" || method === "stream")) return true;
|
|
132
132
|
if (ns === "agent" && method.startsWith("session.")) return true;
|
|
133
133
|
if (ns === "image" && (method === "generate" || method === "edit")) return true;
|
|
134
134
|
if (ns === "upload" && (method === "inline" || method === "negotiate" || method === "confirm")) return true;
|
|
@@ -140,7 +140,7 @@ var LlmBridge = class {
|
|
|
140
140
|
* ``LlmBridge.handles(ns, method)`` without an instance. Returns the
|
|
141
141
|
* legacy (no-storage) decision since options aren't available here. */
|
|
142
142
|
static handles(ns, method) {
|
|
143
|
-
if (ns === "llm" && (method === "complete" || method === "embed")) return true;
|
|
143
|
+
if (ns === "llm" && (method === "complete" || method === "embed" || method === "stream")) return true;
|
|
144
144
|
if (ns === "agent" && method.startsWith("session.")) return true;
|
|
145
145
|
if (ns === "image" && (method === "generate" || method === "edit")) return true;
|
|
146
146
|
if (ns === "upload" && (method === "inline" || method === "negotiate" || method === "confirm")) return true;
|
|
@@ -453,6 +453,25 @@ var LlmBridge = class {
|
|
|
453
453
|
result
|
|
454
454
|
};
|
|
455
455
|
}
|
|
456
|
+
if (args.ns === "llm" && args.method === "stream") {
|
|
457
|
+
const ms = await this.mintComplete(args.windowUuid);
|
|
458
|
+
const sid = `dev-${++this.streamCounter}`;
|
|
459
|
+
this.pumpCompleteStream({
|
|
460
|
+
host: acc.host,
|
|
461
|
+
token: ms.appSessionToken,
|
|
462
|
+
body: args.args,
|
|
463
|
+
streamId: sid,
|
|
464
|
+
windowUuid: args.windowUuid,
|
|
465
|
+
onEvent: args.onEvent
|
|
466
|
+
});
|
|
467
|
+
return {
|
|
468
|
+
ok: true,
|
|
469
|
+
result: {
|
|
470
|
+
stream_id: sid,
|
|
471
|
+
run_id: String(args.args.run_id ?? sid)
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
}
|
|
456
475
|
if (args.ns === "agent") switch (args.method) {
|
|
457
476
|
case "session.create": {
|
|
458
477
|
const ms = await this.mintAgent(args.args);
|
|
@@ -846,7 +865,24 @@ var LlmBridge = class {
|
|
|
846
865
|
}
|
|
847
866
|
/** Consume an SSE response and forward each frame as `rpc.stream`. */
|
|
848
867
|
async pumpAgentRun(args) {
|
|
849
|
-
|
|
868
|
+
await this.pumpSse({
|
|
869
|
+
...args,
|
|
870
|
+
url: `${canonicalHost(args.host)}/api/v1/copilot/app/agent`
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
/** L1 streaming: consume ``/app/complete/stream`` SSE and forward each
|
|
874
|
+
* ``{event:"model_token"|"complete"}`` frame as ``rpc.stream`` (mirrors
|
|
875
|
+
* ``pumpAgentRun``). */
|
|
876
|
+
async pumpCompleteStream(args) {
|
|
877
|
+
await this.pumpSse({
|
|
878
|
+
...args,
|
|
879
|
+
url: `${canonicalHost(args.host)}/api/v1/copilot/app/complete/stream`
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
/** Shared SSE→rpc.stream pump used by both L1 (`llm.stream`) and L2
|
|
883
|
+
* (`agent.session.run`) — POSTs the body, reassembles `data:` frames,
|
|
884
|
+
* and re-emits each as an ordered `rpc.stream` event. */
|
|
885
|
+
async pumpSse(args) {
|
|
850
886
|
let seq = 0;
|
|
851
887
|
const emit = (payload, done) => {
|
|
852
888
|
seq += 1;
|
|
@@ -859,7 +895,7 @@ var LlmBridge = class {
|
|
|
859
895
|
});
|
|
860
896
|
};
|
|
861
897
|
try {
|
|
862
|
-
const res = await fetch(url, {
|
|
898
|
+
const res = await fetch(args.url, {
|
|
863
899
|
method: "POST",
|
|
864
900
|
headers: {
|
|
865
901
|
"content-type": "application/json",
|
|
@@ -951,6 +987,187 @@ const MIME = {
|
|
|
951
987
|
".woff2": "font/woff2",
|
|
952
988
|
".map": "application/json"
|
|
953
989
|
};
|
|
990
|
+
function makeAppsStub() {
|
|
991
|
+
const catalog = [
|
|
992
|
+
{
|
|
993
|
+
id: 1,
|
|
994
|
+
slug: "finder",
|
|
995
|
+
qualified_ref: "@anna/finder",
|
|
996
|
+
name: "Finder",
|
|
997
|
+
tagline: "Browse, preview and curate APS storage.",
|
|
998
|
+
logo_url: null,
|
|
999
|
+
category: "utilities",
|
|
1000
|
+
is_enabled: true,
|
|
1001
|
+
installed_version: "0.0.1",
|
|
1002
|
+
latest_version: "0.0.1",
|
|
1003
|
+
update_available: false,
|
|
1004
|
+
deck_pinned: true,
|
|
1005
|
+
deck_order: 0
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
id: 2,
|
|
1009
|
+
slug: "avalon",
|
|
1010
|
+
qualified_ref: "@anna/avalon",
|
|
1011
|
+
name: "Avalon",
|
|
1012
|
+
tagline: "A 5-player social-deduction game.",
|
|
1013
|
+
logo_url: null,
|
|
1014
|
+
category: "game",
|
|
1015
|
+
is_enabled: true,
|
|
1016
|
+
installed_version: "0.0.1",
|
|
1017
|
+
latest_version: "0.0.1",
|
|
1018
|
+
update_available: false,
|
|
1019
|
+
deck_pinned: false,
|
|
1020
|
+
deck_order: null
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
id: 3,
|
|
1024
|
+
slug: "apps",
|
|
1025
|
+
qualified_ref: "@anna/apps",
|
|
1026
|
+
name: "Apps",
|
|
1027
|
+
tagline: "A Launchpad-style launcher for your installed apps.",
|
|
1028
|
+
logo_url: null,
|
|
1029
|
+
category: "utilities",
|
|
1030
|
+
is_enabled: true,
|
|
1031
|
+
installed_version: "0.0.1",
|
|
1032
|
+
latest_version: "0.0.1",
|
|
1033
|
+
update_available: false,
|
|
1034
|
+
deck_pinned: true,
|
|
1035
|
+
deck_order: 1
|
|
1036
|
+
}
|
|
1037
|
+
];
|
|
1038
|
+
const resolve$1 = (ref) => {
|
|
1039
|
+
if (typeof ref === "number") return catalog.find((a) => a.id === ref);
|
|
1040
|
+
const s = String(ref ?? "").trim();
|
|
1041
|
+
if (/^\d+$/.test(s)) return catalog.find((a) => a.id === Number(s));
|
|
1042
|
+
return catalog.find((a) => a.qualified_ref === s || a.slug === s);
|
|
1043
|
+
};
|
|
1044
|
+
const deck = () => catalog.filter((a) => a.deck_pinned).sort((a, b) => (a.deck_order ?? 0) - (b.deck_order ?? 0));
|
|
1045
|
+
const nextOrder = () => deck().reduce((m, a) => Math.max(m, a.deck_order ?? 0), -1) + 1;
|
|
1046
|
+
const handle = (method, args) => {
|
|
1047
|
+
switch (method) {
|
|
1048
|
+
case "list": {
|
|
1049
|
+
const q = String(args.search ?? args.query ?? "").trim().toLowerCase();
|
|
1050
|
+
const items = q ? catalog.filter((a) => a.name.toLowerCase().includes(q) || a.slug.toLowerCase().includes(q) || a.tagline.toLowerCase().includes(q) || a.category.toLowerCase().includes(q)) : catalog;
|
|
1051
|
+
return {
|
|
1052
|
+
ok: true,
|
|
1053
|
+
result: { items }
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
case "search": {
|
|
1057
|
+
const q = String(args.query ?? args.search ?? "").trim().toLowerCase();
|
|
1058
|
+
const items = catalog.filter((a) => a.name.toLowerCase().includes(q) || a.slug.toLowerCase().includes(q) || a.tagline.toLowerCase().includes(q));
|
|
1059
|
+
return {
|
|
1060
|
+
ok: true,
|
|
1061
|
+
result: { items }
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
case "get": {
|
|
1065
|
+
const hit = resolve$1(args.app_ref ?? args.app_id);
|
|
1066
|
+
return hit ? {
|
|
1067
|
+
ok: true,
|
|
1068
|
+
result: hit
|
|
1069
|
+
} : {
|
|
1070
|
+
ok: false,
|
|
1071
|
+
error: {
|
|
1072
|
+
code: "app_not_installed",
|
|
1073
|
+
message: "not installed"
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
case "launch": {
|
|
1078
|
+
const hit = resolve$1(args.app_ref ?? args.app_id);
|
|
1079
|
+
if (!hit) return {
|
|
1080
|
+
ok: false,
|
|
1081
|
+
error: {
|
|
1082
|
+
code: "app_not_installed",
|
|
1083
|
+
message: "not installed"
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
1086
|
+
return {
|
|
1087
|
+
ok: true,
|
|
1088
|
+
result: {
|
|
1089
|
+
window_uuid: `dev-win-${hit.slug}`,
|
|
1090
|
+
app: {
|
|
1091
|
+
id: hit.id,
|
|
1092
|
+
slug: hit.slug,
|
|
1093
|
+
name: hit.name
|
|
1094
|
+
},
|
|
1095
|
+
opened_new: true
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
case "deck.list": return {
|
|
1100
|
+
ok: true,
|
|
1101
|
+
result: { items: deck() }
|
|
1102
|
+
};
|
|
1103
|
+
case "deck.add": {
|
|
1104
|
+
const hit = resolve$1(args.app_ref ?? args.app_id);
|
|
1105
|
+
if (!hit) return {
|
|
1106
|
+
ok: false,
|
|
1107
|
+
error: {
|
|
1108
|
+
code: "app_not_installed",
|
|
1109
|
+
message: "not installed"
|
|
1110
|
+
}
|
|
1111
|
+
};
|
|
1112
|
+
if (!hit.deck_pinned) {
|
|
1113
|
+
hit.deck_pinned = true;
|
|
1114
|
+
hit.deck_order = nextOrder();
|
|
1115
|
+
}
|
|
1116
|
+
return {
|
|
1117
|
+
ok: true,
|
|
1118
|
+
result: { items: deck() }
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
case "deck.remove": {
|
|
1122
|
+
const hit = resolve$1(args.app_ref ?? args.app_id);
|
|
1123
|
+
if (!hit) return {
|
|
1124
|
+
ok: false,
|
|
1125
|
+
error: {
|
|
1126
|
+
code: "app_not_installed",
|
|
1127
|
+
message: "not installed"
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
if (hit.deck_pinned) {
|
|
1131
|
+
hit.deck_pinned = false;
|
|
1132
|
+
hit.deck_order = null;
|
|
1133
|
+
}
|
|
1134
|
+
return {
|
|
1135
|
+
ok: true,
|
|
1136
|
+
result: { items: deck() }
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
case "deck.reorder": {
|
|
1140
|
+
const ordered = args.ordered ?? args.app_refs;
|
|
1141
|
+
if (!Array.isArray(ordered)) return {
|
|
1142
|
+
ok: false,
|
|
1143
|
+
error: {
|
|
1144
|
+
code: "invalid_arg",
|
|
1145
|
+
message: "ordered must be a list"
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
ordered.forEach((ref, i) => {
|
|
1149
|
+
const hit = resolve$1(ref);
|
|
1150
|
+
if (hit) {
|
|
1151
|
+
hit.deck_pinned = true;
|
|
1152
|
+
hit.deck_order = i;
|
|
1153
|
+
}
|
|
1154
|
+
});
|
|
1155
|
+
return {
|
|
1156
|
+
ok: true,
|
|
1157
|
+
result: { items: deck() }
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
default: return {
|
|
1161
|
+
ok: false,
|
|
1162
|
+
error: {
|
|
1163
|
+
code: "not_implemented",
|
|
1164
|
+
message: `apps.${method} stub missing`
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
return { handle };
|
|
1170
|
+
}
|
|
954
1171
|
var HarnessServer = class {
|
|
955
1172
|
server = createServer((req, res) => this.handle(req, res));
|
|
956
1173
|
wss = null;
|
|
@@ -961,6 +1178,8 @@ var HarnessServer = class {
|
|
|
961
1178
|
/** Pending events queued by the LLM bridge — drained alongside Python events. */
|
|
962
1179
|
llmEventQueue = [];
|
|
963
1180
|
llmBridge;
|
|
1181
|
+
/** In-memory `apps.*` dev stub (Apps launcher). */
|
|
1182
|
+
appsStub = makeAppsStub();
|
|
964
1183
|
constructor(cfg, bridge) {
|
|
965
1184
|
this.cfg = cfg;
|
|
966
1185
|
this.bridge = bridge;
|
|
@@ -1242,6 +1461,11 @@ var HarnessServer = class {
|
|
|
1242
1461
|
}
|
|
1243
1462
|
});
|
|
1244
1463
|
}
|
|
1464
|
+
if (parsed.ns === "apps") {
|
|
1465
|
+
const out = this.appsStub.handle(parsed.method, parsed.args ?? {});
|
|
1466
|
+
this.json(res, 200, out);
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1245
1469
|
if (this.llmBridge != null && this.llmBridge.handles(parsed.ns, parsed.method)) {
|
|
1246
1470
|
const out = await this.llmBridge.dispatch({
|
|
1247
1471
|
windowUuid: this.sessionId ?? "harness",
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { canonicalHost } from "./credentials-BTv2IfUZ.js";
|
|
2
|
-
import { hostOf, requireAccount, withCode } from "./dev-account-
|
|
2
|
+
import { hostOf, requireAccount, withCode } from "./dev-account-DqEFCmVg.js";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
5
|
|
|
6
6
|
//#region src/executa/storage.ts
|
|
7
7
|
/** JSON-RPC error codes from matrix/src/executa/protocol.py. */
|
|
8
|
-
const STORAGE_ERR_INVALID_REQUEST = -32020;
|
|
9
8
|
const STORAGE_ERR_NOT_GRANTED = -32021;
|
|
10
9
|
const STORAGE_ERR_NOT_FOUND = -32022;
|
|
11
10
|
const STORAGE_ERR_PRECONDITION_FAILED = -32023;
|
|
12
|
-
const
|
|
11
|
+
const STORAGE_ERR_INVALID_REQUEST = -32028;
|
|
12
|
+
const STORAGE_ERR_UPSTREAM = -32029;
|
|
13
13
|
/** Method → (http_method, sub_path, payload_kind). Mirrors matrix/storage.py. */
|
|
14
14
|
const ROUTING = {
|
|
15
15
|
"storage/get": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./credentials-BTv2IfUZ.js";
|
|
2
2
|
import "./client-D-_z1ALk.js";
|
|
3
|
-
import { resolveClient, withErrorHandling } from "./_lifecycle-shared-
|
|
3
|
+
import { resolveClient, withErrorHandling } from "./_lifecycle-shared-CUK2CE76.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-
|
|
2
|
+
import { createApp, findAppBySlug, getApp } from "./apps-DlVsVHQ5.js";
|
|
3
3
|
import { CliError } from "./client-D-_z1ALk.js";
|
|
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-
|
|
4
|
+
import { parseExecutaIdOverrides, readExecutasLock, substituteBundledRefs, validateBundledHandles, writeBundleToolIdSidecar, writeExecutasLock } from "./bundled-executas-_H1A9M50.js";
|
|
5
|
+
import { runExecutaPublish } from "./executa-publish-Ah6J7jYd.js";
|
|
6
|
+
import { loadExecutaManifest } from "./manifest-DOMrcdCK.js";
|
|
7
|
+
import { runExecutaInstall } from "./executa-install-BW9jjY7u.js";
|
|
8
|
+
import { appCacheMatches, readAppIdentity, writeAppIdentity } from "./app-cache-BqnTkxUw.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";
|
|
@@ -174,24 +174,40 @@ async function resolveAppIdentity(params) {
|
|
|
174
174
|
const found = await findAppBySlug(client, manifest.slug);
|
|
175
175
|
let appId;
|
|
176
176
|
let serverSlug;
|
|
177
|
+
let serverHandle;
|
|
177
178
|
let firstPublish = false;
|
|
178
179
|
if (found) {
|
|
179
180
|
appId = found.id;
|
|
180
181
|
serverSlug = found.slug;
|
|
182
|
+
serverHandle = typeof found.handle === "string" ? found.handle : void 0;
|
|
181
183
|
} else {
|
|
182
184
|
if (dryRun) {
|
|
183
185
|
if (!json) console.log(yellow(`[dry-run] would create AnnaApp slug=${manifest.slug}`));
|
|
184
186
|
return null;
|
|
185
187
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
188
|
+
let created;
|
|
189
|
+
try {
|
|
190
|
+
created = await createApp(client, {
|
|
191
|
+
slug: manifest.slug,
|
|
192
|
+
name: manifest.name,
|
|
193
|
+
category: manifest.category,
|
|
194
|
+
tagline: manifest.tagline,
|
|
195
|
+
description: manifest.description
|
|
196
|
+
});
|
|
197
|
+
} catch (e) {
|
|
198
|
+
if (e instanceof CliError && e.status === 409) {
|
|
199
|
+
const body = e.body;
|
|
200
|
+
const code = body?.detail?.code;
|
|
201
|
+
if (code === "HANDLE_REQUIRED") throw new CliError("you must set a developer handle before creating an app.\n Run: anna-app account set-handle <handle>\n Your apps will then publish as @<handle>/" + manifest.slug + ".", 5, {
|
|
202
|
+
status: 409,
|
|
203
|
+
body
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
throw e;
|
|
207
|
+
}
|
|
193
208
|
appId = created.id;
|
|
194
209
|
serverSlug = created.slug;
|
|
210
|
+
serverHandle = typeof created.handle === "string" ? created.handle : void 0;
|
|
195
211
|
firstPublish = true;
|
|
196
212
|
}
|
|
197
213
|
writeAppIdentity(cwd, {
|
|
@@ -199,6 +215,7 @@ async function resolveAppIdentity(params) {
|
|
|
199
215
|
host: canonicalHost(host),
|
|
200
216
|
app_id: appId,
|
|
201
217
|
slug: serverSlug,
|
|
218
|
+
handle: serverHandle,
|
|
202
219
|
first_published_at: cached?.first_published_at ?? new Date().toISOString()
|
|
203
220
|
});
|
|
204
221
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anna-ai/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
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.
|
|
37
|
-
"@anna-ai/app-schema": "^0.
|
|
36
|
+
"@anna-ai/app-runtime": "^0.10.0",
|
|
37
|
+
"@anna-ai/app-schema": "^0.12.0",
|
|
38
38
|
"ajv": "^8.17.1",
|
|
39
39
|
"ajv-formats": "^3.0.1",
|
|
40
40
|
"commander": "^12.1.0",
|
|
@@ -85,7 +85,7 @@ async function dispatch(env) {
|
|
|
85
85
|
} else if (method === "describe") {
|
|
86
86
|
result = MANIFEST;
|
|
87
87
|
} else if (method === "health") {
|
|
88
|
-
result = { status: "
|
|
88
|
+
result = { status: "ready" };
|
|
89
89
|
} else if (method === "invoke") {
|
|
90
90
|
result = await invoke(params.tool, params.arguments ?? {});
|
|
91
91
|
} else {
|
|
@@ -119,7 +119,7 @@ def _dispatch(env: dict[str, Any]) -> None:
|
|
|
119
119
|
elif method == "describe":
|
|
120
120
|
result = MANIFEST
|
|
121
121
|
elif method == "health":
|
|
122
|
-
result = {"status": "
|
|
122
|
+
result = {"status": "ready"}
|
|
123
123
|
elif method == "invoke":
|
|
124
124
|
params = env.get("params", {})
|
|
125
125
|
result = invoke(params.get("tool", ""), params.get("arguments", {}))
|
|
@@ -40,7 +40,7 @@ def main() -> None:
|
|
|
40
40
|
if req.get("method") == "describe":
|
|
41
41
|
result = MANIFEST
|
|
42
42
|
elif req.get("method") == "health":
|
|
43
|
-
result = {"status": "
|
|
43
|
+
result = {"status": "ready"}
|
|
44
44
|
elif req.get("method") == "invoke":
|
|
45
45
|
result = invoke(req["params"]["tool"], req["params"].get("arguments", {}))
|
|
46
46
|
else:
|