skrypt-ai 0.3.3 → 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 (97) 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 +3 -1
  25. package/dist/template/package.json +17 -14
  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 +141 -14
  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 +57 -7
  63. package/dist/template/src/app/not-found.tsx +35 -0
  64. package/dist/template/src/app/page.tsx +95 -11
  65. package/dist/template/src/components/ai-chat.tsx +26 -21
  66. package/dist/template/src/components/breadcrumbs.tsx +56 -12
  67. package/dist/template/src/components/copy-button.tsx +17 -3
  68. package/dist/template/src/components/docs-layout.tsx +202 -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 +56 -20
  72. package/dist/template/src/components/mdx/accordion.tsx +17 -13
  73. package/dist/template/src/components/mdx/callout.tsx +50 -37
  74. package/dist/template/src/components/mdx/card.tsx +24 -12
  75. package/dist/template/src/components/mdx/code-block.tsx +17 -3
  76. package/dist/template/src/components/mdx/code-group.tsx +78 -18
  77. package/dist/template/src/components/mdx/code-playground.tsx +3 -0
  78. package/dist/template/src/components/mdx/go-playground.tsx +3 -0
  79. package/dist/template/src/components/mdx/highlighted-code.tsx +178 -38
  80. package/dist/template/src/components/mdx/python-playground.tsx +2 -0
  81. package/dist/template/src/components/mdx/steps.tsx +6 -6
  82. package/dist/template/src/components/mdx/tabs.tsx +76 -8
  83. package/dist/template/src/components/page-header.tsx +19 -0
  84. package/dist/template/src/components/scroll-to-top.tsx +33 -0
  85. package/dist/template/src/components/search-dialog.tsx +251 -57
  86. package/dist/template/src/components/sidebar.tsx +137 -77
  87. package/dist/template/src/components/table-of-contents.tsx +29 -13
  88. package/dist/template/src/lib/highlight.ts +90 -31
  89. package/dist/template/src/lib/search.ts +14 -4
  90. package/dist/template/src/lib/theme-utils.ts +140 -0
  91. package/dist/template/src/styles/globals.css +397 -84
  92. package/dist/template/src/types/remark-gfm.d.ts +2 -0
  93. package/dist/utils/files.d.ts +9 -0
  94. package/dist/utils/files.js +33 -0
  95. package/dist/utils/validation.d.ts +4 -0
  96. package/dist/utils/validation.js +38 -0
  97. package/package.json +1 -4
