@anna-ai/cli 0.1.11 → 0.1.12
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/apps-CDe6Fjq2.js +44 -0
- package/dist/bridge-BEHyfpPI.js +3 -0
- package/dist/cli.js +18 -10
- package/dist/{credentials-ggdaz_-7.js → credentials-BTv2IfUZ.js} +1 -1
- package/dist/credentials-CIOYq2Lm.js +3 -0
- package/dist/dashboard.html +8 -4
- package/dist/{dev-BPIUX2Nh.js → dev-DoY58pBM.js} +52 -7
- package/dist/dev-app-cache-BMfOlTHd.js +93 -0
- package/dist/dev-app-cache-cXvO2XwQ.js +4 -0
- package/dist/{doctor-R1pjmBDG.js → doctor-DP2UB10l.js} +1 -1
- package/dist/{login-D8cmvBb6.js → login-dl1Zfny8.js} +1 -1
- package/dist/{logout-P6L9VU4W.js → logout-DablvlFs.js} +1 -1
- package/dist/{server-Cd5Lo-2v.js → server-NXmiWJjX.js} +10 -4
- package/dist/{whoami-jqlQwe7Z.js → whoami-giXOY415.js} +1 -1
- package/package.json +3 -3
- package/dist/bridge-BIO7ilgO.js +0 -3
- /package/dist/{bridge-Cpm3D2Wk.js → bridge-BQUo6ehX.js} +0 -0
- /package/dist/{fixture-RceUUd84.js → fixture-BEu4LXLG.js} +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { getAccount } from "./credentials-BTv2IfUZ.js";
|
|
2
|
+
import { listDevApps } from "./dev-app-cache-BMfOlTHd.js";
|
|
3
|
+
import { bold, cyan, dim, green, red, yellow } from "kleur/colors";
|
|
4
|
+
|
|
5
|
+
//#region src/commands/apps.ts
|
|
6
|
+
async function runAppsList(opts) {
|
|
7
|
+
const acc = getAccount(opts.account);
|
|
8
|
+
if (!acc) {
|
|
9
|
+
console.error(red("✗ no PAT on disk — run `anna-app login --host <nexus-url>` first."));
|
|
10
|
+
return 2;
|
|
11
|
+
}
|
|
12
|
+
let apps;
|
|
13
|
+
try {
|
|
14
|
+
apps = await listDevApps({
|
|
15
|
+
host: acc.host,
|
|
16
|
+
pat: acc.pat
|
|
17
|
+
});
|
|
18
|
+
} catch (e) {
|
|
19
|
+
console.error(red(`✗ ${e.message}`));
|
|
20
|
+
return 2;
|
|
21
|
+
}
|
|
22
|
+
if (opts.json) {
|
|
23
|
+
console.log(JSON.stringify({
|
|
24
|
+
host: acc.host,
|
|
25
|
+
apps
|
|
26
|
+
}, null, 2));
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
console.log(bold(cyan("dev apps installed for")) + " " + cyan(acc.host));
|
|
30
|
+
if (apps.length === 0) {
|
|
31
|
+
console.log(dim(" (none — run `anna-app dev` in a project to register one)"));
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
for (const a of apps) {
|
|
35
|
+
const tag = a.is_dev ? yellow("[dev]") : green("[prod]");
|
|
36
|
+
const enabled = a.is_enabled ? green("✓") : red("✗");
|
|
37
|
+
console.log(` ${tag} ${enabled} ${bold(a.slug)} ${dim(`(app_id=${a.app_id}, v=${a.installed_version})`)}`);
|
|
38
|
+
if (a.name && a.name !== a.slug) console.log(` ${dim(a.name)}`);
|
|
39
|
+
}
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { runAppsList };
|
package/dist/cli.js
CHANGED
|
@@ -444,8 +444,8 @@ program.command("validate").description("Run schema + ACL checks on a manifest+b
|
|
|
444
444
|
const code = printResult(result);
|
|
445
445
|
process.exit(code);
|
|
446
446
|
});
|
|
447
|
-
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)"
|
|
448
|
-
const { runDev, parseExecutaSpec } = await import("./dev-
|
|
447
|
+
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)").action(async (opts) => {
|
|
448
|
+
const { runDev, parseExecutaSpec } = await import("./dev-DoY58pBM.js");
|
|
449
449
|
const cwd = opts.cwd ?? process.cwd();
|
|
450
450
|
let executas;
|
|
451
451
|
if (opts.executa && opts.executa.length > 0) {
|
|
@@ -473,13 +473,13 @@ program.command("dev").description("Run a local harness (in-process dispatcher +
|
|
|
473
473
|
noLlm: opts.llm === false,
|
|
474
474
|
mockLlm: opts.mockLlm,
|
|
475
475
|
llmAccount: opts.llmAccount,
|
|
476
|
-
|
|
476
|
+
llmAppSlug: opts.llmAppSlug
|
|
477
477
|
});
|
|
478
478
|
process.exit(code);
|
|
479
479
|
});
|
|
480
480
|
const fixture = program.command("fixture").description("Inspect / replay harness recordings (Phase 6)");
|
|
481
481
|
fixture.command("verify <file>").description("Schema + invariant checks on a harness JSONL recording").option("--json", "Emit machine-readable JSON", false).action(async (file, opts) => {
|
|
482
|
-
const { runFixtureVerify } = await import("./fixture-
|
|
482
|
+
const { runFixtureVerify } = await import("./fixture-BEu4LXLG.js");
|
|
483
483
|
const code = await runFixtureVerify({
|
|
484
484
|
file,
|
|
485
485
|
json: opts.json
|
|
@@ -487,7 +487,7 @@ fixture.command("verify <file>").description("Schema + invariant checks on a har
|
|
|
487
487
|
process.exit(code);
|
|
488
488
|
});
|
|
489
489
|
fixture.command("summarize <file>").description("Print a human-readable digest of a harness recording").option("--json", "Emit machine-readable JSON", false).action(async (file, opts) => {
|
|
490
|
-
const { runFixtureSummarize } = await import("./fixture-
|
|
490
|
+
const { runFixtureSummarize } = await import("./fixture-BEu4LXLG.js");
|
|
491
491
|
const code = await runFixtureSummarize({
|
|
492
492
|
file,
|
|
493
493
|
json: opts.json
|
|
@@ -495,7 +495,7 @@ fixture.command("summarize <file>").description("Print a human-readable digest o
|
|
|
495
495
|
process.exit(code);
|
|
496
496
|
});
|
|
497
497
|
fixture.command("replay <file>").description("Dry-run replay of a harness recording (Phase 6 MVP)").option("--manifest <path>", "manifest.json path", "manifest.json").action(async (file, opts) => {
|
|
498
|
-
const { runFixtureReplay } = await import("./fixture-
|
|
498
|
+
const { runFixtureReplay } = await import("./fixture-BEu4LXLG.js");
|
|
499
499
|
const code = await runFixtureReplay({
|
|
500
500
|
file,
|
|
501
501
|
manifest: opts.manifest
|
|
@@ -503,12 +503,12 @@ fixture.command("replay <file>").description("Dry-run replay of a harness record
|
|
|
503
503
|
process.exit(code);
|
|
504
504
|
});
|
|
505
505
|
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) => {
|
|
506
|
-
const { runDoctor } = await import("./doctor-
|
|
506
|
+
const { runDoctor } = await import("./doctor-DP2UB10l.js");
|
|
507
507
|
const code = await runDoctor({ matrixNexusRoot: opts.matrixNexusRoot });
|
|
508
508
|
process.exit(code);
|
|
509
509
|
});
|
|
510
510
|
program.command("login").description("Device-flow login against a nexus host; saves a PAT to ~/.config/anna/credentials.json").requiredOption("--host <url>", "nexus base URL, e.g. https://nexus.example.com").option("--no-browser", "Do not open a browser window automatically", false).action(async (opts) => {
|
|
511
|
-
const { runLogin } = await import("./login-
|
|
511
|
+
const { runLogin } = await import("./login-dl1Zfny8.js");
|
|
512
512
|
const code = await runLogin({
|
|
513
513
|
host: opts.host,
|
|
514
514
|
noBrowser: opts.browser === false
|
|
@@ -516,7 +516,7 @@ program.command("login").description("Device-flow login against a nexus host; sa
|
|
|
516
516
|
process.exit(code);
|
|
517
517
|
});
|
|
518
518
|
program.command("logout").description("Remove a saved PAT entry").option("--host <url>", "Account to remove (default: current)").option("--all", "Remove every saved account", false).action(async (opts) => {
|
|
519
|
-
const { runLogout } = await import("./logout-
|
|
519
|
+
const { runLogout } = await import("./logout-DablvlFs.js");
|
|
520
520
|
const code = await runLogout({
|
|
521
521
|
host: opts.host,
|
|
522
522
|
all: opts.all
|
|
@@ -524,10 +524,18 @@ program.command("logout").description("Remove a saved PAT entry").option("--host
|
|
|
524
524
|
process.exit(code);
|
|
525
525
|
});
|
|
526
526
|
program.command("whoami").description("Show the current account (and any others)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
|
|
527
|
-
const { runWhoami } = await import("./whoami-
|
|
527
|
+
const { runWhoami } = await import("./whoami-giXOY415.js");
|
|
528
528
|
const code = await runWhoami({ json: opts.json });
|
|
529
529
|
process.exit(code);
|
|
530
530
|
});
|
|
531
|
+
program.command("apps:list").description("List dev apps installed for the current PAT").option("--account <host>", "Saved account host (default: current)").option("--json", "Emit machine-readable JSON", false).action(async (opts) => {
|
|
532
|
+
const { runAppsList } = await import("./apps-CDe6Fjq2.js");
|
|
533
|
+
const code = await runAppsList({
|
|
534
|
+
account: opts.account,
|
|
535
|
+
json: opts.json
|
|
536
|
+
});
|
|
537
|
+
process.exit(code);
|
|
538
|
+
});
|
|
531
539
|
program.parseAsync(process.argv).catch((e) => {
|
|
532
540
|
console.error(e);
|
|
533
541
|
process.exit(2);
|
|
@@ -119,4 +119,4 @@ function credentialsAreLooselyPermissioned() {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
//#endregion
|
|
122
|
-
export { canonicalHost, credentialsAreLooselyPermissioned, getAccount, maskPat, readCredentials, removeAccount, saveAccount };
|
|
122
|
+
export { canonicalHost, credentialsAreLooselyPermissioned, credentialsPath, getAccount, maskPat, readCredentials, removeAccount, saveAccount, writeCredentials };
|
package/dist/dashboard.html
CHANGED
|
@@ -337,20 +337,24 @@
|
|
|
337
337
|
}
|
|
338
338
|
|
|
339
339
|
function relayEventToIframe(ev) {
|
|
340
|
-
// ev
|
|
340
|
+
// ev arrives from the WS server as { kind:"event", event:"<name>", payload }
|
|
341
|
+
// (see server.ts: `ws.send({ kind: "event", ...ev })`). The SDK keys its
|
|
342
|
+
// handlers off `event` (e.g. "rpc.stream", "auth.refresh"), so we MUST
|
|
343
|
+
// forward `ev.event` — not `ev.kind`, which is always the literal
|
|
344
|
+
// string "event" and would drop every frame on the floor.
|
|
341
345
|
if (!iframe.contentWindow) return;
|
|
342
346
|
const env = {
|
|
343
347
|
wid: windowUuid,
|
|
344
348
|
kind: "event",
|
|
345
|
-
event: ev.
|
|
349
|
+
event: ev.event,
|
|
346
350
|
payload: ev.payload,
|
|
347
351
|
};
|
|
348
352
|
iframe.contentWindow.postMessage(env, "*");
|
|
349
353
|
logLine(
|
|
350
354
|
"event",
|
|
351
|
-
`← event <span class="pill">${escapeHtml(ev.
|
|
355
|
+
`← event <span class="pill">${escapeHtml(ev.event)}</span> ${escapeHtml(JSON.stringify(ev.payload))}`,
|
|
352
356
|
);
|
|
353
|
-
recPush("event", { event: ev.
|
|
357
|
+
recPush("event", { event: ev.event, payload: ev.payload });
|
|
354
358
|
}
|
|
355
359
|
|
|
356
360
|
// postMessage RPC bridge: iframe → POST /api/session/call → result
|
|
@@ -31,8 +31,8 @@ async function runDev(opts) {
|
|
|
31
31
|
}
|
|
32
32
|
const matrixNexusRoot = await resolveMatrixNexusRoot(opts.matrixNexusRoot, cwd);
|
|
33
33
|
const mode = matrixNexusRoot ? "nexus-source" : "uvx";
|
|
34
|
-
const { PythonBridge, PINNED_RUNTIME_VERSION } = await import("./bridge-
|
|
35
|
-
const { HarnessServer } = await import("./server-
|
|
34
|
+
const { PythonBridge, PINNED_RUNTIME_VERSION } = await import("./bridge-BEHyfpPI.js");
|
|
35
|
+
const { HarnessServer } = await import("./server-NXmiWJjX.js");
|
|
36
36
|
const bridge = new PythonBridge({
|
|
37
37
|
mode,
|
|
38
38
|
matrixNexusRoot: matrixNexusRoot ?? void 0,
|
|
@@ -68,12 +68,14 @@ async function runDev(opts) {
|
|
|
68
68
|
const llm = opts.noLlm ? { mode: "off" } : opts.mockLlm ? {
|
|
69
69
|
mode: "mock",
|
|
70
70
|
mockFile: opts.mockLlm
|
|
71
|
-
} : {
|
|
72
|
-
|
|
71
|
+
} : await resolveRealLlm({
|
|
72
|
+
cwd,
|
|
73
73
|
account: opts.llmAccount,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
appSlug: opts.llmAppSlug ?? slug,
|
|
75
|
+
manifest
|
|
76
|
+
});
|
|
77
|
+
if (llm === null) return 2;
|
|
78
|
+
console.log(` llm bridge ${dim(llm.mode === "off" ? "disabled (--no-llm)" : llm.mode === "mock" ? `mock (${opts.mockLlm})` : `real${opts.llmAccount ? ` [${opts.llmAccount}]` : ""} → app_slug=${llm.appSlug}`)}`);
|
|
77
79
|
const server = new HarnessServer({
|
|
78
80
|
slug,
|
|
79
81
|
manifest,
|
|
@@ -111,6 +113,49 @@ async function runDev(opts) {
|
|
|
111
113
|
await new Promise(() => {});
|
|
112
114
|
return 0;
|
|
113
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Resolve the `real` LlmBridgeOptions: load the dev PAT, register
|
|
118
|
+
* (or re-use) an `AnnaApp(is_dev=True)` on nexus, cache the result.
|
|
119
|
+
*
|
|
120
|
+
* Returns `null` (after printing) when registration fails so the caller
|
|
121
|
+
* can exit cleanly. Otherwise returns a bridge config carrying the
|
|
122
|
+
* registered `appSlug`.
|
|
123
|
+
*/
|
|
124
|
+
async function resolveRealLlm(args) {
|
|
125
|
+
const { getAccount } = await import("./credentials-CIOYq2Lm.js");
|
|
126
|
+
const { ensureDevAppRegistered } = await import("./dev-app-cache-cXvO2XwQ.js");
|
|
127
|
+
const acc = getAccount(args.account);
|
|
128
|
+
if (!acc) {
|
|
129
|
+
console.error(red("✗ no developer PAT on disk — run `anna-app login --host <nexus-url>` first.\n (or use `--no-llm` / `--mock-llm <fixture>` to develop offline.)"));
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
if (acc.expires_at && acc.expires_at < Math.floor(Date.now() / 1e3)) {
|
|
133
|
+
console.error(red("✗ PAT expired — run `anna-app login` again."));
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
const manifest = args.manifest;
|
|
137
|
+
try {
|
|
138
|
+
const entry = await ensureDevAppRegistered({
|
|
139
|
+
cwd: args.cwd,
|
|
140
|
+
host: acc.host,
|
|
141
|
+
pat: acc.pat,
|
|
142
|
+
input: {
|
|
143
|
+
slug: args.appSlug,
|
|
144
|
+
name: manifest.name,
|
|
145
|
+
category: manifest.category,
|
|
146
|
+
tagline: manifest.tagline
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
mode: "real",
|
|
151
|
+
account: args.account,
|
|
152
|
+
appSlug: entry.slug
|
|
153
|
+
};
|
|
154
|
+
} catch (e) {
|
|
155
|
+
console.error(red(`✗ failed to register dev app on nexus: ${e.message}`));
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
114
159
|
function deriveSlug(manifest, path) {
|
|
115
160
|
const fromMan = manifest.slug ?? manifest.name;
|
|
116
161
|
if (typeof fromMan === "string" && fromMan) return fromMan;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { canonicalHost } from "./credentials-BTv2IfUZ.js";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
|
|
5
|
+
//#region src/dev-app-cache.ts
|
|
6
|
+
const CACHE_DIR = ".anna";
|
|
7
|
+
const CACHE_FILE = "dev-app.json";
|
|
8
|
+
function cachePath(cwd) {
|
|
9
|
+
return resolve(cwd, CACHE_DIR, CACHE_FILE);
|
|
10
|
+
}
|
|
11
|
+
function readDevAppCache(cwd) {
|
|
12
|
+
const p = cachePath(cwd);
|
|
13
|
+
if (!existsSync(p)) return null;
|
|
14
|
+
try {
|
|
15
|
+
const raw = JSON.parse(readFileSync(p, "utf-8"));
|
|
16
|
+
if (typeof raw.host === "string" && typeof raw.slug === "string" && typeof raw.app_id === "number") return {
|
|
17
|
+
host: raw.host,
|
|
18
|
+
slug: raw.slug,
|
|
19
|
+
app_id: raw.app_id,
|
|
20
|
+
name: raw.name ?? raw.slug,
|
|
21
|
+
registered_at: raw.registered_at ?? ""
|
|
22
|
+
};
|
|
23
|
+
} catch {}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
function writeDevAppCache(cwd, entry) {
|
|
27
|
+
const p = cachePath(cwd);
|
|
28
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
29
|
+
writeFileSync(p, JSON.stringify(entry, null, 2) + "\n", "utf-8");
|
|
30
|
+
}
|
|
31
|
+
/** Call POST /api/v1/anna-apps/dev/apps/register. Idempotent server-side. */
|
|
32
|
+
async function registerDevApp(args) {
|
|
33
|
+
const url = `${canonicalHost(args.host)}/api/v1/anna-apps/dev/apps/register`;
|
|
34
|
+
const res = await fetch(url, {
|
|
35
|
+
method: "POST",
|
|
36
|
+
headers: { "content-type": "application/json" },
|
|
37
|
+
body: JSON.stringify({
|
|
38
|
+
pat: args.pat,
|
|
39
|
+
slug: args.input.slug,
|
|
40
|
+
name: args.input.name,
|
|
41
|
+
category: args.input.category,
|
|
42
|
+
tagline: args.input.tagline
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
const text = await res.text().catch(() => "");
|
|
47
|
+
throw new Error(`/dev/apps/register failed: HTTP ${res.status} ${text}`);
|
|
48
|
+
}
|
|
49
|
+
return await res.json();
|
|
50
|
+
}
|
|
51
|
+
/** Call GET /api/v1/anna-apps/dev/apps. */
|
|
52
|
+
async function listDevApps(args) {
|
|
53
|
+
const url = new URL(`${canonicalHost(args.host)}/api/v1/anna-apps/dev/apps`);
|
|
54
|
+
url.searchParams.set("pat", args.pat);
|
|
55
|
+
const res = await fetch(url, { method: "GET" });
|
|
56
|
+
if (!res.ok) {
|
|
57
|
+
const text = await res.text().catch(() => "");
|
|
58
|
+
throw new Error(`/dev/apps failed: HTTP ${res.status} ${text}`);
|
|
59
|
+
}
|
|
60
|
+
const body = await res.json();
|
|
61
|
+
return body.apps;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Convenience helper for `anna-app dev`: returns a valid cached entry if
|
|
65
|
+
* it still matches the manifest slug, otherwise hits the server to
|
|
66
|
+
* (re-)register. Throws if no PAT is available on disk.
|
|
67
|
+
*/
|
|
68
|
+
async function ensureDevAppRegistered(args) {
|
|
69
|
+
const canonical = canonicalHost(args.host);
|
|
70
|
+
const cached = readDevAppCache(args.cwd);
|
|
71
|
+
if (cached && cached.host === canonical && cached.slug === args.input.slug) return cached;
|
|
72
|
+
const r = await registerDevApp({
|
|
73
|
+
host: args.host,
|
|
74
|
+
pat: args.pat,
|
|
75
|
+
input: args.input
|
|
76
|
+
});
|
|
77
|
+
const entry = {
|
|
78
|
+
host: canonical,
|
|
79
|
+
slug: r.slug,
|
|
80
|
+
app_id: r.app_id,
|
|
81
|
+
name: r.name,
|
|
82
|
+
registered_at: new Date().toISOString()
|
|
83
|
+
};
|
|
84
|
+
writeDevAppCache(args.cwd, entry);
|
|
85
|
+
return entry;
|
|
86
|
+
}
|
|
87
|
+
const _internal = {
|
|
88
|
+
cachePath,
|
|
89
|
+
CACHE_DIR: join(CACHE_DIR, CACHE_FILE)
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
export { ensureDevAppRegistered, listDevApps, readDevAppCache, registerDevApp, writeDevAppCache };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PINNED_RUNTIME_VERSION } from "./bridge-
|
|
1
|
+
import { PINNED_RUNTIME_VERSION } from "./bridge-BQUo6ehX.js";
|
|
2
2
|
import { dirname, isAbsolute, resolve } from "node:path";
|
|
3
3
|
import { existsSync, statSync } from "node:fs";
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { canonicalHost, getAccount, readCredentials, removeAccount } from "./credentials-
|
|
1
|
+
import { canonicalHost, getAccount, readCredentials, removeAccount } from "./credentials-BTv2IfUZ.js";
|
|
2
2
|
|
|
3
3
|
//#region src/commands/logout.ts
|
|
4
4
|
async function runLogout(opts) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { canonicalHost, getAccount } from "./credentials-
|
|
1
|
+
import { canonicalHost, getAccount } from "./credentials-BTv2IfUZ.js";
|
|
2
2
|
import { dirname, join, normalize, resolve } from "node:path";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { createReadStream, existsSync, readFileSync, statSync, watch } from "node:fs";
|
|
@@ -48,12 +48,12 @@ var LlmBridge = class {
|
|
|
48
48
|
const cached = this.mintedAuto.get(windowUuid);
|
|
49
49
|
if (cached && cached.expiresAt - 30 > Math.floor(Date.now() / 1e3)) return cached;
|
|
50
50
|
const acc = this.account();
|
|
51
|
+
const slug = this.requireAppSlug();
|
|
51
52
|
const body = {
|
|
52
53
|
pat: acc.pat,
|
|
53
54
|
kind: "complete",
|
|
54
|
-
|
|
55
|
+
app_slug: slug
|
|
55
56
|
};
|
|
56
|
-
if (!body.app_id) body.app_id = 1;
|
|
57
57
|
const minted = await this.callMint(acc.host, body);
|
|
58
58
|
const ms = {
|
|
59
59
|
appSessionToken: minted.app_session_token,
|
|
@@ -68,13 +68,14 @@ var LlmBridge = class {
|
|
|
68
68
|
/** Mint a kind=agent session — called from `agent.session.create`. */
|
|
69
69
|
async mintAgent(args) {
|
|
70
70
|
const acc = this.account();
|
|
71
|
+
const slug = this.requireAppSlug();
|
|
71
72
|
const submode = args.submode ?? "auto";
|
|
72
73
|
const body = {
|
|
73
74
|
pat: acc.pat,
|
|
74
75
|
kind: "agent",
|
|
75
76
|
submode,
|
|
76
77
|
fixed_client_id: args.fixed_client_id ?? args.fixedClientId ?? null,
|
|
77
|
-
|
|
78
|
+
app_slug: slug,
|
|
78
79
|
label: args.label ?? "anna-app dev",
|
|
79
80
|
quota_caps: args.quotaCaps ?? null
|
|
80
81
|
};
|
|
@@ -89,6 +90,11 @@ var LlmBridge = class {
|
|
|
89
90
|
this.mintedAgent.set(ms.appSessionUuid, ms);
|
|
90
91
|
return ms;
|
|
91
92
|
}
|
|
93
|
+
/** Throws a friendly error if no appSlug was wired into the bridge. */
|
|
94
|
+
requireAppSlug() {
|
|
95
|
+
if (!this.opts.appSlug) throw new Error("llm bridge has no app_slug — the harness must register the dev app via POST /api/v1/anna-apps/dev/apps/register before minting sessions. (Run `anna-app login` once, then `anna-app dev` will auto-register the manifest slug.)");
|
|
96
|
+
return this.opts.appSlug;
|
|
97
|
+
}
|
|
92
98
|
async callMint(host, body) {
|
|
93
99
|
const url = `${canonicalHost(host)}/api/v1/anna-apps/dev/session/mint`;
|
|
94
100
|
const res = await fetch(url, {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { credentialsAreLooselyPermissioned, maskPat, readCredentials } from "./credentials-
|
|
1
|
+
import { credentialsAreLooselyPermissioned, maskPat, readCredentials } from "./credentials-BTv2IfUZ.js";
|
|
2
2
|
|
|
3
3
|
//#region src/commands/whoami.ts
|
|
4
4
|
async function runWhoami(opts = {}) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anna-ai/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Anna App developer CLI: scaffold, validate, harness (Phase 2 MVP: init + validate).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"prepublishOnly": "pnpm lint && pnpm test && pnpm build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@anna-ai/app-runtime": "^0.
|
|
36
|
-
"@anna-ai/app-schema": "^0.
|
|
35
|
+
"@anna-ai/app-runtime": "^0.2.0",
|
|
36
|
+
"@anna-ai/app-schema": "^0.4.0",
|
|
37
37
|
"ajv": "^8.17.1",
|
|
38
38
|
"ajv-formats": "^3.0.1",
|
|
39
39
|
"commander": "^12.1.0",
|
package/dist/bridge-BIO7ilgO.js
DELETED
|
File without changes
|
|
File without changes
|