feat(types): Complete strict static analysis and typing track
This commit is contained in:
45
aggregate.py
45
aggregate.py
@@ -16,7 +16,7 @@ import tomllib
|
||||
import re
|
||||
import glob
|
||||
from pathlib import Path, PureWindowsPath
|
||||
from typing import Any
|
||||
from typing import Any, cast
|
||||
import summarize
|
||||
import project_manager
|
||||
from file_cache import ASTParser
|
||||
@@ -67,9 +67,11 @@ def build_files_section(base_dir: Path, files: list[str | dict[str, Any]]) -> st
|
||||
sections = []
|
||||
for entry_raw in files:
|
||||
if isinstance(entry_raw, dict):
|
||||
entry = entry_raw.get("path")
|
||||
entry = cast(str, entry_raw.get("path", ""))
|
||||
else:
|
||||
entry = entry_raw
|
||||
if not entry or not isinstance(entry, str):
|
||||
continue
|
||||
paths = resolve_paths(base_dir, entry)
|
||||
if not paths:
|
||||
sections.append(f"### `{entry}`\n\n```text\nERROR: no files matched: {entry}\n```")
|
||||
@@ -90,6 +92,8 @@ def build_files_section(base_dir: Path, files: list[str | dict[str, Any]]) -> st
|
||||
def build_screenshots_section(base_dir: Path, screenshots: list[str]) -> str:
|
||||
sections = []
|
||||
for entry in screenshots:
|
||||
if not entry or not isinstance(entry, str):
|
||||
continue
|
||||
paths = resolve_paths(base_dir, entry)
|
||||
if not paths:
|
||||
sections.append(f"### `{entry}`\n\n_ERROR: no files matched: {entry}_")
|
||||
@@ -115,14 +119,16 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[
|
||||
mtime : float (last modification time, for skip-if-unchanged optimization)
|
||||
tier : int | None (optional tier for context management)
|
||||
"""
|
||||
items = []
|
||||
items: list[dict[str, Any]] = []
|
||||
for entry_raw in files:
|
||||
if isinstance(entry_raw, dict):
|
||||
entry = entry_raw.get("path")
|
||||
entry = cast(str, entry_raw.get("path", ""))
|
||||
tier = entry_raw.get("tier")
|
||||
else:
|
||||
entry = entry_raw
|
||||
tier = None
|
||||
if not entry or not isinstance(entry, str):
|
||||
continue
|
||||
paths = resolve_paths(base_dir, entry)
|
||||
if not paths:
|
||||
items.append({"path": None, "entry": entry, "content": f"ERROR: no files matched: {entry}", "error": True, "mtime": 0.0, "tier": tier})
|
||||
@@ -156,14 +162,15 @@ def _build_files_section_from_items(file_items: list[dict[str, Any]]) -> str:
|
||||
sections = []
|
||||
for item in file_items:
|
||||
path = item.get("path")
|
||||
entry = item.get("entry", "unknown")
|
||||
content = item.get("content", "")
|
||||
entry = cast(str, item.get("entry", "unknown"))
|
||||
content = cast(str, item.get("content", ""))
|
||||
if path is None:
|
||||
sections.append(f"### `{entry}`\n\n```text\n{content}\n```")
|
||||
continue
|
||||
suffix = path.suffix.lstrip(".") if hasattr(path, "suffix") else "text"
|
||||
p = cast(Path, path)
|
||||
suffix = p.suffix.lstrip(".") if hasattr(p, "suffix") else "text"
|
||||
lang = suffix if suffix else "text"
|
||||
original = entry if "*" not in entry else str(path)
|
||||
original = entry if "*" not in entry else str(p)
|
||||
sections.append(f"### `{original}`\n\n```{lang}\n{content}\n```")
|
||||
return "\n\n---\n\n".join(sections)
|
||||
|
||||
@@ -205,15 +212,16 @@ def build_tier1_context(file_items: list[dict[str, Any]], screenshot_base_dir: P
|
||||
sections = []
|
||||
for item in file_items:
|
||||
path = item.get("path")
|
||||
name = path.name if path else ""
|
||||
name = path.name if path and isinstance(path, Path) else ""
|
||||
if name in core_files or item.get("tier") == 1:
|
||||
# Include in full
|
||||
sections.append("### `" + (item.get("entry") or str(path)) + "`\n\n" +
|
||||
f"```{path.suffix.lstrip('.') if path.suffix else 'text'}\n{item.get('content', '')}\n```")
|
||||
sections.append("### `" + (cast(str, item.get("entry")) or str(path)) + "`\n\n" +
|
||||
f"```{path.suffix.lstrip('.') if path and isinstance(path, Path) and path.suffix else 'text'}\n{item.get('content', '')}\n```")
|
||||
else:
|
||||
# Summarize
|
||||
sections.append("### `" + (item.get("entry") or str(path)) + "`\n\n" +
|
||||
summarize.summarise_file(path, item.get("content", "")))
|
||||
if path and isinstance(path, Path):
|
||||
sections.append("### `" + (cast(str, item.get("entry")) or str(path)) + "`\n\n" +
|
||||
summarize.summarise_file(path, cast(str, item.get("content", ""))))
|
||||
parts.append("## Files (Tier 1 - Mixed)\n\n" + "\n\n---\n\n".join(sections))
|
||||
if screenshots:
|
||||
parts.append("## Screenshots\n\n" + build_screenshots_section(screenshot_base_dir, screenshots))
|
||||
@@ -237,20 +245,20 @@ def build_tier3_context(file_items: list[dict[str, Any]], screenshot_base_dir: P
|
||||
if file_items:
|
||||
sections = []
|
||||
for item in file_items:
|
||||
path = item.get("path")
|
||||
entry = item.get("entry", "")
|
||||
path = cast(Path, item.get("path"))
|
||||
entry = cast(str, item.get("entry", ""))
|
||||
path_str = str(path) if path else ""
|
||||
# Check if this file is in focus_files (by name or path)
|
||||
is_focus = False
|
||||
for focus in focus_files:
|
||||
if focus == entry or (path and focus == path.name) or focus in path_str:
|
||||
if focus == entry or (path and focus == path.name) or (path_str and focus in path_str):
|
||||
is_focus = True
|
||||
break
|
||||
if is_focus or item.get("tier") == 3:
|
||||
sections.append("### `" + (entry or path_str) + "`\n\n" +
|
||||
f"```{path.suffix.lstrip('.') if path and path.suffix else 'text'}\n{item.get('content', '')}\n```")
|
||||
else:
|
||||
content = item.get("content", "")
|
||||
content = cast(str, item.get("content", ""))
|
||||
if path and path.suffix == ".py" and not item.get("error"):
|
||||
try:
|
||||
parser = ASTParser("python")
|
||||
@@ -260,7 +268,8 @@ def build_tier3_context(file_items: list[dict[str, Any]], screenshot_base_dir: P
|
||||
# Fallback to summary if AST parsing fails
|
||||
sections.append(f"### `{entry or path_str}`\n\n" + summarize.summarise_file(path, content))
|
||||
else:
|
||||
sections.append(f"### `{entry or path_str}`\n\n" + summarize.summarise_file(path, content))
|
||||
if path:
|
||||
sections.append(f"### `{entry or path_str}`\n\n" + summarize.summarise_file(path, content))
|
||||
parts.append("## Files (Tier 3 - Focused)\n\n" + "\n\n---\n\n".join(sections))
|
||||
if screenshots:
|
||||
parts.append("## Screenshots\n\n" + build_screenshots_section(screenshot_base_dir, screenshots))
|
||||
|
||||
Reference in New Issue
Block a user