@openpkg-ts/cli 0.6.4 → 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
@@ -1,233 +1,48 @@
1
1
  # @openpkg-ts/cli
2
2
 
3
- CLI for TypeScript API extraction and documentation generation.
3
+ CLI for [OpenPkg](https://github.com/ryanwaits/openpkg-ts) — extract TypeScript API specs and generate docs. Thin wrapper over [@openpkg-ts/sdk](https://www.npmjs.com/package/@openpkg-ts/sdk).
4
4
 
5
- ## Install
5
+ ## Usage
6
6
 
7
7
  ```bash
8
- npm install -g @openpkg-ts/cli
9
- # or use directly
10
- npx @openpkg-ts/cli <command>
11
- ```
12
-
13
- ## Command Structure
14
-
15
- Commands organized under `openpkg spec` and `openpkg docs`. Legacy commands work as aliases.
16
-
17
- ```bash
18
- openpkg spec snapshot ./src/index.ts -o spec.json
19
- openpkg spec validate spec.json
20
-
21
- openpkg docs init
22
- openpkg docs generate spec.json -o ./docs
23
- openpkg docs add function-section
24
- ```
25
-
26
- ---
27
-
28
- ## Spec Commands
29
-
30
- ### list
31
-
32
- ```bash
33
- openpkg list src/index.ts
34
- ```
8
+ # Extract an OpenPkg spec
9
+ bunx @openpkg-ts/cli spec src/index.ts -o openpkg.json
35
10
 
36
- Output: JSON array of `{ name, kind, file, line, description }`
11
+ # Generate markdown docs (from source or an existing spec)
12
+ bunx @openpkg-ts/cli docs src/index.ts -o docs/api.md
13
+ bunx @openpkg-ts/cli docs openpkg.json -f html -o docs/api.html
37
14
 
38
- ### get
15
+ # List exports
16
+ bunx @openpkg-ts/cli list src/index.ts
39
17
 
40
- ```bash
41
- openpkg get src/index.ts createClient
18
+ # Diff two specs, get a semver recommendation
19
+ bunx @openpkg-ts/cli diff old.json new.json
42
20
  ```
43
21
 
44
- Output: JSON with `{ export, types }` - full spec for the export plus referenced types.
22
+ ## Commands
45
23
 
46
- ### spec snapshot
24
+ | Command | Description |
25
+ |---------|-------------|
26
+ | `spec <entry.ts>` | Extract an OpenPkg spec from a TypeScript entry point |
27
+ | `docs <entry.ts \| spec.json>` | Generate docs (`-f md\|html\|json`) |
28
+ | `list <entry.ts>` | List exports with kind and location (`--json`) |
29
+ | `diff <old.json> <new.json>` | Compare specs; exits 2 if breaking changes |
47
30
 
48
- ```bash
49
- openpkg spec snapshot src/index.ts -o openpkg.json
50
- openpkg spec snapshot src/index.ts -o - # stdout
51
- openpkg spec snapshot src/index.ts --max-depth 4 --runtime --verify
52
- openpkg spec snapshot src/index.ts --only "use*,create*" --ignore "*Internal"
53
- ```
31
+ `-o, --output` writes to a file instead of stdout.
54
32
 
55
- | Flag | Description |
56
- |------|-------------|
57
- | `-o, --output <file>` | Output file (default: openpkg.json, `-` for stdout) |
58
- | `--max-depth <n>` | Max type depth (default: 4) |
59
- | `--skip-resolve` | Skip external type resolution |
60
- | `--runtime` | Enable Standard Schema runtime extraction (Zod, Valibot) |
61
- | `--only <exports>` | Filter exports (comma-separated, wildcards) |
62
- | `--ignore <exports>` | Ignore exports (comma-separated, wildcards) |
63
- | `--verify` | Exit 1 if any exports fail |
33
+ For programmatic use, richer options, and framework integrations (search indexes, nav trees), use `@openpkg-ts/sdk` directly.
64
34
 
65
- ### spec validate
35
+ ## Agent-assisted docs generation
66
36
 
67
- ```bash
68
- openpkg spec validate openpkg.json
69
- openpkg spec validate openpkg.json --version 1.0
70
- ```
71
-
72
- ### spec diagnostics
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:
73
38
 
74
39
  ```bash
75
- openpkg spec diagnostics openpkg.json
40
+ cp -r node_modules/@openpkg-ts/cli/skills/generate-docs .claude/skills/
76
41
  ```
77
42
 
78
- ### spec filter
79
-
80
- ```bash
81
- openpkg spec filter openpkg.json --kind function,class
82
- openpkg spec filter openpkg.json --has-description -o documented.json
83
- openpkg spec filter openpkg.json --search "user" --summary
84
- openpkg spec filter openpkg.json --deprecated --quiet | jq '.exports[].name'
85
- ```
86
-
87
- | Flag | Description |
88
- |------|-------------|
89
- | `--kind <kinds>` | Filter by kinds (comma-separated) |
90
- | `--name <names>` | Filter by exact names (comma-separated) |
91
- | `--id <ids>` | Filter by export IDs (comma-separated) |
92
- | `--tag <tags>` | Filter by tags (comma-separated) |
93
- | `--deprecated` | Only deprecated exports |
94
- | `--no-deprecated` | Exclude deprecated exports |
95
- | `--has-description` | Only exports with descriptions |
96
- | `--missing-description` | Only exports without descriptions |
97
- | `--search <term>` | Search name/description (case-insensitive) |
98
- | `--module <path>` | Filter by source file path (contains) |
99
- | `-o, --output <file>` | Output file (default: stdout) |
100
- | `--summary` | Only output matched/total counts |
101
- | `--quiet` | Output raw spec only (no wrapper) |
102
-
103
- ### spec diff
104
-
105
- ```bash
106
- openpkg spec diff old.json new.json
107
- openpkg spec diff old.json new.json --summary
108
- ```
109
-
110
- ### spec breaking
111
-
112
- Exit 1 if breaking changes found.
113
-
114
- ```bash
115
- openpkg spec breaking old.json new.json
116
- ```
117
-
118
- ### spec semver
119
-
120
- ```bash
121
- openpkg spec semver old.json new.json
122
- ```
123
-
124
- ### spec changelog
125
-
126
- ```bash
127
- openpkg spec changelog old.json new.json
128
- openpkg spec changelog old.json new.json --format json
129
- ```
130
-
131
- ---
132
-
133
- ## Docs Commands
134
-
135
- ### docs init
136
-
137
- Initialize docs configuration.
43
+ Then ask your agent to "generate API docs" (or run `/generate-docs` in Claude Code).
138
44
 
139
- ```bash
140
- openpkg docs init
141
- ```
142
-
143
- Creates `openpkg.config.json` with default settings.
144
-
145
- ### docs generate
146
-
147
- Generate documentation from spec.
148
-
149
- ```bash
150
- # Markdown (default)
151
- openpkg docs generate openpkg.json -o api.md
152
-
153
- # React layout (single layout + spec JSON, add components via registry)
154
- openpkg docs generate openpkg.json -f react -o ./app/api
155
-
156
- # HTML
157
- openpkg docs generate openpkg.json -f html -o api.html
158
-
159
- # JSON (simplified structure)
160
- openpkg docs generate openpkg.json -f json
161
-
162
- # Split: one file per export
163
- openpkg docs generate openpkg.json --split -o docs/api/
164
-
165
- # With adapter
166
- openpkg docs generate openpkg.json -a fumadocs -o docs/api/
167
-
168
- # From stdin
169
- openpkg spec snapshot src/index.ts -o - | openpkg docs generate - -f md
170
- ```
171
-
172
- | Flag | Description |
173
- |------|-------------|
174
- | `-o, --output <path>` | Output file or directory (default: stdout) |
175
- | `-f, --format <fmt>` | Format: `md`, `json`, `html`, `react` (default: md) |
176
- | `--split` | One file per export (requires `-o` as directory) |
177
- | `-a, --adapter <name>` | Use adapter: `fumadocs`, `raw` (default: raw) |
178
-
179
- ### docs add
180
-
181
- Add components from shadcn-compatible registry.
182
-
183
- ```bash
184
- openpkg docs add function-section
185
- openpkg docs add class-section interface-section
186
- openpkg docs add export-card param-table signature
187
- ```
188
-
189
- ### docs list
190
-
191
- List available registry components.
192
-
193
- ```bash
194
- openpkg docs list
195
- ```
196
-
197
- 16 components available: layouts, sections, primitives.
198
-
199
- ### docs view
200
-
201
- View component details and dependencies.
202
-
203
- ```bash
204
- openpkg docs view function-section
205
- ```
206
-
207
- ---
208
-
209
- ## Pipelines
210
-
211
- Commands are composable via stdin/stdout:
212
-
213
- ```bash
214
- # Extract and generate docs
215
- openpkg spec snapshot src/index.ts -o - | openpkg docs generate - -f md > api.md
216
-
217
- # Extract, verify, then diff
218
- openpkg spec snapshot src/index.ts --verify -o new.json
219
- openpkg spec diff baseline.json new.json --summary
220
- ```
221
-
222
- ## Programmatic Use
223
-
224
- ```typescript
225
- import { getExport, listExports } from '@openpkg-ts/sdk';
226
-
227
- // Same primitives as CLI
228
- const { exports } = await listExports({ entryFile: './src/index.ts' });
229
- const { export: spec } = await getExport({ entryFile: './src/index.ts', exportName: 'myFunc' });
230
- ```
45
+ > Versions ≤ 0.6.4 are broken (unresolvable dependency) and deprecated. Use 0.7.0+.
231
46
 
232
47
  ## License
233
48
 
package/dist/index.js ADDED
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import { parseArgs } from "node:util";
7
+ import {
8
+ createDocs,
9
+ diffSpecs,
10
+ extractSpec,
11
+ listExports,
12
+ recommendSemverBump
13
+ } from "@openpkg-ts/sdk";
14
+ var HELP = `openpkg - extract TypeScript API specs and generate docs
15
+
16
+ Usage:
17
+ openpkg spec <entry.ts> [-o spec.json]
18
+ openpkg docs <entry.ts | spec.json> [-f md|html|json] [-o out]
19
+ openpkg list <entry.ts> [--json]
20
+ openpkg diff <old.json> <new.json>
21
+
22
+ Commands:
23
+ spec Extract an OpenPkg spec from a TypeScript entry point
24
+ docs Generate docs from an entry point or an existing spec file
25
+ list List exports (name, kind, location)
26
+ diff Compare two spec files and recommend a semver bump
27
+
28
+ Options:
29
+ -o, --output Write to file instead of stdout
30
+ -f, --format docs output format: md (default), html, json
31
+ --json list output as JSON
32
+ -h, --help Show this help
33
+ -v, --version Show version
34
+ `;
35
+ function fail(message) {
36
+ console.error(`error: ${message}`);
37
+ process.exit(1);
38
+ }
39
+ function write(content, output) {
40
+ if (output) {
41
+ fs.mkdirSync(path.dirname(path.resolve(output)), { recursive: true });
42
+ fs.writeFileSync(output, content);
43
+ console.error(`wrote ${output}`);
44
+ } else {
45
+ console.log(content);
46
+ }
47
+ }
48
+ function version() {
49
+ const pkg = JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
50
+ return pkg.version;
51
+ }
52
+ function reportDiagnostics(diagnostics) {
53
+ for (const d of diagnostics) {
54
+ if (d.severity === "error" || d.severity === "warning") {
55
+ console.error(`${d.severity}: ${d.message}`);
56
+ }
57
+ }
58
+ }
59
+ async function specCommand(args) {
60
+ const { values, positionals } = parseArgs({
61
+ args,
62
+ options: { output: { type: "string", short: "o" } },
63
+ allowPositionals: true
64
+ });
65
+ const entryFile = positionals[0];
66
+ if (!entryFile)
67
+ fail("spec requires an entry file (openpkg spec src/index.ts)");
68
+ const { spec, diagnostics } = await extractSpec({ entryFile });
69
+ reportDiagnostics(diagnostics);
70
+ write(JSON.stringify(spec, null, 2), values.output);
71
+ }
72
+ async function docsCommand(args) {
73
+ const { values, positionals } = parseArgs({
74
+ args,
75
+ options: {
76
+ output: { type: "string", short: "o" },
77
+ format: { type: "string", short: "f" }
78
+ },
79
+ allowPositionals: true
80
+ });
81
+ const input = positionals[0];
82
+ if (!input)
83
+ fail("docs requires an entry file or spec file (openpkg docs src/index.ts)");
84
+ const format = values.format ?? "md";
85
+ if (!["md", "html", "json"].includes(format))
86
+ fail(`unknown format "${format}" (md|html|json)`);
87
+ let docs;
88
+ if (input.endsWith(".json")) {
89
+ docs = createDocs(input);
90
+ } else {
91
+ const { spec, diagnostics } = await extractSpec({ entryFile: input });
92
+ reportDiagnostics(diagnostics);
93
+ docs = createDocs(spec);
94
+ }
95
+ const content = format === "md" ? docs.toMarkdown() : format === "html" ? docs.toHTML() : JSON.stringify(docs.toJSON(), null, 2);
96
+ write(content, values.output);
97
+ }
98
+ async function listCommand(args) {
99
+ const { values, positionals } = parseArgs({
100
+ args,
101
+ options: { json: { type: "boolean" } },
102
+ allowPositionals: true
103
+ });
104
+ const entryFile = positionals[0];
105
+ if (!entryFile)
106
+ fail("list requires an entry file (openpkg list src/index.ts)");
107
+ const { exports } = await listExports({ entryFile });
108
+ if (values.json) {
109
+ console.log(JSON.stringify(exports, null, 2));
110
+ return;
111
+ }
112
+ for (const exp of exports) {
113
+ const location = exp.file ? ` (${exp.file}:${exp.line})` : "";
114
+ console.log(`${exp.kind.padEnd(10)}${exp.name}${location}`);
115
+ }
116
+ }
117
+ function readSpecFile(file) {
118
+ try {
119
+ return JSON.parse(fs.readFileSync(file, "utf-8"));
120
+ } catch (err) {
121
+ fail(`failed to read spec file ${file}: ${err instanceof Error ? err.message : String(err)}`);
122
+ }
123
+ }
124
+ function diffCommand(args) {
125
+ const [oldFile, newFile] = args;
126
+ if (!oldFile || !newFile)
127
+ fail("diff requires two spec files (openpkg diff old.json new.json)");
128
+ const diff = diffSpecs(readSpecFile(oldFile), readSpecFile(newFile));
129
+ const recommendation = recommendSemverBump(diff);
130
+ const section = (title, items) => {
131
+ if (!items.length)
132
+ return;
133
+ console.log(`${title}:`);
134
+ for (const item of items)
135
+ console.log(` - ${item}`);
136
+ };
137
+ section("Breaking", diff.breaking);
138
+ section("Non-breaking", diff.nonBreaking);
139
+ section("Docs-only", diff.docsOnly);
140
+ if (!diff.breaking.length && !diff.nonBreaking.length && !diff.docsOnly.length) {
141
+ console.log("No changes.");
142
+ }
143
+ console.log(`
144
+ Recommended bump: ${recommendation.bump} (${recommendation.reason})`);
145
+ if (diff.breaking.length)
146
+ process.exitCode = 2;
147
+ }
148
+ async function main() {
149
+ const [command, ...rest] = process.argv.slice(2);
150
+ switch (command) {
151
+ case "spec":
152
+ await specCommand(rest);
153
+ break;
154
+ case "docs":
155
+ await docsCommand(rest);
156
+ break;
157
+ case "list":
158
+ await listCommand(rest);
159
+ break;
160
+ case "diff":
161
+ diffCommand(rest);
162
+ break;
163
+ case "-v":
164
+ case "--version":
165
+ console.log(version());
166
+ break;
167
+ case undefined:
168
+ case "-h":
169
+ case "--help":
170
+ console.log(HELP);
171
+ break;
172
+ default:
173
+ fail(`unknown command "${command}" - run openpkg --help`);
174
+ }
175
+ }
176
+ main().catch((err) => {
177
+ fail(err instanceof Error ? err.message : String(err));
178
+ });
package/package.json CHANGED
@@ -1,31 +1,41 @@
1
1
  {
2
2
  "name": "@openpkg-ts/cli",
3
- "version": "0.6.4",
4
- "description": "CLI for OpenPkg TypeScript API extraction and documentation generation",
3
+ "version": "0.8.0",
4
+ "description": "CLI for OpenPkg - extract TypeScript API specs and generate docs",
5
+ "keywords": [
6
+ "openpkg",
7
+ "typescript",
8
+ "api-extractor",
9
+ "cli",
10
+ "docs"
11
+ ],
5
12
  "homepage": "https://github.com/ryanwaits/openpkg-ts#readme",
6
13
  "repository": {
7
14
  "type": "git",
8
15
  "url": "git+https://github.com/ryanwaits/openpkg-ts.git",
9
16
  "directory": "packages/cli"
10
17
  },
18
+ "license": "MIT",
19
+ "author": "Ryan Waits",
11
20
  "type": "module",
12
- "main": "./dist/src/index.js",
13
- "types": "./dist/src/index.d.ts",
14
21
  "bin": {
15
- "openpkg": "./dist/bin/openpkg.js"
22
+ "openpkg": "./dist/index.js"
16
23
  },
17
24
  "files": [
18
- "dist"
25
+ "dist",
26
+ "skills"
19
27
  ],
20
28
  "scripts": {
21
29
  "build": "bunup",
22
30
  "dev": "bunup --watch",
31
+ "lint": "biome check src/",
32
+ "lint:fix": "biome check --write src/",
33
+ "format": "biome format --write src/",
34
+ "typecheck": "tsc --noEmit -p .",
23
35
  "test": "bun test"
24
36
  },
25
37
  "dependencies": {
26
- "@openpkg-ts/adapters": "^0.3.15",
27
- "@openpkg-ts/sdk": "^0.36.0",
28
- "commander": "^14.0.0"
38
+ "@openpkg-ts/sdk": "^0.38.0"
29
39
  },
30
40
  "devDependencies": {
31
41
  "@types/bun": "latest",