skrypt-ai 0.8.0 → 0.8.1

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 (101) hide show
  1. package/dist/auth/index.js +6 -0
  2. package/dist/binding/binder.d.ts +5 -0
  3. package/dist/binding/binder.js +63 -0
  4. package/dist/binding/detector.d.ts +5 -0
  5. package/dist/binding/detector.js +51 -0
  6. package/dist/binding/doc-parser.d.ts +9 -0
  7. package/dist/binding/doc-parser.js +138 -0
  8. package/dist/binding/extractor.d.ts +14 -0
  9. package/dist/binding/extractor.js +39 -0
  10. package/dist/binding/index.d.ts +5 -0
  11. package/dist/binding/index.js +5 -0
  12. package/dist/binding/types.d.ts +74 -0
  13. package/dist/binding/types.js +1 -0
  14. package/dist/claims/extractor.d.ts +13 -0
  15. package/dist/claims/extractor.js +138 -0
  16. package/dist/claims/index.d.ts +4 -0
  17. package/dist/claims/index.js +4 -0
  18. package/dist/claims/reporter.d.ts +9 -0
  19. package/dist/claims/reporter.js +65 -0
  20. package/dist/claims/store.d.ts +13 -0
  21. package/dist/claims/store.js +51 -0
  22. package/dist/claims/types.d.ts +34 -0
  23. package/dist/claims/types.js +1 -0
  24. package/dist/cli.js +516 -56
  25. package/dist/commands/bind.d.ts +2 -0
  26. package/dist/commands/bind.js +139 -0
  27. package/dist/commands/claims.d.ts +2 -0
  28. package/dist/commands/claims.js +84 -0
  29. package/dist/commands/coverage.d.ts +2 -0
  30. package/dist/commands/coverage.js +61 -0
  31. package/dist/commands/generate/index.js +5 -0
  32. package/dist/commands/generate/scan.js +33 -14
  33. package/dist/commands/generate/write.d.ts +7 -0
  34. package/dist/commands/generate/write.js +65 -1
  35. package/dist/commands/import.js +12 -3
  36. package/dist/commands/init.js +68 -5
  37. package/dist/commands/monitor.d.ts +15 -0
  38. package/dist/commands/monitor.js +2 -2
  39. package/dist/commands/mutate.d.ts +2 -0
  40. package/dist/commands/mutate.js +177 -0
  41. package/dist/config/types.js +2 -2
  42. package/dist/coverage/calculator.d.ts +7 -0
  43. package/dist/coverage/calculator.js +86 -0
  44. package/dist/coverage/index.d.ts +3 -0
  45. package/dist/coverage/index.js +3 -0
  46. package/dist/coverage/reporter.d.ts +9 -0
  47. package/dist/coverage/reporter.js +65 -0
  48. package/dist/coverage/types.d.ts +36 -0
  49. package/dist/coverage/types.js +1 -0
  50. package/dist/generator/generator.d.ts +3 -1
  51. package/dist/generator/generator.js +137 -23
  52. package/dist/generator/mdx-serializer.js +3 -2
  53. package/dist/generator/organizer.d.ts +5 -1
  54. package/dist/generator/organizer.js +29 -14
  55. package/dist/generator/types.d.ts +6 -0
  56. package/dist/generator/writer.js +7 -2
  57. package/dist/github/org-discovery.js +5 -0
  58. package/dist/importers/mintlify.js +4 -3
  59. package/dist/llm/anthropic-client.js +1 -0
  60. package/dist/llm/index.d.ts +15 -0
  61. package/dist/llm/index.js +148 -29
  62. package/dist/llm/openai-client.js +2 -0
  63. package/dist/mutation/index.d.ts +4 -0
  64. package/dist/mutation/index.js +4 -0
  65. package/dist/mutation/mutator.d.ts +5 -0
  66. package/dist/mutation/mutator.js +101 -0
  67. package/dist/mutation/reporter.d.ts +14 -0
  68. package/dist/mutation/reporter.js +66 -0
  69. package/dist/mutation/runner.d.ts +9 -0
  70. package/dist/mutation/runner.js +70 -0
  71. package/dist/mutation/types.d.ts +51 -0
  72. package/dist/mutation/types.js +1 -0
  73. package/dist/qa/checks.d.ts +1 -0
  74. package/dist/qa/checks.js +47 -0
  75. package/dist/qa/index.js +2 -1
  76. package/dist/scanner/index.js +78 -11
  77. package/dist/scanner/typescript.js +42 -31
  78. package/dist/sentry.d.ts +3 -0
  79. package/dist/sentry.js +28 -0
  80. package/dist/template/docs.json +6 -3
  81. package/dist/template/next.config.mjs +15 -1
  82. package/dist/template/package.json +4 -3
  83. package/dist/template/public/docs-schema.json +257 -0
  84. package/dist/template/sentry.client.config.ts +12 -0
  85. package/dist/template/sentry.edge.config.ts +7 -0
  86. package/dist/template/sentry.server.config.ts +7 -0
  87. package/dist/template/src/app/docs/[...slug]/page.tsx +11 -5
  88. package/dist/template/src/app/docs/layout.tsx +2 -4
  89. package/dist/template/src/app/global-error.tsx +60 -0
  90. package/dist/template/src/app/layout.tsx +7 -16
  91. package/dist/template/src/app/page.tsx +2 -5
  92. package/dist/template/src/components/ai-chat-impl.tsx +1 -1
  93. package/dist/template/src/components/docs-layout.tsx +1 -15
  94. package/dist/template/src/components/footer.tsx +95 -19
  95. package/dist/template/src/components/header.tsx +1 -1
  96. package/dist/template/src/components/search-dialog.tsx +5 -0
  97. package/dist/template/src/instrumentation.ts +11 -0
  98. package/dist/template/src/lib/docs-config.ts +235 -0
  99. package/dist/template/src/lib/fonts.ts +3 -3
  100. package/dist/testing/runner.js +8 -1
  101. package/package.json +2 -1
