@openpkg-ts/cli 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Ryan Waits
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 CHANGED
@@ -32,6 +32,16 @@ bunx @openpkg-ts/cli diff old.json new.json
32
32
 
33
33
  For programmatic use, richer options, and framework integrations (search indexes, nav trees), use `@openpkg-ts/sdk` directly.
34
34
 
35
+ ## Agent-assisted docs generation
36
+
37
+ The package ships an agent skill that scaffolds framework-ready API reference pages (Fumadocs, Docusaurus, or plain Markdown) — framework detection, page-per-export MDX with navigation, search indexes, and output verification. Copy it into your project's skills directory:
38
+
39
+ ```bash
40
+ cp -r node_modules/@openpkg-ts/cli/skills/generate-docs .claude/skills/
41
+ ```
42
+
43
+ Then ask your agent to "generate API docs" (or run `/generate-docs` in Claude Code).
44
+
35
45
  > Versions ≤ 0.6.4 are broken (unresolvable dependency) and deprecated. Use 0.7.0+.
36
46
 
37
47
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/cli",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "CLI for OpenPkg - extract TypeScript API specs and generate docs",
5
5
  "keywords": [
6
6
  "openpkg",
@@ -22,7 +22,8 @@
22
22
  "openpkg": "./dist/index.js"
23
23
  },
24
24
  "files": [
25
- "dist"
25
+ "dist",
26
+ "skills"
26
27
  ],
27
28
  "scripts": {
28
29
  "build": "bunup",
@@ -30,10 +31,11 @@
30
31
  "lint": "biome check src/",
31
32
  "lint:fix": "biome check --write src/",
32
33
  "format": "biome format --write src/",
34
+ "typecheck": "tsc --noEmit -p .",
33
35
  "test": "bun test"
34
36
  },
35
37
  "dependencies": {
36
- "@openpkg-ts/sdk": "^0.37.1"
38
+ "@openpkg-ts/sdk": "^0.38.0"
37
39
  },
