| """Pure-regex session genre detection for TurboSkillSlug.""" |
|
|
| from __future__ import annotations |
|
|
| import re |
|
|
|
|
| GENRES = ("debugging", "exploration", "authoring", "feature", "refactor", "setup") |
|
|
| _PATTERNS = { |
| "debugging": ( |
| r"\b(debug|bug|fix|error|traceback|exception|fail(?:ed|ing)?|broken|crash|" |
| r"regression|why.*not|doesn't work|not working|stuck|issue)\b", |
| ), |
| "exploration": ( |
| r"\b(explore|understand|inspect|go through|read through|map out|figure out|" |
| r"investigate|familiarize|what does|how does|codebase|repo)\b", |
| ), |
| "authoring": ( |
| r"\b(write|draft|document|readme|docs|blog|article|copy|proposal|report|" |
| r"build log|submission|explain|summarize)\b", |
| ), |
| "feature": ( |
| r"\b(add|implement|wire|build|create|ship|feature|endpoint|button|ui|" |
| r"component|integrate)\b", |
| ), |
| "refactor": ( |
| r"\b(refactor|cleanup|clean up|reorganize|simplify|rename|dedupe|extract " |
| r"helper|move .* into)\b", |
| ), |
| "setup": ( |
| r"\b(set ?up|install|configure|config|dependency|requirements|deploy|" |
| r"environment|env var|ci|workflow|initialize|scaffold)\b", |
| ), |
| } |
|
|
| _FRAMES = { |
| "debugging": ( |
| "Witness the struggle: the failed approaches, the exact symptoms, the " |
| "turning point, and what finally fixed the problem." |
| ), |
| "exploration": ( |
| "Witness the discoveries: the non-obvious facts learned about the " |
| "codebase, the map that emerged, and the clearest insight." |
| ), |
| "authoring": ( |
| "Witness the decisions: what was clarified, what false assumptions were " |
| "caught, and what document or explanation was delivered." |
| ), |
| "feature": ( |
| "Witness what was built: the new behavior, the integration points, the " |
| "naive paths that would break, and the delivered feature." |
| ), |
| "refactor": ( |
| "Witness the reshaping: what moved, what got simpler, what invariants " |
| "had to hold, and what could have broken." |
| ), |
| "setup": ( |
| "Witness the setup path: the configuration choices, dependency traps, " |
| "environment gotchas, and the final working baseline." |
| ), |
| } |
|
|
| _LEGENDS = { |
| "debugging": { |
| "knot": "dead ends and failed approaches", |
| "jewel": "verification gotchas", |
| "aperture": "the breakthrough that fixed it", |
| }, |
| "exploration": { |
| "knot": "confusions or branches that did not explain the system", |
| "jewel": "discoveries about the codebase", |
| "aperture": "the clearest insight", |
| }, |
| "authoring": { |
| "knot": "false assumptions caught", |
| "jewel": "decisions worth preserving", |
| "aperture": "the document delivered", |
| }, |
| "feature": { |
| "knot": "implementation paths that would break", |
| "jewel": "integration gotchas", |
| "aperture": "the feature working", |
| }, |
| "refactor": { |
| "knot": "risky seams and avoided regressions", |
| "jewel": "invariants worth remembering", |
| "aperture": "the simpler shape that remained", |
| }, |
| "setup": { |
| "knot": "environment traps", |
| "jewel": "configuration details worth saving", |
| "aperture": "the working baseline", |
| }, |
| } |
|
|
|
|
| def detect_genre(first_instruction: str, transcript: str = "") -> str: |
| """Detect the session genre with deterministic regex scoring.""" |
| text = f"{first_instruction}\n{transcript[:3000]}".lower() |
| scores = {genre: 0 for genre in GENRES} |
| for genre, patterns in _PATTERNS.items(): |
| for pattern in patterns: |
| scores[genre] += len(re.findall(pattern, text, re.IGNORECASE)) |
|
|
| |
| first = first_instruction.lower() |
| for genre, patterns in _PATTERNS.items(): |
| for pattern in patterns: |
| if re.search(pattern, first, re.IGNORECASE): |
| scores[genre] += 3 |
|
|
| best = max(GENRES, key=lambda genre: (scores[genre], -GENRES.index(genre))) |
| return best if scores[best] > 0 else "feature" |
|
|
|
|
| def frame_for(genre: str) -> str: |
| """Return the witness frame for a genre.""" |
| return _FRAMES.get(genre, _FRAMES["feature"]) |
|
|
|
|
| def shell_legend(genre: str) -> dict[str, str]: |
| """Return genre-specific meanings for shell features.""" |
| return dict(_LEGENDS.get(genre, _LEGENDS["feature"])) |
|
|