openfox 2.0.37 → 2.0.39

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.
@@ -2,7 +2,7 @@ import {
2
2
  injectWorkflowKickoffIfNeeded,
3
3
  runAgentTurn,
4
4
  runChatTurn
5
- } from "./chunk-QG2WM7EX.js";
5
+ } from "./chunk-BG5ILIWN.js";
6
6
  import {
7
7
  applyDynamicContext,
8
8
  checkAborted,
@@ -16,7 +16,7 @@ import {
16
16
  loadAllAgentsDefault,
17
17
  saveItemToDir,
18
18
  spawnShellProcess
19
- } from "./chunk-BJPPDLJX.js";
19
+ } from "./chunk-UR4A2HYT.js";
20
20
  import {
21
21
  getPlatformShell,
22
22
  onProcessEvent
@@ -2056,4 +2056,4 @@ export {
2056
2056
  signalMcpReady,
2057
2057
  createWebSocketServer
2058
2058
  };
2059
- //# sourceMappingURL=chunk-DAC7YKYW.js.map
2059
+ //# sourceMappingURL=chunk-P4SOUTLD.js.map
@@ -71,7 +71,7 @@ import {
71
71
  import {
72
72
  loadGlobalConfig,
73
73
  saveGlobalConfig
74
- } from "./chunk-PWY6EBZ6.js";
74
+ } from "./chunk-EZ3BPIUV.js";
75
75
  import {
76
76
  getGlobalConfigDir
77
77
  } from "./chunk-CQGTEGKL.js";
@@ -2938,7 +2938,7 @@ async function describeImageFromDataUrl(dataUrl, visionModel, options) {
2938
2938
  import { createHash as createHash2 } from "crypto";
2939
2939
  async function loadVisionModelFromGlobalConfig() {
2940
2940
  try {
2941
- const { loadGlobalConfig: loadGlobalConfig2, getVisionFallback } = await import("./config-QI3KOU42.js");
2941
+ const { loadGlobalConfig: loadGlobalConfig2, getVisionFallback } = await import("./config-XOXIIBUY.js");
2942
2942
  const runtimeConfig = getRuntimeConfig();
2943
2943
  const mode = runtimeConfig.mode ?? "production";
2944
2944
  const globalConfig = await loadGlobalConfig2(mode);
@@ -3452,7 +3452,7 @@ var callSubAgentTool = {
3452
3452
  };
3453
3453
  }
3454
3454
  try {
3455
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-JPKBLAQ5.js");
3455
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-ZYUJUI4R.js");
3456
3456
  const toolRegistry = getToolRegistryForAgent2(agentDef);
3457
3457
  const turnMetrics = new TurnMetrics();
3458
3458
  const result = await executeSubAgent({
@@ -4268,7 +4268,7 @@ function resolveAgentDef2(sessionManager, sessionId) {
4268
4268
  }
4269
4269
  async function buildCachedPrompt(sessionManager, sessionId, agentDef) {
4270
4270
  const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
4271
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-JPKBLAQ5.js");
4271
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-ZYUJUI4R.js");
4272
4272
  const tools = getToolRegistryForAgent2(agentDef).definitions;
4273
4273
  const toolFingerprint = getToolFingerprint(tools);
4274
4274
  const allAgents = await loadAllAgentsDefault();
@@ -4281,7 +4281,7 @@ async function buildCachedPrompt(sessionManager, sessionId, agentDef) {
4281
4281
  async function computeSessionHash(sessionManager, sessionId) {
4282
4282
  const { instructionContent, skills } = await loadSessionContext(sessionManager, sessionId);
4283
4283
  const agentDef = await resolveAgentDef2(sessionManager, sessionId);
4284
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-JPKBLAQ5.js");
4284
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-ZYUJUI4R.js");
4285
4285
  const tools = getToolRegistryForAgent2(agentDef).definitions;
4286
4286
  const toolFingerprint = getToolFingerprint(tools);
4287
4287
  return computeDynamicContextHash(instructionContent, skills, toolFingerprint);
@@ -4388,7 +4388,7 @@ var mcpConfigTool = createTool(
4388
4388
  await saveGlobalConfig(mcpConfigMode, { ...globalConfig, mcpServers: updated });
4389
4389
  }
4390
4390
  async function rebuildTools() {
4391
- const { setMcpTools: setMcpTools2 } = await import("./tools-JPKBLAQ5.js");
4391
+ const { setMcpTools: setMcpTools2 } = await import("./tools-ZYUJUI4R.js");
4392
4392
  const mcpTools = createMcpTools(mcpManagerForTools);
4393
4393
  setMcpTools2(mcpTools);
4394
4394
  }
@@ -4401,9 +4401,10 @@ var mcpConfigTool = createTool(
4401
4401
  for (const server of servers) {
4402
4402
  const connStr = server.status === "connected" ? "\u25CF" : server.status === "error" ? "\u2717" : "\u25CB";
4403
4403
  const cmdStr = server.config.command ? `${server.config.command} ${(server.config.args ?? []).join(" ")}` : server.config.url ?? "";
4404
- lines.push(
4405
- `${connStr} ${server.name} (${server.config.transport}) \u2014 ${server.status}${server.error ? `: ${server.error}` : ""}`
4406
- );
4404
+ const hasCachedTools = server.tools.length > 0;
4405
+ const sourceLabel = server.status === "connected" ? " (live)" : hasCachedTools ? " (from cache)" : "";
4406
+ const statusLine = server.error ? `${server.status}${sourceLabel}: ${server.error}` : `${server.status}${sourceLabel}`;
4407
+ lines.push(`${connStr} ${server.name} (${server.config.transport}) \u2014 ${statusLine}`);
4407
4408
  lines.push(` ${cmdStr}`);
4408
4409
  lines.push(` ${server.tools.length} tools, ~${server.estimatedTokens} tokens`);
4409
4410
  const enabledTools = server.tools.filter((t) => t.enabled);
@@ -4488,6 +4489,270 @@ var mcpConfigTool = createTool(
4488
4489
  }
4489
4490
  );
4490
4491
 
4492
+ // src/server/tools/trace-code.ts
4493
+ import { stat as stat2, readFile as readFile8 } from "fs/promises";
4494
+ function graphNode(location, depth, relation, symbolName, symbolKind) {
4495
+ const node = { location, depth, relation, symbolName };
4496
+ if (symbolKind) node.symbolKind = symbolKind;
4497
+ return node;
4498
+ }
4499
+ var MAX_DEPTH = 5;
4500
+ var VALID_DIRECTIONS = ["up", "down", "both"];
4501
+ var SNIPPET_RADIUS = 2;
4502
+ var CACHE_MAX_SIZE = 50;
4503
+ function locationKey(loc) {
4504
+ return `${loc.path}:${loc.line}:${loc.character}`;
4505
+ }
4506
+ function formatLocation(loc, workdir) {
4507
+ const relPath = loc.path.startsWith(workdir) ? loc.path.slice(workdir.length + 1) : loc.path;
4508
+ return `${relPath}:${loc.line + 1}:${loc.character}`;
4509
+ }
4510
+ var fileCache = /* @__PURE__ */ new Map();
4511
+ async function getCachedLines(path, approvedPaths) {
4512
+ if (!approvedPaths.has(path)) return [];
4513
+ const cached = fileCache.get(path);
4514
+ if (cached) {
4515
+ try {
4516
+ const stats = await stat2(path);
4517
+ if (stats.mtimeMs === cached.mtimeMs) {
4518
+ return cached.lines;
4519
+ }
4520
+ } catch {
4521
+ }
4522
+ }
4523
+ try {
4524
+ const stats = await stat2(path);
4525
+ const content = await readFile8(path, "utf-8");
4526
+ const lines = content.split("\n");
4527
+ fileCache.set(path, { mtimeMs: stats.mtimeMs, lines });
4528
+ if (fileCache.size > CACHE_MAX_SIZE) {
4529
+ const oldest = fileCache.keys().next();
4530
+ if (!oldest.done && oldest.value !== void 0) {
4531
+ fileCache.delete(oldest.value);
4532
+ }
4533
+ }
4534
+ return lines;
4535
+ } catch {
4536
+ return [];
4537
+ }
4538
+ }
4539
+ async function getSnippet(path, line, approvedPaths, radius = SNIPPET_RADIUS) {
4540
+ const lines = await getCachedLines(path, approvedPaths);
4541
+ if (lines.length === 0) return "";
4542
+ const start = Math.max(0, line - radius);
4543
+ const end = Math.min(lines.length - 1, line + radius);
4544
+ const lineNumWidth = String(end + 1).length;
4545
+ const result = [];
4546
+ for (let i = start; i <= end; i++) {
4547
+ const gutter = i === line ? ">" : " ";
4548
+ const lineNum = String(i + 1).padStart(lineNumWidth);
4549
+ result.push(`${gutter} ${lineNum}\u2502 ${lines[i] ?? ""}`);
4550
+ }
4551
+ return result.join("\n");
4552
+ }
4553
+ function formatEdgeLabel(relation) {
4554
+ switch (relation) {
4555
+ case "definition":
4556
+ return "definition";
4557
+ case "references":
4558
+ return "reference";
4559
+ case "type-definition":
4560
+ return "type definition";
4561
+ default:
4562
+ return relation;
4563
+ }
4564
+ }
4565
+ async function collectNodes(lsp, startLocations, symbolName, symbolKind, maxDepth, direction) {
4566
+ const visited = /* @__PURE__ */ new Set();
4567
+ const nodes = [];
4568
+ const edges = [];
4569
+ const queue = startLocations.map((loc) => ({ location: loc, depth: 0, relation: "match" }));
4570
+ let idx = 0;
4571
+ while (idx < queue.length) {
4572
+ const item = queue[idx];
4573
+ idx++;
4574
+ const key = locationKey(item.location);
4575
+ if (visited.has(key)) continue;
4576
+ visited.add(key);
4577
+ nodes.push(graphNode(item.location, item.depth, item.relation, symbolName, symbolKind));
4578
+ if (item.parentKey) {
4579
+ const relation = item.relation === "definition" ? "definition" : item.relation === "type-definition" ? "type-definition" : "references";
4580
+ edges.push({ from: item.parentKey, to: key, relation });
4581
+ }
4582
+ if (item.depth >= maxDepth) continue;
4583
+ const { path, line, character } = item.location;
4584
+ if (direction === "down" || direction === "both") {
4585
+ const defs = await lsp.getDefinition(path, line, character);
4586
+ for (const def of defs) {
4587
+ const defKey = locationKey(def);
4588
+ if (!visited.has(defKey)) {
4589
+ queue.push({ location: def, depth: item.depth + 1, relation: "definition", parentKey: key });
4590
+ }
4591
+ }
4592
+ const typeDefs = await lsp.getTypeDefinition(path, line, character);
4593
+ for (const td of typeDefs) {
4594
+ const tdKey = locationKey(td);
4595
+ if (!visited.has(tdKey)) {
4596
+ queue.push({ location: td, depth: item.depth + 1, relation: "type-definition", parentKey: key });
4597
+ }
4598
+ }
4599
+ }
4600
+ if (direction === "up" || direction === "both") {
4601
+ const refs = await lsp.getReferences(path, line, character);
4602
+ for (const ref of refs) {
4603
+ const refKey = locationKey(ref);
4604
+ if (!visited.has(refKey)) {
4605
+ queue.push({ location: ref, depth: item.depth + 1, relation: "reference", parentKey: key });
4606
+ }
4607
+ }
4608
+ }
4609
+ }
4610
+ return { nodes, edges };
4611
+ }
4612
+ async function formatOutput(symbolName, direction, depth, nodes, edges, workdir, approvedPaths) {
4613
+ const lines = [];
4614
+ lines.push(`Symbol: ${symbolName}`);
4615
+ lines.push(`Direction: ${direction} | Depth: ${depth}`);
4616
+ lines.push(`Nodes: ${nodes.length} | Edges: ${edges.length}`);
4617
+ lines.push("");
4618
+ if (nodes.length === 0) {
4619
+ lines.push("No results found.");
4620
+ return lines.join("\n");
4621
+ }
4622
+ const byDepth = /* @__PURE__ */ new Map();
4623
+ for (const node of nodes) {
4624
+ const group = byDepth.get(node.depth) ?? [];
4625
+ group.push(node);
4626
+ byDepth.set(node.depth, group);
4627
+ }
4628
+ for (const [depth2, group] of [...byDepth.entries()].sort(([a], [b]) => a - b)) {
4629
+ lines.push(`\u2500\u2500 Depth ${depth2} \u2500\u2500`);
4630
+ const fileGroups = /* @__PURE__ */ new Map();
4631
+ for (const node of group) {
4632
+ const fileKey = node.location.path;
4633
+ const fileGroup = fileGroups.get(fileKey) ?? [];
4634
+ fileGroup.push(node);
4635
+ fileGroups.set(fileKey, fileGroup);
4636
+ }
4637
+ for (const [filePath, fileNodes] of fileGroups) {
4638
+ const relPath = filePath.startsWith(workdir) ? filePath.slice(workdir.length + 1) : filePath;
4639
+ if (fileNodes.length > 5) {
4640
+ const kinds = [...new Set(fileNodes.map((n) => formatEdgeLabel(n.relation)))];
4641
+ lines.push(` ${kinds.join(", ")} \xD7 ${fileNodes.length} in ${relPath}`);
4642
+ } else {
4643
+ for (const node of fileNodes) {
4644
+ const label = formatEdgeLabel(node.relation);
4645
+ const kind = node.symbolKind ? ` (${node.symbolKind})` : "";
4646
+ const loc = formatLocation(node.location, workdir);
4647
+ lines.push(` ${label}: ${loc}${kind}`);
4648
+ const snippet = await getSnippet(node.location.path, node.location.line, approvedPaths);
4649
+ if (snippet) {
4650
+ for (const snipLine of snippet.split("\n")) {
4651
+ lines.push(` ${snipLine}`);
4652
+ }
4653
+ }
4654
+ }
4655
+ }
4656
+ }
4657
+ lines.push("");
4658
+ }
4659
+ if (edges.length > 0 && edges.length <= 20) {
4660
+ lines.push("Edges:");
4661
+ for (const edge of edges) {
4662
+ lines.push(` ${edge.from} \u2500\u2500${edge.relation}\u2500\u2500\u25B6 ${edge.to}`);
4663
+ }
4664
+ lines.push("");
4665
+ } else if (edges.length > 20) {
4666
+ lines.push(`Edges: ${edges.length} total (suppressed, too many to display individually)`);
4667
+ lines.push("");
4668
+ }
4669
+ return lines.join("\n");
4670
+ }
4671
+ var traceCodeTool = createTool(
4672
+ "trace_code",
4673
+ {
4674
+ type: "function",
4675
+ function: {
4676
+ name: "trace_code",
4677
+ description: "Trace a symbol through the codebase using LSP-powered static analysis. Finds definitions, references, and type definitions up to a configurable depth. Returns a graph of locations with inline code snippets for each node.",
4678
+ parameters: {
4679
+ type: "object",
4680
+ properties: {
4681
+ symbol: {
4682
+ type: "string",
4683
+ description: 'Symbol name to trace (e.g., "rebuildTools", "handleSubmit", "UserProfile")'
4684
+ },
4685
+ file: {
4686
+ type: "string",
4687
+ description: "File path containing the symbol. Used to seed the LSP server and detect the language. Relative to the working directory."
4688
+ },
4689
+ depth: {
4690
+ type: "number",
4691
+ description: "Graph traversal depth (default: 1, max: 5). How many hops to follow. Start with 1 for immediate defs+refs.",
4692
+ default: 1
4693
+ },
4694
+ direction: {
4695
+ type: "string",
4696
+ enum: ["up", "down", "both"],
4697
+ description: '"down" follows definitions, "up" finds references, "both" does both (default).',
4698
+ default: "both"
4699
+ }
4700
+ },
4701
+ required: ["symbol", "file"]
4702
+ }
4703
+ }
4704
+ },
4705
+ async (args, context, helpers) => {
4706
+ const symbol = args.symbol?.trim();
4707
+ if (!symbol) {
4708
+ return helpers.error("symbol is required");
4709
+ }
4710
+ const file = args.file?.trim();
4711
+ if (!file) {
4712
+ return helpers.error("file is required");
4713
+ }
4714
+ const depth = args.depth ?? 1;
4715
+ if (depth > MAX_DEPTH) {
4716
+ return helpers.error(`depth cannot exceed ${MAX_DEPTH}`);
4717
+ }
4718
+ const direction = args.direction ?? "both";
4719
+ if (!VALID_DIRECTIONS.includes(direction)) {
4720
+ return helpers.error(`direction must be one of: ${VALID_DIRECTIONS.join(", ")}`);
4721
+ }
4722
+ const lsp = context.lspManager;
4723
+ if (!lsp) {
4724
+ return helpers.error("LSP is not available. The trace_code tool requires a running LSP server.");
4725
+ }
4726
+ const fullPath = helpers.resolvePath(file);
4727
+ try {
4728
+ await stat2(fullPath);
4729
+ } catch {
4730
+ return helpers.error(`File not found: "${file}". Check that the path exists.`);
4731
+ }
4732
+ let symbols;
4733
+ try {
4734
+ symbols = await lsp.seedAndFindWorkspaceSymbol(symbol, fullPath);
4735
+ } catch {
4736
+ return helpers.error(`Failed to search for symbol "${symbol}". LSP may not be responding.`);
4737
+ }
4738
+ if (symbols.length === 0) {
4739
+ const installHint = lsp.getInstallHint(fullPath);
4740
+ const hint = installHint ? ` ${installHint}` : "";
4741
+ return helpers.error(
4742
+ `Symbol "${symbol}" not found in "${file}". Check that the symbol name is correct and that the LSP server has indexed the project.${hint}`
4743
+ );
4744
+ }
4745
+ const startLocations = symbols.map((s) => s.location);
4746
+ const symbolKind = symbols[0].kind;
4747
+ const { nodes, edges } = await collectNodes(lsp, startLocations, symbol, symbolKind, depth, direction);
4748
+ const allPaths = [...new Set(nodes.map((n) => n.location.path))];
4749
+ await helpers.checkPathAccess(allPaths);
4750
+ const approvedPaths = new Set(allPaths);
4751
+ const output = await formatOutput(symbol, direction, depth, nodes, edges, context.workdir, approvedPaths);
4752
+ return helpers.success(output);
4753
+ }
4754
+ );
4755
+
4491
4756
  // src/server/tools/index.ts
4492
4757
  var _builtInTools;
4493
4758
  function getBuiltInTools() {
@@ -4506,7 +4771,8 @@ function getBuiltInTools() {
4506
4771
  devServerTool,
4507
4772
  stepDoneTool,
4508
4773
  backgroundProcessTool,
4509
- mcpConfigTool
4774
+ mcpConfigTool,
4775
+ traceCodeTool
4510
4776
  ];
4511
4777
  }
4512
4778
  return _builtInTools;
@@ -4792,4 +5058,4 @@ export {
4792
5058
  getToolRegistryForAgent,
4793
5059
  createToolRegistry
4794
5060
  };
4795
- //# sourceMappingURL=chunk-BJPPDLJX.js.map
5061
+ //# sourceMappingURL=chunk-UR4A2HYT.js.map
package/dist/cli/dev.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "../chunk-PKE4MQWI.js";
4
+ } from "../chunk-4RYP3RBY.js";
5
5
  import {
6
6
  logger
7
7
  } from "../chunk-K44MW7JJ.js";
package/dist/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "../chunk-PKE4MQWI.js";
4
+ } from "../chunk-4RYP3RBY.js";
5
5
  import {
6
6
  logger
7
7
  } from "../chunk-K44MW7JJ.js";
@@ -13,7 +13,7 @@ import {
13
13
  saveGlobalConfig,
14
14
  setDefaultModelSelection,
15
15
  updateProvider
16
- } from "./chunk-PWY6EBZ6.js";
16
+ } from "./chunk-EZ3BPIUV.js";
17
17
  import "./chunk-CQGTEGKL.js";
18
18
  export {
19
19
  activateProvider,
@@ -31,4 +31,4 @@ export {
31
31
  setDefaultModelSelection,
32
32
  updateProvider
33
33
  };
34
- //# sourceMappingURL=config-QI3KOU42.js.map
34
+ //# sourceMappingURL=config-XOXIIBUY.js.map
@@ -2,8 +2,8 @@ import {
2
2
  injectWorkflowKickoffIfNeeded,
3
3
  runAgentTurn,
4
4
  runChatTurn
5
- } from "./chunk-QG2WM7EX.js";
6
- import "./chunk-BJPPDLJX.js";
5
+ } from "./chunk-BG5ILIWN.js";
6
+ import "./chunk-UR4A2HYT.js";
7
7
  import "./chunk-DL6ZILAF.js";
8
8
  import "./chunk-PBGOZMVY.js";
9
9
  import "./chunk-VRGRAQDG.js";
@@ -28,7 +28,7 @@ import "./chunk-Z4FMBCJO.js";
28
28
  import "./chunk-Z6W4YHJB.js";
29
29
  import "./chunk-K44MW7JJ.js";
30
30
  import "./chunk-YD6NDTKF.js";
31
- import "./chunk-PWY6EBZ6.js";
31
+ import "./chunk-EZ3BPIUV.js";
32
32
  import "./chunk-CQGTEGKL.js";
33
33
  import "./chunk-V4IE7HJY.js";
34
34
  export {
@@ -42,4 +42,4 @@ export {
42
42
  runAgentTurn,
43
43
  runChatTurn
44
44
  };
45
- //# sourceMappingURL=orchestrator-PTKTND5E.js.map
45
+ //# sourceMappingURL=orchestrator-7B3XOZ4T.js.map
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openfox",
3
- "version": "2.0.37",
3
+ "version": "2.0.39",
4
4
  "description": "Local-LLM-first agentic coding assistant",
5
5
  "type": "module",
6
6
  "bin": {
@@ -3,7 +3,7 @@ import {
3
3
  finalizeTurnCompletion,
4
4
  generateSessionNameForSession
5
5
  } from "./chunk-JGNAYJJZ.js";
6
- import "./chunk-BJPPDLJX.js";
6
+ import "./chunk-UR4A2HYT.js";
7
7
  import "./chunk-DL6ZILAF.js";
8
8
  import "./chunk-PBGOZMVY.js";
9
9
  import "./chunk-VRGRAQDG.js";
@@ -28,7 +28,7 @@ import {
28
28
  logger
29
29
  } from "./chunk-K44MW7JJ.js";
30
30
  import "./chunk-YD6NDTKF.js";
31
- import "./chunk-PWY6EBZ6.js";
31
+ import "./chunk-EZ3BPIUV.js";
32
32
  import "./chunk-CQGTEGKL.js";
33
33
  import "./chunk-V4IE7HJY.js";
34
34
 
@@ -171,7 +171,7 @@ var QueueProcessor = class {
171
171
  backend: provider?.backend ?? llmClient.getBackend(),
172
172
  model: llmClient.getModel()
173
173
  };
174
- const { runChatTurn } = await import("./orchestrator-PTKTND5E.js");
174
+ const { runChatTurn } = await import("./orchestrator-7B3XOZ4T.js");
175
175
  const runChatTurnParams = buildRunChatTurnParams({
176
176
  sessionManager,
177
177
  sessionId,
@@ -216,4 +216,4 @@ var QueueProcessor = class {
216
216
  export {
217
217
  QueueProcessor
218
218
  };
219
- //# sourceMappingURL=processor-D6HYPRZD.js.map
219
+ //# sourceMappingURL=processor-FB2I73B3.js.map
@@ -18,7 +18,7 @@ import {
18
18
  loadGlobalConfig,
19
19
  removeProvider,
20
20
  saveGlobalConfig
21
- } from "./chunk-PWY6EBZ6.js";
21
+ } from "./chunk-EZ3BPIUV.js";
22
22
  import "./chunk-CQGTEGKL.js";
23
23
  import "./chunk-V4IE7HJY.js";
24
24
 
@@ -260,7 +260,7 @@ async function runProviderAdd(mode) {
260
260
  isActive: makeActive
261
261
  });
262
262
  if (makeActive) {
263
- const { setDefaultModelSelection } = await import("./config-QI3KOU42.js");
263
+ const { setDefaultModelSelection } = await import("./config-XOXIIBUY.js");
264
264
  newConfig = setDefaultModelSelection(
265
265
  newConfig,
266
266
  newConfig.providers[newConfig.providers.length - 1].id,
@@ -388,4 +388,4 @@ export {
388
388
  runProviderRemove,
389
389
  runProviderUse
390
390
  };
391
- //# sourceMappingURL=provider-ZLMMOORK.js.map
391
+ //# sourceMappingURL=provider-JLLIB72V.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  VERSION,
3
3
  createServer
4
- } from "./chunk-2G2H4HUO.js";
5
- import "./chunk-DAC7YKYW.js";
6
- import "./chunk-QG2WM7EX.js";
7
- import "./chunk-BJPPDLJX.js";
4
+ } from "./chunk-BMRC6TQ5.js";
5
+ import "./chunk-P4SOUTLD.js";
6
+ import "./chunk-BG5ILIWN.js";
7
+ import "./chunk-UR4A2HYT.js";
8
8
  import "./chunk-DL6ZILAF.js";
9
9
  import "./chunk-PBGOZMVY.js";
10
10
  import "./chunk-VRGRAQDG.js";
@@ -37,7 +37,7 @@ import {
37
37
  getActiveProvider,
38
38
  getDefaultModel,
39
39
  loadGlobalConfig
40
- } from "./chunk-PWY6EBZ6.js";
40
+ } from "./chunk-EZ3BPIUV.js";
41
41
  import {
42
42
  ensureDataDirExists,
43
43
  getDatabasePath,
@@ -199,4 +199,4 @@ async function runServe(options) {
199
199
  export {
200
200
  runServe
201
201
  };
202
- //# sourceMappingURL=serve-NGAWODZ2.js.map
202
+ //# sourceMappingURL=serve-RZWSK3AA.js.map
@@ -118,6 +118,33 @@ interface LLMClientWithModel extends LLMClient {
118
118
  setBackend(backend: Backend): void;
119
119
  }
120
120
 
121
+ interface CodeLocation {
122
+ path: string;
123
+ line: number;
124
+ character: number;
125
+ endLine: number;
126
+ endCharacter: number;
127
+ }
128
+ interface SymbolInfo {
129
+ name: string;
130
+ kind: string;
131
+ location: CodeLocation;
132
+ containerName?: string;
133
+ }
134
+ interface HoverInfo {
135
+ contents: string;
136
+ range?: {
137
+ start: {
138
+ line: number;
139
+ character: number;
140
+ };
141
+ end: {
142
+ line: number;
143
+ character: number;
144
+ };
145
+ };
146
+ }
147
+
121
148
  interface LspManagerInterface {
122
149
  /**
123
150
  * Notify the LSP that a file has changed and get diagnostics
@@ -136,6 +163,34 @@ interface LspManagerInterface {
136
163
  * Get installation hint for a file's language server, if it's not installed
137
164
  */
138
165
  getInstallHint(path: string): string | null;
166
+ /**
167
+ * Find the definition of a symbol at the given position
168
+ */
169
+ getDefinition(path: string, line: number, character: number): Promise<CodeLocation[]>;
170
+ /**
171
+ * Find all references to a symbol at the given position
172
+ */
173
+ getReferences(path: string, line: number, character: number): Promise<CodeLocation[]>;
174
+ /**
175
+ * Find the type definition of a symbol at the given position
176
+ */
177
+ getTypeDefinition(path: string, line: number, character: number): Promise<CodeLocation[]>;
178
+ /**
179
+ * Search workspace for a symbol by name
180
+ */
181
+ findWorkspaceSymbol(query: string): Promise<SymbolInfo[]>;
182
+ /**
183
+ * Open a file to seed the LSP server, then search for a workspace symbol.
184
+ * Some LSP servers (e.g., typescript-language-server) only index projects
185
+ * after a file is opened via textDocument/didOpen. This method handles
186
+ * that by opening the given file first, flushing the notification queue,
187
+ * then querying workspace/symbol.
188
+ */
189
+ seedAndFindWorkspaceSymbol(query: string, filePath: string): Promise<SymbolInfo[]>;
190
+ /**
191
+ * Get hover information for a symbol at the given position
192
+ */
193
+ getHoverInfo(path: string, line: number, character: number): Promise<HoverInfo | null>;
139
194
  /**
140
195
  * Shutdown all LSP servers
141
196
  */
@@ -242,6 +297,39 @@ declare class LspManager implements LspManagerInterface {
242
297
  * to avoid spamming the user on every edit.
243
298
  */
244
299
  getInstallHint(path: string): string | null;
300
+ /**
301
+ * Find the definition of a symbol at the given position.
302
+ */
303
+ getDefinition(path: string, line: number, character: number): Promise<CodeLocation[]>;
304
+ /**
305
+ * Find all references to a symbol at the given position.
306
+ */
307
+ getReferences(path: string, line: number, character: number): Promise<CodeLocation[]>;
308
+ /**
309
+ * Find the type definition of a symbol at the given position.
310
+ */
311
+ getTypeDefinition(path: string, line: number, character: number): Promise<CodeLocation[]>;
312
+ /**
313
+ * Search workspace for a symbol by name.
314
+ * Uses the first available server that supports workspace/symbol.
315
+ */
316
+ findWorkspaceSymbol(query: string): Promise<SymbolInfo[]>;
317
+ /**
318
+ * Open a file to seed the LSP server, then search for a workspace symbol.
319
+ *
320
+ * Some LSP servers (e.g., typescript-language-server) only index projects
321
+ * after a file is opened via textDocument/didOpen. This method:
322
+ * 1. Detects the language from the file and starts the appropriate server
323
+ * 2. Reads the file from disk and sends didOpen to trigger project indexing
324
+ * 3. Sends a hover request to flush the notification queue (JSON-RPC processes
325
+ * requests sequentially, so the server must finish didOpen before responding)
326
+ * 4. Queries workspace/symbol for the given symbol
327
+ */
328
+ seedAndFindWorkspaceSymbol(query: string, filePath: string): Promise<SymbolInfo[]>;
329
+ /**
330
+ * Get hover information for a symbol at the given position.
331
+ */
332
+ getHoverInfo(path: string, line: number, character: number): Promise<HoverInfo | null>;
245
333
  /**
246
334
  * Shutdown all LSP servers.
247
335
  */
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createServer,
3
3
  createServerHandle
4
- } from "../chunk-2G2H4HUO.js";
5
- import "../chunk-DAC7YKYW.js";
6
- import "../chunk-QG2WM7EX.js";
7
- import "../chunk-BJPPDLJX.js";
4
+ } from "../chunk-BMRC6TQ5.js";
5
+ import "../chunk-P4SOUTLD.js";
6
+ import "../chunk-BG5ILIWN.js";
7
+ import "../chunk-UR4A2HYT.js";
8
8
  import "../chunk-DL6ZILAF.js";
9
9
  import "../chunk-PBGOZMVY.js";
10
10
  import "../chunk-VRGRAQDG.js";
@@ -29,7 +29,7 @@ import "../chunk-IEDE6VK4.js";
29
29
  import "../chunk-K44MW7JJ.js";
30
30
  import "../chunk-VUQCQXXJ.js";
31
31
  import "../chunk-YD6NDTKF.js";
32
- import "../chunk-PWY6EBZ6.js";
32
+ import "../chunk-EZ3BPIUV.js";
33
33
  import "../chunk-CQGTEGKL.js";
34
34
  import "../chunk-V4IE7HJY.js";
35
35
  export {