@kairyou/agent-tools 0.9.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
@@ -102,8 +102,9 @@ The installer writes `statusLine` to `~/.claude/settings.json`. Example output:
102
102
  # Pick and order the fields via statusline.fields in ~/.agent-tools/config.jsonc:
103
103
  ⎇ main | Opus 4.8 | 5h 7% ⟳2h54m | w 41% ⟳3d1h
104
104
 
105
- # With a compatible API relay, its quota info is shown instead, e.g.:
105
+ # With a compatible API relay, quota info is shown too:
106
106
  ⎇ main | Opus 4.8 | balance $362 | today $61.7 | 30d $566
107
+
107
108
  ```
108
109
 
109
110
  Here `5h` and `w` are Claude's rolling usage windows and `⟳` is the reset
@@ -112,35 +113,25 @@ compatibility and configuration.
112
113
 
113
114
  ### Provider usage
114
115
 
115
- For API relay / gateway setups: shows the relay's balance / quota inside the
116
- agent, so when you pay per use or have plan limits you always know how much you
117
- have spent and how much is left without opening the gateway console.
118
- Works with API-key usage endpoints exposed by relay software such as Sub2API,
119
- One API (including OneHub and DoneHub), New API, and Claude Code Hub. It also
120
- supports the OpenRouter platform. Compatibility depends on the gateway version
121
- and whether the 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.
122
119
 
123
120
  ```bash
124
121
  npx -y @kairyou/agent-tools@latest usage -a claude codex opencode
125
122
  ```
126
123
 
127
- - **Claude Code** — installs the `at-usage` skill into `~/.claude/skills`; invoke
128
- `/at-usage` to show the current usage in the conversation.
129
- - **Codex** adds a hook to `UserPromptSubmit` and `Stop` in `~/.codex/hooks.json`
130
- and the `at-usage` skill to `~/.agents/skills`. Run `/hooks` inside Codex once
131
- to approve it. The Codex CLI displays hook output; some clients (e.g. Paseo)
132
- currently do not — invoke `$at-usage` there.
133
- - **OpenCode** adds server and TUI plugins: usage refreshes when the session
134
- goes idle and shows as a toast, and `/at-usage` shows the latest cached value.
135
- Restart opencode after installing or updating.
136
-
137
- The relay endpoint is auto-discovered — Codex: the active provider's `base_url`
138
- and key from `~/.codex/config.toml` / `auth.json`; Claude Code:
139
- `ANTHROPIC_BASE_URL` plus `ANTHROPIC_AUTH_TOKEN` / `ANTHROPIC_API_KEY`.
140
- Official (non-relay) endpoints are skipped. If it reports
141
- `Provider usage is unavailable.`, point it at the relay explicitly —
142
- `PROVIDER_USAGE_BASE_URL` / `PROVIDER_USAGE_API_KEY` env vars override the
143
- 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:
144
135
 
145
136
  ```jsonc
