[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6D9SJPWXDKPJVWSJD2WANZX":3,"skill-same:01M6D9SJPWXDKPJVWSJD2WANZX":63},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":25,"publishedAt":36,"linkOnly":37,"markdownContent":38,"markdownBody":39,"frontMatter":40,"refName":41,"commitSha":42,"skillDirectory":43,"forksCount":44,"repositoryHtmlUrl":45,"repositoryHomepageUrl":46,"ownerHtmlUrl":47,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":48,"install":49,"resources":62},"01M6D9SJPWXDKPJVWSJD2WANZX","e2e",null,"E2E agent testing with fflow verify — write test plans (gen), run them (run), or diagnose failures (fix). Dispatch via positional arg.","freematters\u002Ffreematters","freematters","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F266749953?v=4","01M6D9S9REGCVDFCTZ7BM853DS","01M6D9S9WY29PTMRNB7X58QGTP",27,"MIT","https:\u002F\u002Fgithub.com\u002Ffreematters\u002Ffreematters\u002Fblob\u002Fmain\u002Fpackages\u002Ffreeflow\u002Fskills\u002Fe2e\u002FSKILL.md",[17,22],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[5,26,27,28,29,30,31,32,33,34,35],"testing","test","diagnose","run","verify","write","fix","dispatch","agent testing","plans","2026-11-10 10:12:30",false,"---\nname: e2e\ndescription: E2E agent testing with fflow verify — write test plans (gen), run them (run), or diagnose failures (fix). Dispatch via positional arg.\n---\n\n# E2E Agent Testing\n\nDispatch on the first positional arg:\n\n- `gen [target]` — write a new e2e test plan to `.\u002Fe2e\u002F` (see [§ gen](#gen))\n- `run \u003Cplan.md> [--test-dir \u003Cpath>] [--model \u003Cm>] [--verbose]` — execute a plan with `fflow verify` (see [§ run](#run))\n- `fix [run-dir]` — diagnose a failed run and fix the code (see [§ fix](#fix))\n\nIf the user did not provide a subcommand, ask which mode they want before proceeding.\n\n---\n\n## gen\n\nWrite an e2e agent test plan for `fflow verify`.\n\n### Overview\n\n`fflow verify` is a generic e2e testing framework built on the **verifier–executor model**\n(see `packages\u002Ffreeflow\u002Fdocs\u002Fe2e-testing-design.md`):\n\n- **Verifier** — the outer agent. Reads the test plan, launches the executor, provides input\n  via `send()`, observes output via `wait()`, and judges pass\u002Ffail.\n- **Executor** — the inner agent. Operates the software under test. It acts as the universal\n  adapter — it can start servers, run CLI commands, interact with UIs, call APIs.\n\nEverything is agent. The executor IS the user of the software.\n\nTest plans should be written to `.\u002Fe2e\u002F` by convention (e.g. `.\u002Fe2e\u002Fmy-feature.md`),\nor to `.\u002Fspecs\u002F\u003Cslug>\u002Fe2e.md` when part of a spec-gen\u002Fspec-to-code workflow.\n\n### Before Writing: Explore the Codebase\n\nBefore generating a test plan, you MUST explore the project for:\n\n1. **Existing test infrastructure** — look for test directories, test configs, CI scripts,\n   existing e2e tests, and testing frameworks already in use.\n2. **How to build and run the software** — check README, CLAUDE.md\u002FAGENTS.md, package.json,\n   Makefile, etc. for build commands, dev servers, and test commands.\n3. **Environment requirements** — env vars, services (databases, APIs), fixtures, seed data.\n4. **Existing e2e test plans** in `.\u002Fe2e\u002F` — follow their patterns and conventions.\n\nThis exploration informs the Setup section and ensures the executor knows how to operate\nthe software correctly.\n\n### Test Plan Format\n\nThe parser enforces this structure:\n\n```markdown\n# Test: \u003CDescriptive Name>\n\n\u003CBrief description of what this test verifies.>\n\n## Background\n\n\u003CExplain what the executor agent is expected to do — behavior, expected input\u002Foutput.\nThe verifier agent does NOT know the internals. This section is critical.>\n\n## Setup\n\nThe verifier executes this section BEFORE launching the executor.\n\n- Executor prompt: \u003Cthe initial prompt sent to the executor agent via run_agent()>\n- \u003Cprerequisites — files to create, build steps, env setup, services to start, etc.>\n\nThe executor prompt MUST include enough context for the executor to operate the software:\n- What the software is and how to use it\n- Relevant skills, commands, or workflows available\n- Environment details (working directory, config files, available tools)\n- What the executor should NOT do (e.g., \"do not modify production data\")\n\n## Steps\n1. **\u003CStep Name>**: \u003CWhat to do — observe output, provide input, verify behavior>\n   - Expected: \u003CWhat the executor agent should do>\n2. **\u003CStep Name>**: \u003CDescription>\n   - Expected: \u003CExpected behavior>\n\n## Expected Outcomes\n- \u003CHigh-level outcome when all steps pass>\n\n## Timeout Strategy\n\n| Phase | Suggested wait timeout |\n|-------|----------------------|\n| Agent startup \u002F initial output | 60s |\n| Simple state transition | 30s |\n| Agent processing with tool calls | 60-120s |\n\n## Cleanup\n\nThe verifier executes this section AFTER all steps complete (pass or fail).\nCleanup MUST ensure no leftover side effects:\n\n- Kill any processes started during the test (servers, watchers, background jobs)\n- Remove created files, directories, and temp data\n- Tear down any services or containers started in Setup\n- Reset environment variables modified during the test\n- Remove any database entries or state created during the test\n```\n\n#### Parser Rules\n\n- `## Steps` and `## Expected Outcomes` are **required**\n- Steps must be numbered (`1.`, `2.`, etc.)\n- Step names must be **bold** followed by `:` — e.g. `1. **Start workflow**: ...`\n- Each step needs `- Expected:` on the next line\n- `## Background`, `## Timeout Strategy`, `## Cleanup` are optional but recommended\n\n### Setup Section: Configuring the Executor\n\nThe Setup section tells the verifier how to prepare the environment and launch the executor.\nThe executor prompt is the single most important element — it determines whether the executor\ncan successfully operate the software.\n\n#### Executor Prompt Best Practices\n\nThe executor is a full Claude Code session with no prior context. The prompt must be\nself-contained:\n\n```markdown\n# Good — executor has full context\n- Executor prompt: |\n    You are testing a CLI tool called `fflow`. The CLI is built at `packages\u002Ffreeflow\u002Fdist\u002Fcli.js`.\n    Start a workflow by running: node packages\u002Ffreeflow\u002Fdist\u002Fcli.js start workflows\u002Fsimple.workflow.yaml --run-id test-1\n    Then transition through all states until done.\n\n# Bad — executor has no idea what to do\n- Executor prompt: `\u002Ffflow simple.workflow.yaml`\n```\n\nFor simple cases (skills, slash commands) a short prompt is fine. For complex software,\ninclude operating instructions.\n\n#### Prerequisites\n\nList anything the verifier needs to prepare before launching the executor:\n\n- **Build steps**: `npm run build`, compile commands — run these BEFORE `run_agent()`\n- **Files to create**: test fixtures, config files, seed data\n- **Services to start**: dev servers, databases, mock APIs — start and verify they're ready\n- **Environment**: env vars to set, working directory requirements\n- **Dependencies**: tools that must be installed, packages to verify\n\n#### Examples by Software Type\n\n##### Workflow Tests\n\n```markdown\n## Setup\n- Ensure fflow CLI is built: `npm run build` in `packages\u002Ffreeflow\u002F`\n- Executor prompt: `\u002Ffflow path\u002Fto\u002Fworkflow.workflow.yaml`\n```\n\n##### CLI Tool Tests\n\n```markdown\n## Setup\n- Build the CLI: `npm run build`\n- Create test input file at `\u002Ftmp\u002Ftest-input.json` with: `{\"key\": \"value\"}`\n- Executor prompt: |\n    Run the CLI tool: node dist\u002Fcli.js process \u002Ftmp\u002Ftest-input.json --format yaml\n    Report the output and exit code.\n```\n\n##### Web Application Tests\n\n```markdown\n## Setup\n- Install dependencies: `npm install`\n- Start dev server: `npm run dev` (verify port 3000 is listening)\n- Executor prompt: |\n    A web application is running at http:\u002F\u002Flocalhost:3000.\n    Use curl or fetch to interact with the API endpoints.\n    Test the user registration flow: POST \u002Fapi\u002Fregister, then GET \u002Fapi\u002Fprofile.\n\n## Cleanup\n- Stop the dev server (kill the process on port 3000)\n- Remove any test database entries\n```\n\n##### Multi-Turn Conversation Tests\n\nStart with an initial prompt, then use `send()` in steps to continue:\n\n```markdown\n## Setup\n- Create `src\u002Fmain.ts` with a function that needs refactoring\n- Executor prompt: `Help me refactor the function in src\u002Fmain.ts`\n\n## Steps\n1. **Initial analysis**: Wait for executor to analyze the code\n   - Expected: Executor identifies the function and suggests refactoring approach\n2. **Approve refactoring**: Send \"yes, go ahead with that approach\" to the executor\n   - Expected: Executor applies the refactoring and shows the diff\n```\n\n### Writing Good Test Plans\n\n#### Background Section\n\nThe most important section. The verifier has no prior knowledge. Explain:\n\n- What the executor is expected to do when given the prompt\n- What input the executor might request (so the verifier knows when to `send()`)\n- What output the executor produces at each stage\n- For workflows: states, transitions, and expected behavior per state\n\n#### Steps Describe Interactions, Not CLI Commands\n\nSteps tell the verifier how to interact with the executor via `wait()` and `send()`:\n\n```markdown\n# Good — describes agent interaction\n1. **Start the workflow**: Start the executor and wait for initial output\n   - Expected: Executor initializes in \"gather\" state and asks for user input\n2. **Provide input**: Send \"my-project\" when the executor asks for a project name\n   - Expected: Executor acknowledges the name and transitions to \"generate\" state\n\n# Bad — describes CLI commands\n1. **Start the workflow**: Run `fflow start my.workflow.yaml --run-id test`\n   - Expected: Exit code 0\n```\n\n#### Expected Should Be Specific\n\n```markdown\n# Good\n- Expected: Output includes today's date in YYYY-MM-DD format\n\n# Bad\n- Expected: Should work correctly\n```\n\n#### Cleanup Should Be Thorough\n\nThe shared sandbox persists across tests. Leftover processes, files, or state from one\ntest can cause the next test to fail or behave unexpectedly.\n\n```markdown\n# Good — explicit cleanup\n## Cleanup\n- Kill the dev server: `kill $(lsof -ti:3000)` or equivalent\n- Remove test fixtures: `rm -rf \u002Ftmp\u002Ftest-workspace`\n- Remove created database: `dropdb test_db`\n\n# Bad — no cleanup or vague\n## Cleanup\n- Clean up test files\n```\n\n### Examples\n\n#### Workflow Test\n\n```markdown\n# Test: Simple workflow lifecycle\n\n## Background\n\nThe simple workflow has two states: \"start\" and \"done\".\nFrom \"start\", the executor should transition to \"done\" via the \"next\" transition.\nThe workflow completes when reaching \"done\" (terminal state with no transitions).\n\n## Setup\n- Executor prompt: `\u002Ffflow e2e\u002Fsimple.workflow.yaml`\n\n## Steps\n1. **Start workflow**: Wait for the executor to initialize\n   - Expected: Run initializes successfully in \"start\" state\n2. **Verify completion**: Wait for the executor to transition through the workflow\n   - Expected: Executor reaches \"done\" state and workflow completes\n\n## Expected Outcomes\n- Workflow starts in initial state and transitions to done\n- The full lifecycle works end-to-end\n```\n\n#### General Agent Behavior (Non-Workflow)\n\n```markdown\n# Test: Agent creates a file with correct content\n\n## Background\n\nWhen asked to create a greeting module, the executor should use the Write tool\nto create a TypeScript file that exports a greet function. This tests basic\nagent file creation behavior, not a workflow.\n\n## Setup\n- Executor prompt: `Create a file src\u002Fgreet.ts that exports a function greet(name: string): string which returns \"Hello, \u003Cname>!\"`\n\n## Steps\n1. **Wait for executor to create file**: Wait for the executor to complete\n   - Expected: Executor uses the Write tool to create src\u002Fgreet.ts\n2. **Verify file content**: Send \"Read src\u002Fgreet.ts and show me the content\"\n   - Expected: File contains a greet function that takes a name parameter and returns a greeting string\n\n## Expected Outcomes\n- src\u002Fgreet.ts is created with the correct function signature\n- The function returns the expected greeting format\n\n## Cleanup\n- Remove src\u002Fgreet.ts\n```\n\n### Common Mistakes\n\n| Mistake | Fix |\n|---------|-----|\n| Skipping codebase exploration | MUST explore existing tests, build setup, and env before writing |\n| Missing Background section | Always explain expected behavior — verifier has no context |\n| Executor prompt lacks context | Include how to build, run, and operate the software |\n| Steps reference CLI directly | Describe agent interactions via wait\u002Fsend, not shell commands |\n| Vague expected outcomes | Be specific: what text, what state, what behavior |\n| No timeout guidance | Add Timeout Strategy table — prevents flaky hangs |\n| Steps not numbered | Parser requires `1.`, `2.`, etc. |\n| Step name not bold | Must use `**Name**:` format |\n| Missing `- Expected:` line | Each step requires expected on the next line |\n| Assuming verifier knows the executor | Background must explain what the executor does |\n| No cleanup or vague cleanup | List every process, file, and service to tear down |\n| Leftover processes after test | Always kill servers\u002Fwatchers started in Setup |\n\n---\n\n## run\n\nRun an existing e2e test plan through the `fflow verify` workflow.\n\nShell out to:\n\n```bash\nfflow verify \u003Cplan.md> --test-dir \u003Cpath> [--model \u003Cmodel>] [--verbose]\n```\n\nIf no test plan is specified, invoke `\u002Fe2e gen` first to write one to `.\u002Fe2e\u002F`, then run it.\n\nExit codes: `0` pass, `2` fail. Report written to `\u003Ctest-dir>\u002Ftest-report.md`.\n\n---\n\n## fix\n\nDiagnose a failed `fflow verify` run and repair the code.\n\n### Process\n\n1. If the user specifies a failed run directory or test-dir, go directly to step 2.\n2. If no failed run is specified, the user should describe what to test. Invoke `\u002Fe2e run` first\n   to generate (via `\u002Fe2e gen`) and execute a test plan. If it fails, use the resulting\n   run directory for step 2.\n3. Read the run-dir artifacts (`test-report.md`, `verifier-session.jsonl`,\n   `executor-session.jsonl`, the copied test plan) and diagnose the failure.\n4. Write a deterministic shell script that reproduces the failure from the session logs.\n5. Fix the code so the reproduction passes.\n6. Re-run via `\u002Fe2e run` with the original plan to confirm the fix.\n","# E2E Agent Testing\n\nDispatch on the first positional arg:\n\n- `gen [target]` — write a new e2e test plan to `.\u002Fe2e\u002F` (see [§ gen](#gen))\n- `run \u003Cplan.md> [--test-dir \u003Cpath>] [--model \u003Cm>] [--verbose]` — execute a plan with `fflow verify` (see [§ run](#run))\n- `fix [run-dir]` — diagnose a failed run and fix the code (see [§ fix](#fix))\n\nIf the user did not provide a subcommand, ask which mode they want before proceeding.\n\n---\n\n## gen\n\nWrite an e2e agent test plan for `fflow verify`.\n\n### Overview\n\n`fflow verify` is a generic e2e testing framework built on the **verifier–executor model**\n(see `packages\u002Ffreeflow\u002Fdocs\u002Fe2e-testing-design.md`):\n\n- **Verifier** — the outer agent. Reads the test plan, launches the executor, provides input\n  via `send()`, observes output via `wait()`, and judges pass\u002Ffail.\n- **Executor** — the inner agent. Operates the software under test. It acts as the universal\n  adapter — it can start servers, run CLI commands, interact with UIs, call APIs.\n\nEverything is agent. The executor IS the user of the software.\n\nTest plans should be written to `.\u002Fe2e\u002F` by convention (e.g. `.\u002Fe2e\u002Fmy-feature.md`),\nor to `.\u002Fspecs\u002F\u003Cslug>\u002Fe2e.md` when part of a spec-gen\u002Fspec-to-code workflow.\n\n### Before Writing: Explore the Codebase\n\nBefore generating a test plan, you MUST explore the project for:\n\n1. **Existing test infrastructure** — look for test directories, test configs, CI scripts,\n   existing e2e tests, and testing frameworks already in use.\n2. **How to build and run the software** — check README, CLAUDE.md\u002FAGENTS.md, package.json,\n   Makefile, etc. for build commands, dev servers, and test commands.\n3. **Environment requirements** — env vars, services (databases, APIs), fixtures, seed data.\n4. **Existing e2e test plans** in `.\u002Fe2e\u002F` — follow their patterns and conventions.\n\nThis exploration informs the Setup section and ensures the executor knows how to operate\nthe software correctly.\n\n### Test Plan Format\n\nThe parser enforces this structure:\n\n```markdown\n# Test: \u003CDescriptive Name>\n\n\u003CBrief description of what this test verifies.>\n\n## Background\n\n\u003CExplain what the executor agent is expected to do — behavior, expected input\u002Foutput.\nThe verifier agent does NOT know the internals. This section is critical.>\n\n## Setup\n\nThe verifier executes this section BEFORE launching the executor.\n\n- Executor prompt: \u003Cthe initial prompt sent to the executor agent via run_agent()>\n- \u003Cprerequisites — files to create, build steps, env setup, services to start, etc.>\n\nThe executor prompt MUST include enough context for the executor to operate the software:\n- What the software is and how to use it\n- Relevant skills, commands, or workflows available\n- Environment details (working directory, config files, available tools)\n- What the executor should NOT do (e.g., \"do not modify production data\")\n\n## Steps\n1. **\u003CStep Name>**: \u003CWhat to do — observe output, provide input, verify behavior>\n   - Expected: \u003CWhat the executor agent should do>\n2. **\u003CStep Name>**: \u003CDescription>\n   - Expected: \u003CExpected behavior>\n\n## Expected Outcomes\n- \u003CHigh-level outcome when all steps pass>\n\n## Timeout Strategy\n\n| Phase | Suggested wait timeout |\n|-------|----------------------|\n| Agent startup \u002F initial output | 60s |\n| Simple state transition | 30s |\n| Agent processing with tool calls | 60-120s |\n\n## Cleanup\n\nThe verifier executes this section AFTER all steps complete (pass or fail).\nCleanup MUST ensure no leftover side effects:\n\n- Kill any processes started during the test (servers, watchers, background jobs)\n- Remove created files, directories, and temp data\n- Tear down any services or containers started in Setup\n- Reset environment variables modified during the test\n- Remove any database entries or state created during the test\n```\n\n#### Parser Rules\n\n- `## Steps` and `## Expected Outcomes` are **required**\n- Steps must be numbered (`1.`, `2.`, etc.)\n- Step names must be **bold** followed by `:` — e.g. `1. **Start workflow**: ...`\n- Each step needs `- Expected:` on the next line\n- `## Background`, `## Timeout Strategy`, `## Cleanup` are optional but recommended\n\n### Setup Section: Configuring the Executor\n\nThe Setup section tells the verifier how to prepare the environment and launch the executor.\nThe executor prompt is the single most important element — it determines whether the executor\ncan successfully operate the software.\n\n#### Executor Prompt Best Practices\n\nThe executor is a full Claude Code session with no prior context. The prompt must be\nself-contained:\n\n```markdown\n# Good — executor has full context\n- Executor prompt: |\n    You are testing a CLI tool called `fflow`. The CLI is built at `packages\u002Ffreeflow\u002Fdist\u002Fcli.js`.\n    Start a workflow by running: node packages\u002Ffreeflow\u002Fdist\u002Fcli.js start workflows\u002Fsimple.workflow.yaml --run-id test-1\n    Then transition through all states until done.\n\n# Bad — executor has no idea what to do\n- Executor prompt: `\u002Ffflow simple.workflow.yaml`\n```\n\nFor simple cases (skills, slash commands) a short prompt is fine. For complex software,\ninclude operating instructions.\n\n#### Prerequisites\n\nList anything the verifier needs to prepare before launching the executor:\n\n- **Build steps**: `npm run build`, compile commands — run these BEFORE `run_agent()`\n- **Files to create**: test fixtures, config files, seed data\n- **Services to start**: dev servers, databases, mock APIs — start and verify they're ready\n- **Environment**: env vars to set, working directory requirements\n- **Dependencies**: tools that must be installed, packages to verify\n\n#### Examples by Software Type\n\n##### Workflow Tests\n\n```markdown\n## Setup\n- Ensure fflow CLI is built: `npm run build` in `packages\u002Ffreeflow\u002F`\n- Executor prompt: `\u002Ffflow path\u002Fto\u002Fworkflow.workflow.yaml`\n```\n\n##### CLI Tool Tests\n\n```markdown\n## Setup\n- Build the CLI: `npm run build`\n- Create test input file at `\u002Ftmp\u002Ftest-input.json` with: `{\"key\": \"value\"}`\n- Executor prompt: |\n    Run the CLI tool: node dist\u002Fcli.js process \u002Ftmp\u002Ftest-input.json --format yaml\n    Report the output and exit code.\n```\n\n##### Web Application Tests\n\n```markdown\n## Setup\n- Install dependencies: `npm install`\n- Start dev server: `npm run dev` (verify port 3000 is listening)\n- Executor prompt: |\n    A web application is running at http:\u002F\u002Flocalhost:3000.\n    Use curl or fetch to interact with the API endpoints.\n    Test the user registration flow: POST \u002Fapi\u002Fregister, then GET \u002Fapi\u002Fprofile.\n\n## Cleanup\n- Stop the dev server (kill the process on port 3000)\n- Remove any test database entries\n```\n\n##### Multi-Turn Conversation Tests\n\nStart with an initial prompt, then use `send()` in steps to continue:\n\n```markdown\n## Setup\n- Create `src\u002Fmain.ts` with a function that needs refactoring\n- Executor prompt: `Help me refactor the function in src\u002Fmain.ts`\n\n## Steps\n1. **Initial analysis**: Wait for executor to analyze the code\n   - Expected: Executor identifies the function and suggests refactoring approach\n2. **Approve refactoring**: Send \"yes, go ahead with that approach\" to the executor\n   - Expected: Executor applies the refactoring and shows the diff\n```\n\n### Writing Good Test Plans\n\n#### Background Section\n\nThe most important section. The verifier has no prior knowledge. Explain:\n\n- What the executor is expected to do when given the prompt\n- What input the executor might request (so the verifier knows when to `send()`)\n- What output the executor produces at each stage\n- For workflows: states, transitions, and expected behavior per state\n\n#### Steps Describe Interactions, Not CLI Commands\n\nSteps tell the verifier how to interact with the executor via `wait()` and `send()`:\n\n```markdown\n# Good — describes agent interaction\n1. **Start the workflow**: Start the executor and wait for initial output\n   - Expected: Executor initializes in \"gather\" state and asks for user input\n2. **Provide input**: Send \"my-project\" when the executor asks for a project name\n   - Expected: Executor acknowledges the name and transitions to \"generate\" state\n\n# Bad — describes CLI commands\n1. **Start the workflow**: Run `fflow start my.workflow.yaml --run-id test`\n   - Expected: Exit code 0\n```\n\n#### Expected Should Be Specific\n\n```markdown\n# Good\n- Expected: Output includes today's date in YYYY-MM-DD format\n\n# Bad\n- Expected: Should work correctly\n```\n\n#### Cleanup Should Be Thorough\n\nThe shared sandbox persists across tests. Leftover processes, files, or state from one\ntest can cause the next test to fail or behave unexpectedly.\n\n```markdown\n# Good — explicit cleanup\n## Cleanup\n- Kill the dev server: `kill $(lsof -ti:3000)` or equivalent\n- Remove test fixtures: `rm -rf \u002Ftmp\u002Ftest-workspace`\n- Remove created database: `dropdb test_db`\n\n# Bad — no cleanup or vague\n## Cleanup\n- Clean up test files\n```\n\n### Examples\n\n#### Workflow Test\n\n```markdown\n# Test: Simple workflow lifecycle\n\n## Background\n\nThe simple workflow has two states: \"start\" and \"done\".\nFrom \"start\", the executor should transition to \"done\" via the \"next\" transition.\nThe workflow completes when reaching \"done\" (terminal state with no transitions).\n\n## Setup\n- Executor prompt: `\u002Ffflow e2e\u002Fsimple.workflow.yaml`\n\n## Steps\n1. **Start workflow**: Wait for the executor to initialize\n   - Expected: Run initializes successfully in \"start\" state\n2. **Verify completion**: Wait for the executor to transition through the workflow\n   - Expected: Executor reaches \"done\" state and workflow completes\n\n## Expected Outcomes\n- Workflow starts in initial state and transitions to done\n- The full lifecycle works end-to-end\n```\n\n#### General Agent Behavior (Non-Workflow)\n\n```markdown\n# Test: Agent creates a file with correct content\n\n## Background\n\nWhen asked to create a greeting module, the executor should use the Write tool\nto create a TypeScript file that exports a greet function. This tests basic\nagent file creation behavior, not a workflow.\n\n## Setup\n- Executor prompt: `Create a file src\u002Fgreet.ts that exports a function greet(name: string): string which returns \"Hello, \u003Cname>!\"`\n\n## Steps\n1. **Wait for executor to create file**: Wait for the executor to complete\n   - Expected: Executor uses the Write tool to create src\u002Fgreet.ts\n2. **Verify file content**: Send \"Read src\u002Fgreet.ts and show me the content\"\n   - Expected: File contains a greet function that takes a name parameter and returns a greeting string\n\n## Expected Outcomes\n- src\u002Fgreet.ts is created with the correct function signature\n- The function returns the expected greeting format\n\n## Cleanup\n- Remove src\u002Fgreet.ts\n```\n\n### Common Mistakes\n\n| Mistake | Fix |\n|---------|-----|\n| Skipping codebase exploration | MUST explore existing tests, build setup, and env before writing |\n| Missing Background section | Always explain expected behavior — verifier has no context |\n| Executor prompt lacks context | Include how to build, run, and operate the software |\n| Steps reference CLI directly | Describe agent interactions via wait\u002Fsend, not shell commands |\n| Vague expected outcomes | Be specific: what text, what state, what behavior |\n| No timeout guidance | Add Timeout Strategy table — prevents flaky hangs |\n| Steps not numbered | Parser requires `1.`, `2.`, etc. |\n| Step name not bold | Must use `**Name**:` format |\n| Missing `- Expected:` line | Each step requires expected on the next line |\n| Assuming verifier knows the executor | Background must explain what the executor does |\n| No cleanup or vague cleanup | List every process, file, and service to tear down |\n| Leftover processes after test | Always kill servers\u002Fwatchers started in Setup |\n\n---\n\n## run\n\nRun an existing e2e test plan through the `fflow verify` workflow.\n\nShell out to:\n\n```bash\nfflow verify \u003Cplan.md> --test-dir \u003Cpath> [--model \u003Cmodel>] [--verbose]\n```\n\nIf no test plan is specified, invoke `\u002Fe2e gen` first to write one to `.\u002Fe2e\u002F`, then run it.\n\nExit codes: `0` pass, `2` fail. Report written to `\u003Ctest-dir>\u002Ftest-report.md`.\n\n---\n\n## fix\n\nDiagnose a failed `fflow verify` run and repair the code.\n\n### Process\n\n1. If the user specifies a failed run directory or test-dir, go directly to step 2.\n2. If no failed run is specified, the user should describe what to test. Invoke `\u002Fe2e run` first\n   to generate (via `\u002Fe2e gen`) and execute a test plan. If it fails, use the resulting\n   run directory for step 2.\n3. Read the run-dir artifacts (`test-report.md`, `verifier-session.jsonl`,\n   `executor-session.jsonl`, the copied test plan) and diagnose the failure.\n4. Write a deterministic shell script that reproduces the failure from the session logs.\n5. Fix the code so the reproduction passes.\n6. Re-run via `\u002Fe2e run` with the original plan to confirm the fix.\n",{"name":5,"description":7},"main","898550a01eca98e666c6c16aef03ee6bbd04175c","packages\u002Ffreeflow\u002Fskills\u002Fe2e",5,"https:\u002F\u002Fgithub.com\u002Ffreematters\u002Ffreematters","https:\u002F\u002Ffreematters.vercel.app","https:\u002F\u002Fgithub.com\u002Ffreematters","2026-05-19 20:22:18",{"source":8,"skillName":5,"commands":50,"prompt":60,"zipAvailable":61},[51,54,57],{"tool":52,"command":53},"npx","npx skills add freematters\u002Ffreematters --skill e2e",{"tool":55,"command":56},"bunx","bunx skills add freematters\u002Ffreematters --skill e2e",{"tool":58,"command":59},"pnpm","pnpm dlx skills add freematters\u002Ffreematters --skill e2e","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Ffreematters\u002Ffreematters\u002Fblob\u002Fmain\u002Fpackages\u002Ffreeflow\u002Fskills\u002Fe2e\u002FSKILL.md",true,[],[64,75,93,110,123,135],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":72,"publishedAt":36},"01M6D9TNZ52Y3DXX3PTGTR1Q0K","verifier","E2E test verifier workflow.","https:\u002F\u002Fgithub.com\u002Ffreematters\u002Ffreematters\u002Fblob\u002Fmain\u002Fpackages\u002Ffreeflow\u002Fworkflows\u002Fverifier\u002FSKILL.md",[70,71],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[66,73,5,27,74],"e2e test","workflow",{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":86,"publishedAt":36},"01M6D9TJSJDF87RMDCDSXRBZHT","spec-to-code","Implement a spec into working code, one plan step at a time.","https:\u002F\u002Fgithub.com\u002Ffreematters\u002Ffreematters\u002Fblob\u002Fmain\u002Fpackages\u002Ffreeflow\u002Fworkflows\u002Fspec-to-code\u002FSKILL.md",[81],{"categoryNo":82,"categoryName":83,"taxonomyType":84,"taxonomyTypeDesc":85},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[87,88,89,90,91,92],"spec to code","code","spec","time","plan","implement",{"skillNo":94,"name":95,"nameZh":6,"description":96,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":97,"categories":98,"keywords":99,"publishedAt":36},"01M6D9TFTDG16JC379AD3TT9E8","spec-gen","Generate a complete specification from a rough idea through interactive requirements gathering, research, design, and implementation planning.","https:\u002F\u002Fgithub.com\u002Ffreematters\u002Ffreematters\u002Fblob\u002Fmain\u002Fpackages\u002Ffreeflow\u002Fworkflows\u002Fspec-gen\u002FSKILL.md",[],[100,89,101,102,103,104,105,106,107,108,109],"spec gen","implementation","requirements","idea","specification","interactive","planning","generate","research","design",{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":117,"publishedAt":36},"01M6D9TDFC5MDPJW068JGGMB1W","spec-driven","End-to-end pipeline from rough idea to merged pull request. Passing --quick forwards the flag to the spec-gen sub workflow.","https:\u002F\u002Fgithub.com\u002Ffreematters\u002Ffreematters\u002Fblob\u002Fmain\u002Fpackages\u002Ffreeflow\u002Fworkflows\u002Fspec-driven\u002FSKILL.md",[116],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[118,89,119,103,120,121,122,74],"spec driven","end","pipeline","pull","pull request",{"skillNo":124,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":127,"categories":128,"keywords":130,"publishedAt":36},"01M6D9TB81ZTY2ATQRCTDKPXZK","release","General release workflow for GitHub projects.","https:\u002F\u002Fgithub.com\u002Ffreematters\u002Ffreematters\u002Fblob\u002Fmain\u002Fpackages\u002Ffreeflow\u002Fworkflows\u002Frelease\u002FSKILL.md",[129],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[125,131,74,132,133,134],"github","general","projects","github projects",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":141,"publishedAt":36},"01M6D9T8Y48YE2YM0HYXPV59PM","pr-lifecycle","Monitor a PR\u002FMR until it is merged or closed.","https:\u002F\u002Fgithub.com\u002Ffreematters\u002Ffreematters\u002Fblob\u002Fmain\u002Fpackages\u002Ffreeflow\u002Fworkflows\u002Fpr-lifecycle\u002FSKILL.md",[],[142,143,144,145],"pr","pr lifecycle","lifecycle","monitor"]