mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-16 08:06:24 +03:00
- Marketplace source moved from "./" to "./plugin", a thin generated subtree containing only the plugin manifest and the impeccable skill. Per-version plugin cache shrinks ~378× (~770 KB instead of ~291 MB), and the lockfile is no longer included in the source path so the cache extraction never runs bun install. (#107) - skills field in plugin.json now ends with a trailing slash to match the documented schema (code.claude.com/docs/en/plugins-reference, every directory example uses ./path/). Three reporters converged on this fix because Claude Code's plugin loader skips command registration on some setups when the slash is missing. (#86) - Anti-patterns maintenance agent moved out of .claude/agents/ into CLAUDE.md / AGENTS.md as concise inline guidance, since it is repo-internal dev workflow, not user-facing. The plugin was also the only place this agent was exposed to install users. - Skills version bumped to 3.0.2 so existing users pick up the new install path on next /plugin update. - Top-level harness directories (.claude/skills/, .cursor/skills/, ...) intentionally stay where they are; npx skills add reads them directly from the GitHub repo and that path is unaffected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
57 lines
6.4 KiB
Markdown
57 lines
6.4 KiB
Markdown
# Repository Guidelines
|
||
|
||
## Skill bootstrap: skip the post-update-cleanup step
|
||
|
||
If you load the Impeccable skill from `.agents/skills/impeccable/SKILL.md` (or any sibling harness directory under this repo), it begins with a `<post-update-cleanup>` block that runs `scripts/cleanup-deprecated.mjs` and then self-deletes. **Do not run it here, and do not delete the block.** This repo is the source of truth for the skill; cleanup-deprecated assumes a consumer project and would touch legitimate source files. The block is regenerated from `source/skills/impeccable/SKILL.md` on every `bun run build`, so any deletion churns back. Skip it silently and proceed with the task.
|
||
|
||
## Project Structure & Module Organization
|
||
|
||
`source/` is the source of truth. Author skills in `source/skills/impeccable/` and keep provider output in `dist/` generated, not hand-edited. Build logic lives in `scripts/`, with provider configs in `scripts/lib/transformers/`. Runtime detection code ships from `src/`. The website lives in `public/`, local API/dev serving lives in `server/`, and regression coverage lives in `tests/` with fixtures under `tests/fixtures/`.
|
||
|
||
## Build, Test, and Development Commands
|
||
|
||
- `bun run dev` - start the local Bun server.
|
||
- `bun run build` - regenerate `dist/`, derived site assets, and validation output.
|
||
- `bun run rebuild` - clean and rebuild everything from scratch.
|
||
- `bun test tests/build.test.js` - run a focused Bun test.
|
||
- `bun run test` - run the full Bun + Node test suite.
|
||
- `bun run test:live-e2e` - opt-in live-mode E2E against framework fixtures (~2 min; needs `npx playwright install chromium` once).
|
||
- `bun run build:browser` / `bun run build:extension` - rebuild browser-specific bundles.
|
||
|
||
Run `bun run build` after changing anything in `source/`, transformer code, or user-facing counts.
|
||
|
||
## Coding Style & Naming Conventions
|
||
|
||
Use ESM, semicolons, and the existing two-space indentation style in JS, HTML, and CSS. Prefer small, single-purpose modules over large abstractions. Keep filenames descriptive and lowercase with hyphens where needed; skill entrypoints stay as `SKILL.md`, helper scripts use `.js` or `.mjs`. In source frontmatter, use clear kebab-case names and concise descriptions. There is no dedicated formatter or linter configured here, so match surrounding code closely.
|
||
|
||
## Testing Guidelines
|
||
|
||
Tests use Bun’s test runner plus Node’s built-in `--test`. Name tests `*.test.js` or `*.test.mjs` and place new fixtures near the behavior they cover, usually under `tests/fixtures/`. Prefer targeted test runs while iterating, then finish with `bun run test`. If you change generated outputs or provider transforms, verify both source parsing and at least one affected provider path in `dist/`.
|
||
|
||
For changes to `source/skills/impeccable/scripts/live-*.{mjs,js}`, also run `bun run test:live-e2e` (kept out of the default suite because it does real `npm install` per fixture and boots framework dev servers). Scope to one fixture with `IMPECCABLE_E2E_ONLY=<fixture-name>` while iterating; pass `IMPECCABLE_E2E_DEBUG=1` for page-DOM and dev-server-log dumps on failure. Schema and authoring guide for new fixtures live in `tests/framework-fixtures/README.md`.
|
||
|
||
Set `IMPECCABLE_E2E_AGENT=llm` to swap the deterministic fake agent for a Claude-backed one (`tests/live-e2e/agents/llm-agent.mjs`, default Haiku 4.5, override via `IMPECCABLE_E2E_LLM_MODEL`). Requires `ANTHROPIC_API_KEY`; tests skip cleanly when it's unset. This path hits the API — use it for verification, not CI.
|
||
|
||
## Anti-pattern detection rules
|
||
|
||
`src/detect-antipatterns.mjs` is the source of truth for the rule engine. It feeds the CLI, the site overlay (`src/detect-antipatterns-browser.js`, regenerated by `bun run build:browser`), the Chrome extension (`extension/detector/`, regenerated by `bun run build:extension`), and the homepage `DETECTION_COUNT` in `public/js/generated/counts.js` (regenerated by `bun run build`). After any rule change run all three builds plus `bun run test` so nothing drifts.
|
||
|
||
TDD order is non-negotiable:
|
||
|
||
1. Add a fixture at `tests/fixtures/antipatterns/{rule-id}.html` with two columns (should-flag / should-pass), each case identified by a unique heading. ≥4 flag cases and ≥5 false-positive shapes. **Use explicit pixel dimensions in CSS** — jsdom does no layout.
|
||
2. Add a failing test in `tests/detect-antipatterns-fixtures.test.mjs` using the snippet-substring pattern (regex `/"([^"]+)"/` against `SHOULD_FLAG` / `SHOULD_PASS` lists).
|
||
3. Add the rule entry to the `ANTIPATTERNS` array (`id`, `category` = `slop` or `quality`, `name`, `description`, optional `skillSection` / `skillGuideline`).
|
||
4. Implement a pure `checkXxx(opts)` returning `[{ id, snippet }]` — no DOM access inside.
|
||
5. Add two adapters that wrap the pure check: `checkElementXxxDOM(el)` for the browser (`getComputedStyle` + `getBoundingClientRect`) and `checkElementXxx(el, tag, window)` for jsdom (`parseFloat(style.width)` instead of layout). Wire **both** adapters into **both** element loops in `src/detect-antipatterns.mjs` (browser loop ~line 1837, jsdom loop in `detectHtml` ~line 2058). Forgetting one is the most common mistake.
|
||
6. Verify on a live page at `http://localhost:3000/fixtures/antipatterns/{rule-id}.html` and on the homepage. The two adapter paths can disagree.
|
||
|
||
Conventions: wrap the identifying heading text in straight double quotes inside snippets so the fixture test can extract it. jsdom-specific helpers `resolveBackground()`, `resolveGradientStops()`, and `parseGradientColors()` exist because `background:` shorthand isn't decomposed and computed colors aren't normalized in jsdom — use them. Reference rules to copy from: `side-tab` (border), `low-contrast` (color+gradient), `icon-tile-stack` (sibling relationship), `flat-type-hierarchy` (page-level).
|
||
|
||
## Commit & Pull Request Guidelines
|
||
|
||
Recent history favors short, imperative subjects such as `Fix: ...`, `Add ...`, `Improve ...`, or `Bump ...`. Keep commits focused and explain the user-facing impact when it is not obvious. PRs should summarize what changed, list validation performed, and call out regenerated artifacts like `dist/` or `build/`. Include screenshots for visible `public/` changes and mention affected providers when transform behavior changes.
|
||
|
||
## Contributor Notes
|
||
|
||
Do not edit generated provider files directly unless you are intentionally patching generated output as part of a build-system change. Prefer fixing the root source in `source/`, `scripts/`, or `src/`, then regenerate artifacts.
|