@robota-sdk/agent-cli 3.0.0-beta.46 → 3.0.0-beta.47
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 +37 -13
- package/dist/node/bin.js +1 -1
- package/dist/node/{chunk-L5G6WFOL.js → chunk-74WEPZG2.js} +55 -31
- package/dist/node/index.cjs +55 -31
- package/dist/node/index.js +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -78,10 +78,33 @@ robota --model <model> # Model override (e.g., claude-sonnet-4-6)
|
|
|
78
78
|
robota --language <lang> # Response language (ko, en, ja, zh)
|
|
79
79
|
robota --permission-mode <mode> # plan | default | acceptEdits | bypassPermissions
|
|
80
80
|
robota --max-turns <n> # Limit agentic turns per interaction
|
|
81
|
+
robota --output-format <fmt> # text | json | stream-json (print mode)
|
|
82
|
+
robota --system-prompt <text> # Replace system prompt (print mode)
|
|
83
|
+
robota --append-system-prompt <text> # Append to system prompt (print mode)
|
|
81
84
|
robota --reset # Delete user settings and exit
|
|
82
85
|
robota --version # Show version
|
|
83
86
|
```
|
|
84
87
|
|
|
88
|
+
### Print Mode Output Formats
|
|
89
|
+
|
|
90
|
+
Print mode (`-p`) supports three output formats via `--output-format`:
|
|
91
|
+
|
|
92
|
+
| Format | Description |
|
|
93
|
+
| ------------- | ------------------------------------------------------------------ |
|
|
94
|
+
| `text` | Plain text response to stdout (default) |
|
|
95
|
+
| `json` | Single JSON object: `{ type, result, session_id, subtype }` |
|
|
96
|
+
| `stream-json` | Newline-delimited JSON with `content_block_delta` streaming events |
|
|
97
|
+
|
|
98
|
+
### Stdin Pipe
|
|
99
|
+
|
|
100
|
+
When `-p` is used without a positional argument and stdin is piped, the CLI reads from stdin:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
echo "Explain this error" | robota -p
|
|
104
|
+
cat file.ts | robota -p "Review this code" --output-format json
|
|
105
|
+
git diff | robota -p "Summarize changes" --output-format stream-json
|
|
106
|
+
```
|
|
107
|
+
|
|
85
108
|
## First-Run Setup
|
|
86
109
|
|
|
87
110
|
When no settings file exists, the CLI prompts for:
|
|
@@ -227,7 +250,7 @@ When a session has a name, it appears in three places:
|
|
|
227
250
|
| `/rename <name>` | Rename the current session |
|
|
228
251
|
| `/exit` | Exit CLI |
|
|
229
252
|
|
|
230
|
-
Typing `/` triggers an autocomplete popup with arrow-key navigation
|
|
253
|
+
Typing `/` triggers an autocomplete popup with arrow-key navigation and Esc to dismiss. Tab inserts the highlighted command into the input field without executing — continue typing args or press Enter to execute. Enter selects and executes immediately. Commands with subcommands (e.g., `/mode`, `/model`) show a nested submenu. Skill commands discovered from `.agents/skills/` and `.claude/commands/` appear alongside built-in commands.
|
|
231
254
|
|
|
232
255
|
## Plugin Management
|
|
233
256
|
|
|
@@ -317,18 +340,19 @@ bin.ts → cli.ts (arg parsing)
|
|
|
317
340
|
|
|
318
341
|
## Dependencies
|
|
319
342
|
|
|
320
|
-
| Package
|
|
321
|
-
|
|
|
322
|
-
| `@robota-sdk/agent-sdk`
|
|
323
|
-
| `@robota-sdk/agent-core`
|
|
324
|
-
| `
|
|
325
|
-
| `ink
|
|
326
|
-
| `ink-
|
|
327
|
-
| `
|
|
328
|
-
| `
|
|
329
|
-
| `
|
|
330
|
-
| `
|
|
331
|
-
| `
|
|
343
|
+
| Package | Purpose |
|
|
344
|
+
| -------------------------------------- | ------------------------------------------ |
|
|
345
|
+
| `@robota-sdk/agent-sdk` | Session factory, query, config, context |
|
|
346
|
+
| `@robota-sdk/agent-core` | Types (TPermissionMode, TToolArgs) |
|
|
347
|
+
| `@robota-sdk/agent-transport-headless` | Headless runner for print mode (`-p`) |
|
|
348
|
+
| `ink`, `react` | TUI rendering |
|
|
349
|
+
| `ink-select-input` | Arrow-key selection (permission prompt) |
|
|
350
|
+
| `ink-spinner` | Loading spinner |
|
|
351
|
+
| `chalk` | Terminal colors |
|
|
352
|
+
| `ink-text-input` | Base text input (extended by CjkTextInput) |
|
|
353
|
+
| `marked`, `marked-terminal` | Markdown parsing and terminal rendering |
|
|
354
|
+
| `cli-highlight` | Syntax highlighting for code blocks |
|
|
355
|
+
| `string-width` | Unicode-aware string width (CJK support) |
|
|
332
356
|
|
|
333
357
|
## Documentation
|
|
334
358
|
|
package/dist/node/bin.js
CHANGED
|
@@ -40,6 +40,9 @@ function parseCliArgs() {
|
|
|
40
40
|
"max-turns": { type: "string" },
|
|
41
41
|
"fork-session": { type: "boolean", default: false },
|
|
42
42
|
name: { type: "string", short: "n" },
|
|
43
|
+
"output-format": { type: "string" },
|
|
44
|
+
"system-prompt": { type: "string" },
|
|
45
|
+
"append-system-prompt": { type: "string" },
|
|
43
46
|
version: { type: "boolean", default: false },
|
|
44
47
|
reset: { type: "boolean", default: false }
|
|
45
48
|
}
|
|
@@ -55,6 +58,9 @@ function parseCliArgs() {
|
|
|
55
58
|
maxTurns: parseMaxTurns(values["max-turns"]),
|
|
56
59
|
forkSession: values["fork-session"] ?? false,
|
|
57
60
|
sessionName: values["name"],
|
|
61
|
+
outputFormat: values["output-format"],
|
|
62
|
+
systemPrompt: values["system-prompt"],
|
|
63
|
+
appendSystemPrompt: values["append-system-prompt"],
|
|
58
64
|
version: values["version"] ?? false,
|
|
59
65
|
reset: values["reset"] ?? false
|
|
60
66
|
};
|
|
@@ -134,6 +140,9 @@ function createProviderFromSettings(cwd, modelOverride) {
|
|
|
134
140
|
}
|
|
135
141
|
}
|
|
136
142
|
|
|
143
|
+
// src/cli.ts
|
|
144
|
+
import { createHeadlessTransport } from "@robota-sdk/agent-transport-headless";
|
|
145
|
+
|
|
137
146
|
// src/ui/render.tsx
|
|
138
147
|
import { render } from "ink";
|
|
139
148
|
|
|
@@ -911,9 +920,7 @@ function CjkTextInput({
|
|
|
911
920
|
const pasteBufferRef = useRef2("");
|
|
912
921
|
if (value !== valueRef.current) {
|
|
913
922
|
valueRef.current = value;
|
|
914
|
-
|
|
915
|
-
cursorRef.current = value.length;
|
|
916
|
-
}
|
|
923
|
+
cursorRef.current = value.length;
|
|
917
924
|
}
|
|
918
925
|
useInput(
|
|
919
926
|
(input, key) => {
|
|
@@ -1194,23 +1201,23 @@ function InputArea({
|
|
|
1194
1201
|
const label = `[Pasted text #${id} +${lineCount} lines]`;
|
|
1195
1202
|
setValue((prev) => prev ? `${prev} ${label}` : label);
|
|
1196
1203
|
}, []);
|
|
1197
|
-
const
|
|
1198
|
-
(
|
|
1199
|
-
const
|
|
1200
|
-
if (
|
|
1201
|
-
|
|
1202
|
-
selectCommand(filteredCommands[selectedIndex]);
|
|
1204
|
+
const tabCompleteCommand = useCallback2(
|
|
1205
|
+
(cmd) => {
|
|
1206
|
+
const parsed = parseSlashInput(value);
|
|
1207
|
+
if (parsed.parentCommand) {
|
|
1208
|
+
setValue(`/${parsed.parentCommand} ${cmd.name} `);
|
|
1203
1209
|
return;
|
|
1204
1210
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1211
|
+
if (cmd.subcommands && cmd.subcommands.length > 0) {
|
|
1212
|
+
setValue(`/${cmd.name} `);
|
|
1213
|
+
setSelectedIndex(0);
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
setValue(`/${cmd.name} `);
|
|
1210
1217
|
},
|
|
1211
|
-
[
|
|
1218
|
+
[value, setSelectedIndex]
|
|
1212
1219
|
);
|
|
1213
|
-
const
|
|
1220
|
+
const enterSelectCommand = useCallback2(
|
|
1214
1221
|
(cmd) => {
|
|
1215
1222
|
const parsed = parseSlashInput(value);
|
|
1216
1223
|
if (parsed.parentCommand) {
|
|
@@ -1229,6 +1236,22 @@ function InputArea({
|
|
|
1229
1236
|
},
|
|
1230
1237
|
[value, onSubmit, setSelectedIndex]
|
|
1231
1238
|
);
|
|
1239
|
+
const handleSubmit = useCallback2(
|
|
1240
|
+
(text) => {
|
|
1241
|
+
const trimmed = text.trim();
|
|
1242
|
+
if (trimmed.length === 0) return;
|
|
1243
|
+
if (showPopup && filteredCommands[selectedIndex]) {
|
|
1244
|
+
enterSelectCommand(filteredCommands[selectedIndex]);
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1247
|
+
const expanded = expandPasteLabels(trimmed, pasteStore.current);
|
|
1248
|
+
setValue("");
|
|
1249
|
+
pasteStore.current.clear();
|
|
1250
|
+
pasteIdRef.current = 0;
|
|
1251
|
+
onSubmit(expanded);
|
|
1252
|
+
},
|
|
1253
|
+
[showPopup, filteredCommands, selectedIndex, onSubmit, enterSelectCommand]
|
|
1254
|
+
);
|
|
1232
1255
|
useInput2(
|
|
1233
1256
|
(_input, key) => {
|
|
1234
1257
|
if (!showPopup) return;
|
|
@@ -1240,7 +1263,7 @@ function InputArea({
|
|
|
1240
1263
|
setShowPopup(false);
|
|
1241
1264
|
} else if (key.tab) {
|
|
1242
1265
|
const cmd = filteredCommands[selectedIndex];
|
|
1243
|
-
if (cmd)
|
|
1266
|
+
if (cmd) tabCompleteCommand(cmd);
|
|
1244
1267
|
}
|
|
1245
1268
|
},
|
|
1246
1269
|
{ isActive: showPopup && !isDisabled }
|
|
@@ -2446,8 +2469,15 @@ async function startCli() {
|
|
|
2446
2469
|
}
|
|
2447
2470
|
}
|
|
2448
2471
|
if (args.printMode) {
|
|
2449
|
-
|
|
2450
|
-
if (prompt
|
|
2472
|
+
let prompt = args.positional.join(" ").trim();
|
|
2473
|
+
if (!prompt && !process.stdin.isTTY) {
|
|
2474
|
+
const chunks = [];
|
|
2475
|
+
for await (const chunk of process.stdin) {
|
|
2476
|
+
chunks.push(chunk);
|
|
2477
|
+
}
|
|
2478
|
+
prompt = Buffer.concat(chunks).toString("utf-8").trim();
|
|
2479
|
+
}
|
|
2480
|
+
if (!prompt) {
|
|
2451
2481
|
process.stderr.write("Print mode (-p) requires a prompt argument.\n");
|
|
2452
2482
|
process.exit(1);
|
|
2453
2483
|
}
|
|
@@ -2459,19 +2489,13 @@ async function startCli() {
|
|
|
2459
2489
|
sessionStore,
|
|
2460
2490
|
sessionName: args.sessionName
|
|
2461
2491
|
});
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
resolve();
|
|
2466
|
-
});
|
|
2467
|
-
session.on("interrupted", (result) => {
|
|
2468
|
-
if (result.response) process.stdout.write(result.response + "\n");
|
|
2469
|
-
resolve();
|
|
2470
|
-
});
|
|
2471
|
-
session.on("error", (err) => reject(err));
|
|
2472
|
-
session.submit(prompt).catch(reject);
|
|
2492
|
+
const transport = createHeadlessTransport({
|
|
2493
|
+
outputFormat: args.outputFormat ?? "text",
|
|
2494
|
+
prompt
|
|
2473
2495
|
});
|
|
2474
|
-
|
|
2496
|
+
session.attachTransport(transport);
|
|
2497
|
+
await transport.start();
|
|
2498
|
+
process.exit(transport.getExitCode());
|
|
2475
2499
|
}
|
|
2476
2500
|
renderApp({
|
|
2477
2501
|
cwd,
|
package/dist/node/index.cjs
CHANGED
|
@@ -76,6 +76,9 @@ function parseCliArgs() {
|
|
|
76
76
|
"max-turns": { type: "string" },
|
|
77
77
|
"fork-session": { type: "boolean", default: false },
|
|
78
78
|
name: { type: "string", short: "n" },
|
|
79
|
+
"output-format": { type: "string" },
|
|
80
|
+
"system-prompt": { type: "string" },
|
|
81
|
+
"append-system-prompt": { type: "string" },
|
|
79
82
|
version: { type: "boolean", default: false },
|
|
80
83
|
reset: { type: "boolean", default: false }
|
|
81
84
|
}
|
|
@@ -91,6 +94,9 @@ function parseCliArgs() {
|
|
|
91
94
|
maxTurns: parseMaxTurns(values["max-turns"]),
|
|
92
95
|
forkSession: values["fork-session"] ?? false,
|
|
93
96
|
sessionName: values["name"],
|
|
97
|
+
outputFormat: values["output-format"],
|
|
98
|
+
systemPrompt: values["system-prompt"],
|
|
99
|
+
appendSystemPrompt: values["append-system-prompt"],
|
|
94
100
|
version: values["version"] ?? false,
|
|
95
101
|
reset: values["reset"] ?? false
|
|
96
102
|
};
|
|
@@ -170,6 +176,9 @@ function createProviderFromSettings(cwd, modelOverride) {
|
|
|
170
176
|
}
|
|
171
177
|
}
|
|
172
178
|
|
|
179
|
+
// src/cli.ts
|
|
180
|
+
var import_agent_transport_headless = require("@robota-sdk/agent-transport-headless");
|
|
181
|
+
|
|
173
182
|
// src/ui/render.tsx
|
|
174
183
|
var import_ink15 = require("ink");
|
|
175
184
|
|
|
@@ -934,9 +943,7 @@ function CjkTextInput({
|
|
|
934
943
|
const pasteBufferRef = (0, import_react4.useRef)("");
|
|
935
944
|
if (value !== valueRef.current) {
|
|
936
945
|
valueRef.current = value;
|
|
937
|
-
|
|
938
|
-
cursorRef.current = value.length;
|
|
939
|
-
}
|
|
946
|
+
cursorRef.current = value.length;
|
|
940
947
|
}
|
|
941
948
|
(0, import_ink4.useInput)(
|
|
942
949
|
(input, key) => {
|
|
@@ -1217,23 +1224,23 @@ function InputArea({
|
|
|
1217
1224
|
const label = `[Pasted text #${id} +${lineCount} lines]`;
|
|
1218
1225
|
setValue((prev) => prev ? `${prev} ${label}` : label);
|
|
1219
1226
|
}, []);
|
|
1220
|
-
const
|
|
1221
|
-
(
|
|
1222
|
-
const
|
|
1223
|
-
if (
|
|
1224
|
-
|
|
1225
|
-
selectCommand(filteredCommands[selectedIndex]);
|
|
1227
|
+
const tabCompleteCommand = (0, import_react6.useCallback)(
|
|
1228
|
+
(cmd) => {
|
|
1229
|
+
const parsed = parseSlashInput(value);
|
|
1230
|
+
if (parsed.parentCommand) {
|
|
1231
|
+
setValue(`/${parsed.parentCommand} ${cmd.name} `);
|
|
1226
1232
|
return;
|
|
1227
1233
|
}
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1234
|
+
if (cmd.subcommands && cmd.subcommands.length > 0) {
|
|
1235
|
+
setValue(`/${cmd.name} `);
|
|
1236
|
+
setSelectedIndex(0);
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
setValue(`/${cmd.name} `);
|
|
1233
1240
|
},
|
|
1234
|
-
[
|
|
1241
|
+
[value, setSelectedIndex]
|
|
1235
1242
|
);
|
|
1236
|
-
const
|
|
1243
|
+
const enterSelectCommand = (0, import_react6.useCallback)(
|
|
1237
1244
|
(cmd) => {
|
|
1238
1245
|
const parsed = parseSlashInput(value);
|
|
1239
1246
|
if (parsed.parentCommand) {
|
|
@@ -1252,6 +1259,22 @@ function InputArea({
|
|
|
1252
1259
|
},
|
|
1253
1260
|
[value, onSubmit, setSelectedIndex]
|
|
1254
1261
|
);
|
|
1262
|
+
const handleSubmit = (0, import_react6.useCallback)(
|
|
1263
|
+
(text) => {
|
|
1264
|
+
const trimmed = text.trim();
|
|
1265
|
+
if (trimmed.length === 0) return;
|
|
1266
|
+
if (showPopup && filteredCommands[selectedIndex]) {
|
|
1267
|
+
enterSelectCommand(filteredCommands[selectedIndex]);
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
const expanded = expandPasteLabels(trimmed, pasteStore.current);
|
|
1271
|
+
setValue("");
|
|
1272
|
+
pasteStore.current.clear();
|
|
1273
|
+
pasteIdRef.current = 0;
|
|
1274
|
+
onSubmit(expanded);
|
|
1275
|
+
},
|
|
1276
|
+
[showPopup, filteredCommands, selectedIndex, onSubmit, enterSelectCommand]
|
|
1277
|
+
);
|
|
1255
1278
|
(0, import_ink7.useInput)(
|
|
1256
1279
|
(_input, key) => {
|
|
1257
1280
|
if (!showPopup) return;
|
|
@@ -1263,7 +1286,7 @@ function InputArea({
|
|
|
1263
1286
|
setShowPopup(false);
|
|
1264
1287
|
} else if (key.tab) {
|
|
1265
1288
|
const cmd = filteredCommands[selectedIndex];
|
|
1266
|
-
if (cmd)
|
|
1289
|
+
if (cmd) tabCompleteCommand(cmd);
|
|
1267
1290
|
}
|
|
1268
1291
|
},
|
|
1269
1292
|
{ isActive: showPopup && !isDisabled }
|
|
@@ -2470,8 +2493,15 @@ async function startCli() {
|
|
|
2470
2493
|
}
|
|
2471
2494
|
}
|
|
2472
2495
|
if (args.printMode) {
|
|
2473
|
-
|
|
2474
|
-
if (prompt
|
|
2496
|
+
let prompt = args.positional.join(" ").trim();
|
|
2497
|
+
if (!prompt && !process.stdin.isTTY) {
|
|
2498
|
+
const chunks = [];
|
|
2499
|
+
for await (const chunk of process.stdin) {
|
|
2500
|
+
chunks.push(chunk);
|
|
2501
|
+
}
|
|
2502
|
+
prompt = Buffer.concat(chunks).toString("utf-8").trim();
|
|
2503
|
+
}
|
|
2504
|
+
if (!prompt) {
|
|
2475
2505
|
process.stderr.write("Print mode (-p) requires a prompt argument.\n");
|
|
2476
2506
|
process.exit(1);
|
|
2477
2507
|
}
|
|
@@ -2483,19 +2513,13 @@ async function startCli() {
|
|
|
2483
2513
|
sessionStore,
|
|
2484
2514
|
sessionName: args.sessionName
|
|
2485
2515
|
});
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
resolve();
|
|
2490
|
-
});
|
|
2491
|
-
session.on("interrupted", (result) => {
|
|
2492
|
-
if (result.response) process.stdout.write(result.response + "\n");
|
|
2493
|
-
resolve();
|
|
2494
|
-
});
|
|
2495
|
-
session.on("error", (err) => reject(err));
|
|
2496
|
-
session.submit(prompt).catch(reject);
|
|
2516
|
+
const transport = (0, import_agent_transport_headless.createHeadlessTransport)({
|
|
2517
|
+
outputFormat: args.outputFormat ?? "text",
|
|
2518
|
+
prompt
|
|
2497
2519
|
});
|
|
2498
|
-
|
|
2520
|
+
session.attachTransport(transport);
|
|
2521
|
+
await transport.start();
|
|
2522
|
+
process.exit(transport.getExitCode());
|
|
2499
2523
|
}
|
|
2500
2524
|
renderApp({
|
|
2501
2525
|
cwd,
|
package/dist/node/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robota-sdk/agent-cli",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.47",
|
|
4
4
|
"description": "AI coding assistant CLI built on Robota SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@robota-sdk/agent-sessions": "3.0.0-beta.
|
|
28
|
+
"@robota-sdk/agent-sessions": "3.0.0-beta.47",
|
|
29
29
|
"chalk": "^5.3.0",
|
|
30
30
|
"cli-highlight": "^2.1.0",
|
|
31
31
|
"ink": "^6.8.0",
|
|
@@ -36,9 +36,10 @@
|
|
|
36
36
|
"marked-terminal": "^7.3.0",
|
|
37
37
|
"react": "19.2.4",
|
|
38
38
|
"string-width": "^8.2.0",
|
|
39
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
40
|
-
"@robota-sdk/agent-sdk": "3.0.0-beta.
|
|
41
|
-
"@robota-sdk/agent-provider-anthropic": "3.0.0-beta.
|
|
39
|
+
"@robota-sdk/agent-core": "3.0.0-beta.47",
|
|
40
|
+
"@robota-sdk/agent-sdk": "3.0.0-beta.47",
|
|
41
|
+
"@robota-sdk/agent-provider-anthropic": "3.0.0-beta.47",
|
|
42
|
+
"@robota-sdk/agent-transport-headless": "3.0.0-beta.47"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
45
|
"@types/marked": "^6.0.0",
|