quackstack 1.0.15 ā 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 +13 -34
- package/dist/repl.js +48 -31
- package/package.json +1 -1
package/dist/lib/ai-provider.js
CHANGED
|
@@ -68,18 +68,10 @@ export class AIClient {
|
|
|
68
68
|
provider: "openai",
|
|
69
69
|
name: "OpenAI",
|
|
70
70
|
models: [
|
|
71
|
-
"gpt-5",
|
|
72
|
-
"gpt-5-mini",
|
|
73
|
-
"gpt-5-nano",
|
|
74
|
-
"gpt-4.1",
|
|
75
|
-
"gpt-4.1-mini",
|
|
76
|
-
"gpt-4.1-nano",
|
|
77
71
|
"gpt-4o",
|
|
78
72
|
"gpt-4o-mini",
|
|
79
73
|
"gpt-4-turbo",
|
|
80
|
-
"
|
|
81
|
-
"o4-mini",
|
|
82
|
-
"o4-mini-high"
|
|
74
|
+
"gpt-3.5-turbo"
|
|
83
75
|
],
|
|
84
76
|
defaultModel: "gpt-4o-mini"
|
|
85
77
|
});
|
|
@@ -89,15 +81,12 @@ export class AIClient {
|
|
|
89
81
|
provider: "anthropic",
|
|
90
82
|
name: "Anthropic",
|
|
91
83
|
models: [
|
|
92
|
-
"claude-opus-4-
|
|
93
|
-
"claude-
|
|
94
|
-
"claude-sonnet-
|
|
95
|
-
"claude-
|
|
96
|
-
"claude-haiku-4-5",
|
|
97
|
-
"claude-3-7-sonnet",
|
|
98
|
-
"claude-3-5-haiku"
|
|
84
|
+
"claude-opus-4-20250514",
|
|
85
|
+
"claude-sonnet-4-20250514",
|
|
86
|
+
"claude-3-7-sonnet-20250219",
|
|
87
|
+
"claude-3-5-haiku-20241022"
|
|
99
88
|
],
|
|
100
|
-
defaultModel: "claude-sonnet-4"
|
|
89
|
+
defaultModel: "claude-sonnet-4-20250514"
|
|
101
90
|
});
|
|
102
91
|
}
|
|
103
92
|
if (process.env.QUACKSTACK_GEMINI_KEY) {
|
|
@@ -105,16 +94,12 @@ export class AIClient {
|
|
|
105
94
|
provider: "gemini",
|
|
106
95
|
name: "Gemini",
|
|
107
96
|
models: [
|
|
108
|
-
"gemini-
|
|
109
|
-
"gemini-3-pro",
|
|
110
|
-
"gemini-2.5-pro",
|
|
111
|
-
"gemini-2.5-flash",
|
|
112
|
-
"gemini-2.5-flash-lite",
|
|
113
|
-
"gemini-2.0-flash",
|
|
97
|
+
"gemini-2.0-flash-exp",
|
|
114
98
|
"gemini-1.5-pro",
|
|
115
|
-
"gemini-1.5-flash"
|
|
99
|
+
"gemini-1.5-flash",
|
|
100
|
+
"gemini-1.5-flash-8b"
|
|
116
101
|
],
|
|
117
|
-
defaultModel: "gemini-
|
|
102
|
+
defaultModel: "gemini-1.5-flash"
|
|
118
103
|
});
|
|
119
104
|
}
|
|
120
105
|
if (process.env.QUACKSTACK_DEEPSEEK_KEY) {
|
|
@@ -134,14 +119,8 @@ export class AIClient {
|
|
|
134
119
|
name: "Mistral",
|
|
135
120
|
models: [
|
|
136
121
|
"mistral-large-latest",
|
|
137
|
-
"mistral-large-24.11",
|
|
138
|
-
"mistral-medium-3",
|
|
139
122
|
"mistral-small-latest",
|
|
140
|
-
"codestral-
|
|
141
|
-
"codestral-latest",
|
|
142
|
-
"magistral-small-2506",
|
|
143
|
-
"magistral-medium-2506",
|
|
144
|
-
"pixtral-12b"
|
|
123
|
+
"codestral-latest"
|
|
145
124
|
],
|
|
146
125
|
defaultModel: "mistral-large-latest"
|
|
147
126
|
});
|
|
@@ -151,8 +130,8 @@ export class AIClient {
|
|
|
151
130
|
getDefaultModel(provider) {
|
|
152
131
|
const defaults = {
|
|
153
132
|
openai: "gpt-4o-mini",
|
|
154
|
-
anthropic: "claude-sonnet-4",
|
|
155
|
-
gemini: "gemini-
|
|
133
|
+
anthropic: "claude-sonnet-4-20250514",
|
|
134
|
+
gemini: "gemini-1.5-flash",
|
|
156
135
|
deepseek: "deepseek-chat",
|
|
157
136
|
mistral: "mistral-large-latest",
|
|
158
137
|
};
|
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) {
|