@leveragent/e2e-testing 0.1.2 → 0.1.6

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.
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import{CopilotClient as vt}from"@github/copilot-sdk";import*as wt from"readline";import{approveAll as Ut}from"@github/copilot-sdk";import{readFile as bt}from"fs/promises";var Z=(t,e)=>t===void 0?e:/^(1|true|yes|on)$/i.test(t.trim()),tt=t=>{let e=(t??"high").trim().toLowerCase();switch(e){case"low":case"medium":case"high":case"xhigh":return e;default:return"high"}},et=async(t,e={})=>{let{trim:s=!0,onError:o}=e;try{let n=await bt(t,"utf8");return(s?n.trim():n)||""}catch(n){return o?.(n),""}},I=t=>typeof t=="number"&&Number.isFinite(t)?t:0,st=t=>new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:4,maximumFractionDigits:6}).format(t);var yt="",W="none",ot=`You are a senior frontend engineer, specialized on E2E testing in a local CLI. Be concise but highly useful.
2
+ import{CopilotClient as qt}from"@github/copilot-sdk";import*as Et from"readline";import{approveAll as Ft}from"@github/copilot-sdk";import{readFile as yt}from"fs/promises";var Z=(t,e)=>t===void 0?e:/^(1|true|yes|on)$/i.test(t.trim()),tt=t=>{let e=(t??"high").trim().toLowerCase();switch(e){case"low":case"medium":case"high":case"xhigh":return e;default:return"high"}},et=async(t,e={})=>{let{trim:s=!0,onError:o}=e;try{let n=await yt(t,"utf8");return(s?n.trim():n)||""}catch(n){return o?.(n),""}},I=t=>typeof t=="number"&&Number.isFinite(t)?t:0,st=t=>new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:4,maximumFractionDigits:6}).format(t);var Ot="",W="none",ot=`You are a senior frontend engineer, specialized on E2E testing in a local CLI. Be concise but highly useful.
3
3
  Prefer concrete steps, ask clarifying questions only when necessary, and use tools when needed.
4
- If a tool returns uncertain data, state assumptions clearly. ${yt}`,nt=1e9,k=Number(process.env.COPILOT_USD_PER_AIU??"0");var Ot="gpt-5.3-codex";var M=1e6,N="\x1B[0m",D="\x1B[38;5;110m",$=1e4,rt=1e6,it=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".json",".go",".py",".java",".rb",".rs",".php",".swift",".kt",".kts",".cs",".c",".h",".hpp",".cpp",".cc"]);var v=process.env.COPILOT_MODEL??Ot,q=tt(process.env.COPILOT_REASONING_EFFORT),at=Z(process.env.COPILOT_RESUME_LAST,!0),H=process.env.COPILOT_SDK_AUTH_TOKEN??process.env.GITHUB_TOKEN??process.env.GH_TOKEN;var Rt="\x1B[0m",Ct="\x1B[38;5;245m",B=t=>`${Ct}${t}${Rt}`,It=t=>{if(t===void 0)return"{}";try{return JSON.stringify(t,null,2)}catch{return"[unserializable arguments]"}},Lt=(t,e,s)=>{if(s){if(t&&typeof t=="object"){let o=t;if(typeof o.detailedContent=="string")return o.detailedContent;if(typeof o.content=="string")return o.content}return"[no response content]"}if(e&&typeof e=="object"){let o=e;if(typeof o.message=="string")return o.message}return"[tool failed without error details]"},ct=(t,e)=>{if(t.waitingForAssistantOutput){if(t.waitingForAssistantOutput=!1,t.waitingForToolResult){e.start("Tool");return}e.stop(!0)}},lt=(t,e)=>{let{uiState:s,spinner:o}=e,n=[];return n.push(t.on("assistant.message_delta",i=>{ct(s,o),process.stdout.write(i.data.deltaContent)})),n.push(t.on("assistant.message",()=>{ct(s,o)})),n.push(t.on("session.idle",()=>{s.waitingForToolResult=!1,s.waitingForAssistantOutput&&(s.waitingForAssistantOutput=!1,o.stop(!1)),process.stdout.write(`
4
+ If a tool returns uncertain data, state assumptions clearly. ${Ot}`,nt=1e9,N=Number(process.env.COPILOT_USD_PER_AIU??"0");var Rt="gpt-5.3-codex";var M=1e6,D="\x1B[0m",$="\x1B[38;5;110m",v=1e4,rt=1e6,it=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".json",".go",".py",".java",".rb",".rs",".php",".swift",".kt",".kts",".cs",".c",".h",".hpp",".cpp",".cc"]);var Ct="0.1.6",at=Ct||process.env.npm_package_version||"unknown";var k=process.env.COPILOT_MODEL??Rt,G=tt(process.env.COPILOT_REASONING_EFFORT),ct=Z(process.env.COPILOT_RESUME_LAST,!0),q=process.env.COPILOT_SDK_AUTH_TOKEN??process.env.GITHUB_TOKEN??process.env.GH_TOKEN;var It="\x1B[0m",Lt="\x1B[38;5;245m",B=t=>`${Lt}${t}${It}`,Pt=t=>{if(t===void 0)return"{}";try{return JSON.stringify(t,null,2)}catch{return"[unserializable arguments]"}},Ut=(t,e,s)=>{if(s){if(t&&typeof t=="object"){let o=t;if(typeof o.detailedContent=="string")return o.detailedContent;if(typeof o.content=="string")return o.content}return"[no response content]"}if(e&&typeof e=="object"){let o=e;if(typeof o.message=="string")return o.message}return"[tool failed without error details]"},lt=(t,e)=>{if(t.waitingForAssistantOutput){if(t.waitingForAssistantOutput=!1,t.waitingForToolResult){e.start("Tool");return}e.stop(!0)}},ut=(t,e)=>{let{uiState:s,spinner:o}=e,n=[];return n.push(t.on("assistant.message_delta",i=>{lt(s,o),process.stdout.write(i.data.deltaContent)})),n.push(t.on("assistant.message",()=>{lt(s,o)})),n.push(t.on("session.idle",()=>{s.waitingForToolResult=!1,s.waitingForAssistantOutput&&(s.waitingForAssistantOutput=!1,o.stop(!1)),process.stdout.write(`
5
5
  `)})),n.push(t.on("session.error",i=>{s.waitingForToolResult=!1,s.waitingForAssistantOutput&&(s.waitingForAssistantOutput=!1,o.stop(!1)),console.error(`
