Replace machine-specific C:\Users\bowei\... paths in 7 skill docs with %USERPROFILE% / $env:USERPROFILE (or $USERPROFILE in Git Bash blocks). Conda paths use a two-layout resolver (miniconda3\envs vs .conda\envs) or reference ~\skills_env.md CONDA_LANGGRAPH_PYTHON, since the conda location is machine-specific. Fixes paths that resolved wrong on non-bowei machines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
10 KiB
name, description
| name | description |
|---|---|
| fpga-goldenref-flow | Run the fpga-goldenref-flow LangGraph design-and-execution workflow for the project at E:\LangGraph_Design\fpga-goldenref-flow. Drives the compiled graph in-process (NO langgraph dev server) via a persistent SQLite checkpointer: submits a run, surfaces the human-review interrupt (plans are summarised in the Claude conversation for the user to approve/reject), resumes execution, and displays the final summary — all within the Claude session. Trigger whenever the user says any of: "run FPGA flow", "start FPGA workflow", "invoke fpga-goldenref-flow", "run goldenref flow", "启动 FPGA 工作流", "运行 FPGA 设计流程", "跑一下 FPGA flow", "run the FPGA agent", "execute the FPGA design pipeline", or any request to interact with the LangGraph agent inside this project. Also trigger when the user wants to approve or reject the generated plan, or resume a paused fpga-goldenref-flow run. |
驱动方式:进程内驱动(无 dev server)
工作流是一张 LangGraph 图,由 scripts\run_fpga_local.py 在本进程内驱动
(已移除 langgraph dev server 路径)。直接 build_graph() + SqliteSaver 持久化
驱动编译好的图,状态存在 <output_dir>\.fpga_flow_local.sqlite,按 thread_id
持久化,start/resume/continue 各自独立进程调用都能接续。
conda run -n langgraph python `
"$env:USERPROFILE\.claude\skills\fpga-goldenref-flow\scripts\run_fpga_local.py" `
start --input-dir "E:\<proj>\Notes" --output-dir "E:\<proj>\fpga_runs"
为什么是进程内驱动:langgraph dev 是内存存储的开发服务器,对本项目这种长耗时、
多模块、反复中断续跑的执行不可靠——重启丢线程、run 队列被 cancel 残留堵成永久
pending、watchfiles --reload 自激。进程内驱动没有这些问题(无队列、无内存丢失、
无 reload),状态全部落在 SQLite。
Project info
| Item | Value |
|---|---|
| Root | E:\LangGraph_Design\fpga-goldenref-flow |
| Conda env | langgraph (path 见 ~\skills_env.md 的 CONDA_LANGGRAPH_PYTHON) |
| Graph name | fpga_goldenref_flow (在 langgraph.json 里声明;进程内驱动直接 build_graph()) |
| Default input dir | Notes/ (contains PR00.md, Task00.md) |
| Helper script | %USERPROFILE%\.claude\skills\fpga-goldenref-flow\scripts\run_fpga_local.py |
Full workflow
入口约束:下面每一步都通过 helper 脚本
run_fpga_local.py在langgraphconda 环境里执行。不要直接importapp.*在别处运行,统一走 helper 脚本以保证 SQLite 持久化与退出码一致。
Step 1 — Submit a new run
Before calling the script, determine the two key paths:
--input-dir— the directory that holds the project's requirement files (e.g.Notes/). Use an absolute path or a path relative to the current shell's CWD.--output-dir— the directory where all generated files (task folders, plan.md, summary.md) and the run's checkpoint DB + session file will be written. This must be inside the caller's project directory, not inside the workflow development directory. Use the absolute path to the project being worked on, e.g.E:\MyProject\fpga_runs.
Run the helper script using the langgraph conda environment:
conda run -n langgraph python `
"$env:USERPROFILE\.claude\skills\fpga-goldenref-flow\scripts\run_fpga_local.py" `
start `
--input-dir "E:\<project-path>\Notes" `
--output-dir "E:\<project-path>\fpga_runs"
Optional flag: --prompt "additional context" if the user supplied extra requirements.
Rule: always pass
--output-diras an absolute path pointing into the calling project. If omitted, files fall back to<input-dir-parent>/runswhich may or may not be in the project directory.
The script prints [INFO] Thread : <id> and [INFO] Output dir : <path> (note them
for resume), then node-level progress (-> node_name) as the graph runs.
Exit codes:
| Code | Meaning |
|---|---|
| 0 | Workflow completed — jump to Step 4 |
| 1 | Error — read the output, diagnose, report to user |
| 2 | An interrupt fired — read the [INTERRUPT] payload's action and branch (see below) |
| 3 | Codex unavailable — workflow stopped (no downgrade). Resume from checkpoint later with continue. |
Two interrupts fire in order — branch on action in the [INTERRUPT] payload:
"action": "select_plan_model"— first, right after decomposition → Step 1.5."action": "confirm_plan"— later, after plans are generated → Step 2.
Step 1.5 — Select plan model (first interrupt)
When the [INTERRUPT] payload has "action": "select_plan_model", the workflow has
finished decomposition and is waiting for the user to pick the Claude model used to
author/revise the plans (review stays on Codex). The payload includes default
(Opus 4.8) and the decomposition overview.
Ask the user which model (use AskUserQuestion), offering Opus 4.8 (default/recommended), Fable 5, Sonnet 4.6. Then resume with the choice:
conda run -n langgraph python `
"$env:USERPROFILE\.claude\skills\fpga-goldenref-flow\scripts\run_fpga_local.py" `
resume --output-dir "E:\<project-path>\fpga_runs" `
--plan-model opus # or: fable | sonnet | a full id like claude-opus-4-8
The workflow then generates plans with that model and stops again at the
confirm_plan interrupt (exit 2) → go to Step 2.
Step 2 — Human review (Claude reads plans, asks user)
When the script exits with code 2 (confirm_plan) it prints:
[INTERRUPT]— the raw interrupt payload (may include a message)[PLAN] <task_id>: <path>— absolute paths to generated plan files[REQ] <task_id>: <path>— absolute paths to requirement files
For each plan path, read the file:
Get-Content "<plan_path>" -Encoding utf8
Then summarise the plan for the user in 3–5 bullet points per task and ask:
"FPGA 工作流已生成以下设计计划,请确认是否批准继续执行: …bullet points… 批准(继续执行)还是拒绝(请说明需要修改的地方)?"
Wait for the user's answer before proceeding to Step 3.
Step 3 — Resume the workflow
并发安全(MANDATORY):
resume必须绑定到本次运行的工程,绝不能依赖全局会话文件。 总是带上--output-dir(与start时完全相同的绝对路径),这样多个工程并发时 各自的会话文件与 SQLite 互不串。等价地,也可以用--thread-id "<start 打印的 Thread id>"直接指定线程,完全绕过会话文件(最稳)。省略两者只在「同一时间只有一个工程在跑」时才安全。
If the user approves:
conda run -n langgraph python `
"$env:USERPROFILE\.claude\skills\fpga-goldenref-flow\scripts\run_fpga_local.py" `
resume --output-dir "E:\<project-path>\fpga_runs"
(Default behaviour is approved — no extra flag needed.)
If the user rejects:
conda run -n langgraph python `
"$env:USERPROFILE\.claude\skills\fpga-goldenref-flow\scripts\run_fpga_local.py" `
resume --output-dir "E:\<project-path>\fpga_runs" `
--rejected --feedback "<user feedback verbatim>"
Use the same
--output-diryou passed atstart(it is printed on the[INFO] Output dir :line). Alternatively pass--thread-id "<id>"from the[INFO] Thread :line at start.
After rejection the workflow loops back to plan generation; you will likely hit exit code 2 again with new plans — repeat Step 2.
Codex 不可用 (exit 3):若任一 resume/start 以 exit 3 退出,说明 codex(gpt-5.5) 额度被占满,工作流已停在断点(状态已存 SQLite,不降级)。等 codex 空出来后从断点续跑:
conda run -n langgraph python ` "$env:USERPROFILE\.claude\skills\fpga-goldenref-flow\scripts\run_fpga_local.py" ` continue --output-dir "E:\<project-path>\fpga_runs"
Step 4 — Show results
When the script exits with code 0 it prints [SUMMARY] followed by the contents
of <output-dir>\summary.md. Present this to the user.
If the user wants to inspect a specific task's plan or requirement:
<output-dir>\<task_id>\plan.md
<output-dir>\<task_id>\requirement.md
The output-dir is the value passed to --output-dir at start time (printed in the
[INFO] Output dir : line) and is also stored in the session file.
Session state (per-project — concurrency safe)
Between start and resume the helper writes a small session file inside the
run's own output_dir, so concurrent projects never share it:
<output_dir>\.fpga_flow_session.json
It holds thread_id and output_dir. resume/continue locate it via the
--output-dir you pass (hence Step 3 requires it). It is deleted automatically when
the run completes successfully.
Isolation guarantees for concurrent projects:
- Graph state (
MainState/FpgaState, checkpoints) is isolated bythread_idinside that run's own<output_dir>\.fpga_flow_local.sqlite— different projects use different output dirs and different DBs, and cannot see each other's state. - Generated files are isolated by
output_dir. - The session pointer is isolated by living inside each
output_dir. Always pass--output-dir(or--thread-id) toresumeso it never reads another project's session.
To abandon a paused run and start fresh, delete that project's
<output_dir>\.fpga_flow_session.json (and, if you want a clean checkpoint,
<output_dir>\.fpga_flow_local.sqlite) before calling start.
Troubleshooting
| Symptom | Fix |
|---|---|
ModuleNotFoundError |
conda run -n langgraph pip install langgraph langgraph-checkpoint-sqlite |
No session file found |
Must call start before resume (or pass --thread-id) |
Empty [PLAN] lines |
Look in <output_dir>\ for plan.md files under each <task_id> folder |
interrupted never advances |
Make sure --rejected flag is accompanied by --feedback text |
| exit 3 (Codex 不可用) | Wait for codex quota, then continue --output-dir <same path> from the checkpoint |
Stale state after editing app\* |
In-process driver imports fresh each run; just re-run start/continue. To reset a thread, delete that run's .fpga_flow_local.sqlite. |