|
10 | 10 | import logging |
11 | 11 | import threading |
12 | 12 | from pathlib import Path |
13 | | -from typing import Any |
14 | 13 |
|
15 | 14 | from attune_help.progression import populate_progressive |
16 | 15 | from attune_help.storage import LocalFileStorage, SessionStorage |
@@ -88,6 +87,46 @@ def _load_summaries(template_dir: Path) -> dict[str, str]: |
88 | 87 | 2: '\n\n*(reference — deepest level; say "simpler" to step back)*', |
89 | 88 | } |
90 | 89 |
|
| 90 | +# Tag maps for precursor_warnings, extracted to module level |
| 91 | +# so the method body stays concise and the maps are testable. |
| 92 | +_EXT_TAGS: dict[str, list[str]] = { |
| 93 | + ".py": ["python", "imports", "testing", "error-handling"], |
| 94 | + ".yml": ["ci", "github-actions"], |
| 95 | + ".yaml": ["ci", "github-actions"], |
| 96 | + ".json": ["packaging"], |
| 97 | + ".toml": ["packaging", "python", "publishing"], |
| 98 | + ".md": ["claude-code"], |
| 99 | + ".sql": ["database", "migrations"], |
| 100 | + ".env": ["config", "secrets"], |
| 101 | + ".cfg": ["config"], |
| 102 | + ".ini": ["config"], |
| 103 | + ".js": ["javascript", "testing", "error-handling"], |
| 104 | + ".jsx": ["javascript", "testing", "error-handling"], |
| 105 | + ".ts": ["typescript", "javascript", "testing", "error-handling"], |
| 106 | + ".tsx": ["typescript", "javascript", "testing", "error-handling"], |
| 107 | + ".rs": ["rust", "testing", "error-handling"], |
| 108 | + ".go": ["go", "testing", "error-handling"], |
| 109 | + ".rb": ["ruby", "testing", "error-handling"], |
| 110 | + ".java": ["java", "testing", "error-handling"], |
| 111 | +} |
| 112 | + |
| 113 | +_NAME_TAGS: dict[str, list[str]] = { |
| 114 | + "pyproject.toml": ["deps", "publishing", "packaging"], |
| 115 | + "requirements.txt": ["deps"], |
| 116 | + "setup.py": ["publishing", "packaging"], |
| 117 | + "setup.cfg": ["publishing", "packaging"], |
| 118 | + "config.py": ["config"], |
| 119 | + "settings.py": ["config"], |
| 120 | + "models.py": ["database"], |
| 121 | + "alembic.ini": ["database", "migrations"], |
| 122 | + "dockerfile": ["ci", "cd"], |
| 123 | + "docker-compose.yml": ["ci", "cd"], |
| 124 | + ".gitignore": ["git"], |
| 125 | + ".env": ["config", "secrets"], |
| 126 | + ".env.example": ["config", "secrets"], |
| 127 | + "manifest.in": ["publishing"], |
| 128 | +} |
| 129 | + |
91 | 130 |
|
92 | 131 | def _depth_prompt(depth: int) -> str: |
93 | 132 | """Return the progressive depth prompt for the current level.""" |
@@ -289,22 +328,23 @@ def lookup( |
289 | 328 |
|
290 | 329 | def list_topics( |
291 | 330 | self, |
292 | | - type: str | None = None, |
| 331 | + type_filter: str | None = None, |
293 | 332 | limit: int | None = None, |
294 | 333 | ) -> list[str]: |
295 | 334 | """Enumerate available topic slugs. |
296 | 335 |
|
297 | 336 | Args: |
298 | | - type: Optional type filter (``"concepts"``, |
299 | | - ``"tasks"``, ``"references"``, etc.). |
| 337 | + type_filter: Optional type filter |
| 338 | + (``"concepts"``, ``"tasks"``, |
| 339 | + ``"references"``, etc.). |
300 | 340 | limit: Optional cap on results. |
301 | 341 |
|
302 | 342 | Returns: |
303 | 343 | Sorted list of slugs. |
304 | 344 | """ |
305 | 345 | from attune_help.discovery import list_topics as _list |
306 | 346 |
|
307 | | - return _list(self.generated_dir, type=type, limit=limit) |
| 347 | + return _list(self.generated_dir, type_filter=type_filter, limit=limit) |
308 | 348 |
|
309 | 349 | def search( |
310 | 350 | self, |
@@ -486,48 +526,8 @@ def precursor_warnings( |
486 | 526 | name = Path(file_path).name.lower() |
487 | 527 |
|
488 | 528 | tags: list[str] = [] |
489 | | - |
490 | | - # Extension-based triggers |
491 | | - ext_map = { |
492 | | - ".py": ["python", "imports", "testing", "error-handling"], |
493 | | - ".yml": ["ci", "github-actions"], |
494 | | - ".yaml": ["ci", "github-actions"], |
495 | | - ".json": ["packaging"], |
496 | | - ".toml": ["packaging", "python", "publishing"], |
497 | | - ".md": ["claude-code"], |
498 | | - ".sql": ["database", "migrations"], |
499 | | - ".env": ["config", "secrets"], |
500 | | - ".cfg": ["config"], |
501 | | - ".ini": ["config"], |
502 | | - ".js": ["javascript", "testing", "error-handling"], |
503 | | - ".jsx": ["javascript", "testing", "error-handling"], |
504 | | - ".ts": ["typescript", "javascript", "testing", "error-handling"], |
505 | | - ".tsx": ["typescript", "javascript", "testing", "error-handling"], |
506 | | - ".rs": ["rust", "testing", "error-handling"], |
507 | | - ".go": ["go", "testing", "error-handling"], |
508 | | - ".rb": ["ruby", "testing", "error-handling"], |
509 | | - ".java": ["java", "testing", "error-handling"], |
510 | | - } |
511 | | - tags.extend(ext_map.get(ext, [])) |
512 | | - |
513 | | - # Filename-based triggers |
514 | | - name_map = { |
515 | | - "pyproject.toml": ["deps", "publishing", "packaging"], |
516 | | - "requirements.txt": ["deps"], |
517 | | - "setup.py": ["publishing", "packaging"], |
518 | | - "setup.cfg": ["publishing", "packaging"], |
519 | | - "config.py": ["config"], |
520 | | - "settings.py": ["config"], |
521 | | - "models.py": ["database"], |
522 | | - "alembic.ini": ["database", "migrations"], |
523 | | - "dockerfile": ["ci", "cd"], |
524 | | - "docker-compose.yml": ["ci", "cd"], |
525 | | - ".gitignore": ["git"], |
526 | | - ".env": ["config", "secrets"], |
527 | | - ".env.example": ["config", "secrets"], |
528 | | - "manifest.in": ["publishing"], |
529 | | - } |
530 | | - tags.extend(name_map.get(name, [])) |
| 529 | + tags.extend(_EXT_TAGS.get(ext, [])) |
| 530 | + tags.extend(_NAME_TAGS.get(name, [])) |
531 | 531 |
|
532 | 532 | if not tags: |
533 | 533 | return [] |
@@ -577,7 +577,7 @@ def precursor_warnings( |
577 | 577 | return results |
578 | 578 |
|
579 | 579 | @staticmethod |
580 | | - def _auto_detect_renderer() -> Any: |
| 580 | + def _auto_detect_renderer() -> Callable[[PopulatedTemplate], str]: |
581 | 581 | """Detect the best renderer for the current environment. |
582 | 582 |
|
583 | 583 | Priority: |
|
0 commit comments