From eb26ad04870bd2a7c7963845b82a1e577dd3d0f6 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Tue, 3 Mar 2026 11:55:37 +0000 Subject: [PATCH 1/9] use ci --- .devcontainer/devcontainer.json | 2 +- .devcontainer/on-create-command.sh | 2 +- extensions/context.py | 2 +- template/.devcontainer/on-create-command.sh.jinja-base | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0185c12c..72178a16 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -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): 24ef7faf # spellchecker:disable-line } 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/extensions/context.py b/extensions/context.py index 9f96b7a8..e6430c5b 100644 --- a/extensions/context.py +++ b/extensions/context.py @@ -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" 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 %} From 52d7afa035cca356809f5434c08785fe18d0ee9b Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 5 Mar 2026 17:34:31 +0000 Subject: [PATCH 2/9] More agent instructinos --- .coderabbit.yaml | 2 +- AGENTS.md | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 9904260d..8df8214d 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: "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. 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/AGENTS.md b/AGENTS.md index 9b62bfc3..c5305378 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. From 5c3baf6c7d2cb8c97c5bb1e7b56f972ce52790bd Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 5 Mar 2026 17:37:25 +0000 Subject: [PATCH 3/9] more rabbit --- .coderabbit.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 8df8214d..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. Do not warn about missing type hints; a pre-commit hook already checks for that." + 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 From 39f0dde17bf41dce9c33817b5b9df4e55910853d Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 5 Mar 2026 21:14:41 +0000 Subject: [PATCH 4/9] fix hook --- .claude/helpers/merge-claude-settings.sh | 3 +++ 1 file changed, 3 insertions(+) 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) } From c78c40c28b133bde8e66638bf7568922a8c2a542 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 5 Mar 2026 21:29:40 +0000 Subject: [PATCH 5/9] uv --- .devcontainer/devcontainer.json | 2 +- .devcontainer/install-ci-tooling.py | 2 +- extensions/context.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 72178a16..b2472bb4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -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): 24ef7faf # 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/extensions/context.py b/extensions/context.py index e6430c5b..8472db6d 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" @@ -84,7 +84,7 @@ 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 From 92b13067a58103bc4dc5b67b08447e38f9450bcf Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 5 Mar 2026 21:30:25 +0000 Subject: [PATCH 6/9] nuxt --- extensions/context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/context.py b/extensions/context.py index 8472db6d..58110d46 100644 --- a/extensions/context.py +++ b/extensions/context.py @@ -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" From 3d313c302ac3d65dd44b1b994311a24d4275c2ac Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 5 Mar 2026 21:31:45 +0000 Subject: [PATCH 7/9] gha --- extensions/context.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/context.py b/extensions/context.py index 58110d46..e928df7f 100644 --- a/extensions/context.py +++ b/extensions/context.py @@ -90,11 +90,11 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]: # 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" From bd9533342f85514de8f5b09815fc31e53c75f262 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 5 Mar 2026 21:34:14 +0000 Subject: [PATCH 8/9] hyphen --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index c5305378..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 (unless a very clear single argument function): 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. From c3fe99f125c9d54519ac04124ad94665b1006b17 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 5 Mar 2026 22:00:38 +0000 Subject: [PATCH 9/9] rabbit --- .devcontainer/devcontainer.json | 2 +- template/.devcontainer/devcontainer.json.jinja-base | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b2472bb4..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", 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",