--- name: langgraph-plan-review description: Use the LangGraph plan-review workflow from the current Claude Code session. Trigger when the user asks to create Taskxx plans, run the Claude/Codex review loop, generate or revise Notes/Taskxx.md, or use the LangGraph workflow described by Task00.md. This skill uses the current Claude Code environment for Claude steps and only invokes the Python LangGraph app for Codex review and discuss file numbering. --- # LangGraph Plan Review Workflow Use this skill to run the LangGraph plan-review workflow. All scripts are bundled under the skill's own `scripts\` directory (`C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\`) — no dependency on `E:\LangGraph_Design\lab00`. ## 运行方式:进程内驱动,无 dev server(2026-07 起) **本 skill 已去掉 `langgraph dev` 服务器**。工作流由进程内 runner **`scripts\clean_run.py`** 直接驱动: 它 `build_workflow()` 编译图、用 **SqliteSaver**(`scripts\.plan_review_state.sqlite`)做跨调用持久化、 自己处理 `interrupt`/`Command(resume=...)`。不再需要 `manage_dev_server.ps1` / `run_langgraph.ps1` / `run_workflow.py`(这些是旧的 dev-server 路径,保留仅作参考,勿再使用)。 - **入口**:用 `langgraph` conda 环境的 python 跑 `clean_run.py`: ```powershell $PY = "C:\Users\bowei\.conda\envs\langgraph\python.exe" $RUN = "C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\clean_run.py" # 首次(到 write_plan 中断): & $PY $RUN --task-id 10 --work-dir "" --notes-dir Notes --prompt "<原始请求>" # resume(写完/改完 Task10.md 后;resume 值 base64(JSON)): $resume = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('true')) & $PY $RUN --task-id 10 --work-dir "" --notes-dir Notes --resume-b64 $resume --codex-review-command-b64 $CMD --timeout 900 ``` 每次调用推进到下一个 `interrupt` 或结束,打印一行 JSON:`{"status":"waiting","action_required":{...}}` 或 `{"status":"done","has_serious_issue":...}`。`action_required` 的处理同下(write_plan / decide / revise / write_rejection),resume 值:`write_plan`/`revise`/`write_rejection` 用 `true`;`decide` 用 `{"accepts":true}` 或 `{"accepts":false,"reason":"..."}`。 - **codex 评审的两个必备条件**(本次踩坑记录): 1. **codex CLI 要足够新**。config.toml 若配了较新模型(如 `gpt-5.6-sol`),旧 codex 会返回 400 `requires a newer version of Codex`。升级:`npm i -g @openai/codex@latest`(≥0.144.5 实测可用)。 2. **codex 子进程要能到 chatgpt.com**。`clean_run.py` 会自动读 Windows 系统代理(HKCU Internet Settings 的 `ProxyServer`)设进 `HTTP(S)_PROXY`,让 codex 走代理;也可用 `PLAN_REVIEW_PROXY` 覆盖。 3. **codex 超时**:`review_task.py` 的内层 codex 超时取 argv[5](默认 300s,评审常不够)。用 `--codex-review-command-b64` 传一条**末尾带超时秒数**的命令(见 Workflow),并把 `--timeout` 设一致。 - **改了 `workflow.py`/`agents.py`/`clean_run.py` 后**:无 dev server 缓存,下次 `clean_run.py` 直接生效。 若图结构改到与旧 checkpoint 不兼容,删 `scripts\.plan_review_state.sqlite` 重新开始该 thread。 ## Pre-flight: Environment Setup Before running the workflow for the first time (or when unsure the environment is ready), verify that the required packages are installed in the `langgraph` conda env: ```powershell # Install langgraph dev server, SDK, and HTTP client conda run -n langgraph pip install "langgraph-cli[inmem]" langgraph-sdk httpx # Verify the SDK is importable conda run -n langgraph python -c "from langgraph_sdk import get_sync_client; print('SDK OK')" # Verify the langgraph dev command is available conda run -n langgraph langgraph --version ``` | Package | Purpose | |---|---| | `langgraph-cli[inmem]` | Provides the `langgraph dev` server command | | `langgraph-sdk` | Python client used by `run_workflow.py` to submit runs | | `httpx` | HTTP health-check in `run_workflow.py` | **Codex auth** (if not already set up): `C:\Users\bowei\.codex\auth.json` must contain a valid ChatGPT OAuth token. Run `codex auth login` if the file is missing. ## Invariants - **Drive the graph only through the dev server** (see the mandatory rule above): `run_langgraph.ps1` → `run_workflow.py` → `http://127.0.0.1:2024`. Never import or run `graph.py`/`workflow.py`/`agents.py` in-process to execute the workflow — that bypasses the dev server and LangGraph Studio cannot track it. - Use the current Claude Code session for all Claude Code work. Do not launch another `claude` process. - Assume the current Claude Code session already has `--dangerously-skip-permissions`. - Run Python through the recorded conda environment. `run_langgraph.ps1` resolves conda from `-CondaExe`, `CONDA_EXE`, `conda` on PATH, or the user-profile miniconda fallback: ```powershell run -n langgraph python ``` - Codex CLI is installed in the `langgraph` conda env as `codex.cmd` at `C:\Users\bowei\.conda\envs\langgraph\codex.cmd`. It must be invoked via `cmd /c` because `.cmd` files are not directly executable by Python subprocess on Windows. - Codex auth uses ChatGPT OAuth tokens stored in `C:\Users\bowei\.codex\auth.json`. No API key is needed. - `run_langgraph.ps1` sets `CODEX_HOME` from `-CodexHome`, existing `CODEX_HOME`, or `\.codex`. - **Always use `review_task.py` as the Codex review shim.** Pass it via `--codex-review-command` as a JSON array with no spaces. This shim handles all Windows-specific codex invocation requirements: `cmd /c`, stdin prompt passing, `--skip-git-repo-check`, session resume, and explicit `cwd`. - Keep all workflow files under `\Notes` unless the user explicitly overrides `-NotesDir`. - `TaskId` is the numeric suffix, such as `01`; write the plan to `Notes\Task01.md`. - `discussxx-yy.md` numbering is managed by the LangGraph app for Codex review files. If Claude rejects a review comment, create the next numbered discuss file manually before rerunning review. - The workflow uses LangGraph `interrupt()` and persists state via the langgraph dev server. - Each `run_langgraph.ps1` invocation advances the graph to the next interrupt or completion. Use `-Resume` to continue the same thread after completing the requested Claude Code action. ## Dev Server Lifecycle ⛔ DEPRECATED > **已弃用(2026-07 起)。** 本 skill 现用 `clean_run.py` 进程内驱动,**不再需要 dev server**。 > 下面这套 `manage_dev_server.ps1` / `langgraph dev` / Studio 仅作历史参考,正常流程不要用。 The `langgraph dev` server must be running for the entire duration of a workflow session. Use `manage_dev_server.ps1` to start it before the first `run_langgraph.ps1` call and stop it after the workflow completes. ```powershell # Start (idempotent — safe to call even if already running) C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps1 start # Stop (call once when workflow returns {"status":"done"}) C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps1 stop # Status check C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps1 status ``` - `start` waits up to 45 s for `http://127.0.0.1:2024/ok` to respond, then prints the Studio URL. - `stop` kills the process by PID file and removes it; falls back to killing by port 2024 if the PID is stale. - If the server is already running, `start` is a no-op. - Server stdout/stderr logs are written to `%TEMP%\langgraph_dev_server.stdout.log` and `%TEMP%\langgraph_dev_server.stderr.log` for debugging. - **Studio URL**: `https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024` — open in browser to track workflow execution in real time. ## Workflow > **注意**:下列步骤是**旧的 dev-server 流程**(`manage_dev_server.ps1` + `run_langgraph.ps1`)。 > 正常请用上方"**运行方式:进程内驱动**"节的 `clean_run.py`。以下 action 语义(write_plan / decide / > revise / write_rejection 及其 resume 值)两种流程通用,可参考。 1. Determine `TaskId` from the user. If missing, ask for it. 2. Start the dev server (idempotent): ```powershell C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps1 start ``` Wait for the "[dev-server] Ready" line in the output. Then **immediately tell the user** in your text response: - that the dev server is running, and - the Studio URL: `https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024` Example message to user: > LangGraph dev server 已就绪。可在浏览器中打开 Studio 实时监控工作流: > https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024 3. Start or resume the LangGraph app: ```powershell # Use double backslashes (\\) in the JSON string so Windows paths are valid JSON. # $task_path / $latest_discuss_path / etc. are Python Template placeholders — keep them literal. $codexCmd = '["C:\\Users\\bowei\\.conda\\envs\\langgraph\\python.exe","C:\\Users\\bowei\\.claude\\skills\\langgraph-plan-review\\scripts\\review_task.py","$task_path","$latest_discuss_path","$codex_session_id","$work_dir"]' C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\run_langgraph.ps1 ` -TaskId ` -Prompt "" ` -CodexReviewCommand $codexCmd ` -Timeout 300 ``` 4. Inspect the returned JSON. If `status` is `waiting`, perform `action_required` in the current Claude Code session: - `write_plan`: write `Task.md` with project background, task objective, and concrete implementation plan, then resume with `-Resume 'true'`. - `decide`: read the discuss file and resume with `-Resume '{"accepts":true}'` or `-Resume '{"accepts":false,"reason":"..."}'`. - `revise`: revise `Task.md`, then resume with `-Resume 'true'`. - `write_rejection`: write the specified `output_path`, then resume with `-Resume 'true'`. **Why `review_task.py`**: Using the shim keeps all codex-specific logic in Python, and the JSON array stays simple. `run_langgraph.ps1` base64-encodes the JSON command and resume payload before passing them through `conda run`, so normal PowerShell single-quoted JSON can be used. **Windows paths inside the JSON string must use `\\` (double backslash) to produce valid JSON**, e.g. `C:\\Users\\bowei\\...`. `run_langgraph.ps1` automatically sets `PYTHONIOENCODING=utf-8` so prompts containing Unicode (Chinese, etc.) pass through correctly. 5. Inspect the command output after each resume. - Check `"status"` to determine next action: `"waiting"` means perform the next `action_required`; `"done"` means the workflow is complete. - If a new `latest_discuss_path` is present in the output, read that discuss file for context. 6. Stop when the workflow returns `{"status":"done", ...}`: ```powershell C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps1 stop ``` ## Rejection File Rule When the `action_required` is `write_rejection`, the interrupt payload already contains the exact file path: ```json {"action": "write_rejection", "output_path": "Notes/discuss04-01.md", "reason_hint": "..."} ``` Write the rejection content directly to `action_required.output_path`: ```markdown # discuss- ## Claude Code Rejection ``` ## Notes - The LangGraph app automatically scans existing discuss files and writes the next Codex review file without overwriting old discussions. - The app no longer accepts Claude command arguments; Claude actions happen in this current session. - If `codex` is unavailable, report that the review step cannot run rather than simulating it. - `review_task.py` passes the review prompt through stdin with `-` to avoid Windows command-line quoting issues with multiline prompts. - `review_task.py` passes `--skip-git-repo-check` so the workflow can run from Claude launch directories that are not git repositories. - `review_task.py` reads Codex final output via `--output-last-message` so intermediate JSONL progress messages are not treated as review findings. - `review_task.py` persists the Codex session id through LangGraph state and uses `codex exec resume` on later review passes. - `review_task.py` runs Codex with the original Claude Code launch working directory as cwd. - Codex review output is normalized to JSON for `agents.py`: `{"has_serious_issue":true/false,"comment":"...","codex_session_id":"..."}`. - If the dev server restarts, `run_workflow.py` detects that the stored thread no longer exists and creates a new thread automatically. - `run_workflow.py` passes the codex command and timeout as `config["configurable"]` per run — no server restart needed when switching projects.