## Feat * feat(ai): add AI suggestion engine, context gathering, and ghost text overlay (`v0.3.0`) ## Security & Perf * fix(ai): restrict background `--help` execution to a hardcoded command allowlist to prevent RCE * fix(root): defer context cancellation in goroutine to prevent resource leaks * perf(ai): implement LRU eviction and maximum size limit for `ProviderCache` * perf(ai): truncate command context output (`CommandContextProvider.Gather`) to 1000 characters to save tokens ## Bug Fixes * fix(ai): add mutex synchronization and thread-safe snapshotting to `AIEngine.RegisterProvider` and `GatherDynamicContext` * fix(ai): return a copy of fresh `Suggestion` in `AIEngine.Suggest` to prevent cache mutation * fix(ai): use length-prefixed encoding in `EnvSnapshot.Hash` to prevent delimiter collisions * fix(ai): skip variable assignment lines containing `=` when extracting Makefile targets * fix(runner): check `scanner.Err()` and return `nil` on scan errors in justfile generator * test(ci): rename `git commit` to `git checkout` in overlay test to resolve CI `typos` false positive
140 lines
3.4 KiB
Go
140 lines
3.4 KiB
Go
package integration
|
||
|
||
import "strings"
|
||
|
||
var iconMap = map[string]string{
|
||
"git": "",
|
||
"gh": "",
|
||
"docker": "",
|
||
"docker-compose": "",
|
||
"podman": "",
|
||
"go": "",
|
||
"golang": "",
|
||
"python": "",
|
||
"python3": "",
|
||
"pip": "",
|
||
"pip3": "",
|
||
"pipx": "",
|
||
"conda": "",
|
||
"node": "",
|
||
"npm": "",
|
||
"npx": "",
|
||
"pnpm": "",
|
||
"pnpx": "",
|
||
"bun": "",
|
||
"bunx": "",
|
||
"yarn": "",
|
||
"deno": "",
|
||
"rust": "",
|
||
"cargo": "",
|
||
"rustup": "",
|
||
"rustc": "",
|
||
"java": "",
|
||
"javac": "",
|
||
"kotlin": "",
|
||
"mvn": "",
|
||
"gradle": "",
|
||
"ruby": "",
|
||
"gem": "",
|
||
"rails": "",
|
||
"php": "",
|
||
"composer": "",
|
||
"lua": "",
|
||
"nvim": "",
|
||
"vim": "",
|
||
"vi": "",
|
||
"nano": "",
|
||
"emacs": "",
|
||
"code": "",
|
||
"subl": "",
|
||
"cd": "",
|
||
"ls": "",
|
||
"eza": "",
|
||
"exa": "",
|
||
"lsd": "",
|
||
"tree": "",
|
||
"pwd": "",
|
||
"cat": "",
|
||
"bat": "",
|
||
"less": "",
|
||
"more": "",
|
||
"head": "",
|
||
"tail": "",
|
||
"grep": "",
|
||
"rg": "",
|
||
"ripgrep": "",
|
||
"find": "",
|
||
"fd": "",
|
||
"ssh": "",
|
||
"scp": "",
|
||
"sftp": "",
|
||
"rsync": "",
|
||
"kubectl": "",
|
||
"helm": "",
|
||
"k9s": "",
|
||
"minikube": "",
|
||
"terraform": "",
|
||
"ansible": "",
|
||
"aws": "",
|
||
"gcloud": "",
|
||
"tmux": "",
|
||
"screen": "",
|
||
"curl": "",
|
||
"wget": "",
|
||
"nginx": "",
|
||
"mysql": "",
|
||
"psql": "",
|
||
"mongosh": "",
|
||
"redis-cli": "",
|
||
"sqlite3": "",
|
||
"firebase": "",
|
||
"supabase": "",
|
||
"vercel": "▲",
|
||
"netlify": "",
|
||
"hugo": "",
|
||
"next": "▲",
|
||
"vite": "",
|
||
"webpack": "",
|
||
"eslint": "",
|
||
"prettier": "",
|
||
"jest": "",
|
||
"pytest": "",
|
||
"make": "",
|
||
"cmake": "",
|
||
"just": "",
|
||
"nmap": "",
|
||
"ffmpeg": "",
|
||
"ollama": "",
|
||
"ai": "",
|
||
"llm": "",
|
||
"openai": "",
|
||
"groq": "",
|
||
"gemini": "",
|
||
"claude": "",
|
||
"anthropic": "",
|
||
"copilot": "",
|
||
"chatgpt": "",
|
||
"systemctl": "",
|
||
"htop": "",
|
||
"btop": "",
|
||
"top": "",
|
||
"tar": "",
|
||
"zip": "",
|
||
"unzip": "",
|
||
"alias": "",
|
||
"history": "",
|
||
"system": "",
|
||
"root": "",
|
||
}
|
||
|
||
func lookupIcon(key string) string {
|
||
key = strings.ToLower(strings.TrimSpace(key))
|
||
if icon, ok := iconMap[key]; ok {
|
||
return icon
|
||
}
|
||
if len(key) > 0 && key[0] >= '0' && key[0] <= '9' {
|
||
return ""
|
||
}
|
||
return "❯"
|
||
}
|