@austinthesing/magic-shell 0.2.19 → 0.2.20

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/tui.js CHANGED
@@ -37000,21 +37000,66 @@ var WORKERS_AI_MODELS = [
37000
37000
  ];
37001
37001
  var OPENCODE_ZEN_MODELS = [
37002
37002
  {
37003
- id: "kimi-k2.6-free",
37004
- name: "Kimi K2.6 Free",
37005
- description: "Moonshot's latest model (free, limited time)",
37003
+ id: "minimax-m2.5-free",
37004
+ name: "MiniMax M2.5 Free",
37005
+ description: "MiniMax's free model (limited time)",
37006
37006
  category: "smart",
37007
37007
  provider: "opencode-zen",
37008
- contextLength: 262144,
37008
+ contextLength: 196608,
37009
37009
  free: true
37010
37010
  },
37011
37011
  {
37012
- id: "deepseek-v4-flash-free",
37013
- name: "DeepSeek V4 Flash Free",
37014
- description: "DeepSeek's latest fast model (free, limited time)",
37012
+ id: "ling-2.6-flash-free",
37013
+ name: "Ling 2.6 Flash Free",
37014
+ description: "Ling's free flash model (limited time)",
37015
37015
  category: "fast",
37016
37016
  provider: "opencode-zen",
37017
- contextLength: 1048576,
37017
+ contextLength: 131072,
37018
+ free: true
37019
+ },
37020
+ {
37021
+ id: "hy3-preview-free",
37022
+ name: "Hy3 Preview Free",
37023
+ description: "Hy3 preview model (free, limited time)",
37024
+ category: "smart",
37025
+ provider: "opencode-zen",
37026
+ contextLength: 131072,
37027
+ free: true
37028
+ },
37029
+ {
37030
+ id: "nemotron-3-super-free",
37031
+ name: "Nemotron 3 Super Free",
37032
+ description: "NVIDIA Nemotron free trial model",
37033
+ category: "smart",
37034
+ provider: "opencode-zen",
37035
+ contextLength: 131072,
37036
+ free: true
37037
+ },
37038
+ {
37039
+ id: "trinity-large-preview-free",
37040
+ name: "Trinity Large Preview Free",
37041
+ description: "Trinity large preview model (free, limited time)",
37042
+ category: "smart",
37043
+ provider: "opencode-zen",
37044
+ contextLength: 131072,
37045
+ free: true
37046
+ },
37047
+ {
37048
+ id: "big-pickle",
37049
+ name: "Big Pickle",
37050
+ description: "OpenCode stealth model (free, limited time)",
37051
+ category: "smart",
37052
+ provider: "opencode-zen",
37053
+ contextLength: 131072,
37054
+ free: true
37055
+ },
37056
+ {
37057
+ id: "gpt-5-nano",
37058
+ name: "GPT 5 Nano",
37059
+ description: "OpenAI's free lightweight GPT model",
37060
+ category: "fast",
37061
+ provider: "opencode-zen",
37062
+ contextLength: 400000,
37018
37063
  free: true
37019
37064
  },
37020
37065
  {
@@ -37583,7 +37628,8 @@ var DEFAULT_CONFIG = {
37583
37628
  workersAiApiKey: "",
37584
37629
  cloudflareAccountId: "",
37585
37630
  cloudflareAiGatewayId: "default",
37586
- defaultModel: "kimi-k2.6-free",
37631
+ defaultModel: "minimax-m2.5-free",
37632
+ thinkingLevel: "low",
37587
37633
  safetyLevel: "moderate",
37588
37634
  dryRunByDefault: false,
37589
37635
  blockedCommands: [
@@ -76352,7 +76398,94 @@ function cleanCommand(command) {
76352
76398
  }
76353
76399
  return cleaned.trim();
76354
76400
  }
76355
- async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
76401
+ function getThinkingLevel(config2) {
76402
+ return config2?.thinkingLevel || "low";
76403
+ }
76404
+ function supportsThinkingControl(modelId) {
76405
+ return modelId.includes("thinking") || modelId.includes("gpt-5") || modelId.includes("claude-") || modelId.includes("gemini-");
76406
+ }
76407
+ function buildOpenRouterThinkingOptions(modelId, thinkingLevel) {
76408
+ if (thinkingLevel === "off" || !supportsThinkingControl(modelId)) {
76409
+ return {};
76410
+ }
76411
+ return {
76412
+ reasoning: {
76413
+ effort: thinkingLevel
76414
+ }
76415
+ };
76416
+ }
76417
+ function buildOpenAICompatibleThinkingOptions(modelId, thinkingLevel) {
76418
+ if (thinkingLevel === "off" || !supportsThinkingControl(modelId)) {
76419
+ return {};
76420
+ }
76421
+ return {
76422
+ reasoning_effort: thinkingLevel
76423
+ };
76424
+ }
76425
+ function buildAiSdkProviderOptions(modelId, thinkingLevel, providerOptionsName) {
76426
+ if (thinkingLevel === "off" || !supportsThinkingControl(modelId)) {
76427
+ return;
76428
+ }
76429
+ if (modelId.startsWith("gpt-")) {
76430
+ const compatibleOptions = providerOptionsName && providerOptionsName !== "openai" ? {
76431
+ [providerOptionsName]: {
76432
+ reasoningEffort: thinkingLevel
76433
+ }
76434
+ } : {};
76435
+ return {
76436
+ openai: {
76437
+ reasoningEffort: thinkingLevel
76438
+ },
76439
+ openaiCompatible: {
76440
+ reasoningEffort: thinkingLevel
76441
+ },
76442
+ ...compatibleOptions
76443
+ };
76444
+ }
76445
+ if (modelId.startsWith("gemini-")) {
76446
+ return {
76447
+ google: {
76448
+ thinkingConfig: {
76449
+ thinkingLevel
76450
+ }
76451
+ }
76452
+ };
76453
+ }
76454
+ if (modelId.startsWith("claude-")) {
76455
+ const budgetByLevel = {
76456
+ low: 1024,
76457
+ medium: 4096,
76458
+ high: 8192
76459
+ };
76460
+ return {
76461
+ anthropic: {
76462
+ thinking: {
76463
+ type: "enabled",
76464
+ budgetTokens: budgetByLevel[thinkingLevel]
76465
+ }
76466
+ }
76467
+ };
76468
+ }
76469
+ if (modelId.includes("thinking")) {
76470
+ return {
76471
+ openaiCompatible: {
76472
+ reasoningEffort: thinkingLevel
76473
+ },
76474
+ ...providerOptionsName ? {
76475
+ [providerOptionsName]: {
76476
+ reasoningEffort: thinkingLevel
76477
+ }
76478
+ } : {}
76479
+ };
76480
+ }
76481
+ return;
76482
+ }
76483
+ function shouldOmitTemperature(modelId, thinkingLevel) {
76484
+ return thinkingLevel !== "off" && (modelId.startsWith("claude-") || modelId.includes("gpt-5"));
76485
+ }
76486
+ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
76487
+ const thinkingOptions = buildOpenRouterThinkingOptions(modelId, thinkingLevel);
76488
+ const temperatureOptions = shouldOmitTemperature(modelId, thinkingLevel) ? {} : { temperature: 0.1 };
76356
76489
  const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
76357
76490
  method: "POST",
76358
76491
  headers: {
@@ -76368,7 +76501,8 @@ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
76368
76501
  { role: "user", content: userInput }
76369
76502
  ],
76370
76503
  max_tokens: 500,
76371
- temperature: 0.1
76504
+ ...temperatureOptions,
76505
+ ...thinkingOptions
76372
76506
  })
76373
76507
  });
