ec18a783d8
- Narrow markdown pipeline result with isinstance assert (static type correctness; .code/.tables/.images access no longer leaks Document abstraction). - Simplify _execute_with_lock_retry to 5 linear-backoff attempts; the helper was tuned for WAL schema bootstrap, not repeated retry. - Add Literal['markdown','code','plain'] alias for pipeline keys so typos at the dispatch site become type errors. - Fix misleading stage="discover" label on post-discovery errors; relabel as "read" where it actually applies. - Extract _make_config / _write into tests/workspace/conftest.py fixtures so the two test files share one source. - Factor str(Path(raw).resolve()) into workspace.constants.resolve_path_prefix and call from both search_workspace and the CLI command. - Drop a stale WHAT-comment on the retry backoff line.
40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
"""Workspace search API.
|
|
|
|
Thin wrapper around SQLiteFTS5Store.search() that handles config loading
|
|
and store lifecycle.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from workspace.config import WorkspaceConfig
|
|
from workspace.constants import resolve_path_prefix
|
|
from workspace.store import SQLiteFTS5Store
|
|
from workspace.types import SearchResult
|
|
|
|
|
|
def search_workspace(
|
|
query: str,
|
|
config: WorkspaceConfig,
|
|
*,
|
|
limit: int | None = None,
|
|
path_prefix: str | None = None,
|
|
file_glob: str | None = None,
|
|
) -> list[SearchResult]:
|
|
if limit is None:
|
|
limit = config.knowledgebase.search.default_limit
|
|
|
|
# Resolve symlinks + relative segments so the byte-prefix match in the store
|
|
# aligns with the indexer, which stores resolved absolute paths
|
|
# (`str(file_path.resolve())` in `indexer.py`). Mirrors what `commands.py`
|
|
# already does for CLI search — without this, callers who hand in a
|
|
# symlinked path via the Python API silently get zero hits.
|
|
resolved_prefix = resolve_path_prefix(path_prefix)
|
|
|
|
with SQLiteFTS5Store(config.workspace_root) as store:
|
|
return store.search(
|
|
query,
|
|
limit=limit,
|
|
path_prefix=resolved_prefix,
|
|
file_glob=file_glob,
|
|
)
|