@austinthesing/magic-shell 0.2.2 → 0.2.4

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 CHANGED
@@ -174,16 +174,16 @@ You can also type commands directly in the TUI:
174
174
  OpenCode Zen provides curated models optimized for coding tasks, including **free models**.
175
175
 
176
176
  **Free Models:**
177
+ - `big-pickle` - Stealth model (default)
177
178
  - `grok-code` - xAI's Grok Code Fast 1
178
179
  - `glm-4.7-free` - GLM 4.7
179
180
  - `minimax-m2.1-free` - MiniMax M2.1
180
- - `big-pickle` - Stealth model
181
181
 
182
182
  **Premium Models:**
183
183
  - Claude Sonnet 4.5, Claude Opus 4.5
184
- - Gemini 3 Flash, Gemini 3 Pro
185
184
  - Kimi K2, Kimi K2 Thinking
186
185
  - Qwen3 Coder 480B
186
+ - GLM 4.6
187
187
  - And more...
188
188
 
189
189
  Get your API key at: https://opencode.ai/auth
@@ -195,13 +195,11 @@ Access to a wide variety of models from different providers.
195
195
  **Free Models:**
196
196
  - MiMo V2 Flash
197
197
  - DeepSeek V3
198
- - Gemini 2.5 Flash
199
198
 
200
199
  **Premium Models:**
201
200
  - Claude Sonnet 4.5, Claude Opus 4.5
202
- - GPT 5.2 Codex
203
- - Gemini 2.5 Pro
204
201
  - DeepSeek R1
202
+ - GLM 4.7
205
203
  - And many more...
206
204
 
207
205
  Get your API key at: https://openrouter.ai/keys
