seeflow
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseseeflow
SeeFlow
Turn a natural-language prompt into a registered SeeFlow flow at , with node-attached content (scripts, detail.md, view.html) under . Orchestrate five sub-agents and the CLI; never read the codebase directly, never author by hand ( writes the envelope for you).
<projectPath>/flow.json<projectPath>/nodes/<id>/seeflowflow.jsonprojects:create将自然语言提示转换为已注册的SeeFlow流程,存储在中,节点附属内容(脚本、detail.md、view.html)位于下。协调五个子Agent和 CLI;禁止直接读取代码库,禁止手动编写(会为你生成基础框架)。
<projectPath>/flow.json<projectPath>/nodes/<id>/seeflowflow.jsonprojects:createProject layout convention
项目布局规范
A host repo opts into seeflow by creating a directory (the only place this skill introduces a folder — the studio itself is path-agnostic). is shared across every flow in the host and lives at ; each flow lives in its own subdirectory beside it:
<host>/.seeflow/.seeflowLEARN.md<host>/.seeflow/LEARN.md<host>/ ← the user's repo
.seeflow/ ← container, created by this skill
LEARN.md ← shared crib for this skill (project-wide, used by every flow)
<flow-name>/ ← seeflow project root — passed to projects:create --path
flow.json ← envelope + nodes/connectors
style.json ← layout/visuals (managed by `flows:layout`)
nodes/<id>/ ← per-node sidecar files (detail.md, view.html, scripts/)
.tmp/ ← per-flow scratch ($SEEFLOW_TMP)
state/ ← per-flow runtime script stateAlways call . Inside , every CLI / file reference is relative to that project root — never re-prefix with .
seeflow projects:create --path "$repoPath/.seeflow/<flow-name>" --name "..."--path.seeflow/~/.seeflow/Parallelism is the default — one message, N calls. Phase 1's wrong/right block below is canonical; later parallel phases reference it. Narrate each phase boundary with a one-line status (e.g. ) so silent waits don't feel broken.
TaskPhase 3: scaffolding skeleton flow…宿主仓库可通过创建目录来启用SeeFlow(这是本技能唯一会创建文件夹的位置——Studio本身与路径无关)。是宿主仓库中所有流程共享的参考文档,存储在;每个流程都位于其旁的独立子目录中:
<host>/.seeflow/.seeflowLEARN.md<host>/.seeflow/LEARN.md<host>/ ← 用户的仓库
.seeflow/ ← 容器目录,由本技能创建
LEARN.md ← 本技能的共享参考文档(项目级,所有流程共用)
<flow-name>/ ← SeeFlow项目根目录——传递给`projects:create --path`参数
flow.json ← 框架文件 + 节点/连接器
style.json ← 布局/视觉配置(由`flows:layout`管理)
nodes/<id>/ ← 每个节点的附属文件(detail.md、view.html、scripts/)
.tmp/ ← 每个流程的临时目录($SEEFLOW_TMP)
state/ ← 每个流程的运行时脚本状态务必调用。在指定的目录内,所有CLI/文件引用均相对于该项目根目录——切勿添加前缀。
seeflow projects:create --path "$repoPath/.seeflow/<flow-name>" --name "..."--path.seeflow/~/.seeflow/默认采用并行执行——一条消息,N个调用。下文第1阶段的错误/正确示例是标准范式;后续并行阶段均遵循此规则。每个阶段结束时用一行状态说明(例如),避免用户因静默等待而误以为程序故障。
TaskPhase 3: 搭建流程骨架…When NOT to invoke
请勿调用的场景
- Editing nodes on an existing flow → use the canvas, or hit the CLI directly ().
nodes:patch - Deleting a flow → .
flows:delete - Re-laying out an existing flow without semantic changes → .
flows:layout - Empty project (nothing to analyze) → ask the user first.
- Debugging a single broken Play/Status script → edit in-place, re-run Phase 6.
- 编辑现有流程的节点 → 使用画布,或直接调用CLI()。
nodes:patch - 删除流程 → 。
flows:delete - 仅调整现有流程布局而不修改语义 → 。
flows:layout - 空项目(无内容可分析) → 先询问用户。
- 调试单个故障Play/Status脚本 → 就地编辑,重新运行第6阶段。
Inputs
输入参数
- User's prompt; project root ();
$PWD(optional studio host:port).~/.seeflow/config.json - Existing (skip the creation path if already present — fall back to
<project>/flow.json).register --flow flow.json - (
$learnPath) — persistent crib sheet shared across every flow in this host repo, written by prior$PWD/.seeflow/LEARN.mdruns. Read before Phase 1. Format:/seeflow.references/learn-format.md
- 用户提示;项目根目录();
$PWD(可选的Studio主机:端口)。~/.seeflow/config.json - 已存在的(若已存在则跳过创建流程,改用
<project>/flow.json)。register --flow flow.json - (
$learnPath)——宿主仓库中所有流程共享的持久化参考文档,由之前的$PWD/.seeflow/LEARN.md运行生成。在第1阶段前读取。格式参考:/seeflow。references/learn-format.md
Conventions
变量约定
| Variable | Resolution |
|---|---|
| |
| |
| |
| |
| Locally installed |
| 变量名 | 解析规则 |
|---|---|
| 优先使用 |
| |
| |
| |
| 若本地已安装 |
Scratch files & cleanup
临时文件与清理
Any intermediate file the orchestrator or a generated Play/Status script needs (curl output, jq scratch, downloaded fixtures, comparison snapshots, etc.) goes under — never , , or . The project-local path requires no extra permission, survives the run for debugging, and is gitignored by convention (the project lives inside the host's container, which is gitignored — add explicitly if not).
$SEEFLOW_TMP/tmp/var/tmp$TMPDIR.seeflow/.tmp/Lifecycle:
- Create on first use — inside any script or wrapper that writes there. Idempotent, costs nothing.
mkdir -p "$SEEFLOW_TMP" - Generated scripts (Phase 5) — Play / Status bodies that need scratch space should reference (or hardcode
"$SEEFLOW_TMP"relative to.tmp/...when running outside a wrapper that exports it).$repoPath - Cleanup at end of run — after Phase 6 prints the final line, the orchestrator removes
Flow "..." registered ...($SEEFLOW_TMP). On a failed/aborted run, leave it in place — the contents are the debugging trail.rm -rf "$SEEFLOW_TMP" - Never check in — if is not yet gitignored, add it before committing.
.tmp/
Every flow mutation goes through the CLI. The studio validates every write server-side — there is no separate validation step. Don't memorise CLI syntax — run to see every subcommand and for synopsis, body shape, output, and error kinds. Treat the help output as the source of truth and follow what it prints. See for the resolver snippet.
$SEEFLOW help$SEEFLOW help <command>references/cli.md编排器或生成的Play/Status脚本所需的任何中间文件(curl输出、jq临时文件、下载的测试数据、对比快照等)都必须放入——禁止放入、或。项目级路径无需额外权限,运行期间保留用于调试,且按约定会被git忽略(项目位于宿主的容器内,该目录已被git忽略——若未被忽略,需显式添加)。
$SEEFLOW_TMP/tmp/var/tmp$TMPDIR.seeflow/.tmp/生命周期:
- 首次使用时创建 —— 任何需要写入临时目录的脚本或包装器内执行。该操作是幂等的,无额外开销。
mkdir -p "$SEEFLOW_TMP" - 生成的脚本(第5阶段) —— 需要临时空间的Play/Status脚本应引用(或在无包装器导出该变量时,相对于
"$SEEFLOW_TMP"硬编码$repoPath)。.tmp/... - 运行结束时清理 —— 第6阶段打印最终的信息后,编排器删除
Flow "..." registered ...($SEEFLOW_TMP)。若运行失败/中止,则保留该目录——其内容可作为调试线索。rm -rf "$SEEFLOW_TMP" - 禁止提交到版本库 —— 若尚未被git忽略,提交前需添加忽略规则。
.tmp/
所有流程修改均通过CLI执行。Studio会在服务端验证每一次写入——无需单独的验证步骤。无需记忆CLI语法——运行查看所有子命令,运行查看命令概要、请求体格式、输出及错误类型。将帮助输出作为权威来源并严格遵循。CLI解析器片段参考。
$SEEFLOW help$SEEFLOW help <command>references/cli.mdPipeline
执行流程
P0 /health probe ‖ read $learnPath
P1 code-analyzer ‖ system-analyzer
P2 node-planner (kicks off when code-analyzer returns;
system-analyzer continues in background)
P3 projects:create (path + name → empty flow.json registered)
→ flow:add-bulk (nodes + connectors, atomic) → flows:layout
→ USER REVIEW + dynamic gate (one combined ask)
P4 play-designer ‖ status-designer
P5 write scripts to nodes/<nodeId>/scripts/
→ nodes:patch (per node, with playAction / statusAction)
→ optional newTriggerNodes via flow:add-bulk
→ flows:layout
P6 e2eEach phase gates on the previous (with the Phase 1 → Phase 2 overlap).
P0 /健康检查 ‖ 读取$learnPath
P1 代码分析器 ‖ 系统分析器
P2 节点规划器(代码分析器返回后启动;
系统分析器在后台继续运行)
P3 projects:create(路径 + 名称 → 注册空flow.json)
→ flow:add-bulk(批量添加节点 + 连接器,原子操作) → flows:layout
→ 用户评审 + 动态分支选择(合并为一次询问)
P4 Play脚本设计器 ‖ Status脚本设计器
P5 将脚本写入nodes/<nodeId>/scripts/
→ nodes:patch(按节点更新,附带playAction / statusAction)
→ 可选通过flow:add-bulk添加新触发节点
→ flows:layout
P6 端到端验证每个阶段依赖前一阶段的完成(第1阶段到第2阶段可重叠)。
Core rules
核心规则
Full text in :
references/core-rules.md- No mocks. Real services, real state. If something isn't running, stop and ask.
- Bigger picture before INSERTs. Use the natural data-entry path (API, file-drop, producer, seed, webhook).
- Match the project's primary language. Use for every script.
runtimeProfile.primaryLanguage
完整内容见:
references/core-rules.md- 禁止模拟。使用真实服务、真实状态。若服务未运行,停止并询问用户。
- 先了解全局再执行插入操作。使用自然的数据输入路径(API、文件上传、生产者、种子数据、Webhook)。
- 匹配项目的主要语言。所有脚本均使用指定的语言。
runtimeProfile.primaryLanguage
Common mistakes
常见错误
- Serial sub-agent dispatch (N messages, one Task call each). One message, N Task calls — see Phase 1's wrong/right.
- One sub-agent fixing multiple failing scripts in Phase 6. Each needs isolated context.
- Authoring directly. Every mutation is a CLI call.
flow.json - Silently overwriting (or silently falling back from) an existing flow at the target path. Phase 3 step 1's existing-flow gate is mandatory — open / rename / overwrite, the user decides. The old "fall back to " behavior was data-loss-adjacent.
register - Touching . The studio owns it via
style.json.flows:layout - Passing as
<slug>/scripts/…. New anchor is the node folder — emit justscriptPath.scripts/play.ts - Mocking services or fake fixtures. Use real triggers; copy fixtures from integration tests.
- Asking "what's your codebase?". Launch the analyzers — that is their job.
- Skipping or simulating Phase 6. Mandatory; the retry budget handles flakiness.
- Bypassing the Phase 0 consent check. Never default to ; always read
enabled: truefirst.~/.seeflow/consent.json - Writing inside a flow folder (
LEARN.md). It is shared across every flow in the host repo — always read/write<host>/.seeflow/<flow-name>/LEARN.md=$learnPath, never anywhere else.$PWD/.seeflow/LEARN.md - Touching after the initial
statuswrite. Thependinghook owns that field — seeSessionEnd.feedback.md - Logging without a redacted summary. If the summary would leak a path, hostname, project name, or prompt text, skip the entry rather than emit a leaky one.
- Writing scratch files to (or
/tmp). Use$TMPDIR($SEEFLOW_TMP) — project-local, no permission prompts, and cleaned up at end of run. Same rule applies to scripts the Phase 4 designers emit.<projectPath>/.tmp/ - Forgetting to clean after a successful run. Leave it in place on failure (debugging trail);
$SEEFLOW_TMPafter Phase 6 prints the finalrm -rf "$SEEFLOW_TMP"line on success.Flow registered
- 串行调度子Agent(N条消息,每次调用一个Task)。应使用一条消息,N个Task调用——见第1阶段的错误/正确示例。
- 单个子Agent修复第6阶段的多个故障脚本。每个故障脚本需独立上下文。
- 手动编写。所有修改必须通过CLI调用完成。
flow.json - 静默覆盖(或静默回退)目标路径下的现有流程。第3阶段第1步的现有流程检查是强制要求——打开/重命名/覆盖,由用户决定。旧的“回退到”行为可能导致数据丢失。
register - 修改。该文件由Studio通过
style.json管理。flows:layout - 将作为
<slug>/scripts/…传递。新的锚点是节点文件夹——只需传入scriptPath。scripts/play.ts - 模拟服务或伪造测试数据。使用真实触发器;从集成测试中复制测试数据。
- 询问“你的代码库是什么?”。启动分析器——这是它们的职责。
- 跳过或模拟第6阶段。该阶段是强制要求;重试机制可处理不稳定情况。
- 绕过第0阶段的授权检查。切勿默认设置;务必先读取
enabled: true。~/.seeflow/consent.json - 在流程文件夹内编写(
LEARN.md)。该文件是宿主仓库中所有流程共享的——务必读写<host>/.seeflow/<flow-name>/LEARN.md=$learnPath,禁止写入其他位置。$PWD/.seeflow/LEARN.md - 初始写入后修改
pending字段。该字段由status钩子管理——见SessionEnd。feedback.md - 日志未包含脱敏摘要。若摘要会泄露路径、主机名、项目名称或提示文本,跳过该日志条目,避免泄露信息。
- 将临时文件写入(或
/tmp)。使用$TMPDIR($SEEFLOW_TMP)——项目级路径,无需权限提示,运行结束时清理。第4阶段设计器生成的脚本也需遵循此规则。<projectPath>/.tmp/ - 成功运行后忘记清理。失败时保留该目录(用于调试);成功运行第6阶段并打印最终
$SEEFLOW_TMP信息后,执行Flow registered。rm -rf "$SEEFLOW_TMP"
Phase 0 — pre-flight (parallel)
第0阶段 — 预检查(并行)
Lookup-first gate — run before anything else
先检查再执行 — 先于所有步骤运行
If the user's prompt reads as inspection rather than creation — any of "show me", "show the", "how does", "how do", "what does", "diagram", "explain", "where does", "what handles" — STOP and route through instead. That skill catalogues registered flows and only hands back here if nothing matches. Going straight to creation when a flow already exists wastes the run and surfaces a duplicate. The same gate applies when the user names a flow by slug or title without an explicit verb ("the CRN Enhancement flow", "the checkout flow") — assume inspection unless they prefix it with "create / scaffold / generate / add".
/seeflow-lookupCreation-only triggers (skip the gate): the prompt explicitly says "create / scaffold / generate / add a flow", or has already run in this turn and reported no match.
/seeflow-lookup若用户提示属于检查类而非创建类——例如“show me”“show the”“how does”“how do”“what does”“diagram”“explain”“where does”“what handles”——停止操作并将请求路由至。该技能会列出已注册的流程,仅当未找到匹配流程时才会转交至此处。若已存在流程却直接创建,会浪费资源并生成重复流程。当用户通过别名或标题指定流程但未明确说明操作(例如“CRN增强流程”“结账流程”)时,同样假设为检查请求,除非用户前缀包含“create / scaffold / generate / add”。
/seeflow-lookup仅触发创建的场景(跳过检查):用户明确说明“create / scaffold / generate / add a flow”,或本次会话中已运行且未找到匹配流程。
/seeflow-lookupSilent consent check (see feedback.md
)
feedback.md静默授权检查(见feedback.md
)
feedback.mdRead . If absent, run the first-run prompt and write the file before continuing. The result governs whether qualifying events get logged to for the rest of the run — the skill only writes locally; a hook handles transfer.
~/.seeflow/consent.json~/.seeflow/feedback.jsonlSessionEndCreate a checklist of the six phases ( … ); each as it finishes. Phases skipped at the dynamic gate get marked completed with a one-line note. (If / aren't loaded, run with first.)
TaskCreatePhase 1 — discoverPhase 6 — end-to-end validationTaskUpdateTaskCreateTaskUpdateToolSearchselect:TaskCreate,TaskUpdate读取。若文件不存在,运行首次启动提示并在继续前写入该文件。检查结果将决定后续运行中符合条件的事件是否会记录到——本技能仅在本地写入;钩子负责数据传输。
~/.seeflow/consent.json~/.seeflow/feedback.jsonlSessionEnd创建一个包含六个阶段的检查清单( … );每个阶段完成时调用更新状态。动态分支中跳过的阶段需标记为已完成并添加一行说明。(若未加载/,先运行并指定。)
TaskCreatePhase 1 — 发现Phase 6 — 端到端验证TaskUpdateTaskCreateTaskUpdateToolSearchselect:TaskCreate,TaskUpdateCapability probe — run before anything else
能力检查 — 先于所有步骤运行
Run once and confirm every required subcommand is present: , , , , , , , . (Older versions on lack one or more — was added with the project-local scaffold flow; is the current new-project entry point.) For each missing subcommand, log a feedback entry and surface to the user.
$SEEFLOW helpprojects:createregisterflow:add-bulkflows:layoutnodes:patchschemaidse2e@tuongaz/seeflownpxidsprojects:create- Required missing → log (
env-capability-mismatch,severity: blocker,phase: P0,details: missing <subcommand>[, <subcommand>...]npm i -g @tuongaz/seeflow@latestsummary: $SEEFLOW lacks required subcommands; run). Then stop — do not start Phase 1.and retry - All present → continue.
If itself fails (binary not on PATH, unavailable), log (, , ) and stop.
$SEEFLOW helpnpxenv-tool-missingseverity: blockerphase: P0summary: $SEEFLOW unresolved — neither local binary nor npx fallback available运行一次并确认所有必需的子命令均存在:、、、、、、、。(旧版本的可能缺少部分子命令——是随项目级流程骨架新增的;是当前创建新项目的入口。)对于每个缺失的子命令,记录反馈并告知用户。
$SEEFLOW helpprojects:createregisterflow:add-bulkflows:layoutnodes:patchschemaidse2e@tuongaz/seeflowidsprojects:create- 必需子命令缺失 → 记录(
env-capability-mismatch,severity: blocker,phase: P0,details: missing <subcommand>[, <subcommand>...]npm i -g @tuongaz/seeflow@latestsummary: $SEEFLOW缺少必需的子命令;请运行)。然后停止操作——切勿启动第1阶段。后重试 - 所有必需子命令均存在 → 继续。
若本身执行失败(二进制文件不在PATH中,不可用),记录(,,)并停止操作。
$SEEFLOW helpnpxenv-tool-missingseverity: blockerphase: P0summary: $SEEFLOW无法解析——本地二进制文件和npx备用方案均不可用Studio probe + LEARN.md (parallel)
Studio健康检查 + LEARN.md(并行)
Then in a single message:
curl --max-time 0.5 -fsS "$STUDIO_URL/health"- Read (
$learnPath) if present →$PWD/.seeflow/LEARN.md(elselearnContext). This file is shared across every flow in this host — do not look inside anynullfolder for it. Format:<flow-name>/.references/learn-format.md
- 200 → Phase 1.
- !200 → tell the user the studio isn't running, warn the first launch can take a minute or two if it has to fall back to , then run the CLI's
npxsubcommand. Re-probestartonce. If still unreachable, log/health(env-service-unreachable,severity: blocker,phase: P0), surface and stop.summary: studio /health unreachable after start retry
然后在一条消息中执行以下操作:
curl --max-time 0.5 -fsS "$STUDIO_URL/health"- 若(
$learnPath)存在则读取 → 存入$PWD/.seeflow/LEARN.md(否则为learnContext)。该文件由宿主仓库中所有流程共享——切勿在任何null文件夹内查找。格式参考:<flow-name>/。references/learn-format.md
- 返回200 → 进入第1阶段。
- 未返回200 → 告知用户Studio未运行,提醒首次启动若回退到可能需要一两分钟,然后运行CLI的
npx子命令。重新检查start一次。若仍无法访问,记录/health(env-service-unreachable,severity: blocker,phase: P0),告知用户并停止操作。summary: 启动重试后Studio /health仍无法访问
Phase 1 — discover (parallel)
第1阶段 — 发现(并行)
Launch both analyzers in parallel — single message, two calls. Serial launch roughly doubles wall-clock for zero benefit.
TaskWrong:
message 1: Task(seeflow-code-analyzer, …) → wait
message 2: Task(seeflow-system-analyzer, …)Right:
message 1: Task(seeflow-code-analyzer, …)
Task(seeflow-system-analyzer, …)Every later parallel phase (Phase 4 designers, Phase 5 retries spanning both overlay families, Phase 6 per-script fix-up) follows this pattern.
- — in:
seeflow-code-analyzer,userPrompt,projectRoot,existingDemo. Out:learnContext,userIntent,audienceFraming,scope,codePointers,knownEndpoints,techStack.existingDemo - — in:
seeflow-system-analyzer,projectRoot. Out:learnContext+ aruntimeProfilepayload (learnUpdates,localDevSetup,integrationTests,fixtures,factories,seedCommands,dataEntryPaths,gotchas). Every fact it learns about how to start / set up the local environment MUST land intechAdaptations.learnUpdates
Tools: (read-only). Schemas: , , . Unparseable output: retry that single agent once, then log (, , ), surface, and stop. The same rule applies to every sub-agent in Phases 2 and 4.
Read, Grep, Glob, LS, Bashagents/seeflow-code-analyzer.mdagents/seeflow-system-analyzer.mdreferences/learn-format.mdagent-output-unparseableseverity: failureagent: <slug>summary: <agent> returned unparseable JSON after retryagent-output-unparseable并行启动两个分析器——一条消息,两个调用。串行启动会将运行时间大致翻倍且无任何收益。
Task错误示例:
消息1: Task(seeflow-code-analyzer, …) → 等待
消息2: Task(seeflow-system-analyzer, …)正确示例:
消息1: Task(seeflow-code-analyzer, …)
Task(seeflow-system-analyzer, …)后续所有并行阶段(第4阶段设计器、第5阶段跨覆盖家族的重试、第6阶段按脚本修复)均遵循此模式。
- —— 输入:
seeflow-code-analyzer、userPrompt、projectRoot、existingDemo。输出:learnContext、userIntent、audienceFraming、scope、codePointers、knownEndpoints、techStack。existingDemo - —— 输入:
seeflow-system-analyzer、projectRoot。输出:learnContext+runtimeProfilepayload(learnUpdates、localDevSetup、integrationTests、fixtures、factories、seedCommands、dataEntryPaths、gotchas)。它所了解的关于本地环境启动/设置的所有信息必须存入techAdaptations。learnUpdates
工具:(只读)。Schema:、、。若输出无法解析:重试该Agent一次,然后记录(,,),告知用户并停止操作。此规则同样适用于第2阶段和第4阶段的所有子Agent。
Read, Grep, Glob, LS, Bashagents/seeflow-code-analyzer.mdagents/seeflow-system-analyzer.mdreferences/learn-format.mdagent-output-unparseableseverity: failureagent: <slug>summary: <agent>重试后仍返回无法解析的JSONEmpty-project / design-only mode
空项目/仅设计模式
If the project root has no source tree (no , no Go module, no Python project, no language source files), the "When NOT to invoke" rule kicks in: ask the user first. If they say "design anyway" (mockups, demo skeletons, architectural sketches), skip both analyzers and build a synthetic brief by hand from the user's prompt:
package.jsonjson
{
"userIntent": "<extracted verbatim from the user's prompt>",
"audienceFraming":"design-only sketch — no running system to observe",
"scope": { "rootEntities": [<inferred from prompt>], "outOfScope": [] },
"codePointers": [],
"knownEndpoints": [],
"techStack": [<user-stated, or empty>],
"existingDemo": null,
"runtimeProfile": null
}Forward that brief to (Phase 2) as-is — the planner already tolerates a sparse brief.
seeflow-node-plannerLog (, , , ).
mode-fallbackseverity: degradedphase: P1details: design-onlysummary: empty project — analyzers skipped, synthetic brief built from promptDownstream consequences:
- Phase 3 dynamic gate: default to static without re-asking. Without , Phase 4 designers cannot pick a real interpreter or fixture; tell the user to populate code first if they later want dynamic.
runtimeProfile - Phase 6 (e2e): N/A — skip with a one-line note when summarising the run.
- : still write the flow row, but mark it
$learnPathin the purpose column so the next run knows the canvas is not wired to a real system.(design-only)
若项目根目录无源代码树(无、Go模块、Python项目或语言源文件),则触发“请勿调用的场景”规则:先询问用户。若用户表示“仍要设计”(原型、演示骨架、架构草图),跳过两个分析器,根据用户提示手动构建合成概要:
package.jsonjson
{
"userIntent": "<从用户提示中提取的原文>",
"audienceFraming":"仅设计草图——无运行中的系统可观察",
"scope": { "rootEntities": [<从提示中推断>], "outOfScope": [] },
"codePointers": [],
"knownEndpoints": [],
"techStack": [<用户指定,或为空>],
"existingDemo": null,
"runtimeProfile": null
}将该概要直接转发给(第2阶段)——规划器已兼容精简概要。
seeflow-node-planner记录(,,,)。
mode-fallbackseverity: degradedphase: P1details: design-onlysummary: 空项目——跳过分析器,根据提示构建合成概要下游影响:
- 第3阶段动态分支选择:默认采用静态模式,无需再次询问。若无,第4阶段设计器无法选择真实解释器或测试数据;若用户后续需要动态模式,告知用户先填充代码。
runtimeProfile - 第6阶段(端到端验证):不适用——运行总结时跳过该阶段并添加一行说明。
- :仍需写入流程记录,但在purpose列标记为
$learnPath,以便下次运行时了解画布未连接到真实系统。(design-only)
Phase 1 → Phase 2 overlap
第1阶段 → 第2阶段重叠
Start as soon as the code-analyzer returns — it only needs the code-analyzer's brief plus . The system-analyzer continues in the background.
seeflow-node-plannertechStackWhen the system-analyzer returns:
- Size-check the payload first. Measure the JSON byte length. If > 16 KB (twice the agent's budget — see § "Output budget"), the analyzer drifted. Apply the per-field caps from that section before merging: truncate
agents/seeflow-system-analyzer.mdto 10,gotchas[]/fixtures[]to 8, prose fields to 400 chars, etc. Drop any inherited fact that already appears verbatim infactories[](the merger would keep it anyway). Log$learnPathonce withagent-output-corrected. The trimmed payload is what feeds steps 1–3.agent: seeflow-system-analyzer, details: oversize-learnupdates-truncated (Nb → Mb) - Merge into
learnUpdates($learnPath— create$PWD/.seeflow/LEARN.mdif missing; the file is shared across every flow in this host). Anything about boot, ports, env vars, fixtures, gotchas, or tech adaptations MUST land in the file. Re-cap$PWD/.seeflow/to ~6 KB after the merge per$learnPath§ "Merging rules" (push oldest gotchas into a collapsedreferences/learn-format.mdblock).<details> - Splice +
runtimeProfilefacts into the in-memory context brief used by Phase 4. Forward the trimmed payload — never the raw analyzer output — and only the fields each designer actually consumes ($learnPath, the matchingruntimeProfilefor techs in this flow, the relevanttechAdaptations.<techId>, top 5dataEntryPaths). The rest stays ingotchasfor the next run; it doesn't need to ride along in every designer prompt.$learnPath - Merge /
knownEndpointsfrom the code-analyzer into the same write.techStack
Resolve tech refs. Map each in the merged to . Forward those paths and the matching into Phase 2 / 4 prompts (~3–5 refs per flow). If the system-analyzer hasn't returned yet, forward whatever already had; the planner produces a first draft and the user reviews in Phase 3 anyway.
techId## Tech stackreferences/tech/<techId>.md## Tech stack adaptationstechAdaptations$learnPath代码分析器返回后立即启动——它仅需代码分析器的概要和。系统分析器在后台继续运行。
seeflow-node-plannertechStack系统分析器返回后:
- 首先检查payload大小。测量JSON字节长度。若超过16 KB(Agent预算的两倍——见§ "Output budget"),说明分析器输出超出范围。合并前应用该章节的字段限制:将
agents/seeflow-system-analyzer.md截断为10条,gotchas[]/fixtures[]截断为8条, prose字段截断为400字符等。删除任何已在factories[]中存在的重复事实(合并时也会自动忽略)。记录一次$learnPath,参数为agent-output-corrected。修剪后的payload将用于步骤1–3。agent: seeflow-system-analyzer, details: oversize-learnupdates-truncated (Nb → Mb) - 将合并到
learnUpdates($learnPath——若$PWD/.seeflow/LEARN.md不存在则创建;该文件由宿主仓库中所有流程共享)。任何关于启动、端口、环境变量、测试数据、注意事项或技术适配的信息必须写入该文件。合并后按照$PWD/.seeflow/§ "Merging rules"将references/learn-format.md压缩至约6 KB(将最旧的注意事项放入折叠的$learnPath块中)。<details> - 将+
runtimeProfile中的信息插入第4阶段使用的内存上下文概要中。仅转发修剪后的payload——切勿转发原始分析器输出——且仅转发每个设计器实际需要的字段($learnPath、与当前流程技术匹配的runtimeProfile、相关的techAdaptations.<techId>、前5条dataEntryPaths)。其余信息保留在gotchas中供下次运行使用;无需随每个设计器提示传递。$learnPath - 将代码分析器的/
knownEndpoints合并到同一文件中。techStack
解析技术引用。将合并后的中的每个映射到。将这些路径和匹配的转发到第2/4阶段的提示中(每个流程约3–5个引用)。若系统分析器尚未返回,转发中已有的;规划器会生成初稿,用户将在第3阶段评审。
## Tech stacktechIdreferences/tech/<techId>.md## Tech stack adaptations$learnPathtechAdaptationsPhase 2 — plan nodes
第2阶段 — 节点规划
Look up the current node + connector contract from the CLI first. Before drafting anything, run and (parallel; one message, two Bash calls) and capture both outputs. Pass them to the planner alongside the brief — the planner has no shell, so what you don't forward, it doesn't know. Skipping this step lets the planner invent fields the CLI rejects on , burning a retry.
$SEEFLOW schema node$SEEFLOW schema connectorflow:add-bulkLaunch with: the brief, the resolved tech-ref paths, the matching , and the two CLI outputs above. No tools — pure reasoning. The planner reads each ref's Node modelling section and treats as the project-specific override.
seeflow-node-plannertechAdaptationstechAdaptationsConnectors conform to and nothing more. If the planner emits any field the contract rejects, strip it before and log with . Do not enumerate the legal fields here — re-run the schema command whenever in doubt.
$SEEFLOW schema connectorflow:add-bulkagent-output-correcteddetails: connector-extras-stripped (×N)- Resource nodes first — every DB, queue, event bus, cache, file store, external SaaS gets its own node, typed with a matching Lucide
rectangle(icon,database,list-ordered,radio-tower,cloud) and aservercapability when state is worth probing.statusAction - Abstraction — one node per service / workflow / worker / queue / DB. Exceptions: independently-meaningful pipeline stages, fan-out consumers, branches, and services hosting multiple independent state machines.
- Duplicate shared resources for clarity. When a DB / queue / bus is referenced by many nodes and the lines tangle the canvas, split it into role-specific copies (,
orders-db-read) sharing the sameorders-db-write+type+data.iconbut distinctdata.names.id
Output: a single envelope carrying , , , , and (planner-only sibling map). The and arrays must conform to and — they are forwarded verbatim in a single body to the subcommand in Phase 3. Any key the CLI rejects here is rejected at too. One retry on unparseable output, then surface and stop. Full contract: .
nameslugnodesconnectorsrationalesnodesconnectors$SEEFLOW schema node$SEEFLOW schema connectorflow:add-bulkflow:add-bulkagents/seeflow-node-planner.mdValidate the envelope before continuing. A parseable JSON blob is not the same as a complete envelope. After , assert every required key is present and non-empty:
JSON.parsetypeof name === 'string' && name.length > 0typeof slug === 'string' && slug.length > 0Array.isArray(nodes) && nodes.length > 0- (may be empty for single-node flows)
Array.isArray(connectors) - (one entry per node id)
rationales && typeof rationales === 'object' && Object.keys(rationales).length === nodes.length
If any assertion fails, re-dispatch the planner once with the specific gap echoed back in the prompt (). On second failure, log (, , , , ), surface, and stop. Never silently synthesise the missing fields — losing the planner's own justifications at the Phase 3 review gate is a real loss of signal, and a fabricated / ships under the planner's authority without its review.
Your previous output was missing: name, rationales[3 of 5 nodes]. Re-emit the full envelope.agent-output-incompleteseverity: failurephase: P2agent: seeflow-node-plannerdetails: <missing-keys>summary: planner returned partial envelope after retrynameslug首先从CLI获取当前节点 + 连接器的契约。在起草任何内容前,并行运行和(一条消息,两个Bash调用)并捕获输出。将输出与概要一起传递给规划器——规划器无shell权限,未转发的信息它无法获取。跳过此步骤会导致规划器生成CLI在时拒绝的字段,浪费重试机会。
$SEEFLOW schema node$SEEFLOW schema connectorflow:add-bulk启动,传入:概要、解析后的技术引用路径、匹配的、上述两个CLI输出。无需工具——纯推理。规划器会读取每个引用的Node modelling章节,并将作为项目特定的覆盖规则。
seeflow-node-plannertechAdaptationstechAdaptations连接器必须严格遵循。若规划器输出契约中未定义的字段,在前删除这些字段并记录,参数为。无需在此枚举合法字段——如有疑问重新运行schema命令即可。
$SEEFLOW schema connectorflow:add-bulkagent-output-correcteddetails: connector-extras-stripped (×N)- 优先创建资源节点 —— 每个数据库、队列、事件总线、缓存、文件存储、外部SaaS服务都要有独立节点,类型为,并匹配Lucide图标(
rectangle、database、list-ordered、radio-tower、cloud);若状态值得探测,需具备server能力。statusAction - 抽象原则 —— 每个服务/工作流/ worker/队列/数据库对应一个节点。例外情况:独立有意义的流水线阶段、扇出消费者、分支、托管多个独立状态机的服务。
- 为清晰起见复制共享资源。当数据库/队列/总线被多个节点引用导致连线混乱时,将其拆分为角色特定的副本(、
orders-db-read),它们共享相同的orders-db-write+type+data.icon但data.name不同。id
输出:包含、、、和(规划器专用的节点映射)的单个框架文件。和数组必须符合和——它们将原样转发给第3阶段的子命令。CLI在此处拒绝的任何键也会在时被拒绝。若输出无法解析,重试一次,然后告知用户并停止操作。完整契约见。
nameslugnodesconnectorsrationalesnodesconnectors$SEEFLOW schema node$SEEFLOW schema connectorflow:add-bulkflow:add-bulkagents/seeflow-node-planner.md继续前验证框架文件。可解析的JSON blob不代表完整的框架文件。后,断言所有必需键均存在且非空:
JSON.parsetypeof name === 'string' && name.length > 0typeof slug === 'string' && slug.length > 0Array.isArray(nodes) && nodes.length > 0- (单节点流程可为空)
Array.isArray(connectors) - (每个节点id对应一个条目)
rationales && typeof rationales === 'object' && Object.keys(rationales).length === nodes.length
若任何断言失败,重新调度规划器一次,并在提示中回显具体缺失项()。若第二次失败,记录(,,,,),告知用户并停止操作。切勿静默合成缺失字段——第3阶段评审时丢失规划器自身的理由会导致信号丢失,且伪造的/会在未经规划器评审的情况下生效。
Your previous output was missing: name, rationales[3 of 5 nodes]. Re-emit the full envelope.agent-output-incompleteseverity: failurephase: P2agent: seeflow-node-plannerdetails: <missing-keys>summary: 规划器重试后仍返回不完整的框架文件nameslugPhase 3 — scaffold, populate, layout, review
第3阶段 — 搭建、填充、布局、评审
The skeleton flow lands via four steps, in order. No authoring by hand — writes the empty envelope for you. Run for each subcommand's body shape and flags.
flow.jsonprojects:create$SEEFLOW help <command>-
Scaffold + register inside the project via. This is the entry point for a new project: the CLI writes the empty
projects:createatflow.json(project root) and registers it in one shot.<repoPath>/flow.jsonExisting-flow gate — check before the CLI write. Test. If the file exists (ortest -f "$repoPath/flow.json"later returnsprojects:createexit code 4 because the pre-check raced), STOP and ask viaalreadyExists— never silently overwrite, never silently fall back:AskUserQuestionA SeeFlow flow is already registered at this path. What do you want to do?- Open the existing flow (Recommended) — skip creation; run to re-attach the existing envelope, surface
$SEEFLOW register --path "$repoPath", then stop. If the user wanted to inspect rather than edit, hand off to$STUDIO_URL/d/<slug>./seeflow-lookup - Create a new flow with a different name — ask the user for a new flow name, recompute , then retry this step (Phase 1/2 only rerun if the user's intent also changed).
$repoPath = $PWD/.seeflow/<new-slug> - Overwrite the existing flow — destructive. Confirm once more, then (and
$SEEFLOW flows:delete --path "$repoPath"for any sidecar leftovers), then retry this step.rm -rf "$repoPath"
Log oneper session (plan-revision,severity: friction,phase: P3). Debounce — even if the user toggles between options, the entry is written once.summary: existing flow at target path; user picked <open|rename|overwrite>Gate clear → forward the planner-supplied(andnameif the planner provided one):descriptionbash$SEEFLOW projects:create --path "$repoPath" --name "$plannerName" [--description "$plannerDescription"]The studio writes the envelope, adds a registry entry under, and returns~/.seeflow/registry.json(slug is derived from{ id, slug }). Capturenamefrom the response and use it (notid) for every follow-up CLI call below — several commands document slug support inslugbut the server only resolves by id today. Registration is a precondition for opening the canvas: thehelproute only works after this step succeeds, so never surface the canvas URL to the user before this step.$STUDIO_URL/d/<slug>Ifreturnsprojects:create(code 4) after the pre-check passed (filesystem race), loop back to the gate above and let the user decide — do not auto-fall-back. Do not hardcode the envelope shape from memory; if you need to inspect whatalreadyExistswrites, runprojects:create.$SEEFLOW schema flow - Open the existing flow (Recommended) — skip creation; run
-
Normalize the planner output: strip(keep them in memory for the review prompt below), then for the planner's designated trigger node (the one whose
rationalesis set even as a placeholder), inject the minimumdata.playActionpayload the contract requires so the server accepts the batch. Look up the exact required fields by runningplayActionand$SEEFLOW schema action(the$SEEFLOW schema nodeshape's required keys) — do not hardcode the shape from memory. Pick the interpreter fromPlayAction(falling back toruntimeProfile.primaryLanguage) and pointbunatscriptPath. The Phase 4 play-designer overwrites the placeholder with the real action viascripts/play.ts. The script file does not need to exist yet — Phase 5 writes it, Phase 6 runs it. 2a. Mint canonical ids. Planner ids are descriptive (nodes:patch,checkout-api); the studio's id producers (canvas, server auto-assign, the upload endpoint regex) usec-order-server-event-bus/node-<10 base62>. Rewrite at the boundary so flow.json matches. Use the CLI — it shares the exact alphabet and rejection-sampling logic with every other id producer in the studio:conn-<10 base62>bashmapfile -t nodeIds < <($SEEFLOW ids node "${#nodes[@]}") mapfile -t connIds < <($SEEFLOW ids connector "${#connectors[@]}")For eachthat already matchesnodes[i].id(edit-case reuse from^node-[A-Za-z0-9]{10}$), keep it; only mint new canonical ids for net-new nodes. Build aeditTargetmap and rewrite:descriptiveId → canonicalIdnodes[].id- ,
connectors[].id,connectors[].sourceconnectors[].target - keys (kept in memory for the review prompt) 2b. Log any silent corrections from steps 2 and 2a (see
rationales). For each correction kind that fired (placeholder-feedback.mdinjection, descriptive→canonical id rewrite, unknown-type rename, unknown-field rename, bidir-connector strip, user-to-system-rectangle retype, …), emit oneplayActionentry withagent-output-corrected,severity: corrected,phase: P3, andagent: seeflow-node-plannerwhere N is the count. Aggregate across nodes — never one entry per node. If no corrections were needed, log nothing. This is the signal that the planner drifted from the contract; without it, the orchestrator's silent patching is invisible.details: <correction-kind> (×N)
retype rule. If the planner shippeduser-to-system-rectanglefor a node whosetype:'user'is clearly a software system (data.name,Web UI,Mobile App,Browser,SPA,Desktop Client,CLI, anything ending inSDK/Client/App/UI/Frontend), silently retype toServicewithrectangleinferred from the name (data.iconfor web/UI/frontend,monitorfor mobile,smartphonefor CLI,terminalfor SDK/Client). Keepplugonly whentype:'user'is a human role (data.name,Customer,Support Agent,Reviewer,Approver). Log one aggregateOperatorentry withagent-output-corrected. The Phase 3 canvas review surfaces the result to the user — they see the correction.details: user-to-system-rectangle (×N) -
— atomic seed of nodes + connectors in one transactional write. Forward the normalized + id-rewritten
flow:add-bulkandnodesarrays asconnectors. Connectors may reference nodes from the same call — the server validates the merged graph as a whole, so a dangling source/target or a malformed node rolls back both arrays together. No two-phase commit to reason about; no orphan nodes if connectors fail.{ nodes, connectors } -
— run ELK and write
flows:layout.style.json
Each call validates server-side. A exit means feed the issues back to the planner and retry — no separate validation step.
badSchemaOpen the canvas, surface the planner's per node — prefix each with so the human sees a readable anchor despite the opaque id () — and ask one combined question (layout review + dynamic gate in a single round-trip — two consecutive waits is interrogation):
rationales<data.name> (<canonical id>):POST /orders (node-Ab12cd34Ef): Single HTTP service — internal routes are implementation detail.bash
URL="$STUDIO_URL/d/$slug"
(open "$URL" 2>/dev/null || xdg-open "$URL" 2>/dev/null || start "$URL" 2>/dev/null) &Opened the canvas at. Two quick questions:<url>
- Layout — any additions, removals, or renames?
- Dynamic or static — continue with Play scripts + Status probes so the canvas reacts to your running system, or stop with the static layout?
Wait once. Parse both answers from the reply.
- Layout changes requested → log (
plan-revision,severity: friction,phase: P3), re-run node-planner with the feedback, repeat the combined ask. The dynamic answer (if given) is remembered but not acted on until the layout is approved. Debounce — log once per session even if the user revises multiple times.summary: user requested layout changes at canvas review gate - Layout approved + dynamic → Phase 4. If the system-analyzer is still running, await it now; Phase 4 designers need its , fixtures, data-entry paths, and tech adaptations. Re-merge any new
runtimeProfilefirst.learnUpdates - Layout approved + static → print and stop. Still merge any pending
Flow "<name>" registered as <slug> (static). Open: $STUDIO_URL/d/<slug>.learnUpdates - Dynamic answer unclear or absent → default to static (dynamic writes executable scripts; opt-in). Log (
mode-fallback,severity: degraded,phase: P3,details: dynamic-to-static).summary: dynamic gate unclear; auto-downgraded to static
(Design-only mode from Phase 1's empty-project branch defaults to static here without re-asking.)
流程骨架通过四个步骤依次生成。禁止手动编写——会为你生成空框架文件。每个子命令的请求体格式和参数见。
flow.jsonprojects:create$SEEFLOW help <command>-
通过在项目内搭建并注册。这是创建新项目的入口:CLI在
projects:create(项目根目录)写入空<repoPath>/flow.json并完成注册。flow.json现有流程检查——CLI写入前执行。测试。若文件存在(或test -f "$repoPath/flow.json"因检查竞态返回projects:create退出码4),停止操作并通过alreadyExists询问用户——切勿静默覆盖,切勿静默回退:AskUserQuestion该路径已注册一个SeeFlow流程。你想要执行什么操作?- 打开现有流程(推荐)——跳过创建;运行重新关联现有框架文件,显示
$SEEFLOW register --path "$repoPath",然后停止。若用户想要检查而非编辑,转交至$STUDIO_URL/d/<slug>。/seeflow-lookup - 使用不同名称创建新流程——询问用户新流程名称,重新计算,然后重试此步骤(仅当用户意图改变时才重新运行第1/2阶段)。
$repoPath = $PWD/.seeflow/<new-slug> - 覆盖现有流程——破坏性操作。再次确认,然后执行(并执行
$SEEFLOW flows:delete --path "$repoPath"删除任何附属文件),然后重试此步骤。rm -rf "$repoPath"
每个会话记录一次(plan-revision,severity: friction,phase: P3)。去重——即使用户多次切换选项,仅记录一次。summary: 目标路径存在现有流程;用户选择<open|rename|overwrite>检查通过后,转发规划器提供的(若规划器提供了name也一并转发):descriptionbash$SEEFLOW projects:create --path "$repoPath" --name "$plannerName" [--description "$plannerDescription"]Studio写入框架文件,在中添加注册表条目,并返回~/.seeflow/registry.json(slug由{ id, slug }派生)。从响应中捕获name并在后续所有CLI调用中使用(而非id)——多个命令在slug中说明支持slug,但服务器目前仅通过id解析。注册是打开画布的前提:help路由仅在此步骤成功后生效,因此切勿在此步骤前向用户显示画布URL。$STUDIO_URL/d/<slug>若预检查通过后仍返回projects:create(代码4,文件系统竞态),回到上述检查步骤让用户决定——切勿自动回退。切勿凭记忆硬编码框架文件格式;若需要查看alreadyExists写入的内容,运行projects:create。$SEEFLOW schema flow - 打开现有流程(推荐)——跳过创建;运行
-
规范化规划器输出:删除(保留在内存中用于下文的评审提示),然后对于规划器指定的触发节点(
rationales已设置为占位符的节点),注入契约要求的最小data.playActionpayload,确保服务器接受批量操作。通过运行playAction和$SEEFLOW schema action($SEEFLOW schema node形状的必需键)查找确切的必需字段——切勿凭记忆硬编码形状。从PlayAction选择解释器(回退到runtimeProfile.primaryLanguage),并将bun指向scriptPath。第4阶段的Play设计器会通过scripts/play.ts用真实操作覆盖占位符。脚本文件无需提前存在——第5阶段会写入,第6阶段会运行。 2a. 生成标准id。规划器生成的id是描述性的(nodes:patch、checkout-api);Studio的id生成器(画布、服务器自动分配、上传端点正则)使用c-order-server-event-bus/node-<10位base62>格式。在边界处重写id,使flow.json匹配该格式。使用CLI——它与Studio中所有其他id生成器共享完全相同的字符集和拒绝采样逻辑:conn-<10位base62>bashmapfile -t nodeIds < <($SEEFLOW ids node "${#nodes[@]}") mapfile -t connIds < <($SEEFLOW ids connector "${#connectors[@]}")对于已匹配的^node-[A-Za-z0-9]{10}$(来自nodes[i].id的编辑复用),保留原id;仅为新增节点生成新的标准id。构建editTarget映射并重写:描述性id → 标准idnodes[].id- 、
connectors[].id、connectors[].sourceconnectors[].target - 的键(保留在内存中用于评审提示) 2b. 记录步骤2和2a中的任何静默修正(见
rationales)。对于每种触发的修正类型(占位符feedback.md注入、描述性id→标准id重写、未知类型重命名、未知字段重命名、双向连接器删除、用户节点→系统矩形重命名等),记录一条playAction条目,参数为agent-output-corrected、severity: corrected、phase: P3、agent: seeflow-node-planner(N为数量)。按节点聚合——切勿为每个节点记录一条。若无需修正,无需记录。这是规划器偏离契约的信号;若无此记录,编排器的静默修补将不可见。details: <correction-kind> (×N)
用户节点→系统矩形重命名规则。若规划器为明显是软件系统的节点(data.name、Web UI、Mobile App、Browser、SPA、Desktop Client、CLI、任何以SDK/Client/App/UI/Frontend结尾的名称)设置了Service,静默将其重命名为type:'user'类型,并根据名称推断rectangle(web/UI/frontend对应data.icon,mobile对应monitor,CLI对应smartphone,SDK/Client对应terminal)。仅当plug是人类角色(data.name、Customer、Support Agent、Reviewer、Approver)时保留Operator。记录一条聚合的type:'user'条目,参数为agent-output-corrected。第3阶段的画布评审会将结果展示给用户——用户会看到修正后的内容。details: user-to-system-rectangle (×N) -
—— 原子性批量写入节点 + 连接器。将规范化并完成id重写的
flow:add-bulk和nodes数组作为connectors转发。连接器可引用本次调用中的节点——服务器会整体验证合并后的图,因此悬空的源/目标或格式错误的节点会回滚两个数组。无需考虑两阶段提交;若连接器失败,不会产生孤立节点。{ nodes, connectors } -
—— 运行ELK算法并写入
flows:layout。style.json
每个调用都会在服务端验证。若返回退出码,将问题反馈给规划器并重试——无需单独的验证步骤。
badSchema打开画布,按节点展示规划器的——每个条目前缀为,以便用户在id不透明的情况下看到可读的锚点(例如)——并询问一个合并后的问题(布局评审 + 动态分支选择合并为一次往返——连续两次等待会让用户感到被审问):
rationales<data.name> (<标准id>):POST /orders (node-Ab12cd34Ef): 单个HTTP服务——内部路由是实现细节。bash
URL="$STUDIO_URL/d/$slug"
(open "$URL" 2>/dev/null || xdg-open "$URL" 2>/dev/null || start "$URL" 2>/dev/null) &已在<url>打开画布。两个快速问题:
- 布局——是否需要添加、删除或重命名节点?
- 动态或静态——继续添加Play脚本 + Status探针使画布能响应运行中的系统,还是停止并保留静态布局?
等待一次回复。从回复中解析两个问题的答案。
- 用户要求修改布局 → 记录(
plan-revision,severity: friction,phase: P3),将反馈转发给节点规划器重新运行,重复合并询问。动态选择的答案(若已提供)会被记住,但需等到布局批准后才生效。去重——即使用户多次修改,每个会话仅记录一次。summary: 用户在画布评审阶段要求修改布局 - 布局批准 + 动态模式 → 进入第4阶段。若系统分析器仍在运行,等待其完成;第4阶段设计器需要其、测试数据、数据输入路径和技术适配信息。先合并任何新的
runtimeProfile。learnUpdates - 布局批准 + 静态模式 → 打印并停止操作。仍需合并任何待处理的
Flow "<name>" 已注册为<slug>(静态)。打开:$STUDIO_URL/d/<slug>。learnUpdates - 动态选择答案不明确或未提供 → 默认采用静态模式(动态模式会写入可执行脚本;需用户主动选择)。记录(
mode-fallback,severity: degraded,phase: P3,details: dynamic-to-static)。summary: 动态分支选择不明确;自动降级为静态模式
(第1阶段空项目分支的仅设计模式在此处默认采用静态模式,无需再次询问。)
Phase 4 — design Play + Status (parallel)
第4阶段 — 设计Play + Status(并行)
Launch + in parallel (Phase 1 rule). Both receive: context brief, node draft, edit target, tech-ref paths, matching . They read each ref's Play / Status section and treat as the project override. Tools: .
seeflow-play-designerseeflow-status-designertechAdaptationstechAdaptationsRead, Grep, Glob, LSLook up the action + node contract from the CLI first. Run and (parallel; one message, two Bash calls) and capture both outputs. Pass them to each designer alongside the brief — designers have no shell, so what you don't forward, they don't know. The same outputs serve both designers; reuse them. Skipping this step lets the designer invent fields the CLI rejects on , burning a retry.
$SEEFLOW schema action$SEEFLOW schema nodenodes:patchOutput shape (both): triples. is the exact body for . is project-root-relative (); inside is node-folder-relative (). Full contracts: , .
{ nodeId, patch, scriptFile: {path, body, chmod}, validationSafe?, rationale }patchseeflow nodes:patchscriptFile.pathnodes/<nodeId>/scripts/<name>playAction.scriptPathpatchscripts/play.tsagents/seeflow-play-designer.mdagents/seeflow-status-designer.mdSample data priority: integration/e2e fixtures (, copy verbatim) → seed / migration / ORM factories → README / OpenAPI / Postman examples → invent last, note in .
runtimeProfile.integrationTestDirrationalenewTriggerNodes{nodes, connectors}并行启动 + (遵循第1阶段规则)。两者均接收:上下文概要、节点草稿、编辑目标、技术引用路径、匹配的。它们会读取每个引用的Play / Status章节,并将作为项目覆盖规则。工具:。
seeflow-play-designerseeflow-status-designertechAdaptationstechAdaptationsRead, Grep, Glob, LS首先从CLI获取操作 + 节点的契约。并行运行和(一条消息,两个Bash调用)并捕获输出。将输出与概要一起传递给每个设计器——设计器无shell权限,未转发的信息它无法获取。同一输出可用于两个设计器;复用即可。跳过此步骤会导致设计器生成CLI在时拒绝的字段,浪费重试机会。
$SEEFLOW schema action$SEEFLOW schema nodenodes:patch输出格式(两者相同):三元组。是的精确请求体。是相对于项目根目录的路径();内的是相对于节点文件夹的路径()。完整契约见、。
{ nodeId, patch, scriptFile: {path, body, chmod}, validationSafe?, rationale }patchseeflow nodes:patchscriptFile.pathnodes/<nodeId>/scripts/<name>patchplayAction.scriptPathscripts/play.tsagents/seeflow-play-designer.mdagents/seeflow-status-designer.md测试数据优先级: 集成/端到端测试数据(,原样复制) → 种子/迁移/ORM工厂 → README/OpenAPI/Postman示例 → 最后才自行生成,并在中说明。
runtimeProfile.integrationTestDirrationalenewTriggerNodes{nodes, connectors}Phase 5 — patch overlays + layout
第5阶段 — 修补覆盖层 + 布局
For each overlay returned by Phase 4 (parallelise the writes when the script bodies don't depend on each other):
- Write to
scriptFile.body(Write tool).scriptFile.path - per
chmod(default 755).scriptFile.chmod - Call with the overlay's
nodes:patchbody. (Body shape:patch.)$SEEFLOW help nodes:patch
If the play-designer emitted , batch them via (one call, both arrays atomic), then re-run . (Body shape: .)
newTriggerNodesflow:add-bulkflows:layout$SEEFLOW help flow:add-bulkEdit-case retype routing. When the Phase 2 diff against flags a node whose already exists but whose changed (e.g. a former trigger reshaped to a decorative ), route it through — not + . The patch path preserves the per-node folder under ; the delete cascade destroys it. The server validates required fields for the new type after the merge (e.g. needs , needs , accepts an optional string); a exit means feed the issues to the play-designer and retry.
editTargetidtyperectangledatabasenodes:patch { type, ...required fields }nodes:deleteflow:add-bulknodes/<id>/* → imagepath* → iconicon* → htmlhtmlbadSchemaRetry budget: per-node failure → re-dispatch that one designer with the CLI's reported issues, retry, max 3 per node. Parallelise re-dispatches when more than one node failed (Phase 1 rule). When the budget is exhausted for a node, log (, , (or the actual code), ). Aggregate across nodes — one entry per (kind, code) pair, not one per node.
nodes:patchretry-exhaustedseverity: failurephase: P5code: badSchemasummary: nodes:patch retries exhausted on <kind> (N nodes)对于第4阶段返回的每个覆盖层(当脚本内容互不依赖时并行写入):
- 将写入
scriptFile.body(使用Write工具)。scriptFile.path - 按设置权限(默认755)。
scriptFile.chmod - 使用覆盖层的请求体调用
patch。(请求体格式见nodes:patch。)$SEEFLOW help nodes:patch
若Play设计器输出了,通过批量添加(一次调用,原子性写入两个数组),然后重新运行。(请求体格式见。)
newTriggerNodesflow:add-bulkflows:layout$SEEFLOW help flow:add-bulk编辑场景下的类型重命名路由。当第2阶段与的差异标记显示某个节点的已存在但已更改(例如原触发节点改为装饰性),通过处理——禁止使用 + 。修补路径会保留下的节点文件夹;删除操作会级联销毁该文件夹。服务器会在合并后验证新类型的必需字段(例如需要,需要,接受可选的字符串);若返回退出码,将问题反馈给Play设计器并重试。
editTargetidtyperectangledatabasenodes:patch { type, ...required fields }nodes:deleteflow:add-bulknodes/<id>/* → imagepath* → iconicon* → htmlhtmlbadSchema重试预算: 按节点的失败 → 重新调度该节点对应的设计器并传入CLI报告的问题,重试,每个节点最多3次。当多个节点失败时并行重新调度(遵循第1阶段规则)。当某个节点的重试预算耗尽,记录(,,(或实际错误码),)。按节点聚合——每个(类型,错误码)对记录一条,而非每个节点一条。
nodes:patchretry-exhaustedseverity: failurephase: P5code: badSchemasummary: nodes:patch在<kind>上重试耗尽(N个节点)Phase 6 — end-to-end validation
第6阶段 — 端到端验证
Must run. Do not skip or simulate.
Run the subcommand for the flow. Pass with the s of any Phase 4 overlays whose (third-party or paid actions); skipped nodes appear in , not as failures. Body / flag details: .
e2e--skip-nodesnodeIdvalidationSafe === falseskipped[]$SEEFLOW help e2eok: trueFlow "<name>" registered as <slug>. Open: $STUDIO_URL/d/<slug>rm -rf "$SEEFLOW_TMP"ok: false- Identify failing nodes from /
plays[*].error.statuses[*].outcome - Parallel fix-up (Phase 1 rule): one sub-agent per failing script, single message. A single agent fixing N scripts cross-contaminates.
- Each agent gets the script path (under ), the specific error payload, and a concrete fix hypothesis (
nodes/<nodeId>/scripts/).play.ts: ECONNREFUSED on :3001 — start the app first - Edit in-place, re-run the subcommand. Max 2 retries, then log
e2e(seeflow:e2e-fail,severity: failure,phase: P6,details: <N> failing scripts after fix-up) and ask retry / stop.summary: e2e ok:false after retry budget exhausted
If the run is design-only (Phase 1 fallback), skip Phase 6 entirely and log (, , , ).
phase-skippedseverity: degradedphase: P6details: design-onlysummary: e2e skipped — no runtime to validate against必须运行。禁止跳过或模拟。
运行流程的子命令。对于第4阶段覆盖层中的节点(第三方或付费操作),传入参数指定其;跳过的节点会出现在中,不会被标记为失败。请求体/参数细节见。
e2evalidationSafe === false--skip-nodesnodeIdskipped[]$SEEFLOW help e2eok: trueFlow "<name>" 已注册为<slug>。打开:$STUDIO_URL/d/<slug>rm -rf "$SEEFLOW_TMP"ok: false- 从/
plays[*].error中识别失败节点。statuses[*].outcome - 并行修复(遵循第1阶段规则):每个故障脚本对应一个子Agent,一条消息。单个Agent修复N个脚本会导致上下文交叉污染。
- 每个Agent会收到脚本路径(位于下)、具体错误payload和明确的修复假设(例如
nodes/<nodeId>/scripts/)。play.ts: ECONNREFUSED on :3001 — 先启动应用 - 就地编辑,重新运行子命令。最多重试2次,然后记录
e2e(seeflow:e2e-fail,severity: failure,phase: P6,details: <N>个脚本修复后仍失败)并询问用户是否重试/停止。summary: 重试预算耗尽后端到端验证ok:false
若为仅设计模式(第1阶段回退),完全跳过第6阶段并记录(,,,)。
phase-skippedseverity: degradedphase: P6details: design-onlysummary: 跳过端到端验证——无运行时可验证Polish LEARN.md with anything learned
用新发现的内容完善LEARN.md
If Phases 5-6 surfaced something the next run would want — port mismatch, fixture path, missed env var, working seed command, useful data-entry path — append to ( bullet or the relevant section). Also append the flow to the "Flows already created" table with today's date and a one-line purpose. Skip if nothing new — empty updates are noise. The file is shared across every flow in this host, so the table accumulates every flow the skill has ever scaffolded here.
$learnPathGotchasTech-specific learnings (a helper, a required attribute, an emulator quirk, a fixture path) go in → , not just . If the code-analyzer missed a tech entirely, also append the to . This is what makes the next run reuse the work.
## Tech stack adaptations### <techId>## GotchastechId## Tech stack/seeflow若第5-6阶段发现了下次运行需要的信息——端口不匹配、测试数据路径、遗漏的环境变量、可用的种子命令、有用的数据输入路径——追加到(项目符号或相关章节)。同时将该流程追加到“已创建流程”表格中,包含日期和一行说明。若无新内容则跳过——空更新是冗余信息。该文件由宿主仓库中所有流程共享,因此表格会累积本技能在此处搭建的所有流程。
$learnPathGotchas技术特定的经验(助手、必需属性、模拟器 quirks、测试数据路径)应放入 → ,而非仅放入。若代码分析器完全遗漏了某项技术,还需将追加到中。这能让下次运行复用已有工作。
## Tech stack adaptations### <techId>## GotchastechId## Tech stack/seeflowOperations
操作参考
| Topic | File |
|---|---|
CLI resolver + discovery via | |
| Error handling, retry caps, sub-agent table | |
| Per-node file convention, action runtime budgets, when-to-use guidance | |
| Core rules | |
| |
| Tech-specific best practices | |
| Sub-agent prompts | |
| Feedback collection — consent, kinds, format, redaction, hook handoff | |
| Canonical id generator | |
| 主题 | 文件 |
|---|---|
CLI解析器 + 通过 | |
| 错误处理、重试上限、子Agent表格 | |
| 按节点的文件约定、操作运行时预算、使用场景指南 | |
| 核心规则 | |
| |
| 技术特定最佳实践 | |
| 子Agent提示 | |
| 反馈收集——授权、类型、格式、脱敏、钩子转交 | |
| 标准id生成器 | |