feat: implement tweaks plan - modals, smart shell, spinner, /models, debug log, skills

Phase 1: Permission modal dialog, session resume modal, HistoryInput with
up/down arrow cycling, remove "You:" echo from chat log, LLM client cleanup
on unmount.

Phase 2: Smart shell auto-approve using allowed/denied command lists from
ToolsConfig, animated thinking spinner with live token count in status bar.

Phase 3: /models slash command (list + switch), CLI directory positional
argument, JSONL debug logger with rotation.

Phase 4: Skills system with SkillsManager, load_skill LLM tool, /skills
listing, skill invocation via slash commands, system prompt integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 15:46:44 -05:00
parent 7600195ecf
commit 3f9012e6c2
13 changed files with 683 additions and 37 deletions

View File

@@ -90,6 +90,24 @@ class DisplayConfig(BaseModel):
stream_output: bool = Field(default=True, description="Stream LLM output to terminal")
class SkillsConfig(BaseModel):
"""Skills system configuration."""
enabled: bool = Field(default=True, description="Enable skills system")
directories: list[Path] = Field(
default_factory=lambda: [Path(".sneakycode/skills")],
description="Directories to scan for skill markdown files",
)
class DebugConfig(BaseModel):
"""Debug logging configuration."""
enabled: bool = Field(default=False, description="Enable debug logging")
log_dir: Path = Field(default=Path(".sneakycode/logs"), description="Debug log directory")
max_files: int = Field(default=10, description="Max debug log files to retain")
class AppConfig(BaseModel):
"""Top-level application configuration composing all sub-configs."""
@@ -99,6 +117,8 @@ class AppConfig(BaseModel):
tools: ToolsConfig = Field(default_factory=ToolsConfig)
display: DisplayConfig = Field(default_factory=DisplayConfig)
session: SessionConfig = Field(default_factory=SessionConfig)
debug: DebugConfig = Field(default_factory=DebugConfig)
skills: SkillsConfig = Field(default_factory=SkillsConfig)
@model_validator(mode="after")
def resolve_workspace_root(self) -> "AppConfig":