@@ -244,7 +242,7 @@ Configuration is stored in `~/.magic-shell/config.json`.
244
242
  ```json
245
243
  {
246
244
  "provider": "opencode-zen",
247
- "defaultModel": "gemini-3-flash",
245
+ "defaultModel": "big-pickle",
248
246
  "safetyLevel": "moderate",
249
247
  "dryRunByDefault": false,
250
248
  "repoContext": false,
package/dist/cli.js CHANGED
@@ -20500,23 +20500,6 @@ var OPENROUTER_MODELS = [
20500
20500
  contextLength: 128000,
20501
20501
  free: true
20502
20502
  },
20503
- {
20504
- id: "google/gemini-2.5-flash-preview:free",
20505
- name: "Gemini 2.5 Flash",
20506
- description: "Free Google model with thinking capabilities",
20507
- category: "fast",
20508
- provider: "openrouter",
20509
- contextLength: 1048576,
20510
- free: true
20511
- },
20512
- {
20513
- id: "google/gemini-3-flash-preview",
20514
- name: "Gemini 3 Flash",
20515
- description: "Google's fastest model, 1M context",
20516
- category: "fast",
20517
- provider: "openrouter",
20518
- contextLength: 1048576
20519
- },
20520
20503
  {
20521
20504
  id: "anthropic/claude-haiku-4-5",
20522
20505
  name: "Claude Haiku 4.5",
@@ -20525,14 +20508,6 @@ var OPENROUTER_MODELS = [
20525
20508
  provider: "openrouter",
20526
20509
  contextLength: 200000
20527
20510
  },
20528
- {
20529
- id: "openai/gpt-5.1-codex-mini",
20530
- name: "GPT 5.1 Codex Mini",
20531
- description: "OpenAI's efficient coding model",
20532
- category: "fast",
20533
- provider: "openrouter",
20534
- contextLength: 128000
20535
- },
20536
20511
  {
20537
20512
  id: "anthropic/claude-sonnet-4.5",
20538
20513
  name: "Claude Sonnet 4.5",
@@ -20549,22 +20524,6 @@ var OPENROUTER_MODELS = [
20549
20524
  provider: "openrouter",
20550
20525
  contextLength: 200000
20551
20526
  },
20552
- {
20553
- id: "openai/gpt-5.2-codex",
20554
- name: "GPT 5.2 Codex",
20555
- description: "OpenAI's latest coding model",
20556
- category: "smart",
20557
- provider: "openrouter",
20558
- contextLength: 400000
20559
- },
20560
- {
20561
- id: "google/gemini-2.5-pro",
20562
- name: "Gemini 2.5 Pro",
20563
- description: "Google's advanced reasoning model",
20564
- category: "smart",
20565
- provider: "openrouter",
20566
- contextLength: 1048576
20567
- },
20568
20527
  {
20569
20528
  id: "zhipu/glm-4.7",
20570
20529
  name: "GLM 4.7",
@@ -20591,6 +20550,15 @@ var OPENROUTER_MODELS = [
20591
20550
  }
20592
20551
  ];
20593
20552
  var OPENCODE_ZEN_MODELS = [
20553
+ {
20554
+ id: "big-pickle",
20555
+ name: "Big Pickle",
20556
+ description: "Free stealth model (limited time)",
20557
+ category: "smart",
20558
+ provider: "opencode-zen",
20559
+ contextLength: 128000,
20560
+ free: true
20561
+ },
20594
20562
  {
20595
20563
  id: "grok-code",
20596
20564
  name: "Grok Code Fast 1",
@@ -20618,34 +20586,6 @@ var OPENCODE_ZEN_MODELS = [
20618
20586
  contextLength: 128000,
20619
20587
  free: true
20620
20588
  },
20621
- {
20622
- id: "big-pickle",
20623
- name: "Big Pickle",
20624
- description: "Free stealth model (limited time)",
20625
- category: "smart",
20626
- provider: "opencode-zen",
20627
- contextLength: 128000,
20628
- free: true
20629
- },
20630
- {
20631
- id: "gpt-5-nano",
20632
- name: "GPT 5 Nano",
20633
- description: "Free OpenAI model (temporarily disabled)",
20634
- category: "fast",
20635
- provider: "opencode-zen",
20636
- contextLength: 128000,
20637
- free: true,
20638
- disabled: true,
20639
- disabledReason: "OpenCode Zen API issue"
20640
- },
20641
- {
20642
- id: "gemini-3-flash",
20643
- name: "Gemini 3 Flash",
20644
- description: "Google's fastest Gemini model",
20645
- category: "fast",
20646
- provider: "opencode-zen",
20647
- contextLength: 1e6
20648
- },
20649
20589
  {
20650
20590
  id: "claude-3-5-haiku",
20651
20591
  name: "Claude Haiku 3.5",
@@ -20654,16 +20594,6 @@ var OPENCODE_ZEN_MODELS = [
20654
20594
  provider: "opencode-zen",
20655
20595
  contextLength: 200000
20656
20596
  },
20657
- {
20658
- id: "gpt-5.1-codex-mini",
20659
- name: "GPT 5.1 Codex Mini",
20660
- description: "OpenAI's efficient coding model (temporarily disabled)",
20661
- category: "fast",
20662
- provider: "opencode-zen",
20663
- disabled: true,
20664
- disabledReason: "OpenCode Zen API issue",
20665
- contextLength: 128000
20666
- },
20667
20597
  {
20668
20598
  id: "claude-sonnet-4",
20669
20599
  name: "Claude Sonnet 4",
@@ -20680,34 +20610,6 @@ var OPENCODE_ZEN_MODELS = [
20680
20610
  provider: "opencode-zen",
20681
20611
  contextLength: 200000
20682
20612
  },
20683
- {
20684
- id: "gpt-5.1-codex",
20685
- name: "GPT 5.1 Codex",
20686
- description: "OpenAI's coding-optimized model (temporarily disabled)",
20687
- category: "smart",
20688
- provider: "opencode-zen",
20689
- contextLength: 128000,
20690
- disabled: true,
20691
- disabledReason: "OpenCode Zen API issue"
20692
- },
20693
- {
20694
- id: "gpt-5.2-codex",
20695
- name: "GPT 5.2 Codex",
20696
- description: "OpenAI's latest coding model (temporarily disabled)",
20697
- category: "smart",
20698
- provider: "opencode-zen",
20699
- contextLength: 128000,
20700
- disabled: true,
20701
- disabledReason: "OpenCode Zen API issue"
20702
- },
20703
- {
20704
- id: "gemini-3-pro",
20705
- name: "Gemini 3 Pro",
20706
- description: "Google's advanced Gemini model",
20707
- category: "smart",
20708
- provider: "opencode-zen",
20709
- contextLength: 1e6
20710
- },
20711
20613
  {
20712
20614
  id: "kimi-k2",
20713
20615
  name: "Kimi K2",
@@ -21070,7 +20972,7 @@ var DEFAULT_CONFIG = {
21070
20972
  provider: "opencode-zen",
21071
20973
  openrouterApiKey: "",
21072
20974
  opencodeZenApiKey: "",
21073
- defaultModel: "gemini-3-flash",
20975
+ defaultModel: "big-pickle",
21074
20976
  safetyLevel: "moderate",
21075
20977
  dryRunByDefault: false,
21076
20978
  blockedCommands: [
@@ -21738,6 +21640,13 @@ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
21738
21640
  return data.choices[0]?.message?.content?.trim() || "";
21739
21641
  }
21740
21642
  var DEBUG_API = process.env.DEBUG_API === "1";
21643
+ function appendDebugInfo(message, status, responseText) {
21644
+ if (!DEBUG_API)
21645
+ return message;
21646
+ const snippet = responseText.slice(0, 1000);
21647
+ return `${message}
21648
+ [DEBUG] status=${status} response=${snippet}`;
21649
+ }
21741
21650
  async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput) {
21742
21651
  if (DEBUG_API) {
21743
21652
  console.error(`[DEBUG] Calling OpenAI Responses API`);
@@ -21755,7 +21664,8 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
21755
21664
  instructions: systemPrompt,
21756
21665
  input: userInput,
21757
21666
  max_output_tokens: 500,
21758
- temperature: 0.1
21667
+ temperature: 0.1,
21668
+ stream: false
21759
21669
  })
21760
21670
  });
21761
21671
  const responseText = await response.text();
@@ -21773,7 +21683,7 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
21773
21683
  errorMessage = errorData.message;
21774
21684
  }
21775
21685
  } catch {}
21776
- throw new Error(errorMessage);
21686
+ throw new Error(appendDebugInfo(errorMessage, response.status, responseText));
21777
21687
  }
21778
21688
  let data;
21779
21689
  try {
@@ -21782,7 +21692,8 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
21782
21692
  throw new Error(`Invalid JSON response: ${responseText.slice(0, 200)}`);
21783
21693
  }
21784
21694
  if (data.error) {
21785
- throw new Error(data.error.message || data.error);
21695
+ const errorMessage = data.error.message || data.error;
21696
+ throw new Error(appendDebugInfo(errorMessage, response.status, responseText));
21786
21697
  }
21787
21698
  if (typeof data.output_text === "string") {
21788
21699
  return data.output_text.trim();
@@ -21837,7 +21748,7 @@ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
21837
21748
  errorMessage = errorData.error.message;
21838
21749
  }
21839
21750
  } catch {}
21840
- throw new Error(errorMessage);
21751
+ throw new Error(appendDebugInfo(errorMessage, response.status, errorText));
21841
21752
  }
21842
21753
  const data = await response.json();
21843
21754
  if (data.error) {
@@ -21876,21 +21787,38 @@ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput)
21876
21787
  errorMessage = errorData.error.message;
21877
21788
  }
21878
21789
  } catch {}
21879
- throw new Error(errorMessage);
21790
+ throw new Error(appendDebugInfo(errorMessage, response.status, errorText));
21880
21791
  }
21881
21792
  const data = await response.json();
21882
21793
  if (data.error) {
21883
21794
  throw new Error(data.error.message);
21884
21795
  }
21885
- return data.choices?.[0]?.message?.content?.trim() || "";
21796
+ const choice = data.choices?.[0];
21797
+ const messageContent = choice?.message?.content;
21798
+ if (typeof messageContent === "string") {
21799
+ return messageContent.trim();
21800
+ }
21801
+ if (Array.isArray(messageContent)) {
21802
+ const textBlocks = messageContent.map((block) => typeof block === "string" ? block : block?.text).filter(Boolean);
21803
+ if (textBlocks.length > 0) {
21804
+ return textBlocks.join("").trim();
21805
+ }
21806
+ }
21807
+ if (typeof choice?.text === "string") {
21808
+ return choice.text.trim();
21809
+ }
21810
+ return "";
21886
21811
  }
21887
21812
  async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
21888
- const endpoint = `https://opencode.ai/zen/v1/models/${modelId}:generateContent`;
21813
+ const endpoint = `https://opencode.ai/zen/v1/models/${modelId}`;
21889
21814
  if (DEBUG_API) {
21890
21815
  console.error(`[DEBUG] Calling Google Gemini API`);
21891
21816
  console.error(`[DEBUG] Model: ${modelId}`);
21892
21817
  console.error(`[DEBUG] Endpoint: ${endpoint}`);
21893
21818
  }
