wiggum-cli 0.2.5 → 0.3.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 (79) hide show
  1. package/README.md +73 -60
  2. package/dist/ai/agents/codebase-analyst.d.ts +11 -0
  3. package/dist/ai/agents/codebase-analyst.d.ts.map +1 -0
  4. package/dist/ai/agents/codebase-analyst.js +150 -0
  5. package/dist/ai/agents/codebase-analyst.js.map +1 -0
  6. package/dist/ai/agents/index.d.ts +16 -0
  7. package/dist/ai/agents/index.d.ts.map +1 -0
  8. package/dist/ai/agents/index.js +85 -0
  9. package/dist/ai/agents/index.js.map +1 -0
  10. package/dist/ai/agents/orchestrator.d.ts +15 -0
  11. package/dist/ai/agents/orchestrator.d.ts.map +1 -0
  12. package/dist/ai/agents/orchestrator.js +187 -0
  13. package/dist/ai/agents/orchestrator.js.map +1 -0
  14. package/dist/ai/agents/stack-researcher.d.ts +15 -0
  15. package/dist/ai/agents/stack-researcher.d.ts.map +1 -0
  16. package/dist/ai/agents/stack-researcher.js +274 -0
  17. package/dist/ai/agents/stack-researcher.js.map +1 -0
  18. package/dist/ai/agents/types.d.ts +123 -0
  19. package/dist/ai/agents/types.d.ts.map +1 -0
  20. package/dist/ai/agents/types.js +6 -0
  21. package/dist/ai/agents/types.js.map +1 -0
  22. package/dist/ai/enhancer.d.ts +39 -1
  23. package/dist/ai/enhancer.d.ts.map +1 -1
  24. package/dist/ai/enhancer.js +105 -9
  25. package/dist/ai/enhancer.js.map +1 -1
  26. package/dist/ai/index.d.ts +4 -2
  27. package/dist/ai/index.d.ts.map +1 -1
  28. package/dist/ai/index.js +5 -1
  29. package/dist/ai/index.js.map +1 -1
  30. package/dist/ai/prompts.d.ts +2 -2
  31. package/dist/ai/prompts.d.ts.map +1 -1
  32. package/dist/ai/prompts.js +66 -4
  33. package/dist/ai/prompts.js.map +1 -1
  34. package/dist/ai/providers.d.ts +28 -0
  35. package/dist/ai/providers.d.ts.map +1 -1
  36. package/dist/ai/providers.js +40 -0
  37. package/dist/ai/providers.js.map +1 -1
  38. package/dist/ai/tools/context7.d.ts +34 -0
  39. package/dist/ai/tools/context7.d.ts.map +1 -0
  40. package/dist/ai/tools/context7.js +135 -0
  41. package/dist/ai/tools/context7.js.map +1 -0
  42. package/dist/ai/tools/index.d.ts +7 -0
  43. package/dist/ai/tools/index.d.ts.map +1 -0
  44. package/dist/ai/tools/index.js +7 -0
  45. package/dist/ai/tools/index.js.map +1 -0
  46. package/dist/ai/tools/tavily.d.ts +27 -0
  47. package/dist/ai/tools/tavily.d.ts.map +1 -0
  48. package/dist/ai/tools/tavily.js +75 -0
  49. package/dist/ai/tools/tavily.js.map +1 -0
  50. package/dist/cli.d.ts.map +1 -1
  51. package/dist/cli.js +14 -12
  52. package/dist/cli.js.map +1 -1
  53. package/dist/commands/init.d.ts +2 -5
  54. package/dist/commands/init.d.ts.map +1 -1
  55. package/dist/commands/init.js +233 -154
  56. package/dist/commands/init.js.map +1 -1
  57. package/dist/utils/colors.d.ts.map +1 -1
  58. package/dist/utils/colors.js +10 -3
  59. package/dist/utils/colors.js.map +1 -1
  60. package/dist/utils/header.d.ts +1 -1
  61. package/dist/utils/header.js +3 -3
  62. package/dist/utils/header.js.map +1 -1
  63. package/package.json +3 -3
  64. package/src/ai/agents/codebase-analyst.ts +172 -0
  65. package/src/ai/agents/index.ts +147 -0
  66. package/src/ai/agents/orchestrator.ts +222 -0
  67. package/src/ai/agents/stack-researcher.ts +298 -0
  68. package/src/ai/agents/types.ts +132 -0
  69. package/src/ai/enhancer.ts +159 -9
  70. package/src/ai/index.ts +31 -1
  71. package/src/ai/prompts.ts +67 -4
  72. package/src/ai/providers.ts +48 -0
  73. package/src/ai/tools/context7.ts +167 -0
  74. package/src/ai/tools/index.ts +17 -0
  75. package/src/ai/tools/tavily.ts +101 -0
  76. package/src/cli.ts +14 -12
  77. package/src/commands/init.ts +278 -173
  78. package/src/utils/colors.ts +11 -3
  79. package/src/utils/header.ts +3 -3
package/src/ai/index.ts CHANGED
@@ -7,10 +7,17 @@
7
7
  export {
8
8
  type AIProvider,
9
9
  type ProviderConfig,
10
+ type OptionalService,
10
11
  getModel,
11
12
  hasApiKey,
12
13
  getAvailableProvider,
13
14
  getApiKeyEnvVar,
15
+ OPTIONAL_SERVICE_ENV_VARS,
16
+ hasTavilyKey,
17
+ getTavilyKey,
18
+ hasContext7Key,
19
+ getContext7Key,
20
+ getOptionalServicesStatus,
14
21
  } from './providers.js';
15
22
 
16
23
  // Analysis prompts
@@ -29,11 +36,34 @@ export {
29
36
  RIPGREP_SKILL,
30
37
  } from './tools.js';
31
38
 
39
+ // New tools (Tavily, Context7)
40
+ export {
41
+ createTavilySearchTool,
42
+ canUseTavily,
43
+ createContext7Tool,
44
+ canUseContext7,
45
+ } from './tools/index.js';
46
+
47
+ // Agents
48
+ export {
49
+ runMultiAgentAnalysis,
50
+ runCodebaseAnalyst,
51
+ runStackResearcher,
52
+ runOrchestrator,
53
+ mergeAgentResults,
54
+ type CodebaseAnalysis,
55
+ type StackResearch,
56
+ type McpRecommendations,
57
+ type MultiAgentAnalysis,
58
+ type AgentCapabilities,
59
+ type AgentOptions,
60
+ } from './agents/index.js';
61
+
32
62
  // AI enhancer
