@cryer/star-cli 0.3.5 → 0.3.7
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 +97 -38
- package/README.zh-CN.md +95 -39
- package/dist/chunk-4X25DNTF.js +1441 -0
- package/dist/chunk-4X25DNTF.js.map +1 -0
- package/dist/{chunk-OIDB2E5J.js → chunk-OOOW7FC4.js} +1574 -200
- package/dist/chunk-OOOW7FC4.js.map +1 -0
- package/dist/{loop-H5RYTO2O.js → loop-DVVPIOS7.js} +2 -3
- package/dist/main.js +126 -5975
- package/dist/main.js.map +1 -1
- package/dist/repl-RT6HBM5B.js +5464 -0
- package/dist/repl-RT6HBM5B.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-B6P4VUBE.js +0 -122
- package/dist/chunk-B6P4VUBE.js.map +0 -1
- package/dist/chunk-OIDB2E5J.js.map +0 -1
- package/dist/stream-H4BYBVAZ.js +0 -184
- package/dist/stream-H4BYBVAZ.js.map +0 -1
- /package/dist/{loop-H5RYTO2O.js.map → loop-DVVPIOS7.js.map} +0 -0
package/README.md
CHANGED
|
@@ -46,55 +46,84 @@ Without `npm link` you can run the bundle directly: `node dist/main.js` (re-run
|
|
|
46
46
|
|
|
47
47
|
## Configuration
|
|
48
48
|
|
|
49
|
-
Config file: `~/.star-cli/config.toml` (project-level override: `.star/config.toml` in cwd; CLI flags win over both).
|
|
49
|
+
Config file: `~/.star-cli/config.toml` (set the `STAR_HOME` environment variable to use a different home than `~/.star-cli`; project-level override: `.star/config.toml` in cwd, sandboxed to safe keys only; CLI flags win over both).
|
|
50
50
|
|
|
51
51
|
```toml
|
|
52
|
-
defaultModel = "gpt"
|
|
53
|
-
permissionMode = "ask"
|
|
54
|
-
contextMaxTokens = 100000
|
|
52
|
+
defaultModel = "gpt" # name of the [[models]] block used by default
|
|
53
|
+
permissionMode = "ask" # ask | auto | readonly | yolo | plan
|
|
54
|
+
contextMaxTokens = 100000 # context window in tokens (per-model override below)
|
|
55
|
+
# compactThresholdTokens = 80000 # optional auto-compaction trigger in tokens; defaults to the
|
|
56
|
+
# context window and is clamped to it (top-level only — there is
|
|
57
|
+
# no per-model override). /compact always compacts, regardless.
|
|
55
58
|
# Max model round-trips ("steps") per turn between progress checkpoints — one
|
|
56
59
|
# step is a reply plus the tool calls it asked for; retries and auto-continue
|
|
57
60
|
# nudges don't count. Reaching the cap while tools still execute resets it
|
|
58
61
|
# with a notice instead of stopping the turn; 0 disables the cap entirely.
|
|
59
62
|
maxSteps = 100
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
#
|
|
64
|
-
# (some relays never close the stream)
|
|
65
|
-
|
|
66
|
-
#
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
contextCompaction = "summary" # summary | truncate — how over-budget history is compacted
|
|
64
|
+
streamMaxRetries = 5 # extra attempts per model request on transient failures
|
|
65
|
+
# (network error, 429/5xx, idle cutoff, empty reply); 0 disables
|
|
66
|
+
streamIdleTimeoutSec = 20 # seconds with no stream output before a stalled response is
|
|
67
|
+
# ended gracefully (some relays never close the stream)
|
|
68
|
+
streamFirstChunkTimeoutSec = 300 # seconds to wait for the very first content part — slow
|
|
69
|
+
# thinking-model endpoints can stay silent for minutes
|
|
70
|
+
maxAutoContinues = 2 # nudges for consecutive unproductive text-only replies before
|
|
71
|
+
# the turn is handed back; tool calls reset the count; 0 disables
|
|
72
|
+
doomLoopThreshold = 3 # consecutive identical tool calls before the loop refuses the
|
|
73
|
+
# repeat and tells the model to change approach; 0 disables
|
|
74
|
+
gitSnapshots = true # track the whole working tree each turn (internal repo outside
|
|
75
|
+
# your .git) so /undo and /redo also cover bash-made changes
|
|
76
|
+
# sessionBudgetUsd = 5 # optional per-session cost cap in USD; unset = no cap
|
|
77
|
+
notifyBell = true # ring the terminal bell when a long turn finishes (REPL only)
|
|
78
|
+
notifyBellThresholdSec = 10 # turns shorter than this stay silent
|
|
69
79
|
|
|
70
80
|
[permissions]
|
|
71
|
-
# persistent allow-rules, written automatically when you pick "a" (always) on a permission prompt
|
|
72
|
-
|
|
73
|
-
#
|
|
74
|
-
# and
|
|
81
|
+
# persistent allow-rules, written automatically when you pick "a" (always) on a permission prompt.
|
|
82
|
+
# Syntax: <tool> or <tool(<pattern>)>, * is a glob wildcard. A bash rule is matched per command
|
|
83
|
+
# segment (the command line is split on shell separators): an allow rule must match EVERY segment,
|
|
84
|
+
# and any command substitution or file redirection disables auto-allow entirely.
|
|
85
|
+
allow = ["bash(npm test)", "read_file"]
|
|
86
|
+
# persistent deny-rules — checked after the hard safety rules; a deny matching ANY segment beats
|
|
87
|
+
# auto mode and allow-rules (yolo still bypasses everything)
|
|
75
88
|
deny = ["bash(rm -rf *)"]
|
|
76
89
|
|
|
77
90
|
[[providers]]
|
|
78
91
|
name = "openai"
|
|
79
|
-
protocol = "openai-compatible"
|
|
92
|
+
protocol = "openai-compatible" # openai-compatible | anthropic | openai-responses
|
|
80
93
|
baseURL = "https://api.openai.com/v1"
|
|
81
|
-
apiKeyEnv = "OPENAI_API_KEY"
|
|
82
|
-
#
|
|
94
|
+
apiKeyEnv = "OPENAI_API_KEY" # recommended: name of the env var holding the key — keys live in
|
|
95
|
+
# ~/.star-cli/.env (written by /connect), never in this file
|
|
96
|
+
# apiKey = "sk-..." # inline key instead of apiKeyEnv (not recommended)
|
|
97
|
+
# headers = { "X-Title" = "star-cli" } # extra HTTP headers sent with every request
|
|
98
|
+
# protocol = "openai-responses" # for relays exposing only /v1/responses
|
|
83
99
|
|
|
84
100
|
[[models]]
|
|
85
|
-
name = "gpt"
|
|
86
|
-
provider = "openai"
|
|
87
|
-
model = "gpt-4o"
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
# contextMaxTokens
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
101
|
+
name = "gpt" # referenced by defaultModel and -m
|
|
102
|
+
provider = "openai" # name of a [[providers]] block
|
|
103
|
+
model = "gpt-4o" # model id sent to the API
|
|
104
|
+
# maxTokens = 8192 # cap on generated tokens per reply
|
|
105
|
+
# contextMaxTokens = 272000 # per-model context window — overrides the top-level
|
|
106
|
+
# contextMaxTokens for compaction and the ctx % in the status bar
|
|
107
|
+
# temperature = 1 # sampling temperature forwarded on every request. Unset = the AI
|
|
108
|
+
# SDK default applies (ai@4 sends 0 — it does NOT omit the field),
|
|
109
|
+
# so endpoints that mandate one explicit value (kimi-for-coding/k3
|
|
110
|
+
# accept only 1) MUST set it here.
|
|
111
|
+
# reasoningEffort = "high" # reasoning intensity for thinking models, forwarded verbatim as
|
|
112
|
+
# reasoning_effort on every request. Level naming varies by
|
|
113
|
+
# provider (low/medium/high are common; some add minimal/max...).
|
|
114
|
+
# Unset = server default. Ignored for anthropic. The /model
|
|
115
|
+
# picker also offers these levels after a model pick.
|
|
116
|
+
# streamIdleTimeoutSec = 60 # per-model overrides of the global stream watchdog timeouts
|
|
117
|
+
# streamFirstChunkTimeoutSec = 600
|
|
118
|
+
# optional per-model pricing in USD per 1M tokens — enables the $ estimate in /cost and /usage.
|
|
119
|
+
# promptPrice prices input tokens (system prompt, history, @file contents, tool results — resent
|
|
120
|
+
# every turn, so the bulk of usage); completionPrice prices output tokens (the model's replies and
|
|
121
|
+
# tool calls — less volume, usually the pricier rate). BOTH fields are required together.
|
|
96
122
|
promptPrice = 2.5
|
|
97
123
|
completionPrice = 10
|
|
124
|
+
# cacheReadPrice = 0.25 # optional price for cache-read prompt tokens; unset = OpenAI-style
|
|
125
|
+
# cached tokens bill at promptPrice and Anthropic-style cache
|
|
126
|
+
# reads are not billed
|
|
98
127
|
|
|
99
128
|
[[providers]]
|
|
100
129
|
name = "claude"
|
|
@@ -110,13 +139,45 @@ model = "claude-sonnet-4-20250514"
|
|
|
110
139
|
[[hooks]]
|
|
111
140
|
event = "PostToolUse" # PreToolUse | PostToolUse | Stop
|
|
112
141
|
matcher = "edit_file|write_file" # optional regex on the tool name; matches all tools when omitted
|
|
113
|
-
command = "biome check --write ."
|
|
114
|
-
#
|
|
142
|
+
command = "biome check --write ." # PreToolUse exiting with code 2 blocks the tool (stderr
|
|
143
|
+
# becomes its result); Stop fires on every turn end
|
|
144
|
+
# timeoutSec = 30 # optional per-hook timeout (default 30; on timeout the hook
|
|
145
|
+
# is allowed through with a warning)
|
|
115
146
|
```
|
|
116
147
|
|
|
117
148
|
API keys resolve from the environment variable first (`apiKeyEnv`), then the `apiKey` field in the config file. On startup Star CLI also loads `~/.star-cli/.env` (dotenv-style `KEY=VALUE` lines) into the environment without overwriting variables that are already set — this is where `/connect` stores the keys it collects, so `config.toml` only ever references the variable name, never the key itself.
|
|
118
149
|
|
|
119
|
-
The fastest way to set up a provider is the `/connect` wizard inside the REPL: pick a preset (OpenAI, Anthropic, Kimi/Moonshot, DeepSeek) or a custom endpoint, paste the API key (masked while typing), name a model, and it appends the `[[providers]]`/`[[models]]` blocks to `config.toml` (existing content and comments preserved), writes the key to `~/.star-cli/.env` (as `STAR_API_KEY_<NAME>`, file mode 600 where the platform honors it), and optionally makes the new model the default — all without restarting.
|
|
150
|
+
The fastest way to set up a provider is the `/connect` wizard inside the REPL: pick a preset (OpenAI, Anthropic, Kimi/Moonshot, DeepSeek) or a custom endpoint, paste the API key (masked while typing), name a model, and it appends the `[[providers]]`/`[[models]]` blocks to `config.toml` (existing content and comments preserved), writes the key to `~/.star-cli/.env` (as `STAR_API_KEY_<NAME>`, file mode 600 where the platform honors it), and optionally makes the new model the default — all without restarting. The written `[[models]]` block comes with `contextMaxTokens = 128000` and `temperature = 1` (a safe default — coding models like kimi-for-coding/k3 reject any other value; lower it only for models that allow it) plus zero placeholder prices — edit all three to the real limits and rates as needed.
|
|
151
|
+
|
|
152
|
+
### Using a relay (中转站)
|
|
153
|
+
|
|
154
|
+
Third-party relays usually front one of the standard wire formats: set `protocol` to `openai-responses` when the relay exposes the Responses API (`/responses`), otherwise `openai-compatible` (`/chat/completions`).
|
|
155
|
+
|
|
156
|
+
Many relays buffer a whole generation before flushing — tens of seconds to minutes can pass without a single SSE chunk, which looks like a dead stream. Star CLI timestamps the raw response bytes of every request: as long as bytes keep flowing (including SSE heartbeat comments the SDK itself swallows) the stream watchdog is extended instead of cutting the relay off mid-generation, bounded by a 10-minute cap on total part silence so a heartbeat-only zombie can't hang a turn. If a relay still triggers frequent idle timeouts, raise the model's own watchdogs:
|
|
157
|
+
|
|
158
|
+
```toml
|
|
159
|
+
[[providers]]
|
|
160
|
+
name = "kimi"
|
|
161
|
+
protocol = "openai-responses"
|
|
162
|
+
baseURL = "https://api.kimi.com/coding/v1" # official Kimi coding endpoint
|
|
163
|
+
apiKeyEnv = "STAR_API_KEY_KIMI"
|
|
164
|
+
|
|
165
|
+
[[models]]
|
|
166
|
+
name = "kimi"
|
|
167
|
+
provider = "kimi"
|
|
168
|
+
model = "kimi-for-coding"
|
|
169
|
+
temperature = 1 # mandatory here — the endpoint rejects any other value
|
|
170
|
+
contextMaxTokens = 128000
|
|
171
|
+
# raise these when the relay buffers long generations:
|
|
172
|
+
# streamIdleTimeoutSec = 60 # default 20
|
|
173
|
+
# streamFirstChunkTimeoutSec = 600 # default 300
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Environment variables
|
|
177
|
+
|
|
178
|
+
- `STAR_HOME` — overrides `~/.star-cli` as the data home (config, sessions, `.env`, memory, debug log).
|
|
179
|
+
- `STAR_DEBUG` — any non-empty value enables stream diagnostics appended to `~/.star-cli/debug.log`, one JSON object per line.
|
|
180
|
+
- `STAR_NO_NOTIFY=1` — disables the terminal bell without touching the config.
|
|
120
181
|
|
|
121
182
|
|
|
122
183
|
## CLI flags
|
|
@@ -171,9 +232,7 @@ star --clear-sessions all delete every stored session
|
|
|
171
232
|
|
|
172
233
|
Keys: `ESC` / `Ctrl+C` interrupts the current stream — the partial reply generated so far stays on screen (and in the session history) with a dim `[interrupted]` marker; on a permission prompt: `y` allow, `n` deny, `a` always allow — the generated allow-rule (e.g. `bash(npm test)`) is saved to `permissions.allow` in the config file and survives restarts. Write/edit prompts include a colored diff preview of the pending change. `Shift+Tab` cycles the permission mode for the session (`ask` → `auto` → `readonly` → `plan`; not saved to config). Input editing: arrow keys move the cursor, `Ctrl+A`/`Ctrl+E` jump to start/end, `Ctrl+U`/`Ctrl+K` delete before/after the cursor, `Ctrl+W` deletes the previous word, up/down recall history (persisted to `~/.star-cli/history` across sessions, capped at 50 entries, consecutive duplicates collapsed, slash commands and key-repeat garbage never recorded); while a recalled entry is unmodified up/down keep switching entries, but once you edit the text — or are typing your own multi-line input — up/down move the cursor between lines instead. `Ctrl+R` starts a reverse history search: type to filter (case-insensitive, newest match first), `Ctrl+R`/`↑` for older matches, `↓` for newer, `Enter` to accept the match into the input, `ESC`/`Ctrl+C`/`Ctrl+G` to cancel and restore what you had. Multi-line input: use `Ctrl+J` (or `Alt+Enter`), or end the line with `\` and press `Enter` — pasted multi-line text is kept intact. Pasting a large block (10+ lines or 500+ characters in one go) collapses it into a dim `[pasted #N: L lines]` placeholder so the input box stays compact; the full text is restored into what gets submitted, and `Backspace` removes the placeholder as a unit. A huge paste that the terminal delivers in several chunks is reassembled (via bracketed paste where the terminal supports it) and still collapses into a single placeholder. Typing `/` shows slash-command suggestions with their usage — prefix matches first, then fuzzy subsequence matches; `↑`/`↓` to highlight, `Tab` (or `→` at end of input) to complete, `ESC` to dismiss, and an unknown command name gets a `Did you mean: …` hint. Typing `@` completes file paths relative to the working directory with the same keys; directories end in `/` so `Tab` descends, and `node_modules`, `.git`, `dist` and `.starignore` entries are skipped. `Alt+V` pastes an image from the clipboard as an attachment (each one shows as `[image attached: clipboard.png]` above the input; uses PowerShell on Windows, pngpaste/osascript on macOS, xclip on Linux). Images larger than 2000px on the longest side are automatically downsampled to fit (keeping the aspect ratio, via platform-native tools — no extra installs on Windows/macOS; ImageMagick or ffmpeg on Linux); when resizing isn't possible the original is kept and a warning is shown. `Ctrl+V` also works where the terminal passes it through — Windows Terminal binds Ctrl+V to its own paste, so use `Alt+V` there. While a turn is streaming you can keep typing: submitted prompts (and `!` bangs) queue up as dimmed entries and auto-send in order once the turn finishes; `ESC` during a turn aborts it and clears the queue (the partial reply is kept, marked `[interrupted]`). Pressing `ESC` twice within half a second while idle retracts your last prompt and restores its text into the input for editing.
|
|
173
234
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
The status bar shows the working directory (full path on wide terminals), the git branch, the model, the permission mode, context usage as a percentage of the model's context window (its own `contextMaxTokens` when set, else the top-level one), the session prompt-cache hit rate when the provider reports cache usage (`cache: 42%`, or `cache: Not provided` when it never does), the session cost when the model has pricing configured, and total tokens.
|
|
235
|
+
The status bar shows the working directory (full path on wide terminals), the git branch, the model, the permission mode, context usage as a percentage of the model's context window (its own `contextMaxTokens` when set, else the top-level one), the session prompt-cache hit rate when the provider reports cache usage (`cache: 42%`, or `cache: Not provided` when it never does), the session cost when the model has pricing configured, and total tokens. Model replies render as markdown (headings, emphasis, code blocks, tables) directly in the terminal. Decorative icons use emoji on terminals known to render them double-width (Windows Terminal, VS Code, Kitty, …) and fall back to plain symbols elsewhere so the display never desyncs; force a style with `STAR_ICONS=emoji|plain`.
|
|
177
236
|
|
|
178
237
|
## !shell passthrough
|
|
179
238
|
|
|
@@ -289,7 +348,7 @@ A `.starignore` file in the working directory hides paths from the agent: the `g
|
|
|
289
348
|
|
|
290
349
|
## Built-in tools
|
|
291
350
|
|
|
292
|
-
`read_file`, `write_file`, `edit_file`, `glob`, `grep`, `bash`, `web_fetch`, `web_search` (DuckDuckGo, no API key needed), `todo_read`, `todo_write`, `task_list`, `task_output`, `task_kill`, `subagent`, `skill`, `remember` — each declares a permission level (`read` / `write` / `exec`) enforced by the permission gate. Hard safety rules (dangerous shell commands, paths outside the working directory, secret files like `.env` / private keys) are denied in `ask` / `auto` / `readonly` and cannot be overridden by allow-rules.
|
|
351
|
+
`read_file`, `read_image` (attach an image file to the conversation mid-session — screenshots, mockups; png/jpg/gif/webp, auto-downsampled past 2000px), `write_file`, `edit_file`, `glob`, `grep`, `bash`, `web_fetch`, `web_search` (DuckDuckGo, no API key needed), `todo_read`, `todo_write`, `task_list`, `task_output`, `task_kill`, `subagent`, `skill`, `remember` — each declares a permission level (`read` / `write` / `exec`) enforced by the permission gate. Hard safety rules (dangerous shell commands, paths outside the working directory, secret files like `.env` / private keys) are denied in `ask` / `auto` / `readonly` and cannot be overridden by allow-rules.
|
|
293
352
|
|
|
294
353
|
The `subagent` tool (`exec` level, so it is hidden in plan mode and denied in readonly) spawns a child agent loop with the same built-in tools to handle a focused, self-contained subtask — research, exploration, or an isolated change — and returns the child's final report as the tool result. Subagents run one level deep (a subagent cannot spawn further subagents), share the parent's permission mode and confirmation prompt, and their conversation is not persisted to the session.
|
|
295
354
|
|
package/README.zh-CN.md
CHANGED
|
@@ -46,54 +46,81 @@ star -p "hi" # non-interactive print mode
|
|
|
46
46
|
|
|
47
47
|
## 配置
|
|
48
48
|
|
|
49
|
-
配置文件:`~/.star-cli/config.toml
|
|
49
|
+
配置文件:`~/.star-cli/config.toml`(可用环境变量 `STAR_HOME` 把数据目录改为 `~/.star-cli` 以外的位置;项目级覆盖:当前目录下的 `.star/config.toml`,经过沙箱过滤只保留安全键;CLI 参数优先于两者)。
|
|
50
50
|
|
|
51
51
|
```toml
|
|
52
|
-
defaultModel = "gpt"
|
|
53
|
-
permissionMode = "ask"
|
|
54
|
-
contextMaxTokens = 100000
|
|
52
|
+
defaultModel = "gpt" # 默认使用的 [[models]] 块名称
|
|
53
|
+
permissionMode = "ask" # ask | auto | readonly | yolo | plan
|
|
54
|
+
contextMaxTokens = 100000 # 上下文窗口(token 数,下方可按模型覆盖)
|
|
55
|
+
# compactThresholdTokens = 80000 # 可选的自动压缩触发阈值(token 数);默认为上下文窗口本身,
|
|
56
|
+
# 且会被钳制到窗口以内(仅顶层键——没有按模型覆盖)。
|
|
57
|
+
# /compact 无视此阈值,总是执行压缩。
|
|
55
58
|
# 每回合在进度检查点之间允许的最大模型往返("step")数——一个 step 是
|
|
56
59
|
# 一次回复加上它请求的所有工具调用;重试和 auto-continue nudge 不占 step。
|
|
57
60
|
# 到达上限时若工具仍在执行,会发提示并重置额度而不是终止回合;0 表示完全不限。
|
|
58
61
|
maxSteps = 100
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
#
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
contextCompaction = "summary" # summary | truncate —— 历史超出预算时的压缩方式
|
|
63
|
+
streamMaxRetries = 5 # 单次模型请求在瞬时失败(网络错误、429/5xx、idle 截断、
|
|
64
|
+
# 空回复)时的额外重试次数;0 表示禁用
|
|
65
|
+
streamIdleTimeoutSec = 20 # 流没有任何输出的秒数,超过后将停滞的响应优雅结束
|
|
66
|
+
#(有些中转站从不关闭流)
|
|
67
|
+
streamFirstChunkTimeoutSec = 300 # 等待第一个内容分片的秒数——慢速思考模型端点在接受请求后
|
|
68
|
+
# 可能静默数分钟
|
|
69
|
+
maxAutoContinues = 2 # 连续无产出的纯文本回复在被 nudge 多少次后交还回合;
|
|
70
|
+
# 工具调用会重置计数;0 表示禁用
|
|
71
|
+
doomLoopThreshold = 3 # 连续相同工具调用达到此次数后,循环拒绝执行该重复调用
|
|
72
|
+
# 并要求模型换思路;0 表示禁用
|
|
73
|
+
gitSnapshots = true # 每回合用内部 git 仓库(位于你的 .git 之外)跟踪整个工作树,
|
|
74
|
+
# 使 /undo 和 /redo 也能覆盖 bash 造成的改动
|
|
75
|
+
# sessionBudgetUsd = 5 # 可选的每会话成本上限(美元);不设置 = 无上限
|
|
76
|
+
notifyBell = true # 长回合结束时响终端铃(仅 REPL)
|
|
77
|
+
notifyBellThresholdSec = 10 # 短于此耗时的回合不响铃
|
|
68
78
|
|
|
69
79
|
[permissions]
|
|
70
|
-
#
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
#
|
|
80
|
+
# 持久 allow 规则——在权限提示上选择 "a"(始终允许)时自动写入。
|
|
81
|
+
# 语法:<tool> 或 <tool(<pattern>)>,* 是 glob 通配符。bash 规则按命令分段匹配
|
|
82
|
+
#(命令行先按 shell 分隔符切分):allow 规则必须匹配每一段,且命令中含有命令替换
|
|
83
|
+
# 或文件重定向时完全不会自动放行。
|
|
84
|
+
allow = ["bash(npm test)", "read_file"]
|
|
85
|
+
# 持久 deny 规则——在硬性安全规则之后检查;deny 命中任意一段即优先于 auto 模式和
|
|
86
|
+
# allow 规则(yolo 仍然绕过一切)
|
|
74
87
|
deny = ["bash(rm -rf *)"]
|
|
75
88
|
|
|
76
89
|
[[providers]]
|
|
77
90
|
name = "openai"
|
|
78
|
-
protocol = "openai-compatible"
|
|
91
|
+
protocol = "openai-compatible" # openai-compatible | anthropic | openai-responses
|
|
79
92
|
baseURL = "https://api.openai.com/v1"
|
|
80
|
-
apiKeyEnv = "OPENAI_API_KEY"
|
|
81
|
-
#
|
|
93
|
+
apiKeyEnv = "OPENAI_API_KEY" # 推荐:存放密钥的环境变量名——密钥本体放在
|
|
94
|
+
# ~/.star-cli/.env(由 /connect 写入),绝不出现在本文件
|
|
95
|
+
# apiKey = "sk-..." # 不用 apiKeyEnv 而直接内联密钥(不推荐)
|
|
96
|
+
# headers = { "X-Title" = "star-cli" } # 随每次请求发送的额外 HTTP 头
|
|
97
|
+
# protocol = "openai-responses" # 适用于只暴露 /v1/responses 的中转站
|
|
82
98
|
|
|
83
99
|
[[models]]
|
|
84
|
-
name = "gpt"
|
|
85
|
-
provider = "openai"
|
|
86
|
-
model = "gpt-4o"
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
100
|
+
name = "gpt" # 被 defaultModel 和 -m 引用
|
|
101
|
+
provider = "openai" # 某个 [[providers]] 块的 name
|
|
102
|
+
model = "gpt-4o" # 发送给 API 的模型 id
|
|
103
|
+
# maxTokens = 8192 # 单次回复的生成 token 上限
|
|
104
|
+
# contextMaxTokens = 272000 # 按模型的上下文窗口——覆盖顶层 contextMaxTokens,
|
|
105
|
+
# 用于压缩和状态栏的 ctx 百分比
|
|
106
|
+
# temperature = 1 # 采样温度,随每次请求发送。不设置 = 应用 AI SDK 默认值
|
|
107
|
+
#(ai@4 会发送 0——它不会省略该字段),所以只接受某个固定值的
|
|
108
|
+
# 端点(kimi-for-coding/k3 只接受 1)必须在此显式设置。
|
|
109
|
+
# reasoningEffort = "high" # 思考模型的推理强度,每次请求原样以 reasoning_effort 发送。
|
|
110
|
+
# 档位命名因服务商/模型而异(常见 low/medium/high,部分还有
|
|
111
|
+
# minimal/max 等),因此接受任意字符串,由服务端校验。
|
|
112
|
+
# 不设置 = 服务端默认。anthropic 协议下忽略。
|
|
113
|
+
# /model 选完模型后也会接着让你选择推理强度。
|
|
114
|
+
# streamIdleTimeoutSec = 60 # 按模型覆盖全局的流看门狗超时
|
|
115
|
+
# streamFirstChunkTimeoutSec = 600
|
|
116
|
+
# 可选的按模型定价(美元/1M token)——启用 /cost 和 /usage 中的美元估算。
|
|
117
|
+
# promptPrice 为输入 token 定价(系统提示词、历史、@file 内容、工具结果——每回合重发,
|
|
118
|
+
# 是用量的大头);completionPrice 为输出 token 定价(模型的回复和工具调用——量较少,
|
|
119
|
+
# 通常单价更贵)。两个字段必须同时设置。
|
|
95
120
|
promptPrice = 2.5
|
|
96
121
|
completionPrice = 10
|
|
122
|
+
# cacheReadPrice = 0.25 # 可选的缓存读取输入 token 价格;不设置 = OpenAI 风格的缓存
|
|
123
|
+
# token 按 promptPrice 计费,Anthropic 风格的缓存读取不计费
|
|
97
124
|
|
|
98
125
|
[[providers]]
|
|
99
126
|
name = "claude"
|
|
@@ -108,14 +135,45 @@ model = "claude-sonnet-4-20250514"
|
|
|
108
135
|
|
|
109
136
|
[[hooks]]
|
|
110
137
|
event = "PostToolUse" # PreToolUse | PostToolUse | Stop
|
|
111
|
-
matcher = "edit_file|write_file" #
|
|
112
|
-
command = "biome check --write ."
|
|
113
|
-
|
|
138
|
+
matcher = "edit_file|write_file" # 可选的工具名正则;省略时匹配所有工具
|
|
139
|
+
command = "biome check --write ." # PreToolUse 以退出码 2 退出会阻止该工具
|
|
140
|
+
#(stderr 成为工具结果);Stop 在每回合结束时触发
|
|
141
|
+
# timeoutSec = 30 # 可选的单钩子超时(默认 30;超时 = 放行并警告)
|
|
114
142
|
```
|
|
115
143
|
|
|
116
144
|
API 密钥优先从环境变量解析(`apiKeyEnv`),其次是配置文件中的 `apiKey` 字段。启动时 Star CLI 还会把 `~/.star-cli/.env`(dotenv 风格的 `KEY=VALUE` 行)加载进环境变量,且不会覆盖已存在的变量——`/connect` 收集的密钥就存放在这里,因此 `config.toml` 只引用变量名,永远不会包含密钥本身。
|
|
117
145
|
|
|
118
|
-
配置服务商最快的方式是 REPL 内的 `/connect` 向导:选择预设(OpenAI、Anthropic、Kimi/Moonshot、DeepSeek)或自定义端点,粘贴 API 密钥(输入时掩码显示),命名一个模型,它会把 `[[providers]]`/`[[models]]` 块追加到 `config.toml`(保留已有内容与注释),把密钥写入 `~/.star-cli/.env`(以 `STAR_API_KEY_<NAME>` 为名,在支持的平台上文件权限为 600
|
|
146
|
+
配置服务商最快的方式是 REPL 内的 `/connect` 向导:选择预设(OpenAI、Anthropic、Kimi/Moonshot、DeepSeek)或自定义端点,粘贴 API 密钥(输入时掩码显示),命名一个模型,它会把 `[[providers]]`/`[[models]]` 块追加到 `config.toml`(保留已有内容与注释),把密钥写入 `~/.star-cli/.env`(以 `STAR_API_KEY_<NAME>` 为名,在支持的平台上文件权限为 600),并可选择将新模型设为默认——全程无需重启。写入的 `[[models]]` 块默认带 `contextMaxTokens = 128000` 和 `temperature = 1`(稳妥的默认值——kimi-for-coding/k3 这类 coding 模型拒绝任何其他取值;仅在模型允许时才调低它),另有占位的零价格——可按需改成真实的限额与费率。
|
|
147
|
+
|
|
148
|
+
### 使用中转站(relay)
|
|
149
|
+
|
|
150
|
+
第三方中转站通常前置某种标准线路格式:中转支持 Responses API(`/responses`)时把 `protocol` 设为 `openai-responses`,否则用 `openai-compatible`(`/chat/completions`)。
|
|
151
|
+
|
|
152
|
+
很多中转站会把整段生成缓冲起来再一次性下发——几十秒到几分钟可能没有任何 SSE 分片,看起来像流已死亡。Star CLI 会对每次请求的原始响应字节做时间戳检测:只要还有字节在流动(包括 SDK 自己会吞掉的 SSE 心跳注释),流看门狗就会延长等待而不是中途掐断正在缓冲生成的中转站,并以 10 分钟的总分片静默上限兜底,避免只剩心跳的僵尸连接挂住整个回合。如果某个中转站仍频繁触发 idle 超时,可以调大该模型自己的看门狗:
|
|
153
|
+
|
|
154
|
+
```toml
|
|
155
|
+
[[providers]]
|
|
156
|
+
name = "kimi"
|
|
157
|
+
protocol = "openai-responses"
|
|
158
|
+
baseURL = "https://api.kimi.com/coding/v1" # Kimi 官方 coding 端点
|
|
159
|
+
apiKeyEnv = "STAR_API_KEY_KIMI"
|
|
160
|
+
|
|
161
|
+
[[models]]
|
|
162
|
+
name = "kimi"
|
|
163
|
+
provider = "kimi"
|
|
164
|
+
model = "kimi-for-coding"
|
|
165
|
+
temperature = 1 # 此处必须设置——该端点拒绝任何其他取值
|
|
166
|
+
contextMaxTokens = 128000
|
|
167
|
+
# 中转站长时间缓冲整段生成时可调大:
|
|
168
|
+
# streamIdleTimeoutSec = 60 # 默认 20
|
|
169
|
+
# streamFirstChunkTimeoutSec = 600 # 默认 300
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 环境变量
|
|
173
|
+
|
|
174
|
+
- `STAR_HOME` —— 把数据目录从 `~/.star-cli` 改为其他位置(配置、会话、`.env`、记忆、调试日志)。
|
|
175
|
+
- `STAR_DEBUG` —— 任意非空值即启用流诊断日志,追加写入 `~/.star-cli/debug.log`,每行一个 JSON 对象。
|
|
176
|
+
- `STAR_NO_NOTIFY=1` —— 不改配置即可禁用终端响铃。
|
|
119
177
|
|
|
120
178
|
|
|
121
179
|
## CLI 参数
|
|
@@ -170,9 +228,7 @@ star --clear-sessions all delete every stored session
|
|
|
170
228
|
|
|
171
229
|
按键:`ESC` / `Ctrl+C` 中断当前流——已生成的部分回复保留在屏幕上(以及会话历史中),并带暗色 `[interrupted]` 标记;在权限提示上:`y` 允许,`n` 拒绝,`a` 始终允许——生成的 allow 规则(如 `bash(npm test)`)会保存到配置文件的 `permissions.allow` 中,重启后依然有效。写入/编辑提示包含待变更内容的彩色 diff 预览。`Shift+Tab` 在会话内循环切换权限模式(`ask` → `auto` → `readonly` → `plan`;不保存到配置)。输入编辑:方向键移动光标,`Ctrl+A`/`Ctrl+E` 跳到行首/行尾,`Ctrl+U`/`Ctrl+K` 删除光标前/后的内容,`Ctrl+W` 删除前一个单词,上/下键回忆历史(跨会话持久化到 `~/.star-cli/history`,上限 50 条,连续重复自动折叠,斜杠命令与按键重复的垃圾输入从不记录);当回忆出的条目未被修改时,上/下键继续在条目间切换,而一旦你编辑了文本——或正在输入自己的多行内容——上/下键改为在行之间移动光标。`Ctrl+R` 启动反向历史搜索:输入以过滤(不区分大小写,最新匹配优先),`Ctrl+R`/`↑` 找更早的匹配,`↓` 找更新的,`Enter` 将匹配接进输入框,`ESC`/`Ctrl+C`/`Ctrl+G` 取消并恢复你原有的内容。多行输入:使用 `Ctrl+J`(或 `Alt+Enter`),或以 `\` 结尾再按 `Enter`——粘贴的多行文本会原样保留。一次性粘贴大块内容(10+ 行或 500+ 字符)会折叠成暗色占位符 `[pasted #N: L lines]`,让输入框保持紧凑;完整文本会在提交时还原,`Backspace` 可将占位符整体删除。终端分多个块送达的超长粘贴会被重新组装(在支持的终端上通过 bracketed paste),并仍然折叠为单个占位符。输入 `/` 会显示斜杠命令建议及其用法——前缀匹配优先,然后是模糊子序列匹配;`↑`/`↓` 高亮,`Tab`(或在输入末尾按 `→`)补全,`ESC` 关闭,未知命令名会给出 `Did you mean: …` 提示。输入 `@` 会以同样的按键补全相对工作目录的文件路径;目录以 `/` 结尾以便用 `Tab` 下钻,`node_modules`、`.git`、`dist` 和 `.starignore` 条目会被跳过。`Alt+V` 把剪贴板中的图片作为附件粘贴(每张图片在输入框上方显示为 `[image attached: clipboard.png]`;Windows 上使用 PowerShell,macOS 上使用 pngpaste/osascript,Linux 上使用 xclip)。最长边超过 2000px 的图片会自动缩放以符合限制(保持宽高比,使用平台原生工具——Windows/macOS 无需额外安装;Linux 上使用 ImageMagick 或 ffmpeg);无法缩放时保留原图并显示警告。在终端透传的地方 `Ctrl+V` 也可用——Windows Terminal 把 Ctrl+V 绑定为自己的粘贴,请在那里使用 `Alt+V`。回合流式输出期间你可以继续输入:提交的提示(和 `!` bang)会以暗色条目排队,回合结束后按序自动发送;回合中按 `ESC` 会中止该回合并清空队列(部分回复保留,标记为 `[interrupted]`)。空闲时半秒内连按两次 `ESC` 会撤回你上一条提示,并把原文恢复进输入框供编辑。
|
|
172
230
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
状态栏显示工作目录(宽终端上显示完整路径)、git 分支、模型、权限模式、上下文用量占模型上下文窗口的百分比(模型自身设置了 `contextMaxTokens` 时用它,否则用顶层值)、服务商上报缓存用量时的会话提示词缓存命中率(`cache: 42%`,从不上报时显示 `cache: Not provided`)、模型配置了定价时的会话成本,以及 token 总数。
|
|
231
|
+
状态栏显示工作目录(宽终端上显示完整路径)、git 分支、模型、权限模式、上下文用量占模型上下文窗口的百分比(模型自身设置了 `contextMaxTokens` 时用它,否则用顶层值)、服务商上报缓存用量时的会话提示词缓存命中率(`cache: 42%`,从不上报时显示 `cache: Not provided`)、模型配置了定价时的会话成本,以及 token 总数。模型回复会以 Markdown 形式直接在终端渲染(标题、强调、代码块、表格等)。装饰图标在已知能正确双宽渲染 emoji 的终端(Windows Terminal、VS Code、Kitty 等)上使用 emoji,其他终端回退为纯符号以避免显示错位;也可用 `STAR_ICONS=emoji|plain` 强制指定。
|
|
176
232
|
|
|
177
233
|
## !shell 直通
|
|
178
234
|
|
|
@@ -288,7 +344,7 @@ star -p "what's wrong in this UI?" --image screenshot.png --image mockup.jpg
|
|
|
288
344
|
|
|
289
345
|
## 内置工具
|
|
290
346
|
|
|
291
|
-
`read_file`、`write_file`、`edit_file`、`glob`、`grep`、`bash`、`web_fetch`、`web_search`(DuckDuckGo,无需 API 密钥)、`todo_read`、`todo_write`、`task_list`、`task_output`、`task_kill`、`subagent`、`skill`、`remember`——每个都声明一个权限级别(`read` / `write` / `exec`),由权限门禁强制执行。硬性安全规则(危险 shell 命令、工作目录之外的路径、`.env` / 私钥等机密文件)在 `ask` / `auto` / `readonly` 下被拒绝,且无法被 allow 规则覆盖。
|
|
347
|
+
`read_file`、`read_image`(会话中把图片文件带给模型——截图、设计稿等;支持 png/jpg/gif/webp,超过 2000px 自动降采样)、`write_file`、`edit_file`、`glob`、`grep`、`bash`、`web_fetch`、`web_search`(DuckDuckGo,无需 API 密钥)、`todo_read`、`todo_write`、`task_list`、`task_output`、`task_kill`、`subagent`、`skill`、`remember`——每个都声明一个权限级别(`read` / `write` / `exec`),由权限门禁强制执行。硬性安全规则(危险 shell 命令、工作目录之外的路径、`.env` / 私钥等机密文件)在 `ask` / `auto` / `readonly` 下被拒绝,且无法被 allow 规则覆盖。
|
|
292
348
|
|
|
293
349
|
`subagent` 工具(`exec` 级别,因此在计划模式下隐藏,在 readonly 下被拒绝)派生一个带相同内置工具的子代理循环,处理专注、自包含的子任务——调研、探索或一处孤立的改动——并把子代理的最终报告作为工具结果返回。子代理只运行一层(子代理不能再派生子代理),共享父代理的权限模式与确认提示,其对话不持久化到会话。
|
|
294
350
|
|