Skip to content

spekhq/spek

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

spek

A lightweight, read-only viewer for OpenSpec content — browse specs, changes, and tasks with structure.

Specs Open Changes Tasks

繁體中文


What is spek?

spek turns your local OpenSpec directory into a navigable, searchable interface. Instead of reading raw Markdown files in a text editor, spek provides structured browsing with BDD syntax highlighting, task progress tracking, and full-text search.

Live Demo — Try it instantly in your browser, no install needed.

Available in three forms:

  • Web — Local Express + React app, accessible in any browser
  • VS Code Extension — Integrated Webview Panel within your editor
  • IntelliJ Plugin — JCEF-based Tool Window for IntelliJ IDEA and other JetBrains IDEs

All are read-only and local-only. No server deployment, no authentication, no data leaves your machine.

Features

  • Dashboard — Overview of specs count, changes count, task completion rates, plus lifecycle stats (avg archived lifecycle, stale active changes)
  • Specs Browser — Alphabetical listing with detail view and revision history
  • Changes Browser — Active and archived changes with tabbed views (Proposal / Design / Tasks / Specs); each row surfaces creation and archive dates plus lifecycle duration
  • Git Worktree Aggregation — Discovers every git worktree of a repo and merges their in-flight changes into one view — built for the AI-agent era of parallel worktrees
  • Timeline — Horizontal Gantt-style chart of every change's lifecycle, with optional spec-topic grouping, status filters, and an auto-scaling time axis
  • BDD Syntax Highlighting — Visual distinction for WHEN/GIVEN, THEN, AND, MUST/SHALL keywords
  • Task Progress — Checkbox parsing with section-grouped progress bars
  • Full-text SearchCmd+K / Ctrl+K to search across all specs and changes
  • Dark / Light Theme — Toggle between themes; dark by default
  • Spec History — Git-based timestamp tracking for spec revisions
  • Responsive Layout — Works on various screen sizes
  • VS Code Sidebar — Activity Bar icon with TreeView for browsing specs and changes directly from the sidebar

Git Worktree Aggregation

In the AI-agent era, a single repository often has several git worktrees in flight at once — each agent, or each parallel task, working on its own branch in its own worktree. The OpenSpec changes for that work scatter across those worktrees, and pointing a viewer at any one directory shows only a fraction of what's happening.

spek discovers every worktree of a repository (via git worktree list) and aggregates their in-flight changes into one view. Point spek at any worktree — or the main repo — and you see the whole picture:

  • Active changes from every worktree, each tagged with its source branch
  • Archived changes merged and deduplicated across worktrees
  • An aggregation toggle (auto-on when multiple worktrees exist); main-worktree changes stay unlabelled so feature-worktree work stands out
  • Works in the Web app and the VS Code extension (panel + sidebar), with live refresh when any worktree's openspec/ changes

Git Worktree Aggregation

Quick Start

Web Version

git clone https://github.com/spekhq/spek.git
cd spek
npm install
npm run dev

Open http://localhost:5173, enter a path to a repo containing an openspec/ directory, and start browsing.

npm install compiles the shared @spekjs/core package, and npm run dev rebuilds it before launching — so a fresh clone starts with no extra build step.

VS Code Extension

Install from the Visual Studio Marketplace. The extension activates automatically when your workspace contains openspec/config.yaml.

Once activated, click the spek icon in the Activity Bar to browse specs and changes from the sidebar. Click any item to open the full viewer panel.

Commands:

  • spek: Open spek — Open the viewer panel
  • spek: Search OpenSpec — Open search dialog
  • spek: Open Dashboard — Open the dashboard from sidebar

IntelliJ Plugin

Install from the JetBrains Marketplace — search for "spek" in Settings > Plugins > Marketplace.

The plugin activates automatically when your project contains an openspec/ directory. Click the spek icon in the right sidebar to open the viewer.

Action:

  • Tools > Open spek — Open the viewer panel

Screenshots

Dashboard

Overview of specs count, changes count, and task completion rates.

Dashboard

Specs Browser

Alphabetical listing of all spec topics with filter support.

Specs List

Spec Detail with BDD Highlighting

