agex 0.1.2 → 0.2.2

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 (2) hide show
  1. package/dist/cli.js +348 -337
  2. package/package.json +3 -2
package/dist/cli.js CHANGED
@@ -6,218 +6,117 @@ import {
6
6
  } from "./chunk-H3CMLOXO.js";
7
7
  import "./chunk-2ZRS4JND.js";
8
8
 
9
- // src/commands/proov.ts
10
- function printHelp() {
11
- console.log(`
12
- agex proov - Prove visual assertions with screenshots
13
-
14
- USAGE:
15
- agex proov "<assertion>" [options]
16
-
17
- OPTIONS:
18
- --agent, -a <name> Agent to use: cursor (default), claude, codex
19
- --url, -u <url> URL to navigate to
20
- --output, -o <dir> Output directory (default: ./proov-results)
21
- --video Enable video recording (default)
22
- --no-video Disable video recording
23
- --screenshots Enable screenshots (default)
24
- --no-screenshots Disable screenshots
25
- --model, -m <model> Model to use
26
- --timeout, -t <ms> Timeout in milliseconds
27
- --viewport <WxH> Viewport size (default: 1920x1080)
28
- --headless Run headless (default)
29
- --headed Show browser window
30
- --help, -h Show this help
9
+ // src/cli.ts
10
+ import { defineCommand as defineCommand5, runMain } from "citty";
31
11
 
32
- EXAMPLES:
33
- agex proov "prove the Google logo is on the homepage" --url https://google.com
34
- agex proov "verify login button exists" --agent claude --url https://example.com
35
- `);
36
- }
37
- function parseArgs(args) {
38
- const options = {};
39
- let assertion = "";
40
- for (let i = 0; i < args.length; i++) {
41
- const arg = args[i];
42
- if (arg === "--agent" || arg === "-a") {
43
- options.agent = args[++i];
44
- } else if (arg === "--url" || arg === "-u") {
45
- options.url = args[++i];
46
- } else if (arg === "--output" || arg === "-o") {
47
- options.outputDir = args[++i];
48
- } else if (arg === "--video") {
49
- options.video = true;
50
- } else if (arg === "--no-video") {
51
- options.video = false;
52
- } else if (arg === "--model" || arg === "-m") {
53
- options.model = args[++i];
54
- } else if (arg === "--timeout" || arg === "-t") {
55
- options.timeout = parseInt(args[++i], 10);
56
- } else if (arg === "--viewport") {
57
- const [width, height] = args[++i].split("x").map(Number);
58
- options.viewport = { width, height };
59
- } else if (arg === "--headless") {
60
- options.headless = true;
61
- } else if (arg === "--headed") {
62
- options.headless = false;
63
- } else if (arg === "--screenshots") {
64
- options.screenshots = true;
65
- } else if (arg === "--no-screenshots") {
66
- options.screenshots = false;
67
- } else if (arg === "--help" || arg === "-h") {
68
- printHelp();
69
- process.exit(0);
70
- } else if (!arg.startsWith("-")) {
71
- assertion = assertion ? `${assertion} ${arg}` : arg;
12
+ // src/commands/proov.ts
13
+ import { defineCommand } from "citty";
14
+ var proov_default = defineCommand({
15
+ meta: {
16
+ name: "proov",
17
+ description: "Prove visual assertions with screenshots"
18
+ },
19
+ args: {
20
+ assertion: {
21
+ type: "positional",
22
+ description: "The assertion to prove",
23
+ required: true
24
+ },
25
+ agent: {
26
+ type: "string",
27
+ alias: "a",
28
+ description: "Agent to use: cursor (default), claude, codex",
29
+ default: "cursor"
30
+ },
31
+ url: {
32
+ type: "string",
33
+ alias: "u",
34
+ description: "URL to navigate to"
35
+ },
36
+ output: {
37
+ type: "string",
38
+ alias: "o",
39
+ description: "Output directory",
40
+ default: "./proov-results"
41
+ },
42
+ video: {
43
+ type: "boolean",
44
+ description: "Enable video recording",
45
+ default: true
46
+ },
47
+ screenshots: {
48
+ type: "boolean",
49
+ description: "Enable screenshots",
50
+ default: true
51
+ },
52
+ model: {
53
+ type: "string",
54
+ alias: "m",
55
+ description: "Model to use"
56
+ },
57
+ timeout: {
58
+ type: "string",
59
+ alias: "t",
60
+ description: "Timeout in milliseconds"
61
+ },
62
+ viewport: {
63
+ type: "string",
64
+ description: "Viewport size (WxH)",
65
+ default: "1920x1080"
66
+ },
67
+ headless: {
68
+ type: "boolean",
69
+ description: "Run headless",
70
+ default: true
71
+ },
72
+ browser: {
73
+ type: "string",
74
+ alias: "b",
75
+ description: "Browser mode: mcp (default) or cli (agent-browser)",
76
+ default: "mcp"
72
77
  }
73
- }
74
- return { assertion, options };
75
- }
76
- async function runProov(args) {
77
- const { assertion, options } = parseArgs(args);
78
- if (!assertion) {
79
- console.error("Error: No assertion provided");
80
- printHelp();
81
- process.exit(1);
82
- }
83
- console.log("========================================");
84
- console.log("agex proov");
85
- console.log("========================================");
86
- console.log(`Agent: ${options.agent ?? "cursor"}`);
87
- console.log(`Task: ${assertion}`);
88
- if (options.url) {
89
- console.log(`URL: ${options.url}`);
90
- }
91
- console.log("========================================\n");
92
- const result = await proov(assertion, options);
93
- console.log("\n========================================");
94
- if (result.verdict === "pass") {
95
- console.log("\u2705 PASS");
96
- } else if (result.verdict === "fail") {
97
- console.log("\u274C FAIL");
98
- } else {
99
- console.log("\u23ED\uFE0F SKIP");
100
- }
101
- console.log(`Reason: ${result.reason}`);
102
- console.log(`Duration: ${result.durationMs}ms`);
103
- console.log(`Output: ${result.outputDir}`);
104
- console.log("========================================");
105
- process.exit(result.verdict === "pass" ? 0 : 1);
106
- }
107
-
108
- // src/commands/run.ts
109
- function printHelp2() {
110
- console.log(`
111
- agex run - Execute AI agent tasks
112
-
113
- USAGE:
114
- agex run --agent <name> "<prompt>" [options]
115
-
116
- OPTIONS:
117
- --agent, -a <name> Agent to use: cursor, claude, codex (required)
118
- --model, -m <model> Model to use
119
- --prompt, -p <text> Prompt (can also be positional)
120
- --install Run install command before agent
121
- --install-command Custom install command
122
- --require-api-key Require API key
123
- --no-approve-mcps Don't auto-approve MCPs
124
- --no-browser Disable browser
125
- --no-stream Disable streaming output
126
- --mode <mode> Output mode: text, json, debug
127
- --approval <policy> Approval policy
128
- --timeout <ms> Timeout in milliseconds
129
- --help, -h Show this help
130
-
131
- EXAMPLES:
132
- agex run --agent cursor "build a landing page"
133
- agex run --agent claude "refactor this function" --mode json
134
- `);
135
- }
136
- function parseArgs2(args) {
137
- let agent;
138
- let model;
139
- let prompt = "";
140
- let install = false;
141
- let installCommand;
142
- let timeoutMs;
143
- let requireApiKey = false;
144
- let approveMcps = true;
145
- let browser = true;
146
- let streamOutput = true;
147
- let outputMode = "text";
148
- let approvalPolicy;
149
- for (let i = 0; i < args.length; i += 1) {
150
- const arg = args[i];
151
- if (arg === "--help" || arg === "-h") {
152
- printHelp2();
153
- process.exit(0);
154
- } else if (arg === "--agent" || arg === "-a") {
155
- agent = args[i + 1];
156
- i += 1;
157
- } else if (arg === "--model" || arg === "-m") {
158
- model = args[i + 1];
159
- i += 1;
160
- } else if (arg === "--prompt" || arg === "-p") {
161
- prompt = args[i + 1] ?? "";
162
- i += 1;
163
- } else if (arg === "--install") {
164
- install = true;
165
- } else if (arg === "--install-command") {
166
- installCommand = args[i + 1];
167
- i += 1;
168
- } else if (arg === "--require-api-key") {
169
- requireApiKey = true;
170
- } else if (arg === "--no-approve-mcps") {
171
- approveMcps = false;
172
- } else if (arg === "--no-browser") {
173
- browser = false;
174
- } else if (arg === "--no-stream") {
175
- streamOutput = false;
176
- } else if (arg === "--mode") {
177
- const value = args[i + 1];
178
- if (value === "json" || value === "text" || value === "debug") {
179
- outputMode = value;
180
- }
181
- i += 1;
182
- } else if (arg === "--approval") {
183
- approvalPolicy = args[i + 1];
184
- i += 1;
185
- } else if (arg === "--timeout") {
186
- const value = Number(args[i + 1]);
187
- if (!Number.isNaN(value)) {
188
- timeoutMs = value;
189
- }
190
- i += 1;
78
+ },
79
+ async run({ args }) {
80
+ const [width, height] = args.viewport.split("x").map(Number);
81
+ const options = {
82
+ agent: args.agent,
83
+ url: args.url,
84
+ outputDir: args.output,
85
+ video: args.video,
86
+ screenshots: args.screenshots,
87
+ model: args.model,
88
+ timeout: args.timeout ? parseInt(args.timeout, 10) : void 0,
89
+ viewport: { width, height },
90
+ headless: args.headless
91
+ };
92
+ console.log("========================================");
93
+ console.log("agex proov");
94
+ console.log("========================================");
95
+ console.log(`Agent: ${options.agent}`);
96
+ console.log(`Task: ${args.assertion}`);
97
+ if (options.url) {
98
+ console.log(`URL: ${options.url}`);
99
+ }
100
+ console.log("========================================\n");
101
+ const result = await proov(args.assertion, options);
102
+ console.log("\n========================================");
103
+ if (result.verdict === "pass") {
104
+ console.log("\u2705 PASS");
105
+ } else if (result.verdict === "fail") {
106
+ console.log("\u274C FAIL");
191
107
  } else {
192
- prompt = prompt ? `${prompt} ${arg}` : arg;
108
+ console.log("\u23ED\uFE0F SKIP");
193
109
  }
110
+ console.log(`Reason: ${result.reason}`);
111
+ console.log(`Duration: ${result.durationMs}ms`);
112
+ console.log(`Output: ${result.outputDir}`);
113
+ console.log("========================================");
114
+ process.exit(result.verdict === "pass" ? 0 : 1);
194
115
  }
195
- if (!agent) {
196
- throw new Error("Missing --agent");
197
- }
198
- if (!prompt) {
199
- throw new Error("Missing prompt");
200
- }
201
- const quietOutput = outputMode === "json";
202
- if (quietOutput) {
203
- streamOutput = false;
204
- }
205
- return {
206
- agent,
207
- model,
208
- prompt,
209
- install,
210
- installCommand,
211
- requireApiKey,
212
- approveMcps,
213
- browser,
214
- streamOutput,
215
- quietOutput,
216
- outputMode,
217
- approvalPolicy,
218
- timeoutMs
219
- };
220
- }
116
+ });
117
+
118
+ // src/commands/run.ts
119
+ import { defineCommand as defineCommand2 } from "citty";
221
120
  function formatOutput(result, mode, wasStreamed) {
222
121
  switch (mode) {
223
122
  case "json":
@@ -233,155 +132,267 @@ ${JSON.stringify(result.json, null, 2)}`;
233
132
  return null;
234
133
  }
235
134
  }
236
- async function runRun(args) {
237
- const request = parseArgs2(args);
238
- const result = await runAgent(request);
239
- const output = formatOutput(result, request.outputMode, request.streamOutput ?? true);
240
- if (output !== null) {
241
- process.stdout.write(`${output}
135
+ var run_default = defineCommand2({
136
+ meta: {
137
+ name: "run",
138
+ description: "Execute AI agent tasks"
139
+ },
140
+ args: {
141
+ prompt: {
142
+ type: "positional",
143
+ description: "The prompt to execute",
144
+ required: true
145
+ },
146
+ agent: {
147
+ type: "string",
148
+ alias: "a",
149
+ description: "Agent to use: cursor, claude, codex",
150
+ required: true
151
+ },
152
+ model: {
153
+ type: "string",
154
+ alias: "m",
155
+ description: "Model to use"
156
+ },
157
+ install: {
158
+ type: "boolean",
159
+ description: "Run install command before agent",
160
+ default: false
161
+ },
162
+ installCommand: {
163
+ type: "string",
164
+ description: "Custom install command"
165
+ },
166
+ requireApiKey: {
167
+ type: "boolean",
168
+ description: "Require API key",
169
+ default: false
170
+ },
171
+ approveMcps: {
172
+ type: "boolean",
173
+ description: "Auto-approve MCPs",
174
+ default: true
175
+ },
176
+ browser: {
177
+ type: "boolean",
178
+ description: "Enable browser",
179
+ default: true
180
+ },
181
+ stream: {
182
+ type: "boolean",
183
+ description: "Enable streaming output",
184
+ default: true
185
+ },
186
+ mode: {
187
+ type: "string",
188
+ description: "Output mode: text, json, debug",
189
+ default: "text"
190
+ },
191
+ approval: {
192
+ type: "string",
193
+ description: "Approval policy: never, on-request, on-failure, untrusted"
194
+ },
195
+ timeout: {
196
+ type: "string",
197
+ description: "Timeout in milliseconds"
198
+ }
199
+ },
200
+ async run({ args }) {
201
+ const outputMode = args.mode;
202
+ const quietOutput = outputMode === "json";
203
+ const streamOutput = quietOutput ? false : args.stream;
204
+ const request = {
205
+ agent: args.agent,
206
+ prompt: args.prompt,
207
+ model: args.model,
208
+ install: args.install,
209
+ installCommand: args.installCommand,
210
+ requireApiKey: args.requireApiKey,
211
+ approveMcps: args.approveMcps,
212
+ browser: args.browser,
213
+ streamOutput,
214
+ quietOutput,
215
+ approvalPolicy: args.approval,
216
+ timeoutMs: args.timeout ? parseInt(args.timeout, 10) : void 0
217
+ };
218
+ const result = await runAgent(request);
219
+ const output = formatOutput(result, outputMode, streamOutput);
220
+ if (output !== null) {
221
+ process.stdout.write(`${output}
242
222
  `);
223
+ }
243
224
  }
244
- }
225
+ });
245
226
 
246
227
  // src/commands/review.ts
247
- function printHelp3() {
248
- console.log(`
249
- agex review - Review code changes
250
-
251
- USAGE:
252
- agex review --base <ref> --agent <name> [options]
253
-
254
- OPTIONS:
255
- --base <ref> Base branch/commit to compare against (required)
256
- --agent, -a <name> Agent to use: cursor, claude, codex (required)
257
- --model, -m <model> Model to use
258
- --no-worktree Exclude worktree changes
259
- --hypotheses <n> Number of hypotheses to generate
260
- --hint <text> Additional prompt hint
261
- --help, -h Show this help
228
+ import { defineCommand as defineCommand3 } from "citty";
229
+ var review_default = defineCommand3({
230
+ meta: {
231
+ name: "review",
232
+ description: "Review code changes"
233
+ },
234
+ args: {
235
+ base: {
236
+ type: "string",
237
+ description: "Base branch/commit to compare against",
238
+ required: true
239
+ },
240
+ agent: {
241
+ type: "string",
242
+ alias: "a",
243
+ description: "Agent to use: cursor, claude, codex",
244
+ required: true
245
+ },
246
+ model: {
247
+ type: "string",
248
+ alias: "m",
249
+ description: "Model to use"
250
+ },
251
+ worktree: {
252
+ type: "boolean",
253
+ description: "Include worktree changes",
254
+ default: true
255
+ },
256
+ hypotheses: {
257
+ type: "string",
258
+ description: "Number of hypotheses to generate"
259
+ },
260
+ hint: {
261
+ type: "string",
262
+ description: "Additional prompt hint"
263
+ }
264
+ },
265
+ async run({ args }) {
266
+ await runReview({
267
+ baseRef: args.base,
268
+ agent: args.agent,
269
+ model: args.model,
270
+ includeWorktree: args.worktree,
271
+ hypotheses: args.hypotheses ? parseInt(args.hypotheses, 10) : void 0,
272
+ promptHint: args.hint
273
+ });
274
+ }
275
+ });
262
276
 
263
- EXAMPLES:
264
- agex review --base main --agent cursor
265
- agex review --base HEAD~3 --agent claude --hint "focus on security"
266
- `);
277
+ // src/commands/browse.ts
278
+ import { defineCommand as defineCommand4 } from "citty";
279
+ import { execa } from "execa";
280
+ async function installBrowser() {
281
+ console.log("[agex browse] Browser not found. Installing Chromium...");
282
+ await execa("npx", ["--yes", "playwright", "install", "chromium"], { stdio: "inherit" });
283
+ console.log("[agex browse] Browser installed successfully.");
267
284
  }
268
- function parseArgs3(args) {
269
- let baseRef = "";
270
- let agent;
271
- let model;
272
- let includeWorktree = true;
273
- let hypotheses;
274
- let promptHint;
275
- for (let i = 0; i < args.length; i += 1) {
276
- const arg = args[i];
277
- if (arg === "--help" || arg === "-h") {
278
- printHelp3();
279
- process.exit(0);
280
- } else if (arg === "--base") {
281
- baseRef = args[i + 1] ?? "";
282
- i += 1;
283
- } else if (arg === "--agent" || arg === "-a") {
284
- agent = args[i + 1];
285
- i += 1;
286
- } else if (arg === "--model" || arg === "-m") {
287
- model = args[i + 1];
288
- i += 1;
289
- } else if (arg === "--no-worktree") {
290
- includeWorktree = false;
291
- } else if (arg === "--hypotheses") {
292
- const value = Number(args[i + 1]);
293
- if (!Number.isNaN(value)) {
294
- hypotheses = value;
295
- }
296
- i += 1;
297
- } else if (arg === "--hint") {
298
- promptHint = args[i + 1];
299
- i += 1;
285
+ async function runAgentBrowser(browserArgs) {
286
+ try {
287
+ const result = await execa("npx", ["--yes", "agent-browser", ...browserArgs], {
288
+ stdio: "pipe",
289
+ env: { ...process.env }
290
+ });
291
+ if (result.stdout) process.stdout.write(result.stdout);
292
+ if (result.stderr) process.stderr.write(result.stderr);
293
+ return { success: true, needsBrowserInstall: false };
294
+ } catch (error) {
295
+ const execaError = error;
296
+ const output = `${execaError.stdout ?? ""}${execaError.stderr ?? ""}`;
297
+ if (output.includes("Executable doesn't exist") || output.includes("npx playwright install")) {
298
+ return { success: false, needsBrowserInstall: true };
300
299
  }
300
+ if (execaError.stdout) process.stdout.write(execaError.stdout);
301
+ if (execaError.stderr) process.stderr.write(execaError.stderr);
302
+ return { success: false, needsBrowserInstall: false };
301
303
  }
302
- if (!baseRef) {
303
- throw new Error("Missing --base");
304
- }
305
- if (!agent) {
306
- throw new Error("Missing --agent");
307
- }
308
- return {
309
- baseRef,
310
- agent,
311
- model,
312
- includeWorktree,
313
- hypotheses,
314
- promptHint
315
- };
316
304
  }
317
- async function runReview2(args) {
318
- const request = parseArgs3(args);
319
- await runReview(request);
320
- }
321
-
322
- // src/cli.ts
323
- var VERSION = "0.1.0";
324
- var COMMANDS = {
325
- proov: {
326
- description: "Prove visual assertions with screenshots",
327
- run: runProov
305
+ var browse_default = defineCommand4({
306
+ meta: {
307
+ name: "browse",
308
+ description: "Browser automation via agent-browser"
328
309
  },
329
- run: {
330
- description: "Execute AI agent tasks",
331
- run: runRun
310
+ args: {
311
+ install: {
312
+ type: "boolean",
313
+ description: "Force reinstall browser",
314
+ default: false
315
+ },
316
+ _: {
317
+ type: "positional",
318
+ description: "agent-browser command and arguments",
319
+ required: false
320
+ }
332
321
  },
333
- review: {
334
- description: "Review code changes",
335
- run: runReview2
336
- }
337
- };
338
- function printHelp4() {
339
- console.log(`
340
- agex - AI-powered automation toolkit
341
-
342
- VERSION: ${VERSION}
322
+ async run({ args, rawArgs }) {
323
+ const browserArgs = rawArgs.filter((arg) => arg !== "--install");
324
+ if (browserArgs.length === 0) {
325
+ console.log(`
326
+ agex browse - Browser automation via agent-browser
343
327
 
344
328
  USAGE:
345
- agex <command> [options]
329
+ agex browse <command> [options]
346
330
 
347
331
  COMMANDS:
348
- proov ${COMMANDS.proov.description}
349
- run ${COMMANDS.run.description}
350
- review ${COMMANDS.review.description}
332
+ All agent-browser commands are supported. Common ones:
333
+
334
+ open <url> Navigate to URL
335
+ snapshot [-i] Get accessibility tree (use -i for interactive elements)
336
+ click @e1 Click element by ref
337
+ fill @e2 "text" Fill input by ref
338
+ screenshot [path] Take screenshot
339
+ close Close browser
340
+
341
+ OPTIONS:
342
+ --install Force reinstall browser
351
343
 
352
344
  EXAMPLES:
353
- agex proov "prove google has a logo" --url https://google.com
354
- agex run --agent cursor "build a landing page"
355
- agex review --base main --agent cursor
345
+ agex browse open https://example.com
346
+ agex browse snapshot -i
347
+ agex browse click @e1
348
+ agex browse fill @e2 "hello@example.com"
349
+ agex browse screenshot page.png
350
+ agex browse close
356
351
 
357
- Run 'agex <command> --help' for command-specific options.
352
+ For full documentation, run: npx agent-browser --help
353
+ Or visit: https://github.com/vercel-labs/agent-browser
358
354
  `);
359
- }
360
- function printVersion() {
361
- console.log(`agex v${VERSION}`);
362
- }
363
- async function main() {
364
- const args = process.argv.slice(2);
365
- if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
366
- printHelp4();
367
- process.exit(0);
368
- }
369
- if (args[0] === "--version" || args[0] === "-v") {
370
- printVersion();
371
- process.exit(0);
372
- }
373
- const command = args[0];
374
- const commandArgs = args.slice(1);
375
- if (!(command in COMMANDS)) {
376
- console.error(`Unknown command: ${command}`);
377
- console.error(`Run 'agex --help' for available commands.`);
355
+ return;
356
+ }
357
+ if (args.install) {
358
+ await installBrowser();
359
+ if (browserArgs.length === 0) {
360
+ return;
361
+ }
362
+ }
363
+ const firstRun = await runAgentBrowser(browserArgs);
364
+ if (firstRun.success) {
365
+ return;
366
+ }
367
+ if (firstRun.needsBrowserInstall) {
368
+ await installBrowser();
369
+ try {
370
+ await execa("npx", ["--yes", "agent-browser", ...browserArgs], {
371
+ stdio: "inherit",
372
+ env: { ...process.env }
373
+ });
374
+ } catch (error) {
375
+ const exitCode = error.exitCode ?? 1;
376
+ process.exit(exitCode);
377
+ }
378
+ return;
379
+ }
378
380
  process.exit(1);
379
381
  }
380
- try {
381
- await COMMANDS[command].run(commandArgs);
382
- } catch (error) {
383
- console.error("Error:", error instanceof Error ? error.message : error);
384
- process.exit(1);
382
+ });
383
+
384
+ // src/cli.ts
385
+ var main = defineCommand5({
386
+ meta: {
387
+ name: "agex",
388
+ version: "0.1.2",
389
+ description: "AI-powered automation toolkit"
390
+ },
391
+ subCommands: {
392
+ proov: proov_default,
393
+ run: run_default,
394
+ review: review_default,
395
+ browse: browse_default
385
396
  }
386
- }
387
- main();
397
+ });
398
+ runMain(main);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agex",
3
- "version": "0.1.2",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,6 +12,7 @@
12
12
  "assets"
13
13
  ],
14
14
  "dependencies": {
15
+ "citty": "^0.2.0",
15
16
  "execa": "^9.6.1"
16
17
  },
17
18
  "devDependencies": {
@@ -19,8 +20,8 @@
19
20
  "tsup": "^8.4.0",
20
21
  "typescript": "^5.9.3",
21
22
  "vitest": "^2.1.9",
22
- "agex-review": "0.1.0",
23
23
  "agex-browse": "0.1.0",
24
+ "agex-review": "0.1.0",
24
25
  "agex-proov": "0.1.0",
25
26
  "agex-run": "0.1.0"
26
27
  },