--- id: NVIM-PLAN-T7XG71CC type: plan title: Deliver pivi tool presentation spec: NVIM-SPEC-GMWDCMJZ status: approved depends_on: - NVIM-PLAN-CEJPO_XF - NVIM-PLAN-LAJ8PGRK --- # Deliver pivi tool presentation ## Intent Make a tool call as legible in Neovim as it is in Pi's own interface, using native surfaces rather than a ported component tree. [NVIM-PLAN-LAJ8PGRK](../NVIM-PLAN-LAJ8PGRK-deliver-pivi-transcript-presentation-and-navigat/index.md) made every tool call an addressable, collapsible entry. That entry currently shows what a tool acted on and nothing about how it ended, and it discards everything a tool reports about its own work. Blocker: the behavior below is not yet in [NVIM-SPEC-GMWDCMJZ](../../specs/NVIM-SPEC-GMWDCMJZ-pivi-native-neovim-integration/index.md). A tool presentation section and its acceptance criteria were drafted and await one-shot approval. This plan is not executable until that amendment lands. ## Evidence Read from the installed Pi 0.85.1 implementation, not from prose. Tool results reach a client unchanged, so everything a tool reports is already on the wire and merely unused. | Tool | What it reports about its own work | When | | --- | --- | --- | | edit | a display diff, a unified patch, and the first changed line | always | | bash | progressive output, truncation, and a full output path | while running, throttled | | read | truncation | only when truncated | | grep, find, ls | truncation and the limit that was reached | only at a limit | | write | nothing | — | Neovim side: no diff parser ships, but diff syntax and the diff highlight groups do, and the theme already defines them. ## Module map ```mermaid flowchart TB session["bugabinga.pivi.session"] --> tool["bugabinga.pivi.tool"] tool --> entry["bugabinga.pivi.entry"] tool --> render["bugabinga.pivi.render"] render --> fold["bugabinga.pivi.fold"] tool --> diff["bugabinga.pivi.diff"] diff --> command["bugabinga.pivi.command"] tool --> navigate["bugabinga.pivi.navigate"] ``` | Module | Responsibility | | --- | --- | | `bugabinga.pivi.tool` | Interprets what a tool reports: outcome, change, progress, language, truncation | | `bugabinga.pivi.render` | Presents that interpretation as decoration inside the entry | | `bugabinga.pivi.diff` | Editor comparison of a completed change | | `bugabinga.pivi.fold` | Collapsed line that still states subject and outcome | | `bugabinga.pivi.navigate` | Reaching the first changed line rather than the file start | | `bugabinga.pivi.entry` | Carries the interpretation as entry metadata | | `bugabinga.pivi.session` | Feeds tool reports in, including while a tool still runs | ## Slice order ```mermaid flowchart LR s1["1 Outcome after the name"] --> s2["2 Change as a diff"] s1 --> s6["6 Truncation is reachable"] s2 --> s3["3 First changed line"] s2 --> s4["4 Editor comparison"] s1 --> s5["5 Output while running"] s5 --> s7["7 Output in its language"] ``` | # | Observable behavior | Modules touched | Verified by | | --- | --- | --- | --- | | 1 | A finished tool entry states how it ended beside what it acted on, and a collapsed entry keeps both | `bugabinga.pivi.tool`, `bugabinga.pivi.render`, `bugabinga.pivi.fold`, `bugabinga.pivi.session` | Outcome spec across edit, shell, search, and failure, plus a collapsed-line spec | | 2 | A completed edit shows its change with added and removed lines distinguished | `bugabinga.pivi.tool`, `bugabinga.pivi.render` | Diff presentation spec asserting distinct added and removed lines and unchanged buffer text | | 3 | Navigating from an edit lands on its first changed line | `bugabinga.pivi.navigate`, `bugabinga.pivi.tool` | Navigation spec over a recorded edit | | 4 | A change can be opened as a full editor comparison and left again | `bugabinga.pivi.diff`, `bugabinga.pivi.command` | Comparison spec asserting the working window survives and the transcript is unchanged | | 5 | Output of a running tool appears as it arrives rather than only at completion | `bugabinga.pivi.session`, `bugabinga.pivi.tool`, `bugabinga.pivi.entry` | Progressive-output spec asserting growth before completion and stable bounds | | 6 | A truncated result says so, and its full output is reachable | `bugabinga.pivi.tool`, `bugabinga.pivi.render`, `bugabinga.pivi.navigate` | Truncation spec asserting the notice and a reachable full output | | 7 | Output is presented in the language it came from when that language is known | `bugabinga.pivi.tool`, `bugabinga.pivi.render` | Language spec asserting a second language is parsed inside the transcript | Slice 1 is the walking skeleton: it establishes the interpretation every later slice reads. ## Critical paths - Interpretation is derived only from what a tool reports; a tool that reports nothing degrades to today's behavior rather than to a guess. - Diff presentation is decoration over reported change text, so the transcript still yields message text when copied. - An editor comparison reconstructs the prior content from the reported change rather than re-reading a file that has already moved on. - Progressive output replaces the tail of its own entry; entry bounds stay extmark-backed and must survive repeated rewrites. - Presentation stays redraw-driven, so a tool that emits output continuously cannot force parsing per update. ## Risks | Risk | Slice | Mitigation | | --- | --- | --- | | Tools differ in what they report | 1 | Interpretation is per tool with a plain fallback, asserted for a tool that reports nothing | | Diff decoration drifts from the text it marks | 2 | Anchor decoration to entry-relative rows and assert after later entries are appended | | A reconstructed comparison disagrees with the file on disk | 4 | Present it as a comparison of the recorded change, and state when the file has moved on | | Frequent progress updates cost too much | 5 | Rewrite only the entry tail, keep parsing redraw-driven, and hold the streaming budget spec | | A collapsed line grows unreadable | 1 | Bound subject and outcome, and assert a maximum collapsed width |