skrypt-ai 0.1.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 (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +200 -0
  3. package/dist/autofix/index.d.ts +46 -0
  4. package/dist/autofix/index.js +240 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +40 -0
  7. package/dist/commands/autofix.d.ts +2 -0
  8. package/dist/commands/autofix.js +143 -0
  9. package/dist/commands/generate.d.ts +2 -0
  10. package/dist/commands/generate.js +320 -0
  11. package/dist/commands/init.d.ts +2 -0
  12. package/dist/commands/init.js +56 -0
  13. package/dist/commands/review-pr.d.ts +2 -0
  14. package/dist/commands/review-pr.js +117 -0
  15. package/dist/commands/watch.d.ts +2 -0
  16. package/dist/commands/watch.js +142 -0
  17. package/dist/config/index.d.ts +2 -0
  18. package/dist/config/index.js +2 -0
  19. package/dist/config/loader.d.ts +9 -0
  20. package/dist/config/loader.js +82 -0
  21. package/dist/config/types.d.ts +24 -0
  22. package/dist/config/types.js +34 -0
  23. package/dist/generator/generator.d.ts +15 -0
  24. package/dist/generator/generator.js +144 -0
  25. package/dist/generator/index.d.ts +4 -0
  26. package/dist/generator/index.js +4 -0
  27. package/dist/generator/organizer.d.ts +29 -0
  28. package/dist/generator/organizer.js +222 -0
  29. package/dist/generator/types.d.ts +83 -0
  30. package/dist/generator/types.js +1 -0
  31. package/dist/generator/writer.d.ts +28 -0
  32. package/dist/generator/writer.js +320 -0
  33. package/dist/github/pr-comments.d.ts +40 -0
  34. package/dist/github/pr-comments.js +308 -0
  35. package/dist/llm/anthropic-client.d.ts +16 -0
  36. package/dist/llm/anthropic-client.js +92 -0
  37. package/dist/llm/index.d.ts +53 -0
  38. package/dist/llm/index.js +400 -0
  39. package/dist/llm/llm.manual-test.d.ts +1 -0
  40. package/dist/llm/llm.manual-test.js +112 -0
  41. package/dist/llm/llm.mock-test.d.ts +4 -0
  42. package/dist/llm/llm.mock-test.js +79 -0
  43. package/dist/llm/openai-client.d.ts +17 -0
  44. package/dist/llm/openai-client.js +90 -0
  45. package/dist/llm/types.d.ts +60 -0
  46. package/dist/llm/types.js +20 -0
  47. package/dist/scanner/content-type.d.ts +39 -0
  48. package/dist/scanner/content-type.js +194 -0
  49. package/dist/scanner/content-type.test.d.ts +1 -0
  50. package/dist/scanner/content-type.test.js +231 -0
  51. package/dist/scanner/go.d.ts +20 -0
  52. package/dist/scanner/go.js +269 -0
  53. package/dist/scanner/index.d.ts +21 -0
  54. package/dist/scanner/index.js +137 -0
  55. package/dist/scanner/python.d.ts +6 -0
  56. package/dist/scanner/python.js +57 -0
  57. package/dist/scanner/python_parser.py +230 -0
  58. package/dist/scanner/rust.d.ts +23 -0
  59. package/dist/scanner/rust.js +304 -0
  60. package/dist/scanner/scanner.test.d.ts +1 -0
  61. package/dist/scanner/scanner.test.js +210 -0
  62. package/dist/scanner/types.d.ts +50 -0
  63. package/dist/scanner/types.js +1 -0
  64. package/dist/scanner/typescript.d.ts +34 -0
  65. package/dist/scanner/typescript.js +327 -0
  66. package/dist/scanner/typescript.manual-test.d.ts +1 -0
  67. package/dist/scanner/typescript.manual-test.js +112 -0
  68. package/dist/template/docs.json +32 -0
  69. package/dist/template/mdx-components.tsx +62 -0
  70. package/dist/template/next-env.d.ts +6 -0
  71. package/dist/template/next.config.mjs +17 -0
  72. package/dist/template/package.json +39 -0
  73. package/dist/template/postcss.config.mjs +5 -0
  74. package/dist/template/public/search-index.json +1 -0
  75. package/dist/template/scripts/build-search-index.mjs +120 -0
  76. package/dist/template/src/app/api/mock/[...path]/route.ts +224 -0
  77. package/dist/template/src/app/api/openapi/route.ts +48 -0
  78. package/dist/template/src/app/api/rate-limit/route.ts +84 -0
  79. package/dist/template/src/app/docs/[...slug]/page.tsx +81 -0
  80. package/dist/template/src/app/docs/layout.tsx +9 -0
  81. package/dist/template/src/app/docs/page.mdx +67 -0
  82. package/dist/template/src/app/error.tsx +63 -0
  83. package/dist/template/src/app/layout.tsx +71 -0
  84. package/dist/template/src/app/page.tsx +18 -0
  85. package/dist/template/src/app/reference/route.ts +36 -0
  86. package/dist/template/src/app/robots.ts +14 -0
  87. package/dist/template/src/app/sitemap.ts +64 -0
  88. package/dist/template/src/components/breadcrumbs.tsx +41 -0
  89. package/dist/template/src/components/copy-button.tsx +29 -0
  90. package/dist/template/src/components/docs-layout.tsx +35 -0
  91. package/dist/template/src/components/edit-link.tsx +39 -0
  92. package/dist/template/src/components/feedback.tsx +52 -0
  93. package/dist/template/src/components/header.tsx +66 -0
  94. package/dist/template/src/components/mdx/accordion.tsx +48 -0
  95. package/dist/template/src/components/mdx/api-badge.tsx +57 -0
  96. package/dist/template/src/components/mdx/callout.tsx +111 -0
  97. package/dist/template/src/components/mdx/card.tsx +62 -0
  98. package/dist/template/src/components/mdx/changelog.tsx +57 -0
  99. package/dist/template/src/components/mdx/code-block.tsx +42 -0
  100. package/dist/template/src/components/mdx/code-group.tsx +125 -0
  101. package/dist/template/src/components/mdx/code-playground.tsx +322 -0
  102. package/dist/template/src/components/mdx/go-playground.tsx +235 -0
  103. package/dist/template/src/components/mdx/heading.tsx +37 -0
  104. package/dist/template/src/components/mdx/highlighted-code.tsx +89 -0
  105. package/dist/template/src/components/mdx/index.tsx +15 -0
  106. package/dist/template/src/components/mdx/param-table.tsx +71 -0
  107. package/dist/template/src/components/mdx/python-playground.tsx +293 -0
  108. package/dist/template/src/components/mdx/steps.tsx +43 -0
  109. package/dist/template/src/components/mdx/tabs.tsx +81 -0
  110. package/dist/template/src/components/rate-limit-display.tsx +183 -0
  111. package/dist/template/src/components/search-dialog.tsx +178 -0
  112. package/dist/template/src/components/sidebar.tsx +129 -0
  113. package/dist/template/src/components/syntax-theme-selector.tsx +50 -0
  114. package/dist/template/src/components/table-of-contents.tsx +84 -0
  115. package/dist/template/src/components/theme-toggle.tsx +46 -0
  116. package/dist/template/src/components/version-selector.tsx +61 -0
  117. package/dist/template/src/contexts/syntax-theme.tsx +52 -0
  118. package/dist/template/src/lib/highlight.ts +83 -0
  119. package/dist/template/src/lib/search-types.ts +37 -0
  120. package/dist/template/src/lib/search.ts +125 -0
  121. package/dist/template/src/lib/utils.ts +6 -0
  122. package/dist/template/src/styles/globals.css +152 -0
  123. package/dist/template/tsconfig.json +25 -0
  124. package/dist/template/tsconfig.tsbuildinfo +1 -0
  125. package/package.json +72 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Mock tests for LLM client - tests structure without API calls
3
+ */
4
+ import { createLLMClient, PROVIDER_BASE_URLS } from './index.js';
5
+ function runMockTests() {
6
+ console.log('=== LLM Client Mock Tests ===\n');
7
+ // Test 1: Client creation for each provider
8
+ console.log('Test 1: Create client for each provider');
9
+ const providers = ['deepseek', 'openai', 'anthropic', 'google', 'ollama', 'openrouter'];
10
+ for (const provider of providers) {
11
+ try {
12
+ // Create client to verify no errors thrown
13
+ createLLMClient({
14
+ provider,
15
+ model: 'test-model'
16
+ });
17
+ console.log(` ✓ ${provider}: client created`);
18
+ }
19
+ catch (err) {
20
+ console.log(` ✗ ${provider}: ${err}`);
21
+ process.exit(1);
22
+ }
23
+ }
24
+ console.log('');
25
+ // Test 2: Verify base URLs
26
+ console.log('Test 2: Verify provider base URLs');
27
+ const expectedUrls = {
28
+ deepseek: 'https://api.deepseek.com/v1',
29
+ openai: 'https://api.openai.com/v1',
30
+ anthropic: 'https://api.anthropic.com',
31
+ google: 'https://generativelanguage.googleapis.com/v1beta/openai',
32
+ ollama: 'http://localhost:11434/v1',
33
+ openrouter: 'https://openrouter.ai/api/v1'
34
+ };
35
+ for (const [provider, expectedUrl] of Object.entries(expectedUrls)) {
36
+ const actualUrl = PROVIDER_BASE_URLS[provider];
37
+ if (actualUrl === expectedUrl) {
38
+ console.log(` ✓ ${provider}: ${actualUrl}`);
39
+ }
40
+ else {
41
+ console.log(` ✗ ${provider}: expected ${expectedUrl}, got ${actualUrl}`);
42
+ process.exit(1);
43
+ }
44
+ }
45
+ console.log('');
46
+ // Test 3: Anthropic vs OpenAI-compatible client selection
47
+ console.log('Test 3: Client type selection');
48
+ const anthropicClient = createLLMClient({ provider: 'anthropic', model: 'claude-3' });
49
+ const openaiClient = createLLMClient({ provider: 'openai', model: 'gpt-4' });
50
+ const deepseekClient = createLLMClient({ provider: 'deepseek', model: 'deepseek-v3' });
51
+ // Check they're different implementations for anthropic vs others
52
+ const anthropicType = anthropicClient.constructor.name;
53
+ const openaiType = openaiClient.constructor.name;
54
+ const deepseekType = deepseekClient.constructor.name;
55
+ console.log(` anthropic client: ${anthropicType}`);
56
+ console.log(` openai client: ${openaiType}`);
57
+ console.log(` deepseek client: ${deepseekType}`);
58
+ if (anthropicType !== openaiType) {
59
+ console.log(' ✓ anthropic uses different client than openai');
60
+ }
61
+ else {
62
+ console.log(' ✗ anthropic should use different client');
63
+ process.exit(1);
64
+ }
65
+ if (openaiType === deepseekType) {
66
+ console.log(' ✓ deepseek uses same client as openai (OpenAI-compatible)');
67
+ }
68
+ else {
69
+ console.log(' ✗ deepseek should use same client as openai');
70
+ process.exit(1);
71
+ }
72
+ console.log('');
73
+ console.log('✓ All mock tests passed\n');
74
+ console.log('To run real API tests, set an API key and run:');
75
+ console.log(' DEEPSEEK_API_KEY=your-key npx tsx src/llm/llm.test.ts');
76
+ console.log(' ANTHROPIC_API_KEY=your-key npx tsx src/llm/llm.test.ts');
77
+ console.log(' Or start Ollama locally');
78
+ }
79
+ runMockTests();
@@ -0,0 +1,17 @@
1
+ import { LLMClient, LLMClientConfig, CompletionRequest, CompletionResponse } from './types.js';
2
+ import { LLMProvider } from '../config/types.js';
3
+ /**
4
+ * OpenAI-compatible client
5
+ * Works with: OpenAI, DeepSeek, Ollama, OpenRouter, Google Gemini
6
+ */
7
+ export declare class OpenAICompatibleClient implements LLMClient {
8
+ provider: LLMProvider;
9
+ private client;
10
+ private model;
11
+ private maxRetries;
12
+ constructor(config: LLMClientConfig);
13
+ isConfigured(): boolean;
14
+ complete(request: CompletionRequest): Promise<CompletionResponse>;
15
+ private mapFinishReason;
16
+ private handleError;
17
+ }
@@ -0,0 +1,90 @@
1
+ import OpenAI from 'openai';
2
+ import { PROVIDER_BASE_URLS, PROVIDER_EXTRA_HEADERS } from './types.js';
3
+ /**
4
+ * OpenAI-compatible client
5
+ * Works with: OpenAI, DeepSeek, Ollama, OpenRouter, Google Gemini
6
+ */
7
+ export class OpenAICompatibleClient {
8
+ provider;
9
+ client;
10
+ model;
11
+ maxRetries;
12
+ constructor(config) {
13
+ this.provider = config.provider;
14
+ this.model = config.model;
15
+ this.maxRetries = config.maxRetries ?? 3;
16
+ const baseURL = config.baseUrl || PROVIDER_BASE_URLS[config.provider];
17
+ const extraHeaders = PROVIDER_EXTRA_HEADERS[config.provider] || {};
18
+ this.client = new OpenAI({
19
+ apiKey: config.apiKey || 'ollama', // Ollama doesn't need a real key
20
+ baseURL,
21
+ timeout: config.timeout ?? 60000,
22
+ maxRetries: this.maxRetries,
23
+ defaultHeaders: extraHeaders
24
+ });
25
+ }
26
+ isConfigured() {
27
+ return true; // OpenAI SDK handles validation
28
+ }
29
+ async complete(request) {
30
+ const model = request.model || this.model;
31
+ try {
32
+ const response = await this.client.chat.completions.create({
33
+ model,
34
+ messages: request.messages.map(m => ({
35
+ role: m.role,
36
+ content: m.content
37
+ })),
38
+ temperature: request.temperature ?? 0,
39
+ max_tokens: request.maxTokens ?? 4096
40
+ });
41
+ const choice = response.choices[0];
42
+ const content = choice?.message?.content || '';
43
+ return {
44
+ content,
45
+ model: response.model,
46
+ usage: {
47
+ inputTokens: response.usage?.prompt_tokens ?? 0,
48
+ outputTokens: response.usage?.completion_tokens ?? 0,
49
+ totalTokens: response.usage?.total_tokens ?? 0
50
+ },
51
+ finishReason: this.mapFinishReason(choice?.finish_reason)
52
+ };
53
+ }
54
+ catch (error) {
55
+ throw this.handleError(error);
56
+ }
57
+ }
58
+ mapFinishReason(reason) {
59
+ switch (reason) {
60
+ case 'stop':
61
+ case 'end_turn':
62
+ return 'stop';
63
+ case 'length':
64
+ case 'max_tokens':
65
+ return 'length';
66
+ default:
67
+ return 'error';
68
+ }
69
+ }
70
+ handleError(error) {
71
+ if (error instanceof OpenAI.APIError) {
72
+ const status = error.status;
73
+ const message = error.message;
74
+ if (status === 401) {
75
+ return new Error(`Authentication failed for ${this.provider}: Invalid API key`);
76
+ }
77
+ if (status === 429) {
78
+ return new Error(`Rate limited by ${this.provider}: ${message}`);
79
+ }
80
+ if (status === 500 || status === 502 || status === 503) {
81
+ return new Error(`${this.provider} service error: ${message}`);
82
+ }
83
+ return new Error(`${this.provider} API error (${status}): ${message}`);
84
+ }
85
+ if (error instanceof Error) {
86
+ return error;
87
+ }
88
+ return new Error(`Unknown error from ${this.provider}: ${String(error)}`);
89
+ }
90
+ }
@@ -0,0 +1,60 @@
1
+ import { LLMProvider } from '../config/types.js';
2
+ /**
3
+ * Message in a conversation
4
+ */
5
+ export interface Message {
6
+ role: 'system' | 'user' | 'assistant';
7
+ content: string;
8
+ }
9
+ /**
10
+ * Request to generate a completion
11
+ */
12
+ export interface CompletionRequest {
13
+ messages: Message[];
14
+ model?: string;
15
+ temperature?: number;
16
+ maxTokens?: number;
17
+ }
18
+ /**
19
+ * Response from a completion request
20
+ */
21
+ export interface CompletionResponse {
22
+ content: string;
23
+ model: string;
24
+ usage: {
25
+ inputTokens: number;
26
+ outputTokens: number;
27
+ totalTokens: number;
28
+ };
29
+ finishReason: 'stop' | 'length' | 'error';
30
+ }
31
+ /**
32
+ * LLM client configuration
33
+ */
34
+ export interface LLMClientConfig {
35
+ provider: LLMProvider;
36
+ model: string;
37
+ apiKey: string;
38
+ baseUrl?: string;
39
+ timeout?: number;
40
+ maxRetries?: number;
41
+ }
42
+ /**
43
+ * LLM client interface
44
+ */
45
+ export interface LLMClient {
46
+ /** The provider this client uses */
47
+ provider: LLMProvider;
48
+ /** Generate a completion */
49
+ complete(request: CompletionRequest): Promise<CompletionResponse>;
50
+ /** Check if the client is properly configured */
51
+ isConfigured(): boolean;
52
+ }
53
+ /**
54
+ * Provider base URLs
55
+ */
56
+ export declare const PROVIDER_BASE_URLS: Record<LLMProvider, string>;
57
+ /**
58
+ * Extra headers needed per provider
59
+ */
60
+ export declare const PROVIDER_EXTRA_HEADERS: Partial<Record<LLMProvider, Record<string, string>>>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Provider base URLs
3
+ */
4
+ export const PROVIDER_BASE_URLS = {
5
+ deepseek: 'https://api.deepseek.com/v1',
6
+ openai: 'https://api.openai.com/v1',
7
+ anthropic: 'https://api.anthropic.com',
8
+ google: 'https://generativelanguage.googleapis.com/v1beta/openai',
9
+ ollama: 'http://localhost:11434/v1',
10
+ openrouter: 'https://openrouter.ai/api/v1'
11
+ };
12
+ /**
13
+ * Extra headers needed per provider
14
+ */
15
+ export const PROVIDER_EXTRA_HEADERS = {
16
+ openrouter: {
17
+ 'HTTP-Referer': 'https://github.com/debgotwired/skrypt',
18
+ 'X-Title': 'skrypt'
19
+ }
20
+ };
@@ -0,0 +1,39 @@
1
+ import { APIElement } from './types.js';
2
+ /**
3
+ * Content type detection for documentation
4
+ * Determines if code should be documented as API reference, guide, or tutorial
5
+ */
6
+ export type ContentType = 'api' | 'guide' | 'tutorial' | 'overview';
7
+ export interface ContentClassification {
8
+ type: ContentType;
9
+ confidence: number;
10
+ reasons: string[];
11
+ }
12
+ /**
13
+ * Classify what type of documentation an API element needs
14
+ */
15
+ export declare function classifyElement(element: APIElement): ContentClassification;
16
+ /**
17
+ * Batch classify elements and group by content type
18
+ */
19
+ export declare function classifyElements(elements: APIElement[]): Map<ContentType, APIElement[]>;
20
+ /**
21
+ * Get recommended documentation structure for a set of elements
22
+ */
23
+ export declare function getRecommendedStructure(elements: APIElement[]): {
24
+ sections: {
25
+ name: string;
26
+ type: ContentType;
27
+ elements: APIElement[];
28
+ }[];
29
+ stats: {
30
+ api: number;
31
+ guide: number;
32
+ tutorial: number;
33
+ overview: number;
34
+ };
35
+ };
36
+ /**
37
+ * Generate documentation prompt based on content type
38
+ */
39
+ export declare function getPromptForContentType(type: ContentType): string;
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Classify what type of documentation an API element needs
3
+ */
4
+ export function classifyElement(element) {
5
+ const reasons = [];
6
+ let apiScore = 0;
7
+ let guideScore = 0;
8
+ let tutorialScore = 0;
9
+ // API Reference indicators
10
+ if (element.parameters.length >= 3) {
11
+ apiScore += 2;
12
+ reasons.push('Multiple parameters suggest API reference');
13
+ }
14
+ if (element.returnType && element.returnType.length > 10) {
15
+ apiScore += 1;
16
+ reasons.push('Complex return type');
17
+ }
18
+ if (element.kind === 'method' && element.parentClass) {
19
+ apiScore += 1;
20
+ reasons.push('Method on a class');
21
+ }
22
+ if (element.signature.includes('async') || element.signature.includes('Promise')) {
23
+ apiScore += 1;
24
+ reasons.push('Async pattern suggests API');
25
+ }
26
+ // Check for HTTP/REST patterns
27
+ const httpPatterns = /\b(GET|POST|PUT|DELETE|PATCH|http|request|response|fetch|axios)\b/i;
28
+ if (httpPatterns.test(element.signature) || httpPatterns.test(element.docstring || '')) {
29
+ apiScore += 3;
30
+ reasons.push('HTTP/REST patterns detected');
31
+ }
32
+ // Check for handler/endpoint patterns - no strict word boundaries for camelCase
33
+ const handlerPatterns = /(handler|endpoint|route|controller|middleware)/i;
34
+ if (handlerPatterns.test(element.name) || handlerPatterns.test(element.filePath)) {
35
+ apiScore += 2;
36
+ reasons.push('Handler/endpoint pattern');
37
+ }
38
+ // Guide indicators - use case-insensitive match without strict word boundaries
39
+ // to handle camelCase names like configureAuth, setupDatabase
40
+ const guidePatterns = /(config|setup|init|configure|options|settings)/i;
41
+ if (guidePatterns.test(element.name)) {
42
+ guideScore += 2;
43
+ reasons.push('Configuration/setup function');
44
+ }
45
+ if (element.docstring && element.docstring.length > 200) {
46
+ guideScore += 1;
47
+ reasons.push('Extensive documentation');
48
+ }
49
+ // Check for integration patterns - no strict word boundaries for camelCase
50
+ const integrationPatterns = /(connect|integrate|provider|client)/i;
51
+ if (integrationPatterns.test(element.name) || integrationPatterns.test(element.docstring || '')) {
52
+ guideScore += 1;
53
+ reasons.push('Integration pattern');
54
+ }
55
+ // Tutorial indicators
56
+ const tutorialPatterns = /\b(example|demo|sample|tutorial|quickstart|getting.?started)\b/i;
57
+ if (tutorialPatterns.test(element.filePath) || tutorialPatterns.test(element.docstring || '')) {
58
+ tutorialScore += 3;
59
+ reasons.push('Example/tutorial pattern in path or docs');
60
+ }
61
+ if (element.name.toLowerCase().includes('example') || element.name.toLowerCase().includes('demo')) {
62
+ tutorialScore += 2;
63
+ reasons.push('Name suggests example');
64
+ }
65
+ // Simple functions with few params = tutorial
66
+ if (element.parameters.length <= 1 && element.kind === 'function') {
67
+ tutorialScore += 1;
68
+ reasons.push('Simple function, good for tutorial');
69
+ }
70
+ // Determine winner
71
+ const maxScore = Math.max(apiScore, guideScore, tutorialScore);
72
+ const totalScore = apiScore + guideScore + tutorialScore;
73
+ if (maxScore === 0) {
74
+ return {
75
+ type: 'overview',
76
+ confidence: 0.5,
77
+ reasons: ['No strong indicators, defaulting to overview']
78
+ };
79
+ }
80
+ let type;
81
+ if (apiScore === maxScore) {
82
+ type = 'api';
83
+ }
84
+ else if (guideScore === maxScore) {
85
+ type = 'guide';
86
+ }
87
+ else {
88
+ type = 'tutorial';
89
+ }
90
+ const confidence = totalScore > 0 ? maxScore / totalScore : 0.5;
91
+ return { type, confidence, reasons };
92
+ }
93
+ /**
94
+ * Batch classify elements and group by content type
95
+ */
96
+ export function classifyElements(elements) {
97
+ const groups = new Map([
98
+ ['api', []],
99
+ ['guide', []],
100
+ ['tutorial', []],
101
+ ['overview', []]
102
+ ]);
103
+ for (const element of elements) {
104
+ const classification = classifyElement(element);
105
+ const group = groups.get(classification.type);
106
+ group.push(element);
107
+ }
108
+ return groups;
109
+ }
110
+ /**
111
+ * Get recommended documentation structure for a set of elements
112
+ */
113
+ export function getRecommendedStructure(elements) {
114
+ const classified = classifyElements(elements);
115
+ const sections = [];
116
+ const stats = { api: 0, guide: 0, tutorial: 0, overview: 0 };
117
+ // API Reference section
118
+ const apiElements = classified.get('api');
119
+ if (apiElements.length > 0) {
120
+ sections.push({
121
+ name: 'API Reference',
122
+ type: 'api',
123
+ elements: apiElements
124
+ });
125
+ stats.api = apiElements.length;
126
+ }
127
+ // Guides section
128
+ const guideElements = classified.get('guide');
129
+ if (guideElements.length > 0) {
130
+ sections.push({
131
+ name: 'Guides',
132
+ type: 'guide',
133
+ elements: guideElements
134
+ });
135
+ stats.guide = guideElements.length;
136
+ }
137
+ // Tutorials section
138
+ const tutorialElements = classified.get('tutorial');
139
+ if (tutorialElements.length > 0) {
140
+ sections.push({
141
+ name: 'Tutorials',
142
+ type: 'tutorial',
143
+ elements: tutorialElements
144
+ });
145
+ stats.tutorial = tutorialElements.length;
146
+ }
147
+ // Overview/Other
148
+ const overviewElements = classified.get('overview');
149
+ if (overviewElements.length > 0) {
150
+ sections.push({
151
+ name: 'Overview',
152
+ type: 'overview',
153
+ elements: overviewElements
154
+ });
155
+ stats.overview = overviewElements.length;
156
+ }
157
+ return { sections, stats };
158
+ }
159
+ /**
160
+ * Generate documentation prompt based on content type
161
+ */
162
+ export function getPromptForContentType(type) {
163
+ switch (type) {
164
+ case 'api':
165
+ return `Generate detailed API reference documentation. Include:
166
+ - Clear parameter descriptions with types
167
+ - Return value documentation
168
+ - Error cases and edge conditions
169
+ - Code example showing typical usage
170
+ Focus on technical accuracy and completeness.`;
171
+ case 'guide':
172
+ return `Generate a practical guide for this functionality. Include:
173
+ - What problem it solves
174
+ - Step-by-step setup instructions
175
+ - Configuration options explained
176
+ - Best practices and common patterns
177
+ Focus on helping developers integrate this into their projects.`;
178
+ case 'tutorial':
179
+ return `Generate a beginner-friendly tutorial. Include:
180
+ - What you'll learn
181
+ - Prerequisites
182
+ - Step-by-step walkthrough with explanations
183
+ - Complete working example
184
+ - Next steps for learning more
185
+ Focus on teaching concepts through hands-on examples.`;
186
+ case 'overview':
187
+ return `Generate an overview of this functionality. Include:
188
+ - What it does at a high level
189
+ - When to use it
190
+ - Basic example
191
+ - Links to related documentation
192
+ Keep it concise but informative.`;
193
+ }
194
+ }
@@ -0,0 +1 @@
1
+ export {};