fss-link 1.3.0 → 1.4.1

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.
Files changed (3) hide show
  1. package/README.md +28 -24
  2. package/bundle/fss-link.js +668 -356
  3. package/package.json +1 -1
@@ -10388,9 +10388,9 @@ var init_qwen_logger = __esm({
10388
10388
  init_user_id();
10389
10389
  init_mnemonist();
10390
10390
  init_contentGenerator();
10391
- USAGE_STATS_HOSTNAME = "gb4w8c3ygj-default-sea.rum.aliyuncs.com";
10392
- USAGE_STATS_PATH = "/";
10393
- RUN_APP_ID = "gb4w8c3ygj@851d5d500f08f92";
10391
+ USAGE_STATS_HOSTNAME = "localhost";
10392
+ USAGE_STATS_PATH = "/blocked";
10393
+ RUN_APP_ID = "DISABLED";
10394
10394
  FLUSH_INTERVAL_MS = 1e3 * 60;
10395
10395
  MAX_EVENTS = 1e3;
10396
10396
  MAX_RETRY_EVENTS = 100;
@@ -10428,7 +10428,8 @@ var init_qwen_logger = __esm({
10428
10428
  return `user-${getInstallationId()}`;
10429
10429
  }
10430
10430
  static getInstance(config) {
10431
- if (config === void 0 || !config?.getUsageStatisticsEnabled())
10431
+ const telemetryDisabled = process.env["FSS_DISABLE_TELEMETRY"] !== "false";
10432
+ if (telemetryDisabled || config === void 0 || !config?.getUsageStatisticsEnabled())
10432
10433
  return void 0;
10433
10434
  if (!_QwenLogger.instance) {
10434
10435
  _QwenLogger.instance = new _QwenLogger(config);
@@ -10513,6 +10514,11 @@ var init_qwen_logger = __esm({
10513
10514
  });
10514
10515
  }
10515
10516
  async flushToRum() {
10517
+ if (this.config?.getDebugMode()) {
10518
+ console.debug("QwenLogger: Telemetry disabled, endpoint blocked");
10519
+ }
10520
+ this.events.clear();
10521
+ return {};
10516
10522
  if (this.isFlushInProgress) {
10517
10523
  if (this.config?.getDebugMode()) {
10518
10524
  console.debug("QwenLogger: Flush already in progress, marking pending flush.");
@@ -22373,7 +22379,7 @@ async function createContentGeneratorConfig(config, authType) {
22373
22379
  async function createContentGenerator(config, gcConfig, sessionId2) {
22374
22380
  if (DEBUG_CONTENT)
22375
22381
  console.log(`\u{1F41B} DEBUG createContentGenerator: authType=${config.authType}, apiKey=${config.apiKey}, baseUrl=${config.baseUrl}`);
22376
- const version = "1.3.0";
22382
+ const version = "1.4.1";
22377
22383
  const userAgent = `FSS-Link/${version} (${process.platform}; ${process.arch})`;
22378
22384
  const baseHeaders = {
22379
22385
  "User-Agent": userAgent
@@ -60944,6 +60950,7 @@ var init_text_analyzer = __esm({
60944
60950
  // packages/core/dist/src/tools/project-structure.js
60945
60951
  import * as fs23 from "fs/promises";
60946
60952
  import * as path27 from "path";
60953
+ import { execSync as execSync2 } from "child_process";
60947
60954
  var projectStructureToolSchemaData, projectStructureToolDescription, ProjectStructureToolInvocation, ProjectStructureTool;
60948
60955
  var init_project_structure = __esm({
60949
60956
  "packages/core/dist/src/tools/project-structure.js"() {
@@ -61040,7 +61047,7 @@ var init_project_structure = __esm({
61040
61047
  show_hidden: {
61041
61048
  type: "boolean",
61042
61049
  description: "Include hidden files and directories",
61043
- default: false
61050
+ default: true
61044
61051
  },
61045
61052
  file_types: {
61046
61053
  type: "array",
@@ -61084,6 +61091,8 @@ var init_project_structure = __esm({
61084
61091
  ".nyc_output",
61085
61092
  ".coverage",
61086
61093
  "htmlcov",
61094
+ "test_results",
61095
+ "test-results",
61087
61096
  // Ruby
61088
61097
  ".bundle",
61089
61098
  "vendor",
@@ -61102,7 +61111,33 @@ var init_project_structure = __esm({
61102
61111
  "Thumbs.db",
61103
61112
  // Temporary
61104
61113
  ".tmp",
61105
- ".cache"
61114
+ ".cache",
61115
+ // Archives and Backups (AGGRESSIVE FILTERING)
61116
+ "archive",
61117
+ "archives",
61118
+ "archived",
61119
+ "backup",
61120
+ "backups",
61121
+ "*_backup",
61122
+ "*_backup_*",
61123
+ "*.backup",
61124
+ "*_bak",
61125
+ "*.bak",
61126
+ "*-backup-*",
61127
+ // Analysis and Research Artifacts
61128
+ "analysis_output",
61129
+ "analysis-output",
61130
+ "scan_results",
61131
+ "scan-results",
61132
+ "results",
61133
+ "research",
61134
+ "reports",
61135
+ // TODO and planning artifacts
61136
+ "todo",
61137
+ "todos",
61138
+ "planning",
61139
+ // Logs directory (but not *.log files)
61140
+ "logs"
61106
61141
  ]
61107
61142
  },
61108
61143
  size_analysis: {
@@ -61160,10 +61195,12 @@ Features:
61160
61195
  return `Analyze project structure (${analysis_type}) for ${target}`;
61161
61196
  }
61162
61197
  async execute(_signal) {
61163
- const { target = ".", analysis_type = "overview", max_depth = 5, show_hidden = false, file_types, exclude_patterns = [
61198
+ const { target = ".", analysis_type = "overview", max_depth = 5, show_hidden = true, file_types, exclude_patterns = [
61199
+ // Version control
61164
61200
  ".git",
61165
61201
  ".svn",
61166
61202
  ".hg",
61203
+ // Dependencies
61167
61204
  "node_modules",
61168
61205
  ".npm",
61169
61206
  ".yarn",
@@ -61171,6 +61208,7 @@ Features:
61171
61208
  "venv",
61172
61209
  ".venv",
61173
61210
  "virtualenv",
61211
+ // Python artifacts
61174
61212
  "__pycache__",
61175
61213
  "*.pyc",
61176
61214
  ".pytest_cache",
@@ -61180,27 +61218,60 @@ Features:
61180
61218
  "site-packages",
61181
61219
  "*.egg-info",
61182
61220
  ".eggs",
61221
+ // Build outputs
61183
61222
  "dist",
61184
61223
  "build",
61185
61224
  "out",
61225
+ // Testing artifacts
61186
61226
  "coverage",
61187
61227
  ".nyc_output",
61188
61228
  ".coverage",
61189
61229
  "htmlcov",
61230
+ "test_results",
61231
+ "test-results",
61232
+ // Other language artifacts
61190
61233
  ".bundle",
61191
61234
  "vendor",
61192
61235
  ".gradle",
61193
61236
  ".m2",
61194
61237
  "target",
61238
+ // IDE
61195
61239
  ".idea",
61196
61240
  ".vscode",
61197
61241
  ".vs",
61198
61242
  "*.swp",
61199
61243
  "*.swo",
61244
+ // OS
61200
61245
  ".DS_Store",
61201
61246
  "Thumbs.db",
61202
61247
  ".tmp",
61203
- ".cache"
61248
+ ".cache",
61249
+ // Archives and Backups (AGGRESSIVE)
61250
+ "archive",
61251
+ "archives",
61252
+ "archived",
61253
+ "backup",
61254
+ "backups",
61255
+ "*_backup",
61256
+ "*_backup_*",
61257
+ "*.backup",
61258
+ "*_bak",
61259
+ "*.bak",
61260
+ "*-backup-*",
61261
+ // Analysis artifacts
61262
+ "analysis_output",
61263
+ "analysis-output",
61264
+ "scan_results",
61265
+ "scan-results",
61266
+ "results",
61267
+ "research",
61268
+ "reports",
61269
+ // Planning artifacts
61270
+ "todo",
61271
+ "todos",
61272
+ "planning",
61273
+ // Logs directory
61274
+ "logs"
61204
61275
  ], size_analysis = true, git_awareness = true, query } = this.params;
61205
61276
  try {
61206
61277
  const targetPath = path27.resolve(target);
@@ -61264,22 +61335,78 @@ Features:
61264
61335
  if (file_types && file_types.length > 0) {
61265
61336
  analysis.structure = analysis.structure.filter((file) => file.type === "directory" || file.extension && file_types.includes(file.extension));
61266
61337
  }
61267
- const display = this.formatAnalysis(analysis, analysis_type, targetPath);
61268
- return {
61269
- llmContent: JSON.stringify({
61270
- success: true,
61271
- analysis_type,
61272
- target: targetPath,
61273
- analysis,
61274
- configuration: {
61275
- max_depth,
61276
- show_hidden,
61277
- file_types,
61278
- exclude_patterns,
61279
- size_analysis,
61280
- git_awareness
61338
+ const readmePreview = await this.readReadmePreview(targetPath, 30);
61339
+ const gitCommits = this.getRecentGitCommits(targetPath, 5);
61340
+ const codeFiles = analysis.structure.filter((f) => this.isCodeFile(f));
61341
+ const largestCodeFiles = [...codeFiles].sort((a, b) => b.size - a.size).slice(0, 5).map((f) => ({ path: f.path, size: f.size, extension: f.extension }));
61342
+ const recentCodeFiles = [...codeFiles].sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime()).slice(0, 5).map((f) => ({
61343
+ path: f.path,
61344
+ daysAgo: Math.floor((Date.now() - f.lastModified.getTime()) / (1e3 * 60 * 60 * 24)),
61345
+ extension: f.extension
61346
+ }));
61347
+ const dataSummary = this.analyzeDataFolder(analysis.structure);
61348
+ const display = this.formatAnalysis(analysis, analysis_type, targetPath, readmePreview, gitCommits, largestCodeFiles.length > 0 ? { largest: largestCodeFiles, recent: recentCodeFiles } : null, dataSummary);
61349
+ const twoLevelTree = this.build2LevelTree(analysis.structure);
61350
+ const llmSummary = {
61351
+ success: true,
61352
+ analysis_type,
61353
+ target: targetPath,
61354
+ // Smart summary for context understanding
61355
+ ...readmePreview || gitCommits ? {
61356
+ smartSummary: {
61357
+ ...readmePreview && {
61358
+ readme: {
61359
+ preview: readmePreview,
61360
+ lines: 30,
61361
+ note: "First 30 lines for project context"
61362
+ }
61363
+ },
61364
+ ...gitCommits && {
61365
+ recentActivity: {
61366
+ commits: gitCommits,
61367
+ count: gitCommits.length,
61368
+ note: "Recent git commits showing development activity"
61369
+ }
61370
+ }
61281
61371
  }
61282
- }),
61372
+ } : {},
61373
+ summary: {
61374
+ totalFiles: analysis.totalFiles,
61375
+ totalSize: analysis.totalSize,
61376
+ depth: analysis.architecture.depth,
61377
+ techStack: analysis.techStack
61378
+ },
61379
+ // 2-level tree gives LLM structural context
61380
+ structure: twoLevelTree,
61381
+ entryPoints: analysis.entryPoints,
61382
+ configFiles: analysis.configFiles.slice(0, 10),
61383
+ architecture: {
61384
+ patterns: analysis.architecture.patterns,
61385
+ modules: analysis.architecture.modules.map((name2) => ({
61386
+ name: name2,
61387
+ fileCount: analysis.structure.filter((f) => f.path.startsWith(name2 + "/")).length
61388
+ }))
61389
+ },
61390
+ // File analysis - all files
61391
+ largestFiles: analysis.largestFiles.slice(0, 5).map((f) => ({
61392
+ path: f.path,
61393
+ size: f.size,
61394
+ extension: f.extension
61395
+ })),
61396
+ recentlyModified: analysis.recentlyModified.slice(0, 5).map((f) => ({
61397
+ path: f.path,
61398
+ daysAgo: Math.floor((Date.now() - f.lastModified.getTime()) / (1e3 * 60 * 60 * 24))
61399
+ })),
61400
+ // File analysis - code files only (NEW)
61401
+ ...largestCodeFiles.length > 0 && {
61402
+ largestCodeFiles,
61403
+ recentCodeFiles
61404
+ },
61405
+ // Data folder summary (NEW)
61406
+ ...dataSummary && { dataSummary }
61407
+ };
61408
+ return {
61409
+ llmContent: JSON.stringify(llmSummary),
61283
61410
  returnDisplay: display
61284
61411
  };
61285
61412
  } catch (error) {
@@ -61302,7 +61429,7 @@ Features:
61302
61429
  totalFiles: structure.filter((f) => f.type === "file").length,
61303
61430
  totalSize: structure.reduce((sum, f) => sum + f.size, 0),
61304
61431
  largestFiles: structure.filter((f) => f.type === "file").sort((a, b) => b.size - a.size).slice(0, 10),
61305
- recentlyModified: structure.filter((f) => f.type === "file").sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime()).slice(0, 10),
61432
+ recentlyModified: structure.filter((f) => f.type === "file" && this.isRelevantForRecentlyModified(f)).sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime()).slice(0, 10),
61306
61433
  architecture: {
61307
61434
  patterns: this.detectArchitecturePatterns(structure),
61308
61435
  modules: this.identifyModules(structure),
@@ -61357,7 +61484,7 @@ Features:
61357
61484
  totalFiles: structure.filter((f) => f.type === "file").length,
61358
61485
  totalSize: structure.reduce((sum, f) => sum + f.size, 0),
61359
61486
  largestFiles: structure.filter((f) => f.type === "file").sort((a, b) => b.size - a.size).slice(0, 20),
61360
- recentlyModified: structure.filter((f) => f.type === "file").sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime()).slice(0, 20),
61487
+ recentlyModified: structure.filter((f) => f.type === "file" && this.isRelevantForRecentlyModified(f)).sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime()).slice(0, 20),
61361
61488
  architecture: {
61362
61489
  patterns: [],
61363
61490
  modules: [],
@@ -61625,10 +61752,60 @@ Features:
61625
61752
  identifyModules(structure) {
61626
61753
  return structure.filter((f) => f.type === "directory" && f.path.split("/").length === 1).map((f) => f.name).slice(0, 20);
61627
61754
  }
61755
+ /**
61756
+ * Build a smart 2-level tree for LLM context
61757
+ * Shows ALL root files (including hidden) + 1st level dirs with smart sampling
61758
+ */
61759
+ build2LevelTree(structure) {
61760
+ const tree = {
61761
+ _rootFiles: [],
61762
+ _directories: {}
61763
+ };
61764
+ const rootFiles = structure.filter((f) => f.type === "file" && !f.path.includes("/"));
61765
+ const level1Dirs = structure.filter((f) => f.type === "directory" && f.path.split("/").length === 1);
61766
+ tree["_rootFiles"] = rootFiles.map((f) => ({
61767
+ name: f.name,
61768
+ type: f.extension || "file",
61769
+ isEntryPoint: f.isEntryPoint,
61770
+ isConfig: f.isConfig
61771
+ }));
61772
+ for (const dir of level1Dirs) {
61773
+ const dirPath = dir.path;
61774
+ const filesInDir = structure.filter((f) => f.path.startsWith(dirPath + "/") && f.path.split("/").length === 2 && f.type === "file");
61775
+ const subdirsInDir = structure.filter((f) => f.path.startsWith(dirPath + "/") && f.path.split("/").length === 2 && f.type === "directory");
61776
+ let filesToShow;
61777
+ let truncatedCount = 0;
61778
+ if (filesInDir.length > 10) {
61779
+ const recentFiles = [...filesInDir].sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime()).slice(0, 10);
61780
+ filesToShow = recentFiles.map((f) => ({
61781
+ name: f.name,
61782
+ type: f.extension || "file",
61783
+ important: f.isEntryPoint || f.isConfig
61784
+ }));
61785
+ truncatedCount = filesInDir.length - 10;
61786
+ } else {
61787
+ filesToShow = filesInDir.map((f) => ({
61788
+ name: f.name,
61789
+ type: f.extension || "file",
61790
+ important: f.isEntryPoint || f.isConfig
61791
+ }));
61792
+ }
61793
+ tree["_directories"][dir.name] = {
61794
+ fileCount: filesInDir.length,
61795
+ files: filesToShow,
61796
+ ...truncatedCount > 0 && { truncated: `... and ${truncatedCount} more files` },
61797
+ subdirectories: subdirsInDir.map((sd) => ({
61798
+ name: sd.name,
61799
+ fileCount: structure.filter((f) => f.path.startsWith(sd.path + "/")).length
61800
+ }))
61801
+ };
61802
+ }
61803
+ return tree;
61804
+ }
61628
61805
  calculateMaxDepth(structure) {
61629
61806
  return Math.max(...structure.map((f) => f.path.split("/").length));
61630
61807
  }
61631
- formatAnalysis(analysis, analysisType, targetPath) {
61808
+ formatAnalysis(analysis, analysisType, targetPath, readmePreview = null, gitCommits = null, codeFiles = null, dataSummary = null) {
61632
61809
  let display = `\u{1F3D7}\uFE0F **Project Structure Analysis (${analysisType.toUpperCase()}) - ${path27.basename(targetPath)}**
61633
61810
 
61634
61811
  `;
@@ -61637,7 +61814,7 @@ Features:
61637
61814
  display += this.formatTreeView(analysis);
61638
61815
  break;
61639
61816
  case "overview":
61640
- display += this.formatOverview(analysis);
61817
+ display += this.formatOverview(analysis, readmePreview, gitCommits, codeFiles, dataSummary);
61641
61818
  break;
61642
61819
  case "architecture":
61643
61820
  display += this.formatArchitecture(analysis);
@@ -61652,13 +61829,22 @@ Features:
61652
61829
  display += this.formatContentAnalysis(analysis);
61653
61830
  break;
61654
61831
  default:
61655
- display += this.formatOverview(analysis);
61832
+ display += this.formatOverview(analysis, readmePreview, gitCommits, codeFiles, dataSummary);
61656
61833
  break;
61657
61834
  }
61658
61835
  return display;
61659
61836
  }
61660
- formatOverview(analysis) {
61837
+ formatOverview(analysis, readmePreview = null, gitCommits = null, codeFiles = null, dataSummary = null) {
61661
61838
  let output = "";
61839
+ if (readmePreview) {
61840
+ const previewLines = readmePreview.split("\n").slice(0, 5).join("\n");
61841
+ output += `\u{1F4D6} **Project Description:**
61842
+ ${previewLines}
61843
+ `;
61844
+ output += ` *(First 5 lines of README - full content sent to LLM)*
61845
+
61846
+ `;
61847
+ }
61662
61848
  output += `\u{1F4CA} **Project Overview:**
61663
61849
  `;
61664
61850
  output += `\u2022 Total files: ${analysis.totalFiles}
@@ -61670,6 +61856,15 @@ Features:
61670
61856
  output += `\u2022 Tech stack: ${analysis.techStack.join(", ") || "Unknown"}
61671
61857
 
61672
61858
  `;
61859
+ if (gitCommits && gitCommits.length > 0) {
61860
+ output += `\u{1F4DC} **Recent Git Activity:**
61861
+ `;
61862
+ gitCommits.forEach((commit) => {
61863
+ output += `\u2022 \`${commit.hash}\` ${commit.message}
61864
+ `;
61865
+ });
61866
+ output += "\n";
61867
+ }
61673
61868
  if (analysis.entryPoints.length > 0) {
61674
61869
  output += `\u{1F6AA} **Entry Points:**
61675
61870
  `;
@@ -61698,8 +61893,28 @@ Features:
61698
61893
  });
61699
61894
  output += "\n";
61700
61895
  }
61896
+ if (codeFiles) {
61897
+ if (codeFiles.recent && codeFiles.recent.length > 0) {
61898
+ output += `\u{1F4BB} **Recently Modified Code:**
61899
+ `;
61900
+ codeFiles.recent.slice(0, 5).forEach((file) => {
61901
+ output += `\u2022 ${file.path} (${file.daysAgo} days ago)
61902
+ `;
61903
+ });
61904
+ output += "\n";
61905
+ }
61906
+ if (codeFiles.largest && codeFiles.largest.length > 0) {
61907
+ output += `\u{1F4E6} **Largest Code Files:**
61908
+ `;
61909
+ codeFiles.largest.slice(0, 5).forEach((file) => {
61910
+ output += `\u2022 ${file.path} (${this.formatSize(file.size)})
61911
+ `;
61912
+ });
61913
+ output += "\n";
61914
+ }
61915
+ }
61701
61916
  if (analysis.recentlyModified.length > 0) {
61702
- output += `\u{1F4DD} **Recently Modified:**
61917
+ output += `\u{1F4DD} **Recently Modified (All Files):**
61703
61918
  `;
61704
61919
  analysis.recentlyModified.slice(0, 5).forEach((file) => {
61705
61920
  const age = Math.floor((Date.now() - file.lastModified.getTime()) / (1e3 * 60 * 60 * 24));
@@ -61708,6 +61923,19 @@ Features:
61708
61923
  });
61709
61924
  output += "\n";
61710
61925
  }
61926
+ if (dataSummary) {
61927
+ output += `\u{1F5C4}\uFE0F **Data Folder Summary:**
61928
+ `;
61929
+ output += `\u2022 Total files: ${dataSummary.fileCount}
61930
+ `;
61931
+ output += `\u2022 Total size: ${this.formatSize(dataSummary.totalSize)}
61932
+ `;
61933
+ if (dataSummary.structure.subdirectories && dataSummary.structure.subdirectories.length > 0) {
61934
+ output += `\u2022 Subdirectories: ${dataSummary.structure.subdirectories.map((d) => `${d.name}/ (${d.fileCount})`).join(", ")}
61935
+ `;
61936
+ }
61937
+ output += "\n";
61938
+ }
61711
61939
  return output;
61712
61940
  }
61713
61941
  formatTreeView(analysis) {
@@ -61922,6 +62150,148 @@ Features:
61922
62150
  }
61923
62151
  return `${size.toFixed(1)} ${units[unitIndex]}`;
61924
62152
  }
62153
+ // ========== SMART SUMMARY HELPERS ==========
62154
+ /**
62155
+ * Read first N lines of README for project context
62156
+ */
62157
+ async readReadmePreview(targetPath, lines = 30) {
62158
+ const readmeFiles = ["README.md", "readme.md", "README", "readme.txt"];
62159
+ for (const readmeFile of readmeFiles) {
62160
+ try {
62161
+ const readmePath = path27.join(targetPath, readmeFile);
62162
+ const content = await fs23.readFile(readmePath, "utf-8");
62163
+ const previewLines = content.split("\n").slice(0, lines).join("\n");
62164
+ return previewLines;
62165
+ } catch {
62166
+ continue;
62167
+ }
62168
+ }
62169
+ return null;
62170
+ }
62171
+ /**
62172
+ * Get recent git commit history
62173
+ */
62174
+ getRecentGitCommits(targetPath, count = 5) {
62175
+ try {
62176
+ const gitLog = execSync2(`git -C "${targetPath}" log --oneline -${count}`, {
62177
+ encoding: "utf-8",
62178
+ timeout: 5e3
62179
+ }).trim();
62180
+ if (!gitLog)
62181
+ return null;
62182
+ return gitLog.split("\n").map((line) => {
62183
+ const match2 = line.match(/^([a-f0-9]+)\s+(.+)$/);
62184
+ if (match2) {
62185
+ return { hash: match2[1], message: match2[2] };
62186
+ }
62187
+ return { hash: "", message: line };
62188
+ });
62189
+ } catch {
62190
+ return null;
62191
+ }
62192
+ }
62193
+ /**
62194
+ * Check if file is a code file based on extension
62195
+ */
62196
+ isCodeFile(fileInfo) {
62197
+ const codeExtensions = /* @__PURE__ */ new Set([
62198
+ "js",
62199
+ "jsx",
62200
+ "ts",
62201
+ "tsx",
62202
+ "mjs",
62203
+ "cjs",
62204
+ "py",
62205
+ "pyw",
62206
+ "pyx",
62207
+ "java",
62208
+ "kt",
62209
+ "kts",
62210
+ "cpp",
62211
+ "cc",
62212
+ "cxx",
62213
+ "c",
62214
+ "h",
62215
+ "hpp",
62216
+ "cs",
62217
+ "fs",
62218
+ "fsx",
62219
+ "rb",
62220
+ "rake",
62221
+ "php",
62222
+ "phtml",
62223
+ "go",
62224
+ "rs",
62225
+ "swift",
62226
+ "scala",
62227
+ "r",
62228
+ "lua",
62229
+ "pl",
62230
+ "pm",
62231
+ "sh",
62232
+ "bash",
62233
+ "zsh",
62234
+ "sql",
62235
+ "html",
62236
+ "htm",
62237
+ "xml",
62238
+ "css",
62239
+ "scss",
62240
+ "sass",
62241
+ "less",
62242
+ "vue",
62243
+ "svelte"
62244
+ ]);
62245
+ return fileInfo.type === "file" && fileInfo.extension !== void 0 && codeExtensions.has(fileInfo.extension.toLowerCase());
62246
+ }
62247
+ /**
62248
+ * Check if file should be included in "recently modified" analysis
62249
+ * Excludes data files, logs, caches, databases that change constantly
62250
+ */
62251
+ isRelevantForRecentlyModified(fileInfo) {
62252
+ if (fileInfo.path.startsWith("data/"))
62253
+ return false;
62254
+ if (fileInfo.extension && ["log", "logs"].includes(fileInfo.extension.toLowerCase()))
62255
+ return false;
62256
+ if (fileInfo.extension && ["db", "sqlite", "sqlite3"].includes(fileInfo.extension.toLowerCase()))
62257
+ return false;
62258
+ if (fileInfo.path.includes("__pycache__/"))
62259
+ return false;
62260
+ if (fileInfo.extension && ["pyc", "pyo", "class", "o", "obj"].includes(fileInfo.extension.toLowerCase()))
62261
+ return false;
62262
+ const lockFiles = ["package-lock.json", "yarn.lock", "poetry.lock", "Gemfile.lock", "pnpm-lock.yaml"];
62263
+ if (lockFiles.includes(fileInfo.name))
62264
+ return false;
62265
+ if (fileInfo.path.startsWith("generated_images/"))
62266
+ return false;
62267
+ if (fileInfo.path.startsWith("generated/"))
62268
+ return false;
62269
+ if (fileInfo.path.startsWith("dist/") || fileInfo.path.startsWith("build/"))
62270
+ return false;
62271
+ return true;
62272
+ }
62273
+ /**
62274
+ * Analyze data folder separately for focused summary
62275
+ */
62276
+ analyzeDataFolder(structure) {
62277
+ const dataFiles = structure.filter((f) => f.path.startsWith("data/"));
62278
+ if (dataFiles.length === 0)
62279
+ return null;
62280
+ const totalSize = dataFiles.reduce((sum, f) => sum + f.size, 0);
62281
+ const dataDirs = dataFiles.filter((f) => f.type === "directory" && f.path.split("/").length === 2).map((d) => ({
62282
+ name: d.name,
62283
+ fileCount: structure.filter((f) => f.path.startsWith(`data/${d.name}/`)).length
62284
+ }));
62285
+ const dataRootFiles = dataFiles.filter((f) => f.type === "file" && f.path.split("/").length === 2).map((f) => ({ name: f.name, type: f.extension || "file", size: f.size }));
62286
+ return {
62287
+ fileCount: dataFiles.length,
62288
+ totalSize,
62289
+ structure: {
62290
+ files: dataRootFiles.slice(0, 5),
62291
+ subdirectories: dataDirs
62292
+ }
62293
+ };
62294
+ }
61925
62295
  // ========== QUERY MODE IMPLEMENTATION ==========
61926
62296
  /**
61927
62297
  * Execute a focused query on project files
@@ -73502,7 +73872,7 @@ var init_geminiRequest = __esm({
73502
73872
  });
73503
73873
 
73504
73874
  // packages/core/dist/src/utils/editor.js
73505
- import { execSync as execSync2, spawn as spawn3 } from "child_process";
73875
+ import { execSync as execSync3, spawn as spawn3 } from "child_process";
73506
73876
  function isValidEditorType(editor) {
73507
73877
  return [
73508
73878
  "vscode",
@@ -73517,7 +73887,7 @@ function isValidEditorType(editor) {
73517
73887
  }
73518
73888
  function commandExists(cmd) {
73519
73889
  try {
73520
- execSync2(process.platform === "win32" ? `where.exe ${cmd}` : `command -v ${cmd}`, { stdio: "ignore" });
73890
+ execSync3(process.platform === "win32" ? `where.exe ${cmd}` : `command -v ${cmd}`, { stdio: "ignore" });
73521
73891
  return true;
73522
73892
  } catch {
73523
73893
  return false;
@@ -73627,7 +73997,7 @@ async function openDiff(oldPath, newPath, editor, onEditorClose) {
73627
73997
  case "neovim": {
73628
73998
  const command = process.platform === "win32" ? `${diffCommand.command} ${diffCommand.args.join(" ")}` : `${diffCommand.command} ${diffCommand.args.map((arg) => `"${arg}"`).join(" ")}`;
73629
73999
  try {
73630
- execSync2(command, {
74000
+ execSync3(command, {
73631
74001
  stdio: "inherit",
73632
74002
  encoding: "utf8"
73633
74003
  });
@@ -89850,7 +90220,7 @@ import React31 from "react";
89850
90220
  import { render as render2 } from "ink";
89851
90221
 
89852
90222
  // packages/cli/src/ui/App.tsx
89853
- import { useCallback as useCallback29, useEffect as useEffect43, useMemo as useMemo9, useState as useState48, useRef as useRef12 } from "react";
90223
+ import { useCallback as useCallback29, useEffect as useEffect44, useMemo as useMemo9, useState as useState48, useRef as useRef12 } from "react";
89854
90224
  import {
89855
90225
  Box as Box59,
89856
90226
  measureElement,
@@ -93734,246 +94104,6 @@ var XCode = new Theme(
93734
94104
  lightSemanticColors
93735
94105
  );
93736
94106
 
93737
- // packages/cli/src/ui/themes/qwen-light.ts
93738
- init_theme();
93739
- init_semantic_tokens();
93740
- var qwenLightColors = {
93741
- type: "light",
93742
- Background: "#f8f9fa",
93743
- Foreground: "#5c6166",
93744
- LightBlue: "#55b4d4",
93745
- AccentBlue: "#399ee6",
93746
- AccentPurple: "#a37acc",
93747
- AccentCyan: "#4cbf99",
93748
- AccentGreen: "#86b300",
93749
- AccentYellow: "#f2ae49",
93750
- AccentRed: "#f07171",
93751
- DiffAdded: "#86b300",
93752
- DiffRemoved: "#f07171",
93753
- Comment: "#ABADB1",
93754
- Gray: "#CCCFD3",
93755
- GradientColors: ["#399ee6", "#86b300"]
93756
- };
93757
- var QwenLight = new Theme(
93758
- "Qwen Light",
93759
- "light",
93760
- {
93761
- hljs: {
93762
- display: "block",
93763
- overflowX: "auto",
93764
- padding: "0.5em",
93765
- background: qwenLightColors.Background,
93766
- color: qwenLightColors.Foreground
93767
- },
93768
- "hljs-comment": {
93769
- color: qwenLightColors.Comment,
93770
- fontStyle: "italic"
93771
- },
93772
- "hljs-quote": {
93773
- color: qwenLightColors.AccentCyan,
93774
- fontStyle: "italic"
93775
- },
93776
- "hljs-string": {
93777
- color: qwenLightColors.AccentGreen
93778
- },
93779
- "hljs-constant": {
93780
- color: qwenLightColors.AccentCyan
93781
- },
93782
- "hljs-number": {
93783
- color: qwenLightColors.AccentPurple
93784
- },
93785
- "hljs-keyword": {
93786
- color: qwenLightColors.AccentYellow
93787
- },
93788
- "hljs-selector-tag": {
93789
- color: qwenLightColors.AccentYellow
93790
- },
93791
- "hljs-attribute": {
93792
- color: qwenLightColors.AccentYellow
93793
- },
93794
- "hljs-variable": {
93795
- color: qwenLightColors.Foreground
93796
- },
93797
- "hljs-variable.language": {
93798
- color: qwenLightColors.LightBlue,
93799
- fontStyle: "italic"
93800
- },
93801
- "hljs-title": {
93802
- color: qwenLightColors.AccentBlue
93803
- },
93804
- "hljs-section": {
93805
- color: qwenLightColors.AccentGreen,
93806
- fontWeight: "bold"
93807
- },
93808
- "hljs-type": {
93809
- color: qwenLightColors.LightBlue
93810
- },
93811
- "hljs-class .hljs-title": {
93812
- color: qwenLightColors.AccentBlue
93813
- },
93814
- "hljs-tag": {
93815
- color: qwenLightColors.LightBlue
93816
- },
93817
- "hljs-name": {
93818
- color: qwenLightColors.AccentBlue
93819
- },
93820
- "hljs-builtin-name": {
93821
- color: qwenLightColors.AccentYellow
93822
- },
93823
- "hljs-meta": {
93824
- color: qwenLightColors.AccentYellow
93825
- },
93826
- "hljs-symbol": {
93827
- color: qwenLightColors.AccentRed
93828
- },
93829
- "hljs-bullet": {
93830
- color: qwenLightColors.AccentYellow
93831
- },
93832
- "hljs-regexp": {
93833
- color: qwenLightColors.AccentCyan
93834
- },
93835
- "hljs-link": {
93836
- color: qwenLightColors.LightBlue
93837
- },
93838
- "hljs-deletion": {
93839
- color: qwenLightColors.AccentRed
93840
- },
93841
- "hljs-addition": {
93842
- color: qwenLightColors.AccentGreen
93843
- },
93844
- "hljs-emphasis": {
93845
- fontStyle: "italic"
93846
- },
93847
- "hljs-strong": {
93848
- fontWeight: "bold"
93849
- },
93850
- "hljs-literal": {
93851
- color: qwenLightColors.AccentCyan
93852
- },
93853
- "hljs-built_in": {
93854
- color: qwenLightColors.AccentRed
93855
- },
93856
- "hljs-doctag": {
93857
- color: qwenLightColors.AccentRed
93858
- },
93859
- "hljs-template-variable": {
93860
- color: qwenLightColors.AccentCyan
93861
- },
93862
- "hljs-selector-id": {
93863
- color: qwenLightColors.AccentRed
93864
- }
93865
- },
93866
- qwenLightColors,
93867
- lightSemanticColors
93868
- );
93869
-
93870
- // packages/cli/src/ui/themes/qwen-dark.ts
93871
- init_theme();
93872
- init_semantic_tokens();
93873
- var qwenDarkColors = {
93874
- type: "dark",
93875
- Background: "#0b0e14",
93876
- Foreground: "#bfbdb6",
93877
- LightBlue: "#59C2FF",
93878
- AccentBlue: "#39BAE6",
93879
- AccentPurple: "#D2A6FF",
93880
- AccentCyan: "#95E6CB",
93881
- AccentGreen: "#AAD94C",
93882
- AccentYellow: "#FFD700",
93883
- AccentRed: "#F26D78",
93884
- DiffAdded: "#AAD94C",
93885
- DiffRemoved: "#F26D78",
93886
- Comment: "#646A71",
93887
- Gray: "#3D4149",
93888
- GradientColors: ["#FFD700", "#da7959"]
93889
- };
93890
- var QwenDark = new Theme(
93891
- "Qwen Dark",
93892
- "dark",
93893
- {
93894
- hljs: {
93895
- display: "block",
93896
- overflowX: "auto",
93897
- padding: "0.5em",
93898
- background: qwenDarkColors.Background,
93899
- color: qwenDarkColors.Foreground
93900
- },
93901
- "hljs-keyword": {
93902
- color: qwenDarkColors.AccentYellow
93903
- },
93904
- "hljs-literal": {
93905
- color: qwenDarkColors.AccentPurple
93906
- },
93907
- "hljs-symbol": {
93908
- color: qwenDarkColors.AccentCyan
93909
- },
93910
- "hljs-name": {
93911
- color: qwenDarkColors.LightBlue
93912
- },
93913
- "hljs-link": {
93914
- color: qwenDarkColors.AccentBlue
93915
- },
93916
- "hljs-function .hljs-keyword": {
93917
- color: qwenDarkColors.AccentYellow
93918
- },
93919
- "hljs-subst": {
93920
- color: qwenDarkColors.Foreground
93921
- },
93922
- "hljs-string": {
93923
- color: qwenDarkColors.AccentGreen
93924
- },
93925
- "hljs-title": {
93926
- color: qwenDarkColors.AccentYellow
93927
- },
93928
- "hljs-type": {
93929
- color: qwenDarkColors.AccentBlue
93930
- },
93931
- "hljs-attribute": {
93932
- color: qwenDarkColors.AccentYellow
93933
- },
93934
- "hljs-bullet": {
93935
- color: qwenDarkColors.AccentYellow
93936
- },
93937
- "hljs-addition": {
93938
- color: qwenDarkColors.AccentGreen
93939
- },
93940
- "hljs-variable": {
93941
- color: qwenDarkColors.Foreground
93942
- },
93943
- "hljs-template-tag": {
93944
- color: qwenDarkColors.AccentYellow
93945
- },
93946
- "hljs-template-variable": {
93947
- color: qwenDarkColors.AccentYellow
93948
- },
93949
- "hljs-comment": {
93950
- color: qwenDarkColors.Comment,
93951
- fontStyle: "italic"
93952
- },
93953
- "hljs-quote": {
93954
- color: qwenDarkColors.AccentCyan,
93955
- fontStyle: "italic"
93956
- },
93957
- "hljs-deletion": {
93958
- color: qwenDarkColors.AccentRed
93959
- },
93960
- "hljs-meta": {
93961
- color: qwenDarkColors.AccentYellow
93962
- },
93963
- "hljs-doctag": {
93964
- fontWeight: "bold"
93965
- },
93966
- "hljs-strong": {
93967
- fontWeight: "bold"
93968
- },
93969
- "hljs-emphasis": {
93970
- fontStyle: "italic"
93971
- }
93972
- },
93973
- qwenDarkColors,
93974
- darkSemanticColors
93975
- );
93976
-
93977
94107
  // packages/cli/src/ui/themes/fss-light.ts
93978
94108
  init_theme();
93979
94109
  init_semantic_tokens();
@@ -94842,8 +94972,6 @@ var ThemeManager = class {
94842
94972
  FSSCodeDark,
94843
94973
  FssLight,
94844
94974
  FssDark,
94845
- QwenLight,
94846
- QwenDark,
94847
94975
  ShadesOfPurple,
94848
94976
  XCode,
94849
94977
  ANSI,
@@ -94952,13 +95080,7 @@ var ThemeManager = class {
94952
95080
  isCustom: true
94953
95081
  })
94954
95082
  );
94955
- const qwenThemes = builtInThemes.filter(
94956
- (theme2) => theme2.name === QwenLight.name || theme2.name === QwenDark.name
94957
- );
94958
- const otherBuiltInThemes = builtInThemes.filter(
94959
- (theme2) => theme2.name !== QwenLight.name && theme2.name !== QwenDark.name
94960
- );
94961
- const sortedOtherThemes = [...otherBuiltInThemes, ...customThemes].sort(
95083
+ const sortedThemes = [...builtInThemes, ...customThemes].sort(
94962
95084
  (a, b) => {
94963
95085
  const typeOrder = (type2) => {
94964
95086
  switch (type2) {
@@ -94982,7 +95104,7 @@ var ThemeManager = class {
94982
95104
  return a.name.localeCompare(b.name);
94983
95105
  }
94984
95106
  );
94985
- return [...qwenThemes, ...sortedOtherThemes];
95107
+ return sortedThemes;
94986
95108
  }
94987
95109
  /**
94988
95110
  * Gets a theme by name.
@@ -95952,7 +96074,7 @@ async function getPackageJson() {
95952
96074
  // packages/cli/src/utils/version.ts
95953
96075
  async function getCliVersion() {
95954
96076
  const pkgJson = await getPackageJson();
95955
- return "1.3.0";
96077
+ return "1.4.1";
95956
96078
  }
95957
96079
 
95958
96080
  // packages/cli/src/ui/commands/aboutCommand.ts
@@ -96004,7 +96126,7 @@ import open4 from "open";
96004
96126
  import process11 from "node:process";
96005
96127
 
96006
96128
  // packages/cli/src/generated/git-commit.ts
96007
- var GIT_COMMIT_INFO = "5edc2acf";
96129
+ var GIT_COMMIT_INFO = "b055e021";
96008
96130
 
96009
96131
  // packages/cli/src/ui/commands/bugCommand.ts
96010
96132
  init_dist2();
@@ -98007,11 +98129,11 @@ import { Writable } from "node:stream";
98007
98129
  import { ProxyAgent as ProxyAgent4 } from "undici";
98008
98130
 
98009
98131
  // packages/cli/src/utils/gitUtils.ts
98010
- import { execSync as execSync4 } from "child_process";
98132
+ import { execSync as execSync5 } from "child_process";
98011
98133
  import { ProxyAgent as ProxyAgent3 } from "undici";
98012
98134
  var isGitHubRepository = () => {
98013
98135
  try {
98014
- const remotes = (execSync4("git remote -v", {
98136
+ const remotes = (execSync5("git remote -v", {
98015
98137
  encoding: "utf-8"
98016
98138
  }) || "").trim();
98017
98139
  const pattern = /github\.com/;
@@ -98022,7 +98144,7 @@ var isGitHubRepository = () => {
98022
98144
  }
98023
98145
  };
98024
98146
  var getGitRepoRoot = () => {
98025
- const gitRepoRoot = (execSync4("git rev-parse --show-toplevel", {
98147
+ const gitRepoRoot = (execSync5("git rev-parse --show-toplevel", {
98026
98148
  encoding: "utf-8"
98027
98149
  }) || "").trim();
98028
98150
  if (!gitRepoRoot) {
@@ -98062,7 +98184,7 @@ var getLatestGitHubRelease = async (proxy) => {
98062
98184
  }
98063
98185
  };
98064
98186
  function getGitHubRepoInfo() {
98065
- const remoteUrl = execSync4("git remote get-url origin", {
98187
+ const remoteUrl = execSync5("git remote get-url origin", {
98066
98188
  encoding: "utf-8"
98067
98189
  }).trim();
98068
98190
  const match2 = remoteUrl.match(
@@ -120297,8 +120419,60 @@ function LMStudioModelPrompt({
120297
120419
 
120298
120420
  // packages/cli/src/ui/components/AddCustomEndpointDialog.tsx
120299
120421
  init_dist2();
120300
- import { useState as useState33 } from "react";
120422
+ import { useState as useState33, useEffect as useEffect32 } from "react";
120301
120423
  import { Box as Box19, Text as Text26, useInput as useInput4 } from "ink";
120424
+
120425
+ // packages/cli/src/utils/modelFetcher.ts
120426
+ async function fetchModelsFromCustomEndpoint(baseUrl, providerType, apiKey) {
120427
+ const normalizedBase = baseUrl.replace(/\/+$/, "");
120428
+ const url2 = `${normalizedBase}/models`;
120429
+ const headers = {
120430
+ "Accept": "application/json"
120431
+ };
120432
+ if (apiKey && apiKey.trim() !== "") {
120433
+ headers["Authorization"] = `Bearer ${apiKey}`;
120434
+ }
120435
+ try {
120436
+ const controller = new AbortController();
120437
+ const timeoutId = setTimeout(() => controller.abort(), 1e4);
120438
+ const response = await fetch(url2, {
120439
+ headers,
120440
+ signal: controller.signal
120441
+ });
120442
+ clearTimeout(timeoutId);
120443
+ if (!response.ok) {
120444
+ if (response.status === 401 || response.status === 403) {
120445
+ throw new Error("Authentication failed - check API key");
120446
+ }
120447
+ if (response.status === 404) {
120448
+ throw new Error("Endpoint not found - verify URL includes /v1 suffix");
120449
+ }
120450
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
120451
+ }
120452
+ const json3 = await response.json();
120453
+ if (!json3.data || !Array.isArray(json3.data)) {
120454
+ throw new Error("Invalid response format - expected OpenAI-compatible /models endpoint");
120455
+ }
120456
+ if (json3.data.length === 0) {
120457
+ throw new Error("No models available on this endpoint");
120458
+ }
120459
+ return json3.data.map((m) => ({
120460
+ id: m.id,
120461
+ ownedBy: m.owned_by || "unknown",
120462
+ object: m.object
120463
+ }));
120464
+ } catch (error) {
120465
+ if (error instanceof Error) {
120466
+ if (error.name === "AbortError") {
120467
+ throw new Error("Connection timeout - endpoint took too long to respond");
120468
+ }
120469
+ throw error;
120470
+ }
120471
+ throw new Error(`Connection failed: ${String(error)}`);
120472
+ }
120473
+ }
120474
+
120475
+ // packages/cli/src/ui/components/AddCustomEndpointDialog.tsx
120302
120476
  import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
120303
120477
  function AddCustomEndpointDialog({
120304
120478
  onSubmit,
@@ -120311,11 +120485,25 @@ function AddCustomEndpointDialog({
120311
120485
  const [providerType, setProviderType] = useState33(null);
120312
120486
  const [selectedProviderIndex, setSelectedProviderIndex] = useState33(0);
120313
120487
  const [inputBuffer, setInputBuffer] = useState33("");
120488
+ const [availableModels, setAvailableModels] = useState33([]);
120489
+ const [selectedModelIndex, setSelectedModelIndex] = useState33(0);
120490
+ const [fetchError, setFetchError] = useState33(null);
120314
120491
  const providerOptions = [
120315
120492
  { label: "OpenAI-compatible API", value: AuthType.USE_OPENAI },
120316
120493
  { label: "Ollama", value: AuthType.OLLAMA },
120317
120494
  { label: "LM Studio", value: AuthType.LM_STUDIO }
120318
120495
  ];
120496
+ useEffect32(() => {
120497
+ if (step === "model-fetch" && url2 && providerType) {
120498
+ fetchModelsFromCustomEndpoint(url2, providerType, apiKey || void 0).then((models) => {
120499
+ setAvailableModels(models);
120500
+ setFetchError(null);
120501
+ setStep("model-select");
120502
+ }).catch((err) => {
120503
+ setFetchError(err instanceof Error ? err.message : String(err));
120504
+ });
120505
+ }
120506
+ }, [step, url2, providerType, apiKey]);
120319
120507
  useInput4((input, key) => {
120320
120508
  if (key.escape) {
120321
120509
  onCancel();
@@ -120337,6 +120525,32 @@ function AddCustomEndpointDialog({
120337
120525
  }
120338
120526
  return;
120339
120527
  }
120528
+ if (step === "model-select") {
120529
+ if (key.upArrow && selectedModelIndex > 0) {
120530
+ setSelectedModelIndex(selectedModelIndex - 1);
120531
+ return;
120532
+ }
120533
+ if (key.downArrow && selectedModelIndex < availableModels.length - 1) {
120534
+ setSelectedModelIndex(selectedModelIndex + 1);
120535
+ return;
120536
+ }
120537
+ if (key.return) {
120538
+ if (availableModels.length > 0 && providerType) {
120539
+ const selectedModel = availableModels[selectedModelIndex];
120540
+ onSubmit(name2, url2, selectedModel.id, apiKey, providerType);
120541
+ }
120542
+ return;
120543
+ }
120544
+ return;
120545
+ }
120546
+ if (step === "model-fetch" && fetchError) {
120547
+ if (input === "r" || input === "R") {
120548
+ setFetchError(null);
120549
+ setStep("model-fetch");
120550
+ return;
120551
+ }
120552
+ return;
120553
+ }
120340
120554
  if (key.return) {
120341
120555
  if (step === "name") {
120342
120556
  if (inputBuffer.trim()) {
@@ -120352,9 +120566,8 @@ function AddCustomEndpointDialog({
120352
120566
  }
120353
120567
  } else if (step === "apikey") {
120354
120568
  setApiKey(inputBuffer.trim());
120355
- if (providerType) {
120356
- onSubmit(name2, url2, inputBuffer.trim(), providerType);
120357
- }
120569
+ setInputBuffer("");
120570
+ setStep("model-fetch");
120358
120571
  }
120359
120572
  return;
120360
120573
  }
@@ -120372,7 +120585,7 @@ function AddCustomEndpointDialog({
120372
120585
  return /* @__PURE__ */ jsxs22(Fragment4, { children: [
120373
120586
  /* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentBlue, children: "Step 1: Endpoint Name" }),
120374
120587
  /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Enter a friendly name for this endpoint:" }) }),
120375
- /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "vLLM Production" or "Internal API"' }) }),
120588
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "RTX3090 Proxy" or "Inference Server"' }) }),
120376
120589
  /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
120377
120590
  /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentPurple, children: "> " }),
120378
120591
  inputBuffer,
@@ -120388,7 +120601,7 @@ function AddCustomEndpointDialog({
120388
120601
  /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: name2 })
120389
120602
  ] }) }),
120390
120603
  /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Enter the base URL for this endpoint:" }) }),
120391
- /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "http://localhost:11433" or "https://api.company.com"' }) }),
120604
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: 'Example: "https://rtx3090.bobai.com.au/v1"' }) }),
120392
120605
  /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
120393
120606
  /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentPurple, children: "> " }),
120394
120607
  inputBuffer,
@@ -120437,12 +120650,94 @@ function AddCustomEndpointDialog({
120437
120650
  ")"
120438
120651
  ] }) }),
120439
120652
  /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Enter API key if required (leave empty if none):" }) }),
120653
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentYellow, children: "\u2139 External endpoints usually require authentication" }) }),
120440
120654
  /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
120441
120655
  /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentPurple, children: "> " }),
120442
120656
  "*".repeat(inputBuffer.length),
120443
120657
  /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentCyan, children: "\u258B" })
120444
120658
  ] }) }),
120445
- /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press Enter to save endpoint, Esc to cancel" }) })
120659
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press Enter to fetch models, Esc to cancel" }) })
120660
+ ] });
120661
+ case "model-fetch":
120662
+ if (fetchError) {
120663
+ return /* @__PURE__ */ jsxs22(Fragment4, { children: [
120664
+ /* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentRed, children: "Connection Failed" }),
120665
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
120666
+ "Endpoint: ",
120667
+ /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: name2 }),
120668
+ " (",
120669
+ url2,
120670
+ ")"
120671
+ ] }) }),
120672
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { color: Colors.AccentRed, children: [
120673
+ "Error: ",
120674
+ fetchError
120675
+ ] }) }),
120676
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentYellow, children: "Common issues:" }) }),
120677
+ /* @__PURE__ */ jsxs22(Box19, { marginLeft: 2, flexDirection: "column", children: [
120678
+ /* @__PURE__ */ jsx24(Text26, { children: "\u2022 Incorrect URL (verify /v1 suffix)" }),
120679
+ /* @__PURE__ */ jsx24(Text26, { children: "\u2022 API key required but not provided" }),
120680
+ /* @__PURE__ */ jsx24(Text26, { children: "\u2022 Endpoint not accessible from this machine" }),
120681
+ /* @__PURE__ */ jsx24(Text26, { children: "\u2022 Firewall blocking connection" })
120682
+ ] }),
120683
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Press R to retry, Esc to cancel" }) })
120684
+ ] });
120685
+ }
120686
+ return /* @__PURE__ */ jsxs22(Fragment4, { children: [
120687
+ /* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentBlue, children: "Fetching Models..." }),
120688
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
120689
+ "Connecting to ",
120690
+ /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: url2 })
120691
+ ] }) }),
120692
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "Please wait..." }) })
120693
+ ] });
120694
+ case "model-select":
120695
+ return /* @__PURE__ */ jsxs22(Fragment4, { children: [
120696
+ /* @__PURE__ */ jsx24(Text26, { bold: true, color: Colors.AccentBlue, children: "Step 5: Select Model" }),
120697
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { children: [
120698
+ "Endpoint: ",
120699
+ /* @__PURE__ */ jsx24(Text26, { color: Colors.AccentGreen, children: name2 }),
120700
+ " (",
120701
+ url2,
120702
+ ")"
120703
+ ] }) }),
120704
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs22(Text26, { color: Colors.AccentGreen, children: [
120705
+ "\u2713 Found ",
120706
+ availableModels.length,
120707
+ " available models"
120708
+ ] }) }),
120709
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { children: "Choose a model to use:" }) }),
120710
+ /* @__PURE__ */ jsxs22(Box19, { marginTop: 1, flexDirection: "column", children: [
120711
+ availableModels.slice(0, 15).map((model, index) => {
120712
+ const isSelected = index === selectedModelIndex;
120713
+ const prefix = isSelected ? ">" : " ";
120714
+ return /* @__PURE__ */ jsxs22(
120715
+ Text26,
120716
+ {
120717
+ color: isSelected ? Colors.AccentBlue : Colors.Gray,
120718
+ bold: isSelected,
120719
+ children: [
120720
+ prefix,
120721
+ " ",
120722
+ model.id,
120723
+ " ",
120724
+ /* @__PURE__ */ jsxs22(Text26, { color: Colors.Gray, children: [
120725
+ "(",
120726
+ model.ownedBy,
120727
+ ")"
120728
+ ] })
120729
+ ]
120730
+ },
120731
+ model.id
120732
+ );
120733
+ }),
120734
+ availableModels.length > 15 && /* @__PURE__ */ jsxs22(Text26, { color: Colors.Gray, children: [
120735
+ "... and ",
120736
+ availableModels.length - 15,
120737
+ " more models"
120738
+ ] })
120739
+ ] }),
120740
+ /* @__PURE__ */ jsx24(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text26, { color: Colors.Gray, children: "\u2191/\u2193 to navigate, Enter to confirm, Esc to cancel" }) })
120446
120741
  ] });
120447
120742
  }
120448
120743
  };
@@ -120466,7 +120761,7 @@ function AddCustomEndpointDialog({
120466
120761
  init_modelManager();
120467
120762
 
120468
120763
  // packages/cli/src/ui/components/OpenAIEndpointDialog.tsx
120469
- import { useState as useState34, useEffect as useEffect32 } from "react";
120764
+ import { useState as useState34, useEffect as useEffect33 } from "react";
120470
120765
  import { Box as Box20, Text as Text27 } from "ink";
120471
120766
  init_database();
120472
120767
  import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
@@ -120496,7 +120791,7 @@ function OpenAIEndpointDialog({
120496
120791
  }) {
120497
120792
  const [savedEndpoints, setSavedEndpoints] = useState34([]);
120498
120793
  const [isLoading, setIsLoading] = useState34(true);
120499
- useEffect32(() => {
120794
+ useEffect33(() => {
120500
120795
  const loadEndpoints = async () => {
120501
120796
  try {
120502
120797
  const db = await getFSSLinkDatabase();
@@ -120705,7 +121000,7 @@ function AuthDialog({
120705
121000
  setSelectedEndpoint(null);
120706
121001
  setErrorMessage("OpenAI endpoint selection is required.");
120707
121002
  };
120708
- const handleCustomEndpointSubmit = async (name2, url2, apiKey, providerType) => {
121003
+ const handleCustomEndpointSubmit = async (name2, url2, model, apiKey, providerType) => {
120709
121004
  const db = await getFSSLinkDatabase();
120710
121005
  const endpointId = await db.saveCustomEndpoint(
120711
121006
  null,
@@ -120717,14 +121012,31 @@ function AuthDialog({
120717
121012
  await db.forceSave();
120718
121013
  console.log(`\u{1F4BE} [AUTH-DIALOG] Custom endpoint saved: ${name2} (${url2})`);
120719
121014
  setShowAddCustomEndpointDialog(false);
120720
- setSelectedEndpoint({ id: endpointId, name: name2, url: url2, isDefault: false });
120721
- if (providerType === AuthType.USE_OPENAI) {
120722
- setShowOpenAIKeyPrompt(true);
120723
- } else if (providerType === AuthType.OLLAMA) {
120724
- setShowOllamaModelPrompt(true);
120725
- } else if (providerType === AuthType.LM_STUDIO) {
120726
- setShowLMStudioModelPrompt(true);
121015
+ const modelManager = getModelManager();
121016
+ const modelId = await modelManager.configureModel(
121017
+ providerType,
121018
+ model,
121019
+ // ✨ Use selected model from dialog
121020
+ url2,
121021
+ // ✨ Use custom endpoint URL
121022
+ apiKey,
121023
+ `${name2}: ${model}`
121024
+ );
121025
+ if (endpointId && modelId) {
121026
+ await db.linkModelToEndpoint(modelId, endpointId);
121027
+ await db.saveCustomEndpoint(
121028
+ modelId,
121029
+ // Set provider_id to the model ID
121030
+ name2,
121031
+ url2,
121032
+ `Custom ${providerType} endpoint`,
121033
+ false
121034
+ );
121035
+ console.log(`\u{1F4BE} [AUTH-DIALOG] Linked custom_endpoints.provider_id=${modelId} for endpoint ${endpointId}`);
121036
+ await db.forceSave();
121037
+ console.log(`\u{1F4BE} [AUTH-DIALOG] Model ${modelId} linked to endpoint ${endpointId}`);
120727
121038
  }
121039
+ onSelect(providerType, "User" /* User */);
120728
121040
  };
120729
121041
  const handleCustomEndpointCancel = () => {
120730
121042
  setShowAddCustomEndpointDialog(false);
@@ -120825,7 +121137,7 @@ function AuthDialog({
120825
121137
  }
120826
121138
 
120827
121139
  // packages/cli/src/ui/components/ProviderEndpointSelectionDialog.tsx
120828
- import { useState as useState36, useEffect as useEffect33 } from "react";
121140
+ import { useState as useState36, useEffect as useEffect34 } from "react";
120829
121141
  import { Box as Box22, Text as Text29, useInput as useInput5 } from "ink";
120830
121142
  init_modelManager();
120831
121143
  import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
@@ -120839,7 +121151,7 @@ function ProviderEndpointSelectionDialog({
120839
121151
  const [loading, setLoading] = useState36(true);
120840
121152
  const [switching, setSwitching] = useState36(false);
120841
121153
  const [error, setError] = useState36(null);
120842
- useEffect33(() => {
121154
+ useEffect34(() => {
120843
121155
  const loadEndpoints = async () => {
120844
121156
  try {
120845
121157
  const modelManager = getModelManager();
@@ -121083,7 +121395,7 @@ function ProviderEndpointSelectionDialog({
121083
121395
  }
121084
121396
 
121085
121397
  // packages/cli/src/ui/components/EnhancedModelSelectionDialog.tsx
121086
- import { useState as useState37, useEffect as useEffect34 } from "react";
121398
+ import { useState as useState37, useEffect as useEffect35 } from "react";
121087
121399
  import { Box as Box23, Text as Text30, useInput as useInput6 } from "ink";
121088
121400
  init_modelManager();
121089
121401
  import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
@@ -121134,7 +121446,7 @@ function EnhancedModelSelectionDialog({
121134
121446
  setLoading(false);
121135
121447
  }
121136
121448
  };
121137
- useEffect34(() => {
121449
+ useEffect35(() => {
121138
121450
  loadModels();
121139
121451
  }, [providerType, endpointUrl]);
121140
121452
  useInput6((input, key) => {
@@ -121474,7 +121786,7 @@ var WelcomeBackDialog = ({
121474
121786
  };
121475
121787
 
121476
121788
  // packages/cli/src/ui/components/SearchEngineConfigDialog.tsx
121477
- import { useState as useState38, useEffect as useEffect35 } from "react";
121789
+ import { useState as useState38, useEffect as useEffect36 } from "react";
121478
121790
  import { Box as Box25, Text as Text32, useInput as useInput7 } from "ink";
121479
121791
  init_database();
121480
121792
  import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
@@ -121487,7 +121799,7 @@ function SearchEngineConfigDialog({
121487
121799
  const [currentField, setCurrentField] = useState38("braveApiKey");
121488
121800
  const [isLoading, setIsLoading] = useState38(true);
121489
121801
  const [isSaving, setIsSaving] = useState38(false);
121490
- useEffect35(() => {
121802
+ useEffect36(() => {
121491
121803
  const loadConfig = async () => {
121492
121804
  console.log("[WEBSCRAPER-DEBUG] Loading existing API keys from database...");
121493
121805
  const db = await getFSSLinkDatabase();
@@ -121507,7 +121819,7 @@ function SearchEngineConfigDialog({
121507
121819
  };
121508
121820
  loadConfig().catch(console.error);
121509
121821
  }, []);
121510
- useEffect35(() => {
121822
+ useEffect36(() => {
121511
121823
  if (!isSaving) return;
121512
121824
  const saveConfig = async () => {
121513
121825
  try {
@@ -121731,7 +122043,7 @@ function SearchEngineConfigDialog({
121731
122043
  }
121732
122044
 
121733
122045
  // packages/cli/src/ui/components/AuthInProgress.tsx
121734
- import { useState as useState39, useEffect as useEffect36 } from "react";
122046
+ import { useState as useState39, useEffect as useEffect37 } from "react";
121735
122047
  import { Box as Box26, Text as Text33 } from "ink";
121736
122048
  import Spinner2 from "ink-spinner";
121737
122049
  import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
@@ -121747,7 +122059,7 @@ function AuthInProgress({
121747
122059
  },
121748
122060
  { isActive: true }
121749
122061
  );
121750
- useEffect36(() => {
122062
+ useEffect37(() => {
121751
122063
  const timer = setTimeout(() => {
121752
122064
  setTimedOut(true);
121753
122065
  onTimeout();
@@ -125358,7 +125670,7 @@ function IdeIntegrationNudge({
125358
125670
  }
125359
125671
 
125360
125672
  // packages/cli/src/ui/hooks/useGitBranchName.ts
125361
- import { useState as useState42, useEffect as useEffect37, useCallback as useCallback24 } from "react";
125673
+ import { useState as useState42, useEffect as useEffect38, useCallback as useCallback24 } from "react";
125362
125674
  import { exec as exec6 } from "node:child_process";
125363
125675
  import fs65 from "node:fs";
125364
125676
  import fsPromises3 from "node:fs/promises";
@@ -125394,7 +125706,7 @@ function useGitBranchName(cwd3) {
125394
125706
  ),
125395
125707
  [cwd3, setBranchName]
125396
125708
  );
125397
- useEffect37(() => {
125709
+ useEffect38(() => {
125398
125710
  fetchBranchName();
125399
125711
  const gitLogsHeadPath = path77.join(cwd3, ".git", "logs", "HEAD");
125400
125712
  let watcher;
@@ -125418,14 +125730,14 @@ function useGitBranchName(cwd3) {
125418
125730
  }
125419
125731
 
125420
125732
  // packages/cli/src/ui/hooks/useBracketedPaste.ts
125421
- import { useEffect as useEffect38 } from "react";
125733
+ import { useEffect as useEffect39 } from "react";
125422
125734
  var ENABLE_BRACKETED_PASTE = "\x1B[?2004h";
125423
125735
  var DISABLE_BRACKETED_PASTE = "\x1B[?2004l";
125424
125736
  var useBracketedPaste = () => {
125425
125737
  const cleanup = () => {
125426
125738
  process.stdout.write(DISABLE_BRACKETED_PASTE);
125427
125739
  };
125428
- useEffect38(() => {
125740
+ useEffect39(() => {
125429
125741
  process.stdout.write(ENABLE_BRACKETED_PASTE);
125430
125742
  process.on("exit", cleanup);
125431
125743
  process.on("SIGINT", cleanup);
@@ -125445,7 +125757,7 @@ import {
125445
125757
  createContext as createContext5,
125446
125758
  useCallback as useCallback25,
125447
125759
  useContext as useContext5,
125448
- useEffect as useEffect39,
125760
+ useEffect as useEffect40,
125449
125761
  useState as useState43
125450
125762
  } from "react";
125451
125763
  import { jsx as jsx59 } from "react/jsx-runtime";
@@ -125459,7 +125771,7 @@ var VimModeProvider = ({
125459
125771
  const [vimMode, setVimMode] = useState43(
125460
125772
  initialVimEnabled ? "NORMAL" : "INSERT"
125461
125773
  );
125462
- useEffect39(() => {
125774
+ useEffect40(() => {
125463
125775
  const enabled = settings.merged.vimMode ?? false;
125464
125776
  setVimEnabled(enabled);
125465
125777
  if (enabled) {
@@ -125492,7 +125804,7 @@ var useVimMode = () => {
125492
125804
  };
125493
125805
 
125494
125806
  // packages/cli/src/ui/hooks/vim.ts
125495
- import { useCallback as useCallback26, useReducer as useReducer4, useEffect as useEffect40 } from "react";
125807
+ import { useCallback as useCallback26, useReducer as useReducer4, useEffect as useEffect41 } from "react";
125496
125808
  var DIGIT_MULTIPLIER = 10;
125497
125809
  var DEFAULT_COUNT = 1;
125498
125810
  var DIGIT_1_TO_9 = /^[1-9]$/;
@@ -125556,7 +125868,7 @@ var vimReducer = (state, action) => {
125556
125868
  function useVim(buffer, onSubmit) {
125557
125869
  const { vimEnabled, vimMode, setVimMode } = useVimMode();
125558
125870
  const [state, dispatch] = useReducer4(vimReducer, initialVimState);
125559
- useEffect40(() => {
125871
+ useEffect41(() => {
125560
125872
  dispatch({ type: "SET_MODE", mode: vimMode });
125561
125873
  }, [vimMode]);
125562
125874
  const updateMode = useCallback26(
@@ -126352,12 +126664,12 @@ import { Box as Box56, Newline as Newline3, Text as Text61 } from "ink";
126352
126664
 
126353
126665
  // packages/cli/src/ui/hooks/usePrivacySettings.ts
126354
126666
  init_dist2();
126355
- import { useState as useState45, useEffect as useEffect41, useCallback as useCallback27 } from "react";
126667
+ import { useState as useState45, useEffect as useEffect42, useCallback as useCallback27 } from "react";
126356
126668
  var usePrivacySettings = (config) => {
126357
126669
  const [privacyState, setPrivacyState] = useState45({
126358
126670
  isLoading: true
126359
126671
  });
126360
- useEffect41(() => {
126672
+ useEffect42(() => {
126361
126673
  const fetchInitialState = async () => {
126362
126674
  setPrivacyState({
126363
126675
  isLoading: true
@@ -126571,7 +126883,7 @@ function useSettingsCommand() {
126571
126883
  }
126572
126884
 
126573
126885
  // packages/cli/src/ui/components/SettingsDialog.tsx
126574
- import React30, { useState as useState47, useEffect as useEffect42 } from "react";
126886
+ import React30, { useState as useState47, useEffect as useEffect43 } from "react";
126575
126887
  import { Box as Box58, Text as Text62 } from "ink";
126576
126888
  init_settings();
126577
126889
  import chalk2 from "chalk";
@@ -126603,7 +126915,7 @@ function SettingsDialog({
126603
126915
  );
126604
126916
  const [globalPendingChanges, setGlobalPendingChanges] = useState47(/* @__PURE__ */ new Map());
126605
126917
  const [_restartRequiredSettings, setRestartRequiredSettings] = useState47(/* @__PURE__ */ new Set());
126606
- useEffect42(() => {
126918
+ useEffect43(() => {
126607
126919
  let updated = structuredClone(settings.forScope(selectedScope).settings);
126608
126920
  const newModified = /* @__PURE__ */ new Set();
126609
126921
  const newRestartRequired = /* @__PURE__ */ new Set();
@@ -126713,7 +127025,7 @@ function SettingsDialog({
126713
127025
  const [editBuffer, setEditBuffer] = useState47("");
126714
127026
  const [editCursorPos, setEditCursorPos] = useState47(0);
126715
127027
  const [cursorVisible, setCursorVisible] = useState47(true);
126716
- useEffect42(() => {
127028
+ useEffect43(() => {
126717
127029
  if (!editingKey) {
126718
127030
  setCursorVisible(true);
126719
127031
  return;
@@ -127417,11 +127729,11 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
127417
127729
  const { history, addItem, clearItems, loadHistory } = useHistory();
127418
127730
  const [idePromptAnswered, setIdePromptAnswered] = useState48(false);
127419
127731
  const currentIDE = config.getIdeClient().getCurrentIde();
127420
- useEffect43(() => {
127732
+ useEffect44(() => {
127421
127733
  registerCleanup(() => config.getIdeClient().disconnect());
127422
127734
  }, [config]);
127423
127735
  const shouldShowIdePrompt = currentIDE && !config.getIdeMode() && !settings.merged.hasSeenIdeIntegrationNudge && !idePromptAnswered;
127424
- useEffect43(() => {
127736
+ useEffect44(() => {
127425
127737
  const cleanup = setUpdateHandler(addItem, setUpdateInfo);
127426
127738
  return cleanup;
127427
127739
  }, [addItem]);
@@ -127430,7 +127742,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
127430
127742
  handleNewMessage,
127431
127743
  clearConsoleMessages: clearConsoleMessagesState
127432
127744
  } = useConsoleMessages();
127433
- useEffect43(() => {
127745
+ useEffect44(() => {
127434
127746
  const consolePatcher = new ConsolePatcher({
127435
127747
  onNewMessage: handleNewMessage,
127436
127748
  debugMode: config.getDebugMode()
@@ -127453,7 +127765,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
127453
127765
  const [isSearchDialogOpen, setIsSearchDialogOpen] = useState48(false);
127454
127766
  const [isAddCustomEndpointDialogOpen, setIsAddCustomEndpointDialogOpen] = useState48(false);
127455
127767
  const [footerHeight, setFooterHeight] = useState48(0);
127456
- useEffect43(() => {
127768
+ useEffect44(() => {
127457
127769
  const initializeSearchEngineConfig = async () => {
127458
127770
  const configProvider = SearchEngineConfigProvider.getInstance();
127459
127771
  await configProvider.loadConfiguration();
@@ -127480,12 +127792,12 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
127480
127792
  const [ideContextState, setIdeContextState] = useState48();
127481
127793
  const [showEscapePrompt, setShowEscapePrompt] = useState48(false);
127482
127794
  const [isProcessing, setIsProcessing] = useState48(false);
127483
- useEffect43(() => {
127795
+ useEffect44(() => {
127484
127796
  const unsubscribe = ideContext.subscribeToIdeContext(setIdeContextState);
127485
127797
  setIdeContextState(ideContext.getIdeContext());
127486
127798
  return unsubscribe;
127487
127799
  }, []);
127488
- useEffect43(() => {
127800
+ useEffect44(() => {
127489
127801
  const openDebugConsole = () => {
127490
127802
  setShowErrorDetails(true);
127491
127803
  setConstrainHeight(false);
@@ -127552,7 +127864,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
127552
127864
  handleRestart: handleWelcomeBackRestart,
127553
127865
  handleCancel: handleWelcomeBackCancel
127554
127866
  } = useWelcomeBack(settings);
127555
- useEffect43(() => {
127867
+ useEffect44(() => {
127556
127868
  if (settings.merged.selectedAuthType && !settings.merged.useExternalAuth) {
127557
127869
  const error = validateAuthMethod(settings.merged.selectedAuthType);
127558
127870
  if (error) {
@@ -127566,7 +127878,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
127566
127878
  openAuthDialog,
127567
127879
  setAuthError
127568
127880
  ]);
127569
- useEffect43(() => {
127881
+ useEffect44(() => {
127570
127882
  if (!isAuthenticating) {
127571
127883
  setUserTier(config.getGeminiClient()?.getUserTier());
127572
127884
  }
@@ -127630,7 +127942,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
127630
127942
  console.error("Error refreshing memory:", error);
127631
127943
  }
127632
127944
  }, [config, addItem, settings.merged]);
127633
- useEffect43(() => {
127945
+ useEffect44(() => {
127634
127946
  const checkModelChange = () => {
127635
127947
  const configModel = config.getModel();
127636
127948
  if (configModel !== currentModel) {
@@ -127641,7 +127953,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
127641
127953
  const interval = setInterval(checkModelChange, 1e3);
127642
127954
  return () => clearInterval(interval);
127643
127955
  }, [config, currentModel]);
127644
- useEffect43(() => {
127956
+ useEffect44(() => {
127645
127957
  const flashFallbackHandler = async (currentModel2, fallbackModel, error) => {
127646
127958
  let message;
127647
127959
  if (config.getContentGeneratorConfig().authType === AuthType.LOGIN_WITH_GOOGLE) {
@@ -127800,7 +128112,7 @@ var App = ({ config, settings, startupWarnings = [], version }) => {
127800
128112
  refreshStatic,
127801
128113
  () => cancelHandlerRef.current()
127802
128114
  );
127803
- useEffect43(() => {
128115
+ useEffect44(() => {
127804
128116
  if (contextToPopulate && !initialPromptSubmitted.current) {
127805
128117
  submitQuery(contextToPopulate);
127806
128118
  initialPromptSubmitted.current = true;
@@ -127935,13 +128247,13 @@ ${queuedText}` : queuedText;
127935
128247
  useKeypress(handleGlobalKeypress, {
127936
128248
  isActive: true
127937
128249
  });
127938
- useEffect43(() => {
128250
+ useEffect44(() => {
127939
128251
  if (config) {
127940
128252
  setGeminiMdFileCount(config.getGeminiMdFileCount());
127941
128253
  }
127942
128254
  }, [config, config.getGeminiMdFileCount]);
127943
128255
  const logger6 = useLogger();
127944
- useEffect43(() => {
128256
+ useEffect44(() => {
127945
128257
  const fetchUserMessages = async () => {
127946
128258
  const pastMessagesRaw = await logger6?.getPreviousUserMessages() || [];
127947
128259
  const currentSessionUserMessages = history.filter(
@@ -127973,7 +128285,7 @@ ${queuedText}` : queuedText;
127973
128285
  }, [clearItems, clearConsoleMessagesState, refreshStatic]);
127974
128286
  const mainControlsRef = useRef12(null);
127975
128287
  const pendingHistoryItemRef = useRef12(null);
127976
- useEffect43(() => {
128288
+ useEffect44(() => {
127977
128289
  if (mainControlsRef.current) {
127978
128290
  const fullFooterMeasurement = measureElement(mainControlsRef.current);
127979
128291
  setFooterHeight(fullFooterMeasurement.height);
@@ -127987,7 +128299,7 @@ ${queuedText}` : queuedText;
127987
128299
  () => terminalHeight - footerHeight - staticExtraHeight,
127988
128300
  [terminalHeight, footerHeight]
127989
128301
  );
127990
- useEffect43(() => {
128302
+ useEffect44(() => {
127991
128303
  if (isInitialMount.current) {
127992
128304
  isInitialMount.current = false;
127993
128305
  return;
@@ -128000,7 +128312,7 @@ ${queuedText}` : queuedText;
128000
128312
  clearTimeout(handler);
128001
128313
  };
128002
128314
  }, [terminalWidth, terminalHeight, refreshStatic]);
128003
- useEffect43(() => {
128315
+ useEffect44(() => {
128004
128316
  if (streamingState === "idle" /* Idle */ && staticNeedsRefresh) {
128005
128317
  setStaticNeedsRefresh(false);
128006
128318
  refreshStatic();
@@ -128022,7 +128334,7 @@ ${queuedText}` : queuedText;
128022
128334
  }, [settings.merged.contextFileName]);
128023
128335
  const initialPrompt = useMemo9(() => config.getQuestion(), [config]);
128024
128336
  const geminiClient = config.getGeminiClient();
128025
- useEffect43(() => {
128337
+ useEffect44(() => {
128026
128338
  if (initialPrompt && !initialPromptSubmitted.current && !isAuthenticating && !isAuthDialogOpen && !shouldShowWelcomeBack && !isThemeDialogOpen && !isEditorDialogOpen && !isSearchDialogOpen && modelDialogState === "none" && !showPrivacyNotice && geminiClient?.isInitialized?.()) {
128027
128339
  submitQuery(initialPrompt);
128028
128340
  initialPromptSubmitted.current = true;
@@ -128462,7 +128774,7 @@ import { spawn as spawn7 } from "node:child_process";
128462
128774
  // packages/cli/src/utils/sandbox.ts
128463
128775
  var import_shell_quote4 = __toESM(require_shell_quote(), 1);
128464
128776
  init_settings();
128465
- import { exec as exec7, execSync as execSync6, spawn as spawn6 } from "node:child_process";
128777
+ import { exec as exec7, execSync as execSync7, spawn as spawn6 } from "node:child_process";
128466
128778
  import os29 from "node:os";
128467
128779
  import path80 from "node:path";
128468
128780
  import fs68 from "node:fs";
@@ -128612,7 +128924,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128612
128924
  "-D",
128613
128925
  `HOME_DIR=${fs68.realpathSync(os29.homedir())}`,
128614
128926
  "-D",
128615
- `CACHE_DIR=${fs68.realpathSync(execSync6(`getconf DARWIN_USER_CACHE_DIR`).toString().trim())}`
128927
+ `CACHE_DIR=${fs68.realpathSync(execSync7(`getconf DARWIN_USER_CACHE_DIR`).toString().trim())}`
128616
128928
  ];
128617
128929
  const MAX_INCLUDE_DIRS = 5;
128618
128930
  const targetDir = fs68.realpathSync(cliConfig?.getTargetDir() || "");
@@ -128725,7 +129037,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128725
129037
  console.error(`using ${projectSandboxDockerfile2} for sandbox`);
128726
129038
  buildArgs += `-f ${path80.resolve(projectSandboxDockerfile2)} -i ${image2}`;
128727
129039
  }
128728
- execSync6(
129040
+ execSync7(
128729
129041
  `cd ${gcRoot} && node scripts/build_sandbox.js -s ${buildArgs}`,
128730
129042
  {
128731
129043
  stdio: "inherit",
@@ -128836,12 +129148,12 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128836
129148
  args.push("--env", `no_proxy=${noProxy}`);
128837
129149
  }
128838
129150
  if (proxy) {
128839
- execSync6(
129151
+ execSync7(
128840
129152
  `${config.command} network inspect ${SANDBOX_NETWORK_NAME} || ${config.command} network create --internal ${SANDBOX_NETWORK_NAME}`
128841
129153
  );
128842
129154
  args.push("--network", SANDBOX_NETWORK_NAME);
128843
129155
  if (proxyCommand) {
128844
- execSync6(
129156
+ execSync7(
128845
129157
  `${config.command} network inspect ${SANDBOX_PROXY_NAME} || ${config.command} network create ${SANDBOX_PROXY_NAME}`
128846
129158
  );
128847
129159
  }
@@ -128849,7 +129161,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128849
129161
  }
128850
129162
  const imageName = parseImageName(image2);
128851
129163
  let index = 0;
128852
- const containerNameCheck = execSync6(
129164
+ const containerNameCheck = execSync7(
128853
129165
  `${config.command} ps -a --format "{{.Names}}"`
128854
129166
  ).toString().trim();
128855
129167
  while (containerNameCheck.includes(`${imageName}-${index}`)) {
@@ -128958,8 +129270,8 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128958
129270
  userFlag = "--user root";
128959
129271
  } else if (await shouldUseCurrentUserInSandbox()) {
128960
129272
  args.push("--user", "root");
128961
- const uid = execSync6("id -u").toString().trim();
128962
- const gid = execSync6("id -g").toString().trim();
129273
+ const uid = execSync7("id -u").toString().trim();
129274
+ const gid = execSync7("id -g").toString().trim();
128963
129275
  const username = "fss-link";
128964
129276
  const homeDir2 = getContainerPath(os29.homedir());
128965
129277
  const setupUserCommands = [
@@ -128988,7 +129300,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128988
129300
  });
128989
129301
  const stopProxy = () => {
128990
129302
  console.log("stopping proxy container ...");
128991
- execSync6(`${config.command} rm -f ${SANDBOX_PROXY_NAME}`);
129303
+ execSync7(`${config.command} rm -f ${SANDBOX_PROXY_NAME}`);
128992
129304
  };
128993
129305
  process.on("exit", stopProxy);
128994
129306
  process.on("SIGINT", stopProxy);