@cryer/star-cli 0.3.6 → 0.3.8

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
@@ -17,7 +17,7 @@ Multi-model LLM access · streaming terminal UI · tool calling · permission co
17
17
 
18
18
  </div>
19
19
 
20
- Features: streaming REPL with slash commands (+ autocomplete) · OpenAI / Anthropic / OpenAI-compatible providers with an interactive `/connect` onboarding wizard · built-in fs / bash / web tools with a permission gate · git integration (`/commit` drafts Conventional Commits messages, `/diff` shows a colored working-tree diff, repo status injected into the system prompt) · plan mode with read-only research and plan approval · thinking spinner with dim reasoning preview · diff preview on write/edit approval · `@file` mentions · `!cmd` shell passthrough · custom slash commands from Markdown files · conversation compaction (`/compact`) · session persistence and resume with auto-generated titles (`/resume`, `star -r`) · subagent delegation for focused subtasks · lifecycle hooks (`PreToolUse`/`PostToolUse`/`Stop` shell commands from config) · file-write snapshots with `/undo` and checkpoint rollback with `/rewind` · TODO task tracking · background shell tasks with status-bar visibility (`/tasks`) · terminal bell on long turns and background-task completion · Markdown session export (`/export`) · `/init` + `/doctor` project scaffolding and environment checks · cost estimation · update notifier · `--json` NDJSON output for scripting.
20
+ Features: streaming REPL with slash commands (+ autocomplete) · OpenAI / Anthropic / OpenAI-compatible providers with an interactive `/connect` onboarding wizard · built-in fs / bash / web tools with a permission gate · git integration (`/commit` drafts Conventional Commits messages, `/diff` shows a colored working-tree diff, repo status sent as a per-turn request-scoped reminder so it never breaks the prompt cache) · prompt caching on Anthropic providers (cache breakpoints on the stable prefix and the history tail; OpenAI-style protocols cache server-side automatically) with a status-bar hit rate · token thrift: re-reading an unchanged file answers with a one-line note, and auxiliary calls (summaries, titles) can run on a cheaper `smallModel` · plan mode with read-only research and plan approval · thinking spinner with dim reasoning preview · diff preview on write/edit approval · `@file` mentions · `!cmd` shell passthrough · custom slash commands from Markdown files · conversation compaction (`/compact`) · session persistence and resume with auto-generated titles (`/resume`, `star -r`) · subagent delegation for focused subtasks · lifecycle hooks (`PreToolUse`/`PostToolUse`/`Stop` shell commands from config) · file-write snapshots with `/undo` and checkpoint rollback with `/rewind` · TODO task tracking · background shell tasks with status-bar visibility (`/tasks`) · terminal bell on long turns and background-task completion · Markdown session export (`/export`) · `/init` + `/doctor` project scaffolding and environment checks · cost estimation · update notifier · `--json` NDJSON output for scripting.
21
21
 
22
22
  ## Requirements
23
23
 
@@ -46,60 +46,87 @@ 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" # ask | auto | readonly | yolo | plan
54
- contextMaxTokens = 100000
52
+ defaultModel = "gpt" # name of the [[models]] block used by default
53
+ # smallModel = "haiku" # optional [[models]] block for cheap auxiliary calls
54
+ # (compaction summaries, session titles, completion checks);
55
+ # unset = the active main model does them
56
+ permissionMode = "ask" # ask | auto | readonly | yolo | plan
57
+ contextMaxTokens = 100000 # context window in tokens (per-model override below)
58
+ # compactThresholdTokens = 80000 # optional auto-compaction trigger in tokens; defaults to the
59
+ # context window and is clamped to it (top-level only — there is
60
+ # no per-model override). /compact always compacts, regardless.
55
61
  # Max model round-trips ("steps") per turn between progress checkpoints — one
56
62
  # step is a reply plus the tool calls it asked for; retries and auto-continue
57
63
  # nudges don't count. Reaching the cap while tools still execute resets it
58
64
  # with a notice instead of stopping the turn; 0 disables the cap entirely.
59
65
  maxSteps = 100
60
- # compactThresholdTokens = 80000 # optional auto-compaction trigger in tokens; defaults to the
61
- # context window. /compact always compacts, regardless of this.
62
- contextCompaction = "summary" # summary | truncate — how over-budget history is compacted
63
- # Seconds with no stream output before a stalled response is ended gracefully
64
- # (some relays never close the stream). The first token gets a fixed 120s allowance.
65
- streamIdleTimeoutSec = 20
66
- # sessionBudgetUsd = 5 # optional per-session cost cap in USD; unset = no cap
67
- notifyBell = true # ring the terminal bell when a long turn finishes (REPL only)
68
- notifyBellThresholdSec = 10 # turns shorter than this stay silent
66
+ contextCompaction = "summary" # summary | truncate — how over-budget history is compacted
67
+ streamMaxRetries = 5 # extra attempts per model request on transient failures
68
+ # (network error, 429/5xx, idle cutoff, empty reply); 0 disables
69
+ streamIdleTimeoutSec = 20 # seconds with no stream output before a stalled response is
70
+ # ended gracefully (some relays never close the stream)
71
+ streamFirstChunkTimeoutSec = 300 # seconds to wait for the very first content part — slow
72
+ # thinking-model endpoints can stay silent for minutes
73
+ maxAutoContinues = 2 # nudges for consecutive unproductive text-only replies before
74
+ # the turn is handed back; tool calls reset the count; 0 disables
75
+ doomLoopThreshold = 3 # consecutive identical tool calls before the loop refuses the
76
+ # repeat and tells the model to change approach; 0 disables
77
+ gitSnapshots = true # track the whole working tree each turn (internal repo outside
78
+ # your .git) so /undo and /redo also cover bash-made changes
79
+ # sessionBudgetUsd = 5 # optional per-session cost cap in USD; unset = no cap
80
+ notifyBell = true # ring the terminal bell when a long turn finishes (REPL only)
81
+ notifyBellThresholdSec = 10 # turns shorter than this stay silent
69
82
 
70
83
  [permissions]
71
- # persistent allow-rules, written automatically when you pick "a" (always) on a permission prompt
72
- allow = ["bash(npm test)", "read_file"] # <tool> or <tool(<pattern>)>, * is a glob wildcard
73
- # persistent deny-rules — checked after the hard safety rules; they beat auto mode
74
- # and allow-rules (yolo still bypasses everything)
84
+ # persistent allow-rules, written automatically when you pick "a" (always) on a permission prompt.
85
+ # Syntax: <tool> or <tool(<pattern>)>, * is a glob wildcard. A bash rule is matched per command
86
+ # segment (the command line is split on shell separators): an allow rule must match EVERY segment,
87
+ # and any command substitution or file redirection disables auto-allow entirely.
88
+ allow = ["bash(npm test)", "read_file"]
89
+ # persistent deny-rules — checked after the hard safety rules; a deny matching ANY segment beats
90
+ # auto mode and allow-rules (yolo still bypasses everything)
75
91
  deny = ["bash(rm -rf *)"]
76
92
 
77
93
  [[providers]]
78
94
  name = "openai"
79
- protocol = "openai-compatible"
95
+ protocol = "openai-compatible" # openai-compatible | anthropic | openai-responses
80
96
  baseURL = "https://api.openai.com/v1"
81
- apiKeyEnv = "OPENAI_API_KEY"
82
- # protocol = "openai-responses" # for relays exposing only /v1/responses
97
+ apiKeyEnv = "OPENAI_API_KEY" # recommended: name of the env var holding the key — keys live in
98
+ # ~/.star-cli/.env (written by /connect), never in this file
99
+ # apiKey = "sk-..." # inline key instead of apiKeyEnv (not recommended)
100
+ # headers = { "X-Title" = "star-cli" } # extra HTTP headers sent with every request
101
+ # protocol = "openai-responses" # for relays exposing only /v1/responses
83
102
 
