# AGENTS.md ## Project Overview `hobs.nvim` is a Neovim plugin for concurrent AI-assisted programming. The core idea is that AI agents should work **alongside** the human rather than forcing a blocking request/response workflow. A user can select some code and run: ```vim :Hob ``` The plugin launches an OpenCode agent for that task while the user continues editing normally. The long-term goal is to let multiple AI "hobs" work concurrently against Neovim's live buffers, with human edits always taking precedence. ## Design Philosophy The most important rule is: > Agents must never require the editor to stop moving. Human and AI work should be concurrent. The intended priority model is: ```text human edits authoritative agent edits conditional AI suggestions speculative ``` Agent behavior should be designed around optimistic concurrency rather than exclusive ownership of files or buffers. Do not introduce workflows that require the user to avoid editing while an agent is running. ## Current MVP The MVP is intentionally simple. When the user visually selects code and runs: ```vim :Hob ``` the plugin: 1. Captures the current filename. 2. Captures the visual selection range. 3. Captures the raw selected text. 4. Creates an extmark associated with the task. 5. Displays agent status near the selected code. 6. Runs: ```sh opencode run ``` 7. Instructs OpenCode to return a `sed` script. 8. Applies that script against the current live buffer when the agent completes. The `sed` approach is temporary. It exists only to validate the concurrent editing interaction model. Do not over-engineer the sed layer. It is expected to be replaced. ## Future Architecture The likely long-term architecture is: ```text Neovim | live buffer state | overridden OpenCode tools | OpenCode | LLM ``` OpenCode's built-in filesystem tools will eventually be overridden so operations against files loaded in Neovim use live buffer contents instead of stale on-disk contents. Likely overridden tools include: ```text read edit write grep apply_patch ``` Files not loaded into Neovim may continue to use ordinary filesystem operations. Dynamic connection state should be passed through environment variables rather than generated OpenCode configuration. The plugin may ship its own OpenCode configuration directory and launch OpenCode with: ```sh OPENCODE_CONFIG_DIR=/opencode ``` ## Concurrency Model Never rely on absolute line numbers for delayed edits. Line and column information may be supplied to an agent as initial context, but it is not authoritative once the user continues editing. Prefer content-addressed edits. A future edit operation should work conceptually like: ```text read current text | v identify expected old text | v attempt replacement | +-- still matches --> apply | +-- changed -------> conflict / reread ``` If the human modifies code that an agent previously read, the agent must not silently overwrite the human's changes. The human always wins conflicts. ## Extmarks Use Neovim extmarks for persistent task anchors. Extmarks are appropriate for: * tracking the original task region; * anchoring agent status UI; * tracking suggestions; * following code as lines are inserted or deleted around it. Extmarks are primarily a UI/location mechanism. Do not assume an extmark alone guarantees that the contents under it are still semantically valid for an agent edit. ## UI Agent status should remain attached to the code that spawned the task. A likely UI is a small floating window anchored near an extmark. Example: ```text parseThing x = ... ... +-- Hob ----------------------+ | Reading related code... | | Updating parser... | | Running tests... | +-----------------------------+ ``` The UI must not block normal editing. Prefer non-focusable status windows unless explicit interaction is required. Avoid intrusive notifications for routine agent progress. ## Suggestion Mode A future mode will periodically inspect code while the user is typing and offer edits. Suggestion agents must not modify the buffer directly. They should produce proposals such as: ```text old text new text explanation ``` The proposal is only committed when the user explicitly accepts it. Suggestions should be conservative. It is preferable to produce no suggestion rather than constantly surface low-value cosmetic changes. Potential triggers should use debouncing rather than running an agent on every keystroke. ## OpenCode OpenCode is the initial agent runtime. Support for both of these may eventually exist: ```sh opencode run ``` and a persistent OpenCode server. The MVP should prefer simple `opencode run` invocation unless a feature clearly requires persistent server state. Avoid coupling core plugin abstractions too tightly to OpenCode internals. OpenCode should eventually be one agent backend rather than the definition of the plugin architecture. ## Lua Style Keep the Lua implementation straightforward and idiomatic. Prefer: ```lua vim.api.* vim.system(...) vim.schedule(...) vim.uv.* ``` over shelling out to Neovim commands when a clean Lua API exists. Use local variables aggressively. Keep modules small and cohesive. Avoid global state where possible. Maintain plugin state inside Lua modules. Suggested conceptual separation: ```text lua/hobs/ init.lua task.lua ui.lua opencode.lua buffer.lua ``` Do not split files prematurely if the implementation is still small. ## Async Behavior Agent execution must be asynchronous. Never block Neovim while waiting for OpenCode. Use callbacks or scheduled handlers for process output. Remember that process callbacks may execute in contexts where direct Neovim API calls are unsafe. Use: ```lua vim.schedule(...) ``` when necessary before touching editor state. Each running Hob should have its own task identity and state. Eventually multiple Hobs must be able to run simultaneously. Avoid global "current agent" assumptions. ## Buffer Safety Before modifying a buffer: * verify it still exists; * verify it is modifiable; * verify the task still refers to the intended buffer; * avoid replacing human edits based on stale assumptions. The MVP's generated `sed` script should be validated before replacing the buffer. Do not allow failed external commands to destroy or blank the user's current buffer. ## Error Handling Errors should be visible but unobtrusive. Examples: * OpenCode executable not found; * agent process exits non-zero; * malformed sed output; * sed application fails; * source buffer was deleted; * task was cancelled. Include enough stderr/output to diagnose failures. Do not silently ignore errors that may leave the user thinking an edit succeeded. ## Commands The primary user-facing command is: ```vim :Hob ``` When invoked from a visual selection, the selected source is part of the task context. Future commands may include things such as: ```vim :Hobs :HobStop :HobSuggest ``` Do not add commands merely for internal plumbing. ## Naming A "Hob" is one AI worker. The project is: ```text hobs.nvim ``` Use "Hob" in user-facing terminology where natural. Avoid generic branding such as "AI Agent Manager" when the Hob terminology communicates the concept more clearly. ## Testing Where practical, keep core functionality separable from UI so it can be tested headlessly. Useful test targets include: * visual selection extraction; * prompt construction; * task lifecycle state; * extmark movement; * stale-task handling; * subprocess success/failure; * generated edit validation; * multiple concurrent tasks. For integration testing, prefer headless Neovim where possible: ```sh nvim --headless ... ``` Do not require a real LLM invocation for every test. Agent execution should eventually be abstracted enough that tests can substitute a fake process/backend. ## Scope Discipline The MVP exists to prove one thing: > Can a human keep editing normally while an AI agent independently works against the same live source state? Prioritize proving that interaction. Do not spend substantial effort yet on: * complex configuration systems; * elaborate status dashboards; * multiple model providers; * persistent chat history; * generalized agent orchestration; * elaborate diff UIs; * plugin-manager-specific behavior. Build the smallest system that validates concurrent human/agent editing, then evolve from evidence.