wiggum-cli 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/agents/context-enricher.d.ts.map +1 -1
- package/dist/ai/agents/context-enricher.js +37 -17
- package/dist/ai/agents/context-enricher.js.map +1 -1
- package/dist/ai/agents/evaluator-optimizer.d.ts.map +1 -1
- package/dist/ai/agents/evaluator-optimizer.js +74 -11
- package/dist/ai/agents/evaluator-optimizer.js.map +1 -1
- package/dist/ai/agents/mcp-detector.d.ts +6 -0
- package/dist/ai/agents/mcp-detector.d.ts.map +1 -1
- package/dist/ai/agents/mcp-detector.js +11 -4
- package/dist/ai/agents/mcp-detector.js.map +1 -1
- package/dist/ai/agents/stack-researcher.d.ts.map +1 -1
- package/dist/ai/agents/stack-researcher.js +29 -12
- package/dist/ai/agents/stack-researcher.js.map +1 -1
- package/dist/ai/agents/tech-researcher.d.ts.map +1 -1
- package/dist/ai/agents/tech-researcher.js +29 -11
- package/dist/ai/agents/tech-researcher.js.map +1 -1
- package/dist/ai/index.d.ts +1 -1
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +1 -1
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/tools/context7.d.ts +18 -24
- package/dist/ai/tools/context7.d.ts.map +1 -1
- package/dist/ai/tools/context7.js +14 -122
- package/dist/ai/tools/context7.js.map +1 -1
- package/dist/ai/tools/index.d.ts +1 -1
- package/dist/ai/tools/index.d.ts.map +1 -1
- package/dist/ai/tools/index.js +1 -1
- package/dist/ai/tools/index.js.map +1 -1
- package/dist/ai/tools/tavily.d.ts +1 -0
- package/dist/ai/tools/tavily.d.ts.map +1 -1
- package/dist/ai/tools/tavily.js +13 -8
- package/dist/ai/tools/tavily.js.map +1 -1
- package/package.json +2 -1
- package/src/ai/agents/context-enricher.ts +38 -18
- package/src/ai/agents/evaluator-optimizer.ts +78 -11
- package/src/ai/agents/mcp-detector.ts +11 -4
- package/src/ai/agents/stack-researcher.ts +30 -12
- package/src/ai/agents/tech-researcher.ts +30 -11
- package/src/ai/index.ts +1 -1
- package/src/ai/tools/context7.ts +17 -152
- package/src/ai/tools/index.ts +1 -3
- package/src/ai/tools/tavily.ts +13 -8
package/dist/ai/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export { formatStackForPrompt, SYSTEM_PROMPT, SYSTEM_PROMPT_AGENTIC, createAnaly
|
|
|
9
9
|
// Tools for agentic exploration
|
|
10
10
|
export { createExplorationTools, RIPGREP_SKILL, } from './tools.js';
|
|
11
11
|
// New tools (Tavily, Context7)
|
|
12
|
-
export { createTavilySearchTool, canUseTavily,
|
|
12
|
+
export { createTavilySearchTool, canUseTavily, createContext7Tools, canUseContext7, } from './tools/index.js';
|
|
13
13
|
// Agents - New 4-phase architecture
|
|
14
14
|
export {
|
|
15
15
|
// Main orchestration
|
package/dist/ai/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yBAAyB;AACzB,OAAO,EAIL,QAAQ,EACR,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,yBAAyB,EACzB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,mBAAmB;AACnB,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AAEtB,gCAAgC;AAChC,OAAO,EACL,sBAAsB,EACtB,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,+BAA+B;AAC/B,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,yBAAyB;AACzB,OAAO,EAIL,QAAQ,EACR,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,yBAAyB,EACzB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,mBAAmB;AACnB,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AAEtB,gCAAgC;AAChC,OAAO,EACL,sBAAsB,EACtB,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,+BAA+B;AAC/B,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,mBAAmB,EACnB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,oCAAoC;AACpC,OAAO;AACL,qBAAqB;AACrB,qBAAqB;AACrB,oBAAoB;AACpB,uBAAuB;AACvB,4BAA4B;AAC5B,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB;AACnB,qCAAqC;AACrC,iBAAiB,EACjB,qBAAqB,EACrB,iCAAiC;AACjC,mBAAmB;AACnB,qBAAqB;AAcrB,8DAA8D;AAC9D,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,cAAc;AACd,OAAO,EAOL,UAAU,EACV,aAAa,EACb,gBAAgB,GACjB,MAAM,eAAe,CAAC"}
|
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Context7 Documentation Lookup
|
|
3
|
-
*
|
|
2
|
+
* Context7 Documentation Lookup Tools
|
|
3
|
+
* Uses official @upstash/context7-tools-ai-sdk for proper two-step workflow
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
* Context7
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
codeSnippetCount?: number;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Context7 documentation result
|
|
16
|
-
*/
|
|
17
|
-
export interface Context7DocResult {
|
|
18
|
-
title: string;
|
|
19
|
-
content: string;
|
|
20
|
-
codeExamples?: string[];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Create a Context7 documentation lookup tool
|
|
6
|
+
* Create Context7 tools using official AI SDK integration
|
|
7
|
+
*
|
|
8
|
+
* The official tools implement the proper two-step workflow:
|
|
9
|
+
* 1. resolveLibraryId - finds the correct library ID
|
|
10
|
+
* 2. queryDocs - queries documentation with specific questions
|
|
11
|
+
*
|
|
24
12
|
* @param apiKey - Context7 API key
|
|
25
13
|
*/
|
|
26
|
-
export declare function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
14
|
+
export declare function createContext7Tools(apiKey: string): {
|
|
15
|
+
resolveLibraryId: import("ai").Tool<{
|
|
16
|
+
query: string;
|
|
17
|
+
libraryName: string;
|
|
18
|
+
}, string>;
|
|
19
|
+
queryDocs: import("ai").Tool<{
|
|
20
|
+
query: string;
|
|
21
|
+
libraryId: string;
|
|
22
|
+
}, string>;
|
|
23
|
+
};
|
|
30
24
|
/**
|
|
31
25
|
* Check if Context7 can be used
|
|
32
26
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context7.d.ts","sourceRoot":"","sources":["../../../src/ai/tools/context7.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"context7.d.ts","sourceRoot":"","sources":["../../../src/ai/tools/context7.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM;;;;;;;;;EAKjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -1,130 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Context7 Documentation Lookup
|
|
3
|
-
*
|
|
2
|
+
* Context7 Documentation Lookup Tools
|
|
3
|
+
* Uses official @upstash/context7-tools-ai-sdk for proper two-step workflow
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { z } from 'zod';
|
|
5
|
+
import { resolveLibraryId as createResolveLibraryIdTool, queryDocs as createQueryDocsTool, } from '@upstash/context7-tools-ai-sdk';
|
|
7
6
|
/**
|
|
8
|
-
* Create
|
|
7
|
+
* Create Context7 tools using official AI SDK integration
|
|
8
|
+
*
|
|
9
|
+
* The official tools implement the proper two-step workflow:
|
|
10
|
+
* 1. resolveLibraryId - finds the correct library ID
|
|
11
|
+
* 2. queryDocs - queries documentation with specific questions
|
|
12
|
+
*
|
|
9
13
|
* @param apiKey - Context7 API key
|
|
10
14
|
*/
|
|
11
|
-
export function
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- Usage examples and patterns
|
|
17
|
-
- Configuration options
|
|
18
|
-
- Best practices from official docs`,
|
|
19
|
-
inputSchema: zodSchema(z.object({
|
|
20
|
-
library: z.string().describe('Library name (e.g., "react", "express", "prisma")'),
|
|
21
|
-
query: z.string().describe('What you want to find in the documentation'),
|
|
22
|
-
})),
|
|
23
|
-
execute: async ({ library, query }) => {
|
|
24
|
-
try {
|
|
25
|
-
// First, resolve the library ID
|
|
26
|
-
const resolveResponse = await fetch('https://api.context7.com/v1/resolve-library-id', {
|
|
27
|
-
method: 'POST',
|
|
28
|
-
headers: {
|
|
29
|
-
'Content-Type': 'application/json',
|
|
30
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
31
|
-
},
|
|
32
|
-
body: JSON.stringify({
|
|
33
|
-
libraryName: library,
|
|
34
|
-
query: query,
|
|
35
|
-
}),
|
|
36
|
-
});
|
|
37
|
-
if (!resolveResponse.ok) {
|
|
38
|
-
// Try alternative endpoint structure
|
|
39
|
-
return await fallbackDocLookup(apiKey, library, query);
|
|
40
|
-
}
|
|
41
|
-
const resolveData = await resolveResponse.json();
|
|
42
|
-
const libraryId = resolveData.libraryId || resolveData.libraries?.[0]?.id;
|
|
43
|
-
if (!libraryId) {
|
|
44
|
-
return `No documentation found for "${library}". Try a different library name.`;
|
|
45
|
-
}
|
|
46
|
-
// Query the documentation
|
|
47
|
-
const queryResponse = await fetch('https://api.context7.com/v1/query-docs', {
|
|
48
|
-
method: 'POST',
|
|
49
|
-
headers: {
|
|
50
|
-
'Content-Type': 'application/json',
|
|
51
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
52
|
-
},
|
|
53
|
-
body: JSON.stringify({
|
|
54
|
-
libraryId,
|
|
55
|
-
query,
|
|
56
|
-
}),
|
|
57
|
-
});
|
|
58
|
-
if (!queryResponse.ok) {
|
|
59
|
-
const errorText = await queryResponse.text();
|
|
60
|
-
return `Documentation lookup failed: ${queryResponse.status} - ${errorText}`;
|
|
61
|
-
}
|
|
62
|
-
const docsData = await queryResponse.json();
|
|
63
|
-
// Format results
|
|
64
|
-
const results = [];
|
|
65
|
-
results.push(`Documentation for ${library}:`);
|
|
66
|
-
results.push('');
|
|
67
|
-
if (docsData.results && docsData.results.length > 0) {
|
|
68
|
-
for (const doc of docsData.results.slice(0, 3)) {
|
|
69
|
-
results.push(`## ${doc.title}`);
|
|
70
|
-
results.push(doc.content.substring(0, 500));
|
|
71
|
-
if (doc.codeExamples && doc.codeExamples.length > 0) {
|
|
72
|
-
results.push('');
|
|
73
|
-
results.push('Example:');
|
|
74
|
-
results.push('```');
|
|
75
|
-
results.push(doc.codeExamples[0].substring(0, 300));
|
|
76
|
-
results.push('```');
|
|
77
|
-
}
|
|
78
|
-
results.push('');
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
results.push(`No specific documentation found for query: "${query}"`);
|
|
83
|
-
}
|
|
84
|
-
return results.join('\n');
|
|
85
|
-
}
|
|
86
|
-
catch (error) {
|
|
87
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
88
|
-
return `Documentation lookup error: ${errMsg}`;
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Fallback documentation lookup using alternative approach
|
|
95
|
-
*/
|
|
96
|
-
async function fallbackDocLookup(apiKey, library, query) {
|
|
97
|
-
try {
|
|
98
|
-
// Try a simpler query format
|
|
99
|
-
const response = await fetch(`https://api.context7.com/v1/search`, {
|
|
100
|
-
method: 'POST',
|
|
101
|
-
headers: {
|
|
102
|
-
'Content-Type': 'application/json',
|
|
103
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
104
|
-
},
|
|
105
|
-
body: JSON.stringify({
|
|
106
|
-
query: `${library} ${query}`,
|
|
107
|
-
limit: 5,
|
|
108
|
-
}),
|
|
109
|
-
});
|
|
110
|
-
if (!response.ok) {
|
|
111
|
-
return `Unable to find documentation for "${library}". The Context7 API may not support this library or the request format has changed.`;
|
|
112
|
-
}
|
|
113
|
-
const data = await response.json();
|
|
114
|
-
if (data.results && data.results.length > 0) {
|
|
115
|
-
const results = [`Documentation for ${library}:`, ''];
|
|
116
|
-
for (const item of data.results.slice(0, 3)) {
|
|
117
|
-
results.push(`## ${item.title}`);
|
|
118
|
-
results.push(item.content.substring(0, 400));
|
|
119
|
-
results.push('');
|
|
120
|
-
}
|
|
121
|
-
return results.join('\n');
|
|
122
|
-
}
|
|
123
|
-
return `No documentation found for "${library}" with query "${query}"`;
|
|
124
|
-
}
|
|
125
|
-
catch {
|
|
126
|
-
return `Documentation lookup for "${library}" failed. Please check your Context7 API key.`;
|
|
127
|
-
}
|
|
15
|
+
export function createContext7Tools(apiKey) {
|
|
16
|
+
return {
|
|
17
|
+
resolveLibraryId: createResolveLibraryIdTool({ apiKey }),
|
|
18
|
+
queryDocs: createQueryDocsTool({ apiKey }),
|
|
19
|
+
};
|
|
128
20
|
}
|
|
129
21
|
/**
|
|
130
22
|
* Check if Context7 can be used
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context7.js","sourceRoot":"","sources":["../../../src/ai/tools/context7.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"context7.js","sourceRoot":"","sources":["../../../src/ai/tools/context7.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,gBAAgB,IAAI,0BAA0B,EAC9C,SAAS,IAAI,mBAAmB,GACjC,MAAM,gCAAgC,CAAC;AAExC;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,OAAO;QACL,gBAAgB,EAAE,0BAA0B,CAAC,EAAE,MAAM,EAAE,CAAC;QACxD,SAAS,EAAE,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,OAAO,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;AACvC,CAAC"}
|
package/dist/ai/tools/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* Exports all tools for agent use
|
|
4
4
|
*/
|
|
5
5
|
export { createTavilySearchTool, canUseTavily, type TavilySearchResult, } from './tavily.js';
|
|
6
|
-
export {
|
|
6
|
+
export { createContext7Tools, canUseContext7, } from './context7.js';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai/tools/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai/tools/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EACnB,cAAc,GACf,MAAM,eAAe,CAAC"}
|
package/dist/ai/tools/index.js
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* Exports all tools for agent use
|
|
4
4
|
*/
|
|
5
5
|
export { createTavilySearchTool, canUseTavily, } from './tavily.js';
|
|
6
|
-
export {
|
|
6
|
+
export { createContext7Tools, canUseContext7, } from './context7.js';
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ai/tools/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,sBAAsB,EACtB,YAAY,GAEb,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ai/tools/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,sBAAsB,EACtB,YAAY,GAEb,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EACnB,cAAc,GACf,MAAM,eAAe,CAAC"}
|
|
@@ -19,6 +19,7 @@ export declare function createTavilySearchTool(apiKey: string): import("ai").Too
|
|
|
19
19
|
query: string;
|
|
20
20
|
searchDepth?: "basic" | "advanced" | undefined;
|
|
21
21
|
maxResults?: number | undefined;
|
|
22
|
+
timeRange?: "day" | "week" | "month" | "year" | undefined;
|
|
22
23
|
}, string>;
|
|
23
24
|
/**
|
|
24
25
|
* Create a function that checks if Tavily search can be performed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tavily.d.ts","sourceRoot":"","sources":["../../../src/ai/tools/tavily.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAWD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"tavily.d.ts","sourceRoot":"","sources":["../../../src/ai/tools/tavily.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAWD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM;;;;;WAmEpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAErD"}
|
package/dist/ai/tools/tavily.js
CHANGED
|
@@ -10,20 +10,24 @@ import { z } from 'zod';
|
|
|
10
10
|
*/
|
|
11
11
|
export function createTavilySearchTool(apiKey) {
|
|
12
12
|
return tool({
|
|
13
|
-
description: `Search the web for current
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
13
|
+
description: `Search the web for current information.
|
|
14
|
+
|
|
15
|
+
USAGE TIPS:
|
|
16
|
+
- Keep queries concise and specific (not conversational)
|
|
17
|
+
- Use timeRange: "year" for recent best practices
|
|
18
|
+
- Break complex research into focused individual searches
|
|
19
|
+
- Good: "Express middleware error handling patterns"
|
|
20
|
+
- Bad: "best practices production 2024 testing documentation"`,
|
|
19
21
|
inputSchema: zodSchema(z.object({
|
|
20
|
-
query: z.string().describe('Search query - be specific
|
|
22
|
+
query: z.string().describe('Search query - be specific and concise'),
|
|
21
23
|
searchDepth: z.enum(['basic', 'advanced']).optional()
|
|
22
24
|
.describe('Search depth - use "advanced" for comprehensive results'),
|
|
23
25
|
maxResults: z.number().min(1).max(10).optional()
|
|
24
26
|
.describe('Maximum number of results (default 5)'),
|
|
27
|
+
timeRange: z.enum(['day', 'week', 'month', 'year']).optional()
|
|
28
|
+
.describe('Time filter for results. Use "year" for recent best practices'),
|
|
25
29
|
})),
|
|
26
|
-
execute: async ({ query, searchDepth, maxResults }) => {
|
|
30
|
+
execute: async ({ query, searchDepth, maxResults, timeRange }) => {
|
|
27
31
|
try {
|
|
28
32
|
const response = await fetch('https://api.tavily.com/search', {
|
|
29
33
|
method: 'POST',
|
|
@@ -35,6 +39,7 @@ Use this to find:
|
|
|
35
39
|
query,
|
|
36
40
|
search_depth: searchDepth || 'basic',
|
|
37
41
|
max_results: maxResults || 5,
|
|
42
|
+
...(timeRange && { time_range: timeRange }),
|
|
38
43
|
include_answer: true,
|
|
39
44
|
include_raw_content: false,
|
|
40
45
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tavily.js","sourceRoot":"","sources":["../../../src/ai/tools/tavily.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACrC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqBxB;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,OAAO,IAAI,CAAC;QACV,WAAW,EAAE
|
|
1
|
+
{"version":3,"file":"tavily.js","sourceRoot":"","sources":["../../../src/ai/tools/tavily.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wiggum-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "AI-powered feature development loop CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"@ai-sdk/openai": "^3.0.12",
|
|
33
33
|
"@braintrust/otel": "^0.2.0",
|
|
34
34
|
"@clack/prompts": "^0.7.0",
|
|
35
|
+
"@upstash/context7-tools-ai-sdk": "^0.2.1",
|
|
35
36
|
"ai": "^6.0.41",
|
|
36
37
|
"braintrust": "^2.0.2",
|
|
37
38
|
"cfonts": "^3.2.0",
|
|
@@ -15,7 +15,7 @@ import { detectProjectType } from './stack-utils.js';
|
|
|
15
15
|
/**
|
|
16
16
|
* System prompt for the Context Enricher worker
|
|
17
17
|
*/
|
|
18
|
-
const CONTEXT_ENRICHER_SYSTEM_PROMPT = `You are a Context Enricher worker. Your job is to explore specific areas of a codebase and
|
|
18
|
+
const CONTEXT_ENRICHER_SYSTEM_PROMPT = `You are a Context Enricher worker. Your job is to explore specific areas of a codebase and discover ACTUAL file paths and structures.
|
|
19
19
|
|
|
20
20
|
## Your Mission
|
|
21
21
|
Based on the analysis plan, explore the codebase to:
|
|
@@ -32,28 +32,48 @@ Based on the analysis plan, explore the codebase to:
|
|
|
32
32
|
- getPackageInfo: Get package.json info
|
|
33
33
|
|
|
34
34
|
## Exploration Strategy
|
|
35
|
-
1.
|
|
36
|
-
2.
|
|
37
|
-
3.
|
|
38
|
-
4.
|
|
39
|
-
|
|
40
|
-
## Project Types
|
|
41
|
-
- MCP Server: Has @modelcontextprotocol
|
|
42
|
-
- REST API: Express/Fastify/Hono
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
35
|
+
1. Read package.json FIRST for main/bin entries - these are authoritative entry points
|
|
36
|
+
2. List root directory to discover actual structure (src/, app/, pages/, lib/, cmd/, etc.)
|
|
37
|
+
3. Explore discovered directories to understand their purpose
|
|
38
|
+
4. Search for patterns to answer specific questions
|
|
39
|
+
|
|
40
|
+
## Project Types & Entry Point Patterns
|
|
41
|
+
- MCP Server: Has @modelcontextprotocol deps → main field or src/index.ts
|
|
42
|
+
- REST API: Express/Fastify/Hono → main field, app.ts, server.ts, or src/
|
|
43
|
+
- Next.js App: next in deps → app/page.tsx, pages/index.tsx, or pages/_app.tsx
|
|
44
|
+
- CLI Tool: Has bin entry in package.json → use the bin paths directly
|
|
45
|
+
- Library: main/module fields → use those paths
|
|
46
|
+
- Python: main.py, app.py, or __main__.py at root
|
|
47
|
+
- Go: main.go or cmd/*/main.go
|
|
48
|
+
|
|
49
|
+
## CRITICAL: Output Requirements
|
|
50
|
+
- entryPoints: ONLY actual file paths you discovered
|
|
51
|
+
- NEVER output instructions like "Check package.json..."
|
|
52
|
+
- NEVER output suggestions like "If exists, use..."
|
|
53
|
+
- Priority order for discovery:
|
|
54
|
+
1. package.json "bin" field paths (for CLI tools)
|
|
55
|
+
2. package.json "main" or "module" field paths
|
|
56
|
+
3. Framework conventions (app/page.tsx, pages/index.tsx)
|
|
57
|
+
4. Common patterns you find (index.ts, main.ts, app.ts)
|
|
58
|
+
- If truly nothing found, use empty array [] - don't guess
|
|
59
|
+
- keyDirectories: ONLY directories that actually exist with their discovered purpose
|
|
60
|
+
- First list root to find actual directories (don't assume src/ exists)
|
|
61
|
+
- Map each real directory to its purpose based on file contents
|
|
62
|
+
- Example: {"src/commands": "CLI commands", "app": "Next.js app router"}
|
|
47
63
|
|
|
48
64
|
## Output Format
|
|
49
|
-
|
|
65
|
+
Output ONLY valid JSON with discovered facts, not exploration instructions:
|
|
50
66
|
{
|
|
51
|
-
"entryPoints": ["
|
|
52
|
-
"keyDirectories": {
|
|
67
|
+
"entryPoints": ["bin/cli.js", "dist/index.js"],
|
|
68
|
+
"keyDirectories": {
|
|
69
|
+
"src": "TypeScript source code",
|
|
70
|
+
"bin": "CLI entry scripts",
|
|
71
|
+
"lib": "Compiled output"
|
|
72
|
+
},
|
|
53
73
|
"namingConventions": "camelCase files, PascalCase components",
|
|
54
74
|
"commands": {"test": "npm test", "build": "npm run build"},
|
|
55
75
|
"answeredQuestions": {"What is the auth strategy?": "NextAuth with JWT"},
|
|
56
|
-
"projectType": "
|
|
76
|
+
"projectType": "CLI Tool"
|
|
57
77
|
}`;
|
|
58
78
|
|
|
59
79
|
/**
|
|
@@ -87,7 +107,7 @@ Start by exploring the specified areas, then answer the questions and produce yo
|
|
|
87
107
|
system: CONTEXT_ENRICHER_SYSTEM_PROMPT,
|
|
88
108
|
prompt,
|
|
89
109
|
tools,
|
|
90
|
-
stopWhen: stepCountIs(
|
|
110
|
+
stopWhen: stepCountIs(8), // Increased from 5 to allow proper directory exploration
|
|
91
111
|
maxOutputTokens: 3000,
|
|
92
112
|
...(isReasoningModel(modelId) ? {} : { temperature: 0.3 }),
|
|
93
113
|
experimental_telemetry: {
|
|
@@ -39,6 +39,55 @@ const optimizerOutputSchema = z.object({
|
|
|
39
39
|
additionalMcpServers: z.array(z.string()).describe('Additional MCP servers to recommend (empty array if none)'),
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Patterns that indicate an entry point is an instruction, not a real path
|
|
44
|
+
*/
|
|
45
|
+
const INVALID_ENTRY_POINT_PATTERNS = [
|
|
46
|
+
/^check /i,
|
|
47
|
+
/^if /i,
|
|
48
|
+
/^open /i,
|
|
49
|
+
/^look /i,
|
|
50
|
+
/^search /i,
|
|
51
|
+
/^find /i,
|
|
52
|
+
/^inspect /i,
|
|
53
|
+
/^run /i,
|
|
54
|
+
/^see /i,
|
|
55
|
+
/^review /i,
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Check if a single entry point looks like an actual file path (not an instruction)
|
|
60
|
+
*/
|
|
61
|
+
function isValidEntryPoint(ep: string): boolean {
|
|
62
|
+
// Must look like a file path
|
|
63
|
+
const looksLikePath = ep.includes('/') || ep.includes('.') || ep.startsWith('src') || ep.startsWith('app') || ep.startsWith('pages');
|
|
64
|
+
// Must not start with instruction words
|
|
65
|
+
const isNotInstruction = !INVALID_ENTRY_POINT_PATTERNS.some(pattern => pattern.test(ep));
|
|
66
|
+
return looksLikePath && isNotInstruction;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Check if entry points look like actual file paths (not instructions)
|
|
71
|
+
*/
|
|
72
|
+
function hasValidEntryPoints(entryPoints: string[]): boolean {
|
|
73
|
+
if (entryPoints.length === 0) return false;
|
|
74
|
+
return entryPoints.every(isValidEntryPoint);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Filter entry points to only include valid file paths
|
|
79
|
+
*/
|
|
80
|
+
function filterValidEntryPoints(entryPoints: string[]): string[] {
|
|
81
|
+
return entryPoints.filter(isValidEntryPoint);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Normalize MCP names (strip parenthetical explanations)
|
|
86
|
+
*/
|
|
87
|
+
function normalizeMcpName(name: string): string {
|
|
88
|
+
return name.split('(')[0].trim().toLowerCase();
|
|
89
|
+
}
|
|
90
|
+
|
|
42
91
|
/**
|
|
43
92
|
* System prompt for the Evaluator
|
|
44
93
|
*/
|
|
@@ -58,10 +107,16 @@ Evaluate the analysis result for:
|
|
|
58
107
|
- 3-4: Incomplete, vague, or partially incorrect
|
|
59
108
|
- 1-2: Poor, missing critical information
|
|
60
109
|
|
|
61
|
-
## Quality Checks
|
|
62
|
-
- Entry points
|
|
63
|
-
-
|
|
64
|
-
-
|
|
110
|
+
## Quality Checks - IMPORTANT
|
|
111
|
+
- Entry points MUST be actual file paths (e.g., "src/index.ts", "src/cli.ts")
|
|
112
|
+
- FAIL if they contain instructions like "Check", "If", "Open", "Look"
|
|
113
|
+
- FAIL if they don't look like file paths (no / or . characters)
|
|
114
|
+
- Key directories MUST map actual directories to their purposes
|
|
115
|
+
- FAIL if only generic entries like {"src": "Source code"}
|
|
116
|
+
- Guidelines MUST be actionable commands, not exploration tasks
|
|
117
|
+
- Good: "Run npm test", "Check API routes in src/routes"
|
|
118
|
+
- Bad: "Investigate the codebase", "Look for patterns"
|
|
119
|
+
- MCP servers MUST be single-word identifiers only (no parenthetical explanations)
|
|
65
120
|
|
|
66
121
|
Be constructive but honest. If it's good, say so. If it needs work, explain why.`;
|
|
67
122
|
|
|
@@ -80,7 +135,13 @@ Based on the evaluation feedback, improve:
|
|
|
80
135
|
- Keep guidelines to 5-10 words
|
|
81
136
|
- Start with action verbs
|
|
82
137
|
- Be specific to the detected stack
|
|
83
|
-
- Don't remove good content, only add or improve
|
|
138
|
+
- Don't remove good content, only add or improve
|
|
139
|
+
|
|
140
|
+
## MCP Server Names
|
|
141
|
+
- Use ONLY single-word identifiers: "playwright", "supabase", "postgres"
|
|
142
|
+
- NEVER add explanations in parentheses
|
|
143
|
+
- NEVER add descriptions after the name
|
|
144
|
+
- If unsure, omit rather than guess`;
|
|
84
145
|
|
|
85
146
|
/**
|
|
86
147
|
* Run the Evaluator-Optimizer QA loop
|
|
@@ -107,10 +168,11 @@ export async function runEvaluatorOptimizer(
|
|
|
107
168
|
}
|
|
108
169
|
}
|
|
109
170
|
|
|
110
|
-
// Check if quality meets threshold
|
|
171
|
+
// Check if quality meets threshold (including valid entry point paths)
|
|
111
172
|
if (
|
|
112
173
|
evaluation.qualityScore >= QUALITY_THRESHOLD &&
|
|
113
174
|
evaluation.hasEntryPoints &&
|
|
175
|
+
hasValidEntryPoints(currentResult.codebaseAnalysis.projectContext.entryPoints) &&
|
|
114
176
|
evaluation.hasImplementationGuidelines
|
|
115
177
|
) {
|
|
116
178
|
if (verbose) {
|
|
@@ -248,16 +310,21 @@ Provide improved guidelines and any additional entry points or MCP servers.`;
|
|
|
248
310
|
: result.codebaseAnalysis.implementationGuidelines,
|
|
249
311
|
projectContext: {
|
|
250
312
|
...result.codebaseAnalysis.projectContext,
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
313
|
+
// Filter invalid entry points (instructions) and merge with new ones
|
|
314
|
+
entryPoints: filterValidEntryPoints([
|
|
315
|
+
...result.codebaseAnalysis.projectContext.entryPoints,
|
|
316
|
+
...improvements.additionalEntryPoints,
|
|
317
|
+
]).filter((ep, i, arr) => arr.indexOf(ep) === i), // dedupe
|
|
254
318
|
},
|
|
255
319
|
},
|
|
256
320
|
mcpServers: {
|
|
257
321
|
...result.mcpServers,
|
|
258
322
|
recommended: improvements.additionalMcpServers.length > 0
|
|
259
|
-
? [...new Set([
|
|
260
|
-
|
|
323
|
+
? [...new Set([
|
|
324
|
+
...result.mcpServers.recommended.map(normalizeMcpName),
|
|
325
|
+
...improvements.additionalMcpServers.map(normalizeMcpName)
|
|
326
|
+
])]
|
|
327
|
+
: result.mcpServers.recommended.map(normalizeMcpName),
|
|
261
328
|
},
|
|
262
329
|
};
|
|
263
330
|
|
|
@@ -177,26 +177,33 @@ export function detectRalphMcpServers(stack: DetectedStack): RalphMcpServers {
|
|
|
177
177
|
/**
|
|
178
178
|
* Convert RalphMcpServers to the legacy McpRecommendations format
|
|
179
179
|
* for backward compatibility with existing code
|
|
180
|
+
*
|
|
181
|
+
* Ralph loop essentials only:
|
|
182
|
+
* - Playwright for E2E testing (always)
|
|
183
|
+
* - Database MCP if detected (Supabase, Convex, Postgres, etc.)
|
|
184
|
+
*
|
|
185
|
+
* Note: filesystem and git are assumed available in Claude Code
|
|
180
186
|
*/
|
|
181
187
|
export function convertToLegacyMcpRecommendations(ralphMcp: RalphMcpServers): {
|
|
182
188
|
essential: string[];
|
|
183
189
|
recommended: string[];
|
|
184
190
|
} {
|
|
185
|
-
const essential: string[] = [
|
|
191
|
+
const essential: string[] = [];
|
|
186
192
|
|
|
187
|
-
//
|
|
193
|
+
// Ralph loop essentials only
|
|
194
|
+
// 1. Playwright for E2E testing (always)
|
|
188
195
|
if (ralphMcp.e2eTesting) {
|
|
189
196
|
essential.push(ralphMcp.e2eTesting);
|
|
190
197
|
}
|
|
191
198
|
|
|
192
|
-
//
|
|
199
|
+
// 2. Database MCP if detected (Supabase, Convex, Postgres, etc.)
|
|
193
200
|
if (ralphMcp.database) {
|
|
194
201
|
essential.push(ralphMcp.database);
|
|
195
202
|
}
|
|
196
203
|
|
|
197
204
|
return {
|
|
198
205
|
essential,
|
|
199
|
-
recommended:
|
|
206
|
+
recommended: [], // No optional MCPs - keep focused on Ralph loop
|
|
200
207
|
};
|
|
201
208
|
}
|
|
202
209
|
|