6
- [session error]`,i.data)})),n.push(t.on("tool.execution_start",i=>{let h=i.data.toolName??"unknown_tool",O=It(i.data.arguments);s.waitingForToolResult=!0,o.stop(!1),process.stdout.write(B(`
6
+ [session error]`,i.data)})),n.push(t.on("tool.execution_start",i=>{let h=i.data.toolName??"unknown_tool",O=Pt(i.data.arguments);s.waitingForToolResult=!0,o.stop(!1),process.stdout.write(B(`
7
7
  [tool] ${h}
8
8
  `)),process.stdout.write(B(`[tool args] ${O}
9
- `)),o.start(`Tool: ${h}`)})),n.push(t.on("tool.execution_complete",i=>{s.waitingForToolResult=!1;let h=Lt(i.data.result,i.data.error,i.data.success),O=i.data.success?"[tool response]":"[tool error]";if(process.stdout.write(B(`${O} ${h}
10
- `)),s.waitingForAssistantOutput){o.start("Assistant");return}o.stop(!1)})),n.push(t.on("assistant.usage",i=>{e.usageTotals.events+=1,e.usageTotals.inputTokens+=I(i.data.inputTokens),e.usageTotals.outputTokens+=I(i.data.outputTokens),e.usageTotals.cacheReadTokens+=I(i.data.cacheReadTokens),e.usageTotals.cacheWriteTokens+=I(i.data.cacheWriteTokens),e.usageTotals.totalNanoAiu+=I(i.data.copilotUsage?.totalNanoAiu)})),n};var Pt=async(t,e)=>new Promise(s=>{t.rl.question(`${D}${e}`,o=>{process.stdout.write(N),s(o)})}),X=(t,e)=>{t.detachSessionHandlers.forEach(s=>s()),t.detachSessionHandlers=lt(e,t)},ut=t=>({model:v,reasoningEffort:q,streaming:!0,tools:t.tools,onPermissionRequest:Ut,onUserInputRequest:async e=>{process.stdout.write(`
9
+ `)),o.start(`Tool: ${h}`)})),n.push(t.on("tool.execution_complete",i=>{s.waitingForToolResult=!1;let h=Ut(i.data.result,i.data.error,i.data.success),O=i.data.success?"[tool response]":"[tool error]";if(process.stdout.write(B(`${O} ${h}
10
+ `)),s.waitingForAssistantOutput){o.start("Assistant");return}o.stop(!1)})),n.push(t.on("assistant.usage",i=>{e.usageTotals.events+=1,e.usageTotals.inputTokens+=I(i.data.inputTokens),e.usageTotals.outputTokens+=I(i.data.outputTokens),e.usageTotals.cacheReadTokens+=I(i.data.cacheReadTokens),e.usageTotals.cacheWriteTokens+=I(i.data.cacheWriteTokens),e.usageTotals.totalNanoAiu+=I(i.data.copilotUsage?.totalNanoAiu)})),n};var kt=async(t,e)=>new Promise(s=>{t.rl.question(`${$}${e}`,o=>{process.stdout.write(D),s(o)})}),X=(t,e)=>{t.detachSessionHandlers.forEach(s=>s()),t.detachSessionHandlers=ut(e,t)},pt=t=>({model:k,reasoningEffort:G,streaming:!0,tools:t.tools,onPermissionRequest:Ft,onUserInputRequest:async e=>{process.stdout.write(`
11
11
  Agent asks: ${e.question}