76374
76508
  if (!response.ok) {
@@ -76388,7 +76522,9 @@ async function callOpenRouter(apiKey, modelId, systemPrompt, userInput) {
76388
76522
  }
76389
76523
  return data.choices[0]?.message?.content?.trim() || "";
76390
76524
  }
76391
- async function callOpenAICompatibleFetch(baseURL, apiKey, modelId, systemPrompt, userInput, headers = {}, includeAuthorization = true) {
76525
+ async function callOpenAICompatibleFetch(baseURL, apiKey, modelId, systemPrompt, userInput, thinkingLevel, headers = {}, includeAuthorization = true) {
76526
+ const thinkingOptions = buildOpenAICompatibleThinkingOptions(modelId, thinkingLevel);
76527
+ const temperatureOptions = shouldOmitTemperature(modelId, thinkingLevel) ? {} : { temperature: 0.1 };
76392
76528
  const requestHeaders = {
76393
76529
  "Content-Type": "application/json",
76394
76530
  ...headers
@@ -76406,8 +76542,9 @@ async function callOpenAICompatibleFetch(baseURL, apiKey, modelId, systemPrompt,
76406
76542
  { role: "user", content: userInput }
76407
76543
  ],
76408
76544
  max_tokens: 500,
76409
- temperature: 0.1,
76410
- stream: false
76545
+ stream: false,
76546
+ ...temperatureOptions,
76547
+ ...thinkingOptions
76411
76548
  })
76412
76549
  });
