quackstack 1.0.15 → 1.0.17

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/cli.cjs CHANGED
@@ -46,8 +46,8 @@ program
46
46
  });
47
47
  });
48
48
  console.log(chalk_1.default.cyan("\nUsage:"));
49
- console.log(chalk_1.default.white(" quackstack --provider anthropic --model claude-sonnet-4-5-20250929"));
50
- console.log(chalk_1.default.white(" quackstack -p openai -m gpt-4o\n"));
49
+ console.log(chalk_1.default.white(" quack --provider anthropic --model claude-sonnet-4-20250514"));
50
+ console.log(chalk_1.default.white(" quack -p openai -m gpt-4o\n"));
51
51
  process.exit(0);
52
52
  }
53
53
  const title = chalk_animation_1.default.rainbow("QuackStack\n");
@@ -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
- "o3",
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-1",
93
- "claude-opus-4",
94
- "claude-sonnet-4-5",
95
- "claude-sonnet-4",
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-3",
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-2.5-flash"
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-25.01",
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-2.5-flash",
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,33 @@ 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
- const aiClient = getAIClient(provider, model);
12
- console.log(chalk.cyan(`\nUsing: ${aiClient.getProviderName()} - ${aiClient.getModel()}`));
13
- console.log(chalk.gray("Run 'quackstack --list-models' to see all options"));
14
- console.log(chalk.cyan("\nPress Ctrl+C to exit\n"));
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(`\nFailed 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(`\nDetected ${changes.totalChanges} file change${changes.totalChanges > 1 ? 's' : ''} since last index:`));
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 tempRl = readline.createInterface({
29
+ input: process.stdin,
30
+ output: process.stdout,
31
+ });
32
+ const shouldReindex = await new Promise((resolve) => {
33
+ tempRl.question(chalk.yellow("Reindex now? (y/n) > "), (answer) => {
34
+ tempRl.close();
35
+ resolve(answer);
36
+ });
37
+ });
22
38
  if (shouldReindex.toLowerCase() === 'y') {
23
39
  forceReindex = true;
24
40
  }
@@ -34,14 +50,14 @@ export async function startREPL(forceReindex = false, provider, model) {
34
50
  where: { projectName: PROJECT_NAME },
35
51
  });
36
52
  }
37
- console.log(chalk.gray("Indexing your codebase..."));
53
+ console.log(chalk.gray("šŸ” Indexing your codebase..."));
38
54
  await ingest(process.cwd(), PROJECT_NAME, true);
39
- console.log(chalk.green("Indexing complete"));
55
+ console.log(chalk.green("Indexing complete\n"));
40
56
  }
41
57
  const rl = readline.createInterface({
42
58
  input: process.stdin,
43
59
  output: process.stdout,
44
- prompt: chalk.yellow("quack > "),
60
+ prompt: chalk.yellow("🐄 quack > "),
45
61
  });
46
62
  rl.prompt();
47
63
  rl.on("line", async (line) => {
@@ -58,23 +74,25 @@ export async function startREPL(forceReindex = false, provider, model) {
58
74
  try {
59
75
  const { answer, sources } = await search(query, PROJECT_NAME, provider, model);
60
76
  console.log(chalk.white(`\n${answer}\n`));
61
- const showDetails = await promptUser(chalk.cyan("Want more details? (y/n) > "));
62
- if (showDetails.toLowerCase() === "y") {
63
- console.log(chalk.blue("\nRelevant Code:\n"));
64
- sources.forEach((src, i) => {
65
- console.log(chalk.gray(`[${i + 1}] ${src.filePath} (relevance: ${(src.score * 100).toFixed(1)}%)`));
66
- console.log(chalk.white(src.content));
67
- console.log(chalk.gray("\n---\n"));
68
- });
69
- }
77
+ rl.question(chalk.cyan("šŸ’” Want more details? (y/n) > "), (showDetails) => {
78
+ if (showDetails.toLowerCase() === "y") {
79
+ console.log(chalk.blue("\nšŸ“š Relevant Code:\n"));
80
+ sources.forEach((src, i) => {
81
+ console.log(chalk.gray(`[${i + 1}] ${src.filePath} (relevance: ${(src.score * 100).toFixed(1)}%)`));
82
+ console.log(chalk.white(src.content));
83
+ console.log(chalk.gray("\n---\n"));
84
+ });
85
+ }
86
+ rl.prompt();
87
+ });
70
88
  }
71
89
  catch (error) {
72
- console.error(chalk.red(`\nError: ${error.message}\n`));
90
+ console.error(chalk.red(`\nāŒ Error: ${error.message}\n`));
91
+ rl.prompt();
73
92
  }
74
- rl.prompt();
75
93
  });
76
94
  rl.on("close", () => {
77
- console.log(chalk.gray("\nBye"));
95
+ console.log(chalk.gray("\nšŸ‘‹ Happy coding!\n"));
78
96
  process.exit(0);
79
97
  });
80
98
  }
@@ -84,8 +102,13 @@ async function handleCommand(command, rl) {
84
102
  case "model":
85
103
  case "m":
86
104
  if (args.length === 0) {
87
- const client = getAIClient();
88
- console.log(chalk.cyan(`\nCurrent: ${client.getProviderName()} - ${client.getModel()}\n`));
105
+ try {
106
+ const client = getAIClient();
107
+ console.log(chalk.cyan(`\nCurrent: ${client.getProviderName()} - ${client.getModel()}\n`));
108
+ }
109
+ catch (error) {
110
+ console.log(chalk.red(`\nāŒ Error: ${error.message}\n`));
111
+ }
89
112
  }
90
113
  else {
91
114
  const [newModel] = args;
@@ -95,56 +118,49 @@ async function handleCommand(command, rl) {
95
118
  console.log(chalk.green(`\nSwitched to: ${client.getProviderName()} - ${client.getModel()}\n`));
96
119
  }
97
120
  catch (error) {
98
- console.log(chalk.red(`\nError: ${error.message}\n`));
121
+ console.log(chalk.red(`\nāŒ Error: ${error.message}\n`));
99
122
  }
100
123
  }
101
124
  break;
102
125
  case "provider":
103
126
  case "p":
104
127
  if (args.length === 0) {
105
- const client = getAIClient();
106
- const providers = client.getAvailableProviders();
107
- console.log(chalk.cyan("\nAvailable Providers:\n"));
108
- providers.forEach(p => {
109
- const current = p.provider === client.getProvider() ? chalk.green(" (current)") : "";
110
- console.log(chalk.white(` ${p.provider}: ${p.name}${current}`));
111
- });
112
- console.log();
128
+ try {
129
+ const client = getAIClient();
130
+ const providers = client.getAvailableProviders();
131
+ console.log(chalk.cyan("\nšŸ”Œ Available Providers:\n"));
132
+ providers.forEach(p => {
133
+ const current = p.provider === client.getProvider() ? chalk.green(" ← current") : "";
134
+ console.log(chalk.white(` • ${p.provider}: ${p.name}${current}`));
135
+ });
136
+ console.log();
137
+ }
138
+ catch (error) {
139
+ console.log(chalk.red(`\nāŒ Error: ${error.message}\n`));
140
+ }
113
141
  }
114
142
  else {
115
143
  const [newProvider] = args;
116
144
  try {
117
145
  resetAIClient();
118
146
  const client = getAIClient(newProvider);
119
- console.log(chalk.green(`\nSwitched to: ${client.getProviderName()} - ${client.getModel()}\n`));
147
+ console.log(chalk.green(`\nāœ… Switched to: ${client.getProviderName()} - ${client.getModel()}\n`));
120
148
  }
121
149
  catch (error) {
122
- console.log(chalk.red(`\nError: ${error.message}\n`));
150
+ console.log(chalk.red(`\nāŒ Error: ${error.message}\n`));
123
151
  }
124
152
  }
125
153
  break;
126
154
  case "help":
127
155
  case "h":
128
- console.log(chalk.cyan("\nAvailable Commands:\n"));
156
+ console.log(chalk.cyan("\nšŸ“– Available Commands:\n"));
129
157
  console.log(chalk.white(" /model, /m [model] Show or change model"));
130
158
  console.log(chalk.white(" /provider, /p [name] Show or change provider"));
131
159
  console.log(chalk.white(" /help, /h Show this help"));
132
160
  console.log();
133
161
  break;
134
162
  default:
135
- console.log(chalk.red(`\nUnknown command: ${cmd}\n`));
136
- console.log(chalk.gray("Type /help for available commands\n"));
163
+ console.log(chalk.red(`\nāŒ Unknown command: ${cmd}\n`));
164
+ console.log(chalk.gray("šŸ’” Type /help for available commands\n"));
137
165
  }
138
166
  }
139
- function promptUser(question) {
140
- const rl = readline.createInterface({
141
- input: process.stdin,
142
- output: process.stdout,
143
- });
144
- return new Promise((resolve) => {
145
- rl.question(question, (answer) => {
146
- rl.close();
147
- resolve(answer);
148
- });
149
- });
150
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quackstack",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "Your cracked unpaid intern for all things codebase related! AI-powered codebase search and Q&A.",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",