12
12
  `),e.choices&&e.choices.length>0&&process.stdout.write(`Choices: ${e.choices.join(" | ")}
13
- `);let s=await Pt(t,"You (for agent): ");return{answer:s,wasFreeform:!e.choices?.includes(s)}},workingDirectory:process.cwd(),infiniteSessions:{enabled:!0,backgroundCompactionThreshold:.8,bufferExhaustionThreshold:.95},systemMessage:{content:ot}}),pt=async t=>{let e=ut(t);if(at){let o=await t.client.getLastSessionId();if(o)try{let n=await t.client.resumeSession(o,e);return X(t,n),process.stdout.write(`[session] Resumed ${n.sessionId}
13
+ `);let s=await kt(t,"You (for agent): ");return{answer:s,wasFreeform:!e.choices?.includes(s)}},workingDirectory:process.cwd(),infiniteSessions:{enabled:!0,backgroundCompactionThreshold:.8,bufferExhaustionThreshold:.95},systemMessage:{content:ot}}),dt=async t=>{let e=pt(t);if(ct){let o=await t.client.getLastSessionId();if(o)try{let n=await t.client.resumeSession(o,e);return X(t,n),process.stdout.write(`[session] Resumed ${n.sessionId}
14
14
  `),n}catch(n){console.error("[session] Resume failed, creating a new session:",n)}}let s=await t.client.createSession(e);return X(t,s),process.stdout.write(`[session] Started ${s.sessionId}
