diff --git a/cmd/chat_model_test.go b/cmd/chat_model_test.go index d9ed693c..9ba50d1a 100644 --- a/cmd/chat_model_test.go +++ b/cmd/chat_model_test.go @@ -84,6 +84,8 @@ func restoreThemeGlobals(t *testing.T) { savedCost, savedBranch, savedToken, savedCwd := costViolet, branchYellow, tokenSage, cwdBlue savedPrimary, savedMuted, savedPlaceholder, savedDisabled := textPrimary, textMuted, textPlaceholder, textDisabled savedBorderDim, savedBgCode := borderDim, bgCode + savedInputBorder := inputBorderStyle + savedMinimalChrome := minimalChrome hasDark := lipgloss.HasDarkBackground(os.Stdin, os.Stdout) t.Cleanup(func() { rhoColor, successTeal, warnAmber, errorCoral, infoSky = savedRho, savedSuccess, savedWarn, savedErr, savedInfo @@ -93,6 +95,10 @@ func restoreThemeGlobals(t *testing.T) { costViolet, branchYellow, tokenSage, cwdBlue = savedCost, savedBranch, savedToken, savedCwd textPrimary, textMuted, textPlaceholder, textDisabled = savedPrimary, savedMuted, savedPlaceholder, savedDisabled borderDim, bgCode = savedBorderDim, savedBgCode + // ApplyTheme also rewrites the input border and chrome mode; restore + // them so a palette swap cannot leak into layout tests. + inputBorderStyle = savedInputBorder + minimalChrome = savedMinimalChrome // HasDarkBackground is now a function (no args), SetHasDarkBackground removed in v2 _ = hasDark }) diff --git a/cmd/contextual_help.go b/cmd/contextual_help.go index bf7317a2..8013ff8e 100644 --- a/cmd/contextual_help.go +++ b/cmd/contextual_help.go @@ -33,451 +33,452 @@ func NewContextualHelp() *ContextualHelp { } func (ch *ContextualHelp) registerAllEntries() { - entries := []*HelpEntry{ - // ─── Slash Commands ─────────────────────────────────────────── - { - Topic: "/commit", - Summary: "Auto-commit with AI message", - Detail: "Creates a git commit with an AI-generated message based on staged changes.", - Examples: []string{"/commit — commit all staged changes", "/commit --amend — amend the last commit", `/commit "msg" — use custom message`}, - Related: []string{"/diff", "/branch", "/undo"}, - Category: "slash-commands", - }, - { - Topic: "/diff", - Summary: "Show current changes with AI summary", - Detail: "Displays a diff of uncommitted changes along with an AI-generated summary explaining what changed and why.", - Examples: []string{"/diff — show all uncommitted changes", "/diff --staged — show only staged changes", "/diff file.go — diff a specific file"}, - Related: []string{"/commit", "/status", "/branch"}, - Category: "slash-commands", - }, - { - Topic: "/test", - Summary: "Run tests with AI analysis", - Detail: "Runs your project test suite and provides AI-powered analysis of failures, including suggested fixes.", - Examples: []string{"/test — run all tests", "/test ./pkg/... — run tests in a package", "/test -v — verbose output"}, - Related: []string{"/lint", "/bugfind", "/fix"}, - Category: "slash-commands", - }, - { - Topic: "/lint", - Summary: "Lint code and suggest fixes", - Detail: "Runs configured linters on your codebase and provides AI-powered fix suggestions for any issues found.", - Examples: []string{"/lint — lint entire project", "/lint ./cmd/... — lint specific package", "/lint --fix — auto-fix where possible"}, - Related: []string{"/test", "/fix", "/format"}, - Category: "slash-commands", - }, - { - Topic: "/branch", - Summary: "Create or switch branches", - Detail: "Manages git branches with AI-suggested naming based on your current work context.", - Examples: []string{"/branch — list branches", "/branch feat/login — create and switch to branch", "/branch -d old-feat — delete a branch"}, - Related: []string{"/commit", "/diff", "/merge"}, - Category: "slash-commands", - }, - { - Topic: "/undo", - Summary: "Undo last action safely", - Detail: "Reverts the last rho action (commit, file edit, etc.) using safe snapshot-based rollback.", - Examples: []string{"/undo — undo last action", "/undo --hard — undo and discard changes", "/undo 3 — undo last 3 actions"}, - Related: []string{"/commit", "/snapshot", "/history"}, - Category: "slash-commands", - }, - { - Topic: "/status", - Summary: "Show project and session status", - Detail: "Displays current git status, session info, active tasks, and recent activity in a unified view.", - Examples: []string{"/status — full status overview", "/status --short — abbreviated status", "/status --git — git status only"}, - Related: []string{"/diff", "/history", "/session"}, - Category: "slash-commands", - }, - { - Topic: "/fix", - Summary: "Auto-fix errors and issues", - Detail: "Analyzes errors from tests, linting, or compilation and applies AI-generated fixes.", - Examples: []string{"/fix — fix last error", "/fix test — fix failing tests", "/fix lint — fix lint issues"}, - Related: []string{"/test", "/lint", "/bugfind"}, - Category: "slash-commands", - }, - { - Topic: "/config", - Summary: "Open configuration panel", - Detail: "Opens the interactive configuration panel for rho settings, model selection, and preferences.", - Examples: []string{"/config — open config panel", "/config model — change model", "/config key remove — remove stored API key", "/config keys — show key status"}, - Related: []string{"/session", "/profile", "/rules"}, - Category: "slash-commands", - }, - { - Topic: "/chat", - Summary: "Start or continue a conversation", - Detail: "Opens the AI chat interface for freeform conversation about your code, design decisions, or debugging.", - Examples: []string{"/chat — start new conversation", "/chat \"explain this\" — ask a question directly", "/chat --continue — continue last conversation"}, - Related: []string{"/explain", "/ask", "/session"}, - Category: "slash-commands", - }, - { - Topic: "/explain", - Summary: "Explain code or concepts", - Detail: "Provides AI-generated explanations of selected code, functions, or architectural patterns.", - Examples: []string{"/explain main.go — explain a file", "/explain func Init — explain a function", "/explain --deep — detailed explanation"}, - Related: []string{"/chat", "/docs", "/repomap"}, - Category: "slash-commands", - }, - { - Topic: "/search", - Summary: "Semantic code search", - Detail: "Searches your codebase using semantic understanding, not just text matching.", - Examples: []string{"/search \"auth logic\" — find authentication code", "/search --type func — search functions only", "/search --file *.go — limit to Go files"}, - Related: []string{"/explain", "/repomap", "/find"}, - Category: "slash-commands", - }, - { - Topic: "/format", - Summary: "Format code files", - Detail: "Formats source files using the configured formatter for each language.", - Examples: []string{"/format — format all changed files", "/format main.go — format specific file", "/format --check — check without modifying"}, - Related: []string{"/lint", "/fix", "/commit"}, - Category: "slash-commands", - }, - { - Topic: "/merge", - Summary: "Merge branches with conflict resolution", - Detail: "Merges branches and provides AI-assisted conflict resolution when conflicts arise.", - Examples: []string{"/merge main — merge main into current", "/merge --squash feat — squash merge a feature", "/merge --abort — abort in-progress merge"}, - Related: []string{"/branch", "/diff", "/commit"}, - Category: "slash-commands", - }, - { - Topic: "/snapshot", - Summary: "Save or restore project snapshots", - Detail: "Creates point-in-time snapshots of your project state that can be restored later.", - Examples: []string{"/snapshot — create a snapshot", "/snapshot list — list all snapshots", "/snapshot restore 3 — restore snapshot #3"}, - Related: []string{"/undo", "/history", "/branch"}, - Category: "slash-commands", - }, - { - Topic: "/history", - Summary: "View session and action history", - Detail: "Displays a timeline of actions taken during the current or past sessions.", - Examples: []string{"/history — show recent history", "/history --all — show full history", "/history --session 5 — history for session 5"}, - Related: []string{"/undo", "/snapshot", "/status"}, - Category: "slash-commands", - }, - { - Topic: "/session", - Summary: "Manage rho sessions", - Detail: "Start, stop, resume, or list rho working sessions with full context preservation.", - Examples: []string{"/session — show current session", "/session new — start new session", "/session resume 3 — resume session #3"}, - Related: []string{"/status", "/history", "/config"}, - Category: "slash-commands", - }, - { - Topic: "/bugfind", - Summary: "AI-powered bug detection", - Detail: "Scans code for potential bugs, race conditions, and logic errors using AI analysis.", - Examples: []string{"/bugfind — scan all changed files", "/bugfind ./pkg/... — scan specific package", "/bugfind --deep — thorough analysis"}, - Related: []string{"/test", "/lint", "/fix"}, - Category: "slash-commands", - }, - { - Topic: "/profile", - Summary: "Manage user profiles", - Detail: "Switch between user profiles with different settings, API keys, and preferences.", - Examples: []string{"/profile — show current profile", "/profile work — switch to work profile", "/profile create home — create new profile"}, - Related: []string{"/config", "/session", "/rules"}, - Category: "slash-commands", - }, - { - Topic: "/rules", - Summary: "Manage project rules", - Detail: "View and edit project-specific rules that guide AI behavior and code generation.", - Examples: []string{"/rules — list active rules", "/rules add \"no tabs\" — add a new rule", "/rules edit 3 — edit rule #3"}, - Related: []string{"/config", "/profile", "/docs"}, - Category: "slash-commands", - }, - { - Topic: "/docs", - Summary: "Generate or view documentation", - Detail: "Generates documentation for functions, packages, or entire projects using AI.", - Examples: []string{"/docs — generate for changed files", "/docs pkg/auth — document a package", "/docs --format md — output as markdown"}, - Related: []string{"/explain", "/repomap", "/chat"}, - Category: "slash-commands", - }, - { - Topic: "/repomap", - Summary: "Generate repository map", - Detail: "Creates an AI-generated map of your repository structure, showing key files and their relationships.", - Examples: []string{"/repomap — full repo map", "/repomap --compact — abbreviated map", "/repomap ./cmd — map a subdirectory"}, - Related: []string{"/explain", "/search", "/docs"}, - Category: "slash-commands", - }, - { - Topic: "/find", - Summary: "Find files and symbols", - Detail: "Locates files, functions, types, and other symbols in your project.", - Examples: []string{"/find Handler — find symbol by name", "/find --type struct — find all structs", "/find --file *.test — find test files"}, - Related: []string{"/search", "/repomap", "/explain"}, - Category: "slash-commands", - }, - { - Topic: "/ask", - Summary: "Ask a question about the codebase", - Detail: "Asks the AI a question with full codebase context, without making any changes.", - Examples: []string{"/ask \"how does auth work?\"", "/ask \"what calls this function?\"", "/ask \"is this thread-safe?\""}, - Related: []string{"/chat", "/explain", "/search"}, - Category: "slash-commands", - }, - // ─── Common Tasks ──────────────────────────────────────────── - { - Topic: "how to fix tests", - Summary: "Fixing failing tests with rho", - Detail: "Use /test to run tests and identify failures, then /fix test to apply AI-generated fixes. For complex failures, use /chat to discuss the issue.", - Examples: []string{"/test — identify failures", "/fix test — auto-fix test failures", "/chat \"why is TestX failing?\""}, - Related: []string{"/test", "/fix", "/bugfind"}, - Category: "common-tasks", - }, - { - Topic: "how to commit", - Summary: "Making commits with rho", - Detail: "Stage your changes with git add, then use /commit to create a commit with an AI-generated message. Use /diff first to review what you are committing.", - Examples: []string{"/diff --staged — review staged changes", "/commit — commit with AI message", `/commit "my message" — commit with custom message`}, - Related: []string{"/commit", "/diff", "/branch"}, - Category: "common-tasks", - }, - { - Topic: "how to debug", - Summary: "Debugging with rho AI assistance", - Detail: "Describe the bug in /chat or use /bugfind for automated detection. For test failures, /test with /fix provides targeted debugging.", - Examples: []string{"/bugfind — automated bug detection", "/chat \"I see panic at line 42\"", "/test -v ./pkg/... — verbose test output"}, - Related: []string{"/bugfind", "/test", "/fix", "/chat"}, - Category: "common-tasks", - }, - { - Topic: "how to review code", - Summary: "Code review assistance", - Detail: "Use /diff to see changes with AI summary, /bugfind to scan for issues, and /explain for understanding complex sections.", - Examples: []string{"/diff — see changes with AI summary", "/bugfind — scan for potential issues", "/explain func Handle — understand a function"}, - Related: []string{"/diff", "/bugfind", "/explain"}, - Category: "common-tasks", - }, - { - Topic: "how to refactor", - Summary: "Refactoring code with AI assistance", - Detail: "Use /chat to discuss refactoring strategies, then rho can apply changes. Use /snapshot before large refactors for safety.", - Examples: []string{"/snapshot — save state before refactor", "/chat \"refactor auth to use interfaces\"", "/test — verify nothing broke"}, - Related: []string{"/chat", "/snapshot", "/test", "/undo"}, - Category: "common-tasks", - }, - { - Topic: "how to start a session", - Summary: "Starting a new rho session", - Detail: "Run rho in your project directory to start a session. Your context is preserved across the session. Use /session to manage sessions.", - Examples: []string{"rho — start rho in current dir", "/session new — start fresh session", "/session resume — resume last session"}, - Related: []string{"/session", "/config", "/status"}, - Category: "common-tasks", - }, - // ─── Error Explanations ────────────────────────────────────── - { - Topic: "error: api key invalid", - Summary: "API key is missing or invalid", - Detail: "Your API key is not configured or has expired. Save a new key via /config (paste in the panel). Keys are stored in the OS secret store (macOS Keychain / Linux keyring).", - Examples: []string{"/config — paste API key in the config panel", "rho credentials status — verify stored keys"}, - Related: []string{"/config", "error: rate limit", "error: network"}, - Category: "errors", - }, - { - Topic: "error: rate limit", - Summary: "API rate limit exceeded", - Detail: "You have exceeded the API rate limit. Rho will automatically retry with exponential backoff. Consider upgrading your plan for higher limits.", - Examples: []string{"/config model — switch to a lower-tier model", "/status — check rate limit status"}, - Related: []string{"error: api key invalid", "/config", "error: timeout"}, - Category: "errors", - }, - { - Topic: "error: network", - Summary: "Network connection failed", - Detail: "Unable to reach the API server. Check your internet connection and proxy settings.", - Examples: []string{"/config proxy — configure proxy", "export HTTPS_PROXY=http://proxy:8080"}, - Related: []string{"error: timeout", "error: api key invalid", "/config"}, - Category: "errors", - }, - { - Topic: "error: timeout", - Summary: "Request timed out", - Detail: "The API request took too long and was cancelled. This may be due to network issues or a complex request. Try again or simplify your request.", - Examples: []string{"/config timeout 60 — increase timeout to 60s", "/chat --short — request shorter response"}, - Related: []string{"error: network", "error: rate limit", "/config"}, - Category: "errors", - }, - { - Topic: "error: git conflict", - Summary: "Git merge conflict detected", - Detail: "A merge conflict was encountered. Rho can assist with conflict resolution using AI to understand both sides.", - Examples: []string{"/merge --resolve — AI-assisted resolution", "/diff --conflicts — show conflict details", "/undo — abort and go back"}, - Related: []string{"/merge", "/diff", "/undo"}, - Category: "errors", - }, - { - Topic: "error: no git repo", - Summary: "Not in a git repository", - Detail: "Rho requires a git repository. Initialize one with git init or navigate to an existing repo.", - Examples: []string{"git init — initialize new repo", "cd /path/to/repo — navigate to a repo"}, - Related: []string{"/status", "/branch", "/commit"}, - Category: "errors", - }, - { - Topic: "error: model not available", - Summary: "Selected model is not available", - Detail: "The configured model is not available for your account. Switch to a different model or check your plan.", - Examples: []string{"/config model — change model", "/config model sonnet — use a specific model"}, - Related: []string{"/config", "error: api key invalid"}, - Category: "errors", - }, - { - Topic: "error: file too large", - Summary: "File exceeds size limit", - Detail: "The file is too large to process in a single request. Try working with smaller sections or use streaming mode.", - Examples: []string{"/explain func X — explain specific function", "/chat \"summarize main.go lines 1-100\""}, - Related: []string{"/explain", "/search", "/config"}, - Category: "errors", - }, - // ─── Configuration Options ─────────────────────────────────── - { - Topic: "config: model", - Summary: "Configure the AI model", - Detail: "Choose which AI model to use. Options include various sizes with different speed/quality tradeoffs.", - Examples: []string{"/config model opus — use most capable model", "/config model sonnet — balanced model", "/config model haiku — fastest model"}, - Related: []string{"/config", "config: api-key", "config: temperature"}, - Category: "configuration", - }, - { - Topic: "config: api-key", - Summary: "Set the API key", - Detail: "API keys are stored in the OS secret store. Use /config to paste a key, or /config key remove to delete one.", - Examples: []string{"/config — paste API key in the config panel", "/config key remove — remove a stored key", "rho credentials status — list configured providers"}, - Related: []string{"/config", "config: model", "error: api key invalid"}, - Category: "configuration", - }, - { - Topic: "config: temperature", - Summary: "Set model temperature", - Detail: "Controls randomness in AI responses. Lower values (0.0) are more deterministic, higher values (1.0) are more creative.", - Examples: []string{"/config temperature 0.0 — deterministic", "/config temperature 0.7 — balanced", "/config temperature 1.0 — creative"}, - Related: []string{"/config", "config: model", "config: max-tokens"}, - Category: "configuration", - }, - { - Topic: "config: max-tokens", - Summary: "Set maximum response length", - Detail: "Limits the maximum number of tokens in AI responses. Higher values allow longer responses but cost more.", - Examples: []string{"/config max-tokens 1024 — short responses", "/config max-tokens 4096 — medium responses", "/config max-tokens 16384 — long responses"}, - Related: []string{"/config", "config: temperature", "config: model"}, - Category: "configuration", - }, - { - Topic: "config: editor", - Summary: "Set preferred editor", - Detail: "Configure which editor rho uses when opening files for editing.", - Examples: []string{"/config editor vim — use vim", "/config editor code — use VS Code", "/config editor nano — use nano"}, - Related: []string{"/config", "config: theme", "config: shell"}, - Category: "configuration", - }, - { - Topic: "config: theme", - Summary: "Set color theme", - Detail: "Choose the color theme for rho terminal output. Supports light and dark terminal backgrounds.", - Examples: []string{"/config theme dark — dark background theme", "/config theme light — light background theme", "/config theme none — disable colors"}, - Related: []string{"/config", "config: editor", "config: shell"}, - Category: "configuration", - }, - { - Topic: "config: shell", - Summary: "Set shell for command execution", - Detail: "Configure which shell rho uses when running commands.", - Examples: []string{"/config shell bash — use bash", "/config shell zsh — use zsh", "/config shell fish — use fish"}, - Related: []string{"/config", "config: editor", "config: theme"}, - Category: "configuration", - }, - { - Topic: "config: proxy", - Summary: "Configure HTTP proxy", - Detail: "Set a proxy server for API requests. Useful in corporate environments.", - Examples: []string{"/config proxy http://proxy:8080", "/config proxy socks5://proxy:1080", "/config proxy none — disable proxy"}, - Related: []string{"/config", "error: network", "config: timeout"}, - Category: "configuration", - }, - { - Topic: "config: timeout", - Summary: "Set request timeout", - Detail: "Configure how long to wait for API responses before timing out. Default is 30 seconds.", - Examples: []string{"/config timeout 30 — 30 second timeout", "/config timeout 60 — 60 second timeout", "/config timeout 120 — 2 minute timeout"}, - Related: []string{"/config", "error: timeout", "config: proxy"}, - Category: "configuration", - }, - // ─── Tool Descriptions ─────────────────────────────────────── - { - Topic: "tool: repomap", - Summary: "Repository mapping engine", - Detail: "Analyzes your repository structure to build a semantic map of files, symbols, and their relationships. Used internally to provide context to the AI.", - Examples: []string{"/repomap — view the generated map", "/repomap --refresh — force rebuild"}, - Related: []string{"/search", "/explain", "tool: embeddings"}, - Category: "tools", - }, - { - Topic: "tool: embeddings", - Summary: "Code embedding engine", - Detail: "Generates vector embeddings of your code for semantic search and similarity matching.", - Examples: []string{"/search \"auth logic\" — uses embeddings internally"}, - Related: []string{"/search", "tool: repomap", "tool: memory"}, - Category: "tools", - }, - { - Topic: "tool: memory", - Summary: "Session memory system", - Detail: "Stores context across sessions including conversation history, decisions made, and project understanding.", - Examples: []string{"/session resume — restore memory from session", "/history — view remembered actions"}, - Related: []string{"/session", "/history", "tool: embeddings"}, - Category: "tools", - }, - { - Topic: "tool: snapshot", - Summary: "Project snapshot engine", - Detail: "Creates and manages point-in-time snapshots of your project for safe experimentation and undo capability.", - Examples: []string{"/snapshot — create a snapshot", "/snapshot restore 2 — restore a snapshot", "/undo — uses snapshots internally"}, - Related: []string{"/snapshot", "/undo", "tool: memory"}, - Category: "tools", - }, - { - Topic: "tool: parallel", - Summary: "Parallel execution engine", - Detail: "Runs multiple AI tasks in parallel for faster results. Used for multi-file analysis and batch operations.", - Examples: []string{"/bugfind — scans files in parallel", "/test — analyzes results in parallel"}, - Related: []string{"/bugfind", "/test", "tool: repomap"}, - Category: "tools", - }, - { - Topic: "tool: bash", - Summary: "Run shell commands", - Detail: "Runs shell commands in the workspace. Destructive patterns are blocked and every call is subject to the active autonomy tier.", - Examples: []string{"/test — runs the project test command", "/fix — validates fixes"}, - Related: []string{"/test", "/fix", "tool: snapshot"}, - Category: "tools", - }, - { - Topic: "tool: daemon", - Summary: "Background daemon service", - Detail: "Runs in the background to provide file watching, indexing, and real-time analysis of your project.", - Examples: []string{"rho daemon start — start the daemon", "rho daemon status — check daemon status", "rho daemon stop — stop the daemon"}, - Related: []string{"/status", "tool: repomap", "tool: memory"}, - Category: "tools", - }, - } - - for _, entry := range entries { + for _, entry := range builtinHelpEntries { ch.Entries[entry.Topic] = entry } } +// builtinHelpEntries is the static contextual-help catalog. +var builtinHelpEntries = []*HelpEntry{ + // ─── Slash Commands ─────────────────────────────────────────── + { + Topic: "/commit", + Summary: "Auto-commit with AI message", + Detail: "Creates a git commit with an AI-generated message based on staged changes.", + Examples: []string{"/commit — commit all staged changes", "/commit --amend — amend the last commit", `/commit "msg" — use custom message`}, + Related: []string{"/diff", "/branch", "/undo"}, + Category: "slash-commands", + }, + { + Topic: "/diff", + Summary: "Show current changes with AI summary", + Detail: "Displays a diff of uncommitted changes along with an AI-generated summary explaining what changed and why.", + Examples: []string{"/diff — show all uncommitted changes", "/diff --staged — show only staged changes", "/diff file.go — diff a specific file"}, + Related: []string{"/commit", "/status", "/branch"}, + Category: "slash-commands", + }, + { + Topic: "/test", + Summary: "Run tests with AI analysis", + Detail: "Runs your project test suite and provides AI-powered analysis of failures, including suggested fixes.", + Examples: []string{"/test — run all tests", "/test ./pkg/... — run tests in a package", "/test -v — verbose output"}, + Related: []string{"/lint", "/bugfind", "/fix"}, + Category: "slash-commands", + }, + { + Topic: "/lint", + Summary: "Lint code and suggest fixes", + Detail: "Runs configured linters on your codebase and provides AI-powered fix suggestions for any issues found.", + Examples: []string{"/lint — lint entire project", "/lint ./cmd/... — lint specific package", "/lint --fix — auto-fix where possible"}, + Related: []string{"/test", "/fix", "/format"}, + Category: "slash-commands", + }, + { + Topic: "/branch", + Summary: "Create or switch branches", + Detail: "Manages git branches with AI-suggested naming based on your current work context.", + Examples: []string{"/branch — list branches", "/branch feat/login — create and switch to branch", "/branch -d old-feat — delete a branch"}, + Related: []string{"/commit", "/diff", "/merge"}, + Category: "slash-commands", + }, + { + Topic: "/undo", + Summary: "Undo last action safely", + Detail: "Reverts the last rho action (commit, file edit, etc.) using safe snapshot-based rollback.", + Examples: []string{"/undo — undo last action", "/undo --hard — undo and discard changes", "/undo 3 — undo last 3 actions"}, + Related: []string{"/commit", "/snapshot", "/history"}, + Category: "slash-commands", + }, + { + Topic: "/status", + Summary: "Show project and session status", + Detail: "Displays current git status, session info, active tasks, and recent activity in a unified view.", + Examples: []string{"/status — full status overview", "/status --short — abbreviated status", "/status --git — git status only"}, + Related: []string{"/diff", "/history", "/session"}, + Category: "slash-commands", + }, + { + Topic: "/fix", + Summary: "Auto-fix errors and issues", + Detail: "Analyzes errors from tests, linting, or compilation and applies AI-generated fixes.", + Examples: []string{"/fix — fix last error", "/fix test — fix failing tests", "/fix lint — fix lint issues"}, + Related: []string{"/test", "/lint", "/bugfind"}, + Category: "slash-commands", + }, + { + Topic: "/config", + Summary: "Open configuration panel", + Detail: "Opens the interactive configuration panel for rho settings, model selection, and preferences.", + Examples: []string{"/config — open config panel", "/config model — change model", "/config key remove — remove stored API key", "/config keys — show key status"}, + Related: []string{"/session", "/profile", "/rules"}, + Category: "slash-commands", + }, + { + Topic: "/chat", + Summary: "Start or continue a conversation", + Detail: "Opens the AI chat interface for freeform conversation about your code, design decisions, or debugging.", + Examples: []string{"/chat — start new conversation", "/chat \"explain this\" — ask a question directly", "/chat --continue — continue last conversation"}, + Related: []string{"/explain", "/ask", "/session"}, + Category: "slash-commands", + }, + { + Topic: "/explain", + Summary: "Explain code or concepts", + Detail: "Provides AI-generated explanations of selected code, functions, or architectural patterns.", + Examples: []string{"/explain main.go — explain a file", "/explain func Init — explain a function", "/explain --deep — detailed explanation"}, + Related: []string{"/chat", "/docs", "/repomap"}, + Category: "slash-commands", + }, + { + Topic: "/search", + Summary: "Semantic code search", + Detail: "Searches your codebase using semantic understanding, not just text matching.", + Examples: []string{"/search \"auth logic\" — find authentication code", "/search --type func — search functions only", "/search --file *.go — limit to Go files"}, + Related: []string{"/explain", "/repomap", "/find"}, + Category: "slash-commands", + }, + { + Topic: "/format", + Summary: "Format code files", + Detail: "Formats source files using the configured formatter for each language.", + Examples: []string{"/format — format all changed files", "/format main.go — format specific file", "/format --check — check without modifying"}, + Related: []string{"/lint", "/fix", "/commit"}, + Category: "slash-commands", + }, + { + Topic: "/merge", + Summary: "Merge branches with conflict resolution", + Detail: "Merges branches and provides AI-assisted conflict resolution when conflicts arise.", + Examples: []string{"/merge main — merge main into current", "/merge --squash feat — squash merge a feature", "/merge --abort — abort in-progress merge"}, + Related: []string{"/branch", "/diff", "/commit"}, + Category: "slash-commands", + }, + { + Topic: "/snapshot", + Summary: "Save or restore project snapshots", + Detail: "Creates point-in-time snapshots of your project state that can be restored later.", + Examples: []string{"/snapshot — create a snapshot", "/snapshot list — list all snapshots", "/snapshot restore 3 — restore snapshot #3"}, + Related: []string{"/undo", "/history", "/branch"}, + Category: "slash-commands", + }, + { + Topic: "/history", + Summary: "View session and action history", + Detail: "Displays a timeline of actions taken during the current or past sessions.", + Examples: []string{"/history — show recent history", "/history --all — show full history", "/history --session 5 — history for session 5"}, + Related: []string{"/undo", "/snapshot", "/status"}, + Category: "slash-commands", + }, + { + Topic: "/session", + Summary: "Manage rho sessions", + Detail: "Start, stop, resume, or list rho working sessions with full context preservation.", + Examples: []string{"/session — show current session", "/session new — start new session", "/session resume 3 — resume session #3"}, + Related: []string{"/status", "/history", "/config"}, + Category: "slash-commands", + }, + { + Topic: "/bugfind", + Summary: "AI-powered bug detection", + Detail: "Scans code for potential bugs, race conditions, and logic errors using AI analysis.", + Examples: []string{"/bugfind — scan all changed files", "/bugfind ./pkg/... — scan specific package", "/bugfind --deep — thorough analysis"}, + Related: []string{"/test", "/lint", "/fix"}, + Category: "slash-commands", + }, + { + Topic: "/profile", + Summary: "Manage user profiles", + Detail: "Switch between user profiles with different settings, API keys, and preferences.", + Examples: []string{"/profile — show current profile", "/profile work — switch to work profile", "/profile create home — create new profile"}, + Related: []string{"/config", "/session", "/rules"}, + Category: "slash-commands", + }, + { + Topic: "/rules", + Summary: "Manage project rules", + Detail: "View and edit project-specific rules that guide AI behavior and code generation.", + Examples: []string{"/rules — list active rules", "/rules add \"no tabs\" — add a new rule", "/rules edit 3 — edit rule #3"}, + Related: []string{"/config", "/profile", "/docs"}, + Category: "slash-commands", + }, + { + Topic: "/docs", + Summary: "Generate or view documentation", + Detail: "Generates documentation for functions, packages, or entire projects using AI.", + Examples: []string{"/docs — generate for changed files", "/docs pkg/auth — document a package", "/docs --format md — output as markdown"}, + Related: []string{"/explain", "/repomap", "/chat"}, + Category: "slash-commands", + }, + { + Topic: "/repomap", + Summary: "Generate repository map", + Detail: "Creates an AI-generated map of your repository structure, showing key files and their relationships.", + Examples: []string{"/repomap — full repo map", "/repomap --compact — abbreviated map", "/repomap ./cmd — map a subdirectory"}, + Related: []string{"/explain", "/search", "/docs"}, + Category: "slash-commands", + }, + { + Topic: "/find", + Summary: "Find files and symbols", + Detail: "Locates files, functions, types, and other symbols in your project.", + Examples: []string{"/find Handler — find symbol by name", "/find --type struct — find all structs", "/find --file *.test — find test files"}, + Related: []string{"/search", "/repomap", "/explain"}, + Category: "slash-commands", + }, + { + Topic: "/ask", + Summary: "Ask a question about the codebase", + Detail: "Asks the AI a question with full codebase context, without making any changes.", + Examples: []string{"/ask \"how does auth work?\"", "/ask \"what calls this function?\"", "/ask \"is this thread-safe?\""}, + Related: []string{"/chat", "/explain", "/search"}, + Category: "slash-commands", + }, + // ─── Common Tasks ──────────────────────────────────────────── + { + Topic: "how to fix tests", + Summary: "Fixing failing tests with rho", + Detail: "Use /test to run tests and identify failures, then /fix test to apply AI-generated fixes. For complex failures, use /chat to discuss the issue.", + Examples: []string{"/test — identify failures", "/fix test — auto-fix test failures", "/chat \"why is TestX failing?\""}, + Related: []string{"/test", "/fix", "/bugfind"}, + Category: "common-tasks", + }, + { + Topic: "how to commit", + Summary: "Making commits with rho", + Detail: "Stage your changes with git add, then use /commit to create a commit with an AI-generated message. Use /diff first to review what you are committing.", + Examples: []string{"/diff --staged — review staged changes", "/commit — commit with AI message", `/commit "my message" — commit with custom message`}, + Related: []string{"/commit", "/diff", "/branch"}, + Category: "common-tasks", + }, + { + Topic: "how to debug", + Summary: "Debugging with rho AI assistance", + Detail: "Describe the bug in /chat or use /bugfind for automated detection. For test failures, /test with /fix provides targeted debugging.", + Examples: []string{"/bugfind — automated bug detection", "/chat \"I see panic at line 42\"", "/test -v ./pkg/... — verbose test output"}, + Related: []string{"/bugfind", "/test", "/fix", "/chat"}, + Category: "common-tasks", + }, + { + Topic: "how to review code", + Summary: "Code review assistance", + Detail: "Use /diff to see changes with AI summary, /bugfind to scan for issues, and /explain for understanding complex sections.", + Examples: []string{"/diff — see changes with AI summary", "/bugfind — scan for potential issues", "/explain func Handle — understand a function"}, + Related: []string{"/diff", "/bugfind", "/explain"}, + Category: "common-tasks", + }, + { + Topic: "how to refactor", + Summary: "Refactoring code with AI assistance", + Detail: "Use /chat to discuss refactoring strategies, then rho can apply changes. Use /snapshot before large refactors for safety.", + Examples: []string{"/snapshot — save state before refactor", "/chat \"refactor auth to use interfaces\"", "/test — verify nothing broke"}, + Related: []string{"/chat", "/snapshot", "/test", "/undo"}, + Category: "common-tasks", + }, + { + Topic: "how to start a session", + Summary: "Starting a new rho session", + Detail: "Run rho in your project directory to start a session. Your context is preserved across the session. Use /session to manage sessions.", + Examples: []string{"rho — start rho in current dir", "/session new — start fresh session", "/session resume — resume last session"}, + Related: []string{"/session", "/config", "/status"}, + Category: "common-tasks", + }, + // ─── Error Explanations ────────────────────────────────────── + { + Topic: "error: api key invalid", + Summary: "API key is missing or invalid", + Detail: "Your API key is not configured or has expired. Save a new key via /config (paste in the panel). Keys are stored in the OS secret store (macOS Keychain / Linux keyring).", + Examples: []string{"/config — paste API key in the config panel", "rho credentials status — verify stored keys"}, + Related: []string{"/config", "error: rate limit", "error: network"}, + Category: "errors", + }, + { + Topic: "error: rate limit", + Summary: "API rate limit exceeded", + Detail: "You have exceeded the API rate limit. Rho will automatically retry with exponential backoff. Consider upgrading your plan for higher limits.", + Examples: []string{"/config model — switch to a lower-tier model", "/status — check rate limit status"}, + Related: []string{"error: api key invalid", "/config", "error: timeout"}, + Category: "errors", + }, + { + Topic: "error: network", + Summary: "Network connection failed", + Detail: "Unable to reach the API server. Check your internet connection and proxy settings.", + Examples: []string{"/config proxy — configure proxy", "export HTTPS_PROXY=http://proxy:8080"}, + Related: []string{"error: timeout", "error: api key invalid", "/config"}, + Category: "errors", + }, + { + Topic: "error: timeout", + Summary: "Request timed out", + Detail: "The API request took too long and was cancelled. This may be due to network issues or a complex request. Try again or simplify your request.", + Examples: []string{"/config timeout 60 — increase timeout to 60s", "/chat --short — request shorter response"}, + Related: []string{"error: network", "error: rate limit", "/config"}, + Category: "errors", + }, + { + Topic: "error: git conflict", + Summary: "Git merge conflict detected", + Detail: "A merge conflict was encountered. Rho can assist with conflict resolution using AI to understand both sides.", + Examples: []string{"/merge --resolve — AI-assisted resolution", "/diff --conflicts — show conflict details", "/undo — abort and go back"}, + Related: []string{"/merge", "/diff", "/undo"}, + Category: "errors", + }, + { + Topic: "error: no git repo", + Summary: "Not in a git repository", + Detail: "Rho requires a git repository. Initialize one with git init or navigate to an existing repo.", + Examples: []string{"git init — initialize new repo", "cd /path/to/repo — navigate to a repo"}, + Related: []string{"/status", "/branch", "/commit"}, + Category: "errors", + }, + { + Topic: "error: model not available", + Summary: "Selected model is not available", + Detail: "The configured model is not available for your account. Switch to a different model or check your plan.", + Examples: []string{"/config model — change model", "/config model sonnet — use a specific model"}, + Related: []string{"/config", "error: api key invalid"}, + Category: "errors", + }, + { + Topic: "error: file too large", + Summary: "File exceeds size limit", + Detail: "The file is too large to process in a single request. Try working with smaller sections or use streaming mode.", + Examples: []string{"/explain func X — explain specific function", "/chat \"summarize main.go lines 1-100\""}, + Related: []string{"/explain", "/search", "/config"}, + Category: "errors", + }, + // ─── Configuration Options ─────────────────────────────────── + { + Topic: "config: model", + Summary: "Configure the AI model", + Detail: "Choose which AI model to use. Options include various sizes with different speed/quality tradeoffs.", + Examples: []string{"/config model opus — use most capable model", "/config model sonnet — balanced model", "/config model haiku — fastest model"}, + Related: []string{"/config", "config: api-key", "config: temperature"}, + Category: "configuration", + }, + { + Topic: "config: api-key", + Summary: "Set the API key", + Detail: "API keys are stored in the OS secret store. Use /config to paste a key, or /config key remove to delete one.", + Examples: []string{"/config — paste API key in the config panel", "/config key remove — remove a stored key", "rho credentials status — list configured providers"}, + Related: []string{"/config", "config: model", "error: api key invalid"}, + Category: "configuration", + }, + { + Topic: "config: temperature", + Summary: "Set model temperature", + Detail: "Controls randomness in AI responses. Lower values (0.0) are more deterministic, higher values (1.0) are more creative.", + Examples: []string{"/config temperature 0.0 — deterministic", "/config temperature 0.7 — balanced", "/config temperature 1.0 — creative"}, + Related: []string{"/config", "config: model", "config: max-tokens"}, + Category: "configuration", + }, + { + Topic: "config: max-tokens", + Summary: "Set maximum response length", + Detail: "Limits the maximum number of tokens in AI responses. Higher values allow longer responses but cost more.", + Examples: []string{"/config max-tokens 1024 — short responses", "/config max-tokens 4096 — medium responses", "/config max-tokens 16384 — long responses"}, + Related: []string{"/config", "config: temperature", "config: model"}, + Category: "configuration", + }, + { + Topic: "config: editor", + Summary: "Set preferred editor", + Detail: "Configure which editor rho uses when opening files for editing.", + Examples: []string{"/config editor vim — use vim", "/config editor code — use VS Code", "/config editor nano — use nano"}, + Related: []string{"/config", "config: theme", "config: shell"}, + Category: "configuration", + }, + { + Topic: "config: theme", + Summary: "Set color theme", + Detail: "Choose the color theme for rho terminal output. Supports light and dark terminal backgrounds.", + Examples: []string{"/config theme dark — dark background theme", "/config theme light — light background theme", "/config theme none — disable colors"}, + Related: []string{"/config", "config: editor", "config: shell"}, + Category: "configuration", + }, + { + Topic: "config: shell", + Summary: "Set shell for command execution", + Detail: "Configure which shell rho uses when running commands.", + Examples: []string{"/config shell bash — use bash", "/config shell zsh — use zsh", "/config shell fish — use fish"}, + Related: []string{"/config", "config: editor", "config: theme"}, + Category: "configuration", + }, + { + Topic: "config: proxy", + Summary: "Configure HTTP proxy", + Detail: "Set a proxy server for API requests. Useful in corporate environments.", + Examples: []string{"/config proxy http://proxy:8080", "/config proxy socks5://proxy:1080", "/config proxy none — disable proxy"}, + Related: []string{"/config", "error: network", "config: timeout"}, + Category: "configuration", + }, + { + Topic: "config: timeout", + Summary: "Set request timeout", + Detail: "Configure how long to wait for API responses before timing out. Default is 30 seconds.", + Examples: []string{"/config timeout 30 — 30 second timeout", "/config timeout 60 — 60 second timeout", "/config timeout 120 — 2 minute timeout"}, + Related: []string{"/config", "error: timeout", "config: proxy"}, + Category: "configuration", + }, + // ─── Tool Descriptions ─────────────────────────────────────── + { + Topic: "tool: repomap", + Summary: "Repository mapping engine", + Detail: "Analyzes your repository structure to build a semantic map of files, symbols, and their relationships. Used internally to provide context to the AI.", + Examples: []string{"/repomap — view the generated map", "/repomap --refresh — force rebuild"}, + Related: []string{"/search", "/explain", "tool: embeddings"}, + Category: "tools", + }, + { + Topic: "tool: embeddings", + Summary: "Code embedding engine", + Detail: "Generates vector embeddings of your code for semantic search and similarity matching.", + Examples: []string{"/search \"auth logic\" — uses embeddings internally"}, + Related: []string{"/search", "tool: repomap", "tool: memory"}, + Category: "tools", + }, + { + Topic: "tool: memory", + Summary: "Session memory system", + Detail: "Stores context across sessions including conversation history, decisions made, and project understanding.", + Examples: []string{"/session resume — restore memory from session", "/history — view remembered actions"}, + Related: []string{"/session", "/history", "tool: embeddings"}, + Category: "tools", + }, + { + Topic: "tool: snapshot", + Summary: "Project snapshot engine", + Detail: "Creates and manages point-in-time snapshots of your project for safe experimentation and undo capability.", + Examples: []string{"/snapshot — create a snapshot", "/snapshot restore 2 — restore a snapshot", "/undo — uses snapshots internally"}, + Related: []string{"/snapshot", "/undo", "tool: memory"}, + Category: "tools", + }, + { + Topic: "tool: parallel", + Summary: "Parallel execution engine", + Detail: "Runs multiple AI tasks in parallel for faster results. Used for multi-file analysis and batch operations.", + Examples: []string{"/bugfind — scans files in parallel", "/test — analyzes results in parallel"}, + Related: []string{"/bugfind", "/test", "tool: repomap"}, + Category: "tools", + }, + { + Topic: "tool: bash", + Summary: "Run shell commands", + Detail: "Runs shell commands in the workspace. Destructive patterns are blocked and every call is subject to the active autonomy tier.", + Examples: []string{"/test — runs the project test command", "/fix — validates fixes"}, + Related: []string{"/test", "/fix", "tool: snapshot"}, + Category: "tools", + }, + { + Topic: "tool: daemon", + Summary: "Background daemon service", + Detail: "Runs in the background to provide file watching, indexing, and real-time analysis of your project.", + Examples: []string{"rho daemon start — start the daemon", "rho daemon status — check daemon status", "rho daemon stop — stop the daemon"}, + Related: []string{"/status", "tool: repomap", "tool: memory"}, + Category: "tools", + }, +} + // GetHelp retrieves a specific help entry by topic. func (ch *ContextualHelp) GetHelp(topic string) *HelpEntry { ch.mu.RLock() diff --git a/internal/tool/safety_bench_test.go b/internal/tool/safety_bench_test.go index 7971b067..14b40d13 100644 --- a/internal/tool/safety_bench_test.go +++ b/internal/tool/safety_bench_test.go @@ -2,15 +2,20 @@ package tool import ( "context" + "os" + "path/filepath" "testing" ) func BenchmarkIsSensitivePath(b *testing.B) { + // Use realistic paths under the user's home / temp dir. Literal "/home/..." + // paths hit macOS's autofs automounter and would measure the wrong thing. + home, _ := os.UserHomeDir() paths := []string{ - "/home/user/project/main.go", - "/home/user/.ssh/id_rsa", - "/home/user/project/.env", - "/tmp/notes.txt", + filepath.Join(home, "project", "main.go"), + filepath.Join(home, ".ssh", "id_rsa"), + filepath.Join(home, "project", ".env"), + filepath.Join(os.TempDir(), "notes.txt"), } b.ReportAllocs() for i := 0; i < b.N; i++ { diff --git a/tool.test b/tool.test new file mode 100755 index 00000000..ea317ea0 Binary files /dev/null and b/tool.test differ