diff --git a/.claude/helpers/merge-claude-settings.sh b/.claude/helpers/merge-claude-settings.sh index 3de8e1a2..8343e15d 100644 --- a/.claude/helpers/merge-claude-settings.sh +++ b/.claude/helpers/merge-claude-settings.sh @@ -72,6 +72,9 @@ merged_json=$(echo "$parsed_json" | jq -s ' # Collect allow patterns from all files, flatten, and deduplicate allow: ([.[].permissions.allow // [] | .[] ] | unique), + # Collect ask patterns from all files, flatten, and deduplicate + ask: ([.[].permissions.ask // [] | .[] ] | unique), + # Collect deny patterns from all files, flatten, and deduplicate deny: ([.[].permissions.deny // [] | .[] ] | unique) } diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 9904260d..1d2e81ac 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -6,7 +6,7 @@ reviews: - path: "**/vendor_files/**" instructions: "These files came from a vendor and we're not allowed to change them. Refer to it if you need to understand how the main code interacts with it, but do not make comments about it." - path: "**/*.py" - instructions: "Do not express concerns about assert statements being removed by using the -O python flag; we never use that flag. Do not express concerns about ruff rules; a pre-commit hook already runs a ruff check. Do not warn about unnecessary super().init() calls; pyright prefers those to be present." + instructions: "Check the `ruff.toml` and `ruff-test.toml` for linting rules we've explicitly disabled and don't suggest changes to please conventions we've disabled. Do not express concerns about ruff rules; a pre-commit hook already runs a ruff check. Do not warn about unnecessary super().__init__() calls; pyright prefers those to be present. Do not warn about missing type hints; a pre-commit hook already checks for that." tools: eslint: # when the code contains typescript, eslint will be run by pre-commit, and coderabbit often generates false positives enabled: false diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0185c12c..2f3f5769 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -30,7 +30,7 @@ "-AmazonWebServices.aws-toolkit-vscode", // the AWS CLI feature installs this automatically, but it's causing problems in VS Code // basic tooling // "eamodio.gitlens@15.5.1", - "coderabbit.coderabbit-vscode@0.18.1", + "coderabbit.coderabbit-vscode@0.18.3", "ms-vscode.live-server@0.5.2025051301", "MS-vsliveshare.vsliveshare@1.0.5905", "github.copilot@1.388.0", @@ -71,5 +71,5 @@ "initializeCommand": "sh .devcontainer/initialize-command.sh", "onCreateCommand": "sh .devcontainer/on-create-command.sh", "postStartCommand": "sh .devcontainer/post-start-command.sh" - // Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): a6bb81da # spellchecker:disable-line + // Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): 2fb97fb0 # spellchecker:disable-line } diff --git a/.devcontainer/install-ci-tooling.py b/.devcontainer/install-ci-tooling.py index a311f6c5..e81fb990 100644 --- a/.devcontainer/install-ci-tooling.py +++ b/.devcontainer/install-ci-tooling.py @@ -5,7 +5,7 @@ import subprocess import sys -UV_VERSION = "0.10.7" +UV_VERSION = "0.10.8" COPIER_VERSION = "9.12.0" COPIER_TEMPLATE_EXTENSIONS_VERSION = "0.3.3" PRE_COMMIT_VERSION = "4.5.1" diff --git a/.devcontainer/on-create-command.sh b/.devcontainer/on-create-command.sh index 9cdf9e7a..a8e3552a 100644 --- a/.devcontainer/on-create-command.sh +++ b/.devcontainer/on-create-command.sh @@ -12,7 +12,7 @@ repo_root="$(CDPATH= cd -- "$script_dir/.." && pwd)" mkdir -p "$repo_root/.claude" chmod -R ug+rwX "$repo_root/.claude" chgrp -R 0 "$repo_root/.claude" || true -npm --prefix "$repo_root/.claude" install +npm --prefix "$repo_root/.claude" ci # Install beads for use in Claude planning npm install -g @beads/bd@0.57.0 # no specific reason for this version, just pinning for best practice diff --git a/AGENTS.md b/AGENTS.md index 9b62bfc3..913180b3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ - Don't sort or remove imports manually — pre-commit handles it. - Always include type hints for pyright in Python - Respect the pyright rule reportUnusedCallResult; assign unneeded return values to `_` -- Prefer keyword-only parameters: use `*` in Python signatures and destructured options objects in TypeScript. +- Prefer keyword-only parameters (unless a very clear single-argument function): use `*` in Python signatures and destructured options objects in TypeScript. ## Testing - Always run tests with an explicit path (e.g. uv run pytest tests/unit) — test runners discover all types by default. @@ -12,9 +12,15 @@ - Avoid magic values in comparisons in tests in all languages (like ruff rule PLR2004 specifies) - Prefer using random values in tests rather than arbitrary ones (e.g. the faker library, uuids, random.randint) when possible. +### Python Testing +- When using `mocker.spy` on a class-level method (including inherited ones), the spy records the unbound call, so assertions need `ANY` as the first argument to match self: `spy.assert_called_once_with(ANY, expected_arg)` +- Before writing new mock/spy helpers, check the `tests/unit/` folder for pre-built helpers in files like `fixtures.py` or `*mocks.py` + + ## Tooling - Always use `uv run python` instead of `python3` or `python` when running Python commands. - Check .devcontainer/devcontainer.json for tooling versions (Python, Node, etc.) when reasoning about version-specific stdlib or tooling behavior. +- For frontend work, run commands via `pnpm` scripts from `frontend/package.json` - When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & unless the user explicitly asks for it. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. diff --git a/extensions/context.py b/extensions/context.py index 9f96b7a8..e928df7f 100644 --- a/extensions/context.py +++ b/extensions/context.py @@ -11,7 +11,7 @@ class ContextUpdater(ContextHook): @override def hook(self, context: dict[Any, Any]) -> dict[Any, Any]: # These are duplicated in the install-ci-tooling.py script in this repository - context["uv_version"] = "0.10.7" + context["uv_version"] = "0.10.8" context["pre_commit_version"] = "4.5.1" # These also in pyproject.toml context["copier_version"] = "==9.12.0" @@ -38,7 +38,7 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]: context["pyinstaller_version"] = ">=6.19.0" context["setuptools_version"] = "80.7.1" context["strawberry_graphql_version"] = ">=0.298.0" - context["fastapi_version"] = ">=0.129.0" + context["fastapi_version"] = ">=0.135.1" context["fastapi_offline_version"] = ">=1.7.4" context["uvicorn_version"] = ">=0.41.0" context["lab_auto_pulumi_version"] = ">=0.1.18" @@ -56,7 +56,7 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]: context["python_faker_version"] = ">=40.4.0" ####### context["default_node_version"] = "24.11.1" - context["nuxt_ui_version"] = "^4.4.0" + context["nuxt_ui_version"] = "^4.5.1" context["nuxt_version"] = "^4.3.1" context["nuxt_icon_version"] = "^2.2.1" context["typescript_version"] = "^5.9.3" @@ -84,17 +84,17 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]: context["vue_test_utils_version"] = "^2.4.6" context["nuxt_test_utils_version"] = "3.19.1" context["vue_eslint_parser_version"] = "^10.4.0" - context["happy_dom_version"] = "^20.6.3" + context["happy_dom_version"] = "^20.8.3" context["node_kiota_bundle_version"] = "1.0.0-preview.99" ####### # These are duplicated in the CI files for this repository context["gha_checkout"] = "v6.0.2" context["gha_setup_python"] = "v6.2.0" - context["gha_cache"] = "v5.0.2" + context["gha_cache"] = "v5.0.3" context["gha_linux_runner"] = "ubuntu-24.04" ####### - context["gha_upload_artifact"] = "v6.0.0" - context["gha_download_artifact"] = "v7.0.0" + context["gha_upload_artifact"] = "v7.0.0" + context["gha_download_artifact"] = "v8.0.0" context["gha_github_script"] = "v7.0.1" context["gha_setup_buildx"] = "v3.11.1" context["buildx_version"] = "v0.27.0" diff --git a/template/.devcontainer/devcontainer.json.jinja-base b/template/.devcontainer/devcontainer.json.jinja-base index ac580d72..6998ae94 100644 --- a/template/.devcontainer/devcontainer.json.jinja-base +++ b/template/.devcontainer/devcontainer.json.jinja-base @@ -35,7 +35,7 @@ "-AmazonWebServices.aws-toolkit-vscode", // the AWS CLI feature installs this automatically, but it's causing problems in VS Code{% endraw %}{% endif %}{% raw %} // basic tooling // "eamodio.gitlens@15.5.1", - "coderabbit.coderabbit-vscode@0.18.1", + "coderabbit.coderabbit-vscode@0.18.3", "ms-vscode.live-server@0.5.2025051301", "MS-vsliveshare.vsliveshare@1.0.5905", "github.copilot@1.388.0", diff --git a/template/.devcontainer/on-create-command.sh.jinja-base b/template/.devcontainer/on-create-command.sh.jinja-base index 4614face..19933278 100644 --- a/template/.devcontainer/on-create-command.sh.jinja-base +++ b/template/.devcontainer/on-create-command.sh.jinja-base @@ -12,7 +12,7 @@ repo_root="$(CDPATH= cd -- "$script_dir/.." && pwd)" mkdir -p "$repo_root/.claude" chmod -R ug+rwX "$repo_root/.claude" chgrp -R 0 "$repo_root/.claude" || true -npm --prefix "$repo_root/.claude" install +npm --prefix "$repo_root/.claude" ci # Install beads for use in Claude planning npm install -g @beads/bd@0.57.0 # no specific reason for this version, just pinning for best practice{% endraw %}{% endif %}{% raw %}