neuronlayer 0.1.6 → 0.1.8

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.

Potentially problematic release.


This version of neuronlayer might be problematic. Click here for more details.

package/dist/index.js CHANGED
@@ -20821,8 +20821,8 @@ var StdioServerTransport = class {
20821
20821
  };
20822
20822
 
20823
20823
  // src/core/engine.ts
20824
- import { join as join14, basename as basename6 } from "path";
20825
- import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync10 } from "fs";
20824
+ import { join as join13, basename as basename6 } from "path";
20825
+ import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync10, renameSync } from "fs";
20826
20826
 
20827
20827
  // src/storage/database.ts
20828
20828
  import Database from "better-sqlite3";
@@ -21677,9 +21677,20 @@ var Tier2Storage = class {
21677
21677
  SELECT DISTINCT i.file_id as fileId, f.path as filePath
21678
21678
  FROM imports i
21679
21679
  JOIN files f ON i.file_id = f.id
21680
- WHERE i.imported_from LIKE ?
21680
+ WHERE i.imported_from = ?
21681
+ OR i.imported_from LIKE ?
21682
+ OR i.imported_from LIKE ?
21683
+ OR i.imported_from LIKE ?
21681
21684
  `);
21682
- return stmt.all(`%${modulePath}%`);
21685
+ return stmt.all(
21686
+ modulePath,
21687
+ `%/${modulePath}`,
21688
+ // ends with /modulePath
21689
+ `./${modulePath}`,
21690
+ // relative ./modulePath
21691
+ `../${modulePath}`
21692
+ // parent ../modulePath
21693
+ );
21683
21694
  }
21684
21695
  // Phase 2: Export operations
21685
21696
  clearExports(fileId) {
@@ -21735,7 +21746,10 @@ var Tier2Storage = class {
21735
21746
  const deps = [];
21736
21747
  for (const importer of importers) {
21737
21748
  const imports = this.getImportsByFile(importer.fileId);
21738
- const relevantImport = imports.find((i) => i.importedFrom.includes(fileName));
21749
+ const relevantImport = imports.find((i) => {
21750
+ const importedName = i.importedFrom.split(/[/\\]/).pop()?.replace(/\.[^.]+$/, "") || "";
21751
+ return importedName === fileName || i.importedFrom.endsWith(`/${fileName}`) || i.importedFrom.endsWith(`./${fileName}`);
21752
+ });
21739
21753
  if (relevantImport) {
21740
21754
  deps.push({
21741
21755
  file: importer.filePath,
@@ -21745,6 +21759,161 @@ var Tier2Storage = class {
21745
21759
  }
21746
21760
  return deps;
21747
21761
  }
21762
+ /**
21763
+ * Get ALL files affected by a change, walking the dependency graph.
21764
+ * depth=1 is direct importers only. depth=3 catches ripple effects.
21765
+ */
21766
+ getTransitiveDependents(filePath, maxDepth = 3) {
21767
+ const visited = /* @__PURE__ */ new Map();
21768
+ const queue = [{ path: filePath, depth: 0 }];
21769
+ while (queue.length > 0) {
21770
+ const current = queue.shift();
21771
+ if (current.depth >= maxDepth) continue;
21772
+ if (visited.has(current.path) && visited.get(current.path).depth <= current.depth) continue;
21773
+ const dependents = this.getFileDependents(current.path);
21774
+ for (const dep of dependents) {
21775
+ const existingDepth = visited.get(dep.file)?.depth ?? Infinity;
21776
+ const newDepth = current.depth + 1;
21777
+ if (newDepth < existingDepth) {
21778
+ visited.set(dep.file, { depth: newDepth, imports: dep.imports });
21779
+ queue.push({ path: dep.file, depth: newDepth });
21780
+ }
21781
+ }
21782
+ }
21783
+ visited.delete(filePath);
21784
+ return Array.from(visited.entries()).map(([file2, info]) => ({ file: file2, ...info })).sort((a, b) => a.depth - b.depth);
21785
+ }
21786
+ /**
21787
+ * Get the full import graph as an adjacency list.
21788
+ * Returns { file → [files it imports] } for the whole project.
21789
+ */
21790
+ getFullDependencyGraph() {
21791
+ const stmt = this.db.prepare(`
21792
+ SELECT f.path as filePath, i.imported_from as importedFrom
21793
+ FROM imports i
21794
+ JOIN files f ON i.file_id = f.id
21795
+ `);
21796
+ const rows = stmt.all();
21797
+ const graph = /* @__PURE__ */ new Map();
21798
+ for (const row of rows) {
21799
+ if (!graph.has(row.filePath)) graph.set(row.filePath, []);
21800
+ graph.get(row.filePath).push(row.importedFrom);
21801
+ }
21802
+ return graph;
21803
+ }
21804
+ /**
21805
+ * Find circular dependencies in the project.
21806
+ * Returns arrays of file paths that form cycles.
21807
+ */
21808
+ findCircularDependencies() {
21809
+ const graph = this.getFullDependencyGraph();
21810
+ const cycles = [];
21811
+ const visited = /* @__PURE__ */ new Set();
21812
+ const stack = /* @__PURE__ */ new Set();
21813
+ const dfs = (node, path) => {
21814
+ if (stack.has(node)) {
21815
+ const cycleStart = path.indexOf(node);
21816
+ if (cycleStart >= 0) {
21817
+ cycles.push(path.slice(cycleStart).concat(node));
21818
+ }
21819
+ return;
21820
+ }
21821
+ if (visited.has(node)) return;
21822
+ visited.add(node);
21823
+ stack.add(node);
21824
+ path.push(node);
21825
+ const deps = graph.get(node) || [];
21826
+ for (const dep of deps) {
21827
+ const resolved = this.resolveImportPath(node, dep);
21828
+ if (resolved) dfs(resolved, [...path]);
21829
+ }
21830
+ stack.delete(node);
21831
+ };
21832
+ for (const file2 of graph.keys()) {
21833
+ dfs(file2, []);
21834
+ }
21835
+ const uniqueCycles = [];
21836
+ const seen = /* @__PURE__ */ new Set();
21837
+ for (const cycle of cycles) {
21838
+ const normalized = [...cycle].sort().join("|");
21839
+ if (!seen.has(normalized)) {
21840
+ seen.add(normalized);
21841
+ uniqueCycles.push(cycle);
21842
+ }
21843
+ }
21844
+ return uniqueCycles;
21845
+ }
21846
+ /**
21847
+ * Resolve a relative import path to an actual file path in the database.
21848
+ */
21849
+ resolveImportPath(fromFile, importPath) {
21850
+ if (!importPath.startsWith(".") && !importPath.startsWith("/")) return null;
21851
+ const dir = fromFile.split(/[/\\]/).slice(0, -1).join("/");
21852
+ let resolved = importPath;
21853
+ if (importPath.startsWith("./")) {
21854
+ resolved = dir + "/" + importPath.slice(2);
21855
+ } else if (importPath.startsWith("../")) {
21856
+ const parts = dir.split("/");
21857
+ let impParts = importPath.split("/");
21858
+ while (impParts[0] === "..") {
21859
+ parts.pop();
21860
+ impParts.shift();
21861
+ }
21862
+ resolved = parts.join("/") + "/" + impParts.join("/");
21863
+ }
21864
+ const baseName = resolved.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/, "");
21865
+ const stmt = this.db.prepare(`
21866
+ SELECT path FROM files
21867
+ WHERE path = ? OR path = ? OR path = ? OR path = ?
21868
+ OR path = ? OR path = ?
21869
+ LIMIT 1
21870
+ `);
21871
+ const result = stmt.get(
21872
+ `${baseName}.ts`,
21873
+ `${baseName}.tsx`,
21874
+ `${baseName}.js`,
21875
+ `${baseName}.jsx`,
21876
+ `${baseName}/index.ts`,
21877
+ `${baseName}/index.js`
21878
+ );
21879
+ return result?.path || null;
21880
+ }
21881
+ /**
21882
+ * Resolve an import path to a file record in the database.
21883
+ * Used by indexer to build the dependencies table.
21884
+ */
21885
+ resolveImportToFile(sourceFilePath, importPath) {
21886
+ if (!importPath.startsWith(".") && !importPath.startsWith("/")) return null;
21887
+ const sourceDir = sourceFilePath.split(/[/\\]/).slice(0, -1).join("/");
21888
+ let resolved = importPath;
21889
+ if (importPath.startsWith("./")) {
21890
+ resolved = sourceDir + "/" + importPath.slice(2);
21891
+ } else if (importPath.startsWith("../")) {
21892
+ const parts = sourceDir.split("/");
21893
+ let impParts = importPath.split("/");
21894
+ while (impParts[0] === "..") {
21895
+ parts.pop();
21896
+ impParts.shift();
21897
+ }
21898
+ resolved = parts.join("/") + "/" + impParts.join("/");
21899
+ }
21900
+ resolved = resolved.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/, "");
21901
+ const stmt = this.db.prepare(`
21902
+ SELECT id, path FROM files
21903
+ WHERE path = ? OR path = ? OR path = ? OR path = ?
21904
+ OR path = ? OR path = ?
21905
+ LIMIT 1
21906
+ `);
21907
+ const result = stmt.get(
21908
+ `${resolved}.ts`,
21909
+ `${resolved}.tsx`,
21910
+ `${resolved}.js`,
21911
+ `${resolved}.jsx`,
21912
+ `${resolved}/index.ts`,
21913
+ `${resolved}/index.js`
21914
+ );
21915
+ return result || null;
21916
+ }
21748
21917
  };
21749
21918
 
21750
21919
  // src/storage/tier3.ts
@@ -21903,8 +22072,6 @@ var EmbeddingGenerator = class {
21903
22072
  };
21904
22073
 
21905
22074
  // src/indexing/ast.ts
21906
- import Parser from "web-tree-sitter";
21907
- import { join as join2 } from "path";
21908
22075
  var LANGUAGE_CONFIGS = {
21909
22076
  typescript: {
21910
22077
  wasmFile: "tree-sitter-typescript.wasm",
@@ -21967,6 +22134,30 @@ var LANGUAGE_CONFIGS = {
21967
22134
  (import_from_statement) @import
21968
22135
  `
21969
22136
  }
22137
+ },
22138
+ go: {
22139
+ wasmFile: "tree-sitter-go.wasm",
22140
+ extensions: [".go"],
22141
+ queries: {
22142
+ functions: `(function_declaration name: (identifier) @name) @func`,
22143
+ classes: `(type_declaration (type_spec name: (type_identifier) @name type: (struct_type))) @class`
22144
+ }
22145
+ },
22146
+ rust: {
22147
+ wasmFile: "tree-sitter-rust.wasm",
22148
+ extensions: [".rs"],
22149
+ queries: {
22150
+ functions: `(function_item name: (identifier) @name) @func`,
22151
+ classes: `(struct_item name: (type_identifier) @name) @class`
22152
+ }
22153
+ },
22154
+ java: {
22155
+ wasmFile: "tree-sitter-java.wasm",
22156
+ extensions: [".java"],
22157
+ queries: {
22158
+ functions: `(method_declaration name: (identifier) @name) @func`,
22159
+ classes: `(class_declaration name: (identifier) @name) @class`
22160
+ }
21970
22161
  }
21971
22162
  };
21972
22163
  var ASTParser = class {
@@ -21979,33 +22170,10 @@ var ASTParser = class {
21979
22170
  }
21980
22171
  async initialize() {
21981
22172
  if (this.initialized) return;
21982
- try {
21983
- await Parser.init();
21984
- this.parser = new Parser();
21985
- this.initialized = true;
21986
- console.error("AST Parser initialized");
21987
- } catch (error2) {
21988
- console.error("Failed to initialize AST parser:", error2);
21989
- throw error2;
21990
- }
22173
+ this.initialized = true;
21991
22174
  }
21992
- async loadLanguage(langName) {
21993
- if (this.languages.has(langName)) {
21994
- return this.languages.get(langName);
21995
- }
21996
- const config2 = LANGUAGE_CONFIGS[langName];
21997
- if (!config2) {
21998
- return null;
21999
- }
22000
- try {
22001
- const wasmDir = join2(this.dataDir, "wasm");
22002
- const wasmPath = join2(wasmDir, config2.wasmFile);
22003
- console.error(`Language ${langName} WASM not available yet`);
22004
- return null;
22005
- } catch (error2) {
22006
- console.error(`Failed to load language ${langName}:`, error2);
22007
- return null;
22008
- }
22175
+ async loadLanguage(_langName) {
22176
+ return null;
22009
22177
  }
22010
22178
  getLanguageForFile(filePath) {
22011
22179
  const ext = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
@@ -22022,7 +22190,9 @@ var ASTParser = class {
22022
22190
  }
22023
22191
  return this.parseWithRegex(filePath, content);
22024
22192
  }
22025
- // Regex-based parsing fallback (works without WASM)
22193
+ // Regex-based parsing for symbol extraction
22194
+ // Handles: functions, classes, interfaces, types, imports, exports
22195
+ // Supports: TypeScript, JavaScript, Python, Go, Rust, Java
22026
22196
  parseWithRegex(filePath, content) {
22027
22197
  const symbols = [];
22028
22198
  const imports = [];
@@ -22033,39 +22203,62 @@ var ASTParser = class {
22033
22203
  this.parseTypeScriptJS(filePath, content, lines, symbols, imports, exports);
22034
22204
  } else if (lang === "python") {
22035
22205
  this.parsePython(filePath, content, lines, symbols, imports, exports);
22206
+ } else if (lang === "go") {
22207
+ this.parseGo(filePath, content, lines, symbols, imports, exports);
22208
+ } else if (lang === "rust") {
22209
+ this.parseRust(filePath, content, lines, symbols, imports, exports);
22210
+ } else if (lang === "java") {
22211
+ this.parseJava(filePath, content, lines, symbols, imports, exports);
22036
22212
  }
22037
22213
  return { symbols, imports, exports };
22038
22214
  }
22039
22215
  parseTypeScriptJS(filePath, content, lines, symbols, imports, exports) {
22040
22216
  const patterns = {
22041
- // Functions: function name(), const name = () =>, const name = function()
22042
- function: /^(?:export\s+)?(?:async\s+)?function\s+(\w+)/,
22043
- arrowFunc: /^(?:export\s+)?(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?(?:\([^)]*\)|[^=])\s*=>/,
22217
+ // Functions: function name(), export default function name(), const name = () =>
22218
+ function: /^(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s+(\w+)/,
22219
+ // Arrow functions: handles type annotations and destructured params
22220
+ arrowFunc: /^(?:export\s+)?(?:const|let|var)\s+(\w+)\s*(?::\s*[^=]+)?\s*=\s*(?:async\s+)?(?:\([^)]*\)|[a-zA-Z_]\w*)\s*(?::\s*[^=]+)?\s*=>/,
22044
22221
  // Classes
22045
- class: /^(?:export\s+)?(?:abstract\s+)?class\s+(\w+)/,
22222
+ class: /^(?:export\s+)?(?:default\s+)?(?:abstract\s+)?class\s+(\w+)/,
22046
22223
  // Interfaces (TS only)
22047
22224
  interface: /^(?:export\s+)?interface\s+(\w+)/,
22048
22225
  // Types (TS only)
22049
- type: /^(?:export\s+)?type\s+(\w+)\s*=/,
22050
- // Imports
22051
- import: /^import\s+(?:(\w+)(?:\s*,\s*)?)?(?:\{([^}]+)\})?\s*from\s*['"]([^'"]+)['"]/,
22052
- importAll: /^import\s+\*\s+as\s+(\w+)\s+from\s*['"]([^'"]+)['"]/,
22226
+ type: /^(?:export\s+)?type\s+(\w+)\s*(?:<[^>]*>)?\s*=/,
22227
+ // Imports - supports 'import type'
22228
+ import: /^import\s+(?:type\s+)?(?:(\w+)(?:\s*,\s*)?)?(?:\{([^}]+)\})?\s*from\s*['"]([^'"]+)['"]/,
22229
+ importAll: /^import\s+(?:type\s+)?\*\s+as\s+(\w+)\s+from\s*['"]([^'"]+)['"]/,
22053
22230
  importSideEffect: /^import\s*['"]([^'"]+)['"]/,
22054
22231
  // Exports
22055
- exportNamed: /^export\s+\{([^}]+)\}/,
22232
+ exportNamed: /^export\s+(?:type\s+)?\{([^}]+)\}/,
22056
22233
  exportDefault: /^export\s+default\s+(?:class|function|const|let|var)?\s*(\w+)?/,
22057
22234
  exportDirect: /^export\s+(?:const|let|var|function|class|interface|type|enum|async\s+function)\s+(\w+)/,
22058
22235
  // Enums (TS)
22059
22236
  enum: /^(?:export\s+)?(?:const\s+)?enum\s+(\w+)/,
22060
- // Methods inside classes (simplified)
22061
- method: /^\s+(?:async\s+)?(?:static\s+)?(?:private\s+|public\s+|protected\s+)?(\w+)\s*\([^)]*\)\s*[:{]/
22237
+ // Methods inside classes - handles generics, readonly, and all modifiers
22238
+ method: /^\s+(?:async\s+)?(?:static\s+)?(?:readonly\s+)?(?:private\s+|public\s+|protected\s+)?(?:get\s+|set\s+)?(\w+)\s*(?:<[^>]+>)?\s*\(/
22062
22239
  };
22063
22240
  let currentClass = null;
22064
22241
  let braceDepth = 0;
22242
+ let inBlockComment = false;
22065
22243
  for (let i = 0; i < lines.length; i++) {
22066
22244
  const line = lines[i] || "";
22067
22245
  const trimmed = line.trim();
22068
22246
  const lineNum = i + 1;
22247
+ if (inBlockComment) {
22248
+ if (trimmed.includes("*/")) {
22249
+ inBlockComment = false;
22250
+ }
22251
+ continue;
22252
+ }
22253
+ if (trimmed.startsWith("//")) {
22254
+ continue;
22255
+ }
22256
+ if (trimmed.startsWith("/*")) {
22257
+ if (!trimmed.includes("*/")) {
22258
+ inBlockComment = true;
22259
+ }
22260
+ continue;
22261
+ }
22069
22262
  braceDepth += (line.match(/\{/g) || []).length;
22070
22263
  braceDepth -= (line.match(/\}/g) || []).length;
22071
22264
  if (currentClass && braceDepth === 0) {
@@ -22075,9 +22268,6 @@ var ASTParser = class {
22075
22268
  }
22076
22269
  currentClass = null;
22077
22270
  }
22078
- if (trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*")) {
22079
- continue;
22080
- }
22081
22271
  let match = trimmed.match(patterns.function);
22082
22272
  if (match && match[1]) {
22083
22273
  symbols.push({
@@ -22314,6 +22504,224 @@ var ASTParser = class {
22314
22504
  }
22315
22505
  }
22316
22506
  }
22507
+ parseGo(filePath, content, lines, symbols, imports, exports) {
22508
+ let inImportBlock = false;
22509
+ for (let i = 0; i < lines.length; i++) {
22510
+ const line = lines[i] || "";
22511
+ const trimmed = line.trim();
22512
+ const lineNum = i + 1;
22513
+ if (trimmed.startsWith("//")) continue;
22514
+ if (trimmed === "import (") {
22515
+ inImportBlock = true;
22516
+ continue;
22517
+ }
22518
+ if (inImportBlock && trimmed === ")") {
22519
+ inImportBlock = false;
22520
+ continue;
22521
+ }
22522
+ const importMatch = inImportBlock ? trimmed.match(/^(?:(\w+)\s+)?"([^"]+)"/) : trimmed.match(/^import\s+(?:(\w+)\s+)?"([^"]+)"/);
22523
+ if (importMatch) {
22524
+ const alias = importMatch[1];
22525
+ const path = importMatch[2] || "";
22526
+ const pkg = alias || path.split("/").pop() || "";
22527
+ imports.push({
22528
+ fileId: 0,
22529
+ filePath,
22530
+ importedFrom: path,
22531
+ importedSymbols: [pkg],
22532
+ isDefault: false,
22533
+ isNamespace: false,
22534
+ lineNumber: lineNum
22535
+ });
22536
+ continue;
22537
+ }
22538
+ const funcMatch = trimmed.match(/^func\s+(?:\((\w+)\s+\*?(\w+)\)\s+)?(\w+)\s*\(/);
22539
+ if (funcMatch) {
22540
+ const receiver = funcMatch[2];
22541
+ const name = receiver ? `${receiver}.${funcMatch[3]}` : funcMatch[3] || "";
22542
+ symbols.push({
22543
+ fileId: 0,
22544
+ filePath,
22545
+ kind: receiver ? "method" : "function",
22546
+ name,
22547
+ lineStart: lineNum,
22548
+ lineEnd: this.findBlockEnd(lines, i),
22549
+ exported: /^[A-Z]/.test(funcMatch[3] || ""),
22550
+ signature: trimmed.split("{")[0]?.trim()
22551
+ });
22552
+ continue;
22553
+ }
22554
+ const structMatch = trimmed.match(/^type\s+(\w+)\s+struct\s*\{?/);
22555
+ if (structMatch) {
22556
+ symbols.push({
22557
+ fileId: 0,
22558
+ filePath,
22559
+ kind: "class",
22560
+ name: structMatch[1] || "",
22561
+ lineStart: lineNum,
22562
+ lineEnd: this.findBlockEnd(lines, i),
22563
+ exported: /^[A-Z]/.test(structMatch[1] || "")
22564
+ });
22565
+ continue;
22566
+ }
22567
+ const ifaceMatch = trimmed.match(/^type\s+(\w+)\s+interface\s*\{?/);
22568
+ if (ifaceMatch) {
22569
+ symbols.push({
22570
+ fileId: 0,
22571
+ filePath,
22572
+ kind: "interface",
22573
+ name: ifaceMatch[1] || "",
22574
+ lineStart: lineNum,
22575
+ lineEnd: this.findBlockEnd(lines, i),
22576
+ exported: /^[A-Z]/.test(ifaceMatch[1] || "")
22577
+ });
22578
+ }
22579
+ }
22580
+ }
22581
+ parseRust(filePath, content, lines, symbols, imports, exports) {
22582
+ for (let i = 0; i < lines.length; i++) {
22583
+ const line = lines[i] || "";
22584
+ const trimmed = line.trim();
22585
+ const lineNum = i + 1;
22586
+ if (trimmed.startsWith("//")) continue;
22587
+ const fnMatch = trimmed.match(/^(?:pub\s+)?(?:async\s+)?fn\s+(\w+)/);
22588
+ if (fnMatch) {
22589
+ symbols.push({
22590
+ fileId: 0,
22591
+ filePath,
22592
+ kind: "function",
22593
+ name: fnMatch[1] || "",
22594
+ lineStart: lineNum,
22595
+ lineEnd: this.findBlockEnd(lines, i),
22596
+ exported: trimmed.startsWith("pub"),
22597
+ signature: trimmed.split("{")[0]?.trim()
22598
+ });
22599
+ continue;
22600
+ }
22601
+ const structMatch = trimmed.match(/^(?:pub\s+)?struct\s+(\w+)/);
22602
+ if (structMatch) {
22603
+ symbols.push({
22604
+ fileId: 0,
22605
+ filePath,
22606
+ kind: "class",
22607
+ name: structMatch[1] || "",
22608
+ lineStart: lineNum,
22609
+ lineEnd: this.findBlockEnd(lines, i),
22610
+ exported: trimmed.startsWith("pub")
22611
+ });
22612
+ continue;
22613
+ }
22614
+ const enumMatch = trimmed.match(/^(?:pub\s+)?enum\s+(\w+)/);
22615
+ if (enumMatch) {
22616
+ symbols.push({
22617
+ fileId: 0,
22618
+ filePath,
22619
+ kind: "enum",
22620
+ name: enumMatch[1] || "",
22621
+ lineStart: lineNum,
22622
+ lineEnd: this.findBlockEnd(lines, i),
22623
+ exported: trimmed.startsWith("pub")
22624
+ });
22625
+ continue;
22626
+ }
22627
+ const traitMatch = trimmed.match(/^(?:pub\s+)?trait\s+(\w+)/);
22628
+ if (traitMatch) {
22629
+ symbols.push({
22630
+ fileId: 0,
22631
+ filePath,
22632
+ kind: "interface",
22633
+ name: traitMatch[1] || "",
22634
+ lineStart: lineNum,
22635
+ lineEnd: this.findBlockEnd(lines, i),
22636
+ exported: trimmed.startsWith("pub")
22637
+ });
22638
+ continue;
22639
+ }
22640
+ const implMatch = trimmed.match(/^impl\s+(?:<[^>]+>\s+)?(?:(\w+)\s+for\s+)?(\w+)/);
22641
+ if (implMatch) {
22642
+ const traitName = implMatch[1];
22643
+ const typeName = implMatch[2] || "";
22644
+ const name = traitName ? `${traitName} for ${typeName}` : typeName;
22645
+ symbols.push({
22646
+ fileId: 0,
22647
+ filePath,
22648
+ kind: "class",
22649
+ name: `impl ${name}`,
22650
+ lineStart: lineNum,
22651
+ lineEnd: this.findBlockEnd(lines, i),
22652
+ exported: false
22653
+ });
22654
+ continue;
22655
+ }
22656
+ const useMatch = trimmed.match(/^(?:pub\s+)?use\s+(.+);/);
22657
+ if (useMatch) {
22658
+ const path = (useMatch[1] || "").replace(/::/g, "/");
22659
+ imports.push({
22660
+ fileId: 0,
22661
+ filePath,
22662
+ importedFrom: path,
22663
+ importedSymbols: [path.split("/").pop()?.replace(/[{}]/g, "") || ""],
22664
+ isDefault: false,
22665
+ isNamespace: path.includes("*"),
22666
+ lineNumber: lineNum
22667
+ });
22668
+ }
22669
+ }
22670
+ }
22671
+ parseJava(filePath, content, lines, symbols, imports, exports) {
22672
+ let currentClass = null;
22673
+ for (let i = 0; i < lines.length; i++) {
22674
+ const line = lines[i] || "";
22675
+ const trimmed = line.trim();
22676
+ const lineNum = i + 1;
22677
+ if (trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*")) continue;
22678
+ const importMatch = trimmed.match(/^import\s+(?:static\s+)?([^;]+);/);
22679
+ if (importMatch) {
22680
+ const path = importMatch[1] || "";
22681
+ imports.push({
22682
+ fileId: 0,
22683
+ filePath,
22684
+ importedFrom: path,
22685
+ importedSymbols: [path.split(".").pop() || ""],
22686
+ isDefault: false,
22687
+ isNamespace: path.endsWith("*"),
22688
+ lineNumber: lineNum
22689
+ });
22690
+ continue;
22691
+ }
22692
+ const classMatch = trimmed.match(/^(?:public\s+|private\s+|protected\s+)?(?:abstract\s+)?(?:final\s+)?(class|interface|enum)\s+(\w+)/);
22693
+ if (classMatch) {
22694
+ currentClass = classMatch[2] || "";
22695
+ symbols.push({
22696
+ fileId: 0,
22697
+ filePath,
22698
+ kind: classMatch[1] === "interface" ? "interface" : classMatch[1] === "enum" ? "enum" : "class",
22699
+ name: currentClass,
22700
+ lineStart: lineNum,
22701
+ lineEnd: this.findBlockEnd(lines, i),
22702
+ exported: trimmed.includes("public")
22703
+ });
22704
+ continue;
22705
+ }
22706
+ const methodMatch = trimmed.match(/^(?:public\s+|private\s+|protected\s+)?(?:static\s+)?(?:final\s+)?(?:synchronized\s+)?(?:abstract\s+)?(?:<[^>]+>\s+)?(\w+(?:<[^>]+>)?)\s+(\w+)\s*\(/);
22707
+ if (methodMatch && currentClass && !["if", "for", "while", "switch", "catch", "class", "interface", "enum"].includes(methodMatch[2] || "")) {
22708
+ const returnType = methodMatch[1];
22709
+ const methodName = methodMatch[2] || "";
22710
+ if (methodName !== currentClass) {
22711
+ symbols.push({
22712
+ fileId: 0,
22713
+ filePath,
22714
+ kind: "method",
22715
+ name: `${currentClass}.${methodName}`,
22716
+ lineStart: lineNum,
22717
+ lineEnd: this.findBlockEnd(lines, i),
22718
+ exported: trimmed.includes("public"),
22719
+ signature: `${returnType} ${methodName}(...)`
22720
+ });
22721
+ }
22722
+ }
22723
+ }
22724
+ }
22317
22725
  findBlockEnd(lines, startIndex) {
22318
22726
  let braceCount = 0;
22319
22727
  let started = false;
@@ -22634,11 +23042,31 @@ var Indexer = class extends EventEmitter2 {
22634
23042
  const exportsWithFileId = parsed.exports.map((e) => ({ ...e, fileId }));
22635
23043
  this.tier2.insertExports(exportsWithFileId);
22636
23044
  }
23045
+ if (parsed.imports.length > 0) {
23046
+ this.tier2.clearDependencies(fileId);
23047
+ for (const imp of parsed.imports) {
23048
+ const targetFile = this.tier2.resolveImportToFile(relativePath, imp.importedFrom);
23049
+ if (targetFile) {
23050
+ this.tier2.addDependency(fileId, targetFile.id, "imports");
23051
+ }
23052
+ }
23053
+ }
22637
23054
  }
22638
23055
  } catch (astError) {
22639
23056
  console.error(`AST parsing failed for ${relativePath}:`, astError);
22640
23057
  }
22641
23058
  this.emit("fileIndexed", relativePath);
23059
+ if (!this.isIndexing) {
23060
+ const dependents = this.tier2.getFileDependents(relativePath);
23061
+ if (dependents.length > 0) {
23062
+ this.emit("fileImpact", {
23063
+ file: relativePath,
23064
+ affectedFiles: dependents.map((d) => d.file),
23065
+ affectedCount: dependents.length,
23066
+ imports: dependents.map((d) => ({ file: d.file, symbols: d.imports }))
23067
+ });
23068
+ }
23069
+ }
22642
23070
  return true;
22643
23071
  } catch (error2) {
22644
23072
  console.error(`Error indexing ${absolutePath}:`, error2);
@@ -22735,7 +23163,7 @@ var Indexer = class extends EventEmitter2 {
22735
23163
  };
22736
23164
 
22737
23165
  // src/core/context.ts
22738
- import { dirname as dirname4, basename } from "path";
23166
+ import { dirname as dirname3, basename } from "path";
22739
23167
 
22740
23168
  // src/utils/tokens.ts
22741
23169
  var AVG_CHARS_PER_TOKEN = 4;
@@ -22931,7 +23359,7 @@ ${result.preview}
22931
23359
  const filesViewed = this.tier1.getFilesViewed();
22932
23360
  return results.map((r) => {
22933
23361
  let score = r.similarity;
22934
- if (currentFile && dirname4(r.file) === dirname4(currentFile)) {
23362
+ if (currentFile && dirname3(r.file) === dirname3(currentFile)) {
22935
23363
  score *= 1.5;
22936
23364
  }
22937
23365
  const hoursSinceModified = (Date.now() - r.lastModified) / 36e5;
@@ -23033,7 +23461,7 @@ ${tags.join(" ")}`;
23033
23461
  // src/core/decision-extractor.ts
23034
23462
  import { execSync } from "child_process";
23035
23463
  import { readFileSync as readFileSync3, existsSync as existsSync3 } from "fs";
23036
- import { join as join4 } from "path";
23464
+ import { join as join3 } from "path";
23037
23465
  import { glob as glob2 } from "glob";
23038
23466
  import { randomUUID as randomUUID2 } from "crypto";
23039
23467
  var COMMIT_PATTERNS = [
@@ -23073,7 +23501,7 @@ var DecisionExtractor = class {
23073
23501
  isGitRepo;
23074
23502
  constructor(projectPath) {
23075
23503
  this.projectPath = projectPath;
23076
- this.isGitRepo = existsSync3(join4(projectPath, ".git"));
23504
+ this.isGitRepo = existsSync3(join3(projectPath, ".git"));
23077
23505
  }
23078
23506
  async extractAll() {
23079
23507
  const decisions = [];
@@ -23898,7 +24326,7 @@ var FileSummarizer = class {
23898
24326
 
23899
24327
  // src/core/project-manager.ts
23900
24328
  import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2, readdirSync } from "fs";
23901
- import { join as join5, basename as basename2, resolve } from "path";
24329
+ import { join as join4, basename as basename2, resolve } from "path";
23902
24330
  import { createHash as createHash3 } from "crypto";
23903
24331
  import { homedir } from "os";
23904
24332
  import Database2 from "better-sqlite3";
@@ -23907,8 +24335,8 @@ var ProjectManager = class {
23907
24335
  registry;
23908
24336
  baseDataDir;
23909
24337
  constructor() {
23910
- this.baseDataDir = join5(homedir(), ".memorylayer");
23911
- this.registryPath = join5(this.baseDataDir, "registry.json");
24338
+ this.baseDataDir = join4(homedir(), ".memorylayer");
24339
+ this.registryPath = join4(this.baseDataDir, "registry.json");
23912
24340
  if (!existsSync4(this.baseDataDir)) {
23913
24341
  mkdirSync3(this.baseDataDir, { recursive: true });
23914
24342
  }
@@ -23943,7 +24371,7 @@ var ProjectManager = class {
23943
24371
  getProjectDataDir(projectPath) {
23944
24372
  const projectId = this.generateProjectId(projectPath);
23945
24373
  const projectName = basename2(projectPath);
23946
- return join5(this.baseDataDir, "projects", `${projectName}-${projectId}`);
24374
+ return join4(this.baseDataDir, "projects", `${projectName}-${projectId}`);
23947
24375
  }
23948
24376
  // Register a new project or update existing
23949
24377
  registerProject(projectPath) {
@@ -24057,17 +24485,17 @@ var ProjectManager = class {
24057
24485
  const discovered = [];
24058
24486
  const homeDir = homedir();
24059
24487
  const searchDirs = [
24060
- join5(homeDir, "projects"),
24061
- join5(homeDir, "Projects"),
24062
- join5(homeDir, "code"),
24063
- join5(homeDir, "Code"),
24064
- join5(homeDir, "dev"),
24065
- join5(homeDir, "Development"),
24066
- join5(homeDir, "workspace"),
24067
- join5(homeDir, "repos"),
24068
- join5(homeDir, "github"),
24069
- join5(homeDir, "Desktop"),
24070
- join5(homeDir, "Documents")
24488
+ join4(homeDir, "projects"),
24489
+ join4(homeDir, "Projects"),
24490
+ join4(homeDir, "code"),
24491
+ join4(homeDir, "Code"),
24492
+ join4(homeDir, "dev"),
24493
+ join4(homeDir, "Development"),
24494
+ join4(homeDir, "workspace"),
24495
+ join4(homeDir, "repos"),
24496
+ join4(homeDir, "github"),
24497
+ join4(homeDir, "Desktop"),
24498
+ join4(homeDir, "Documents")
24071
24499
  ];
24072
24500
  for (const searchDir of searchDirs) {
24073
24501
  if (!existsSync4(searchDir)) continue;
@@ -24075,7 +24503,7 @@ var ProjectManager = class {
24075
24503
  const entries = readdirSync(searchDir, { withFileTypes: true });
24076
24504
  for (const entry of entries) {
24077
24505
  if (!entry.isDirectory()) continue;
24078
- const projectPath = join5(searchDir, entry.name);
24506
+ const projectPath = join4(searchDir, entry.name);
24079
24507
  const projectIndicators = [
24080
24508
  "package.json",
24081
24509
  "Cargo.toml",
@@ -24087,7 +24515,7 @@ var ProjectManager = class {
24087
24515
  ".git"
24088
24516
  ];
24089
24517
  const isProject = projectIndicators.some(
24090
- (indicator) => existsSync4(join5(projectPath, indicator))
24518
+ (indicator) => existsSync4(join4(projectPath, indicator))
24091
24519
  );
24092
24520
  if (isProject) {
24093
24521
  discovered.push(projectPath);
@@ -24102,7 +24530,10 @@ var ProjectManager = class {
24102
24530
  getProjectDatabases() {
24103
24531
  const result = [];
24104
24532
  for (const project of this.listProjects()) {
24105
- const dbPath = join5(project.dataDir, "memorylayer.db");
24533
+ let dbPath = join4(project.dataDir, "neuronlayer.db");
24534
+ if (!existsSync4(dbPath)) {
24535
+ dbPath = join4(project.dataDir, "memorylayer.db");
24536
+ }
24106
24537
  if (existsSync4(dbPath)) {
24107
24538
  try {
24108
24539
  const db = new Database2(dbPath, { readonly: true });
@@ -24126,7 +24557,7 @@ var ProjectManager = class {
24126
24557
 
24127
24558
  // src/core/adr-exporter.ts
24128
24559
  import { existsSync as existsSync5, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "fs";
24129
- import { join as join6 } from "path";
24560
+ import { join as join5 } from "path";
24130
24561
  var ADRExporter = class {
24131
24562
  projectPath;
24132
24563
  constructor(projectPath) {
@@ -24134,7 +24565,7 @@ var ADRExporter = class {
24134
24565
  }
24135
24566
  // Export a single decision to ADR file
24136
24567
  exportDecision(decision, options = {}) {
24137
- const outputDir = options.outputDir || join6(this.projectPath, "docs", "decisions");
24568
+ const outputDir = options.outputDir || join5(this.projectPath, "docs", "decisions");
24138
24569
  const format = options.format || "madr";
24139
24570
  if (!existsSync5(outputDir)) {
24140
24571
  mkdirSync4(outputDir, { recursive: true });
@@ -24143,7 +24574,7 @@ var ADRExporter = class {
24143
24574
  const nextNumber = this.getNextADRNumber(existingFiles);
24144
24575
  const slug = this.slugify(decision.title);
24145
24576
  const filename = `${String(nextNumber).padStart(4, "0")}-${slug}.md`;
24146
- const filePath = join6(outputDir, filename);
24577
+ const filePath = join5(outputDir, filename);
24147
24578
  let content;
24148
24579
  switch (format) {
24149
24580
  case "madr":
@@ -24163,7 +24594,7 @@ var ADRExporter = class {
24163
24594
  // Export all decisions
24164
24595
  exportAllDecisions(decisions, options = {}) {
24165
24596
  const exportedFiles = [];
24166
- const outputDir = options.outputDir || join6(this.projectPath, "docs", "decisions");
24597
+ const outputDir = options.outputDir || join5(this.projectPath, "docs", "decisions");
24167
24598
  const sorted = [...decisions].sort(
24168
24599
  (a, b) => a.createdAt.getTime() - b.createdAt.getTime()
24169
24600
  );
@@ -24179,7 +24610,7 @@ var ADRExporter = class {
24179
24610
  }
24180
24611
  // Generate index file
24181
24612
  generateIndex(decisions, outputDir) {
24182
- const indexPath = join6(outputDir, "README.md");
24613
+ const indexPath = join5(outputDir, "README.md");
24183
24614
  const lines = [
24184
24615
  "# Architecture Decision Records",
24185
24616
  "",
@@ -24331,7 +24762,7 @@ ${decision.files.map((f) => `- \`${f}\``).join("\n")}
24331
24762
  // src/core/feature-context.ts
24332
24763
  import { EventEmitter as EventEmitter3 } from "events";
24333
24764
  import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync5 } from "fs";
24334
- import { dirname as dirname5, join as join7, basename as basename3 } from "path";
24765
+ import { dirname as dirname4, join as join6, basename as basename3 } from "path";
24335
24766
  import { randomUUID as randomUUID3 } from "crypto";
24336
24767
  var MAX_FILES = 20;
24337
24768
  var MAX_CHANGES = 50;
@@ -24351,7 +24782,7 @@ var FeatureContextManager = class extends EventEmitter3 {
24351
24782
  super();
24352
24783
  this.projectPath = projectPath;
24353
24784
  this.dataDir = dataDir;
24354
- this.persistPath = join7(dataDir, "feature-context.json");
24785
+ this.persistPath = join6(dataDir, "feature-context.json");
24355
24786
  this.load();
24356
24787
  this.startInactivityTimer();
24357
24788
  }
@@ -24580,7 +25011,7 @@ var FeatureContextManager = class extends EventEmitter3 {
24580
25011
  // ========== PERSISTENCE ==========
24581
25012
  save() {
24582
25013
  try {
24583
- const dir = dirname5(this.persistPath);
25014
+ const dir = dirname4(this.persistPath);
24584
25015
  if (!existsSync6(dir)) {
24585
25016
  mkdirSync5(dir, { recursive: true });
24586
25017
  }
@@ -24643,7 +25074,7 @@ var FeatureContextManager = class extends EventEmitter3 {
24643
25074
  if (relativePath.startsWith(this.projectPath)) {
24644
25075
  return relativePath;
24645
25076
  }
24646
- return join7(this.projectPath, relativePath);
25077
+ return join6(this.projectPath, relativePath);
24647
25078
  }
24648
25079
  // ========== CONTEXT RESURRECTION ==========
24649
25080
  /**
@@ -24842,7 +25273,7 @@ var FeatureContextManager = class extends EventEmitter3 {
24842
25273
 
24843
25274
  // src/core/living-docs/architecture-generator.ts
24844
25275
  import { existsSync as existsSync7, readFileSync as readFileSync7, readdirSync as readdirSync2 } from "fs";
24845
- import { basename as basename4, join as join8 } from "path";
25276
+ import { basename as basename4, join as join7 } from "path";
24846
25277
  var ArchitectureGenerator = class _ArchitectureGenerator {
24847
25278
  projectPath;
24848
25279
  tier2;
@@ -24920,7 +25351,7 @@ var ArchitectureGenerator = class _ArchitectureGenerator {
24920
25351
  detectLayers() {
24921
25352
  const layers = [];
24922
25353
  const layerMap = /* @__PURE__ */ new Map();
24923
- const srcDir = existsSync7(join8(this.projectPath, "src")) ? join8(this.projectPath, "src") : this.projectPath;
25354
+ const srcDir = existsSync7(join7(this.projectPath, "src")) ? join7(this.projectPath, "src") : this.projectPath;
24924
25355
  try {
24925
25356
  const entries = readdirSync2(srcDir, { withFileTypes: true });
24926
25357
  for (const entry of entries) {
@@ -24928,7 +25359,7 @@ var ArchitectureGenerator = class _ArchitectureGenerator {
24928
25359
  const dirName = entry.name.toLowerCase();
24929
25360
  const layerName = _ArchitectureGenerator.LAYER_MAPPING[dirName];
24930
25361
  if (layerName) {
24931
- const dirPath = join8(srcDir, entry.name);
25362
+ const dirPath = join7(srcDir, entry.name);
24932
25363
  const relativePath = dirPath.replace(this.projectPath, "").replace(/^[/\\]/, "");
24933
25364
  const files = this.getFilesInDirectory(relativePath);
24934
25365
  if (files.length > 0) {
@@ -24971,12 +25402,12 @@ var ArchitectureGenerator = class _ArchitectureGenerator {
24971
25402
  }
24972
25403
  getFilesInDirectory(relativePath) {
24973
25404
  const files = [];
24974
- const absolutePath = join8(this.projectPath, relativePath);
25405
+ const absolutePath = join7(this.projectPath, relativePath);
24975
25406
  try {
24976
25407
  const entries = readdirSync2(absolutePath, { withFileTypes: true });
24977
25408
  for (const entry of entries) {
24978
25409
  if (entry.isFile() && this.isCodeFile(entry.name)) {
24979
- files.push(join8(relativePath, entry.name));
25410
+ files.push(join7(relativePath, entry.name));
24980
25411
  }
24981
25412
  }
24982
25413
  } catch {
@@ -25105,7 +25536,7 @@ var ArchitectureGenerator = class _ArchitectureGenerator {
25105
25536
  }
25106
25537
  getProjectDependencies() {
25107
25538
  const deps = [];
25108
- const packageJsonPath = join8(this.projectPath, "package.json");
25539
+ const packageJsonPath = join7(this.projectPath, "package.json");
25109
25540
  if (existsSync7(packageJsonPath)) {
25110
25541
  try {
25111
25542
  const pkg = JSON.parse(readFileSync7(packageJsonPath, "utf-8"));
@@ -25133,7 +25564,7 @@ var ArchitectureGenerator = class _ArchitectureGenerator {
25133
25564
  } catch {
25134
25565
  }
25135
25566
  }
25136
- const requirementsPath = join8(this.projectPath, "requirements.txt");
25567
+ const requirementsPath = join7(this.projectPath, "requirements.txt");
25137
25568
  if (existsSync7(requirementsPath)) {
25138
25569
  try {
25139
25570
  const content = readFileSync7(requirementsPath, "utf-8");
@@ -25178,7 +25609,7 @@ var ArchitectureGenerator = class _ArchitectureGenerator {
25178
25609
  // src/core/living-docs/component-generator.ts
25179
25610
  import { execSync as execSync2 } from "child_process";
25180
25611
  import { existsSync as existsSync8 } from "fs";
25181
- import { basename as basename5, extname as extname2, join as join9 } from "path";
25612
+ import { basename as basename5, extname as extname2, join as join8 } from "path";
25182
25613
  var ComponentGenerator = class {
25183
25614
  projectPath;
25184
25615
  tier2;
@@ -25186,7 +25617,7 @@ var ComponentGenerator = class {
25186
25617
  constructor(projectPath, tier2) {
25187
25618
  this.projectPath = projectPath;
25188
25619
  this.tier2 = tier2;
25189
- this.isGitRepo = existsSync8(join9(projectPath, ".git"));
25620
+ this.isGitRepo = existsSync8(join8(projectPath, ".git"));
25190
25621
  }
25191
25622
  async generate(filePath) {
25192
25623
  const file2 = this.tier2.getFile(filePath);
@@ -25355,7 +25786,7 @@ var ComponentGenerator = class {
25355
25786
  // src/core/living-docs/changelog-generator.ts
25356
25787
  import { execSync as execSync3 } from "child_process";
25357
25788
  import { existsSync as existsSync9 } from "fs";
25358
- import { join as join10 } from "path";
25789
+ import { join as join9 } from "path";
25359
25790
  var ChangelogGenerator = class {
25360
25791
  projectPath;
25361
25792
  db;
@@ -25363,7 +25794,7 @@ var ChangelogGenerator = class {
25363
25794
  constructor(projectPath, db) {
25364
25795
  this.projectPath = projectPath;
25365
25796
  this.db = db;
25366
- this.isGitRepo = existsSync9(join10(projectPath, ".git"));
25797
+ this.isGitRepo = existsSync9(join9(projectPath, ".git"));
25367
25798
  }
25368
25799
  async generate(options = {}) {
25369
25800
  if (!this.isGitRepo) {
@@ -25810,7 +26241,7 @@ var DocValidator = class {
25810
26241
  // src/core/living-docs/activity-tracker.ts
25811
26242
  import { execSync as execSync4 } from "child_process";
25812
26243
  import { existsSync as existsSync10 } from "fs";
25813
- import { join as join11 } from "path";
26244
+ import { join as join10 } from "path";
25814
26245
  var ActivityTracker = class {
25815
26246
  projectPath;
25816
26247
  db;
@@ -25820,7 +26251,7 @@ var ActivityTracker = class {
25820
26251
  this.projectPath = projectPath;
25821
26252
  this.db = db;
25822
26253
  this.tier2 = tier2;
25823
- this.isGitRepo = existsSync10(join11(projectPath, ".git"));
26254
+ this.isGitRepo = existsSync10(join10(projectPath, ".git"));
25824
26255
  }
25825
26256
  async whatHappened(since, scope) {
25826
26257
  const sinceDate = this.parseSinceString(since);
@@ -30036,7 +30467,7 @@ ${category.toUpperCase()}:`);
30036
30467
 
30037
30468
  // src/core/test-awareness/test-indexer.ts
30038
30469
  import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
30039
- import { join as join12 } from "path";
30470
+ import { join as join11 } from "path";
30040
30471
 
30041
30472
  // src/core/test-awareness/test-parser.ts
30042
30473
  import { createHash as createHash4 } from "crypto";
@@ -30598,7 +31029,7 @@ var TestIndexer = class {
30598
31029
  this.parser = new TestParser();
30599
31030
  }
30600
31031
  detectFramework() {
30601
- const packageJsonPath = join12(this.projectPath, "package.json");
31032
+ const packageJsonPath = join11(this.projectPath, "package.json");
30602
31033
  if (existsSync11(packageJsonPath)) {
30603
31034
  try {
30604
31035
  const pkg = JSON.parse(readFileSync8(packageJsonPath, "utf-8"));
@@ -30611,21 +31042,21 @@ var TestIndexer = class {
30611
31042
  }
30612
31043
  const pytestConfigs = ["pytest.ini", "pyproject.toml", "setup.cfg", "conftest.py"];
30613
31044
  for (const config2 of pytestConfigs) {
30614
- if (existsSync11(join12(this.projectPath, config2))) {
30615
- const content = readFileSync8(join12(this.projectPath, config2), "utf-8");
31045
+ if (existsSync11(join11(this.projectPath, config2))) {
31046
+ const content = readFileSync8(join11(this.projectPath, config2), "utf-8");
30616
31047
  if (content.includes("[pytest]") || content.includes("pytest") || config2 === "conftest.py") {
30617
31048
  return "pytest";
30618
31049
  }
30619
31050
  }
30620
31051
  }
30621
- const goMod = join12(this.projectPath, "go.mod");
31052
+ const goMod = join11(this.projectPath, "go.mod");
30622
31053
  if (existsSync11(goMod)) {
30623
31054
  return "go";
30624
31055
  }
30625
31056
  const vitestConfigs = ["vitest.config.ts", "vitest.config.js", "vite.config.ts", "vite.config.js"];
30626
31057
  for (const config2 of vitestConfigs) {
30627
- if (existsSync11(join12(this.projectPath, config2))) {
30628
- const content = readFileSync8(join12(this.projectPath, config2), "utf-8");
31058
+ if (existsSync11(join11(this.projectPath, config2))) {
31059
+ const content = readFileSync8(join11(this.projectPath, config2), "utf-8");
30629
31060
  if (content.includes("vitest") || content.includes("test:")) {
30630
31061
  return "vitest";
30631
31062
  }
@@ -30633,7 +31064,7 @@ var TestIndexer = class {
30633
31064
  }
30634
31065
  const jestConfigs = ["jest.config.ts", "jest.config.js", "jest.config.json"];
30635
31066
  for (const config2 of jestConfigs) {
30636
- if (existsSync11(join12(this.projectPath, config2))) {
31067
+ if (existsSync11(join11(this.projectPath, config2))) {
30637
31068
  return "jest";
30638
31069
  }
30639
31070
  }
@@ -30672,7 +31103,7 @@ var TestIndexer = class {
30672
31103
  absolute: false
30673
31104
  });
30674
31105
  for (const file2 of files) {
30675
- const absolutePath = join12(this.projectPath, file2);
31106
+ const absolutePath = join11(this.projectPath, file2);
30676
31107
  const tests = this.parseTestFile(absolutePath, file2);
30677
31108
  allTests.push(...tests);
30678
31109
  }
@@ -30799,7 +31230,7 @@ var TestIndexer = class {
30799
31230
  absolute: false
30800
31231
  });
30801
31232
  for (const file2 of files) {
30802
- const absolutePath = join12(this.projectPath, file2);
31233
+ const absolutePath = join11(this.projectPath, file2);
30803
31234
  const tests = this.parseTestFile(absolutePath, file2);
30804
31235
  allTests.push(...tests);
30805
31236
  }
@@ -31833,6 +32264,8 @@ var TECH_PATTERNS = [
31833
32264
  var GhostMode = class {
31834
32265
  activeFiles = /* @__PURE__ */ new Map();
31835
32266
  recentDecisions = /* @__PURE__ */ new Map();
32267
+ recentImpacts = /* @__PURE__ */ new Map();
32268
+ // Track file impacts
31836
32269
  tier2;
31837
32270
  embeddingGenerator;
31838
32271
  // Ghost mode settings
@@ -31840,10 +32273,47 @@ var GhostMode = class {
31840
32273
  FILE_TTL_MS = 60 * 60 * 1e3;
31841
32274
  // 1 hour
31842
32275
  DECISION_CACHE_SIZE = 50;
32276
+ IMPACT_TTL_MS = 30 * 60 * 1e3;
32277
+ // 30 minutes
31843
32278
  constructor(tier2, embeddingGenerator) {
31844
32279
  this.tier2 = tier2;
31845
32280
  this.embeddingGenerator = embeddingGenerator;
31846
32281
  }
32282
+ /**
32283
+ * Called when a file change impacts other files
32284
+ */
32285
+ onFileImpact(changedFile, affectedFiles) {
32286
+ const impact = {
32287
+ changedFile,
32288
+ affectedFiles,
32289
+ timestamp: /* @__PURE__ */ new Date()
32290
+ };
32291
+ for (const file2 of affectedFiles) {
32292
+ this.recentImpacts.set(file2, impact);
32293
+ }
32294
+ this.evictStaleImpacts();
32295
+ }
32296
+ /**
32297
+ * Check if a file was recently impacted by changes to another file
32298
+ */
32299
+ getImpactWarning(filePath) {
32300
+ const impact = this.recentImpacts.get(filePath);
32301
+ if (!impact) return null;
32302
+ const age = Date.now() - impact.timestamp.getTime();
32303
+ if (age > this.IMPACT_TTL_MS) {
32304
+ this.recentImpacts.delete(filePath);
32305
+ return null;
32306
+ }
32307
+ return impact;
32308
+ }
32309
+ evictStaleImpacts() {
32310
+ const now = Date.now();
32311
+ for (const [file2, impact] of this.recentImpacts) {
32312
+ if (now - impact.timestamp.getTime() > this.IMPACT_TTL_MS) {
32313
+ this.recentImpacts.delete(file2);
32314
+ }
32315
+ }
32316
+ }
31847
32317
  /**
31848
32318
  * Called when any file is read - silently track and pre-fetch decisions
31849
32319
  */
@@ -32399,7 +32869,7 @@ var DejaVuDetector = class {
32399
32869
 
32400
32870
  // src/core/code-verifier.ts
32401
32871
  import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
32402
- import { join as join13, dirname as dirname7, extname as extname4 } from "path";
32872
+ import { join as join12, dirname as dirname6, extname as extname4 } from "path";
32403
32873
  var SECURITY_PATTERNS2 = [
32404
32874
  // SQL Injection
32405
32875
  {
@@ -32644,11 +33114,11 @@ var CodeVerifier = class {
32644
33114
  nodeModulesPath;
32645
33115
  constructor(projectPath) {
32646
33116
  this.projectPath = projectPath;
32647
- this.nodeModulesPath = join13(projectPath, "node_modules");
33117
+ this.nodeModulesPath = join12(projectPath, "node_modules");
32648
33118
  this.loadPackageJson();
32649
33119
  }
32650
33120
  loadPackageJson() {
32651
- const packageJsonPath = join13(this.projectPath, "package.json");
33121
+ const packageJsonPath = join12(this.projectPath, "package.json");
32652
33122
  if (existsSync12(packageJsonPath)) {
32653
33123
  try {
32654
33124
  this.packageJson = JSON.parse(readFileSync9(packageJsonPath, "utf-8"));
@@ -32801,7 +33271,7 @@ var CodeVerifier = class {
32801
33271
  }
32802
33272
  const packageName = this.getPackageName(importPath);
32803
33273
  if (!packages.has(packageName)) {
32804
- const nodeModulePath = join13(this.nodeModulesPath, packageName);
33274
+ const nodeModulePath = join12(this.nodeModulesPath, packageName);
32805
33275
  if (existsSync12(nodeModulePath)) {
32806
33276
  issues.push({
32807
33277
  package: packageName,
@@ -32844,22 +33314,22 @@ var CodeVerifier = class {
32844
33314
  }
32845
33315
  verifyRelativeImport(importPath, file2, issues) {
32846
33316
  if (!file2) return;
32847
- const baseDir = dirname7(join13(this.projectPath, file2));
33317
+ const baseDir = dirname6(join12(this.projectPath, file2));
32848
33318
  const possibleExtensions = [".ts", ".tsx", ".js", ".jsx", ".json", ""];
32849
33319
  const possibleIndexes = ["index.ts", "index.tsx", "index.js", "index.jsx"];
32850
33320
  let found = false;
32851
33321
  for (const ext of possibleExtensions) {
32852
- const fullPath = join13(baseDir, importPath + ext);
33322
+ const fullPath = join12(baseDir, importPath + ext);
32853
33323
  if (existsSync12(fullPath)) {
32854
33324
  found = true;
32855
33325
  break;
32856
33326
  }
32857
33327
  }
32858
33328
  if (!found) {
32859
- const dirPath = join13(baseDir, importPath);
33329
+ const dirPath = join12(baseDir, importPath);
32860
33330
  if (existsSync12(dirPath)) {
32861
33331
  for (const indexFile of possibleIndexes) {
32862
- if (existsSync12(join13(dirPath, indexFile))) {
33332
+ if (existsSync12(join12(dirPath, indexFile))) {
32863
33333
  found = true;
32864
33334
  break;
32865
33335
  }
@@ -32877,7 +33347,7 @@ var CodeVerifier = class {
32877
33347
  }
32878
33348
  verifyPackageImport(importPath, issues, warnings) {
32879
33349
  const packageName = this.getPackageName(importPath);
32880
- const nodeModulePath = join13(this.nodeModulesPath, packageName);
33350
+ const nodeModulePath = join12(this.nodeModulesPath, packageName);
32881
33351
  if (!existsSync12(nodeModulePath)) {
32882
33352
  issues.push({
32883
33353
  import: importPath,
@@ -32889,7 +33359,7 @@ var CodeVerifier = class {
32889
33359
  }
32890
33360
  if (importPath !== packageName) {
32891
33361
  const subpath = importPath.slice(packageName.length + 1);
32892
- const subpathFull = join13(nodeModulePath, subpath);
33362
+ const subpathFull = join12(nodeModulePath, subpath);
32893
33363
  const possibleExtensions = [".js", ".json", ""];
32894
33364
  let found = false;
32895
33365
  for (const ext of possibleExtensions) {
@@ -32898,7 +33368,7 @@ var CodeVerifier = class {
32898
33368
  break;
32899
33369
  }
32900
33370
  }
32901
- const pkgJsonPath = join13(nodeModulePath, "package.json");
33371
+ const pkgJsonPath = join12(nodeModulePath, "package.json");
32902
33372
  if (!found && existsSync12(pkgJsonPath)) {
32903
33373
  try {
32904
33374
  const pkgJson = JSON.parse(readFileSync9(pkgJsonPath, "utf-8"));
@@ -33323,7 +33793,17 @@ var MemoryLayerEngine = class {
33323
33793
  if (!existsSync13(config2.dataDir)) {
33324
33794
  mkdirSync6(config2.dataDir, { recursive: true });
33325
33795
  }
33326
- const dbPath = join14(config2.dataDir, "memorylayer.db");
33796
+ let dbPath = join13(config2.dataDir, "neuronlayer.db");
33797
+ const oldDbPath = join13(config2.dataDir, "memorylayer.db");
33798
+ if (!existsSync13(dbPath) && existsSync13(oldDbPath)) {
33799
+ try {
33800
+ console.error("Migrating database from memorylayer.db to neuronlayer.db...");
33801
+ renameSync(oldDbPath, dbPath);
33802
+ } catch (err) {
33803
+ console.error("Migration skipped (file in use), using existing database");
33804
+ dbPath = oldDbPath;
33805
+ }
33806
+ }
33327
33807
  this.db = initializeDatabase(dbPath);
33328
33808
  this.tier1 = new Tier1Storage(config2.dataDir);
33329
33809
  this.tier2 = new Tier2Storage(this.db);
@@ -33418,11 +33898,31 @@ var MemoryLayerEngine = class {
33418
33898
  this.updateProjectSummary();
33419
33899
  this.updateProjectStats();
33420
33900
  this.extractDecisions().catch((err) => console.error("Decision extraction error:", err));
33901
+ try {
33902
+ const testResult = this.testAwareness.refreshIndex();
33903
+ if (testResult.testsIndexed > 0) {
33904
+ console.error(`Test index: ${testResult.testsIndexed} tests (${testResult.framework})`);
33905
+ }
33906
+ } catch (err) {
33907
+ console.error("Test indexing error:", err);
33908
+ }
33421
33909
  });
33422
33910
  this.indexer.on("fileIndexed", (path) => {
33423
33911
  this.featureContextManager.onFileOpened(path);
33424
33912
  this.summarizer.invalidateSummaryByPath(path);
33425
33913
  });
33914
+ this.indexer.on("fileImpact", (impact) => {
33915
+ if (impact.affectedCount > 0) {
33916
+ console.error(`[Impact] ${impact.file} changed \u2192 ${impact.affectedCount} file(s) may be affected`);
33917
+ if (impact.affectedCount <= 5) {
33918
+ impact.affectedFiles.forEach((f) => console.error(` \u2192 ${f}`));
33919
+ } else {
33920
+ impact.affectedFiles.slice(0, 3).forEach((f) => console.error(` \u2192 ${f}`));
33921
+ console.error(` ... and ${impact.affectedCount - 3} more`);
33922
+ }
33923
+ this.ghostMode.onFileImpact(impact.file, impact.affectedFiles);
33924
+ }
33925
+ });
33426
33926
  this.indexer.on("error", (error2) => {
33427
33927
  console.error("Indexer error:", error2);
33428
33928
  });
@@ -33629,7 +34129,7 @@ ${description}`,
33629
34129
  }
33630
34130
  async getFileContext(filePath) {
33631
34131
  this.activityGate.recordActivity();
33632
- const absolutePath = join14(this.config.projectPath, filePath);
34132
+ const absolutePath = join13(this.config.projectPath, filePath);
33633
34133
  if (!existsSync13(absolutePath)) {
33634
34134
  return null;
33635
34135
  }
@@ -33716,7 +34216,7 @@ ${decision.description}`;
33716
34216
  const commonDirs = ["src", "lib", "app", "pages", "components", "api", "server", "client", "core"];
33717
34217
  const found = [];
33718
34218
  for (const dir of commonDirs) {
33719
- if (existsSync13(join14(this.config.projectPath, dir))) {
34219
+ if (existsSync13(join13(this.config.projectPath, dir))) {
33720
34220
  found.push(dir);
33721
34221
  }
33722
34222
  }
@@ -33724,7 +34224,7 @@ ${decision.description}`;
33724
34224
  }
33725
34225
  detectDependencies() {
33726
34226
  const deps = [];
33727
- const packageJsonPath = join14(this.config.projectPath, "package.json");
34227
+ const packageJsonPath = join13(this.config.projectPath, "package.json");
33728
34228
  if (existsSync13(packageJsonPath)) {
33729
34229
  try {
33730
34230
  const pkg = JSON.parse(readFileSync10(packageJsonPath, "utf-8"));
@@ -33736,7 +34236,7 @@ ${decision.description}`;
33736
34236
  } catch {
33737
34237
  }
33738
34238
  }
33739
- const requirementsPath = join14(this.config.projectPath, "requirements.txt");
34239
+ const requirementsPath = join13(this.config.projectPath, "requirements.txt");
33740
34240
  if (existsSync13(requirementsPath)) {
33741
34241
  try {
33742
34242
  const content = readFileSync10(requirementsPath, "utf-8");
@@ -33779,6 +34279,14 @@ ${decision.description}`;
33779
34279
  }));
33780
34280
  return { imports, importedBy, symbols };
33781
34281
  }
34282
+ // Find circular dependencies in the project
34283
+ findCircularDependencies() {
34284
+ return this.tier2.findCircularDependencies();
34285
+ }
34286
+ // Get transitive dependents (all files affected by changing a file)
34287
+ getTransitiveDependents(filePath, maxDepth = 3) {
34288
+ return this.tier2.getTransitiveDependents(filePath, maxDepth);
34289
+ }
33782
34290
  // Phase 2: Get symbol count
33783
34291
  getSymbolCount() {
33784
34292
  return this.tier2.getSymbolCount();
@@ -33793,7 +34301,7 @@ ${decision.description}`;
33793
34301
  let fetched = 0;
33794
34302
  for (const filePath of predicted) {
33795
34303
  if (!this.learningEngine.isInHotCache(filePath)) {
33796
- const absolutePath = join14(this.config.projectPath, filePath);
34304
+ const absolutePath = join13(this.config.projectPath, filePath);
33797
34305
  if (existsSync13(absolutePath)) {
33798
34306
  try {
33799
34307
  const content = readFileSync10(absolutePath, "utf-8");
@@ -36758,6 +37266,83 @@ async function handleToolCall(engine, toolName, args) {
36758
37266
  symbols: result.symbols
36759
37267
  };
36760
37268
  }
37269
+ case "find_circular_deps": {
37270
+ const cycles = engine.findCircularDependencies();
37271
+ if (cycles.length === 0) {
37272
+ return {
37273
+ status: "clean",
37274
+ message: "No circular dependencies found",
37275
+ cycles: []
37276
+ };
37277
+ }
37278
+ return {
37279
+ status: "cycles_found",
37280
+ message: `Found ${cycles.length} circular dependency chain(s)`,
37281
+ cycles: cycles.map((cycle, i) => ({
37282
+ id: i + 1,
37283
+ files: cycle,
37284
+ length: cycle.length - 1,
37285
+ // -1 because last element repeats first
37286
+ description: cycle.join(" \u2192 ")
37287
+ })),
37288
+ recommendation: "Break cycles by extracting shared code into a separate module, using dependency injection, or restructuring imports."
37289
+ };
37290
+ }
37291
+ case "get_impact_analysis": {
37292
+ const filePath = args.file;
37293
+ const depth = args.depth || 3;
37294
+ const includeTests = args.include_tests !== false;
37295
+ const affected = engine.getTransitiveDependents(filePath, depth);
37296
+ const deps = engine.getFileDependencies(filePath);
37297
+ let affectedTests = [];
37298
+ if (includeTests) {
37299
+ const allAffectedFiles = [filePath, ...affected.map((a) => a.file)];
37300
+ const testSet = /* @__PURE__ */ new Set();
37301
+ for (const f of allAffectedFiles) {
37302
+ const tests = engine.getTestsForFile(f);
37303
+ for (const t of tests) {
37304
+ if (!testSet.has(t.id)) {
37305
+ testSet.add(t.id);
37306
+ affectedTests.push({ name: t.name, file: t.file });
37307
+ }
37308
+ }
37309
+ }
37310
+ }
37311
+ const allCycles = engine.findCircularDependencies();
37312
+ const relevantCycles = allCycles.filter((cycle) => cycle.includes(filePath));
37313
+ const totalAffected = affected.length;
37314
+ const riskLevel = totalAffected > 10 ? "HIGH" : totalAffected > 5 ? "MEDIUM" : "LOW";
37315
+ const riskFactors = [];
37316
+ if (totalAffected > 10) riskFactors.push(`${totalAffected} files depend on this`);
37317
+ if (relevantCycles.length > 0) riskFactors.push(`Involved in ${relevantCycles.length} circular dependency chain(s)`);
37318
+ if (affectedTests.length > 5) riskFactors.push(`${affectedTests.length} tests may need updates`);
37319
+ if (deps.imports.length > 10) riskFactors.push(`File has ${deps.imports.length} dependencies`);
37320
+ return {
37321
+ file: filePath,
37322
+ risk_level: riskLevel,
37323
+ risk_factors: riskFactors.length > 0 ? riskFactors : ["No significant risk factors detected"],
37324
+ summary: {
37325
+ total_affected_files: totalAffected,
37326
+ direct_dependents: affected.filter((a) => a.depth === 1).length,
37327
+ indirect_dependents: affected.filter((a) => a.depth > 1).length,
37328
+ affected_tests: affectedTests.length,
37329
+ circular_dependencies: relevantCycles.length
37330
+ },
37331
+ direct_dependents: affected.filter((a) => a.depth === 1).map((a) => ({
37332
+ file: a.file,
37333
+ imports: a.imports
37334
+ })),
37335
+ indirect_dependents: affected.filter((a) => a.depth > 1).map((a) => ({
37336
+ file: a.file,
37337
+ depth: a.depth,
37338
+ imports: a.imports
37339
+ })),
37340
+ this_file_imports: deps.imports.map((i) => i.file),
37341
+ affected_tests: affectedTests,
37342
+ circular_dependencies: relevantCycles.map((cycle) => cycle.join(" \u2192 ")),
37343
+ recommendation: riskLevel === "HIGH" ? "High-impact change. Consider breaking it into smaller changes and testing incrementally." : riskLevel === "MEDIUM" ? "Moderate impact. Review affected files and ensure tests cover the changes." : "Low-risk change. Standard review and testing should suffice."
37344
+ };
37345
+ }
36761
37346
  case "get_file_summary": {
36762
37347
  const path = args.path;
36763
37348
  const summary = engine.getFileSummary(path);
@@ -37918,7 +38503,7 @@ var MCPServer = class {
37918
38503
  this.engine = new MemoryLayerEngine(config2);
37919
38504
  this.server = new Server(
37920
38505
  {
37921
- name: "memorylayer",
38506
+ name: "neuronlayer",
37922
38507
  version: "0.1.0"
37923
38508
  },
37924
38509
  {
@@ -38021,13 +38606,13 @@ var MCPServer = class {
38021
38606
  };
38022
38607
 
38023
38608
  // src/utils/config.ts
38024
- import { join as join15, resolve as resolve2 } from "path";
38609
+ import { join as join14, resolve as resolve2 } from "path";
38025
38610
  function getDefaultConfig(projectPath) {
38026
38611
  const normalizedPath = resolve2(projectPath);
38027
38612
  return {
38028
38613
  projectPath: normalizedPath,
38029
38614
  // Store in project directory (standard practice like .git/, .vscode/)
38030
- dataDir: join15(normalizedPath, ".memorylayer"),
38615
+ dataDir: join14(normalizedPath, ".memorylayer"),
38031
38616
  maxTokens: 6e3,
38032
38617
  embeddingModel: "Xenova/all-MiniLM-L6-v2",
38033
38618
  // Fallback model, faster and smaller
@@ -38189,7 +38774,7 @@ function parseArgs(args) {
38189
38774
  }
38190
38775
 
38191
38776
  // src/cli/commands.ts
38192
- import { join as join16 } from "path";
38777
+ import { join as join15 } from "path";
38193
38778
  import { existsSync as existsSync14, readFileSync as readFileSync11, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7 } from "fs";
38194
38779
  import { homedir as homedir2 } from "os";
38195
38780
  var projectManager = new ProjectManager();
@@ -38305,12 +38890,17 @@ function exportDecisions(projectPath, options = {}) {
38305
38890
  message: `Project not registered: ${targetPath}. Use "memorylayer projects add ${targetPath}" first.`
38306
38891
  };
38307
38892
  }
38308
- const dbPath = join16(projectInfo.dataDir, "memorylayer.db");
38893
+ let dbPath = join15(projectInfo.dataDir, "neuronlayer.db");
38309
38894
  if (!existsSync14(dbPath)) {
38310
- return {
38311
- success: false,
38312
- message: `Project database not found. Has the project been indexed?`
38313
- };
38895
+ const oldDbPath = join15(projectInfo.dataDir, "memorylayer.db");
38896
+ if (existsSync14(oldDbPath)) {
38897
+ dbPath = oldDbPath;
38898
+ } else {
38899
+ return {
38900
+ success: false,
38901
+ message: `Project database not found. Has the project been indexed?`
38902
+ };
38903
+ }
38314
38904
  }
38315
38905
  const db = initializeDatabase(dbPath);
38316
38906
  const tier2 = new Tier2Storage(db);
@@ -38330,7 +38920,7 @@ function exportDecisions(projectPath, options = {}) {
38330
38920
  });
38331
38921
  return {
38332
38922
  success: true,
38333
- message: `Exported ${exportedFiles.length} ADR files to ${options.outputDir || join16(targetPath, "docs", "decisions")}`,
38923
+ message: `Exported ${exportedFiles.length} ADR files to ${options.outputDir || join15(targetPath, "docs", "decisions")}`,
38334
38924
  data: exportedFiles
38335
38925
  };
38336
38926
  }
@@ -38403,11 +38993,11 @@ function initProject(projectPath) {
38403
38993
  const failedClients = [];
38404
38994
  let claudeConfigPath;
38405
38995
  if (platform === "win32") {
38406
- claudeConfigPath = join16(homedir2(), "AppData", "Roaming", "Claude", "claude_desktop_config.json");
38996
+ claudeConfigPath = join15(homedir2(), "AppData", "Roaming", "Claude", "claude_desktop_config.json");
38407
38997
  } else if (platform === "darwin") {
38408
- claudeConfigPath = join16(homedir2(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
38998
+ claudeConfigPath = join15(homedir2(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
38409
38999
  } else {
38410
- claudeConfigPath = join16(homedir2(), ".config", "claude", "claude_desktop_config.json");
39000
+ claudeConfigPath = join15(homedir2(), ".config", "claude", "claude_desktop_config.json");
38411
39001
  }
38412
39002
  const claudeResult = configureMCPClient("Claude Desktop", claudeConfigPath, serverName, targetPath);
38413
39003
  if (claudeResult.success) {
@@ -38415,14 +39005,14 @@ function initProject(projectPath) {
38415
39005
  } else {
38416
39006
  failedClients.push(claudeResult.message);
38417
39007
  }
38418
- const openCodeConfigPath = join16(homedir2(), ".opencode", "config.json");
39008
+ const openCodeConfigPath = join15(homedir2(), ".opencode", "config.json");
38419
39009
  const openCodeResult = configureMCPClient("OpenCode", openCodeConfigPath, serverName, targetPath);
38420
39010
  if (openCodeResult.success) {
38421
39011
  configuredClients.push(openCodeResult.message);
38422
39012
  } else {
38423
39013
  failedClients.push(openCodeResult.message);
38424
39014
  }
38425
- const claudeCodeConfigPath = join16(homedir2(), ".claude.json");
39015
+ const claudeCodeConfigPath = join15(homedir2(), ".claude.json");
38426
39016
  const claudeCodeResult = configureMCPClient("Claude Code", claudeCodeConfigPath, serverName, targetPath);
38427
39017
  if (claudeCodeResult.success) {
38428
39018
  configuredClients.push(claudeCodeResult.message);