Visual distinction for BDD keywords — WHEN/GIVEN (blue), THEN (green), AND (gray), MUST/SHALL (red).

Spec Detail

Changes Browser

Active and archived changes listed chronologically, with lifecycle duration on every row.

Changes List

Timeline

Horizontal Gantt-style view of every change's lifecycle — active bars extend to today, archived ones render as fixed segments.

Timeline

Change Detail

Tabbed view with one tab per artifact the change contains. For the default spec-driven schema that's Proposal, Design, Specs, and Tasks; the schema a change was authored under is shown as a badge.

Change Detail

Custom Schemas

spek renders whatever artifacts a change actually contains, so changes authored under a custom OpenSpec schema (e.g. superpowers-bridge with brainstorm / plan / verify / retrospective) show every artifact as its own tab. Tabs default to last-modified order so the artifact you're actively editing surfaces first, and a sort control lets you switch to Schema order or A–Z. Schema order comes from the OpenSpec authority (the openspec CLI) rather than spek parsing the schema format itself, so it's correct for any schema; when the CLI isn't available (or the change is archived) that mode falls back to the default order and says why.

Custom Schema

Full-text Search

Cmd+K / Ctrl+K to search across all specs and changes.

Search

GitHub Action

GitHub Marketplace

Use spek as a GitHub Action to automatically build a static OpenSpec site in your CI pipeline.

Basic Usage

- uses: actions/checkout@v7
  with:
    fetch-depth: 0  # Recommended for accurate change timestamps

- uses: spekhq/spek@v1
  with:
    title: "My Project - OpenSpec"

Deploy to GitHub Pages

name: Build OpenSpec Site
on:
  push:
    branches: [main]
    paths: ["openspec/**"]

permissions:
  pages: write
  id-token: write

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deploy.outputs.page_url }}
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0

      - uses: spekhq/spek@v1
        with:
          title: "My Project - OpenSpec"

      - uses: actions/upload-pages-artifact@v5
        with:
          path: spek-output

      - name: Deploy to GitHub Pages
        id: deploy
        uses: actions/deploy-pages@v5

Inputs

Input Description Default
repo-path Path to the repo containing openspec/ .
output-path Output HTML file path spek-output/spek.html
title Page title OpenSpec Viewer
spek-version spek version (tag, branch, or SHA) master
generate-badges Generate SVG badge files false

Outputs

Output Description
html-path Absolute path to the generated HTML file
badges-path Absolute path to the generated badges directory

Badges

Enable generate-badges to generate SVG status badges (specs count, open changes, tasks progress) alongside your static site. Deploy them to GitHub Pages and reference in your README:

- uses: spekhq/spek@v1
  with:
    title: "My Project - OpenSpec"
    generate-badges: true

Then in your README:

