--- id: NVIM-PLAN-CEJPO_XF type: plan title: Deliver pivi native Neovim integration spec: NVIM-SPEC-GMWDCMJZ status: approved --- # Deliver pivi native Neovim integration ## Intent Deliver [NVIM-SPEC-GMWDCMJZ](../../specs/NVIM-SPEC-GMWDCMJZ-pivi-native-neovim-integration/index.md) as vertical slices, each observable through Neovim surfaces. Evidence for transport, tool authority, and concurrency comes from [NVIM-RESEARCH-KZYYEFY_](../../research/NVIM-RESEARCH-KZYYEFY_-pi-and-neovim-capabilities-for-pivi/index.md). Placement: pivi is an ordinary configuration module at `lua/bugabinga/pivi/`, like the other Neovim modules, with its bundled Pi companion extension under `lua/bugabinga/pivi/extension/`. Module-level testing rules live in that directory's `AGENTS.md`. Publishing state through native variables and `User` events still holds, so other configuration consumes pivi without depending on its internals. ## Module map ```mermaid flowchart TB command["bugabinga.pivi.command"] --> session["bugabinga.pivi.session"] command --> help["bugabinga.pivi.help"] session --> rpc["bugabinga.pivi.rpc"] session --> status["bugabinga.pivi.status"] status --> publish["bugabinga.pivi.publish"] session --> transcript["bugabinga.pivi.transcript"] session --> context["bugabinga.pivi.context"] session --> dialog["bugabinga.pivi.dialog"] rpc --> extension["companion Pi extension"] extension --> edit["bugabinga.pivi.edit"] edit --> activity["bugabinga.pivi.activity"] activity --> follow["bugabinga.pivi.follow"] help --> rpc ``` | Module | Responsibility | | --- | --- | | `bugabinga.pivi.rpc` | Child process lifetime, strict LF JSONL framing, request correlation, deferral out of fast contexts | | `bugabinga.pivi.session` | Session identity, working directory, queue delivery, abort, resume, switch | | `bugabinga.pivi.status` | Cached semantic state; no RPC during status evaluation | | `bugabinga.pivi.publish` | `vim.g` state plus `User` autocmd events with payload data | | `bugabinga.pivi.transcript` | Prompt, transcript, and detail buffers | | `bugabinga.pivi.context` | Immutable submission snapshots and ambient editor state | | `bugabinga.pivi.edit` | Buffer-authoritative mutation, undo coherence, disk visibility | | `bugabinga.pivi.activity` | Extmarks, signs, virtual text, diagnostics, quickfix and location lists | | `bugabinga.pivi.follow` | Optional viewport following | | `bugabinga.pivi.dialog` | Extension UI requests mapped to `vim.ui` surfaces | | `bugabinga.pivi.help` | Ephemeral session-less run | | `bugabinga.pivi.command` | `:Pi` subcommands, slash-command entry, `` mappings | | companion extension | Editor tools plus buffer-authoritative operations for built-in Pi tools | ## Slice order ```mermaid flowchart LR s1["1 Ask and stream"] --> s3["3 Status and events"] s1 --> s2["2 Ephemeral help"] s3 --> s4["4 Session control"] s4 --> s5["5 Submission context"] s5 --> s6["6 Buffer-authoritative reads"] s6 --> s7["7 Native edits"] s7 --> s8["8 Activity and lists"] s7 --> s9["9 Streaming ghost text"] s8 --> s10["10 Follow mode"] s4 --> s11["11 Slash commands"] s4 --> s12["12 Extension dialogs"] ``` | # | Observable behavior | Modules touched | Verified by | | --- | --- | --- | --- | | 1 | `:Pi ask {text}` starts Pi, streams assistant text into a transcript buffer, and survives partial reads | `bugabinga.pivi.rpc`, `bugabinga.pivi.session`, `bugabinga.pivi.transcript`, `bugabinga.pivi.command` | Framing and assembly specs plus a live round trip | | 2 | `:Pi help {q}` answers from an independent session-less run without touching any working session | `bugabinga.pivi.help`, `bugabinga.pivi.command` | Concurrent-run spec asserting untouched session history, queue, and status | | 3 | Status changes update cached state, emit semantic `User` events, and never issue RPC during evaluation | `bugabinga.pivi.status`, `bugabinga.pivi.publish` | Event payload spec plus a consumer that degrades when pivi is absent | | 4 | Create, resume, switch, stop sessions; queue steering or follow-up during a run; list, clear, abort | `bugabinga.pivi.session`, `bugabinga.pivi.command`, `bugabinga.pivi.transcript` | Queue state-machine spec matching the spec's run states | | 5 | Submissions carry immutable buffer, revision, cursor, range, and selection snapshots; queued items keep their own | `bugabinga.pivi.context`, `bugabinga.pivi.session` | Snapshot immutability spec under later buffer edits | | 6 | Pi reads unsaved loaded-buffer content and current core editor state on demand, including arbitrary Lua | companion extension, `bugabinga.pivi.rpc` | Tool-result spec comparing buffer versus disk content | | 7 | A normal Pi edit lands in a loaded buffer without reload, stays undoable as one change, and is visible to later shell work | `bugabinga.pivi.edit`, companion extension | Undo and coherence spec covering join failure fallback | | 8 | Edits leave a navigable trail; findings populate quickfix, location lists, and a distinct diagnostic namespace | `bugabinga.pivi.activity` | Namespace isolation and navigation spec | | 9 | Streaming tool arguments render ghost text that never mutates a buffer before arguments are complete | `bugabinga.pivi.activity`, `bugabinga.pivi.edit` | Partial-argument spec asserting zero mutation | | 10 | Follow mode tracks located events in a dedicated window or tab and restores the prior location | `bugabinga.pivi.follow` | Window ownership and restore spec | | 11 | `:Pi command ...` runs discovered Pi commands; `/` opens entry only at the first character of an input buffer | `bugabinga.pivi.command` | Cursor-position and discovery spec | | 12 | Extension dialogs and fire-and-forget status map to native surfaces and answer with matching identifiers | `bugabinga.pivi.dialog` | Request and response correlation spec | Slice 1 is the walking skeleton; every later slice keeps `just test` green before the next begins. ## Critical paths - Child output arrives in fast contexts; all editor work defers through scheduling before API calls. - Submission during an active run always chooses steering or follow-up; rejection is never silent. - Help spawns its own session-less child so working-session history, queue, and status remain untouched. - Buffer authority prefers injecting operations into Pi's built-in tools over reimplementing them, because result and detail shapes must match exactly. ## Risks | Risk | Slice | Mitigation | | --- | --- | --- | | Undo join refuses after undo or redo | 7 | Detect refusal and fall back to separate undo blocks rather than losing the edit | | Partial tool arguments are invalid JSON | 9 | Treat ghost text as presentation only; mutate solely on complete validated arguments | | Tool override breaks rendering or session state | 6, 7 | Keep built-in renderers and detail shapes; override behavior only | | Status consumers stall the statusline | 3 | Read cached state only | | Agent shell work reads stale disk content | 7 | Make agent buffer edits visible to filesystem readers as part of the edit behavior |