15
- `),s},dt=async t=>{let e=ut(t),s=t.requireSession(),o=s.sessionId;await s.disconnect();let n=await t.client.createSession(e);return X(t,n),process.stdout.write(`[session] Switched from ${o} to ${n.sessionId}
16
- `),n};var mt=["|","/","-","\\"],ft=t=>{let e=null,s=0,o="Assistant";return{start:h=>{o=h,t()&&(e||(e=setInterval(()=>{let O=mt[s%mt.length];s+=1,process.stdout.write(`\r${o}: ${O}`)},90)))},stop:(h=!1)=>{e&&(clearInterval(e),e=null),s=0,process.stdout.write("\r\x1B[K"),h&&process.stdout.write(`${o}: `)}}};import{spawn as Ft}from"child_process";import{promises as E}from"fs";import*as u from"path";var kt=t=>t.split(u.sep).join("/"),ht=async t=>{let e=await E.realpath(t),s=a=>{let r=u.relative(e,a);return r.length===0?".":r},o=a=>{let r=u.relative(e,a);if(r.startsWith("..")||u.isAbsolute(r))throw new Error(`Path is outside the working directory: ${a}`)},n=a=>{let r=a.trim();if(!r)throw new Error("Path must be a non-empty string.");let l=u.resolve(e,r);return o(l),l},i=async a=>{let r=n(a),l=await E.realpath(r);return o(l),l},h=async a=>{let r=await i(a),l=await E.stat(r);if(!l.isFile())throw new Error(`Path is not a regular file: ${s(r)}`);return{absolutePath:r,stats:l}},O=async a=>{let r=n(a),l=u.dirname(r);await E.mkdir(l,{recursive:!0});let g=await E.realpath(l);return o(g),r},At=async({command:a,args:r,commandCwd:l,timeoutMs:g,maxOutputBytes:S})=>new Promise((R,T)=>{let d=Ft(a,r,{cwd:l,shell:!1,env:{...process.env,GIT_PAGER:"cat"}}),x="",w="",_=!1,b=!1,m=!1,p,y=(c,f,L)=>{if(c.length>=L)return{text:c,truncated:!0};let U=L-c.length;return f.length<=U?{text:c+f,truncated:!1}:{text:c+f.slice(0,U),truncated:!0}};d.stdout&&d.stdout.on("data",c=>{let f=y(x,c.toString(),S);x=f.text,f.truncated&&(_=!0)}),d.stderr&&d.stderr.on("data",c=>{let f=y(w,c.toString(),S);w=f.text,f.truncated&&(b=!0)}),d.on("error",c=>{p&&clearTimeout(p),T(c)}),p=setTimeout(()=>{m=!0,d.pid&&(process.kill(d.pid,"SIGTERM"),setTimeout(()=>{d.pid&&process.kill(d.pid,"SIGKILL")},1e3))},g),d.on("close",(c,f)=>{p&&clearTimeout(p),R({exitCode:c,signal:f,stdout:x,stderr:w,stdoutTruncated:_,stderrTruncated:b,timedOut:m})})}),J=async({rootDirectory:a,maxEntries:r,includeHidden:l,maxDepth:g,includeDirectories:S,includeFiles:R})=>{let T=[],d=!1,x=async(w,_)=>{if(T.length>=r||T.length>=$){d=!0;return}let b=await E.readdir(w,{withFileTypes:!0});b.sort((m,p)=>m.name.localeCompare(p.name));for(let m of b){if(T.length>=r||T.length>=$){d=!0;return}if(!l&&m.name.startsWith("."))continue;let p=u.join(w,m.name),y=s(p);if(m.isDirectory()){S&&T.push({path:y,type:"directory"}),_<g&&await x(p,_+1);continue}if(m.isFile()){if(R){let c=await E.stat(p);T.push({path:y,type:"file",sizeBytes:c.size})}continue}if(m.isSymbolicLink()){let c=await E.realpath(p);o(c),(R||S)&&T.push({path:y,type:"symlink",target:s(c)})}}};return await x(a,0),{entries:T,truncated:d}},xt=async a=>{let r=await i(a),l=await E.stat(r);if(l.isFile())return{files:[r],truncated:!1};if(l.isDirectory()){let g=await J({rootDirectory:r,maxEntries:$,includeHidden:!1,maxDepth:100,includeDirectories:!1,includeFiles:!0});return{files:g.entries.map(S=>u.resolve(e,S.path)),truncated:g.truncated}}throw new Error(`Path is neither a file nor a directory: ${a}`)};return{workspaceRoot:e,toWorkspacePath:s,resolveExistingPath:i,resolveReadableFile:h,resolveWritableFile:O,executeCommand:At,walkDirectory:J,collectTextMatches:async({query:a,searchPath:r,maxResults:l,caseSensitive:g,useRegex:S,globPattern:R,requireCodeFiles:T})=>{let{files:d,truncated:x}=await xt(r),w=[],_=S?new RegExp(a,g?"g":"gi"):void 0,b=g?a:a.toLowerCase(),m=!1;for(let p of d){if(m)break;let y=u.extname(p).toLowerCase();if(T&&!it.has(y))continue;let c=s(p);if(!u.matchesGlob(kt(c),R))continue;let f=await E.stat(p);if(!f.isFile()||f.size>rt)continue;let L=await E.readFile(p,"utf8");if(L.includes("\0"))continue;let U=L.split(/\r?\n/u);for(let P=0;P<U.length&&!m;P+=1){let C=U[P];if(C.length===0)continue;if(_){_.lastIndex=0;for(let F of C.matchAll(_)){let V=F.index;if(V!==void 0&&(w.push({path:c,line:P+1,column:V+1,preview:C}),w.length>=l)){m=!0;break}}continue}let Q=g?C:C.toLowerCase(),G=0;for(;G<Q.length;){let F=Q.indexOf(b,G);if(F===-1)break;if(w.push({path:c,line:P+1,column:F+1,preview:C}),w.length>=l){m=!0;break}G=F+Math.max(b.length,1)}}}return{matches:w,truncated:x||m}}}};var gt=async t=>{let e=await ht(t);return{tools:[]}};var Tt=t=>{let e=t.usageTotals.inputTokens+t.usageTotals.outputTokens+t.usageTotals.cacheReadTokens+t.usageTotals.cacheWriteTokens,s=t.usageTotals.totalNanoAiu/nt,o=s*k;W!=="none"&&(process.stdout.write(`
15
+ `),s},mt=async t=>{let e=pt(t),s=t.requireSession(),o=s.sessionId;await s.disconnect();let n=await t.client.createSession(e);return X(t,n),process.stdout.write(`[session] Switched from ${o} to ${n.sessionId}
16
+ `),n};var ft=["|","/","-","\\"],ht=t=>{let e=null,s=0,o="Assistant";return{start:h=>{o=h,t()&&(e||(e=setInterval(()=>{let O=ft[s%ft.length];s+=1,process.stdout.write(`\r${o}: ${O}`)},90)))},stop:(h=!1)=>{e&&(clearInterval(e),e=null),s=0,process.stdout.write("\r\x1B[K"),h&&process.stdout.write(`${o}: `)}}};import{spawn as Nt}from"child_process";import{promises as E}from"fs";import*as u from"path";var Mt=t=>t.split(u.sep).join("/"),gt=async t=>{let e=await E.realpath(t),s=a=>{let r=u.relative(e,a);return r.length===0?".":r},o=a=>{let r=u.relative(e,a);if(r.startsWith("..")||u.isAbsolute(r))throw new Error(`Path is outside the working directory: ${a}`)},n=a=>{let r=a.trim();if(!r)throw new Error("Path must be a non-empty string.");let l=u.resolve(e,r);return o(l),l},i=async a=>{let r=n(a),l=await E.realpath(r);return o(l),l},h=async a=>{let r=await i(a),l=await E.stat(r);if(!l.isFile())throw new Error(`Path is not a regular file: ${s(r)}`);return{absolutePath:r,stats:l}},O=async a=>{let r=n(a),l=u.dirname(r);await E.mkdir(l,{recursive:!0});let g=await E.realpath(l);return o(g),r},xt=async({command:a,args:r,commandCwd:l,timeoutMs:g,maxOutputBytes:_})=>new Promise((R,T)=>{let d=Nt(a,r,{cwd:l,shell:!1,env:{...process.env,GIT_PAGER:"cat"}}),x="",w="",S=!1,b=!1,m=!1,p,y=(c,f,L)=>{if(c.length>=L)return{text:c,truncated:!0};let P=L-c.length;return f.length<=P?{text:c+f,truncated:!1}:{text:c+f.slice(0,P),truncated:!0}};d.stdout&&d.stdout.on("data",c=>{let f=y(x,c.toString(),_);x=f.text,f.truncated&&(S=!0)}),d.stderr&&d.stderr.on("data",c=>{let f=y(w,c.toString(),_);w=f.text,f.truncated&&(b=!0)}),d.on("error",c=>{p&&clearTimeout(p),T(c)}),p=setTimeout(()=>{m=!0,d.pid&&(process.kill(d.pid,"SIGTERM"),setTimeout(()=>{d.pid&&process.kill(d.pid,"SIGKILL")},1e3))},g),d.on("close",(c,f)=>{p&&clearTimeout(p),R({exitCode:c,signal:f,stdout:x,stderr:w,stdoutTruncated:S,stderrTruncated:b,timedOut:m})})}),J=async({rootDirectory:a,maxEntries:r,includeHidden:l,maxDepth:g,includeDirectories:_,includeFiles:R})=>{let T=[],d=!1,x=async(w,S)=>{if(T.length>=r||T.length>=v){d=!0;return}let b=await E.readdir(w,{withFileTypes:!0});b.sort((m,p)=>m.name.localeCompare(p.name));for(let m of b){if(T.length>=r||T.length>=v){d=!0;return}if(!l&&m.name.startsWith("."))continue;let p=u.join(w,m.name),y=s(p);if(m.isDirectory()){_&&T.push({path:y,type:"directory"}),S<g&&await x(p,S+1);continue}if(m.isFile()){if(R){let c=await E.stat(p);T.push({path:y,type:"file",sizeBytes:c.size})}continue}if(m.isSymbolicLink()){let c=await E.realpath(p);o(c),(R||_)&&T.push({path:y,type:"symlink",target:s(c)})}}};return await x(a,0),{entries:T,truncated:d}},bt=async a=>{let r=await i(a),l=await E.stat(r);if(l.isFile())return{files:[r],truncated:!1};if(l.isDirectory()){let g=await J({rootDirectory:r,maxEntries:v,includeHidden:!1,maxDepth:100,includeDirectories:!1,includeFiles:!0});return{files:g.entries.map(_=>u.resolve(e,_.path)),truncated:g.truncated}}throw new Error(`Path is neither a file nor a directory: ${a}`)};return{workspaceRoot:e,toWorkspacePath:s,resolveExistingPath:i,resolveReadableFile:h,resolveWritableFile:O,executeCommand:xt,walkDirectory:J,collectTextMatches:async({query:a,searchPath:r,maxResults:l,caseSensitive:g,useRegex:_,globPattern:R,requireCodeFiles:T})=>{let{files:d,truncated:x}=await bt(r),w=[],S=_?new RegExp(a,g?"g":"gi"):void 0,b=g?a:a.toLowerCase(),m=!1;for(let p of d){if(m)break;let y=u.extname(p).toLowerCase();if(T&&!it.has(y))continue;let c=s(p);if(!u.matchesGlob(Mt(c),R))continue;let f=await E.stat(p);if(!f.isFile()||f.size>rt)continue;let L=await E.readFile(p,"utf8");if(L.includes("\0"))continue;let P=L.split(/\r?\n/u);for(let U=0;U<P.length&&!m;U+=1){let C=P[U];if(C.length===0)continue;if(S){S.lastIndex=0;for(let F of C.matchAll(S)){let Q=F.index;if(Q!==void 0&&(w.push({path:c,line:U+1,column:Q+1,preview:C}),w.length>=l)){m=!0;break}}continue}let V=g?C:C.toLowerCase(),j=0;for(;j<V.length;){let F=V.indexOf(b,j);if(F===-1)break;if(w.push({path:c,line:U+1,column:F+1,preview:C}),w.length>=l){m=!0;break}j=F+Math.max(b.length,1)}}}return{matches:w,truncated:x||m}}}};var Tt=async t=>{let e=await gt(t);return{tools:[]}};var wt=t=>{let e=t.usageTotals.inputTokens+t.usageTotals.outputTokens+t.usageTotals.cacheReadTokens+t.usageTotals.cacheWriteTokens,s=t.usageTotals.totalNanoAiu/nt,o=s*N;W!=="none"&&(process.stdout.write(`
17
17
  Session usage summary:
18
18
  `),process.stdout.write(` Input tokens: ${t.usageTotals.inputTokens}
19
19
  `),process.stdout.write(` Output tokens: ${t.usageTotals.outputTokens}
@@ -22,17 +22,20 @@ Session usage summary:
22
22
  `),process.stdout.write(` Cache read tokens: ${t.usageTotals.cacheReadTokens}
23
23
  `),process.stdout.write(` Cache write tokens: ${t.usageTotals.cacheWriteTokens}
24
24
  `),process.stdout.write(` Estimated cost: ${s.toFixed(6)} AIU
25
- `),k>0?process.stdout.write(` Estimated cost (USD): ${st(o)} (COPILOT_USD_PER_AIU=${k})
25
+ `),N>0?process.stdout.write(` Estimated cost (USD): ${st(o)} (COPILOT_USD_PER_AIU=${N})
26
26
  `):process.stdout.write(` Estimated cost (USD): set COPILOT_USD_PER_AIU to enable USD estimate
27
- `)))};var{tools:Mt}=await gt(process.cwd()),Nt=wt.createInterface({input:process.stdin,output:process.stdout}),j=class{constructor(e){this.client=e;this.spinner=ft(()=>!this.isShuttingDown&&!this.isInputClosed)}session=null;rl=Nt;tools=Mt;detachSessionHandlers=[];isShuttingDown=!1;isInputClosed=!1;uiState={waitingForAssistantOutput:!1,waitingForToolResult:!1};usageTotals={events:0,inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,totalNanoAiu:0};spinner;async init(){let e=await pt(this);this.setSession(e)}setSession(e){this.session=e}requireSession(){if(!this.session)throw new Error("No active session available.");return this.session}async cleanupAndExit(){if(this.isShuttingDown)return;if(this.isShuttingDown=!0,this.uiState.waitingForAssistantOutput=!1,this.uiState.waitingForToolResult=!1,this.spinner.stop(!1),this.detachSessionHandlers.forEach(s=>s()),this.detachSessionHandlers=[],this.session)try{await this.session.disconnect()}catch(s){console.error("[shutdown] session disconnect warning",s)}Tt(this);try{await this.client.stop()}catch(s){console.error("[shutdown] client stop warning",s)}this.rl.close(),process.exitCode=0,setTimeout(()=>{process.exit(0)},25).unref()}listenToShutdownSignals(){this.rl.on("close",()=>{this.isShuttingDown=!0,this.isInputClosed=!0}),process.on("unhandledRejection",e=>{this.isShuttingDown||console.error("[unhandled rejection]",e)}),process.on("SIGINT",async()=>{process.stdout.write(`
27
+ `)))};var{tools:Dt}=await Tt(process.cwd()),$t=Et.createInterface({input:process.stdin,output:process.stdout}),H=class{constructor(e){this.client=e;this.spinner=ht(()=>!this.isShuttingDown&&!this.isInputClosed)}session=null;rl=$t;tools=Dt;detachSessionHandlers=[];isShuttingDown=!1;isInputClosed=!1;uiState={waitingForAssistantOutput:!1,waitingForToolResult:!1};usageTotals={events:0,inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,totalNanoAiu:0};spinner;async init(){let e=await dt(this);this.setSession(e)}setSession(e){this.session=e}requireSession(){if(!this.session)throw new Error("No active session available.");return this.session}async cleanupAndExit(){if(this.isShuttingDown)return;if(this.isShuttingDown=!0,this.uiState.waitingForAssistantOutput=!1,this.uiState.waitingForToolResult=!1,this.spinner.stop(!1),this.detachSessionHandlers.forEach(s=>s()),this.detachSessionHandlers=[],this.session)try{await this.session.disconnect()}catch(s){console.error("[shutdown] session disconnect warning",s)}wt(this);try{await this.client.stop()}catch(s){console.error("[shutdown] client stop warning",s)}this.rl.close(),process.exitCode=0,setTimeout(()=>{process.exit(0)},25).unref()}listenToShutdownSignals(){this.rl.on("close",()=>{this.isShuttingDown=!0,this.isInputClosed=!0}),process.on("unhandledRejection",e=>{this.isShuttingDown||console.error("[unhandled rejection]",e)}),process.on("SIGINT",async()=>{process.stdout.write(`
28
28
  Shutting down...
29
- `),await this.cleanupAndExit()})}};import{fileURLToPath as Dt}from"url";var Et=async t=>{let e=await t.getAuthStatus();if(!e.isAuthenticated){let s=H?"A token was provided but authentication still failed. Verify your token has Copilot access.":"No token detected. Authenticate with `copilot auth login` (or set GITHUB_TOKEN / GH_TOKEN).";console.error("Copilot authentication is not configured."),e.statusMessage&&console.error(`Status: ${e.statusMessage}`),console.error(s),await t.stop(),process.exit(1)}},St=()=>{console.log("System Commands:"),console.log(" /help Show commands"),console.log(" /status Show auth + session info"),console.log(" /models List available models"),console.log(" /new Start a fresh session"),console.log(` exit|quit|q Leave the agent
29
+ `),await this.cleanupAndExit()})}};import{fileURLToPath as vt}from"url";var _t=async t=>{let e=await t.getAuthStatus();if(!e.isAuthenticated){let s=q?"A token was provided but authentication still failed. Verify your token has Copilot access.":"No token detected. Authenticate with `copilot auth login` (or set GITHUB_TOKEN / GH_TOKEN).";console.error("Copilot authentication is not configured."),e.statusMessage&&console.error(`Status: ${e.statusMessage}`),console.error(s),await t.stop(),process.exit(1)}},St=()=>{console.log(`
30
+ System Commands:`),console.log(" /help Show commands"),console.log(" /status Show auth + session info"),console.log(" /models List available models"),console.log(" /new Start a fresh session"),console.log(` exit|quit|q Leave the agent
30
31
  `),console.log("----------------------------------------------------------------"),console.log(`