146
137
  {
@@ -155,8 +146,8 @@ endpoint and key — and tune `providerUsage` in `~/.agent-tools/config.jsonc`:
155
146
  ```
156
147
 
157
148
  Keep `preset` set to `auto` for automatic detection. Select a specific protocol
158
- only when you know which usage endpoint the gateway exposes; a configured
159
- 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.
160
151
 
161
152
  Output examples:
162
153
 
@@ -175,61 +166,17 @@ balance $362 | today $61.7 | 30d $566
175
166
  ```
176
167
 
177
168
  Fields: `5h/D/W/M/T` are five-hour/daily/weekly/monthly/total spend against
178
- limits; `Exp` is the plan expiry; `balance` is wallet credit; `today` and `30d`
179
- are API spend.
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.
180
171
 
181
172
  #### Custom gateway routes
182
173
 
183
- For gateways the built-in probes cannot reach (e.g. cookie-authenticated
184
- relays), write your own route module and declare it in `providerUsage.routes`
185
- (paths resolve against `~/.agent-tools`). Declared routes are probed first;
186
- setting `"preset"` to a route id selects it directly.
187
-
188
- ```jsonc
189
- {
190
- "providerUsage": {
191
- "routes": [
192
- "custom/my-gateway.mjs",
193
- "custom/another-gateway.mjs"
194
- ],
195
- "myGateway": { "username": "me", "password": "..." }
196
- }
197
- }
198
- ```
199
-
200
- ```js
201
- // ~/.agent-tools/custom/my-gateway.mjs
202
- export const meta = { id: "my-gateway" }; // optional; id defaults to the file name
203
-
204
- export async function run(context, { requestJson, agentConfig }) {
205
- // context: { baseUrl, key, providerName, provider, label }
206
- const { myGateway = {} } = await agentConfig(); // the providerUsage object; custom keys welcome
207
-
208
- // Tip: save the token to a file (e.g. under ~/.agent-tools/cache) and reuse
209
- // it; log in again only when a query fails with it (e.g. 401), then save the
210
- // new token.
211
- const login = await fetch(`${context.baseUrl}/api/user/login`, {
212
- method: "POST",
213
- headers: { "content-type": "application/json" },
214
- body: JSON.stringify({ username: myGateway.username, password: myGateway.password }),
215
- });
216
- const session = await login.json();
217
-
218
- // Plain fetch works too; custom headers: authorization, cookie, ...
219
- const me = await requestJson(`${context.baseUrl}/api/user/self`, {
220
- headers: { authorization: `Bearer ${session?.data?.accessToken}` },
221
- });
222
- return { text: `balance ¥${me?.data?.balance}` };
223
- }
224
- ```
225
-
226
- `text` is a free-form string; return `{ text }` on success, throw to fall
227
- through to the next route (with `providerUsage.debug` enabled, failures are
228
- 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).
229
176
 
230
177
  ### Vision (cross-model image understanding)
231
178
 
232
- 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.
233
180
 
234
181
  #### Install
235
182
 
@@ -237,10 +184,7 @@ Lets a main model that cannot see images ask a multimodal model specific questio
237
184
  npx -y @kairyou/agent-tools@latest vision -a claude codex opencode
238
185
  ```
239
186
 
240
- Uninstalling keeps your vision provider config. The installer registers the
241
- `inspect_image` MCP server for each agent (Claude Code: `~/.claude.json`; Codex:
242
- `~/.codex/config.toml`; OpenCode: `opencode.json`) and installs the `at-vision`
243
- skill into the agent's skills directory.
187
+ Uninstalling keeps your vision provider config by default.
244
188
 
245
189
  #### Configure
246
190
 
@@ -252,20 +196,19 @@ skill into the agent's skills directory.
252
196
  "provider": "openai-compatible", // or "anthropic-compatible"
253
197
  "baseUrl": "https://gateway.example.com/v1", // anthropic-compatible: gateway root, /v1/messages is appended
254
198
  "model": "internal-vlm",
255
- "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
256
200
  // , "timeoutMs": 30000, "maxImageBytes": 20971520, "maxOutputTokens": 8192
257
201
  // , "maxConcurrentRequests": 2, "maxRequestsPerMinute": 30
258
202
  }
259
203
  }
260
204
  ```
261
205
 
262
- `apiKey` takes the key itself, or `{ "env": "VARIABLE_NAME" }` to reuse an existing environment variable; omit it if your gateway needs no key.
263
- 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.
264
- 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.
265
207
 
266
208
  #### Use
267
209
 
268
- 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.
269
212
 
270
213
  To diagnose the provider setup or test recognition quality manually:
271
214
 
@@ -282,25 +225,7 @@ To run directly from the repository, replace the npm package name with
282
225
  npx -y github:kairyou/agent-tools usage -a codex
283
226
  ```
284
227
 
285
- ## Repository Structure
286
-
287
- ```text
288
- agent-tools/
289
- ├── .claude-plugin/ # Claude Code/plugin ecosystem manifest.
290
- ├── .codex-plugin/ # Codex plugin manifest.
291
- ├── integrations/ # Installable capabilities, one directory each.
292
- │ ├── statusline/ # Agent status line: branch, model, usage.
293
- │ ├── usage/ # Provider balance / quota display.
294
- │ └── vision/ # Cross-model image understanding.
295
- ├── skills/ # Reusable Agent Skills.
296
- │ ├── workflow/ # Workflow-oriented skills.
297
- │ │ ├── at-commit/ # Conventional Commit message skill.
298
- │ │ ├── at-review/ # Review changes for bugs and regressions.
299
- │ │ └── at-simplify/ # Reduce complexity and duplication in changes.
300
- │ └── integrations/ # Skills that integrate external systems.
301
- │ └── at-zentao/ # ZenTao bug/task fixing workflow.
302
- └── scripts/ # Install, sync, validation, and maintenance scripts.
303
- ```
228
+ Contributors can see the [repository structure](docs/en/repository-structure.md).
304
229
 
305
230
  ## FAQ
306
231
 
@@ -310,8 +235,11 @@ agent-tools/
310
235
  PromptScript agent does not support global installation. It does not affect
311
236
  other agents and can be ignored. See [`skills` issue #1352](https://github.com/vercel-labs/skills/issues/1352).
312
237
 
313
- ## References
238
+ ## Acknowledgements
314
239
 
315
- - [OpenCommit](https://github.com/di-sukharev/opencommit)
316
- - [GitLens](https://github.com/gitkraken/vscode-gitlens)
317
- - [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.
@@ -99,8 +101,9 @@ npx -y @kairyou/agent-tools@latest statusline -a claude
99
101
  # 显示项与顺序由 ~/.agent-tools/config.jsonc 的 statusline.fields 控制:
100
102
  ⎇ main | Opus 4.8 | 5h 7% ⟳2h54m | w 41% ⟳3d1h
101
103
 
102
- # 使用兼容的 API 中转时, 显示中转的额度信息, 比如:
104
+ # 使用兼容的 API 中转时, 也会显示中转额度:
103
105
  ⎇ main | Opus 4.8 | balance $362 | today $61.7 | 30d $566
106
+
104
107
  ```
105
108
 
106
109
  其中 `5h` / `w` 是 Claude 的滚动用量窗口, `⟳` 后面是重置倒计时;
@@ -108,31 +111,24 @@ npx -y @kairyou/agent-tools@latest statusline -a claude
108
111
 
109
112
  ### Provider usage
110
113
 
111
- 面向使用 API 中转的场景: agent 内直接显示中转网关的余额/额度, 按量付费或
112
- 有套餐限额时, 随时知道花了多少, 还剩多少, 不用切出去登录网关后台.
113
- 支持 Sub2API, One API (包括 OneHub 与 DoneHub), New API 与 Claude Code Hub
114
- 等中转程序提供的 API Key 用量接口, 也支持 OpenRouter 平台. 具体兼容性取决于
115
- 网关版本及其是否开放相应接口.
114
+ agent 内查看 API 中转网关的余额和额度. 支持 Sub2API, One API (包括 OneHub
115
+ DoneHub), New API, Claude Code Hub 和 OpenRouter. 具体兼容性取决于网关版本
116
+ 及其是否开放相应接口.
116
117
 
117
118
  ```bash
118
119
  npx -y @kairyou/agent-tools@latest usage -a claude codex opencode
119
120
  ```
120
121
 
121
- - **Claude Code** — `at-usage` skill 装入 `~/.claude/skills`; 调用
122
- `/at-usage` 即可在对话中显示当前用量.
123
- - **Codex** — 把 hook 添加到 `~/.codex/hooks.json` 的 `UserPromptSubmit` 和
124
- `Stop`, 并把 `at-usage` skill 装入 `~/.agents/skills`. 安装后在 Codex 里运行
125
- `/hooks` 批准一次. Codex CLI 会显示 hook 输出; 部分客户端(如 Paseo)目前不显示,
126
- 可调用 `$at-usage` 按需查询.
127
- - **OpenCode** — 添加 server plugin TUI plugin: session 进入 idle 后自动刷新
128
- usage 并以 toast 显示, `/at-usage` 查看最新缓存值. 安装或更新后需要重启 opencode.
129
-
130
- 中转端点自动发现 Codex: 读取 `~/.codex/config.toml` / `auth.json` 里当前
131
- provider 的 `base_url` 和密钥; Claude Code: 读取 `ANTHROPIC_BASE_URL` 与
132
- `ANTHROPIC_AUTH_TOKEN` / `ANTHROPIC_API_KEY`. 官方(非中转)端点会被跳过.
133
- 如果结果是 `Provider usage is unavailable.`, 可用环境变量
134
- `PROVIDER_USAGE_BASE_URL` / `PROVIDER_USAGE_API_KEY` 显式指定端点和密钥,
135
- 并在 `~/.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`:
136
132
 
137
133
  ```jsonc
138
134
  {
@@ -166,57 +162,16 @@ balance $362 | today $61.7 | 30d $566
166
162
  ```
167
163
 
168
164
  字段含义: `5h/D/W/M/T` 是 5 小时/日/周/月/总消耗与上限, `Exp` 是套餐到期日,
169
- `balance` 是钱包余额, `today` / `30d` 是今日与近 30 天 API 消耗.
165
+ `balance` 是钱包余额, `used` 是已用额度, `today` / `30d` 是今日与近 30 天 API 消耗.
170
166
 
171
167
  #### 自定义网关路由
172
168
 
173
- 内置探测覆盖不到的网关(比如 cookie 认证的中转), 可以自己写路由模块并在
174
- `providerUsage.routes` 里声明(相对 `~/.agent-tools` 解析). 声明的路由优先
175
- 探测; `"preset"` 填路由 id 可直接选中.
176
-
177
- ```jsonc
178
- {
179
- "providerUsage": {
180
- "routes": [
181
- "custom/my-gateway.mjs",
182
- "custom/another-gateway.mjs"
183
- ],
184
- "myGateway": { "username": "me", "password": "..." }
185
- }
186
- }
187
- ```
188
-
189
- ```js
190
- // ~/.agent-tools/custom/my-gateway.mjs
191
- export const meta = { id: "my-gateway" }; // 可选; id 缺省用文件名
192
-
193
- export async function run(context, { requestJson, agentConfig }) {
194
- // context: { baseUrl, key, providerName, provider, label }
195
- const { myGateway = {} } = await agentConfig(); // providerUsage 对象, 自定义键随意加
196
-
197
- // 建议: 把 token 存到文件里(如 ~/.agent-tools/cache 下)重复使用,
198
- // 用它查询失败(如 401)时才重新登录, 并把新 token 写回文件.
199
- const login = await fetch(`${context.baseUrl}/api/user/login`, {
200
- method: "POST",
201
- headers: { "content-type": "application/json" },
202
- body: JSON.stringify({ username: myGateway.username, password: myGateway.password }),
203
- });
204
- const session = await login.json();
205
-
206
- // 用 fetch 也行; 自定义 header: authorization, cookie 等.
207
- const me = await requestJson(`${context.baseUrl}/api/user/self`, {
208
- headers: { authorization: `Bearer ${session?.data?.accessToken}` },
209
- });
210
- return { text: `balance ¥${me?.data?.balance}` };
211
- }
212
- ```
213
-
214
- `text` 是自由字符串; 成功返回 `{ text }`, 抛错则回落到下一条路由
215
- (开启 `providerUsage.debug` 后, 失败会记录到 `~/.agent-tools/logs/usage-debug.log`).
169
+ 内置探测覆盖不到的网关可以通过自定义路由接入, 详见
170
+ [自定义网关路由](docs/zh-CN/custom-gateway-routes.md).
216
171
 
217
172
  ### Vision(跨模型识图)
218
173
 
219
- 让不支持图片的主模型借助多模态模型识图: 针对图片(本地路径或 http(s) URL)提出具体问题, 拿到答案后继续自己的推理. 常见场景: 读取报错截图, 按设计稿还原 UI, 定位测试反馈截图里的界面问题. 一个安装器 capability 包含三部分: `inspect_image` MCP stdio server, `at-vision` 策略 skill, 以及人工诊断 CLI.
174
+ 让不支持图片的主模型借助多模态模型识图, 适用于读取报错截图、按设计稿还原 UI、定位测试反馈截图里的界面问题.
220
175
 
221
176
  #### 安装
222
177
 
@@ -224,9 +179,7 @@ export async function run(context, { requestJson, agentConfig }) {
224
179
  npx -y @kairyou/agent-tools@latest vision -a claude codex opencode
225
180
  ```
226
181
 
227
- 卸载默认保留 vision provider 配置. 安装器会为每个 agent 注册 `inspect_image`
228
- MCP server (Claude Code: `~/.claude.json`; Codex: `~/.codex/config.toml`;
229
- OpenCode: `opencode.json`), 并把 `at-vision` skill 装入对应 agent 的 skills 目录.
182
+ 卸载时默认保留 vision provider 配置.
230
183
 
231
184
  #### 配置
232
185
 
@@ -238,20 +191,19 @@ OpenCode: `opencode.json`), 并把 `at-vision` skill 装入对应 agent 的 skil
238
191
  "provider": "openai-compatible", // 或 "anthropic-compatible"
239
192
  "baseUrl": "https://gateway.example.com/v1", // anthropic-compatible 填网关根地址, 会自动拼 /v1/messages
240
193
  "model": "internal-vlm",
241
- "apiKey": { "env": "OPENAI_API_KEY" } // 引用已有环境变量, 也可以直接填密钥
194
+ "apiKey": { "env": "OPENAI_API_KEY" } // 从环境变量 OPENAI_API_KEY 读取
242
195
  // , "timeoutMs": 30000, "maxImageBytes": 20971520, "maxOutputTokens": 8192
243
196
  // , "maxConcurrentRequests": 2, "maxRequestsPerMinute": 30
244
197
  }
245
198
  }
246
199
  ```
247
200
 
248
- `apiKey` 可直接填密钥, 或用 `{ "env": "VARIABLE_NAME" }` 引用已有环境变量; 网关不需要密钥时可省略.
249
- Provider 请求由 runtime 直接发送, API key 不进入 shell 命令; 对外错误会将 key 脱敏为 `***`. `maxConcurrentRequests` 和 `maxRequestsPerMinute` 在本机的 MCP/CLI 进程之间共享.
250
- 图片字节会无损地流式编码到 Provider 的 base64 JSON 请求中, 不做重压缩; URL 图片使用私有临时文件, 每次请求结束后自动删除.
201
+ `apiKey` 可以直接填写密钥字符串, 例如 `"apiKey": "sk-..."`; 也可以使用 `{ "env": "OPENAI_API_KEY" }` 从环境变量读取. 网关不需要密钥时可以省略. 建议优先使用环境变量, 避免把密钥写入配置文件.
251
202
 
252
203
  #### 使用
253
204
 
254
- 在消息里给出图片的文件路径或 URL 即可. Agent 优先调用 MCP 的 `inspect_image`; 模型网关不支持 MCP namespace tools 时, 改用已安装的本地 vision CLI. 不要直接粘贴截图: 主模型不支持图片时, 粘贴会在到达工具前就报 API 400 — 保存成文件再给路径.
205
+ 在消息里给出本地图片路径或 URL 即可. 主模型不支持图片时, 请先保存图片,
206
+ 再提供文件路径, 不要直接粘贴.
255
207
 
256
208
  人工排查配置或测试识别质量时可用:
257
209
 
@@ -267,25 +219,7 @@ npx -y @kairyou/agent-tools@latest inspect-image <path|url> -q "导航栏的背
267
219
  npx -y github:kairyou/agent-tools usage -a codex
268
220
  ```
269
221
 
270
- ## 仓库结构
271
-
272
- ```text
273
- agent-tools/
274
- ├── .claude-plugin/ # Claude Code/plugin 生态的 manifest.
275
- ├── .codex-plugin/ # Codex plugin manifest.
276
- ├── integrations/ # 可安装的 capability, 一个一目录.
277
- │ ├── statusline/ # Agent 状态栏: 分支, 模型, 用量.
278
- │ ├── usage/ # Provider 余额/额度显示.
279
- │ └── vision/ # 跨模型识图.
280
- ├── skills/ # 可复用的 Agent Skills.
281
- │ ├── workflow/ # 工作流类 skills.
282
- │ │ ├── at-commit/ # 生成 Conventional Commits message.
283
- │ │ ├── at-review/ # 审查改动中的 bug 与回归风险.
284
- │ │ └── at-simplify/ # 减少改动中的冗余和复杂度.
285
- │ └── integrations/ # 对接外部系统的 skills.
286
- │ └── at-zentao/ # 禅道 bug/task 修复工作流.
287
- └── scripts/ # 安装, 同步, 校验和仓库维护脚本.
288
- ```
222
+ 贡献者可参考[仓库结构](docs/zh-CN/repository-structure.md).
289
223
 
290
224
  ## FAQ
291
225
 
@@ -294,8 +228,11 @@ agent-tools/
294
228
  `PromptScript does not support global skill installation` 表示 PromptScript Agent 不支持全局
295
229
  安装, 不影响其他 Agent, 可忽略. 参见 [`skills` issue #1352](https://github.com/vercel-labs/skills/issues/1352).
296
230
 
297
- ## References
231
+ ## 参考与致谢
298
232
 
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)
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
  }