From e7f46097fb896d8ba02f3b095f8e935dd4b8c5a8 Mon Sep 17 00:00:00 2001 From: AirLongDian Date: Thu, 11 Jun 2026 14:42:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=AE=9E=E9=99=85?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E4=B8=AD=E5=8F=91=E7=8E=B0=E7=9A=84=204=20?= =?UTF-8?q?=E4=B8=AA=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - todo_parser: 支持无方括号的短 ID 提取(G-001/H-000 格式) 原来只认 [T-xxx] 方括号格式,非方括号行退化为全文当 ID - arc_mode: parallel_review_mode 保留 arcPhase 字段 原来写 state 时覆盖为 {enabled, updatedAt, projectRoot},丢失 phase - airplan.py: 新增 --task-text CLI 参数 原来 argparse 缺此参数,do 模式无法接收任务描述 - do_mode.main: 透传 task_text 给 enter_worker 原来调 enter_worker(project_root, tid) 缺第三个参数 P1-20 is_ui_task() 永远收到空字符串 Co-Authored-By: Claude Opus 4.7 --- lib/air_runtime/modes/arc_mode.py | 7 +++++-- lib/air_runtime/modes/do_mode.py | 3 ++- lib/air_runtime/todo_parser.py | 8 ++++++-- scripts/airplan.py | 2 ++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/air_runtime/modes/arc_mode.py b/lib/air_runtime/modes/arc_mode.py index 0651334..c926249 100644 --- a/lib/air_runtime/modes/arc_mode.py +++ b/lib/air_runtime/modes/arc_mode.py @@ -249,8 +249,11 @@ def parallel_review_mode(project_root: Path, todo_path: Path) -> dict: markdown_lines.append(f"- `{g.name}`: {', '.join(g.task_ids)} — {g.reason}") paths["execution_plan_md"].write_text("\n".join(markdown_lines) + "\n", encoding="utf-8") - atomic_json_write(paths["state"], {"enabled": True, "updatedAt": now_iso(), - "projectRoot": str(project_root)}) + # 保留 arcPhase 字段,避免 phase 被 reset 为 discussing + existing_state = safe_json_load(paths["state"]) or {} + state_payload = {**existing_state, "enabled": True, "updatedAt": now_iso(), + "projectRoot": str(project_root)} + atomic_json_write(paths["state"], state_payload) return {"json_path": str(review_json_path), "markdown_path": str(review_md_path), "execution_plan_json_path": str(paths["execution_plan_json"]), "parallel_group_count": len(review.parallel_groups), diff --git a/lib/air_runtime/modes/do_mode.py b/lib/air_runtime/modes/do_mode.py index 9bc7d7d..7aed2a8 100644 --- a/lib/air_runtime/modes/do_mode.py +++ b/lib/air_runtime/modes/do_mode.py @@ -244,7 +244,8 @@ def main(args) -> None: print(f"active_task_id={s['activeTaskId']}") print(f"known_tasks={','.join(s['taskIds'])}") elif sub == "enter": - result = enter_worker(project_root, tid) + task_text = getattr(args, "task_text", "") or "" + result = enter_worker(project_root, tid, task_text=task_text) print("airplan_mode=do") print(f"task_id={result['taskId']}") print(f"brief_path={result['briefPath']}") diff --git a/lib/air_runtime/todo_parser.py b/lib/air_runtime/todo_parser.py index c04c1ec..f70b4b5 100644 --- a/lib/air_runtime/todo_parser.py +++ b/lib/air_runtime/todo_parser.py @@ -69,9 +69,13 @@ def parse_tasks(todo_path: Path) -> list[TodoTask]: continue task_cell = cells[col_map.get("task", 0)] if col_map.get("task", 0) < len(cells) else "" - # 提取 [T-xxx] 格式的任务 ID + # 优先提取 [T-xxx] 方括号格式的 ID;若没有则尝试从开头提取 G-001/H-000 类短 ID tid_match = re.match(r"\[([A-Za-z0-9_\-\.]+)\]", task_cell) - task_id = tid_match.group(1) if tid_match else task_cell + if tid_match: + task_id = tid_match.group(1) + else: + short_match = re.match(r"^([A-Z]+-\d+[a-z]*)", task_cell) + task_id = short_match.group(1) if short_match else task_cell task = task_cell status = cells[col_map.get("status", 1)] if col_map.get("status", 1) < len(cells) else "TODO" files_dirs = cells[col_map.get("files_dirs", 2)] if col_map.get("files_dirs", 2) < len(cells) else "" diff --git a/scripts/airplan.py b/scripts/airplan.py index 91c0447..c09b8f5 100644 --- a/scripts/airplan.py +++ b/scripts/airplan.py @@ -170,6 +170,8 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace: help="截图后端偏好(xdb 使用): kms|xvfb|fallback|auto") parser.add_argument("--output", default="", help="截图输出文件名(xdb 使用,默认 screenshot.png)") + parser.add_argument("--task-text", default="", + help="任务描述文本(do 使用,用于 UI 任务检测和路由)") return parser.parse_args(argv)