mcp-lsp-driver 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -252,6 +252,14 @@ interface DefinitionProvider {
252
252
  * @returns Array of code snippets representing definition locations
253
253
  */
254
254
  provideDefinition(uri: UnifiedUri, position: ExactPosition): Promise<CodeSnippet[]>;
255
+ /**
256
+ * Returns the type definition location for the symbol at the given position.
257
+ *
258
+ * @param uri - The URI of the file
259
+ * @param position - The exact position to find the type definition for
260
+ * @returns Array of code snippets representing type definition locations
261
+ */
262
+ provideTypeDefinition?(uri: UnifiedUri, position: ExactPosition): Promise<CodeSnippet[]>;
255
263
  }
256
264
  /**
257
265
  * Provides find-references functionality.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PartialIdeCapabilities, F as FileAccessProvider, I as IdeCapabilities, U as UnifiedUri, a as FuzzyPosition, E as ExactPosition, D as DiskRange } from './capabilities-96hGHyOj.js';
2
- export { C as CodeSnippet, b as DefinitionProvider, c as Diagnostic, d as DiagnosticSeverity, e as DiagnosticsProvider, f as DocumentSymbol, g as EditFailureReason, h as EditProvider, i as EditResult, j as Frontmatter, k as FrontmatterMatch, l as FrontmatterProvider, m as FrontmatterValue, G as GlobalFindMatch, n as GlobalFindOptions, o as GlobalFindProvider, p as GraphProvider, H as HierarchyProvider, L as Link, O as OnDiagnosticsChangedCallback, q as OutlineProvider, r as PendingEditOperation, R as ReferencesProvider, S as SymbolKind, T as TextEdit } from './capabilities-96hGHyOj.js';
1
+ import { P as PartialIdeCapabilities, F as FileAccessProvider, I as IdeCapabilities, U as UnifiedUri, a as FuzzyPosition, E as ExactPosition, D as DiskRange } from './capabilities-DM3FLRwy.js';
2
+ export { C as CodeSnippet, b as DefinitionProvider, c as Diagnostic, d as DiagnosticSeverity, e as DiagnosticsProvider, f as DocumentSymbol, g as EditFailureReason, h as EditProvider, i as EditResult, j as Frontmatter, k as FrontmatterMatch, l as FrontmatterProvider, m as FrontmatterValue, G as GlobalFindMatch, n as GlobalFindOptions, o as GlobalFindProvider, p as GraphProvider, H as HierarchyProvider, L as Link, O as OnDiagnosticsChangedCallback, q as OutlineProvider, r as PendingEditOperation, R as ReferencesProvider, S as SymbolKind, T as TextEdit } from './capabilities-DM3FLRwy.js';
3
3
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
4
 
5
5
  /**
package/dist/index.js CHANGED
@@ -1,15 +1,15 @@
1
- import {connect,createServer}from'net';import {unlinkSync}from'fs';import {ResourceTemplate}from'@modelcontextprotocol/sdk/server/mcp.js';import {z as z$1}from'zod';function Y(t){return t[0]}function Z(t){return t[0]}function ee(t){if(t.length!==0)return t.length===1?t[0]:{async provideDefinition(e,r){return (await Promise.all(t.map(i=>i.provideDefinition(e,r)))).flat()}}}function te(t){if(t.length!==0)return t.length===1?t[0]:{async provideReferences(e,r){return (await Promise.all(t.map(i=>i.provideReferences(e,r)))).flat()}}}function re(t){if(t.length!==0)return t.length===1?t[0]:{async provideCallHierarchy(e,r,n){return (await Promise.all(t.map(o=>o.provideCallHierarchy(e,r,n)))).flat()}}}function ne(t){if(t.length===0)return;if(t.length===1)return t[0];let e={async provideDiagnostics(n){return (await Promise.all(t.map(o=>o.provideDiagnostics(n)))).flat()}},r=t.map(n=>n.getWorkspaceDiagnostics).filter(n=>n!=null);return r.length>0&&(e.getWorkspaceDiagnostics=async()=>(await Promise.all(r.map(i=>i()))).flat()),e}function ie(t){if(t.length!==0)return t.length===1?t[0]:{async provideDocumentSymbols(e){return (await Promise.all(t.map(n=>n.provideDocumentSymbols(e)))).flat()}}}function oe(t){if(t.length!==0)return t.length===1?t[0]:{async globalFind(e,r){return (await Promise.all(t.map(i=>i.globalFind(e,r)))).flat()},async globalReplace(e,r,n){return (await Promise.all(t.map(o=>o.globalReplace(e,r,n)))).reduce((o,s)=>o+s,0)}}}function se(t){if(t.length===1)return t[0];let[e]=t;if(e)return {async getLinkStructure(){return (await Promise.all(t.map(n=>n.getLinkStructure()))).flat()},async resolveOutlinks(r){return (await Promise.all(t.map(i=>i.resolveOutlinks(r)))).flat()},async resolveBacklinks(r){return (await Promise.all(t.map(i=>i.resolveBacklinks(r)))).flat()},addLink:(r,n,i)=>e.addLink(r,n,i)}}function ae(t){if(t.length===1)return t[0];let[e]=t;if(e)return {async getFrontmatterStructure(r,n){return (await Promise.all(t.map(o=>o.getFrontmatterStructure(r,n)))).flat()},async getFrontmatter(r){let n=await Promise.all(t.map(i=>i.getFrontmatter(r)));return Object.assign({},...n)},setFrontmatter:(r,n,i)=>e.setFrontmatter(r,n,i)}}function ce(t){if(t.length!==0)return t.length===1?t[0]:e=>{for(let r of t)r(e);}}function h(t,e){let r=[];for(let n of t){let i=n[e];i!=null&&r.push(i);}return r}function le(t,e){return t.length===0?{fileAccess:e}:{fileAccess:Y(h(t,"fileAccess"))??e,edit:Z(h(t,"edit")),definition:ee(h(t,"definition")),references:te(h(t,"references")),hierarchy:re(h(t,"hierarchy")),diagnostics:ne(h(t,"diagnostics")),outline:ie(h(t,"outline")),globalFind:oe(h(t,"globalFind")),graph:se(h(t,"graph")),frontmatter:ae(h(t,"frontmatter")),onDiagnosticsChanged:ce(h(t,"onDiagnosticsChanged"))}}var k=class{socket;requestHandler;notificationHandler;nextId=1;pending=new Map;buffer="";destroyed=false;constructor(e,r){this.socket=e,this.requestHandler=r?.onRequest,this.notificationHandler=r?.onNotification,e.on("data",n=>this.handleData(n)),e.on("close",()=>this.rejectAll(new Error("Connection closed"))),e.on("error",n=>this.rejectAll(n));}sendRequest(e,r){return this.destroyed?Promise.reject(new Error("Transport destroyed")):new Promise((n,i)=>{let o=this.nextId++;this.pending.set(o,{resolve:n,reject:i});let s={type:"request",id:o,method:e,params:r};this.socket.write(`${JSON.stringify(s)}
1
+ import {connect,createServer}from'net';import {unlinkSync}from'fs';import {ResourceTemplate}from'@modelcontextprotocol/sdk/server/mcp.js';import {z as z$1}from'zod';function Y(t){return t[0]}function Z(t){return t[0]}function ee(t){if(t.length!==0)return t.length===1?t[0]:{async provideDefinition(e,r){return (await Promise.all(t.map(i=>i.provideDefinition(e,r)))).flat()}}}function te(t){if(t.length!==0)return t.length===1?t[0]:{async provideReferences(e,r){return (await Promise.all(t.map(i=>i.provideReferences(e,r)))).flat()}}}function re(t){if(t.length!==0)return t.length===1?t[0]:{async provideCallHierarchy(e,r,n){return (await Promise.all(t.map(o=>o.provideCallHierarchy(e,r,n)))).flat()}}}function ne(t){if(t.length===0)return;if(t.length===1)return t[0];let e={async provideDiagnostics(n){return (await Promise.all(t.map(o=>o.provideDiagnostics(n)))).flat()}},r=t.map(n=>n.getWorkspaceDiagnostics).filter(n=>n!=null);return r.length>0&&(e.getWorkspaceDiagnostics=async()=>(await Promise.all(r.map(i=>i()))).flat()),e}function ie(t){if(t.length!==0)return t.length===1?t[0]:{async provideDocumentSymbols(e){return (await Promise.all(t.map(n=>n.provideDocumentSymbols(e)))).flat()}}}function oe(t){if(t.length!==0)return t.length===1?t[0]:{async globalFind(e,r){return (await Promise.all(t.map(i=>i.globalFind(e,r)))).flat()},async globalReplace(e,r,n){return (await Promise.all(t.map(o=>o.globalReplace(e,r,n)))).reduce((o,s)=>o+s,0)}}}function se(t){if(t.length===1)return t[0];let[e]=t;if(e)return {async getLinkStructure(){return (await Promise.all(t.map(n=>n.getLinkStructure()))).flat()},async resolveOutlinks(r){return (await Promise.all(t.map(i=>i.resolveOutlinks(r)))).flat()},async resolveBacklinks(r){return (await Promise.all(t.map(i=>i.resolveBacklinks(r)))).flat()},addLink:(r,n,i)=>e.addLink(r,n,i)}}function ae(t){if(t.length===1)return t[0];let[e]=t;if(e)return {async getFrontmatterStructure(r,n){return (await Promise.all(t.map(o=>o.getFrontmatterStructure(r,n)))).flat()},async getFrontmatter(r){let n=await Promise.all(t.map(i=>i.getFrontmatter(r)));return Object.assign({},...n)},setFrontmatter:(r,n,i)=>e.setFrontmatter(r,n,i)}}function ce(t){if(t.length!==0)return t.length===1?t[0]:e=>{for(let r of t)r(e);}}function y(t,e){let r=[];for(let n of t){let i=n[e];i!=null&&r.push(i);}return r}function le(t,e){return t.length===0?{fileAccess:e}:{fileAccess:Y(y(t,"fileAccess"))??e,edit:Z(y(t,"edit")),definition:ee(y(t,"definition")),references:te(y(t,"references")),hierarchy:re(y(t,"hierarchy")),diagnostics:ne(y(t,"diagnostics")),outline:ie(y(t,"outline")),globalFind:oe(y(t,"globalFind")),graph:se(y(t,"graph")),frontmatter:ae(y(t,"frontmatter")),onDiagnosticsChanged:ce(y(t,"onDiagnosticsChanged"))}}var S=class{socket;requestHandler;notificationHandler;nextId=1;pending=new Map;buffer="";destroyed=false;constructor(e,r){this.socket=e,this.requestHandler=r?.onRequest,this.notificationHandler=r?.onNotification,e.on("data",n=>this.handleData(n)),e.on("close",()=>this.rejectAll(new Error("Connection closed"))),e.on("error",n=>this.rejectAll(n));}sendRequest(e,r){return this.destroyed?Promise.reject(new Error("Transport destroyed")):new Promise((n,i)=>{let o=this.nextId++;this.pending.set(o,{resolve:n,reject:i});let s={type:"request",id:o,method:e,params:r};this.socket.write(`${JSON.stringify(s)}
2
2
  `);})}sendNotification(e,r){if(this.destroyed)return;let n={type:"notification",method:e,params:r};this.socket.write(`${JSON.stringify(n)}
3
3
  `);}destroy(){this.destroyed||(this.destroyed=true,this.rejectAll(new Error("Transport destroyed")),this.socket.destroy());}handleData(e){this.buffer+=e.toString();let r=this.buffer.split(`
4
4
  `);this.buffer=r.pop()??"";for(let n of r){let i=n.replace(/\r$/,"");if(i)try{let o=JSON.parse(i);this.dispatch(o);}catch{}}}dispatch(e){switch(e.type){case "response":{let r=this.pending.get(e.id);r&&(this.pending.delete(e.id),e.error?r.reject(new Error(e.error.message)):r.resolve(e.result));break}case "request":{this.requestHandler&&this.requestHandler(e.method,e.params).then(r=>{if(this.destroyed)return;let n={type:"response",id:e.id,result:r};this.socket.write(`${JSON.stringify(n)}
5
5
  `);}).catch(r=>{if(this.destroyed)return;let n={type:"response",id:e.id,error:{message:r instanceof Error?r.message:String(r)}};this.socket.write(`${JSON.stringify(n)}
6
- `);});break}case "notification":{this.notificationHandler?.(e.method,e.params);break}}}rejectAll(e){for(let[,r]of this.pending)r.reject(e);this.pending.clear();}};function T(t){return process.platform==="win32"?`\\\\.\\pipe\\${t}`:`/tmp/${t}.sock`}var R=[{providerKey:"fileAccess",methods:["readFile","readDirectory","getFileTree"]},{providerKey:"edit",methods:["applyEdits","previewAndApplyEdits"]},{providerKey:"definition",methods:["provideDefinition"]},{providerKey:"references",methods:["provideReferences"]},{providerKey:"hierarchy",methods:["provideCallHierarchy"]},{providerKey:"diagnostics",methods:["provideDiagnostics","getWorkspaceDiagnostics"]},{providerKey:"outline",methods:["provideDocumentSymbols"]},{providerKey:"globalFind",methods:["globalFind","globalReplace"]},{providerKey:"graph",methods:["getLinkStructure","resolveOutlinks","resolveBacklinks","addLink"]},{providerKey:"frontmatter",methods:["getFrontmatterStructure","getFrontmatter","setFrontmatter"]}];function ue(t){let{pipeName:e,connectTimeout:r=5e3}=t,n=T(e);return new Promise((i,o)=>{let s=connect(n),a=false,l=setTimeout(()=>{a||(a=true,s.destroy(),o(new Error(`Connection timeout after ${r}ms`)));},r);s.on("error",c=>{a||(a=true,clearTimeout(l),o(c));}),s.on("connect",()=>{if(clearTimeout(l),a)return;let c,p=new k(s,{onNotification:(f,g)=>{f==="onDiagnosticsChanged"&&c&&c(g[0]);}});p.sendRequest("_handshake",[]).then(f=>{if(a)return;let b=f.methods;if(!b.includes("fileAccess.readFile")||!b.includes("fileAccess.readDirectory"))throw p.destroy(),new Error("Server missing required methods: fileAccess.readFile, fileAccess.readDirectory");let P={};for(let{providerKey:v,methods:D}of R){let O=D.filter(E=>b.includes(`${v}.${E}`));if(O.length===0)continue;let _={};for(let E of O)_[E]=(...X)=>p.sendRequest(`${v}.${E}`,X);P[v]=_;}b.includes("onDiagnosticsChanged")&&(P.onDiagnosticsChanged=v=>{c=v;}),a=true,i({capabilities:P,availableMethods:b,disconnect(){p.destroy();}});}).catch(f=>{a||(a=true,p.destroy(),o(f instanceof Error?f:new Error(String(f))));});});})}function fe(t){let{capabilities:e,pipeName:r}=t,n=T(r),i=new Map;for(let{providerKey:l,methods:c}of R){let p=e[l];if(p)for(let f of c){let g=p[f];if(typeof g=="function"){let b=`${l}.${f}`;i.set(b,(...P)=>g.apply(p,P));}}}let o=[...i.keys()];e.onDiagnosticsChanged&&o.push("onDiagnosticsChanged");let s=new Set,a=createServer(l=>{let c=new k(l,{onRequest:async(p,f)=>{if(p==="_handshake")return {methods:o};let g=i.get(p);if(!g)throw new Error(`Unknown method: ${p}`);return g(...f)}});s.add(c),l.on("close",()=>s.delete(c));});return e.onDiagnosticsChanged&&e.onDiagnosticsChanged(l=>{for(let c of s)c.sendNotification("onDiagnosticsChanged",[l]);}),new Promise((l,c)=>{if(process.platform!=="win32")try{unlinkSync(n);}catch{}a.on("error",c),a.listen(n,()=>{a.removeListener("error",c),l({get pipePath(){return n},get connectionCount(){return s.size},async close(){for(let p of s)p.destroy();if(s.clear(),await new Promise((p,f)=>{a.close(g=>{g?f(g):p();});}),process.platform!=="win32")try{unlinkSync(n);}catch{}}});});})}var x=class extends Error{constructor(r,n,i){super(`Could not find symbol '${r}' at or near line ${n}. ${i}`);this.symbolName=r;this.lineHint=n;this.reason=i;this.name="SymbolResolutionError";}},S=class{constructor(e,r){this.fs=e;this.lineSearchRadius=r?.lineSearchRadius??2;}lineSearchRadius;async resolvePosition(e,r){let i=(await this.fs.readFile(e)).split(/\r?\n/),o=r.lineHint-1,s=r.orderHint??0,a=this.findSymbolInLine(i[o],r.symbolName,s);if(a!==null)return {line:o,character:a};for(let l=1;l<=this.lineSearchRadius;l++){let c=o-l;if(c>=0){let f=this.findSymbolInLine(i[c],r.symbolName,s);if(f!==null)return {line:c,character:f}}let p=o+l;if(p<i.length){let f=this.findSymbolInLine(i[p],r.symbolName,s);if(f!==null)return {line:p,character:f}}}throw new x(r.symbolName,r.lineHint,`Please verify the file content and try again. Searched lines ${Math.max(1,r.lineHint-this.lineSearchRadius)} to ${Math.min(i.length,r.lineHint+this.lineSearchRadius)}.`)}findSymbolInLine(e,r,n){if(e===void 0||e.length===0)return null;let i=0,o=0;for(;i<e.length;){let s=e.indexOf(r,i);if(s===-1)break;if(o===n)return s;o++,i=s+1;}return null}async findExactText(e,r){let n=await this.fs.readFile(e),i=[],o=0;for(;o<n.length;){let p=n.indexOf(r,o);if(p===-1)break;i.push(p),o=p+1;}if(i.length===0)throw new Error(`Text not found in file: "${r.slice(0,50)}${r.length>50?"...":""}"`);if(i.length>1)throw new Error(`Text appears ${i.length} times in file. Please provide more context to uniquely identify the location.`);let s=i[0],a=s+r.length,l=this.offsetToPosition(n,s),c=this.offsetToPosition(n,a);return {start:l,end:c}}offsetToPosition(e,r){let n=0,i=0,o=0;for(let s of e){if(o===r)break;s===`
7
- `?(n++,i=0):i++,o++;}return {line:n,character:i}}};var y=t=>({content:[{type:"text",text:JSON.stringify(t??"")}],structuredContent:t});function m(t){if(t.includes(".."))throw new Error('URI could not include ".." operator');return t.replace(/\\/g,"/")}function M(){return `edit-${Date.now()}`}function F(t){return t.length===0?"No diagnostics found.":t.map(e=>{let r=e.range.start.line+1,n=e.severity.toUpperCase(),i=e.source?` [${e.source}]`:"",o=e.code!==void 0?` (${e.code})`:"";return `- **${n}**${i}${o} at line ${r}: ${e.message}`}).join(`
8
- `)}function $(t,e=0){if(t.length===0&&e===0)return "No symbols found.";let r=" ".repeat(e);return t.map(n=>{let i=n.range.start.line+1,o=n.range.end.line+1,s=i===o?`line ${i}`:`lines ${i}-${o}`,a=n.detail?` - ${n.detail}`:"",l=`${r}- **${n.kind}** \`${n.name}\`${a} (${s})`;return n.children&&n.children.length>0?`${l}
9
- ${$(n.children,e+1)}`:l}).join(`
10
- `)}var L=z$1.string().describe("The relative file path"),N=z$1.string().describe("The text of the symbol to find"),A=z$1.number().int().positive().describe("Approximate 1-based line number where the symbol is expected"),H=z$1.number().int().min(0).default(0).describe("0-based index of which occurrence to target if symbol appears multiple times"),I=z$1.object({uri:L,symbol_name:N,line_hint:A,order_hint:H}),C=z$1.object({uri:L,search_text:z$1.string().describe("Exact text to replace (must exist uniquely in the file)"),replace_text:z$1.string().describe("New text to insert"),description:z$1.string().describe("Rationale for the edit")}),G=z$1.object({uri:z$1.string().describe("The file URI or path"),symbol_name:N,line_hint:A,order_hint:H,direction:z$1.enum(["incoming","outgoing"]).describe("Direction of the call hierarchy")}),U=z$1.string().describe("The search query"),K=z$1.boolean().default(false).describe("Whether the search is case-sensitive"),q=z$1.boolean().default(false).describe("Whether to match exact words only"),z=z$1.boolean().default(false).describe("Whether the query is a regular expression"),J=z$1.object({query:U,case_sensitive:K,exact_match:q,regex_mode:z}),W=z$1.object({query:U,case_sensitive:K,exact_match:q,regex_mode:z,replace_with:z$1.string().describe("The replacement text")}),B=z$1.object({path:z$1.string().describe("The path to the document to modify"),pattern:z$1.string().describe("The text pattern to find and replace with a link"),link_to:z$1.string().describe("The target URI the link should point to")}),V=z$1.object({property:z$1.string().describe("The frontmatter property name to search for"),path:z$1.string().optional().describe("Optional path to limit the search to a specific document. If not provided, searches all documents.")}),Q=z$1.object({path:z$1.string().describe("The path to the document to modify"),property:z$1.string().describe("The frontmatter property name to set"),value:z$1.union([z$1.string(),z$1.array(z$1.string()),z$1.number(),z$1.array(z$1.number()),z$1.boolean(),z$1.array(z$1.boolean()),z$1.null()]).describe("The value to set. Can be a string, number, boolean, array of these types, or null to remove.")});function me(t){if(!t)return null;let e=t.match(/^L(\d+)(?:-L(\d+))?$/);if(!e||!e[1])return null;let r=parseInt(e[1],10),n=e[2]?parseInt(e[2],10):r;return r<1||n<r?null:{start:r,end:n}}function ge(t,e){let r=t.split(/\r?\n/),n=e.start-1,i=e.end;return r.slice(n,i).join(`
11
- `)}function he({server:t,capabilities:e,config:r}){let n=new S(e.fileAccess,r?.resolverConfig);try{ye(t,e,n);}catch(i){return {success:false,error:i,reason:"Error occured during registration of tools"}}try{be(t,e);}catch(i){return {success:false,error:i,reason:"Error occured during registration of resources"}}return {success:true}}function ye(t,e,r){e.definition&&ve(t,e,r),e.references&&Pe(t,e,r),e.hierarchy&&xe(t,e,r),e.edit&&Se(t,e,r),e.globalFind&&(Ee(t,e),Te(t,e)),e.graph&&(De(t,e),Fe(t,e)),e.frontmatter&&($e(t,e),Ie(t,e));}function be(t,e){Ce(t,e),e.diagnostics&&we(t,e),e.outline&&ke(t,e),e.graph&&Re(t,e),e.frontmatter&&Oe(t,e);}function ve(t,e,r){let n=e.definition;n&&t.registerTool("goto_definition",{description:"Navigate to the definition of a symbol.",inputSchema:I,outputSchema:{snippets:z$1.array(z$1.object({uri:z$1.string(),startLine:z$1.number(),endLine:z$1.number(),content:z$1.string()}))}},async i=>{try{let o=m(i.uri),s={symbolName:i.symbol_name,lineHint:i.line_hint,orderHint:i.order_hint},a=await r.resolvePosition(o,s),l=(await n.provideDefinition(o,a)).map(c=>({uri:c.uri,startLine:c.range.start.line+1,endLine:c.range.end.line+1,content:c.content}));return y({snippets:l})}catch(o){let s=o instanceof x?o.message:`Error: ${o instanceof Error?o.message:String(o)}`;return {content:[{type:"text",text:s}],structuredContent:{error:s},isError:true}}});}function Pe(t,e,r){let n=e.references;n&&t.registerTool("find_references",{description:"Find all references to a symbol. Returns a list of locations where the symbol is used.",inputSchema:I,outputSchema:{snippets:z$1.array(z$1.object({uri:z$1.string(),startLine:z$1.number(),endLine:z$1.number(),content:z$1.string()}))}},async i=>{try{let o=m(i.uri),s={symbolName:i.symbol_name,lineHint:i.line_hint,orderHint:i.order_hint},a=await r.resolvePosition(o,s),l=(await n.provideReferences(o,a)).map(c=>({uri:c.uri,startLine:c.range.start.line+1,endLine:c.range.end.line+1,content:c.content}));return y({snippets:l})}catch(o){let s=o instanceof x?o.message:`Error: ${o instanceof Error?o.message:String(o)}`;return {content:[{type:"text",text:s}],structuredContent:{error:s},isError:true}}});}function xe(t,e,r){let n=e.hierarchy;n&&t.registerTool("call_hierarchy",{description:"Get call hierarchy for a function or method. Shows incoming or outgoing calls.",inputSchema:G,outputSchema:{snippets:z$1.array(z$1.object({uri:z$1.string(),startLine:z$1.number(),endLine:z$1.number(),content:z$1.string()}))}},async i=>{try{let o=m(i.uri),s={symbolName:i.symbol_name,lineHint:i.line_hint,orderHint:i.order_hint},a=await r.resolvePosition(o,s),l=(await n.provideCallHierarchy(o,a,i.direction)).map(c=>({uri:c.uri,startLine:c.range.start.line+1,endLine:c.range.end.line+1,content:c.content}));return y({snippets:l})}catch(o){let s=o instanceof x?o.message:`Error: ${o instanceof Error?o.message:String(o)}`;return {content:[{type:"text",text:s}],structuredContent:{error:s},isError:true}}});}function we(t,e){let r=e.diagnostics;if(!r)return;let n=new ResourceTemplate("diagnostics://{+path}",{list:void 0});if(t.registerResource("diagnostics",n,{description:"Diagnostics (errors, warnings, hints) for a specific file. Use the file path after diagnostics://",mimeType:"text/markdown"},async(i,o)=>{try{let s=o.path,a=m(s),l=await r.provideDiagnostics(a),c=F(l);return {contents:[{uri:`diagnostics://${s}`,mimeType:"text/markdown",text:c}]}}catch(s){let a=`Error: ${s instanceof Error?s.message:String(s)}`;return {contents:[{uri:`diagnostics://${o.path}`,mimeType:"text/markdown",text:a}]}}}),r.getWorkspaceDiagnostics){let i=r.getWorkspaceDiagnostics.bind(r);t.registerResource("workspace-diagnostics","diagnostics://workspace",{description:"All diagnostics (errors, warnings, hints) across the entire workspace",mimeType:"text/markdown"},async()=>{try{let o=await i(),s=new Map;for(let l of o){let c=s.get(l.uri)??[];c.push(l),s.set(l.uri,c);}if(s.size===0)return {contents:[{uri:"diagnostics://workspace",mimeType:"text/markdown",text:"No diagnostics found in workspace."}]};let a=[];for(let[l,c]of s)a.push(`## ${l}
12
- ${F(c)}`);return {contents:[{uri:"diagnostics://workspace",mimeType:"text/markdown",text:a.join(`
6
+ `);});break}case "notification":{this.notificationHandler?.(e.method,e.params);break}}}rejectAll(e){for(let[,r]of this.pending)r.reject(e);this.pending.clear();}};function T(t){return process.platform==="win32"?`\\\\.\\pipe\\${t}`:`/tmp/${t}.sock`}var R=[{providerKey:"fileAccess",methods:["readFile","readDirectory","getFileTree"]},{providerKey:"edit",methods:["applyEdits","previewAndApplyEdits"]},{providerKey:"definition",methods:["provideDefinition"]},{providerKey:"references",methods:["provideReferences"]},{providerKey:"hierarchy",methods:["provideCallHierarchy"]},{providerKey:"diagnostics",methods:["provideDiagnostics","getWorkspaceDiagnostics"]},{providerKey:"outline",methods:["provideDocumentSymbols"]},{providerKey:"globalFind",methods:["globalFind","globalReplace"]},{providerKey:"graph",methods:["getLinkStructure","resolveOutlinks","resolveBacklinks","addLink"]},{providerKey:"frontmatter",methods:["getFrontmatterStructure","getFrontmatter","setFrontmatter"]}];function de(t){let{pipeName:e,connectTimeout:r=5e3}=t,n=T(e);return new Promise((i,o)=>{let s=connect(n),a=false,l=setTimeout(()=>{a||(a=true,s.destroy(),o(new Error(`Connection timeout after ${r}ms`)));},r);s.on("error",c=>{a||(a=true,clearTimeout(l),o(c));}),s.on("connect",()=>{if(clearTimeout(l),a)return;let c,p=new S(s,{onNotification:(f,g)=>{f==="onDiagnosticsChanged"&&c&&c(g[0]);}});p.sendRequest("_handshake",[]).then(f=>{if(a)return;let b=f.methods;if(!b.includes("fileAccess.readFile")||!b.includes("fileAccess.readDirectory"))throw p.destroy(),new Error("Server missing required methods: fileAccess.readFile, fileAccess.readDirectory");let x={};for(let{providerKey:v,methods:F}of R){let _=F.filter(C=>b.includes(`${v}.${C}`));if(_.length===0)continue;let O={};for(let C of _)O[C]=(...X)=>p.sendRequest(`${v}.${C}`,X);x[v]=O;}b.includes("onDiagnosticsChanged")&&(x.onDiagnosticsChanged=v=>{c=v;}),a=true,i({capabilities:x,availableMethods:b,disconnect(){p.destroy();}});}).catch(f=>{a||(a=true,p.destroy(),o(f instanceof Error?f:new Error(String(f))));});});})}function fe(t){let{capabilities:e,pipeName:r}=t,n=T(r),i=new Map;for(let{providerKey:l,methods:c}of R){let p=e[l];if(p)for(let f of c){let g=p[f];if(typeof g=="function"){let b=`${l}.${f}`;i.set(b,(...x)=>g.apply(p,x));}}}let o=[...i.keys()];e.onDiagnosticsChanged&&o.push("onDiagnosticsChanged");let s=new Set,a=createServer(l=>{let c=new S(l,{onRequest:async(p,f)=>{if(p==="_handshake")return {methods:o};let g=i.get(p);if(!g)throw new Error(`Unknown method: ${p}`);return g(...f)}});s.add(c),l.on("close",()=>s.delete(c));});return e.onDiagnosticsChanged&&e.onDiagnosticsChanged(l=>{for(let c of s)c.sendNotification("onDiagnosticsChanged",[l]);}),new Promise((l,c)=>{if(process.platform!=="win32")try{unlinkSync(n);}catch{}a.on("error",c),a.listen(n,()=>{a.removeListener("error",c),l({get pipePath(){return n},get connectionCount(){return s.size},async close(){for(let p of s)p.destroy();if(s.clear(),await new Promise((p,f)=>{a.close(g=>{g?f(g):p();});}),process.platform!=="win32")try{unlinkSync(n);}catch{}}});});})}var P=class extends Error{constructor(r,n,i){super(`Could not find symbol '${r}' at or near line ${n}. ${i}`);this.symbolName=r;this.lineHint=n;this.reason=i;this.name="SymbolResolutionError";}},k=class{constructor(e,r){this.fs=e;this.lineSearchRadius=r?.lineSearchRadius??2;}lineSearchRadius;async resolvePosition(e,r){let i=(await this.fs.readFile(e)).split(/\r?\n/),o=r.lineHint-1,s=r.orderHint??0,a=this.findSymbolInLine(i[o],r.symbolName,s);if(a!==null)return {line:o,character:a};for(let l=1;l<=this.lineSearchRadius;l++){let c=o-l;if(c>=0){let f=this.findSymbolInLine(i[c],r.symbolName,s);if(f!==null)return {line:c,character:f}}let p=o+l;if(p<i.length){let f=this.findSymbolInLine(i[p],r.symbolName,s);if(f!==null)return {line:p,character:f}}}throw new P(r.symbolName,r.lineHint,`Please verify the file content and try again. Searched lines ${Math.max(1,r.lineHint-this.lineSearchRadius)} to ${Math.min(i.length,r.lineHint+this.lineSearchRadius)}.`)}findSymbolInLine(e,r,n){if(e===void 0||e.length===0)return null;let i=0,o=0;for(;i<e.length;){let s=e.indexOf(r,i);if(s===-1)break;if(o===n)return s;o++,i=s+1;}return null}async findExactText(e,r){let n=await this.fs.readFile(e),i=[],o=0;for(;o<n.length;){let p=n.indexOf(r,o);if(p===-1)break;i.push(p),o=p+1;}if(i.length===0)throw new Error(`Text not found in file: "${r.slice(0,50)}${r.length>50?"...":""}"`);if(i.length>1)throw new Error(`Text appears ${i.length} times in file. Please provide more context to uniquely identify the location.`);let s=i[0],a=s+r.length,l=this.offsetToPosition(n,s),c=this.offsetToPosition(n,a);return {start:l,end:c}}offsetToPosition(e,r){let n=0,i=0,o=0;for(let s of e){if(o===r)break;s===`
7
+ `?(n++,i=0):i++,o++;}return {line:n,character:i}}};var h=t=>({content:[{type:"text",text:JSON.stringify(t??"")}],structuredContent:t});function m(t){if(t.includes(".."))throw new Error('URI could not include ".." operator');return t.replace(/\\/g,"/")}function j(){return `edit-${Date.now()}`}function $(t){return t.length===0?"No diagnostics found.":t.map(e=>{let r=e.range.start.line+1,n=e.severity.toUpperCase(),i=e.source?` [${e.source}]`:"",o=e.code!==void 0?` (${e.code})`:"";return `- **${n}**${i}${o} at line ${r}: ${e.message}`}).join(`
8
+ `)}function I(t,e=0){if(t.length===0&&e===0)return "No symbols found.";let r=" ".repeat(e);return t.map(n=>{let i=n.range.start.line+1,o=n.range.end.line+1,s=i===o?`line ${i}`:`lines ${i}-${o}`,a=n.detail?` - ${n.detail}`:"",l=`${r}- **${n.kind}** \`${n.name}\`${a} (${s})`;return n.children&&n.children.length>0?`${l}
9
+ ${I(n.children,e+1)}`:l}).join(`
10
+ `)}var M=z$1.string().describe("The relative file path"),N=z$1.string().describe("The text of the symbol to find"),A=z$1.number().int().positive().describe("Approximate 1-based line number where the symbol is expected"),H=z$1.number().int().min(0).default(0).describe("0-based index of which occurrence to target if symbol appears multiple times"),D=z$1.object({uri:M,symbol_name:N,line_hint:A,order_hint:H}),E=z$1.object({uri:M,search_text:z$1.string().describe("Exact text to replace (must exist uniquely in the file)"),replace_text:z$1.string().describe("New text to insert"),description:z$1.string().describe("Rationale for the edit")}),G=z$1.object({uri:z$1.string().describe("The file URI or path"),symbol_name:N,line_hint:A,order_hint:H,direction:z$1.enum(["incoming","outgoing"]).describe("Direction of the call hierarchy")}),U=z$1.string().describe("The search query"),z=z$1.boolean().default(false).describe("Whether the search is case-sensitive"),K=z$1.boolean().default(false).describe("Whether to match exact words only"),q=z$1.boolean().default(false).describe("Whether the query is a regular expression"),J=z$1.object({query:U,case_sensitive:z,exact_match:K,regex_mode:q}),W=z$1.object({query:U,case_sensitive:z,exact_match:K,regex_mode:q,replace_with:z$1.string().describe("The replacement text")}),B=z$1.object({path:z$1.string().describe("The path to the document to modify"),pattern:z$1.string().describe("The text pattern to find and replace with a link"),link_to:z$1.string().describe("The target URI the link should point to")}),V=z$1.object({property:z$1.string().describe("The frontmatter property name to search for"),path:z$1.string().optional().describe("Optional path to limit the search to a specific document. If not provided, searches all documents.")}),Q=z$1.object({path:z$1.string().describe("The path to the document to modify"),property:z$1.string().describe("The frontmatter property name to set"),value:z$1.union([z$1.string(),z$1.array(z$1.string()),z$1.number(),z$1.array(z$1.number()),z$1.boolean(),z$1.array(z$1.boolean()),z$1.null()]).describe("The value to set. Can be a string, number, boolean, array of these types, or null to remove.")});function me(t){if(!t)return null;let e=t.match(/^L(\d+)(?:-L(\d+))?$/);if(!e||!e[1])return null;let r=parseInt(e[1],10),n=e[2]?parseInt(e[2],10):r;return r<1||n<r?null:{start:r,end:n}}function ge(t,e){let r=t.split(/\r?\n/),n=e.start-1,i=e.end;return r.slice(n,i).join(`
11
+ `)}function he({server:t,capabilities:e,config:r}){let n=new k(e.fileAccess,r?.resolverConfig);try{ye(t,e,n);}catch(i){return {success:false,error:i,reason:"Error occured during registration of tools"}}try{be(t,e);}catch(i){return {success:false,error:i,reason:"Error occured during registration of resources"}}return {success:true}}function ye(t,e,r){e.definition&&ve(t,e,r),e.definition?.provideTypeDefinition&&Pe(t,e,r),e.references&&xe(t,e,r),e.hierarchy&&we(t,e,r),e.edit&&Ee(t,e,r),e.globalFind&&(Te(t,e),Re(t,e)),e.graph&&(Fe(t,e),$e(t,e)),e.frontmatter&&(Ie(t,e),_e(t,e));}function be(t,e){Ce(t,e),e.diagnostics&&Se(t,e),e.outline&&ke(t,e),e.graph&&De(t,e),e.frontmatter&&Oe(t,e);}function ve(t,e,r){let n=e.definition;n&&t.registerTool("goto_definition",{description:"Navigate to the definition of a symbol.",inputSchema:D,outputSchema:{snippets:z$1.array(z$1.object({uri:z$1.string(),startLine:z$1.number(),endLine:z$1.number(),content:z$1.string()}))}},async i=>{try{let o=m(i.uri),s={symbolName:i.symbol_name,lineHint:i.line_hint,orderHint:i.order_hint},a=await r.resolvePosition(o,s),l=(await n.provideDefinition(o,a)).map(c=>({uri:c.uri,startLine:c.range.start.line+1,endLine:c.range.end.line+1,content:c.content}));return h({snippets:l})}catch(o){let s=o instanceof P?o.message:`Error: ${o instanceof Error?o.message:String(o)}`;return {content:[{type:"text",text:s}],structuredContent:{error:s},isError:true}}});}function Pe(t,e,r){let n=e.definition?.provideTypeDefinition;n&&t.registerTool("goto_type_definition",{description:"Navigate to the type definition of a symbol.",inputSchema:D,outputSchema:{snippets:z$1.array(z$1.object({uri:z$1.string(),startLine:z$1.number(),endLine:z$1.number(),content:z$1.string()}))}},async i=>{try{let o=m(i.uri),s={symbolName:i.symbol_name,lineHint:i.line_hint,orderHint:i.order_hint},a=await r.resolvePosition(o,s),l=(await n(o,a)).map(c=>({uri:c.uri,startLine:c.range.start.line+1,endLine:c.range.end.line+1,content:c.content}));return h({snippets:l})}catch(o){let s=o instanceof P?o.message:`Error: ${o instanceof Error?o.message:String(o)}`;return {content:[{type:"text",text:s}],structuredContent:{error:s},isError:true}}});}function xe(t,e,r){let n=e.references;n&&t.registerTool("find_references",{description:"Find all references to a symbol. Returns a list of locations where the symbol is used.",inputSchema:D,outputSchema:{snippets:z$1.array(z$1.object({uri:z$1.string(),startLine:z$1.number(),endLine:z$1.number(),content:z$1.string()}))}},async i=>{try{let o=m(i.uri),s={symbolName:i.symbol_name,lineHint:i.line_hint,orderHint:i.order_hint},a=await r.resolvePosition(o,s),l=(await n.provideReferences(o,a)).map(c=>({uri:c.uri,startLine:c.range.start.line+1,endLine:c.range.end.line+1,content:c.content}));return h({snippets:l})}catch(o){let s=o instanceof P?o.message:`Error: ${o instanceof Error?o.message:String(o)}`;return {content:[{type:"text",text:s}],structuredContent:{error:s},isError:true}}});}function we(t,e,r){let n=e.hierarchy;n&&t.registerTool("call_hierarchy",{description:"Get call hierarchy for a function or method. Shows incoming or outgoing calls.",inputSchema:G,outputSchema:{snippets:z$1.array(z$1.object({uri:z$1.string(),startLine:z$1.number(),endLine:z$1.number(),content:z$1.string()}))}},async i=>{try{let o=m(i.uri),s={symbolName:i.symbol_name,lineHint:i.line_hint,orderHint:i.order_hint},a=await r.resolvePosition(o,s),l=(await n.provideCallHierarchy(o,a,i.direction)).map(c=>({uri:c.uri,startLine:c.range.start.line+1,endLine:c.range.end.line+1,content:c.content}));return h({snippets:l})}catch(o){let s=o instanceof P?o.message:`Error: ${o instanceof Error?o.message:String(o)}`;return {content:[{type:"text",text:s}],structuredContent:{error:s},isError:true}}});}function Se(t,e){let r=e.diagnostics;if(!r)return;let n=new ResourceTemplate("diagnostics://{+path}",{list:void 0});if(t.registerResource("diagnostics",n,{description:"Diagnostics (errors, warnings, hints) for a specific file. Use the file path after diagnostics://",mimeType:"text/markdown"},async(i,o)=>{try{let s=o.path,a=m(s),l=await r.provideDiagnostics(a),c=$(l);return {contents:[{uri:`diagnostics://${s}`,mimeType:"text/markdown",text:c}]}}catch(s){let a=`Error: ${s instanceof Error?s.message:String(s)}`;return {contents:[{uri:`diagnostics://${o.path}`,mimeType:"text/markdown",text:a}]}}}),r.getWorkspaceDiagnostics){let i=r.getWorkspaceDiagnostics.bind(r);t.registerResource("workspace-diagnostics","diagnostics://workspace",{description:"All diagnostics (errors, warnings, hints) across the entire workspace",mimeType:"text/markdown"},async()=>{try{let o=await i(),s=new Map;for(let l of o){let c=s.get(l.uri)??[];c.push(l),s.set(l.uri,c);}if(s.size===0)return {contents:[{uri:"diagnostics://workspace",mimeType:"text/markdown",text:"No diagnostics found in workspace."}]};let a=[];for(let[l,c]of s)a.push(`## ${l}
12
+ ${$(c)}`);return {contents:[{uri:"diagnostics://workspace",mimeType:"text/markdown",text:a.join(`
13
13
 
14
- `)}]}}catch(o){return {contents:[{uri:"diagnostics://workspace",mimeType:"text/markdown",text:`Error: ${o instanceof Error?o.message:String(o)}`}]}}});}e.onDiagnosticsChanged&&e.onDiagnosticsChanged(i=>{let o=m(i);t.server.sendResourceUpdated({uri:`diagnostics://${o}`}),r.getWorkspaceDiagnostics&&t.server.sendResourceUpdated({uri:"diagnostics://workspace"});});}function ke(t,e){let r=e.outline;if(!r)return;let n=new ResourceTemplate("outline://{+path}",{list:void 0});t.registerResource("outline",n,{description:"Document outline (symbols like classes, functions, variables) for a specific file. Use the file path after outline://",mimeType:"text/markdown"},async(i,o)=>{try{let s=o.path,a=m(s),l=await r.provideDocumentSymbols(a),c=$(l);return {contents:[{uri:`outline://${s}`,mimeType:"text/markdown",text:c}]}}catch(s){let a=`Error: ${s instanceof Error?s.message:String(s)}`;return {contents:[{uri:`outline://${o.path}`,mimeType:"text/markdown",text:a}]}}});}function Se(t,e,r){let n=e.edit;if(!n)return;let i=n.previewAndApplyEdits?.bind(n)??n.applyEdits?.bind(n);i&&t.registerTool("apply_edit",{description:"Apply a text edit to a file. The edit must be approved by the user before being applied.",inputSchema:{uri:C.shape.uri,search_text:C.shape.search_text,replace_text:C.shape.replace_text,description:C.shape.description},outputSchema:{success:z$1.boolean(),message:z$1.string()}},async o=>{try{let s=m(o.uri),a=await r.findExactText(s,o.search_text),l={id:M(),uri:s,edits:[{range:a,newText:o.replace_text}],description:o.description},p=await i(l)?{success:!0,message:"Edit successfully applied and saved."}:{success:!1,message:"Edit rejected by user."};return y(p)}catch(s){let a=`Error: ${s instanceof Error?s.message:String(s)}`;return {content:[{type:"text",text:a}],structuredContent:{success:false,message:a},isError:true}}});}function Ce(t,e){let{readFile:r,readDirectory:n,getFileTree:i}=e.fileAccess;if(i!==void 0){let s=new ResourceTemplate("filetree://{+path}",{list:void 0});t.registerResource("filetree",s,{description:'Access file tree inside a relative path or use "." for root.'},async(a,{path:l})=>({contents:[{uri:a.toString(),mimeType:"application/json",text:JSON.stringify(await i(m(l))??"")}]}));}let o=new ResourceTemplate("files://{+path}",{list:void 0});t.registerResource("filesystem",o,{description:"Access filesystem resources. For directories: returns children (git-ignored files excluded). For files: returns file content. Supports line ranges with #L23 or #L23-L30 fragment."},async(s,a)=>{let l=s.toString();try{let c=a.path,p,f=c,g=c.indexOf("#");g!==-1&&(p=c.slice(g+1),f=c.slice(0,g));let b=m(f),P=me(p);try{let v=await r(b),D=P?ge(v,P):v;return {contents:[{uri:l,mimeType:"text/plain",text:D}]}}catch{let v=await n(b);return {contents:[{uri:l,mimeType:"application/json",text:JSON.stringify(v)}]}}}catch(c){let p=`Error: ${c instanceof Error?c.message:String(c)}`;return {contents:[{uri:l,mimeType:"text/plain",text:p}]}}});}function Ee(t,e){let r=e.globalFind;r&&t.registerTool("global_find",{description:"Search for text across the entire workspace.",inputSchema:J,outputSchema:{matches:z$1.array(z$1.object({uri:z$1.string(),line:z$1.number(),column:z$1.number(),matchText:z$1.string(),context:z$1.string()})),count:z$1.number()}},async n=>{try{let i=n.case_sensitive??!1,o=n.exact_match??!1,s=n.regex_mode??!1,a=await r.globalFind(n.query,{caseSensitive:i,exactMatch:o,regexMode:s});return y({count:a.length,matches:a})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{error:o},isError:true}}});}function Te(t,e){let r=e.globalFind;r&&t.registerTool("global_replace",{description:"Replace all occurrences of text across the entire workspace.",inputSchema:W,outputSchema:{success:z$1.boolean(),count:z$1.number(),message:z$1.string().optional()}},async n=>{try{let i=n.case_sensitive??!1,o=n.exact_match??!1,s=n.regex_mode??!1,a=await r.globalReplace(n.query,n.replace_with,{caseSensitive:i,exactMatch:o,regexMode:s});return y({success:!0,count:a})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{success:false,replacementCount:0,message:o},isError:true}}});}function Re(t,e){let r=e.graph;if(!r)return;let n=new ResourceTemplate("outlinks://{+path}",{list:void 0});t.registerResource("outlinks",n,{description:"Outgoing links from a specific file. Use the file path after outlinks://",mimeType:"application/json"},async(o,s)=>{try{let a=s.path,l=m(a),c=await r.resolveOutlinks(l);return {contents:[{uri:`outlinks://${a}`,mimeType:"application/json",text:JSON.stringify(c,null,2)}]}}catch(a){let l=`Error: ${a instanceof Error?a.message:String(a)}`;return {contents:[{uri:`outlinks://${s.path}`,mimeType:"application/json",text:JSON.stringify({error:l})}]}}});let i=new ResourceTemplate("backlinks://{+path}",{list:void 0});t.registerResource("backlinks",i,{description:"Incoming links (backlinks) to a specific file. Use the file path after backlinks://",mimeType:"application/json"},async(o,s)=>{try{let a=s.path,l=m(a),c=await r.resolveBacklinks(l);return {contents:[{uri:`backlinks://${a}`,mimeType:"application/json",text:JSON.stringify(c,null,2)}]}}catch(a){let l=`Error: ${a instanceof Error?a.message:String(a)}`;return {contents:[{uri:`backlinks://${s.path}`,mimeType:"application/json",text:JSON.stringify({error:l})}]}}});}function De(t,e){let r=e.graph;r&&t.registerTool("get_link_structure",{description:"Get all links in the workspace, showing relationships between documents.",inputSchema:{},outputSchema:{links:z$1.array(z$1.object({sourceUri:z$1.string(),targetUri:z$1.string(),subpath:z$1.string().optional(),displayText:z$1.string().optional(),resolved:z$1.boolean(),line:z$1.number(),column:z$1.number()}))}},async()=>{try{let n=await r.getLinkStructure();return y({links:n})}catch(n){let i=`Error: ${n instanceof Error?n.message:String(n)}`;return {content:[{type:"text",text:i}],structuredContent:{error:i},isError:true}}});}function Fe(t,e){let r=e.graph;r&&t.registerTool("add_link",{description:"Add a link to a document by finding a text pattern and replacing it with a link to the target.",inputSchema:B,outputSchema:{success:z$1.boolean(),message:z$1.string().optional()}},async n=>{try{let i=m(n.path),o=m(n.link_to);return await r.addLink(i,n.pattern,o),y({success:!0,message:"Link added successfully."})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{success:false,message:o},isError:true}}});}function $e(t,e){let r=e.frontmatter;r&&t.registerTool("get_frontmatter_structure",{description:"Get frontmatter property values across documents. If path is provided, searches only that document. Otherwise, searches all documents.",inputSchema:V,outputSchema:{matches:z$1.array(z$1.object({path:z$1.string(),value:z$1.unknown()}))}},async n=>{try{let i=n.path?m(n.path):void 0,o=await r.getFrontmatterStructure(n.property,i);return y({matches:o})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{error:o},isError:true}}});}function Ie(t,e){let r=e.frontmatter;r&&t.registerTool("set_frontmatter",{description:"Set a frontmatter property on a document. Use null to remove the property.",inputSchema:Q,outputSchema:{success:z$1.boolean(),message:z$1.string().optional()}},async n=>{try{let i=m(n.path),o=n.value===null?void 0:n.value;return await r.setFrontmatter(i,n.property,o),y({success:!0,message:"Frontmatter updated successfully."})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{success:false,message:o},isError:true}}});}function Oe(t,e){let r=e.frontmatter;if(!r)return;let n=new ResourceTemplate("frontmatter://{+path}",{list:void 0});t.registerResource("frontmatter",n,{description:"Frontmatter metadata for a specific file. Use the file path after frontmatter://",mimeType:"application/json"},async(i,o)=>{try{let s=o.path,a=m(s),l=await r.getFrontmatter(a);return {contents:[{uri:`frontmatter://${s}`,mimeType:"application/json",text:JSON.stringify(l,null,2)}]}}catch(s){let a=`Error: ${s instanceof Error?s.message:String(s)}`;return {contents:[{uri:`frontmatter://${o.path}`,mimeType:"application/json",text:JSON.stringify({error:a})}]}}});}
15
- export{x as SymbolResolutionError,S as SymbolResolver,ue as connectLspPipe,he as installMcpLspDriver,le as mergeCapabilities,fe as serveLspPipe};
14
+ `)}]}}catch(o){return {contents:[{uri:"diagnostics://workspace",mimeType:"text/markdown",text:`Error: ${o instanceof Error?o.message:String(o)}`}]}}});}e.onDiagnosticsChanged&&e.onDiagnosticsChanged(i=>{let o=m(i);t.server.sendResourceUpdated({uri:`diagnostics://${o}`}),r.getWorkspaceDiagnostics&&t.server.sendResourceUpdated({uri:"diagnostics://workspace"});});}function ke(t,e){let r=e.outline;if(!r)return;let n=new ResourceTemplate("outline://{+path}",{list:void 0});t.registerResource("outline",n,{description:"Document outline (symbols like classes, functions, variables) for a specific file. Use the file path after outline://",mimeType:"text/markdown"},async(i,o)=>{try{let s=o.path,a=m(s),l=await r.provideDocumentSymbols(a),c=I(l);return {contents:[{uri:`outline://${s}`,mimeType:"text/markdown",text:c}]}}catch(s){let a=`Error: ${s instanceof Error?s.message:String(s)}`;return {contents:[{uri:`outline://${o.path}`,mimeType:"text/markdown",text:a}]}}});}function Ee(t,e,r){let n=e.edit;if(!n)return;let i=n.previewAndApplyEdits?.bind(n)??n.applyEdits?.bind(n);i&&t.registerTool("apply_edit",{description:"Apply a text edit to a file. The edit must be approved by the user before being applied.",inputSchema:{uri:E.shape.uri,search_text:E.shape.search_text,replace_text:E.shape.replace_text,description:E.shape.description},outputSchema:{success:z$1.boolean(),message:z$1.string()}},async o=>{try{let s=m(o.uri),a=await r.findExactText(s,o.search_text),l={id:j(),uri:s,edits:[{range:a,newText:o.replace_text}],description:o.description},p=await i(l)?{success:!0,message:"Edit successfully applied and saved."}:{success:!1,message:"Edit rejected by user."};return h(p)}catch(s){let a=`Error: ${s instanceof Error?s.message:String(s)}`;return {content:[{type:"text",text:a}],structuredContent:{success:false,message:a},isError:true}}});}function Ce(t,e){let{readFile:r,readDirectory:n,getFileTree:i}=e.fileAccess;if(i!==void 0){let s=new ResourceTemplate("filetree://{+path}",{list:void 0});t.registerResource("filetree",s,{description:'Access file tree inside a relative path or use "." for root.'},async(a,{path:l})=>({contents:[{uri:a.toString(),mimeType:"application/json",text:JSON.stringify(await i(m(l))??"")}]}));}let o=new ResourceTemplate("files://{+path}",{list:void 0});t.registerResource("filesystem",o,{description:"Access filesystem resources. For directories: returns children (git-ignored files excluded). For files: returns file content. Supports line ranges with #L23 or #L23-L30 fragment."},async(s,a)=>{let l=s.toString();try{let c=a.path,p,f=c,g=c.indexOf("#");g!==-1&&(p=c.slice(g+1),f=c.slice(0,g));let b=m(f),x=me(p);try{let v=await r(b),F=x?ge(v,x):v;return {contents:[{uri:l,mimeType:"text/plain",text:F}]}}catch{let v=await n(b);return {contents:[{uri:l,mimeType:"application/json",text:JSON.stringify(v)}]}}}catch(c){let p=`Error: ${c instanceof Error?c.message:String(c)}`;return {contents:[{uri:l,mimeType:"text/plain",text:p}]}}});}function Te(t,e){let r=e.globalFind;r&&t.registerTool("global_find",{description:"Search for text across the entire workspace.",inputSchema:J,outputSchema:{matches:z$1.array(z$1.object({uri:z$1.string(),line:z$1.number(),column:z$1.number(),matchText:z$1.string(),context:z$1.string()})),count:z$1.number()}},async n=>{try{let i=n.case_sensitive??!1,o=n.exact_match??!1,s=n.regex_mode??!1,a=await r.globalFind(n.query,{caseSensitive:i,exactMatch:o,regexMode:s});return h({count:a.length,matches:a})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{error:o},isError:true}}});}function Re(t,e){let r=e.globalFind;r&&t.registerTool("global_replace",{description:"Replace all occurrences of text across the entire workspace.",inputSchema:W,outputSchema:{success:z$1.boolean(),count:z$1.number(),message:z$1.string().optional()}},async n=>{try{let i=n.case_sensitive??!1,o=n.exact_match??!1,s=n.regex_mode??!1,a=await r.globalReplace(n.query,n.replace_with,{caseSensitive:i,exactMatch:o,regexMode:s});return h({success:!0,count:a})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{success:false,replacementCount:0,message:o},isError:true}}});}function De(t,e){let r=e.graph;if(!r)return;let n=new ResourceTemplate("outlinks://{+path}",{list:void 0});t.registerResource("outlinks",n,{description:"Outgoing links from a specific file. Use the file path after outlinks://",mimeType:"application/json"},async(o,s)=>{try{let a=s.path,l=m(a),c=await r.resolveOutlinks(l);return {contents:[{uri:`outlinks://${a}`,mimeType:"application/json",text:JSON.stringify(c,null,2)}]}}catch(a){let l=`Error: ${a instanceof Error?a.message:String(a)}`;return {contents:[{uri:`outlinks://${s.path}`,mimeType:"application/json",text:JSON.stringify({error:l})}]}}});let i=new ResourceTemplate("backlinks://{+path}",{list:void 0});t.registerResource("backlinks",i,{description:"Incoming links (backlinks) to a specific file. Use the file path after backlinks://",mimeType:"application/json"},async(o,s)=>{try{let a=s.path,l=m(a),c=await r.resolveBacklinks(l);return {contents:[{uri:`backlinks://${a}`,mimeType:"application/json",text:JSON.stringify(c,null,2)}]}}catch(a){let l=`Error: ${a instanceof Error?a.message:String(a)}`;return {contents:[{uri:`backlinks://${s.path}`,mimeType:"application/json",text:JSON.stringify({error:l})}]}}});}function Fe(t,e){let r=e.graph;r&&t.registerTool("get_link_structure",{description:"Get all links in the workspace, showing relationships between documents.",inputSchema:{},outputSchema:{links:z$1.array(z$1.object({sourceUri:z$1.string(),targetUri:z$1.string(),subpath:z$1.string().optional(),displayText:z$1.string().optional(),resolved:z$1.boolean(),line:z$1.number(),column:z$1.number()}))}},async()=>{try{let n=await r.getLinkStructure();return h({links:n})}catch(n){let i=`Error: ${n instanceof Error?n.message:String(n)}`;return {content:[{type:"text",text:i}],structuredContent:{error:i},isError:true}}});}function $e(t,e){let r=e.graph;r&&t.registerTool("add_link",{description:"Add a link to a document by finding a text pattern and replacing it with a link to the target.",inputSchema:B,outputSchema:{success:z$1.boolean(),message:z$1.string().optional()}},async n=>{try{let i=m(n.path),o=m(n.link_to);return await r.addLink(i,n.pattern,o),h({success:!0,message:"Link added successfully."})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{success:false,message:o},isError:true}}});}function Ie(t,e){let r=e.frontmatter;r&&t.registerTool("get_frontmatter_structure",{description:"Get frontmatter property values across documents. If path is provided, searches only that document. Otherwise, searches all documents.",inputSchema:V,outputSchema:{matches:z$1.array(z$1.object({path:z$1.string(),value:z$1.unknown()}))}},async n=>{try{let i=n.path?m(n.path):void 0,o=await r.getFrontmatterStructure(n.property,i);return h({matches:o})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{error:o},isError:true}}});}function _e(t,e){let r=e.frontmatter;r&&t.registerTool("set_frontmatter",{description:"Set a frontmatter property on a document. Use null to remove the property.",inputSchema:Q,outputSchema:{success:z$1.boolean(),message:z$1.string().optional()}},async n=>{try{let i=m(n.path),o=n.value===null?void 0:n.value;return await r.setFrontmatter(i,n.property,o),h({success:!0,message:"Frontmatter updated successfully."})}catch(i){let o=`Error: ${i instanceof Error?i.message:String(i)}`;return {content:[{type:"text",text:o}],structuredContent:{success:false,message:o},isError:true}}});}function Oe(t,e){let r=e.frontmatter;if(!r)return;let n=new ResourceTemplate("frontmatter://{+path}",{list:void 0});t.registerResource("frontmatter",n,{description:"Frontmatter metadata for a specific file. Use the file path after frontmatter://",mimeType:"application/json"},async(i,o)=>{try{let s=o.path,a=m(s),l=await r.getFrontmatter(a);return {contents:[{uri:`frontmatter://${s}`,mimeType:"application/json",text:JSON.stringify(l,null,2)}]}}catch(s){let a=`Error: ${s instanceof Error?s.message:String(s)}`;return {contents:[{uri:`frontmatter://${o.path}`,mimeType:"application/json",text:JSON.stringify({error:a})}]}}});}
15
+ export{P as SymbolResolutionError,k as SymbolResolver,de as connectLspPipe,he as installMcpLspDriver,le as mergeCapabilities,fe as serveLspPipe};
@@ -1,6 +1,6 @@
1
1
  import { ChildProcess } from 'node:child_process';
2
2
  import { ProtocolConnection } from 'vscode-languageserver-protocol/node.js';
3
- import { b as DefinitionProvider, R as ReferencesProvider, H as HierarchyProvider, q as OutlineProvider, e as DiagnosticsProvider, O as OnDiagnosticsChangedCallback, d as DiagnosticSeverity, C as CodeSnippet, c as Diagnostic$1, f as DocumentSymbol$1, E as ExactPosition, D as DiskRange, S as SymbolKind } from '../capabilities-96hGHyOj.js';
3
+ import { b as DefinitionProvider, R as ReferencesProvider, H as HierarchyProvider, q as OutlineProvider, e as DiagnosticsProvider, O as OnDiagnosticsChangedCallback, d as DiagnosticSeverity, C as CodeSnippet, c as Diagnostic$1, f as DocumentSymbol$1, E as ExactPosition, D as DiskRange, S as SymbolKind } from '../capabilities-DM3FLRwy.js';
4
4
  import { Location, LocationLink, Diagnostic, DocumentSymbol, SymbolInformation } from 'vscode-languageserver-protocol';
5
5
 
6
6
  interface LspClientOptions {
@@ -47,6 +47,7 @@ declare class LspClient {
47
47
  private scheduleDocumentClose;
48
48
  private closeDocument;
49
49
  private provideDefinition;
50
+ private provideTypeDefinition;
50
51
  private provideReferences;
51
52
  private provideCallHierarchy;
52
53
  private provideDocumentSymbols;
package/dist/lsp/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import {spawn}from'child_process';import {InitializedNotification,ShutdownRequest,ExitNotification,StreamMessageReader,StreamMessageWriter,createProtocolConnection,InitializeRequest,CancellationTokenSource,DidOpenTextDocumentNotification,DidCloseTextDocumentNotification}from'vscode-languageserver-protocol/node.js';import D from'path';import {pathToFileURL,fileURLToPath}from'url';function c(o,t){let e=D.resolve(o,t);return pathToFileURL(e).toString()}function u(o,t){let e=fileURLToPath(t);return D.relative(o,e).replace(/\\/g,"/")}function p(o){return {start:{line:o.start.line,character:o.start.character},end:{line:o.end.line,character:o.end.character}}}function x(o){return {line:o.line,character:o.character}}var T={1:"error",2:"warning",3:"information",4:"hint"};function b(o){return T[o??1]??"error"}var I=["file","file","module","namespace","package","class","method","property","field","constructor","enum","interface","function","variable","constant","string","number","boolean","array","object","key","null","enumMember","struct","event","operator","typeParameter"];function P(o){return I[o]??"variable"}function g(o,t,e){return {uri:u(o,t),range:p(e.range),severity:b(e.severity),message:e.message,source:e.source,code:typeof e.code=="object"?String(e.code):e.code??void 0}}function f(o){return {name:o.name,detail:o.detail,kind:P(o.kind),range:p(o.range),selectionRange:p(o.selectionRange),children:o.children?.map(f)}}function C(o,t){return {name:t.name,kind:P(t.kind),range:p(t.location.range),selectionRange:p(t.location.range)}}async function m(o,t,e){if(!t)return [];let i=Array.isArray(t)?t:[t];if(i.length===0)return [];let n=[];for(let s of i){let r="targetUri"in s,a=r?s.targetUri:s.uri,h=r?s.targetRange:s.range,d=u(o,a),l=p(h);try{let S=(await e(d)).split(`
2
- `).slice(l.start.line,l.end.line+1);n.push({uri:d,range:l,content:S.join(`
3
- `)});}catch{n.push({uri:d,range:l,content:""});}}return n}var O={".ts":"typescript",".tsx":"typescriptreact",".js":"javascript",".jsx":"javascriptreact",".rs":"rust",".go":"go",".py":"python",".rb":"ruby",".java":"java",".kt":"kotlin",".kts":"kotlin",".c":"c",".h":"c",".cpp":"cpp",".cc":"cpp",".cxx":"cpp",".hpp":"cpp",".cs":"csharp",".swift":"swift",".lua":"lua",".zig":"zig",".json":"json",".yaml":"yaml",".yml":"yaml",".toml":"toml",".xml":"xml",".html":"html",".css":"css",".scss":"scss",".md":"markdown",".sql":"sql",".sh":"shellscript",".bash":"shellscript",".zsh":"shellscript",".ps1":"powershell",".dart":"dart",".ex":"elixir",".exs":"elixir",".erl":"erlang",".hs":"haskell",".ml":"ocaml",".mli":"ocaml",".scala":"scala",".r":"r",".R":"r",".php":"php",".pl":"perl",".vim":"vim"};function w(o){let t=D.extname(o);return O[t]??"plaintext"}var y=class{state="idle";process=null;connection=null;openDocuments=new Map;diagnosticsCache=new Map;diagnosticsListeners=[];definition;references;hierarchy;outline;diagnostics;options;constructor(t){this.options={documentIdleTimeout:3e4,requestTimeout:3e4,...t},this.definition=void 0,this.references=void 0,this.hierarchy=void 0,this.outline=void 0,this.diagnostics=void 0;}getState(){return this.state}get onDiagnosticsChanged(){return t=>{this.diagnosticsListeners.push(t);}}async start(){if(this.state!=="idle")throw new Error(`Cannot start: client is in "${this.state}" state`);this.state="starting";try{let t=this.spawnAndConnect();this.connection=t,t.onClose(()=>{(this.state==="running"||this.state==="starting")&&this.transitionToDead();}),t.listen();let i=(await this.sendInitialize()).capabilities;this.setupProviders(i),t.onNotification("textDocument/publishDiagnostics",n=>{let s=u(this.options.workspacePath,n.uri),r=n.diagnostics.map(a=>g(this.options.workspacePath,n.uri,a));this.diagnosticsCache.set(s,r);for(let a of this.diagnosticsListeners)a(s);}),await t.sendNotification(InitializedNotification.type,{}),this.state="running";}catch(t){throw this.transitionToDead(),t}}async stop(){if(this.state!=="running")return;let t=[...this.openDocuments.keys()].map(e=>this.closeDocument(e));await Promise.all(t);try{await this.connection?.sendRequest(ShutdownRequest.type),await this.connection?.sendNotification(ExitNotification.type);}catch{}this.cleanup();}async notifyFileChanged(t){if(this.state!=="running")return;let e=c(this.options.workspacePath,t);this.openDocuments.get(e)&&(await this.closeDocument(e),await this.ensureDocumentOpen(e));}startWithConnection(t,e){this.connection=t,this.process=e;}async initializeConnection(){let t=this.connection;if(!t)throw new Error("Connection not set");this.state="starting",t.onClose(()=>{(this.state==="running"||this.state==="starting")&&this.transitionToDead();}),t.listen();let i=(await this.sendInitialize()).capabilities;this.setupProviders(i),t.onNotification("textDocument/publishDiagnostics",n=>{let s=u(this.options.workspacePath,n.uri),r=n.diagnostics.map(a=>g(this.options.workspacePath,n.uri,a));this.diagnosticsCache.set(s,r);for(let a of this.diagnosticsListeners)a(s);}),await t.sendNotification(InitializedNotification.type,{}),this.state="running";}spawnAndConnect(){let t=spawn(this.options.command,this.options.args??[],{stdio:["pipe","pipe","pipe"],env:this.options.env?{...process.env,...this.options.env}:process.env});this.process=t,t.on("exit",()=>{(this.state==="running"||this.state==="starting")&&this.transitionToDead();});let e=new StreamMessageReader(t.stdout),i=new StreamMessageWriter(t.stdin);return createProtocolConnection(e,i)}async sendInitialize(){if(!this.connection)throw new Error("No connection");let t={textDocument:{synchronization:{dynamicRegistration:false,didSave:true},definition:{dynamicRegistration:false},references:{dynamicRegistration:false},callHierarchy:{dynamicRegistration:false},documentSymbol:{dynamicRegistration:false,hierarchicalDocumentSymbolSupport:true},publishDiagnostics:{relatedInformation:true}}};return await this.connection.sendRequest(InitializeRequest.type,{processId:process.pid,capabilities:t,rootUri:c(this.options.workspacePath,"."),initializationOptions:this.options.initializationOptions??null})}setupProviders(t){t.definitionProvider&&(this.definition={provideDefinition:(e,i)=>this.provideDefinition(e,i)}),t.referencesProvider&&(this.references={provideReferences:(e,i)=>this.provideReferences(e,i)}),t.callHierarchyProvider&&(this.hierarchy={provideCallHierarchy:(e,i,n)=>this.provideCallHierarchy(e,i,n)}),t.documentSymbolProvider&&(this.outline={provideDocumentSymbols:e=>this.provideDocumentSymbols(e)}),this.diagnostics={provideDiagnostics:e=>this.provideDiagnostics(e),getWorkspaceDiagnostics:()=>this.getWorkspaceDiagnostics()};}assertRunning(){if(this.state!=="running")throw new Error(`Client is not running (state: "${this.state}")`);if(!this.connection)throw new Error("No connection");return this.connection}createTimeout(){let t=new CancellationTokenSource,e,i=new Promise((n,s)=>{e=setTimeout(()=>{t.cancel(),s(new Error("LSP request timed out"));},this.options.requestTimeout);});return {token:t,promise:i,clear:()=>{e&&clearTimeout(e);}}}async sendRequest(t,e){let i=this.assertRunning(),n=this.createTimeout();try{return await Promise.race([i.sendRequest(t,e,n.token.token),n.promise])}finally{n.clear();}}async ensureDocumentOpen(t){let e=this.openDocuments.get(t);if(e){e.closeTimer&&clearTimeout(e.closeTimer),e.closeTimer=this.scheduleDocumentClose(t);return}let i=u(this.options.workspacePath,t),n=await this.options.readFile(i),s=w(i),r={uri:t,version:1,closeTimer:this.scheduleDocumentClose(t)};this.openDocuments.set(t,r),await this.connection?.sendNotification(DidOpenTextDocumentNotification.type,{textDocument:{uri:t,languageId:s,version:r.version,text:n}});}scheduleDocumentClose(t){return setTimeout(()=>{this.closeDocument(t);},this.options.documentIdleTimeout)}async closeDocument(t){let e=this.openDocuments.get(t);if(e&&(e.closeTimer&&clearTimeout(e.closeTimer),this.openDocuments.delete(t),this.connection&&this.state==="running"))try{await this.connection.sendNotification(DidCloseTextDocumentNotification.type,{textDocument:{uri:t}});}catch{}}async provideDefinition(t,e){let i=c(this.options.workspacePath,t);await this.ensureDocumentOpen(i);let n=await this.sendRequest("textDocument/definition",{textDocument:{uri:i},position:{line:e.line,character:e.character}});return m(this.options.workspacePath,n,this.options.readFile)}async provideReferences(t,e){let i=c(this.options.workspacePath,t);await this.ensureDocumentOpen(i);let n=await this.sendRequest("textDocument/references",{textDocument:{uri:i},position:{line:e.line,character:e.character},context:{includeDeclaration:true}});return m(this.options.workspacePath,n,this.options.readFile)}async provideCallHierarchy(t,e,i){let n=c(this.options.workspacePath,t);await this.ensureDocumentOpen(n);let s=await this.sendRequest("textDocument/prepareCallHierarchy",{textDocument:{uri:n},position:{line:e.line,character:e.character}});if(!s||s.length===0)return [];let r=s[0],a=i==="incoming"?"callHierarchy/incomingCalls":"callHierarchy/outgoingCalls",h=await this.sendRequest(a,{item:r});if(!h||h.length===0)return [];let d=h.map(l=>{let v="from"in l?l.from:l.to;return {uri:v.uri,range:v.selectionRange}});return m(this.options.workspacePath,d,this.options.readFile)}async provideDocumentSymbols(t){let e=c(this.options.workspacePath,t);await this.ensureDocumentOpen(e);let i=await this.sendRequest("textDocument/documentSymbol",{textDocument:{uri:e}});if(!i||i.length===0)return [];let n=i[0];return n&&"range"in n&&"selectionRange"in n?i.map(f):i.map(s=>C(this.options.workspacePath,s))}async provideDiagnostics(t){this.assertRunning();let e=c(this.options.workspacePath,t);await this.ensureDocumentOpen(e);let i=this.diagnosticsCache.get(t);return i||(await new Promise(n=>setTimeout(n,200)),this.diagnosticsCache.get(t)??[])}async getWorkspaceDiagnostics(){this.assertRunning();let t=[];for(let e of this.diagnosticsCache.values())t.push(...e);return t}transitionToDead(){this.state="dead",this.cleanup();}cleanup(){for(let t of this.openDocuments.values())t.closeTimer&&clearTimeout(t.closeTimer);if(this.openDocuments.clear(),this.connection){try{this.connection.dispose();}catch{}this.connection=null;}if(this.process){try{this.process.kill();}catch{}this.process=null;}this.state="dead";}};function F(o){return new y(o)}export{y as LspClient,b as convertDiagnosticSeverity,m as convertLocationsToSnippets,g as convertLspDiagnostic,f as convertLspDocumentSymbol,x as convertLspPosition,p as convertLspRange,C as convertSymbolInformation,P as convertSymbolKind,F as createLspClient,w as guessLanguageId,u as lspUriToPath,c as pathToLspUri};
1
+ import {spawn}from'child_process';import {InitializedNotification,ShutdownRequest,ExitNotification,StreamMessageReader,StreamMessageWriter,createProtocolConnection,InitializeRequest,CancellationTokenSource,DidOpenTextDocumentNotification,DidCloseTextDocumentNotification}from'vscode-languageserver-protocol/node.js';import D from'path';import {pathToFileURL,fileURLToPath}from'url';function c(o,t){let e=D.resolve(o,t);return pathToFileURL(e).toString()}function u(o,t){let e=fileURLToPath(t);return D.relative(o,e).replace(/\\/g,"/")}function p(o){return {start:{line:o.start.line,character:o.start.character},end:{line:o.end.line,character:o.end.character}}}function R(o){return {line:o.line,character:o.character}}var T={1:"error",2:"warning",3:"information",4:"hint"};function b(o){return T[o??1]??"error"}var O=["file","file","module","namespace","package","class","method","property","field","constructor","enum","interface","function","variable","constant","string","number","boolean","array","object","key","null","enumMember","struct","event","operator","typeParameter"];function P(o){return O[o]??"variable"}function g(o,t,e){return {uri:u(o,t),range:p(e.range),severity:b(e.severity),message:e.message,source:e.source,code:typeof e.code=="object"?String(e.code):e.code??void 0}}function f(o){return {name:o.name,detail:o.detail,kind:P(o.kind),range:p(o.range),selectionRange:p(o.selectionRange),children:o.children?.map(f)}}function C(o,t){return {name:t.name,kind:P(t.kind),range:p(t.location.range),selectionRange:p(t.location.range)}}async function h(o,t,e){if(!t)return [];let i=Array.isArray(t)?t:[t];if(i.length===0)return [];let n=[];for(let s of i){let r="targetUri"in s,a=r?s.targetUri:s.uri,d=r?s.targetRange:s.range,m=u(o,a),l=p(d);try{let S=(await e(m)).split(`
2
+ `).slice(l.start.line,l.end.line+1);n.push({uri:m,range:l,content:S.join(`
3
+ `)});}catch{n.push({uri:m,range:l,content:""});}}return n}var I={".ts":"typescript",".tsx":"typescriptreact",".js":"javascript",".jsx":"javascriptreact",".rs":"rust",".go":"go",".py":"python",".rb":"ruby",".java":"java",".kt":"kotlin",".kts":"kotlin",".c":"c",".h":"c",".cpp":"cpp",".cc":"cpp",".cxx":"cpp",".hpp":"cpp",".cs":"csharp",".swift":"swift",".lua":"lua",".zig":"zig",".json":"json",".yaml":"yaml",".yml":"yaml",".toml":"toml",".xml":"xml",".html":"html",".css":"css",".scss":"scss",".md":"markdown",".sql":"sql",".sh":"shellscript",".bash":"shellscript",".zsh":"shellscript",".ps1":"powershell",".dart":"dart",".ex":"elixir",".exs":"elixir",".erl":"erlang",".hs":"haskell",".ml":"ocaml",".mli":"ocaml",".scala":"scala",".r":"r",".R":"r",".php":"php",".pl":"perl",".vim":"vim"};function w(o){let t=D.extname(o);return I[t]??"plaintext"}var y=class{state="idle";process=null;connection=null;openDocuments=new Map;diagnosticsCache=new Map;diagnosticsListeners=[];definition;references;hierarchy;outline;diagnostics;options;constructor(t){this.options={documentIdleTimeout:3e4,requestTimeout:3e4,...t},this.definition=void 0,this.references=void 0,this.hierarchy=void 0,this.outline=void 0,this.diagnostics=void 0;}getState(){return this.state}get onDiagnosticsChanged(){return t=>{this.diagnosticsListeners.push(t);}}async start(){if(this.state!=="idle")throw new Error(`Cannot start: client is in "${this.state}" state`);this.state="starting";try{let t=this.spawnAndConnect();this.connection=t,t.onClose(()=>{(this.state==="running"||this.state==="starting")&&this.transitionToDead();}),t.listen();let i=(await this.sendInitialize()).capabilities;this.setupProviders(i),t.onNotification("textDocument/publishDiagnostics",n=>{let s=u(this.options.workspacePath,n.uri),r=n.diagnostics.map(a=>g(this.options.workspacePath,n.uri,a));this.diagnosticsCache.set(s,r);for(let a of this.diagnosticsListeners)a(s);}),await t.sendNotification(InitializedNotification.type,{}),this.state="running";}catch(t){throw this.transitionToDead(),t}}async stop(){if(this.state!=="running")return;let t=[...this.openDocuments.keys()].map(e=>this.closeDocument(e));await Promise.all(t);try{await this.connection?.sendRequest(ShutdownRequest.type),await this.connection?.sendNotification(ExitNotification.type);}catch{}this.cleanup();}async notifyFileChanged(t){if(this.state!=="running")return;let e=c(this.options.workspacePath,t);this.openDocuments.get(e)&&(await this.closeDocument(e),await this.ensureDocumentOpen(e));}startWithConnection(t,e){this.connection=t,this.process=e;}async initializeConnection(){let t=this.connection;if(!t)throw new Error("Connection not set");this.state="starting",t.onClose(()=>{(this.state==="running"||this.state==="starting")&&this.transitionToDead();}),t.listen();let i=(await this.sendInitialize()).capabilities;this.setupProviders(i),t.onNotification("textDocument/publishDiagnostics",n=>{let s=u(this.options.workspacePath,n.uri),r=n.diagnostics.map(a=>g(this.options.workspacePath,n.uri,a));this.diagnosticsCache.set(s,r);for(let a of this.diagnosticsListeners)a(s);}),await t.sendNotification(InitializedNotification.type,{}),this.state="running";}spawnAndConnect(){let t=spawn(this.options.command,this.options.args??[],{stdio:["pipe","pipe","pipe"],env:this.options.env?{...process.env,...this.options.env}:process.env});this.process=t,t.on("exit",()=>{(this.state==="running"||this.state==="starting")&&this.transitionToDead();});let e=new StreamMessageReader(t.stdout),i=new StreamMessageWriter(t.stdin);return createProtocolConnection(e,i)}async sendInitialize(){if(!this.connection)throw new Error("No connection");let t={textDocument:{synchronization:{dynamicRegistration:false,didSave:true},definition:{dynamicRegistration:false},references:{dynamicRegistration:false},callHierarchy:{dynamicRegistration:false},documentSymbol:{dynamicRegistration:false,hierarchicalDocumentSymbolSupport:true},publishDiagnostics:{relatedInformation:true}}};return await this.connection.sendRequest(InitializeRequest.type,{processId:process.pid,capabilities:t,rootUri:c(this.options.workspacePath,"."),initializationOptions:this.options.initializationOptions??null})}setupProviders(t){t.definitionProvider&&(this.definition={provideDefinition:(e,i)=>this.provideDefinition(e,i),provideTypeDefinition:(e,i)=>this.provideTypeDefinition(e,i)}),t.referencesProvider&&(this.references={provideReferences:(e,i)=>this.provideReferences(e,i)}),t.callHierarchyProvider&&(this.hierarchy={provideCallHierarchy:(e,i,n)=>this.provideCallHierarchy(e,i,n)}),t.documentSymbolProvider&&(this.outline={provideDocumentSymbols:e=>this.provideDocumentSymbols(e)}),this.diagnostics={provideDiagnostics:e=>this.provideDiagnostics(e),getWorkspaceDiagnostics:()=>this.getWorkspaceDiagnostics()};}assertRunning(){if(this.state!=="running")throw new Error(`Client is not running (state: "${this.state}")`);if(!this.connection)throw new Error("No connection");return this.connection}createTimeout(){let t=new CancellationTokenSource,e,i=new Promise((n,s)=>{e=setTimeout(()=>{t.cancel(),s(new Error("LSP request timed out"));},this.options.requestTimeout);});return {token:t,promise:i,clear:()=>{e&&clearTimeout(e);}}}async sendRequest(t,e){let i=this.assertRunning(),n=this.createTimeout();try{return await Promise.race([i.sendRequest(t,e,n.token.token),n.promise])}finally{n.clear();}}async ensureDocumentOpen(t){let e=this.openDocuments.get(t);if(e){e.closeTimer&&clearTimeout(e.closeTimer),e.closeTimer=this.scheduleDocumentClose(t);return}let i=u(this.options.workspacePath,t),n=await this.options.readFile(i),s=w(i),r={uri:t,version:1,closeTimer:this.scheduleDocumentClose(t)};this.openDocuments.set(t,r),await this.connection?.sendNotification(DidOpenTextDocumentNotification.type,{textDocument:{uri:t,languageId:s,version:r.version,text:n}});}scheduleDocumentClose(t){return setTimeout(()=>{this.closeDocument(t);},this.options.documentIdleTimeout)}async closeDocument(t){let e=this.openDocuments.get(t);if(e&&(e.closeTimer&&clearTimeout(e.closeTimer),this.openDocuments.delete(t),this.connection&&this.state==="running"))try{await this.connection.sendNotification(DidCloseTextDocumentNotification.type,{textDocument:{uri:t}});}catch{}}async provideDefinition(t,e){let i=c(this.options.workspacePath,t);await this.ensureDocumentOpen(i);let n=await this.sendRequest("textDocument/definition",{textDocument:{uri:i},position:{line:e.line,character:e.character}});return h(this.options.workspacePath,n,this.options.readFile)}async provideTypeDefinition(t,e){let i=c(this.options.workspacePath,t);await this.ensureDocumentOpen(i);let n=await this.sendRequest("textDocument/typeDefinition",{textDocument:{uri:i},position:{line:e.line,character:e.character}});return h(this.options.workspacePath,n,this.options.readFile)}async provideReferences(t,e){let i=c(this.options.workspacePath,t);await this.ensureDocumentOpen(i);let n=await this.sendRequest("textDocument/references",{textDocument:{uri:i},position:{line:e.line,character:e.character},context:{includeDeclaration:true}});return h(this.options.workspacePath,n,this.options.readFile)}async provideCallHierarchy(t,e,i){let n=c(this.options.workspacePath,t);await this.ensureDocumentOpen(n);let s=await this.sendRequest("textDocument/prepareCallHierarchy",{textDocument:{uri:n},position:{line:e.line,character:e.character}});if(!s||s.length===0)return [];let r=s[0],a=i==="incoming"?"callHierarchy/incomingCalls":"callHierarchy/outgoingCalls",d=await this.sendRequest(a,{item:r});if(!d||d.length===0)return [];let m=d.map(l=>{let v="from"in l?l.from:l.to;return {uri:v.uri,range:v.selectionRange}});return h(this.options.workspacePath,m,this.options.readFile)}async provideDocumentSymbols(t){let e=c(this.options.workspacePath,t);await this.ensureDocumentOpen(e);let i=await this.sendRequest("textDocument/documentSymbol",{textDocument:{uri:e}});if(!i||i.length===0)return [];let n=i[0];return n&&"range"in n&&"selectionRange"in n?i.map(f):i.map(s=>C(this.options.workspacePath,s))}async provideDiagnostics(t){this.assertRunning();let e=c(this.options.workspacePath,t);await this.ensureDocumentOpen(e);let i=this.diagnosticsCache.get(t);return i||(await new Promise(n=>setTimeout(n,200)),this.diagnosticsCache.get(t)??[])}async getWorkspaceDiagnostics(){this.assertRunning();let t=[];for(let e of this.diagnosticsCache.values())t.push(...e);return t}transitionToDead(){this.state="dead",this.cleanup();}cleanup(){for(let t of this.openDocuments.values())t.closeTimer&&clearTimeout(t.closeTimer);if(this.openDocuments.clear(),this.connection){try{this.connection.dispose();}catch{}this.connection=null;}if(this.process){try{this.process.kill();}catch{}this.process=null;}this.state="dead";}};function _(o){return new y(o)}export{y as LspClient,b as convertDiagnosticSeverity,h as convertLocationsToSnippets,g as convertLspDiagnostic,f as convertLspDocumentSymbol,R as convertLspPosition,p as convertLspRange,C as convertSymbolInformation,P as convertSymbolKind,_ as createLspClient,w as guessLanguageId,u as lspUriToPath,c as pathToLspUri};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-lsp-driver",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "MCP LSP Driver for IDE plugins to easily expose LSP features via an MCP server.",
5
5
  "type": "module",
6
6
  "types": "dist/index.d.ts",