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
8 changes: 8 additions & 0 deletions .cursor/rules/pnpm-install.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
alwaysApply: false
---

# pnpm install

- Never run `pnpm install` or `pnpm i` in the sandbox.
- When dependencies need installing or updating, **prompt the user** to run `pnpm install` (or the exact `pnpm` command) locally instead of running it here.
19 changes: 19 additions & 0 deletions .cursor/rules/skill-maintenance.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
description: When changing deps, scripts, e2e, release, or issue format, update the matching project skills and note it in the response
alwaysApply: true
---

# Skill maintenance

When you change any of the following, update the corresponding skill(s) in `.cursor/skills/` and briefly mention in your response that skills were updated.

| Change | Update these skills |
|--------|----------------------|
| Key dependencies (WXT, Svelte, Playwright, changesets, oxlint, dprint) or build/config (wxt.config.ts, .oxlintrc.json) | wxt-svelte-extension (SKILL.md; reference.md if a new known issue) |
| package.json scripts (dev/build/zip) or new build targets | wxt-svelte-extension, releases-changesets if release steps change |
| E2E layout (e2e/tests, e2e/pages, fixture file path or name) | e2e-playwright-extension |
| Release workflow (.changeset/, release steps, workflow_dispatch) | releases-changesets |
| Issue refinement format or label set (docs/ISSUE_REFINEMENTS.md) | issue-refinement-triage |
| New recurring “known issue” that should guide extension code | wxt-svelte-extension/reference.md |

Read the current skill file before editing so the update stays consistent with existing structure and wording.
24 changes: 24 additions & 0 deletions .cursor/rules/svelte-wxt-standards.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
description: Svelte 5 + WXT + Tailwind v4 coding standards; runes-only, no comments, readability first
alwaysApply: true
---

# Svelte WXT standards

## Svelte / WXT / stack

- Use PascalCase for component file names (e.g. MyComponent.svelte).
- Use semantic HTML where possible.
- Use Svelte stores for global state; TypeScript for type safety.
- Svelte 5 runes only: never use legacy reactive statements ($:) or reactive `let`.
- Use $state() for reactive local state, $derived() for computed values, $effect() for side effects, $props() for component props.
- No comments; rely on clear naming and structure.
- Use Tailwind v4 classes instead of custom styles.

## General

- Follow the user's requirements carefully and fully.
- Prefer readable, correct, and complete code; avoid todos and placeholders.
- Reference file names; be concise; follow project structure and formatting.
- If the answer is uncertain or unknown, say so instead of guessing.
- When asked, produce or update architecture diagrams from project structure and requirements.
37 changes: 37 additions & 0 deletions .cursor/skills/e2e-playwright-extension/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
name: e2e-playwright-extension
description: Adds or updates extension E2E tests using the project Playwright setup and fixture (load unpacked extension, popup/background). Use when adding e2e for a feature, fixing failing e2e, or when changing popup/options/background flows.
---

# E2E with Playwright (extension)