33
63
  export {
34
64
  type ProjectContext,
35
65
  type DetectedCommands,
36
- type McpRecommendations,
66
+ type McpRecommendations as McpRecommendationsLegacy,
37
67
  type AIAnalysisResult,
38
68
  type EnhancedScanResult,
39
69
  type EnhancerOptions,
package/src/ai/prompts.ts CHANGED
@@ -100,6 +100,8 @@ Your goal is to thoroughly understand the codebase structure and produce actiona
100
100
  3. Search for key patterns: entry points, routes, components, tests
101
101
  4. Identify naming conventions by examining existing files
102
102
  5. Look for existing documentation (.md files, README)
103
+ 6. Determine the PROJECT TYPE (e.g., MCP server, REST API, React SPA, CLI tool, library)
104
+ 7. Based on project type, include TECHNOLOGY-SPECIFIC testing/debugging tools
103
105
 
104
106
  ## Tools Available
105
107
  You have these tools to explore the codebase:
@@ -110,6 +112,30 @@ You have these tools to explore the codebase:
110
112
 
111
113
  ${RIPGREP_SKILL}
112
114
 
115
+ ## Technology-Specific Guidance
116
+
117
+ When you detect specific project types, include their specialized tools:
118
+
119
+ **MCP Server Projects** (detected by @modelcontextprotocol dependencies):
120
+ - Testing: "npx @anthropic-ai/mcp-inspector" for interactive debugging
121
+ - Practices: Follow MCP protocol spec, validate tool schemas, handle resources properly
122
+
123
+ **REST APIs** (Express, Fastify, Hono, etc.):
124
+ - Testing: API testing tools (supertest, httpie, curl examples)
125
+ - Debugging: Request logging, OpenAPI validation
126
+
127
+ **React/Next.js Projects**:
128
+ - Testing: React Testing Library patterns, Storybook for components
129
+ - Debugging: React DevTools, component isolation
130
+
131
+ **CLI Tools**:
132
+ - Testing: Integration tests with actual CLI invocation
133
+ - Debugging: --verbose flags, debug logging patterns
134
+
135
+ **Libraries/Packages**:
136
+ - Testing: Unit tests with high coverage, type checking
137
+ - Practices: Semantic versioning, changelog maintenance
138
+
113
139
  ## Output Requirements
114
140
  After exploration, output valid JSON with:
115
141
  - projectContext: entry points, key directories, naming conventions
@@ -117,8 +143,11 @@ After exploration, output valid JSON with:
117
143
  - implementationGuidelines: short actionable rules (5-10 words each, max 7)
118
144
  - mcpServers: essential and recommended servers
119
145
  - possibleMissedTechnologies: technologies that might be in use
146
+ - technologyTools: testing, debugging, and validation tools specific to this project type
147
+ - technologyPractices: projectType, practices, antiPatterns, documentationHints
120
148
 
121
- Be concise. Focus on WHAT TO DO, not what exists.`;
149
+ Be concise. Focus on WHAT TO DO, not what exists.
150
+ Include SPECIFIC testing/debugging commands for the detected project type.`;
122
151
 
123
152
  /**
124
153
  * System prompt for codebase analysis (simple mode - no tools)
@@ -133,7 +162,16 @@ Rules:
133
162
  - Focus on WHAT TO DO, not what exists
134
163
  - Include specific file paths and commands
135
164
  - Max 5-7 items per array
136
- - No explanations, just actionable rules`;
165
+ - No explanations, just actionable rules
166
+ - CRITICAL: Include technology-specific testing and debugging tools
167
+ - Identify the PROJECT TYPE and provide stack-specific practices
168
+
169
+ Technology-specific tools to consider:
170
+ - MCP servers: "npx @anthropic-ai/mcp-inspector" for testing
171
+ - REST APIs: supertest, curl examples, OpenAPI validation
172
+ - React apps: React Testing Library, Storybook, DevTools
173
+ - CLI tools: integration tests, --verbose flags
174
+ - Libraries: high coverage unit tests, semantic versioning`;
137
175
 
138
176
  /**
139
177
  * Create the codebase analysis prompt
@@ -175,16 +213,41 @@ Respond with this JSON structure (keep values SHORT - 5-10 words max per item):
175
213
  "essential": ["filesystem", "git"],
176
214
  "recommended": ["docker", "postgres"]
177
215
  },
178
- "possibleMissedTechnologies": ["Redis", "WebSockets"]
216
+ "possibleMissedTechnologies": ["Redis", "WebSockets"],
217
+ "technologyTools": {
218
+ "testing": ["npx @anthropic-ai/mcp-inspector", "node test/test-*.js"],
219
+ "debugging": ["--verbose flag", "DEBUG=* env var"],
220
+ "validation": ["npx tsc --noEmit", "npm run lint"]
221
+ },
222
+ "technologyPractices": {
223
+ "projectType": "MCP Server",
224
+ "practices": [
225
+ "Validate tool input schemas with Zod",
226
+ "Return structured JSON from tools",
227
+ "Handle errors with proper MCP error codes"
228
+ ],
229
+ "antiPatterns": [
230
+ "Don't expose internal errors to clients",
231
+ "Avoid blocking operations in tool handlers"
232
+ ],
233
+ "documentationHints": [
234
+ "MCP spec: modelcontextprotocol.io/docs",
235
+ "Inspector: modelcontextprotocol.io/docs/tools/inspector"
236
+ ]
237
+ }
179
238
  }
180
239
 
181
- Important:
240
+ CRITICAL:
241
+ - Identify the PROJECT TYPE first (MCP Server, REST API, React SPA, CLI, Library, etc.)
242
+ - Include technology-specific testing tools (e.g., MCP Inspector for MCP projects)
243
+ - Include technology-specific debugging approaches
182
244
  - implementationGuidelines should be short rules (not analysis prompts)
183
245
  - Include actual file paths from this project
184
246
  - Infer commands from package.json patterns
185
247
  - Max 5-7 items per array`;
186
248
  }
187
249
 
250
+
188
251
  /**
189
252
  * Prompt for validating and improving scanner results
190
253
  */
@@ -30,6 +30,16 @@ const API_KEY_ENV_VARS: Record<AIProvider, string> = {
30
30
  openrouter: 'OPENROUTER_API_KEY',
31
31
  };
32
32
 
33
+ /**
34
+ * Environment variable names for optional services
35
+ */
36
+ export const OPTIONAL_SERVICE_ENV_VARS = {
37
+ tavily: 'TAVILY_API_KEY',
38
+ context7: 'CONTEXT7_API_KEY',
39
+ } as const;
40
+
41
+ export type OptionalService = keyof typeof OPTIONAL_SERVICE_ENV_VARS;
42
+
33
43
  /**
34
44
  * Model option with label and value
35
45
  */
@@ -184,3 +194,41 @@ const REASONING_MODELS = [
184
194
  export function isReasoningModel(modelId: string): boolean {
185
195
  return REASONING_MODELS.some(m => modelId.startsWith(m));
186
196
  }
197
+
198
+ /**
199
+ * Check if Tavily API key is available
200
+ */
201
+ export function hasTavilyKey(): boolean {
202
+ return !!process.env[OPTIONAL_SERVICE_ENV_VARS.tavily];
203
+ }
204
+
205
+ /**
206
+ * Get the Tavily API key
207
+ */
208
+ export function getTavilyKey(): string | undefined {
209
+ return process.env[OPTIONAL_SERVICE_ENV_VARS.tavily];
210
+ }
211
+
212
+ /**
213
+ * Check if Context7 API key is available
214
+ */
215
+ export function hasContext7Key(): boolean {
216
+ return !!process.env[OPTIONAL_SERVICE_ENV_VARS.context7];
217
+ }
218
+
219
+ /**
220
+ * Get the Context7 API key
221
+ */
222
+ export function getContext7Key(): string | undefined {
223
+ return process.env[OPTIONAL_SERVICE_ENV_VARS.context7];
224
+ }
225
+
226
+ /**
227
+ * Get the status of all optional services
228
+ */
229
+ export function getOptionalServicesStatus(): Record<OptionalService, boolean> {
230
+ return {
231
+ tavily: hasTavilyKey(),
232
+ context7: hasContext7Key(),
233
+ };
234
+ }
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Context7 Documentation Lookup Tool
3
+ * Enables documentation lookup for libraries and frameworks
4
+ */
5
+
6
+ import { tool, zodSchema } from 'ai';
7
+ import { z } from 'zod';
8
+
9
+ /**
10
+ * Context7 library info
11
+ */
12
+ export interface Context7Library {
13
+ id: string;
14
+ name: string;
15
+ description?: string;
16
+ codeSnippetCount?: number;
17
+ }
18
+
19
+ /**
20
+ * Context7 documentation result
21
+ */
22
+ export interface Context7DocResult {
23
+ title: string;
24
+ content: string;
25
+ codeExamples?: string[];
26
+ }
27
+
28
+ /**
29
+ * Create a Context7 documentation lookup tool
30
+ * @param apiKey - Context7 API key
31
+ */
32
+ export function createContext7Tool(apiKey: string) {
33
+ return tool({
34
+ description: `Look up documentation for libraries and frameworks.
35
+ Use this to find:
36
+ - API documentation for specific functions
37
+ - Usage examples and patterns
38
+ - Configuration options
39
+ - Best practices from official docs`,
40
+ inputSchema: zodSchema(z.object({
41
+ library: z.string().describe('Library name (e.g., "react", "express", "prisma")'),
42
+ query: z.string().describe('What you want to find in the documentation'),
43
+ })),
44
+ execute: async ({ library, query }) => {
45
+ try {
46
+ // First, resolve the library ID
47
+ const resolveResponse = await fetch('https://api.context7.com/v1/resolve-library-id', {
48
+ method: 'POST',
49
+ headers: {
50
+ 'Content-Type': 'application/json',
51
+ 'Authorization': `Bearer ${apiKey}`,
52
+ },
53
+ body: JSON.stringify({
54
+ libraryName: library,
55
+ query: query,
56
+ }),
57
+ });
58
+
59
+ if (!resolveResponse.ok) {
60
+ // Try alternative endpoint structure
61
+ return await fallbackDocLookup(apiKey, library, query);
62
+ }
63
+
64
+ const resolveData = await resolveResponse.json() as { libraryId?: string; libraries?: Context7Library[] };
65
+ const libraryId = resolveData.libraryId || resolveData.libraries?.[0]?.id;
66
+
67
+ if (!libraryId) {
68
+ return `No documentation found for "${library}". Try a different library name.`;
69
+ }
70
+
71
+ // Query the documentation
72
+ const queryResponse = await fetch('https://api.context7.com/v1/query-docs', {
73
+ method: 'POST',
74
+ headers: {
75
+ 'Content-Type': 'application/json',
76
+ 'Authorization': `Bearer ${apiKey}`,
77
+ },
78
+ body: JSON.stringify({
79
+ libraryId,
80
+ query,
81
+ }),
82
+ });
83
+
84
+ if (!queryResponse.ok) {
85
+ const errorText = await queryResponse.text();
86
+ return `Documentation lookup failed: ${queryResponse.status} - ${errorText}`;
87
+ }
88
+
89
+ const docsData = await queryResponse.json() as { results?: Context7DocResult[] };
90
+
91
+ // Format results
92
+ const results: string[] = [];
93
+ results.push(`Documentation for ${library}:`);
94
+ results.push('');
95
+
96
+ if (docsData.results && docsData.results.length > 0) {
97
+ for (const doc of docsData.results.slice(0, 3)) {
98
+ results.push(`## ${doc.title}`);
99
+ results.push(doc.content.substring(0, 500));
100
+ if (doc.codeExamples && doc.codeExamples.length > 0) {
101
+ results.push('');
102
+ results.push('Example:');
103
+ results.push('```');
104
+ results.push(doc.codeExamples[0].substring(0, 300));
105
+ results.push('```');
106
+ }
107
+ results.push('');
108
+ }
109
+ } else {
110
+ results.push(`No specific documentation found for query: "${query}"`);
111
+ }
112
+
113
+ return results.join('\n');
114
+ } catch (error) {
115
+ const errMsg = error instanceof Error ? error.message : String(error);
116
+ return `Documentation lookup error: ${errMsg}`;
117
+ }
118
+ },
119
+ });
120
+ }
121
+
122
+ /**
123
+ * Fallback documentation lookup using alternative approach
124
+ */
125
+ async function fallbackDocLookup(apiKey: string, library: string, query: string): Promise<string> {
126
+ try {
127
+ // Try a simpler query format
128
+ const response = await fetch(`https://api.context7.com/v1/search`, {
129
+ method: 'POST',
130
+ headers: {
131
+ 'Content-Type': 'application/json',
132
+ 'Authorization': `Bearer ${apiKey}`,
133
+ },
134
+ body: JSON.stringify({
135
+ query: `${library} ${query}`,
136
+ limit: 5,
137
+ }),
138
+ });
139
+
140
+ if (!response.ok) {
141
+ return `Unable to find documentation for "${library}". The Context7 API may not support this library or the request format has changed.`;
142
+ }
143
+
144
+ const data = await response.json() as { results?: Array<{ title: string; content: string }> };
145
+
146
+ if (data.results && data.results.length > 0) {
147
+ const results: string[] = [`Documentation for ${library}:`, ''];
148
+ for (const item of data.results.slice(0, 3)) {
149
+ results.push(`## ${item.title}`);
150
+ results.push(item.content.substring(0, 400));
151
+ results.push('');
152
+ }
153
+ return results.join('\n');
154
+ }
155
+
156
+ return `No documentation found for "${library}" with query "${query}"`;
157
+ } catch {
158
+ return `Documentation lookup for "${library}" failed. Please check your Context7 API key.`;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Check if Context7 can be used
164
+ */
165
+ export function canUseContext7(apiKey?: string): boolean {
166
+ return !!apiKey && apiKey.length > 0;
167
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * AI Tools Index
3
+ * Exports all tools for agent use
4
+ */
5
+
6
+ export {
7
+ createTavilySearchTool,
8
+ canUseTavily,
9
+ type TavilySearchResult,
10
+ } from './tavily.js';
11
+
12
+ export {
13
+ createContext7Tool,
14
+ canUseContext7,
15
+ type Context7Library,
16
+ type Context7DocResult,
17
+ } from './context7.js';
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Tavily Web Search Tool
3
+ * Enables web search for current best practices and documentation
4
+ */
5
+
6
+ import { tool, zodSchema } from 'ai';
7
+ import { z } from 'zod';
8
+
9
+ /**
10
+ * Tavily search result
11
+ */
12
+ export interface TavilySearchResult {
13
+ title: string;
14
+ url: string;
15
+ content: string;
16
+ score: number;
17
+ }
18
+
19
+ /**
20
+ * Tavily API response
21
+ */
22
+ interface TavilyApiResponse {
23
+ results: TavilySearchResult[];
24
+ query: string;
25
+ answer?: string;
26
+ }
27
+
28
+ /**
29
+ * Create a Tavily web search tool
30
+ * @param apiKey - Tavily API key
31
+ */
32
+ export function createTavilySearchTool(apiKey: string) {
33
+ return tool({
34
+ description: `Search the web for current best practices, documentation, and recent information.
35
+ Use this to find:
36
+ - Current best practices for technologies
37
+ - Testing patterns and tools
38
+ - Library documentation and examples
39
+ - Recent updates and changes`,
40
+ inputSchema: zodSchema(z.object({
41
+ query: z.string().describe('Search query - be specific about what you want to find'),
42
+ searchDepth: z.enum(['basic', 'advanced']).optional()
43
+ .describe('Search depth - use "advanced" for comprehensive results'),
44
+ maxResults: z.number().min(1).max(10).optional()
45
+ .describe('Maximum number of results (default 5)'),
46
+ })),
47
+ execute: async ({ query, searchDepth, maxResults }) => {
48
+ try {
49
+ const response = await fetch('https://api.tavily.com/search', {
50
+ method: 'POST',
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ },
54
+ body: JSON.stringify({
55
+ api_key: apiKey,
56
+ query,
57
+ search_depth: searchDepth || 'basic',
58
+ max_results: maxResults || 5,
59
+ include_answer: true,
60
+ include_raw_content: false,
61
+ }),
62
+ });
63
+
64
+ if (!response.ok) {
65
+ const errorText = await response.text();
66
+ return `Search failed: ${response.status} - ${errorText}`;
67
+ }
68
+
69
+ const data = await response.json() as TavilyApiResponse;
70
+
71
+ // Format results for the AI
72
+ const results: string[] = [];
73
+
74
+ if (data.answer) {
75
+ results.push(`Summary: ${data.answer}`);
76
+ results.push('');
77
+ }
78
+
79
+ results.push('Sources:');
80
+ for (const result of data.results) {
81
+ results.push(`- ${result.title}`);
82
+ results.push(` URL: ${result.url}`);
83
+ results.push(` ${result.content.substring(0, 300)}...`);
84
+ results.push('');
85
+ }
86
+
87
+ return results.join('\n');
88
+ } catch (error) {
89
+ const errMsg = error instanceof Error ? error.message : String(error);
90
+ return `Search error: ${errMsg}`;
91
+ }
92
+ },
93
+ });
94
+ }
95
+
96
+ /**
97
+ * Create a function that checks if Tavily search can be performed
98
+ */
99
+ export function canUseTavily(apiKey?: string): boolean {
100
+ return !!apiKey && apiKey.length > 0;
101
+ }
package/src/cli.ts CHANGED
@@ -27,8 +27,7 @@ export function createCli(): Command {
27
27
  'after',
28
28
  `
29
29
  Examples:
30
- $ ralph init Initialize Ralph in your project
31
- $ ralph init --ai Initialize with AI-enhanced analysis
30
+ $ ralph init Initialize Ralph with AI analysis
32
31
  $ ralph new my-feature Create a new feature specification
33
32
  $ ralph run my-feature Run the feature development loop
34
33
  $ ralph monitor my-feature Monitor progress in real-time
@@ -43,10 +42,9 @@ Documentation:
43
42
  .command('init')
44
43
  .description(
45
44
  'Initialize Ralph in the current project.\n\n' +
46
- 'Scans your codebase to detect the tech stack (framework, testing,\n' +
47
- 'database, auth, etc.) and generates configuration files in .ralph/'
45
+ 'Uses AI to analyze your codebase, detect the tech stack, and generate\n' +
46
+ 'intelligent configuration files in .ralph/'
48
47
  )
49
- .option('--ai', 'Enable AI-enhanced analysis for deeper project insights')
50
48
  .option(
51
49
  '--provider <name>',
52
50
  'AI provider to use (anthropic, openai, openrouter)',
@@ -57,15 +55,19 @@ Documentation:
57
55
  'after',
58
56
  `
59
57
  Examples:
60
- $ ralph init Basic initialization
61
- $ ralph init --ai With AI-enhanced analysis (Anthropic)
62
- $ ralph init --ai --provider openai With OpenAI provider
58
+ $ ralph init Initialize with AI analysis
59
+ $ ralph init --provider openai Use OpenAI provider
63
60
  $ ralph init --yes Non-interactive mode
64
61
 
65
- Environment Variables:
66
- ANTHROPIC_API_KEY Required for --ai with anthropic provider
67
- OPENAI_API_KEY Required for --ai with openai provider
68
- OPENROUTER_API_KEY Required for --ai with openrouter provider
62
+ API Keys (BYOK - Bring Your Own Keys):
63
+ Required (one of):
64
+ ANTHROPIC_API_KEY For Anthropic (Claude) provider
65
+ OPENAI_API_KEY For OpenAI provider
66
+ OPENROUTER_API_KEY For OpenRouter provider
67
+
68
+ Optional (for enhanced research):
69
+ TAVILY_API_KEY Enable web search for best practices
70
+ CONTEXT7_API_KEY Enable documentation lookup
69
71
  `
70
72
  )
71
73
  .action(async (options) => {