@aigne/cli 1.48.4-beta.4 → 1.49.0-beta.10

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.
Files changed (33) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/dist/commands/aigne.js +2 -0
  3. package/dist/commands/app.d.ts +29 -15
  4. package/dist/commands/app.js +111 -106
  5. package/dist/commands/create.js +3 -2
  6. package/dist/commands/deploy.js +3 -2
  7. package/dist/commands/eval.d.ts +11 -0
  8. package/dist/commands/eval.js +109 -0
  9. package/dist/commands/run.js +4 -3
  10. package/dist/tracer/terminal.js +7 -6
  11. package/dist/utils/evaluation/core.d.ts +8 -0
  12. package/dist/utils/evaluation/core.js +80 -0
  13. package/dist/utils/evaluation/dataset.d.ts +15 -0
  14. package/dist/utils/evaluation/dataset.js +61 -0
  15. package/dist/utils/evaluation/evaluator.d.ts +9 -0
  16. package/dist/utils/evaluation/evaluator.js +107 -0
  17. package/dist/utils/evaluation/reporter.d.ts +28 -0
  18. package/dist/utils/evaluation/reporter.js +221 -0
  19. package/dist/utils/evaluation/runner.d.ts +16 -0
  20. package/dist/utils/evaluation/runner.js +129 -0
  21. package/dist/utils/evaluation/type.d.ts +68 -0
  22. package/dist/utils/load-aigne.d.ts +2 -1
  23. package/dist/utils/load-aigne.js +7 -7
  24. package/dist/utils/workers/run-aigne-in-child-process-worker.d.ts +18 -0
  25. package/dist/utils/workers/run-aigne-in-child-process-worker.js +72 -0
  26. package/dist/utils/workers/run-aigne-in-child-process.d.ts +14 -0
  27. package/dist/utils/workers/run-aigne-in-child-process.js +30 -0
  28. package/dist/utils/yargs.d.ts +1 -1
  29. package/package.json +12 -9
  30. package/dist/utils/workers/load-aigne-worker.js +0 -13
  31. package/dist/utils/workers/load-aigne.d.ts +0 -2
  32. package/dist/utils/workers/load-aigne.js +0 -24
  33. /package/dist/utils/{workers/load-aigne-worker.d.ts → evaluation/type.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,128 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.49.0-beta.10](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.49.0-beta.9...cli-v1.49.0-beta.10) (2025-09-27)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **cli:** resolve input schema not working for run command ([#557](https://github.com/AIGNE-io/aigne-framework/issues/557)) ([6fa12b3](https://github.com/AIGNE-io/aigne-framework/commit/6fa12b3e068aaec28cf204c3a3f7c471bd2827ae))
9
+
10
+ ## [1.49.0-beta.9](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.49.0-beta.8...cli-v1.49.0-beta.9) (2025-09-26)
11
+
12
+
13
+ ### Features
14
+
15
+ * **cli:** add `--beta` `--target-version` `--force` options for `upgrade` command ([#555](https://github.com/AIGNE-io/aigne-framework/issues/555)) ([f9f0471](https://github.com/AIGNE-io/aigne-framework/commit/f9f04719020cca00bc3adbe8169c42422201df49))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **blocklet:** observability blocklet start failure ([#554](https://github.com/AIGNE-io/aigne-framework/issues/554)) ([8431d4d](https://github.com/AIGNE-io/aigne-framework/commit/8431d4d89a4b96f735f23e774e9545bbe1fd811c))
21
+ * **blocklet:** observability blocklet start failure ([#554](https://github.com/AIGNE-io/aigne-framework/issues/554)) ([8431d4d](https://github.com/AIGNE-io/aigne-framework/commit/8431d4d89a4b96f735f23e774e9545bbe1fd811c))
22
+
23
+
24
+ ### Dependencies
25
+
26
+ * The following workspace dependencies were updated
27
+ * dependencies
28
+ * @aigne/agent-library bumped to 1.21.46-beta.9
29
+ * @aigne/agentic-memory bumped to 1.0.46-beta.9
30
+ * @aigne/aigne-hub bumped to 0.10.0-beta.9
31
+ * @aigne/core bumped to 1.61.0-beta.8
32
+ * @aigne/default-memory bumped to 1.2.9-beta.9
33
+ * @aigne/observability-api bumped to 0.11.0-beta.1
34
+ * @aigne/openai bumped to 0.16.0-beta.9
35
+ * devDependencies
36
+ * @aigne/test-utils bumped to 0.5.53-beta.8
37
+
38
+ ## [1.49.0-beta.8](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.49.0-beta.7...cli-v1.49.0-beta.8) (2025-09-26)
39
+
40
+
41
+ ### Dependencies
42
+
43
+ * The following workspace dependencies were updated
44
+ * dependencies
45
+ * @aigne/agent-library bumped to 1.21.46-beta.8
46
+ * @aigne/agentic-memory bumped to 1.0.46-beta.8
47
+ * @aigne/aigne-hub bumped to 0.10.0-beta.8
48
+ * @aigne/core bumped to 1.61.0-beta.7
49
+ * @aigne/default-memory bumped to 1.2.9-beta.8
50
+ * @aigne/openai bumped to 0.16.0-beta.8
51
+ * devDependencies
52
+ * @aigne/test-utils bumped to 0.5.53-beta.7
53
+
54
+ ## [1.49.0-beta.7](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.49.0-beta.6...cli-v1.49.0-beta.7) (2025-09-26)
55
+
56
+
57
+ ### Bug Fixes
58
+
59
+ * **cli:** options.prompts should always available ([44ca0a6](https://github.com/AIGNE-io/aigne-framework/commit/44ca0a65d910fbd327b89d2f3dfe38ab7d1be7df))
60
+
61
+
62
+ ### Dependencies
63
+
64
+ * The following workspace dependencies were updated
65
+ * dependencies
66
+ * @aigne/agent-library bumped to 1.21.46-beta.7
67
+ * @aigne/agentic-memory bumped to 1.0.46-beta.7
68
+ * @aigne/aigne-hub bumped to 0.10.0-beta.7
69
+ * @aigne/core bumped to 1.61.0-beta.6
70
+ * @aigne/default-memory bumped to 1.2.9-beta.7
71
+ * @aigne/openai bumped to 0.16.0-beta.7
72
+ * devDependencies
73
+ * @aigne/test-utils bumped to 0.5.53-beta.6
74
+
75
+ ## [1.49.0-beta.6](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.49.0-beta.5...cli-v1.49.0-beta.6) (2025-09-25)
76
+
77
+
78
+ ### Features
79
+
80
+ * **blocklet:** add token and cost summary for tracing list ([#543](https://github.com/AIGNE-io/aigne-framework/issues/543)) ([5e78919](https://github.com/AIGNE-io/aigne-framework/commit/5e789199b8183cf9c48339ec8163faec001ca64c))
81
+
82
+
83
+ ### Dependencies
84
+
85
+ * The following workspace dependencies were updated
86
+ * dependencies
87
+ * @aigne/agent-library bumped to 1.21.46-beta.6
88
+ * @aigne/agentic-memory bumped to 1.0.46-beta.6
89
+ * @aigne/aigne-hub bumped to 0.10.0-beta.6
90
+ * @aigne/core bumped to 1.61.0-beta.5
91
+ * @aigne/default-memory bumped to 1.2.9-beta.6
92
+ * @aigne/observability-api bumped to 0.11.0-beta
93
+ * @aigne/openai bumped to 0.16.0-beta.6
94
+ * devDependencies
95
+ * @aigne/test-utils bumped to 0.5.53-beta.5
96
+
97
+ ## [1.49.0-beta.5](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.48.4-beta.5...cli-v1.49.0-beta.5) (2025-09-25)
98
+
99
+
100
+ ### Features
101
+
102
+ * **cli:** add new eval command for assessing AI agent performance using custom datasets ([#535](https://github.com/AIGNE-io/aigne-framework/issues/535)) ([9da967b](https://github.com/AIGNE-io/aigne-framework/commit/9da967b01ef9eeee4c5e1242934cf08e14815753))
103
+
104
+
105
+ ### Dependencies
106
+
107
+ * The following workspace dependencies were updated
108
+ * dependencies
109
+ * @aigne/agent-library bumped to 1.21.46-beta.5
110
+ * @aigne/agentic-memory bumped to 1.0.46-beta.5
111
+ * @aigne/aigne-hub bumped to 0.10.0-beta.5
112
+ * @aigne/core bumped to 1.61.0-beta.4
113
+ * @aigne/default-memory bumped to 1.2.9-beta.5
114
+ * @aigne/observability-api bumped to 0.10.5-beta
115
+ * @aigne/openai bumped to 0.16.0-beta.5
116
+ * devDependencies
117
+ * @aigne/test-utils bumped to 0.5.53-beta.4
118
+
119
+ ## [1.48.4-beta.5](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.48.4-beta.4...cli-v1.48.4-beta.5) (2025-09-24)
120
+
121
+
122
+ ### Bug Fixes
123
+
124
+ * replace import.meta.dirname with Node 20 compatible dirname approach ([#541](https://github.com/AIGNE-io/aigne-framework/issues/541)) ([8a4fb26](https://github.com/AIGNE-io/aigne-framework/commit/8a4fb2649e88791444a7d4b3ddf9addcec2b666a))
125
+
3
126
  ## [1.48.4-beta.4](https://github.com/AIGNE-io/aigne-framework/compare/cli-v1.48.4-beta.3...cli-v1.48.4-beta.4) (2025-09-24)
4
127
 
5
128
 
@@ -4,6 +4,7 @@ import { asciiLogo } from "../utils/ascii-logo.js";
4
4
  import { createAppCommands } from "./app.js";
5
5
  import { createCreateCommand } from "./create.js";
6
6
  import { createDeployCommands } from "./deploy.js";
7
+ import { createEvalCommand } from "./eval.js";
7
8
  import { createHubCommand } from "./hub.js";
8
9
  import { createObservabilityCommand } from "./observe.js";
9
10
  import { createRunCommand } from "./run.js";
@@ -15,6 +16,7 @@ export function createAIGNECommand(options) {
15
16
  .usage(`${asciiLogo}\n$0 <command> [options]`)
16
17
  .version(AIGNE_CLI_VERSION)
17
18
  .command(createRunCommand(options))
19
+ .command(createEvalCommand(options))
18
20
  .command(createTestCommand(options))
19
21
  .command(createCreateCommand())
20
22
  .command(createServeMCPCommand(options))
@@ -1,27 +1,41 @@
1
- import type { Agent, AIGNE, Message } from "@aigne/core";
2
1
  import type { CommandModule } from "yargs";
2
+ import { type AgentInChildProcess, type LoadAIGNEInChildProcessResult } from "../utils/workers/run-aigne-in-child-process.js";
3
3
  import { type AgentRunCommonOptions } from "../utils/yargs.js";
4
4
  export declare function createAppCommands(): CommandModule[];
5
5
  export declare const agentCommandModule: ({ dir, agent, }: {
6
6
  dir: string;
7
- agent: Agent;
7
+ agent: AgentInChildProcess;
8
8
  }) => CommandModule<unknown, AgentRunCommonOptions>;
9
- export declare function invokeCLIAgentFromDir(options: {
10
- dir: string;
11
- agent: string;
12
- input: Message & AgentRunCommonOptions;
13
- }): Promise<void>;
14
- export declare function loadApplication({ name, dir, forceUpgrade, }: {
15
- name: string;
16
- dir?: string;
17
- forceUpgrade?: boolean;
18
- }): Promise<{
19
- aigne: AIGNE;
9
+ interface LoadApplicationOptions {
10
+ packageName: string;
20
11
  dir: string;
12
+ install?: boolean;
13
+ }
14
+ interface LoadApplicationResult {
15
+ aigne: LoadAIGNEInChildProcessResult;
21
16
  version: string;
22
17
  isCache?: boolean;
18
+ }
19
+ export declare function loadApplication(options: LoadApplicationOptions & {
20
+ install: true;
21
+ }): Promise<LoadApplicationResult>;
22
+ export declare function loadApplication(options: LoadApplicationOptions & {
23
+ install?: false;
24
+ }): Promise<LoadApplicationResult | null>;
25
+ export declare function installApp({ dir, packageName, beta, version, }: {
26
+ dir: string;
27
+ packageName: string;
28
+ beta?: boolean;
29
+ version?: string;
30
+ }): Promise<{
31
+ url: string;
32
+ version: string;
23
33
  }>;
24
- export declare function getNpmTgzInfo(name: string): Promise<{
34
+ export declare function getNpmTgzInfo(name: string, { version, beta }?: {
35
+ version?: string;
36
+ beta?: boolean;
37
+ }): Promise<{
25
38
  version: string;
26
- url: any;
39
+ url: string;
27
40
  }>;
41
+ export {};
@@ -1,16 +1,14 @@
1
- import assert from "node:assert";
2
1
  import { spawn } from "node:child_process";
3
2
  import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
4
3
  import { homedir } from "node:os";
5
4
  import { join } from "node:path";
6
5
  import { logger } from "@aigne/core/utils/logger.js";
6
+ import { jsonSchemaToZod } from "@aigne/json-schema-to-zod";
7
7
  import { Listr, PRESET_TIMER } from "@aigne/listr2";
8
8
  import { joinURL } from "ufo";
9
9
  import { downloadAndExtract } from "../utils/download.js";
10
- import { loadAIGNE } from "../utils/load-aigne.js";
11
- import { runAgentWithAIGNE } from "../utils/run-with-aigne.js";
12
- import { safeLoadAIGNE } from "../utils/workers/load-aigne.js";
13
- import { parseAgentInput, withAgentInputSchema, } from "../utils/yargs.js";
10
+ import { runAIGNEInChildProcess, } from "../utils/workers/run-aigne-in-child-process.js";
11
+ import { withAgentInputSchema } from "../utils/yargs.js";
14
12
  import { serveMCPServerFromDir } from "./serve-mcp.js";
15
13
  const NPM_PACKAGE_CACHE_TIME_MS = 1000 * 60 * 60 * 24; // 1 day
16
14
  /**
@@ -23,11 +21,13 @@ function shouldUseBetaApps() {
23
21
  const builtinApps = [
24
22
  {
25
23
  name: "doc-smith",
24
+ packageName: "@aigne/doc-smith",
26
25
  describe: "Generate and maintain project docs — powered by agents.",
27
26
  aliases: ["docsmith", "doc"],
28
27
  },
29
28
  {
30
29
  name: "web-smith",
30
+ packageName: "@aigne/web-smith",
31
31
  describe: "Generate and maintain project website pages — powered by agents.",
32
32
  aliases: ["websmith", "web"],
33
33
  },
@@ -38,30 +38,28 @@ export function createAppCommands() {
38
38
  describe: app.describe,
39
39
  aliases: app.aliases,
40
40
  builder: async (yargs) => {
41
- const { aigne, dir, version, isCache } = await loadApplication({
42
- name: app.name,
43
- });
44
- yargs
45
- .option("model", {
46
- type: "string",
47
- description: "Model to use for the application, example: openai:gpt-4.1 or google:gemini-2.5-flash",
48
- })
49
- .command(serveMcpCommandModule({ name: app.name, dir }))
50
- .command(upgradeCommandModule({
51
- name: app.name,
41
+ const dir = join(homedir(), ".aigne", "registry.npmjs.org", app.packageName);
42
+ const { aigne, version } = await loadApplication({
52
43
  dir,
53
- isLatest: !isCache,
54
- version,
55
- }));
56
- if (aigne.cli.chat) {
44
+ packageName: app.packageName,
45
+ install: true,
46
+ });
47
+ if (aigne.cli?.chat) {
57
48
  yargs.command({
58
49
  ...agentCommandModule({ dir, agent: aigne.cli.chat }),
59
50
  command: "$0",
60
51
  });
61
52
  }
62
- for (const agent of aigne.cli.agents) {
53
+ for (const agent of aigne.cli?.agents ?? []) {
63
54
  yargs.command(agentCommandModule({ dir, agent }));
64
55
  }
56
+ yargs
57
+ .option("model", {
58
+ type: "string",
59
+ description: "Model to use for the application, example: openai:gpt-4.1 or google:gemini-2.5-flash",
60
+ })
61
+ .command(serveMcpCommandModule({ name: app.name, dir }))
62
+ .command(upgradeCommandModule({ packageName: app.packageName, dir }));
65
63
  yargs.version(`${app.name} v${version}`).alias("version", "v");
66
64
  return yargs.demandCommand();
67
65
  },
@@ -92,18 +90,39 @@ const serveMcpCommandModule = ({ name, dir, }) => ({
92
90
  await serveMCPServerFromDir({ ...options, dir });
93
91
  },
94
92
  });
95
- const upgradeCommandModule = ({ name, dir, isLatest, version, }) => ({
93
+ const upgradeCommandModule = ({ packageName, dir, }) => ({
96
94
  command: "upgrade",
97
- describe: `Upgrade ${name} to the latest version`,
98
- handler: async () => {
99
- if (!isLatest) {
100
- const result = await loadApplication({ name, dir, forceUpgrade: true });
101
- if (version !== result.version) {
102
- console.log(`\n✅ Upgraded ${name} to version ${result.version}`);
103
- return;
104
- }
95
+ describe: `Upgrade ${packageName} to the latest version`,
96
+ builder: (argv) => {
97
+ return argv
98
+ .option("beta", {
99
+ type: "boolean",
100
+ describe: "Use beta versions if available",
101
+ })
102
+ .option("target-version", {
103
+ type: "string",
104
+ describe: "Specify a version to upgrade to (default is latest)",
105
+ alias: ["to", "target"],
106
+ })
107
+ .option("force", {
108
+ type: "boolean",
109
+ describe: "Force upgrade even if already at latest version",
110
+ default: false,
111
+ });
112
+ },
113
+ handler: async ({ beta, targetVersion, force }) => {
114
+ beta ??= shouldUseBetaApps();
115
+ let app = await loadApplication({ packageName, dir });
116
+ const npm = await getNpmTgzInfo(packageName, { beta, version: targetVersion });
117
+ if (!app || force || npm.version !== app.version) {
118
+ if (force)
119
+ await rm(dir, { force: true, recursive: true });
120
+ await installApp({ packageName, dir, beta, version: targetVersion });
121
+ app = await loadApplication({ dir, packageName, install: true });
122
+ console.log(`\n✅ Upgraded ${packageName} to version ${app.version}`);
123
+ return;
105
124
  }
106
- console.log(`\n✅ ${name} is already at the latest version (${version})`);
125
+ console.log(`\n✅ ${packageName} is already at the latest version (${app.version})`);
107
126
  },
108
127
  });
109
128
  export const agentCommandModule = ({ dir, agent, }) => {
@@ -111,76 +130,76 @@ export const agentCommandModule = ({ dir, agent, }) => {
111
130
  command: agent.name,
112
131
  aliases: agent.alias || [],
113
132
  describe: agent.description || "",
114
- builder: async (yargs) => withAgentInputSchema(yargs, agent),
133
+ builder: async (yargs) => {
134
+ return withAgentInputSchema(yargs, { inputSchema: jsonSchemaToZod(agent.inputSchema) });
135
+ },
115
136
  handler: async (options) => {
116
137
  if (options.logLevel)
117
138
  logger.level = options.logLevel;
118
- await invokeCLIAgentFromDir({ dir, agent: agent.name, input: options });
139
+ await runAIGNEInChildProcess("invokeCLIAgentFromDir", {
140
+ dir,
141
+ agent: agent.name,
142
+ input: options,
143
+ });
119
144
  process.exit(0);
120
145
  },
121
146
  };
122
147
  };
123
- export async function invokeCLIAgentFromDir(options) {
124
- const aigne = await loadAIGNE({
125
- path: options.dir,
126
- modelOptions: options.input,
127
- });
128
- try {
129
- const { chat } = aigne.cli;
130
- const agent = chat && chat.name === options.agent
131
- ? chat
132
- : aigne.cli.agents[options.agent] ||
133
- aigne.agents[options.agent] ||
134
- aigne.skills[options.agent] ||
135
- aigne.mcpServer.agents[options.agent];
136
- assert(agent, `Agent ${options.agent} not found in ${options.dir}`);
137
- const input = await parseAgentInput(options.input, agent);
138
- await runAgentWithAIGNE(aigne, agent, {
139
- ...options.input,
140
- input,
141
- chat: agent === chat || options.input.chat,
142
- });
143
- }
144
- finally {
145
- await aigne.shutdown();
146
- }
147
- }
148
- export async function loadApplication({ name, dir, forceUpgrade = false, }) {
149
- name = `@aigne/${name}`;
150
- dir ??= join(homedir(), ".aigne", "registry.npmjs.org", name);
151
- let check = forceUpgrade ? undefined : await isInstallationAvailable(dir);
152
- if (check?.available) {
153
- const aigne = await safeLoadAIGNE(dir).catch((error) => {
154
- console.warn(`⚠️ Failed to load ${name}, trying to reinstall:`, error.message);
148
+ export async function loadApplication(options) {
149
+ const { dir, packageName } = options;
150
+ const check = await checkInstallation(dir);
151
+ if (check && !check.expired) {
152
+ const aigne = await runAIGNEInChildProcess("loadAIGNE", dir).catch((error) => {
153
+ console.warn(`⚠️ Failed to load ${packageName}, trying to reinstall:`, error.message);
155
154
  });
156
155
  if (aigne) {
157
- return {
158
- aigne,
159
- dir,
160
- version: check.version,
161
- isCache: true,
162
- };
156
+ return { aigne, version: check.version, isCache: true };
163
157
  }
164
- check = undefined;
165
158
  }
166
- const result = await new Listr([
159
+ if (!options.install)
160
+ return null;
161
+ const result = await installApp({ dir, packageName, beta: check?.version?.includes("beta") });
162
+ return {
163
+ aigne: await runAIGNEInChildProcess("loadAIGNE", dir),
164
+ version: result.version,
165
+ };
166
+ }
167
+ async function readInstallationMetadata(dir) {
168
+ return safeParseJSON(await readFile(join(dir, ".aigne-cli.json"), "utf-8").catch(() => "{}"));
169
+ }
170
+ async function writeInstallationMetadata(dir, metadata) {
171
+ await writeFile(join(dir, ".aigne-cli.json"), JSON.stringify(metadata, null, 2));
172
+ }
173
+ async function checkInstallation(dir, { cacheTimeMs = NPM_PACKAGE_CACHE_TIME_MS } = {}) {
174
+ const s = await stat(join(dir, "package.json")).catch(() => null);
175
+ if (!s)
176
+ return null;
177
+ const version = safeParseJSON(await readFile(join(dir, "package.json"), "utf-8"))?.version;
178
+ if (!version)
179
+ return null;
180
+ const installedAt = (await readInstallationMetadata(dir))?.installedAt;
181
+ if (!installedAt)
182
+ return null;
183
+ const now = Date.now();
184
+ const expired = now - installedAt > cacheTimeMs;
185
+ return { version, expired };
186
+ }
187
+ export async function installApp({ dir, packageName, beta, version, }) {
188
+ return await new Listr([
167
189
  {
168
- title: `Fetching ${name} metadata`,
190
+ title: `Fetching ${packageName} metadata`,
169
191
  task: async (ctx, task) => {
170
- const info = await getNpmTgzInfo(name);
171
- Object.assign(ctx, info);
172
- const useBeta = shouldUseBetaApps();
173
- if (useBeta && ctx.version.includes("beta")) {
174
- task.title = `Fetching ${name} metadata (using beta version)`;
192
+ if (beta) {
193
+ task.title = `Fetching ${packageName} metadata (using beta version)`;
175
194
  }
195
+ const info = await getNpmTgzInfo(packageName, { beta, version });
196
+ Object.assign(ctx, info);
176
197
  },
177
198
  },
178
199
  {
179
- title: `Downloading ${name}`,
180
- skip: (ctx) => ctx.version === check?.version,
200
+ title: `Downloading ${packageName}`,
181
201
  task: async (ctx, task) => {
182
- task.title = `Downloading ${name}(v${ctx.version})`;
183
- await rm(dir, { force: true, recursive: true });
202
+ task.title = `Downloading ${packageName} (v${ctx.version})`;
184
203
  await mkdir(dir, { recursive: true });
185
204
  await downloadAndExtract(ctx.url, dir, { strip: 1 });
186
205
  },
@@ -195,6 +214,7 @@ export async function loadApplication({ name, dir, forceUpgrade = false, }) {
195
214
  task.output = last;
196
215
  },
197
216
  });
217
+ await writeInstallationMetadata(dir, { installedAt: Date.now() });
198
218
  },
199
219
  },
200
220
  ], {
@@ -204,25 +224,6 @@ export async function loadApplication({ name, dir, forceUpgrade = false, }) {
204
224
  timer: PRESET_TIMER,
205
225
  },
206
226
  }).run();
207
- return {
208
- aigne: await safeLoadAIGNE(dir),
209
- dir,
210
- version: result.version,
211
- };
212
- }
213
- async function isInstallationAvailable(dir, { cacheTimeMs = NPM_PACKAGE_CACHE_TIME_MS } = {}) {
214
- const s = await stat(join(dir, "package.json")).catch(() => null);
215
- if (!s)
216
- return null;
217
- const version = safeParseJSON(await readFile(join(dir, "package.json"), "utf-8"))?.version;
218
- if (!version)
219
- return null;
220
- const installedAt = safeParseJSON(await readFile(join(dir, ".aigne-cli.json"), "utf-8").catch(() => "{}"))?.installedAt;
221
- if (!installedAt)
222
- return null;
223
- const now = Date.now();
224
- const available = installedAt ? now - installedAt < cacheTimeMs : false;
225
- return { version, available };
226
227
  }
227
228
  async function installDependencies(dir, { log } = {}) {
228
229
  await new Promise((resolve, reject) => {
@@ -250,16 +251,20 @@ async function installDependencies(dir, { log } = {}) {
250
251
  }
251
252
  });
252
253
  });
253
- await writeFile(join(dir, ".aigne-cli.json"), JSON.stringify({ installedAt: Date.now() }, null, 2));
254
254
  }
255
- export async function getNpmTgzInfo(name) {
255
+ export async function getNpmTgzInfo(name, { version, beta } = {}) {
256
256
  const res = await fetch(joinURL("https://registry.npmjs.org", name));
257
257
  if (!res.ok)
258
258
  throw new Error(`Failed to fetch package info for ${name}: ${res.statusText}`);
259
259
  const data = await res.json();
260
- const useBeta = shouldUseBetaApps();
261
260
  let targetVersion;
262
- if (useBeta && data["dist-tags"].beta) {
261
+ if (version) {
262
+ if (!data.versions[version]) {
263
+ throw new Error(`Version ${version} of package ${name} not found`);
264
+ }
265
+ targetVersion = version;
266
+ }
267
+ else if (beta && data["dist-tags"].beta) {
263
268
  // Use beta version if available and beta flag is set
264
269
  targetVersion = data["dist-tags"].beta;
265
270
  }
@@ -1,6 +1,7 @@
1
1
  import { existsSync, mkdirSync, readdirSync } from "node:fs";
2
2
  import { cp } from "node:fs/promises";
3
- import { isAbsolute, join, relative, resolve } from "node:path";
3
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
4
5
  import inquirer from "inquirer";
5
6
  export function createCreateCommand() {
6
7
  return {
@@ -57,7 +58,7 @@ export function createCreateCommand() {
57
58
  },
58
59
  ]);
59
60
  mkdirSync(path, { recursive: true });
60
- const templatePath = join(import.meta.dirname, "../../templates", template);
61
+ const templatePath = join(dirname(fileURLToPath(import.meta.url)), "../../templates", template);
61
62
  if (!existsSync(templatePath))
62
63
  throw new Error(`Template "${template}" not found.`);
63
64
  const files = readdirSync(templatePath);
@@ -2,7 +2,8 @@ import { spawn } from "node:child_process";
2
2
  import { constants } from "node:fs";
3
3
  import { access, copyFile, mkdir, readdir, readFile, rm, writeFile } from "node:fs/promises";
4
4
  import { homedir } from "node:os";
5
- import { basename, isAbsolute, join, resolve } from "node:path";
5
+ import { basename, dirname, isAbsolute, join, resolve } from "node:path";
6
+ import { fileURLToPath } from "node:url";
6
7
  import { Listr } from "@aigne/listr2";
7
8
  import { input as inputInquirer, select as selectInquirer } from "@inquirer/prompts";
8
9
  import { ListrInquirerPromptAdapter } from "@listr2/prompt-adapter-inquirer";
@@ -119,7 +120,7 @@ export const deploy = async (path, endpoint) => {
119
120
  }
120
121
  await rm(deployRoot, { recursive: true, force: true });
121
122
  task.output = "Copying template files...";
122
- const templatePath = join(import.meta.dirname, "../../templates/blocklet");
123
+ const templatePath = join(dirname(fileURLToPath(import.meta.url)), "../../templates/blocklet");
123
124
  await copyDir(templatePath, deployRoot);
124
125
  await copyDir(path, agentDest);
125
126
  const specialFiles = [
@@ -0,0 +1,11 @@
1
+ import type { CommandModule } from "yargs";
2
+ export declare function createEvalCommand({ aigneFilePath, }?: {
3
+ aigneFilePath?: string;
4
+ }): CommandModule<unknown, {
5
+ path?: string;
6
+ agent?: string;
7
+ dataset?: string;
8
+ evaluator?: string;
9
+ concurrency?: number;
10
+ output?: string;
11
+ }>;