fss-link 1.3.0 → 1.4.0

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 (2) hide show
  1. package/bundle/fss-link.js +421 -299
  2. 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.0";
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
  });
@@ -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.0";
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 = "92ea8a8d";
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(
@@ -128462,7 +128584,7 @@ import { spawn as spawn7 } from "node:child_process";
128462
128584
  // packages/cli/src/utils/sandbox.ts
128463
128585
  var import_shell_quote4 = __toESM(require_shell_quote(), 1);
128464
128586
  init_settings();
128465
- import { exec as exec7, execSync as execSync6, spawn as spawn6 } from "node:child_process";
128587
+ import { exec as exec7, execSync as execSync7, spawn as spawn6 } from "node:child_process";
128466
128588
  import os29 from "node:os";
128467
128589
  import path80 from "node:path";
128468
128590
  import fs68 from "node:fs";
@@ -128612,7 +128734,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128612
128734
  "-D",
128613
128735
  `HOME_DIR=${fs68.realpathSync(os29.homedir())}`,
128614
128736
  "-D",
128615
- `CACHE_DIR=${fs68.realpathSync(execSync6(`getconf DARWIN_USER_CACHE_DIR`).toString().trim())}`
128737
+ `CACHE_DIR=${fs68.realpathSync(execSync7(`getconf DARWIN_USER_CACHE_DIR`).toString().trim())}`
128616
128738
  ];
128617
128739
  const MAX_INCLUDE_DIRS = 5;
128618
128740
  const targetDir = fs68.realpathSync(cliConfig?.getTargetDir() || "");
@@ -128725,7 +128847,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128725
128847
  console.error(`using ${projectSandboxDockerfile2} for sandbox`);
128726
128848
  buildArgs += `-f ${path80.resolve(projectSandboxDockerfile2)} -i ${image2}`;
128727
128849
  }
128728
- execSync6(
128850
+ execSync7(
128729
128851
  `cd ${gcRoot} && node scripts/build_sandbox.js -s ${buildArgs}`,
128730
128852
  {
128731
128853
  stdio: "inherit",
@@ -128836,12 +128958,12 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128836
128958
  args.push("--env", `no_proxy=${noProxy}`);
128837
128959
  }
128838
128960
  if (proxy) {
128839
- execSync6(
128961
+ execSync7(
128840
128962
  `${config.command} network inspect ${SANDBOX_NETWORK_NAME} || ${config.command} network create --internal ${SANDBOX_NETWORK_NAME}`
128841
128963
  );
128842
128964
  args.push("--network", SANDBOX_NETWORK_NAME);
128843
128965
  if (proxyCommand) {
128844
- execSync6(
128966
+ execSync7(
128845
128967
  `${config.command} network inspect ${SANDBOX_PROXY_NAME} || ${config.command} network create ${SANDBOX_PROXY_NAME}`
128846
128968
  );
128847
128969
  }
@@ -128849,7 +128971,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128849
128971
  }
128850
128972
  const imageName = parseImageName(image2);
128851
128973
  let index = 0;
128852
- const containerNameCheck = execSync6(
128974
+ const containerNameCheck = execSync7(
128853
128975
  `${config.command} ps -a --format "{{.Names}}"`
128854
128976
  ).toString().trim();
128855
128977
  while (containerNameCheck.includes(`${imageName}-${index}`)) {
@@ -128958,8 +129080,8 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128958
129080
  userFlag = "--user root";
128959
129081
  } else if (await shouldUseCurrentUserInSandbox()) {
128960
129082
  args.push("--user", "root");
128961
- const uid = execSync6("id -u").toString().trim();
128962
- const gid = execSync6("id -g").toString().trim();
129083
+ const uid = execSync7("id -u").toString().trim();
129084
+ const gid = execSync7("id -g").toString().trim();
128963
129085
  const username = "fss-link";
128964
129086
  const homeDir2 = getContainerPath(os29.homedir());
128965
129087
  const setupUserCommands = [
@@ -128988,7 +129110,7 @@ async function start_sandbox(config, nodeArgs = [], cliConfig) {
128988
129110
  });
128989
129111
  const stopProxy = () => {
128990
129112
  console.log("stopping proxy container ...");
128991
- execSync6(`${config.command} rm -f ${SANDBOX_PROXY_NAME}`);
129113
+ execSync7(`${config.command} rm -f ${SANDBOX_PROXY_NAME}`);
128992
129114
  };
128993
129115
  process.on("exit", stopProxy);
128994
129116
  process.on("SIGINT", stopProxy);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fss-link",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "engines": {
5
5
  "node": ">=20.0.0"
6
6
  },