opencode-codebase-index 0.5.2 → 0.6.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.
package/dist/index.cjs CHANGED
@@ -33,7 +33,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
33
33
 
34
34
  // node_modules/eventemitter3/index.js
35
35
  var require_eventemitter3 = __commonJS({
36
- "node_modules/eventemitter3/index.js"(exports2, module2) {
36
+ "node_modules/eventemitter3/index.js"(exports2, module3) {
37
37
  "use strict";
38
38
  var has = Object.prototype.hasOwnProperty;
39
39
  var prefix = "~";
@@ -187,15 +187,15 @@ var require_eventemitter3 = __commonJS({
187
187
  EventEmitter3.prototype.addListener = EventEmitter3.prototype.on;
188
188
  EventEmitter3.prefixed = prefix;
189
189
  EventEmitter3.EventEmitter = EventEmitter3;
190
- if ("undefined" !== typeof module2) {
191
- module2.exports = EventEmitter3;
190
+ if ("undefined" !== typeof module3) {
191
+ module3.exports = EventEmitter3;
192
192
  }
193
193
  }
194
194
  });
195
195
 
196
196
  // node_modules/ignore/index.js
197
197
  var require_ignore = __commonJS({
198
- "node_modules/ignore/index.js"(exports2, module2) {
198
+ "node_modules/ignore/index.js"(exports2, module3) {
199
199
  "use strict";
200
200
  function makeArray(subject) {
201
201
  return Array.isArray(subject) ? subject : [subject];
@@ -644,10 +644,10 @@ var require_ignore = __commonJS({
644
644
  ) {
645
645
  setupWindows();
646
646
  }
647
- module2.exports = factory;
647
+ module3.exports = factory;
648
648
  factory.default = factory;
649
- module2.exports.isPathValid = isPathValid;
650
- define(module2.exports, /* @__PURE__ */ Symbol.for("setupWindows"), setupWindows);
649
+ module3.exports.isPathValid = isPathValid;
650
+ define(module3.exports, /* @__PURE__ */ Symbol.for("setupWindows"), setupWindows);
651
651
  }
652
652
  });
653
653
 
@@ -668,7 +668,7 @@ var DEFAULT_INCLUDE = [
668
668
  "**/*.{py,pyi}",
669
669
  "**/*.{go,rs,java,kt,scala}",
670
670
  "**/*.{c,cpp,cc,h,hpp}",
671
- "**/*.{rb,php,swift}",
671
+ "**/*.{rb,php,inc,swift}",
672
672
  "**/*.{vue,svelte,astro}",
673
673
  "**/*.{sql,graphql,proto}",
674
674
  "**/*.{yaml,yml,toml}",
@@ -2929,6 +2929,7 @@ function initializeLogger(config) {
2929
2929
  // src/native/index.ts
2930
2930
  var path3 = __toESM(require("path"), 1);
2931
2931
  var os2 = __toESM(require("os"), 1);
2932
+ var module2 = __toESM(require("module"), 1);
2932
2933
  var import_url = require("url");
2933
2934
  var import_meta = {};
2934
2935
  function getNativeBinding() {
@@ -2949,17 +2950,22 @@ function getNativeBinding() {
2949
2950
  throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
2950
2951
  }
2951
2952
  let currentDir;
2953
+ let requireTarget;
2952
2954
  if (typeof import_meta !== "undefined" && import_meta.url) {
2953
2955
  currentDir = path3.dirname((0, import_url.fileURLToPath)(import_meta.url));
2956
+ requireTarget = import_meta.url;
2954
2957
  } else if (typeof __dirname !== "undefined") {
2955
2958
  currentDir = __dirname;
2959
+ requireTarget = __filename;
2956
2960
  } else {
2957
2961
  currentDir = process.cwd();
2962
+ requireTarget = path3.join(currentDir, "index.js");
2958
2963
  }
2959
2964
  const isDevMode = currentDir.includes("/src/native");
2960
2965
  const packageRoot = isDevMode ? path3.resolve(currentDir, "../..") : path3.resolve(currentDir, "..");
2961
2966
  const nativePath = path3.join(packageRoot, "native", bindingName);
2962
- return require(nativePath);
2967
+ const require2 = module2.createRequire(requireTarget);
2968
+ return require2(nativePath);
2963
2969
  }
2964
2970
  var native = getNativeBinding();
2965
2971
  function parseFiles(files) {
@@ -3441,7 +3447,36 @@ var Database = class {
3441
3447
  // src/git/index.ts
3442
3448
  var import_fs3 = require("fs");
3443
3449
  var path4 = __toESM(require("path"), 1);
3444
- var import_child_process = require("child_process");
3450
+ function readPackedRefs(gitDir) {
3451
+ const packedRefsPath = path4.join(gitDir, "packed-refs");
3452
+ if (!(0, import_fs3.existsSync)(packedRefsPath)) {
3453
+ return [];
3454
+ }
3455
+ try {
3456
+ return (0, import_fs3.readFileSync)(packedRefsPath, "utf-8").split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#") && !line.startsWith("^"));
3457
+ } catch {
3458
+ return [];
3459
+ }
3460
+ }
3461
+ function resolveCommonGitDir(gitDir) {
3462
+ const commonDirPath = path4.join(gitDir, "commondir");
3463
+ if (!(0, import_fs3.existsSync)(commonDirPath)) {
3464
+ return gitDir;
3465
+ }
3466
+ try {
3467
+ const raw = (0, import_fs3.readFileSync)(commonDirPath, "utf-8").trim();
3468
+ if (!raw) {
3469
+ return gitDir;
3470
+ }
3471
+ const resolved = path4.isAbsolute(raw) ? raw : path4.resolve(gitDir, raw);
3472
+ if ((0, import_fs3.existsSync)(resolved)) {
3473
+ return resolved;
3474
+ }
3475
+ } catch {
3476
+ return gitDir;
3477
+ }
3478
+ return gitDir;
3479
+ }
3445
3480
  function resolveGitDir(repoRoot) {
3446
3481
  const gitPath = path4.join(repoRoot, ".git");
3447
3482
  if (!(0, import_fs3.existsSync)(gitPath)) {
@@ -3495,37 +3530,20 @@ function getCurrentBranch(repoRoot) {
3495
3530
  }
3496
3531
  function getBaseBranch(repoRoot) {
3497
3532
  const gitDir = resolveGitDir(repoRoot);
3533
+ const refStoreDir = gitDir ? resolveCommonGitDir(gitDir) : null;
3498
3534
  const candidates = ["main", "master", "develop", "trunk"];
3499
- if (gitDir) {
3535
+ if (refStoreDir) {
3500
3536
  for (const candidate of candidates) {
3501
- const refPath = path4.join(gitDir, "refs", "heads", candidate);
3537
+ const refPath = path4.join(refStoreDir, "refs", "heads", candidate);
3502
3538
  if ((0, import_fs3.existsSync)(refPath)) {
3503
3539
  return candidate;
3504
3540
  }
3505
- const packedRefsPath = path4.join(gitDir, "packed-refs");
3506
- if ((0, import_fs3.existsSync)(packedRefsPath)) {
3507
- try {
3508
- const content = (0, import_fs3.readFileSync)(packedRefsPath, "utf-8");
3509
- if (content.includes(`refs/heads/${candidate}`)) {
3510
- return candidate;
3511
- }
3512
- } catch {
3513
- }
3541
+ const packedRefs = readPackedRefs(refStoreDir);
3542
+ if (packedRefs.some((line) => line.endsWith(` refs/heads/${candidate}`))) {
3543
+ return candidate;
3514
3544
  }
3515
3545
  }
3516
3546
  }
3517
- try {
3518
- const result = (0, import_child_process.execSync)("git remote show origin", {
3519
- cwd: repoRoot,
3520
- encoding: "utf-8",
3521
- stdio: ["pipe", "pipe", "pipe"]
3522
- });
3523
- const match = result.match(/HEAD branch: (.+)/);
3524
- if (match) {
3525
- return match[1].trim();
3526
- }
3527
- } catch {
3528
- }
3529
3547
  return getCurrentBranch(repoRoot) ?? "main";
3530
3548
  }
3531
3549
  function getBranchOrDefault(repoRoot) {
@@ -3543,7 +3561,7 @@ function getHeadPath(repoRoot) {
3543
3561
  }
3544
3562
 
3545
3563
  // src/indexer/index.ts
3546
- var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust"]);
3564
+ var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust", "php"]);
3547
3565
  var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
3548
3566
  "function_declaration",
3549
3567
  "function",
@@ -3564,7 +3582,8 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
3564
3582
  "struct_item",
3565
3583
  "enum_item",
3566
3584
  "trait_item",
3567
- "mod_item"
3585
+ "mod_item",
3586
+ "trait_declaration"
3568
3587
  ]);
3569
3588
  function float32ArrayToBuffer(arr) {
3570
3589
  const float32 = new Float32Array(arr);
@@ -3946,8 +3965,8 @@ function stripFilePathHint(query) {
3946
3965
  const stripped = query.replace(FILE_PATH_HINT_SUFFIX_REGEX, "").trim();
3947
3966
  return stripped.length > 0 ? stripped : query;
3948
3967
  }
3949
- function buildDeterministicIdentifierPass(query, candidates, limit) {
3950
- if (classifyQueryIntentRaw(query) !== "source") {
3968
+ function buildDeterministicIdentifierPass(query, candidates, limit, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
3969
+ if (!prioritizeSourcePaths) {
3951
3970
  return [];
3952
3971
  }
3953
3972
  const primary = extractPrimaryIdentifierQueryHint(query);
@@ -4163,9 +4182,8 @@ function rankHybridResults(query, semanticResults, keywordResults, options) {
4163
4182
  const fused = options.fusionStrategy === "rrf" ? fuseResultsRrf(semanticResults, keywordResults, options.rrfK, overfetchLimit) : fuseResultsWeighted(semanticResults, keywordResults, options.hybridWeight, overfetchLimit);
4164
4183
  const rerankPoolLimit = Math.max(overfetchLimit, options.rerankTopN * 3, options.limit * 6);
4165
4184
  const rerankPool = fused.slice(0, rerankPoolLimit);
4166
- const intent = classifyQueryIntentRaw(query);
4167
4185
  return rerankResults(query, rerankPool, options.rerankTopN, {
4168
- prioritizeSourcePaths: intent === "source"
4186
+ prioritizeSourcePaths: options.prioritizeSourcePaths ?? classifyQueryIntentRaw(query) === "source"
4169
4187
  });
4170
4188
  }
4171
4189
  function rankSemanticOnlyResults(query, semanticResults, options) {
@@ -4175,11 +4193,11 @@ function rankSemanticOnlyResults(query, semanticResults, options) {
4175
4193
  prioritizeSourcePaths: options.prioritizeSourcePaths ?? false
4176
4194
  });
4177
4195
  }
4178
- function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCandidates, database, branchChunkIds) {
4196
+ function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCandidates, database, branchChunkIds, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
4179
4197
  if (combined.length === 0) {
4180
4198
  return combined;
4181
4199
  }
4182
- if (classifyQueryIntentRaw(query) !== "source") {
4200
+ if (!prioritizeSourcePaths) {
4183
4201
  return combined;
4184
4202
  }
4185
4203
  const identifierHints = extractIdentifierHints(query);
@@ -4269,8 +4287,8 @@ function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCa
4269
4287
  const remainder = combined.filter((candidate) => !promotedIds.has(candidate.id));
4270
4288
  return [...promoted, ...remainder];
4271
4289
  }
4272
- function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallbackCandidates) {
4273
- if (classifyQueryIntentRaw(query) !== "source") {
4290
+ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallbackCandidates, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
4291
+ if (!prioritizeSourcePaths) {
4274
4292
  return [];
4275
4293
  }
4276
4294
  const identifierHints = extractIdentifierHints(query);
@@ -4415,8 +4433,8 @@ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallb
4415
4433
  const withFallback = Array.from(symbolCandidates.values()).sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));
4416
4434
  return withFallback.slice(0, Math.max(limit * 2, limit));
4417
4435
  }
4418
- function buildIdentifierDefinitionLane(query, candidates, limit) {
4419
- if (classifyQueryIntentRaw(query) !== "source") {
4436
+ function buildIdentifierDefinitionLane(query, candidates, limit, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
4437
+ if (!prioritizeSourcePaths) {
4420
4438
  return [];
4421
4439
  }
4422
4440
  const primaryHint = extractPrimaryIdentifierQueryHint(query);
@@ -5348,6 +5366,7 @@ var Indexer = class {
5348
5366
  const rrfK = this.config.search.rrfK;
5349
5367
  const rerankTopN = this.config.search.rerankTopN;
5350
5368
  const filterByBranch = options?.filterByBranch ?? true;
5369
+ const sourceIntent = options?.definitionIntent === true || classifyQueryIntentRaw(query) === "source";
5351
5370
  this.logger.search("debug", "Starting search", {
5352
5371
  query,
5353
5372
  maxResults,
@@ -5399,7 +5418,8 @@ var Indexer = class {
5399
5418
  rrfK,
5400
5419
  rerankTopN,
5401
5420
  limit: maxResults,
5402
- hybridWeight
5421
+ hybridWeight,
5422
+ prioritizeSourcePaths: sourceIntent
5403
5423
  });
5404
5424
  const fusionMs = import_perf_hooks.performance.now() - fusionStartTime;
5405
5425
  const rescued = promoteIdentifierMatches(
@@ -5408,30 +5428,33 @@ var Indexer = class {
5408
5428
  semanticCandidates,
5409
5429
  keywordCandidates,
5410
5430
  database,
5411
- branchChunkIds
5431
+ branchChunkIds,
5432
+ sourceIntent
5412
5433
  );
5413
5434
  const union = unionCandidates(semanticCandidates, keywordCandidates);
5414
5435
  const deterministicIdentifierLane = buildDeterministicIdentifierPass(
5415
5436
  query,
5416
5437
  union,
5417
- maxResults
5438
+ maxResults,
5439
+ sourceIntent
5418
5440
  );
5419
5441
  const identifierLane = buildIdentifierDefinitionLane(
5420
5442
  query,
5421
5443
  union,
5422
- maxResults
5444
+ maxResults,
5445
+ sourceIntent
5423
5446
  );
5424
5447
  const symbolLane = buildSymbolDefinitionLane(
5425
5448
  query,
5426
5449
  database,
5427
5450
  branchChunkIds,
5428
5451
  maxResults,
5429
- union
5452
+ union,
5453
+ sourceIntent
5430
5454
  );
5431
5455
  const prePrimaryLane = mergeTieredResults(deterministicIdentifierLane, identifierLane, maxResults * 4);
5432
5456
  const primaryLane = mergeTieredResults(prePrimaryLane, symbolLane, maxResults * 4);
5433
5457
  const tiered = mergeTieredResults(primaryLane, rescued, maxResults * 4);
5434
- const sourceIntent = classifyQueryIntentRaw(query) === "source";
5435
5458
  const hasCodeHints = extractCodeTermHints(query).length > 0 || extractIdentifierHints(query).length > 0;
5436
5459
  const baseFiltered = tiered.filter((r) => {
5437
5460
  if (r.score < this.config.search.minScore) return false;
@@ -7877,6 +7900,22 @@ function formatLogs(logs) {
7877
7900
  return `[${l.timestamp}] [${l.level.toUpperCase()}] [${l.category}] ${l.message}${dataStr}`;
7878
7901
  }).join("\n");
7879
7902
  }
7903
+ function formatDefinitionLookup(results, query) {
7904
+ if (results.length === 0) {
7905
+ return `No definition found for "${query}". Try codebase_search for broader discovery, or verify the symbol name.`;
7906
+ }
7907
+ const formatted = results.map((r, idx) => {
7908
+ const header2 = r.name ? `[${idx + 1}] ${r.chunkType} "${r.name}" in ${r.filePath}:${r.startLine}-${r.endLine}` : `[${idx + 1}] ${r.chunkType} in ${r.filePath}:${r.startLine}-${r.endLine}`;
7909
+ return `${header2} (score: ${r.score.toFixed(2)})
7910
+ \`\`\`
7911
+ ${truncateContent(r.content)}
7912
+ \`\`\``;
7913
+ });
7914
+ const header = results.length === 1 ? `Definition found for "${query}":` : `Found ${results.length} definition candidates for "${query}":`;
7915
+ return `${header}
7916
+
7917
+ ${formatted.join("\n\n")}`;
7918
+ }
7880
7919
  function formatSearchResults(results, scoreFormat = "similarity") {
7881
7920
  const formatted = results.map((r, idx) => {
7882
7921
  const header = r.name ? `[${idx + 1}] ${r.chunkType} "${r.name}" in ${r.filePath}:${r.startLine}-${r.endLine}` : `[${idx + 1}] ${r.chunkType} in ${r.filePath}:${r.startLine}-${r.endLine}`;
@@ -8062,6 +8101,24 @@ var codebase_search = (0, import_plugin.tool)({
8062
8101
  ${formatSearchResults(results, "score")}`;
8063
8102
  }
8064
8103
  });
8104
+ var implementation_lookup = (0, import_plugin.tool)({
8105
+ description: "Jump to symbol definition. Find WHERE something is defined. Returns the authoritative source location(s) for a function, class, method, type, or variable. Prefers real implementation files over tests, docs, examples, and fixtures. Use when you need the definition site, not all usages.",
8106
+ args: {
8107
+ query: z.string().describe("Symbol name or natural language description (e.g., 'validateToken', 'where is the payment handler defined')"),
8108
+ limit: z.number().optional().default(5).describe("Maximum number of results"),
8109
+ fileType: z.string().optional().describe("Filter by file extension (e.g., 'ts', 'py')"),
8110
+ directory: z.string().optional().describe("Filter by directory path (e.g., 'src/utils')")
8111
+ },
8112
+ async execute(args) {
8113
+ const indexer = getIndexer();
8114
+ const results = await indexer.search(args.query, args.limit ?? 5, {
8115
+ fileType: args.fileType,
8116
+ directory: args.directory,
8117
+ definitionIntent: true
8118
+ });
8119
+ return formatDefinitionLookup(results, args.query);
8120
+ }
8121
+ });
8065
8122
  var call_graph = (0, import_plugin.tool)({
8066
8123
  description: "Query the call graph to find callers or callees of a function/method. Use to understand code flow and dependencies between functions.",
8067
8124
  args: {
@@ -8203,7 +8260,8 @@ var plugin = async ({ directory }) => {
8203
8260
  index_metrics,
8204
8261
  index_logs,
8205
8262
  find_similar,
8206
- call_graph
8263
+ call_graph,
8264
+ implementation_lookup
8207
8265
  },
8208
8266
  async config(cfg) {
8209
8267
  cfg.command = cfg.command ?? {};