@wispbit/local 1.0.30 → 1.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +92 -79
- package/dist/package.json +1 -1
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -1,88 +1,101 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import*as
|
|
3
|
-
`).filter(Boolean).map(t=>t.trim())}async function
|
|
4
|
-
`)[0].match(/a\/(.+?) b\//);if(
|
|
2
|
+
import*as Q from"fs/promises";import*as Nt from"os";import*as je from"path";import Ot from"big.js";import A from"chalk";import Ti from"dotenv";import _i from"meow";import Ai from"semver";import jt from"p-retry";import{z as p}from"zod";var Wt=p.object({repository_url:p.string(),powerlint_version:p.string(),schema_version:p.string()}),Ut=p.object({configured:p.boolean(),invalid_api_key:p.boolean().optional(),is_valid_repository:p.boolean().optional(),config:p.object({ignored_globs:p.array(p.string())}).optional()}),Vt=p.object({repository_url:p.string(),rule_ids:p.array(p.string()).optional(),schema_version:p.string(),powerlint_version:p.string()}),qt=p.object({rules:p.array(p.object({id:p.string(),internalId:p.string(),internalVersionId:p.string(),message:p.string(),prompt:p.string(),severity:p.enum(["suggestion","violation"]),schema:p.any(),execution:p.enum(["llm","deterministic"]).optional()}))}),zt=p.object({rule:p.object({id:p.string(),versionId:p.string(),contents:p.string(),message:p.string()}),matches:p.array(p.any()),messages:p.array(p.any()),tools:p.array(p.enum(["read","grep","glob"])),files:p.array(p.object({path:p.string(),sha:p.string()})).optional(),schema_version:p.string(),powerlint_version:p.string(),repository_url:p.string(),commit:p.object({sha:p.string(),branch:p.string(),message:p.string(),timestamp:p.string()})}),Kt=p.discriminatedUnion("type",[p.object({type:p.literal("tool_request"),tool_calls:p.array(p.any()),usage:p.object({cost:p.string(),inputTokens:p.string(),outputTokens:p.string()})}),p.object({type:p.literal("matches"),matches:p.array(p.any()),usage:p.object({cost:p.string(),inputTokens:p.string(),outputTokens:p.string()}),files:p.array(p.object({path:p.string(),sha:p.string()})).optional()}),p.object({type:p.literal("request_files"),files:p.array(p.object({path:p.string(),sha:p.string()})),usage:p.object({cost:p.string(),inputTokens:p.string(),outputTokens:p.string()})})]),Ht=p.object({rule:p.object({id:p.string(),versionId:p.string(),contents:p.string(),message:p.string()}),matches:p.array(p.any()),files:p.array(p.object({path:p.string(),sha:p.string()})).optional(),schema_version:p.string(),powerlint_version:p.string(),repository_url:p.string(),commit:p.object({sha:p.string(),branch:p.string(),message:p.string(),timestamp:p.string()})}),Jt=p.object({type:p.literal("matches"),matches:p.array(p.any()),usage:p.object({cost:p.string(),inputTokens:p.string(),outputTokens:p.string()})}),me=class{baseUrl;apiKey;constructor(e){this.baseUrl=e.baseUrl,this.apiKey=e.apiKey}async request(e,t,n){let i=`${this.baseUrl}${e}`,a=await(await jt(async()=>{let s=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(t)});if(!s.ok){let l=await s.text();throw new Error(`Wispbit API request failed: ${s.status} ${s.statusText} - ${l}`)}return s},{retries:3,minTimeout:1e3,maxTimeout:5e3,onFailedAttempt:s=>{console.warn(`API request to ${e} failed (attempt ${s.attemptNumber}/4): ${s.message}`)}})).json();return n?n.parse(a):a}async initialize(e){let t=Wt.parse(e);return await this.request("/plv1/initialize",t,Ut)}async getRules(e){let t=Vt.parse(e);return await this.request("/plv1/get-rules",t,qt)}async matchLLMSearch(e){let t=zt.parse(e);return await this.request("/plv1/llm-search",t,Kt)}async matchLLMValidate(e){let t=Ht.parse(e);return await this.request("/plv1/llm-validate",t,Jt)}};var Me=class{config;environment;constructor(e,t){this.config=e,this.environment=t}async search(e){let t=this.config.getApiClient(),n=await this.environment.getRepositoryUrl(),i=await this.environment.getCurrentCommit(),r={id:e.rule.internalId,versionId:e.rule.internalVersionId,contents:e.rule.prompt,message:e.rule.config.message};return await t.matchLLMSearch({rule:r,matches:e.matches,messages:e.messages,tools:e.tools,files:e.files,schema_version:this.config.getSchemaVersion(),powerlint_version:this.config.getLocalVersion(),repository_url:n,commit:i})}async validate(e){let t=this.config.getApiClient(),n=await this.environment.getRepositoryUrl(),i=await this.environment.getCurrentCommit(),r={id:e.rule.internalId,versionId:e.rule.internalVersionId,contents:e.rule.prompt,message:e.rule.config.message};return await t.matchLLMValidate({rule:r,matches:e.matches,files:e.files,schema_version:this.config.getSchemaVersion(),powerlint_version:this.config.getLocalVersion(),repository_url:n,commit:i})}};import{readFileSync as Yt}from"fs";import{dirname as Qt,join as Xt}from"path";import{fileURLToPath as Zt}from"url";import en from"latest-version";function Y(){let o=Zt(import.meta.url?import.meta.url:__filename),e=Qt(o),t=Xt(e,"../package.json");try{let n=Yt(t,"utf8");return JSON.parse(n).version}catch{return"0.0.0"}}async function et(){try{return await en("@wispbit/local")}catch{return Y()}}var ge=class o{config;apiKey=null;baseUrl=null;apiClient=null;llmProvider=null;constructor(e,t){this.config={...e,ignoredGlobs:e.ignoredGlobs||[]},this.apiKey=e.apiKey||null,this.baseUrl=e.baseUrl||null,this.apiKey&&this.baseUrl&&(this.apiClient=new me({baseUrl:this.baseUrl,apiKey:this.apiKey})),t!=null&&t.llmProvider&&(this.llmProvider=t.llmProvider)}getIgnoredGlobs(){return this.config.ignoredGlobs||[]}getApiKey(){return this.apiKey}getBaseUrl(){return this.baseUrl}getApiClient(){if(!this.apiClient)throw new Error("API client not initialized. Config must have both apiKey and baseUrl.");return this.apiClient}getLLMProvider(){if(!this.llmProvider)throw new Error("LLM provider not initialized. Use Config.initialize() instead of initializeLocal().");return this.llmProvider}getLocalVersion(){return Y()}getSchemaVersion(){return"v1"}static initializeLocal(e={}){let t=e.ignoredGlobs||[];return new o({ignoredGlobs:t},{llmProvider:e.llmProvider})}static async initialize(e,{apiKey:t,baseUrl:n}){var m;let i=n||process.env.WISPBIT_API_BASE_URL||"https://api.wispbit.com",r=t||process.env.WISPBIT_API_KEY||null;if(!r)return console.log("No API key found"),{failed:!0,error:"INVALID_API_KEY"};let a=await e.getRepositoryUrl(),l=await new me({baseUrl:i,apiKey:r}).initialize({repository_url:a,powerlint_version:Y(),schema_version:"v1"});if(l.invalid_api_key)return{failed:!0,error:"INVALID_API_KEY"};if(!l.is_valid_repository)return{failed:!0,error:"INVALID_REPOSITORY"};let c=((m=l.config)==null?void 0:m.ignored_globs)||[],u=new o({ignoredGlobs:c,apiKey:r,baseUrl:i},{});return u.llmProvider=new Me(u,e),u}isConfigured(){return this.getApiKey()!==null}};import{exec as nn,execSync as rn}from"child_process";import{existsSync as sn,readFileSync as on}from"fs";import{promisify as an}from"util";import{createHash as tn}from"crypto";function pe(o){return tn("sha256").update(o).digest("hex")}var F=an(nn);function nt(){return rn("git rev-parse --show-toplevel",{encoding:"utf-8"}).trim()}async function it(o){let{stdout:e}=await F("git ls-files --ignored --exclude-standard --others",{cwd:o,maxBuffer:52428800});return e.split(`
|
|
3
|
+
`).filter(Boolean).map(t=>t.trim())}async function rt(o,e="origin"){let{stdout:t}=await F(`git config --get remote.${e}.url`,{cwd:o});return t.trim()||null}async function st(o,e="origin"){try{let{stdout:t}=await F(`git rev-parse --abbrev-ref ${e}/HEAD`,{cwd:o});return t.trim().split("/").pop()||null}catch{let n=["main","master"];for(let i of n)try{return await F(`git rev-parse --verify ${i}`,{cwd:o}),i}catch{}return null}}async function ot(o){let{stdout:e}=await F("git rev-parse --abbrev-ref --symbolic-full-name @{u}",{cwd:o});return e.trim()||void 0}function at(o,e){let t=`.git/refs/branch-metadata/${e}`,n=`${o}/${t}`;if(!sn(n))return;let r=on(n,"utf-8").match(/"parent"\s*:\s*"([^"]+)"/);return r==null?void 0:r[1]}function B(o){return`'${o.replace(/'/g,"'\\''")}'`}function z(o){return o.map(B).join(" ")}function ln(o){let e={committed:!0,staged:!0,unstaged:!0,untracked:!0};if(!o||o.length===0)return e;let t=new Set(o);return{committed:t.has("committed"),staged:t.has("staged"),unstaged:t.has("unstaged"),untracked:t.has("untracked")}}function Se(o,e){if(!o)return[];let t=[],n=o.split("\0").filter(Boolean);for(let i=0;i<n.length;){let r=n[i];if(!r)break;if(r.startsWith("R")){let a=n[i+1],s=n[i+2];a&&s?(t.push({status:r,path:s,oldPath:a,source:e}),i+=3):i++}else{let a=n[i+1];a?(t.push({status:r,path:a,source:e}),i+=2):i++}}return t}function cn(o){return o?o.split("\0").filter(Boolean).map(e=>({status:"U",path:e,source:"untracked"})):[]}function un(o){let e=new Map;for(let t of o){let n=e.get(t.path);if(!n)e.set(t.path,t);else{let i=tt(n.source),r=tt(t.source);r>i?e.set(t.path,t):r===i&&t.oldPath&&(n.oldPath=n.oldPath||t.oldPath)}}return Array.from(e.values())}function tt(o){switch(o){case"untracked":return 4;case"unstaged":return 3;case"staged":return 2;case"committed":return 1}}function Ue(o){let e=new Map;if(!o)return e;let t=o.split(/^diff --git /m).filter(Boolean);for(let n of t){let a=n.split(`
|
|
4
|
+
`)[0].match(/a\/(.+?) b\//);if(a){let s=a[1];e.set(s,"diff --git "+n)}}return e}function mn(o){return o.status==="U"||o.status==="A"?"added":o.status==="D"?"removed":"modified"}function fe(o){if(!o)return"";let e=o.split(`
|
|
5
5
|
`),t=[],n=!1;for(let i of e)i.startsWith("diff --git")||i.startsWith("index ")||i.startsWith("--- ")||i.startsWith("+++ ")||i.startsWith("new file mode")||i.startsWith("deleted file mode")||i.startsWith("old mode")||i.startsWith("new mode")||i.startsWith("similarity index")||i.startsWith("rename from")||i.startsWith("rename to")||i.startsWith("copy from")||i.startsWith("copy to")||i==="\"||(i.startsWith("@@")&&(n=!0),n&&t.push(i));return t.join(`
|
|
6
|
-
`).trimEnd()}function Pe(
|
|
7
|
-
`).filter(Boolean);for(let
|
|
8
|
-
`).filter(Boolean);for(let
|
|
9
|
-
`).filter(Boolean);for(let
|
|
10
|
-
`)
|
|
11
|
-
`),i=0,o=!1;for(let s of n){let a=s.match(/^@@\s+-\d+(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/);if(a){i=parseInt(a[1],10),o=!0;continue}if(o)if(s.startsWith("+")){if(i>=e&&i<=t)return!0;i++}else{if(s.startsWith("-"))continue;if(!s.startsWith("\\")){if(i>=e&&i<=t)return!0;i++}}}return!1}import gn from"ignore";function K(r,e){return e.length===0?!1:gn().add(e).ignores(r)}var Se=class r{environment;_filePaths=[];mode;eventEmitter;config;diffMode;constructor(e,t,n,i){this.environment=t,this.mode=n,this.eventEmitter=i||new N,this.config=e}static async initialize(e,t,n,i,o,s){let a=new r(e,t,n,i);if(n==="diff"&&!o){let u=a.environment.getWorkspaceRoot(),m=s==null?void 0:s.include,g=s==null?void 0:s.commitSelector;if(!g||!m)throw new Error("Commit selector and include are required in diff mode");let p=await st(u,{include:m,commitSelector:g}).catch(()=>{throw new Error("Diff mode requires a git repository. Please run this command from within a git repository.")});a.diffMode={gitChanges:p,changedFiles:p.files.map(y=>y.filename),fileChangeMap:new Map(p.files.map(y=>[y.filename,y]))},a.eventEmitter.fileDiscoveryProgress(`Found ${a.diffMode.changedFiles.length} changed files`)}let l=n==="check"?await a.loadGitIgnoredFiles():new Set,c=await a.discoverFiles(o,l);return a._filePaths=c,a}get filePaths(){return this._filePaths}filterFiles(e){let t=e.length,n;return this.mode==="check"?n=e:n=e.filter(i=>this.isFileValid({filePath:i})),t!==n.length&&this.eventEmitter.fileFilter(t,n.length,`${this.mode}-mode-files`),n}filterMatches(e){let t=e.length,n=e.filter(i=>this.isMatchValid({match:i}));return t!==n.length&&this.eventEmitter.fileFilter(t,n.length,`${this.mode}-mode-matches`),n}filterMatchesByFilePaths(e,t){if(e.length===0)return e;let n=new Set(t);return e.filter(i=>n.has(i.filePath))}get executionMode(){return this.mode}async loadGitIgnoredFiles(){let e=this.environment.getWorkspaceRoot(),t=await Ze(e).catch(()=>(this.eventEmitter.fileDiscoveryProgress("Not in a git repository, skipping git-ignored files"),[])),n=new Set(t);return t.length>0&&this.eventEmitter.fileDiscoveryProgress(`Found ${t.length} git-ignored files`),n}async discoverFiles(e,t){this.eventEmitter.startFileDiscovery(this.mode);let n;if(e)n=await this.discoverFilesFromPath(e,t);else if(this.mode==="diff"){let i=this.environment.getWorkspaceRoot();n=this.diffMode.changedFiles.filter(s=>ee.existsSync(j.resolve(i,s))).map(s=>s);let o=this.config.getIgnoredGlobs();if(o.length>0){this.eventEmitter.fileDiscoveryProgress("Applying ignore patterns...");let s=n.length;n=n.filter(a=>!K(a,o)),s!==n.length&&this.eventEmitter.fileDiscoveryProgress(`Filtered out ${s-n.length} ignored files`)}}else{this.eventEmitter.fileDiscoveryProgress("Scanning workspace for files...");let i=this.environment.getWorkspaceRoot(),o=this.config.getIgnoredGlobs();n=await this.discoverAllFiles([i],o,t)}return this.eventEmitter.completeFileDiscovery(n.length,this.mode),n}async discoverFilesFromPath(e,t){let n=this.environment.getWorkspaceRoot(),i=j.resolve(n,e),o=this.config.getIgnoredGlobs();if(this.isGlobPattern(e))return this.eventEmitter.fileDiscoveryProgress(`Discovering files matching glob pattern: ${e}`),await this.discoverFilesFromGlob(e,o,t);if(!ee.existsSync(i))throw new Error(`Path not found: ${e}`);let s=ee.statSync(i);if(s.isFile())return this.eventEmitter.fileDiscoveryProgress(`Checking specific file: ${e}`),t.has(e)?(this.eventEmitter.fileDiscoveryProgress(`File ${e} is ignored by git`),[]):K(e,o)?(this.eventEmitter.fileDiscoveryProgress(`File ${e} is ignored by patterns`),[]):[e];if(s.isDirectory())return this.eventEmitter.fileDiscoveryProgress(`Discovering files in directory: ${e}`),await this.discoverFilesFromDirectory(e,o,t);throw new Error(`Path is neither a file nor directory: ${e}`)}isGlobPattern(e){return/[*?[\]{}]/.test(e)}async discoverFilesFromGlob(e,t,n){let i=this.environment.getWorkspaceRoot(),o=["**/node_modules/**","**/.git/**",...t],a=(await je(e,{cwd:i,nodir:!0,absolute:!1,ignore:o})).filter(l=>!n.has(l));return this.eventEmitter.fileDiscoveryProgress(`Found ${a.length} files matching pattern`),a}async discoverFilesFromDirectory(e,t,n){let i=this.environment.getWorkspaceRoot(),o=j.join(e,"**/*").replace(/\\/g,"/"),s=["**/node_modules/**","**/.git/**",...t],l=(await je(o,{cwd:i,nodir:!0,absolute:!1,ignore:s})).filter(c=>!n.has(c));return this.eventEmitter.fileDiscoveryProgress(`Found ${l.length} files in directory`),l}async discoverAllFiles(e,t,n){let i=[],o=this.environment.getWorkspaceRoot(),s=["**/node_modules/**","**/.git/**",...t];for(let a of e){if(!ee.statSync(a).isDirectory()){let m=j.relative(o,a),g=n.has(m),p=K(m,t);!g&&!p&&i.push(m);continue}let u=(await je("**/*",{cwd:a,nodir:!0,absolute:!1,ignore:s})).map(m=>{let g=j.resolve(a,m);return j.relative(o,g)}).filter(m=>!n.has(m));i.push(...u)}return[...new Set(i)]}isFileValid(e){if(this.mode==="check")return!0;let{filePath:t}=e;return Ue(t,{changedFiles:this.diffMode.changedFiles,fileChangeMap:this.diffMode.fileChangeMap})}isMatchValid(e){if(this.mode==="check")return!0;let{match:t}=e;return ot(t,{changedFiles:this.diffMode.changedFiles,fileChangeMap:this.diffMode.fileChangeMap})}};import*as te from"fs";import*as B from"path";var Me=class{environment;constructor(e){this.environment=e}evaluateCondition(e,t){let n=this.environment.getWorkspaceRoot(),i=B.resolve(n,t);if("fs.siblingExists"in e){let{filename:o}=e["fs.siblingExists"],s=B.dirname(i),a=B.join(s,o);return te.existsSync(a)}if("fs.ancestorHas"in e){let{filename:o}=e["fs.ancestorHas"],s=B.dirname(i),a=B.parse(s).root;for(;s!==a;){let l=B.join(s,o);if(te.existsSync(l))return!0;let c=B.dirname(s);if(c===s)break;s=c}return!1}if("fs.siblingAny"in e){let{pattern:o}=e["fs.siblingAny"],s=B.dirname(i);return te.existsSync(s)?te.readdirSync(s).some(l=>K(l,[o])):!1}return!1}evaluateConditions(e,t){let n=[];return e.all&&e.all.length>0&&n.push(e.all.every(i=>this.evaluateCondition(i,t))),e.any&&e.any.length>0&&n.push(e.any.some(i=>this.evaluateCondition(i,t))),e.not&&e.not.length>0&&n.push(!e.not.some(i=>this.evaluateCondition(i,t))),n.length===0?!0:n.every(i=>i===!0)}async execute(e,t){var s,a;let n=Date.now(),i=e;(s=t.include)!=null&&s.length&&(i=i.filter(l=>K(l,t.include))),(a=t.ignore)!=null&&a.length&&(i=i.filter(l=>!K(l,t.ignore))),Object.keys(t.conditions||{}).length>0&&i.length>0&&(i=i.filter(l=>this.evaluateConditions(t.conditions,l)));let o=Date.now()-n;return await Promise.resolve({filteredPaths:i,executionTime:o})}};import ni from"path";import{existsSync as Ve}from"fs";import{createRequire as fn}from"module";import fe from"path";import pn from"@ast-grep/lang-angular";import dn from"@ast-grep/lang-bash";import hn from"@ast-grep/lang-c";import xn from"@ast-grep/lang-cpp";import vn from"@ast-grep/lang-csharp";import yn from"@ast-grep/lang-css";import bn from"@ast-grep/lang-dart";import wn from"@ast-grep/lang-elixir";import Pn from"@ast-grep/lang-go";import Sn from"@ast-grep/lang-haskell";import Mn from"@ast-grep/lang-html";import En from"@ast-grep/lang-java";import $n from"@ast-grep/lang-javascript";import Rn from"@ast-grep/lang-json";import In from"@ast-grep/lang-kotlin";import Ln from"@ast-grep/lang-lua";import Cn from"@ast-grep/lang-markdown";import kn from"@ast-grep/lang-php";import Fn from"@ast-grep/lang-python";import Dn from"@ast-grep/lang-ruby";import Tn from"@ast-grep/lang-rust";import _n from"@ast-grep/lang-scala";import An from"@ast-grep/lang-sql";import On from"@ast-grep/lang-swift";import Nn from"@ast-grep/lang-toml";import Gn from"@ast-grep/lang-tsx";import Bn from"@ast-grep/lang-typescript";import Wn from"@ast-grep/lang-yaml";import{registerDynamicLanguage as Un}from"@ast-grep/napi";console.debug=()=>{};var jn=fn(import.meta.url?import.meta.url:__filename);function Vn(){let r=fe.dirname(jn.resolve("tree-sitter-graphql")),e=fe.join(r,"../../build/Release/tree_sitter_graphql_binding.node");if(Ve(e))return e;let t=fe.join(r,"../../build/Debug/tree_sitter_graphql_binding.node");if(Ve(t))return t;let n=fe.join(r,"parser.so");return Ve(n)?n:null}var lt=Vn(),zn={libraryPath:lt,extensions:["graphql"],languageSymbol:"tree_sitter_graphql",metaVarChar:"$",expandoChar:void 0},ct={Angular:pn,Bash:dn,C:hn,Cpp:xn,Csharp:vn,Css:yn,Dart:bn,Elixir:wn,Go:Pn,Haskell:Sn,Html:Mn,Java:En,JavaScript:$n,Json:Rn,Kotlin:In,Lua:Ln,Markdown:Cn,Php:kn,Python:Fn,Ruby:Dn,Rust:Tn,Scala:_n,Sql:An,Swift:On,Toml:Nn,Tsx:Gn,TypeScript:Bn,Yaml:Wn,...lt?{GraphQL:zn}:{}};Un(ct);var at=Object.entries(ct).reduce((r,[e,t])=>(r[e]=t.extensions??[],r),{});function ut(r){let e=fe.extname(r).slice(1);return Kn(e)??"Unknown"}function Kn(r){return Object.keys(at).find(e=>at[e].includes(r))}import{readFile as mt}from"fs/promises";import gt from"path";import{parse as qn,parseAsync as Hn}from"@ast-grep/napi";function pe(r){return{...r,range:{start:{line:r.range.start.line-1,column:r.range.start.column-1},end:{line:r.range.end.line-1,column:r.range.end.column-1}}}}function ne(r){return{...r,range:{start:{line:r.range.start.line+1,column:r.range.start.column+1},end:{line:r.range.end.line+1,column:r.range.end.column+1}}}}var Ee=class{environment;language;constructor(e,t){this.environment=e,this.language=t}async findMatches(e,t){if(e.length===0)return[];let{rule:n,constraints:i}=t,o=this.getBatchSize(),s=[];for(let a=0;a<e.length;a+=o){let l=e.slice(a,a+o),c=await this.processBatch(l,n,i);s.push(...c)}return s}getBatchSize(){let e=parseInt(process.env.UV_THREADPOOL_SIZE||"4",10);return Math.max(2,Math.floor(e/2))}async processBatch(e,t,n){let i=e.map(async l=>{let c=await mt(gt.resolve(this.environment.getWorkspaceRoot(),l),"utf-8");return(await Hn(this.language,c)).root().findAll({rule:t,language:this.language,constraints:n}).map(g=>({filePath:l,sgNode:g}))}),s=(await Promise.all(i)).flat(),a=[];for(let{filePath:l,sgNode:c}of s){let u=c.range(),m={filePath:l,text:c.text(),range:{start:{line:u.start.line,column:u.start.column},end:{line:u.end.line,column:u.end.column}},symbol:this.extractSymbol(c),language:this.language};a.push(ne(m))}return a}extractSymbol(e){let t=e.kind();if(t==="call_expression"){let n=e.field("function");if(n)return this.extractSymbol(n)}else if(t==="member_expression"){let n=e.field("property");if(n)return n.text()}else if(t==="identifier")return e.text()}async expandMatch(e){let t=new Set(["method_definition","function_declaration","function_expression","arrow_function","class_declaration","export_statement","lexical_declaration"]),n=gt.resolve(this.environment.getWorkspaceRoot(),e.filePath),i=await mt(n,"utf-8"),o=qn(this.language,i).root(),s=pe(e),a=this.findNodeAtPosition(o,s.range.start.line,s.range.start.column);if(!a)return null;let l=a;for(;l;){let c=l.kind(),u=typeof c=="string"?c:String(c);if(t.has(u)){let m=l.range(),g={filePath:e.filePath,text:l.text(),range:{start:{line:m.start.line,column:m.start.column},end:{line:m.end.line,column:m.end.column}},symbol:e.symbol,language:this.language};return ne(g)}l=l.parent()}return null}findNodeAtPosition(e,t,n){let i=e.range(),o=t>i.start.line||t===i.start.line&&n>=i.start.column,s=t<i.end.line||t===i.end.line&&n<=i.end.column;if(!o||!s)return null;let a=e.children();for(let l of a){let c=this.findNodeAtPosition(l,t,n);if(c)return c}return e}};import{spawn as Qn}from"child_process";import Ke from"fs/promises";import{createRequire as Xn}from"module";import Zn from"os";import pt from"path";import{readFile as Jn}from"fs/promises";import Yn from"path";async function ze(r,e,t){let n=Yn.resolve(r,e),o=(await Jn(n,"utf-8")).split(`
|
|
12
|
-
`),
|
|
13
|
-
`)
|
|
14
|
-
`),a=s.pop()||"",l=null;for(let c of s){let u=c.trim();u.match(ft)&&(l=u)}for(let c of s){let u=c.trim();if(!u)continue;let m=u.match(ft);if(m){if(u===l){let[,g,p]=m,y=pt.relative(i,g);t.indexingProgress(n,`Indexed ${y}`,y,parseInt(p,10))}}else t.indexingProgress(n,u)}return a}var Re=class{environment;storage;language;scipIndex=null;indexingPromise=null;eventEmitter;constructor(e,t,n){this.environment=e,this.storage=new Z(e),this.language=t,this.eventEmitter=n||new N}getScipCommand(){switch(this.language){case"TypeScript":case"JavaScript":case"Tsx":return"scip-typescript";case"Python":return"scip-python";default:throw new Error(`SCIP is not supported for language: ${this.language}`)}}async ensureIndexReady(){if(this.scipIndex===null){if(this.indexingPromise!==null)return this.indexingPromise;this.indexingPromise=this.startIndexing(),await this.indexingPromise}}async startIndexing(){if(await this.storage.indexExists(this.language,"index.scip")){await this.loadIndex();return}let e=await this.storage.getIndexFilePath(this.language,"index.scip"),t=pt.join(Zn.tmpdir(),`scip-index-${this.language}-${Date.now()}.tmp`);this.eventEmitter.startIndexing(this.language);let n=this.getScipCommand(),i=Qn(n,["index","--output",t],{cwd:this.environment.getWorkspaceRoot(),stdio:["ignore","pipe","pipe"],env:process.env}),o="";i.stdout.on("data",a=>{o=ti(a,o,this.eventEmitter,this.language,this.environment.getWorkspaceRoot())});let s="";i.stderr.on("data",a=>{s+=a.toString(),process.stderr.write(a)}),await new Promise((a,l)=>{i.on("close",async c=>{c===0?(await Ke.rename(t,e),a()):(await Ke.unlink(t).catch(()=>{}),l(new Error(`${n} index exited with code ${c}, stderr: ${s}`)))}),i.on("error",async c=>{await Ke.unlink(t).catch(()=>{}),l(c)})}),s&&console.error("SCIP indexing stderr:",s),this.eventEmitter.completeIndexing(this.language),await this.loadIndex()}async findDefinitions(e){if(await this.ensureIndexReady(),!this.scipIndex)throw new Error("SCIP index not ready");let t=pe(e);this.eventEmitter.startScipMatchLookup(this.language,t);let n=[],i=this.scipIndex.documents;for(let o of i){if(o.relative_path!==t.filePath)continue;this.eventEmitter.scipMatchLookupProgress(this.language,o);let s=this.findBestOverlappingOccurrence(o.occurrences,t);if(s){if(this.isExternalSymbol(s.symbol))continue;this.eventEmitter.scipMatchLookupProgress(this.language,s);let a=await this.findDefinitionForSymbol(s.symbol,i);a&&n.push(ne(a))}}return n}async findReferences(e){if(await this.ensureIndexReady(),!this.scipIndex)return[];let t=pe(e),n=[],i=this.scipIndex.documents;for(let o of i){if(o.relative_path!==t.filePath)continue;let s=this.findBestOverlappingOccurrence(o.occurrences,t);if(s){if(this.isExternalSymbol(s.symbol))break;let a=await this.findReferencesForSymbol(s.symbol,i);n.push(...a.map(l=>ne(l)));break}}return n}isExternalSymbol(e){return e.includes("node_modules")||e.startsWith("npm/")}findBestOverlappingOccurrence(e,t){let n=[];for(let i of e){let o=i.range;if(!o||o.length<3||!this.rangesOverlap(o,t))continue;let s=0;if(!this.rangeFullyInside(o,t))continue;let a=(o.length===3,o[1]);if(s+=a*1e3,i.symbol_roles!==$e.SymbolRole.Definition&&(s+=100),t.symbol){let{className:l,methodName:c}=this.extractSymbolNames(i.symbol);(c===t.symbol||l===t.symbol)&&(s+=1e4)}n.push({occurrence:i,score:s})}return n.length===0?null:(n.sort((i,o)=>o.score-i.score),n[0].occurrence)}rangesOverlap(e,t){if(e.length===3){let[n,i,o]=e;return t.range.start.line===t.range.end.line?n===t.range.start.line&&!(o<=t.range.start.column||i>=t.range.end.column):!(n<t.range.start.line||n>t.range.end.line||n===t.range.start.line&&o<=t.range.start.column||n===t.range.end.line&&i>=t.range.end.column)}else if(e.length===4){let[n,i,o,s]=e;return!(o<t.range.start.line||n>t.range.end.line)}return!1}rangeFullyInside(e,t){if(e.length===3){let[n,i,o]=e;return!(n<t.range.start.line||n>t.range.end.line||n===t.range.start.line&&i<t.range.start.column||n===t.range.end.line&&o>t.range.end.column)}else if(e.length===4){let[n,i,o,s]=e;return!(n<t.range.start.line||o>t.range.end.line||n===t.range.start.line&&i<t.range.start.column||o===t.range.end.line&&s>t.range.end.column)}return!1}extractSymbolNames(e){let t=e.match(/`([^`]+)`#([^#./`(]+)(?:\(\))?[.`]*$/);if(t)return{className:t[1],methodName:t[2]};let n=e.match(/([^#./`(]+)(?:\(\))?[.`]*$/);return n?{className:null,methodName:n[1]}:{className:null,methodName:null}}async findDefinitionForSymbol(e,t){for(let n of t)for(let i of n.occurrences)if(i.symbol===e&&i.symbol_roles===$e.SymbolRole.Definition){let o=i.range??[],s=o[0]??0,a=o[1]??0,l=o.length===4?o[2]:s,c=o.length===4?o[3]:o[2]??a,u=await ze(this.environment.getWorkspaceRoot(),n.relative_path,{start:{line:s,column:a},end:{line:l,column:c}});return{language:this.language,filePath:n.relative_path,range:{start:{line:s,column:a},end:{line:l,column:c}},symbol:e,text:u}}return null}async findReferencesForSymbol(e,t){let n=[];for(let i of t)for(let o of i.occurrences)if(o.symbol===e&&o.symbol_roles!==$e.SymbolRole.Definition){let s=o.range??[],a=s[0]??0,l=s[1]??0,c=s.length===4?s[2]:a,u=s.length===4?s[3]:s[2]??l,m=await ze(this.environment.getWorkspaceRoot(),i.relative_path,{start:{line:a,column:l},end:{line:c,column:u}});n.push({language:this.language,filePath:i.relative_path,range:{start:{line:a,column:l},end:{line:c,column:u}},symbol:e,text:m})}return n}async loadIndex(){let e=await this.storage.readIndex(this.language,"index.scip");if(!e)throw new Error(`Index not found for language: ${this.language}`);this.scipIndex=this.parseIndex(new Uint8Array(e))}parseIndex(e){return $e.Index.deserialize(e)}};var ie=class extends Error{constructor(e,t){super(`${e} is not supported: ${t}`),this.name="LanguageBackendNotSupportedError"}},re=class{astProvider;intelligenceProvider;language;constructor(e,t,n){this.language=t,this.astProvider=new Ee(e,t),this.intelligenceProvider=new Re(e,t,n)}async findMatches(e,t){if(!this.astProvider)throw new ie("findMatches","no AST provider configured for this language");return await this.astProvider.findMatches(e,t)}async findDefinitions(e){if(!this.intelligenceProvider)throw new ie("findDefinitions","no intelligence provider configured for this language");return await this.intelligenceProvider.findDefinitions(e)}async findReferences(e){if(!this.intelligenceProvider)throw new ie("findReferences","no intelligence provider configured for this language");return await this.intelligenceProvider.findReferences(e)}async expandMatch(e){if(!this.astProvider)throw new ie("expandMatch","no AST provider configured for this language");return await this.astProvider.expandMatch(e)}};var Ie=class{environment;eventEmitter;constructor(e,t){this.environment=e,this.eventEmitter=t}async execute(e,t,n){let i=Date.now(),o=n.filePaths.filter(m=>ut(m)===t),l=(await new re(this.environment,t,this.eventEmitter).findMatches(o,e)).map(m=>{if(ni.isAbsolute(m.filePath))throw new Error(`Match provider returned absolute path: ${m.filePath}. All file paths must be relative to workspace root.`);return{...m,language:t}}),c=n.previousMatches&&n.previousMatches.length>0?this.filterMatchesByRanges(l,n.previousMatches,t):l;c=this.deduplicateMatches(c);let u=Date.now()-i;return{matches:c,totalMatches:c.length,executionTime:u}}filterMatchesByRanges(e,t,n){let i=[];for(let o of e){let s=t.find(l=>this.isMatchInRange(o,l));if(!s)continue;let a=[...s.evidence||[],{filePath:s.filePath,text:s.text,range:s.range,symbol:s.symbol,language:s.language}];i.push({...o,evidence:a})}return i}isMatchInRange(e,t){if(e.filePath!==t.filePath)return!1;let n=e.range.start,i=e.range.end,o=t.range.start,s=t.range.end,a=n.line>o.line||n.line===o.line&&n.column>=o.column,l=i.line<s.line||i.line===s.line&&i.column<=s.column;return a&&l}deduplicateMatches(e){if(e.length<=1)return e;let t=[];for(let n of e)e.some(o=>n===o?!1:this.isMatchInRange(n,o))||t.push(n);return t}};import ii from"path";import ri from"ignore";var Le=class{maxDepth=1;environment;eventEmitter;constructor(e,t){this.environment=e,this.eventEmitter=t||new N}async execute(e,t,n={}){let i=Date.now(),o=new re(this.environment,t,this.eventEmitter),s=await this.followDefinitions(e,o,this.maxDepth,n.where,t),a=Date.now()-i,l=s.map(c=>{let{depth:u,sourceMatch:m,...g}=c,p=m?[{filePath:m.filePath,text:m.text,range:m.range,symbol:m.symbol,language:m.language},...m.evidence||[]]:[];return{...g,source:p}});return{definitions:l,totalDefinitions:l.length,executionTime:a}}async followDefinitions(e,t,n,i,o){let s=[],a=new Set;for(let l of e)await this.followDefinitionsRecursive(l,t,0,n,i,s,a,l,o);return s}async followDefinitionsRecursive(e,t,n,i,o,s,a,l,c){if(n>=i)return;let u=`${e.filePath}:${e.range.start.line}:${e.range.start.column}:${e.symbol??""}`;if(a.has(u))return;a.add(u);let m=await t.findDefinitions(e);for(let g of m){let y={...await t.expandMatch(g)??g,language:c,depth:n,sourceMatch:l||e};o&&!this.matchesDefinitionFilter(y,o)||(s.push(y),n+1<i&&await this.followDefinitionsRecursive(g,t,n+1,i,o,s,a,l||e,c))}}matchesDefinitionFilter(e,t){var n,i,o;if(t.all)return t.all.every(s=>this.matchesDefinitionFilter(e,s));if(t.any)return t.any.some(s=>this.matchesDefinitionFilter(e,s));if(t.not)return!this.matchesDefinitionFilter(e,t.not);if(t.file&&!this.matchesFileSpec(e.filePath,t.file))return!1;if((n=t.method)!=null&&n.name){let s=e.symbol;if(!s||!this.matchesNameSpec(s,t.method.name))return!1}if((i=t.function)!=null&&i.name){let s=e.symbol;if(!s||!this.matchesNameSpec(s,t.function.name))return!1}return(o=t.class)!=null&&o.name,!0}matchesNameSpec(e,t){return t.equals?e===t.equals:t.anyOf?t.anyOf.includes(e):t.regex?new RegExp(t.regex).test(e):!0}matchesFileSpec(e,t){let n=ii.relative(this.environment.getWorkspaceRoot(),e);return t.path?n===t.path:t.glob?ri().add(t.glob).ignores(n):t.regex?new RegExp(t.regex).test(n):!0}};import{spawn as ci}from"child_process";import he from"fs";import V,{dirname as vt,join as yt}from"path";import{glob as ui}from"glob";import{promises as si}from"fs";import Ws from"path";async function Ce(r){try{return await si.access(r),!0}catch{return!1}}import{execSync as oi}from"child_process";function dt(){return oi("which rg").toString().trim()}import ke from"fs";import ai from"path";async function ht(r){try{if(r.includes("/")||r.includes("\\"))return await ke.promises.access(r,ke.constants.X_OK),!0;let e=process.env.PATH||"",t=process.platform==="win32"?";":":",n=e.split(t),i=process.platform==="win32"?(process.env.PATHEXT||".exe;.cmd;.bat").split(";"):[""];for(let o of n)for(let s of i){let a=ai.join(o,r+s);try{return await ke.promises.access(a,ke.constants.X_OK),!0}catch{}}return!1}catch{return!1}}import li from"ignore";function xt(r){let e=r.match(/\{([^}]+)\}/);if(!e)return[r];let t=e[1].split(","),n=r.slice(0,e.index),i=r.slice(e.index+e[0].length),o=[];for(let s of t){let a=n+s+i;o.push(...xt(a))}return o}function de(r,e){if(e.length===0)return!1;let t=[];for(let i of e)t.push(...xt(i));return li().add(t).ignores(r)}function Fe(r,e){let t=new RegExp(e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g");return r.replace(t,"").replace(/\/\//g,"/")}function De(r,e){try{let t=V.resolve(r),n=V.resolve(r,e),i=V.normalize(t),o=V.normalize(n);return o===i||o.startsWith(i+V.sep)?o:null}catch{return null}}function mi(r,e,t){try{let i=he.readFileSync(r,"utf8").split(`
|
|
15
|
-
`),
|
|
16
|
-
`);let a=
|
|
17
|
-
`);let c=
|
|
18
|
-
`),s<
|
|
19
|
-
|
|
20
|
-
`),a=[];for(let l of s){let c=l.match(/^([^:]+):(\d+):(.*)$/);if(c){let[,u,m,g]=c,p=u;p=V.relative(n,u);let y=V.join(n,p);try{he.existsSync(y)&&a.push({file:p,line_number:parseInt(m,10),content:g})}catch{}}}return a}catch(o){let s=o;if(s.code===1&&!s.stderr)return[];throw s.signal==="SIGTERM"?new Error("rg search operation timed out"):o}}async function wt(r,e,t=[]){var a;let{pattern:n,include:i}=r,o=dt(),s=(a=r.path)!=null&&a.startsWith("/")?r.path.slice(1):r.path;try{if(!await ht(o))throw new Error(`ripgrep is not found or not executable: ${o}`);let c=null;if(s){let g=De(e,s);if(!g)return{error:`Invalid path: '${s}'. Please provide the correct path.`};if(!await Ce(g))return{error:`Path not found or not accessible: ${s}. Please provide the correct path.`};let p=await he.promises.stat(g);if(p.isFile())c=vt(g),s=vt(s);else if(p.isDirectory())c=g;else return{error:`Path is neither a file nor a directory: ${s}`}}return{matches:(await gi(o,n,i,c||e)).filter(g=>{let p=s?yt(s,g.file):g.file;return!de(p,t)}).slice(0,50).map(g=>({...g,file:s?yt(s,g.file):g.file}))}}catch(l){let c=typeof l=="object"&&l!==null&&"message"in l&&typeof l.message=="string"?l.message:String(l);return{error:Fe(c,e)}}}async function Pt(r,e,t=[]){let n=r.pattern,i=r.path;i&&n.startsWith(i)&&(n=n.replace(i,"")),n=n.startsWith("/")?n.slice(1):n;let o;if(i){if(i=i.startsWith("/")?i.slice(1):i,i!=="."&&de(i,t))return{files:[]};let s=De(e,i);if(!s)return{error:`Path not found or not accessible: '${i}'. Please provide the correct path.`};o=s}else o=e;if(!await Ce(o))return{error:`Directory not found or not accessible: ${i||"."}. Please provide the correct path.`};try{if(!(await he.promises.stat(o)).isDirectory())return{error:`Not a directory: ${i||"."}. Please provide the correct path.`}}catch{return{error:`Directory not found or not accessible: ${i||"."}. Please provide the correct path.`}}try{return{files:(await fi(n,i,e)).filter(l=>!de(l,t)).slice(0,50)}}catch(s){let a=typeof s=="object"&&s!==null&&"message"in s&&typeof s.message=="string"?s.message:String(s);return{error:Fe(a,e)}}}async function fi(r,e,t){try{let n;if(e){let s=e.startsWith("/")?e.slice(1):e,a=De(t,s);if(!a)throw new Error(`Invalid directory path: potential directory traversal detected in '${s}'`);n=a}else n=t;let i=await ui(r,{cwd:n,nodir:!0,ignore:["node_modules/**",".git/**","**/__pycache__/**"],absolute:!1}),o=[];for(let s of i)try{let a=V.join(n,s),l=await he.promises.stat(a);l.isFile()&&o.push({path:e?V.join(e,s):s,mtime:l.mtime})}catch{}return o.sort((s,a)=>a.mtime.getTime()-s.mtime.getTime()),o.map(s=>s.path)}catch(n){let i=n instanceof Error?n.message:String(n);throw new Error(Fe(`Glob search failed: ${i}`,t))}}var Te=class{environment;eventEmitter;config;maxIterations;constructor(e,t,n,i){this.environment=t,this.eventEmitter=n||new N,this.config=e,this.maxIterations=i||20}async executeTool(e,t){switch(e){case"read":{let n=await bt(t,this.environment.getWorkspaceRoot());return"error"in n?n:n.content}case"grep":{let n=await wt(t,this.environment.getWorkspaceRoot());return"error"in n?n:JSON.stringify(n.matches)}case"glob":{let n=await Pt(t,this.environment.getWorkspaceRoot());return"error"in n?n:JSON.stringify(n.files)}default:return{error:`Unknown tool: ${e}`}}}async executeLLMValidation(e,t,n){let i=Date.now(),o=this.config.getLLMProvider();this.eventEmitter.startLLMValidation(e.id,t.length);let s=[];for(let a=0;a<this.maxIterations;a++){let l=await o.call({rule:e,matches:t,tools:n,messages:s});if(l.type==="violations"){let u=l.violations.map(m=>m.match).map(m=>({...m,metadata:{llmValidation:{isViolation:!0,confidence:1,reason:"Confirmed violation"}}}));return this.eventEmitter.completeLLMValidation(e.id,0,Date.now()-i,u.length,!1),{matches:u,executionTime:Date.now()-i}}if(l.type==="tool_request"){s.push({type:"tool_request",tool_calls:l.tool_calls});let c=await Promise.all(l.tool_calls.map(async u=>{let m=JSON.parse(u.function.arguments),g=await this.executeTool(u.function.name,m),p=typeof g=="string"?g:JSON.stringify(g);return{tool_call_id:u.id,content:p}}));for(let u of c)s.push({type:"tool_response",tool_call_id:u.tool_call_id,content:u.content});continue}}throw new Error(`Max iterations (${this.maxIterations}) reached without getting violations`)}async execute(e,t,n){return t.length===0?{matches:[],executionTime:0}:await this.executeLLMValidation(e,t,n)}};var _e=class{fileFilterStep;findMatchesStep;gotoDefinitionStep;llmStep;environment;executionContext;currentMode;eventEmitter;config;constructor(e,t,n){this.environment=t,this.eventEmitter=n||new N,this.config=e,this.fileFilterStep=new Me(this.environment),this.findMatchesStep=new Ie(this.environment,this.eventEmitter),this.gotoDefinitionStep=new Le(this.environment,this.eventEmitter),this.llmStep=new Te(this.config,this.environment,this.eventEmitter)}async executeStep(e,t,n,i,o,s,a){let l=n.type;if(l==="ast-grep"){let{type:c,language:u,...m}=n;return{matches:(await this.findMatchesStep.execute(m,u,{filePaths:i,previousMatches:o})).matches}}if(l==="step-group")throw new Error("step-group step is disabled");if(l==="file-filter")return{filePaths:(await this.fileFilterStep.execute(i,{include:n.include,ignore:n.ignore,conditions:n.conditions})).filteredPaths};if(l==="goto-definition")throw new Error("goto-definition step is disabled");if(l==="llm")return o.length===0?{matches:[]}:{matches:(await this.llmStep.execute(e,o,n.tools??[])).matches};throw new Error(`Unknown step type: ${l}`)}async executeRule(e,t){let n=e.id,i=e.config,o=[...this.executionContext.filePaths],s=[];for(let l of i.steps){let c=l.id,u=l.step;this.eventEmitter.startStep(n,c,u.type,{filePaths:o,matches:s});let m=Date.now(),g=await this.executeStep(e,c,u,o,s,t),p=Date.now()-m;if(this.eventEmitter.completeStep(n,c,u.type,g,p),g.filePaths!==void 0&&(o=this.executionContext.filterFiles(g.filePaths),s=this.executionContext.filterMatchesByFilePaths(s,o)),g.matches!==void 0&&(s=this.executionContext.filterMatches(g.matches)),o.length===0)break}let a=s.sort((l,c)=>l.filePath.localeCompare(c.filePath));return{ruleId:n,matches:a}}getPoolSize(){let e=pi().length;return Math.max(2,Math.min(8,e))}async execute(e,t){if(this.currentMode&&this.currentMode!==t.mode)throw new Error(`Execution mode mismatch: expected ${this.currentMode}, got ${t.mode}`);(!this.executionContext||this.currentMode!==t.mode)&&(this.executionContext=await Se.initialize(this.config,this.environment,t.mode,this.eventEmitter,t.filePath,t.diffOptions),this.currentMode=t.mode),this.eventEmitter.startRules(e.length);let n=this.getPoolSize(),i=[],o=[...e],s=async u=>{let m=u.id,g=!1;for(let y of u.config.steps)if(y.step.type==="llm"){g=!0;break}this.eventEmitter.emit("rules:rule-start",{ruleId:m,isLlm:g,message:u.config.message,severity:u.config.severity});let p=await this.executeRule(u,t);return this.eventEmitter.emit("rules:rule-complete",{ruleId:m}),p};await(async()=>{let u=async()=>{if(o.length===0)return;let g=o.shift(),p=await s(g);i.push(p),await u()},m=[];for(let g=0;g<Math.min(n,e.length);g++)m.push(u());await Promise.all(m)})();let l=new Map(e.map((u,m)=>[u.id,m]));i.sort((u,m)=>{let g=l.get(u.ruleId)??0,p=l.get(m.ruleId)??0;return g-p});let c=i.reduce((u,m)=>u+m.matches.length,0);return this.eventEmitter.completeRules(e.length,c),i}};var Ae=class extends Error{constructor(t,n,i){super(`Invalid rule format in '${t}': ${n}`);this.validationErrors=i;this.name="InvalidRuleFormatError"}};import{stripVTControlCharacters as Mt}from"node:util";import f from"chalk";import di from"ora";var q="#f87171",H="#60a5fa",hi="#9b59b6",C="#fbbf24",qe="#9ca3af",ve="#9b59b6",Oe="\u25A0",xe="\u25CF",ye="\u2B25";function Et(r,e){if(e){let t=`https://app.wispbit.com/rules/${e}`;return f.dim.underline(`\x1B]8;;${t}\x1B\\${r}\x1B]8;;\x1B\\`)}return f.dim.underline(r)}function xi(r,e){return r.length<=e?r:r.substring(0,e-3)+"..."}var vi="#f8f8f8",yi="#888888",bi=[f.hex(C)("~(oo)~"),f.hex(C)("~(oO)~"),f.hex(C)("~(Oo)~"),f.hex(C)("~(OO)~"),f.hex(C)("~(\u25CFo)~"),f.hex(C)("~(o\u25CF)~"),f.hex(C)("~(\u25C9o)~"),f.hex(C)("~(o\u25C9)~"),f.hex(C)("\\(oo)/"),f.hex(C)("\\(oO)/"),f.hex(C)("\\(Oo)/"),f.hex(C)("\\(OO)/"),f.hex(C)("~(Oo)~"),f.hex(C)("~(oO)~"),f.hex(C)("~(\u25CEo)~"),f.hex(C)("~(o\u25CE)~"),f.hex(C)("~(oo)~"),f.hex(C)("~(OO)~"),f.hex(C)("~(Oo)~"),f.hex(C)("\\(oo)/"),f.hex(C)("\\(oO)/"),f.hex(C)("\\(Oo)/"),f.hex(C)("\\(OO)/")];function St(r,e){return e===1?r:`${r}s`}function wi(r,e={}){let n=e.align||[],i=e.stringLength||(s=>Mt(s).length),o=r.reduce((s,a)=>(a.forEach((l,c)=>{let u=i(l);(!s[c]||u>s[c])&&(s[c]=u)}),s),[]);return r.map(s=>s.map((a,l)=>{let c=o[l]-i(a)||0,u=Array(Math.max(c+1,1)).join(" ");return n[l]==="r"?u+a:a+u}).join(" ").trimEnd()).join(`
|
|
21
|
-
`)}function
|
|
22
|
-
`,n=0,i=0,
|
|
6
|
+
`).trimEnd()}function Pe(o){let e=o.match(/^(.+)\.\.\.(.+)$/);if(e)return[e[1],e[2],!0];let t=o.match(/^(.+)\.\.([^.].*)$/);return t?[t[1],t[2],!1]:[o,o,!1]}function gn(o){let[,e]=Pe(o);return e}async function Ve(o){let{stdout:e}=await F("git rev-parse --abbrev-ref HEAD",{cwd:o});return e.trim()}async function lt(o){let e=await Ve(o),{stdout:t}=await F("git rev-parse HEAD",{cwd:o}),n=t.trim(),{stdout:i}=await F('git log -1 --pretty=format:"%s"',{cwd:o}),r=i.trim(),{stdout:a}=await F('git log -1 --pretty=format:"%cI"',{cwd:o}),s=a.trim();return{sha:n,branch:e,message:r,timestamp:s}}function qe(o,e,t){if(!o.includes("..")||!(e.includes("staged")||e.includes("unstaged")||e.includes("untracked")))return null;let r=gn(o);return r==="HEAD"||r===t?null:`Worktree includes (staged, unstaged, untracked) require range to end at HEAD or current branch (${t}). Got: ${o}`}async function ze(o){let{stdout:e}=await F("git rev-parse --abbrev-ref HEAD",{cwd:o}),t=e.trim(),n=["committed","staged","unstaged","untracked"],i=at(o,t);if(i)return{commitSelector:`${i}...${t}`,include:n};let r=await st(o);if(r){if(t===r){let c=await ot(o).catch(()=>{});return c?{commitSelector:`${c}...HEAD`,include:n}:{commitSelector:"HEAD~1...HEAD",include:n}}let a=`origin/${r}`,{stdout:s}=await F(`git rev-parse --verify ${a}`,{cwd:o});return{commitSelector:`${s.trim()?a:r}...${t}`,include:n}}return{commitSelector:"HEAD...HEAD",include:n}}async function ct(o,e){let t=e.commitSelector.trim(),n=t.includes(".."),{stdout:i}=await F("git rev-parse --abbrev-ref HEAD",{cwd:o}),r=i.trim(),{stdout:a}=await F("git rev-parse HEAD",{cwd:o}),s=a.trim(),l="",c="";if(n)l=t,c=t;else{let x=at(o,r),d=await st(o),P=t||x||`origin/${d||"main"}`;c=P;let $=`git merge-base --fork-point ${B(P)} HEAD || git merge-base ${B(P)} HEAD`,{stdout:w}=await F($,{cwd:o});if(l=w.trim(),!t&&r===(d||"main")){let S=await ot(o).catch(()=>{});if(S){c=S;let{stdout:O}=await F(`git merge-base --fork-point ${B(S)} HEAD || git merge-base ${B(S)} HEAD`,{cwd:o});l=O.trim()}else c="HEAD~1",l="HEAD~1"}}let u=ln(e.include),m=qe(t,e.include,r);if(m)throw new Error(m);let g=[];if(u.committed)if(n){let[x,d]=Pe(t),{stdout:P}=await F(`git diff --name-status -M -z ${B(x)}..${B(d)}`,{cwd:o,maxBuffer:50*1024*1024});g.push(...Se(P,"committed"))}else{let{stdout:x}=await F(`git diff --name-status -M -z ${l}..HEAD`,{cwd:o,maxBuffer:52428800});g.push(...Se(x,"committed"))}if(u.staged){let{stdout:x}=await F("git diff --name-status -M -z --cached",{cwd:o,maxBuffer:52428800});g.push(...Se(x,"staged"))}if(u.unstaged){let{stdout:x}=await F("git diff --name-status -M -z",{cwd:o,maxBuffer:52428800});g.push(...Se(x,"unstaged"))}if(u.untracked){let{stdout:x}=await F("git ls-files --others --exclude-standard -z",{cwd:o,maxBuffer:52428800});g.push(...cn(x))}let h=un(g),v=h.filter(x=>x.source==="committed"),M=h.filter(x=>x.source==="staged"),E=h.filter(x=>x.source==="unstaged"),C=h.filter(x=>x.source==="untracked"),R=new Map;if(v.length>0){let x=v.map(w=>w.path),d="";if(n){let[w,S]=Pe(t);d=`git diff -U0 -M ${B(w)}..${B(S)} -- ${z(x)}`}else d=`git diff -U0 -M ${l}..HEAD -- ${z(x)}`;let{stdout:P}=await F(d,{cwd:o,maxBuffer:50*1024*1024});Ue(P).forEach((w,S)=>R.set(S,fe(w)))}if(M.length>0){let x=M.map(w=>w.path),d=`git diff -U0 -M --cached -- ${z(x)}`,{stdout:P}=await F(d,{cwd:o,maxBuffer:50*1024*1024});Ue(P).forEach((w,S)=>R.set(S,fe(w)))}if(E.length>0){let x=E.map(w=>w.path),d=`git diff -U0 -M -- ${z(x)}`,{stdout:P}=await F(d,{cwd:o,maxBuffer:50*1024*1024});Ue(P).forEach((w,S)=>R.set(S,fe(w)))}for(let x of C)try{let{stdout:d}=await F(`git diff -U0 --no-index /dev/null ${B(x.path)}`,{cwd:o,maxBuffer:52428800});R.set(x.path,fe(d))}catch(d){if(d.stdout)R.set(x.path,fe(d.stdout));else throw d}let b=new Map;if(v.length>0){let x=v.map(w=>w.path),d="";if(n){let[w,S]=Pe(t);d=`git diff --numstat ${B(w)}..${B(S)} -- ${z(x)}`}else d=`git diff --numstat ${l}..HEAD -- ${z(x)}`;let{stdout:P}=await F(d,{cwd:o,maxBuffer:50*1024*1024}),$=P.split(`
|
|
7
|
+
`).filter(Boolean);for(let w of $){let S=w.split(" ");if(S.length>=3){let[O,k,_]=S;b.set(_,{additions:parseInt(O)||0,deletions:parseInt(k)||0})}}}if(M.length>0){let x=M.map(w=>w.path),d=`git diff --numstat --cached -- ${z(x)}`,{stdout:P}=await F(d,{cwd:o,maxBuffer:50*1024*1024}),$=P.split(`
|
|
8
|
+
`).filter(Boolean);for(let w of $){let S=w.split(" ");if(S.length>=3){let[O,k,_]=S;b.set(_,{additions:parseInt(O)||0,deletions:parseInt(k)||0})}}}if(E.length>0){let x=E.map(w=>w.path),d=`git diff --numstat -- ${z(x)}`,{stdout:P}=await F(d,{cwd:o,maxBuffer:50*1024*1024}),$=P.split(`
|
|
9
|
+
`).filter(Boolean);for(let w of $){let S=w.split(" ");if(S.length>=3){let[O,k,_]=S;b.set(_,{additions:parseInt(O)||0,deletions:parseInt(k)||0})}}}for(let x of C){let P=(R.get(x.path)||"").split(`
|
|
10
|
+
`),$=0,w=0;for(let S of P)S.startsWith("+")&&!S.startsWith("+++")?$++:S.startsWith("-")&&!S.startsWith("---")&&w++;b.set(x.path,{additions:$,deletions:w})}let L=[];for(let x of h){let d=R.get(x.path)||"",P=b.get(x.path)||{additions:0,deletions:0},$=mn(x),w={filename:x.path,status:$,patch:d,additions:P.additions,deletions:P.deletions,sha:pe(d)};x.oldPath&&(w.oldFilename=x.oldPath),L.push(w)}return{files:L,currentBranch:r,currentCommit:s,diffBranch:c,diffCommit:l}}var X=class{workspaceRoot;repositoryUrl;constructor(e){this.repositoryUrl=(e==null?void 0:e.repositoryUrl)||null,this.workspaceRoot=(e==null?void 0:e.workspaceRoot)||nt()}getWorkspaceRoot(){return this.workspaceRoot}async getRepositoryUrl(e="origin"){if(this.repositoryUrl)return this.repositoryUrl;let t=await rt(this.workspaceRoot,e);if(!t)throw new Error("Could not determine repository URL. Make sure you're in a Git repository with a remote origin.");return t}async getCurrentCommit(){return await lt(this.workspaceRoot)}};import*as N from"fs/promises";import pn from"os";import Z from"path";import fn from"keyv";import{KeyvFile as hn}from"keyv-file";var ee=class{environment;cacheStore;constructor(e){this.environment=e}getStorageDirectory(){return Z.join(pn.homedir(),".powerlint")}getIndexDirectory(){return Z.join(this.getStorageDirectory(),"indexes",pe(this.environment.getWorkspaceRoot()))}getCacheDirectory(){return Z.join(this.getStorageDirectory(),"cache",pe(this.environment.getWorkspaceRoot()))}async ensureDirectory(e){await N.mkdir(e,{recursive:!0})}async getIndexFilePath(e,t){let n=this.getIndexDirectory();await this.ensureDirectory(n);let i=t||`${e.toLowerCase()}-index.scip`;return Z.join(n,`${e.toLowerCase()}-${i}`)}async indexExists(e,t){let n=await this.getIndexFilePath(e,t);try{return await N.access(n),!0}catch{return!1}}async readIndex(e,t){let n=await this.getIndexFilePath(e,t);try{return await N.access(n),await N.readFile(n)}catch{return null}}async saveIndex(e,t,n){let i=await this.getIndexFilePath(e,n);await N.writeFile(i,t)}getCacheFilePath(){return Z.join(this.getCacheDirectory(),"cache.json")}async purgeStorage(){let e=0,t=this.getStorageDirectory();try{await N.access(t),await N.rm(t,{recursive:!0,force:!0}),e++}catch{}return{success:!0,deletedCount:e}}async purgeCache(){let e=0,t=this.getCacheDirectory();try{await N.access(t),await N.rm(t,{recursive:!0,force:!0}),e++}catch{}return{success:!0,deletedCount:e}}getCacheStore(){if(!this.cacheStore){let e=this.getCacheDirectory();this.cacheStore=new fn({store:new hn({filename:Z.join(e,"cache.json")})})}return this.cacheStore}async saveCache(e,t,n){let i=this.getCacheStore(),r=`${e}:${t}`;await i.set(r,n)}async readCache(e,t){let n=this.getCacheStore(),i=`${e}:${t}`;return await n.get(i)||null}async purgeIndexes(){let e=0,t=this.getIndexDirectory();try{await N.access(t),await N.rm(t,{recursive:!0,force:!0}),e++}catch{}return{success:!0,deletedCount:e}}};var he=class{config;environment;constructor(e,t){this.config=e,this.environment=t}async getRepositoryUrl(){let e=await this.environment.getRepositoryUrl();if(!e)throw new Error("Could not determine repository URL. Make sure you're in a Git repository with a remote origin.");return e}async loadRuleById(e){let t=await this.fetchRules([e]);if(t.length===0)throw new Error(`Rule with ID '${e}' not found`);return t[0]}async loadAllRules(){return await this.fetchRules()}async fetchRules(e){let t=await this.getRepositoryUrl();return(await this.config.getApiClient().getRules({repository_url:t,rule_ids:e,schema_version:this.config.getSchemaVersion(),powerlint_version:this.config.getLocalVersion()})).rules.map(r=>({id:r.id,internalId:r.internalId,internalVersionId:r.internalVersionId,config:{message:r.message,severity:r.severity,execution:r.execution||"llm",steps:r.schema},prompt:r.prompt,testCases:[]}))}};import{EventEmitter as dn}from"events";var G=class extends dn{rulesStartTime=0;indexingStartTimes=new Map;fileDiscoveryStartTime=0;constructor(){super(),this.setMaxListeners(20)}emit(e,t){return super.emit(e,t)}on(e,t){return super.on(e,t)}once(e,t){return super.once(e,t)}off(e,t){return super.off(e,t)}setExecutionMode(e,t){this.emit("execution:mode",{mode:e,...t})}startRules(e){this.rulesStartTime=Date.now(),this.emit("rules:start",{totalRules:e})}progressRule(e,t,n,i){let r=Math.round(e/t*100);this.emit("rules:progress",{currentRule:e,totalRules:t,ruleId:n,percentage:r,isLlm:i})}completeRules(e,t){let n=Date.now()-this.rulesStartTime;this.emit("rules:complete",{totalRules:e,totalMatches:t,executionTime:n})}startFileDiscovery(e){this.fileDiscoveryStartTime=Date.now(),this.emit("files:discovery:start",{mode:e})}fileDiscoveryProgress(e,t){this.emit("files:discovery:progress",{message:e,currentCount:t})}completeFileDiscovery(e,t){let n=Date.now()-this.fileDiscoveryStartTime;this.emit("files:discovery:complete",{totalFiles:e,mode:t,executionTime:n})}fileFilter(e,t,n){this.emit("files:filter",{originalCount:e,filteredCount:t,filterType:n})}startScipMatchLookup(e,t){this.emit("scip:match-lookup:start",{language:e,match:t})}scipMatchLookupProgress(e,t){this.emit("scip:match-lookup:progress",{language:e,document:t})}scipMatchLookupComplete(e,t){this.emit("scip:match-lookup:complete",{language:e,document:t})}startIndexing(e){this.indexingStartTimes.set(e,Date.now()),this.emit("indexing:start",{language:e})}indexingProgress(e,t,n,i){this.emit("indexing:progress",{language:e,message:t,packageName:n,timeMs:i})}completeIndexing(e){let t=this.indexingStartTimes.get(e)||Date.now(),n=Date.now()-t;this.indexingStartTimes.delete(e),this.emit("indexing:complete",{language:e,executionTime:n})}startStep(e,t,n,i,r){this.emit("step:start",{ruleId:e,stepName:t,stepType:n,inputs:i,parentStepName:r})}completeStep(e,t,n,i,r=0,a){this.emit("step:complete",{ruleId:e,stepName:t,stepType:n,outputs:i,executionTime:r,parentStepName:a})}startTest(e,t){this.emit("test:start",{ruleId:e,testName:t})}testMatches(e,t,n){this.emit("test:matches",{ruleId:e,testName:t,matches:n})}completeTest(e,t,n,i){this.emit("test:complete",{ruleId:e,testName:t,matches:n,stepExecutions:i})}startLLMValidation(e,t,n){this.emit("llm:validation:start",{ruleId:e,matchCount:t,estimatedCost:n})}llmValidationProgress(e,t,n,i){this.emit("llm:validation:progress",{ruleId:e,tokenCount:t,elapsedTime:n,streamedText:i})}completeLLMValidation(e,t,n,i,r,a,s,l){this.emit("llm:validation:complete",{ruleId:e,tokenCount:t,inputTokens:n,outputTokens:i,cost:r,executionTime:a,violationCount:s,fromCache:l})}llmToolExecution(e,t,n){this.emit("llm:tool-execution",{ruleId:e,toolName:t,...n})}startLLMValidationPhase(e,t){this.emit("llm:validation-phase:start",{ruleId:e,matchCount:t})}};import{cpus as $i}from"os";import*as te from"fs";import*as U from"path";import{glob as He}from"glob";function Ke(o,e){let{changedFiles:t}=e;return t.some(n=>o===n||o.endsWith(n)||n.endsWith(o))}function xn(o,e,t,n){let{fileChangeMap:i}=n,r=i.get(o);return r?r.status==="added"?!0:r.status==="removed"?!1:vn(r.patch,e,t):!1}function ut(o,e){return Ke(o.file.path,e)&&xn(o.file.path,o.range.start.line,o.range.end.line,e)}function vn(o,e,t){let n=o.split(`
|
|
11
|
+
`),i=0,r=!1;for(let a of n){let s=a.match(/^@@\s+-\d+(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/);if(s){i=parseInt(s[1],10),r=!0;continue}if(r)if(a.startsWith("+")){if(i>=e&&i<=t)return!0;i++}else{if(a.startsWith("-"))continue;if(!a.startsWith("\\")){if(i>=e&&i<=t)return!0;i++}}}return!1}import yn from"ignore";function K(o,e){return e.length===0?!1:yn().add(e).ignores(o)}var Ee=class o{environment;_filePaths=[];mode;eventEmitter;config;diffMode;constructor(e,t,n,i){this.environment=t,this.mode=n,this.eventEmitter=i||new G,this.config=e}static async initialize(e,t,n,i,r,a){let s=new o(e,t,n,i);if(n==="diff"&&!r){let u=s.environment.getWorkspaceRoot(),m=a==null?void 0:a.include,g=a==null?void 0:a.commitSelector;if(!g||!m)throw new Error("Commit selector and include are required in diff mode");let h=await ct(u,{include:m,commitSelector:g}).catch(()=>{throw new Error("Diff mode requires a git repository. Please run this command from within a git repository.")});s.diffMode={gitChanges:h,changedFiles:h.files.map(v=>v.filename),fileChangeMap:new Map(h.files.map(v=>[v.filename,v]))},s.eventEmitter.fileDiscoveryProgress(`Found ${s.diffMode.changedFiles.length} changed files`)}let l=n==="check"?await s.loadGitIgnoredFiles():new Set,c=await s.discoverFiles(r,l);return s._filePaths=c,s}get filePaths(){return this._filePaths}filterFiles(e){let t=e.length,n;return this.mode==="check"?n=e:n=e.filter(i=>this.isFileValid({filePath:i})),t!==n.length&&this.eventEmitter.fileFilter(t,n.length,`${this.mode}-mode-files`),n}filterMatches(e){let t=e.length,n=e.filter(i=>this.isMatchValid({match:i}));return t!==n.length&&this.eventEmitter.fileFilter(t,n.length,`${this.mode}-mode-matches`),n}filterMatchesByFilePaths(e,t){if(e.length===0)return e;let n=new Set(t);return e.filter(i=>n.has(i.file.path))}get executionMode(){return this.mode}async loadGitIgnoredFiles(){let e=this.environment.getWorkspaceRoot(),t=await it(e).catch(()=>(this.eventEmitter.fileDiscoveryProgress("Not in a git repository, skipping git-ignored files"),[])),n=new Set(t);return t.length>0&&this.eventEmitter.fileDiscoveryProgress(`Found ${t.length} git-ignored files`),n}async discoverFiles(e,t){this.eventEmitter.startFileDiscovery(this.mode);let n;if(e)n=await this.discoverFilesFromPath(e,t);else if(this.mode==="diff"){let i=this.environment.getWorkspaceRoot();n=this.diffMode.changedFiles.filter(a=>te.existsSync(U.resolve(i,a))).map(a=>a);let r=this.config.getIgnoredGlobs();if(r.length>0){this.eventEmitter.fileDiscoveryProgress("Applying ignore patterns...");let a=n.length;n=n.filter(s=>!K(s,r)),a!==n.length&&this.eventEmitter.fileDiscoveryProgress(`Filtered out ${a-n.length} ignored files`)}}else{this.eventEmitter.fileDiscoveryProgress("Scanning workspace for files...");let i=this.environment.getWorkspaceRoot(),r=this.config.getIgnoredGlobs();n=await this.discoverAllFiles([i],r,t)}return this.eventEmitter.completeFileDiscovery(n.length,this.mode),n}async discoverFilesFromPath(e,t){let n=this.environment.getWorkspaceRoot(),i=U.resolve(n,e),r=this.config.getIgnoredGlobs();if(this.isGlobPattern(e))return this.eventEmitter.fileDiscoveryProgress(`Discovering files matching glob pattern: ${e}`),await this.discoverFilesFromGlob(e,r,t);if(!te.existsSync(i))throw new Error(`Path not found: ${e}`);let a=te.statSync(i);if(a.isFile())return this.eventEmitter.fileDiscoveryProgress(`Checking specific file: ${e}`),t.has(e)?(this.eventEmitter.fileDiscoveryProgress(`File ${e} is ignored by git`),[]):K(e,r)?(this.eventEmitter.fileDiscoveryProgress(`File ${e} is ignored by patterns`),[]):[e];if(a.isDirectory())return this.eventEmitter.fileDiscoveryProgress(`Discovering files in directory: ${e}`),await this.discoverFilesFromDirectory(e,r,t);throw new Error(`Path is neither a file nor directory: ${e}`)}isGlobPattern(e){return/[*?[\]{}]/.test(e)}async discoverFilesFromGlob(e,t,n){let i=this.environment.getWorkspaceRoot(),r=["**/node_modules/**","**/.git/**",...t],s=(await He(e,{cwd:i,nodir:!0,absolute:!1,ignore:r})).filter(l=>!n.has(l));return this.eventEmitter.fileDiscoveryProgress(`Found ${s.length} files matching pattern`),s}async discoverFilesFromDirectory(e,t,n){let i=this.environment.getWorkspaceRoot(),r=U.join(e,"**/*").replace(/\\/g,"/"),a=["**/node_modules/**","**/.git/**",...t],l=(await He(r,{cwd:i,nodir:!0,absolute:!1,ignore:a})).filter(c=>!n.has(c));return this.eventEmitter.fileDiscoveryProgress(`Found ${l.length} files in directory`),l}async discoverAllFiles(e,t,n){let i=[],r=this.environment.getWorkspaceRoot(),a=["**/node_modules/**","**/.git/**",...t];for(let s of e){if(!te.statSync(s).isDirectory()){let m=U.relative(r,s),g=n.has(m),h=K(m,t);!g&&!h&&i.push(m);continue}let u=(await He("**/*",{cwd:s,nodir:!0,absolute:!1,ignore:a})).map(m=>{let g=U.resolve(s,m);return U.relative(r,g)}).filter(m=>!n.has(m));i.push(...u)}return[...new Set(i)]}isFileValid(e){if(this.mode==="check")return!0;let{filePath:t}=e;return Ke(t,{changedFiles:this.diffMode.changedFiles,fileChangeMap:this.diffMode.fileChangeMap})}isMatchValid(e){if(this.mode==="check")return!0;let{match:t}=e;return ut(t,{changedFiles:this.diffMode.changedFiles,fileChangeMap:this.diffMode.fileChangeMap})}};import*as ne from"fs";import*as j from"path";var Re=class{environment;constructor(e){this.environment=e}evaluateCondition(e,t){let n=this.environment.getWorkspaceRoot(),i=j.resolve(n,t);if("fs.siblingExists"in e){let{filename:r}=e["fs.siblingExists"],a=j.dirname(i),s=j.join(a,r);return ne.existsSync(s)}if("fs.ancestorHas"in e){let{filename:r}=e["fs.ancestorHas"],a=j.dirname(i),s=j.parse(a).root;for(;a!==s;){let l=j.join(a,r);if(ne.existsSync(l))return!0;let c=j.dirname(a);if(c===a)break;a=c}return!1}if("fs.siblingAny"in e){let{pattern:r}=e["fs.siblingAny"],a=j.dirname(i);return ne.existsSync(a)?ne.readdirSync(a).some(l=>K(l,[r])):!1}return!1}evaluateConditions(e,t){let n=[];return e.all&&e.all.length>0&&n.push(e.all.every(i=>this.evaluateCondition(i,t))),e.any&&e.any.length>0&&n.push(e.any.some(i=>this.evaluateCondition(i,t))),e.not&&e.not.length>0&&n.push(!e.not.some(i=>this.evaluateCondition(i,t))),n.length===0?!0:n.every(i=>i===!0)}async execute(e,t){var a,s;let n=Date.now(),i=e;(a=t.include)!=null&&a.length&&(i=i.filter(l=>K(l,t.include))),(s=t.ignore)!=null&&s.length&&(i=i.filter(l=>!K(l,t.ignore))),Object.keys(t.conditions||{}).length>0&&i.length>0&&(i=i.filter(l=>this.evaluateConditions(t.conditions,l)));let r=Date.now()-n;return await Promise.resolve({filteredPaths:i,executionTime:r})}};import yi from"path";import{existsSync as Je}from"fs";import{createRequire as wn}from"module";import de from"path";import bn from"@ast-grep/lang-angular";import $n from"@ast-grep/lang-bash";import Mn from"@ast-grep/lang-c";import Sn from"@ast-grep/lang-cpp";import Pn from"@ast-grep/lang-csharp";import En from"@ast-grep/lang-css";import Rn from"@ast-grep/lang-dart";import Ln from"@ast-grep/lang-elixir";import In from"@ast-grep/lang-go";import Cn from"@ast-grep/lang-haskell";import kn from"@ast-grep/lang-html";import Fn from"@ast-grep/lang-java";import Dn from"@ast-grep/lang-javascript";import Tn from"@ast-grep/lang-json";import _n from"@ast-grep/lang-kotlin";import An from"@ast-grep/lang-lua";import On from"@ast-grep/lang-markdown";import Nn from"@ast-grep/lang-php";import Gn from"@ast-grep/lang-python";import Bn from"@ast-grep/lang-ruby";import jn from"@ast-grep/lang-rust";import Wn from"@ast-grep/lang-scala";import Un from"@ast-grep/lang-sql";import Vn from"@ast-grep/lang-swift";import qn from"@ast-grep/lang-toml";import zn from"@ast-grep/lang-tsx";import Kn from"@ast-grep/lang-typescript";import Hn from"@ast-grep/lang-yaml";import{registerDynamicLanguage as Jn}from"@ast-grep/napi";console.debug=()=>{};var Yn=wn(import.meta.url?import.meta.url:__filename);function Qn(){let o=de.dirname(Yn.resolve("tree-sitter-graphql")),e=de.join(o,"../../build/Release/tree_sitter_graphql_binding.node");if(Je(e))return e;let t=de.join(o,"../../build/Debug/tree_sitter_graphql_binding.node");if(Je(t))return t;let n=de.join(o,"parser.so");return Je(n)?n:null}var gt=Qn(),Xn={libraryPath:gt,extensions:["graphql"],languageSymbol:"tree_sitter_graphql",metaVarChar:"$",expandoChar:void 0},pt={Angular:bn,Bash:$n,C:Mn,Cpp:Sn,Csharp:Pn,Css:En,Dart:Rn,Elixir:Ln,Go:In,Haskell:Cn,Html:kn,Java:Fn,JavaScript:Dn,Json:Tn,Kotlin:_n,Lua:An,Markdown:On,Php:Nn,Python:Gn,Ruby:Bn,Rust:jn,Scala:Wn,Sql:Un,Swift:Vn,Toml:qn,Tsx:zn,TypeScript:Kn,Yaml:Hn,...gt?{GraphQL:Xn}:{}};Jn(pt);var mt=Object.entries(pt).reduce((o,[e,t])=>(o[e]=t.extensions??[],o),{});function ft(o){let e=de.extname(o).slice(1);return Zn(e)??"Unknown"}function Zn(o){return Object.keys(mt).find(e=>mt[e].includes(o))}import{readFile as Mt}from"fs/promises";import St from"path";import{parse as ui,parseAsync as mi}from"@ast-grep/napi";import{spawn as ri}from"child_process";import si from"crypto";import ie from"fs";import V,{dirname as vt,join as yt}from"path";import{glob as oi}from"glob";import{promises as ei}from"fs";import fs from"path";async function Le(o){try{return await ei.access(o),!0}catch{return!1}}import{execSync as ti}from"child_process";function ht(){return ti("which rg").toString().trim()}import Ie from"fs";import ni from"path";async function dt(o){try{if(o.includes("/")||o.includes("\\"))return await Ie.promises.access(o,Ie.constants.X_OK),!0;let e=process.env.PATH||"",t=process.platform==="win32"?";":":",n=e.split(t),i=process.platform==="win32"?(process.env.PATHEXT||".exe;.cmd;.bat").split(";"):[""];for(let r of n)for(let a of i){let s=ni.join(r,o+a);try{return await Ie.promises.access(s,Ie.constants.X_OK),!0}catch{}}return!1}catch{return!1}}import ii from"ignore";function xt(o){let e=o.match(/\{([^}]+)\}/);if(!e)return[o];let t=e[1].split(","),n=o.slice(0,e.index),i=o.slice(e.index+e[0].length),r=[];for(let a of t){let s=n+a+i;r.push(...xt(s))}return r}function xe(o,e){if(e.length===0)return!1;let t=[];for(let i of e)t.push(...xt(i));return ii().add(t).ignores(o)}function Ce(o,e){let t=new RegExp(e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g");return o.replace(t,"").replace(/\/\//g,"/")}async function ve(o){return await new Promise((e,t)=>{let n=si.createHash("sha256"),i=ie.createReadStream(o);i.on("error",r=>t(r)),i.on("data",r=>n.update(r)),i.on("end",()=>e(n.digest("hex")))})}function ke(o,e){try{let t=V.resolve(o),n=V.resolve(o,e),i=V.normalize(t),r=V.normalize(n);return r===i||r.startsWith(i+V.sep)?r:null}catch{return null}}function ai(o,e,t){try{let i=ie.readFileSync(o,"utf8").split(`
|
|
12
|
+
`),r=Math.max(0,e-1),a=Math.min(i.length,t);if(r===0&&a>=i.length)return i.map((u,m)=>`L${m+1} ${u}`).join(`
|
|
13
|
+
`);let s=i.slice(r,a),l="";r>0&&(l+=`[Lines 1-${r} omitted]
|
|
14
|
+
`);let c=s.map((u,m)=>`L${r+m+1} ${u}`);return l+=c.join(`
|
|
15
|
+
`),a<i.length&&(l+=`
|
|
16
|
+
[Lines ${a+1}-${i.length} omitted]`),l}catch(n){let i=n instanceof Error?n.message:String(n);throw new Error(`Failed to read file ${o}: ${i}`)}}async function wt(o,e,t=[]){var l,c;let{target_file:n}=o,i=o.offset?parseInt((l=o.offset)==null?void 0:l.toString(),10):void 0,r=o.limit?parseInt((c=o.limit)==null?void 0:c.toString(),10):void 0,a=n.startsWith("/")?n.slice(1):n;if(xe(a,t))return{error:`File not found or not accessible: ${n}. Please provide the correct path.`};let s=ke(e,a);if(!s)return{error:`Invalid file path: '${n}'`};if(!await Le(s))return{error:`File not found or not accessible: ${n}. Please provide the correct path. It could also have been deleted as part of the PR.`};try{if(i!==void 0&&(Number.isNaN(Number(i))||i<0))return{error:`Invalid offset: ${i}. Offset must be a non-negative number starting from 0.`};if(r!==void 0&&(Number.isNaN(Number(r))||r<1))return{error:`Invalid limit: ${r}. Limit must be a positive number.`};let u=i??1,g=Math.min(r??200,500),h=u+g-1,v=ai(s,u,h),M=await ve(s);return{content:v,sha:M}}catch(u){let m=u.message||String(u);return{error:Ce(`Error reading file: ${m}`,e)}}}async function li(o,e,t,n="."){let i=["--no-config","--line-number","--color=never","--max-columns=300","--max-filesize=1M","--max-count=50","-i"];t&&i.push("-g",t),i.push(e),i.push(n);try{let r=await new Promise((l,c)=>{var v,M;let u=ri(o,i,{cwd:n,shell:!1,stdio:["ignore","pipe","pipe"],env:{LANG:"C",RIPGREP_CONFIG_PATH:""}}),m="",g="";(v=u.stdout)==null||v.on("data",E=>{m+=E.toString()}),(M=u.stderr)==null||M.on("data",E=>{g+=E.toString()});let h=setTimeout(()=>{u.kill("SIGTERM"),c(new Error("rg search operation timed out"))},3e4);u.on("close",E=>{clearTimeout(h),E===1&&!g?l({stdout:"",stderr:""}):E===0||E===1&&!g?l({stdout:m,stderr:g}):c(new Error(`ripgrep exited with code ${E}: ${g}`))}),u.on("error",E=>{clearTimeout(h),c(E)})});if(!r.stdout.trim())return[];let a=r.stdout.trim().split(`
|
|
17
|
+
`),s=[];for(let l of a){let c=l.match(/^([^:]+):(\d+):(.*)$/);if(c){let[,u,m,g]=c,h=u;h=V.relative(n,u);let v=V.join(n,h);try{if(ie.existsSync(v)){let M=await ve(v);s.push({file:h,line_number:parseInt(m,10),content:g,sha:M})}}catch{}}}return s}catch(r){let a=r;if(a.code===1&&!a.stderr)return[];throw a.signal==="SIGTERM"?new Error("rg search operation timed out"):r}}async function bt(o,e,t=[]){var s;let{pattern:n,include:i}=o,r=ht(),a=(s=o.path)!=null&&s.startsWith("/")?o.path.slice(1):o.path;try{if(!await dt(r))throw new Error(`ripgrep is not found or not executable: ${r}`);let c=null;if(a){let g=ke(e,a);if(!g)return{error:`Invalid path: '${a}'. Please provide the correct path.`};if(!await Le(g))return{error:`Path not found or not accessible: ${a}. Please provide the correct path.`};let h=await ie.promises.stat(g);if(h.isFile())c=vt(g),a=vt(a);else if(h.isDirectory())c=g;else return{error:`Path is neither a file nor a directory: ${a}`}}return{matches:(await li(r,n,i,c||e)).filter(g=>{let h=a?yt(a,g.file):g.file;return!xe(h,t)}).slice(0,50).map(g=>({...g,file:a?yt(a,g.file):g.file}))}}catch(l){let c=typeof l=="object"&&l!==null&&"message"in l&&typeof l.message=="string"?l.message:String(l);return{error:Ce(c,e)}}}async function $t(o,e,t=[]){let n=o.pattern,i=o.path;i&&n.startsWith(i)&&(n=n.replace(i,"")),n=n.startsWith("/")?n.slice(1):n;let r;if(i){if(i=i.startsWith("/")?i.slice(1):i,i!=="."&&xe(i,t))return{files:[]};let a=ke(e,i);if(!a)return{error:`Path not found or not accessible: '${i}'. Please provide the correct path.`};r=a}else r=e;if(!await Le(r))return{error:`Directory not found or not accessible: ${i||"."}. Please provide the correct path.`};try{if(!(await ie.promises.stat(r)).isDirectory())return{error:`Not a directory: ${i||"."}. Please provide the correct path.`}}catch{return{error:`Directory not found or not accessible: ${i||"."}. Please provide the correct path.`}}try{return{files:(await ci(n,i,e)).filter(l=>!xe(l,t)).slice(0,50)}}catch(a){let s=typeof a=="object"&&a!==null&&"message"in a&&typeof a.message=="string"?a.message:String(a);return{error:Ce(s,e)}}}async function ci(o,e,t){try{let n;if(e){let a=e.startsWith("/")?e.slice(1):e,s=ke(t,a);if(!s)throw new Error(`Invalid directory path: potential directory traversal detected in '${a}'`);n=s}else n=t;let i=await oi(o,{cwd:n,nodir:!0,ignore:["node_modules/**",".git/**","**/__pycache__/**"],absolute:!1}),r=[];for(let a of i)try{let s=V.join(n,a),l=await ie.promises.stat(s);l.isFile()&&r.push({path:e?V.join(e,a):a,mtime:l.mtime})}catch{}return r.sort((a,s)=>s.mtime.getTime()-a.mtime.getTime()),r.map(a=>a.path)}catch(n){let i=n instanceof Error?n.message:String(n);throw new Error(Ce(`Glob search failed: ${i}`,t))}}function ye(o){return{...o,range:{start:{line:o.range.start.line-1,column:o.range.start.column-1},end:{line:o.range.end.line-1,column:o.range.end.column-1}}}}function re(o){return{...o,range:{start:{line:o.range.start.line+1,column:o.range.start.column+1},end:{line:o.range.end.line+1,column:o.range.end.column+1}}}}var Fe=class{environment;language;constructor(e,t){this.environment=e,this.language=t}async findMatches(e,t){if(e.length===0)return[];let{rule:n,constraints:i}=t,r=this.getBatchSize(),a=[];for(let s=0;s<e.length;s+=r){let l=e.slice(s,s+r),c=await this.processBatch(l,n,i);a.push(...c)}return a}getBatchSize(){let e=parseInt(process.env.UV_THREADPOOL_SIZE||"4",10);return Math.max(2,Math.floor(e/2))}async processBatch(e,t,n){let i=e.map(async l=>{let c=St.resolve(this.environment.getWorkspaceRoot(),l),u=await Mt(c,"utf-8"),g=(await mi(this.language,u)).root().findAll({rule:t,language:this.language,constraints:n});if(g.length===0)return[];let h=await ve(c);return g.map(v=>({filePath:l,sgNode:v,sha:h}))}),a=(await Promise.all(i)).flat(),s=[];for(let{filePath:l,sgNode:c,sha:u}of a){let m=c.range(),g={file:{path:l,sha:u},text:c.text(),range:{start:{line:m.start.line,column:m.start.column},end:{line:m.end.line,column:m.end.column}},language:this.language};s.push(re(g))}return s}extractSymbol(e){let t=e.kind();if(t==="call_expression"){let n=e.field("function");if(n)return this.extractSymbol(n)}else if(t==="member_expression"){let n=e.field("property");if(n)return n.text()}else if(t==="identifier")return e.text()}async expandMatch(e){let t=new Set(["method_definition","function_declaration","function_expression","arrow_function","class_declaration","export_statement","lexical_declaration"]),n=St.resolve(this.environment.getWorkspaceRoot(),e.file.path),[i,r]=await Promise.all([Mt(n,"utf-8"),ve(n)]),a=ui(this.language,i).root(),s=ye(e),l=this.findNodeAtPosition(a,s.range.start.line,s.range.start.column);if(!l)return null;let c=l;for(;c;){let u=c.kind(),m=typeof u=="string"?u:String(u);if(t.has(m)){let g=c.range(),h={file:{path:e.file.path,sha:r},text:c.text(),range:{start:{line:g.start.line,column:g.start.column},end:{line:g.end.line,column:g.end.column}},language:this.language};return re(h)}c=c.parent()}return null}findNodeAtPosition(e,t,n){let i=e.range(),r=t>i.start.line||t===i.start.line&&n>=i.start.column,a=t<i.end.line||t===i.end.line&&n<=i.end.column;if(!r||!a)return null;let s=e.children();for(let l of s){let c=this.findNodeAtPosition(l,t,n);if(c)return c}return e}};import{spawn as fi}from"child_process";import Ye from"fs/promises";import{createRequire as hi}from"module";import di from"os";import Et from"path";import{readFile as gi}from"fs/promises";import pi from"path";async function se(o,e,t,n=!1){let i=pi.resolve(o,e),a=(await gi(i,"utf-8")).split(`
|
|
18
|
+
`),{start:s,end:l}=t,c=s.line-1,u=l.line-1;if(s.line===l.line){let g=a[c]||"";return n?g.substring(s.column-1,l.column-1):g}let m=[];for(let g=c;g<=u&&g<a.length;g++){let h=a[g];g===c?m.push(n?h.substring(s.column-1):h):g===u?m.push(n?h.substring(0,l.column-1):h):m.push(h)}return m.join(`
|
|
19
|
+
`)}var xi=hi(import.meta.url?import.meta.url:__filename),{scip:De}=xi("@sourcegraph/scip-root/bindings/typescript/scip.js"),Pt=/^\+ (.+?) \((\d+)ms\)$/;function vi(o,e,t,n,i){let r=o.toString();e+=r;let a=e.split(`
|
|
20
|
+
`),s=a.pop()||"",l=null;for(let c of a){let u=c.trim();u.match(Pt)&&(l=u)}for(let c of a){let u=c.trim();if(!u)continue;let m=u.match(Pt);if(m){if(u===l){let[,g,h]=m,v=Et.relative(i,g);t.indexingProgress(n,`Indexed ${v}`,v,parseInt(h,10))}}else t.indexingProgress(n,u)}return s}var Te=class{environment;storage;language;scipIndex=null;indexingPromise=null;eventEmitter;constructor(e,t,n){this.environment=e,this.storage=new ee(e),this.language=t,this.eventEmitter=n||new G}getScipCommand(){switch(this.language){case"TypeScript":case"JavaScript":case"Tsx":return"scip-typescript";case"Python":return"scip-python";default:throw new Error(`SCIP is not supported for language: ${this.language}`)}}async ensureIndexReady(){if(this.scipIndex===null){if(this.indexingPromise!==null)return this.indexingPromise;this.indexingPromise=this.startIndexing(),await this.indexingPromise}}async startIndexing(){if(await this.storage.indexExists(this.language,"index.scip")){await this.loadIndex();return}let e=await this.storage.getIndexFilePath(this.language,"index.scip"),t=Et.join(di.tmpdir(),`scip-index-${this.language}-${Date.now()}.tmp`);this.eventEmitter.startIndexing(this.language);let n=this.getScipCommand(),i=fi(n,["index","--output",t],{cwd:this.environment.getWorkspaceRoot(),stdio:["ignore","pipe","pipe"],env:process.env}),r="";i.stdout.on("data",s=>{r=vi(s,r,this.eventEmitter,this.language,this.environment.getWorkspaceRoot())});let a="";i.stderr.on("data",s=>{a+=s.toString(),process.stderr.write(s)}),await new Promise((s,l)=>{i.on("close",async c=>{c===0?(await Ye.rename(t,e),s()):(await Ye.unlink(t).catch(()=>{}),l(new Error(`${n} index exited with code ${c}, stderr: ${a}`)))}),i.on("error",async c=>{await Ye.unlink(t).catch(()=>{}),l(c)})}),a&&console.error("SCIP indexing stderr:",a),this.eventEmitter.completeIndexing(this.language),await this.loadIndex()}async findDefinitions(e){if(await this.ensureIndexReady(),!this.scipIndex)throw new Error("SCIP index not ready");let t=ye(e);this.eventEmitter.startScipMatchLookup(this.language,t);let n=[],i=this.scipIndex.documents;for(let r of i){if(r.relative_path!==t.file.path)continue;this.eventEmitter.scipMatchLookupProgress(this.language,r);let a=this.findBestOverlappingOccurrence(r.occurrences,t);if(a){if(this.isExternalSymbol(a.symbol))continue;this.eventEmitter.scipMatchLookupProgress(this.language,a);let s=await this.findDefinitionForSymbol(a.symbol,i);s&&n.push(re(s))}}return n}async findReferences(e){if(await this.ensureIndexReady(),!this.scipIndex)return[];let t=ye(e),n=[],i=this.scipIndex.documents;for(let r of i){if(r.relative_path!==t.file.path)continue;let a=this.findBestOverlappingOccurrence(r.occurrences,t);if(a){if(this.isExternalSymbol(a.symbol))break;let s=await this.findReferencesForSymbol(a.symbol,i);n.push(...s.map(l=>re(l)));break}}return n}isExternalSymbol(e){return e.includes("node_modules")||e.startsWith("npm/")}findBestOverlappingOccurrence(e,t){let n=[];for(let i of e){let r=i.range;if(!r||r.length<3||!this.rangesOverlap(r,t))continue;let a=0;if(!this.rangeFullyInside(r,t))continue;let s=(r.length===3,r[1]);a+=s*1e3,i.symbol_roles!==De.SymbolRole.Definition&&(a+=100),n.push({occurrence:i,score:a})}return n.length===0?null:(n.sort((i,r)=>r.score-i.score),n[0].occurrence)}rangesOverlap(e,t){if(e.length===3){let[n,i,r]=e;return t.range.start.line===t.range.end.line?n===t.range.start.line&&!(r<=t.range.start.column||i>=t.range.end.column):!(n<t.range.start.line||n>t.range.end.line||n===t.range.start.line&&r<=t.range.start.column||n===t.range.end.line&&i>=t.range.end.column)}else if(e.length===4){let[n,i,r,a]=e;return!(r<t.range.start.line||n>t.range.end.line)}return!1}rangeFullyInside(e,t){if(e.length===3){let[n,i,r]=e;return!(n<t.range.start.line||n>t.range.end.line||n===t.range.start.line&&i<t.range.start.column||n===t.range.end.line&&r>t.range.end.column)}else if(e.length===4){let[n,i,r,a]=e;return!(n<t.range.start.line||r>t.range.end.line||n===t.range.start.line&&i<t.range.start.column||r===t.range.end.line&&a>t.range.end.column)}return!1}extractSymbolNames(e){let t=e.match(/`([^`]+)`#([^#./`(]+)(?:\(\))?[.`]*$/);if(t)return{className:t[1],methodName:t[2]};let n=e.match(/([^#./`(]+)(?:\(\))?[.`]*$/);return n?{className:null,methodName:n[1]}:{className:null,methodName:null}}async findDefinitionForSymbol(e,t){for(let n of t)for(let i of n.occurrences)if(i.symbol===e&&i.symbol_roles===De.SymbolRole.Definition){let r=i.range??[],a=r[0]??0,s=r[1]??0,l=r.length===4?r[2]:a,c=r.length===4?r[3]:r[2]??s,u=await se(this.environment.getWorkspaceRoot(),n.relative_path,{start:{line:a,column:s},end:{line:l,column:c}});return{language:this.language,file:{path:n.relative_path,sha:""},range:{start:{line:a,column:s},end:{line:l,column:c}},text:u}}return null}async findReferencesForSymbol(e,t){let n=[];for(let i of t)for(let r of i.occurrences)if(r.symbol===e&&r.symbol_roles!==De.SymbolRole.Definition){let a=r.range??[],s=a[0]??0,l=a[1]??0,c=a.length===4?a[2]:s,u=a.length===4?a[3]:a[2]??l,m=await se(this.environment.getWorkspaceRoot(),i.relative_path,{start:{line:s,column:l},end:{line:c,column:u}});n.push({language:this.language,file:{path:i.relative_path,sha:""},range:{start:{line:s,column:l},end:{line:c,column:u}},text:m})}return n}async loadIndex(){let e=await this.storage.readIndex(this.language,"index.scip");if(!e)throw new Error(`Index not found for language: ${this.language}`);this.scipIndex=this.parseIndex(new Uint8Array(e))}parseIndex(e){return De.Index.deserialize(e)}};var oe=class extends Error{constructor(e,t){super(`${e} is not supported: ${t}`),this.name="LanguageBackendNotSupportedError"}},ae=class{astProvider;intelligenceProvider;language;constructor(e,t,n){this.language=t,this.astProvider=new Fe(e,t),this.intelligenceProvider=new Te(e,t,n)}async findMatches(e,t){if(!this.astProvider)throw new oe("findMatches","no AST provider configured for this language");return await this.astProvider.findMatches(e,t)}async findDefinitions(e){if(!this.intelligenceProvider)throw new oe("findDefinitions","no intelligence provider configured for this language");return await this.intelligenceProvider.findDefinitions(e)}async findReferences(e){if(!this.intelligenceProvider)throw new oe("findReferences","no intelligence provider configured for this language");return await this.intelligenceProvider.findReferences(e)}async expandMatch(e){if(!this.astProvider)throw new oe("expandMatch","no AST provider configured for this language");return await this.astProvider.expandMatch(e)}};var _e=class{environment;eventEmitter;constructor(e,t){this.environment=e,this.eventEmitter=t}async execute(e,t,n){let i=Date.now(),r=n.filePaths.filter(m=>ft(m)===t),l=(await new ae(this.environment,t,this.eventEmitter).findMatches(r,e)).map(m=>{if(yi.isAbsolute(m.file.path))throw new Error(`Match provider returned absolute path: ${m.file.path}. All file paths must be relative to workspace root.`);return{...m,language:t}}),c=n.previousMatches&&n.previousMatches.length>0?this.filterMatchesByRanges(l,n.previousMatches,t):l;c=this.deduplicateMatches(c);let u=Date.now()-i;return{matches:c,totalMatches:c.length,executionTime:u}}filterMatchesByRanges(e,t,n){let i=[];for(let r of e){let a=t.find(l=>this.isMatchInRange(r,l));if(!a)continue;let s=[...a.evidence||[],{file:a.file,text:a.text,range:a.range,language:a.language}];i.push({...r,evidence:s})}return i}isMatchInRange(e,t){if(e.file.path!==t.file.path)return!1;let n=e.range.start,i=e.range.end,r=t.range.start,a=t.range.end,s=n.line>r.line||n.line===r.line&&n.column>=r.column,l=i.line<a.line||i.line===a.line&&i.column<=a.column;return s&&l}deduplicateMatches(e){if(e.length<=1)return e;let t=[];for(let n of e)e.some(r=>n===r?!1:this.isMatchInRange(n,r))||t.push(n);return t}};import wi from"path";import bi from"ignore";var Ae=class{maxDepth=1;environment;eventEmitter;constructor(e,t){this.environment=e,this.eventEmitter=t||new G}async execute(e,t,n={}){let i=Date.now(),r=new ae(this.environment,t,this.eventEmitter),a=await this.followDefinitions(e,r,this.maxDepth,n.where,t),s=Date.now()-i,l=a.map(c=>{let{depth:u,sourceMatch:m,...g}=c,h=m?[{file:m.file,text:m.text,range:m.range,language:m.language},...m.evidence||[]]:[];return{...g,source:h}});return{definitions:l,totalDefinitions:l.length,executionTime:s}}async followDefinitions(e,t,n,i,r){let a=[],s=new Set;for(let l of e)await this.followDefinitionsRecursive(l,t,0,n,i,a,s,l,r);return a}async followDefinitionsRecursive(e,t,n,i,r,a,s,l,c){if(n>=i)return;let u=`${e.file.path}:${e.range.start.line}:${e.range.start.column}`;if(s.has(u))return;s.add(u);let m=await t.findDefinitions(e);for(let g of m){let v={...await t.expandMatch(g)??g,language:c,depth:n,sourceMatch:l||e};r&&!this.matchesDefinitionFilter(v,r)||(a.push(v),n+1<i&&await this.followDefinitionsRecursive(g,t,n+1,i,r,a,s,l||e,c))}}matchesDefinitionFilter(e,t){var n;return t.all?t.all.every(i=>this.matchesDefinitionFilter(e,i)):t.any?t.any.some(i=>this.matchesDefinitionFilter(e,i)):t.not?!this.matchesDefinitionFilter(e,t.not):!(t.file&&!this.matchesFileSpec(e.file.path,t.file)||(n=t.function)!=null&&n.name)}matchesNameSpec(e,t){return t.equals?e===t.equals:t.anyOf?t.anyOf.includes(e):t.regex?new RegExp(t.regex).test(e):!0}matchesFileSpec(e,t){let n=wi.relative(this.environment.getWorkspaceRoot(),e);return t.path?n===t.path:t.glob?bi().add(t.glob).ignores(n):t.regex?new RegExp(t.regex).test(n):!0}};import q from"big.js";var Oe=class{environment;eventEmitter;config;maxIterations;constructor(e,t,n,i){this.environment=t,this.eventEmitter=n||new G,this.config=e,this.maxIterations=i||20}async executeTool(e,t,n,i){switch(t){case"read":{this.eventEmitter.llmToolExecution(e,"read",{file:n.target_file,offset:n.offset,limit:n.limit});let r=await wt(n,this.environment.getWorkspaceRoot());if(!("error"in r)){let a=n.target_file;i.some(s=>s.path===a)||i.push({path:a,sha:r.sha})}return"error"in r?r:r.content}case"grep":{this.eventEmitter.llmToolExecution(e,"grep",{path:n.path,pattern:n.pattern});let r=await bt(n,this.environment.getWorkspaceRoot());if(!("error"in r))for(let a of r.matches)i.some(s=>s.path===a.file)||i.push({path:a.file,sha:a.sha});return"error"in r?r:JSON.stringify(r.matches)}case"glob":{this.eventEmitter.llmToolExecution(e,"glob",{path:n.path,pattern:n.pattern});let r=await $t(n,this.environment.getWorkspaceRoot());return"error"in r?r:JSON.stringify(r.files)}default:return{error:`Unknown tool: ${t}`}}}async hydrateMatchesWithFileContent(e){let t=[];for(let n of e){let i=await se(this.environment.getWorkspaceRoot(),n.file.path,n.range),r=n.evidence;if(n.evidence&&n.evidence.length>0){r=[];for(let a of n.evidence){let s=await se(this.environment.getWorkspaceRoot(),a.file.path,a.range);r.push({...a,text:s})}}t.push({...n,text:i,evidence:r})}return t}async executeLLMValidation(e,t,n){let i=Date.now(),r=this.config.getLLMProvider();this.eventEmitter.startLLMValidation(e.id,t.length);let a=[],s=[],l=new q(0),c=new q(0),u=new q(0),m;for(let E=0;E<this.maxIterations;E++){let C=await r.search({rule:e,matches:t,tools:n,messages:a,files:s});if(C.usage&&(l=l.plus(new q(C.usage.inputTokens)),c=c.plus(new q(C.usage.outputTokens)),u=u.plus(new q(C.usage.cost))),C.type==="matches"){let R=await this.hydrateMatchesWithFileContent(C.matches);m={...C,matches:R};break}if(C.type==="request_files"){for(let R of C.files)s.some(b=>b.path===R.path)||s.push({path:R.path,sha:R.sha});continue}if(C.type==="tool_request"){a.push({type:"tool_request",tool_calls:C.tool_calls});let R=await Promise.all(C.tool_calls.map(async b=>{let L=JSON.parse(b.function.arguments),x=await this.executeTool(e.id,b.function.name,L,s),d=typeof x=="string"?x:JSON.stringify(x);return{tool_call_id:b.id,content:d}}));for(let b of R)a.push({type:"tool_response",tool_call_id:b.tool_call_id,content:b.content});continue}}if(!m)throw new Error(`Max iterations (${this.maxIterations}) reached without getting matches`);let g=m.matches;if(g.length===0){let E=l.plus(c).toNumber();return this.eventEmitter.completeLLMValidation(e.id,E,l.toNumber(),c.toNumber(),u.toString(),Date.now()-i,0,!1),{matches:[],executionTime:Date.now()-i}}this.eventEmitter.startLLMValidationPhase(e.id,g.length);let h=await r.validate({rule:e,matches:g,files:s});h.usage&&(l=l.plus(new q(h.usage.inputTokens)),c=c.plus(new q(h.usage.outputTokens)),u=u.plus(new q(h.usage.cost)));let v=await this.hydrateMatchesWithFileContent(h.matches),M=l.plus(c).toNumber();return this.eventEmitter.completeLLMValidation(e.id,M,l.toNumber(),c.toNumber(),u.toString(),Date.now()-i,v.length,!1),{matches:v,executionTime:Date.now()-i}}async execute(e,t,n){return t.length===0?{matches:[],executionTime:0}:await this.executeLLMValidation(e,t,n)}};var Ne=class{fileFilterStep;findMatchesStep;gotoDefinitionStep;llmStep;environment;executionContext;currentMode;eventEmitter;config;constructor(e,t,n){this.environment=t,this.eventEmitter=n||new G,this.config=e,this.fileFilterStep=new Re(this.environment),this.findMatchesStep=new _e(this.environment,this.eventEmitter),this.gotoDefinitionStep=new Ae(this.environment,this.eventEmitter),this.llmStep=new Oe(this.config,this.environment,this.eventEmitter)}async executeStep(e,t,n,i,r,a,s){let l=n.type;if(l==="ast-grep"){let{type:c,language:u,...m}=n;return{matches:(await this.findMatchesStep.execute(m,u,{filePaths:i,previousMatches:r})).matches}}if(l==="step-group")throw new Error("step-group step is disabled");if(l==="file-filter")return{filePaths:(await this.fileFilterStep.execute(i,{include:n.include,ignore:n.ignore,conditions:n.conditions})).filteredPaths};if(l==="goto-definition")throw new Error("goto-definition step is disabled");if(l==="llm")return r.length===0?{matches:[]}:{matches:(await this.llmStep.execute(e,r,n.tools??[])).matches};throw new Error(`Unknown step type: ${l}`)}async executeRule(e,t){let n=e.id,i=e.config,r=[...this.executionContext.filePaths],a=[];for(let l of i.steps){let c=l.id,u=l.step;this.eventEmitter.startStep(n,c,u.type,{filePaths:r,matches:a});let m=Date.now(),g=await this.executeStep(e,c,u,r,a,t),h=Date.now()-m;if(this.eventEmitter.completeStep(n,c,u.type,g,h),g.filePaths!==void 0&&(r=this.executionContext.filterFiles(g.filePaths),a=this.executionContext.filterMatchesByFilePaths(a,r)),g.matches!==void 0&&(a=this.executionContext.filterMatches(g.matches)),r.length===0)break}let s=a.sort((l,c)=>l.file.path.localeCompare(c.file.path));return{ruleId:n,matches:s}}getPoolSize(){let e=$i().length;return Math.max(2,Math.min(8,e))}async execute(e,t){if(this.currentMode&&this.currentMode!==t.mode)throw new Error(`Execution mode mismatch: expected ${this.currentMode}, got ${t.mode}`);(!this.executionContext||this.currentMode!==t.mode)&&(this.executionContext=await Ee.initialize(this.config,this.environment,t.mode,this.eventEmitter,t.filePath,t.diffOptions),this.currentMode=t.mode),this.eventEmitter.startRules(e.length);let n=this.getPoolSize(),i=[],r=[...e],a=async u=>{let m=u.id,g=!1;for(let v of u.config.steps)if(v.step.type==="llm"){g=!0;break}this.eventEmitter.emit("rules:rule-start",{ruleId:m,isLlm:g,message:u.config.message,severity:u.config.severity});let h=await this.executeRule(u,t);return this.eventEmitter.emit("rules:rule-complete",{ruleId:m}),h};await(async()=>{let u=async()=>{if(r.length===0)return;let g=r.shift(),h=await a(g);i.push(h),await u()},m=[];for(let g=0;g<Math.min(n,e.length);g++)m.push(u());await Promise.all(m)})();let l=new Map(e.map((u,m)=>[u.id,m]));i.sort((u,m)=>{let g=l.get(u.ruleId)??0,h=l.get(m.ruleId)??0;return g-h});let c=i.reduce((u,m)=>u+m.matches.length,0);return this.eventEmitter.completeRules(e.length,c),i}};var Ge=class extends Error{constructor(t,n,i){super(`Invalid rule format in '${t}': ${n}`);this.validationErrors=i;this.name="InvalidRuleFormatError"}};import{stripVTControlCharacters as Ct}from"node:util";import f from"chalk";import Mi from"ora";var H="#f87171",J="#60a5fa",Si="#9b59b6",D="#fbbf24",Qe="#9ca3af",be="#9b59b6",Be="\u25A0",we="\u25CF",$e="\u2B25";function Pi(o,e){if(e){let t=`https://app.wispbit.com/rules/${e}`;return f.dim(`\x1B]8;;${t}\x1B\\${o}\x1B]8;;\x1B\\`)}return f.dim(o)}function kt(o,e){return o.length<=e?o:o.substring(0,e-3)+"..."}var Rt="#f8f8f8",Lt="#888888",Ei=[f.hex(D)("~(oo)~"),f.hex(D)("~(oO)~"),f.hex(D)("~(Oo)~"),f.hex(D)("~(OO)~"),f.hex(D)("~(\u25CFo)~"),f.hex(D)("~(o\u25CF)~"),f.hex(D)("~(\u25C9o)~"),f.hex(D)("~(o\u25C9)~"),f.hex(D)("\\(oo)/"),f.hex(D)("\\(oO)/"),f.hex(D)("\\(Oo)/"),f.hex(D)("\\(OO)/"),f.hex(D)("~(Oo)~"),f.hex(D)("~(oO)~"),f.hex(D)("~(\u25CEo)~"),f.hex(D)("~(o\u25CE)~"),f.hex(D)("~(oo)~"),f.hex(D)("~(OO)~"),f.hex(D)("~(Oo)~"),f.hex(D)("\\(oo)/"),f.hex(D)("\\(oO)/"),f.hex(D)("\\(Oo)/"),f.hex(D)("\\(OO)/")];function It(o,e){return e===1?o:`${o}s`}function Ri(o,e={}){let n=e.align||[],i=e.stringLength||(a=>Ct(a).length),r=o.reduce((a,s)=>(s.forEach((l,c)=>{let u=i(l);(!a[c]||u>a[c])&&(a[c]=u)}),a),[]);return o.map(a=>a.map((s,l)=>{let c=r[l]-i(s)||0,u=Array(Math.max(c+1,1)).join(" ");return n[l]==="r"?u+s:s+u}).join(" ").trimEnd()).join(`
|
|
21
|
+
`)}function Ft(o,e){let t=`
|
|
22
|
+
`,n=0,i=0,r=new Map;o.forEach(v=>{if(v.matches.length===0)return;let M=v.ruleId||"unknown";r.has(M)||r.set(M,{message:v.message,severity:v.severity,internalId:v.internalId,execution:v.execution,matches:[]});let E=r.get(M);v.matches.forEach(C=>{var R;E.matches.push({file:{path:C.file.path,sha:C.file.sha},line:C.range.start.line,column:C.range.start.column,endLine:C.range.end.line!==C.range.start.line?C.range.end.line:void 0,text:C.text,description:C.description,evidence:(R=C.evidence)==null?void 0:R.map(b=>({file:{path:b.file.path,sha:b.file.sha},text:b.text,range:b.range,description:b.description}))}),v.severity==="violation"?n++:i++})}),r.forEach((v,M)=>{if(v.matches.length===0&&v.severity!=="skipped")return;let E;v.severity==="violation"?E=f.hex(H)(Be):v.severity==="suggestion"?E=f.hex(J)(we):E=f.hex(Si)(we);let C=v.execution==="llm"?`${f.hex(be)($e)} `:"",R;if(v.internalId){let L=`https://app.wispbit.com/rules/${v.internalId}`;R=f.bold(`\x1B]8;;${L}\x1B\\${M}\x1B]8;;\x1B\\`)}else R=f.bold(M);let b=`${E} ${C}${R} ${v.message.replace(/([^ ])\.$/u,"$1")}`;if(t+=`${b}
|
|
23
23
|
`,t+=`${f.dim("\u2500".repeat(80))}
|
|
24
|
-
`,
|
|
25
|
-
`;else{let
|
|
26
|
-
`).length<=30)?
|
|
27
|
-
`).length<=30)t+=` ${
|
|
28
|
-
`,
|
|
29
|
-
`).forEach((
|
|
30
|
-
`})
|
|
31
|
-
`}
|
|
32
|
-
`)
|
|
33
|
-
`
|
|
24
|
+
`,v.severity==="skipped")t+=`
|
|
25
|
+
`;else{let L=v.matches.sort((d,P)=>d.file.path.localeCompare(P.file.path));L.length<10&&L.some(d=>d.text&&d.text.split(`
|
|
26
|
+
`).length<=30)?L.forEach((d,P)=>{if(d.text&&d.text.split(`
|
|
27
|
+
`).length<=30){let $=d.description?` - ${f.dim(d.description)}`:"";t+=` ${d.file.path}${$}
|
|
28
|
+
`,d.text.split(`
|
|
29
|
+
`).forEach((S,O)=>{let k=d.line+O,_=f.bgHex(Rt).hex(Lt)(` ${String(k)} `);t+=` ${_} ${f.dim(S)}
|
|
30
|
+
`})}else{let $=d.endLine?`(${d.line}:${d.endLine})`:`(${d.line})`,w=d.description?` - ${f.dim(d.description)}`:"";t+=` ${d.file.path} ${f.dim($)}${w}
|
|
31
|
+
`}d.evidence&&d.evidence.length>0&&d.evidence.forEach($=>{if($.text&&$.text.split(`
|
|
32
|
+
`).length<=30){let w=$.description?` - ${f.dim($.description)}`:"";t+=` ${$.file.path}${w}
|
|
33
|
+
`,$.text.split(`
|
|
34
|
+
`).forEach((O,k)=>{let _=$.range.start.line+k,We=f.bgHex(Rt).hex(Lt)(` ${String(_)} `);t+=` ${We} ${f.dim(O)}
|
|
35
|
+
`})}else{let w=`${$.range.start.line}:${$.range.end.line}`,S=$.description?` - ${f.dim($.description)}`:"";t+=` ${$.file.path} ${f.dim(`(${w})`)}${S}
|
|
36
|
+
`}}),P<L.length-1&&(t+=`
|
|
37
|
+
`)}):L.forEach(d=>{let P=d.endLine?`(${d.line}:${d.endLine})`:`(${d.line})`,$=d.description?` - ${f.dim(d.description)}`:"";t+=` ${d.file.path} ${f.dim(P)}${$}
|
|
38
|
+
`,d.evidence&&d.evidence.length>0&&d.evidence.forEach(w=>{let S=`${w.range.start.line}:${w.range.end.line}`,O=w.description?` - ${f.dim(w.description)}`:"";t+=` ${w.file.path} ${f.dim(`(${S})`)}${O}
|
|
39
|
+
`})}),t+=`
|
|
34
40
|
|
|
35
|
-
`}}),console.log(t);let
|
|
36
|
-
`,
|
|
37
|
-
`,
|
|
38
|
-
`,console.log(
|
|
39
|
-
`+
|
|
40
|
-
Use 'wispbit check --rule <rule-id>' to run a specific rule.`))}function
|
|
41
|
-
${
|
|
42
|
-
`),
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
${
|
|
48
|
-
${
|
|
49
|
-
|
|
50
|
-
${
|
|
51
|
-
${
|
|
41
|
+
`}}),console.log(t);let a=n+i,s=n>0?`${f.dim("violations".padStart(12))} ${f.hex(H)(Be)} ${f.hex(H).bold(n)}`:`${f.dim("violations".padStart(12))} ${f.dim(n)}`,l=i>0?`${f.dim("suggestions".padStart(12))} ${f.hex(J)(we)} ${f.hex(J).bold(i)}`:`${f.dim("suggestions".padStart(12))} ${f.dim(i)}`,c=e.totalFiles?`${e.totalFiles} ${It("file",e.totalFiles)}`:"0 files",u=`${e.totalRules} ${It("rule",e.totalRules)}`,m=e.executionTime?`${Math.round(e.executionTime)}ms`:"",g=[c,u,m].filter(Boolean).join(", "),h="";h+=`${s}
|
|
42
|
+
`,h+=`${l}
|
|
43
|
+
`,h+=`${f.dim("summary".padStart(12))} ${g}
|
|
44
|
+
`,console.log(a>0?f.reset(h):h),n>0&&process.exit(1)}function Dt(o){if(o.length===0){console.log(f.yellow("No rules found.")),console.log(f.dim("Go to https://app.wispbit.com/rules to create a rule."));return}let e=[];e.push(["",`${"id".padEnd(12)} ${f.dim("\u2502")} ${"severity".padEnd(16)} ${f.dim("\u2502")} ${"execution".padEnd(18)} ${f.dim("\u2502")} message`]);let t=process.stdout.columns||120,i=Math.max(20,t-55-10);e.push(["",`${f.dim("\u2500".repeat(12))} ${f.dim("\u253C")} ${f.dim("\u2500".repeat(16))} ${f.dim("\u253C")} ${f.dim("\u2500".repeat(18))} ${f.dim("\u253C")} ${f.dim("\u2500".repeat(i))}`]);for(let a of o){let s=a.config.severity==="violation"?Be:we,l=a.config.severity==="violation"?f.hex(H).bold:f.hex(J).bold,u=(a.config.severity==="violation"?f.hex(H):f.hex(J))(s)+" "+l(a.config.severity),m=Pi(a.id,a.internalId),g=a.config.execution==="llm"?f.hex(be)($e)+" "+f.hex(be)("llm"):f.hex(Qe)($e)+" "+f.hex(Qe)("deterministic"),h=kt(a.config.message,i),v=Math.max(0,12-a.id.length),M=Math.max(0,16-(a.config.severity.length+2)),E=Math.max(0,18-(a.config.execution.length+2));e.push(["",`${m}${" ".repeat(v)} ${f.dim("\u2502")} ${u}${" ".repeat(M)} ${f.dim("\u2502")} ${g}${" ".repeat(E)} ${f.dim("\u2502")} ${h}`])}let r=Ri(e,{align:["","l"],stringLength(a){return Ct(a).length}});console.log(`
|
|
45
|
+
`+r),console.log(f.dim(`
|
|
46
|
+
Use 'wispbit check --rule <rule-id>' to run a specific rule.`))}function Tt(o,e="pretty"){let t=[];for(let n of o)for(let i of n.matches){let r={file:i.file,range:i.range,language:i.language,text:i.text,evidence:i.evidence,ruleId:n.ruleId,internalId:n.internalId,severity:n.severity,message:n.message};t.push(r)}if(e==="stream")for(let n of t)console.log(JSON.stringify(n));else console.log(e==="compact"?JSON.stringify(t):JSON.stringify(t,null,2))}function _t(o,e=!1){let t=null,n=null,i=null,r=new Map,a=()=>{if(!t)return;let s=[],l=process.stdout.columns||120;for(let[u,{isLlm:m,message:g,severity:h,dotAnimationFrame:v,toolInfo:M,validationPhase:E}]of r){if(M||E){let $=r.get(u);$.dotAnimationFrame=($.dotAnimationFrame+1)%3}let C=v+1,R=f.hex(D)(".".repeat(C).padEnd(3," ")),b=h==="violation"?f.hex(H)(Be):f.hex(J)(we),L=m?`${f.hex(be)($e)} ${f.hex(be)("llm")}`:f.hex(Qe)($e),x=Math.max(40,l-50),d=kt(g,x),P=`${b} ${L} ${f.dim(u)} ${d}`;if(E){let $=` ${R} ${f.dim(`validating ${E.matchCount} ${E.matchCount===1?"match":"matches"}`)}`;s.push(`${P}
|
|
47
|
+
${$}`)}else if(M)if(M.toolName==="read"&&M.file){let $="";if(M.offset||M.limit){let S=M.offset?parseInt(M.offset,10):1,O=M.limit?parseInt(M.limit,10):200,k=S+O-1;$=` ${f.dim(`(lines ${S}-${k})`)}`}let w=` ${R} ${f.dim("tool: read")} ${M.file}${$}`;s.push(`${P}
|
|
48
|
+
${w}`)}else if(M.toolName==="grep"){let $=M.path||".",w=M.pattern||"",S=` ${R} ${f.dim("tool: grep")} ${$} ${f.dim(`for "${w}"`)}`;s.push(`${P}
|
|
49
|
+
${S}`)}else if(M.toolName==="glob"){let $=M.path||".",w=M.pattern||"",S=` ${R} ${f.dim("tool: glob")} ${$} ${f.dim(`for "${w}"`)}`;s.push(`${P}
|
|
50
|
+
${S}`)}else s.push(P);else s.push(P)}let c="";if(i&&(i.mode==="check"?c=i.filePath?` ${f.dim(`(${i.filePath})`)}`:"":i.mode==="diff"&&(c=` ${f.dim(`(${i.baseCommit} \u2192 ${i.headCommit})`)}`)),s.length>0){let u=s.map((m,g)=>g===0?m:m.split(`
|
|
51
|
+
`).map((v,M)=>M===0?` ${v}`:v).join(`
|
|
52
|
+
`));t.text=`${u.join(`
|
|
53
|
+
`)}${c}`}else t.text=`${c}`};return o.on("execution:mode",s=>{i=s}),o.on("rules:start",s=>{t=Mi({spinner:{interval:120,frames:Ei},color:!1}).start();let l=()=>{t&&t.stopAndPersist(),process.exit(130)};process.on("SIGINT",l),process.on("SIGTERM",l);let c=setInterval(()=>{a()},200);t._updateInterval=c}),o.on("rules:rule-start",s=>{r.set(s.ruleId,{isLlm:s.isLlm,message:s.message,severity:s.severity,dotAnimationFrame:0}),a()}),o.on("rules:rule-complete",s=>{r.delete(s.ruleId),a()}),o.on("llm:tool-execution",s=>{let l=r.get(s.ruleId);l&&(l.toolInfo={toolName:s.toolName,file:s.file,path:s.path,pattern:s.pattern,offset:s.offset,limit:s.limit},a())}),o.on("llm:validation-phase:start",s=>{let l=r.get(s.ruleId);l&&(l.toolInfo=void 0,l.validationPhase={matchCount:s.matchCount},a())}),o.on("rules:progress",s=>{a()}),o.on("rules:complete",()=>{t&&(t._updateInterval&&clearInterval(t._updateInterval),t.stopAndPersist(),t=null),r.clear()}),o.on("files:discovery:start",s=>{e&&console.log(`
|
|
54
|
+
${f.blue("Discovering files")} in ${f.bold(s.mode)} mode...`)}),o.on("files:discovery:progress",s=>{e&&console.log(` ${s.message}`)}),o.on("files:discovery:complete",s=>{e&&console.log(f.green("File discovery complete:"),`${s.totalFiles} files found (${s.executionTime}ms)`)}),o.on("files:filter",s=>{e&&s.originalCount!==s.filteredCount&&console.log(f.yellow("Filtered:"),`${s.originalCount} \u2192 ${s.filteredCount} ${s.filterType}`)}),o.on("indexing:start",s=>{n=Date.now()}),o.on("indexing:progress",s=>{t&&(t.color="yellow"),n&&Date.now()-n>1e3&&t&&(t.text=`Indexing ${s.language}...`),t&&(s.packageName&&s.timeMs?t.text=`Indexing ${s.language}: ${s.packageName}`:s.message!=="Indexing files..."&&(t.text=`Indexing ${s.language}: ${s.message}`)),e&&(s.packageName&&s.timeMs?console.log(` + ${s.packageName} (${s.timeMs}ms)`):s.message==="Indexing files..."?process.stdout.write("."):s.message!=="Indexing files..."&&console.log(` ${s.message}`))}),o.on("indexing:complete",s=>{n=null,t&&(t.color="blue"),e&&(process.stdout.write(`
|
|
55
|
+
`),console.log(f.green("Indexing complete for"),`${s.language} (${s.executionTime}ms)`))}),e&&(o.on("scip:match-lookup:start",s=>{console.log(f.cyan(`
|
|
56
|
+
\u{1F50D} [${s.language}] Starting SCIP match lookup for: ${JSON.stringify(s.match)}`))}),o.on("scip:match-lookup:progress",s=>{console.log(`${JSON.stringify(s.document)}`)}),o.on("scip:match-lookup:complete",s=>{console.log(f.green(`SCIP match lookup complete for: ${s.language}`))}),o.on("step:start",s=>{console.log(f.cyan(`
|
|
57
|
+
\u{1F527} [${s.ruleId}] Starting step: ${s.stepName} (${s.stepType})`)),console.log(` Input files: ${s.inputs.filePaths.length}`),console.log(` Input matches: ${s.inputs.matches.length}`),s.inputs.matches.length>0&&(console.log(" Match details:"),s.inputs.matches.forEach((l,c)=>{var u;console.log(` Match ${c+1}:`),console.log(` File: ${l.file.path}`),console.log(` Range: ${l.range.start.line}:${l.range.start.column} \u2192 ${l.range.end.line}:${l.range.end.column}`),l.evidence&&l.evidence.length>0&&(console.log(` Evidence chain: ${l.evidence.length} evidence(s)`),l.evidence.forEach((m,g)=>{console.log(` ${g+1}. ${m.filePath} @ ${m.range.start.line} \u2192 ${m.range.end.line}`)})),console.log(` Text preview: ${(u=l.text)==null?void 0:u.substring(0,120)}...`)}))}),o.on("step:complete",s=>{console.log(f.cyan(`\u2705 [${s.ruleId}] Completed step: ${s.stepName} (${s.stepType}) (${s.executionTime}ms)`)),s.outputs.filePaths!==void 0&&console.log(` Output files: ${s.outputs.filePaths.length}`),s.outputs.matches!==void 0&&(console.log(` Output matches: ${s.outputs.matches.length}`),s.outputs.matches.length>0&&(console.log(" Output match details:"),s.outputs.matches.forEach((l,c)=>{var u;console.log(` Match ${c+1}:`),console.log(` File: ${l.file.path}`),console.log(` Range: ${l.range.start.line}:${l.range.start.column} \u2192 ${l.range.end.line}:${l.range.end.column}`),l.evidence&&l.evidence.length>0&&(console.log(` Evidence chain: ${l.evidence.length} evidence(s)`),l.evidence.forEach((m,g)=>{console.log(` ${g+1}. ${m.filePath} @ ${m.range.start.line} \u2192 ${m.range.end.line}`)})),console.log(` Text preview: ${(u=l.text)==null?void 0:u.substring(0,120)}...`)})))}),o.on("test:start",s=>{console.log(f.magenta(`
|
|
58
|
+
\u{1F9EA} [${s.ruleId}] Running test: "${s.testName}"`))}),o.on("test:matches",s=>{console.log(f.magenta(` Found ${s.matches.length} match(es):`)),s.matches.forEach((l,c)=>{var u;console.log(` Match ${c+1}:`),console.log(` File: ${l.file.path}`),console.log(` Range: ${l.range.start.line}:${l.range.start.column} \u2192 ${l.range.end.line}:${l.range.end.column}`),l.evidence&&l.evidence.length>0&&(console.log(` Evidence chain: ${l.evidence.length} evidence(s)`),l.evidence.forEach((m,g)=>{console.log(` ${g+1}. ${m.filePath} @ ${m.range.start.line} \u2192 ${m.range.end.line}`)})),console.log(` Text preview: ${(u=l.text)==null?void 0:u.substring(0,120)}...`)})})),()=>{t&&(t._updateInterval&&clearInterval(t._updateInterval),t.stopAndPersist(),t=null),r.clear()}}import Li from"readline";import ue from"chalk";import Ii from"ora";import y from"chalk";var I="#fbbf24",le="#ff6b35",W="#4a90e2",ce="#9b59b6",Xe=[`
|
|
59
|
+
${y.hex(I)(" \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")}
|
|
60
|
+
${y.hex(I)(" \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")}
|
|
61
|
+
${y.hex(I)(" \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 ")}
|
|
62
|
+
${y.hex(I)(" \u2588\u2588\u2551\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
63
|
+
${y.hex(I)(" \u255A\u2588\u2588\u2588\u2554\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
64
|
+
${y.hex(I)(" \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ")}
|
|
52
65
|
`,`
|
|
53
|
-
${
|
|
54
|
-
${
|
|
55
|
-
${
|
|
56
|
-
${
|
|
57
|
-
${
|
|
58
|
-
${
|
|
66
|
+
${y.hex(W)(" \u2588\u2588\u2557 ")}${y.hex(I)("\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")}
|
|
67
|
+
${y.hex(W)(" \u2588\u2588\u2551 ")}${y.hex(I)("\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")}
|
|
68
|
+
${y.hex(W)(" \u2588\u2588\u2551 \u2588\u2557 ")}${y.hex(I)("\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 ")}
|
|
69
|
+
${y.hex(W)(" \u2588\u2588\u2551\u2588\u2588\u2588\u2557")}${y.hex(I)("\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
70
|
+
${y.hex(W)(" \u255A\u2588\u2588\u2588\u2554\u2588\u2588")}${y.hex(I)("\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
71
|
+
${y.hex(W)(" \u255A\u2550\u2550\u255D\u255A\u2550")}${y.hex(I)("\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ")}
|
|
59
72
|
`,`
|
|
60
|
-
${
|
|
61
|
-
${
|
|
62
|
-
${
|
|
63
|
-
${
|
|
64
|
-
${
|
|
65
|
-
${
|
|
73
|
+
${y.hex(I)(" \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557")}${y.hex(ce)("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 ")}${y.hex(I)("\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
|
|
74
|
+
${y.hex(I)(" \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551")}${y.hex(ce)("\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557")}${y.hex(I)("\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D")}
|
|
75
|
+
${y.hex(I)(" \u2588\u2588\u2551 \u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551")}${y.hex(ce)("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D")}${y.hex(I)("\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
76
|
+
${y.hex(I)(" \u2588\u2588\u2551\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551")}${y.hex(ce)("\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255D ")}${y.hex(I)("\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
77
|
+
${y.hex(I)(" \u255A\u2588\u2588\u2588\u2554\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551")}${y.hex(ce)("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 ")}${y.hex(I)("\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
78
|
+
${y.hex(I)(" \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u255D")}${y.hex(ce)("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D ")}${y.hex(I)("\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ")}
|
|
66
79
|
`,`
|
|
67
|
-
${
|
|
68
|
-
${
|
|
69
|
-
${
|
|
70
|
-
${
|
|
71
|
-
${
|
|
72
|
-
${
|
|
80
|
+
${y.hex(I)(" \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 ")}${y.hex(le)("\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
|
|
81
|
+
${y.hex(I)(" \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")}${y.hex(le)("\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D")}
|
|
82
|
+
${y.hex(I)(" \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")}${y.hex(le)("\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
83
|
+
${y.hex(I)(" \u2588\u2588\u2551\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255D ")}${y.hex(le)("\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
84
|
+
${y.hex(I)(" \u255A\u2588\u2588\u2588\u2554\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 ")}${y.hex(le)("\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
|
|
85
|
+
${y.hex(I)(" \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D ")}${y.hex(le)("\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ")}
|
|
73
86
|
`,`
|
|
74
|
-
${
|
|
75
|
-
${
|
|
76
|
-
${
|
|
77
|
-
${
|
|
78
|
-
${
|
|
79
|
-
${
|
|
80
|
-
`];function
|
|
81
|
-
Welcome to wispbit`)),console.log(
|
|
82
|
-
`)),console.log(
|
|
83
|
-
`));let
|
|
84
|
-
Setup cancelled.`)),null)}
|
|
85
|
-
`)))}var
|
|
87
|
+
${y.hex(I)(" \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")}${y.hex(W)("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
|
|
88
|
+
${y.hex(I)(" \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")}${y.hex(W)("\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D")}
|
|
89
|
+
${y.hex(I)(" \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")}${y.hex(W)(" \u2588\u2588\u2551 ")}
|
|
90
|
+
${y.hex(I)(" \u2588\u2588\u2551\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551")}${y.hex(W)(" \u2588\u2588\u2551 ")}
|
|
91
|
+
${y.hex(I)(" \u255A\u2588\u2588\u2588\u2554\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551")}${y.hex(W)(" \u2588\u2588\u2551 ")}
|
|
92
|
+
${y.hex(I)(" \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D")}${y.hex(W)(" \u255A\u2550\u255D ")}
|
|
93
|
+
`];function Ci(){process.stdout.write("\x1B[2J\x1B[H")}function ki(o){return new Promise(e=>setTimeout(e,o))}async function Fi(o=3e3){let e=Ii({text:"",spinner:{interval:100,frames:Xe}}).start();await ki(o),e.stop()}async function Di(o){let e=Li.createInterface({input:process.stdin,output:process.stdout});return await new Promise(t=>{e.question(o,n=>{e.close(),t(n.trim())})})}async function At(){Ci(),await Fi(1500),console.log(Xe[0]),console.log(ue.hex(H)(`
|
|
94
|
+
Welcome to wispbit`)),console.log(ue(` The linter for AI
|
|
95
|
+
`)),console.log(ue.dim(" To use wispbit, you need an API key.")),console.log(ue.dim(` You can get one at: https://app.wispbit.com/api-keys
|
|
96
|
+
`));let o=await Di(ue.bold.hex(J)(" Enter your Wispbit API key (or press Enter to exit): "));return o||(console.log(ue.dim(`
|
|
97
|
+
Setup cancelled.`)),null)}Ti.config();function Gt(){return je.join(Nt.homedir(),".powerlint","config.json")}async function Oi(o){let e=Gt(),t=je.dirname(e);await Q.mkdir(t,{recursive:!0});let n={};try{let r=await Q.readFile(e,"utf-8");n=JSON.parse(r)}catch{}let i={...n,apiKey:o};await Q.writeFile(e,JSON.stringify(i,null,2))}async function Ni(){if(process.env.WISPBIT_API_KEY)return process.env.WISPBIT_API_KEY;let o=Gt();try{let e=await Q.readFile(o,"utf-8");return JSON.parse(e).apiKey||null}catch{return null}}async function Bt(o){let e=process.env.WISPBIT_API_KEY||null;e||(e=await Ni());let t=await ge.initialize(o,{apiKey:e||void 0});if("failed"in t){if(t.error==="INVALID_API_KEY"){let n=await At();if(n||process.exit(0),await o.getRepositoryUrl()||(console.log(A.red("Repository URL not found. Make sure you're in a git repository.")),process.exit(1)),console.log(A.dim("Validating API key...")),await Oi(n),t=await ge.initialize(o,{apiKey:n}),"failed"in t)console.log(A.red("Invalid API key. Please check your API key and try again.")),process.exit(1);else return console.log(A.green("Setup complete! powerlint has been configured.")),t}else if(t.error==="INVALID_REPOSITORY"){let n=await o.getRepositoryUrl();console.log(A.red(`No repository in wispbit found for url: ${n}. If you are passing the repository URL as a flag, make sure it is correct. If your git remote URL was recently modified, use "git remote set-url origin <new-url>" to update the remote URL.`)),process.exit(1)}}return t}async function Gi(){let o=Y(),e=await et();Ai.gt(e,o)&&(console.log(A.bgHex("#b2f5ea").black.bold(` NEW VERSION AVAILABLE: ${e} (current: ${o}) `)),console.log(A.bgHex("#b2f5ea").black.bold(` Run 'pnpm install -g @wispbit/local' to update
|
|
98
|
+
`)))}var T=_i(`
|
|
86
99
|
wispbit - the linter for AI
|
|
87
100
|
https://wispbit.com/
|
|
88
101
|
|
|
@@ -127,5 +140,5 @@ Global options:
|
|
|
127
140
|
--repo-url <url> Override repository URL (default: from git remote)
|
|
128
141
|
-v, --version Show version number
|
|
129
142
|
-h, --help Show help
|
|
130
|
-
`,{importMeta:import.meta,flags:{rule:{type:"string"},json:{type:"string"},include:{type:"string"},repoUrl:{type:"string"},debug:{type:"boolean",shortFlag:"d",default:!1},version:{type:"boolean",shortFlag:"v"},help:{type:"boolean",shortFlag:"h"}},version:
|
|
131
|
-
${
|
|
143
|
+
`,{importMeta:import.meta,flags:{rule:{type:"string"},json:{type:"string"},include:{type:"string"},repoUrl:{type:"string"},debug:{type:"boolean",shortFlag:"d",default:!1},version:{type:"boolean",shortFlag:"v"},help:{type:"boolean",shortFlag:"h"}},version:Y()});async function Ze(o){let e=new X({repositoryUrl:o.repoUrl}),t=await Bt(e),{ruleId:n,json:i,mode:r,filePath:a}=o,{commitSelector:s,diffInclude:l}=o;if(r==="diff"){let b=e.getWorkspaceRoot();if(s)l||(l=(await ze(b)).include);else{let L=await ze(b);s=L.commitSelector,l||(l=L.include)}}if(r==="diff"&&s&&l){let b=e.getWorkspaceRoot(),L=await Ve(b),x=qe(s,l,L);x&&(console.error(A.red(x)),process.exit(1))}let c=!1,u="pretty";i!==void 0?(c=!0,typeof i=="string"?i==="stream"?u="stream":i==="compact"?u="compact":u="pretty":u="pretty"):await Gi();let m;try{let b=new he(t,e);n?m=[await b.loadRuleById(n)]:m=await b.loadAllRules()}catch(b){throw b instanceof Ge&&(console.error(A.red("Rule Validation Error:"),b.message),b.validationErrors&&b.validationErrors.length>0&&(console.error(A.red("Validation errors:")),b.validationErrors.forEach(L=>{console.error(A.red(" \u2022"),L)})),process.exit(1)),b}if(!c)if(r==="check"){let b=A.bgHex("#eab308").black(" CHECK "),L=A.dim(` (${a||"all files"})`);console.log(`${b}${L}`)}else{let b=A.bgHex("#4a90e2").black(" DIFF "),L=(s||"").replace(/\b[0-9a-f]{30,}\b/gi,d=>d.substring(0,7)),x=l?` ${L} ${A.dim(`[${l.join("/")}]`)}`:` ${L}`;console.log(`${b}${x}`)}let g=new G;if(r==="check")g.setExecutionMode("check",{filePath:a});else{let b=l?l.join(", "):"all";g.setExecutionMode("diff",{baseCommit:s||"",headCommit:b})}let h=o.json?void 0:_t(g,o.debug||!1),v=Date.now(),M=new Ne(t,e,g),E=0;g.on("files:discovery:complete",b=>{E=b.totalFiles});let C=await M.execute(m,{mode:r,filePath:a,diffOptions:r==="diff"?{include:l,commitSelector:s}:void 0}),R=[];for(let b of C){let L=m.find(x=>x.id===b.ruleId);if(L){let P={ruleId:b.ruleId,internalId:L.internalId,message:L.config.message,severity:L.config.severity,execution:L.config.execution,matches:b.matches,llmCost:void 0,llmTokens:void 0};R.push(P)}}if(h==null||h(),c)Tt(R,u);else{let b=R.filter(k=>k.severity==="violation"),L=R.filter(k=>k.severity==="suggestion"),x=b.reduce((k,_)=>k+_.matches.length,0),d=L.reduce((k,_)=>k+_.matches.length,0),P=x+d,$=R.filter(k=>k.llmCost).reduce((k,_)=>k.plus(new Ot(_.llmCost||0)),new Ot(0)),w=R.filter(k=>k.llmTokens).reduce((k,_)=>k+(_.llmTokens||0),0),S;if(r==="check")S={mode:"check",filePath:a};else{let k=(s||"").replace(/\b[0-9a-f]{30,}\b/gi,We=>We.substring(0,7)),_=l?l.join(", "):"all";S={mode:"diff",baseCommit:k,headCommit:_}}let O=Date.now()-v;Ft(R,{totalRules:m.length,violationCount:x,suggestionCount:d,totalMatches:P,totalLLMCost:$.toString(),totalLLMTokens:w,executionMode:S,executionTime:O,totalFiles:E})}return R}async function Bi(o){let e=new X({repositoryUrl:o}),t=await Bt(e),i=await new he(t,e).loadAllRules();Dt(i)}async function ji(){let o=T.input[0],e=T.input[1];switch(o){case"check":{let t=T.input[1];await Ze({ruleId:T.flags.rule,json:T.flags.json,debug:T.flags.debug,mode:"check",filePath:t,repoUrl:T.flags.repoUrl});break}case"diff":{let t;if(T.flags.include){let r=T.flags.include.split(",").map(l=>l.trim()),a=["committed","staged","unstaged","untracked"],s=r.filter(l=>!a.includes(l));s.length>0&&(console.error(A.red(`Invalid include(s): ${s.join(", ")}. Valid includes: ${a.join(", ")}`)),process.exit(1)),t=r}let n=T.input[1];await Ze({ruleId:T.flags.rule,json:T.flags.json,debug:T.flags.debug,mode:"diff",diffInclude:t,commitSelector:n,repoUrl:T.flags.repoUrl});break}case"list":{await Bi(T.flags.repoUrl);break}case"cache":{if(e==="purge"){let t=new X({repositoryUrl:T.flags.repoUrl}),i=await new ee(t).purgeCache();console.log(`
|
|
144
|
+
${A.green("Cache purged successfully.")} Removed ${i.deletedCount} item(s).`)}else console.error(A.red("Unknown cache subcommand:"),e),T.showHelp(),process.exit(1);break}default:{let t;if(T.flags.include){let r=T.flags.include.split(",").map(l=>l.trim()),a=["committed","staged","unstaged","untracked"],s=r.filter(l=>!a.includes(l));s.length>0&&(console.error(A.red(`Invalid include(s): ${s.join(", ")}. Valid includes: ${a.join(", ")}`)),process.exit(1)),t=r}let n=T.input[0];await Ze({ruleId:T.flags.rule,json:T.flags.json,debug:T.flags.debug,mode:"diff",diffInclude:t,commitSelector:n,repoUrl:T.flags.repoUrl});break}}}ji();export{Gi as checkForUpdates};
|
package/dist/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wispbit/local",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.31",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"build": "tsc",
|
|
85
85
|
"lint": "eslint . --ext .ts",
|
|
86
86
|
"test": "vitest",
|
|
87
|
+
"test:update": "UPDATE_SNAPSHOTS=true vitest",
|
|
87
88
|
"cli": "tsx src/index.ts",
|
|
88
89
|
"deploy": "pnpm run build:cli && node ./dist/index.js --help && pnpm publish --access=public --no-git-checks"
|
|
89
90
|
}
|