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.
Files changed (95) hide show
  1. package/README.md +1 -1
  2. package/dist/auth/index.d.ts +0 -1
  3. package/dist/auth/index.js +3 -5
  4. package/dist/autofix/index.js +15 -3
  5. package/dist/cli.js +19 -4
  6. package/dist/commands/check-links.js +164 -174
  7. package/dist/commands/deploy.js +5 -2
  8. package/dist/commands/generate.js +206 -199
  9. package/dist/commands/i18n.js +3 -20
  10. package/dist/commands/init.js +47 -40
  11. package/dist/commands/lint.js +3 -20
  12. package/dist/commands/mcp.js +125 -122
  13. package/dist/commands/monitor.js +125 -108
  14. package/dist/commands/review-pr.js +1 -1
  15. package/dist/commands/sdk.js +1 -1
  16. package/dist/config/loader.js +21 -2
  17. package/dist/generator/organizer.d.ts +3 -0
  18. package/dist/generator/organizer.js +4 -9
  19. package/dist/generator/writer.js +2 -10
  20. package/dist/github/pr-comments.js +21 -8
  21. package/dist/plugins/index.js +1 -0
  22. package/dist/scanner/index.js +8 -2
  23. package/dist/template/docs.json +2 -1
  24. package/dist/template/next.config.mjs +2 -1
  25. package/dist/template/package.json +17 -15
  26. package/dist/template/public/favicon.svg +4 -0
  27. package/dist/template/public/search-index.json +1 -1
  28. package/dist/template/scripts/build-search-index.mjs +120 -25
  29. package/dist/template/src/app/api/chat/route.ts +11 -3
  30. package/dist/template/src/app/docs/README.md +28 -0
  31. package/dist/template/src/app/docs/[...slug]/page.tsx +139 -16
  32. package/dist/template/src/app/docs/auth/page.mdx +589 -0
  33. package/dist/template/src/app/docs/autofix/page.mdx +624 -0
  34. package/dist/template/src/app/docs/cli/page.mdx +217 -0
  35. package/dist/template/src/app/docs/config/page.mdx +428 -0
  36. package/dist/template/src/app/docs/configuration/page.mdx +86 -0
  37. package/dist/template/src/app/docs/deployment/page.mdx +112 -0
  38. package/dist/template/src/app/docs/error.tsx +20 -0
  39. package/dist/template/src/app/docs/generator/generator.md +504 -0
  40. package/dist/template/src/app/docs/generator/organizer.md +779 -0
  41. package/dist/template/src/app/docs/generator/page.mdx +613 -0
  42. package/dist/template/src/app/docs/github/page.mdx +502 -0
  43. package/dist/template/src/app/docs/llm/anthropic-client.md +549 -0
  44. package/dist/template/src/app/docs/llm/index.md +471 -0
  45. package/dist/template/src/app/docs/llm/page.mdx +428 -0
  46. package/dist/template/src/app/docs/llms-full.md +256 -0
  47. package/dist/template/src/app/docs/llms.txt +2971 -0
  48. package/dist/template/src/app/docs/not-found.tsx +23 -0
  49. package/dist/template/src/app/docs/page.mdx +0 -3
  50. package/dist/template/src/app/docs/plugins/page.mdx +1793 -0
  51. package/dist/template/src/app/docs/pro/page.mdx +121 -0
  52. package/dist/template/src/app/docs/quickstart/page.mdx +93 -0
  53. package/dist/template/src/app/docs/scanner/content-type.md +599 -0
  54. package/dist/template/src/app/docs/scanner/index.md +212 -0
  55. package/dist/template/src/app/docs/scanner/page.mdx +307 -0
  56. package/dist/template/src/app/docs/scanner/python.md +469 -0
  57. package/dist/template/src/app/docs/scanner/python_parser.md +1056 -0
  58. package/dist/template/src/app/docs/scanner/rust.md +325 -0
  59. package/dist/template/src/app/docs/scanner/typescript.md +201 -0
  60. package/dist/template/src/app/error.tsx +3 -3
  61. package/dist/template/src/app/icon.tsx +29 -0
  62. package/dist/template/src/app/layout.tsx +42 -0
  63. package/dist/template/src/app/not-found.tsx +35 -0
  64. package/dist/template/src/app/page.tsx +62 -28
  65. package/dist/template/src/components/ai-chat.tsx +26 -21
  66. package/dist/template/src/components/breadcrumbs.tsx +46 -2
  67. package/dist/template/src/components/copy-button.tsx +17 -3
  68. package/dist/template/src/components/docs-layout.tsx +142 -8
  69. package/dist/template/src/components/feedback.tsx +4 -2
  70. package/dist/template/src/components/footer.tsx +42 -0
  71. package/dist/template/src/components/header.tsx +29 -5
  72. package/dist/template/src/components/mdx/accordion.tsx +7 -6
  73. package/dist/template/src/components/mdx/card.tsx +19 -7
  74. package/dist/template/src/components/mdx/code-block.tsx +17 -3
  75. package/dist/template/src/components/mdx/code-group.tsx +65 -18
  76. package/dist/template/src/components/mdx/code-playground.tsx +3 -0
  77. package/dist/template/src/components/mdx/go-playground.tsx +3 -0
  78. package/dist/template/src/components/mdx/highlighted-code.tsx +171 -76
  79. package/dist/template/src/components/mdx/python-playground.tsx +2 -0
  80. package/dist/template/src/components/mdx/tabs.tsx +74 -6
  81. package/dist/template/src/components/page-header.tsx +19 -0
  82. package/dist/template/src/components/scroll-to-top.tsx +33 -0
  83. package/dist/template/src/components/search-dialog.tsx +206 -52
  84. package/dist/template/src/components/sidebar.tsx +136 -77
  85. package/dist/template/src/components/table-of-contents.tsx +23 -7
  86. package/dist/template/src/lib/highlight.ts +90 -31
  87. package/dist/template/src/lib/search.ts +14 -4
  88. package/dist/template/src/lib/theme-utils.ts +140 -0
  89. package/dist/template/src/styles/globals.css +307 -166
  90. package/dist/template/src/types/remark-gfm.d.ts +2 -0
  91. package/dist/utils/files.d.ts +9 -0
  92. package/dist/utils/files.js +33 -0
  93. package/dist/utils/validation.d.ts +4 -0
  94. package/dist/utils/validation.js +38 -0
  95. 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
+