{"owner":"ankitects","repo":"anki","hasSkills":true,"totalSkillsCount":4,"totalTokensCount":1927,"categories":["project-spec","anthropic-skill","claude-rule"],"hasMcp":false,"mcpConfig":null,"found":["docs/architecture.md",".cursor/rules/building.md",".cursor/rules/i18n.md","CLAUDE.md"],"skills":{"docs/architecture.md":"<!-- DO NOT MANUALLY EDIT THIS FILE -->\n<!-- This file is copied from docs-site/developers/architecture.mdx automatically -->\n\n# Anki Architecture\n\n<!-- <<<<cog\nfrom cogdocs import get_file_contents\ncog.out(get_file_contents(\"architecture\"))\n>>>> -->\n\nVery brief notes for now.\n\n## Backend/GUI\n\nAt the highest level, Anki is logically separated into two parts.\n\nA neat visualization of the file layout is available here:\n[https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=ankitects%2Fanki](https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=ankitects%2Fanki)\n(or go to [https://githubnext.com/projects/repo-visualization#explore-for-yourself](https://githubnext.com/projects/repo-visualization#explore-for-yourself) and enter `ankitects/anki`).\n\n### Library (rslib & pylib)\n\nThe Python library (pylib) exports \"backend\" methods - opening collections,\nfetching and answering cards, and so on. It is used by Anki’s GUI, and can also\nbe included in command line programs to access Anki decks without the GUI.\n\nThe library is accessible in Python with \"import anki\". Its code lives in\nthe `pylib/anki/` folder.\n\nThese days, the majority of backend logic lives in a Rust library (rslib, located in `rslib/`). Calls to pylib proxy requests to rslib, and return the results.\n\npylib contains a private Python module called rsbridge (`pylib/rsbridge/`) that wraps the Rust code, making it accessible in Python.\n\n### GUI (aqt & ts)\n\nAnki's _GUI_ is a mix of Qt (via the PyQt Python bindings for Qt), and\nTypeScript/HTML/CSS. The Qt code lives in `qt/aqt/`, and is importable in Python\nwith \"import aqt\". The web code is split between `qt/aqt/data/web/` and `ts/`,\nwith the majority of new code being placed in the latter, and copied into the\nformer at build time.\n\n## Protobuf\n\nAnki uses Protocol Buffers to define backend methods, and the storage format of\nsome items in a collection file. The definitions live in `proto/anki/`.\n\nThe Python/Rust bridge uses them to pass data back and forth, and some of the\nTypeScript code also makes use of them, allowing data to be communicated in a\ntype-safe manner between the different languages.\n\nAt the moment, the protobuf is not considered public API. Some pylib methods\nexpose a protobuf object directly to callers, but when they do so, they use a\ntype alias, so callers outside pylib should never need to import a generated\n\\_pb2.py file.\n\n<!-- <<<<end>>>> -->\n",".cursor/rules/building.md":"- To build and check the project, use ./check in the root folder (or check.bat on Windows)\n- This will format files, then run lints and unit tests.\n",".cursor/rules/i18n.md":"- We use the fluent system+code generation for translation.\n- New strings should be added to rslib/core/. Ask for the appropriate file if you're not sure.\n- Assuming a string addons-you-have-count has been added to addons.ftl, that string is accessible in our different languages as follows:\n  - Python: from aqt.utils import tr; msg = tr.addons_you_have_count(count=3)\n  - TypeScript: import * as tr from \"@generated/ftl\"; tr.addonsYouHaveCount({count: 3})\n  - Rust: collection.tr.addons_you_have_count(3)\n- In Qt .ui files, strings that are marked as translatable will automatically use the registered ftl strings. So a QLabel with a title 'addons_you_have_count' that is marked as translatable will automatically use the translation defined in our addons.ftl file.\n","CLAUDE.md":"# Claude Code Configuration\n\n> **Note:** Every command you need — building, running, testing, linting,\n> formatting — is defined as a recipe in the project `justfile`. Run\n> `just --list` to see them. Do not invoke `./ninja`, `./run`, or scripts\n> under `./tools` directly — use the `just` recipes instead.\n\n## Project Overview\n\nAnki is a spaced repetition flashcard program with a multi-layered architecture. Main components:\n\n- Web frontend: Svelte/TypeScript in ts/\n- PyQt GUI, which embeds the web components in aqt/\n- Python library which wraps our rust Layer (pylib/, with Rust module in pylib/rsbridge)\n- Core Rust layer in rslib/\n- Protobuf definitions in proto/ that are used by the different layers to\n  talk to each other.\n\n## Running Anki\n\nTo build and run Anki in development mode:\n\n```\njust run\n```\n\nThis builds pylib and qt, then launches Anki with debugging enabled. Web\nviews are served at http://localhost:40000/_anki/pages/ (e.g.,\ndeckconfig.html). Use `just run-optimized` for a release-optimized build.\nFor live-reloading during web development, run `just web-watch` in a\nseparate terminal — it monitors ts/, sass/, and qt/aqt/data/web/ and\nauto-rebuilds on changes (`just rebuild-web` triggers a one-off rebuild).\n\n## Building/checking\n\n`just check` will format the code and run the main build & checks.\nPlease do this as a final step before marking a task as completed.\n\nRun `just` (or `just --list`) to see all available commands.\n\n## Quick iteration\n\nDuring development, you can build/check subsections of our code:\n\n- Rust: `cargo check`\n- Python: `just lint` (runs mypy/ruff), and if wheel-related, `just wheels`\n- TypeScript/Svelte: `just lint` (includes check:svelte and check:typescript)\n\nLanguage-specific tests are also available: `just test-rust`, `just test-py`,\n`just test-ts`. Use `just fmt` / `just fix-fmt` for formatting and\n`just fix-lint` to auto-fix lint issues.\n\nTypeScript/Svelte browser e2e tests live in `ts/tests/e2e/` and run with\n`just test-e2e`. The harness launches a temporary Anki instance and drives\nmediasrv pages with Playwright's Chromium.\n\nBe mindful that some changes (such as modifications to .proto files) may\nneed a full build with `just check` first.\n\n## Testing guidance\n\nBefore adding or changing unit or component tests, read and follow the\n[Writing Unit Tests for Anki](docs-site/developers/unit-testing.mdx).\n\n## Build tooling\n\n`just` recipes wrap our build system (implemented in build/), which takes\ncare of downloading required deps and invoking our build steps. See the\nproject `justfile` for the full set of recipes.\n\n## Translations\n\nftl/ contains our Fluent translation files. We have scripts in rslib/i18n\nto auto-generate an API for Rust, TypeScript and Python so that our code can\naccess the translations in a type-safe manner. Changes should be made to\nftl/core or ftl/qt. Except for features specific to our Qt interface, prefer\nthe core module. When adding new strings, confirm the appropriate ftl file\nfirst, and try to match the existing style.\n\n## Protobuf and IPC\n\nOur build scripts use the .proto files to define our Rust library's\nnon-Rust API. pylib/rsbridge exposes that API, and \\_backend.py exposes\nsnake_case methods for each protobuf RPC that call into the API.\nSimilar tooling creates a @generated/backend TypeScript module for\ncommunicating with the Rust backend (which happens over POST requests).\n\n## Fixing errors\n\nWhen dealing with build errors or failing tests, invoke 'check' or one\nof the quick iteration commands regularly. This helps verify your changes\nare correct. To locate other instances of a problem, run the check again -\ndon't attempt to grep the codebase.\n\n## Ignores\n\nThe files in out/ are auto-generated. Mostly you should ignore that folder,\nthough you may sometimes find it useful to view out/{pylib/anki,qt/\\_aqt,ts/lib/generated} when dealing with cross-language communication or our other generated sourcecode.\n\n## Installer\n\nThe code for our Briefcase-based installer is in qt/installer, with\nseparate templates for each platform (mac-template/, linux-template/,\nwindows-template/).\n\n## Rust dependencies\n\nPrefer adding to the root workspace, and using dep.workspace = true in the individual Rust project.\n\n## Rust utilities\n\nrslib/{process,io} contain some helpers for file and process operations,\nwhich provide better error messages/context and some ergonomics. Use them\nwhen possible.\n\n## Rust error handling\n\nin rslib, use error/mod.rs's AnkiError/Result and snafu. In our other Rust modules, prefer anyhow + additional context where appropriate. Unwrapping\nin build scripts/tests is fine.\n\n## Individual preferences\n\nSee @.claude/user.md\n"},"files":{"docs/architecture.md":"<!-- DO NOT MANUALLY EDIT THIS FILE -->\n<!-- This file is copied from docs-site/developers/architecture.mdx automatically -->\n\n# Anki Architecture\n\n<!-- <<<<cog\nfrom cogdocs import get_file_contents\ncog.out(get_file_contents(\"architecture\"))\n>>>> -->\n\nVery brief notes for now.\n\n## Backend/GUI\n\nAt the highest level, Anki is logically separated into two parts.\n\nA neat visualization of the file layout is available here:\n[https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=ankitects%2Fanki](https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=ankitects%2Fanki)\n(or go to [https://githubnext.com/projects/repo-visualization#explore-for-yourself](https://githubnext.com/projects/repo-visualization#explore-for-yourself) and enter `ankitects/anki`).\n\n### Library (rslib & pylib)\n\nThe Python library (pylib) exports \"backend\" methods - opening collections,\nfetching and answering cards, and so on. It is used by Anki’s GUI, and can also\nbe included in command line programs to access Anki decks without the GUI.\n\nThe library is accessible in Python with \"import anki\". Its code lives in\nthe `pylib/anki/` folder.\n\nThese days, the majority of backend logic lives in a Rust library (rslib, located in `rslib/`). Calls to pylib proxy requests to rslib, and return the results.\n\npylib contains a private Python module called rsbridge (`pylib/rsbridge/`) that wraps the Rust code, making it accessible in Python.\n\n### GUI (aqt & ts)\n\nAnki's _GUI_ is a mix of Qt (via the PyQt Python bindings for Qt), and\nTypeScript/HTML/CSS. The Qt code lives in `qt/aqt/`, and is importable in Python\nwith \"import aqt\". The web code is split between `qt/aqt/data/web/` and `ts/`,\nwith the majority of new code being placed in the latter, and copied into the\nformer at build time.\n\n## Protobuf\n\nAnki uses Protocol Buffers to define backend methods, and the storage format of\nsome items in a collection file. The definitions live in `proto/anki/`.\n\nThe Python/Rust bridge uses them to pass data back and forth, and some of the\nTypeScript code also makes use of them, allowing data to be communicated in a\ntype-safe manner between the different languages.\n\nAt the moment, the protobuf is not considered public API. Some pylib methods\nexpose a protobuf object directly to callers, but when they do so, they use a\ntype alias, so callers outside pylib should never need to import a generated\n\\_pb2.py file.\n\n<!-- <<<<end>>>> -->\n",".cursor/rules/building.md":"- To build and check the project, use ./check in the root folder (or check.bat on Windows)\n- This will format files, then run lints and unit tests.\n",".cursor/rules/i18n.md":"- We use the fluent system+code generation for translation.\n- New strings should be added to rslib/core/. Ask for the appropriate file if you're not sure.\n- Assuming a string addons-you-have-count has been added to addons.ftl, that string is accessible in our different languages as follows:\n  - Python: from aqt.utils import tr; msg = tr.addons_you_have_count(count=3)\n  - TypeScript: import * as tr from \"@generated/ftl\"; tr.addonsYouHaveCount({count: 3})\n  - Rust: collection.tr.addons_you_have_count(3)\n- In Qt .ui files, strings that are marked as translatable will automatically use the registered ftl strings. So a QLabel with a title 'addons_you_have_count' that is marked as translatable will automatically use the translation defined in our addons.ftl file.\n","CLAUDE.md":"# Claude Code Configuration\n\n> **Note:** Every command you need — building, running, testing, linting,\n> formatting — is defined as a recipe in the project `justfile`. Run\n> `just --list` to see them. Do not invoke `./ninja`, `./run`, or scripts\n> under `./tools` directly — use the `just` recipes instead.\n\n## Project Overview\n\nAnki is a spaced repetition flashcard program with a multi-layered architecture. Main components:\n\n- Web frontend: Svelte/TypeScript in ts/\n- PyQt GUI, which embeds the web components in aqt/\n- Python library which wraps our rust Layer (pylib/, with Rust module in pylib/rsbridge)\n- Core Rust layer in rslib/\n- Protobuf definitions in proto/ that are used by the different layers to\n  talk to each other.\n\n## Running Anki\n\nTo build and run Anki in development mode:\n\n```\njust run\n```\n\nThis builds pylib and qt, then launches Anki with debugging enabled. Web\nviews are served at http://localhost:40000/_anki/pages/ (e.g.,\ndeckconfig.html). Use `just run-optimized` for a release-optimized build.\nFor live-reloading during web development, run `just web-watch` in a\nseparate terminal — it monitors ts/, sass/, and qt/aqt/data/web/ and\nauto-rebuilds on changes (`just rebuild-web` triggers a one-off rebuild).\n\n## Building/checking\n\n`just check` will format the code and run the main build & checks.\nPlease do this as a final step before marking a task as completed.\n\nRun `just` (or `just --list`) to see all available commands.\n\n## Quick iteration\n\nDuring development, you can build/check subsections of our code:\n\n- Rust: `cargo check`\n- Python: `just lint` (runs mypy/ruff), and if wheel-related, `just wheels`\n- TypeScript/Svelte: `just lint` (includes check:svelte and check:typescript)\n\nLanguage-specific tests are also available: `just test-rust`, `just test-py`,\n`just test-ts`. Use `just fmt` / `just fix-fmt` for formatting and\n`just fix-lint` to auto-fix lint issues.\n\nTypeScript/Svelte browser e2e tests live in `ts/tests/e2e/` and run with\n`just test-e2e`. The harness launches a temporary Anki instance and drives\nmediasrv pages with Playwright's Chromium.\n\nBe mindful that some changes (such as modifications to .proto files) may\nneed a full build with `just check` first.\n\n## Testing guidance\n\nBefore adding or changing unit or component tests, read and follow the\n[Writing Unit Tests for Anki](docs-site/developers/unit-testing.mdx).\n\n## Build tooling\n\n`just` recipes wrap our build system (implemented in build/), which takes\ncare of downloading required deps and invoking our build steps. See the\nproject `justfile` for the full set of recipes.\n\n## Translations\n\nftl/ contains our Fluent translation files. We have scripts in rslib/i18n\nto auto-generate an API for Rust, TypeScript and Python so that our code can\naccess the translations in a type-safe manner. Changes should be made to\nftl/core or ftl/qt. Except for features specific to our Qt interface, prefer\nthe core module. When adding new strings, confirm the appropriate ftl file\nfirst, and try to match the existing style.\n\n## Protobuf and IPC\n\nOur build scripts use the .proto files to define our Rust library's\nnon-Rust API. pylib/rsbridge exposes that API, and \\_backend.py exposes\nsnake_case methods for each protobuf RPC that call into the API.\nSimilar tooling creates a @generated/backend TypeScript module for\ncommunicating with the Rust backend (which happens over POST requests).\n\n## Fixing errors\n\nWhen dealing with build errors or failing tests, invoke 'check' or one\nof the quick iteration commands regularly. This helps verify your changes\nare correct. To locate other instances of a problem, run the check again -\ndon't attempt to grep the codebase.\n\n## Ignores\n\nThe files in out/ are auto-generated. Mostly you should ignore that folder,\nthough you may sometimes find it useful to view out/{pylib/anki,qt/\\_aqt,ts/lib/generated} when dealing with cross-language communication or our other generated sourcecode.\n\n## Installer\n\nThe code for our Briefcase-based installer is in qt/installer, with\nseparate templates for each platform (mac-template/, linux-template/,\nwindows-template/).\n\n## Rust dependencies\n\nPrefer adding to the root workspace, and using dep.workspace = true in the individual Rust project.\n\n## Rust utilities\n\nrslib/{process,io} contain some helpers for file and process operations,\nwhich provide better error messages/context and some ergonomics. Use them\nwhen possible.\n\n## Rust error handling\n\nin rslib, use error/mod.rs's AnkiError/Result and snafu. In our other Rust modules, prefer anyhow + additional context where appropriate. Unwrapping\nin build scripts/tests is fine.\n\n## Individual preferences\n\nSee @.claude/user.md\n"},"items":[{"name":"architecture.md","path":"docs/architecture.md","rawUrl":"https://raw.githubusercontent.com/ankitects/anki/HEAD/docs/architecture.md","title":"docs - System Architecture & Module Boundaries","category":"project-spec","format":"markdown","content":"<!-- DO NOT MANUALLY EDIT THIS FILE -->\n<!-- This file is copied from docs-site/developers/architecture.mdx automatically -->\n\n# Anki Architecture\n\n<!-- <<<<cog\nfrom cogdocs import get_file_contents\ncog.out(get_file_contents(\"architecture\"))\n>>>> -->\n\nVery brief notes for now.\n\n## Backend/GUI\n\nAt the highest level, Anki is logically separated into two parts.\n\nA neat visualization of the file layout is available here:\n[https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=ankitects%2Fanki](https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=ankitects%2Fanki)\n(or go to [https://githubnext.com/projects/repo-visualization#explore-for-yourself](https://githubnext.com/projects/repo-visualization#explore-for-yourself) and enter `ankitects/anki`).\n\n### Library (rslib & pylib)\n\nThe Python library (pylib) exports \"backend\" methods - opening collections,\nfetching and answering cards, and so on. It is used by Anki’s GUI, and can also\nbe included in command line programs to access Anki decks without the GUI.\n\nThe library is accessible in Python with \"import anki\". Its code lives in\nthe `pylib/anki/` folder.\n\nThese days, the majority of backend logic lives in a Rust library (rslib, located in `rslib/`). Calls to pylib proxy requests to rslib, and return the results.\n\npylib contains a private Python module called rsbridge (`pylib/rsbridge/`) that wraps the Rust code, making it accessible in Python.\n\n### GUI (aqt & ts)\n\nAnki's _GUI_ is a mix of Qt (via the PyQt Python bindings for Qt), and\nTypeScript/HTML/CSS. The Qt code lives in `qt/aqt/`, and is importable in Python\nwith \"import aqt\". The web code is split between `qt/aqt/data/web/` and `ts/`,\nwith the majority of new code being placed in the latter, and copied into the\nformer at build time.\n\n## Protobuf\n\nAnki uses Protocol Buffers to define backend methods, and the storage format of\nsome items in a collection file. The definitions live in `proto/anki/`.\n\nThe Python/Rust bridge uses them to pass data back and forth, and some of the\nTypeScript code also makes use of them, allowing data to be communicated in a\ntype-safe manner between the different languages.\n\nAt the moment, the protobuf is not considered public API. Some pylib methods\nexpose a protobuf object directly to callers, but when they do so, they use a\ntype alias, so callers outside pylib should never need to import a generated\n\\_pb2.py file.\n\n<!-- <<<<end>>>> -->\n","isInternal":false,"tokens":612,"sizeBytes":2412},{"name":"building.md","path":".cursor/rules/building.md","rawUrl":"https://raw.githubusercontent.com/ankitects/anki/HEAD/.cursor/rules/building.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"- To build and check the project, use ./check in the root folder (or check.bat on Windows)\n- This will format files, then run lints and unit tests.\n","isInternal":false,"tokens":36,"sizeBytes":148},{"name":"i18n.md","path":".cursor/rules/i18n.md","rawUrl":"https://raw.githubusercontent.com/ankitects/anki/HEAD/.cursor/rules/i18n.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"- We use the fluent system+code generation for translation.\n- New strings should be added to rslib/core/. Ask for the appropriate file if you're not sure.\n- Assuming a string addons-you-have-count has been added to addons.ftl, that string is accessible in our different languages as follows:\n  - Python: from aqt.utils import tr; msg = tr.addons_you_have_count(count=3)\n  - TypeScript: import * as tr from \"@generated/ftl\"; tr.addonsYouHaveCount({count: 3})\n  - Rust: collection.tr.addons_you_have_count(3)\n- In Qt .ui files, strings that are marked as translatable will automatically use the registered ftl strings. So a QLabel with a title 'addons_you_have_count' that is marked as translatable will automatically use the translation defined in our addons.ftl file.\n","isInternal":false,"tokens":179,"sizeBytes":768},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/ankitects/anki/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# Claude Code Configuration\n\n> **Note:** Every command you need — building, running, testing, linting,\n> formatting — is defined as a recipe in the project `justfile`. Run\n> `just --list` to see them. Do not invoke `./ninja`, `./run`, or scripts\n> under `./tools` directly — use the `just` recipes instead.\n\n## Project Overview\n\nAnki is a spaced repetition flashcard program with a multi-layered architecture. Main components:\n\n- Web frontend: Svelte/TypeScript in ts/\n- PyQt GUI, which embeds the web components in aqt/\n- Python library which wraps our rust Layer (pylib/, with Rust module in pylib/rsbridge)\n- Core Rust layer in rslib/\n- Protobuf definitions in proto/ that are used by the different layers to\n  talk to each other.\n\n## Running Anki\n\nTo build and run Anki in development mode:\n\n```\njust run\n```\n\nThis builds pylib and qt, then launches Anki with debugging enabled. Web\nviews are served at http://localhost:40000/_anki/pages/ (e.g.,\ndeckconfig.html). Use `just run-optimized` for a release-optimized build.\nFor live-reloading during web development, run `just web-watch` in a\nseparate terminal — it monitors ts/, sass/, and qt/aqt/data/web/ and\nauto-rebuilds on changes (`just rebuild-web` triggers a one-off rebuild).\n\n## Building/checking\n\n`just check` will format the code and run the main build & checks.\nPlease do this as a final step before marking a task as completed.\n\nRun `just` (or `just --list`) to see all available commands.\n\n## Quick iteration\n\nDuring development, you can build/check subsections of our code:\n\n- Rust: `cargo check`\n- Python: `just lint` (runs mypy/ruff), and if wheel-related, `just wheels`\n- TypeScript/Svelte: `just lint` (includes check:svelte and check:typescript)\n\nLanguage-specific tests are also available: `just test-rust`, `just test-py`,\n`just test-ts`. Use `just fmt` / `just fix-fmt` for formatting and\n`just fix-lint` to auto-fix lint issues.\n\nTypeScript/Svelte browser e2e tests live in `ts/tests/e2e/` and run with\n`just test-e2e`. The harness launches a temporary Anki instance and drives\nmediasrv pages with Playwright's Chromium.\n\nBe mindful that some changes (such as modifications to .proto files) may\nneed a full build with `just check` first.\n\n## Testing guidance\n\nBefore adding or changing unit or component tests, read and follow the\n[Writing Unit Tests for Anki](docs-site/developers/unit-testing.mdx).\n\n## Build tooling\n\n`just` recipes wrap our build system (implemented in build/), which takes\ncare of downloading required deps and invoking our build steps. See the\nproject `justfile` for the full set of recipes.\n\n## Translations\n\nftl/ contains our Fluent translation files. We have scripts in rslib/i18n\nto auto-generate an API for Rust, TypeScript and Python so that our code can\naccess the translations in a type-safe manner. Changes should be made to\nftl/core or ftl/qt. Except for features specific to our Qt interface, prefer\nthe core module. When adding new strings, confirm the appropriate ftl file\nfirst, and try to match the existing style.\n\n## Protobuf and IPC\n\nOur build scripts use the .proto files to define our Rust library's\nnon-Rust API. pylib/rsbridge exposes that API, and \\_backend.py exposes\nsnake_case methods for each protobuf RPC that call into the API.\nSimilar tooling creates a @generated/backend TypeScript module for\ncommunicating with the Rust backend (which happens over POST requests).\n\n## Fixing errors\n\nWhen dealing with build errors or failing tests, invoke 'check' or one\nof the quick iteration commands regularly. This helps verify your changes\nare correct. To locate other instances of a problem, run the check again -\ndon't attempt to grep the codebase.\n\n## Ignores\n\nThe files in out/ are auto-generated. Mostly you should ignore that folder,\nthough you may sometimes find it useful to view out/{pylib/anki,qt/\\_aqt,ts/lib/generated} when dealing with cross-language communication or our other generated sourcecode.\n\n## Installer\n\nThe code for our Briefcase-based installer is in qt/installer, with\nseparate templates for each platform (mac-template/, linux-template/,\nwindows-template/).\n\n## Rust dependencies\n\nPrefer adding to the root workspace, and using dep.workspace = true in the individual Rust project.\n\n## Rust utilities\n\nrslib/{process,io} contain some helpers for file and process operations,\nwhich provide better error messages/context and some ergonomics. Use them\nwhen possible.\n\n## Rust error handling\n\nin rslib, use error/mod.rs's AnkiError/Result and snafu. In our other Rust modules, prefer anyhow + additional context where appropriate. Unwrapping\nin build scripts/tests is fine.\n\n## Individual preferences\n\nSee @.claude/user.md\n","isInternal":false,"tokens":1100,"sizeBytes":4672}],"systemPromptSnippet":"<yakaai_skills repo=\"ankitects/anki\">\n<!-- File: docs/architecture.md (Tokens: ~612 | Category: project-spec) -->\n<!-- DO NOT MANUALLY EDIT THIS FILE -->\n<!-- This file is copied from docs-site/developers/architecture.mdx automatically -->\n\n# Anki Architecture\n\n<!-- <<<<cog\nfrom cogdocs import get_file_contents\ncog.out(get_file_contents(\"architecture\"))\n>>>> -->\n\nVery brief notes for now.\n\n## Backend/GUI\n\nAt the highest level, Anki is logically separated into two parts.\n\nA neat visualization of the file layout is available here:\n[https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=ankitects%2Fanki](https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=ankitects%2Fanki)\n(or go to [https://githubnext.com/projects/repo-visualization#explore-for-yourself](https://githubnext.com/projects/repo-visualization#explore-for-yourself) and enter `ankitects/anki`).\n\n### Library (rslib & pylib)\n\nThe Python library (pylib) exports \"backend\" methods - opening collections,\nfetching and answering cards, and so on. It is used by Anki’s GUI, and can also\nbe included in command line programs to access Anki decks without the GUI.\n\nThe library is accessible in Python with \"import anki\". Its code lives in\nthe `pylib/anki/` folder.\n\nThese days, the majority of backend logic lives in a Rust library (rslib, located in `rslib/`). Calls to pylib proxy requests to rslib, and return the results.\n\npylib contains a private Python module called rsbridge (`pylib/rsbridge/`) that wraps the Rust code, making it accessible in Python.\n\n### GUI (aqt & ts)\n\nAnki's _GUI_ is a mix of Qt (via the PyQt Python bindings for Qt), and\nTypeScript/HTML/CSS. The Qt code lives in `qt/aqt/`, and is importable in Python\nwith \"import aqt\". The web code is split between `qt/aqt/data/web/` and `ts/`,\nwith the majority of new code being placed in the latter, and copied into the\nformer at build time.\n\n## Protobuf\n\nAnki uses Protocol Buffers to define backend methods, and the storage format of\nsome items in a collection file. The definitions live in `proto/anki/`.\n\nThe Python/Rust bridge uses them to pass data back and forth, and some of the\nTypeScript code also makes use of them, allowing data to be communicated in a\ntype-safe manner between the different languages.\n\nAt the moment, the protobuf is not considered public API. Some pylib methods\nexpose a protobuf object directly to callers, but when they do so, they use a\ntype alias, so callers outside pylib should never need to import a generated\n\\_pb2.py file.\n\n<!-- <<<<end>>>> -->\n\n<!-- File: .cursor/rules/building.md (Tokens: ~36 | Category: anthropic-skill) -->\n- To build and check the project, use ./check in the root folder (or check.bat on Windows)\n- This will format files, then run lints and unit tests.\n\n<!-- File: .cursor/rules/i18n.md (Tokens: ~179 | Category: anthropic-skill) -->\n- We use the fluent system+code generation for translation.\n- New strings should be added to rslib/core/. Ask for the appropriate file if you're not sure.\n- Assuming a string addons-you-have-count has been added to addons.ftl, that string is accessible in our different languages as follows:\n  - Python: from aqt.utils import tr; msg = tr.addons_you_have_count(count=3)\n  - TypeScript: import * as tr from \"@generated/ftl\"; tr.addonsYouHaveCount({count: 3})\n  - Rust: collection.tr.addons_you_have_count(3)\n- In Qt .ui files, strings that are marked as translatable will automatically use the registered ftl strings. So a QLabel with a title 'addons_you_have_count' that is marked as translatable will automatically use the translation defined in our addons.ftl file.\n\n<!-- File: CLAUDE.md (Tokens: ~1100 | Category: claude-rule) -->\n# Claude Code Configuration\n\n> **Note:** Every command you need — building, running, testing, linting,\n> formatting — is defined as a recipe in the project `justfile`. Run\n> `just --list` to see them. Do not invoke `./ninja`, `./run`, or scripts\n> under `./tools` directly — use the `just` recipes instead.\n\n## Project Overview\n\nAnki is a spaced repetition flashcard program with a multi-layered architecture. Main components:\n\n- Web frontend: Svelte/TypeScript in ts/\n- PyQt GUI, which embeds the web components in aqt/\n- Python library which wraps our rust Layer (pylib/, with Rust module in pylib/rsbridge)\n- Core Rust layer in rslib/\n- Protobuf definitions in proto/ that are used by the different layers to\n  talk to each other.\n\n## Running Anki\n\nTo build and run Anki in development mode:\n\n```\njust run\n```\n\nThis builds pylib and qt, then launches Anki with debugging enabled. Web\nviews are served at http://localhost:40000/_anki/pages/ (e.g.,\ndeckconfig.html). Use `just run-optimized` for a release-optimized build.\nFor live-reloading during web development, run `just web-watch` in a\nseparate terminal — it monitors ts/, sass/, and qt/aqt/data/web/ and\nauto-rebuilds on changes (`just rebuild-web` triggers a one-off rebuild).\n\n## Building/checking\n\n`just check` will format the code and run the main build & checks.\nPlease do this as a final step before marking a task as completed.\n\nRun `just` (or `just --list`) to see all available commands.\n\n## Quick iteration\n\nDuring development, you can build/check subsections of our code:\n\n- Rust: `cargo check`\n- Python: `just lint` (runs mypy/ruff), and if wheel-related, `just wheels`\n- TypeScript/Svelte: `just lint` (includes check:svelte and check:typescript)\n\nLanguage-specific tests are also available: `just test-rust`, `just test-py`,\n`just test-ts`. Use `just fmt` / `just fix-fmt` for formatting and\n`just fix-lint` to auto-fix lint issues.\n\nTypeScript/Svelte browser e2e tests live in `ts/tests/e2e/` and run with\n`just test-e2e`. The harness launches a temporary Anki instance and drives\nmediasrv pages with Playwright's Chromium.\n\nBe mindful that some changes (such as modifications to .proto files) may\nneed a full build with `just check` first.\n\n## Testing guidance\n\nBefore adding or changing unit or component tests, read and follow the\n[Writing Unit Tests for Anki](docs-site/developers/unit-testing.mdx).\n\n## Build tooling\n\n`just` recipes wrap our build system (implemented in build/), which takes\ncare of downloading required deps and invoking our build steps. See the\nproject `justfile` for the full set of recipes.\n\n## Translations\n\nftl/ contains our Fluent translation files. We have scripts in rslib/i18n\nto auto-generate an API for Rust, TypeScript and Python so that our code can\naccess the translations in a type-safe manner. Changes should be made to\nftl/core or ftl/qt. Except for features specific to our Qt interface, prefer\nthe core module. When adding new strings, confirm the appropriate ftl file\nfirst, and try to match the existing style.\n\n## Protobuf and IPC\n\nOur build scripts use the .proto files to define our Rust library's\nnon-Rust API. pylib/rsbridge exposes that API, and \\_backend.py exposes\nsnake_case methods for each protobuf RPC that call into the API.\nSimilar tooling creates a @generated/backend TypeScript module for\ncommunicating with the Rust backend (which happens over POST requests).\n\n## Fixing errors\n\nWhen dealing with build errors or failing tests, invoke 'check' or one\nof the quick iteration commands regularly. This helps verify your changes\nare correct. To locate other instances of a problem, run the check again -\ndon't attempt to grep the codebase.\n\n## Ignores\n\nThe files in out/ are auto-generated. Mostly you should ignore that folder,\nthough you may sometimes find it useful to view out/{pylib/anki,qt/\\_aqt,ts/lib/generated} when dealing with cross-language communication or our other generated sourcecode.\n\n## Installer\n\nThe code for our Briefcase-based installer is in qt/installer, with\nseparate templates for each platform (mac-template/, linux-template/,\nwindows-template/).\n\n## Rust dependencies\n\nPrefer adding to the root workspace, and using dep.workspace = true in the individual Rust project.\n\n## Rust utilities\n\nrslib/{process,io} contain some helpers for file and process operations,\nwhich provide better error messages/context and some ergonomics. Use them\nwhen possible.\n\n## Rust error handling\n\nin rslib, use error/mod.rs's AnkiError/Result and snafu. In our other Rust modules, prefer anyhow + additional context where appropriate. Unwrapping\nin build scripts/tests is fine.\n\n## Individual preferences\n\nSee @.claude/user.md\n</yakaai_skills>"}