@agi_inc/cli 0.4.0

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/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # AGI CLI
2
+
3
+ Terminal-based agent interaction for AGI desktop automation. Control AI agents directly from your command line with a beautiful TUI interface.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g agi-cli
9
+ ```
10
+
11
+ ## Prerequisites
12
+
13
+ Set your API key:
14
+
15
+ ```bash
16
+ export AGI_API_KEY=your_api_key
17
+ # or
18
+ export ANTHROPIC_API_KEY=your_api_key
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```bash
24
+ # Basic usage
25
+ agi "Open calculator and compute 2+2"
26
+
27
+ # Use a specific model
28
+ agi "Find flights from SFO to JFK" --model claude-opus
29
+
30
+ # Verbose output (shows agent thinking)
31
+ agi "Install Node.js" --verbose
32
+
33
+ # Auto-approve confirmations
34
+ agi "Delete old files" --no-confirm
35
+ ```
36
+
37
+ ## Options
38
+
39
+ | Option | Alias | Description | Default |
40
+ |--------|-------|-------------|---------|
41
+ | `--model` | `-m` | Model to use | `claude-sonnet` |
42
+ | `--verbose` | `-v` | Show agent thinking | `false` |
43
+ | `--no-confirm` | | Auto-approve confirmations | `false` |
44
+ | `--help` | `-h` | Show help | |
45
+ | `--version` | `-V` | Show version | |
46
+
47
+ ## Keyboard Shortcuts
48
+
49
+ While the agent is running:
50
+
51
+ | Key | Action |
52
+ |-----|--------|
53
+ | `Space` | Pause/Resume |
54
+ | `Q` | Stop |
55
+ | `Ctrl+C` | Cancel |
56
+
57
+ ## Features
58
+
59
+ - **Real-time event display**: See actions, thinking, and status updates as they happen
60
+ - **Interactive dialogs**: Respond to agent questions and confirmation requests
61
+ - **Pause/Resume**: Take control when needed
62
+ - **Verbose mode**: See the agent's reasoning process
63
+ - **Multiple models**: Choose between Claude Sonnet and Opus
64
+
65
+ ## How It Works
66
+
67
+ The CLI uses the AGI SDK's driver module to spawn and manage the agent binary locally. The agent:
68
+
69
+ 1. Captures screenshots of your desktop
70
+ 2. Analyzes them using Claude
71
+ 3. Decides on actions to take
72
+ 4. Executes those actions
73
+ 5. Repeats until the task is complete
74
+
75
+ ## Requirements
76
+
77
+ - Node.js 20.4.0 or later
78
+ - macOS, Linux, or Windows
79
+ - AGI API key or Anthropic API key
80
+
81
+ ## License
82
+
83
+ MIT
package/bin/agi ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import('../dist/index.mjs');
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.mjs ADDED
@@ -0,0 +1,393 @@
1
+ // src/index.tsx
2
+ import React7 from "react";
3
+ import { render } from "ink";
4
+ import { isBinaryAvailable } from "agi";
5
+
6
+ // src/cli.ts
7
+ import yargs from "yargs";
8
+ import { hideBin } from "yargs/helpers";
9
+ async function parseArgs() {
10
+ const argv = await yargs(hideBin(process.argv)).scriptName("agi").usage("$0 <goal>", "Run an agent with the given goal", (yargs2) => {
11
+ return yargs2.positional("goal", {
12
+ describe: "The task for the agent to accomplish",
13
+ type: "string",
14
+ demandOption: true
15
+ });
16
+ }).option("model", {
17
+ alias: "m",
18
+ describe: "Model to use",
19
+ type: "string",
20
+ default: "claude-sonnet",
21
+ choices: ["claude-sonnet", "claude-opus"]
22
+ }).option("verbose", {
23
+ alias: "v",
24
+ describe: "Show verbose output including agent thinking",
25
+ type: "boolean",
26
+ default: false
27
+ }).option("no-confirm", {
28
+ describe: "Auto-approve all confirmation requests",
29
+ type: "boolean",
30
+ default: false
31
+ }).help().alias("help", "h").version().alias("version", "V").example('$0 "Open calculator and compute 2+2"', "Basic task").example('$0 "Find flights from SFO to JFK" --model claude-opus', "Use a specific model").example('$0 "Install Node.js" --verbose', "Verbose output").parse();
32
+ return {
33
+ goal: argv.goal,
34
+ model: argv.model,
35
+ verbose: argv.verbose,
36
+ noConfirm: argv["no-confirm"]
37
+ };
38
+ }
39
+
40
+ // src/app/App.tsx
41
+ import React6, { useEffect as useEffect2, useState as useState4 } from "react";
42
+ import { Box as Box6, Text as Text6, useApp } from "ink";
43
+
44
+ // src/hooks/useAgent.ts
45
+ import { useState, useCallback, useRef, useEffect } from "react";
46
+ import { AgentDriver } from "agi";
47
+ function useAgent(options) {
48
+ const { model, verbose, noConfirm, onFinished } = options;
49
+ const [state, setState] = useState("idle");
50
+ const [step, setStep] = useState(0);
51
+ const [events, setEvents] = useState([]);
52
+ const [pendingConfirm, setPendingConfirm] = useState(null);
53
+ const [pendingQuestion, setPendingQuestion] = useState(null);
54
+ const driverRef = useRef(null);
55
+ const addEvent = useCallback((event) => {
56
+ setEvents((prev) => [...prev, event]);
57
+ }, []);
58
+ const start = useCallback(
59
+ async (goal) => {
60
+ const driver = new AgentDriver({ model, mode: "local" });
61
+ driverRef.current = driver;
62
+ driver.on("state_change", (newState) => {
63
+ setState(newState);
64
+ });
65
+ driver.on("thinking", (text) => {
66
+ if (verbose) {
67
+ addEvent({ type: "thinking", text });
68
+ }
69
+ });
70
+ driver.on("action", async (action) => {
71
+ const actionStr = action.type + (action.x !== void 0 ? ` (${action.x}, ${action.y})` : "");
72
+ addEvent({ type: "action", action: actionStr });
73
+ });
74
+ driver.on("confirm", async (reason) => {
75
+ if (noConfirm) {
76
+ driver.respondConfirm(true);
77
+ return true;
78
+ }
79
+ addEvent({ type: "confirm", reason });
80
+ setPendingConfirm(reason);
81
+ return true;
82
+ });
83
+ driver.on("ask_question", async (question) => {
84
+ addEvent({ type: "question", question });
85
+ setPendingQuestion(question);
86
+ return "";
87
+ });
88
+ driver.on("finished", (evt) => {
89
+ addEvent({
90
+ type: "finished",
91
+ summary: evt.summary,
92
+ success: evt.success
93
+ });
94
+ });
95
+ driver.on("error", (evt) => {
96
+ addEvent({ type: "error", message: evt.message });
97
+ });
98
+ try {
99
+ const result = await driver.start(goal);
100
+ if (onFinished) {
101
+ onFinished(result);
102
+ }
103
+ } catch (error) {
104
+ addEvent({ type: "error", message: String(error) });
105
+ }
106
+ },
107
+ [model, verbose, noConfirm, addEvent, onFinished, state]
108
+ );
109
+ const stop = useCallback(async () => {
110
+ if (driverRef.current) {
111
+ await driverRef.current.stop("User cancelled");
112
+ }
113
+ }, []);
114
+ const pause = useCallback(() => {
115
+ if (driverRef.current) {
116
+ driverRef.current.pause();
117
+ }
118
+ }, []);
119
+ const resume = useCallback(() => {
120
+ if (driverRef.current) {
121
+ driverRef.current.resume();
122
+ }
123
+ }, []);
124
+ const respondConfirm = useCallback((approved) => {
125
+ if (driverRef.current && pendingConfirm) {
126
+ driverRef.current.respondConfirm(approved);
127
+ setPendingConfirm(null);
128
+ }
129
+ }, [pendingConfirm]);
130
+ const respondAnswer = useCallback((answer) => {
131
+ if (driverRef.current && pendingQuestion) {
132
+ driverRef.current.respondAnswer(answer);
133
+ setPendingQuestion(null);
134
+ }
135
+ }, [pendingQuestion]);
136
+ useEffect(() => {
137
+ const interval = setInterval(() => {
138
+ if (driverRef.current) {
139
+ setStep(driverRef.current.currentStep);
140
+ }
141
+ }, 100);
142
+ return () => clearInterval(interval);
143
+ }, []);
144
+ return {
145
+ state,
146
+ step,
147
+ events,
148
+ pendingConfirm,
149
+ pendingQuestion,
150
+ start,
151
+ stop,
152
+ pause,
153
+ resume,
154
+ respondConfirm,
155
+ respondAnswer
156
+ };
157
+ }
158
+
159
+ // src/hooks/useKeybindings.ts
160
+ import { useInput } from "ink";
161
+ import { useCallback as useCallback2 } from "react";
162
+ function useKeybindings(options) {
163
+ const { onPause, onResume, onStop, isPaused = false, disabled = false } = options;
164
+ const handleInput = useCallback2(
165
+ (input, key) => {
166
+ if (disabled) return;
167
+ if (input === " ") {
168
+ if (isPaused) {
169
+ onResume?.();
170
+ } else {
171
+ onPause?.();
172
+ }
173
+ }
174
+ if (input === "q" || input === "Q" || key.ctrl && input === "c") {
175
+ onStop?.();
176
+ }
177
+ if (key.escape) {
178
+ onStop?.();
179
+ }
180
+ },
181
+ [disabled, isPaused, onPause, onResume, onStop]
182
+ );
183
+ useInput(handleInput);
184
+ }
185
+
186
+ // src/components/StatusBar.tsx
187
+ import React from "react";
188
+ import { Text, Box } from "ink";
189
+ var stateColors = {
190
+ idle: "gray",
191
+ running: "green",
192
+ paused: "yellow",
193
+ waiting_confirmation: "yellow",
194
+ waiting_answer: "yellow",
195
+ finished: "green",
196
+ stopped: "red",
197
+ error: "red"
198
+ };
199
+ var stateLabels = {
200
+ idle: "IDLE",
201
+ running: "RUNNING",
202
+ paused: "PAUSED",
203
+ waiting_confirmation: "WAITING",
204
+ waiting_answer: "WAITING",
205
+ finished: "DONE",
206
+ stopped: "STOPPED",
207
+ error: "ERROR"
208
+ };
209
+ var StatusBar = ({ state, step, goal }) => {
210
+ const color = stateColors[state] || "white";
211
+ const label = stateLabels[state] || state.toUpperCase();
212
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "AGI Agent"), /* @__PURE__ */ React.createElement(Text, null, " | "), /* @__PURE__ */ React.createElement(Text, { color }, label), /* @__PURE__ */ React.createElement(Text, null, " | "), /* @__PURE__ */ React.createElement(Text, null, "Step ", step)), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "gray" }, "Goal: "), /* @__PURE__ */ React.createElement(Text, null, goal.length > 60 ? goal.slice(0, 60) + "..." : goal)));
213
+ };
214
+
215
+ // src/components/EventDisplay.tsx
216
+ import React2 from "react";
217
+ import { Text as Text2, Box as Box2 } from "ink";
218
+ var EventDisplay = ({ events, maxEvents = 10 }) => {
219
+ const displayEvents = events.slice(-maxEvents);
220
+ return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", paddingY: 1 }, displayEvents.map((event, index) => /* @__PURE__ */ React2.createElement(EventLine, { key: index, event })));
221
+ };
222
+ var EventLine = ({ event }) => {
223
+ switch (event.type) {
224
+ case "thinking":
225
+ return /* @__PURE__ */ React2.createElement(Box2, null, /* @__PURE__ */ React2.createElement(Text2, { color: "cyan" }, "\u{1F4AD} "), /* @__PURE__ */ React2.createElement(Text2, { color: "gray" }, event.text));
226
+ case "action":
227
+ return /* @__PURE__ */ React2.createElement(Box2, null, /* @__PURE__ */ React2.createElement(Text2, { color: "blue" }, "\u26A1 "), /* @__PURE__ */ React2.createElement(Text2, null, event.action));
228
+ case "confirm":
229
+ return /* @__PURE__ */ React2.createElement(Box2, null, /* @__PURE__ */ React2.createElement(Text2, { color: "yellow" }, "\u2753 "), /* @__PURE__ */ React2.createElement(Text2, { color: "yellow" }, event.reason));
230
+ case "question":
231
+ return /* @__PURE__ */ React2.createElement(Box2, null, /* @__PURE__ */ React2.createElement(Text2, { color: "magenta" }, "\u{1F4DD} "), /* @__PURE__ */ React2.createElement(Text2, { color: "magenta" }, event.question));
232
+ case "finished":
233
+ return /* @__PURE__ */ React2.createElement(Box2, null, /* @__PURE__ */ React2.createElement(Text2, { color: event.success ? "green" : "red" }, event.success ? "\u2705 " : "\u274C "), /* @__PURE__ */ React2.createElement(Text2, null, event.summary));
234
+ case "error":
235
+ return /* @__PURE__ */ React2.createElement(Box2, null, /* @__PURE__ */ React2.createElement(Text2, { color: "red" }, "\u26A0\uFE0F "), /* @__PURE__ */ React2.createElement(Text2, { color: "red" }, event.message));
236
+ default:
237
+ return null;
238
+ }
239
+ };
240
+
241
+ // src/components/ConfirmDialog.tsx
242
+ import React3, { useState as useState2 } from "react";
243
+ import { Text as Text3, Box as Box3, useInput as useInput2 } from "ink";
244
+ var ConfirmDialog = ({ reason, onConfirm }) => {
245
+ const [selected, setSelected] = useState2("yes");
246
+ useInput2((input, key) => {
247
+ if (key.leftArrow || input === "h") {
248
+ setSelected("yes");
249
+ } else if (key.rightArrow || input === "l") {
250
+ setSelected("no");
251
+ } else if (key.return) {
252
+ onConfirm(selected === "yes");
253
+ } else if (input === "y" || input === "Y") {
254
+ onConfirm(true);
255
+ } else if (input === "n" || input === "N") {
256
+ onConfirm(false);
257
+ }
258
+ });
259
+ return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "yellow", bold: true }, "Confirmation Required")), /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, null, reason)), /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Box3, { marginRight: 2 }, /* @__PURE__ */ React3.createElement(
260
+ Text3,
261
+ {
262
+ backgroundColor: selected === "yes" ? "green" : void 0,
263
+ color: selected === "yes" ? "white" : "gray"
264
+ },
265
+ " [Y]es "
266
+ )), /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(
267
+ Text3,
268
+ {
269
+ backgroundColor: selected === "no" ? "red" : void 0,
270
+ color: selected === "no" ? "white" : "gray"
271
+ },
272
+ " [N]o "
273
+ ))), /* @__PURE__ */ React3.createElement(Box3, { marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: "gray", dimColor: true }, "Press Y/N or use arrow keys and Enter")));
274
+ };
275
+
276
+ // src/components/QuestionDialog.tsx
277
+ import React4, { useState as useState3 } from "react";
278
+ import { Text as Text4, Box as Box4, useInput as useInput3 } from "ink";
279
+ import TextInput from "ink-text-input";
280
+ var QuestionDialog = ({ question, onAnswer }) => {
281
+ const [answer, setAnswer] = useState3("");
282
+ const handleSubmit = () => {
283
+ if (answer.trim()) {
284
+ onAnswer(answer.trim());
285
+ }
286
+ };
287
+ useInput3((_, key) => {
288
+ if (key.return && answer.trim()) {
289
+ handleSubmit();
290
+ }
291
+ });
292
+ return /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React4.createElement(Box4, { marginBottom: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "magenta", bold: true }, "Agent Question")), /* @__PURE__ */ React4.createElement(Box4, { marginBottom: 1 }, /* @__PURE__ */ React4.createElement(Text4, null, question)), /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "green" }, "> "), /* @__PURE__ */ React4.createElement(
293
+ TextInput,
294
+ {
295
+ value: answer,
296
+ onChange: setAnswer,
297
+ onSubmit: handleSubmit,
298
+ placeholder: "Type your answer..."
299
+ }
300
+ )), /* @__PURE__ */ React4.createElement(Box4, { marginTop: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, "Press Enter to submit")));
301
+ };
302
+
303
+ // src/components/Spinner.tsx
304
+ import React5 from "react";
305
+ import { Text as Text5, Box as Box5 } from "ink";
306
+ import InkSpinner from "ink-spinner";
307
+ var Spinner = ({ text = "", type = "dots" }) => {
308
+ return /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "cyan" }, /* @__PURE__ */ React5.createElement(InkSpinner, { type })), text && /* @__PURE__ */ React5.createElement(Text5, null, " ", text));
309
+ };
310
+
311
+ // src/app/App.tsx
312
+ var App = ({ args }) => {
313
+ const { exit } = useApp();
314
+ const [started, setStarted] = useState4(false);
315
+ const {
316
+ state,
317
+ step,
318
+ events,
319
+ pendingConfirm,
320
+ pendingQuestion,
321
+ start,
322
+ stop,
323
+ pause,
324
+ resume,
325
+ respondConfirm,
326
+ respondAnswer
327
+ } = useAgent({
328
+ model: args.model,
329
+ verbose: args.verbose,
330
+ noConfirm: args.noConfirm,
331
+ onFinished: () => {
332
+ setTimeout(() => exit(), 500);
333
+ }
334
+ });
335
+ useEffect2(() => {
336
+ if (!started) {
337
+ setStarted(true);
338
+ start(args.goal);
339
+ }
340
+ }, [started, start, args.goal]);
341
+ useKeybindings({
342
+ onPause: pause,
343
+ onResume: resume,
344
+ onStop: async () => {
345
+ await stop();
346
+ exit();
347
+ },
348
+ isPaused: state === "paused",
349
+ disabled: !!pendingConfirm || !!pendingQuestion
350
+ });
351
+ const isTerminal = state === "finished" || state === "stopped" || state === "error";
352
+ return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(StatusBar, { state, step, goal: args.goal }), state === "running" && /* @__PURE__ */ React6.createElement(Box6, { marginY: 1 }, /* @__PURE__ */ React6.createElement(Spinner, { text: "Agent is working..." })), state === "paused" && /* @__PURE__ */ React6.createElement(Box6, { marginY: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "yellow" }, "\u23F8\uFE0F Paused - Press Space to resume, Q to stop")), /* @__PURE__ */ React6.createElement(EventDisplay, { events }), pendingConfirm && /* @__PURE__ */ React6.createElement(ConfirmDialog, { reason: pendingConfirm, onConfirm: respondConfirm }), pendingQuestion && /* @__PURE__ */ React6.createElement(QuestionDialog, { question: pendingQuestion, onAnswer: respondAnswer }), !isTerminal && !pendingConfirm && !pendingQuestion && /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React6.createElement(Text6, { color: "gray", dimColor: true }, "Space: Pause/Resume | Q: Stop | Ctrl+C: Cancel")));
353
+ };
354
+
355
+ // src/index.tsx
356
+ async function main() {
357
+ if (!process.env.AGI_API_KEY && !process.env.ANTHROPIC_API_KEY) {
358
+ console.error("Error: AGI_API_KEY or ANTHROPIC_API_KEY environment variable is required");
359
+ console.error("");
360
+ console.error("Set your API key:");
361
+ console.error(" export AGI_API_KEY=your_key");
362
+ console.error("");
363
+ process.exit(1);
364
+ }
365
+ if (!isBinaryAvailable()) {
366
+ console.error("Error: AGI driver binary not found");
367
+ console.error("");
368
+ console.error("The driver binary is required for local agent execution.");
369
+ console.error("It should be installed automatically with the agi package.");
370
+ console.error("");
371
+ console.error("Try reinstalling: npm install -g agi-cli");
372
+ console.error("");
373
+ process.exit(1);
374
+ }
375
+ try {
376
+ const args = await parseArgs();
377
+ if (!args.goal) {
378
+ console.error("Error: Goal is required");
379
+ console.error("");
380
+ console.error("Usage: agi <goal>");
381
+ console.error("");
382
+ console.error('Example: agi "Open calculator and compute 2+2"');
383
+ process.exit(1);
384
+ }
385
+ const { waitUntilExit } = render(/* @__PURE__ */ React7.createElement(App, { args }));
386
+ await waitUntilExit();
387
+ } catch (error) {
388
+ console.error("Error:", error);
389
+ process.exit(1);
390
+ }
391
+ }
392
+ main();
393
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx","../src/cli.ts","../src/app/App.tsx","../src/hooks/useAgent.ts","../src/hooks/useKeybindings.ts","../src/components/StatusBar.tsx","../src/components/EventDisplay.tsx","../src/components/ConfirmDialog.tsx","../src/components/QuestionDialog.tsx","../src/components/Spinner.tsx"],"sourcesContent":["/**\n * AGI CLI - Terminal-based agent interaction for AGI desktop automation.\n *\n * Usage:\n * agi \"Open calculator and compute 2+2\"\n * agi \"Find flights from SFO to JFK\" --model claude-opus\n * agi \"Install Node.js\" --verbose\n */\n\nimport React from 'react';\nimport { render } from 'ink';\nimport { isBinaryAvailable } from 'agi';\nimport { parseArgs } from './cli.js';\nimport { App } from './app/App.js';\n\nasync function main(): Promise<void> {\n // Check for API key\n if (!process.env.AGI_API_KEY && !process.env.ANTHROPIC_API_KEY) {\n console.error('Error: AGI_API_KEY or ANTHROPIC_API_KEY environment variable is required');\n console.error('');\n console.error('Set your API key:');\n console.error(' export AGI_API_KEY=your_key');\n console.error('');\n process.exit(1);\n }\n\n // Check for driver binary\n if (!isBinaryAvailable()) {\n console.error('Error: AGI driver binary not found');\n console.error('');\n console.error('The driver binary is required for local agent execution.');\n console.error('It should be installed automatically with the agi package.');\n console.error('');\n console.error('Try reinstalling: npm install -g agi-cli');\n console.error('');\n process.exit(1);\n }\n\n try {\n const args = await parseArgs();\n\n // Check if goal is provided\n if (!args.goal) {\n console.error('Error: Goal is required');\n console.error('');\n console.error('Usage: agi <goal>');\n console.error('');\n console.error('Example: agi \"Open calculator and compute 2+2\"');\n process.exit(1);\n }\n\n // Render the app\n const { waitUntilExit } = render(<App args={args} />);\n await waitUntilExit();\n } catch (error) {\n console.error('Error:', error);\n process.exit(1);\n }\n}\n\nmain();\n","/**\n * CLI argument parsing and configuration.\n */\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\n\nexport interface CliArgs {\n goal: string;\n model: string;\n verbose: boolean;\n noConfirm: boolean;\n}\n\nexport async function parseArgs(): Promise<CliArgs> {\n const argv = await yargs(hideBin(process.argv))\n .scriptName('agi')\n .usage('$0 <goal>', 'Run an agent with the given goal', (yargs) => {\n return yargs.positional('goal', {\n describe: 'The task for the agent to accomplish',\n type: 'string',\n demandOption: true,\n });\n })\n .option('model', {\n alias: 'm',\n describe: 'Model to use',\n type: 'string',\n default: 'claude-sonnet',\n choices: ['claude-sonnet', 'claude-opus'],\n })\n .option('verbose', {\n alias: 'v',\n describe: 'Show verbose output including agent thinking',\n type: 'boolean',\n default: false,\n })\n .option('no-confirm', {\n describe: 'Auto-approve all confirmation requests',\n type: 'boolean',\n default: false,\n })\n .help()\n .alias('help', 'h')\n .version()\n .alias('version', 'V')\n .example('$0 \"Open calculator and compute 2+2\"', 'Basic task')\n .example('$0 \"Find flights from SFO to JFK\" --model claude-opus', 'Use a specific model')\n .example('$0 \"Install Node.js\" --verbose', 'Verbose output')\n .parse();\n\n return {\n goal: argv.goal as string,\n model: argv.model as string,\n verbose: argv.verbose as boolean,\n noConfirm: argv['no-confirm'] as boolean,\n };\n}\n","import React, { useEffect, useState } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport type { CliArgs } from '../cli.js';\nimport { useAgent } from '../hooks/useAgent.js';\nimport { useKeybindings } from '../hooks/useKeybindings.js';\nimport { StatusBar } from '../components/StatusBar.js';\nimport { EventDisplay } from '../components/EventDisplay.js';\nimport { ConfirmDialog } from '../components/ConfirmDialog.js';\nimport { QuestionDialog } from '../components/QuestionDialog.js';\nimport { Spinner } from '../components/Spinner.js';\n\ninterface AppProps {\n args: CliArgs;\n}\n\nexport const App: React.FC<AppProps> = ({ args }) => {\n const { exit } = useApp();\n const [started, setStarted] = useState(false);\n\n const {\n state,\n step,\n events,\n pendingConfirm,\n pendingQuestion,\n start,\n stop,\n pause,\n resume,\n respondConfirm,\n respondAnswer,\n } = useAgent({\n model: args.model,\n verbose: args.verbose,\n noConfirm: args.noConfirm,\n onFinished: () => {\n // Wait a moment for final output, then exit\n setTimeout(() => exit(), 500);\n },\n });\n\n // Start the agent on mount\n useEffect(() => {\n if (!started) {\n setStarted(true);\n start(args.goal);\n }\n }, [started, start, args.goal]);\n\n // Handle keyboard shortcuts\n useKeybindings({\n onPause: pause,\n onResume: resume,\n onStop: async () => {\n await stop();\n exit();\n },\n isPaused: state === 'paused',\n disabled: !!pendingConfirm || !!pendingQuestion,\n });\n\n const isTerminal = state === 'finished' || state === 'stopped' || state === 'error';\n\n return (\n <Box flexDirection=\"column\">\n {/* Status bar */}\n <StatusBar state={state} step={step} goal={args.goal} />\n\n {/* Running indicator */}\n {state === 'running' && (\n <Box marginY={1}>\n <Spinner text=\"Agent is working...\" />\n </Box>\n )}\n\n {/* Paused indicator */}\n {state === 'paused' && (\n <Box marginY={1}>\n <Text color=\"yellow\">⏸️ Paused - Press Space to resume, Q to stop</Text>\n </Box>\n )}\n\n {/* Events display */}\n <EventDisplay events={events} />\n\n {/* Confirmation dialog */}\n {pendingConfirm && (\n <ConfirmDialog reason={pendingConfirm} onConfirm={respondConfirm} />\n )}\n\n {/* Question dialog */}\n {pendingQuestion && (\n <QuestionDialog question={pendingQuestion} onAnswer={respondAnswer} />\n )}\n\n {/* Help text */}\n {!isTerminal && !pendingConfirm && !pendingQuestion && (\n <Box marginTop={1}>\n <Text color=\"gray\" dimColor>\n Space: Pause/Resume | Q: Stop | Ctrl+C: Cancel\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport { AgentDriver } from 'agi';\nimport type { DriverState, DriverAction, DriverResult } from 'agi';\nimport type { EventItem } from '../components/EventDisplay.js';\n\ninterface UseAgentOptions {\n model: string;\n verbose: boolean;\n noConfirm: boolean;\n onFinished?: (result: DriverResult) => void;\n}\n\ninterface UseAgentReturn {\n state: DriverState;\n step: number;\n events: EventItem[];\n pendingConfirm: string | null;\n pendingQuestion: string | null;\n start: (goal: string) => Promise<void>;\n stop: () => Promise<void>;\n pause: () => void;\n resume: () => void;\n respondConfirm: (approved: boolean) => void;\n respondAnswer: (answer: string) => void;\n}\n\nexport function useAgent(options: UseAgentOptions): UseAgentReturn {\n const { model, verbose, noConfirm, onFinished } = options;\n\n const [state, setState] = useState<DriverState>('idle');\n const [step, setStep] = useState(0);\n const [events, setEvents] = useState<EventItem[]>([]);\n const [pendingConfirm, setPendingConfirm] = useState<string | null>(null);\n const [pendingQuestion, setPendingQuestion] = useState<string | null>(null);\n\n const driverRef = useRef<AgentDriver | null>(null);\n\n const addEvent = useCallback((event: EventItem) => {\n setEvents((prev) => [...prev, event]);\n }, []);\n\n const start = useCallback(\n async (goal: string) => {\n const driver = new AgentDriver({ model, mode: 'local' });\n driverRef.current = driver;\n\n // Set up event handlers\n driver.on('state_change', (newState: DriverState) => {\n setState(newState);\n });\n\n driver.on('thinking', (text: string) => {\n if (verbose) {\n addEvent({ type: 'thinking', text });\n }\n });\n\n driver.on('action', async (action: DriverAction) => {\n const actionStr = action.type + (action.x !== undefined ? ` (${action.x}, ${action.y})` : '');\n addEvent({ type: 'action', action: actionStr });\n // In local mode, the driver binary executes actions and captures screenshots\n });\n\n driver.on('confirm', async (reason: string) => {\n if (noConfirm) {\n driver.respondConfirm(true);\n return true;\n }\n addEvent({ type: 'confirm', reason });\n setPendingConfirm(reason);\n return true;\n });\n\n driver.on('ask_question', async (question: string) => {\n addEvent({ type: 'question', question });\n setPendingQuestion(question);\n return '';\n });\n\n driver.on('finished', (evt) => {\n addEvent({\n type: 'finished',\n summary: evt.summary,\n success: evt.success,\n });\n });\n\n driver.on('error', (evt) => {\n addEvent({ type: 'error', message: evt.message });\n });\n\n // Start the agent in local mode β€” no screenshot needed, driver handles it\n try {\n const result = await driver.start(goal);\n\n if (onFinished) {\n onFinished(result);\n }\n } catch (error) {\n addEvent({ type: 'error', message: String(error) });\n }\n },\n [model, verbose, noConfirm, addEvent, onFinished, state]\n );\n\n const stop = useCallback(async () => {\n if (driverRef.current) {\n await driverRef.current.stop('User cancelled');\n }\n }, []);\n\n const pause = useCallback(() => {\n if (driverRef.current) {\n driverRef.current.pause();\n }\n }, []);\n\n const resume = useCallback(() => {\n if (driverRef.current) {\n driverRef.current.resume();\n }\n }, []);\n\n const respondConfirm = useCallback((approved: boolean) => {\n if (driverRef.current && pendingConfirm) {\n driverRef.current.respondConfirm(approved);\n setPendingConfirm(null);\n }\n }, [pendingConfirm]);\n\n const respondAnswer = useCallback((answer: string) => {\n if (driverRef.current && pendingQuestion) {\n driverRef.current.respondAnswer(answer);\n setPendingQuestion(null);\n }\n }, [pendingQuestion]);\n\n // Update step from driver\n useEffect(() => {\n const interval = setInterval(() => {\n if (driverRef.current) {\n setStep(driverRef.current.currentStep);\n }\n }, 100);\n return () => clearInterval(interval);\n }, []);\n\n return {\n state,\n step,\n events,\n pendingConfirm,\n pendingQuestion,\n start,\n stop,\n pause,\n resume,\n respondConfirm,\n respondAnswer,\n };\n}\n","import { useInput } from 'ink';\nimport { useCallback } from 'react';\n\ninterface UseKeybindingsOptions {\n onPause?: () => void;\n onResume?: () => void;\n onStop?: () => void;\n isPaused?: boolean;\n disabled?: boolean;\n}\n\n/**\n * Hook for handling keyboard shortcuts.\n *\n * - Space: Pause/Resume\n * - Q/Ctrl+C: Stop\n * - Escape: Stop\n */\nexport function useKeybindings(options: UseKeybindingsOptions): void {\n const { onPause, onResume, onStop, isPaused = false, disabled = false } = options;\n\n const handleInput = useCallback(\n (input: string, key: { ctrl: boolean; escape: boolean }) => {\n if (disabled) return;\n\n // Space: Toggle pause/resume\n if (input === ' ') {\n if (isPaused) {\n onResume?.();\n } else {\n onPause?.();\n }\n }\n\n // Q or Ctrl+C: Stop\n if (input === 'q' || input === 'Q' || (key.ctrl && input === 'c')) {\n onStop?.();\n }\n\n // Escape: Stop\n if (key.escape) {\n onStop?.();\n }\n },\n [disabled, isPaused, onPause, onResume, onStop]\n );\n\n useInput(handleInput);\n}\n","import React from 'react';\nimport { Text, Box } from 'ink';\nimport type { DriverState } from 'agi';\n\ninterface StatusBarProps {\n state: DriverState;\n step: number;\n goal: string;\n}\n\nconst stateColors: Record<DriverState, string> = {\n idle: 'gray',\n running: 'green',\n paused: 'yellow',\n waiting_confirmation: 'yellow',\n waiting_answer: 'yellow',\n finished: 'green',\n stopped: 'red',\n error: 'red',\n};\n\nconst stateLabels: Record<DriverState, string> = {\n idle: 'IDLE',\n running: 'RUNNING',\n paused: 'PAUSED',\n waiting_confirmation: 'WAITING',\n waiting_answer: 'WAITING',\n finished: 'DONE',\n stopped: 'STOPPED',\n error: 'ERROR',\n};\n\nexport const StatusBar: React.FC<StatusBarProps> = ({ state, step, goal }) => {\n const color = stateColors[state] || 'white';\n const label = stateLabels[state] || state.toUpperCase();\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"single\" borderColor=\"gray\" paddingX={1}>\n <Box>\n <Text bold>AGI Agent</Text>\n <Text> | </Text>\n <Text color={color}>{label}</Text>\n <Text> | </Text>\n <Text>Step {step}</Text>\n </Box>\n <Box>\n <Text color=\"gray\">Goal: </Text>\n <Text>{goal.length > 60 ? goal.slice(0, 60) + '...' : goal}</Text>\n </Box>\n </Box>\n );\n};\n","import React from 'react';\nimport { Text, Box } from 'ink';\n\nexport type EventItem =\n | { type: 'thinking'; text: string }\n | { type: 'action'; action: string }\n | { type: 'confirm'; reason: string }\n | { type: 'question'; question: string }\n | { type: 'finished'; summary: string; success: boolean }\n | { type: 'error'; message: string };\n\ninterface EventDisplayProps {\n events: EventItem[];\n maxEvents?: number;\n}\n\nexport const EventDisplay: React.FC<EventDisplayProps> = ({ events, maxEvents = 10 }) => {\n const displayEvents = events.slice(-maxEvents);\n\n return (\n <Box flexDirection=\"column\" paddingY={1}>\n {displayEvents.map((event, index) => (\n <EventLine key={index} event={event} />\n ))}\n </Box>\n );\n};\n\nconst EventLine: React.FC<{ event: EventItem }> = ({ event }) => {\n switch (event.type) {\n case 'thinking':\n return (\n <Box>\n <Text color=\"cyan\">πŸ’­ </Text>\n <Text color=\"gray\">{event.text}</Text>\n </Box>\n );\n\n case 'action':\n return (\n <Box>\n <Text color=\"blue\">⚑ </Text>\n <Text>{event.action}</Text>\n </Box>\n );\n\n case 'confirm':\n return (\n <Box>\n <Text color=\"yellow\">❓ </Text>\n <Text color=\"yellow\">{event.reason}</Text>\n </Box>\n );\n\n case 'question':\n return (\n <Box>\n <Text color=\"magenta\">πŸ“ </Text>\n <Text color=\"magenta\">{event.question}</Text>\n </Box>\n );\n\n case 'finished':\n return (\n <Box>\n <Text color={event.success ? 'green' : 'red'}>\n {event.success ? 'βœ… ' : '❌ '}\n </Text>\n <Text>{event.summary}</Text>\n </Box>\n );\n\n case 'error':\n return (\n <Box>\n <Text color=\"red\">⚠️ </Text>\n <Text color=\"red\">{event.message}</Text>\n </Box>\n );\n\n default:\n return null;\n }\n};\n","import React, { useState } from 'react';\nimport { Text, Box, useInput } from 'ink';\n\ninterface ConfirmDialogProps {\n reason: string;\n onConfirm: (approved: boolean) => void;\n}\n\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = ({ reason, onConfirm }) => {\n const [selected, setSelected] = useState<'yes' | 'no'>('yes');\n\n useInput((input, key) => {\n if (key.leftArrow || input === 'h') {\n setSelected('yes');\n } else if (key.rightArrow || input === 'l') {\n setSelected('no');\n } else if (key.return) {\n onConfirm(selected === 'yes');\n } else if (input === 'y' || input === 'Y') {\n onConfirm(true);\n } else if (input === 'n' || input === 'N') {\n onConfirm(false);\n }\n });\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"yellow\" paddingX={2} paddingY={1}>\n <Box marginBottom={1}>\n <Text color=\"yellow\" bold>\n Confirmation Required\n </Text>\n </Box>\n <Box marginBottom={1}>\n <Text>{reason}</Text>\n </Box>\n <Box>\n <Box marginRight={2}>\n <Text\n backgroundColor={selected === 'yes' ? 'green' : undefined}\n color={selected === 'yes' ? 'white' : 'gray'}\n >\n {' [Y]es '}\n </Text>\n </Box>\n <Box>\n <Text\n backgroundColor={selected === 'no' ? 'red' : undefined}\n color={selected === 'no' ? 'white' : 'gray'}\n >\n {' [N]o '}\n </Text>\n </Box>\n </Box>\n <Box marginTop={1}>\n <Text color=\"gray\" dimColor>\n Press Y/N or use arrow keys and Enter\n </Text>\n </Box>\n </Box>\n );\n};\n","import React, { useState } from 'react';\nimport { Text, Box, useInput } from 'ink';\nimport TextInput from 'ink-text-input';\n\ninterface QuestionDialogProps {\n question: string;\n onAnswer: (answer: string) => void;\n}\n\nexport const QuestionDialog: React.FC<QuestionDialogProps> = ({ question, onAnswer }) => {\n const [answer, setAnswer] = useState('');\n\n const handleSubmit = () => {\n if (answer.trim()) {\n onAnswer(answer.trim());\n }\n };\n\n useInput((_, key) => {\n if (key.return && answer.trim()) {\n handleSubmit();\n }\n });\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"magenta\" paddingX={2} paddingY={1}>\n <Box marginBottom={1}>\n <Text color=\"magenta\" bold>\n Agent Question\n </Text>\n </Box>\n <Box marginBottom={1}>\n <Text>{question}</Text>\n </Box>\n <Box>\n <Text color=\"green\">{'> '}</Text>\n <TextInput\n value={answer}\n onChange={setAnswer}\n onSubmit={handleSubmit}\n placeholder=\"Type your answer...\"\n />\n </Box>\n <Box marginTop={1}>\n <Text color=\"gray\" dimColor>\n Press Enter to submit\n </Text>\n </Box>\n </Box>\n );\n};\n","import React from 'react';\nimport { Text, Box } from 'ink';\nimport InkSpinner from 'ink-spinner';\n\ninterface SpinnerProps {\n text?: string;\n type?: 'dots' | 'line' | 'arc' | 'circle';\n}\n\nexport const Spinner: React.FC<SpinnerProps> = ({ text = '', type = 'dots' }) => {\n return (\n <Box>\n <Text color=\"cyan\">\n <InkSpinner type={type} />\n </Text>\n {text && <Text> {text}</Text>}\n </Box>\n );\n};\n"],"mappings":"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","names":["React","yargs","React","useEffect","useState","Box","Text","useCallback","React","Text","Box","React","useState","Text","Box","useInput","React","useState","Text","Box","useInput","React","Text","Box","useState","useEffect","React","Box","Text","React"]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@agi_inc/cli",
3
+ "version": "0.4.0",
4
+ "description": "Terminal-based agent interaction for AGI desktop automation",
5
+ "main": "./dist/index.js",
6
+ "bin": {
7
+ "agi": "./bin/agi"
8
+ },
9
+ "scripts": {
10
+ "build": "tsup",
11
+ "dev": "tsup --watch",
12
+ "start": "node dist/index.js",
13
+ "lint": "eslint src --ext .ts,.tsx",
14
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
15
+ "typecheck": "tsc --noEmit",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "keywords": [
19
+ "agi",
20
+ "cli",
21
+ "terminal",
22
+ "ai",
23
+ "agent",
24
+ "automation",
25
+ "desktop"
26
+ ],
27
+ "author": "AGI Inc <sdk@agi.tech>",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/agi-inc/agi-cli.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/agi-inc/agi-cli/issues"
35
+ },
36
+ "homepage": "https://docs.agi.tech",
37
+ "engines": {
38
+ "node": ">=20.4.0"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "bin",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "dependencies": {
47
+ "agi": "^0.4.0",
48
+ "ink": "^5.0.1",
49
+ "ink-spinner": "^5.0.0",
50
+ "ink-text-input": "^6.0.0",
51
+ "react": "^18.3.1",
52
+ "yargs": "^17.7.2"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^20.10.0",
56
+ "@types/react": "^18.2.0",
57
+ "@types/yargs": "^17.0.32",
58
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
59
+ "@typescript-eslint/parser": "^6.13.0",
60
+ "eslint": "^8.55.0",
61
+ "eslint-config-prettier": "^9.1.0",
62
+ "prettier": "^3.1.0",
63
+ "tsup": "^8.0.1",
64
+ "typescript": "^5.3.3"
65
+ }
66
+ }