package/dist/cli.js CHANGED
@@ -1,32 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import { generateCommand } from './commands/generate/index.js';
4
- import { initCommand } from './commands/init.js';
5
- import { watchCommand } from './commands/watch.js';
6
- import { autofixCommand } from './commands/autofix.js';
7
- import { reviewPRCommand } from './commands/review-pr.js';
8
- import { lintCommand } from './commands/lint.js';
9
- import { qaCommand } from './commands/qa.js';
10
- import { checkLinksCommand } from './commands/check-links.js';
11
- import { mcpCommand } from './commands/mcp.js';
12
- import { versionCommand } from './commands/version.js';
13
- import { i18nCommand } from './commands/i18n.js';
14
- import { monitorCommand } from './commands/monitor.js';
15
- import { sdkCommand } from './commands/sdk.js';
16
- import { ghActionCommand } from './commands/gh-action.js';
17
- import { llmsTxtCommand } from './commands/llms-txt.js';
18
- import { loginCommand, logoutCommand, whoamiCommand } from './commands/login.js';
19
- import { cronCommand } from './commands/cron.js';
20
- import { deployCommand } from './commands/deploy.js';
21
- import { testCommand } from './commands/test.js';
22
- import { securityCommand } from './commands/security.js';
23
- import { importCommand } from './commands/import.js';
24
- import { healCommand } from './commands/heal.js';
25
- import { auditCommand } from './commands/audit.js';
26
- import { refreshCommand } from './commands/refresh.js';
27
- import { reviewCommand } from './commands/review.js';
28
- import { configCommand } from './commands/config.js';
29
- import { handlePostAction } from './next-actions/index.js';
30
3
  import { createRequire } from 'module';