38
40
  "devDependencies": {
39
41
  "@types/bun": "latest",
@@ -0,0 +1,200 @@
1
+ ---
2
+ name: generate-docs
3
+ description: >
4
+ Generate framework-ready API reference docs (Fumadocs, Docusaurus, or plain
5
+ Markdown) for a TypeScript package using OpenPkg. Detects the target docs
6
+ framework, extracts an OpenPkg spec, writes page-per-export MDX/MD with
7
+ navigation (meta.json / sidebars) and optional search indexes, then verifies
8
+ output. Use when the user asks to "generate API docs", "generate docs from
9
+ my TypeScript exports", "add an API reference to my docs site", "scaffold
10
+ fumadocs/docusaurus API pages", "create reference docs with openpkg", or
11
+ runs "/generate-docs". Optional args: entry file, framework
12
+ (fumadocs|docusaurus|markdown), output dir.
13
+ ---
14
+
15
+ # Generate API Reference Docs (OpenPkg)
16
+
17
+ Orchestrate `@openpkg-ts/cli` and `@openpkg-ts/sdk` to produce API reference pages for the consumer's docs framework. You orchestrate; the SDK renders. Do NOT hand-write per-export markdown — always render via the SDK so regeneration stays deterministic.
18
+
19
+ ## 0. Prerequisites
20
+
21
+ Check `package.json` `packageManager`; prefer bun, fall back to the project's manager. Ensure tooling is available:
22
+
23
+ ```bash
24
+ bunx @openpkg-ts/cli --help # thin CLI: spec, docs, list, diff
25
+ ```
26
+
27
+ For the generation script you need the SDK as a dev dep in the consumer project:
28
+
29
+ ```bash
30
+ bun add -d @openpkg-ts/sdk
31
+ ```
32
+
33
+ ## 1. Detect entry point
34
+
35
+ If not given, in order: `package.json` `exports["."]` (source, not dist — check `src/index.ts` first), `main`/`module` mapped back to `src/`, else `src/index.ts`. Confirm it resolves by listing exports:
36
+
37
+ ```bash
38
+ bunx @openpkg-ts/cli list src/index.ts
39
+ ```
40
+
41
+ If this errors, stop and fix the entry (missing tsconfig path aliases are the usual cause). Note the export count — verify against it in step 6.
42
+
43
+ ## 2. Detect docs framework
44
+
45
+ If not given, inspect the repo (also check sibling `apps/docs` or `docs/` workspaces in monorepos):
46
+
47
+ | Signal | Framework |
48
+ |---|---|
49
+ | `fumadocs-core` / `fumadocs-ui` in deps; `content/docs/` dir; `source.config.ts` | fumadocs |
50
+ | `@docusaurus/core` in deps; `docusaurus.config.*`; `sidebars.*` | docusaurus |
51
+ | `nextra`, `vitepress`, `mintlify` (`docs.json`/`mint.json`) | markdown (plain .md/.mdx pages; wire nav per that framework's convention manually) |
52
+ | none of the above | markdown |
53
+
54
+ Tell the user what you detected before generating. If they just want a single reference file, the CLI alone suffices:
55
+
56
+ ```bash
57
+ bunx @openpkg-ts/cli docs src/index.ts -f md -o docs/API.md
58
+ ```
59
+
60
+ ## 3. Extract the spec
61
+
62
+ Always materialize the spec as a committed file — it is the regeneration input and the `diff` baseline:
63
+
64
+ ```bash
65
+ bunx @openpkg-ts/cli spec src/index.ts -o openpkg.json
66
+ ```
67
+
68
+ Warnings from diagnostics are fine; errors mean the spec is incomplete — surface them.
69
+
70
+ ## 4. Generate pages + navigation
71
+
72
+ Write a small script into the consumer repo (e.g. `scripts/generate-api-docs.ts`) so regeneration is one command. Adapt paths; keep the slugify identical everywhere — the SDK's nav/search default is `name.toLowerCase().replace(/[^a-z0-9]+/g, '-')`, and filenames MUST match it or nav links 404.
73
+
74
+ ### Fumadocs
75
+
76
+ Layout (page-per-export, grouped by kind — small APIs can skip subdirs and use one flat dir):
77
+
78
+ ```
79
+ content/docs/api/
80
+ index.mdx # package overview
81
+ meta.json # root: index + kind folders
82
+ functions/ … # one .mdx per export + meta.json per kind dir
83
+ classes/ … interfaces/ … types/ … variables/ …
84
+ ```
85
+
86
+ ```ts
87
+ // scripts/generate-api-docs.ts
88
+ import fs from 'node:fs';
89
+ import path from 'node:path';
90
+ import { createDocs } from '@openpkg-ts/sdk';
91
+
92
+ const OUT = 'content/docs/api';
93
+ const slug = (n: string) => n.toLowerCase().replace(/[^a-z0-9]+/g, '-');
94
+ const KIND_DIRS: Record<string, string> = {
95
+ function: 'functions', class: 'classes', interface: 'interfaces',
96
+ type: 'types', enum: 'enums', variable: 'variables',
97
+ };
98
+
99
+ const docs = createDocs('./openpkg.json'); // throws on invalid spec
100
+ fs.rmSync(OUT, { recursive: true, force: true });
101
+ fs.mkdirSync(OUT, { recursive: true });
102
+
103
+ // index page
104
+ fs.writeFileSync(path.join(OUT, 'index.mdx'),
105
+ `---\ntitle: ${docs.spec.meta.name}\ndescription: API reference\n---\n\n${docs.spec.meta.description ?? ''}\n`);
106
+
107
+ const grouped = docs.groupByKind();
108
+ const rootPages: string[] = ['index'];
109
+
110
+ for (const [kind, exps] of Object.entries(grouped)) {
111
+ if (!exps.length) continue;
112
+ const dir = KIND_DIRS[kind] ?? `${kind}s`;
113
+ fs.mkdirSync(path.join(OUT, dir), { recursive: true });
114
+ const sorted = [...exps].sort((a, b) => a.name.localeCompare(b.name));
115
+ for (const exp of sorted) {
116
+ const md = docs.toMarkdown({ export: exp.id, frontmatter: true, codeSignatures: true });
117
+ fs.writeFileSync(path.join(OUT, dir, `${slug(exp.name)}.mdx`), md);
118
+ }
119
+ fs.writeFileSync(path.join(OUT, dir, 'meta.json'), JSON.stringify({
120
+ title: dir[0].toUpperCase() + dir.slice(1),
121
+ pages: sorted.map((e) => slug(e.name)),
122
+ defaultOpen: false,
123
+ }, null, 2));
124
+ rootPages.push(`...${dir}`);
125
+ }
126
+
127
+ fs.writeFileSync(path.join(OUT, 'meta.json'), JSON.stringify({
128
+ title: `${docs.spec.meta.name} API`, pages: rootPages, defaultOpen: true,
129
+ }, null, 2));
130
+ ```
131
+
132
+ Run: `bun scripts/generate-api-docs.ts`. For a flat single-dir layout instead, write all pages into `OUT` and use `toFumadocsMetaJSON(docs.spec, { groupBy: 'kind' })` from the SDK for `meta.json` — but verify the rendered sidebar, since fumadocs meta grouping conventions vary by version.
133
+
134
+ ### Docusaurus
135
+
136
+ Same script shape; write `.md` into `docs/api/<slug>.md` (no kind subdirs unless the site is large), then generate the sidebar:
137
+
138
+ ```ts
139
+ import { createDocs, toDocusaurusSidebarJS } from '@openpkg-ts/sdk';
140
+ const docs = createDocs('./openpkg.json');
141
+ // pages: docs.toMarkdown({ export: exp.id, frontmatter: true, codeSignatures: true }) per export
142
+ fs.writeFileSync('sidebars.api.js', toDocusaurusSidebarJS(docs.spec, { basePath: 'api' }));
143
+ ```
144
+
145
+ Do NOT overwrite the consumer's existing `sidebars.js` — write the API sidebar to its own file and merge/import it into their config (`apiSidebar: require('./sidebars.api.js')`). `basePath` must match the docs folder route.
146
+
147
+ ### Plain Markdown (no framework)
148
+
149
+ ```bash
150
+ bunx @openpkg-ts/cli docs src/index.ts -f md -o docs/API.md
151
+ ```
152
+
153
+ or page-per-export into `docs/api/` with the script above (`.md` extension, skip meta files) plus a `docs/api/README.md` index linking each page.
154
+
155
+ ## 5. Search indexes (optional — ask the user)
156
+
157
+ Only if the site has (or wants) search:
158
+
159
+ ```ts
160
+ import { createDocs } from '@openpkg-ts/sdk';
161
+ const docs = createDocs('./openpkg.json');
162
+
163
+ // Pagefind (self-hosted search)
164
+ fs.writeFileSync('public/api-pagefind.json',
165
+ JSON.stringify(docs.toPagefindRecords({ baseUrl: '/docs/api' }), null, 2));
166
+
167
+ // Algolia (upload via their API/CLI)
168
+ fs.writeFileSync('algolia-records.json',
169
+ JSON.stringify(docs.toAlgoliaRecords({ baseUrl: '/docs/api' }), null, 2));
170
+
171
+ // Generic index (roll your own client-side search)
172
+ fs.writeFileSync('public/api-search.json',
173
+ JSON.stringify(docs.toSearchIndex({ baseUrl: '/docs/api' }), null, 2));
174
+ ```
175
+
176
+ `baseUrl` must match the deployed route prefix of the generated pages. Fumadocs and docusaurus both index rendered pages themselves by default — skip this step unless they're wiring an external index.
177
+
178
+ ## 6. Verify
179
+
180
+ Run every check; report failures instead of declaring success:
181
+
182
+ 1. **Coverage**: page count equals the export count from step 1 (`bunx @openpkg-ts/cli list src/index.ts --json` array length, minus intentionally filtered exports).
183
+ 2. **Frontmatter**: spot-check 2-3 files — `---` block with `title:` present, first heading renders the export name, signature is inside a code fence.
184
+ 3. **Nav ↔ files**: every slug in `meta.json` / `sidebars.api.js` has a matching file, and vice versa. A mismatch means slugify drift — fix the script, not the files.
185
+ 4. **MDX compiles** (fumadocs/docusaurus): run the docs site build. Generic types like `Promise<T>` in prose can break MDX — if it fails, find the offending page, confirm `codeSignatures: true` was used, and escape or fence stray angle brackets.
186
+ 5. **Links resolve**: check a couple of nav hrefs against the dev server — `basePath` mismatches are the common failure.
187
+
188
+ ## 7. Leave it regenerable
189
+
190
+ - Commit `openpkg.json`, `scripts/generate-api-docs.ts`, and generated pages.
191
+ - Add to consumer `package.json`: `"docs:api": "openpkg spec src/index.ts -o openpkg.json && bun scripts/generate-api-docs.ts"`.
192
+ - On future API changes, semver guidance is one command: `bunx @openpkg-ts/cli diff openpkg.old.json openpkg.json` (exit code 2 = breaking).
193
+ - Warn the user that the generated dir is wiped on regeneration — hand-written docs belong outside it.
194
+
195
+ ## Rules
196
+
197
+ - Never edit generated pages by hand to fix content — fix the source JSDoc and regenerate.
198
+ - Never overwrite user-owned config (`sidebars.js`, `source.config.ts`, `meta.json` outside the API dir); write alongside and show the merge.
199
+ - Ask before adding search indexes or deleting an existing docs dir.
200
+ - Keep all rendering in the SDK; if the SDK output is wrong, report it upstream rather than post-processing.