76413
76550
  if (!response.ok) {
@@ -76439,42 +76576,45 @@ function getCloudflareAccountId(config2) {
76439
76576
  function getCloudflareGatewayId(config2) {
76440
76577
  return config2.cloudflareAiGatewayId || process.env.CLOUDFLARE_AI_GATEWAY_ID || process.env.CF_AIG_GATEWAY_ID || "default";
76441
76578
  }
76442
- async function callGatewayProvider(provider, apiKey, modelId, systemPrompt, userInput) {
76579
+ async function callGatewayProvider(provider, apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
76443
76580
  const config2 = loadConfig2();
76444
76581
  switch (provider) {
76445
76582
  case "vercel-ai-gateway":
76446
- return await callOpenAICompatibleFetch("https://ai-gateway.vercel.sh/v1", apiKey, modelId, systemPrompt, userInput);
76583
+ return await callOpenAICompatibleFetch("https://ai-gateway.vercel.sh/v1", apiKey, modelId, systemPrompt, userInput, thinkingLevel);
76447
76584
  case "cloudflare-ai-gateway": {
76448
76585
  const accountId = getCloudflareAccountId(config2);
76449
76586
  if (!accountId) {
76450
76587
  throw new Error("Cloudflare account ID is required. Set cloudflareAccountId in config or CLOUDFLARE_ACCOUNT_ID.");
76451
76588
  }
76452
76589
  const gatewayId = getCloudflareGatewayId(config2);
76453
- return await callOpenAICompatibleFetch(`https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}/compat`, apiKey, modelId, systemPrompt, userInput, { "cf-aig-authorization": `Bearer ${apiKey}` }, false);
76590
+ return await callOpenAICompatibleFetch(`https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}/compat`, apiKey, modelId, systemPrompt, userInput, thinkingLevel, { "cf-aig-authorization": `Bearer ${apiKey}` }, false);
76454
76591
  }
76455
76592
  case "workers-ai": {
76456
76593
  const accountId = getCloudflareAccountId(config2);
76457
76594
  if (!accountId) {
76458
76595
  throw new Error("Cloudflare account ID is required. Set cloudflareAccountId in config or CLOUDFLARE_ACCOUNT_ID.");
76459
76596
  }
76460
- return await callOpenAICompatibleFetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1`, apiKey, modelId, systemPrompt, userInput);
76597
+ return await callOpenAICompatibleFetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/v1`, apiKey, modelId, systemPrompt, userInput, thinkingLevel);
76461
76598
  }
76462
76599
  default:
76463
76600
  throw new Error(`Unsupported gateway provider: ${provider}`);
76464
76601
  }
76465
76602
  }
76466
76603
  var DEBUG_API = process.env.DEBUG_API === "1";
76467
- async function generateZenText(model, systemPrompt, userInput) {
76604
+ async function generateZenText(model, modelId, systemPrompt, userInput, thinkingLevel, providerOptionsName) {
76605
+ const providerOptions = buildAiSdkProviderOptions(modelId, thinkingLevel, providerOptionsName);
76606
+ const temperatureOptions = shouldOmitTemperature(modelId, thinkingLevel) ? {} : { temperature: 0.1 };
76468
76607
  const { text: text2 } = await generateText({
76469
76608
  model,
76470
76609
  system: systemPrompt,
76471
76610
  prompt: userInput,
76472
76611
  maxOutputTokens: 500,
76473
- temperature: 0.1
76612
+ ...temperatureOptions,
76613
+ ...providerOptions ? { providerOptions } : {}
76474
76614
  });
76475
76615
  return text2.trim();
76476
76616
  }
76477
- async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput) {
76617
+ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
76478
76618
  if (DEBUG_API) {
76479
76619
  console.error(`[DEBUG] Calling OpenAI Responses API`);
76480
76620
  console.error(`[DEBUG] Model: ${modelId}`);
@@ -76485,7 +76625,7 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
76485
76625
  baseURL: ZEN_BASE_URL
76486
76626
  });
76487
76627
  try {
76488
- return await generateZenText(openai2(modelId), systemPrompt, userInput);
76628
+ return await generateZenText(openai2(modelId), modelId, systemPrompt, userInput, thinkingLevel);
76489
76629
  } catch (error40) {
76490
76630
  const message = error40 instanceof Error ? error40.message : String(error40);
76491
76631
  if (DEBUG_API) {
@@ -76494,7 +76634,7 @@ async function callZenOpenAIResponses(apiKey, modelId, systemPrompt, userInput)
76494
76634
  throw new Error(message);
76495
76635
  }
76496
76636
  }
76497
- async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
76637
+ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
76498
76638
  if (DEBUG_API) {
76499
76639
  console.error(`[DEBUG] Calling Anthropic Messages API`);
76500
76640
  console.error(`[DEBUG] Model: ${modelId}`);
@@ -76505,7 +76645,7 @@ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
76505
76645
  baseURL: ZEN_BASE_URL
76506
76646
  });
76507
76647
  try {
76508
- return await generateZenText(anthropic2(modelId), systemPrompt, userInput);
76648
+ return await generateZenText(anthropic2(modelId), modelId, systemPrompt, userInput, thinkingLevel);
76509
76649
  } catch (error40) {
76510
76650
  const message = error40 instanceof Error ? error40.message : String(error40);
76511
76651
  if (DEBUG_API) {
@@ -76514,7 +76654,7 @@ async function callZenAnthropic(apiKey, modelId, systemPrompt, userInput) {
76514
76654
  throw new Error(message);
76515
76655
  }
76516
76656
  }
76517
- async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput) {
76657
+ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
76518
76658
  if (DEBUG_API) {
76519
76659
  console.error(`[DEBUG] Calling OpenAI-compatible Chat Completions API`);
76520
76660
  console.error(`[DEBUG] Model: ${modelId}`);
@@ -76525,7 +76665,7 @@ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput)
76525
76665
  baseURL: ZEN_BASE_URL
76526
76666
  });
