Install
$ agentstack add mcp-ravitemer-codecompanion-history-nvim ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
CodeCompanion History Extension
[](https://neovim.io) [](https://www.lua.org) [](https://github.com/ravitemer/codecompanion-history.nvim/actions) [](https://opensource.org/licenses/MIT) [](./CONTRIBUTING.md)
A history management extension for codecompanion.nvim that enables saving, browsing and restoring chat sessions.
✨ Features
🤖 Chat Management
- 💾 Flexible chat saving:
- Automatic session saving (can be disabled)
- Manual save with dedicated keymap
- 🎯 Smart title generation for chats
- 🔄 Continue from where you left
- 📚 Browse saved chats with preview
- 🔍 Multiple picker interfaces
- ⌛ Optional automatic chat expiration
- ⚡ Restore chat sessions with full context and tools state
- 🏢 Project-aware filtering: Filter chats by workspace/project context
- 📋 Chat duplication: Easily duplicate chats to create variations or backups
📝 Summary System
- Manual summary generation: Create summaries for any chat with
gcs - Intelligent content processing: Extracts meaningful conversation content while filtering noise
- Chunked summarization: Handles large conversations by splitting into manageable chunks
- Customizable generation: Configure adapter, model, and system prompts
- Summary browsing: Dedicated browser with
gbsto explore all summaries
🧠 Memory System (@memory tool)
- Vector-based search: Uses VectorCode CLI to index and search through chat summaries
- Automatic indexing: Optionally index summaries as they are generated
- Smart integration: Available as
@memorytool in new chats when VectorCode is installed
The following CodeCompanion features are preserved when saving and restoring chats:
| Feature | Status | Notes | |---------|--------|-------| | System Prompts | ✅ | System prompt used in the chat | | Messages History | ✅ | All messages | | Images | ✅ | Restores images as base64 strings | | LLM Adapter | ✅ | The specific adapter used for the chat | | LLM Settings | ✅ | Model, temperature and other adapter settings | | Tools | ✅ | Tool schemas and their system prompts | | Tool Outputs | ✅ | Tool execution results | | Variables | ✅ | Variables used in the chat | | References | ✅ | Code snippets and command outputs added via slash commands | | Pinned References | ✅ | Pinned references | | Watchers | ⚠ | Saved but requires original buffer context to resume watching |
When restoring a chat:
- The complete message history is recreated
- All tools and references are reinitialized
- Original LLM settings and adapter are restored
- Previous system prompts are preserved
> Note: While watched buffer states are saved, they require the original buffer context to resume watching functionality.
> [!NOTE] > As this is an extension that deeply integrates with CodeCompanion's internal APIs, occasional compatibility issues may arise when CodeCompanion updates. If you encounter any bugs or unexpected behavior, please raise an issue to help us maintain compatibility.
📋 Requirements
- Neovim >= 0.8.0
- codecompanion.nvim
- VectorCode CLI (optional, for
@memorytool) - snacks.nvim (optional, for enhanced picker)
- telescope.nvim (optional, for enhanced picker)
- fzf-lua (optional, for enhanced picker)
📦 Installation
Using lazy.nvim:
First install the plugin
{
"olimorris/codecompanion.nvim",
dependencies = {
--other plugins
"ravitemer/codecompanion-history.nvim"
}
}
Add history extension to CodeCompanion config
require("codecompanion").setup({
extensions = {
history = {
enabled = true,
opts = {
-- Keymap to open history from chat buffer (default: gh)
keymap = "gh",
-- Keymap to save the current chat manually (when auto_save is disabled)
save_chat_keymap = "sc",
-- Save all chats by default (disable to save only manually using 'sc')
auto_save = true,
-- Number of days after which chats are automatically deleted (0 to disable)
expiration_days = 0,
-- Picker interface (auto resolved to a valid picker)
picker = "telescope", --- ("telescope", "snacks", "fzf-lua", or "default")
---Optional filter function to control which chats are shown when browsing
chat_filter = nil, -- function(chat_data) return boolean end
-- Customize picker keymaps (optional)
picker_keymaps = {
rename = { n = "r", i = "" },
delete = { n = "d", i = "" },
duplicate = { n = "", i = "" },
},
---Automatically generate titles for new chats
auto_generate_title = true,
title_generation_opts = {
---Adapter for generating titles (defaults to current chat adapter)
adapter = nil, -- "copilot"
---Model for generating titles (defaults to current chat model)
model = nil, -- "gpt-4o"
---Number of user prompts after which to refresh the title (0 to disable)
refresh_every_n_prompts = 0, -- e.g., 3 to refresh after every 3rd user prompt
---Maximum number of times to refresh the title (default: 3)
max_refreshes = 3,
format_title = function(original_title)
-- this can be a custom function that applies some custom
-- formatting to the title.
return original_title
end
},
---On exiting and entering neovim, loads the last chat on opening chat
continue_last_chat = false,
---When chat is cleared with `gx` delete the chat from history
delete_on_clearing_chat = false,
---Directory path to save the chats
dir_to_save = vim.fn.stdpath("data") .. "/codecompanion-history",
---Enable detailed logging for history extension
enable_logging = false,
-- Summary system
summary = {
-- Keymap to generate summary for current chat (default: "gcs")
create_summary_keymap = "gcs",
-- Keymap to browse summaries (default: "gbs")
browse_summaries_keymap = "gbs",
generation_opts = {
adapter = nil, -- defaults to current chat adapter
model = nil, -- defaults to current chat model
context_size = 90000, -- max tokens that the model supports
include_references = true, -- include slash command content
include_tool_outputs = true, -- include tool execution results
system_prompt = nil, -- custom system prompt (string or function)
format_summary = nil, -- custom function to format generated summary e.g to remove tags from summary
},
},
-- Memory system (requires VectorCode CLI)
memory = {
-- Automatically index summaries when they are generated
auto_create_memories_on_summary_generation = true,
-- Path to the VectorCode executable
vectorcode_exe = "vectorcode",
-- Tool configuration
tool_opts = {
-- Default number of memories to retrieve
default_num = 10
},
-- Enable notifications for indexing progress
notify = true,
-- Index all existing memories on startup
-- (requires VectorCode 0.6.12+ for efficient incremental indexing)
index_on_startup = false,
},
}
}
}
})
> [!WARNING] > Title and summary generation defaults to current chat's adapter and model. Make sure to set cheaper models in title_generation_opts and summary.generation_opts to avoid using premium models.
🛠️ Usage
🎯 Commands
:CodeCompanionHistory- Open the history browser:CodeCompanionSummaries- Browse all summaries
⌨️ Chat Buffer Keymaps
History Management:
gh- Open history browser (customizable viaopts.keymap)sc- Save current chat manually (customizable viaopts.save_chat_keymap)
Summary System:
gcs- Generate summary for current chat (customizable viaopts.summary.create_summary_keymap)gbs- Browse saved summaries (customizable viaopts.summary.browse_summaries_keymap)
📚 History Browser
The history browser shows all your saved chats with:
- Title (auto-generated or custom)
- Summary indicator (📝 icon for chats with summaries)
- Token estimates and relative timestamps
- Preview of chat contents
Actions in history browser:
- `` - Open selected chat
- Normal mode:
d- Delete selected chat(s)r- Rename selected chat- `` - Duplicate selected chat
- Insert mode:
- `` (Alt+d) - Delete selected chat(s)
- `` (Alt+r) - Rename selected chat
- `` - Duplicate selected chat
📝 Summary Browser
The summary browser shows all your generated summaries with:
- Chat title (from original conversation)
- Project context and relative timestamps
- Preview of summary content
Actions in summary browser:
- `` - Add the summary to the current chat
- Normal mode:
d- Delete selected summary(s)- Insert mode:
- `` (Alt+d) - Delete selected summary(s)
The @memory tool
If you have installed the VectorCode CLI, this plugin will use VectorCode to create an index for your chat summaries and create a tool called @memory. This tool gives the LLM the ability to search for (the summary of) previous chats so that you can refer to them in a new chat.
Available options for the memory submodule:
opts.memory = {
auto_create_memories_on_summary_generation = true,
-- path to the `vectorcode` executable
vectorcode_exe = "vectorcode",
tool_opts = {
-- default number of memories to retrieve
default_num = 10
},
-- whether to enable notification
notify = true,
-- whether to automatically update the index of all existing memories on startup
-- (requires VectorCode 0.6.12+ for efficient incremental indexing)
index_on_startup = false,
}
🔄 Title Refresh Feature
The extension can automatically refresh chat titles as conversations evolve:
refresh_every_n_prompts: Set to refresh the title after every N user prompts (e.g., 3 means refresh after the 3rd, 6th, 9th user message)max_refreshes: Limits how many times a title can be refreshed to avoid excessive API calls- When refreshing, the system considers recent conversation context (both user and assistant messages) and the original title
- Individual messages are truncated at 1000 characters with a
[truncated]indicator - Total conversation context is limited to 10,000 characters with a
[conversation truncated]indicator
Example configuration for title refresh:
title_generation_opts = {
refresh_every_n_prompts = 3, -- Refresh after every 3rd user prompt
max_refreshes = 10, -- Allow up to 10 refreshes per chat
}
🏢 Project-Aware Chat Filtering
The extension supports flexible chat filtering to help you focus on relevant conversations:
Configurable Filtering:
chat_filter = function(chat_data)
return chat_data.cwd == vim.fn.getcwd()
end
-- Recent chats only (last 7 days)
chat_filter = function(chat_data)
local seven_days_ago = os.time() - (7 * 24 * 60 * 60)
return chat_data.updated_at >= seven_days_ago
end
Chat Index Data Structure: Each chat index entry (used in filtering) includes the following information:
-- ChatIndexData - lightweight metadata used for browsing and filtering
{
save_id = "1672531200", -- Unique chat identifier
title = "Debug API endpoint", -- Chat title (auto-generated or custom)
cwd = "/home/user/my-project", -- Working directory when saved
project_root = "/home/user/my-project", -- Detected project root
adapter = "openai", -- LLM adapter used
model = "gpt-4", -- Model name
updated_at = 1672531200, -- Unix timestamp of last update
message_count = 15, -- Number of messages in chat
token_estimate = 3420, -- Estimated token count
}
🔧 API
The history extension exports the following functions that can be accessed via require("codecompanion").extensions.history:
-- Chat Management
get_location(): string? -- Get storage location
-- Save a chat to storage (uses last chat if none provided)
save_chat(chat?: CodeCompanion.Chat)
-- Browse chats with custom filter function
browse_chats(filter_fn?: function(ChatIndexData): boolean)
-- Get metadata for all saved chats with optional filtering
get_chats(filter_fn?: function(ChatIndexData): boolean): table
-- Load a specific chat by its save_id
load_chat(save_id: string): ChatData?
-- Delete a chat by its save_id
delete_chat(save_id: string): boolean
-- Duplicate a chat by its save_id
duplicate_chat(save_id: string, new_title?: string): string?
-- Summary Management
--- Generate a summary for the current chat
generate_summary(chat?: CodeCompanion.Chat)
--- Delete a sumamry
delete_summary(summary_id: string)
--- Get summaries index
get_summaries(): table
--- Load summary
load_summary(summary_id: string): string?
Example usage:
local history = require("codecompanion").extensions.history
-- Browse chats with project filter
history.browse_chats(function(chat_data)
return chat_data.project_root == utils.find_project_root()
end)
-- Get all saved chats metadata
local chats = history.get_chats()
local chat_data = history.load_chat("some_save_id")
history.delete_chat("some_save_id")
-- Duplicate a chat with custom title
local new_save_id = history.duplicate_chat("some_save_id", "My Custom Copy")
-- Duplicate a chat with auto-generated title (appends "(1)")
local new_save_id = history.duplicate_chat("some_save_id")
-- Summary operations
history.generate_summary() -- generates for current chat
local summaries = history.get_summaries()
local summary_content = history.load_summary("some_save_id")
⚙️ How It Works
graph TD
subgraph CodeCompanion Core Lifecycle
A[CodeCompanionChatCreated Event] --> B{Chat Submitted};
B --> C[LLM Response Received];
subgraph Chat End
direction RL
D[CodeCompanionChatCleared Event];
end
C --> D;
B --> D;
end
subgraph Extension Integration
A -- Extension Hooks --> E[Init & Subscribe];
E --> F[Setup Auto-Save];
F --> G[Prepare Auto-Title];
C -- Extension Hooks --> H[Subscriber Triggered];
H --> H1{Auto-Save Enabled?};
H1 -- Yes --> I[Save Chat State - Messages, Tools, Refs];
H1 -- No --> H2[Manual Save via `sc`];
H2 --> I;
I --> J{No Title & Auto
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [ravitemer](https://github.com/ravitemer)
- **Source:** [ravitemer/codecompanion-history.nvim](https://github.com/ravitemer/codecompanion-history.nvim)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.