@stritti/vitepress-plugin-openspec 0.8.4 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -76
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @stritti/vitepress-plugin-openspec
|
|
2
2
|
|
|
3
|
-
A [VitePress](https://vitepress.dev/) plugin that renders your
|
|
3
|
+
A [VitePress](https://vitepress.dev/) plugin that renders your [OpenSpec](https://openspec.dev/) folder as structured documentation pages with automatic sidebar and navigation integration.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@stritti/vitepress-plugin-openspec)
|
|
6
6
|
[](https://www.npmjs.com/package/@stritti/vitepress-plugin-openspec)
|
|
@@ -9,7 +9,20 @@ A [VitePress](https://vitepress.dev/) plugin that renders your project's [OpenSp
|
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## What is OpenSpec?
|
|
13
|
+
|
|
14
|
+
[OpenSpec](https://openspec.dev/) is a specification format that organizes your project documentation into capabilities and changes. It structures your docs into:
|
|
15
|
+
- **Specs** – Capability specifications in `openspec/specs/<capability>/spec.md`
|
|
16
|
+
- **Changes** – Proposed changes with artifacts in `openspec/changes/<name>/`
|
|
17
|
+
- **Archive** – Completed changes in `openspec/changes/archive/`
|
|
18
|
+
|
|
19
|
+
This plugin renders your OpenSpec folder as navigable VitePress documentation pages.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### Install
|
|
13
26
|
|
|
14
27
|
```bash
|
|
15
28
|
npm install @stritti/vitepress-plugin-openspec
|
|
@@ -17,76 +30,82 @@ npm install @stritti/vitepress-plugin-openspec
|
|
|
17
30
|
bun add @stritti/vitepress-plugin-openspec
|
|
18
31
|
```
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
## Usage
|
|
33
|
+
### Configure
|
|
23
34
|
|
|
24
|
-
|
|
35
|
+
Wrap your VitePress config with `withOpenSpec()`:
|
|
25
36
|
|
|
26
37
|
```typescript
|
|
38
|
+
// docs/.vitepress/config.ts
|
|
27
39
|
import { defineConfig } from 'vitepress'
|
|
28
40
|
import { withOpenSpec } from '@stritti/vitepress-plugin-openspec'
|
|
29
41
|
|
|
30
42
|
export default defineConfig(
|
|
31
43
|
withOpenSpec({
|
|
32
|
-
|
|
33
|
-
themeConfig: {
|
|
34
|
-
nav: [{ text: 'Home', link: '/' }],
|
|
35
|
-
sidebar: {},
|
|
36
|
-
},
|
|
44
|
+
title: 'My Project',
|
|
37
45
|
})
|
|
38
46
|
)
|
|
39
47
|
```
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
That's it! Run `vitepress dev` and your OpenSpec docs appear at `/openspec/`.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Features
|
|
42
54
|
|
|
43
|
-
**Zero-config
|
|
55
|
+
- **Zero-config** – Automatically detects your `openspec/` folder and VitePress source directory
|
|
56
|
+
- **Live reload** – Pages update automatically during `vitepress dev` when you edit OpenSpec files
|
|
57
|
+
- **Sidebar & nav** – Automatic integration into VitePress theme with configurable labels
|
|
58
|
+
- **Index pages** – Generated overviews for specs, changes, and archive with proper hierarchy
|
|
59
|
+
- **Smart defaults** – Works with standard project layouts out of the box
|
|
44
60
|
|
|
45
|
-
|
|
46
|
-
- `srcDir`: the plugin detects the directory containing `.vitepress` — either the working directory itself, a first-level subdirectory such as `docs/`, or the parent when the config is evaluated from inside `docs/.vitepress/`.
|
|
61
|
+
---
|
|
47
62
|
|
|
48
|
-
|
|
63
|
+
## Configuration
|
|
49
64
|
|
|
50
|
-
|
|
65
|
+
### `withOpenSpec(config, options?)`
|
|
66
|
+
|
|
67
|
+
Wrap your VitePress config. `withOpenSpec` handles page generation, the Vite plugin for live reload, nav entry, and sidebar section in one call.
|
|
51
68
|
|
|
52
69
|
```typescript
|
|
53
70
|
import { defineConfig } from 'vitepress'
|
|
54
71
|
import { withOpenSpec } from '@stritti/vitepress-plugin-openspec'
|
|
55
|
-
import myOtherPlugin from 'vitepress-plugin-something'
|
|
56
72
|
|
|
57
73
|
export default defineConfig(
|
|
58
74
|
withOpenSpec(
|
|
59
75
|
{
|
|
60
|
-
|
|
61
|
-
themeConfig: {
|
|
76
|
+
// Your regular VitePress config
|
|
77
|
+
themeConfig: {
|
|
78
|
+
nav: [{ text: 'Home', link: '/' }],
|
|
79
|
+
sidebar: {},
|
|
80
|
+
},
|
|
62
81
|
},
|
|
63
|
-
{ specDir: '../openspec', outDir: 'openspec' } //
|
|
82
|
+
{ specDir: '../openspec', outDir: 'openspec' } // Options (all optional)
|
|
64
83
|
)
|
|
65
84
|
)
|
|
66
85
|
```
|
|
67
86
|
|
|
68
|
-
|
|
87
|
+
**Note:** Array-based sidebars are automatically converted to object form (`{ '/': [...] }`) to inject the OpenSpec section while preserving your existing entries.
|
|
69
88
|
|
|
70
|
-
|
|
89
|
+
### Options
|
|
71
90
|
|
|
72
91
|
| Option | Type | Default | Description |
|
|
73
92
|
| --- | --- | --- | --- |
|
|
74
|
-
| `specDir` | `string` | auto-detected
|
|
93
|
+
| `specDir` | `string` | auto-detected | Path to your `openspec/` directory. Auto-detects nearest ancestor folder or falls back to `./openspec` |
|
|
75
94
|
| `outDir` | `string` | `'openspec'` | Output directory relative to VitePress `srcDir` |
|
|
76
|
-
| `srcDir` | `string` | auto-detected
|
|
77
|
-
| `nav` | `boolean` | `true` |
|
|
78
|
-
| `sidebar` | `boolean` | `true` |
|
|
79
|
-
| `navText` | `string` | `'Docs'` | Label for the nav entry
|
|
95
|
+
| `srcDir` | `string` | auto-detected | VitePress source directory (folder containing `.vitepress/`) |
|
|
96
|
+
| `nav` | `boolean` | `true` | Prepend OpenSpec entry to `themeConfig.nav` |
|
|
97
|
+
| `sidebar` | `boolean` | `true` | Inject OpenSpec sidebar section into `themeConfig.sidebar` |
|
|
98
|
+
| `navText` | `string` | `'Docs'` | Label for the nav entry |
|
|
80
99
|
|
|
81
|
-
> **Missing
|
|
100
|
+
> **Missing `specDir`:** If the folder doesn't exist, the plugin emits a warning and skips generation. Your build continues normally.
|
|
82
101
|
|
|
83
|
-
> **Invalid `outDir
|
|
102
|
+
> **Invalid `outDir`:** An absolute path, empty string, or path resolving outside `srcDir` throws an error at config time.
|
|
84
103
|
|
|
85
104
|
---
|
|
86
105
|
|
|
87
|
-
## Advanced
|
|
106
|
+
## Advanced Setup
|
|
88
107
|
|
|
89
|
-
|
|
108
|
+
For full control over each integration point, use the lower-level APIs:
|
|
90
109
|
|
|
91
110
|
```typescript
|
|
92
111
|
import { defineConfig } from 'vitepress'
|
|
@@ -99,23 +118,22 @@ import openspec, {
|
|
|
99
118
|
} from '@stritti/vitepress-plugin-openspec'
|
|
100
119
|
|
|
101
120
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
102
|
-
const specDir = path.resolve(__dirname, '../openspec')
|
|
103
121
|
|
|
104
|
-
// Must be called before defineConfig so pages exist when VitePress scans for routes
|
|
122
|
+
// Must be called before defineConfig so pages exist when VitePress scans for routes
|
|
105
123
|
generateOpenSpecPages({
|
|
106
|
-
specDir,
|
|
124
|
+
specDir: path.resolve(__dirname, '../openspec'),
|
|
107
125
|
outDir: 'openspec',
|
|
108
126
|
srcDir: path.resolve(__dirname, '..'),
|
|
109
127
|
})
|
|
110
128
|
|
|
111
129
|
export default defineConfig({
|
|
112
130
|
vite: {
|
|
113
|
-
plugins: [openspec({ specDir, outDir: 'openspec' })],
|
|
131
|
+
plugins: [openspec({ specDir: path.resolve(__dirname, '../openspec'), outDir: 'openspec' })],
|
|
114
132
|
},
|
|
115
133
|
themeConfig: {
|
|
116
|
-
nav: [openspecNav(
|
|
134
|
+
nav: [openspecNav(path.resolve(__dirname, '../openspec'), { outDir: 'openspec', text: 'Docs' })],
|
|
117
135
|
sidebar: {
|
|
118
|
-
'/openspec/': generateOpenSpecSidebar(
|
|
136
|
+
'/openspec/': generateOpenSpecSidebar(path.resolve(__dirname, '../openspec'), { outDir: 'openspec' }),
|
|
119
137
|
},
|
|
120
138
|
},
|
|
121
139
|
})
|
|
@@ -123,51 +141,22 @@ export default defineConfig({
|
|
|
123
141
|
|
|
124
142
|
---
|
|
125
143
|
|
|
126
|
-
##
|
|
144
|
+
## How It Works
|
|
127
145
|
|
|
128
|
-
|
|
146
|
+
VitePress scans `srcDir` for `.md` files **before** any Vite plugin hooks run. This plugin solves this with two mechanisms:
|
|
129
147
|
|
|
130
|
-
|
|
131
|
-
openspec
|
|
132
|
-
├── specs/
|
|
133
|
-
│ └── <capability>/
|
|
134
|
-
│ └── spec.md
|
|
135
|
-
└── changes/
|
|
136
|
-
├── <change-name>/
|
|
137
|
-
│ ├── .openspec.yaml
|
|
138
|
-
│ ├── proposal.md
|
|
139
|
-
│ ├── design.md
|
|
140
|
-
│ └── tasks.md
|
|
141
|
-
└── archive/
|
|
142
|
-
└── YYYY-MM-DD-<change-name>/
|
|
143
|
-
|
|
144
|
-
docs/openspec/ ← generated by the plugin (automatically gitignored)
|
|
145
|
-
├── index.md
|
|
146
|
-
├── specs/
|
|
147
|
-
│ ├── index.md
|
|
148
|
-
│ └── <capability>/
|
|
149
|
-
│ └── index.md
|
|
150
|
-
└── changes/
|
|
151
|
-
├── index.md
|
|
152
|
-
├── <change-name>/
|
|
153
|
-
│ ├── index.md
|
|
154
|
-
│ ├── proposal.md
|
|
155
|
-
│ └── tasks.md
|
|
156
|
-
└── archive/
|
|
157
|
-
└── YYYY-MM-DD-<change-name>/
|
|
158
|
-
└── ...
|
|
159
|
-
```
|
|
148
|
+
1. **`generateOpenSpecPages()`** – Called synchronously before `defineConfig()` to ensure pages exist when VitePress scans for routes (critical for first builds and CI)
|
|
149
|
+
2. **`openspec()` Vite plugin** – Re-generates pages on every config reload during `vitepress dev` for live reload support
|
|
160
150
|
|
|
161
|
-
The plugin automatically writes a `.gitignore`
|
|
151
|
+
The plugin automatically writes a `.gitignore` in the output directory to exclude generated files.
|
|
162
152
|
|
|
163
153
|
---
|
|
164
154
|
|
|
165
|
-
##
|
|
166
|
-
|
|
167
|
-
VitePress scans `srcDir` for `.md` files **before** any Vite plugin hooks run. The plugin solves this with two complementary mechanisms:
|
|
155
|
+
## Documentation
|
|
168
156
|
|
|
169
|
-
|
|
170
|
-
|
|
157
|
+
- [Full Integration Guide](https://stritti.github.io/vitepress-plugin-openspec/guide) – Complete setup and configuration
|
|
158
|
+
- [API Reference](https://stritti.github.io/vitepress-plugin-openspec/guide#api-reference) – Detailed API documentation
|
|
159
|
+
- [Troubleshooting](https://stritti.github.io/vitepress-plugin-openspec/guide#troubleshooting) – Common issues and solutions
|
|
171
160
|
|
|
172
161
|
---
|
|
173
162
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stritti/vitepress-plugin-openspec",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"description": "A VitePress plugin that integrates OpenSpec documentation into your VitePress site",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openspec",
|
|
@@ -47,22 +47,24 @@
|
|
|
47
47
|
"picocolors": "^1.1.1"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
+
"@eslint/js": "^10.0.0",
|
|
51
|
+
"@semantic-release/changelog": "^7.0.0",
|
|
50
52
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
53
|
+
"@semantic-release/git": "^11.0.1",
|
|
51
54
|
"@semantic-release/github": "^12.0.6",
|
|
52
55
|
"@semantic-release/npm": "^13.1.5",
|
|
53
56
|
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
54
57
|
"@types/js-yaml": "^4.0.9",
|
|
55
58
|
"@types/node": "^26.6.4",
|
|
56
59
|
"@vitest/coverage-v8": "^5.0.3",
|
|
60
|
+
"eslint": "^10.13.0",
|
|
57
61
|
"semantic-release": "^25.0.3",
|
|
58
|
-
"tsup": "^
|
|
62
|
+
"tsup": "^9.0.0",
|
|
59
63
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
64
|
+
"typescript-eslint": "^8.72.0",
|
|
60
65
|
"vite": "^8.0.5",
|
|
61
66
|
"vitepress": "^1.6.4",
|
|
62
|
-
"vitest": "^5.0.3"
|
|
63
|
-
"@eslint/js": "^10.0.0",
|
|
64
|
-
"eslint": "^10.13.0",
|
|
65
|
-
"typescript-eslint": "^8.72.0"
|
|
67
|
+
"vitest": "^5.0.3"
|
|
66
68
|
},
|
|
67
69
|
"peerDependencies": {
|
|
68
70
|
"vite": ">=5.0.0",
|