diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-08 21:55:01 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-08 21:55:01 +0200 |
| commit | ec9e3714ed12cc86f585550d56241b3e6b7e63aa (patch) | |
| tree | d45f3ae88b2fc8382df8dc10cc912623d1a2e44f /docs | |
| parent | 3f21625333daec30ff8fce5d8a2bf479a9450995 (diff) | |
chore: stop tracking build artifacts and temp files
Co-authored-by: Cursor <cursoragent@cursor.com>
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/coverage.html | 11268 | ||||
| -rw-r--r-- | docs/coverage.out | 126969 | ||||
| -rw-r--r-- | docs/coverage/_internal.out | 1 | ||||
| -rw-r--r-- | docs/coverage/_internal_appconfig.out | 514 | ||||
| -rw-r--r-- | docs/coverage/_internal_editor.out | 25 | ||||
| -rw-r--r-- | docs/coverage/_internal_hexaiaction.out | 302 | ||||
| -rw-r--r-- | docs/coverage/_internal_hexaicli.out | 240 | ||||
| -rw-r--r-- | docs/coverage/_internal_hexailsp.out | 47 | ||||
| -rw-r--r-- | docs/coverage/_internal_ignore.out | 20 | ||||
| -rw-r--r-- | docs/coverage/_internal_llm.out | 371 | ||||
| -rw-r--r-- | docs/coverage/_internal_llmutils.out | 8 | ||||
| -rw-r--r-- | docs/coverage/_internal_logging.out | 16 | ||||
| -rw-r--r-- | docs/coverage/_internal_lsp.out | 1190 | ||||
| -rw-r--r-- | docs/coverage/_internal_runtimeconfig.out | 76 | ||||
| -rw-r--r-- | docs/coverage/_internal_stats.out | 89 | ||||
| -rw-r--r-- | docs/coverage/_internal_testutil.out | 6 | ||||
| -rw-r--r-- | docs/coverage/_internal_textutil.out | 60 | ||||
| -rw-r--r-- | docs/coverage/_internal_tmux.out | 104 | ||||
| -rw-r--r-- | docs/coverage/_internal_tmuxedit.out | 231 |
19 files changed, 0 insertions, 141537 deletions
diff --git a/docs/coverage.html b/docs/coverage.html deleted file mode 100644 index 1694242..0000000 --- a/docs/coverage.html +++ /dev/null @@ -1,11268 +0,0 @@ - -<!DOCTYPE html> -<html> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - <title>hexai-lsp: Go Coverage Report</title> - <style> - body { - background: black; - color: rgb(80, 80, 80); - } - body, pre, #legend span { - font-family: Menlo, monospace; - font-weight: bold; - } - #topbar { - background: black; - position: fixed; - top: 0; left: 0; right: 0; - height: 42px; - border-bottom: 1px solid rgb(80, 80, 80); - } - #content { - margin-top: 50px; - } - #nav, #legend { - float: left; - margin-left: 10px; - } - #legend { - margin-top: 12px; - } - #nav { - margin-top: 10px; - } - #legend span { - margin: 0 5px; - } - .cov0 { color: rgb(192, 0, 0) } -.cov1 { color: rgb(128, 128, 128) } -.cov2 { color: rgb(116, 140, 131) } -.cov3 { color: rgb(104, 152, 134) } -.cov4 { color: rgb(92, 164, 137) } -.cov5 { color: rgb(80, 176, 140) } -.cov6 { color: rgb(68, 188, 143) } -.cov7 { color: rgb(56, 200, 146) } -.cov8 { color: rgb(44, 212, 149) } -.cov9 { color: rgb(32, 224, 152) } -.cov10 { color: rgb(20, 236, 155) } - - </style> - </head> - <body> - <div id="topbar"> - <div id="nav"> - <select id="files"> - - <option value="file0">codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go (73.3%)</option> - - <option value="file1">codeberg.org/snonux/hexai/cmd/hexai-tmux-action/main.go (0.0%)</option> - - <option value="file2">codeberg.org/snonux/hexai/cmd/hexai-tmux-edit/main.go (0.0%)</option> - - <option value="file3">codeberg.org/snonux/hexai/cmd/hexai/main.go (61.9%)</option> - - <option value="file4">codeberg.org/snonux/hexai/internal/appconfig/config.go (82.4%)</option> - - <option value="file5">codeberg.org/snonux/hexai/internal/editor/editor.go (58.3%)</option> - - <option value="file6">codeberg.org/snonux/hexai/internal/hexaiaction/cmdentry.go (84.5%)</option> - - <option value="file7">codeberg.org/snonux/hexai/internal/hexaiaction/parse.go (92.6%)</option> - - <option value="file8">codeberg.org/snonux/hexai/internal/hexaiaction/prompts.go (92.3%)</option> - - <option value="file9">codeberg.org/snonux/hexai/internal/hexaiaction/run.go (71.1%)</option> - - <option value="file10">codeberg.org/snonux/hexai/internal/hexaiaction/tui.go (65.5%)</option> - - <option value="file11">codeberg.org/snonux/hexai/internal/hexaiaction/tui_custom.go (83.8%)</option> - - <option value="file12">codeberg.org/snonux/hexai/internal/hexaiaction/tui_delegate.go (100.0%)</option> - - <option value="file13">codeberg.org/snonux/hexai/internal/hexaicli/run.go (71.4%)</option> - - <option value="file14">codeberg.org/snonux/hexai/internal/hexailsp/run.go (88.6%)</option> - - <option value="file15">codeberg.org/snonux/hexai/internal/ignore/checker.go (100.0%)</option> - - <option value="file16">codeberg.org/snonux/hexai/internal/llm/anthropic.go (80.4%)</option> - - <option value="file17">codeberg.org/snonux/hexai/internal/llm/ollama.go (88.7%)</option> - - <option value="file18">codeberg.org/snonux/hexai/internal/llm/openai.go (86.4%)</option> - - <option value="file19">codeberg.org/snonux/hexai/internal/llm/openrouter.go (75.8%)</option> - - <option value="file20">codeberg.org/snonux/hexai/internal/llm/provider.go (72.1%)</option> - - <option value="file21">codeberg.org/snonux/hexai/internal/llm/util.go (100.0%)</option> - - <option value="file22">codeberg.org/snonux/hexai/internal/llmutils/client.go (100.0%)</option> - - <option value="file23">codeberg.org/snonux/hexai/internal/logging/chatlogger.go (100.0%)</option> - - <option value="file24">codeberg.org/snonux/hexai/internal/logging/logging.go (90.9%)</option> - - <option value="file25">codeberg.org/snonux/hexai/internal/lsp/chat_commands.go (83.3%)</option> - - <option value="file26">codeberg.org/snonux/hexai/internal/lsp/context.go (74.4%)</option> - - <option value="file27">codeberg.org/snonux/hexai/internal/lsp/document.go (91.5%)</option> - - <option value="file28">codeberg.org/snonux/hexai/internal/lsp/handlers.go (89.8%)</option> - - <option value="file29">codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go (81.1%)</option> - - <option value="file30">codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go (75.4%)</option> - - <option value="file31">codeberg.org/snonux/hexai/internal/lsp/handlers_document.go (77.8%)</option> - - <option value="file32">codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go (75.0%)</option> - - <option value="file33">codeberg.org/snonux/hexai/internal/lsp/handlers_ignore.go (86.7%)</option> - - <option value="file34">codeberg.org/snonux/hexai/internal/lsp/handlers_init.go (66.7%)</option> - - <option value="file35">codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go (85.3%)</option> - - <option value="file36">codeberg.org/snonux/hexai/internal/lsp/server.go (81.0%)</option> - - <option value="file37">codeberg.org/snonux/hexai/internal/lsp/transport.go (73.0%)</option> - - <option value="file38">codeberg.org/snonux/hexai/internal/runtimeconfig/store.go (88.1%)</option> - - <option value="file39">codeberg.org/snonux/hexai/internal/stats/lock_posix.go (83.3%)</option> - - <option value="file40">codeberg.org/snonux/hexai/internal/stats/stats.go (76.0%)</option> - - <option value="file41">codeberg.org/snonux/hexai/internal/testutil/fixtures.go (100.0%)</option> - - <option value="file42">codeberg.org/snonux/hexai/internal/textutil/human.go (92.3%)</option> - - <option value="file43">codeberg.org/snonux/hexai/internal/textutil/textutil.go (90.4%)</option> - - <option value="file44">codeberg.org/snonux/hexai/internal/tmux/status.go (76.7%)</option> - - <option value="file45">codeberg.org/snonux/hexai/internal/tmux/tmux.go (88.6%)</option> - - <option value="file46">codeberg.org/snonux/hexai/internal/tmuxedit/agent.go (82.1%)</option> - - <option value="file47">codeberg.org/snonux/hexai/internal/tmuxedit/agentutil.go (47.1%)</option> - - <option value="file48">codeberg.org/snonux/hexai/internal/tmuxedit/capture.go (100.0%)</option> - - <option value="file49">codeberg.org/snonux/hexai/internal/tmuxedit/claude_agent.go (86.2%)</option> - - <option value="file50">codeberg.org/snonux/hexai/internal/tmuxedit/config_agent.go (97.5%)</option> - - <option value="file51">codeberg.org/snonux/hexai/internal/tmuxedit/cursor_agent.go (75.0%)</option> - - <option value="file52">codeberg.org/snonux/hexai/internal/tmuxedit/pane.go (92.3%)</option> - - <option value="file53">codeberg.org/snonux/hexai/internal/tmuxedit/run.go (56.8%)</option> - - <option value="file54">codeberg.org/snonux/hexai/internal/tmuxedit/send.go (56.2%)</option> - - </select> - </div> - <div id="legend"> - <span>not tracked</span> - - <span class="cov0">no coverage</span> - <span class="cov1">low coverage</span> - <span class="cov2">*</span> - <span class="cov3">*</span> - <span class="cov4">*</span> - <span class="cov5">*</span> - <span class="cov6">*</span> - <span class="cov7">*</span> - <span class="cov8">*</span> - <span class="cov9">*</span> - <span class="cov10">high coverage</span> - - </div> - </div> - <div id="content"> - - <pre class="file" id="file0" style="display: none">// Summary: Hexai LSP entrypoint; parses flags and delegates to internal/hexailsp. -package main - -import ( - "flag" - "fmt" - "log" - "os" - "strings" - - "codeberg.org/snonux/hexai/internal" - "codeberg.org/snonux/hexai/internal/appconfig" - "codeberg.org/snonux/hexai/internal/hexailsp" -) - -func main() <span class="cov10" title="3">{ - logPath := flag.String("log", "/tmp/hexai-lsp.log", "path to log file (optional)") - defaultCfg := defaultConfigPath() - configPath := flag.String("config", "", fmt.Sprintf("path to config file (default: %s)", defaultCfg)) - showVersion := flag.Bool("version", false, "print version and exit") - flag.Parse() - if *showVersion </span><span class="cov10" title="3">{ - log.Println(internal.Version) - return - }</span> - - <span class="cov0" title="0">path := strings.TrimSpace(*configPath) - if err := hexailsp.RunWithConfig(*logPath, path, os.Stdin, os.Stdout, os.Stderr); err != nil </span><span class="cov0" title="0">{ - log.Fatalf("server error: %v", err) - }</span> -} - -func defaultConfigPath() string <span class="cov10" title="3">{ - path, err := appconfig.ConfigPath() - if err != nil </span><span class="cov0" title="0">{ - return "$XDG_CONFIG_HOME/hexai/config.toml" - }</span> - <span class="cov10" title="3">return path</span> -} -</pre> - - <pre class="file" id="file1" style="display: none">package main - -import ( - "context" - "flag" - "fmt" - "os" - "strings" - - "codeberg.org/snonux/hexai/internal/appconfig" - "codeberg.org/snonux/hexai/internal/hexaiaction" -) - -func main() <span class="cov0" title="0">{ - infile := flag.String("infile", "", "Read input from this file instead of stdin") - outfile := flag.String("outfile", "", "Write output to this file instead of stdout") - uiChild := flag.Bool("ui-child", false, "INTERNAL: run interactive UI and write to -outfile atomically") - defaultPath := defaultConfigPath() - configPath := flag.String("config", "", fmt.Sprintf("path to config file (default: %s)", defaultPath)) - tmuxTarget := flag.String("tmux-target", "", "tmux split target (advanced)") - tmuxSplit := flag.String("tmux-split", "v", "tmux split orientation: v or h") - tmuxPercent := flag.Int("tmux-percent", 33, "tmux split size percentage (1-100)") - flag.Parse() - - opts := hexaiaction.Options{ - Infile: *infile, Outfile: *outfile, - UIChild: *uiChild, TmuxTarget: *tmuxTarget, TmuxSplit: *tmuxSplit, TmuxPercent: *tmuxPercent, - } - ctx := context.Background() - if path := strings.TrimSpace(*configPath); path != "" </span><span class="cov0" title="0">{ - ctx = hexaiaction.WithConfigPath(ctx, path) - }</span> - <span class="cov0" title="0">if err := hexaiaction.RunCommand(ctx, opts, os.Stdin, os.Stdout, os.Stderr); err != nil </span><span class="cov0" title="0">{ - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - }</span> -} - -func defaultConfigPath() string <span class="cov0" title="0">{ - path, err := appconfig.ConfigPath() - if err != nil </span><span class="cov0" title="0">{ - return "$XDG_CONFIG_HOME/hexai/config.toml" - }</span> - <span class="cov0" title="0">return path</span> -} -</pre> - - <pre class="file" id="file2" style="display: none">// hexai-tmux-edit opens a tmux popup with $EDITOR for composing AI agent -// prompts. It captures existing prompt text from the target pane, pre-fills -// the editor, and sends the edited text back via tmux send-keys. -// -// Usage: -// -// hexai-tmux-edit [--config <path>] [--agent <name>] [--pane <id>] -// -// Tmux keybinding (add to ~/.tmux.conf): -// -// bind e run-shell -b "hexai-tmux-edit --pane '#{pane_id}'" -package main - -import ( - "flag" - "fmt" - "os" - "strings" - - "codeberg.org/snonux/hexai/internal/appconfig" - "codeberg.org/snonux/hexai/internal/tmuxedit" -) - -func main() <span class="cov0" title="0">{ - defaultPath := defaultConfigPath() - configPath := flag.String("config", "", fmt.Sprintf("path to config file (default: %s)", defaultPath)) - agent := flag.String("agent", "", "AI agent name (auto-detected if omitted)") - pane := flag.String("pane", "", "tmux target pane ID (e.g. %%5)") - flag.Parse() - - opts := tmuxedit.Options{ - ConfigPath: strings.TrimSpace(*configPath), - Agent: strings.TrimSpace(*agent), - Pane: strings.TrimSpace(*pane), - } - if err := tmuxedit.Run(opts); err != nil </span><span class="cov0" title="0">{ - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - }</span> -} - -func defaultConfigPath() string <span class="cov0" title="0">{ - path, err := appconfig.ConfigPath() - if err != nil </span><span class="cov0" title="0">{ - return "$XDG_CONFIG_HOME/hexai/config.toml" - }</span> - <span class="cov0" title="0">return path</span> -} -</pre> - - <pre class="file" id="file3" style="display: none">// Summary: Hexai CLI entrypoint; parses flags and delegates to internal/hexaicli. -package main - -import ( - "context" - "flag" - "fmt" - "io" - "log" - "os" - "strconv" - "strings" - - "codeberg.org/snonux/hexai/internal" - "codeberg.org/snonux/hexai/internal/appconfig" - "codeberg.org/snonux/hexai/internal/hexaicli" -) - -func main() <span class="cov8" title="1">{ - configPath, remaining := splitConfigPath(os.Args[1:]) - logger := log.New(io.Discard, "", 0) - cfg := appconfig.LoadWithOptions(logger, appconfig.LoadOptions{ConfigPath: configPath}) - cliEntries := cfg.CLIConfigs - if len(cliEntries) == 0 </span><span class="cov8" title="1">{ - cliEntries = []appconfig.SurfaceConfig{{Provider: cfg.Provider}} - }</span> - <span class="cov8" title="1">fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError) - defaultPath := defaultConfigPath() - configFlag := fs.String("config", configPath, fmt.Sprintf("path to config file (default: %s)", defaultPath)) - showVersion := fs.Bool("version", false, "print version and exit") - selectedFlags := make([]bool, len(cliEntries)) - for i, entry := range cliEntries </span><span class="cov8" title="1">{ - name := strconv.Itoa(i) - provider := strings.TrimSpace(entry.Provider) - if provider == "" </span><span class="cov8" title="1">{ - provider = cfg.Provider - }</span> - <span class="cov8" title="1">model := strings.TrimSpace(entry.Model) - if model == "" </span><span class="cov8" title="1">{ - model = pickDefaultModel(cfg, provider) - }</span> - <span class="cov8" title="1">desc := fmt.Sprintf("use only provider #%d (%s:%s)", i, provider, model) - fs.BoolVar(&selectedFlags[i], name, false, desc)</span> - } - <span class="cov8" title="1">_ = fs.Parse(remaining) - if *showVersion </span><span class="cov8" title="1">{ - fmt.Fprintln(os.Stdout, internal.Version) - return - }</span> - <span class="cov0" title="0">var selection []int - for i, sel := range selectedFlags </span><span class="cov0" title="0">{ - if sel </span><span class="cov0" title="0">{ - selection = append(selection, i) - }</span> - } - <span class="cov0" title="0">finalPath := strings.TrimSpace(*configFlag) - if finalPath == "" </span><span class="cov0" title="0">{ - finalPath = configPath - }</span> - <span class="cov0" title="0">ctx := context.Background() - if finalPath != "" </span><span class="cov0" title="0">{ - ctx = hexaicli.WithCLIConfigPath(ctx, finalPath) - }</span> - <span class="cov0" title="0">if len(selection) > 0 </span><span class="cov0" title="0">{ - ctx = hexaicli.WithCLISelection(ctx, selection) - }</span> - <span class="cov0" title="0">if err := hexaicli.Run(ctx, fs.Args(), os.Stdin, os.Stdout, os.Stderr); err != nil </span><span class="cov0" title="0">{ - os.Exit(1) - }</span> -} - -func splitConfigPath(args []string) (string, []string) <span class="cov8" title="1">{ - var path string - rest := make([]string, 0, len(args)) - skip := false - for i := 0; i < len(args); i++ </span><span class="cov8" title="1">{ - if skip </span><span class="cov0" title="0">{ - skip = false - continue</span> - } - <span class="cov8" title="1">arg := args[i] - switch </span>{ - case arg == "--config" || arg == "-config":<span class="cov0" title="0"> - if i+1 < len(args) </span><span class="cov0" title="0">{ - path = args[i+1] - skip = true - }</span> - case strings.HasPrefix(arg, "--config="):<span class="cov0" title="0"> - path = arg[len("--config="):]</span> - case strings.HasPrefix(arg, "-config="):<span class="cov0" title="0"> - path = arg[len("-config="):]</span> - default:<span class="cov8" title="1"> - rest = append(rest, arg)</span> - } - } - <span class="cov8" title="1">return strings.TrimSpace(path), rest</span> -} - -func pickDefaultModel(cfg appconfig.App, provider string) string <span class="cov8" title="1">{ - switch strings.ToLower(strings.TrimSpace(provider)) </span>{ - case "ollama":<span class="cov0" title="0"> - return strings.TrimSpace(cfg.OllamaModel)</span> - case "anthropic":<span class="cov0" title="0"> - return strings.TrimSpace(cfg.AnthropicModel)</span> - default:<span class="cov8" title="1"> - return strings.TrimSpace(cfg.OpenAIModel)</span> - } -} - -func defaultConfigPath() string <span class="cov8" title="1">{ - cfgPath, err := appconfig.ConfigPath() - if err != nil </span><span class="cov0" title="0">{ - return "$XDG_CONFIG_HOME/hexai/config.toml" - }</span> - <span class="cov8" title="1">return cfgPath</span> -} -</pre> - - <pre class="file" id="file4" style="display: none">// Summary: Application configuration model and loader; reads ~/.config/hexai/config.toml and merges defaults. -package appconfig - -import ( - "fmt" - "log" - "os" - "path/filepath" - "slices" - "strconv" - "strings" - - "github.com/pelletier/go-toml/v2" -) - -// SurfaceConfig describes a provider/model pairing (with optional temperature). -type SurfaceConfig struct { - Provider string - Model string - Temperature *float64 -} - -// App holds user-configurable settings read from ~/.config/hexai/config.toml. -type App struct { - MaxTokens int `json:"max_tokens" toml:"max_tokens"` - ContextMode string `json:"context_mode" toml:"context_mode"` - ContextWindowLines int `json:"context_window_lines" toml:"context_window_lines"` - MaxContextTokens int `json:"max_context_tokens" toml:"max_context_tokens"` - LogPreviewLimit int `json:"log_preview_limit" toml:"log_preview_limit"` - RequestTimeout int `json:"request_timeout" toml:"request_timeout"` - // Single knob for LSP requests; if set, overrides hardcoded temps in LSP. - CodingTemperature *float64 `json:"coding_temperature" toml:"coding_temperature"` - // Minimum identifier characters required for manual (TriggerKind=1) invoke - // to proceed without structural triggers. 0 means always allow. - ManualInvokeMinPrefix int `json:"manual_invoke_min_prefix" toml:"manual_invoke_min_prefix"` - - // Completion debounce in milliseconds. When > 0, the server waits until - // there has been no text change for at least this duration before sending - // an LLM completion request. - CompletionDebounceMs int `json:"completion_debounce_ms" toml:"completion_debounce_ms"` - // Completion throttle in milliseconds. When > 0, caps the minimum spacing - // between LLM requests (both chat and code-completer paths). - CompletionThrottleMs int `json:"completion_throttle_ms" toml:"completion_throttle_ms"` - // CompletionWaitAll controls whether to wait for all configured completion - // backends before returning results. When true (default), waits for all - // backends. When false, returns the first result immediately. - CompletionWaitAll *bool `json:"completion_wait_all" toml:"completion_wait_all"` - - TriggerCharacters []string `json:"trigger_characters" toml:"trigger_characters"` - Provider string `json:"provider" toml:"provider"` - - // Inline prompt trigger characters (default: >!text> and >>!text>) - InlineOpen string `json:"inline_open" toml:"inline_open"` - InlineClose string `json:"inline_close" toml:"inline_close"` - // In-editor chat triggers (default: suffix ">" after one of [?, !, :, ;]) - ChatSuffix string `json:"chat_suffix" toml:"chat_suffix"` - ChatPrefixes []string `json:"chat_prefixes" toml:"chat_prefixes"` - - // Provider-specific options - OpenAIBaseURL string `json:"openai_base_url" toml:"openai_base_url"` - OpenAIModel string `json:"openai_model" toml:"openai_model"` - // Default temperature for OpenAI requests (nil means use provider default) - OpenAITemperature *float64 `json:"openai_temperature" toml:"openai_temperature"` - OpenRouterBaseURL string `json:"openrouter_base_url" toml:"openrouter_base_url"` - OpenRouterModel string `json:"openrouter_model" toml:"openrouter_model"` - // Default temperature for OpenRouter requests (nil means use provider default) - OpenRouterTemperature *float64 `json:"openrouter_temperature" toml:"openrouter_temperature"` - OllamaBaseURL string `json:"ollama_base_url" toml:"ollama_base_url"` - OllamaModel string `json:"ollama_model" toml:"ollama_model"` - // Default temperature for Ollama requests (nil means use provider default) - OllamaTemperature *float64 `json:"ollama_temperature" toml:"ollama_temperature"` - AnthropicBaseURL string `json:"anthropic_base_url" toml:"anthropic_base_url"` - AnthropicModel string `json:"anthropic_model" toml:"anthropic_model"` - // Default temperature for Anthropic requests (nil means use provider default) - AnthropicTemperature *float64 `json:"anthropic_temperature" toml:"anthropic_temperature"` - - // Per-surface provider/model configurations (ordered; first entry is primary) - CompletionConfigs []SurfaceConfig `json:"-" toml:"-"` - CodeActionConfigs []SurfaceConfig `json:"-" toml:"-"` - ChatConfigs []SurfaceConfig `json:"-" toml:"-"` - CLIConfigs []SurfaceConfig `json:"-" toml:"-"` - - // Prompt templates (configured only via file; no env overrides) - // Completion/chat/code action/CLI prompt strings. See config.toml.example for placeholders. - // Completion - PromptCompletionSystemGeneral string `json:"-" toml:"-"` - PromptCompletionSystemParams string `json:"-" toml:"-"` - PromptCompletionSystemInline string `json:"-" toml:"-"` - PromptCompletionUserGeneral string `json:"-" toml:"-"` - PromptCompletionUserParams string `json:"-" toml:"-"` - PromptCompletionExtraHeader string `json:"-" toml:"-"` - // Provider-native code-completer - PromptNativeCompletion string `json:"-" toml:"-"` - // In-editor chat - PromptChatSystem string `json:"-" toml:"-"` - // Code actions - PromptCodeActionRewriteSystem string `json:"-" toml:"-"` - PromptCodeActionDiagnosticsSystem string `json:"-" toml:"-"` - PromptCodeActionDocumentSystem string `json:"-" toml:"-"` - PromptCodeActionRewriteUser string `json:"-" toml:"-"` - PromptCodeActionDiagnosticsUser string `json:"-" toml:"-"` - PromptCodeActionDocumentUser string `json:"-" toml:"-"` - PromptCodeActionGoTestSystem string `json:"-" toml:"-"` - PromptCodeActionGoTestUser string `json:"-" toml:"-"` - PromptCodeActionSimplifySystem string `json:"-" toml:"-"` - PromptCodeActionSimplifyUser string `json:"-" toml:"-"` - // CLI - PromptCLIDefaultSystem string `json:"-" toml:"-"` - PromptCLIExplainSystem string `json:"-" toml:"-"` - - // Custom code actions and tmux integration - CustomActions []CustomAction `json:"-" toml:"-"` - TmuxCustomMenuHotkey string `json:"-" toml:"-"` - // Stats - StatsWindowMinutes int `json:"-" toml:"-"` - - // Ignore: gitignore-aware file filtering for LSP - IgnoreGitignore *bool `json:"-" toml:"-"` - IgnoreExtraPatterns []string `json:"-" toml:"-"` - IgnoreLSPNotify *bool `json:"-" toml:"-"` - - // TmuxEdit: popup editor settings for hexai-tmux-edit - TmuxEditPopupWidth string `json:"-" toml:"-"` - TmuxEditPopupHeight string `json:"-" toml:"-"` - TmuxEditDefaultAgent string `json:"-" toml:"-"` - TmuxEditAgents []TmuxEditAgentCfg `json:"-" toml:"-"` -} - -// CustomAction describes a user-defined code action. -type CustomAction struct { - ID string - Title string - Kind string // optional; default "refactor" - Scope string // "selection" (default) | "diagnostics" - Hotkey string // optional, used by tmux submenu - Instruction string // optional; if set and User is empty, use global rewrite templates - System string // optional; used only when User is set - User string // optional; if set, render with available vars -} - -// TmuxEditAgentCfg describes an AI agent's detection and interaction patterns -// for the tmux popup editor (hexai-tmux-edit). -type TmuxEditAgentCfg struct { - Name string - DisplayName string - DetectPattern string - SectionPattern string - PromptPattern string - StripPatterns []string - ClearFirst *bool - ClearKeys string - NewlineKeys string - SubmitKeys string -} - -// Constructor: defaults for App (kept first among functions) -func newDefaultConfig() App <span class="cov5" title="62">{ - // Coding-friendly default temperature across providers - // Users can override per provider in config.toml (including 0.0). - t := 0.2 - return App{ - MaxTokens: 4000, - ContextMode: "always-full", - ContextWindowLines: 120, - MaxContextTokens: 4000, - LogPreviewLimit: 100, - RequestTimeout: 30, - CodingTemperature: &t, - OpenAITemperature: &t, - OllamaTemperature: &t, - AnthropicTemperature: &t, - ManualInvokeMinPrefix: 0, - CompletionDebounceMs: 800, - CompletionThrottleMs: 0, - // Inline/chat trigger defaults - InlineOpen: ">!", - InlineClose: ">", - ChatSuffix: ">", - ChatPrefixes: []string{"?", "!", ":", ";"}, - - // Default prompt templates (match current hard-coded strings) - PromptCompletionSystemParams: "You are a code completion engine for function signatures. Return only the parameter list contents (without parentheses), no braces, no prose. Prefer idiomatic names and types.", - PromptCompletionUserParams: "Cursor is inside the function parameter list. Suggest only the parameter list (no parentheses).\nFunction line: {{function}}\nCurrent line (cursor at {{char}}): {{current}}", - PromptCompletionSystemGeneral: "You are a terse code completion engine. Return only the code to insert, no surrounding prose or backticks. Only continue from the cursor; never repeat characters already present to the left of the cursor on the current line (e.g., if 'name :=' is already typed, only return the right-hand side expression).", - PromptCompletionUserGeneral: "Provide the next likely code to insert at the cursor.\nFile: {{file}}\nFunction/context: {{function}}\nAbove line: {{above}}\nCurrent line (cursor at character {{char}}): {{current}}\nBelow line: {{below}}\nOnly return the completion snippet.", - PromptCompletionSystemInline: "You are a precise code completion/refactoring engine. Output only the code to insert with no prose, no comments, and no backticks. Return raw code only.", - PromptCompletionExtraHeader: "Additional context:\n{{context}}", - - PromptNativeCompletion: "// Path: {{path}}\n{{before}}", - - PromptChatSystem: "You are a helpful coding assistant. Answer concisely and clearly.", - - PromptCodeActionRewriteSystem: "You are a precise code refactoring engine. Rewrite the given code strictly according to the instruction. Return only the updated code with no prose or backticks. Preserve formatting where reasonable.", - PromptCodeActionDiagnosticsSystem: "You are a precise code fixer. Resolve the given diagnostics by editing only the selected code. Return only the corrected code with no prose or backticks. Keep behavior and style, and avoid unrelated changes.", - PromptCodeActionDocumentSystem: "You are a precise code documentation engine. Add idiomatic documentation comments to the given code. Preserve exact behavior and formatting as much as possible. Return only the updated code with comments, no prose or backticks.", - PromptCodeActionRewriteUser: "Instruction: {{instruction}}\n\nSelected code to transform:\n{{selection}}", - PromptCodeActionDiagnosticsUser: "Diagnostics to resolve (selection only):\n{{diagnostics}}\n\nSelected code:\n{{selection}}", - PromptCodeActionDocumentUser: "Add documentation comments to this code:\n{{selection}}", - PromptCodeActionGoTestSystem: "You are a precise Go unit test generator. Given a Go function, write one or more Test* functions using the testing package. Do NOT include package or imports, only the test function(s). Prefer table-driven tests. Keep it minimal and idiomatic.", - PromptCodeActionGoTestUser: "Function under test:\n{{function}}", - PromptCodeActionSimplifySystem: "You are a precise code improvement engine. Simplify and improve the given code while preserving behavior. Return only the improved code with no prose or backticks.", - PromptCodeActionSimplifyUser: "Improve this code:\n{{selection}}", - - PromptCLIDefaultSystem: "You are Hexai CLI. Default to very short, concise answers. If the user asks for commands, output only the commands (one per line) with no commentary or explanation. Only when the word 'explain' appears in the prompt, produce a verbose explanation.", - PromptCLIExplainSystem: "You are Hexai CLI. The user requested an explanation. Provide a clear, verbose explanation with reasoning and details. If commands are needed, include them with brief context.", - - // Stats - StatsWindowMinutes: 60, - - // Ignore: respect .gitignore by default, notify in LSP by default - IgnoreGitignore: boolPtr(true), - IgnoreLSPNotify: boolPtr(true), - } -}</span> - -func boolPtr(b bool) *bool <span class="cov6" title="124">{ return &b }</span> - -// Load reads configuration from a file and merges with defaults. -// It respects the XDG Base Directory Specification. -func Load(logger *log.Logger) App <span class="cov5" title="36">{ return LoadWithOptions(logger, LoadOptions{}) }</span> - -// LoadOptions tune how configuration is loaded at runtime. -type LoadOptions struct { - // IgnoreEnv skips applying environment overrides when true. - IgnoreEnv bool - // ConfigPath overrides the global config file path (e.g. via --config flag). - ConfigPath string - // ProjectRoot overrides the project root directory for locating .hexaiconfig.toml. - // When empty, findGitRoot() is used to auto-detect from the current working directory. - ProjectRoot string -} - -// LoadWithOptions reads configuration and applies the requested loading options. -func LoadWithOptions(logger *log.Logger, opts LoadOptions) App <span class="cov5" title="60">{ - cfg := newDefaultConfig() - if logger == nil </span><span class="cov4" title="14">{ - return cfg // Return defaults if no logger is provided (e.g. in tests) - }</span> - - // Step 1: Load global config file - <span class="cov5" title="46">configPath := strings.TrimSpace(opts.ConfigPath) - if configPath != "" </span><span class="cov3" title="6">{ - if fileCfg, err := loadFromFile(configPath, logger); err == nil && fileC |
