mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-08-05 23:41:31 +08:00
32 lines
66 KiB
JavaScript
Generated
32 lines
66 KiB
JavaScript
Generated
"use strict";var vn=Object.create;var Ee=Object.defineProperty;var Ln=Object.getOwnPropertyDescriptor;var Tn=Object.getOwnPropertyNames;var En=Object.getPrototypeOf,Pn=Object.prototype.hasOwnProperty;var _n=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Tn(e))!Pn.call(t,o)&&o!==r&&Ee(t,o,{get:()=>e[o],enumerable:!(n=Ln(e,o))||n.enumerable});return t};var f=(t,e,r)=>(r=t!=null?vn(En(t)):{},_n(e||!t||!t.__esModule?Ee(r,"default",{value:t,enumerable:!0}):r,t));var xn=f(require("node:fs"));var He=f(require("node:fs")),C=f(require("node:path")),Ge=require("node:url");function Cn(t){switch(t){case 1:return"error";case 2:return"warning";case 3:return"info";case 4:return"hint";default:return"error"}}function x(t){return t.map(e=>({severity:Cn(e.severity),line:e.range.start.line+1,column:e.range.start.character+1,code:e.code,message:e.message,source:e.source}))}var Rn={5:"class",6:"method",8:"field",9:"constructor",10:"enum",11:"interface",12:"function",13:"variable",14:"constant",22:"enum-member",26:"type-parameter"};function Dn(t){return t!==void 0&&Rn[t]||"symbol"}function ie(t){let e=[];for(let r of t){if(typeof r!="object"||r===null)continue;let n=r,o=n.selectionRange?.start?.line??n.range?.start?.line,i={name:typeof n.name=="string"?n.name:"?",kind:Dn(typeof n.kind=="number"?n.kind:void 0),line:(typeof o=="number"?o:0)+1};Array.isArray(n.children)&&n.children.length>0&&(i.children=ie(n.children)),e.push(i)}return e}function Pe(t,e){if(e.length===0)return`No Apex symbols found in \`${t}\`.`;let r=[`### Symbols in \`${t}\``,""],n=(o,i)=>{for(let s of o)r.push(`${" ".repeat(i)}- \`${s.name}\` _(${s.kind})_ \u2014 line ${s.line}`),s.children&&n(s.children,i+1)};return n(e,0),r.join(`
|
|
`)}var An={2:"method",3:"function",4:"constructor",5:"field",6:"variable",7:"class",8:"interface",9:"module",10:"property",13:"enum",14:"keyword",20:"enum-member",21:"constant",22:"struct",25:"type-parameter"};function On(t){return t!==void 0&&An[t]||"symbol"}function B(t){let e=Array.isArray(t)?t:Array.isArray(t?.items)?t.items:[],r=[];for(let n of e){if(typeof n!="object"||n===null)continue;let o=n;if(typeof o.label!="string"||o.label.length===0)continue;let i={label:o.label,kind:On(typeof o.kind=="number"?o.kind:void 0)};typeof o.detail=="string"&&o.detail.length>0&&(i.detail=o.detail),r.push(i)}return r}function _e(t,e,r){if(r.length===0)return e;let n=[t,""];for(let o of r){let i=o.detail?` \u2014 ${o.detail}`:"";n.push(`- \`${o.label}\` _(${o.kind})_${i}`)}return n.join(`
|
|
`)}function Ce(t,e){return _e(`### Completions in \`${t}\``,`No Apex completions at that position in \`${t}\`.`,e)}function Re(t,e){return _e(`### LWC completions in \`${t}\``,`No LWC completions at that position in \`${t}\`.`,e)}function In(t){if(typeof t!="object"||t===null)return;let e=t.start;if(typeof e?.line=="number")return{line:e.line+1,character:(typeof e.character=="number"?e.character:0)+1}}function De(t){if(t==null)return[];let e=Array.isArray(t)?t:[t],r=[];for(let n of e){if(typeof n!="object"||n===null)continue;let o=n,i=typeof o.uri=="string"?o.uri:typeof o.targetUri=="string"?o.targetUri:void 0;if(!i)continue;let s=In(o.range??o.targetRange)??{line:1,character:1};r.push({uri:i,line:s.line,character:s.character})}return r}function Ae(t,e){if(e.length===0)return`No definition found at that position in \`${t}\`.`;let r=[`### Definition for symbol in \`${t}\``,""];for(let n of e)r.push(`- \`${n.uri}\` \u2014 line ${n.line}`);return r.join(`
|
|
`)}var qn={error:"\u{1F534}",warning:"\u{1F7E1}",info:"\u{1F535}",hint:"\u{1F4A1}"};function se(t,e,r){if(r.length===0)return e;let n=x(r),o=n.reduce((a,c)=>(a[c.severity]++,a),{error:0,warning:0,info:0,hint:0}),i=["error","warning","info","hint"].filter(a=>o[a]>0).map(a=>`${o[a]} ${a}${o[a]===1?"":"s"}`).join(", "),s=[t,"",`${i}`,"","| | Location | Code | Message |","|---|---|---|---|"];for(let a of n){let c=a.code!==void 0?`\`${a.code}\``:"",d=a.message.replace(/\|/g,"\\|").replace(/\n/g," ");s.push(`| ${qn[a.severity]} | ${a.line}:${a.column} | ${c} | ${d} |`)}return s.join(`
|
|
`)}function Oe(t,e){return se(`### Apex diagnostics for \`${t}\``,`\u2705 No Apex diagnostics for \`${t}\`.`,e)}function Ie(t){return se("### SOQL diagnostics","\u2705 Valid SOQL \u2014 no diagnostics.",t)}function qe(t,e){return se(`### LWC diagnostics for \`${t}\``,`\u2705 No LWC diagnostics for \`${t}\`.`,e)}var H=class{failures=0;openedAt=0;threshold;cooldownMs;now;constructor(e={}){this.threshold=e.threshold??3,this.cooldownMs=e.cooldownMs??3e4,this.now=e.now??Date.now}state(){return this.failures<this.threshold?"closed":this.now()-this.openedAt>=this.cooldownMs?"half-open":"open"}canAttempt(){return this.state()!=="open"}recordSuccess(){this.failures=0,this.openedAt=0}recordFailure(){this.failures++,this.failures>=this.threshold&&(this.openedAt=this.now())}};var je=process.env.SFDX_LSP_DEBUG==="1";function G(t,e){let r=e.map(n=>typeof n=="string"?n:jn(n));process.stderr.write(`[sf-lsp-host] ${t} ${r.join(" ")}
|
|
`)}function jn(t){try{return JSON.stringify(t)}catch{return String(t)}}var l={info(...t){G("info",t)},warn(...t){G("warn",t)},error(...t){G("error",t)},debug(...t){je&&G("debug",t)},get debugEnabled(){return je}};function Me(t){switch((t??"").trim().toLowerCase()){case"":case"all":return"all";case"apex-only":return"apex-only";case"disabled":return"disabled";default:return l.warn(`unknown SFDX_LSP value '${t}', defaulting to 'all'`),"all"}}function We(t,e){return t==="disabled"?!1:t==="apex-only"?e==="apex":!0}var Mn=t=>{process.stderr.write(t+`
|
|
`)},W=class{enabled;sink;now;constructor(e={}){this.enabled=e.enabled??process.env.SFDX_LSP_DEBUG==="1",this.sink=e.sink??Mn,this.now=e.now??Date.now}clock(){return this.now()}emit(e){this.enabled&&this.sink(JSON.stringify({telemetry:!0,ts:this.now(),...e}))}async time(e,r){if(!this.enabled)return r();let n=this.now();try{let o=await r();return this.emit({event:"request",tool:e,ms:this.now()-n,outcome:"ok"}),o}catch(o){throw this.emit({event:"request",tool:e,ms:this.now()-n,outcome:"error",error:o instanceof Error?o.message:String(o)}),o}}},V=new W({enabled:!1});var Wn=5e3,g=class extends Error{constructor(r){super(r);this.code=r;this.name="LspUnavailableError"}code},z=class{constructor(e,r){this.specs=e;this.options=r;this.spawnTimeoutMs=r.spawnTimeoutMs??Wn,this.now=r.now??Date.now,this.telemetry=r.telemetry??V;for(let n of e)this.entries.set(n.language,{spec:n,status:"idle",lastUsedAt:0}),this.breakers.set(n.language,new H({now:this.now}))}specs;options;entries=new Map;breakers=new Map;spawnTimeoutMs;now;telemetry;snapshot(){return[...this.entries.values()].map(e=>({language:e.spec.language,status:e.status,lastError:e.lastError,lastSpawnMs:e.lastSpawnMs,breaker:this.breakers.get(e.spec.language).state()}))}async getReadyClient(e,r){let n=this.entries.get(e);if(!n)throw new g("unknown_language");if(!We(this.options.killSwitch,e))throw new g("lsp_disabled");if(n.status==="ready"&&n.client&&!n.client.hasExited)return this.telemetry.emit({event:"client_cache",language:e,result:"hit"}),this.touch(n),n.client;if(n.status==="spawning"&&n.initPromise)return n.initPromise;let o=this.breakers.get(e);if(!o.canAttempt())throw new g("circuit_open");this.telemetry.emit({event:"client_cache",language:e,result:"miss"}),n.status="spawning";let i=this.bringUp(n,o,r);return n.initPromise=i,i}async bringUp(e,r,n){let o=await e.spec.gate(n);if(!o.ok)throw e.status="idle",e.initPromise=void 0,new g(o.error??"gate_failed");let i=e.spec.language,s=this.now();try{let a=await this.spawnWithTimeout(e,n);return e.client=a,e.status="ready",e.initPromise=void 0,e.lastError=void 0,e.lastSpawnMs=this.now()-s,this.recordBreaker(r,i,()=>r.recordSuccess()),this.telemetry.emit({event:"spawn",language:i,ms:e.lastSpawnMs,outcome:"ok"}),this.touch(e),l.debug(`${i} LSP ready`,{coldMs:e.lastSpawnMs}),a}catch(a){throw e.status="failed",e.initPromise=void 0,e.client=void 0,e.lastError=a instanceof Error?a.message:String(a),this.recordBreaker(r,i,()=>r.recordFailure()),this.telemetry.emit({event:"spawn",language:i,ms:this.now()-s,outcome:"error",error:e.lastError}),a instanceof g?a:new g("spawn_timeout")}}recordBreaker(e,r,n){let o=e.state();n();let i=e.state();o!==i&&this.telemetry.emit({event:"circuit",language:r,from:o,to:i})}spawnWithTimeout(e,r){let n=e.spec.createClient(r),o=new Promise((i,s)=>{let a=setTimeout(()=>s(new g("spawn_timeout")),this.spawnTimeoutMs);typeof a.unref=="function"&&a.unref()});return Promise.race([n,o])}touch(e){e.lastUsedAt=this.now(),this.armIdleTimer(e)}armIdleTimer(e){e.idleTimer&&clearTimeout(e.idleTimer);let r=setTimeout(()=>this.reap(e),e.spec.idleMs);typeof r.unref=="function"&&r.unref(),e.idleTimer=r}reap(e){if(e.status==="ready"){l.debug(`reaping idle ${e.spec.language} LSP`);try{e.client?.dispose()}catch(r){l.debug("LSP client dispose failed",{err:r.message})}e.client=void 0,e.status="idle",e.idleTimer&&clearTimeout(e.idleTimer),e.idleTimer=void 0}}shutdownAll(){for(let e of this.entries.values())this.reap(e)}};var m=class extends Error{constructor(e){super(e),this.name="ValidationError"}};function E(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Q(t){if(!E(t))throw new m("arguments must be an object");let e=t.filePath;if(typeof e!="string"||e.length===0)throw new m("filePath is required and must be a non-empty string");return{filePath:e}}function Fe(t){if(!E(t))throw new m("arguments must be an object");let e=t.query;if(typeof e!="string"||e.trim().length===0)throw new m("query is required and must be a non-empty string");return{query:e}}function ae(t){if(!E(t))throw new m("arguments must be an object");let e=t.filePath;if(typeof e!="string"||e.length===0)throw new m("filePath is required and must be a non-empty string");return{filePath:e}}function v(t){let{filePath:e}=ae(t),r=t;if(typeof r.line!="number"||!Number.isFinite(r.line)||r.line<1)throw new m("line is required and must be a positive (one-based) integer");if(typeof r.character!="number"||!Number.isFinite(r.character)||r.character<1)throw new m("character is required and must be a positive (one-based) integer");return{filePath:e,line:r.line,character:r.character}}function P(t){if(t.endsWith(".js"))return"javascript";if(t.endsWith(".html"))return"html"}function Ne(t){if(!E(t)||typeof t.line!="number"||typeof t.character!="number")throw new m("invalid LSP Position");return{line:t.line,character:t.character}}function Nn(t){if(!E(t))throw new m("invalid LSP Range");return{start:Ne(t.start),end:Ne(t.end)}}function Fn(t){if(!E(t))throw new m("diagnostic must be an object");if(typeof t.message!="string")throw new m("diagnostic.message must be a string");let e=typeof t.severity=="number"?t.severity:void 0,r=typeof t.code=="string"||typeof t.code=="number"?t.code:void 0,n=typeof t.source=="string"?t.source:void 0;return{range:Nn(t.range),message:t.message,severity:e,code:r,source:n}}function _(t){if(!Array.isArray(t))throw new m("diagnostics must be an array");let e=[];for(let r of t)try{e.push(Fn(r))}catch{}return e}var Ve="apex",$n=5e3,$e=20,Ue=250,Un=6;function ze(t){return{name:"apex.diagnostics",description:"Run semantic Apex diagnostics on a .cls file via the Apex language server. Returns errors/warnings (unknown SObject fields, type errors, missing symbols) before a deploy round-trip. Spawns the Apex LSP lazily on first use; returns a structured { error } envelope (no_apex_workspace | lsp_disabled | spawn_timeout | circuit_open) when unavailable so callers can fall back gracefully.",inputSchema:{type:"object",properties:{filePath:{type:"string",description:"Absolute or workspace-relative path to the .cls file to analyze."}},required:["filePath"],additionalProperties:!1},handler:async e=>{let{filePath:r}=Q(e),n=t.resolveWorkspace(),o=C.isAbsolute(r)?r:C.resolve(n.root,r),i;try{i=He.readFileSync(o,"utf8")}catch{return{error:"file_not_found",filePath:o}}let s;try{s=await t.lifecycle.getReadyClient(Ve,n)}catch(u){if(u instanceof g)return{error:u.code,filePath:o};throw u}let a=(0,Ge.pathToFileURL)(o).toString(),c=await Bn(s,a,i),d=_(c);return{ok:!0,filePath:o,diagnostics:x(d),markdown:Oe(C.basename(o),d)}}}}async function Bn(t,e,r){t.notify("textDocument/didOpen",{textDocument:{uri:e,languageId:Ve,version:1,text:r}});try{let n=0;for(let o=0;o<$e;o++){let i;try{i=(await Hn(t.request("textDocument/diagnostic",{textDocument:{uri:e}}),$n))?.items}catch(a){if((a instanceof Error?a.message:String(a)).includes("Unhandled method")&&o<$e-1){await Be(Ue);continue}throw a}let s=Array.isArray(i)?i:[];if(s.length>0)return s;if(++n>=Un)return[];await Be(Ue)}return[]}catch(n){return l.debug("diagnostic pull failed; treating as clean",{uri:e,error:n instanceof Error?n.message:String(n)}),[]}finally{try{t.notify("textDocument/didClose",{textDocument:{uri:e}})}catch{}}}function Be(t){return new Promise(e=>{let r=setTimeout(e,t);typeof r.unref=="function"&&r.unref()})}function Hn(t,e){return new Promise((r,n)=>{let o=setTimeout(()=>n(new Error("diagnostic_pull_timeout")),e);typeof o.unref=="function"&&o.unref(),t.then(i=>{clearTimeout(o),r(i)},i=>{clearTimeout(o),n(i)})})}var st=f(require("node:fs")),T=f(require("node:path")),at=require("node:url");var tt=f(require("node:fs")),ue=require("node:url"),Vn=f(require("node:zlib"));var ce=f(require("node:fs")),L=f(require("node:path")),Qe=new Set(["node_modules",".git",".sfdx",".sf","dist","out","coverage"]);function Je(t,e=0){if(e>12)return!1;let r;try{r=ce.readdirSync(t,{withFileTypes:!0})}catch{return!1}let n=L.basename(t)==="classes";for(let o of r)if(o.isFile()&&n&&o.name.endsWith(".cls"))return!0;for(let o of r)if(o.isDirectory()&&!Qe.has(o.name)&&Je(L.join(t,o.name),e+1))return!0;return!1}function Gn(t){return t.packageDirs.some(e=>Je(e))}function le(t,e=0,r=[]){if(e>12)return r;let n;try{n=ce.readdirSync(t,{withFileTypes:!0})}catch{return r}let o=L.basename(t)==="classes";for(let i of n)i.isFile()?o&&i.name.endsWith(".cls")&&r.push(L.join(t,i.name)):i.isDirectory()&&!Qe.has(i.name)&&le(L.join(t,i.name),e+1,r);return r}function Ke(t){return Gn(t)?{ok:!0}:{ok:!1,error:"no_apex_workspace"}}var N="apex",Ye=20,zn=250,Xe=2e4,Ze=new WeakMap;function pe(t,e){let r=Ze.get(t);if(r)return r;let n=Qn(t,e).catch(o=>(l.debug("apex workspace load failed",{error:o instanceof Error?o.message:String(o)}),!1));return Ze.set(t,n),n}async function Qn(t,e){let r=Yn(e);if(!r)return l.debug("apex workspace load skipped: no .cls files to batch"),!1;t.notify("workspace/didChangeConfiguration",{settings:{apex:{loadWorkspace:{enabled:!0}}}});let n,o=new Promise(a=>{n=a}),i=new Promise(a=>{t.onNotification("apex/workspaceIngestionComplete",()=>a())});t.onNotification("apex/requestWorkspaceLoad",()=>{n?.(),Kn(t,r)}),t.onNotification("apex/workspaceLoadFailed",a=>{l.debug("apex/workspaceLoadFailed",{params:a})});let s=(0,ue.pathToFileURL)(r.files[0].absPath).toString();return Jn(t,s),await et(o,Xe,"workspace_load_not_requested"),await et(i,Xe,"workspace_ingestion_timeout"),t.notify("apex/workspaceLoadComplete",{success:!0}),l.debug("apex workspace load complete",{files:r.files.length}),!0}async function Jn(t,e){for(let r=0;r<Ye;r++)try{await t.request("textDocument/references",{textDocument:{uri:e},position:{line:0,character:0},context:{includeDeclaration:!0}});return}catch(n){if((n instanceof Error?n.message:String(n)).includes("Unhandled method")&&r<Ye-1){await er(zn);continue}return}}async function Kn(t,e){try{await t.request("apex/sendWorkspaceBatch",{batchIndex:0,totalBatches:1,fileMetadata:e.fileMetadata,compressedData:e.compressedData}),await t.request("apex/processWorkspaceBatches",{totalBatches:1})}catch(r){l.debug("apex sendWorkspaceBatch failed",{error:r instanceof Error?r.message:String(r)})}}function Yn(t){let e=t.packageDirs.flatMap(i=>le(i));if(e.length===0)return;let r=e.map(i=>({absPath:i,uri:(0,ue.pathToFileURL)(i).toString()})),n=r.map(i=>({uri:i.uri,version:1})),o=[{name:"__metadata.json",data:Buffer.from(JSON.stringify({fileMetadata:n}),"utf8")},...r.map(i=>({name:i.uri,data:tt.readFileSync(i.absPath)}))];return{files:r,fileMetadata:n,compressedData:Xn(o).toString("base64")}}function Xn(t){let e=[],r=[],n=0;for(let{name:s,data:a}of t){let c=Buffer.from(s,"utf8"),d=Zn(a),u=Buffer.alloc(30);u.writeUInt32LE(67324752,0),u.writeUInt16LE(20,4),u.writeUInt16LE(0,8),u.writeUInt32LE(d,14),u.writeUInt32LE(a.length,18),u.writeUInt32LE(a.length,22),u.writeUInt16LE(c.length,26),e.push(u,c,a);let p=Buffer.alloc(46);p.writeUInt32LE(33639248,0),p.writeUInt16LE(20,4),p.writeUInt16LE(20,6),p.writeUInt16LE(0,10),p.writeUInt32LE(d,16),p.writeUInt32LE(a.length,20),p.writeUInt32LE(a.length,24),p.writeUInt16LE(c.length,28),p.writeUInt32LE(n,42),r.push(p,c),n+=u.length+c.length+a.length}let o=Buffer.concat(r),i=Buffer.alloc(22);return i.writeUInt32LE(101010256,0),i.writeUInt16LE(t.length,8),i.writeUInt16LE(t.length,10),i.writeUInt32LE(o.length,12),i.writeUInt32LE(n,16),Buffer.concat([...e,o,i])}function Zn(t){let e=Vn;if(typeof e.crc32=="function")return e.crc32(t)>>>0;let r=-1;for(let n=0;n<t.length;n++){r^=t[n];for(let o=0;o<8;o++)r=r>>>1^3988292384&-(r&1)}return~r>>>0}function er(t){return new Promise(e=>{let r=setTimeout(e,t);typeof r.unref=="function"&&r.unref()})}function et(t,e,r){return new Promise((n,o)=>{let i=setTimeout(()=>o(new Error(r)),e);typeof i.unref=="function"&&i.unref(),t.then(s=>{clearTimeout(i),n(s)},s=>{clearTimeout(i),o(s)})})}var nt=12,tr=250,de=8e3,rt=12,nr=250,ot=12,rr=250;function ct(t){return{name:"apex.hover",description:"Get the signature, type, and modifiers for the Apex symbol at a position in a .cls file, via the Apex language server. One-based line/character (as shown in an editor). Returns a structured { error } envelope (no_apex_workspace | lsp_disabled | spawn_timeout | circuit_open) when unavailable so callers can fall back gracefully.",inputSchema:{type:"object",properties:{filePath:{type:"string",description:"Absolute or workspace-relative path to the .cls file."},line:{type:"number",description:"One-based line of the symbol (as shown in an editor)."},character:{type:"number",description:"One-based column of the symbol (as shown in an editor)."}},required:["filePath","line","character"],additionalProperties:!1},handler:async e=>{let{filePath:r,line:n,character:o}=v(e),i=await fe(t,r);if("error"in i)return i;let{client:s,uri:a,absPath:c,text:d}=i;s.notify("textDocument/didOpen",{textDocument:{uri:a,languageId:N,version:1,text:d}});try{let u=await sr(s,a,n,o);return{ok:!0,filePath:c,hover:u,found:u!==void 0}}catch(u){return l.debug("apex.hover request failed",{uri:a,error:u instanceof Error?u.message:String(u)}),{ok:!0,filePath:c,hover:void 0,found:!1}}finally{me(s,a)}}}}function lt(t){return{name:"apex.documentSymbol",description:"List the symbols (classes, methods, fields, enums) declared in an Apex .cls file as a hierarchical outline, via the Apex language server. Spawns the Apex LSP and loads the workspace lazily on first use. Returns a structured { error } envelope (no_apex_workspace | lsp_disabled | spawn_timeout | circuit_open) when unavailable so callers can fall back.",inputSchema:{type:"object",properties:{filePath:{type:"string",description:"Absolute or workspace-relative path to the .cls file."}},required:["filePath"],additionalProperties:!1},handler:async e=>{let{filePath:r}=ae(e),n=await fe(t,r);if("error"in n)return n;let{client:o,uri:i,absPath:s,text:a,workspace:c}=n;o.notify("textDocument/didOpen",{textDocument:{uri:i,languageId:N,version:1,text:a}}),await pe(o,c);try{let d=await or(o,i),u=ie(d);return{ok:!0,filePath:s,symbols:u,markdown:Pe(T.basename(s),u)}}finally{me(o,i)}}}}function ut(t){return{name:"apex.completion",description:"List the Apex completions (methods, fields, properties, types) valid at a position in a .cls file, via the Apex language server \u2014 e.g. the members of a type after a `.`. Use to ground code on symbols that actually exist with correct signatures. One-based line/character (as shown in an editor). Spawns the Apex LSP and loads the workspace lazily on first use. Returns a structured { error } envelope (no_apex_workspace | lsp_disabled | spawn_timeout | circuit_open) when unavailable so callers can fall back.",inputSchema:{type:"object",properties:{filePath:{type:"string",description:"Absolute or workspace-relative path to the .cls file."},line:{type:"number",description:"One-based line of the completion position (as shown in an editor)."},character:{type:"number",description:"One-based column of the completion position (as shown in an editor)."}},required:["filePath","line","character"],additionalProperties:!1},handler:async e=>{let{filePath:r,line:n,character:o}=v(e),i=await fe(t,r);if("error"in i)return i;let{client:s,uri:a,absPath:c,text:d,workspace:u}=i;s.notify("textDocument/didOpen",{textDocument:{uri:a,languageId:N,version:1,text:d}}),await pe(s,u);try{let p=await ir(s,a,n,o),h=B(p);return{ok:!0,filePath:c,completions:h,markdown:Ce(T.basename(c),h)}}finally{me(s,a)}}}}async function fe(t,e){let r=t.resolveWorkspace(),n=T.isAbsolute(e)?e:T.resolve(r.root,e),o;try{o=st.readFileSync(n,"utf8")}catch{return{error:"file_not_found",filePath:n}}let i;try{i=await t.lifecycle.getReadyClient(N,r)}catch(s){if(s instanceof g)return{error:s.code,filePath:n};throw s}return{client:i,uri:(0,at.pathToFileURL)(n).toString(),absPath:n,text:o,workspace:r}}async function or(t,e){for(let r=0;r<nt;r++)try{let n=await he(t.request("textDocument/documentSymbol",{textDocument:{uri:e}}),de);return Array.isArray(n)?n:[]}catch(n){let o=n instanceof Error?n.message:String(n);if(o.includes("Unhandled method")&&r<nt-1){await ge(tr);continue}return l.debug("apex.documentSymbol request failed",{uri:e,error:o}),[]}return[]}async function ir(t,e,r,n){for(let o=0;o<ot;o++)try{return await he(t.request("textDocument/completion",{textDocument:{uri:e},position:{line:r-1,character:n-1}}),de)}catch(i){let s=i instanceof Error?i.message:String(i);if(s.includes("Unhandled method")&&o<ot-1){await ge(rr);continue}return l.debug("apex.completion request failed",{uri:e,error:s}),[]}return[]}async function sr(t,e,r,n){for(let o=0;o<rt;o++){let i=await he(t.request("textDocument/hover",{textDocument:{uri:e},position:{line:r-1,character:n-1}}),de),s=ar(i);if(s!==void 0)return s;o<rt-1&&await ge(nr)}}function ar(t){let e=t?.contents;if(e!=null){if(typeof e=="string")return e||void 0;if(Array.isArray(e)){let r=e.map(n=>typeof n=="string"?n:it(n)?n.value:void 0).filter(n=>typeof n=="string"&&n.length>0);return r.length>0?r.join(`
|
|
|
|
`):void 0}if(it(e))return e.value||void 0}}function it(t){return typeof t=="object"&&t!==null&&typeof t.value=="string"}function me(t,e){try{t.notify("textDocument/didClose",{textDocument:{uri:e}})}catch{}}function ge(t){return new Promise(e=>{let r=setTimeout(e,t);typeof r.unref=="function"&&r.unref()})}function he(t,e){return new Promise((r,n)=>{let o=setTimeout(()=>n(new Error("request_timeout")),e);typeof o.unref=="function"&&o.unref(),t.then(i=>{clearTimeout(o),r(i)},i=>{clearTimeout(o),n(i)})})}var bt=f(require("node:path")),kt=require("node:url");var ye=`\r
|
|
\r
|
|
`,cr=/Content-Length:\s*(\d+)/i,J=class{buffer=Buffer.alloc(0);push(e){this.buffer=Buffer.concat([this.buffer,e]);let r=[];for(;;){let n=this.buffer.indexOf(ye);if(n===-1)break;let o=this.buffer.toString("utf8",0,n),i=cr.exec(o);if(!i){this.buffer=this.buffer.subarray(n+ye.length);continue}let s=Number(i[1]),a=n+ye.length,c=a+s;if(this.buffer.length<c)break;let d=this.buffer.toString("utf8",a,c);this.buffer=this.buffer.subarray(c);try{r.push(JSON.parse(d))}catch{}}return r}};function pt(t){let e=JSON.stringify(t),r=Buffer.from(e,"utf8"),n=Buffer.from(`Content-Length: ${r.length}\r
|
|
\r
|
|
`,"ascii");return Buffer.concat([n,r])}var K=class{constructor(e){this.transport=e}transport;nextId=1;pending=new Map;notificationHandlers=new Map;serverRequestHandlers=new Map;request(e,r){let n=this.nextId++,o={jsonrpc:"2.0",id:n,method:e,params:r};return new Promise((i,s)=>{this.pending.set(n,{resolve:i,reject:s}),this.transport.send(o)})}notify(e,r){let n={jsonrpc:"2.0",method:e,params:r};this.transport.send(n)}onNotification(e,r){let n=this.notificationHandlers.get(e)??[];return n.push(r),this.notificationHandlers.set(e,n),()=>{let o=this.notificationHandlers.get(e);if(!o)return;let i=o.indexOf(r);i>=0&&o.splice(i,1)}}onServerRequest(e,r){this.serverRequestHandlers.set(e,r)}handleMessage(e){let r=e;if(r.id!==void 0&&r.method===void 0){let n=this.pending.get(r.id);if(!n)return;this.pending.delete(r.id),r.error?n.reject(new Error(`LSP error ${r.error.code}: ${r.error.message}`)):n.resolve(r.result);return}if(r.id!==void 0&&r.method!==void 0){let n=this.serverRequestHandlers.get(r.method),o=n?n(r.params):null,i={jsonrpc:"2.0",id:r.id,result:o};this.transport.send(i);return}if(r.method!==void 0){let n=this.notificationHandlers.get(r.method);if(n)for(let o of n.slice())o(r.params)}}rejectAll(e){for(let[,r]of this.pending)r.reject(new Error(e));this.pending.clear()}};var S=class{constructor(e){this.child=e;let r={send:n=>{if(!this.exited)try{this.child.stdin.write(pt(n))}catch(o){l.debug("LSP child stdin write failed",{err:o.message})}}};this.rpc=new K(r),this.child.stdin.on("error",n=>{l.debug("LSP child stdin error",{err:n.message})}),this.child.stdout.on("data",n=>{for(let o of this.decoder.push(n))this.rpc.handleMessage(o)}),this.rpc.onServerRequest("client/registerCapability",()=>null),this.rpc.onServerRequest("client/unregisterCapability",()=>null),this.rpc.onServerRequest("workspace/configuration",n=>(n?.items??[]).map(()=>null)),this.rpc.onServerRequest("window/workDoneProgress/create",()=>null),this.child.on("exit",n=>{this.exited=!0,this.rpc.rejectAll(`LSP child exited (code ${n})`),l.debug("LSP child exited",{code:n})})}child;decoder=new J;rpc;exited=!1;request(e,r){return this.rpc.request(e,r)}notify(e,r){this.rpc.notify(e,r)}onNotification(e,r){return this.rpc.onNotification(e,r)}onServerRequest(e,r){this.rpc.onServerRequest(e,r)}get hasExited(){return this.exited}dispose(){if(!this.exited){try{this.rpc.notify("shutdown"),this.rpc.notify("exit")}catch{}try{this.child.kill()}catch{}}}};var dt=require("node:child_process");function R(t){let e=(0,dt.spawn)(t.command,t.args,{cwd:t.cwd,stdio:["pipe","pipe","pipe"]});return e.stderr.on("data",r=>{l.debugEnabled&&process.stderr.write(`[lsp:${t.label}] ${r.toString("utf8")}`)}),e.on("error",r=>{l.error(`failed to spawn LSP child '${t.label}'`,r.message)}),e}var ft=f(require("node:fs")),b=f(require("node:path"));function lr(t){return ft.existsSync(b.join(t,".claude-plugin","plugin.json"))}function ur(t){for(let e=t;;){if(lr(e))return e;let r=b.dirname(e);if(r===e)break;e=r}return b.resolve(t,"..")}function Y(){let t=process.env.CLAUDE_PLUGIN_ROOT;return t&&t.length>0?t:ur(__dirname)}function mt(){return b.join(Y(),"vendor","apex-ls","dist","server.node.js")}function gt(){return b.join(Y(),"vendor","apex-ls","VERSION")}function ht(){return b.join(Y(),"bin","soql-lsp.bundled.js")}function yt(){return b.join(Y(),"vendor","lwc-language-server","node_modules","@salesforce","lwc-language-server","lib","server.js")}function wt(t){return(0,kt.pathToFileURL)(t).toString()}function pr(t){return{processId:process.pid,rootUri:wt(t.root),workspaceFolders:t.packageDirs.map(e=>({uri:wt(e),name:bt.basename(e)})),capabilities:{textDocument:{diagnostic:{dynamicRegistration:!1,relatedDocumentSupport:!1},publishDiagnostics:{relatedInformation:!0},synchronization:{didSave:!0,dynamicRegistration:!1}},workspace:{workspaceFolders:!0,configuration:!0,diagnostics:{refreshSupport:!0}}},initializationOptions:{apex:{environment:{serverMode:"development"},detailLevel:"public-api"}}}}async function St(t){let e=mt(),r=R({command:"node",args:[e,"--stdio"],cwd:t.root,label:"apex"}),n=new S(r);return await n.request("initialize",pr(t)),n.notify("initialized",{}),l.debug("apex-ls initialized",{root:t.root}),n}var dr=900*1e3,xt={language:"apex",idleMs:dr,gate:Ke,createClient:St};var Lt=f(require("node:path")),Tt=require("node:url");function vt(t){return(0,Tt.pathToFileURL)(t).toString()}function fr(t){return{processId:process.pid,rootUri:vt(t.root),workspaceFolders:t.packageDirs.map(e=>({uri:vt(e),name:Lt.basename(e)})),capabilities:{textDocument:{synchronization:{didSave:!0,dynamicRegistration:!1},completion:{dynamicRegistration:!1}}}}}async function Et(t){let e=ht(),r=R({command:"node",args:[e,"--stdio"],cwd:t.root,label:"soql"}),n=new S(r);return await n.request("initialize",fr(t)),n.notify("initialized",{}),l.debug("soql-ls initialized",{root:t.root}),n}function Pt(t){return{ok:!0}}var mr=300*1e3,_t={language:"soql",idleMs:mr,gate:Pt,createClient:Et};var Ct=require("node:url");function gr(t){return(0,Ct.pathToFileURL)(t).toString()}function hr(t){let e=gr(t.root);return{processId:process.pid,rootUri:e,rootPath:t.root,workspaceFolders:[{uri:e,name:"sfdx"}],capabilities:{textDocument:{synchronization:{didSave:!0,dynamicRegistration:!1},completion:{dynamicRegistration:!1},hover:{dynamicRegistration:!1},definition:{dynamicRegistration:!1}},workspace:{workspaceFolders:!0,configuration:!0}}}}async function Rt(t){let e=yt(),r=R({command:"node",args:[e,"--stdio"],cwd:t.root,label:"lwc"}),n=new S(r);return await n.request("initialize",hr(t)),n.notify("initialized",{}),l.debug("lwc-ls initialized",{root:t.root}),n}var Dt=f(require("node:fs")),At=f(require("node:path")),yr=new Set(["node_modules",".git",".sfdx",".sf","dist","out","coverage"]);function Ot(t,e=!1,r=0){if(r>12)return!1;let n;try{n=Dt.readdirSync(t,{withFileTypes:!0})}catch{return!1}if(e){for(let o of n)if(o.isFile()&&o.name.endsWith(".js"))return!0}for(let o of n)if(o.isDirectory()&&!yr.has(o.name)){let i=e||o.name==="lwc";if(Ot(At.join(t,o.name),i,r+1))return!0}return!1}function wr(t){return t.packageDirs.some(e=>Ot(e))}function It(t){return wr(t)?{ok:!0}:{ok:!1,error:"no_lwc_bundles"}}var br=900*1e3,qt={language:"lwc",idleMs:br,gate:It,createClient:Rt};var jt=f(require("node:fs")),X=f(require("node:path")),Mt=require("node:url");var we="lwc";async function D(t,e){let r=t.resolveWorkspace(),n=X.isAbsolute(e)?e:X.resolve(r.root,e),o;try{o=jt.readFileSync(n,"utf8")}catch{return{error:"file_not_found",filePath:n}}let i;try{i=await t.lifecycle.getReadyClient(we,r)}catch(s){if(s instanceof g)return{error:s.code,filePath:n};throw s}return{client:i,uri:(0,Mt.pathToFileURL)(n).toString(),absPath:n,text:o,workspace:r}}function A(t){return"error"in t}function O(t,e){try{t.notify("textDocument/didClose",{textDocument:{uri:e}})}catch{}}function I(t){return new Promise(e=>{let r=setTimeout(e,t);typeof r.unref=="function"&&r.unref()})}function be(t,e){return new Promise((r,n)=>{let o=setTimeout(()=>n(new Error("request_timeout")),e);typeof o.unref=="function"&&o.unref(),t.then(i=>{clearTimeout(o),r(i)},i=>{clearTimeout(o),n(i)})})}var kr=8e3,Sr=150;function Wt(t){return{name:"lwc.diagnostics",description:"Run diagnostics on a Lightning Web Component file (.js module or .html template) via the LWC language server. Catches @api/@track/@wire misuse, compile errors, and invalid template tags/directives before a deploy round-trip. Spawns the LWC LSP lazily on first use; returns a structured { error } envelope (no_lwc_bundles | lsp_disabled | spawn_timeout | circuit_open) when unavailable so callers can fall back gracefully.",inputSchema:{type:"object",properties:{filePath:{type:"string",description:"Absolute or workspace-relative path to the LWC .js or .html file."}},required:["filePath"],additionalProperties:!1},handler:async e=>{let{filePath:r}=Q(e),n=await D(t,r);if(A(n))return n;let{client:o,uri:i,absPath:s,text:a}=n,c=P(s);if(!c)return{error:"unsupported_lwc_file",filePath:s};let d=await xr(o,i,c,a),u=_(d);return{ok:!0,filePath:s,diagnostics:x(u),markdown:qe(s,u)}}}}async function xr(t,e,r,n){let o=()=>{};try{let i=new Promise(s=>{o=t.onNotification("textDocument/publishDiagnostics",a=>{let c=a;c?.uri===e&&s(Array.isArray(c.diagnostics)?c.diagnostics:[])})});return t.notify("textDocument/didOpen",{textDocument:{uri:e,languageId:r,version:1,text:n}}),await I(Sr),t.notify("textDocument/didChange",{textDocument:{uri:e,version:2},contentChanges:[{text:n}]}),await vr(i,kr)}catch(i){return l.debug("lwc.diagnostics push wait failed; treating as clean",{uri:e,error:i instanceof Error?i.message:String(i)}),[]}finally{o(),O(t,e)}}function vr(t,e){return new Promise(r=>{let n=setTimeout(()=>r([]),e);typeof n.unref=="function"&&n.unref(),t.then(o=>{clearTimeout(n),r(o)},()=>{clearTimeout(n),r([])})})}var Ft=8e3,F=12,ke=250;function $t(t){return{name:"lwc.hover",description:"Get hover docs for the symbol or template tag at a position in an LWC .js or .html file, via the LWC language server. One-based line/character (as shown in an editor). Returns a structured { error } envelope (no_lwc_bundles | lsp_disabled | spawn_timeout | circuit_open) when unavailable so callers can fall back gracefully.",inputSchema:Se("Absolute or workspace-relative path to the LWC .js or .html file."),handler:async e=>{let{filePath:r,line:n,character:o}=v(e),i=await D(t,r);if(A(i))return i;let{client:s,uri:a,absPath:c,text:d}=i,u=P(c);if(!u)return{error:"unsupported_lwc_file",filePath:c};xe(s,a,u,d);try{let p=await Tr(s,a,n,o);return{ok:!0,filePath:c,hover:p,found:p!==void 0}}catch(p){return l.debug("lwc.hover request failed",{uri:a,error:p instanceof Error?p.message:String(p)}),{ok:!0,filePath:c,hover:void 0,found:!1}}finally{O(s,a)}}}}function Ut(t){return{name:"lwc.definition",description:"Resolve the definition location(s) for the symbol or component tag at a position in an LWC .js or .html file, via the LWC language server \u2014 e.g. a `<c-foo>` tag in a template jumps to the foo component bundle. One-based line/character. Returns a structured { error } envelope (no_lwc_bundles | lsp_disabled | spawn_timeout | circuit_open) when unavailable.",inputSchema:Se("Absolute or workspace-relative path to the LWC .js or .html file."),handler:async e=>{let{filePath:r,line:n,character:o}=v(e),i=await D(t,r);if(A(i))return i;let{client:s,uri:a,absPath:c,text:d}=i,u=P(c);if(!u)return{error:"unsupported_lwc_file",filePath:c};xe(s,a,u,d);try{let p=await Ht(s,"textDocument/definition",a,n,o),h=De(p);return{ok:!0,filePath:c,locations:h,found:h.length>0,markdown:Ae(c,h)}}finally{O(s,a)}}}}function Bt(t){return{name:"lwc.completion",description:"List the LWC completions valid at a position in an LWC .js or .html file, via the LWC language server \u2014 e.g. the lightning-*/c-* tags valid in a template, or members after a `.` in a module. Use to ground generated markup/code on tags and members that actually exist. One-based line/character. Returns a structured { error } envelope (no_lwc_bundles | lsp_disabled | spawn_timeout | circuit_open) when unavailable.",inputSchema:Se("Absolute or workspace-relative path to the LWC .js or .html file."),handler:async e=>{let{filePath:r,line:n,character:o}=v(e),i=await D(t,r);if(A(i))return i;let{client:s,uri:a,absPath:c,text:d}=i,u=P(c);if(!u)return{error:"unsupported_lwc_file",filePath:c};xe(s,a,u,d);try{let p=await Ht(s,"textDocument/completion",a,n,o),h=B(p);return{ok:!0,filePath:c,completions:h,markdown:Re(c,h)}}finally{O(s,a)}}}}function Se(t){return{type:"object",properties:{filePath:{type:"string",description:t},line:{type:"number",description:"One-based line (as shown in an editor)."},character:{type:"number",description:"One-based column (as shown in an editor)."}},required:["filePath","line","character"],additionalProperties:!1}}function xe(t,e,r,n){t.notify("textDocument/didOpen",{textDocument:{uri:e,languageId:r,version:1,text:n}})}async function Ht(t,e,r,n,o){for(let i=0;i<F;i++)try{let s=await be(t.request(e,{textDocument:{uri:r},position:{line:n-1,character:o-1}}),Ft);if(!Lr(s)||i===F-1)return s;await I(ke)}catch(s){let a=s instanceof Error?s.message:String(s);if(a.includes("Unhandled method")&&i<F-1){await I(ke);continue}return l.debug(`${e} request failed`,{uri:r,error:a}),null}return null}function Lr(t){if(t==null)return!0;if(Array.isArray(t))return t.length===0;let e=t.items;return Array.isArray(e)?e.length===0:!1}async function Tr(t,e,r,n){for(let o=0;o<F;o++){let i=await be(t.request("textDocument/hover",{textDocument:{uri:e},position:{line:r-1,character:n-1}}),Ft),s=Er(i);if(s!==void 0)return s;o<F-1&&await I(ke)}}function Er(t){let e=t?.contents;if(e!=null){if(typeof e=="string")return e||void 0;if(Array.isArray(e)){let r=e.map(n=>typeof n=="string"?n:Nt(n)?n.value:void 0).filter(n=>typeof n=="string"&&n.length>0);return r.length>0?r.join(`
|
|
|
|
`):void 0}if(Nt(e))return e.value||void 0}}function Nt(t){return typeof t=="object"&&t!==null&&typeof t.value=="string"}var Gt=f(require("node:fs")),$=f(require("node:path"));var Pr=$.join(".sfdx","indexes","lwc","custom-components.json");function Vt(t){return{name:"lwc.workspace_symbols",description:"List every Lightning Web Component in the project (name, template tag, and source file), via the LWC language server\u2019s component index. Use to discover available `c-*` components before authoring a template. Spawns the LWC LSP lazily on first use to build the index; returns a structured { error } envelope (no_lwc_bundles | lsp_disabled | spawn_timeout | circuit_open) when unavailable so callers can fall back.",inputSchema:{type:"object",properties:{},additionalProperties:!1},handler:async()=>{let e=t.resolveWorkspace();try{await t.lifecycle.getReadyClient(we,e)}catch(o){if(o instanceof g)return{error:o.code};throw o}let r=$.join(e.root,Pr),n=_r(r);return{ok:!0,components:n,markdown:Rr(n)}}}}function _r(t){let e;try{e=JSON.parse(Gt.readFileSync(t,"utf8"))}catch(n){return l.debug("lwc.workspace_symbols: component index unreadable",{indexPath:t,error:n instanceof Error?n.message:String(n)}),[]}if(!Array.isArray(e))return[];let r=[];for(let n of e){if(typeof n!="object"||n===null)continue;let o=n.file;if(typeof o!="string"||o.length===0)continue;let i=$.parse(o).name;r.push({name:i,tag:Cr(i),file:o})}return r.sort((n,o)=>n.name.localeCompare(o.name)),r}function Cr(t){return`c-${t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}`}function Rr(t){if(t.length===0)return"No Lightning Web Components found in this project.";let e=[`### Lightning Web Components (${t.length})`,"","| Tag | Name | File |","|---|---|---|"];for(let r of t)e.push(`| \`${r.tag}\` | \`${r.name}\` | ${r.file} |`);return e.join(`
|
|
`)}var zt=require("node:url");var Qt="soql",Dr=5e3;function Jt(t){return{name:"validate_soql",description:"Validate a SOQL query string and return parser diagnostics (syntax errors) with one-based line/column. Parser-only \u2014 works without an org connection. A valid query returns an empty diagnostics list. Returns a structured { error } envelope (lsp_disabled | spawn_timeout | circuit_open) when the language server is unavailable so callers can fall back gracefully.",inputSchema:{type:"object",properties:{query:{type:"string",description:'The SOQL query string to validate, e.g. "SELECT Id FROM Account".'}},required:["query"],additionalProperties:!1},handler:async e=>{let{query:r}=Fe(e),n=t.resolveWorkspace(),o;try{o=await t.lifecycle.getReadyClient(Qt,n)}catch(a){if(a instanceof g)return{error:a.code};throw a}let i=await Ar(o,n,r),s=_(i);return{ok:!0,diagnostics:x(s),markdown:Ie(s)}}}}async function Ar(t,e,r){let n=(0,zt.pathToFileURL)(`${e.root}/__validate__.soql`).toString(),o=new Promise(i=>{let s=t.onNotification("textDocument/publishDiagnostics",a=>{let c=a;c?.uri===n&&(s(),i(Array.isArray(c.diagnostics)?c.diagnostics:[]))})});t.notify("textDocument/didOpen",{textDocument:{uri:n,languageId:Qt,version:1,text:r}});try{return await Or(o,Dr)}catch(i){return l.debug("soql publishDiagnostics timed out; treating as clean",{error:i instanceof Error?i.message:String(i)}),[]}finally{try{t.notify("textDocument/didClose",{textDocument:{uri:n}})}catch{}}}function Or(t,e){return new Promise((r,n)=>{let o=setTimeout(()=>n(new Error("soql_validate_timeout")),e);typeof o.unref=="function"&&o.unref(),t.then(i=>{clearTimeout(o),r(i)},i=>{clearTimeout(o),n(i)})})}var Z=f(require("node:fs")),q=f(require("node:path")),Ir=120;function qr(t){let e=[],r=[],n=[],o=t.length,i=0,s=1,a=1;for(;i<o;){let c=t[i],d=i+1<o?t[i+1]:"";if(c==="/"&&d==="/"){for(i+=2,a+=2;i<o&&t[i]!==`
|
|
`;)i++,a++;continue}if(c==="/"&&d==="*"){for(i+=2,a+=2;i<o&&!(t[i]==="*"&&t[i+1]==="/");)t[i]===`
|
|
`?(s++,a=1):a++,i++;i<o&&(i+=2,a+=2);continue}if(c==="'"){let u=i,p=s,h=a;i++,a++;let w="";for(;i<o&&t[i]!=="'";){if(t[i]==="\\"&&i+1<o){w+=t[i]+t[i+1],i+=2,a+=2;continue}t[i]===`
|
|
`?(s++,a=1):a++,w+=t[i],i++}i<o&&(i++,a++),n.length===0&&r.push({content:w,startIndex:u,endIndex:i,line:p,column:h});continue}if(c==="["){n.push({line:s,column:a,contentStart:i+1}),i++,a++;continue}if(c==="]"){let u=n.pop();if(u&&n.length===0){let h=t.slice(u.contentStart,i).trim();/^SELECT\b/i.test(h)&&e.push({query:h,startLine:u.line,startColumn:u.column,endLine:s,endColumn:a})}i++,a++;continue}c===`
|
|
`?(s++,a=1):a++,i++}return{queries:e,dynamic:jr(t,r)}}function jr(t,e){let r=[],n=0;for(;n<e.length;){let o=[e[n]],i=n;for(;i+1<e.length&&Mr(t.slice(e[i].endIndex,e[i+1].startIndex));)o.push(e[i+1]),i++;let s=o.map(a=>a.content).join(" ");Wr(s)&&r.push({snippet:Nr(s.trim(),Ir),line:o[0].line,column:o[0].column}),n=i+1}return r}function Mr(t){return t.includes("+")&&!/[;{}]/.test(t)}function Wr(t){return/\bSELECT\b[\s\S]*\bFROM\b/i.test(t)}function Nr(t,e){return t.length>e?`${t.slice(0,e)}\u2026`:t}var Kt=500,Fr=12,$r=new Set(["node_modules",".git",".sfdx",".sf","dist","out","coverage"]);function Xt(t){return{name:"extract_soql_from_apex",description:"Extract every inline SOQL query ([SELECT ... FROM ...]) from Apex .cls/.trigger files, with one-based file/line/column ranges. Dynamic queries built by string concatenation are flagged separately (located, not extracted \u2014 their text is not known statically). Pass a filePath to scan one file, or omit it to walk the workspace package directories. Pure static analysis \u2014 never spawns a language server.",inputSchema:{type:"object",properties:{filePath:{type:"string",description:"Optional absolute or workspace-relative path to a single .cls/.trigger file. Omit to scan all Apex files under the workspace package directories."}},additionalProperties:!1},handler:e=>{let r=Ur(e),n=t.resolveWorkspace(),o=r?Br(r,n):Hr(n),i=o.length>Kt,s=i?o.slice(0,Kt):o,a=[];for(let u of s){let p;try{p=Z.readFileSync(u,"utf8")}catch{continue}let{queries:h,dynamic:w}=qr(p);(h.length>0||w.length>0)&&a.push({filePath:u,queries:h,dynamic:w})}let c=a.reduce((u,p)=>u+p.queries.length,0),d=a.reduce((u,p)=>u+p.dynamic.length,0);return{ok:!0,scannedFileCount:s.length,truncated:i,totalQueries:c,totalDynamic:d,files:a,markdown:Gr(a,c,d,s.length,i)}}}}function Ur(t){let e=t?.filePath;if(e!==void 0){if(typeof e!="string"||e.length===0)throw new Error("filePath, when provided, must be a non-empty string");if(!Zt(e))throw new Error("filePath must be an Apex source file (.cls or .trigger)");return e}}function Zt(t){return t.endsWith(".cls")||t.endsWith(".trigger")}function Br(t,e){return[q.isAbsolute(t)?t:q.resolve(e.root,t)]}function Hr(t){let e=[];for(let r of t.packageDirs)en(r,0,e);return e}function en(t,e,r){if(e>Fr)return;let n;try{n=Z.readdirSync(t,{withFileTypes:!0})}catch{return}for(let o of n){if(o.name.startsWith(".")||$r.has(o.name))continue;let i=q.join(t,o.name);o.isDirectory()?en(i,e+1,r):o.isFile()&&Zt(o.name)&&r.push(i)}}function Gr(t,e,r,n,o){if(t.length===0)return`No SOQL found in ${n} Apex file${n===1?"":"s"}.`;let i=["### Inline SOQL in Apex","",`${e} inline quer${e===1?"y":"ies"}, ${r} dynamic quer${r===1?"y":"ies"} flagged, across ${t.length} file${t.length===1?"":"s"}`+(o?` (scan truncated at ${n} files)`:"")];for(let s of t){i.push("",`**${s.filePath}**`);for(let a of s.queries)i.push(`- ${a.startLine}:${a.startColumn} \u2014 \`${Yt(a.query)}\``);for(let a of s.dynamic)i.push(`- \u26A1 ${a.line}:${a.column} dynamic \u2014 \`${Yt(a.snippet)}\` (not extracted)`)}return i.join(`
|
|
`)}function Yt(t){let e=t.replace(/\s+/g," ").trim();return e.length>80?`${e.slice(0,80)}\u2026`:e}var tn=require("node:child_process");var Vr=15e3,nn=(t,e)=>new Promise(r=>{(0,tn.execFile)(t,e,{timeout:Vr,maxBuffer:8*1024*1024,encoding:"utf8"},(n,o)=>{if(n){l.debug("sf-context-bridge: cli command failed",{command:t,arg0:e[0],error:n.message}),r(null);return}r(o)})});async function ee(t={}){let e=t.runCli??nn,r=await on(e);if(!r)return null;let{orgId:n,instanceUrl:o,apiVersion:i}=r;if(!n||!o)return l.debug("sf-context-bridge: org display missing id/instanceUrl",{hasId:!!n}),null;let s=await zr(e);return s?{orgId:n,accessToken:s,instanceUrl:o,apiVersion:i||"unknown"}:null}async function rn(t={}){let e=t.runCli??nn;return(await on(e))?.orgId??null}async function on(t){let e=await t("sf",["org","display","--json"]),r=Qr(e);return r?{orgId:ve(r.id),instanceUrl:ve(r.instanceUrl),apiVersion:ve(r.apiVersion)}:null}async function zr(t){let e=await t("sf",["org","auth","show-access-token","--json","--no-prompt"]);if(!e)return null;try{let r=JSON.parse(e),n=typeof r.result=="string"?r.result.trim():"";return!n||/redacted/i.test(n)?(l.debug("sf-context-bridge: access token unavailable or redacted"),null):n}catch{return null}}function Qr(t){if(!t)return null;try{let e=JSON.parse(t);if(e.status!==0)return null;let r=e.result;return r&&typeof r=="object"?r:null}catch{return null}}function ve(t){return typeof t=="string"?t:""}var Jr=new Set(["id","name","createddate","createdbyid","lastmodifieddate","lastmodifiedbyid","systemmodstamp","recordtypeid","ownerid"]);function Kr(t){let e=[],r=Xr(t),n=Yr(r,t),o=/\bWHERE\b/i.test(n.normalized),i=/\bLIMIT\b/i.test(n.normalized);if(o||(i?e.push({code:"no_where_clause",severity:"info",message:"Query has no WHERE clause. A LIMIT bounds the rows returned but the query still scans the object; add a selective filter for large objects."}):e.push({code:"missing_where",severity:"warning",message:"Query has no WHERE clause and no LIMIT \u2014 it scans the entire object and will fail on large objects (non-selective query, >100k rows)."})),Zr(t)&&e.push({code:"leading_wildcard_like",severity:"warning",message:`A LIKE filter with a leading wildcard (e.g. "LIKE '%foo%'") cannot use an index and forces a full scan. Anchor the pattern or filter on an indexed field.`}),o){let a=eo(n.normalized);a.length>0&&!a.some(c=>no(c))&&e.push({code:"possibly_non_indexed_filter",severity:"info",message:`WHERE filters on ${a.join(", ")} \u2014 none are standard-indexed fields. If these are not custom-indexed/external-id fields, the query may be non-selective. Use --check-runtime to verify against the org.`})}for(let a of n.subselects)if(!/\bLIMIT\b/i.test(a)){e.push({code:"unbounded_child_subselect",severity:"info",message:"A child-relationship subselect has no LIMIT. Parent rows with many children can blow the subquery row cap; add a LIMIT to the subselect."});break}return{selective:!e.some(a=>a.severity==="warning"),findings:e}}function Yr(t,e){let r=[],n="",o=0,i="";for(let s of t){if(s==="("&&(o++,o===1)){i="";continue}if(s===")"){if(o===1){/\bSELECT\b/i.test(i)&&/\bFROM\b/i.test(i)?(r.push(i),n+=" () "):n+=` (${i}) `,o--;continue}o--}o>=1?i+=s:n+=s}return{normalized:n,subselects:r}}function Xr(t){return t.replace(/'(?:\\.|[^'\\])*'/g,"''")}function Zr(t){let e=/\bLIKE\s+'(\\.|[^'\\])*?'/gi,r;for(;(r=e.exec(t))!==null;){let n=r[0].slice(r[0].indexOf("'")+1,-1);if(n.startsWith("%")||n.startsWith("_"))return!0}return!1}function eo(t){let e=to(t,"WHERE",["GROUP BY","ORDER BY","LIMIT","HAVING","OFFSET","FOR "]);if(!e)return[];let r=new Set,n=/([A-Za-z_][A-Za-z0-9_.]*)\s*(=|!=|<>|<|>|<=|>=|\bLIKE\b|\bIN\b|\bNOT\s+IN\b)/gi,o;for(;(o=n.exec(e))!==null;){let i=o[1];/^(AND|OR|NOT)$/i.test(i)||r.add(i)}return[...r]}function to(t,e,r){let n=new RegExp(`\\b${e}\\b`,"i").exec(t);if(!n)return null;let o=t.length;for(let i of r){let s=new RegExp(`\\b${i.trim()}\\b`,"i").exec(t.slice(n.index+e.length));s&&(o=Math.min(o,n.index+e.length+s.index))}return t.slice(n.index+e.length,o)}function no(t){let r=(t.split(".").pop()??t).toLowerCase();return Jr.has(r)||r.endsWith("id")}function sn(t={}){let e=t.runtimeCheck??oo;return{name:"check_soql_selectivity",description:"Analyze a SOQL query for selectivity problems that cause full scans or trip the platform's non-selective-query limit: missing WHERE, leading-wildcard LIKE, filters on non-indexed fields, and unbounded child subselects. Static and offline by default. Pass checkRuntime:true to additionally run the query with LIMIT 0 against the connected org for query-plan-style validation (requires an org).",inputSchema:{type:"object",properties:{query:{type:"string",description:`The SOQL query to analyze, e.g. "SELECT Id FROM Account WHERE Name = 'Acme'".`},checkRuntime:{type:"boolean",description:"Opt in to a LIMIT-0 run against the connected org (default false). No effect when no org is connected."}},required:["query"],additionalProperties:!1},handler:async r=>{let{query:n,checkRuntime:o}=ro(r),i=Kr(n),s;if(o){let a=await ee(t.bridge);if(!a)s={skipped:"no_org_connected"};else{let c=await e(a,n);s=c??{skipped:"runtime_check_failed"},c&&!c.ok&&(i.findings.push({code:"runtime_non_selective",severity:"warning",message:`Org rejected the LIMIT-0 plan: ${c.message??"non-selective query"}`}),i.selective=!1)}}return{ok:!0,selective:i.selective,findings:i.findings,runtime:s,markdown:so(n,i,s)}}}}function ro(t){let e=t?.query;if(typeof e!="string"||e.trim().length===0)throw new m("query is required and must be a non-empty string");let r=t?.checkRuntime;if(r!==void 0&&typeof r!="boolean")throw new m("checkRuntime must be a boolean when provided");return{query:e,checkRuntime:r===!0}}var oo=async(t,e)=>{let r=t.apiVersion&&t.apiVersion!=="unknown"?t.apiVersion:"60.0",n=t.instanceUrl.replace(/\/+$/,""),o=io(e),i=`${n}/services/data/v${r}/query?q=${encodeURIComponent(o)}`;try{let s=await fetch(i,{headers:{Authorization:`Bearer ${t.accessToken}`,Accept:"application/json"}});if(s.ok)return{ok:!0};let a=`HTTP ${s.status}`;try{let c=await s.json(),d=Array.isArray(c)?c[0]:c;d?.message&&(a=d.message)}catch{}return{ok:!1,message:a}}catch(s){return l.debug("selectivity: runtime check failed",{error:s instanceof Error?s.message:String(s)}),null}};function io(t){let e=t.trim().replace(/;+\s*$/,"");return/\bLIMIT\s+\d+\b/i.test(e)?e.replace(/\bLIMIT\s+\d+\b/i,"LIMIT 0"):`${e} LIMIT 0`}function so(t,e,r){let n=["### SOQL selectivity"];if(e.findings.length===0)n.push("","\u2705 No selectivity issues detected.");else{n.push("",`${e.findings.length} finding(s):`,"");for(let o of e.findings){let i=o.severity==="warning"?"\u26A0\uFE0F":"\u2139\uFE0F";n.push(`- ${i} **${o.code}** \u2014 ${o.message}`)}}return r&&"skipped"in r?n.push("",`_Runtime check skipped: ${r.skipped}._`):r&&n.push("",r.ok?"_Runtime LIMIT-0 plan: accepted._":`_Runtime LIMIT-0 plan: rejected \u2014 ${r.message}._`),n.join(`
|
|
`)}function an(t){return{name:"refresh_org_schema",description:"Invalidate the cached org schema so the next SOQL completion re-fetches it from the org. Pass sobject to invalidate just one SObject, or omit it to clear the whole org's cache. Use after changing fields/objects in the org. Returns no_org_connected when no org is connected.",inputSchema:{type:"object",properties:{sobject:{type:"string",description:'Optional SObject API name to invalidate (e.g. "Account"). Omit to clear the entire org schema cache.'}},additionalProperties:!1},handler:async e=>{let r=ao(e),n=await t.cache.invalidate(r);return n===null?{ok:!1,error:"no_org_connected",markdown:co}:{ok:!0,scope:r??"all SObjects",removed:n,markdown:lo(r,n)}}}}function ao(t){let e=t?.sobject;if(e!==void 0){if(typeof e!="string"||e.trim().length===0)throw new m("sobject, when provided, must be a non-empty string");return e.trim()}}var co="### Refresh org schema\n\nNo org connected \u2014 nothing to refresh. Connect an org with `sf org login web` and set a default with `sf config set target-org <alias>`.";function lo(t,e){return t?`### Refresh org schema
|
|
|
|
`+(e>0?`Invalidated cached schema for **${t}**. The next completion will re-fetch it.`:`No cached schema for **${t}** \u2014 nothing to invalidate (it will fetch on first use).`):`### Refresh org schema
|
|
|
|
Cleared the org schema cache (${e} SObject${e===1?"":"s"}). The next completion will re-fetch from the org.`}var un=require("node:url");var j={SOBJECTS:"__SOBJECTS_PLACEHOLDER",SOBJECT_FIELDS:"__SOBJECT_FIELDS_PLACEHOLDER",RELATIONSHIPS:"__RELATIONSHIPS_PLACEHOLDER",RELATIONSHIP_FIELDS:"__RELATIONSHIP_FIELDS_PLACEHOLDER",LITERAL_VALUES:"__LITERAL_VALUES_FOR_FIELD"},uo=new Set(Object.values(j));function po(t){return typeof t=="string"&&uo.has(t)}var cn=7,fo=5,mo=12;async function ln(t,e){let r=[],n=[],o=[];for(let i of t){if(!po(i.label)){r.push(i);continue}let s=await go(i,e);if(s===null){r.push(i),o.push(i.label);continue}n.push(i.label),r.push(...s)}return{items:r,expanded:n,unresolved:o}}async function go(t,e){let r=bo(t);switch(t.label){case j.SOBJECTS:{let n=await e.listSObjectNames();return n===null?null:n.map(o=>({label:o,kind:cn}))}case j.SOBJECT_FIELDS:case j.RELATIONSHIP_FIELDS:{let n=await Le(r,e);return n?n.fields.map(ho):n===void 0?[]:null}case j.RELATIONSHIPS:{let n=await Le(r,e);return n?n.childRelationships.filter(o=>o.relationshipName).map(o=>({label:o.relationshipName,kind:cn,detail:`child: ${o.childSObject}`})):n===void 0?[]:null}case j.LITERAL_VALUES:{let n=await Le(r,e);if(!n)return n===void 0?[]:null;let o=r.fieldName?n.fields.find(i=>i.name.toLowerCase()===r.fieldName.toLowerCase()):void 0;return o?o.picklistValues.map(i=>wo(i,o.type)):[]}default:return null}}async function Le(t,e){let r=t.sobjectName?.trim();if(r)return e.getSObject(r)}function ho(t){let e=t.label&&t.label!==t.name?`${t.type} \u2014 ${t.label}`:t.type;return{label:t.name,kind:fo,detail:e}}var yo=new Set(["picklist","multipicklist","string","textarea","email","phone","url","reference","id","combobox","encryptedstring"]);function wo(t,e){let r=yo.has(e.toLowerCase());return{label:t,kind:mo,insertText:r?`'${t}'`:t}}function bo(t){let r=t.data?.soqlContext;if(typeof r!="object"||r===null)return{};let n=r;return{sobjectName:typeof n.sobjectName=="string"?n.sobjectName:void 0,fieldName:typeof n.fieldName=="string"?n.fieldName:void 0,onlyTypes:Array.isArray(n.onlyTypes)?n.onlyTypes.filter(o=>typeof o=="string"):void 0}}var pn="soql",ko=5e3;function dn(t){return{name:"complete_soql",description:"Get SOQL code completions at a cursor position in a query. Returns real SObject names, fields, relationships, and picklist literal values resolved against the connected org, plus SOQL keywords and functions. Line and column are one-based. Without an org connection the schema entries are returned as unexpanded placeholders with a no_org_connected hint; keyword and function completions still work. Returns a structured { error } envelope (lsp_disabled | spawn_timeout | circuit_open) when the language server is unavailable so callers can fall back gracefully.",inputSchema:{type:"object",properties:{query:{type:"string",description:'The SOQL query text, e.g. "SELECT Id FROM Account WHERE ".'},line:{type:"number",description:"One-based line of the cursor within the query (default 1)."},column:{type:"number",description:"One-based column of the cursor within the line. Defaults to the end of the (single-line) query."}},required:["query"],additionalProperties:!1},handler:async e=>{let{query:r,line:n,column:o}=xo(e),i=t.resolveWorkspace(),s;try{s=await t.lifecycle.getReadyClient(pn,i)}catch(w){if(w instanceof g)return{error:w.code};throw w}let a=await vo(s,i,r,n,o),c=So(t.cache),{items:d,expanded:u,unresolved:p}=await ln(a,c),h=p.length>0&&u.length===0;return{ok:!0,items:d,expanded:u,unresolved:p,...h?{hint:"no_org_connected"}:{},markdown:To(d,p,h)}}}}function So(t){return{getSObject:e=>t.getSObject(e),listSObjectNames:()=>t.listSObjectNames()}}function xo(t){if(typeof t!="object"||t===null||Array.isArray(t))throw new m("arguments must be an object");let e=t;if(typeof e.query!="string"||e.query.trim().length===0)throw new m("query is required and must be a non-empty string");let r=e.query;if(e.line!==void 0&&(typeof e.line!="number"||!Number.isFinite(e.line)||e.line<1))throw new m("line, when provided, must be a positive (one-based) integer");if(e.column!==void 0&&(typeof e.column!="number"||!Number.isFinite(e.column)||e.column<1))throw new m("column, when provided, must be a positive (one-based) integer");let n=r.split(`
|
|
`),o=e.line!==void 0?e.line-1:n.length-1,i=n[Math.min(o,n.length-1)]?.length??0,s=e.column!==void 0?e.column-1:i;return{query:r,line:o,column:s}}async function vo(t,e,r,n,o){let i=(0,un.pathToFileURL)(`${e.root}/__complete__.soql`).toString();t.notify("textDocument/didOpen",{textDocument:{uri:i,languageId:pn,version:1,text:r}});try{let s=await Eo(t.request("textDocument/completion",{textDocument:{uri:i},position:{line:n,character:o}}),ko);return Lo(s)}catch(s){return l.debug("soql completion timed out / failed; treating as empty",{error:s instanceof Error?s.message:String(s)}),[]}finally{try{t.notify("textDocument/didClose",{textDocument:{uri:i}})}catch{}}}function Lo(t){let e=Array.isArray(t)?t:Array.isArray(t?.items)?t.items:[],r=[];for(let n of e){if(typeof n!="object"||n===null)continue;let o=n;if(typeof o.label!="string"||o.label.length===0)continue;let i={label:o.label};typeof o.kind=="number"&&(i.kind=o.kind),typeof o.insertText=="string"&&(i.insertText=o.insertText),typeof o.detail=="string"&&(i.detail=o.detail),typeof o.data=="object"&&o.data!==null&&(i.data=o.data),r.push(i)}return r}function To(t,e,r){if(t.length===0)return`### SOQL completions
|
|
|
|
No completions at that position.`;let n=["### SOQL completions",""];r?n.push("> No org connected \u2014 schema entries (SObjects, fields, picklist values) could not be resolved and are shown as placeholders. Connect an org with `sf org login web` for real schema completions.",""):e.length>0&&n.push(`> Some schema entries could not be resolved (${e.join(", ")}); try \`refresh_org_schema\` if the org schema changed.`,"");for(let o of t.slice(0,50)){let i=o.detail?` \u2014 ${o.detail}`:"";n.push(`- \`${o.label}\`${i}`)}return t.length>50&&n.push(`- \u2026and ${t.length-50} more`),n.join(`
|
|
`)}function Eo(t,e){return new Promise((r,n)=>{let o=setTimeout(()=>n(new Error("soql_complete_timeout")),e);typeof o.unref=="function"&&o.unref(),t.then(i=>{clearTimeout(o),r(i)},i=>{clearTimeout(o),n(i)})})}var y=f(require("node:fs")),gn=f(require("node:os")),M=f(require("node:path"));var Po=1440*60*1e3,hn="__sobjects__.json";function _o(){return M.join(gn.homedir(),".sfdx","claude","soql-schema")}var te=class{cacheRoot;now;ttlMs;fetchDescribe;fetchGlobal;bridge;orgContext;constructor(e={}){this.cacheRoot=e.cacheRoot??_o(),this.now=e.now??Date.now,this.ttlMs=e.ttlMs??Po,this.fetchDescribe=e.fetchDescribe??Ro,this.fetchGlobal=e.fetchGlobal??Do,this.bridge=e.bridge??{}}async getSObject(e){let r=fn(e);if(!r)return null;let n=await this.getOrgContext();if(!n)return null;let o=this.entryPath(n.orgId,r),i=this.readFresh(o);if(i)return i;let s=await this.fetchDescribe(n,r);if(!s)return null;let a=Co(r,s,this.now());return this.write(o,a),a}async listSObjectNames(){let e=await this.getOrgContext();if(!e)return null;let r=this.entryPath(e.orgId,hn.replace(/\.json$/,"")),n=this.readFreshGlobal(r);if(n)return n;let o=await this.fetchGlobal(e);if(!o)return null;let i=[...o].sort((s,a)=>s.localeCompare(a));return this.write(r,{names:i,fetchedAt:this.now()}),i}async invalidate(e){let r=await this.getOrgId();if(!r)return null;if(e){let i=fn(e);if(!i)return 0;let s=this.entryPath(r,i);return Ao(s)?1:0}let n=this.orgDir(r),o=Oo(n);return Io(n),o}orgDir(e){return M.join(this.cacheRoot,mn(e))}entryPath(e,r){return M.join(this.orgDir(e),`${mn(r)}.json`)}readFresh(e){let r;try{r=y.readFileSync(e,"utf8")}catch{return null}let n;try{n=JSON.parse(r)}catch{return null}return typeof n.fetchedAt!="number"||this.now()-n.fetchedAt>this.ttlMs?null:n}readFreshGlobal(e){let r;try{r=y.readFileSync(e,"utf8")}catch{return null}let n;try{n=JSON.parse(r)}catch{return null}return!Array.isArray(n.names)||typeof n.fetchedAt!="number"||this.now()-n.fetchedAt>this.ttlMs?null:n.names}write(e,r){try{y.mkdirSync(M.dirname(e),{recursive:!0}),y.writeFileSync(e,JSON.stringify(r),"utf8")}catch(n){l.debug("org-cache: failed to write entry",{file:e,error:n instanceof Error?n.message:String(n)})}}async getOrgContext(){return this.orgContext===void 0&&(this.orgContext=await ee(this.bridge)),this.orgContext}async getOrgId(){return this.orgContext?this.orgContext.orgId:rn(this.bridge)}};function Co(t,e,r){let n=(e.fields??[]).map(i=>({name:i.name??"",label:i.label??i.name??"",type:i.type??"unknown",referenceTo:Array.isArray(i.referenceTo)?i.referenceTo.filter(Te):[],relationshipName:i.relationshipName??null,picklistValues:(i.picklistValues??[]).filter(s=>s.active!==!1).map(s=>s.value??"").filter(Te)})),o=(e.childRelationships??[]).map(i=>({relationshipName:i.relationshipName??null,childSObject:i.childSObject??"",field:i.field??""}));return{name:e.name||t,fields:n,childRelationships:o,fetchedAt:r}}var Ro=async(t,e)=>{let r=t.apiVersion&&t.apiVersion!=="unknown"?t.apiVersion:"60.0",o=`${t.instanceUrl.replace(/\/+$/,"")}/services/data/v${r}/sobjects/${encodeURIComponent(e)}/describe`;try{let i=await fetch(o,{headers:{Authorization:`Bearer ${t.accessToken}`,Accept:"application/json"}});return i.ok?await i.json():(l.debug("org-cache: describe fetch non-ok",{sObject:e,status:i.status}),null)}catch(i){return l.debug("org-cache: describe fetch failed",{sObject:e,error:i instanceof Error?i.message:String(i)}),null}},Do=async t=>{let e=t.apiVersion&&t.apiVersion!=="unknown"?t.apiVersion:"60.0",n=`${t.instanceUrl.replace(/\/+$/,"")}/services/data/v${e}/sobjects`;try{let o=await fetch(n,{headers:{Authorization:`Bearer ${t.accessToken}`,Accept:"application/json"}});return o.ok?((await o.json()).sobjects??[]).filter(s=>s.queryable!==!1&&Te(s.name??"")).map(s=>s.name):(l.debug("org-cache: global describe non-ok",{status:o.status}),null)}catch(o){return l.debug("org-cache: global describe failed",{error:o instanceof Error?o.message:String(o)}),null}};function fn(t){return typeof t=="string"?t.trim():""}function Te(t){return typeof t=="string"&&t.length>0}function mn(t){return t.replace(/[^A-Za-z0-9._-]/g,"_")}function Ao(t){try{return y.unlinkSync(t),!0}catch{return!1}}function Oo(t){try{return y.readdirSync(t).filter(e=>e.endsWith(".json")&&e!==hn).length}catch{return 0}}function Io(t){try{y.rmSync(t,{recursive:!0,force:!0})}catch{}}function yn(t){return{name:"lsp.health",description:"Debug view of the LSP host: kill-switch mode, resolved workspace, per-language server state, circuit-breaker state, last cold-spawn timing, and the vendored Apex LSP version. Read-only \u2014 never spawns an LSP child.",inputSchema:{type:"object",properties:{},additionalProperties:!1},handler:()=>{let e=t.resolveWorkspace();return{status:"ready",killSwitch:t.killSwitch,workspace:{root:e.root,packageDirs:e.packageDirs,source:e.source},servers:t.lifecycle.snapshot(),apexLspVersion:t.apexVersion()??"unknown"}}}}var wn=f(require("node:readline")),U={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603},ne=class{constructor(e=process.stdin,r=process.stdout){this.input=e;this.output=r}input;output;listen(e){wn.createInterface({input:this.input,crlfDelay:1/0}).on("line",n=>{let o=n.trim();o&&this.dispatch(o,e)})}async dispatch(e,r){let n;try{n=JSON.parse(e)}catch{this.write({jsonrpc:"2.0",id:0,error:{code:U.ParseError,message:"Parse error"}});return}let o=n.id===void 0;try{let i=await r(n);o||this.write({jsonrpc:"2.0",id:n.id,result:i})}catch(i){o||this.write({jsonrpc:"2.0",id:n.id,error:{code:U.InternalError,message:i instanceof Error?i.message:String(i)}})}}write(e){this.output.write(JSON.stringify(e)+`
|
|
`)}};var qo="2024-11-05",re=class{constructor(e,r,n=V){this.serverName=e;this.serverVersion=r;this.telemetry=n}serverName;serverVersion;telemetry;tools=new Map;registerTool(e){this.tools.set(e.name,e)}start(e=new ne){e.listen(r=>this.handle(r)),l.debug("MCP server listening",{tools:[...this.tools.keys()]})}async handle(e){switch(e.method){case"initialize":return{protocolVersion:qo,capabilities:{tools:{}},serverInfo:{name:this.serverName,version:this.serverVersion}};case"notifications/initialized":return;case"tools/list":return{tools:[...this.tools.values()].map(r=>({name:r.name,description:r.description,inputSchema:r.inputSchema}))};case"tools/call":return this.callTool(e.params);default:throw bn(U.MethodNotFound,`Unknown method: ${e.method}`)}}async callTool(e){let r=e.name?this.tools.get(e.name):void 0;if(!r)throw bn(U.MethodNotFound,`Unknown tool: ${e.name}`);let n=e.arguments??{},o=await this.telemetry.time(r.name,async()=>r.handler(n));return{content:[{type:"text",text:JSON.stringify(o,null,2)}]}}};function bn(t,e){let r=new Error(e);return r.code=t,r}var kn=require("node:child_process"),oe=f(require("node:fs")),k=f(require("node:path"));function jo(t){let e=k.resolve(t);for(let r=0;r<64;r++){if(oe.existsSync(k.join(e,"sfdx-project.json")))return e;let n=k.dirname(e);if(n===e)break;e=n}}function Mo(t){try{let r=(0,kn.execFileSync)("git",["rev-parse","--show-toplevel"],{cwd:t,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();return r.length>0?r:void 0}catch{return}}function Wo(t){try{let e=oe.readFileSync(k.join(t,"sfdx-project.json"),"utf8"),n=(JSON.parse(e).packageDirectories??[]).map(o=>o?.path).filter(o=>typeof o=="string"&&o.length>0).map(o=>k.resolve(t,o));return n.length>0?No(n):[t]}catch{return[t]}}function No(t){return Array.from(new Set(t))}function Sn(t=process.cwd()){let e=jo(t);if(e)return{root:e,packageDirs:Wo(e),source:"sfdx-project"};let r=Mo(t);if(r)return{root:r,packageDirs:[r],source:"git-root"};let n=k.resolve(t);return{root:n,packageDirs:[n],source:"cwd"}}var Fo="salesforce-lsp",$o="0.1.0";function Uo(){try{return xn.readFileSync(gt(),"utf8").trim()}catch{return}}function Bo(){let t=Me(process.env.SFDX_LSP),e=new W,r,n=()=>(r||(r=Sn()),r),o=new z([xt,_t,qt],{killSwitch:t,telemetry:e}),i=new re(Fo,$o,e);i.registerTool(yn({killSwitch:t,lifecycle:o,resolveWorkspace:n,apexVersion:Uo})),i.registerTool(ze({lifecycle:o,resolveWorkspace:n})),i.registerTool(ct({lifecycle:o,resolveWorkspace:n})),i.registerTool(lt({lifecycle:o,resolveWorkspace:n})),i.registerTool(ut({lifecycle:o,resolveWorkspace:n})),i.registerTool(Jt({lifecycle:o,resolveWorkspace:n})),i.registerTool(Xt({resolveWorkspace:n})),i.registerTool(sn());let s=new te;i.registerTool(an({cache:s})),i.registerTool(dn({lifecycle:o,resolveWorkspace:n,cache:s})),i.registerTool(Wt({lifecycle:o,resolveWorkspace:n})),i.registerTool($t({lifecycle:o,resolveWorkspace:n})),i.registerTool(Ut({lifecycle:o,resolveWorkspace:n})),i.registerTool(Bt({lifecycle:o,resolveWorkspace:n})),i.registerTool(Vt({lifecycle:o,resolveWorkspace:n}));let a=!1,c=()=>{a||(a=!0,o.shutdownAll(),process.exit(0))};process.on("SIGTERM",c),process.on("SIGINT",c),process.stdin.on("end",c),process.stdin.on("close",c),i.start(),l.debug("sf-lsp-host started",{killSwitch:t,telemetry:e.enabled})}Bo();
|