84
103
  [[models]]
85
- name = "gpt"
86
- provider = "openai"
87
- model = "gpt-4o"
88
- # optional per-model context window — overrides the top-level contextMaxTokens
89
- # for compaction and the ctx % in the status bar
90
- # contextMaxTokens = 272000
91
- # optional reasoning intensity for thinking models — forwarded verbatim as
92
- # reasoning_effort on every request. Level naming varies by provider
93
- # (low/medium/high are common; some add minimal/max...). Unset = server
94
- # default. The /model picker also offers these levels after a model pick.
95
- # reasoningEffort = "high"
96
- # optional per-model pricing in USD per 1M tokens — enables the $ estimate in
97
- # /cost and /usage. promptPrice prices input tokens (system prompt, history,
98
- # @file contents, tool results — resent every turn, so the bulk of usage);
99
- # completionPrice prices output tokens (the model's replies and tool calls —
100
- # less volume, usually the pricier rate). BOTH fields are required together.
104
+ name = "gpt" # referenced by defaultModel and -m
105
+ provider = "openai" # name of a [[providers]] block
106
+ model = "gpt-4o" # model id sent to the API
107
+ # maxTokens = 8192 # cap on generated tokens per reply
108
+ # contextMaxTokens = 272000 # per-model context window — overrides the top-level
109
+ # contextMaxTokens for compaction and the ctx % in the status bar
110
+ # temperature = 1 # sampling temperature forwarded on every request. Unset = the AI
111
+ # SDK default applies (ai@4 sends 0 — it does NOT omit the field),
112
+ # so endpoints that mandate one explicit value (kimi-for-coding/k3
113
+ # accept only 1) MUST set it here.
114
+ # reasoningEffort = "high" # reasoning intensity for thinking models, forwarded verbatim as
115
+ # reasoning_effort on every request. Level naming varies by
116
+ # provider (low/medium/high are common; some add minimal/max...).
117
+ # Unset = server default. Ignored for anthropic. The /model
118
+ # picker also offers these levels after a model pick.
119
+ # streamIdleTimeoutSec = 60 # per-model overrides of the global stream watchdog timeouts
120
+ # streamFirstChunkTimeoutSec = 600
121
+ # optional per-model pricing in USD per 1M tokens — enables the $ estimate in /cost and /usage.
122
+ # promptPrice prices input tokens (system prompt, history, @file contents, tool results — resent
123
+ # every turn, so the bulk of usage); completionPrice prices output tokens (the model's replies and
124
+ # tool calls — less volume, usually the pricier rate). BOTH fields are required together.
101
125
  promptPrice = 2.5
102
126
  completionPrice = 10
127
+ # cacheReadPrice = 0.25 # optional price for cache-read prompt tokens; unset = OpenAI-style
128
+ # cached tokens bill at promptPrice and Anthropic-style cache
129
+ # reads are not billed
103
130
 
104
131
  [[providers]]
105
132
  name = "claude"
@@ -115,13 +142,45 @@ model = "claude-sonnet-4-20250514"
115
142
  [[hooks]]
116
143
  event = "PostToolUse" # PreToolUse | PostToolUse | Stop
117
144
  matcher = "edit_file|write_file" # optional regex on the tool name; matches all tools when omitted
