{"owner":"MODSetter","repo":"SurfSense","hasSkills":true,"totalSkillsCount":5,"totalTokensCount":5298,"categories":["root-instruction","claude-rule","mcp-config","marketplace","plugin-manifest"],"hasMcp":true,"mcpConfig":{"mcpServers":{"SurfSense":{"command":"npx","args":["-y","@modelcontextprotocol/server-SurfSense"]}}},"found":["AGENTS.md","CLAUDE.md",".cursor/mcp.json",".claude-plugin/marketplace.json",".claude-plugin/plugin.json"],"skills":{"AGENTS.md":"# AGENTS.md\n\nNearest `AGENTS.md` wins. Edit this file, not `CLAUDE.md` (`CLAUDE.md` is a symlink).\n\n## Overview\n\nDesktop app plus scraper API. Five trees:\n\n| Tree | Role |\n|------|------|\n| `surfsense_backend` | FastAPI API |\n| `surfsense_web` | Next.js hosted UI |\n| `surfsense_local` | Electron desktop |\n| `surfsense_mcp` | MCP server over the REST API |\n| `plugins` | SurfSense's own plugin servers ([plugin host](docs/architecture/plugin-host.md)) and the [registry](docs/architecture/plugin-registry.md). `bundles/` holds the earlier, local design's SDK and tooling, deferred |\n\nThe hosted service has been export-only since the 2.0.0 launch on 18 Sep 2026, and its user data is purged on 18 Oct 2026 ([sunset](docs/architecture/sunset.md)). Product direction is local + API.\n\n## Code organization\n\nApplies to **every new file**. Existing code is not a template and not a cleanup ticket.\n\n**Must**\n\n- Organize by feature (vertical slice), not by technical layer.\n- One responsibility per file. One responsibility per folder.\n- If a responsibility grows sub-responsibilities, promote it to a folder. Each sub-responsibility is its own file.\n- Names state what and why, not how.\n- Comments and docstrings state intent only. Do not restate the code.\n- Keep them short. A line or two. Write only what the code cannot say: a constraint, a rejected alternative, a number that justifies a threshold.\n\n**Must not**\n\n- Do not write essays in docstrings. If it explains how you arrived at the code rather than what the code must honour, delete it.\n- Do not put new work in a nearby file because it is convenient. New responsibility, new file.\n- Do not add catch-all folders (`utils`, `helpers`, `common`, `misc`, `shared`) unless that name is the product concept.\n- Do not layer-split new work (`controllers/`, `services/`, `models/` as the primary tree).\n- Do not rewrite existing code to this layout unless the task is that rewrite.\n\nThe tree is inconsistent. New work follows this. Old work stays until a task explicitly owns it.\n\n## Docs\n\n[`docs/`](docs/README.md) is the engineering map. `architecture/` says what is true now, one doc per feature; `adr/` says why; `proposals/` holds designs not built yet; `contracts/` holds the frozen interfaces between trees. Task status lives in GitHub issues; docs carry only a proposal's `status` and each architecture doc's Known gaps. `plans/` is business and ops material, not specs.\n\n- Before changing a feature, read its doc in `docs/architecture/` and the ADRs it links.\n- If a change alters behaviour a doc describes, update the doc in the same change. Fixing a Known gap deletes its line.\n- Run `python scripts/check_docs.py` after editing anything under `docs/` or `plans/`.\n\n## Commands\n\n```bash\n# backend\ncd surfsense_backend && uv sync\ncd surfsense_backend && uv run ruff check .\ncd surfsense_backend && uv run pytest -m unit\n\n# web\ncd surfsense_web && pnpm install\ncd surfsense_web && pnpm dev\ncd surfsense_web && pnpm format\n\n# desktop\ncd surfsense_local/electron && pnpm dev\n\n# MCP\ncd surfsense_mcp && uv sync\n\n# plugin host: SurfSense's own plugins, from plugins/remote/\ncd plugins/remote/host && uv sync\ncd plugins/remote && uv run --project host python -m host\n\n# bundles (deferred): the manifest rules, the SDK, the surfsense-plugins command\ncd plugins/bundles/core/manifest && uv sync\ncd plugins/bundles/core/sdk && uv sync\ncd plugins/bundles/core/sdk && uv run pyright\ncd plugins/bundles/core/cli && uv sync\n\n# compose (dev and self-host, not production)\ndocker compose -f docker/docker-compose.yml\n\n# hooks\npre-commit run --all-files\n```\n\n## Testing\n\n| Area | Command |\n|------|---------|\n| Backend unit | `cd surfsense_backend && uv run pytest -m unit` |\n| Backend integration | `cd surfsense_backend && uv run pytest -m integration` |\n| Web unit | `cd surfsense_web && pnpm test:unit` |\n| Web e2e | `cd surfsense_web && pnpm test:e2e` |\n| MCP | `cd surfsense_mcp && uv run pytest` |\n| Plugin host | `cd plugins/remote/host && uv run pytest` |\n| Bundles: manifest rules | `cd plugins/bundles/core/manifest && uv run pytest -m unit` |\n| Bundles: SDK | `cd plugins/bundles/core/sdk && uv run pytest -m unit` |\n| Bundles: SDK against the app | `cd plugins/bundles/core/sdk && uv run pytest -m contract` (starts the backend; `uv sync` it first) |\n| Bundles: CLI | `cd plugins/bundles/core/cli && uv run pytest` (starts the backend; `uv sync` it first) |\n| Desktop | `cd surfsense_local/electron && pnpm test` |\nCI: `.github/workflows/`. New behavior: one failing test, then the minimum code to pass it. Use the `tdd` skill. Tests hit public seams, not internals.\n\n## Pull requests\n\nFollow [CONTRIBUTING.md](CONTRIBUTING.md). The parts agents miss:\n\n- Open PRs against `dev`. `gh pr create` targets the default branch, `main`, unless you pass `--base dev`.\n- `gh pr create --body` skips the PR template. Keep its headings: What, Why, `Fixes #`, How to test.\n- Commit messages and PR titles are Conventional Commits, `type(scope): summary`. The commitizen hook runs only where it is installed; CI does not run it.\n- A new feature starts as a proposal PR in `docs/proposals/`, not as code.\n- `surfsense_backend/app/proprietary/` and `plugins/remote/proprietary/` are Business Source License 1.1 and changed only by maintainers: ask one before changing them. A change to `docs/contracts/` needs the owners of both sides.\n\n## Skills\n\nCanonical dir: `.agents/skills/`. `.claude/skills` is a symlink to it.\n\n| Skill | When |\n|-------|------|\n| `tdd` | New behavior or a bug fix with a testable seam |\n| `codebase-design` | Module shape, seam, depth — `tdd` depends on this vocabulary |\n| `fastapi` | FastAPI / Pydantic work. Symlink into the installed wheel; repair the **same** root link after a FastAPI or Python bump. Do not keep `surfsense_backend/.agents/`. |\n| `frontend-workflow` | Frontend work in `surfsense_web` and `surfsense_local/frontend`: React/Next performance, color tokens, UI polish, motion. Bundles `react-performance/`, `color/`, `polish/`, `motion/`, and `base-ui.md` for Base UI in `surfsense_local/frontend`; routes out to `shadcn`. |\n| `shadcn` | UI components in a tree with `components.json`. Standalone — it inspects the project live and grants its own CLI, which only works as a discovered skill. Load it after `frontend-workflow`, not instead of it. |\n| `translate` | Interface strings in `surfsense_local`: adding a message in code (`en.json` is generated from it), moving hard-coded text into messages, translating Japanese and German. Holds the key shape, tone and glossary. |\n\nDo not install skill catalogs. Do not add `CONTEXT.md` or a second rules tree.\n\n`frontend-workflow` bundles what were separate skills under `react-performance/`,\n`color/`, `polish/`, and `motion/`. Those files keep their old frontmatter, which\nis inert — they are reference files, not discovered skills. Skill discovery is one\nlevel deep, so do not nest a new skill inside another skill's folder.\n\nBundle a skill only if it is static markdown that overlaps the others. Anything\nwith frontmatter that does work — `allowed-tools`, `` !`command` `` substitution —\nmust stay top-level, because that frontmatter is inert in a bundled file.\n\n`shadcn/SKILL.md` carries one local addition: a note routing to `frontend-workflow`\nfirst. It is the only edit to that vendored file — restore it after any shadcn\nre-sync, or component work bypasses the color palette and polish rules.\n\n`skills-lock.json` lists `vercel-react-best-practices`, which now lives at\n`frontend-workflow/react-performance/`. `shadcn` is back at its original path and\nits lock entry is valid.\n\n## Boundaries\n\n- Do not carve hosted code out of backend/web until the purge on 18 Oct 2026. The export window and the purge script run on that code until then.\n- Do not drop SearxNG, sandbox, OpenSandbox, or zero-cache from compose until a new compose is defined.\n- Edit the root `README.md` directly. The draft at `plans/community-local/seo/drafts/README.md` shipped on 18 Sep 2026 and is kept only for history. Anything added to the README replaces something — its length was measured against the eight biggest repos in this category. Make the same change in every `README.<locale>.md`, section for section; [`06-repo-readme.md`](plans/community-local/seo/06-repo-readme.md#the-readme-since-9-oct-2026) has the rules, where each format-table cell is checked, and how to replace the demo video.\n- Do not commit, push or open a PR unless asked.\n\n## Security\n\n- Never commit `.env` or secrets.\n- Do not put credentials in diffs, logs, or sample payloads.\n","CLAUDE.md":"# AGENTS.md\n\nNearest `AGENTS.md` wins. Edit this file, not `CLAUDE.md` (`CLAUDE.md` is a symlink).\n\n## Overview\n\nDesktop app plus scraper API. Five trees:\n\n| Tree | Role |\n|------|------|\n| `surfsense_backend` | FastAPI API |\n| `surfsense_web` | Next.js hosted UI |\n| `surfsense_local` | Electron desktop |\n| `surfsense_mcp` | MCP server over the REST API |\n| `plugins` | SurfSense's own plugin servers ([plugin host](docs/architecture/plugin-host.md)) and the [registry](docs/architecture/plugin-registry.md). `bundles/` holds the earlier, local design's SDK and tooling, deferred |\n\nThe hosted service has been export-only since the 2.0.0 launch on 18 Sep 2026, and its user data is purged on 18 Oct 2026 ([sunset](docs/architecture/sunset.md)). Product direction is local + API.\n\n## Code organization\n\nApplies to **every new file**. Existing code is not a template and not a cleanup ticket.\n\n**Must**\n\n- Organize by feature (vertical slice), not by technical layer.\n- One responsibility per file. One responsibility per folder.\n- If a responsibility grows sub-responsibilities, promote it to a folder. Each sub-responsibility is its own file.\n- Names state what and why, not how.\n- Comments and docstrings state intent only. Do not restate the code.\n- Keep them short. A line or two. Write only what the code cannot say: a constraint, a rejected alternative, a number that justifies a threshold.\n\n**Must not**\n\n- Do not write essays in docstrings. If it explains how you arrived at the code rather than what the code must honour, delete it.\n- Do not put new work in a nearby file because it is convenient. New responsibility, new file.\n- Do not add catch-all folders (`utils`, `helpers`, `common`, `misc`, `shared`) unless that name is the product concept.\n- Do not layer-split new work (`controllers/`, `services/`, `models/` as the primary tree).\n- Do not rewrite existing code to this layout unless the task is that rewrite.\n\nThe tree is inconsistent. New work follows this. Old work stays until a task explicitly owns it.\n\n## Docs\n\n[`docs/`](docs/README.md) is the engineering map. `architecture/` says what is true now, one doc per feature; `adr/` says why; `proposals/` holds designs not built yet; `contracts/` holds the frozen interfaces between trees. Task status lives in GitHub issues; docs carry only a proposal's `status` and each architecture doc's Known gaps. `plans/` is business and ops material, not specs.\n\n- Before changing a feature, read its doc in `docs/architecture/` and the ADRs it links.\n- If a change alters behaviour a doc describes, update the doc in the same change. Fixing a Known gap deletes its line.\n- Run `python scripts/check_docs.py` after editing anything under `docs/` or `plans/`.\n\n## Commands\n\n```bash\n# backend\ncd surfsense_backend && uv sync\ncd surfsense_backend && uv run ruff check .\ncd surfsense_backend && uv run pytest -m unit\n\n# web\ncd surfsense_web && pnpm install\ncd surfsense_web && pnpm dev\ncd surfsense_web && pnpm format\n\n# desktop\ncd surfsense_local/electron && pnpm dev\n\n# MCP\ncd surfsense_mcp && uv sync\n\n# plugin host: SurfSense's own plugins, from plugins/remote/\ncd plugins/remote/host && uv sync\ncd plugins/remote && uv run --project host python -m host\n\n# bundles (deferred): the manifest rules, the SDK, the surfsense-plugins command\ncd plugins/bundles/core/manifest && uv sync\ncd plugins/bundles/core/sdk && uv sync\ncd plugins/bundles/core/sdk && uv run pyright\ncd plugins/bundles/core/cli && uv sync\n\n# compose (dev and self-host, not production)\ndocker compose -f docker/docker-compose.yml\n\n# hooks\npre-commit run --all-files\n```\n\n## Testing\n\n| Area | Command |\n|------|---------|\n| Backend unit | `cd surfsense_backend && uv run pytest -m unit` |\n| Backend integration | `cd surfsense_backend && uv run pytest -m integration` |\n| Web unit | `cd surfsense_web && pnpm test:unit` |\n| Web e2e | `cd surfsense_web && pnpm test:e2e` |\n| MCP | `cd surfsense_mcp && uv run pytest` |\n| Plugin host | `cd plugins/remote/host && uv run pytest` |\n| Bundles: manifest rules | `cd plugins/bundles/core/manifest && uv run pytest -m unit` |\n| Bundles: SDK | `cd plugins/bundles/core/sdk && uv run pytest -m unit` |\n| Bundles: SDK against the app | `cd plugins/bundles/core/sdk && uv run pytest -m contract` (starts the backend; `uv sync` it first) |\n| Bundles: CLI | `cd plugins/bundles/core/cli && uv run pytest` (starts the backend; `uv sync` it first) |\n| Desktop | `cd surfsense_local/electron && pnpm test` |\nCI: `.github/workflows/`. New behavior: one failing test, then the minimum code to pass it. Use the `tdd` skill. Tests hit public seams, not internals.\n\n## Pull requests\n\nFollow [CONTRIBUTING.md](CONTRIBUTING.md). The parts agents miss:\n\n- Open PRs against `dev`. `gh pr create` targets the default branch, `main`, unless you pass `--base dev`.\n- `gh pr create --body` skips the PR template. Keep its headings: What, Why, `Fixes #`, How to test.\n- Commit messages and PR titles are Conventional Commits, `type(scope): summary`. The commitizen hook runs only where it is installed; CI does not run it.\n- A new feature starts as a proposal PR in `docs/proposals/`, not as code.\n- `surfsense_backend/app/proprietary/` and `plugins/remote/proprietary/` are Business Source License 1.1 and changed only by maintainers: ask one before changing them. A change to `docs/contracts/` needs the owners of both sides.\n\n## Skills\n\nCanonical dir: `.agents/skills/`. `.claude/skills` is a symlink to it.\n\n| Skill | When |\n|-------|------|\n| `tdd` | New behavior or a bug fix with a testable seam |\n| `codebase-design` | Module shape, seam, depth — `tdd` depends on this vocabulary |\n| `fastapi` | FastAPI / Pydantic work. Symlink into the installed wheel; repair the **same** root link after a FastAPI or Python bump. Do not keep `surfsense_backend/.agents/`. |\n| `frontend-workflow` | Frontend work in `surfsense_web` and `surfsense_local/frontend`: React/Next performance, color tokens, UI polish, motion. Bundles `react-performance/`, `color/`, `polish/`, `motion/`, and `base-ui.md` for Base UI in `surfsense_local/frontend`; routes out to `shadcn`. |\n| `shadcn` | UI components in a tree with `components.json`. Standalone — it inspects the project live and grants its own CLI, which only works as a discovered skill. Load it after `frontend-workflow`, not instead of it. |\n| `translate` | Interface strings in `surfsense_local`: adding a message in code (`en.json` is generated from it), moving hard-coded text into messages, translating Japanese and German. Holds the key shape, tone and glossary. |\n\nDo not install skill catalogs. Do not add `CONTEXT.md` or a second rules tree.\n\n`frontend-workflow` bundles what were separate skills under `react-performance/`,\n`color/`, `polish/`, and `motion/`. Those files keep their old frontmatter, which\nis inert — they are reference files, not discovered skills. Skill discovery is one\nlevel deep, so do not nest a new skill inside another skill's folder.\n\nBundle a skill only if it is static markdown that overlaps the others. Anything\nwith frontmatter that does work — `allowed-tools`, `` !`command` `` substitution —\nmust stay top-level, because that frontmatter is inert in a bundled file.\n\n`shadcn/SKILL.md` carries one local addition: a note routing to `frontend-workflow`\nfirst. It is the only edit to that vendored file — restore it after any shadcn\nre-sync, or component work bypasses the color palette and polish rules.\n\n`skills-lock.json` lists `vercel-react-best-practices`, which now lives at\n`frontend-workflow/react-performance/`. `shadcn` is back at its original path and\nits lock entry is valid.\n\n## Boundaries\n\n- Do not carve hosted code out of backend/web until the purge on 18 Oct 2026. The export window and the purge script run on that code until then.\n- Do not drop SearxNG, sandbox, OpenSandbox, or zero-cache from compose until a new compose is defined.\n- Edit the root `README.md` directly. The draft at `plans/community-local/seo/drafts/README.md` shipped on 18 Sep 2026 and is kept only for history. Anything added to the README replaces something — its length was measured against the eight biggest repos in this category. Make the same change in every `README.<locale>.md`, section for section; [`06-repo-readme.md`](plans/community-local/seo/06-repo-readme.md#the-readme-since-9-oct-2026) has the rules, where each format-table cell is checked, and how to replace the demo video.\n- Do not commit, push or open a PR unless asked.\n\n## Security\n\n- Never commit `.env` or secrets.\n- Do not put credentials in diffs, logs, or sample payloads.\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/plugin.json)"},"files":{"AGENTS.md":"# AGENTS.md\n\nNearest `AGENTS.md` wins. Edit this file, not `CLAUDE.md` (`CLAUDE.md` is a symlink).\n\n## Overview\n\nDesktop app plus scraper API. Five trees:\n\n| Tree | Role |\n|------|------|\n| `surfsense_backend` | FastAPI API |\n| `surfsense_web` | Next.js hosted UI |\n| `surfsense_local` | Electron desktop |\n| `surfsense_mcp` | MCP server over the REST API |\n| `plugins` | SurfSense's own plugin servers ([plugin host](docs/architecture/plugin-host.md)) and the [registry](docs/architecture/plugin-registry.md). `bundles/` holds the earlier, local design's SDK and tooling, deferred |\n\nThe hosted service has been export-only since the 2.0.0 launch on 18 Sep 2026, and its user data is purged on 18 Oct 2026 ([sunset](docs/architecture/sunset.md)). Product direction is local + API.\n\n## Code organization\n\nApplies to **every new file**. Existing code is not a template and not a cleanup ticket.\n\n**Must**\n\n- Organize by feature (vertical slice), not by technical layer.\n- One responsibility per file. One responsibility per folder.\n- If a responsibility grows sub-responsibilities, promote it to a folder. Each sub-responsibility is its own file.\n- Names state what and why, not how.\n- Comments and docstrings state intent only. Do not restate the code.\n- Keep them short. A line or two. Write only what the code cannot say: a constraint, a rejected alternative, a number that justifies a threshold.\n\n**Must not**\n\n- Do not write essays in docstrings. If it explains how you arrived at the code rather than what the code must honour, delete it.\n- Do not put new work in a nearby file because it is convenient. New responsibility, new file.\n- Do not add catch-all folders (`utils`, `helpers`, `common`, `misc`, `shared`) unless that name is the product concept.\n- Do not layer-split new work (`controllers/`, `services/`, `models/` as the primary tree).\n- Do not rewrite existing code to this layout unless the task is that rewrite.\n\nThe tree is inconsistent. New work follows this. Old work stays until a task explicitly owns it.\n\n## Docs\n\n[`docs/`](docs/README.md) is the engineering map. `architecture/` says what is true now, one doc per feature; `adr/` says why; `proposals/` holds designs not built yet; `contracts/` holds the frozen interfaces between trees. Task status lives in GitHub issues; docs carry only a proposal's `status` and each architecture doc's Known gaps. `plans/` is business and ops material, not specs.\n\n- Before changing a feature, read its doc in `docs/architecture/` and the ADRs it links.\n- If a change alters behaviour a doc describes, update the doc in the same change. Fixing a Known gap deletes its line.\n- Run `python scripts/check_docs.py` after editing anything under `docs/` or `plans/`.\n\n## Commands\n\n```bash\n# backend\ncd surfsense_backend && uv sync\ncd surfsense_backend && uv run ruff check .\ncd surfsense_backend && uv run pytest -m unit\n\n# web\ncd surfsense_web && pnpm install\ncd surfsense_web && pnpm dev\ncd surfsense_web && pnpm format\n\n# desktop\ncd surfsense_local/electron && pnpm dev\n\n# MCP\ncd surfsense_mcp && uv sync\n\n# plugin host: SurfSense's own plugins, from plugins/remote/\ncd plugins/remote/host && uv sync\ncd plugins/remote && uv run --project host python -m host\n\n# bundles (deferred): the manifest rules, the SDK, the surfsense-plugins command\ncd plugins/bundles/core/manifest && uv sync\ncd plugins/bundles/core/sdk && uv sync\ncd plugins/bundles/core/sdk && uv run pyright\ncd plugins/bundles/core/cli && uv sync\n\n# compose (dev and self-host, not production)\ndocker compose -f docker/docker-compose.yml\n\n# hooks\npre-commit run --all-files\n```\n\n## Testing\n\n| Area | Command |\n|------|---------|\n| Backend unit | `cd surfsense_backend && uv run pytest -m unit` |\n| Backend integration | `cd surfsense_backend && uv run pytest -m integration` |\n| Web unit | `cd surfsense_web && pnpm test:unit` |\n| Web e2e | `cd surfsense_web && pnpm test:e2e` |\n| MCP | `cd surfsense_mcp && uv run pytest` |\n| Plugin host | `cd plugins/remote/host && uv run pytest` |\n| Bundles: manifest rules | `cd plugins/bundles/core/manifest && uv run pytest -m unit` |\n| Bundles: SDK | `cd plugins/bundles/core/sdk && uv run pytest -m unit` |\n| Bundles: SDK against the app | `cd plugins/bundles/core/sdk && uv run pytest -m contract` (starts the backend; `uv sync` it first) |\n| Bundles: CLI | `cd plugins/bundles/core/cli && uv run pytest` (starts the backend; `uv sync` it first) |\n| Desktop | `cd surfsense_local/electron && pnpm test` |\nCI: `.github/workflows/`. New behavior: one failing test, then the minimum code to pass it. Use the `tdd` skill. Tests hit public seams, not internals.\n\n## Pull requests\n\nFollow [CONTRIBUTING.md](CONTRIBUTING.md). The parts agents miss:\n\n- Open PRs against `dev`. `gh pr create` targets the default branch, `main`, unless you pass `--base dev`.\n- `gh pr create --body` skips the PR template. Keep its headings: What, Why, `Fixes #`, How to test.\n- Commit messages and PR titles are Conventional Commits, `type(scope): summary`. The commitizen hook runs only where it is installed; CI does not run it.\n- A new feature starts as a proposal PR in `docs/proposals/`, not as code.\n- `surfsense_backend/app/proprietary/` and `plugins/remote/proprietary/` are Business Source License 1.1 and changed only by maintainers: ask one before changing them. A change to `docs/contracts/` needs the owners of both sides.\n\n## Skills\n\nCanonical dir: `.agents/skills/`. `.claude/skills` is a symlink to it.\n\n| Skill | When |\n|-------|------|\n| `tdd` | New behavior or a bug fix with a testable seam |\n| `codebase-design` | Module shape, seam, depth — `tdd` depends on this vocabulary |\n| `fastapi` | FastAPI / Pydantic work. Symlink into the installed wheel; repair the **same** root link after a FastAPI or Python bump. Do not keep `surfsense_backend/.agents/`. |\n| `frontend-workflow` | Frontend work in `surfsense_web` and `surfsense_local/frontend`: React/Next performance, color tokens, UI polish, motion. Bundles `react-performance/`, `color/`, `polish/`, `motion/`, and `base-ui.md` for Base UI in `surfsense_local/frontend`; routes out to `shadcn`. |\n| `shadcn` | UI components in a tree with `components.json`. Standalone — it inspects the project live and grants its own CLI, which only works as a discovered skill. Load it after `frontend-workflow`, not instead of it. |\n| `translate` | Interface strings in `surfsense_local`: adding a message in code (`en.json` is generated from it), moving hard-coded text into messages, translating Japanese and German. Holds the key shape, tone and glossary. |\n\nDo not install skill catalogs. Do not add `CONTEXT.md` or a second rules tree.\n\n`frontend-workflow` bundles what were separate skills under `react-performance/`,\n`color/`, `polish/`, and `motion/`. Those files keep their old frontmatter, which\nis inert — they are reference files, not discovered skills. Skill discovery is one\nlevel deep, so do not nest a new skill inside another skill's folder.\n\nBundle a skill only if it is static markdown that overlaps the others. Anything\nwith frontmatter that does work — `allowed-tools`, `` !`command` `` substitution —\nmust stay top-level, because that frontmatter is inert in a bundled file.\n\n`shadcn/SKILL.md` carries one local addition: a note routing to `frontend-workflow`\nfirst. It is the only edit to that vendored file — restore it after any shadcn\nre-sync, or component work bypasses the color palette and polish rules.\n\n`skills-lock.json` lists `vercel-react-best-practices`, which now lives at\n`frontend-workflow/react-performance/`. `shadcn` is back at its original path and\nits lock entry is valid.\n\n## Boundaries\n\n- Do not carve hosted code out of backend/web until the purge on 18 Oct 2026. The export window and the purge script run on that code until then.\n- Do not drop SearxNG, sandbox, OpenSandbox, or zero-cache from compose until a new compose is defined.\n- Edit the root `README.md` directly. The draft at `plans/community-local/seo/drafts/README.md` shipped on 18 Sep 2026 and is kept only for history. Anything added to the README replaces something — its length was measured against the eight biggest repos in this category. Make the same change in every `README.<locale>.md`, section for section; [`06-repo-readme.md`](plans/community-local/seo/06-repo-readme.md#the-readme-since-9-oct-2026) has the rules, where each format-table cell is checked, and how to replace the demo video.\n- Do not commit, push or open a PR unless asked.\n\n## Security\n\n- Never commit `.env` or secrets.\n- Do not put credentials in diffs, logs, or sample payloads.\n","CLAUDE.md":"# AGENTS.md\n\nNearest `AGENTS.md` wins. Edit this file, not `CLAUDE.md` (`CLAUDE.md` is a symlink).\n\n## Overview\n\nDesktop app plus scraper API. Five trees:\n\n| Tree | Role |\n|------|------|\n| `surfsense_backend` | FastAPI API |\n| `surfsense_web` | Next.js hosted UI |\n| `surfsense_local` | Electron desktop |\n| `surfsense_mcp` | MCP server over the REST API |\n| `plugins` | SurfSense's own plugin servers ([plugin host](docs/architecture/plugin-host.md)) and the [registry](docs/architecture/plugin-registry.md). `bundles/` holds the earlier, local design's SDK and tooling, deferred |\n\nThe hosted service has been export-only since the 2.0.0 launch on 18 Sep 2026, and its user data is purged on 18 Oct 2026 ([sunset](docs/architecture/sunset.md)). Product direction is local + API.\n\n## Code organization\n\nApplies to **every new file**. Existing code is not a template and not a cleanup ticket.\n\n**Must**\n\n- Organize by feature (vertical slice), not by technical layer.\n- One responsibility per file. One responsibility per folder.\n- If a responsibility grows sub-responsibilities, promote it to a folder. Each sub-responsibility is its own file.\n- Names state what and why, not how.\n- Comments and docstrings state intent only. Do not restate the code.\n- Keep them short. A line or two. Write only what the code cannot say: a constraint, a rejected alternative, a number that justifies a threshold.\n\n**Must not**\n\n- Do not write essays in docstrings. If it explains how you arrived at the code rather than what the code must honour, delete it.\n- Do not put new work in a nearby file because it is convenient. New responsibility, new file.\n- Do not add catch-all folders (`utils`, `helpers`, `common`, `misc`, `shared`) unless that name is the product concept.\n- Do not layer-split new work (`controllers/`, `services/`, `models/` as the primary tree).\n- Do not rewrite existing code to this layout unless the task is that rewrite.\n\nThe tree is inconsistent. New work follows this. Old work stays until a task explicitly owns it.\n\n## Docs\n\n[`docs/`](docs/README.md) is the engineering map. `architecture/` says what is true now, one doc per feature; `adr/` says why; `proposals/` holds designs not built yet; `contracts/` holds the frozen interfaces between trees. Task status lives in GitHub issues; docs carry only a proposal's `status` and each architecture doc's Known gaps. `plans/` is business and ops material, not specs.\n\n- Before changing a feature, read its doc in `docs/architecture/` and the ADRs it links.\n- If a change alters behaviour a doc describes, update the doc in the same change. Fixing a Known gap deletes its line.\n- Run `python scripts/check_docs.py` after editing anything under `docs/` or `plans/`.\n\n## Commands\n\n```bash\n# backend\ncd surfsense_backend && uv sync\ncd surfsense_backend && uv run ruff check .\ncd surfsense_backend && uv run pytest -m unit\n\n# web\ncd surfsense_web && pnpm install\ncd surfsense_web && pnpm dev\ncd surfsense_web && pnpm format\n\n# desktop\ncd surfsense_local/electron && pnpm dev\n\n# MCP\ncd surfsense_mcp && uv sync\n\n# plugin host: SurfSense's own plugins, from plugins/remote/\ncd plugins/remote/host && uv sync\ncd plugins/remote && uv run --project host python -m host\n\n# bundles (deferred): the manifest rules, the SDK, the surfsense-plugins command\ncd plugins/bundles/core/manifest && uv sync\ncd plugins/bundles/core/sdk && uv sync\ncd plugins/bundles/core/sdk && uv run pyright\ncd plugins/bundles/core/cli && uv sync\n\n# compose (dev and self-host, not production)\ndocker compose -f docker/docker-compose.yml\n\n# hooks\npre-commit run --all-files\n```\n\n## Testing\n\n| Area | Command |\n|------|---------|\n| Backend unit | `cd surfsense_backend && uv run pytest -m unit` |\n| Backend integration | `cd surfsense_backend && uv run pytest -m integration` |\n| Web unit | `cd surfsense_web && pnpm test:unit` |\n| Web e2e | `cd surfsense_web && pnpm test:e2e` |\n| MCP | `cd surfsense_mcp && uv run pytest` |\n| Plugin host | `cd plugins/remote/host && uv run pytest` |\n| Bundles: manifest rules | `cd plugins/bundles/core/manifest && uv run pytest -m unit` |\n| Bundles: SDK | `cd plugins/bundles/core/sdk && uv run pytest -m unit` |\n| Bundles: SDK against the app | `cd plugins/bundles/core/sdk && uv run pytest -m contract` (starts the backend; `uv sync` it first) |\n| Bundles: CLI | `cd plugins/bundles/core/cli && uv run pytest` (starts the backend; `uv sync` it first) |\n| Desktop | `cd surfsense_local/electron && pnpm test` |\nCI: `.github/workflows/`. New behavior: one failing test, then the minimum code to pass it. Use the `tdd` skill. Tests hit public seams, not internals.\n\n## Pull requests\n\nFollow [CONTRIBUTING.md](CONTRIBUTING.md). The parts agents miss:\n\n- Open PRs against `dev`. `gh pr create` targets the default branch, `main`, unless you pass `--base dev`.\n- `gh pr create --body` skips the PR template. Keep its headings: What, Why, `Fixes #`, How to test.\n- Commit messages and PR titles are Conventional Commits, `type(scope): summary`. The commitizen hook runs only where it is installed; CI does not run it.\n- A new feature starts as a proposal PR in `docs/proposals/`, not as code.\n- `surfsense_backend/app/proprietary/` and `plugins/remote/proprietary/` are Business Source License 1.1 and changed only by maintainers: ask one before changing them. A change to `docs/contracts/` needs the owners of both sides.\n\n## Skills\n\nCanonical dir: `.agents/skills/`. `.claude/skills` is a symlink to it.\n\n| Skill | When |\n|-------|------|\n| `tdd` | New behavior or a bug fix with a testable seam |\n| `codebase-design` | Module shape, seam, depth — `tdd` depends on this vocabulary |\n| `fastapi` | FastAPI / Pydantic work. Symlink into the installed wheel; repair the **same** root link after a FastAPI or Python bump. Do not keep `surfsense_backend/.agents/`. |\n| `frontend-workflow` | Frontend work in `surfsense_web` and `surfsense_local/frontend`: React/Next performance, color tokens, UI polish, motion. Bundles `react-performance/`, `color/`, `polish/`, `motion/`, and `base-ui.md` for Base UI in `surfsense_local/frontend`; routes out to `shadcn`. |\n| `shadcn` | UI components in a tree with `components.json`. Standalone — it inspects the project live and grants its own CLI, which only works as a discovered skill. Load it after `frontend-workflow`, not instead of it. |\n| `translate` | Interface strings in `surfsense_local`: adding a message in code (`en.json` is generated from it), moving hard-coded text into messages, translating Japanese and German. Holds the key shape, tone and glossary. |\n\nDo not install skill catalogs. Do not add `CONTEXT.md` or a second rules tree.\n\n`frontend-workflow` bundles what were separate skills under `react-performance/`,\n`color/`, `polish/`, and `motion/`. Those files keep their old frontmatter, which\nis inert — they are reference files, not discovered skills. Skill discovery is one\nlevel deep, so do not nest a new skill inside another skill's folder.\n\nBundle a skill only if it is static markdown that overlaps the others. Anything\nwith frontmatter that does work — `allowed-tools`, `` !`command` `` substitution —\nmust stay top-level, because that frontmatter is inert in a bundled file.\n\n`shadcn/SKILL.md` carries one local addition: a note routing to `frontend-workflow`\nfirst. It is the only edit to that vendored file — restore it after any shadcn\nre-sync, or component work bypasses the color palette and polish rules.\n\n`skills-lock.json` lists `vercel-react-best-practices`, which now lives at\n`frontend-workflow/react-performance/`. `shadcn` is back at its original path and\nits lock entry is valid.\n\n## Boundaries\n\n- Do not carve hosted code out of backend/web until the purge on 18 Oct 2026. The export window and the purge script run on that code until then.\n- Do not drop SearxNG, sandbox, OpenSandbox, or zero-cache from compose until a new compose is defined.\n- Edit the root `README.md` directly. The draft at `plans/community-local/seo/drafts/README.md` shipped on 18 Sep 2026 and is kept only for history. Anything added to the README replaces something — its length was measured against the eight biggest repos in this category. Make the same change in every `README.<locale>.md`, section for section; [`06-repo-readme.md`](plans/community-local/seo/06-repo-readme.md#the-readme-since-9-oct-2026) has the rules, where each format-table cell is checked, and how to replace the demo video.\n- Do not commit, push or open a PR unless asked.\n\n## Security\n\n- Never commit `.env` or secrets.\n- Do not put credentials in diffs, logs, or sample payloads.\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/plugin.json)"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md\n\nNearest `AGENTS.md` wins. Edit this file, not `CLAUDE.md` (`CLAUDE.md` is a symlink).\n\n## Overview\n\nDesktop app plus scraper API. Five trees:\n\n| Tree | Role |\n|------|------|\n| `surfsense_backend` | FastAPI API |\n| `surfsense_web` | Next.js hosted UI |\n| `surfsense_local` | Electron desktop |\n| `surfsense_mcp` | MCP server over the REST API |\n| `plugins` | SurfSense's own plugin servers ([plugin host](docs/architecture/plugin-host.md)) and the [registry](docs/architecture/plugin-registry.md). `bundles/` holds the earlier, local design's SDK and tooling, deferred |\n\nThe hosted service has been export-only since the 2.0.0 launch on 18 Sep 2026, and its user data is purged on 18 Oct 2026 ([sunset](docs/architecture/sunset.md)). Product direction is local + API.\n\n## Code organization\n\nApplies to **every new file**. Existing code is not a template and not a cleanup ticket.\n\n**Must**\n\n- Organize by feature (vertical slice), not by technical layer.\n- One responsibility per file. One responsibility per folder.\n- If a responsibility grows sub-responsibilities, promote it to a folder. Each sub-responsibility is its own file.\n- Names state what and why, not how.\n- Comments and docstrings state intent only. Do not restate the code.\n- Keep them short. A line or two. Write only what the code cannot say: a constraint, a rejected alternative, a number that justifies a threshold.\n\n**Must not**\n\n- Do not write essays in docstrings. If it explains how you arrived at the code rather than what the code must honour, delete it.\n- Do not put new work in a nearby file because it is convenient. New responsibility, new file.\n- Do not add catch-all folders (`utils`, `helpers`, `common`, `misc`, `shared`) unless that name is the product concept.\n- Do not layer-split new work (`controllers/`, `services/`, `models/` as the primary tree).\n- Do not rewrite existing code to this layout unless the task is that rewrite.\n\nThe tree is inconsistent. New work follows this. Old work stays until a task explicitly owns it.\n\n## Docs\n\n[`docs/`](docs/README.md) is the engineering map. `architecture/` says what is true now, one doc per feature; `adr/` says why; `proposals/` holds designs not built yet; `contracts/` holds the frozen interfaces between trees. Task status lives in GitHub issues; docs carry only a proposal's `status` and each architecture doc's Known gaps. `plans/` is business and ops material, not specs.\n\n- Before changing a feature, read its doc in `docs/architecture/` and the ADRs it links.\n- If a change alters behaviour a doc describes, update the doc in the same change. Fixing a Known gap deletes its line.\n- Run `python scripts/check_docs.py` after editing anything under `docs/` or `plans/`.\n\n## Commands\n\n```bash\n# backend\ncd surfsense_backend && uv sync\ncd surfsense_backend && uv run ruff check .\ncd surfsense_backend && uv run pytest -m unit\n\n# web\ncd surfsense_web && pnpm install\ncd surfsense_web && pnpm dev\ncd surfsense_web && pnpm format\n\n# desktop\ncd surfsense_local/electron && pnpm dev\n\n# MCP\ncd surfsense_mcp && uv sync\n\n# plugin host: SurfSense's own plugins, from plugins/remote/\ncd plugins/remote/host && uv sync\ncd plugins/remote && uv run --project host python -m host\n\n# bundles (deferred): the manifest rules, the SDK, the surfsense-plugins command\ncd plugins/bundles/core/manifest && uv sync\ncd plugins/bundles/core/sdk && uv sync\ncd plugins/bundles/core/sdk && uv run pyright\ncd plugins/bundles/core/cli && uv sync\n\n# compose (dev and self-host, not production)\ndocker compose -f docker/docker-compose.yml\n\n# hooks\npre-commit run --all-files\n```\n\n## Testing\n\n| Area | Command |\n|------|---------|\n| Backend unit | `cd surfsense_backend && uv run pytest -m unit` |\n| Backend integration | `cd surfsense_backend && uv run pytest -m integration` |\n| Web unit | `cd surfsense_web && pnpm test:unit` |\n| Web e2e | `cd surfsense_web && pnpm test:e2e` |\n| MCP | `cd surfsense_mcp && uv run pytest` |\n| Plugin host | `cd plugins/remote/host && uv run pytest` |\n| Bundles: manifest rules | `cd plugins/bundles/core/manifest && uv run pytest -m unit` |\n| Bundles: SDK | `cd plugins/bundles/core/sdk && uv run pytest -m unit` |\n| Bundles: SDK against the app | `cd plugins/bundles/core/sdk && uv run pytest -m contract` (starts the backend; `uv sync` it first) |\n| Bundles: CLI | `cd plugins/bundles/core/cli && uv run pytest` (starts the backend; `uv sync` it first) |\n| Desktop | `cd surfsense_local/electron && pnpm test` |\nCI: `.github/workflows/`. New behavior: one failing test, then the minimum code to pass it. Use the `tdd` skill. Tests hit public seams, not internals.\n\n## Pull requests\n\nFollow [CONTRIBUTING.md](CONTRIBUTING.md). The parts agents miss:\n\n- Open PRs against `dev`. `gh pr create` targets the default branch, `main`, unless you pass `--base dev`.\n- `gh pr create --body` skips the PR template. Keep its headings: What, Why, `Fixes #`, How to test.\n- Commit messages and PR titles are Conventional Commits, `type(scope): summary`. The commitizen hook runs only where it is installed; CI does not run it.\n- A new feature starts as a proposal PR in `docs/proposals/`, not as code.\n- `surfsense_backend/app/proprietary/` and `plugins/remote/proprietary/` are Business Source License 1.1 and changed only by maintainers: ask one before changing them. A change to `docs/contracts/` needs the owners of both sides.\n\n## Skills\n\nCanonical dir: `.agents/skills/`. `.claude/skills` is a symlink to it.\n\n| Skill | When |\n|-------|------|\n| `tdd` | New behavior or a bug fix with a testable seam |\n| `codebase-design` | Module shape, seam, depth — `tdd` depends on this vocabulary |\n| `fastapi` | FastAPI / Pydantic work. Symlink into the installed wheel; repair the **same** root link after a FastAPI or Python bump. Do not keep `surfsense_backend/.agents/`. |\n| `frontend-workflow` | Frontend work in `surfsense_web` and `surfsense_local/frontend`: React/Next performance, color tokens, UI polish, motion. Bundles `react-performance/`, `color/`, `polish/`, `motion/`, and `base-ui.md` for Base UI in `surfsense_local/frontend`; routes out to `shadcn`. |\n| `shadcn` | UI components in a tree with `components.json`. Standalone — it inspects the project live and grants its own CLI, which only works as a discovered skill. Load it after `frontend-workflow`, not instead of it. |\n| `translate` | Interface strings in `surfsense_local`: adding a message in code (`en.json` is generated from it), moving hard-coded text into messages, translating Japanese and German. Holds the key shape, tone and glossary. |\n\nDo not install skill catalogs. Do not add `CONTEXT.md` or a second rules tree.\n\n`frontend-workflow` bundles what were separate skills under `react-performance/`,\n`color/`, `polish/`, and `motion/`. Those files keep their old frontmatter, which\nis inert — they are reference files, not discovered skills. Skill discovery is one\nlevel deep, so do not nest a new skill inside another skill's folder.\n\nBundle a skill only if it is static markdown that overlaps the others. Anything\nwith frontmatter that does work — `allowed-tools`, `` !`command` `` substitution —\nmust stay top-level, because that frontmatter is inert in a bundled file.\n\n`shadcn/SKILL.md` carries one local addition: a note routing to `frontend-workflow`\nfirst. It is the only edit to that vendored file — restore it after any shadcn\nre-sync, or component work bypasses the color palette and polish rules.\n\n`skills-lock.json` lists `vercel-react-best-practices`, which now lives at\n`frontend-workflow/react-performance/`. `shadcn` is back at its original path and\nits lock entry is valid.\n\n## Boundaries\n\n- Do not carve hosted code out of backend/web until the purge on 18 Oct 2026. The export window and the purge script run on that code until then.\n- Do not drop SearxNG, sandbox, OpenSandbox, or zero-cache from compose until a new compose is defined.\n- Edit the root `README.md` directly. The draft at `plans/community-local/seo/drafts/README.md` shipped on 18 Sep 2026 and is kept only for history. Anything added to the README replaces something — its length was measured against the eight biggest repos in this category. Make the same change in every `README.<locale>.md`, section for section; [`06-repo-readme.md`](plans/community-local/seo/06-repo-readme.md#the-readme-since-9-oct-2026) has the rules, where each format-table cell is checked, and how to replace the demo video.\n- Do not commit, push or open a PR unless asked.\n\n## Security\n\n- Never commit `.env` or secrets.\n- Do not put credentials in diffs, logs, or sample payloads.\n","isInternal":false,"tokens":2199,"sizeBytes":8588},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# AGENTS.md\n\nNearest `AGENTS.md` wins. Edit this file, not `CLAUDE.md` (`CLAUDE.md` is a symlink).\n\n## Overview\n\nDesktop app plus scraper API. Five trees:\n\n| Tree | Role |\n|------|------|\n| `surfsense_backend` | FastAPI API |\n| `surfsense_web` | Next.js hosted UI |\n| `surfsense_local` | Electron desktop |\n| `surfsense_mcp` | MCP server over the REST API |\n| `plugins` | SurfSense's own plugin servers ([plugin host](docs/architecture/plugin-host.md)) and the [registry](docs/architecture/plugin-registry.md). `bundles/` holds the earlier, local design's SDK and tooling, deferred |\n\nThe hosted service has been export-only since the 2.0.0 launch on 18 Sep 2026, and its user data is purged on 18 Oct 2026 ([sunset](docs/architecture/sunset.md)). Product direction is local + API.\n\n## Code organization\n\nApplies to **every new file**. Existing code is not a template and not a cleanup ticket.\n\n**Must**\n\n- Organize by feature (vertical slice), not by technical layer.\n- One responsibility per file. One responsibility per folder.\n- If a responsibility grows sub-responsibilities, promote it to a folder. Each sub-responsibility is its own file.\n- Names state what and why, not how.\n- Comments and docstrings state intent only. Do not restate the code.\n- Keep them short. A line or two. Write only what the code cannot say: a constraint, a rejected alternative, a number that justifies a threshold.\n\n**Must not**\n\n- Do not write essays in docstrings. If it explains how you arrived at the code rather than what the code must honour, delete it.\n- Do not put new work in a nearby file because it is convenient. New responsibility, new file.\n- Do not add catch-all folders (`utils`, `helpers`, `common`, `misc`, `shared`) unless that name is the product concept.\n- Do not layer-split new work (`controllers/`, `services/`, `models/` as the primary tree).\n- Do not rewrite existing code to this layout unless the task is that rewrite.\n\nThe tree is inconsistent. New work follows this. Old work stays until a task explicitly owns it.\n\n## Docs\n\n[`docs/`](docs/README.md) is the engineering map. `architecture/` says what is true now, one doc per feature; `adr/` says why; `proposals/` holds designs not built yet; `contracts/` holds the frozen interfaces between trees. Task status lives in GitHub issues; docs carry only a proposal's `status` and each architecture doc's Known gaps. `plans/` is business and ops material, not specs.\n\n- Before changing a feature, read its doc in `docs/architecture/` and the ADRs it links.\n- If a change alters behaviour a doc describes, update the doc in the same change. Fixing a Known gap deletes its line.\n- Run `python scripts/check_docs.py` after editing anything under `docs/` or `plans/`.\n\n## Commands\n\n```bash\n# backend\ncd surfsense_backend && uv sync\ncd surfsense_backend && uv run ruff check .\ncd surfsense_backend && uv run pytest -m unit\n\n# web\ncd surfsense_web && pnpm install\ncd surfsense_web && pnpm dev\ncd surfsense_web && pnpm format\n\n# desktop\ncd surfsense_local/electron && pnpm dev\n\n# MCP\ncd surfsense_mcp && uv sync\n\n# plugin host: SurfSense's own plugins, from plugins/remote/\ncd plugins/remote/host && uv sync\ncd plugins/remote && uv run --project host python -m host\n\n# bundles (deferred): the manifest rules, the SDK, the surfsense-plugins command\ncd plugins/bundles/core/manifest && uv sync\ncd plugins/bundles/core/sdk && uv sync\ncd plugins/bundles/core/sdk && uv run pyright\ncd plugins/bundles/core/cli && uv sync\n\n# compose (dev and self-host, not production)\ndocker compose -f docker/docker-compose.yml\n\n# hooks\npre-commit run --all-files\n```\n\n## Testing\n\n| Area | Command |\n|------|---------|\n| Backend unit | `cd surfsense_backend && uv run pytest -m unit` |\n| Backend integration | `cd surfsense_backend && uv run pytest -m integration` |\n| Web unit | `cd surfsense_web && pnpm test:unit` |\n| Web e2e | `cd surfsense_web && pnpm test:e2e` |\n| MCP | `cd surfsense_mcp && uv run pytest` |\n| Plugin host | `cd plugins/remote/host && uv run pytest` |\n| Bundles: manifest rules | `cd plugins/bundles/core/manifest && uv run pytest -m unit` |\n| Bundles: SDK | `cd plugins/bundles/core/sdk && uv run pytest -m unit` |\n| Bundles: SDK against the app | `cd plugins/bundles/core/sdk && uv run pytest -m contract` (starts the backend; `uv sync` it first) |\n| Bundles: CLI | `cd plugins/bundles/core/cli && uv run pytest` (starts the backend; `uv sync` it first) |\n| Desktop | `cd surfsense_local/electron && pnpm test` |\nCI: `.github/workflows/`. New behavior: one failing test, then the minimum code to pass it. Use the `tdd` skill. Tests hit public seams, not internals.\n\n## Pull requests\n\nFollow [CONTRIBUTING.md](CONTRIBUTING.md). The parts agents miss:\n\n- Open PRs against `dev`. `gh pr create` targets the default branch, `main`, unless you pass `--base dev`.\n- `gh pr create --body` skips the PR template. Keep its headings: What, Why, `Fixes #`, How to test.\n- Commit messages and PR titles are Conventional Commits, `type(scope): summary`. The commitizen hook runs only where it is installed; CI does not run it.\n- A new feature starts as a proposal PR in `docs/proposals/`, not as code.\n- `surfsense_backend/app/proprietary/` and `plugins/remote/proprietary/` are Business Source License 1.1 and changed only by maintainers: ask one before changing them. A change to `docs/contracts/` needs the owners of both sides.\n\n## Skills\n\nCanonical dir: `.agents/skills/`. `.claude/skills` is a symlink to it.\n\n| Skill | When |\n|-------|------|\n| `tdd` | New behavior or a bug fix with a testable seam |\n| `codebase-design` | Module shape, seam, depth — `tdd` depends on this vocabulary |\n| `fastapi` | FastAPI / Pydantic work. Symlink into the installed wheel; repair the **same** root link after a FastAPI or Python bump. Do not keep `surfsense_backend/.agents/`. |\n| `frontend-workflow` | Frontend work in `surfsense_web` and `surfsense_local/frontend`: React/Next performance, color tokens, UI polish, motion. Bundles `react-performance/`, `color/`, `polish/`, `motion/`, and `base-ui.md` for Base UI in `surfsense_local/frontend`; routes out to `shadcn`. |\n| `shadcn` | UI components in a tree with `components.json`. Standalone — it inspects the project live and grants its own CLI, which only works as a discovered skill. Load it after `frontend-workflow`, not instead of it. |\n| `translate` | Interface strings in `surfsense_local`: adding a message in code (`en.json` is generated from it), moving hard-coded text into messages, translating Japanese and German. Holds the key shape, tone and glossary. |\n\nDo not install skill catalogs. Do not add `CONTEXT.md` or a second rules tree.\n\n`frontend-workflow` bundles what were separate skills under `react-performance/`,\n`color/`, `polish/`, and `motion/`. Those files keep their old frontmatter, which\nis inert — they are reference files, not discovered skills. Skill discovery is one\nlevel deep, so do not nest a new skill inside another skill's folder.\n\nBundle a skill only if it is static markdown that overlaps the others. Anything\nwith frontmatter that does work — `allowed-tools`, `` !`command` `` substitution —\nmust stay top-level, because that frontmatter is inert in a bundled file.\n\n`shadcn/SKILL.md` carries one local addition: a note routing to `frontend-workflow`\nfirst. It is the only edit to that vendored file — restore it after any shadcn\nre-sync, or component work bypasses the color palette and polish rules.\n\n`skills-lock.json` lists `vercel-react-best-practices`, which now lives at\n`frontend-workflow/react-performance/`. `shadcn` is back at its original path and\nits lock entry is valid.\n\n## Boundaries\n\n- Do not carve hosted code out of backend/web until the purge on 18 Oct 2026. The export window and the purge script run on that code until then.\n- Do not drop SearxNG, sandbox, OpenSandbox, or zero-cache from compose until a new compose is defined.\n- Edit the root `README.md` directly. The draft at `plans/community-local/seo/drafts/README.md` shipped on 18 Sep 2026 and is kept only for history. Anything added to the README replaces something — its length was measured against the eight biggest repos in this category. Make the same change in every `README.<locale>.md`, section for section; [`06-repo-readme.md`](plans/community-local/seo/06-repo-readme.md#the-readme-since-9-oct-2026) has the rules, where each format-table cell is checked, and how to replace the demo video.\n- Do not commit, push or open a PR unless asked.\n\n## Security\n\n- Never commit `.env` or secrets.\n- Do not put credentials in diffs, logs, or sample payloads.\n","isInternal":false,"tokens":2199,"sizeBytes":8588},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/marketplace.json)","tokens":300,"sizeBytes":198},{"name":"plugin.json","path":".claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/plugin.json","title":"claude-plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/plugin.json)","tokens":300,"sizeBytes":184},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.cursor/mcp.json)","tokens":300,"sizeBytes":177}],"systemPromptSnippet":"<yakaai_skills repo=\"MODSetter/SurfSense\">\n<!-- File: AGENTS.md (Tokens: ~2199 | Category: root-instruction) -->\n# AGENTS.md\n\nNearest `AGENTS.md` wins. Edit this file, not `CLAUDE.md` (`CLAUDE.md` is a symlink).\n\n## Overview\n\nDesktop app plus scraper API. Five trees:\n\n| Tree | Role |\n|------|------|\n| `surfsense_backend` | FastAPI API |\n| `surfsense_web` | Next.js hosted UI |\n| `surfsense_local` | Electron desktop |\n| `surfsense_mcp` | MCP server over the REST API |\n| `plugins` | SurfSense's own plugin servers ([plugin host](docs/architecture/plugin-host.md)) and the [registry](docs/architecture/plugin-registry.md). `bundles/` holds the earlier, local design's SDK and tooling, deferred |\n\nThe hosted service has been export-only since the 2.0.0 launch on 18 Sep 2026, and its user data is purged on 18 Oct 2026 ([sunset](docs/architecture/sunset.md)). Product direction is local + API.\n\n## Code organization\n\nApplies to **every new file**. Existing code is not a template and not a cleanup ticket.\n\n**Must**\n\n- Organize by feature (vertical slice), not by technical layer.\n- One responsibility per file. One responsibility per folder.\n- If a responsibility grows sub-responsibilities, promote it to a folder. Each sub-responsibility is its own file.\n- Names state what and why, not how.\n- Comments and docstrings state intent only. Do not restate the code.\n- Keep them short. A line or two. Write only what the code cannot say: a constraint, a rejected alternative, a number that justifies a threshold.\n\n**Must not**\n\n- Do not write essays in docstrings. If it explains how you arrived at the code rather than what the code must honour, delete it.\n- Do not put new work in a nearby file because it is convenient. New responsibility, new file.\n- Do not add catch-all folders (`utils`, `helpers`, `common`, `misc`, `shared`) unless that name is the product concept.\n- Do not layer-split new work (`controllers/`, `services/`, `models/` as the primary tree).\n- Do not rewrite existing code to this layout unless the task is that rewrite.\n\nThe tree is inconsistent. New work follows this. Old work stays until a task explicitly owns it.\n\n## Docs\n\n[`docs/`](docs/README.md) is the engineering map. `architecture/` says what is true now, one doc per feature; `adr/` says why; `proposals/` holds designs not built yet; `contracts/` holds the frozen interfaces between trees. Task status lives in GitHub issues; docs carry only a proposal's `status` and each architecture doc's Known gaps. `plans/` is business and ops material, not specs.\n\n- Before changing a feature, read its doc in `docs/architecture/` and the ADRs it links.\n- If a change alters behaviour a doc describes, update the doc in the same change. Fixing a Known gap deletes its line.\n- Run `python scripts/check_docs.py` after editing anything under `docs/` or `plans/`.\n\n## Commands\n\n```bash\n# backend\ncd surfsense_backend && uv sync\ncd surfsense_backend && uv run ruff check .\ncd surfsense_backend && uv run pytest -m unit\n\n# web\ncd surfsense_web && pnpm install\ncd surfsense_web && pnpm dev\ncd surfsense_web && pnpm format\n\n# desktop\ncd surfsense_local/electron && pnpm dev\n\n# MCP\ncd surfsense_mcp && uv sync\n\n# plugin host: SurfSense's own plugins, from plugins/remote/\ncd plugins/remote/host && uv sync\ncd plugins/remote && uv run --project host python -m host\n\n# bundles (deferred): the manifest rules, the SDK, the surfsense-plugins command\ncd plugins/bundles/core/manifest && uv sync\ncd plugins/bundles/core/sdk && uv sync\ncd plugins/bundles/core/sdk && uv run pyright\ncd plugins/bundles/core/cli && uv sync\n\n# compose (dev and self-host, not production)\ndocker compose -f docker/docker-compose.yml\n\n# hooks\npre-commit run --all-files\n```\n\n## Testing\n\n| Area | Command |\n|------|---------|\n| Backend unit | `cd surfsense_backend && uv run pytest -m unit` |\n| Backend integration | `cd surfsense_backend && uv run pytest -m integration` |\n| Web unit | `cd surfsense_web && pnpm test:unit` |\n| Web e2e | `cd surfsense_web && pnpm test:e2e` |\n| MCP | `cd surfsense_mcp && uv run pytest` |\n| Plugin host | `cd plugins/remote/host && uv run pytest` |\n| Bundles: manifest rules | `cd plugins/bundles/core/manifest && uv run pytest -m unit` |\n| Bundles: SDK | `cd plugins/bundles/core/sdk && uv run pytest -m unit` |\n| Bundles: SDK against the app | `cd plugins/bundles/core/sdk && uv run pytest -m contract` (starts the backend; `uv sync` it first) |\n| Bundles: CLI | `cd plugins/bundles/core/cli && uv run pytest` (starts the backend; `uv sync` it first) |\n| Desktop | `cd surfsense_local/electron && pnpm test` |\nCI: `.github/workflows/`. New behavior: one failing test, then the minimum code to pass it. Use the `tdd` skill. Tests hit public seams, not internals.\n\n## Pull requests\n\nFollow [CONTRIBUTING.md](CONTRIBUTING.md). The parts agents miss:\n\n- Open PRs against `dev`. `gh pr create` targets the default branch, `main`, unless you pass `--base dev`.\n- `gh pr create --body` skips the PR template. Keep its headings: What, Why, `Fixes #`, How to test.\n- Commit messages and PR titles are Conventional Commits, `type(scope): summary`. The commitizen hook runs only where it is installed; CI does not run it.\n- A new feature starts as a proposal PR in `docs/proposals/`, not as code.\n- `surfsense_backend/app/proprietary/` and `plugins/remote/proprietary/` are Business Source License 1.1 and changed only by maintainers: ask one before changing them. A change to `docs/contracts/` needs the owners of both sides.\n\n## Skills\n\nCanonical dir: `.agents/skills/`. `.claude/skills` is a symlink to it.\n\n| Skill | When |\n|-------|------|\n| `tdd` | New behavior or a bug fix with a testable seam |\n| `codebase-design` | Module shape, seam, depth — `tdd` depends on this vocabulary |\n| `fastapi` | FastAPI / Pydantic work. Symlink into the installed wheel; repair the **same** root link after a FastAPI or Python bump. Do not keep `surfsense_backend/.agents/`. |\n| `frontend-workflow` | Frontend work in `surfsense_web` and `surfsense_local/frontend`: React/Next performance, color tokens, UI polish, motion. Bundles `react-performance/`, `color/`, `polish/`, `motion/`, and `base-ui.md` for Base UI in `surfsense_local/frontend`; routes out to `shadcn`. |\n| `shadcn` | UI components in a tree with `components.json`. Standalone — it inspects the project live and grants its own CLI, which only works as a discovered skill. Load it after `frontend-workflow`, not instead of it. |\n| `translate` | Interface strings in `surfsense_local`: adding a message in code (`en.json` is generated from it), moving hard-coded text into messages, translating Japanese and German. Holds the key shape, tone and glossary. |\n\nDo not install skill catalogs. Do not add `CONTEXT.md` or a second rules tree.\n\n`frontend-workflow` bundles what were separate skills under `react-performance/`,\n`color/`, `polish/`, and `motion/`. Those files keep their old frontmatter, which\nis inert — they are reference files, not discovered skills. Skill discovery is one\nlevel deep, so do not nest a new skill inside another skill's folder.\n\nBundle a skill only if it is static markdown that overlaps the others. Anything\nwith frontmatter that does work — `allowed-tools`, `` !`command` `` substitution —\nmust stay top-level, because that frontmatter is inert in a bundled file.\n\n`shadcn/SKILL.md` carries one local addition: a note routing to `frontend-workflow`\nfirst. It is the only edit to that vendored file — restore it after any shadcn\nre-sync, or component work bypasses the color palette and polish rules.\n\n`skills-lock.json` lists `vercel-react-best-practices`, which now lives at\n`frontend-workflow/react-performance/`. `shadcn` is back at its original path and\nits lock entry is valid.\n\n## Boundaries\n\n- Do not carve hosted code out of backend/web until the purge on 18 Oct 2026. The export window and the purge script run on that code until then.\n- Do not drop SearxNG, sandbox, OpenSandbox, or zero-cache from compose until a new compose is defined.\n- Edit the root `README.md` directly. The draft at `plans/community-local/seo/drafts/README.md` shipped on 18 Sep 2026 and is kept only for history. Anything added to the README replaces something — its length was measured against the eight biggest repos in this category. Make the same change in every `README.<locale>.md`, section for section; [`06-repo-readme.md`](plans/community-local/seo/06-repo-readme.md#the-readme-since-9-oct-2026) has the rules, where each format-table cell is checked, and how to replace the demo video.\n- Do not commit, push or open a PR unless asked.\n\n## Security\n\n- Never commit `.env` or secrets.\n- Do not put credentials in diffs, logs, or sample payloads.\n\n<!-- File: CLAUDE.md (Tokens: ~2199 | Category: claude-rule) -->\n# AGENTS.md\n\nNearest `AGENTS.md` wins. Edit this file, not `CLAUDE.md` (`CLAUDE.md` is a symlink).\n\n## Overview\n\nDesktop app plus scraper API. Five trees:\n\n| Tree | Role |\n|------|------|\n| `surfsense_backend` | FastAPI API |\n| `surfsense_web` | Next.js hosted UI |\n| `surfsense_local` | Electron desktop |\n| `surfsense_mcp` | MCP server over the REST API |\n| `plugins` | SurfSense's own plugin servers ([plugin host](docs/architecture/plugin-host.md)) and the [registry](docs/architecture/plugin-registry.md). `bundles/` holds the earlier, local design's SDK and tooling, deferred |\n\nThe hosted service has been export-only since the 2.0.0 launch on 18 Sep 2026, and its user data is purged on 18 Oct 2026 ([sunset](docs/architecture/sunset.md)). Product direction is local + API.\n\n## Code organization\n\nApplies to **every new file**. Existing code is not a template and not a cleanup ticket.\n\n**Must**\n\n- Organize by feature (vertical slice), not by technical layer.\n- One responsibility per file. One responsibility per folder.\n- If a responsibility grows sub-responsibilities, promote it to a folder. Each sub-responsibility is its own file.\n- Names state what and why, not how.\n- Comments and docstrings state intent only. Do not restate the code.\n- Keep them short. A line or two. Write only what the code cannot say: a constraint, a rejected alternative, a number that justifies a threshold.\n\n**Must not**\n\n- Do not write essays in docstrings. If it explains how you arrived at the code rather than what the code must honour, delete it.\n- Do not put new work in a nearby file because it is convenient. New responsibility, new file.\n- Do not add catch-all folders (`utils`, `helpers`, `common`, `misc`, `shared`) unless that name is the product concept.\n- Do not layer-split new work (`controllers/`, `services/`, `models/` as the primary tree).\n- Do not rewrite existing code to this layout unless the task is that rewrite.\n\nThe tree is inconsistent. New work follows this. Old work stays until a task explicitly owns it.\n\n## Docs\n\n[`docs/`](docs/README.md) is the engineering map. `architecture/` says what is true now, one doc per feature; `adr/` says why; `proposals/` holds designs not built yet; `contracts/` holds the frozen interfaces between trees. Task status lives in GitHub issues; docs carry only a proposal's `status` and each architecture doc's Known gaps. `plans/` is business and ops material, not specs.\n\n- Before changing a feature, read its doc in `docs/architecture/` and the ADRs it links.\n- If a change alters behaviour a doc describes, update the doc in the same change. Fixing a Known gap deletes its line.\n- Run `python scripts/check_docs.py` after editing anything under `docs/` or `plans/`.\n\n## Commands\n\n```bash\n# backend\ncd surfsense_backend && uv sync\ncd surfsense_backend && uv run ruff check .\ncd surfsense_backend && uv run pytest -m unit\n\n# web\ncd surfsense_web && pnpm install\ncd surfsense_web && pnpm dev\ncd surfsense_web && pnpm format\n\n# desktop\ncd surfsense_local/electron && pnpm dev\n\n# MCP\ncd surfsense_mcp && uv sync\n\n# plugin host: SurfSense's own plugins, from plugins/remote/\ncd plugins/remote/host && uv sync\ncd plugins/remote && uv run --project host python -m host\n\n# bundles (deferred): the manifest rules, the SDK, the surfsense-plugins command\ncd plugins/bundles/core/manifest && uv sync\ncd plugins/bundles/core/sdk && uv sync\ncd plugins/bundles/core/sdk && uv run pyright\ncd plugins/bundles/core/cli && uv sync\n\n# compose (dev and self-host, not production)\ndocker compose -f docker/docker-compose.yml\n\n# hooks\npre-commit run --all-files\n```\n\n## Testing\n\n| Area | Command |\n|------|---------|\n| Backend unit | `cd surfsense_backend && uv run pytest -m unit` |\n| Backend integration | `cd surfsense_backend && uv run pytest -m integration` |\n| Web unit | `cd surfsense_web && pnpm test:unit` |\n| Web e2e | `cd surfsense_web && pnpm test:e2e` |\n| MCP | `cd surfsense_mcp && uv run pytest` |\n| Plugin host | `cd plugins/remote/host && uv run pytest` |\n| Bundles: manifest rules | `cd plugins/bundles/core/manifest && uv run pytest -m unit` |\n| Bundles: SDK | `cd plugins/bundles/core/sdk && uv run pytest -m unit` |\n| Bundles: SDK against the app | `cd plugins/bundles/core/sdk && uv run pytest -m contract` (starts the backend; `uv sync` it first) |\n| Bundles: CLI | `cd plugins/bundles/core/cli && uv run pytest` (starts the backend; `uv sync` it first) |\n| Desktop | `cd surfsense_local/electron && pnpm test` |\nCI: `.github/workflows/`. New behavior: one failing test, then the minimum code to pass it. Use the `tdd` skill. Tests hit public seams, not internals.\n\n## Pull requests\n\nFollow [CONTRIBUTING.md](CONTRIBUTING.md). The parts agents miss:\n\n- Open PRs against `dev`. `gh pr create` targets the default branch, `main`, unless you pass `--base dev`.\n- `gh pr create --body` skips the PR template. Keep its headings: What, Why, `Fixes #`, How to test.\n- Commit messages and PR titles are Conventional Commits, `type(scope): summary`. The commitizen hook runs only where it is installed; CI does not run it.\n- A new feature starts as a proposal PR in `docs/proposals/`, not as code.\n- `surfsense_backend/app/proprietary/` and `plugins/remote/proprietary/` are Business Source License 1.1 and changed only by maintainers: ask one before changing them. A change to `docs/contracts/` needs the owners of both sides.\n\n## Skills\n\nCanonical dir: `.agents/skills/`. `.claude/skills` is a symlink to it.\n\n| Skill | When |\n|-------|------|\n| `tdd` | New behavior or a bug fix with a testable seam |\n| `codebase-design` | Module shape, seam, depth — `tdd` depends on this vocabulary |\n| `fastapi` | FastAPI / Pydantic work. Symlink into the installed wheel; repair the **same** root link after a FastAPI or Python bump. Do not keep `surfsense_backend/.agents/`. |\n| `frontend-workflow` | Frontend work in `surfsense_web` and `surfsense_local/frontend`: React/Next performance, color tokens, UI polish, motion. Bundles `react-performance/`, `color/`, `polish/`, `motion/`, and `base-ui.md` for Base UI in `surfsense_local/frontend`; routes out to `shadcn`. |\n| `shadcn` | UI components in a tree with `components.json`. Standalone — it inspects the project live and grants its own CLI, which only works as a discovered skill. Load it after `frontend-workflow`, not instead of it. |\n| `translate` | Interface strings in `surfsense_local`: adding a message in code (`en.json` is generated from it), moving hard-coded text into messages, translating Japanese and German. Holds the key shape, tone and glossary. |\n\nDo not install skill catalogs. Do not add `CONTEXT.md` or a second rules tree.\n\n`frontend-workflow` bundles what were separate skills under `react-performance/`,\n`color/`, `polish/`, and `motion/`. Those files keep their old frontmatter, which\nis inert — they are reference files, not discovered skills. Skill discovery is one\nlevel deep, so do not nest a new skill inside another skill's folder.\n\nBundle a skill only if it is static markdown that overlaps the others. Anything\nwith frontmatter that does work — `allowed-tools`, `` !`command` `` substitution —\nmust stay top-level, because that frontmatter is inert in a bundled file.\n\n`shadcn/SKILL.md` carries one local addition: a note routing to `frontend-workflow`\nfirst. It is the only edit to that vendored file — restore it after any shadcn\nre-sync, or component work bypasses the color palette and polish rules.\n\n`skills-lock.json` lists `vercel-react-best-practices`, which now lives at\n`frontend-workflow/react-performance/`. `shadcn` is back at its original path and\nits lock entry is valid.\n\n## Boundaries\n\n- Do not carve hosted code out of backend/web until the purge on 18 Oct 2026. The export window and the purge script run on that code until then.\n- Do not drop SearxNG, sandbox, OpenSandbox, or zero-cache from compose until a new compose is defined.\n- Edit the root `README.md` directly. The draft at `plans/community-local/seo/drafts/README.md` shipped on 18 Sep 2026 and is kept only for history. Anything added to the README replaces something — its length was measured against the eight biggest repos in this category. Make the same change in every `README.<locale>.md`, section for section; [`06-repo-readme.md`](plans/community-local/seo/06-repo-readme.md#the-readme-since-9-oct-2026) has the rules, where each format-table cell is checked, and how to replace the demo video.\n- Do not commit, push or open a PR unless asked.\n\n## Security\n\n- Never commit `.env` or secrets.\n- Do not put credentials in diffs, logs, or sample payloads.\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/marketplace.json)\n\n<!-- File: .claude-plugin/plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.claude-plugin/plugin.json)\n\n<!-- File: .cursor/mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/MODSetter/SurfSense/HEAD/.cursor/mcp.json)\n</yakaai_skills>"}