21819
+ const prompt = `${systemPrompt}
21820
+
21821
+ User request: ${userInput}`;
21894
21822
  const response = await fetch(endpoint, {
21895
21823
  method: "POST",
21896
21824
  headers: {
@@ -21899,9 +21827,8 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
21899
21827
  },
21900
21828
  body: JSON.stringify({
21901
21829
  contents: [
21902
- { role: "user", parts: [{ text: userInput }] }
21830
+ { role: "user", parts: [{ text: prompt }] }
21903
21831
  ],
21904
- systemInstruction: { parts: [{ text: systemPrompt }] },
21905
21832
  generationConfig: {
21906
21833
  maxOutputTokens: 500,
21907
21834
  temperature: 0.1
@@ -21921,7 +21848,7 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
21921
21848
  errorMessage = errorData.error.message;
21922
21849
  }
21923
21850
  } catch {}
21924
- throw new Error(errorMessage);
21851
+ throw new Error(appendDebugInfo(errorMessage, response.status, responseText));
21925
21852
  }
21926
21853
  let data;
21927
21854
  try {
@@ -21930,7 +21857,7 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
21930
21857
  throw new Error(`Invalid JSON response: ${responseText.slice(0, 200)}`);
21931
21858
  }
21932
21859
  if (data.error) {
21933
- throw new Error(data.error.message);
21860
+ throw new Error(appendDebugInfo(data.error.message, response.status, responseText));
21934
21861
  }
21935
21862
  const candidate = data.candidates?.[0];
21936
21863
  const textPart = candidate?.content?.parts?.find((p) => p.text);
@@ -21966,7 +21893,11 @@ async function translateToCommand(apiKey, model, userInput, cwd, history = [], r
21966
21893
  break;
21967
21894
  }
21968
21895
  }
21969
- return cleanCommand(rawCommand);
21896
+ const cleaned = cleanCommand(rawCommand);
21897
+ if (!cleaned) {
21898
+ throw new Error("Model returned an empty command. Try another model or rephrase your request.");
21899
+ }
21900
+ return cleaned;
21970
21901
  }
21971
21902
 
21972
21903
  // src/lib/theme.ts
@@ -22319,7 +22250,7 @@ Enter your API key below:`,
22319
22250
  const freeNote = new TextRenderable(renderer, {
22320
22251
  id: "free-note",
22321
22252
  content: t`
22322
- ${fg("#22c55e")("Tip:")} OpenCode Zen has free models like GPT 5 Nano and Grok Code!`,
22253
+ ${fg("#22c55e")("Tip:")} OpenCode Zen has free models like Big Pickle and GLM 4.7!`,
22323
22254
  marginTop: 1
22324
22255
  });
22325
22256
  container.add(freeNote);
@@ -22335,7 +22266,7 @@ ${fg("#64748b")("Press Enter to save | Ctrl+C to exit")}`,
22335
22266
  if (value.trim()) {
22336
22267
  setApiKey(provider, value.trim());
22337
22268
  if (provider === "opencode-zen") {
22338
- currentModel = OPENCODE_ZEN_MODELS.find((m) => m.id === "gpt-5-nano") || OPENCODE_ZEN_MODELS[0];
22269
+ currentModel = OPENCODE_ZEN_MODELS.find((m) => m.id === "big-pickle") || OPENCODE_ZEN_MODELS[0];
22339
22270
  } else {
22340
22271
  currentModel = OPENROUTER_MODELS[0];
22341
22272
  }
@@ -22371,11 +22302,6 @@ function createMainUI() {
22371
22302
  flexGrow: 1
22372
22303
  });
22373
22304
  headerRow.add(headerText);
22374
- const modelBadge = new TextRenderable(renderer, {
22375
- id: "model-badge",
22376
- content: getModelDisplay()
22377
- });
22378
- headerRow.add(modelBadge);
22379
22305
  statusBarText = new TextRenderable(renderer, {
22380
22306
  id: "status-bar-text",
22381
22307
  content: getStatusBarContent(),
@@ -22458,14 +22384,14 @@ function getStatusBarContent() {
22458
22384
  function getHelpBarContent() {
22459
22385
  const theme = getTheme();
22460
22386
  if (awaitingConfirmation) {
22461
- return t`${fg(theme.colors.warning)("[Enter] Run")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.error)("[Esc] Cancel")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.primary)("[e] Edit")}`;
22387
+ return t`${fg(theme.colors.warning)(">>> Press Enter to execute command <<<")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.error)("Esc")}${fg(theme.colors.textMuted)(" Cancel")} ${fg(theme.colors.primary)("e")}${fg(theme.colors.textMuted)(" Edit")} ${fg(theme.colors.primary)("c")}${fg(theme.colors.textMuted)(" Copy")}`;
22462
22388
  }
22463
22389
  return t`${fg(theme.colors.textMuted)("Ctrl+X")} ${fg(theme.colors.primary)("P")}${fg(theme.colors.textMuted)(" Palette")} ${fg(theme.colors.primary)("M")}${fg(theme.colors.textMuted)(" Model")} ${fg(theme.colors.primary)("T")}${fg(theme.colors.textMuted)(" Theme")} ${fg(theme.colors.primary)("D")}${fg(theme.colors.textMuted)(" Dry-run")} ${fg(theme.colors.primary)("?")}${fg(theme.colors.textMuted)(" Help")}`;
22464
22390
  }
22465
22391
  function getWelcomeMessage() {
22466
22392
  const providerName = config.provider === "opencode-zen" ? "OpenCode Zen" : "OpenRouter";
22467
22393
  const freeNote = config.provider === "opencode-zen" ? `
22468
- Free models: grok-code, glm-4.7-free` : "";
22394
+ Free models: big-pickle, glm-4.7-free` : "";
22469
22395
  return `Ready. Using ${providerName}.${freeNote}
22470
22396
  Type what you want to do, or press Ctrl+X P for command palette.`;
22471
22397
  }
