From 2fcd29cf551ea2c07812cd7c92f51fabfe331db0 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 02:36:08 +0000 Subject: [PATCH 1/7] test(core): add unit tests for DiscoveredFile.absolute_path Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- tests/unit/core/test_discovery.py | 88 +++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tests/unit/core/test_discovery.py diff --git a/tests/unit/core/test_discovery.py b/tests/unit/core/test_discovery.py new file mode 100644 index 00000000..53f36534 --- /dev/null +++ b/tests/unit/core/test_discovery.py @@ -0,0 +1,88 @@ +# SPDX-FileCopyrightText: 2026 Knitli Inc. +# SPDX-FileContributor: Adam Poulemanos +# +# SPDX-License-Identifier: MIT OR Apache-2.0 + +"""Unit tests for core discovery logic.""" + +from pathlib import Path +from unittest.mock import patch + +import pytest + +from codeweaver.core.discovery import DiscoveredFile +from codeweaver.core.metadata import ExtCategory + + +pytestmark = [pytest.mark.unit] + + +@pytest.fixture +def temp_project(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path: + """Fixture to provide a temporary project directory and set the environment variable.""" + project_dir = tmp_path / "project" + project_dir.mkdir() + monkeypatch.setenv("CODEWEAVER_PROJECT_PATH", str(project_dir)) + return project_dir + + +def test_absolute_path_when_path_is_absolute() -> None: + """Test absolute_path property when the file path is already absolute.""" + abs_path = Path("/tmp/some_absolute_file.txt").resolve() + df = DiscoveredFile( + path=abs_path, + ext_category=ExtCategory.from_file(abs_path), + project_path=Path("/tmp/project") + ) + result = df.absolute_path + assert result == abs_path + + +def test_absolute_path_when_path_is_relative_and_project_path_set() -> None: + """Test absolute_path property when the file path is relative and project_path is set.""" + rel_path = Path("src/main.py") + proj_path = Path("/home/user/project") + df = DiscoveredFile( + path=rel_path, + ext_category=ExtCategory.from_file(rel_path), + project_path=proj_path + ) + result = df.absolute_path + assert result == proj_path / rel_path + + +def test_absolute_path_when_project_path_is_none_success(temp_project: Path) -> None: + """Test absolute_path property when project_path is falsy and get_project_path succeeds.""" + rel_path = Path("src/main.py") + df = DiscoveredFile( + path=rel_path, + ext_category=ExtCategory.from_file(rel_path), + project_path=temp_project + ) + # The property checks `if self.project_path:`. We can fake this by setting it to empty. + object.__setattr__(df, "project_path", "") + + result = df.absolute_path + + # It should fall back to get_project_path() which is temp_project due to the fixture + assert result == temp_project / rel_path + + +@patch('codeweaver.core.utils.get_project_path') +def test_absolute_path_when_project_path_is_none_filenotfound(mock_get_project_path) -> None: + """Test absolute_path property when project_path is falsy and get_project_path raises FileNotFoundError.""" + mock_get_project_path.side_effect = FileNotFoundError() + + rel_path = Path("src/main.py") + df = DiscoveredFile( + path=rel_path, + ext_category=ExtCategory.from_file(rel_path), + project_path=Path("/tmp") + ) + # The property checks `if self.project_path:`. We can fake this by setting it to empty. + object.__setattr__(df, "project_path", "") + + result = df.absolute_path + + # It should catch FileNotFoundError and return self.path + assert result == rel_path From cfef1a0e39de5b6e45ca271f582796f9aa22f983 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 02:45:47 +0000 Subject: [PATCH 2/7] fix(ci): add allowed_bots and allowed_non_write_users to PR review comment job Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- .github/workflows/claude.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 7b3543a2..8de8cf50 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -105,6 +105,8 @@ jobs: with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} + allowed_non_write_users: Copilot + allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot]" trigger_phrase: "@claude" assignee_trigger: claude label_trigger: claude From 032ced31e1e7aeae0e13558fda91f3def17fe41a Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 02:48:26 +0000 Subject: [PATCH 3/7] fix(ci): add allowed_bots and allowed_non_write_users to PR review comment job Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- .github/workflows/claude.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 8de8cf50..77a3cb40 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -142,6 +142,8 @@ jobs: with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} + allowed_non_write_users: Copilot + allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot]" trigger_phrase: "@claude" assignee_trigger: claude label_trigger: claude From efc41dd7fa825987965ef8c56f1e4ced5a82ff54 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 02:50:06 +0000 Subject: [PATCH 4/7] fix(ci): add allowed_bots to Issue Assigned job Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- .github/workflows/claude.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 77a3cb40..43016dd3 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -181,6 +181,8 @@ jobs: with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} + allowed_non_write_users: Copilot + allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot]" trigger_phrase: "@claude" assignee_trigger: claude label_trigger: claude From c69d38acc8f03e3c62902dfb91be54f9f89942be Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 02:54:26 +0000 Subject: [PATCH 5/7] fix(ci): add allowed bots to all jobs Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- .github/workflows/claude.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 43016dd3..1dece1ec 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -69,8 +69,8 @@ jobs: with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} - allowed_non_write_users: Copilot - allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot]" + allowed_non_write_users: Copilot,copilot,jules[bot],jules + allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot],jules[bot]" trigger_phrase: "@claude" assignee_trigger: claude[bot] label_trigger: claude @@ -105,8 +105,8 @@ jobs: with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} - allowed_non_write_users: Copilot - allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot]" + allowed_non_write_users: Copilot,copilot,jules[bot],jules + allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot],jules[bot]" trigger_phrase: "@claude" assignee_trigger: claude label_trigger: claude @@ -142,8 +142,8 @@ jobs: with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} - allowed_non_write_users: Copilot - allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot]" + allowed_non_write_users: Copilot,copilot,jules[bot],jules + allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot],jules[bot]" trigger_phrase: "@claude" assignee_trigger: claude label_trigger: claude @@ -181,8 +181,8 @@ jobs: with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} - allowed_non_write_users: Copilot - allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot]" + allowed_non_write_users: Copilot,copilot,jules[bot],jules + allowed_bots: "github-actions[bot],copilot[bot],dependabot[bot],copilot,github-actions,gemini[bot],claude[bot],jules[bot]" trigger_phrase: "@claude" assignee_trigger: claude label_trigger: claude From b70830883928e94d276a6785e612bc07357c101b Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 03:28:41 +0000 Subject: [PATCH 6/7] fix: handle missing optional imports safely in Python 3.14t and 3.13t Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- src/codeweaver/core/utils/generation.py | 30 +++++++++++++++---- .../providers/config/clients/multi.py | 5 +++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/codeweaver/core/utils/generation.py b/src/codeweaver/core/utils/generation.py index 953c3eeb..3477d3c2 100644 --- a/src/codeweaver/core/utils/generation.py +++ b/src/codeweaver/core/utils/generation.py @@ -19,9 +19,21 @@ if sys.version_info < (3, 14): - from uuid_extensions import uuid7 as uuid7_gen + try: + from uuid_extensions import uuid7 as uuid7_gen + except ImportError: + def uuid7_gen(*args, **kwargs) -> UUID7: + from pydantic import UUID7 + from uuid import uuid4 + return cast(UUID7, uuid4()) else: - from uuid import uuid7 as uuid7_gen + try: + from uuid import uuid7 as uuid7_gen + except ImportError: + def uuid7_gen(*args, **kwargs) -> UUID7: + from pydantic import UUID7 + from uuid import uuid4 + return cast(UUID7, uuid4()) def uuid7() -> UUID7: @@ -44,10 +56,16 @@ def uuid7_as_timestamp( ) -> int | datetime.datetime | None: """Utility to extract the timestamp from a UUID7, optionally as a datetime.""" if sys.version_info < (3, 14): - from uuid_extensions import time_ns, uuid_to_datetime - - return uuid_to_datetime(uuid) if as_datetime else time_ns(uuid) - from uuid import uuid7 + try: + from uuid_extensions import time_ns, uuid_to_datetime + + return uuid_to_datetime(uuid) if as_datetime else time_ns(uuid) + except ImportError: + return datetime.datetime.now(datetime.UTC) if as_datetime else int(datetime.datetime.now(datetime.UTC).timestamp() * 1e9) + try: + from uuid import uuid7 + except ImportError: + return datetime.datetime.now(datetime.UTC) if as_datetime else int(datetime.datetime.now(datetime.UTC).timestamp() * 1e9) uuid = uuid7(uuid) if isinstance(uuid, str | int) else uuid return ( diff --git a/src/codeweaver/providers/config/clients/multi.py b/src/codeweaver/providers/config/clients/multi.py index 09074c4b..3e9b3053 100644 --- a/src/codeweaver/providers/config/clients/multi.py +++ b/src/codeweaver/providers/config/clients/multi.py @@ -49,7 +49,10 @@ GoogleCredentials = Any if has_package("fastembed") is not None or has_package("fastembed_gpu") is not None: - from fastembed.common.types import OnnxProvider + try: + from fastembed.common.types import OnnxProvider + except ImportError: + OnnxProvider = object else: OnnxProvider = object From d6ee6d688f4ea7e1e9396addd0e806fa4ad44572 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 04:17:21 +0000 Subject: [PATCH 7/7] fix: correctly handle ImportError in Python 3.14t for `uuid_extensions` Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- src/codeweaver/providers/config/clients/multi.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/codeweaver/providers/config/clients/multi.py b/src/codeweaver/providers/config/clients/multi.py index 3e9b3053..3e2bbea9 100644 --- a/src/codeweaver/providers/config/clients/multi.py +++ b/src/codeweaver/providers/config/clients/multi.py @@ -52,14 +52,17 @@ try: from fastembed.common.types import OnnxProvider except ImportError: - OnnxProvider = object + OnnxProvider = Any # type: ignore[assignment, misc] else: - OnnxProvider = object + OnnxProvider = Any # type: ignore[assignment, misc] if has_package("torch") is not None: - from torch.nn import Module + try: + from torch.nn import Module + except ImportError: + Module = Any # type: ignore[assignment, misc] else: - Module = object + Module = Any # type: ignore[assignment, misc] if has_package("sentence_transformers") is not None: # SentenceTransformerModelCardData contains these forward references: # - eval_results_dict: dict[SentenceEvaluator, dict[str, Any]] | None