ronds_ai 0.1.13 → 0.1.17
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 +41 -21
- package/bin/ronds_ai.js +60 -8
- package/lib/code_record.js +177 -317
- package/lib/doctor.js +4 -2
- package/lib/hooks_deploy.js +604 -396
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ronds_ai
|
|
1
|
+
# ronds_ai
|
|
2
2
|
|
|
3
3
|
`ronds_ai` 是一个命令行工具,主要用于两类事情:
|
|
4
4
|
|
|
@@ -121,11 +121,12 @@ npx ronds_ai@latest record cursor
|
|
|
121
121
|
|
|
122
122
|
行为说明:
|
|
123
123
|
|
|
124
|
-
- 从 `stdin` 读取一段 JSON
|
|
125
|
-
- 根据来源提取文件路径、变更内容、增删行数、仓库信息、worker_id
|
|
126
|
-
- 组装事件后通过 HTTP POST 上报
|
|
127
|
-
- 成功时输出一行 JSON
|
|
128
|
-
- 失败时会把事件写入本地失败日志,并输出保存位置
|
|
124
|
+
- 从 `stdin` 读取一段 JSON
|
|
125
|
+
- 根据来源提取文件路径、变更内容、增删行数、仓库信息、worker_id
|
|
126
|
+
- 组装事件后通过 HTTP POST 上报
|
|
127
|
+
- Claude / Cursor 成功时输出一行 JSON
|
|
128
|
+
- Claude / Cursor 失败时会把事件写入本地失败日志,并输出保存位置
|
|
129
|
+
- Codex 作为 `PostToolUse` hook 调用时,标准输出固定为 Codex hook command output schema,避免触发 `invalid post-tool-use JSON output`
|
|
129
130
|
|
|
130
131
|
成功输出示例:
|
|
131
132
|
|
|
@@ -148,7 +149,7 @@ npx ronds_ai@latest record cursor
|
|
|
148
149
|
目前支持的 hook 事件:
|
|
149
150
|
|
|
150
151
|
- Claude: `PostToolUse`
|
|
151
|
-
- Codex: `
|
|
152
|
+
- Codex: `PostToolUse`(`apply_patch` 编辑后采集)
|
|
152
153
|
- Cursor: `afterFileEdit`
|
|
153
154
|
|
|
154
155
|
其中 Claude 仅处理这些工具产生的事件:
|
|
@@ -157,7 +158,13 @@ npx ronds_ai@latest record cursor
|
|
|
157
158
|
- `Edit`
|
|
158
159
|
- `MultiEdit`
|
|
159
160
|
|
|
160
|
-
Codex 使用 `
|
|
161
|
+
Codex 使用 `PostToolUse` hook,在 `apply_patch` 执行后直接解析本次补丁内容并生成变更事件;失败事件同样写入 `~/.ronds_ai/failed-events`。
|
|
162
|
+
|
|
163
|
+
Codex 输出示例:
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{"continue":true,"suppressOutput":true,"hookSpecificOutput":{"hookEventName":"PostToolUse"}}
|
|
167
|
+
```
|
|
161
168
|
|
|
162
169
|
### `doctor`
|
|
163
170
|
|
|
@@ -196,7 +203,8 @@ Claude 会检查:
|
|
|
196
203
|
|
|
197
204
|
Codex 会检查:
|
|
198
205
|
|
|
199
|
-
-
|
|
206
|
+
- Windows: `C:\ProgramData\OpenAI\Codex\requirements.toml`
|
|
207
|
+
- Linux / macOS: `/etc/codex/requirements.toml`
|
|
200
208
|
|
|
201
209
|
Cursor 会检查:
|
|
202
210
|
|
|
@@ -204,33 +212,44 @@ Cursor 会检查:
|
|
|
204
212
|
|
|
205
213
|
### `hooks deploy`
|
|
206
214
|
|
|
207
|
-
|
|
215
|
+
在当前项目目录或用户目录生成/更新 Claude / Codex / Cursor 的 hook 配置。
|
|
208
216
|
|
|
209
217
|
```bash
|
|
210
|
-
ronds_ai hooks deploy
|
|
218
|
+
ronds_ai hooks deploy [--scope project|user]
|
|
211
219
|
```
|
|
212
220
|
|
|
213
221
|
示例:
|
|
214
222
|
|
|
215
223
|
```bash
|
|
216
224
|
npx ronds_ai@latest hooks deploy
|
|
225
|
+
npx ronds_ai@latest hooks deploy --scope user
|
|
217
226
|
```
|
|
218
227
|
|
|
219
|
-
|
|
228
|
+
默认 scope 为 `project`(项目级部署),行为:
|
|
220
229
|
|
|
221
|
-
-
|
|
222
|
-
-
|
|
223
|
-
-
|
|
224
|
-
-
|
|
225
|
-
- 清理旧版 hook 脚本文件
|
|
226
|
-
- 如果存在 `.claude/settings.local.json`,会移除其中由本工具管理的旧 hook,避免重复触发
|
|
227
|
-
- 所有工具的失败事件统一写入 `~/.ronds_ai/failed-events`
|
|
230
|
+
- 写入或更新 `.cursor/hooks.json`
|
|
231
|
+
- 写入或更新 `.claude/settings.json`
|
|
232
|
+
- 清理项目内旧版 Cursor、Claude、Codex hook 脚本
|
|
233
|
+
- 跳过 Codex 项目级配置部署,并在输出中说明原因
|
|
228
234
|
|
|
229
|
-
|
|
235
|
+
`--scope user`(用户级部署),行为:
|
|
230
236
|
|
|
237
|
+
- 写入或更新用户级 Cursor hook 配置
|
|
238
|
+
- 写入或更新用户级 Claude hook 配置
|
|
239
|
+
- 写入或更新系统级 `requirements.toml`(Windows: `C:\ProgramData\OpenAI\Codex\requirements.toml`,Linux / macOS: `/etc/codex/requirements.toml`),包含 `[features] hooks = true`、`[hooks]` 托管目录配置以及 `PostToolUse` 的 `apply_patch` hook
|
|
240
|
+
- 清理用户目录中的旧版 hook 脚本文件
|
|
241
|
+
|
|
242
|
+
Codex 推荐使用 `--scope user`,因为项目级 `.codex` 配置在未被用户显式信任的项目中会被 Codex 忽略。
|
|
243
|
+
|
|
244
|
+
输出是一个 JSON,包含:
|
|
245
|
+
|
|
246
|
+
- `scope`: 本次部署的 scope
|
|
247
|
+
- `targetDir`: 命令执行时的项目目录
|
|
248
|
+
- `configRoot`: 实际写入配置的根目录
|
|
231
249
|
- `createdFiles`
|
|
232
250
|
- `updatedFiles`
|
|
233
251
|
- `removedFiles`
|
|
252
|
+
- `skipped`: 被跳过的工具及原因(仅在 project scope 下出现)
|
|
234
253
|
|
|
235
254
|
### `skills install`
|
|
236
255
|
|
|
@@ -284,7 +303,7 @@ npx ronds_ai@latest skills install demo-skill --tool codex,cursor --scope projec
|
|
|
284
303
|
- `HOOK_REPORT_TIMEOUT_MS`: 请求超时时间,默认 `10000`
|
|
285
304
|
- `HOOK_REPORT_TOKEN`: 如果设置,会以 `Authorization: Bearer <token>` 发送
|
|
286
305
|
- `HOOK_REPORT_HEADERS`: 额外请求头,要求是 JSON 字符串
|
|
287
|
-
- `HOOK_REQUEST_DRY_RUN=1`:
|
|
306
|
+
- `HOOK_REQUEST_DRY_RUN=1`: 不发请求。Claude / Cursor 会把事件打印到标准输出;Codex 仍输出合法的 PostToolUse hook command output schema
|
|
288
307
|
|
|
289
308
|
默认上报地址:
|
|
290
309
|
|
|
@@ -322,3 +341,4 @@ https://aihub.ronds.com/api/api/v1/ai-code-events
|
|
|
322
341
|
- `record` 和 `doctor` 目前支持 `claude`、`codex` 与 `cursor`
|
|
323
342
|
- `skills install` 支持 `claude`、`codex`、`cursor`
|
|
324
343
|
- 不支持的命令或参数会直接报错,并把错误写入 CLI 错误日志
|
|
344
|
+
|
package/bin/ronds_ai.js
CHANGED
|
@@ -65,7 +65,7 @@ function printUsage() {
|
|
|
65
65
|
' ronds_ai record <tool>',
|
|
66
66
|
' ronds_ai check record',
|
|
67
67
|
' ronds_ai doctor <tool>',
|
|
68
|
-
' ronds_ai hooks deploy',
|
|
68
|
+
' ronds_ai hooks deploy [--scope project|user] [--tool cursor|claude|codex]',
|
|
69
69
|
' ronds_ai skills install <name> [--tool claude,codex,cursor] [--scope project|global] [--project-dir <path>] [--force]',
|
|
70
70
|
'',
|
|
71
71
|
'Supported tools:',
|
|
@@ -80,6 +80,9 @@ function printUsage() {
|
|
|
80
80
|
' npx ronds_ai@latest doctor claude',
|
|
81
81
|
' npx ronds_ai@latest doctor cursor',
|
|
82
82
|
' npx ronds_ai@latest hooks deploy',
|
|
83
|
+
' npx ronds_ai@latest hooks deploy --scope user',
|
|
84
|
+
' npx ronds_ai@latest hooks deploy --tool cursor',
|
|
85
|
+
' npx ronds_ai@latest hooks deploy --tool claude --scope user',
|
|
83
86
|
' npx ronds_ai@latest skills install demo-skill',
|
|
84
87
|
' npx ronds_ai@latest skills install demo-skill --tool claude --scope global',
|
|
85
88
|
' npx ronds_ai@latest skills install demo-skill --tool codex,cursor --scope project',
|
|
@@ -88,13 +91,8 @@ function printUsage() {
|
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
async function runHooksCommand(args) {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
if (action !== 'deploy') {
|
|
94
|
-
throw new Error('Unsupported hooks command');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const result = deployHooks(process.cwd());
|
|
94
|
+
const options = parseHooksDeployArgs(args);
|
|
95
|
+
const result = deployHooks(process.cwd(), options);
|
|
98
96
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
99
97
|
}
|
|
100
98
|
|
|
@@ -186,6 +184,60 @@ function parseSkillsInstallArgs(args) {
|
|
|
186
184
|
};
|
|
187
185
|
}
|
|
188
186
|
|
|
187
|
+
function parseHooksDeployArgs(args) {
|
|
188
|
+
const [action, ...rest] = args;
|
|
189
|
+
if (action !== 'deploy') {
|
|
190
|
+
throw new Error('Unsupported hooks command');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const options = {
|
|
194
|
+
scope: 'project',
|
|
195
|
+
tool: '',
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
199
|
+
const value = rest[index];
|
|
200
|
+
|
|
201
|
+
if (value === '--scope') {
|
|
202
|
+
index += 1;
|
|
203
|
+
options.scope = rest[index] || '';
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (value.startsWith('--scope=')) {
|
|
208
|
+
options.scope = value.slice('--scope='.length);
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (value === '--tool') {
|
|
213
|
+
index += 1;
|
|
214
|
+
options.tool = rest[index] || '';
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (value.startsWith('--tool=')) {
|
|
219
|
+
options.tool = value.slice('--tool='.length);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
throw new Error(`Unsupported option: ${value}`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (!['project', 'user'].includes(options.scope)) {
|
|
227
|
+
throw new Error(`Unsupported hooks deploy scope: ${options.scope}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (options.tool) {
|
|
231
|
+
const normalizedTool = options.tool.trim().toLowerCase();
|
|
232
|
+
if (!SUPPORTED_SOURCES.has(normalizedTool)) {
|
|
233
|
+
throw new Error(`Unsupported hooks deploy tool: ${options.tool}`);
|
|
234
|
+
}
|
|
235
|
+
options.tool = normalizedTool;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return options;
|
|
239
|
+
}
|
|
240
|
+
|
|
189
241
|
async function runSkillsCommand(args) {
|
|
190
242
|
const { runSkillsInstall } = require('../lib/skills_install');
|
|
191
243
|
const [action, ...rest] = args;
|