@robota-sdk/agent-cli 3.0.0-beta.40 → 3.0.0-beta.41

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 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 an Anthropic API key (input masked with asterisks) and creates `~/.robota/settings.json`. Use `robota --reset` to return to first-run state.
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 CLI provides 6 tools that the AI agent can invoke:
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 before execution:
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 immediately
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 | Alias | Read/Glob/Grep | Write/Edit | Bash |
123
- | ------------------- | -------- | :------------: | :--------: | :-----: |
124
- | `plan` | safe | auto | deny | deny |
125
- | `default` | moderate | auto | approve | approve |
126
- | `acceptEdits` | full | auto | auto | approve |
127
- | `bypassPermissions` | — | auto | auto | auto |
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 in the REPL:
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 (allow/deny lists)
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
- **Pattern syntax:**
153
+ Pattern syntax: `ToolName` matches any invocation; `ToolName(pattern)` matches on the primary argument with shell-style globs (`*`, `**`).
154
+
155
+ ## Keyboard Controls
170
156
 
171
- - `ToolName` — match any invocation of that tool (e.g., `Bash`)
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)
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 |
175
164
 
176
- **Evaluation order:** deny patterns are checked first, then allow patterns, then the mode policy. Deny always wins.
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 help |
183
- | `/clear` | Clear conversation history |
184
- | `/mode [mode]` | Show or change permission mode |
185
- | `/model [model]` | Select AI model (confirmation + restart) |
186
- | `/compact [instructions]` | Compress context window |
187
- | `/cost` | Show session info |
188
- | `/context` | Context window details |
189
- | `/permissions` | Show permission rules |
190
- | `/exit` | Exit CLI |
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. `~/.robota/settings.json` (user global)
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,67 @@ Settings are loaded from (highest priority first):
212
238
  }
213
239
  ```
214
240
 
215
- ### Environment Variables
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
- After the Edit tool runs, a `DiffBlock` component renders the change with colored `+`/`-` line markers (green = added, red = removed), giving immediate visual feedback on file modifications.
243
+ The CLI automatically discovers and loads:
230
244
 
231
- ## Plugin Commands Display
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
- Plugin-provided commands appear in the slash command autocomplete with their source plugin name as a hint. Commands are also accessible via colon format: `/plugin-name:command`.
249
+ All context is assembled into the system prompt.
234
250
 
235
251
  ## Memory Management
236
252
 
237
- The CLI applies two strategies to keep memory usage bounded during long sessions:
238
-
239
- - **Message windowing** — Conversation history is capped at 100 messages. Older messages are pruned from the window.
240
- - **Tool state cleanup** — Completed tool results older than 50 entries are cleaned up to reduce retained state.
241
-
242
- React components use `React.memo` to avoid unnecessary re-renders.
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.
243
256
 
244
- ### Forced Summary on maxRounds
257
+ ## Session Logging
245
258
 
246
- When the tool execution loop exhausts its maximum rounds, the CLI injects a synthetic user message requesting a summary. This ensures the user always receives a meaningful response even if the agent could not complete all planned tool calls.
259
+ Session logs are written to `.robota/logs/{sessionId}.jsonl` in JSONL format by default, capturing structured events for diagnostics and replay.
247
260
 
248
- ## Context Discovery
261
+ ## Architecture
249
262
 
250
- The CLI automatically discovers and loads:
263
+ ```
264
+ bin.ts → cli.ts (arg parsing)
265
+ └── ui/render.tsx → App.tsx (Ink TUI)
266
+ ├── MessageList.tsx
267
+ ├── InputArea.tsx (CjkTextInput, bracketed paste, slash detection)
268
+ ├── StatusBar.tsx (mode, model, context %, message count)
269
+ ├── PermissionPrompt.tsx (arrow-key Allow/Deny)
270
+ ├── SlashAutocomplete.tsx (command popup with scroll)
271
+ ├── DiffBlock.tsx (Edit tool diff display)
272
+ ├── MenuSelect.tsx (arrow-key menu, Plugin TUI)
273
+ ├── PluginTUI.tsx (plugin management screen stack)
274
+ ├── TextPrompt.tsx (text input for Plugin TUI)
275
+ ├── ConfirmPrompt.tsx (reusable yes/no prompt)
276
+ ├── CommandRegistry
277
+ │ ├── BuiltinCommandSource
278
+ │ ├── SkillCommandSource (discovers from 4 paths)
279
+ │ └── PluginCommandSource (from installed plugins)
280
+ └── Session (from @robota-sdk/agent-sessions)
281
+ ```
251
282
 
252
- - **AGENTS.md** — walking up from cwd to filesystem root
253
- - **CLAUDE.md** — same walk-up discovery
254
- - **Project metadata** — from `package.json`, `tsconfig.json`
283
+ ## Dependencies
255
284
 
256
- All context is assembled into the system prompt for the AI assistant.
285
+ | Package | Purpose |
286
+ | --------------------------- | ------------------------------------------ |
287
+ | `@robota-sdk/agent-sdk` | Session factory, query, config, context |
288
+ | `@robota-sdk/agent-core` | Types (TPermissionMode, TToolArgs) |
289
+ | `ink`, `react` | TUI rendering |
290
+ | `ink-select-input` | Arrow-key selection (permission prompt) |
291
+ | `ink-spinner` | Loading spinner |
292
+ | `chalk` | Terminal colors |
293
+ | `ink-text-input` | Base text input (extended by CjkTextInput) |
294
+ | `marked`, `marked-terminal` | Markdown parsing and terminal rendering |
295
+ | `cli-highlight` | Syntax highlighting for code blocks |
296
+ | `string-width` | Unicode-aware string width (CJK support) |
257
297
 
258
- ## Architecture
298
+ ## Documentation
259
299
 
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
- ```
300
+ See [docs/SPEC.md](./docs/SPEC.md) for the full specification, architecture details, and design decisions.
275
301
 
276
- Tool calls flow through the permission system:
302
+ ## License
277
303
 
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
- ```
304
+ MIT
package/dist/node/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startCli
4
- } from "./chunk-CRPNSO52.js";
4
+ } from "./chunk-KX3JUGSB.js";
5
5
 
6
6
  // src/bin.ts
7
7
  process.on("uncaughtException", (err) => {