@@ -22580,14 +22506,16 @@ function createAssistantMessageRenderable(msg, theme) {
22580
22506
  if (isSelected && !msg.executed) {
22581
22507
  const actionsText = new TextRenderable(renderer, {
22582
22508
  id: `msg-${msg.id}-actions`,
22583
- content: t`${fg(theme.colors.warning)("[Enter]")} ${fg(theme.colors.textMuted)("Run")} ${fg(theme.colors.primary)("[c]")} ${fg(theme.colors.textMuted)("Copy")} ${fg(theme.colors.primary)("[e]")} ${fg(theme.colors.textMuted)("Edit")}`
22509
+ content: t`${fg(theme.colors.warning)("Press Enter to run")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.primary)("[c]")} ${fg(theme.colors.textMuted)("Copy")} ${fg(theme.colors.primary)("[e]")} ${fg(theme.colors.textMuted)("Edit")} ${fg(theme.colors.error)("[Esc]")} ${fg(theme.colors.textMuted)("Cancel")}`
22584
22510
  });
22585
22511
  card.add(actionsText);
22586
22512
  }
22587
22513
  if (msg.executed) {
22514
+ const wasAutoRun = !msg.safety?.isDangerous;
22515
+ const execLabel = wasAutoRun ? "Auto-executed (safe)" : "Executed";
22588
22516
  const execText = new TextRenderable(renderer, {
22589
22517
  id: `msg-${msg.id}-exec`,
22590
- content: t`${fg(theme.colors.success)("Executed")}`
22518
+ content: t`${fg(theme.colors.success)("")} ${fg(theme.colors.success)(execLabel)}`
22591
22519
  });
22592
22520
  card.add(execText);
22593
22521
  }
@@ -22702,13 +22630,6 @@ function toggleLastResultExpand() {
22702
22630
  const lastResult = resultMessages[resultMessages.length - 1];
22703
22631
  toggleResultExpand(lastResult.id);
22704
22632
  }
22705
- function getModelDisplay() {
22706
- const theme = getTheme();
22707
- const categoryColor = currentModel.category === "fast" ? theme.colors.success : currentModel.category === "smart" ? theme.colors.primary : theme.colors.secondary;
22708
- const providerBadge = currentModel.provider === "opencode-zen" ? fg(theme.colors.accent)("[zen]") : fg(theme.colors.warning)("[or]");
22709
- const freeBadge = currentModel.free ? fg(theme.colors.success)(" FREE") : "";
22710
- return t`${providerBadge} ${fg(categoryColor)(currentModel.name)}${freeBadge}`;
22711
- }
22712
22633
  function refreshThemeColors() {
22713
22634
  const theme = getTheme();
22714
22635
  renderer.setBackgroundColor(theme.colors.background);
package/dist/index.js CHANGED
@@ -43,23 +43,6 @@ var OPENROUTER_MODELS = [
43
43
  contextLength: 128000,
44
44
  free: true
45
45
  },
46
- {
47
- id: "google/gemini-2.5-flash-preview:free",
48
- name: "Gemini 2.5 Flash",
49
- description: "Free Google model with thinking capabilities",
50
- category: "fast",
51
- provider: "openrouter",
52
- contextLength: 1048576,
53
- free: true
54
- },
55
- {
56
- id: "google/gemini-3-flash-preview",
57
- name: "Gemini 3 Flash",
58
- description: "Google's fastest model, 1M context",
59
- category: "fast",
60
- provider: "openrouter",
61
- contextLength: 1048576
62
- },
63
46
  {
64
47
  id: "anthropic/claude-haiku-4-5",
65
48
  name: "Claude Haiku 4.5",
@@ -68,14 +51,6 @@ var OPENROUTER_MODELS = [
68
51
  provider: "openrouter",
69
52
  contextLength: 200000
70
53
  },
71
- {
72
- id: "openai/gpt-5.1-codex-mini",
73
- name: "GPT 5.1 Codex Mini",
74
- description: "OpenAI's efficient coding model",
75
- category: "fast",
76
- provider: "openrouter",
77
- contextLength: 128000
78
- },
79
54
  {
80
55
  id: "anthropic/claude-sonnet-4.5",
81
56
  name: "Claude Sonnet 4.5",
@@ -92,22 +67,6 @@ var OPENROUTER_MODELS = [
92
67
  provider: "openrouter",
93
68
  contextLength: 200000
94
69
  },
95
- {
96
- id: "openai/gpt-5.2-codex",
97
- name: "GPT 5.2 Codex",
98
- description: "OpenAI's latest coding model",
99
- category: "smart",
100
- provider: "openrouter",
101
- contextLength: 400000
102
- },
103
- {
104
- id: "google/gemini-2.5-pro",
105
- name: "Gemini 2.5 Pro",
106
- description: "Google's advanced reasoning model",
107
- category: "smart",
108
- provider: "openrouter",
109
- contextLength: 1048576
110
- },
111
70
  {
112
71
  id: "zhipu/glm-4.7",
113
72
  name: "GLM 4.7",
@@ -134,6 +93,15 @@ var OPENROUTER_MODELS = [
134
93
  }
135
94
  ];
136
95
  var OPENCODE_ZEN_MODELS = [
96
+ {
97
+ id: "big-pickle",
98
+ name: "Big Pickle",
99
+ description: "Free stealth model (limited time)",
100
+ category: "smart",
101
+ provider: "opencode-zen",
102
+ contextLength: 128000,
103
+ free: true
104
+ },
137
105
  {
138
106
  id: "grok-code",
139
107
  name: "Grok Code Fast 1",
@@ -161,34 +129,6 @@ var OPENCODE_ZEN_MODELS = [
161
129
  contextLength: 128000,
162
130
  free: true
163
131
  },
164
- {
165
- id: "big-pickle",
166
- name: "Big Pickle",
167
- description: "Free stealth model (limited time)",
168
- category: "smart",
169
- provider: "opencode-zen",
170
- contextLength: 128000,
171
- free: true
172
- },
173
- {
174
- id: "gpt-5-nano",
175
- name: "GPT 5 Nano",
176
- description: "Free OpenAI model (temporarily disabled)",
177
- category: "fast",
178
- provider: "opencode-zen",
179
- contextLength: 128000,
180
- free: true,
181
- disabled: true,
182
- disabledReason: "OpenCode Zen API issue"
183
- },
184
- {
185
- id: "gemini-3-flash",
186
- name: "Gemini 3 Flash",
187
- description: "Google's fastest Gemini model",
188
- category: "fast",
189
- provider: "opencode-zen",
190
- contextLength: 1e6
191
- },
192
132
  {
193
133
  id: "claude-3-5-haiku",
194
134
  name: "Claude Haiku 3.5",
@@ -197,16 +137,6 @@ var OPENCODE_ZEN_MODELS = [
197
137
  provider: "opencode-zen",
198
138
  contextLength: 200000
199
139
  },
200
- {
201
- id: "gpt-5.1-codex-mini",
202
- name: "GPT 5.1 Codex Mini",
203
- description: "OpenAI's efficient coding model (temporarily disabled)",
204
- category: "fast",
205
- provider: "opencode-zen",
206
- disabled: true,
207
- disabledReason: "OpenCode Zen API issue",
208
- contextLength: 128000
209
- },
210
140
  {
211
141
  id: "claude-sonnet-4",
212
142
  name: "Claude Sonnet 4",
@@ -223,34 +153,6 @@ var OPENCODE_ZEN_MODELS = [
223
153
  provider: "opencode-zen",
224
154
  contextLength: 200000
225
155
  },
226
- {
227
- id: "gpt-5.1-codex",
228
- name: "GPT 5.1 Codex",
229
- description: "OpenAI's coding-optimized model (temporarily disabled)",
230
- category: "smart",
231
- provider: "opencode-zen",
232
- contextLength: 128000,
233
- disabled: true,
234
- disabledReason: "OpenCode Zen API issue"
235
- },
236
- {
237
- id: "gpt-5.2-codex",
238
- name: "GPT 5.2 Codex",
239
- description: "OpenAI's latest coding model (temporarily disabled)",
240
- category: "smart",
241
- provider: "opencode-zen",
242
- contextLength: 128000,
243
- disabled: true,
244
- disabledReason: "OpenCode Zen API issue"
245
- },
246
- {
247
- id: "gemini-3-pro",
248
- name: "Gemini 3 Pro",
249
- description: "Google's advanced Gemini model",
250
- category: "smart",
251
- provider: "opencode-zen",
252
- contextLength: 1e6
253
- },
254
156
  {
255
157
  id: "kimi-k2",
256
158
  name: "Kimi K2",
@@ -613,7 +515,7 @@ var DEFAULT_CONFIG = {
613
515
  provider: "opencode-zen",
614
516
  openrouterApiKey: "",
615
517
  opencodeZenApiKey: "",
616
- defaultModel: "gemini-3-flash",
518
+ defaultModel: "big-pickle",
617
519
  safetyLevel: "moderate",
618
520
  dryRunByDefault: false,
619
521
  blockedCommands: [
@@ -1259,6 +1161,13 @@ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
1259
1161
  return data.choices[0]?.message?.content?.trim() || "";
1260
1162
  }
1261
1163
  var DEBUG_API = process.env.DEBUG_API === "1";
1164
+ function appendDebugInfo(message, status, responseText) {
1165
+ if (!DEBUG_API)
1166
+ return message;
1167
+ const snippet = responseText.slice(0, 1000);
1168
+ return `${message}
1169
+ [DEBUG] status=${status} response=${snippet}`;
1170
+ }
1262
1171
  async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput) {
1263
1172
  if (DEBUG_API) {
1264
1173
  console.error(`[DEBUG] Calling OpenAI Responses API`);
@@ -1276,7 +1185,8 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
1276
1185
  instructions: systemPrompt,
1277
1186
  input: userInput,
1278
1187
  max_output_tokens: 500,
1279
- temperature: 0.1
1188
+ temperature: 0.1,
1189
+ stream: false
1280
1190
  })
1281
1191
  });
1282
1192
  const responseText = await response.text();
@@ -1294,7 +1204,7 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
1294
1204
  errorMessage = errorData.message;
1295
1205
  }
1296
1206
  } catch {}
1297
- throw new Error(errorMessage);
1207
+ throw new Error(appendDebugInfo(errorMessage, response.status, responseText));
1298
1208
  }
1299
1209
  let data;
1300
1210
  try {
@@ -1303,7 +1213,8 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
1303
1213
  throw new Error(`Invalid JSON response: ${responseText.slice(0, 200)}`);
1304
1214
  }
1305
1215
  if (data.error) {
1306
- throw new Error(data.error.message || data.error);
1216
+ const errorMessage = data.error.message || data.error;
1217
+ throw new Error(appendDebugInfo(errorMessage, response.status, responseText));
1307
1218
  }
1308
1219
  if (typeof data.output_text === "string") {
1309
1220
  return data.output_text.trim();
@@ -1358,7 +1269,7 @@ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
1358
1269
  errorMessage = errorData.error.message;
1359
1270
  }
1360
1271
  } catch {}
1361
- throw new Error(errorMessage);
1272
+ throw new Error(appendDebugInfo(errorMessage, response.status, errorText));
1362
1273
  }
1363
1274
  const data = await response.json();
1364
1275
  if (data.error) {
@@ -1397,21 +1308,38 @@ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput)
1397
1308
  errorMessage = errorData.error.message;
1398
1309
  }
1399
1310
  } catch {}
