refactor: rewrite CLAUDE.md (107 lines, critical rules first) + add pre-commit hook
This commit is contained in:
18
.husky/pre-commit
Executable file
18
.husky/pre-commit
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
# Pre-commit: same checks as CI. Fix here, not in CI.
|
||||
set -e
|
||||
echo "🔍 Pre-commit checks..."
|
||||
|
||||
# Lint + types (only if TS files staged)
|
||||
STAGED_TS=$(git diff --cached --name-only | grep -E '\.(ts|tsx)$' || true)
|
||||
if [ -n "$STAGED_TS" ]; then
|
||||
echo " → lint + tsc..."
|
||||
pnpm lint --quiet
|
||||
npx tsc --noEmit
|
||||
fi
|
||||
|
||||
# Unit tests
|
||||
echo " → tests..."
|
||||
pnpm test --run --silent
|
||||
|
||||
echo "✅ Pre-commit passed"
|
||||
414
CLAUDE.md
414
CLAUDE.md
@@ -1,353 +1,107 @@
|
||||
# CLAUDE.md — Laputa App
|
||||
|
||||
## Project
|
||||
Laputa App is a personal knowledge and life management desktop app, built with Tauri v2 + React + TypeScript + CodeMirror 6. It reads a vault of markdown files with YAML frontmatter and presents them in a four-panel UI inspired by Bear Notes.
|
||||
## ⛔ BEFORE EVERY COMMIT — Non-negotiable checklist
|
||||
|
||||
**Full project spec** (ontology, UI design, milestones): `docs/PROJECT-SPEC.md`
|
||||
**UI wireframes**: `ui-design.pen`
|
||||
|
||||
## Tech Stack
|
||||
- **Desktop shell**: Tauri v2 (Rust backend)
|
||||
- **Frontend**: React 18+ with TypeScript
|
||||
- **Editor**: CodeMirror 6 (live preview, reveal-on-focus)
|
||||
- **Build**: Vite
|
||||
- **Tests**: Vitest (unit), Playwright (E2E), `cargo test` (Rust)
|
||||
- **Package manager**: pnpm
|
||||
|
||||
## Architecture
|
||||
- `src-tauri/` — Rust backend (file I/O, frontmatter parsing, git ops, filesystem watching)
|
||||
- `src/` — React frontend
|
||||
- `src/mock-tauri.ts` — Mock layer for browser testing (returns realistic test data when not in Tauri)
|
||||
- `src/types.ts` — Shared TypeScript types (VaultEntry, etc.)
|
||||
- `e2e/` — Playwright E2E tests and screenshot verification
|
||||
- Vault path is configurable (not hardcoded) — the app works with "a vault at some path"
|
||||
- All data lives in markdown files with YAML frontmatter, git-versioned
|
||||
- The app reads/writes these files directly — no database
|
||||
- **Luca's vault**: `~/Laputa/` (~9200 markdown files)
|
||||
|
||||
## Coding Standards
|
||||
- Rust: use `serde` for serialization, `gray_matter` or similar for frontmatter parsing
|
||||
- TypeScript: strict mode, functional components, hooks
|
||||
- Keep components responsive-ready (don't hardcode four-panel layout assumptions)
|
||||
- Use Context7 MCP to look up current API docs for Tauri v2, CodeMirror 6, etc.
|
||||
|
||||
## Product Philosophy
|
||||
|
||||
These principles apply to every task, especially when requirements are intentionally vague.
|
||||
|
||||
### Think like a PM, not just a developer
|
||||
|
||||
Features in this project are often described at a high level on purpose. Luca trusts you to make sensible product decisions. When something is unclear:
|
||||
|
||||
- **Don't ask, decide.** Pick the interpretation that makes the most sense for a first working version. Document your decision in the commit message or a code comment.
|
||||
- **Bias toward shipping.** A working, testable feature is the goal. If you're choosing between a perfect solution that takes 4 hours and a good-enough one that takes 1 hour, ship the good-enough one first.
|
||||
- **Never block waiting for instructions.** Luca may not read messages for hours. If you're stuck on a product decision, make the call yourself. The worst case is a short code review; the alternative is hours of delay.
|
||||
- **Document your reasoning.** When you make a non-obvious product decision (e.g., "I chose to show archived notes grayed out rather than hiding them entirely"), note it in the relevant `docs/` file so Luca can review and adjust.
|
||||
|
||||
### Always produce a design file
|
||||
|
||||
Every feature must have a `design/<slug>.pen` file committed on the feature branch. This is mandatory — Luca reviews it as part of the In Review step.
|
||||
|
||||
**The design file must be ADDITIVE** — it must contain ONLY the new frames for this feature. Do NOT copy ui-design.pen.
|
||||
|
||||
Create a fresh file with the correct structure:
|
||||
```bash
|
||||
mkdir -p design
|
||||
|
||||
# First, study the frame schema from ui-design.pen:
|
||||
node -e "
|
||||
const f = JSON.parse(require('fs').readFileSync('ui-design.pen', 'utf8'));
|
||||
console.log('Frame schema:', JSON.stringify(f.children[0], null, 2));
|
||||
console.log('Variables available:', Object.keys(f.variables || {}));
|
||||
"
|
||||
|
||||
# Then create the feature file with ONLY new frames (empty children to start):
|
||||
echo '{"children": [], "variables": {}}' > design/<slug>.pen
|
||||
# Add your feature frames to children[]
|
||||
```
|
||||
|
||||
⚠️ **DO NOT** `cp ui-design.pen design/<slug>.pen` — this copies all existing frames and the merge will find 0 new frames (all duplicates), breaking the design workflow.
|
||||
|
||||
Add new frames to `children[]` for the feature's screens/states. Use existing `variables` (design tokens) from ui-design.pen — don't invent new values.
|
||||
|
||||
**Complex feature** (new panel, new modal, new UI surface) → design first, then implement.
|
||||
**Simple feature** (new property, filter pill, minor modification) → implement first, then update design to reflect what was built.
|
||||
|
||||
Commit with: `git add design/<slug>.pen && git commit -m "design: <feature> wireframes"`
|
||||
|
||||
### Always update test data
|
||||
|
||||
If a feature requires new data to be testable (e.g., a new `archived: true` property in frontmatter, a new type of note, a relationship type), update `src/mock-tauri.ts` with realistic examples before writing the feature. This ensures visual verification actually tests the new code path.
|
||||
|
||||
### Always keep docs current
|
||||
|
||||
After every meaningful architectural decision or abstraction, update the relevant file in `docs/`. The docs in this repo are how Luca understands what was built and why. Stale docs are worse than no docs.
|
||||
|
||||
## How to Work
|
||||
|
||||
### Approach
|
||||
- **Small steps**: Build one thing at a time. Get it working, test it, commit it. Then move to the next.
|
||||
- **Test as you go**: Write tests alongside code, not after. If you build a frontmatter parser, test it immediately with real-world examples before moving on.
|
||||
- **Verify constantly**: After each meaningful change, run the relevant tests (`cargo test`, `pnpm test`). Don't stack up a bunch of code and hope it all works.
|
||||
- **Never develop on `main`**: all work happens on a feature branch (`task/<slug>`). This repo has CI that runs on PRs — pushing directly to main skips the pre-merge checks. Brian merges via PR (`gh pr create` + `gh pr merge`) after Luca approves. If you somehow end up on main, stash your work and switch to the correct branch first.
|
||||
- **Commit often — small and atomic**: Each logical unit of work gets its own commit. **Never work for more than 20–30 minutes without committing something.** If you've been coding for 30 min and have no commit, stop and commit what you have — even if it's incomplete (use `wip:` prefix). This protects against session crashes and timeouts. NEVER batch multiple features or fixes into one big commit. Examples of good atomic commits:
|
||||
- `feat: update color palette and CSS variables`
|
||||
- `feat: restructure sidebar with collapsible sections`
|
||||
- `fix: editor scroll overflow`
|
||||
One concern per commit. If you're doing a multi-phase task, commit after EACH phase, not at the end. This makes reviews, reverts, and bisecting possible.
|
||||
- **Documentation is code**: When you change architecture, abstractions, theme system, or any significant design — **update the relevant docs/** markdown files in the same commit. Documentation should always reflect current reality, not past state. Push docs changes together with code changes.
|
||||
|
||||
### Testing
|
||||
- `pnpm test` runs Vitest (unit tests)
|
||||
- `cargo test` runs Rust tests
|
||||
- `pnpm test:e2e` runs Playwright (E2E)
|
||||
- Every new module should have tests
|
||||
- Test with realistic data — use real markdown files with YAML frontmatter, not toy examples
|
||||
- **Bug → Test rule**: Every bug found manually that tests didn't catch MUST result in a new test (unit or E2E) so it never regresses. Ask yourself: "Why didn't tests catch this?" and close the gap.
|
||||
- **New feature rule**: every task that adds or changes behavior MUST include tests that specifically cover the new behavior. "Existing tests pass" is not enough — new tests must exist for the new code path. This is a hard requirement for moving to In Review.
|
||||
- **No coverage theater**: tests must verify real business behavior (e.g. "archiving a note calls the right Tauri command and updates state"), not framework behavior (e.g. "component renders without crashing"). The goal is confidence that the feature works, not a number.
|
||||
- Edge cases matter: empty frontmatter, missing fields, malformed YAML, files with no H1 title
|
||||
|
||||
### Test Coverage (MANDATORY — run before every commit)
|
||||
|
||||
Coverage must never regress. Run these two commands before committing:
|
||||
Run all of these. If any fails, fix before committing. No exceptions.
|
||||
|
||||
```bash
|
||||
# Frontend — enforces 70% threshold on lines/functions/branches; exits non-zero if coverage drops
|
||||
pnpm test:coverage
|
||||
|
||||
# Rust — enforces 85% line coverage; exits non-zero if coverage drops
|
||||
pnpm lint && npx tsc --noEmit # lint + types
|
||||
pnpm test # unit tests
|
||||
pnpm test:coverage # frontend ≥70% coverage
|
||||
cargo test # Rust tests
|
||||
cargo llvm-cov --manifest-path src-tauri/Cargo.toml --fail-under-lines 85
|
||||
pre_commit_code_health_safeguard # CodeScene ≥8.5 — if it fails, fix structurally (see below)
|
||||
```
|
||||
|
||||
If either command exits non-zero, **do not commit** until you've added tests to restore coverage.
|
||||
**CI is a safety net, not a discovery tool.** If CI catches something you didn't catch locally, that's a process failure. All these tools are available locally — use them while you code, not just at the end.
|
||||
|
||||
Current baselines (Feb 2026): Frontend ≥70% | Rust lines ≥85% (89.8% actual), functions ≥75% (81.5% actual).
|
||||
## ⛔ BEFORE FIRING laputa-task-done — QA on real vault
|
||||
|
||||
### macOS / Tauri Platform Gotchas (CHECK BEFORE SUBMITTING)
|
||||
1. Acquire lockfile: `echo $$ > /tmp/laputa-qa.lock && trap "rm -f /tmp/laputa-qa.lock" EXIT`
|
||||
2. Kill other instances: `pkill -x laputa 2>/dev/null || true; sleep 1`
|
||||
3. Start app: `pnpm tauri dev` from worktree
|
||||
4. Switch vault to `~/Laputa` (not demo)
|
||||
5. Test the feature/fix with real mouse clicks (`cliclick`) on real notes
|
||||
6. If task touches file save: verify `git -C ~/Laputa diff` shows changes
|
||||
7. If QA fails → fix and re-run. Do NOT fire the signal until it passes.
|
||||
|
||||
These bugs slip through unit tests because JSDOM doesn't simulate real macOS behavior. Verify manually or note them explicitly.
|
||||
|
||||
**Keyboard shortcuts:**
|
||||
- `Option/Alt+N` on macOS produces special characters (e.g. `¡`, `™`), NOT `key:'1'`. Never use `e.key` to detect Alt+number combos.
|
||||
- Use `e.code` (`'Digit1'`) for layout-independent keys, or use `Cmd+N` shortcuts instead (more standard on macOS).
|
||||
- Prefer `CmdOrCtrl+N` for cross-platform shortcuts.
|
||||
|
||||
**Tauri menu accelerators:**
|
||||
- Adding shortcut text to the menu label (`format!("{label} Alt+1")`) is purely decorative — it does NOT register a keyboard shortcut.
|
||||
- Always use `MenuItemBuilder::new(label).id(id).accelerator("CmdOrCtrl+1").build(app)?` to register real accelerators.
|
||||
- After changing `menu.rs`, the Rust binary must recompile — test the running app, not just unit tests.
|
||||
|
||||
**Custom macOS menu:**
|
||||
- `app.set_menu(menu)` replaces the ENTIRE menu bar. If you only add a `View` submenu, you lose the standard app menus (File, Edit, Window, Help). Include all necessary submenus or use `window.set_menu()` instead.
|
||||
|
||||
**App focus for keyboard events:**
|
||||
- JS `window.addEventListener('keydown')` only fires when the WebView has focus. If the user is interacting with native UI elements (menus, title bar), events may not reach the JS layer.
|
||||
|
||||
### Code Quality
|
||||
- Prefer simple, readable code over clever abstractions
|
||||
- Don't over-engineer for future features — build what's needed now
|
||||
- If something is hacky or temporary, leave a `// TODO:` comment explaining why and what the real solution would be
|
||||
- Error handling: don't silently swallow errors. Log them, surface them, or return Result types (Rust)
|
||||
|
||||
### Visual Verification (MANDATORY)
|
||||
Before declaring any milestone or feature complete, you MUST visually verify it works.
|
||||
|
||||
**You must manually test every feature via Chrome (`claude --chrome`):**
|
||||
1. **Start the dev server**: `pnpm dev` (Vite only, no Tauri needed)
|
||||
2. **Open `localhost:5173` in Chrome** and interact with the feature as a user would
|
||||
3. **Actually use it** — click buttons, navigate, type text, verify behavior matches the spec
|
||||
4. **Don't just screenshot** — interact end-to-end. If something looks wrong, fix it before declaring done.
|
||||
5. **If mock data doesn't cover the feature**, update `src/mock-tauri.ts` with appropriate test data first
|
||||
|
||||
Also run Playwright for automated verification:
|
||||
- `npx playwright test e2e/screenshot.spec.ts` — captures screenshots
|
||||
- Write ad-hoc Playwright tests that click, navigate, and screenshot results
|
||||
|
||||
The app has a **Tauri mock layer** (`src/mock-tauri.ts`): when running in a browser (not Tauri), it returns realistic test data. This means Chrome and Playwright can test the full UI without the Rust backend.
|
||||
|
||||
**Key rule**: passing unit tests ≠ working app. If you can't see it working AND interact with it successfully, it's not done.
|
||||
|
||||
### Native App QA (MANDATORY — Stage 1 of 2, before firing done signal)
|
||||
|
||||
⚠️ **CRITICAL**: The browser/Chrome uses `mock-tauri.ts` which silently swallows Tauri commands. Bugs on real vaults NEVER surface in Chrome. You MUST test on the native Tauri app with Luca's real vault.
|
||||
|
||||
**QA is a two-stage process**: you do Stage 1, Brian does Stage 2 independently before merging.
|
||||
|
||||
#### Stage 1 — Your QA (required before firing laputa-task-done)
|
||||
|
||||
**Step 1: Acquire the QA lockfile** (ensures only one laputa instance runs at a time):
|
||||
```bash
|
||||
LOCK=/tmp/laputa-qa.lock
|
||||
WAITED=0
|
||||
while [ -f "$LOCK" ]; do
|
||||
sleep 10; WAITED=$((WAITED+10))
|
||||
if [ $WAITED -ge 300 ]; then echo "QA lock timeout after 5min"; exit 1; fi
|
||||
done
|
||||
echo "$$" > "$LOCK"
|
||||
trap "rm -f $LOCK" EXIT
|
||||
```
|
||||
|
||||
**Step 2: Kill other laputa instances and start fresh**:
|
||||
```bash
|
||||
pkill -x laputa 2>/dev/null || true
|
||||
sleep 1
|
||||
# Start native app from your worktree
|
||||
pnpm tauri dev --port <port>
|
||||
# Wait for it to open (~30s)
|
||||
```
|
||||
|
||||
**Step 3: Test on ~/Laputa (not demo vault)**:
|
||||
- Switch vault to `~/Laputa` from the vault picker if needed
|
||||
- Take screenshot, verify feature is visually present
|
||||
- **Click through the happy path** with `cliclick` — real mouse interaction
|
||||
- **If task touches save/edit**: `git -C ~/Laputa diff` must show changed files after Cmd+S
|
||||
- **If task fixes a bug**: reproduce original bug scenario on ~/Laputa, confirm it's gone
|
||||
- Take final screenshot
|
||||
|
||||
**Step 4: Release lock and fire signal** (only if QA passed):
|
||||
Fire done signal only after QA passes:
|
||||
```bash
|
||||
rm -f /tmp/laputa-qa.lock
|
||||
openclaw system event --text "laputa-task-done:<task_id>:<slug>" --mode now
|
||||
```
|
||||
|
||||
If QA fails: fix the bug, re-run QA. Do NOT fire the done signal until QA passes on ~/Laputa.
|
||||
## ⛔ CODE HEALTH — No shortcuts
|
||||
|
||||
If `pre_commit_code_health_safeguard` flags a file:
|
||||
- **Understand why** — use `code_health_review` via CodeScene MCP
|
||||
- Fix the structural problem (extract hooks, split components, reduce complexity)
|
||||
- **Never** add a JSDoc comment, `#[allow(...)]`, `// eslint-disable`, or `as any` just to pass the gate
|
||||
- It's fine to take longer. False quality is worse than no quality.
|
||||
|
||||
---
|
||||
|
||||
## Project
|
||||
|
||||
Tauri v2 + React + TypeScript desktop app. Reads a vault of markdown files with YAML frontmatter.
|
||||
|
||||
- **Spec**: `docs/PROJECT-SPEC.md`
|
||||
- **Architecture**: `docs/ARCHITECTURE.md`
|
||||
- **Abstractions**: `docs/ABSTRACTIONS.md`
|
||||
- **Wireframes**: `ui-design.pen`
|
||||
- **Luca's vault**: `~/Laputa/` (~9200 markdown files)
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- Desktop: Tauri v2 (Rust backend)
|
||||
- Frontend: React 18 + TypeScript + BlockNote editor
|
||||
- Tests: Vitest (unit), Playwright (E2E), `cargo test` (Rust)
|
||||
- Package manager: pnpm
|
||||
|
||||
## Architecture
|
||||
|
||||
- `src-tauri/src/` — Rust backend (file I/O, git, frontmatter parsing)
|
||||
- `src/` — React frontend
|
||||
- `src/mock-tauri.ts` — Mock layer for browser/test env (silently swallows Tauri calls — **not a substitute for native app testing**)
|
||||
- `src/types.ts` — Shared TypeScript types
|
||||
|
||||
## How to Work
|
||||
|
||||
- **Never develop on `main`** — always on `task/<slug>` branch
|
||||
- **Commit every 20–30 min** — atomic commits, one concern per commit (`feat:`, `fix:`, `refactor:`, `test:`, `docs:`)
|
||||
- **Update docs/** when changing architecture, abstractions, or significant design
|
||||
- **Test as you go** — write tests alongside code, not after
|
||||
|
||||
## Testing
|
||||
|
||||
- Unit tests must cover real business logic, not "component renders"
|
||||
- Every bug fixed manually → add a regression test
|
||||
- Every new feature → new tests for new behavior paths
|
||||
- `pnpm test:coverage` and `cargo llvm-cov` must pass before committing
|
||||
|
||||
## Design File (every UI task)
|
||||
|
||||
Every task with UI changes needs `design/<slug>.pen` — **additive only, NOT a copy of ui-design.pen**.
|
||||
|
||||
Use the `laputa-qa` skill scripts:
|
||||
```bash
|
||||
bash ~/.openclaw/skills/laputa-qa/scripts/focus-app.sh laputa
|
||||
bash ~/.openclaw/skills/laputa-qa/scripts/screenshot.sh /tmp/before.png
|
||||
bash ~/.openclaw/skills/laputa-qa/scripts/shortcut.sh "command" "s" # Cmd+S
|
||||
bash ~/.openclaw/skills/laputa-qa/scripts/click.sh 400 300 # × 2.56 for retina
|
||||
mkdir -p design
|
||||
# Study schema first:
|
||||
node -e "const f=JSON.parse(require('fs').readFileSync('ui-design.pen','utf8')); console.log(JSON.stringify(f.children[0],null,2))"
|
||||
# Start fresh:
|
||||
echo '{"children":[],"variables":{}}' > design/<slug>.pen
|
||||
```
|
||||
|
||||
### Playwright for Testing & Verification
|
||||
- `npx playwright test` — runs all E2E tests
|
||||
- `npx playwright test e2e/screenshot.spec.ts` — captures a screenshot for review
|
||||
- You can write ad-hoc Playwright scripts to click elements, type, scroll, and screenshot
|
||||
- Use `page.screenshot({ path: 'test-results/something.png' })` to capture state
|
||||
- Always screenshot before AND after interactions to verify changes
|
||||
## macOS / Tauri Gotchas
|
||||
|
||||
### When Stuck
|
||||
- Use Context7 MCP to look up current API docs (Tauri v2, CodeMirror 6, etc.)
|
||||
- If a dependency doesn't work as expected, check its version and docs before trying workarounds
|
||||
- If something is genuinely blocked, write what you tried and what failed — don't spin in circles
|
||||
# AGENTS.md
|
||||
- `Option+N` on macOS → special chars (`¡`, `™`), not `key:'N'`. Use `e.code` or `Cmd+N`.
|
||||
- Tauri menu accelerators: use `MenuItemBuilder::new(label).accelerator("CmdOrCtrl+1")` — decorative text in labels doesn't register shortcuts.
|
||||
- `app.set_menu()` replaces the ENTIRE menu bar — include all submenus.
|
||||
|
||||
## Agent TL;DR
|
||||
|
||||
- **Code Health is authoritative.** Treat it as the single source of truth for maintainability.
|
||||
- **Target Code Health 10.0.** This is the standard for AI-friendly code. 9+ is not “good enough.”
|
||||
- **Safeguard all AI-touched code** before suggesting a commit.
|
||||
- If Code Health regresses or violates goals, **refactor — don’t declare done.**
|
||||
- Use Code Health to guide **incremental, high-impact refactorings.**
|
||||
- When in doubt, **call the appropriate CodeScene MCP tool — don’t guess.**
|
||||
|
||||
---
|
||||
|
||||
# Core Use Cases
|
||||
|
||||
## 1️⃣ Safeguard All AI-Generated or Modified Code (Mandatory)
|
||||
|
||||
### The CI is a safety net, not a discovery tool
|
||||
|
||||
**Catch problems locally, before pushing.** You have all the tools: CodeScene MCP, eslint, tsc, coverage. Use them. Every CI failure that could have been caught locally wastes time on push/wait/fix/push cycles that are completely avoidable.
|
||||
|
||||
**Rule**: never push code that you haven't already verified locally passes all quality gates. The CI should never be the first place you learn about a lint error, a coverage drop, or a CodeScene regression.
|
||||
|
||||
### After every significant change (not just pre-commit):
|
||||
|
||||
1. **Lint** — run immediately after changing TS/TSX files:
|
||||
```bash
|
||||
pnpm lint # catches eslint errors before they reach CI
|
||||
npx tsc --noEmit # catches type errors
|
||||
```
|
||||
|
||||
2. **CodeScene health** — run after any non-trivial implementation:
|
||||
```bash
|
||||
pre_commit_code_health_safeguard # fails if health drops below threshold
|
||||
```
|
||||
If it flags a file: use `code_health_review` to understand *why*, then fix structurally (see rules below). Don't push until it passes.
|
||||
|
||||
3. **Coverage** — run before committing (both must exit 0):
|
||||
```bash
|
||||
pnpm test:coverage
|
||||
cargo llvm-cov --manifest-path src-tauri/Cargo.toml --fail-under-lines 85
|
||||
```
|
||||
|
||||
4. Run `code_health_review` for detailed analysis if the safeguard reports a regression.
|
||||
3. If Code Health regresses or fails quality gates — **take it seriously, no shortcuts**:
|
||||
- A CI gate failure means the code has a real structural problem. Fix it properly.
|
||||
- **Never add superficial fixes to pass a gate** (e.g. a JSDoc comment to gain 0.02 points, a trivial test to hit coverage, splitting a function just to reduce line count without improving clarity). This creates "false quality" — the metric looks green but the problem is still there.
|
||||
- Understand *why* the gate is failing:
|
||||
- CodeScene low score → the file has too many responsibilities. Extract hooks, split components, reduce cyclomatic complexity structurally.
|
||||
- Coverage below threshold → write tests that cover real business logic paths, not just "does this render" or framework boilerplate.
|
||||
- Clippy/lint error → fix the actual issue, don't add `#[allow(...)]` unless there's a documented reason.
|
||||
- If a large/complex function is reported: extract sub-functions or hooks with clear single responsibilities. Use `code_health_auto_refactor` if available, then refine.
|
||||
- It's fine to take longer. A proper fix is always better than a fast workaround.
|
||||
4. Do **not** mark changes as ready unless risks are explicitly accepted.
|
||||
|
||||
---
|
||||
|
||||
## 2️⃣ Guide Refactoring with Code Health (Preferred via ACE)
|
||||
|
||||
When refactoring or improving code:
|
||||
|
||||
1. Inspect with `code_health_review`.
|
||||
2. Identify complexity, size, coupling, or other code health issues.
|
||||
3. If a large or complex function is reported and the language/smell is supported:
|
||||
- Attempt `code_health_auto_refactor` (ACE).
|
||||
- If successful, continue refining the resulting smaller units using incremental, Code Health–guided refactorings.
|
||||
- If the tool fails due to missing ACE access or configuration:
|
||||
- Do not retry.
|
||||
- Continue with manual, incremental refactoring guided by Code Health.
|
||||
4. Refactor in **3–5 small, reviewable steps**.
|
||||
5. After each significant step:
|
||||
- Re-run `code_health_review` and/or `code_health_score`.
|
||||
- Confirm measurable improvement or no regression.
|
||||
|
||||
ACE is optional. Refactoring must always proceed, with or without ACE.
|
||||
|
||||
---
|
||||
|
||||
# Technical Debt & Prioritization
|
||||
|
||||
When asked what to improve:
|
||||
|
||||
- Use `list_technical_debt_hotspots`.
|
||||
- Use `list_technical_debt_goals`.
|
||||
- Use `code_health_score` to rank risk.
|
||||
- Optionally use `code_health_refactoring_business_case` to quantify ROI.
|
||||
|
||||
Always produce:
|
||||
- The ranked list of hotspots.
|
||||
- Small, incremental refactor plans.
|
||||
- Business justification when relevant.
|
||||
|
||||
---
|
||||
|
||||
# Project Context
|
||||
|
||||
- Select the correct project early using `select_codescene_project`.
|
||||
- Assume all subsequent tool calls operate within the active project.
|
||||
|
||||
---
|
||||
|
||||
# Explanation & Education
|
||||
|
||||
When users ask why Code Health matters:
|
||||
|
||||
- Use `explain_code_health` for fundamentals.
|
||||
- Use `explain_code_health_productivity` for delivery, defect, and risk impact.
|
||||
- Tie explanations to actual project data when possible.
|
||||
|
||||
---
|
||||
|
||||
# Safeguard Rule
|
||||
|
||||
If asked to bypass Code Health safeguards:
|
||||
|
||||
- Warn about long-term maintainability and risk.
|
||||
- Keep changes minimal and reversible.
|
||||
- Recommend follow-up refactoring.
|
||||
## QA Scripts
|
||||
|
||||
```bash
|
||||
bash ~/.openclaw/skills/laputa-qa/scripts/focus-app.sh laputa
|
||||
bash ~/.openclaw/skills/laputa-qa/scripts/screenshot.sh /tmp/out.png
|
||||
bash ~/.openclaw/skills/laputa-qa/scripts/shortcut.sh "command" "s"
|
||||
bash ~/.openclaw/skills/laputa-qa/scripts/click.sh 400 300 # logical coords
|
||||
```
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"test:e2e": "playwright test",
|
||||
"test:coverage": "vitest run --coverage"
|
||||
"test:coverage": "vitest run --coverage",
|
||||
"prepare": "husky"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.78.0",
|
||||
@@ -65,6 +66,7 @@
|
||||
"eslint-plugin-react-refresh": "^0.4.24",
|
||||
"globals": "^16.5.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
"husky": "^9.1.7",
|
||||
"jsdom": "^28.0.0",
|
||||
"typescript": "~5.9.3",
|
||||
"typescript-eslint": "^8.48.0",
|
||||
|
||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -153,6 +153,9 @@ importers:
|
||||
gray-matter:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
husky:
|
||||
specifier: ^9.1.7
|
||||
version: 9.1.7
|
||||
jsdom:
|
||||
specifier: ^28.0.0
|
||||
version: 28.0.0
|
||||
@@ -2468,6 +2471,11 @@ packages:
|
||||
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
husky@9.1.7:
|
||||
resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
ignore@5.3.2:
|
||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||
engines: {node: '>= 4'}
|
||||
@@ -5999,6 +6007,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
husky@9.1.7: {}
|
||||
|
||||
ignore@5.3.2: {}
|
||||
|
||||
ignore@7.0.5: {}
|
||||
|
||||
Reference in New Issue
Block a user