Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .claude/commands/implement-feature.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ MANDATORY READS:

If a design document exists, read it too:
```
docs/plans/<feature-name>.md
docs/features/<feature-name>/plan.md
```

---
Expand Down Expand Up @@ -188,9 +188,8 @@ When ALL tasks have QA PASS:

## Phase 9: Cleanup

- Update `docs/progress/<feature>-progress.md` → status: COMPLETE
- Update `docs/plans/<design-doc>.md` → status: IMPLEMENTED
- Move design doc to `doc-history/` if requested
- Update `docs/tracker.json → status: IMPLEMENTED
- Update `docs/features/<slug>/plan.md` → status: IMPLEMENTED
- Clean up worktrees: `git worktree remove <path>`
- Report completion summary to user

Expand Down
7 changes: 4 additions & 3 deletions .claude/commands/plan-feature.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ Identify which tasks can run **in parallel** (no shared files).

## Phase 5: Write the Plan

Write the complete plan to: `docs/plans/<feature-slug>-plan.md`
Write the complete plan to: `docs/features/<feature-slug>/plan.md`

The feature slug should be derived from the description: lowercase, hyphens, no special chars.
Example: "Add user authentication" becomes `docs/plans/add-user-authentication-plan.md`
Example: "Add user authentication" becomes `docs/features/add-user-authentication/plan.md`

### Plan File Format

Expand Down Expand Up @@ -145,7 +145,8 @@ After writing the plan file, output the **absolute file path** as the very last

Example final line:
```
PLAN_FILE:docs/plans/add-user-authentication-plan.md
PLAN_FILE:docs/features/add-user-authentication/plan.md
nAlso add a tracker entry to `docs/tracker.json` with the slug as key and status `DRAFT`.
```

---
Expand Down
2 changes: 1 addition & 1 deletion .claude/commands/resume-feature.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Based on your analysis:
- Check if a plan file was partially written
- If yes, review and complete it
- If no, start the planning process fresh using the `/plan-feature` approach
- Write the plan to `docs/plans/<feature-slug>-plan.md`
- Write the plan to `docs/features/<feature-slug>/plan.md`

### If resuming an execution phase:
- Identify which tasks from the plan are complete vs incomplete
Expand Down
54 changes: 51 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ If tests don't exist for the area you're modifying, **that doesn't exempt you fr
> that future agents read. If agent docs are stale, agents produce wrong code, which wastes time and money.
> **Failing to update docs is the same as shipping broken code. Treat it that way.**

`npm run check:docs` enforces that source changes include doc updates. Accepted doc paths: `ai-docs/`, `docs/plans/`, `.claude/agents/`, `docs/tracker.json`, and `CLAUDE.md`. Use this mapping to know which docs to update:
`npm run check:docs` enforces that source changes include doc updates. Accepted doc paths: `ai-docs/`, `docs/features/`, `.claude/agents/`, `docs/tracker.json`, and `CLAUDE.md`. Use this mapping to know which docs to update:

| Change Type | Docs to Update |
|-------------|----------------|
Expand All @@ -123,8 +123,8 @@ If tests don't exist for the area you're modifying, **that doesn't exempt you fr
| UI layout changes | `user-interface-flow.md` (UX flow sections), `FEATURES-INDEX.md` (layouts) |
| New feature module | `FEATURES-INDEX.md` (feature table), `ARCHITECTURE.md` (system diagram if applicable) |
| New pattern or convention | `PATTERNS.md` (pattern example with code), **ALL relevant agent files** |
| Feature plan or design doc | `docs/plans/<feature>-plan.md` (implementation plan) |
| Plan lifecycle changes | `docs/tracker.json` |
| Feature plan or design doc | `docs/features/<slug>/plan.md` (implementation plan) |
| Plan lifecycle changes | `docs/tracker.json` (update status + add entry) |
| Any change to file structure, imports, or conventions | **ALL `.claude/agents/*.md` files that reference the affected area** |

**Checklist before committing — ALL items are mandatory:**
Expand Down Expand Up @@ -370,3 +370,51 @@ Raw hex/rgb/hsl values are **ONLY** allowed inside theme variable definitions:

**Plan lifecycle tracking:** `docs/tracker.json` (single source of truth for all plan/progress status)

## Plan Tracking Protocol — MANDATORY

**Every plan, feature, or design doc MUST be tracked.** No exceptions — ad-hoc plans, on-the-fly features, and formal design docs all follow the same convention.

### The Naming Convention

One **slug** (lowercase, hyphen-separated) used everywhere:

| Artifact | Location |
|----------|----------|
| Tracker entry key | `docs/tracker.json` → `plans.<slug>` |
| Plan/design doc | `docs/features/<slug>/plan.md` |
| Feature branch | `feature/<slug>` |
| Runtime progress | `.claude/progress/<slug>/` (gitignored, workflow plugin) |

### When Creating a New Plan or Feature

1. **Choose a slug** — short, descriptive, hyphenated: `custom-theme-editor`, `tracking-consolidation`
2. **Create the folder**: `docs/features/<slug>/`
3. **Write the plan**: `docs/features/<slug>/plan.md`
4. **Add to tracker**: Add an entry to `docs/tracker.json` with the slug as key
5. **Create the branch**: `feature/<slug>`

### Tracker Entry Format (v2)

```json
{
"<slug>": {
"title": "Human-Readable Title",
"status": "DRAFT | APPROVED | IN_PROGRESS | IMPLEMENTED | ARCHIVED | TRACKING",
"planFile": "docs/features/<slug>/plan.md",
"created": "YYYY-MM-DD",
"statusChangedAt": "YYYY-MM-DD",
"branch": "feature/<slug>",
"pr": null,
"tags": ["category"]
}
}
```

### Rules

- **No plan without a tracker entry.** If you create `docs/features/X/plan.md`, add `X` to `docs/tracker.json`.
- **No feature branch without a tracker entry.** If you create `feature/X`, add `X` to tracker.
- **Slug = folder = key = branch suffix.** They MUST match. `docs/features/foo/` + tracker key `foo` + branch `feature/foo`.
- **`npm run validate:tracker`** catches orphan folders (in `docs/features/` but not in tracker) and missing plan files.
- **On-the-fly plans** still need a tracker entry with status `DRAFT` or `IN_PROGRESS` — you can skip the plan.md file by setting `planFile: null`, but the entry MUST exist.

2 changes: 1 addition & 1 deletion ai-docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -857,4 +857,4 @@ For exploratory testing, the AI QA agent uses MCP Electron tools to interact wit
- Reads console logs for error detection
- Follows natural language test scenarios in `tests/qa-scenarios/`

See `docs/plans/2026-02-14-test-suite-design.md` for the full testing strategy.
See the test suite design document for the full testing strategy.
2 changes: 1 addition & 1 deletion ai-docs/CODEBASE-GUARDIAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
|------|----------|------|
| `tracker.json` | `docs/tracker.json` | Single source of truth for plan status. MUST be updated when plans change status. |
| `validate-tracker.mjs` | `scripts/validate-tracker.mjs` | Validation script — do not move. |
| Active plans | `docs/plans/` | Plans with status DRAFT, APPROVED, IN_PROGRESS, TRACKING |
| Active plans | `docs/features/<slug>/plan.md` | Plans with status DRAFT, APPROVED, IN_PROGRESS, TRACKING |

**Cleanup rules:**
- Plans for features with status `IMPLEMENTED` that are older than 14 days should be deleted and their tracker entry removed
Expand Down
2 changes: 1 addition & 1 deletion ai-docs/FEATURES-INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ npm run format # Prettier format

### File Organization

- **Plans**: `docs/plans/` — design docs for active and recently completed features
- **Plans**: `docs/features/<slug>/plan.md` — design docs for active and recently completed features
- **Tracker**: `docs/tracker.json` — single source of truth for plan status (v2 schema)

---
Expand Down
8 changes: 4 additions & 4 deletions ai-docs/TASK-PLANNING-PIPELINE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Agent writes plan file → exits
event-wiring.ts detects plan file
│ ├── Scan log for PLAN_FILE:<path> marker
│ └── Fallback: scan docs/plans/*-plan.md (most recent)
│ └── Fallback: scan docs/features/*/plan.md (most recent)
taskRepository: planning → plan_ready (local + Hub mirror)
Expand Down Expand Up @@ -164,7 +164,7 @@ Contract source: `src/shared/ipc/agents/contract.ts`
When a planning-phase agent completes (exit code 0), `event-wiring.ts` runs `detectPlanFile()`:

1. **Strategy 1 — Log marker:** Scans the agent's log file (last line first) for `PLAN_FILE:<relative-path>`. The `/plan-feature` command is instructed to output this marker.
2. **Strategy 2 — Filesystem fallback:** Scans `docs/plans/` for files matching `*-plan.md`, sorted reverse-alphabetically (most recent first).
2. **Strategy 2 — Filesystem fallback:** Scans `docs/features/` for subdirectories containing `plan.md`, sorted reverse-alphabetically (most recent first).

If found:
- Reads the plan file content
Expand Down Expand Up @@ -230,9 +230,9 @@ For Claude instances and developers working **on** the application:
- `CODEBASE-GUARDIAN.md` — Structural rules
- `user-interface-flow.md` — UX flow and gap analysis

### Runtime Docs (`.claude/commands/`, `docs/plans/`)
### Runtime Docs (`.claude/commands/`, `docs/features/`)
Used **by** the application at runtime (Claude CLI reads these):
- `.claude/commands/plan-feature.md` — Planning agent instructions
- `.claude/commands/resume-feature.md` — Resume agent instructions
- `.claude/commands/implement-feature.md` — Execution agent instructions
- `docs/plans/*-plan.md` — Generated plan files (output of planning agents)
- `docs/features/<slug>/plan.md` — Generated plan files (output of planning agents)
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
**Team**: <team-name>
**Base Branch**: master
**Feature Branch**: feature/<feature-name>
**Design Doc**: docs/plans/<design-doc>.md
**Design Doc**: docs/features/<slug>/plan.md
**Started**: <YYYY-MM-DD HH:MM>
**Last Updated**: <YYYY-MM-DD HH:MM>
**Updated By**: <agent name or "team-lead">
Expand Down
2 changes: 1 addition & 1 deletion ai-docs/prompts/implementing-features/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Progress is tracked via the team's TaskList and the `.claude/progress/` runtime
**Status**: IN_PROGRESS | BLOCKED | QA_REVIEW | INTEGRATING | COMPLETE
**Team**: <team-name>
**Branch**: feature/<feature-name>
**Design Doc**: docs/plans/<design-doc>.md
**Design Doc**: docs/features/<slug>/plan.md
**Started**: <ISO timestamp>
**Last Updated**: <ISO timestamp>