1400
- throw new Error(errorMessage);
1311
+ throw new Error(appendDebugInfo(errorMessage, response.status, errorText));
1401
1312
  }
1402
1313
  const data = await response.json();
1403
1314
  if (data.error) {
1404
1315
  throw new Error(data.error.message);
1405
1316
  }
1406
- return data.choices?.[0]?.message?.content?.trim() || "";
1317
+ const choice = data.choices?.[0];
1318
+ const messageContent = choice?.message?.content;
1319
+ if (typeof messageContent === "string") {
1320
+ return messageContent.trim();
1321
+ }
1322
+ if (Array.isArray(messageContent)) {
1323
+ const textBlocks = messageContent.map((block) => typeof block === "string" ? block : block?.text).filter(Boolean);
1324
+ if (textBlocks.length > 0) {
1325
+ return textBlocks.join("").trim();
1326
+ }
1327
+ }
1328
+ if (typeof choice?.text === "string") {
1329
+ return choice.text.trim();
1330
+ }
1331
+ return "";
1407
1332
  }
1408
1333
  async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
1409
- const endpoint = `https://opencode.ai/zen/v1/models/${modelId}:generateContent`;
1334
+ const endpoint = `https://opencode.ai/zen/v1/models/${modelId}`;
1410
1335
  if (DEBUG_API) {
1411
1336
  console.error(`[DEBUG] Calling Google Gemini API`);
1412
1337
  console.error(`[DEBUG] Model: ${modelId}`);
1413
1338
  console.error(`[DEBUG] Endpoint: ${endpoint}`);
1414
1339
  }
1340
+ const prompt = `${systemPrompt}
1341
+
1342
+ User request: ${userInput}`;
1415
1343
  const response = await fetch(endpoint, {
1416
1344
  method: "POST",
1417
1345
  headers: {
@@ -1420,9 +1348,8 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
1420
1348
  },
1421
1349
  body: JSON.stringify({
1422
1350
  contents: [
1423
- { role: "user", parts: [{ text: userInput }] }
1351
+ { role: "user", parts: [{ text: prompt }] }
1424
1352
  ],
1425
- systemInstruction: { parts: [{ text: systemPrompt }] },
1426
1353
  generationConfig: {
1427
1354
  maxOutputTokens: 500,
1428
1355
  temperature: 0.1
@@ -1442,7 +1369,7 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
1442
1369
  errorMessage = errorData.error.message;
1443
1370
  }
1444
1371
  } catch {}
1445
- throw new Error(errorMessage);
1372
+ throw new Error(appendDebugInfo(errorMessage, response.status, responseText));
1446
1373
  }
1447
1374
  let data;
1448
1375
  try {
@@ -1451,7 +1378,7 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
1451
1378
  throw new Error(`Invalid JSON response: ${responseText.slice(0, 200)}`);
1452
1379
  }
1453
1380
  if (data.error) {
1454
- throw new Error(data.error.message);
1381
+ throw new Error(appendDebugInfo(data.error.message, response.status, responseText));
1455
1382
  }
1456
1383
  const candidate = data.candidates?.[0];
1457
1384
  const textPart = candidate?.content?.parts?.find((p) => p.text);
@@ -1487,7 +1414,11 @@ async function translateToCommand(apiKey, model, userInput, cwd, history = [], r
1487
1414
  break;
1488
1415
  }
1489
1416
  }
1490
- return cleanCommand(rawCommand);
1417
+ const cleaned = cleanCommand(rawCommand);
1418
+ if (!cleaned) {
1419
+ throw new Error("Model returned an empty command. Try another model or rephrase your request.");
1420
+ }
1421
+ return cleaned;
1491
1422
  }
