@ranger1/dx 0.1.42 → 0.1.44

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.
@@ -116,9 +116,37 @@ def _git_fetch_origin(ref):
116
116
  subprocess.run(["git", "fetch", "origin", ref], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
117
117
 
118
118
 
119
- def _git_numstat(base_ref):
120
- # Prefer origin/<base>...HEAD; fallback to <base>...HEAD.
121
- for lhs in (f"origin/{base_ref}...HEAD", f"{base_ref}...HEAD"):
119
+ def _gh_default_branch(owner_repo):
120
+ if not owner_repo:
121
+ return ""
122
+ rc, out, _ = _run_capture(
123
+ [
124
+ "gh",
125
+ "repo",
126
+ "view",
127
+ "--repo",
128
+ owner_repo,
129
+ "--json",
130
+ "defaultBranchRef",
131
+ "--jq",
132
+ ".defaultBranchRef.name",
133
+ ]
134
+ )
135
+ if rc != 0:
136
+ return ""
137
+ return (out or "").strip()
138
+
139
+
140
+ def _git_numstat(base_ref, base_oid):
141
+ # Prefer commit-oid diff when available; it's unambiguous for stacked PRs.
142
+ candidates = []
143
+ if base_oid:
144
+ candidates.append(f"{base_oid}...HEAD")
145
+ if base_ref:
146
+ candidates.append(f"origin/{base_ref}...HEAD")
147
+ candidates.append(f"{base_ref}...HEAD")
148
+
149
+ for lhs in candidates:
122
150
  rc, out, _ = _run_capture(["git", "diff", "--numstat", lhs])
123
151
  if rc == 0:
124
152
  return out
@@ -205,15 +233,22 @@ def main(argv):
205
233
  return 1
206
234
 
207
235
  head_oid = (pr.get("headRefOid") or "").strip()
208
- base_ref = (pr.get("baseRefName") or "").strip() or "main"
236
+ base_oid = (pr.get("baseRefOid") or "").strip()
237
+ base_ref = (pr.get("baseRefName") or "").strip()
238
+ if not base_ref:
239
+ base_ref = _gh_default_branch(owner_repo)
240
+ if not base_ref and not base_oid:
241
+ _json_out({"error": "PR_BASE_REF_NOT_FOUND"})
242
+ return 1
209
243
  head_ref = (pr.get("headRefName") or "").strip()
210
244
  url = (pr.get("url") or "").strip()
211
245
 
212
246
  seed = f"{pr_number}:{round_num}:{head_oid}".encode("utf-8")
213
247
  run_id = hashlib.sha1(seed).hexdigest()[:12]
214
248
 
215
- _git_fetch_origin(base_ref)
216
- file_rows = _parse_numstat(_git_numstat(base_ref))
249
+ if base_ref:
250
+ _git_fetch_origin(base_ref)
251
+ file_rows = _parse_numstat(_git_numstat(base_ref, base_oid))
217
252
 
218
253
  labels = []
219
254
  for l in (pr.get("labels") or []):
@@ -4,7 +4,7 @@
4
4
  # - Verify GitHub auth (gh)
5
5
  # - Read PR info (headRefName/baseRefName/mergeable)
6
6
  # - Checkout PR branch (gh pr checkout) if needed
7
- # - Fetch base branch (origin/<base>, fallback main/master)
7
+ # - Fetch base branch (origin/<base>)
8
8
  # - If mergeable == CONFLICTING: return {"error":"PR_MERGE_CONFLICTS_UNRESOLVED"}
9
9
  # - Run dx cache clear
10
10
  # - Run dx lint and dx build all concurrently
@@ -227,17 +227,8 @@ def main():
227
227
  return 1
228
228
 
229
229
  if run(["git", "fetch", "origin", base]) != 0:
230
- ok = False
231
- for fallback in ("main", "master"):
232
- if fallback == base:
233
- continue
234
- if run(["git", "fetch", "origin", fallback]) == 0:
235
- base = fallback
236
- ok = True
237
- break
238
- if not ok:
239
- print(json.dumps({"error": "PR_BASE_REF_FETCH_FAILED"}))
240
- return 1
230
+ print(json.dumps({"error": "PR_BASE_REF_FETCH_FAILED", "baseRefName": base}))
231
+ return 1
241
232
 
242
233
  if mergeable == "CONFLICTING":
243
234
  print(json.dumps({"error": "PR_MERGE_CONFLICTS_UNRESOLVED"}))
@@ -6,158 +6,229 @@ agent: build
6
6
 
7
7
  ---
8
8
 
9
- ## Step 0: 强制安装 dx CLI
9
+ ## Step 0: Bootstrap(dx + 模板 + pnpm)
10
10
 
11
- **无论当前是否安装,必须执行:**
11
+ 目标:
12
12
 
13
- ```bash
14
- pnpm add -g @ranger1/dx@latest && dx initial
15
- ```
13
+ - dx 安装/升级到最新
14
+ - 刷新 `~/.opencode/commands/*`(确保 `opencode_attach.py` 可用)
16
15
 
17
- ---
16
+ ```bash
17
+ set -euo pipefail
18
18
 
19
- ## Step 1: 并行检测
19
+ # 必要前提:node + corepack(用于 pnpm)
20
+ if ! command -v node >/dev/null 2>&1; then
21
+ echo "ERROR: node NOT_FOUND (need Node.js >= 20)"
22
+ echo "macOS: brew install node"
23
+ echo "Debian/Ubuntu: curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs"
24
+ exit 1
25
+ fi
20
26
 
21
- **同时执行以下 4 Bash 调用(真正并行):**
27
+ if ! command -v pnpm >/dev/null 2>&1; then
28
+ corepack enable >/dev/null 2>&1 || true
29
+ corepack prepare pnpm@latest --activate
30
+ fi
22
31
 
23
- ```bash
24
- # 批次 1: CLI 版本检测
25
- echo "=== CLI_VERSIONS ===";
26
- echo "opencode:" && (which opencode && opencode --version 2>/dev/null || echo "NOT_FOUND");
27
- echo "dx:" && (which dx && dx --version 2>/dev/null || echo "NOT_FOUND");
28
- echo "agent-browser:" && (which agent-browser && agent-browser --version 2>/dev/null || echo "NOT_FOUND");
29
- ```
32
+ # 安装/升级 dx 到最新(幂等)
33
+ pnpm add -g @ranger1/dx@latest
30
34
 
31
- ```bash
32
- # 批次 2: 项目文件检测
33
- echo "=== PROJECT_FILES ===";
34
- echo "AGENTS.md:" && (test -f AGENTS.md && echo "FOUND" || echo "NOT_FOUND");
35
- ```
35
+ # 备份后刷新模板(避免覆盖导致不可回退)
36
+ ts="$(date +%Y%m%d%H%M%S)"
37
+ if [ -d "$HOME/.opencode/commands" ]; then
38
+ cp -a "$HOME/.opencode/commands" "$HOME/.opencode/commands.bak.${ts}" 2>/dev/null || true
39
+ fi
40
+ if [ -d "$HOME/.opencode/agents" ]; then
41
+ cp -a "$HOME/.opencode/agents" "$HOME/.opencode/agents.bak.${ts}" 2>/dev/null || true
42
+ fi
36
43
 
37
- ```bash
38
- # 批次 3: OpenCode 插件检测
39
- # 注意:插件名可能带版本号(如 @1.3.0),使用模糊匹配
40
- echo "=== OPENCODE_PLUGINS ===";
41
- echo "oh-my-opencode:" && (opencode plugin list 2>/dev/null | grep -q 'oh-my-opencode' && echo "INSTALLED" || echo "NOT_INSTALLED");
42
- echo "opencode-openai-codex-auth:" && (opencode plugin list 2>/dev/null | grep -q 'opencode-openai-codex-auth' && echo "INSTALLED" || echo "NOT_INSTALLED");
44
+ dx initial
43
45
  ```
44
46
 
45
- ```bash
46
- # 批次 4: attach 配置(统一)
47
- echo "=== OPENCODE_ATTACH ===";
48
- echo "attach:" && (python3 ~/.opencode/commands/opencode_attach.py --dry-run >/dev/null 2>&1 && echo "READY" || echo "NOT_READY");
49
- ```
47
+ ---
50
48
 
51
- ```bash
52
- # 批次 5: Python 检测(python3 + python 软链接)
53
- echo "=== PYTHON ===";
54
- echo "python3:" && (which python3 && python3 --version 2>/dev/null || echo "NOT_FOUND");
55
- echo "python:" && (which python && python --version 2>/dev/null || echo "NOT_FOUND");
56
- ```
49
+ ## Step 1: 快速检测(单次 Bash)
57
50
 
58
- ---
51
+ 目标:一次 Bash 输出完整状态表,减少 tool 调用与 token。
59
52
 
60
- ## Step 2: 输出报告
53
+ ```bash
54
+ set -euo pipefail
55
+
56
+ os="$(uname -s 2>/dev/null || echo unknown)"
57
+ pm="none"
58
+ if command -v brew >/dev/null 2>&1; then pm="brew"; fi
59
+ if command -v apt-get >/dev/null 2>&1; then pm="apt"; fi
60
+
61
+ ver() {
62
+ # usage: ver <bin> <cmd>
63
+ b="$1"; shift
64
+ if command -v "$b" >/dev/null 2>&1; then
65
+ ("$@" 2>/dev/null | head -n 1) || true
66
+ else
67
+ echo "NOT_FOUND"
68
+ fi
69
+ }
70
+
71
+ has_agents="NOT_FOUND"; [ -f AGENTS.md ] && has_agents="FOUND"
72
+
73
+ dx_v="$(ver dx dx --version)"
74
+ opencode_v="$(ver opencode opencode --version)"
75
+ rg_v="$(ver rg rg --version)"
76
+ agent_browser_v="$(ver agent-browser agent-browser --version)"
77
+ py3_v="$(ver python3 python3 --version)"
78
+ py_v="$(ver python python --version)"
79
+
80
+ attach_status="NOT_READY"
81
+ if command -v python3 >/dev/null 2>&1 && [ -f "$HOME/.opencode/commands/opencode_attach.py" ]; then
82
+ python3 "$HOME/.opencode/commands/opencode_attach.py" --dry-run >/dev/null 2>&1 && attach_status="READY" || true
83
+ fi
61
84
 
62
- 汇总结果,输出表格:
85
+ # 插件以“配置是否就绪”为准(真正安装由 opencode 启动时自动完成)
86
+ cfg_opencode="$HOME/.config/opencode/opencode.json"
87
+ plug_oh="NOT_CONFIGURED"
88
+ plug_codex="NOT_CONFIGURED"
89
+ plug_antigravity="NOT_CONFIGURED"
90
+ if [ -f "$cfg_opencode" ]; then
91
+ grep -q 'oh-my-opencode' "$cfg_opencode" && plug_oh="CONFIGURED" || true
92
+ grep -q 'opencode-openai-codex-auth' "$cfg_opencode" && plug_codex="CONFIGURED" || true
93
+ grep -q 'opencode-antigravity-auth' "$cfg_opencode" && plug_antigravity="CONFIGURED" || true
94
+ fi
63
95
 
64
- ```
65
- 工具 | 状态 | 版本
66
- opencode | <状态> | <版本>
67
- dx | <状态> | <版本>
68
- python3 | <状态> | <版本>
69
- python(软链接) | <状态> | <版本>
70
- AGENTS.md | <状态> | -
71
- oh-my-opencode 插件 | <状态> | -
72
- opencode-openai-codex-auth 插件 | <状态> | -
73
- agent-browser | <状态> | <版本>
74
- attach(全局配置写入) | <状态> | -
96
+ echo "OS: ${os} | PM: ${pm}"
97
+ echo
98
+ printf '%-34s | %-12s | %s\n' "tool" "status" "version"
99
+ printf '%-34s | %-12s | %s\n' "opencode" "$( [ "$opencode_v" = NOT_FOUND ] && echo MISSING || echo OK )" "$opencode_v"
100
+ printf '%-34s | %-12s | %s\n' "dx" "$( [ "$dx_v" = NOT_FOUND ] && echo MISSING || echo OK )" "$dx_v"
101
+ printf '%-34s | %-12s | %s\n' "rg" "$( [ "$rg_v" = NOT_FOUND ] && echo MISSING || echo OK )" "$rg_v"
102
+ printf '%-34s | %-12s | %s\n' "agent-browser" "$( [ "$agent_browser_v" = NOT_FOUND ] && echo MISSING || echo OK )" "$agent_browser_v"
103
+ printf '%-34s | %-12s | %s\n' "python3" "$( [ "$py3_v" = NOT_FOUND ] && echo MISSING || echo OK )" "$py3_v"
104
+ printf '%-34s | %-12s | %s\n' "python (softlink)" "$( [ "$py_v" = NOT_FOUND ] && echo MISSING || echo OK )" "$py_v"
105
+ printf '%-34s | %-12s | %s\n' "AGENTS.md" "$has_agents" "-"
106
+ printf '%-34s | %-12s | %s\n' "attach (global config)" "$attach_status" "-"
107
+ printf '%-34s | %-12s | %s\n' "plugin: oh-my-opencode" "$plug_oh" "-"
108
+ printf '%-34s | %-12s | %s\n' "plugin: opencode-openai-codex-auth" "$plug_codex" "-"
109
+ printf '%-34s | %-12s | %s\n' "plugin: opencode-antigravity-auth" "$plug_antigravity" "-"
110
+
111
+ missing=0
112
+ for x in "$opencode_v" "$dx_v" "$rg_v" "$agent_browser_v" "$py3_v"; do
113
+ [ "$x" = NOT_FOUND ] && missing=1
114
+ done
115
+ [ "$attach_status" != READY ] && missing=1
116
+ for x in "$plug_oh" "$plug_codex" "$plug_antigravity"; do
117
+ [ "$x" != CONFIGURED ] && missing=1
118
+ done
119
+
120
+ echo
121
+ if [ "$missing" = 0 ]; then
122
+ echo "OK: all dependencies ready"
123
+ else
124
+ echo "NEED_FIX: missing or not-ready items detected"
125
+ fi
75
126
  ```
76
127
 
77
128
  ---
78
129
 
79
- ## Step 3: 统一处理缺失项
80
-
81
- **如检测到任何缺失项,统一询问一次:**
82
-
83
- `AskUserQuestion`: 检测到以下缺失项,是否自动安装/配置所有?
130
+ ## Step 2: 只问一次(缺失/升级)
84
131
 
85
- 确认后按顺序处理:
132
+ 如果出现 `NEED_FIX`,只问一次:是否一键安装 + 升级到最新版本(包含插件配置 attach)。
86
133
 
87
- ### 3.1 opencode CLI 未安装
134
+ `AskUserQuestion`: 检测到缺失/未就绪项,是否一键修复并升级到最新版本?
88
135
 
89
- 执行安装:
136
+ 选项:
90
137
 
91
- ```bash
92
- # brew 优先
93
- brew install opencode || npm install -g opencode
94
- ```
95
-
96
- ### 3.2 AGENTS.md 未找到
97
-
98
- 提示用户:
138
+ - 一键修复(Recommended)
139
+ - 跳过(只输出检测表)
99
140
 
100
- - AGENTS.md 文件不存在,OpenCode 需要此文件作为项目指令入口
101
- - 建议创建或检查文件路径
141
+ ---
102
142
 
103
- ### 3.6 agent-browser 未安装
143
+ ## Step 3: 一键修复(安装 + 升级到最新)
104
144
 
105
- 执行安装:
145
+ 确认后直接执行以下脚本(幂等;尽量走包管理器升级;插件用 attach 配置确保可自动安装/更新):
106
146
 
107
147
  ```bash
108
- npm install -g agent-browser && agent-browser install
109
- ```
148
+ set -euo pipefail
149
+
150
+ os="$(uname -s 2>/dev/null || echo unknown)"
151
+ has_brew=0; command -v brew >/dev/null 2>&1 && has_brew=1
152
+ has_apt=0; command -v apt-get >/dev/null 2>&1 && has_apt=1
110
153
 
111
- ### 3.6.1 python3 未安装
154
+ need_sudo=0
155
+ if [ "$has_apt" = 1 ] && command -v sudo >/dev/null 2>&1; then
156
+ need_sudo=1
157
+ fi
112
158
 
113
- 执行安装:
159
+ if ! command -v pnpm >/dev/null 2>&1; then
160
+ corepack enable >/dev/null 2>&1 || true
161
+ corepack prepare pnpm@latest --activate
162
+ fi
114
163
 
115
- ```bash
116
- # macOS (Homebrew)
117
- brew install python
118
- ```
164
+ # dx(始终升级到最新)
165
+ pnpm add -g @ranger1/dx@latest
119
166
 
120
- ### 3.6.2 python 命令缺失(需要软链接到 python3)
167
+ if ! command -v dx >/dev/null 2>&1; then
168
+ echo "WARN: dx still NOT_FOUND (check PATH for pnpm global bin: pnpm bin -g)"
169
+ fi
121
170
 
122
- 如果 `python` 不存在但 `python3` 存在,执行:
171
+ # OpenCode 模板(确保 opencode_attach.py 存在)
172
+ if [ ! -f "$HOME/.opencode/commands/opencode_attach.py" ]; then
173
+ dx initial
174
+ fi
123
175
 
124
- ```bash
125
- set -e
176
+ # opencode CLI
177
+ if [ "$os" = "Darwin" ] && [ "$has_brew" = 1 ]; then
178
+ brew update >/dev/null
179
+ brew tap anomalyco/tap >/dev/null 2>&1 || true
180
+ brew install anomalyco/tap/opencode >/dev/null 2>&1 || brew upgrade opencode >/dev/null 2>&1 || true
181
+ else
182
+ # 官方支持 npm/bun/pnpm;这里统一用 pnpm
183
+ pnpm add -g opencode-ai@latest
184
+ fi
126
185
 
127
- if command -v python >/dev/null 2>&1; then
128
- python --version
129
- exit 0
186
+ if ! command -v opencode >/dev/null 2>&1; then
187
+ echo "WARN: opencode still NOT_FOUND (check PATH for pnpm global bin: pnpm bin -g)"
130
188
  fi
131
189
 
132
- PY3="$(command -v python3 2>/dev/null || true)"
133
- if [ -z "$PY3" ]; then
134
- echo "python3 NOT_FOUND"
135
- exit 1
190
+ # ripgrep
191
+ if [ "$has_brew" = 1 ]; then
192
+ brew install ripgrep >/dev/null 2>&1 || brew upgrade ripgrep >/dev/null 2>&1 || true
193
+ elif [ "$has_apt" = 1 ] && [ "$need_sudo" = 1 ]; then
194
+ sudo apt-get update -y >/dev/null
195
+ sudo apt-get install -y ripgrep
196
+ else
197
+ echo "WARN: no brew/apt-get; skip ripgrep auto-install"
136
198
  fi
137
199
 
138
- PY_DIR="$(dirname "$PY3")"
139
- if [ -w "$PY_DIR" ]; then
140
- ln -sf "$PY3" "$PY_DIR/python"
141
- echo "linked: $PY_DIR/python -> $PY3"
200
+ # python3 (+ python 软链接尽量走系统包)
201
+ if [ "$has_brew" = 1 ]; then
202
+ brew install python >/dev/null 2>&1 || brew upgrade python >/dev/null 2>&1 || true
203
+ elif [ "$has_apt" = 1 ] && [ "$need_sudo" = 1 ]; then
204
+ sudo apt-get update -y >/dev/null
205
+ sudo apt-get install -y python3 python3-venv python3-pip python-is-python3
142
206
  else
143
- ln -sf "$PY3" "$HOME/.local/bin/python"
144
- echo "linked: $HOME/.local/bin/python -> $PY3"
145
- echo "NOTE: ensure $HOME/.local/bin is in PATH"
207
+ echo "WARN: no brew/apt-get; skip python auto-install"
146
208
  fi
147
209
 
148
- python --version
149
- ```
210
+ # agent-browser(安装/升级 + 安装 Chromium)
211
+ if [ "$os" = "Darwin" ] && [ "$has_brew" = 1 ]; then
212
+ brew install agent-browser >/dev/null 2>&1 || brew upgrade agent-browser >/dev/null 2>&1 || true
213
+ else
214
+ pnpm add -g agent-browser@latest
215
+ fi
150
216
 
151
- ### 3.9 自动 attach(推荐)
217
+ if command -v agent-browser >/dev/null 2>&1; then
218
+ agent-browser install >/dev/null 2>&1 || agent-browser install --with-deps
219
+ fi
152
220
 
153
- 执行 attach(会自动覆盖/新建对应节点,其它不动,并生成备份文件):
221
+ # attach(写入 ~/.config/opencode/*.json;自动备份 .bak.*)
222
+ if command -v python3 >/dev/null 2>&1 && [ -f "$HOME/.opencode/commands/opencode_attach.py" ]; then
223
+ python3 "$HOME/.opencode/commands/opencode_attach.py"
224
+ else
225
+ echo "ERROR: python3/opencode_attach.py NOT_READY"
226
+ exit 1
227
+ fi
154
228
 
155
- ```bash
156
- python3 ~/.opencode/commands/opencode_attach.py
229
+ echo "DONE"
157
230
  ```
158
231
 
159
-
160
-
161
232
  ---
162
233
 
163
234
  ## 输出格式
@@ -175,4 +246,4 @@ python3 ~/.opencode/commands/opencode_attach.py
175
246
  ```
176
247
 
177
248
  **修复完成后:**
178
- 输出最终状态表格,确认所有项目均为
249
+ 重复执行 Step 1,输出最终状态表格,确认所有项目均为 OK/READY/CONFIGURED。
@@ -223,8 +223,10 @@ git push -u origin HEAD
223
223
  #### 4.2 分析变更
224
224
 
225
225
  ```bash
226
- git log origin/master..HEAD --oneline
227
- git diff origin/master...HEAD --stat
226
+ # 优先使用 origin/HEAD(远端默认分支),避免硬编码 main/master。
227
+ # 如需指定基准分支,使用:/git-commit-and-pr --pr --base <BRANCH>
228
+ git log origin/HEAD..HEAD --oneline
229
+ git diff origin/HEAD...HEAD --stat
228
230
  ```
229
231
 
230
232
  #### 4.3 创建 PR
@@ -7,18 +7,18 @@
7
7
  },
8
8
  "agents": {
9
9
  "sisyphus": {
10
- "model": "openai/gpt-5.2",
10
+ "model": "openai/gpt-5.3-codex",
11
11
  "variant": "none"
12
12
  },
13
13
  "oracle": {
14
- "model": "openai/gpt-5.2",
14
+ "model": "openai/gpt-5.3-codex",
15
15
  "variant": "high"
16
16
  },
17
17
  "librarian": {
18
- "model": "github-copilot/gpt-5-mini"
18
+ "model": "openai/gpt-5.1-codex-mini"
19
19
  },
20
20
  "explore": {
21
- "model": "github-copilot/gpt-5-mini"
21
+ "model": "openai/gpt-5.1-codex-mini"
22
22
  },
23
23
  "multimodal-looker": {
24
24
  "model": "github-copilot/gemini-3-flash-preview"
@@ -36,10 +36,10 @@
36
36
  "variant": "medium"
37
37
  },
38
38
  "atlas": {
39
- "model": "openai/gpt-5.2-codex"
39
+ "model": "openai/gpt-5.3-codex"
40
40
  },
41
41
  "codex-reviewer": {
42
- "model": "openai/gpt-5.2-codex",
42
+ "model": "openai/gpt-5.3-codex",
43
43
  "variant": "xhigh",
44
44
  "temperature": 0.1
45
45
  },
@@ -64,7 +64,7 @@
64
64
  "variant": "high"
65
65
  },
66
66
  "ultrabrain": {
67
- "model": "openai/gpt-5.2-codex",
67
+ "model": "openai/gpt-5.3-codex",
68
68
  "variant": "xhigh"
69
69
  },
70
70
  "artistry": {
@@ -72,7 +72,7 @@
72
72
  "variant": "max"
73
73
  },
74
74
  "quick": {
75
- "model": "github-copilot/claude-haiku-4.5"
75
+ "model": "openai/gpt-5.1-codex-mini"
76
76
  },
77
77
  "middle": {
78
78
  "model": "github-copilot/claude-sonnet-4.5"
@@ -82,7 +82,7 @@
82
82
  "variant": "medium"
83
83
  },
84
84
  "unspecified-high": {
85
- "model": "openai/gpt-5.2",
85
+ "model": "openai/gpt-5.3-codex",
86
86
  "variant": "medium"
87
87
  },
88
88
  "writing": {
@@ -10,7 +10,7 @@
10
10
  ],
11
11
  "agent": {
12
12
  "quick": {
13
- "model": "github-copilot/gpt-5-mini"
13
+ "model": "openai/gpt-5.1-codex-mini"
14
14
  },
15
15
  "middle": {
16
16
  "model": "github-copilot/claude-sonnet-4.5"
@@ -22,5 +22,5 @@
22
22
  "*.env.*": "allow"
23
23
  }
24
24
  },
25
- "model": "openai/gpt-5.2"
25
+ "model": "openai/gpt-5.3-codex"
26
26
  }
@@ -6,6 +6,12 @@ agent: sisyphus
6
6
 
7
7
  # PR Review Loop
8
8
 
9
+ ## Stacked PR / PR -> PR(重要)
10
+
11
+ - 本流程的 diff 基准来自 GitHub PR 元数据的 `baseRefName`(不是硬编码 main/master),因此天然支持“PR 合并到另一个 PR 分支”的 stacked PR。
12
+ - 当 `baseRefName` 缺失时:会回退到仓库默认分支(`defaultBranchRef.name`)。
13
+ - 当 base 分支 fetch 失败时:会直接报错终止(不再静默回退到 main/master),避免 review/changed-files 基准悄悄跑偏。
14
+
9
15
  ## 输入
10
16
 
11
17
  - `{{PR_NUMBER}}`
package/lib/worktree.js CHANGED
@@ -685,7 +685,7 @@ class WorktreeManager {
685
685
 
686
686
  // 检查未推送的提交
687
687
  const unpushed = execSync(
688
- `git log origin/${branchName}..${branchName} --oneline 2>/dev/null || git log origin/main..${branchName} --oneline`,
688
+ `git log origin/${branchName}..${branchName} --oneline 2>/dev/null || git log origin/HEAD..${branchName} --oneline`,
689
689
  ).toString()
690
690
  if (unpushed.trim()) {
691
691
  hasUnpushedCommits = true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ranger1/dx",
3
- "version": "0.1.42",
3
+ "version": "0.1.44",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {