Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ uv run pytest tests/ # Run Python tests

## Code Conventions

The full review-time detection checklist (with worked examples and post-hoc smell patterns) lives in the [`/review-changes`](~/.claude/skills/review-changes/SKILL.md) skill — run it on uncommitted changes before landing a non-trivial PR. The rules below are write-time mnemonics; project-specific ones (Internal/External modules) stay here in full.

### Internal vs External Modules

We distinguish between **internal modules** (under packages with `_` prefix, e.g. `_internal.*` or `connectors.*._source`) and **external modules** (which users can directly import).
Expand Down
15 changes: 14 additions & 1 deletion src/cocoindex_code/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
"""CocoIndex Code - MCP server for indexing and querying codebases."""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Any

logging.basicConfig(level=logging.WARNING)

from ._version import __version__ # noqa: E402
from .server import main # noqa: E402

if TYPE_CHECKING:
from .server import main as main

__all__ = ["main", "__version__"]


def __getattr__(name: str) -> Any:
if name == "main":
from .server import main

return main
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
17 changes: 13 additions & 4 deletions src/cocoindex_code/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@
import sys
from collections.abc import Callable
from pathlib import Path
from typing import TypeVar
from typing import TYPE_CHECKING, TypeVar

import typer as _typer

from .client import DaemonStartError
from .protocol import DoctorCheckResult, IndexingProgress, ProjectStatusResponse, SearchResponse
if TYPE_CHECKING:
from .protocol import (
DoctorCheckResult,
IndexingProgress,
ProjectStatusResponse,
SearchResponse,
)

from .settings import (
DEFAULT_ST_MODEL,
EmbeddingSettings,
Expand Down Expand Up @@ -104,6 +110,8 @@ def _catch_daemon_start_error(func: _F) -> _F:

@functools.wraps(func)
def wrapper(*args: object, **kwargs: object) -> object:
from .client import DaemonStartError

try:
return func(*args, **kwargs)
except DaemonStartError as e:
Expand Down Expand Up @@ -204,7 +212,7 @@ def _on_progress(progress: IndexingProgress) -> None:
except RuntimeError as e:
live.stop()
# Let DaemonStartError propagate to the decorator for consistent handling.
if isinstance(e, DaemonStartError):
if isinstance(e, _client.DaemonStartError):
raise
_typer.echo(f"Indexing failed: {e}", err=True)
raise _typer.Exit(code=1)
Expand Down Expand Up @@ -397,6 +405,7 @@ def _run_init_model_check(settings_path: Path) -> None:
from rich.spinner import Spinner as _Spinner

from . import client as _client
from .protocol import DoctorCheckResult

err_console = _Console(stderr=True)
results: list[DoctorCheckResult] = []
Expand Down
8 changes: 6 additions & 2 deletions src/cocoindex_code/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import os
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
from typing import TYPE_CHECKING, Any

import yaml as _yaml
from pathspec import GitIgnoreSpec

if TYPE_CHECKING:
from pathspec import GitIgnoreSpec

# ---------------------------------------------------------------------------
# Default file patterns (moved from indexer.py)
Expand Down Expand Up @@ -391,6 +393,8 @@ def global_settings_mtime_us() -> int | None:

def load_gitignore_spec(project_root: Path) -> GitIgnoreSpec | None:
"""Load a GitIgnoreSpec for the project's ``.gitignore`` if present."""
from pathspec import GitIgnoreSpec

gitignore = project_root / ".gitignore"
if not gitignore.is_file():
return None
Expand Down
Loading