@kairyou/agent-tools 0.8.0 → 0.10.0

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
@@ -26,7 +26,9 @@ Generate a Conventional Commits message from staged changes and wait for user co
26
26
  npx -y skills@latest add kairyou/agent-tools --skill at-commit -g -y
27
27
  ```
28
28
 
29
- - Usage: `/at-commit [<language>]` — language for the commit description (Conventional Commits tokens stay in English)
29
+ Usage:
30
+
31
+ - `/at-commit [<language>]` — language for the commit description (Conventional Commits tokens stay in English)
30
32
 
31
33
  ### at-review
32
34
 
@@ -36,7 +38,9 @@ Review changes for correctness bugs, regressions, convention violations, and hig
36
38
  npx -y skills@latest add kairyou/agent-tools --skill at-review -g -y
37
39
  ```
38
40
 
39
- - Usage: `/at-review [--fix] [<pr|branch|path>]` — reports findings; `--fix` also applies them
41
+ Usage:
42
+
43
+ - `/at-review [--fix] [<pr|branch|path>]` — reports findings; `--fix` also applies them
40
44
 
41
45
  ### at-simplify
42
46
 
@@ -46,7 +50,9 @@ Refactor changes to reduce duplication, lower complexity, and improve code quali
46
50
  npx -y skills@latest add kairyou/agent-tools --skill at-simplify -g -y
47
51
  ```
48
52
 
49
- - Usage: `/at-simplify [<pr|branch|path>]`
53
+ Usage:
54
+
55
+ - `/at-simplify [<pr|branch|path>]`
50
56
 
51
57
  ### at-zentao
52
58
 
@@ -96,8 +102,9 @@ The installer writes `statusLine` to `~/.claude/settings.json`. Example output:
96
102
  # Pick and order the fields via statusline.fields in ~/.agent-tools/config.jsonc:
97
103
  ⎇ main | Opus 4.8 | 5h 7% ⟳2h54m | w 41% ⟳3d1h
98
104
 
99
- # With a compatible API relay, its quota info is shown instead, e.g.:
105
+ # With a compatible API relay, quota info is shown too:
100
106
  ⎇ main | Opus 4.8 | balance $362 | today $61.7 | 30d $566
107
+
101
108
  ```
102
109
 
103
110
  Here `5h` and `w` are Claude's rolling usage windows and `⟳` is the reset
@@ -106,39 +113,32 @@ compatibility and configuration.
106
113
 
107
114
  ### Provider usage
108
115
 
109
- For API relay / gateway setups: shows the relay's balance / quota inside the
110
- agent, so when you pay per use or have plan limits you always know how much you
111
- have spent and how much is left without opening the gateway console.
112
- Works with API-key usage endpoints exposed by Sub2API, One API, New API, and
113
- OpenRouter. Compatibility depends on the gateway version and whether the
114
- corresponding usage endpoint is enabled.
116
+ Shows API relay / gateway balance and quota inside the agent. Supports Sub2API,
117
+ One API (including OneHub and DoneHub), New API, Claude Code Hub, and OpenRouter;
118
+ compatibility depends on the gateway version and enabled usage endpoints.
115
119
 
116
120
  ```bash
117
121
  npx -y @kairyou/agent-tools@latest usage -a claude codex opencode
118
122
  ```
119
123
 
120
- - **Claude Code** — installs the `at-usage` skill into `~/.claude/skills`; invoke
121
- `/at-usage` to show the current usage in the conversation.
122
- - **Codex** adds a hook to `UserPromptSubmit` and `Stop` in `~/.codex/hooks.json`
123
- and the `at-usage` skill to `~/.agents/skills`. Run `/hooks` inside Codex once
124
- to approve it. The Codex CLI displays hook output; some clients (e.g. Paseo)
125
- currently do not — invoke `$at-usage` there.
126
- - **OpenCode** adds server and TUI plugins: usage refreshes when the session
127
- goes idle and shows as a toast, and `/at-usage` shows the latest cached value.
128
- Restart opencode after installing or updating.
129
-
130
- The relay endpoint is auto-discovered — Codex: the active provider's `base_url`
131
- and key from `~/.codex/config.toml` / `auth.json`; Claude Code:
132
- `ANTHROPIC_BASE_URL` plus `ANTHROPIC_AUTH_TOKEN` / `ANTHROPIC_API_KEY`.
133
- Official (non-relay) endpoints are skipped. If it reports
134
- `Provider usage is unavailable.`, point it at the relay explicitly —
135
- `PROVIDER_USAGE_BASE_URL` / `PROVIDER_USAGE_API_KEY` env vars override the
136
- endpoint and key — and tune `providerUsage` in `~/.agent-tools/config.jsonc`:
124
+ - **Claude Code** — invoke `/at-usage` to show the current usage.
125
+ - **Codex** — run `/hooks` once after installation to approve it. The Codex CLI
126
+ displays usage automatically; clients that hide hook output can use `$at-usage`.
127
+ - **OpenCode** usage refreshes when the session goes idle and appears as a
128
+ toast; `/at-usage` shows it on demand. Restart opencode after installing or updating.
129
+
130
+ The relay endpoint is auto-discovered from the existing Codex and Claude Code
131
+ configuration; official (non-relay) endpoints are skipped. If it reports
132
+ `Provider usage is unavailable.`, set `PROVIDER_USAGE_BASE_URL` and
133
+ `PROVIDER_USAGE_API_KEY` to override the endpoint and key. Configure
134
+ `providerUsage` in `~/.agent-tools/config.jsonc` only when needed:
137
135
 
