@wispbit/local 1.0.92 → 1.0.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli-bundle.js +2 -2
- package/package.json +1 -1
package/cli-bundle.js
CHANGED
|
@@ -283,7 +283,7 @@ ${Re}`)}else u.push(Z)}let E="";if(o&&(o.mode==="check"?E=o.filePath?` ${j.dim(`
|
|
|
283
283
|
`;await h7.promises.appendFile(o,l)}let s=new Oc({level:3}),a=s.dim.italic("wispbit will automatically review all changes in this session"),c=await $1({chalkInstance:s,style:"gentle",inline:!0});return{systemMessage:c?`${a} ${c}`:a}}async handlePostToolUse(e){Ae.log(`[ClaudeHookHandler] PostToolUse (${e.tool_name}) for file ${e.tool_input.file_path}`);let n=new Na;if(!await n.getSession("claude",e.session_id)){Ae.log("[ClaudeHookHandler] Session not initialized, skipping PostToolUse");return}let i=e.tool_input.file_path,o=LC.isAbsolute(i)?LC.relative(e.cwd,i):i,s,a;e.tool_name==="Write"?(a="",s=e.tool_input.content||""):(a=e.tool_input.old_string||"",s=e.tool_input.new_string||""),await n.addFileChange(o,a,s),Ae.log(`[ClaudeHookHandler] Added change for ${o}`)}async handleStop(e){Ae.log(`[ClaudeHookHandler] Stop for session ${e.session_id}`);let n=new Na,r=await n.getSession("claude",e.session_id);if(!r){Ae.log("[ClaudeHookHandler] Session not initialized, skipping Stop");return}Ae.log(`[ClaudeHookHandler] Wispbit session ID: ${r.wispbitSessionId}`);let i=n.getLastCheckpointTimestamp();if((i?n.getFileChanges(i):n.getFileChanges()).length===0){Ae.log("[ClaudeHookHandler] No file changes since last checkpoint, skipping");return}let s=n.getFileChanges();Ae.log(`[ClaudeHookHandler] Found ${s.length} files changed in session`);for(let D of s)Ae.log(`
|
|
284
284
|
[ClaudeHookHandler] File: ${D.filename} (${D.status})`),Ae.log(`[ClaudeHookHandler] +${D.additions} -${D.deletions}`),Ae.log(`[ClaudeHookHandler] Diff:
|
|
285
285
|
${D.patch}`);let{results:a,rules:c}=await this.runPowerlint(e.cwd,s),u=a.flatMap(D=>D.matches.map(G=>({...G,ruleId:D.ruleId}))),l=n.getLastCheckpointMatches(),E=new Map;for(let D of u){let G=D.ruleId;E.has(G)||E.set(G,[]),E.get(G).push(D)}let d=new Map;for(let D of l)d.has(D.ruleId)||d.set(D.ruleId,[]),d.get(D.ruleId).push(D);let f=[];for(let[D,G]of E.entries()){let Y=d.get(D)||[],re=G.map(H=>({file:H.file.path,startLine:H.range.start.line,endLine:H.range.end.line,fingerprint:H.fingerprint})),W=Y.map(H=>({file:H.file.path,startLine:H.range.start.line,endLine:H.range.end.line,fingerprint:H.fingerprint})),q=Ih(re,W),Z=G.filter((H,oe)=>!q.has(oe));f.push(...Z)}let T=new Map;for(let D of f){let G=D.ruleId;T.has(G)||T.set(G,[]),T.get(G).push(D)}let p=Array.from(T.entries()).map(([D,G])=>({ruleId:D,matches:G})),S=new Map;for(let D of u){let G=D.ruleId;S.has(G)||S.set(G,[]),S.get(G).push(D)}let m=Array.from(S.entries()).map(([D,G])=>({ruleId:D,matches:G})),O=f.length,h=u.length;Ae.log(`[ClaudeHookHandler] New: ${O}, Total: ${h}`),await n.createCheckpoint(f);let C=await this.buildStopMessage(p,m,c,e.cwd,O,h,s.length);if(Ae.log(`[ClaudeHookHandler] Built system message: ${C?"yes":"no"}`),!!C)return{systemMessage:C}}async handleSessionEnd(e){Ae.log(`[ClaudeHookHandler] SessionEnd (${e.reason}) for session ${e.session_id}`);let n=new Na;if(!await n.getSession("claude",e.session_id)){Ae.log("[ClaudeHookHandler] Session not initialized, skipping SessionEnd");return}await n.endSession()}async runPowerlint(e,n){let r=Cr.initialize({repositoryUrl:void 0,workspaceRoot:e});if(!r)throw new Error("Not in a git repository");let i=await kh(),o=await eo.initialize(r,{apiKey:i||void 0});if("failed"in o)throw new Error(`Failed to initialize config: ${o.error}`);let s=o,a=new zr,c=new jo(s,r),u=await c.loadAllRules(),l=new La(s,r,a),E=await c.getDismissals([]),d=new Map;for(let p of E)d.has(p.ruleId)||d.set(p.ruleId,[]),d.get(p.ruleId).push(p.match);let f=await Pa.initialize(s,r,"session",a,void 0,void 0,{fileChanges:n});return{results:await l.execute(u,f,{dismissedMatchesByRule:d,emitErrors:!0}),rules:u}}async buildStopMessage(e,n,r,i,o,s,a){let c=e.filter(f=>f.matches.length>0),u=n.filter(f=>f.matches.length>0),l=new Oc({level:3}),E;if(s===o)if(o>0)E=l.red("wispbit found ")+l.red.bold(`${o} new`)+l.red(` ${o===1?"issue":"issues"}`);else if(a>0)E=l.dim.italic(`wispbit checked ${a} ${a===1?"file":"files"} and found 0 issues`);else return null;else o>0?E=l.red("wispbit found ")+l.red.bold(`${o} new`)+l.red(` ${o===1?"issue":"issues"}`)+l.dim(` (${s} total)`):E=l.dim.italic(`wispbit found ${s} total ${s===1?"issue":"issues"} from ${a} ${a===1?"file edit":"file edits"} this session`);let d=[];if(c.length>0){let f=new Set;for(let p of u)for(let S of p.matches)f.add(S.file.path);let T=await Fh(c,r,i,l,{maxMatchesPerRule:1,maxDiffLines:10});d.push(T),d.push("",E),d.push(l.dim("Run ")+l.cyan("!wispbit")+l.dim(" to view, ")+l.cyan("!wispbit --fix")+l.dim(" to fix, ")+l.cyan("!wispbit --dismiss")+l.dim(" to dismiss (add ")+l.cyan("RULE-123")+l.dim(" for specific rules)"))}else u.length>0?d.push(E+l.dim.italic(". Run ")+l.cyan("!wispbit")+l.dim.italic(" to view and fix issues.")):d.push(E);return d.join(`
|
|
286
|
-
`)}};function m7(t){switch(t){case"claude":return new DC;default:throw new Error(`Unknown hook provider: ${t}`)}}import*as zc from"fs/promises";import*as A7 from"os";import*as Hh from"path";var yC=class{getStorageDir(){return Hh.join(A7.homedir(),".wispbit","hooks")}getStoragePath(e){return Hh.join(this.getStorageDir(),`${e}.json`)}async load(e){let n=this.getStoragePath(e);try{let r=await zc.readFile(n,"utf-8");return JSON.parse(r)}catch{return null}}async save(e,n){let r=this.getStoragePath(e);await zc.mkdir(Hh.dirname(r),{recursive:!0}),await zc.writeFile(r,JSON.stringify(n,null,2))}async clear(e){let n=this.getStoragePath(e);try{await zc.unlink(n)}catch{}}};async function g7(t,e){let[n,r]=t.split(".");if(!n||!r)throw new Error(`Invalid providerEvent format: ${t}. Expected "provider.event"`);let i=m7(n),o=new yC,s=i.eventSchemas[r];if(!s)throw new Error(`Unknown event: ${r} for provider: ${n}`);let a=s.parse(e),c=i.getConversationId(a);i._setContext(o,c);let u=await i.handleEvent(r,a);return i._clearContext(),u??{}}import{promises as Zy}from"fs";import{join as ME,relative as cKe}from"path";import{fileURLToPath as xo,pathToFileURL as rPt}from"url";var mr=ue($re(),1);function CE(){return!0}async function ky(){return globalThis.__POWERLINT_IS_BUN_EXECUTABLE__===!0?await Promise.resolve().then(()=>(rKe(),nKe)):await Promise.resolve().then(()=>(Gy(),qWe))}async function IE(t,e){if(!CE())return;(await ky()).captureException(t,e)}async function EK(t){if(!CE())return;(await ky()).setUser(t)}async function jg(t,e){if(!CE())return;(await ky()).setContext(t,e)}async function iKe(t=2e3){if(!CE())return;await(await ky()).close(t)}ud();var Hy=class t{constructor(e,n,r,i){this._uri=e,this._languageId=n,this._version=r,this._content=i,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let n=this.offsetAt(e.start),r=this.offsetAt(e.end);return this._content.substring(n,r)}return this._content}update(e,n){for(let r of e)if(t.isIncremental(r)){let i=aKe(r.range),o=this.offsetAt(i.start),s=this.offsetAt(i.end);this._content=this._content.substring(0,o)+r.text+this._content.substring(s,this._content.length);let a=Math.max(i.start.line,0),c=Math.max(i.end.line,0),u=this._lineOffsets,l=oKe(r.text,!1,o);if(c-a===l.length)for(let d=0,f=l.length;d<f;d++)u[d+a+1]=l[d];else l.length<1e4?u.splice(a+1,c-a,...l):this._lineOffsets=u=u.slice(0,a+1).concat(l,u.slice(c+1));let E=r.text.length-(s-o);if(E!==0)for(let d=a+1+l.length,f=u.length;d<f;d++)u[d]=u[d]+E}else if(t.isFull(r))this._content=r.text,this._lineOffsets=void 0;else throw new Error("Unknown change event received");this._version=n}getLineOffsets(){return this._lineOffsets===void 0&&(this._lineOffsets=oKe(this._content,!0)),this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let n=this.getLineOffsets(),r=0,i=n.length;if(i===0)return{line:0,character:e};for(;r<i;){let s=Math.floor((r+i)/2);n[s]>e?i=s:r=s+1}let o=r-1;return e=this.ensureBeforeEOL(e,n[o]),{line:o,character:e-n[o]}}offsetAt(e){let n=this.getLineOffsets();if(e.line>=n.length)return this._content.length;if(e.line<0)return 0;let r=n[e.line];if(e.character<=0)return r;let i=e.line+1<n.length?n[e.line+1]:this._content.length,o=Math.min(r+e.character,i);return this.ensureBeforeEOL(o,r)}ensureBeforeEOL(e,n){for(;e>n&&sKe(this._content.charCodeAt(e-1));)e--;return e}get lineCount(){return this.getLineOffsets().length}static isIncremental(e){let n=e;return n!=null&&typeof n.text=="string"&&n.range!==void 0&&(n.rangeLength===void 0||typeof n.rangeLength=="number")}static isFull(e){let n=e;return n!=null&&typeof n.text=="string"&&n.range===void 0&&n.rangeLength===void 0}},Wg;(function(t){function e(i,o,s,a){return new Hy(i,o,s,a)}t.create=e;function n(i,o,s){if(i instanceof Hy)return i.update(o,s),i;throw new Error("TextDocument.update: document must be created by TextDocument.create")}t.update=n;function r(i,o){let s=i.getText(),a=dK(o.map(JMt),(l,E)=>{let d=l.range.start.line-E.range.start.line;return d===0?l.range.start.character-E.range.start.character:d}),c=0,u=[];for(let l of a){let E=i.offsetAt(l.range.start);if(E<c)throw new Error("Overlapping edit");E>c&&u.push(s.substring(c,E)),l.newText.length&&u.push(l.newText),c=i.offsetAt(l.range.end)}return u.push(s.substr(c)),u.join("")}t.applyEdits=r})(Wg||(Wg={}));function dK(t,e){if(t.length<=1)return t;let n=t.length/2|0,r=t.slice(0,n),i=t.slice(n);dK(r,e),dK(i,e);let o=0,s=0,a=0;for(;o<r.length&&s<i.length;)e(r[o],i[s])<=0?t[a++]=r[o++]:t[a++]=i[s++];for(;o<r.length;)t[a++]=r[o++];for(;s<i.length;)t[a++]=i[s++];return t}function oKe(t,e,n=0){let r=e?[n]:[];for(let i=0;i<t.length;i++){let o=t.charCodeAt(i);sKe(o)&&(o===13&&i+1<t.length&&t.charCodeAt(i+1)===10&&i++,r.push(n+i+1))}return r}function sKe(t){return t===13||t===10}function aKe(t){let e=t.start,n=t.end;return e.line>n.line||e.line===n.line&&e.character>n.character?{start:n,end:e}:t}function JMt(t){let e=aKe(t.range);return e!==t.range?{newText:t.newText,range:e}:t}function oi(t){let e=decodeURIComponent(t);return e.startsWith("file:///")&&(e=e.replace(/\\/g,"/")),e=e.replace(/^file:\/\/\/([a-z]):/,(n,r)=>`file:///${r.toUpperCase()}:`),e}var Yy=class{syncedDocuments=new Map;diagnosticsByFileAndRule=new Map;dismissalsByFile=new Map;fixesByFile=new Map;listen(e,n){e.onDidOpenTextDocument(r=>{let i=r.textDocument,o=oi(i.uri),s=Wg.create(o,i.languageId,i.version,i.text);this.syncedDocuments.set(o,s),n.onDidOpen?.(o,s)}),e.onDidChangeTextDocument(r=>{let i=r.textDocument,o=oi(i.uri),s=r.contentChanges;if(s.length===0)return;let a=i.version;if(a==null)return;let c=this.syncedDocuments.get(o);c&&(c=Wg.update(c,s,a),this.syncedDocuments.set(o,c),n.onDidChangeContent?.(o,c,s))}),e.onDidCloseTextDocument(r=>{let i=oi(r.textDocument.uri);this.syncedDocuments.delete(i),n.onDidClose?.(i)}),e.onDidSaveTextDocument(r=>{let i=oi(r.textDocument.uri),o=this.syncedDocuments.get(i);o&&n.onDidSave?.(i,o)})}getDocument(e){let n=oi(e);return this.syncedDocuments.get(n)}getAllDocumentUris(){return Array.from(this.syncedDocuments.values()).map(e=>e.uri)}getAllDiagnosticUris(){return Array.from(this.diagnosticsByFileAndRule.keys())}setDiagnosticsForRule(e,n,r){let i=oi(e);this.diagnosticsByFileAndRule.has(i)||this.diagnosticsByFileAndRule.set(i,new Map),this.diagnosticsByFileAndRule.get(i).set(n,r)}getDiagnosticsForRule(e,n){let r=oi(e),i=this.diagnosticsByFileAndRule.get(r);return i?i.get(n)||[]:[]}getDiagnostics(e){let n=oi(e),r=this.diagnosticsByFileAndRule.get(n);if(!r)return[];let i=[];for(let[o,s]of r.entries())i.push(...s);return i}clearDiagnostics(e){let n=oi(e);this.diagnosticsByFileAndRule.delete(n)}setDismissals(e,n){this.dismissalsByFile.set(e,n)}getDismissals(e){return this.dismissalsByFile.get(e)||[]}hasDismissals(e){return this.dismissalsByFile.has(e)}clearDismissals(e){this.dismissalsByFile.delete(e)}setFixes(e,n){this.fixesByFile.set(e,n)}getFixes(e){return this.fixesByFile.get(e)||[]}hasFixes(e){return this.fixesByFile.has(e)}clearFixes(e){this.fixesByFile.delete(e)}};import{sep as nPt}from"path";var $y=class{runtimeManager;config;environment;apiClient;previousResults=new Map;constructor(e,n,r){this.runtimeManager=e,this.config=n,this.environment=r,this.apiClient=new Vl({baseUrl:n.getBaseUrl(),apiKey:n.getApiKey()})}clearCache(){this.previousResults.clear()}async execute(e,n,r){let i=this.environment.getWorkspaceRoot(),o=[],s=n?e.filePaths.filter(E=>E===n):e.filePaths,a=await this.runtimeManager.getDuplicates(i,n),c=await a.loadFileContents(i),u=a.clusterBySharedFiles();Ae.log(`[DuplicateManager] Found ${u.length} clusters`);let l=new Set;for(let E of u){let d=Array.from(E.files),f=new Map,T=!0,p=new Map;for(let h of E.groups)for(let C of h.fragments)p.set(C.file,C.file_sha);for(let h of d){let C=this.previousResults.get(h);if(C&&C.length>0){let D=p.get(h);C.some(Y=>Y.file.sha!==D)?(this.previousResults.delete(h),T=!1):f.set(h,C)}else T=!1}if(T&&f.size===d.length){for(let[h,C]of f.entries())r(h,C,C.length,!1),o.push(...C),l.add(h);continue}let S=[];for(let h of E.groups){let C=await this.createMatchForGroup(h,c,i,a,e);if(!C)continue;let D=e.filterMatches([C],[]);D.length!==0&&S.push({match:D[0],group:h})}if(S.length===0)continue;let m=await this.processClusterMatches(S,d,i,r,c,a),O=new Map;for(let h of m){let C=h.file.path;O.has(C)||O.set(C,[]),O.get(C).push(h)}for(let[h,C]of O.entries())this.previousResults.set(h,C),r(h,C,C.length,!1),o.push(...C),l.add(h)}for(let E of s)!l.has(E)&&this.previousResults.has(E)&&(r(E,[],0,!1),this.previousResults.delete(E));return o}async createMatchForGroup(e,n,r,i,o){if(e.fragments.length===0)return null;let s=[...e.fragments].sort((E,d)=>E.start_line-d.start_line),a=s[0];for(let E of s){let d={file:{path:E.file,sha:E.file_sha},text:"",range:{start:{line:E.start_line+1,column:E.start_column+1,index:E.start_index},end:{line:E.start_line+1,column:9999,index:E.start_index}},language:this.detectLanguage(E.file),fingerprint:e.hash,description:"",evidence:[]};if(o.filterMatches([d],[]).length>0){a=E;break}}let c=await i.extractFragmentSnippet(a,r,n),u=await Promise.all(e.fragments.filter(E=>!(E.file===a.file&&E.start_line===a.start_line)).map(async E=>{let d=await i.extractFragmentSnippet(E,r,n);return{file:{path:E.file,sha:E.file_sha},text:d,range:{start:{line:E.start_line+1,column:E.start_column+1,index:E.start_index},end:{line:E.end_line+1,column:E.end_column+1,index:E.end_index}},language:this.detectLanguage(E.file),description:"Duplicate location"}}));return{file:{path:a.file,sha:a.file_sha},text:c,range:{start:{line:a.start_line+1,column:a.start_column+1,index:a.start_index},end:{line:a.start_line+1,column:9999,index:a.start_index+c.split(`
|
|
286
|
+
`)}};function m7(t){switch(t){case"claude":return new DC;default:throw new Error(`Unknown hook provider: ${t}`)}}import*as zc from"fs/promises";import*as A7 from"os";import*as Hh from"path";var yC=class{getStorageDir(){return Hh.join(A7.homedir(),".wispbit","hooks")}getStoragePath(e){return Hh.join(this.getStorageDir(),`${e}.json`)}async load(e){let n=this.getStoragePath(e);try{let r=await zc.readFile(n,"utf-8");return JSON.parse(r)}catch{return null}}async save(e,n){let r=this.getStoragePath(e);await zc.mkdir(Hh.dirname(r),{recursive:!0}),await zc.writeFile(r,JSON.stringify(n,null,2))}async clear(e){let n=this.getStoragePath(e);try{await zc.unlink(n)}catch{}}};async function g7(t,e){let[n,r]=t.split(".");if(!n||!r)throw new Error(`Invalid providerEvent format: ${t}. Expected "provider.event"`);let i=m7(n),o=new yC,s=i.eventSchemas[r];if(!s)throw new Error(`Unknown event: ${r} for provider: ${n}`);let a=s.parse(e),c=i.getConversationId(a);i._setContext(o,c);let u=await i.handleEvent(r,a);return i._clearContext(),u??{}}import{promises as Zy}from"fs";import{join as ME,relative as cKe}from"path";import{fileURLToPath as xo,pathToFileURL as rPt}from"url";var mr=ue($re(),1);function CE(){return!0}async function ky(){return globalThis.__POWERLINT_IS_BUN_EXECUTABLE__===!0?await Promise.resolve().then(()=>(rKe(),nKe)):await Promise.resolve().then(()=>(Gy(),qWe))}async function IE(t,e){if(!CE())return;(await ky()).captureException(t,e)}async function EK(t){if(!CE())return;(await ky()).setUser(t)}async function jg(t,e){if(!CE())return;(await ky()).setContext(t,e)}async function iKe(t=2e3){if(!CE())return;await(await ky()).close(t)}ud();var Hy=class t{constructor(e,n,r,i){this._uri=e,this._languageId=n,this._version=r,this._content=i,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let n=this.offsetAt(e.start),r=this.offsetAt(e.end);return this._content.substring(n,r)}return this._content}update(e,n){for(let r of e)if(t.isIncremental(r)){let i=aKe(r.range),o=this.offsetAt(i.start),s=this.offsetAt(i.end);this._content=this._content.substring(0,o)+r.text+this._content.substring(s,this._content.length);let a=Math.max(i.start.line,0),c=Math.max(i.end.line,0),u=this._lineOffsets,l=oKe(r.text,!1,o);if(c-a===l.length)for(let d=0,f=l.length;d<f;d++)u[d+a+1]=l[d];else l.length<1e4?u.splice(a+1,c-a,...l):this._lineOffsets=u=u.slice(0,a+1).concat(l,u.slice(c+1));let E=r.text.length-(s-o);if(E!==0)for(let d=a+1+l.length,f=u.length;d<f;d++)u[d]=u[d]+E}else if(t.isFull(r))this._content=r.text,this._lineOffsets=void 0;else throw new Error("Unknown change event received");this._version=n}getLineOffsets(){return this._lineOffsets===void 0&&(this._lineOffsets=oKe(this._content,!0)),this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let n=this.getLineOffsets(),r=0,i=n.length;if(i===0)return{line:0,character:e};for(;r<i;){let s=Math.floor((r+i)/2);n[s]>e?i=s:r=s+1}let o=r-1;return e=this.ensureBeforeEOL(e,n[o]),{line:o,character:e-n[o]}}offsetAt(e){let n=this.getLineOffsets();if(e.line>=n.length)return this._content.length;if(e.line<0)return 0;let r=n[e.line];if(e.character<=0)return r;let i=e.line+1<n.length?n[e.line+1]:this._content.length,o=Math.min(r+e.character,i);return this.ensureBeforeEOL(o,r)}ensureBeforeEOL(e,n){for(;e>n&&sKe(this._content.charCodeAt(e-1));)e--;return e}get lineCount(){return this.getLineOffsets().length}static isIncremental(e){let n=e;return n!=null&&typeof n.text=="string"&&n.range!==void 0&&(n.rangeLength===void 0||typeof n.rangeLength=="number")}static isFull(e){let n=e;return n!=null&&typeof n.text=="string"&&n.range===void 0&&n.rangeLength===void 0}},Wg;(function(t){function e(i,o,s,a){return new Hy(i,o,s,a)}t.create=e;function n(i,o,s){if(i instanceof Hy)return i.update(o,s),i;throw new Error("TextDocument.update: document must be created by TextDocument.create")}t.update=n;function r(i,o){let s=i.getText(),a=dK(o.map(JMt),(l,E)=>{let d=l.range.start.line-E.range.start.line;return d===0?l.range.start.character-E.range.start.character:d}),c=0,u=[];for(let l of a){let E=i.offsetAt(l.range.start);if(E<c)throw new Error("Overlapping edit");E>c&&u.push(s.substring(c,E)),l.newText.length&&u.push(l.newText),c=i.offsetAt(l.range.end)}return u.push(s.substr(c)),u.join("")}t.applyEdits=r})(Wg||(Wg={}));function dK(t,e){if(t.length<=1)return t;let n=t.length/2|0,r=t.slice(0,n),i=t.slice(n);dK(r,e),dK(i,e);let o=0,s=0,a=0;for(;o<r.length&&s<i.length;)e(r[o],i[s])<=0?t[a++]=r[o++]:t[a++]=i[s++];for(;o<r.length;)t[a++]=r[o++];for(;s<i.length;)t[a++]=i[s++];return t}function oKe(t,e,n=0){let r=e?[n]:[];for(let i=0;i<t.length;i++){let o=t.charCodeAt(i);sKe(o)&&(o===13&&i+1<t.length&&t.charCodeAt(i+1)===10&&i++,r.push(n+i+1))}return r}function sKe(t){return t===13||t===10}function aKe(t){let e=t.start,n=t.end;return e.line>n.line||e.line===n.line&&e.character>n.character?{start:n,end:e}:t}function JMt(t){let e=aKe(t.range);return e!==t.range?{newText:t.newText,range:e}:t}function oi(t){let e=decodeURIComponent(t);return e.startsWith("file:///")&&(e=e.replace(/\\/g,"/")),e=e.replace(/^file:\/\/\/([a-z]):/,(n,r)=>`file:///${r.toUpperCase()}:`),e}var Yy=class{syncedDocuments=new Map;everOpenedDocuments=new Set;diagnosticsByFileAndRule=new Map;dismissalsByFile=new Map;fixesByFile=new Map;listen(e,n){e.onDidOpenTextDocument(r=>{let i=r.textDocument,o=oi(i.uri),s=Wg.create(o,i.languageId,i.version,i.text);this.syncedDocuments.set(o,s);let a=!this.everOpenedDocuments.has(o);a&&this.everOpenedDocuments.add(o),n.onDidOpen?.(o,s,a)}),e.onDidChangeTextDocument(r=>{let i=r.textDocument,o=oi(i.uri),s=r.contentChanges;if(s.length===0)return;let a=i.version;if(a==null)return;let c=this.syncedDocuments.get(o);c&&(c=Wg.update(c,s,a),this.syncedDocuments.set(o,c),n.onDidChangeContent?.(o,c,s))}),e.onDidCloseTextDocument(r=>{let i=oi(r.textDocument.uri);this.syncedDocuments.delete(i),n.onDidClose?.(i)}),e.onDidSaveTextDocument(r=>{let i=oi(r.textDocument.uri),o=this.syncedDocuments.get(i);o&&n.onDidSave?.(i,o)})}getDocument(e){let n=oi(e);return this.syncedDocuments.get(n)}getAllDocumentUris(){return Array.from(this.syncedDocuments.values()).map(e=>e.uri)}getAllDiagnosticUris(){return Array.from(this.diagnosticsByFileAndRule.keys())}setDiagnosticsForRule(e,n,r){let i=oi(e);this.diagnosticsByFileAndRule.has(i)||this.diagnosticsByFileAndRule.set(i,new Map),this.diagnosticsByFileAndRule.get(i).set(n,r)}getDiagnosticsForRule(e,n){let r=oi(e),i=this.diagnosticsByFileAndRule.get(r);return i?i.get(n)||[]:[]}getDiagnostics(e){let n=oi(e),r=this.diagnosticsByFileAndRule.get(n);if(!r)return[];let i=[];for(let[o,s]of r.entries())i.push(...s);return i}clearDiagnostics(e){let n=oi(e);this.diagnosticsByFileAndRule.delete(n)}setDismissals(e,n){this.dismissalsByFile.set(e,n)}getDismissals(e){return this.dismissalsByFile.get(e)||[]}hasDismissals(e){return this.dismissalsByFile.has(e)}clearDismissals(e){this.dismissalsByFile.delete(e)}setFixes(e,n){this.fixesByFile.set(e,n)}getFixes(e){return this.fixesByFile.get(e)||[]}hasFixes(e){return this.fixesByFile.has(e)}clearFixes(e){this.fixesByFile.delete(e)}};import{sep as nPt}from"path";var $y=class{runtimeManager;config;environment;apiClient;previousResults=new Map;constructor(e,n,r){this.runtimeManager=e,this.config=n,this.environment=r,this.apiClient=new Vl({baseUrl:n.getBaseUrl(),apiKey:n.getApiKey()})}clearCache(){this.previousResults.clear()}async execute(e,n,r){let i=this.environment.getWorkspaceRoot(),o=[],s=n?e.filePaths.filter(E=>E===n):e.filePaths,a=await this.runtimeManager.getDuplicates(i,n),c=await a.loadFileContents(i),u=a.clusterBySharedFiles();Ae.log(`[DuplicateManager] Found ${u.length} clusters`);let l=new Set;for(let E of u){let d=Array.from(E.files),f=new Map,T=!0,p=new Map;for(let h of E.groups)for(let C of h.fragments)p.set(C.file,C.file_sha);for(let h of d){let C=this.previousResults.get(h);if(C&&C.length>0){let D=p.get(h);C.some(Y=>Y.file.sha!==D)?(this.previousResults.delete(h),T=!1):f.set(h,C)}else T=!1}if(T&&f.size===d.length){for(let[h,C]of f.entries())r(h,C,C.length,!1),o.push(...C),l.add(h);continue}let S=[];for(let h of E.groups){let C=await this.createMatchForGroup(h,c,i,a,e);if(!C)continue;let D=e.filterMatches([C],[]);D.length!==0&&S.push({match:D[0],group:h})}if(S.length===0)continue;let m=await this.processClusterMatches(S,d,i,r,c,a),O=new Map;for(let h of m){let C=h.file.path;O.has(C)||O.set(C,[]),O.get(C).push(h)}for(let[h,C]of O.entries())this.previousResults.set(h,C),r(h,C,C.length,!1),o.push(...C),l.add(h)}for(let E of s)!l.has(E)&&this.previousResults.has(E)&&(r(E,[],0,!1),this.previousResults.delete(E));return o}async createMatchForGroup(e,n,r,i,o){if(e.fragments.length===0)return null;let s=[...e.fragments].sort((E,d)=>E.start_line-d.start_line),a=s[0];for(let E of s){let d={file:{path:E.file,sha:E.file_sha},text:"",range:{start:{line:E.start_line+1,column:E.start_column+1,index:E.start_index},end:{line:E.start_line+1,column:9999,index:E.start_index}},language:this.detectLanguage(E.file),fingerprint:e.hash,description:"",evidence:[]};if(o.filterMatches([d],[]).length>0){a=E;break}}let c=await i.extractFragmentSnippet(a,r,n),u=await Promise.all(e.fragments.filter(E=>!(E.file===a.file&&E.start_line===a.start_line)).map(async E=>{let d=await i.extractFragmentSnippet(E,r,n);return{file:{path:E.file,sha:E.file_sha},text:d,range:{start:{line:E.start_line+1,column:E.start_column+1,index:E.start_index},end:{line:E.end_line+1,column:E.end_column+1,index:E.end_index}},language:this.detectLanguage(E.file),description:"Duplicate location"}}));return{file:{path:a.file,sha:a.file_sha},text:c,range:{start:{line:a.start_line+1,column:a.start_column+1,index:a.start_index},end:{line:a.start_line+1,column:9999,index:a.start_index+c.split(`
|
|
287
287
|
`)[0].length}},language:this.detectLanguage(a.file),fingerprint:e.hash,description:`Duplicate code found in ${e.fragments.length} locations`,evidence:u}}async processClusterMatches(e,n,r,i,o,s){let a=e.map(T=>T.match),c=[];for(let T of n){let p=this.previousResults.get(T);p&&c.push(...p)}let{remappedMatches:u,unmappedMatches:l}=aQ(a,c),E=u.length+l.length;if(u.length>0){let T=new Map;for(let p of u){let S=p.file.path;T.has(S)||T.set(S,[]),T.get(S).push(p)}for(let[p,S]of T.entries())i(p,S,E,!0);Ae.log(`[DuplicateManager] Emitted ${u.length} remapped duplicates, processing ${l.length} through LLM`)}else l.length>0&&Ae.log(`[DuplicateManager] No remapped duplicates, processing ${l.length} through LLM`);if(l.length===0)return u;let d=e.filter(T=>l.some(p=>p.fingerprint===T.match.fingerprint&&p.file.path===T.match.file.path));Ae.log(`[DuplicateManager] Processing ${d.length} duplicates through LLM validation and fix generation`);let f=await this.processMatchesWithLLM(d,r,o,s);return[...u,...f]}async processMatchesWithLLM(e,n,r,i){let o=e.map(T=>T.match),s=this.config.getContext();if(!s)throw new Error("Context is required for duplicate processing. Please ensure the configuration is initialized with repository information.");Ae.log(`[DuplicateManager] Querying validation cache for ${o.length} duplicates`);let a=await this.apiClient.queryLlmCache({matches:o,type:"duplicate_validate",repository_id:s.repository_id});if("error"in a)return Ae.log(`[DuplicateManager] ERROR: Cache query failed: ${a.error}`),await this.processMatchesWithoutCache(e,n,s,r,i);let c=new Map,u=[];for(let T of a.results){let p=`${T.match.fingerprint}:${T.match.file.path}`;if(T.hit&&T.data)c.set(p,T.data[0]);else{let S=o.find(m=>m.fingerprint===T.match.fingerprint&&m.file.path===T.match.file.path);S&&u.push(S)}}Ae.log(`[DuplicateManager] Validation cache: ${c.size} hits, ${u.length} misses`);let l=[];for(let T of o){let p=`${T.fingerprint}:${T.file.path}`,S=c.get(p);S&&(S.isValid?(l.push(T),Ae.log(`[DuplicateManager] Cached validation for ${T.file.path}:${T.range.start.line}: VALID - ${S.reason}`)):Ae.log(`[DuplicateManager] Cached validation for ${T.file.path}:${T.range.start.line}: INVALID - ${S.reason}`))}for(let T=0;T<u.length;T++){let p=u[T];Ae.log(`[DuplicateManager] [${T+1}/${u.length}] Validating duplicate in ${p.file.path}:${p.range.start.line}`);let S=await this.apiClient.validateDuplicates({matches:[p],language:p.language,repository_id:s.repository_id});if("error"in S){let m=p.text?.substring(0,80).replace(/\n/g," ")||"";Ae.log(`[DuplicateManager] ERROR: Validation failed for ${p.file.path}:${p.range.start.line} "${m}...": ${S.error}`);continue}Ae.log(`[DuplicateManager] [${T+1}/${u.length}] Validation result: ${S.isValid?"VALID":"INVALID"} - ${S.reason}`),S.isValid&&l.push(p)}if(l.length===0)return[];Ae.log(`[DuplicateManager] Querying fix generation cache for ${l.length} duplicates`);let E=await this.apiClient.queryLlmCache({matches:l,type:"duplicate_generate",repository_id:s.repository_id});if("error"in E)return Ae.log(`[DuplicateManager] ERROR: Fix cache query failed: ${E.error}`),await this.generateFixesForMatches(l,n,new Map);let d=new Map,f=[];for(let T of E.results){let p=`${T.match.fingerprint}:${T.match.file.path}`;if(T.hit&&T.data)d.set(p,T.data);else{let S=l.find(m=>m.fingerprint===T.match.fingerprint&&m.file.path===T.match.file.path);S&&f.push(S)}}return Ae.log(`[DuplicateManager] Fix generation cache: ${d.size} hits, ${f.length} misses`),await this.generateFixesForMatches(l,n,d)}async generateFixesForMatches(e,n,r){let i=[];for(let o=0;o<e.length;o++){let s=e[o],a=`${s.fingerprint}:${s.file.path}`,c=r.get(a);if(c){Ae.log(`[DuplicateManager] [${o+1}/${e.length}] Using cached fix for ${s.file.path}:${s.range.start.line}`);let u=await this.replayCachedConversation(c,[s],n);if(u){let l={...s,edits:u.edits,description:u.description};i.push(l),Ae.log(`[DuplicateManager] [${o+1}/${e.length}] Cached fix applied: ${u.description}`)}}else{Ae.log(`[DuplicateManager] [${o+1}/${e.length}] Generating fix for ${s.file.path}:${s.range.start.line}`);let u=await this.generateFixesWithToolLoop([s],n);if(u){let l={...s,edits:u.edits,description:u.description};i.push(l),Ae.log(`[DuplicateManager] [${o+1}/${e.length}] Fix generated successfully: ${u.description}`)}else{let l=s.text?.substring(0,80).replace(/\n/g," ")||"";Ae.log(`[DuplicateManager] ERROR: Fix generation failed for ${s.file.path}:${s.range.start.line} "${l}..."`)}}}return i}async processMatchesWithoutCache(e,n,r,i,o){let s=e.map(c=>c.match),a=[];Ae.log(`[DuplicateManager] Processing ${s.length} duplicates without cache`);for(let c=0;c<e.length;c++){let{match:u}=e[c],l=await this.apiClient.validateDuplicates({matches:[u],language:u.language,repository_id:r.repository_id});"error"in l||l.isValid&&a.push(u)}return await this.generateFixesForMatches(a,n,new Map)}async replayCachedConversation(e,n,r){let i=[];return Ae.log(`[DuplicateManager] Resuming from cached conversation with ${e.length} messages`),await this.continueFixGenerationWithLLM(n,r,e,i)}async continueFixGenerationWithLLM(e,n,r,i){let s=this.config.getContext();if(!s)throw new Error("Context is required for fix generation");for(let a=0;a<20;a++){let c=await this.executeToolCalls(r,n,e[0].file.path,i);if(c.length>0){let f=this.extractReportFixResult(c);if(f)return f;r.push(...c)}Ae.log(`[DuplicateManager] LLM call (resume) - Input: ${r.length} previous messages, Match: ${e[0].file.path}:${e[0].range.start.line}`);let u=await this.apiClient.generateDuplicateFixes({matches:e,language:e[0].language,messages:r,repository_id:s.repository_id,visited_files:i});if("error"in u){let f=e[0]?.text?.substring(0,80).replace(/\n/g," ")||"unknown";Ae.log(`[DuplicateManager] ERROR: generateDuplicateFixes API call failed (resume) for ${e[0]?.file?.path}:${e[0]?.range?.start?.line} "${f}...": ${u.error}`);let T=r.slice(-3);return Ae.log(`[DuplicateManager] Last ${T.length} messages before failure:
|
|
288
288
|
${JSON.stringify(T,null,2)}`),null}let l=u.messages,E=await this.executeToolCalls(l,n,e[0].file.path,i);r.push(...l);let d=this.checkForSuccessfulReportFix(l);if(d)return d;if(E.length>0){let f=this.extractReportFixResult(E);if(f)return f;r.push(...E)}}return Ae.log("[DuplicateManager] Max iterations (20) reached without valid fix"),null}extractReportFixFromMessages(e){for(let n of e)if(n.role==="tool"&&n.content){for(let r of n.content)if(r.toolName==="report_fix"){let i=JSON.parse(r.output.value);if(i.success&&i.result)return i.result}}return null}extractReportFixResult(e){return this.extractReportFixFromMessages(e)}async generateFixesWithToolLoop(e,n){let r=[],o=this.config.getContext(),s=[];if(!o)throw new Error("Context is required for fix generation. Please ensure the configuration is initialized with repository information.");for(let a=0;a<20;a++){Ae.log(`[DuplicateManager] LLM call - Input: ${r.length} previous messages, Match: ${e[0].file.path}:${e[0].range.start.line}`);let c=await this.apiClient.generateDuplicateFixes({matches:e,language:e[0].language,messages:r,repository_id:o.repository_id,visited_files:s});if("error"in c){let f=e[0]?.text?.substring(0,80).replace(/\n/g," ")||"unknown";Ae.log(`[DuplicateManager] ERROR: generateDuplicateFixes API call failed for ${e[0]?.file?.path}:${e[0]?.range?.start?.line} "${f}...": ${c.error}`);let T=r.slice(-3);return Ae.log(`[DuplicateManager] Last ${T.length} messages before failure:
|
|
289
289
|
${JSON.stringify(T,null,2)}`),null}let u=c.messages,l=u.find(f=>f.role==="assistant");if(l){let f=Array.isArray(l.content)?l.content.filter(T=>T.type==="tool-call"):[];if(f.length>0){let T=f.map(p=>p.toolName).join(", ");Ae.log(`[DuplicateManager] LLM response - Tool calls: ${T}`)}else if(l.content){let T=typeof l.content=="string"?l.content.substring(0,100):JSON.stringify(l.content).substring(0,100);Ae.log(`[DuplicateManager] LLM response - Content: ${T}...`)}}let E=await this.executeToolCalls(u,n,e[0].file.path,s);r.push(...u);let d=this.checkForSuccessfulReportFix(u);if(d)return d;if(E.length>0){for(let f of E)if(f.role==="tool"&&f.content)for(let T of f.content){let p=typeof T.output?.value=="string"?T.output.value.substring(0,150):JSON.stringify(T.output?.value||"").substring(0,150);if(Ae.log(`[DuplicateManager] Tool result (${T.toolName}): ${p}${p.length>=150?"...":""}`),T.toolName==="report_fix"){let S=JSON.parse(T.output.value);if(S.success&&S.result)return S.result}}r.push(...E)}}return Ae.log("[DuplicateManager] Max iterations (20) reached without valid fix"),null}checkForSuccessfulReportFix(e){return this.extractReportFixFromMessages(e)}async validateFix(e,n,r){let i=await Nc(e,n,r).catch(o=>({error:o.message}));return!i||"error"in i?{valid:!1,error:i?.error||"Failed to compute fix"}:{valid:!0}}async executeToolCalls(e,n,r,i){let o=[];for(let s=0;s<e.length;s++){let a=e[s];if(a.role==="assistant"&&Array.isArray(a.content)){let c=a.content.filter(d=>d.type==="tool-call");if(c.length===0)continue;let u=e[s+1];if(u&&u.role==="tool")continue;let E=await Promise.all(c.map(async d=>{let f=await this.executeTool(d.toolName,d.input,n,r,i);return{type:"tool-result",toolCallId:d.toolCallId,toolName:d.toolName,output:{type:"text",value:typeof f=="string"?f:JSON.stringify(f)}}}));o.push({role:"tool",content:E})}}return o}async executeTool(e,n,r,i,o){let s=[];switch(e){case"read":{let a=await aC(n,r,s);if("error"in a)return a;let c=n.target_file;return a.sha&&!o.some(u=>u.path===c)&&o.push({path:c,sha:a.sha}),a.content}case"grep":{let a=await cC(n,r,s,pC());if("error"in a)return a;for(let c of a.matches)c.sha&&!o.some(u=>u.path===c.file)&&o.push({path:c.file,sha:c.sha});return JSON.stringify(a)}case"glob":{let a=await uC(n,r,s);return"error"in a?a:JSON.stringify(a)}case"report_fix":{let a=(n.edits||[]).map(u=>({...u,replaceAll:u.replaceAll??!0}));Ae.log(`[DuplicateManager] LLM proposed fix with ${a.length} edits: ${n.description||"Duplicate code refactored"}`);let c=await this.validateFix(a,i,r);return c.valid?(Ae.log("[DuplicateManager] Fix validation passed"),JSON.stringify({success:!0,result:{edits:a,description:n.description||"Duplicate code refactored"}})):(Ae.log(`[DuplicateManager] Fix validation failed, sending error back to LLM: ${c.error}`),JSON.stringify({success:!1,error:c.error,message:"The fix could not be applied. Please review the error and provide a corrected fix."}))}default:return{error:`Unknown tool: ${e}`}}}detectLanguage(e){switch(e.split(".").pop()?.toLowerCase()){case"ts":return"TypeScript";case"tsx":return"Tsx";case"js":case"jsx":return"JavaScript";case"py":return"Python";default:return"TypeScript"}}};import{spawn as QMt}from"child_process";var jy=class{serverProcess=null;requestId=0;pendingRequests=new Map;workspaceRoot;stderrBuffer=[];constructor(e){this.workspaceRoot=e}initialize(){return new Promise((e,n)=>{let r=this.getRuntimePath();this.serverProcess=QMt(r,["server"],{stdio:["pipe","pipe","pipe"]}),this.serverProcess.on("error",o=>{Ae.log(`[Runtime] Spawn error: ${o.message}`),n(new Error(`Failed to spawn runtime server: ${o.message}`))});let i="";this.serverProcess.stdout?.on("data",o=>{i+=o.toString();let s=i.split(`
|
|
@@ -311,7 +311,7 @@ ${o.summary.goodExample}
|
|
|
311
311
|
|
|
312
312
|
${o.reason}
|
|
313
313
|
|
|
314
|
-
`),{contents:{kind:mr.MarkupKind.Markdown,value:E}}}registerHandlers(){this.connection.onInitialize(e=>({capabilities:{textDocumentSync:{openClose:!0,change:mr.TextDocumentSyncKind.Incremental,save:!0},codeActionProvider:{codeActionKinds:["quickfix","quickfix.wispbit","source.fixAll","source.fixAll.wispbit","refactor","refactor.disable.wispbit"]},executeCommandProvider:{commands:["wispbit.getDiagnostics","wispbit.quickfix","wispbit.dismiss","wispbit.remember","wispbit.getDismissals","wispbit.undismiss"]},hoverProvider:!0}})),this.connection.onInitialized(async()=>{this.connection.console.log("LSP server initialized, discovering repositories..."),await this.repositoryContextManager.discoverAndInitialize((n,r)=>{this.connection.console.log(`[${n}] Repository initialized successfully`),this.connection.console.log(`[${n}] Using Wispbit API host: ${r.config.getBaseUrl()}`),r.config.getEnableDeduplicator()&&this.connection.console.log(`[${n}] Duplicate detection enabled`),this.setupProgressListenersForContext(r)},(n,r)=>{this.connection.console.log(`[${n}] Failed to initialize: ${r.message}`)});let e=this.repositoryContextManager.getRepoCount();if(e===0){this.connection.console.log("No git repositories found in workspace - Wispbit will not run");return}this.connection.console.log(`Initialized ${e} repository(ies), running initial check...`),this.triggerExecution(),this.startPeriodicBranchCheck()}),this.connection.onCodeAction(e=>{let n=e.textDocument.uri,r=e.context.diagnostics;if(!r||r.length===0){let s=this.getDiagnosticsForUri(n),a=e.range;r=s.filter(c=>this.rangesOverlap({start:a.start,end:a.end},{start:c.range.start,end:c.range.end}))}if(r.length===0)return[];let i=e.context.only,o=this.generateCodeActions(n,r);return i&&i.length>0?o.filter(s=>s.kind?i.some(a=>s.kind?.startsWith(a)):!1):o}),this.connection.onHover(e=>{let n=this.getDiagnosticsForUri(e.textDocument.uri);return this.generateHover(n,e.position)}),this.connection.languages.diagnostics.on(e=>{let n=this.getDiagnosticsForUri(e.textDocument.uri);return{kind:mr.DocumentDiagnosticReportKind.Full,items:n}}),this.connection.onExecuteCommand(async e=>{switch(e.command){case"wispbit.getDiagnostics":{let{uri:n}=e.arguments?.[0]||{};return n?this.getDiagnosticsForUri(n):[]}case"wispbit.quickfix":await this.handleQuickfix(e.arguments||[]);break;case"wispbit.dismiss":await this.handleDismiss(e.arguments||[]);break;case"wispbit.remember":await this.handleRemember(e.arguments||[]);break;case"wispbit.getDismissals":return await this.handleGetDismissals(e.arguments||[]);case"wispbit.undismiss":await this.handleUndismiss(e.arguments||[]);break}}),this.connection.onShutdown(async()=>{await this.shutdown()})}startPeriodicBranchCheck(){this.branchCheckInterval=setInterval(()=>{this.scheduleBranchCheck()},this.BRANCH_CHECK_INTERVAL_MS)}scheduleBranchCheck(){this.branchCheckTimer&&clearTimeout(this.branchCheckTimer),this.branchCheckTimer=setTimeout(async()=>{await this.checkForBranchSwitch(),this.branchCheckTimer=null},this.BRANCH_CHECK_DEBOUNCE_MS)}async checkForBranchSwitch(){let e=this.repositoryContextManager.getAllContexts(),n=!1;for(let r of e){let{commitSelector:i}=await ga(r.repoRoot).catch(()=>({commitSelector:null}));i&&r.lastCommitSelector!==null&&r.lastCommitSelector!==i&&(this.connection.console.log(`[${r.repoRoot}] Branch switch detected (${r.lastCommitSelector} -> ${i}), will re-lint...`),r.ruleExecutor.clearCache(),r.duplicateManager&&r.duplicateManager.clearCache(),r.lastCommitSelector=i,n=!0)}n&&(this.clearAllDiagnostics(),this.clearAllLocalDismissals(),this.hasRunInitialCheck=!1,this.changedFiles.clear(),this.triggerExecution())}async shutdown(){this.connection.console.log("LSP server shutdown requested, cleaning up..."),this.cleanupProgress(),this.executionDebounceTimer&&(clearTimeout(this.executionDebounceTimer),this.executionDebounceTimer=null),this.branchCheckTimer&&(clearTimeout(this.branchCheckTimer),this.branchCheckTimer=null),this.branchCheckInterval&&(clearInterval(this.branchCheckInterval),this.branchCheckInterval=null),await this.repositoryContextManager.shutdown(),this.connection.console.log("LSP server shutdown complete")}start(){this.documentManager.listen(this.connection,{onDidOpen:n=>{let
|
|
314
|
+
`),{contents:{kind:mr.MarkupKind.Markdown,value:E}}}registerHandlers(){this.connection.onInitialize(e=>({capabilities:{textDocumentSync:{openClose:!0,change:mr.TextDocumentSyncKind.Incremental,save:!0},codeActionProvider:{codeActionKinds:["quickfix","quickfix.wispbit","source.fixAll","source.fixAll.wispbit","refactor","refactor.disable.wispbit"]},executeCommandProvider:{commands:["wispbit.getDiagnostics","wispbit.quickfix","wispbit.dismiss","wispbit.remember","wispbit.getDismissals","wispbit.undismiss"]},hoverProvider:!0}})),this.connection.onInitialized(async()=>{this.connection.console.log("LSP server initialized, discovering repositories..."),await this.repositoryContextManager.discoverAndInitialize((n,r)=>{this.connection.console.log(`[${n}] Repository initialized successfully`),this.connection.console.log(`[${n}] Using Wispbit API host: ${r.config.getBaseUrl()}`),r.config.getEnableDeduplicator()&&this.connection.console.log(`[${n}] Duplicate detection enabled`),this.setupProgressListenersForContext(r)},(n,r)=>{this.connection.console.log(`[${n}] Failed to initialize: ${r.message}`)});let e=this.repositoryContextManager.getRepoCount();if(e===0){this.connection.console.log("No git repositories found in workspace - Wispbit will not run");return}this.connection.console.log(`Initialized ${e} repository(ies), running initial check...`),this.triggerExecution(),this.startPeriodicBranchCheck()}),this.connection.onCodeAction(e=>{let n=e.textDocument.uri,r=e.context.diagnostics;if(!r||r.length===0){let s=this.getDiagnosticsForUri(n),a=e.range;r=s.filter(c=>this.rangesOverlap({start:a.start,end:a.end},{start:c.range.start,end:c.range.end}))}if(r.length===0)return[];let i=e.context.only,o=this.generateCodeActions(n,r);return i&&i.length>0?o.filter(s=>s.kind?i.some(a=>s.kind?.startsWith(a)):!1):o}),this.connection.onHover(e=>{let n=this.getDiagnosticsForUri(e.textDocument.uri);return this.generateHover(n,e.position)}),this.connection.languages.diagnostics.on(e=>{let n=this.getDiagnosticsForUri(e.textDocument.uri);return{kind:mr.DocumentDiagnosticReportKind.Full,items:n}}),this.connection.onExecuteCommand(async e=>{switch(e.command){case"wispbit.getDiagnostics":{let{uri:n}=e.arguments?.[0]||{};return n?this.getDiagnosticsForUri(n):[]}case"wispbit.quickfix":await this.handleQuickfix(e.arguments||[]);break;case"wispbit.dismiss":await this.handleDismiss(e.arguments||[]);break;case"wispbit.remember":await this.handleRemember(e.arguments||[]);break;case"wispbit.getDismissals":return await this.handleGetDismissals(e.arguments||[]);case"wispbit.undismiss":await this.handleUndismiss(e.arguments||[]);break}}),this.connection.onShutdown(async()=>{await this.shutdown()})}startPeriodicBranchCheck(){this.branchCheckInterval=setInterval(()=>{this.scheduleBranchCheck()},this.BRANCH_CHECK_INTERVAL_MS)}scheduleBranchCheck(){this.branchCheckTimer&&clearTimeout(this.branchCheckTimer),this.branchCheckTimer=setTimeout(async()=>{await this.checkForBranchSwitch(),this.branchCheckTimer=null},this.BRANCH_CHECK_DEBOUNCE_MS)}async checkForBranchSwitch(){let e=this.repositoryContextManager.getAllContexts(),n=!1;for(let r of e){let{commitSelector:i}=await ga(r.repoRoot).catch(()=>({commitSelector:null}));i&&r.lastCommitSelector!==null&&r.lastCommitSelector!==i&&(this.connection.console.log(`[${r.repoRoot}] Branch switch detected (${r.lastCommitSelector} -> ${i}), will re-lint...`),r.ruleExecutor.clearCache(),r.duplicateManager&&r.duplicateManager.clearCache(),r.lastCommitSelector=i,n=!0)}n&&(this.clearAllDiagnostics(),this.clearAllLocalDismissals(),this.hasRunInitialCheck=!1,this.changedFiles.clear(),this.triggerExecution())}async shutdown(){this.connection.console.log("LSP server shutdown requested, cleaning up..."),this.cleanupProgress(),this.executionDebounceTimer&&(clearTimeout(this.executionDebounceTimer),this.executionDebounceTimer=null),this.branchCheckTimer&&(clearTimeout(this.branchCheckTimer),this.branchCheckTimer=null),this.branchCheckInterval&&(clearInterval(this.branchCheckInterval),this.branchCheckInterval=null),await this.repositoryContextManager.shutdown(),this.connection.console.log("LSP server shutdown complete")}start(){this.documentManager.listen(this.connection,{onDidOpen:(n,r,i)=>{let o=this.getDiagnosticsForUri(n);o.length>0&&this.connection.sendDiagnostics({uri:n,diagnostics:o}),i&&this.lintDocument(n)},onDidChangeContent:(n,r,i)=>{this.handleDocumentChangesWithRanges(n,i),this.scheduleBranchCheck()},onDidSave:n=>{this.connection.console.log(`Document saved: ${n}, running lint...`),this.lintDocument(n),this.scheduleBranchCheck()},onDidClose:async n=>{let r=xo(n);if(!await Zy.access(r).then(()=>!0).catch(()=>!1)){this.connection.console.log(`File deleted: ${n}, clearing diagnostics`),this.clearDiagnosticsForFile(n);let o=this.toRelativePath(r);this.documentManager.clearDismissals(o)}}}),this.connection.listen();let e=Qi();this.connection.console.log(`Wispbit LSP server started and listening (CLI version: ${e})`)}};function _Ke(t){new TK(t).start()}Cc();import oPt from"readline";Cc();var St="#fbbf24",$S="#ff6b35",Vo="#4a90e2",jS="#9b59b6",SK=[`
|
|
315
315
|
${j.hex(St)(" \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
|
|
316
316
|
${j.hex(St)(" \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D")}
|
|
317
317
|
${j.hex(St)(" \u2588\u2588\u2551 \u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|