@@ -0,0 +1,502 @@
1
+ ## Functions
2
+
3
+ ### `postPRComment`
4
+
5
+ ```typescript
6
+ async function postPRComment(config: PRCommentConfig, issues: DocumentationIssue[]): Promise<CommentResult>
7
+ ```
8
+
9
+ Use this to automatically post documentation issue summaries as review comments on GitHub Pull Requests — ideal for CI pipelines that lint or validate docs on every PR.
10
+
11
+ #### Parameters
12
+
13
+ | Name | Type | Required | Description |
14
+ |------|------|----------|-------------|
15
+ | `config` | `PRCommentConfig` | Yes | GitHub connection details including repo owner, repo name, PR number, and optional auth token |
16
+ | `issues` | `DocumentationIssue[]` | Yes | Array of documentation issues to summarize in the PR comment |
17
+
18
+ ## `PRCommentConfig` Fields
19
+
20
+ | Field | Type | Required | Description |
21
+ |-------|------|----------|-------------|
22
+ | `owner` | `string` | Yes | GitHub repository owner (user or org) |
23
+ | `repo` | `string` | Yes | Repository name |
24
+ | `prNumber` | `number` | Yes | Pull request number to comment on |
25
+ | `token` | `string` | No | GitHub personal access token. Falls back to `GITHUB_TOKEN` environment variable |
26
+
27
+ ## `DocumentationIssue` Fields
28
+
29
+ | Field | Type | Required | Description |
30
+ |-------|------|----------|-------------|
31
+ | `file` | `string` | Yes | Path to the file with the issue |
32
+ | `line` | `number` | No | Line number where the issue occurs |
33
+ | `message` | `string` | Yes | Human-readable description of the issue |
34
+ | `severity` | `'error' \| 'warning'` | Yes | Severity level of the issue |
35
+
36
+ #### Returns
37
+
38
+ Returns a `Promise<CommentResult>` that resolves with:
39
+
40
+ | Field | Type | Description |
41
+ |-------|------|-------------|
42
+ | `success` | `boolean` | Whether the comment was posted successfully |
43
+ | `commentId` | `number` | The GitHub comment ID of the newly created comment |
44
+ | `url` | `string` | Direct URL to the posted comment on GitHub |
45
+
46
+ Throws an error if the GitHub API request fails (e.g., invalid token, repo not found, insufficient permissions).
47
+
48
+ **Example:**
49
+
50
+ ```typescript example.ts
51
+ // ── Inline types (no external imports needed) ──────────────────────────────
52
+
53
+ type PRCommentConfig = {
54
+ owner: string
55
+ repo: string
56
+ prNumber: number
57
+ token?: string
58
+ }
59
+
60
+ type DocumentationIssue = {
61
+ file: string
62
+ line?: number
63
+ message: string
64
+ severity: 'error' | 'warning'
65
+ }
66
+
67
+ type CommentResult = {
68
+ success: boolean
69
+ commentId: number
70
+ url: string
71
+ }
72
+
73
+ // ── Self-contained implementation ──────────────────────────────────────────
74
+
75
+ const GITHUB_API = 'https://api.github.com'
76
+
77
+ async function postPRComment(
78
+ config: PRCommentConfig,
79
+ issues: DocumentationIssue[]
80
+ ): Promise<CommentResult> {
81
+ const token = config.token || process.env.GITHUB_TOKEN
82
+
83
+ if (!token) {
84
+ throw new Error(
85
+ 'GitHub token is required. Set GITHUB_TOKEN env var or pass config.token.'
86
+ )
87
+ }
88
+
89
+ // Build a readable markdown summary of all issues
90
+ const errorCount = issues.filter((i) => i.severity === 'error').length
91
+ const warnCount = issues.filter((i) => i.severity === 'warning').length
92
+
93
+ const issueLines = issues
94
+ .map((issue) => {
95
+ const location = issue.line ? `${issue.file}:${issue.line}` : issue.file
96
+ const icon = issue.severity === 'error' ? '🔴' : '🟡'
97
+ return `- ${icon} **${location}** — ${issue.message}`
98
+ })
99
+ .join('\n')
100
+
101
+ const body = [
102
+ '## 📄 Documentation Review',
103
+ '',
104
+ `Found **${errorCount} error(s)** and **${warnCount} warning(s)**.`,
105
+ '',
106
+ issueLines,
107
+ '',
108
+ '_Posted automatically by autodocs._',
109
+ ].join('\n')
110
+
111
+ const url = `${GITHUB_API}/repos/${config.owner}/${config.repo}/issues/${config.prNumber}/comments`
112
+
113
+ const response = await fetch(url, {
114
+ method: 'POST',
115
+ headers: {
116
+ Authorization: `Bearer ${token}`,
117
+ Accept: 'application/vnd.github+json',
118
+ 'Content-Type': 'application/json',
119
+ },
120
+ body: JSON.stringify({ body }),
121
+ })
122
+
123
+ if (!response.ok) {
124
+ const errorText = await response.text()
125
+ throw new Error(
126
+ `GitHub API error ${response.status}: ${errorText}`
127
+ )
128
+ }
129
+
130
+ const data = (await response.json()) as { id: number; html_url: string }
131
+
132
+ return {
133
+ success: true,
134
+ commentId: data.id,
135
+ url: data.html_url,
136
+ }
137
+ }
138
+
139
+ // ── Usage example ──────────────────────────────────────────────────────────
140
+
141
+ const config: PRCommentConfig = {
142
+ owner: 'acme-corp',
143
+ repo: 'platform-api',
144
+ prNumber: 42,
145
+ token: process.env.GITHUB_TOKEN || 'ghp_your_personal_access_token',
146
+ }
147
+
148
+ const issues: DocumentationIssue[] = [
149
+ {
150
+ file: 'src/auth/login.ts',
151
+ line: 14,
152
+ message: 'Missing JSDoc for exported function `loginUser`',
153
+ severity: 'error',
154
+ },
155
+ {
156
+ file: 'src/utils/format.ts',
157
+ line: 88,
158
+ message: '`@param` description is empty',
159
+ severity: 'warning',
160
+ },
161
+ {
162
+ file: 'README.md',
163
+ message: 'No usage examples found in README',
164
+ severity: 'warning',
165
+ },
166
+ ]
167
+
168
+ async function main() {
169
+ try {
170
+ const result = await postPRComment(config, issues)
171
+
172
+ console.log('Comment posted successfully!')
173
+ console.log('Comment ID:', result.commentId)
174
+ console.log('View it at:', result.url)
175
+ // Expected output:
176
+ // Comment posted successfully!
177
+ // Comment ID: 1987654321
178
+ // View it at: https://github.com/acme-corp/platform-api/pull/42#issuecomment-1987654321
179
+ } catch (error) {
180
+ console.error('Failed to post PR comment:', error)
181
+ // Common causes:
182
+ // - Invalid or expired GITHUB_TOKEN
183
+ // - Bot lacks write access to the repository
184
+ // - PR number does not exist
185
+ }
186
+ }
187
+
188
+ main()
189
+ ```
190
+
191
+ ### `postInlineComments`
192
+
193
+ ```typescript
194
+ async function postInlineComments(config: PRCommentConfig, issues: DocumentationIssue[]): Promise<CommentResult[]>
195
+ ```
196
+
197
+ Use this to post inline review comments on specific lines of a pull request, flagging documentation issues directly in the GitHub code review interface.
198
+
199
+ This function iterates over a list of documentation issues and attaches each as an inline comment to the relevant file and line in a PR — ideal for automated doc linters, CI checks, or code review bots.
200
+
201
+ #### Parameters
202
+
203
+ | Name | Type | Required | Description |
204
+ |------|------|----------|-------------|
205
+ | `config` | `PRCommentConfig` | Yes | PR targeting config including `token`, `owner`, `repo`, `pullNumber`, and `commitSha` |
206
+ | `issues` | `DocumentationIssue[]` | Yes | Array of documentation issues, each with a `file`, `line`, and `message` to post as an inline comment |
207
+
208
+ #### Returns
209
+
210
+ **`Promise<CommentResult[]>`** — Resolves to an array of results, one per issue. Each `CommentResult` contains:
211
+
212
+ | Field | Type | Description |
213
+ |-------|------|-------------|
214
+ | `success` | `boolean` | Whether the comment was posted successfully |
215
+ | `commentId` | `number \| undefined` | GitHub comment ID if successful |
216
+ | `error` | `string \| undefined` | Error message if the post failed |
217
+
218
+ Returns an empty array if `issues` is empty. Individual entries may have `success: false` if a specific comment failed (e.g., invalid line number or file path), without aborting the rest.
219
+
220
+ **Example:**
221
+
222
+ ```typescript example.ts
223
+ // ── Inline type definitions (no external imports needed) ──────────────────────
224
+
225
+ type PRCommentConfig = {
226
+ token?: string
227
+ owner: string
228
+ repo: string
229
+ pullNumber: number
230
+ commitSha: string
231
+ }
232
+
233
+ type DocumentationIssue = {
234
+ file: string
235
+ line: number
236
+ message: string
237
+ }
238
+
239
+ type CommentResult = {
240
+ success: boolean
241
+ commentId?: number
242
+ error?: string
243
+ }
244
+
245
+ // ── Simulated implementation of postInlineComments ───────────────────────────
246
+
247
+ async function postInlineComments(
248
+ config: PRCommentConfig,
249
+ issues: DocumentationIssue[]
250
+ ): Promise<CommentResult[]> {
251
+ const token = config.token || process.env.GITHUB_TOKEN
252
+
253
+ if (!token) {
254
+ throw new Error('GitHub token is required (set GITHUB_TOKEN or pass config.token)')
255
+ }
256
+
257
+ const results: CommentResult[] = []
258
+
259
+ for (const issue of issues) {
260
+ try {
261
+ // Simulate a GitHub API call to POST /repos/{owner}/{repo}/pulls/{pull_number}/comments
262
+ const apiUrl = `https://api.github.com/repos/${config.owner}/${config.repo}/pulls/${config.pullNumber}/comments`
263
+
264
+ console.log(`[POST] ${apiUrl}`)
265
+ console.log(` → File: ${issue.file}, Line: ${issue.line}`)
266
+ console.log(` → Comment: "${issue.message}"`)
267
+
268
+ // Simulate a successful response (replace with real fetch in production)
269
+ const simulatedResponse = {
270
+ id: Math.floor(Math.random() * 900000) + 100000,
271
+ body: issue.message,
272
+ path: issue.file,
273
+ line: issue.line,
274
+ }
275
+
276
+ results.push({
277
+ success: true,
278
+ commentId: simulatedResponse.id,
279
+ })
280
+ } catch (err) {
281
+ results.push({
282
+ success: false,
283
+ error: err instanceof Error ? err.message : String(err),
284
+ })
285
+ }
286
+ }
287
+
288
+ return results
289
+ }
290
+
291
+ // ── Example usage ─────────────────────────────────────────────────────────────
292
+
293
+ const prConfig: PRCommentConfig = {
294
+ token: process.env.GITHUB_TOKEN || 'ghp_your_token_here',
295
+ owner: 'acme-corp',
296
+ repo: 'backend-api',
297
+ pullNumber: 42,
298
+ commitSha: 'a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2',
299
+ }
300
+
301
+ const documentationIssues: DocumentationIssue[] = [
302
+ {
303
+ file: 'src/auth/login.ts',
304
+ line: 18,
305
+ message: 'Missing JSDoc comment for exported function `validateToken`.',
306
+ },
307
+ {
308
+ file: 'src/utils/format.ts',
309
+ line: 45,
310
+ message: '`@param` description is empty for parameter `options`.',
311
+ },
312
+ {
313
+ file: 'src/models/user.ts',
314
+ line: 72,
315
+ message: 'Exported interface `UserProfile` has no documentation block.',
316
+ },
317
+ ]
318
+
319
+ async function main() {
320
+ try {
321
+ console.log(`Posting ${documentationIssues.length} inline comment(s) to PR #${prConfig.pullNumber}...\n`)
322
+
323
+ const results = await postInlineComments(prConfig, documentationIssues)
324
+
325
+ results.forEach((result, index) => {
326
+ const issue = documentationIssues[index]
327
+ if (result.success) {
328
+ console.log(`✅ Comment posted on ${issue.file}:${issue.line} (ID: ${result.commentId})`)
329
+ } else {
330
+ console.error(`❌ Failed on ${issue.file}:${issue.line} — ${result.error}`)
331
+ }
332
+ })
333
+
334
+ const successCount = results.filter(r => r.success).length
335
+ console.log(`\nSummary: ${successCount}/${results.length} comments posted successfully.`)
336
+
337
+ // Expected output:
338
+ // Posting 3 inline comment(s) to PR #42...
339
+ //
340
+ // [POST] https://api.github.com/repos/acme-corp/backend-api/pulls/42/comments
341
+ // → File: src/auth/login.ts, Line: 18
342
+ // → Comment: "Missing JSDoc comment for exported function `validateToken`."
343
+ // ✅ Comment posted on src/auth/login.ts:18 (ID: 583921)
344
+ // ... (repeated for each issue)
345
+ // Summary: 3/3 comments posted successfully.
346
+ } catch (error) {
347
+ console.error('Fatal error posting inline comments:', error)
348
+ process.exit(1)
349
+ }
350
+ }
351
+
352
+ main()
353
+ ```
354
+
355
+ ### `analyzePRForDocs`
356
+
357
+ ```typescript
358
+ async function analyzePRForDocs(config: PRCommentConfig, _options: { checkExamples?: boolean } = {}): Promise<DocumentationIssue[]>
359
+ ```
360
+
361
+ Use this to scan a pull request for documentation issues — missing docstrings, undocumented parameters, or incomplete return type descriptions — and get a structured list of problems to act on.
362
+
363
+ Accepts a `PRCommentConfig` object describing the GitHub PR to analyze, plus optional flags to control analysis depth. Returns a list of `DocumentationIssue` objects, each describing a specific documentation problem found in the PR's changed files.
364
+
365
+ ### Parameters
366
+
367
+ | Name | Type | Required | Description |
368
+ |------|------|----------|-------------|
369
+ | `config` | `PRCommentConfig` | Yes | GitHub PR connection details including repo owner, repo name, PR number, and auth token |
370
+ | `config.token` | `string` | No | GitHub personal access token. Falls back to `GITHUB_TOKEN` environment variable |
371
+ | `config.owner` | `string` | Yes | GitHub repository owner (user or org) |
372
+ | `config.repo` | `string` | Yes | Repository name |
373
+ | `config.prNumber` | `number` | Yes | Pull request number to analyze |
374
+ | `_options` | `object` | No | Additional analysis options |
375
+ | `_options.checkExamples` | `boolean` | No | When `true`, also validates that code examples in docstrings are present and well-formed |
376
+
377
+ #### Returns
378
+
379
+ `Promise<DocumentationIssue[]>` — Resolves to an array of documentation issues found in the PR. Each issue describes the file, location, and nature of the documentation problem. Returns an empty array if no issues are found.
380
+
381
+ **Example:**
382
+
383
+ ```typescript example.ts
384
+ // --- Inline types (do not import from autodocs) ---
385
+ type PRCommentConfig = {
386
+ token?: string
387
+ owner: string
388
+ repo: string
389
+ prNumber: number
390
+ }
391
+
392
+ type DocumentationIssue = {
393
+ file: string
394
+ line: number
395
+ severity: 'error' | 'warning' | 'info'
396
+ message: string
397
+ rule: string
398
+ }
399
+
400
+ // --- Simulated implementation of analyzePRForDocs ---
401
+ async function analyzePRForDocs(
402
+ config: PRCommentConfig,
403
+ _options: { checkExamples?: boolean } = {}
404
+ ): Promise<DocumentationIssue[]> {
405
+ const token = config.token || process.env.GITHUB_TOKEN
406
+
407
+ if (!token) {
408
+ throw new Error(
409
+ 'GitHub token is required. Set GITHUB_TOKEN env var or pass config.token.'
410
+ )
411
+ }
412
+
413
+ // Simulate fetching PR diff and analyzing changed files
414
+ console.log(
415
+ `Analyzing PR #${config.prNumber} in ${config.owner}/${config.repo}...`
416
+ )
417
+
418
+ // Simulated issues found in the PR
419
+ const issues: DocumentationIssue[] = [
420
+ {
421
+ file: 'src/payments/charge.ts',
422
+ line: 14,
423
+ severity: 'error',
424
+ message: 'Exported function `chargeCustomer` is missing a docstring.',
425
+ rule: 'require-jsdoc',
426
+ },
427
+ {
428
+ file: 'src/payments/charge.ts',
429
+ line: 14,
430
+ severity: 'warning',
431
+ message: 'Parameter `amount` is not documented.',
432
+ rule: 'require-param-docs',
433
+ },
434
+ {
435
+ file: 'src/utils/format.ts',
436
+ line: 42,
437
+ severity: 'warning',
438
+ message: 'Return type for `formatCurrency` is not documented.',
439
+ rule: 'require-returns-docs',
440
+ },
441
+ ]
442
+
443
+ if (_options.checkExamples) {
444
+ issues.push({
445
+ file: 'src/payments/charge.ts',
446
+ line: 14,
447
+ severity: 'info',
448
+ message: 'No usage example found in docstring for `chargeCustomer`.',
449
+ rule: 'require-example',
450
+ })
451
+ }
452
+
453
+ return issues
454
+ }
455
+
456
+ // --- Usage ---
457
+ async function main() {
458
+ try {
459
+ const issues = await analyzePRForDocs(
460
+ {
461
+ token: process.env.GITHUB_TOKEN || 'ghp_your_token_here',
462
+ owner: 'acme-corp',
463
+ repo: 'payments-service',
464
+ prNumber: 247,
465
+ },
466
+ { checkExamples: true }
467
+ )
468
+
469
+ if (issues.length === 0) {
470
+ console.log('✅ No documentation issues found.')
471
+ return
472
+ }
473
+
474
+ console.log(`Found ${issues.length} documentation issue(s):\n`)
475
+
476
+ for (const issue of issues) {
477
+ const icon = issue.severity === 'error' ? '❌' : issue.severity === 'warning' ? '⚠️' : 'ℹ️'
478
+ console.log(`${icon} [${issue.severity.toUpperCase()}] ${issue.file}:${issue.line}`)
479
+ console.log(` ${issue.message}`)
480
+ console.log(` Rule: ${issue.rule}\n`)
481
+ }
482
+
483
+ // Expected output:
484
+ // Found 4 documentation issue(s):
485
+ //
486
+ // ❌ [ERROR] src/payments/charge.ts:14
487
+ // Exported function `chargeCustomer` is missing a docstring.
488
+ // Rule: require-jsdoc
489
+ //
490
+ // ⚠️ [WARNING] src/payments/charge.ts:14
491
+ // Parameter `amount` is not documented.
492
+ // Rule: require-param-docs
493
+ // ...
494
+ } catch (error) {
495
+ console.error('Analysis failed:', error instanceof Error ? error.message : error)
496
+ process.exit(1)
497
+ }
498
+ }
499
+
500
+ main()
501
+ ```
502
+