Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

neovim/.system/plans/NVIM-PLAN-CEJPO_XF-deliver-pivi-native-neovim-integration/index.md

Raw
Rendered preview

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 as vertical slices, each observable through Neovim surfaces. Evidence for transport, tool authority, and concurrency comes from NVIM-RESEARCH-KZYYEFY_.

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

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, <Plug> mappings
companion extension Editor tools plus buffer-authoritative operations for built-in Pi tools

Slice order

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
---
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, `<Plug>` 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 |