summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Magefile.go200
-rw-r--r--docs/coverage.html4484
-rw-r--r--docs/coverage.out5310
4 files changed, 9894 insertions, 101 deletions
diff --git a/.gitignore b/.gitignore
index e12d3f6..eb9dcfa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,3 @@
/hexai-lsp
/.gocache/
/.gomodcache/
-coverage.html
diff --git a/Magefile.go b/Magefile.go
index e94d89b..2b9cb2b 100644
--- a/Magefile.go
+++ b/Magefile.go
@@ -4,13 +4,13 @@
package main
import (
- "fmt"
- "os"
- "path/filepath"
- "strings"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
- "github.com/magefile/mage/mg"
- "github.com/magefile/mage/sh"
+ "github.com/magefile/mage/mg"
+ "github.com/magefile/mage/sh"
)
// Default target: build both binaries.
@@ -18,69 +18,69 @@ var Default = Build
// Build builds the Hexai LSP and CLI binaries.
func Build() error {
- mg.Deps(BuildHexaiLSP, BuildHexaiCLI)
- return nil
+ mg.Deps(BuildHexaiLSP, BuildHexaiCLI)
+ return nil
}
// BuildHexaiLSP builds the LSP server binary.
func BuildHexaiLSP() error {
- return sh.RunV("go", "build", "-o", "hexai-lsp", "cmd/hexai-lsp/main.go")
+ return sh.RunV("go", "build", "-o", "hexai-lsp", "cmd/hexai-lsp/main.go")
}
// BuildHexaiCLI builds the CLI binary.
func BuildHexaiCLI() error {
- return sh.RunV("go", "build", "-o", "hexai", "cmd/hexai/main.go")
+ return sh.RunV("go", "build", "-o", "hexai", "cmd/hexai/main.go")
}
// Dev runs tests, vet, lint, then builds with race for both binaries.
func Dev() error {
- mg.Deps(Test, Vet, Lint)
- if err := sh.RunV("go", "build", "-race", "-o", "hexai-lsp", "cmd/hexai-lsp/main.go"); err != nil {
- return err
- }
- return sh.RunV("go", "build", "-race", "-o", "hexai", "cmd/hexai/main.go")
+ mg.Deps(Test, Vet, Lint)
+ if err := sh.RunV("go", "build", "-race", "-o", "hexai-lsp", "cmd/hexai-lsp/main.go"); err != nil {
+ return err
+ }
+ return sh.RunV("go", "build", "-race", "-o", "hexai", "cmd/hexai/main.go")
}
// Run launches the LSP server via go run (useful during development).
func Run() error {
- mg.Deps(Dev)
- return sh.RunV("go", "run", "cmd/hexai-lsp/main.go")
+ mg.Deps(Dev)
+ return sh.RunV("go", "run", "cmd/hexai-lsp/main.go")
}
// RunCLI runs the CLI with a small test input.
func RunCLI() error {
- mg.Deps(Dev)
- cmd := "echo 'test' | go run cmd/hexai/main.go"
- return sh.RunV("bash", "-lc", cmd)
+ mg.Deps(Dev)
+ cmd := "echo 'test' | go run cmd/hexai/main.go"
+ return sh.RunV("bash", "-lc", cmd)
}
// Install copies built binaries to GOPATH/bin (defaults to ~/go/bin when GOPATH is unset).
func Install() error {
- mg.Deps(Build)
- gopath := os.Getenv("GOPATH")
- if gopath == "" {
- home, err := os.UserHomeDir()
- if err != nil {
- return fmt.Errorf("resolve home: %w", err)
- }
- gopath = filepath.Join(home, "go")
- }
- bin := filepath.Join(gopath, "bin")
- if err := os.MkdirAll(bin, 0o755); err != nil {
- return err
- }
- if err := sh.RunV("cp", "-v", "./hexai-lsp", bin+"/"); err != nil {
- return err
- }
- return sh.RunV("cp", "-v", "./hexai", bin+"/")
+ mg.Deps(Build)
+ gopath := os.Getenv("GOPATH")
+ if gopath == "" {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ return fmt.Errorf("resolve home: %w", err)
+ }
+ gopath = filepath.Join(home, "go")
+ }
+ bin := filepath.Join(gopath, "bin")
+ if err := os.MkdirAll(bin, 0o755); err != nil {
+ return err
+ }
+ if err := sh.RunV("cp", "-v", "./hexai-lsp", bin+"/"); err != nil {
+ return err
+ }
+ return sh.RunV("cp", "-v", "./hexai", bin+"/")
}
// Test runs the test suite.
func Test() error {
- if err := sh.RunV("go", "clean", "-testcache"); err != nil {
- return err
- }
- return sh.RunV("go", "test", "-v", "./...")
+ if err := sh.RunV("go", "clean", "-testcache"); err != nil {
+ return err
+ }
+ return sh.RunV("go", "test", "-v", "./...")
}
// Cover generates a unit test coverage report.
@@ -88,81 +88,81 @@ func Test() error {
// - Prints function coverage summary to stdout
// - Writes HTML report to coverage.html
func Cover() error {
- // Ensure a clean slate
- _ = os.Remove("coverage.out")
- _ = os.Remove("coverage.html")
- if err := sh.RunV("go", "clean", "-testcache"); err != nil {
- return err
- }
- if err := sh.RunV("go", "test", "-covermode=atomic", "-coverprofile=coverage.out", "./..."); err != nil {
- return err
- }
- // Print function-by-function coverage summary
- if out, err := sh.Output("go", "tool", "cover", "-func=coverage.out"); err == nil {
- fmt.Print(out)
- lines := strings.Split(strings.TrimSpace(out), "\n")
- for i := len(lines) - 1; i >= 0; i-- {
- if strings.HasPrefix(strings.TrimSpace(lines[i]), "total:") {
- fmt.Println("\nTotal coverage:", strings.TrimSpace(lines[i]))
- break
- }
- }
- } else {
- return err
- }
- // Generate an HTML report for browsers/editors
- if err := sh.RunV("go", "tool", "cover", "-html=coverage.out", "-o", "coverage.html"); err != nil {
- return err
- }
- fmt.Println("HTML coverage report written to ./coverage.html")
- return nil
+ // Ensure a clean slate
+ _ = os.Remove("docs/coverage.out")
+ _ = os.Remove("docs/coverage.html")
+ if err := sh.RunV("go", "clean", "-testcache"); err != nil {
+ return err
+ }
+ if err := sh.RunV("go", "test", "-covermode=atomic", "-coverprofile=docs/coverage.out", "./..."); err != nil {
+ return err
+ }
+ // Print function-by-function coverage summary
+ if out, err := sh.Output("go", "tool", "cover", "-func=docs/coverage.out"); err == nil {
+ fmt.Print(out)
+ lines := strings.Split(strings.TrimSpace(out), "\n")
+ for i := len(lines) - 1; i >= 0; i-- {
+ if strings.HasPrefix(strings.TrimSpace(lines[i]), "total:") {
+ fmt.Println("\nTotal coverage:", strings.TrimSpace(lines[i]))
+ break
+ }
+ }
+ } else {
+ return err
+ }
+ // Generate an HTML report for browsers/editors
+ if err := sh.RunV("go", "tool", "cover", "-html=docs/coverage.out", "-o", "docs/coverage.html"); err != nil {
+ return err
+ }
+ fmt.Println("HTML coverage report written to docs/coverage.html")
+ return nil
}
// CoverAll generates a combined coverage profile across all packages (cross-package coverage).
// Instruments all packages during each test run using -coverpkg=./... so that
// coverage collected from one package's tests include code executed in others.
func CoverAll() error {
- _ = os.Remove("coverage.out")
- _ = os.Remove("coverage.html")
- if err := sh.RunV("go", "clean", "-testcache"); err != nil {
- return err
- }
- if err := sh.RunV("go", "test", "-covermode=atomic", "-coverpkg=./...", "-coverprofile=coverage.out", "./..."); err != nil {
- return err
- }
- if out, err := sh.Output("go", "tool", "cover", "-func=coverage.out"); err == nil {
- fmt.Print(out)
- lines := strings.Split(strings.TrimSpace(out), "\n")
- for i := len(lines) - 1; i >= 0; i-- {
- if strings.HasPrefix(strings.TrimSpace(lines[i]), "total:") {
- fmt.Println("\nTotal coverage (cross-package):", strings.TrimSpace(lines[i]))
- break
- }
- }
- } else {
- return err
- }
- if err := sh.RunV("go", "tool", "cover", "-html=coverage.out", "-o", "coverage.html"); err != nil {
- return err
- }
- fmt.Println("HTML coverage report written to ./coverage.html (cross-package)")
- return nil
+ _ = os.Remove("docs/coverage.out")
+ _ = os.Remove("docs/coverage.html")
+ if err := sh.RunV("go", "clean", "-testcache"); err != nil {
+ return err
+ }
+ if err := sh.RunV("go", "test", "-covermode=atomic", "-coverpkg=./...", "-coverprofile=docs/coverage.out", "./..."); err != nil {
+ return err
+ }
+ if out, err := sh.Output("go", "tool", "cover", "-func=docs/coverage.out"); err == nil {
+ fmt.Print(out)
+ lines := strings.Split(strings.TrimSpace(out), "\n")
+ for i := len(lines) - 1; i >= 0; i-- {
+ if strings.HasPrefix(strings.TrimSpace(lines[i]), "total:") {
+ fmt.Println("\nTotal coverage (cross-package):", strings.TrimSpace(lines[i]))
+ break
+ }
+ }
+ } else {
+ return err
+ }
+ if err := sh.RunV("go", "tool", "cover", "-html=docs/coverage.out", "-o", "docs/coverage.html"); err != nil {
+ return err
+ }
+ fmt.Println("HTML coverage report written to docs/coverage.html (cross-package)")
+ return nil
}
// Vet runs go vet.
func Vet() error {
- return sh.RunV("go", "vet", "./...")
+ return sh.RunV("go", "vet", "./...")
}
// Lint runs golangci-lint.
func Lint() error {
- return sh.RunV("golangci-lint", "run")
+ return sh.RunV("golangci-lint", "run")
}
// DevInstall installs helpful developer tools.
func DevInstall() error {
- if err := sh.RunV("go", "install", "golang.org/x/tools/gopls@latest"); err != nil {
- return err
- }
- return sh.RunV("go", "install", "github.com/golangci/golangci-lint/cmd/golangci-lint@latest")
+ if err := sh.RunV("go", "install", "golang.org/x/tools/gopls@latest"); err != nil {
+ return err
+ }
+ return sh.RunV("go", "install", "github.com/golangci/golangci-lint/cmd/golangci-lint@latest")
}
diff --git a/docs/coverage.html b/docs/coverage.html
new file mode 100644
index 0000000..ac804e2
--- /dev/null
+++ b/docs/coverage.html
@@ -0,0 +1,4484 @@
+
+<!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 (0.0%)</option>
+
+ <option value="file1">codeberg.org/snonux/hexai/cmd/hexai/main.go (0.0%)</option>
+
+ <option value="file2">codeberg.org/snonux/hexai/internal/appconfig/config.go (32.3%)</option>
+
+ <option value="file3">codeberg.org/snonux/hexai/internal/hexaicli/run.go (63.8%)</option>
+
+ <option value="file4">codeberg.org/snonux/hexai/internal/hexailsp/run.go (92.5%)</option>
+
+ <option value="file5">codeberg.org/snonux/hexai/internal/llm/copilot.go (7.9%)</option>
+
+ <option value="file6">codeberg.org/snonux/hexai/internal/llm/ollama.go (13.9%)</option>
+
+ <option value="file7">codeberg.org/snonux/hexai/internal/llm/openai.go (32.6%)</option>
+
+ <option value="file8">codeberg.org/snonux/hexai/internal/llm/provider.go (37.9%)</option>
+
+ <option value="file9">codeberg.org/snonux/hexai/internal/llm/util.go (0.0%)</option>
+
+ <option value="file10">codeberg.org/snonux/hexai/internal/logging/chatlogger.go (14.3%)</option>
+
+ <option value="file11">codeberg.org/snonux/hexai/internal/logging/logging.go (90.9%)</option>
+
+ <option value="file12">codeberg.org/snonux/hexai/internal/lsp/context.go (71.8%)</option>
+
+ <option value="file13">codeberg.org/snonux/hexai/internal/lsp/document.go (56.3%)</option>
+
+ <option value="file14">codeberg.org/snonux/hexai/internal/lsp/handlers.go (77.8%)</option>
+
+ <option value="file15">codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go (22.9%)</option>
+
+ <option value="file16">codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go (69.8%)</option>
+
+ <option value="file17">codeberg.org/snonux/hexai/internal/lsp/handlers_document.go (1.8%)</option>
+
+ <option value="file18">codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go (0.0%)</option>
+
+ <option value="file19">codeberg.org/snonux/hexai/internal/lsp/handlers_init.go (0.0%)</option>
+
+ <option value="file20">codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go (65.3%)</option>
+
+ <option value="file21">codeberg.org/snonux/hexai/internal/lsp/server.go (68.8%)</option>
+
+ <option value="file22">codeberg.org/snonux/hexai/internal/lsp/transport.go (17.1%)</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"
+ "log"
+ "os"
+
+ "codeberg.org/snonux/hexai/internal"
+ "codeberg.org/snonux/hexai/internal/hexailsp"
+)
+
+func main() <span class="cov0" title="0">{
+ logPath := flag.String("log", "/tmp/hexai-lsp.log", "path to log file (optional)")
+ showVersion := flag.Bool("version", false, "print version and exit")
+ flag.Parse()
+ if *showVersion </span><span class="cov0" title="0">{
+ log.Println(internal.Version)
+ return
+ }</span>
+
+ <span class="cov0" title="0">if err := hexailsp.Run(*logPath, os.Stdin, os.Stdout, os.Stderr); err != nil </span><span class="cov0" title="0">{
+ log.Fatalf("server error: %v", err)
+ }</span>
+}
+</pre>
+
+ <pre class="file" id="file1" style="display: none">// Summary: Hexai CLI entrypoint; parses flags and delegates to internal/hexaicli.
+package main
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "os"
+
+ "codeberg.org/snonux/hexai/internal"
+ "codeberg.org/snonux/hexai/internal/hexaicli"
+)
+
+func main() <span class="cov0" title="0">{
+ showVersion := flag.Bool("version", false, "print version and exit")
+ flag.Parse()
+ if *showVersion </span><span class="cov0" title="0">{
+ fmt.Fprintln(os.Stdout, internal.Version)
+ return
+ }</span>
+
+ <span class="cov0" title="0">if err := hexaicli.Run(context.Background(), flag.Args(), os.Stdin, os.Stdout, os.Stderr); err != nil </span><span class="cov0" title="0">{
+ os.Exit(1)
+ }</span>
+}
+</pre>
+
+ <pre class="file" id="file2" style="display: none">// Summary: Application configuration model and loader; reads ~/.config/hexai/config.json and merges defaults.
+package appconfig
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+ "slices"
+ "strconv"
+ "strings"
+)
+
+// App holds user-configurable settings read from ~/.config/hexai/config.json.
+type App struct {
+ MaxTokens int `json:"max_tokens"`
+ ContextMode string `json:"context_mode"`
+ ContextWindowLines int `json:"context_window_lines"`
+ MaxContextTokens int `json:"max_context_tokens"`
+ LogPreviewLimit int `json:"log_preview_limit"`
+ // Single knob for LSP requests; if set, overrides hardcoded temps in LSP.
+ CodingTemperature *float64 `json:"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"`
+
+ // Completion debounce in milliseconds. When &gt; 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"`
+ // Completion throttle in milliseconds. When &gt; 0, caps the minimum spacing
+ // between LLM requests (both chat and code-completer paths).
+ CompletionThrottleMs int `json:"completion_throttle_ms"`
+
+ TriggerCharacters []string `json:"trigger_characters"`
+ Provider string `json:"provider"`
+
+ // Provider-specific options
+ OpenAIBaseURL string `json:"openai_base_url"`
+ OpenAIModel string `json:"openai_model"`
+ // Default temperature for OpenAI requests (nil means use provider default)
+ OpenAITemperature *float64 `json:"openai_temperature"`
+ OllamaBaseURL string `json:"ollama_base_url"`
+ OllamaModel string `json:"ollama_model"`
+ // Default temperature for Ollama requests (nil means use provider default)
+ OllamaTemperature *float64 `json:"ollama_temperature"`
+ CopilotBaseURL string `json:"copilot_base_url"`
+ CopilotModel string `json:"copilot_model"`
+ // Default temperature for Copilot requests (nil means use provider default)
+ CopilotTemperature *float64 `json:"copilot_temperature"`
+}
+
+// Constructor: defaults for App (kept first among functions)
+func newDefaultConfig() App <span class="cov4" title="3">{
+ // Coding-friendly default temperature across providers
+ // Users can override per provider in config.json (including 0.0).
+ t := 0.2
+ return App{
+ MaxTokens: 4000,
+ ContextMode: "always-full",
+ ContextWindowLines: 120,
+ MaxContextTokens: 4000,
+ LogPreviewLimit: 100,
+ CodingTemperature: &amp;t,
+ OpenAITemperature: &amp;t,
+ OllamaTemperature: &amp;t,
+ CopilotTemperature: &amp;t,
+ ManualInvokeMinPrefix: 0,
+ CompletionDebounceMs: 200,
+ CompletionThrottleMs: 0,
+ }
+}</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="cov4" title="3">{
+ cfg := newDefaultConfig()
+ if logger == nil </span><span class="cov3" title="2">{
+ return cfg // Return defaults if no logger is provided (e.g. in tests)
+ }</span>
+
+ <span class="cov1" title="1">configPath, err := getConfigPath()
+ if err != nil </span><span class="cov0" title="0">{
+ logger.Printf("%v", err)
+ // Even if config path cannot be resolved, still allow env overrides below.
+ }</span> else<span class="cov1" title="1"> {
+ if fileCfg, err := loadFromFile(configPath, logger); err == nil &amp;&amp; fileCfg != nil </span><span class="cov0" title="0">{
+ cfg.mergeWith(fileCfg)
+ }</span>
+ // When the config file is missing or invalid, we keep defaults and still
+ // apply any environment overrides below.
+ }
+
+ // Environment overrides (take precedence over file)
+ <span class="cov1" title="1">if envCfg := loadFromEnv(logger); envCfg != nil </span><span class="cov0" title="0">{
+ cfg.mergeWith(envCfg)
+ }</span>
+ <span class="cov1" title="1">return cfg</span>
+}
+
+// Private helpers
+func loadFromFile(path string, logger *log.Logger) (*App, error) <span class="cov1" title="1">{
+ f, err := os.Open(path)
+ if err != nil </span><span class="cov1" title="1">{
+ if !os.IsNotExist(err) &amp;&amp; logger != nil </span><span class="cov0" title="0">{
+ logger.Printf("cannot open config file %s: %v", path, err)
+ }</span>
+ <span class="cov1" title="1">return nil, err</span>
+ }
+ <span class="cov0" title="0">defer f.Close()
+
+ dec := json.NewDecoder(f)
+ var fileCfg App
+ if err := dec.Decode(&amp;fileCfg); err != nil </span><span class="cov0" title="0">{
+ if logger != nil </span><span class="cov0" title="0">{
+ logger.Printf("invalid config file %s: %v", path, err)
+ }</span>
+ <span class="cov0" title="0">return nil, err</span>
+ }
+ <span class="cov0" title="0">return &amp;fileCfg, nil</span>
+}
+
+func (a *App) mergeWith(other *App) <span class="cov0" title="0">{
+ a.mergeBasics(other)
+ a.mergeProviderFields(other)
+}</span>
+
+// mergeBasics merges general (non-provider) fields.
+func (a *App) mergeBasics(other *App) <span class="cov0" title="0">{
+ if other.MaxTokens &gt; 0 </span><span class="cov0" title="0">{
+ a.MaxTokens = other.MaxTokens
+ }</span>
+ <span class="cov0" title="0">if s := strings.TrimSpace(other.ContextMode); s != "" </span><span class="cov0" title="0">{
+ a.ContextMode = s
+ }</span>
+ <span class="cov0" title="0">if other.ContextWindowLines &gt; 0 </span><span class="cov0" title="0">{
+ a.ContextWindowLines = other.ContextWindowLines
+ }</span>
+ <span class="cov0" title="0">if other.MaxContextTokens &gt; 0 </span><span class="cov0" title="0">{
+ a.MaxContextTokens = other.MaxContextTokens
+ }</span>
+ <span class="cov0" title="0">if other.LogPreviewLimit &gt;= 0 </span><span class="cov0" title="0">{
+ a.LogPreviewLimit = other.LogPreviewLimit
+ }</span>
+ <span class="cov0" title="0">if other.CodingTemperature != nil </span><span class="cov0" title="0">{ // allow explicit 0.0
+ a.CodingTemperature = other.CodingTemperature
+ }</span>
+ <span class="cov0" title="0">if other.ManualInvokeMinPrefix &gt;= 0 </span><span class="cov0" title="0">{
+ a.ManualInvokeMinPrefix = other.ManualInvokeMinPrefix
+ }</span>
+ <span class="cov0" title="0">if other.CompletionDebounceMs &gt; 0 </span><span class="cov0" title="0">{ a.CompletionDebounceMs = other.CompletionDebounceMs }</span>
+ <span class="cov0" title="0">if other.CompletionThrottleMs &gt; 0 </span><span class="cov0" title="0">{ a.CompletionThrottleMs = other.CompletionThrottleMs }</span>
+ <span class="cov0" title="0">if len(other.TriggerCharacters) &gt; 0 </span><span class="cov0" title="0">{
+ a.TriggerCharacters = slices.Clone(other.TriggerCharacters)
+ }</span>
+ <span class="cov0" title="0">if s := strings.TrimSpace(other.Provider); s != "" </span><span class="cov0" title="0">{
+ a.Provider = s
+ }</span>
+}
+
+// mergeProviderFields merges per-provider configuration.
+func (a *App) mergeProviderFields(other *App) <span class="cov0" title="0">{
+ if s := strings.TrimSpace(other.OpenAIBaseURL); s != "" </span><span class="cov0" title="0">{
+ a.OpenAIBaseURL = s
+ }</span>
+ <span class="cov0" title="0">if s := strings.TrimSpace(other.OpenAIModel); s != "" </span><span class="cov0" title="0">{
+ a.OpenAIModel = s
+ }</span>
+ <span class="cov0" title="0">if other.OpenAITemperature != nil </span><span class="cov0" title="0">{ // allow explicit 0.0
+ a.OpenAITemperature = other.OpenAITemperature
+ }</span>
+ <span class="cov0" title="0">if s := strings.TrimSpace(other.OllamaBaseURL); s != "" </span><span class="cov0" title="0">{
+ a.OllamaBaseURL = s
+ }</span>
+ <span class="cov0" title="0">if s := strings.TrimSpace(other.OllamaModel); s != "" </span><span class="cov0" title="0">{
+ a.OllamaModel = s
+ }</span>
+ <span class="cov0" title="0">if other.OllamaTemperature != nil </span><span class="cov0" title="0">{ // allow explicit 0.0
+ a.OllamaTemperature = other.OllamaTemperature
+ }</span>
+ <span class="cov0" title="0">if s := strings.TrimSpace(other.CopilotBaseURL); s != "" </span><span class="cov0" title="0">{
+ a.CopilotBaseURL = s
+ }</span>
+ <span class="cov0" title="0">if s := strings.TrimSpace(other.CopilotModel); s != "" </span><span class="cov0" title="0">{
+ a.CopilotModel = s
+ }</span>
+ <span class="cov0" title="0">if other.CopilotTemperature != nil </span><span class="cov0" title="0">{ // allow explicit 0.0
+ a.CopilotTemperature = other.CopilotTemperature
+ }</span>
+}
+
+func getConfigPath() (string, error) <span class="cov1" title="1">{
+ var configPath string
+ if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" </span><span class="cov0" title="0">{
+ configPath = filepath.Join(xdgConfigHome, "hexai", "config.json")
+ }</span> else<span class="cov1" title="1"> {
+ home, err := os.UserHomeDir()
+ if err != nil </span><span class="cov0" title="0">{
+ return "", fmt.Errorf("cannot find user home directory: %v", err)
+ }</span>
+ <span class="cov1" title="1">configPath = filepath.Join(home, ".config", "hexai", "config.json")</span>
+ }
+ <span class="cov1" title="1">return configPath, nil</span>
+}
+
+// --- Environment overrides ---
+
+// loadFromEnv constructs an App containing only fields set via HEXAI_* env vars.
+// These values should take precedence over file config when merged.
+func loadFromEnv(logger *log.Logger) *App <span class="cov1" title="1">{
+ var out App
+ var any bool
+
+ // helpers
+ getenv := func(k string) string </span><span class="cov10" title="20">{ return strings.TrimSpace(os.Getenv(k)) }</span>
+ <span class="cov1" title="1">parseInt := func(k string) (int, bool) </span><span class="cov6" title="7">{
+ v := getenv(k)
+ if v == "" </span><span class="cov6" title="7">{ return 0, false }</span>
+ <span class="cov0" title="0">n, err := strconv.Atoi(v)
+ if err != nil </span><span class="cov0" title="0">{ if logger != nil </span><span class="cov0" title="0">{ logger.Printf("invalid %s: %v", k, err) }</span> ; <span class="cov0" title="0">return 0, false</span> }
+ <span class="cov0" title="0">return n, true</span>
+ }
+ <span class="cov1" title="1">parseFloatPtr := func(k string) (*float64, bool) </span><span class="cov5" title="4">{
+ v := getenv(k)
+ if v == "" </span><span class="cov5" title="4">{ return nil, false }</span>
+ <span class="cov0" title="0">f, err := strconv.ParseFloat(v, 64)
+ if err != nil </span><span class="cov0" title="0">{
+ if logger != nil </span><span class="cov0" title="0">{ logger.Printf("invalid %s: %v", k, err) }</span>
+ <span class="cov0" title="0">return nil, false</span>
+ }
+ <span class="cov0" title="0">return &amp;f, true</span>
+ }
+
+ <span class="cov1" title="1">if n, ok := parseInt("HEXAI_MAX_TOKENS"); ok </span><span class="cov0" title="0">{
+ out.MaxTokens = n; any = true
+ }</span>
+ <span class="cov1" title="1">if s := getenv("HEXAI_CONTEXT_MODE"); s != "" </span><span class="cov0" title="0">{
+ out.ContextMode = s; any = true
+ }</span>
+ <span class="cov1" title="1">if n, ok := parseInt("HEXAI_CONTEXT_WINDOW_LINES"); ok </span><span class="cov0" title="0">{
+ out.ContextWindowLines = n; any = true
+ }</span>
+ <span class="cov1" title="1">if n, ok := parseInt("HEXAI_MAX_CONTEXT_TOKENS"); ok </span><span class="cov0" title="0">{
+ out.MaxContextTokens = n; any = true
+ }</span>
+ <span class="cov1" title="1">if n, ok := parseInt("HEXAI_LOG_PREVIEW_LIMIT"); ok </span><span class="cov0" title="0">{
+ out.LogPreviewLimit = n; any = true
+ }</span>
+ <span class="cov1" title="1">if n, ok := parseInt("HEXAI_MANUAL_INVOKE_MIN_PREFIX"); ok </span><span class="cov0" title="0">{
+ out.ManualInvokeMinPrefix = n; any = true
+ }</span>
+ <span class="cov1" title="1">if n, ok := parseInt("HEXAI_COMPLETION_DEBOUNCE_MS"); ok </span><span class="cov0" title="0">{
+ out.CompletionDebounceMs = n; any = true
+ }</span>
+ <span class="cov1" title="1">if n, ok := parseInt("HEXAI_COMPLETION_THROTTLE_MS"); ok </span><span class="cov0" title="0">{
+ out.CompletionThrottleMs = n; any = true
+ }</span>
+ <span class="cov1" title="1">if f, ok := parseFloatPtr("HEXAI_CODING_TEMPERATURE"); ok </span><span class="cov0" title="0">{
+ out.CodingTemperature = f; any = true
+ }</span>
+ <span class="cov1" title="1">if s := getenv("HEXAI_TRIGGER_CHARACTERS"); s != "" </span><span class="cov0" title="0">{
+ parts := strings.Split(s, ",")
+ out.TriggerCharacters = nil
+ for _, p := range parts </span><span class="cov0" title="0">{
+ if t := strings.TrimSpace(p); t != "" </span><span class="cov0" title="0">{
+ out.TriggerCharacters = append(out.TriggerCharacters, t)
+ }</span>
+ }
+ <span class="cov0" title="0">any = true</span>
+ }
+ <span class="cov1" title="1">if s := getenv("HEXAI_PROVIDER"); s != "" </span><span class="cov0" title="0">{
+ out.Provider = s; any = true
+ }</span>
+
+ // Provider-specific
+ <span class="cov1" title="1">if s := getenv("HEXAI_OPENAI_BASE_URL"); s != "" </span><span class="cov0" title="0">{ out.OpenAIBaseURL = s; any = true }</span>
+ <span class="cov1" title="1">if s := getenv("HEXAI_OPENAI_MODEL"); s != "" </span><span class="cov0" title="0">{ out.OpenAIModel = s; any = true }</span>
+ <span class="cov1" title="1">if f, ok := parseFloatPtr("HEXAI_OPENAI_TEMPERATURE"); ok </span><span class="cov0" title="0">{ out.OpenAITemperature = f; any = true }</span>
+
+ <span class="cov1" title="1">if s := getenv("HEXAI_OLLAMA_BASE_URL"); s != "" </span><span class="cov0" title="0">{ out.OllamaBaseURL = s; any = true }</span>
+ <span class="cov1" title="1">if s := getenv("HEXAI_OLLAMA_MODEL"); s != "" </span><span class="cov0" title="0">{ out.OllamaModel = s; any = true }</span>
+ <span class="cov1" title="1">if f, ok := parseFloatPtr("HEXAI_OLLAMA_TEMPERATURE"); ok </span><span class="cov0" title="0">{ out.OllamaTemperature = f; any = true }</span>
+
+ <span class="cov1" title="1">if s := getenv("HEXAI_COPILOT_BASE_URL"); s != "" </span><span class="cov0" title="0">{ out.CopilotBaseURL = s; any = true }</span>
+ <span class="cov1" title="1">if s := getenv("HEXAI_COPILOT_MODEL"); s != "" </span><span class="cov0" title="0">{ out.CopilotModel = s; any = true }</span>
+ <span class="cov1" title="1">if f, ok := parseFloatPtr("HEXAI_COPILOT_TEMPERATURE"); ok </span><span class="cov0" title="0">{ out.CopilotTemperature = f; any = true }</span>
+
+ <span class="cov1" title="1">if !any </span><span class="cov1" title="1">{
+ return nil
+ }</span>
+ <span class="cov0" title="0">return &amp;out</span>
+}
+</pre>
+
+ <pre class="file" id="file3" style="display: none">// Summary: Hexai CLI runner; reads input, creates an LLM client, builds messages,
+// streams or collects the model output, and prints a short summary to stderr.
+package hexaicli
+
+import (
+ "bufio"
+ "context"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "strings"
+ "time"
+
+ "codeberg.org/snonux/hexai/internal/appconfig"
+ "codeberg.org/snonux/hexai/internal/llm"
+ "codeberg.org/snonux/hexai/internal/logging"
+)
+
+// Run executes the Hexai CLI behavior given arguments and I/O streams.
+// It assumes flags have already been parsed by the caller.
+func Run(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) error <span class="cov0" title="0">{
+ // Load configuration with a logger so file-based config is respected.
+ logger := log.New(stderr, "hexai ", log.LstdFlags|log.Lmsgprefix)
+ cfg := appconfig.Load(logger)
+ client, err := newClientFromConfig(cfg)
+ if err != nil </span><span class="cov0" title="0">{
+ fmt.Fprintf(stderr, logging.AnsiBase+"hexai: LLM disabled: %v"+logging.AnsiReset+"\n", err)
+ return err
+ }</span>
+
+ <span class="cov0" title="0">return RunWithClient(ctx, args, stdin, stdout, stderr, client)</span>
+}
+
+// RunWithClient executes the CLI flow using an already-constructed client.
+// Useful for testing and embedding.
+func RunWithClient(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer, client llm.Client) error <span class="cov6" title="3">{
+ input, err := readInput(stdin, args)
+ if err != nil </span><span class="cov0" title="0">{
+ fmt.Fprintln(stderr, logging.AnsiBase+err.Error()+logging.AnsiReset)
+ return err
+ }</span>
+ <span class="cov6" title="3">printProviderInfo(stderr, client)
+ msgs := buildMessages(input)
+ if err := runChat(ctx, client, msgs, input, stdout, stderr); err != nil </span><span class="cov0" title="0">{
+ fmt.Fprintf(stderr, logging.AnsiBase+"hexai: error: %v"+logging.AnsiReset+"\n", err)
+ return err
+ }</span>
+ <span class="cov6" title="3">return nil</span>
+}
+
+// readInput reads from stdin and args, then combines them per CLI rules.
+func readInput(stdin io.Reader, args []string) (string, error) <span class="cov10" title="7">{
+ var stdinData string
+ if fi, err := os.Stdin.Stat(); err == nil &amp;&amp; (fi.Mode()&amp;os.ModeCharDevice) == 0 </span><span class="cov10" title="7">{
+ b, _ := io.ReadAll(bufio.NewReader(stdin))
+ stdinData = strings.TrimSpace(string(b))
+ }</span>
+ <span class="cov10" title="7">argData := strings.TrimSpace(strings.Join(args, " "))
+ switch </span>{
+ case stdinData != "" &amp;&amp; argData != "":<span class="cov4" title="2">
+ return fmt.Sprintf("%s:\n\n%s", argData, stdinData), nil</span>
+ case stdinData != "":<span class="cov1" title="1">
+ return stdinData, nil</span>
+ case argData != "":<span class="cov6" title="3">
+ return argData, nil</span>
+ default:<span class="cov1" title="1">
+ return "", fmt.Errorf("hexai: no input provided; pass text as an argument or via stdin")</span>
+ }
+}
+
+// newClientFromConfig builds an LLM client from the app config and env keys.
+func newClientFromConfig(cfg appconfig.App) (llm.Client, error) <span class="cov0" title="0">{
+ llmCfg := llm.Config{
+ Provider: cfg.Provider,
+ OpenAIBaseURL: cfg.OpenAIBaseURL,
+ OpenAIModel: cfg.OpenAIModel,
+ OpenAITemperature: cfg.OpenAITemperature,
+ OllamaBaseURL: cfg.OllamaBaseURL,
+ OllamaModel: cfg.OllamaModel,
+ OllamaTemperature: cfg.OllamaTemperature,
+ CopilotBaseURL: cfg.CopilotBaseURL,
+ CopilotModel: cfg.CopilotModel,
+ CopilotTemperature: cfg.CopilotTemperature,
+ }
+ // Prefer HEXAI_OPENAI_API_KEY; fall back to OPENAI_API_KEY
+ oaKey := os.Getenv("HEXAI_OPENAI_API_KEY")
+ if strings.TrimSpace(oaKey) == "" </span><span class="cov0" title="0">{
+ oaKey = os.Getenv("OPENAI_API_KEY")
+ }</span>
+ // Prefer HEXAI_COPILOT_API_KEY; fall back to COPILOT_API_KEY
+ <span class="cov0" title="0">cpKey := os.Getenv("HEXAI_COPILOT_API_KEY")
+ if strings.TrimSpace(cpKey) == "" </span><span class="cov0" title="0">{
+ cpKey = os.Getenv("COPILOT_API_KEY")
+ }</span>
+ <span class="cov0" title="0">return llm.NewFromConfig(llmCfg, oaKey, cpKey)</span>
+}
+
+// buildMessages creates system and user messages based on input content.
+func buildMessages(input string) []llm.Message <span class="cov8" title="5">{
+ lower := strings.ToLower(input)
+ system := "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."
+ if strings.Contains(lower, "explain") </span><span class="cov1" title="1">{
+ system = "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."
+ }</span>
+ <span class="cov8" title="5">return []llm.Message{
+ {Role: "system", Content: system},
+ {Role: "user", Content: input},
+ }</span>
+}
+
+// runChat executes the chat request, handling streaming and summary output.
+func runChat(ctx context.Context, client llm.Client, msgs []llm.Message, input string, out io.Writer, errw io.Writer) error <span class="cov8" title="5">{
+ start := time.Now()
+ var output string
+ if s, ok := client.(llm.Streamer); ok </span><span class="cov4" title="2">{
+ var b strings.Builder
+ if err := s.ChatStream(ctx, msgs, func(chunk string) </span><span class="cov7" title="4">{
+ b.WriteString(chunk)
+ fmt.Fprint(out, chunk)
+ }</span>); err != nil <span class="cov0" title="0">{
+ return err
+ }</span>
+ <span class="cov4" title="2">output = b.String()</span>
+ } else<span class="cov6" title="3"> {
+ txt, err := client.Chat(ctx, msgs)
+ if err != nil </span><span class="cov0" title="0">{
+ return err
+ }</span>
+ <span class="cov6" title="3">output = txt
+ fmt.Fprint(out, output)</span>
+ }
+ <span class="cov8" title="5">dur := time.Since(start)
+ fmt.Fprintf(errw, "\n"+logging.AnsiBase+"done provider=%s model=%s time=%s in_bytes=%d out_bytes=%d"+logging.AnsiReset+"\n",
+ client.Name(), client.DefaultModel(), dur.Round(time.Millisecond), len(input), len(output))
+ return nil</span>
+}
+
+// printProviderInfo writes the provider/model line to stderr.
+func printProviderInfo(errw io.Writer, client llm.Client) <span class="cov7" title="4">{
+ fmt.Fprintf(errw, logging.AnsiBase+"provider=%s model=%s"+logging.AnsiReset+"\n", client.Name(), client.DefaultModel())
+}</span>
+</pre>
+
+ <pre class="file" id="file4" style="display: none">// Summary: Hexai LSP runner; configures logging, loads config, builds the LLM client,
+// and constructs/runs the LSP server (with injectable factory for tests).
+package hexailsp
+
+import (
+ "io"
+ "log"
+ "os"
+ "strings"
+
+ "codeberg.org/snonux/hexai/internal/appconfig"
+ "codeberg.org/snonux/hexai/internal/llm"
+ "codeberg.org/snonux/hexai/internal/logging"
+ "codeberg.org/snonux/hexai/internal/lsp"
+)
+
+// ServerRunner is the minimal interface satisfied by lsp.Server.
+type ServerRunner interface{ Run() error }
+
+// ServerFactory creates a ServerRunner. Default uses lsp.NewServer.
+type ServerFactory func(r io.Reader, w io.Writer, logger *log.Logger, opts lsp.ServerOptions) ServerRunner
+
+// Run configures logging, loads config, builds the LLM client and runs the LSP server.
+// It is thin and delegates to RunWithFactory for testability.
+func Run(logPath string, stdin io.Reader, stdout io.Writer, stderr io.Writer) error <span class="cov1" title="1">{
+ logger := log.New(stderr, "hexai-lsp ", log.LstdFlags|log.Lmsgprefix)
+ if strings.TrimSpace(logPath) != "" </span><span class="cov1" title="1">{
+ f, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
+ if err != nil </span><span class="cov0" title="0">{
+ logger.Fatalf("failed to open log file: %v", err)
+ }</span>
+ <span class="cov1" title="1">defer f.Close()
+ logger.SetOutput(f)</span>
+ }
+ <span class="cov1" title="1">logging.Bind(logger)
+ cfg := appconfig.Load(logger)
+ return RunWithFactory(logPath, stdin, stdout, logger, cfg, nil, nil)</span>
+}
+
+// RunWithFactory is the testable entrypoint. When client is nil, it is built from cfg+env.
+// When factory is nil, lsp.NewServer is used.
+func RunWithFactory(logPath string, stdin io.Reader, stdout io.Writer, logger *log.Logger, cfg appconfig.App, client llm.Client, factory ServerFactory) error <span class="cov10" title="6">{
+ normalizeLoggingConfig(&amp;cfg)
+ client = buildClientIfNil(cfg, client)
+ factory = ensureFactory(factory)
+
+ opts := makeServerOptions(cfg, strings.TrimSpace(logPath) != "", client)
+ server := factory(stdin, stdout, logger, opts)
+ if err := server.Run(); err != nil </span><span class="cov0" title="0">{
+ logger.Fatalf("server error: %v", err)
+ }</span>
+ <span class="cov10" title="6">return nil</span>
+}
+
+// --- helpers to keep RunWithFactory small ---
+
+func normalizeLoggingConfig(cfg *appconfig.App) <span class="cov10" title="6">{
+ cfg.ContextMode = strings.ToLower(strings.TrimSpace(cfg.ContextMode))
+ if cfg.LogPreviewLimit &gt;= 0 </span><span class="cov10" title="6">{
+ logging.SetLogPreviewLimit(cfg.LogPreviewLimit)
+ }</span>
+}
+
+func buildClientIfNil(cfg appconfig.App, client llm.Client) llm.Client <span class="cov10" title="6">{
+ if client != nil </span><span class="cov0" title="0">{
+ return client
+ }</span>
+ <span class="cov10" title="6">llmCfg := llm.Config{
+ Provider: cfg.Provider,
+ OpenAIBaseURL: cfg.OpenAIBaseURL,
+ OpenAIModel: cfg.OpenAIModel,
+ OpenAITemperature: cfg.OpenAITemperature,
+ OllamaBaseURL: cfg.OllamaBaseURL,
+ OllamaModel: cfg.OllamaModel,
+ OllamaTemperature: cfg.OllamaTemperature,
+ CopilotBaseURL: cfg.CopilotBaseURL,
+ CopilotModel: cfg.CopilotModel,
+ CopilotTemperature: cfg.CopilotTemperature,
+ }
+ // Prefer HEXAI_OPENAI_API_KEY; fall back to OPENAI_API_KEY
+ oaKey := os.Getenv("HEXAI_OPENAI_API_KEY")
+ if strings.TrimSpace(oaKey) == "" </span><span class="cov10" title="6">{
+ oaKey = os.Getenv("OPENAI_API_KEY")
+ }</span>
+ // Prefer HEXAI_COPILOT_API_KEY; fall back to COPILOT_API_KEY
+ <span class="cov10" title="6">cpKey := os.Getenv("HEXAI_COPILOT_API_KEY")
+ if strings.TrimSpace(cpKey) == "" </span><span class="cov10" title="6">{
+ cpKey = os.Getenv("COPILOT_API_KEY")
+ }</span>
+ <span class="cov10" title="6">if c, err := llm.NewFromConfig(llmCfg, oaKey, cpKey); err != nil </span><span class="cov1" title="1">{
+ logging.Logf("lsp ", "llm disabled: %v", err)
+ return nil
+ }</span> else<span class="cov9" title="5"> {
+ logging.Logf("lsp ", "llm enabled provider=%s model=%s", c.Name(), c.DefaultModel())
+ return c
+ }</span>
+}
+
+func ensureFactory(factory ServerFactory) ServerFactory <span class="cov10" title="6">{
+ if factory != nil </span><span class="cov9" title="5">{
+ return factory
+ }</span>
+ <span class="cov1" title="1">return func(r io.Reader, w io.Writer, logger *log.Logger, opts lsp.ServerOptions) ServerRunner </span><span class="cov1" title="1">{
+ return lsp.NewServer(r, w, logger, opts)
+ }</span>
+}
+
+func makeServerOptions(cfg appconfig.App, logContext bool, client llm.Client) lsp.ServerOptions <span class="cov10" title="6">{
+ return lsp.ServerOptions{
+ LogContext: logContext,
+ MaxTokens: cfg.MaxTokens,
+ ContextMode: cfg.ContextMode,
+ WindowLines: cfg.ContextWindowLines,
+ MaxContextTokens: cfg.MaxContextTokens,
+ CodingTemperature: cfg.CodingTemperature,
+ Client: client,
+ TriggerCharacters: cfg.TriggerCharacters,
+ ManualInvokeMinPrefix: cfg.ManualInvokeMinPrefix,
+ CompletionDebounceMs: cfg.CompletionDebounceMs,
+ CompletionThrottleMs: cfg.CompletionThrottleMs,
+ }
+}</span>
+</pre>
+
+ <pre class="file" id="file5" style="display: none">// Summary: GitHub Copilot client for chat and Codex-style code completion.
+package llm
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "regexp"
+ "strings"
+ "time"
+
+ "encoding/base64"
+ appver "codeberg.org/snonux/hexai/internal"
+ "codeberg.org/snonux/hexai/internal/logging"
+)
+
+// copilotClient implements Client against GitHub Copilot's Chat Completions API.
+type copilotClient struct {
+ httpClient *http.Client
+ apiKey string
+ baseURL string
+ defaultModel string
+ chatLogger logging.ChatLogger
+ defaultTemperature *float64
+
+ // cached Copilot session token retrieved from GitHub API using apiKey
+ sessionToken string
+ tokenExpiry time.Time
+}
+
+type copilotChatRequest struct {
+ Model string `json:"model"`
+ Messages []copilotMessage `json:"messages"`
+ Temperature *float64 `json:"temperature,omitempty"`
+ MaxTokens *int `json:"max_tokens,omitempty"`
+ Stop []string `json:"stop,omitempty"`
+}
+
+type copilotMessage struct {
+ Role string `json:"role"`
+ Content string `json:"content"`
+}
+
+type copilotChatResponse struct {
+ Choices []struct {
+ Index int `json:"index"`
+ Message struct {
+ Role string `json:"role"`
+ Content string `json:"content"`
+ } `json:"message"`
+ FinishReason string `json:"finish_reason"`
+ } `json:"choices"`
+ Error *struct {
+ Message string `json:"message"`
+ Type string `json:"type"`
+ Param any `json:"param"`
+ Code any `json:"code"`
+ } `json:"error,omitempty"`
+}
+
+// Constructor (kept among the first functions by convention)
+func newCopilot(baseURL, model, apiKey string, defaultTemp *float64) Client <span class="cov0" title="0">{
+ if strings.TrimSpace(baseURL) == "" </span><span class="cov0" title="0">{
+ baseURL = "https://api.githubcopilot.com"
+ }</span>
+ <span class="cov0" title="0">if strings.TrimSpace(model) == "" </span><span class="cov0" title="0">{
+ // GitHub Models (Copilot API) commonly supports gpt-4o/gpt-4o-mini.
+ // Default to a broadly available, cost-effective option.
+ model = "gpt-4o-mini"
+ }</span>
+ <span class="cov0" title="0">return copilotClient{
+ httpClient: &amp;http.Client{Timeout: 30 * time.Second},
+ apiKey: apiKey,
+ baseURL: strings.TrimRight(baseURL, "/"),
+ defaultModel: model,
+ chatLogger: logging.NewChatLogger("copilot"),
+ defaultTemperature: defaultTemp,
+ }</span>
+}
+
+func (c copilotClient) Chat(ctx context.Context, messages []Message, opts ...RequestOption) (string, error) <span class="cov0" title="0">{
+ if strings.TrimSpace(c.apiKey) == "" </span><span class="cov0" title="0">{
+ return nilStringErr("missing Copilot API key")
+ }</span>
+ // Ensure we have a fresh session token
+ <span class="cov0" title="0">if err := c.ensureSession(ctx); err != nil </span><span class="cov0" title="0">{
+ return "", err
+ }</span>
+ <span class="cov0" title="0">o := Options{Model: c.defaultModel}
+ for _, opt := range opts </span><span class="cov0" title="0">{
+ opt(&amp;o)
+ }</span>
+ <span class="cov0" title="0">if o.Model == "" </span><span class="cov0" title="0">{
+ o.Model = c.defaultModel
+ }</span>
+ <span class="cov0" title="0">start := time.Now()
+ logMessages := make([]struct{ Role, Content string }, len(messages))
+ for i, m := range messages </span><span class="cov0" title="0">{
+ logMessages[i] = struct{ Role, Content string }{m.Role, m.Content}
+ }</span>
+ <span class="cov0" title="0">c.chatLogger.LogStart(false, o.Model, o.Temperature, o.MaxTokens, o.Stop, logMessages)
+
+ req := buildCopilotChatRequest(o, messages, c.defaultTemperature)
+ body, err := json.Marshal(req)
+ if err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/copilot ", "marshal error: %v", err)
+ return "", err
+ }</span>
+
+ <span class="cov0" title="0">endpoint := c.baseURL + "/chat/completions"
+ logging.Logf("llm/copilot ", "POST %s", endpoint)
+ resp, err := c.postJSON(ctx, endpoint, body, c.headersChat())
+ if err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/copilot ", "%shttp error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return "", err
+ }</span>
+ <span class="cov0" title="0">defer resp.Body.Close()
+ if err := handleCopilotNon2xx(resp, start); err != nil </span><span class="cov0" title="0">{
+ return "", err
+ }</span>
+ <span class="cov0" title="0">out, err := decodeCopilotChat(resp, start)
+ if err != nil </span><span class="cov0" title="0">{
+ return "", err
+ }</span>
+ <span class="cov0" title="0">if len(out.Choices) == 0 </span><span class="cov0" title="0">{
+ logging.Logf("llm/copilot ", "%sno choices returned duration=%s%s", logging.AnsiRed, time.Since(start), logging.AnsiBase)
+ return "", errors.New("copilot: no choices returned")
+ }</span>
+ <span class="cov0" title="0">content := out.Choices[0].Message.Content
+ logging.Logf("llm/copilot ", "success choice=0 finish=%s size=%d preview=%s%s%s duration=%s", out.Choices[0].FinishReason, len(content), logging.AnsiGreen, logging.PreviewForLog(content), logging.AnsiBase, time.Since(start))
+ return content, nil</span>
+}
+
+// Provider metadata
+func (c copilotClient) Name() string <span class="cov0" title="0">{ return "copilot" }</span>
+func (c copilotClient) DefaultModel() string <span class="cov0" title="0">{ return c.defaultModel }</span>
+
+// helpers
+func buildCopilotChatRequest(o Options, messages []Message, defaultTemp *float64) copilotChatRequest <span class="cov8" title="1">{
+ req := copilotChatRequest{Model: o.Model}
+ req.Messages = make([]copilotMessage, len(messages))
+ for i, m := range messages </span><span class="cov8" title="1">{
+ req.Messages[i] = copilotMessage{Role: m.Role, Content: m.Content}
+ }</span>
+ <span class="cov8" title="1">if o.Temperature != 0 </span><span class="cov0" title="0">{
+ req.Temperature = &amp;o.Temperature
+ }</span> else<span class="cov8" title="1"> if defaultTemp != nil </span><span class="cov8" title="1">{
+ t := *defaultTemp
+ req.Temperature = &amp;t
+ }</span>
+ <span class="cov8" title="1">if o.MaxTokens &gt; 0 </span><span class="cov8" title="1">{
+ req.MaxTokens = &amp;o.MaxTokens
+ }</span>
+ <span class="cov8" title="1">if len(o.Stop) &gt; 0 </span><span class="cov8" title="1">{
+ req.Stop = o.Stop
+ }</span>
+ <span class="cov8" title="1">return req</span>
+}
+
+func (c copilotClient) postJSON(ctx context.Context, url string, body []byte, headers map[string]string) (*http.Response, error) <span class="cov0" title="0">{
+ req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
+ if err != nil </span><span class="cov0" title="0">{ return nil, err }</span>
+ <span class="cov0" title="0">for k, v := range headers </span><span class="cov0" title="0">{ req.Header.Set(k, v) }</span>
+ <span class="cov0" title="0">return c.httpClient.Do(req)</span>
+}
+
+func handleCopilotNon2xx(resp *http.Response, start time.Time) error <span class="cov0" title="0">{
+ if resp.StatusCode &gt;= 200 &amp;&amp; resp.StatusCode &lt; 300 </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ <span class="cov0" title="0">var apiErr copilotChatResponse
+ _ = json.NewDecoder(resp.Body).Decode(&amp;apiErr)
+ if apiErr.Error != nil &amp;&amp; strings.TrimSpace(apiErr.Error.Message) != "" </span><span class="cov0" title="0">{
+ logging.Logf("llm/copilot ", "%sapi error status=%d type=%s msg=%s duration=%s%s", logging.AnsiRed, resp.StatusCode, apiErr.Error.Type, apiErr.Error.Message, time.Since(start), logging.AnsiBase)
+ return fmt.Errorf("copilot error: %s (status %d)", apiErr.Error.Message, resp.StatusCode)
+ }</span>
+ <span class="cov0" title="0">logging.Logf("llm/copilot ", "%shttp non-2xx status=%d duration=%s%s", logging.AnsiRed, resp.StatusCode, time.Since(start), logging.AnsiBase)
+ return fmt.Errorf("copilot http error: status %d", resp.StatusCode)</span>
+}
+
+func decodeCopilotChat(resp *http.Response, start time.Time) (copilotChatResponse, error) <span class="cov0" title="0">{
+ var out copilotChatResponse
+ if err := json.NewDecoder(resp.Body).Decode(&amp;out); err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/copilot ", "%sdecode error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return copilotChatResponse{}, err
+ }</span>
+ <span class="cov0" title="0">return out, nil</span>
+}
+
+// --- Copilot session token management ---
+
+type ghCopilotTokenResp struct {
+ Token string `json:"token"`
+}
+
+func (c *copilotClient) ensureSession(ctx context.Context) error <span class="cov0" title="0">{
+ // If token valid for &gt;60s, reuse
+ if c.sessionToken != "" &amp;&amp; time.Now().Add(60*time.Second).Before(c.tokenExpiry) </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ <span class="cov0" title="0">if strings.TrimSpace(c.apiKey) == "" </span><span class="cov0" title="0">{
+ return errors.New("missing Copilot API key")
+ }</span>
+ <span class="cov0" title="0">req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.github.com/copilot_internal/v2/token", nil)
+ if err != nil </span><span class="cov0" title="0">{ return err }</span>
+ <span class="cov0" title="0">req.Header.Set("Authorization", "Bearer "+c.apiKey)
+ req.Header.Set("Accept", "application/json")
+ req.Header.Set("User-Agent", "hexai/"+appver.Version)
+ resp, err := c.httpClient.Do(req)
+ if err != nil </span><span class="cov0" title="0">{ return err }</span>
+ <span class="cov0" title="0">defer resp.Body.Close()
+ if resp.StatusCode &lt; 200 || resp.StatusCode &gt;= 300 </span><span class="cov0" title="0">{
+ return fmt.Errorf("copilot token http error: %d", resp.StatusCode)
+ }</span>
+ <span class="cov0" title="0">var out ghCopilotTokenResp
+ if err := json.NewDecoder(resp.Body).Decode(&amp;out); err != nil </span><span class="cov0" title="0">{ return err }</span>
+ <span class="cov0" title="0">if strings.TrimSpace(out.Token) == "" </span><span class="cov0" title="0">{ return errors.New("empty copilot session token") }</span>
+ // Parse JWT exp
+ <span class="cov0" title="0">exp := parseJWTExp(out.Token)
+ if exp.IsZero() </span><span class="cov0" title="0">{ exp = time.Now().Add(10 * time.Minute) }</span>
+ <span class="cov0" title="0">c.sessionToken = out.Token
+ c.tokenExpiry = exp
+ return nil</span>
+}
+
+var jwtExpRe = regexp.MustCompile(`"exp"\s*:\s*([0-9]+)`) // fallback if we can't base64 decode
+
+func parseJWTExp(token string) time.Time <span class="cov0" title="0">{
+ parts := strings.Split(token, ".")
+ if len(parts) &lt; 2 </span><span class="cov0" title="0">{ return time.Time{} }</span>
+ <span class="cov0" title="0">b, err := base64.RawURLEncoding.DecodeString(parts[1])
+ if err != nil </span><span class="cov0" title="0">{
+ if m := jwtExpRe.FindStringSubmatch(token); len(m) == 2 </span><span class="cov0" title="0">{
+ if n, err2 := parseInt64(m[1]); err2 == nil </span><span class="cov0" title="0">{ return time.Unix(n, 0) }</span>
+ }
+ <span class="cov0" title="0">return time.Time{}</span>
+ }
+ <span class="cov0" title="0">var payload struct{ Exp int64 `json:"exp"` }
+ _ = json.Unmarshal(b, &amp;payload)
+ if payload.Exp == 0 </span><span class="cov0" title="0">{ return time.Time{} }</span>
+ <span class="cov0" title="0">return time.Unix(payload.Exp, 0)</span>
+}
+
+func parseInt64(s string) (int64, error) <span class="cov0" title="0">{ var n int64; _, err := fmt.Sscan(s, &amp;n); return n, err }</span>
+
+// --- Copilot headers ---
+
+func (c *copilotClient) headersChat() map[string]string <span class="cov0" title="0">{
+ _ = c.ensureSession(context.Background())
+ h := map[string]string{
+ "Content-Type": "application/json; charset=utf-8",
+ "Accept": "application/json",
+ "Authorization": "Bearer " + c.sessionToken,
+ "User-Agent": "GitHubCopilotChat/0.8.0",
+ "Editor-Plugin-Version": "copilot-chat/0.8.0",
+ "Editor-Version": "vscode/1.85.1",
+ "Openai-Intent": "conversation-panel",
+ "Openai-Organization": "github-copilot",
+ "VScode-MachineId": randHex(64),
+ "VScode-SessionId": randHex(8) + "-" + randHex(4) + "-" + randHex(4) + "-" + randHex(4) + "-" + randHex(12),
+ "X-Request-Id": randHex(8) + "-" + randHex(4) + "-" + randHex(4) + "-" + randHex(4) + "-" + randHex(12),
+ }
+ return h
+}</span>
+
+func (c *copilotClient) headersGhost() map[string]string <span class="cov0" title="0">{
+ _ = c.ensureSession(context.Background())
+ h := map[string]string{
+ "Content-Type": "application/json; charset=utf-8",
+ "Accept": "*/*",
+ "Authorization": "Bearer " + c.sessionToken,
+ "User-Agent": "GithubCopilot/1.155.0",
+ "Editor-Plugin-Version": "copilot/1.155.0",
+ "Editor-Version": "vscode/1.85.1",
+ "Openai-Intent": "copilot-ghost",
+ "Openai-Organization": "github-copilot",
+ "VScode-MachineId": randHex(64),
+ "VScode-SessionId": randHex(8) + "-" + randHex(4) + "-" + randHex(4) + "-" + randHex(4) + "-" + randHex(12),
+ "X-Request-Id": randHex(8) + "-" + randHex(4) + "-" + randHex(4) + "-" + randHex(4) + "-" + randHex(12),
+ }
+ return h
+}</span>
+
+func randHex(n int) string <span class="cov0" title="0">{
+ const hex = "0123456789abcdef"
+ b := make([]byte, n)
+ for i := range b </span><span class="cov0" title="0">{
+ b[i] = hex[int(time.Now().UnixNano()+int64(i))%len(hex)]
+ }</span>
+ <span class="cov0" title="0">return string(b)</span>
+}
+
+// --- Codex-style code completion ---
+
+// CodeCompletion implements CodeCompleter; returns up to n suggestions.
+func (c copilotClient) CodeCompletion(ctx context.Context, prompt string, suffix string, n int, language string, temperature float64) ([]string, error) <span class="cov0" title="0">{
+ if strings.TrimSpace(c.apiKey) == "" </span><span class="cov0" title="0">{ return nil, errors.New("missing Copilot API key") }</span>
+ <span class="cov0" title="0">if err := c.ensureSession(ctx); err != nil </span><span class="cov0" title="0">{ return nil, err }</span>
+ <span class="cov0" title="0">if n &lt;= 0 </span><span class="cov0" title="0">{ n = 1 }</span>
+ <span class="cov0" title="0">maxTokens := 500
+ body := map[string]any{
+ "extra": map[string]any{
+ "language": language,
+ "next_indent": 0,
+ "prompt_tokens": 500,
+ "suffix_tokens": 400,
+ "trim_by_indentation": true,
+ },
+ "max_tokens": maxTokens,
+ "n": n,
+ "nwo": "hexai",
+ "prompt": prompt,
+ "stop": []string{"\n\n"},
+ "stream": true,
+ "suffix": suffix,
+ "temperature": temperature,
+ "top_p": 1,
+ }
+ buf, _ := json.Marshal(body)
+ url := "https://copilot-proxy.githubusercontent.com/v1/engines/copilot-codex/completions"
+ resp, err := c.postJSON(ctx, url, buf, c.headersGhost())
+ if err != nil </span><span class="cov0" title="0">{ return nil, err }</span>
+ <span class="cov0" title="0">defer resp.Body.Close()
+ if resp.StatusCode &lt; 200 || resp.StatusCode &gt;= 300 </span><span class="cov0" title="0">{
+ return nil, fmt.Errorf("copilot codex http error: %d", resp.StatusCode)
+ }</span>
+ // Read all and parse lines that start with "data: " accumulating by index
+ <span class="cov0" title="0">raw, _ := io.ReadAll(resp.Body)
+ byIndex := make(map[int]string)
+ lines := strings.Split(string(raw), "\n")
+ for _, ln := range lines </span><span class="cov0" title="0">{
+ if !strings.HasPrefix(ln, "data: ") </span><span class="cov0" title="0">{ continue</span> }
+ <span class="cov0" title="0">var evt struct{ Choices []struct{ Index int `json:"index"`; Text string `json:"text"` } `json:"choices"` }
+ if err := json.Unmarshal([]byte(strings.TrimPrefix(ln, "data: ")), &amp;evt); err != nil </span><span class="cov0" title="0">{ continue</span> }
+ <span class="cov0" title="0">for _, ch := range evt.Choices </span><span class="cov0" title="0">{ byIndex[ch.Index] += ch.Text }</span>
+ }
+ <span class="cov0" title="0">out := make([]string, 0, len(byIndex))
+ for i := 0; i &lt; n; i++ </span><span class="cov0" title="0">{
+ if s, ok := byIndex[i]; ok &amp;&amp; strings.TrimSpace(s) != "" </span><span class="cov0" title="0">{ out = append(out, s) }</span>
+ }
+ <span class="cov0" title="0">return out, nil</span>
+}
+
+// newLineDataReader wraps a streaming body and exposes a JSON decoder that
+// decodes successive objects from lines prefixed by "data: ".
+// (no streaming decoder needed; we parse whole body lines)
+</pre>
+
+ <pre class="file" id="file6" style="display: none">// Summary: Ollama client against a local server; supports chat responses and streaming via /api/chat.
+package llm
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+ "time"
+
+ "codeberg.org/snonux/hexai/internal/logging"
+)
+
+// ollamaClient implements Client against a local Ollama server.
+type ollamaClient struct {
+ httpClient *http.Client
+ baseURL string
+ defaultModel string
+ chatLogger logging.ChatLogger
+ defaultTemperature *float64
+}
+
+type ollamaChatRequest struct {
+ Model string `json:"model"`
+ Messages []oaMessage `json:"messages"`
+ Stream bool `json:"stream"`
+ Options any `json:"options,omitempty"`
+}
+
+type ollamaChatResponse struct {
+ Message struct {
+ Role string `json:"role"`
+ Content string `json:"content"`
+ } `json:"message"`
+ Done bool `json:"done"`
+ Error string `json:"error,omitempty"`
+}
+
+// Constructor (kept among the first functions by convention)
+func newOllama(baseURL, model string, defaultTemp *float64) Client <span class="cov0" title="0">{
+ if strings.TrimSpace(baseURL) == "" </span><span class="cov0" title="0">{
+ baseURL = "http://localhost:11434"
+ }</span>
+ <span class="cov0" title="0">if strings.TrimSpace(model) == "" </span><span class="cov0" title="0">{
+ model = "qwen3-coder:30b-a3b-q4_K_M`"
+ }</span>
+ <span class="cov0" title="0">return ollamaClient{
+ httpClient: &amp;http.Client{Timeout: 30 * time.Second},
+ baseURL: strings.TrimRight(baseURL, "/"),
+ defaultModel: model,
+ chatLogger: logging.NewChatLogger("ollama"),
+ defaultTemperature: defaultTemp,
+ }</span>
+}
+
+func (c ollamaClient) Chat(ctx context.Context, messages []Message, opts ...RequestOption) (string, error) <span class="cov0" title="0">{
+ o := Options{Model: c.defaultModel}
+ for _, opt := range opts </span><span class="cov0" title="0">{
+ opt(&amp;o)
+ }</span>
+ <span class="cov0" title="0">if o.Model == "" </span><span class="cov0" title="0">{
+ o.Model = c.defaultModel
+ }</span>
+
+ <span class="cov0" title="0">start := time.Now()
+ c.logStart(false, o, messages)
+ req := buildOllamaRequest(o, messages, c.defaultTemperature, false)
+ body, err := json.Marshal(req)
+ if err != nil </span><span class="cov0" title="0">{
+ return "", err
+ }</span>
+
+ <span class="cov0" title="0">endpoint := c.baseURL + "/api/chat"
+ logging.Logf("llm/ollama ", "POST %s", endpoint)
+ resp, err := c.doJSON(ctx, endpoint, body)
+ if err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/ollama ", "%shttp error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return "", err
+ }</span>
+ <span class="cov0" title="0">defer resp.Body.Close()
+ if err := handleOllamaNon2xx(resp, start); err != nil </span><span class="cov0" title="0">{
+ return "", err
+ }</span>
+
+ <span class="cov0" title="0">var out ollamaChatResponse
+ if err := json.NewDecoder(resp.Body).Decode(&amp;out); err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/ollama ", "%sdecode error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return "", err
+ }</span>
+ <span class="cov0" title="0">if strings.TrimSpace(out.Message.Content) == "" </span><span class="cov0" title="0">{
+ logging.Logf("llm/ollama ", "%sempty content returned duration=%s%s", logging.AnsiRed, time.Since(start), logging.AnsiBase)
+ return "", errors.New("ollama: empty content")
+ }</span>
+ <span class="cov0" title="0">content := out.Message.Content
+ logging.Logf("llm/ollama ", "success size=%d preview=%s%s%s duration=%s", len(content), logging.AnsiGreen, logging.PreviewForLog(content), logging.AnsiBase, time.Since(start))
+ return content, nil</span>
+}
+
+// Provider metadata
+func (c ollamaClient) Name() string <span class="cov0" title="0">{ return "ollama" }</span>
+func (c ollamaClient) DefaultModel() string <span class="cov0" title="0">{ return c.defaultModel }</span>
+
+// Streaming support (optional)
+func (c ollamaClient) ChatStream(ctx context.Context, messages []Message, onDelta func(string), opts ...RequestOption) error <span class="cov0" title="0">{
+ o := Options{Model: c.defaultModel}
+ for _, opt := range opts </span><span class="cov0" title="0">{
+ opt(&amp;o)
+ }</span>
+ <span class="cov0" title="0">if o.Model == "" </span><span class="cov0" title="0">{
+ o.Model = c.defaultModel
+ }</span>
+
+ <span class="cov0" title="0">start := time.Now()
+ c.logStart(true, o, messages)
+ req := buildOllamaRequest(o, messages, c.defaultTemperature, true)
+ body, err := json.Marshal(req)
+ if err != nil </span><span class="cov0" title="0">{
+ return err
+ }</span>
+
+ <span class="cov0" title="0">endpoint := c.baseURL + "/api/chat"
+ logging.Logf("llm/ollama ", "POST %s (stream)", endpoint)
+ resp, err := c.doJSON(ctx, endpoint, body)
+ if err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/ollama ", "%shttp error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return err
+ }</span>
+ <span class="cov0" title="0">defer resp.Body.Close()
+ if err := handleOllamaNon2xx(resp, start); err != nil </span><span class="cov0" title="0">{
+ return err
+ }</span>
+
+ <span class="cov0" title="0">dec := json.NewDecoder(resp.Body)
+ for </span><span class="cov0" title="0">{
+ var ev ollamaChatResponse
+ if err := dec.Decode(&amp;ev); err != nil </span><span class="cov0" title="0">{
+ if errors.Is(err, io.EOF) </span><span class="cov0" title="0">{
+ break</span>
+ }
+ <span class="cov0" title="0">logging.Logf("llm/ollama ", "%sdecode stream error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return err</span>
+ }
+ <span class="cov0" title="0">if strings.TrimSpace(ev.Error) != "" </span><span class="cov0" title="0">{
+ logging.Logf("llm/ollama ", "%sstream event error: %s%s", logging.AnsiRed, ev.Error, logging.AnsiBase)
+ return fmt.Errorf("ollama stream error: %s", ev.Error)
+ }</span>
+ <span class="cov0" title="0">if s := ev.Message.Content; strings.TrimSpace(s) != "" </span><span class="cov0" title="0">{
+ onDelta(s)
+ }</span>
+ <span class="cov0" title="0">if ev.Done </span><span class="cov0" title="0">{
+ break</span>
+ }
+ }
+ <span class="cov0" title="0">logging.Logf("llm/ollama ", "stream end duration=%s", time.Since(start))
+ return nil</span>
+}
+
+// helpers to keep methods small
+func (c ollamaClient) logStart(stream bool, o Options, messages []Message) <span class="cov0" title="0">{
+ logMessages := make([]struct{ Role, Content string }, len(messages))
+ for i, m := range messages </span><span class="cov0" title="0">{
+ logMessages[i] = struct{ Role, Content string }{m.Role, m.Content}
+ }</span>
+ <span class="cov0" title="0">c.chatLogger.LogStart(stream, o.Model, o.Temperature, o.MaxTokens, o.Stop, logMessages)</span>
+}
+
+func buildOllamaRequest(o Options, messages []Message, defaultTemp *float64, stream bool) ollamaChatRequest <span class="cov10" title="2">{
+ req := ollamaChatRequest{Model: o.Model, Stream: stream}
+ req.Messages = make([]oaMessage, len(messages))
+ for i, m := range messages </span><span class="cov10" title="2">{
+ req.Messages[i] = oaMessage{Role: m.Role, Content: m.Content}
+ }</span>
+ <span class="cov10" title="2">optsMap := map[string]any{}
+ if o.Temperature != 0 </span><span class="cov0" title="0">{
+ optsMap["temperature"] = o.Temperature
+ }</span> else<span class="cov10" title="2"> if defaultTemp != nil </span><span class="cov10" title="2">{
+ optsMap["temperature"] = *defaultTemp
+ }</span>
+ <span class="cov10" title="2">if o.MaxTokens &gt; 0 </span><span class="cov10" title="2">{
+ optsMap["num_predict"] = o.MaxTokens
+ }</span>
+ <span class="cov10" title="2">if len(o.Stop) &gt; 0 </span><span class="cov10" title="2">{
+ optsMap["stop"] = o.Stop
+ }</span>
+ <span class="cov10" title="2">if len(optsMap) &gt; 0 </span><span class="cov10" title="2">{
+ req.Options = optsMap
+ }</span>
+ <span class="cov10" title="2">return req</span>
+}
+
+func (c ollamaClient) doJSON(ctx context.Context, url string, body []byte) (*http.Response, error) <span class="cov0" title="0">{
+ req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
+ if err != nil </span><span class="cov0" title="0">{
+ return nil, err
+ }</span>
+ <span class="cov0" title="0">req.Header.Set("Content-Type", "application/json")
+ return c.httpClient.Do(req)</span>
+}
+
+func handleOllamaNon2xx(resp *http.Response, start time.Time) error <span class="cov0" title="0">{
+ if resp.StatusCode &gt;= 200 &amp;&amp; resp.StatusCode &lt; 300 </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ <span class="cov0" title="0">var apiErr ollamaChatResponse
+ _ = json.NewDecoder(resp.Body).Decode(&amp;apiErr)
+ if strings.TrimSpace(apiErr.Error) != "" </span><span class="cov0" title="0">{
+ logging.Logf("llm/ollama ", "%sapi error status=%d msg=%s duration=%s%s", logging.AnsiRed, resp.StatusCode, apiErr.Error, time.Since(start), logging.AnsiBase)
+ return fmt.Errorf("ollama error: %s (status %d)", apiErr.Error, resp.StatusCode)
+ }</span>
+ <span class="cov0" title="0">logging.Logf("llm/ollama ", "%shttp non-2xx status=%d duration=%s%s", logging.AnsiRed, resp.StatusCode, time.Since(start), logging.AnsiBase)
+ return fmt.Errorf("ollama http error: status %d", resp.StatusCode)</span>
+}
+</pre>
+
+ <pre class="file" id="file7" style="display: none">// Summary: OpenAI client implementation for chat completions with optional streaming and detailed logging.
+package llm
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "strings"
+ "time"
+
+ "codeberg.org/snonux/hexai/internal/logging"
+)
+
+// openAIClient implements Client against OpenAI's Chat Completions API.
+type openAIClient struct {
+ httpClient *http.Client
+ apiKey string
+ baseURL string
+ defaultModel string
+ chatLogger logging.ChatLogger
+ defaultTemperature *float64
+}
+
+type oaChatRequest struct {
+ Model string `json:"model"`
+ Messages []oaMessage `json:"messages"`
+ Temperature *float64 `json:"temperature,omitempty"`
+ MaxTokens *int `json:"max_tokens,omitempty"`
+ Stop []string `json:"stop,omitempty"`
+ Stream bool `json:"stream,omitempty"`
+}
+
+type oaMessage struct {
+ Role string `json:"role"`
+ Content string `json:"content"`
+}
+
+type oaChatResponse struct {
+ Choices []struct {
+ Index int `json:"index"`
+ Message struct {
+ Role string `json:"role"`
+ Content string `json:"content"`
+ } `json:"message"`
+ FinishReason string `json:"finish_reason"`
+ } `json:"choices"`
+ Error *struct {
+ Message string `json:"message"`
+ Type string `json:"type"`
+ Param any `json:"param"`
+ Code any `json:"code"`
+ } `json:"error,omitempty"`
+}
+
+// Streaming response chunk type (SSE)
+type oaStreamChunk struct {
+ Choices []struct {
+ Delta struct {
+ Content string `json:"content"`
+ } `json:"delta"`
+ FinishReason string `json:"finish_reason"`
+ } `json:"choices"`
+ Error *struct {
+ Message string `json:"message"`
+ Type string `json:"type"`
+ Param any `json:"param"`
+ Code any `json:"code"`
+ } `json:"error,omitempty"`
+}
+
+// Constructor (kept among the first functions by convention)
+// newOpenAI constructs an OpenAI client using explicit configuration values.
+// The apiKey may be empty; calls will fail until a valid key is supplied.
+func newOpenAI(baseURL, model, apiKey string, defaultTemp *float64) Client <span class="cov10" title="5">{
+ if strings.TrimSpace(baseURL) == "" </span><span class="cov10" title="5">{
+ baseURL = "https://api.openai.com/v1"
+ }</span>
+ <span class="cov10" title="5">if strings.TrimSpace(model) == "" </span><span class="cov10" title="5">{
+ model = "gpt-4.1"
+ }</span>
+ <span class="cov10" title="5">return openAIClient{
+ httpClient: &amp;http.Client{Timeout: 30 * time.Second},
+ apiKey: apiKey,
+ baseURL: baseURL,
+ defaultModel: model,
+ chatLogger: logging.NewChatLogger("openai"),
+ defaultTemperature: defaultTemp,
+ }</span>
+}
+
+func (c openAIClient) Chat(ctx context.Context, messages []Message, opts ...RequestOption) (string, error) <span class="cov0" title="0">{
+ if c.apiKey == "" </span><span class="cov0" title="0">{
+ return nilStringErr("missing OpenAI API key")
+ }</span>
+ <span class="cov0" title="0">o := Options{Model: c.defaultModel}
+ for _, opt := range opts </span><span class="cov0" title="0">{
+ opt(&amp;o)
+ }</span>
+ <span class="cov0" title="0">if o.Model == "" </span><span class="cov0" title="0">{
+ o.Model = c.defaultModel
+ }</span>
+ <span class="cov0" title="0">start := time.Now()
+ c.logStart(false, o, messages)
+ req := buildOAChatRequest(o, messages, c.defaultTemperature, false)
+ body, err := json.Marshal(req)
+ if err != nil </span><span class="cov0" title="0">{
+ c.logf("marshal error: %v", err)
+ return "", err
+ }</span>
+ <span class="cov0" title="0">endpoint := c.baseURL + "/chat/completions"
+ logging.Logf("llm/openai ", "POST %s", endpoint)
+ resp, err := c.doJSON(ctx, endpoint, body, map[string]string{
+ "Authorization": "Bearer " + c.apiKey,
+ })
+ if err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/openai ", "%shttp error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return "", err
+ }</span>
+ <span class="cov0" title="0">defer resp.Body.Close()
+ if err := handleOpenAINon2xx(resp, start); err != nil </span><span class="cov0" title="0">{
+ return "", err
+ }</span>
+ <span class="cov0" title="0">out, err := decodeOpenAIChat(resp, start)
+ if err != nil </span><span class="cov0" title="0">{
+ return "", err
+ }</span>
+ <span class="cov0" title="0">if len(out.Choices) == 0 </span><span class="cov0" title="0">{
+ logging.Logf("llm/openai ", "%sno choices returned duration=%s%s", logging.AnsiRed, time.Since(start), logging.AnsiBase)
+ return "", errors.New("openai: no choices returned")
+ }</span>
+ <span class="cov0" title="0">content := out.Choices[0].Message.Content
+ logging.Logf("llm/openai ", "success choice=0 finish=%s size=%d preview=%s%s%s duration=%s", out.Choices[0].FinishReason, len(content), logging.AnsiGreen, logging.PreviewForLog(content), logging.AnsiBase, time.Since(start))
+ return content, nil</span>
+}
+
+// Provider metadata
+func (c openAIClient) Name() string <span class="cov10" title="5">{ return "openai" }</span>
+func (c openAIClient) DefaultModel() string <span class="cov10" title="5">{ return c.defaultModel }</span>
+
+// Streaming support (optional)
+
+func (c openAIClient) ChatStream(ctx context.Context, messages []Message, onDelta func(string), opts ...RequestOption) error <span class="cov0" title="0">{
+ if c.apiKey == "" </span><span class="cov0" title="0">{
+ return errors.New("missing OpenAI API key")
+ }</span>
+ <span class="cov0" title="0">o := Options{Model: c.defaultModel}
+ for _, opt := range opts </span><span class="cov0" title="0">{
+ opt(&amp;o)
+ }</span>
+ <span class="cov0" title="0">if o.Model == "" </span><span class="cov0" title="0">{
+ o.Model = c.defaultModel
+ }</span>
+ <span class="cov0" title="0">start := time.Now()
+ c.logStart(true, o, messages)
+ req := buildOAChatRequest(o, messages, c.defaultTemperature, true)
+ body, err := json.Marshal(req)
+ if err != nil </span><span class="cov0" title="0">{
+ c.logf("marshal error: %v", err)
+ return err
+ }</span>
+ <span class="cov0" title="0">endpoint := c.baseURL + "/chat/completions"
+ logging.Logf("llm/openai ", "POST %s (stream)", endpoint)
+ resp, err := c.doJSONWithAccept(ctx, endpoint, body, map[string]string{
+ "Authorization": "Bearer " + c.apiKey,
+ }, "text/event-stream")
+ if err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/openai ", "%shttp error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return err
+ }</span>
+ <span class="cov0" title="0">defer resp.Body.Close()
+ if err := handleOpenAINon2xx(resp, start); err != nil </span><span class="cov0" title="0">{
+ return err
+ }</span>
+
+ <span class="cov0" title="0">if err := parseOpenAIStream(resp, start, onDelta); err != nil </span><span class="cov0" title="0">{
+ return err
+ }</span>
+ <span class="cov0" title="0">logging.Logf("llm/openai ", "stream end duration=%s", time.Since(start))
+ return nil</span>
+}
+
+// Private helpers
+func (c openAIClient) logf(format string, args ...any) <span class="cov0" title="0">{ logging.Logf("llm/openai ", format, args...) }</span>
+
+// helpers extracted to keep methods small
+func (c openAIClient) logStart(stream bool, o Options, messages []Message) <span class="cov0" title="0">{
+ logMessages := make([]struct{ Role, Content string }, len(messages))
+ for i, m := range messages </span><span class="cov0" title="0">{
+ logMessages[i] = struct{ Role, Content string }{m.Role, m.Content}
+ }</span>
+ <span class="cov0" title="0">c.chatLogger.LogStart(stream, o.Model, o.Temperature, o.MaxTokens, o.Stop, logMessages)</span>
+}
+
+func buildOAChatRequest(o Options, messages []Message, defaultTemp *float64, stream bool) oaChatRequest <span class="cov4" title="2">{
+ req := oaChatRequest{Model: o.Model, Stream: stream}
+ req.Messages = make([]oaMessage, len(messages))
+ for i, m := range messages </span><span class="cov4" title="2">{
+ req.Messages[i] = oaMessage{Role: m.Role, Content: m.Content}
+ }</span>
+ <span class="cov4" title="2">if o.Temperature != 0 </span><span class="cov0" title="0">{
+ req.Temperature = &amp;o.Temperature
+ }</span> else<span class="cov4" title="2"> if defaultTemp != nil </span><span class="cov4" title="2">{
+ t := *defaultTemp
+ req.Temperature = &amp;t
+ }</span>
+ <span class="cov4" title="2">if o.MaxTokens &gt; 0 </span><span class="cov4" title="2">{
+ req.MaxTokens = &amp;o.MaxTokens
+ }</span>
+ <span class="cov4" title="2">if len(o.Stop) &gt; 0 </span><span class="cov4" title="2">{
+ req.Stop = o.Stop
+ }</span>
+ <span class="cov4" title="2">return req</span>
+}
+
+func (c openAIClient) doJSON(ctx context.Context, url string, body []byte, headers map[string]string) (*http.Response, error) <span class="cov0" title="0">{
+ req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
+ if err != nil </span><span class="cov0" title="0">{
+ return nil, err
+ }</span>
+ <span class="cov0" title="0">req.Header.Set("Content-Type", "application/json")
+ for k, v := range headers </span><span class="cov0" title="0">{
+ req.Header.Set(k, v)
+ }</span>
+ <span class="cov0" title="0">return c.httpClient.Do(req)</span>
+}
+
+func (c openAIClient) doJSONWithAccept(ctx context.Context, url string, body []byte, headers map[string]string, accept string) (*http.Response, error) <span class="cov0" title="0">{
+ req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
+ if err != nil </span><span class="cov0" title="0">{
+ return nil, err
+ }</span>
+ <span class="cov0" title="0">req.Header.Set("Content-Type", "application/json")
+ req.Header.Set("Accept", accept)
+ for k, v := range headers </span><span class="cov0" title="0">{
+ req.Header.Set(k, v)
+ }</span>
+ <span class="cov0" title="0">return c.httpClient.Do(req)</span>
+}
+
+func handleOpenAINon2xx(resp *http.Response, start time.Time) error <span class="cov1" title="1">{
+ if resp.StatusCode &gt;= 200 &amp;&amp; resp.StatusCode &lt; 300 </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ <span class="cov1" title="1">var apiErr oaChatResponse
+ _ = json.NewDecoder(resp.Body).Decode(&amp;apiErr)
+ if apiErr.Error != nil &amp;&amp; apiErr.Error.Message != "" </span><span class="cov1" title="1">{
+ logging.Logf("llm/openai ", "%sapi error status=%d type=%s msg=%s duration=%s%s", logging.AnsiRed, resp.StatusCode, apiErr.Error.Type, apiErr.Error.Message, time.Since(start), logging.AnsiBase)
+ return fmt.Errorf("openai error: %s (status %d)", apiErr.Error.Message, resp.StatusCode)
+ }</span>
+ <span class="cov0" title="0">logging.Logf("llm/openai ", "%shttp non-2xx status=%d duration=%s%s", logging.AnsiRed, resp.StatusCode, time.Since(start), logging.AnsiBase)
+ return fmt.Errorf("openai http error: status %d", resp.StatusCode)</span>
+}
+
+func decodeOpenAIChat(resp *http.Response, start time.Time) (oaChatResponse, error) <span class="cov0" title="0">{
+ var out oaChatResponse
+ if err := json.NewDecoder(resp.Body).Decode(&amp;out); err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/openai ", "%sdecode error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return oaChatResponse{}, err
+ }</span>
+ <span class="cov0" title="0">return out, nil</span>
+}
+
+func parseOpenAIStream(resp *http.Response, start time.Time, onDelta func(string)) error <span class="cov1" title="1">{
+ // Parse SSE: lines starting with "data: " containing JSON or [DONE]
+ scanner := bufio.NewScanner(resp.Body)
+ const maxBuf = 1024 * 1024
+ buf := make([]byte, 0, 64*1024)
+ scanner.Buffer(buf, maxBuf)
+ for scanner.Scan() </span><span class="cov7" title="3">{
+ line := scanner.Text()
+ if !strings.HasPrefix(line, "data: ") </span><span class="cov1" title="1">{
+ continue</span>
+ }
+ <span class="cov4" title="2">payload := strings.TrimPrefix(line, "data: ")
+ if strings.TrimSpace(payload) == "[DONE]" </span><span class="cov1" title="1">{
+ break</span>
+ }
+ <span class="cov1" title="1">var chunk oaStreamChunk
+ if err := json.Unmarshal([]byte(payload), &amp;chunk); err != nil </span><span class="cov0" title="0">{
+ continue</span>
+ }
+ <span class="cov1" title="1">if chunk.Error != nil &amp;&amp; chunk.Error.Message != "" </span><span class="cov0" title="0">{
+ logging.Logf("llm/openai ", "%sstream error: %s%s", logging.AnsiRed, chunk.Error.Message, logging.AnsiBase)
+ return fmt.Errorf("openai stream error: %s", chunk.Error.Message)
+ }</span>
+ <span class="cov1" title="1">for _, ch := range chunk.Choices </span><span class="cov1" title="1">{
+ if ch.Delta.Content != "" </span><span class="cov1" title="1">{
+ onDelta(ch.Delta.Content)
+ }</span>
+ }
+ }
+ <span class="cov1" title="1">if err := scanner.Err(); err != nil </span><span class="cov0" title="0">{
+ logging.Logf("llm/openai ", "%sstream read error after %s: %v%s", logging.AnsiRed, time.Since(start), err, logging.AnsiBase)
+ return err
+ }</span>
+ <span class="cov1" title="1">return nil</span>
+}
+</pre>
+
+ <pre class="file" id="file8" style="display: none">// Summary: LLM provider interfaces, request options, configuration, and factory to build a client from config.
+package llm
+
+import (
+ "context"
+ "errors"
+ "strings"
+)
+
+// Message represents a chat-style prompt message.
+type Message struct {
+ Role string
+ Content string
+}
+
+// Client is a minimal LLM provider interface.
+// Future providers (Ollama, etc.) should implement this.
+type Client interface {
+ // Chat sends chat messages and returns the assistant text.
+ Chat(ctx context.Context, messages []Message, opts ...RequestOption) (string, error)
+ // Name returns the provider's short name (e.g., "openai", "ollama").
+ Name() string
+ // DefaultModel returns the configured default model name.
+ DefaultModel() string
+}
+
+// Streamer is an optional interface that providers may implement to support
+// token-by-token streaming responses. Callers can type-assert to Streamer and
+// fall back to Client.Chat when not implemented.
+type Streamer interface {
+ // ChatStream sends chat messages and invokes onDelta with incremental text
+ // chunks as they are produced by the model. Implementations should call
+ // onDelta with empty strings sparingly (prefer only non-empty chunks).
+ ChatStream(ctx context.Context, messages []Message, onDelta func(string), opts ...RequestOption) error
+}
+
+// CodeCompleter is an optional interface for providers that support a
+// prompt/suffix code-completion API (e.g., Copilot Codex endpoint). Clients
+// can type-assert to this and prefer it over chat when available.
+type CodeCompleter interface {
+ // CodeCompletion requests up to n suggestions given a left-hand prompt and
+ // right-hand suffix around the cursor. Language is advisory and may be
+ // ignored. Temperature applies when provider supports it.
+ CodeCompletion(ctx context.Context, prompt string, suffix string, n int, language string, temperature float64) ([]string, error)
+}
+
+// Options for a request. Providers may ignore unsupported fields.
+type Options struct {
+ Model string
+ Temperature float64
+ MaxTokens int
+ Stop []string
+}
+
+// RequestOption mutates Options.
+type RequestOption func(*Options)
+
+func WithModel(model string) RequestOption <span class="cov0" title="0">{ return func(o *Options) </span><span class="cov0" title="0">{ o.Model = model }</span> }
+func WithTemperature(t float64) RequestOption <span class="cov0" title="0">{ return func(o *Options) </span><span class="cov0" title="0">{ o.Temperature = t }</span> }
+func WithMaxTokens(n int) RequestOption <span class="cov10" title="9">{ return func(o *Options) </span><span class="cov0" title="0">{ o.MaxTokens = n }</span> }
+func WithStop(stop ...string) RequestOption <span class="cov0" title="0">{
+ return func(o *Options) </span><span class="cov0" title="0">{ o.Stop = append([]string{}, stop...) }</span>
+}
+
+// Config defines provider configuration read from the Hexai config file.
+type Config struct {
+ Provider string
+ // OpenAI options
+ OpenAIBaseURL string
+ OpenAIModel string
+ OpenAITemperature *float64
+ // Ollama options
+ OllamaBaseURL string
+ OllamaModel string
+ OllamaTemperature *float64
+ // Copilot options
+ CopilotBaseURL string
+ CopilotModel string
+ CopilotTemperature *float64
+}
+
+// NewFromConfig creates an LLM client using only the supplied configuration.
+// The OpenAI API key is supplied separately and may be read from the environment
+// by the caller; other environment-based configuration is not used.
+func NewFromConfig(cfg Config, openAIAPIKey, copilotAPIKey string) (Client, error) <span class="cov8" title="6">{
+ p := strings.ToLower(strings.TrimSpace(cfg.Provider))
+ if p == "" </span><span class="cov8" title="6">{
+ p = "openai"
+ }</span>
+ <span class="cov8" title="6">switch p </span>{
+ case "openai":<span class="cov8" title="6">
+ if strings.TrimSpace(openAIAPIKey) == "" </span><span class="cov1" title="1">{
+ return nil, errors.New("missing OPENAI_API_KEY for provider openai")
+ }</span>
+ // Set coding-friendly default temperature if none provided
+ <span class="cov7" title="5">if cfg.OpenAITemperature == nil </span><span class="cov5" title="3">{
+ t := 0.2
+ cfg.OpenAITemperature = &amp;t
+ }</span>
+ <span class="cov7" title="5">return newOpenAI(cfg.OpenAIBaseURL, cfg.OpenAIModel, openAIAPIKey, cfg.OpenAITemperature), nil</span>
+ case "ollama":<span class="cov0" title="0">
+ if cfg.OllamaTemperature == nil </span><span class="cov0" title="0">{
+ t := 0.2
+ cfg.OllamaTemperature = &amp;t
+ }</span>
+ <span class="cov0" title="0">return newOllama(cfg.OllamaBaseURL, cfg.OllamaModel, cfg.OllamaTemperature), nil</span>
+ case "copilot":<span class="cov0" title="0">
+ if strings.TrimSpace(copilotAPIKey) == "" </span><span class="cov0" title="0">{
+ return nil, errors.New("missing COPILOT_API_KEY for provider copilot")
+ }</span>
+ <span class="cov0" title="0">if cfg.CopilotTemperature == nil </span><span class="cov0" title="0">{
+ t := 0.2
+ cfg.CopilotTemperature = &amp;t
+ }</span>
+ <span class="cov0" title="0">return newCopilot(cfg.CopilotBaseURL, cfg.CopilotModel, copilotAPIKey, cfg.CopilotTemperature), nil</span>
+ default:<span class="cov0" title="0">
+ return nil, errors.New("unknown LLM provider: " + p)</span>
+ }
+}
+</pre>
+
+ <pre class="file" id="file9" style="display: none">package llm
+
+import "errors"
+
+// small helper to keep return type consistent
+func nilStringErr(msg string) (string, error) <span class="cov0" title="0">{ return "", errors.New(msg) }</span>
+</pre>
+
+ <pre class="file" id="file10" style="display: none">package logging
+
+// ChatLogger provides a structured way to log chat interactions.
+type ChatLogger struct {
+ Provider string
+}
+
+// NewChatLogger creates a new ChatLogger for a given provider.
+func NewChatLogger(provider string) ChatLogger <span class="cov10" title="5">{
+ return ChatLogger{Provider: provider}
+}</span>
+
+// LogStart logs the beginning of a chat or stream interaction.
+func (cl ChatLogger) LogStart(stream bool, model string, temp float64, maxTokens int, stop []string, messages []struct {
+ Role string
+ Content string
+}) <span class="cov0" title="0">{
+ chatOrStream := "chat"
+ if stream </span><span class="cov0" title="0">{
+ chatOrStream = "stream"
+ }</span>
+ <span class="cov0" title="0">Logf("llm/"+cl.Provider+" ", "%s start model=%s temp=%.2f max_tokens=%d stop=%d messages=%d",
+ chatOrStream, model, temp, maxTokens, len(stop), len(messages))
+ for i, m := range messages </span><span class="cov0" title="0">{
+ Logf("llm/"+cl.Provider+" ", "msg[%d] role=%s size=%d preview=%s%s%s",
+ i, m.Role, len(m.Content), AnsiCyan, PreviewForLog(m.Content), AnsiBase)
+ }</span>
+}
+</pre>
+
+ <pre class="file" id="file11" style="display: none">// Summary: ANSI-styled logging utilities with a bound standard logger and configurable preview truncation.
+package logging
+
+import (
+ "fmt"
+ "log"
+)
+
+// ANSI color utilities shared across Hexai.
+const (
+ AnsiBgBlack = "\x1b[40m"
+ AnsiGrey = "\x1b[90m"
+ AnsiCyan = "\x1b[36m"
+ AnsiGreen = "\x1b[32m"
+ AnsiYellow = "\x1b[33m"
+ AnsiRed = "\x1b[31m"
+ AnsiReset = "\x1b[0m"
+)
+
+// AnsiBase is the default style: black background + grey foreground.
+const AnsiBase = AnsiBgBlack + AnsiGrey
+
+// singleton logger used across the codebase
+var std *log.Logger
+
+// Bind sets the underlying standard logger to use for Logf.
+func Bind(l *log.Logger) <span class="cov2" title="2">{ std = l }</span>
+
+// Logf prints a formatted message with a module prefix and base ANSI style.
+func Logf(prefix, format string, args ...any) <span class="cov10" title="33">{
+ if std == nil </span><span class="cov6" title="7">{
+ return
+ }</span>
+ <span class="cov9" title="26">msg := fmt.Sprintf(format, args...)
+ std.Print(AnsiBase + prefix + msg + AnsiReset)</span>
+}
+
+// Logging configuration for previews (shared)
+var logPreviewLimit int // 0 means unlimited
+
+// SetLogPreviewLimit sets the maximum number of characters to log for
+// request/response previews. Set to 0 for unlimited.
+func SetLogPreviewLimit(n int) <span class="cov6" title="7">{ logPreviewLimit = n }</span>
+
+// PreviewForLog returns the string truncated to the configured preview limit.
+func PreviewForLog(s string) string <span class="cov2" title="2">{
+ if logPreviewLimit &gt; 0 </span><span class="cov1" title="1">{
+ if len(s) &lt;= logPreviewLimit </span><span class="cov0" title="0">{
+ return s
+ }</span>
+ <span class="cov1" title="1">return s[:logPreviewLimit] + "…"</span>
+ }
+ <span class="cov1" title="1">return s</span>
+}
+</pre>
+
+ <pre class="file" id="file12" style="display: none">// Summary: Builds additional context snippets based on configured mode and truncates text by token heuristic.
+package lsp
+
+import (
+ "codeberg.org/snonux/hexai/internal/logging"
+ "strings"
+)
+
+// buildAdditionalContext builds extra context messages based on the configured mode.
+// Modes:
+// - minimal: no extra context
+// - window: include a window of lines around the cursor
+// - file-on-new-func: include full file only when defining a new function
+// - always-full: always include the full file
+func (s *Server) buildAdditionalContext(newFunc bool, uri string, pos Position) (string, bool) <span class="cov10" title="4">{
+ mode := s.contextMode
+ switch mode </span>{
+ case "minimal":<span class="cov1" title="1">
+ return "", false</span>
+ case "window":<span class="cov0" title="0">
+ return s.windowContext(uri, pos), true</span>
+ case "file-on-new-func":<span class="cov5" title="2">
+ if newFunc </span><span class="cov1" title="1">{
+ return s.fullFileContext(uri), true
+ }</span>
+ <span class="cov1" title="1">return "", false</span>
+ case "always-full":<span class="cov1" title="1">
+ return s.fullFileContext(uri), true</span>
+ default:<span class="cov0" title="0">
+ // fallback to minimal if unknown
+ return "", false</span>
+ }
+}
+
+func (s *Server) windowContext(uri string, pos Position) string <span class="cov1" title="1">{
+ d := s.getDocument(uri)
+ if d == nil || len(d.lines) == 0 </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "context: window requested but document not open; skipping uri=%s", uri)
+ return ""
+ }</span>
+ <span class="cov1" title="1">n := len(d.lines)
+ half := s.windowLines / 2
+ start := pos.Line - half
+ if start &lt; 0 </span><span class="cov0" title="0">{
+ start = 0
+ }</span>
+ <span class="cov1" title="1">end := pos.Line + half + 1
+ if end &gt; n </span><span class="cov0" title="0">{
+ end = n
+ }</span>
+ <span class="cov1" title="1">text := strings.Join(d.lines[start:end], "\n")
+ return truncateToApproxTokens(text, s.maxContextTokens)</span>
+}
+
+func (s *Server) fullFileContext(uri string) string <span class="cov5" title="2">{
+ d := s.getDocument(uri)
+ if d == nil </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "context: full-file requested but document not open; skipping uri=%s", uri)
+ return ""
+ }</span>
+ <span class="cov5" title="2">return truncateToApproxTokens(d.text, s.maxContextTokens)</span>
+}
+
+// truncateToApproxTokens naively truncates the input to fit approx N tokens.
+// Uses 4 chars/token heuristic for speed and determinism.
+func truncateToApproxTokens(text string, maxTokens int) string <span class="cov10" title="4">{
+ if maxTokens &lt;= 0 </span><span class="cov0" title="0">{
+ return ""
+ }</span>
+ <span class="cov10" title="4">maxChars := maxTokens * 4
+ if len(text) &lt;= maxChars </span><span class="cov8" title="3">{
+ return text
+ }</span>
+ // try to cut on a line boundary near maxChars
+ <span class="cov1" title="1">cut := maxChars
+ if cut &gt; len(text) </span><span class="cov0" title="0">{
+ cut = len(text)
+ }</span>
+ <span class="cov1" title="1">if i := strings.LastIndex(text[:cut], "\n"); i &gt; 0 </span><span class="cov0" title="0">{
+ cut = i
+ }</span>
+ <span class="cov1" title="1">return text[:cut]</span>
+}
+</pre>
+
+ <pre class="file" id="file13" style="display: none">// Summary: In-memory document model for the LSP; tracks text, lines, and applies edits.
+package lsp
+
+import (
+ "strings"
+ "time"
+)
+
+type document struct {
+ uri string
+ text string
+ lines []string
+}
+
+func (s *Server) setDocument(uri, text string) <span class="cov5" title="4">{
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ s.docs[uri] = &amp;document{uri: uri, text: text, lines: splitLines(text)}
+}</span>
+
+func (s *Server) deleteDocument(uri string) <span class="cov0" title="0">{
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ delete(s.docs, uri)
+}</span>
+
+func (s *Server) markActivity() <span class="cov1" title="1">{
+ s.mu.Lock()
+ s.lastInput = time.Now()
+ s.mu.Unlock()
+}</span>
+
+func (s *Server) getDocument(uri string) *document <span class="cov9" title="16">{
+ s.mu.RLock()
+ defer s.mu.RUnlock()
+ return s.docs[uri]
+}</span>
+
+// splitLines splits the input string into lines, normalizing line endings to '\n'.
+func splitLines(sx string) []string <span class="cov10" title="21">{
+ sx = strings.ReplaceAll(sx, "\r\n", "\n")
+ return strings.Split(sx, "\n")
+}</span>
+
+func (s *Server) lineContext(uri string, pos Position) (above, current, below, funcCtx string) <span class="cov3" title="2">{
+ d := s.getDocument(uri)
+ if d == nil || len(d.lines) == 0 </span><span class="cov1" title="1">{
+ return "", "", "", ""
+ }</span>
+ <span class="cov1" title="1">idx := pos.Line
+ if idx &lt; 0 </span><span class="cov0" title="0">{
+ idx = 0
+ }</span>
+ <span class="cov1" title="1">if idx &gt;= len(d.lines) </span><span class="cov0" title="0">{
+ idx = len(d.lines) - 1
+ }</span>
+ <span class="cov1" title="1">current = d.lines[idx]
+ if idx-1 &gt;= 0 </span><span class="cov1" title="1">{
+ above = d.lines[idx-1]
+ }</span>
+ <span class="cov1" title="1">if idx+1 &lt; len(d.lines) </span><span class="cov1" title="1">{
+ below = d.lines[idx+1]
+ }</span>
+ <span class="cov1" title="1">for i := idx; i &gt;= 0; i-- </span><span class="cov3" title="2">{
+ line := strings.TrimSpace(d.lines[i])
+ if hasAny(line, []string{"func ", "def ", "class ", "fn ", "procedure ", "sub "}) </span><span class="cov1" title="1">{
+ funcCtx = line
+ break</span>
+ }
+ }
+ <span class="cov1" title="1">return</span>
+}
+
+// isDefiningNewFunction returns true when the cursor appears to be within
+// a function declaration/signature and before the opening '{' of the body.
+// Heuristic: find nearest preceding line containing "func "; ensure no '{'
+// appears before the cursor across those lines.
+func (s *Server) isDefiningNewFunction(uri string, pos Position) bool <span class="cov0" title="0">{
+ d := s.getDocument(uri)
+ if d == nil || len(d.lines) == 0 </span><span class="cov0" title="0">{
+ return false
+ }</span>
+ <span class="cov0" title="0">idx := pos.Line
+ if idx &lt; 0 </span><span class="cov0" title="0">{
+ idx = 0
+ }</span>
+ <span class="cov0" title="0">if idx &gt;= len(d.lines) </span><span class="cov0" title="0">{
+ idx = len(d.lines) - 1
+ }</span>
+ // Find signature start
+ <span class="cov0" title="0">sigStart := -1
+ for i := idx; i &gt;= 0; i-- </span><span class="cov0" title="0">{
+ if strings.Contains(d.lines[i], "func ") </span><span class="cov0" title="0">{
+ sigStart = i
+ break</span>
+ }
+ // stop if we hit a closing brace which likely ends a previous block
+ <span class="cov0" title="0">if strings.Contains(d.lines[i], "}") </span><span class="cov0" title="0">{
+ break</span>
+ }
+ }
+ <span class="cov0" title="0">if sigStart == -1 </span><span class="cov0" title="0">{
+ return false
+ }</span>
+ // Scan for '{' from sigStart up to cursor position; if found before or at cursor, we're in body
+ <span class="cov0" title="0">for i := sigStart; i &lt;= idx; i++ </span><span class="cov0" title="0">{
+ line := d.lines[i]
+ brace := strings.Index(line, "{")
+ if brace &gt;= 0 </span><span class="cov0" title="0">{
+ if i &lt; idx </span><span class="cov0" title="0">{
+ return false // body started on a previous line
+ }</span>
+ // same line as cursor: if brace position &lt; cursor character, then already in body
+ <span class="cov0" title="0">if pos.Character &gt; brace </span><span class="cov0" title="0">{
+ return false
+ }</span>
+ }
+ }
+ <span class="cov0" title="0">return true</span>
+}
+
+func hasAny(s string, needles []string) bool <span class="cov3" title="2">{
+ for _, n := range needles </span><span class="cov6" title="7">{
+ if strings.Contains(s, n) </span><span class="cov1" title="1">{
+ return true
+ }</span>
+ }
+ <span class="cov1" title="1">return false</span>
+}
+
+func trimLen(s string) string <span class="cov9" title="18">{
+ s = strings.TrimSpace(s)
+ if len(s) &gt; 200 </span><span class="cov1" title="1">{
+ return s[:200] + "…"
+ }</span>
+ <span class="cov9" title="17">return s</span>
+}
+
+func firstLine(s string) string <span class="cov7" title="10">{
+ s = strings.ReplaceAll(s, "\r\n", "\n")
+ if idx := strings.IndexByte(s, '\n'); idx &gt;= 0 </span><span class="cov1" title="1">{
+ return s[:idx]
+ }</span>
+ <span class="cov7" title="9">return s</span>
+}
+</pre>
+
+ <pre class="file" id="file14" style="display: none">// Summary: LSP JSON-RPC handlers; implements core methods and integrates with the LLM client when enabled.
+package lsp
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+)
+
+func (s *Server) handle(req Request) <span class="cov0" title="0">{
+ if h, ok := s.handlers[req.Method]; ok </span><span class="cov0" title="0">{
+ h(req)
+ return
+ }</span>
+ <span class="cov0" title="0">if len(req.ID) != 0 </span><span class="cov0" title="0">{
+ s.reply(req.ID, nil, &amp;RespError{Code: -32601, Message: fmt.Sprintf("method not found: %s", req.Method)})
+ }</span>
+}
+
+// handleInitialize moved to handlers_init.go
+
+// llmRequestOpts moved to handlers_utils.go
+
+// instructionFromSelection extracts the first instruction from selection text.
+// Preference order on each line: strict ;text; marker (no inner spaces), then
+// a line comment (//, #, --). Returns the instruction string and the selection
+// text cleaned of the matched instruction marker or comment.
+func instructionFromSelection(sel string) (string, string) <span class="cov2" title="2">{
+ lines := splitLines(sel)
+ for idx, line := range lines </span><span class="cov2" title="2">{
+ if instr, cleaned, ok := findFirstInstructionInLine(line); ok &amp;&amp; strings.TrimSpace(instr) != "" </span><span class="cov1" title="1">{
+ lines[idx] = cleaned
+ return instr, strings.Join(lines, "\n")
+ }</span>
+ }
+ <span class="cov1" title="1">return "", sel</span>
+}
+
+// findFirstInstructionInLine returns the earliest instruction marker on the
+// line and the line with that marker removed. Supported markers, ordered by
+// earliest byte offset in the line:
+// - ;text; (strict, no space after first ';' or before last ';')
+// - /* text */ (single-line only)
+// - &lt;!-- text --&gt; (single-line only)
+// - // text
+// - # text
+// - -- text
+func findFirstInstructionInLine(line string) (instr string, cleaned string, ok bool) <span class="cov8" title="15">{
+ type cand struct {
+ start, end int
+ text string
+ }
+ cands := []cand{}
+ if t, l, r, ok := findStrictSemicolonTag(line); ok </span><span class="cov5" title="5">{
+ cands = append(cands, cand{start: l, end: r, text: t})
+ }</span>
+ <span class="cov8" title="15">if i := strings.Index(line, "/*"); i &gt;= 0 </span><span class="cov1" title="1">{
+ if j := strings.Index(line[i+2:], "*/"); j &gt;= 0 </span><span class="cov1" title="1">{
+ start := i
+ end := i + 2 + j + 2
+ text := strings.TrimSpace(line[i+2 : i+2+j])
+ cands = append(cands, cand{start: start, end: end, text: text})
+ }</span>
+ }
+ <span class="cov8" title="15">if i := strings.Index(line, "&lt;!--"); i &gt;= 0 </span><span class="cov1" title="1">{
+ if j := strings.Index(line[i+4:], "--&gt;"); j &gt;= 0 </span><span class="cov1" title="1">{
+ start := i
+ end := i + 4 + j + 3
+ text := strings.TrimSpace(line[i+4 : i+4+j])
+ cands = append(cands, cand{start: start, end: end, text: text})
+ }</span>
+ }
+ <span class="cov8" title="15">if i := strings.Index(line, "//"); i &gt;= 0 </span><span class="cov4" title="3">{
+ cands = append(cands, cand{start: i, end: len(line), text: strings.TrimSpace(line[i+2:])})
+ }</span>
+ <span class="cov8" title="15">if i := strings.Index(line, "#"); i &gt;= 0 </span><span class="cov1" title="1">{
+ cands = append(cands, cand{start: i, end: len(line), text: strings.TrimSpace(line[i+1:])})
+ }</span>
+ <span class="cov8" title="15">if i := strings.Index(line, "--"); i &gt;= 0 </span><span class="cov2" title="2">{
+ cands = append(cands, cand{start: i, end: len(line), text: strings.TrimSpace(line[i+2:])})
+ }</span>
+ <span class="cov8" title="15">if len(cands) == 0 </span><span class="cov5" title="5">{
+ return "", line, false
+ }</span>
+ // pick earliest start index
+ <span class="cov7" title="10">best := cands[0]
+ for _, c := range cands[1:] </span><span class="cov4" title="3">{
+ if c.start &gt;= 0 &amp;&amp; (best.start &lt; 0 || c.start &lt; best.start) </span><span class="cov1" title="1">{
+ best = c
+ }</span>
+ }
+ <span class="cov7" title="10">cleaned = strings.TrimRight(line[:best.start]+line[best.end:], " \t")
+ return best.text, cleaned, true</span>
+}
+
+// diagnosticsInRange parses the CodeAction context and returns diagnostics
+// that overlap the given selection range. If the context is missing or does
+// not contain diagnostics, returns an empty slice.
+// CodeAction-related handlers and helpers moved to handlers_codeaction.go
+
+// extractRangeText moved to handlers_utils.go
+
+// handleInitialized moved to handlers_init.go
+
+// handleShutdown moved to handlers_init.go
+
+// handleExit moved to handlers_init.go
+
+// handleDidOpen moved to handlers_document.go
+
+// handleDidChange moved to handlers_document.go
+
+// handleDidClose moved to handlers_document.go
+
+// handleCompletion moved to handlers_completion.go
+
+func (s *Server) reply(id json.RawMessage, result any, err *RespError) <span class="cov0" title="0">{
+ resp := Response{JSONRPC: "2.0", ID: id, Result: result, Error: err}
+ s.writeMessage(resp)
+}</span>
+
+// docBeforeAfter returns the full document text split at the given position.
+// The returned strings are the text before the cursor (inclusive of anything
+// left of the position) and the text after the cursor.
+// docBeforeAfter moved to handlers_document.go
+
+// extractTriggerInfo returns the LSP completion TriggerKind and TriggerCharacter
+// if provided by the client; when absent it returns zeros.
+// extractTriggerInfo moved to handlers_completion.go
+
+// --- in-editor chat (";C ...") ---
+
+// detectAndHandleChat scans the current document for any line that starts with
+// ";C" and appears to be awaiting a response (i.e., followed by a blank line
+// and no non-empty answer line yet). If found, it asks the LLM and inserts the
+// answer below the blank line, leaving exactly one empty line between prompt
+// and response.
+// detectAndHandleChat moved to handlers_document.go
+
+// applyChatEdits removes the triggering punctuation at end of the line and
+// inserts two newlines followed by a new line with the response prefixed.
+// applyChatEdits moved to handlers_document.go
+
+// buildChatHistory walks upwards from the current line to collect the most recent
+// Q/A pairs in the in-editor transcript. It returns messages in chronological order
+// ending with the current user prompt. Limits to a small number of pairs to control tokens.
+// buildChatHistory moved to handlers_document.go
+
+// stripTrailingTrigger removes a single trailing punctuation from the set
+// [?,!,:] or both semicolons if present at end, mirroring the inline trigger rules.
+// stripTrailingTrigger moved to handlers_document.go
+
+// clientApplyEdit sends a workspace/applyEdit request to the client.
+// clientApplyEdit moved to handlers_document.go
+
+// nextReqID returns a unique json.RawMessage id for server-initiated requests.
+// nextReqID moved to handlers_document.go
+
+// --- completion helpers ---
+
+// buildDocString moved to handlers_completion.go
+
+// logCompletionContext moved to handlers_completion.go
+
+// tryLLMCompletion moved to handlers_completion.go
+
+// parseManualInvoke inspects the LSP completion context and reports whether the user manually invoked completion.
+// parseManualInvoke moved to handlers_completion.go
+
+// shouldSuppressForChatTriggerEOL returns true when a chat trigger like "&gt;" follows ?, !, :, or ; at EOL.
+// shouldSuppressForChatTriggerEOL moved to handlers_completion.go
+
+// prefixHeuristicAllows applies minimal prefix rules unless inlinePrompt or structural triggers apply.
+// prefixHeuristicAllows moved to handlers_completion.go
+
+// tryProviderNativeCompletion attempts provider-native completion and returns items when successful.
+// tryProviderNativeCompletion moved to handlers_completion.go
+
+// buildCompletionMessages constructs the LLM messages for completion.
+// buildCompletionMessages moved to handlers_completion.go
+
+// postProcessCompletion normalizes and deduplicates completion text and applies indentation rules.
+// postProcessCompletion moved to handlers_completion.go
+
+// busyCompletionItem builds a visible, non-inserting completion item indicating
+// that an LLM request is already in flight.
+// removed: previous single in-flight LLM busy gate and busy item
+
+// --- small completion cache (last ~10 entries) ---
+
+func (s *Server) completionCacheKey(p CompletionParams, above, current, below, funcCtx string, inParams bool, hasExtra bool, extraText string) string <span class="cov7" title="10">{
+ // Normalize left-of-cursor by trimming trailing spaces/tabs
+ idx := p.Position.Character
+ if idx &gt; len(current) </span><span class="cov0" title="0">{
+ idx = len(current)
+ }</span>
+ <span class="cov7" title="10">left := strings.TrimRight(current[:idx], " \t")
+ right := ""
+ if idx &lt; len(current) </span><span class="cov0" title="0">{
+ right = current[idx:]
+ }</span>
+ <span class="cov7" title="10">prov := ""
+ model := ""
+ if s.llmClient != nil </span><span class="cov7" title="10">{
+ prov = s.llmClient.Name()
+ model = s.llmClient.DefaultModel()
+ }</span>
+ <span class="cov7" title="10">temp := ""
+ if s.codingTemperature != nil </span><span class="cov0" title="0">{
+ temp = fmt.Sprintf("%.3f", *s.codingTemperature)
+ }</span>
+ <span class="cov7" title="10">extra := ""
+ if hasExtra </span><span class="cov0" title="0">{
+ extra = strings.TrimSpace(extraText)
+ }</span>
+ // Compose a key from essential context parts
+ <span class="cov7" title="10">return strings.Join([]string{
+ "v1", // version for future-proofing
+ prov,
+ model,
+ temp,
+ p.TextDocument.URI,
+ fmt.Sprintf("%d:%d", p.Position.Line, len(left)),
+ above,
+ left,
+ right,
+ below,
+ funcCtx,
+ fmt.Sprintf("params=%t", inParams),
+ extra,
+ }, "\x1f")</span> // use unit separator to avoid collisions
+}
+
+func (s *Server) completionCacheGet(key string) (string, bool) <span class="cov7" title="9">{
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ v, ok := s.compCache[key]
+ if !ok </span><span class="cov6" title="8">{
+ return "", false
+ }</span>
+ // move to most-recent
+ <span class="cov1" title="1">s.compCacheTouchLocked(key)
+ return v, true</span>
+}
+
+func (s *Server) completionCachePut(key, value string) <span class="cov6" title="8">{
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.compCache == nil </span><span class="cov0" title="0">{
+ s.compCache = make(map[string]string)
+ }</span>
+ <span class="cov6" title="8">if _, exists := s.compCache[key]; !exists </span><span class="cov6" title="8">{
+ s.compCacheOrder = append(s.compCacheOrder, key)
+ s.compCache[key] = value
+ if len(s.compCacheOrder) &gt; 10 </span><span class="cov0" title="0">{
+ // evict oldest
+ old := s.compCacheOrder[0]
+ s.compCacheOrder = s.compCacheOrder[1:]
+ delete(s.compCache, old)
+ }</span>
+ <span class="cov6" title="8">return</span>
+ }
+ // update existing and mark most-recent
+ <span class="cov0" title="0">s.compCache[key] = value
+ s.compCacheTouchLocked(key)</span>
+}
+
+func (s *Server) compCacheTouchLocked(key string) <span class="cov1" title="1">{
+ // assumes s.mu is held
+ // remove any existing occurrence of key in order slice
+ idx := -1
+ for i, k := range s.compCacheOrder </span><span class="cov1" title="1">{
+ if k == key </span><span class="cov1" title="1">{
+ idx = i
+ break</span>
+ }
+ }
+ <span class="cov1" title="1">if idx &gt;= 0 </span><span class="cov1" title="1">{
+ s.compCacheOrder = append(append([]string{}, s.compCacheOrder[:idx]...), s.compCacheOrder[idx+1:]...)
+ }</span>
+ <span class="cov1" title="1">s.compCacheOrder = append(s.compCacheOrder, key)</span>
+}
+
+// isTriggerEvent returns true when the completion request appears to be caused
+// by typing one of our configured trigger characters. It checks the LSP
+// CompletionContext if provided and also falls back to inspecting the character
+// immediately to the left of the cursor.
+func (s *Server) isTriggerEvent(p CompletionParams, current string) bool <span class="cov8" title="16">{
+ // 1) Inspect LSP completion context if present
+ if p.Context != nil </span><span class="cov5" title="5">{
+ var ctx struct {
+ TriggerKind int `json:"triggerKind"`
+ TriggerCharacter string `json:"triggerCharacter,omitempty"`
+ }
+ if raw, ok := p.Context.(json.RawMessage); ok </span><span class="cov5" title="5">{
+ _ = json.Unmarshal(raw, &amp;ctx)
+ }</span> else<span class="cov0" title="0"> {
+ b, _ := json.Marshal(p.Context)
+ _ = json.Unmarshal(b, &amp;ctx)
+ }</span>
+ // If the line contains a bare ';;' (no ';;text;'), do not treat as a trigger source.
+ <span class="cov5" title="5">if strings.Contains(current, ";;") &amp;&amp; !hasDoubleSemicolonTrigger(current) </span><span class="cov1" title="1">{
+ return false
+ }</span>
+ // TriggerKind 1 = Invoked (manual). Always allow manual invoke.
+ <span class="cov4" title="4">if ctx.TriggerKind == 1 </span><span class="cov4" title="4">{
+ return true
+ }</span>
+ // TriggerKind 2 is TriggerCharacter per LSP spec
+ <span class="cov0" title="0">if ctx.TriggerKind == 2 </span><span class="cov0" title="0">{
+ if ctx.TriggerCharacter != "" </span><span class="cov0" title="0">{
+ for _, c := range s.triggerChars </span><span class="cov0" title="0">{
+ if c == ctx.TriggerCharacter </span><span class="cov0" title="0">{
+ return true
+ }</span>
+ }
+ <span class="cov0" title="0">return false</span>
+ }
+ // No character provided but reported as TriggerCharacter; be conservative
+ <span class="cov0" title="0">return false</span>
+ }
+ // For TriggerForIncomplete (3), require manual char check below
+ }
+ // 2) Fallback: check the character immediately prior to cursor
+ <span class="cov7" title="11">idx := p.Position.Character
+ if idx &lt;= 0 || idx &gt; len(current) </span><span class="cov0" title="0">{
+ return false
+ }</span>
+ // Bare ';;' should not trigger via fallback char either
+ <span class="cov7" title="11">if strings.Contains(current, ";;") &amp;&amp; !hasDoubleSemicolonTrigger(current) </span><span class="cov2" title="2">{
+ return false
+ }</span>
+ <span class="cov7" title="9">ch := string(current[idx-1])
+ for _, c := range s.triggerChars </span><span class="cov10" title="24">{
+ if c == ch </span><span class="cov4" title="4">{
+ return true
+ }</span>
+ }
+ <span class="cov5" title="5">return false</span>
+}
+
+func (s *Server) makeCompletionItems(cleaned string, inParams bool, current string, p CompletionParams, docStr string) []CompletionItem <span class="cov7" title="9">{
+ te, filter := computeTextEditAndFilter(cleaned, inParams, current, p)
+ rm := s.collectPromptRemovalEdits(p.TextDocument.URI)
+ label := labelForCompletion(cleaned, filter)
+ detail := "Hexai LLM completion"
+ if s.llmClient != nil </span><span class="cov7" title="9">{
+ detail = "Hexai " + s.llmClient.Name() + ":" + s.llmClient.DefaultModel()
+ }</span>
+ <span class="cov7" title="9">return []CompletionItem{{
+ Label: label,
+ Kind: 1,
+ Detail: detail,
+ InsertTextFormat: 1,
+ FilterText: strings.TrimLeft(filter, " \t"),
+ TextEdit: te,
+ AdditionalTextEdits: rm,
+ SortText: "0000",
+ Documentation: docStr,
+ }}</span>
+}
+
+// small helpers to keep tryLLMCompletion short
+// LLM stats helpers moved to handlers_utils.go
+
+// collectPromptRemovalEdits returns edits to remove all inline prompt markers.
+// Supported form (inclusive):
+// - ";...;" where there is no space immediately after the first ';'
+// and no space immediately before the last ';'. An optional single space
+// after the trailing ';' is also removed for cleanliness.
+//
+// Multiple markers per line are supported.
+// Inline prompt removal helpers moved to handlers_utils.go
+
+// inParamList moved to handlers_utils.go
+
+// buildPrompts moved to handlers_utils.go
+
+// computeTextEditAndFilter moved to handlers_utils.go
+
+// computeWordStart moved to handlers_utils.go
+
+// isIdentChar moved to handlers_utils.go
+
+// lineHasInlinePrompt returns true if the line contains an inline strict
+// semicolon marker ;text; (no spaces at boundaries) or a double-semicolon
+// pattern recognized by hasDoubleSemicolonTrigger.
+// lineHasInlinePrompt moved to handlers_utils.go
+
+// leadingIndent returns the run of leading spaces/tabs from the provided line.
+// leadingIndent moved to handlers_utils.go
+
+// applyIndent prefixes each non-empty line of suggestion with the given indent
+// unless it already starts with that indent.
+// applyIndent moved to handlers_utils.go
+
+// isBareDoubleSemicolon reports whether the line contains a standalone
+// double-semicolon marker with no inline content (";;" possibly with only
+// whitespace after it). It explicitly excludes the valid form ";;text;".
+// isBareDoubleSemicolon moved to handlers_utils.go
+
+// stripDuplicateAssignmentPrefix removes a duplicated assignment prefix (e.g.,
+// "name :=") from the beginning of the model suggestion when that same prefix
+// already appears immediately to the left of the cursor on the current line.
+// Also handles simple '=' assignments.
+// stripDuplicateAssignmentPrefix moved to handlers_utils.go
+
+// stripDuplicateGeneralPrefix removes any already-typed prefix that the model repeated
+// at the beginning of its suggestion. It compares the entire text to the left of the
+// cursor (prefixBeforeCursor) against the suggestion, trimming whitespace appropriately,
+// and strips the longest sensible overlap. This prevents cases like:
+//
+// prefix: "func New "
+// suggestion:"func New() *Type"
+//
+// resulting in duplicates like "func New func New() *Type".
+// stripDuplicateGeneralPrefix moved to handlers_utils.go
+
+// isIdentBoundary moved to handlers_utils.go
+
+// stripCodeFences removes surrounding Markdown code fences from a model
+// response when the entire output is wrapped, e.g. starting with "```go" or
+// "```" and ending with "```". It returns the inner content unchanged.
+// stripCodeFences moved to handlers_utils.go
+
+// stripInlineCodeSpan returns only the contents of the first inline backtick
+// code span if present, e.g., "some text `x := y()` more" -&gt; "x := y()".
+// If no matching pair of backticks exists, it returns the input unchanged.
+// This is intended for code completion responses where the model may wrap a
+// small snippet in single backticks among prose.
+// stripInlineCodeSpan moved to handlers_utils.go
+
+// labelForCompletion moved to handlers_utils.go
+
+func (s *Server) fallbackCompletionItems(docStr string) []CompletionItem <span class="cov0" title="0">{
+ return []CompletionItem{{
+ Label: "hexai-complete",
+ Kind: 1,
+ Detail: "dummy completion",
+ InsertText: "hexai",
+ SortText: "9999",
+ Documentation: docStr,
+ }}
+}</span>
+</pre>
+
+ <pre class="file" id="file15" style="display: none">// Summary: Code Action handlers and helpers split from handlers.go for clarity.
+package lsp
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "codeberg.org/snonux/hexai/internal/llm"
+ "codeberg.org/snonux/hexai/internal/logging"
+ "strings"
+ "time"
+ "os"
+ "path/filepath"
+)
+
+func (s *Server) handleCodeAction(req Request) <span class="cov0" title="0">{
+ var p CodeActionParams
+ if err := json.Unmarshal(req.Params, &amp;p); err != nil </span><span class="cov0" title="0">{
+ if len(req.ID) != 0 </span><span class="cov0" title="0">{
+ s.reply(req.ID, []CodeAction{}, nil)
+ }</span>
+ <span class="cov0" title="0">return</span>
+ }
+ <span class="cov0" title="0">d := s.getDocument(p.TextDocument.URI)
+ if d == nil || len(d.lines) == 0 || s.llmClient == nil </span><span class="cov0" title="0">{
+ if len(req.ID) != 0 </span><span class="cov0" title="0">{
+ s.reply(req.ID, []CodeAction{}, nil)
+ }</span>
+ <span class="cov0" title="0">return</span>
+ }
+ <span class="cov0" title="0">sel := extractRangeText(d, p.Range)
+
+ actions := make([]CodeAction, 0, 4)
+ if a := s.buildRewriteCodeAction(p, sel); a != nil </span><span class="cov0" title="0">{
+ actions = append(actions, *a)
+ }</span>
+ <span class="cov0" title="0">if a := s.buildDiagnosticsCodeAction(p, sel); a != nil </span><span class="cov0" title="0">{
+ actions = append(actions, *a)
+ }</span>
+ <span class="cov0" title="0">if a := s.buildDocumentCodeAction(p, sel); a != nil </span><span class="cov0" title="0">{
+ actions = append(actions, *a)
+ }</span>
+ <span class="cov0" title="0">if a := s.buildGoUnitTestCodeAction(p); a != nil </span><span class="cov0" title="0">{
+ actions = append(actions, *a)
+ }</span>
+ <span class="cov0" title="0">if len(req.ID) != 0 </span><span class="cov0" title="0">{
+ s.reply(req.ID, actions, nil)
+ }</span>
+}
+
+func (s *Server) buildRewriteCodeAction(p CodeActionParams, sel string) *CodeAction <span class="cov5" title="2">{
+ if instr, cleaned := instructionFromSelection(sel); strings.TrimSpace(instr) != "" </span><span class="cov1" title="1">{
+ payload := struct {
+ Type string `json:"type"`
+ URI string `json:"uri"`
+ Range Range `json:"range"`
+ Instruction string `json:"instruction"`
+ Selection string `json:"selection"`
+ }{Type: "rewrite", URI: p.TextDocument.URI, Range: p.Range, Instruction: instr, Selection: cleaned}
+ raw, _ := json.Marshal(payload)
+ ca := CodeAction{Title: "Hexai: rewrite selection", Kind: "refactor.rewrite", Data: raw}
+ return &amp;ca
+ }</span>
+ <span class="cov1" title="1">return nil</span>
+}
+
+func (s *Server) buildDiagnosticsCodeAction(p CodeActionParams, sel string) *CodeAction <span class="cov5" title="2">{
+ diags := s.diagnosticsInRange(p.Context, p.Range)
+ if len(diags) == 0 </span><span class="cov1" title="1">{
+ return nil
+ }</span>
+ <span class="cov1" title="1">payload := struct {
+ Type string `json:"type"`
+ URI string `json:"uri"`
+ Range Range `json:"range"`
+ Selection string `json:"selection"`
+ Diagnostics []Diagnostic `json:"diagnostics"`
+ }{Type: "diagnostics", URI: p.TextDocument.URI, Range: p.Range, Selection: sel, Diagnostics: diags}
+ raw, _ := json.Marshal(payload)
+ ca := CodeAction{Title: "Hexai: resolve diagnostics", Kind: "quickfix", Data: raw}
+ return &amp;ca</span>
+}
+
+func (s *Server) resolveCodeAction(ca CodeAction) (CodeAction, bool) <span class="cov5" title="2">{
+ if s.llmClient == nil || len(ca.Data) == 0 </span><span class="cov0" title="0">{
+ return ca, false
+ }</span>
+ <span class="cov5" title="2">var payload struct {
+ Type string `json:"type"`
+ URI string `json:"uri"`
+ Range Range `json:"range"`
+ Instruction string `json:"instruction,omitempty"`
+ Selection string `json:"selection"`
+ Diagnostics []Diagnostic `json:"diagnostics,omitempty"`
+ }
+ if err := json.Unmarshal(ca.Data, &amp;payload); err != nil </span><span class="cov0" title="0">{
+ return ca, false
+ }</span>
+ <span class="cov5" title="2">switch payload.Type </span>{
+ case "rewrite":<span class="cov1" title="1">
+ sys := "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."
+ user := fmt.Sprintf("Instruction: %s\n\nSelected code to transform:\n%s", payload.Instruction, payload.Selection)
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ messages := []llm.Message{{Role: "system", Content: sys}, {Role: "user", Content: user}}
+ opts := s.llmRequestOpts()
+ if text, err := s.llmClient.Chat(ctx, messages, opts...); err == nil </span><span class="cov1" title="1">{
+ if out := stripCodeFences(strings.TrimSpace(text)); out != "" </span><span class="cov1" title="1">{
+ edit := WorkspaceEdit{Changes: map[string][]TextEdit{payload.URI: {{Range: payload.Range, NewText: out}}}}
+ ca.Edit = &amp;edit
+ return ca, true
+ }</span>
+ } else<span class="cov0" title="0"> {
+ logging.Logf("lsp ", "codeAction rewrite llm error: %v", err)
+ }</span>
+ case "diagnostics":<span class="cov1" title="1">
+ sys := "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."
+ var b strings.Builder
+ b.WriteString("Diagnostics to resolve (selection only):\n")
+ for i, dgn := range payload.Diagnostics </span><span class="cov1" title="1">{
+ if dgn.Source != "" </span><span class="cov0" title="0">{
+ fmt.Fprintf(&amp;b, "%d. [%s] %s\n", i+1, dgn.Source, dgn.Message)
+ }</span> else<span class="cov1" title="1"> {
+ fmt.Fprintf(&amp;b, "%d. %s\n", i+1, dgn.Message)
+ }</span>
+ }
+ <span class="cov1" title="1">b.WriteString("\nSelected code:\n")
+ b.WriteString(payload.Selection)
+ ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second)
+ defer cancel()
+ messages := []llm.Message{{Role: "system", Content: sys}, {Role: "user", Content: b.String()}}
+ opts := s.llmRequestOpts()
+ if text, err := s.llmClient.Chat(ctx, messages, opts...); err == nil </span><span class="cov1" title="1">{
+ if out := stripCodeFences(strings.TrimSpace(text)); out != "" </span><span class="cov1" title="1">{
+ edit := WorkspaceEdit{Changes: map[string][]TextEdit{payload.URI: {{Range: payload.Range, NewText: out}}}}
+ ca.Edit = &amp;edit
+ return ca, true
+ }</span>
+ } else<span class="cov0" title="0"> {
+ logging.Logf("lsp ", "codeAction diagnostics llm error: %v", err)
+ }</span>
+ case "document":<span class="cov0" title="0">
+ sys := "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."
+ user := "Add documentation comments to this code:\n" + payload.Selection
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ messages := []llm.Message{{Role: "system", Content: sys}, {Role: "user", Content: user}}
+ opts := s.llmRequestOpts()
+ if text, err := s.llmClient.Chat(ctx, messages, opts...); err == nil </span><span class="cov0" title="0">{
+ if out := stripCodeFences(strings.TrimSpace(text)); out != "" </span><span class="cov0" title="0">{
+ edit := WorkspaceEdit{Changes: map[string][]TextEdit{payload.URI: {{Range: payload.Range, NewText: out}}}}
+ ca.Edit = &amp;edit
+ return ca, true
+ }</span>
+ } else<span class="cov0" title="0"> {
+ logging.Logf("lsp ", "codeAction document llm error: %v", err)
+ }</span>
+ case "go_test":<span class="cov0" title="0">
+ if edit, jumpURI, jumpRange, ok := s.resolveGoTest(payload.URI, payload.Range.Start); ok </span><span class="cov0" title="0">{
+ ca.Edit = &amp;edit
+ // After edit is applied, ask client to jump to new test function
+ ca.Command = &amp;Command{Title: "Jump to generated test", Command: "hexai.showDocument", Arguments: []any{jumpURI, jumpRange}}
+ // Also send a server-initiated showDocument shortly after resolve to cover
+ // clients that do not execute commands from code actions.
+ s.deferShowDocument(jumpURI, jumpRange)
+ return ca, true
+ }</span>
+ }
+ <span class="cov0" title="0">return ca, false</span>
+}
+
+func (s *Server) handleCodeActionResolve(req Request) <span class="cov0" title="0">{
+ var ca CodeAction
+ if err := json.Unmarshal(req.Params, &amp;ca); err != nil </span><span class="cov0" title="0">{
+ if len(req.ID) != 0 </span><span class="cov0" title="0">{
+ s.reply(req.ID, ca, nil)
+ }</span>
+ <span class="cov0" title="0">return</span>
+ }
+ <span class="cov0" title="0">if resolved, ok := s.resolveCodeAction(ca); ok </span><span class="cov0" title="0">{
+ s.reply(req.ID, resolved, nil)
+ return
+ }</span>
+ <span class="cov0" title="0">s.reply(req.ID, ca, nil)</span>
+}
+
+// diagnosticsInRange parses the CodeAction context and returns diagnostics
+// that overlap the given selection range. If the context is missing or does
+// not contain diagnostics, returns an empty slice.
+func (s *Server) diagnosticsInRange(ctxRaw json.RawMessage, sel Range) []Diagnostic <span class="cov5" title="2">{
+ if len(ctxRaw) == 0 </span><span class="cov1" title="1">{
+ return nil
+ }</span>
+ <span class="cov1" title="1">var ctx CodeActionContext
+ if err := json.Unmarshal(ctxRaw, &amp;ctx); err != nil </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ <span class="cov1" title="1">if len(ctx.Diagnostics) == 0 </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ <span class="cov1" title="1">out := make([]Diagnostic, 0, len(ctx.Diagnostics))
+ for _, d := range ctx.Diagnostics </span><span class="cov5" title="2">{
+ if rangesOverlap(d.Range, sel) </span><span class="cov1" title="1">{
+ out = append(out, d)
+ }</span>
+ }
+ <span class="cov1" title="1">return out</span>
+}
+
+// rangesOverlap reports whether two LSP ranges overlap at all.
+func rangesOverlap(a, b Range) bool <span class="cov5" title="2">{
+ // Normalize ordering
+ if greaterPos(a.Start, a.End) </span><span class="cov0" title="0">{
+ a.Start, a.End = a.End, a.Start
+ }</span>
+ <span class="cov5" title="2">if greaterPos(b.Start, b.End) </span><span class="cov0" title="0">{
+ b.Start, b.End = b.End, b.Start
+ }</span>
+ // a ends before b starts
+ <span class="cov5" title="2">if lessPos(a.End, b.Start) </span><span class="cov1" title="1">{
+ return false
+ }</span>
+ // b ends before a starts
+ <span class="cov1" title="1">if lessPos(b.End, a.Start) </span><span class="cov0" title="0">{
+ return false
+ }</span>
+ <span class="cov1" title="1">return true</span>
+}
+
+func lessPos(p, q Position) bool <span class="cov8" title="3">{
+ if p.Line != q.Line </span><span class="cov8" title="3">{
+ return p.Line &lt; q.Line
+ }</span>
+ <span class="cov0" title="0">return p.Character &lt; q.Character</span>
+}
+
+func greaterPos(p, q Position) bool <span class="cov10" title="4">{
+ if p.Line != q.Line </span><span class="cov8" title="3">{
+ return p.Line &gt; q.Line
+ }</span>
+ <span class="cov1" title="1">return p.Character &gt; q.Character</span>
+}
+
+// --- Go unit test code action ---
+
+func (s *Server) buildGoUnitTestCodeAction(p CodeActionParams) *CodeAction <span class="cov0" title="0">{
+ uri := p.TextDocument.URI
+ if uri == "" || !strings.HasSuffix(strings.TrimPrefix(uri, "file://"), ".go") </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ // Skip if already a _test.go file
+ <span class="cov0" title="0">if strings.HasSuffix(strings.TrimPrefix(uri, "file://"), "_test.go") </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ // Heuristic: only offer when a function context is found above the cursor
+ <span class="cov0" title="0">_, _, _, funcCtx := s.lineContext(uri, p.Range.Start)
+ if !strings.Contains(funcCtx, "func ") </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ <span class="cov0" title="0">payload := struct {
+ Type string `json:"type"`
+ URI string `json:"uri"`
+ Range Range `json:"range"`
+ }{Type: "go_test", URI: uri, Range: p.Range}
+ raw, _ := json.Marshal(payload)
+ ca := CodeAction{Title: "Hexai: implement unit test", Kind: "quickfix", Data: raw}
+ return &amp;ca</span>
+}
+
+// buildDocumentCodeAction offers to document the selected code by injecting comments.
+func (s *Server) buildDocumentCodeAction(p CodeActionParams, sel string) *CodeAction <span class="cov0" title="0">{
+ if s.llmClient == nil </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ <span class="cov0" title="0">if strings.TrimSpace(sel) == "" </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ <span class="cov0" title="0">payload := struct {
+ Type string `json:"type"`
+ URI string `json:"uri"`
+ Range Range `json:"range"`
+ Selection string `json:"selection"`
+ }{Type: "document", URI: p.TextDocument.URI, Range: p.Range, Selection: sel}
+ raw, _ := json.Marshal(payload)
+ ca := CodeAction{Title: "Hexai: document code", Kind: "refactor.rewrite", Data: raw}
+ return &amp;ca</span>
+}
+
+func (s *Server) resolveGoTest(uri string, pos Position) (WorkspaceEdit, string, Range, bool) <span class="cov0" title="0">{
+ path := strings.TrimPrefix(uri, "file://")
+ if !strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "_test.go") </span><span class="cov0" title="0">{
+ return WorkspaceEdit{}, "", Range{}, false
+ }</span>
+ // Load source text
+ <span class="cov0" title="0">_, lines := s.loadFileText(uri)
+ if len(lines) == 0 </span><span class="cov0" title="0">{
+ return WorkspaceEdit{}, "", Range{}, false
+ }</span>
+ <span class="cov0" title="0">pkg := parseGoPackageName(lines)
+ fnStart, fnEnd := findGoFunctionAtLine(lines, pos.Line)
+ if fnStart &lt; 0 || fnEnd &lt; fnStart </span><span class="cov0" title="0">{
+ return WorkspaceEdit{}, "", Range{}, false
+ }</span>
+ <span class="cov0" title="0">funcCode := strings.Join(lines[fnStart:fnEnd+1], "\n")
+ testFunc := s.generateGoTestFunction(funcCode)
+ if strings.TrimSpace(testFunc) == "" </span><span class="cov0" title="0">{
+ return WorkspaceEdit{}, "", Range{}, false
+ }</span>
+ // Determine test file target
+ <span class="cov0" title="0">testPath := strings.TrimSuffix(path, ".go") + "_test.go"
+ testURI := "file://" + testPath
+
+ // If test file exists, append test at EOF; otherwise, create a new file with package+import
+ if fileExists(testPath) </span><span class="cov0" title="0">{
+ // Build an insertion at end of file
+ _, tLines := s.loadFileText(testURI)
+ // Fallback when not open and cannot read: still insert at line 0
+ lineIdx := 0
+ col := 0
+ if len(tLines) &gt; 0 </span><span class="cov0" title="0">{
+ lineIdx = len(tLines) - 1
+ col = len(tLines[lineIdx])
+ }</span>
+ <span class="cov0" title="0">var b strings.Builder
+ // Ensure at least two newlines before the new test
+ if len(tLines) == 0 || (len(tLines) &gt; 0 &amp;&amp; !strings.HasSuffix(strings.Join(tLines, "\n"), "\n\n")) </span><span class="cov0" title="0">{
+ b.WriteString("\n\n")
+ }</span>
+ <span class="cov0" title="0">b.WriteString(testFunc)
+ insert := b.String()
+ edit := TextEdit{Range: Range{Start: Position{Line: lineIdx, Character: col}, End: Position{Line: lineIdx, Character: col}}, NewText: insert}
+ we := WorkspaceEdit{Changes: map[string][]TextEdit{testURI: {edit}}}
+ // Compute jump range start
+ // Count how many prefix newlines added before the test function
+ prefixNL := 0
+ if strings.HasPrefix(insert, "\n\n") </span><span class="cov0" title="0">{ prefixNL = 2 }</span>
+ <span class="cov0" title="0">startLine := lineIdx + prefixNL
+ // If we inserted with two newlines and last line wasn't blank, first newline moves to next line
+ if prefixNL &gt; 0 </span><span class="cov0" title="0">{ startLine = lineIdx + prefixNL }</span>
+ <span class="cov0" title="0">jump := Range{Start: Position{Line: startLine, Character: 0}, End: Position{Line: startLine, Character: 0}}
+ return we, testURI, jump, true</span>
+ }
+ // Create new file content
+ <span class="cov0" title="0">var content strings.Builder
+ if pkg == "" </span><span class="cov0" title="0">{ pkg = filepath.Base(filepath.Dir(path)) }</span>
+ <span class="cov0" title="0">content.WriteString("package ")
+ content.WriteString(pkg)
+ content.WriteString("\n\n")
+ content.WriteString("import (\n\t\"testing\"\n)\n\n")
+ content.WriteString(testFunc)
+ full := content.String()
+ // Use documentChanges with create + full content insert
+ create := CreateFile{Kind: "create", URI: testURI}
+ tde := TextDocumentEdit{TextDocument: VersionedTextDocumentIdentifier{URI: testURI}, Edits: []TextEdit{{Range: Range{Start: Position{Line: 0, Character: 0}, End: Position{Line: 0, Character: 0}}, NewText: full}}}
+ we := WorkspaceEdit{DocumentChanges: []any{create, tde}}
+ // Find start line of first test function
+ // Count lines before the substring "func Test"
+ pre := content.String()
+ idx := strings.Index(pre, "func Test")
+ startLine := 0
+ if idx &gt; 0 </span><span class="cov0" title="0">{
+ before := pre[:idx]
+ startLine = strings.Count(before, "\n")
+ }</span>
+ <span class="cov0" title="0">jump := Range{Start: Position{Line: startLine, Character: 0}, End: Position{Line: startLine, Character: 0}}
+ return we, testURI, jump, true</span>
+}
+
+// loadFileText returns the file content and lines. It prefers the open document; otherwise reads from disk.
+func (s *Server) loadFileText(uri string) (string, []string) <span class="cov0" title="0">{
+ if d := s.getDocument(uri); d != nil </span><span class="cov0" title="0">{
+ return d.text, append([]string{}, d.lines...)
+ }</span>
+ <span class="cov0" title="0">path := strings.TrimPrefix(uri, "file://")
+ b, err := os.ReadFile(path)
+ if err != nil </span><span class="cov0" title="0">{
+ return "", nil
+ }</span>
+ <span class="cov0" title="0">txt := string(b)
+ return txt, splitLines(txt)</span>
+}
+
+func fileExists(path string) bool <span class="cov0" title="0">{
+ if _, err := os.Stat(path); err == nil </span><span class="cov0" title="0">{
+ return true
+ }</span>
+ <span class="cov0" title="0">return false</span>
+}
+
+// parseGoPackageName returns the package name from file lines, or empty if not found.
+func parseGoPackageName(lines []string) string <span class="cov0" title="0">{
+ for _, ln := range lines </span><span class="cov0" title="0">{
+ t := strings.TrimSpace(ln)
+ if strings.HasPrefix(t, "package ") </span><span class="cov0" title="0">{
+ name := strings.TrimSpace(strings.TrimPrefix(t, "package "))
+ // strip inline comments
+ if i := strings.Index(name, " "); i &gt;= 0 </span><span class="cov0" title="0">{ name = name[:i] }</span>
+ <span class="cov0" title="0">if i := strings.Index(name, "\t"); i &gt;= 0 </span><span class="cov0" title="0">{ name = name[:i] }</span>
+ <span class="cov0" title="0">if i := strings.Index(name, "//"); i &gt;= 0 </span><span class="cov0" title="0">{ name = strings.TrimSpace(name[:i]) }</span>
+ <span class="cov0" title="0">return name</span>
+ }
+ }
+ <span class="cov0" title="0">return ""</span>
+}
+
+// findGoFunctionAtLine finds the function enclosing or preceding line idx. Returns start and end line indexes.
+func findGoFunctionAtLine(lines []string, idx int) (int, int) <span class="cov0" title="0">{
+ if idx &lt; 0 </span><span class="cov0" title="0">{ idx = 0 }</span>
+ <span class="cov0" title="0">if idx &gt;= len(lines) </span><span class="cov0" title="0">{ idx = len(lines)-1 }</span>
+ // find signature start
+ <span class="cov0" title="0">start := -1
+ for i := idx; i &gt;= 0; i-- </span><span class="cov0" title="0">{
+ if strings.Contains(lines[i], "func ") </span><span class="cov0" title="0">{
+ start = i
+ break</span>
+ }
+ <span class="cov0" title="0">if strings.Contains(lines[i], "}") </span><span class="cov0" title="0">{
+ break</span>
+ }
+ }
+ <span class="cov0" title="0">if start == -1 </span><span class="cov0" title="0">{ return -1, -1 }</span>
+ // find first '{'
+ <span class="cov0" title="0">depth := 0
+ seenOpen := false
+ for i := start; i &lt; len(lines); i++ </span><span class="cov0" title="0">{
+ ln := lines[i]
+ for j := 0; j &lt; len(ln); j++ </span><span class="cov0" title="0">{
+ switch ln[j] </span>{
+ case '{':<span class="cov0" title="0">
+ depth++
+ seenOpen = true</span>
+ case '}':<span class="cov0" title="0">
+ if depth &gt; 0 </span><span class="cov0" title="0">{ depth-- }</span>
+ <span class="cov0" title="0">if seenOpen &amp;&amp; depth == 0 </span><span class="cov0" title="0">{
+ return start, i
+ }</span>
+ }
+ }
+ }
+ // if never saw '{', assume single-line prototype; return that line
+ <span class="cov0" title="0">if !seenOpen </span><span class="cov0" title="0">{
+ return start, start
+ }</span>
+ <span class="cov0" title="0">return start, -1</span>
+}
+
+// generateGoTestFunction uses LLM to produce a test function; falls back to a stub when unavailable.
+func (s *Server) generateGoTestFunction(funcCode string) string <span class="cov0" title="0">{
+ if s.llmClient != nil </span><span class="cov0" title="0">{
+ sys := "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."
+ user := "Function under test:\n" + funcCode
+ ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second)
+ defer cancel()
+ messages := []llm.Message{{Role: "system", Content: sys}, {Role: "user", Content: user}}
+ opts := s.llmRequestOpts()
+ if out, err := s.llmClient.Chat(ctx, messages, opts...); err == nil </span><span class="cov0" title="0">{
+ cleaned := strings.TrimSpace(stripCodeFences(out))
+ if cleaned != "" </span><span class="cov0" title="0">{ return cleaned }</span>
+ } else<span class="cov0" title="0"> {
+ logging.Logf("lsp ", "codeAction go_test llm error: %v", err)
+ }</span>
+ }
+ // Fallback stub
+ <span class="cov0" title="0">name := deriveGoFuncName(funcCode)
+ if name == "" </span><span class="cov0" title="0">{ name = "Function" }</span>
+ <span class="cov0" title="0">return fmt.Sprintf("func Test%s(t *testing.T) {\n\t// TODO: implement tests for %s\n}\n", exportName(name), name)</span>
+}
+
+// deriveGoFuncName extracts function or method name from code.
+func deriveGoFuncName(code string) string <span class="cov0" title="0">{
+ // look for line starting with func
+ line := firstLine(code)
+ line = strings.TrimSpace(line)
+ if !strings.HasPrefix(line, "func ") </span><span class="cov0" title="0">{ return "" }</span>
+ <span class="cov0" title="0">rest := strings.TrimSpace(strings.TrimPrefix(line, "func "))
+ // method receiver
+ if strings.HasPrefix(rest, "(") </span><span class="cov0" title="0">{
+ // find ")"
+ if i := strings.Index(rest, ")"); i &gt;= 0 &amp;&amp; i+1 &lt; len(rest) </span><span class="cov0" title="0">{
+ rest = strings.TrimSpace(rest[i+1:])
+ }</span>
+ }
+ // now rest should start with Name(
+ <span class="cov0" title="0">if i := strings.Index(rest, "("); i &gt; 0 </span><span class="cov0" title="0">{
+ return strings.TrimSpace(rest[:i])
+ }</span>
+ <span class="cov0" title="0">return ""</span>
+}
+
+func exportName(name string) string <span class="cov0" title="0">{
+ if name == "" </span><span class="cov0" title="0">{ return name }</span>
+ <span class="cov0" title="0">r := []rune(name)
+ if r[0] &gt;= 'a' &amp;&amp; r[0] &lt;= 'z' </span><span class="cov0" title="0">{
+ r[0] = r[0] - ('a' - 'A')
+ }</span>
+ <span class="cov0" title="0">return string(r)</span>
+}
+</pre>
+
+ <pre class="file" id="file16" style="display: none">// Summary: Completion handlers split from handlers.go to reduce file size and isolate feature logic.
+package lsp
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "codeberg.org/snonux/hexai/internal/llm"
+ "codeberg.org/snonux/hexai/internal/logging"
+ "strings"
+ "time"
+)
+
+func (s *Server) handleCompletion(req Request) <span class="cov0" title="0">{
+ var p CompletionParams
+ var docStr string
+ if err := json.Unmarshal(req.Params, &amp;p); err == nil </span><span class="cov0" title="0">{
+ // Log trigger information for every completion request from client
+ tk, tch := extractTriggerInfo(p)
+ logging.Logf("lsp ", "completion trigger kind=%d char=%q uri=%s line=%d char=%d",
+ tk, tch, p.TextDocument.URI, p.Position.Line, p.Position.Character)
+ above, current, below, funcCtx := s.lineContext(p.TextDocument.URI, p.Position)
+ docStr = s.buildDocString(p, above, current, below, funcCtx)
+ if s.logContext </span><span class="cov0" title="0">{
+ s.logCompletionContext(p, above, current, below, funcCtx)
+ }</span>
+ <span class="cov0" title="0">if s.llmClient != nil </span><span class="cov0" title="0">{
+ newFunc := s.isDefiningNewFunction(p.TextDocument.URI, p.Position)
+ extra, has := s.buildAdditionalContext(newFunc, p.TextDocument.URI, p.Position)
+ items, ok := s.tryLLMCompletion(p, above, current, below, funcCtx, docStr, has, extra)
+ if ok </span><span class="cov0" title="0">{
+ s.reply(req.ID, CompletionList{IsIncomplete: false, Items: items}, nil)
+ return
+ }</span>
+ }
+ }
+ <span class="cov0" title="0">items := s.fallbackCompletionItems(docStr)
+ s.reply(req.ID, CompletionList{IsIncomplete: false, Items: items}, nil)</span>
+}
+
+// extractTriggerInfo returns the LSP completion TriggerKind and TriggerCharacter
+// if provided by the client; when absent it returns zeros.
+func extractTriggerInfo(p CompletionParams) (kind int, ch string) <span class="cov0" title="0">{
+ if p.Context == nil </span><span class="cov0" title="0">{
+ return 0, ""
+ }</span>
+ <span class="cov0" title="0">var ctx struct {
+ TriggerKind int `json:"triggerKind"`
+ TriggerCharacter string `json:"triggerCharacter,omitempty"`
+ }
+ if raw, ok := p.Context.(json.RawMessage); ok </span><span class="cov0" title="0">{
+ _ = json.Unmarshal(raw, &amp;ctx)
+ }</span> else<span class="cov0" title="0"> {
+ b, _ := json.Marshal(p.Context)
+ _ = json.Unmarshal(b, &amp;ctx)
+ }</span>
+ <span class="cov0" title="0">return ctx.TriggerKind, ctx.TriggerCharacter</span>
+}
+
+// --- completion helpers ---
+
+func (s *Server) buildDocString(p CompletionParams, above, current, below, funcCtx string) string <span class="cov0" title="0">{
+ return fmt.Sprintf("file: %s\nline: %d\nabove: %s\ncurrent: %s\nbelow: %s\nfunction: %s",
+ p.TextDocument.URI, p.Position.Line, trimLen(above), trimLen(current), trimLen(below), trimLen(funcCtx))
+}</span>
+
+func (s *Server) logCompletionContext(p CompletionParams, above, current, below, funcCtx string) <span class="cov0" title="0">{
+ logging.Logf("lsp ", "completion ctx uri=%s line=%d char=%d above=%q current=%q below=%q function=%q",
+ p.TextDocument.URI, p.Position.Line, p.Position.Character, trimLen(above), trimLen(current), trimLen(below), trimLen(funcCtx))
+}</span>
+
+func (s *Server) tryLLMCompletion(p CompletionParams, above, current, below, funcCtx, docStr string, hasExtra bool, extraText string) ([]CompletionItem, bool) <span class="cov10" title="17">{
+ ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second)
+ defer cancel()
+
+ inlinePrompt := lineHasInlinePrompt(current)
+ if !inlinePrompt &amp;&amp; !s.isTriggerEvent(p, current) </span><span class="cov7" title="8">{
+ logging.Logf("lsp ", "%scompletion skip=no-trigger line=%d char=%d current=%q%s", logging.AnsiYellow, p.Position.Line, p.Position.Character, trimLen(current), logging.AnsiBase)
+ return []CompletionItem{}, true
+ }</span>
+ <span class="cov7" title="9">if s.shouldSuppressForChatTriggerEOL(current, p) </span><span class="cov0" title="0">{
+ return []CompletionItem{}, true
+ }</span>
+
+ <span class="cov7" title="9">inParams := inParamList(current, p.Position.Character)
+ manualInvoke := parseManualInvoke(p.Context)
+
+ // Cache fast-path
+ key := s.completionCacheKey(p, above, current, below, funcCtx, inParams, hasExtra, extraText)
+ if cleaned, ok := s.completionCacheGet(key); ok &amp;&amp; strings.TrimSpace(cleaned) != "" </span><span class="cov1" title="1">{
+ logging.Logf("lsp ", "completion cache hit uri=%s line=%d char=%d preview=%s%s%s",
+ p.TextDocument.URI, p.Position.Line, p.Position.Character,
+ logging.AnsiGreen, logging.PreviewForLog(cleaned), logging.AnsiBase)
+ return s.makeCompletionItems(cleaned, inParams, current, p, docStr), true
+ }</span>
+ <span class="cov7" title="8">if (isBareDoubleSemicolon(current) || isBareDoubleSemicolon(below)) &amp;&amp; !manualInvoke </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "%scompletion skip=empty-double-semicolon line=%d char=%d current=%q%s", logging.AnsiYellow, p.Position.Line, p.Position.Character, trimLen(current), logging.AnsiBase)
+ return []CompletionItem{}, true
+ }</span>
+
+ <span class="cov7" title="8">if !inParams &amp;&amp; !s.prefixHeuristicAllows(inlinePrompt, current, p, manualInvoke) </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "%scompletion skip=short-prefix line=%d char=%d current=%q%s", logging.AnsiYellow, p.Position.Line, p.Position.Character, trimLen(current), logging.AnsiBase)
+ return []CompletionItem{}, true
+ }</span>
+
+ // Provider-native path
+ <span class="cov7" title="8">if items, ok := s.tryProviderNativeCompletion(current, p, above, below, funcCtx, docStr, hasExtra, extraText, inParams); ok </span><span class="cov1" title="1">{
+ return items, true
+ }</span>
+
+ // Chat path
+ <span class="cov7" title="7">messages := s.buildCompletionMessages(inlinePrompt, hasExtra, extraText, inParams, p, above, current, below, funcCtx)
+ // Counters and options
+ sentSize := 0
+ for _, m := range messages </span><span class="cov9" title="14">{
+ sentSize += len(m.Content)
+ }</span>
+ <span class="cov7" title="7">s.incSentCounters(sentSize)
+ opts := []llm.RequestOption{llm.WithMaxTokens(s.maxTokens)}
+ if s.codingTemperature != nil </span><span class="cov0" title="0">{
+ opts = append(opts, llm.WithTemperature(*s.codingTemperature))
+ }</span>
+ // Debounce and throttle before making the LLM call
+ <span class="cov7" title="7">s.waitForDebounce(ctx)
+ if !s.waitForThrottle(ctx) </span><span class="cov0" title="0">{
+ return nil, false
+ }</span>
+ <span class="cov7" title="7">logging.Logf("lsp ", "completion llm=requesting model=%s", s.llmClient.DefaultModel())
+
+ text, err := s.llmClient.Chat(ctx, messages, opts...)
+ if err != nil </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "llm completion error: %v", err)
+ s.logLLMStats()
+ return nil, false
+ }</span>
+ <span class="cov7" title="7">s.incRecvCounters(len(text))
+ s.logLLMStats()
+
+ cleaned := s.postProcessCompletion(strings.TrimSpace(text), current[:p.Position.Character], current)
+ if cleaned == "" </span><span class="cov0" title="0">{
+ return nil, false
+ }</span>
+ <span class="cov7" title="7">s.completionCachePut(key, cleaned)
+ return s.makeCompletionItems(cleaned, inParams, current, p, docStr), true</span>
+}
+
+// parseManualInvoke inspects the LSP completion context and reports whether the user manually invoked completion.
+func parseManualInvoke(ctx any) bool <span class="cov7" title="9">{
+ if ctx == nil </span><span class="cov6" title="5">{
+ return false
+ }</span>
+ <span class="cov5" title="4">var c struct {
+ TriggerKind int `json:"triggerKind"`
+ }
+ if raw, ok := ctx.(json.RawMessage); ok </span><span class="cov5" title="4">{
+ _ = json.Unmarshal(raw, &amp;c)
+ }</span> else<span class="cov0" title="0"> {
+ b, _ := json.Marshal(ctx)
+ _ = json.Unmarshal(b, &amp;c)
+ }</span>
+ <span class="cov5" title="4">return c.TriggerKind == 1</span>
+}
+
+// shouldSuppressForChatTriggerEOL returns true when a chat trigger like "&gt;" follows ?, !, :, or ; at EOL.
+func (s *Server) shouldSuppressForChatTriggerEOL(current string, p CompletionParams) bool <span class="cov7" title="9">{
+ if t := strings.TrimRight(current, " \t"); len(t) &gt;= 2 &amp;&amp; t[len(t)-1] == '&gt;' </span><span class="cov0" title="0">{
+ prev := t[len(t)-2]
+ if prev == '?' || prev == '!' || prev == ':' || prev == ';' </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "completion skip=chat-trigger-eol uri=%s line=%d", p.TextDocument.URI, p.Position.Line)
+ return true
+ }</span>
+ }
+ <span class="cov7" title="9">return false</span>
+}
+
+// prefixHeuristicAllows applies minimal prefix rules unless inlinePrompt or structural triggers apply.
+func (s *Server) prefixHeuristicAllows(inlinePrompt bool, current string, p CompletionParams, manualInvoke bool) bool <span class="cov7" title="8">{
+ // Determine the effective cursor index within current line, clamped, and
+ // skip over trailing spaces/tabs to support cases like "type Matrix| ".
+ idx := p.Position.Character
+ if idx &gt; len(current) </span><span class="cov0" title="0">{
+ idx = len(current)
+ }</span>
+ <span class="cov7" title="8">allowNoPrefix := inlinePrompt
+ if idx &gt; 0 </span><span class="cov7" title="8">{
+ ch := current[idx-1]
+ if ch == '.' || ch == ':' || ch == '/' || ch == '_' || ch == ')' </span><span class="cov3" title="2">{
+ allowNoPrefix = true
+ }</span>
+ }
+ <span class="cov7" title="8">if allowNoPrefix </span><span class="cov4" title="3">{
+ return true
+ }</span>
+ // Walk left over whitespace
+ <span class="cov6" title="5">j := idx
+ for j &gt; 0 </span><span class="cov8" title="12">{
+ c := current[j-1]
+ if c == ' ' || c == '\t' </span><span class="cov7" title="7">{
+ j--
+ continue</span>
+ }
+ <span class="cov6" title="5">break</span>
+ }
+ <span class="cov6" title="5">start := computeWordStart(current, j)
+ min := 1
+ if manualInvoke &amp;&amp; s.manualInvokeMinPrefix &gt;= 0 </span><span class="cov5" title="4">{
+ min = s.manualInvokeMinPrefix
+ }</span>
+ <span class="cov6" title="5">return j-start &gt;= min</span>
+}
+
+// tryProviderNativeCompletion attempts provider-native completion and returns items when successful.
+func (s *Server) tryProviderNativeCompletion(current string, p CompletionParams, above, below, funcCtx, docStr string, hasExtra bool, extraText string, inParams bool) ([]CompletionItem, bool) <span class="cov7" title="8">{
+ cc, ok := s.llmClient.(llm.CodeCompleter)
+ if !ok </span><span class="cov6" title="6">{
+ return nil, false
+ }</span>
+ <span class="cov3" title="2">before, after := s.docBeforeAfter(p.TextDocument.URI, p.Position)
+ path := strings.TrimPrefix(p.TextDocument.URI, "file://")
+ prompt := "// Path: " + path + "\n" + before
+ lang := ""
+ temp := 0.0
+ if s.codingTemperature != nil </span><span class="cov0" title="0">{
+ temp = *s.codingTemperature
+ }</span>
+ <span class="cov3" title="2">prov := ""
+ if s.llmClient != nil </span><span class="cov3" title="2">{
+ prov = s.llmClient.Name()
+ }</span>
+ <span class="cov3" title="2">logging.Logf("lsp ", "completion path=codex provider=%s uri=%s", prov, path)
+ ctx2, cancel2 := context.WithTimeout(context.Background(), 8*time.Second)
+ defer cancel2()
+
+ // Debounce and throttle prior to provider-native call
+ s.waitForDebounce(ctx2)
+ if !s.waitForThrottle(ctx2) </span><span class="cov0" title="0">{
+ return nil, false
+ }</span>
+ <span class="cov3" title="2">suggestions, err := cc.CodeCompletion(ctx2, prompt, after, 1, lang, temp)
+ if err == nil &amp;&amp; len(suggestions) &gt; 0 </span><span class="cov1" title="1">{
+ cleaned := strings.TrimSpace(suggestions[0])
+ if cleaned != "" </span><span class="cov1" title="1">{
+ cleaned = stripDuplicateAssignmentPrefix(current[:p.Position.Character], cleaned)
+ if cleaned != "" </span><span class="cov1" title="1">{
+ cleaned = stripDuplicateGeneralPrefix(current[:p.Position.Character], cleaned)
+ }</span>
+ <span class="cov1" title="1">if cleaned != "" &amp;&amp; hasDoubleSemicolonTrigger(current) </span><span class="cov0" title="0">{
+ indent := leadingIndent(current)
+ if indent != "" </span><span class="cov0" title="0">{
+ cleaned = applyIndent(indent, cleaned)
+ }</span>
+ }
+ <span class="cov1" title="1">if strings.TrimSpace(cleaned) != "" </span><span class="cov1" title="1">{
+ key := s.completionCacheKey(p, above, current, below, funcCtx, inParams, hasExtra, extraText)
+ s.completionCachePut(key, cleaned)
+ return s.makeCompletionItems(cleaned, inParams, current, p, docStr), true
+ }</span>
+ }
+ } else<span class="cov1" title="1"> if err != nil </span><span class="cov1" title="1">{
+ logging.Logf("lsp ", "completion path=codex error=%v (falling back to chat)", err)
+ }</span>
+ <span class="cov1" title="1">return nil, false</span>
+}
+
+// waitForDebounce sleeps until there has been no input activity for at least
+// completionDebounce. If debounce is zero or ctx is done, it returns promptly.
+func (s *Server) waitForDebounce(ctx context.Context) <span class="cov7" title="9">{
+ d := s.completionDebounce
+ if d &lt;= 0 </span><span class="cov7" title="8">{
+ return
+ }</span>
+ <span class="cov1" title="1">for </span><span class="cov3" title="2">{
+ s.mu.RLock()
+ last := s.lastInput
+ s.mu.RUnlock()
+ if last.IsZero() </span><span class="cov0" title="0">{
+ return
+ }</span>
+ <span class="cov3" title="2">since := time.Since(last)
+ if since &gt;= d </span><span class="cov1" title="1">{
+ return
+ }</span>
+ <span class="cov1" title="1">rem := d - since
+ timer := time.NewTimer(rem)
+ select </span>{
+ case &lt;-ctx.Done():<span class="cov0" title="0">
+ timer.Stop()
+ return</span>
+ case &lt;-timer.C:<span class="cov1" title="1"></span>
+ // loop and re-evaluate in case input occurred during sleep
+ }
+ }
+}
+
+// waitForThrottle enforces a minimum spacing between LLM calls. Returns false
+// if the context is canceled while waiting.
+func (s *Server) waitForThrottle(ctx context.Context) bool <span class="cov7" title="9">{
+ interval := s.throttleInterval
+ if interval &lt;= 0 </span><span class="cov7" title="7">{
+ return true
+ }</span>
+ <span class="cov3" title="2">var wait time.Duration
+ for </span><span class="cov4" title="3">{
+ s.mu.Lock()
+ next := s.lastLLMCall.Add(interval)
+ now := time.Now()
+ if now.Before(next) </span><span class="cov1" title="1">{
+ wait = next.Sub(now)
+ s.mu.Unlock()
+ timer := time.NewTimer(wait)
+ select </span>{
+ case &lt;-ctx.Done():<span class="cov0" title="0">
+ timer.Stop()
+ return false</span>
+ case &lt;-timer.C:<span class="cov1" title="1">
+ // try again to set the next call time
+ continue</span>
+ }
+ }
+ // we are allowed to proceed now; record this call as the latest
+ <span class="cov3" title="2">s.lastLLMCall = now
+ s.mu.Unlock()
+ return true</span>
+ }
+}
+
+// buildCompletionMessages constructs the LLM messages for completion.
+func (s *Server) buildCompletionMessages(inlinePrompt, hasExtra bool, extraText string, inParams bool, p CompletionParams, above, current, below, funcCtx string) []llm.Message <span class="cov7" title="7">{
+ sysPrompt, userPrompt := buildPrompts(inParams, p, above, current, below, funcCtx)
+ messages := []llm.Message{
+ {Role: "system", Content: sysPrompt},
+ {Role: "user", Content: userPrompt},
+ }
+ if hasExtra &amp;&amp; extraText != "" </span><span class="cov0" title="0">{
+ messages = append(messages, llm.Message{Role: "user", Content: "Additional context:\n" + extraText})
+ }</span>
+ <span class="cov7" title="7">if inlinePrompt </span><span class="cov1" title="1">{
+ messages[0].Content = "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."
+ }</span>
+ <span class="cov7" title="7">return messages</span>
+}
+
+// postProcessCompletion normalizes and deduplicates completion text and applies indentation rules.
+func (s *Server) postProcessCompletion(text string, leftOfCursor string, currentLine string) string <span class="cov7" title="7">{
+ cleaned := stripCodeFences(text)
+ if cleaned != "" &amp;&amp; strings.ContainsRune(cleaned, '`') </span><span class="cov0" title="0">{
+ if inline := stripInlineCodeSpan(cleaned); strings.TrimSpace(inline) != "" </span><span class="cov0" title="0">{
+ cleaned = inline
+ }</span>
+ }
+ <span class="cov7" title="7">if cleaned != "" </span><span class="cov7" title="7">{
+ cleaned = stripDuplicateAssignmentPrefix(leftOfCursor, cleaned)
+ }</span>
+ <span class="cov7" title="7">if cleaned != "" </span><span class="cov7" title="7">{
+ cleaned = stripDuplicateGeneralPrefix(leftOfCursor, cleaned)
+ }</span>
+ <span class="cov7" title="7">if cleaned != "" &amp;&amp; hasDoubleSemicolonTrigger(currentLine) </span><span class="cov0" title="0">{
+ if indent := leadingIndent(currentLine); indent != "" </span><span class="cov0" title="0">{
+ cleaned = applyIndent(indent, cleaned)
+ }</span>
+ }
+ <span class="cov7" title="7">return cleaned</span>
+}
+</pre>
+
+ <pre class="file" id="file17" style="display: none">// Summary: Document open/change/close and in-editor chat handlers split out of handlers.go.
+package lsp
+
+import (
+ "context"
+ "encoding/json"
+ "codeberg.org/snonux/hexai/internal/llm"
+ "codeberg.org/snonux/hexai/internal/logging"
+ "strings"
+ "time"
+)
+
+func (s *Server) handleDidOpen(req Request) <span class="cov0" title="0">{
+ var p DidOpenTextDocumentParams
+ if err := json.Unmarshal(req.Params, &amp;p); err == nil </span><span class="cov0" title="0">{
+ s.setDocument(p.TextDocument.URI, p.TextDocument.Text)
+ s.markActivity()
+ }</span>
+}
+
+func (s *Server) handleDidChange(req Request) <span class="cov0" title="0">{
+ var p DidChangeTextDocumentParams
+ if err := json.Unmarshal(req.Params, &amp;p); err == nil </span><span class="cov0" title="0">{
+ if len(p.ContentChanges) &gt; 0 </span><span class="cov0" title="0">{
+ s.setDocument(p.TextDocument.URI, p.ContentChanges[len(p.ContentChanges)-1].Text)
+ }</span>
+ <span class="cov0" title="0">s.markActivity()
+ // Detect in-editor chat trigger lines and respond inline.
+ s.detectAndHandleChat(p.TextDocument.URI)</span>
+ }
+}
+
+func (s *Server) handleDidClose(req Request) <span class="cov0" title="0">{
+ var p DidCloseTextDocumentParams
+ if err := json.Unmarshal(req.Params, &amp;p); err == nil </span><span class="cov0" title="0">{
+ s.deleteDocument(p.TextDocument.URI)
+ s.markActivity()
+ }</span>
+}
+
+// docBeforeAfter returns the full document text split at the given position.
+// The returned strings are the text before the cursor (inclusive of anything
+// left of the position) and the text after the cursor.
+func (s *Server) docBeforeAfter(uri string, pos Position) (string, string) <span class="cov10" title="2">{
+ d := s.getDocument(uri)
+ if d == nil </span><span class="cov10" title="2">{
+ return "", ""
+ }</span>
+ // Clamp indices
+ <span class="cov0" title="0">line := pos.Line
+ if line &lt; 0 </span><span class="cov0" title="0">{
+ line = 0
+ }</span>
+ <span class="cov0" title="0">if line &gt;= len(d.lines) </span><span class="cov0" title="0">{
+ line = len(d.lines) - 1
+ }</span>
+ <span class="cov0" title="0">col := pos.Character
+ if col &lt; 0 </span><span class="cov0" title="0">{
+ col = 0
+ }</span>
+ <span class="cov0" title="0">if col &gt; len(d.lines[line]) </span><span class="cov0" title="0">{
+ col = len(d.lines[line])
+ }</span>
+ // Build before
+ <span class="cov0" title="0">var b strings.Builder
+ for i := 0; i &lt; line; i++ </span><span class="cov0" title="0">{
+ b.WriteString(d.lines[i])
+ b.WriteByte('\n')
+ }</span>
+ <span class="cov0" title="0">b.WriteString(d.lines[line][:col])
+ before := b.String()
+ // Build after
+ var a strings.Builder
+ a.WriteString(d.lines[line][col:])
+ for i := line + 1; i &lt; len(d.lines); i++ </span><span class="cov0" title="0">{
+ a.WriteByte('\n')
+ a.WriteString(d.lines[i])
+ }</span>
+ <span class="cov0" title="0">return before, a.String()</span>
+}
+
+// --- in-editor chat (";C ...") ---
+
+// detectAndHandleChat scans the current document for any line that starts with
+// a new trigger pair (e.g., "?&gt;" ",&gt;" ":&gt;" ";&gt;") at EOL and inserts the LLM
+// reply below.
+func (s *Server) detectAndHandleChat(uri string) <span class="cov0" title="0">{
+ if s.llmClient == nil </span><span class="cov0" title="0">{
+ return
+ }</span>
+ <span class="cov0" title="0">d := s.getDocument(uri)
+ if d == nil || len(d.lines) == 0 </span><span class="cov0" title="0">{
+ return
+ }</span>
+ <span class="cov0" title="0">for i, raw := range d.lines </span><span class="cov0" title="0">{
+ // Find last non-space character index
+ j := len(raw) - 1
+ for j &gt;= 0 </span><span class="cov0" title="0">{
+ if raw[j] == ' ' || raw[j] == '\t' </span><span class="cov0" title="0">{
+ j--
+ continue</span>
+ }
+ <span class="cov0" title="0">break</span>
+ }
+ <span class="cov0" title="0">if j &lt; 1 </span><span class="cov0" title="0">{
+ continue</span>
+ } // need at least two chars
+ <span class="cov0" title="0">pair := raw[j-1 : j+1]
+ isTrigger := pair == "?&gt;" || pair == "!&gt;" || pair == ":&gt;" || pair == ";&gt;"
+ if !isTrigger </span><span class="cov0" title="0">{
+ continue</span>
+ }
+ // Avoid double-answering: if the next non-empty line starts with '&gt;' we skip.
+ <span class="cov0" title="0">k := i + 1
+ for k &lt; len(d.lines) &amp;&amp; strings.TrimSpace(d.lines[k]) == "" </span><span class="cov0" title="0">{
+ k++
+ }</span>
+ <span class="cov0" title="0">if k &lt; len(d.lines) &amp;&amp; strings.HasPrefix(strings.TrimSpace(d.lines[k]), "&gt;") </span><span class="cov0" title="0">{
+ continue</span>
+ }
+ // Derive prompt by removing only the trailing '&gt;'
+ <span class="cov0" title="0">removeCount := 1
+ base := raw[:j+1-removeCount]
+ prompt := strings.TrimSpace(base)
+ if prompt == "" </span><span class="cov0" title="0">{
+ continue</span>
+ }
+ <span class="cov0" title="0">lineIdx := i
+ lastIdx := j
+ go func(prompt string, remove int) </span><span class="cov0" title="0">{
+ ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
+ defer cancel()
+ sys := "You are a helpful coding assistant. Answer concisely and clearly."
+ // Build short conversation history from the document above this line
+ history := s.buildChatHistory(uri, lineIdx, prompt)
+ msgs := append([]llm.Message{{Role: "system", Content: sys}}, history...)
+ opts := s.llmRequestOpts()
+ logging.Logf("lsp ", "chat llm=requesting model=%s", s.llmClient.DefaultModel())
+ text, err := s.llmClient.Chat(ctx, msgs, opts...)
+ if err != nil </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "chat llm error: %v", err)
+ return
+ }</span>
+ <span class="cov0" title="0">out := strings.TrimSpace(stripCodeFences(text))
+ if out == "" </span><span class="cov0" title="0">{
+ return
+ }</span>
+ <span class="cov0" title="0">s.applyChatEdits(uri, lineIdx, lastIdx, remove, "&gt; "+out)</span>
+ }(prompt, removeCount)
+ // Only handle one per change tick to avoid flooding
+ <span class="cov0" title="0">break</span>
+ }
+}
+
+// applyChatEdits removes the triggering punctuation at end of the line and
+// inserts two newlines followed by a new line with the response prefixed.
+func (s *Server) applyChatEdits(uri string, lineIdx int, lastNonSpace int, removeCount int, response string) <span class="cov0" title="0">{
+ d := s.getDocument(uri)
+ if d == nil </span><span class="cov0" title="0">{
+ return
+ }</span>
+ // 1) Delete the trailing punctuation (1 or 2 chars)
+ <span class="cov0" title="0">delStart := Position{Line: lineIdx, Character: lastNonSpace + 1 - removeCount}
+ delEnd := Position{Line: lineIdx, Character: lastNonSpace + 1}
+ // 2) Insert two newlines and the response at end-of-line, then one extra blank line
+ insPos := Position{Line: lineIdx, Character: len(d.lines[lineIdx])}
+ resp := strings.TrimRight(response, "\n") + "\n"
+ insert := "\n\n" + resp + "\n"
+ edits := []TextEdit{
+ {Range: Range{Start: delStart, End: delEnd}, NewText: ""},
+ {Range: Range{Start: insPos, End: insPos}, NewText: insert},
+ }
+ we := WorkspaceEdit{Changes: map[string][]TextEdit{uri: edits}}
+ s.clientApplyEdit("Hexai: insert chat response", we)</span>
+}
+
+// buildChatHistory walks upwards from the current line to collect the most recent
+// Q/A pairs in the in-editor transcript. Returns messages ending with current prompt.
+func (s *Server) buildChatHistory(uri string, lineIdx int, currentPrompt string) []llm.Message <span class="cov0" title="0">{
+ d := s.getDocument(uri)
+ if d == nil </span><span class="cov0" title="0">{
+ return []llm.Message{{Role: "user", Content: currentPrompt}}
+ }</span>
+ <span class="cov0" title="0">type pair struct{ q, a string }
+ pairs := []pair{}
+ i := lineIdx - 1
+ for i &gt;= 0 &amp;&amp; len(pairs) &lt; 3 </span><span class="cov0" title="0">{
+ for i &gt;= 0 &amp;&amp; strings.TrimSpace(d.lines[i]) == "" </span><span class="cov0" title="0">{
+ i--
+ }</span>
+ <span class="cov0" title="0">if i &lt; 0 </span><span class="cov0" title="0">{
+ break</span>
+ }
+ <span class="cov0" title="0">if !strings.HasPrefix(strings.TrimSpace(d.lines[i]), "&gt;") </span><span class="cov0" title="0">{
+ break</span>
+ }
+ <span class="cov0" title="0">var replyLines []string
+ for i &gt;= 0 </span><span class="cov0" title="0">{
+ line := strings.TrimSpace(d.lines[i])
+ if strings.HasPrefix(line, "&gt;") </span><span class="cov0" title="0">{
+ replyLines = append([]string{strings.TrimSpace(strings.TrimPrefix(line, "&gt;"))}, replyLines...)
+ i--
+ continue</span>
+ }
+ <span class="cov0" title="0">break</span>
+ }
+ <span class="cov0" title="0">for i &gt;= 0 &amp;&amp; strings.TrimSpace(d.lines[i]) == "" </span><span class="cov0" title="0">{
+ i--
+ }</span>
+ <span class="cov0" title="0">if i &lt; 0 </span><span class="cov0" title="0">{
+ break</span>
+ }
+ <span class="cov0" title="0">q := strings.TrimSpace(d.lines[i])
+ q = stripTrailingTrigger(q)
+ pairs = append([]pair{{q: q, a: strings.Join(replyLines, "\n")}}, pairs...)
+ i--</span>
+ }
+ <span class="cov0" title="0">msgs := make([]llm.Message, 0, len(pairs)*2+1)
+ for _, p := range pairs </span><span class="cov0" title="0">{
+ if strings.TrimSpace(p.q) != "" </span><span class="cov0" title="0">{
+ msgs = append(msgs, llm.Message{Role: "user", Content: p.q})
+ }</span>
+ <span class="cov0" title="0">if strings.TrimSpace(p.a) != "" </span><span class="cov0" title="0">{
+ msgs = append(msgs, llm.Message{Role: "assistant", Content: p.a})
+ }</span>
+ }
+ <span class="cov0" title="0">msgs = append(msgs, llm.Message{Role: "user", Content: currentPrompt})
+ return msgs</span>
+}
+
+// stripTrailingTrigger removes the trailing chat trigger punctuation from a line if present.
+func stripTrailingTrigger(sx string) string <span class="cov0" title="0">{
+ s := strings.TrimRight(sx, " \t")
+ if len(s) &gt;= 2 &amp;&amp; s[len(s)-1] == '&gt;' </span><span class="cov0" title="0">{ // new triggers
+ prev := s[len(s)-2]
+ if prev == '?' || prev == '!' || prev == ':' || prev == ';' </span><span class="cov0" title="0">{
+ return strings.TrimRight(s[:len(s)-1], " \t")
+ }</span>
+ }
+ <span class="cov0" title="0">if strings.HasSuffix(s, ";;") </span><span class="cov0" title="0">{ // legacy inline cleanup used in history building
+ return strings.TrimRight(strings.TrimSuffix(s, ";;"), " \t")
+ }</span>
+ <span class="cov0" title="0">if len(s) == 0 </span><span class="cov0" title="0">{
+ return sx
+ }</span>
+ <span class="cov0" title="0">last := s[len(s)-1]
+ switch last </span>{ // legacy: remove one trailing punctuation
+ case '?', '!', ':':<span class="cov0" title="0">
+ return strings.TrimRight(s[:len(s)-1], " \t")</span>
+ default:<span class="cov0" title="0">
+ return sx</span>
+ }
+}
+
+// clientApplyEdit sends a workspace/applyEdit request to the client.
+func (s *Server) clientApplyEdit(label string, edit WorkspaceEdit) <span class="cov0" title="0">{
+ params := ApplyWorkspaceEditParams{Label: label, Edit: edit}
+ id := s.nextReqID()
+ req := Request{JSONRPC: "2.0", ID: id, Method: "workspace/applyEdit"}
+ b, _ := json.Marshal(params)
+ req.Params = b
+ s.writeMessage(req)
+}</span>
+
+// nextReqID returns a unique json.RawMessage id for server-initiated requests.
+func (s *Server) nextReqID() json.RawMessage <span class="cov0" title="0">{
+ s.mu.Lock()
+ s.nextID++
+ idNum := s.nextID
+ s.mu.Unlock()
+ b, _ := json.Marshal(idNum)
+ return b
+}</span>
+
+// clientShowDocument asks the client to open/focus a document and select a range.
+func (s *Server) clientShowDocument(uri string, sel *Range) <span class="cov0" title="0">{
+ var params struct {
+ URI string `json:"uri"`
+ External bool `json:"external,omitempty"`
+ TakeFocus bool `json:"takeFocus,omitempty"`
+ Selection *Range `json:"selection,omitempty"`
+ }
+ params.URI = uri
+ params.TakeFocus = true
+ params.Selection = sel
+ id := s.nextReqID()
+ req := Request{JSONRPC: "2.0", ID: id, Method: "window/showDocument"}
+ b, _ := json.Marshal(params)
+ req.Params = b
+ s.writeMessage(req)
+}</span>
+
+// deferShowDocument schedules a showDocument after a short delay to allow the client
+// time to apply any pending edits (e.g., create the file before focusing it).
+func (s *Server) deferShowDocument(uri string, sel Range) <span class="cov0" title="0">{
+ go func() </span><span class="cov0" title="0">{
+ time.Sleep(120 * time.Millisecond)
+ s.clientShowDocument(uri, &amp;sel)
+ }</span>()
+}
+</pre>
+
+ <pre class="file" id="file18" style="display: none">// Summary: ExecuteCommand handler to support post-edit navigation (jump to generated test).
+package lsp
+
+import (
+ "encoding/json"
+)
+
+func (s *Server) handleExecuteCommand(req Request) <span class="cov0" title="0">{
+ var p ExecuteCommandParams
+ if err := json.Unmarshal(req.Params, &amp;p); err != nil </span><span class="cov0" title="0">{
+ s.reply(req.ID, nil, nil)
+ return
+ }</span>
+ <span class="cov0" title="0">switch p.Command </span>{
+ case "hexai.showDocument":<span class="cov0" title="0">
+ if len(p.Arguments) &gt;= 2 </span><span class="cov0" title="0">{
+ uri, _ := p.Arguments[0].(string)
+ var r Range
+ // Convert second arg to Range via re-marshal to be robust across clients
+ if b, err := json.Marshal(p.Arguments[1]); err == nil </span><span class="cov0" title="0">{
+ _ = json.Unmarshal(b, &amp;r)
+ }</span>
+ <span class="cov0" title="0">if uri != "" </span><span class="cov0" title="0">{
+ s.clientShowDocument(uri, &amp;r)
+ }</span>
+ }
+ <span class="cov0" title="0">s.reply(req.ID, nil, nil)
+ return</span>
+ default:<span class="cov0" title="0">
+ // Unknown command; no-op
+ s.reply(req.ID, nil, nil)
+ return</span>
+ }
+}
+
+</pre>
+
+ <pre class="file" id="file19" style="display: none">// Summary: Initialization and lifecycle handlers split from handlers.go.
+package lsp
+
+import (
+ "codeberg.org/snonux/hexai/internal"
+ "codeberg.org/snonux/hexai/internal/logging"
+ "os"
+)
+
+func (s *Server) handleInitialize(req Request) <span class="cov0" title="0">{
+ version := internal.Version
+ if s.llmClient != nil </span><span class="cov0" title="0">{
+ version = version + " [" + s.llmClient.Name() + ":" + s.llmClient.DefaultModel() + "]"
+ }</span>
+ <span class="cov0" title="0">res := InitializeResult{
+ Capabilities: ServerCapabilities{
+ TextDocumentSync: 1, // 1 = TextDocumentSyncKindFull
+ CompletionProvider: &amp;CompletionOptions{
+ ResolveProvider: false,
+ TriggerCharacters: s.triggerChars,
+ },
+ CodeActionProvider: CodeActionOptions{ResolveProvider: true},
+ },
+ ServerInfo: &amp;ServerInfo{Name: "hexai", Version: version},
+ }
+ s.reply(req.ID, res, nil)</span>
+}
+
+func (s *Server) handleInitialized() <span class="cov0" title="0">{
+ logging.Logf("lsp ", "client initialized")
+}</span>
+
+func (s *Server) handleShutdown(req Request) <span class="cov0" title="0">{
+ s.reply(req.ID, nil, nil)
+}</span>
+
+func (s *Server) handleExit() <span class="cov0" title="0">{
+ s.exited = true
+ os.Exit(0)
+}</span>
+</pre>
+
+ <pre class="file" id="file20" style="display: none">// Summary: Generic LSP helpers shared across handlers (LLM opts, prompts, text utils, counters).
+package lsp
+
+import (
+ "fmt"
+ "codeberg.org/snonux/hexai/internal/llm"
+ "codeberg.org/snonux/hexai/internal/logging"
+ "strings"
+ "time"
+)
+
+// llmRequestOpts builds request options from server settings.
+func (s *Server) llmRequestOpts() []llm.RequestOption <span class="cov2" title="2">{
+ opts := []llm.RequestOption{llm.WithMaxTokens(s.maxTokens)}
+ if s.codingTemperature != nil </span><span class="cov0" title="0">{
+ opts = append(opts, llm.WithTemperature(*s.codingTemperature))
+ }</span>
+ <span class="cov2" title="2">return opts</span>
+}
+
+// small helpers for LLM traffic stats
+func (s *Server) incSentCounters(n int) <span class="cov4" title="7">{
+ s.mu.Lock()
+ s.llmReqTotal++
+ s.llmSentBytesTotal += int64(n)
+ s.mu.Unlock()
+}</span>
+
+func (s *Server) incRecvCounters(n int) <span class="cov4" title="7">{
+ s.mu.Lock()
+ s.llmRespTotal++
+ s.llmRespBytesTotal += int64(n)
+ s.mu.Unlock()
+}</span>
+
+func (s *Server) logLLMStats() <span class="cov4" title="7">{
+ s.mu.RLock()
+ avgSent := int64(0)
+ if s.llmReqTotal &gt; 0 </span><span class="cov4" title="7">{
+ avgSent = s.llmSentBytesTotal / s.llmReqTotal
+ }</span>
+ <span class="cov4" title="7">avgRecv := int64(0)
+ if s.llmRespTotal &gt; 0 </span><span class="cov4" title="7">{
+ avgRecv = s.llmRespBytesTotal / s.llmRespTotal
+ }</span>
+ <span class="cov4" title="7">reqs, sentTot, recvTot := s.llmReqTotal, s.llmSentBytesTotal, s.llmRespBytesTotal
+ s.mu.RUnlock()
+ mins := time.Since(s.startTime).Minutes()
+ if mins &lt;= 0 </span><span class="cov0" title="0">{
+ mins = 0.001
+ }</span>
+ <span class="cov4" title="7">rpm := float64(reqs) / mins
+ sentPerMin := float64(sentTot) / mins
+ recvPerMin := float64(recvTot) / mins
+ logging.Logf("lsp ", "llm stats reqs=%d avg_sent=%d avg_recv=%d sent_total=%d recv_total=%d rpm=%.2f sent_per_min=%.0f recv_per_min=%.0f", reqs, avgSent, avgRecv, sentTot, recvTot, rpm, sentPerMin, recvPerMin)</span>
+}
+
+// Completion prompt builders and filters
+func inParamList(current string, cursor int) bool <span class="cov5" title="9">{
+ if !strings.Contains(current, "func ") </span><span class="cov4" title="5">{
+ return false
+ }</span>
+ <span class="cov3" title="4">open := strings.Index(current, "(")
+ close := strings.Index(current, ")")
+ return open &gt;= 0 &amp;&amp; cursor &gt; open &amp;&amp; (close == -1 || cursor &lt;= close)</span>
+}
+
+func buildPrompts(inParams bool, p CompletionParams, above, current, below, funcCtx string) (string, string) <span class="cov4" title="7">{
+ if inParams </span><span class="cov0" title="0">{
+ sys := "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."
+ user := fmt.Sprintf("Cursor is inside the function parameter list. Suggest only the parameter list (no parentheses).\nFunction line: %s\nCurrent line (cursor at %d): %s", funcCtx, p.Position.Character, current)
+ return sys, user
+ }</span>
+ <span class="cov4" title="7">sys := "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)."
+ user := fmt.Sprintf("Provide the next likely code to insert at the cursor.\nFile: %s\nFunction/context: %s\nAbove line: %s\nCurrent line (cursor at character %d): %s\nBelow line: %s\nOnly return the completion snippet.", p.TextDocument.URI, funcCtx, above, p.Position.Character, current, below)
+ return sys, user</span>
+}
+
+func computeTextEditAndFilter(cleaned string, inParams bool, current string, p CompletionParams) (*TextEdit, string) <span class="cov5" title="9">{
+ if inParams </span><span class="cov0" title="0">{
+ open := strings.Index(current, "(")
+ close := strings.Index(current, ")")
+ if open &gt;= 0 </span><span class="cov0" title="0">{
+ left := open + 1
+ right := len(current)
+ if close &gt;= 0 &amp;&amp; close &gt;= left </span><span class="cov0" title="0">{
+ right = close
+ }</span>
+ <span class="cov0" title="0">if p.Position.Character &lt; right </span><span class="cov0" title="0">{
+ right = p.Position.Character
+ }</span>
+ <span class="cov0" title="0">te := &amp;TextEdit{Range: Range{Start: Position{Line: p.Position.Line, Character: left}, End: Position{Line: p.Position.Line, Character: right}}, NewText: cleaned}
+ var filter string
+ if left &gt;= 0 &amp;&amp; right &gt;= left &amp;&amp; right &lt;= len(current) </span><span class="cov0" title="0">{
+ filter = strings.TrimLeft(current[left:right], " \t")
+ }</span>
+ <span class="cov0" title="0">return te, filter</span>
+ }
+ }
+ <span class="cov5" title="9">startChar := computeWordStart(current, p.Position.Character)
+ te := &amp;TextEdit{Range: Range{Start: Position{Line: p.Position.Line, Character: startChar}, End: Position{Line: p.Position.Line, Character: p.Position.Character}}, NewText: cleaned}
+ filter := strings.TrimLeft(current[startChar:p.Position.Character], " \t")
+ return te, filter</span>
+}
+
+func computeWordStart(current string, at int) int <span class="cov6" title="14">{
+ if at &gt; len(current) </span><span class="cov0" title="0">{
+ at = len(current)
+ }</span>
+ <span class="cov6" title="14">for at &gt; 0 </span><span class="cov7" title="22">{
+ ch := current[at-1]
+ if (ch &gt;= 'a' &amp;&amp; ch &lt;= 'z') || (ch &gt;= 'A' &amp;&amp; ch &lt;= 'Z') || (ch &gt;= '0' &amp;&amp; ch &lt;= '9') || ch == '_' </span><span class="cov5" title="9">{
+ at--
+ continue</span>
+ }
+ <span class="cov6" title="13">break</span>
+ }
+ <span class="cov6" title="14">return at</span>
+}
+
+func isIdentChar(ch byte) bool <span class="cov4" title="7">{
+ return (ch &gt;= 'a' &amp;&amp; ch &lt;= 'z') || (ch &gt;= 'A' &amp;&amp; ch &lt;= 'Z') || (ch &gt;= '0' &amp;&amp; ch &lt;= '9') || ch == '_'
+}</span>
+
+// Inline prompt utilities
+func lineHasInlinePrompt(line string) bool <span class="cov6" title="17">{
+ if _, _, _, ok := findStrictSemicolonTag(line); ok </span><span class="cov1" title="1">{
+ return true
+ }</span>
+ <span class="cov6" title="16">return hasDoubleSemicolonTrigger(line)</span>
+}
+
+func leadingIndent(line string) string <span class="cov0" title="0">{
+ i := 0
+ for i &lt; len(line) </span><span class="cov0" title="0">{
+ if line[i] == ' ' || line[i] == '\t' </span><span class="cov0" title="0">{
+ i++
+ continue</span>
+ }
+ <span class="cov0" title="0">break</span>
+ }
+ <span class="cov0" title="0">if i == 0 </span><span class="cov0" title="0">{
+ return ""
+ }</span>
+ <span class="cov0" title="0">return line[:i]</span>
+}
+
+func applyIndent(indent, suggestion string) string <span class="cov0" title="0">{
+ if indent == "" || suggestion == "" </span><span class="cov0" title="0">{
+ return suggestion
+ }</span>
+ <span class="cov0" title="0">lines := splitLines(suggestion)
+ for i, ln := range lines </span><span class="cov0" title="0">{
+ if strings.TrimSpace(ln) == "" </span><span class="cov0" title="0">{
+ continue</span>
+ }
+ <span class="cov0" title="0">if strings.HasPrefix(ln, indent) </span><span class="cov0" title="0">{
+ continue</span>
+ }
+ <span class="cov0" title="0">lines[i] = indent + ln</span>
+ }
+ <span class="cov0" title="0">return strings.Join(lines, "\n")</span>
+}
+
+// --- Inline marker parsing and general string utilities ---
+
+// findStrictSemicolonTag finds ;text; with no space after first ';' and no space
+// before the last ';' on the given line. Returns the text between semicolons,
+// the start index of the opening ';', the end index just after the closing ';',
+// and whether it was found.
+func findStrictSemicolonTag(line string) (string, int, int, bool) <span class="cov8" title="36">{
+ pos := 0
+ for pos &lt; len(line) </span><span class="cov8" title="47">{
+ j := strings.Index(line[pos:], ";")
+ if j &lt; 0 </span><span class="cov7" title="23">{
+ return "", 0, 0, false
+ }</span>
+ <span class="cov7" title="24">j += pos
+ // ensure single ';' (not ';;') and non-space after
+ if j+1 &gt;= len(line) || line[j+1] == ';' || line[j+1] == ' ' </span><span class="cov6" title="12">{
+ pos = j + 1
+ continue</span>
+ }
+ <span class="cov6" title="12">k := strings.Index(line[j+1:], ";")
+ if k &lt; 0 </span><span class="cov2" title="2">{
+ return "", 0, 0, false
+ }</span>
+ <span class="cov5" title="10">closeIdx := j + 1 + k
+ if closeIdx-1 &lt; 0 || line[closeIdx-1] == ' ' </span><span class="cov1" title="1">{
+ pos = closeIdx + 1
+ continue</span>
+ }
+ <span class="cov5" title="9">inner := strings.TrimSpace(line[j+1 : closeIdx])
+ if inner == "" </span><span class="cov0" title="0">{
+ pos = closeIdx + 1
+ continue</span>
+ }
+ <span class="cov5" title="9">end := closeIdx + 1
+ return inner, j, end, true</span>
+ }
+ <span class="cov2" title="2">return "", 0, 0, false</span>
+}
+
+// isBareDoubleSemicolon reports whether the line contains a standalone
+// double-semicolon marker with no inline content (";;" possibly with only
+// whitespace after it). It explicitly excludes the valid form ";;text;".
+func isBareDoubleSemicolon(line string) bool <span class="cov6" title="16">{
+ t := strings.TrimSpace(line)
+ if !strings.Contains(t, ";;") </span><span class="cov6" title="16">{
+ return false
+ }</span>
+ <span class="cov0" title="0">if hasDoubleSemicolonTrigger(t) </span><span class="cov0" title="0">{
+ return false
+ }</span>
+ <span class="cov0" title="0">if strings.HasPrefix(t, ";;") </span><span class="cov0" title="0">{
+ rest := strings.TrimSpace(t[2:])
+ if rest == "" || rest == ";" </span><span class="cov0" title="0">{
+ return true
+ }</span>
+ }
+ <span class="cov0" title="0">return false</span>
+}
+
+// stripDuplicateAssignmentPrefix removes a duplicated assignment prefix from the suggestion.
+func stripDuplicateAssignmentPrefix(prefixBeforeCursor, suggestion string) string <span class="cov5" title="10">{
+ s2 := strings.TrimLeft(suggestion, " \t")
+ // Prefer := if present at end of prefix
+ if idx := strings.LastIndex(prefixBeforeCursor, ":="); idx &gt;= 0 &amp;&amp; idx+2 &lt;= len(prefixBeforeCursor) </span><span class="cov1" title="1">{
+ tail := prefixBeforeCursor[idx+2:]
+ if strings.TrimSpace(tail) == "" </span><span class="cov1" title="1">{
+ start := idx - 1
+ for start &gt;= 0 &amp;&amp; (isIdentChar(prefixBeforeCursor[start]) || prefixBeforeCursor[start] == ' ' || prefixBeforeCursor[start] == '\t') </span><span class="cov4" title="5">{
+ start--
+ }</span>
+ <span class="cov1" title="1">start++
+ seg := strings.TrimRight(prefixBeforeCursor[start:idx+2], " \t")
+ if strings.HasPrefix(s2, seg) </span><span class="cov1" title="1">{
+ return strings.TrimLeft(s2[len(seg):], " \t")
+ }</span>
+ }
+ }
+ // Fallback to plain '=' if present
+ <span class="cov5" title="9">if idx := strings.LastIndex(prefixBeforeCursor, "="); idx &gt;= 0 </span><span class="cov1" title="1">{
+ if !(idx &gt; 0 &amp;&amp; prefixBeforeCursor[idx-1] == ':') </span><span class="cov1" title="1">{ // not :=
+ tail := prefixBeforeCursor[idx+1:]
+ if strings.TrimSpace(tail) == "" </span><span class="cov1" title="1">{
+ start := idx - 1
+ for start &gt;= 0 &amp;&amp; (isIdentChar(prefixBeforeCursor[start]) || prefixBeforeCursor[start] == ' ' || prefixBeforeCursor[start] == '\t') </span><span class="cov2" title="2">{
+ start--
+ }</span>
+ <span class="cov1" title="1">start++
+ seg := strings.TrimRight(prefixBeforeCursor[start:idx+1], " \t")
+ if strings.HasPrefix(s2, seg) </span><span class="cov1" title="1">{
+ return strings.TrimLeft(s2[len(seg):], " \t")
+ }</span>
+ }
+ }
+ }
+ <span class="cov5" title="8">return suggestion</span>
+}
+
+// stripDuplicateGeneralPrefix removes any already-typed prefix that the model repeated.
+func stripDuplicateGeneralPrefix(prefixBeforeCursor, suggestion string) string <span class="cov5" title="10">{
+ if suggestion == "" </span><span class="cov0" title="0">{
+ return suggestion
+ }</span>
+ <span class="cov5" title="10">s := strings.TrimLeft(suggestion, " \t")
+ p := strings.TrimRight(prefixBeforeCursor, " \t")
+ if p != "" &amp;&amp; strings.HasPrefix(s, p) </span><span class="cov2" title="2">{
+ return strings.TrimLeft(s[len(p):], " \t")
+ }</span>
+ <span class="cov5" title="8">for k := len(p) - 1; k &gt; 0; k-- </span><span class="cov10" title="85">{
+ if !isIdentBoundary(p[k-1]) </span><span class="cov9" title="68">{
+ continue</span>
+ }
+ <span class="cov6" title="17">suf := strings.TrimLeft(p[k:], " \t")
+ if suf == "" </span><span class="cov0" title="0">{
+ continue</span>
+ }
+ <span class="cov6" title="17">if strings.HasPrefix(s, suf) </span><span class="cov0" title="0">{
+ return strings.TrimLeft(s[len(suf):], " \t")
+ }</span>
+ }
+ <span class="cov5" title="8">return suggestion</span>
+}
+
+func isIdentBoundary(ch byte) bool <span class="cov10" title="85">{
+ return !((ch &gt;= 'a' &amp;&amp; ch &lt;= 'z') || (ch &gt;= 'A' &amp;&amp; ch &lt;= 'Z') || (ch &gt;= '0' &amp;&amp; ch &lt;= '9') || ch == '_')
+}</span>
+
+// stripCodeFences removes surrounding Markdown code fences from a model response.
+func stripCodeFences(s string) string <span class="cov6" title="14">{
+ t := strings.TrimSpace(s)
+ if t == "" </span><span class="cov0" title="0">{
+ return t
+ }</span>
+ <span class="cov6" title="14">lines := splitLines(t)
+ start := 0
+ for start &lt; len(lines) &amp;&amp; strings.TrimSpace(lines[start]) == "" </span><span class="cov0" title="0">{
+ start++
+ }</span>
+ <span class="cov6" title="14">end := len(lines) - 1
+ for end &gt;= 0 &amp;&amp; strings.TrimSpace(lines[end]) == "" </span><span class="cov0" title="0">{
+ end--
+ }</span>
+ <span class="cov6" title="14">if start &gt;= len(lines) || end &lt; 0 || start &gt; end </span><span class="cov0" title="0">{
+ return t
+ }</span>
+ <span class="cov6" title="14">first := strings.TrimSpace(lines[start])
+ last := strings.TrimSpace(lines[end])
+ if strings.HasPrefix(first, "```") &amp;&amp; last == "```" &amp;&amp; end &gt; start </span><span class="cov3" title="4">{
+ inner := strings.Join(lines[start+1:end], "\n")
+ return inner
+ }</span>
+ <span class="cov5" title="10">return t</span>
+}
+
+// stripInlineCodeSpan returns the contents of the first inline backtick code span if present.
+func stripInlineCodeSpan(s string) string <span class="cov4" title="6">{
+ t := strings.TrimSpace(s)
+ if t == "" </span><span class="cov0" title="0">{
+ return t
+ }</span>
+ <span class="cov4" title="6">i := strings.IndexByte(t, '`')
+ if i &lt; 0 </span><span class="cov1" title="1">{
+ return t
+ }</span>
+ <span class="cov4" title="5">jrel := strings.IndexByte(t[i+1:], '`')
+ if jrel &lt; 0 </span><span class="cov1" title="1">{
+ return t
+ }</span>
+ <span class="cov3" title="4">j := i + 1 + jrel
+ return t[i+1 : j]</span>
+}
+
+// labelForCompletion picks a short, readable label for the completion list.
+func labelForCompletion(cleaned, filter string) string <span class="cov5" title="9">{
+ label := trimLen(firstLine(cleaned))
+ if filter != "" &amp;&amp; !strings.HasPrefix(strings.ToLower(label), strings.ToLower(filter)) </span><span class="cov1" title="1">{
+ return filter
+ }</span>
+ <span class="cov5" title="8">return label</span>
+}
+
+// extractRangeText returns the exact text within the given document range.
+func extractRangeText(d *document, r Range) string <span class="cov0" title="0">{
+ if r.Start.Line == r.End.Line </span><span class="cov0" title="0">{
+ line := d.lines[r.Start.Line]
+ if r.Start.Character &lt; 0 </span><span class="cov0" title="0">{
+ r.Start.Character = 0
+ }</span>
+ <span class="cov0" title="0">if r.End.Character &gt; len(line) </span><span class="cov0" title="0">{
+ r.End.Character = len(line)
+ }</span>
+ <span class="cov0" title="0">if r.Start.Character &gt; r.End.Character </span><span class="cov0" title="0">{
+ return ""
+ }</span>
+ <span class="cov0" title="0">return line[r.Start.Character:r.End.Character]</span>
+ }
+ <span class="cov0" title="0">var b strings.Builder
+ // first line
+ first := d.lines[r.Start.Line]
+ if r.Start.Character &lt; 0 </span><span class="cov0" title="0">{
+ r.Start.Character = 0
+ }</span>
+ <span class="cov0" title="0">if r.Start.Character &gt; len(first) </span><span class="cov0" title="0">{
+ r.Start.Character = len(first)
+ }</span>
+ <span class="cov0" title="0">b.WriteString(first[r.Start.Character:])
+ b.WriteString("\n")
+ // middle lines
+ for i := r.Start.Line + 1; i &lt; r.End.Line; i++ </span><span class="cov0" title="0">{
+ b.WriteString(d.lines[i])
+ if i+1 &lt;= r.End.Line </span><span class="cov0" title="0">{
+ b.WriteString("\n")
+ }</span>
+ }
+ // last line
+ <span class="cov0" title="0">last := d.lines[r.End.Line]
+ if r.End.Character &lt; 0 </span><span class="cov0" title="0">{
+ r.End.Character = 0
+ }</span>
+ <span class="cov0" title="0">if r.End.Character &gt; len(last) </span><span class="cov0" title="0">{
+ r.End.Character = len(last)
+ }</span>
+ <span class="cov0" title="0">b.WriteString(last[:r.End.Character])
+ return b.String()</span>
+}
+
+// collectPromptRemovalEdits returns edits to remove all inline prompt markers.
+func (s *Server) collectPromptRemovalEdits(uri string) []TextEdit <span class="cov5" title="9">{
+ d := s.getDocument(uri)
+ if d == nil || len(d.lines) == 0 </span><span class="cov5" title="9">{
+ return nil
+ }</span>
+ <span class="cov0" title="0">var edits []TextEdit
+ for i, line := range d.lines </span><span class="cov0" title="0">{
+ edits = append(edits, promptRemovalEditsForLine(line, i)...)
+ }</span>
+ <span class="cov0" title="0">return edits</span>
+}
+
+func promptRemovalEditsForLine(line string, lineNum int) []TextEdit <span class="cov1" title="1">{
+ if hasDoubleSemicolonTrigger(line) </span><span class="cov1" title="1">{
+ return []TextEdit{{Range: Range{Start: Position{Line: lineNum, Character: 0}, End: Position{Line: lineNum, Character: len(line)}}, NewText: ""}}
+ }</span>
+ <span class="cov0" title="0">return collectSemicolonMarkers(line, lineNum)</span>
+}
+
+func hasDoubleSemicolonTrigger(line string) bool <span class="cov8" title="37">{
+ pos := 0
+ for pos &lt; len(line) </span><span class="cov8" title="42">{
+ j := strings.Index(line[pos:], ";;")
+ if j &lt; 0 </span><span class="cov7" title="27">{
+ return false
+ }</span>
+ <span class="cov6" title="15">j += pos
+ contentStart := j + 2
+ if contentStart &gt;= len(line) </span><span class="cov4" title="5">{
+ return false
+ }</span>
+ <span class="cov5" title="10">first := line[contentStart]
+ if first == ' ' || first == ';' </span><span class="cov4" title="5">{
+ pos = contentStart + 1
+ continue</span>
+ }
+ <span class="cov4" title="5">k := strings.Index(line[contentStart+1:], ";")
+ if k &lt; 0 </span><span class="cov0" title="0">{
+ return false
+ }</span>
+ <span class="cov4" title="5">closeIdx := contentStart + 1 + k
+ if closeIdx-1 &gt;= 0 &amp;&amp; line[closeIdx-1] == ' ' </span><span class="cov1" title="1">{
+ pos = closeIdx + 1
+ continue</span>
+ }
+ <span class="cov3" title="4">return true</span>
+ }
+ <span class="cov1" title="1">return false</span>
+}
+
+func collectSemicolonMarkers(line string, lineNum int) []TextEdit <span class="cov1" title="1">{
+ var edits []TextEdit
+ startSemi := 0
+ for startSemi &lt; len(line) </span><span class="cov3" title="3">{
+ j := strings.Index(line[startSemi:], ";")
+ if j &lt; 0 </span><span class="cov1" title="1">{
+ break</span>
+ }
+ <span class="cov2" title="2">j += startSemi
+ k := strings.Index(line[j+1:], ";")
+ if k &lt; 0 </span><span class="cov0" title="0">{
+ break</span>
+ }
+ <span class="cov2" title="2">if j+1 &gt;= len(line) || line[j+1] == ' ' </span><span class="cov0" title="0">{
+ startSemi = j + 1
+ continue</span>
+ }
+ <span class="cov2" title="2">if line[j+1] == ';' </span><span class="cov0" title="0">{
+ startSemi = j + 2
+ continue</span>
+ }
+ <span class="cov2" title="2">closeIdx := j + 1 + k
+ if closeIdx-1 &lt; 0 || line[closeIdx-1] == ' ' </span><span class="cov0" title="0">{
+ startSemi = closeIdx + 1
+ continue</span>
+ }
+ <span class="cov2" title="2">if closeIdx-(j+1) &lt; 1 </span><span class="cov0" title="0">{
+ startSemi = closeIdx + 1
+ continue</span>
+ }
+ <span class="cov2" title="2">endChar := closeIdx + 1
+ if endChar &lt; len(line) &amp;&amp; line[endChar] == ' ' </span><span class="cov2" title="2">{
+ endChar++
+ }</span>
+ <span class="cov2" title="2">edits = append(edits, TextEdit{Range: Range{Start: Position{Line: lineNum, Character: j}, End: Position{Line: lineNum, Character: endChar}}, NewText: ""})
+ startSemi = endChar</span>
+ }
+ <span class="cov1" title="1">return edits</span>
+}
+</pre>
+
+ <pre class="file" id="file21" style="display: none">// Summary: Minimal LSP server over stdio; manages documents, dispatches requests, and tracks stats.
+package lsp
+
+import (
+ "bufio"
+ "encoding/json"
+ "codeberg.org/snonux/hexai/internal/llm"
+ "codeberg.org/snonux/hexai/internal/logging"
+ "io"
+ "log"
+ "sync"
+ "time"
+)
+
+// Server implements a minimal LSP over stdio.
+type Server struct {
+ in *bufio.Reader
+ out io.Writer
+ logger *log.Logger
+ exited bool
+ mu sync.RWMutex
+ docs map[string]*document
+ logContext bool
+ llmClient llm.Client
+ lastInput time.Time
+ maxTokens int
+ contextMode string
+ windowLines int
+ maxContextTokens int
+ triggerChars []string
+ // If set, used as the LSP coding temperature for all LLM calls
+ codingTemperature *float64
+ // LLM request stats
+ llmReqTotal int64
+ llmSentBytesTotal int64
+ llmRespTotal int64
+ llmRespBytesTotal int64
+ startTime time.Time
+ // Small LRU cache for recent code completion outputs (keyed by context)
+ compCache map[string]string
+ compCacheOrder []string // most-recent at end; cap ~10
+ // Outgoing JSON-RPC id counter for server-initiated requests
+ nextID int64
+ // Minimum identifier chars required for manual invoke to bypass prefix checks
+ manualInvokeMinPrefix int
+
+ // Debounce and throttle settings
+ completionDebounce time.Duration
+ throttleInterval time.Duration
+ lastLLMCall time.Time
+
+ // Dispatch table for JSON-RPC methods → handler functions
+ handlers map[string]func(Request)
+}
+
+// ServerOptions collects configuration for NewServer to avoid long parameter lists.
+type ServerOptions struct {
+ LogContext bool
+ MaxTokens int
+ ContextMode string
+ WindowLines int
+ MaxContextTokens int
+
+ Client llm.Client
+ TriggerCharacters []string
+ CodingTemperature *float64
+ ManualInvokeMinPrefix int
+ CompletionDebounceMs int
+ CompletionThrottleMs int
+}
+
+func NewServer(r io.Reader, w io.Writer, logger *log.Logger, opts ServerOptions) *Server <span class="cov10" title="2">{
+ s := &amp;Server{in: bufio.NewReader(r), out: w, logger: logger, docs: make(map[string]*document), logContext: opts.LogContext}
+ maxTokens := opts.MaxTokens
+ if maxTokens &lt;= 0 </span><span class="cov1" title="1">{
+ maxTokens = 500
+ }</span>
+ <span class="cov10" title="2">s.maxTokens = maxTokens
+ contextMode := opts.ContextMode
+ if contextMode == "" </span><span class="cov1" title="1">{
+ contextMode = "file-on-new-func"
+ }</span>
+ <span class="cov10" title="2">windowLines := opts.WindowLines
+ if windowLines &lt;= 0 </span><span class="cov1" title="1">{
+ windowLines = 120
+ }</span>
+ <span class="cov10" title="2">maxContextTokens := opts.MaxContextTokens
+ if maxContextTokens &lt;= 0 </span><span class="cov1" title="1">{
+ maxContextTokens = 2000
+ }</span>
+ <span class="cov10" title="2">s.contextMode = contextMode
+ s.windowLines = windowLines
+ s.maxContextTokens = maxContextTokens
+
+ s.startTime = time.Now()
+ s.llmClient = opts.Client
+ if len(opts.TriggerCharacters) == 0 </span><span class="cov10" title="2">{
+ // Defaults (no space to avoid auto-trigger after whitespace)
+ s.triggerChars = []string{".", ":", "/", "_", ")", "{"}
+ }</span> else<span class="cov0" title="0"> {
+ s.triggerChars = append([]string{}, opts.TriggerCharacters...)
+ }</span>
+ <span class="cov10" title="2">s.codingTemperature = opts.CodingTemperature
+ s.compCache = make(map[string]string)
+ s.manualInvokeMinPrefix = opts.ManualInvokeMinPrefix
+ if opts.CompletionDebounceMs &gt; 0 </span><span class="cov1" title="1">{
+ s.completionDebounce = time.Duration(opts.CompletionDebounceMs) * time.Millisecond
+ }</span>
+ <span class="cov10" title="2">if opts.CompletionThrottleMs &gt; 0 </span><span class="cov0" title="0">{
+ s.throttleInterval = time.Duration(opts.CompletionThrottleMs) * time.Millisecond
+ }</span>
+ // Initialize dispatch table
+ <span class="cov10" title="2">s.handlers = map[string]func(Request){
+ "initialize": s.handleInitialize,
+ "initialized": func(_ Request) </span><span class="cov0" title="0">{ s.handleInitialized() }</span>,
+ "shutdown": s.handleShutdown,
+ "exit": func(_ Request) <span class="cov0" title="0">{ s.handleExit() }</span>,
+ "textDocument/didOpen": s.handleDidOpen,
+ "textDocument/didChange": s.handleDidChange,
+ "textDocument/didClose": s.handleDidClose,
+ "textDocument/completion": s.handleCompletion,
+ "textDocument/codeAction": s.handleCodeAction,
+ "codeAction/resolve": s.handleCodeActionResolve,
+ "workspace/executeCommand": s.handleExecuteCommand,
+ }
+ <span class="cov10" title="2">return s</span>
+}
+
+func (s *Server) Run() error <span class="cov1" title="1">{
+ for </span><span class="cov1" title="1">{
+ body, err := s.readMessage()
+ if err == io.EOF </span><span class="cov1" title="1">{
+ return nil
+ }</span>
+ <span class="cov0" title="0">if err != nil </span><span class="cov0" title="0">{
+ return err
+ }</span>
+ <span class="cov0" title="0">var req Request
+ if err := json.Unmarshal(body, &amp;req); err != nil </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "invalid JSON: %v", err)
+ continue</span>
+ }
+ <span class="cov0" title="0">if req.Method == "" </span><span class="cov0" title="0">{
+ // A response from client; ignore
+ continue</span>
+ }
+ <span class="cov0" title="0">go s.handle(req)
+ if s.exited </span><span class="cov0" title="0">{
+ return nil
+ }</span>
+ }
+}
+</pre>
+
+ <pre class="file" id="file22" style="display: none">// Summary: LSP transport utilities to read and write JSON-RPC messages with Content-Length framing.
+package lsp
+
+import (
+ "encoding/json"
+ "fmt"
+ "codeberg.org/snonux/hexai/internal/logging"
+ "io"
+ "net/textproto"
+ "strconv"
+ "strings"
+)
+
+func (s *Server) readMessage() ([]byte, error) <span class="cov8" title="1">{
+ tp := textproto.NewReader(s.in)
+ var contentLength int
+ for </span><span class="cov8" title="1">{
+ line, err := tp.ReadLine()
+ if err != nil </span><span class="cov8" title="1">{
+ return nil, err
+ }</span>
+ <span class="cov0" title="0">if line == "" </span><span class="cov0" title="0">{ // end of headers
+ break</span>
+ }
+ <span class="cov0" title="0">parts := strings.SplitN(line, ":", 2)
+ if len(parts) != 2 </span><span class="cov0" title="0">{
+ continue</span>
+ }
+ <span class="cov0" title="0">key := strings.TrimSpace(strings.ToLower(parts[0]))
+ val := strings.TrimSpace(parts[1])
+ switch key </span>{
+ case "content-length":<span class="cov0" title="0">
+ n, err := strconv.Atoi(val)
+ if err != nil </span><span class="cov0" title="0">{
+ return nil, fmt.Errorf("invalid Content-Length: %v", err)
+ }</span>
+ <span class="cov0" title="0">contentLength = n</span>
+ }
+ }
+ <span class="cov0" title="0">if contentLength &lt;= 0 </span><span class="cov0" title="0">{
+ return nil, fmt.Errorf("missing or invalid Content-Length")
+ }</span>
+ <span class="cov0" title="0">buf := make([]byte, contentLength)
+ if _, err := io.ReadFull(s.in, buf); err != nil </span><span class="cov0" title="0">{
+ return nil, err
+ }</span>
+ <span class="cov0" title="0">return buf, nil</span>
+}
+
+func (s *Server) writeMessage(v any) <span class="cov0" title="0">{
+ data, err := json.Marshal(v)
+ if err != nil </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "marshal error: %v", err)
+ return
+ }</span>
+ <span class="cov0" title="0">header := fmt.Sprintf("Content-Length: %d\r\n\r\n", len(data))
+ if _, err := io.WriteString(s.out, header); err != nil </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "write header error: %v", err)
+ return
+ }</span>
+ <span class="cov0" title="0">if _, err := s.out.Write(data); err != nil </span><span class="cov0" title="0">{
+ logging.Logf("lsp ", "write body error: %v", err)
+ return
+ }</span>
+}
+</pre>
+
+ </div>
+ </body>
+ <script>
+ (function() {
+ var files = document.getElementById('files');
+ var visible;
+ files.addEventListener('change', onChange, false);
+ function select(part) {
+ if (visible)
+ visible.style.display = 'none';
+ visible = document.getElementById(part);
+ if (!visible)
+ return;
+ files.value = part;
+ visible.style.display = 'block';
+ location.hash = part;
+ }
+ function onChange() {
+ select(files.value);
+ window.scrollTo(0, 0);
+ }
+ if (location.hash != "") {
+ select(location.hash.substr(1));
+ }
+ if (!visible) {
+ select("file0");
+ }
+ })();
+ </script>
+</html>
diff --git a/docs/coverage.out b/docs/coverage.out
new file mode 100644
index 0000000..9d67841
--- /dev/null
+++ b/docs/coverage.out
@@ -0,0 +1,5310 @@
+mode: atomic
+codeberg.org/snonux/hexai/cmd/hexai/main.go:14.13,17.18 3 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.2,22.104 1 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.104,24.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:55.29,73.2 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:77.35,79.22 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:79.22,81.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:83.5,84.19 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:84.19,87.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:87.11,88.91 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:88.91,90.10 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.5,96.53 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.53,98.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:99.5,99.15 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:103.66,105.16 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:105.16,106.43 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:106.43,108.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:109.3,109.18 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:111.2,115.45 4 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:115.45,116.20 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:116.20,118.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:119.3,119.18 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:121.2,121.22 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:124.37,127.2 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:130.39,131.25 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:131.25,133.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.2,134.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.56,136.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.2,137.34 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.34,139.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.2,140.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.32,142.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.2,143.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.32,145.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.5,146.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.39,148.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.5,149.41 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.41,151.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.5,152.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.39,152.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.5,153.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.39,153.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.2,154.38 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.38,156.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.2,157.53 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.53,159.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:163.47,164.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:164.58,166.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.2,167.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.56,169.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.2,170.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.36,172.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.2,173.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.58,175.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.2,176.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.56,178.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.2,179.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.36,181.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.2,182.59 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.59,184.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.2,185.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.57,187.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.2,188.37 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.37,190.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:193.38,195.72 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:195.72,197.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:197.8,199.17 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:199.17,201.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:202.3,202.70 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:204.5,204.27 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:211.43,216.37 3 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:216.37,216.79 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.5,217.44 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.44,219.20 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:219.20,219.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:220.9,221.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.23,221.42 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.42,221.85 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.88,221.103 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:222.9,222.23 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.5,224.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.54,226.20 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:226.20,226.41 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:227.9,228.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:228.23,229.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:229.30,229.73 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:230.13,230.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:232.9,232.24 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.5,235.50 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.50,237.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.5,238.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.51,240.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.5,241.60 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.60,243.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.5,244.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.58,246.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.5,247.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.57,249.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.5,250.64 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.64,252.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.5,253.62 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.62,255.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.5,256.62 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.62,258.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.5,259.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.63,261.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.5,262.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.57,265.33 3 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:265.33,266.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:266.51,268.14 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:270.9,270.19 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.5,272.47 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.47,274.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.5,277.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.54,277.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.5,278.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.51,278.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.5,279.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.63,279.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.5,281.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.54,281.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.5,282.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.51,282.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.5,283.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.63,283.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.5,285.55 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.55,285.93 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.5,286.52 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.52,286.88 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.5,287.64 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.64,287.106 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.5,289.13 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.13,291.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:292.5,292.16 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:13.13,17.18 4 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.2,22.79 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.79,24.3 1 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:14.13,17.18 3 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.2,22.104 1 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.104,24.3 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:13.13,17.18 4 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.2,22.79 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.79,24.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:55.29,73.2 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:77.35,79.22 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:79.22,81.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:83.5,84.19 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:84.19,87.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:87.11,88.91 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:88.91,90.10 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.5,96.53 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.53,98.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:99.5,99.15 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:103.66,105.16 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:105.16,106.43 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:106.43,108.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:109.3,109.18 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:111.2,115.45 4 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:115.45,116.20 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:116.20,118.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:119.3,119.18 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:121.2,121.22 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:124.37,127.2 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:130.39,131.25 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:131.25,133.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.2,134.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.56,136.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.2,137.34 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.34,139.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.2,140.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.32,142.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.2,143.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.32,145.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.5,146.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.39,148.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.5,149.41 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.41,151.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.5,152.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.39,152.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.5,153.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.39,153.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.2,154.38 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.38,156.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.2,157.53 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.53,159.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:163.47,164.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:164.58,166.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.2,167.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.56,169.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.2,170.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.36,172.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.2,173.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.58,175.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.2,176.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.56,178.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.2,179.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.36,181.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.2,182.59 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.59,184.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.2,185.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.57,187.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.2,188.37 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.37,190.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:193.38,195.72 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:195.72,197.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:197.8,199.17 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:199.17,201.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:202.3,202.70 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:204.5,204.27 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:211.43,216.37 3 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:216.37,216.79 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.5,217.44 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.44,219.20 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:219.20,219.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:220.9,221.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.23,221.42 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.42,221.85 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.88,221.103 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:222.9,222.23 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.5,224.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.54,226.20 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:226.20,226.41 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:227.9,228.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:228.23,229.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:229.30,229.73 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:230.13,230.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:232.9,232.24 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.5,235.50 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.50,237.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.5,238.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.51,240.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.5,241.60 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.60,243.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.5,244.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.58,246.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.5,247.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.57,249.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.5,250.64 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.64,252.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.5,253.62 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.62,255.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.5,256.62 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.62,258.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.5,259.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.63,261.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.5,262.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.57,265.33 3 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:265.33,266.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:266.51,268.14 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:270.9,270.19 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.5,272.47 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.47,274.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.5,277.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.54,277.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.5,278.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.51,278.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.5,279.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.63,279.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.5,281.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.54,281.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.5,282.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.51,282.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.5,283.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.63,283.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.5,285.55 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.55,285.93 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.5,286.52 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.52,286.88 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.5,287.64 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.64,287.106 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.5,289.13 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.13,291.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:292.5,292.16 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:22.95,27.19 4 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:27.19,30.6 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:32.2,32.64 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:37.124,39.16 2 3
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:39.16,42.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:43.2,45.74 3 3
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:45.74,48.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:49.2,49.12 1 3
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:53.64,55.82 2 7
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:55.82,58.3 2 7
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:59.2,60.9 2 7
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:61.40,62.59 1 2
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:63.23,64.24 1 1
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:65.21,66.22 1 3
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:67.10,68.91 1 1
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:73.65,88.39 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:88.39,90.6 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:92.5,93.39 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:93.39,95.6 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:96.5,96.51 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:100.48,103.40 3 5
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:103.40,105.3 1 1
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:106.2,109.3 1 5
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:113.125,116.40 3 5
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:116.40,118.56 2 2
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:118.56,121.4 2 4
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:121.18,123.4 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:124.3,124.22 1 2
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:125.8,127.17 2 3
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:127.17,129.4 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:130.3,131.26 2 3
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:133.2,136.12 3 5
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:140.59,142.2 1 4
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:25.85,27.38 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:27.38,29.17 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:29.17,31.4 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:32.3,33.22 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:35.2,37.70 3 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:42.159,49.37 6 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:49.37,51.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:52.2,52.12 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:57.49,59.30 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:59.30,61.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:64.72,65.19 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:65.19,67.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:68.2,82.39 3 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:82.39,84.6 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:86.5,87.39 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:87.39,89.6 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:90.2,90.67 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:90.67,93.3 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:93.8,96.3 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:99.57,100.20 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:100.20,102.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:103.2,103.97 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:103.97,105.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:108.97,122.2 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:66.77,67.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:67.38,69.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:70.2,70.36 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:70.36,74.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:75.2,82.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:85.109,86.39 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:86.39,88.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:90.2,90.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:90.45,92.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:93.2,94.27 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:94.27,96.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:97.2,97.19 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:97.19,99.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:100.2,102.29 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:102.29,104.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:105.2,109.16 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:109.16,112.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:114.2,117.16 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:117.16,120.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:121.2,122.57 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:122.57,124.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:125.2,126.16 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:126.16,128.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:129.2,129.27 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:129.27,132.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:133.2,135.21 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:139.46,139.66 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:140.46,140.71 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:143.102,146.29 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:146.29,148.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:149.2,149.24 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:149.24,151.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:151.8,151.31 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:151.31,154.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:155.2,155.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:155.21,157.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:158.2,158.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:158.21,160.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:161.2,161.12 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:164.130,166.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:166.19,166.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:167.5,167.31 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:167.31,167.55 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:168.5,168.32 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:171.70,172.53 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:172.53,174.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:175.2,177.74 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:177.74,180.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:181.2,182.69 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:185.91,187.64 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:187.64,190.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:191.2,191.17 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:200.66,202.85 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:202.85,204.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:205.5,205.42 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:205.42,207.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:208.5,209.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:209.19,209.33 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:210.5,214.19 5 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:214.19,214.33 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:215.5,216.56 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:216.56,218.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:219.5,220.67 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:220.67,220.81 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:221.5,221.43 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:221.43,221.95 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:223.5,224.21 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:224.21,224.63 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:225.5,227.15 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:232.42,234.23 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:234.23,234.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:235.5,236.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:236.19,237.65 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:237.65,238.57 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:238.57,238.83 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:240.9,240.27 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:242.5,244.25 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:244.25,244.47 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:245.5,245.37 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:248.42,248.100 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:252.57,268.2 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:270.58,286.2 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:288.28,291.22 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:291.22,293.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:294.5,294.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:300.153,301.42 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:301.42,301.95 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:302.5,302.48 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:302.48,302.67 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:303.5,303.15 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:303.15,303.24 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:304.5,326.19 6 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:326.19,326.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:327.5,328.56 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:328.56,330.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:332.5,335.30 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:335.30,336.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:336.45,336.55 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:337.9,338.94 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:338.94,338.104 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:339.9,339.40 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:339.40,339.72 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:341.5,342.28 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:342.28,343.66 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:343.66,343.90 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:345.5,345.20 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:44.68,45.38 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:45.38,47.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:48.2,48.36 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:48.36,50.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:51.2,57.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:60.108,62.27 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:62.27,64.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:65.2,65.19 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:65.19,67.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:69.2,73.16 5 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:73.16,75.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:77.2,80.16 4 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:80.16,83.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:84.2,85.56 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:85.56,87.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:89.2,90.64 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:90.64,93.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:94.2,94.50 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:94.50,97.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:98.2,100.21 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:104.45,104.64 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:105.45,105.70 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:108.126,110.27 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:110.27,112.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:113.2,113.19 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:113.19,115.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:117.2,121.16 5 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:121.16,123.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:125.2,128.16 4 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:128.16,131.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:132.2,133.56 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:133.56,135.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:137.2,138.6 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:138.6,140.41 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:140.41,141.30 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:141.30,142.10 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:144.4,145.14 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:147.3,147.40 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:147.40,150.4 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:151.3,151.58 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:151.58,153.4 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:154.3,154.14 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:154.14,155.9 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:158.2,159.12 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:163.76,165.29 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:165.29,167.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:168.2,168.89 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:171.109,174.29 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:174.29,176.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:177.2,178.24 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:178.24,180.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:180.8,180.31 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:180.31,182.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:183.2,183.21 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:183.21,185.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:186.2,186.21 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:186.21,188.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:189.2,189.22 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:189.22,191.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:192.2,192.12 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:195.100,197.16 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:197.16,199.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:200.2,201.29 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:204.69,205.53 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:205.53,207.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:208.2,210.43 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:210.43,213.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:214.2,215.68 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:78.76,79.38 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:79.38,81.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:82.2,82.36 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:82.36,84.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:85.2,92.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:95.108,96.20 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:96.20,98.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:99.2,100.27 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:100.27,102.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:103.2,103.19 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:103.19,105.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:106.2,110.16 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:110.16,113.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:114.2,119.16 4 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:119.16,122.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:123.2,124.56 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:124.56,126.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:127.2,128.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:128.16,130.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:131.2,131.27 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:131.27,134.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:135.2,137.21 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:141.45,141.64 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:142.45,142.70 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:146.126,147.20 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:147.20,149.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:150.2,151.27 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:151.27,153.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:154.2,154.19 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:154.19,156.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:157.2,161.16 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:161.16,164.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:165.2,170.16 4 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:170.16,173.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:174.2,175.56 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:175.56,177.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:179.2,179.64 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:179.64,181.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:182.2,183.12 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:187.56,187.104 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:190.76,192.29 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:192.29,194.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:195.2,195.89 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:198.105,201.29 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:201.29,203.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:204.2,204.24 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:204.24,206.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:206.8,206.31 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:206.31,209.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:210.2,210.21 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:210.21,212.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:213.2,213.21 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:213.21,215.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:216.2,216.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:219.127,221.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:221.16,223.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:224.2,225.28 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:225.28,227.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:228.2,228.29 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:231.152,233.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:233.16,235.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:236.2,238.28 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:238.28,240.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:241.2,241.29 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:244.69,245.53 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:245.53,247.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:248.2,250.55 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:250.55,253.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:254.2,255.68 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:258.85,260.64 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:260.64,263.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:264.2,264.17 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:267.90,273.21 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:273.21,275.41 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:275.41,276.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:278.3,279.45 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:279.45,280.9 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:282.3,283.65 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:283.65,284.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:286.3,286.54 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:286.54,289.4 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:290.3,290.36 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:290.36,291.30 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:291.30,293.5 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:296.2,296.38 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:296.38,299.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:300.2,300.12 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:58.47,58.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:58.73,58.92 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:59.47,59.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:59.73,59.94 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:60.47,60.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:60.73,60.92 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:61.45,62.26 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:62.26,62.66 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:85.84,87.16 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:87.16,89.6 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:90.5,90.14 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:91.19,92.50 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:92.50,94.10 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:96.9,96.41 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:96.41,99.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:100.9,100.103 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:101.19,102.41 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:102.41,105.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:106.9,106.89 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:107.20,108.51 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:108.51,110.10 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:111.9,111.42 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:111.42,114.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:115.9,115.108 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:116.13,117.61 1 0
+codeberg.org/snonux/hexai/internal/llm/util.go:6.47,6.77 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:9.48,11.2 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:17.4,19.12 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:19.12,21.3 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:22.2,24.29 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:24.29,27.3 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:27.26,27.37 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:30.47,31.16 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:31.16,33.3 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:34.2,35.48 2 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:43.32,43.55 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:46.37,47.25 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:47.25,48.32 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:48.32,50.4 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:51.3,51.37 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:53.2,53.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:15.96,17.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:18.17,19.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:20.16,21.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:22.26,23.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:23.14,25.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:26.3,26.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:27.21,28.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:29.10,31.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:35.65,37.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:37.35,40.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:41.2,44.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:44.15,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:47.2,48.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:48.13,50.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:51.2,52.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:55.53,57.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:57.14,60.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:61.2,61.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:66.64,67.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:67.20,69.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:70.2,71.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:71.27,73.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:75.2,76.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:76.21,78.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:79.2,79.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:79.53,81.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:82.2,82.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:15.48,19.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:21.45,25.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:27.33,31.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:33.52,37.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:40.37,43.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:45.96,47.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:47.35,49.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:50.2,51.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:51.13,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:54.2,54.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:54.25,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:57.2,58.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:58.16,60.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:61.2,61.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:61.26,63.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:64.2,64.28 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:64.28,66.85 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:66.85,68.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:71.2,71.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:78.71,80.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:80.35,82.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:83.2,84.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:84.13,86.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:87.2,87.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:87.25,89.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:91.2,92.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:92.28,93.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:93.44,95.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:98.3,98.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:98.40,99.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:102.2,102.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:102.20,104.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:106.2,106.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:106.35,109.17 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:109.17,110.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:110.15,112.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:114.4,114.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:114.29,116.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:119.2,119.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:122.46,123.28 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:123.28,124.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:124.29,126.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:128.2,128.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:131.31,133.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:133.18,135.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:136.2,136.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:139.33,141.49 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:141.49,143.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:144.2,144.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:10.38,11.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:11.41,14.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:15.2,15.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:15.22,17.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:28.60,30.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:30.31,31.99 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:31.99,34.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:36.2,36.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:48.86,54.53 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:54.53,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:57.2,57.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:57.44,58.51 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:58.51,63.4 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:65.2,65.46 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:65.46,66.52 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:66.52,71.4 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:73.2,73.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:73.44,75.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:76.2,76.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:76.43,78.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:79.2,79.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:79.44,81.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:82.2,82.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:82.21,84.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:86.2,87.30 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:87.30,88.63 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:88.63,90.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:92.2,93.33 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:117.72,120.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:191.151,194.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:194.24,196.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:197.2,199.24 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:199.24,201.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:202.2,204.24 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:204.24,207.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:208.2,209.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:209.32,211.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:212.2,213.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:213.14,215.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:217.2,231.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:234.64,238.9 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:238.9,240.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:242.2,243.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:246.56,249.24 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:249.24,251.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:252.2,252.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:252.44,255.33 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:255.33,260.4 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:261.3,261.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:264.2,265.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:268.51,272.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:272.37,273.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:273.15,275.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:278.2,278.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:278.14,280.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:281.2,281.50 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:288.74,290.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:290.22,295.49 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:295.49,297.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:297.9,300.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:302.9,302.83 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:302.83,304.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:306.9,306.33 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:306.33,308.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:310.3,310.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:310.27,311.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:311.34,312.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:312.38,313.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:313.35,315.7 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:317.5,317.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:320.4,320.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:325.2,326.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:326.36,328.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:330.2,330.76 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:330.76,332.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:333.2,334.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:334.35,335.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:335.14,337.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:339.2,339.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:342.137,347.24 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:347.24,349.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:350.2,360.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:435.74,444.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:16.48,18.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:18.55,19.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:19.23,21.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:22.3,22.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:24.2,25.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:25.57,26.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:26.23,28.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:29.3,29.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:31.5,34.56 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:34.56,36.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:37.5,37.60 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:37.60,39.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:40.5,40.57 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:40.57,42.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:43.5,43.54 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:43.54,45.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:46.5,46.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:46.25,48.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:51.85,52.85 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:52.85,63.3 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:64.2,64.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:67.89,69.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:69.21,71.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:72.2,81.12 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:84.70,85.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:85.45,87.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:88.2,96.58 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:96.58,98.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:99.5,99.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:100.20,107.72 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:107.72,108.66 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:108.66,112.5 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:113.9,115.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:116.24,120.43 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:120.43,121.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:121.24,123.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:123.10,125.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:127.3,133.72 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:133.72,134.66 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:134.66,138.5 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:139.9,141.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:142.21,149.78 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:149.78,150.75 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:150.75,154.14 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:155.15,157.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:158.20,159.98 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:159.98,167.10 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:169.5,169.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:172.55,174.56 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:174.56,175.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:175.23,177.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:178.3,178.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:180.2,180.49 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:180.49,183.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:184.2,184.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:190.85,191.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:191.22,193.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:194.2,195.53 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:195.53,197.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:198.2,198.31 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:198.31,200.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:201.2,202.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:202.36,203.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:203.34,205.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:207.2,207.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:211.37,213.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:213.32,215.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:216.2,216.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:216.32,218.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:220.2,220.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:220.29,222.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:224.2,224.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:224.29,226.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:227.2,227.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:230.34,231.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:231.22,233.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:234.2,234.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:237.37,238.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:238.22,240.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:241.2,241.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:246.76,248.83 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:248.83,250.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:252.5,252.74 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:252.74,254.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:256.5,257.44 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:257.44,259.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:260.5,267.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:271.86,272.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:272.27,274.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:275.5,275.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:275.37,277.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:278.5,286.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:289.95,291.79 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:291.79,293.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:295.5,296.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:296.24,298.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:299.5,301.39 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:301.39,303.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:304.5,306.42 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:306.42,308.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:310.5,314.29 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:314.29,320.28 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:320.28,323.10 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:324.9,326.108 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:326.108,328.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:329.9,336.46 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:336.46,336.62 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:337.9,339.25 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:339.25,339.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:340.9,341.39 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:344.5,345.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:345.18,345.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:346.5,361.16 13 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:361.16,364.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:365.5,366.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:370.62,371.42 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:371.42,373.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:374.5,376.19 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:376.19,378.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:379.5,380.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:383.35,384.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:384.44,386.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:387.5,387.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:391.48,392.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:392.30,394.45 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:394.45,397.54 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:397.54,397.73 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:398.13,398.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:398.55,398.74 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:399.13,399.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:399.55,399.93 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:400.13,400.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:403.5,403.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:407.63,408.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:408.16,408.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:409.5,409.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:409.26,409.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:411.5,412.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:412.31,413.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:413.48,415.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:417.9,417.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:417.44,418.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:421.5,421.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:421.20,421.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:423.5,425.41 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:425.41,427.38 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:427.38,428.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:429.22,431.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:432.22,433.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:433.30,433.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:434.17,434.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:434.43,436.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:441.5,441.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:441.18,443.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:444.5,444.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:448.65,449.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:449.27,456.77 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:456.77,458.30 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:458.30,458.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:459.15,461.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:464.5,465.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:465.19,465.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:466.5,466.118 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:470.43,474.42 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:474.42,474.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:475.5,477.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:477.37,479.69 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:479.69,481.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:484.5,484.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:484.45,486.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:487.5,487.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:490.37,491.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:491.19,491.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:492.5,493.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:493.35,495.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:496.5,496.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:14.48,17.55 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:17.55,24.19 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:24.19,26.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:27.3,27.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:27.25,31.10 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:31.10,34.5 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:37.2,38.73 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:43.67,44.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:44.22,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:47.2,51.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:51.48,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:53.8,56.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:57.2,57.46 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:62.99,65.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:67.98,70.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:72.160,77.52 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:77.52,80.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:81.2,81.51 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:81.51,83.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:85.2,90.86 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:90.86,95.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:96.2,96.87 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:96.87,99.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:101.2,101.83 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:101.83,104.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:107.5,107.129 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:107.129,109.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:112.2,115.29 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:115.29,117.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:118.2,120.32 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:120.32,122.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:124.5,125.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:125.32,127.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:128.5,131.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:131.16,135.3 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:136.2,140.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:140.19,142.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:143.2,144.75 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:148.38,149.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:149.16,151.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:152.2,155.42 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:155.42,157.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:157.8,160.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:161.2,161.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:165.91,166.79 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:166.79,168.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:168.63,171.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:173.2,173.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:177.119,181.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:181.24,183.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:184.2,185.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:185.13,187.68 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:187.68,189.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:191.2,191.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:191.19,193.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:195.2,196.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:196.12,198.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:198.28,200.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:202.3,202.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:204.2,206.50 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:206.50,208.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:209.2,209.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:213.193,215.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:215.9,217.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:218.2,223.32 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:223.32,225.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:226.2,227.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:227.24,229.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:230.2,236.33 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:236.33,238.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:239.5,240.40 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:240.40,242.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:242.20,244.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:244.21,246.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:247.4,247.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:247.59,249.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:249.21,251.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:253.4,253.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:253.40,257.5 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:259.8,259.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:259.23,261.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:262.2,262.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:267.55,269.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:269.15,271.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:272.5,272.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:272.9,276.26 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:276.26,278.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:279.9,280.23 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:280.23,282.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:283.9,285.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:286.27,288.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:289.24,289.24 0 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:297.60,299.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:299.22,301.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:302.5,303.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:303.9,307.29 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:307.29,311.20 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:312.31,314.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:315.28,317.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:321.9,323.20 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:328.177,334.33 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:334.33,336.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:337.2,337.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:337.18,339.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:340.2,340.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:344.101,346.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:346.57,347.78 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:347.78,349.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:351.2,351.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:351.19,353.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:354.2,354.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:354.19,356.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:357.2,357.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:357.61,358.57 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:358.57,360.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:362.2,362.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:13.45,15.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:15.55,18.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:21.47,23.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:23.55,24.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:24.32,26.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:27.3,29.44 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:33.46,35.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:35.55,38.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:44.76,46.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:46.14,48.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:50.2,51.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:51.14,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:54.2,54.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:54.26,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:57.2,58.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:58.13,60.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:61.2,61.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:61.30,63.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:65.2,66.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:66.28,69.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:70.2,75.43 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:75.43,78.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:79.2,79.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:87.50,88.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:88.24,90.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:91.2,92.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:92.35,94.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:95.2,95.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:95.30,98.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:98.14,99.39 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:99.39,101.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:103.4,103.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:105.3,105.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:105.12,106.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:108.3,110.17 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:110.17,111.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:114.3,115.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:115.63,117.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:118.3,118.80 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:118.80,119.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:122.3,125.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:125.19,126.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:128.3,130.38 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:130.38,140.18 9 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:140.18,143.5 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:144.4,145.17 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:145.17,147.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:148.4,148.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:151.3,151.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:157.110,159.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:159.14,161.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:163.2,174.54 8 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:179.96,181.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:181.14,183.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:184.2,187.31 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:187.31,188.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:188.53,190.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:191.3,191.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:191.12,192.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:194.3,194.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:194.61,195.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:197.3,198.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:198.14,200.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:200.36,203.13 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:205.4,205.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:207.3,207.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:207.53,209.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:210.3,210.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:210.12,211.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:213.3,216.6 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:218.2,219.26 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:219.26,220.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:220.35,222.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:223.3,223.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:223.35,225.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:227.2,228.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:232.45,234.39 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:234.39,236.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:236.63,238.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:240.2,240.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:240.32,242.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:243.2,243.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:243.17,245.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:246.2,247.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:248.21,249.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:250.10,251.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:256.68,263.2 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:266.46,273.2 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:276.61,291.2 9 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:295.59,296.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:296.15,299.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:8.52,10.58 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:10.58,13.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:14.5,14.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:15.31,16.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:16.34,20.67 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:20.67,22.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:23.13,23.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:23.26,25.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:27.9,28.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:29.13,32.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:10.48,12.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:12.24,14.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:15.2,26.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:29.38,31.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:33.46,35.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:37.31,40.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:13.55,15.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:15.32,17.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:18.2,18.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:22.41,27.2 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:29.41,34.2 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:36.32,39.23 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:39.23,41.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:42.2,43.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:43.24,45.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:46.2,49.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:49.15,51.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:52.2,55.211 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:59.51,60.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:60.41,62.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:63.2,65.71 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:68.110,69.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:69.14,73.3 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:74.2,76.18 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:79.118,80.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:80.14,83.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:83.16,86.35 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:86.35,88.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:89.4,89.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:89.36,91.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:92.4,94.59 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:94.59,96.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:97.4,97.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:100.2,103.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:106.51,107.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:107.23,109.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:110.2,110.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:110.13,112.100 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:112.100,114.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:116.3,116.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:118.2,118.11 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:121.32,123.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:126.44,127.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:127.53,129.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:130.2,130.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:133.40,135.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:135.20,136.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:136.40,138.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:140.3,140.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:142.2,142.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:142.12,144.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:145.2,145.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:148.52,149.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:149.38,151.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:152.2,153.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:153.27,154.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:154.34,155.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:157.3,157.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:157.36,158.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:160.3,160.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:162.2,162.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:171.67,173.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:173.22,175.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:175.12,177.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:178.3,180.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:180.63,182.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:184.3,185.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:185.12,187.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:188.3,189.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:189.48,191.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:193.3,194.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:194.18,196.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:198.3,199.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:201.2,201.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:207.46,209.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:209.32,211.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:212.2,212.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:212.34,214.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:215.2,215.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:215.32,217.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:217.32,219.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:221.2,221.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:225.83,228.102 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:228.102,230.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:230.36,232.136 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:232.136,234.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:235.4,237.34 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:237.34,239.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:243.2,243.65 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:243.65,244.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:244.53,246.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:246.37,248.137 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:248.137,250.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:251.5,253.35 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:253.35,255.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:259.2,259.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:263.80,264.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:264.22,266.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:267.2,269.40 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:269.40,271.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:272.2,272.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:272.34,273.31 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:273.31,274.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:276.3,277.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:277.16,278.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:280.3,280.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:280.32,282.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:284.2,284.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:287.36,289.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:292.39,294.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:294.13,296.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:297.2,299.66 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:299.66,301.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:302.2,303.54 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:303.54,305.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:306.2,306.51 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:306.51,308.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:309.2,311.69 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:311.69,314.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:315.2,315.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:319.43,321.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:321.13,323.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:324.2,325.11 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:325.11,327.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:328.2,329.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:329.14,331.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:332.2,333.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:337.56,339.89 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:339.89,341.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:342.2,342.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:346.52,347.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:347.32,349.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:349.28,351.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:352.3,352.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:352.34,354.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:355.3,355.42 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:355.42,357.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:358.3,358.49 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:360.2,363.27 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:363.27,365.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:366.2,366.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:366.36,368.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:369.2,372.49 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:372.49,374.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:374.24,376.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:379.2,380.25 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:380.25,382.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:383.2,383.33 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:383.33,385.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:386.2,387.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:391.67,393.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:393.35,395.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:396.2,397.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:397.31,399.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:400.2,400.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:403.69,404.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:404.37,406.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:407.2,407.47 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:410.50,412.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:412.22,414.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:414.12,416.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:417.3,419.32 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:419.32,421.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:422.3,423.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:423.35,425.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:427.3,428.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:428.12,430.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:431.3,432.49 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:432.49,434.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:436.3,436.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:438.2,438.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:441.67,444.28 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:444.28,446.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:446.12,447.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:449.3,451.12 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:451.12,452.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:454.3,454.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:454.43,456.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:458.3,458.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:458.23,460.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:462.3,463.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:463.48,465.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:467.3,467.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:467.25,469.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:471.3,472.50 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:472.50,474.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:475.3,476.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:478.2,478.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:72.90,75.20 3 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:75.20,77.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:78.2,80.23 3 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:80.23,82.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:83.2,84.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:84.22,86.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:87.2,88.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:88.27,90.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:91.2,97.38 6 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:97.38,100.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:100.8,102.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:103.5,106.38 4 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:106.38,108.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:109.5,109.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:109.38,111.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:113.2,115.46 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:115.46,115.71 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:117.46,117.64 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:126.2,126.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:129.30,130.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:130.6,132.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:132.20,134.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:135.3,135.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:135.17,137.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:138.3,139.52 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:139.52,141.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:143.3,143.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:143.23,145.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:147.3,148.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:148.15,150.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:14.48,17.6 3 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:17.6,19.17 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:19.17,21.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:22.3,22.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:22.17,23.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:25.3,26.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:26.22,27.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:29.3,31.14 3 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:32.25,34.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:34.18,36.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:37.4,37.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:40.2,40.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:40.24,42.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:43.2,44.50 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:44.50,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:47.2,47.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:50.38,52.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:52.16,55.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:56.2,57.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:57.57,60.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:61.2,61.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:61.45,64.3 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:9.48,11.2 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:17.4,19.12 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:19.12,21.3 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:22.2,24.29 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:24.29,27.3 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:27.26,27.37 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:30.47,31.16 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:31.16,33.3 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:34.2,35.48 2 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:43.32,43.55 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:46.37,47.25 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:47.25,48.32 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:48.32,50.4 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:51.3,51.37 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:53.2,53.10 1 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:14.13,17.18 3 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.2,22.104 1 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.104,24.3 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:13.13,17.18 4 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.2,22.79 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.79,24.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:55.29,73.2 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:77.35,79.22 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:79.22,81.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:83.5,84.19 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:84.19,87.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:87.11,88.91 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:88.91,90.10 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.5,96.53 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.53,98.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:99.5,99.15 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:103.66,105.16 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:105.16,106.43 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:106.43,108.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:109.3,109.18 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:111.2,115.45 4 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:115.45,116.20 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:116.20,118.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:119.3,119.18 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:121.2,121.22 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:124.37,127.2 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:130.39,131.25 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:131.25,133.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.2,134.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.56,136.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.2,137.34 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.34,139.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.2,140.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.32,142.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.2,143.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.32,145.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.5,146.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.39,148.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.5,149.41 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.41,151.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.5,152.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.39,152.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.5,153.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.39,153.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.2,154.38 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.38,156.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.2,157.53 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.53,159.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:163.47,164.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:164.58,166.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.2,167.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.56,169.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.2,170.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.36,172.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.2,173.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.58,175.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.2,176.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.56,178.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.2,179.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.36,181.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.2,182.59 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.59,184.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.2,185.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.57,187.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.2,188.37 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.37,190.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:193.38,195.72 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:195.72,197.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:197.8,199.17 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:199.17,201.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:202.3,202.70 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:204.5,204.27 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:211.43,216.37 3 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:216.37,216.79 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.5,217.44 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.44,219.20 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:219.20,219.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:220.9,221.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.23,221.42 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.42,221.85 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.88,221.103 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:222.9,222.23 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.5,224.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.54,226.20 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:226.20,226.41 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:227.9,228.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:228.23,229.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:229.30,229.73 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:230.13,230.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:232.9,232.24 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.5,235.50 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.50,237.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.5,238.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.51,240.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.5,241.60 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.60,243.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.5,244.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.58,246.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.5,247.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.57,249.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.5,250.64 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.64,252.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.5,253.62 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.62,255.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.5,256.62 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.62,258.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.5,259.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.63,261.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.5,262.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.57,265.33 3 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:265.33,266.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:266.51,268.14 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:270.9,270.19 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.5,272.47 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.47,274.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.5,277.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.54,277.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.5,278.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.51,278.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.5,279.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.63,279.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.5,281.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.54,281.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.5,282.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.51,282.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.5,283.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.63,283.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.5,285.55 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.55,285.93 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.5,286.52 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.52,286.88 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.5,287.64 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.64,287.106 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.5,289.13 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.13,291.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:292.5,292.16 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:22.95,27.19 4 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:27.19,30.6 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:32.2,32.64 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:37.124,39.16 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:39.16,42.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:43.2,45.74 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:45.74,48.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:49.2,49.12 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:53.64,55.82 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:55.82,58.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:59.2,60.9 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:61.40,62.59 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:63.23,64.24 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:65.21,66.22 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:67.10,68.91 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:73.65,88.39 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:88.39,90.6 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:92.5,93.39 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:93.39,95.6 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:96.5,96.51 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:100.48,103.40 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:103.40,105.3 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:106.2,109.3 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:113.125,116.40 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:116.40,118.56 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:118.56,121.4 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:121.18,123.4 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:124.3,124.22 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:125.8,127.17 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:127.17,129.4 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:130.3,131.26 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:133.2,136.12 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:140.59,142.2 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:25.85,27.38 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:27.38,29.17 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:29.17,31.4 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:32.3,33.22 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:35.2,37.70 3 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:42.159,49.37 6 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:49.37,51.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:52.2,52.12 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:57.49,59.30 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:59.30,61.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:64.72,65.19 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:65.19,67.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:68.2,82.39 3 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:82.39,84.6 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:86.5,87.39 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:87.39,89.6 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:90.2,90.67 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:90.67,93.3 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:93.8,96.3 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:99.57,100.20 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:100.20,102.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:103.2,103.97 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:103.97,105.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:108.97,122.2 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:66.77,67.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:67.38,69.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:70.2,70.36 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:70.36,74.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:75.2,82.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:85.109,86.39 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:86.39,88.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:90.2,90.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:90.45,92.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:93.2,94.27 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:94.27,96.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:97.2,97.19 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:97.19,99.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:100.2,102.29 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:102.29,104.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:105.2,109.16 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:109.16,112.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:114.2,117.16 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:117.16,120.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:121.2,122.57 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:122.57,124.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:125.2,126.16 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:126.16,128.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:129.2,129.27 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:129.27,132.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:133.2,135.21 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:139.46,139.66 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:140.46,140.71 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:143.102,146.29 3 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:146.29,148.3 1 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:149.2,149.24 1 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:149.24,151.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:151.8,151.31 1 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:151.31,154.3 2 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:155.2,155.21 1 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:155.21,157.3 1 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:158.2,158.21 1 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:158.21,160.3 1 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:161.2,161.12 1 1
+codeberg.org/snonux/hexai/internal/llm/copilot.go:164.130,166.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:166.19,166.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:167.5,167.31 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:167.31,167.55 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:168.5,168.32 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:171.70,172.53 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:172.53,174.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:175.2,177.74 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:177.74,180.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:181.2,182.69 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:185.91,187.64 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:187.64,190.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:191.2,191.17 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:200.66,202.85 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:202.85,204.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:205.5,205.42 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:205.42,207.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:208.5,209.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:209.19,209.33 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:210.5,214.19 5 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:214.19,214.33 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:215.5,216.56 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:216.56,218.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:219.5,220.67 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:220.67,220.81 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:221.5,221.43 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:221.43,221.95 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:223.5,224.21 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:224.21,224.63 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:225.5,227.15 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:232.42,234.23 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:234.23,234.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:235.5,236.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:236.19,237.65 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:237.65,238.57 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:238.57,238.83 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:240.9,240.27 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:242.5,244.25 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:244.25,244.47 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:245.5,245.37 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:248.42,248.100 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:252.57,268.2 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:270.58,286.2 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:288.28,291.22 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:291.22,293.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:294.5,294.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:300.153,301.42 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:301.42,301.95 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:302.5,302.48 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:302.48,302.67 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:303.5,303.15 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:303.15,303.24 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:304.5,326.19 6 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:326.19,326.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:327.5,328.56 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:328.56,330.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:332.5,335.30 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:335.30,336.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:336.45,336.55 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:337.9,338.94 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:338.94,338.104 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:339.9,339.40 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:339.40,339.72 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:341.5,342.28 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:342.28,343.66 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:343.66,343.90 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:345.5,345.20 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:44.68,45.38 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:45.38,47.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:48.2,48.36 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:48.36,50.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:51.2,57.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:60.108,62.27 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:62.27,64.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:65.2,65.19 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:65.19,67.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:69.2,73.16 5 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:73.16,75.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:77.2,80.16 4 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:80.16,83.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:84.2,85.56 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:85.56,87.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:89.2,90.64 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:90.64,93.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:94.2,94.50 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:94.50,97.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:98.2,100.21 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:104.45,104.64 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:105.45,105.70 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:108.126,110.27 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:110.27,112.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:113.2,113.19 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:113.19,115.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:117.2,121.16 5 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:121.16,123.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:125.2,128.16 4 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:128.16,131.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:132.2,133.56 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:133.56,135.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:137.2,138.6 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:138.6,140.41 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:140.41,141.30 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:141.30,142.10 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:144.4,145.14 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:147.3,147.40 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:147.40,150.4 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:151.3,151.58 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:151.58,153.4 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:154.3,154.14 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:154.14,155.9 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:158.2,159.12 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:163.76,165.29 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:165.29,167.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:168.2,168.89 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:171.109,174.29 3 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:174.29,176.3 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:177.2,178.24 2 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:178.24,180.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:180.8,180.31 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:180.31,182.3 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:183.2,183.21 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:183.21,185.3 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:186.2,186.21 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:186.21,188.3 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:189.2,189.22 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:189.22,191.3 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:192.2,192.12 1 2
+codeberg.org/snonux/hexai/internal/llm/ollama.go:195.100,197.16 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:197.16,199.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:200.2,201.29 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:204.69,205.53 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:205.53,207.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:208.2,210.43 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:210.43,213.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:214.2,215.68 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:78.76,79.38 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:79.38,81.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:82.2,82.36 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:82.36,84.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:85.2,92.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:95.108,96.20 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:96.20,98.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:99.2,100.27 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:100.27,102.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:103.2,103.19 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:103.19,105.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:106.2,110.16 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:110.16,113.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:114.2,119.16 4 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:119.16,122.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:123.2,124.56 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:124.56,126.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:127.2,128.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:128.16,130.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:131.2,131.27 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:131.27,134.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:135.2,137.21 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:141.45,141.64 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:142.45,142.70 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:146.126,147.20 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:147.20,149.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:150.2,151.27 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:151.27,153.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:154.2,154.19 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:154.19,156.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:157.2,161.16 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:161.16,164.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:165.2,170.16 4 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:170.16,173.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:174.2,175.56 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:175.56,177.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:179.2,179.64 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:179.64,181.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:182.2,183.12 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:187.56,187.104 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:190.76,192.29 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:192.29,194.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:195.2,195.89 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:198.105,201.29 3 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:201.29,203.3 1 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:204.2,204.24 1 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:204.24,206.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:206.8,206.31 1 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:206.31,209.3 2 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:210.2,210.21 1 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:210.21,212.3 1 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:213.2,213.21 1 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:213.21,215.3 1 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:216.2,216.12 1 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:219.127,221.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:221.16,223.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:224.2,225.28 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:225.28,227.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:228.2,228.29 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:231.152,233.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:233.16,235.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:236.2,238.28 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:238.28,240.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:241.2,241.29 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:244.69,245.53 1 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:245.53,247.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:248.2,250.55 3 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:250.55,253.3 2 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:254.2,255.68 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:258.85,260.64 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:260.64,263.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:264.2,264.17 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:267.90,273.21 5 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:273.21,275.41 2 3
+codeberg.org/snonux/hexai/internal/llm/openai.go:275.41,276.12 1 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:278.3,279.45 2 2
+codeberg.org/snonux/hexai/internal/llm/openai.go:279.45,280.9 1 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:282.3,283.65 2 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:283.65,284.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:286.3,286.54 1 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:286.54,289.4 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:290.3,290.36 1 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:290.36,291.30 1 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:291.30,293.5 1 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:296.2,296.38 1 1
+codeberg.org/snonux/hexai/internal/llm/openai.go:296.38,299.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:300.2,300.12 1 1
+codeberg.org/snonux/hexai/internal/llm/provider.go:58.47,58.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:58.73,58.92 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:59.47,59.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:59.73,59.94 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:60.47,60.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:60.73,60.92 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:61.45,62.26 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:62.26,62.66 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:85.84,87.16 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:87.16,89.6 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:90.5,90.14 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:91.19,92.50 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:92.50,94.10 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:96.9,96.41 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:96.41,99.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:100.9,100.103 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:101.19,102.41 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:102.41,105.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:106.9,106.89 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:107.20,108.51 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:108.51,110.10 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:111.9,111.42 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:111.42,114.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:115.9,115.108 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:116.13,117.61 1 0
+codeberg.org/snonux/hexai/internal/llm/util.go:6.47,6.77 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:9.48,11.2 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:17.4,19.12 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:19.12,21.3 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:22.2,24.29 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:24.29,27.3 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:27.26,27.37 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:30.47,31.16 1 1
+codeberg.org/snonux/hexai/internal/logging/logging.go:31.16,33.3 1 1
+codeberg.org/snonux/hexai/internal/logging/logging.go:34.2,35.48 2 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:43.32,43.55 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:46.37,47.25 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:47.25,48.32 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:48.32,50.4 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:51.3,51.37 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:53.2,53.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:15.96,17.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:18.17,19.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:20.16,21.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:22.26,23.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:23.14,25.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:26.3,26.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:27.21,28.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:29.10,31.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:35.65,37.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:37.35,40.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:41.2,44.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:44.15,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:47.2,48.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:48.13,50.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:51.2,52.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:55.53,57.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:57.14,60.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:61.2,61.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:66.64,67.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:67.20,69.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:70.2,71.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:71.27,73.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:75.2,76.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:76.21,78.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:79.2,79.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:79.53,81.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:82.2,82.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:15.48,19.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:21.45,25.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:27.33,31.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:33.52,37.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:40.37,43.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:45.96,47.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:47.35,49.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:50.2,51.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:51.13,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:54.2,54.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:54.25,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:57.2,58.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:58.16,60.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:61.2,61.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:61.26,63.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:64.2,64.28 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:64.28,66.85 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:66.85,68.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:71.2,71.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:78.71,80.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:80.35,82.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:83.2,84.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:84.13,86.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:87.2,87.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:87.25,89.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:91.2,92.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:92.28,93.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:93.44,95.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:98.3,98.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:98.40,99.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:102.2,102.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:102.20,104.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:106.2,106.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:106.35,109.17 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:109.17,110.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:110.15,112.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:114.4,114.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:114.29,116.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:119.2,119.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:122.46,123.28 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:123.28,124.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:124.29,126.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:128.2,128.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:131.31,133.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:133.18,135.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:136.2,136.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:139.33,141.49 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:141.49,143.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:144.2,144.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:10.38,11.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:11.41,14.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:15.2,15.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:15.22,17.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:28.60,30.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:30.31,31.99 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:31.99,34.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:36.2,36.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:48.86,54.53 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:54.53,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:57.2,57.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:57.44,58.51 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:58.51,63.4 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:65.2,65.46 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:65.46,66.52 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:66.52,71.4 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:73.2,73.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:73.44,75.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:76.2,76.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:76.43,78.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:79.2,79.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:79.44,81.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:82.2,82.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:82.21,84.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:86.2,87.30 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:87.30,88.63 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:88.63,90.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:92.2,93.33 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:117.72,120.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:191.151,194.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:194.24,196.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:197.2,199.24 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:199.24,201.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:202.2,204.24 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:204.24,207.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:208.2,209.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:209.32,211.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:212.2,213.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:213.14,215.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:217.2,231.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:234.64,238.9 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:238.9,240.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:242.2,243.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:246.56,249.24 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:249.24,251.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:252.2,252.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:252.44,255.33 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:255.33,260.4 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:261.3,261.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:264.2,265.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:268.51,272.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:272.37,273.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:273.15,275.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:278.2,278.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:278.14,280.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:281.2,281.50 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:288.74,290.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:290.22,295.49 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:295.49,297.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:297.9,300.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:302.9,302.83 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:302.83,304.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:306.9,306.33 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:306.33,308.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:310.3,310.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:310.27,311.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:311.34,312.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:312.38,313.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:313.35,315.7 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:317.5,317.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:320.4,320.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:325.2,326.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:326.36,328.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:330.2,330.76 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:330.76,332.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:333.2,334.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:334.35,335.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:335.14,337.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:339.2,339.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:342.137,347.24 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:347.24,349.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:350.2,360.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:435.74,444.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:16.48,18.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:18.55,19.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:19.23,21.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:22.3,22.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:24.2,25.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:25.57,26.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:26.23,28.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:29.3,29.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:31.5,34.56 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:34.56,36.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:37.5,37.60 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:37.60,39.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:40.5,40.57 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:40.57,42.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:43.5,43.54 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:43.54,45.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:46.5,46.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:46.25,48.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:51.85,52.85 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:52.85,63.3 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:64.2,64.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:67.89,69.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:69.21,71.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:72.2,81.12 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:84.70,85.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:85.45,87.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:88.2,96.58 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:96.58,98.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:99.5,99.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:100.20,107.72 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:107.72,108.66 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:108.66,112.5 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:113.9,115.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:116.24,120.43 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:120.43,121.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:121.24,123.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:123.10,125.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:127.3,133.72 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:133.72,134.66 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:134.66,138.5 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:139.9,141.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:142.21,149.78 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:149.78,150.75 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:150.75,154.14 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:155.15,157.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:158.20,159.98 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:159.98,167.10 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:169.5,169.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:172.55,174.56 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:174.56,175.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:175.23,177.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:178.3,178.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:180.2,180.49 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:180.49,183.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:184.2,184.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:190.85,191.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:191.22,193.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:194.2,195.53 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:195.53,197.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:198.2,198.31 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:198.31,200.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:201.2,202.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:202.36,203.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:203.34,205.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:207.2,207.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:211.37,213.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:213.32,215.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:216.2,216.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:216.32,218.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:220.2,220.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:220.29,222.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:224.2,224.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:224.29,226.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:227.2,227.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:230.34,231.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:231.22,233.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:234.2,234.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:237.37,238.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:238.22,240.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:241.2,241.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:246.76,248.83 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:248.83,250.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:252.5,252.74 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:252.74,254.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:256.5,257.44 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:257.44,259.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:260.5,267.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:271.86,272.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:272.27,274.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:275.5,275.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:275.37,277.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:278.5,286.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:289.95,291.79 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:291.79,293.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:295.5,296.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:296.24,298.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:299.5,301.39 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:301.39,303.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:304.5,306.42 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:306.42,308.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:310.5,314.29 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:314.29,320.28 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:320.28,323.10 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:324.9,326.108 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:326.108,328.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:329.9,336.46 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:336.46,336.62 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:337.9,339.25 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:339.25,339.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:340.9,341.39 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:344.5,345.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:345.18,345.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:346.5,361.16 13 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:361.16,364.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:365.5,366.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:370.62,371.42 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:371.42,373.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:374.5,376.19 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:376.19,378.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:379.5,380.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:383.35,384.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:384.44,386.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:387.5,387.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:391.48,392.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:392.30,394.45 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:394.45,397.54 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:397.54,397.73 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:398.13,398.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:398.55,398.74 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:399.13,399.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:399.55,399.93 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:400.13,400.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:403.5,403.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:407.63,408.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:408.16,408.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:409.5,409.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:409.26,409.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:411.5,412.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:412.31,413.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:413.48,415.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:417.9,417.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:417.44,418.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:421.5,421.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:421.20,421.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:423.5,425.41 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:425.41,427.38 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:427.38,428.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:429.22,431.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:432.22,433.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:433.30,433.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:434.17,434.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:434.43,436.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:441.5,441.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:441.18,443.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:444.5,444.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:448.65,449.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:449.27,456.77 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:456.77,458.30 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:458.30,458.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:459.15,461.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:464.5,465.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:465.19,465.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:466.5,466.118 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:470.43,474.42 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:474.42,474.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:475.5,477.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:477.37,479.69 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:479.69,481.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:484.5,484.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:484.45,486.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:487.5,487.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:490.37,491.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:491.19,491.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:492.5,493.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:493.35,495.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:496.5,496.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:14.48,17.55 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:17.55,24.19 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:24.19,26.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:27.3,27.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:27.25,31.10 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:31.10,34.5 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:37.2,38.73 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:43.67,44.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:44.22,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:47.2,51.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:51.48,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:53.8,56.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:57.2,57.46 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:62.99,65.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:67.98,70.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:72.160,77.52 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:77.52,80.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:81.2,81.51 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:81.51,83.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:85.2,90.86 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:90.86,95.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:96.2,96.87 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:96.87,99.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:101.2,101.83 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:101.83,104.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:107.5,107.129 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:107.129,109.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:112.2,115.29 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:115.29,117.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:118.2,120.32 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:120.32,122.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:124.5,125.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:125.32,127.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:128.5,131.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:131.16,135.3 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:136.2,140.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:140.19,142.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:143.2,144.75 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:148.38,149.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:149.16,151.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:152.2,155.42 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:155.42,157.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:157.8,160.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:161.2,161.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:165.91,166.79 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:166.79,168.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:168.63,171.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:173.2,173.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:177.119,181.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:181.24,183.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:184.2,185.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:185.13,187.68 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:187.68,189.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:191.2,191.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:191.19,193.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:195.2,196.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:196.12,198.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:198.28,200.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:202.3,202.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:204.2,206.50 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:206.50,208.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:209.2,209.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:213.193,215.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:215.9,217.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:218.2,223.32 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:223.32,225.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:226.2,227.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:227.24,229.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:230.2,236.33 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:236.33,238.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:239.5,240.40 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:240.40,242.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:242.20,244.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:244.21,246.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:247.4,247.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:247.59,249.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:249.21,251.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:253.4,253.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:253.40,257.5 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:259.8,259.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:259.23,261.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:262.2,262.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:267.55,269.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:269.15,271.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:272.5,272.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:272.9,276.26 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:276.26,278.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:279.9,280.23 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:280.23,282.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:283.9,285.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:286.27,288.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:289.24,289.24 0 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:297.60,299.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:299.22,301.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:302.5,303.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:303.9,307.29 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:307.29,311.20 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:312.31,314.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:315.28,317.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:321.9,323.20 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:328.177,334.33 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:334.33,336.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:337.2,337.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:337.18,339.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:340.2,340.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:344.101,346.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:346.57,347.78 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:347.78,349.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:351.2,351.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:351.19,353.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:354.2,354.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:354.19,356.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:357.2,357.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:357.61,358.57 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:358.57,360.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:362.2,362.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:13.45,15.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:15.55,18.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:21.47,23.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:23.55,24.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:24.32,26.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:27.3,29.44 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:33.46,35.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:35.55,38.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:44.76,46.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:46.14,48.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:50.2,51.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:51.14,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:54.2,54.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:54.26,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:57.2,58.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:58.13,60.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:61.2,61.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:61.30,63.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:65.2,66.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:66.28,69.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:70.2,75.43 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:75.43,78.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:79.2,79.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:87.50,88.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:88.24,90.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:91.2,92.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:92.35,94.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:95.2,95.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:95.30,98.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:98.14,99.39 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:99.39,101.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:103.4,103.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:105.3,105.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:105.12,106.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:108.3,110.17 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:110.17,111.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:114.3,115.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:115.63,117.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:118.3,118.80 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:118.80,119.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:122.3,125.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:125.19,126.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:128.3,130.38 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:130.38,140.18 9 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:140.18,143.5 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:144.4,145.17 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:145.17,147.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:148.4,148.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:151.3,151.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:157.110,159.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:159.14,161.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:163.2,174.54 8 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:179.96,181.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:181.14,183.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:184.2,187.31 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:187.31,188.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:188.53,190.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:191.3,191.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:191.12,192.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:194.3,194.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:194.61,195.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:197.3,198.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:198.14,200.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:200.36,203.13 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:205.4,205.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:207.3,207.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:207.53,209.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:210.3,210.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:210.12,211.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:213.3,216.6 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:218.2,219.26 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:219.26,220.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:220.35,222.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:223.3,223.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:223.35,225.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:227.2,228.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:232.45,234.39 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:234.39,236.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:236.63,238.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:240.2,240.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:240.32,242.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:243.2,243.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:243.17,245.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:246.2,247.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:248.21,249.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:250.10,251.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:256.68,263.2 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:266.46,273.2 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:276.61,291.2 9 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:295.59,296.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:296.15,299.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:8.52,10.58 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:10.58,13.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:14.5,14.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:15.31,16.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:16.34,20.67 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:20.67,22.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:23.13,23.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:23.26,25.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:27.9,28.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:29.13,32.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:10.48,12.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:12.24,14.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:15.2,26.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:29.38,31.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:33.46,35.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:37.31,40.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:13.55,15.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:15.32,17.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:18.2,18.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:22.41,27.2 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:29.41,34.2 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:36.32,39.23 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:39.23,41.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:42.2,43.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:43.24,45.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:46.2,49.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:49.15,51.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:52.2,55.211 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:59.51,60.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:60.41,62.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:63.2,65.71 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:68.110,69.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:69.14,73.3 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:74.2,76.18 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:79.118,80.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:80.14,83.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:83.16,86.35 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:86.35,88.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:89.4,89.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:89.36,91.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:92.4,94.59 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:94.59,96.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:97.4,97.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:100.2,103.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:106.51,107.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:107.23,109.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:110.2,110.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:110.13,112.100 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:112.100,114.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:116.3,116.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:118.2,118.11 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:121.32,123.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:126.44,127.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:127.53,129.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:130.2,130.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:133.40,135.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:135.20,136.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:136.40,138.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:140.3,140.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:142.2,142.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:142.12,144.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:145.2,145.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:148.52,149.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:149.38,151.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:152.2,153.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:153.27,154.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:154.34,155.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:157.3,157.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:157.36,158.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:160.3,160.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:162.2,162.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:171.67,173.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:173.22,175.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:175.12,177.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:178.3,180.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:180.63,182.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:184.3,185.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:185.12,187.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:188.3,189.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:189.48,191.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:193.3,194.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:194.18,196.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:198.3,199.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:201.2,201.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:207.46,209.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:209.32,211.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:212.2,212.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:212.34,214.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:215.2,215.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:215.32,217.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:217.32,219.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:221.2,221.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:225.83,228.102 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:228.102,230.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:230.36,232.136 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:232.136,234.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:235.4,237.34 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:237.34,239.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:243.2,243.65 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:243.65,244.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:244.53,246.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:246.37,248.137 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:248.137,250.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:251.5,253.35 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:253.35,255.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:259.2,259.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:263.80,264.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:264.22,266.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:267.2,269.40 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:269.40,271.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:272.2,272.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:272.34,273.31 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:273.31,274.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:276.3,277.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:277.16,278.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:280.3,280.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:280.32,282.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:284.2,284.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:287.36,289.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:292.39,294.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:294.13,296.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:297.2,299.66 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:299.66,301.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:302.2,303.54 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:303.54,305.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:306.2,306.51 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:306.51,308.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:309.2,311.69 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:311.69,314.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:315.2,315.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:319.43,321.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:321.13,323.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:324.2,325.11 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:325.11,327.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:328.2,329.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:329.14,331.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:332.2,333.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:337.56,339.89 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:339.89,341.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:342.2,342.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:346.52,347.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:347.32,349.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:349.28,351.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:352.3,352.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:352.34,354.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:355.3,355.42 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:355.42,357.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:358.3,358.49 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:360.2,363.27 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:363.27,365.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:366.2,366.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:366.36,368.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:369.2,372.49 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:372.49,374.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:374.24,376.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:379.2,380.25 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:380.25,382.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:383.2,383.33 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:383.33,385.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:386.2,387.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:391.67,393.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:393.35,395.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:396.2,397.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:397.31,399.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:400.2,400.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:403.69,404.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:404.37,406.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:407.2,407.47 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:410.50,412.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:412.22,414.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:414.12,416.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:417.3,419.32 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:419.32,421.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:422.3,423.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:423.35,425.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:427.3,428.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:428.12,430.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:431.3,432.49 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:432.49,434.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:436.3,436.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:438.2,438.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:441.67,444.28 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:444.28,446.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:446.12,447.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:449.3,451.12 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:451.12,452.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:454.3,454.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:454.43,456.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:458.3,458.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:458.23,460.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:462.3,463.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:463.48,465.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:467.3,467.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:467.25,469.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:471.3,472.50 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:472.50,474.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:475.3,476.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:478.2,478.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:72.90,75.20 3 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:75.20,77.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:78.2,80.23 3 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:80.23,82.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:83.2,84.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:84.22,86.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:87.2,88.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:88.27,90.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:91.2,97.38 6 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:97.38,100.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:100.8,102.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:103.5,106.38 4 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:106.38,108.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:109.5,109.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:109.38,111.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:113.2,115.46 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:115.46,115.71 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:117.46,117.64 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:126.2,126.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:129.30,130.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:130.6,132.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:132.20,134.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:135.3,135.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:135.17,137.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:138.3,139.52 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:139.52,141.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:143.3,143.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:143.23,145.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:147.3,148.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:148.15,150.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:14.48,17.6 3 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:17.6,19.17 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:19.17,21.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:22.3,22.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:22.17,23.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:25.3,26.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:26.22,27.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:29.3,31.14 3 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:32.25,34.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:34.18,36.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:37.4,37.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:40.2,40.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:40.24,42.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:43.2,44.50 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:44.50,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:47.2,47.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:50.38,52.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:52.16,55.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:56.2,57.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:57.57,60.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:61.2,61.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:61.45,64.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:14.13,17.18 3 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.2,22.104 1 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.104,24.3 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:13.13,17.18 4 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.2,22.79 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.79,24.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:55.29,73.2 2 3
+codeberg.org/snonux/hexai/internal/appconfig/config.go:77.35,79.22 2 3
+codeberg.org/snonux/hexai/internal/appconfig/config.go:79.22,81.6 1 2
+codeberg.org/snonux/hexai/internal/appconfig/config.go:83.5,84.19 2 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:84.19,87.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:87.11,88.91 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:88.91,90.10 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.5,96.53 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.53,98.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:99.5,99.15 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:103.66,105.16 2 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:105.16,106.43 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:106.43,108.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:109.3,109.18 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:111.2,115.45 4 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:115.45,116.20 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:116.20,118.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:119.3,119.18 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:121.2,121.22 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:124.37,127.2 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:130.39,131.25 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:131.25,133.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.2,134.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.56,136.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.2,137.34 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.34,139.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.2,140.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.32,142.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.2,143.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.32,145.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.5,146.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.39,148.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.5,149.41 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.41,151.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.5,152.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.39,152.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.5,153.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.39,153.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.2,154.38 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.38,156.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.2,157.53 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.53,159.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:163.47,164.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:164.58,166.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.2,167.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.56,169.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.2,170.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.36,172.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.2,173.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.58,175.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.2,176.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.56,178.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.2,179.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.36,181.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.2,182.59 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.59,184.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.2,185.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.57,187.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.2,188.37 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.37,190.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:193.38,195.72 2 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:195.72,197.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:197.8,199.17 2 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:199.17,201.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:202.3,202.70 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:204.5,204.27 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:211.43,216.37 3 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:216.37,216.79 1 20
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.5,217.44 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.44,219.20 2 7
+codeberg.org/snonux/hexai/internal/appconfig/config.go:219.20,219.39 1 7
+codeberg.org/snonux/hexai/internal/appconfig/config.go:220.9,221.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.23,221.42 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.42,221.85 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.88,221.103 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:222.9,222.23 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.5,224.54 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.54,226.20 2 4
+codeberg.org/snonux/hexai/internal/appconfig/config.go:226.20,226.41 1 4
+codeberg.org/snonux/hexai/internal/appconfig/config.go:227.9,228.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:228.23,229.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:229.30,229.73 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:230.13,230.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:232.9,232.24 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.5,235.50 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.50,237.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.5,238.51 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.51,240.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.5,241.60 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.60,243.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.5,244.58 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.58,246.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.5,247.57 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.57,249.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.5,250.64 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.64,252.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.5,253.62 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.62,255.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.5,256.62 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.62,258.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.5,259.63 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.63,261.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.5,262.57 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.57,265.33 3 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:265.33,266.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:266.51,268.14 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:270.9,270.19 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.5,272.47 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.47,274.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.5,277.54 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.54,277.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.5,278.51 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.51,278.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.5,279.63 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.63,279.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.5,281.54 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.54,281.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.5,282.51 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.51,282.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.5,283.63 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.63,283.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.5,285.55 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.55,285.93 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.5,286.52 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.52,286.88 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.5,287.64 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.64,287.106 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.5,289.13 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.13,291.6 1 1
+codeberg.org/snonux/hexai/internal/appconfig/config.go:292.5,292.16 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:22.95,27.19 4 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:27.19,30.6 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:32.2,32.64 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:37.124,39.16 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:39.16,42.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:43.2,45.74 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:45.74,48.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:49.2,49.12 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:53.64,55.82 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:55.82,58.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:59.2,60.9 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:61.40,62.59 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:63.23,64.24 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:65.21,66.22 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:67.10,68.91 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:73.65,88.39 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:88.39,90.6 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:92.5,93.39 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:93.39,95.6 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:96.5,96.51 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:100.48,103.40 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:103.40,105.3 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:106.2,109.3 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:113.125,116.40 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:116.40,118.56 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:118.56,121.4 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:121.18,123.4 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:124.3,124.22 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:125.8,127.17 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:127.17,129.4 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:130.3,131.26 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:133.2,136.12 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:140.59,142.2 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:25.85,27.38 2 1
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:27.38,29.17 2 1
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:29.17,31.4 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:32.3,33.22 2 1
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:35.2,37.70 3 1
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:42.159,49.37 6 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:49.37,51.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:52.2,52.12 1 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:57.49,59.30 2 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:59.30,61.3 1 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:64.72,65.19 1 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:65.19,67.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:68.2,82.39 3 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:82.39,84.6 1 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:86.5,87.39 2 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:87.39,89.6 1 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:90.2,90.67 1 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:90.67,93.3 2 1
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:93.8,96.3 2 5
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:99.57,100.20 1 6
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:100.20,102.3 1 5
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:103.2,103.97 1 1
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:103.97,105.3 1 1
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:108.97,122.2 1 6
+codeberg.org/snonux/hexai/internal/llm/copilot.go:66.77,67.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:67.38,69.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:70.2,70.36 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:70.36,74.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:75.2,82.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:85.109,86.39 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:86.39,88.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:90.2,90.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:90.45,92.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:93.2,94.27 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:94.27,96.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:97.2,97.19 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:97.19,99.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:100.2,102.29 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:102.29,104.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:105.2,109.16 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:109.16,112.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:114.2,117.16 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:117.16,120.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:121.2,122.57 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:122.57,124.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:125.2,126.16 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:126.16,128.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:129.2,129.27 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:129.27,132.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:133.2,135.21 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:139.46,139.66 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:140.46,140.71 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:143.102,146.29 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:146.29,148.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:149.2,149.24 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:149.24,151.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:151.8,151.31 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:151.31,154.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:155.2,155.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:155.21,157.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:158.2,158.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:158.21,160.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:161.2,161.12 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:164.130,166.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:166.19,166.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:167.5,167.31 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:167.31,167.55 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:168.5,168.32 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:171.70,172.53 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:172.53,174.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:175.2,177.74 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:177.74,180.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:181.2,182.69 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:185.91,187.64 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:187.64,190.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:191.2,191.17 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:200.66,202.85 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:202.85,204.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:205.5,205.42 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:205.42,207.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:208.5,209.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:209.19,209.33 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:210.5,214.19 5 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:214.19,214.33 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:215.5,216.56 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:216.56,218.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:219.5,220.67 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:220.67,220.81 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:221.5,221.43 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:221.43,221.95 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:223.5,224.21 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:224.21,224.63 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:225.5,227.15 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:232.42,234.23 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:234.23,234.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:235.5,236.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:236.19,237.65 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:237.65,238.57 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:238.57,238.83 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:240.9,240.27 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:242.5,244.25 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:244.25,244.47 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:245.5,245.37 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:248.42,248.100 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:252.57,268.2 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:270.58,286.2 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:288.28,291.22 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:291.22,293.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:294.5,294.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:300.153,301.42 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:301.42,301.95 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:302.5,302.48 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:302.48,302.67 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:303.5,303.15 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:303.15,303.24 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:304.5,326.19 6 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:326.19,326.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:327.5,328.56 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:328.56,330.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:332.5,335.30 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:335.30,336.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:336.45,336.55 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:337.9,338.94 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:338.94,338.104 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:339.9,339.40 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:339.40,339.72 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:341.5,342.28 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:342.28,343.66 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:343.66,343.90 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:345.5,345.20 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:44.68,45.38 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:45.38,47.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:48.2,48.36 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:48.36,50.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:51.2,57.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:60.108,62.27 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:62.27,64.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:65.2,65.19 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:65.19,67.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:69.2,73.16 5 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:73.16,75.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:77.2,80.16 4 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:80.16,83.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:84.2,85.56 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:85.56,87.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:89.2,90.64 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:90.64,93.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:94.2,94.50 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:94.50,97.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:98.2,100.21 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:104.45,104.64 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:105.45,105.70 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:108.126,110.27 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:110.27,112.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:113.2,113.19 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:113.19,115.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:117.2,121.16 5 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:121.16,123.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:125.2,128.16 4 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:128.16,131.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:132.2,133.56 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:133.56,135.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:137.2,138.6 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:138.6,140.41 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:140.41,141.30 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:141.30,142.10 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:144.4,145.14 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:147.3,147.40 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:147.40,150.4 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:151.3,151.58 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:151.58,153.4 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:154.3,154.14 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:154.14,155.9 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:158.2,159.12 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:163.76,165.29 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:165.29,167.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:168.2,168.89 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:171.109,174.29 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:174.29,176.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:177.2,178.24 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:178.24,180.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:180.8,180.31 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:180.31,182.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:183.2,183.21 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:183.21,185.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:186.2,186.21 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:186.21,188.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:189.2,189.22 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:189.22,191.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:192.2,192.12 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:195.100,197.16 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:197.16,199.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:200.2,201.29 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:204.69,205.53 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:205.53,207.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:208.2,210.43 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:210.43,213.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:214.2,215.68 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:78.76,79.38 1 5
+codeberg.org/snonux/hexai/internal/llm/openai.go:79.38,81.3 1 5
+codeberg.org/snonux/hexai/internal/llm/openai.go:82.2,82.36 1 5
+codeberg.org/snonux/hexai/internal/llm/openai.go:82.36,84.3 1 5
+codeberg.org/snonux/hexai/internal/llm/openai.go:85.2,92.3 1 5
+codeberg.org/snonux/hexai/internal/llm/openai.go:95.108,96.20 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:96.20,98.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:99.2,100.27 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:100.27,102.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:103.2,103.19 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:103.19,105.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:106.2,110.16 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:110.16,113.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:114.2,119.16 4 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:119.16,122.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:123.2,124.56 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:124.56,126.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:127.2,128.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:128.16,130.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:131.2,131.27 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:131.27,134.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:135.2,137.21 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:141.45,141.64 1 5
+codeberg.org/snonux/hexai/internal/llm/openai.go:142.45,142.70 1 5
+codeberg.org/snonux/hexai/internal/llm/openai.go:146.126,147.20 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:147.20,149.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:150.2,151.27 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:151.27,153.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:154.2,154.19 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:154.19,156.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:157.2,161.16 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:161.16,164.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:165.2,170.16 4 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:170.16,173.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:174.2,175.56 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:175.56,177.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:179.2,179.64 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:179.64,181.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:182.2,183.12 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:187.56,187.104 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:190.76,192.29 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:192.29,194.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:195.2,195.89 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:198.105,201.29 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:201.29,203.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:204.2,204.24 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:204.24,206.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:206.8,206.31 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:206.31,209.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:210.2,210.21 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:210.21,212.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:213.2,213.21 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:213.21,215.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:216.2,216.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:219.127,221.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:221.16,223.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:224.2,225.28 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:225.28,227.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:228.2,228.29 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:231.152,233.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:233.16,235.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:236.2,238.28 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:238.28,240.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:241.2,241.29 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:244.69,245.53 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:245.53,247.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:248.2,250.55 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:250.55,253.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:254.2,255.68 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:258.85,260.64 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:260.64,263.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:264.2,264.17 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:267.90,273.21 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:273.21,275.41 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:275.41,276.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:278.3,279.45 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:279.45,280.9 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:282.3,283.65 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:283.65,284.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:286.3,286.54 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:286.54,289.4 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:290.3,290.36 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:290.36,291.30 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:291.30,293.5 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:296.2,296.38 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:296.38,299.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:300.2,300.12 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:58.47,58.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:58.73,58.92 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:59.47,59.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:59.73,59.94 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:60.47,60.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:60.73,60.92 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:61.45,62.26 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:62.26,62.66 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:85.84,87.16 2 6
+codeberg.org/snonux/hexai/internal/llm/provider.go:87.16,89.6 1 6
+codeberg.org/snonux/hexai/internal/llm/provider.go:90.5,90.14 1 6
+codeberg.org/snonux/hexai/internal/llm/provider.go:91.19,92.50 1 6
+codeberg.org/snonux/hexai/internal/llm/provider.go:92.50,94.10 1 1
+codeberg.org/snonux/hexai/internal/llm/provider.go:96.9,96.41 1 5
+codeberg.org/snonux/hexai/internal/llm/provider.go:96.41,99.10 2 3
+codeberg.org/snonux/hexai/internal/llm/provider.go:100.9,100.103 1 5
+codeberg.org/snonux/hexai/internal/llm/provider.go:101.19,102.41 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:102.41,105.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:106.9,106.89 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:107.20,108.51 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:108.51,110.10 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:111.9,111.42 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:111.42,114.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:115.9,115.108 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:116.13,117.61 1 0
+codeberg.org/snonux/hexai/internal/llm/util.go:6.47,6.77 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:9.48,11.2 1 5
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:17.4,19.12 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:19.12,21.3 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:22.2,24.29 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:24.29,27.3 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:27.26,27.37 1 1
+codeberg.org/snonux/hexai/internal/logging/logging.go:30.47,31.16 1 6
+codeberg.org/snonux/hexai/internal/logging/logging.go:31.16,33.3 1 2
+codeberg.org/snonux/hexai/internal/logging/logging.go:34.2,35.48 2 4
+codeberg.org/snonux/hexai/internal/logging/logging.go:43.32,43.55 1 7
+codeberg.org/snonux/hexai/internal/logging/logging.go:46.37,47.25 1 1
+codeberg.org/snonux/hexai/internal/logging/logging.go:47.25,48.32 1 1
+codeberg.org/snonux/hexai/internal/logging/logging.go:48.32,50.4 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:51.3,51.37 1 1
+codeberg.org/snonux/hexai/internal/logging/logging.go:53.2,53.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:15.96,17.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:18.17,19.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:20.16,21.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:22.26,23.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:23.14,25.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:26.3,26.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:27.21,28.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:29.10,31.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:35.65,37.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:37.35,40.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:41.2,44.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:44.15,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:47.2,48.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:48.13,50.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:51.2,52.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:55.53,57.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:57.14,60.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:61.2,61.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:66.64,67.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:67.20,69.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:70.2,71.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:71.27,73.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:75.2,76.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:76.21,78.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:79.2,79.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:79.53,81.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:82.2,82.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:15.48,19.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:21.45,25.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:27.33,31.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:33.52,37.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:40.37,43.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:45.96,47.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:47.35,49.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:50.2,51.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:51.13,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:54.2,54.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:54.25,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:57.2,58.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:58.16,60.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:61.2,61.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:61.26,63.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:64.2,64.28 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:64.28,66.85 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:66.85,68.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:71.2,71.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:78.71,80.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:80.35,82.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:83.2,84.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:84.13,86.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:87.2,87.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:87.25,89.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:91.2,92.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:92.28,93.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:93.44,95.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:98.3,98.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:98.40,99.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:102.2,102.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:102.20,104.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:106.2,106.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:106.35,109.17 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:109.17,110.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:110.15,112.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:114.4,114.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:114.29,116.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:119.2,119.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:122.46,123.28 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:123.28,124.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:124.29,126.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:128.2,128.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:131.31,133.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:133.18,135.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:136.2,136.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:139.33,141.49 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:141.49,143.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:144.2,144.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:10.38,11.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:11.41,14.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:15.2,15.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:15.22,17.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:28.60,30.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:30.31,31.99 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:31.99,34.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:36.2,36.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:48.86,54.53 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:54.53,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:57.2,57.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:57.44,58.51 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:58.51,63.4 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:65.2,65.46 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:65.46,66.52 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:66.52,71.4 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:73.2,73.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:73.44,75.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:76.2,76.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:76.43,78.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:79.2,79.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:79.44,81.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:82.2,82.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:82.21,84.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:86.2,87.30 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:87.30,88.63 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:88.63,90.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:92.2,93.33 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:117.72,120.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:191.151,194.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:194.24,196.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:197.2,199.24 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:199.24,201.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:202.2,204.24 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:204.24,207.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:208.2,209.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:209.32,211.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:212.2,213.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:213.14,215.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:217.2,231.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:234.64,238.9 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:238.9,240.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:242.2,243.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:246.56,249.24 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:249.24,251.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:252.2,252.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:252.44,255.33 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:255.33,260.4 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:261.3,261.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:264.2,265.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:268.51,272.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:272.37,273.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:273.15,275.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:278.2,278.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:278.14,280.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:281.2,281.50 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:288.74,290.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:290.22,295.49 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:295.49,297.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:297.9,300.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:302.9,302.83 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:302.83,304.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:306.9,306.33 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:306.33,308.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:310.3,310.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:310.27,311.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:311.34,312.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:312.38,313.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:313.35,315.7 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:317.5,317.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:320.4,320.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:325.2,326.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:326.36,328.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:330.2,330.76 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:330.76,332.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:333.2,334.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:334.35,335.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:335.14,337.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:339.2,339.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:342.137,347.24 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:347.24,349.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:350.2,360.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:435.74,444.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:16.48,18.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:18.55,19.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:19.23,21.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:22.3,22.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:24.2,25.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:25.57,26.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:26.23,28.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:29.3,29.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:31.5,34.56 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:34.56,36.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:37.5,37.60 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:37.60,39.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:40.5,40.57 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:40.57,42.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:43.5,43.54 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:43.54,45.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:46.5,46.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:46.25,48.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:51.85,52.85 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:52.85,63.3 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:64.2,64.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:67.89,69.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:69.21,71.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:72.2,81.12 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:84.70,85.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:85.45,87.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:88.2,96.58 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:96.58,98.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:99.5,99.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:100.20,107.72 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:107.72,108.66 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:108.66,112.5 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:113.9,115.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:116.24,120.43 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:120.43,121.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:121.24,123.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:123.10,125.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:127.3,133.72 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:133.72,134.66 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:134.66,138.5 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:139.9,141.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:142.21,149.78 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:149.78,150.75 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:150.75,154.14 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:155.15,157.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:158.20,159.98 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:159.98,167.10 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:169.5,169.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:172.55,174.56 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:174.56,175.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:175.23,177.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:178.3,178.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:180.2,180.49 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:180.49,183.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:184.2,184.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:190.85,191.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:191.22,193.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:194.2,195.53 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:195.53,197.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:198.2,198.31 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:198.31,200.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:201.2,202.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:202.36,203.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:203.34,205.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:207.2,207.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:211.37,213.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:213.32,215.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:216.2,216.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:216.32,218.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:220.2,220.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:220.29,222.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:224.2,224.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:224.29,226.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:227.2,227.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:230.34,231.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:231.22,233.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:234.2,234.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:237.37,238.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:238.22,240.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:241.2,241.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:246.76,248.83 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:248.83,250.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:252.5,252.74 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:252.74,254.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:256.5,257.44 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:257.44,259.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:260.5,267.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:271.86,272.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:272.27,274.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:275.5,275.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:275.37,277.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:278.5,286.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:289.95,291.79 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:291.79,293.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:295.5,296.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:296.24,298.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:299.5,301.39 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:301.39,303.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:304.5,306.42 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:306.42,308.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:310.5,314.29 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:314.29,320.28 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:320.28,323.10 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:324.9,326.108 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:326.108,328.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:329.9,336.46 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:336.46,336.62 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:337.9,339.25 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:339.25,339.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:340.9,341.39 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:344.5,345.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:345.18,345.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:346.5,361.16 13 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:361.16,364.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:365.5,366.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:370.62,371.42 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:371.42,373.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:374.5,376.19 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:376.19,378.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:379.5,380.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:383.35,384.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:384.44,386.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:387.5,387.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:391.48,392.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:392.30,394.45 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:394.45,397.54 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:397.54,397.73 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:398.13,398.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:398.55,398.74 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:399.13,399.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:399.55,399.93 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:400.13,400.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:403.5,403.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:407.63,408.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:408.16,408.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:409.5,409.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:409.26,409.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:411.5,412.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:412.31,413.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:413.48,415.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:417.9,417.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:417.44,418.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:421.5,421.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:421.20,421.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:423.5,425.41 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:425.41,427.38 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:427.38,428.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:429.22,431.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:432.22,433.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:433.30,433.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:434.17,434.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:434.43,436.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:441.5,441.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:441.18,443.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:444.5,444.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:448.65,449.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:449.27,456.77 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:456.77,458.30 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:458.30,458.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:459.15,461.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:464.5,465.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:465.19,465.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:466.5,466.118 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:470.43,474.42 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:474.42,474.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:475.5,477.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:477.37,479.69 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:479.69,481.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:484.5,484.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:484.45,486.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:487.5,487.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:490.37,491.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:491.19,491.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:492.5,493.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:493.35,495.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:496.5,496.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:14.48,17.55 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:17.55,24.19 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:24.19,26.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:27.3,27.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:27.25,31.10 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:31.10,34.5 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:37.2,38.73 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:43.67,44.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:44.22,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:47.2,51.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:51.48,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:53.8,56.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:57.2,57.46 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:62.99,65.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:67.98,70.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:72.160,77.52 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:77.52,80.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:81.2,81.51 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:81.51,83.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:85.2,90.86 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:90.86,95.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:96.2,96.87 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:96.87,99.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:101.2,101.83 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:101.83,104.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:107.5,107.129 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:107.129,109.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:112.2,115.29 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:115.29,117.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:118.2,120.32 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:120.32,122.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:124.5,125.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:125.32,127.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:128.5,131.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:131.16,135.3 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:136.2,140.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:140.19,142.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:143.2,144.75 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:148.38,149.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:149.16,151.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:152.2,155.42 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:155.42,157.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:157.8,160.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:161.2,161.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:165.91,166.79 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:166.79,168.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:168.63,171.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:173.2,173.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:177.119,181.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:181.24,183.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:184.2,185.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:185.13,187.68 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:187.68,189.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:191.2,191.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:191.19,193.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:195.2,196.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:196.12,198.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:198.28,200.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:202.3,202.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:204.2,206.50 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:206.50,208.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:209.2,209.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:213.193,215.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:215.9,217.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:218.2,223.32 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:223.32,225.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:226.2,227.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:227.24,229.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:230.2,236.33 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:236.33,238.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:239.5,240.40 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:240.40,242.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:242.20,244.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:244.21,246.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:247.4,247.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:247.59,249.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:249.21,251.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:253.4,253.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:253.40,257.5 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:259.8,259.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:259.23,261.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:262.2,262.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:267.55,269.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:269.15,271.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:272.5,272.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:272.9,276.26 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:276.26,278.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:279.9,280.23 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:280.23,282.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:283.9,285.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:286.27,288.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:289.24,289.24 0 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:297.60,299.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:299.22,301.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:302.5,303.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:303.9,307.29 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:307.29,311.20 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:312.31,314.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:315.28,317.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:321.9,323.20 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:328.177,334.33 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:334.33,336.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:337.2,337.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:337.18,339.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:340.2,340.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:344.101,346.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:346.57,347.78 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:347.78,349.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:351.2,351.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:351.19,353.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:354.2,354.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:354.19,356.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:357.2,357.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:357.61,358.57 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:358.57,360.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:362.2,362.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:13.45,15.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:15.55,18.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:21.47,23.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:23.55,24.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:24.32,26.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:27.3,29.44 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:33.46,35.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:35.55,38.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:44.76,46.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:46.14,48.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:50.2,51.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:51.14,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:54.2,54.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:54.26,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:57.2,58.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:58.13,60.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:61.2,61.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:61.30,63.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:65.2,66.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:66.28,69.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:70.2,75.43 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:75.43,78.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:79.2,79.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:87.50,88.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:88.24,90.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:91.2,92.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:92.35,94.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:95.2,95.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:95.30,98.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:98.14,99.39 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:99.39,101.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:103.4,103.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:105.3,105.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:105.12,106.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:108.3,110.17 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:110.17,111.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:114.3,115.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:115.63,117.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:118.3,118.80 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:118.80,119.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:122.3,125.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:125.19,126.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:128.3,130.38 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:130.38,140.18 9 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:140.18,143.5 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:144.4,145.17 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:145.17,147.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:148.4,148.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:151.3,151.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:157.110,159.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:159.14,161.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:163.2,174.54 8 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:179.96,181.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:181.14,183.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:184.2,187.31 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:187.31,188.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:188.53,190.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:191.3,191.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:191.12,192.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:194.3,194.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:194.61,195.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:197.3,198.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:198.14,200.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:200.36,203.13 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:205.4,205.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:207.3,207.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:207.53,209.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:210.3,210.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:210.12,211.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:213.3,216.6 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:218.2,219.26 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:219.26,220.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:220.35,222.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:223.3,223.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:223.35,225.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:227.2,228.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:232.45,234.39 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:234.39,236.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:236.63,238.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:240.2,240.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:240.32,242.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:243.2,243.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:243.17,245.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:246.2,247.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:248.21,249.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:250.10,251.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:256.68,263.2 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:266.46,273.2 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:276.61,291.2 9 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:295.59,296.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:296.15,299.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:8.52,10.58 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:10.58,13.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:14.5,14.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:15.31,16.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:16.34,20.67 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:20.67,22.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:23.13,23.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:23.26,25.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:27.9,28.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:29.13,32.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:10.48,12.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:12.24,14.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:15.2,26.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:29.38,31.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:33.46,35.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:37.31,40.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:13.55,15.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:15.32,17.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:18.2,18.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:22.41,27.2 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:29.41,34.2 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:36.32,39.23 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:39.23,41.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:42.2,43.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:43.24,45.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:46.2,49.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:49.15,51.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:52.2,55.211 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:59.51,60.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:60.41,62.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:63.2,65.71 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:68.110,69.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:69.14,73.3 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:74.2,76.18 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:79.118,80.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:80.14,83.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:83.16,86.35 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:86.35,88.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:89.4,89.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:89.36,91.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:92.4,94.59 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:94.59,96.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:97.4,97.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:100.2,103.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:106.51,107.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:107.23,109.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:110.2,110.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:110.13,112.100 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:112.100,114.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:116.3,116.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:118.2,118.11 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:121.32,123.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:126.44,127.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:127.53,129.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:130.2,130.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:133.40,135.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:135.20,136.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:136.40,138.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:140.3,140.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:142.2,142.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:142.12,144.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:145.2,145.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:148.52,149.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:149.38,151.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:152.2,153.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:153.27,154.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:154.34,155.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:157.3,157.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:157.36,158.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:160.3,160.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:162.2,162.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:171.67,173.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:173.22,175.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:175.12,177.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:178.3,180.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:180.63,182.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:184.3,185.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:185.12,187.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:188.3,189.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:189.48,191.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:193.3,194.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:194.18,196.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:198.3,199.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:201.2,201.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:207.46,209.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:209.32,211.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:212.2,212.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:212.34,214.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:215.2,215.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:215.32,217.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:217.32,219.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:221.2,221.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:225.83,228.102 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:228.102,230.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:230.36,232.136 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:232.136,234.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:235.4,237.34 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:237.34,239.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:243.2,243.65 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:243.65,244.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:244.53,246.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:246.37,248.137 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:248.137,250.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:251.5,253.35 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:253.35,255.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:259.2,259.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:263.80,264.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:264.22,266.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:267.2,269.40 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:269.40,271.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:272.2,272.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:272.34,273.31 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:273.31,274.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:276.3,277.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:277.16,278.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:280.3,280.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:280.32,282.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:284.2,284.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:287.36,289.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:292.39,294.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:294.13,296.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:297.2,299.66 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:299.66,301.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:302.2,303.54 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:303.54,305.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:306.2,306.51 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:306.51,308.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:309.2,311.69 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:311.69,314.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:315.2,315.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:319.43,321.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:321.13,323.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:324.2,325.11 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:325.11,327.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:328.2,329.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:329.14,331.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:332.2,333.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:337.56,339.89 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:339.89,341.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:342.2,342.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:346.52,347.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:347.32,349.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:349.28,351.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:352.3,352.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:352.34,354.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:355.3,355.42 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:355.42,357.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:358.3,358.49 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:360.2,363.27 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:363.27,365.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:366.2,366.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:366.36,368.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:369.2,372.49 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:372.49,374.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:374.24,376.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:379.2,380.25 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:380.25,382.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:383.2,383.33 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:383.33,385.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:386.2,387.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:391.67,393.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:393.35,395.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:396.2,397.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:397.31,399.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:400.2,400.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:403.69,404.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:404.37,406.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:407.2,407.47 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:410.50,412.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:412.22,414.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:414.12,416.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:417.3,419.32 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:419.32,421.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:422.3,423.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:423.35,425.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:427.3,428.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:428.12,430.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:431.3,432.49 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:432.49,434.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:436.3,436.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:438.2,438.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:441.67,444.28 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:444.28,446.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:446.12,447.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:449.3,451.12 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:451.12,452.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:454.3,454.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:454.43,456.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:458.3,458.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:458.23,460.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:462.3,463.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:463.48,465.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:467.3,467.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:467.25,469.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:471.3,472.50 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:472.50,474.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:475.3,476.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:478.2,478.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:72.90,75.20 3 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:75.20,77.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:78.2,80.23 3 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:80.23,82.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:83.2,84.22 2 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:84.22,86.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:87.2,88.27 2 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:88.27,90.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:91.2,97.38 6 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:97.38,100.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:100.8,102.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:103.5,106.38 4 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:106.38,108.6 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:109.5,109.38 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:109.38,111.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:113.2,115.46 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:115.46,115.71 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:117.46,117.64 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:126.2,126.10 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:129.30,130.6 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:130.6,132.20 2 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:132.20,134.4 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:135.3,135.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:135.17,137.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:138.3,139.52 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:139.52,141.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:143.3,143.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:143.23,145.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:147.3,148.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:148.15,150.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:14.48,17.6 3 1
+codeberg.org/snonux/hexai/internal/lsp/transport.go:17.6,19.17 2 1
+codeberg.org/snonux/hexai/internal/lsp/transport.go:19.17,21.4 1 1
+codeberg.org/snonux/hexai/internal/lsp/transport.go:22.3,22.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:22.17,23.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:25.3,26.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:26.22,27.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:29.3,31.14 3 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:32.25,34.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:34.18,36.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:37.4,37.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:40.2,40.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:40.24,42.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:43.2,44.50 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:44.50,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:47.2,47.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:50.38,52.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:52.16,55.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:56.2,57.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:57.57,60.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:61.2,61.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:61.45,64.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:14.13,17.18 3 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.2,22.104 1 0
+codeberg.org/snonux/hexai/cmd/hexai/main.go:22.104,24.3 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:13.13,17.18 4 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:17.18,20.3 2 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.2,22.79 1 0
+codeberg.org/snonux/hexai/cmd/hexai-lsp/main.go:22.79,24.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:55.29,73.2 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:77.35,79.22 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:79.22,81.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:83.5,84.19 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:84.19,87.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:87.11,88.91 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:88.91,90.10 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.5,96.53 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:96.53,98.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:99.5,99.15 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:103.66,105.16 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:105.16,106.43 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:106.43,108.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:109.3,109.18 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:111.2,115.45 4 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:115.45,116.20 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:116.20,118.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:119.3,119.18 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:121.2,121.22 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:124.37,127.2 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:130.39,131.25 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:131.25,133.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.2,134.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:134.56,136.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.2,137.34 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:137.34,139.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.2,140.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:140.32,142.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.2,143.32 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:143.32,145.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.5,146.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:146.39,148.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.5,149.41 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:149.41,151.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.5,152.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:152.39,152.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.5,153.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:153.39,153.94 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.2,154.38 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:154.38,156.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.2,157.53 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:157.53,159.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:163.47,164.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:164.58,166.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.2,167.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:167.56,169.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.2,170.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:170.36,172.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.2,173.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:173.58,175.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.2,176.56 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:176.56,178.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.2,179.36 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:179.36,181.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.2,182.59 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:182.59,184.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.2,185.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:185.57,187.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.2,188.37 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:188.37,190.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:193.38,195.72 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:195.72,197.3 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:197.8,199.17 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:199.17,201.4 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:202.3,202.70 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:204.5,204.27 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:211.43,216.37 3 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:216.37,216.79 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.5,217.44 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:217.44,219.20 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:219.20,219.39 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:220.9,221.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.23,221.42 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.42,221.85 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:221.88,221.103 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:222.9,222.23 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.5,224.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:224.54,226.20 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:226.20,226.41 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:227.9,228.23 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:228.23,229.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:229.30,229.73 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:230.13,230.30 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:232.9,232.24 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.5,235.50 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:235.50,237.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.5,238.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:238.51,240.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.5,241.60 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:241.60,243.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.5,244.58 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:244.58,246.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.5,247.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:247.57,249.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.5,250.64 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:250.64,252.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.5,253.62 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:253.62,255.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.5,256.62 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:256.62,258.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.5,259.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:259.63,261.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.5,262.57 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:262.57,265.33 3 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:265.33,266.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:266.51,268.14 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:270.9,270.19 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.5,272.47 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:272.47,274.6 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.5,277.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:277.54,277.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.5,278.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:278.51,278.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.5,279.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:279.63,279.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.5,281.54 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:281.54,281.91 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.5,282.51 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:282.51,282.86 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.5,283.63 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:283.63,283.104 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.5,285.55 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:285.55,285.93 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.5,286.52 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:286.52,286.88 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.5,287.64 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:287.64,287.106 2 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.5,289.13 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:289.13,291.6 1 0
+codeberg.org/snonux/hexai/internal/appconfig/config.go:292.5,292.16 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:22.95,27.19 4 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:27.19,30.6 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:32.2,32.64 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:37.124,39.16 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:39.16,42.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:43.2,45.74 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:45.74,48.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:49.2,49.12 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:53.64,55.82 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:55.82,58.3 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:59.2,60.9 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:61.40,62.59 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:63.23,64.24 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:65.21,66.22 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:67.10,68.91 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:73.65,88.39 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:88.39,90.6 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:92.5,93.39 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:93.39,95.6 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:96.5,96.51 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:100.48,103.40 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:103.40,105.3 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:106.2,109.3 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:113.125,116.40 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:116.40,118.56 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:118.56,121.4 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:121.18,123.4 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:124.3,124.22 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:125.8,127.17 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:127.17,129.4 1 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:130.3,131.26 2 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:133.2,136.12 3 0
+codeberg.org/snonux/hexai/internal/hexaicli/run.go:140.59,142.2 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:25.85,27.38 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:27.38,29.17 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:29.17,31.4 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:32.3,33.22 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:35.2,37.70 3 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:42.159,49.37 6 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:49.37,51.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:52.2,52.12 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:57.49,59.30 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:59.30,61.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:64.72,65.19 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:65.19,67.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:68.2,82.39 3 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:82.39,84.6 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:86.5,87.39 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:87.39,89.6 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:90.2,90.67 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:90.67,93.3 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:93.8,96.3 2 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:99.57,100.20 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:100.20,102.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:103.2,103.97 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:103.97,105.3 1 0
+codeberg.org/snonux/hexai/internal/hexailsp/run.go:108.97,122.2 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:66.77,67.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:67.38,69.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:70.2,70.36 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:70.36,74.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:75.2,82.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:85.109,86.39 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:86.39,88.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:90.2,90.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:90.45,92.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:93.2,94.27 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:94.27,96.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:97.2,97.19 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:97.19,99.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:100.2,102.29 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:102.29,104.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:105.2,109.16 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:109.16,112.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:114.2,117.16 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:117.16,120.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:121.2,122.57 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:122.57,124.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:125.2,126.16 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:126.16,128.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:129.2,129.27 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:129.27,132.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:133.2,135.21 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:139.46,139.66 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:140.46,140.71 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:143.102,146.29 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:146.29,148.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:149.2,149.24 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:149.24,151.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:151.8,151.31 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:151.31,154.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:155.2,155.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:155.21,157.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:158.2,158.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:158.21,160.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:161.2,161.12 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:164.130,166.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:166.19,166.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:167.5,167.31 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:167.31,167.55 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:168.5,168.32 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:171.70,172.53 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:172.53,174.3 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:175.2,177.74 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:177.74,180.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:181.2,182.69 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:185.91,187.64 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:187.64,190.3 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:191.2,191.17 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:200.66,202.85 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:202.85,204.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:205.5,205.42 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:205.42,207.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:208.5,209.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:209.19,209.33 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:210.5,214.19 5 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:214.19,214.33 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:215.5,216.56 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:216.56,218.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:219.5,220.67 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:220.67,220.81 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:221.5,221.43 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:221.43,221.95 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:223.5,224.21 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:224.21,224.63 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:225.5,227.15 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:232.42,234.23 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:234.23,234.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:235.5,236.19 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:236.19,237.65 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:237.65,238.57 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:238.57,238.83 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:240.9,240.27 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:242.5,244.25 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:244.25,244.47 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:245.5,245.37 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:248.42,248.100 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:252.57,268.2 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:270.58,286.2 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:288.28,291.22 3 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:291.22,293.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:294.5,294.21 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:300.153,301.42 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:301.42,301.95 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:302.5,302.48 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:302.48,302.67 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:303.5,303.15 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:303.15,303.24 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:304.5,326.19 6 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:326.19,326.38 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:327.5,328.56 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:328.56,330.6 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:332.5,335.30 4 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:335.30,336.45 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:336.45,336.55 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:337.9,338.94 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:338.94,338.104 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:339.9,339.40 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:339.40,339.72 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:341.5,342.28 2 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:342.28,343.66 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:343.66,343.90 1 0
+codeberg.org/snonux/hexai/internal/llm/copilot.go:345.5,345.20 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:44.68,45.38 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:45.38,47.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:48.2,48.36 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:48.36,50.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:51.2,57.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:60.108,62.27 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:62.27,64.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:65.2,65.19 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:65.19,67.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:69.2,73.16 5 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:73.16,75.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:77.2,80.16 4 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:80.16,83.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:84.2,85.56 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:85.56,87.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:89.2,90.64 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:90.64,93.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:94.2,94.50 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:94.50,97.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:98.2,100.21 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:104.45,104.64 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:105.45,105.70 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:108.126,110.27 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:110.27,112.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:113.2,113.19 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:113.19,115.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:117.2,121.16 5 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:121.16,123.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:125.2,128.16 4 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:128.16,131.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:132.2,133.56 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:133.56,135.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:137.2,138.6 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:138.6,140.41 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:140.41,141.30 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:141.30,142.10 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:144.4,145.14 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:147.3,147.40 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:147.40,150.4 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:151.3,151.58 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:151.58,153.4 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:154.3,154.14 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:154.14,155.9 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:158.2,159.12 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:163.76,165.29 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:165.29,167.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:168.2,168.89 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:171.109,174.29 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:174.29,176.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:177.2,178.24 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:178.24,180.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:180.8,180.31 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:180.31,182.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:183.2,183.21 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:183.21,185.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:186.2,186.21 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:186.21,188.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:189.2,189.22 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:189.22,191.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:192.2,192.12 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:195.100,197.16 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:197.16,199.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:200.2,201.29 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:204.69,205.53 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:205.53,207.3 1 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:208.2,210.43 3 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:210.43,213.3 2 0
+codeberg.org/snonux/hexai/internal/llm/ollama.go:214.2,215.68 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:78.76,79.38 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:79.38,81.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:82.2,82.36 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:82.36,84.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:85.2,92.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:95.108,96.20 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:96.20,98.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:99.2,100.27 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:100.27,102.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:103.2,103.19 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:103.19,105.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:106.2,110.16 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:110.16,113.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:114.2,119.16 4 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:119.16,122.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:123.2,124.56 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:124.56,126.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:127.2,128.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:128.16,130.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:131.2,131.27 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:131.27,134.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:135.2,137.21 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:141.45,141.64 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:142.45,142.70 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:146.126,147.20 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:147.20,149.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:150.2,151.27 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:151.27,153.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:154.2,154.19 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:154.19,156.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:157.2,161.16 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:161.16,164.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:165.2,170.16 4 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:170.16,173.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:174.2,175.56 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:175.56,177.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:179.2,179.64 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:179.64,181.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:182.2,183.12 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:187.56,187.104 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:190.76,192.29 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:192.29,194.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:195.2,195.89 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:198.105,201.29 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:201.29,203.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:204.2,204.24 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:204.24,206.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:206.8,206.31 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:206.31,209.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:210.2,210.21 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:210.21,212.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:213.2,213.21 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:213.21,215.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:216.2,216.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:219.127,221.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:221.16,223.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:224.2,225.28 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:225.28,227.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:228.2,228.29 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:231.152,233.16 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:233.16,235.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:236.2,238.28 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:238.28,240.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:241.2,241.29 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:244.69,245.53 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:245.53,247.3 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:248.2,250.55 3 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:250.55,253.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:254.2,255.68 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:258.85,260.64 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:260.64,263.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:264.2,264.17 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:267.90,273.21 5 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:273.21,275.41 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:275.41,276.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:278.3,279.45 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:279.45,280.9 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:282.3,283.65 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:283.65,284.12 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:286.3,286.54 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:286.54,289.4 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:290.3,290.36 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:290.36,291.30 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:291.30,293.5 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:296.2,296.38 1 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:296.38,299.3 2 0
+codeberg.org/snonux/hexai/internal/llm/openai.go:300.2,300.12 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:58.47,58.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:58.73,58.92 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:59.47,59.73 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:59.73,59.94 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:60.47,60.73 1 9
+codeberg.org/snonux/hexai/internal/llm/provider.go:60.73,60.92 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:61.45,62.26 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:62.26,62.66 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:85.84,87.16 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:87.16,89.6 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:90.5,90.14 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:91.19,92.50 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:92.50,94.10 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:96.9,96.41 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:96.41,99.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:100.9,100.103 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:101.19,102.41 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:102.41,105.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:106.9,106.89 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:107.20,108.51 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:108.51,110.10 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:111.9,111.42 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:111.42,114.10 2 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:115.9,115.108 1 0
+codeberg.org/snonux/hexai/internal/llm/provider.go:116.13,117.61 1 0
+codeberg.org/snonux/hexai/internal/llm/util.go:6.47,6.77 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:9.48,11.2 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:17.4,19.12 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:19.12,21.3 1 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:22.2,24.29 2 0
+codeberg.org/snonux/hexai/internal/logging/chatlogger.go:24.29,27.3 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:27.26,27.37 1 1
+codeberg.org/snonux/hexai/internal/logging/logging.go:30.47,31.16 1 26
+codeberg.org/snonux/hexai/internal/logging/logging.go:31.16,33.3 1 4
+codeberg.org/snonux/hexai/internal/logging/logging.go:34.2,35.48 2 22
+codeberg.org/snonux/hexai/internal/logging/logging.go:43.32,43.55 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:46.37,47.25 1 1
+codeberg.org/snonux/hexai/internal/logging/logging.go:47.25,48.32 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:48.32,50.4 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:51.3,51.37 1 0
+codeberg.org/snonux/hexai/internal/logging/logging.go:53.2,53.10 1 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:15.96,17.14 2 4
+codeberg.org/snonux/hexai/internal/lsp/context.go:18.17,19.19 1 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:20.16,21.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:22.26,23.14 1 2
+codeberg.org/snonux/hexai/internal/lsp/context.go:23.14,25.4 1 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:26.3,26.19 1 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:27.21,28.38 1 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:29.10,31.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:35.65,37.35 2 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:37.35,40.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:41.2,44.15 4 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:44.15,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:47.2,48.13 2 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:48.13,50.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:51.2,52.57 2 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:55.53,57.14 2 2
+codeberg.org/snonux/hexai/internal/lsp/context.go:57.14,60.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:61.2,61.59 1 2
+codeberg.org/snonux/hexai/internal/lsp/context.go:66.64,67.20 1 4
+codeberg.org/snonux/hexai/internal/lsp/context.go:67.20,69.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:70.2,71.27 2 4
+codeberg.org/snonux/hexai/internal/lsp/context.go:71.27,73.3 1 3
+codeberg.org/snonux/hexai/internal/lsp/context.go:75.2,76.21 2 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:76.21,78.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:79.2,79.53 1 1
+codeberg.org/snonux/hexai/internal/lsp/context.go:79.53,81.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/context.go:82.2,82.19 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:15.48,19.2 3 4
+codeberg.org/snonux/hexai/internal/lsp/document.go:21.45,25.2 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:27.33,31.2 3 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:33.52,37.2 3 16
+codeberg.org/snonux/hexai/internal/lsp/document.go:40.37,43.2 2 21
+codeberg.org/snonux/hexai/internal/lsp/document.go:45.96,47.35 2 2
+codeberg.org/snonux/hexai/internal/lsp/document.go:47.35,49.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:50.2,51.13 2 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:51.13,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:54.2,54.25 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:54.25,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:57.2,58.16 2 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:58.16,60.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:61.2,61.26 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:61.26,63.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:64.2,64.28 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:64.28,66.85 2 2
+codeberg.org/snonux/hexai/internal/lsp/document.go:66.85,68.9 2 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:71.2,71.8 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:78.71,80.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:80.35,82.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:83.2,84.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:84.13,86.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:87.2,87.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:87.25,89.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:91.2,92.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:92.28,93.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:93.44,95.9 2 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:98.3,98.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:98.40,99.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:102.2,102.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:102.20,104.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:106.2,106.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:106.35,109.17 3 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:109.17,110.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:110.15,112.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:114.4,114.29 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:114.29,116.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:119.2,119.13 1 0
+codeberg.org/snonux/hexai/internal/lsp/document.go:122.46,123.28 1 2
+codeberg.org/snonux/hexai/internal/lsp/document.go:123.28,124.29 1 7
+codeberg.org/snonux/hexai/internal/lsp/document.go:124.29,126.4 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:128.2,128.14 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:131.31,133.18 2 18
+codeberg.org/snonux/hexai/internal/lsp/document.go:133.18,135.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:136.2,136.10 1 17
+codeberg.org/snonux/hexai/internal/lsp/document.go:139.33,141.49 2 10
+codeberg.org/snonux/hexai/internal/lsp/document.go:141.49,143.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/document.go:144.2,144.10 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:10.38,11.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:11.41,14.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:15.2,15.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:15.22,17.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:28.60,30.31 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:30.31,31.99 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:31.99,34.4 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:36.2,36.16 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:48.86,54.53 3 15
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:54.53,56.3 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:57.2,57.44 1 15
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:57.44,58.51 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:58.51,63.4 4 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:65.2,65.46 1 15
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:65.46,66.52 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:66.52,71.4 4 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:73.2,73.44 1 15
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:73.44,75.3 1 3
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:76.2,76.43 1 15
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:76.43,78.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:79.2,79.44 1 15
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:79.44,81.3 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:82.2,82.21 1 15
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:82.21,84.3 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:86.2,87.30 2 10
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:87.30,88.63 1 3
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:88.63,90.4 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:92.2,93.33 2 10
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:117.72,120.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:191.151,194.24 2 10
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:194.24,196.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:197.2,199.24 3 10
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:199.24,201.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:202.2,204.24 3 10
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:204.24,207.3 2 10
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:208.2,209.32 2 10
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:209.32,211.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:212.2,213.14 2 10
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:213.14,215.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:217.2,231.12 1 10
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:234.64,238.9 4 9
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:238.9,240.3 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:242.2,243.16 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:246.56,249.24 3 8
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:249.24,251.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:252.2,252.44 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:252.44,255.33 3 8
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:255.33,260.4 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:261.3,261.9 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:264.2,265.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:268.51,272.37 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:272.37,273.15 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:273.15,275.9 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:278.2,278.14 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:278.14,280.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:281.2,281.50 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:288.74,290.22 1 16
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:290.22,295.49 2 5
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:295.49,297.4 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:297.9,300.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:302.9,302.83 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:302.83,304.10 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:306.9,306.33 1 4
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:306.33,308.10 1 4
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:310.3,310.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:310.27,311.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:311.34,312.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:312.38,313.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:313.35,315.7 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:317.5,317.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:320.4,320.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:325.2,326.36 2 11
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:326.36,328.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:330.2,330.76 1 11
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:330.76,332.3 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:333.2,334.35 2 9
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:334.35,335.14 1 24
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:335.14,337.4 1 4
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:339.2,339.14 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:342.137,347.24 5 9
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:347.24,349.3 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:350.2,360.4 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers.go:435.74,444.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:16.48,18.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:18.55,19.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:19.23,21.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:22.3,22.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:24.2,25.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:25.57,26.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:26.23,28.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:29.3,29.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:31.5,34.56 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:34.56,36.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:37.5,37.60 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:37.60,39.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:40.5,40.57 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:40.57,42.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:43.5,43.54 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:43.54,45.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:46.5,46.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:46.25,48.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:51.85,52.85 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:52.85,63.3 4 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:64.2,64.12 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:67.89,69.21 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:69.21,71.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:72.2,81.12 4 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:84.70,85.45 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:85.45,87.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:88.2,96.58 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:96.58,98.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:99.5,99.25 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:100.20,107.72 7 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:107.72,108.66 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:108.66,112.5 3 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:113.9,115.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:116.24,120.43 4 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:120.43,121.24 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:121.24,123.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:123.10,125.5 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:127.3,133.72 7 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:133.72,134.66 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:134.66,138.5 3 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:139.9,141.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:142.21,149.78 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:149.78,150.75 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:150.75,154.14 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:155.15,157.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:158.20,159.98 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:159.98,167.10 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:169.5,169.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:172.55,174.56 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:174.56,175.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:175.23,177.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:178.3,178.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:180.2,180.49 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:180.49,183.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:184.2,184.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:190.85,191.22 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:191.22,193.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:194.2,195.53 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:195.53,197.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:198.2,198.31 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:198.31,200.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:201.2,202.36 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:202.36,203.34 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:203.34,205.4 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:207.2,207.12 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:211.37,213.32 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:213.32,215.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:216.2,216.32 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:216.32,218.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:220.2,220.29 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:220.29,222.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:224.2,224.29 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:224.29,226.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:227.2,227.13 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:230.34,231.22 1 3
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:231.22,233.3 1 3
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:234.2,234.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:237.37,238.22 1 4
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:238.22,240.3 1 3
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:241.2,241.34 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:246.76,248.83 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:248.83,250.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:252.5,252.74 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:252.74,254.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:256.5,257.44 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:257.44,259.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:260.5,267.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:271.86,272.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:272.27,274.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:275.5,275.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:275.37,277.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:278.5,286.15 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:289.95,291.79 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:291.79,293.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:295.5,296.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:296.24,298.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:299.5,301.39 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:301.39,303.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:304.5,306.42 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:306.42,308.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:310.5,314.29 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:314.29,320.28 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:320.28,323.10 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:324.9,326.108 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:326.108,328.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:329.9,336.46 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:336.46,336.62 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:337.9,339.25 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:339.25,339.59 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:340.9,341.39 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:344.5,345.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:345.18,345.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:346.5,361.16 13 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:361.16,364.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:365.5,366.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:370.62,371.42 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:371.42,373.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:374.5,376.19 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:376.19,378.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:379.5,380.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:383.35,384.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:384.44,386.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:387.5,387.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:391.48,392.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:392.30,394.45 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:394.45,397.54 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:397.54,397.73 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:398.13,398.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:398.55,398.74 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:399.13,399.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:399.55,399.93 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:400.13,400.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:403.5,403.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:407.63,408.16 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:408.16,408.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:409.5,409.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:409.26,409.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:411.5,412.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:412.31,413.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:413.48,415.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:417.9,417.44 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:417.44,418.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:421.5,421.20 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:421.20,421.37 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:423.5,425.41 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:425.41,427.38 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:427.38,428.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:429.22,431.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:432.22,433.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:433.30,433.41 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:434.17,434.43 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:434.43,436.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:441.5,441.18 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:441.18,443.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:444.5,444.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:448.65,449.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:449.27,456.77 7 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:456.77,458.30 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:458.30,458.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:459.15,461.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:464.5,465.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:465.19,465.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:466.5,466.118 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:470.43,474.42 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:474.42,474.55 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:475.5,477.37 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:477.37,479.69 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:479.69,481.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:484.5,484.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:484.45,486.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:487.5,487.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:490.37,491.19 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:491.19,491.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:492.5,493.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:493.35,495.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_codeaction.go:496.5,496.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:14.48,17.55 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:17.55,24.19 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:24.19,26.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:27.3,27.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:27.25,31.10 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:31.10,34.5 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:37.2,38.73 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:43.67,44.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:44.22,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:47.2,51.48 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:51.48,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:53.8,56.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:57.2,57.46 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:62.99,65.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:67.98,70.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:72.160,77.52 4 17
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:77.52,80.3 2 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:81.2,81.51 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:81.51,83.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:85.2,90.86 4 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:90.86,95.3 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:96.2,96.87 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:96.87,99.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:101.2,101.83 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:101.83,104.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:107.5,107.129 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:107.129,109.6 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:112.2,115.29 3 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:115.29,117.3 1 14
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:118.2,120.32 3 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:120.32,122.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:124.5,125.32 2 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:125.32,127.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:128.5,131.16 3 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:131.16,135.3 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:136.2,140.19 4 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:140.19,142.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:143.2,144.75 2 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:148.38,149.16 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:149.16,151.3 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:152.2,155.42 2 4
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:155.42,157.3 1 4
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:157.8,160.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:161.2,161.27 1 4
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:165.91,166.79 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:166.79,168.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:168.63,171.4 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:173.2,173.14 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:177.119,181.24 2 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:181.24,183.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:184.2,185.13 2 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:185.13,187.68 2 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:187.68,189.4 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:191.2,191.19 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:191.19,193.3 1 3
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:195.2,196.12 2 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:196.12,198.28 2 12
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:198.28,200.12 2 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:202.3,202.8 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:204.2,206.50 3 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:206.50,208.3 1 4
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:209.2,209.23 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:213.193,215.9 2 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:215.9,217.3 1 6
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:218.2,223.32 6 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:223.32,225.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:226.2,227.24 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:227.24,229.3 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:230.2,236.33 5 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:236.33,238.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:239.5,240.40 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:240.40,242.20 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:242.20,244.21 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:244.21,246.5 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:247.4,247.59 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:247.59,249.21 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:249.21,251.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:253.4,253.40 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:253.40,257.5 3 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:259.8,259.23 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:259.23,261.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:262.2,262.19 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:267.55,269.15 2 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:269.15,271.6 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:272.5,272.9 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:272.9,276.26 4 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:276.26,278.10 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:279.9,280.23 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:280.23,282.10 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:283.9,285.16 3 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:286.27,288.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:289.24,289.24 0 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:297.60,299.22 2 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:299.22,301.6 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:302.5,303.9 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:303.9,307.29 4 3
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:307.29,311.20 4 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:312.31,314.29 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:315.28,317.25 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:321.9,323.20 3 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:328.177,334.33 3 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:334.33,336.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:337.2,337.18 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:337.18,339.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:340.2,340.17 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:344.101,346.57 2 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:346.57,347.78 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:347.78,349.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:351.2,351.19 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:351.19,353.3 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:354.2,354.19 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:354.19,356.3 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:357.2,357.61 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:357.61,358.57 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:358.57,360.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_completion.go:362.2,362.16 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:13.45,15.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:15.55,18.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:21.47,23.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:23.55,24.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:24.32,26.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:27.3,29.44 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:33.46,35.55 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:35.55,38.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:44.76,46.14 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:46.14,48.3 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:50.2,51.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:51.14,53.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:54.2,54.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:54.26,56.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:57.2,58.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:58.13,60.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:61.2,61.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:61.30,63.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:65.2,66.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:66.28,69.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:70.2,75.43 5 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:75.43,78.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:79.2,79.27 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:87.50,88.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:88.24,90.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:91.2,92.35 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:92.35,94.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:95.2,95.30 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:95.30,98.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:98.14,99.39 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:99.39,101.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:103.4,103.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:105.3,105.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:105.12,106.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:108.3,110.17 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:110.17,111.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:114.3,115.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:115.63,117.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:118.3,118.80 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:118.80,119.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:122.3,125.19 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:125.19,126.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:128.3,130.38 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:130.38,140.18 9 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:140.18,143.5 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:144.4,145.17 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:145.17,147.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:148.4,148.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:151.3,151.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:157.110,159.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:159.14,161.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:163.2,174.54 8 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:179.96,181.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:181.14,183.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:184.2,187.31 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:187.31,188.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:188.53,190.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:191.3,191.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:191.12,192.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:194.3,194.61 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:194.61,195.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:197.3,198.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:198.14,200.36 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:200.36,203.13 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:205.4,205.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:207.3,207.53 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:207.53,209.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:210.3,210.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:210.12,211.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:213.3,216.6 4 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:218.2,219.26 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:219.26,220.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:220.35,222.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:223.3,223.35 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:223.35,225.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:227.2,228.13 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:232.45,234.39 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:234.39,236.63 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:236.63,238.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:240.2,240.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:240.32,242.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:243.2,243.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:243.17,245.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:246.2,247.14 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:248.21,249.48 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:250.10,251.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:256.68,263.2 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:266.46,273.2 6 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:276.61,291.2 9 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:295.59,296.15 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_document.go:296.15,299.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:8.52,10.58 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:10.58,13.6 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:14.5,14.22 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:15.31,16.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:16.34,20.67 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:20.67,22.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:23.13,23.26 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:23.26,25.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:27.9,28.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_execute.go:29.13,32.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:10.48,12.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:12.24,14.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:15.2,26.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:29.38,31.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:33.46,35.2 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_init.go:37.31,40.2 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:13.55,15.32 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:15.32,17.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:18.2,18.13 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:22.41,27.2 4 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:29.41,34.2 4 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:36.32,39.23 3 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:39.23,41.3 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:42.2,43.24 2 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:43.24,45.3 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:46.2,49.15 4 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:49.15,51.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:52.2,55.211 4 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:59.51,60.41 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:60.41,62.3 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:63.2,65.71 3 4
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:68.110,69.14 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:69.14,73.3 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:74.2,76.18 3 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:79.118,80.14 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:80.14,83.16 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:83.16,86.35 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:86.35,88.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:89.4,89.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:89.36,91.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:92.4,94.59 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:94.59,96.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:97.4,97.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:100.2,103.19 4 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:106.51,107.23 1 14
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:107.23,109.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:110.2,110.13 1 14
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:110.13,112.100 2 22
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:112.100,114.12 2 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:116.3,116.8 1 13
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:118.2,118.11 1 14
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:121.32,123.2 1 7
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:126.44,127.53 1 17
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:127.53,129.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:130.2,130.40 1 16
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:133.40,135.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:135.20,136.40 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:136.40,138.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:140.3,140.8 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:142.2,142.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:142.12,144.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:145.2,145.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:148.52,149.38 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:149.38,151.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:152.2,153.27 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:153.27,154.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:154.34,155.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:157.3,157.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:157.36,158.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:160.3,160.25 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:162.2,162.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:171.67,173.22 2 36
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:173.22,175.12 2 47
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:175.12,177.4 1 23
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:178.3,180.63 2 24
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:180.63,182.12 2 12
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:184.3,185.12 2 12
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:185.12,187.4 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:188.3,189.48 2 10
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:189.48,191.12 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:193.3,194.18 2 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:194.18,196.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:198.3,199.29 2 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:201.2,201.24 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:207.46,209.32 2 16
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:209.32,211.3 1 16
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:212.2,212.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:212.34,214.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:215.2,215.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:215.32,217.32 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:217.32,219.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:221.2,221.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:225.83,228.102 2 10
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:228.102,230.36 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:230.36,232.136 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:232.136,234.5 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:235.4,237.34 3 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:237.34,239.5 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:243.2,243.65 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:243.65,244.53 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:244.53,246.37 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:246.37,248.137 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:248.137,250.6 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:251.5,253.35 3 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:253.35,255.6 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:259.2,259.19 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:263.80,264.22 1 10
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:264.22,266.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:267.2,269.40 3 10
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:269.40,271.3 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:272.2,272.34 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:272.34,273.31 1 85
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:273.31,274.12 1 68
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:276.3,277.16 2 17
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:277.16,278.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:280.3,280.32 1 17
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:280.32,282.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:284.2,284.19 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:287.36,289.2 1 85
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:292.39,294.13 2 14
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:294.13,296.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:297.2,299.66 3 14
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:299.66,301.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:302.2,303.54 2 14
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:303.54,305.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:306.2,306.51 1 14
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:306.51,308.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:309.2,311.69 3 14
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:311.69,314.3 2 4
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:315.2,315.10 1 10
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:319.43,321.13 2 6
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:321.13,323.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:324.2,325.11 2 6
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:325.11,327.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:328.2,329.14 2 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:329.14,331.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:332.2,333.19 2 4
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:337.56,339.89 2 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:339.89,341.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:342.2,342.14 1 8
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:346.52,347.32 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:347.32,349.28 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:349.28,351.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:352.3,352.34 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:352.34,354.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:355.3,355.42 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:355.42,357.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:358.3,358.49 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:360.2,363.27 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:363.27,365.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:366.2,366.36 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:366.36,368.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:369.2,372.49 3 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:372.49,374.24 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:374.24,376.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:379.2,380.25 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:380.25,382.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:383.2,383.33 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:383.33,385.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:386.2,387.19 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:391.67,393.35 2 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:393.35,395.3 1 9
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:396.2,397.31 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:397.31,399.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:400.2,400.14 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:403.69,404.37 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:404.37,406.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:407.2,407.47 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:410.50,412.22 2 37
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:412.22,414.12 2 42
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:414.12,416.4 1 27
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:417.3,419.32 3 15
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:419.32,421.4 1 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:422.3,423.35 2 10
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:423.35,425.12 2 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:427.3,428.12 2 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:428.12,430.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:431.3,432.49 2 5
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:432.49,434.12 2 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:436.3,436.14 1 4
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:438.2,438.14 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:441.67,444.28 3 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:444.28,446.12 2 3
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:446.12,447.9 1 1
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:449.3,451.12 3 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:451.12,452.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:454.3,454.43 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:454.43,456.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:458.3,458.23 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:458.23,460.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:462.3,463.48 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:463.48,465.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:467.3,467.25 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:467.25,469.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:471.3,472.50 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:472.50,474.4 1 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:475.3,476.22 2 2
+codeberg.org/snonux/hexai/internal/lsp/handlers_utils.go:478.2,478.14 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:72.90,75.20 3 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:75.20,77.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:78.2,80.23 3 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:80.23,82.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:83.2,84.22 2 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:84.22,86.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:87.2,88.27 2 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:88.27,90.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:91.2,97.38 6 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:97.38,100.3 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:100.8,102.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:103.5,106.38 4 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:106.38,108.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:109.5,109.38 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:109.38,111.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:113.2,115.46 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:115.46,115.71 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:117.46,117.64 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:126.2,126.10 1 1
+codeberg.org/snonux/hexai/internal/lsp/server.go:129.30,130.6 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:130.6,132.20 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:132.20,134.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:135.3,135.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:135.17,137.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:138.3,139.52 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:139.52,141.12 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:143.3,143.23 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:143.23,145.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:147.3,148.15 2 0
+codeberg.org/snonux/hexai/internal/lsp/server.go:148.15,150.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:14.48,17.6 3 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:17.6,19.17 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:19.17,21.4 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:22.3,22.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:22.17,23.9 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:25.3,26.22 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:26.22,27.12 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:29.3,31.14 3 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:32.25,34.18 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:34.18,36.5 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:37.4,37.21 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:40.2,40.24 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:40.24,42.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:43.2,44.50 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:44.50,46.3 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:47.2,47.17 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:50.38,52.16 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:52.16,55.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:56.2,57.57 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:57.57,60.3 2 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:61.2,61.45 1 0
+codeberg.org/snonux/hexai/internal/lsp/transport.go:61.45,64.3 2 0