@robota-sdk/agent-cli 3.0.0-beta.56 → 3.0.0-beta.58
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 +46 -13
- package/dist/node/bin.js +2 -2
- package/dist/node/{chunk-2JAZDNYT.js → chunk-4ZX5RLIX.js} +45 -15
- package/dist/node/{chunk-H3NRW5FW.js → chunk-B522YHTK.js} +1839 -526
- package/dist/node/index.cjs +1922 -585
- package/dist/node/index.js +2 -2
- package/dist/node/subagents/child-process-subagent-worker.js +1 -1
- package/package.json +14 -11
package/README.md
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
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
4
|
|
|
5
|
-
**Version**: 3.0.0-beta.40
|
|
6
|
-
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
7
|
Requires Node.js 22+.
|
|
@@ -31,6 +29,7 @@ robota -p "List all files" # Print mode (one-shot, exit after response)
|
|
|
31
29
|
| Variable | Description | Required |
|
|
32
30
|
| ------------------- | ---------------------------------------------- | -------------- |
|
|
33
31
|
| `ANTHROPIC_API_KEY` | Anthropic API key for the `anthropic` provider | Anthropic only |
|
|
32
|
+
| `DASHSCOPE_API_KEY` | Alibaba Cloud Model Studio key for `qwen` | Qwen only |
|
|
34
33
|
|
|
35
34
|
Set your key before running:
|
|
36
35
|
|
|
@@ -41,11 +40,7 @@ export ANTHROPIC_API_KEY=sk-ant-...
|
|
|
41
40
|
## Development Setup (Monorepo)
|
|
42
41
|
|
|
43
42
|
```bash
|
|
44
|
-
#
|
|
45
|
-
cp packages/agent-cli/.env.example packages/agent-cli/.env
|
|
46
|
-
# Edit .env and set ANTHROPIC_API_KEY=sk-ant-...
|
|
47
|
-
|
|
48
|
-
# 2. Build dependencies and CLI
|
|
43
|
+
# Build dependencies and CLI
|
|
49
44
|
pnpm build:deps
|
|
50
45
|
pnpm --filter @robota-sdk/agent-cli build
|
|
51
46
|
```
|
|
@@ -56,7 +51,7 @@ pnpm --filter @robota-sdk/agent-cli build
|
|
|
56
51
|
# From monorepo root
|
|
57
52
|
cd packages/agent-cli
|
|
58
53
|
|
|
59
|
-
# Development mode (no build needed
|
|
54
|
+
# Development mode (no build needed)
|
|
60
55
|
pnpm dev
|
|
61
56
|
|
|
62
57
|
# Production mode (requires build)
|
|
@@ -84,9 +79,27 @@ robota --output-format <fmt> # text | json | stream-json (print mode)
|
|
|
84
79
|
robota --system-prompt <text> # Replace system prompt (print mode)
|
|
85
80
|
robota --append-system-prompt <text> # Append to system prompt (print mode)
|
|
86
81
|
robota --reset # Delete user settings and exit
|
|
82
|
+
robota --check-update # Check npm for a newer CLI version and exit
|
|
83
|
+
robota --disable-update-check # Skip interactive startup update check for this run
|
|
87
84
|
robota --version # Show version
|
|
88
85
|
```
|
|
89
86
|
|
|
87
|
+
### CLI Updates
|
|
88
|
+
|
|
89
|
+
Robota can check npm for a newer `@robota-sdk/agent-cli` version:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
robota --check-update
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
When an update is available, Robota prints the npm global install command:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npm install -g '@robota-sdk/agent-cli@latest'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
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.
|
|
102
|
+
|
|
90
103
|
### Print Mode Output Formats
|
|
91
104
|
|
|
92
105
|
Print mode (`-p`) supports three output formats via `--output-format`:
|
|
@@ -111,10 +124,15 @@ git diff | robota -p "Summarize changes" --output-format stream-json
|
|
|
111
124
|
|
|
112
125
|
When no usable settings file exists, the CLI prompts for:
|
|
113
126
|
|
|
114
|
-
1. **
|
|
115
|
-
2. **
|
|
127
|
+
1. **Provider selection** from the providers assembled into the CLI binary
|
|
128
|
+
2. **Provider-specific setup fields** such as model, base URL, and masked API key
|
|
129
|
+
3. **Response language** (ko/en/ja/zh, default: en)
|
|
130
|
+
|
|
131
|
+
Creates `~/.robota/settings.json`. Use `robota --reset` to return to first-run state.
|
|
116
132
|
|
|
117
|
-
|
|
133
|
+
Provider setup is generated from provider definitions. The default CLI build includes Anthropic, OpenAI-compatible, Gemma, and Qwen providers; other embeddings can inject their own provider definitions.
|
|
134
|
+
|
|
135
|
+
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`.
|
|
118
136
|
|
|
119
137
|
## Built-in Tools
|
|
120
138
|
|
|
@@ -129,6 +147,15 @@ The AI agent can invoke 6 tools:
|
|
|
129
147
|
| `Glob` | Find files matching a pattern | `pattern` |
|
|
130
148
|
| `Grep` | Search file contents with regex | `pattern` |
|
|
131
149
|
|
|
150
|
+
## Recent TUI Capabilities
|
|
151
|
+
|
|
152
|
+
- Provider setup is generated from provider definitions, so the default CLI build can configure Anthropic, OpenAI-compatible, Gemma, and Qwen profiles without provider-specific UI branches.
|
|
153
|
+
- Interactive startup can check npm for newer CLI versions; print/headless mode skips startup update checks to keep scripted output deterministic.
|
|
154
|
+
- Long-running sessions show provider usage summaries, status activity, background job tree rows, and collapsed command-output transcripts.
|
|
155
|
+
- Edit results render as context hunks with markdown-friendly diff blocks.
|
|
156
|
+
- Background subagents are real runtime jobs with transcripts and resumable task snapshots.
|
|
157
|
+
- Explicit multi-agent requests can use the Agent tool `jobs` batch path through the SDK runtime.
|
|
158
|
+
|
|
132
159
|
## Permission System
|
|
133
160
|
|
|
134
161
|
Every tool call passes through a three-step permission gate:
|
|
@@ -282,8 +309,14 @@ Settings are merged in this order, from lowest to highest priority:
|
|
|
282
309
|
{
|
|
283
310
|
"defaultMode": "default",
|
|
284
311
|
"language": "en",
|
|
285
|
-
"currentProvider": "
|
|
312
|
+
"currentProvider": "qwen",
|
|
286
313
|
"providers": {
|
|
314
|
+
"qwen": {
|
|
315
|
+
"type": "qwen",
|
|
316
|
+
"model": "qwen-plus",
|
|
317
|
+
"apiKey": "$ENV:DASHSCOPE_API_KEY",
|
|
318
|
+
"baseURL": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
|
319
|
+
},
|
|
287
320
|
"gemma": {
|
|
288
321
|
"type": "gemma",
|
|
289
322
|
"model": "supergemma4-26b-uncensored-v2",
|
|
@@ -308,7 +341,7 @@ Settings are merged in this order, from lowest to highest priority:
|
|
|
308
341
|
}
|
|
309
342
|
```
|
|
310
343
|
|
|
311
|
-
`currentProvider` selects a profile from `providers`. Gemma-family LM Studio models use `type: "gemma"` so Robota can apply Gemma-specific channel-marker projection while still talking to the OpenAI-compatible `/v1/chat/completions` API through `baseURL`. Generic OpenAI-compatible profiles use `type: "openai"` and do not apply
|
|
344
|
+
`currentProvider` selects a profile from `providers`. Qwen Model Studio profiles use `type: "qwen"` with a DashScope-compatible `baseURL`; the API key is usually stored as `$ENV:DASHSCOPE_API_KEY`. Gemma-family LM Studio models use `type: "gemma"` so Robota can apply Gemma-specific channel-marker projection while still talking to the OpenAI-compatible `/v1/chat/completions` API through `baseURL`. Generic OpenAI-compatible profiles use `type: "openai"` and do not apply provider-specific projection. The legacy single-provider shape remains supported:
|
|
312
345
|
|
|
313
346
|
```json
|
|
314
347
|
{
|
package/dist/node/bin.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
startCli
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-B522YHTK.js";
|
|
5
|
+
import "./chunk-4ZX5RLIX.js";
|
|
6
6
|
|
|
7
7
|
// src/bin.ts
|
|
8
8
|
import { createAgentCommandModule } from "@robota-sdk/agent-command-agent";
|
|
@@ -6,16 +6,47 @@ import { homedir } from "os";
|
|
|
6
6
|
// src/utils/provider-default-definitions.ts
|
|
7
7
|
import { createAnthropicProviderDefinition } from "@robota-sdk/agent-provider-anthropic";
|
|
8
8
|
import { createGemmaProviderDefinition } from "@robota-sdk/agent-provider-gemma";
|
|
9
|
+
import { createGeminiProviderDefinition } from "@robota-sdk/agent-provider-gemini";
|
|
9
10
|
import { createOpenAIProviderDefinition } from "@robota-sdk/agent-provider-openai";
|
|
11
|
+
import { createQwenProviderDefinition } from "@robota-sdk/agent-provider-qwen";
|
|
10
12
|
var DEFAULT_PROVIDER_DEFINITIONS = [
|
|
11
13
|
createAnthropicProviderDefinition(),
|
|
12
14
|
createOpenAIProviderDefinition(),
|
|
13
|
-
|
|
15
|
+
createGeminiProviderDefinition(),
|
|
16
|
+
createGemmaProviderDefinition(),
|
|
17
|
+
createQwenProviderDefinition()
|
|
14
18
|
];
|
|
15
19
|
|
|
16
20
|
// src/utils/provider-definition.ts
|
|
17
21
|
import { findProviderDefinition, formatSupportedProviderTypes } from "@robota-sdk/agent-core";
|
|
18
22
|
|
|
23
|
+
// src/utils/env-ref.ts
|
|
24
|
+
var ENV_REFERENCE_PREFIX = "$ENV:";
|
|
25
|
+
function isEnvReference(value) {
|
|
26
|
+
return value.startsWith(ENV_REFERENCE_PREFIX);
|
|
27
|
+
}
|
|
28
|
+
function getEnvReferenceName(value) {
|
|
29
|
+
if (!isEnvReference(value)) {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
const envName = value.slice(ENV_REFERENCE_PREFIX.length).trim();
|
|
33
|
+
return envName.length > 0 ? envName : void 0;
|
|
34
|
+
}
|
|
35
|
+
function resolveEnvReference(value) {
|
|
36
|
+
const envName = getEnvReferenceName(value);
|
|
37
|
+
if (envName === void 0) {
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
const resolved = process.env[envName];
|
|
41
|
+
return resolved !== void 0 && resolved.length > 0 ? resolved : void 0;
|
|
42
|
+
}
|
|
43
|
+
function hasUsableSecretReference(value) {
|
|
44
|
+
if (value === void 0 || value.length === 0) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return resolveEnvReference(value) !== void 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
19
50
|
// src/utils/provider-factory.ts
|
|
20
51
|
function readProviderSettings(cwd, options = {}) {
|
|
21
52
|
const merged = readMergedProviderSettings(cwd);
|
|
@@ -88,7 +119,8 @@ function resolveActiveProvider(settings, providerOverride, providerDefinitions =
|
|
|
88
119
|
model: profile.model,
|
|
89
120
|
apiKey: profile.apiKey,
|
|
90
121
|
baseURL: profile.baseURL,
|
|
91
|
-
timeout: profile.timeout
|
|
122
|
+
timeout: profile.timeout,
|
|
123
|
+
options: profile.options
|
|
92
124
|
},
|
|
93
125
|
providerDefinitions
|
|
94
126
|
);
|
|
@@ -101,7 +133,8 @@ function resolveActiveProvider(settings, providerOverride, providerDefinitions =
|
|
|
101
133
|
model: provider.model,
|
|
102
134
|
apiKey: provider.apiKey,
|
|
103
135
|
baseURL: provider.baseURL,
|
|
104
|
-
timeout: provider.timeout
|
|
136
|
+
timeout: provider.timeout,
|
|
137
|
+
options: provider.options
|
|
105
138
|
},
|
|
106
139
|
providerDefinitions
|
|
107
140
|
);
|
|
@@ -114,25 +147,20 @@ function normalizeProviderConfig(settings, providerDefinitions) {
|
|
|
114
147
|
if (!model) {
|
|
115
148
|
throw new Error(`Provider ${settings.name} requires model`);
|
|
116
149
|
}
|
|
150
|
+
const apiKeyReference = settings.apiKey ?? defaults.apiKey;
|
|
151
|
+
const options = settings.options ?? defaults.options;
|
|
117
152
|
return {
|
|
118
153
|
name: settings.name,
|
|
119
154
|
model,
|
|
120
|
-
apiKey:
|
|
155
|
+
apiKey: apiKeyReference !== void 0 ? resolveEnvReference(apiKeyReference) : void 0,
|
|
121
156
|
baseURL: settings.baseURL ?? defaults.baseURL,
|
|
122
|
-
timeout: settings.timeout
|
|
157
|
+
timeout: settings.timeout,
|
|
158
|
+
...options !== void 0 && { options }
|
|
123
159
|
};
|
|
124
160
|
}
|
|
125
|
-
function resolveEnvRef(value) {
|
|
126
|
-
const envPrefix = "$ENV:";
|
|
127
|
-
if (!value.startsWith(envPrefix)) {
|
|
128
|
-
return value;
|
|
129
|
-
}
|
|
130
|
-
const envName = value.slice(envPrefix.length);
|
|
131
|
-
return process.env[envName] ?? value;
|
|
132
|
-
}
|
|
133
161
|
function resolveProfileApiKey(profile) {
|
|
134
162
|
if (profile.apiKey !== void 0) {
|
|
135
|
-
return profile.apiKey;
|
|
163
|
+
return resolveEnvReference(profile.apiKey);
|
|
136
164
|
}
|
|
137
165
|
if (profile.apiKeyEnv !== void 0) {
|
|
138
166
|
return process.env[profile.apiKeyEnv];
|
|
@@ -165,7 +193,8 @@ function createProviderFromProfile(profile, modelOverride, providerDefinitions =
|
|
|
165
193
|
model: modelOverride ?? profile.model,
|
|
166
194
|
apiKey: resolveProfileApiKey(profile),
|
|
167
195
|
baseURL: profile.baseURL,
|
|
168
|
-
timeout: profile.timeout
|
|
196
|
+
timeout: profile.timeout,
|
|
197
|
+
options: profile.options
|
|
169
198
|
},
|
|
170
199
|
providerDefinitions
|
|
171
200
|
),
|
|
@@ -237,6 +266,7 @@ export {
|
|
|
237
266
|
DEFAULT_PROVIDER_DEFINITIONS,
|
|
238
267
|
findProviderDefinition,
|
|
239
268
|
formatSupportedProviderTypes,
|
|
269
|
+
hasUsableSecretReference,
|
|
240
270
|
readProviderSettings,
|
|
241
271
|
readMergedProviderSettings,
|
|
242
272
|
createProviderFromSettings,
|