更新了skill

This commit is contained in:
Myfro9
2026-06-22 16:41:44 +08:00
parent 48b965ec4e
commit 814dbf1681
13 changed files with 845 additions and 13 deletions
+219
View File
@@ -0,0 +1,219 @@
---
name: fpga-goldenref-flow
description: >
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` 各自独立进程调用都能接续。
```powershell
conda run -n langgraph python `
"C:\Users\bowei\.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` (`C:\Users\bowei\.conda\envs\langgraph`) |
| Graph name | `fpga_goldenref_flow` (在 `langgraph.json` 里声明;进程内驱动直接 `build_graph()`) |
| Default input dir | `Notes/` (contains PR00.md, Task00.md) |
| Helper script | `C:\Users\bowei\.claude\skills\fpga-goldenref-flow\scripts\run_fpga_local.py` |
---
## Full workflow
> **入口约束**:下面每一步都通过 helper 脚本 `run_fpga_local.py` 在 `langgraph`
> conda 环境里执行。不要直接 `import` `app.*` 在别处运行,统一走 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:
```powershell
conda run -n langgraph python `
"C:\Users\bowei\.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-dir` as an absolute path pointing into the calling project.
> If omitted, files fall back to `<input-dir-parent>/runs` which 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:**
1. `"action": "select_plan_model"` — first, right after decomposition → **Step 1.5**.
2. `"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:
```powershell
conda run -n langgraph python `
"C:\Users\bowei\.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:
```powershell
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:**
```powershell
conda run -n langgraph python `
"C:\Users\bowei\.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:**
```powershell
conda run -n langgraph python `
"C:\Users\bowei\.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-dir`** you passed at `start` (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 空出来后从断点续跑:
> ```powershell
> conda run -n langgraph python `
> "C:\Users\bowei\.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 by `thread_id`
inside 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`) to `resume`** so 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`. |