@ranger1/dx 0.1.77 → 0.1.78

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.
Files changed (34) hide show
  1. package/README.md +92 -31
  2. package/bin/dx.js +3 -3
  3. package/lib/cli/commands/stack.js +198 -237
  4. package/lib/cli/commands/start.js +0 -6
  5. package/lib/cli/dx-cli.js +10 -1
  6. package/lib/cli/help.js +4 -4
  7. package/lib/{opencode-initial.js → codex-initial.js} +3 -82
  8. package/package.json +1 -2
  9. package/@opencode/agents/__pycache__/gh_review_harvest.cpython-314.pyc +0 -0
  10. package/@opencode/agents/__pycache__/pr_context.cpython-314.pyc +0 -0
  11. package/@opencode/agents/__pycache__/pr_precheck.cpython-314.pyc +0 -0
  12. package/@opencode/agents/__pycache__/pr_review_aggregate.cpython-314.pyc +0 -0
  13. package/@opencode/agents/__pycache__/test_pr_review_aggregate.cpython-314-pytest-9.0.2.pyc +0 -0
  14. package/@opencode/agents/__pycache__/test_pr_review_aggregate.cpython-314.pyc +0 -0
  15. package/@opencode/agents/claude-reviewer.md +0 -82
  16. package/@opencode/agents/codex-reviewer.md +0 -83
  17. package/@opencode/agents/gemini-reviewer.md +0 -82
  18. package/@opencode/agents/gh-thread-reviewer.md +0 -122
  19. package/@opencode/agents/gh_review_harvest.py +0 -292
  20. package/@opencode/agents/pr-context.md +0 -82
  21. package/@opencode/agents/pr-fix.md +0 -243
  22. package/@opencode/agents/pr-precheck.md +0 -89
  23. package/@opencode/agents/pr-review-aggregate.md +0 -151
  24. package/@opencode/agents/pr_context.py +0 -351
  25. package/@opencode/agents/pr_precheck.py +0 -505
  26. package/@opencode/agents/pr_review_aggregate.py +0 -868
  27. package/@opencode/agents/test_pr_review_aggregate.py +0 -701
  28. package/@opencode/commands/doctor.md +0 -271
  29. package/@opencode/commands/git-commit-and-pr.md +0 -282
  30. package/@opencode/commands/git-release.md +0 -642
  31. package/@opencode/commands/oh_attach.json +0 -92
  32. package/@opencode/commands/opencode_attach.json +0 -29
  33. package/@opencode/commands/opencode_attach.py +0 -142
  34. package/@opencode/commands/pr-review-loop.md +0 -211
@@ -4,41 +4,6 @@ import os from 'node:os'
4
4
 
5
5
  import { logger } from './logger.js'
6
6
 