138
136
  ```jsonc
139
137
  {
140
138
  "providerUsage": {
141
- "preset": "auto", // auto | sub2api | one-api | new-api | openrouter | <custom-route-id>
139
+ // auto | sub2api | openai-compatible | one-api | one-hub |
140
+ // done-hub | new-api | claude-code-hub | openrouter | <custom-route-id>
141
+ "preset": "auto",
142
142
  "days": 30, // how many recent days of spend to count
143
143
  "debug": false // true: log probes to ~/.agent-tools/logs/usage-debug.log
144
144
  }
@@ -146,74 +146,37 @@ endpoint and key — and tune `providerUsage` in `~/.agent-tools/config.jsonc`:
146
146
  ```
147
147
 
148
148
  Keep `preset` set to `auto` for automatic detection. Select a specific protocol
149
- only when you know which usage endpoint the gateway exposes; a configured
150
- custom route id is also accepted.
149
+ only when you know which usage endpoint the gateway exposes; a configured custom
150
+ route id is also accepted.
151
151
 
152
152
  Output examples:
153
153
 
154
154
  ```text
155
- # Relay plan quota.
155
+ # Plan limits (sub2api / openai-compatible).
156
156
  D $0.0/$100 | W $0.0/$300 | Exp 07-08
157
157
 
158
- # Wallet balance.
158
+ # Multi-window limits (claude-code-hub).
159
+ 5h $2.1/$10.0 | D $8.0/$20.0 | T $19.0/$100 | Exp 08-31
160
+
161
+ # Balance and usage (one-api / one-hub / done-hub / new-api / openrouter).
162
+ balance $15.0 | used $5.0/$20.0
163
+
164
+ # Wallet and recent spend (sub2api).
159
165
  balance $362 | today $61.7 | 30d $566
160
166
  ```
161
167
 
162
- Fields: `D/W/M` are daily/weekly/monthly spend against plan limits; `Exp` is
163
- the plan expiry; `balance` is wallet credit; `today` and `30d` are API spend.
168
+ Fields: `5h/D/W/M/T` are five-hour/daily/weekly/monthly/total spend against
169
+ limits; `Exp` is the plan expiry; `balance` is wallet credit; `used` is consumed
170
+ credit; `today` and `30d` are today's and the last 30 days' API spend.
164
171
 
165
172
  #### Custom gateway routes
166
173
 
167
- For gateways the built-in probes cannot reach (e.g. cookie-authenticated
168
- relays), write your own route module and declare it in `providerUsage.routes`
169
- (paths resolve against `~/.agent-tools`). Declared routes are probed first;
170
- setting `"preset"` to a route id selects it directly.
171
-
172
- ```jsonc
173
- {
174
- "providerUsage": {
175
- "routes": [
176
- "custom/my-gateway.mjs",
177
- "custom/another-gateway.mjs"
178
- ],
179
- "myGateway": { "username": "me", "password": "..." }
180
- }
181
- }
182
- ```
183
-
184
- ```js
185
- // ~/.agent-tools/custom/my-gateway.mjs
186
- export const meta = { id: "my-gateway" }; // optional; id defaults to the file name
187
-
188
- export async function run(context, { requestJson, agentConfig }) {
189
- // context: { baseUrl, key, providerName, provider, label }
190
- const { myGateway = {} } = await agentConfig(); // the providerUsage object; custom keys welcome
191
-
192
- // Tip: save the token to a file (e.g. under ~/.agent-tools/cache) and reuse
193
- // it; log in again only when a query fails with it (e.g. 401), then save the
194
- // new token.
195
- const login = await fetch(`${context.baseUrl}/api/user/login`, {
196
- method: "POST",
197
- headers: { "content-type": "application/json" },
198
- body: JSON.stringify({ username: myGateway.username, password: myGateway.password }),
199
- });
200
- const session = await login.json();
201
-
202
- // Plain fetch works too; custom headers: authorization, cookie, ...
203
- const me = await requestJson(`${context.baseUrl}/api/user/self`, {
204
- headers: { authorization: `Bearer ${session?.data?.accessToken}` },
205
- });
206
- return { text: `balance ¥${me?.data?.balance}` };
207
- }
208
- ```
209
-
210
- `text` is a free-form string; return `{ text }` on success, throw to fall
211
- through to the next route (with `providerUsage.debug` enabled, failures are
212
- logged to `~/.agent-tools/logs/usage-debug.log`).
174
+ Gateways not covered by the built-in probes can use a custom route. See
175
+ [Custom gateway routes](docs/en/custom-gateway-routes.md).
213
176
 
