ワンクリックで
test-and-verify-walnut
4-agent pipeline: design + implement code tests + Playwright UI tests + quality gate. Reads walnut-console-ops first.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
4-agent pipeline: design + implement code tests + Playwright UI tests + quality gate. Reads walnut-console-ops first.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Review recent activity and generate a standup update. Use when the user asks for a standup, "what did I do yesterday", or a daily summary.
Install, configure, verify, update, and remove Walnut plugins from git repos through the Plugin Store REST API. Use when the user pastes a plugin share snippet ({"walnut_plugin_source": ...}) or a git repo URL and wants the plugin installed, or says "install plugin", "add plugin source", "update/remove a plugin", or asks why a plugin is not active.
Distill a workflow, doc, or conversation into a reusable skill. Use when the user says "learn this", "save this as a skill", or wants a procedure captured for reuse.
Register a repository — delegate a Claude Code session to explore the codebase and create a structured profile. Use when the user says "register repo", "add this repo", or wants a repository profile created.
Triage and prioritize pending tasks. Use when the user asks to triage, review priorities, clean up stale tasks, or decide what to work on next.
Summarize the week's progress across all projects. Use when the user asks for a weekly review, week summary, or "what happened this week".
| name | test-and-verify-walnut |
| description | 4-agent pipeline: design + implement code tests + Playwright UI tests + quality gate. Reads walnut-console-ops first. |
Every test must answer: "If I reverted my code changes, would this test fail?" NO → delete it.
FIRST: Read .claude/skills/walnut-console-ops/SKILL.md for UI layout and interaction patterns.
Main Agent (context) → Agent 1 (design) → Agent 2 (code) ∥ Agent 3 (Playwright) → Agent 4 (quality gate)
git diff --stat HEAD~1 + git log --oneline -5.plan, ~/.claude/plans/, .tasks/*/TASK.md| Change Type | Primary Tests |
|---|---|
| Frontend-only | Playwright UI |
| Backend-only | API + unit + server logs |
| Full-stack | Console E2E + Playwright + unit |
| Bug fix | Reproduce → fix → re-verify |
Design tests in 2 categories. Do NOT implement.
Category A — UI (Playwright): 2-4 scenarios. For each: pre-conditions, steps (real clicks, NO page.goto() SPA nav), assertions (must include downstream verification — see below), screenshot points.
Category B — Code (vitest): 2-4 tests, as E2E as possible. For each: name, tier, setup, exercise, assert (HTTP response + WS event + persisted data).
Self-check each test: "Would this pass with code reverted?" YES = delete.
E2E means full consequence: Every test must verify the downstream effect of the action, not just the immediate UI change. If the action triggers a backend round-trip, the test must wait for and verify the backend result.
Anti-patterns (test is SHALLOW or WORTHLESS if it only checks these):
Implement Category B. Rules:
startServer({ port: 0, dev: true }). Only mock Claude CLI (tests/providers/mock-claude.mjs).tests/e2e/ (pipeline), tests/web/routes/ (API), tests/core/ (logic), tests/e2e/browser/ (Playwright code).First: Read .claude/skills/walnut-console-ops/SKILL.md.
Execute Category A:
mkdir -p /tmp/test-and-verify/, build SPA: cd web && npx vite build/tmp/test-and-verify/<scenario>-step<N>.pngRead tool.CRITICAL — Verify full consequence, not just UI reaction:
Every UI action that triggers backend work must be verified through to the downstream effect. The test is NOT done when the UI element changes — it's done when the outcome is confirmed.
The question: "Did the thing I triggered actually work?" — not "Did the UI react to my click?"
BAD (shallow) — stops at UI reaction:
# Testing model switch:
Click "Opus 1M" → picker closes → screenshot → ✅ DONE
# WRONG: only proved the picker UI works. Did the session actually restart
# with the new model? Did the next message succeed? No idea.
# Testing task creation:
Click "Add" → task appears in list → screenshot → ✅ DONE
# WRONG: only proved the React component rendered. Did the task persist
# to disk? Can you reload and still see it? No idea.
# Testing session start:
Click "Start session" → status shows "Running" → screenshot → ✅ DONE
# WRONG: only proved the status badge updated. Did the session actually
# produce output? Did the CLI process spawn? No idea.
GOOD (full consequence) — verifies the downstream effect:
# Testing model switch:
Click "Opus 1M" → picker closes → send a message in session input →
wait for response → verify response text appears (no "API Error",
no "invalid model") → screenshot response → ✅ DONE
# Testing task creation:
Click "Add" → task appears in list → click the task → verify detail
panel shows correct title/category/project → ✅ DONE
# Testing session start:
Click "Start session" → status shows "Running" → wait for first
assistant message to appear in chat → verify message content →
screenshot → ✅ DONE
The pattern: Action → UI reacts → wait for backend round-trip → verify outcome → screenshot proof. If you stop at "UI reacts", the test is SHALLOW.
For each test, ask TWO questions:
A Playwright test that clicks a button and screenshots is SHALLOW unless it also waits for and verifies what that button caused (response arrived, status updated, data persisted, no errors).
Overall: PASS / NEEDS WORK / FAIL
## Test & Verify Report: <Feature>
### Build — Server: PASS/FAIL, Frontend: PASS/FAIL
### Code Tests — <N> tests, <N> genuine
### UI Tests — <N> scenarios, <N> genuine
### Overall — PASS / NEEDS WORK / FAIL
New patterns → append to Learned Patterns below. Console-related → also update walnut-console-ops/SKILL.md.
npm test # Unit + Integration (~5s)
npm run test:e2e # E2E real server (~15s)
npm run test:all # Everything
npx vitest run <file> # Single test
cd web && npx vite build # Build SPA before Playwright
npx playwright test # Browser tests
Pyramid: Live → Playwright → E2E (most important) → Integration → Unit
Mock only: Claude CLI. Everything else real.
Production safety: OPEN_WALNUT_HOME=/tmp/walnut-test-*/. Never ~/.open-walnut/. Port 3456 = production, never touch.
Open source: No internal tool names, employer references, or personal usernames.
vi.mock('../../src/constants.js', () => createMockConstants('walnut-e2e-FEATURE'));
import { startServer, stopServer } from '../../src/web/server.js';
let server, port;
beforeAll(async () => {
server = await startServer({ port: 0, dev: true });
port = (server.address() as any).port;
});
afterAll(() => stopServer());
it('REST → Core → Bus → WS', async () => {
const ws = await connectWs();
const event = waitForWsEvent(ws, 'task:created');
const res = await fetch(`http://localhost:${port}/api/tasks`, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'test' }),
});
expect(res.status).toBe(201);
expect((await event).data.task.title).toBe('test');
ws.close();
});
const MOCK_CLI = path.resolve(import.meta.dirname, '../providers/mock-claude.mjs');
sessionRunner.setCliCommand(MOCK_WRAPPER); // before startServer
{ type: 'event', name, data } / RPC: { type: 'req', id, method, payload }waitForWsEvent() with timeoutpage.goto('/route') in SPAtests/e2e/browser/test-server.ts wires a
MockDaemon + mock CLI (sessionRunner.setCliCommand + setTestDaemonUrl) into the Playwright
server, so specs can create LIVE sessions via the session:start WS RPC and exercise the real
event pipeline (no __capturedWs injection needed). Disable with PW_NO_MOCK_DAEMON=1 when
bisecting whether a failure comes from this wiring. See
tests/e2e/browser/single-timeline-real-pipeline.spec.ts for the pattern (start session →
poll /api/sessions/task/:id for the mock-session-* id → open /sessions?id=).chunk-delay:<ms> mock-CLI prefix: spaces out content_block_delta emissions in
stream-partial-thinking-then-text so browser tests can observe partial text mid-turn
(the default burst is synchronous and races any DOM poll). Composable: chunk-delay:250 stream-partial-thinking-then-text.GET /:id/history falls back to SESSION_STREAMS_DIR/<sid>.jsonl. Vitest tests
that need real-parser history must copy daemon.streamFilePath(sid) →
SESSION_STREAMS_DIR first (see publishStreamsFile in
tests/web/stream/single-timeline-real-pipeline.test.ts). Symptom otherwise: history 200 with
0 messages forever.npx playwright test failures may come from PARALLEL agents'
uncommitted UI changes, not yours. Bisect by re-running the failing spec against the HEAD
version of the shared harness file you touched (git checkout <file> → run → restore) before
assuming a regression.