Skip to content

Wire LSP diagnostics into self-correct (exec + TUI)#191

Merged
Vasanthdev2004 merged 7 commits into
mainfrom
feat/wire-selfcorrect-lsp
Jun 14, 2026
Merged

Wire LSP diagnostics into self-correct (exec + TUI)#191
Vasanthdev2004 merged 7 commits into
mainfrom
feat/wire-selfcorrect-lsp

Conversation

@gnanam1990

@gnanam1990 gnanam1990 commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Wires the LSP-diagnostics half of the post-edit self-correct loop. It was built and
tested but never connected — the only consumer passed a nil checker with
IncludeLSP=false, which left the entire internal/lsp client unreachable.

  • exec (internal/cli/exec.go): newExecSelfCorrector now backs --self-correct with
    both halves — the workspace test plan and an lsp.Manager-based diagnostics checker
    (IncludeLSP=true). The manager is lazy (Manager.Check degrades a missing/unsupported
    language server to nil, nil) and a deferred cleanup shuts it down at run end.
  • TUI (internal/tui/model.go): self-correct now runs by default every turn, but
    kept fast — only the LSP-diagnostics half, scoped to the changed files. The whole-repo
    test plan is opt-in per session via a new /selfcorrect [on|off] command (alias
    /sc), so it never adds go test ./... latency to a turn and a pre-existing failure can't
    hijack the agent. Spec-draft (planning) is excluded; the per-turn lsp.Manager is torn
    down at run end; auto-fix vs report-only follows the active permission mode
    (unsafe→high, auto→medium, ask→low).
  • Adds TestManagerCheckRealGopls: drives NewManager → Check against a real gopls and
    asserts a real diagnostic; skips when gopls is absent, so it stays CI-safe.

Effect

Revives internal/lsp (44 → 3 unreachable funcs); total prod-unreachable 178 → 135.

Why fast-by-default in the TUI

The test half (go test ./...) is whole-project and slow (up to a 120s timeout); the LSP
half is change-scoped and cheap. Running the full suite after every interactive edit would
add the suite's latency to each turn and re-surface pre-existing failures every time. So the
TUI defaults to LSP-only and gates the test half behind /selfcorrect on. exec keeps both
halves (it is headless and already opt-in via --self-correct).

Verification

  • go build ./..., go vet, gofmt clean; full go test ./... green.
  • The real-gopls test returns the expected compiler diagnostic through the wired path.
  • Manual end-to-end: a --self-correct run surfaces and fixes a seeded compile error that
    the baseline run leaves broken; the gopls serve process spawns mid-run and is cleaned
    up at the end.

Commits

  1. exec LSP wiring + real-gopls test
  2. TUI wiring
  3. TUI fast-by-default + /selfcorrect toggle

Summary by CodeRabbit

  • New Features
    • Added a TUI /selfcorrect command (alias /sc) to control post-edit self-correction depth, including LSP-only diagnostics or broader test-plan verification.
  • Bug Fixes
    • Improved self-correction verification by collecting LSP diagnostics during the post-edit loop and ensuring the LSP service shuts down cleanly after runs.
    • Updated LSP document close handling to avoid lingering session state.
  • Tests
    • Added an integration-style manual test that runs diagnostics using the real gopls binary (skips if not available).

newExecSelfCorrector now backs the --self-correct loop with both halves: the
workspace test plan AND an lsp.Manager-based diagnostics checker (IncludeLSP=true).
The manager is lazy (Manager.Check degrades a missing language server to nil,nil),
and a deferred cleanup shuts it down at run end, terminating any spawned sessions.

This revives the internal/lsp client (44 -> 3 unreachable funcs); it was dead
because the only consumer passed a nil checker with IncludeLSP=false.

Add TestManagerCheckRealGopls: drives NewManager -> Check against a real gopls and
asserts a real diagnostic; skips when gopls is absent, so it stays CI-safe.
runAgentWithOptions now builds a SelfCorrector for every turn, so post-edit
verification (workspace test plan + LSP diagnostics) runs by default in the TUI.
The spec-draft planning path is excluded, matching exec. A per-turn lsp.Manager
is created and torn down when the run returns. Auto-fix vs report-only follows
the active permission mode (unsafe->high, auto->medium, ask/other->low) via
selfCorrectAutonomyForMode.
@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Zero automated PR review

