skrypt-ai 0.5.0 → 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 (120) hide show
  1. package/dist/auth/index.js +8 -1
  2. package/dist/autofix/index.d.ts +0 -4
  3. package/dist/autofix/index.js +0 -21
  4. package/dist/capture/browser.d.ts +11 -0
  5. package/dist/capture/browser.js +173 -0
  6. package/dist/capture/diff.d.ts +23 -0
  7. package/dist/capture/diff.js +52 -0
  8. package/dist/capture/index.d.ts +23 -0
  9. package/dist/capture/index.js +210 -0
  10. package/dist/capture/naming.d.ts +17 -0
  11. package/dist/capture/naming.js +45 -0
  12. package/dist/capture/parser.d.ts +15 -0
  13. package/dist/capture/parser.js +80 -0
  14. package/dist/capture/types.d.ts +57 -0
  15. package/dist/capture/types.js +1 -0
  16. package/dist/cli.js +4 -0
  17. package/dist/commands/autofix.js +136 -120
  18. package/dist/commands/cron.js +58 -47
  19. package/dist/commands/deploy.js +123 -102
  20. package/dist/commands/generate.js +88 -6
  21. package/dist/commands/heal.d.ts +10 -0
  22. package/dist/commands/heal.js +201 -0
  23. package/dist/commands/i18n.js +146 -111
  24. package/dist/commands/lint.js +50 -44
  25. package/dist/commands/llms-txt.js +59 -49
  26. package/dist/commands/login.js +61 -43
  27. package/dist/commands/mcp.js +6 -0
  28. package/dist/commands/monitor.js +13 -8
  29. package/dist/commands/qa.d.ts +2 -0
  30. package/dist/commands/qa.js +43 -0
  31. package/dist/commands/review-pr.js +108 -102
  32. package/dist/commands/sdk.js +128 -122
  33. package/dist/commands/security.js +86 -80
  34. package/dist/commands/test.js +91 -92
  35. package/dist/commands/version.js +104 -75
  36. package/dist/commands/watch.js +130 -114
  37. package/dist/config/types.js +2 -2
  38. package/dist/context-hub/index.d.ts +23 -0
  39. package/dist/context-hub/index.js +179 -0
  40. package/dist/context-hub/mappings.d.ts +8 -0
  41. package/dist/context-hub/mappings.js +55 -0
  42. package/dist/context-hub/types.d.ts +33 -0
  43. package/dist/context-hub/types.js +1 -0
  44. package/dist/generator/generator.js +39 -6
  45. package/dist/generator/types.d.ts +7 -0
  46. package/dist/generator/writer.d.ts +3 -1
  47. package/dist/generator/writer.js +24 -4
  48. package/dist/llm/anthropic-client.d.ts +1 -0
  49. package/dist/llm/anthropic-client.js +3 -1
  50. package/dist/llm/index.d.ts +6 -4
  51. package/dist/llm/index.js +76 -261
  52. package/dist/llm/openai-client.d.ts +1 -0
  53. package/dist/llm/openai-client.js +7 -2
  54. package/dist/qa/checks.d.ts +10 -0
  55. package/dist/qa/checks.js +492 -0
  56. package/dist/qa/fixes.d.ts +30 -0
  57. package/dist/qa/fixes.js +277 -0
  58. package/dist/qa/index.d.ts +29 -0
  59. package/dist/qa/index.js +187 -0
  60. package/dist/qa/types.d.ts +24 -0
  61. package/dist/qa/types.js +1 -0
  62. package/dist/scanner/csharp.d.ts +23 -0
  63. package/dist/scanner/csharp.js +421 -0
  64. package/dist/scanner/index.js +16 -2
  65. package/dist/scanner/java.d.ts +39 -0
  66. package/dist/scanner/java.js +318 -0
  67. package/dist/scanner/kotlin.d.ts +23 -0
  68. package/dist/scanner/kotlin.js +389 -0
  69. package/dist/scanner/php.d.ts +57 -0
  70. package/dist/scanner/php.js +351 -0
  71. package/dist/scanner/ruby.d.ts +36 -0
  72. package/dist/scanner/ruby.js +431 -0
  73. package/dist/scanner/swift.d.ts +25 -0
  74. package/dist/scanner/swift.js +392 -0
  75. package/dist/scanner/types.d.ts +1 -1
  76. package/dist/template/content/docs/_navigation.json +46 -0
  77. package/dist/template/content/docs/_sidebars.json +684 -0
  78. package/dist/template/content/docs/core.md +4544 -0
  79. package/dist/template/content/docs/index.mdx +89 -0
  80. package/dist/template/content/docs/integrations.md +1158 -0
  81. package/dist/template/content/docs/llms-full.md +403 -0
  82. package/dist/template/content/docs/llms.txt +4588 -0
  83. package/dist/template/content/docs/other.md +10379 -0
  84. package/dist/template/content/docs/tools.md +746 -0
  85. package/dist/template/content/docs/types.md +531 -0
  86. package/dist/template/docs.json +13 -11
  87. package/dist/template/mdx-components.tsx +27 -2
  88. package/dist/template/package.json +6 -0
  89. package/dist/template/public/search-index.json +1 -1
  90. package/dist/template/scripts/build-search-index.mjs +84 -6
  91. package/dist/template/src/app/api/chat/route.ts +83 -128
  92. package/dist/template/src/app/docs/[...slug]/page.tsx +75 -20
  93. package/dist/template/src/app/docs/llms-full.md +151 -4
  94. package/dist/template/src/app/docs/llms.txt +2464 -847
  95. package/dist/template/src/app/docs/page.mdx +48 -38
  96. package/dist/template/src/app/layout.tsx +3 -1
  97. package/dist/template/src/app/page.tsx +22 -8
  98. package/dist/template/src/components/ai-chat.tsx +73 -64
  99. package/dist/template/src/components/breadcrumbs.tsx +21 -23
  100. package/dist/template/src/components/copy-button.tsx +13 -9
  101. package/dist/template/src/components/copy-page-button.tsx +54 -0
  102. package/dist/template/src/components/docs-layout.tsx +37 -25
  103. package/dist/template/src/components/header.tsx +51 -10
  104. package/dist/template/src/components/mdx/card.tsx +17 -3
  105. package/dist/template/src/components/mdx/code-block.tsx +13 -9
  106. package/dist/template/src/components/mdx/code-group.tsx +13 -8
  107. package/dist/template/src/components/mdx/heading.tsx +15 -2
  108. package/dist/template/src/components/mdx/highlighted-code.tsx +13 -8
  109. package/dist/template/src/components/mdx/index.tsx +2 -0
  110. package/dist/template/src/components/mdx/mermaid.tsx +110 -0
  111. package/dist/template/src/components/mdx/screenshot.tsx +150 -0
  112. package/dist/template/src/components/scroll-to-hash.tsx +48 -0
  113. package/dist/template/src/components/sidebar.tsx +12 -18
  114. package/dist/template/src/components/table-of-contents.tsx +9 -0
  115. package/dist/template/src/lib/highlight.ts +3 -88
  116. package/dist/template/src/lib/navigation.ts +159 -0
  117. package/dist/template/src/styles/globals.css +17 -6
  118. package/dist/utils/validation.d.ts +0 -3
  119. package/dist/utils/validation.js +0 -26
  120. package/package.json +3 -2