214
177
  ### Vision (cross-model image understanding)
215
178
 
216
- Lets a main model that cannot see images ask a multimodal model specific questions about an image (local path or http(s) URL) and reason on from the answers. Typical uses: reading error screenshots, implementing UI from design mockups, locating the glitch in a bug-report screenshot. One installer capability bundling three parts: the `inspect_image` MCP stdio server, the `at-vision` policy skill, and a human diagnostic CLI.
179
+ Lets a main model that cannot see images use a multimodal model to analyze error screenshots, implement UI from design mockups, and inspect bug-report screenshots.
217
180
 
218
181
  #### Install
219
182
 
@@ -221,10 +184,7 @@ Lets a main model that cannot see images ask a multimodal model specific questio
221
184
  npx -y @kairyou/agent-tools@latest vision -a claude codex opencode
222
185
  ```
223
186
 
224
- Uninstalling keeps your vision provider config. The installer registers the
225
- `inspect_image` MCP server for each agent (Claude Code: `~/.claude.json`; Codex:
226
- `~/.codex/config.toml`; OpenCode: `opencode.json`) and installs the `at-vision`
227
- skill into the agent's skills directory.
187
+ Uninstalling keeps your vision provider config by default.
228
188
 
229
189
  #### Configure
230
190
 
@@ -236,20 +196,19 @@ skill into the agent's skills directory.
236
196
  "provider": "openai-compatible", // or "anthropic-compatible"
237
197
  "baseUrl": "https://gateway.example.com/v1", // anthropic-compatible: gateway root, /v1/messages is appended
238
198
  "model": "internal-vlm",
239
- "apiKey": { "env": "OPENAI_API_KEY" } // reuse an existing env var, or the key itself
199
+ "apiKey": { "env": "OPENAI_API_KEY" } // read from the OPENAI_API_KEY environment variable
240
200
  // , "timeoutMs": 30000, "maxImageBytes": 20971520, "maxOutputTokens": 8192
241
201
  // , "maxConcurrentRequests": 2, "maxRequestsPerMinute": 30
242
202
  }
243
203
  }
244
204
  ```
245
205
 
246
- `apiKey` takes the key itself, or `{ "env": "VARIABLE_NAME" }` to reuse an existing environment variable; omit it if your gateway needs no key.
247
- The runtime sends provider requests directly, so the API key never enters a shell command; user-facing errors redact it as `***`. `maxConcurrentRequests` and `maxRequestsPerMinute` are shared across local MCP and CLI processes.
248
- Image bytes are streamed into the provider's base64 JSON request without recompression; URL inputs use a private temporary file that is removed after each request.
206
+ `apiKey` can be a key string such as `"apiKey": "sk-..."`, or an environment variable reference such as `{ "env": "OPENAI_API_KEY" }`. Omit it if your gateway requires no key. Prefer an environment variable to avoid storing the key in the config file.
249
207
 
250
208
  #### Use
251
209
 
252
- Pass images as file paths or URLs in your message. The agent prefers the `inspect_image` MCP tool and falls back to the installed local vision CLI when its model gateway cannot invoke MCP namespace tools. Do not paste screenshots directly: with a non-vision main model the paste fails with an API 400 before any tool runs — save the image and give its path instead.
210
+ Pass a local image path or URL in your message. If the main model cannot accept
211
+ pasted images, save the image first and pass its file path instead.
253
212
 
254
213
  To diagnose the provider setup or test recognition quality manually:
255
214
 
@@ -266,25 +225,7 @@ To run directly from the repository, replace the npm package name with
266
225
  npx -y github:kairyou/agent-tools usage -a codex
