skrypt-ai 0.5.0 → 0.6.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.
- package/dist/auth/index.js +8 -1
- package/dist/autofix/index.d.ts +0 -4
- package/dist/autofix/index.js +0 -21
- package/dist/capture/browser.d.ts +11 -0
- package/dist/capture/browser.js +173 -0
- package/dist/capture/diff.d.ts +23 -0
- package/dist/capture/diff.js +52 -0
- package/dist/capture/index.d.ts +23 -0
- package/dist/capture/index.js +210 -0
- package/dist/capture/naming.d.ts +17 -0
- package/dist/capture/naming.js +45 -0
- package/dist/capture/parser.d.ts +15 -0
- package/dist/capture/parser.js +80 -0
- package/dist/capture/types.d.ts +57 -0
- package/dist/capture/types.js +1 -0
- package/dist/cli.js +4 -0
- package/dist/commands/autofix.js +136 -120
- package/dist/commands/cron.js +58 -47
- package/dist/commands/deploy.js +123 -102
- package/dist/commands/generate.js +88 -6
- package/dist/commands/heal.d.ts +10 -0
- package/dist/commands/heal.js +201 -0
- package/dist/commands/i18n.js +146 -111
- package/dist/commands/lint.js +50 -44
- package/dist/commands/llms-txt.js +59 -49
- package/dist/commands/login.js +61 -43
- package/dist/commands/mcp.js +6 -0
- package/dist/commands/monitor.js +13 -8
- package/dist/commands/qa.d.ts +2 -0
- package/dist/commands/qa.js +43 -0
- package/dist/commands/review-pr.js +114 -103
- package/dist/commands/sdk.js +128 -122
- package/dist/commands/security.js +86 -80
- package/dist/commands/test.js +91 -92
- package/dist/commands/version.js +104 -75
- package/dist/commands/watch.js +130 -114
- package/dist/config/types.js +2 -2
- package/dist/context-hub/index.d.ts +23 -0
- package/dist/context-hub/index.js +179 -0
- package/dist/context-hub/mappings.d.ts +8 -0
- package/dist/context-hub/mappings.js +55 -0
- package/dist/context-hub/types.d.ts +33 -0
- package/dist/context-hub/types.js +1 -0
- package/dist/generator/generator.js +39 -6
- package/dist/generator/types.d.ts +7 -0
- package/dist/generator/writer.d.ts +3 -1
- package/dist/generator/writer.js +24 -4
- package/dist/llm/anthropic-client.d.ts +1 -0
- package/dist/llm/anthropic-client.js +3 -1
- package/dist/llm/index.d.ts +6 -4
- package/dist/llm/index.js +76 -261
- package/dist/llm/openai-client.d.ts +1 -0
- package/dist/llm/openai-client.js +7 -2
- package/dist/qa/checks.d.ts +10 -0
- package/dist/qa/checks.js +492 -0
- package/dist/qa/fixes.d.ts +30 -0
- package/dist/qa/fixes.js +277 -0
- package/dist/qa/index.d.ts +29 -0
- package/dist/qa/index.js +187 -0
- package/dist/qa/types.d.ts +24 -0
- package/dist/qa/types.js +1 -0
- package/dist/scanner/csharp.d.ts +23 -0
- package/dist/scanner/csharp.js +421 -0
- package/dist/scanner/index.js +16 -2
- package/dist/scanner/java.d.ts +39 -0
- package/dist/scanner/java.js +318 -0
- package/dist/scanner/kotlin.d.ts +23 -0
- package/dist/scanner/kotlin.js +389 -0
- package/dist/scanner/php.d.ts +57 -0
- package/dist/scanner/php.js +351 -0
- package/dist/scanner/ruby.d.ts +36 -0
- package/dist/scanner/ruby.js +431 -0
- package/dist/scanner/swift.d.ts +25 -0
- package/dist/scanner/swift.js +392 -0
- package/dist/scanner/types.d.ts +1 -1
- package/dist/template/content/docs/_navigation.json +46 -0
- package/dist/template/content/docs/_sidebars.json +684 -0
- package/dist/template/content/docs/core.md +4544 -0
- package/dist/template/content/docs/index.mdx +89 -0
- package/dist/template/content/docs/integrations.md +1158 -0
- package/dist/template/content/docs/llms-full.md +403 -0
- package/dist/template/content/docs/llms.txt +4588 -0
- package/dist/template/content/docs/other.md +10379 -0
- package/dist/template/content/docs/tools.md +746 -0
- package/dist/template/content/docs/types.md +531 -0
- package/dist/template/docs.json +13 -11
- package/dist/template/mdx-components.tsx +27 -2
- package/dist/template/package.json +6 -0
- package/dist/template/public/search-index.json +1 -1
- package/dist/template/scripts/build-search-index.mjs +84 -6
- package/dist/template/src/app/api/chat/route.ts +83 -128
- package/dist/template/src/app/docs/[...slug]/page.tsx +75 -20
- package/dist/template/src/app/docs/llms-full.md +151 -4
- package/dist/template/src/app/docs/llms.txt +2464 -847
- package/dist/template/src/app/docs/page.mdx +48 -38
- package/dist/template/src/app/layout.tsx +3 -1
- package/dist/template/src/app/page.tsx +22 -8
- package/dist/template/src/components/ai-chat.tsx +73 -64
- package/dist/template/src/components/breadcrumbs.tsx +21 -23
- package/dist/template/src/components/copy-button.tsx +13 -9
- package/dist/template/src/components/copy-page-button.tsx +54 -0
- package/dist/template/src/components/docs-layout.tsx +37 -25
- package/dist/template/src/components/header.tsx +51 -10
- package/dist/template/src/components/mdx/card.tsx +17 -3
- package/dist/template/src/components/mdx/code-block.tsx +13 -9
- package/dist/template/src/components/mdx/code-group.tsx +13 -8
- package/dist/template/src/components/mdx/heading.tsx +15 -2
- package/dist/template/src/components/mdx/highlighted-code.tsx +13 -8
- package/dist/template/src/components/mdx/index.tsx +2 -0
- package/dist/template/src/components/mdx/mermaid.tsx +110 -0
- package/dist/template/src/components/mdx/screenshot.tsx +150 -0
- package/dist/template/src/components/scroll-to-hash.tsx +48 -0
- package/dist/template/src/components/sidebar.tsx +12 -18
- package/dist/template/src/components/table-of-contents.tsx +9 -0
- package/dist/template/src/lib/highlight.ts +3 -88
- package/dist/template/src/lib/navigation.ts +159 -0
- package/dist/template/src/styles/globals.css +17 -6
- package/dist/utils/validation.d.ts +0 -3
- package/dist/utils/validation.js +0 -26
- package/package.json +3 -2
package/dist/commands/i18n.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
128
|
-
console.
|
|
129
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
165
|
-
|
|
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
|
});
|
package/dist/commands/lint.js
CHANGED
|
@@ -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
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
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
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
console.log(
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
245
|
-
|
|
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
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync, readdirSync, statSync } from 'fs';
|
|
3
|
-
import { resolve, join, extname } from 'path';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, readdirSync, statSync, mkdirSync } from 'fs';
|
|
3
|
+
import { resolve, join, extname, dirname } from 'path';
|
|
4
4
|
function extractFrontmatter(content) {
|
|
5
5
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
6
6
|
if (!match)
|
|
@@ -136,54 +136,64 @@ export const llmsTxtCommand = new Command('llms-txt')
|
|
|
136
136
|
.option('--title <title>', 'Documentation title', 'Documentation')
|
|
137
137
|
.option('--description <desc>', 'Documentation description', 'API and usage documentation')
|
|
138
138
|
.action(async (docsPath, options) => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
139
|
+
try {
|
|
140
|
+
const resolvedDocs = resolve(docsPath);
|
|
141
|
+
const outputDir = resolve(options.output || './public');
|
|
142
|
+
console.log('skrypt llms-txt');
|
|
143
|
+
console.log(` docs: ${resolvedDocs}`);
|
|
144
|
+
console.log(` output: ${outputDir}`);
|
|
145
|
+
console.log(` base-url: ${options.baseUrl}`);
|
|
146
|
+
console.log('');
|
|
147
|
+
// Check if docs directory exists
|
|
148
|
+
if (!existsSync(resolvedDocs)) {
|
|
149
|
+
console.error(`Error: Documentation directory not found: ${resolvedDocs}`);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
// Scan documentation
|
|
153
|
+
console.log('Step 1: Scanning documentation...');
|
|
154
|
+
const docs = walkDocs(resolvedDocs);
|
|
155
|
+
if (docs.length === 0) {
|
|
156
|
+
console.error('Error: No documentation files found');
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
console.log(` Found ${docs.length} documentation files`);
|
|
160
|
+
// Ensure output directory exists
|
|
161
|
+
mkdirSync(outputDir, { recursive: true });
|
|
162
|
+
// Generate llms.txt (summary)
|
|
163
|
+
console.log('\nStep 2: Generating llms.txt...');
|
|
164
|
+
const llmsTxt = generateLLMsTxt(docs, {
|
|
165
|
+
title: options.title || 'Documentation',
|
|
166
|
+
description: options.description || 'API and usage documentation',
|
|
167
|
+
baseUrl: options.baseUrl || 'https://docs.example.com'
|
|
168
|
+
});
|
|
169
|
+
const llmsTxtPath = join(outputDir, 'llms.txt');
|
|
170
|
+
mkdirSync(dirname(llmsTxtPath), { recursive: true });
|
|
171
|
+
writeFileSync(llmsTxtPath, llmsTxt);
|
|
172
|
+
console.log(` Written: ${llmsTxtPath}`);
|
|
173
|
+
// Generate llms-full.txt (complete content)
|
|
174
|
+
console.log('\nStep 3: Generating llms-full.txt...');
|
|
175
|
+
const llmsFullTxt = generateLLMsFullTxt(docs, {
|
|
176
|
+
title: options.title || 'Documentation',
|
|
177
|
+
description: options.description || 'API and usage documentation',
|
|
178
|
+
baseUrl: options.baseUrl || 'https://docs.example.com'
|
|
179
|
+
});
|
|
180
|
+
const llmsFullTxtPath = join(outputDir, 'llms-full.txt');
|
|
181
|
+
mkdirSync(dirname(llmsFullTxtPath), { recursive: true });
|
|
182
|
+
writeFileSync(llmsFullTxtPath, llmsFullTxt);
|
|
183
|
+
console.log(` Written: ${llmsFullTxtPath}`);
|
|
184
|
+
// Summary
|
|
185
|
+
console.log('\n=== Summary ===');
|
|
186
|
+
console.log(` Documentation files: ${docs.length}`);
|
|
187
|
+
console.log(` llms.txt: ${(llmsTxt.length / 1024).toFixed(1)} KB`);
|
|
188
|
+
console.log(` llms-full.txt: ${(llmsFullTxt.length / 1024).toFixed(1)} KB`);
|
|
189
|
+
console.log('');
|
|
190
|
+
console.log('Add these to your robots.txt:');
|
|
191
|
+
console.log(' Sitemap: /llms.txt');
|
|
192
|
+
console.log('');
|
|
193
|
+
console.log('AI agents (GPTBot, ClaudeBot, etc.) will automatically discover your docs!');
|
|
150
194
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const docs = walkDocs(resolvedDocs);
|
|
154
|
-
if (docs.length === 0) {
|
|
155
|
-
console.error('Error: No documentation files found');
|
|
195
|
+
catch (err) {
|
|
196
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
156
197
|
process.exit(1);
|
|
157
198
|
}
|
|
158
|
-
console.log(` Found ${docs.length} documentation files`);
|
|
159
|
-
// Generate llms.txt (summary)
|
|
160
|
-
console.log('\nStep 2: Generating llms.txt...');
|
|
161
|
-
const llmsTxt = generateLLMsTxt(docs, {
|
|
162
|
-
title: options.title || 'Documentation',
|
|
163
|
-
description: options.description || 'API and usage documentation',
|
|
164
|
-
baseUrl: options.baseUrl || 'https://docs.example.com'
|
|
165
|
-
});
|
|
166
|
-
const llmsTxtPath = join(outputDir, 'llms.txt');
|
|
167
|
-
writeFileSync(llmsTxtPath, llmsTxt);
|
|
168
|
-
console.log(` Written: ${llmsTxtPath}`);
|
|
169
|
-
// Generate llms-full.txt (complete content)
|
|
170
|
-
console.log('\nStep 3: Generating llms-full.txt...');
|
|
171
|
-
const llmsFullTxt = generateLLMsFullTxt(docs, {
|
|
172
|
-
title: options.title || 'Documentation',
|
|
173
|
-
description: options.description || 'API and usage documentation',
|
|
174
|
-
baseUrl: options.baseUrl || 'https://docs.example.com'
|
|
175
|
-
});
|
|
176
|
-
const llmsFullTxtPath = join(outputDir, 'llms-full.txt');
|
|
177
|
-
writeFileSync(llmsFullTxtPath, llmsFullTxt);
|
|
178
|
-
console.log(` Written: ${llmsFullTxtPath}`);
|
|
179
|
-
// Summary
|
|
180
|
-
console.log('\n=== Summary ===');
|
|
181
|
-
console.log(` Documentation files: ${docs.length}`);
|
|
182
|
-
console.log(` llms.txt: ${(llmsTxt.length / 1024).toFixed(1)} KB`);
|
|
183
|
-
console.log(` llms-full.txt: ${(llmsFullTxt.length / 1024).toFixed(1)} KB`);
|
|
184
|
-
console.log('');
|
|
185
|
-
console.log('Add these to your robots.txt:');
|
|
186
|
-
console.log(' Sitemap: /llms.txt');
|
|
187
|
-
console.log('');
|
|
188
|
-
console.log('AI agents (GPTBot, ClaudeBot, etc.) will automatically discover your docs!');
|
|
189
199
|
});
|
package/dist/commands/login.js
CHANGED
|
@@ -18,59 +18,77 @@ export const loginCommand = new Command('login')
|
|
|
18
18
|
.description('Login to Skrypt Pro')
|
|
19
19
|
.option('--key <api-key>', 'API key (or set SKRYPT_API_KEY env var)')
|
|
20
20
|
.action(async (options) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
try {
|
|
22
|
+
console.log('skrypt login\n');
|
|
23
|
+
let apiKey = options.key || process.env.SKRYPT_API_KEY;
|
|
24
|
+
if (!apiKey) {
|
|
25
|
+
console.log(' Get your API key at: https://skrypt.sh/dashboard/settings\n');
|
|
26
|
+
apiKey = await prompt(' Enter API key: ');
|
|
27
|
+
}
|
|
28
|
+
if (!apiKey) {
|
|
29
|
+
console.error(' Error: No API key provided');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
console.log('\n Verifying...');
|
|
33
|
+
const result = await checkPlan(apiKey);
|
|
34
|
+
if (!result.valid) {
|
|
35
|
+
console.error(`\n Error: ${result.error || 'Invalid API key'}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
await saveAuthConfig({
|
|
39
|
+
apiKey,
|
|
40
|
+
email: result.email,
|
|
41
|
+
plan: result.plan,
|
|
42
|
+
expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString()
|
|
43
|
+
});
|
|
44
|
+
console.log(`\n ✓ Logged in as ${result.email}`);
|
|
45
|
+
console.log(` Plan: ${result.plan.toUpperCase()}\n`);
|
|
46
|
+
// Trust signals
|
|
47
|
+
const storageMethod = await getKeyStorageMethod();
|
|
48
|
+
if (storageMethod === 'keychain') {
|
|
49
|
+
console.log(` 🔒 API key stored in ${getKeychainPlatformName()}`);
|
|
50
|
+
}
|
|
51
|
+
else if (storageMethod === 'file') {
|
|
52
|
+
console.log(' 🔒 API key stored in ~/.skrypt/auth.json (0600 permissions)');
|
|
53
|
+
}
|
|
54
|
+
console.log(' Your key is hashed (SHA-256) on our servers — never stored in plaintext');
|
|
55
|
+
console.log('');
|
|
56
|
+
if (result.plan === 'free') {
|
|
57
|
+
console.log(' Upgrade to Pro: https://skrypt.sh/pro\n');
|
|
58
|
+
}
|
|
30
59
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (!result.valid) {
|
|
34
|
-
console.error(`\n Error: ${result.error || 'Invalid API key'}`);
|
|
60
|
+
catch (err) {
|
|
61
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
35
62
|
process.exit(1);
|
|
36
63
|
}
|
|
37
|
-
await saveAuthConfig({
|
|
38
|
-
apiKey,
|
|
39
|
-
email: result.email,
|
|
40
|
-
plan: result.plan,
|
|
41
|
-
expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString()
|
|
42
|
-
});
|
|
43
|
-
console.log(`\n ✓ Logged in as ${result.email}`);
|
|
44
|
-
console.log(` Plan: ${result.plan.toUpperCase()}\n`);
|
|
45
|
-
// Trust signals
|
|
46
|
-
const storageMethod = await getKeyStorageMethod();
|
|
47
|
-
if (storageMethod === 'keychain') {
|
|
48
|
-
console.log(` 🔒 API key stored in ${getKeychainPlatformName()}`);
|
|
49
|
-
}
|
|
50
|
-
else if (storageMethod === 'file') {
|
|
51
|
-
console.log(' 🔒 API key stored in ~/.skrypt/auth.json (0600 permissions)');
|
|
52
|
-
}
|
|
53
|
-
console.log(' Your key is hashed (SHA-256) on our servers — never stored in plaintext');
|
|
54
|
-
console.log('');
|
|
55
|
-
if (result.plan === 'free') {
|
|
56
|
-
console.log(' Upgrade to Pro: https://skrypt.sh/pro\n');
|
|
57
|
-
}
|
|
58
64
|
});
|
|
59
65
|
export const logoutCommand = new Command('logout')
|
|
60
66
|
.description('Logout from Skrypt')
|
|
61
67
|
.action(async () => {
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
try {
|
|
69
|
+
await clearAuth();
|
|
70
|
+
console.log(' Logged out successfully\n');
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
64
76
|
});
|
|
65
77
|
export const whoamiCommand = new Command('whoami')
|
|
66
78
|
.description('Show current login status')
|
|
67
79
|
.action(async () => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
80
|
+
try {
|
|
81
|
+
const config = await getAuthConfigAsync();
|
|
82
|
+
if (!config.apiKey) {
|
|
83
|
+
console.log(' Not logged in');
|
|
84
|
+
console.log(' Run: skrypt login\n');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
console.log(` Email: ${config.email || 'Unknown'}`);
|
|
88
|
+
console.log(` Plan: ${(config.plan || 'free').toUpperCase()}\n`);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
92
|
+
process.exit(1);
|
|
73
93
|
}
|
|
74
|
-
console.log(` Email: ${config.email || 'Unknown'}`);
|
|
75
|
-
console.log(` Plan: ${(config.plan || 'free').toUpperCase()}\n`);
|
|
76
94
|
});
|