118
- command = "biome check --write ."
119
- # timeoutSec = 30 # optional per-hook timeout
145
+ command = "biome check --write ." # PreToolUse exiting with code 2 blocks the tool (stderr
146
+ # becomes its result); Stop fires on every turn end
147
+ # timeoutSec = 30 # optional per-hook timeout (default 30; on timeout the hook
148
+ # is allowed through with a warning)
120
149
  ```
121
150
 
122
151
  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.
123
152
 
124
- 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.
153
+ 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.
154
+
155
+ ### Using a relay (中转站)
156
+
157
+ 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`).
158
+
159
+ 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:
160
+
161
+ ```toml
162
+ [[providers]]
163
+ name = "kimi"
164
+ protocol = "openai-responses"
165
+ baseURL = "https://api.kimi.com/coding/v1" # official Kimi coding endpoint
166
+ apiKeyEnv = "STAR_API_KEY_KIMI"
167
+
168
+ [[models]]
169
+ name = "kimi"
170
+ provider = "kimi"
171
+ model = "kimi-for-coding"
172
+ temperature = 1 # mandatory here — the endpoint rejects any other value
173
+ contextMaxTokens = 128000
174
+ # raise these when the relay buffers long generations:
175
+ # streamIdleTimeoutSec = 60 # default 20
176
+ # streamFirstChunkTimeoutSec = 600 # default 300
177
+ ```
178
+
179
+ ### Environment variables
180
+
181
+ - `STAR_HOME` — overrides `~/.star-cli` as the data home (config, sessions, `.env`, memory, debug log).
182
+ - `STAR_DEBUG` — any non-empty value enables stream diagnostics appended to `~/.star-cli/debug.log`, one JSON object per line.
183
+ - `STAR_NO_NOTIFY=1` — disables the terminal bell without touching the config.
125
184
 
126
185
 
127
186
  ## CLI flags