![Specs](https://your-user.github.io/your-repo/badges/specs.svg)
![Open Changes](https://your-user.github.io/your-repo/badges/open_changes.svg)
![Tasks](https://your-user.github.io/your-repo/badges/tasks.svg)

Note: Use fetch-depth: 0 in your checkout step for accurate change timestamps. Without full git history, timestamps will be unavailable (the build still succeeds).

OpenSpec Directory Structure

spek expects the following structure under your repository:

{repo}/openspec/
├── config.yaml
├── specs/
│   └── {topic}/
│       └── spec.md              # BDD-formatted specification
└── changes/
    ├── {active-change}/         # In-progress changes
    │   ├── .openspec.yaml
    │   ├── proposal.md
    │   ├── design.md
    │   ├── tasks.md
    │   └── specs/               # Delta specs for this change
    └── archive/
        └── {YYYY-MM-DD-desc}/   # Archived changes (same structure)

Architecture

Monorepo Structure

packages/
├── core/       # @spekjs/core — Pure logic (scanner, parser, types)         [published to npm]
├── ui/         # @spekjs/ui   — Reusable visualizations (graph, timeline)   [published to npm]
├── web/        # @spekjs/web  — Express API + React SPA
├── vscode/     # spek-vscode  — VS Code Extension
└── intellij/   # spek-intellij — IntelliJ Platform Plugin (Kotlin)

Published packages

Two packages are published so that hosts outside this monorepo can reuse them:

  • @spekjs/core — the engine: scanner, tasks parser, worktree aggregation, shared types. Pure Node.js, no framework.
  • @spekjs/ui — the two visualizations: <SpecGraph> (force-directed spec ↔ change graph) and <ChangeTimeline> (Gantt-style change lifecycle). Presentational only — no router, no data layer, no CSS framework. Colours are an explicit contract of eight CSS custom properties, so a host re-themes them by overriding those.

Within this monorepo they resolve through npm workspaces, so development is not gated on their release cadence. Both are released manually and version independently of the root.

API Adapter Pattern

The frontend communicates through an ApiAdapter interface with two implementations:

  • FetchAdapter — Web + IntelliJ version, calls REST API over HTTP (configurable base URL)
  • MessageAdapter — VS Code version, uses postMessage IPC with the extension host

This allows the same React UI to run in both environments without code changes.

Note that @spekjs/ui does not depend on ApiAdapter: its components take data through props. Fetching is the host's concern — over HTTP here, over IPC in an Electron host.

Tech Stack

Layer Technology
Core TypeScript, Node.js
UI package React 19 (peer), d3 (force, zoom, drag, selection, transition), hand-written CSS
Frontend React 19, Vite 6, Tailwind CSS v4, React Router v7
Backend Express 4
Markdown react-markdown, remark-gfm
Search Fuse.js
VS Code Extension VS Code Webview API, esbuild
IntelliJ Plugin Kotlin, JCEF, IntelliJ Platform SDK

Development

npm install              # Install all workspace dependencies
npm run dev              # Start Vite (5173) + Express (3001)
npm run build            # Build core + ui + web
npm run build:core       # Build @spekjs/core only
npm run build:ui         # Build @spekjs/ui only
npm run build:webview    # Build webview assets for VS Code extension
npm run build:vscode     # Build VS Code extension
npm run build:intellij   # Build IntelliJ webview assets
npm run type-check       # TypeScript type check

IntelliJ Plugin build:

npm run build:intellij                    # Build frontend assets
cd packages/intellij && ./gradlew buildPlugin  # Build plugin ZIP

Requirements: Node.js 22+, Java 17+ (for IntelliJ plugin build)

Live reload in containers (devcontainer / WSL)

spek watches openspec/ and live-reloads on changes. On filesystems that don't deliver native change events — 9p / drvfs / NFS / CIFS bind mounts, as used by devcontainers and WSL — spek automatically falls back to polling so newly created files are still detected. Detection is based on the watched path's filesystem type. To override:

  • SPEK_WATCH_POLLING=on (or off) — force polling on/off for all surfaces
  • CHOKIDAR_USEPOLLING=1 / CHOKIDAR_INTERVAL=<ms> — Web and VS Code also honor chokidar's native env vars

Acknowledgments

This project was inspired by 龍哥(高見龍)'s articles on SDD (Spec Driven Development). Special thanks to him for his contributions to SDD and OpenSpec.

Contributors

Thanks to everyone who has contributed to spek:

  • @nthansen (Norman Hansen)

    • Custom OpenSpec schema support — a change's artifacts are discovered from disk, so any schema's artifacts render as their own tabs
    • User-selectable artifact tab ordering (last-modified / schema order / A–Z), with schema order sourced from the OpenSpec CLI
    • Schema badge across the Changes list, Dashboard, and Change Detail, hidden when it matches the repo default
    • Polling-based live-reload fallback for filesystems without native change events (devcontainer / WSL / network mounts)
    • Worktree-aware schema baseline — under aggregation each change's badge is judged against its own worktree's default schema, and scanning reads each worktree's config once instead of once per change
    • TOC and #hash navigation that lands the target heading below the sticky header instead of behind it
    • Opening a change no longer consults the OpenSpec CLI once per change — the authoritative artifact order is cached per schema, since every change sharing a schema gets the same answer back
  • @david-lutz (David Lutz)

    • Deduplication of active changes shared across git worktrees, in both the Changes list and the dependency graph — the surviving copy is elected from git divergence rather than file timestamps, which a fresh checkout rewrites

License

MIT

About

A lightweight, read-only viewer for OpenSpec content

Topics

Resources

License

Stars

34 stars

Watchers

1 watching

Forks

Contributors