Aligned with [WXT’s Playwright E2E example](https://github.com/wxt-dev/examples/tree/main/examples/playwright-e2e-testing): Chromium only, extension loaded from `dist/chrome-mv3`.

## Layout

- Tests in [e2e/tests/](e2e/tests/) — main suite [e2e/tests/extension.spec.ts](e2e/tests/extension.spec.ts) with describe blocks: **Popup**, **Content injection**, **Per-domain activation**
- Shared fixture in [e2e/fixtures.ts](e2e/fixtures.ts)
- Page helpers in [e2e/pages/](e2e/pages/) (e.g. [e2e/pages/popup.ts](e2e/pages/popup.ts))

## Fixture

The fixture extends Playwright with:

- **context:** Chromium persistent context that loads the unpacked extension from `dist/chrome-mv3`
- **extensionId:** Resolved from the service worker (MV3) or background page otherwise

Use `context` and `extensionId` in tests. Import the extended `test` and `expect` from the fixture.

## Popup

Navigate to `chrome-extension://${extensionId}/popup.html`. Use helpers like `openPopup(page, extensionId)` from [e2e/pages/popup.ts](e2e/pages/popup.ts) for consistent setup. Tests: "popup opens and shows active toggle" (Popup), "inspector root and app load on supported page" (Content injection), "when domain is enabled in storage, inspector is active on page load" (Per-domain activation).

## Run

- First-time: `pnpm exec playwright install chromium` (installs Chromium and headless shell; do not use `--no-shell` or default tests will fail).
- Build the extension: `pnpm build` so `dist/chrome-mv3` exists.
- Run tests: `pnpm test:e2e`

## Note

`playwright-webextext` is in devDependencies for potential future use; current tests use the custom fixture in `fixtures.ts`.
44 changes: 44 additions & 0 deletions .cursor/skills/issue-refinement-triage/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
name: issue-refinement-triage
description: Refines GitHub issues into the ISSUE_REFINEMENTS format and keeps docs/ISSUE_REFINEMENTS.md in sync. Use when triaging issues, refining a new issue, updating the refinements doc, or when the user asks to refine an issue or add to refinements.
---

# Issue Refinement and Triage

## Canonical source

Read [docs/ISSUE_REFINEMENTS.md](docs/ISSUE_REFINEMENTS.md) for the current open/closed list and label table before editing.

## Issue block template

Each refined issue uses this format. Separate blocks with `---`.

```markdown
### #N — Title

**Labels:** `label1` `label2`
**Context:** Raw description or user report.
**Refined:** One-line actionable scope or decision.
**My comments:** _(add notes here)_
```

## Labels (only these)

| Label | Use for |
| ------------------ | -------------------------------------- |
| `bug` | Something broken or incorrect behavior |
| `documentation` | Docs, README, FAQ, browser support |
| `enhancement` | New feature or improvement |
| `good first issue` | Clear, scoped tasks for contributors |
| `question` | Open questions, naming, investigation |
| `UI/UX` | User-facing behavior, flows, layout |
| `Brainstorm` | Ideas, naming, long-running discussion |
| `infrastructure` | CI/CD, release, monitoring, tooling |

Suggest only these labels; use space-separated list in the block.

## Workflow

1. **New or raw issue:** Propose labels (from the table) and a one-line **Refined** that scopes or clarifies the issue.
2. **Updating ISSUE_REFINEMENTS:** Add new refined issues under "Open issues (refined)". When an issue is closed, move its block to "Closed issues (reference)" and keep the same format.
3. **My comments:** Reserved for maintainer notes (priority, blockers, batching). Leave as `*(add notes here)*` if no note.
29 changes: 29 additions & 0 deletions .cursor/skills/jj-bookmark-push/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
name: jj-bookmark-push
description: Uses jj (Jujutsu VCS) to create or update bookmarks and push to the Git remote. Use when creating a branch/bookmark, moving a bookmark to the current revision, or pushing changes with jj instead of git.
---

# jj bookmark and push

Use jj for version control in this project (not git) when creating branches, updating bookmarks, or pushing.

## Rules

- **Never push without a description.** jj rejects pushing revisions with no commit message. Before push, ensure current revision has a description. If it is missing, apply [jj-commit](.cursor/skills/jj-commit/SKILL.md) to add a proper message, then push. Alternatively move the bookmark to a described rev: `jj bookmark set <name> -r <rev> -B` then push.
- **Never rewrite pushed commits.** No amend/squash of commits already pushed or on a branch with an open PR; that force-pushes and removes GitHub PR comments. Add a new commit for follow-up changes unless the user explicitly requests a force-push.

## Workflow

1. Make changes; commit with `jj commit` / `jj new` (set description when committing).
2. `jj bookmark set <branch-name>` so the bookmark points at the revision to publish.
3. `jj git push -b <branch-name>`.

Bookmarks are branch-like pointers. Set: `jj bookmark set <name>`. Set to a revision: `jj bookmark set <name> -r <rev>`. Use `-B` to move backwards. Push one: `jj git push -b <name>`. Push all: `jj git push --all`. List: `jj bookmark list --all`.

## If push fails

| Symptom | Fix |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "has no description" | Apply [jj-commit](.cursor/skills/jj-commit/SKILL.md) to add a proper message, then push. Or move bookmark to a described rev: `jj bookmark set <name> -r <rev> -B` then push. |
| "Refusing to move bookmark backwards" | Use `-B`: `jj bookmark set <name> -r <rev> -B`. |
| Remote bookmark moved / conflict | `jj git fetch`; resolve conflict or set bookmark to desired rev with `-B` if needed, then push. |
37 changes: 37 additions & 0 deletions .cursor/skills/jj-commit/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
name: jj-commit
description: Stages and commits changes in jj (Jujutsu VCS) with a clear, concise commit message. Use when committing changes with jj, setting a revision description, or when the user asks to commit with jj.
---

# jj commit (describe)

Create a commit for the current changes by setting the revision description. In jj there is no staging area; the working copy is the current revision.

## Steps

1. Run `jj status` to see working-copy state and which files changed.
2. Run `jj diff` to see changes in the current revision (working copy vs parent). Use `-r @` to restrict to the current rev if needed.
3. Run `jj log -n 5` to see recent commit style.
4. Write a commit message and run `jj describe -m "message"`.

If the user provides a message hint (e.g. in the request), use it when writing the message.

To start a new change before describing, run `jj new`; then set the description on that revision.

## Commit message rules

- Use the imperative mood ("Add", "Fix", "Remove", not "Added", "Fixes", "Removed").
- Be concise: one short sentence, ideally under 50 characters.
- Do NOT use conventional commit prefixes (no `feat:`, `fix:`, `chore:`, etc.).
- Do NOT add any `Co-Authored-By` or similar trailers.
- Focus on **what** changed and **why**, not how.
- If a second line is needed for context, keep it brief.

## Examples of good messages

- `Prevent discount code from being cleared on edit`
- `Add integration test for offer code persistence`
- `Remove unused legacy export helper`
- `Fix thumbnail missing in upsell insert`

When pushing, use [jj-bookmark-push](.cursor/skills/jj-bookmark-push/SKILL.md); never push without a description.
70 changes: 70 additions & 0 deletions .cursor/skills/pr-from-issue/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
name: pr-from-issue
description: Creates a GitHub PR for the current work using GitHub MCP; links to an existing issue with Closes #N, creates an issue if none exists, and for large scope creates sub-issues and multiple PRs (each PR closes sub-issues; last PR closes sub-issues + main issue). Use when opening a PR for the current issue or when the user asks to create a PR from the current work.
---

# Create PR from current issue

Use GitHub MCP (server `user-github`) for all GitHub actions. Before calling any MCP tool, check its schema (e.g. under `mcps/user-github/tools/` or via Cursor MCP discovery) so parameters are correct.

## Quick decision

1. **Issue:** From conversation (e.g. "issue #5") or search — identify the main issue #M. If none exists, create one via GitHub MCP and use labels from [docs/ISSUE_REFINEMENTS.md](docs/ISSUE_REFINEMENTS.md) / [issue-refinement-triage](.cursor/skills/issue-refinement-triage/SKILL.md).
2. **Scope:** If the change is small or not splittable → single PR. If large and decomposable → create sub-issues S1…Sn, then multiple PRs (see [reference.md](reference.md) for heuristics).

## Single PR workflow

1. Ensure main issue #M exists (found or created).
2. Ensure branch is pushed: use [jj-bookmark-push](.cursor/skills/jj-bookmark-push/SKILL.md) — `jj bookmark set <branch-name>` then `jj git push -b <branch-name>`.
3. Check for a PR template: `.github/PULL_REQUEST_TEMPLATE/` or `pull_request_template.md` in the repo; use it if present.
4. Create the PR via `call_mcp_tool` with server `user-github` and the create_pull_request tool. PR body must include `Closes #M`.

## Multiple PR (sub-issues) workflow

1. Main issue #M exists. Create sub-issues S1, S2, … Sn (e.g. "Part 1: …", "Part 2: …") and reference the main issue in each sub-issue body (e.g. "Parent: #M").
2. For each sub-piece of work: push its branch (jj bookmark + push), then create a PR that closes the corresponding sub-issue(s).
- PR 1: body includes `Closes #S1`.
- PR 2: body includes `Closes #S2`.
- …
3. **Last PR:** Include `Closes #S_last` (and any other sub-issues this PR completes) and **`Closes #M`** so the main issue is closed when the last PR is merged.

## GitHub MCP tools

Use `call_mcp_tool` with `server: "user-github"`. Typical tools and intent:

| Tool (check schema for exact name) | Use for |
| ---------------------------------- | ------------------------------------------------------------------------- |
| get_me | Current user and permissions; infer or confirm owner/repo |
| search_issues | Find existing issue by number, title, or labels; avoid duplicate creation |
| create_issue (or equivalent) | Create main or sub-issue when missing; use ISSUE_REFINEMENTS labels |
| create_pull_request | Create PR from branch; use repo PR template if present |
| list_issue_types | Optional; use for orgs that use issue types |

Infer `owner/repo` from git remote or conversation. Always check the tool’s JSON descriptor for required parameters before calling.

## Branch and push

This project uses jj. A bookmark is the branch name. Before creating a PR:

1. `jj bookmark set <branch-name>` so the bookmark points at the revision to publish.
2. `jj git push -b <branch-name>`.

See [jj-bookmark-push](.cursor/skills/jj-bookmark-push/SKILL.md) for details. Do not rewrite already-pushed commits.

## PR body rules

- **Single issue:** Body must include `Closes #M` (main issue number).
- **Sub-issue PR (not last):** Body must include `Closes #S1` (and any other sub-issues that PR completes).
- **Last PR in a breakdown:** Body must include `Closes #S_last` and `Closes #M`.

Use the repo’s PR template if present. Title and description should reflect the issue and the change.

## Summary

| Scenario | Action |
| ------------------------- | ---------------------------------------------------------------------------------------------------------- |
| No issue | Create issue via MCP; one PR with `Closes #M`. |
| One issue, small scope | One PR with `Closes #M`. |
| One issue, can break down | Create sub-issues S1…Sn; each PR closes its sub-issue(s); last PR closes its sub-issue(s) and `Closes #M`. |

For when to treat work as "big", how to phrase sub-issues, and example PR body snippets, see [reference.md](reference.md).
44 changes: 44 additions & 0 deletions .cursor/skills/pr-from-issue/reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# PR-from-issue reference

## When to consider work "big" and break into sub-issues

Consider creating sub-issues when:

- **Many files or areas:** Change touches several unrelated modules, entrypoints, or layers (e.g. backend + frontend + docs).
- **Logical parts:** Work naturally splits into steps (e.g. "add API", "add UI", "add tests") that can be implemented and reviewed separately.
- **User says so:** User asks to break the PR down or to open multiple smaller PRs.

Stay with a single PR when the change is one coherent patch (e.g. one feature in one area, or a small fix).

## Sub-issue titles and linking to the main issue

- **Titles:** Use clear, scoped titles (e.g. "Part 1: Add API for X", "Part 2: Popup UI for X"). Avoid vague titles like "Sub-issue 1".
- **Body:** In each sub-issue body, reference the main issue (e.g. "Parent: #M" or "Part of #M — …") so the relationship is visible on GitHub.

## Example PR body snippets

**Single issue:**

```markdown
Closes #12.

Implements the settings page as described in the issue.
```

**Sub-issue PR (not the last):**

```markdown
Closes #14.

Part 2 of #10: adds the popup UI. API and types were added in #13.
```

**Last PR in a breakdown (closes sub-issue + main):**

```markdown
Closes #15. Closes #10.

Final part: wiring and E2E tests. With this merge, the main issue #10 is complete.
```

Use the repo’s PR template if one exists; add the "Closes" line(s) in the appropriate place (often at the top or in a "Fixes" section).
24 changes: 24 additions & 0 deletions .cursor/skills/releases-changesets/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: releases-changesets
description: Uses changesets for versioning and changelog; avoids manual version bumps; aligns with build/zip and workflow_dispatch. Use when cutting a release, adding a changeset, preparing for publish, or when touching version or changelog.
---

# Releases and Versioning (changesets)

## Rule

All user-facing or notable changes get a changeset in [.changeset/](.changeset/). Do not edit `package.json` version manually for releases.

## Adding a changeset

- Run `pnpm changeset`, or add a new `.md` file in `.changeset/` with the standard format: semver type (major/minor/patch) and a short summary for the changelog.

## Config

[.changeset/config.json](.changeset/config.json): `changelog: "@changesets/cli/changelog"`, `commit: false`, `baseBranch: "main"`.

## Release steps

1. Build both targets: `pnpm build:all`
2. Create zips: `pnpm zip:all`
3. workflow_dispatch (e.g. issue #27) is the intended automation when available; document in README when in place.
Loading
Loading