76527
76667
  try {
76528
- return await generateZenText(openaiCompatible(modelId), systemPrompt, userInput);
76668
+ return await generateZenText(openaiCompatible(modelId), modelId, systemPrompt, userInput, thinkingLevel, "opencodeZen");
76529
76669
  } catch (error40) {
76530
76670
  const message = error40 instanceof Error ? error40.message : String(error40);
76531
76671
  if (DEBUG_API) {
@@ -76534,7 +76674,7 @@ async function callZenOpenAICompatible(apiKey, modelId, systemPrompt, userInput)
76534
76674
  throw new Error(message);
76535
76675
  }
76536
76676
  }
76537
- async function callCustomModel(model, systemPrompt, userInput) {
76677
+ async function callCustomModel(model, systemPrompt, userInput, thinkingLevel) {
76538
76678
  if (DEBUG_API) {
76539
76679
  console.error(`[DEBUG] Calling Custom Model`);
76540
76680
  console.error(`[DEBUG] Model: ${model.modelId}`);
@@ -76546,7 +76686,7 @@ async function callCustomModel(model, systemPrompt, userInput) {
76546
76686
  baseURL: model.baseUrl
76547
76687
  });
76548
76688
  try {
76549
- return await generateZenText(openaiCompatible(model.modelId), systemPrompt, userInput);
76689
+ return await generateZenText(openaiCompatible(model.modelId), model.modelId, systemPrompt, userInput, thinkingLevel, "custom");
76550
76690
  } catch (error40) {
76551
76691
  const message = error40 instanceof Error ? error40.message : String(error40);
76552
76692
  if (DEBUG_API) {
@@ -76555,7 +76695,7 @@ async function callCustomModel(model, systemPrompt, userInput) {
76555
76695
  throw new Error(message);
76556
76696
  }
76557
76697
  }
76558
- async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
76698
+ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput, thinkingLevel) {
76559
76699
  if (DEBUG_API) {
76560
76700
  console.error(`[DEBUG] Calling Google Gemini API`);
76561
76701
  console.error(`[DEBUG] Model: ${modelId}`);
@@ -76565,7 +76705,7 @@ async function callZenGoogle(apiKey, modelId, systemPrompt, userInput) {
76565
76705
  baseURL: `https://opencode.ai/zen/v1/models/${modelId}`
76566
76706
  });
76567
76707
  try {
76568
- return await generateZenText(google2(modelId), systemPrompt, userInput);
76708
+ return await generateZenText(google2(modelId), modelId, systemPrompt, userInput, thinkingLevel);
76569
76709
  } catch (error40) {
76570
76710
  const message = error40 instanceof Error ? error40.message : String(error40);
76571
76711
  if (DEBUG_API) {
@@ -76581,30 +76721,31 @@ function getShellInfo() {
76581
76721
  }
76582
76722
  return cachedShellInfo;
76583
76723
  }
76584
- async function translateToCommand(apiKey, model, userInput, cwd, history = [], repoContextEnabled) {
76724
+ async function translateToCommand(apiKey, model, userInput, cwd, history = [], repoContextEnabled, config2) {
76585
76725
  const shellInfo = getShellInfo();
76586
76726
  const systemPrompt = buildSystemPrompt(cwd, history, shellInfo, repoContextEnabled);
76727
+ const thinkingLevel = getThinkingLevel(config2);
76587
76728
  let rawCommand;
76588
76729
  if (isCustomModel(model)) {
76589
- rawCommand = await callCustomModel(model, systemPrompt, userInput);
76730
+ rawCommand = await callCustomModel(model, systemPrompt, userInput, "off");
76590
76731
  } else if (model.provider === "openrouter") {
76591
- rawCommand = await callOpenRouter(apiKey, model.id, systemPrompt, userInput);
76732
+ rawCommand = await callOpenRouter(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
76592
76733
  } else if (model.provider === "vercel-ai-gateway" || model.provider === "cloudflare-ai-gateway" || model.provider === "workers-ai") {
76593
- rawCommand = await callGatewayProvider(model.provider, apiKey, model.id, systemPrompt, userInput);
76734
+ rawCommand = await callGatewayProvider(model.provider, apiKey, model.id, systemPrompt, userInput, thinkingLevel);
76594
76735
  } else {
76595
76736
  const apiType = getZenApiType(model.id);
76596
76737
  switch (apiType) {
76597
76738
  case "openai-responses":
76598
- rawCommand = await callZenOpenAIResponses(apiKey, model.id, systemPrompt, userInput);
76739
+ rawCommand = await callZenOpenAIResponses(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
76599
76740
  break;
76600
76741
  case "anthropic":
76601
- rawCommand = await callZenAnthropic(apiKey, model.id, systemPrompt, userInput);
76742
+ rawCommand = await callZenAnthropic(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
76602
76743
  break;
76603
76744
  case "google":
76604
- rawCommand = await callZenGoogle(apiKey, model.id, systemPrompt, userInput);
76745
+ rawCommand = await callZenGoogle(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
76605
76746
  break;
76606
76747
  case "openai-compatible":
76607
- rawCommand = await callZenOpenAICompatible(apiKey, model.id, systemPrompt, userInput);
76748
+ rawCommand = await callZenOpenAICompatible(apiKey, model.id, systemPrompt, userInput, thinkingLevel);
76608
76749
  break;
76609
76750
  }
76610
76751
  }
@@ -77141,15 +77282,16 @@ function getStatusBarContent() {
77141
77282
  const safeModeIndicator = dryRunMode ? fg(theme.colors.warning)("[DRY RUN]") : "";
77142
77283
  const safetyLevelColor = config2.safetyLevel === "strict" ? theme.colors.warning : config2.safetyLevel === "relaxed" ? theme.colors.error : theme.colors.success;
77143
77284
  const safetyIndicator = fg(safetyLevelColor)(`[${config2.safetyLevel}]`);
77285
+ const thinkingIndicator = config2.thinkingLevel !== "off" ? fg(theme.colors.secondary)(`[Think:${config2.thinkingLevel}]`) : "";
77144
77286
  const repoContextIndicator = config2.repoContext ? fg(theme.colors.info)("[Repo]") : "";
77145
- return t`${fg(theme.colors.textMuted)("Provider:")} ${fg(theme.colors.text)(providerName)} ${fg(theme.colors.textMuted)("Model:")} ${fg(theme.colors.text)(currentModel.name)} ${safetyIndicator}${safeModeIndicator ? " " : ""}${safeModeIndicator}${repoContextIndicator ? " " : ""}${repoContextIndicator}`;
77287
+ return t`${fg(theme.colors.textMuted)("Provider:")} ${fg(theme.colors.text)(providerName)} ${fg(theme.colors.textMuted)("Model:")} ${fg(theme.colors.text)(currentModel.name)} ${safetyIndicator}${thinkingIndicator ? " " : ""}${thinkingIndicator}${safeModeIndicator ? " " : ""}${safeModeIndicator}${repoContextIndicator ? " " : ""}${repoContextIndicator}`;
77146
77288
  }
77147
77289
  function getHelpBarContent() {
77148
77290
  const theme = getTheme();
77149
77291
  if (awaitingConfirmation) {
77150
77292
  return t`${fg(theme.colors.warning)(">>> Cmd+Enter or Enter to execute <<<")} ${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")}`;
77151
77293
  }
77152
- return t`${fg(theme.colors.primary)("Ctrl+X P")}${fg(theme.colors.textMuted)(" Commands")} ${fg(theme.colors.primary)("Ctrl+Y")}${fg(theme.colors.textMuted)(" Safety")} ${fg(theme.colors.primary)("Ctrl+Z")}${fg(theme.colors.textMuted)(" Exit")}`;
77294
+ return t`${fg(theme.colors.primary)("Ctrl+X P")}${fg(theme.colors.textMuted)(" Commands")} ${fg(theme.colors.primary)("Ctrl+Y")}${fg(theme.colors.textMuted)(" Safety")} ${fg(theme.colors.primary)("Ctrl+K")}${fg(theme.colors.textMuted)(" Think")} ${fg(theme.colors.primary)("Ctrl+Z")}${fg(theme.colors.textMuted)(" Exit")}`;
77153
77295
  }
77154
77296
  function getInputHintContent() {
77155
77297
  const theme = getTheme();
@@ -77472,7 +77614,7 @@ async function translateAndProcess(input) {
77472
77614
  }
77473
77615
  const loadingMsg = addSystemMessage("Translating...");
77474
77616
  try {
77475
- const command = await translateToCommand(apiKey, currentModel, input, currentCwd, history, config2.repoContext);
77617
+ const command = await translateToCommand(apiKey, currentModel, input, currentCwd, history, config2.repoContext, config2);
77476
77618
  chatScrollBox.remove(`msg-${loadingMsg.id}`);
77477
77619
  chatMessages = chatMessages.filter((m2) => m2.id !== loadingMsg.id);
77478
77620
  const safety = analyzeCommand(command, config2);
@@ -77602,6 +77744,10 @@ async function handleSpecialCommand(input) {
77602
77744
  statusBarText.content = getStatusBarContent();
77603
77745
  addSystemMessage(`Dry-run mode: ${dryRunMode ? "ON" : "OFF"}`);
77604
77746
  break;
77747
+ case "thinking":
77748
+ case "think":
77749
+ cycleThinkingLevel();
77750
+ break;
77605
77751
  case "config":
77606
77752
  await showConfig();
77607
77753
  break;
@@ -77628,6 +77774,7 @@ function clearChat() {
77628
77774
  function showHelp() {
77629
77775
  const helpText = `Direct Shortcuts:
77630
77776
  Ctrl+Y Cycle safety level (strict/moderate/relaxed)
77777
+ Ctrl+K Cycle thinking level (low/medium/high/off)
77631
77778
  Ctrl+Z Exit magic-shell
77632
77779
  Ctrl+C Cancel / Close popup
77633
77780
 
@@ -77636,19 +77783,26 @@ P Command palette M Change model
77636
77783
  S Switch provider D Toggle dry-run
77637
77784
  T Change theme R Toggle repo context
77638
77785
  H Show history L Clear chat
77639
- C Show config ? This help
77786
+ C Show config K Thinking level
77787
+ ? This help
77640
77788
 
77641
77789
  Commands (type ! or / followed by):
77642
77790
  help Show this help model Change model
77643
77791
  provider Switch provider dry Toggle dry-run
77644
- config Show configuration history Show history
77645
- clear Clear chat
77792
+ thinking Cycle thinking config Show configuration
77793
+ history Show history clear Clear chat
77646
77794
 
77647
77795
  Safety Levels:
77648
77796
  - strict: Confirm ALL potentially dangerous commands
77649
77797
  - moderate: Confirm high/critical severity commands (default)
77650
77798
  - relaxed: Only confirm critical commands
77651
77799
 
77800
+ Thinking Levels:
77801
+ - low: Default low-cost reasoning for supported models
77802
+ - medium: More reasoning for harder translations
77803
+ - high: Maximum reasoning for supported models
77804
+ - off: Do not request provider thinking controls
77805
+
77652
77806
  Tips:
77653
77807
  - Type naturally: "list all files" -> ls -la
77654
77808
  - Use ! or / commands: !help or /help
@@ -77675,6 +77829,7 @@ Theme: ${theme.name}
77675
77829
  Shell: ${shellInfo.shell} (${shellInfo.shellPath})
77676
77830
  Platform: ${shellInfo.platform}${shellInfo.isWSL ? " (WSL)" : ""}
77677
77831
  Safety: ${config2.safetyLevel}
77832
+ Thinking: ${config2.thinkingLevel}
77678
77833
  Dry-run: ${dryRunMode ? "ON" : "OFF"}
77679
77834
  Repo context: ${config2.repoContext ? "ON" : "OFF"}
77680
77835
  API Key: ${apiKeyStatus}
@@ -77914,6 +78069,15 @@ function showThemeSelector() {
77914
78069
  }
77915
78070
  var commandPalette = null;
77916
78071
  var chordMode = "none";
78072
+ function cycleThinkingLevel() {
78073
+ const levels = ["low", "medium", "high", "off"];
78074
+ const currentIndex = levels.indexOf(config2.thinkingLevel);
78075
+ const nextIndex = (currentIndex + 1) % levels.length;
78076
+ config2.thinkingLevel = levels[nextIndex];
78077
+ saveConfig(config2);
78078
+ statusBarText.content = getStatusBarContent();
78079
+ addSystemMessage(`Thinking level: ${config2.thinkingLevel}`);
78080
+ }
77917
78081
  function getCommandPaletteOptions() {
77918
78082
  return [
77919
78083
  {
@@ -77968,6 +78132,13 @@ function getCommandPaletteOptions() {
77968
78132
  addSystemMessage(`Safety level: ${config2.safetyLevel} (${descriptions[config2.safetyLevel]})`);
77969
78133
  }
77970
78134
  },
78135
+ {
78136
+ name: "Cycle Thinking Level",
78137
+ description: `Current: ${config2.thinkingLevel}`,
78138
+ key: "k",
78139
+ chord: "k",
78140
+ action: () => cycleThinkingLevel()
78141
+ },
77971
78142
  {
77972
78143
  name: "Toggle Project Context",
77973
78144
  description: config2.repoContext ? "Currently ON (sends script names to AI)" : "Currently OFF",
@@ -78104,6 +78275,10 @@ function handleKeypress(key) {
78104
78275
  addSystemMessage(`Safety level: ${config2.safetyLevel} (${descriptions[config2.safetyLevel]})`);
78105
78276
  return;
78106
78277
  }
78278
+ if (key.ctrl && key.name === "k") {
78279
+ cycleThinkingLevel();
78280
+ return;
78281
+ }
78107
78282
  if (key.ctrl && key.name === "z") {
78108
78283
  renderer.destroy();
78109
78284
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@austinthesing/magic-shell",
3
- "version": "0.2.19",
3
+ "version": "0.2.20",
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",