@robota-sdk/agent-cli 3.0.0-beta.7 → 3.0.0-beta.71
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 +414 -114
- package/bin/robota.cjs +47 -0
- package/dist/node/bin.d.ts +2 -1
- package/dist/node/bin.js +57 -10
- package/dist/node/bin.js.map +1 -0
- package/dist/node/child-process-subagent-ipc--Vp2dk1v.js +2 -0
- package/dist/node/child-process-subagent-ipc--Vp2dk1v.js.map +1 -0
- package/dist/node/child-process-subagent-ipc-Aitv2i6E.cjs +1 -0
- package/dist/node/child-process-subagent-ipc-CEy8bLN6.cjs +1 -0
- package/dist/node/child-process-subagent-ipc-DVpVp43R.js +2 -0
- package/dist/node/child-process-subagent-ipc-DVpVp43R.js.map +1 -0
- package/dist/node/cli.cjs +1 -0
- package/dist/node/cli.d.ts +7 -0
- package/dist/node/cli.d.ts.map +1 -0
- package/dist/node/cli.js +2 -0
- package/dist/node/cli.js.map +1 -0
- package/dist/node/constants.cjs +1 -0
- package/dist/node/constants.js +2 -0
- package/dist/node/constants.js.map +1 -0
- package/dist/node/index.cjs +49 -1257
- package/dist/node/index.d.ts +12 -47
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +50 -13
- package/dist/node/index.js.map +1 -0
- package/dist/node/init/init-command.cjs +32 -0
- package/dist/node/init/init-command.js +33 -0
- package/dist/node/init/init-command.js.map +1 -0
- package/dist/node/modes/print-mode.cjs +6 -0
- package/dist/node/modes/print-mode.js +7 -0
- package/dist/node/modes/print-mode.js.map +1 -0
- package/dist/node/modes/shell-exec.cjs +1 -0
- package/dist/node/modes/shell-exec.js +2 -0
- package/dist/node/modes/shell-exec.js.map +1 -0
- package/dist/node/modes/tui-mode.cjs +1 -0
- package/dist/node/modes/tui-mode.js +2 -0
- package/dist/node/modes/tui-mode.js.map +1 -0
- package/dist/node/provider-default-definitions-CKtxv2k0.js +2 -0
- package/dist/node/provider-default-definitions-CKtxv2k0.js.map +1 -0
- package/dist/node/provider-default-definitions-GFiYzACo.cjs +1 -0
- package/dist/node/provider-default-definitions-g0ZUDeii.cjs +1 -0
- package/dist/node/startup/append-system-prompt.cjs +3 -0
- package/dist/node/startup/append-system-prompt.js +4 -0
- package/dist/node/startup/append-system-prompt.js.map +1 -0
- package/dist/node/startup/args-to-options.cjs +1 -0
- package/dist/node/startup/args-to-options.js +2 -0
- package/dist/node/startup/args-to-options.js.map +1 -0
- package/dist/node/startup/command-setup.cjs +1 -0
- package/dist/node/startup/command-setup.d.ts +11 -0
- package/dist/node/startup/command-setup.d.ts.map +1 -0
- package/dist/node/startup/command-setup.js +2 -0
- package/dist/node/startup/command-setup.js.map +1 -0
- package/dist/node/startup/config-phase.cjs +1 -0
- package/dist/node/startup/config-phase.js +2 -0
- package/dist/node/startup/config-phase.js.map +1 -0
- package/dist/node/startup/preflight.cjs +1 -0
- package/dist/node/startup/preflight.js +2 -0
- package/dist/node/startup/preflight.js.map +1 -0
- package/dist/node/startup/provider-setup.cjs +1 -0
- package/dist/node/startup/provider-setup.js +2 -0
- package/dist/node/startup/provider-setup.js.map +1 -0
- package/dist/node/startup/provider-startup.cjs +2 -0
- package/dist/node/startup/provider-startup.js +3 -0
- package/dist/node/startup/provider-startup.js.map +1 -0
- package/dist/node/startup/reset-config.cjs +1 -0
- package/dist/node/startup/reset-config.js +2 -0
- package/dist/node/startup/reset-config.js.map +1 -0
- package/dist/node/startup/session-setup.cjs +1 -0
- package/dist/node/startup/session-setup.js +2 -0
- package/dist/node/startup/session-setup.js.map +1 -0
- package/dist/node/startup/subagent-setup.cjs +1 -0
- package/dist/node/startup/subagent-setup.js +2 -0
- package/dist/node/startup/subagent-setup.js.map +1 -0
- package/dist/node/startup/update-notice.cjs +1 -0
- package/dist/node/startup/update-notice.js +2 -0
- package/dist/node/startup/update-notice.js.map +1 -0
- package/dist/node/startup/version.cjs +1 -0
- package/dist/node/startup/version.js +2 -0
- package/dist/node/startup/version.js.map +1 -0
- package/dist/node/subagents/child-process-subagent-worker.cjs +1 -0
- package/dist/node/subagents/child-process-subagent-worker.d.ts +1 -0
- package/dist/node/subagents/child-process-subagent-worker.js +2 -0
- package/dist/node/subagents/child-process-subagent-worker.js.map +1 -0
- package/dist/node/user-local-direct-command.cjs +1 -0
- package/dist/node/user-local-direct-command.js +2 -0
- package/dist/node/user-local-direct-command.js.map +1 -0
- package/dist/node/utils/cli-args.cjs +35 -0
- package/dist/node/utils/cli-args.js +36 -0
- package/dist/node/utils/cli-args.js.map +1 -0
- package/package.json +52 -16
- package/dist/node/bin.cjs +0 -1240
- package/dist/node/bin.d.cts +0 -1
- package/dist/node/chunk-A2A66S6Q.js +0 -1219
- package/dist/node/index.d.cts +0 -49
package/README.md
CHANGED
|
@@ -1,17 +1,72 @@
|
|
|
1
|
+
**Language:** [English](README.md) | [한국어](docs/README-KO.md)
|
|
2
|
+
|
|
3
|
+
> **Beta software** — currently `3.0.0-beta`. APIs and behavior may change before stable release.
|
|
4
|
+
> Please [report issues](https://github.com/woojubb/robota/issues) to help us improve.
|
|
5
|
+
|
|
1
6
|
# @robota-sdk/agent-cli
|
|
2
7
|
|
|
3
|
-
AI coding assistant CLI built on Robota SDK. Loads AGENTS.md/CLAUDE.md for project context and provides tool-calling REPL with Claude Code-compatible permission modes.
|
|
8
|
+
AI coding assistant CLI built on Robota SDK. Loads AGENTS.md/CLAUDE.md for project context and provides a tool-calling REPL with Claude Code-compatible permission modes.
|
|
4
9
|
|
|
5
|
-
##
|
|
10
|
+
## Why Robota?
|
|
11
|
+
|
|
12
|
+
| | Robota | Claude Code | Aider |
|
|
13
|
+
| ------------------------------------------------- | :----: | :---------: | :---: |
|
|
14
|
+
| Multi-provider (Anthropic, OpenAI, Gemini, Qwen…) | ✅ | ❌ | ✅ |
|
|
15
|
+
| Embed SDK in your own app | ✅ | ❌ | ❌ |
|
|
16
|
+
| Local models (LM Studio, Ollama via OpenAI API) | ✅ | ❌ | ✅ |
|
|
17
|
+
| Open source (MIT) | ✅ | partial | ✅ |
|
|
18
|
+
| Claude Code config compatible (CLAUDE.md, modes) | ✅ | — | ❌ |
|
|
19
|
+
|
|
20
|
+
## Embed in Your App
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { createAgentRuntime } from '@robota-sdk/agent-framework';
|
|
24
|
+
import { createAnthropicProvider } from '@robota-sdk/agent-provider';
|
|
25
|
+
|
|
26
|
+
const runtime = createAgentRuntime({
|
|
27
|
+
provider: createAnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
|
|
28
|
+
});
|
|
29
|
+
const session = runtime.createSession({ permissionMode: 'bypassPermissions' });
|
|
30
|
+
const response = await session.submit('Explain this codebase');
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Prerequisites
|
|
34
|
+
|
|
35
|
+
Node.js **22 or higher** is required. The TUI renderer ([ink 7.x](https://github.com/vadimdemedes/ink)) requires Node.js 22+.
|
|
6
36
|
|
|
7
37
|
```bash
|
|
8
|
-
#
|
|
9
|
-
|
|
38
|
+
node --version # Must output v22.x.x or higher
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If your version is below 22, upgrade using one of:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# nvm
|
|
45
|
+
nvm install 22 && nvm use 22
|
|
46
|
+
|
|
47
|
+
# Volta
|
|
48
|
+
volta install node@22
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Demo
|
|
52
|
+
|
|
53
|
+
<!-- TODO: Add demo GIF here -->
|
|
54
|
+
<!-- Run `pnpm demo:record` to capture a demo recording — see docs/demo-script.md for instructions -->
|
|
55
|
+
|
|
56
|
+

|
|
57
|
+
|
|
58
|
+
## Installation
|
|
10
59
|
|
|
11
|
-
|
|
60
|
+
```bash
|
|
61
|
+
# Try it now — no install needed
|
|
12
62
|
npx @robota-sdk/agent-cli
|
|
63
|
+
|
|
64
|
+
# Install globally for persistent use
|
|
65
|
+
npm install -g @robota-sdk/agent-cli
|
|
13
66
|
```
|
|
14
67
|
|
|
68
|
+
> **macOS users**: Korean/CJK IME input may crash macOS Terminal.app. Use **[iTerm2](https://iterm2.com/)** instead. This is a known Ink + Terminal.app issue shared with Claude Code.
|
|
69
|
+
|
|
15
70
|
After installing globally, the `robota` command is available system-wide:
|
|
16
71
|
|
|
17
72
|
```bash
|
|
@@ -22,9 +77,14 @@ robota -p "List all files" # Print mode (one-shot, exit after response)
|
|
|
22
77
|
|
|
23
78
|
### Environment Variables
|
|
24
79
|
|
|
25
|
-
| Variable | Description
|
|
26
|
-
| ------------------- |
|
|
27
|
-
| `ANTHROPIC_API_KEY` | Anthropic API key
|
|
80
|
+
| Variable | Description | Provider |
|
|
81
|
+
| ------------------- | -------------------------------------------------------- | --------- |
|
|
82
|
+
| `ANTHROPIC_API_KEY` | Anthropic API key | Anthropic |
|
|
83
|
+
| `OPENAI_API_KEY` | OpenAI API key | OpenAI |
|
|
84
|
+
| `GEMINI_API_KEY` | Google Gemini API key | Gemini |
|
|
85
|
+
| `DEEPSEEK_API_KEY` | DeepSeek API key | DeepSeek |
|
|
86
|
+
| `DASHSCOPE_API_KEY` | Alibaba Cloud Model Studio key | Qwen |
|
|
87
|
+
| `BRAVE_API_KEY` | Brave Search API key (optional — enables WebSearch tool) | WebSearch |
|
|
28
88
|
|
|
29
89
|
Set your key before running:
|
|
30
90
|
|
|
@@ -35,11 +95,7 @@ export ANTHROPIC_API_KEY=sk-ant-...
|
|
|
35
95
|
## Development Setup (Monorepo)
|
|
36
96
|
|
|
37
97
|
```bash
|
|
38
|
-
#
|
|
39
|
-
cp packages/agent-cli/.env.example packages/agent-cli/.env
|
|
40
|
-
# Edit .env and set ANTHROPIC_API_KEY=sk-ant-...
|
|
41
|
-
|
|
42
|
-
# 2. Build dependencies and CLI
|
|
98
|
+
# Build dependencies and CLI
|
|
43
99
|
pnpm build:deps
|
|
44
100
|
pnpm --filter @robota-sdk/agent-cli build
|
|
45
101
|
```
|
|
@@ -50,7 +106,7 @@ pnpm --filter @robota-sdk/agent-cli build
|
|
|
50
106
|
# From monorepo root
|
|
51
107
|
cd packages/agent-cli
|
|
52
108
|
|
|
53
|
-
# Development mode (no build needed
|
|
109
|
+
# Development mode (no build needed)
|
|
54
110
|
pnpm dev
|
|
55
111
|
|
|
56
112
|
# Production mode (requires build)
|
|
@@ -70,74 +126,142 @@ robota "prompt" # REPL with initial prompt
|
|
|
70
126
|
robota -p "prompt" # Print mode (one-shot, exit after response)
|
|
71
127
|
robota -c # Continue last session
|
|
72
128
|
robota -r <session-id> # Resume session by ID
|
|
73
|
-
robota --
|
|
129
|
+
robota --language <lang> # Response language (ko, en, ja, zh)
|
|
74
130
|
robota --permission-mode <mode> # plan | default | acceptEdits | bypassPermissions
|
|
75
131
|
robota --max-turns <n> # Limit agentic turns per interaction
|
|
132
|
+
robota --output-format <fmt> # text | json | stream-json (print mode)
|
|
133
|
+
robota --system-prompt <text> # Replace system prompt (print mode)
|
|
134
|
+
robota --append-system-prompt <text> # Append to system prompt (print mode)
|
|
135
|
+
robota --model claude-opus-4-7 # Override provider model for this session
|
|
136
|
+
robota --allowed-tools "Bash,Read" # Whitelist specific tools
|
|
137
|
+
robota --denied-tools "Bash,Write" # Blacklist specific tools (denied > allowed)
|
|
138
|
+
robota --reset # Delete user settings and exit
|
|
139
|
+
robota --check-update # Check npm for a newer CLI version and exit
|
|
140
|
+
robota --disable-update-check # Skip interactive startup update check for this run
|
|
76
141
|
robota --version # Show version
|
|
77
142
|
```
|
|
78
143
|
|
|
79
|
-
|
|
144
|
+
### CLI Updates
|
|
80
145
|
|
|
81
|
-
|
|
146
|
+
Robota can check npm for a newer `@robota-sdk/agent-cli` version:
|
|
82
147
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
| `Read` | Read file contents with line numbers | `filePath` |
|
|
87
|
-
| `Write` | Write content to a file | `filePath` |
|
|
88
|
-
| `Edit` | Replace a string in a file | `filePath` |
|
|
89
|
-
| `Glob` | Find files matching a pattern | `pattern` |
|
|
90
|
-
| `Grep` | Search file contents with regex | `pattern` |
|
|
148
|
+
```bash
|
|
149
|
+
robota --check-update
|
|
150
|
+
```
|
|
91
151
|
|
|
92
|
-
|
|
152
|
+
When an update is available, Robota prints the npm global install command:
|
|
93
153
|
|
|
94
|
-
|
|
154
|
+
```bash
|
|
155
|
+
npm install -g '@robota-sdk/agent-cli@latest'
|
|
156
|
+
```
|
|
95
157
|
|
|
96
|
-
|
|
97
|
-
2. **Allow list** — if any allow pattern matches, the action is auto-approved
|
|
98
|
-
3. **Mode policy** — the active permission mode determines the decision
|
|
158
|
+
Robota does not implement its own updater and does not modify `~/.robota/settings.json` for update checks. Interactive startup checks use a user-level operational cache at `~/.robota/update-check.json` and can be skipped for one run with `--disable-update-check`. Print/headless mode (`robota -p`) does not perform automatic startup update checks so scripted stdout and stderr remain deterministic.
|
|
99
159
|
|
|
100
|
-
|
|
160
|
+
### Print Mode Output Formats
|
|
101
161
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
162
|
+
Print mode (`-p`) supports three output formats via `--output-format`:
|
|
163
|
+
|
|
164
|
+
| Format | Description |
|
|
165
|
+
| ------------- | ------------------------------------------------------------------ |
|
|
166
|
+
| `text` | Plain text response to stdout (default) |
|
|
167
|
+
| `json` | Single JSON object: `{ type, result, session_id, subtype }` |
|
|
168
|
+
| `stream-json` | Newline-delimited JSON with `content_block_delta` streaming events |
|
|
169
|
+
|
|
170
|
+
### Exit Codes (print mode)
|
|
171
|
+
|
|
172
|
+
| Code | Meaning |
|
|
173
|
+
| ---- | ---------------------------------------------- |
|
|
174
|
+
| 0 | Success |
|
|
175
|
+
| 1 | General error |
|
|
176
|
+
| 2 | Argument error |
|
|
177
|
+
| 3 | Configuration error (missing provider/API key) |
|
|
178
|
+
| 4 | API error |
|
|
179
|
+
| 5 | Tool execution error |
|
|
180
|
+
|
|
181
|
+
### Stdin Pipe
|
|
182
|
+
|
|
183
|
+
When stdin is piped, the CLI reads it automatically. If a positional prompt is also given, the piped content is appended inside `<stdin>` tags:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
echo "Explain this error" | robota -p
|
|
187
|
+
cat file.ts | robota -p "Review this code" --output-format json
|
|
188
|
+
git diff | robota -p "Summarize changes" --output-format stream-json
|
|
106
189
|
```
|
|
107
190
|
|
|
108
|
-
-
|
|
109
|
-
- Press Enter or type anything else to deny
|
|
191
|
+
## First-Run Setup
|
|
110
192
|
|
|
111
|
-
|
|
193
|
+
When no usable settings file exists, the CLI prompts for:
|
|
112
194
|
|
|
113
|
-
|
|
195
|
+
1. **Provider selection** from the providers assembled into the CLI binary
|
|
196
|
+
2. **Provider-specific setup fields** such as model, base URL, and masked API key
|
|
197
|
+
3. **Response language** (ko/en/ja/zh, default: en)
|
|
114
198
|
|
|
115
|
-
|
|
116
|
-
| ------------------- | -------- | :------------: | :--------: | :-----: |
|
|
117
|
-
| `plan` | safe | auto | deny | deny |
|
|
118
|
-
| `default` | moderate | auto | approve | approve |
|
|
119
|
-
| `acceptEdits` | full | auto | auto | approve |
|
|
120
|
-
| `bypassPermissions` | — | auto | auto | auto |
|
|
199
|
+
Creates `~/.robota/settings.json`. Use `robota --reset` to return to first-run state.
|
|
121
200
|
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
|
|
201
|
+
Provider setup is generated from provider definitions. The default CLI build includes Anthropic,
|
|
202
|
+
OpenAI-compatible, DeepSeek, Gemma, and Qwen providers; other embeddings can inject their own
|
|
203
|
+
provider definitions.
|
|
204
|
+
Interactive setup creates a readable profile key from the selected model id, such as
|
|
205
|
+
`claude-sonnet-4-6` or `gpt-4o`, and appends `-2`, `-3`, etc. when that key already exists. Generated
|
|
206
|
+
profile keys never include API keys or credential hints.
|
|
125
207
|
|
|
126
|
-
|
|
208
|
+
Inside the TUI, `/provider` and `/provider list` show configured profiles as an interactive picker. Selecting a profile opens command-owned actions for switch, edit, test, duplicate, delete, and cancel. Headless mode prints the same profile list text without opening prompts.
|
|
127
209
|
|
|
128
|
-
|
|
210
|
+
Non-interactive/headless mode never prompts. Configure a provider ahead of time with `robota --configure` in an interactive terminal, or use `robota --configure-provider <profile> --type <type> ... --set-current`.
|
|
129
211
|
|
|
130
|
-
|
|
212
|
+
## Built-in Tools
|
|
131
213
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
214
|
+
The AI agent can invoke 8 local tools:
|
|
215
|
+
|
|
216
|
+
| Tool | Description | Primary Argument |
|
|
217
|
+
| ----------- | ---------------------------------------------- | ---------------- |
|
|
218
|
+
| `Bash` | Execute shell commands | `command` |
|
|
219
|
+
| `Read` | Read file contents with line numbers | `filePath` |
|
|
220
|
+
| `Write` | Write content to a file | `filePath` |
|
|
221
|
+
| `Edit` | Replace a string in a file | `filePath` |
|
|
222
|
+
| `Glob` | Find files matching a pattern | `pattern` |
|
|
223
|
+
| `Grep` | Search file contents with regex | `pattern` |
|
|
224
|
+
| `WebFetch` | Fetch URL content as text | `url` |
|
|
225
|
+
| `WebSearch` | Search the internet (requires `BRAVE_API_KEY`) | `query` |
|
|
226
|
+
|
|
227
|
+
> **WebSearch** requires a `BRAVE_API_KEY` environment variable. Without it, the tool returns a setup message instead of results. Get a free key at [brave.com/search/api](https://brave.com/search/api/) (2,000 queries/month free tier).
|
|
135
228
|
|
|
136
|
-
|
|
137
|
-
|
|
229
|
+
## Recent TUI Capabilities
|
|
230
|
+
|
|
231
|
+
- Provider setup and profile management are generated from provider definitions, so the default CLI
|
|
232
|
+
build can configure, switch, edit, test, duplicate, and delete Anthropic, OpenAI-compatible,
|
|
233
|
+
DeepSeek, Gemma, and Qwen profiles without provider-specific UI branches.
|
|
234
|
+
- Interactive startup can check npm for newer CLI versions; print/headless mode skips startup update checks to keep scripted output deterministic.
|
|
235
|
+
- Long-running sessions show provider usage summaries, status activity, background job tree rows, and collapsed command-output transcripts.
|
|
236
|
+
- Edit results render as context hunks with markdown-friendly diff blocks.
|
|
237
|
+
- Background subagents are real runtime jobs with transcripts and resumable task snapshots.
|
|
238
|
+
- Explicit multi-agent requests use the `/agent` command module batch path through the SDK runtime.
|
|
239
|
+
|
|
240
|
+
## Permission System
|
|
241
|
+
|
|
242
|
+
Every tool call passes through a three-step permission gate:
|
|
243
|
+
|
|
244
|
+
1. **Deny list** — if any deny pattern matches, the action is blocked
|
|
245
|
+
2. **Allow list** — if any allow pattern matches, the action is auto-approved
|
|
246
|
+
3. **Mode policy** — the active permission mode determines the decision
|
|
247
|
+
|
|
248
|
+
### Permission Modes
|
|
249
|
+
|
|
250
|
+
| Mode | Read/Glob/Grep | Write/Edit | Bash |
|
|
251
|
+
| ------------------- | :------------: | :--------: | :-----: |
|
|
252
|
+
| `plan` | auto | deny | deny |
|
|
253
|
+
| `default` | auto | approve | approve |
|
|
254
|
+
| `acceptEdits` | auto | auto | approve |
|
|
255
|
+
| `bypassPermissions` | auto | auto | auto |
|
|
256
|
+
|
|
257
|
+
### Changing Mode at Runtime
|
|
258
|
+
|
|
259
|
+
Use the `/permissions` slash command:
|
|
138
260
|
|
|
139
|
-
|
|
140
|
-
|
|
261
|
+
```
|
|
262
|
+
> /permissions # Show current mode and session-approved tools
|
|
263
|
+
> /permissions plan # Switch to plan (read-only)
|
|
264
|
+
> /permissions bypassPermissions # Skip all prompts
|
|
141
265
|
```
|
|
142
266
|
|
|
143
267
|
Or set it at startup:
|
|
@@ -146,7 +270,7 @@ Or set it at startup:
|
|
|
146
270
|
robota --permission-mode plan
|
|
147
271
|
```
|
|
148
272
|
|
|
149
|
-
### Permission Patterns
|
|
273
|
+
### Permission Patterns
|
|
150
274
|
|
|
151
275
|
Configure in `.robota/settings.json` or `.robota/settings.local.json`:
|
|
152
276
|
|
|
@@ -159,42 +283,167 @@ Configure in `.robota/settings.json` or `.robota/settings.local.json`:
|
|
|
159
283
|
}
|
|
160
284
|
```
|
|
161
285
|
|
|
162
|
-
|
|
286
|
+
Pattern syntax: `ToolName` matches any invocation; `ToolName(pattern)` matches on the primary argument with shell-style globs (`*`, `**`).
|
|
287
|
+
|
|
288
|
+
## Keyboard Controls
|
|
289
|
+
|
|
290
|
+
| Key | Action |
|
|
291
|
+
| ---------- | ----------------------------------------------------------- |
|
|
292
|
+
| Enter | Submit input |
|
|
293
|
+
| ESC | Abort current execution (graceful — saves partial response) |
|
|
294
|
+
| Ctrl+C | Exit process immediately |
|
|
295
|
+
| Up/Down | Navigate visual lines in wrapped multi-line input |
|
|
296
|
+
| Arrow keys | Navigate slash command autocomplete, permission prompt |
|
|
297
|
+
|
|
298
|
+
## Paste Handling
|
|
163
299
|
|
|
164
|
-
|
|
165
|
-
- `ToolName(pattern)` — match when the primary argument matches the glob (e.g., `Bash(pnpm *)`)
|
|
166
|
-
- `*` — zero or more characters (shell-style)
|
|
167
|
-
- `**` — one or more characters (recursive path matching)
|
|
300
|
+
Bracketed paste mode (DECSET 2004) is enabled on startup. When pasting multiline text, the input area collapses it into a label: `[Pasted text #1 +42 lines]`. Multiple pastes are numbered sequentially. The full content is expanded on submit.
|
|
168
301
|
|
|
169
|
-
|
|
302
|
+
Single-line paste is inserted directly as typed text. Terminals without bracketed paste fall back to heuristic detection.
|
|
303
|
+
|
|
304
|
+
## Edit Diff Display
|
|
305
|
+
|
|
306
|
+
After the Edit tool runs, a `DiffBlock` component renders the change inline:
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
✓ Edit(src/provider.ts)
|
|
310
|
+
│ src/provider.ts
|
|
311
|
+
│ - const DEFAULT_MAX_TOKENS = 4096;
|
|
312
|
+
│ + const maxTokens = getModelMaxOutput(modelId);
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Removed lines appear in red with `-`, added lines in green with `+`. Diffs longer than 10 lines show the first 8 + a `... and N more lines` summary.
|
|
316
|
+
|
|
317
|
+
## Session Management
|
|
318
|
+
|
|
319
|
+
The CLI supports continuing, resuming, forking, and naming sessions.
|
|
320
|
+
|
|
321
|
+
### CLI Flags
|
|
322
|
+
|
|
323
|
+
| Flag | Description |
|
|
324
|
+
| --------------------- | ------------------------------------------------ |
|
|
325
|
+
| `-c`, `--continue` | Continue the most recent session |
|
|
326
|
+
| `-r`, `--resume <id>` | Resume a specific session by ID |
|
|
327
|
+
| `--fork-session <id>` | Fork a session (new session with copied history) |
|
|
328
|
+
| `--name <name>` | Assign a name to the session at startup |
|
|
329
|
+
|
|
330
|
+
### TUI Commands
|
|
331
|
+
|
|
332
|
+
| Command | Description |
|
|
333
|
+
| ---------------- | ----------------------------------- |
|
|
334
|
+
| `/resume` | List recent sessions and resume one |
|
|
335
|
+
| `/rename <name>` | Rename the current session |
|
|
336
|
+
|
|
337
|
+
### Session Name Display
|
|
338
|
+
|
|
339
|
+
When a session has a name, it appears in three places:
|
|
340
|
+
|
|
341
|
+
- **Input border** — session name shown in the input area border
|
|
342
|
+
- **Terminal title** — updated via ANSI escape sequences
|
|
343
|
+
- **StatusBar** — displayed alongside activity, model, and context usage
|
|
170
344
|
|
|
171
345
|
## Slash Commands
|
|
172
346
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
|
178
|
-
|
|
|
179
|
-
| `/
|
|
180
|
-
| `/
|
|
181
|
-
| `/
|
|
347
|
+
Typing `/` in the TUI opens an autocomplete popup. Arrow keys navigate, Tab inserts without executing, Enter executes. Subcommands (e.g., `/provider list`) show a nested submenu.
|
|
348
|
+
|
|
349
|
+
### Session & Context
|
|
350
|
+
|
|
351
|
+
| Command | Description |
|
|
352
|
+
| ------------------------- | ---------------------------------------------------------------------- |
|
|
353
|
+
| `/clear` | Clear conversation history |
|
|
354
|
+
| `/compact [instructions]` | Compress context window |
|
|
355
|
+
| `/context` | Context window details, reference inventory, and auto-compact controls |
|
|
356
|
+
| `/cost` | Show session token usage and cost |
|
|
357
|
+
| `/resume` | List recent sessions and resume one |
|
|
358
|
+
| `/rename <name>` | Rename the current session |
|
|
359
|
+
| `/rewind` | List, inspect, restore, or rollback edit checkpoints |
|
|
360
|
+
|
|
361
|
+
### Providers & Settings
|
|
362
|
+
|
|
363
|
+
| Command | Description |
|
|
364
|
+
| ------------------------ | -------------------------------------------------------------------- | ------- | -------------------------------------------------- |
|
|
365
|
+
| `/provider [subcommand]` | Manage provider profiles: `list`, `switch`, `add`, `test`, `current` |
|
|
366
|
+
| `/mode [mode]` | Show or switch permission mode |
|
|
367
|
+
| `/permissions [mode]` | Show permission rules or change permission mode |
|
|
368
|
+
| `/settings` | Open transport settings (enable/disable transports) |
|
|
369
|
+
| `/language [lang]` | Set response language (ko, en, ja, zh), saves and restarts |
|
|
370
|
+
| `/statusline [on | off | reset]` | Configure status-line fields (model, context, git) |
|
|
371
|
+
|
|
372
|
+
### Tools & Memory
|
|
373
|
+
|
|
374
|
+
| Command | Description |
|
|
375
|
+
| ---------------------- | ---------------------------------------------- |
|
|
376
|
+
| `/memory [subcommand]` | Inspect, add, or review project memory entries |
|
|
377
|
+
| `/background` | List and control background tasks |
|
|
378
|
+
| `/agent` | Run and manage background subagent jobs |
|
|
379
|
+
| `/skills [name]` | List registered skills or activate one by name |
|
|
380
|
+
| `/plugin [subcommand]` | Plugin management |
|
|
381
|
+
|
|
382
|
+
### Utility
|
|
383
|
+
|
|
384
|
+
| Command | Description |
|
|
385
|
+
| -------- | -------------------------------------------------- |
|
|
386
|
+
| `/help` | Show available commands |
|
|
387
|
+
| `/reset` | Delete user settings and return to first-run state |
|
|
388
|
+
| `/exit` | Exit CLI |
|
|
389
|
+
|
|
390
|
+
Skill commands discovered from `.agents/skills/` and `.claude/commands/` appear alongside built-in commands.
|
|
391
|
+
|
|
392
|
+
## Plugin Management
|
|
393
|
+
|
|
394
|
+
The `/plugin` command opens an interactive TUI or runs plugin operations through the injected plugin command module:
|
|
395
|
+
|
|
396
|
+
| Subcommand | Description |
|
|
397
|
+
| ---------------------------------------- | ------------------------------------- |
|
|
398
|
+
| `/plugin` or `/plugin manage` | Open the plugin manager TUI |
|
|
399
|
+
| `/plugin install <name>@<marketplace>` | Install a plugin from a marketplace |
|
|
400
|
+
| `/plugin uninstall <name>@<marketplace>` | Remove an installed plugin |
|
|
401
|
+
| `/plugin enable <name>@<marketplace>` | Enable a disabled plugin |
|
|
402
|
+
| `/plugin disable <name>@<marketplace>` | Disable a plugin without uninstalling |
|
|
403
|
+
| `/plugin marketplace add <source>` | Add a marketplace source |
|
|
404
|
+
| `/plugin marketplace remove <name>` | Remove a marketplace source |
|
|
405
|
+
| `/plugin marketplace update <name>` | Update a marketplace source |
|
|
406
|
+
| `/plugin marketplace list` | List configured marketplace sources |
|
|
182
407
|
|
|
183
408
|
## Configuration
|
|
184
409
|
|
|
185
|
-
Settings are
|
|
410
|
+
Settings are merged in this order, from lowest to highest priority:
|
|
186
411
|
|
|
187
|
-
1.
|
|
188
|
-
2.
|
|
189
|
-
3.
|
|
412
|
+
1. `~/.robota/settings.json` (user global)
|
|
413
|
+
2. `~/.claude/settings.json` (user global, Claude Code compatible)
|
|
414
|
+
3. `.robota/settings.json` (project, shared)
|
|
415
|
+
4. `.robota/settings.local.json` (local, gitignored)
|
|
416
|
+
5. `.claude/settings.json` (project, Claude Code compatible)
|
|
417
|
+
6. `.claude/settings.local.json` (local, gitignored, Claude Code compatible)
|
|
190
418
|
|
|
191
419
|
```json
|
|
192
420
|
{
|
|
193
421
|
"defaultMode": "default",
|
|
194
|
-
"
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
"
|
|
422
|
+
"language": "en",
|
|
423
|
+
"currentProvider": "qwen-plus",
|
|
424
|
+
"providers": {
|
|
425
|
+
"qwen-plus": {
|
|
426
|
+
"type": "qwen",
|
|
427
|
+
"model": "qwen-plus",
|
|
428
|
+
"apiKey": "$ENV:DASHSCOPE_API_KEY",
|
|
429
|
+
"baseURL": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
|
430
|
+
},
|
|
431
|
+
"supergemma4-26b-uncensored-v2": {
|
|
432
|
+
"type": "gemma",
|
|
433
|
+
"model": "supergemma4-26b-uncensored-v2",
|
|
434
|
+
"apiKey": "lm-studio",
|
|
435
|
+
"baseURL": "http://localhost:1234/v1"
|
|
436
|
+
},
|
|
437
|
+
"gpt-4o": {
|
|
438
|
+
"type": "openai",
|
|
439
|
+
"model": "gpt-4o",
|
|
440
|
+
"apiKey": "$ENV:OPENAI_API_KEY"
|
|
441
|
+
},
|
|
442
|
+
"claude-sonnet-4-6": {
|
|
443
|
+
"type": "anthropic",
|
|
444
|
+
"model": "claude-sonnet-4-6",
|
|
445
|
+
"apiKey": "$ENV:ANTHROPIC_API_KEY"
|
|
446
|
+
}
|
|
198
447
|
},
|
|
199
448
|
"permissions": {
|
|
200
449
|
"allow": ["Bash(pnpm *)"],
|
|
@@ -203,13 +452,27 @@ Settings are loaded from (highest priority first):
|
|
|
203
452
|
}
|
|
204
453
|
```
|
|
205
454
|
|
|
206
|
-
|
|
455
|
+
`currentProvider` selects a profile key from `providers`. The key is the stable profile identity, not
|
|
456
|
+
the provider type; multiple profile keys may use the same provider type and model when they represent
|
|
457
|
+
different credentials, endpoints, accounts, or operational defaults. Qwen Model Studio profiles use
|
|
458
|
+
`type: "qwen"` with a DashScope-compatible `baseURL`; the API key is usually stored as
|
|
459
|
+
`$ENV:DASHSCOPE_API_KEY`. DeepSeek profiles use `type: "deepseek"` with
|
|
460
|
+
`https://api.deepseek.com` and `$ENV:DEEPSEEK_API_KEY`. Gemma-family LM Studio models use
|
|
461
|
+
`type: "gemma"` so Robota can apply Gemma-specific channel-marker projection while still talking to
|
|
462
|
+
the OpenAI-compatible `/v1/chat/completions` API through `baseURL`. Generic OpenAI-compatible profiles use
|
|
463
|
+
`type: "openai"` and do not apply provider-specific projection. Use `--provider <profile>` for a
|
|
464
|
+
one-shot invocation override; add `--set-current` only when the selected profile should become the
|
|
465
|
+
persisted default. The legacy single-provider shape remains supported:
|
|
207
466
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
467
|
+
```json
|
|
468
|
+
{
|
|
469
|
+
"provider": {
|
|
470
|
+
"name": "anthropic",
|
|
471
|
+
"model": "claude-sonnet-4-6",
|
|
472
|
+
"apiKey": "$ENV:ANTHROPIC_API_KEY"
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
```
|
|
213
476
|
|
|
214
477
|
## Context Discovery
|
|
215
478
|
|
|
@@ -219,36 +482,73 @@ The CLI automatically discovers and loads:
|
|
|
219
482
|
- **CLAUDE.md** — same walk-up discovery
|
|
220
483
|
- **Project metadata** — from `package.json`, `tsconfig.json`
|
|
221
484
|
|
|
222
|
-
All context is assembled into the system prompt
|
|
485
|
+
All context is assembled into the system prompt.
|
|
486
|
+
|
|
487
|
+
Ordinary prompts may also reference workspace-local files with path-like `@file` tokens, for
|
|
488
|
+
example `@AGENTS.md` or `@docs/SPEC.md`. The CLI passes those prompts through unchanged; the SDK
|
|
489
|
+
resolves bounded file content under the active `cwd`, sends the enriched prompt to the model, and
|
|
490
|
+
records a structured file-reference event in the session history.
|
|
491
|
+
|
|
492
|
+
## Memory Management
|
|
493
|
+
|
|
494
|
+
- **Message windowing** — React state keeps the most recent 100 messages. Older messages are dropped from the render tree; full history remains in the session store.
|
|
495
|
+
- **Tool state cleanup** — Completed tool execution states are trimmed to the most recent 50 entries.
|
|
496
|
+
- **React.memo** — `MessageItem` uses `React.memo` to skip redundant re-renders.
|
|
497
|
+
|
|
498
|
+
## Session Logging
|
|
499
|
+
|
|
500
|
+
Session logs are written to `.robota/logs/{sessionId}.jsonl` in JSONL format by default, capturing structured events for diagnostics and replay. Background task lifecycle/progress events are logged there as they happen. Child-process subagents also write append-only transcripts to `.robota/logs/{sessionId}/subagents/{agentId}.jsonl`, including streaming text deltas while the local provider request is still running.
|
|
501
|
+
|
|
502
|
+
Resumable session JSON is written to `.robota/sessions/{sessionId}.json` for the current project and includes messages, UI history, the exact system prompt, registered tool schemas, and background task snapshots. High-frequency streaming chunks stay in JSONL transcript files; the session JSON stores task state and transcript paths.
|
|
223
503
|
|
|
224
504
|
## Architecture
|
|
225
505
|
|
|
506
|
+
The CLI is a pure TUI layer. All business logic lives in `@robota-sdk/agent-framework`'s `InteractiveSession`. `useInteractiveSession` is the sole React↔SDK bridge, converting SDK events to React state.
|
|
507
|
+
|
|
226
508
|
```
|
|
227
|
-
bin.ts → cli.ts (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
509
|
+
bin.ts → cli.ts (arg parsing)
|
|
510
|
+
└── ui/render.tsx → App.tsx (thin JSX shell)
|
|
511
|
+
├── useInteractiveSession (ONLY React↔SDK bridge)
|
|
512
|
+
│ ├── InteractiveSession (SDK)
|
|
513
|
+
│ ├── CommandRegistry (SDK, re-exported by CLI)
|
|
514
|
+
│ │ ├── BuiltinCommandSource (SDK, empty by default)
|
|
515
|
+
│ │ ├── agent-command-skills (/skills command + virtual skill aliases)
|
|
516
|
+
│ │ ├── PluginCommandSource (SDK, plugin skills)
|
|
517
|
+
│ │ └── ICommandModule sources (/help, /compact, ...)
|
|
518
|
+
│ └── SystemCommandExecutor (SDK)
|
|
519
|
+
├── plugin-hooks-merger.ts (merges plugin hooks into SDK config)
|
|
520
|
+
├── MessageList.tsx
|
|
521
|
+
├── InputArea.tsx (CjkTextInput, bracketed paste, slash detection)
|
|
522
|
+
├── StatusBar.tsx (activity, conditional mode, model, context %)
|
|
523
|
+
├── PermissionPrompt.tsx (arrow-key Allow/Deny)
|
|
524
|
+
├── SlashAutocomplete.tsx (command popup with scroll)
|
|
525
|
+
├── DiffBlock.tsx (Edit tool diff display)
|
|
526
|
+
├── MenuSelect.tsx (arrow-key menu, Plugin TUI)
|
|
527
|
+
├── PluginTUI.tsx (plugin management screen stack)
|
|
528
|
+
├── TextPrompt.tsx (text input for Plugin TUI)
|
|
529
|
+
└── ConfirmPrompt.tsx (reusable yes/no prompt)
|
|
240
530
|
```
|
|
241
531
|
|
|
242
|
-
|
|
532
|
+
## Dependencies
|
|
243
533
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
534
|
+
| Package | Purpose |
|
|
535
|
+
| -------------------------------------- | ------------------------------------------ |
|
|
536
|
+
| `@robota-sdk/agent-framework` | Session factory, query, config, context |
|
|
537
|
+
| `@robota-sdk/agent-core` | Types (TPermissionMode, TToolArgs) |
|
|
538
|
+
| `@robota-sdk/agent-transport-headless` | Headless runner for print mode (`-p`) |
|
|
539
|
+
| `ink` 7, `react` 19.2+ | TUI rendering |
|
|
540
|
+
| `ink-select-input` | Arrow-key selection (permission prompt) |
|
|
541
|
+
| `ink-spinner` | Loading spinner |
|
|
542
|
+
| `chalk` | Terminal colors |
|
|
543
|
+
| `ink-text-input` | Base text input (extended by CjkTextInput) |
|
|
544
|
+
| `marked`, `marked-terminal` | Markdown parsing and terminal rendering |
|
|
545
|
+
| `cli-highlight` | Syntax highlighting for code blocks |
|
|
546
|
+
| `string-width` | Unicode-aware string width (CJK support) |
|
|
547
|
+
|
|
548
|
+
## Documentation
|
|
549
|
+
|
|
550
|
+
See [docs/SPEC.md](./docs/SPEC.md) for the full specification, architecture details, and design decisions.
|
|
551
|
+
|
|
552
|
+
## License
|
|
553
|
+
|
|
554
|
+
MIT
|