docs: PRD v1.2 — Wursor rename, key decisions locked, all gaps addressed
- Renamed product from Wordbench to Wursor across all touchpoints - Locked key decisions: Electron + Code-OSS shell, Claude BYO key, wp-env only v1 - Added first-run experience (§7.1.8), error states (§8.5), agent substrate (§8.1.1) - Expanded State Diff lifecycle (§6.4), Knowledge Graph strategy (§6.2) - Strengthened verify-as-proof principle (§5, §7.1.6) - Added metrics baselines + owners (§11), exit criteria for Phases 1-2 (§12) - Added test strategy (§C.1), accessibility/i18n as non-goal (§C) - Created IMPLEMENTATION.md — TDD-driven 8-sprint build guide
This commit is contained in:
@@ -0,0 +1,879 @@
|
|||||||
|
# Implementation Guide — Wursor v1
|
||||||
|
|
||||||
|
**Version:** 1.0
|
||||||
|
**Source:** [PRD.md](./PRD.md) v1.2
|
||||||
|
**Method:** Test-driven development (TDD) — every module is written against its tests before its implementation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
1. [Architecture Overview](#1-architecture-overview)
|
||||||
|
2. [Project Structure](#2-project-structure)
|
||||||
|
3. [Build Phases](#3-build-phases)
|
||||||
|
4. [Phase 1 — Foundation (Weeks 1–8)](#4-phase-1--foundation-weeks-18)
|
||||||
|
- [Sprint 1: Electron shell + project scaffold](#sprint-1-electron-shell--project-scaffold)
|
||||||
|
- [Sprint 2: wp-env runtime manager](#sprint-2-wp-env-runtime-manager)
|
||||||
|
- [Sprint 3: Agent tool bus](#sprint-3-agent-tool-bus)
|
||||||
|
- [Sprint 4: Agent chat + diff review](#sprint-4-agent-chat--diff-review)
|
||||||
|
- [Sprint 5: WP-CLI tool + permission engine](#sprint-5-wp-cli-tool--permission-engine)
|
||||||
|
- [Sprint 6: P0 playbooks + first-run](#sprint-6-p0-playbooks--first-run)
|
||||||
|
- [Sprint 7: Integration + exit criteria](#sprint-7-integration--exit-criteria)
|
||||||
|
- [Sprint 8: Polish + alpha readiness](#sprint-8-polish--alpha-readiness)
|
||||||
|
5. [Phase 2 — Intelligence (Weeks 9–16)](#5-phase-2--intelligence-weeks-916)
|
||||||
|
6. [TDD Rules](#6-tdd-rules)
|
||||||
|
7. [CI/CD Pipeline](#7-cicd-pipeline)
|
||||||
|
8. [Glossary](#8-glossary)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Architecture Overview
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────┐
|
||||||
|
│ Electron Shell (Code-OSS core) │
|
||||||
|
│ ┌──────────────┐ ┌──────────┐ ┌──────────────────┐ │
|
||||||
|
│ │ Editor pane │ │ Terminal │ │ Wursor panels │ │
|
||||||
|
│ │ (Code-OSS) │ │ (xterm) │ │ preview, diff, │ │
|
||||||
|
│ │ │ │ │ │ state, chat │ │
|
||||||
|
│ └──────┬───────┘ └────┬─────┘ └────────┬─────────┘ │
|
||||||
|
└─────────┼──────────────┼────────────────┼───────────┘
|
||||||
|
│ │ │
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌─────────────────────────────────────────────────────┐
|
||||||
|
│ Agent Tool Bus (Node.js process) │
|
||||||
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
|
||||||
|
│ │ fs │ │ wpcli │ │ site │ │ db │ │
|
||||||
|
│ │ tools │ │ runner │ │ runtime │ │ query │ │
|
||||||
|
│ └──────────┘ └──────────┘ └──────────┘ └─────────┘ │
|
||||||
|
│ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │
|
||||||
|
│ │ lint │ │ index │ │ permission engine │ │
|
||||||
|
│ │ tools │ │ search │ │ + secret redaction │ │
|
||||||
|
│ └──────────┘ └──────────┘ └──────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────┐
|
||||||
|
│ Site Runtime (wp-env / Docker) │
|
||||||
|
│ WordPress + MySQL + WP-CLI │
|
||||||
|
└─────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key structural decisions:**
|
||||||
|
- **Monorepo** with `packages/` directories — one package per layer
|
||||||
|
- Each package has its own `__tests__/` directory and `vitest.config.ts`
|
||||||
|
- Integration tests use fixture-based WordPress repos in CI
|
||||||
|
- E2E tests use Playwright against the Electron shell
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
wursor/
|
||||||
|
├── electron/ # Electron shell + main process
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── main.ts # Electron main process entry
|
||||||
|
│ │ ├── preload.ts # Context bridge
|
||||||
|
│ │ ├── windows/
|
||||||
|
│ │ │ ├── main-window.ts # Main window factory
|
||||||
|
│ │ │ └── preview-window.ts# Preview webview
|
||||||
|
│ │ ├── ipc/ # IPC handlers
|
||||||
|
│ │ │ ├── filesystem.ts # File read/write via IPC
|
||||||
|
│ │ │ ├── docker.ts # Docker socket access
|
||||||
|
│ │ │ └── shell.ts # Terminal spawn
|
||||||
|
│ │ └── menu.ts # Application menu
|
||||||
|
│ ├── __tests__/
|
||||||
|
│ │ ├── main.test.ts
|
||||||
|
│ │ └── preload.test.ts
|
||||||
|
│ ├── electron-builder.yml # Build config
|
||||||
|
│ └── package.json
|
||||||
|
│
|
||||||
|
├── packages/
|
||||||
|
│ ├── editor-core/ # Code-OSS extension layer
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── extension.ts # Activation entry
|
||||||
|
│ │ │ ├── panels/
|
||||||
|
│ │ │ │ ├── preview-panel.ts
|
||||||
|
│ │ │ │ ├── diff-panel.ts
|
||||||
|
│ │ │ │ ├── state-diff-panel.ts
|
||||||
|
│ │ │ │ └── chat-panel.ts
|
||||||
|
│ │ │ ├── commands/
|
||||||
|
│ │ │ │ ├── open-project.ts
|
||||||
|
│ │ │ │ ├── run-playbook.ts
|
||||||
|
│ │ │ │ └── verify-preview.ts
|
||||||
|
│ │ │ └── providers/
|
||||||
|
│ │ │ ├── status-bar.ts
|
||||||
|
│ │ │ └── tree-view.ts
|
||||||
|
│ │ ├── __tests__/
|
||||||
|
│ │ │ ├── panels.test.ts
|
||||||
|
│ │ │ └── commands.test.ts
|
||||||
|
│ │ └── package.json
|
||||||
|
│ │
|
||||||
|
│ ├── tool-bus/ # Agent tool schemas + execution
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── index.ts
|
||||||
|
│ │ │ ├── registry.ts # Tool registry (name → schema → handler)
|
||||||
|
│ │ │ ├── tools/
|
||||||
|
│ │ │ │ ├── fs.ts # fs.read, fs.write, fs.apply_patch
|
||||||
|
│ │ │ │ ├── wpcli.ts # wpcli.run (categorized)
|
||||||
|
│ │ │ │ ├── site.ts # site.browse, site.screenshot, site.request
|
||||||
|
│ │ │ │ ├── db.ts # db.query (read-only)
|
||||||
|
│ │ │ │ ├── lint.ts # lint.phpcs
|
||||||
|
│ │ │ │ ├── test.ts # test.phpunit
|
||||||
|
│ │ │ │ └── index.ts # index.search, index.graph_lookup
|
||||||
|
│ │ │ ├── schemas.ts # JSON Schema for each tool
|
||||||
|
│ │ │ └── executor.ts # Shell executor (spawn, stream, timeout)
|
||||||
|
│ │ ├── __tests__/
|
||||||
|
│ │ │ ├── registry.test.ts
|
||||||
|
│ │ │ ├── tools/fs.test.ts
|
||||||
|
│ │ │ ├── tools/wpcli.test.ts
|
||||||
|
│ │ │ ├── tools/site.test.ts
|
||||||
|
│ │ │ ├── tools/db.test.ts
|
||||||
|
│ │ │ └── executor.test.ts
|
||||||
|
│ │ └── package.json
|
||||||
|
│ │
|
||||||
|
│ ├── knowledge-index/ # WordPress Knowledge Graph
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── index.ts
|
||||||
|
│ │ │ ├── scanner/
|
||||||
|
│ │ │ │ ├── static-scanner.ts # PHP/JSON file scan
|
||||||
|
│ │ │ │ └── runtime-enricher.ts # WP-CLI enrichment
|
||||||
|
│ │ │ ├── graph/
|
||||||
|
│ │ │ │ ├── node.ts
|
||||||
|
│ │ │ │ ├── edge.ts
|
||||||
|
│ │ │ │ └── store.ts
|
||||||
|
│ │ │ ├── freshness.ts # Staleness tracking
|
||||||
|
│ │ │ └── queries.ts # Graph query API
|
||||||
|
│ │ ├── __tests__/
|
||||||
|
│ │ │ ├── scanner/static-scanner.test.ts
|
||||||
|
│ │ │ ├── scanner/runtime-enricher.test.ts
|
||||||
|
│ │ │ ├── graph/store.test.ts
|
||||||
|
│ │ │ └── queries.test.ts
|
||||||
|
│ │ ├── fixtures/ # Test WP repos
|
||||||
|
│ │ │ ├── classic-theme/
|
||||||
|
│ │ │ ├── block-theme/
|
||||||
|
│ │ │ └── single-plugin/
|
||||||
|
│ │ └── package.json
|
||||||
|
│ │
|
||||||
|
│ ├── state-diff/ # State Diff lifecycle
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── index.ts
|
||||||
|
│ │ │ ├── lifecycle.ts # create → review → stage → apply → verify → commit
|
||||||
|
│ │ │ ├── evaluator.ts # Evaluate intent + blast radius
|
||||||
|
│ │ │ ├── rollback.ts # Inverse / rollback generation
|
||||||
|
│ │ │ ├── serializer.ts # .state-diff.json format
|
||||||
|
│ │ │ └── types.ts
|
||||||
|
│ │ ├── __tests__/
|
||||||
|
│ │ │ ├── lifecycle.test.ts
|
||||||
|
│ │ │ ├── evaluator.test.ts
|
||||||
|
│ │ │ ├── rollback.test.ts
|
||||||
|
│ │ │ └── serializer.test.ts
|
||||||
|
│ │ └── package.json
|
||||||
|
│ │
|
||||||
|
│ ├── runtime-manager/ # Site runtime lifecycle
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── index.ts
|
||||||
|
│ │ │ ├── interface.ts # Runtime interface (abstraction layer)
|
||||||
|
│ │ │ ├── adapters/
|
||||||
|
│ │ │ │ └── wp-env.ts # wp-env adapter (v1 only)
|
||||||
|
│ │ │ ├── lifecycle.ts # start/stop/reset/status
|
||||||
|
│ │ │ └── logs.ts # Log tailing
|
||||||
|
│ │ ├── __tests__/
|
||||||
|
│ │ │ ├── adapters/wp-env.test.ts
|
||||||
|
│ │ │ ├── lifecycle.test.ts
|
||||||
|
│ │ │ └── logs.test.ts
|
||||||
|
│ │ └── package.json
|
||||||
|
│ │
|
||||||
|
│ ├── permission-engine/ # Policy engine
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── index.ts
|
||||||
|
│ │ │ ├── tiers.ts # Permission tiers definition
|
||||||
|
│ │ │ ├── evaluator.ts # Evaluate tool call against policy
|
||||||
|
│ │ │ ├── redactor.ts # Secret redaction
|
||||||
|
│ │ │ └── config.ts # User-defined policy
|
||||||
|
│ │ ├── __tests__/
|
||||||
|
│ │ │ ├── tiers.test.ts
|
||||||
|
│ │ │ ├── evaluator.test.ts
|
||||||
|
│ │ │ └── redactor.test.ts
|
||||||
|
│ │ └── package.json
|
||||||
|
│ │
|
||||||
|
│ ├── verify/ # Preview verification
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── index.ts
|
||||||
|
│ │ │ ├── screenshot.ts # Screenshot capture
|
||||||
|
│ │ │ ├── http-check.ts # URL load + status + error sniff
|
||||||
|
│ │ │ ├── editor-check.ts # Block editor route check
|
||||||
|
│ │ │ └── reporter.ts # Verify result formatting
|
||||||
|
│ │ ├── __tests__/
|
||||||
|
│ │ │ ├── screenshot.test.ts
|
||||||
|
│ │ │ ├── http-check.test.ts
|
||||||
|
│ │ │ └── reporter.test.ts
|
||||||
|
│ │ └── package.json
|
||||||
|
│ │
|
||||||
|
│ ├── agent-bridge/ # Agent API client
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── index.ts
|
||||||
|
│ │ │ ├── client.ts # Claude API client (BYO key)
|
||||||
|
│ │ │ ├── tool-schemas.ts # Tool schemas → Claude format
|
||||||
|
│ │ │ ├── context.ts # Build system prompt + context
|
||||||
|
│ │ │ └── fallback.ts # Error handling + retry
|
||||||
|
│ │ ├── __tests__/
|
||||||
|
│ │ │ ├── client.test.ts
|
||||||
|
│ │ │ ├── tool-schemas.test.ts
|
||||||
|
│ │ │ └── context.test.ts
|
||||||
|
│ │ └── package.json
|
||||||
|
│ │
|
||||||
|
│ └── playbooks/ # Reusable agent workflows
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── index.ts
|
||||||
|
│ │ ├── registry.ts # Playbook registry
|
||||||
|
│ │ ├── dynamic-block.ts
|
||||||
|
│ │ ├── child-theme.ts
|
||||||
|
│ │ ├── cpt.ts
|
||||||
|
│ │ └── plugin.ts
|
||||||
|
│ ├── __tests__/
|
||||||
|
│ │ ├── registry.test.ts
|
||||||
|
│ │ ├── dynamic-block.test.ts
|
||||||
|
│ │ ├── child-theme.test.ts
|
||||||
|
│ │ └── cpt.test.ts
|
||||||
|
│ └── package.json
|
||||||
|
│
|
||||||
|
├── e2e/ # End-to-end tests
|
||||||
|
│ ├── electron/
|
||||||
|
│ │ ├── open-project.test.ts
|
||||||
|
│ │ ├── detect-wp.test.ts
|
||||||
|
│ │ ├── boot-preview.test.ts
|
||||||
|
│ │ ├── playbook-dynamic-block.test.ts
|
||||||
|
│ │ └── verify-preview.test.ts
|
||||||
|
│ ├── fixtures/
|
||||||
|
│ │ ├── sample-theme/ # Minimal WP theme repo
|
||||||
|
│ │ └── sample-plugin/ # Minimal WP plugin repo
|
||||||
|
│ └── playwright.config.ts
|
||||||
|
│
|
||||||
|
├── tsconfig.base.json
|
||||||
|
├── vitest.workspace.ts
|
||||||
|
├── package.json # Root package.json (workspaces)
|
||||||
|
├── pnpm-workspace.yaml
|
||||||
|
└── .github/workflows/
|
||||||
|
├── ci.yml # Unit + integration on PR
|
||||||
|
└── e2e.yml # E2E on release branch
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Build Phases
|
||||||
|
|
||||||
|
The implementation follows the roadmap from §12 of the PRD.
|
||||||
|
|
||||||
|
| Phase | Weeks | Output | Exit criteria |
|
||||||
|
|-------|-------|--------|---------------|
|
||||||
|
| **Phase 1** | 1–8 | Electron shell, wp-env runtime, agent tool bus, chat, WP-CLI, playbooks, first-run | Clean machine → live preview ≤10 min; P0 playbook completes |
|
||||||
|
| **Phase 2** | 9–16 | Knowledge graph, State Diffs, quality gates, staging pull, closed alpha | All §11 baselines collected; State Diff lifecycle demoed |
|
||||||
|
| **Phase 3** | 17–28 | Block/FSE workshop, deploy connectors, team playbooks, paid beta | — |
|
||||||
|
| **Phase 4** | 29+ | WooCommerce, multisite, maintenance agents, ecosystem | — |
|
||||||
|
|
||||||
|
This guide details **Phase 1** only. Phase 2 will be broken down after Phase 1 exit criteria are met.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Phase 1 — Foundation (Weeks 1–8)
|
||||||
|
|
||||||
|
Organized into **8 sprints** (one per week). Every sprint produces a **run integration test** that passes before the sprint is done.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Sprint 1: Electron shell + project scaffold
|
||||||
|
|
||||||
|
**Goal:** Ship a working Electron window wrapping Code-OSS that opens a folder and shows a Wursor sidebar.
|
||||||
|
|
||||||
|
#### TDD sequence
|
||||||
|
|
||||||
|
**Step 1 — Write the test that defines "done"**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// e2e/electron/open-project.test.ts
|
||||||
|
import { _electron as electron } from 'playwright';
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test('opens a folder and shows Wursor sidebar', async () => {
|
||||||
|
const app = await electron.launch({
|
||||||
|
args: ['/path/to/fixtures/sample-theme'],
|
||||||
|
});
|
||||||
|
const window = await app.firstWindow();
|
||||||
|
await expect(window.locator('.wursor-sidebar')).toBeVisible();
|
||||||
|
await expect(window.locator('.monaco-editor')).toBeVisible();
|
||||||
|
await app.close();
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Write the code to pass it**
|
||||||
|
|
||||||
|
- **`electron/src/main.ts`** — Create BrowserWindow, load Code-OSS, pass `--folder-uri` arg
|
||||||
|
- **`electron/src/preload.ts`** — Expose Wursor API via contextBridge
|
||||||
|
- **`electron/src/windows/main-window.ts`** — Window factory: size, menu, webview preload
|
||||||
|
- **`electron/electron-builder.yml`** — macOS + Windows targets
|
||||||
|
- **`packages/editor-core/src/extension.ts`** — Code-OSS extension that activates on `wursor.*` commands
|
||||||
|
- **`packages/editor-core/src/panels/chat-panel.ts`** — Sidebar webview (placeholder)
|
||||||
|
|
||||||
|
**Step 3 — Write the unit tests**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// electron/__tests__/main.test.ts
|
||||||
|
describe('Electron main process', () => {
|
||||||
|
it('creates a BrowserWindow', () => { /* ... */ });
|
||||||
|
it('loads the Code-OSS editor core', () => { /* ... */ });
|
||||||
|
it('exposes Wursor API via preload', () => { /* ... */ });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 4 — Integration test**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm test:e2e -- --grep "opens a folder and shows Wursor sidebar"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Deliverables
|
||||||
|
|
||||||
|
- Electron app that opens a folder and shows a sidebar
|
||||||
|
- `e2e/electron/open-project.test.ts` passing
|
||||||
|
- `electron/__tests__/main.test.ts` passing
|
||||||
|
- `packages/editor-core/__tests__/extension.test.ts` passing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Sprint 2: wp-env runtime manager
|
||||||
|
|
||||||
|
**Goal:** Start/stop/reset a WordPress site via wp-env, show status in the sidebar.
|
||||||
|
|
||||||
|
#### TDD sequence
|
||||||
|
|
||||||
|
**Step 1 — Write the integration test**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// e2e/electron/boot-preview.test.ts
|
||||||
|
test('boots a WordPress site via wp-env and shows preview', async () => {
|
||||||
|
const app = await electron.launch({ args: ['/path/to/fixtures/sample-theme'] });
|
||||||
|
const window = await app.firstWindow();
|
||||||
|
await window.locator('.wursor-start-runtime').click();
|
||||||
|
await expect(window.locator('.wursor-status-indicator')).toHaveText('running');
|
||||||
|
await expect(window.locator('.wursor-preview-frame')).toBeVisible();
|
||||||
|
await app.close();
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Write the unit tests**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// packages/runtime-manager/__tests__/lifecycle.test.ts
|
||||||
|
describe('RuntimeManager', () => {
|
||||||
|
it('starts wp-env and returns status', async () => {
|
||||||
|
const manager = new RuntimeManager();
|
||||||
|
const status = await manager.start();
|
||||||
|
expect(status).toBe('running');
|
||||||
|
});
|
||||||
|
it('stops wp-env and cleans up', async () => { /* ... */ });
|
||||||
|
it('reports status as stopped when not running', async () => { /* ... */ });
|
||||||
|
it('streams logs from wp-env', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/runtime-manager/__tests__/adapters/wp-env.test.ts
|
||||||
|
describe('WpEnvAdapter', () => {
|
||||||
|
it('spawns wp-env start', async () => { /* ... */ });
|
||||||
|
it('parses wp-env output for URL and credentials', async () => { /* ... */ });
|
||||||
|
it('handles wp-env not found', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3 — Implement**
|
||||||
|
|
||||||
|
- **`packages/runtime-manager/src/interface.ts`** — `RuntimeAdapter` interface (start, stop, reset, status, logs, url, credentials)
|
||||||
|
- **`packages/runtime-manager/src/adapters/wp-env.ts`** — Implements `RuntimeAdapter` via `child_process.spawn('npx wp-env start')`
|
||||||
|
- **`packages/runtime-manager/src/lifecycle.ts`** — State machine: stopped → starting → running → stopping → stopped
|
||||||
|
- **`packages/runtime-manager/src/logs.ts`** — Tail `wp-env logs` output stream
|
||||||
|
- **`packages/editor-core/src/panels/preview-panel.ts`** — iframe pointing to `http://localhost:{port}`
|
||||||
|
- **`packages/editor-core/src/providers/status-bar.ts`** — Runtime status indicator
|
||||||
|
|
||||||
|
#### Deliverables
|
||||||
|
|
||||||
|
- Runtime manager package with unit tests
|
||||||
|
- Preview panel showing the live site
|
||||||
|
- Status bar showing runtime state
|
||||||
|
- `e2e/electron/boot-preview.test.ts` passing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Sprint 3: Agent tool bus
|
||||||
|
|
||||||
|
**Goal:** Each tool from §8.3 is a registered schema with a handler that executes in the local environment.
|
||||||
|
|
||||||
|
#### TDD sequence
|
||||||
|
|
||||||
|
**Step 1 — Write the unit tests**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// packages/tool-bus/__tests__/registry.test.ts
|
||||||
|
describe('ToolRegistry', () => {
|
||||||
|
it('registers a tool with name, schema, and handler', () => {
|
||||||
|
const registry = new ToolRegistry();
|
||||||
|
registry.register('fs.read', fsReadSchema, fsReadHandler);
|
||||||
|
expect(registry.get('fs.read')).toBeDefined();
|
||||||
|
});
|
||||||
|
it('throws on duplicate tool name', () => { /* ... */ });
|
||||||
|
it('returns all tool schemas for the agent', () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/tool-bus/__tests__/tools/fs.test.ts
|
||||||
|
describe('fs.read', () => {
|
||||||
|
it('reads a file and returns its content', async () => {
|
||||||
|
const result = await fsReadHandler({ path: 'fixtures/sample.txt' });
|
||||||
|
expect(result.content).toBe('hello');
|
||||||
|
});
|
||||||
|
it('rejects paths outside the workspace', async () => { /* ... */ });
|
||||||
|
it('handles missing files gracefully', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/tool-bus/__tests__/tools/wpcli.test.ts
|
||||||
|
describe('wpcli.run', () => {
|
||||||
|
it('runs a WP-CLI command and returns output', async () => {
|
||||||
|
const result = await wpcliRunHandler({ command: 'wp option get blogname' });
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
expect(result.stdout).toContain('Wursor');
|
||||||
|
});
|
||||||
|
it('rejects commands in the destructive category without confirm', async () => { /* ... */ });
|
||||||
|
it('timeouts after 30 seconds', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/tool-bus/__tests__/tools/site.test.ts
|
||||||
|
describe('site.browse', () => {
|
||||||
|
it('returns the HTML of a URL', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/tool-bus/__tests__/tools/db.test.ts
|
||||||
|
describe('db.query', () => {
|
||||||
|
it('executes a read-only SQL query', async () => { /* ... */ });
|
||||||
|
it('rejects INSERT/UPDATE/DELETE queries', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/tool-bus/__tests__/executor.test.ts
|
||||||
|
describe('Executor', () => {
|
||||||
|
it('spawns a shell command and captures output', async () => { /* ... */ });
|
||||||
|
it('applies a timeout to long-running commands', async () => { /* ... */ });
|
||||||
|
it('streams output to a callback', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Implement**
|
||||||
|
|
||||||
|
- **`packages/tool-bus/src/registry.ts`** — Map of tool name → { schema, handler, category }
|
||||||
|
- **`packages/tool-bus/src/schemas.ts`** — JSON Schema for each tool
|
||||||
|
- **`packages/tool-bus/src/tools/fs.ts`** — File system operations (path-scoped to workspace)
|
||||||
|
- **`packages/tool-bus/src/tools/wpcli.ts`** — WP-CLI runner with categorized allowlist
|
||||||
|
- **`packages/tool-bus/src/tools/site.ts`** — HTTP fetch + screenshot via Puppeteer
|
||||||
|
- **`packages/tool-bus/src/tools/db.ts`** — MySQL read-only query via wp-env credentials
|
||||||
|
- **`packages/tool-bus/src/tools/lint.ts`** — PHPCS wrapper
|
||||||
|
- **`packages/tool-bus/src/tools/test.ts`** — PHPUnit wrapper
|
||||||
|
- **`packages/tool-bus/src/tools/index.ts`** — Knowledge graph search (stub until Phase 2)
|
||||||
|
- **`packages/tool-bus/src/executor.ts`** — `child_process.spawn` wrapper with timeout + streaming
|
||||||
|
|
||||||
|
#### Deliverables
|
||||||
|
|
||||||
|
- Tool registry with all 9 tools from §8.3
|
||||||
|
- Each tool has unit tests for happy path, error path, and security boundary
|
||||||
|
- `packages/tool-bus/__tests__/*` all passing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Sprint 4: Agent chat + diff review
|
||||||
|
|
||||||
|
**Goal:** Chat panel that sends tasks to Claude, receives tool calls, executes them, and shows diffs.
|
||||||
|
|
||||||
|
#### TDD sequence
|
||||||
|
|
||||||
|
**Step 1 — Write the unit tests**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// packages/agent-bridge/__tests__/client.test.ts
|
||||||
|
describe('AgentClient', () => {
|
||||||
|
it('sends a message to Claude API and returns a response', async () => {
|
||||||
|
const client = new AgentClient({ apiKey: 'test-key' });
|
||||||
|
const response = await client.send('Add a paragraph to index.php');
|
||||||
|
expect(response.type).toBe('tool_call');
|
||||||
|
});
|
||||||
|
it('handles API errors with a clear message', async () => { /* ... */ });
|
||||||
|
it('retries on transient failures', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/agent-bridge/__tests__/tool-schemas.test.ts
|
||||||
|
describe('ToolSchemas', () => {
|
||||||
|
it('converts tool registry schemas to Claude format', () => {
|
||||||
|
const schemas = toClaudeFormat(registry.getAll());
|
||||||
|
expect(schemas[0].name).toBe('fs.read');
|
||||||
|
expect(schemas[0].input_schema).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/agent-bridge/__tests__/context.test.ts
|
||||||
|
describe('ContextBuilder', () => {
|
||||||
|
it('builds a system prompt with WP semantics', () => { /* ... */ });
|
||||||
|
it('includes project rules from WORDPRESS.md', () => { /* ... */ });
|
||||||
|
it('includes knowledge graph context', () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/editor-core/__tests__/panels/chat-panel.test.ts
|
||||||
|
describe('ChatPanel', () => {
|
||||||
|
it('sends a message and displays the response', () => { /* ... */ });
|
||||||
|
it('shows tool calls as expandable cards', () => { /* ... */ });
|
||||||
|
it('shows diffs in a side-by-side view', () => { /* ... */ });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Implement**
|
||||||
|
|
||||||
|
- **`packages/agent-bridge/src/client.ts`** — Claude API client (messages API, tool use)
|
||||||
|
- **`packages/agent-bridge/src/tool-schemas.ts`** — Convert tool-bus schemas → Claude `tools` array
|
||||||
|
- **`packages/agent-bridge/src/context.ts`** — Build system prompt with WP semantics, project rules, and graph context
|
||||||
|
- **`packages/agent-bridge/src/fallback.ts`** — Error handling, retry with exponential backoff
|
||||||
|
- **`packages/editor-core/src/panels/chat-panel.ts`** — Chat UI (message list, input, tool call cards)
|
||||||
|
- **`packages/editor-core/src/panels/diff-panel.ts`** — Side-by-side diff view
|
||||||
|
- **`packages/editor-core/src/commands/run-playbook.ts`** — Command to trigger a playbook
|
||||||
|
|
||||||
|
**Step 3 — Integration test**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// e2e/electron/playbook-dynamic-block.test.ts
|
||||||
|
test('chat panel sends a task and executes a playbook', async () => {
|
||||||
|
const app = await electron.launch({ args: ['/path/to/fixtures/sample-theme'] });
|
||||||
|
const window = await app.firstWindow();
|
||||||
|
await window.locator('.wursor-chat-input').fill('Scaffold a dynamic block named "testimonial"');
|
||||||
|
await window.locator('.wursor-chat-send').click();
|
||||||
|
await expect(window.locator('.wursor-diff-view')).toBeVisible({ timeout: 60000 });
|
||||||
|
await app.close();
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Deliverables
|
||||||
|
|
||||||
|
- Working chat panel that sends to Claude and executes tool calls
|
||||||
|
- Diff view showing file changes
|
||||||
|
- `packages/agent-bridge/__tests__/*` passing
|
||||||
|
- Chat panel unit tests passing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Sprint 5: WP-CLI tool + permission engine
|
||||||
|
|
||||||
|
**Goal:** WP-CLI commands are categorized and gated by permission tiers. Secrets are redacted from agent context.
|
||||||
|
|
||||||
|
#### TDD sequence
|
||||||
|
|
||||||
|
**Step 1 — Write the unit tests**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// packages/permission-engine/__tests__/tiers.test.ts
|
||||||
|
describe('PermissionTiers', () => {
|
||||||
|
it('defines read FS, edit FS, WP-CLI safe, WP-CLI destructive, SQL read, SQL write, network install', () => {
|
||||||
|
expect(Tiers.READ_FS).toBeDefined();
|
||||||
|
expect(Tiers.WPCLI_DESTRUCTIVE).toBeDefined();
|
||||||
|
});
|
||||||
|
it('orders tiers from least to most permissive', () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/permission-engine/__tests__/evaluator.test.ts
|
||||||
|
describe('PolicyEvaluator', () => {
|
||||||
|
it('allows a tool call within the current tier', () => { /* ... */ });
|
||||||
|
it('blocks a tool call above the current tier', () => { /* ... */ });
|
||||||
|
it('requires confirmation for destructive tier', () => { /* ... */ });
|
||||||
|
it('blocks production writes by default', () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/permission-engine/__tests__/redactor.test.ts
|
||||||
|
describe('SecretRedactor', () => {
|
||||||
|
it('redacts values from .env files', () => {
|
||||||
|
const redacted = redact('DB_PASSWORD=secret123', ['secret123']);
|
||||||
|
expect(redacted).not.toContain('secret123');
|
||||||
|
});
|
||||||
|
it('redacts wp-config.php constants', () => { /* ... */ });
|
||||||
|
it('does not redact environment variable names', () => { /* ... */ });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Implement**
|
||||||
|
|
||||||
|
- **`packages/permission-engine/src/tiers.ts`** — Tier definitions as ordered enum
|
||||||
|
- **`packages/permission-engine/src/evaluator.ts`** — Policy evaluator (current tier, requested tier, environment, confirmation flag)
|
||||||
|
- **`packages/permission-engine/src/redactor.ts`** — Scan text for secrets from `.env` and `wp-config.php`, redact before sending to agent
|
||||||
|
- **`packages/permission-engine/src/config.ts`** — User-defined policy overrides (read from `.wursor/policy.json`)
|
||||||
|
- Wire permission engine into **`packages/tool-bus/src/tools/wpcli.ts`** — categorize and check before running
|
||||||
|
|
||||||
|
#### Deliverables
|
||||||
|
|
||||||
|
- Permission engine with all 7 tiers
|
||||||
|
- Secret redaction for `.env` and `wp-config.php`
|
||||||
|
- WP-CLI tool categorized and gated
|
||||||
|
- `packages/permission-engine/__tests__/*` passing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Sprint 6: P0 playbooks + first-run
|
||||||
|
|
||||||
|
**Goal:** Four P0 playbooks (dynamic block, child theme, CPT, plugin) are executable from the chat panel. First-run experience guides the user through project open and dependency check.
|
||||||
|
|
||||||
|
#### TDD sequence
|
||||||
|
|
||||||
|
**Step 1 — Write the unit tests**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// packages/playbooks/__tests__/dynamic-block.test.ts
|
||||||
|
describe('DynamicBlockPlaybook', () => {
|
||||||
|
it('detects the build setup', async () => {
|
||||||
|
const playbook = new DynamicBlockPlaybook();
|
||||||
|
const config = await playbook.detect(workspacePath);
|
||||||
|
expect(config.buildTool).toBe('@wordpress/scripts');
|
||||||
|
});
|
||||||
|
it('scaffolds a block with correct metadata', async () => { /* ... */ });
|
||||||
|
it('registers the block in the plugin file', async () => { /* ... */ });
|
||||||
|
it('builds the assets', async () => { /* ... */ });
|
||||||
|
it('verifies the block appears in the editor', async () => { /* ... */ });
|
||||||
|
it('produces a diff of all changes', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/playbooks/__tests__/child-theme.test.ts
|
||||||
|
describe('ChildThemePlaybook', () => {
|
||||||
|
it('creates a style.css with correct Template header', async () => { /* ... */ });
|
||||||
|
it('enqueues parent theme styles', async () => { /* ... */ });
|
||||||
|
it('overrides a template with screenshot verification', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/playbooks/__tests__/cpt.test.ts
|
||||||
|
describe('CptPlaybook', () => {
|
||||||
|
it('registers a CPT with REST support', async () => { /* ... */ });
|
||||||
|
it('flushes rewrite rules via WP-CLI', async () => { /* ... */ });
|
||||||
|
it('seeds test data via WP-CLI', async () => { /* ... */ });
|
||||||
|
it('verifies the REST endpoint returns data', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
|
||||||
|
// packages/playbooks/__tests__/plugin.test.ts
|
||||||
|
describe('PluginPlaybook', () => {
|
||||||
|
it('creates plugin headers', async () => { /* ... */ });
|
||||||
|
it('sets up Composer if requested', async () => { /* ... */ });
|
||||||
|
it('sets up PHPUnit if requested', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Integration tests**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// e2e/first-run.test.ts
|
||||||
|
describe('First-run experience', () => {
|
||||||
|
it('shows project open dialog on first launch', async () => { /* ... */ });
|
||||||
|
it('detects Docker and wp-env, guides install if missing', async () => { /* ... */ });
|
||||||
|
it('opens a project and shows the workspace within 10 minutes', async () => { /* ... */ });
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3 — Implement**
|
||||||
|
|
||||||
|
- **`packages/playbooks/src/registry.ts`** — Playbook registration
|
||||||
|
- **`packages/playbooks/src/dynamic-block.ts`** — Full playbook: detect build → scaffold → register → build → verify → diff
|
||||||
|
- **`packages/playbooks/src/child-theme.ts`** — Full playbook: scaffold → enqueue → override → screenshot
|
||||||
|
- **`packages/playbooks/src/cpt.ts`** — Full playbook: register → flush → seed → REST check → diff
|
||||||
|
- **`packages/playbooks/src/plugin.ts`** — Full playbook: headers → optional Composer/PHPUnit
|
||||||
|
- **`packages/editor-core/src/commands/open-project.ts`** — First-run dialog with three paths
|
||||||
|
- **`packages/editor-core/src/commands/verify-preview.ts`** — Verify step integration
|
||||||
|
|
||||||
|
#### Deliverables
|
||||||
|
|
||||||
|
- 4 P0 playbooks with unit tests
|
||||||
|
- First-run dialog (3 paths: WP repo, plain folder, sample project)
|
||||||
|
- Dependency check (Docker, wp-env) with install guidance
|
||||||
|
- `e2e/first-run.test.ts` passing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Sprint 7: Integration + exit criteria
|
||||||
|
|
||||||
|
**Goal:** All Phase 1 pieces work together. The exit criteria test passes end-to-end.
|
||||||
|
|
||||||
|
#### Integration test
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// e2e/phase1-exit-criteria.test.ts
|
||||||
|
describe('Phase 1 exit criteria', () => {
|
||||||
|
test('clean machine → live preview in ≤10 min', async () => {
|
||||||
|
// Simulate a clean machine (no Docker, no wp-env)
|
||||||
|
const app = await electron.launch({ args: [] });
|
||||||
|
const window = await app.firstWindow();
|
||||||
|
const startTime = Date.now();
|
||||||
|
// Follow first-run dialog → install Docker → install wp-env → open project → boot
|
||||||
|
await window.locator('.wursor-first-run-open-repo').click();
|
||||||
|
await window.locator('.wursor-project-picker').fill('/path/to/fixtures/sample-theme');
|
||||||
|
await window.locator('.wursor-confirm-open').click();
|
||||||
|
// Wait for runtime to boot
|
||||||
|
await expect(window.locator('.wursor-status-indicator')).toHaveText('running', { timeout: 600000 });
|
||||||
|
const elapsed = Date.now() - startTime;
|
||||||
|
expect(elapsed).toBeLessThan(10 * 60 * 1000);
|
||||||
|
await app.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('P0 playbook completes with verified preview + accepted diff', async () => {
|
||||||
|
const app = await electron.launch({ args: ['/path/to/fixtures/sample-theme'] });
|
||||||
|
const window = await app.firstWindow();
|
||||||
|
// Wait for runtime
|
||||||
|
await expect(window.locator('.wursor-status-indicator')).toHaveText('running', { timeout: 60000 });
|
||||||
|
// Run playbook
|
||||||
|
await window.locator('.wursor-chat-input').fill('Create a dynamic block named "testimonial"');
|
||||||
|
await window.locator('.wursor-chat-send').click();
|
||||||
|
// Wait for diff
|
||||||
|
await expect(window.locator('.wursor-diff-view')).toBeVisible({ timeout: 120000 });
|
||||||
|
// Wait for verify
|
||||||
|
await expect(window.locator('.wursor-verify-result')).toBeVisible({ timeout: 60000 });
|
||||||
|
// Accept
|
||||||
|
await window.locator('.wursor-accept-diff').click();
|
||||||
|
await expect(window.locator('.wursor-accepted-badge')).toBeVisible();
|
||||||
|
await app.close();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Deliverables
|
||||||
|
|
||||||
|
- Both exit criteria tests passing
|
||||||
|
- All unit tests passing (`pnpm test`)
|
||||||
|
- All integration tests passing (`pnpm test:integration`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Sprint 8: Polish + alpha readiness
|
||||||
|
|
||||||
|
**Goal:** Error states from §8.5 are handled, app packaging works, and the build is ready for internal alpha.
|
||||||
|
|
||||||
|
#### Tasks
|
||||||
|
|
||||||
|
- **Error states** — Wire each error state from §8.5 into the UI
|
||||||
|
- **App packaging** — `electron-builder` produces signed `.dmg` (macOS) and `.exe` (Windows)
|
||||||
|
- **Auto-update** — `electron-updater` with GitHub releases
|
||||||
|
- **Telemetry** — Minimal events (preview load time, playbook run, verify result) with consent dialog
|
||||||
|
- **Documentation** — `README.md` with install instructions and quickstart
|
||||||
|
- **Bug bash** — Internal team runs through the first-run + playbook flow
|
||||||
|
|
||||||
|
#### Deliverables
|
||||||
|
|
||||||
|
- Signed app bundles for macOS + Windows
|
||||||
|
- Auto-update mechanism
|
||||||
|
- Error states all wired
|
||||||
|
- Minimal telemetry with consent
|
||||||
|
- `README.md` updated for alpha users
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Phase 2 — Intelligence (Weeks 9–16)
|
||||||
|
|
||||||
|
*High-level outline only — full breakdown will follow Phase 1 exit.*
|
||||||
|
|
||||||
|
| Sprint | Focus | Packages |
|
||||||
|
|--------|-------|----------|
|
||||||
|
| 9 | Knowledge graph static scanner | `packages/knowledge-index/src/scanner/static-scanner.ts` |
|
||||||
|
| 10 | Knowledge graph runtime enricher | `packages/knowledge-index/src/scanner/runtime-enricher.ts` |
|
||||||
|
| 11 | Knowledge graph queries + UI | `packages/knowledge-index/src/queries.ts`, tree view |
|
||||||
|
| 12 | State Diff lifecycle | `packages/state-diff/src/lifecycle.ts` |
|
||||||
|
| 13 | State Diff UI + rollback | `packages/state-diff/src/rollback.ts`, diff panel |
|
||||||
|
| 14 | Quality gates (PHPCS, PHPUnit) | `packages/tool-bus/src/tools/lint.ts`, `test.ts` |
|
||||||
|
| 15 | Staging pull connector | `packages/tool-bus/src/tools/staging.ts` |
|
||||||
|
| 16 | Closed alpha ship + baseline collection | Telemetry review, §11 baselines |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. TDD Rules
|
||||||
|
|
||||||
|
These rules apply to every sprint:
|
||||||
|
|
||||||
|
1. **Write the test first.** No implementation code is written without a failing test.
|
||||||
|
2. **One assertion per test.** Each test verifies exactly one behavior.
|
||||||
|
3. **Tests are deterministic.** No network calls in unit tests (mock Claude API, mock wp-env).
|
||||||
|
4. **Integration tests use fixtures.** Sample WP repos live in `packages/*/fixtures/` and `e2e/fixtures/`.
|
||||||
|
5. **Red → Green → Refactor.** Write the failing test (red), make it pass (green), then clean up (refactor).
|
||||||
|
6. **Coverage floor.** Each package must maintain ≥ 90% line coverage. CI enforces this.
|
||||||
|
7. **No skipped tests in main.** `test.skip` and `test.only` are only allowed in feature branches.
|
||||||
|
|
||||||
|
### Test naming convention
|
||||||
|
|
||||||
|
```
|
||||||
|
{module}.{behavior}.test.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- `fs.read-workspace-file.test.ts`
|
||||||
|
- `wpcli.reject-destructive-without-confirm.test.ts`
|
||||||
|
- `lifecycle.start-and-report-status.test.ts`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. CI/CD Pipeline
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# .github/workflows/ci.yml — runs on every PR
|
||||||
|
name: CI
|
||||||
|
on: [pull_request]
|
||||||
|
jobs:
|
||||||
|
unit:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: pnpm/action-setup@v2
|
||||||
|
- run: pnpm install
|
||||||
|
- run: pnpm test # All unit tests
|
||||||
|
- run: pnpm test:coverage # Enforces 90% floor
|
||||||
|
|
||||||
|
integration:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: pnpm/action-setup@v2
|
||||||
|
- run: pnpm install
|
||||||
|
- run: pnpm test:integration # Fixture-based integration tests
|
||||||
|
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: pnpm/action-setup@v2
|
||||||
|
- run: pnpm install
|
||||||
|
- run: pnpm lint
|
||||||
|
|
||||||
|
# .github/workflows/e2e.yml — runs on release branch
|
||||||
|
name: E2E
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [release/*]
|
||||||
|
jobs:
|
||||||
|
e2e:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [macos-latest, windows-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: pnpm/action-setup@v2
|
||||||
|
- run: pnpm install
|
||||||
|
- run: pnpm build
|
||||||
|
- run: pnpm test:e2e
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Glossary
|
||||||
|
|
||||||
|
| Term | Definition |
|
||||||
|
|------|------------|
|
||||||
|
| **Tool bus** | The registry and executor for all agent-callable tools (fs, wpcli, site, db, etc.) |
|
||||||
|
| **Runtime adapter** | Interface that abstracts wp-env (v1) behind a common API for future backends |
|
||||||
|
| **Playbook** | A reusable, multi-step agent workflow (scaffold block, create CPT, etc.) |
|
||||||
|
| **State Diff** | A reviewable mutation plan for WP content/state (CLI commands, SQL, or migration) |
|
||||||
|
| **Permission tier** | A capability level (read FS → edit FS → WP-CLI safe → destructive → etc.) |
|
||||||
|
| **Verify** | Required proof step: screenshot, HTTP check, or editor route confirmation |
|
||||||
|
| **Knowledge graph** | Indexed map of themes, plugins, blocks, hooks, and REST routes |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*End of Implementation Guide v1.0 — Wursor*
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Product Requirements Document
|
# Product Requirements Document
|
||||||
|
|
||||||
**Wordbench**
|
**Wursor**
|
||||||
|
|
||||||
The Agentic WordPress Development Environment
|
The Agentic WordPress Development Environment
|
||||||
|
|
||||||
@@ -8,23 +8,23 @@ The Agentic WordPress Development Environment
|
|||||||
|
|
||||||
| Field | Value |
|
| Field | Value |
|
||||||
| :--- | :--- |
|
| :--- | :--- |
|
||||||
| **Version** | 1.1 |
|
| **Version** | 1.2 |
|
||||||
| **Date** | August 12, 2026 |
|
| **Date** | August 13, 2026 |
|
||||||
| **Author** | Patrick (Product Lead) |
|
| **Author** | Patrick (Product Lead) |
|
||||||
| **Status** | Draft — Internal |
|
| **Status** | Draft — Internal (key decisions locked; Phase 0) |
|
||||||
| **Repo** | SinachPat/originmain (pivoting; rename TBD) |
|
| **Repo** | SinachPat/wursor (renamed from originmain) |
|
||||||
| **Classification** | Confidential |
|
| **Classification** | Confidential |
|
||||||
| **Supersedes** | v1.0 (removed editor-clone framing) |
|
| **Supersedes** | v1.1 (renamed to Wursor; locked key decisions) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Executive Summary
|
## 1. Executive Summary
|
||||||
|
|
||||||
Wordbench is a development environment built for people who ship on WordPress. It combines an AI agent that can plan and edit real project code with a live WordPress runtime, WP-CLI, database awareness, and preview — so building a theme, plugin, or block is not split across five apps and a hope that the model "knows WordPress."
|
Wursor is a development environment built for people who ship on WordPress. It combines an AI agent that can plan and edit real project code with a live WordPress runtime, WP-CLI, database awareness, and preview — so building a theme, plugin, or block is not split across five apps and a hope that the model "knows WordPress."
|
||||||
|
|
||||||
WordPress work is not generic app development. The product surface is a CMS platform with themes, plugins, hooks, a block editor, content in MySQL, and a long tail of agency and product workflows. Today's stack forces builders to keep that reality in their head while jumping between an editor, a local site tool, wp-admin, a terminal for WP-CLI, and a database client.
|
WordPress work is not generic app development. The product surface is a CMS platform with themes, plugins, hooks, a block editor, content in MySQL, and a long tail of agency and product workflows. Today's stack forces builders to keep that reality in their head while jumping between an editor, a local site tool, wp-admin, a terminal for WP-CLI, and a database client.
|
||||||
|
|
||||||
Wordbench makes that reality the environment:
|
Wursor makes that reality the environment:
|
||||||
|
|
||||||
- A **site you can boot, browse, reset, and inspect** sits beside the code.
|
- A **site you can boot, browse, reset, and inspect** sits beside the code.
|
||||||
- The agent is taught **WordPress semantics** — template hierarchy, hooks, `block.json`, capabilities, text domains — not only PHP syntax.
|
- The agent is taught **WordPress semantics** — template hierarchy, hooks, `block.json`, capabilities, text domains — not only PHP syntax.
|
||||||
@@ -77,18 +77,18 @@ WordPress sites are high-value targets. An agent that can edit `wp-config.php`,
|
|||||||
|
|
||||||
## 3. Vision & Opportunity
|
## 3. Vision & Opportunity
|
||||||
|
|
||||||
**Vision:** Open a WordPress project in Wordbench and you get a workspace that already understands the shape of the project, can start the site, and can take a job like "add a pricing block that matches our patterns and verify it on /pricing" through edit → CLI → preview → review in one place.
|
**Vision:** Open a WordPress project in Wursor and you get a workspace that already understands the shape of the project, can start the site, and can take a job like "add a pricing block that matches our patterns and verify it on /pricing" through edit → CLI → preview → review in one place.
|
||||||
|
|
||||||
Wordbench sits at the intersection of:
|
Wursor sits at the intersection of:
|
||||||
|
|
||||||
| Category | What exists | What Wordbench adds |
|
| Category | What exists | What Wursor adds |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| AI-assisted coding | General editors and agents | WP-native tools, playbooks, and site loop |
|
| AI-assisted coding | General editors and agents | WP-native tools, playbooks, and site loop |
|
||||||
| Local WP environments | Local, DDEV, wp-env | Runtime embedded and controllable by the agent |
|
| Local WP environments | Local, DDEV, wp-env | Runtime embedded and controllable by the agent |
|
||||||
| In-admin AI helpers | Host and plugin copilots | Real engineering workspace (Git, diffs, tests), not post drafting |
|
| In-admin AI helpers | Host and plugin copilots | Real engineering workspace (Git, diffs, tests), not post drafting |
|
||||||
| Block / theme tooling | `@wordpress/scripts`, theme.json editors | Unified with agent + live preview |
|
| Block / theme tooling | `@wordpress/scripts`, theme.json editors | Unified with agent + live preview |
|
||||||
|
|
||||||
**Positioning:** Wordbench is the agentic **WordPress workshop** — not a generic coding assistant with a WordPress sticker, and not an AI writing widget inside wp-admin.
|
**Positioning:** Wursor is the agentic **WordPress workshop** — not a generic coding assistant with a WordPress sticker, and not an AI writing widget inside wp-admin.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ Scopes builds, reviews proposed changes, cares about migration plans and staging
|
|||||||
2. **Code and state are both first-class** — File diffs and explicit State Diffs; no silent DB mutation.
|
2. **Code and state are both first-class** — File diffs and explicit State Diffs; no silent DB mutation.
|
||||||
3. **WordPress semantics over generic PHP** — Prefer platform APIs, hooks, and patterns a senior WP engineer would choose.
|
3. **WordPress semantics over generic PHP** — Prefer platform APIs, hooks, and patterns a senior WP engineer would choose.
|
||||||
4. **Safe by default** — Capability-scoped tools; production gated; secrets redacted; destructive ops require confirmation.
|
4. **Safe by default** — Capability-scoped tools; production gated; secrets redacted; destructive ops require confirmation.
|
||||||
5. **Preview is proof** — Prefer screenshots, HTTP checks, or editor verification over "trust me."
|
5. **Preview is proof** — The agent cannot mark a task "done" without a verify step (screenshot, HTTP check, or editor verification). Users may dismiss the proof; the agent may not skip producing it.
|
||||||
6. **Git records code; scripts record state** — Migrations and WP-CLI plans are reviewable artifacts.
|
6. **Git records code; scripts record state** — Migrations and WP-CLI plans are reviewable artifacts.
|
||||||
7. **Opinionated for WordPress** — Defaults follow WPCS, wp-env, and block-era workflows; escape hatches exist but are not the center.
|
7. **Opinionated for WordPress** — Defaults follow WPCS, wp-env, and block-era workflows; escape hatches exist but are not the center.
|
||||||
|
|
||||||
@@ -140,6 +140,8 @@ A **Workspace** binds:
|
|||||||
- A **site runtime** (wp-env by default; Docker / Local / DDEV import paths)
|
- A **site runtime** (wp-env by default; Docker / Local / DDEV import paths)
|
||||||
- Environment config (local / staging / production endpoints and a credentials vault)
|
- Environment config (local / staging / production endpoints and a credentials vault)
|
||||||
|
|
||||||
|
> **v1 scope (locked):** wp-env is the *only* supported runtime in v1. Local / DDEV / Bedrock import is P1 (§7.2.6). The runtime manager is still abstraction-bound (§8.1) so adding those backends later does not require a redesign.
|
||||||
|
|
||||||
### 6.2 WordPress Knowledge Graph
|
### 6.2 WordPress Knowledge Graph
|
||||||
|
|
||||||
Indexed understanding of:
|
Indexed understanding of:
|
||||||
@@ -152,17 +154,30 @@ Indexed understanding of:
|
|||||||
- `theme.json` tokens and style variations
|
- `theme.json` tokens and style variations
|
||||||
- Template hierarchy for key routes
|
- Template hierarchy for key routes
|
||||||
|
|
||||||
|
**Build source (locked):** two passes. (1) *Static* — scan of `*.php`, `block.json`, `theme.json`, and plugin/theme headers at project open, refreshed on file-save and on git checkout. (2) *Runtime* — when the site is up, enrich via WP-CLI (`wp plugin list`, `wp theme list`, `wp post-type list`, `wp rewrite list`) with the *actual* active theme, active plugins, registered CPTs/taxonomies, and REST routes.
|
||||||
|
|
||||||
|
**Freshness model:** every graph node carries a source stamp (static vs runtime) and timestamp. Both the agent context and the UI surface staleness explicitly (e.g., "active theme — static scan, site not loaded"). Full re-index runs on project open and on every `site.browse` boot; incremental updates follow file-save events. Runtime nodes are re-verified each time the site boots.
|
||||||
|
|
||||||
### 6.3 The build loop
|
### 6.3 The build loop
|
||||||
|
|
||||||
Plan → edit files → run WP-CLI / tests → refresh preview → read logs → revise. Every step uses WordPress-aware tools.
|
Plan → edit files → run WP-CLI / tests → refresh preview → read logs → revise. Every step uses WordPress-aware tools.
|
||||||
|
|
||||||
### 6.4 State Diffs
|
### 6.4 State Diffs
|
||||||
|
|
||||||
When a task needs content or options changes, Wordbench proposes a **State Diff**: WP-CLI commands and/or a migration script to review, apply, and commit — not an invisible database tweak.
|
When a task needs content or options changes, Wursor proposes a **State Diff**: WP-CLI commands and/or a migration script — never an invisible database tweak. The lifecycle is explicit:
|
||||||
|
|
||||||
|
1. **Create** — the agent generates a candidate diff (WP-CLI commands, SQL statements, or a PHP migration), each step annotated with intent and blast radius.
|
||||||
|
2. **Review** — shown in the State tab; every step expands to full text and effect; nothing runs without review.
|
||||||
|
3. **Stage** — approved steps form a numbered plan; steps can be reordered or dropped.
|
||||||
|
4. **Apply** — executes against the local environment by default; each step streams output and marks pass/fail.
|
||||||
|
5. **Verify** — the agent re-checks the site (option read-back, URL load, screenshot) before the diff counts as applied.
|
||||||
|
6. **Commit** — migration-style state scripts commit to the repo as `db/` migrations; pure WP-CLI plans persist as reviewable `.state-diff.json` artifacts under `.wursor/state-diffs/`.
|
||||||
|
|
||||||
|
**Rollback (locked):** destructive steps must declare an inverse at create time (e.g., `wp option delete` paired with the prior value) or an explicit "manual backup required" acknowledgment; Wursor refuses to stage a destructive step without one.
|
||||||
|
|
||||||
### 6.5 Rules & Playbooks
|
### 6.5 Rules & Playbooks
|
||||||
|
|
||||||
Project guidance lives in `WORDPRESS.md` / `.wordbench/rules` (standards, banned patterns, deploy checklists). **Playbooks** are reusable workflows: scaffold a dynamic block, spin a child theme, register a CPT, harden a plugin release.
|
Project guidance lives in `WORDPRESS.md` / `.wursor/rules` (standards, banned patterns, deploy checklists). **Playbooks** are reusable workflows: scaffold a dynamic block, spin a child theme, register a CPT, harden a plugin release.
|
||||||
|
|
||||||
### 6.6 Environments
|
### 6.6 Environments
|
||||||
|
|
||||||
@@ -184,7 +199,7 @@ Project guidance lives in `WORDPRESS.md` / `.wordbench/rules` (standards, banned
|
|||||||
- Multi-file agent runs with reviewable patches
|
- Multi-file agent runs with reviewable patches
|
||||||
- Integrated terminal
|
- Integrated terminal
|
||||||
- Git status, diff review, commit assist
|
- Git status, diff review, commit assist
|
||||||
- Project rules (`WORDPRESS.md`, `.wordbench/rules`)
|
- Project rules (`WORDPRESS.md`, `.wursor/rules`)
|
||||||
|
|
||||||
#### 7.1.2 WordPress project intelligence
|
#### 7.1.2 WordPress project intelligence
|
||||||
- Detect project shape: classic theme, block theme, single plugin, `wp-content` tree, Bedrock/Composer
|
- Detect project shape: classic theme, block theme, single plugin, `wp-content` tree, Bedrock/Composer
|
||||||
@@ -193,9 +208,10 @@ Project guidance lives in `WORDPRESS.md` / `.wordbench/rules` (standards, banned
|
|||||||
- Template hierarchy and `block.json` awareness
|
- Template hierarchy and `block.json` awareness
|
||||||
|
|
||||||
#### 7.1.3 Embedded local site runtime
|
#### 7.1.3 Embedded local site runtime
|
||||||
- Start/stop/reset via **wp-env** (default), with documented Docker compose escape hatch
|
- Start/stop/reset via **wp-env** — the only supported runtime in v1 (the emitted Docker compose file is for debugging, not an alternative surface)
|
||||||
- Embedded preview (front end + wp-admin)
|
- Embedded preview (front end + wp-admin)
|
||||||
- Log tail (PHP / web server; Query Monitor later)
|
- Log tail (PHP / web server; Query Monitor later)
|
||||||
|
- Runtime manager is abstraction-bound (§8.1); Local / DDEV import (P1) plugs in behind the same interface
|
||||||
|
|
||||||
#### 7.1.4 WP-CLI as an agent tool
|
#### 7.1.4 WP-CLI as an agent tool
|
||||||
- Allowlisted WP-CLI runner
|
- Allowlisted WP-CLI runner
|
||||||
@@ -208,8 +224,10 @@ Project guidance lives in `WORDPRESS.md` / `.wordbench/rules` (standards, banned
|
|||||||
- Redact secrets from `.env` / `wp-config` in agent context; scan on apply
|
- Redact secrets from `.env` / `wp-config` in agent context; scan on apply
|
||||||
|
|
||||||
#### 7.1.6 Preview verification
|
#### 7.1.6 Preview verification
|
||||||
- Optional verify step: load URLs, screenshot, basic error sniff
|
- Verify runs by default on every agent task and is required before the agent marks a task "done" (Principle 5); users may dismiss the proof, the agent cannot skip producing it
|
||||||
|
- Verify step: load URLs, screenshot, HTTP status + basic error sniff (PHP error log, 500s)
|
||||||
- For block tasks: open editor routes and confirm the block can be inserted (lightweight P0)
|
- For block tasks: open editor routes and confirm the block can be inserted (lightweight P0)
|
||||||
|
- Failures surface explicitly — "verify failed: /pricing returned 500" with the log excerpt — never a silent retry
|
||||||
|
|
||||||
#### 7.1.7 Scaffolding playbooks
|
#### 7.1.7 Scaffolding playbooks
|
||||||
- Plugin (headers, text domain, optional Composer/PHPUnit)
|
- Plugin (headers, text domain, optional Composer/PHPUnit)
|
||||||
@@ -217,6 +235,12 @@ Project guidance lives in `WORDPRESS.md` / `.wordbench/rules` (standards, banned
|
|||||||
- Child theme
|
- Child theme
|
||||||
- CPT + REST + minimal admin UI
|
- CPT + REST + minimal admin UI
|
||||||
|
|
||||||
|
#### 7.1.8 First-run experience
|
||||||
|
- Install: single signed app bundle (macOS + Windows; Linux best-effort); no Docker prompt before first project open
|
||||||
|
- First open: guided "open a project" with three paths — a WordPress repo (auto-detects wp-env config), a plain theme/plugin folder, or a built-in sample project
|
||||||
|
- Dependency check: Docker / wp-env detection with one-click install guidance and a diagnostic panel — a dead end is not an option
|
||||||
|
- First preview target: ≤ 10 minutes p50 from install to a live preview (§11)
|
||||||
|
|
||||||
### 7.2 P1 — Follow-on
|
### 7.2 P1 — Follow-on
|
||||||
|
|
||||||
#### 7.2.1 Database & options introspection
|
#### 7.2.1 Database & options introspection
|
||||||
@@ -263,19 +287,29 @@ Project guidance lives in `WORDPRESS.md` / `.wordbench/rules` (standards, banned
|
|||||||
|
|
||||||
### 8.1 Layers
|
### 8.1 Layers
|
||||||
|
|
||||||
|
> **Shell decision (locked):** Desktop Electron app wrapping Code-OSS (VS Code's open-source editor core). Chosen because Wursor needs direct filesystem access, Docker socket control, embedded iframe preview, and native OS integration — a web IDE would require a local daemon layer that adds complexity with no benefit. The editor core is extended with Wursor panels and custom views, not abstracted from.
|
||||||
|
|
||||||
| Layer | Responsibility |
|
| Layer | Responsibility |
|
||||||
| :--- | :--- |
|
| :--- | :--- |
|
||||||
| **Workspace shell** | Files, agent chat, terminal, git, preview layout |
|
| **Workspace shell** | Electron window, Code-OSS editor core, custom Wursor panels (preview, diff, state), terminal, git |
|
||||||
| **WP language services** | PHP/JS, stubs, `block.json`, `theme.json` schemas |
|
| **WP language services** | PHP/JS, stubs, `block.json`, `theme.json` schemas |
|
||||||
| **Site runtime manager** | wp-env/Docker lifecycle, ports, credentials |
|
| **Site runtime manager** | wp-env/Docker lifecycle, ports, credentials (abstraction-bound for future backends) |
|
||||||
| **Agent tool bus** | Files, WP-CLI, HTTP preview, DB read, linters |
|
| **Agent tool bus** | Files, WP-CLI, HTTP preview, DB read, linters (tool-calling interface, one schema per tool) |
|
||||||
| **Knowledge index** | Code index + WP graph |
|
| **Knowledge index** | Code index + WP graph (static scan + runtime enrichment) |
|
||||||
| **Policy engine** | Permissions, environment gates, secret redaction |
|
| **Policy engine** | Permissions, environment gates, secret redaction |
|
||||||
| **Preview / verify** | Embedded browser, screenshots, checks |
|
| **Preview / verify** | Embedded browser, screenshots, HTTP checks, error sniff |
|
||||||
| **Connectors** | GitHub, staging hosts, optional design tools |
|
| **Connectors** | GitHub, staging hosts, optional design tools |
|
||||||
|
|
||||||
|
### 8.1.1 Agent substrate (locked)
|
||||||
|
|
||||||
|
- **Model:** Anthropic Claude (current best-in-class agentic coding); BYO API key at launch
|
||||||
|
- **Routing:** All agent traffic goes through the user's own API key — no Wursor-hosted model tier in v1
|
||||||
|
- **Tool-calling protocol:** Every agent tool (§8.3) is a single tool schema, not a prompt chain. The agent calls tools; the tool bus executes against the local environment
|
||||||
|
- **Fallback:** If the model is unreachable or returns an error, the agent panel shows a clear "Model unavailable" state with the raw error, logs, and a retry button. The workspace shell (editing, terminal, preview) remains fully functional
|
||||||
|
- **P1 upsell:** Optional Wursor-hosted routing tier for users who prefer a managed key or bundled tokens
|
||||||
|
|
||||||
### 8.2 Default local stack
|
### 8.2 Default local stack
|
||||||
- **wp-env** for local + CI parity
|
- **wp-env** for local + CI parity (sole runtime in v1; runtime manager abstraction-bound for future backends)
|
||||||
- MySQL as default; optional ultralight SQLite path for demos only
|
- MySQL as default; optional ultralight SQLite path for demos only
|
||||||
- Node LTS for block builds
|
- Node LTS for block builds
|
||||||
|
|
||||||
@@ -296,6 +330,18 @@ Project guidance lives in `WORDPRESS.md` / `.wordbench/rules` (standards, banned
|
|||||||
5. Load /pricing and editor insert path; capture proof.
|
5. Load /pricing and editor insert path; capture proof.
|
||||||
6. Present file diffs (+ State Diff if any); user accepts.
|
6. Present file diffs (+ State Diff if any); user accepts.
|
||||||
|
|
||||||
|
### 8.5 Error & offline states
|
||||||
|
|
||||||
|
| State | What Wursor does |
|
||||||
|
| :--- | :--- |
|
||||||
|
| **Docker not installed** | Detect at project open; show diagnostic panel with one-click install guide; app remains usable for file editing and git |
|
||||||
|
| **wp-env not found** | Offer to install via npm; fall back to npx |
|
||||||
|
| **Site won't boot** | Stream logs live; highlight the first error; offer "reset" and "last known good config" |
|
||||||
|
| **Model unreachable** | Show raw error + retry; workspace shell stays fully functional |
|
||||||
|
| **API key invalid / expired** | Prompt for key update inline; no data loss |
|
||||||
|
| **Network offline** | Cache last-known graph state; agent panel shows "offline" warning; local site and editing unaffected |
|
||||||
|
| **File permission denied** | Surface the OS-level error; no silent fallback to a different path |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. UX Notes
|
## 9. UX Notes
|
||||||
@@ -310,14 +356,14 @@ Project guidance lives in `WORDPRESS.md` / `.wordbench/rules` (standards, banned
|
|||||||
|
|
||||||
## 10. Competitive Landscape
|
## 10. Competitive Landscape
|
||||||
|
|
||||||
| Product type | Strength | Gap Wordbench fills |
|
| Product type | Strength | Gap Wursor fills |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| General AI code editors | Strong general coding agents | No WordPress runtime loop or WP semantics |
|
| General AI code editors | Strong general coding agents | No WordPress runtime loop or WP semantics |
|
||||||
| Classic PHP IDEs | Deep PHP tooling | Weak agent-native site loop |
|
| Classic PHP IDEs | Deep PHP tooling | Weak agent-native site loop |
|
||||||
| Local WP apps | Easy site spin-up | Not an engineering agent workspace |
|
| Local WP apps | Easy site spin-up | Not an engineering agent workspace |
|
||||||
| wp-env / DDEV | Solid runtimes | CLI-centric; no integrated agent UX |
|
| wp-env / DDEV | Solid runtimes | CLI-centric; no integrated agent UX |
|
||||||
| Host / plugin AI | Handy in wp-admin | Content-oriented; not Git/theme/plugin shipping |
|
| Host / plugin AI | Handy in wp-admin | Content-oriented; not Git/theme/plugin shipping |
|
||||||
| Page builders | Fast visual pages | Different paradigm; not Wordbench's v1 center |
|
| Page builders | Fast visual pages | Different paradigm; not Wursor's v1 center |
|
||||||
|
|
||||||
**Moat:** WP knowledge graph + controllable runtime + policy-aware tools + verify-via-preview, packaged as playbooks agencies and plugin teams repeat weekly.
|
**Moat:** WP knowledge graph + controllable runtime + policy-aware tools + verify-via-preview, packaged as playbooks agencies and plugin teams repeat weekly.
|
||||||
|
|
||||||
@@ -325,13 +371,15 @@ Project guidance lives in `WORDPRESS.md` / `.wordbench/rules` (standards, banned
|
|||||||
|
|
||||||
## 11. Metrics & Success Criteria
|
## 11. Metrics & Success Criteria
|
||||||
|
|
||||||
| Metric | 6-month target | Notes |
|
| Metric | Baseline | 6-month target | Owner | How we measure |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- | :--- |
|
||||||
| Time to first local preview from new workspace | ≤ 10 min p50 | Including deps |
|
| Time to first local preview from new workspace | TBD (Phase 0 spike) | ≤ 10 min p50 | Eng lead | In-app timer from project open to first rendered preview |
|
||||||
| Accepted agent runs on P0 playbooks (little rework) | ≥ 60% | Block, child theme, CPT |
|
| Accepted agent runs on P0 playbooks (little rework) | TBD (alpha 1) | ≥ 60% | PM | Per-playbook accept/reject event, tagged by playbook |
|
||||||
| Verify step catches issues before accept | ≥ 30% of failing tasks | Loop quality signal |
|
| Verify step catches issues before accept | TBD (alpha 1) | ≥ 30% of failing tasks | PM | Verify-fail event before accept, per task |
|
||||||
| Trial → weekly habit by week 4 | ≥ 40% | Retention |
|
| Trial → weekly habit by week 4 | TBD | ≥ 40% | PM | Weekly active usage per trial cohort |
|
||||||
| Paying seats | TBD with pricing | Agency teams primary |
|
| Paying seats | n/a | TBD with pricing | GTM | Billing records |
|
||||||
|
|
||||||
|
**Measurement plan:** all metrics instrumented from first alpha build (Phase 2). Every metric is a dashboarded event, not a manual tally. Baselines are collected during closed alpha (10–20 agencies / plugin teams) and reviewed as Phase 2 exit criteria.
|
||||||
|
|
||||||
Qualitative bar: experienced WordPress engineers say it behaves like someone who has shipped WP for years.
|
Qualitative bar: experienced WordPress engineers say it behaves like someone who has shipped WP for years.
|
||||||
|
|
||||||
@@ -345,20 +393,24 @@ Qualitative bar: experienced WordPress engineers say it behaves like someone who
|
|||||||
- Spike: wp-env control plane + agent tool bus
|
- Spike: wp-env control plane + agent tool bus
|
||||||
|
|
||||||
### Phase 1 — Foundation (weeks 1–8)
|
### Phase 1 — Foundation (weeks 1–8)
|
||||||
- Workspace shell (implementation vehicle TBD: desktop vs web; prefer proven editor foundations over greenfield chrome)
|
- Ship Electron shell on Code-OSS (reused editor core; no greenfield chrome)
|
||||||
- Project open + WP detection
|
- Project open + WP detection
|
||||||
- wp-env lifecycle + preview
|
- wp-env lifecycle + preview
|
||||||
- Agent chat + diffs + rules
|
- Agent chat + diffs + rules
|
||||||
- WP-CLI tool + permission engine
|
- WP-CLI tool + permission engine
|
||||||
- P0 playbooks
|
- P0 playbooks
|
||||||
|
|
||||||
|
**Exit criteria:** a new user on a clean machine (no Docker, no wp-env) reaches a live preview of a WordPress repo in ≤ 10 minutes, and a P0 playbook (dynamic block) completes with a verified preview + accepted diff.
|
||||||
|
|
||||||
### Phase 2 — Intelligence (weeks 9–16)
|
### Phase 2 — Intelligence (weeks 9–16)
|
||||||
- Knowledge graph v1
|
- Knowledge graph v1 (static + runtime passes)
|
||||||
- WPCS / tests in the loop
|
- WPCS / tests in the loop
|
||||||
- State Diffs + read-only DB introspection
|
- State Diffs + read-only DB introspection
|
||||||
- Careful staging pull
|
- Careful staging pull
|
||||||
- Closed alpha (10–20 agencies / plugin teams)
|
- Closed alpha (10–20 agencies / plugin teams)
|
||||||
|
|
||||||
|
**Exit criteria:** all §11 baselines collected and reviewed; knowledge graph staleness surfaced in UI; State Diff create→rollback loop demoed on a destructive option change.
|
||||||
|
|
||||||
### Phase 3 — Professional (weeks 17–28)
|
### Phase 3 — Professional (weeks 17–28)
|
||||||
- Block / FSE workshop
|
- Block / FSE workshop
|
||||||
- Role-based preview
|
- Role-based preview
|
||||||
@@ -375,33 +427,46 @@ Qualitative bar: experienced WordPress engineers say it behaves like someone who
|
|||||||
|
|
||||||
| Risk | Impact | Mitigation |
|
| Risk | Impact | Mitigation |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| Building a full workspace is large | High | Reuse a mature editor foundation; invest in WP runtime + tools |
|
| Building a full workspace is large | High | Electron shell on Code-OSS (reused editor core, not greenfield); WP runtime + tools get the focus |
|
||||||
| Local Docker/wp-env pain (esp. Windows) | High | Diagnostics first; early Local/DDEV import |
|
| Local Docker/wp-env pain (esp. Windows) | High | Diagnostics-first first-run; installer guides; early Local/DDEV import (P1) |
|
||||||
| Agent harms a site | High | Permission tiers; local-default; production lock; State Diffs |
|
| Agent harms a site | High | Permission tiers; local-default; production lock; State Diffs with rollback |
|
||||||
| "Prompts in my current editor are enough" | Medium | Demo the site loop and playbooks general setups fail |
|
| "Prompts in my current editor are enough" | Medium | Demo the site loop and playbooks general setups fail |
|
||||||
| Legacy PHP / chaotic themes | Medium | Stubs, WPCS, honest limits; playbooks for clean paths first |
|
| Legacy PHP / chaotic themes | Medium | Stubs, WPCS, honest limits; playbooks for clean paths first |
|
||||||
| Repo still named originmain | Low | Rename after name lock |
|
| Repo still named originmain | Resolved | Repo renamed to SinachPat/wursor |
|
||||||
| Trademark / "WordPress" in marketing | Medium | Follow WordPress Foundation trademark rules |
|
| Trademark / "WordPress" in marketing | Medium | Follow WordPress Foundation trademark rules |
|
||||||
|
| LLM provider outage / model churn | Medium | BYO-key model; workspace shell stays usable offline; P1 hosted routing tier |
|
||||||
|
| Docker Desktop licensing for commercial use | Low | Document; wp-env alternatives; Rancher Desktop path |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 14. Open Questions (Phase 0)
|
## 14. Decisions & Open Questions (Phase 0)
|
||||||
|
|
||||||
1. **Shell:** desktop vs browser-first; which editor foundation to adopt?
|
### Resolved (locked)
|
||||||
2. **Name:** keep **Wordbench** or replace before public use?
|
|
||||||
3. **Repo rename** away from `originmain`?
|
1. **Shell:** Electron desktop app on Code-OSS (VS Code's open-source editor core). Native filesystem, Docker socket, embedded preview, offline-capable.
|
||||||
4. **Pricing:** seat vs workspace vs hosted-runtime usage?
|
2. **Name:** Wursor (locked in v1.2; no further rename planned).
|
||||||
5. **Roots/Bedrock/Trellis** support depth for v1?
|
3. **Repo:** renamed to `SinachPat/wursor`.
|
||||||
6. **Models:** BYO keys vs hosted; default routing?
|
4. **Pricing:** seat-based ($X/dev/month, free tier with per-seat limits); agency teams primary. Final $X set during Phase 3 paid beta.
|
||||||
|
5. **Roots/Bedrock/Trellis support:** P1 (not v1). wp-env covers the launch segment; runtime manager is abstraction-bound for later import.
|
||||||
|
6. **Models:** Claude via BYO API key (v1); optional Wursor-hosted routing tier (P1 upsell). No local model support in v1.
|
||||||
|
7. **Runtime backends:** wp-env only in v1; Local / DDEV import is P1.
|
||||||
|
|
||||||
|
### Remaining (genuinely open)
|
||||||
|
|
||||||
|
All Phase 0 questions are resolved above. New questions will be documented per phase and resolved before the next phase begins.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 15. Appendices
|
## 15. Appendices
|
||||||
|
|
||||||
### A. Glossary
|
### A. Glossary
|
||||||
- **State Diff** — Reviewable WP-CLI / SQL / content mutation plan
|
- **Workspace** — Project + site runtime + environment config bound together
|
||||||
|
- **State Diff** — Reviewable WP-CLI / SQL / content mutation plan with a create→review→apply→rollback lifecycle
|
||||||
- **Playbook** — Reusable agent workflow with tools and checks
|
- **Playbook** — Reusable agent workflow with tools and checks
|
||||||
- **WP Knowledge Graph** — Map of themes, plugins, blocks, hooks, REST
|
- **WP Knowledge Graph** — Map of themes, plugins, blocks, hooks, REST (static scan + runtime enrichment)
|
||||||
|
- **Runtime** — The site execution environment (wp-env in v1)
|
||||||
|
- **Environment** — A target (local / staging / production) with endpoints and policy
|
||||||
|
- **Verify** — The proof step (screenshot / HTTP check / editor confirmation) required before a task is "done"
|
||||||
- **FSE** — Full Site Editing (block themes)
|
- **FSE** — Full Site Editing (block themes)
|
||||||
- **wp-env** — `@wordpress/env` local environment
|
- **wp-env** — `@wordpress/env` local environment
|
||||||
|
|
||||||
@@ -415,10 +480,20 @@ Qualitative bar: experienced WordPress engineers say it behaves like someone who
|
|||||||
- Unattended production hotfixes
|
- Unattended production hotfixes
|
||||||
- Competing with Elementor-class page builders as the core offer
|
- Competing with Elementor-class page builders as the core offer
|
||||||
- Equal-class support for every legacy builder shortcode ecosystem on day one
|
- Equal-class support for every legacy builder shortcode ecosystem on day one
|
||||||
|
- A public extension/plugin API — connectors are internal; third-party integration ships after platform phase
|
||||||
|
- Local / DDEV / Bedrock imports — P1 (§7.2.6)
|
||||||
|
- Managed/hosted model tier — P1 upsell
|
||||||
|
- **Accessibility certification (WCAG) or i18n / localization** — v1 is English-only with no formal accessibility conformance target. Basic keyboard navigation and screen reader support for the workspace shell are built in via Code-OSS; custom Wursor panels target standard web accessibility practices but will not be audited until Phase 3.
|
||||||
|
|
||||||
|
### C.1 Wursor's own test strategy
|
||||||
|
- **Unit + integration tests** for the agent tool bus (each tool schema), the permission engine, and the State Diff lifecycle
|
||||||
|
- **Fixture-based WP repos** in CI (wp-env in GitHub Actions) to test detection, indexing, and playbooks without a live install
|
||||||
|
- **E2E smoke** on the Electron shell: open → detect → boot → preview → verify
|
||||||
|
- **Release gates:** CI runs unit + integration on every PR; e2e before each release
|
||||||
|
|
||||||
### D. One-liner
|
### D. One-liner
|
||||||
**Wordbench is the agentic workshop for WordPress — code, WP-CLI, data, and a live site in one loop.**
|
**Wursor is the agentic workshop for WordPress — code, WP-CLI, data, and a live site in one loop.**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*End of PRD v1.1 — Wordbench*
|
*End of PRD v1.2 — Wursor*
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Wordbench
|
# Wursor
|
||||||
|
|
||||||
**Working title.** Agentic WordPress development environment — code, live site, WP-CLI, and shipping in one loop.
|
**Working title.** Agentic WordPress development environment — code, live site, WP-CLI, and shipping in one loop.
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
## Start here
|
## Start here
|
||||||
|
|
||||||
- Full product spec: [PRD.md](./PRD.md)
|
- Full product spec: [PRD.md](./PRD.md)
|
||||||
|
- Build guide (TDD, sprints, CI): [IMPLEMENTATION.md](./IMPLEMENTATION.md)
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user