openspec.nvim
July 4, 2026 ยท View on GitHub
Neovim control surface for OpenSpec workflows.
openspec.nvim keeps OpenSpec markdown artifacts as the source of truth while
bringing change status, task progress, artifact context, validation signals, and
implementation handoffs into Neovim.
It is built for developers who use OpenSpec, Codex-style agents, or spec-driven development and want the current change lifecycle to stay close to the code they are editing.
Current status
Early public plugin. The current release focuses on OpenSpec task tracking, workspace awareness, temporary change reports, archive search, and explicit implementation-session launchers. The baseline stays dependency-free and uses built-in Neovim APIs.
Demo
:OpenSpecImplement resolves the current change context, selects the provider
and model from your profile, and launches a new implementation session in a
tmux or Neovim split without manual copy-paste.

Why this exists
OpenSpec changes usually span several places at once:
proposal.md / design.md / tasks.md
-> Git branch and worktree
-> Neovim implementation loop
-> validation and AI-agent handoff
openspec.nvim makes that state visible from inside Neovim. It does not replace
the OpenSpec CLI, Git, or your AI coding agent. It gives them a shared,
editor-native control surface grounded in the same repo-local artifacts.
Features
- Discover the nearest
openspec/changesdirectory from the current buffer or cwd. - Prefer the current
openspec/changes/<change>/tasks.mdwhen the cursor is already inside a change. - Parse checkbox tasks:
- [ ]todo- [x]/- [X]done- [/],- [~],- [>]work in progress- [-]skipped
- Show a larger, focused floating summary with total progress, next task, and the highest-priority sections that still have todo/WIP work.
- Generate a temporary dark-mode HTML change report from
proposal.md,design.md,specs/**/*.md, andtasks.mdwithout writing generated files into the project. - Toggle the HTML report between dark and light mode from the report header without requiring JavaScript.
- Set a checkbox task status from an open
tasks.mdbuffer. - Show an OpenSpec control cockpit with artifact digest, Git context, local findings, and next recommended upstream action.
- Generate context packs from the selected/next task without driving OpenSpec lifecycle actions from inside Neovim.
- Keep OpenSpec artifacts as the source of truth while making terminal-side OpenSpec actions (apply/verify/archive) explicit and auditable.
- Start implementation sessions with a forced provider/model context through
:OpenSpecImplement. - Optionally launch implementation sessions in a dedicated git worktree per change with
worktree=auto.
Installation
With lazy.nvim:
{
"ctchen222/openspec.nvim",
opts = {},
}
For local development:
{
dir = "/Users/ctchen/Development/project/openspec.nvim",
name = "openspec.nvim",
opts = {},
}
Requirements:
- Neovim 0.10 or newer.
- An OpenSpec project with
openspec/changes. - Optional:
openspecCLI, Git, tmux, Codex, Claude, or opencode for the richer workflow surfaces.
Usage
Default keymaps:
| Key | Action |
|---|---|
<leader>os | Toggle task summary |
<leader>ow | Open workspace cockpit |
<leader>oh | Open a temporary HTML change report |
<leader>oa | Open archive search |
Information ladder:
| Surface | Use it for |
|---|---|
<leader>os | Fast task progress, next task, and top incomplete sections |
<leader>ow / :OpenSpecWorkspace | Native Neovim cockpit with artifact digest, Git context, local findings, and next upstream action |
:OpenSpecArchiveSearch [query] | Read-only archived change search with proposal/design/spec/tasks navigation (run again to close the window) |
<leader>oa | Open archive search for archived OpenSpec changes |
<leader>oh | Full browser-readable proposal, design, spec delta, and tasks dossier |
The workspace cockpit is a digest, not a full artifact preview or picker. Use it to decide what needs attention, then open the source artifact or HTML report for complete proposal, design, spec delta, or task content.
Commands:
:OpenSpecTasksSummary
:OpenSpecTasksHtml
:OpenSpecTaskStatus done
:OpenSpecWorkspace
:OpenSpecTaskStart
:OpenSpecContext
:OpenSpecCurrent
:OpenSpecImplement
:OpenSpecWorktree list
:OpenSpecArchiveSearch [query]
Run :OpenSpecArchiveSearch again to close the current archive search window.
Inside archive search/detail windows, press q to close the window.
Use :OpenSpecTaskStatus {done|todo|wip|skipped} [line] from an open tasks.md
buffer to update a task checkbox. When [line] is omitted, the command uses
the current cursor line. The command updates the buffer and leaves normal
Neovim write control to you.
<leader>ow opens the native workspace cockpit. Other workflow commands remain
explicit so task mutation and audit actions are deliberate:
:OpenSpecWorkspaceopens a scratch split workspace for the selected change.:OpenSpecTaskStart [line]marks the chosen task as WIP, then opens the workspace cockpit and local findings quickfix.:OpenSpecContext [line]opens a scratch Markdown context pack for terminal agents.:OpenSpecImplement {provider} [profile=<name>] [model=<model>] [effort=<effort>] [layout=<auto|tmux-right|tmux-bottom|nvim-right|nvim-bottom|external|copy>] [goal=<off|auto|copy|true|false>] [worktree=<off|auto|force>]launches a new provider session with model, goal mode, layout, and optional worktree isolation resolved before launch.:OpenSpecWorktree {list|remove} [change]lists or safely removes OpenSpec worktrees.:OpenSpecCurrentprints a lightweight current-change summary and the top recommendation.
Worktree launches:
worktree=offis the default and preserves the current checkout behavior.worktree=autocreates or reuses.worktrees/<change>on branchopenspec/<change>after the launch preview is confirmed, then launches the agent with that worktree as cwd.worktree=autoblocks dirty or diverged implementation worktrees before side effects. Useworktree=forceonly when you intentionally want to resume a dirty or diverged worktree and pass that real state into the agent context.- If the origin checkout has uncommitted or untracked files under
openspec/changes/<change>/,worktree=autoshows a spec snapshot block in the preview instead of blocking. After confirmation it copies only that change's spec artifacts into the worktree before launch. - The spec snapshot flow never commits, stashes, cleans, or modifies the origin checkout. Treat it as a one-time handoff of your draft spec into the implementation worktree, then reconcile the origin draft and worktree branch before the final commit.
- While a valid worktree binding exists, summary, workspace, context, and HTML views read the change copy from the worktree and show a worktree indicator. Set
implement.worktree.redirect = falseto disable that redirect. - If origin still has an uncommitted spec draft for a bound change, summary/workspace show an origin-spec-draft warning so you know reconciliation is still needed.
- Fresh worktrees do not inherit untracked local infrastructure such as
node_modules,.env, or linked secrets. Useimplement.worktree.post_createfor setup commands or create the files manually. :OpenSpecWorktree remove <change>refuses dirty worktrees and uses safe branch deletion only.
Agent collaboration pattern:
:OpenSpecTaskStartand:OpenSpecWorkspacekeep task context local./opsx:apply <change>executes upstream implementation flow outside Neovim.- In skill-enabled integrations (e.g. Kimi CLI, Trae), the equivalent command may be
/skill:openspec-apply-change <change>. /opsx:verify <change>and/opsx:archive <change>are recommended when tasks are complete and validation passes.- Use
:OpenSpecContextwhen you need a focused handoff buffer for terminal automation.
Scope
openspec.nvim is intentionally OpenSpec-specific.
It is:
- a Neovim-native status and context surface for OpenSpec projects;
- a way to keep proposal, design, specs, tasks, Git state, and agent handoffs aligned;
- a small dependency-free base that can grow optional integrations later.
It is not:
- a generic AI chat plugin;
- a project-management dashboard;
- a replacement for OpenSpec CLI lifecycle commands;
- the source of truth for tasks or specs.
Configuration
require("openspec").setup({
commands = true,
keymaps = true,
mappings = {
summary = "<leader>os",
html = "<leader>oh",
workspace = "<leader>ow",
archive = "<leader>oa",
},
tasks = {
include_skipped_in_total = false,
statuses = {
todo = { " " },
done = { "x", "X" },
wip = { "/", "~", ">" },
skipped = { "-" },
},
},
ui = {
border = "rounded",
max_width = 120,
},
health = {
validation = {
enabled = true,
},
},
implement = {
default_profile = "implementation",
profiles = {
implementation = {
model = "gpt-5.5",
effort = "high",
layout = "auto",
},
},
providers = {
codex = {
command_template = "codex {model_flag} {effort_flag} {initial_prompt}",
effort_flag = "-c model_reasoning_effort={effort}",
model_flag = "--model {model}",
model = "gpt-5.4",
effort = "high",
},
claude = {
command_template = "claude {model_flag} {effort_flag} {context_prompt}",
model_flag = "--model {model}",
effort_flag = "--effort {effort}",
model = "sonnet",
effort = "high",
},
opencode = {
command_template = "opencode --context {context_file} --model {model} --effort {effort}",
},
},
layouts = {
non_tmux = "nvim-right",
},
tmux = {
min_pane_width_for_right = 140,
},
external = {
command_template = nil,
},
worktree = {
mode = "off",
root = ".worktrees",
branch_template = "openspec/{change}",
base = "HEAD",
redirect = true,
post_create = nil,
init_submodules = false,
},
},
})
Product direction
The long-term direction is to make Neovim an OpenSpec control plane: current change awareness, local health and drift checks, worktree context, artifact search, and AI collaboration context while OpenSpec markdown remains the source of truth.
Roadmap phases:
- Build an OpenSpec-aware cockpit for current-change health and task visibility.
- Add artifact-quality checks, missing-file findings, and drift warnings before implementation.
- Make Git branch and worktree context visible from Neovim.
- Keep context packs focused on selected tasks and upstream commands.
- Add optional downstream search and archived-change awareness while staying in plugin scope.
See docs/roadmap.md for the full product roadmap, docs/ideas.md for backlog notes, docs/architecture.md for the current plugin boundary, and docs/release-checklist.md for release-readiness criteria.
Development
Run local checks:
make check
Generate helptags:
make helptags
See DEVELOPMENT.md for the manual smoke test checklist and release criteria.