quackstack 1.0.14 ā 1.0.16
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/lib/ai-provider.js +24 -40
- package/dist/repl.js +48 -31
- package/package.json +1 -1
package/dist/lib/ai-provider.js
CHANGED
|
@@ -67,12 +67,12 @@ export class AIClient {
|
|
|
67
67
|
providers.push({
|
|
68
68
|
provider: "openai",
|
|
69
69
|
name: "OpenAI",
|
|
70
|
-
models: [
|
|
71
|
-
"gpt-
|
|
72
|
-
"gpt-
|
|
70
|
+
models: [
|
|
71
|
+
"gpt-4o",
|
|
72
|
+
"gpt-4o-mini",
|
|
73
73
|
"gpt-4-turbo",
|
|
74
|
-
"gpt-3.5-turbo"
|
|
75
|
-
|
|
74
|
+
"gpt-3.5-turbo"
|
|
75
|
+
],
|
|
76
76
|
defaultModel: "gpt-4o-mini"
|
|
77
77
|
});
|
|
78
78
|
}
|
|
@@ -80,44 +80,35 @@ export class AIClient {
|
|
|
80
80
|
providers.push({
|
|
81
81
|
provider: "anthropic",
|
|
82
82
|
name: "Anthropic",
|
|
83
|
-
models: [
|
|
84
|
-
"claude-
|
|
85
|
-
"claude-
|
|
86
|
-
"claude-3
|
|
83
|
+
models: [
|
|
84
|
+
"claude-opus-4-20250514",
|
|
85
|
+
"claude-sonnet-4-20250514",
|
|
86
|
+
"claude-3-7-sonnet-20250219",
|
|
87
|
+
"claude-3-5-haiku-20241022"
|
|
87
88
|
],
|
|
88
|
-
defaultModel: "claude-sonnet-4"
|
|
89
|
+
defaultModel: "claude-sonnet-4-20250514"
|
|
89
90
|
});
|
|
90
91
|
}
|
|
91
92
|
if (process.env.QUACKSTACK_GEMINI_KEY) {
|
|
92
93
|
providers.push({
|
|
93
94
|
provider: "gemini",
|
|
94
95
|
name: "Gemini",
|
|
95
|
-
models: [
|
|
96
|
-
"gemini-2.
|
|
97
|
-
"gemini-
|
|
98
|
-
"gemini-
|
|
99
|
-
"gemini-
|
|
100
|
-
"gemini-2.0-spark",
|
|
101
|
-
"gemini-2.0-flash-lite"
|
|
96
|
+
models: [
|
|
97
|
+
"gemini-2.0-flash-exp",
|
|
98
|
+
"gemini-1.5-pro",
|
|
99
|
+
"gemini-1.5-flash",
|
|
100
|
+
"gemini-1.5-flash-8b"
|
|
102
101
|
],
|
|
103
|
-
defaultModel: "gemini-
|
|
102
|
+
defaultModel: "gemini-1.5-flash"
|
|
104
103
|
});
|
|
105
104
|
}
|
|
106
105
|
if (process.env.QUACKSTACK_DEEPSEEK_KEY) {
|
|
107
106
|
providers.push({
|
|
108
107
|
provider: "deepseek",
|
|
109
108
|
name: "DeepSeek",
|
|
110
|
-
models: [
|
|
111
|
-
"deepseek-
|
|
112
|
-
"deepseek-
|
|
113
|
-
"deepseek-r1-32b",
|
|
114
|
-
"deepseek-r1-14b",
|
|
115
|
-
"deepseek-r1-8b",
|
|
116
|
-
"deepseek-r1-7b",
|
|
117
|
-
"deepseek-r1-1.5b",
|
|
118
|
-
"deepseek-vl2",
|
|
119
|
-
"deepseek-vl2-small",
|
|
120
|
-
"deepseek-vl2-tiny"
|
|
109
|
+
models: [
|
|
110
|
+
"deepseek-chat",
|
|
111
|
+
"deepseek-reasoner"
|
|
121
112
|
],
|
|
122
113
|
defaultModel: "deepseek-chat"
|
|
123
114
|
});
|
|
@@ -127,16 +118,9 @@ export class AIClient {
|
|
|
127
118
|
provider: "mistral",
|
|
128
119
|
name: "Mistral",
|
|
129
120
|
models: [
|
|
130
|
-
"mistral-large",
|
|
131
|
-
"mistral-
|
|
132
|
-
"
|
|
133
|
-
"mistral-7b",
|
|
134
|
-
"mixtral-8x7b",
|
|
135
|
-
"mixtral-8x22b",
|
|
136
|
-
"codestral",
|
|
137
|
-
"codestral-mamba",
|
|
138
|
-
"mathstral",
|
|
139
|
-
"mistral-nemo-12b"
|
|
121
|
+
"mistral-large-latest",
|
|
122
|
+
"mistral-small-latest",
|
|
123
|
+
"codestral-latest"
|
|
140
124
|
],
|
|
141
125
|
defaultModel: "mistral-large-latest"
|
|
142
126
|
});
|
|
@@ -146,7 +130,7 @@ export class AIClient {
|
|
|
146
130
|
getDefaultModel(provider) {
|
|
147
131
|
const defaults = {
|
|
148
132
|
openai: "gpt-4o-mini",
|
|
149
|
-
anthropic: "claude-
|
|
133
|
+
anthropic: "claude-sonnet-4-20250514",
|
|
150
134
|
gemini: "gemini-1.5-flash",
|
|
151
135
|
deepseek: "deepseek-chat",
|
|
152
136
|
mistral: "mistral-large-latest",
|
package/dist/repl.js
CHANGED
|
@@ -8,17 +8,24 @@ import { detectFileChanges, formatChangeMessage } from "./lib/file-change-detect
|
|
|
8
8
|
import { getAIClient, resetAIClient } from "./lib/ai-provider.js";
|
|
9
9
|
const PROJECT_NAME = path.basename(process.cwd());
|
|
10
10
|
export async function startREPL(forceReindex = false, provider, model) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
console.log(chalk.cyan("\nš„ Welcome to QuackStack!\n"));
|
|
12
|
+
try {
|
|
13
|
+
const aiClient = getAIClient(provider, model);
|
|
14
|
+
console.log(chalk.cyan(`š¤ Using: ${aiClient.getProviderName()} - ${aiClient.getModel()}`));
|
|
15
|
+
console.log(chalk.gray("š” Tip: Type '/help' for commands or 'quack --list-models' to see all options"));
|
|
16
|
+
console.log(chalk.cyan("ā” Press Ctrl+C to exit\n"));
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
console.error(chalk.red(`\nā Failed to initialize AI provider: ${error.message}\n`));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
15
22
|
if (!forceReindex) {
|
|
16
23
|
const changes = await detectFileChanges(process.cwd(), PROJECT_NAME);
|
|
17
24
|
if (changes && changes.totalChanges > 0) {
|
|
18
|
-
console.log(chalk.yellow(`\
|
|
25
|
+
console.log(chalk.yellow(`\nā ļø Detected ${changes.totalChanges} file change${changes.totalChanges > 1 ? 's' : ''} since last index:`));
|
|
19
26
|
console.log(chalk.yellow(` ${formatChangeMessage(changes)}`));
|
|
20
27
|
console.log(chalk.yellow(` Run 'quack --reindex' for best results.\n`));
|
|
21
|
-
const shouldReindex = await promptUser(chalk.yellow("Reindex now? (y/n) > "));
|
|
28
|
+
const shouldReindex = await promptUser(chalk.yellow("š Reindex now? (y/n) > "));
|
|
22
29
|
if (shouldReindex.toLowerCase() === 'y') {
|
|
23
30
|
forceReindex = true;
|
|
24
31
|
}
|
|
@@ -29,19 +36,19 @@ export async function startREPL(forceReindex = false, provider, model) {
|
|
|
29
36
|
});
|
|
30
37
|
if (existingCount === 0 || forceReindex) {
|
|
31
38
|
if (forceReindex) {
|
|
32
|
-
console.log(chalk.gray("Clearing old index..."));
|
|
39
|
+
console.log(chalk.gray("šļø Clearing old index..."));
|
|
33
40
|
await client.codeSnippet.deleteMany({
|
|
34
41
|
where: { projectName: PROJECT_NAME },
|
|
35
42
|
});
|
|
36
43
|
}
|
|
37
|
-
console.log(chalk.gray("Indexing your codebase..."));
|
|
44
|
+
console.log(chalk.gray("š Indexing your codebase..."));
|
|
38
45
|
await ingest(process.cwd(), PROJECT_NAME, true);
|
|
39
|
-
console.log(chalk.green("Indexing complete"));
|
|
46
|
+
console.log(chalk.green("ā
Indexing complete\n"));
|
|
40
47
|
}
|
|
41
48
|
const rl = readline.createInterface({
|
|
42
49
|
input: process.stdin,
|
|
43
50
|
output: process.stdout,
|
|
44
|
-
prompt: chalk.yellow("quack > "),
|
|
51
|
+
prompt: chalk.yellow("š„ quack > "),
|
|
45
52
|
});
|
|
46
53
|
rl.prompt();
|
|
47
54
|
rl.on("line", async (line) => {
|
|
@@ -58,9 +65,9 @@ export async function startREPL(forceReindex = false, provider, model) {
|
|
|
58
65
|
try {
|
|
59
66
|
const { answer, sources } = await search(query, PROJECT_NAME, provider, model);
|
|
60
67
|
console.log(chalk.white(`\n${answer}\n`));
|
|
61
|
-
const showDetails = await promptUser(chalk.cyan("Want more details? (y/n) > "));
|
|
68
|
+
const showDetails = await promptUser(chalk.cyan("š” Want more details? (y/n) > "));
|
|
62
69
|
if (showDetails.toLowerCase() === "y") {
|
|
63
|
-
console.log(chalk.blue("\
|
|
70
|
+
console.log(chalk.blue("\nš Relevant Code:\n"));
|
|
64
71
|
sources.forEach((src, i) => {
|
|
65
72
|
console.log(chalk.gray(`[${i + 1}] ${src.filePath} (relevance: ${(src.score * 100).toFixed(1)}%)`));
|
|
66
73
|
console.log(chalk.white(src.content));
|
|
@@ -69,12 +76,12 @@ export async function startREPL(forceReindex = false, provider, model) {
|
|
|
69
76
|
}
|
|
70
77
|
}
|
|
71
78
|
catch (error) {
|
|
72
|
-
console.error(chalk.red(`\
|
|
79
|
+
console.error(chalk.red(`\nā Error: ${error.message}\n`));
|
|
73
80
|
}
|
|
74
81
|
rl.prompt();
|
|
75
82
|
});
|
|
76
83
|
rl.on("close", () => {
|
|
77
|
-
console.log(chalk.gray("\
|
|
84
|
+
console.log(chalk.gray("\nš Happy coding!\n"));
|
|
78
85
|
process.exit(0);
|
|
79
86
|
});
|
|
80
87
|
}
|
|
@@ -84,56 +91,66 @@ async function handleCommand(command, rl) {
|
|
|
84
91
|
case "model":
|
|
85
92
|
case "m":
|
|
86
93
|
if (args.length === 0) {
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
try {
|
|
95
|
+
const client = getAIClient();
|
|
96
|
+
console.log(chalk.cyan(`\nš¤ Current: ${client.getProviderName()} - ${client.getModel()}\n`));
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.log(chalk.red(`\nā Error: ${error.message}\n`));
|
|
100
|
+
}
|
|
89
101
|
}
|
|
90
102
|
else {
|
|
91
103
|
const [newModel] = args;
|
|
92
104
|
try {
|
|
93
105
|
resetAIClient();
|
|
94
106
|
const client = getAIClient(undefined, newModel);
|
|
95
|
-
console.log(chalk.green(`\
|
|
107
|
+
console.log(chalk.green(`\nā
Switched to: ${client.getProviderName()} - ${client.getModel()}\n`));
|
|
96
108
|
}
|
|
97
109
|
catch (error) {
|
|
98
|
-
console.log(chalk.red(`\
|
|
110
|
+
console.log(chalk.red(`\nā Error: ${error.message}\n`));
|
|
99
111
|
}
|
|
100
112
|
}
|
|
101
113
|
break;
|
|
102
114
|
case "provider":
|
|
103
115
|
case "p":
|
|
104
116
|
if (args.length === 0) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
try {
|
|
118
|
+
const client = getAIClient();
|
|
119
|
+
const providers = client.getAvailableProviders();
|
|
120
|
+
console.log(chalk.cyan("\nš Available Providers:\n"));
|
|
121
|
+
providers.forEach(p => {
|
|
122
|
+
const current = p.provider === client.getProvider() ? chalk.green(" ā current") : "";
|
|
123
|
+
console.log(chalk.white(` ⢠${p.provider}: ${p.name}${current}`));
|
|
124
|
+
});
|
|
125
|
+
console.log();
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.log(chalk.red(`\nā Error: ${error.message}\n`));
|
|
129
|
+
}
|
|
113
130
|
}
|
|
114
131
|
else {
|
|
115
132
|
const [newProvider] = args;
|
|
116
133
|
try {
|
|
117
134
|
resetAIClient();
|
|
118
135
|
const client = getAIClient(newProvider);
|
|
119
|
-
console.log(chalk.green(`\
|
|
136
|
+
console.log(chalk.green(`\nā
Switched to: ${client.getProviderName()} - ${client.getModel()}\n`));
|
|
120
137
|
}
|
|
121
138
|
catch (error) {
|
|
122
|
-
console.log(chalk.red(`\
|
|
139
|
+
console.log(chalk.red(`\nā Error: ${error.message}\n`));
|
|
123
140
|
}
|
|
124
141
|
}
|
|
125
142
|
break;
|
|
126
143
|
case "help":
|
|
127
144
|
case "h":
|
|
128
|
-
console.log(chalk.cyan("\
|
|
145
|
+
console.log(chalk.cyan("\nš Available Commands:\n"));
|
|
129
146
|
console.log(chalk.white(" /model, /m [model] Show or change model"));
|
|
130
147
|
console.log(chalk.white(" /provider, /p [name] Show or change provider"));
|
|
131
148
|
console.log(chalk.white(" /help, /h Show this help"));
|
|
132
149
|
console.log();
|
|
133
150
|
break;
|
|
134
151
|
default:
|
|
135
|
-
console.log(chalk.red(`\
|
|
136
|
-
console.log(chalk.gray("Type /help for available commands\n"));
|
|
152
|
+
console.log(chalk.red(`\nā Unknown command: ${cmd}\n`));
|
|
153
|
+
console.log(chalk.gray("š” Type /help for available commands\n"));
|
|
137
154
|
}
|
|
138
155
|
}
|
|
139
156
|
function promptUser(question) {
|