1492
1423
 
1493
1424
  // src/lib/config.ts
@@ -1503,7 +1434,7 @@ var DEFAULT_CONFIG2 = {
1503
1434
  provider: "opencode-zen",
1504
1435
  openrouterApiKey: "",
1505
1436
  opencodeZenApiKey: "",
1506
- defaultModel: "gemini-3-flash",
1437
+ defaultModel: "big-pickle",
1507
1438
  safetyLevel: "moderate",
1508
1439
  dryRunByDefault: false,
1509
1440
  blockedCommands: [
package/dist/tui.js CHANGED
@@ -20500,23 +20500,6 @@ var OPENROUTER_MODELS = [
20500
20500
  contextLength: 128000,
20501
20501
  free: true
20502
20502
  },
20503
- {
20504
- id: "google/gemini-2.5-flash-preview:free",
20505
- name: "Gemini 2.5 Flash",
20506
- description: "Free Google model with thinking capabilities",
20507
- category: "fast",
20508
- provider: "openrouter",
20509
- contextLength: 1048576,
20510
- free: true
20511
- },
20512
- {
20513
- id: "google/gemini-3-flash-preview",
20514
- name: "Gemini 3 Flash",
20515
- description: "Google's fastest model, 1M context",
20516
- category: "fast",
20517
- provider: "openrouter",
20518
- contextLength: 1048576
20519
- },
20520
20503
  {
20521
20504
  id: "anthropic/claude-haiku-4-5",
20522
20505
  name: "Claude Haiku 4.5",
@@ -20525,14 +20508,6 @@ var OPENROUTER_MODELS = [
20525
20508
  provider: "openrouter",
20526
20509
  contextLength: 200000
20527
20510
  },
20528
- {
20529
- id: "openai/gpt-5.1-codex-mini",
20530
- name: "GPT 5.1 Codex Mini",
20531
- description: "OpenAI's efficient coding model",
20532
- category: "fast",
20533
- provider: "openrouter",
20534
- contextLength: 128000
20535
- },
20536
20511
  {
20537
20512
  id: "anthropic/claude-sonnet-4.5",
20538
20513
  name: "Claude Sonnet 4.5",
@@ -20549,22 +20524,6 @@ var OPENROUTER_MODELS = [
20549
20524
  provider: "openrouter",
20550
20525
  contextLength: 200000
20551
20526
  },
20552
- {
20553
- id: "openai/gpt-5.2-codex",
20554
- name: "GPT 5.2 Codex",
20555
- description: "OpenAI's latest coding model",
20556
- category: "smart",
20557
- provider: "openrouter",
20558
- contextLength: 400000
20559
- },
20560
- {
20561
- id: "google/gemini-2.5-pro",
20562
- name: "Gemini 2.5 Pro",
20563
- description: "Google's advanced reasoning model",
20564
- category: "smart",
20565
- provider: "openrouter",
20566
- contextLength: 1048576
20567
- },
20568
20527
  {
20569
20528
  id: "zhipu/glm-4.7",
20570
20529
  name: "GLM 4.7",
@@ -20591,6 +20550,15 @@ var OPENROUTER_MODELS = [
20591
20550
  }
20592
20551
  ];
20593
20552
  var OPENCODE_ZEN_MODELS = [
20553
+ {
20554
+ id: "big-pickle",
20555
+ name: "Big Pickle",
20556
+ description: "Free stealth model (limited time)",
20557
+ category: "smart",
20558
+ provider: "opencode-zen",
20559
+ contextLength: 128000,
20560
+ free: true
20561
+ },
20594
20562
  {
20595
20563
  id: "grok-code",
20596
20564
  name: "Grok Code Fast 1",
@@ -20618,34 +20586,6 @@ var OPENCODE_ZEN_MODELS = [
20618
20586
  contextLength: 128000,
20619
20587
  free: true
20620
20588
  },
20621
- {
20622
- id: "big-pickle",
20623
- name: "Big Pickle",
20624
- description: "Free stealth model (limited time)",
20625
- category: "smart",
20626
- provider: "opencode-zen",
20627
- contextLength: 128000,
20628
- free: true
20629
- },
20630
- {
20631
- id: "gpt-5-nano",
20632
- name: "GPT 5 Nano",
20633
- description: "Free OpenAI model (temporarily disabled)",
20634
- category: "fast",
20635
- provider: "opencode-zen",
20636
- contextLength: 128000,
20637
- free: true,
20638
- disabled: true,
20639
- disabledReason: "OpenCode Zen API issue"
20640
- },
20641
- {
20642
- id: "gemini-3-flash",
20643
- name: "Gemini 3 Flash",
20644
- description: "Google's fastest Gemini model",
20645
- category: "fast",
20646
- provider: "opencode-zen",
20647
- contextLength: 1e6
20648
- },
20649
20589
  {
20650
20590
  id: "claude-3-5-haiku",
20651
20591
  name: "Claude Haiku 3.5",
@@ -20654,16 +20594,6 @@ var OPENCODE_ZEN_MODELS = [
20654
20594
  provider: "opencode-zen",
20655
20595
  contextLength: 200000
20656
20596
  },
20657
- {
20658
- id: "gpt-5.1-codex-mini",
20659
- name: "GPT 5.1 Codex Mini",
20660
- description: "OpenAI's efficient coding model (temporarily disabled)",
20661
- category: "fast",
20662
- provider: "opencode-zen",
20663
- disabled: true,
20664
- disabledReason: "OpenCode Zen API issue",
20665
- contextLength: 128000
20666
- },
20667
20597
  {
20668
20598
  id: "claude-sonnet-4",
20669
20599
  name: "Claude Sonnet 4",
@@ -20680,34 +20610,6 @@ var OPENCODE_ZEN_MODELS = [
20680
20610
  provider: "opencode-zen",
20681
20611
  contextLength: 200000
20682
20612
  },
20683
- {
20684
- id: "gpt-5.1-codex",
20685
- name: "GPT 5.1 Codex",
20686
- description: "OpenAI's coding-optimized model (temporarily disabled)",
20687
- category: "smart",
20688
- provider: "opencode-zen",
20689
- contextLength: 128000,
20690
- disabled: true,
20691
- disabledReason: "OpenCode Zen API issue"
20692
- },
20693
- {
20694
- id: "gpt-5.2-codex",
20695
- name: "GPT 5.2 Codex",
20696
- description: "OpenAI's latest coding model (temporarily disabled)",
20697
- category: "smart",
20698
- provider: "opencode-zen",
20699
- contextLength: 128000,
20700
- disabled: true,
20701
- disabledReason: "OpenCode Zen API issue"
20702
- },
20703
- {
20704
- id: "gemini-3-pro",
20705
- name: "Gemini 3 Pro",
20706
- description: "Google's advanced Gemini model",
20707
- category: "smart",
20708
- provider: "opencode-zen",
20709
- contextLength: 1e6
20710
- },
20711
20613
  {
20712
20614
  id: "kimi-k2",
20713
20615
  name: "Kimi K2",
@@ -21070,7 +20972,7 @@ var DEFAULT_CONFIG = {
21070
20972
  provider: "opencode-zen",
21071
20973
  openrouterApiKey: "",
21072
20974
  opencodeZenApiKey: "",
21073
- defaultModel: "gemini-3-flash",
20975
+ defaultModel: "big-pickle",
21074
20976
  safetyLevel: "moderate",
21075
20977
  dryRunByDefault: false,
21076
20978
  blockedCommands: [
@@ -21738,6 +21640,13 @@ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
21738
21640
  return data.choices[0]?.message?.content?.trim() || "";
21739
21641
  }
21740
21642
  var DEBUG_API = process.env.DEBUG_API === "1";
21643
+ function appendDebugInfo(message, status, responseText) {
21644
+ if (!DEBUG_API)
21645
+ return message;
21646
+ const snippet = responseText.slice(0, 1000);
21647
+ return `${message}
21648
+ [DEBUG] status=${status} response=${snippet}`;
21649
+ }
21741
21650
  async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput) {
21742
21651
  if (DEBUG_API) {
21743
21652
  console.error(`[DEBUG] Calling OpenAI Responses API`);
@@ -21755,7 +21664,8 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
21755
21664
  instructions: systemPrompt,
21756
21665
  input: userInput,
21757
21666
  max_output_tokens: 500,
21758
- temperature: 0.1
21667
+ temperature: 0.1,
21668
+ stream: false
21759
21669
  })
21760
21670
  });
21761
21671
  const responseText = await response.text();
@@ -21773,7 +21683,7 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
21773
21683
  errorMessage = errorData.message;
21774
21684
  }
21775
21685
  } catch {}
21776
- throw new Error(errorMessage);
21686
+ throw new Error(appendDebugInfo(errorMessage, response.status, responseText));
21777
21687
  }
21778
21688
  let data;
21779
21689
  try {
@@ -21782,7 +21692,8 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
21782
21692
  throw new Error(`Invalid JSON response: ${responseText.slice(0, 200)}`);
21783
21693
  }
21784
21694
  if (data.error) {
21785
- throw new Error(data.error.message || data.error);
21695
+ const errorMessage = data.error.message || data.error;
21696
+ throw new Error(appendDebugInfo(errorMessage, response.status, responseText));
21786
21697
  }
21787
21698
  if (typeof data.output_text === "string") {
21788
21699
  return data.output_text.trim();
@@ -21837,7 +21748,7 @@ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
21837
21748
  errorMessage = errorData.error.message;
21838
21749
  }
21839
21750
  } catch {}
21840
- throw new Error(errorMessage);
21751
+ throw new Error(appendDebugInfo(errorMessage, response.status, errorText));
21841
21752
  }
21842
21753
  const data = await response.json();
21843
21754
  if (data.error) {
@@ -21876,21 +21787,38 @@ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput)
21876
21787
  errorMessage = errorData.error.message;
21877
21788
  }
21878
21789
  } catch {}