31
- Test Generation Commands:`),console.log(" /init Init E2E tests from zero"),console.log(" /custom-tests Add custom E2E test based on your input"),console.log(" /diff-test Add E2E test based on code diff")},_t=()=>{console.log("Copilot SDK Interactive Assistant"),console.log("Type your message and press Enter. Use 'exit', 'quit', or 'q' to quit."),St()},z=async t=>{let e=Dt(new URL(`../prompts/${t}`,import.meta.url));return await et(e,{onError:o=>{console.error(`[prompt] could not read ${e}; continuing without startup prompt`,o)}})},$t=async t=>{try{let e=await fetch(t);return e.ok?await e.text():(console.error(`[prompt] could not fetch ${t}; HTTP ${e.status} ${e.statusText}`),"")}catch(e){return console.error(`[prompt] could not fetch ${t}`,e),""}},A=t=>{if(!(t.isShuttingDown||t.isInputClosed)){if(process.stdin.readableEnded||process.stdin.destroyed){t.isInputClosed=!0,t.cleanupAndExit();return}try{t.rl.question(`${D}You: `,async e=>{if(process.stdout.write(N),t.isShuttingDown||t.isInputClosed)return;let s=e.trim().toLowerCase();if(s==="exit"||s==="quit"||s==="q"){await t.cleanupAndExit();return}if(s==="/help"){St(),A(t);return}if(s==="/new"){try{t.setSession(await dt(t))}catch(n){console.error("[request failed] could not start a new session",n)}A(t);return}if(s==="/status"){try{let n=await t.client.getAuthStatus(),i=t.requireSession();console.log(`
32
- Status`),console.log(` Session: ${i.sessionId}`),console.log(` Model: ${v}`),console.log(` Reasoning: ${q}`),console.log(` Request timeout: ${M}ms`),console.log(` Authenticated: ${n.isAuthenticated}`),n.login&&console.log(` Login: ${n.login}`)}catch(n){console.error("[request failed] could not read status",n)}process.stdout.write(`
32
+ Test Generation Commands:`),console.log(" /init Init E2E tests from zero"),console.log(" /custom-tests Add custom E2E test based on your input"),console.log(" /diff-test Add E2E test based on code diff")},At=()=>{console.log(`
33
+
34
+ Welcome to LeverAgent, your E2E testing assistant!`),console.log(`You're currently using version: ${at} with the following model: ${k}`),console.log("Type your message and press Enter. Use 'exit', 'quit', or 'q' to quit."),St()},K=async t=>{let e=vt(new URL(`../prompts/${t}`,import.meta.url));return await et(e,{onError:o=>{console.error(`[prompt] could not read ${e}; continuing without startup prompt`,o)}})},Gt=async t=>{try{let e=await fetch(t);return e.ok?await e.text():(console.error(`[prompt] could not fetch ${t}; HTTP ${e.status} ${e.statusText}`),"")}catch(e){return console.error(`[prompt] could not fetch ${t}`,e),""}},A=t=>{if(!(t.isShuttingDown||t.isInputClosed)){if(process.stdin.readableEnded||process.stdin.destroyed){t.isInputClosed=!0,t.cleanupAndExit();return}try{t.rl.question(`${$}You: `,async e=>{if(process.stdout.write(D),t.isShuttingDown||t.isInputClosed)return;let s=e.trim().toLowerCase();if(s==="exit"||s==="quit"||s==="q"){await t.cleanupAndExit();return}if(s==="/help"){St(),A(t);return}if(s==="/new"){try{t.setSession(await mt(t))}catch(n){console.error("[request failed] could not start a new session",n)}A(t);return}if(s==="/status"){try{let n=await t.client.getAuthStatus(),i=t.requireSession();console.log(`
35
+ Status`),console.log(` Session: ${i.sessionId}`),console.log(` Model: ${k}`),console.log(` Reasoning: ${G}`),console.log(` Request timeout: ${M}ms`),console.log(` Authenticated: ${n.isAuthenticated}`),n.login&&console.log(` Login: ${n.login}`)}catch(n){console.error("[request failed] could not read status",n)}process.stdout.write(`
33
36
  `),A(t);return}if(s==="/models"){try{let i=(await t.client.listModels()).slice(0,20);console.log(`