31
4
  process.on('uncaughtException', (err) => {
32
5
  console.error('\x1b[31mFatal error:\x1b[0m', err.message);
@@ -42,6 +15,24 @@ process.on('unhandledRejection', (reason) => {
42
15
  });
43
16
  const require = createRequire(import.meta.url);
44
17
  const { version: VERSION } = require('../package.json');
18
+ /** Lazily initialize Sentry — called once on first real command invocation */
19
+ let sentryInitialized = false;
20
+ async function ensureSentry() {
21
+ if (sentryInitialized)
22
+ return;
23
+ sentryInitialized = true;
24
+ const { initSentry } = await import('./sentry.js');
25
+ initSentry();
26
+ }
27
+ /**
28
+ * Extract the action handler from a Commander Command instance.
29
+ * Commander stores it as `_actionHandler` (not in public types).
30
+ */
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ function getAction(cmd) {
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ return cmd._actionHandler;
35
+ }
45
36
  function semverNewer(latest, current) {
46
37
  const parse = (v) => v.split('.').map(Number);
47
38
  const [lMaj, lMin, lPatch] = parse(latest);
@@ -76,35 +67,504 @@ program
76
67
  .description('AI-powered documentation generator with code examples')
77
68
  .version(VERSION)
78
69
  .hook('postAction', async (_thisCommand, actionCommand) => {
70
+ const { handlePostAction } = await import('./next-actions/index.js');
79
71
  await handlePostAction(actionCommand.name());
80
72
  await checkForUpdates();
81
73
  });
82
- program.addCommand(initCommand);
83
- program.addCommand(generateCommand);
84
- program.addCommand(watchCommand);
85
- program.addCommand(autofixCommand);
86
- program.addCommand(reviewPRCommand);
87
- program.addCommand(lintCommand);
88
- program.addCommand(qaCommand);
89
- program.addCommand(checkLinksCommand);
90
- program.addCommand(mcpCommand);
91
- program.addCommand(versionCommand);
92
- program.addCommand(i18nCommand);
93
- program.addCommand(monitorCommand);
94
- program.addCommand(sdkCommand);
95
- program.addCommand(ghActionCommand);
96
- program.addCommand(llmsTxtCommand);
97
- program.addCommand(loginCommand);
98
- program.addCommand(logoutCommand);
99
- program.addCommand(whoamiCommand);
100
- program.addCommand(cronCommand);
101
- program.addCommand(deployCommand);
102
- program.addCommand(testCommand);
103
- program.addCommand(securityCommand);
104
- program.addCommand(importCommand);
105
- program.addCommand(healCommand);
106
- program.addCommand(auditCommand);
107
- program.addCommand(refreshCommand);
108
- program.addCommand(reviewCommand);
109
- program.addCommand(configCommand);
110
- program.parse();
74
+ // ── init ──────────────────────────────────────────────────────────────
75
+ program
76
+ .command('init')
77
+ .description('Initialize a new documentation site')
78
+ .argument('[directory]', 'Target directory', '.')
79
+ .option('--name <name>', 'Project name', 'my-docs')
80
+ .option('--color <hex>', 'Primary brand color (hex, e.g. "#FF5733")')
81
+ .option('--logo <url-or-path>', 'Logo URL or local file path')
82
+ .option('--favicon <url-or-path>', 'Favicon URL or local file path')
83
+ .action(async (directory, options) => {
84
+ await ensureSentry();
85
+ const mod = await import('./commands/init.js');
86
+ await getAction(mod.initCommand)(directory, options);
87
+ });
88
+ // ── generate ──────────────────────────────────────────────────────────
89
+ program
90
+ .command('generate')
91
+ .description('Generate documentation with code examples')
92
+ .argument('[sources...]', 'Source directories to scan (use dir:Label for labels)')
93
+ .option('-o, --output <dir>', 'Output directory')
94
+ .option('-c, --config <file>', 'Config file path')
95
+ .option('--provider <name>', 'LLM provider (deepseek, openai, anthropic, google, ollama, openrouter)')
96
+ .option('--model <name>', 'LLM model name')
97
+ .option('--base-url <url>', 'Custom API base URL (for Ollama or proxies)')
98
+ .option('--dry-run', 'Scan only, do not generate docs')
99
+ .option('--multi-lang', 'Generate TypeScript + Python examples')
100
+ .option('--by-topic', 'Organize output by topic instead of file')
101
+ .option('--openapi <file>', 'Include OpenAPI spec file for API Playground')
102
+ .option('--public-only', 'Only document exported/public APIs')
103
+ .option('--exclude <patterns...>', 'Exclude patterns (files, names, or name:pattern)')
104
+ .option('--llms-txt', 'Generate llms.txt for Answer Engine Optimization (AEO)')
105
+ .option('--project-name <name>', 'Project name for llms.txt header')
106
+ .option('--org <name>', 'GitHub organization to discover repos from')
107
+ .option('--repos <list>', 'Comma-separated list of repos to include (with --org)')
108
+ .option('--exclude-repos <list>', 'Comma-separated list of repos to exclude (with --org)')
109
+ .option('--verify', 'Verify generated code examples by running them (Pro)')
110
+ .option('--env-file <file>', 'Load environment variables for code verification')
111
+ .option('--smart-structure', 'Organize docs by user journey instead of file structure (Pro)')
112
+ .option('--max-verify-iterations <n>', 'Max re-generation attempts for failing snippets', '2')
113
+ .option('--no-agents-md', 'Skip AGENTS.md / CLAUDE.md generation')
114
+ .action(async (sources, options) => {
115
+ await ensureSentry();
116
+ const mod = await import('./commands/generate/index.js');
117
+ await getAction(mod.generateCommand)(sources, options);
118
+ });
119
+ // ── watch ─────────────────────────────────────────────────────────────
120
+ program
121
+ .command('watch')
122
+ .description('Watch source files and regenerate docs on changes')
123
+ .argument('[sources...]', 'Source directories to watch')
124
+ .option('-o, --output <dir>', 'Output directory')
125
+ .option('-c, --config <file>', 'Config file path')
126
+ .option('--provider <name>', 'LLM provider')
127
+ .option('--model <name>', 'LLM model name')
128
+ .option('--debounce <ms>', 'Debounce time in milliseconds', '1000')
129
+ .action(async (sources, options) => {
130
+ await ensureSentry();
131
+ const mod = await import('./commands/watch.js');
132
+ await getAction(mod.watchCommand)(sources, options);
133
+ });
134
+ // ── autofix ───────────────────────────────────────────────────────────
135
+ program
136
+ .command('autofix')
137
+ .description('Auto-fix broken code examples in documentation')
138
+ .argument('<file>', 'Documentation file to fix (markdown/mdx)')
139
+ .option('-c, --config <file>', 'Config file path')
140
+ .option('--provider <name>', 'LLM provider')
141
+ .option('--model <name>', 'LLM model')
142
+ .option('--max-iterations <n>', 'Max fix attempts per example', '3')
143
+ .option('--dry-run', 'Show fixes without writing')
144
+ .option('--language <lang>', 'Force language for validation')
145
+ .action(async (file, options) => {
146
+ await ensureSentry();
147
+ const mod = await import('./commands/autofix.js');
148
+ await getAction(mod.autofixCommand)(file, options);
149
+ });
150
+ // ── review-pr ─────────────────────────────────────────────────────────
151
+ program
152
+ .command('review-pr')
153
+ .description('Review a GitHub PR for documentation issues')
154
+ .argument('<pr-url>', 'GitHub PR URL (e.g., https://github.com/owner/repo/pull/123)')
155
+ .option('--inline', 'Post inline comments instead of a single comment')
156
+ .option('--dry-run', 'Show issues without posting comments')
157
+ .option('--token <token>', 'GitHub token (or use GITHUB_TOKEN env var)')
158
+ .action(async (prUrl, options) => {
159
+ await ensureSentry();
160
+ const mod = await import('./commands/review-pr.js');
161
+ await getAction(mod.reviewPRCommand)(prUrl, options);
162
+ });
163
+ // ── lint ──────────────────────────────────────────────────────────────
164
+ program
165
+ .command('lint')
166
+ .description('Lint documentation files for common issues')
167
+ .argument('[path]', 'Directory or file to lint', '.')
168
+ .option('--fix', 'Attempt to fix issues automatically')
169
+ .option('-c, --config <file>', 'Config file with custom rules')
170
+ .action(async (path, options) => {
171
+ await ensureSentry();
172
+ const mod = await import('./commands/lint.js');
173
+ await getAction(mod.lintCommand)(path, options);
174
+ });
175
+ // ── qa ────────────────────────────────────────────────────────────────
176
+ program
177
+ .command('qa')
178
+ .description('Run quality assurance checks on documentation')
179
+ .argument('<dir>', 'Documentation directory to check')
180
+ .option('--strict', 'Fail on warnings (not just errors)')
181
+ .option('--fix', 'Auto-fix safe issues before reporting')
182
+ .action(async (dir, options) => {
183
+ await ensureSentry();
184
+ const mod = await import('./commands/qa.js');
185
+ await getAction(mod.qaCommand)(dir, options);
186
+ });
187
+ // ── check-links ───────────────────────────────────────────────────────
188
+ program
189
+ .command('check-links')
190
+ .description('Check for broken links in documentation')
191
+ .argument('[path]', 'Directory to check', '.')
192
+ .option('--external', 'Also check external links (slower)')
193
+ .option('--timeout <ms>', 'Timeout for external links', '5000')
194
+ .action(async (path, options) => {
195
+ await ensureSentry();
196
+ const mod = await import('./commands/check-links.js');
197
+ await getAction(mod.checkLinksCommand)(path, options);
198
+ });
199
+ // ── mcp ───────────────────────────────────────────────────────────────
200
+ program
201
+ .command('mcp')
202
+ .description('Start MCP server for AI tools or generate MCP manifest')
203
+ .argument('[path]', 'Documentation directory', '.')
204
+ .option('-p, --port <port>', 'Server port', '3100')
205
+ .option('-h, --host <host>', 'Server host', 'localhost')
206
+ .option('-o, --output <file>', 'Output manifest to file instead of starting server')
207
+ .option('-t, --token <token>', 'Bearer token for authenticating MCP requests')
208
+ .action(async (path, options) => {
209
+ await ensureSentry();
210
+ const mod = await import('./commands/mcp.js');
211
+ await getAction(mod.mcpCommand)(path, options);
212
+ });
213
+ // ── version (subcommands) ─────────────────────────────────────────────
214
+ {
215
+ const versionCmd = program
216
+ .command('version')
217
+ .description('Manage documentation versions');
218
+ versionCmd.hook('preAction', async () => {
219
+ await ensureSentry();
220
+ });
221
+ versionCmd.hook('preSubcommand', async () => {
222
+ await ensureSentry();
223
+ });
224
+ versionCmd
225
+ .command('list')
226
+ .description('List all versions')
227
+ .argument('[docs-path]', 'Documentation directory', './docs')
228
+ .action(async (docsPath) => {
229
+ const mod = await import('./commands/version.js');
230
+ const cmd = mod.versionCommand.commands.find(c => c.name() === 'list');
231
+ await getAction(cmd)(docsPath);
232
+ });
233
+ versionCmd
234
+ .command('create')
235
+ .description('Create a new version from current docs')
236
+ .argument('<version>', 'Version name (e.g., v1, v2.0)')
237
+ .argument('[docs-path]', 'Documentation directory', './docs')
238
+ .option('--from <version>', 'Copy from existing version instead of current')
239
+ .action(async (version, docsPath, options) => {
240
+ const mod = await import('./commands/version.js');
241
+ const cmd = mod.versionCommand.commands.find(c => c.name() === 'create');
242
+ await getAction(cmd)(version, docsPath, options);
243
+ });
244
+ versionCmd
245
+ .command('set-current')
246
+ .description('Set the current/default version')
247
+ .argument('<version>', 'Version to set as current')
248
+ .argument('[docs-path]', 'Documentation directory', './docs')
249
+ .action(async (version, docsPath) => {
250
+ const mod = await import('./commands/version.js');
251
+ const cmd = mod.versionCommand.commands.find(c => c.name() === 'set-current');
252
+ await getAction(cmd)(version, docsPath);
253
+ });
254
+ versionCmd
255
+ .command('delete')
256
+ .description('Delete a version')
257
+ .argument('<version>', 'Version to delete')
258
+ .argument('[docs-path]', 'Documentation directory', './docs')
259
+ .option('--force', 'Skip confirmation')
260
+ .action(async (version, docsPath, options) => {
261
+ const mod = await import('./commands/version.js');
262
+ const cmd = mod.versionCommand.commands.find(c => c.name() === 'delete');
263
+ await getAction(cmd)(version, docsPath, options);
264
+ });
265
+ }
266
+ // ── i18n (subcommands) ────────────────────────────────────────────────
267
+ {
268
+ const i18nCmd = program
269
+ .command('i18n')
270
+ .description('Manage documentation translations');
271
+ i18nCmd.hook('preSubcommand', async () => {
272
+ await ensureSentry();
273
+ });
274
+ i18nCmd
275
+ .command('init')
276
+ .description('Initialize i18n for documentation')
277
+ .argument('[docs-path]', 'Documentation directory', './docs')
278
+ .option('--default <locale>', 'Default locale', 'en')
279
+ .action(async (docsPath, options) => {
280
+ const mod = await import('./commands/i18n.js');
281
+ const cmd = mod.i18nCommand.commands.find(c => c.name() === 'init');
282
+ await getAction(cmd)(docsPath, options);
283
+ });
284
+ i18nCmd
285
+ .command('add')
286
+ .description('Add a new locale')
287
+ .argument('<locale>', 'Locale code (e.g., ja, fr, de)')
288
+ .argument('[docs-path]', 'Documentation directory', './docs')
289
+ .action(async (locale, docsPath) => {
290
+ const mod = await import('./commands/i18n.js');
291
+ const cmd = mod.i18nCommand.commands.find(c => c.name() === 'add');
292
+ await getAction(cmd)(locale, docsPath);
293
+ });
294
+ i18nCmd
295
+ .command('status')
296
+ .description('Show translation status')
297
+ .argument('[docs-path]', 'Documentation directory', './docs')
298
+ .action(async (docsPath) => {
299
+ const mod = await import('./commands/i18n.js');
300
+ const cmd = mod.i18nCommand.commands.find(c => c.name() === 'status');
301
+ await getAction(cmd)(docsPath);
302
+ });
303
+ i18nCmd
304
+ .command('missing')
305
+ .description('List missing translations for a locale')
306
+ .argument('<locale>', 'Locale to check')
307
+ .argument('[docs-path]', 'Documentation directory', './docs')
308
+ .action(async (locale, docsPath) => {
309
+ const mod = await import('./commands/i18n.js');
310
+ const cmd = mod.i18nCommand.commands.find(c => c.name() === 'missing');
311
+ await getAction(cmd)(locale, docsPath);
312
+ });
313
+ i18nCmd
314
+ .command('extract')
315
+ .description('Extract strings for translation')
316
+ .argument('[docs-path]', 'Documentation directory', './docs')
317
+ .option('-o, --output <file>', 'Output file', 'strings.json')
318
+ .action(async (docsPath, options) => {
319
+ const mod = await import('./commands/i18n.js');
320
+ const cmd = mod.i18nCommand.commands.find(c => c.name() === 'extract');
321
+ await getAction(cmd)(docsPath, options);
322
+ });
323
+ }
324
+ // ── monitor ───────────────────────────────────────────────────────────
325
+ program
326
+ .command('monitor')
327
+ .description('Monitor codebase for changes and suggest documentation updates')
328
+ .argument('[repo-path]', 'Repository path', '.')
329
+ .option('--since <ref>', 'Git ref to compare against', 'HEAD~10')
330
+ .option('-o, --output <file>', 'Output suggestions to JSON file')
331
+ .option('--provider <name>', 'LLM provider')
332
+ .option('--model <name>', 'LLM model')
333
+ .option('--auto-fix', 'Automatically generate documentation for suggestions')
334
+ .option('--create-pr', 'Create a GitHub PR with changes')
335
+ .option('--dry-run', 'Show what would be done without making changes')
336
+ .action(async (repoPath, options) => {
337
+ await ensureSentry();
338
+ const mod = await import('./commands/monitor.js');
339
+ await getAction(mod.monitorCommand)(repoPath, options);
340
+ });
341
+ // ── sdk ───────────────────────────────────────────────────────────────
342
+ program
343
+ .command('sdk')
344
+ .description('Generate SDK code samples from OpenAPI spec')
345
+ .argument('<spec>', 'Path to OpenAPI/Swagger spec file (JSON or YAML)')
346
+ .option('-o, --output <dir>', 'Output directory', './docs/sdk')
347
+ .option('-l, --languages <list>', 'Languages to generate (comma-separated)', 'typescript,python,curl')
348
+ .option('--provider <name>', 'LLM provider for enhanced samples')
349
+ .option('--model <name>', 'LLM model')
350
+ .option('--format <type>', 'Output format (markdown or json)', 'markdown')
351
+ .action(async (specPath, options) => {
352
+ await ensureSentry();
353
+ const mod = await import('./commands/sdk.js');
354
+ await getAction(mod.sdkCommand)(specPath, options);
355
+ });
356
+ // ── gh-action ─────────────────────────────────────────────────────────
357
+ program
358
+ .command('gh-action')
359
+ .description('Generate GitHub Action workflow for documentation CI/CD')
360
+ .argument('[repo-path]', 'Repository path', '.')
361
+ .option('-f, --force', 'Overwrite existing workflow')
362
+ .action(async (repoPath, options) => {
363
+ await ensureSentry();
364
+ const mod = await import('./commands/gh-action.js');
365
+ await getAction(mod.ghActionCommand)(repoPath, options);
366
+ });
367
+ // ── llms-txt ──────────────────────────────────────────────────────────
368
+ program
369
+ .command('llms-txt')
370
+ .description('Generate llms.txt and llms-full.txt for AI discoverability')
371
+ .argument('[docs-path]', 'Path to documentation directory', './docs')
372
+ .option('-o, --output <dir>', 'Output directory', './public')
373
+ .option('--base-url <url>', 'Base URL for documentation', 'https://docs.example.com')
374
+ .option('--title <title>', 'Documentation title', 'Documentation')
375
+ .option('--description <desc>', 'Documentation description', 'API and usage documentation')
376
+ .action(async (docsPath, options) => {
377
+ await ensureSentry();
378
+ const mod = await import('./commands/llms-txt.js');
379
+ await getAction(mod.llmsTxtCommand)(docsPath, options);
380
+ });
381
+ // ── login ─────────────────────────────────────────────────────────────
382
+ program
383
+ .command('login')
384
+ .description('Login to Skrypt Pro')
385
+ .option('--key <api-key>', 'API key (or set SKRYPT_API_KEY env var)')
386
+ .action(async (options) => {
387
+ await ensureSentry();
388
+ const mod = await import('./commands/login.js');
389
+ await getAction(mod.loginCommand)(options);
390
+ });
391
+ // ── logout ────────────────────────────────────────────────────────────
392
+ program
393
+ .command('logout')
394
+ .description('Logout from Skrypt')
395
+ .action(async () => {
396
+ await ensureSentry();
397
+ const mod = await import('./commands/login.js');
398
+ await getAction(mod.logoutCommand)();
399
+ });
400
+ // ── whoami ────────────────────────────────────────────────────────────
401
+ program
402
+ .command('whoami')
403
+ .description('Show current login status')
404
+ .action(async () => {
405
+ await ensureSentry();
406
+ const mod = await import('./commands/login.js');
407
+ await getAction(mod.whoamiCommand)();
408
+ });
409
+ // ── cron ──────────────────────────────────────────────────────────────
410
+ program
411
+ .command('cron')
412
+ .description('Set up automated documentation updates with GitHub Actions')
413
+ .argument('[repo-path]', 'Repository path', '.')
414
+ .option('-s, --schedule <cron>', 'Cron schedule (default: daily at 2am UTC)', '0 2 * * *')
415
+ .option('-f, --force', 'Overwrite existing workflow')
416
+ .action(async (repoPath, options) => {
417
+ await ensureSentry();
418
+ const mod = await import('./commands/cron.js');
419
+ await getAction(mod.cronCommand)(repoPath, options);
420
+ });
421
+ // ── deploy ────────────────────────────────────────────────────────────
422
+ program
423
+ .command('deploy')
424
+ .description('Deploy documentation site to Skrypt hosting')
425
+ .argument('[directory]', 'Documentation site directory', '.')
426
+ .option('--project <slug>', 'Project slug (e.g., my-docs)')
427
+ .option('--token <key>', 'API token (or set SKRYPT_API_KEY env var)')
428
+ .action(async (directory, options) => {
429
+ await ensureSentry();
430
+ const mod = await import('./commands/deploy.js');
431
+ await getAction(mod.deployCommand)(directory, options);
432
+ });
433
+ // ── test ──────────────────────────────────────────────────────────────
434
+ program
435
+ .command('test')
436
+ .description('Test code examples in documentation files')
437
+ .argument('[path]', 'Directory or file to test', '.')
438
+ .option('-f, --file <file>', 'Test a specific file or directory')
439
+ .option('-l, --language <lang>', 'Filter by language (typescript, javascript, python)')
440
+ .option('--fix', 'Auto-fix failing examples using autofix command')
441
+ .option('-t, --timeout <ms>', 'Timeout per code block in milliseconds', '10000')
442
+ .option('-v, --verbose', 'Show detailed output')
443
+ .option('--verify-output', 'Compare stdout against // Output: comments')
444
+ .option('--env-file <file>', 'Load environment variables from file')
445
+ .option('--environments <list>', 'Comma-separated Docker environments (e.g. node-20,python-3.12)')
446
+ .action(async (path, options) => {
447
+ await ensureSentry();
448
+ const mod = await import('./commands/test.js');
449
+ await getAction(mod.testCommand)(path, options);
450
+ });
451
+ // ── security ──────────────────────────────────────────────────────────
452
+ program
453
+ .command('security')
454
+ .description('Show security and key storage details')
455
+ .action(async () => {
456
+ await ensureSentry();
457
+ const mod = await import('./commands/security.js');
458
+ await getAction(mod.securityCommand)();
459
+ });
460
+ // ── import ────────────────────────────────────────────────────────────
461
+ program
462
+ .command('import')
463
+ .description('Import documentation from another platform')
464
+ .argument('<source>', 'Local directory or GitHub URL')
465
+ .option('--from <format>', 'Source format (mintlify, docusaurus, gitbook, readme, notion, confluence, markdown)')
466
+ .option('-o, --output <dir>', 'Output directory')
467
+ .option('--dry-run', 'Show what would be imported without writing files')
468
+ .option('--name <name>', 'Project name')
469
+ .action(async (source, options) => {
470
+ await ensureSentry();
471
+ const mod = await import('./commands/import.js');
472
+ await getAction(mod.importCommand)(source, options);
473
+ });
474
+ // ── heal ──────────────────────────────────────────────────────────────
475
+ program
476
+ .command('heal')
477
+ .description('Self-heal documentation: fix QA issues, broken code, and capture screenshots')
478
+ .argument('[docs-dir]', 'Documentation directory', '.')
479
+ .option('--base-url <url>', 'Base URL for screenshot capture', 'http://localhost:3000')
480
+ .option('--output <dir>', 'Screenshot output directory', 'public/screenshots')
481
+ .option('--viewport <size>', 'Viewport WxH', '1280x720')
482
+ .option('--dark', 'Also capture dark mode variants')
483
+ .option('--diff', 'Only re-capture changed screenshots')
484
+ .option('--screenshots', 'Run screenshot capture phase')
485
+ .option('--qa-only', 'Run only QA fix phase')
486
+ .option('--code-only', 'Run only code fix phase')
487
+ .option('--deep', 'Run all 3 phases')
488
+ .option('--dry-run', 'Show what would change without writing')
489
+ .option('--timeout <ms>', 'Page load timeout', '30000')
490
+ .option('--wait <ms>', 'Wait after page load', '1000')
491
+ .option('--device <name>', 'Emulate device (e.g. "iPhone 14")')
492
+ .option('--concurrency <n>', 'Parallel capture limit', '3')
493
+ .option('--provider <name>', 'LLM provider (for code fix phase)')
494
+ .option('--model <name>', 'LLM model (for code fix phase)')
495
+ .option('--max-iterations <n>', 'Max fix attempts per code example', '3')
496
+ .option('-c, --config <file>', 'Config file path')
497
+ .action(async (docsDir, options) => {
498
+ await ensureSentry();
499
+ const mod = await import('./commands/heal.js');
500
+ await getAction(mod.healCommand)(docsDir, options);
501
+ });
502
+ // ── audit ─────────────────────────────────────────────────────────────
503
+ program
504
+ .command('audit')
505
+ .description('Audit documentation coverage and staleness')
506
+ .argument('[source]', 'Source code directory to audit', '.')
507
+ .option('--docs <dir>', 'Documentation directory to compare against', './docs')
508
+ .option('--format <type>', 'Output format: text or json', 'text')
509
+ .option('--public-only', 'Only audit exported/public APIs')
510
+ .action(async (source, options) => {
511
+ await ensureSentry();
512
+ const mod = await import('./commands/audit.js');
513
+ await getAction(mod.auditCommand)(source, options);
514
+ });
515
+ // ── refresh ───────────────────────────────────────────────────────────
516
+ program
517
+ .command('refresh')
518
+ .description('Refresh stale documentation based on code changes')
519
+ .argument('[source]', 'Source code directory', '.')
520
+ .option('--docs <dir>', 'Documentation directory', './docs')
521
+ .option('--since <ref>', 'Git ref to compare against (e.g. HEAD~3, 2026-03-01)', 'HEAD~1')
522
+ .option('-c, --config <file>', 'Config file path')
523
+ .option('--provider <name>', 'LLM provider')
524
+ .option('--model <name>', 'LLM model name')
525
+ .action(async (source, options) => {
526
+ await ensureSentry();
527
+ const mod = await import('./commands/refresh.js');
528
+ await getAction(mod.refreshCommand)(source, options);
529
+ });
530
+ // ── review ────────────────────────────────────────────────────────────
531
+ program
532
+ .command('review')
533
+ .description('Incorporate feedback into documentation')
534
+ .argument('[docs]', 'Documentation directory', './docs')
535
+ .option('--feedback <file>', 'Feedback file (markdown format)')
536
+ .option('--inline', 'Process <!-- FIXME: --> and <!-- TODO: --> comments in docs')
537
+ .option('-c, --config <file>', 'Config file path')
538
+ .option('--provider <name>', 'LLM provider')
539
+ .option('--model <name>', 'LLM model name')
540
+ .action(async (docs, options) => {
541
+ await ensureSentry();
542
+ const mod = await import('./commands/review.js');
543
+ await getAction(mod.reviewCommand)(docs, options);
544
+ });
545
+ // ── config ────────────────────────────────────────────────────────────
546
+ program
547
+ .command('config')
548
+ .description('Configure Skrypt preferences')
549
+ .option('--suggestions', 'Configure next-step suggestions')
550
+ .option('--suggestions-on', 'Enable next-step suggestions')
551
+ .option('--suggestions-off', 'Disable next-step suggestions')
552
+ .action(async (options) => {
553
+ await ensureSentry();
554
+ const mod = await import('./commands/config.js');
555
+ await getAction(mod.configCommand)(options);
556
+ });
557
+ try {
558
+ await program.parseAsync();
559
+ }
560
+ catch (err) {
561
+ try {
562
+ const { Sentry } = await import('./sentry.js');
563
+ Sentry.captureException(err);
564
+ await Sentry.flush(2000);
565
+ }
566
+ catch {
567
+ // Sentry may not be available
568
+ }
569
+ throw err;
570
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const bindCommand: Command;