21879
- throw new Error(errorMessage);
21790
+ throw new Error(appendDebugInfo(errorMessage, response.status, errorText));
21880
21791
  }
21881
21792
  const data = await response.json();
21882
21793
  if (data.error) {
21883
21794
  throw new Error(data.error.message);
21884
21795
  }
21885
- return data.choices?.[0]?.message?.content?.trim() || "";
21796
+ const choice = data.choices?.[0];
21797
+ const messageContent = choice?.message?.content;
21798
+ if (typeof messageContent === "string") {
21799
+ return messageContent.trim();
21800
+ }
21801
+ if (Array.isArray(messageContent)) {
21802
+ const textBlocks = messageContent.map((block) => typeof block === "string" ? block : block?.text).filter(Boolean);
21803
+ if (textBlocks.length > 0) {
21804
+ return textBlocks.join("").trim();
21805
+ }
21806
+ }
21807
+ if (typeof choice?.text === "string") {
21808
+ return choice.text.trim();
21809
+ }
21810
+ return "";
21886
21811
  }
21887
21812
  async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
21888
- const endpoint = `https://opencode.ai/zen/v1/models/${modelId}:generateContent`;
21813
+ const endpoint = `https://opencode.ai/zen/v1/models/${modelId}`;
21889
21814
  if (DEBUG_API) {
21890
21815
  console.error(`[DEBUG] Calling Google Gemini API`);
21891
21816
  console.error(`[DEBUG] Model: ${modelId}`);
21892
21817
  console.error(`[DEBUG] Endpoint: ${endpoint}`);
21893
21818
  }
21819
+ const prompt = `${systemPrompt}
21820
+
21821
+ User request: ${userInput}`;
21894
21822
  const response = await fetch(endpoint, {
21895
21823
  method: "POST",
21896
21824
  headers: {
@@ -21899,9 +21827,8 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
21899
21827
  },
21900
21828
  body: JSON.stringify({
21901
21829
  contents: [
21902
- { role: "user", parts: [{ text: userInput }] }
21830
+ { role: "user", parts: [{ text: prompt }] }
21903
21831
  ],
21904
- systemInstruction: { parts: [{ text: systemPrompt }] },
21905
21832
  generationConfig: {
21906
21833
  maxOutputTokens: 500,
21907
21834
  temperature: 0.1
@@ -21921,7 +21848,7 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
21921
21848
  errorMessage = errorData.error.message;
21922
21849
  }
21923
21850
  } catch {}
21924
- throw new Error(errorMessage);
21851
+ throw new Error(appendDebugInfo(errorMessage, response.status, responseText));
21925
21852
  }
21926
21853
  let data;
21927
21854
  try {
@@ -21930,7 +21857,7 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
21930
21857
  throw new Error(`Invalid JSON response: ${responseText.slice(0, 200)}`);
21931
21858
  }
21932
21859
  if (data.error) {
21933
- throw new Error(data.error.message);
21860
+ throw new Error(appendDebugInfo(data.error.message, response.status, responseText));
21934
21861
  }
21935
21862
  const candidate = data.candidates?.[0];
21936
21863
  const textPart = candidate?.content?.parts?.find((p) => p.text);
@@ -21966,7 +21893,11 @@ async function translateToCommand(apiKey, model, userInput, cwd, history = [], r
21966
21893
  break;
21967
21894
  }
21968
21895
  }
21969
- return cleanCommand(rawCommand);
21896
+ const cleaned = cleanCommand(rawCommand);
21897
+ if (!cleaned) {
21898
+ throw new Error("Model returned an empty command. Try another model or rephrase your request.");
21899
+ }
21900
+ return cleaned;
21970
21901
  }
