snow-ai 0.6.15 → 0.6.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundle/cli.mjs CHANGED
@@ -46553,13 +46553,17 @@ var init_help = __esm({
46553
46553
  // dist/utils/config/codebaseConfig.js
46554
46554
  var codebaseConfig_exports = {};
46555
46555
  __export(codebaseConfig_exports, {
46556
+ disableCodebase: () => disableCodebase,
46557
+ enableCodebase: () => enableCodebase,
46558
+ isCodebaseEnabled: () => isCodebaseEnabled,
46556
46559
  loadCodebaseConfig: () => loadCodebaseConfig,
46557
- saveCodebaseConfig: () => saveCodebaseConfig
46560
+ saveCodebaseConfig: () => saveCodebaseConfig,
46561
+ toggleCodebaseEnabled: () => toggleCodebaseEnabled
46558
46562
  });
46559
46563
  import fs7 from "fs";
46560
46564
  import path7 from "path";
46561
46565
  import os3 from "os";
46562
- var DEFAULT_CONFIG, getConfigDir, getConfigPath, loadCodebaseConfig, saveCodebaseConfig;
46566
+ var DEFAULT_CONFIG, getGlobalConfigDir, getProjectConfigDir, getProjectConfigPath, getGlobalConfigPath, loadGlobalEmbeddingConfig, loadCodebaseConfig, saveCodebaseConfig, isCodebaseEnabled, toggleCodebaseEnabled, enableCodebase, disableCodebase;
46563
46567
  var init_codebaseConfig = __esm({
46564
46568
  "dist/utils/config/codebaseConfig.js"() {
46565
46569
  "use strict";
@@ -46585,7 +46589,7 @@ var init_codebaseConfig = __esm({
46585
46589
  overlapLines: 20
46586
46590
  }
46587
46591
  };
46588
- getConfigDir = () => {
46592
+ getGlobalConfigDir = () => {
46589
46593
  const homeDir = os3.homedir();
46590
46594
  const configDir = path7.join(homeDir, ".snow");
46591
46595
  if (!fs7.existsSync(configDir)) {
@@ -46593,37 +46597,63 @@ var init_codebaseConfig = __esm({
46593
46597
  }
46594
46598
  return configDir;
46595
46599
  };
46596
- getConfigPath = () => {
46597
- return path7.join(getConfigDir(), "codebase.json");
46600
+ getProjectConfigDir = (workingDirectory) => {
46601
+ const baseDir = workingDirectory || process.cwd();
46602
+ const configDir = path7.join(baseDir, ".snow");
46603
+ if (!fs7.existsSync(configDir)) {
46604
+ fs7.mkdirSync(configDir, { recursive: true });
46605
+ }
46606
+ return configDir;
46607
+ };
46608
+ getProjectConfigPath = (workingDirectory) => {
46609
+ return path7.join(getProjectConfigDir(workingDirectory), "codebase.json");
46610
+ };
46611
+ getGlobalConfigPath = () => {
46612
+ return path7.join(getGlobalConfigDir(), "codebase.json");
46598
46613
  };
46599
- loadCodebaseConfig = () => {
46600
- var _a21, _b14, _c6, _d4, _e2, _f, _g, _h, _i, _j, _k;
46614
+ loadGlobalEmbeddingConfig = () => {
46615
+ var _a21, _b14, _c6, _d4, _e2;
46601
46616
  try {
46602
- const configPath = getConfigPath();
46617
+ const configPath = getGlobalConfigPath();
46603
46618
  if (!fs7.existsSync(configPath)) {
46604
- return { ...DEFAULT_CONFIG };
46619
+ return { ...DEFAULT_CONFIG.embedding };
46605
46620
  }
46606
46621
  const configContent = fs7.readFileSync(configPath, "utf-8");
46607
46622
  const config3 = JSON.parse(configContent);
46608
46623
  return {
46609
- enabled: config3.enabled ?? DEFAULT_CONFIG.enabled,
46610
- enableAgentReview: config3.enableAgentReview ?? DEFAULT_CONFIG.enableAgentReview,
46611
- embedding: {
46612
- type: ((_a21 = config3.embedding) == null ? void 0 : _a21.type) ?? DEFAULT_CONFIG.embedding.type,
46613
- modelName: ((_b14 = config3.embedding) == null ? void 0 : _b14.modelName) ?? DEFAULT_CONFIG.embedding.modelName,
46614
- baseUrl: ((_c6 = config3.embedding) == null ? void 0 : _c6.baseUrl) ?? DEFAULT_CONFIG.embedding.baseUrl,
46615
- apiKey: ((_d4 = config3.embedding) == null ? void 0 : _d4.apiKey) ?? DEFAULT_CONFIG.embedding.apiKey,
46616
- dimensions: ((_e2 = config3.embedding) == null ? void 0 : _e2.dimensions) ?? DEFAULT_CONFIG.embedding.dimensions
46617
- },
46624
+ type: ((_a21 = config3.embedding) == null ? void 0 : _a21.type) ?? DEFAULT_CONFIG.embedding.type,
46625
+ modelName: ((_b14 = config3.embedding) == null ? void 0 : _b14.modelName) ?? DEFAULT_CONFIG.embedding.modelName,
46626
+ baseUrl: ((_c6 = config3.embedding) == null ? void 0 : _c6.baseUrl) ?? DEFAULT_CONFIG.embedding.baseUrl,
46627
+ apiKey: ((_d4 = config3.embedding) == null ? void 0 : _d4.apiKey) ?? DEFAULT_CONFIG.embedding.apiKey,
46628
+ dimensions: ((_e2 = config3.embedding) == null ? void 0 : _e2.dimensions) ?? DEFAULT_CONFIG.embedding.dimensions
46629
+ };
46630
+ } catch {
46631
+ return { ...DEFAULT_CONFIG.embedding };
46632
+ }
46633
+ };
46634
+ loadCodebaseConfig = (workingDirectory) => {
46635
+ var _a21, _b14, _c6, _d4, _e2, _f;
46636
+ try {
46637
+ const projectConfigPath = getProjectConfigPath(workingDirectory);
46638
+ const globalEmbedding = loadGlobalEmbeddingConfig();
46639
+ let projectConfig = {};
46640
+ if (fs7.existsSync(projectConfigPath)) {
46641
+ const configContent = fs7.readFileSync(projectConfigPath, "utf-8");
46642
+ projectConfig = JSON.parse(configContent);
46643
+ }
46644
+ return {
46645
+ enabled: projectConfig.enabled ?? DEFAULT_CONFIG.enabled,
46646
+ enableAgentReview: projectConfig.enableAgentReview ?? DEFAULT_CONFIG.enableAgentReview,
46647
+ embedding: globalEmbedding,
46618
46648
  batch: {
46619
- maxLines: ((_f = config3.batch) == null ? void 0 : _f.maxLines) ?? DEFAULT_CONFIG.batch.maxLines,
46620
- concurrency: ((_g = config3.batch) == null ? void 0 : _g.concurrency) ?? DEFAULT_CONFIG.batch.concurrency
46649
+ maxLines: ((_a21 = projectConfig.batch) == null ? void 0 : _a21.maxLines) ?? DEFAULT_CONFIG.batch.maxLines,
46650
+ concurrency: ((_b14 = projectConfig.batch) == null ? void 0 : _b14.concurrency) ?? DEFAULT_CONFIG.batch.concurrency
46621
46651
  },
46622
46652
  chunking: {
46623
- maxLinesPerChunk: ((_h = config3.chunking) == null ? void 0 : _h.maxLinesPerChunk) ?? DEFAULT_CONFIG.chunking.maxLinesPerChunk,
46624
- minLinesPerChunk: ((_i = config3.chunking) == null ? void 0 : _i.minLinesPerChunk) ?? DEFAULT_CONFIG.chunking.minLinesPerChunk,
46625
- minCharsPerChunk: ((_j = config3.chunking) == null ? void 0 : _j.minCharsPerChunk) ?? DEFAULT_CONFIG.chunking.minCharsPerChunk,
46626
- overlapLines: ((_k = config3.chunking) == null ? void 0 : _k.overlapLines) ?? DEFAULT_CONFIG.chunking.overlapLines
46653
+ maxLinesPerChunk: ((_c6 = projectConfig.chunking) == null ? void 0 : _c6.maxLinesPerChunk) ?? DEFAULT_CONFIG.chunking.maxLinesPerChunk,
46654
+ minLinesPerChunk: ((_d4 = projectConfig.chunking) == null ? void 0 : _d4.minLinesPerChunk) ?? DEFAULT_CONFIG.chunking.minLinesPerChunk,
46655
+ minCharsPerChunk: ((_e2 = projectConfig.chunking) == null ? void 0 : _e2.minCharsPerChunk) ?? DEFAULT_CONFIG.chunking.minCharsPerChunk,
46656
+ overlapLines: ((_f = projectConfig.chunking) == null ? void 0 : _f.overlapLines) ?? DEFAULT_CONFIG.chunking.overlapLines
46627
46657
  }
46628
46658
  };
46629
46659
  } catch (error) {
@@ -46631,15 +46661,44 @@ var init_codebaseConfig = __esm({
46631
46661
  return { ...DEFAULT_CONFIG };
46632
46662
  }
46633
46663
  };
46634
- saveCodebaseConfig = (config3) => {
46664
+ saveCodebaseConfig = (config3, workingDirectory) => {
46635
46665
  try {
46636
- const configPath = getConfigPath();
46637
- fs7.writeFileSync(configPath, JSON.stringify(config3, null, 2), "utf-8");
46666
+ const globalConfigPath = getGlobalConfigPath();
46667
+ const globalConfig = { embedding: config3.embedding };
46668
+ fs7.writeFileSync(globalConfigPath, JSON.stringify(globalConfig, null, 2), "utf-8");
46669
+ const projectConfigPath = getProjectConfigPath(workingDirectory);
46670
+ const projectConfig = {
46671
+ enabled: config3.enabled,
46672
+ enableAgentReview: config3.enableAgentReview,
46673
+ batch: config3.batch,
46674
+ chunking: config3.chunking
46675
+ };
46676
+ fs7.writeFileSync(projectConfigPath, JSON.stringify(projectConfig, null, 2), "utf-8");
46638
46677
  } catch (error) {
46639
46678
  console.error("Failed to save codebase config:", error);
46640
46679
  throw error;
46641
46680
  }
46642
46681
  };
46682
+ isCodebaseEnabled = (workingDirectory) => {
46683
+ const config3 = loadCodebaseConfig(workingDirectory);
46684
+ return config3.enabled;
46685
+ };
46686
+ toggleCodebaseEnabled = (workingDirectory) => {
46687
+ const config3 = loadCodebaseConfig(workingDirectory);
46688
+ config3.enabled = !config3.enabled;
46689
+ saveCodebaseConfig(config3, workingDirectory);
46690
+ return config3.enabled;
46691
+ };
46692
+ enableCodebase = (workingDirectory) => {
46693
+ const config3 = loadCodebaseConfig(workingDirectory);
46694
+ config3.enabled = true;
46695
+ saveCodebaseConfig(config3, workingDirectory);
46696
+ };
46697
+ disableCodebase = (workingDirectory) => {
46698
+ const config3 = loadCodebaseConfig(workingDirectory);
46699
+ config3.enabled = false;
46700
+ saveCodebaseConfig(config3, workingDirectory);
46701
+ };
46643
46702
  }
46644
46703
  });
46645
46704
 
@@ -46764,7 +46823,7 @@ function getSystemEnvironmentInfo(includePowerShellVersion = false) {
46764
46823
  Shell: ${shell}
46765
46824
  Working Directory: ${workingDirectory}`;
46766
46825
  }
46767
- function isCodebaseEnabled() {
46826
+ function isCodebaseEnabled2() {
46768
46827
  try {
46769
46828
  const config3 = loadCodebaseConfig();
46770
46829
  return config3.enabled;
@@ -46859,7 +46918,7 @@ function getAvailableToolsSection(hasCodebase) {
46859
46918
  function getVulnerabilityHuntingModeSystemPrompt() {
46860
46919
  const basePrompt = getSystemPromptWithRole(VULNERABILITY_HUNTING_MODE_SYSTEM_PROMPT, "You are Snow AI CLI");
46861
46920
  const systemEnv = getSystemEnvironmentInfo();
46862
- const hasCodebase = isCodebaseEnabled();
46921
+ const hasCodebase = isCodebaseEnabled2();
46863
46922
  const analysisToolsSection = getAnalysisToolsSection(hasCodebase);
46864
46923
  const availableToolsSection = getAvailableToolsSection(hasCodebase);
46865
46924
  const timeInfo = getCurrentTimeInfo();
@@ -47459,7 +47518,7 @@ function getAvailableToolsSection2(hasCodebase) {
47459
47518
  function getPlanModeSystemPrompt() {
47460
47519
  const basePrompt = getSystemPromptWithRole(PLAN_MODE_SYSTEM_PROMPT, "You are Snow AI CLI");
47461
47520
  const systemEnv = getSystemEnvironmentInfo();
47462
- const hasCodebase = isCodebaseEnabled();
47521
+ const hasCodebase = isCodebaseEnabled2();
47463
47522
  const analysisToolsSection = getAnalysisToolsSection2(hasCodebase);
47464
47523
  const availableToolsSection = getAvailableToolsSection2(hasCodebase);
47465
47524
  const timeInfo = getCurrentTimeInfo();
@@ -47941,7 +48000,7 @@ function getCodeSearchSection(hasCodebase) {
47941
48000
  function getSystemPrompt() {
47942
48001
  const basePrompt = getSystemPromptWithRole(SYSTEM_PROMPT_TEMPLATE, "You are Snow AI CLI, an intelligent command-line assistant.");
47943
48002
  const systemEnv = getSystemEnvironmentInfo(true);
47944
- const hasCodebase = isCodebaseEnabled();
48003
+ const hasCodebase = isCodebaseEnabled2();
47945
48004
  const workflowSection = getWorkflowSection(hasCodebase);
47946
48005
  const codeSearchSection = getCodeSearchSection(hasCodebase);
47947
48006
  const platformCommandsSection = getPlatformCommandsSection();
@@ -72208,13 +72267,16 @@ async function* createStreamingGeminiCompletion(options3, abortSignal, onRetry)
72208
72267
  const effectiveModel = options3.model || config3.advancedModel || "";
72209
72268
  const modelName = effectiveModel.startsWith("models/") ? effectiveModel : `models/${effectiveModel}`;
72210
72269
  const baseUrl = config3.baseUrl && config3.baseUrl !== "https://api.openai.com/v1" ? config3.baseUrl : "https://generativelanguage.googleapis.com/v1beta";
72211
- const url = `${baseUrl}/${modelName}:streamGenerateContent?key=${config3.apiKey}&alt=sse`;
72270
+ const urlObj = new URL(`${baseUrl}/${modelName}:streamGenerateContent`);
72271
+ urlObj.searchParams.set("alt", "sse");
72272
+ const url = urlObj.toString();
72212
72273
  const customHeaders = options3.customHeaders || getCustomHeadersForConfig(config3);
72213
72274
  const fetchOptions = addProxyToFetchOptions(url, {
72214
72275
  method: "POST",
72215
72276
  headers: {
72216
72277
  "Content-Type": "application/json",
72217
72278
  Authorization: `Bearer ${config3.apiKey}`,
72279
+ "x-goog-api-key": config3.apiKey,
72218
72280
  "x-snow": getVersionHeader(),
72219
72281
  ...customHeaders
72220
72282
  },
@@ -80899,6 +80961,8 @@ var init_en = __esm({
80899
80961
  activeProfile: "Active Profile:",
80900
80962
  settingsPosition: "Settings",
80901
80963
  scrollHint: "\xB7 \u2191\u2193 to scroll",
80964
+ moreAbove: "{count} more above",
80965
+ moreBelow: "{count} more below",
80902
80966
  profile: "Profile:",
80903
80967
  baseUrl: "Base URL:",
80904
80968
  apiKey: "API Key:",
@@ -81211,6 +81275,7 @@ var init_en = __esm({
81211
81275
  todo: "Search and select TODO comments from project files",
81212
81276
  addDir: "Add working directory for multi-project context. Usage: /add-dir or /add-dir path",
81213
81277
  reindex: "Rebuild codebase index. Use -force to delete existing database and rebuild from scratch",
81278
+ codebase: "Toggle codebase indexing for current project. Usage: /codebase [on|off|status]",
81214
81279
  permissions: "Manage always-approved tools permissions",
81215
81280
  backend: "Show background processes panel",
81216
81281
  profiles: "Switch configuration profiles",
@@ -81232,6 +81297,8 @@ var init_en = __esm({
81232
81297
  title: "Select Profile",
81233
81298
  scrollHint: "\u2191\u2193 to scroll",
81234
81299
  moreHidden: "{count} more hidden",
81300
+ moreAbove: "{count} more above",
81301
+ moreBelow: "{count} more below",
81235
81302
  escHint: "Press ESC to close",
81236
81303
  activeLabel: "(active)",
81237
81304
  searchLabel: "Search:",
@@ -81837,12 +81904,15 @@ var init_en = __esm({
81837
81904
  searchLabel: "Search:",
81838
81905
  searchPlaceholder: "Type to search",
81839
81906
  searching: "searching...",
81840
- navigationHint: "Type to search \u2022 \u2191\u2193 navigate \u2022 Space mark \u2022 D delete \u2022 Enter select \u2022 ESC close",
81907
+ navigationHint: "Type to search \u2022 \u2191\u2193 navigate \u2022 Space mark \u2022 D delete \u2022 R rename \u2022 Enter select \u2022 ESC close",
81841
81908
  moreAbove: "\u2191 {count} more above",
81842
81909
  moreBelow: "\u2193 {count} more below",
81843
81910
  scrollToLoadMore: "(scroll to load more)",
81844
81911
  untitled: "Untitled",
81845
- now: "now"
81912
+ now: "now",
81913
+ renamePrompt: "Rename Session",
81914
+ renaming: "Renaming...",
81915
+ renamePlaceholder: "Enter new title"
81846
81916
  },
81847
81917
  mcpInfoPanel: {
81848
81918
  title: "MCP Services",
@@ -82057,6 +82127,8 @@ var init_zh = __esm({
82057
82127
  activeProfile: "\u5F53\u524D\u914D\u7F6E:",
82058
82128
  settingsPosition: "\u8BBE\u7F6E",
82059
82129
  scrollHint: "\xB7 \u2191\u2193 \u6EDA\u52A8",
82130
+ moreAbove: "\u4E0A\u65B9\u8FD8\u6709 {count} \u9879",
82131
+ moreBelow: "\u4E0B\u65B9\u8FD8\u6709 {count} \u9879",
82060
82132
  profile: "\u914D\u7F6E\u6587\u4EF6:",
82061
82133
  baseUrl: "Base URL:",
82062
82134
  apiKey: "API \u5BC6\u94A5:",
@@ -82369,6 +82441,7 @@ var init_zh = __esm({
82369
82441
  todo: "\u4ECE\u9879\u76EE\u6587\u4EF6\u641C\u7D22\u5E76\u9009\u62E9 TODO \u6CE8\u91CA",
82370
82442
  addDir: "\u6DFB\u52A0\u5DE5\u4F5C\u76EE\u5F55\u4EE5\u652F\u6301\u591A\u9879\u76EE\u4E0A\u4E0B\u6587\u3002\u7528\u6CD5: /add-dir \u6216 /add-dir \u8DEF\u5F84",
82371
82443
  reindex: "\u91CD\u5EFA\u4EE3\u7801\u5E93\u7D22\u5F15\u3002\u4F7F\u7528 -force \u5220\u9664\u73B0\u6709\u6570\u636E\u5E93\u5E76\u5B8C\u5168\u91CD\u5EFA",
82444
+ codebase: "\u5207\u6362\u5F53\u524D\u9879\u76EE\u7684\u4EE3\u7801\u5E93\u7D22\u5F15\u529F\u80FD\u3002\u7528\u6CD5: /codebase [on|off|status]",
82372
82445
  permissions: "\u7BA1\u7406\u59CB\u7EC8\u6279\u51C6\u7684\u5DE5\u5177\u6743\u9650",
82373
82446
  vulnerabilityHunting: "\u5207\u6362\u6F0F\u6D1E\u68C0\u67E5\u6A21\u5F0F\uFF0C\u8FDB\u884C\u5B89\u5168\u6027\u4EE3\u7801\u5206\u6790",
82374
82447
  backend: "\u663E\u793A\u540E\u53F0\u8FDB\u7A0B\u9762\u677F",
@@ -82390,6 +82463,8 @@ var init_zh = __esm({
82390
82463
  title: "\u9009\u62E9\u914D\u7F6E",
82391
82464
  scrollHint: "\u2191\u2193 \u6EDA\u52A8",
82392
82465
  moreHidden: "\u9690\u85CF {count} \u4E2A",
82466
+ moreAbove: "\u4E0A\u65B9\u8FD8\u6709 {count} \u9879",
82467
+ moreBelow: "\u4E0B\u65B9\u8FD8\u6709 {count} \u9879",
82393
82468
  escHint: "\u6309 ESC \u5173\u95ED",
82394
82469
  activeLabel: "(\u5F53\u524D)",
82395
82470
  searchLabel: "\u641C\u7D22:",
@@ -82994,12 +83069,15 @@ var init_zh = __esm({
82994
83069
  searchLabel: "\u641C\u7D22:",
82995
83070
  searchPlaceholder: "\u8F93\u5165\u4EE5\u641C\u7D22",
82996
83071
  searching: "\u641C\u7D22\u4E2D...",
82997
- navigationHint: "\u8F93\u5165\u4EE5\u641C\u7D22 \u2022 \u2191\u2193 \u5BFC\u822A \u2022 \u7A7A\u683C \u6807\u8BB0 \u2022 D \u5220\u9664 \u2022 Enter \u9009\u62E9 \u2022 ESC \u5173\u95ED",
83072
+ navigationHint: "\u8F93\u5165\u4EE5\u641C\u7D22 \u2022 \u2191\u2193 \u5BFC\u822A \u2022 \u7A7A\u683C \u6807\u8BB0 \u2022 D \u5220\u9664 \u2022 R \u91CD\u547D\u540D \u2022 Enter \u9009\u62E9 \u2022 ESC \u5173\u95ED",
82998
83073
  moreAbove: "\u2191 \u4E0A\u65B9\u8FD8\u6709 {count} \u4E2A",
82999
83074
  moreBelow: "\u2193 \u4E0B\u65B9\u8FD8\u6709 {count} \u4E2A",
83000
83075
  scrollToLoadMore: "(\u6EDA\u52A8\u52A0\u8F7D\u66F4\u591A)",
83001
83076
  untitled: "\u65E0\u6807\u9898",
83002
- now: "\u73B0\u5728"
83077
+ now: "\u73B0\u5728",
83078
+ renamePrompt: "\u91CD\u547D\u540D\u4F1A\u8BDD",
83079
+ renaming: "\u91CD\u547D\u540D\u4E2D...",
83080
+ renamePlaceholder: "\u8F93\u5165\u65B0\u7684\u6807\u9898"
83003
83081
  },
83004
83082
  mcpInfoPanel: {
83005
83083
  title: "MCP \u670D\u52A1",
@@ -83214,6 +83292,8 @@ var init_zh_TW = __esm({
83214
83292
  activeProfile: "\u7576\u524D\u914D\u7F6E:",
83215
83293
  settingsPosition: "\u8A2D\u5B9A",
83216
83294
  scrollHint: "\xB7 \u2191\u2193 \u6372\u52D5",
83295
+ moreAbove: "\u4E0A\u65B9\u9084\u6709 {count} \u9805",
83296
+ moreBelow: "\u4E0B\u65B9\u9084\u6709 {count} \u9805",
83217
83297
  profile: "\u914D\u7F6E\u6A94\u6848:",
83218
83298
  baseUrl: "Base URL:",
83219
83299
  apiKey: "API \u91D1\u9470:",
@@ -83526,6 +83606,7 @@ var init_zh_TW = __esm({
83526
83606
  todo: "\u5F9E\u5C08\u6848\u6A94\u6848\u641C\u5C0B\u4E26\u9078\u64C7 TODO \u8A3B\u91CB",
83527
83607
  addDir: "\u65B0\u589E\u5DE5\u4F5C\u76EE\u9304\u4EE5\u652F\u63F4\u591A\u5C08\u6848\u4E0A\u4E0B\u6587\u3002\u7528\u6CD5: /add-dir \u6216 /add-dir \u8DEF\u5F91",
83528
83608
  reindex: "\u91CD\u5EFA\u4EE3\u78BC\u5EAB\u7D22\u5F15\u3002\u4F7F\u7528 -force \u522A\u9664\u73FE\u6709\u8CC7\u6599\u5EAB\u4E26\u5B8C\u5168\u91CD\u5EFA",
83609
+ codebase: "\u5207\u63DB\u7576\u524D\u5C08\u6848\u7684\u4EE3\u78BC\u5EAB\u7D22\u5F15\u529F\u80FD\u3002\u7528\u6CD5: /codebase [on|off|status]",
83529
83610
  permissions: "\u7BA1\u7406\u6C38\u9060\u5141\u8A31\u7684\u5DE5\u5177\u6B0A\u9650",
83530
83611
  vulnerabilityHunting: "\u5207\u63DB\u6F0F\u6D1E\u6AA2\u67E5\u6A21\u5F0F\uFF0C\u9032\u884C\u5B89\u5168\u6027\u4EE3\u78BC\u5206\u6790",
83531
83612
  backend: "\u986F\u793A\u80CC\u666F\u8655\u7406\u7A0B\u5E8F\u9762\u677F",
@@ -83547,6 +83628,8 @@ var init_zh_TW = __esm({
83547
83628
  title: "\u9078\u64C7\u8A2D\u5B9A\u6A94",
83548
83629
  scrollHint: "\u2191\u2193 \u6372\u52D5",
83549
83630
  moreHidden: "\u96B1\u85CF {count} \u500B",
83631
+ moreAbove: "\u4E0A\u65B9\u9084\u6709 {count} \u9805",
83632
+ moreBelow: "\u4E0B\u65B9\u9084\u6709 {count} \u9805",
83550
83633
  escHint: "\u6309 ESC \u95DC\u9589",
83551
83634
  activeLabel: "(\u76EE\u524D)",
83552
83635
  searchLabel: "\u641C\u5C0B:",
@@ -84146,12 +84229,15 @@ var init_zh_TW = __esm({
84146
84229
  searchLabel: "\u641C\u5C0B:",
84147
84230
  searchPlaceholder: "\u8F38\u5165\u4EE5\u641C\u5C0B",
84148
84231
  searching: "\u641C\u5C0B\u4E2D...",
84149
- navigationHint: "\u8F38\u5165\u4EE5\u641C\u5C0B \u2022 \u2191\u2193 \u5C0E\u822A \u2022 \u7A7A\u683C \u6A19\u8A18 \u2022 D \u522A\u9664 \u2022 Enter \u9078\u64C7 \u2022 ESC \u95DC\u9589",
84232
+ navigationHint: "\u8F38\u5165\u4EE5\u641C\u5C0B \u2022 \u2191\u2193 \u5C0E\u822A \u2022 \u7A7A\u683C \u6A19\u8A18 \u2022 D \u522A\u9664 \u2022 R \u91CD\u65B0\u547D\u540D \u2022 Enter \u9078\u64C7 \u2022 ESC \u95DC\u9589",
84150
84233
  moreAbove: "\u2191 \u4E0A\u65B9\u9084\u6709 {count} \u500B",
84151
84234
  moreBelow: "\u2193 \u4E0B\u65B9\u9084\u6709 {count} \u500B",
84152
84235
  scrollToLoadMore: "(\u6EFE\u52D5\u8F09\u5165\u66F4\u591A)",
84153
84236
  untitled: "\u7121\u6A19\u984C",
84154
- now: "\u73FE\u5728"
84237
+ now: "\u73FE\u5728",
84238
+ renamePrompt: "\u91CD\u65B0\u547D\u540D\u6703\u8A71",
84239
+ renaming: "\u91CD\u65B0\u547D\u540D\u4E2D...",
84240
+ renamePlaceholder: "\u8F38\u5165\u65B0\u7684\u6A19\u984C"
84155
84241
  },
84156
84242
  mcpInfoPanel: {
84157
84243
  title: "MCP \u670D\u52D9",
@@ -89138,11 +89224,12 @@ async function fetchOpenAIModels(baseUrl, apiKey, customHeaders) {
89138
89224
  return data.data || [];
89139
89225
  }
89140
89226
  async function fetchGeminiModels(baseUrl, apiKey) {
89141
- const url = `${baseUrl}/models?key=${apiKey}`;
89227
+ const url = `${baseUrl}/models`;
89142
89228
  const fetchOptions = addProxyToFetchOptions(url, {
89143
89229
  method: "GET",
89144
89230
  headers: {
89145
- "Content-Type": "application/json"
89231
+ "Content-Type": "application/json",
89232
+ "x-goog-api-key": apiKey
89146
89233
  }
89147
89234
  });
89148
89235
  const response = await fetch(url, fetchOptions);
@@ -89344,6 +89431,28 @@ function ConfigScreen({ onBack, onSave, inlineMode = false }) {
89344
89431
  const allFields = getAllFields();
89345
89432
  const currentFieldIndex = allFields.indexOf(currentField);
89346
89433
  const totalFields = allFields.length;
89434
+ const fieldsDisplayWindow = import_react63.default.useMemo(() => {
89435
+ if (allFields.length <= MAX_VISIBLE_FIELDS) {
89436
+ return {
89437
+ items: allFields,
89438
+ startIndex: 0,
89439
+ endIndex: allFields.length
89440
+ };
89441
+ }
89442
+ const halfWindow = Math.floor(MAX_VISIBLE_FIELDS / 2);
89443
+ let startIndex = Math.max(0, currentFieldIndex - halfWindow);
89444
+ let endIndex = Math.min(allFields.length, startIndex + MAX_VISIBLE_FIELDS);
89445
+ if (endIndex - startIndex < MAX_VISIBLE_FIELDS) {
89446
+ startIndex = Math.max(0, endIndex - MAX_VISIBLE_FIELDS);
89447
+ }
89448
+ return {
89449
+ items: allFields.slice(startIndex, endIndex),
89450
+ startIndex,
89451
+ endIndex
89452
+ };
89453
+ }, [allFields, currentFieldIndex]);
89454
+ const hiddenAboveFieldsCount = fieldsDisplayWindow.startIndex;
89455
+ const hiddenBelowFieldsCount = Math.max(0, allFields.length - fieldsDisplayWindow.endIndex);
89347
89456
  (0, import_react63.useEffect)(() => {
89348
89457
  loadProfilesAndConfig();
89349
89458
  }, []);
@@ -90628,7 +90737,25 @@ function ConfigScreen({ onBack, onSave, inlineMode = false }) {
90628
90737
  totalFields,
90629
90738
  ")"
90630
90739
  ),
90631
- totalFields > MAX_VISIBLE_FIELDS && import_react63.default.createElement(Text, { color: theme14.colors.menuSecondary, dimColor: true }, t.configScreen.scrollHint)
90740
+ totalFields > MAX_VISIBLE_FIELDS && import_react63.default.createElement(
90741
+ Text,
90742
+ { color: theme14.colors.menuSecondary, dimColor: true },
90743
+ t.configScreen.scrollHint,
90744
+ hiddenAboveFieldsCount > 0 && import_react63.default.createElement(
90745
+ import_react63.default.Fragment,
90746
+ null,
90747
+ "\xB7",
90748
+ " ",
90749
+ t.configScreen.moreAbove.replace("{count}", hiddenAboveFieldsCount.toString())
90750
+ ),
90751
+ hiddenBelowFieldsCount > 0 && import_react63.default.createElement(
90752
+ import_react63.default.Fragment,
90753
+ null,
90754
+ "\xB7",
90755
+ " ",
90756
+ t.configScreen.moreBelow.replace("{count}", hiddenBelowFieldsCount.toString())
90757
+ )
90758
+ )
90632
90759
  ),
90633
90760
  isEditing && (currentField === "profile" || currentField === "requestMethod" || currentField === "systemPromptId" || currentField === "customHeadersSchemeId" || currentField === "advancedModel" || currentField === "basicModel" || currentField === "responsesReasoningEffort") ? import_react63.default.createElement(
90634
90761
  Box_default,
@@ -90728,19 +90855,7 @@ function ConfigScreen({ onBack, onSave, inlineMode = false }) {
90728
90855
  setIsEditing(false);
90729
90856
  } })
90730
90857
  )
90731
- ) : import_react63.default.createElement(Box_default, { flexDirection: "column" }, (() => {
90732
- if (allFields.length <= MAX_VISIBLE_FIELDS) {
90733
- return allFields.map((field) => renderField(field));
90734
- }
90735
- const halfWindow = Math.floor(MAX_VISIBLE_FIELDS / 2);
90736
- let startIndex = Math.max(0, currentFieldIndex - halfWindow);
90737
- let endIndex = Math.min(allFields.length, startIndex + MAX_VISIBLE_FIELDS);
90738
- if (endIndex - startIndex < MAX_VISIBLE_FIELDS) {
90739
- startIndex = Math.max(0, endIndex - MAX_VISIBLE_FIELDS);
90740
- }
90741
- const visibleFields = allFields.slice(startIndex, endIndex);
90742
- return visibleFields.map((field) => renderField(field));
90743
- })()),
90858
+ ) : import_react63.default.createElement(Box_default, { flexDirection: "column" }, fieldsDisplayWindow.items.map((field) => renderField(field))),
90744
90859
  errors.length > 0 && import_react63.default.createElement(
90745
90860
  Box_default,
90746
90861
  { flexDirection: "column", marginTop: 1 },
@@ -253842,7 +253957,7 @@ var init_sshClient = __esm({
253842
253957
  /**
253843
253958
  * Execute command on remote server
253844
253959
  */
253845
- async exec(command) {
253960
+ async exec(command, options3) {
253846
253961
  if (!this.connected) {
253847
253962
  throw new Error("Not connected");
253848
253963
  }
@@ -253854,8 +253969,67 @@ var init_sshClient = __esm({
253854
253969
  }
253855
253970
  let stdout = "";
253856
253971
  let stderr = "";
253972
+ let settled = false;
253973
+ const safeResolve = (value) => {
253974
+ if (settled)
253975
+ return;
253976
+ settled = true;
253977
+ safeCleanup();
253978
+ resolve12(value);
253979
+ };
253980
+ const safeReject = (error) => {
253981
+ if (settled)
253982
+ return;
253983
+ settled = true;
253984
+ safeCleanup();
253985
+ reject2(error);
253986
+ };
253987
+ let timeoutTimer = null;
253988
+ const safeCleanup = () => {
253989
+ if (timeoutTimer) {
253990
+ clearTimeout(timeoutTimer);
253991
+ timeoutTimer = null;
253992
+ }
253993
+ if ((options3 == null ? void 0 : options3.signal) && abortHandler) {
253994
+ options3.signal.removeEventListener("abort", abortHandler);
253995
+ }
253996
+ };
253997
+ const abortHandler = (options3 == null ? void 0 : options3.signal) ? () => {
253998
+ const abortError = new Error("SSH command aborted");
253999
+ abortError.code = "ABORT_ERR";
254000
+ abortError.stdout = stdout;
254001
+ abortError.stderr = stderr;
254002
+ try {
254003
+ stream.close();
254004
+ stream.destroy();
254005
+ } catch {
254006
+ }
254007
+ safeReject(abortError);
254008
+ } : null;
254009
+ if ((options3 == null ? void 0 : options3.signal) && abortHandler) {
254010
+ if (options3.signal.aborted) {
254011
+ abortHandler();
254012
+ return;
254013
+ }
254014
+ options3.signal.addEventListener("abort", abortHandler);
254015
+ }
254016
+ const timeoutMs = options3 == null ? void 0 : options3.timeout;
254017
+ if (typeof timeoutMs === "number" && timeoutMs > 0) {
254018
+ timeoutTimer = setTimeout(() => {
254019
+ const timeoutError = new Error(`SSH command timed out after ${timeoutMs}ms`);
254020
+ timeoutError.code = "ETIMEDOUT";
254021
+ timeoutError.stdout = stdout;
254022
+ timeoutError.stderr = stderr;
254023
+ try {
254024
+ stream.close();
254025
+ stream.destroy();
254026
+ } catch {
254027
+ }
254028
+ safeReject(timeoutError);
254029
+ }, timeoutMs);
254030
+ }
253857
254031
  stream.on("close", (code2) => {
253858
- resolve12({ stdout, stderr, code: code2 });
254032
+ safeResolve({ stdout, stderr, code: code2 });
253859
254033
  });
253860
254034
  stream.on("data", (data) => {
253861
254035
  stdout += data.toString();
@@ -353644,7 +353818,7 @@ var init_bash = __esm({
353644
353818
  /**
353645
353819
  * Execute command on remote SSH server
353646
353820
  */
353647
- async executeRemoteCommand(command, remotePath, sshConfig, _timeout) {
353821
+ async executeRemoteCommand(command, remotePath, sshConfig, timeout2, abortSignal) {
353648
353822
  const sshClient = new SSHClient();
353649
353823
  try {
353650
353824
  const connectResult = await sshClient.connect(sshConfig, sshConfig.password);
@@ -353653,7 +353827,10 @@ var init_bash = __esm({
353653
353827
  }
353654
353828
  const fullCommand = `cd "${remotePath}" && ${command}`;
353655
353829
  appendTerminalOutput(`[SSH] Executing on ${sshConfig.host}: ${command}`);
353656
- const result2 = await sshClient.exec(fullCommand);
353830
+ const result2 = await sshClient.exec(fullCommand, {
353831
+ timeout: timeout2,
353832
+ signal: abortSignal
353833
+ });
353657
353834
  if (result2.stdout) {
353658
353835
  const lines = result2.stdout.split("\n").filter((line) => line.trim());
353659
353836
  lines.forEach((line) => appendTerminalOutput(line));
@@ -353695,7 +353872,7 @@ var init_bash = __esm({
353695
353872
  if (!sshConfig) {
353696
353873
  throw new Error(`No SSH configuration found for: ${this.workingDirectory}. Please add this remote directory first.`);
353697
353874
  }
353698
- const result2 = await this.executeRemoteCommand(command, parsed.path, sshConfig, timeout2);
353875
+ const result2 = await this.executeRemoteCommand(command, parsed.path, sshConfig, timeout2, abortSignal);
353699
353876
  return {
353700
353877
  stdout: truncateOutput(result2.stdout, this.maxOutputLength),
353701
353878
  stderr: truncateOutput(result2.stderr, this.maxOutputLength),
@@ -353761,6 +353938,43 @@ var init_bash = __esm({
353761
353938
  registerInputCallback(inputHandler);
353762
353939
  const { stdout, stderr } = await new Promise((resolve12, reject2) => {
353763
353940
  var _a21, _b14;
353941
+ let timeoutTimer = null;
353942
+ let timedOut = false;
353943
+ const safeClearTimeout = () => {
353944
+ if (timeoutTimer) {
353945
+ clearTimeout(timeoutTimer);
353946
+ timeoutTimer = null;
353947
+ }
353948
+ };
353949
+ const triggerTimeout = () => {
353950
+ if (timedOut)
353951
+ return;
353952
+ timedOut = true;
353953
+ safeClearTimeout();
353954
+ if (childProcess2.pid && !childProcess2.killed) {
353955
+ try {
353956
+ if (process.platform === "win32") {
353957
+ exec5(`taskkill /PID ${childProcess2.pid} /T /F 2>NUL`, {
353958
+ windowsHide: true
353959
+ });
353960
+ } else {
353961
+ childProcess2.kill("SIGTERM");
353962
+ }
353963
+ } catch {
353964
+ }
353965
+ }
353966
+ const timeoutError = new Error(`Command timed out after ${timeout2}ms: ${command}`);
353967
+ timeoutError.code = "ETIMEDOUT";
353968
+ reject2(timeoutError);
353969
+ };
353970
+ if (typeof timeout2 === "number" && timeout2 > 0) {
353971
+ timeoutTimer = setTimeout(triggerTimeout, timeout2);
353972
+ }
353973
+ if (abortSignal) {
353974
+ abortSignal.addEventListener("abort", () => {
353975
+ safeClearTimeout();
353976
+ });
353977
+ }
353764
353978
  let stdoutData = "";
353765
353979
  let stderrData = "";
353766
353980
  let backgroundProcessId = null;
@@ -353818,6 +354032,7 @@ var init_bash = __esm({
353818
354032
  }, 200);
353819
354033
  const backgroundCheckInterval = setInterval(() => {
353820
354034
  if (shouldMoveToBackground) {
354035
+ safeClearTimeout();
353821
354036
  clearInterval(backgroundCheckInterval);
353822
354037
  if (inputCheckInterval)
353823
354038
  clearInterval(inputCheckInterval);
@@ -353843,6 +354058,7 @@ var init_bash = __esm({
353843
354058
  lines.forEach((line) => appendTerminalOutput(line));
353844
354059
  });
353845
354060
  childProcess2.on("error", (error) => {
354061
+ safeClearTimeout();
353846
354062
  clearInterval(backgroundCheckInterval);
353847
354063
  if (inputCheckInterval)
353848
354064
  clearInterval(inputCheckInterval);
@@ -353866,6 +354082,7 @@ var init_bash = __esm({
353866
354082
  reject2(error);
353867
354083
  });
353868
354084
  childProcess2.on("close", (code2, signal) => {
354085
+ safeClearTimeout();
353869
354086
  clearInterval(backgroundCheckInterval);
353870
354087
  if (inputCheckInterval)
353871
354088
  clearInterval(inputCheckInterval);
@@ -353883,7 +354100,11 @@ var init_bash = __esm({
353883
354100
  }
353884
354101
  if (signal) {
353885
354102
  const error = new Error(`Process killed by signal ${signal}`);
353886
- error.code = code2 || 1;
354103
+ if (timedOut) {
354104
+ error.code = "ETIMEDOUT";
354105
+ } else {
354106
+ error.code = code2 || 1;
354107
+ }
353887
354108
  error.stdout = stdoutData;
353888
354109
  error.stderr = stderrData;
353889
354110
  error.signal = signal;
@@ -355188,7 +355409,7 @@ var init_aceCodeSearch = __esm({
355188
355409
  init_symbol_utils();
355189
355410
  init_search_utils();
355190
355411
  init_constants_utils();
355191
- ACECodeSearchService = class {
355412
+ ACECodeSearchService = class _ACECodeSearchService {
355192
355413
  async withIndexBuildLock(fn) {
355193
355414
  const next = this.indexBuildQueue.then(fn, fn);
355194
355415
  this.indexBuildQueue = next.then(() => void 0, () => void 0);
@@ -355261,6 +355482,24 @@ var init_aceCodeSearch = __esm({
355261
355482
  writable: true,
355262
355483
  value: /* @__PURE__ */ new Map()
355263
355484
  });
355485
+ Object.defineProperty(this, "commandAvailabilityCache", {
355486
+ enumerable: true,
355487
+ configurable: true,
355488
+ writable: true,
355489
+ value: /* @__PURE__ */ new Map()
355490
+ });
355491
+ Object.defineProperty(this, "isGitRepoCache", {
355492
+ enumerable: true,
355493
+ configurable: true,
355494
+ writable: true,
355495
+ value: null
355496
+ });
355497
+ Object.defineProperty(this, "fileStatCache", {
355498
+ enumerable: true,
355499
+ configurable: true,
355500
+ writable: true,
355501
+ value: /* @__PURE__ */ new Map()
355502
+ });
355264
355503
  this.basePath = path22.resolve(basePath);
355265
355504
  }
355266
355505
  /**
@@ -355332,14 +355571,36 @@ var init_aceCodeSearch = __esm({
355332
355571
  this.excludesLoaded = true;
355333
355572
  }
355334
355573
  /**
355335
- * Check if a directory is a Git repository
355574
+ * Check if a command is available (with caching)
355575
+ */
355576
+ async isCommandAvailableCached(command) {
355577
+ const cached = this.commandAvailabilityCache.get(command);
355578
+ if (cached !== void 0) {
355579
+ return cached;
355580
+ }
355581
+ const available = await isCommandAvailable(command);
355582
+ this.commandAvailabilityCache.set(command, available);
355583
+ return available;
355584
+ }
355585
+ /**
355586
+ * Check if a directory is a Git repository (with caching)
355336
355587
  */
355337
355588
  async isGitRepository(directory = this.basePath) {
355589
+ if (directory === this.basePath && this.isGitRepoCache !== null) {
355590
+ return this.isGitRepoCache;
355591
+ }
355338
355592
  try {
355339
355593
  const gitDir = path22.join(directory, ".git");
355340
355594
  const stats = await fs20.stat(gitDir);
355341
- return stats.isDirectory();
355595
+ const isRepo = stats.isDirectory();
355596
+ if (directory === this.basePath) {
355597
+ this.isGitRepoCache = isRepo;
355598
+ }
355599
+ return isRepo;
355342
355600
  } catch {
355601
+ if (directory === this.basePath) {
355602
+ this.isGitRepoCache = false;
355603
+ }
355343
355604
  return false;
355344
355605
  }
355345
355606
  }
@@ -355708,8 +355969,7 @@ var init_aceCodeSearch = __esm({
355708
355969
  /**
355709
355970
  * Strategy 2: Use system grep (or ripgrep if available) for fast searching
355710
355971
  */
355711
- async systemGrepSearch(pattern, fileGlob, maxResults = 100) {
355712
- const grepCommand = await isCommandAvailable("rg") ? "rg" : "grep";
355972
+ async systemGrepSearch(pattern, fileGlob, maxResults = 100, grepCommand = "grep") {
355713
355973
  const isRipgrep = grepCommand === "rg";
355714
355974
  return new Promise((resolve12, reject2) => {
355715
355975
  const args2 = isRipgrep ? ["-n", "-i", "--no-heading", pattern] : ["-r", "-n", "-H", "-E", "-i"];
@@ -355898,25 +356158,27 @@ var init_aceCodeSearch = __esm({
355898
356158
  * Searches for text patterns across files with glob filtering
355899
356159
  */
355900
356160
  async textSearch(pattern, fileGlob, isRegex = false, maxResults = 100) {
355901
- if (await this.isGitRepository()) {
356161
+ const [isGitRepo, gitAvailable, rgAvailable, grepAvailable] = await Promise.all([
356162
+ this.isGitRepository(),
356163
+ this.isCommandAvailableCached("git"),
356164
+ this.isCommandAvailableCached("rg"),
356165
+ this.isCommandAvailableCached("grep")
356166
+ ]);
356167
+ if (isGitRepo && gitAvailable) {
355902
356168
  try {
355903
- const gitAvailable = await isCommandAvailable("git");
355904
- if (gitAvailable) {
355905
- const results2 = await this.gitGrepSearch(pattern, fileGlob, maxResults, isRegex);
355906
- if (results2.length > 0) {
355907
- return await this.sortResultsByRecency(results2);
355908
- }
356169
+ const results2 = await this.gitGrepSearch(pattern, fileGlob, maxResults, isRegex);
356170
+ if (results2.length > 0) {
356171
+ return await this.sortResultsByRecency(results2);
355909
356172
  }
355910
356173
  } catch (error) {
355911
356174
  }
355912
356175
  }
355913
- try {
355914
- const grepAvailable = await isCommandAvailable("rg") || await isCommandAvailable("grep");
355915
- if (grepAvailable) {
355916
- const results2 = await this.systemGrepSearch(pattern, fileGlob, maxResults);
356176
+ if (rgAvailable || grepAvailable) {
356177
+ try {
356178
+ const results2 = await this.systemGrepSearch(pattern, fileGlob, maxResults, rgAvailable ? "rg" : "grep");
355917
356179
  return await this.sortResultsByRecency(results2);
356180
+ } catch (error) {
355918
356181
  }
355919
- } catch (error) {
355920
356182
  }
355921
356183
  const results = await this.jsTextSearch(pattern, fileGlob, isRegex, maxResults);
355922
356184
  return await this.sortResultsByRecency(results);
@@ -355924,7 +356186,7 @@ var init_aceCodeSearch = __esm({
355924
356186
  /**
355925
356187
  * Sort search results by file modification time (recent files first)
355926
356188
  * Files modified within last 24 hours are prioritized
355927
- * Uses parallel stat calls for better performance
356189
+ * Uses cached stat calls for better performance
355928
356190
  */
355929
356191
  async sortResultsByRecency(results) {
355930
356192
  if (results.length === 0)
@@ -355932,19 +356194,33 @@ var init_aceCodeSearch = __esm({
355932
356194
  const now = Date.now();
355933
356195
  const recentThreshold = 24 * 60 * 60 * 1e3;
355934
356196
  const uniqueFiles = Array.from(new Set(results.map((r) => r.filePath)));
355935
- const statResults = await Promise.allSettled(uniqueFiles.map(async (filePath) => {
355936
- const fullPath = path22.resolve(this.basePath, filePath);
355937
- const stats = await fs20.stat(fullPath);
355938
- return { filePath, mtimeMs: stats.mtimeMs };
355939
- }));
355940
356197
  const fileModTimes = /* @__PURE__ */ new Map();
355941
- statResults.forEach((result2, index) => {
355942
- if (result2.status === "fulfilled") {
355943
- fileModTimes.set(result2.value.filePath, result2.value.mtimeMs);
356198
+ const uncachedFiles = [];
356199
+ for (const filePath of uniqueFiles) {
356200
+ const cached = this.fileStatCache.get(filePath);
356201
+ if (cached && now - cached.cachedAt < _ACECodeSearchService.STAT_CACHE_TTL) {
356202
+ fileModTimes.set(filePath, cached.mtimeMs);
355944
356203
  } else {
355945
- fileModTimes.set(uniqueFiles[index], 0);
356204
+ uncachedFiles.push(filePath);
355946
356205
  }
355947
- });
356206
+ }
356207
+ if (uncachedFiles.length > 0) {
356208
+ const statResults = await Promise.allSettled(uncachedFiles.map(async (filePath) => {
356209
+ const fullPath = path22.resolve(this.basePath, filePath);
356210
+ const stats = await fs20.stat(fullPath);
356211
+ return { filePath, mtimeMs: stats.mtimeMs };
356212
+ }));
356213
+ statResults.forEach((result2, index) => {
356214
+ const filePath = uncachedFiles[index];
356215
+ if (result2.status === "fulfilled") {
356216
+ const mtimeMs = result2.value.mtimeMs;
356217
+ fileModTimes.set(filePath, mtimeMs);
356218
+ this.fileStatCache.set(filePath, { mtimeMs, cachedAt: now });
356219
+ } else {
356220
+ fileModTimes.set(filePath, 0);
356221
+ }
356222
+ });
356223
+ }
355948
356224
  return results.sort((a, b) => {
355949
356225
  const aMtime = fileModTimes.get(a.filePath) || 0;
355950
356226
  const bMtime = fileModTimes.get(b.filePath) || 0;
@@ -356038,6 +356314,12 @@ var init_aceCodeSearch = __esm({
356038
356314
  };
356039
356315
  }
356040
356316
  };
356317
+ Object.defineProperty(ACECodeSearchService, "STAT_CACHE_TTL", {
356318
+ enumerable: true,
356319
+ configurable: true,
356320
+ writable: true,
356321
+ value: 60 * 1e3
356322
+ });
356041
356323
  aceCodeSearchService = new ACECodeSearchService();
356042
356324
  mcpTools3 = [
356043
356325
  {
@@ -431511,6 +431793,39 @@ var init_sessionManager = __esm({
431511
431793
  clearCurrentSession() {
431512
431794
  this.currentSession = null;
431513
431795
  }
431796
+ /**
431797
+ * Update the title of a session
431798
+ * @param sessionId - Session ID to update
431799
+ * @param newTitle - New title for the session
431800
+ */
431801
+ async updateSessionTitle(sessionId, newTitle) {
431802
+ var _a21;
431803
+ try {
431804
+ const session = await this.findSessionInDateFolders(sessionId);
431805
+ if (!session) {
431806
+ logger.warn("Session not found for title update:", { sessionId });
431807
+ return false;
431808
+ }
431809
+ session.title = this.cleanTitle(newTitle);
431810
+ session.updatedAt = Date.now();
431811
+ await this.saveSession(session);
431812
+ if (((_a21 = this.currentSession) == null ? void 0 : _a21.id) === sessionId) {
431813
+ this.currentSession.title = session.title;
431814
+ this.currentSession.updatedAt = session.updatedAt;
431815
+ }
431816
+ logger.info("Session title updated:", {
431817
+ sessionId,
431818
+ newTitle: session.title
431819
+ });
431820
+ return true;
431821
+ } catch (error) {
431822
+ logger.error("Failed to update session title:", {
431823
+ sessionId,
431824
+ error: error instanceof Error ? error.message : String(error)
431825
+ });
431826
+ return false;
431827
+ }
431828
+ }
431514
431829
  async deleteSession(sessionId) {
431515
431830
  let sessionDeleted = false;
431516
431831
  try {
@@ -537686,7 +538001,7 @@ function MarkdownRenderer({ content }) {
537686
538001
  return renderFallback(content);
537687
538002
  }
537688
538003
  }
537689
- var import_react75, import_markdown_it_terminal, import_cli_highlight2, md, HEADING_STYLE, FIRST_HEADING_STYLE, originalFenceRule, ANSI_PATTERN;
538004
+ var import_react75, import_markdown_it_terminal, import_cli_highlight2, md, HEADING_STYLE, FIRST_HEADING_STYLE, originalBulletListOpen, originalBulletListClose, originalOrderedListOpen, originalOrderedListClose, originalListItemClose, originalFenceRule, ANSI_PATTERN;
537690
538005
  var init_MarkdownRenderer = __esm({
537691
538006
  async "dist/ui/components/common/MarkdownRenderer.js"() {
537692
538007
  "use strict";
@@ -537741,11 +538056,31 @@ var init_MarkdownRenderer = __esm({
537741
538056
  const style = ((_b14 = tokens2[idx2]) == null ? void 0 : _b14.tag) === "h1" ? FIRST_HEADING_STYLE : HEADING_STYLE;
537742
538057
  return style.close + "\n\n";
537743
538058
  };
537744
- md.renderer.rules["bullet_list_open"] = () => "";
537745
- md.renderer.rules["bullet_list_close"] = () => "\n";
537746
- md.renderer.rules["ordered_list_open"] = () => "";
537747
- md.renderer.rules["ordered_list_close"] = () => "\n";
537748
- md.renderer.rules["list_item_close"] = () => "\n";
538059
+ originalBulletListOpen = md.renderer.rules["bullet_list_open"];
538060
+ originalBulletListClose = md.renderer.rules["bullet_list_close"];
538061
+ originalOrderedListOpen = md.renderer.rules["ordered_list_open"];
538062
+ originalOrderedListClose = md.renderer.rules["ordered_list_close"];
538063
+ originalListItemClose = md.renderer.rules["list_item_close"];
538064
+ md.renderer.rules["bullet_list_open"] = (tokens2, idx2, options3, env5, self2) => {
538065
+ originalBulletListOpen == null ? void 0 : originalBulletListOpen(tokens2, idx2, options3, env5, self2);
538066
+ return "";
538067
+ };
538068
+ md.renderer.rules["bullet_list_close"] = (tokens2, idx2, options3, env5, self2) => {
538069
+ originalBulletListClose == null ? void 0 : originalBulletListClose(tokens2, idx2, options3, env5, self2);
538070
+ return "\n";
538071
+ };
538072
+ md.renderer.rules["ordered_list_open"] = (tokens2, idx2, options3, env5, self2) => {
538073
+ originalOrderedListOpen == null ? void 0 : originalOrderedListOpen(tokens2, idx2, options3, env5, self2);
538074
+ return "";
538075
+ };
538076
+ md.renderer.rules["ordered_list_close"] = (tokens2, idx2, options3, env5, self2) => {
538077
+ originalOrderedListClose == null ? void 0 : originalOrderedListClose(tokens2, idx2, options3, env5, self2);
538078
+ return "\n";
538079
+ };
538080
+ md.renderer.rules["list_item_close"] = (tokens2, idx2, options3, env5, self2) => {
538081
+ originalListItemClose == null ? void 0 : originalListItemClose(tokens2, idx2, options3, env5, self2);
538082
+ return "\n";
538083
+ };
537749
538084
  md.renderer.rules["hr"] = () => {
537750
538085
  const width = (process.stdout.columns || 80) - 4;
537751
538086
  return "\n" + "-".repeat(width) + "\n\n";
@@ -540824,6 +541159,10 @@ function useCommandPanel(buffer, isProcessing = false) {
540824
541159
  name: "reindex",
540825
541160
  description: t.commandPanel.commands.reindex
540826
541161
  },
541162
+ {
541163
+ name: "codebase",
541164
+ description: t.commandPanel.commands.codebase || "Toggle codebase indexing for current project"
541165
+ },
540827
541166
  {
540828
541167
  name: "permissions",
540829
541168
  description: t.commandPanel.commands.permissions || "Manage tool permissions"
@@ -541796,6 +542135,22 @@ function useKeyboardInput(options3) {
541796
542135
  updateCommandPanelState(text3);
541797
542136
  forceUpdate({});
541798
542137
  };
542138
+ const flushPendingInput = () => {
542139
+ if (!inputBuffer.current)
542140
+ return;
542141
+ if (inputTimer.current) {
542142
+ clearTimeout(inputTimer.current);
542143
+ inputTimer.current = null;
542144
+ }
542145
+ const accumulated = inputBuffer.current;
542146
+ const savedCursorPosition = inputStartCursorPos.current;
542147
+ inputBuffer.current = "";
542148
+ isPasting.current = false;
542149
+ isProcessingInput.current = false;
542150
+ buffer.setCursorPosition(savedCursorPosition);
542151
+ buffer.insert(accumulated);
542152
+ inputStartCursorPos.current = buffer.getCursorPosition();
542153
+ };
541799
542154
  use_input_default((input2, key) => {
541800
542155
  var _a21;
541801
542156
  if (disabled)
@@ -542049,6 +542404,7 @@ function useKeyboardInput(options3) {
542049
542404
  }
542050
542405
  };
542051
542406
  if (key.ctrl && input2 === "a") {
542407
+ flushPendingInput();
542052
542408
  const text3 = buffer.text;
542053
542409
  const cursorPos = buffer.getCursorPosition();
542054
542410
  const lineStart = text3.lastIndexOf("\n", cursorPos - 1) + 1;
@@ -542057,6 +542413,7 @@ function useKeyboardInput(options3) {
542057
542413
  return;
542058
542414
  }
542059
542415
  if (key.ctrl && input2 === "e") {
542416
+ flushPendingInput();
542060
542417
  const text3 = buffer.text;
542061
542418
  const cursorPos = buffer.getCursorPosition();
542062
542419
  let lineEnd = text3.indexOf("\n", cursorPos);
@@ -542067,6 +542424,7 @@ function useKeyboardInput(options3) {
542067
542424
  return;
542068
542425
  }
542069
542426
  if (key.meta && input2 === "f") {
542427
+ flushPendingInput();
542070
542428
  const text3 = buffer.text;
542071
542429
  const cursorPos = buffer.getCursorPosition();
542072
542430
  const newPos = findWordBoundary(text3, cursorPos, "forward");
@@ -542075,6 +542433,7 @@ function useKeyboardInput(options3) {
542075
542433
  return;
542076
542434
  }
542077
542435
  if (key.meta && input2 === "b") {
542436
+ flushPendingInput();
542078
542437
  const text3 = buffer.text;
542079
542438
  const cursorPos = buffer.getCursorPosition();
542080
542439
  const newPos = findWordBoundary(text3, cursorPos, "backward");
@@ -542083,6 +542442,7 @@ function useKeyboardInput(options3) {
542083
542442
  return;
542084
542443
  }
542085
542444
  if (key.ctrl && input2 === "k") {
542445
+ flushPendingInput();
542086
542446
  const text3 = buffer.text;
542087
542447
  const cursorPos = buffer.getCursorPosition();
542088
542448
  let lineEnd = text3.indexOf("\n", cursorPos);
@@ -542095,6 +542455,7 @@ function useKeyboardInput(options3) {
542095
542455
  return;
542096
542456
  }
542097
542457
  if (key.ctrl && input2 === "u") {
542458
+ flushPendingInput();
542098
542459
  const text3 = buffer.text;
542099
542460
  const cursorPos = buffer.getCursorPosition();
542100
542461
  const lineStart = text3.lastIndexOf("\n", cursorPos - 1) + 1;
@@ -542106,6 +542467,7 @@ function useKeyboardInput(options3) {
542106
542467
  return;
542107
542468
  }
542108
542469
  if (key.ctrl && input2 === "w") {
542470
+ flushPendingInput();
542109
542471
  const text3 = buffer.text;
542110
542472
  const cursorPos = buffer.getCursorPosition();
542111
542473
  const wordStart = findWordBoundary(text3, cursorPos, "backward");
@@ -542117,6 +542479,7 @@ function useKeyboardInput(options3) {
542117
542479
  return;
542118
542480
  }
542119
542481
  if (key.ctrl && input2 === "d") {
542482
+ flushPendingInput();
542120
542483
  const text3 = buffer.text;
542121
542484
  const cursorPos = buffer.getCursorPosition();
542122
542485
  if (cursorPos < text3.length) {
@@ -542128,6 +542491,7 @@ function useKeyboardInput(options3) {
542128
542491
  return;
542129
542492
  }
542130
542493
  if (key.ctrl && input2 === "l") {
542494
+ flushPendingInput();
542131
542495
  const displayText = buffer.text;
542132
542496
  const cursorPos = buffer.getCursorPosition();
542133
542497
  const afterCursor = displayText.slice(cursorPos);
@@ -542136,6 +542500,7 @@ function useKeyboardInput(options3) {
542136
542500
  return;
542137
542501
  }
542138
542502
  if (key.ctrl && input2 === "r") {
542503
+ flushPendingInput();
542139
542504
  const displayText = buffer.text;
542140
542505
  const cursorPos = buffer.getCursorPosition();
542141
542506
  const beforeCursor = displayText.slice(0, cursorPos);
@@ -542150,12 +542515,14 @@ function useKeyboardInput(options3) {
542150
542515
  }
542151
542516
  if (deleteKeyPressed.current) {
542152
542517
  deleteKeyPressed.current = false;
542518
+ flushPendingInput();
542153
542519
  buffer.delete();
542154
542520
  forceStateUpdate();
542155
542521
  return;
542156
542522
  }
542157
542523
  const isBackspace = key.backspace || key.delete || input2 === "\x7F" || input2 === "\b";
542158
542524
  if (isBackspace) {
542525
+ flushPendingInput();
542159
542526
  buffer.backspace();
542160
542527
  forceStateUpdate();
542161
542528
  return;
@@ -542246,6 +542613,7 @@ function useKeyboardInput(options3) {
542246
542613
  }
542247
542614
  }
542248
542615
  if (key.ctrl && key.return) {
542616
+ flushPendingInput();
542249
542617
  buffer.insert("\n");
542250
542618
  const text3 = buffer.getFullText();
542251
542619
  const cursorPos = buffer.getCursorPosition();
@@ -542255,6 +542623,7 @@ function useKeyboardInput(options3) {
542255
542623
  return;
542256
542624
  }
542257
542625
  if (key.return) {
542626
+ flushPendingInput();
542258
542627
  if (isProcessingInput.current) {
542259
542628
  return;
542260
542629
  }
@@ -542322,19 +542691,7 @@ function useKeyboardInput(options3) {
542322
542691
  return;
542323
542692
  }
542324
542693
  if (key.leftArrow) {
542325
- if (inputBuffer.current) {
542326
- if (inputTimer.current) {
542327
- clearTimeout(inputTimer.current);
542328
- inputTimer.current = null;
542329
- }
542330
- const accumulated = inputBuffer.current;
542331
- const savedCursorPosition = inputStartCursorPos.current;
542332
- inputBuffer.current = "";
542333
- isPasting.current = false;
542334
- buffer.setCursorPosition(savedCursorPosition);
542335
- buffer.insert(accumulated);
542336
- inputStartCursorPos.current = buffer.getCursorPosition();
542337
- }
542694
+ flushPendingInput();
542338
542695
  buffer.moveLeft();
542339
542696
  const text3 = buffer.getFullText();
542340
542697
  const cursorPos = buffer.getCursorPosition();
@@ -542343,19 +542700,7 @@ function useKeyboardInput(options3) {
542343
542700
  return;
542344
542701
  }
542345
542702
  if (key.rightArrow) {
542346
- if (inputBuffer.current) {
542347
- if (inputTimer.current) {
542348
- clearTimeout(inputTimer.current);
542349
- inputTimer.current = null;
542350
- }
542351
- const accumulated = inputBuffer.current;
542352
- const savedCursorPosition = inputStartCursorPos.current;
542353
- inputBuffer.current = "";
542354
- isPasting.current = false;
542355
- buffer.setCursorPosition(savedCursorPosition);
542356
- buffer.insert(accumulated);
542357
- inputStartCursorPos.current = buffer.getCursorPosition();
542358
- }
542703
+ flushPendingInput();
542359
542704
  buffer.moveRight();
542360
542705
  const text3 = buffer.getFullText();
542361
542706
  const cursorPos = buffer.getCursorPosition();
@@ -542364,19 +542709,7 @@ function useKeyboardInput(options3) {
542364
542709
  return;
542365
542710
  }
542366
542711
  if (key.upArrow && !showCommands && !showFilePicker && !disableKeyboardNavigation) {
542367
- if (inputBuffer.current) {
542368
- if (inputTimer.current) {
542369
- clearTimeout(inputTimer.current);
542370
- inputTimer.current = null;
542371
- }
542372
- const accumulated = inputBuffer.current;
542373
- const savedCursorPosition = inputStartCursorPos.current;
542374
- inputBuffer.current = "";
542375
- isPasting.current = false;
542376
- buffer.setCursorPosition(savedCursorPosition);
542377
- buffer.insert(accumulated);
542378
- inputStartCursorPos.current = buffer.getCursorPosition();
542379
- }
542712
+ flushPendingInput();
542380
542713
  const text3 = buffer.getFullText();
542381
542714
  const cursorPos = buffer.getCursorPosition();
542382
542715
  const isEmpty3 = text3.trim() === "";
@@ -542395,19 +542728,7 @@ function useKeyboardInput(options3) {
542395
542728
  return;
542396
542729
  }
542397
542730
  if (key.downArrow && !showCommands && !showFilePicker && !disableKeyboardNavigation) {
542398
- if (inputBuffer.current) {
542399
- if (inputTimer.current) {
542400
- clearTimeout(inputTimer.current);
542401
- inputTimer.current = null;
542402
- }
542403
- const accumulated = inputBuffer.current;
542404
- const savedCursorPosition = inputStartCursorPos.current;
542405
- inputBuffer.current = "";
542406
- isPasting.current = false;
542407
- buffer.setCursorPosition(savedCursorPosition);
542408
- buffer.insert(accumulated);
542409
- inputStartCursorPos.current = buffer.getCursorPosition();
542410
- }
542731
+ flushPendingInput();
542411
542732
  const text3 = buffer.getFullText();
542412
542733
  const cursorPos = buffer.getCursorPosition();
542413
542734
  const isEmpty3 = text3.trim() === "";
@@ -542944,11 +543265,66 @@ function useBashMode() {
542944
543265
  const shellArgs = isWindows4 ? ["/c", command] : ["-c", command];
542945
543266
  const child = spawn13(shell, shellArgs, {
542946
543267
  cwd: process.cwd(),
542947
- timeout: timeout2,
542948
543268
  env: process.env
542949
543269
  });
542950
543270
  let stdout = "";
542951
543271
  let stderr = "";
543272
+ let settled = false;
543273
+ let timeoutTimer = null;
543274
+ const safeCleanup = () => {
543275
+ if (timeoutTimer) {
543276
+ clearTimeout(timeoutTimer);
543277
+ timeoutTimer = null;
543278
+ }
543279
+ };
543280
+ const safeResolve = (result2) => {
543281
+ if (settled)
543282
+ return;
543283
+ settled = true;
543284
+ safeCleanup();
543285
+ setState((prev) => {
543286
+ const newResults = new Map(prev.executionResults);
543287
+ newResults.set(command, result2);
543288
+ return {
543289
+ ...prev,
543290
+ isExecuting: false,
543291
+ currentCommand: null,
543292
+ currentTimeout: null,
543293
+ output: [],
543294
+ executionResults: newResults
543295
+ };
543296
+ });
543297
+ resolve12(result2);
543298
+ };
543299
+ const killProcessTree = () => {
543300
+ if (!child.pid || child.killed)
543301
+ return;
543302
+ try {
543303
+ if (process.platform === "win32") {
543304
+ const { exec: exec8 } = __require("child_process");
543305
+ exec8(`taskkill /PID ${child.pid} /T /F 2>NUL`, {
543306
+ windowsHide: true
543307
+ });
543308
+ } else {
543309
+ child.kill("SIGTERM");
543310
+ }
543311
+ } catch {
543312
+ }
543313
+ };
543314
+ const triggerTimeout = () => {
543315
+ killProcessTree();
543316
+ safeResolve({
543317
+ success: false,
543318
+ stdout: stdout.trim(),
543319
+ stderr: `Command timed out after ${timeout2}ms: ${command}`,
543320
+ command,
543321
+ exitCode: null,
543322
+ signal: "SIGTERM"
543323
+ });
543324
+ };
543325
+ if (typeof timeout2 === "number" && timeout2 > 0) {
543326
+ timeoutTimer = setTimeout(triggerTimeout, timeout2);
543327
+ }
542952
543328
  (_a21 = child.stdout) == null ? void 0 : _a21.on("data", (data) => {
542953
543329
  stdout += data.toString();
542954
543330
  const lines = data.toString().split("\n").filter((line) => line.trim());
@@ -542970,50 +543346,24 @@ function useBashMode() {
542970
543346
  }
542971
543347
  });
542972
543348
  child.on("close", (code2, signal) => {
542973
- const result2 = {
543349
+ safeResolve({
542974
543350
  success: code2 === 0,
542975
543351
  stdout: stdout.trim(),
542976
543352
  stderr: stderr.trim(),
542977
543353
  command,
542978
543354
  exitCode: code2,
542979
543355
  signal
542980
- };
542981
- setState((prev) => {
542982
- const newResults = new Map(prev.executionResults);
542983
- newResults.set(command, result2);
542984
- return {
542985
- ...prev,
542986
- isExecuting: false,
542987
- currentCommand: null,
542988
- currentTimeout: null,
542989
- output: [],
542990
- executionResults: newResults
542991
- };
542992
543356
  });
542993
- resolve12(result2);
542994
543357
  });
542995
543358
  child.on("error", (error) => {
542996
- const result2 = {
543359
+ safeResolve({
542997
543360
  success: false,
542998
543361
  stdout: "",
542999
543362
  stderr: error.message,
543000
543363
  command,
543001
543364
  exitCode: null,
543002
543365
  signal: null
543003
- };
543004
- setState((prev) => {
543005
- const newResults = new Map(prev.executionResults);
543006
- newResults.set(command, result2);
543007
- return {
543008
- ...prev,
543009
- isExecuting: false,
543010
- currentCommand: null,
543011
- currentTimeout: null,
543012
- output: [],
543013
- executionResults: newResults
543014
- };
543015
543366
  });
543016
- resolve12(result2);
543017
543367
  });
543018
543368
  });
543019
543369
  }, []);
@@ -544171,9 +544521,13 @@ var init_ProfilePanel = __esm({
544171
544521
  const { theme: theme14 } = useTheme();
544172
544522
  const MAX_DISPLAY_ITEMS = 5;
544173
544523
  const effectiveMaxItems = maxHeight ? Math.min(maxHeight, MAX_DISPLAY_ITEMS) : MAX_DISPLAY_ITEMS;
544174
- const displayedProfiles = (0, import_react98.useMemo)(() => {
544524
+ const displayWindow = (0, import_react98.useMemo)(() => {
544175
544525
  if (profiles.length <= effectiveMaxItems) {
544176
- return profiles;
544526
+ return {
544527
+ items: profiles,
544528
+ startIndex: 0,
544529
+ endIndex: profiles.length
544530
+ };
544177
544531
  }
544178
544532
  const halfWindow = Math.floor(effectiveMaxItems / 2);
544179
544533
  let startIndex = Math.max(0, selectedIndex - halfWindow);
@@ -544181,8 +544535,15 @@ var init_ProfilePanel = __esm({
544181
544535
  if (endIndex - startIndex < effectiveMaxItems) {
544182
544536
  startIndex = Math.max(0, endIndex - effectiveMaxItems);
544183
544537
  }
544184
- return profiles.slice(startIndex, endIndex);
544538
+ return {
544539
+ items: profiles.slice(startIndex, endIndex),
544540
+ startIndex,
544541
+ endIndex
544542
+ };
544185
544543
  }, [profiles, selectedIndex, effectiveMaxItems]);
544544
+ const displayedProfiles = displayWindow.items;
544545
+ const hiddenAboveCount = displayWindow.startIndex;
544546
+ const hiddenBelowCount = Math.max(0, profiles.length - displayWindow.endIndex);
544186
544547
  const displayedSelectedIndex = (0, import_react98.useMemo)(() => {
544187
544548
  return displayedProfiles.findIndex((profile) => {
544188
544549
  const originalIndex = profiles.indexOf(profile);
@@ -544248,9 +544609,27 @@ var init_ProfilePanel = __esm({
544248
544609
  Text,
544249
544610
  { color: theme14.colors.menuSecondary, dimColor: true },
544250
544611
  t.profilePanel.scrollHint,
544251
- " \xB7",
544252
- " ",
544253
- t.profilePanel.moreHidden.replace("{count}", (profiles.length - effectiveMaxItems).toString())
544612
+ hiddenAboveCount > 0 && import_react98.default.createElement(
544613
+ import_react98.default.Fragment,
544614
+ null,
544615
+ "\xB7",
544616
+ " ",
544617
+ t.profilePanel.moreAbove.replace("{count}", hiddenAboveCount.toString())
544618
+ ),
544619
+ hiddenBelowCount > 0 && import_react98.default.createElement(
544620
+ import_react98.default.Fragment,
544621
+ null,
544622
+ "\xB7",
544623
+ " ",
544624
+ t.profilePanel.moreBelow.replace("{count}", hiddenBelowCount.toString())
544625
+ ),
544626
+ hiddenAboveCount === 0 && hiddenBelowCount === 0 && import_react98.default.createElement(
544627
+ import_react98.default.Fragment,
544628
+ null,
544629
+ "\xB7",
544630
+ " ",
544631
+ t.profilePanel.moreHidden.replace("{count}", (profiles.length - effectiveMaxItems).toString())
544632
+ )
544254
544633
  )
544255
544634
  )
544256
544635
  ),
@@ -549875,6 +550254,9 @@ function SessionListPanel({ onSelectSession, onClose }) {
549875
550254
  const [totalCount, setTotalCount] = (0, import_react124.useState)(0);
549876
550255
  const [searchInput, setSearchInput] = (0, import_react124.useState)("");
549877
550256
  const [debouncedSearch, setDebouncedSearch] = (0, import_react124.useState)("");
550257
+ const [renamingSessionId, setRenamingSessionId] = (0, import_react124.useState)(null);
550258
+ const [renameInput, setRenameInput] = (0, import_react124.useState)("");
550259
+ const [isRenaming, setIsRenaming] = (0, import_react124.useState)(false);
549878
550260
  const VISIBLE_ITEMS2 = 5;
549879
550261
  const PAGE_SIZE2 = 20;
549880
550262
  const SEARCH_DEBOUNCE_MS = 300;
@@ -549940,6 +550322,41 @@ function SessionListPanel({ onSelectSession, onClose }) {
549940
550322
  use_input_default((input2, key) => {
549941
550323
  if (loading)
549942
550324
  return;
550325
+ if (renamingSessionId) {
550326
+ if (key.escape) {
550327
+ setRenamingSessionId(null);
550328
+ setRenameInput("");
550329
+ return;
550330
+ }
550331
+ if (key.return && renameInput.trim()) {
550332
+ const handleRename = async () => {
550333
+ setIsRenaming(true);
550334
+ const success = await sessionManager.updateSessionTitle(renamingSessionId, renameInput.trim());
550335
+ if (success) {
550336
+ const result2 = await sessionManager.listSessionsPaginated(0, PAGE_SIZE2, debouncedSearch);
550337
+ setSessions(result2.sessions);
550338
+ setHasMore(result2.hasMore);
550339
+ setTotalCount(result2.total);
550340
+ setCurrentPage(0);
550341
+ }
550342
+ setRenamingSessionId(null);
550343
+ setRenameInput("");
550344
+ setIsRenaming(false);
550345
+ };
550346
+ void handleRename();
550347
+ return;
550348
+ }
550349
+ if (key.backspace || key.delete) {
550350
+ setRenameInput((prev) => prev.slice(0, -1));
550351
+ return;
550352
+ }
550353
+ if (input2 && !key.ctrl && !key.meta) {
550354
+ if (!key.upArrow && !key.downArrow && !key.leftArrow && !key.rightArrow && !key.return && !key.escape && !key.tab) {
550355
+ setRenameInput((prev) => prev + input2);
550356
+ }
550357
+ }
550358
+ return;
550359
+ }
549943
550360
  if (key.escape) {
549944
550361
  if (searchInput) {
549945
550362
  setSearchInput("");
@@ -550014,6 +550431,14 @@ function SessionListPanel({ onSelectSession, onClose }) {
550014
550431
  }
550015
550432
  return;
550016
550433
  }
550434
+ if (input2 === "r" || input2 === "R") {
550435
+ const currentSession2 = sessions[selectedIndex];
550436
+ if (currentSession2) {
550437
+ setRenamingSessionId(currentSession2.id);
550438
+ setRenameInput(currentSession2.title || "");
550439
+ }
550440
+ return;
550441
+ }
550017
550442
  if (key.return && sessions.length > 0) {
550018
550443
  const selectedSession = sessions[selectedIndex];
550019
550444
  if (selectedSession) {
@@ -550076,6 +550501,20 @@ function SessionListPanel({ onSelectSession, onClose }) {
550076
550501
  t.sessionListPanel.searching,
550077
550502
  ")"
550078
550503
  )
550504
+ ) : renamingSessionId ? import_react124.default.createElement(
550505
+ Text,
550506
+ { color: "yellow" },
550507
+ t.sessionListPanel.renamePrompt,
550508
+ ":",
550509
+ " ",
550510
+ import_react124.default.createElement(Text, { color: "white" }, renameInput),
550511
+ isRenaming && import_react124.default.createElement(
550512
+ Text,
550513
+ { color: "gray" },
550514
+ " (",
550515
+ t.sessionListPanel.renaming,
550516
+ ")"
550517
+ )
550079
550518
  ) : import_react124.default.createElement(Text, { color: "gray", dimColor: true }, t.sessionListPanel.navigationHint)
550080
550519
  ),
550081
550520
  loading ? import_react124.default.createElement(Text, { color: "gray", dimColor: true }, t.sessionListPanel.loading) : sessions.length === 0 ? import_react124.default.createElement(Text, { color: "gray", dimColor: true }, debouncedSearch ? t.sessionListPanel.noResults.replace("{query}", debouncedSearch) : t.sessionListPanel.noConversations) : import_react124.default.createElement(
@@ -552473,6 +552912,20 @@ ${filePath}`,
552473
552912
  options3.setMessages((prev) => [...prev, errorMessage]);
552474
552913
  }
552475
552914
  }
552915
+ } else if (result2.success && result2.action === "toggleCodebase") {
552916
+ if (options3.onToggleCodebase) {
552917
+ try {
552918
+ await options3.onToggleCodebase(result2.prompt);
552919
+ } catch (error) {
552920
+ const errorMsg = error instanceof Error ? error.message : "Unknown error";
552921
+ const errorMessage = {
552922
+ role: "command",
552923
+ content: `Failed to toggle codebase: ${errorMsg}`,
552924
+ commandName
552925
+ };
552926
+ options3.setMessages((prev) => [...prev, errorMessage]);
552927
+ }
552928
+ }
552476
552929
  } else if (result2.message) {
552477
552930
  const commandMessage = {
552478
552931
  role: "command",
@@ -553314,8 +553767,7 @@ async function handleConversationWithTools(options3) {
553314
553767
  saveMessage(sessionMsg).catch((err) => console.error("Failed to save sub-agent tool result:", err));
553315
553768
  if (isTimeConsumingTool) {
553316
553769
  const statusIcon = isError2 ? "\u2717" : "\u2713";
553317
- const statusText = isError2 ? `
553318
- \u2514\u2500 ${msg.content}` : "";
553770
+ const statusText = "";
553319
553771
  let terminalResultData;
553320
553772
  if (msg.tool_name === "terminal-execute" && !isError2) {
553321
553773
  try {
@@ -553387,11 +553839,9 @@ async function handleConversationWithTools(options3) {
553387
553839
  return [...prev, uiMsg];
553388
553840
  }
553389
553841
  if (isError2) {
553390
- const statusText = `
553391
- \u2514\u2500 ${msg.content}`;
553392
553842
  const uiMsg = {
553393
553843
  role: "subagent",
553394
- content: `\x1B[38;2;255;100;100m\u2687\u2717 ${msg.tool_name}\x1B[0m${statusText}`,
553844
+ content: `\x1B[38;2;255;100;100m\u2687\u2717 ${msg.tool_name}\x1B[0m`,
553395
553845
  streaming: false,
553396
553846
  subAgent: {
553397
553847
  agentId: subAgentMessage.agentId,
@@ -553614,8 +554064,7 @@ async function handleConversationWithTools(options3) {
553614
554064
  if (toolCall.function.name.startsWith("subagent-")) {
553615
554065
  const isError3 = result2.content.startsWith("Error:");
553616
554066
  const statusIcon2 = isError3 ? "\u2717" : "\u2713";
553617
- const statusText2 = isError3 ? `
553618
- \u2514\u2500 ${result2.content}` : "";
554067
+ const statusText2 = "";
553619
554068
  let usage = void 0;
553620
554069
  if (!isError3) {
553621
554070
  try {
@@ -553637,8 +554086,7 @@ async function handleConversationWithTools(options3) {
553637
554086
  }
553638
554087
  const isError2 = result2.content.startsWith("Error:");
553639
554088
  const statusIcon = isError2 ? "\u2717" : "\u2713";
553640
- const statusText = isError2 ? `
553641
- \u2514\u2500 ${result2.content}` : "";
554089
+ const statusText = "";
553642
554090
  let editDiffData;
553643
554091
  if ((toolCall.function.name === "filesystem-edit" || toolCall.function.name === "filesystem-edit_search") && !isError2) {
553644
554092
  try {
@@ -554003,8 +554451,7 @@ function convertSessionMessagesToUI(sessionMessages) {
554003
554451
  }
554004
554452
  if (isTimeConsumingTool) {
554005
554453
  const statusIcon = isError2 ? "\u2717" : "\u2713";
554006
- const statusText = isError2 ? `
554007
- \u2514\u2500 ${msg.content}` : "";
554454
+ const statusText = "";
554008
554455
  let terminalResultData;
554009
554456
  if (toolName === "terminal-execute" && !isError2) {
554010
554457
  try {
@@ -554071,11 +554518,9 @@ function convertSessionMessagesToUI(sessionMessages) {
554071
554518
  });
554072
554519
  } else {
554073
554520
  if (isError2) {
554074
- const statusText = `
554075
- \u2514\u2500 ${msg.content}`;
554076
554521
  uiMessages.push({
554077
554522
  role: "subagent",
554078
- content: `\x1B[38;2;255;100;100m\u2687\u2717 ${toolName}\x1B[0m${statusText}`,
554523
+ content: `\x1B[38;2;255;100;100m\u2687\u2717 ${toolName}\x1B[0m`,
554079
554524
  streaming: false,
554080
554525
  messageStatus: "error",
554081
554526
  subAgentInternal: true
@@ -554136,10 +554581,7 @@ function convertSessionMessagesToUI(sessionMessages) {
554136
554581
  const isError2 = status === "error";
554137
554582
  const statusIcon = isError2 ? "\u2717" : "\u2713";
554138
554583
  let statusText = "";
554139
- if (isError2) {
554140
- statusText = `
554141
- \u2514\u2500 ${msg.content}`;
554142
- } else if (isRejectedWithReply) {
554584
+ if (isRejectedWithReply) {
554143
554585
  const reason = ((_b14 = msg.content.split("Tool execution rejected by user:")[1]) == null ? void 0 : _b14.trim()) || "";
554144
554586
  statusText = reason ? `
554145
554587
  \u2514\u2500 Rejection reason: ${reason}` : "";
@@ -558006,6 +558448,38 @@ ${errorMsg}`,
558006
558448
  throw error;
558007
558449
  }
558008
558450
  };
558451
+ const handleToggleCodebase = async (mode) => {
558452
+ const workingDirectory = process.cwd();
558453
+ const { loadCodebaseConfig: loadCodebaseConfig2, saveCodebaseConfig: saveCodebaseConfig2 } = await Promise.resolve().then(() => (init_codebaseConfig(), codebaseConfig_exports));
558454
+ const config3 = loadCodebaseConfig2(workingDirectory);
558455
+ let newEnabled;
558456
+ if (mode === "on") {
558457
+ newEnabled = true;
558458
+ } else if (mode === "off") {
558459
+ newEnabled = false;
558460
+ } else {
558461
+ newEnabled = !config3.enabled;
558462
+ }
558463
+ config3.enabled = newEnabled;
558464
+ saveCodebaseConfig2(config3, workingDirectory);
558465
+ const statusMessage = {
558466
+ role: "command",
558467
+ content: `Codebase indexing ${newEnabled ? "enabled" : "disabled"} for this project`,
558468
+ commandName: "codebase"
558469
+ };
558470
+ setMessages((prev) => [...prev, statusMessage]);
558471
+ if (newEnabled) {
558472
+ await handleReindexCodebase();
558473
+ } else {
558474
+ if (codebaseAgentRef.current) {
558475
+ await codebaseAgentRef.current.stop();
558476
+ codebaseAgentRef.current.stopWatching();
558477
+ codebaseAgentRef.current = null;
558478
+ setCodebaseIndexing(false);
558479
+ setWatcherEnabled(false);
558480
+ }
558481
+ }
558482
+ };
558009
558483
  const handleReviewCommitConfirm = async (selection, notes) => {
558010
558484
  setShowReviewCommitPanel(false);
558011
558485
  try {
@@ -558108,6 +558582,7 @@ Please provide your review in a clear, structured format.`;
558108
558582
  handleSessionPanelSelect,
558109
558583
  handleQuit,
558110
558584
  handleReindexCodebase,
558585
+ handleToggleCodebase,
558111
558586
  handleReviewCommitConfirm,
558112
558587
  rollbackViaSSE
558113
558588
  };
@@ -558714,6 +559189,71 @@ var init_profiles = __esm({
558714
559189
  }
558715
559190
  });
558716
559191
 
559192
+ // dist/utils/commands/codebase.js
559193
+ var codebase_exports = {};
559194
+ __export(codebase_exports, {
559195
+ default: () => codebase_default
559196
+ });
559197
+ var codebase_default;
559198
+ var init_codebase = __esm({
559199
+ "dist/utils/commands/codebase.js"() {
559200
+ "use strict";
559201
+ init_commandExecutor();
559202
+ init_codebaseConfig();
559203
+ registerCommand("codebase", {
559204
+ execute: (args2) => {
559205
+ const trimmedArgs = args2 == null ? void 0 : args2.trim().toLowerCase();
559206
+ const config3 = loadCodebaseConfig();
559207
+ const hasEmbeddingConfig = config3.embedding.baseUrl && config3.embedding.apiKey;
559208
+ if (trimmedArgs === "status") {
559209
+ const enabled = isCodebaseEnabled();
559210
+ if (!hasEmbeddingConfig) {
559211
+ return {
559212
+ success: true,
559213
+ message: "Codebase: Not configured. Please configure embedding settings in /home first."
559214
+ };
559215
+ }
559216
+ return {
559217
+ success: true,
559218
+ message: `Codebase: ${enabled ? "Enabled" : "Disabled"} for this project`
559219
+ };
559220
+ }
559221
+ if (trimmedArgs === "on") {
559222
+ if (!hasEmbeddingConfig) {
559223
+ return {
559224
+ success: false,
559225
+ message: "Cannot enable codebase: Embedding settings not configured. Please configure in /home first."
559226
+ };
559227
+ }
559228
+ return {
559229
+ success: true,
559230
+ action: "toggleCodebase",
559231
+ prompt: "on"
559232
+ };
559233
+ }
559234
+ if (trimmedArgs === "off") {
559235
+ return {
559236
+ success: true,
559237
+ action: "toggleCodebase",
559238
+ prompt: "off"
559239
+ };
559240
+ }
559241
+ if (!hasEmbeddingConfig) {
559242
+ return {
559243
+ success: false,
559244
+ message: "Cannot enable codebase: Embedding settings not configured. Please configure in /home first."
559245
+ };
559246
+ }
559247
+ return {
559248
+ success: true,
559249
+ action: "toggleCodebase"
559250
+ };
559251
+ }
559252
+ });
559253
+ codebase_default = {};
559254
+ }
559255
+ });
559256
+
558717
559257
  // dist/utils/commands/permissions.js
558718
559258
  var permissions_exports = {};
558719
559259
  __export(permissions_exports, {
@@ -558906,6 +559446,7 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
558906
559446
  Promise.resolve().then(() => (init_skills(), skills_exports)),
558907
559447
  Promise.resolve().then(() => (init_quit(), quit_exports)),
558908
559448
  Promise.resolve().then(() => (init_reindex(), reindex_exports)),
559449
+ Promise.resolve().then(() => (init_codebase(), codebase_exports)),
558909
559450
  Promise.resolve().then(() => (init_addDir(), addDir_exports)),
558910
559451
  Promise.resolve().then(() => (init_permissions(), permissions_exports)),
558911
559452
  Promise.resolve().then(() => (init_backend(), backend_exports))
@@ -559166,7 +559707,7 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
559166
559707
  });
559167
559708
  };
559168
559709
  const MIN_TERMINAL_HEIGHT = 10;
559169
- const { handleMessageSubmit, processMessage, processPendingMessages, handleHistorySelect, handleRollbackConfirm, handleUserQuestionAnswer, handleSessionPanelSelect, handleQuit, handleReindexCodebase, handleReviewCommitConfirm } = useChatLogic({
559710
+ const { handleMessageSubmit, processMessage, processPendingMessages, handleHistorySelect, handleRollbackConfirm, handleUserQuestionAnswer, handleSessionPanelSelect, handleQuit, handleReindexCodebase, handleToggleCodebase, handleReviewCommitConfirm } = useChatLogic({
559170
559711
  messages,
559171
559712
  setMessages,
559172
559713
  pendingMessages,
@@ -559236,7 +559777,8 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
559236
559777
  setCustomCommandExecution,
559237
559778
  processMessage,
559238
559779
  onQuit: handleQuit,
559239
- onReindexCodebase: handleReindexCodebase
559780
+ onReindexCodebase: handleReindexCodebase,
559781
+ onToggleCodebase: handleToggleCodebase
559240
559782
  });
559241
559783
  (0, import_react136.useEffect)(() => {
559242
559784
  if (!commandsLoaded) {
@@ -559590,9 +560132,14 @@ function ChatScreen({ autoResume, enableYolo, enablePlan }) {
559590
560132
  } : void 0, initialContent: restoreInputContent, onContextPercentageChange: setCurrentContextPercentage, showProfilePicker: panelState.showProfilePanel, setShowProfilePicker: panelState.setShowProfilePanel, profileSelectedIndex: panelState.profileSelectedIndex, setProfileSelectedIndex: panelState.setProfileSelectedIndex, getFilteredProfiles: () => {
559591
560133
  const allProfiles = getAllProfiles();
559592
560134
  const query = panelState.profileSearchQuery.toLowerCase();
560135
+ const currentName = panelState.currentProfileName;
560136
+ const profilesWithMemoryState = allProfiles.map((profile) => ({
560137
+ ...profile,
560138
+ isActive: profile.displayName === currentName
560139
+ }));
559593
560140
  if (!query)
559594
- return allProfiles;
559595
- return allProfiles.filter((profile) => profile.name.toLowerCase().includes(query) || profile.displayName.toLowerCase().includes(query));
560141
+ return profilesWithMemoryState;
560142
+ return profilesWithMemoryState.filter((profile) => profile.name.toLowerCase().includes(query) || profile.displayName.toLowerCase().includes(query));
559596
560143
  }, profileSearchQuery: panelState.profileSearchQuery, setProfileSearchQuery: panelState.setProfileSearchQuery, vscodeConnectionStatus: vscodeState.vscodeConnectionStatus, editorContext: vscodeState.editorContext, codebaseIndexing, codebaseProgress, watcherEnabled, fileUpdateNotification, currentProfileName: panelState.currentProfileName, isCompressing, compressionError, backgroundProcesses: backgroundProcesses.processes, showBackgroundPanel: backgroundProcesses.showPanel, selectedProcessIndex, terminalWidth })
559597
560144
  );
559598
560145
  }