diff --git a/.claude/.beads/config.yaml b/.claude/.beads/config.yaml index 46b9e82e..5d0ceecc 100644 --- a/.claude/.beads/config.yaml +++ b/.claude/.beads/config.yaml @@ -26,11 +26,6 @@ # Default actor for audit trails (overridden by BD_ACTOR or --actor) # actor: "" -# Export events (audit trail) to .beads/events.jsonl on each flush/sync -# When enabled, new events are appended incrementally using a high-water mark. -# Use 'bd export --events' to trigger manually regardless of this setting. -# events-export: false - # Multi-repo configuration (experimental - bd-307) # Allows hydrating from multiple repositories and routing writes to the correct JSONL # repos: diff --git a/.claude/commands/add-command.md b/.claude/commands/add-command.md index ceb45a2d..23be23eb 100644 --- a/.claude/commands/add-command.md +++ b/.claude/commands/add-command.md @@ -11,7 +11,7 @@ argument-hint: - Write natural, descriptive code without meta-commentary about the development process - The code should speak for itself - TDD is the process, not the product -Beads is available for task tracking. Use `mcp__beads__*` tools to manage issues (the user interacts via `bd` commands). +Beads is available for task tracking. Use `bd` CLI commands to manage issues. ## Plan File Restriction diff --git a/.claude/commands/commit.md b/.claude/commands/commit.md index e40205e9..2ac4ec53 100644 --- a/.claude/commands/commit.md +++ b/.claude/commands/commit.md @@ -11,7 +11,7 @@ argument-hint: [optional-commit-description] - Write natural, descriptive code without meta-commentary about the development process - The code should speak for itself - TDD is the process, not the product -Beads is available for task tracking. Use `mcp__beads__*` tools to manage issues (the user interacts via `bd` commands). +Beads is available for task tracking. Use `bd` CLI commands to manage issues. ## Plan File Restriction diff --git a/.claude/commands/create-adr.md b/.claude/commands/create-adr.md index 68bab708..4b79f296 100644 --- a/.claude/commands/create-adr.md +++ b/.claude/commands/create-adr.md @@ -17,7 +17,7 @@ Create a new ADR to document an architectural decision. ADRs capture the "why" b - Write natural, descriptive code without meta-commentary about the development process - The code should speak for itself - TDD is the process, not the product -Beads is available for task tracking. Use `mcp__beads__*` tools to manage issues (the user interacts via `bd` commands). +Beads is available for task tracking. Use `bd` CLI commands to manage issues. ## Plan File Restriction diff --git a/.claude/commands/create-issues.md b/.claude/commands/create-issues.md index 7c1ec62d..ae37f027 100644 --- a/.claude/commands/create-issues.md +++ b/.claude/commands/create-issues.md @@ -15,7 +15,7 @@ Create structured implementation plan that bridges product thinking (PRD) with t - Write natural, descriptive code without meta-commentary about the development process - The code should speak for itself - TDD is the process, not the product -Beads is available for task tracking. Use `mcp__beads__*` tools to manage issues (the user interacts via `bd` commands). +Beads is available for task tracking. Use `bd` CLI commands to manage issues. ## Plan File Restriction @@ -113,7 +113,7 @@ For each task, create a bd issue with: ```bash bd create "Task title" \ - --type [feature|bug|task|chore] \ + --type [feature|bug|task|epic|chore|decision] \ --priority [1-3] \ --description "Context and what needs to be built" \ --design "Technical approach, architecture notes" \ @@ -149,8 +149,10 @@ bd create "Task title" \ **Dependencies**: Link related issues +The first argument is the issue that becomes blocked; the second is the blocker it waits on. + ```bash -bd dep add ISSUE-123 ISSUE-456 --type blocks +bd dep add --type blocks ``` ### Validation @@ -179,20 +181,20 @@ After creating issues, verify: ### Beads Integration -Use Beads MCP to: +Use the `bd` CLI to: - Track work with `bd ready` to find next task - Create issues with `bd create "description"` - Track dependencies with `bd dep add` -See for more information. +See for more information. ## Integration with Other Commands - **Before /create-issues**: Use `/spike` if you need technical exploration first - **After /create-issues**: Use `/red` to start TDD on first task - **During work**: Use `bd update` to add notes/findings back to issues -- **When stuck**: Check `bd show ISSUE-ID` to review acceptance criteria +- **When stuck**: Check `bd show ` to review acceptance criteria -## Issue Tracking with bd (beads) +## Work Tracking with bd (beads) -**IMPORTANT**: This project uses **bd (beads)** for ALL issue tracking. Do NOT use markdown TODOs, task lists, or other tracking methods. +**IMPORTANT**: Use **bd (beads)** to break down and track your own work while implementing a ticket. Within a working session it is the only place to track that breakdown — do NOT use markdown TODOs, task lists, or other scratch tracking methods. + +bd is not the team's ticket tracker. It is a local tool for a developer and an AI agent working together: `bd init --stealth` adds `.beads/` to `.git/info/exclude`, so neither the database nor its JSONL export is committed, and nothing recorded in bd is visible to reviewers, teammates, or CI. The ticket a session is implementing lives in whatever system the team owning the repository uses — GitHub Issues, Jira, Linear, or something else. ### Why bd? -- Dependency-aware: Track blockers and relationships between issues -- Git-friendly: Auto-syncs to JSONL for version control +- Dependency-aware: Track blockers and relationships between the pieces of work in a session - Agent-optimized: JSON output, ready work detection, discovered-from links -- Prevents duplicate tracking systems and confusion +- Keeps session breakdown out of the team's ticket tracker, and out of the codebase ### Quick Start @@ -115,20 +120,20 @@ bd ready --json ```bash bd create "Issue title" --description="Detailed context" -t bug|feature|task -p 0-4 --json -bd create "Issue title" --description="What this issue is about" -p 1 --deps discovered-from:bd-123 --json +bd create "Issue title" --description="What this issue is about" -p 1 --deps discovered-from: --json ``` **Claim and update:** ```bash -bd update bd-42 --status in_progress --json -bd update bd-42 --priority 1 --json +bd update --status in_progress --json +bd update --priority 1 --json ``` **Complete work:** ```bash -bd close bd-42 --reason "Completed" --json +bd close --reason "Completed" --json ``` **Creating human readable file:** @@ -145,6 +150,7 @@ bd export -o [relative path to repository root]/.claude/.beads/issues-dump.jsonl - `task` - Work item (tests, docs, refactoring) - `epic` - Large feature with subtasks - `chore` - Maintenance (dependencies, tooling) +- `decision` - An architectural decision (aliases: `dec`, `adr`) ### Priorities @@ -166,15 +172,15 @@ bd export -o [relative path to repository root]/.claude/.beads/issues-dump.jsonl ### Important Rules -- ✅ Use bd for ALL task tracking +- ✅ Use bd for ALL tracking of your own work within a session - ✅ Always use `--json` flag for programmatic use - ✅ Link discovered work with `discovered-from` dependencies - ✅ Check `bd ready` before asking "what should I work on?" -- ❌ Do NOT create markdown TODO lists -- ❌ Do NOT use external issue trackers -- ❌ Do NOT duplicate tracking systems +- ❌ Do NOT create markdown TODO lists to track session work +- ❌ Do NOT stand up a second scratch tracking system alongside bd +- ❌ Do NOT propose bd for work that needs tracking beyond the session — a bd issue is invisible to everyone else. Suggest a code comment, or a ticket in the team's own tracker, and do not assume which tracker that is -For more details, see README.md and docs/QUICKSTART.md. +For more details, run `bd quickstart` or see . # Copier-Managed Files diff --git a/README.md b/README.md index afc47eba..2b408e3e 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,11 @@ To create a new repository using this template: # Development +Multi-step workflows are defined as [Task](https://taskfile.dev) tasks. Run `task --list` to see them; the definitions live in `.config/taskfiles/`, and `Taskfile.yaml` in the repo root is only a shim that includes them. + ## Updating from the template -This repository uses a copier template. To pull in the latest updates from the template, use the command: -`copier update --answers-file .config/.copier-answers.yml --trust --conflict rej --defaults` +This repository uses a copier template. To pull in the latest updates from the template, run `task copier-update` -## Issue Tracking with bd (beads) +## Work Tracking with bd (beads) -**IMPORTANT**: This project uses **bd (beads)** for ALL issue tracking. Do NOT use markdown TODOs, task lists, or other tracking methods. +**IMPORTANT**: Use **bd (beads)** to break down and track your own work while implementing a ticket. Within a working session it is the only place to track that breakdown — do NOT use markdown TODOs, task lists, or other scratch tracking methods. + +bd is not the team's ticket tracker. It is a local tool for a developer and an AI agent working together: `bd init --stealth` adds `.beads/` to `.git/info/exclude`, so neither the database nor its JSONL export is committed, and nothing recorded in bd is visible to reviewers, teammates, or CI. The ticket a session is implementing lives in whatever system the team owning the repository uses — GitHub Issues, Jira, Linear, or something else. ### Why bd? -- Dependency-aware: Track blockers and relationships between issues -- Git-friendly: Auto-syncs to JSONL for version control +- Dependency-aware: Track blockers and relationships between the pieces of work in a session - Agent-optimized: JSON output, ready work detection, discovered-from links -- Prevents duplicate tracking systems and confusion +- Keeps session breakdown out of the team's ticket tracker, and out of the codebase ### Quick Start @@ -115,20 +120,20 @@ bd ready --json ```bash bd create "Issue title" --description="Detailed context" -t bug|feature|task -p 0-4 --json -bd create "Issue title" --description="What this issue is about" -p 1 --deps discovered-from:bd-123 --json +bd create "Issue title" --description="What this issue is about" -p 1 --deps discovered-from: --json ``` **Claim and update:** ```bash -bd update bd-42 --status in_progress --json -bd update bd-42 --priority 1 --json +bd update --status in_progress --json +bd update --priority 1 --json ``` **Complete work:** ```bash -bd close bd-42 --reason "Completed" --json +bd close --reason "Completed" --json ``` **Creating human readable file:** @@ -145,6 +150,7 @@ bd export -o [relative path to repository root]/.claude/.beads/issues-dump.jsonl - `task` - Work item (tests, docs, refactoring) - `epic` - Large feature with subtasks - `chore` - Maintenance (dependencies, tooling) +- `decision` - An architectural decision (aliases: `dec`, `adr`) ### Priorities @@ -166,15 +172,15 @@ bd export -o [relative path to repository root]/.claude/.beads/issues-dump.jsonl ### Important Rules -- ✅ Use bd for ALL task tracking +- ✅ Use bd for ALL tracking of your own work within a session - ✅ Always use `--json` flag for programmatic use - ✅ Link discovered work with `discovered-from` dependencies - ✅ Check `bd ready` before asking "what should I work on?" -- ❌ Do NOT create markdown TODO lists -- ❌ Do NOT use external issue trackers -- ❌ Do NOT duplicate tracking systems +- ❌ Do NOT create markdown TODO lists to track session work +- ❌ Do NOT stand up a second scratch tracking system alongside bd +- ❌ Do NOT propose bd for work that needs tracking beyond the session — a bd issue is invisible to everyone else. Suggest a code comment, or a ticket in the team's own tracker, and do not assume which tracker that is -For more details, see README.md and docs/QUICKSTART.md. +For more details, run `bd quickstart` or see . # Copier-Managed Files diff --git a/template/README.md.jinja b/template/README.md.jinja index 21a3ded1..13938c53 100644 --- a/template/README.md.jinja +++ b/template/README.md.jinja @@ -23,6 +23,9 @@ Documentation is hosted on [ReadTheDocs](https://{% endraw %}{{ package_name }}{% raw %}.readthedocs.io/en/latest/?badge=latest). # Development + +Multi-step workflows are defined as [Task](https://taskfile.dev) tasks. Run `task --list` to see them; the definitions live in `.config/taskfiles/`, and `Taskfile.yaml` in the repo root is only a shim that includes them. + This project has a dev container. If you already have VS Code and Docker installed, you can click the badge above or [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url={% endraw %}{{ full_repo_url }}{% raw %}) to get started. Clicking these links will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use. {% endraw %}{% if not deploy_as_executable %}{% raw %}To publish a new version of the repository, you can run the `Publish` workflow manually and publish to the staging registry from any branch, and you can check the 'Publish to Primary' option when on `main` to publish to the primary registry and create a git tag. @@ -37,5 +40,4 @@ This project has a dev container. If you already have VS Code and Docker install ## Updating from the template -This repository uses a copier template. To pull in the latest updates from the template, use the command: -`copier update --answers-file .config/.copier-answers.yml --trust --conflict rej --defaults`{% endraw %} +This repository uses a copier template. To pull in the latest updates from the template, run `task copier-update`{% endraw %} diff --git a/template/Taskfile.yaml.jinja b/template/Taskfile.yaml.jinja new file mode 100644 index 00000000..acf1ccfb --- /dev/null +++ b/template/Taskfile.yaml.jinja @@ -0,0 +1,9 @@ +{% raw %}# Task definitions live in .config/taskfiles/ next to the other tool configs so the repo root stays uncluttered. +# This shim exists because Task cannot be pointed at a config directory: auto-discovery covers only Taskfile.yml, taskfile.yml, Taskfile.yaml, taskfile.yaml and their .dist variants in the current directory walking up through parents, no environment variable sets the Taskfile path (https://github.com/go-task/task/issues/1721 requested one and was closed as a duplicate on 2025-12-10 with no linked replacement and no implementation), and requiring -t/--taskfile on every call would break both the ergonomics and the Claude Code bash permission matcher. +# Every include is flattened so that no task name contains a colon: Task's ':' namespace separator is not configurable and Claude Code cannot match a ':*' permission pattern (see .claude/settings/permissions/bash.jsonc). Flattened names share one global namespace, so a collision between two included files is a hard error rather than a silent shadow, and names are prefixed by hand (build-frontend) instead of namespaced (frontend:build). +version: '3' + +includes: + copier: + taskfile: ./.config/taskfiles/copier-template.yaml + flatten: true{% endraw %} diff --git a/template/scripts/delete_false_positive_rej.py b/template/scripts/delete_false_positive_rej.py old mode 100644 new mode 100755 diff --git a/tests/unit/copier_tasks/helpers.py b/tests/unit/copier_tasks/helpers.py index 2c6d7701..4b3da80d 100644 --- a/tests/unit/copier_tasks/helpers.py +++ b/tests/unit/copier_tasks/helpers.py @@ -19,6 +19,8 @@ def run_copier_task( script_path: Path, *args: str, env: dict[str, str] | None = None, + # bounded so a runaway traversal fails the test rather than wedging the runner + timeout: float = 60, ) -> subprocess.CompletedProcess[str]: return subprocess.run( # noqa: S603 -- these are our own scripts [sys.executable, str(script_path), *args], @@ -26,4 +28,5 @@ def run_copier_task( capture_output=True, text=True, env=env, + timeout=timeout, ) diff --git a/tests/unit/copier_tasks/test_copier_provenance.py b/tests/unit/copier_tasks/test_copier_provenance.py index 639bd879..9011a011 100644 --- a/tests/unit/copier_tasks/test_copier_provenance.py +++ b/tests/unit/copier_tasks/test_copier_provenance.py @@ -184,6 +184,48 @@ def test_jinja_if_check_directory_matched(self, tmp_path: Path) -> None: assert content.startswith(expected_hash_comment) +class TestWhenTaskRunAgainstDestination: + def test_Given_symlink_cycle__Then_managed_file_stamped(self, tmp_path: Path) -> None: + # Two links back to the root rather than one: a single link is bounded by the kernel's ELOOP + # limit, so it would terminate on its own and catch no regression. + template_dir = tmp_path / "template" + template_dir.mkdir() + (template_dir / "README.md.jinja-base").touch() + + dst_dir = tmp_path / "destination" + node_modules = dst_dir / "node_modules" + node_modules.mkdir(parents=True) + (node_modules / "pkg-a").symlink_to(dst_dir, target_is_directory=True) + (node_modules / "pkg-b").symlink_to(dst_dir, target_is_directory=True) + file_content = "some content\n" + _ = (dst_dir / "README.md").write_text(file_content, encoding="utf-8") + + _ = _run_script(src_template_dir=template_dir, dst_dir=dst_dir) + + content = (dst_dir / "README.md").read_text(encoding="utf-8") + assert content == file_content + "\n" + expected_markdown_comment + "\n" + + def test_Given_broken_symlink_at_managed_path__Then_path_skipped(self, tmp_path: Path) -> None: + template_dir = tmp_path / "template" + template_dir.mkdir() + (template_dir / "config.yaml.jinja-base").touch() + (template_dir / "keep.yaml.jinja-base").touch() + + dst_dir = tmp_path / "destination" + dst_dir.mkdir() + broken = dst_dir / "config.yaml" + broken.symlink_to(dst_dir / "does-not-exist.yaml") + _ = (dst_dir / "keep.yaml").write_text("key: value\n", encoding="utf-8") + assert broken.is_symlink() + + _ = _run_script(src_template_dir=template_dir, dst_dir=dst_dir) + + manifest = _read_manifest(dst_dir) + + assert (dst_dir / "keep.yaml").read_text(encoding="utf-8").startswith(expected_hash_comment) + assert manifest["templates"][0]["managed_files"] == ["keep.yaml"] + + class TestFileExtensionComments: @pytest.mark.parametrize( ("filename", "expected_location", "expected_comment"), diff --git a/uv.lock b/uv.lock index e3d2960f..f10339af 100644 --- a/uv.lock +++ b/uv.lock @@ -22,7 +22,7 @@ wheels = [ [[package]] name = "copier" -version = "9.17.1" +version = "9.18.2" source = { registry = "https://pypi.org/simple/" } dependencies = [ { name = "colorama" }, @@ -39,9 +39,9 @@ dependencies = [ { name = "pyyaml" }, { name = "questionary" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/40/65/11c8635a27ce06ef525946bb02b1d5271b0f11e5acf9c5ab6d242512598e/copier-9.17.1.tar.gz", hash = "sha256:778e85f1c2de86824a72ddf4a34140744921d6354450c427c4c8a475371b1bda", size = 647338, upload-time = "2026-08-04T09:15:04.826Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/60/2fe1777b27f489450ed8ac5c75390caf91a175d647be05b4284bf515b413/copier-9.18.2.tar.gz", hash = "sha256:0f97902fee79374551c9391fb1132f5a038079f3b497f4dad673295489fc032e", size = 669824, upload-time = "2026-09-07T13:14:38.435Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/bf/3adcb9b3091b36de729dad91c107179c8c7c51adb2b08c31177bb540bef1/copier-9.17.1-py3-none-any.whl", hash = "sha256:f6a48f296e2e536c635213e1000ea71099f9f58f3b464a60f2f0fd386e343628", size = 66364, upload-time = "2026-08-04T09:15:03.026Z" }, + { url = "https://files.pythonhosted.org/packages/8d/2a/854d86eb28ced1c4ade3d8c83bdc7ba529ac5df6c80b5d5202a090244d7a/copier-9.18.2-py3-none-any.whl", hash = "sha256:ef0e1b09dece031b09085f2aa637bdc3d5952b98d96b986feaa45a8f3a00d2c6", size = 68113, upload-time = "2026-09-07T13:14:36.934Z" }, ] [[package]] @@ -60,13 +60,13 @@ dependencies = [ [package.metadata] requires-dist = [ - { name = "copier", specifier = "==9.17.1" }, + { name = "copier", specifier = "==9.18.2" }, { name = "copier-template-extensions", specifier = "==0.3.3" }, - { name = "faker", specifier = ">=40.36.0" }, - { name = "pyrefly", specifier = ">=1.2.0" }, + { name = "faker", specifier = ">=40.39.0" }, + { name = "pyrefly", specifier = ">=1.3.1" }, { name = "pytest", specifier = ">=9.1.1" }, { name = "pytest-cov", specifier = ">=7.1.0" }, - { name = "pytest-randomly", specifier = ">=4.1.0" }, + { name = "pytest-randomly", specifier = ">=5.0.0" }, ] [[package]] @@ -159,14 +159,14 @@ wheels = [ [[package]] name = "faker" -version = "40.36.0" +version = "40.39.0" source = { registry = "https://pypi.org/simple/" } dependencies = [ { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/98/d2/026af1e002bbc6df534d1f8262b18ec79a974f928e9290bfbfdfe7c7b2af/faker-40.36.0.tar.gz", hash = "sha256:754048c76c03afa7de83eee8f4bcee3cf668cbb7d995f54a4e9678db7f110308", size = 2025903, upload-time = "2026-07-24T21:11:33.088Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/62/fea935af7a312f073c99d470b05a7c96650ee8d9562ce82e8cb7ee4c1247/faker-40.39.0.tar.gz", hash = "sha256:52799ad96fcf92aab2fc96a9e03869bbf1a634300f7cd91c38dbfd51f639f6fa", size = 2029463, upload-time = "2026-09-14T16:50:17.939Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/9a/b947ed175ce9a0dcb070ccf3607f0ce8720cfb5ed1a36166a150b2acd5af/faker-40.36.0-py3-none-any.whl", hash = "sha256:82b9497d9cfe017048075bcf969298a74b1b6e39f5e4dad1211085d1133f7b62", size = 2062829, upload-time = "2026-07-24T21:11:31.37Z" }, + { url = "https://files.pythonhosted.org/packages/45/c8/901282279841ebb59216433be01aac825fb905e1a597de3b7b5ab8b0c43e/faker-40.39.0-py3-none-any.whl", hash = "sha256:c4c7ec2cddfaf602c5a8a2c960614946aa8c161250bd9d49a8846cd24d1ef028", size = 2066232, upload-time = "2026-09-14T16:50:16.061Z" }, ] [[package]] @@ -374,21 +374,21 @@ wheels = [ [[package]] name = "pyrefly" -version = "1.2.0" +version = "1.3.1" source = { registry = "https://pypi.org/simple/" } -sdist = { url = "https://files.pythonhosted.org/packages/89/01/a86e9f24722b095c3f88e3616132b75a21b0df53804bdc6a45314dd4d93c/pyrefly-1.2.0.tar.gz", hash = "sha256:5485f960fc2481617068c918335c39ab1507ef90b6b5bd35bf57726e60e73185", size = 6243654, upload-time = "2026-08-01T02:56:27.592Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/7e/082cc1b392318bacfbc087732524f3e089e9e7fe45b7645c4649b6f1f1e9/pyrefly-1.3.1.tar.gz", hash = "sha256:b774f1dfac82867fc16fe2175d80a630e2a72a6835d5b7e492568d6bfb6b05e7", size = 6679145, upload-time = "2026-09-15T05:09:34.49Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7d/9d/3c0ef1d4843987b22f996ed381ec9cf5a3b1273e29804db276252e4c95eb/pyrefly-1.2.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7f46d983ac49ddd2b043694960a01dc6a19a5cfd8eec609d6bd9c42866f91b4e", size = 14026305, upload-time = "2026-08-01T02:56:02.611Z" }, - { url = "https://files.pythonhosted.org/packages/0a/06/03bbb78fbea54cdc65b626619f3597d5611aca4fdef11e72a4e8360e7e63/pyrefly-1.2.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:756f669b5555090f5c1a4fef30db1785fabe657764f7e4e6dc88994dfb8ca82d", size = 13463880, upload-time = "2026-08-01T02:56:04.93Z" }, - { url = "https://files.pythonhosted.org/packages/13/5a/7d8bc00a38e93bbc9c3e7bd14d305f7948717e667c9bcddeab9dd42fd255/pyrefly-1.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3465812ce5ef4781fb592edbf2724547296f0a3124be115d73c7e8b2401862d", size = 13907329, upload-time = "2026-08-01T02:56:07.104Z" }, - { url = "https://files.pythonhosted.org/packages/be/94/9e08b4bf799d0b8f36b55a2783c7ba5f51730cf0632a85a67b5b5ed876cd/pyrefly-1.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5de7b2ad2bba5c8055181681a84b74143eac2234a48ba5d1b7ed7e7a722b02bd", size = 15039020, upload-time = "2026-08-01T02:56:09.208Z" }, - { url = "https://files.pythonhosted.org/packages/5b/bd/bca5fd0c80f4daf8ee6903a29df9f3de1feb05ff0946b8f35ec8c5096b13/pyrefly-1.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25822ea9505f589ea8a725e4268b475132fb89e038fbf092e446510443ac142a", size = 14986199, upload-time = "2026-08-01T02:56:11.924Z" }, - { url = "https://files.pythonhosted.org/packages/97/f7/f07087f3d185ad2eced0c56cef89ca5474dfb4ff25f146cd50a861c97553/pyrefly-1.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90efe75e17491ef5d636e10469e9278d7d0256b3b4c5e1f4750069bf3ae0f5d1", size = 14393715, upload-time = "2026-08-01T02:56:14.143Z" }, - { url = "https://files.pythonhosted.org/packages/d3/70/0d142c320e284b9e3ce35e9b1e58b8ce2ee1f578f2a7234bc30e5022b94f/pyrefly-1.2.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:368aaf7eee4f511ddc0f8e564cf14e01ab2f10b0db9105c6d5b153bf498d07bf", size = 13933008, upload-time = "2026-08-01T02:56:16.525Z" }, - { url = "https://files.pythonhosted.org/packages/5d/e8/e84f11b6e1f63fd453ad3654213b9a0f6f4de8cef6b58038eef2d0d5955d/pyrefly-1.2.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d52d5da7bc65fb7675fbaa80eda879d4f8787c494f04cac21603330d3abbdbbe", size = 14431827, upload-time = "2026-08-01T02:56:18.645Z" }, - { url = "https://files.pythonhosted.org/packages/0f/06/810d31380f66c75e1c0779a408d3b16117b1b368b57894f6aa66bef21686/pyrefly-1.2.0-py3-none-win32.whl", hash = "sha256:8c90751de8506d938e8f802659c74cf35bd7a0036510ee6c634a38eebb280bfa", size = 13229447, upload-time = "2026-08-01T02:56:20.921Z" }, - { url = "https://files.pythonhosted.org/packages/ed/98/4dafa3c7a1caed2dc8cc708dde09ba27963c7736508f55b626fff3024113/pyrefly-1.2.0-py3-none-win_amd64.whl", hash = "sha256:8a8964c224ccc4882730130955815de21ff443c1ac3f0b90685b19bf63848170", size = 14087387, upload-time = "2026-08-01T02:56:23.188Z" }, - { url = "https://files.pythonhosted.org/packages/1b/1c/df3cb0a2e5591660ded7a1836cd2f29dc48c91adb1c0a3a700a96f6d09e1/pyrefly-1.2.0-py3-none-win_arm64.whl", hash = "sha256:3a90bb8df39dfbac74b1f3b2e9d7c526b8f80568884c3944d955023a73ebf61e", size = 13430873, upload-time = "2026-08-01T02:56:25.425Z" }, + { url = "https://files.pythonhosted.org/packages/6b/bc/f09b5bd7eed796349bd93627aa2c3086df7ed0a114dafc3d2b2841599ee7/pyrefly-1.3.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0a2a7dfed824fb066aa8a7c8d856c152b98e998fb84b954d5f892fb9834c0bd1", size = 15090117, upload-time = "2026-09-15T05:08:58.477Z" }, + { url = "https://files.pythonhosted.org/packages/78/24/a31e7de8e0f310c9f0753826d0df8b6a8ff86793941a6bd88ba24b735633/pyrefly-1.3.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37a1a1fb41e7190fe3964a877875dd809d6ee2887809e2c3d6e5f25a69805bfd", size = 14430773, upload-time = "2026-09-15T05:09:01.67Z" }, + { url = "https://files.pythonhosted.org/packages/75/e1/022352beb186f36d6213a95a975c42676ee418ff5e730629378d25564c5e/pyrefly-1.3.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45b7650bc651a5a784701f2fb4f579da9a421c4d1b5fd91f9048f4529e46093c", size = 14877762, upload-time = "2026-09-15T05:09:04.767Z" }, + { url = "https://files.pythonhosted.org/packages/19/2c/d62a1b445aad1fd46375b83393b8a67da53883aeeba73d269ce71b3e8fd1/pyrefly-1.3.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad57f38bc73679c14a5f62995a2bd3bc43649b7270c858487e2eab78a6f95362", size = 16118225, upload-time = "2026-09-15T05:09:07.828Z" }, + { url = "https://files.pythonhosted.org/packages/32/67/3c3fa8a13e3ce8d8322ffb3627255a41a52261f17793e1a24e9214f10857/pyrefly-1.3.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3506b1252e9f5d755d0693c5a46d46b85579d36534f6e22a41eb8e098d0dde90", size = 16051197, upload-time = "2026-09-15T05:09:10.81Z" }, + { url = "https://files.pythonhosted.org/packages/19/d1/84f81b9e32288b5d11c75e006f67e0f6b78b85da575673bd1a21524c8172/pyrefly-1.3.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39d5a17c1ad655e5f93a6e8e0be90b8db28c6015fe07d6ed4e054891c9e14ef8", size = 15440062, upload-time = "2026-09-15T05:09:14.641Z" }, + { url = "https://files.pythonhosted.org/packages/46/3c/2aa0c5ad6a2957a728bb38cfab70d1e9cafad21b0b1c1d92df74a3cf22bd/pyrefly-1.3.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c61e9dcf888beb81ca0e0c60ea4442640fdcf2f1f65bfe3d9f5d89b85516eb03", size = 14898534, upload-time = "2026-09-15T05:09:17.823Z" }, + { url = "https://files.pythonhosted.org/packages/03/5d/2974f249fb2e285f966485719d977c5a2248cc4866403af94d935775ff15/pyrefly-1.3.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a78eed1c53f37807f0e2997be8edbe833b91eb9915f2cb553a1bdcd599e7105c", size = 15477758, upload-time = "2026-09-15T05:09:20.964Z" }, + { url = "https://files.pythonhosted.org/packages/68/79/d31f8f0abf5b0610ec24183286ee8a1ee5b76c9aaaa91091399d7e1aaf60/pyrefly-1.3.1-py3-none-win32.whl", hash = "sha256:ea0d0349f1bc80fe8e00a7b3640e40db7486398b685f87b9bd5d2207063668f0", size = 14133005, upload-time = "2026-09-15T05:09:25.03Z" }, + { url = "https://files.pythonhosted.org/packages/3f/23/1859f47f536314755d80c4ec2a76d2698435ae8b73604bcd1dfa57ecb39b/pyrefly-1.3.1-py3-none-win_amd64.whl", hash = "sha256:4c24e7d99df9237916c33be23714219a7c8eaf22bad2ac0c3e1d45adcf7df8fb", size = 15066557, upload-time = "2026-09-15T05:09:28.265Z" }, + { url = "https://files.pythonhosted.org/packages/92/2a/73e3721921c2bb2c950a9f8c362ee5e2367556b5d4416eb4f8f88503e66f/pyrefly-1.3.1-py3-none-win_arm64.whl", hash = "sha256:1ed85e2b957a78e93353125d890ce3668ce450e49b74025a15c87b6e8ec7f3d1", size = 14348209, upload-time = "2026-09-15T05:09:31.422Z" }, ] [[package]] @@ -423,14 +423,14 @@ wheels = [ [[package]] name = "pytest-randomly" -version = "4.1.0" +version = "5.0.0" source = { registry = "https://pypi.org/simple/" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/27/b3/36192dacc0f470ac2cc516f73e01739c9a48a8224f76beada4f85e1c8a89/pytest_randomly-4.1.0.tar.gz", hash = "sha256:47f1d9746c3bc3efabd53ae1ebfb8bb385cf3d4df4b505b6d58d9c97a3dfe70f", size = 14302, upload-time = "2026-04-20T13:01:51.831Z" } +sdist = { url = "https://files.pythonhosted.org/packages/01/3b/6a40e1b9d925651e601e056a97f60d8a1daeddeac03d5609be60cb4362ce/pytest_randomly-5.0.0.tar.gz", hash = "sha256:e9c575a5873ef168ddbe340ed9e97ce9edb4492ccc821e4b2ac6bb1f0ed515d2", size = 8542, upload-time = "2026-09-01T22:34:20.441Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/db/2df9a1fca597a273f957a559c20c2d95d629928384507b2afa43ba6909d1/pytest_randomly-4.1.0-py3-none-any.whl", hash = "sha256:f55e89e53367b090c0c053697d7f9d77595543d0e0516c93978b50c0f6b252f9", size = 8353, upload-time = "2026-04-20T13:01:50.382Z" }, + { url = "https://files.pythonhosted.org/packages/10/b4/47e939285caad9a623d021512912ac08dc92a467ad075d179f43729d2934/pytest_randomly-5.0.0-py3-none-any.whl", hash = "sha256:8a0d4703115c0c25b38b6e129fc16b1947b9643ff26a41bc1d185d7e5a7689c1", size = 8920, upload-time = "2026-09-01T22:34:19.227Z" }, ] [[package]]