skrypt-ai 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.
Files changed (110) hide show
  1. package/dist/auth/index.js +3 -3
  2. package/dist/cli.js +1 -1
  3. package/dist/commands/cron.js +0 -4
  4. package/dist/commands/generate/index.d.ts +3 -0
  5. package/dist/commands/generate/index.js +393 -0
  6. package/dist/commands/generate/scan.d.ts +41 -0
  7. package/dist/commands/generate/scan.js +256 -0
  8. package/dist/commands/generate/verify.d.ts +14 -0
  9. package/dist/commands/generate/verify.js +122 -0
  10. package/dist/commands/generate/write.d.ts +25 -0
  11. package/dist/commands/generate/write.js +120 -0
  12. package/dist/commands/import.js +4 -1
  13. package/dist/commands/llms-txt.js +6 -4
  14. package/dist/config/loader.d.ts +0 -1
  15. package/dist/config/loader.js +1 -1
  16. package/dist/generator/agents-md.d.ts +25 -0
  17. package/dist/generator/agents-md.js +122 -0
  18. package/dist/generator/index.d.ts +2 -0
  19. package/dist/generator/index.js +2 -0
  20. package/dist/generator/mdx-serializer.d.ts +11 -0
  21. package/dist/generator/mdx-serializer.js +135 -0
  22. package/dist/generator/organizer.d.ts +1 -16
  23. package/dist/generator/organizer.js +0 -38
  24. package/dist/generator/writer.js +5 -4
  25. package/dist/llm/proxy-client.d.ts +32 -0
  26. package/dist/llm/proxy-client.js +103 -0
  27. package/dist/scanner/csharp.d.ts +0 -4
  28. package/dist/scanner/csharp.js +9 -49
  29. package/dist/scanner/go.d.ts +0 -3
  30. package/dist/scanner/go.js +8 -35
  31. package/dist/scanner/java.d.ts +0 -4
  32. package/dist/scanner/java.js +9 -49
  33. package/dist/scanner/kotlin.d.ts +0 -3
  34. package/dist/scanner/kotlin.js +6 -33
  35. package/dist/scanner/php.d.ts +0 -10
  36. package/dist/scanner/php.js +11 -55
  37. package/dist/scanner/ruby.d.ts +0 -3
  38. package/dist/scanner/ruby.js +8 -38
  39. package/dist/scanner/rust.d.ts +0 -3
  40. package/dist/scanner/rust.js +10 -37
  41. package/dist/scanner/swift.d.ts +0 -3
  42. package/dist/scanner/swift.js +8 -35
  43. package/dist/scanner/utils.d.ts +41 -0
  44. package/dist/scanner/utils.js +97 -0
  45. package/dist/template/docs.json +5 -2
  46. package/dist/template/next.config.mjs +31 -0
  47. package/dist/template/package.json +5 -3
  48. package/dist/template/src/app/layout.tsx +13 -13
  49. package/dist/template/src/app/llms-full.md/route.ts +29 -0
  50. package/dist/template/src/app/llms.txt/route.ts +29 -0
  51. package/dist/template/src/app/md/[...slug]/route.ts +174 -0
  52. package/dist/template/src/app/reference/route.ts +22 -18
  53. package/dist/template/src/app/sitemap.ts +1 -1
  54. package/dist/template/src/components/ai-chat-impl.tsx +206 -0
  55. package/dist/template/src/components/ai-chat.tsx +20 -193
  56. package/dist/template/src/components/mdx/index.tsx +27 -4
  57. package/dist/template/src/lib/fonts.ts +135 -0
  58. package/dist/template/src/middleware.ts +101 -0
  59. package/dist/template/src/styles/globals.css +28 -20
  60. package/dist/utils/files.d.ts +0 -8
  61. package/dist/utils/files.js +0 -33
  62. package/package.json +1 -1
  63. package/dist/autofix/autofix.test.d.ts +0 -1
  64. package/dist/autofix/autofix.test.js +0 -487
  65. package/dist/commands/generate.d.ts +0 -9
  66. package/dist/commands/generate.js +0 -739
  67. package/dist/generator/generator.test.d.ts +0 -1
  68. package/dist/generator/generator.test.js +0 -259
  69. package/dist/generator/writer.test.d.ts +0 -1
  70. package/dist/generator/writer.test.js +0 -411
  71. package/dist/llm/llm.manual-test.d.ts +0 -1
  72. package/dist/llm/llm.manual-test.js +0 -112
  73. package/dist/llm/llm.mock-test.d.ts +0 -4
  74. package/dist/llm/llm.mock-test.js +0 -79
  75. package/dist/plugins/index.d.ts +0 -47
  76. package/dist/plugins/index.js +0 -181
  77. package/dist/scanner/content-type.test.d.ts +0 -1
  78. package/dist/scanner/content-type.test.js +0 -231
  79. package/dist/scanner/integration.test.d.ts +0 -4
  80. package/dist/scanner/integration.test.js +0 -180
  81. package/dist/scanner/scanner.test.d.ts +0 -1
  82. package/dist/scanner/scanner.test.js +0 -210
  83. package/dist/scanner/typescript.manual-test.d.ts +0 -1
  84. package/dist/scanner/typescript.manual-test.js +0 -112
  85. package/dist/template/src/app/docs/auth/page.mdx +0 -589
  86. package/dist/template/src/app/docs/autofix/page.mdx +0 -624
  87. package/dist/template/src/app/docs/cli/page.mdx +0 -217
  88. package/dist/template/src/app/docs/config/page.mdx +0 -428
  89. package/dist/template/src/app/docs/configuration/page.mdx +0 -86
  90. package/dist/template/src/app/docs/deployment/page.mdx +0 -112
  91. package/dist/template/src/app/docs/generator/generator.md +0 -504
  92. package/dist/template/src/app/docs/generator/organizer.md +0 -779
  93. package/dist/template/src/app/docs/generator/page.mdx +0 -613
  94. package/dist/template/src/app/docs/github/page.mdx +0 -502
  95. package/dist/template/src/app/docs/llm/anthropic-client.md +0 -549
  96. package/dist/template/src/app/docs/llm/index.md +0 -471
  97. package/dist/template/src/app/docs/llm/page.mdx +0 -428
  98. package/dist/template/src/app/docs/plugins/page.mdx +0 -1793
  99. package/dist/template/src/app/docs/pro/page.mdx +0 -121
  100. package/dist/template/src/app/docs/quickstart/page.mdx +0 -93
  101. package/dist/template/src/app/docs/scanner/content-type.md +0 -599
  102. package/dist/template/src/app/docs/scanner/index.md +0 -212
  103. package/dist/template/src/app/docs/scanner/page.mdx +0 -307
  104. package/dist/template/src/app/docs/scanner/python.md +0 -469
  105. package/dist/template/src/app/docs/scanner/python_parser.md +0 -1056
  106. package/dist/template/src/app/docs/scanner/rust.md +0 -325
  107. package/dist/template/src/app/docs/scanner/typescript.md +0 -201
  108. package/dist/template/src/app/icon.tsx +0 -29
  109. package/dist/utils/validation.d.ts +0 -1
  110. package/dist/utils/validation.js +0 -12