267
226
  ```
268
227
 
269
- ## Repository Structure
270
-
271
- ```text
272
- agent-tools/
273
- ├── .claude-plugin/ # Claude Code/plugin ecosystem manifest.
274
- ├── .codex-plugin/ # Codex plugin manifest.
275
- ├── integrations/ # Installable capabilities, one directory each.
276
- │ ├── statusline/ # Agent status line: branch, model, usage.
277
- │ ├── usage/ # Provider balance / quota display.
278
- │ └── vision/ # Cross-model image understanding.
279
- ├── skills/ # Reusable Agent Skills.
280
- │ ├── workflow/ # Workflow-oriented skills.
281
- │ │ ├── at-commit/ # Conventional Commit message skill.
282
- │ │ ├── at-review/ # Review changes for bugs and regressions.
283
- │ │ └── at-simplify/ # Reduce complexity and duplication in changes.
284
- │ └── integrations/ # Skills that integrate external systems.
285
- │ └── at-zentao/ # ZenTao bug/task fixing workflow.
286
- └── scripts/ # Install, sync, validation, and maintenance scripts.
287
- ```
228
+ Contributors can see the [repository structure](docs/en/repository-structure.md).
288
229
 
289
230
  ## FAQ
290
231
 
@@ -294,8 +235,11 @@ agent-tools/
294
235
  PromptScript agent does not support global installation. It does not affect
295
236
  other agents and can be ignored. See [`skills` issue #1352](https://github.com/vercel-labs/skills/issues/1352).
296
237
 
297
- ## References
238
+ ## Acknowledgements
298
239
 
299
- - [OpenCommit](https://github.com/di-sukharev/opencommit)
300
- - [GitLens](https://github.com/gitkraken/vscode-gitlens)
301
- - [claude-code-system-prompts](https://github.com/Piebald-AI/claude-code-system-prompts)
240
+ - `at-commit` draws on commit-message generation ideas from
241
+ [OpenCommit](https://github.com/di-sukharev/opencommit) and
242
+ [GitLens](https://github.com/gitkraken/vscode-gitlens), reimplemented for an
243
+ Agent Skill workflow.
244
+ - `at-review` and `at-simplify` draw on the corresponding workflows in
245
+ [claude-code-system-prompts](https://github.com/Piebald-AI/claude-code-system-prompts).
package/README.zh-CN.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Agent Tools
2
2
 
3
+ [English](README.md)
4
+
3
5
  可复用的 Agent Skills, 以及面向 Codex, Claude Code 与 opencode 的可安装 integrations: statusline, provider usage 与跨模型识图.
4
6
 
5
7
  需要 Node.js >= 22.
@@ -24,7 +26,9 @@ npx -y skills@latest add kairyou/agent-tools --skill <name...> -g -y
24
26
  npx -y skills@latest add kairyou/agent-tools --skill at-commit -g -y
25
27
  ```
26
28
 
27
- - 用法: `/at-commit [<语言>]` — 指定 commit description 的语言(Conventional Commits 语法部分保持英文)
29
+ 用法:
30
+
31
+ - `/at-commit [<语言>]` — 指定 commit description 的语言(Conventional Commits 语法部分保持英文)
28
32
 
29
33
  ### at-review
30
34
 
@@ -34,7 +38,9 @@ npx -y skills@latest add kairyou/agent-tools --skill at-commit -g -y
34
38
  npx -y skills@latest add kairyou/agent-tools --skill at-review -g -y
35
39
  ```
36
40
 
37
- - 用法: `/at-review [--fix] [<pr|分支|路径>]` — 输出审查结果; 加 `--fix` 则同时应用修复
41
+ 用法:
42
+
43
+ - `/at-review [--fix] [<pr|分支|路径>]` — 输出审查结果; 加 `--fix` 则同时应用修复
38
44
 
39
45
  ### at-simplify
40
46
 
@@ -44,7 +50,9 @@ npx -y skills@latest add kairyou/agent-tools --skill at-review -g -y
44
50
  npx -y skills@latest add kairyou/agent-tools --skill at-simplify -g -y
45
51
  ```
46
52
 
47
- - 用法: `/at-simplify [<pr|分支|路径>]`
53
+ 用法:
54
+
55
+ - `/at-simplify [<pr|分支|路径>]`
48
56
 
49
57
  ### at-zentao
50
58
 
@@ -93,8 +101,9 @@ npx -y @kairyou/agent-tools@latest statusline -a claude
93
101
  # 显示项与顺序由 ~/.agent-tools/config.jsonc 的 statusline.fields 控制:
94
102
  ⎇ main | Opus 4.8 | 5h 7% ⟳2h54m | w 41% ⟳3d1h
95
103
 
96
- # 使用兼容的 API 中转时, 显示中转的额度信息, 比如:
104
+ # 使用兼容的 API 中转时, 也会显示中转额度:
97
105
  ⎇ main | Opus 4.8 | balance $362 | today $61.7 | 30d $566
