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
@@ -5,7 +5,12 @@ const CONFIG_FILE = 'skrypt.versions.json';
5
5
  function loadVersionConfig(docsPath) {
6
6
  const configPath = join(docsPath, CONFIG_FILE);
7
7
  if (existsSync(configPath)) {
8
- return JSON.parse(readFileSync(configPath, 'utf-8'));
8
+ try {
9
+ return JSON.parse(readFileSync(configPath, 'utf-8'));
10
+ }
11
+ catch {
12
+ return { versions: [], current: '' };
13
+ }
9
14
  }
10
15
  return { versions: [], current: '' };
11
16
  }
@@ -20,16 +25,22 @@ versionCommand
20
25
  .description('List all versions')
21
26
  .argument('[docs-path]', 'Documentation directory', './docs')
22
27
  .action((docsPath) => {
23
- const config = loadVersionConfig(resolve(docsPath));
24
- if (config.versions.length === 0) {
25
- console.log('No versions configured.');
26
- console.log('Run: skrypt version create <version>');
27
- return;
28
+ try {
29
+ const config = loadVersionConfig(resolve(docsPath));
30
+ if (config.versions.length === 0) {
31
+ console.log('No versions configured.');
32
+ console.log('Run: skrypt version create <version>');
33
+ return;
34
+ }
35
+ console.log('Versions:');
36
+ for (const v of config.versions) {
37
+ const marker = v === config.current ? ' (current)' : '';
38
+ console.log(` ${v}${marker}`);
39
+ }
28
40
  }
29
- console.log('Versions:');
30
- for (const v of config.versions) {
31
- const marker = v === config.current ? ' (current)' : '';
32
- console.log(` ${v}${marker}`);
41
+ catch (err) {
42
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
43
+ process.exit(1);
33
44
  }
34
45
  });
35
46
  versionCommand
@@ -39,49 +50,55 @@ versionCommand
39
50
  .argument('[docs-path]', 'Documentation directory', './docs')
40
51
  .option('--from <version>', 'Copy from existing version instead of current')
41
52
  .action((version, docsPath, options) => {
42
- const resolvedPath = resolve(docsPath);
43
- const config = loadVersionConfig(resolvedPath);
44
- if (config.versions.includes(version)) {
45
- console.error(`Version ${version} already exists.`);
46
- process.exit(1);
47
- }
48
- const versionDir = join(resolvedPath, 'versions', version);
49
- if (existsSync(versionDir)) {
50
- console.error(`Directory already exists: ${versionDir}`);
51
- process.exit(1);
52
- }
53
- // Determine source
54
- let sourceDir;
55
- if (options.from) {
56
- sourceDir = join(resolvedPath, 'versions', options.from);
57
- if (!existsSync(sourceDir)) {
58
- console.error(`Source version not found: ${options.from}`);
53
+ try {
54
+ const resolvedPath = resolve(docsPath);
55
+ const config = loadVersionConfig(resolvedPath);
56
+ if (config.versions.includes(version)) {
57
+ console.error(`Version ${version} already exists.`);
59
58
  process.exit(1);
60
59
  }
60
+ const versionDir = join(resolvedPath, 'versions', version);
61
+ if (existsSync(versionDir)) {
62
+ console.error(`Directory already exists: ${versionDir}`);
63
+ process.exit(1);
64
+ }
65
+ // Determine source
66
+ let sourceDir;
67
+ if (options.from) {
68
+ sourceDir = join(resolvedPath, 'versions', options.from);
69
+ if (!existsSync(sourceDir)) {
70
+ console.error(`Source version not found: ${options.from}`);
71
+ process.exit(1);
72
+ }
73
+ }
74
+ else {
75
+ // Copy current docs (excluding versions folder)
76
+ sourceDir = resolvedPath;
77
+ }
78
+ // Create version directory
79
+ mkdirSync(versionDir, { recursive: true });
80
+ // Copy files
81
+ const entries = readdirSync(sourceDir, { withFileTypes: true });
82
+ for (const entry of entries) {
83
+ if (entry.name === 'versions' || entry.name === CONFIG_FILE)
84
+ continue;
85
+ const srcPath = join(sourceDir, entry.name);
86
+ const destPath = join(versionDir, entry.name);
87
+ cpSync(srcPath, destPath, { recursive: true });
88
+ }
89
+ // Update config
90
+ config.versions.push(version);
91
+ if (!config.current) {
92
+ config.current = version;
93
+ }
94
+ saveVersionConfig(resolvedPath, config);
95
+ console.log(`Created version: ${version}`);
96
+ console.log(` Location: ${versionDir}`);
61
97
  }
62
- else {
63
- // Copy current docs (excluding versions folder)
64
- sourceDir = resolvedPath;
65
- }
66
- // Create version directory
67
- mkdirSync(versionDir, { recursive: true });
68
- // Copy files
69
- const entries = readdirSync(sourceDir, { withFileTypes: true });
70
- for (const entry of entries) {
71
- if (entry.name === 'versions' || entry.name === CONFIG_FILE)
72
- continue;
73
- const srcPath = join(sourceDir, entry.name);
74
- const destPath = join(versionDir, entry.name);
75
- cpSync(srcPath, destPath, { recursive: true });
76
- }
77
- // Update config
78
- config.versions.push(version);
79
- if (!config.current) {
80
- config.current = version;
98
+ catch (err) {
99
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
100
+ process.exit(1);
81
101
  }
82
- saveVersionConfig(resolvedPath, config);
83
- console.log(`Created version: ${version}`);
84
- console.log(` Location: ${versionDir}`);
85
102
  });
86
103
  versionCommand
87
104
  .command('set-current')
@@ -89,16 +106,22 @@ versionCommand
89
106
  .argument('<version>', 'Version to set as current')
90
107
  .argument('[docs-path]', 'Documentation directory', './docs')
91
108
  .action((version, docsPath) => {
92
- const resolvedPath = resolve(docsPath);
93
- const config = loadVersionConfig(resolvedPath);
94
- if (!config.versions.includes(version)) {
95
- console.error(`Version ${version} not found.`);
96
- console.log('Available versions:', config.versions.join(', '));
109
+ try {
110
+ const resolvedPath = resolve(docsPath);
111
+ const config = loadVersionConfig(resolvedPath);
112
+ if (!config.versions.includes(version)) {
113
+ console.error(`Version ${version} not found.`);
114
+ console.log('Available versions:', config.versions.join(', '));
115
+ process.exit(1);
116
+ }
117
+ config.current = version;
118
+ saveVersionConfig(resolvedPath, config);
119
+ console.log(`Set current version to: ${version}`);
120
+ }
121
+ catch (err) {
122
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
97
123
  process.exit(1);
98
124
  }
99
- config.current = version;
100
- saveVersionConfig(resolvedPath, config);
101
- console.log(`Set current version to: ${version}`);
102
125
  });
103
126
  versionCommand
104
127
  .command('delete')
@@ -107,25 +130,31 @@ versionCommand
107
130
  .argument('[docs-path]', 'Documentation directory', './docs')
108
131
  .option('--force', 'Skip confirmation')
109
132
  .action((version, docsPath, options) => {
110
- const resolvedPath = resolve(docsPath);
111
- const config = loadVersionConfig(resolvedPath);
112
- if (!config.versions.includes(version)) {
113
- console.error(`Version ${version} not found.`);
114
- process.exit(1);
133
+ try {
134
+ const resolvedPath = resolve(docsPath);
135
+ const config = loadVersionConfig(resolvedPath);
136
+ if (!config.versions.includes(version)) {
137
+ console.error(`Version ${version} not found.`);
138
+ process.exit(1);
139
+ }
140
+ if (version === config.current && !options.force) {
141
+ console.error(`Cannot delete current version. Use --force or set a different current version first.`);
142
+ process.exit(1);
143
+ }
144
+ const versionDir = join(resolvedPath, 'versions', version);
145
+ // Remove from config
146
+ config.versions = config.versions.filter(v => v !== version);
147
+ if (config.current === version) {
148
+ config.current = config.versions[0] || '';
149
+ }
150
+ saveVersionConfig(resolvedPath, config);
151
+ // Note: Not actually deleting files for safety
152
+ console.log(`Removed version ${version} from config.`);
153
+ console.log(`Files still exist at: ${versionDir}`);
154
+ console.log(`To fully delete, run: rm -rf "${versionDir}"`);
115
155
  }
116
- if (version === config.current && !options.force) {
117
- console.error(`Cannot delete current version. Use --force or set a different current version first.`);
156
+ catch (err) {
157
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
118
158
  process.exit(1);
119
159
  }
120
- const versionDir = join(resolvedPath, 'versions', version);
121
- // Remove from config
122
- config.versions = config.versions.filter(v => v !== version);
123
- if (config.current === version) {
124
- config.current = config.versions[0] || '';
125
- }
126
- saveVersionConfig(resolvedPath, config);
127
- // Note: Not actually deleting files for safety
128
- console.log(`Removed version ${version} from config.`);
129
- console.log(`Files still exist at: ${versionDir}`);
130
- console.log(`To fully delete, run: rm -rf "${versionDir}"`);
131
160
  });
@@ -7,6 +7,7 @@ import { DEFAULT_MODELS } from '../config/types.js';
7
7
  import { scanDirectory } from '../scanner/index.js';
8
8
  import { createLLMClient } from '../llm/index.js';
9
9
  import { generateForElements, groupDocsByFile, writeDocsToDirectory } from '../generator/index.js';
10
+ import { runQA, printQAReport, fixQAIssues, printFixReport } from '../qa/index.js';
10
11
  export const watchCommand = new Command('watch')
11
12
  .description('Watch source files and regenerate docs on changes')
12
13
  .argument('<source>', 'Source directory to watch')
@@ -16,127 +17,142 @@ export const watchCommand = new Command('watch')
16
17
  .option('--model <name>', 'LLM model name')
17
18
  .option('--debounce <ms>', 'Debounce time in milliseconds', '1000')
18
19
  .action(async (source, options) => {
19
- const config = loadConfig(options.config);
20
- if (source)
21
- config.source.path = source;
22
- if (options.output)
23
- config.output.path = options.output;
24
- if (options.provider) {
25
- config.llm.provider = options.provider;
26
- if (!options.model) {
27
- config.llm.model = DEFAULT_MODELS[config.llm.provider];
20
+ try {
21
+ const config = loadConfig(options.config);
22
+ if (source)
23
+ config.source.path = source;
24
+ if (options.output)
25
+ config.output.path = options.output;
26
+ if (options.provider) {
27
+ config.llm.provider = options.provider;
28
+ if (!options.model) {
29
+ config.llm.model = DEFAULT_MODELS[config.llm.provider];
30
+ }
28
31
  }
29
- }
30
- if (options.model)
31
- config.llm.model = options.model;
32
- const errors = validateConfig(config);
33
- if (errors.length > 0) {
34
- console.error('Config errors:', errors);
35
- process.exit(1);
36
- }
37
- const { ok, envKey } = checkApiKey(config.llm.provider);
38
- if (!ok && envKey) {
39
- console.error(`Error: ${envKey} required`);
40
- process.exit(1);
41
- }
42
- const sourcePath = resolve(config.source.path);
43
- const outputPath = resolve(config.output.path);
44
- if (!existsSync(sourcePath)) {
45
- console.error(`Source not found: ${sourcePath}`);
46
- process.exit(1);
47
- }
48
- console.log('skrypt watch');
49
- console.log(` source: ${sourcePath}`);
50
- console.log(` output: ${outputPath}`);
51
- console.log(` provider: ${config.llm.provider}`);
52
- console.log('');
53
- const client = createLLMClient({
54
- provider: config.llm.provider,
55
- model: config.llm.model,
56
- baseUrl: config.llm.baseUrl
57
- });
58
- let generating = false;
59
- let pendingGenerate = false;
60
- const debounceMs = parseInt(options.debounce);
61
- async function generate() {
62
- if (generating) {
63
- pendingGenerate = true;
64
- return;
32
+ if (options.model)
33
+ config.llm.model = options.model;
34
+ const errors = validateConfig(config);
35
+ if (errors.length > 0) {
36
+ console.error('Config errors:', errors);
37
+ process.exit(1);
38
+ }
39
+ const { ok, envKey } = checkApiKey(config.llm.provider);
40
+ if (!ok && envKey) {
41
+ console.error(`Error: ${envKey} required`);
42
+ process.exit(1);
65
43
  }
66
- generating = true;
67
- const startTime = Date.now();
68
- try {
69
- console.log('\n[' + new Date().toLocaleTimeString() + '] Regenerating docs...');
70
- const scanResult = await scanDirectory(sourcePath, {
71
- include: config.source.include,
72
- exclude: config.source.exclude,
73
- });
74
- if (scanResult.totalElements === 0) {
75
- console.log(' No elements found');
44
+ const sourcePath = resolve(config.source.path);
45
+ const outputPath = resolve(config.output.path);
46
+ if (!existsSync(sourcePath)) {
47
+ console.error(`Source not found: ${sourcePath}`);
48
+ process.exit(1);
49
+ }
50
+ console.log('skrypt watch');
51
+ console.log(` source: ${sourcePath}`);
52
+ console.log(` output: ${outputPath}`);
53
+ console.log(` provider: ${config.llm.provider}`);
54
+ console.log('');
55
+ const client = createLLMClient({
56
+ provider: config.llm.provider,
57
+ model: config.llm.model,
58
+ baseUrl: config.llm.baseUrl
59
+ });
60
+ let generating = false;
61
+ let pendingGenerate = false;
62
+ const debounceMs = parseInt(options.debounce, 10);
63
+ if (isNaN(debounceMs) || debounceMs < 1) {
64
+ console.error('Error: --debounce must be a positive number');
65
+ process.exit(1);
66
+ }
67
+ async function generate() {
68
+ if (generating) {
69
+ pendingGenerate = true;
76
70
  return;
77
71
  }
78
- const allElements = [];
79
- for (const file of scanResult.files) {
80
- allElements.push(...file.elements);
72
+ generating = true;
73
+ const startTime = Date.now();
74
+ try {
75
+ console.log('\n[' + new Date().toLocaleTimeString() + '] Regenerating docs...');
76
+ const scanResult = await scanDirectory(sourcePath, {
77
+ include: config.source.include,
78
+ exclude: config.source.exclude,
79
+ });
80
+ if (scanResult.totalElements === 0) {
81
+ console.log(' No elements found');
82
+ return;
83
+ }
84
+ const allElements = [];
85
+ for (const file of scanResult.files) {
86
+ allElements.push(...file.elements);
87
+ }
88
+ const docs = await generateForElements(allElements, client, {
89
+ onProgress: (p) => {
90
+ process.stdout.write(`\r [${p.current}/${p.total}] ${p.element}`.padEnd(60));
91
+ }
92
+ });
93
+ const fileResults = groupDocsByFile(docs);
94
+ await writeDocsToDirectory(fileResults, outputPath, sourcePath);
95
+ // Auto-fix then run QA on generated output
96
+ const fixReport = fixQAIssues(outputPath);
97
+ printFixReport(fixReport);
98
+ const qaReport = runQA(outputPath);
99
+ printQAReport(qaReport);
100
+ const duration = ((Date.now() - startTime) / 1000).toFixed(1);
101
+ console.log(`\n Done in ${duration}s`);
102
+ }
103
+ catch (err) {
104
+ console.error('\n Error:', err);
81
105
  }
82
- const docs = await generateForElements(allElements, client, {
83
- onProgress: (p) => {
84
- process.stdout.write(`\r [${p.current}/${p.total}] ${p.element}`.padEnd(60));
106
+ finally {
107
+ generating = false;
108
+ if (pendingGenerate) {
109
+ pendingGenerate = false;
110
+ setTimeout(generate, debounceMs);
85
111
  }
86
- });
87
- const fileResults = groupDocsByFile(docs);
88
- await writeDocsToDirectory(fileResults, outputPath, sourcePath);
89
- const duration = ((Date.now() - startTime) / 1000).toFixed(1);
90
- console.log(`\n Done in ${duration}s`);
91
- }
92
- catch (err) {
93
- console.error('\n Error:', err);
94
- }
95
- finally {
96
- generating = false;
97
- if (pendingGenerate) {
98
- pendingGenerate = false;
99
- setTimeout(generate, debounceMs);
100
112
  }
101
113
  }
114
+ // Initial generation
115
+ await generate();
116
+ // Watch for changes
117
+ console.log('\nWatching for changes... (Ctrl+C to stop)');
118
+ let debounceTimer = null;
119
+ const watcher = watch(sourcePath, {
120
+ ignored: [
121
+ '**/node_modules/**',
122
+ '**/.git/**',
123
+ '**/dist/**',
124
+ '**/__pycache__/**',
125
+ ],
126
+ persistent: true,
127
+ ignoreInitial: true,
128
+ });
129
+ watcher.on('change', (path) => {
130
+ console.log(` Changed: ${path}`);
131
+ if (debounceTimer)
132
+ clearTimeout(debounceTimer);
133
+ debounceTimer = setTimeout(generate, debounceMs);
134
+ });
135
+ watcher.on('add', (path) => {
136
+ console.log(` Added: ${path}`);
137
+ if (debounceTimer)
138
+ clearTimeout(debounceTimer);
139
+ debounceTimer = setTimeout(generate, debounceMs);
140
+ });
141
+ watcher.on('unlink', (path) => {
142
+ console.log(` Removed: ${path}`);
143
+ if (debounceTimer)
144
+ clearTimeout(debounceTimer);
145
+ debounceTimer = setTimeout(generate, debounceMs);
146
+ });
147
+ // Keep process alive
148
+ process.on('SIGINT', () => {
149
+ console.log('\nStopping watch...');
150
+ watcher.close();
151
+ process.exit(0);
152
+ });
153
+ }
154
+ catch (err) {
155
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
156
+ process.exit(1);
102
157
  }
103
- // Initial generation
104
- await generate();
105
- // Watch for changes
106
- console.log('\nWatching for changes... (Ctrl+C to stop)');
107
- let debounceTimer = null;
108
- const watcher = watch(sourcePath, {
109
- ignored: [
110
- '**/node_modules/**',
111
- '**/.git/**',
112
- '**/dist/**',
113
- '**/__pycache__/**',
114
- ],
115
- persistent: true,
116
- ignoreInitial: true,
117
- });
118
- watcher.on('change', (path) => {
119
- console.log(` Changed: ${path}`);
120
- if (debounceTimer)
121
- clearTimeout(debounceTimer);
122
- debounceTimer = setTimeout(generate, debounceMs);
123
- });
124
- watcher.on('add', (path) => {
125
- console.log(` Added: ${path}`);
126
- if (debounceTimer)
127
- clearTimeout(debounceTimer);
128
- debounceTimer = setTimeout(generate, debounceMs);
129
- });
130
- watcher.on('unlink', (path) => {
131
- console.log(` Removed: ${path}`);
132
- if (debounceTimer)
133
- clearTimeout(debounceTimer);
134
- debounceTimer = setTimeout(generate, debounceMs);
135
- });
136
- // Keep process alive
137
- process.on('SIGINT', () => {
138
- console.log('\nStopping watch...');
139
- watcher.close();
140
- process.exit(0);
141
- });
142
158
  });
@@ -20,8 +20,8 @@ export const DEFAULT_CONFIG = {
20
20
  version: 1,
21
21
  source: {
22
22
  path: './src',
23
- include: ['**/*.py', '**/*.js', '**/*.ts', '**/*.go', '**/*.rs'],
24
- exclude: ['**/node_modules/**', '**/__pycache__/**', '**/dist/**', '**/target/**']
23
+ include: ['**/*.py', '**/*.js', '**/*.ts', '**/*.go', '**/*.rs', '**/*.java', '**/*.cs', '**/*.php', '**/*.kt', '**/*.kts', '**/*.swift', '**/*.rb'],
24
+ exclude: ['**/node_modules/**', '**/__pycache__/**', '**/dist/**', '**/target/**', '**/vendor/**', '**/build/**', '**/bin/**', '**/obj/**', '**/.build/**']
25
25
  },
26
26
  output: {
27
27
  path: './docs',
@@ -0,0 +1,23 @@
1
+ import type { ContextHubExportOptions, ContextHubExportResult, ContextHubContext } from './types.js';
2
+ import type { GeneratedDoc } from '../generator/types.js';
3
+ export type { ContextHubExportOptions, ContextHubExportResult, ContextHubContext };
4
+ /**
5
+ * Check if the `chub` CLI is installed
6
+ */
7
+ export declare function isChubInstalled(): boolean;
8
+ /**
9
+ * Extract Context Hub IDs from import lines by matching against known mappings
10
+ */
11
+ export declare function extractDependencyIds(imports: string[]): string[];
12
+ /**
13
+ * Fetch docs from Context Hub for the given IDs
14
+ */
15
+ export declare function fetchContextHubDocs(chubIds: string[], language?: string): Map<string, string>;
16
+ /**
17
+ * Given an element's imports, return relevant fetched docs as a single string
18
+ */
19
+ export declare function matchImportsToContext(imports: string[], contextMap: Map<string, string>): string | undefined;
20
+ /**
21
+ * Export generated docs to Context Hub format
22
+ */
23
+ export declare function exportToContextHub(docs: GeneratedDoc[], outputDir: string, options: ContextHubExportOptions): ContextHubExportResult;