summaryrefslogtreecommitdiff
path: root/internal/lsp
AgeCommit message (Collapse)Author
2026-06-11Extract shared chatrun package to eliminate chat-runner DRY violationsPaul Buetow
The CLI, LSP server and tmux code-action tool each carried near-identical chat-running logic: invoking the LLM (streaming-aware), collecting the response, and accounting sent/received bytes into the stats package. Introduce internal/chatrun with: - Invoke: streaming-aware LLM call that collects the full response and optionally mirrors chunks to a writer (nil writer = collect only). - SentBytes / Account: shared byte counting and stats.Update. Wire all three surfaces to it: - hexaicli: runChatRequest delegates to chatrun.Invoke; summarizeChatRun uses chatrun.Account. Removed the duplicated streaming/simple helpers. - hexaiaction: runOnce uses chatrun.Invoke + chatrun.Account, keeping the tmux status update local. - lsp: chatWithStats and the completion path use chatrun.SentBytes/Invoke; extracted unavailableClientError to keep chatWithStats small. chatrun has 100% test coverage; full suite passes with -race. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11Refactor lsp.Server God Object: extract chat and completion subsystemsPaul Buetow
The Server type accumulated two large, tangled feature subsystems (in-editor chat and code completion) alongside its core LSP dispatch role. Pull them into cohesive types that own their state and logic while delegating shared infrastructure back to Server via a back-reference. - Add completionService (completion_service.go): owns the completion cache/throttle state (completionState) and all completion request-handling logic (handleCompletion, plan/jobs/execute, provider-native path, post-processing, message building, prefix heuristics). Methods moved off Server in handlers_completion.go to completionService. - Add chatService (chat_service.go + chat_handlers.go): owns the input-activity clock (lastInput, with its own mutex instead of Server.mu) and all in-editor chat logic (detection, transcript history, message building, edit application, inline prompts) plus the slash-command handlers (chat_commands.go). - Server now holds chat/completion fields, wires them in NewServer, and delegates (dispatch table, didChange, debounce gate) to them. Thin Server shims preserve the existing completion-state API for callers/tests. Pure refactor: no behavior or LSP protocol changes. Tests adjusted only to reach the relocated methods/state via the services. All tests pass with -race; coverage 86.1%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10lsp: rename 'close' return to 'closeStr' in inlineMarkers to avoid shadowing ↵Paul Buetow
builtin The named return value 'close' in Server.inlineMarkers() shadowed the Go builtin 'close'. Renamed it to 'closeStr' (matching the 'openStr' naming used by callers) and added a comment explaining the reasoning. Callers use positional returns, so no call sites changed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-26fix(lsp): stop timer leak in deferShowDocumentPaul Buetow
Replace time.After with time.NewTimer + defer timer.Stop() to prevent a leaked goroutine when the context is cancelled before the timer fires.
2026-04-26feat: default to Ollama Cloud (kimi-k2.6) when no provider configuredPaul Buetow
Switches the in-code defaults so that hexai talks to Ollama Cloud (https://ollama.com) with model kimi-k2.6 when no provider is configured, instead of OpenAI. The example config, README, and configuration guide all reflect the new recommended setup; previous OpenAI / local-Ollama options are still documented as alternatives. Tests that depended on the implicit "openai" default now pin the provider explicitly so they continue to exercise the OpenAI / gpt-5 code paths they were designed to cover. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-03-23chore: bump version to v0.25.9v0.25.9Paul Buetow
Code quality fixes from audit: - Log silently discarded errors in status sinks and stats.Update call sites - Fix json.Marshal errors silently ignored in LSP handlers - Replace time.Sleep in tests with channel signaling (mcp) and fake clock (stats) - Make context cancellation work in production time.Sleep sites (handlers_document, cmdentry) - Remove init()-based provider registration from llm package; use explicit RegisterAllProviders() - Add WaitGroup goroutine tracking to MCP server Run() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23refactor: split oversized functions, fix double logging, add %w wrappingPaul Buetow
- lsp/handlers_completion.go: extract buildNativeCompletionCacheKey and postProcessNativeCompletion; track collectFirstCompletion in inflight; remove redundant logLLMStats("") on error path - lsp/handlers.go: extract checkTriggerFromContext and checkTriggerFromCursorChar; isTriggerEvent reduced from 63→10 lines - lsp/transport.go: use %w for error wrapping in Content-Length parse - llm/ollama.go: extract parseOllamaStream; ChatStream reduced to ~35 lines - appconfig/config_load.go: extract decodeModelEntryFromMap; rename 'any' to 'found'; decodeModelEntry reduced to ~18 lines - llm/provider.go: document why providerRegistry is package-level - integrationtests/ask_test.go: add //go:build integration; move repoRoot init from init() to TestMain with diagnostic message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23fix: code quality improvements across lsp, askcli, appconfig, integrationtestsPaul Buetow
- lsp/handlers_completion.go: track collectFirstCompletion goroutine in inflight WaitGroup (goroutine leak fix) - lsp/transport.go: use %w instead of %v for error wrapping - askcli/command_list.go: extract handleListWithFilters shared helper; handleList/handleAll/handleReady are now single-liners - askcli/command_list.go, urgency.go, dep.go: log ParseTaskExport errors to stderr instead of returning 1 silently - appconfig/config_load.go: rename 'any' variable to 'found' to avoid shadowing the built-in identifier - llm/provider.go: add explanatory comment for package-level registry - integrationtests/ask_test.go: add //go:build integration tag; move repoRoot init from init() to TestMain with diagnostic error message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23fix: address all HIGH-severity code quality audit findingsPaul Buetow
- lsp/server.go: track request goroutines in inflight WaitGroup to prevent use-after-close writes on shutdown - lsp/llm_client_registry.go: acquire write lock before calling build() to eliminate TOCTOU race on cache population - lsp/handlers_codeaction.go: resolveSimplifyCodeAction now uses PromptCodeActionSimplify{System,User} (was wrongly using rewrite prompts) - askcli/taskexport.go: remove exported MustParseTaskExport to prevent panic on malformed external input; move to unexported test helper - cmd/ask/main.go: print error to stderr before os.Exit - llm/{openai,ollama,openrouter}.go: add interface satisfaction assertions - integrationtests/ask_test.go: replace type assertions with errors.As for robust exec.ExitError unwrapping Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19Improve actionable error guidancePaul Buetow
2026-03-17Fix bugs, remove duplication, and clean up code quality issuesPaul Buetow
- Log swallowed JSON unmarshal errors in stats and LSP handlers - Fix debug log file handle leak in tmuxedit (return closer from initDebugLog) - Check f.Close() errors on write paths in promptstore and tmuxedit - Fix cacheGet TOCTOU race by using single write lock - Fix readInput to use passed stdin reader instead of os.Stdin.Stat() - Remove 45 'moved to' comment tombstones from lsp/handlers.go - Deduplicate canonicalProvider wrappers (use llmutils.CanonicalProvider directly) - Remove SetWindow side effect from stats.TakeSnapshot (pure read now) - Move duplicated splitLines to textutil.SplitLinesBytes - Collapse StatusSink.SetGlobal 10 params into GlobalStatus struct - Simplify LRU touchLocked to in-place delete-and-append Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16Strengthen LLM stats counter tests with value assertionsPaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Fix byte vs UTF-16 indexing in LSP position handlingPaul Buetow
Adds utf16OffsetToByteOffset helper to correctly convert LSP character positions (UTF-16 code units) to Go string byte offsets. Fixes trigger detection, prefix heuristic, and completion text slicing for files containing multi-byte characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Extract LLM stats counters into llmStatsSubsystemPaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Document lock ordering, fix test data races, correct stateMu guardPaul Buetow
- Add doc comments clarifying Server.mu and completionState.stateMu are independent (no ordering constraint). - Fix test using wrong lock (s.mu instead of stateMu) for lastLLMCall. - Replace time.Sleep polling in 7 tests with s.inflight.Wait() to eliminate data races under -race. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Add Snapshot.ScopeReqs/ScopeRPM and simplify 3 callersPaul Buetow
Centralizes the provider+model map traversal and window-minutes guard that was duplicated in hexaiaction, hexaicli, and lsp. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Track fire-and-forget goroutines with sync.WaitGroup for clean shutdownPaul Buetow
Adds inflight WaitGroup to Server and wraps inline-prompt, chat-response, and deferShowDocument goroutines. Run() waits for all in-flight work before returning. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Replace Summary: prefixes with standard Go package doc commentsPaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Make deferShowDocument respect serverCtx for graceful shutdownPaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Use atomic.Int64 for LLM stats counters instead of server-wide mutexPaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Address review: add zero-temp test, remove unused surface parameterPaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Centralize GPT-5 temperature override into llmutils.ResolveTemperaturePaul Buetow
Eliminates identical temperature resolution logic duplicated in hexaiaction, hexaicli, and lsp packages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Add bounds checks to extractRangeText and split into helper functionsPaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Use read lock for cache misses in completionState.cacheGetPaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Replace interface{} with any in LSP typesPaul Buetow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Add doc comments to exported types and functionsPaul Buetow
Document ~30 exported types in lsp/types.go and exported functions in llm/provider.go, lsp/server.go, and hexailsp/run.go. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16Decompose App God struct into embedded section structsPaul Buetow
Replace 60+ flat fields in App with 4 embedded section structs: CoreConfig, ProviderConfig, PromptConfig, FeatureConfig. Go field promotion preserves all existing field access patterns. Updated flattenAppConfig to recurse into embedded structs for runtimeconfig. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10task bf088a70: extract LSP client and completion statePaul Buetow
2026-03-02lsp: inject StatusSink to decouple core from tmux package (task 407)Paul Buetow
2026-03-02io: use errors.Is for EOF checks in lsp and mcp servers (task 409)Paul Buetow
2026-03-02gotest: extract Go codegen heuristics from lsp handlers (task 406)Paul Buetow
2026-03-02lsp: use appconfig.CustomAction directly for custom actions (task 411)Paul Buetow
2026-03-02lsp: decompose tryLLMCompletion orchestration helpers (task 415)Paul Buetow
2026-03-02lsp: decompose resolveGoTest workflow into helpers (task 416)Paul Buetow
2026-03-02lsp: decompose detectAndHandleChat into focused helpers (task 418)Paul Buetow
2026-03-02llmutils: remove remaining default-model wrappers in callers (task 413)Paul Buetow
2026-03-02lsp: cancel handler contexts on shutdown via server context (task 423)Paul Buetow
2026-03-02lsp: use context-mode registry for additional context dispatch (task 408)Paul Buetow
2026-03-02lsp: extract completion/chat/codeaction server subtypes (task 406)Paul Buetow
2026-03-02lsp: make exit flag atomic to avoid data race (task 406)Paul Buetow
2026-03-02lsp: handle code action payload marshal errors (task 406)Paul Buetow
2026-03-02lsp: simplify ServerOptions to config-first model (task 410)Paul Buetow
2026-03-02lsp: return cleanly on exit and propagate runner errors (task 410)Paul Buetow
2026-03-02llmutils: centralize provider normalization and client setup (task 410)Paul Buetow
2026-03-02codeaction: add Build/Resolve handler registries (task 410)Paul Buetow
2026-02-08add gitignore-aware file filtering for LSP completions and code actionsPaul Buetow
Files matching .gitignore patterns or user-configured extra patterns are now skipped for completions and code actions. Configurable via [ignore] section in config.toml with gitignore, extra_patterns, and lsp_notify_ignored options. Includes hot-reload support and env var overrides (HEXAI_IGNORE_*). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06Remove GitHub Copilot provider supportpaul@buetow.org
Remove all GitHub Copilot integration from the codebase to streamline the supported provider set to OpenAI, OpenRouter, Anthropic, and Ollama. Changes: - Delete core Copilot implementation (copilot.go) and all related tests - Remove Copilot configuration fields from App struct and Config - Remove Copilot from provider factory and API key handling - Update all test files to replace Copilot references with other providers - Remove Copilot documentation from README, configuration guide, and examples - Remove Copilot section from config.toml.example All tests pass successfully after removal. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06fix: add missing Anthropic and OpenRouter provider support in config and LSPpaul@buetow.org
- Add Anthropic field merging in config.mergeProviderFields() to properly load AnthropicModel/BaseURL/Temperature from config.toml - Add anthropic and openrouter cases in lsp.resolveDefaultModel() to prevent fallback to OpenAI defaults - Update default Anthropic model to valid claude-3-5-sonnet-20240620 (previous 20241022 doesn't exist) - Update test expectation to match new default model This fixes the issue where Anthropic provider configuration was ignored, causing LSP to return dummy completions instead of real LLM responses. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-01fix: pass RequestTimeout to all llm.Config instancesFlorian
Add RequestTimeout field to llm.Config construction in: - internal/hexailsp/run.go (buildClientIfNil) - internal/llmutils/client.go (NewClientFromApp) - internal/lsp/server.go (newClientForProvider) This ensures the configured timeout is used in all code paths, not just the ones already updated.
2026-01-30feat: add completion_wait_all config and fix Anthropic system messagesPaul Buetow
- Add completion_wait_all config option (default true) to wait for all backends before returning results, or return first result immediately - Fix Anthropic API: extract system messages to top-level system field as required by Messages API (was causing 400 errors) - Add anthropic case to server.go clientFor() for model overrides