@robota-sdk/agent-cli 3.0.0-beta.40 → 3.0.0-beta.42
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 +133 -112
- package/dist/node/bin.js +1 -1
- package/dist/node/{chunk-CRPNSO52.js → chunk-SYGOHAAL.js} +489 -1298
- package/dist/node/index.cjs +516 -1323
- package/dist/node/index.js +1 -1
- package/package.json +4 -4
- package/dist/node/bin.cjs +0 -3180
- package/dist/node/bin.d.cts +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @robota-sdk/agent-cli
|
|
2
2
|
|
|
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.
|
|
3
|
+
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
|
+
|
|
5
|
+
**Version**: 3.0.0-beta.40
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -73,6 +75,7 @@ robota -p "prompt" # Print mode (one-shot, exit after response)
|
|
|
73
75
|
robota -c # Continue last session
|
|
74
76
|
robota -r <session-id> # Resume session by ID
|
|
75
77
|
robota --model <model> # Model override (e.g., claude-sonnet-4-6)
|
|
78
|
+
robota --language <lang> # Response language (ko, en, ja, zh)
|
|
76
79
|
robota --permission-mode <mode> # plan | default | acceptEdits | bypassPermissions
|
|
77
80
|
robota --max-turns <n> # Limit agentic turns per interaction
|
|
78
81
|
robota --reset # Delete user settings and exit
|
|
@@ -81,11 +84,16 @@ robota --version # Show version
|
|
|
81
84
|
|
|
82
85
|
## First-Run Setup
|
|
83
86
|
|
|
84
|
-
When no settings file exists, the CLI prompts for
|
|
87
|
+
When no settings file exists, the CLI prompts for:
|
|
88
|
+
|
|
89
|
+
1. **Anthropic API key** (input masked with asterisks)
|
|
90
|
+
2. **Response language** (ko/en/ja/zh, default: en)
|
|
91
|
+
|
|
92
|
+
Creates `~/.robota/settings.json`. Use `robota --reset` to return to first-run state.
|
|
85
93
|
|
|
86
94
|
## Built-in Tools
|
|
87
95
|
|
|
88
|
-
The
|
|
96
|
+
The AI agent can invoke 6 tools:
|
|
89
97
|
|
|
90
98
|
| Tool | Description | Primary Argument |
|
|
91
99
|
| ------- | ------------------------------------ | ---------------- |
|
|
@@ -98,53 +106,29 @@ The CLI provides 6 tools that the AI agent can invoke:
|
|
|
98
106
|
|
|
99
107
|
## Permission System
|
|
100
108
|
|
|
101
|
-
Every tool call passes through a three-step permission gate
|
|
109
|
+
Every tool call passes through a three-step permission gate:
|
|
102
110
|
|
|
103
|
-
1. **Deny list** — if any deny pattern matches, the action is blocked
|
|
111
|
+
1. **Deny list** — if any deny pattern matches, the action is blocked
|
|
104
112
|
2. **Allow list** — if any allow pattern matches, the action is auto-approved
|
|
105
113
|
3. **Mode policy** — the active permission mode determines the decision
|
|
106
114
|
|
|
107
|
-
When a tool requires approval, the user sees an interactive prompt:
|
|
108
|
-
|
|
109
|
-
```
|
|
110
|
-
[Permission Required] Tool: Bash
|
|
111
|
-
Arguments: command: rm -rf dist
|
|
112
|
-
Allow? [y/N]
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
- Type `y` or `yes` to approve
|
|
116
|
-
- Press Enter or type anything else to deny
|
|
117
|
-
|
|
118
|
-
If denied, the AI agent receives a "Permission denied" error and can adjust its approach.
|
|
119
|
-
|
|
120
115
|
### Permission Modes
|
|
121
116
|
|
|
122
|
-
| Mode |
|
|
123
|
-
| ------------------- |
|
|
124
|
-
| `plan` |
|
|
125
|
-
| `default` |
|
|
126
|
-
| `acceptEdits` |
|
|
127
|
-
| `bypassPermissions` |
|
|
128
|
-
|
|
129
|
-
- **auto** — tool executes without prompting
|
|
130
|
-
- **approve** — user is prompted to allow or deny
|
|
131
|
-
- **deny** — tool is blocked silently (no prompt shown)
|
|
132
|
-
|
|
133
|
-
Unknown tools default to `approve` in most modes, `deny` in `plan` mode.
|
|
117
|
+
| Mode | Read/Glob/Grep | Write/Edit | Bash |
|
|
118
|
+
| ------------------- | :------------: | :--------: | :-----: |
|
|
119
|
+
| `plan` | auto | deny | deny |
|
|
120
|
+
| `default` | auto | approve | approve |
|
|
121
|
+
| `acceptEdits` | auto | auto | approve |
|
|
122
|
+
| `bypassPermissions` | auto | auto | auto |
|
|
134
123
|
|
|
135
124
|
### Changing Mode at Runtime
|
|
136
125
|
|
|
137
|
-
Use the `/mode` slash command
|
|
126
|
+
Use the `/mode` slash command:
|
|
138
127
|
|
|
139
128
|
```
|
|
140
129
|
> /mode # Show current mode
|
|
141
|
-
Current permission mode: default
|
|
142
|
-
|
|
143
130
|
> /mode plan # Switch to plan (read-only)
|
|
144
|
-
Permission mode set to: plan
|
|
145
|
-
|
|
146
131
|
> /mode bypassPermissions # Skip all prompts
|
|
147
|
-
Permission mode set to: bypassPermissions
|
|
148
132
|
```
|
|
149
133
|
|
|
150
134
|
Or set it at startup:
|
|
@@ -153,7 +137,7 @@ Or set it at startup:
|
|
|
153
137
|
robota --permission-mode plan
|
|
154
138
|
```
|
|
155
139
|
|
|
156
|
-
### Permission Patterns
|
|
140
|
+
### Permission Patterns
|
|
157
141
|
|
|
158
142
|
Configure in `.robota/settings.json` or `.robota/settings.local.json`:
|
|
159
143
|
|
|
@@ -166,28 +150,67 @@ Configure in `.robota/settings.json` or `.robota/settings.local.json`:
|
|
|
166
150
|
}
|
|
167
151
|
```
|
|
168
152
|
|
|
169
|
-
|
|
153
|
+
Pattern syntax: `ToolName` matches any invocation; `ToolName(pattern)` matches on the primary argument with shell-style globs (`*`, `**`).
|
|
170
154
|
|
|
171
|
-
|
|
172
|
-
- `ToolName(pattern)` — match when the primary argument matches the glob (e.g., `Bash(pnpm *)`)
|
|
173
|
-
- `*` — zero or more characters (shell-style)
|
|
174
|
-
- `**` — one or more characters (recursive path matching)
|
|
155
|
+
## Keyboard Controls
|
|
175
156
|
|
|
176
|
-
|
|
157
|
+
| Key | Action |
|
|
158
|
+
| ---------- | ----------------------------------------------------------- |
|
|
159
|
+
| Enter | Submit input |
|
|
160
|
+
| ESC | Abort current execution (graceful — saves partial response) |
|
|
161
|
+
| Ctrl+C | Exit process immediately |
|
|
162
|
+
| Up/Down | Navigate visual lines in wrapped multi-line input |
|
|
163
|
+
| Arrow keys | Navigate slash command autocomplete, permission prompt |
|
|
164
|
+
|
|
165
|
+
## Paste Handling
|
|
166
|
+
|
|
167
|
+
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
|
+
|
|
169
|
+
Single-line paste is inserted directly as typed text. Terminals without bracketed paste fall back to heuristic detection.
|
|
170
|
+
|
|
171
|
+
## Edit Diff Display
|
|
172
|
+
|
|
173
|
+
After the Edit tool runs, a `DiffBlock` component renders the change inline:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
✓ Edit(src/provider.ts)
|
|
177
|
+
│ src/provider.ts
|
|
178
|
+
│ - const DEFAULT_MAX_TOKENS = 4096;
|
|
179
|
+
│ + const maxTokens = getModelMaxOutput(modelId);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
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.
|
|
177
183
|
|
|
178
184
|
## Slash Commands
|
|
179
185
|
|
|
180
|
-
| Command | Description
|
|
181
|
-
| ------------------------- |
|
|
182
|
-
| `/help` | Show
|
|
183
|
-
| `/clear` | Clear conversation history
|
|
184
|
-
| `/mode [mode]` | Show or change permission mode
|
|
185
|
-
| `/model [model]` | Select AI model (confirmation
|
|
186
|
-
| `/
|
|
187
|
-
| `/
|
|
188
|
-
| `/
|
|
189
|
-
| `/
|
|
190
|
-
| `/
|
|
186
|
+
| Command | Description |
|
|
187
|
+
| ------------------------- | ---------------------------------------------------------- |
|
|
188
|
+
| `/help` | Show available commands |
|
|
189
|
+
| `/clear` | Clear conversation history |
|
|
190
|
+
| `/mode [mode]` | Show or change permission mode |
|
|
191
|
+
| `/model [model]` | Select AI model (confirmation prompt, CLI restarts) |
|
|
192
|
+
| `/language [lang]` | Set response language (ko, en, ja, zh), saves and restarts |
|
|
193
|
+
| `/compact [instructions]` | Compress context window |
|
|
194
|
+
| `/cost` | Show session info |
|
|
195
|
+
| `/context` | Context window details |
|
|
196
|
+
| `/permissions` | Show permission rules |
|
|
197
|
+
| `/plugin [subcommand]` | Plugin management TUI |
|
|
198
|
+
| `/exit` | Exit CLI |
|
|
199
|
+
|
|
200
|
+
Typing `/` triggers an autocomplete popup with arrow-key navigation, Tab completion, and Esc to dismiss. 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.
|
|
201
|
+
|
|
202
|
+
## Plugin Management
|
|
203
|
+
|
|
204
|
+
The `/plugin` command opens an interactive TUI for managing bundle plugins:
|
|
205
|
+
|
|
206
|
+
| Subcommand | Description |
|
|
207
|
+
| -------------------------- | ------------------------------------------------ |
|
|
208
|
+
| `/plugin install <name>` | Install a plugin from marketplace or local path |
|
|
209
|
+
| `/plugin uninstall <name>` | Remove an installed plugin |
|
|
210
|
+
| `/plugin enable <name>` | Enable a disabled plugin |
|
|
211
|
+
| `/plugin disable <name>` | Disable a plugin without uninstalling |
|
|
212
|
+
| `/plugin list` | List installed plugins with status |
|
|
213
|
+
| `/plugin marketplace` | Browse available plugins from configured sources |
|
|
191
214
|
|
|
192
215
|
## Configuration
|
|
193
216
|
|
|
@@ -195,11 +218,14 @@ Settings are loaded from (highest priority first):
|
|
|
195
218
|
|
|
196
219
|
1. `.robota/settings.local.json` (local, gitignored)
|
|
197
220
|
2. `.robota/settings.json` (project, shared)
|
|
198
|
-
3.
|
|
221
|
+
3. `.claude/settings.json` (project, Claude Code compatible)
|
|
222
|
+
4. `~/.robota/settings.json` (user global)
|
|
223
|
+
5. `~/.claude/settings.json` (user global, Claude Code compatible)
|
|
199
224
|
|
|
200
225
|
```json
|
|
201
226
|
{
|
|
202
227
|
"defaultMode": "default",
|
|
228
|
+
"language": "en",
|
|
203
229
|
"provider": {
|
|
204
230
|
"name": "anthropic",
|
|
205
231
|
"model": "claude-sonnet-4-6",
|
|
@@ -212,77 +238,72 @@ Settings are loaded from (highest priority first):
|
|
|
212
238
|
}
|
|
213
239
|
```
|
|
214
240
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
| Variable | Description | Required |
|
|
218
|
-
| ------------------- | ----------------- | -------- |
|
|
219
|
-
| `ANTHROPIC_API_KEY` | Anthropic API key | Yes |
|
|
220
|
-
|
|
221
|
-
Copy `.env.example` to `.env` and set your key. The CLI reads `.env` automatically in dev mode.
|
|
222
|
-
|
|
223
|
-
## Paste Template
|
|
224
|
-
|
|
225
|
-
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, keeping the input area compact while preserving the complete text for the AI.
|
|
226
|
-
|
|
227
|
-
## Edit Diff Display
|
|
241
|
+
## Context Discovery
|
|
228
242
|
|
|
229
|
-
|
|
243
|
+
The CLI automatically discovers and loads:
|
|
230
244
|
|
|
231
|
-
|
|
245
|
+
- **AGENTS.md** — walking up from cwd to filesystem root
|
|
246
|
+
- **CLAUDE.md** — same walk-up discovery
|
|
247
|
+
- **Project metadata** — from `package.json`, `tsconfig.json`
|
|
232
248
|
|
|
233
|
-
|
|
249
|
+
All context is assembled into the system prompt.
|
|
234
250
|
|
|
235
251
|
## Memory Management
|
|
236
252
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
- **
|
|
240
|
-
- **Tool state cleanup** — Completed tool results older than 50 entries are cleaned up to reduce retained state.
|
|
253
|
+
- **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.
|
|
254
|
+
- **Tool state cleanup** — Completed tool execution states are trimmed to the most recent 50 entries.
|
|
255
|
+
- **React.memo** — `MessageItem` uses `React.memo` to skip redundant re-renders.
|
|
241
256
|
|
|
242
|
-
|
|
257
|
+
## Session Logging
|
|
243
258
|
|
|
244
|
-
|
|
259
|
+
Session logs are written to `.robota/logs/{sessionId}.jsonl` in JSONL format by default, capturing structured events for diagnostics and replay.
|
|
245
260
|
|
|
246
|
-
|
|
261
|
+
## Architecture
|
|
247
262
|
|
|
248
|
-
|
|
263
|
+
The CLI is a pure TUI layer. All business logic lives in `@robota-sdk/agent-sdk`'s `InteractiveSession`. `useInteractiveSession` is the sole React↔SDK bridge, converting SDK events to React state.
|
|
249
264
|
|
|
250
|
-
|
|
265
|
+
```
|
|
266
|
+
bin.ts → cli.ts (arg parsing)
|
|
267
|
+
└── ui/render.tsx → App.tsx (thin JSX shell)
|
|
268
|
+
├── useInteractiveSession (ONLY React↔SDK bridge)
|
|
269
|
+
│ ├── InteractiveSession (SDK)
|
|
270
|
+
│ ├── CommandRegistry (SDK, re-exported by CLI)
|
|
271
|
+
│ │ ├── BuiltinCommandSource (SDK)
|
|
272
|
+
│ │ ├── SkillCommandSource (SDK, discovers from 4 paths)
|
|
273
|
+
│ │ └── PluginCommandSource (CLI-local)
|
|
274
|
+
│ └── SystemCommandExecutor (SDK)
|
|
275
|
+
├── plugin-hooks-merger.ts (merges plugin hooks into SDK config)
|
|
276
|
+
├── MessageList.tsx
|
|
277
|
+
├── InputArea.tsx (CjkTextInput, bracketed paste, slash detection)
|
|
278
|
+
├── StatusBar.tsx (mode, model, context %, message count)
|
|
279
|
+
├── PermissionPrompt.tsx (arrow-key Allow/Deny)
|
|
280
|
+
├── SlashAutocomplete.tsx (command popup with scroll)
|
|
281
|
+
├── DiffBlock.tsx (Edit tool diff display)
|
|
282
|
+
├── MenuSelect.tsx (arrow-key menu, Plugin TUI)
|
|
283
|
+
├── PluginTUI.tsx (plugin management screen stack)
|
|
284
|
+
├── TextPrompt.tsx (text input for Plugin TUI)
|
|
285
|
+
└── ConfirmPrompt.tsx (reusable yes/no prompt)
|
|
286
|
+
```
|
|
251
287
|
|
|
252
|
-
|
|
253
|
-
- **CLAUDE.md** — same walk-up discovery
|
|
254
|
-
- **Project metadata** — from `package.json`, `tsconfig.json`
|
|
288
|
+
## Dependencies
|
|
255
289
|
|
|
256
|
-
|
|
290
|
+
| Package | Purpose |
|
|
291
|
+
| --------------------------- | ------------------------------------------ |
|
|
292
|
+
| `@robota-sdk/agent-sdk` | Session factory, query, config, context |
|
|
293
|
+
| `@robota-sdk/agent-core` | Types (TPermissionMode, TToolArgs) |
|
|
294
|
+
| `ink`, `react` | TUI rendering |
|
|
295
|
+
| `ink-select-input` | Arrow-key selection (permission prompt) |
|
|
296
|
+
| `ink-spinner` | Loading spinner |
|
|
297
|
+
| `chalk` | Terminal colors |
|
|
298
|
+
| `ink-text-input` | Base text input (extended by CjkTextInput) |
|
|
299
|
+
| `marked`, `marked-terminal` | Markdown parsing and terminal rendering |
|
|
300
|
+
| `cli-highlight` | Syntax highlighting for code blocks |
|
|
301
|
+
| `string-width` | Unicode-aware string width (CJK support) |
|
|
257
302
|
|
|
258
|
-
##
|
|
303
|
+
## Documentation
|
|
259
304
|
|
|
260
|
-
|
|
261
|
-
bin.ts → cli.ts (parseArgs, load config/context, create Session)
|
|
262
|
-
├── config/config-loader.ts — settings file discovery + Zod validation
|
|
263
|
-
├── context/context-loader.ts — AGENTS.md/CLAUDE.md walk-up discovery
|
|
264
|
-
├── context/project-detector.ts — package.json/tsconfig detection
|
|
265
|
-
├── context/system-prompt-builder.ts — system message assembly
|
|
266
|
-
├── session.ts — Robota agent wrapper + permission enforcement
|
|
267
|
-
│ └── permissions/
|
|
268
|
-
│ ├── permission-gate.ts — 3-step evaluation (deny → allow → mode)
|
|
269
|
-
│ ├── permission-mode.ts — mode × tool policy matrix
|
|
270
|
-
│ └── permission-prompt.ts — interactive [y/N] prompt
|
|
271
|
-
├── tools/ — 6 built-in tools (Bash, Read, Write, Edit, Glob, Grep)
|
|
272
|
-
├── session-store.ts — JSON file-based session persistence
|
|
273
|
-
└── ui/ — Ink TUI components (App, MessageList, InputArea, etc.)
|
|
274
|
-
```
|
|
305
|
+
See [docs/SPEC.md](./docs/SPEC.md) for the full specification, architecture details, and design decisions.
|
|
275
306
|
|
|
276
|
-
|
|
307
|
+
## License
|
|
277
308
|
|
|
278
|
-
|
|
279
|
-
AI agent requests tool call
|
|
280
|
-
→ Session.wrapToolWithPermission() intercepts execute()
|
|
281
|
-
→ evaluatePermission(toolName, args, mode, allow/deny lists)
|
|
282
|
-
→ deny list match? → blocked
|
|
283
|
-
→ allow list match? → auto-approved
|
|
284
|
-
→ mode policy lookup → auto | approve | deny
|
|
285
|
-
→ if 'approve': promptForApproval() → user types y/N
|
|
286
|
-
→ if allowed: original tool.execute() runs
|
|
287
|
-
→ if denied: returns error result to AI agent
|
|
288
|
-
```
|
|
309
|
+
MIT
|