Verdict: No blockers found

Blockers

  • None found.

Validation

  • [pass] Diff hygiene: git diff --check
  • [pass] Tests: go test ./...
  • [pass] Build: go run ./cmd/zero-release build
  • [pass] Smoke build: go run ./cmd/zero-release smoke

Scope

Head: 0b634f53dfbb
Changed files (6): internal/cli/exec.go, internal/lsp/documents.go, internal/lsp/real_gopls_manual_test.go, internal/tui/commands.go, internal/tui/model.go, internal/tui/session_controls.go

This deterministic review checks validation status and basic diff hygiene. A human reviewer still owns product judgment and design quality.

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f709a2c4-96f7-472a-934a-9d90d5d00c5a

📥 Commits

Reviewing files that changed from the base of the PR and between e746120 and 0b634f5.

📒 Files selected for processing (1)
  • internal/tui/commands.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/tui/commands.go

Walkthrough

LSP diagnostics are now collected during the post-edit self-correct loop in both the CLI exec path and the TUI. Both entry points create a per-run lsp.Manager, defer its timed shutdown, and wire it into agent.NewSelfCorrector with IncludeLSP: true. The TUI additionally maps PermissionMode to autonomy levels, exposes user-facing /selfcorrect commands to toggle between LSP-only and full test verification, enables default self-correction in the model, and removes unused document close-notification handling from LSP session management. A real-gopls integration test validates that Manager.Check returns error diagnostics for deliberately broken code.

Changes

LSP diagnostics wiring into self-correct loop

Layer / File(s) Summary
CLI exec: LSP manager lifecycle and self-corrector wiring
internal/cli/exec.go
Imports internal/lsp; refactors newExecSelfCorrector to return (*agent.SelfCorrector, func()), constructing an lsp.Manager and wiring agent.NewLSPDiagnosticsChecker with IncludeLSP: true when enabled, plus a shutdown cleanup. runExec now defers the returned cleanup.
TUI model: LSP integration, autonomy mapping, and default self-corrector setup
internal/tui/model.go
Adds lsp import; introduces selfCorrectTests field controlling whether tests are included in post-edit verification; adds selfCorrectAutonomyForMode helper mapping PermissionMode to "high"/"medium"/"low"; wires commandSelfCorrect dispatch; and extends runAgentWithOptions to create a default SelfCorrector with an lsp.Manager, deferred timed shutdown, configurable tests and LSP, and autonomy level — unless in specDraft mode or Cwd is empty.
TUI self-correct command: definition, handler, and status rendering
internal/tui/commands.go, internal/tui/session_controls.go
Adds commandSelfCorrect enum and registers /selfcorrect command with /sc alias. Implements handleSelfCorrectCommand to parse on/off/tests/lsp arguments, update model state, and render a status view reflecting whether verification runs LSP diagnostics only or includes the full test plan.
Real gopls integration test
internal/lsp/real_gopls_manual_test.go
Adds TestManagerCheckRealGopls: skips if gopls is not on PATH, writes a temporary Go module containing a type error, calls Manager.Check against real gopls, and asserts at least one SeverityError diagnostic is returned with proper manager shutdown during test cleanup.
LSP session document close handling removal
internal/lsp/documents.go
Removes session.didClose method that previously deleted document URIs from open-state tracking and sent textDocument/didClose notifications. ⚠️ Review for side effects: verify that document lifecycle is now handled correctly elsewhere or that close notifications are intentionally no longer needed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Gitlawb/zero#176: Introduced SelfCorrector.AfterEdit, IncludeLSP, and NewLSPDiagnosticsChecker — the exact contracts this PR wires up in exec.go and tui/model.go.
  • Gitlawb/zero#175: Added the lsp.Manager and diagnostics plumbing that this PR depends on for both the CLI and TUI self-correct paths.

Suggested reviewers

  • Vasanthdev2004
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: wiring LSP diagnostics into the self-correct feature across both exec and TUI interfaces.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/wire-selfcorrect-lsp

Comment @coderabbitai help to get the list of available commands and usage tips.

@gnanam1990
gnanam1990 requested review from Vasanthdev2004 and anandh8x and removed request for anandh8x June 14, 2026 04:37
…fcorrect

