mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-21 19:08:17 +08:00
feat: enhance search, ranking, reranker and CLI tooling across ccw and codex-lens
Major improvements to smart-search, chain-search cascade, ranking pipeline, reranker factory, CLI history store, codex-lens integration, and uv-manager. Simplify command-generator skill by inlining phases. Add comprehensive tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,10 @@ from pathlib import Path
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from codexlens.config import Config
|
||||
from codexlens.storage.index_tree import IndexTreeBuilder
|
||||
from codexlens.storage.dir_index import DirIndexStore
|
||||
from codexlens.storage.index_tree import DirBuildResult, IndexTreeBuilder
|
||||
from codexlens.storage.path_mapper import PathMapper
|
||||
from codexlens.storage.registry import RegistryStore
|
||||
|
||||
|
||||
def _relative_dirs(source_root: Path, dirs_by_depth: dict[int, list[Path]]) -> set[str]:
|
||||
@@ -145,3 +148,148 @@ def test_builder_loads_saved_ignore_and_extension_filters_by_default(tmp_path: P
|
||||
|
||||
assert [path.name for path in source_files] == ["app.ts"]
|
||||
assert "frontend/dist" not in discovered_dirs
|
||||
|
||||
|
||||
def test_prune_stale_project_dirs_removes_ignored_artifact_mappings(tmp_path: Path) -> None:
|
||||
workspace = tmp_path / "workspace"
|
||||
src_dir = workspace / "src"
|
||||
dist_dir = workspace / "dist"
|
||||
src_dir.mkdir(parents=True)
|
||||
dist_dir.mkdir(parents=True)
|
||||
(src_dir / "app.py").write_text("print('ok')\n", encoding="utf-8")
|
||||
(dist_dir / "bundle.py").write_text("print('artifact')\n", encoding="utf-8")
|
||||
|
||||
mapper = PathMapper(index_root=tmp_path / "indexes")
|
||||
registry = RegistryStore(db_path=tmp_path / "registry.db")
|
||||
registry.initialize()
|
||||
project = registry.register_project(workspace, mapper.source_to_index_dir(workspace))
|
||||
registry.register_dir(project.id, workspace, mapper.source_to_index_db(workspace), depth=0)
|
||||
registry.register_dir(project.id, src_dir, mapper.source_to_index_db(src_dir), depth=1)
|
||||
registry.register_dir(project.id, dist_dir, mapper.source_to_index_db(dist_dir), depth=1)
|
||||
|
||||
builder = IndexTreeBuilder(
|
||||
registry=registry,
|
||||
mapper=mapper,
|
||||
config=Config(data_dir=tmp_path / "data"),
|
||||
incremental=False,
|
||||
)
|
||||
|
||||
dirs_by_depth = builder._collect_dirs_by_depth(workspace)
|
||||
pruned = builder._prune_stale_project_dirs(
|
||||
project_id=project.id,
|
||||
source_root=workspace,
|
||||
dirs_by_depth=dirs_by_depth,
|
||||
)
|
||||
|
||||
remaining = {mapping.source_path.resolve() for mapping in registry.get_project_dirs(project.id)}
|
||||
registry.close()
|
||||
|
||||
assert dist_dir.resolve() in pruned
|
||||
assert workspace.resolve() in remaining
|
||||
assert src_dir.resolve() in remaining
|
||||
assert dist_dir.resolve() not in remaining
|
||||
|
||||
|
||||
def test_force_full_build_prunes_stale_ignored_mappings(tmp_path: Path) -> None:
|
||||
workspace = tmp_path / "workspace"
|
||||
src_dir = workspace / "src"
|
||||
dist_dir = workspace / "dist"
|
||||
src_dir.mkdir(parents=True)
|
||||
dist_dir.mkdir(parents=True)
|
||||
(src_dir / "app.py").write_text("print('ok')\n", encoding="utf-8")
|
||||
(dist_dir / "bundle.py").write_text("print('artifact')\n", encoding="utf-8")
|
||||
|
||||
mapper = PathMapper(index_root=tmp_path / "indexes")
|
||||
registry = RegistryStore(db_path=tmp_path / "registry.db")
|
||||
registry.initialize()
|
||||
project = registry.register_project(workspace, mapper.source_to_index_dir(workspace))
|
||||
registry.register_dir(project.id, workspace, mapper.source_to_index_db(workspace), depth=0)
|
||||
registry.register_dir(project.id, dist_dir, mapper.source_to_index_db(dist_dir), depth=1)
|
||||
|
||||
builder = IndexTreeBuilder(
|
||||
registry=registry,
|
||||
mapper=mapper,
|
||||
config=Config(
|
||||
data_dir=tmp_path / "data",
|
||||
global_symbol_index_enabled=False,
|
||||
),
|
||||
incremental=False,
|
||||
)
|
||||
|
||||
def fake_build_level_parallel(
|
||||
dirs: list[Path],
|
||||
languages,
|
||||
workers,
|
||||
*,
|
||||
source_root: Path,
|
||||
project_id: int,
|
||||
global_index_db_path: Path,
|
||||
) -> list[DirBuildResult]:
|
||||
return [
|
||||
DirBuildResult(
|
||||
source_path=dir_path,
|
||||
index_path=mapper.source_to_index_db(dir_path),
|
||||
files_count=1 if dir_path == src_dir else 0,
|
||||
symbols_count=0,
|
||||
subdirs=[],
|
||||
)
|
||||
for dir_path in dirs
|
||||
]
|
||||
|
||||
builder._build_level_parallel = fake_build_level_parallel # type: ignore[method-assign]
|
||||
builder._link_children_to_parent = MagicMock()
|
||||
|
||||
build_result = builder.build(workspace, force_full=True, workers=1)
|
||||
|
||||
remaining = {mapping.source_path.resolve() for mapping in registry.get_project_dirs(project.id)}
|
||||
registry.close()
|
||||
|
||||
assert build_result.total_dirs == 2
|
||||
assert workspace.resolve() in remaining
|
||||
assert src_dir.resolve() in remaining
|
||||
assert dist_dir.resolve() not in remaining
|
||||
|
||||
|
||||
def test_force_full_build_rewrites_directory_db_and_drops_stale_ignored_subdirs(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
project_root = tmp_path / "project"
|
||||
src_dir = project_root / "src"
|
||||
build_dir = project_root / "build"
|
||||
src_dir.mkdir(parents=True)
|
||||
build_dir.mkdir(parents=True)
|
||||
(src_dir / "app.py").write_text("print('ok')\n", encoding="utf-8")
|
||||
(build_dir / "generated.py").write_text("print('artifact')\n", encoding="utf-8")
|
||||
|
||||
mapper = PathMapper(index_root=tmp_path / "indexes")
|
||||
registry = RegistryStore(db_path=tmp_path / "registry.db")
|
||||
registry.initialize()
|
||||
config = Config(
|
||||
data_dir=tmp_path / "data",
|
||||
global_symbol_index_enabled=False,
|
||||
)
|
||||
|
||||
root_index_db = mapper.source_to_index_db(project_root)
|
||||
with DirIndexStore(root_index_db, config=config) as store:
|
||||
store.register_subdir(
|
||||
name="build",
|
||||
index_path=mapper.source_to_index_db(build_dir),
|
||||
files_count=1,
|
||||
)
|
||||
|
||||
builder = IndexTreeBuilder(
|
||||
registry=registry,
|
||||
mapper=mapper,
|
||||
config=config,
|
||||
incremental=False,
|
||||
)
|
||||
|
||||
build_result = builder.build(project_root, force_full=True, workers=1)
|
||||
|
||||
with DirIndexStore(root_index_db, config=config) as store:
|
||||
subdir_names = [link.name for link in store.get_subdirs()]
|
||||
|
||||
registry.close()
|
||||
|
||||
assert build_result.total_dirs == 2
|
||||
assert subdir_names == ["src"]
|
||||
|
||||
Reference in New Issue
Block a user