feat: add pstack-style rigor skill family for Zed
- wursor-precheck: router skill, entry point for non-trivial tasks - wursor-principles: 21 engineering principles adapted for Wursor - wursor-tdd, wursor-bug-fix, wursor-feature, wursor-investigation, wursor-review, wursor-decision-log: playbook skills - AGENTS.md: repo guide wiring the skill routing table - Fix: double-quote YAML frontmatter descriptions (colon-space in plain scalars broke Zed's skill loader)
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
---
|
||||
name: wursor-tdd
|
||||
description: "Write a failing test first, then implement, then verify. For any code change in api/ (Node.js + TypeScript), web/ (React + TypeScript), plugin/ (PHP), or infrastructure/ (Docker) that has a measurable test path. Adapted from pstack's /tdd skill."
|
||||
---
|
||||
|
||||
# Wursor TDD
|
||||
|
||||
Write the failing test first, then the implementation, then verify the test passes. This is the default workflow for any code change in this repository.
|
||||
|
||||
## When to use
|
||||
|
||||
Use this skill when:
|
||||
- Fixing a bug with a measurable test path
|
||||
- Building a new feature with unit-testable boundaries
|
||||
- Adding a helper, utility, or pure function
|
||||
- Refactoring where behavior should be preserved
|
||||
- The task tells you the test path is cheap or fast
|
||||
|
||||
Do **not** use this for: configuration-only changes, non-code documentation, or infrastructure scripts whose test would be a full e2e run.
|
||||
|
||||
## Playbook
|
||||
|
||||
### Step 1 — Understand what's being tested
|
||||
|
||||
Read the relevant module. Understand the function signature, the inputs, the outputs, and the side effects. For `api/` modules, check the existing `__tests__/` or `tests/` directory for patterns.
|
||||
|
||||
### Step 2 — Write the failing test
|
||||
|
||||
One test per behavior. One assertion per test.
|
||||
|
||||
```typescript
|
||||
// Example for api/ modules
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
describe('SandboxMirror', () => {
|
||||
it('fetches site info from the plugin API', async () => {
|
||||
const mirror = new SandboxMirror('https://example.com', 'token');
|
||||
const info = await mirror.fetchSiteInfo();
|
||||
expect(info.theme).toBeDefined();
|
||||
expect(info.plugins).toBeInstanceOf(Array);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
```php
|
||||
// Example for plugin/ modules
|
||||
class WursorAuthTest extends WP_UnitTestCase {
|
||||
public function test_generates_six_character_code() {
|
||||
$auth = new Wursor_Auth();
|
||||
$code = $auth->generate_pairing_code();
|
||||
$this->assertEquals(6, strlen($code));
|
||||
$this->assertMatchesRegularExpression('/^[A-Z0-9]{6}$/', $code);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3 — Run the test. It must fail.
|
||||
|
||||
Do not proceed until the test runner confirms the test fails. A test that passes before implementation is a test that tests nothing.
|
||||
|
||||
```bash
|
||||
# api/ — vitest
|
||||
pnpm test -- --grep "SandboxMirror"
|
||||
# plugin/ — phpunit
|
||||
phpunit --filter test_generates_six_character_code
|
||||
```
|
||||
|
||||
### Step 4 — Implement the minimum code to pass
|
||||
|
||||
Write the implementation. No more than what's needed to make the test pass.
|
||||
|
||||
### Step 5 — Run the test. It must pass.
|
||||
|
||||
Same command as step 3. The test must pass.
|
||||
|
||||
### Step 6 — Refactor
|
||||
|
||||
Clean up the implementation and the test. Remove debug code, rename unclear variables, extract helpers if they exist. The test should still pass.
|
||||
|
||||
### Step 7 — Verify with the broader test suite
|
||||
|
||||
Run the relevant test suite to make sure nothing is broken:
|
||||
|
||||
```bash
|
||||
# api/
|
||||
pnpm test:api
|
||||
# web/
|
||||
pnpm test:web
|
||||
# plugin/
|
||||
phpunit
|
||||
```
|
||||
|
||||
### Step 8 — Report
|
||||
|
||||
State what was tested, what the test proved, and what the broader suite showed.
|
||||
|
||||
## Hard rules
|
||||
|
||||
- No implementation code is written without a failing test.
|
||||
- One test per behavior. One assertion per test.
|
||||
- Tests are deterministic: no network calls in unit tests. Mock the Grok API, the plugin API, Docker, and the filesystem.
|
||||
- The test must fail before the implementation. If it passes, the test is wrong.
|
||||
- Coverage floor: api/ and web/ ≥ 90% line coverage. plugin/ ≥ 80%.
|
||||
Reference in New Issue
Block a user