From 691df36b30a0e1319e2b02412ba43473ced42966 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 10:38:46 +0000 Subject: [PATCH 01/11] copier --- .claude/settings/permissions/bash.jsonc | 11 ++++++++++- .copier-answers.yml | 2 +- AGENTS.md | 4 +++- template/.claude/settings/permissions/bash.jsonc | 11 ++++++++++- template/AGENTS.md | 4 +++- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/.claude/settings/permissions/bash.jsonc b/.claude/settings/permissions/bash.jsonc index 92caa8a..8fb4d7c 100644 --- a/.claude/settings/permissions/bash.jsonc +++ b/.claude/settings/permissions/bash.jsonc @@ -74,9 +74,15 @@ "Bash(tail *)", // Search "Bash(rg *)", + // Research + "Bash(gh issue list *)", ], "ask": [ - "Bash(gh *)", // let's hold off before we let it use the github CLI in any free running allow mode...I don't want it somehow approving PRs with the user's credentials + // let's hold off before we let it use the github CLI in any free running allow mode...I don't want it somehow approving PRs with the user's credentials + "Bash(gh repo *)", + "Bash(gh release *)", + "Bash(gh secret *)", + "Bash(gh ruleset *)", "Bash(aws *)", // let's hold off before we let it use AWS CLI in any free running allow mode. We need to be very sure we don't have any access to staging or production credentials in our dev environment (...which we shouldn't...but we need to double check that or consider any other safeguards first) "Bash(curl *)", "Bash(ln *)", @@ -85,6 +91,9 @@ "deny": [ // Exceptions to generally allowed AI tooling "Bash(bd init*)", // we need to control the init process, don't let AI do that in the background + // Github + "Bash(gh pr *)", // Claude should not ever interfere with the PR process, that is how we gate AI's work + // Destructive File Operations "Bash(chmod -R *)", "Bash(chown -R *)", diff --git a/.copier-answers.yml b/.copier-answers.yml index aba944f..4aba8f4 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: v0.0.107 +_commit: v0.0.107-3-g2ae229c _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Template for creating a Static Website using Nuxt frontend hosted on AWS diff --git a/AGENTS.md b/AGENTS.md index 115db42..a24a7ef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,7 +17,8 @@ This project is a Copier template used to generate other copier templates. It is ## Testing -- Always run tests with an explicit path (e.g. uv run pytest tests/unit) — test runners discover all types by default. +- Always run tests with an explicit path (e.g. uv run pytest tests/unit) — test runners discover all types (unit, integration, E2E...) by default. +- When iterating on a single test, run that test in isolation first and confirm it is in the expected state (red or green) before widening to the full suite. Use the most targeted invocation available: a specific test function for Python (e.g. `uv run pytest path/to/test.py::test_name --no-cov`) or a file path and name filter for TypeScript (e.g. `pnpm test-unit -- path/to/test.spec.ts -t "test name" --no-coverage`). Only run the full suite once the target test behaves as expected. - Test coverage requirements are usually at 100%, so when running a subset of tests, always disable test coverage to avoid the test run failing for insufficient coverage. - 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. For enums, pick randomly rather than hardcoding one value. @@ -31,6 +32,7 @@ This project is a Copier template used to generate other copier templates. It is - When a test needs a fixture only for its side effects (not its return value), use `@pytest.mark.usefixtures(fixture_name.__name__)` instead of adding an unused parameter with a noqa comment - Use `__name__` instead of string literals when referencing functions/methods (e.g., `mocker.patch.object(MyClass, MyClass.method.__name__)`, `pytest.mark.usefixtures(my_fixture.__name__)`). This enables IDE refactoring tools to catch renames. - When using the faker library, prefer the pytest fixture (provided by the faker library) over instantiating instances of Faker. +- **Choosing between cassettes and mocks:** At the layer that directly wraps an external API or service, strongly prefer VCR cassette-recorded interactions (via pytest-recording/vcrpy) — they capture real HTTP traffic and verify the wire format, catching integration issues that mocks would miss. At layers above that (e.g. business logic, route handlers), mock the wrapper layer instead (e.g. `mocker.patch.object(ThresholdsRepository, ...)`) — there is no value in re-testing the HTTP interaction from higher up. - **Never hand-write VCR cassette YAML files.** Cassettes must be recorded from real HTTP interactions by running the test once with `--record-mode=once` against a live external service: `uv run pytest --record-mode=once --no-cov`. The default mode is `none` — a missing cassette will cause an error, which is expected until recorded. - **Never hand-edit syrupy snapshot files.** Snapshots are auto-generated — to create or update them, run `uv run pytest --snapshot-update --no-cov`. A missing snapshot causes the test to fail, which is expected until you run with `--snapshot-update`. When a snapshot mismatch occurs, fix the code if the change was unintentional; run `--snapshot-update` if it was intentional. - **Never hand-write or hand-edit pytest-reserial `.jsonl` recording files.** Recordings must be captured from real serial port traffic by running the test with `--record` while the device is connected: `uv run pytest --record --no-cov`. The default mode replays recordings — a missing recording causes an error, which is expected until recorded against a live device. diff --git a/template/.claude/settings/permissions/bash.jsonc b/template/.claude/settings/permissions/bash.jsonc index 92caa8a..8fb4d7c 100644 --- a/template/.claude/settings/permissions/bash.jsonc +++ b/template/.claude/settings/permissions/bash.jsonc @@ -74,9 +74,15 @@ "Bash(tail *)", // Search "Bash(rg *)", + // Research + "Bash(gh issue list *)", ], "ask": [ - "Bash(gh *)", // let's hold off before we let it use the github CLI in any free running allow mode...I don't want it somehow approving PRs with the user's credentials + // let's hold off before we let it use the github CLI in any free running allow mode...I don't want it somehow approving PRs with the user's credentials + "Bash(gh repo *)", + "Bash(gh release *)", + "Bash(gh secret *)", + "Bash(gh ruleset *)", "Bash(aws *)", // let's hold off before we let it use AWS CLI in any free running allow mode. We need to be very sure we don't have any access to staging or production credentials in our dev environment (...which we shouldn't...but we need to double check that or consider any other safeguards first) "Bash(curl *)", "Bash(ln *)", @@ -85,6 +91,9 @@ "deny": [ // Exceptions to generally allowed AI tooling "Bash(bd init*)", // we need to control the init process, don't let AI do that in the background + // Github + "Bash(gh pr *)", // Claude should not ever interfere with the PR process, that is how we gate AI's work + // Destructive File Operations "Bash(chmod -R *)", "Bash(chown -R *)", diff --git a/template/AGENTS.md b/template/AGENTS.md index 115db42..a24a7ef 100644 --- a/template/AGENTS.md +++ b/template/AGENTS.md @@ -17,7 +17,8 @@ This project is a Copier template used to generate other copier templates. It is ## Testing -- Always run tests with an explicit path (e.g. uv run pytest tests/unit) — test runners discover all types by default. +- Always run tests with an explicit path (e.g. uv run pytest tests/unit) — test runners discover all types (unit, integration, E2E...) by default. +- When iterating on a single test, run that test in isolation first and confirm it is in the expected state (red or green) before widening to the full suite. Use the most targeted invocation available: a specific test function for Python (e.g. `uv run pytest path/to/test.py::test_name --no-cov`) or a file path and name filter for TypeScript (e.g. `pnpm test-unit -- path/to/test.spec.ts -t "test name" --no-coverage`). Only run the full suite once the target test behaves as expected. - Test coverage requirements are usually at 100%, so when running a subset of tests, always disable test coverage to avoid the test run failing for insufficient coverage. - 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. For enums, pick randomly rather than hardcoding one value. @@ -31,6 +32,7 @@ This project is a Copier template used to generate other copier templates. It is - When a test needs a fixture only for its side effects (not its return value), use `@pytest.mark.usefixtures(fixture_name.__name__)` instead of adding an unused parameter with a noqa comment - Use `__name__` instead of string literals when referencing functions/methods (e.g., `mocker.patch.object(MyClass, MyClass.method.__name__)`, `pytest.mark.usefixtures(my_fixture.__name__)`). This enables IDE refactoring tools to catch renames. - When using the faker library, prefer the pytest fixture (provided by the faker library) over instantiating instances of Faker. +- **Choosing between cassettes and mocks:** At the layer that directly wraps an external API or service, strongly prefer VCR cassette-recorded interactions (via pytest-recording/vcrpy) — they capture real HTTP traffic and verify the wire format, catching integration issues that mocks would miss. At layers above that (e.g. business logic, route handlers), mock the wrapper layer instead (e.g. `mocker.patch.object(ThresholdsRepository, ...)`) — there is no value in re-testing the HTTP interaction from higher up. - **Never hand-write VCR cassette YAML files.** Cassettes must be recorded from real HTTP interactions by running the test once with `--record-mode=once` against a live external service: `uv run pytest --record-mode=once --no-cov`. The default mode is `none` — a missing cassette will cause an error, which is expected until recorded. - **Never hand-edit syrupy snapshot files.** Snapshots are auto-generated — to create or update them, run `uv run pytest --snapshot-update --no-cov`. A missing snapshot causes the test to fail, which is expected until you run with `--snapshot-update`. When a snapshot mismatch occurs, fix the code if the change was unintentional; run `--snapshot-update` if it was intentional. - **Never hand-write or hand-edit pytest-reserial `.jsonl` recording files.** Recordings must be captured from real serial port traffic by running the test with `--record` while the device is connected: `uv run pytest --record --no-cov`. The default mode replays recordings — a missing recording causes an error, which is expected until recorded against a live device. From 7f86fc9643a8e6568b1bbc270d189d868dff7467 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 10:42:55 +0000 Subject: [PATCH 02/11] precommit --- .copier-answers.yml | 2 +- .devcontainer/devcontainer.json | 2 +- .devcontainer/manual-setup-deps.py | 16 ++++++++++++++++ .github/actions/install_deps/action.yml | 7 ++++++- .github/workflows/pre-commit.yaml | 1 + template/.devcontainer/manual-setup-deps.py | 16 ++++++++++++++++ template/.github/actions/install_deps/action.yml | 7 ++++++- template/.github/workflows/pre-commit.yaml | 1 + 8 files changed, 48 insertions(+), 4 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index 4aba8f4..321a823 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: v0.0.107-3-g2ae229c +_commit: v0.0.107-6-g4da21c7 _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Template for creating a Static Website using Nuxt frontend hosted on AWS diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3aa3314..accb952 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -65,5 +65,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): ae7229d4 # spellchecker:disable-line + // Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): 8982d671 # spellchecker:disable-line } diff --git a/.devcontainer/manual-setup-deps.py b/.devcontainer/manual-setup-deps.py index 6f6fe0d..3035d63 100644 --- a/.devcontainer/manual-setup-deps.py +++ b/.devcontainer/manual-setup-deps.py @@ -44,6 +44,12 @@ default=False, help="Allow uv to install new versions of Python on the fly. This is typically only needed when instantiating the copier template.", ) +_ = parser.add_argument( + "--skip-installing-pulumi-cli", + action="store_true", + default=False, + help="Do not install the Pulumi CLI even if the lock file references it", +) class PackageManager(str, enum.Enum): @@ -127,6 +133,16 @@ def main(): check=True, env=uv_env, ) + if ( + not args.skip_installing_pulumi_cli + and platform.system() == "Linux" + and env.lock_file.exists() + and '"pulumi"' in env.lock_file.read_text() + ): + _ = subprocess.run( + ["sh", str(REPO_ROOT_DIR / ".devcontainer" / "install-pulumi-cli.sh"), str(env.lock_file)], + check=True, + ) elif env.package_manager == PackageManager.PNPM: pnpm_command = ["pnpm", "install", "--dir", str(env.path)] if env_check_lock: diff --git a/.github/actions/install_deps/action.yml b/.github/actions/install_deps/action.yml index 0cedd63..27e3fc4 100644 --- a/.github/actions/install_deps/action.yml +++ b/.github/actions/install_deps/action.yml @@ -44,6 +44,11 @@ inputs: description: Whether to skip updating the hash when running manual-setup-deps.py default: true required: false + skip-installing-pulumi-cli: + type: boolean + description: Whether to skip installing the Pulumi CLI even if the lock file references it + default: true + required: false runs: @@ -83,5 +88,5 @@ runs: - name: Install dependencies # the funky syntax is github action ternary if: ${{ inputs.install-deps }} - run: python .devcontainer/manual-setup-deps.py ${{ inputs.python-version == 'notUsing' && '--no-python' || '' }} ${{ inputs.node-version == 'notUsing' && '--no-node' || '' }} ${{ inputs.skip-updating-devcontainer-hash && '--skip-updating-devcontainer-hash' || '' }} + run: python .devcontainer/manual-setup-deps.py ${{ inputs.python-version == 'notUsing' && '--no-python' || '' }} ${{ inputs.node-version == 'notUsing' && '--no-node' || '' }} ${{ inputs.skip-updating-devcontainer-hash && '--skip-updating-devcontainer-hash' || '' }} ${{ inputs.skip-installing-pulumi-cli && '--skip-installing-pulumi-cli' || '' }} shell: pwsh diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index ffeb948..fbdeb86 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -50,6 +50,7 @@ jobs: python-version: ${{ inputs.python-version }} node-version: ${{ inputs.node-version }} skip-installing-ssm-plugin-manager: true + skip-installing-pulumi-cli: true - name: Set up mutex # Github concurrency management is horrible, things get arbitrarily cancelled if queued up. So using mutex until github fixes itself. When multiple jobs are modifying cache at once, weird things can happen. possible issue is https://github.com/actions/toolkit/issues/658 if: ${{ runner.os != 'Windows' }} # we're just gonna have to YOLO on Windows, because this action doesn't support it yet https://github.com/ben-z/gh-action-mutex/issues/14 diff --git a/template/.devcontainer/manual-setup-deps.py b/template/.devcontainer/manual-setup-deps.py index 6f6fe0d..3035d63 100644 --- a/template/.devcontainer/manual-setup-deps.py +++ b/template/.devcontainer/manual-setup-deps.py @@ -44,6 +44,12 @@ default=False, help="Allow uv to install new versions of Python on the fly. This is typically only needed when instantiating the copier template.", ) +_ = parser.add_argument( + "--skip-installing-pulumi-cli", + action="store_true", + default=False, + help="Do not install the Pulumi CLI even if the lock file references it", +) class PackageManager(str, enum.Enum): @@ -127,6 +133,16 @@ def main(): check=True, env=uv_env, ) + if ( + not args.skip_installing_pulumi_cli + and platform.system() == "Linux" + and env.lock_file.exists() + and '"pulumi"' in env.lock_file.read_text() + ): + _ = subprocess.run( + ["sh", str(REPO_ROOT_DIR / ".devcontainer" / "install-pulumi-cli.sh"), str(env.lock_file)], + check=True, + ) elif env.package_manager == PackageManager.PNPM: pnpm_command = ["pnpm", "install", "--dir", str(env.path)] if env_check_lock: diff --git a/template/.github/actions/install_deps/action.yml b/template/.github/actions/install_deps/action.yml index 0cedd63..27e3fc4 100644 --- a/template/.github/actions/install_deps/action.yml +++ b/template/.github/actions/install_deps/action.yml @@ -44,6 +44,11 @@ inputs: description: Whether to skip updating the hash when running manual-setup-deps.py default: true required: false + skip-installing-pulumi-cli: + type: boolean + description: Whether to skip installing the Pulumi CLI even if the lock file references it + default: true + required: false runs: @@ -83,5 +88,5 @@ runs: - name: Install dependencies # the funky syntax is github action ternary if: ${{ inputs.install-deps }} - run: python .devcontainer/manual-setup-deps.py ${{ inputs.python-version == 'notUsing' && '--no-python' || '' }} ${{ inputs.node-version == 'notUsing' && '--no-node' || '' }} ${{ inputs.skip-updating-devcontainer-hash && '--skip-updating-devcontainer-hash' || '' }} + run: python .devcontainer/manual-setup-deps.py ${{ inputs.python-version == 'notUsing' && '--no-python' || '' }} ${{ inputs.node-version == 'notUsing' && '--no-node' || '' }} ${{ inputs.skip-updating-devcontainer-hash && '--skip-updating-devcontainer-hash' || '' }} ${{ inputs.skip-installing-pulumi-cli && '--skip-installing-pulumi-cli' || '' }} shell: pwsh diff --git a/template/.github/workflows/pre-commit.yaml b/template/.github/workflows/pre-commit.yaml index ffeb948..fbdeb86 100644 --- a/template/.github/workflows/pre-commit.yaml +++ b/template/.github/workflows/pre-commit.yaml @@ -50,6 +50,7 @@ jobs: python-version: ${{ inputs.python-version }} node-version: ${{ inputs.node-version }} skip-installing-ssm-plugin-manager: true + skip-installing-pulumi-cli: true - name: Set up mutex # Github concurrency management is horrible, things get arbitrarily cancelled if queued up. So using mutex until github fixes itself. When multiple jobs are modifying cache at once, weird things can happen. possible issue is https://github.com/actions/toolkit/issues/658 if: ${{ runner.os != 'Windows' }} # we're just gonna have to YOLO on Windows, because this action doesn't support it yet https://github.com/ben-z/gh-action-mutex/issues/14 From efdfd26eb96bcd8ba2164e3823ea4097954d1a88 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 10:45:26 +0000 Subject: [PATCH 03/11] redame --- template/README.md.jinja | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/template/README.md.jinja b/template/README.md.jinja index 5b378f3..5b0e207 100644 --- a/template/README.md.jinja +++ b/template/README.md.jinja @@ -8,8 +8,13 @@ # Development +## Frontend +- To start a local development server (accessible at localhost:3000): `pnpm --dir={% endraw %}{{ app_name }}_app{% raw %} dev` +- To generate the production build to prepare for deployment to the cloud: `pnpm --dir={% endraw %}{{ app_name }}_app{% raw %} generate` + ## Infrastructure Deployments Run a Pulumi Preview: `uv --directory=./infrastructure run python -m infrastructure.pulumi_deploy --stack=dev` +Deploy the dev stack: `uv --directory=./infrastructure run python -m infrastructure.pulumi_deploy --stack=dev --up` ## Updating from the template From 044b086895a71346621962126b222d2e15ef1792 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 10:48:26 +0000 Subject: [PATCH 04/11] ci --- template/.github/workflows/ci.yaml.jinja | 1 + 1 file changed, 1 insertion(+) diff --git a/template/.github/workflows/ci.yaml.jinja b/template/.github/workflows/ci.yaml.jinja index cc38169..78ec69b 100644 --- a/template/.github/workflows/ci.yaml.jinja +++ b/template/.github/workflows/ci.yaml.jinja @@ -65,6 +65,7 @@ jobs: with: node-version: {% endraw %}{{ node_version }}{% raw %} skip-installing-ssm-plugin-manager: true + skip-installing-pulumi-cli: true - name: Build frontend run: pnpm --dir={% endraw %}{{ app_name }}{% raw %}_app generate From 2f6ff4b555f643e7e4e2a6d186d2c3d4267c4616 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 10:49:19 +0000 Subject: [PATCH 05/11] comment --- .copier-answers.yml | 2 +- template/.github/workflows/pulumi-aws.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index 321a823..c47d66d 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: v0.0.107-6-g4da21c7 +_commit: v0.0.107-7-g6819bcf _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Template for creating a Static Website using Nuxt frontend hosted on AWS diff --git a/template/.github/workflows/pulumi-aws.yml b/template/.github/workflows/pulumi-aws.yml index e4481dd..3ce9e46 100644 --- a/template/.github/workflows/pulumi-aws.yml +++ b/template/.github/workflows/pulumi-aws.yml @@ -122,6 +122,7 @@ jobs: uses: ./.github/actions/install_deps with: python-version: ${{ inputs.PYTHON_VERSION }} + skip-installing-pulumi-cli: true # at the moment, we're more specifically installing the Pulumi CLI just in the target direction inside the pulumi_ephemeral_deploy action - name: Download Artifact uses: actions/download-artifact@v8.0.0 From d5c1cb6ace2b66affa24edcac654dedac8be84c6 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 11:09:58 +0000 Subject: [PATCH 06/11] More agents --- .claude/settings/permissions/bash.jsonc | 10 +++++++++- .copier-answers.yml | 2 +- .devcontainer/devcontainer.json | 2 +- .devcontainer/manual-setup-deps.py | 3 ++- AGENTS.md | 1 + template/.claude/settings/permissions/bash.jsonc | 10 +++++++++- template/.devcontainer/manual-setup-deps.py | 3 ++- template/AGENTS.md | 1 + 8 files changed, 26 insertions(+), 6 deletions(-) diff --git a/.claude/settings/permissions/bash.jsonc b/.claude/settings/permissions/bash.jsonc index 8fb4d7c..a6dca2c 100644 --- a/.claude/settings/permissions/bash.jsonc +++ b/.claude/settings/permissions/bash.jsonc @@ -76,6 +76,8 @@ "Bash(rg *)", // Research "Bash(gh issue list *)", + "Bash(gh pr view *)", + "Bash(gh pr diff *)" ], "ask": [ // let's hold off before we let it use the github CLI in any free running allow mode...I don't want it somehow approving PRs with the user's credentials @@ -92,7 +94,13 @@ // Exceptions to generally allowed AI tooling "Bash(bd init*)", // we need to control the init process, don't let AI do that in the background // Github - "Bash(gh pr *)", // Claude should not ever interfere with the PR process, that is how we gate AI's work + // Claude should not ever interfere with the PR process, that is how we gate AI's work + "Bash(gh pr create *)", + "Bash(gh pr edit *)", + "Bash(gh pr ready *)", + "Bash(gh pr review *)", + "Bash(gh pr merge *)", + "Bash(gh pr close *)", // Destructive File Operations "Bash(chmod -R *)", diff --git a/.copier-answers.yml b/.copier-answers.yml index c47d66d..1169ba8 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: v0.0.107-7-g6819bcf +_commit: v0.0.107-9-g7dc142b _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Template for creating a Static Website using Nuxt frontend hosted on AWS diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index accb952..9f30e86 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -65,5 +65,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): 8982d671 # spellchecker:disable-line + // Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): afefe4b2 # spellchecker:disable-line } diff --git a/.devcontainer/manual-setup-deps.py b/.devcontainer/manual-setup-deps.py index 3035d63..53e59e1 100644 --- a/.devcontainer/manual-setup-deps.py +++ b/.devcontainer/manual-setup-deps.py @@ -134,7 +134,8 @@ def main(): env=uv_env, ) if ( - not args.skip_installing_pulumi_cli + not generate_lock_file_only + and not args.skip_installing_pulumi_cli and platform.system() == "Linux" and env.lock_file.exists() and '"pulumi"' in env.lock_file.read_text() diff --git a/AGENTS.md b/AGENTS.md index a24a7ef..713b9c9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -52,6 +52,7 @@ This project is a Copier template used to generate other copier templates. It is - For linting and type-checking, prefer `pre-commit run ` over invoking tools directly — this matches the permission allow-list and mirrors what CI runs. Key hook IDs: `typescript-check`, `eslint`, `pyright`, `ruff`, `ruff-format`. - Never rely on IDE diagnostics for ruff warnings — the IDE may not respect the project's ruff.toml config. Run `pre-commit run ruff -a` to get accurate results. - When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use absolute paths instead of `cd` to avoid needing to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts +- Never use `pnpm --prefix ` or `uv --directory ` to target a different directory — these flags break the permission allow-list matcher the same way chained `cd &&` commands do. Instead, rely on the working directory already being correct (the cwd persists between Bash tool calls), or issue a plain `cd ` as a separate prior tool call to reposition before running the command. - Never use backslash line continuations in shell commands — always write the full command on a single line. Backslashes break the permission allow-list matcher. - **Never manually edit files in any `generated/` folder.** These files are produced by codegen tooling (typically Kiota) and any manual changes will be overwritten. If a generated file needs to change, update the source (e.g. the OpenAPI schema) and re-run the generator. diff --git a/template/.claude/settings/permissions/bash.jsonc b/template/.claude/settings/permissions/bash.jsonc index 8fb4d7c..a6dca2c 100644 --- a/template/.claude/settings/permissions/bash.jsonc +++ b/template/.claude/settings/permissions/bash.jsonc @@ -76,6 +76,8 @@ "Bash(rg *)", // Research "Bash(gh issue list *)", + "Bash(gh pr view *)", + "Bash(gh pr diff *)" ], "ask": [ // let's hold off before we let it use the github CLI in any free running allow mode...I don't want it somehow approving PRs with the user's credentials @@ -92,7 +94,13 @@ // Exceptions to generally allowed AI tooling "Bash(bd init*)", // we need to control the init process, don't let AI do that in the background // Github - "Bash(gh pr *)", // Claude should not ever interfere with the PR process, that is how we gate AI's work + // Claude should not ever interfere with the PR process, that is how we gate AI's work + "Bash(gh pr create *)", + "Bash(gh pr edit *)", + "Bash(gh pr ready *)", + "Bash(gh pr review *)", + "Bash(gh pr merge *)", + "Bash(gh pr close *)", // Destructive File Operations "Bash(chmod -R *)", diff --git a/template/.devcontainer/manual-setup-deps.py b/template/.devcontainer/manual-setup-deps.py index 3035d63..53e59e1 100644 --- a/template/.devcontainer/manual-setup-deps.py +++ b/template/.devcontainer/manual-setup-deps.py @@ -134,7 +134,8 @@ def main(): env=uv_env, ) if ( - not args.skip_installing_pulumi_cli + not generate_lock_file_only + and not args.skip_installing_pulumi_cli and platform.system() == "Linux" and env.lock_file.exists() and '"pulumi"' in env.lock_file.read_text() diff --git a/template/AGENTS.md b/template/AGENTS.md index a24a7ef..713b9c9 100644 --- a/template/AGENTS.md +++ b/template/AGENTS.md @@ -52,6 +52,7 @@ This project is a Copier template used to generate other copier templates. It is - For linting and type-checking, prefer `pre-commit run ` over invoking tools directly — this matches the permission allow-list and mirrors what CI runs. Key hook IDs: `typescript-check`, `eslint`, `pyright`, `ruff`, `ruff-format`. - Never rely on IDE diagnostics for ruff warnings — the IDE may not respect the project's ruff.toml config. Run `pre-commit run ruff -a` to get accurate results. - When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use absolute paths instead of `cd` to avoid needing to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts +- Never use `pnpm --prefix ` or `uv --directory ` to target a different directory — these flags break the permission allow-list matcher the same way chained `cd &&` commands do. Instead, rely on the working directory already being correct (the cwd persists between Bash tool calls), or issue a plain `cd ` as a separate prior tool call to reposition before running the command. - Never use backslash line continuations in shell commands — always write the full command on a single line. Backslashes break the permission allow-list matcher. - **Never manually edit files in any `generated/` folder.** These files are produced by codegen tooling (typically Kiota) and any manual changes will be overwritten. If a generated file needs to change, update the source (e.g. the OpenAPI schema) and re-run the generator. From 4b5ab52aae78b92a3c85d5e3b8f88b248c2ebe38 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 12:32:03 +0000 Subject: [PATCH 07/11] whitespace --- .copier-answers.yml | 2 +- AGENTS.md | 4 ++-- template/AGENTS.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index 1169ba8..fb4abbe 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: v0.0.107-9-g7dc142b +_commit: v0.0.107-10-g469f0ce _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Template for creating a Static Website using Nuxt frontend hosted on AWS diff --git a/AGENTS.md b/AGENTS.md index 713b9c9..bee931c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -18,7 +18,7 @@ This project is a Copier template used to generate other copier templates. It is ## Testing - Always run tests with an explicit path (e.g. uv run pytest tests/unit) — test runners discover all types (unit, integration, E2E...) by default. -- When iterating on a single test, run that test in isolation first and confirm it is in the expected state (red or green) before widening to the full suite. Use the most targeted invocation available: a specific test function for Python (e.g. `uv run pytest path/to/test.py::test_name --no-cov`) or a file path and name filter for TypeScript (e.g. `pnpm test-unit -- path/to/test.spec.ts -t "test name" --no-coverage`). Only run the full suite once the target test behaves as expected. +- When iterating on a single test, run that test in isolation first and confirm it is in the expected state (red or green) before widening to the full suite. Use the most targeted invocation available: a specific test function for Python (e.g. `uv run pytest path/to/test.py::test_name --no-cov`) or a file path and name filter for TypeScript (e.g. `pnpm test-unit -- path/to/test.spec.ts -t "test name" --no-coverage`). Only run the full suite once the target test behaves as expected. - Test coverage requirements are usually at 100%, so when running a subset of tests, always disable test coverage to avoid the test run failing for insufficient coverage. - 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. For enums, pick randomly rather than hardcoding one value. @@ -27,7 +27,7 @@ This project is a Copier template used to generate other copier templates. It is ### 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)` +- 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` - When a test needs a fixture only for its side effects (not its return value), use `@pytest.mark.usefixtures(fixture_name.__name__)` instead of adding an unused parameter with a noqa comment - Use `__name__` instead of string literals when referencing functions/methods (e.g., `mocker.patch.object(MyClass, MyClass.method.__name__)`, `pytest.mark.usefixtures(my_fixture.__name__)`). This enables IDE refactoring tools to catch renames. diff --git a/template/AGENTS.md b/template/AGENTS.md index 713b9c9..bee931c 100644 --- a/template/AGENTS.md +++ b/template/AGENTS.md @@ -18,7 +18,7 @@ This project is a Copier template used to generate other copier templates. It is ## Testing - Always run tests with an explicit path (e.g. uv run pytest tests/unit) — test runners discover all types (unit, integration, E2E...) by default. -- When iterating on a single test, run that test in isolation first and confirm it is in the expected state (red or green) before widening to the full suite. Use the most targeted invocation available: a specific test function for Python (e.g. `uv run pytest path/to/test.py::test_name --no-cov`) or a file path and name filter for TypeScript (e.g. `pnpm test-unit -- path/to/test.spec.ts -t "test name" --no-coverage`). Only run the full suite once the target test behaves as expected. +- When iterating on a single test, run that test in isolation first and confirm it is in the expected state (red or green) before widening to the full suite. Use the most targeted invocation available: a specific test function for Python (e.g. `uv run pytest path/to/test.py::test_name --no-cov`) or a file path and name filter for TypeScript (e.g. `pnpm test-unit -- path/to/test.spec.ts -t "test name" --no-coverage`). Only run the full suite once the target test behaves as expected. - Test coverage requirements are usually at 100%, so when running a subset of tests, always disable test coverage to avoid the test run failing for insufficient coverage. - 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. For enums, pick randomly rather than hardcoding one value. @@ -27,7 +27,7 @@ This project is a Copier template used to generate other copier templates. It is ### 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)` +- 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` - When a test needs a fixture only for its side effects (not its return value), use `@pytest.mark.usefixtures(fixture_name.__name__)` instead of adding an unused parameter with a noqa comment - Use `__name__` instead of string literals when referencing functions/methods (e.g., `mocker.patch.object(MyClass, MyClass.method.__name__)`, `pytest.mark.usefixtures(my_fixture.__name__)`). This enables IDE refactoring tools to catch renames. From 844c131a180af203ddb884d699b8f0bbeeaae6f8 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 12:37:57 +0000 Subject: [PATCH 08/11] reconcile --- .copier-answers.yml | 2 +- AGENTS.md | 2 +- template/AGENTS.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index fb4abbe..259e2d8 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: v0.0.107-10-g469f0ce +_commit: v0.0.107-11-g23e880f _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Template for creating a Static Website using Nuxt frontend hosted on AWS diff --git a/AGENTS.md b/AGENTS.md index bee931c..bf9870e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,7 +51,7 @@ This project is a Copier template used to generate other copier templates. It is - For frontend tests, run commands via `pnpm` scripts from `frontend/package.json` — never invoke tools directly (not pnpm exec , npx , etc.). ✅ pnpm test-unit ❌ pnpm vitest ... or npx vitest ... - For linting and type-checking, prefer `pre-commit run ` over invoking tools directly — this matches the permission allow-list and mirrors what CI runs. Key hook IDs: `typescript-check`, `eslint`, `pyright`, `ruff`, `ruff-format`. - Never rely on IDE diagnostics for ruff warnings — the IDE may not respect the project's ruff.toml config. Run `pre-commit run ruff -a` to get accurate results. -- When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use absolute paths instead of `cd` to avoid needing to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts +- When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use `cd` to change to the directory you want before running the command, avaiding the need to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts - Never use `pnpm --prefix ` or `uv --directory ` to target a different directory — these flags break the permission allow-list matcher the same way chained `cd &&` commands do. Instead, rely on the working directory already being correct (the cwd persists between Bash tool calls), or issue a plain `cd ` as a separate prior tool call to reposition before running the command. - Never use backslash line continuations in shell commands — always write the full command on a single line. Backslashes break the permission allow-list matcher. - **Never manually edit files in any `generated/` folder.** These files are produced by codegen tooling (typically Kiota) and any manual changes will be overwritten. If a generated file needs to change, update the source (e.g. the OpenAPI schema) and re-run the generator. diff --git a/template/AGENTS.md b/template/AGENTS.md index bee931c..bf9870e 100644 --- a/template/AGENTS.md +++ b/template/AGENTS.md @@ -51,7 +51,7 @@ This project is a Copier template used to generate other copier templates. It is - For frontend tests, run commands via `pnpm` scripts from `frontend/package.json` — never invoke tools directly (not pnpm exec , npx , etc.). ✅ pnpm test-unit ❌ pnpm vitest ... or npx vitest ... - For linting and type-checking, prefer `pre-commit run ` over invoking tools directly — this matches the permission allow-list and mirrors what CI runs. Key hook IDs: `typescript-check`, `eslint`, `pyright`, `ruff`, `ruff-format`. - Never rely on IDE diagnostics for ruff warnings — the IDE may not respect the project's ruff.toml config. Run `pre-commit run ruff -a` to get accurate results. -- When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use absolute paths instead of `cd` to avoid needing to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts +- When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use `cd` to change to the directory you want before running the command, avaiding the need to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts - Never use `pnpm --prefix ` or `uv --directory ` to target a different directory — these flags break the permission allow-list matcher the same way chained `cd &&` commands do. Instead, rely on the working directory already being correct (the cwd persists between Bash tool calls), or issue a plain `cd ` as a separate prior tool call to reposition before running the command. - Never use backslash line continuations in shell commands — always write the full command on a single line. Backslashes break the permission allow-list matcher. - **Never manually edit files in any `generated/` folder.** These files are produced by codegen tooling (typically Kiota) and any manual changes will be overwritten. If a generated file needs to change, update the source (e.g. the OpenAPI schema) and re-run the generator. From b0b972d1ff90dca09c65579148cab8bf26806627 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 12:40:30 +0000 Subject: [PATCH 09/11] phrasing --- .claude/settings/permissions/bash.jsonc | 2 ++ .copier-answers.yml | 2 +- template/.claude/settings/permissions/bash.jsonc | 2 ++ template/.github/workflows/pulumi-aws.yml | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.claude/settings/permissions/bash.jsonc b/.claude/settings/permissions/bash.jsonc index a6dca2c..bdf2771 100644 --- a/.claude/settings/permissions/bash.jsonc +++ b/.claude/settings/permissions/bash.jsonc @@ -101,6 +101,8 @@ "Bash(gh pr review *)", "Bash(gh pr merge *)", "Bash(gh pr close *)", + "Bash(gh pr comment *)", + "Bash(gh pr update-branch *)", // Destructive File Operations "Bash(chmod -R *)", diff --git a/.copier-answers.yml b/.copier-answers.yml index 259e2d8..43b9a55 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: v0.0.107-11-g23e880f +_commit: v0.0.107-13-gf0905e6 _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Template for creating a Static Website using Nuxt frontend hosted on AWS diff --git a/template/.claude/settings/permissions/bash.jsonc b/template/.claude/settings/permissions/bash.jsonc index a6dca2c..bdf2771 100644 --- a/template/.claude/settings/permissions/bash.jsonc +++ b/template/.claude/settings/permissions/bash.jsonc @@ -101,6 +101,8 @@ "Bash(gh pr review *)", "Bash(gh pr merge *)", "Bash(gh pr close *)", + "Bash(gh pr comment *)", + "Bash(gh pr update-branch *)", // Destructive File Operations "Bash(chmod -R *)", diff --git a/template/.github/workflows/pulumi-aws.yml b/template/.github/workflows/pulumi-aws.yml index 3ce9e46..a170e08 100644 --- a/template/.github/workflows/pulumi-aws.yml +++ b/template/.github/workflows/pulumi-aws.yml @@ -122,7 +122,7 @@ jobs: uses: ./.github/actions/install_deps with: python-version: ${{ inputs.PYTHON_VERSION }} - skip-installing-pulumi-cli: true # at the moment, we're more specifically installing the Pulumi CLI just in the target direction inside the pulumi_ephemeral_deploy action + skip-installing-pulumi-cli: true # at the moment, we're more specifically installing the Pulumi CLI just in the target directory inside the pulumi_ephemeral_deploy action - name: Download Artifact uses: actions/download-artifact@v8.0.0 From 7a3bd82cf7ba9b65d938cc5d4e8c79d7fc80036d Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 12:49:20 +0000 Subject: [PATCH 10/11] typo --- .copier-answers.yml | 2 +- AGENTS.md | 2 +- template/AGENTS.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index 43b9a55..d38f205 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: v0.0.107-13-gf0905e6 +_commit: v0.0.107-14-g53495f3 _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Template for creating a Static Website using Nuxt frontend hosted on AWS diff --git a/AGENTS.md b/AGENTS.md index bf9870e..6c9e9f6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,7 +51,7 @@ This project is a Copier template used to generate other copier templates. It is - For frontend tests, run commands via `pnpm` scripts from `frontend/package.json` — never invoke tools directly (not pnpm exec , npx , etc.). ✅ pnpm test-unit ❌ pnpm vitest ... or npx vitest ... - For linting and type-checking, prefer `pre-commit run ` over invoking tools directly — this matches the permission allow-list and mirrors what CI runs. Key hook IDs: `typescript-check`, `eslint`, `pyright`, `ruff`, `ruff-format`. - Never rely on IDE diagnostics for ruff warnings — the IDE may not respect the project's ruff.toml config. Run `pre-commit run ruff -a` to get accurate results. -- When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use `cd` to change to the directory you want before running the command, avaiding the need to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts +- When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use `cd` to change to the directory you want before running the command, avoiding the need to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts - Never use `pnpm --prefix ` or `uv --directory ` to target a different directory — these flags break the permission allow-list matcher the same way chained `cd &&` commands do. Instead, rely on the working directory already being correct (the cwd persists between Bash tool calls), or issue a plain `cd ` as a separate prior tool call to reposition before running the command. - Never use backslash line continuations in shell commands — always write the full command on a single line. Backslashes break the permission allow-list matcher. - **Never manually edit files in any `generated/` folder.** These files are produced by codegen tooling (typically Kiota) and any manual changes will be overwritten. If a generated file needs to change, update the source (e.g. the OpenAPI schema) and re-run the generator. diff --git a/template/AGENTS.md b/template/AGENTS.md index bf9870e..6c9e9f6 100644 --- a/template/AGENTS.md +++ b/template/AGENTS.md @@ -51,7 +51,7 @@ This project is a Copier template used to generate other copier templates. It is - For frontend tests, run commands via `pnpm` scripts from `frontend/package.json` — never invoke tools directly (not pnpm exec , npx , etc.). ✅ pnpm test-unit ❌ pnpm vitest ... or npx vitest ... - For linting and type-checking, prefer `pre-commit run ` over invoking tools directly — this matches the permission allow-list and mirrors what CI runs. Key hook IDs: `typescript-check`, `eslint`, `pyright`, `ruff`, `ruff-format`. - Never rely on IDE diagnostics for ruff warnings — the IDE may not respect the project's ruff.toml config. Run `pre-commit run ruff -a` to get accurate results. -- When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use `cd` to change to the directory you want before running the command, avaiding the need to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts +- When running terminal commands, execute exactly one command per tool call. Do not chain commands with &&, ||, ;, or & — this prohibition has no exceptions, even for `cd && ...` patterns. Use `cd` to change to the directory you want before running the command, avoiding the need to chain. Pipes (|) are allowed for output transformation (e.g., head, tail, grep). If two sequential commands are needed, run them in separate tool calls. Chained commands break the permission allow-list matcher and cause unnecessary permission prompts - Never use `pnpm --prefix ` or `uv --directory ` to target a different directory — these flags break the permission allow-list matcher the same way chained `cd &&` commands do. Instead, rely on the working directory already being correct (the cwd persists between Bash tool calls), or issue a plain `cd ` as a separate prior tool call to reposition before running the command. - Never use backslash line continuations in shell commands — always write the full command on a single line. Backslashes break the permission allow-list matcher. - **Never manually edit files in any `generated/` folder.** These files are produced by codegen tooling (typically Kiota) and any manual changes will be overwritten. If a generated file needs to change, update the source (e.g. the OpenAPI schema) and re-run the generator. From 31ad2c59e4dc9f8b713da05135815d4455e0ea21 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Mon, 30 Mar 2026 16:51:09 +0000 Subject: [PATCH 11/11] tag --- .copier-answers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index d38f205..359c578 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: v0.0.107-14-g53495f3 +_commit: v0.0.108 _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Template for creating a Static Website using Nuxt frontend hosted on AWS