skrypt-ai 0.4.2 → 0.6.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 (159) hide show
  1. package/dist/auth/index.d.ts +13 -3
  2. package/dist/auth/index.js +101 -9
  3. package/dist/auth/keychain.d.ts +5 -0
  4. package/dist/auth/keychain.js +82 -0
  5. package/dist/auth/notices.d.ts +3 -0
  6. package/dist/auth/notices.js +42 -0
  7. package/dist/autofix/index.d.ts +0 -4
  8. package/dist/autofix/index.js +10 -24
  9. package/dist/capture/browser.d.ts +11 -0
  10. package/dist/capture/browser.js +173 -0
  11. package/dist/capture/diff.d.ts +23 -0
  12. package/dist/capture/diff.js +52 -0
  13. package/dist/capture/index.d.ts +23 -0
  14. package/dist/capture/index.js +210 -0
  15. package/dist/capture/naming.d.ts +17 -0
  16. package/dist/capture/naming.js +45 -0
  17. package/dist/capture/parser.d.ts +15 -0
  18. package/dist/capture/parser.js +80 -0
  19. package/dist/capture/types.d.ts +57 -0
  20. package/dist/capture/types.js +1 -0
  21. package/dist/cli.js +20 -3
  22. package/dist/commands/autofix.js +136 -120
  23. package/dist/commands/cron.js +58 -47
  24. package/dist/commands/deploy.js +123 -102
  25. package/dist/commands/generate.js +125 -7
  26. package/dist/commands/heal.d.ts +10 -0
  27. package/dist/commands/heal.js +201 -0
  28. package/dist/commands/i18n.js +146 -111
  29. package/dist/commands/import.d.ts +2 -0
  30. package/dist/commands/import.js +157 -0
  31. package/dist/commands/init.js +19 -7
  32. package/dist/commands/lint.js +50 -44
  33. package/dist/commands/llms-txt.js +59 -49
  34. package/dist/commands/login.js +63 -34
  35. package/dist/commands/mcp.js +6 -0
  36. package/dist/commands/monitor.js +13 -8
  37. package/dist/commands/qa.d.ts +2 -0
  38. package/dist/commands/qa.js +43 -0
  39. package/dist/commands/review-pr.js +108 -92
  40. package/dist/commands/sdk.js +128 -122
  41. package/dist/commands/security.d.ts +2 -0
  42. package/dist/commands/security.js +109 -0
  43. package/dist/commands/test.js +91 -92
  44. package/dist/commands/version.js +104 -75
  45. package/dist/commands/watch.js +130 -114
  46. package/dist/config/types.js +2 -2
  47. package/dist/context-hub/index.d.ts +23 -0
  48. package/dist/context-hub/index.js +179 -0
  49. package/dist/context-hub/mappings.d.ts +8 -0
  50. package/dist/context-hub/mappings.js +55 -0
  51. package/dist/context-hub/types.d.ts +33 -0
  52. package/dist/context-hub/types.js +1 -0
  53. package/dist/generator/generator.js +39 -6
  54. package/dist/generator/types.d.ts +7 -0
  55. package/dist/generator/writer.d.ts +3 -1
  56. package/dist/generator/writer.js +36 -7
  57. package/dist/importers/confluence.d.ts +5 -0
  58. package/dist/importers/confluence.js +137 -0
  59. package/dist/importers/detect.d.ts +20 -0
  60. package/dist/importers/detect.js +121 -0
  61. package/dist/importers/docusaurus.d.ts +5 -0
  62. package/dist/importers/docusaurus.js +279 -0
  63. package/dist/importers/gitbook.d.ts +5 -0
  64. package/dist/importers/gitbook.js +189 -0
  65. package/dist/importers/github.d.ts +8 -0
  66. package/dist/importers/github.js +99 -0
  67. package/dist/importers/index.d.ts +15 -0
  68. package/dist/importers/index.js +30 -0
  69. package/dist/importers/markdown.d.ts +6 -0
  70. package/dist/importers/markdown.js +105 -0
  71. package/dist/importers/mintlify.d.ts +5 -0
  72. package/dist/importers/mintlify.js +172 -0
  73. package/dist/importers/notion.d.ts +5 -0
  74. package/dist/importers/notion.js +174 -0
  75. package/dist/importers/readme.d.ts +5 -0
  76. package/dist/importers/readme.js +184 -0
  77. package/dist/importers/transform.d.ts +90 -0
  78. package/dist/importers/transform.js +457 -0
  79. package/dist/importers/types.d.ts +37 -0
  80. package/dist/importers/types.js +1 -0
  81. package/dist/llm/anthropic-client.d.ts +1 -0
  82. package/dist/llm/anthropic-client.js +3 -1
  83. package/dist/llm/index.d.ts +6 -4
  84. package/dist/llm/index.js +76 -261
  85. package/dist/llm/openai-client.d.ts +1 -0
  86. package/dist/llm/openai-client.js +7 -2
  87. package/dist/plugins/index.js +7 -0
  88. package/dist/qa/checks.d.ts +10 -0
  89. package/dist/qa/checks.js +492 -0
  90. package/dist/qa/fixes.d.ts +30 -0
  91. package/dist/qa/fixes.js +277 -0
  92. package/dist/qa/index.d.ts +29 -0
  93. package/dist/qa/index.js +187 -0
  94. package/dist/qa/types.d.ts +24 -0
  95. package/dist/qa/types.js +1 -0
  96. package/dist/scanner/csharp.d.ts +23 -0
  97. package/dist/scanner/csharp.js +421 -0
  98. package/dist/scanner/index.js +53 -26
  99. package/dist/scanner/java.d.ts +39 -0
  100. package/dist/scanner/java.js +318 -0
  101. package/dist/scanner/kotlin.d.ts +23 -0
  102. package/dist/scanner/kotlin.js +389 -0
  103. package/dist/scanner/php.d.ts +57 -0
  104. package/dist/scanner/php.js +351 -0
  105. package/dist/scanner/python.js +17 -0
  106. package/dist/scanner/ruby.d.ts +36 -0
  107. package/dist/scanner/ruby.js +431 -0
  108. package/dist/scanner/swift.d.ts +25 -0
  109. package/dist/scanner/swift.js +392 -0
  110. package/dist/scanner/types.d.ts +1 -1
  111. package/dist/template/content/docs/_navigation.json +46 -0
  112. package/dist/template/content/docs/_sidebars.json +684 -0
  113. package/dist/template/content/docs/core.md +4544 -0
  114. package/dist/template/content/docs/index.mdx +89 -0
  115. package/dist/template/content/docs/integrations.md +1158 -0
  116. package/dist/template/content/docs/llms-full.md +403 -0
  117. package/dist/template/content/docs/llms.txt +4588 -0
  118. package/dist/template/content/docs/other.md +10379 -0
  119. package/dist/template/content/docs/tools.md +746 -0
  120. package/dist/template/content/docs/types.md +531 -0
  121. package/dist/template/docs.json +13 -11
  122. package/dist/template/mdx-components.tsx +27 -2
  123. package/dist/template/package.json +6 -0
  124. package/dist/template/public/search-index.json +1 -1
  125. package/dist/template/scripts/build-search-index.mjs +149 -13
  126. package/dist/template/src/app/api/chat/route.ts +83 -128
  127. package/dist/template/src/app/docs/[...slug]/page.tsx +75 -20
  128. package/dist/template/src/app/docs/llms-full.md +151 -4
  129. package/dist/template/src/app/docs/llms.txt +2464 -847
  130. package/dist/template/src/app/docs/page.mdx +48 -38
  131. package/dist/template/src/app/layout.tsx +3 -1
  132. package/dist/template/src/app/page.tsx +22 -8
  133. package/dist/template/src/components/ai-chat.tsx +73 -64
  134. package/dist/template/src/components/breadcrumbs.tsx +21 -23
  135. package/dist/template/src/components/copy-button.tsx +13 -9
  136. package/dist/template/src/components/copy-page-button.tsx +54 -0
  137. package/dist/template/src/components/docs-layout.tsx +37 -25
  138. package/dist/template/src/components/header.tsx +51 -10
  139. package/dist/template/src/components/mdx/card.tsx +17 -3
  140. package/dist/template/src/components/mdx/code-block.tsx +13 -9
  141. package/dist/template/src/components/mdx/code-group.tsx +13 -8
  142. package/dist/template/src/components/mdx/heading.tsx +15 -2
  143. package/dist/template/src/components/mdx/highlighted-code.tsx +13 -8
  144. package/dist/template/src/components/mdx/index.tsx +2 -0
  145. package/dist/template/src/components/mdx/mermaid.tsx +110 -0
  146. package/dist/template/src/components/mdx/screenshot.tsx +150 -0
  147. package/dist/template/src/components/scroll-to-hash.tsx +48 -0
  148. package/dist/template/src/components/sidebar.tsx +12 -18
  149. package/dist/template/src/components/table-of-contents.tsx +9 -0
  150. package/dist/template/src/lib/highlight.ts +3 -88
  151. package/dist/template/src/lib/navigation.ts +159 -0
  152. package/dist/template/src/lib/search-types.ts +4 -1
  153. package/dist/template/src/lib/search.ts +30 -7
  154. package/dist/template/src/styles/globals.css +17 -6
  155. package/dist/utils/files.d.ts +9 -1
  156. package/dist/utils/files.js +59 -10
  157. package/dist/utils/validation.d.ts +0 -3
  158. package/dist/utils/validation.js +0 -26
  159. package/package.json +5 -1