The TUI default now runs only the LSP-diagnostics half of self-correct — cheap and
scoped to the changed files — so it never adds the whole-repo test plan's latency to a
turn (and a pre-existing failure can't hijack the agent). The project test plan is opt-in
per session via a new /selfcorrect [on|off] command (alias /sc); IncludeTests reads
m.selfCorrectTests, default false. exec keeps both halves.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/tui/commands.go`:
- Around line 208-210: Update the usage field for the /selfcorrect command
definition (at the usage line in the command struct around line 208) to include
all accepted arguments. The usage string currently shows only [on|off] but the
command handler also accepts status, list, tests, full, and lsp as valid
arguments. Expand the usage string to reflect all these options so users can
discover the full command capabilities through the help text.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fdd08b2b-dd43-458a-a987-3e5a01689b95

📥 Commits

Reviewing files that changed from the base of the PR and between 9347d1a and 79c6e05.

📒 Files selected for processing (3)
  • internal/tui/commands.go
  • internal/tui/model.go
  • internal/tui/session_controls.go

Comment thread internal/tui/commands.go Outdated
session.didClose sent a textDocument/didClose notification but was never called (the
manager only closes documents via Shutdown), so it was unreachable even from tests and
flagged by staticcheck U1000. Removing it takes internal/lsp to 0 truly-dead funcs and 0
U1000 findings; the 2 remaining unreachable-from-main funcs (Available, URIToPath) are
public, test-covered API.
The usage/description advertised only [on|off] but the handler also accepts status,
list, tests, full, and lsp. Surface the primary verbs (on|off|status) and clarify the
on/off behavior so command discovery matches the handler (CodeRabbit).
@gnanam1990

Copy link
Copy Markdown
Collaborator Author

Addressed the /selfcorrect help-text finding in d680258usage is now [on|off|status] and the description clarifies the on/off behavior, so help matches the handler. Aliases (tests/full/lsp/list) still work; the usage surfaces the primary verbs.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

@gnanam1990: Got it — the help-text fix looks solid. Triggering a re-review now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Vasanthdev2004 Vasanthdev2004 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: Request changes

The runtime wiring looks good and validation is green, but one user-facing help issue is still present:

  • internal/tui/commands.go:208 documents /selfcorrect [on|off], while handleSelfCorrectCommand also accepts status, list, tests, full, and lsp.
  • internal/tui/session_controls.go:197 returns the same incomplete usage text for invalid arguments.

Please update both usage strings to reflect the accepted forms, for example:

/selfcorrect [status|on|off|tests|full|lsp]

Validation I ran locally on the PR head:

  • git diff --check origin/main...HEAD
  • go test ./internal/cli ./internal/tui ./internal/lsp ./internal/agent -run 'SelfCorrect|LSP|Manager|Command|Exec' -count=1 -timeout 180s
  • go test ./internal/cli ./internal/tui ./internal/lsp -count=1 -timeout 240s
  • go test ./... -timeout 300s

Once the usage text is fixed, I do not see another blocker from this pass.

Both the command definition and the invalid-argument error message now list the full
accepted set [status|on|off|tests|full|lsp]; the redundant 'list' alias is dropped so docs
and handler agree exactly. Addresses Vasanth's review (the error-message usage at
session_controls.go was still [on|off]) and CodeRabbit's help-text finding.
@gnanam1990

Copy link
Copy Markdown
Collaborator Author

@Vasanthdev2004 thanks — fixed in e746120. Both usage strings now list the full accepted set and match the handler exactly:

  • internal/tui/commands.go: usage → /selfcorrect [status|on|off|tests|full|lsp]
  • internal/tui/session_controls.go: the invalid-argument error message now returns the same string (this was the spot the first fix missed)

Dropped the redundant list alias so the documented forms == the handler's accepted forms exactly. go test ./internal/cli ./internal/tui ./internal/lsp ./internal/agent green.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

@gnanam1990: Solid — the usage string and error message now match the handler exactly, and dropping list keeps the surface clean. Triggering a re-review of the latest commits now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/tui/commands.go (1)

210-210: ⚡ Quick win

Consider clarifying "off" semantics for UX.

The phrase "off/lsp return to LSP-only" may confuse users—"off" could be interpreted as "disable entirely" rather than "disable tests, keep LSP." More explicit phrasing would improve discoverability: e.g., "off/lsp disable tests (LSP-only)" or "off/lsp: LSP-only mode".

📝 Example revision
-		description: "Show or set post-edit self-correction depth (LSP-only default; on/tests/full add the project test plan; off/lsp return to LSP-only).",
+		description: "Show or set post-edit self-correction depth (LSP-only default; on/tests/full add the project test plan; off/lsp disable tests, LSP-only).",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/tui/commands.go` at line 210, The description string for the
post-edit self-correction depth option in the commands.go file is ambiguous. The
phrase "off/lsp return to LSP-only" may confuse users who could interpret "off"
as disabling the feature entirely rather than disabling tests while keeping LSP
functionality. Replace this phrase with clearer language that explicitly states
what the "off" option does, such as "off/lsp disable tests (LSP-only)" or
"off/lsp: LSP-only mode" to improve user discoverability and reduce confusion
about the actual behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/tui/commands.go`:
- Line 210: The description field in the commands.go file contains a comma
splice where two independent clauses are joined by a comma instead of a
semicolon. In the description string that starts with "Show or set post-edit
self-correction depth", replace the comma before "off/lsp return to LSP-only"
with a semicolon to properly separate the independent clauses and maintain
grammatical correctness in the user-facing help text.

---

Nitpick comments:
In `@internal/tui/commands.go`:
- Line 210: The description string for the post-edit self-correction depth
option in the commands.go file is ambiguous. The phrase "off/lsp return to
LSP-only" may confuse users who could interpret "off" as disabling the feature
entirely rather than disabling tests while keeping LSP functionality. Replace
this phrase with clearer language that explicitly states what the "off" option
does, such as "off/lsp disable tests (LSP-only)" or "off/lsp: LSP-only mode" to
improve user discoverability and reduce confusion about the actual behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b0065e33-0a10-4c96-9352-5b18dd7b2233

📥 Commits

Reviewing files that changed from the base of the PR and between d680258 and e746120.

📒 Files selected for processing (2)
  • internal/tui/commands.go
  • internal/tui/session_controls.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/tui/session_controls.go

Comment thread internal/tui/commands.go Outdated
Reword the description so 'off/lsp' reads as 'disable tests, LSP-only' rather than the
ambiguous 'return to LSP-only', which could be misread as disabling the feature entirely
(CodeRabbit).
@gnanam1990

Copy link
Copy Markdown
Collaborator Author

Addressed the description nitpick in 0b634f5/selfcorrect help now reads "off/lsp disable tests, LSP-only" instead of the ambiguous "return to LSP-only".

@coderabbitai review

@Vasanthdev2004 Vasanthdev2004 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: Approved

The previous requested change is fixed on the latest head (e746120):

  • internal/tui/commands.go now documents /selfcorrect [status|on|off|tests|full|lsp].
  • internal/tui/session_controls.go now returns the same usage string for invalid args.
  • The handler accepts exactly those documented args now (status, on, off, tests, full, lsp).

I rechecked the LSP self-correct wiring and did not find a functional blocker. One note: CodeRabbit has a fresh wording nit on the /selfcorrect description (off/lsp return to LSP-only could be clearer), but I do not consider that a blocker from this review.

Validation run locally on PR head:

  • git diff --check origin/main...HEAD
  • go test ./internal/cli ./internal/tui ./internal/lsp ./internal/agent -run 'SelfCorrect|LSP|Manager|Command|Exec' -count=1 -timeout 180s
  • go test ./internal/cli ./internal/tui ./internal/lsp -count=1 -timeout 240s
  • go test ./... -timeout 300s
  • go vet ./...
  • go build ./...
  • go run ./cmd/zero-release build
  • go run ./cmd/zero-release smoke

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

@gnanam1990: Clean fix — "off/lsp disable tests, LSP-only" is unambiguous and directly maps to the handler behavior. Triggering a re-review now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Vasanthdev2004
Vasanthdev2004 merged commit e0dd67a into main Jun 14, 2026
6 checks passed
@Vasanthdev2004
Vasanthdev2004 deleted the feat/wire-selfcorrect-lsp branch June 28, 2026 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants