skrypt-ai 0.3.4 → 0.4.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 +1 -1
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/index.js +3 -5
- package/dist/autofix/index.js +15 -3
- package/dist/cli.js +19 -4
- package/dist/commands/check-links.js +164 -174
- package/dist/commands/deploy.js +5 -2
- package/dist/commands/generate.js +206 -199
- package/dist/commands/i18n.js +3 -20
- package/dist/commands/init.js +47 -40
- package/dist/commands/lint.js +3 -20
- package/dist/commands/mcp.js +125 -122
- package/dist/commands/monitor.js +125 -108
- package/dist/commands/review-pr.js +1 -1
- package/dist/commands/sdk.js +1 -1
- package/dist/config/loader.js +21 -2
- package/dist/generator/organizer.d.ts +3 -0
- package/dist/generator/organizer.js +4 -9
- package/dist/generator/writer.js +2 -10
- package/dist/github/pr-comments.js +21 -8
- package/dist/plugins/index.js +1 -0
- package/dist/scanner/index.js +8 -2
- package/dist/template/docs.json +2 -1
- package/dist/template/next.config.mjs +2 -1
- package/dist/template/package.json +17 -15
- package/dist/template/public/favicon.svg +4 -0
- package/dist/template/public/search-index.json +1 -1
- package/dist/template/scripts/build-search-index.mjs +120 -25
- package/dist/template/src/app/api/chat/route.ts +11 -3
- package/dist/template/src/app/docs/README.md +28 -0
- package/dist/template/src/app/docs/[...slug]/page.tsx +139 -16
- package/dist/template/src/app/docs/auth/page.mdx +589 -0
- package/dist/template/src/app/docs/autofix/page.mdx +624 -0
- package/dist/template/src/app/docs/cli/page.mdx +217 -0
- package/dist/template/src/app/docs/config/page.mdx +428 -0
- package/dist/template/src/app/docs/configuration/page.mdx +86 -0
- package/dist/template/src/app/docs/deployment/page.mdx +112 -0
- package/dist/template/src/app/docs/error.tsx +20 -0
- package/dist/template/src/app/docs/generator/generator.md +504 -0
- package/dist/template/src/app/docs/generator/organizer.md +779 -0
- package/dist/template/src/app/docs/generator/page.mdx +613 -0
- package/dist/template/src/app/docs/github/page.mdx +502 -0
- package/dist/template/src/app/docs/llm/anthropic-client.md +549 -0
- package/dist/template/src/app/docs/llm/index.md +471 -0
- package/dist/template/src/app/docs/llm/page.mdx +428 -0
- package/dist/template/src/app/docs/llms-full.md +256 -0
- package/dist/template/src/app/docs/llms.txt +2971 -0
- package/dist/template/src/app/docs/not-found.tsx +23 -0
- package/dist/template/src/app/docs/page.mdx +0 -3
- package/dist/template/src/app/docs/plugins/page.mdx +1793 -0
- package/dist/template/src/app/docs/pro/page.mdx +121 -0
- package/dist/template/src/app/docs/quickstart/page.mdx +93 -0
- package/dist/template/src/app/docs/scanner/content-type.md +599 -0
- package/dist/template/src/app/docs/scanner/index.md +212 -0
- package/dist/template/src/app/docs/scanner/page.mdx +307 -0
- package/dist/template/src/app/docs/scanner/python.md +469 -0
- package/dist/template/src/app/docs/scanner/python_parser.md +1056 -0
- package/dist/template/src/app/docs/scanner/rust.md +325 -0
- package/dist/template/src/app/docs/scanner/typescript.md +201 -0
- package/dist/template/src/app/error.tsx +3 -3
- package/dist/template/src/app/icon.tsx +29 -0
- package/dist/template/src/app/layout.tsx +42 -0
- package/dist/template/src/app/not-found.tsx +35 -0
- package/dist/template/src/app/page.tsx +62 -28
- package/dist/template/src/components/ai-chat.tsx +26 -21
- package/dist/template/src/components/breadcrumbs.tsx +46 -2
- package/dist/template/src/components/copy-button.tsx +17 -3
- package/dist/template/src/components/docs-layout.tsx +142 -8
- package/dist/template/src/components/feedback.tsx +4 -2
- package/dist/template/src/components/footer.tsx +42 -0
- package/dist/template/src/components/header.tsx +29 -5
- package/dist/template/src/components/mdx/accordion.tsx +7 -6
- package/dist/template/src/components/mdx/card.tsx +19 -7
- package/dist/template/src/components/mdx/code-block.tsx +17 -3
- package/dist/template/src/components/mdx/code-group.tsx +65 -18
- package/dist/template/src/components/mdx/code-playground.tsx +3 -0
- package/dist/template/src/components/mdx/go-playground.tsx +3 -0
- package/dist/template/src/components/mdx/highlighted-code.tsx +171 -76
- package/dist/template/src/components/mdx/python-playground.tsx +2 -0
- package/dist/template/src/components/mdx/tabs.tsx +74 -6
- package/dist/template/src/components/page-header.tsx +19 -0
- package/dist/template/src/components/scroll-to-top.tsx +33 -0
- package/dist/template/src/components/search-dialog.tsx +206 -52
- package/dist/template/src/components/sidebar.tsx +136 -77
- package/dist/template/src/components/table-of-contents.tsx +23 -7
- package/dist/template/src/lib/highlight.ts +90 -31
- package/dist/template/src/lib/search.ts +14 -4
- package/dist/template/src/lib/theme-utils.ts +140 -0
- package/dist/template/src/styles/globals.css +307 -166
- package/dist/template/src/types/remark-gfm.d.ts +2 -0
- package/dist/utils/files.d.ts +9 -0
- package/dist/utils/files.js +33 -0
- package/dist/utils/validation.d.ts +4 -0
- package/dist/utils/validation.js +38 -0
- package/package.json +1 -4
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: CLI Reference
|
|
3
|
+
description: Complete reference for all Skrypt CLI commands
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
All available commands in the Skrypt CLI.
|
|
7
|
+
|
|
8
|
+
## Core Commands
|
|
9
|
+
|
|
10
|
+
### `skrypt init`
|
|
11
|
+
|
|
12
|
+
Initialize a new documentation site.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
skrypt init [directory] --name <project-name>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
| Option | Description | Default |
|
|
19
|
+
|--------|-------------|---------|
|
|
20
|
+
| `directory` | Target directory | `.` |
|
|
21
|
+
| `--name` | Project name | `my-docs` |
|
|
22
|
+
|
|
23
|
+
### `skrypt generate`
|
|
24
|
+
|
|
25
|
+
Generate documentation from source code.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
skrypt generate <source> [options]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Option | Description |
|
|
32
|
+
|--------|-------------|
|
|
33
|
+
| `-o, --output <dir>` | Output directory |
|
|
34
|
+
| `-c, --config <file>` | Config file path |
|
|
35
|
+
| `--provider <name>` | LLM provider (openai, anthropic, deepseek, ollama) |
|
|
36
|
+
| `--model <name>` | Model name |
|
|
37
|
+
| `--dry-run` | Scan only, don't generate |
|
|
38
|
+
| `--multi-lang` | Generate TypeScript + Python examples |
|
|
39
|
+
| `--by-topic` | Organize by topic instead of file |
|
|
40
|
+
| `--public-only` | Only document exported APIs |
|
|
41
|
+
| `--openapi <file>` | Include OpenAPI spec |
|
|
42
|
+
| `--llms-txt` | Generate llms.txt for AEO |
|
|
43
|
+
| `--exclude <patterns>` | Exclude patterns |
|
|
44
|
+
|
|
45
|
+
**Example:**
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
skrypt generate ./src -o ./docs \
|
|
49
|
+
--provider openai \
|
|
50
|
+
--model gpt-4o \
|
|
51
|
+
--public-only \
|
|
52
|
+
--llms-txt
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### `skrypt deploy`
|
|
56
|
+
|
|
57
|
+
Deploy docs to Skrypt Cloud.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
skrypt deploy [options]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
| Option | Description |
|
|
64
|
+
|--------|-------------|
|
|
65
|
+
| `--dir <path>` | Docs directory (default: current) |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Watch Mode
|
|
70
|
+
|
|
71
|
+
### `skrypt watch`
|
|
72
|
+
|
|
73
|
+
Watch for changes and regenerate docs.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
skrypt watch <source> [options]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Same options as `generate`, plus continuous watching.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Quality Commands
|
|
84
|
+
|
|
85
|
+
### `skrypt lint`
|
|
86
|
+
|
|
87
|
+
Check documentation for issues.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
skrypt lint [directory]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `skrypt check-links`
|
|
94
|
+
|
|
95
|
+
Validate all links in documentation.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
skrypt check-links [directory]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### `skrypt test` (Pro)
|
|
102
|
+
|
|
103
|
+
Validate code examples are runnable.
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
skrypt test [directory]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Pro Commands
|
|
112
|
+
|
|
113
|
+
These require authentication via `skrypt login`.
|
|
114
|
+
|
|
115
|
+
### `skrypt monitor` (Pro)
|
|
116
|
+
|
|
117
|
+
Detect documentation drift from code changes.
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
skrypt monitor [options]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `skrypt autofix` (Pro)
|
|
124
|
+
|
|
125
|
+
AI-powered documentation healing.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
skrypt autofix [options]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### `skrypt review-pr` (Pro)
|
|
132
|
+
|
|
133
|
+
Review pull request for doc impact.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
skrypt review-pr <pr-number>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `skrypt sdk` (Pro)
|
|
140
|
+
|
|
141
|
+
Generate SDK code samples in multiple languages.
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
skrypt sdk --openapi <spec> --output <dir>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### `skrypt mcp` (Pro)
|
|
148
|
+
|
|
149
|
+
Start MCP server for AI tool integration.
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
skrypt mcp
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Utility Commands
|
|
158
|
+
|
|
159
|
+
### `skrypt i18n`
|
|
160
|
+
|
|
161
|
+
Generate translations for documentation.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
skrypt i18n --locales <codes>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### `skrypt llms-txt`
|
|
168
|
+
|
|
169
|
+
Generate llms.txt for Answer Engine Optimization.
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
skrypt llms-txt --project-name <name>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### `skrypt gh-action`
|
|
176
|
+
|
|
177
|
+
Generate GitHub Action workflow.
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
skrypt gh-action
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### `skrypt cron`
|
|
184
|
+
|
|
185
|
+
Set up automated doc updates.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
skrypt cron
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Authentication
|
|
194
|
+
|
|
195
|
+
### `skrypt login`
|
|
196
|
+
|
|
197
|
+
Authenticate with Skrypt Cloud.
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
skrypt login
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### `skrypt logout`
|
|
204
|
+
|
|
205
|
+
Clear local authentication.
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
skrypt logout
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### `skrypt whoami`
|
|
212
|
+
|
|
213
|
+
Show current authentication status.
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
skrypt whoami
|
|
217
|
+
```
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
## Functions
|
|
2
|
+
|
|
3
|
+
### `findConfigFile`
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
function findConfigFile(dir: string): string | null
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Use this to locate a Skrypt configuration file by searching a directory for any of the supported config filenames (`.skrypt.yaml`, `.skrypt.yml`, `skrypt.yaml`, `skrypt.yml`).
|
|
10
|
+
|
|
11
|
+
Returns the **full path** to the first matching config file found, or `null` if none exist in the given directory. Useful for resolving config before initializing your toolchain, or for validating that a project is properly configured.
|
|
12
|
+
|
|
13
|
+
### Parameters
|
|
14
|
+
|
|
15
|
+
| Name | Type | Required | Description |
|
|
16
|
+
|------|------|----------|-------------|
|
|
17
|
+
| `dir` | `string` | ✅ | Absolute or relative path to the directory to search for a config file |
|
|
18
|
+
|
|
19
|
+
#### Returns
|
|
20
|
+
|
|
21
|
+
| Value | When |
|
|
22
|
+
|-------|------|
|
|
23
|
+
| `string` | Full file path (e.g. `/projects/myapp/.skrypt.yaml`) when a config file is found |
|
|
24
|
+
| `null` | No supported config filename exists in the given directory |
|
|
25
|
+
|
|
26
|
+
**Example:**
|
|
27
|
+
|
|
28
|
+
```typescript example.ts
|
|
29
|
+
import { existsSync } from 'fs'
|
|
30
|
+
import { join } from 'path'
|
|
31
|
+
|
|
32
|
+
// Supported config filenames (in priority order)
|
|
33
|
+
const CONFIG_FILENAMES = ['.skrypt.yaml', '.skrypt.yml', 'skrypt.yaml', 'skrypt.yml']
|
|
34
|
+
|
|
35
|
+
// Inline implementation of findConfigFile
|
|
36
|
+
function findConfigFile(dir: string): string | null {
|
|
37
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
38
|
+
const filepath = join(dir, filename)
|
|
39
|
+
if (existsSync(filepath)) {
|
|
40
|
+
return filepath
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// --- Usage Example ---
|
|
47
|
+
|
|
48
|
+
// Search the current working directory for a config file
|
|
49
|
+
const projectDir = process.env.PROJECT_DIR || process.cwd()
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const configPath = findConfigFile(projectDir)
|
|
53
|
+
|
|
54
|
+
if (configPath) {
|
|
55
|
+
console.log('Config file found:', configPath)
|
|
56
|
+
// Output: Config file found: /projects/myapp/.skrypt.yaml
|
|
57
|
+
} else {
|
|
58
|
+
console.log('No config file found in:', projectDir)
|
|
59
|
+
// Output: No config file found in: /projects/myapp
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Common pattern: fall back to a default config location
|
|
63
|
+
const searchDirs = [
|
|
64
|
+
projectDir,
|
|
65
|
+
join(projectDir, 'config'),
|
|
66
|
+
process.env.HOME || '/tmp',
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
const found = searchDirs.map(dir => ({
|
|
70
|
+
dir,
|
|
71
|
+
config: findConfigFile(dir),
|
|
72
|
+
}))
|
|
73
|
+
|
|
74
|
+
const firstMatch = found.find(entry => entry.config !== null)
|
|
75
|
+
|
|
76
|
+
if (firstMatch?.config) {
|
|
77
|
+
console.log('Using config from:', firstMatch.config)
|
|
78
|
+
// Output: Using config from: /projects/myapp/.skrypt.yaml
|
|
79
|
+
} else {
|
|
80
|
+
console.log('No config found in any search path — using defaults')
|
|
81
|
+
}
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error('Error while searching for config file:', error)
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### `loadConfig`
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
function loadConfig(configPath?: string): Config
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Use this to load a configuration file for autodocs, either from a specific path or by auto-discovering it from standard locations in your project.
|
|
94
|
+
|
|
95
|
+
Searches for config files in common locations (e.g., `autodocs.config.yml`, `.autodocs.yml`) when no path is provided. Throws an error if an explicit path is given but the file does not exist.
|
|
96
|
+
|
|
97
|
+
### Parameters
|
|
98
|
+
|
|
99
|
+
| Name | Type | Required | Description |
|
|
100
|
+
|------|------|----------|-------------|
|
|
101
|
+
| `configPath` | `string` | No | Absolute or relative path to a YAML/JSON config file. If omitted, auto-discovery is used. |
|
|
102
|
+
|
|
103
|
+
#### Returns
|
|
104
|
+
|
|
105
|
+
Returns a `Config` object populated with values from the config file, merged with defaults for any missing fields.
|
|
106
|
+
|
|
107
|
+
| Scenario | Result |
|
|
108
|
+
|----------|--------|
|
|
109
|
+
| `configPath` provided and file exists | `Config` loaded from that file |
|
|
110
|
+
| `configPath` provided but file missing | Throws `Error: Config file not found: <path>` |
|
|
111
|
+
| No `configPath`, file auto-discovered | `Config` loaded from discovered file |
|
|
112
|
+
| No `configPath`, no file found | `Config` with default values |
|
|
113
|
+
|
|
114
|
+
**Example:**
|
|
115
|
+
|
|
116
|
+
```typescript example.ts
|
|
117
|
+
import { existsSync, readFileSync } from 'fs'
|
|
118
|
+
import { join } from 'path'
|
|
119
|
+
|
|
120
|
+
// --- Inline types (mirrors autodocs internals) ---
|
|
121
|
+
type LLMProvider = 'openai' | 'anthropic' | 'gemini'
|
|
122
|
+
|
|
123
|
+
interface Config {
|
|
124
|
+
provider: LLMProvider
|
|
125
|
+
model: string
|
|
126
|
+
outputDir: string
|
|
127
|
+
include: string[]
|
|
128
|
+
exclude: string[]
|
|
129
|
+
apiKey?: string
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const DEFAULT_CONFIG: Config = {
|
|
133
|
+
provider: 'openai',
|
|
134
|
+
model: 'gpt-4o',
|
|
135
|
+
outputDir: './docs',
|
|
136
|
+
include: ['src/**/*.ts'],
|
|
137
|
+
exclude: ['**/*.test.ts'],
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// --- Inline config search logic ---
|
|
141
|
+
const SEARCH_PATHS = [
|
|
142
|
+
'autodocs.config.yml',
|
|
143
|
+
'autodocs.config.yaml',
|
|
144
|
+
'.autodocs.yml',
|
|
145
|
+
'.autodocs.yaml',
|
|
146
|
+
'autodocs.config.json',
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
function findConfigFile(): string | null {
|
|
150
|
+
for (const candidate of SEARCH_PATHS) {
|
|
151
|
+
const fullPath = join(process.cwd(), candidate)
|
|
152
|
+
if (existsSync(fullPath)) return fullPath
|
|
153
|
+
}
|
|
154
|
+
return null
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function parseConfig(raw: string, filePath: string): Partial<Config> {
|
|
158
|
+
// Minimal parser: supports JSON only for this self-contained example
|
|
159
|
+
if (filePath.endsWith('.json')) {
|
|
160
|
+
return JSON.parse(raw) as Partial<Config>
|
|
161
|
+
}
|
|
162
|
+
// For YAML files, a real implementation would use js-yaml
|
|
163
|
+
throw new Error('YAML parsing requires js-yaml — use a .json config in this example')
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// --- Self-contained loadConfig implementation ---
|
|
167
|
+
function loadConfig(configPath?: string): Config {
|
|
168
|
+
let resolvedPath: string | null = null
|
|
169
|
+
|
|
170
|
+
if (configPath) {
|
|
171
|
+
if (!existsSync(configPath)) {
|
|
172
|
+
throw new Error(`Config file not found: ${configPath}`)
|
|
173
|
+
}
|
|
174
|
+
resolvedPath = configPath
|
|
175
|
+
} else {
|
|
176
|
+
resolvedPath = findConfigFile()
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!resolvedPath) {
|
|
180
|
+
console.log('No config file found — using defaults.')
|
|
181
|
+
return { ...DEFAULT_CONFIG }
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const raw = readFileSync(resolvedPath, 'utf-8')
|
|
185
|
+
const userConfig = parseConfig(raw, resolvedPath)
|
|
186
|
+
|
|
187
|
+
return { ...DEFAULT_CONFIG, ...userConfig }
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// --- Usage examples ---
|
|
191
|
+
async function main() {
|
|
192
|
+
try {
|
|
193
|
+
// Example 1: Auto-discover config
|
|
194
|
+
console.log('=== Auto-discovery ===')
|
|
195
|
+
const autoConfig = loadConfig()
|
|
196
|
+
console.log('Loaded config:', autoConfig)
|
|
197
|
+
// Output: Config with defaults (or merged values if a config file exists)
|
|
198
|
+
|
|
199
|
+
// Example 2: Explicit path
|
|
200
|
+
console.log('\n=== Explicit path ===')
|
|
201
|
+
const explicitConfig = loadConfig(
|
|
202
|
+
process.env.AUTODOCS_CONFIG || './autodocs.config.json'
|
|
203
|
+
)
|
|
204
|
+
console.log('Loaded config:', explicitConfig)
|
|
205
|
+
// Output: Config merged from the specified file + defaults
|
|
206
|
+
|
|
207
|
+
} catch (error) {
|
|
208
|
+
if (error instanceof Error) {
|
|
209
|
+
// Common case: explicit path was wrong
|
|
210
|
+
console.error('Failed to load config:', error.message)
|
|
211
|
+
// e.g. "Config file not found: ./autodocs.config.json"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
main()
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### `validateConfig`
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
function validateConfig(config: Config): string[]
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Use this to validate a configuration object before using it, catching all errors upfront instead of failing at runtime.
|
|
226
|
+
|
|
227
|
+
Returns an array of error message strings — an empty array means the config is valid. Each string describes a specific validation failure, making it easy to surface all problems at once rather than one at a time.
|
|
228
|
+
|
|
229
|
+
### Parameters
|
|
230
|
+
|
|
231
|
+
| Name | Type | Required | Description |
|
|
232
|
+
|------|------|----------|-------------|
|
|
233
|
+
| config | `Config` | ✅ | The configuration object to validate |
|
|
234
|
+
|
|
235
|
+
### The `Config` Object
|
|
236
|
+
|
|
237
|
+
| Field | Type | Required | Description |
|
|
238
|
+
|-------|------|----------|-------------|
|
|
239
|
+
| version | `number` | ✅ | Must be `1` — any other value produces a validation error |
|
|
240
|
+
| ...other fields | `any` | varies | Additional fields validated by the function |
|
|
241
|
+
|
|
242
|
+
#### Returns
|
|
243
|
+
|
|
244
|
+
| Value | Meaning |
|
|
245
|
+
|-------|---------|
|
|
246
|
+
| `[]` (empty array) | Config is valid — safe to use |
|
|
247
|
+
| `string[]` (non-empty) | One or more validation errors found — each string describes a problem |
|
|
248
|
+
|
|
249
|
+
### Common Patterns
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
const errors = validateConfig(config)
|
|
253
|
+
|
|
254
|
+
// Guard pattern — stop early if invalid
|
|
255
|
+
if (errors.length > 0) {
|
|
256
|
+
throw new Error(`Invalid config:\n${errors.join('\n')}`)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Collect and display all errors
|
|
260
|
+
errors.forEach(err => console.warn('Config error:', err))
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Example:**
|
|
264
|
+
|
|
265
|
+
```typescript example.ts
|
|
266
|
+
// Inline type definition — mirrors the real Config shape
|
|
267
|
+
type LLMProvider = 'openai' | 'anthropic' | 'gemini'
|
|
268
|
+
|
|
269
|
+
type Config = {
|
|
270
|
+
version: number
|
|
271
|
+
provider?: LLMProvider
|
|
272
|
+
apiKey?: string
|
|
273
|
+
outputDir?: string
|
|
274
|
+
license?: string
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Inline implementation — mirrors the real validation logic
|
|
278
|
+
function validateConfig(config: Config): string[] {
|
|
279
|
+
const errors: string[] = []
|
|
280
|
+
|
|
281
|
+
if (config.version !== 1) {
|
|
282
|
+
errors.push(`Unsupported config version: ${config.version}`)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!config.provider) {
|
|
286
|
+
errors.push('Missing required field: provider')
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (!config.apiKey) {
|
|
290
|
+
errors.push('Missing required field: apiKey')
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return errors
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// --- Example usage ---
|
|
297
|
+
|
|
298
|
+
const validConfig: Config = {
|
|
299
|
+
version: 1,
|
|
300
|
+
provider: 'openai',
|
|
301
|
+
apiKey: process.env.OPENAI_API_KEY || 'sk-abc123xyz',
|
|
302
|
+
outputDir: './docs',
|
|
303
|
+
license: 'MIT'
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const invalidConfig: Config = {
|
|
307
|
+
version: 2, // wrong version
|
|
308
|
+
provider: undefined, // missing provider
|
|
309
|
+
apiKey: undefined // missing API key
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function applyConfig(config: Config) {
|
|
313
|
+
try {
|
|
314
|
+
const errors = validateConfig(config)
|
|
315
|
+
|
|
316
|
+
if (errors.length > 0) {
|
|
317
|
+
// Surface ALL problems at once instead of failing one at a time
|
|
318
|
+
throw new Error(`Invalid configuration:\n - ${errors.join('\n - ')}`)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
console.log('✅ Config is valid — proceeding with:', {
|
|
322
|
+
version: config.version,
|
|
323
|
+
provider: config.provider,
|
|
324
|
+
outputDir: config.outputDir ?? '(default)'
|
|
325
|
+
})
|
|
326
|
+
} catch (error) {
|
|
327
|
+
console.error('❌', (error as Error).message)
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
console.log('--- Valid config ---')
|
|
332
|
+
applyConfig(validConfig)
|
|
333
|
+
// Output:
|
|
334
|
+
// ✅ Config is valid — proceeding with: { version: 1, provider: 'openai', outputDir: '(default)' }
|
|
335
|
+
|
|
336
|
+
console.log('\n--- Invalid config ---')
|
|
337
|
+
applyConfig(invalidConfig)
|
|
338
|
+
// Output:
|
|
339
|
+
// ❌ Invalid configuration:
|
|
340
|
+
// - Unsupported config version: 2
|
|
341
|
+
// - Missing required field: provider
|
|
342
|
+
// - Missing required field: apiKey
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### `checkApiKey`
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
function checkApiKey(provider: LLMProvider): { ok: boolean; envKey: string | null }
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Use this to verify whether a required API key environment variable is set for a given LLM provider before making requests.
|
|
352
|
+
|
|
353
|
+
Returns `{ ok: true }` for providers that don't require an API key (e.g., Ollama), and checks the appropriate environment variable for cloud providers (e.g., OpenAI, Anthropic). Use this at startup or before inference calls to give users clear, actionable feedback when credentials are missing.
|
|
354
|
+
|
|
355
|
+
### Parameters
|
|
356
|
+
|
|
357
|
+
| Name | Type | Required | Description |
|
|
358
|
+
|------|------|----------|-------------|
|
|
359
|
+
| `provider` | `LLMProvider` | ✅ | The LLM provider to check (e.g., `'openai'`, `'anthropic'`, `'ollama'`) |
|
|
360
|
+
|
|
361
|
+
#### Returns
|
|
362
|
+
|
|
363
|
+
| Field | Type | Description |
|
|
364
|
+
|-------|------|-------------|
|
|
365
|
+
| `ok` | `boolean` | `true` if the API key is present or not required; `false` if a key is required but missing |
|
|
366
|
+
| `envKey` | `string \| null` | The name of the environment variable checked (e.g., `'OPENAI_API_KEY'`), or `null` if no key is needed |
|
|
367
|
+
|
|
368
|
+
### Behavior by Provider
|
|
369
|
+
|
|
370
|
+
- **Providers requiring a key** (e.g., `openai`, `anthropic`): Returns `{ ok: false, envKey: 'OPENAI_API_KEY' }` when the variable is unset, or `{ ok: true, envKey: 'OPENAI_API_KEY' }` when it is set.
|
|
371
|
+
- **Self-hosted providers** (e.g., `ollama`): Always returns `{ ok: true, envKey: null }` — no key needed.
|
|
372
|
+
|
|
373
|
+
**Example:**
|
|
374
|
+
|
|
375
|
+
```typescript example.ts
|
|
376
|
+
// Inline types — do not import from autodocs
|
|
377
|
+
type LLMProvider = 'openai' | 'anthropic' | 'ollama' | 'gemini'
|
|
378
|
+
|
|
379
|
+
// Maps each provider to its required environment variable (null = no key needed)
|
|
380
|
+
const PROVIDER_ENV_KEYS: Record<LLMProvider, string | null> = {
|
|
381
|
+
openai: 'OPENAI_API_KEY',
|
|
382
|
+
anthropic: 'ANTHROPIC_API_KEY',
|
|
383
|
+
gemini: 'GEMINI_API_KEY',
|
|
384
|
+
ollama: null, // self-hosted, no key required
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Inline implementation matching autodocs behavior
|
|
388
|
+
function checkApiKey(provider: LLMProvider): { ok: boolean; envKey: string | null } {
|
|
389
|
+
const envKey = PROVIDER_ENV_KEYS[provider]
|
|
390
|
+
|
|
391
|
+
// Provider doesn't need an API key (e.g. Ollama)
|
|
392
|
+
if (!envKey) {
|
|
393
|
+
return { ok: true, envKey: null }
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const ok = Boolean(process.env[envKey])
|
|
397
|
+
return { ok, envKey }
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// --- Usage ---
|
|
401
|
+
|
|
402
|
+
const providers: LLMProvider[] = ['openai', 'anthropic', 'ollama', 'gemini']
|
|
403
|
+
|
|
404
|
+
for (const provider of providers) {
|
|
405
|
+
try {
|
|
406
|
+
const result = checkApiKey(provider)
|
|
407
|
+
|
|
408
|
+
if (!result.ok) {
|
|
409
|
+
console.warn(
|
|
410
|
+
`[${provider}] ❌ Missing API key — set the ${result.envKey} environment variable`
|
|
411
|
+
)
|
|
412
|
+
} else if (result.envKey === null) {
|
|
413
|
+
console.log(`[${provider}] ✅ No API key required (self-hosted)`)
|
|
414
|
+
} else {
|
|
415
|
+
console.log(`[${provider}] ✅ API key found in ${result.envKey}`)
|
|
416
|
+
}
|
|
417
|
+
} catch (error) {
|
|
418
|
+
console.error(`[${provider}] Failed to check API key:`, error)
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Example output (when only OPENAI_API_KEY is set):
|
|
423
|
+
// [openai] ✅ API key found in OPENAI_API_KEY
|
|
424
|
+
// [anthropic] ❌ Missing API key — set the ANTHROPIC_API_KEY environment variable
|
|
425
|
+
// [ollama] ✅ No API key required (self-hosted)
|
|
426
|
+
// [gemini] ❌ Missing API key — set the GEMINI_API_KEY environment variable
|
|
427
|
+
```
|
|
428
|
+
|