ctchen222/openspec.nvim

github github
ai
stars 8
issues 0
subscribers 0
forks 0
CREATED

UPDATED


openspec.nvim

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.

OpenSpecImplement Demo

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/changes directory from the current buffer or cwd.
  • Prefer the current openspec/changes/<change>/tasks.md when 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, and tasks.md without 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.md buffer.
  • 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: openspec CLI, 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:

  • :OpenSpecWorkspace opens 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.
  • :OpenSpecCurrent prints a lightweight current-change summary and the top recommendation.

Worktree launches:

  • worktree=off is the default and preserves the current checkout behavior.
  • worktree=auto creates or reuses .worktrees/<change> on branch openspec/<change> after the launch preview is confirmed, then launches the agent with that worktree as cwd.
  • worktree=auto blocks dirty or diverged implementation worktrees before side effects. Use worktree=force only 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=auto shows 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 = false to 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. Use implement.worktree.post_create for setup commands or create the files manually.
  • :OpenSpecWorktree remove <change> refuses dirty worktrees and uses safe branch deletion only.

Agent collaboration pattern:

  • :OpenSpecTaskStart and :OpenSpecWorkspace keep 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 :OpenSpecContext when 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.

License

MIT