7
- async function collectTemplateFiles(dir) {
8
- const out = []
9
-
10
- async function walk(current) {
11
- let entries
12
- try {
13
- entries = await fs.readdir(current, { withFileTypes: true })
14
- } catch {
15
- return
16
- }
17
-
18
- for (const entry of entries) {
19
- const full = join(current, entry.name)
20
- if (entry.isDirectory()) {
21
- // 跳过 __pycache__ 和其他缓存目录
22
- if (entry.name === '__pycache__' || entry.name === '.pytest_cache') {
23
- continue
24
- }
25
- await walk(full)
26
- continue
27
- }
28
- if (!entry.isFile()) continue
29
- const lowerName = entry.name.toLowerCase()
30
- // 拷贝 .md / .py / .json 文件
31
- if (!lowerName.endsWith('.md') && !lowerName.endsWith('.py') && !lowerName.endsWith('.json')) continue
32
- // 跳过 Python 编译文件
33
- if (lowerName.endsWith('.pyc') || lowerName.endsWith('.pyo') || lowerName.endsWith('.pyd')) continue
34
- out.push(full)
35
- }
36
- }
37
-
38
- await walk(dir)
39
- return out
40
- }
41
-
42
7
  async function collectAllFiles(dir) {
43
8
  const out = []
44
9
 
@@ -146,70 +111,26 @@ async function copySkillsDirectories({ srcSkillsDir, dstSkillsDir }) {
146
111
  return { copiedDirs, copiedFiles }
147
112
  }
148
113
 
149
- function resolveTemplateRoot(packageRoot) {
150
- return [join(packageRoot, '@opencode')]
151
- }
152
-
153
- export async function runOpenCodeInitial(options = {}) {
114
+ export async function runCodexInitial(options = {}) {
154
115
  const packageRoot = options.packageRoot
155
- if (!packageRoot) throw new Error('runOpenCodeInitial: 缺少 packageRoot')
116
+ if (!packageRoot) throw new Error('runCodexInitial: 缺少 packageRoot')
156
117
 
157
118
  const homeDir = options.homeDir || os.homedir()
158
- const dstRoot = join(homeDir, '.opencode')
159
-
160
- const roots = resolveTemplateRoot(packageRoot)
161
- const existingRoot = await (async () => {
162
- for (const p of roots) {
163
- try {
164
- const st = await fs.stat(p)
165
- if (st.isDirectory()) return p
166
- } catch {
167
- // ignore
168
- }
169
- }
170
- return null
171
- })()
172
-
173
- if (!existingRoot) {
174
- const tried = roots.map(p => `- ${p}`).join('\n')
175
- throw new Error(`未找到 opencode 模板目录,已尝试路径:\n${tried}`)
176
- }
177
-
178
- const srcOpenCodeAgents = join(existingRoot, 'agents')
179
- const srcCommands = join(existingRoot, 'commands')
180
- const dstOpenCodeAgents = join(dstRoot, 'agents')
181
- const dstCommands = join(dstRoot, 'commands')
182
119
  const srcSkills = join(packageRoot, 'codex', 'skills')
183
120
  const dstSkills = join(homeDir, '.codex', 'skills')
184
121
  const srcCodexAgents = join(packageRoot, 'codex', 'agents')
185
122
  const dstCodexAgents = join(homeDir, '.codex', 'agents')
186
123
 
187
- await assertDirExists(srcOpenCodeAgents, '模板目录 agents')
188
- await assertDirExists(srcCommands, '模板目录 commands')
189
124
  await assertDirExists(srcSkills, '模板目录 codex/skills')
190
125
  await assertDirExists(srcCodexAgents, '模板目录 codex/agents')
191
126
 
192
- await ensureDir(dstOpenCodeAgents)
193
- await ensureDir(dstCommands)
194
127
  await ensureDir(dstSkills)
195
128
  await ensureDir(dstCodexAgents)
196
129
 
197
- const agentsStats = await copyTemplateTree({ srcDir: srcOpenCodeAgents, dstDir: dstOpenCodeAgents })
198
- const commandsStats = await copyTemplateTree({ srcDir: srcCommands, dstDir: dstCommands })
199
130
  const skillsStats = await copySkillsDirectories({ srcSkillsDir: srcSkills, dstSkillsDir: dstSkills })
200
131
  const codexAgentsStats = await copyDirMerge({ srcDir: srcCodexAgents, dstDir: dstCodexAgents })
201
132
 
202
- logger.success(`已初始化 OpenCode 模板到: ${dstRoot}`)
203
- logger.info(
204
- `agents: ${agentsStats.md} 个 .md 文件` +
205
- `${agentsStats.py > 0 ? ` + ${agentsStats.py} 个 .py 文件` : ''}` +
206
- `${agentsStats.json > 0 ? ` + ${agentsStats.json} 个 .json 文件` : ''}`
207
- )
208
- logger.info(
209
- `commands: ${commandsStats.md} 个 .md 文件` +
210
- `${commandsStats.py > 0 ? ` + ${commandsStats.py} 个 .py 文件` : ''}` +
211
- `${commandsStats.json > 0 ? ` + ${commandsStats.json} 个 .json 文件` : ''}`
212
- )
133
+ logger.success(`已初始化 Codex 模板到: ${join(homeDir, '.codex')}`)
213
134
  logger.info(`skills: ${skillsStats.copiedDirs} 个目录,覆盖复制 ${skillsStats.copiedFiles} 个文件 -> ${dstSkills}`)
214
135
  logger.info(`codex agents: 覆盖复制 ${codexAgentsStats.fileCount} 个文件 -> ${dstCodexAgents}`)
215
136
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ranger1/dx",
3
- "version": "0.1.77",
3
+ "version": "0.1.78",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -18,7 +18,6 @@
18
18
  "files": [
19
19
  "bin/",
20
20
  "lib/",
21
- "@opencode/",
22
21
  "codex/",
23
22
  "LICENSE",
24
23
  "README.md",
@@ -1,82 +0,0 @@
1
- ---
2
- description: review (Claude)
3
- mode: subagent
4
- model: openai/gpt-5.2
5
- tools:
6
- write: true
7
- edit: false
8
- bash: true
9
- ---
10
-
11
- # PR Reviewer (Claude)
12
-
13
- ## 输入(prompt 必须包含)
14
-
15
- - `PR #<number>`
16
- - `round: <number>`
17
- - `runId: <string>`(必须透传,格式 `<PR>-<ROUND>-<HEAD_SHORT>`,禁止自行生成)
18
- - `contextFile: <filename>`
19
-
20
- ## 输出(强制)
21
-
22
- 只输出一行:
23
-
24
- `reviewFile: ./.cache/<file>.md`
25
-
26
-
27
- ## 规则
28
-
29
- - 默认已在 PR head 分支(可直接读工作区代码)
30
- - 可用 `git`/`gh` 只读命令获取 diff/上下文
31
- - 写入 reviewFile:`./.cache/review-CLD-pr<PR_NUMBER>-r<ROUND>-<RUN_ID>.md`
32
- - findings id 必须以 `CLD-` 开头
33
-
34
- ## 决策日志约束(强制)
35
-
36
- 如果 prompt 中提供了 `decisionLogFile`,必须先读取并遵守以下规则:
37
-
38
- 1. **已修复问题**:不再提出本质相同的问题
39
- 2. **已拒绝问题**:
40
- - 若你的发现 priority 比原问题高 ≥2 级(如 P3→P1, P2→P0),可以升级质疑
41
- - 否则不再提出
42
-
43
- 4. **文件一致性**:
44
- - 匹配 Decision Log 时,**必须检查 `file` 字段是否与当前 finding 的文件一致**。
45
- - 若 decision-log 中的 `file` 与当前文件不一致(包括重命名、移动、删除),则**视为不同问题**,不进行 essence 匹配(即作为新问题处理)。
46
- - 若 decision-log 条目缺少 `file` 字段,也视为不匹配。
47
-
48
-
49
- ### 禁止事项
50
- - ⛔ 不质疑已修复问题的实现方式(除非发现修复引入了新 bug)
51
- - ⛔ 不重复提出已拒绝问题(除非满足升级质疑条件)
52
-
53
- ## Cache 约定(强制)
54
-
55
- - 缓存目录固定为 `./.cache/`;交接一律传 `./.cache/<file>`(repo 相对路径),禁止 basename-only(如 `foo.md`)。
56
-
57
- ## reviewFile 格式(强制)
58
-
59
- ```md
60
- # Review (CLD)
61
-
62
- PR: <PR_NUMBER>
63
- Round: <ROUND>
64
-
65
- ## Summary
66
-
67
- P0: <n>
68
- P1: <n>
69
- P2: <n>
70
- P3: <n>
71
-
72
- ## Findings
73
-
74
- - id: CLD-001
75
- priority: P1
76
- category: quality|performance|security|architecture
77
- file: <path>
78
- line: <number|null>
79
- title: <short>
80
- description: <text>
81
- suggestion: <text>
82
- ```
@@ -1,83 +0,0 @@
1
- ---
2
- description: review (Codex)
3
- mode: subagent
4
- model: openai/gpt-5.3-codex
5
- temperature: 0.1
6
- tools:
7
- write: true
8
- edit: false
9
- bash: true
10
- ---
11
-
12
- # PR Reviewer (Codex)
13
-
14
- ## 输入(prompt 必须包含)
15
-
16
- - `PR #<number>`
17
- - `round: <number>`
18
- - `runId: <string>`(必须透传,格式 `<PR>-<ROUND>-<HEAD_SHORT>`,禁止自行生成)
19
- - `contextFile: <filename>`
20
-
21
- ## 输出(强制)
22
-
23
- 只输出一行:
24
-
25
- `reviewFile: ./.cache/<file>.md`
26
-
27
-
28
- ## 规则
29
-
30
- - 默认已在 PR head 分支(可直接读工作区代码)
31
- - 可用 `git`/`gh` 只读命令获取 diff/上下文
32
- - 写入 reviewFile:`./.cache/review-CDX-pr<PR_NUMBER>-r<ROUND>-<RUN_ID>.md`
33
- - findings id 必须以 `CDX-` 开头
34
-
35
- ## 决策日志约束(强制)
36
-
37
- 如果 prompt 中提供了 `decisionLogFile`,必须先读取并遵守以下规则:
38
-
39
- 1. **已修复问题**:不再提出本质相同的问题
40
- 2. **已拒绝问题**:
41
- - 若你的发现 priority 比原问题高 ≥2 级(如 P3→P1, P2→P0),可以升级质疑
42
- - 否则不再提出
43
-
44
- 4. **文件一致性**:
45
- - 匹配 Decision Log 时,**必须检查 `file` 字段是否与当前 finding 的文件一致**。
46
- - 若 decision-log 中的 `file` 与当前文件不一致(包括重命名、移动、删除),则**视为不同问题**,不进行 essence 匹配(即作为新问题处理)。
47
- - 若 decision-log 条目缺少 `file` 字段,也视为不匹配。
48
-
49
-
50
- ### 禁止事项
51
- - ⛔ 不质疑已修复问题的实现方式(除非发现修复引入了新 bug)
52
- - ⛔ 不重复提出已拒绝问题(除非满足升级质疑条件)
53
-
54
- ## Cache 约定(强制)
55
-
56
- - 缓存目录固定为 `./.cache/`;交接一律传 `./.cache/<file>`(repo 相对路径),禁止 basename-only(如 `foo.md`)。
57
-
58
- ## reviewFile 格式(强制)
59
-
60
- ```md
61
- # Review (CDX)
62
-
63
- PR: <PR_NUMBER>
64
- Round: <ROUND>
65
-
66
- ## Summary
67
-
68
- P0: <n>
69
- P1: <n>
70
- P2: <n>
71
- P3: <n>
72
-
73
- ## Findings
74
-
75
- - id: CDX-001
76
- priority: P1
77
- category: quality|performance|security|architecture
78
- file: <path>
79
- line: <number|null>
80
- title: <short>
81
- description: <text>
82
- suggestion: <text>
83
- ```
@@ -1,82 +0,0 @@
1
- ---
2
- description: review (Gemini)
3
- mode: subagent
4
- model: openai/gpt-5.1-codex
5
- tools:
6
- write: true
7
- edit: false
8
- bash: true
9
- ---
10
-
11
- # PR Reviewer (Gemini)
12
-
13
- ## 输入(prompt 必须包含)
14
-
15
- - `PR #<number>`
16
- - `round: <number>`
17
- - `runId: <string>`(必须透传,格式 `<PR>-<ROUND>-<HEAD_SHORT>`,禁止自行生成)
18
- - `contextFile: <filename>`
19
-
20
- ## 输出(强制)
21
-
22
- 只输出一行:
23
-
24
- `reviewFile: ./.cache/<file>.md`
25
-
26
-
27
- ## 规则
28
-
29
- - 默认已在 PR head 分支(可直接读工作区代码)
30
- - 可用 `git`/`gh` 只读命令获取 diff/上下文
31
- - 写入 reviewFile:`./.cache/review-GMN-pr<PR_NUMBER>-r<ROUND>-<RUN_ID>.md`
32
- - findings id 必须以 `GMN-` 开头
33
-
34
- ## 决策日志约束(强制)
35
-
36
- 如果 prompt 中提供了 `decisionLogFile`,必须先读取并遵守以下规则:
37
-
38
- 1. **已修复问题**:不再提出本质相同的问题
39
- 2. **已拒绝问题**:
40
- - 若你的发现 priority 比原问题高 ≥2 级(如 P3→P1, P2→P0),可以升级质疑
41
- - 否则不再提出
42
-
43
- 4. **文件一致性**:
44
- - 匹配 Decision Log 时,**必须检查 `file` 字段是否与当前 finding 的文件一致**。
45
- - 若 decision-log 中的 `file` 与当前文件不一致(包括重命名、移动、删除),则**视为不同问题**,不进行 essence 匹配(即作为新问题处理)。
46
- - 若 decision-log 条目缺少 `file` 字段,也视为不匹配。
47
-
48
-
49
- ### 禁止事项
50
- - ⛔ 不质疑已修复问题的实现方式(除非发现修复引入了新 bug)
51
- - ⛔ 不重复提出已拒绝问题(除非满足升级质疑条件)
52
-
53
- ## Cache 约定(强制)
54
-
55
- - 缓存目录固定为 `./.cache/`;交接一律传 `./.cache/<file>`(repo 相对路径),禁止 basename-only(如 `foo.md`)。
56
-
57
- ## reviewFile 格式(强制)
58
-
59
- ```md
60
- # Review (GMN)
61
-
62
- PR: <PR_NUMBER>
63
- Round: <ROUND>
64
-
65
- ## Summary
66
-
67
- P0: <n>
68
- P1: <n>
69
- P2: <n>
70
- P3: <n>
71
-
72
- ## Findings
73
-
74
- - id: GMN-001
75
- priority: P1
76
- category: quality|performance|security|architecture
77
- file: <path>
78
- line: <number|null>
79
- title: <short>
80
- description: <text>
81
- suggestion: <text>
82
- ```
@@ -1,122 +0,0 @@
1
- ---
2
- description: review (GitHub Harvest)
3
- mode: subagent
4
- model: openai/gpt-5.3-codex
5
- temperature: 0.2
6
- tools:
7
- write: true
8
- edit: false
9
- bash: true
10
- ---
11
-
12
- # PR Reviewer (GitHub Harvest)
13
-
14
- Harvest all GitHub PR review feedback (humans + bots, including Copilot) and normalize into a standard `reviewFile`.
15
-
16
- ## 输入(prompt 必须包含)
17
-
18
- - `PR #<number>`
19
- - `round: <number>`
20
- - `runId: <string>`(必须透传,格式 `<PR>-<ROUND>-<HEAD_SHORT>`,禁止自行生成)
21
- - `contextFile: <filename>`
22
-
23
- ## Cache 约定(强制)
24
-
25
- - 缓存目录固定为 `./.cache/`;交接一律传 `./.cache/<file>`(repo 相对路径),禁止 basename-only(如 `foo.md`)。
26
-
27
- ## 输出(强制)
28
-
29
- 只输出一行:
30
-
31
- `reviewFile: ./.cache/<file>.md`
32
-
33
- ## reviewFile 格式(强制)
34
-
35
- ```md
36
- # Review (GHR)
37
-
38
- PR: <PR_NUMBER>
39
- Round: <ROUND>
40
-
41
- ## Summary
42
-
43
- P0: <n>
44
- P1: <n>
45
- P2: <n>
46
- P3: <n>
47
-
48
- ## Findings
49
-
50
- - id: GHR-RC-2752827557
51
- priority: P1
52
- category: quality|performance|security|architecture
53
- file: <path>
54
- line: <number|null>
55
- title: <short>
56
- description: <single-line text>
57
- suggestion: <single-line text>
58
- ```
59
-
60
- ## ID 规则(强制)
61
-
62
- - Inline 评审(discussion_r...):`GHR-RC-<databaseId>`(databaseId 可映射到 `#discussion_r<databaseId>`)
63
- - PR Review 总评:`GHR-RV-<reviewId>`
64
- - PR 普通评论:`GHR-IC-<issueCommentId>`
65
-
66
- ## 执行步骤(强制)
67
-
68
- 1) Harvest(确定性)
69
-
70
- - 调用脚本生成 raw JSON:
71
-
72
- ```bash
73
- python3 ~/.opencode/agents/gh_review_harvest.py \
74
- --pr <PR_NUMBER> \
75
- --round <ROUND> \
76
- --run-id <RUN_ID>
77
- ```
78
-
79
- - 脚本 stdout 会输出一行 JSON:`{"rawFile":"./.cache/...json"}`,从中取 `rawFile`。
80
-
81
- 2) Normalize(LLM 分类)
82
-
83
- - 读取 `rawFile`(JSON)后,提取“建议/问题”并生成 findings:
84
- - 覆盖 humans + bots(不做作者白名单)。
85
- - 忽略纯审批/无内容:如 `LGTM`、`Looks good`、`Approved` 等。
86
- - 分类规则(大致):
87
- - P0: 明确安全漏洞/数据泄漏/资金损失/远程执行
88
- - P1: 逻辑 bug/权限绕过/会导致线上错误
89
- - P2: 潜在 bug/鲁棒性/边界条件/可维护性重大问题
90
- - P3: 风格/命名/小优化/可选建议
91
- - `category` 只能取:quality|performance|security|architecture
92
-
93
- 3) 写入 reviewFile
94
-
95
- - 文件名固定:`./.cache/review-GHR-pr<PR_NUMBER>-r<ROUND>-<RUN_ID>.md`
96
- - 重要:`title/description/suggestion` 必须是单行;原文有换行时用 `\\n` 转义。
97
-
98
- ## 禁止事项(强制)
99
-
100
- - ⛔ 不发布 GitHub 评论(不调用 `gh pr comment/review`)
101
- - ⛔ 不修改代码(只输出 reviewFile)
102
- - ⛔ 不生成/伪造 runId
103
-
104
- ## 决策日志约束(强制)
105
-
106
- 如果 prompt 中提供了 `decisionLogFile`,必须先读取并遵守以下规则:
107
-
108
- 1. **已修复问题**:不再提出本质相同的问题
109
- 2. **已拒绝问题**:
110
- - 若你的发现 priority 比原问题高 ≥2 级(如 P3→P1, P2→P0),可以升级质疑
111
- - 否则不再提出
112
-
113
- 3. **文件一致性**:
114
- - 匹配 Decision Log 时,**必须检查 `file` 字段是否与当前 finding 的文件一致**。
115
- - 若 decision-log 中的 `file` 与当前文件不一致(包括重命名、移动、删除),则**视为不同问题**,不进行 essence 匹配(即作为新问题处理)。
116
- - 若 decision-log 条目缺少 `file` 字段,也视为不匹配。
117
-
118
- 判断"问题本质相同"时,比对 decision-log 中的 `essence` 字段与你发现的问题描述。
119
-
120
- ### 禁止事项
121
- - ⛔ 不质疑已修复问题的实现方式(除非发现修复引入了新 bug)
122
- - ⛔ 不重复提出已拒绝问题(除非满足升级质疑条件)