34
37
  Available models (first 20):`),i.forEach(h=>{console.log(` - ${h.id}`)})}catch(n){console.error("[request failed] could not list models",n)}process.stdout.write(`
35
- `),A(t);return}if(!e.trim()){A(t);return}let o=e;if(s==="/init"?o=await z("init.md"):s==="/custom-tests"?o=await z("custom-test.md"):s==="/diff-test"?o=await $t("https://gist.githubusercontent.com/marcellkiss/fbe9294d4de00c2ef11f1437919353b7/raw/16a8ae53a9019386ef5fea5d321934d5bec70188/diff-test.md"):s==="/t"&&(o=await z("test.md")),!o.trim()){console.error("[prompt] loaded prompt is empty; request was not sent"),A(t);return}process.stdout.write("Assistant: "),t.uiState.waitingForAssistantOutput=!0,t.spinner.start("Assistant");try{await t.requireSession().sendAndWait({prompt:o},M)}catch(n){t.uiState.waitingForAssistantOutput=!1,t.spinner.stop(!1),n instanceof Error&&n.message.includes("Timeout after")?console.error(`
38
+ `),A(t);return}if(!e.trim()){A(t);return}let o=e;if(s==="/init"?o=await K("init.md"):s==="/custom-tests"?o=await K("custom-test.md"):s==="/diff-test"?o=await Gt("https://gist.githubusercontent.com/marcellkiss/fbe9294d4de00c2ef11f1437919353b7/raw/16a8ae53a9019386ef5fea5d321934d5bec70188/diff-test.md"):s==="/t"&&(o=await K("test.md")),!o.trim()){console.error("[prompt] loaded prompt is empty; request was not sent"),A(t);return}process.stdout.write("Assistant: "),t.uiState.waitingForAssistantOutput=!0,t.spinner.start("Assistant");try{await t.requireSession().sendAndWait({prompt:o},M)}catch(n){t.uiState.waitingForAssistantOutput=!1,t.spinner.stop(!1),n instanceof Error&&n.message.includes("Timeout after")?console.error(`
36
39
  [request failed] ${n.message}. Increase COPILOT_REQUEST_TIMEOUT_MS (current: ${M}ms).`):console.error(`
37
40
  [request failed]`,n)}process.stdout.write(`
38
- `),!t.isShuttingDown&&!t.isInputClosed&&A(t)})}catch(e){if(e&&typeof e=="object"&&"code"in e&&e.code==="ERR_USE_AFTER_CLOSE"){t.isInputClosed=!0,t.cleanupAndExit();return}throw e}}};var K=new vt({githubToken:H,useLoggedInUser:!0,autoRestart:!1});await K.start();await Et(K);var Y=new j(K);await Y.init();_t();A(Y);Y.listenToShutdownSignals();
41
+ `),!t.isShuttingDown&&!t.isInputClosed&&A(t)})}catch(e){if(e&&typeof e=="object"&&"code"in e&&e.code==="ERR_USE_AFTER_CLOSE"){t.isInputClosed=!0,t.cleanupAndExit();return}throw e}}};var z=new qt({githubToken:q,useLoggedInUser:!0,autoRestart:!1});await z.start();await _t(z);var Y=new H(z);await Y.init();At();A(Y);Y.listenToShutdownSignals();
package/dist/cli.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{existsSync as n}from"fs";import{copyFile as c}from"fs/promises";import{createRequire as a}from"module";import{dirname as p,join as s}from"path";var m=async()=>{let i=a(import.meta.url).resolve("vscode-jsonrpc/package.json"),r=p(i),e=s(r,"node"),t=s(r,"node.js");n(e)||!n(t)||await c(t,e)};try{await m()}catch(o){console.error("[bootstrap warning] could not prepare vscode-jsonrpc compatibility shim",o)}await import("./agentRunner-FJ3IRLV7.js");
2
+ import{existsSync as n}from"fs";import{copyFile as c}from"fs/promises";import{createRequire as a}from"module";import{dirname as p,join as s}from"path";var m=async()=>{let i=a(import.meta.url).resolve("vscode-jsonrpc/package.json"),r=p(i),e=s(r,"node"),t=s(r,"node.js");n(e)||!n(t)||await c(t,e)};try{await m()}catch(o){console.error("[bootstrap warning] could not prepare vscode-jsonrpc compatibility shim",o)}await import("./agentRunner-KXOMLN2S.js");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leveragent/e2e-testing",
3
- "version": "0.1.2",
3
+ "version": "0.1.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,6 +12,7 @@
12
12
  "README.md"
13
13
  ],
14
14
  "scripts": {
15
+ "prebuild": "node scripts/inject-package-version.mjs",
15
16
  "build": "rm -rf dist && npx tsup src/cli.ts --format esm --dts --minify",
16
17
  "start": "tsx src/agentRunner.ts",
17
18
  "dev": "tsx watch src/agentRunner.ts",