Expand Down
4 changes: 2 additions & 2 deletions docs/tracker.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"future-roadmap": {
"title": "Future Roadmap",
"status": "TRACKING",
"planFile": "docs/plans/2026-02-16-future-roadmap.md",
"planFile": "docs/features/future-roadmap/plan.md",
"created": "2026-02-16",
"statusChangedAt": "2026-02-16",
"branch": null,
Expand All @@ -15,7 +15,7 @@
"separation-of-concerns": {
"title": "Codebase Separation of Concerns",
"status": "IMPLEMENTED",
"planFile": "docs/plans/2026-02-16-codebase-separation-of-concerns-design.md",
"planFile": "docs/features/separation-of-concerns/plan.md",
"created": "2026-02-16",
"statusChangedAt": "2026-02-19",
"branch": null,
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-docs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ function isSrcFile(file) {
function isDocFile(file) {
return (
file.startsWith('ai-docs/') ||
file.startsWith('docs/plans/') ||
file.startsWith('docs/features/') ||
file.startsWith('.claude/agents/') ||
file === 'docs/tracker.json' ||
file === 'CLAUDE.md'
Expand Down
19 changes: 10 additions & 9 deletions scripts/validate-tracker.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { join, resolve } from 'node:path';
* 5 checks:
* 1. Schema validation (required fields, valid status enum)
* 2. File existence (planFile paths exist on disk)
* 3. Orphan detection (every .md in docs/plans/ is tracked)
* 3. Orphan detection (every folder in docs/features/ is tracked)
* 4. Staleness warning (APPROVED entries older than 7 days)
* 5. Archive candidates (IMPLEMENTED entries older than 14 days)
*
Expand Down Expand Up @@ -117,14 +117,15 @@ const entries = Object.entries(plans);
}
}

// Check docs/plans/
const plansDir = join(ROOT, 'docs', 'plans');
if (existsSync(plansDir)) {
const planFiles = readdirSync(plansDir).filter((f) => f.endsWith('.md'));
for (const file of planFiles) {
const relativePath = `docs/plans/${file}`;
if (!trackedFiles.has(relativePath)) {
console.warn(` WARN: Orphan plan file not tracked: ${relativePath}`);
// Check docs/features/ — each subfolder should have a matching tracker key
const featuresDir = join(ROOT, 'docs', 'features');
if (existsSync(featuresDir)) {
const featureSlugs = readdirSync(featuresDir, { withFileTypes: true })
.filter((d) => d.isDirectory())
.map((d) => d.name);
for (const slug of featureSlugs) {
if (!plans[slug]) {
console.warn(` WARN: Orphan feature folder not tracked: docs/features/${slug}/`);
orphanCount++;
}
}
Expand Down
23 changes: 14 additions & 9 deletions src/main/bootstrap/event-wiring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface EventWiringDeps {
*
* Checks two locations in order:
* 1. The agent's log file for a `PLAN_FILE:<path>` output line
* 2. The `docs/plans/` directory for recently created `*-plan.md` files
* 2. The `docs/features/` directory for subdirectories containing `plan.md`
*
* Returns `{ filePath, content }` or `null` if no plan file found.
*/
Expand Down Expand Up @@ -67,18 +67,23 @@ function detectPlanFile(
// Log may be gone if cleanup ran first — continue to fallback
}

// Strategy 2: Scan docs/plans/ for *-plan.md files (most recent first)
const plansDir = join(projectPath, 'docs', 'plans');
// Strategy 2: Scan docs/features/ for subdirectories containing plan.md (most recent first)
const featuresDir = join(projectPath, 'docs', 'features');
try {
if (existsSync(plansDir)) {
const planFiles = readdirSync(plansDir)
.filter((f) => f.endsWith('-plan.md'))
if (existsSync(featuresDir)) {
const featureDirs = readdirSync(featuresDir, { withFileTypes: true })
.filter((d) => d.isDirectory())
.map((d) => d.name)
.sort()
.reverse();

if (planFiles.length > 0) {
const filePath = `docs/plans/${planFiles[0]}`;
const fullPath = join(plansDir, planFiles[0]);
const dirWithPlan = featureDirs.find((d) =>
existsSync(join(featuresDir, d, 'plan.md')),
);

if (dirWithPlan) {
const filePath = `docs/features/${dirWithPlan}/plan.md`;
const fullPath = join(featuresDir, dirWithPlan, 'plan.md');
return {
filePath,
content: readFileSync(fullPath, 'utf-8'),
Expand Down
Loading