@aisa-one/cli 0.2.1 → 0.2.3
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/CHANGELOG.md +144 -1
- package/README.md +249 -102
- package/dist/api.d.ts +46 -1
- package/dist/api.js +77 -8
- package/dist/cache.d.ts +18 -0
- package/dist/cache.js +65 -0
- package/dist/catalog.d.ts +90 -0
- package/dist/catalog.js +101 -0
- package/dist/commands/account.d.ts +4 -1
- package/dist/commands/account.js +36 -6
- package/dist/commands/api.d.ts +18 -4
- package/dist/commands/api.js +357 -24
- package/dist/commands/cacheCmd.d.ts +2 -0
- package/dist/commands/cacheCmd.js +10 -0
- package/dist/commands/completionCmd.d.ts +7 -0
- package/dist/commands/completionCmd.js +37 -0
- package/dist/commands/configCmd.js +19 -1
- package/dist/commands/finance.d.ts +4 -0
- package/dist/commands/finance.js +212 -29
- package/dist/commands/models.js +6 -0
- package/dist/commands/run.d.ts +21 -0
- package/dist/commands/run.js +113 -6
- package/dist/commands/search.js +8 -3
- package/dist/commands/skills.d.ts +6 -2
- package/dist/commands/skills.js +189 -134
- package/dist/commands/twitter.js +2 -3
- package/dist/commands/video.d.ts +40 -0
- package/dist/commands/video.js +272 -55
- package/dist/completion.d.ts +26 -0
- package/dist/completion.js +293 -0
- package/dist/constants.d.ts +55 -5
- package/dist/constants.js +136 -11
- package/dist/index.js +86 -23
- package/dist/skills-registry.d.ts +64 -0
- package/dist/skills-registry.js +219 -0
- package/dist/types.d.ts +32 -1
- package/dist/utils/file.d.ts +5 -1
- package/dist/utils/file.js +5 -1
- package/dist/utils/pool.d.ts +8 -0
- package/dist/utils/pool.js +27 -0
- package/package.json +9 -3
- package/dist/agent/env-setup.d.ts +0 -5
- package/dist/agent/env-setup.js +0 -49
- package/dist/agent/index-client.d.ts +0 -7
- package/dist/agent/index-client.js +0 -22
- package/dist/agent/installer.d.ts +0 -19
- package/dist/agent/installer.js +0 -70
- package/dist/agent/setup-python.d.ts +0 -15
- package/dist/agent/setup-python.js +0 -51
- package/dist/commands/agent.d.ts +0 -37
- package/dist/commands/agent.js +0 -129
- package/tests/streaming.test.ts +0 -73
package/dist/commands/agent.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
-
import { existsSync } from "node:fs";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { execFile } from "node:child_process";
|
|
6
|
-
import { table, success, hint, truncate } from "../utils/display.js";
|
|
7
|
-
import { fetchIndex, requireAgent, siblingAssetUrl } from "../agent/index-client.js";
|
|
8
|
-
import { hermesRoot, profileDir, downloadArtifact, extractBundle, readBundleManifest, writeMarker, listInstalled, } from "../agent/installer.js";
|
|
9
|
-
import { collectEnv } from "../agent/env-setup.js";
|
|
10
|
-
import { runPythonSetup } from "../agent/setup-python.js";
|
|
11
|
-
const realExec = (cmd, args) => new Promise((resolve) => {
|
|
12
|
-
execFile(cmd, args, (err, stdout, stderr) => resolve({ code: err ? 1 : 0, stdout: String(stdout), stderr: String(stderr) }));
|
|
13
|
-
});
|
|
14
|
-
export async function agentListAction(_opts, deps = {}) {
|
|
15
|
-
const index = await fetchIndex(deps.fetchImpl);
|
|
16
|
-
const rows = Object.entries(index.agents).sort(([a], [b]) => a.localeCompare(b))
|
|
17
|
-
.map(([id, e]) => [id, e.name, e.latest, truncate(e.description, 60)]);
|
|
18
|
-
console.log(table(["ID", "NAME", "LATEST", "DESCRIPTION"], rows));
|
|
19
|
-
hint(`install one with: aisa agent install <id>`);
|
|
20
|
-
return index;
|
|
21
|
-
}
|
|
22
|
-
export async function agentInfoAction(id, deps = {}) {
|
|
23
|
-
const index = await fetchIndex(deps.fetchImpl);
|
|
24
|
-
const e = requireAgent(index, id);
|
|
25
|
-
console.log(`${chalk.bold(e.name)} (${id})`);
|
|
26
|
-
console.log(` ${e.description}`);
|
|
27
|
-
console.log(` repo: https://github.com/${e.repo}`);
|
|
28
|
-
console.log(` latest: ${e.latest}`);
|
|
29
|
-
for (const [v, spec] of Object.entries(e.versions))
|
|
30
|
-
console.log(` ${v}: targets ${Object.keys(spec.targets).join(", ")}`);
|
|
31
|
-
hint(`install with: aisa agent install ${id}`);
|
|
32
|
-
return e;
|
|
33
|
-
}
|
|
34
|
-
export async function agentInstallAction(id, opts, deps = {}) {
|
|
35
|
-
const runtime = opts.runtime ?? "hermes";
|
|
36
|
-
if (runtime !== "hermes")
|
|
37
|
-
throw new Error(`runtime "${runtime}" not supported yet — v1 supports: hermes`);
|
|
38
|
-
if (!existsSync(hermesRoot()))
|
|
39
|
-
throw new Error(`hermes not found at ${hermesRoot()} — install it first:\n` +
|
|
40
|
-
` curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash`);
|
|
41
|
-
const index = await fetchIndex(deps.fetchImpl);
|
|
42
|
-
const entry = requireAgent(index, id);
|
|
43
|
-
const version = opts.version ?? entry.latest;
|
|
44
|
-
const versionSpec = entry.versions[version];
|
|
45
|
-
if (!versionSpec)
|
|
46
|
-
throw new Error(`version ${version} not found for ${id} — available: ${Object.keys(entry.versions).join(", ")}`);
|
|
47
|
-
const artifact = versionSpec.targets[runtime];
|
|
48
|
-
if (!artifact)
|
|
49
|
-
throw new Error(`no ${runtime} artifact for ${id}@${version}`);
|
|
50
|
-
const dir = profileDir(id);
|
|
51
|
-
const existingEnv = existsSync(join(dir, ".env"))
|
|
52
|
-
? await readFile(join(dir, ".env"), "utf8") : null;
|
|
53
|
-
const buf = await downloadArtifact(artifact.url, artifact.sha256, deps.fetchImpl);
|
|
54
|
-
await extractBundle(buf, dir);
|
|
55
|
-
const manifest = await readBundleManifest(dir);
|
|
56
|
-
const envText = await collectEnv(manifest, existingEnv, { prompt: deps.prompt });
|
|
57
|
-
await writeFile(join(dir, ".env"), envText);
|
|
58
|
-
const exec = deps.exec ?? realExec;
|
|
59
|
-
// system vars go to render as process env, never into .env — new render.sh
|
|
60
|
-
// reads them from the bundled agent.json itself, old artifacts (≤1.0.4)
|
|
61
|
-
// still require them in the environment
|
|
62
|
-
const r = await exec("env", [
|
|
63
|
-
`PROFILE_ID=${manifest.id}`,
|
|
64
|
-
`MODEL_DEFAULT=${manifest.models.default}`,
|
|
65
|
-
`MODEL_PROVIDER=${manifest.models.provider}`,
|
|
66
|
-
"bash", join(dir, "scripts", "render.sh"), dir,
|
|
67
|
-
]);
|
|
68
|
-
if (r.code !== 0)
|
|
69
|
-
throw new Error(`render failed: ${r.stderr}`);
|
|
70
|
-
await runPythonSetup(manifest, dir, exec);
|
|
71
|
-
await writeMarker(dir, {
|
|
72
|
-
id, version, target: "hermes",
|
|
73
|
-
pinned: !!opts.version || manifest.update.channel === "pinned",
|
|
74
|
-
});
|
|
75
|
-
success(`installed ${entry.name} ${version} -> ${dir}`);
|
|
76
|
-
hint(`start it with: hermes --profile ${id}`);
|
|
77
|
-
}
|
|
78
|
-
export async function agentUpdateAction(id, _opts, deps = {}) {
|
|
79
|
-
const installed = await listInstalled();
|
|
80
|
-
const targets = id ? installed.filter((i) => i.marker.id === id) : installed;
|
|
81
|
-
if (id && targets.length === 0)
|
|
82
|
-
throw new Error(`agent "${id}" is not installed (no .agentspec.json marker found)`);
|
|
83
|
-
if (targets.length === 0) {
|
|
84
|
-
hint("no installed agents found");
|
|
85
|
-
return [];
|
|
86
|
-
}
|
|
87
|
-
const index = await fetchIndex(deps.fetchImpl);
|
|
88
|
-
const results = [];
|
|
89
|
-
for (const { marker } of targets) {
|
|
90
|
-
if (marker.pinned) {
|
|
91
|
-
console.log(`${marker.id}: pinned at ${marker.version} — skipping`);
|
|
92
|
-
results.push({ id: marker.id, from: marker.version, to: marker.version, status: "pinned" });
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
const entry = index.agents[marker.id];
|
|
96
|
-
if (!entry || entry.latest === marker.version) {
|
|
97
|
-
results.push({ id: marker.id, from: marker.version, to: marker.version, status: "up-to-date" });
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
await agentInstallAction(marker.id, {}, deps); // install 已保留 .env、更新 marker
|
|
101
|
-
results.push({ id: marker.id, from: marker.version, to: entry.latest, status: "updated" });
|
|
102
|
-
}
|
|
103
|
-
for (const r of results)
|
|
104
|
-
if (r.status === "updated")
|
|
105
|
-
success(`${r.id}: ${r.from} -> ${r.to}`);
|
|
106
|
-
return results;
|
|
107
|
-
}
|
|
108
|
-
export async function agentGuideAction(id, opts, deps = {}) {
|
|
109
|
-
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
110
|
-
const index = await fetchIndex(deps.fetchImpl);
|
|
111
|
-
const entry = requireAgent(index, id);
|
|
112
|
-
const artifact = entry.versions[entry.latest]?.targets["hermes"];
|
|
113
|
-
if (!artifact)
|
|
114
|
-
throw new Error(`no hermes artifact for ${id}@${entry.latest}`);
|
|
115
|
-
// 优先读索引携带的资产 URL(2026-07-15 起 publish 写入);老条目回落到
|
|
116
|
-
// legacy 裸文件名拼接,保证旧版本 Release 仍可用
|
|
117
|
-
const url = opts.md
|
|
118
|
-
? (artifact.installMd ?? siblingAssetUrl(artifact.url, "INSTALL.md"))
|
|
119
|
-
: (artifact.guidePrompt ?? siblingAssetUrl(artifact.url, "guide-prompt.txt"));
|
|
120
|
-
const filename = url.split("/").pop();
|
|
121
|
-
const res = await fetchImpl(url);
|
|
122
|
-
if (!res.ok)
|
|
123
|
-
throw new Error(`failed to fetch ${filename} (${res.status}): ${url}`);
|
|
124
|
-
const text = await res.text();
|
|
125
|
-
console.log(text);
|
|
126
|
-
if (!opts.md)
|
|
127
|
-
hint("paste the text above into your local AI agent (Claude Code, hermes, …)");
|
|
128
|
-
return text;
|
|
129
|
-
}
|
package/tests/streaming.test.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { handleSSEStream } from "../src/utils/streaming.js";
|
|
3
|
-
|
|
4
|
-
function sseResponse(chunks: string[]): Response {
|
|
5
|
-
const encoder = new TextEncoder();
|
|
6
|
-
const stream = new ReadableStream<Uint8Array>({
|
|
7
|
-
start(controller) {
|
|
8
|
-
for (const chunk of chunks) {
|
|
9
|
-
controller.enqueue(encoder.encode(chunk));
|
|
10
|
-
}
|
|
11
|
-
controller.close();
|
|
12
|
-
},
|
|
13
|
-
});
|
|
14
|
-
return new Response(stream);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
describe("handleSSEStream", () => {
|
|
18
|
-
it("emits tokens from a native fetch Response body", async () => {
|
|
19
|
-
const res = sseResponse([
|
|
20
|
-
'data: {"choices":[{"delta":{"content":"Hello"}}]}\n\n',
|
|
21
|
-
'data: {"choices":[{"delta":{"content":" world"}}]}\n\n',
|
|
22
|
-
"data: [DONE]\n\n",
|
|
23
|
-
]);
|
|
24
|
-
|
|
25
|
-
const tokens: string[] = [];
|
|
26
|
-
let done = false;
|
|
27
|
-
await handleSSEStream(
|
|
28
|
-
res,
|
|
29
|
-
(t) => tokens.push(t),
|
|
30
|
-
() => {
|
|
31
|
-
done = true;
|
|
32
|
-
}
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
expect(tokens.join("")).toBe("Hello world");
|
|
36
|
-
expect(done).toBe(true);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("handles multi-byte characters split across chunks", async () => {
|
|
40
|
-
const encoder = new TextEncoder();
|
|
41
|
-
const line = encoder.encode(
|
|
42
|
-
'data: {"choices":[{"delta":{"content":"你好"}}]}\n\ndata: [DONE]\n\n'
|
|
43
|
-
);
|
|
44
|
-
// split in the middle of a multi-byte character
|
|
45
|
-
const stream = new ReadableStream<Uint8Array>({
|
|
46
|
-
start(controller) {
|
|
47
|
-
controller.enqueue(line.slice(0, 40));
|
|
48
|
-
controller.enqueue(line.slice(40));
|
|
49
|
-
controller.close();
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
const res = new Response(stream);
|
|
53
|
-
|
|
54
|
-
const tokens: string[] = [];
|
|
55
|
-
await handleSSEStream(res, (t) => tokens.push(t));
|
|
56
|
-
|
|
57
|
-
expect(tokens.join("")).toBe("你好");
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("reports usage to onDone", async () => {
|
|
61
|
-
const res = sseResponse([
|
|
62
|
-
'data: {"choices":[{"delta":{"content":"hi"}}],"usage":{"prompt_tokens":3,"completion_tokens":1}}\n\n',
|
|
63
|
-
"data: [DONE]\n\n",
|
|
64
|
-
]);
|
|
65
|
-
|
|
66
|
-
let usage: { prompt_tokens: number; completion_tokens: number } | undefined;
|
|
67
|
-
await handleSSEStream(res, () => {}, (u) => {
|
|
68
|
-
usage = u;
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
expect(usage).toEqual({ prompt_tokens: 3, completion_tokens: 1 });
|
|
72
|
-
});
|
|
73
|
-
});
|