@@ -1,86 +0,0 @@
1
- ---
2
- title: Configuration
3
- description: Configure Skrypt with skrypt.config.yaml
4
- ---
5
-
6
- Configure Skrypt behavior with a `skrypt.config.yaml` file.
7
-
8
- ## Basic Configuration
9
-
10
- ```yaml
11
- source: ./src
12
- output: ./docs/src/app/docs
13
- provider: openai
14
- model: gpt-4o
15
- ```
16
-
17
- ## Full Reference
18
-
19
- ```yaml
20
- output: ./docs
21
-
22
- model: gpt-4o # Model name
23
- baseUrl: null # Custom API URL (for Ollama/proxies)
24
-
25
- publicOnly: true # Only document exported/public APIs
26
- multiLang: false # Generate TypeScript + Python examples
27
- byTopic: false # Organize by topic instead of file structure
28
- llmsTxt: true # Generate llms.txt for AEO
29
- projectName: "My Project"
30
-
31
- - "**/*.test.ts"
32
- - "**/__tests__/**"
33
- - "name:internal*"
34
- - "name:_*"
35
-
36
- ```
37
-
38
- ## Environment Variables
39
-
40
- ```bash
41
- export OPENAI_API_KEY=sk-...
42
- export ANTHROPIC_API_KEY=sk-ant-...
43
- export DEEPSEEK_API_KEY=sk-...
44
- ```
45
-
46
- ## Provider Examples
47
-
48
- ### OpenAI
49
-
50
- ```yaml
51
- provider: openai
52
- model: gpt-4o
53
- ```
54
-
55
- ### Anthropic
56
-
57
- ```yaml
58
- provider: anthropic
59
- model: claude-sonnet-4-6
60
- ```
61
-
62
- ### Ollama (Local)
63
-
64
- ```yaml
65
- provider: ollama
66
- model: llama3.2
67
- baseUrl: http://localhost:11434
68
- ```
69
-
70
- ## Exclusion Patterns
71
-
72
- ### File Patterns
73
-
74
- ```yaml
75
- exclude:
76
- - "**/*.test.ts"
77
- - "**/internal/**"
78
- ```
79
-
80
- ### Name Patterns
81
-
82
- ```yaml
83
- exclude:
84
- - "name:_*" # Private
85
- - "name:internal*" # Internal functions
86
- ```
@@ -1,112 +0,0 @@
1
- ---
2
- title: Deployment Guide
3
- description: Deploy your Skrypt documentation site
4
- ---
5
-
6
- ## Quick Deploy (Skrypt Cloud)
7
-
8
- ```bash
9
- skrypt deploy
10
- ```
11
-
12
- Your docs will be live at `https://your-project.skrypt.sh`.
13
-
14
- ## Self-Hosted Setup
15
-
16
- ### Prerequisites
17
-
18
- - Node.js 18+
19
- - Supabase account
20
- - Cloudflare account
21
- - Vercel account
22
-
23
- ### 1. Clone and Install
24
-
25
- ```bash
26
- git clone https://github.com/debgotwired/skrypt
27
- cd skrypt
28
- npm install
29
- npm run build
30
- ```
31
-
32
- ### 2. Supabase Setup
33
-
34
- ```bash
35
- cd landing
36
- npx supabase login
37
- npx supabase link --project-ref YOUR_PROJECT_REF
38
- npx supabase db push
39
- ```
40
-
41
- ### 3. Environment Variables
42
-
43
- Create `.env.local`:
44
-
45
- ```bash
46
- NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
47
- NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
48
- SUPABASE_SERVICE_ROLE_KEY=eyJ...
49
-
50
- STRIPE_SECRET_KEY=sk_live_...
51
- OPENAI_API_KEY=sk-...
52
-
53
- NEXT_PUBLIC_APP_URL=https://skrypt.sh
54
- ```
55
-
56
- ### 4. Deploy Landing
57
-
58
- ```bash
59
- cd landing
60
- vercel
61
- ```
62
-
63
- ### 5. Cloudflare Pages
64
-
65
- For user docs hosting:
66
-
67
- 1. Create Cloudflare Pages project
68
- 2. Configure wildcard DNS: `*.skrypt.sh`
69
-
70
- ### 6. Stripe Webhooks
71
-
72
- URL: `https://skrypt.sh/api/webhooks/stripe`
73
-
74
- Events:
75
- - `checkout.session.completed`
76
- - `customer.subscription.updated`
77
- - `customer.subscription.deleted`
78
-
79
- ---
80
-
81
- ## CLI Installation
82
-
83
- ### npm
84
-
85
- ```bash
86
- npm install -g skrypt-ai
87
- ```
88
-
89
- ### Homebrew
90
-
91
- ```bash
92
- brew tap debgotwired/tap
93
- brew install skrypt
94
- ```
95
-
96
- ---
97
-
98
- ## Troubleshooting
99
-
100
- ### "API_KEY required"
101
-
102
- ```bash
103
- export OPENAI_API_KEY=sk-...
104
- ```
105
-
106
- ### Build Errors
107
-
108
- ```bash
109
- rm -rf node_modules
110
- npm install
111
- npm run build
112
- ```
@@ -1,504 +0,0 @@
1
- # Generator.ts
2
-
3
- ## Functions
4
-
5
- ### `generateForElement`
6
-
7
- ```typescript
8
- async function generateForElement(element: APIElement, client: LLMClient, options: GenerationOptions, onProgress?: (progress: GenerationProgress) => void): Promise<GeneratedDoc>
9
- ```
10
-
11
- Use this to generate documentation for a single API element using an LLM client, without running any test validation on the output.
12
-
13
- This is the core documentation generation function — pass it a parsed API element (function, class, type, etc.), an LLM client, and generation options to receive structured documentation. Optionally track progress in real time via the `onProgress` callback.
14
-
15
- ## Parameters
16
-
17
- | Name | Type | Required | Description |
18
- |------|------|----------|-------------|
19
- | `element` | `APIElement` | ✅ | The parsed API element to document (function, class, interface, etc.) |
20
- | `client` | `LLMClient` | ✅ | Configured LLM client used to generate the documentation |
21
- | `options` | `GenerationOptions` | ✅ | Controls generation behavior: model, style, language, max tokens, etc. |
22
- | `onProgress` | `(progress: GenerationProgress) => void` | ❌ | Optional callback invoked during generation to report progress stages |
23
-
24
- ## Returns
25
-
26
- Returns a `Promise<GeneratedDoc>` that resolves to a structured documentation object containing:
27
-
28
- | Field | Description |
29
- |-------|-------------|
30
- | `markdown` | The generated documentation as a markdown string |
31
- | `element` | Reference back to the source `APIElement` |
32
- | `metadata` | Generation metadata (model used, token counts, timestamp) |
33
-
34
- Rejects with an error if the LLM client fails or the element cannot be processed.
35
-
36
- **Example:**
37
-
38
- ```typescript example.ts
39
- // ─── Inline type definitions (no external imports needed) ───────────────────
40
-
41
- type APIElement = {
42
- name: string
43
- kind: 'function' | 'class' | 'interface' | 'type'
44
- signature: string
45
- docstring?: string
46
- filePath: string
47
- }
48
-
49
- type GenerationOptions = {
50
- model: string
51
- style: 'concise' | 'detailed'
52
- language: 'typescript' | 'javascript'
53
- maxTokens?: number
54
- }
55
-
56
- type GenerationProgress = {
57
- stage: 'preparing' | 'generating' | 'formatting' | 'complete'
58
- percentComplete: number
59
- message: string
60
- }
61
-
62
- type GeneratedDoc = {
63
- markdown: string
64
- element: APIElement
65
- metadata: {
66
- model: string
67
- tokensUsed: number
68
- generatedAt: string
69
- }
70
- }
71
-
72
- type LLMClient = {
73
- apiKey: string
74
- baseUrl: string
75
- complete: (prompt: string, maxTokens: number) => Promise<string>
76
- }
77
-
78
- // ─── Simulated implementations ───────────────────────────────────────────────
79
-
80
- function createLLMClient(apiKey: string): LLMClient {
81
- return {
82
- apiKey,
83
- baseUrl: 'https://api.openai.com/v1',
84
- complete: async (prompt: string, maxTokens: number): Promise<string> => {
85
- // Simulates an LLM response for demonstration
86
- return `Use this to calculate the total price including tax.\n\n**Parameters:**\n- \`price\`: number — base price\n- \`taxRate\`: number — tax rate as a decimal\n\n**Returns:** \`number\` — final price with tax applied`
87
- }
88
- }
89
- }
90
-
91
- async function generateForElement(
92
- element: APIElement,
93
- client: LLMClient,
94
- options: GenerationOptions,
95
- onProgress?: (progress: GenerationProgress) => void
96
- ): Promise<GeneratedDoc> {
97
- const reportProgress = (stage: GenerationProgress['stage'], percent: number, message: string) => {
98
- onProgress?.({ stage, percentComplete: percent, message })
99
- }
100
-
101
- reportProgress('preparing', 10, `Preparing context for "${element.name}"`)
102
- await new Promise(r => setTimeout(r, 50)) // simulate async work
103
-
104
- reportProgress('generating', 40, `Sending "${element.name}" to ${options.model}`)
105
- const prompt = `Generate ${options.style} documentation for:\n${element.signature}`
106
- const rawDoc = await client.complete(prompt, options.maxTokens ?? 1024)
107
-
108
- reportProgress('formatting', 80, 'Formatting output')
109
- await new Promise(r => setTimeout(r, 30))
110
-
111
- reportProgress('complete', 100, 'Documentation generated successfully')
112
-
113
- return {
114
- markdown: rawDoc,
115
- element,
116
- metadata: {
117
- model: options.model,
118
- tokensUsed: rawDoc.split(' ').length * 2, // rough estimate for demo
119
- generatedAt: new Date().toISOString()
120
- }
121
- }
122
- }
123
-
124
- // ─── Usage example ────────────────────────────────────────────────────────────
125
-
126
- const apiElement: APIElement = {
127
- name: 'calculateTotalPrice',
128
- kind: 'function',
129
- signature: 'function calculateTotalPrice(price: number, taxRate: number): number',
130
- docstring: 'Calculates the total price including tax.',
131
- filePath: 'src/pricing/utils.ts'
132
- }
133
-
134
- const client = createLLMClient(process.env.OPENAI_API_KEY || 'sk-your-api-key-here')
135
-
136
- const options: GenerationOptions = {
137
- model: 'gpt-4o',
138
- style: 'detailed',
139
- language: 'typescript',
140
- maxTokens: 512
141
- }
142
-
143
- async function main() {
144
- try {
145
- console.log(`Generating docs for: ${apiElement.name}\n`)
146
-
147
- const doc = await generateForElement(
148
- apiElement,
149
- client,
150
- options,
151
- (progress: GenerationProgress) => {
152
- console.log(`[${progress.percentComplete}%] ${progress.stage}: ${progress.message}`)
153
- }
154
- )
155
-
156
- console.log('\n─── Generated Documentation ───────────────────────────')
157
- console.log(doc.markdown)
158
- console.log('\n─── Metadata ──────────────────────────────────────────')
159
- console.log(`Model: ${doc.metadata.model}`)
160
- console.log(`Tokens used: ${doc.metadata.tokensUsed}`)
161
- console.log(`Generated at: ${doc.metadata.generatedAt}`)
162
-
163
- // Expected output:
164
- // [10%] preparing: Preparing context for "calculateTotalPrice"
165
- // [40%] generating: Sending "calculateTotalPrice" to gpt-4o
166
- // [80%] formatting: Formatting output
167
- // [100%] complete: Documentation generated successfully
168
- //
169
- // ─── Generated Documentation ───
170
- // Use this to calculate the total price including tax.
171
- // ...
172
- } catch (error) {
173
- console.error('Documentation generation failed:', error)
174
- process.exit(1)
175
- }
176
- }
177
-
178
- main()
179
- ```
180
-
181
- ### `generateForElements`
182
-
183
- ```typescript
184
- async function generateForElements(elements: APIElement[], client: LLMClient, options: GenerationOptions): Promise<GeneratedDoc[]>
185
- ```
186
-
187
- Use this to batch-generate documentation for multiple API elements in a single call, processing an entire scanned API surface and returning structured docs for each element.
188
-
189
- This is the primary entry point for bulk documentation generation — pass in your parsed API elements, an LLM client, and generation options to get back a full array of generated documentation objects.
190
-
191
- ## Parameters
192
-
193
- | Name | Type | Required | Description |
194
- |------|------|----------|-------------|
195
- | `elements` | `APIElement[]` | Yes | Array of parsed API elements (functions, classes, types, etc.) to generate docs for |
196
- | `client` | `LLMClient` | Yes | Configured LLM client used to generate the documentation content |
197
- | `options` | `GenerationOptions` | Yes | Controls generation behavior: model selection, output format, concurrency, etc. |
198
-
199
- ## Returns
200
-
201
- Returns `Promise<GeneratedDoc[]>` — resolves to an array of generated documentation objects, one per input element, in the same order as the input `elements` array.
202
-
203
- | Scenario | Result |
204
- |----------|--------|
205
- | All elements processed successfully | Array of `GeneratedDoc` objects with markdown/content for each element |
206
- | Empty `elements` array | Resolves to `[]` |
207
- | LLM client error on an element | Rejects or returns partial results depending on `options.onError` strategy |
208
-
209
- **Example:**
210
-
211
- ```typescript example.ts
212
- // ─── Inline type definitions (no external imports needed) ───────────────────
213
-
214
- type APIElement = {
215
- name: string
216
- kind: 'function' | 'class' | 'type' | 'interface' | 'variable'
217
- signature: string
218
- docstring?: string
219
- filePath: string
220
- }
221
-
222
- type GeneratedDoc = {
223
- elementName: string
224
- kind: APIElement['kind']
225
- markdown: string
226
- generatedAt: Date
227
- }
228
-
229
- type GenerationOptions = {
230
- model?: string
231
- maxConcurrency?: number
232
- outputFormat?: 'markdown' | 'html'
233
- onError?: 'skip' | 'throw'
234
- }
235
-
236
- type LLMClient = {
237
- apiKey: string
238
- baseUrl: string
239
- complete: (prompt: string) => Promise<string>
240
- }
241
-
242
- // ─── Simulated implementation of generateForElements ────────────────────────
243
-
244
- async function generateForElements(
245
- elements: APIElement[],
246
- client: LLMClient,
247
- options: GenerationOptions
248
- ): Promise<GeneratedDoc[]> {
249
- const {
250
- maxConcurrency = 3,
251
- outputFormat = 'markdown',
252
- onError = 'skip',
253
- } = options
254
-
255
- const results: GeneratedDoc[] = []
256
-
257
- // Process in batches to respect maxConcurrency
258
- for (let i = 0; i < elements.length; i += maxConcurrency) {
259
- const batch = elements.slice(i, i + maxConcurrency)
260
-
261
- const batchResults = await Promise.allSettled(
262
- batch.map(async (element) => {
263
- const prompt = `Generate ${outputFormat} documentation for: ${element.signature}`
264
-
265
- try {
266
- const content = await client.complete(prompt)
267
- return {
268
- elementName: element.name,
269
- kind: element.kind,
270
- markdown: content,
271
- generatedAt: new Date(),
272
- } satisfies GeneratedDoc
273
- } catch (err) {
274
- if (onError === 'throw') throw err
275
- console.warn(`Skipping ${element.name} due to error:`, err)
276
- return null
277
- }
278
- })
279
- )
280
-
281
- for (const result of batchResults) {
282
- if (result.status === 'fulfilled' && result.value !== null) {
283
- results.push(result.value)
284
- }
285
- }
286
- }
287
-
288
- return results
289
- }
290
-
291
- // ─── Simulated LLM client (replace complete() with real API call) ────────────
292
-
293
- function createLLMClient(apiKey: string): LLMClient {
294
- return {
295
- apiKey,
296
- baseUrl: 'https://api.openai.com/v1',
297
- complete: async (prompt: string): Promise<string> => {
298
- // Simulate LLM latency
299
- await new Promise((r) => setTimeout(r, 50))
300
- return `**Auto-generated doc**\n\nPrompt received: "${prompt.slice(0, 60)}..."`
301
- },
302
- }
303
- }
304
-
305
- // ─── Example usage ───────────────────────────────────────────────────────────
306
-
307
- const elements: APIElement[] = [
308
- {
309
- name: 'fetchUser',
310
- kind: 'function',
311
- signature: 'async function fetchUser(id: string): Promise<User>',
312
- docstring: 'Fetches a user by ID',
313
- filePath: 'src/api/users.ts',
314
- },
315
- {
316
- name: 'UserService',
317
- kind: 'class',
318
- signature: 'class UserService { constructor(db: Database) }',
319
- filePath: 'src/services/UserService.ts',
320
- },
321
- {
322
- name: 'UserRole',
323
- kind: 'type',
324
- signature: "type UserRole = 'admin' | 'editor' | 'viewer'",
325
- filePath: 'src/types/roles.ts',
326
- },
327
- ]
328
-
329
- const client = createLLMClient(process.env.LLM_API_KEY || 'sk-your-api-key-here')
330
-
331
- const options: GenerationOptions = {
332
- model: 'gpt-4o',
333
- maxConcurrency: 2,
334
- outputFormat: 'markdown',
335
- onError: 'skip',
336
- }
337
-
338
- async function main() {
339
- try {
340
- console.log(`Generating docs for ${elements.length} elements...\n`)
341
-
342
- const docs = await generateForElements(elements, client, options)
343
-
344
- console.log(`✅ Generated ${docs.length} documentation entries:\n`)
345
-
346
- for (const doc of docs) {
347
- console.log(`─── ${doc.elementName} (${doc.kind}) ───`)
348
- console.log(doc.markdown)
349
- console.log(`Generated at: ${doc.generatedAt.toISOString()}\n`)
350
- }
351
-
352
- // Expected output:
353
- // ✅ Generated 3 documentation entries:
354
- // ─── fetchUser (function) ───
355
- // **Auto-generated doc**
356
- // Prompt received: "Generate markdown documentation for: async function fe..."
357
- // Generated at: 2024-11-15T10:23:45.123Z
358
- // ... (one entry per element)
359
- } catch (error) {
360
- console.error('Documentation generation failed:', error)
361
- process.exit(1)
362
- }
363
- }
364
-
365
- main()
366
- ```
367
-
368
- ### `formatAsMarkdown`
369
-
370
- ```typescript
371
- function formatAsMarkdown(docs: GeneratedDoc[], title: string): string
372
- ```
373
-
374
- Use this to convert an array of generated documentation objects into a formatted Markdown string, ready to write to a `.md` file or display in a docs site.
375
-
376
- Takes structured doc data (functions, classes, methods) and a page title, and returns a complete Markdown document with sections organized by element type.
377
-
378
- ## Parameters
379
-
380
- | Name | Type | Required | Description |
381
- |------|------|----------|-------------|
382
- | `docs` | `GeneratedDoc[]` | ✅ | Array of generated documentation objects, each containing an element descriptor and its rendered doc content |
383
- | `title` | `string` | ✅ | The top-level heading for the Markdown document (rendered as `# title`) |
384
-
385
- ## Returns
386
-
387
- A `string` containing the full Markdown file content, with:
388
- - A `# Title` heading at the top
389
- - Sections grouped by element kind: **Functions**, **Classes**, and **Methods**
390
- - Each doc entry rendered under its appropriate section
391
-
392
- ---MARKDOWN---
393
-
394
- **Example:**
395
-
396
- ```typescript example.ts
397
- // ---- Inline types (mirrors the real GeneratedDoc / APIElement shape) ----
398
- type ElementKind = 'function' | 'class' | 'method'
399
-
400
- interface APIElement {
401
- name: string
402
- kind: ElementKind
403
- signature?: string
404
- }
405
-
406
- interface GeneratedDoc {
407
- element: APIElement
408
- documentation: string
409
- }
410
-
411
- // ---- Inline implementation of formatAsMarkdown ----
412
- function formatAsMarkdown(docs: GeneratedDoc[], title: string): string {
413
- let content = `# ${title}\n\n`
414
-
415
- const functions = docs.filter(d => d.element.kind === 'function')
416
- const classes = docs.filter(d => d.element.kind === 'class')
417
- const methods = docs.filter(d => d.element.kind === 'method')
418
-
419
- function renderSection(heading: string, items: GeneratedDoc[]): string {
420
- if (items.length === 0) return ''
421
- let section = `## ${heading}\n\n`
422
- for (const doc of items) {
423
- section += `### \`${doc.element.name}\`\n\n`
424
- if (doc.element.signature) {
425
- section += `\`\`\`ts\n${doc.element.signature}\n\`\`\`\n\n`
426
- }
427
- section += `${doc.documentation}\n\n`
428
- }
429
- return section
430
- }
431
-
432
- content += renderSection('Functions', functions)
433
- content += renderSection('Classes', classes)
434
- content += renderSection('Methods', methods)
435
-
436
- return content.trimEnd() + '\n'
437
- }
438
-
439
- // ---- Realistic sample data ----
440
- const sampleDocs: GeneratedDoc[] = [
441
- {
442
- element: {
443
- name: 'fetchUser',
444
- kind: 'function',
445
- signature: 'function fetchUser(id: string): Promise<User>',
446
- },
447
- documentation:
448
- 'Fetches a user record by ID from the remote API. Throws `NotFoundError` if the user does not exist.',
449
- },
450
- {
451
- element: {
452
- name: 'UserService',
453
- kind: 'class',
454
- signature: 'class UserService',
455
- },
456
- documentation:
457
- 'Provides high-level methods for managing user accounts, including creation, updates, and deletion.',
458
- },
459
- {
460
- element: {
461
- name: 'UserService.update',
462
- kind: 'method',
463
- signature: 'update(id: string, patch: Partial<User>): Promise<User>',
464
- },
465
- documentation:
466
- 'Applies a partial update to an existing user. Returns the updated user object.',
467
- },
468
- ]
469
-
470
- // ---- Run the example ----
471
- try {
472
- const markdown = formatAsMarkdown(sampleDocs, 'API Reference')
473
- console.log(markdown)
474
- /*
475
- Expected output:
476
- ─────────────────────────────────────────
477
- # API Reference
478
-
479
- ## Functions
480
-
481
- ### `fetchUser`
482
-
483
- ```ts
484
- function fetchUser(id: string): Promise<User>
485
- ```
486
-
487
- Fetches a user record by ID from the remote API. Throws `NotFoundError` if the user does not exist.
488
-
489
- ## Classes
490
-
491
- ### `UserService`
492
- ...
493
-
494
- ## Methods
495
-
496
- ### `UserService.update`
497
- ...
498
- ─────────────────────────────────────────
499
- */
500
- } catch (error) {
501
- console.error('formatAsMarkdown failed:', error)
502
- }
503
- ```
504
-