@@ -292,7 +351,7 @@ A `.starignore` file in the working directory hides paths from the agent: the `g
292
351
 
293
352
  ## Built-in tools
294
353
 
295
- `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.
354
+ `read_file`, `read_image` (attach an image file to the conversation mid-session — screenshots, mockups; png/jpg/gif/webp, auto-downsampled past 2000px), `screenshot` (capture the primary display and see it — visual verification of a running program, e.g. a dev server's rendered page; platform-native capture with no dependencies, DPI-aware on Windows so scaled displays come out pixel-exact, headless sessions get a clear error), `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.
296
355
 
297
356
  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.
298
357
 
package/README.zh-CN.md CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
  </div>
19
19
 
20
- 功能特性:带斜杠命令(+ 自动补全)的流式 REPL · OpenAI / Anthropic / OpenAI 兼容服务商,配交互式 `/connect` 接入向导 · 内置 fs / bash / web 工具,带权限门禁 · git 集成(`/commit` 起草 Conventional Commits 提交信息,`/diff` 显示彩色工作区 diff,仓库状态注入系统提示词)· 计划模式:只读调研 + 计划批准 · 带暗色推理预览的思考动画 · 写入/编辑批准时的 diff 预览 · `@file` 引用 · `!cmd` shell 直通 · 用 Markdown 文件自定义斜杠命令 · 对话压缩(`/compact`)· 会话持久化与恢复,自动生成标题(`/resume`、`star -r`)· 子代理委派,处理专注的子任务 · 生命周期钩子(来自配置的 `PreToolUse`/`PostToolUse`/`Stop` shell 命令)· 文件写入快照 `/undo` 与检查点回滚 `/rewind` · TODO 任务跟踪 · 状态栏可见的后台 shell 任务(`/tasks`)· 长回合与后台任务完成时的终端响铃 · Markdown 会话导出(`/export`)· `/init` + `/doctor` 项目脚手架与环境检查 · 成本估算 · 更新提醒 · 便于脚本化的 `--json` NDJSON 输出。
20
+ 功能特性:带斜杠命令(+ 自动补全)的流式 REPL · OpenAI / Anthropic / OpenAI 兼容服务商,配交互式 `/connect` 接入向导 · 内置 fs / bash / web 工具,带权限门禁 · git 集成(`/commit` 起草 Conventional Commits 提交信息,`/diff` 显示彩色工作区 diff,仓库状态以每回合请求级 reminder 发送,不会破坏提示词缓存)· Anthropic 服务商的提示词缓存(在稳定前缀与历史尾部打缓存断点;OpenAI 系协议由服务端自动缓存),状态栏显示命中率 · token 节俭:重复读取未变化的文件只回一行说明,压缩摘要、标题等辅助调用可配置更便宜的 `smallModel` · 计划模式:只读调研 + 计划批准 · 带暗色推理预览的思考动画 · 写入/编辑批准时的 diff 预览 · `@file` 引用 · `!cmd` shell 直通 · 用 Markdown 文件自定义斜杠命令 · 对话压缩(`/compact`)· 会话持久化与恢复,自动生成标题(`/resume`、`star -r`)· 子代理委派,处理专注的子任务 · 生命周期钩子(来自配置的 `PreToolUse`/`PostToolUse`/`Stop` shell 命令)· 文件写入快照 `/undo` 与检查点回滚 `/rewind` · TODO 任务跟踪 · 状态栏可见的后台 shell 任务(`/tasks`)· 长回合与后台任务完成时的终端响铃 · Markdown 会话导出(`/export`)· `/init` + `/doctor` 项目脚手架与环境检查 · 成本估算 · 更新提醒 · 便于脚本化的 `--json` NDJSON 输出。
21
21
 
22
22
  ## 环境要求
23
23
 
@@ -46,59 +46,84 @@ star -p "hi" # non-interactive print mode
46
46
 
47
47
  ## 配置
48
48
 
49
- 配置文件:`~/.star-cli/config.toml`(项目级覆盖:当前目录下的 `.star/config.toml`;CLI 参数优先于两者)。
49
+ 配置文件:`~/.star-cli/config.toml`(可用环境变量 `STAR_HOME` 把数据目录改为 `~/.star-cli` 以外的位置;项目级覆盖:当前目录下的 `.star/config.toml`,经过沙箱过滤只保留安全键;CLI 参数优先于两者)。
50
50
 
51
51
  ```toml
52
- defaultModel = "gpt"
53
- permissionMode = "ask" # ask | auto | readonly | yolo | plan
54
- contextMaxTokens = 100000
52
+ defaultModel = "gpt" # 默认使用的 [[models]] 块名称
53
+ # smallModel = "haiku" # 可选的 [[models]] 块,用于低价的辅助调用
54
+ #(压缩摘要、会话标题、完成度检查);
55
+ # 不设置 = 由当前主模型执行
56
+ permissionMode = "ask" # ask | auto | readonly | yolo | plan
57
+ contextMaxTokens = 100000 # 上下文窗口(token 数,下方可按模型覆盖)
58
+ # compactThresholdTokens = 80000 # 可选的自动压缩触发阈值(token 数);默认为上下文窗口本身,
59
+ # 且会被钳制到窗口以内(仅顶层键——没有按模型覆盖)。
60
+ # /compact 无视此阈值,总是执行压缩。
55
61
  # 每回合在进度检查点之间允许的最大模型往返("step")数——一个 step 是
56
62
  # 一次回复加上它请求的所有工具调用;重试和 auto-continue nudge 不占 step。
57
63
  # 到达上限时若工具仍在执行,会发提示并重置额度而不是终止回合;0 表示完全不限。
58
64
  maxSteps = 100
59
- # compactThresholdTokens = 80000 # optional auto-compaction trigger in tokens; defaults to the
60
- # context window. /compact always compacts, regardless of this.
61
- contextCompaction = "summary" # summary | truncate — how over-budget history is compacted
62
- # Seconds with no stream output before a stalled response is ended gracefully
63
- # (some relays never close the stream). The first token gets a fixed 120s allowance.
64
- streamIdleTimeoutSec = 20
65
- # sessionBudgetUsd = 5 # optional per-session cost cap in USD; unset = no cap
66
- notifyBell = true # ring the terminal bell when a long turn finishes (REPL only)
67
- notifyBellThresholdSec = 10 # turns shorter than this stay silent
65
+ contextCompaction = "summary" # summary | truncate —— 历史超出预算时的压缩方式
66
+ streamMaxRetries = 5 # 单次模型请求在瞬时失败(网络错误、429/5xx、idle 截断、
67
+ # 空回复)时的额外重试次数;0 表示禁用
68
+ streamIdleTimeoutSec = 20 # 流没有任何输出的秒数,超过后将停滞的响应优雅结束
69
+ #(有些中转站从不关闭流)
70
+ streamFirstChunkTimeoutSec = 300 # 等待第一个内容分片的秒数——慢速思考模型端点在接受请求后
71
+ # 可能静默数分钟
72
+ maxAutoContinues = 2 # 连续无产出的纯文本回复在被 nudge 多少次后交还回合;
73
+ # 工具调用会重置计数;0 表示禁用
74
+ doomLoopThreshold = 3 # 连续相同工具调用达到此次数后,循环拒绝执行该重复调用
75
+ # 并要求模型换思路;0 表示禁用
76
+ gitSnapshots = true # 每回合用内部 git 仓库(位于你的 .git 之外)跟踪整个工作树,
77
+ # 使 /undo 和 /redo 也能覆盖 bash 造成的改动
78
+ # sessionBudgetUsd = 5 # 可选的每会话成本上限(美元);不设置 = 无上限
79
+ notifyBell = true # 长回合结束时响终端铃(仅 REPL)
80
+ notifyBellThresholdSec = 10 # 短于此耗时的回合不响铃
68
81
 
69
82
  [permissions]
70
- # persistent allow-rules, written automatically when you pick "a" (always) on a permission prompt
71
- allow = ["bash(npm test)", "read_file"] # <tool> or <tool(<pattern>)>, * is a glob wildcard
72
- # persistent deny-rules — checked after the hard safety rules; they beat auto mode
73
- # and allow-rules (yolo still bypasses everything)
83
+ # 持久 allow 规则——在权限提示上选择 "a"(始终允许)时自动写入。
84
+ # 语法:<tool> 或 <tool(<pattern>)>,* 是 glob 通配符。bash 规则按命令分段匹配
85
+ #(命令行先按 shell 分隔符切分):allow 规则必须匹配每一段,且命令中含有命令替换
86
+ # 或文件重定向时完全不会自动放行。
87
+ allow = ["bash(npm test)", "read_file"]
88
+ # 持久 deny 规则——在硬性安全规则之后检查;deny 命中任意一段即优先于 auto 模式和
89
+ # allow 规则(yolo 仍然绕过一切)
74
90
  deny = ["bash(rm -rf *)"]
75
91
 
76
92
  [[providers]]
77
93
  name = "openai"
78
- protocol = "openai-compatible"
94
+ protocol = "openai-compatible" # openai-compatible | anthropic | openai-responses
79
95
  baseURL = "https://api.openai.com/v1"
80
- apiKeyEnv = "OPENAI_API_KEY"
81
- # protocol = "openai-responses" # for relays exposing only /v1/responses
96
+ apiKeyEnv = "OPENAI_API_KEY" # 推荐:存放密钥的环境变量名——密钥本体放在
97
+ # ~/.star-cli/.env(由 /connect 写入),绝不出现在本文件
98
+ # apiKey = "sk-..." # 不用 apiKeyEnv 而直接内联密钥(不推荐)
99
+ # headers = { "X-Title" = "star-cli" } # 随每次请求发送的额外 HTTP 头
100
+ # protocol = "openai-responses" # 适用于只暴露 /v1/responses 的中转站
82
101
 
83
102
  [[models]]
84
- name = "gpt"
85
- provider = "openai"
86
- model = "gpt-4o"
87
- # optional per-model context window — overrides the top-level contextMaxTokens
88
- # for compaction and the ctx % in the status bar
89
- # contextMaxTokens = 272000
90
- # 可选的推理强度(思考模型用)——每次请求原样以 reasoning_effort 发送。
91
- # 档位命名因服务商/模型而异(常见 low/medium/high,部分还有 minimal/max 等),
92
- # 因此接受任意字符串,由服务端校验。不设置 = 服务端默认。
93
- # /model 选完模型后也会接着让你选择推理强度。
94
- # reasoningEffort = "high"
95
- # optional per-model pricing in USD per 1M tokens — enables the $ estimate in
96
- # /cost and /usage. promptPrice prices input tokens (system prompt, history,
97
- # @file contents, tool results — resent every turn, so the bulk of usage);
98
- # completionPrice prices output tokens (the model's replies and tool calls —
99
- # less volume, usually the pricier rate). BOTH fields are required together.
103
+ name = "gpt" # 被 defaultModel 和 -m 引用
104
+ provider = "openai" # 某个 [[providers]] 块的 name
105
+ model = "gpt-4o" # 发送给 API 的模型 id
106
+ # maxTokens = 8192 # 单次回复的生成 token 上限
107
+ # contextMaxTokens = 272000 # 按模型的上下文窗口——覆盖顶层 contextMaxTokens,
108
+ # 用于压缩和状态栏的 ctx 百分比
109
+ # temperature = 1 # 采样温度,随每次请求发送。不设置 = 应用 AI SDK 默认值
110
+ #(ai@4 会发送 0——它不会省略该字段),所以只接受某个固定值的
111
+ # 端点(kimi-for-coding/k3 只接受 1)必须在此显式设置。
112
+ # reasoningEffort = "high" # 思考模型的推理强度,每次请求原样以 reasoning_effort 发送。
113
+ # 档位命名因服务商/模型而异(常见 low/medium/high,部分还有
114
+ # minimal/max 等),因此接受任意字符串,由服务端校验。
115
+ # 不设置 = 服务端默认。anthropic 协议下忽略。
116
+ # /model 选完模型后也会接着让你选择推理强度。
117
+ # streamIdleTimeoutSec = 60 # 按模型覆盖全局的流看门狗超时
118
+ # streamFirstChunkTimeoutSec = 600
119
+ # 可选的按模型定价(美元/1M token)——启用 /cost 和 /usage 中的美元估算。
120
+ # promptPrice 为输入 token 定价(系统提示词、历史、@file 内容、工具结果——每回合重发,
121
+ # 是用量的大头);completionPrice 为输出 token 定价(模型的回复和工具调用——量较少,
122
+ # 通常单价更贵)。两个字段必须同时设置。
100
123
  promptPrice = 2.5
101
124
  completionPrice = 10
125
+ # cacheReadPrice = 0.25 # 可选的缓存读取输入 token 价格;不设置 = OpenAI 风格的缓存
126
+ # token 按 promptPrice 计费,Anthropic 风格的缓存读取不计费
102
127
 
103
128
  [[providers]]
104
129
  name = "claude"
@@ -113,14 +138,45 @@ model = "claude-sonnet-4-20250514"
113
138
 
114
139
  [[hooks]]
115
140
  event = "PostToolUse" # PreToolUse | PostToolUse | Stop
116
- matcher = "edit_file|write_file" # optional regex on the tool name; matches all tools when omitted
117
- command = "biome check --write ."
118
- # timeoutSec = 30 # optional per-hook timeout
141
+ matcher = "edit_file|write_file" # 可选的工具名正则;省略时匹配所有工具
142
+ command = "biome check --write ." # PreToolUse 以退出码 2 退出会阻止该工具
143
+ #(stderr 成为工具结果);Stop 在每回合结束时触发
144
+ # timeoutSec = 30 # 可选的单钩子超时(默认 30;超时 = 放行并警告)
119
145
  ```
120
146
 
121
147
  API 密钥优先从环境变量解析(`apiKeyEnv`),其次是配置文件中的 `apiKey` 字段。启动时 Star CLI 还会把 `~/.star-cli/.env`(dotenv 风格的 `KEY=VALUE` 行)加载进环境变量,且不会覆盖已存在的变量——`/connect` 收集的密钥就存放在这里,因此 `config.toml` 只引用变量名,永远不会包含密钥本身。
122
148
 
123
- 配置服务商最快的方式是 REPL 内的 `/connect` 向导:选择预设(OpenAI、Anthropic、Kimi/Moonshot、DeepSeek)或自定义端点,粘贴 API 密钥(输入时掩码显示),命名一个模型,它会把 `[[providers]]`/`[[models]]` 块追加到 `config.toml`(保留已有内容与注释),把密钥写入 `~/.star-cli/.env`(以 `STAR_API_KEY_<NAME>` 为名,在支持的平台上文件权限为 600),并可选择将新模型设为默认——全程无需重启。
149
+ 配置服务商最快的方式是 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 模型拒绝任何其他取值;仅在模型允许时才调低它),另有占位的零价格——可按需改成真实的限额与费率。
150
+
151
+ ### 使用中转站(relay)
152
+
153
+ 第三方中转站通常前置某种标准线路格式:中转支持 Responses API(`/responses`)时把 `protocol` 设为 `openai-responses`,否则用 `openai-compatible`(`/chat/completions`)。
154
+
155
+ 很多中转站会把整段生成缓冲起来再一次性下发——几十秒到几分钟可能没有任何 SSE 分片,看起来像流已死亡。Star CLI 会对每次请求的原始响应字节做时间戳检测:只要还有字节在流动(包括 SDK 自己会吞掉的 SSE 心跳注释),流看门狗就会延长等待而不是中途掐断正在缓冲生成的中转站,并以 10 分钟的总分片静默上限兜底,避免只剩心跳的僵尸连接挂住整个回合。如果某个中转站仍频繁触发 idle 超时,可以调大该模型自己的看门狗:
156
+
157
+ ```toml
158
+ [[providers]]
159
+ name = "kimi"
160
+ protocol = "openai-responses"
161
+ baseURL = "https://api.kimi.com/coding/v1" # Kimi 官方 coding 端点
162
+ apiKeyEnv = "STAR_API_KEY_KIMI"
163
+
164
+ [[models]]
165
+ name = "kimi"
166
+ provider = "kimi"
167
+ model = "kimi-for-coding"
168
+ temperature = 1 # 此处必须设置——该端点拒绝任何其他取值
169
+ contextMaxTokens = 128000
170
+ # 中转站长时间缓冲整段生成时可调大:
171
+ # streamIdleTimeoutSec = 60 # 默认 20
172
+ # streamFirstChunkTimeoutSec = 600 # 默认 300
173
+ ```
174
+
175
+ ### 环境变量
176
+
177
+ - `STAR_HOME` —— 把数据目录从 `~/.star-cli` 改为其他位置(配置、会话、`.env`、记忆、调试日志)。
178
+ - `STAR_DEBUG` —— 任意非空值即启用流诊断日志,追加写入 `~/.star-cli/debug.log`,每行一个 JSON 对象。
179
+ - `STAR_NO_NOTIFY=1` —— 不改配置即可禁用终端响铃。
124
180
 
125
181
 
126
182
  ## CLI 参数
@@ -291,7 +347,7 @@ star -p "what's wrong in this UI?" --image screenshot.png --image mockup.jpg
291
347
 
292
348
  ## 内置工具
293
349
 
294
- `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 规则覆盖。
350
+ `read_file`、`read_image`(会话中把图片文件带给模型——截图、设计稿等;支持 png/jpg/gif/webp,超过 2000px 自动降采样)、`screenshot`(截取主显示器画面给模型看——用于核对运行中程序的真实视觉效果,比如 dev server 渲染的页面;平台原生截图、零依赖,Windows 上 DPI 感知保证缩放下像素精确,无显示器的 headless 会话返回明确错误)、`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 规则覆盖。
295
351
 
296
352
  `subagent` 工具(`exec` 级别,因此在计划模式下隐藏,在 readonly 下被拒绝)派生一个带相同内置工具的子代理循环,处理专注、自包含的子任务——调研、探索或一处孤立的改动——并把子代理的最终报告作为工具结果返回。子代理只运行一层(子代理不能再派生子代理),共享父代理的权限模式与确认提示,其对话不持久化到会话。
297
353