Skip to content

feat(neovim): add known_human checkpoint plugin#1053

Open
svarlamov wants to merge 10 commits into
mainfrom
feat/known-human-neovim
Open

feat(neovim): add known_human checkpoint plugin#1053
svarlamov wants to merge 10 commits into
mainfrom
feat/known-human-neovim

Conversation

@svarlamov
Copy link
Copy Markdown
Member

@svarlamov svarlamov commented Apr 11, 2026

Summary

  • New Lua plugin (agent-support/neovim/) that fires git-ai checkpoint known_human --hook-input stdin on file save with 500ms debounce per git repo root
  • Uses BufWritePost autocmd + vim.loop.new_timer() for debounce
  • Uses vim.loop.spawn() for non-blocking async git-ai invocation
  • Follows the lazy.nvim opts = {} / setup() convention
  • New NeovimInstaller Rust struct that detects nvim and surfaces manual install instructions

Manual install steps (for docs site)

lazy.nvim (~/.config/nvim/init.lua)

{ 'git-ai-project/git-ai', opts = {} }

packer.nvim

use { 'git-ai-project/git-ai',
      config = function() require('git-ai').setup() end }

Native install

# Clone or copy plugin to Neovim rtp
cp -r agent-support/neovim ~/.local/share/nvim/site/pack/git-ai/start/git-ai

Or add to init.lua:

vim.opt.rtp:prepend('/path/to/agent-support/neovim')
require('git-ai').setup()

Test plan

  • cargo clippy -- -D warnings passes
  • cargo test passes

🤖 Generated with Claude Code


Open with Devin

Adds a Lua plugin for Neovim that fires git-ai checkpoint known_human
on file save with 500ms debounce per git repo root. Uses BufWritePost
autocmd, vim.loop timers for debounce, and vim.loop.spawn for async
non-blocking git-ai invocation. No auto-install; installer surfaces
manual steps for lazy.nvim, packer, and native rtp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment on lines +126 to +128
if opts.enabled == false then
vim.g.git_ai_enabled = false
return
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot Apr 11, 2026

Choose a reason for hiding this comment

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

🟡 setup({ enabled = false }) silently overridden by auto-load shim because setup() doesn't set loaded_git_ai

The plugin/git-ai.lua shim guards on vim.g.loaded_git_ai (agent-support/neovim/plugin/git-ai.lua:3), but M.setup() never sets this variable. For native installs where init.lua runs before plugin/ files are sourced, a user calling require('git-ai').setup({ enabled = false }) in init.lua will have their setting silently overridden: setup() sets git_ai_enabled = false and returns early at line 128 without setting loaded_git_ai, then the shim sees loaded_git_ai is nil, proceeds to call setup() again with defaults, which sets git_ai_enabled = true and creates the autocmd. The user's explicit disable is lost.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 9 additional findings in Devin Review.

Open in Devin Review

Comment thread src/mdm/agents/neovim.rs
Comment on lines +53 to +67
message: concat!(
"Neovim: Automatic installation is not supported. ",
"Install the plugin using one of these methods:\n",
"\n",
" lazy.nvim (recommended):\n",
" { 'git-ai-project/git-ai', opts = {} }\n",
"\n",
" packer.nvim:\n",
" use { 'git-ai-project/git-ai',\n",
" config = function() require('git-ai').setup() end }\n",
"\n",
" Native (~/.config/nvim/init.lua):\n",
" vim.opt.rtp:prepend('/path/to/agent-support/neovim')\n",
" require('git-ai').setup()",
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 Neovim install_extras message is silently dropped because it doesn't match any display condition

The Neovim install_extras returns changed: false and a message "Neovim: Automatic installation is not supported. ...". In install_hooks.rs:570-588, the display logic only shows messages when: (1) result.changed is true, (2) message contains "already", or (3) message contains "Unable" or "manually". The Neovim message matches none of these conditions, so the manual installation instructions are never displayed to the user during git-ai install-hooks. Since the entire purpose of the Neovim installer is to show these instructions (it can't auto-install), the feature added by this PR is effectively non-functional.

Display condition matching
  • result.changed = false → branches at lines 570 and 574 skip
  • "already" → not in "Automatic installation is not supported" → line 578 skips
  • "Unable" or "manually" → not in the message → line 582 skips

Result: no spinner is created, no output is shown for Neovim.

Suggested change
message: concat!(
"Neovim: Automatic installation is not supported. ",
"Install the plugin using one of these methods:\n",
"\n",
" lazy.nvim (recommended):\n",
" { 'git-ai-project/git-ai', opts = {} }\n",
"\n",
" packer.nvim:\n",
" use { 'git-ai-project/git-ai',\n",
" config = function() require('git-ai').setup() end }\n",
"\n",
" Native (~/.config/nvim/init.lua):\n",
" vim.opt.rtp:prepend('/path/to/agent-support/neovim')\n",
" require('git-ai').setup()",
)
message: concat!(
"Neovim: Unable to install automatically. ",
"Install the plugin using one of these methods:\n",
"\n",
" lazy.nvim (recommended):\n",
" { 'git-ai-project/git-ai', opts = {} }\n",
"\n",
" packer.nvim:\n",
" use { 'git-ai-project/git-ai',\n",
" config = function() require('git-ai').setup() end }\n",
"\n",
" Native (~/.config/nvim/init.lua):\n",
" vim.opt.rtp:prepend('/path/to/agent-support/neovim')\n",
" require('git-ai').setup()",
)
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 10 additional findings in Devin Review.

Open in Devin Review

Comment on lines +104 to +105
local lines = vim.api.nvim_buf_get_lines(args.buf, 0, -1, false)
local content = table.concat(lines, '\n')
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot Apr 11, 2026

Choose a reason for hiding this comment

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

🟡 Missing trailing newline in dirty_files content causes spurious diffs

On line 104-105, nvim_buf_get_lines(buf, 0, -1, false) returns lines without terminators, and table.concat(lines, '\n') joins them—producing content that lacks a trailing newline. Most files on disk (and in git) end with \n, and the VSCode known-human extension at agent-support/vscode/src/known-human-checkpoint-manager.ts:90 uses doc.getText() which preserves it. Because the checkpoint pipeline compares dirty_files content against working-tree or tracked content (e.g. src/daemon.rs:1686: tracked_content != target_content), the systematically missing trailing newline will cause every file to appear "changed" on every save, generating unnecessary checkpoint work and potentially skewing character-level attribution by one byte.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@svarlamov
Copy link
Copy Markdown
Member Author

@heapwolf this was vibe coded fyi -- no idea what the right way to do this in (neo)vim would be

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