@lucasviola/specwiki 1.0.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.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +227 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +226 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/generate.d.ts +5 -0
  8. package/dist/commands/generate.d.ts.map +1 -0
  9. package/dist/commands/generate.js +197 -0
  10. package/dist/commands/generate.js.map +1 -0
  11. package/dist/commands/init.d.ts +5 -0
  12. package/dist/commands/init.d.ts.map +1 -0
  13. package/dist/commands/init.js +91 -0
  14. package/dist/commands/init.js.map +1 -0
  15. package/dist/commands/open.d.ts +8 -0
  16. package/dist/commands/open.d.ts.map +1 -0
  17. package/dist/commands/open.js +150 -0
  18. package/dist/commands/open.js.map +1 -0
  19. package/dist/config/loader.d.ts +20 -0
  20. package/dist/config/loader.d.ts.map +1 -0
  21. package/dist/config/loader.js +143 -0
  22. package/dist/config/loader.js.map +1 -0
  23. package/dist/config/patterns.d.ts +9 -0
  24. package/dist/config/patterns.d.ts.map +1 -0
  25. package/dist/config/patterns.js +159 -0
  26. package/dist/config/patterns.js.map +1 -0
  27. package/dist/core/Logger.d.ts +8 -0
  28. package/dist/core/Logger.d.ts.map +1 -0
  29. package/dist/core/Logger.js +33 -0
  30. package/dist/core/Logger.js.map +1 -0
  31. package/dist/core/paths.d.ts +8 -0
  32. package/dist/core/paths.d.ts.map +1 -0
  33. package/dist/core/paths.js +45 -0
  34. package/dist/core/paths.js.map +1 -0
  35. package/dist/discover/specs.d.ts +11 -0
  36. package/dist/discover/specs.d.ts.map +1 -0
  37. package/dist/discover/specs.js +157 -0
  38. package/dist/discover/specs.js.map +1 -0
  39. package/dist/output/html/assets/highlight.css +101 -0
  40. package/dist/output/html/assets/search.js +368 -0
  41. package/dist/output/html/assets/specwiki.css +905 -0
  42. package/dist/output/html/renderer.d.ts +21 -0
  43. package/dist/output/html/renderer.d.ts.map +1 -0
  44. package/dist/output/html/renderer.js +203 -0
  45. package/dist/output/html/renderer.js.map +1 -0
  46. package/dist/output/html/search-index.d.ts +20 -0
  47. package/dist/output/html/search-index.d.ts.map +1 -0
  48. package/dist/output/html/search-index.js +46 -0
  49. package/dist/output/html/search-index.js.map +1 -0
  50. package/dist/output/html/templates/article.mustache +85 -0
  51. package/dist/output/html/templates/index.mustache +80 -0
  52. package/dist/output/html/templates/layout.mustache +205 -0
  53. package/dist/output/llms.d.ts +4 -0
  54. package/dist/output/llms.d.ts.map +1 -0
  55. package/dist/output/llms.js +44 -0
  56. package/dist/output/llms.js.map +1 -0
  57. package/dist/output/readme-index.d.ts +17 -0
  58. package/dist/output/readme-index.d.ts.map +1 -0
  59. package/dist/output/readme-index.js +71 -0
  60. package/dist/output/readme-index.js.map +1 -0
  61. package/dist/output/wiki.d.ts +11 -0
  62. package/dist/output/wiki.d.ts.map +1 -0
  63. package/dist/output/wiki.js +400 -0
  64. package/dist/output/wiki.js.map +1 -0
  65. package/dist/parse/markdown.d.ts +6 -0
  66. package/dist/parse/markdown.d.ts.map +1 -0
  67. package/dist/parse/markdown.js +225 -0
  68. package/dist/parse/markdown.js.map +1 -0
  69. package/dist/types.d.ts +96 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +2 -0
  72. package/dist/types.js.map +1 -0
  73. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 specwiki contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,227 @@
