wiggum-cli 0.2.6 → 0.3.1
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/README.md +73 -60
- package/dist/ai/agents/codebase-analyst.d.ts +11 -0
- package/dist/ai/agents/codebase-analyst.d.ts.map +1 -0
- package/dist/ai/agents/codebase-analyst.js +146 -0
- package/dist/ai/agents/codebase-analyst.js.map +1 -0
- package/dist/ai/agents/index.d.ts +16 -0
- package/dist/ai/agents/index.d.ts.map +1 -0
- package/dist/ai/agents/index.js +85 -0
- package/dist/ai/agents/index.js.map +1 -0
- package/dist/ai/agents/orchestrator.d.ts +15 -0
- package/dist/ai/agents/orchestrator.d.ts.map +1 -0
- package/dist/ai/agents/orchestrator.js +181 -0
- package/dist/ai/agents/orchestrator.js.map +1 -0
- package/dist/ai/agents/stack-researcher.d.ts +15 -0
- package/dist/ai/agents/stack-researcher.d.ts.map +1 -0
- package/dist/ai/agents/stack-researcher.js +269 -0
- package/dist/ai/agents/stack-researcher.js.map +1 -0
- package/dist/ai/agents/types.d.ts +123 -0
- package/dist/ai/agents/types.d.ts.map +1 -0
- package/dist/ai/agents/types.js +6 -0
- package/dist/ai/agents/types.js.map +1 -0
- package/dist/ai/enhancer.d.ts +39 -1
- package/dist/ai/enhancer.d.ts.map +1 -1
- package/dist/ai/enhancer.js +78 -36
- package/dist/ai/enhancer.js.map +1 -1
- package/dist/ai/index.d.ts +4 -2
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +5 -1
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/prompts.d.ts +2 -2
- package/dist/ai/prompts.d.ts.map +1 -1
- package/dist/ai/prompts.js +66 -4
- package/dist/ai/prompts.js.map +1 -1
- package/dist/ai/providers.d.ts +28 -0
- package/dist/ai/providers.d.ts.map +1 -1
- package/dist/ai/providers.js +40 -0
- package/dist/ai/providers.js.map +1 -1
- package/dist/ai/tools/context7.d.ts +34 -0
- package/dist/ai/tools/context7.d.ts.map +1 -0
- package/dist/ai/tools/context7.js +135 -0
- package/dist/ai/tools/context7.js.map +1 -0
- package/dist/ai/tools/index.d.ts +7 -0
- package/dist/ai/tools/index.d.ts.map +1 -0
- package/dist/ai/tools/index.js +7 -0
- package/dist/ai/tools/index.js.map +1 -0
- package/dist/ai/tools/tavily.d.ts +27 -0
- package/dist/ai/tools/tavily.d.ts.map +1 -0
- package/dist/ai/tools/tavily.js +75 -0
- package/dist/ai/tools/tavily.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -12
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.d.ts +2 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +233 -154
- package/dist/commands/init.js.map +1 -1
- package/dist/utils/colors.d.ts.map +1 -1
- package/dist/utils/colors.js +10 -3
- package/dist/utils/colors.js.map +1 -1
- package/dist/utils/header.d.ts +1 -1
- package/dist/utils/header.js +3 -3
- package/dist/utils/header.js.map +1 -1
- package/dist/utils/json-repair.d.ts +14 -0
- package/dist/utils/json-repair.d.ts.map +1 -0
- package/dist/utils/json-repair.js +103 -0
- package/dist/utils/json-repair.js.map +1 -0
- package/dist/utils/tracing.d.ts +25 -0
- package/dist/utils/tracing.d.ts.map +1 -0
- package/dist/utils/tracing.js +64 -0
- package/dist/utils/tracing.js.map +1 -0
- package/package.json +5 -3
- package/src/ai/agents/codebase-analyst.ts +169 -0
- package/src/ai/agents/index.ts +147 -0
- package/src/ai/agents/orchestrator.ts +218 -0
- package/src/ai/agents/stack-researcher.ts +294 -0
- package/src/ai/agents/types.ts +132 -0
- package/src/ai/enhancer.ts +128 -38
- package/src/ai/index.ts +31 -1
- package/src/ai/prompts.ts +67 -4
- package/src/ai/providers.ts +48 -0
- package/src/ai/tools/context7.ts +167 -0
- package/src/ai/tools/index.ts +17 -0
- package/src/ai/tools/tavily.ts +101 -0
- package/src/cli.ts +14 -12
- package/src/commands/init.ts +278 -173
- package/src/utils/colors.ts +11 -3
- package/src/utils/header.ts +3 -3
- package/src/utils/json-repair.ts +113 -0
- package/src/utils/tracing.ts +76 -0
package/src/utils/colors.ts
CHANGED
|
@@ -72,16 +72,24 @@ export function drawLine(width: number = 50): string {
|
|
|
72
72
|
return simpson.brown(box.horizontal.repeat(width));
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Strip ANSI escape codes from text to get visible length
|
|
77
|
+
*/
|
|
78
|
+
function stripAnsi(text: string): string {
|
|
79
|
+
// eslint-disable-next-line no-control-regex
|
|
80
|
+
return text.replace(/\x1b\[[0-9;]*m/g, '');
|
|
81
|
+
}
|
|
82
|
+
|
|
75
83
|
/**
|
|
76
84
|
* Draw a box around text
|
|
77
85
|
*/
|
|
78
86
|
export function drawBox(text: string, padding: number = 1): string {
|
|
79
87
|
const paddedText = ' '.repeat(padding) + text + ' '.repeat(padding);
|
|
80
|
-
const
|
|
88
|
+
const visibleWidth = stripAnsi(paddedText).length;
|
|
81
89
|
|
|
82
|
-
const top = simpson.brown(box.topLeft + box.horizontal.repeat(
|
|
90
|
+
const top = simpson.brown(box.topLeft + box.horizontal.repeat(visibleWidth) + box.topRight);
|
|
83
91
|
const middle = simpson.brown(box.vertical) + paddedText + simpson.brown(box.vertical);
|
|
84
|
-
const bottom = simpson.brown(box.bottomLeft + box.horizontal.repeat(
|
|
92
|
+
const bottom = simpson.brown(box.bottomLeft + box.horizontal.repeat(visibleWidth) + box.bottomRight);
|
|
85
93
|
|
|
86
94
|
return `${top}\n${middle}\n${bottom}`;
|
|
87
95
|
}
|
package/src/utils/header.ts
CHANGED
|
@@ -2,11 +2,11 @@ import cfonts from 'cfonts';
|
|
|
2
2
|
import { simpson, drawBox, SIMPSON_COLORS } from './colors.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Display the
|
|
5
|
+
* Display the WIGGUM CLI ASCII header with welcome box
|
|
6
6
|
*/
|
|
7
7
|
export function displayHeader(): void {
|
|
8
8
|
// Welcome box like Claude Code
|
|
9
|
-
const welcomeText =
|
|
9
|
+
const welcomeText = '🍩 Welcome to ' + simpson.yellow('Wiggum CLI') + ': AI-powered Ralph development loop CLI 🍩';
|
|
10
10
|
console.log('');
|
|
11
11
|
console.log(drawBox(welcomeText, 2));
|
|
12
12
|
console.log('');
|
|
@@ -27,6 +27,6 @@ export function displayHeader(): void {
|
|
|
27
27
|
*/
|
|
28
28
|
export function displayMinimalHeader(): void {
|
|
29
29
|
console.log('');
|
|
30
|
-
console.log(simpson.yellow('
|
|
30
|
+
console.log(simpson.yellow('Wiggum CLI') + simpson.brown(' │ ') + 'AI-powered Ralph development loop');
|
|
31
31
|
console.log('');
|
|
32
32
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Repair Utility
|
|
3
|
+
* Fixes common JSON syntax errors from AI responses
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Attempt to repair malformed JSON from AI responses
|
|
8
|
+
*/
|
|
9
|
+
export function repairJson(text: string): string {
|
|
10
|
+
let json = text;
|
|
11
|
+
|
|
12
|
+
// Remove any leading/trailing whitespace
|
|
13
|
+
json = json.trim();
|
|
14
|
+
|
|
15
|
+
// Remove trailing commas before ] or }
|
|
16
|
+
json = json.replace(/,(\s*[\]}])/g, '$1');
|
|
17
|
+
|
|
18
|
+
// Fix missing commas between array elements or object properties
|
|
19
|
+
// Pattern: value followed by newline and another value without comma
|
|
20
|
+
json = json.replace(/("|\d|true|false|null|\]|\})(\s*\n\s*)("|\[|\{)/g, '$1,$2$3');
|
|
21
|
+
|
|
22
|
+
// Fix single quotes to double quotes (but not inside strings)
|
|
23
|
+
// This is a simplified approach - may not work for all cases
|
|
24
|
+
json = json.replace(/'/g, '"');
|
|
25
|
+
|
|
26
|
+
// Remove JavaScript-style comments
|
|
27
|
+
json = json.replace(/\/\/.*$/gm, '');
|
|
28
|
+
json = json.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
29
|
+
|
|
30
|
+
// Fix unquoted keys (simple cases)
|
|
31
|
+
json = json.replace(/(\{|\,)\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":');
|
|
32
|
+
|
|
33
|
+
// Remove any text before the first { or [
|
|
34
|
+
const firstBrace = json.indexOf('{');
|
|
35
|
+
const firstBracket = json.indexOf('[');
|
|
36
|
+
let startIndex = -1;
|
|
37
|
+
|
|
38
|
+
if (firstBrace !== -1 && firstBracket !== -1) {
|
|
39
|
+
startIndex = Math.min(firstBrace, firstBracket);
|
|
40
|
+
} else if (firstBrace !== -1) {
|
|
41
|
+
startIndex = firstBrace;
|
|
42
|
+
} else if (firstBracket !== -1) {
|
|
43
|
+
startIndex = firstBracket;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (startIndex > 0) {
|
|
47
|
+
json = json.substring(startIndex);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Remove any text after the last } or ]
|
|
51
|
+
const lastBrace = json.lastIndexOf('}');
|
|
52
|
+
const lastBracket = json.lastIndexOf(']');
|
|
53
|
+
let endIndex = -1;
|
|
54
|
+
|
|
55
|
+
if (lastBrace !== -1 && lastBracket !== -1) {
|
|
56
|
+
endIndex = Math.max(lastBrace, lastBracket);
|
|
57
|
+
} else if (lastBrace !== -1) {
|
|
58
|
+
endIndex = lastBrace;
|
|
59
|
+
} else if (lastBracket !== -1) {
|
|
60
|
+
endIndex = lastBracket;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (endIndex !== -1 && endIndex < json.length - 1) {
|
|
64
|
+
json = json.substring(0, endIndex + 1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return json;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Parse JSON with repair attempts
|
|
72
|
+
* Tries to fix common issues before parsing
|
|
73
|
+
*/
|
|
74
|
+
export function parseJsonSafe<T>(text: string): T | null {
|
|
75
|
+
// First try parsing as-is
|
|
76
|
+
try {
|
|
77
|
+
return JSON.parse(text) as T;
|
|
78
|
+
} catch {
|
|
79
|
+
// Try with repairs
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Try repairing the JSON
|
|
83
|
+
try {
|
|
84
|
+
const repaired = repairJson(text);
|
|
85
|
+
return JSON.parse(repaired) as T;
|
|
86
|
+
} catch {
|
|
87
|
+
// Repair failed
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Last resort: try to extract JSON from markdown code blocks
|
|
91
|
+
const jsonMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
92
|
+
if (jsonMatch) {
|
|
93
|
+
try {
|
|
94
|
+
const repaired = repairJson(jsonMatch[1]);
|
|
95
|
+
return JSON.parse(repaired) as T;
|
|
96
|
+
} catch {
|
|
97
|
+
// Still failed
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Try finding a JSON object
|
|
102
|
+
const objectMatch = text.match(/\{[\s\S]*\}/);
|
|
103
|
+
if (objectMatch) {
|
|
104
|
+
try {
|
|
105
|
+
const repaired = repairJson(objectMatch[0]);
|
|
106
|
+
return JSON.parse(repaired) as T;
|
|
107
|
+
} catch {
|
|
108
|
+
// Still failed
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Braintrust Tracing Utility
|
|
3
|
+
* Provides AI call tracing for debugging and analysis
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { initLogger, wrapAISDK } from 'braintrust';
|
|
7
|
+
import * as ai from 'ai';
|
|
8
|
+
|
|
9
|
+
// Re-export traced utilities
|
|
10
|
+
export { traced, currentSpan, wrapTraced } from 'braintrust';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Initialize Braintrust logger if API key is available
|
|
14
|
+
*/
|
|
15
|
+
let loggerInitialized = false;
|
|
16
|
+
|
|
17
|
+
export function initTracing(): void {
|
|
18
|
+
if (loggerInitialized) return;
|
|
19
|
+
|
|
20
|
+
const apiKey = process.env.BRAINTRUST_API_KEY;
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
// Silently skip tracing if no API key
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
initLogger({
|
|
28
|
+
apiKey,
|
|
29
|
+
projectName: process.env.BRAINTRUST_PROJECT_NAME || 'wiggum-cli',
|
|
30
|
+
});
|
|
31
|
+
loggerInitialized = true;
|
|
32
|
+
} catch {
|
|
33
|
+
// Silently fail if tracing can't be initialized
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Check if tracing is enabled
|
|
39
|
+
*/
|
|
40
|
+
export function isTracingEnabled(): boolean {
|
|
41
|
+
return !!process.env.BRAINTRUST_API_KEY;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get wrapped AI SDK functions for automatic tracing
|
|
46
|
+
* Falls back to original functions if tracing not available
|
|
47
|
+
*/
|
|
48
|
+
export function getTracedAI() {
|
|
49
|
+
initTracing();
|
|
50
|
+
|
|
51
|
+
if (isTracingEnabled()) {
|
|
52
|
+
return wrapAISDK(ai);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Return original AI SDK functions if tracing not enabled
|
|
56
|
+
return ai;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Wrap a function with tracing
|
|
61
|
+
* No-op if tracing is not enabled
|
|
62
|
+
*/
|
|
63
|
+
export function maybeTraced<T extends (...args: unknown[]) => unknown>(
|
|
64
|
+
fn: T,
|
|
65
|
+
options: { type?: string; name?: string } = {}
|
|
66
|
+
): T {
|
|
67
|
+
if (!isTracingEnabled()) {
|
|
68
|
+
return fn;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const { wrapTraced } = require('braintrust');
|
|
72
|
+
return wrapTraced(fn, {
|
|
73
|
+
type: options.type || 'function',
|
|
74
|
+
name: options.name || fn.name || 'anonymous',
|
|
75
|
+
});
|
|
76
|
+
}
|