21971
21902
 
21972
21903
  // src/lib/theme.ts
@@ -22319,7 +22250,7 @@ Enter your API key below:`,
22319
22250
  const freeNote = new TextRenderable(renderer, {
22320
22251
  id: "free-note",
22321
22252
  content: t`
22322
- ${fg("#22c55e")("Tip:")} OpenCode Zen has free models like GPT 5 Nano and Grok Code!`,
22253
+ ${fg("#22c55e")("Tip:")} OpenCode Zen has free models like Big Pickle and GLM 4.7!`,
22323
22254
  marginTop: 1
22324
22255
  });
22325
22256
  container.add(freeNote);
@@ -22335,7 +22266,7 @@ ${fg("#64748b")("Press Enter to save | Ctrl+C to exit")}`,
22335
22266
  if (value.trim()) {
22336
22267
  setApiKey(provider, value.trim());
22337
22268
  if (provider === "opencode-zen") {
22338
- currentModel = OPENCODE_ZEN_MODELS.find((m) => m.id === "gpt-5-nano") || OPENCODE_ZEN_MODELS[0];
22269
+ currentModel = OPENCODE_ZEN_MODELS.find((m) => m.id === "big-pickle") || OPENCODE_ZEN_MODELS[0];
22339
22270
  } else {
22340
22271
  currentModel = OPENROUTER_MODELS[0];
22341
22272
  }
@@ -22371,11 +22302,6 @@ function createMainUI() {
22371
22302
  flexGrow: 1
22372
22303
  });
22373
22304
  headerRow.add(headerText);
22374
- const modelBadge = new TextRenderable(renderer, {
22375
- id: "model-badge",
22376
- content: getModelDisplay()
22377
- });
22378
- headerRow.add(modelBadge);
22379
22305
  statusBarText = new TextRenderable(renderer, {
22380
22306
  id: "status-bar-text",
22381
22307
  content: getStatusBarContent(),
@@ -22458,14 +22384,14 @@ function getStatusBarContent() {
22458
22384
  function getHelpBarContent() {
22459
22385
  const theme = getTheme();
22460
22386
  if (awaitingConfirmation) {
22461
- return t`${fg(theme.colors.warning)("[Enter] Run")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.error)("[Esc] Cancel")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.primary)("[e] Edit")}`;
22387
+ return t`${fg(theme.colors.warning)(">>> Press Enter to execute command <<<")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.error)("Esc")}${fg(theme.colors.textMuted)(" Cancel")} ${fg(theme.colors.primary)("e")}${fg(theme.colors.textMuted)(" Edit")} ${fg(theme.colors.primary)("c")}${fg(theme.colors.textMuted)(" Copy")}`;
22462
22388
  }
22463
22389
  return t`${fg(theme.colors.textMuted)("Ctrl+X")} ${fg(theme.colors.primary)("P")}${fg(theme.colors.textMuted)(" Palette")} ${fg(theme.colors.primary)("M")}${fg(theme.colors.textMuted)(" Model")} ${fg(theme.colors.primary)("T")}${fg(theme.colors.textMuted)(" Theme")} ${fg(theme.colors.primary)("D")}${fg(theme.colors.textMuted)(" Dry-run")} ${fg(theme.colors.primary)("?")}${fg(theme.colors.textMuted)(" Help")}`;
22464
22390
  }
22465
22391
  function getWelcomeMessage() {
22466
22392
  const providerName = config.provider === "opencode-zen" ? "OpenCode Zen" : "OpenRouter";
22467
22393
  const freeNote = config.provider === "opencode-zen" ? `
22468
- Free models: grok-code, glm-4.7-free` : "";
22394
+ Free models: big-pickle, glm-4.7-free` : "";
22469
22395
  return `Ready. Using ${providerName}.${freeNote}
22470
22396
  Type what you want to do, or press Ctrl+X P for command palette.`;
22471
22397
  }
@@ -22580,14 +22506,16 @@ function createAssistantMessageRenderable(msg, theme) {
22580
22506
  if (isSelected && !msg.executed) {
22581
22507
  const actionsText = new TextRenderable(renderer, {
22582
22508
  id: `msg-${msg.id}-actions`,
22583
- content: t`${fg(theme.colors.warning)("[Enter]")} ${fg(theme.colors.textMuted)("Run")} ${fg(theme.colors.primary)("[c]")} ${fg(theme.colors.textMuted)("Copy")} ${fg(theme.colors.primary)("[e]")} ${fg(theme.colors.textMuted)("Edit")}`
22509
+ content: t`${fg(theme.colors.warning)("Press Enter to run")} ${fg(theme.colors.textMuted)("|")} ${fg(theme.colors.primary)("[c]")} ${fg(theme.colors.textMuted)("Copy")} ${fg(theme.colors.primary)("[e]")} ${fg(theme.colors.textMuted)("Edit")} ${fg(theme.colors.error)("[Esc]")} ${fg(theme.colors.textMuted)("Cancel")}`
22584
22510
  });
22585
22511
  card.add(actionsText);
22586
22512
  }
22587
22513
  if (msg.executed) {
22514
+ const wasAutoRun = !msg.safety?.isDangerous;
22515
+ const execLabel = wasAutoRun ? "Auto-executed (safe)" : "Executed";
22588
22516
  const execText = new TextRenderable(renderer, {
22589
22517
  id: `msg-${msg.id}-exec`,
22590
- content: t`${fg(theme.colors.success)("Executed")}`
22518
+ content: t`${fg(theme.colors.success)("")} ${fg(theme.colors.success)(execLabel)}`
22591
22519
  });
22592
22520
  card.add(execText);
22593
22521
  }
@@ -22702,13 +22630,6 @@ function toggleLastResultExpand() {
22702
22630
  const lastResult = resultMessages[resultMessages.length - 1];
22703
22631
  toggleResultExpand(lastResult.id);
22704
22632
  }
22705
- function getModelDisplay() {
22706
- const theme = getTheme();
22707
- const categoryColor = currentModel.category === "fast" ? theme.colors.success : currentModel.category === "smart" ? theme.colors.primary : theme.colors.secondary;
22708
- const providerBadge = currentModel.provider === "opencode-zen" ? fg(theme.colors.accent)("[zen]") : fg(theme.colors.warning)("[or]");
22709
- const freeBadge = currentModel.free ? fg(theme.colors.success)(" FREE") : "";
22710
- return t`${providerBadge} ${fg(categoryColor)(currentModel.name)}${freeBadge}`;
22711
- }
22712
22633
  function refreshThemeColors() {
22713
22634
  const theme = getTheme();
22714
22635
  renderer.setBackgroundColor(theme.colors.background);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@austinthesing/magic-shell",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Natural language to terminal commands with safety features. Supports OpenCode Zen (with free models) and OpenRouter.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",