1
+ <div align="center">
2
+
3
+ <img src="docs/brand/specwiki-wordmark-light.svg" alt="[[specwiki]]" width="220">
4
+
5
+ <br><br>
6
+
7
+ [![CI](https://github.com/lucasviola/specwiki/actions/workflows/ci.yml/badge.svg)](https://github.com/lucasviola/specwiki/actions/workflows/ci.yml)
8
+ [![version](https://img.shields.io/badge/version-0.1.0-blue)](package.json)
9
+ [![node](https://img.shields.io/badge/node-%3E%3D20-339933?logo=node.js&logoColor=white)](package.json)
10
+ [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
11
+
12
+ </div>
13
+
14
+ Transform AI specs into structured wiki-like documentation.
15
+
16
+ **One command → categorized wiki from scattered agent specs.**
17
+
18
+ [[specwiki]] Your AI live documentation. A library that discovers AI agent instructions, spec-driven development artifacts, and general markdown files scattered across a repository and synthesizes them into a browsable wiki.
19
+
20
+ **Requires Node.js 20+.** MIT licensed.
21
+
22
+ ## What it finds
23
+
24
+ Out of the box, [[specwiki]] discovers specs from:
25
+
26
+ | Source | Patterns |
27
+ | ---------------- | --------------------------------------------------- |
28
+ | Root agent files | `AGENTS.md`, `SPEC.md`, `CLAUDE.md`, `GEMINI.md` |
29
+ | Cursor | `.cursor/rules/**`, `.cursor/skills/**/SKILL.md` |
30
+ | Spec frameworks | `specs/**`, `openspec/**`, `.kiro/specs/**` |
31
+ | Docs & plans | `docs/specs/**`, `docs/plans/**`, `requirements/**` |
32
+ | GitHub Copilot | `.github/copilot-instructions.md` |
33
+ | Monorepo agents | `**/AGENTS.md` (nested packages) |
34
+ | BMAD output | `_bmad-output/**/*.md` |
35
+ | Agent skills | `.agents/skills/**/SKILL.md` |
36
+ | README files | `**/README.md` (standalone wiki pages) |
37
+ | All markdown | `**/*.{md,mdc}` (any `.md` / `.mdc` in the project) |
38
+
39
+ Ignored directories: `node_modules`, `dist`, `wiki`, `.specwiki`, `.git`, `coverage`, `.venv`, `vendor`.
40
+
41
+ ## Install
42
+
43
+ ### For users
44
+
45
+ ```bash
46
+ # Try without installing
47
+ npx @lucasviola/specwiki generate && npx @lucasviola/specwiki open
48
+
49
+ # Or install globally (then use the `specwiki` command)
50
+ npm install -g @lucasviola/specwiki
51
+ ```
52
+
53
+ #### Quick start
54
+
55
+ ```bash
56
+ npm run build
57
+ npm link
58
+ specwiki init && specwiki generate && specwiki open
59
+ ```
60
+
61
+ ### For contributors
62
+
63
+ Clone this repo, then:
64
+
65
+ ```bash
66
+ npm install
67
+ npm run build
68
+ npm run setup-hooks # optional: install git hooks
69
+ npm link # optional: use `specwiki` globally from source
70
+ ```
71
+
72
+ ### For maintainers (npm publish prep)
73
+
74
+ Before publishing to npm, run the local package verification and quality gate:
75
+
76
+ ```bash
77
+ npm run verify-package # pack tarball, clean-install, run specwiki --help
78
+ npm run prepublishOnly # full quality gate (also runs automatically on npm publish)
79
+ ```
80
+
81
+ **Publish to npm** (maintainer only, requires `npm login`):
82
+
83
+ ```bash
84
+ # Preview what npm would upload (runs verify-package + prepublishOnly + dry-run publish)
85
+ npm run publish:package -- --dry-run
86
+
87
+ # Publish the version in package.json
88
+ npm run publish:package -- --confirm
89
+ ```
90
+
91
+ Publishing to the npm registry is an explicit maintainer action after these checks pass. Requires **Node.js 20+** and npm maintainer access to the `@lucasviola/specwiki` package. This repository does not automate registry credentials or release versioning.
92
+
93
+ ## Usage
94
+
95
+ Use `npx @lucasviola/specwiki …` without a global install, or `specwiki …` after `npm install -g @lucasviola/specwiki`.
96
+
97
+ ```bash
98
+ # List spec files found in the current project
99
+ npx @lucasviola/specwiki list
100
+
101
+ # Generate wiki documentation
102
+ npx @lucasviola/specwiki generate
103
+
104
+ # Scan a different project
105
+ npx @lucasviola/specwiki generate --project /path/to/repo
106
+
107
+ # Custom output directory (must stay inside --project)
108
+ npx @lucasviola/specwiki generate --output .specwiki
109
+
110
+ # Verbose mode
111
+ npx @lucasviola/specwiki generate --verbose
112
+
113
+ # Machine-readable discovery results for scripts and AI agents
114
+ npx @lucasviola/specwiki list --json
115
+
116
+ # Machine-readable generation summary (stdout is one JSON document)
117
+ npx @lucasviola/specwiki generate --json
118
+
119
+ # Generate an llms.txt manifest grouped by wiki category
120
+ npx @lucasviola/specwiki generate --emit-llms-txt
121
+
122
+ # Keep JSON stdout clean while sending verbose diagnostics to stderr
123
+ npx @lucasviola/specwiki list --json --verbose
124
+
125
+ # Open the HTML wiki in your default browser (run generate first)
126
+ npx @lucasviola/specwiki open
127
+
128
+ # Open a wiki written to a custom output directory
129
+ npx @lucasviola/specwiki open --output .specwiki
130
+
131
+ # Open a wiki in a different project
132
+ npx @lucasviola/specwiki open --project /path/to/repo
133
+ ```
134
+
135
+ `specwiki open` resolves `{project}/{output}/html/index.html` (same `--project` and `--output` defaults as `generate`) and launches it with your OS default browser. Both commands require `--output` to stay within `--project` (symlinks that escape the project are rejected). If the wiki has not been generated yet, it exits with a message suggesting you run `specwiki generate` first.
136
+
137
+ ### JSON output
138
+
139
+ Use `--json` with `list` or `generate` when another program needs to consume the result.
140
+ `list --json` returns discovered files grouped by category; `generate --json` returns the
141
+ generated page count, resolved output directory, and page metadata. The JSON result is the
142
+ only CLI output on stdout. With `--verbose`, structured diagnostics including `output.json`
143
+ are written to stderr.
144
+
145
+ ### llms.txt export
146
+
147
+ Use `generate --emit-llms-txt` to add `llms.txt` to the generated wiki root. The
148
+ opt-in manifest starts with a project summary, groups every generated page by category,
149
+ and links to its local Markdown wiki page with its description when available.
150
+
151
+ ## Output
152
+
153
+ Running `specwiki generate` creates:
154
+
155
+ ```
156
+ wiki/
157
+ ├── index.md # Landing page with categorized links
158
+ ├── llms.txt # Optional AI-oriented manifest (--emit-llms-txt)
159
+ ├── agents.md # One page per discovered spec
160
+ ├── cursor-rules-*.md
161
+ └── html/
162
+ ├── index.html # Browsable HTML version
163
+ └── *.html
164
+ ```
165
+
166
+ Each wiki page includes:
167
+
168
+ - Title and source file path
169
+ - Auto-generated table of contents from headings
170
+ - Full spec content, preserved as markdown
171
+
172
+ ## Tech stack
173
+
174
+ [[specwiki]] is a Node.js CLI written in **TypeScript**. It runs on **Node.js 20+** with no runtime beyond npm dependencies. It is supposed to be fast, deterministic and reliable.
175
+
176
+ | Layer | Libraries |
177
+ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
178
+ | CLI | [Commander](https://github.com/tj/commander.js), [chalk](https://github.com/chalk/chalk) |
179
+ | Discovery | [fast-glob](https://github.com/mrmlnc/fast-glob) |
180
+ | Parsing | [gray-matter](https://github.com/jonschlinkert/gray-matter) (frontmatter), [marked](https://marked.js.org/) (GFM markdown) |
181
+ | HTML wiki | [Mustache](https://mustache.github.io/) templates, [highlight.js](https://highlightjs.org/) (code blocks), [lunr](https://lunrjs.com/) (client-side search), [Wikimedia UI Base](https://www.npmjs.com/package/wikimedia-ui-base) design tokens |
182
+
183
+ Generated HTML is **self-contained** — bundled CSS/JS, system fonts only, and `file://`-safe output so you can open `wiki/html/` locally without a server or CDN.
184
+
185
+ Contributor tooling: **Vitest** (tests + coverage), **ESLint**, **Prettier**, **tsx** (dev runner).
186
+
187
+ ## Security
188
+
189
+ [[specwiki]] is a local CLI — it does not open network ports or run code on `npm install`. Treat these boundaries as part of the threat model:
190
+
191
+ ### Trusted projects only
192
+
193
+ Run `specwiki` only on repositories you trust. The tool reads markdown from your project and writes a wiki under `--output` inside `--project`.
194
+
195
+ - **`specwiki.config.js` executes arbitrary Node.js** when present. A malicious config runs with your user privileges. Prefer `specwiki.config.json` when you do not need programmatic patterns.
196
+ - **Spec markdown is rendered as HTML** for the wiki skin. Raw HTML in `.md` / `.mdc` files is passed through to generated pages (trusted-local-content model). Opening `wiki/html/` in a browser can run scripts embedded in spec files.
197
+ - **`specwiki open` launches a local file** in your default browser via `open` / `xdg-open` / `cmd start` — no shell interpolation of paths.
198
+
199
+ ### Path safety
200
+
201
+ - **`--output` must stay within `--project`** for both `generate` and `open`. Symlinked output directories that resolve outside the project are rejected.
202
+ - **Discovery patterns cannot target parent directories** (`..` and absolute paths are rejected).
203
+ - **Wiki file writes are confined** to the resolved output directory; slug-based path traversal is blocked.
204
+ - **Config files must live in the project root** and cannot escape via symlinks.
205
+
206
+ ### npm package surface
207
+
208
+ - The published tarball includes only `dist/`, `README.md`, and `LICENSE` (verified by `npm run verify-package`).
209
+ - No `postinstall` or `prepare` scripts run on consumer installs.
210
+ - `prepublishOnly` runs the full test/lint/build quality gate before publish.
211
+
212
+ Report security issues privately to the maintainer before opening a public issue.
213
+
214
+ ## Development
215
+
216
+ ```bash
217
+ npm run dev list
218
+ npm run dev generate -- --verbose
219
+ npm run dev open -- --project tests/fixtures/sample-project --output wiki
220
+ npm run build
221
+ npm run typecheck
222
+ npm test
223
+ ```
224
+
225
+ ## License
226
+
227
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env node
2
+ import { Command, CommanderError, InvalidArgumentError } from "commander";
3
+ import path from "node:path";
4
+ import { generateWiki, isCliErrorLogged, listSpecs, } from "./commands/generate.js";
5
+ import { getInitExitCode, initConfig, isInitErrorLogged, } from "./commands/init.js";
6
+ import { isOpenErrorLogged, openWiki } from "./commands/open.js";
7
+ import { parsePatternList } from "./config/patterns.js";
8
+ import { ConfigError, resolveEffectivePatterns } from "./config/loader.js";
9
+ import { log } from "./core/Logger.js";
10
+ const USAGE_ERROR_CODES = new Set([
11
+ "commander.unknownOption",
12
+ "commander.unknownCommand",
13
+ "commander.missingArgument",
14
+ "commander.optionMissingArgument",
15
+ "commander.missingMandatoryOptionValue",
16
+ "commander.conflictingOption",
17
+ "commander.excessArguments",
18
+ "commander.invalidArgument",
19
+ ]);
20
+ let patternsValidationMessage;
21
+ function resolveCommandForUsageError() {
22
+ const entryIndex = process.argv.findIndex((arg) => arg.endsWith("cli.ts") ||
23
+ arg.endsWith("cli.js") ||
24
+ arg.endsWith("/specwiki") ||
25
+ arg === "specwiki");
26
+ const args = entryIndex >= 0
27
+ ? process.argv.slice(entryIndex + 1)
28
+ : process.argv.slice(2);
29
+ const subcommand = args.find((arg) => !arg.startsWith("-"));
30
+ return subcommand ?? "specwiki";
31
+ }
32
+ function handleCommanderError(err) {
33
+ if (USAGE_ERROR_CODES.has(err.code)) {
34
+ if (err.code === "commander.optionMissingArgument" &&
35
+ err.message.includes("--patterns")) {
36
+ log.error("config.error", {
37
+ message: "Patterns option requires a comma-separated glob list",
38
+ });
39
+ }
40
+ const message = err.code === "commander.invalidArgument" && patternsValidationMessage
41
+ ? `Invalid --patterns value: ${patternsValidationMessage}`
42
+ : err.message;
43
+ patternsValidationMessage = undefined;
44
+ log.error("cli.error", {
45
+ command: resolveCommandForUsageError(),
46
+ message,
47
+ });
48
+ process.exit(2);
49
+ }
50
+ process.exit(err.exitCode ?? 1);
51
+ }
52
+ function parsePatternsOption(value) {
53
+ try {
54
+ return parsePatternList(value);
55
+ }
56
+ catch (err) {
57
+ const message = err instanceof Error ? err.message : "Invalid patterns";
58
+ patternsValidationMessage = message;
59
+ log.error("config.error", { message });
60
+ throw new InvalidArgumentError(message);
61
+ }
62
+ }
63
+ function emitPatternsOverride(patterns) {
64
+ if (patterns) {
65
+ log.info("config.patterns-override", { patternCount: patterns.length });
66
+ }
67
+ }
68
+ async function resolveCommandPatterns(command, projectRoot, cliPatterns, verbose) {
69
+ if (cliPatterns) {
70
+ emitPatternsOverride(cliPatterns);
71
+ return cliPatterns;
72
+ }
73
+ try {
74
+ const resolved = await resolveEffectivePatterns({
75
+ projectRoot,
76
+ cliPatterns,
77
+ });
78
+ if (resolved.configSource && verbose) {
79
+ log.info("config.load", { sourcePath: resolved.configSource });
80
+ }
81
+ return resolved.patterns;
82
+ }
83
+ catch (err) {
84
+ const message = err instanceof ConfigError
85
+ ? err.message
86
+ : err instanceof Error
87
+ ? err.message
88
+ : "Invalid configuration";
89
+ log.error("config.error", { message });
90
+ log.error("cli.error", { command, message });
91
+ process.exit(2);
92
+ }
93
+ }
94
+ const program = new Command();
95
+ program.exitOverride();
96
+ program
97
+ .name("specwiki")
98
+ .description("Transform AI specs into structured wiki-like documentation")
99
+ .version("0.1.0");
100
+ program
101
+ .command("generate")
102
+ .description("Discover specs and generate wiki documentation")
103
+ .option("-p, --project <path>", "Project root to scan", process.cwd())
104
+ .option("-o, --output <dir>", "Output directory (relative to project)", "wiki")
105
+ .option("-v, --verbose", "Show detailed output")
106
+ .option("--patterns <globs>", "Comma-separated glob patterns (replaces defaults)", parsePatternsOption)
107
+ .option("--no-search", "Skip client-side search index and JS")
108
+ .option("--json", "Print a machine-readable JSON result")
109
+ .option("--emit-llms-txt", "Write an llms.txt manifest alongside the wiki")
110
+ .action(async (opts) => {
111
+ try {
112
+ log.setVerbose(Boolean(opts.verbose));
113
+ const projectRoot = path.resolve(opts.project);
114
+ const patterns = await resolveCommandPatterns("generate", projectRoot, opts.patterns, Boolean(opts.verbose));
115
+ await generateWiki({
116
+ projectRoot,
117
+ outputDir: opts.output,
118
+ patterns,
119
+ verbose: opts.verbose,
120
+ noSearch: opts.search === false,
121
+ json: opts.json,
122
+ emitLlmsTxt: opts.emitLlmsTxt,
123
+ });
124
+ }
125
+ catch (err) {
126
+ if (!isCliErrorLogged(err)) {
127
+ log.error("cli.error", {
128
+ command: "generate",
129
+ message: err instanceof Error ? err.message : String(err),
130
+ });
131
+ }
132
+ process.exit(1);
133
+ }
134
+ });
135
+ program
136
+ .command("list")
137
+ .description("List discovered spec files without generating")
138
+ .option("-p, --project <path>", "Project root to scan", process.cwd())
139
+ .option("-v, --verbose", "Show detailed discover diagnostics on stderr")
140
+ .option("--json", "Print a machine-readable JSON result")
141
+ .option("--patterns <globs>", "Comma-separated glob patterns (replaces defaults)", parsePatternsOption)
142
+ .action(async (opts) => {
143
+ try {
144
+ log.setVerbose(Boolean(opts.verbose));
145
+ const projectRoot = path.resolve(opts.project);
146
+ const patterns = await resolveCommandPatterns("list", projectRoot, opts.patterns, Boolean(opts.verbose));
147
+ await listSpecs({
148
+ projectRoot,
149
+ outputDir: "wiki",
150
+ patterns,
151
+ verbose: opts.verbose,
152
+ json: opts.json,
153
+ });
154
+ }
155
+ catch (err) {
156
+ if (!isCliErrorLogged(err)) {
157
+ log.error("cli.error", {
158
+ command: "list",
159
+ message: err instanceof Error ? err.message : String(err),
160
+ });
161
+ }
162
+ process.exit(1);
163
+ }
164
+ });
165
+ program
166
+ .command("init")
167
+ .description("Scaffold specwiki.config.json with default discovery patterns")
168
+ .option("-p, --project <path>", "Project root", process.cwd())
169
+ .option("-f, --force", "Overwrite specwiki.config.json when it exists (never overwrites .js config)")
170
+ .option("-v, --verbose", "Show detailed output")
171
+ .action(async (opts) => {
172
+ try {
173
+ log.setVerbose(Boolean(opts.verbose));
174
+ const projectRoot = path.resolve(opts.project);
175
+ await initConfig({
176
+ projectRoot,
177
+ force: Boolean(opts.force),
178
+ verbose: opts.verbose,
179
+ });
180
+ }
181
+ catch (err) {
182
+ if (!isInitErrorLogged(err) && !isCliErrorLogged(err)) {
183
+ log.error("cli.error", {
184
+ command: "init",
185
+ message: err instanceof Error ? err.message : String(err),
186
+ });
187
+ }
188
+ process.exit(getInitExitCode(err));
189
+ }
190
+ });
191
+ program
192
+ .command("open")
193
+ .description("Open the generated HTML wiki in the default browser")
194
+ .option("-p, --project <path>", "Project root", process.cwd())
195
+ .option("-o, --output <dir>", "Output directory (relative to project)", "wiki")
196
+ .option("-v, --verbose", "Show detailed output")
197
+ .action(async (opts) => {
198
+ try {
199
+ log.setVerbose(Boolean(opts.verbose));
200
+ const projectRoot = path.resolve(opts.project);
201
+ await openWiki({
202
+ projectRoot,
203
+ outputDir: opts.output,
204
+ verbose: opts.verbose,
205
+ });
206
+ }
207
+ catch (err) {
208
+ if (!isOpenErrorLogged(err) && !isCliErrorLogged(err)) {
209
+ log.error("cli.error", {
210
+ command: "open",
211
+ message: err instanceof Error ? err.message : String(err),
212
+ });
213
+ }
214
+ process.exit(1);
215
+ }
216
+ });
217
+ try {
218
+ program.parse();
219
+ }
220
+ catch (err) {
221
+ if (err instanceof CommanderError) {
222
+ handleCommanderError(err);
223
+ }
224
+ throw err;
225
+ }
226
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { GenerateOptions } from "../types.js";
2
+ export declare function generateWiki(options: GenerateOptions): Promise<void>;
3
+ export declare function listSpecs(options: GenerateOptions): Promise<void>;
4
+ export declare function isCliErrorLogged(err: unknown): boolean;
5
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,aAAa,CAAC;AAoGrB,wBAAsB,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAsF1E;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDvE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEtD"}