@@ -6,7 +6,12 @@ const CONFIG_FILE = 'skrypt.i18n.json';
6
6
  function loadI18nConfig(docsPath) {
7
7
  const configPath = join(docsPath, CONFIG_FILE);
8
8
  if (existsSync(configPath)) {
9
- return JSON.parse(readFileSync(configPath, 'utf-8'));
9
+ try {
10
+ return JSON.parse(readFileSync(configPath, 'utf-8'));
11
+ }
12
+ catch {
13
+ return { defaultLocale: 'en', locales: ['en'] };
14
+ }
10
15
  }
11
16
  return { defaultLocale: 'en', locales: ['en'] };
12
17
  }
@@ -22,25 +27,31 @@ i18nCommand
22
27
  .argument('[docs-path]', 'Documentation directory', './docs')
23
28
  .option('--default <locale>', 'Default locale', 'en')
24
29
  .action((docsPath, options) => {
25
- const resolvedPath = resolve(docsPath);
26
- if (!existsSync(resolvedPath)) {
27
- console.error(`Directory not found: ${resolvedPath}`);
28
- process.exit(1);
30
+ try {
31
+ const resolvedPath = resolve(docsPath);
32
+ if (!existsSync(resolvedPath)) {
33
+ console.error(`Directory not found: ${resolvedPath}`);
34
+ process.exit(1);
35
+ }
36
+ const config = {
37
+ defaultLocale: options.default,
38
+ locales: [options.default],
39
+ };
40
+ saveI18nConfig(resolvedPath, config);
41
+ // Create locale directory structure
42
+ const localeDir = join(resolvedPath, options.default);
43
+ if (!existsSync(localeDir)) {
44
+ mkdirSync(localeDir, { recursive: true });
45
+ console.log(`Created locale directory: ${localeDir}`);
46
+ }
47
+ console.log('i18n initialized.');
48
+ console.log(` Default locale: ${options.default}`);
49
+ console.log(` Config: ${join(resolvedPath, CONFIG_FILE)}`);
29
50
  }
30
- const config = {
31
- defaultLocale: options.default,
32
- locales: [options.default],
33
- };
34
- saveI18nConfig(resolvedPath, config);
35
- // Create locale directory structure
36
- const localeDir = join(resolvedPath, options.default);
37
- if (!existsSync(localeDir)) {
38
- mkdirSync(localeDir, { recursive: true });
39
- console.log(`Created locale directory: ${localeDir}`);
51
+ catch (err) {
52
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
53
+ process.exit(1);
40
54
  }
41
- console.log('i18n initialized.');
42
- console.log(` Default locale: ${options.default}`);
43
- console.log(` Config: ${join(resolvedPath, CONFIG_FILE)}`);
44
55
  });
45
56
  i18nCommand
46
57
  .command('add')
@@ -48,53 +59,65 @@ i18nCommand
48
59
  .argument('<locale>', 'Locale code (e.g., ja, fr, de)')
49
60
  .argument('[docs-path]', 'Documentation directory', './docs')
50
61
  .action((locale, docsPath) => {
51
- const resolvedPath = resolve(docsPath);
52
- const config = loadI18nConfig(resolvedPath);
53
- if (config.locales.includes(locale)) {
54
- console.log(`Locale ${locale} already exists.`);
55
- return;
62
+ try {
63
+ const resolvedPath = resolve(docsPath);
64
+ const config = loadI18nConfig(resolvedPath);
65
+ if (config.locales.includes(locale)) {
66
+ console.log(`Locale ${locale} already exists.`);
67
+ return;
68
+ }
69
+ config.locales.push(locale);
70
+ saveI18nConfig(resolvedPath, config);
71
+ // Create locale directory
72
+ const localeDir = join(resolvedPath, locale);
73
+ mkdirSync(localeDir, { recursive: true });
74
+ console.log(`Added locale: ${locale}`);
75
+ console.log(` Directory: ${localeDir}`);
76
+ }
77
+ catch (err) {
78
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
79
+ process.exit(1);
56
80
  }
57
- config.locales.push(locale);
58
- saveI18nConfig(resolvedPath, config);
59
- // Create locale directory
60
- const localeDir = join(resolvedPath, locale);
61
- mkdirSync(localeDir, { recursive: true });
62
- console.log(`Added locale: ${locale}`);
63
- console.log(` Directory: ${localeDir}`);
64
81
  });
65
82
  i18nCommand
66
83
  .command('status')
67
84
  .description('Show translation status')
68
85
  .argument('[docs-path]', 'Documentation directory', './docs')
69
86
  .action((docsPath) => {
70
- const resolvedPath = resolve(docsPath);
71
- const config = loadI18nConfig(resolvedPath);
72
- console.log('i18n Status');
73
- console.log(` Default locale: ${config.defaultLocale}`);
74
- console.log(` Locales: ${config.locales.join(', ')}`);
75
- console.log('');
76
- // Get files from default locale
77
- const defaultDir = join(resolvedPath, config.defaultLocale);
78
- if (!existsSync(defaultDir)) {
79
- console.log(`Default locale directory not found: ${defaultDir}`);
80
- return;
81
- }
82
- const defaultFiles = findMdxFiles(defaultDir);
83
- console.log(`Default locale (${config.defaultLocale}): ${defaultFiles.length} files`);
84
- // Check each other locale
85
- for (const locale of config.locales) {
86
- if (locale === config.defaultLocale)
87
- continue;
88
- const localeDir = join(resolvedPath, locale);
89
- if (!existsSync(localeDir)) {
90
- console.log(`${locale}: 0/${defaultFiles.length} (directory missing)`);
91
- continue;
87
+ try {
88
+ const resolvedPath = resolve(docsPath);
89
+ const config = loadI18nConfig(resolvedPath);
90
+ console.log('i18n Status');
91
+ console.log(` Default locale: ${config.defaultLocale}`);
92
+ console.log(` Locales: ${config.locales.join(', ')}`);
93
+ console.log('');
94
+ // Get files from default locale
95
+ const defaultDir = join(resolvedPath, config.defaultLocale);
96
+ if (!existsSync(defaultDir)) {
97
+ console.log(`Default locale directory not found: ${defaultDir}`);
98
+ return;
99
+ }
100
+ const defaultFiles = findMdxFiles(defaultDir);
101
+ console.log(`Default locale (${config.defaultLocale}): ${defaultFiles.length} files`);
102
+ // Check each other locale
103
+ for (const locale of config.locales) {
104
+ if (locale === config.defaultLocale)
105
+ continue;
106
+ const localeDir = join(resolvedPath, locale);
107
+ if (!existsSync(localeDir)) {
108
+ console.log(`${locale}: 0/${defaultFiles.length} (directory missing)`);
109
+ continue;
110
+ }
111
+ const localeFiles = findMdxFiles(localeDir);
112
+ const translated = localeFiles.length;
113
+ const total = defaultFiles.length;
114
+ const pct = total > 0 ? Math.round((translated / total) * 100) : 0;
115
+ console.log(`${locale}: ${translated}/${total} (${pct}%)`);
92
116
  }
93
- const localeFiles = findMdxFiles(localeDir);
94
- const translated = localeFiles.length;
95
- const total = defaultFiles.length;
96
- const pct = total > 0 ? Math.round((translated / total) * 100) : 0;
97
- console.log(`${locale}: ${translated}/${total} (${pct}%)`);
117
+ }
118
+ catch (err) {
119
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
120
+ process.exit(1);
98
121
  }
99
122
  });
100
123
  i18nCommand
@@ -103,34 +126,40 @@ i18nCommand
103
126
  .argument('<locale>', 'Locale to check')
104
127
  .argument('[docs-path]', 'Documentation directory', './docs')
105
128
  .action((locale, docsPath) => {
106
- const resolvedPath = resolve(docsPath);
107
- const config = loadI18nConfig(resolvedPath);
108
- if (!config.locales.includes(locale)) {
109
- console.error(`Locale ${locale} not configured.`);
110
- process.exit(1);
111
- }
112
- const defaultDir = join(resolvedPath, config.defaultLocale);
113
- const localeDir = join(resolvedPath, locale);
114
- if (!existsSync(defaultDir)) {
115
- console.error(`Default locale directory not found: ${defaultDir}`);
116
- process.exit(1);
117
- }
118
- const defaultFiles = findMdxFiles(defaultDir);
119
- const missing = [];
120
- for (const file of defaultFiles) {
121
- const relPath = relative(defaultDir, file);
122
- const localePath = join(localeDir, relPath);
123
- if (!existsSync(localePath)) {
124
- missing.push(relPath);
129
+ try {
130
+ const resolvedPath = resolve(docsPath);
131
+ const config = loadI18nConfig(resolvedPath);
132
+ if (!config.locales.includes(locale)) {
133
+ console.error(`Locale ${locale} not configured.`);
134
+ process.exit(1);
135
+ }
136
+ const defaultDir = join(resolvedPath, config.defaultLocale);
137
+ const localeDir = join(resolvedPath, locale);
138
+ if (!existsSync(defaultDir)) {
139
+ console.error(`Default locale directory not found: ${defaultDir}`);
140
+ process.exit(1);
141
+ }
142
+ const defaultFiles = findMdxFiles(defaultDir);
143
+ const missing = [];
144
+ for (const file of defaultFiles) {
145
+ const relPath = relative(defaultDir, file);
146
+ const localePath = join(localeDir, relPath);
147
+ if (!existsSync(localePath)) {
148
+ missing.push(relPath);
149
+ }
150
+ }
151
+ if (missing.length === 0) {
152
+ console.log(`All files translated for ${locale}!`);
153
+ return;
154
+ }
155
+ console.log(`Missing translations for ${locale} (${missing.length} files):`);
156
+ for (const file of missing) {
157
+ console.log(` ${file}`);
125
158
  }
126
159
  }
127
- if (missing.length === 0) {
128
- console.log(`All files translated for ${locale}!`);
129
- return;
130
- }
131
- console.log(`Missing translations for ${locale} (${missing.length} files):`);
132
- for (const file of missing) {
133
- console.log(` ${file}`);
160
+ catch (err) {
161
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
162
+ process.exit(1);
134
163
  }
135
164
  });
136
165
  i18nCommand
@@ -139,35 +168,41 @@ i18nCommand
139
168
  .argument('[docs-path]', 'Documentation directory', './docs')
140
169
  .option('-o, --output <file>', 'Output file', 'strings.json')
141
170
  .action((docsPath, options) => {
142
- const resolvedPath = resolve(docsPath);
143
- const config = loadI18nConfig(resolvedPath);
144
- const defaultDir = join(resolvedPath, config.defaultLocale);
145
- if (!existsSync(defaultDir)) {
146
- console.error(`Default locale directory not found: ${defaultDir}`);
147
- process.exit(1);
148
- }
149
- const files = findMdxFiles(defaultDir);
150
- const strings = {};
151
- for (const file of files) {
152
- const relPath = relative(defaultDir, file);
153
- const content = readFileSync(file, 'utf-8');
154
- const lines = content.split('\n');
155
- const fileStrings = {};
156
- for (const line of lines) {
157
- // Extract headings
158
- const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
159
- if (headingMatch) {
160
- const key = `heading_${Object.keys(fileStrings).length}`;
161
- fileStrings[key] = headingMatch[2];
162
- }
171
+ try {
172
+ const resolvedPath = resolve(docsPath);
173
+ const config = loadI18nConfig(resolvedPath);
174
+ const defaultDir = join(resolvedPath, config.defaultLocale);
175
+ if (!existsSync(defaultDir)) {
176
+ console.error(`Default locale directory not found: ${defaultDir}`);
177
+ process.exit(1);
163
178
  }
164
- if (Object.keys(fileStrings).length > 0) {
165
- strings[relPath] = fileStrings;
179
+ const files = findMdxFiles(defaultDir);
180
+ const strings = {};
181
+ for (const file of files) {
182
+ const relPath = relative(defaultDir, file);
183
+ const content = readFileSync(file, 'utf-8');
184
+ const lines = content.split('\n');
185
+ const fileStrings = {};
186
+ for (const line of lines) {
187
+ // Extract headings
188
+ const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
189
+ if (headingMatch) {
190
+ const key = `heading_${Object.keys(fileStrings).length}`;
191
+ fileStrings[key] = headingMatch[2];
192
+ }
193
+ }
194
+ if (Object.keys(fileStrings).length > 0) {
195
+ strings[relPath] = fileStrings;
196
+ }
166
197
  }
198
+ const outputPath = resolve(options.output);
199
+ writeFileSync(outputPath, JSON.stringify(strings, null, 2));
200
+ console.log(`Extracted strings to: ${outputPath}`);
201
+ console.log(` Files: ${Object.keys(strings).length}`);
202
+ console.log(` Strings: ${Object.values(strings).reduce((a, b) => a + Object.keys(b).length, 0)}`);
203
+ }
204
+ catch (err) {
205
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
206
+ process.exit(1);
167
207
  }
168
- const outputPath = resolve(options.output);
169
- writeFileSync(outputPath, JSON.stringify(strings, null, 2));
170
- console.log(`Extracted strings to: ${outputPath}`);
171
- console.log(` Files: ${Object.keys(strings).length}`);
172
- console.log(` Strings: ${Object.values(strings).reduce((a, b) => a + Object.keys(b).length, 0)}`);
173
208
  });
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const importCommand: Command;
@@ -0,0 +1,157 @@
1
+ import { Command } from 'commander';
2
+ import { existsSync, mkdirSync, cpSync, readFileSync, writeFileSync } from 'fs';
3
+ import { resolve, join, dirname, basename } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { detectFormat, isGitHubUrl, parseGitHubUrl, runImport, importFromGitHub } from '../importers/index.js';
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = dirname(__filename);
8
+ export const importCommand = new Command('import')
9
+ .description('Import documentation from another platform')
10
+ .argument('<source>', 'Local directory or GitHub URL')
11
+ .option('--from <format>', 'Source format (mintlify, docusaurus, gitbook, readme, notion, confluence, markdown)')
12
+ .option('-o, --output <dir>', 'Output directory')
13
+ .option('--dry-run', 'Show what would be imported without writing files')
14
+ .option('--name <name>', 'Project name')
15
+ .action(async (source, options) => {
16
+ try {
17
+ console.log('skrypt import\n');
18
+ // Validate --from flag
19
+ const VALID_FORMATS = ['mintlify', 'docusaurus', 'gitbook', 'readme', 'notion', 'confluence', 'markdown'];
20
+ if (options.from && !VALID_FORMATS.includes(options.from)) {
21
+ console.error(` Error: Unknown format "${options.from}". Valid formats: ${VALID_FORMATS.join(', ')}`);
22
+ process.exit(1);
23
+ }
24
+ let result;
25
+ if (isGitHubUrl(source)) {
26
+ // GitHub URL import
27
+ const { owner, repo, path, ref } = parseGitHubUrl(source);
28
+ console.log(` Source: github.com/${owner}/${repo}/${path} (${ref})`);
29
+ result = await importFromGitHub(owner, repo, path, ref, {
30
+ format: options.from,
31
+ name: options.name,
32
+ });
33
+ }
34
+ else {
35
+ // Local directory import
36
+ const sourceDir = resolve(source);
37
+ if (!existsSync(sourceDir)) {
38
+ console.error(` Error: Source directory not found: ${sourceDir}`);
39
+ process.exit(1);
40
+ }
41
+ const format = options.from || detectFormat(sourceDir);
42
+ console.log(` Source: ${sourceDir} (${format})`);
43
+ result = runImport(sourceDir, format, options.name);
44
+ }
45
+ // Determine output directory
46
+ const outputDir = resolve(options.output || `${basename(source).replace(/[^a-zA-Z0-9-_]/g, '-')}-docs`);
47
+ console.log(` Output: ${outputDir}`);
48
+ console.log('');
49
+ // Print migration report
50
+ printReport(result);
51
+ if (options.dryRun) {
52
+ console.log(' [dry run — no files written]\n');
53
+ return;
54
+ }
55
+ // Scaffold output directory
56
+ scaffoldOutput(outputDir, result);
57
+ console.log(' Next steps:');
58
+ console.log(` cd ${outputDir} && npm install && npm run dev\n`);
59
+ }
60
+ catch (err) {
61
+ const message = err instanceof Error ? err.message : String(err);
62
+ console.error(` Error: ${message}`);
63
+ process.exit(1);
64
+ }
65
+ });
66
+ function printReport(result) {
67
+ console.log(' Imported:');
68
+ console.log(` ${result.stats.pages} pages across ${result.stats.groups} groups`);
69
+ const { transforms } = result.stats;
70
+ if (transforms.callouts > 0)
71
+ console.log(` ${transforms.callouts} callouts mapped`);
72
+ if (transforms.tabs > 0)
73
+ console.log(` ${transforms.tabs} tabs mapped`);
74
+ if (transforms.codeGroups > 0)
75
+ console.log(` ${transforms.codeGroups} code groups mapped`);
76
+ if (transforms.steps > 0)
77
+ console.log(` ${transforms.steps} steps mapped`);
78
+ if (transforms.accordions > 0)
79
+ console.log(` ${transforms.accordions} accordions mapped`);
80
+ if (transforms.images > 0)
81
+ console.log(` ${transforms.images} images copied`);
82
+ if (result.warnings.length > 0) {
83
+ console.log('');
84
+ console.log(' Warnings:');
85
+ for (const w of result.warnings.slice(0, 10)) {
86
+ console.log(` - ${w}`);
87
+ }
88
+ if (result.warnings.length > 10) {
89
+ console.log(` ... and ${result.warnings.length - 10} more`);
90
+ }
91
+ }
92
+ console.log('');
93
+ }
94
+ function scaffoldOutput(outputDir, result) {
95
+ // Copy template
96
+ const templateDir = join(__dirname, '..', 'template');
97
+ if (existsSync(templateDir)) {
98
+ mkdirSync(outputDir, { recursive: true });
99
+ cpSync(templateDir, outputDir, { recursive: true });
100
+ }
101
+ else {
102
+ mkdirSync(outputDir, { recursive: true });
103
+ }
104
+ // Write transformed content files
105
+ for (const [filePath, content] of result.files) {
106
+ const outputPath = join(outputDir, filePath);
107
+ mkdirSync(dirname(outputPath), { recursive: true });
108
+ writeFileSync(outputPath, content);
109
+ }
110
+ // Copy assets
111
+ for (const [destPath, srcPath] of result.assets) {
112
+ const outputPath = join(outputDir, destPath);
113
+ mkdirSync(dirname(outputPath), { recursive: true });
114
+ try {
115
+ cpSync(srcPath, outputPath);
116
+ }
117
+ catch {
118
+ // Image may not exist (e.g. CDN URL)
119
+ }
120
+ }
121
+ // Generate docs.json navigation
122
+ const docsJson = {
123
+ name: result.name,
124
+ description: result.description,
125
+ theme: {
126
+ primaryColor: '#3b82f6',
127
+ accentColor: '#8b5cf6',
128
+ font: 'Inter',
129
+ },
130
+ navigation: result.navigation.map(group => ({
131
+ group: group.group,
132
+ pages: group.pages.map(page => ({
133
+ title: page.title,
134
+ path: `/docs/${page.slug}`,
135
+ })),
136
+ })),
137
+ footer: {
138
+ links: [],
139
+ },
140
+ };
141
+ writeFileSync(join(outputDir, 'docs.json'), JSON.stringify(docsJson, null, 2));
142
+ // Update package.json name if template exists
143
+ const pkgPath = join(outputDir, 'package.json');
144
+ if (existsSync(pkgPath)) {
145
+ try {
146
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
147
+ pkg.name = result.name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
148
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
149
+ }
150
+ catch { /* skip */ }
151
+ }
152
+ console.log(` ✓ Wrote ${result.files.size} pages to ${outputDir}`);
153
+ if (result.assets.size > 0) {
154
+ console.log(` ✓ Copied ${result.assets.size} assets`);
155
+ }
156
+ console.log('');
157
+ }
@@ -35,15 +35,27 @@ export const initCommand = new Command('init')
35
35
  cpSync(templateDir, targetDir, { recursive: true });
36
36
  // Update package.json with project name
37
37
  const packageJsonPath = join(targetDir, 'package.json');
38
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
39
- packageJson.name = options.name;
40
- writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
38
+ try {
39
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
40
+ packageJson.name = options.name;
41
+ writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
42
+ }
43
+ catch {
44
+ console.error('Error: Template package.json is missing or corrupted. Please reinstall skrypt.');
45
+ process.exit(1);
46
+ }
41
47
  // Update docs.json with project name
42
48
  const docsJsonPath = join(targetDir, 'docs.json');
43
- const docsJson = JSON.parse(readFileSync(docsJsonPath, 'utf-8'));
44
- docsJson.name = options.name;
45
- docsJson.description = `${options.name} documentation`;
46
- writeFileSync(docsJsonPath, JSON.stringify(docsJson, null, 2));
49
+ try {
50
+ const docsJson = JSON.parse(readFileSync(docsJsonPath, 'utf-8'));
51
+ docsJson.name = options.name;
52
+ docsJson.description = `${options.name} documentation`;
53
+ writeFileSync(docsJsonPath, JSON.stringify(docsJson, null, 2));
54
+ }
55
+ catch {
56
+ console.error('Error: Template docs.json is missing or corrupted. Please reinstall skrypt.');
57
+ process.exit(1);
58
+ }
47
59
  console.log('');
48
60
  console.log('Done! Next steps:');
49
61
  console.log('');
@@ -198,55 +198,61 @@ export const lintCommand = new Command('lint')
198
198
  .option('--fix', 'Attempt to fix issues automatically')
199
199
  .option('-c, --config <file>', 'Config file with custom rules')
200
200
  .action(async (path, _options) => {
201
- const targetPath = resolve(path);
202
- if (!existsSync(targetPath)) {
203
- console.error(`Error: Path not found: ${targetPath}`);
204
- process.exit(1);
205
- }
206
- console.log('skrypt lint');
207
- console.log(` path: ${targetPath}`);
208
- console.log('');
209
- // Find all MDX files
210
- const files = statSync(targetPath).isDirectory()
211
- ? findMdxFiles(targetPath)
212
- : [targetPath];
213
- if (files.length === 0) {
214
- console.log('No .md or .mdx files found.');
215
- process.exit(0);
216
- }
217
- console.log(`Linting ${files.length} files...\n`);
218
- let totalErrors = 0;
219
- let totalWarnings = 0;
220
- const results = [];
221
- for (const file of files) {
222
- const result = lintFile(file);
223
- if (result.issues.length > 0) {
224
- results.push(result);
201
+ try {
202
+ const targetPath = resolve(path);
203
+ if (!existsSync(targetPath)) {
204
+ console.error(`Error: Path not found: ${targetPath}`);
205
+ process.exit(1);
206
+ }
207
+ console.log('skrypt lint');
208
+ console.log(` path: ${targetPath}`);
209
+ console.log('');
210
+ // Find all MDX files
211
+ const files = statSync(targetPath).isDirectory()
212
+ ? findMdxFiles(targetPath)
213
+ : [targetPath];
214
+ if (files.length === 0) {
215
+ console.log('No .md or .mdx files found.');
216
+ process.exit(0);
217
+ }
218
+ console.log(`Linting ${files.length} files...\n`);
219
+ let totalErrors = 0;
220
+ let totalWarnings = 0;
221
+ const results = [];
222
+ for (const file of files) {
223
+ const result = lintFile(file);
224
+ if (result.issues.length > 0) {
225
+ results.push(result);
226
+ for (const issue of result.issues) {
227
+ if (issue.severity === 'error')
228
+ totalErrors++;
229
+ else
230
+ totalWarnings++;
231
+ }
232
+ }
233
+ }
234
+ // Print results
235
+ for (const result of results) {
236
+ const relPath = result.file.replace(targetPath + '/', '');
237
+ console.log(`\n${relPath}`);
225
238
  for (const issue of result.issues) {
226
- if (issue.severity === 'error')
227
- totalErrors++;
228
- else
229
- totalWarnings++;
239
+ const icon = issue.severity === 'error' ? '✖' : '⚠';
240
+ const color = issue.severity === 'error' ? '\x1b[31m' : '\x1b[33m';
241
+ const reset = '\x1b[0m';
242
+ console.log(` ${color}${icon}${reset} ${issue.line}:${issue.column} ${issue.message} ${color}${issue.rule}${reset}`);
230
243
  }
231
244
  }
232
- }
233
- // Print results
234
- for (const result of results) {
235
- const relPath = result.file.replace(targetPath + '/', '');
236
- console.log(`\n${relPath}`);
237
- for (const issue of result.issues) {
238
- const icon = issue.severity === 'error' ? '✖' : '⚠';
239
- const color = issue.severity === 'error' ? '\x1b[31m' : '\x1b[33m';
240
- const reset = '\x1b[0m';
241
- console.log(` ${color}${icon}${reset} ${issue.line}:${issue.column} ${issue.message} ${color}${issue.rule}${reset}`);
245
+ // Summary
246
+ console.log('\n=== Summary ===');
247
+ console.log(` Files: ${files.length}`);
248
+ console.log(` Errors: ${totalErrors}`);
249
+ console.log(` Warnings: ${totalWarnings}`);
250
+ if (totalErrors > 0) {
251
+ process.exit(1);
242
252
  }
243
253
  }
244
- // Summary
245
- console.log('\n=== Summary ===');
246
- console.log(` Files: ${files.length}`);
247
- console.log(` Errors: ${totalErrors}`);
248
- console.log(` Warnings: ${totalWarnings}`);
249
- if (totalErrors > 0) {
254
+ catch (err) {
255
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
250
256
  process.exit(1);
251
257
  }
252
258
  });