scream-code 0.7.9 → 0.7.10

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.
@@ -121994,7 +121994,7 @@ function optionalBuildString(value) {
121994
121994
  return typeof value === "string" && value.length > 0 ? value : void 0;
121995
121995
  }
121996
121996
  const SCREAM_BUILD_INFO = {
121997
- version: optionalBuildString("0.7.9"),
121997
+ version: optionalBuildString("0.7.10"),
121998
121998
  channel: optionalBuildString(""),
121999
121999
  commit: optionalBuildString(""),
122000
122000
  buildTarget: optionalBuildString("darwin-arm64")
@@ -123818,13 +123818,17 @@ function effectiveThinkingLevel(model, thinkingDraft) {
123818
123818
  function modelHasImageIn(model) {
123819
123819
  return model.capabilities?.includes("image_in") === true;
123820
123820
  }
123821
+ function modelHasVideoIn(model) {
123822
+ return model.capabilities?.includes("video_in") === true;
123823
+ }
123824
+ function modelHasAudioIn(model) {
123825
+ return model.capabilities?.includes("audio_in") === true;
123826
+ }
123821
123827
  var ModelSelectorComponent = class extends Container {
123822
123828
  focused = false;
123823
123829
  opts;
123824
123830
  list;
123825
123831
  thinkingDraft;
123826
- imageDraft;
123827
- lastSelectedAlias;
123828
123832
  constructor(opts) {
123829
123833
  super();
123830
123834
  this.opts = opts;
@@ -123840,8 +123844,6 @@ var ModelSelectorComponent = class extends Container {
123840
123844
  });
123841
123845
  const initialChoice = choices[selectedIdx];
123842
123846
  this.thinkingDraft = initialChoice !== void 0 ? effectiveThinkingLevel(initialChoice.model, opts.currentThinkingLevel) : opts.currentThinkingLevel;
123843
- this.imageDraft = initialChoice !== void 0 ? modelHasImageIn(initialChoice.model) : false;
123844
- this.lastSelectedAlias = initialChoice?.alias;
123845
123847
  }
123846
123848
  handleInput(data) {
123847
123849
  if (matchesKey(data, Key.escape)) {
@@ -123850,34 +123852,27 @@ var ModelSelectorComponent = class extends Container {
123850
123852
  return;
123851
123853
  }
123852
123854
  const selected = this.list.selected();
123853
- if (selected !== void 0 && selected.alias !== this.lastSelectedAlias) {
123854
- this.imageDraft = modelHasImageIn(selected.model);
123855
- this.lastSelectedAlias = selected.alias;
123856
- }
123857
123855
  if (selected !== void 0 && thinkingAvailability(selected.model) !== "unsupported") {
123858
123856
  const levels = getThinkingLevels(selected.model);
123859
123857
  const idx = levels.indexOf(this.thinkingDraft);
123860
123858
  if (matchesKey(data, Key.left)) {
123861
123859
  const nextIdx = idx <= 0 ? levels.length - 1 : idx - 1;
123862
123860
  this.thinkingDraft = levels[nextIdx];
123861
+ this.opts.onChangeThinking?.(selected.alias, this.thinkingDraft);
123863
123862
  return;
123864
123863
  }
123865
123864
  if (matchesKey(data, Key.right)) {
123866
123865
  const nextIdx = idx === -1 || idx >= levels.length - 1 ? 0 : idx + 1;
123867
123866
  this.thinkingDraft = levels[nextIdx];
123867
+ this.opts.onChangeThinking?.(selected.alias, this.thinkingDraft);
123868
123868
  return;
123869
123869
  }
123870
123870
  }
123871
- if (selected !== void 0 && !modelHasImageIn(selected.model) && matchesKey(data, Key.space)) {
123872
- this.imageDraft = !this.imageDraft;
123873
- return;
123874
- }
123875
123871
  if (matchesKey(data, Key.enter)) {
123876
123872
  if (selected === void 0) return;
123877
123873
  this.opts.onSelect({
123878
123874
  alias: selected.alias,
123879
- thinkingLevel: effectiveThinkingLevel(selected.model, this.thinkingDraft),
123880
- imageEnabled: this.imageDraft
123875
+ thinkingLevel: effectiveThinkingLevel(selected.model, this.thinkingDraft)
123881
123876
  });
123882
123877
  return;
123883
123878
  }
@@ -123888,13 +123883,9 @@ var ModelSelectorComponent = class extends Container {
123888
123883
  const searchable = this.opts.searchable === true;
123889
123884
  const view = this.list.view();
123890
123885
  const choices = view.items;
123891
- const navParts = [
123892
- "↑↓ 模型",
123893
- "←→ 思考等级",
123894
- "Space(空格) vision识图"
123895
- ];
123886
+ const navParts = ["↑↓ 模型", "←→ 思考等级"];
123896
123887
  if (view.page.pageCount > 1) navParts.push("PgUp/PgDn 翻页");
123897
- navParts.push("Enter 应用", "Esc 取消");
123888
+ navParts.push("Enter 切换模型", "Esc 取消");
123898
123889
  const titleSuffix = searchable && view.query.length === 0 ? chalk.hex(colors.textMuted)(" (输入搜索)") : "";
123899
123890
  const lines = [chalk.hex(colors.primary)("─".repeat(width)), chalk.hex(colors.primary).bold(" 选择模型") + titleSuffix];
123900
123891
  if (searchable && view.query.length > 0) lines.push(chalk.hex(colors.primary)(" 搜索:") + chalk.hex(colors.text)(view.query));
@@ -123913,12 +123904,16 @@ var ModelSelectorComponent = class extends Container {
123913
123904
  lines.push(line);
123914
123905
  }
123915
123906
  lines.push("");
123916
- lines.push(chalk.hex(colors.textMuted)(" Thinking"));
123907
+ lines.push(chalk.hex(colors.textMuted)(" Thinking(全局设置)"));
123917
123908
  const selected = choices[view.selectedIndex];
123918
123909
  if (selected !== void 0) lines.push(this.renderThinkingControl(selected.model));
123919
123910
  lines.push("");
123920
- lines.push(chalk.hex(colors.textMuted)(" Vision 识图"));
123921
- if (selected !== void 0) lines.push(this.renderImageControl(selected.model));
123911
+ lines.push(chalk.hex(colors.textMuted)(" 多模态能力"));
123912
+ if (selected !== void 0) {
123913
+ lines.push(this.renderImageControl(selected.model));
123914
+ lines.push(this.renderVideoControl(selected.model));
123915
+ lines.push(this.renderAudioControl(selected.model));
123916
+ }
123922
123917
  lines.push("");
123923
123918
  if (view.page.pageCount > 1) lines.push(chalk.hex(colors.textMuted)(` Page ${String(view.page.page + 1)}/${String(view.page.pageCount)}`));
123924
123919
  lines.push(chalk.hex(colors.primary)("─".repeat(width)));
@@ -123937,8 +123932,18 @@ var ModelSelectorComponent = class extends Container {
123937
123932
  }
123938
123933
  renderImageControl(model) {
123939
123934
  const { colors } = this.opts;
123940
- if (modelHasImageIn(model)) return ` ${chalk.hex(colors.success).bold("✓ 默认开启")}${chalk.hex(colors.textMuted)(" (catalog)")}`;
123941
- return ` ${this.imageDraft ? chalk.hex(colors.success).bold("✓ 开启") : chalk.hex(colors.textDim)("✗ 关闭")}${this.imageDraft ? chalk.hex(colors.textMuted)(" (手动开启)") : ""}`;
123935
+ if (modelHasImageIn(model)) return ` ${chalk.hex(colors.textMuted)("识图")}: ${chalk.hex(colors.success).bold(" 支持")}`;
123936
+ return ` ${chalk.hex(colors.textMuted)("识图")}: ${chalk.hex(colors.textDim)("✗ 不支持")}`;
123937
+ }
123938
+ renderVideoControl(model) {
123939
+ const { colors } = this.opts;
123940
+ if (modelHasVideoIn(model)) return ` ${chalk.hex(colors.textMuted)("视频")}: ${chalk.hex(colors.success).bold("✓ 支持")}`;
123941
+ return ` ${chalk.hex(colors.textMuted)("视频")}: ${chalk.hex(colors.textDim)("✗ 不支持")}`;
123942
+ }
123943
+ renderAudioControl(model) {
123944
+ const { colors } = this.opts;
123945
+ if (modelHasAudioIn(model)) return ` ${chalk.hex(colors.textMuted)("音频")}: ${chalk.hex(colors.success).bold("✓ 支持")}`;
123946
+ return ` ${chalk.hex(colors.textMuted)("音频")}: ${chalk.hex(colors.textDim)("✗ 不支持")}`;
123942
123947
  }
123943
123948
  };
123944
123949
  //#endregion
@@ -124152,6 +124157,33 @@ const THINKING_OPTIONS = [
124152
124157
  label: "高强度思考"
124153
124158
  }
124154
124159
  ];
124160
+ const IMAGE_OPTIONS = [{
124161
+ value: "off",
124162
+ label: "关闭识图",
124163
+ description: "模型不支持图片输入时请选择此项"
124164
+ }, {
124165
+ value: "on",
124166
+ label: "开启识图",
124167
+ description: "模型支持图片输入时开启,允许发送图片"
124168
+ }];
124169
+ const VIDEO_OPTIONS = [{
124170
+ value: "off",
124171
+ label: "关闭视频",
124172
+ description: "模型不支持视频输入时请选择此项"
124173
+ }, {
124174
+ value: "on",
124175
+ label: "开启视频",
124176
+ description: "模型支持视频输入时开启,允许发送视频"
124177
+ }];
124178
+ const AUDIO_OPTIONS = [{
124179
+ value: "off",
124180
+ label: "关闭音频",
124181
+ description: "模型不支持音频输入时请选择此项"
124182
+ }, {
124183
+ value: "on",
124184
+ label: "开启音频",
124185
+ description: "模型支持音频输入时开启,允许发送音频"
124186
+ }];
124155
124187
  function promptWireType(host) {
124156
124188
  return new Promise((resolve) => {
124157
124189
  const picker = new ChoicePickerComponent({
@@ -124205,6 +124237,63 @@ function promptThinkingMode(host) {
124205
124237
  host.mountEditorReplacement(picker);
124206
124238
  });
124207
124239
  }
124240
+ function promptImageMode(host) {
124241
+ return new Promise((resolve) => {
124242
+ const picker = new ChoicePickerComponent({
124243
+ title: "多模态配置 · 图片输入",
124244
+ hint: "模型不支持请选择关闭",
124245
+ options: IMAGE_OPTIONS,
124246
+ colors: host.state.theme.colors,
124247
+ onSelect: (value) => {
124248
+ host.restoreEditor();
124249
+ resolve(value === "on");
124250
+ },
124251
+ onCancel: () => {
124252
+ host.restoreEditor();
124253
+ resolve(void 0);
124254
+ }
124255
+ });
124256
+ host.mountEditorReplacement(picker);
124257
+ });
124258
+ }
124259
+ function promptVideoMode(host) {
124260
+ return new Promise((resolve) => {
124261
+ const picker = new ChoicePickerComponent({
124262
+ title: "多模态配置 · 视频输入",
124263
+ hint: "模型不支持请选择关闭",
124264
+ options: VIDEO_OPTIONS,
124265
+ colors: host.state.theme.colors,
124266
+ onSelect: (value) => {
124267
+ host.restoreEditor();
124268
+ resolve(value === "on");
124269
+ },
124270
+ onCancel: () => {
124271
+ host.restoreEditor();
124272
+ resolve(void 0);
124273
+ }
124274
+ });
124275
+ host.mountEditorReplacement(picker);
124276
+ });
124277
+ }
124278
+ function promptAudioMode(host) {
124279
+ return new Promise((resolve) => {
124280
+ const picker = new ChoicePickerComponent({
124281
+ title: "多模态配置 · 音频输入",
124282
+ hint: "模型不支持请选择关闭",
124283
+ options: AUDIO_OPTIONS,
124284
+ colors: host.state.theme.colors,
124285
+ onSelect: (value) => {
124286
+ host.restoreEditor();
124287
+ resolve(value === "on");
124288
+ },
124289
+ onCancel: () => {
124290
+ host.restoreEditor();
124291
+ resolve(void 0);
124292
+ }
124293
+ });
124294
+ host.mountEditorReplacement(picker);
124295
+ });
124296
+ }
124208
124297
  //#endregion
124209
124298
  //#region src/tui/commands/auth.ts
124210
124299
  async function handleConnectCommand(host, args) {
@@ -124347,15 +124436,21 @@ async function handleDiyConfig(host) {
124347
124436
  const maxContextTokens = parseInt(maxContextStr, 10) || 131072;
124348
124437
  const thinkingLevel = await promptThinkingMode(host);
124349
124438
  if (thinkingLevel === void 0) return;
124439
+ const imageEnabled = await promptImageMode(host);
124440
+ if (imageEnabled === void 0) return;
124441
+ const videoEnabled = await promptVideoMode(host);
124442
+ if (videoEnabled === void 0) return;
124443
+ const audioEnabled = await promptAudioMode(host);
124444
+ if (audioEnabled === void 0) return;
124350
124445
  const providerId = `custom-${modelId.replaceAll(/[^A-Za-z0-9._-]/g, "-")}`;
124351
124446
  const catalogModel = {
124352
124447
  id: modelId,
124353
124448
  name: modelId,
124354
124449
  capability: {
124355
124450
  max_context_tokens: maxContextTokens,
124356
- image_in: false,
124357
- video_in: false,
124358
- audio_in: false,
124451
+ image_in: imageEnabled,
124452
+ video_in: videoEnabled,
124453
+ audio_in: audioEnabled,
124359
124454
  thinking: thinkingLevel !== "off",
124360
124455
  tool_use: true
124361
124456
  },
@@ -125653,24 +125748,82 @@ function showModelPicker(host, selectedValue = host.state.appState.model) {
125653
125748
  currentThinkingLevel: host.state.appState.thinkingLevel,
125654
125749
  colors: host.state.theme.colors,
125655
125750
  searchable: true,
125656
- onSelect: ({ alias, thinkingLevel, imageEnabled }) => {
125751
+ onSelect: ({ alias, thinkingLevel }) => {
125657
125752
  host.restoreEditor();
125658
- performModelSwitch(host, alias, thinkingLevel, imageEnabled);
125753
+ performModelSwitch(host, alias, thinkingLevel);
125754
+ },
125755
+ onChangeThinking: (alias, level) => {
125756
+ changeThinkingLevel(host, alias, level);
125659
125757
  },
125660
125758
  onCancel: () => {
125661
125759
  host.restoreEditor();
125662
125760
  }
125663
125761
  }));
125664
125762
  }
125665
- async function performModelSwitch(host, alias, thinkingLevel, imageEnabled) {
125763
+ /**
125764
+ * Apply a thinking-level change immediately (←/→ keys in the model selector).
125765
+ * Decoupled from performModelSwitch so the user can cycle thinking on the
125766
+ * currently-selected model without pressing Enter. If the alias is the active
125767
+ * model, the running session is updated too; otherwise only the default is
125768
+ * persisted.
125769
+ */
125770
+ async function changeThinkingLevel(host, alias, level) {
125771
+ if (isBusy(host.state.appState)) {
125772
+ host.showError("Cannot change thinking while streaming — press Esc or Ctrl-C first.");
125773
+ return;
125774
+ }
125775
+ const prevLevel = host.state.appState.thinkingLevel;
125776
+ const isActiveModel = alias === host.state.appState.model;
125777
+ if (isActiveModel && level !== prevLevel) {
125778
+ const session = host.session;
125779
+ try {
125780
+ if (session === void 0) await host.authFlow.activateModelAfterLogin(alias, level);
125781
+ else await session.setThinking(level);
125782
+ } catch (error) {
125783
+ const msg = formatErrorMessage(error);
125784
+ host.showError(`Failed to set thinking: ${msg}`);
125785
+ return;
125786
+ }
125787
+ host.setAppState({ thinkingLevel: level });
125788
+ }
125789
+ let persisted = false;
125790
+ try {
125791
+ persisted = await persistThinkingDefault(host, alias, level);
125792
+ } catch (error) {
125793
+ const msg = formatErrorMessage(error);
125794
+ host.showError(`Failed to save thinking default: ${msg}`);
125795
+ return;
125796
+ }
125797
+ const status = isActiveModel && level !== prevLevel ? `Thinking set to ${level} for ${alias}.` : persisted ? `Saved thinking ${level} as default for ${alias}.` : `Thinking already ${level} for ${alias}.`;
125798
+ host.showStatus(status, host.state.theme.colors.success);
125799
+ }
125800
+ async function persistThinkingDefault(host, alias, level) {
125801
+ const config = await host.harness.getConfig({ reload: true });
125802
+ const effectiveThinking = level !== "off";
125803
+ const existingEffort = config.thinking?.effort;
125804
+ const newEffort = effectiveThinking ? level : existingEffort;
125805
+ if (!(config.defaultModel === alias)) return false;
125806
+ if (config.defaultThinking === effectiveThinking && existingEffort === newEffort) return false;
125807
+ await host.harness.setConfig({
125808
+ defaultThinking: effectiveThinking,
125809
+ thinking: {
125810
+ ...config.thinking,
125811
+ mode: effectiveThinking ? "on" : "off",
125812
+ effort: newEffort
125813
+ }
125814
+ });
125815
+ return true;
125816
+ }
125817
+ async function performModelSwitch(host, alias, thinkingLevel) {
125666
125818
  if (isBusy(host.state.appState)) {
125667
125819
  host.showError("Cannot switch models while streaming — press Esc or Ctrl-C first.");
125668
125820
  return;
125669
125821
  }
125670
125822
  const prevModel = host.state.appState.model;
125671
125823
  const prevThinkingLevel = host.state.appState.thinkingLevel;
125672
- const prevImageEnabled = host.state.appState.availableModels[alias]?.capabilities?.includes("image_in") === true;
125673
- const runtimeChanged = alias !== prevModel || thinkingLevel !== prevThinkingLevel || imageEnabled !== prevImageEnabled;
125824
+ const modelChanged = alias !== prevModel;
125825
+ const thinkingChanged = thinkingLevel !== prevThinkingLevel;
125826
+ const needsSessionActivation = modelChanged || thinkingChanged;
125674
125827
  const overflow = alias !== prevModel ? contextOverflowForModel(host.state.appState, alias) : null;
125675
125828
  if (overflow !== null) {
125676
125829
  host.showNotice("Storm Breaker(风暴守护者)", `无法切换到模型「${alias}」:当前会话上下文 ${formatTokenCount$1(overflow.currentTokens)} 已超出该模型上限 ${formatTokenCount$1(overflow.maxContextTokens)}。建议先执行 /compact 压缩上下文,或选择上下文窗口更大的模型。`);
@@ -125678,10 +125831,10 @@ async function performModelSwitch(host, alias, thinkingLevel, imageEnabled) {
125678
125831
  }
125679
125832
  const session = host.session;
125680
125833
  try {
125681
- if (session === void 0 && runtimeChanged) await host.authFlow.activateModelAfterLogin(alias, thinkingLevel);
125834
+ if (session === void 0 && needsSessionActivation) await host.authFlow.activateModelAfterLogin(alias, thinkingLevel);
125682
125835
  else if (session !== void 0) {
125683
- if (alias !== prevModel) await session.setModel(alias);
125684
- if (thinkingLevel !== prevThinkingLevel) await session.setThinking(thinkingLevel);
125836
+ if (modelChanged) await session.setModel(alias);
125837
+ if (thinkingChanged) await session.setThinking(thinkingLevel);
125685
125838
  }
125686
125839
  } catch (error) {
125687
125840
  const msg = formatErrorMessage(error);
@@ -125694,38 +125847,26 @@ async function performModelSwitch(host, alias, thinkingLevel, imageEnabled) {
125694
125847
  });
125695
125848
  let persisted = false;
125696
125849
  try {
125697
- persisted = await persistModelSelection(host, alias, thinkingLevel, imageEnabled);
125850
+ persisted = await persistModelSelection(host, alias, thinkingLevel);
125698
125851
  } catch (error) {
125699
125852
  const msg = formatErrorMessage(error);
125700
125853
  host.showError(`Switched to ${alias}, but failed to save default: ${msg}`);
125701
125854
  return;
125702
125855
  }
125703
- if (persisted) {
125704
- const prevAlias = host.state.appState.availableModels[alias];
125705
- if (prevAlias !== void 0) {
125706
- const nextCaps = computeCapabilities(prevAlias.capabilities, imageEnabled);
125707
- host.setAppState({ availableModels: {
125708
- ...host.state.appState.availableModels,
125709
- [alias]: {
125710
- ...prevAlias,
125711
- capabilities: nextCaps
125712
- }
125713
- } });
125714
- }
125715
- }
125716
- const status = runtimeChanged ? `Switched to ${alias} with thinking ${thinkingLevel}.` : persisted ? `Saved ${alias} with thinking ${thinkingLevel} as default.` : `Already using ${alias} with thinking ${thinkingLevel}.`;
125856
+ const status = (() => {
125857
+ if (modelChanged) return `Switched to ${alias} with thinking ${thinkingLevel}.`;
125858
+ if (thinkingChanged) return `Thinking set to ${thinkingLevel} for ${alias}.`;
125859
+ if (persisted) return `Saved ${alias} with thinking ${thinkingLevel} as default.`;
125860
+ return `Already using ${alias} with thinking ${thinkingLevel}.`;
125861
+ })();
125717
125862
  host.showStatus(status, host.state.theme.colors.success);
125718
125863
  }
125719
- async function persistModelSelection(host, alias, thinkingLevel, imageEnabled) {
125864
+ async function persistModelSelection(host, alias, thinkingLevel) {
125720
125865
  const config = await host.harness.getConfig({ reload: true });
125721
125866
  const effectiveThinking = thinkingLevel !== "off";
125722
125867
  const existingEffort = config.thinking?.effort;
125723
125868
  const newEffort = effectiveThinking ? thinkingLevel : existingEffort;
125724
- const aliasCfg = config.models?.[alias];
125725
- const prevCaps = aliasCfg?.capabilities;
125726
- const nextCaps = computeCapabilities(prevCaps, imageEnabled);
125727
- const capsChanged = prevCaps?.includes("image_in") === true !== imageEnabled;
125728
- if (config.defaultModel === alias && config.defaultThinking === effectiveThinking && existingEffort === newEffort && !capsChanged) return false;
125869
+ if (config.defaultModel === alias && config.defaultThinking === effectiveThinking && existingEffort === newEffort) return false;
125729
125870
  await host.harness.setConfig({
125730
125871
  defaultModel: alias,
125731
125872
  defaultThinking: effectiveThinking,
@@ -125733,28 +125874,10 @@ async function persistModelSelection(host, alias, thinkingLevel, imageEnabled) {
125733
125874
  ...config.thinking,
125734
125875
  mode: effectiveThinking ? "on" : "off",
125735
125876
  effort: newEffort
125736
- },
125737
- models: capsChanged && aliasCfg !== void 0 ? { [alias]: {
125738
- ...aliasCfg,
125739
- capabilities: nextCaps
125740
- } } : void 0
125877
+ }
125741
125878
  });
125742
125879
  return true;
125743
125880
  }
125744
- /**
125745
- * Returns the new capabilities array after toggling 'image_in'. Returns
125746
- * `undefined` when the result would be empty, so legacy aliases without a
125747
- * capabilities declaration stay clean (no `capabilities = []` in toml).
125748
- */
125749
- function computeCapabilities(prev, imageEnabled) {
125750
- if (imageEnabled) {
125751
- if (prev === void 0) return ["image_in"];
125752
- return prev.includes("image_in") ? [...prev] : [...prev, "image_in"];
125753
- }
125754
- if (prev === void 0) return void 0;
125755
- const filtered = prev.filter((c) => c !== "image_in");
125756
- return filtered.length === 0 ? void 0 : filtered;
125757
- }
125758
125881
  function showThemePicker(host) {
125759
125882
  host.mountEditorReplacement(new ThemeSelectorComponent({
125760
125883
  currentValue: host.state.appState.theme,
package/dist/main.mjs CHANGED
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
6
6
  import "./suppress-sqlite-warning-C2VB0doZ.mjs";
7
7
  //#region src/main.ts
8
8
  try {
9
- (await import("./app-DxQ8R4AP.mjs")).main();
9
+ (await import("./app-BJoewl4C.mjs")).main();
10
10
  } catch (error) {
11
11
  process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
12
12
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scream-code",
3
- "version": "0.7.9",
3
+ "version": "0.7.10",
4
4
  "description": "A terminal-native AI agent for builders",
5
5
  "license": "MIT",
6
6
  "author": "ScreamCli",