106
+
98
107
  ```
99
108
 
100
109
  其中 `5h` / `w` 是 Claude 的滚动用量窗口, `⟳` 后面是重置倒计时;
@@ -102,35 +111,31 @@ npx -y @kairyou/agent-tools@latest statusline -a claude
102
111
 
103
112
  ### Provider usage
104
113
 
105
- 面向使用 API 中转的场景: agent 内直接显示中转网关的余额/额度, 按量付费或
106
- 有套餐限额时, 随时知道花了多少, 还剩多少, 不用切出去登录网关后台.
107
- 支持 Sub2API, One API, New API 与 OpenRouter 提供的 API Key 用量接口.
108
- 具体兼容性取决于网关版本及其是否开放相应接口.
114
+ agent 内查看 API 中转网关的余额和额度. 支持 Sub2API, One API (包括 OneHub
115
+ DoneHub), New API, Claude Code Hub 和 OpenRouter. 具体兼容性取决于网关版本
116
+ 及其是否开放相应接口.
109
117
 
110
118
  ```bash
111
119
  npx -y @kairyou/agent-tools@latest usage -a claude codex opencode
112
120
  ```
113
121
 
114
- - **Claude Code** — `at-usage` skill 装入 `~/.claude/skills`; 调用
115
- `/at-usage` 即可在对话中显示当前用量.
116
- - **Codex** — 把 hook 添加到 `~/.codex/hooks.json` 的 `UserPromptSubmit` 和
117
- `Stop`, 并把 `at-usage` skill 装入 `~/.agents/skills`. 安装后在 Codex 里运行
118
- `/hooks` 批准一次. Codex CLI 会显示 hook 输出; 部分客户端(如 Paseo)目前不显示,
119
- 可调用 `$at-usage` 按需查询.
120
- - **OpenCode** — 添加 server plugin TUI plugin: session 进入 idle 后自动刷新
121
- usage 并以 toast 显示, `/at-usage` 查看最新缓存值. 安装或更新后需要重启 opencode.
122
-
123
- 中转端点自动发现 Codex: 读取 `~/.codex/config.toml` / `auth.json` 里当前
124
- provider 的 `base_url` 和密钥; Claude Code: 读取 `ANTHROPIC_BASE_URL` 与
125
- `ANTHROPIC_AUTH_TOKEN` / `ANTHROPIC_API_KEY`. 官方(非中转)端点会被跳过.
126
- 如果结果是 `Provider usage is unavailable.`, 可用环境变量
127
- `PROVIDER_USAGE_BASE_URL` / `PROVIDER_USAGE_API_KEY` 显式指定端点和密钥,
128
- 并在 `~/.agent-tools/config.jsonc` 里调整 `providerUsage`:
122
+ - **Claude Code** — 调用 `/at-usage` 在对话中查看当前用量.
123
+ - **Codex** — 安装后运行 `/hooks` 批准一次. Codex CLI 会自动显示用量;
124
+ 不显示 hook 输出的客户端可调用 `$at-usage` 查询.
125
+ - **OpenCode** 空闲时自动刷新并以 toast 显示, 也可调用 `/at-usage` 查询.
126
+ 安装或更新后需要重启 opencode.
127
+
128
+ 默认会从 CodexClaude Code 的现有配置中自动发现中转端点, 并跳过官方端点.
129
+ 如果结果是 `Provider usage is unavailable.`, 可用
130
+ `PROVIDER_USAGE_BASE_URL` / `PROVIDER_USAGE_API_KEY` 显式指定端点和密钥.
131
+ 需要调整探测方式时, `~/.agent-tools/config.jsonc` 中配置 `providerUsage`:
129
132
 
130
133
  ```jsonc
