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.js CHANGED
@@ -6,13 +6,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
- }) : x)(function(x) {
12
- if (typeof require !== "undefined") return require.apply(this, arguments);
13
- throw Error('Dynamic require of "' + x + '" is not supported');
14
- });
15
- var __commonJS = (cb, mod) => function __require2() {
9
+ var __commonJS = (cb, mod) => function __require() {
16
10
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
17
11
  };
18
12
  var __copyProps = (to, from, except, desc) => {
@@ -34,7 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
28
 
35
29
  // node_modules/eventemitter3/index.js
36
30
  var require_eventemitter3 = __commonJS({
37
- "node_modules/eventemitter3/index.js"(exports, module) {
31
+ "node_modules/eventemitter3/index.js"(exports, module2) {
38
32
  "use strict";
39
33
  var has = Object.prototype.hasOwnProperty;
40
34
  var prefix = "~";
@@ -188,15 +182,15 @@ var require_eventemitter3 = __commonJS({
188
182
  EventEmitter3.prototype.addListener = EventEmitter3.prototype.on;
189
183
  EventEmitter3.prefixed = prefix;
190
184
  EventEmitter3.EventEmitter = EventEmitter3;
191
- if ("undefined" !== typeof module) {
192
- module.exports = EventEmitter3;
185
+ if ("undefined" !== typeof module2) {
186
+ module2.exports = EventEmitter3;
193
187
  }
194
188
  }
195
189
  });
196
190
 
197
191
  // node_modules/ignore/index.js
198
192
  var require_ignore = __commonJS({
199
- "node_modules/ignore/index.js"(exports, module) {
193
+ "node_modules/ignore/index.js"(exports, module2) {
200
194
  "use strict";
201
195
  function makeArray(subject) {
202
196
  return Array.isArray(subject) ? subject : [subject];
@@ -645,10 +639,10 @@ var require_ignore = __commonJS({
645
639
  ) {
646
640
  setupWindows();
647
641
  }
648
- module.exports = factory;
642
+ module2.exports = factory;
649
643
  factory.default = factory;
650
- module.exports.isPathValid = isPathValid;
651
- define(module.exports, /* @__PURE__ */ Symbol.for("setupWindows"), setupWindows);
644
+ module2.exports.isPathValid = isPathValid;
645
+ define(module2.exports, /* @__PURE__ */ Symbol.for("setupWindows"), setupWindows);
652
646
  }
653
647
  });
654
648
 
@@ -664,7 +658,7 @@ var DEFAULT_INCLUDE = [
664
658
  "**/*.{py,pyi}",
665
659
  "**/*.{go,rs,java,kt,scala}",
666
660
  "**/*.{c,cpp,cc,h,hpp}",
667
- "**/*.{rb,php,swift}",
661
+ "**/*.{rb,php,inc,swift}",
668
662
  "**/*.{vue,svelte,astro}",
669
663
  "**/*.{sql,graphql,proto}",
670
664
  "**/*.{yaml,yml,toml}",
@@ -2925,6 +2919,7 @@ function initializeLogger(config) {
2925
2919
  // src/native/index.ts
2926
2920
  import * as path3 from "path";
2927
2921
  import * as os2 from "os";
2922
+ import * as module from "module";
2928
2923
  import { fileURLToPath } from "url";
2929
2924
  function getNativeBinding() {
2930
2925
  const platform2 = os2.platform();
@@ -2944,17 +2939,22 @@ function getNativeBinding() {
2944
2939
  throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
2945
2940
  }
2946
2941
  let currentDir;
2942
+ let requireTarget;
2947
2943
  if (typeof import.meta !== "undefined" && import.meta.url) {
2948
2944
  currentDir = path3.dirname(fileURLToPath(import.meta.url));
2945
+ requireTarget = import.meta.url;
2949
2946
  } else if (typeof __dirname !== "undefined") {
2950
2947
  currentDir = __dirname;
2948
+ requireTarget = __filename;
2951
2949
  } else {
2952
2950
  currentDir = process.cwd();
2951
+ requireTarget = path3.join(currentDir, "index.js");
2953
2952
  }
2954
2953
  const isDevMode = currentDir.includes("/src/native");
2955
2954
  const packageRoot = isDevMode ? path3.resolve(currentDir, "../..") : path3.resolve(currentDir, "..");
2956
2955
  const nativePath = path3.join(packageRoot, "native", bindingName);
2957
- return __require(nativePath);
2956
+ const require2 = module.createRequire(requireTarget);
2957
+ return require2(nativePath);
2958
2958
  }
2959
2959
  var native = getNativeBinding();
2960
2960
  function parseFiles(files) {
@@ -3436,7 +3436,36 @@ var Database = class {
3436
3436
  // src/git/index.ts
3437
3437
  import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync, statSync } from "fs";
3438
3438
  import * as path4 from "path";
3439
- import { execSync } from "child_process";
3439
+ function readPackedRefs(gitDir) {
3440
+ const packedRefsPath = path4.join(gitDir, "packed-refs");
3441
+ if (!existsSync3(packedRefsPath)) {
3442
+ return [];
3443
+ }
3444
+ try {
3445
+ return readFileSync3(packedRefsPath, "utf-8").split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#") && !line.startsWith("^"));
3446
+ } catch {
3447
+ return [];
3448
+ }
3449
+ }
3450
+ function resolveCommonGitDir(gitDir) {
3451
+ const commonDirPath = path4.join(gitDir, "commondir");
3452
+ if (!existsSync3(commonDirPath)) {
3453
+ return gitDir;
3454
+ }
3455
+ try {
3456
+ const raw = readFileSync3(commonDirPath, "utf-8").trim();
3457
+ if (!raw) {
3458
+ return gitDir;
3459
+ }
3460
+ const resolved = path4.isAbsolute(raw) ? raw : path4.resolve(gitDir, raw);
3461
+ if (existsSync3(resolved)) {
3462
+ return resolved;
3463
+ }
3464
+ } catch {
3465
+ return gitDir;
3466
+ }
3467
+ return gitDir;
3468
+ }
3440
3469
  function resolveGitDir(repoRoot) {
3441
3470
  const gitPath = path4.join(repoRoot, ".git");
3442
3471
  if (!existsSync3(gitPath)) {
@@ -3490,37 +3519,20 @@ function getCurrentBranch(repoRoot) {
3490
3519
  }
3491
3520
  function getBaseBranch(repoRoot) {
3492
3521
  const gitDir = resolveGitDir(repoRoot);
3522
+ const refStoreDir = gitDir ? resolveCommonGitDir(gitDir) : null;
3493
3523
  const candidates = ["main", "master", "develop", "trunk"];
3494
- if (gitDir) {
3524
+ if (refStoreDir) {
3495
3525
  for (const candidate of candidates) {
3496
- const refPath = path4.join(gitDir, "refs", "heads", candidate);
3526
+ const refPath = path4.join(refStoreDir, "refs", "heads", candidate);
3497
3527
  if (existsSync3(refPath)) {
3498
3528
  return candidate;
3499
3529
  }
3500
- const packedRefsPath = path4.join(gitDir, "packed-refs");
3501
- if (existsSync3(packedRefsPath)) {
3502
- try {
3503
- const content = readFileSync3(packedRefsPath, "utf-8");
3504
- if (content.includes(`refs/heads/${candidate}`)) {
3505
- return candidate;
3506
- }
3507
- } catch {
3508
- }
3530
+ const packedRefs = readPackedRefs(refStoreDir);
3531
+ if (packedRefs.some((line) => line.endsWith(` refs/heads/${candidate}`))) {
3532
+ return candidate;
3509
3533
  }
3510
3534
  }
3511
3535
  }
3512
- try {
3513
- const result = execSync("git remote show origin", {
3514
- cwd: repoRoot,
3515
- encoding: "utf-8",
3516
- stdio: ["pipe", "pipe", "pipe"]
3517
- });
3518
- const match = result.match(/HEAD branch: (.+)/);
3519
- if (match) {
3520
- return match[1].trim();
3521
- }
3522
- } catch {
3523
- }
3524
3536
  return getCurrentBranch(repoRoot) ?? "main";
3525
3537
  }
3526
3538
  function getBranchOrDefault(repoRoot) {
@@ -3538,7 +3550,7 @@ function getHeadPath(repoRoot) {
3538
3550
  }
3539
3551
 
3540
3552
  // src/indexer/index.ts
3541
- var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust"]);
3553
+ var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust", "php"]);
3542
3554
  var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
3543
3555
  "function_declaration",
3544
3556
  "function",
@@ -3559,7 +3571,8 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
3559
3571
  "struct_item",
3560
3572
  "enum_item",
3561
3573
  "trait_item",
3562
- "mod_item"
3574
+ "mod_item",
3575
+ "trait_declaration"
3563
3576
  ]);
3564
3577
  function float32ArrayToBuffer(arr) {
3565
3578
  const float32 = new Float32Array(arr);
@@ -3941,8 +3954,8 @@ function stripFilePathHint(query) {
3941
3954
  const stripped = query.replace(FILE_PATH_HINT_SUFFIX_REGEX, "").trim();
3942
3955
  return stripped.length > 0 ? stripped : query;
3943
3956
  }
3944
- function buildDeterministicIdentifierPass(query, candidates, limit) {
3945
- if (classifyQueryIntentRaw(query) !== "source") {
3957
+ function buildDeterministicIdentifierPass(query, candidates, limit, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
3958
+ if (!prioritizeSourcePaths) {
3946
3959
  return [];
3947
3960
  }
3948
3961
  const primary = extractPrimaryIdentifierQueryHint(query);
@@ -4158,9 +4171,8 @@ function rankHybridResults(query, semanticResults, keywordResults, options) {
4158
4171
  const fused = options.fusionStrategy === "rrf" ? fuseResultsRrf(semanticResults, keywordResults, options.rrfK, overfetchLimit) : fuseResultsWeighted(semanticResults, keywordResults, options.hybridWeight, overfetchLimit);
4159
4172
  const rerankPoolLimit = Math.max(overfetchLimit, options.rerankTopN * 3, options.limit * 6);
4160
4173
  const rerankPool = fused.slice(0, rerankPoolLimit);
4161
- const intent = classifyQueryIntentRaw(query);
4162
4174
  return rerankResults(query, rerankPool, options.rerankTopN, {
4163
- prioritizeSourcePaths: intent === "source"
4175
+ prioritizeSourcePaths: options.prioritizeSourcePaths ?? classifyQueryIntentRaw(query) === "source"
4164
4176
  });
4165
4177
  }
4166
4178
  function rankSemanticOnlyResults(query, semanticResults, options) {
@@ -4170,11 +4182,11 @@ function rankSemanticOnlyResults(query, semanticResults, options) {
4170
4182
  prioritizeSourcePaths: options.prioritizeSourcePaths ?? false
4171
4183
  });
4172
4184
  }
4173
- function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCandidates, database, branchChunkIds) {
4185
+ function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCandidates, database, branchChunkIds, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
4174
4186
  if (combined.length === 0) {
4175
4187
  return combined;
4176
4188
  }
4177
- if (classifyQueryIntentRaw(query) !== "source") {
4189
+ if (!prioritizeSourcePaths) {
4178
4190
  return combined;
4179
4191
  }
4180
4192
  const identifierHints = extractIdentifierHints(query);
@@ -4264,8 +4276,8 @@ function promoteIdentifierMatches(query, combined, semanticCandidates, keywordCa
4264
4276
  const remainder = combined.filter((candidate) => !promotedIds.has(candidate.id));
4265
4277
  return [...promoted, ...remainder];
4266
4278
  }
4267
- function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallbackCandidates) {
4268
- if (classifyQueryIntentRaw(query) !== "source") {
4279
+ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallbackCandidates, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
4280
+ if (!prioritizeSourcePaths) {
4269
4281
  return [];
4270
4282
  }
4271
4283
  const identifierHints = extractIdentifierHints(query);
@@ -4410,8 +4422,8 @@ function buildSymbolDefinitionLane(query, database, branchChunkIds, limit, fallb
4410
4422
  const withFallback = Array.from(symbolCandidates.values()).sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));
4411
4423
  return withFallback.slice(0, Math.max(limit * 2, limit));
4412
4424
  }
4413
- function buildIdentifierDefinitionLane(query, candidates, limit) {
4414
- if (classifyQueryIntentRaw(query) !== "source") {
4425
+ function buildIdentifierDefinitionLane(query, candidates, limit, prioritizeSourcePaths = classifyQueryIntentRaw(query) === "source") {
4426
+ if (!prioritizeSourcePaths) {
4415
4427
  return [];
4416
4428
  }
4417
4429
  const primaryHint = extractPrimaryIdentifierQueryHint(query);
@@ -5343,6 +5355,7 @@ var Indexer = class {
5343
5355
  const rrfK = this.config.search.rrfK;
5344
5356
  const rerankTopN = this.config.search.rerankTopN;
5345
5357
  const filterByBranch = options?.filterByBranch ?? true;
5358
+ const sourceIntent = options?.definitionIntent === true || classifyQueryIntentRaw(query) === "source";
5346
5359
  this.logger.search("debug", "Starting search", {
5347
5360
  query,
5348
5361
  maxResults,
@@ -5394,7 +5407,8 @@ var Indexer = class {
5394
5407
  rrfK,
5395
5408
  rerankTopN,
5396
5409
  limit: maxResults,
5397
- hybridWeight
5410
+ hybridWeight,
5411
+ prioritizeSourcePaths: sourceIntent
5398
5412
  });
5399
5413
  const fusionMs = performance2.now() - fusionStartTime;
5400
5414
  const rescued = promoteIdentifierMatches(
@@ -5403,30 +5417,33 @@ var Indexer = class {
5403
5417
  semanticCandidates,
5404
5418
  keywordCandidates,
5405
5419
  database,
5406
- branchChunkIds
5420
+ branchChunkIds,
5421
+ sourceIntent
5407
5422
  );
5408
5423
  const union = unionCandidates(semanticCandidates, keywordCandidates);
5409
5424
  const deterministicIdentifierLane = buildDeterministicIdentifierPass(
5410
5425
  query,
5411
5426
  union,
5412
- maxResults
5427
+ maxResults,
5428
+ sourceIntent
5413
5429
  );
5414
5430
  const identifierLane = buildIdentifierDefinitionLane(
5415
5431
  query,
5416
5432
  union,
5417
- maxResults
5433
+ maxResults,
5434
+ sourceIntent
5418
5435
  );
5419
5436
  const symbolLane = buildSymbolDefinitionLane(
5420
5437
  query,
5421
5438
  database,
5422
5439
  branchChunkIds,
5423
5440
  maxResults,
5424
- union
5441
+ union,
5442
+ sourceIntent
5425
5443
  );
5426
5444
  const prePrimaryLane = mergeTieredResults(deterministicIdentifierLane, identifierLane, maxResults * 4);
5427
5445
  const primaryLane = mergeTieredResults(prePrimaryLane, symbolLane, maxResults * 4);
5428
5446
  const tiered = mergeTieredResults(primaryLane, rescued, maxResults * 4);
5429
- const sourceIntent = classifyQueryIntentRaw(query) === "source";
5430
5447
  const hasCodeHints = extractCodeTermHints(query).length > 0 || extractIdentifierHints(query).length > 0;
5431
5448
  const baseFiltered = tiered.filter((r) => {
5432
5449
  if (r.score < this.config.search.minScore) return false;
@@ -7872,6 +7889,22 @@ function formatLogs(logs) {
7872
7889
  return `[${l.timestamp}] [${l.level.toUpperCase()}] [${l.category}] ${l.message}${dataStr}`;
7873
7890
  }).join("\n");
7874
7891
  }
7892
+ function formatDefinitionLookup(results, query) {
7893
+ if (results.length === 0) {
7894
+ return `No definition found for "${query}". Try codebase_search for broader discovery, or verify the symbol name.`;
7895
+ }
7896
+ const formatted = results.map((r, idx) => {
7897
+ 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}`;
7898
+ return `${header2} (score: ${r.score.toFixed(2)})
7899
+ \`\`\`
7900
+ ${truncateContent(r.content)}
7901
+ \`\`\``;
7902
+ });
7903
+ const header = results.length === 1 ? `Definition found for "${query}":` : `Found ${results.length} definition candidates for "${query}":`;
7904
+ return `${header}
7905
+
7906
+ ${formatted.join("\n\n")}`;
7907
+ }
7875
7908
  function formatSearchResults(results, scoreFormat = "similarity") {
7876
7909
  const formatted = results.map((r, idx) => {
7877
7910
  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}`;
@@ -8057,6 +8090,24 @@ var codebase_search = tool({
8057
8090
  ${formatSearchResults(results, "score")}`;
8058
8091
  }
8059
8092
  });
8093
+ var implementation_lookup = tool({
8094
+ 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.",
8095
+ args: {
8096
+ query: z.string().describe("Symbol name or natural language description (e.g., 'validateToken', 'where is the payment handler defined')"),
8097
+ limit: z.number().optional().default(5).describe("Maximum number of results"),
8098
+ fileType: z.string().optional().describe("Filter by file extension (e.g., 'ts', 'py')"),
8099
+ directory: z.string().optional().describe("Filter by directory path (e.g., 'src/utils')")
8100
+ },
8101
+ async execute(args) {
8102
+ const indexer = getIndexer();
8103
+ const results = await indexer.search(args.query, args.limit ?? 5, {
8104
+ fileType: args.fileType,
8105
+ directory: args.directory,
8106
+ definitionIntent: true
8107
+ });
8108
+ return formatDefinitionLookup(results, args.query);
8109
+ }
8110
+ });
8060
8111
  var call_graph = tool({
8061
8112
  description: "Query the call graph to find callers or callees of a function/method. Use to understand code flow and dependencies between functions.",
8062
8113
  args: {
@@ -8197,7 +8248,8 @@ var plugin = async ({ directory }) => {
8197
8248
  index_metrics,
8198
8249
  index_logs,
8199
8250
  find_similar,
8200
- call_graph
8251
+ call_graph,
8252
+ implementation_lookup
8201
8253
  },
8202
8254
  async config(cfg) {
8203
8255
  cfg.command = cfg.command ?? {};