@@ -0,0 +1,351 @@
1
+ import { readFileSync } from 'fs';
2
+ /**
3
+ * Scanner for PHP source files
4
+ * Extracts: classes, interfaces, enums, traits, abstract classes,
5
+ * public functions, public methods, public static methods
6
+ */
7
+ export class PHPScanner {
8
+ languages = ['php'];
9
+ canHandle(filePath) {
10
+ return (/\.php$/.test(filePath) &&
11
+ !filePath.includes('Test.php') &&
12
+ !filePath.includes('/tests/') &&
13
+ !filePath.includes('/test/'));
14
+ }
15
+ async scanFile(filePath) {
16
+ try {
17
+ const source = readFileSync(filePath, 'utf-8');
18
+ const elements = [];
19
+ const errors = [];
20
+ const lines = source.split('\n');
21
+ // Extract namespace as package name
22
+ const namespaceMatch = source.match(/^namespace\s+([\w\\]+)\s*;/m);
23
+ const packageName = namespaceMatch?.[1] ?? 'global';
24
+ // Extract use/import statements for context
25
+ const imports = this.extractImports(source);
26
+ // Find all public API elements
27
+ this.extractTypes(source, lines, filePath, packageName, imports, elements);
28
+ this.extractMethods(source, lines, filePath, packageName, imports, elements);
29
+ this.extractFunctions(source, lines, filePath, packageName, imports, elements);
30
+ return {
31
+ filePath,
32
+ language: 'php',
33
+ elements,
34
+ errors
35
+ };
36
+ }
37
+ catch (err) {
38
+ return {
39
+ filePath,
40
+ language: 'php',
41
+ elements: [],
42
+ errors: [`Failed to parse: ${err}`]
43
+ };
44
+ }
45
+ }
46
+ extractImports(source) {
47
+ const imports = [];
48
+ const useMatches = source.matchAll(/^use\s+([\w\\]+)(?:\s+as\s+\w+)?;/gm);
49
+ for (const m of useMatches) {
50
+ if (m[1])
51
+ imports.push(m[1]);
52
+ }
53
+ return imports;
54
+ }
55
+ /**
56
+ * Extract classes, interfaces, enums, traits, abstract classes
57
+ */
58
+ extractTypes(source, lines, filePath, packageName, imports, elements) {
59
+ // Match: class, abstract class, final class, readonly class, final readonly class, interface, enum, trait
60
+ const typeRegex = /^(?:(?:abstract|final|readonly)\s+)*(?:class|interface|enum|trait)\s+(\w+)/gm;
61
+ let match;
62
+ while ((match = typeRegex.exec(source)) !== null) {
63
+ const name = match[1];
64
+ if (!name)
65
+ continue;
66
+ const fullMatch = match[0];
67
+ const lineNumber = this.getLineNumber(source, match.index);
68
+ const docstring = this.getDocComment(lines, lineNumber - 1);
69
+ const signature = fullMatch.trim();
70
+ elements.push({
71
+ kind: 'class',
72
+ name,
73
+ signature,
74
+ parameters: [],
75
+ docstring,
76
+ filePath,
77
+ lineNumber,
78
+ isExported: true,
79
+ isPublic: true,
80
+ imports,
81
+ packageName,
82
+ sourceContext: this.getSourceContext(lines, lineNumber, 15)
83
+ });
84
+ }
85
+ }
86
+ /**
87
+ * Extract the content between matching parentheses, handling nested parens.
88
+ * Starts at the given index which must point to an opening '('.
89
+ */
90
+ extractParenContent(source, openIndex) {
91
+ if (source[openIndex] !== '(')
92
+ return null;
93
+ let depth = 0;
94
+ for (let i = openIndex; i < source.length; i++) {
95
+ if (source[i] === '(')
96
+ depth++;
97
+ else if (source[i] === ')') {
98
+ depth--;
99
+ if (depth === 0)
100
+ return source.slice(openIndex + 1, i);
101
+ }
102
+ }
103
+ return null;
104
+ }
105
+ /**
106
+ * Extract public methods (instance and static) from classes/interfaces/traits
107
+ * Skips private and protected methods
108
+ */
109
+ extractMethods(source, lines, filePath, packageName, imports, elements) {
110
+ // First, build a map of class boundaries to determine parentClass
111
+ const classBoundaries = this.getClassBoundaries(source);
112
+ // Match public methods up to and including the opening paren
113
+ // Supports: public function, public static function, public final function,
114
+ // final public function, final public static function, etc.
115
+ const methodRegex = /^[ \t]+(?:final\s+)?public\s+(?:(?:static|abstract|final)\s+)*function\s+(\w+)\s*\(/gm;
116
+ let match;
117
+ while ((match = methodRegex.exec(source)) !== null) {
118
+ const name = match[1];
119
+ if (!name)
120
+ continue;
121
+ // Extract params using balanced-paren helper
122
+ const openParenIndex = match.index + match[0].length - 1;
123
+ const paramsStr = this.extractParenContent(source, openParenIndex);
124
+ if (paramsStr === null)
125
+ continue;
126
+ // Look for return type after the closing paren
127
+ const closeParenIndex = openParenIndex + 1 + paramsStr.length; // index of ')'
128
+ const afterParen = source.slice(closeParenIndex + 1);
129
+ const returnTypeMatch = afterParen.match(/^\s*:\s*([\w\\|?]+)/);
130
+ const returnType = returnTypeMatch?.[1]?.trim() || undefined;
131
+ const lineNumber = this.getLineNumber(source, match.index);
132
+ const docstring = this.getDocComment(lines, lineNumber - 1);
133
+ const parameters = this.parsePHPParams(paramsStr);
134
+ const parentClass = this.findParentClass(match.index, classBoundaries);
135
+ // Build signature including params and return type
136
+ const sigBase = match[0] + paramsStr + ')';
137
+ const signature = (returnType ? sigBase + ': ' + returnType : sigBase).trim();
138
+ elements.push({
139
+ kind: 'method',
140
+ name,
141
+ signature,
142
+ parameters,
143
+ returnType,
144
+ docstring,
145
+ filePath,
146
+ lineNumber,
147
+ parentClass,
148
+ isExported: true,
149
+ isPublic: true,
150
+ imports,
151
+ packageName,
152
+ sourceContext: this.getSourceContext(lines, lineNumber)
153
+ });
154
+ }
155
+ }
156
+ /**
157
+ * Extract standalone functions (not inside a class/interface/trait)
158
+ */
159
+ extractFunctions(source, lines, filePath, packageName, imports, elements) {
160
+ const classBoundaries = this.getClassBoundaries(source);
161
+ // Match top-level functions up to and including the opening paren
162
+ // Must start at the beginning of a line (no leading whitespace = not a method)
163
+ const funcRegex = /^function\s+(\w+)\s*\(/gm;
164
+ let match;
165
+ while ((match = funcRegex.exec(source)) !== null) {
166
+ const name = match[1];
167
+ if (!name)
168
+ continue;
169
+ // Skip if inside a class boundary
170
+ const parentClass = this.findParentClass(match.index, classBoundaries);
171
+ if (parentClass)
172
+ continue;
173
+ // Extract params using balanced-paren helper
174
+ const openParenIndex = match.index + match[0].length - 1;
175
+ const paramsStr = this.extractParenContent(source, openParenIndex);
176
+ if (paramsStr === null)
177
+ continue;
178
+ // Look for return type after the closing paren
179
+ const closeParenIndex = openParenIndex + 1 + paramsStr.length;
180
+ const afterParen = source.slice(closeParenIndex + 1);
181
+ const returnTypeMatch = afterParen.match(/^\s*:\s*([\w\\|?]+)/);
182
+ const returnType = returnTypeMatch?.[1]?.trim() || undefined;
183
+ const lineNumber = this.getLineNumber(source, match.index);
184
+ const docstring = this.getDocComment(lines, lineNumber - 1);
185
+ const parameters = this.parsePHPParams(paramsStr);
186
+ // Build signature including params and return type
187
+ const sigBase = match[0] + paramsStr + ')';
188
+ const signature = (returnType ? sigBase + ': ' + returnType : sigBase).trim();
189
+ elements.push({
190
+ kind: 'function',
191
+ name,
192
+ signature,
193
+ parameters,
194
+ returnType,
195
+ docstring,
196
+ filePath,
197
+ lineNumber,
198
+ isExported: true,
199
+ isPublic: true,
200
+ imports,
201
+ packageName,
202
+ sourceContext: this.getSourceContext(lines, lineNumber)
203
+ });
204
+ }
205
+ }
206
+ /**
207
+ * Build a map of class/interface/trait/enum boundaries (start offset, end offset, name)
208
+ */
209
+ getClassBoundaries(source) {
210
+ const boundaries = [];
211
+ const typeRegex = /^(?:(?:abstract|final|readonly)\s+)*(?:class|interface|enum|trait)\s+(\w+)[^{]*\{/gm;
212
+ let match;
213
+ while ((match = typeRegex.exec(source)) !== null) {
214
+ const name = match[1];
215
+ if (!name)
216
+ continue;
217
+ const start = match.index;
218
+ const braceStart = source.indexOf('{', start + match[0].length - 1);
219
+ const end = this.findMatchingBrace(source, braceStart);
220
+ boundaries.push({ name, start, end });
221
+ }
222
+ return boundaries;
223
+ }
224
+ /**
225
+ * Find the matching closing brace for an opening brace
226
+ */
227
+ findMatchingBrace(source, openPos) {
228
+ let depth = 0;
229
+ for (let i = openPos; i < source.length; i++) {
230
+ if (source[i] === '{')
231
+ depth++;
232
+ else if (source[i] === '}') {
233
+ depth--;
234
+ if (depth === 0)
235
+ return i;
236
+ }
237
+ }
238
+ return source.length;
239
+ }
240
+ /**
241
+ * Find which class/interface/trait contains the given source offset
242
+ */
243
+ findParentClass(offset, boundaries) {
244
+ for (const b of boundaries) {
245
+ if (offset > b.start && offset < b.end) {
246
+ return b.name;
247
+ }
248
+ }
249
+ return undefined;
250
+ }
251
+ /**
252
+ * Parse PHP function parameters into Parameter objects
253
+ * Handles: type hints (?string, int|string, array), default values
254
+ */
255
+ parsePHPParams(paramsStr) {
256
+ if (!paramsStr.trim())
257
+ return [];
258
+ const params = [];
259
+ const parts = this.splitParams(paramsStr);
260
+ for (const part of parts) {
261
+ const trimmed = part.trim();
262
+ if (!trimmed)
263
+ continue;
264
+ // PHP param format: [?]Type $name [= default]
265
+ // or: Type|Type2 $name
266
+ // or: $name (no type hint)
267
+ const paramMatch = trimmed.match(/^((?:[\w\\|?]+\s+)?)(\$\w+)(?:\s*=\s*(.+))?$/);
268
+ if (paramMatch) {
269
+ const type = paramMatch[1]?.trim() || undefined;
270
+ const name = paramMatch[2]?.replace(/^\$/, '') ?? '';
271
+ const defaultValue = paramMatch[3]?.trim() || undefined;
272
+ if (name) {
273
+ params.push({ name, type, default: defaultValue });
274
+ }
275
+ }
276
+ }
277
+ return params;
278
+ }
279
+ /**
280
+ * Split parameter string by commas, respecting nested brackets
281
+ */
282
+ splitParams(str) {
283
+ const parts = [];
284
+ let depth = 0;
285
+ let current = '';
286
+ for (const char of str) {
287
+ if (char === '(' || char === '[' || char === '{' || char === '<')
288
+ depth++;
289
+ else if (char === ')' || char === ']' || char === '}' || char === '>')
290
+ depth--;
291
+ else if (char === ',' && depth === 0) {
292
+ parts.push(current);
293
+ current = '';
294
+ continue;
295
+ }
296
+ current += char;
297
+ }
298
+ if (current.trim())
299
+ parts.push(current);
300
+ return parts;
301
+ }
302
+ getLineNumber(source, index) {
303
+ return source.slice(0, index).split('\n').length;
304
+ }
305
+ /**
306
+ * Extract PHPDoc block comment above a given line
307
+ */
308
+ getDocComment(lines, lineIndex) {
309
+ // Look for a closing */ above the declaration line
310
+ let i = lineIndex - 1;
311
+ // Skip blank lines and PHP 8 attribute lines (#[...])
312
+ while (i >= 0) {
313
+ const trimmed = lines[i]?.trim() ?? '';
314
+ if (trimmed === '') {
315
+ i--;
316
+ }
317
+ else if (trimmed.startsWith('#[')) {
318
+ i--;
319
+ }
320
+ else {
321
+ break;
322
+ }
323
+ }
324
+ if (i < 0)
325
+ return undefined;
326
+ const closeLine = lines[i];
327
+ if (!closeLine || !closeLine.trim().endsWith('*/'))
328
+ return undefined;
329
+ // Walk up to find the opening /**
330
+ let start = i;
331
+ while (start >= 0 && !lines[start]?.includes('/**')) {
332
+ start--;
333
+ }
334
+ if (start < 0 || !lines[start]?.includes('/**'))
335
+ return undefined;
336
+ const block = lines.slice(start, i + 1).join('\n');
337
+ const cleaned = block
338
+ .replace(/\/\*\*/, '')
339
+ .replace(/\*\//, '')
340
+ .split('\n')
341
+ .map(l => l.trim().replace(/^\*\s?/, ''))
342
+ .filter(Boolean)
343
+ .join('\n');
344
+ return cleaned || undefined;
345
+ }
346
+ getSourceContext(lines, lineNumber, context = 5) {
347
+ const start = Math.max(0, lineNumber - context - 1);
348
+ const end = Math.min(lines.length, lineNumber + context);
349
+ return lines.slice(start, end).join('\n');
350
+ }
351
+ }
@@ -0,0 +1,36 @@
1
+ import { Scanner, ScanResult } from './types.js';
2
+ /**
3
+ * Scanner for Ruby source files
4
+ * Extracts: classes, modules, methods (public only)
5
+ */
6
+ export declare class RubyScanner implements Scanner {
7
+ languages: string[];
8
+ canHandle(filePath: string): boolean;
9
+ scanFile(filePath: string): Promise<ScanResult>;
10
+ private extractImports;
11
+ private extractModuleNesting;
12
+ private extractClasses;
13
+ private extractModules;
14
+ /**
15
+ * Get the body of a module/class starting at the given source index.
16
+ * Returns the text between the opening line and its matching `end`, or null.
17
+ */
18
+ private getModuleBody;
19
+ private extractMethods;
20
+ /**
21
+ * Build a map of lineNumber → visibility for every `def` line.
22
+ * Ruby's `private` / `protected` markers apply to all subsequent defs
23
+ * within the same class/module scope until another visibility marker.
24
+ */
25
+ private buildVisibilityMap;
26
+ private findParentClass;
27
+ private parseRubyParams;
28
+ private splitParams;
29
+ private getDocComment;
30
+ /**
31
+ * Extract @return type from YARD comments above a method.
32
+ */
33
+ private extractReturnType;
34
+ private getLineNumber;
35
+ private getSourceContext;
36
+ }