131
134
  {
132
135
  "providerUsage": {
133
- "preset": "auto", // auto | sub2api | one-api | new-api | openrouter | <自定义 route id>
136
+ // auto | sub2api | openai-compatible | one-api | one-hub |
137
+ // done-hub | new-api | claude-code-hub | openrouter | <自定义 route id>
138
+ "preset": "auto",
134
139
  "days": 30, // 统计最近多少天的消耗
135
140
  "debug": false // true: 探测过程写入 ~/.agent-tools/logs/usage-debug.log
136
141
  }
@@ -143,65 +148,30 @@ provider 的 `base_url` 和密钥; Claude Code: 读取 `ANTHROPIC_BASE_URL` 与
143
148
  显示效果示例:
144
149
 
145
150
  ```text
146
- # 中转套餐额度.
151
+ # 套餐限额 (sub2api / openai-compatible).
147
152
  D $0.0/$100 | W $0.0/$300 | Exp 07-08
148
153
 
149
- # 钱包余额.
154
+ # 多窗口限额 (claude-code-hub).
155
+ 5h $2.1/$10.0 | D $8.0/$20.0 | T $19.0/$100 | Exp 08-31
156
+
157
+ # 余额与用量 (one-api / one-hub / done-hub / new-api / openrouter).
158
+ balance $15.0 | used $5.0/$20.0
159
+
160
+ # 钱包与近期消耗 (sub2api).
150
161
  balance $362 | today $61.7 | 30d $566
151
162
  ```
152
163
 
153
- 字段含义: `D/W/M` 是日/周/月套餐消耗与上限, `Exp` 是套餐到期日,
154
- `balance` 是钱包余额, `today` / `30d` 是今日与近 30 天 API 消耗.
164
+ 字段含义: `5h/D/W/M/T` 5 小时/日/周/月/总消耗与上限, `Exp` 是套餐到期日,
165
+ `balance` 是钱包余额, `used` 是已用额度, `today` / `30d` 是今日与近 30 天 API 消耗.
155
166
 
156
167
  #### 自定义网关路由
157
168
 
158
- 内置探测覆盖不到的网关(比如 cookie 认证的中转), 可以自己写路由模块并在
159
- `providerUsage.routes` 里声明(相对 `~/.agent-tools` 解析). 声明的路由优先
160
- 探测; `"preset"` 填路由 id 可直接选中.
161
-
162
- ```jsonc
163
- {
164
- "providerUsage": {
165
- "routes": [
166
- "custom/my-gateway.mjs",
167
- "custom/another-gateway.mjs"
168
- ],
169
- "myGateway": { "username": "me", "password": "..." }
170
- }
171
- }
172
- ```
173
-
174
- ```js
175
- // ~/.agent-tools/custom/my-gateway.mjs
176
- export const meta = { id: "my-gateway" }; // 可选; id 缺省用文件名
177
-
178
- export async function run(context, { requestJson, agentConfig }) {
179
- // context: { baseUrl, key, providerName, provider, label }
180
- const { myGateway = {} } = await agentConfig(); // providerUsage 对象, 自定义键随意加
181
-
182
- // 建议: 把 token 存到文件里(如 ~/.agent-tools/cache 下)重复使用,
183
- // 用它查询失败(如 401)时才重新登录, 并把新 token 写回文件.
184
- const login = await fetch(`${context.baseUrl}/api/user/login`, {
185
- method: "POST",
186
- headers: { "content-type": "application/json" },
187
- body: JSON.stringify({ username: myGateway.username, password: myGateway.password }),
188
- });
189
- const session = await login.json();
190
-
191
- // 用 fetch 也行; 自定义 header: authorization, cookie 等.
192
- const me = await requestJson(`${context.baseUrl}/api/user/self`, {
193
- headers: { authorization: `Bearer ${session?.data?.accessToken}` },
194
- });
195
- return { text: `balance ¥${me?.data?.balance}` };
196
- }
197
- ```
198
-
199
- `text` 是自由字符串; 成功返回 `{ text }`, 抛错则回落到下一条路由
200
- (开启 `providerUsage.debug` 后, 失败会记录到 `~/.agent-tools/logs/usage-debug.log`).
169
+ 内置探测覆盖不到的网关可以通过自定义路由接入, 详见
170
+ [自定义网关路由](docs/zh-CN/custom-gateway-routes.md).
201
171
 
202
172
  ### Vision(跨模型识图)
203
173
 
204
- 让不支持图片的主模型借助多模态模型识图: 针对图片(本地路径或 http(s) URL)提出具体问题, 拿到答案后继续自己的推理. 常见场景: 读取报错截图, 按设计稿还原 UI, 定位测试反馈截图里的界面问题. 一个安装器 capability 包含三部分: `inspect_image` MCP stdio server, `at-vision` 策略 skill, 以及人工诊断 CLI.
174
+ 让不支持图片的主模型借助多模态模型识图, 适用于读取报错截图、按设计稿还原 UI、定位测试反馈截图里的界面问题.
205
175
 
206
176
  #### 安装
207
177
 
@@ -209,9 +179,7 @@ export async function run(context, { requestJson, agentConfig }) {
209
179
  npx -y @kairyou/agent-tools@latest vision -a claude codex opencode
210
180
  ```
211
181
 
212
- 卸载默认保留 vision provider 配置. 安装器会为每个 agent 注册 `inspect_image`
213
- MCP server (Claude Code: `~/.claude.json`; Codex: `~/.codex/config.toml`;
214
- OpenCode: `opencode.json`), 并把 `at-vision` skill 装入对应 agent 的 skills 目录.
182
+ 卸载时默认保留 vision provider 配置.
215
183
 
216
184
  #### 配置
217
185
 
@@ -223,20 +191,19 @@ OpenCode: `opencode.json`), 并把 `at-vision` skill 装入对应 agent 的 skil
223
191
  "provider": "openai-compatible", // 或 "anthropic-compatible"
224
192
  "baseUrl": "https://gateway.example.com/v1", // anthropic-compatible 填网关根地址, 会自动拼 /v1/messages
225
193
  "model": "internal-vlm",
226
- "apiKey": { "env": "OPENAI_API_KEY" } // 引用已有环境变量, 也可以直接填密钥
194
+ "apiKey": { "env": "OPENAI_API_KEY" } // 从环境变量 OPENAI_API_KEY 读取
227
195
  // , "timeoutMs": 30000, "maxImageBytes": 20971520, "maxOutputTokens": 8192
228
196
  // , "maxConcurrentRequests": 2, "maxRequestsPerMinute": 30
229
197
  }
230
198
  }
231
199
  ```
232
200
 
233
- `apiKey` 可直接填密钥, 或用 `{ "env": "VARIABLE_NAME" }` 引用已有环境变量; 网关不需要密钥时可省略.
234
- Provider 请求由 runtime 直接发送, API key 不进入 shell 命令; 对外错误会将 key 脱敏为 `***`. `maxConcurrentRequests` 和 `maxRequestsPerMinute` 在本机的 MCP/CLI 进程之间共享.
235
- 图片字节会无损地流式编码到 Provider 的 base64 JSON 请求中, 不做重压缩; URL 图片使用私有临时文件, 每次请求结束后自动删除.
201
+ `apiKey` 可以直接填写密钥字符串, 例如 `"apiKey": "sk-..."`; 也可以使用 `{ "env": "OPENAI_API_KEY" }` 从环境变量读取. 网关不需要密钥时可以省略. 建议优先使用环境变量, 避免把密钥写入配置文件.
236
202
 
237
203
  #### 使用
238
204
 
239
- 在消息里给出图片的文件路径或 URL 即可. Agent 优先调用 MCP 的 `inspect_image`; 模型网关不支持 MCP namespace tools 时, 改用已安装的本地 vision CLI. 不要直接粘贴截图: 主模型不支持图片时, 粘贴会在到达工具前就报 API 400 — 保存成文件再给路径.
205
+ 在消息里给出本地图片路径或 URL 即可. 主模型不支持图片时, 请先保存图片,
206
+ 再提供文件路径, 不要直接粘贴.
240
207
 
241
208
  人工排查配置或测试识别质量时可用:
242
209
 
@@ -252,25 +219,7 @@ npx -y @kairyou/agent-tools@latest inspect-image <path|url> -q "导航栏的背
252
219
  npx -y github:kairyou/agent-tools usage -a codex
253
220
  ```
254
221
 
255
- ## 仓库结构
256
-
257
- ```text
258
- agent-tools/
259
- ├── .claude-plugin/ # Claude Code/plugin 生态的 manifest.
260
- ├── .codex-plugin/ # Codex plugin manifest.
261
- ├── integrations/ # 可安装的 capability, 一个一目录.
262
- │ ├── statusline/ # Agent 状态栏: 分支, 模型, 用量.
263
- │ ├── usage/ # Provider 余额/额度显示.
264
- │ └── vision/ # 跨模型识图.
265
- ├── skills/ # 可复用的 Agent Skills.
266
- │ ├── workflow/ # 工作流类 skills.
267
- │ │ ├── at-commit/ # 生成 Conventional Commits message.
268
- │ │ ├── at-review/ # 审查改动中的 bug 与回归风险.
269
- │ │ └── at-simplify/ # 减少改动中的冗余和复杂度.
270
- │ └── integrations/ # 对接外部系统的 skills.
271
- │ └── at-zentao/ # 禅道 bug/task 修复工作流.
272
- └── scripts/ # 安装, 同步, 校验和仓库维护脚本.
273
- ```
222
+ 贡献者可参考[仓库结构](docs/zh-CN/repository-structure.md).
274
223
 
275
224
  ## FAQ
276
225
 
@@ -279,8 +228,11 @@ agent-tools/
279
228
  `PromptScript does not support global skill installation` 表示 PromptScript Agent 不支持全局
280
229
  安装, 不影响其他 Agent, 可忽略. 参见 [`skills` issue #1352](https://github.com/vercel-labs/skills/issues/1352).
281
230
 
282
- ## References
231
+ ## 参考与致谢
283
232
 
284
- - [OpenCommit](https://github.com/di-sukharev/opencommit)
285
- - [GitLens](https://github.com/gitkraken/vscode-gitlens)
286
- - [claude-code-system-prompts](https://github.com/Piebald-AI/claude-code-system-prompts)
233
+ - `at-commit` 借鉴了 [OpenCommit](https://github.com/di-sukharev/opencommit)
234
+ [GitLens](https://github.com/gitkraken/vscode-gitlens) 的提交消息生成思路,
235
+ 并针对 Agent Skill 工作流重新实现.
236
+ - `at-review` 和 `at-simplify` 参考了
237
+ [claude-code-system-prompts](https://github.com/Piebald-AI/claude-code-system-prompts)
238
+ 中对应工作流的设计.
@@ -875,9 +875,10 @@ var AUTH_PATH = join(CODEX_HOME, "auth.json");
875
875
  var CODEX_CONFIG_PATH = join(CODEX_HOME, "config.toml");
876
876
  var AGENT_CONFIG_PATH = join(AGENT_TOOLS_HOME, "config.jsonc");
877
877
  var DEBUG_PATH = join(AGENT_TOOLS_HOME, "logs", "usage-debug.log");
878
- var ROUTE_CACHE_PATH = join(AGENT_TOOLS_HOME, "cache", "usage-routes.json");
879
- var SNAPSHOT_PATH = join(AGENT_TOOLS_HOME, "cache", "usage-snapshot.json");
880
- var REFRESH_STATE_PATH = join(AGENT_TOOLS_HOME, "cache", "usage-refresh-state.json");
878
+ var CACHE_DIR = join(AGENT_TOOLS_HOME, "cache");
879
+ var ROUTE_CACHE_PATH = join(CACHE_DIR, "usage-routes.json");
880
+ var SNAPSHOT_PATH = join(CACHE_DIR, "usage-snapshot.json");
881
+ var REFRESH_STATE_PATH = join(CACHE_DIR, "usage-refresh-state.json");
881
882
  async function readTextIfExists(path) {
882
883
  if (!existsSync(path)) return "";
883
884
  return readFile(path, "utf8");
@@ -928,6 +929,7 @@ async function debugLog(event) {
928
929
  await writeFile(DEBUG_PATH, `${line}
929
930
  `, { flag: "a" });
930
931
  }
932
+ var HOOK_SNAPSHOT_MAX_AGE_MS = 10 * 6e4;
931
933
 
932
934
  // integrations/usage/cli.mjs
933
935
  function parseAgent(argv) {
@@ -13,6 +13,7 @@ var LOG_PATH = path.join(AGENT_TOOLS_HOME, "logs", "usage-hook.log");
13
13
  var TIMEOUT_MS = Number(process.env.AGENT_TOOLS_USAGE_HOOK_TIMEOUT_MS || 4500);
14
14
  var MAX_LOG_BYTES = Number(process.env.AGENT_TOOLS_USAGE_HOOK_LOG_BYTES || 256 * 1024);
15
15
  var KEEP_LOG_BYTES = 128 * 1024;
16
+ var SILENT = process.argv.includes("--silent");
16
17
  function hookOut(message) {
17
18
  const payload = { continue: true };
18
19
  if (message) payload.systemMessage = message;
@@ -56,6 +57,9 @@ function rotateLogIfNeeded() {
56
57
  function failureMessage() {
57
58
  return `API usage hook failed; see ${LOG_PATH.replace(/\\/g, "/")}`;
58
59
  }
60
+ function hookFailureOut() {
61
+ hookOut(SILENT ? "" : failureMessage());
62
+ }
59
63
  function parseHookJson(stdout) {
60
64
  const text = stdout.trim();
61
65
  if (!text) return { continue: true };
@@ -64,16 +68,20 @@ function parseHookJson(stdout) {
64
68
  async function runUsageScript() {
65
69
  if (!fs.existsSync(USAGE_SCRIPT)) {
66
70
  logFailure({ reason: "missing usage script", usageScript: USAGE_SCRIPT });
67
- hookOut(failureMessage());
71
+ hookFailureOut();
68
72
  return;
69
73
  }
70
74
  const result = await new Promise((resolve) => {
71
- const child = spawn(process.execPath, [USAGE_SCRIPT, "hook", "--agent", "codex"], {
72
- cwd: process.cwd(),
73
- env: process.env,
74
- stdio: ["ignore", "pipe", "pipe"],
75
- windowsHide: true
76
- });
75
+ const child = spawn(
76
+ process.execPath,
77
+ [USAGE_SCRIPT, "hook", "--agent", "codex", ...SILENT ? ["--silent"] : []],
78
+ {
79
+ cwd: process.cwd(),
80
+ env: process.env,
81
+ stdio: ["ignore", "pipe", "pipe"],
82
+ windowsHide: true
83
+ }
84
+ );
77
85
  let stdout = "";
78
86
  let stderr = "";
79
87
  let settled = false;
@@ -114,7 +122,7 @@ async function runUsageScript() {
114
122
  node: process.version,
115
123
  platform: `${process.platform} ${os.release()}`
116
124
  });
117
- hookOut(failureMessage());
125
+ hookFailureOut();
118
126
  return;
119
127
  }
120
128
  try {
@@ -129,7 +137,7 @@ async function runUsageScript() {
129
137
  stderr: preview(result.stderr),
130
138
  usageScript: USAGE_SCRIPT
131
139
  });
132
- hookOut(failureMessage());
140
+ hookFailureOut();
133
141
  }
134
142
  }
135
143
  try {
@@ -140,5 +148,5 @@ try {
140
148
  error: error?.stack || error?.message || String(error),
141
149
  usageScript: USAGE_SCRIPT
142
150
  });
143
- hookOut(failureMessage());
151
+ hookFailureOut();
144
152
  }