mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
refactor: 优化异常处理,使用 cached_property 替代 property,增强代码可读性;添加 RelationshipType 枚举以规范化关系类型
This commit is contained in:
@@ -248,12 +248,6 @@ def init(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Init failed:[/red] {exc}")
|
console.print(f"[red]Init failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Init failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
finally:
|
finally:
|
||||||
if registry is not None:
|
if registry is not None:
|
||||||
registry.close()
|
registry.close()
|
||||||
@@ -457,12 +451,6 @@ def search(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Search failed:[/red] {exc}")
|
console.print(f"[red]Search failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Search failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
finally:
|
finally:
|
||||||
if registry is not None:
|
if registry is not None:
|
||||||
registry.close()
|
registry.close()
|
||||||
@@ -522,12 +510,6 @@ def symbol(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Symbol lookup failed:[/red] {exc}")
|
console.print(f"[red]Symbol lookup failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Symbol lookup failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
finally:
|
finally:
|
||||||
if registry is not None:
|
if registry is not None:
|
||||||
registry.close()
|
registry.close()
|
||||||
@@ -583,12 +565,6 @@ def inspect(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Inspect failed:[/red] {exc}")
|
console.print(f"[red]Inspect failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Inspect failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
@@ -727,12 +703,6 @@ def status(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Status failed:[/red] {exc}")
|
console.print(f"[red]Status failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Status failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
finally:
|
finally:
|
||||||
if registry is not None:
|
if registry is not None:
|
||||||
registry.close()
|
registry.close()
|
||||||
@@ -884,12 +854,6 @@ def projects(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Projects command failed:[/red] {exc}")
|
console.print(f"[red]Projects command failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Projects command failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
finally:
|
finally:
|
||||||
if registry is not None:
|
if registry is not None:
|
||||||
registry.close()
|
registry.close()
|
||||||
@@ -1060,12 +1024,6 @@ def config(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Config command failed:[/red] {exc}")
|
console.print(f"[red]Config command failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Config command failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
@@ -1192,12 +1150,6 @@ def migrate(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Migration failed:[/red] {exc}")
|
console.print(f"[red]Migration failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Migration failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
finally:
|
finally:
|
||||||
if registry is not None:
|
if registry is not None:
|
||||||
registry.close()
|
registry.close()
|
||||||
@@ -1346,12 +1298,6 @@ def clean(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Clean failed:[/red] {exc}")
|
console.print(f"[red]Clean failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Clean failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|
||||||
|
|
||||||
@app.command("semantic-list")
|
@app.command("semantic-list")
|
||||||
@@ -1472,12 +1418,6 @@ def semantic_list(
|
|||||||
else:
|
else:
|
||||||
console.print(f"[red]Semantic-list failed:[/red] {exc}")
|
console.print(f"[red]Semantic-list failed:[/red] {exc}")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=f"Unexpected error: {exc}")
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Semantic-list failed (unexpected):[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
finally:
|
finally:
|
||||||
if registry is not None:
|
if registry is not None:
|
||||||
registry.close()
|
registry.close()
|
||||||
@@ -1549,12 +1489,6 @@ def model_list(
|
|||||||
console.print("[red]Error:[/red] fastembed not installed")
|
console.print("[red]Error:[/red] fastembed not installed")
|
||||||
console.print("[yellow]Install with:[/yellow] pip install codexlens[semantic]")
|
console.print("[yellow]Install with:[/yellow] pip install codexlens[semantic]")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=str(exc))
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Model-list failed:[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|
||||||
|
|
||||||
@app.command(name="model-download")
|
@app.command(name="model-download")
|
||||||
@@ -1600,12 +1534,6 @@ def model_download(
|
|||||||
console.print("[red]Error:[/red] fastembed not installed")
|
console.print("[red]Error:[/red] fastembed not installed")
|
||||||
console.print("[yellow]Install with:[/yellow] pip install codexlens[semantic]")
|
console.print("[yellow]Install with:[/yellow] pip install codexlens[semantic]")
|
||||||
raise typer.Exit(code=1)
|
raise typer.Exit(code=1)
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=str(exc))
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Model-download failed:[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|
||||||
|
|
||||||
@app.command(name="model-delete")
|
@app.command(name="model-delete")
|
||||||
@@ -1639,13 +1567,6 @@ def model_delete(
|
|||||||
console.print(f" Model: {data['model_name']}")
|
console.print(f" Model: {data['model_name']}")
|
||||||
console.print(f" Freed space: {data['deleted_size_mb']:.1f} MB")
|
console.print(f" Freed space: {data['deleted_size_mb']:.1f} MB")
|
||||||
|
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=str(exc))
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Model-delete failed:[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|
||||||
|
|
||||||
@app.command(name="model-info")
|
@app.command(name="model-info")
|
||||||
def model_info(
|
def model_info(
|
||||||
@@ -1682,13 +1603,6 @@ def model_info(
|
|||||||
console.print(f"\n Description: {data['description']}")
|
console.print(f"\n Description: {data['description']}")
|
||||||
console.print(f" Use case: {data['use_case']}")
|
console.print(f" Use case: {data['use_case']}")
|
||||||
|
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=str(exc))
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Model-info failed:[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|
||||||
|
|
||||||
# ==================== Embedding Management Commands ====================
|
# ==================== Embedding Management Commands ====================
|
||||||
|
|
||||||
@@ -1821,13 +1735,6 @@ def embeddings_status(
|
|||||||
console.print("\n[dim]Generate embeddings with:[/dim]")
|
console.print("\n[dim]Generate embeddings with:[/dim]")
|
||||||
console.print(f" [cyan]codexlens embeddings-generate {index_path}[/cyan]")
|
console.print(f" [cyan]codexlens embeddings-generate {index_path}[/cyan]")
|
||||||
|
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=str(exc))
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Embeddings-status failed:[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|
||||||
|
|
||||||
@app.command(name="embeddings-generate")
|
@app.command(name="embeddings-generate")
|
||||||
def embeddings_generate(
|
def embeddings_generate(
|
||||||
@@ -2011,10 +1918,3 @@ def embeddings_generate(
|
|||||||
|
|
||||||
console.print("\n[dim]Use vector search with:[/dim]")
|
console.print("\n[dim]Use vector search with:[/dim]")
|
||||||
console.print(" [cyan]codexlens search 'your query' --mode pure-vector[/cyan]")
|
console.print(" [cyan]codexlens search 'your query' --mode pure-vector[/cyan]")
|
||||||
|
|
||||||
except Exception as exc:
|
|
||||||
if json_mode:
|
|
||||||
print_json(success=False, error=str(exc))
|
|
||||||
else:
|
|
||||||
console.print(f"[red]Embeddings-generate failed:[/red] {exc}")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
from functools import cached_property
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
@@ -96,17 +97,17 @@ class Config:
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise ConfigError(f"Failed to initialize data_dir at {self.data_dir}: {exc}") from exc
|
raise ConfigError(f"Failed to initialize data_dir at {self.data_dir}: {exc}") from exc
|
||||||
|
|
||||||
@property
|
@cached_property
|
||||||
def cache_dir(self) -> Path:
|
def cache_dir(self) -> Path:
|
||||||
"""Directory for transient caches."""
|
"""Directory for transient caches."""
|
||||||
return self.data_dir / "cache"
|
return self.data_dir / "cache"
|
||||||
|
|
||||||
@property
|
@cached_property
|
||||||
def index_dir(self) -> Path:
|
def index_dir(self) -> Path:
|
||||||
"""Directory where index artifacts are stored."""
|
"""Directory where index artifacts are stored."""
|
||||||
return self.data_dir / "index"
|
return self.data_dir / "index"
|
||||||
|
|
||||||
@property
|
@cached_property
|
||||||
def db_path(self) -> Path:
|
def db_path(self) -> Path:
|
||||||
"""Default SQLite index path."""
|
"""Default SQLite index path."""
|
||||||
return self.index_dir / "codexlens.db"
|
return self.index_dir / "codexlens.db"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
from typing import Any, Dict, List, Optional, Tuple
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from pydantic import BaseModel, Field, field_validator
|
from pydantic import BaseModel, Field, field_validator
|
||||||
@@ -62,24 +63,23 @@ class IndexedFile(BaseModel):
|
|||||||
return cleaned
|
return cleaned
|
||||||
|
|
||||||
|
|
||||||
|
class RelationshipType(str, Enum):
|
||||||
|
"""Types of code relationships."""
|
||||||
|
CALL = "call"
|
||||||
|
INHERITS = "inherits"
|
||||||
|
IMPORTS = "imports"
|
||||||
|
|
||||||
|
|
||||||
class CodeRelationship(BaseModel):
|
class CodeRelationship(BaseModel):
|
||||||
"""A relationship between code symbols (e.g., function calls, inheritance)."""
|
"""A relationship between code symbols (e.g., function calls, inheritance)."""
|
||||||
|
|
||||||
source_symbol: str = Field(..., min_length=1, description="Name of source symbol")
|
source_symbol: str = Field(..., min_length=1, description="Name of source symbol")
|
||||||
target_symbol: str = Field(..., min_length=1, description="Name of target symbol")
|
target_symbol: str = Field(..., min_length=1, description="Name of target symbol")
|
||||||
relationship_type: str = Field(..., min_length=1, description="Type of relationship (call, inherits, etc.)")
|
relationship_type: RelationshipType = Field(..., description="Type of relationship (call, inherits, etc.)")
|
||||||
source_file: str = Field(..., min_length=1, description="File path containing source symbol")
|
source_file: str = Field(..., min_length=1, description="File path containing source symbol")
|
||||||
target_file: Optional[str] = Field(default=None, description="File path containing target (None if same file)")
|
target_file: Optional[str] = Field(default=None, description="File path containing target (None if same file)")
|
||||||
source_line: int = Field(..., ge=1, description="Line number where relationship occurs (1-based)")
|
source_line: int = Field(..., ge=1, description="Line number where relationship occurs (1-based)")
|
||||||
|
|
||||||
@field_validator("relationship_type")
|
|
||||||
@classmethod
|
|
||||||
def validate_relationship_type(cls, value: str) -> str:
|
|
||||||
allowed_types = {"call", "inherits", "imports"}
|
|
||||||
if value not in allowed_types:
|
|
||||||
raise ValueError(f"relationship_type must be one of {allowed_types}")
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
class AdditionalLocation(BaseModel):
|
class AdditionalLocation(BaseModel):
|
||||||
"""A pointer to another location where a similar result was found.
|
"""A pointer to another location where a similar result was found.
|
||||||
|
|||||||
Reference in New Issue
Block a user