@stritti/vitepress-plugin-openspec 0.7.0 → 0.8.0
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 +12 -2
- package/dist/index.cjs +537 -137
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -217
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +537 -136
- package/dist/index.js.map +1 -1
- package/dist/lib/detect.d.ts +43 -0
- package/dist/lib/detect.d.ts.map +1 -0
- package/dist/lib/dev-server.d.ts +28 -0
- package/dist/lib/dev-server.d.ts.map +1 -0
- package/dist/lib/generator.d.ts +12 -0
- package/dist/lib/generator.d.ts.map +1 -0
- package/dist/lib/links.d.ts +10 -0
- package/dist/lib/links.d.ts.map +1 -0
- package/dist/lib/logger.d.ts +5 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/markdown.d.ts +6 -0
- package/dist/lib/markdown.d.ts.map +1 -0
- package/dist/lib/navigation.d.ts +16 -0
- package/dist/lib/navigation.d.ts.map +1 -0
- package/dist/lib/options.d.ts +28 -0
- package/dist/lib/options.d.ts.map +1 -0
- package/dist/lib/pages.d.ts +22 -0
- package/dist/lib/pages.d.ts.map +1 -0
- package/dist/lib/reader.d.ts +10 -0
- package/dist/lib/reader.d.ts.map +1 -0
- package/dist/lib/watch.d.ts +36 -0
- package/dist/lib/watch.d.ts.map +1 -0
- package/dist/plugin.d.ts +50 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/types.d.ts +133 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +5 -5
- package/dist/index.d.cts +0 -217
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import type { OpenSpecPluginOptions, WithOpenSpecOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Synchronously generates all VitePress Markdown pages from the openspec/
|
|
5
|
+
* directory and writes them to disk.
|
|
6
|
+
*
|
|
7
|
+
* Call this at the top of your `docs/.vitepress/config.ts` **before**
|
|
8
|
+
* `defineConfig()` so the files exist when VitePress scans the source
|
|
9
|
+
* directory for routes. In most cases `withOpenSpec()` (which calls this
|
|
10
|
+
* internally) is the simpler integration point.
|
|
11
|
+
*
|
|
12
|
+
* @returns true when pages were written; false when generation was skipped
|
|
13
|
+
* (missing or unreadable source, ambiguous source-directory detection) or
|
|
14
|
+
* failed.
|
|
15
|
+
* @throws if `outDir` is not a relative path inside `srcDir` (absolute,
|
|
16
|
+
* traversal, or empty).
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateOpenSpecPages(userOptions?: OpenSpecPluginOptions): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Vite plugin that regenerates the openspec documentation pages whenever a
|
|
21
|
+
* file inside the openspec/ directory changes. This makes `vitepress dev`
|
|
22
|
+
* pick up spec edits without a manual restart.
|
|
23
|
+
*
|
|
24
|
+
* For the pages to be available on the first build (including CI), the pages
|
|
25
|
+
* are generated once in `configResolved`. When using `withOpenSpec()` this
|
|
26
|
+
* plugin is wired up automatically.
|
|
27
|
+
*/
|
|
28
|
+
export declare function openspec(userOptions?: OpenSpecPluginOptions): Plugin;
|
|
29
|
+
/**
|
|
30
|
+
* One-call VitePress config helper that wires up the full openspec integration.
|
|
31
|
+
*
|
|
32
|
+
* Calls `generateOpenSpecPages()` synchronously (required before VitePress scans
|
|
33
|
+
* for routes), then merges the openspec Vite plugin, nav entry, and sidebar section
|
|
34
|
+
* into the provided config object.
|
|
35
|
+
*
|
|
36
|
+
* Other Vite plugins go into `vite.plugins` as usual — `withOpenSpec` appends to
|
|
37
|
+
* the array without replacing it.
|
|
38
|
+
*
|
|
39
|
+
* When the VitePress source directory cannot be detected unambiguously
|
|
40
|
+
* (multiple `.vitepress` folders at the same level), a warning is emitted and
|
|
41
|
+
* the config is returned with only the sidebar shape normalized — nothing is
|
|
42
|
+
* generated or injected.
|
|
43
|
+
*
|
|
44
|
+
* @param config - Your VitePress `UserConfig` object (same as what `defineConfig` accepts).
|
|
45
|
+
* @param options - OpenSpec options. All fields are optional; defaults match `generateOpenSpecPages`.
|
|
46
|
+
* @throws if `outDir` is not a relative path inside `srcDir` (absolute, traversal, or empty).
|
|
47
|
+
*/
|
|
48
|
+
export declare function withOpenSpec<T extends Record<string, unknown>>(config: T, options?: WithOpenSpecOptions): T;
|
|
49
|
+
export default openspec;
|
|
50
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAS5E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,GAAE,qBAA0B,GAAG,OAAO,CAQtF;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,WAAW,GAAE,qBAA0B,GAAG,MAAM,CAyFxE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,mBAAwB,GAChC,CAAC,CA+DH;eAEc,QAAQ"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for the `withOpenSpec()` config helper.
|
|
3
|
+
* Extends `OpenSpecPluginOptions` with optional nav/sidebar merge controls.
|
|
4
|
+
*/
|
|
5
|
+
export interface WithOpenSpecOptions extends OpenSpecPluginOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Whether to prepend an openspec nav entry to `themeConfig.nav`.
|
|
8
|
+
* @default true
|
|
9
|
+
*/
|
|
10
|
+
nav?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Whether to inject the openspec sidebar section into `themeConfig.sidebar`.
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
sidebar?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Label for the nav entry injected into `themeConfig.nav`.
|
|
18
|
+
* @default 'Docs'
|
|
19
|
+
*/
|
|
20
|
+
navText?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Configuration options for the vitepress-plugin-openspec plugin.
|
|
24
|
+
*/
|
|
25
|
+
export interface OpenSpecPluginOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Path to the openspec/ directory of the project.
|
|
28
|
+
*
|
|
29
|
+
* By default the plugin walks up from the current working directory looking
|
|
30
|
+
* for an `openspec/` folder (skipping generated output recognized by its
|
|
31
|
+
* marker), so no configuration is needed when it lives at the project root.
|
|
32
|
+
* Set an explicit path only for custom locations.
|
|
33
|
+
*
|
|
34
|
+
* If the directory does not exist a warning is printed and the build continues
|
|
35
|
+
* without generating any pages or nav/sidebar entries — no error is thrown.
|
|
36
|
+
* An invalid `outDir` (absolute, empty, or escaping `srcDir`) throws instead.
|
|
37
|
+
*
|
|
38
|
+
* @default auto-detected (`<nearest ancestor>/openspec`, falling back to `'./openspec'`)
|
|
39
|
+
* @example
|
|
40
|
+
* // Resolving from docs/.vitepress/config.ts
|
|
41
|
+
* import path from 'node:path'
|
|
42
|
+
* import { fileURLToPath } from 'node:url'
|
|
43
|
+
* const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
44
|
+
* const specDir = path.resolve(__dirname, '../../openspec')
|
|
45
|
+
*/
|
|
46
|
+
specDir?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Output directory (relative to VitePress `srcDir`) where the generated
|
|
49
|
+
* Markdown pages will be written.
|
|
50
|
+
* @default 'openspec'
|
|
51
|
+
*/
|
|
52
|
+
outDir?: string;
|
|
53
|
+
/**
|
|
54
|
+
* VitePress source directory — the directory containing your `.md` files
|
|
55
|
+
* (i.e. the `docs/` folder). By default the plugin detects the directory that
|
|
56
|
+
* contains `.vitepress` (the working directory, a first-level subdirectory
|
|
57
|
+
* such as `docs/`, or the parent when the config is evaluated from inside
|
|
58
|
+
* `docs/.vitepress/`), so no configuration is needed for standard layouts.
|
|
59
|
+
*
|
|
60
|
+
* @default auto-detected (directory containing `.vitepress`, falling back to the working directory)
|
|
61
|
+
* @example path.resolve(__dirname, '..') // from docs/.vitepress/config.ts
|
|
62
|
+
*/
|
|
63
|
+
srcDir?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A canonical capability specification from openspec/specs/<name>/spec.md
|
|
67
|
+
*/
|
|
68
|
+
export interface CapabilitySpec {
|
|
69
|
+
/** Folder name (kebab-case capability identifier) */
|
|
70
|
+
name: string;
|
|
71
|
+
/** Optional display title from spec.md frontmatter. Overrides humanized name. */
|
|
72
|
+
title?: string;
|
|
73
|
+
/** Absolute path to the spec.md file */
|
|
74
|
+
specPath: string;
|
|
75
|
+
/** Raw Markdown content of the spec */
|
|
76
|
+
content: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A single artifact (file) belonging to a Change.
|
|
80
|
+
*/
|
|
81
|
+
export type ChangeArtifact = 'proposal' | 'design' | 'tasks';
|
|
82
|
+
/**
|
|
83
|
+
* An OpenSpec change (active or archived).
|
|
84
|
+
*/
|
|
85
|
+
export interface Change {
|
|
86
|
+
/** Change directory name (e.g. "my-feature" or for archived: "my-feature" extracted from "2026-03-10-my-feature") */
|
|
87
|
+
name: string;
|
|
88
|
+
/** Optional display title from .openspec.yaml. Overrides humanized name. */
|
|
89
|
+
title?: string;
|
|
90
|
+
/** Absolute path to the change directory */
|
|
91
|
+
dir: string;
|
|
92
|
+
/** Which artifact files are present */
|
|
93
|
+
artifacts: ChangeArtifact[];
|
|
94
|
+
/** Creation date from .openspec.yaml, if available */
|
|
95
|
+
createdDate?: string;
|
|
96
|
+
/** For archived changes: the archive date (YYYY-MM-DD) parsed from directory name */
|
|
97
|
+
archivedDate?: string;
|
|
98
|
+
/**
|
|
99
|
+
* For archived changes: the original archive folder name (e.g. "2026-01-15-my-feature" or
|
|
100
|
+
* "legacy-feature" for non-standard names). Used to build correct archive URLs.
|
|
101
|
+
*/
|
|
102
|
+
archiveFolderName?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The full parsed structure of an openspec/ directory.
|
|
106
|
+
*/
|
|
107
|
+
export interface OpenSpecFolder {
|
|
108
|
+
/** Absolute path to the openspec/ root */
|
|
109
|
+
dir: string;
|
|
110
|
+
/** Canonical capability specs from openspec/specs/ */
|
|
111
|
+
specs: CapabilitySpec[];
|
|
112
|
+
/** Active changes from openspec/changes/ (excluding archive/) */
|
|
113
|
+
changes: Change[];
|
|
114
|
+
/** Archived changes from openspec/changes/archive/ */
|
|
115
|
+
archivedChanges: Change[];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* A nav item compatible with VitePress `DefaultTheme.NavItem`.
|
|
119
|
+
*/
|
|
120
|
+
export interface NavItem {
|
|
121
|
+
text: string;
|
|
122
|
+
link: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A sidebar item compatible with VitePress `DefaultTheme.SidebarItem`.
|
|
126
|
+
*/
|
|
127
|
+
export interface SidebarItem {
|
|
128
|
+
text: string;
|
|
129
|
+
link?: string;
|
|
130
|
+
collapsed?: boolean;
|
|
131
|
+
items?: SidebarItem[];
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB;IAChE;;;OAGG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAA;IACZ,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAA;IAChB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE5D;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,qHAAqH;IACrH,IAAI,EAAE,MAAM,CAAA;IACZ,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAA;IACX,uCAAuC;IACvC,SAAS,EAAE,cAAc,EAAE,CAAA;IAC3B,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAA;IACX,sDAAsD;IACtD,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,iEAAiE;IACjE,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,sDAAsD;IACtD,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,KAAK,CAAC,EAAE,WAAW,EAAE,CAAA;CACtB"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility re-exports. The implementation lives in `./lib/` modules;
|
|
3
|
+
* these named exports are kept stable for existing consumers.
|
|
4
|
+
*/
|
|
5
|
+
export { readOpenSpecFolder } from './lib/reader.js';
|
|
6
|
+
export { rewriteRelativeLinks } from './lib/links.js';
|
|
7
|
+
export { generateSpecPage, generateSpecsIndexPage, generateChangeIndexPage, generateChangesIndexPage, } from './lib/pages.js';
|
|
8
|
+
export { generateOpenSpecSidebar, openspecNav } from './lib/navigation.js';
|
|
9
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stritti/vitepress-plugin-openspec",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "A VitePress plugin that integrates OpenSpec documentation into your VitePress site",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openspec",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
|
-
"build": "tsup",
|
|
35
|
+
"build": "tsup && tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist",
|
|
36
36
|
"dev": "tsup --watch",
|
|
37
37
|
"lint": "tsc --noEmit",
|
|
38
38
|
"prepublishOnly": "npm run build",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"docs:build": "cd docs && bun run build"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"js-yaml": "^4.
|
|
45
|
+
"js-yaml": "^5.4.2",
|
|
46
46
|
"picocolors": "^1.1.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"@types/node": "^25.4.0",
|
|
55
55
|
"semantic-release": "^25.0.3",
|
|
56
56
|
"tsup": "^8.5.1",
|
|
57
|
-
"typescript": "^
|
|
58
|
-
"vite": "^
|
|
57
|
+
"typescript": "^7.0.2",
|
|
58
|
+
"vite": "^8.0.5",
|
|
59
59
|
"vitepress": "^1.6.4",
|
|
60
60
|
"vitest": "^4.0.18"
|
|
61
61
|
},
|
package/dist/index.d.cts
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import { Plugin } from 'vite';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Options for the `withOpenSpec()` config helper.
|
|
5
|
-
* Extends `OpenSpecPluginOptions` with optional nav/sidebar merge controls.
|
|
6
|
-
*/
|
|
7
|
-
interface WithOpenSpecOptions extends OpenSpecPluginOptions {
|
|
8
|
-
/**
|
|
9
|
-
* Whether to prepend an openspec nav entry to `themeConfig.nav`.
|
|
10
|
-
* @default true
|
|
11
|
-
*/
|
|
12
|
-
nav?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* Whether to inject the openspec sidebar section into `themeConfig.sidebar`.
|
|
15
|
-
* @default true
|
|
16
|
-
*/
|
|
17
|
-
sidebar?: boolean;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Configuration options for the vitepress-plugin-openspec plugin.
|
|
21
|
-
*/
|
|
22
|
-
interface OpenSpecPluginOptions {
|
|
23
|
-
/**
|
|
24
|
-
* Path to the openspec/ directory of the project.
|
|
25
|
-
*
|
|
26
|
-
* Use an explicit path when your `openspec/` folder is not at the project root
|
|
27
|
-
* (e.g. when `config.ts` lives inside `docs/.vitepress/`).
|
|
28
|
-
*
|
|
29
|
-
* If the directory does not exist a warning is printed and the build continues
|
|
30
|
-
* without generating any pages or nav/sidebar entries — no error is thrown.
|
|
31
|
-
*
|
|
32
|
-
* @default './openspec'
|
|
33
|
-
* @example
|
|
34
|
-
* // Resolving from docs/.vitepress/config.ts
|
|
35
|
-
* import path from 'node:path'
|
|
36
|
-
* import { fileURLToPath } from 'node:url'
|
|
37
|
-
* const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
38
|
-
* const specDir = path.resolve(__dirname, '../../openspec')
|
|
39
|
-
*/
|
|
40
|
-
specDir?: string;
|
|
41
|
-
/**
|
|
42
|
-
* Output directory (relative to VitePress `srcDir`) where the generated
|
|
43
|
-
* Markdown pages will be written.
|
|
44
|
-
* @default 'openspec'
|
|
45
|
-
*/
|
|
46
|
-
outDir?: string;
|
|
47
|
-
/**
|
|
48
|
-
* VitePress source directory — the directory containing your `.md` files
|
|
49
|
-
* (i.e. the `docs/` folder). Required when calling `generateOpenSpecPages()`
|
|
50
|
-
* at config evaluation time so it knows where to write the generated files.
|
|
51
|
-
*
|
|
52
|
-
* @default process.cwd()
|
|
53
|
-
* @example path.resolve(__dirname, '..') // from docs/.vitepress/config.ts
|
|
54
|
-
*/
|
|
55
|
-
srcDir?: string;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* A canonical capability specification from openspec/specs/<name>/spec.md
|
|
59
|
-
*/
|
|
60
|
-
interface CapabilitySpec {
|
|
61
|
-
/** Folder name (kebab-case capability identifier) */
|
|
62
|
-
name: string;
|
|
63
|
-
/** Optional display title from spec.md frontmatter. Overrides humanized name. */
|
|
64
|
-
title?: string;
|
|
65
|
-
/** Absolute path to the spec.md file */
|
|
66
|
-
specPath: string;
|
|
67
|
-
/** Raw Markdown content of the spec */
|
|
68
|
-
content: string;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* A single artifact (file) belonging to a Change.
|
|
72
|
-
*/
|
|
73
|
-
type ChangeArtifact = 'proposal' | 'design' | 'tasks';
|
|
74
|
-
/**
|
|
75
|
-
* An OpenSpec change (active or archived).
|
|
76
|
-
*/
|
|
77
|
-
interface Change {
|
|
78
|
-
/** Change directory name (e.g. "my-feature" or for archived: "my-feature" extracted from "2026-03-10-my-feature") */
|
|
79
|
-
name: string;
|
|
80
|
-
/** Optional display title from .openspec.yaml. Overrides humanized name. */
|
|
81
|
-
title?: string;
|
|
82
|
-
/** Absolute path to the change directory */
|
|
83
|
-
dir: string;
|
|
84
|
-
/** Which artifact files are present */
|
|
85
|
-
artifacts: ChangeArtifact[];
|
|
86
|
-
/** Creation date from .openspec.yaml, if available */
|
|
87
|
-
createdDate?: string;
|
|
88
|
-
/** For archived changes: the archive date (YYYY-MM-DD) parsed from directory name */
|
|
89
|
-
archivedDate?: string;
|
|
90
|
-
/**
|
|
91
|
-
* For archived changes: the original archive folder name (e.g. "2026-01-15-my-feature" or
|
|
92
|
-
* "legacy-feature" for non-standard names). Used to build correct archive URLs.
|
|
93
|
-
*/
|
|
94
|
-
archiveFolderName?: string;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* The full parsed structure of an openspec/ directory.
|
|
98
|
-
*/
|
|
99
|
-
interface OpenSpecFolder {
|
|
100
|
-
/** Absolute path to the openspec/ root */
|
|
101
|
-
dir: string;
|
|
102
|
-
/** Canonical capability specs from openspec/specs/ */
|
|
103
|
-
specs: CapabilitySpec[];
|
|
104
|
-
/** Active changes from openspec/changes/ (excluding archive/) */
|
|
105
|
-
changes: Change[];
|
|
106
|
-
/** Archived changes from openspec/changes/archive/ */
|
|
107
|
-
archivedChanges: Change[];
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* A nav item compatible with VitePress `DefaultTheme.NavItem`.
|
|
111
|
-
*/
|
|
112
|
-
interface NavItem {
|
|
113
|
-
text: string;
|
|
114
|
-
link: string;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* A sidebar item compatible with VitePress `DefaultTheme.SidebarItem`.
|
|
118
|
-
*/
|
|
119
|
-
interface SidebarItem {
|
|
120
|
-
text: string;
|
|
121
|
-
link?: string;
|
|
122
|
-
collapsed?: boolean;
|
|
123
|
-
items?: SidebarItem[];
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Synchronously generates all VitePress Markdown pages from the openspec/
|
|
128
|
-
* directory and writes them to disk.
|
|
129
|
-
*
|
|
130
|
-
* Call this at the top of your `docs/.vitepress/config.ts` **before**
|
|
131
|
-
* `defineConfig()` so the files exist when VitePress scans the source
|
|
132
|
-
* directory for routes.
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* ```typescript
|
|
136
|
-
* // docs/.vitepress/config.ts
|
|
137
|
-
* import { defineConfig } from 'vitepress'
|
|
138
|
-
* import path from 'node:path'
|
|
139
|
-
* import { fileURLToPath } from 'node:url'
|
|
140
|
-
* import openspec, { generateOpenSpecPages } from 'vitepress-plugin-openspec'
|
|
141
|
-
*
|
|
142
|
-
* const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
143
|
-
* const specDir = path.resolve(__dirname, '../../openspec')
|
|
144
|
-
*
|
|
145
|
-
* // Generate pages before VitePress scans srcDir for routes
|
|
146
|
-
* generateOpenSpecPages({ specDir, outDir: 'openspec', srcDir: path.resolve(__dirname, '..') })
|
|
147
|
-
*
|
|
148
|
-
* export default defineConfig({ ... })
|
|
149
|
-
* ```
|
|
150
|
-
*/
|
|
151
|
-
declare function generateOpenSpecPages(userOptions?: OpenSpecPluginOptions): void;
|
|
152
|
-
/**
|
|
153
|
-
* VitePress plugin that reads an openspec/ directory and generates structured
|
|
154
|
-
* Markdown documentation pages inside the VitePress source directory.
|
|
155
|
-
*
|
|
156
|
-
* For the pages to be available on the first build (including CI), also call
|
|
157
|
-
* `generateOpenSpecPages()` at the top of your `config.ts` before `defineConfig`.
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* ```typescript
|
|
161
|
-
* // .vitepress/config.ts
|
|
162
|
-
* import { defineConfig } from 'vitepress'
|
|
163
|
-
* import openspec, { generateOpenSpecPages } from 'vitepress-plugin-openspec'
|
|
164
|
-
*
|
|
165
|
-
* generateOpenSpecPages({ specDir, outDir: 'openspec', srcDir: path.resolve(__dirname, '..') })
|
|
166
|
-
*
|
|
167
|
-
* export default defineConfig({
|
|
168
|
-
* vite: { plugins: [openspec({ specDir: './openspec', outDir: 'project-docs' })] },
|
|
169
|
-
* })
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
declare function openspec(userOptions?: OpenSpecPluginOptions): Plugin;
|
|
173
|
-
/**
|
|
174
|
-
* One-call VitePress config helper that wires up the full openspec integration.
|
|
175
|
-
*
|
|
176
|
-
* Calls `generateOpenSpecPages()` synchronously (required before VitePress scans
|
|
177
|
-
* for routes), then merges the openspec Vite plugin, nav entry, and sidebar section
|
|
178
|
-
* into the provided config object.
|
|
179
|
-
*
|
|
180
|
-
* Other Vite plugins go into `vite.plugins` as usual — `withOpenSpec` appends to
|
|
181
|
-
* the array without replacing it:
|
|
182
|
-
*
|
|
183
|
-
* @example
|
|
184
|
-
* ```typescript
|
|
185
|
-
* // docs/.vitepress/config.ts
|
|
186
|
-
* import { defineConfig } from 'vitepress'
|
|
187
|
-
* import { withOpenSpec } from 'vitepress-plugin-openspec'
|
|
188
|
-
*
|
|
189
|
-
* export default defineConfig(
|
|
190
|
-
* withOpenSpec({
|
|
191
|
-
* vite: { plugins: [myOtherPlugin()] }, // other plugins are preserved
|
|
192
|
-
* themeConfig: { nav: [], sidebar: {} },
|
|
193
|
-
* })
|
|
194
|
-
* )
|
|
195
|
-
* ```
|
|
196
|
-
*
|
|
197
|
-
* @param config - Your VitePress `UserConfig` object (same as what `defineConfig` accepts).
|
|
198
|
-
* @param options - OpenSpec options. All fields are optional; defaults match `generateOpenSpecPages`.
|
|
199
|
-
*/
|
|
200
|
-
declare function withOpenSpec<T extends Record<string, unknown>>(config: T, options?: WithOpenSpecOptions): T;
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Returns a VitePress sidebar configuration for the OpenSpec documentation.
|
|
204
|
-
* Includes groups for Specifications, active Changes, and archived Changes.
|
|
205
|
-
*/
|
|
206
|
-
declare function generateOpenSpecSidebar(specDir: string, options?: {
|
|
207
|
-
outDir?: string;
|
|
208
|
-
}): SidebarItem[];
|
|
209
|
-
/**
|
|
210
|
-
* Returns a VitePress nav entry for the OpenSpec documentation section.
|
|
211
|
-
*/
|
|
212
|
-
declare function openspecNav(specDir: string, options?: {
|
|
213
|
-
outDir?: string;
|
|
214
|
-
text?: string;
|
|
215
|
-
}): NavItem | null;
|
|
216
|
-
|
|
217
|
-
export { type CapabilitySpec, type Change, type ChangeArtifact, type NavItem, type OpenSpecFolder, type OpenSpecPluginOptions, type SidebarItem, type WithOpenSpecOptions, openspec as default, generateOpenSpecPages, generateOpenSpecSidebar, openspec, openspecNav, withOpenSpec };
|