Small, structured Neovim context snapshots for Pi.
Dome captures the current editor state into JSONL so Pi can work with what you are actually looking at in Neovim, including unsaved buffer text, selections, diagnostics, Tree-sitter context, LSP hover, references, and call hierarchy.
By default Dome uses the lean profile to keep snapshots small and relevant.
Important
Dome is both a Neovim plugin and a Pi extension. You need to install both pieces for the intended workflow: the Neovim plugin saves contexts, and the Pi extension lets Pi read and attach them.
- bring unsaved editor state into Pi
- capture a function or selection without pasting it manually
- include diagnostics and symbol intelligence next to the code
- let Pi search or attach saved Neovim contexts later
:DomeSaveContext [title] can capture:
- current file, cursor position, and filetype
- unsaved buffer text around the cursor
- a visual/range selection
- diagnostics from the current buffer
- Tree-sitter node and ancestor chain when available
- LSP hover for the selected/current symbol
- LSP references for the selected/current symbol
- LSP call hierarchy (incoming and outgoing) when the server supports it
Saved contexts are appended to:
<project-root>/.pi/dome-contexts.jsonl
Project root is detected from .git or .pi by default. If no marker is found, Dome falls back to Neovim's current working directory.
Dome has two installable parts, and both are required:
- the Neovim plugin, which saves editor context into
.pi/dome-contexts.jsonl - the Pi extension, which adds the
dome_contextstool and/dome*commands so Pi can read those saved contexts
If you install only the Neovim plugin, contexts will be saved but Pi will not have the Dome commands/tooling. If you install only the Pi extension, Pi can look for Dome contexts but Neovim will not be saving them.
Use your plugin manager against this repository. Example with lazy.nvim:
{
dir = "/path/to/dome", -- replace with your checkout or published repo
config = function()
require("dome").setup({
profile = "lean", -- default
lsp_timeout_ms = 500,
output_file = ".pi/dome-contexts.jsonl",
})
end,
}If you do not need custom options, Dome works with its defaults out of the box.
This repo also includes a Pi extension in pi-extension/.
Load it for one Pi session:
pi -e /path/to/dome/pi-extension/index.tsOr install/register it with Pi:
pi install /path/to/dome/pi-extensionAfter installing both the Neovim plugin and the Pi extension:
-
In Neovim, save a context:
:DomeSaveContext debugging auth handler
-
In Pi, attach the newest one:
/dome-latest -
Ask Pi to help with the problem.
For symbol-aware context, place the cursor on a function name or visually select a function before saving.
Normal mode:
:DomeSaveContext debugging auth handlerVisual or range mode:
:'<,'>DomeSaveContext selected broken functionSuggested keymaps:
vim.keymap.set("n", "<leader>ds", function()
require("dome").save_context()
end, { desc = "Dome: save context" })
vim.keymap.set("v", "<leader>ds", ":DomeSaveContext<CR>", { desc = "Dome: save selected context" })- fewer surrounding context lines
- fewer diagnostics, biased toward
WARNandERROR - smaller reference and call hierarchy limits
- call hierarchy limited to files under the current project root
- omits
surroundingTextwhen a selection is captured
Use profile = "full" to keep the more verbose behavior.
Common options:
require("dome").setup({
profile = "lean", -- "lean" or "full"
output_file = ".pi/dome-contexts.jsonl",
root_markers = { ".git", ".pi" },
context_lines = 20, -- lean default
lsp_timeout_ms = 500,
call_hierarchy_timeout_ms = 800,
include_references = true,
include_call_hierarchy = true,
max_references = 15, -- lean default
max_incoming_calls = 8, -- lean default
max_outgoing_calls = 8, -- lean default
max_text_bytes = 200000,
})Notes:
- relative
output_filepaths are resolved from the detected project root - absolute
output_filepaths are used as-is Tree-sitterandLSPdata are best-effort and may be absent
Once the Pi extension is installed, it adds:
dome_contextstool for agentsaction: "list"action: "search"action: "get"action: "path"
/dome [query]to pick a saved context and attach it to the next prompt/dome-latestto attach the newest saved context/dome-clearto remove the pending context/dome-pathto show the JSONL path Pi will read
By default the extension reads .pi/dome-contexts.jsonl relative to Pi's current working directory. In practice, that means Pi should usually be started from the same project root that Dome used when saving the context.
If needed, the dome_contexts tool also accepts contextFile to read a different JSONL file.
References and call hierarchy are best-effort features. They require:
- an LSP client attached to the current buffer (
:LspInfo) - server support for
textDocument/references - server support for call hierarchy if you want caller/callee data
- a request position that resolves to the symbol name, not just the function body
Dome uses Tree-sitter when available and falls back to simple text patterns for common function and class definitions.
If references or call hierarchy do not appear:
- Check the save path with
/dome-pathin Pi or inspect.pi/dome-contexts.jsonlunder the project root. - Confirm Neovim has an attached LSP with
:LspInfo. - Put the cursor directly on the function name and run
:DomeSaveContext test symbol. - Try Neovim's built-in LSP references on the same symbol.
- Install the matching Tree-sitter parser for better selected-function detection.
It is normal for references or callHierarchy to be missing when the language server returns no result or does not support that method.
Each line in .pi/dome-contexts.jsonl is one JSON object. Example:
{
"source": "dome.nvim",
"version": 1,
"id": "2026-04-29T18-02-13Z-src-foo-ts-42-123456",
"createdAt": "2026-04-29T18:02:13Z",
"cwd": "/path/to/project",
"file": "src/foo.ts",
"absoluteFile": "/path/to/project/src/foo.ts",
"filetype": "typescript",
"buftype": "",
"modified": true,
"profile": "lean",
"cursor": { "line": 42, "col": 13 },
"symbolPosition": { "line": 42, "col": 10 },
"title": "debugging auth handler",
"selection": null,
"surroundingText": {
"startLine": 22,
"endLine": 62,
"text": "..."
},
"treesitter": {
"node": "identifier",
"ancestors": ["identifier", "call_expression", "function_declaration"]
},
"lsp": {
"hover": {
"client": "tsserver",
"text": "..."
}
},
"references": {
"total": 12,
"items": [
{
"file": "src/server.ts",
"line": 92,
"col": 15,
"text": "return selectedFunction(req.user)"
}
]
},
"callHierarchy": {
"symbol": {
"name": "selectedFunction",
"kindName": "Function",
"file": "src/service.ts",
"line": 42
},
"totalIncoming": 3,
"totalOutgoing": 2,
"incoming": [],
"outgoing": []
},
"diagnostics": []
}- Dome is append-only; contexts accumulate until you rotate or delete the file yourself.
- Saved contexts can include source code and unsaved changes. Treat the JSONL file as sensitive project data.