@testmuai/kane-cli 0.3.4 → 0.3.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.
- package/dist/{ChromeProfilePicker-DLK4RTFZ.js → ChromeProfilePicker-H4OBHZ2O.js} +1 -1
- package/dist/{CliFeedbackPrompt-HNB4SHPG.js → CliFeedbackPrompt-TVXNCWLX.js} +1 -1
- package/dist/{CliUploadProgress-6KB7IKFV.js → CliUploadProgress-Z3FSUSUL.js} +1 -1
- package/dist/{ConfigView-LMW2B764.js → ConfigView-3YAJ7ILS.js} +1 -1
- package/dist/FolderPicker-WFGOWR2V.js +2 -0
- package/dist/{HelpView-6HAZNUNN.js → HelpView-7LKN3TJT.js} +1 -1
- package/dist/{InfoBox-6OL6MFL6.js → InfoBox-57AAACTY.js} +1 -1
- package/dist/{LinksBox-Q6L6WY53.js → LinksBox-LGB3H7NO.js} +1 -1
- package/dist/{ProfilesView-ERKUUJWU.js → ProfilesView-4Z3QHZOC.js} +1 -1
- package/dist/ProjectPicker-EXI7U76F.js +2 -0
- package/dist/{SaveSessionPrompt-GKITQ3KR.js → SaveSessionPrompt-OUXIE3TS.js} +1 -1
- package/dist/SingleShotApp-HOPZGLDV.js +2 -0
- package/dist/{SummaryBox-MB2JQIXZ.js → SummaryBox-63JMAMEH.js} +1 -1
- package/dist/{TestMdRunView-UMTYIRAE.js → TestMdRunView-5NGUC56R.js} +1 -1
- package/dist/{WhoamiView-UF5WWELM.js → WhoamiView-ROUT7L3F.js} +1 -1
- package/dist/{changelog-JFMKP277.js → changelog-HFYALWQT.js} +1 -1
- package/dist/{chunk-TI5CHPPN.js → chunk-2IAYS2ZB.js} +1 -1
- package/dist/{chunk-MIZDUPND.js → chunk-67BQCZWE.js} +1 -1
- package/dist/{chunk-6566EYUL.js → chunk-6EZHIVLZ.js} +1 -1
- package/dist/{chunk-PQLKQKQH.js → chunk-6ISGQNS2.js} +1 -1
- package/dist/{chunk-LIJX5PIV.js → chunk-7CLUJYMW.js} +1 -1
- package/dist/{chunk-LT4VR7MQ.js → chunk-7DDXXT4W.js} +2 -2
- package/dist/{chunk-VKPAHDXM.js → chunk-7F4LHGTO.js} +1 -1
- package/dist/{chunk-BNLJNHAZ.js → chunk-7QXTYKSW.js} +1 -1
- package/dist/chunk-BPF7TDRU.js +2 -0
- package/dist/{chunk-ND5EFB3C.js → chunk-DKHTWC7S.js} +1 -1
- package/dist/{chunk-FOT6AMNP.js → chunk-DTQJGYDA.js} +1 -1
- package/dist/{chunk-OFX2RC33.js → chunk-DY2ZW7XX.js} +1 -1
- package/dist/{chunk-535PXOLA.js → chunk-EMWJ6YF6.js} +1 -1
- package/dist/{chunk-RHLK4XYO.js → chunk-FITKUFJG.js} +1 -1
- package/dist/chunk-FVOT76XR.js +13 -0
- package/dist/chunk-GPR5DODR.js +5 -0
- package/dist/{chunk-FOMM3MYV.js → chunk-I3AGHICC.js} +1 -1
- package/dist/{chunk-EJR3WRTW.js → chunk-IXNVLVFT.js} +1 -1
- package/dist/{chunk-TXUKXLYR.js → chunk-LZX6NTDJ.js} +1 -1
- package/dist/{chunk-KKZRPFWO.js → chunk-NLCCBXXV.js} +1 -1
- package/dist/{chunk-6JONCMIS.js → chunk-NLP4UA2F.js} +1 -1
- package/dist/{chunk-LJA5UGU6.js → chunk-NVUVNXTE.js} +1 -1
- package/dist/{chunk-ZYJ4HQAI.js → chunk-OOKRZUN4.js} +1 -1
- package/dist/{chunk-ZCHXYZGV.js → chunk-RSXBXGXL.js} +1 -1
- package/dist/chunk-RZ4F3BHX.js +3 -0
- package/dist/{chunk-VZIBZDS2.js → chunk-SLGV3RDD.js} +1 -1
- package/dist/{chunk-CBDUXGVQ.js → chunk-TC74YD2D.js} +1 -1
- package/dist/{chunk-KA23QNUA.js → chunk-TQAOXA7C.js} +1 -1
- package/dist/{chunk-V7M72PLH.js → chunk-VUIXILBR.js} +11 -11
- package/dist/chunk-WAOCHXJ5.js +2 -0
- package/dist/{chunk-T3JEMMTA.js → chunk-X6XWDJ5U.js} +1 -1
- package/dist/{chunk-YEV3OBEO.js → chunk-XR6QKTHK.js} +1 -1
- package/dist/controller-client-RD2YEMAH.js +2 -0
- package/dist/index.js +35 -35
- package/dist/login-flow-VJWYUHU3.js +2 -0
- package/dist/{persist-recorded-session-CDT2I4SH.js → persist-recorded-session-A2KBQ5MZ.js} +1 -1
- package/dist/pipeline-L3VM7QEX.js +2 -0
- package/dist/{recording-banner-YFDZ6CJ4.js → recording-banner-ZRJAZLAK.js} +1 -1
- package/dist/{resolver-F6HCOZOX.js → resolver-OA35IO7J.js} +1 -1
- package/dist/run-test-md-E2K4GEOB.js +64 -0
- package/dist/{testmd-actions-D3TJX2Q4.js → testmd-actions-AUBFHDIP.js} +2 -2
- package/dist/tms-client-R5ZIAOBH.js +2 -0
- package/dist/{validate-basic-LTATIAAW.js → validate-basic-XCW5LHJF.js} +1 -1
- package/dist/{version-check-Q6M7YAML.js → version-check-MK3U56PI.js} +1 -1
- package/package.json +5 -5
- package/dist/FolderPicker-JBOPRMPT.js +0 -2
- package/dist/ProjectPicker-Y4AXSEVW.js +0 -2
- package/dist/SingleShotApp-MKACYNG2.js +0 -2
- package/dist/chunk-ANOIEEVS.js +0 -13
- package/dist/chunk-CB4WEGVB.js +0 -5
- package/dist/chunk-GCAHPH2E.js +0 -2
- package/dist/chunk-HZUU7USC.js +0 -2
- package/dist/chunk-IFWLAQ3L.js +0 -2
- package/dist/chunk-JI7KJKG4.js +0 -2
- package/dist/chunk-V7QXJKX7.js +0 -3
- package/dist/controller-client-OMKEBP4B.js +0 -2
- package/dist/logging-M7EYIZTV.js +0 -2
- package/dist/login-flow-THKISL7X.js +0 -2
- package/dist/machine-id-DZN4MYOO.js +0 -2
- package/dist/pipeline-IF775CGJ.js +0 -2
- package/dist/run-test-md-6ELVP2MT.js +0 -65
- package/dist/tms-client-T3EAD4Y7.js +0 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{a}from"./chunk-NLP4UA2F.js";import"./chunk-6ISGQNS2.js";import"./chunk-TC74YD2D.js";import"./chunk-DTQJGYDA.js";import"./chunk-RZ4F3BHX.js";import"./chunk-UR6MHSHU.js";export{a as LoginFlow};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as h}from"./chunk-OQZG3V6B.js";import{g as S}from"./chunk-X7VI7KK3.js";import{a as m,b as I,j as _}from"./chunk-AH4AXJML.js";import"./chunk-L5LI2JF4.js";import{a as f}from"./chunk-
|
|
2
|
+
import{a as h}from"./chunk-OQZG3V6B.js";import{g as S}from"./chunk-X7VI7KK3.js";import{a as m,b as I,j as _}from"./chunk-AH4AXJML.js";import"./chunk-L5LI2JF4.js";import{a as f}from"./chunk-XR6QKTHK.js";import"./chunk-DTQJGYDA.js";import"./chunk-UR6MHSHU.js";function y(e,d={}){e.flushRecorder();let o=e.recorder?.lastWrittenPath??null;if(!o)return e.log("info","PERSIST_SKIPPED","No recorded path \u2014 recorder.flush no-op",{reason:e.sessionName?"recorder_flush_failed":"no_session_name",session_name:e.sessionName}),null;let p;try{p=h(o)}catch(t){throw e.log("error","PERSIST_RESOLVE_FAILED","resolveTestMd threw",{error:t.message,recorded_path:o}),t}let i=e.getRunsAsStepRecords(),u=e.getFlows(),a=[],c=0;for(let t=0;t<i.length;t++){let r=i[t],l=u.slice(c,c+r.totalRunDirs);c+=r.totalRunDirs;let g=l.find(n=>n.status==="failed"||n.status==="error"),R=g?"failed":l.length===0?"skipped":"passed";a.push({rootStepIndex:t+1,status:R,duration_s:l.reduce((n,D)=>n+(D.duration??0),0),reason:g?.reason})}let P=a.some(t=>t.status==="failed")?"failed":"passed",E=new f().load().code_export?.language==="javascript"?"javascript":"python",s=I(o);e.log("info","PERSIST_START","Building staging dir",{recorded_path:o,output_dir:s,session_dir:e.sessionDir,step_count:i.length,flow_count:u.length});try{S({resolvedTest:p,sessionDir:e.sessionDir,stepRunRecords:i,outcomes:a,overallStatus:P,startedISO:e.startedAt,durationS:a.reduce((t,r)=>t+(r.duration_s??0),0),sessionId:e.sessionId,commitId:e.sessionId,tmsIds:{testId:e.testId??void 0,testcaseId:d.testcaseId,projectId:d.projectId,folderId:d.folderId,orgId:d.orgId??e.orgId??void 0,sessionName:e.sessionName??m(o)},codeExportDir:d.codeExportDir,codeExportLanguage:E}),e.log("info","PERSIST_STAGING_OK","Staging dir built",{output_dir:s}),_(s),e.log("info","PERSIST_OK","Persist complete",{output_dir:s})}catch(t){let r=t;e.log("error","PERSIST_FAILED","staging build / atomic replace failed",{error:r.message,stack:r.stack,output_dir:s}),process.stderr.write(`[persist] staging build / atomic replace failed: ${r.message}
|
|
3
3
|
`)}return{recordedTestPath:o,outputDir:s}}export{y as persistRecordedSession};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{a}from"./chunk-VUIXILBR.js";import"./chunk-MDBXYXSC.js";import"./chunk-WAOCHXJ5.js";import"./chunk-7CLUJYMW.js";import"./chunk-NLCCBXXV.js";import"./chunk-RZ4F3BHX.js";import"./chunk-UR6MHSHU.js";export{a as UploadPipeline};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
2
|
import{a as n}from"./chunk-3MSXQU2C.js";import"./chunk-UR6MHSHU.js";function p(t){let s=t.sessionName!==null,e={type:"recording_state",enabled:!0,session_id:t.sessionId,persist:s};return t.sessionName&&(e.session_name=t.sessionName),t.testPath&&(e.test_path=t.testPath),t.outputPath&&(e.output_path=t.outputPath),e}async function g(t){if(t.isAgent){process.stdout.write(JSON.stringify(p(t))+`
|
|
3
|
-
`);return}let s=(await import("./react-QWOAB3TB.js")).default,{render:e,useApp:a}=await import("./build-JIKYOZUH.js"),{useEffect:o}=s,{InfoBox:r}=await import("./InfoBox-
|
|
3
|
+
`);return}let s=(await import("./react-QWOAB3TB.js")).default,{render:e,useApp:a}=await import("./build-JIKYOZUH.js"),{useEffect:o}=s,{InfoBox:r}=await import("./InfoBox-57AAACTY.js"),u=t.sessionName?[{label:"session",value:t.sessionName},{label:"test",value:n(t.testPath??"")},{label:"output",value:n(t.outputPath??"")}]:[{label:"session",value:"ephemeral"},{label:"note",value:"use /name <name> to persist this session"}];function l(){let{exit:i}=a();return o(()=>{let c=setTimeout(()=>i(),50);return()=>clearTimeout(c)},[i]),s.createElement(r,{title:"Recording",titleColor:"#ff9500",rows:u})}await e(s.createElement(l),{stdout:process.stderr}).waitUntilExit()}export{p as buildRecordingStateEvent,g as printRecordingBanner};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a}from"./chunk-
|
|
2
|
+
import{a}from"./chunk-BPF7TDRU.js";import"./chunk-WAOCHXJ5.js";import"./chunk-NLCCBXXV.js";import"./chunk-RZ4F3BHX.js";import"./chunk-UR6MHSHU.js";export{a as AuthResolver};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{a as qt}from"./chunk-FITKUFJG.js";import{a as Nt}from"./chunk-OQZG3V6B.js";import{a as de,b as zt}from"./chunk-C5UNZ6ZY.js";import{A as Bt,a as ft,b as mt,f as bt,g as Me,h as $e,i as yt,j as St,k as vt,m as Re,n as It,o as kt,p as _t,q as Ct,r as At,s as Et,t as Ke,u as Tt,v as jt,w as Dt,x as Lt,y as Ut,z as $t}from"./chunk-FVOT76XR.js";import{b as Ge,c as Mt,d as Vt}from"./chunk-I3AGHICC.js";import{c as wt}from"./chunk-S3DAAAE5.js";import{a as Ft,b as Be,c as qe,d as ze,e as He}from"./chunk-X7VI7KK3.js";import{a as ye,b as xt,c as Pt,e as Se,f as Ve,i as Ot}from"./chunk-AH4AXJML.js";import{a as pt}from"./chunk-6EZHIVLZ.js";import"./chunk-L5LI2JF4.js";import{a as ht}from"./chunk-XR6QKTHK.js";import{b as Ne}from"./chunk-GPR5DODR.js";import{a as gt,c as Ue,d as Q,e as J}from"./chunk-G7VF5SDK.js";import"./chunk-VE3SUJMA.js";import{a as ut}from"./chunk-6ISGQNS2.js";import{a as ne}from"./chunk-TC74YD2D.js";import"./chunk-BPF7TDRU.js";import{a as Rt}from"./chunk-VUIXILBR.js";import"./chunk-MDBXYXSC.js";import"./chunk-WAOCHXJ5.js";import"./chunk-E47GFYXA.js";import{c as Le,h as re}from"./chunk-DTQJGYDA.js";import"./chunk-7CLUJYMW.js";import"./chunk-NLCCBXXV.js";import"./chunk-RZ4F3BHX.js";import"./chunk-UR6MHSHU.js";import{resolve as Ar,join as ke,basename as Er}from"path";import{existsSync as Xe,readFileSync as xr}from"fs";import{existsSync as Ye}from"fs";import{join as we,basename as Ht}from"path";function Kt(e,t){if(!t||!Ye(t))return e.steps.map(()=>({kind:"author",reason:"no-result-md"}));let r=qe(t),o=[],s=new Set,d=new Map;function i(a){let S=ze(a),_=we(S,"Result.md");if(d.has(_))return d.get(_);let I=Ye(_)?qe(_):null;return d.set(_,I),I}function R(a){for(let S=1;S<a.trace.length;S++){let I=a.trace[S-1].file===e.rootPath?r:i(a.trace.slice(0,S));if(!I)return{kind:"author",reason:"no-result-md"};let F=a.trace[S-1].stepIndex,f=I.steps[F-1];if(!f)return{kind:"author",reason:"no-result-md"};if(f.kind!=="import")return{kind:"author",reason:"structure-mismatch"};let C=Ht(f.importPath),w=Ht(a.trace[S].file);if(C!==w)return{kind:"author",reason:"structure-mismatch"};if(f.status!=="passed")return{kind:"author",reason:"recorded-failed"}}return null}for(let a of e.steps){let S=a.trace[a.trace.length-1].file,_=a.trace[a.trace.length-1].stepIndex,I=s.has(S);for(let w=0;w<a.trace.length-1&&!I;w++)s.has(a.trace[w].file)&&(I=!0);if(I){o.push({kind:"author",reason:"downstream-of-divergence"});continue}let F=R(a);if(F){o.push(F);for(let w=0;w<a.trace.length;w++)s.add(a.trace[w].file);continue}let f=S===e.rootPath?r:i(a.trace),C=wr(a,f,_);if(o.push(C),C.kind==="author"){s.add(S);for(let w=0;w<a.trace.length-1;w++)s.add(a.trace[w].file)}}return o}function wr(e,t,r){if(!t)return{kind:"author",reason:"no-result-md"};let o=t.steps[r-1];if(!o)return{kind:"author",reason:"no-result-md"};if(o.kind!=="objective")return{kind:"author",reason:"structure-mismatch"};if(o.status!=="passed")return{kind:"author",reason:"recorded-failed"};let s=Ft(e);if(s!==o.md5)return{kind:"author",reason:"md5-mismatch"};let d=e.trace.length===1?Ot(e.trace[0].file,r,s.slice(0,8)):we(ze(e.trace),".internal","steps",`${r}-${s.slice(0,8)}`),i=we(d,"flows","0","actions.ndjson");return Ye(i)?{kind:"replay",recordingDir:d}:{kind:"author",reason:"missing-recording"}}function Gt(e){return e.some(t=>t.kind==="author")}function ve(e){for(let t=0;t<e.length;t++)if(e[t].kind==="author")return t;return e.length}function Yt(e){return we(e.recordingDir,"flows","0","actions.ndjson")}function Wt(e,t){if(process.env.KANE_REPLAY_TRACE==="1")for(let r=0;r<e.steps.length;r++){let o=e.steps[r],s=t[r],d=" ".repeat(o.trace.length-1),i=`step ${o.flatIndex}`;s.kind==="replay"?process.stderr.write(`[replay-trace] ${d}${i}: REPLAY (would skip; v1 always authors)
|
|
3
|
+
`):process.stderr.write(`[replay-trace] ${d}${i}: AUTHOR (${s.reason})
|
|
4
|
+
`)}}function se(e){process.env.KANE_REPLAY_TRACE==="1"&&process.stderr.write(e)}function Zt(e,t){let r=e===0?"(none)":`0..${e-1}`,o=e>=t?"(none)":`${e}..${t-1}`;se(`[replay-trace] phase: replay ${r}, author ${o}
|
|
5
|
+
`)}function Qt(e,t){se(`[replay-trace] step ${e}: REPLAY ${t==="ok"?"OK":"FAILED"}
|
|
6
|
+
`)}function Jt(e,t,r){se(`[replay-trace] shrink ${e}/${t} \u2192 new boundary ${r}
|
|
7
|
+
`)}function Xt(e,t){se(`[replay-trace] complete-reauthor (${e} shrinks exhausted of ${t})
|
|
8
|
+
`)}function er(){se(`[replay-trace] force-author (--author) \u2014 walker bypassed
|
|
9
|
+
`)}function tr(e){se(`[replay-trace] cancelled at step ${e}
|
|
10
|
+
`)}import{join as vr}from"path";function We(e){let t={objective:e.step.objective,model:"v16-alpha",width:e.windowSize.width,height:e.windowSize.height,session_id:e.sessionId,run_index:e.runIndex,stream:!0,mode:"replay",replay:{recording_path:Yt(e.decision),step_label:e.step.objective},screenshot_dir:vr(e.sessionDir,"runs",String(e.runIndex)),run_id:"run",test_id:"test"};return e.forceNavigateUrl&&(t.url=e.forceNavigateUrl),e.chrome.wsEndpoint?t.ws_endpoint=e.chrome.wsEndpoint:e.chrome.cdpEndpoint&&(t.cdp_endpoint=e.chrome.cdpEndpoint),e.auth.basicAuth?(t.username=e.auth.basicAuth.username,t.access_key=e.auth.basicAuth.access_key):e.auth.token&&(t.auth={type:"bearer",token:e.auth.token}),e.variables&&Object.keys(e.variables).length>0&&(t.variables=e.variables),e.sessionContext&&(t.session_context=e.sessionContext),t}async function rr(e){let t=ve(e.decisions),r=0,o=!1;for(;;){let s=e.session.snapshot(),d=e.accumulator.snapshot(),i=await e.runReplayPhase(t);if(i.cancelled)return o=!0,tr(i.failedAt??0),{authorBoundary:t,cancelledInPhase:o,shrinkCount:r};if(i.failedAt===null)return{authorBoundary:t,cancelledInPhase:o,shrinkCount:r};let R=zt({failedAt:i.failedAt,shrinkCount:r,hasRetry:e.hasRetry,maxShrinks:e.maxShrinks});if(R.kind==="fail")return{authorBoundary:-1,cancelledInPhase:o,shrinkCount:r};if(e.acquireLockIfNeeded&&!await e.acquireLockIfNeeded())return{authorBoundary:-1,cancelledInPhase:o,shrinkCount:r};if(e.session.rollback(s),e.accumulator.rollback(d),R.kind==="complete-reauthor")return Xt(r+1,e.maxShrinks),{authorBoundary:0,cancelledInPhase:o,shrinkCount:r};r++,Jt(r,de.maxShrinks,R.newAuthorBoundary),t=R.newAuthorBoundary}}var Ir=60*1e3,nr="lock-heartbeat",oe=null;function Ze(e){oe===null&&(oe=setInterval(async()=>{let t=await Tt({baseUrl:e.baseUrl,testId:e.testId,auth:e.auth});if(!t.ok){let r=t.expired?"session expired":t.message;process.stderr.write(`[lock] heartbeat failed: ${r}; continuing run
|
|
11
|
+
`)}},Ir),Q(nr,()=>{oe!==null&&(clearInterval(oe),oe=null)}))}function Qe(){oe!==null&&J(nr,"stopped")}var Ie=class{constructor(t){this.resolved=t;this.outcomes=t.rootSteps.map(r=>({rootStepIndex:r.index,status:"skipped"}))}outcomes;skipRoot=null;overallHalted=!1;shouldRunFlatStep(t){if(this.overallHalted)return!1;let r=t.trace[0].stepIndex;return!(this.skipRoot!==null&&r===this.skipRoot)}recordStep(t,r){let o=t.trace[0].stepIndex,s=this.outcomes.find(a=>a.rootStepIndex===o),d=this.resolved.rootSteps.find(a=>a.index===o),i=d.body.kind!=="objective";return i&&(s.refKind="import",s.refLabel=d.body.path,s.inlinedCount=(s.inlinedCount??0)+1,s.duration_s=(s.duration_s??0)+r.duration_s),r.status==="passed"?(i?s.status!=="failed"&&(s.status="passed"):(s.status="passed",s.duration_s=r.duration_s),{continueOverall:!0}):t.optional?(s.softFailures=s.softFailures??[],s.softFailures.push({subStepIndex:t.trace[t.trace.length-1].stepIndex,reason:r.reason}),{continueOverall:!0}):(s.status="failed",s.duration_s=i?s.duration_s:r.duration_s,s.failedSubStepIndex=i?t.trace.slice(1).map(a=>a.stepIndex):void 0,s.reason=r.reason,this.skipRoot=o,d.optional??!1?(s.softFailed=!0,{continueOverall:!0}):(this.overallHalted=!0,{continueOverall:!1}))}snapshotOutcomes(){return[...this.outcomes]}snapshot(){return{outcomes:this.outcomes.map(t=>({...t,softFailures:t.softFailures?[...t.softFailures]:void 0})),skipRoot:this.skipRoot,overallHalted:this.overallHalted}}rollback(t){this.outcomes=t.outcomes.map(r=>({...r,softFailures:r.softFailures?[...r.softFailures]:void 0})),this.skipRoot=t.skipRoot,this.overallHalted=t.overallHalted}finalize(){let t=this.outcomes.some(o=>o.status==="failed"&&!o.softFailed)?"failed":"passed",r=this.outcomes.reduce((o,s)=>o+(s.duration_s??0),0);return{overallStatus:t,outcomes:this.outcomes,totalDurationS:r}}};import{writeFileSync as kr,mkdirSync as _r}from"fs";import{dirname as sr}from"path";function Je(e){let t=Se(e.sourcePath);try{_r(sr(t),{recursive:!0})}catch(o){return process.stderr.write(`
|
|
12
|
+
\u26A0 Failed to create output directory.
|
|
13
|
+
${o.message}
|
|
14
|
+
Path: ${sr(t)}
|
|
15
|
+
|
|
16
|
+
`),t}let r={commit_id:e.commitId};e.testId!==void 0&&(r.test_id=e.testId),e.testcaseId!==void 0&&(r.testcase_id=e.testcaseId),e.projectId!==void 0&&(r.project_id=e.projectId),e.folderId!==void 0&&(r.folder_id=e.folderId),e.orgId!==void 0&&(r.org_id=e.orgId),e.sessionName!==void 0&&(r.session_name=e.sessionName);try{kr(t,JSON.stringify(r,null,2)+`
|
|
17
|
+
`,"utf8")}catch(o){process.stderr.write(`
|
|
18
|
+
\u26A0 Failed to write meta.json.
|
|
19
|
+
${o.message}
|
|
20
|
+
Path: ${t}
|
|
21
|
+
|
|
22
|
+
`)}return t}var Cr=()=>{};async function or(e,t,r){let o=t.log??Cr,s=e.session.testId??null,d=null,i=null,R=null;if(!r.localMode&&t.performUpload)try{d=await t.performUpload(),d?.success&&(d.testId&&(s=d.testId),d.testcaseId&&e.session.setTestcaseId(d.testcaseId))}catch(a){o("error","FINALIZE_UPLOAD_ERROR","Upload pipeline threw",{error:String(a)})}if(t.renderFeedbackPrompt)try{i=await t.renderFeedbackPrompt(),i&&s&&t.submitFeedback&&t.submitFeedback(s,i).catch(a=>{o("error","FINALIZE_FEEDBACK_SUBMIT_ERROR","Feedback submit failed",{error:String(a)})})}catch(a){o("error","FINALIZE_FEEDBACK_RENDER_ERROR","Feedback prompt threw",{error:String(a)})}if(e.session.flushRecorder(),r.skipLocalWrites)o("info","FINALIZE_SKIP_LOCAL_WRITES","Skipping local writes (testmd flow handles via staging)");else if(r.sourcePath&&r.rootSteps&&r.outcomes){try{R=Be({sourcePath:r.sourcePath,title:r.title,rootSteps:r.rootSteps,outcomes:r.outcomes,overallStatus:r.overallStatus,startedISO:r.startedISO,durationS:r.durationS,sessionId:e.session.sessionId})}catch(a){o("error","FINALIZE_RESULT_MD_ERROR","_Result.md write failed",{error:String(a)})}try{Je({sourcePath:r.sourcePath,commitId:e.session.sessionId,testId:s??void 0,testcaseId:e.session.testcaseId??void 0,projectId:e.tuiConfig.project_id??void 0,folderId:e.tuiConfig.folder_id??void 0,orgId:e.session.orgId??void 0,sessionName:e.session.sessionName??ye(r.sourcePath)})}catch(a){o("error","FINALIZE_META_WRITE_ERROR","meta.json write failed",{error:String(a)})}if(d?.codeExportDir)try{let a=e.tuiConfig.code_export?.language??"python";He(d.codeExportDir,Ve(r.sourcePath,"playwright",a))}catch(a){o("error","FINALIZE_CODE_COPY_ERROR","code-export copy failed",{error:String(a)})}}else if(e.session.recorder?.lastWrittenPath){let a=e.session.recorder.lastWrittenPath,S=e.session.getFlows(),_=S.map((f,C)=>({index:C+1,heading:`Step ${C+1}`,headingLine:0,body:{kind:"objective",text:f.objective}})),I=S.map((f,C)=>({rootStepIndex:C+1,status:f.status==="passed"?"passed":f.status==="failed"?"failed":"skipped",duration_s:f.duration,reason:f.reason})),F=I.some(f=>f.status==="failed")?"failed":"passed";try{R=Be({sourcePath:a,title:e.session.sessionName??"Session",rootSteps:_,outcomes:I,overallStatus:F,startedISO:e.session.startedAt,durationS:I.reduce((f,C)=>f+(C.duration_s??0),0),sessionId:e.session.sessionId})}catch(f){o("error","FINALIZE_TUI_RESULT_MD_ERROR","TUI _Result.md write failed",{error:String(f)})}try{Je({sourcePath:a,commitId:e.session.sessionId,testId:s??void 0,testcaseId:e.session.testcaseId??void 0,sessionName:e.session.sessionName??void 0,projectId:e.tuiConfig.project_id??void 0,folderId:e.tuiConfig.folder_id??void 0})}catch(f){o("error","FINALIZE_TUI_META_WRITE_ERROR","TUI meta.json write failed",{error:String(f)})}if(d?.codeExportDir)try{let f=e.tuiConfig.code_export?.language??"python";He(d.codeExportDir,Ve(a,"playwright",f))}catch(f){o("error","FINALIZE_TUI_CODE_COPY_ERROR","TUI code-export copy failed",{error:String(f)})}e.session.recorder.lastCollisionSuffixed&&process.stderr.write(`Saved to ${a} (renamed: ${e.session.sessionName}_test.md already existed)
|
|
23
|
+
`)}try{t.runCleanup?.()}catch(a){o("error","FINALIZE_CLEANUP_ERROR","Cleanup hook threw",{error:String(a)})}try{await e.session.finish("complete")}catch(a){o("error","FINALIZE_SESSION_FINISH_ERROR","session.finish threw",{error:String(a)})}return{uploadResult:d,feedbackChoice:i,resultMdPath:R}}var _e=["target","chrome_profile","cdp_endpoint","ws_endpoint","headless"];async function ns(e,t){let r=Ar(e);if(!Xe(r))return process.stderr.write(`error: file not found: ${r}
|
|
24
|
+
`),2;qt(r);let o=!process.stdin.isTTY||!!t.agent,s=!1,d=o?n=>process.stdout.write(JSON.stringify(n)+`
|
|
25
|
+
`):n=>{},i;try{i=Nt(r)}catch(n){return process.stderr.write(`error: ${n.message}
|
|
26
|
+
`),2}if(i.steps.length===0)return process.stderr.write(`info: no steps in ${r}; nothing to run.
|
|
27
|
+
`),0;let R=Pr(t),a=new ut,S=new ht,_=!!(t.username&&t.accessKey);await Vt({isInteractive:!!process.stdin.isTTY&&!t.agent&&!_,creds:a,config:S});let I=a.getActiveProfile()??"default",f=t.env??void 0??a.getDefaultEnv()??"prod",C=ne(f),w="v16-alpha",p;try{p=await Mt({creds:a,env:f,usernameFlag:t.username,accessKeyFlag:t.accessKey,log:()=>{}})}catch(n){return n instanceof Ge&&n.code==="not_authenticated"?process.stderr.write(`error: Not authenticated. Choose one:
|
|
28
|
+
\u2022 Pass credentials inline: --username <user> --access-key <key>
|
|
29
|
+
\u2022 Run 'kane-cli login --oauth' (browser-based)
|
|
30
|
+
\u2022 Run 'kane-cli login --username <user> --access-key <key>'
|
|
31
|
+
`):n instanceof Ge&&n.code==="refresh_failed"?process.stderr.write(`error: Token refresh failed. Run 'kane-cli login' to re-authenticate.
|
|
32
|
+
`):process.stderr.write(`error: auth resolution failed: ${n.message}
|
|
33
|
+
`),2}let U=String(p.resolvedCreds?.org_id??"");if(!U)return process.stderr.write("error: TMS did not return an org_id. Run `kane-cli login` again.\n"),2;{let{readMetaIfExists:n,assertOrgMatchOrExit:c}=await import("./testmd-actions-AUBFHDIP.js"),u=c(n(r),U);if(u!==null)return u}let l=new pt,g=await jr(r,i,t,{resolvedAuth:p,tmsBaseUrl:C.tmsBaseUrl},l.sessionId);if(g.abort)return g.abort.exitCode;let x=g.lockAcquired,B=!1,P=!1,ue=!1;x&&d({type:"test_md_lock_state",phase:"acquired",scope:"preemptive"}),l.start({model:w,environment:f,profile:I}),l.setRecordingEnabled(!1);let pe=0,et=p.basicAuth?{username:p.basicAuth.username,accessKey:p.basicAuth.access_key}:p.token??null,fe=null;if(et!==null){let n=await vt({env:f,tmsCreds:p.resolvedCreds??null,resolver:p.resolver,auth:et,getToken:async()=>p.token??null,session:l,log:(c,u,m,h)=>l.log(c,u,m,h),skipScreenshotQueue:!!t.local||!p.basicAuth});fe=n.screenshotQueue,n.remoteLogger&&(Q("remote-logger",()=>n.remoteLogger.shutdownSync()),gt(n.remoteLogger))}if(t.name){try{wt(t.name)}catch(n){return process.stderr.write(`error: ${n.message}
|
|
34
|
+
`),2}l.setSessionName(t.name)}let Ee={};for(let[n,c]of Object.entries(i.rootGlobal))_e.includes(n)||(Ee[n]=c);for(let[n,c]of Object.entries(R))_e.includes(n)||c!==void 0&&(Ee[n]=c);let q={...i.chrome};for(let n of _e){let c=R[n];c!==void 0&&(q[n]=c)}let lr={...Ee,...q};l.setResolvedGlobal(lr);let K;try{K=await $t({config:{chrome_profile_path:q.chrome_profile??null,window_size:{width:1920,height:1080}},startUrl:re,headless:q.headless??!1,wsEndpoint:q.ws_endpoint,cdpEndpoint:q.cdp_endpoint})}catch(n){return process.stderr.write(`error: Chrome launch failed: ${n.message}
|
|
35
|
+
`),await l.finish("complete"),2}let me=K.instance;me&&Q("chrome",()=>{try{me.kill()}catch{}});let D=null,tt=K.cdpEndpoint??q.cdp_endpoint;if(tt&&!q.ws_endpoint&&!q.headless)try{D=bt({headless:q.headless??!1,cdpEndpoint:tt,chromePid:me?.process.pid}),D&&Q("marker-overlay",()=>D.kill())}catch(n){l.log("warn","OVERLAY_SPAWN_FAILED","Marker overlay spawn failed",{error:String(n)})}p.resolvedCreds?.org_id!==void 0&&l.setOrgId(String(p.resolvedCreds.org_id));let X=Ct({objective:"",globalDir:ke(Le,"variables"),localDir:ke(process.cwd(),".testmuai","variables"),file:t.variablesFile,inline:t.variables}),cr=i.rootGlobal.variables??{},M=Or(X.raw,cr);l.setAuteurVariables(M.auteur);let rt=Me(ke(Le,"global-memory.md"))??void 0,nt=Me(ke(process.cwd(),".testmuai","context.md"))??void 0,st=a.getActiveProfile()??"default",ot=a.getDefaultEnv(),{rehydrateIfStale:dr}=await import("./profile-sync-DTTRRIVP.js");dr(a,S,st,ot);let $=S.load(),V=$.project_id??null,he=$.folder_id??null;if(!t.local&&!V&&p.basicAuth)try{let n=await Bt({creds:a,config:S,profile:st,env:ot,tmsCreds:p.basicAuth,log:(c,u,m,h)=>l.log(c,u,m,h)});V=n.projectId,he=n.folderId,$=S.load(),process.stderr.write(`info: using project '${n.projectName}' / folder '${n.folderName}' (auto-configured)
|
|
36
|
+
`)}catch(n){process.stderr.write(`warn: could not auto-configure project/folder: ${n.message}
|
|
37
|
+
KaneAI upload will be skipped for this run.
|
|
38
|
+
`)}t.local?process.stderr.write(`info: --local \u2014 KaneAI upload skipped
|
|
39
|
+
`):p.basicAuth?V||process.stderr.write(`warn: KaneAI upload skipped \u2014 no project configured.
|
|
40
|
+
`):process.stderr.write(`warn: KaneAI upload skipped \u2014 TMS credentials could not be resolved.
|
|
41
|
+
Run 'kane-cli login' (OAuth) or 'kane-cli config set-username/set-access-key' (basic auth).
|
|
42
|
+
`);let ae=!t.local&&!!p.basicAuth&&V!=null;if(l.log("info","PIPELINE_GATE_STATE","Initial gate state (run-start)",{phase:"run-start",shouldUploadArtifacts:ae,lockHeld:x,isFirstRun:g.isFirstRun,hasAuth:g.hasAuth}),ae&&g.testId==null){let n=ne(f);try{let c=await Ut({tmsBaseUrl:n.tmsBaseUrl,auth:p.basicAuth,objective:i.steps[0].objective,url:"",projectId:V,folderId:he??"",hasCustomProfile:!!q.chrome_profile,log:(u,m,h,b)=>l.log(u,m,h,b)});c&&l.setTestId(c)}catch(c){process.stderr.write(`warn: ATM test creation failed: ${c.message}
|
|
43
|
+
`)}}else g.testId&&l.setTestId(g.testId);let ge={};if(p.basicAuth&&!t.local&&(M.secretEntries.length>0||M.nonSecretEntries.length>0))try{ge=await At({variables:M,auth:p.basicAuth,orgId:String(p.resolvedCreds?.org_id??""),env:f,localMode:!!t.local,log:(n,c,u,m)=>l.log(n,c,u,m)})}catch(n){process.stderr.write(`warn: variable/secret push failed: ${n.message}
|
|
44
|
+
`)}let xe=new Map;for(let[n,c]of M.nonSecretEntries)xe.set(n,c.value);let Pe=new Map;for(let[n,c]of M.secretEntries)Pe.set(n,c.value);async function Oe(n){if(!p.basicAuth||t.local)return;let c=[],u=[];for(let[h,b]of Object.entries(n))if(b.secret){if(Pe.get(h)===b.value)continue;u.push([h,b])}else{if(xe.get(h)===b.value)continue;c.push([h,b])}if(c.length===0&&u.length===0)return;let m=ne(f);if(c.length>0){let h=new kt(m.tmsBaseUrl,p.basicAuth.username,p.basicAuth.access_key);for(let[b,A]of c)try{let v=await h.upsertVariable({name:b,value:A.value});ge[b]=v.id,xe.set(b,A.value),l.log("info","VAR_PUSH_STEP","Variable updated mid-run",{name:b})}catch(v){l.log("warn","VAR_PUSH_STEP_FAILED","Mid-run variable push failed",{name:b,error:String(v)})}}if(u.length>0){let h=new It(m.secretsBaseUrl);for(let[b,A]of u)try{await h.pushSecret({secretKey:b,secretValue:A.value,username:p.basicAuth.username,accessKey:p.basicAuth.access_key,orgId:String(p.resolvedCreds?.org_id??"")}),Pe.set(b,A.value),l.log("info","SECRET_PUSH_STEP","Secret updated mid-run",{name:b})}catch(v){l.log("warn","SECRET_PUSH_STEP_FAILED","Mid-run secret push failed",{name:b,error:String(v)})}}}let le=fe?(n,c,u)=>{if(!(x||g.isFirstRun))return;let m=pe+c;St(l.sessionDir,m,n,fe,(h,b,A,v)=>l.log(h,b,A,v),u)}:void 0,it=i.rootTitle??i.rootSteps[0]?.heading??Er(r),ur=Object.keys(M.raw).length>0?Re(M.raw,it).objective:it;l.setFirstRun(ur,re);let W=new Ie(i),Fe=new Date().toISOString(),pr=Date.now(),fr=typeof t.maxSteps=="string"&&t.maxSteps!==""?parseInt(t.maxSteps,10):void 0;function at(n,c){let u=i.steps[n],m=ir(u.config,R),h=ie(X.raw,m.variables,u.objective);return Et({objective:h.objective,url:n===0?re:void 0,model:w,chrome:K,auth:p,sessionId:l.sessionId,runIndex:c,windowSize:{width:1920,height:1080},maxSteps:m.max_steps??fr??30,headless:q.headless??!1,variables:Object.keys(h.variables).length>0?h.variables:void 0,globalContext:m.global_context??rt,localContext:m.local_context??nt,sessionContext:l.getContext()})}function lt(n){let u=i.steps[n].trace[0].stepIndex,m=i.rootSteps.find(b=>b.index===u);i.steps.slice(0,n).some(b=>b.trace[0].stepIndex===u)||d({type:"test_md_step_start",step_index:u,heading:m.heading,ref:m.body.kind==="import_ref"?{kind:"import",label:m.body.path}:null})}function Te(n,c,u,m,h,b){let A=i.steps[n],v=A.trace[0].stepIndex,T=!i.steps.slice(n+1).some(k=>k.trace[0].stepIndex===v),O=u?.status==="passed"?"passed":"failed",j=u?.reason??h??void 0,L=u?.duration??b,{continueOverall:H}=W.recordStep(A,{status:O,duration_s:L,reason:j}),z=ir(A.config,R),G=ie(X.raw,z.variables,A.objective).objective;if(u){let k=ft(u,c,m);l.addRunResult(mt(u,G,c,k),u.total_runs)}else l.addRunResult({index:c,objective:G,status:O,summary:"",context:{memory:{},variables:{},pointer:""}},1);if(T||!H){let k=W.snapshotOutcomes().find(y=>y.rootStepIndex===v);d({type:"test_md_step_end",step_index:v,status:k.status,duration_s:k.duration_s??0,ref_kind:k.refKind??null,inlined_count:k.inlinedCount??null,failed_sub_step_index:k.failedSubStepIndex??null})}return H}async function mr(n){Zt(n,i.steps.length);for(let c=0;c<n;c++){if(s)return{failedAt:c,cancelled:!0};let u=i.steps[c],m=g.decisions[c];if(m.kind!=="replay")return process.stderr.write(`error: runReplayPhase invoked on a non-replay decision at step ${c}
|
|
45
|
+
`),{failedAt:c,cancelled:!1};let h=l.nextRunIndex();pe=h;let b=c===0?re:void 0,A={width:$.window_size.width,height:$.window_size.height},v=ie(X.raw,u.config.variables,u.objective),T=We({step:u,decision:m,chrome:K,auth:p,sessionId:l.sessionId,runIndex:h,sessionDir:l.sessionDir,windowSize:A,forceNavigateUrl:b,sessionContext:l.getContext(),variables:Object.keys(v.variables).length>0?v.variables:void 0});await Oe(v.raw),lt(c);let O=Date.now(),j=null,L=null;try{let k=Ne(T,{environment:f});Q("runner",()=>{Ue()&&(s=!0);try{k.cancel()}catch{}}),D?.setRunActive(!0);try{for await(let y of k.events){if(o&&process.stdout.write(JSON.stringify(y)+`
|
|
46
|
+
`),y.type==="step_event"&&y.event==="reasoning"?D?.setStepText(y.detail):y.type==="step_end"&&(y.status==="passed"&&D?.setStepComplete(),le&&le(y.index,0,y.child_id)),y.type==="run_end"){j=y;break}if(y.type==="error"){L=y.message??"runner error";break}}try{k.cancel()}catch{}if(!j&&!L){let{code:y}=await k.exited;y!==0&&(L=`runner exited with code ${y}`)}}finally{D?.setRunActive(!1),J("runner","Replay step complete")}}catch(k){L=k.message}if(s)return{failedAt:c,cancelled:!0};let H=Math.round((Date.now()-O)/1e3),z=Te(c,h,j,null,L,H);l.recordStepRun({testmdStepIndex:i.steps[c].flatIndex,runIndex:h,totalRunDirs:1});let G=!!L||j?.status==="failed";if(Qt(c,G?"failed":"ok"),G||!z)return{failedAt:c,cancelled:!1}}return{failedAt:null,cancelled:!1}}let ct=async()=>{if(x)return!0;let n=p.basicAuth;if(!n){let h=await p.resolver.resolve(!0);h?.username&&h?.access_key&&(n={username:h.username,access_key:h.access_key},p.basicAuth=n)}if(!g.testId||!g.fromCommitId||!n)return process.stderr.write(`error: cannot acquire lock \u2014 missing required state
|
|
47
|
+
`),!1;let c=l.sessionId,u=t.onLockConflict??i.rootGlobal.on_lock_conflict??"readonly",m=await ar({tmsBaseUrl:C.tmsBaseUrl,testId:g.testId,fromCommitId:g.fromCommitId,newCommitId:c,basicAuth:n,onLockConflict:u});return m==="ok"?(x=!0,g.newCommitId=c,l.log("info","MID_RUN_LOCK_ACQUIRED","Mid-run lock acquired",{test_id:g.testId}),o&&d({type:"test_md_lock_state",phase:"acquired",scope:"mid_run"}),Ze({baseUrl:Ce(C.tmsBaseUrl),testId:g.testId,auth:Ae(n)}),!0):(l.log("error","MID_RUN_LOCK_CONFLICT","Mid-run lock acquisition failed",{reason:m}),o&&d({type:"test_md_lock_state",phase:"conflict",scope:"mid_run",reason:m}),process.stderr.write(`error: mid-run lock acquisition failed (${m})
|
|
48
|
+
`),!1)};if(o){let{authorBoundary:n,cancelledInPhase:c,shrinkCount:u}=await rr({decisions:g.decisions,hasRetry:t.retry===!0||t.retryCount!==void 0,maxShrinks:t.retryCount!==void 0?parseInt(t.retryCount,10):de.maxShrinks,runReplayPhase:mr,session:l,accumulator:W,acquireLockIfNeeded:ct});if(ue=u>0,u>0&&(l.log("info","RETRY_TRIGGERED","Retry loop triggered",{shrink_count:u,final_author_boundary:n}),d({type:"test_md_retry_attempt",shrink_count:u,final_author_boundary:n,complete_reauthor:n===0})),n===0&&u>0&&l.log("info","COMPLETE_REAUTHOR_TRIGGERED","Complete reauthor fallback",{shrink_count:u}),!c&&n>=0)for(let m=n;m<i.steps.length;m++){let h=i.steps[m];if(!W.shouldRunFlatStep(h))continue;lt(m),B=!0;let b=l.nextRunIndex();pe=b,await Oe(ie(X.raw,h.config.variables,h.objective).raw);let A=at(m,b),v=Date.now(),T=null,O=null,j=null,L=!1,H=0;try{let k=Ne(A,{environment:f});Q("runner",()=>{Ue()&&(s=!0);try{k.cancel()}catch{}}),D?.setRunActive(!0);try{for await(let y of k.events){if(process.stdout.write(JSON.stringify(y)+`
|
|
49
|
+
`),y.type==="bifurcation"){let ce=y.count??y.flows?.length??0;(y.is_single_flow??ce<=1)||(j=y.flows??null,L=!0,H=0)}else if(y.type==="run_start"&&L)H++;else if(y.type==="step_event"&&y.event==="reasoning")D?.setStepText(y.detail);else if(y.type==="step_end"&&(y.status==="passed"&&D?.setStepComplete(),le)){let ce=L?Math.max(0,H-1):0;le(y.index,ce,y.child_id)}if(y.type==="run_end"){T=y;break}if(y.type==="error"){O=y.message??"runner error";break}}try{k.cancel()}catch{}}finally{D?.setRunActive(!1),J("runner","Step complete")}}catch(k){O=k.message}let z=Math.round((Date.now()-v)/1e3),G=Te(m,b,T,j,O,z);if(l.recordStepRun({testmdStepIndex:i.steps[m].flatIndex,runIndex:b,totalRunDirs:T?.total_runs??1}),!G||s)break}}else{let{default:n}=await import("./react-QWOAB3TB.js"),{render:c}=await import("./build-JIKYOZUH.js"),{TestMdRunView:u}=await import("./TestMdRunView-5NGUC56R.js"),{effectiveDecisions:m}=await import("./effective-decisions-DRM3JSR4.js"),{decideRetry:h}=await import("./replay-policy-6USQBT3E.js"),b=t.retry===!0||t.retryCount!==void 0,A=t.retryCount!==void 0?parseInt(t.retryCount,10):de.maxShrinks,v=t.author===!0;v&&(er(),l.log("info","FORCE_AUTHOR_RUN","--author flag set; walker bypassed"));let T=v?0:ve(g.decisions),O=0,j=null,L=g.decisions.filter(k=>k.kind==="replay").length,H=g.decisions.length-L,z=[];t.push&&z.push("--push"),b&&z.push("--retry"),t.retryCount!==void 0&&z.push(`--retry-count=${t.retryCount}`),v&&z.push("--author");let G={source:r,steps:{total:g.decisions.length,replay:L,author:H},model:w,viewport:{width:$.window_size.width,height:$.window_size.height},chrome:K.cdpEndpoint??K.wsEndpoint??"managed",session:l.sessionName??"ephemeral",variables:{count:Object.keys(M.raw).length,secrets:Object.values(M.raw).filter(k=>k.secret).length,names:Object.keys(M.raw)},flags:z,mode:R.mode??"testing"};for(;;){let k=l.snapshot(),y=W.snapshot(),ce=m(g.decisions,T,v);if(O>=1){let E=T===0?`\u21BB Complete re-author \u2014 retry budget exhausted (${O}/${A})`:`\u21BB Retry ${O}/${A} \u2014 replay 0..${T-1}, author ${T}..${g.decisions.length-1}
|
|
50
|
+
reason: replay miss at step ${(j??0)+1}`;process.stderr.write(E+`
|
|
51
|
+
`)}let br=O>=1&&T>0&&j!==null?{startIdx:0,endIdx:j,count:j}:void 0;D?.setRunActive(!0);let be=await Ur({decisions:ce,resolved:i,session:l,accumulator:W,tuiConfig:$,globalConfig:G,buildStepConfigAt:at,buildReplayConfig:E=>{let Y=g.decisions[E];if(Y.kind!=="replay")throw new Error("expected replay decision at index "+E);let Z=i.steps[E];return We({step:Z,decision:Y,chrome:K,auth:p,sessionId:l.sessionId,runIndex:l.nextRunIndex(),sessionDir:l.sessionDir,windowSize:{width:$.window_size.width,height:$.window_size.height},forceNavigateUrl:E===0?re:void 0,sessionContext:l.getContext(),variables:Fr(X.raw,Z.config.variables,Z.objective)})},onAnyAuthorStep:()=>{B=!0},onCancel:()=>{P=!0},topBannerModel:w,topBannerAuth:`${a.getActiveProfile()??"no profile"}/${f}`,spawnOpts:{environment:f,mode:R.mode??"testing",log:(E,Y,Z,De)=>l.log(E,Y,Z,De)},priorAttemptRollup:br,pushStepLevelDelta:(E,Y)=>Oe(ie(X.raw,E,Y).raw),onSequencerStepEnd:(E,Y,Z,De)=>{let Rr=Math.round((Date.now()-De)/1e3),yr=E.hadError?E.reason??"runner error":null,Sr=Te(Y,Z,E.runEnd,E.bifurcationFlows??null,yr,Rr);return l.recordStepRun({testmdStepIndex:i.steps[Y].flatIndex,runIndex:Z,totalRunDirs:E.runEnd?.total_runs??E.bifurcationFlows?.length??1}),Sr},screenshotDispatcher:le,onReasoning:E=>D?.setStepText(E),onStepComplete:()=>D?.setStepComplete(),onSpawnStart:E=>{pe=E}});if(D?.setRunActive(!1),be.cancelled){J("marker-overlay","user cancelled run"),J("chrome","user cancelled run");break}if(be.failedAt===null)break;let je=h({failedAt:be.failedAt,shrinkCount:O,hasRetry:b,maxShrinks:A});if(je.kind==="fail"||!x&&!await ct())break;l.rollback(k),W.rollback(y),je.kind==="complete-reauthor"?T=0:T=je.newAuthorBoundary,O++,ue=!0,l.log("info","RETRY_TRIGGERED","Retry loop triggered (TTY)",{shrink_count:O,failed_at:j}),T===0&&l.log("info","COMPLETE_REAUTHOR_TRIGGERED","Complete reauthor fallback (TTY)",{shrink_count:O}),j=be.failedAt}}let N=W.finalize(),ee=Math.round((Date.now()-pr)/1e3),hr={session:l,resolvedAuth:p,chromeResult:K,chromeInstance:me??null,testId:l.testId??null,preparedVariables:M,variableIds:ge,globalContext:rt,localContext:nt,tuiConfig:$,env:f,localMode:!!t.local},te=await or(hr,{performUpload:async()=>{if(!p.basicAuth)return null;let n=ne(f),c=(B||t.push===!0)&&!P,u=(x||g.isFirstRun)&&!P&&N.overallStatus==="passed",m=ae&&(x||g.isFirstRun);l.log("info","PIPELINE_GATE_STATE","Derived gate state (finalize)",{phase:"finalize",shouldUploadArtifacts:ae,shouldUploadPipeline:m,shouldReplaceLocalOutput:c,shouldCommit:u,lockHeld:x,anyAuthorStepRan:B,cancelled:P,overallStatus:N.overallStatus});let h=Dt({session:l,env:f,auth:p,variables:M,variableIds:ge,projectId:V,folderId:he,totalSteps:N.outcomes.length,totalDuration:ee,screenshotExtMap:fe?.getExtMap(),codeExport:Lt({codeExport:t.codeExport,codeLanguage:t.codeLanguage,skipCodeValidation:t.skipCodeValidation},$.code_export),onProgress:()=>{},log:(v,T,O,j)=>l.log(v,T,O,j),shouldUploadArtifacts:m,shouldReplaceLocalOutput:c,shouldCommit:u,isFirstRun:g.isFirstRun,resolvedTest:i,sourcePath:r,stepRunRecords:l.getStepRunRecords(),outcomes:N.outcomes,overallStatus:N.overallStatus,fromCommitId:g.fromCommitId,startedISO:Fe,durationS:ee,tmsIds:{testId:g.testId??l.testId??void 0,testcaseId:g.testcaseId??l.testcaseId??void 0,projectId:V??void 0,folderId:he??void 0,orgId:l.orgId??void 0,sessionName:l.sessionName??ye(r)},tmsBaseUrl:C.tmsBaseUrl,testId:g.testId??void 0,newCommitId:g.newCommitId??void 0,basicAuth:p.basicAuth??void 0,decisions:g.decisions,wantsPush:t.push===!0,retryTriggered:ue,forceAuthor:t.author===!0});g.newCommitId!=null&&(h.skipTmsFinalize=!0);let b=new Rt(h);if(o)return await b.execute();let{renderUploadProgress:A}=await import("./CliUploadProgress-Z3FSUSUL.js");return await A(b,v=>{if(v.testcaseId&&v.shareId&&V)return $e(n.testManagerUiUrl,V,v.testcaseId,v.shareId)})},runCleanup:()=>{J("chrome","test.md run complete")},log:(n,c,u,m)=>l.log(n,c,u,m)},{overallStatus:N.overallStatus,outcomes:N.outcomes,sourcePath:r,title:i.rootTitle,rootSteps:i.rootSteps,startedISO:Fe,durationS:ee,localMode:!!t.local,skipLocalWrites:!0});await Dr(r,g,l,N.outcomes,N.overallStatus,Fe,ee,te.uploadResult,$,t,{resolvedAuth:p,tmsBaseUrl:C.tmsBaseUrl},x);let dt={overallStatus:N.overallStatus,durationS:ee,decisions:g.decisions,outcomes:N.outcomes,cancelled:P,retryTriggered:ue,lockHeld:x,anyAuthorStepRan:B,isFirstRun:g.isFirstRun,wantsPush:t.push===!0,uploadResult:te.uploadResult,shouldUploadArtifacts:ae,shouldReplaceLocalOutput:B&&!P,shouldCommit:(x||g.isFirstRun)&&!P&&N.overallStatus==="passed"},{buildSummaryEvent:gr}=await import("./SummaryBox-63JMAMEH.js");if(o)d(gr(dt));else try{let{default:n}=await import("./react-QWOAB3TB.js"),{render:c}=await import("./build-JIKYOZUH.js"),{AutoExitSummaryBox:u}=await import("./SummaryBox-63JMAMEH.js"),{waitUntilExit:m}=c(n.createElement(u,{data:dt}),{stdout:process.stderr});await m()}catch(n){l.log("warn","TEST_MD_SUMMARY_RENDER_FAILED","Summary box render failed",{error:String(n)})}if(!o)try{let{default:n}=await import("./react-QWOAB3TB.js"),{render:c}=await import("./build-JIKYOZUH.js"),{LinksBox:u}=await import("./LinksBox-LGB3H7NO.js"),m=ne(f),h=te.uploadResult?.testcaseId,b=h&&te.uploadResult?.shareId&&V?$e(m.testManagerUiUrl,V,h,te.uploadResult.shareId):void 0,A=h&&V?yt(m.testManagerUiUrl,V,h):void 0,{waitUntilExit:v}=c(n.createElement(u,{recordedTestPath:r,outputDir:xt(r),shareableLink:b,testCaseLink:A,codeExportDir:te.uploadResult?.codeExportDir}),{stdout:process.stderr});await v()}catch(n){l.log("warn","TEST_MD_LINKS_RENDER_FAILED","LinksBox render failed",{error:String(n)})}return d({type:"test_md_done",overall_status:N.overallStatus,duration_s:ee,session_id:l.sessionId}),N.overallStatus==="passed"?0:1}function Pr(e){let t={mode:"mode",maxSteps:"max_steps",timeout:"timeout",globalContext:"global_context",localContext:"local_context",codeExport:"code_export",codeLanguage:"code_language",headless:"headless",cdpEndpoint:"cdp_endpoint",wsEndpoint:"ws_endpoint"},r=new Set(["max_steps","timeout"]),o={};for(let[s,d]of Object.entries(t)){let i=e[s];if(i===void 0||i==="")continue;let R=i;if(r.has(d)&&(R=Number(i),Number.isNaN(R))){let a="--"+s.replace(/[A-Z]/g,S=>"-"+S.toLowerCase());process.stderr.write(`error: ${a} must be a number
|
|
52
|
+
`),process.exit(2)}o[d]=R}return o}function Or(e,t){let r={...e,...t},o=Object.keys(r).length>0?Re(r,""):{variables:{},objective:"",keyMap:{}};return{raw:r,auteur:o.variables,auteurObjective:"",secretEntries:Object.entries(r).filter(([,s])=>s.secret),nonSecretEntries:Object.entries(r).filter(([,s])=>!s.secret)}}function ie(e,t,r){let o={...e,...t??{}};if(Object.keys(o).length===0)return{raw:o,variables:{},objective:r};let s=Re(o,r);return{raw:o,variables:_t(s.variables,s.objective),objective:s.objective}}function Fr(e,t,r){let o=ie(e,t,r).variables;return Object.keys(o).length>0?o:void 0}function ir(e,t){let r=new Set(_e),o={...e};for(let[s,d]of Object.entries(t))r.has(s)||s!=="variables"&&d!==void 0&&e[s]===void 0&&(o[s]=d);return o}function Tr(e,t){return e.length<=t?e:e.slice(0,t-1)+"\u2026"}async function jr(e,t,r,o,s){let d=Pt(e),i=Kt(t,Xe(d)?d:null);Wt(t,i);let R=Se(e),a=Xe(R)?JSON.parse(xr(R,"utf8")):null,S=a?.testcase_id,_=a?.test_id,I=a?.commit_id,F=r.push===!0,f=r.retry===!0||r.retryCount!==void 0,C=r.author===!0;F&&!S&&process.stderr.write(`[--push] no meta.json yet \u2014 flag is a no-op on first run
|
|
53
|
+
`),C&&(S=void 0,_=void 0,I=void 0);let w=o.resolvedAuth.basicAuth;if(!w){let P=await o.resolvedAuth.resolver.resolve(!0);P?.username&&P?.access_key&&(w={username:P.username,access_key:P.access_key},o.resolvedAuth.basicAuth=w)}let p=!!w,U=!r.local&&p&&_!=null&&I!=null&&S!=null,l=U&&(Gt(i)||F);if(F&&!U)return process.stderr.write(`error: --push requires authenticated credentials for the lock API. Run 'kane-cli login' (OAuth) or pass --username/--access-key inline.
|
|
54
|
+
`),{resolved:t,decisions:i,testId:_,testcaseId:S,fromCommitId:I,newCommitId:null,isFirstRun:!1,hasAuth:p,canLock:U,lockAcquired:!1,abort:{exitCode:2}};if(f&&!U)return process.stderr.write(`error: --retry requires authenticated credentials for the lock API. Run 'kane-cli login' (OAuth) or pass --username/--access-key inline.
|
|
55
|
+
`),{resolved:t,decisions:i,testId:_,testcaseId:S,fromCommitId:I,newCommitId:null,isFirstRun:!1,hasAuth:p,canLock:U,lockAcquired:!1,abort:{exitCode:2}};if(C&&!p)return process.stderr.write(`error: --author requires authenticated credentials for the TMS API. Run 'kane-cli login' (OAuth) or pass --username/--access-key inline.
|
|
56
|
+
`),{resolved:t,decisions:i,testId:_,testcaseId:S,fromCommitId:I,newCommitId:null,isFirstRun:!1,hasAuth:p,canLock:U,lockAcquired:!1,abort:{exitCode:2}};let g=null,x=!1;if(l){g=s;let B=r.onLockConflict??t.rootGlobal.on_lock_conflict??"readonly",P=await ar({tmsBaseUrl:o.tmsBaseUrl,testId:_,fromCommitId:I,newCommitId:g,basicAuth:w,onLockConflict:B});if(P==="ok")x=!0,Ze({baseUrl:Ce(o.tmsBaseUrl),testId:_,auth:Ae(w)});else{if(P==="abort")return{resolved:t,decisions:i,testId:_,testcaseId:S,fromCommitId:I,newCommitId:null,isFirstRun:!1,hasAuth:p,canLock:U,lockAcquired:!1,abort:{exitCode:2}};g=null}}return{resolved:t,decisions:i,testId:_,testcaseId:S,fromCommitId:I,newCommitId:g,isFirstRun:S==null,hasAuth:p,canLock:U,lockAcquired:x}}function Ce(e){return`${e}/kane-cli/v1`}function Ae(e){return{username:e.username,accessKey:e.access_key}}async function ar(e){let t=Ce(e.tmsBaseUrl),r=Ae(e.basicAuth),o={baseUrl:t,testId:e.testId,fromCommitId:e.fromCommitId,newCommitId:e.newCommitId,auth:r},s=await Ke(o);if(s.ok)return"ok";if(!(s.reason==="concurrent"||s.reason==="base_mismatch"))return process.stderr.write(`[lock] acquire failed: ${s.reason} (HTTP ${s.httpStatus}): ${s.message}
|
|
57
|
+
`),"abort";let i=s.reason==="concurrent"?"concurrent session":"base commit mismatch (pull latest)";if(e.onLockConflict==="fail")return process.stderr.write(`[lock] ${i}; aborting (--on-lock-conflict fail)
|
|
58
|
+
`),"abort";if(e.onLockConflict==="wait"){if(s.reason==="base_mismatch")return process.stderr.write(`[lock] base commit mismatch \u2014 pull latest; aborting
|
|
59
|
+
`),"abort";for(;;){process.stderr.write(`[lock] waiting (concurrent session)...
|
|
60
|
+
`),await new Promise(a=>setTimeout(a,3e4));let R=await Ke(o);if(R.ok)return"ok";if(R.reason!=="concurrent")return process.stderr.write(`[lock] wait drifted to ${R.reason} (HTTP ${R.httpStatus}): ${R.message}; aborting
|
|
61
|
+
`),"abort"}}return process.stderr.write(`[lock] ${i} \u2014 running in readonly mode (no commit)
|
|
62
|
+
`),"readonly"}async function Dr(e,t,r,o,s,d,i,R,a,S,_,I){let{decisions:F,testId:f,testcaseId:C,fromCommitId:w,newCommitId:p}=t;if(!(s==="passed")&&I&&f&&w&&p){process.stderr.write(`[lock] run failed (${s}); discarding new commit
|
|
63
|
+
`),await Lr(_,f,w,p),Qe();return}Qe()}async function Lr(e,t,r,o){let s=e.resolvedAuth.basicAuth;if(!s){let i=await e.resolvedAuth.resolver.resolve(!0);i?.username&&i?.access_key&&(s={username:i.username,access_key:i.access_key},e.resolvedAuth.basicAuth=s)}if(!s)return;let d=await jt({baseUrl:Ce(e.tmsBaseUrl),testId:t,body:{commitId:o,fromCommitId:r},auth:Ae(s)});d.ok||process.stderr.write(`warn: discardLock failed: ${d.reason} (HTTP ${d.httpStatus}): ${d.message}
|
|
64
|
+
`)}async function Ur(e){let{default:t}=await import("./react-QWOAB3TB.js"),{render:r}=await import("./build-JIKYOZUH.js"),{TestMdRunView:o}=await import("./TestMdRunView-5NGUC56R.js"),s=null,d=!1,i=0,R=-1,a=-1,S=0,_=async F=>{if(F&&F.status==="failed")return i>0&&e.decisions[i-1].kind==="replay"&&(s=i-1),null;for(;i<e.decisions.length&&!e.accumulator.shouldRunFlatStep(e.resolved.steps[i]);)i++;if(i>=e.decisions.length)return null;let f=e.decisions[i],C=e.resolved.steps[i],w=i;i++;let p=e.session.nextRunIndex();R=w,a=p,S=Date.now(),e.onSpawnStart?.(p),f.kind==="author"&&e.onAnyAuthorStep(),await e.pushStepLevelDelta(C.config.variables,C.objective);let U=f.kind==="replay"?e.buildReplayConfig(w):e.buildStepConfigAt(w,p),l=f.kind==="replay"?"md5-match":f.reason,g=C.config??{},x={};for(let[B,P]of Object.entries(g))P!=null&&B!=="variables"&&(x[B]=P);return{config:U,banner:{stepLabel:`Step ${w+1}/${e.decisions.length}`,objective:Tr(C.objective,100)},mode:f.kind,modeReason:l,perStepOverrides:Object.keys(x).length>0?x:void 0}},{waitUntilExit:I}=r(t.createElement(o,{topBanner:{model:e.topBannerModel,auth:e.topBannerAuth},globalConfig:e.globalConfig,getNextStep:_,onStepEnd:F=>(F.status==="failed"&&R>=0&&e.decisions[R]?.kind==="replay"&&(s=R),e.onSequencerStepEnd(F,R,a,S)),onAllComplete:()=>{},onCancel:()=>{d=!0,e.onCancel()},spawnOpts:e.spawnOpts,priorAttemptRollup:e.priorAttemptRollup,screenshotDispatcher:e.screenshotDispatcher,onReasoning:e.onReasoning,onStepComplete:e.onStepComplete}),{stdout:process.stderr,exitOnCtrlC:!1});return await I(),{failedAt:s,cancelled:d}}export{ir as applyCliStepConfig,ie as buildStepRunVariables,Or as buildTestLevelVariables,Fr as replayVariablesForStep,ns as runTestMdFile};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as $}from"./chunk-
|
|
2
|
+
import{a as $}from"./chunk-FITKUFJG.js";import{b as J,c as U,d as tt}from"./chunk-I3AGHICC.js";import{a as C,b as W,e as S,f as Z}from"./chunk-AH4AXJML.js";import{a as N}from"./chunk-XR6QKTHK.js";import"./chunk-G7VF5SDK.js";import{a as z}from"./chunk-IXNVLVFT.js";import{a as B}from"./chunk-6ISGQNS2.js";import{a as G}from"./chunk-TC74YD2D.js";import"./chunk-BPF7TDRU.js";import{a as K,b as Q}from"./chunk-MDBXYXSC.js";import"./chunk-WAOCHXJ5.js";import"./chunk-2IAYS2ZB.js";import{a as F}from"./chunk-HCBYKLMW.js";import{t as _}from"./chunk-DTQJGYDA.js";import{a as y,b as g,i as H}from"./chunk-C44QQJR4.js";import{a as A}from"./chunk-6YGTRKDT.js";import"./chunk-NLCCBXXV.js";import{a as O}from"./chunk-RZ4F3BHX.js";import{e as T}from"./chunk-UR6MHSHU.js";var P=T(A(),1);import{existsSync as v,readFileSync as Lt,rmSync as lt,unlinkSync as jt}from"fs";import{resolve as Y}from"path";import{promises as et,realpathSync as gt}from"fs";import{homedir as pt}from"os";import{join as V,parse as ht,relative as rt,resolve as nt}from"path";var _t=new Set(["node_modules",".git","dist","build",".next",".venv","venv","target","__pycache__"]),R=class extends Error{constructor(i){super(`refusing to scan '${i}'. Run from your project root, or pass --root <dir>.`);this.cwd=i;this.name="HomeRefusedError"}};function ot(t){try{return gt(nt(t))}catch{return nt(t)}}function xt(t){let r=ot(t),i=ot(pt()),n=ht(r).root;if(process.platform==="win32"){let e=o=>o.toLowerCase();return e(r)===e(i)||e(r)===e(n)}return r===i||r===n}async function I(t){if(xt(t.root))throw new R(t.root);let r=t.maxEntries??5e4,i=t.maxResults??5e3,n=new Set(t.ignore??[]),e=[],o=0,c=0,a=!1,l,s=[t.root];for(;s.length>0&&!a;){let u=s.shift(),w;try{w=await et.readdir(u,{withFileTypes:!0})}catch{continue}c++;for(let h of w){if(o++,o>r){a=!0,l="max_entries";break}let f=h.name,b=V(u,f);if(h.isDirectory()){if(_t.has(f)||f.startsWith(".")||f.startsWith("output-")||n.has(f))continue;s.push(b)}else if(h.isFile()&&f.endsWith("_test.md")&&(e.push({path:b,relPath:rt(t.root,b),source:"cwd"}),e.length>=i)){a=!0,l="max_results";break}}t.onProgress?.(c,e.length)}if(!a){let u=V(t.root,".testmuai","tests");try{let w=await et.readdir(u,{withFileTypes:!0});c++;for(let h of w){if(!h.isFile()||!h.name.endsWith("_test.md"))continue;let f=V(u,h.name);if(e.push({path:f,relPath:rt(t.root,f),source:"tests-dir"}),e.length>=i){a=!0,l="max_results";break}}}catch{}}return{results:e,aborted:a,abortReason:l,dirsScanned:c}}import{mkdirSync as wt,writeFileSync as yt}from"fs";import{join as kt}from"path";function it(t,r){return`Basic ${Buffer.from(`${t}:${r}`).toString("base64")}`}async function bt(t){let r=K({tmsBaseUrl:t.tmsBaseUrl,testcaseId:t.testcaseId,codeExport:{enabled:!0,language:t.language,skipValidation:t.skipValidation}}),i=await O(r.url,{method:"POST",headers:{"content-type":"application/json",authorization:it(t.auth.username,t.auth.access_key)},body:JSON.stringify(r.body)});if(!i.ok)throw new Error(`code-export trigger failed: ${i.status} ${await i.text()}`);t.log("info","CODE_EXPORT_TRIGGERED","Code export triggered",{testcase_id:t.testcaseId})}async function Et(t){let r=Q({tmsBaseUrl:t.tmsBaseUrl,testcaseId:t.testcaseId}),i=t.pollIntervalMs??5e3,n=t.timeoutMs??3e5,e=Date.now()+n;for(;Date.now()<e;){let o=await O(r,{headers:{authorization:it(t.auth.username,t.auth.access_key),accept:"application/json"}});if(!o.ok){await new Promise(s=>setTimeout(s,i));continue}let a=(await o.json()).data?.find(s=>s.code_name==="kane-cli-trigger");if(!a){await new Promise(s=>setTimeout(s,i));continue}let l=(a.status??"").toLowerCase();if(l==="in progress"||l==="in_progress"||l==="pending"){await new Promise(s=>setTimeout(s,i));continue}if(!a.url||a.url.length===0)throw new Error(`code-export status=${a.status} but no files returned`);wt(t.outDir,{recursive:!0});for(let s of a.url){let u=kt(t.outDir,s.file_name),w=await O(s.file_url);if(!w.ok){t.log("warn","CODE_EXPORT_FILE_FAILED","Failed to download file",{file_name:s.file_name,status:w.status});continue}let h=await w.text();yt(u,h,"utf-8")}return t.log("info","CODE_EXPORT_DOWNLOADED","Code export saved",{out_dir:t.outDir,file_count:a.url.length}),t.outDir}throw new Error("code-export polling timed out")}async function st(t){return await bt(t),await Et(t)}var k=T(A(),1);import{existsSync as Tt,readFileSync as Rt}from"fs";var p=T(F(),1);function St(t){$(t);let r=S(t);if(!Tt(r))return null;try{return JSON.parse(Rt(r,"utf8"))}catch{return{}}}function Pt(t){return t===null?"never_run":t.testcase_id?"synced":"local_only"}function vt(t){return t==="synced"?"\u2601":t==="local_only"?"\u25A3":"\u25CB"}function Mt(t){return t==="tests-dir"?"\u2726":" "}function Ct(t,r){return r==="all"?!0:r==="synced"?t.status==="synced":r==="local"?t.status==="local_only":r==="never_run"?t.status==="never_run":r==="cli"?t.source==="tests-dir":r==="hand"?t.source==="cwd":!0}var X=["all","synced","local","never_run","cli","hand"];function Dt(t){let r=X.indexOf(t);return X[(r+1)%X.length]}function at({root:t,currentOrgId:r,onSelect:i,onCancel:n}){let[e,o]=(0,k.useState)([]),[c,a]=(0,k.useState)(null),[l,s]=(0,k.useState)(!0),[u,w]=(0,k.useState)("all");(0,k.useEffect)(()=>{(async()=>{try{let m=await I({root:t}),M=[];for(let E of m.results){let j=St(E.path);j?.org_id!==void 0&&j.org_id!==r||M.push({path:E.path,relPath:E.relPath,name:C(E.path),status:Pt(j),source:E.source})}o(M),s(!1)}catch(m){m instanceof R,a(m.message),s(!1)}})()},[t,r]);let h=(0,k.useMemo)(()=>e.filter(m=>Ct(m,u)).map(m=>({id:m.path,label:`${vt(m.status)} ${Mt(m.source)} ${m.relPath}`})),[e,u]),f=(0,k.useMemo)(()=>Ot(u,e),[u,e]);if(c)return(0,p.jsxs)(y,{flexDirection:"column",borderStyle:"round",borderColor:_.statusFail,paddingX:2,paddingY:1,children:[(0,p.jsx)(g,{color:_.statusFail,bold:!0,children:"testmd"}),(0,p.jsx)(y,{marginTop:1,children:(0,p.jsx)(g,{color:_.statusFail,children:c})})]});let b=u==="all"?"all":Ft(u);return(0,p.jsx)(z,{title:`testmd \xB7 filter: ${b}`,items:h,loading:l,itemNoun:"tests",onSelect:m=>{let M=e.find(E=>E.path===m.id);M&&i(M)},onCancel:n,onTab:()=>w(m=>Dt(m)),extraHint:"cycle filter",footer:f})}function Ft(t){return t==="synced"?"synced (\u2601)":t==="local"?"local (\u25A3)":t==="never_run"?"never run (\u25CB)":t==="cli"?"cli-generated (\u2726)":t==="hand"?"hand-written":"all"}function Ot(t,r){let i={synced:r.filter(e=>e.status==="synced").length,local:r.filter(e=>e.status==="local_only").length,never:r.filter(e=>e.status==="never_run").length,cli:r.filter(e=>e.source==="tests-dir").length,hand:r.filter(e=>e.source==="cwd").length},n=e=>e?_.primary:_.dim;return(0,p.jsxs)(y,{flexDirection:"column",children:[(0,p.jsx)(g,{color:_.dim,children:"legend:"}),(0,p.jsxs)(y,{children:[(0,p.jsx)(g,{color:n(t==="synced"),children:` \u2601 synced (${i.synced}) `}),(0,p.jsx)(g,{color:n(t==="local"),children:`\u25A3 local (${i.local}) `}),(0,p.jsx)(g,{color:n(t==="never_run"),children:`\u25CB never run (${i.never})`})]}),(0,p.jsxs)(y,{children:[(0,p.jsx)(g,{color:n(t==="cli"),children:` \u2726 cli-generated (${i.cli}) `}),(0,p.jsx)(g,{color:n(t==="hand"),children:` hand-written (${i.hand})`})]})]})}var D=T(A(),1);import{existsSync as $t,readFileSync as It}from"fs";var d=T(F(),1);function ct({path:t,relPath:r,onAction:i,onBack:n}){let[e,o]=(0,D.useState)(null),[c,a]=(0,D.useState)(!1);(0,D.useEffect)(()=>{let s=S(t);if($t(s))try{o(JSON.parse(It(s,"utf8")))}catch{o(null)}},[t]),H((s,u)=>{if(u.escape){if(c){a(!1);return}n();return}if(c){s==="y"||s==="Y"?(a(!1),i("delete")):(s==="n"||s==="N")&&a(!1);return}s==="r"&&i("run"),s==="e"&&e?.testcase_id&&i("export"),s==="d"&&a(!0)});let l=({k:s,v:u})=>u?(0,d.jsxs)(g,{children:[(0,d.jsx)(g,{color:_.dim,children:s.padEnd(14)}),u]}):null;return(0,d.jsxs)(y,{flexDirection:"column",borderStyle:"round",borderColor:_.primary,paddingX:2,paddingY:1,children:[(0,d.jsx)(g,{color:_.primary,bold:!0,children:r}),(0,d.jsx)(y,{marginTop:1,flexDirection:"column",children:e?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(l,{k:"test_id",v:e.test_id}),(0,d.jsx)(l,{k:"testcase_id",v:e.testcase_id}),(0,d.jsx)(l,{k:"project_id",v:e.project_id}),(0,d.jsx)(l,{k:"folder_id",v:e.folder_id}),(0,d.jsx)(l,{k:"org_id",v:e.org_id}),(0,d.jsx)(l,{k:"session_name",v:e.session_name}),(0,d.jsx)(l,{k:"commit_id",v:e.commit_id})]}):(0,d.jsx)(g,{color:_.dim,children:"(never run \u2014 no meta.json)"})}),c?(0,d.jsx)(y,{marginTop:1,children:(0,d.jsxs)(g,{color:_.statusFail,bold:!0,children:["Delete ",r," and its output dir? [y/n]"]})}):(0,d.jsx)(y,{marginTop:1,children:(0,d.jsxs)(g,{color:_.dim,children:["[r] run [e] export",e?.testcase_id?"":" (need testcase_id)"," [d] delete [Esc] back"]})})]})}function L(t){$(t);let r=S(t);if(!v(r))return null;try{return JSON.parse(Lt(r,"utf8"))}catch{return null}}function ut(t,r){return!t||t.org_id===void 0?!0:t.org_id===r}function q(t,r){return ut(t,r)?null:(process.stderr.write(`error: this test belongs to org ${t.org_id}; you are logged in as org ${r}.
|
|
3
3
|
Switch profiles with \`kane-cli profiles switch\` to act on it.
|
|
4
4
|
`),2)}async function Pe(t={}){let r=!!process.stdin.isTTY&&!t.json,i=new B,n=new N;await tt({isInteractive:r,creds:i,config:n});let e=i.getDefaultEnv()??"prod";try{let o=await U({creds:i,env:e,log:()=>{}});return o.resolvedCreds?.org_id===void 0?(process.stderr.write("error: TMS did not return an org_id. Run `kane-cli login` again.\n"),{ok:!1,code:2}):{ok:!0,orgId:String(o.resolvedCreds.org_id)}}catch(o){if(o instanceof J)return process.stderr.write("error: not authenticated. Run `kane-cli login` first.\n"),{ok:!1,code:2};throw o}}async function ve(t,r){if(process.stdin.isTTY&&!t.json)return await Nt(r,t.root);let i=t.root??process.cwd(),n;try{n=await I({root:i,ignore:t.ignore})}catch(e){if(e instanceof R)return process.stderr.write(`error: ${e.message}
|
|
5
5
|
`),2;throw e}for(let e of n.results){let o=L(e.path);if(!ut(o,r))continue;let c={path:e.relPath.startsWith(".")?e.relPath:`./${e.relPath}`,name:C(e.path),has_meta:o!==null,source:e.source,synced:!!o?.testcase_id};o&&(o.test_id&&(c.test_id=o.test_id),o.testcase_id&&(c.testcase_id=o.testcase_id),o.org_id&&(c.org_id=o.org_id),o.project_id&&(c.project_id=o.project_id),o.folder_id&&(c.folder_id=o.folder_id)),process.stdout.write(JSON.stringify(c)+`
|
|
6
6
|
`)}return n.aborted&&process.stderr.write(`warn: walk aborted (${n.abortReason}). Pass --root or --ignore to narrow.
|
|
7
|
-
`),0}var dt=-1001,ft=-1002,mt=-1003,x={action:null,path:null};function At(t,r){return x.action=t,x.path=r,t==="run"?dt:t==="export"?ft:mt}function Bt({root:t,currentOrgId:r,onComplete:i}){let[n,e]=P.default.useState({kind:"list"});return P.default.useEffect(()=>{n.kind==="exiting"&&i(n.code)},[n,i]),n.kind==="list"?P.default.createElement(at,{root:t,currentOrgId:r,onSelect:o=>e({kind:"inspect",path:o.path,relPath:o.relPath}),onCancel:()=>e({kind:"exiting",code:0})}):n.kind==="inspect"?P.default.createElement(ct,{path:n.path,relPath:n.relPath,onAction:async o=>{e({kind:"exiting",code:At(o,n.path)})},onBack:()=>e({kind:"list"})}):null}async function Nt(t,r){let i=r??process.cwd(),{render:n}=await import("./build-JIKYOZUH.js"),e=await new Promise(o=>{let{unmount:c,waitUntilExit:a}=n(P.default.createElement(Bt,{root:i,currentOrgId:t,onComplete:l=>{c(),o(l)}}),{stdout:process.stderr,exitOnCtrlC:!0});a().then(()=>o(0)).catch(()=>o(0))});if(e===dt&&x.path){let{runTestMdFile:o}=await import("./run-test-md-
|
|
7
|
+
`),0}var dt=-1001,ft=-1002,mt=-1003,x={action:null,path:null};function At(t,r){return x.action=t,x.path=r,t==="run"?dt:t==="export"?ft:mt}function Bt({root:t,currentOrgId:r,onComplete:i}){let[n,e]=P.default.useState({kind:"list"});return P.default.useEffect(()=>{n.kind==="exiting"&&i(n.code)},[n,i]),n.kind==="list"?P.default.createElement(at,{root:t,currentOrgId:r,onSelect:o=>e({kind:"inspect",path:o.path,relPath:o.relPath}),onCancel:()=>e({kind:"exiting",code:0})}):n.kind==="inspect"?P.default.createElement(ct,{path:n.path,relPath:n.relPath,onAction:async o=>{e({kind:"exiting",code:At(o,n.path)})},onBack:()=>e({kind:"list"})}):null}async function Nt(t,r){let i=r??process.cwd(),{render:n}=await import("./build-JIKYOZUH.js"),e=await new Promise(o=>{let{unmount:c,waitUntilExit:a}=n(P.default.createElement(Bt,{root:i,currentOrgId:t,onComplete:l=>{c(),o(l)}}),{stdout:process.stderr,exitOnCtrlC:!0});a().then(()=>o(0)).catch(()=>o(0))});if(e===dt&&x.path){let{runTestMdFile:o}=await import("./run-test-md-E2K4GEOB.js"),c=await o(x.path,{});return x.action=null,x.path=null,c}if(e===ft&&x.path){let o=await Jt(x.path,{},t);return x.action=null,x.path=null,o}if(e===mt&&x.path){let o=await Wt(x.path,!0,t);return x.action=null,x.path=null,o}return e}async function Me(t,r){let i=Y(t);if(!v(i))return process.stderr.write(`error: file not found: ${i}
|
|
8
8
|
`),2;let n=L(i),e=q(n,r);if(e!==null)return e;let o={path:i,name:C(i),has_meta:n!==null};return n&&(n.commit_id&&(o.commit_id=n.commit_id),n.test_id&&(o.test_id=n.test_id),n.testcase_id&&(o.testcase_id=n.testcase_id),n.project_id&&(o.project_id=n.project_id),n.folder_id&&(o.folder_id=n.folder_id),n.org_id&&(o.org_id=n.org_id),n.session_name&&(o.session_name=n.session_name)),process.stdout.write(JSON.stringify(o)+`
|
|
9
9
|
`),0}async function Wt(t,r,i){let n=Y(t);if(!v(n))return process.stderr.write(`error: file not found: ${n}
|
|
10
10
|
`),2;let e=L(n),o=q(e,i);if(o!==null)return o;if(!r)return process.stderr.write(`error: refusing to delete without --yes.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as t}from"./chunk-
|
|
2
|
+
import{a as t}from"./chunk-TC74YD2D.js";import"./chunk-DTQJGYDA.js";import"./chunk-UR6MHSHU.js";async function a(n,e,o){let{TmsClient:r}=await import("./tms-client-R5ZIAOBH.js"),i=new r(t(n).tmsBaseUrl,e,o);for await(let m of i.listProjectsStream({perPage:1,maxPages:1}))return}export{a as validateBasicAuth};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b,c,d}from"./chunk-
|
|
2
|
+
import{a,b,c,d}from"./chunk-OOKRZUN4.js";import"./chunk-DTQJGYDA.js";import"./chunk-RZ4F3BHX.js";import"./chunk-UR6MHSHU.js";export{d as checkForUpdate,b as compareVersions,c as getSeverity,a as getUpdateCommand};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testmuai/kane-cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "KaneAI Terminal UI — browser automation testing agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"sharp": "^0.34.5"
|
|
24
24
|
},
|
|
25
25
|
"optionalDependencies": {
|
|
26
|
-
"@testmuai/kane-cli-darwin-arm64": "0.3.
|
|
27
|
-
"@testmuai/kane-cli-darwin-x64": "0.3.
|
|
28
|
-
"@testmuai/kane-cli-linux-x64": "0.3.
|
|
29
|
-
"@testmuai/kane-cli-win-x64": "0.3.
|
|
26
|
+
"@testmuai/kane-cli-darwin-arm64": "0.3.6",
|
|
27
|
+
"@testmuai/kane-cli-darwin-x64": "0.3.6",
|
|
28
|
+
"@testmuai/kane-cli-linux-x64": "0.3.6",
|
|
29
|
+
"@testmuai/kane-cli-win-x64": "0.3.6"
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"registry": "https://registry.npmjs.org",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b}from"./chunk-T3JEMMTA.js";import"./chunk-YCCUBQY4.js";import"./chunk-EJR3WRTW.js";import"./chunk-CBDUXGVQ.js";import"./chunk-TI5CHPPN.js";import"./chunk-HCBYKLMW.js";import"./chunk-FOT6AMNP.js";import"./chunk-C44QQJR4.js";import"./chunk-6YGTRKDT.js";import"./chunk-LIJX5PIV.js";import"./chunk-KKZRPFWO.js";import"./chunk-V7QXJKX7.js";import"./chunk-UR6MHSHU.js";export{b as FolderPicker,a as formatFolderLine};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b}from"./chunk-VZIBZDS2.js";import"./chunk-YCCUBQY4.js";import"./chunk-EJR3WRTW.js";import"./chunk-CBDUXGVQ.js";import"./chunk-TI5CHPPN.js";import"./chunk-HCBYKLMW.js";import"./chunk-FOT6AMNP.js";import"./chunk-C44QQJR4.js";import"./chunk-6YGTRKDT.js";import"./chunk-LIJX5PIV.js";import"./chunk-KKZRPFWO.js";import"./chunk-V7QXJKX7.js";import"./chunk-UR6MHSHU.js";export{b as ProjectPicker,a as formatProjectLine};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{f as a}from"./chunk-LT4VR7MQ.js";import"./chunk-6566EYUL.js";import"./chunk-G7VF5SDK.js";import"./chunk-L5LI2JF4.js";import"./chunk-YEV3OBEO.js";import"./chunk-VZIBZDS2.js";import"./chunk-T3JEMMTA.js";import"./chunk-YCCUBQY4.js";import"./chunk-EJR3WRTW.js";import"./chunk-VE3SUJMA.js";import"./chunk-PQLKQKQH.js";import"./chunk-CBDUXGVQ.js";import"./chunk-GCAHPH2E.js";import"./chunk-JI7KJKG4.js";import"./chunk-TI5CHPPN.js";import"./chunk-HCBYKLMW.js";import"./chunk-FOT6AMNP.js";import"./chunk-C44QQJR4.js";import"./chunk-6YGTRKDT.js";import"./chunk-LIJX5PIV.js";import"./chunk-KKZRPFWO.js";import"./chunk-V7QXJKX7.js";import"./chunk-UR6MHSHU.js";export{a as SingleShotApp};
|
package/dist/chunk-ANOIEEVS.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as z}from"./chunk-CB4WEGVB.js";import{d as X,g as Y}from"./chunk-X7VI7KK3.js";import{b as Q,e as F,j as V}from"./chunk-AH4AXJML.js";import{b as J,d as W}from"./chunk-G7VF5SDK.js";import{b as $}from"./chunk-VE3SUJMA.js";import{a as E}from"./chunk-CBDUXGVQ.js";import{a as q}from"./chunk-E47GFYXA.js";import{i as N,j as U}from"./chunk-FOT6AMNP.js";import{a as P}from"./chunk-LIJX5PIV.js";import{a as A,b as G}from"./chunk-KKZRPFWO.js";import{a as g}from"./chunk-V7QXJKX7.js";import{dirname as Ee,join as Re}from"path";function nt(e,r,t){let s=e.total_runs??1,o=e.run_dir,n,i;if(s>1&&o){let a=Ee(o);n=Array.from({length:s},(c,l)=>Re(a,String(r+l))),t&&t.length===s&&(i=t)}return{allRunDirs:n,flowObjectives:i}}function it(e,r,t,s){return{index:t,objective:r,summary:e.summary,oneLiner:e.one_liner,status:e.status,resultCode:e.result_code,reasonCode:e.reason_code,perFlowMetadata:e.per_flow_metadata,context:e.context??{memory:{},variables:{},pointer:""},run_dir:e.run_dir,run_dirs:s.allRunDirs,flow_objectives:s.flowObjectives}}import{spawn as xe}from"child_process";async function Z(e,r,t=100){let s=`${e.replace(/\/+$/,"")}/json/version`,o=await g(s);if(!o.ok)throw new Error(`CDP /json/version returned ${o.status}`);let n=await o.json();if(!n.webSocketDebuggerUrl)throw new Error("CDP /json/version missing webSocketDebuggerUrl");let i=new q(n.webSocketDebuggerUrl);await new Promise((C,u)=>{i.once("open",C),i.once("error",u)});let a=1,c=new Map;i.on("message",C=>{let u;try{u=JSON.parse(C.toString())}catch{return}if(u.id==null)return;let y=c.get(u.id);y&&(c.delete(u.id),u.error?y.reject(new Error(u.error.message)):y.resolve(u.result))});function l(C,u){let y=a++;return new Promise((Ce,Se)=>{c.set(y,{resolve:ve=>Ce(ve),reject:Se});let H={id:y,method:C};u&&(H.params=u),i.send(JSON.stringify(H))})}let d=(await l("Target.getTargets")).targetInfos.find(C=>C.type==="page");if(!d)throw i.close(),new Error("CDP: no page target found");let S=(await l("Browser.getWindowForTarget",{targetId:d.targetId})).windowId,b="",h=!1,_=null,R=!1;i.on("close",()=>{R=!0}),i.on("error",()=>{R=!0});async function K(){if(!h){if(R){h=!0;return}try{let u=(await l("Browser.getWindowBounds",{windowId:S})).bounds,y=`${u.left}:${u.top}:${u.width}:${u.height}`;y!==b&&(b=y,r({left:u.left,top:u.top,width:u.width,height:u.height}))}catch{}h||(_=setTimeout(K,t))}}return K(),{stop(){if(!h){h=!0,_&&clearTimeout(_);try{i.close()}catch{}}}}}var Ie=new Set(["1","true","yes"]);function gt(e){if(e?.headless)return null;let r=process.env.KANE_CLI_DISABLE_MARKER;if(r!=null&&Ie.has(r.toLowerCase()))return null;let t=z();if(!t)return null;let s=[...t.args,"overlay"];e?.text&&s.push(e.text);let o;try{o=xe(t.cmd,s,{cwd:t.cwd,stdio:["pipe","ignore","ignore"],detached:!1,windowsHide:!0})}catch{return null}function n(c){if(!(!o.stdin||o.stdin.destroyed))try{o.stdin.write(JSON.stringify(c)+`
|
|
3
|
-
`)}catch{}}e?.chromePid&&e.chromePid>0&&n({type:"chrome_pid",pid:e.chromePid});let i=null;e?.cdpEndpoint&&Z(e.cdpEndpoint,c=>n({type:"bounds",...c})).then(c=>{i=c.stop}).catch(()=>{});let a=!1;return{setRunActive(c){a||n({type:"run_active",active:c})},setStepText(c){if(a)return;let l=c.trim();l&&n({type:"step_text",text:l})},setStepComplete(){a||n({type:"step_complete"})},kill(){if(!a){a=!0,i?.();try{o.stdin?.end()}catch{}try{o.kill("SIGTERM")}catch{}}}}}import{readFileSync as ke,existsSync as Ae}from"fs";function bt(e){if(!Ae(e))return null;try{return ke(e,"utf-8").trim()||null}catch{return null}}function ee(e,r,t){return`${e}/projects/${r}/test-cases/${t}`}function wt(e,r,t,s){return`${ee(e,r,t)}/dashboard/share/${s}?type=summary&agentView=true&fqdn=summary-page`}function _t(e,r,t){return`${ee(e,r,t)}/dashboard?type=summary&agentView=true&fqdn=summary-page`}import{readFileSync as te,readdirSync as re,existsSync as v}from"fs";import{join as w}from"path";function Et(e,r,t,s,o,n){try{let i=w(e,"runs",String(r),"run-test");if(!v(i)){o("warn","SCREENSHOT_SKIP","Runs dir not found",{step_index:t,reason:"runsDir_not_found",path:i});return}let a=i;if(n){let h=w(i,`child-${n}`);if(!v(h)){o("warn","SCREENSHOT_SKIP","Child dir not found",{step_index:t,child_id:n,reason:"child_dir_not_found",path:h});return}let _=re(h).filter(R=>v(w(h,R,"screenshots")));if(_.length===0){o("warn","SCREENSHOT_SKIP","No screenshots dir under child",{step_index:t,child_id:n,reason:"no_child_screenshots_dir"});return}a=w(h,_[0])}else if(!v(w(i,"screenshots"))){let h=re(i).filter(_=>v(w(i,_,"screenshots")));if(h.length===0){o("warn","SCREENSHOT_SKIP","No screenshots dir found",{step_index:t,reason:"no_screenshots_dir"});return}a=w(i,h[0])}let c=w(a,"screenshots",`step_${String(t).padStart(3,"0")}.png`);if(!v(c)){o("warn","SCREENSHOT_SKIP","Screenshot not found",{step_index:t,child_id:n,reason:"screenshot_not_found",path:c});return}let l=w(i,"actions.ndjson");if(!v(l)){o("warn","SCREENSHOT_SKIP","NDJSON not found",{step_index:t,reason:"ndjson_not_found"});return}let f=te(l,"utf-8").trim().split(`
|
|
4
|
-
`),d=f[f.length-1];if(!d){o("warn","SCREENSHOT_SKIP","NDJSON empty",{step_index:t,reason:"ndjson_empty"});return}let S=JSON.parse(d).action_id;if(!S){o("warn","SCREENSHOT_SKIP","No action_id in NDJSON",{step_index:t,reason:"no_action_id"});return}let b=te(c);s.enqueue(S,b),o("info","SCREENSHOT_ENQUEUED","Screenshot enqueued",{step_index:t,child_id:n,action_id:S,size:b.length})}catch(i){o("error","SCREENSHOT_DISPATCH_ERROR","Screenshot dispatch error",{step_index:t,error:i instanceof Error?i.message:String(i)})}}var Pe=null,Te=()=>Pe??=import("sharp").then(e=>e.default??e).catch(()=>null),se=class{maxWorkers;maxRetries=2;queue=[];activeCount=0;drainResolvers=[];sas;log;uploadedExt=new Map;constructor(r,t=3,s){this.sas=r,this.maxWorkers=t,this.log=s}updateSas(r){this.sas=r}enqueue(r,t){this.queue.push({operationId:r,buffer:t}),this.pump()}async drain(r=3e4){if(!(this.queue.length===0&&this.activeCount===0))return new Promise(t=>{this.drainResolvers.push(t),setTimeout(()=>{t()},r)})}pump(){for(;this.activeCount<this.maxWorkers&&this.queue.length>0;){let r=this.queue.shift();this.activeCount++,this.processJob(r).finally(()=>{if(this.activeCount--,this.pump(),this.queue.length===0&&this.activeCount===0){for(let t of this.drainResolvers)t();this.drainResolvers=[]}})}}async processJob(r){let t,s="image/webp",o=await Te();if(o)try{let c=await o(r.buffer).webp({quality:80}).toBuffer();t=new Uint8Array(c)}catch(c){t=new Uint8Array(r.buffer),s="image/png",this.log?.("warn","SCREENSHOT_CONVERT_FAILED","WebP conversion failed, using PNG",{operation_id:r.operationId,error:c instanceof Error?c.message:String(c)})}else t=new Uint8Array(r.buffer),s="image/png";let n=s==="image/webp"?"webp":"png",i=`test_screenshots/untagged_screenshot/${r.operationId}.${n}`,a=`${this.sas.base_url}/${this.sas.container}/${i}?${this.sas.sas_token}`;for(let c=0;c<=this.maxRetries;c++)try{let l=await g(a,{method:"PUT",headers:{"Content-Type":s,"x-ms-blob-type":"BlockBlob"},body:t});if(l.ok){this.uploadedExt.set(r.operationId,n);return}if(c<this.maxRetries){await this.backoff(c);continue}this.log?.("warn","SCREENSHOT_UPLOAD_FAILED","Screenshot upload failed after retries",{operation_id:r.operationId,status:l.status,attempts:this.maxRetries+1})}catch{if(c<this.maxRetries){await this.backoff(c);continue}this.log?.("warn","SCREENSHOT_UPLOAD_FAILED","Screenshot upload failed (network error)",{operation_id:r.operationId,error:"network",attempts:this.maxRetries+1})}}backoff(r){let t=r===0?1e3:3e3;return new Promise(s=>setTimeout(s,t))}getExt(r){return this.uploadedExt.get(r)??"png"}getExtMap(){return this.uploadedExt}isNearExpiry(){if(!this.sas.expiry)return!1;let r=new Date(this.sas.expiry).getTime();return Date.now()>r-5*6e4}};function oe(e,r){let t={},s={},o=r;for(let[n,i]of Object.entries(e))if(i.secret){let a=`secrets.user.${n}`;t[a]={value:i.value,secret:!0,syntax:`{{secrets.user.${n}}}`,type:"secret"},s[n]=a,o=o.replaceAll(`{{${n}}}`,`{{secrets.user.${n}}}`)}else{let a=`global.${n}`;t[a]={value:i.value,secret:!1,syntax:`{{global.${n}}}`,type:"global"},s[n]=a,o=o.replaceAll(`{{${n}}}`,`{{global.${n}}}`)}return{variables:t,objective:o,keyMap:s}}var T=class{constructor(r){this.baseUrl=r}async pushSecret(r){let t=A(r.username,r.accessKey),s=await g(`${this.baseUrl}/logistics/v1.0/secrets/create`,{method:"PUT",headers:{Authorization:t,"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({secretKey:r.secretKey,secretValue:r.secretValue,orgId:r.orgId,username:r.username,scope:"user",type:"user",accessKey:r.accessKey})});if(!s.ok)throw new Error(`Push secret failed: ${s.status} ${await s.text()}`)}static extractVariableKeys(r){let t=r.matchAll(/\{\{([a-zA-Z_][a-zA-Z0-9_]*)\}\}/g),s=new Set;for(let o of t)s.add(o[1]);return[...s]}};var j=class extends G{constructor(r,t,s){super(r,{username:t,accessKey:s})}async upsertVariable(r){let t=r.environmentId??0,s=await g(`${this.baseUrl}/v1/variables`,{method:"POST",headers:this.headers(),body:JSON.stringify({name:r.name,value:String(r.value),type:"variable",value_type:"string",is_persist:r.isPersist??!1,environment_id:t})});if(s.ok)return{id:(await s.json()).id??0};if(s.status!==409&&s.status!==422)return{id:0};if(!(await g(`${this.baseUrl}/v1/variables/name/${encodeURIComponent(r.name)}`,{method:"PUT",headers:this.headers(),body:JSON.stringify({value:String(r.value),value_type:"string",type:"variable",environment_id:t})})).ok)return{id:0};let n=await g(`${this.baseUrl}/v1/variables/${encodeURIComponent(r.name)}?environment_id=${t}`,{method:"GET",headers:this.headers()});return n.ok?{id:(await n.json()).data?.id??0}:{id:0}}};import{readdirSync as je,readFileSync as ie,existsSync as ae}from"fs";import{join as Oe}from"path";function ne(e,r){if(!ae(e))return{};let t={},s;try{s=je(e).filter(o=>o.endsWith(".json")).sort()}catch{return{}}for(let o of s)try{let n=ie(Oe(e,o),"utf-8"),i=JSON.parse(n);if(i&&typeof i=="object"){for(let[a,c]of Object.entries(i))if(c&&typeof c=="object"&&"value"in c){let l=c;t[a]={value:l.value,secret:l.secret??!1,syntax:l.syntax??`{{${a}}}`}}}}catch{r?r("warn","VARIABLE_PARSE_FAILED","Skipping invalid variables file",{file:o}):process.stderr.write(`[variables] Warning: skipping invalid variables file: ${o}
|
|
5
|
-
`)}return t}function ce(e){if(!ae(e))throw new Error(`Variables file not found: ${e}`);let r=ie(e,"utf-8"),t=JSON.parse(r),s={};if(t&&typeof t=="object"){for(let[o,n]of Object.entries(t))if(n&&typeof n=="object"&&"value"in n){let i=n;s[o]={value:i.value,secret:i.secret??!1,syntax:i.syntax??`{{${o}}}`}}}return s}function le(e){let r;try{r=JSON.parse(e)}catch{throw new Error("Invalid --variables JSON")}let t={};if(r&&typeof r=="object"){for(let[s,o]of Object.entries(r))if(o&&typeof o=="object"&&"value"in o){let n=o;t[s]={value:n.value,secret:n.secret??!1,syntax:n.syntax??`{{${s}}}`}}}return t}function de(e,r,t){let s=ne(e,t),o=ne(r,t);return{...s,...o}}function Kt(e,r){if(Object.keys(e).length===0)return{};let t={};for(let[s,o]of Object.entries(e)){let n=o.syntax??`{{${s}}}`;r.includes(n)&&(t[s]=o)}return t}function Ht(e){let r=de(e.globalDir,e.localDir,e.onLoadError),t=e.file?ce(e.file):{},s=e.inline?le(e.inline):{},o={...r,...t,...s},n=Object.keys(o).length>0,{variables:i,objective:a}=n?oe(o,e.objective):{variables:{},objective:e.objective},c=Object.entries(o).filter(([,f])=>f.secret),l=Object.entries(o).filter(([,f])=>!f.secret);return{raw:o,auteur:i,auteurObjective:a,secretEntries:c,nonSecretEntries:l}}async function qt(e){if(e.localMode)return{};let r=E(e.env);if(e.variables.secretEntries.length>0){let s=new T(r.secretsBaseUrl);for(let[o,n]of e.variables.secretEntries)s.pushSecret({secretKey:o,secretValue:n.value,username:e.auth.username,accessKey:e.auth.access_key,orgId:e.orgId}).then(()=>e.log("info","SECRET_PUSH_OK","Secret pushed",{key:o})).catch(i=>e.log("error","SECRET_PUSH_FAILED","Secret push failed",{key:o,error:String(i)}))}let t={};if(e.variables.nonSecretEntries.length>0){let s=new j(r.tmsBaseUrl,e.auth.username,e.auth.access_key);for(let[o,n]of e.variables.nonSecretEntries)try{let i=await s.upsertVariable({name:o,value:n.value});t[o]=i.id,e.log("info","VAR_PUSH_OK","Variable pushed",{name:o,id:i.id})}catch(i){e.log("error","VAR_PUSH_FAILED","Variable push failed",{name:o,error:String(i)})}}return t}function Jt(e){let r={objective:e.objective,model:e.model,width:e.windowSize.width,height:e.windowSize.height,session_id:e.sessionId,run_index:e.runIndex,stream:!0,max_steps:e.maxSteps??30,headless:e.headless??!1};return e.url&&(r.url=e.url),e.chrome.wsEndpoint?r.ws_endpoint=e.chrome.wsEndpoint:e.chrome.cdpEndpoint&&(r.cdp_endpoint=e.chrome.cdpEndpoint),e.auth.basicAuth?(r.username=e.auth.basicAuth.username,r.access_key=e.auth.basicAuth.access_key):e.auth.token&&(r.auth={type:"bearer",token:e.auth.token}),e.disableAskUser&&(r.disable_ask_user=!0),e.enableTaskSkills&&(r.enable_task_skills=!0),e.variables&&Object.keys(e.variables).length>0&&(r.variables=e.variables),e.globalContext&&(r.global_context=e.globalContext),e.localContext&&(r.local_context=e.localContext),e.sessionContext&&(r.session_context=e.sessionContext),r}var De=15e3,M=3,ue=[500,1e3];async function Xt(e){if(process.env.KANE_LOCK_CONFLICT_SIMULATE==="1")return{ok:!1,reason:"concurrent",httpStatus:409,message:"simulated contention (KANE_LOCK_CONFLICT_SIMULATE=1)"};let r=`${e.baseUrl}/test/${encodeURIComponent(e.testId)}/playground`,t=await O(r,{from_commit_id:e.fromCommitId,new_commit_id:e.newCommitId},e.auth);return t.ok?{ok:!0,sessionExpiresAt:m(t.body,"session_expires_at")??""}:{ok:!1,...Le(t)}}function Le(e){let r=m(e.body,"error")??m(e.body,"code")??"",t=m(e.body,"message")??m(e.body,"detail")??e.text??`HTTP ${e.status}`,s;return e.status===0?s="network":e.status===401||e.status===403?s="auth":e.status===409&&r==="PlaygroundBaseCommitMismatch"?s="base_mismatch":e.status===409?s="concurrent":e.status===422?s="disabled":e.status===400&&/no committed/i.test(t)?s="no_commits":e.status===400?s="missing_field":e.status>=500||e.status===408||e.status===429?s="network":s="other",{reason:s,httpStatus:e.status,message:t}}async function Yt(e){let r=`${e.baseUrl}/test/${encodeURIComponent(e.testId)}/playground/reserve`,t=await O(r,void 0,e.auth);return t.ok?{ok:!0,sessionExpiresAt:m(t.body,"session_expires_at")??""}:{ok:!1,expired:t.status===404,httpStatus:t.status,message:m(t.body,"message")??m(t.body,"detail")??t.text??`HTTP ${t.status}`}}async function fe(e){let r=`${e.baseUrl}/test/${encodeURIComponent(e.testId)}/commit`,t={commit_id:e.body.commitId,from_commit_id:e.body.fromCommitId,commit_message:e.body.commitMessage,total_steps:e.body.totalSteps};e.body.timeTaken!==void 0&&(t.time_taken=e.body.timeTaken),e.body.objectives!==void 0&&(t.objectives=e.body.objectives);let s=await O(r,t,e.auth);return s.ok?{ok:!0,testId:m(s.body,"test_id")??e.testId,testcaseId:m(s.body,"testcase_id")??"",projectId:m(s.body,"project_id"),isTestCaseDeleted:typeof s.body?.is_test_case_deleted=="boolean"?s.body.is_test_case_deleted:void 0}:{ok:!1,...Ne(s)}}function Ne(e){let r=m(e.body,"error")??m(e.body,"code")??"",t=m(e.body,"message")??m(e.body,"detail")??e.text??`HTTP ${e.status}`,s;return e.status===0?s="network":e.status===401||e.status===403?s="auth":e.status===409&&r==="PlaygroundBaseCommitMismatch"?s="base_mismatch":e.status===409&&r==="PlaygroundCommitLockMismatch"?s="lock_mismatch":e.status===409?s="expired":e.status===422?s="not_found":e.status>=500||e.status===408||e.status===429?s="network":s="other",{reason:s,httpStatus:e.status,message:t}}async function Zt(e){let r=`${e.baseUrl}/test/${encodeURIComponent(e.testId)}/commit`,t={discard:!0,commit_id:e.body.commitId,from_commit_id:e.body.fromCommitId,commit_message:"(discarded)",total_steps:1},s=await O(r,t,e.auth);return s.ok?{ok:!0}:{ok:!1,reason:m(s.body,"error")??"other",httpStatus:s.status,message:m(s.body,"message")??m(s.body,"detail")??s.text??`HTTP ${s.status}`}}async function O(e,r,t){let s=null;for(let o=1;o<=M;o++){let n=new AbortController,i=setTimeout(()=>n.abort(),De);try{let a=await g(e,{method:"POST",headers:{Authorization:A(t.username,t.accessKey),"Content-Type":"application/json",Accept:"application/json"},...r!==void 0?{body:JSON.stringify(r)}:{},signal:n.signal});clearTimeout(i);let c=await a.text(),l=null;if(c)try{l=JSON.parse(c)}catch{}let f=a.status>=500||a.status===408||a.status===429;if(a.ok||!f)return{ok:a.ok,status:a.status,body:l,text:c};if(o<M){await me(ue[o-1]??1e3);continue}return{ok:!1,status:a.status,body:l,text:c}}catch(a){if(clearTimeout(i),s=a,o<M){await me(ue[o-1]??1e3);continue}}}return{ok:!1,status:0,body:null,text:s?.message??"exhausted retries"}}function me(e){return new Promise(r=>setTimeout(r,e))}function m(e,r){if(typeof e!="object"||e===null)return;let t=e[r];return typeof t=="string"?t:void 0}import{readFileSync as pe,writeFileSync as he,existsSync as be}from"fs";function ge(e,r,t){if(t.forceAuthor)return"re-recorded from scratch";if(t.retryTriggered)return"re-recorded after retry";if(r.length>0&&r.every(i=>i.kind==="author"&&i.reason==="no-result-md"))return"initial recording";if(r.length>0&&r.every(i=>i.kind==="replay"))return t.wantsPush?"re-recorded (no source changes)":"no changes";let s=[];for(let i=0;i<r.length;i++){let a=r[i];if(!a||a.kind!=="author"||a.reason==="downstream-of-divergence"||a.reason==="no-result-md")continue;let c=Ue(e,e.steps[i]);switch(a.reason){case"structure-mismatch":s.push(`added/removed: ${c}`);break;case"md5-mismatch":s.push(`modified: ${c}`);break;case"missing-recording":s.push(`re-recorded: ${c}`);break;case"recorded-failed":s.push(`re-authored after failure: ${c}`);break}}if(s.length===0)return"automated commit";let o=s.filter((i,a)=>a===0||s[a-1]!==i),n=o.slice(0,3).join("; ");return o.length>3?`${n}; +${o.length-3} more`:n}function Ue(e,r){if(!r)return"unknown step";let t=r.trace[0]?.stepIndex;if(t==null)return"unknown step";let o=e.rootSteps[t-1]?.heading?.trim()??"";return r.trace.length>1?o?`imported step in "${o}"`:`imported step ${t}`:o||`step ${t}`}function $e(e){if(!(!e.shouldReplaceLocalOutput||!e.resolvedTest||!e.sourcePath||!e.stepRunRecords||!e.outcomes||!e.overallStatus))return async()=>{Y({resolvedTest:e.resolvedTest,sessionDir:e.session.sessionDir,stepRunRecords:e.stepRunRecords,outcomes:e.outcomes,overallStatus:e.overallStatus,startedISO:e.startedISO??new Date().toISOString(),durationS:e.durationS??0,sessionId:e.session.sessionId,commitId:e.fromCommitId??"",tmsIds:e.tmsIds??{},codeExportDir:e.codeExportDir}),V(Q(e.sourcePath));let r=new Set;for(let t of e.resolvedTest.steps)if(t.trace.length>1){let s=X(t.trace);if(r.has(s))continue;r.add(s),be(`${s}.staging`)&&V(s)}}}function Fe(e){if(!(!e.shouldCommit||e.isFirstRun||!e.tmsBaseUrl||!e.testId||!e.fromCommitId||!e.newCommitId||!e.basicAuth||!e.resolvedTest||!e.decisions))return async()=>{let r=ge(e.resolvedTest,e.decisions,{wantsPush:e.wantsPush??!1,retryTriggered:e.retryTriggered??!1,forceAuthor:e.forceAuthor??!1}),t=e.resolvedTest.steps.map(o=>o.objective).filter(o=>typeof o=="string"&&o.length>0).slice(0,50),s=await fe({baseUrl:`${e.tmsBaseUrl}/kane-cli/v1`,testId:e.testId,body:{commitId:e.newCommitId,fromCommitId:e.fromCommitId,commitMessage:r,totalSteps:e.resolvedTest.steps.length,timeTaken:Math.round(e.durationS??0),objectives:t},auth:{username:e.basicAuth.username,accessKey:e.basicAuth.access_key}});if(s.ok&&e.sourcePath){let o=F(e.sourcePath);try{let n=JSON.parse(pe(o,"utf8"));n.commit_id=e.newCommitId,he(o,JSON.stringify(n,null,2)+`
|
|
6
|
-
`,"utf8")}catch(n){process.stderr.write(`warn: failed to update meta.json commit_id: ${n.message}
|
|
7
|
-
`)}}return s}}function Ve(e){if(!(!e.isFirstRun||!e.sourcePath))return async r=>{if(!e.sourcePath)return;let t=F(e.sourcePath);try{let s=be(t)?JSON.parse(pe(t,"utf8")):{};e.session.sessionId&&(s.commit_id=e.session.sessionId),r&&(s.testcase_id=r),e.tmsIds?.testId&&(s.test_id=e.tmsIds.testId),e.tmsIds?.projectId&&(s.project_id=e.tmsIds.projectId),e.tmsIds?.folderId&&(s.folder_id=e.tmsIds.folderId),e.tmsIds?.orgId&&(s.org_id=e.tmsIds.orgId),e.tmsIds?.sessionName&&(s.session_name=e.tmsIds.sessionName),he(t,JSON.stringify(s,null,2)+`
|
|
8
|
-
`,"utf8")}catch(s){process.stderr.write(`warn: failed to update meta.json after endTest: ${s.message}
|
|
9
|
-
`)}}}function dr(e){let r=E(e.env),{session:t,auth:s}=e,o=s.basicAuth?{username:s.basicAuth.username,accessKey:s.basicAuth.access_key}:s.token,n=s.resolvedCreds?.username??s.basicAuth?.username??"",i=s.resolvedCreds?.access_key??s.basicAuth?.access_key??"",a=s.resolvedCreds?.org_id??0,c=s.resolvedCreds?.user_id??0,l=[];for(let b of Object.keys(t.auteurVariables))b.startsWith("secrets.user.")&&l.push({key_name:b.replace("secrets.user.",""),scope:"user"});let d=t.getContext().prior_runs.map(b=>b.status),p=t.auteurVariables,S=Object.keys(p).length>0;return{controllerBaseUrl:r.controllerBaseUrl,tmsBaseUrl:r.tmsBaseUrl,auth:o,authResolver:s.resolver,sessionId:t.sessionId,sessionDir:t.sessionDir,testId:t.testId,commitId:t.sessionId,projectId:e.projectId,folderId:e.folderId,firstObjective:t.firstObjective??"KaneAI Test",firstUrl:t.firstUrl??"",runDirs:t.getRunDirs(),runObjectives:t.getRunObjectives(),runMetadata:t.getRunMetadata(),startedAt:t.startedAt,endedAt:new Date().toISOString(),totalSteps:e.totalSteps,totalDuration:e.totalDuration,runStatuses:d,orgId:a,userId:c,tmsUsername:n,tmsAccessKey:i,screenshotBaseUrl:t.screenshotBaseUrl,screenshotExtMap:e.screenshotExtMap,shareApiBaseUrl:r.shareApiBaseUrl,variables:S?p:void 0,variableIds:e.variableIds,secrets:l,codeExport:e.codeExport,onProgress:e.onProgress,log:e.log,shouldUploadArtifacts:e.shouldUploadArtifacts,shouldReplaceLocalOutput:e.shouldReplaceLocalOutput,shouldCommit:e.shouldCommit,isFirstRun:e.isFirstRun,onAtomicReplace:$e(e),onCommitLock:Fe(e),onFinalizeSuccess:Ve(e)}}var ye=["python","javascript"];function Me(e){if(e!==void 0){if(!ye.includes(e))throw new Error(`--code-language must be one of: ${ye.join(", ")} (got "${e}")`);return e}}function mr(e,r){let t=Me(e.codeLanguage);return{enabled:e.codeExport??r.enabled,language:t??r.language,skipValidation:e.skipCodeValidation??r.skip_validation}}async function pr(e){try{let t=await new P(e.tmsBaseUrl,e.auth.username,e.auth.access_key).createAtmTest({objective:e.objective.slice(0,100),creation_mode:"KANECLI",playground_disabled:e.hasCustomProfile,testURL:e.url,project_id:e.projectId,folder_id:e.folderId,authoring_version:4});return e.log("info","ATM_CREATE_OK","Test created",{test_id:t}),t}catch(r){return e.log("error","ATM_CREATE_FAILED","Test creation failed",{error:r instanceof Error?r.message:String(r)}),null}}import{mkdtempSync as Ye,rmSync as Ze}from"fs";import{join as et}from"path";import{tmpdir as tt}from"os";import{spawn as we,spawnSync as Be}from"child_process";import{existsSync as B}from"fs";import{createConnection as Ke}from"net";import{homedir as x,platform as k}from"os";import{join as I}from"path";var He=new Set(["1","true","yes"]),D=class extends Error{constructor(r){super(r),this.name="ChromeNotFoundError"}};function Rr(e){return e instanceof D?e.message:`Chrome failed: ${e instanceof Error?e.message:String(e)}`}var L={darwin:["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",I(x(),"Applications/Google Chrome.app/Contents/MacOS/Google Chrome"),"/Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing",I(x(),"Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"),"/Applications/Chromium.app/Contents/MacOS/Chromium"],linux:["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/usr/bin/google-chrome-for-testing","/usr/local/bin/google-chrome-for-testing",I(x(),"chrome-for-testing/chrome-linux64/chrome"),"/usr/bin/chromium","/usr/bin/chromium-browser","/snap/bin/chromium"],win32:["C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe","C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",I(x(),"AppData\\Local\\Google\\Chrome\\Application\\chrome.exe"),"C:\\chrome-for-testing\\chrome-win64\\chrome.exe",I(x(),"AppData\\Local\\chrome-for-testing\\chrome-win64\\chrome.exe")]};function qe(){if(process.env.KANE_CLI_CHROME_PATH)return process.env.KANE_CLI_CHROME_PATH;let e=k(),r=L[e]??L.linux;for(let t of r)if(B(t))return t;return e==="win32"?"chrome.exe":"google-chrome"}function Ge(){if(process.env.KANE_CLI_CHROME_PATH)return B(process.env.KANE_CLI_CHROME_PATH);let e=k();if((L[e]??L.linux).some(o=>B(o)))return!0;let t=e==="win32"?"chrome.exe":"google-chrome",s=e==="win32"?"where":"which";try{return Be(s,[t],{stdio:"ignore"}).status===0}catch{return!1}}function Je(){let e=k();return e==="darwin"?["Google Chrome is required but was not found at any standard path.","","Install via Homebrew (recommended):"," brew install --cask google-chrome","","Or download:"," https://www.google.com/chrome/","","Then re-run your command. Set KANE_CLI_CHROME_PATH=/path/to/chrome","to point at a non-standard install."].join(`
|
|
10
|
-
`):e==="linux"?["Google Chrome is required but was not found at /usr/bin/google-chrome.","(amd64 / x86_64 only \u2014 Google does not ship Chrome for Linux ARM.)","","Debian / Ubuntu (any version):"," wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"," sudo apt install -y ./google-chrome-stable_current_amd64.deb","","Fedora / RHEL / AlmaLinux / Rocky:"," sudo dnf install -y https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm","","Then re-run your command. Set KANE_CLI_CHROME_PATH=/path/to/chrome","to point at a non-standard install."].join(`
|
|
11
|
-
`):e==="win32"?["Google Chrome is required but was not found in Program Files or AppData.","","Install via winget (Windows 10 1809+):"," winget install --id Google.Chrome -e --silent","","Or download:"," https://www.google.com/chrome/","","Then re-run your command. Set KANE_CLI_CHROME_PATH=C:\\path\\to\\chrome.exe","to point at a non-standard install."].join(`
|
|
12
|
-
`):["Google Chrome is required.","Install from https://www.google.com/chrome/","(Note: no official Chrome builds for BSD or Alpine/musl Linux.)"].join(`
|
|
13
|
-
`)}function We(e){let r=k(),t=[`--remote-debugging-port=${e.port}`,`--user-data-dir=${e.userDataDir}`,`--window-size=${e.width},${e.height}`,"--no-first-run","--no-default-browser-check","--disable-blink-features=AutomationControlled","--disable-features=DownloadBubble,DownloadBubbleV2","--safebrowsing-disable-download-protection","--disable-popup-blocking","--disable-notifications","--disable-infobars","--disable-translate","--disable-prompt-on-repost","--disable-background-networking","--disable-client-side-phishing-detection","--disable-default-apps","--disable-hang-monitor","--disable-sync","--metrics-recording-only","--safebrowsing-disable-auto-update","--disable-backgrounding-occluded-windows","--disable-background-timer-throttling","--test-type=webdriver","--allow-pre-commit-input","--enable-logging","--v=1"];return r==="linux"&&(t.push("--no-sandbox"),t.push("--disable-dev-shm-usage"),t.push("--password-store=basic")),r==="darwin"&&t.push("--use-mock-keychain"),e.headless&&t.push("--headless=new"),t}function ze(e){return new Promise(r=>{let t=Ke({port:e,host:"127.0.0.1"});t.setTimeout(1e3),t.on("connect",()=>{t.destroy(),r(!0)}),t.on("timeout",()=>{t.destroy(),r(!1)}),t.on("error",()=>{t.destroy(),r(!1)})})}async function Qe(){for(let e=N;e<=U;e++)if(!await ze(e))return e;throw new Error(`All CDP ports ${N}-${U} are in use. Close other Chrome instances.`)}async function Xe(e,r=15e3){let t=Date.now(),s=`http://127.0.0.1:${e}/json/version`;for(;Date.now()-t<r;){try{if((await g(s)).ok)return`http://127.0.0.1:${e}`}catch{}await new Promise(o=>setTimeout(o,200))}throw new Error(`Chrome CDP not ready after ${r}ms on port ${e}`)}async function _e(e){let r=process.env.KANE_CLI_SKIP_BROWSER_DOWNLOAD;if(!(r!=null&&He.has(r.toLowerCase()))&&!Ge())throw J()?.log("error","CHROME_NOT_FOUND","Startup gate: Chrome unavailable at standard system paths",{platform:process.platform,kane_cli_chrome_path:process.env.KANE_CLI_CHROME_PATH??null,skip_browser_download:process.env.KANE_CLI_SKIP_BROWSER_DOWNLOAD??null}),new D(Je());let s=k(),o=await Qe(),n=qe(),i=We({port:o,...e});e.startUrl&&i.push(e.startUrl);let a=we(n,i,{stdio:"ignore",detached:!0});a.unref();let c=await new Promise((l,f)=>{a.on("error",d=>{f(new Error(`Failed to launch Chrome: ${d.message}. Is Chrome installed at ${n}?`))}),a.on("close",d=>{d!==null&&d!==0&&f(new Error(`Chrome exited during startup with code ${d}`))}),Xe(o).then(l,f)});return{process:a,port:o,cdpEndpoint:c,kill(){try{if(a.pid)if(s==="win32")we("taskkill",["/pid",String(a.pid),"/T","/F"],{stdio:"ignore"});else try{process.kill(-a.pid,"SIGKILL")}catch{a.kill("SIGKILL")}else a.kill("SIGKILL")}catch{}}}}async function Or(e){if(e.cft)return{instance:null,tempDir:null};if(e.wsEndpoint)return{wsEndpoint:e.wsEndpoint,instance:null,tempDir:null};if(e.cdpEndpoint){let o=await g(`${e.cdpEndpoint}/json/version`);if(!o.ok)throw new Error(`CDP endpoint not reachable: ${e.cdpEndpoint} (${o.status})`);return{cdpEndpoint:e.cdpEndpoint,instance:null,tempDir:null}}let r,t=null;if(e.config.chrome_profile_path)r=e.config.chrome_profile_path.replace("~",process.env.HOME??"~");else{t=Ye(et(tt(),"kane-clean-")),r=t;let o=t;W("tempDir",()=>{try{Ze(o,{recursive:!0,force:!0})}catch{}})}let s=await _e({userDataDir:r,width:e.config.window_size.width,height:e.config.window_size.height,startUrl:e.startUrl,headless:e.headless});return{cdpEndpoint:s.cdpEndpoint,instance:s,tempDir:t}}var rt="KaneAI Generated",st="Untitled";async function $r(e){let r=e.config.load(),t=new P(E(e.env).tmsBaseUrl,e.tmsCreds.username,e.tmsCreds.access_key),s=e.projectName??rt,o=e.folderName??st,n=r.project_id??null,i=r.project_name??null;if(!n){let d=(await t.listProjects()).find(p=>p.name===s);if(d)n=d.project_id,i=d.name,e.log("info","ENSURE_PROJECT_FOUND","Found default project",{project_id:n,name:i});else{let p=await t.createProject(s);n=p.id,i=p.name,e.log("info","ENSURE_PROJECT_CREATED","Created default project",{project_id:n,name:i})}$(e.creds,e.config,e.profile,e.env,{projectId:n,projectName:i})}let a=r.folder_id??null,c=r.folder_name??null,l=!r.project_id;if(!a||l){let d=(await t.listFolders(n)).find(p=>p.name===o);if(d)a=d.id,c=d.name,e.log("info","ENSURE_FOLDER_FOUND","Found default folder",{folder_id:a,name:c});else{let p=await t.createFolder(n,o);a=p.id,c=p.name,e.log("info","ENSURE_FOLDER_CREATED","Created default folder",{folder_id:a,name:c})}$(e.creds,e.config,e.profile,e.env,{folderId:a,folderName:c})}return{projectId:n,projectName:i??s,folderId:a,folderName:c??o}}export{nt as a,it as b,D as c,Rr as d,_e as e,gt as f,bt as g,wt as h,_t as i,Et as j,se as k,oe as l,T as m,j as n,Kt as o,Ht as p,qt as q,Jt as r,Xt as s,Yt as t,Zt as u,dr as v,mr as w,pr as x,Or as y,$r as z};
|
package/dist/chunk-CB4WEGVB.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as v}from"./chunk-CBDUXGVQ.js";import{spawn as x,execSync as b}from"child_process";import{existsSync as g}from"fs";import{resolve as e,dirname as h}from"path";import{fileURLToPath as N}from"url";import{createInterface as S}from"readline";async function*E(i){let n=S({input:i,crlfDelay:1/0});for await(let l of n){let r=l.trim();if(r)try{let d=JSON.parse(r);d&&typeof d.type=="string"&&(yield d)}catch{}}}function w(i){return i==="action"?{set:{V16_AGENT_ENABLE_ALL_BLOCKERS:"true"},unset:[]}:{set:{},unset:["V16_AGENT_ENABLE_ALL_BLOCKERS"]}}var c=h(N(import.meta.url));function O(){for(let i of["python3","python"])try{return b(`${i} --version`,{stdio:"ignore"}),i}catch{}return null}function C(){let n=process.platform==="win32"?"v16-runner.exe":"v16-runner",l={"darwin-arm64":["@testmuai/kane-cli-darwin-arm64","@lambdatestincprivate/kane-cli-darwin-arm64"],"darwin-x64":["@testmuai/kane-cli-darwin-x64","@lambdatestincprivate/kane-cli-darwin-x64"],"linux-x64":["@testmuai/kane-cli-linux-x64","@lambdatestincprivate/kane-cli-linux-x64"],"win32-x64":["@testmuai/kane-cli-win-x64","@lambdatestincprivate/kane-cli-win-x64"]},r=`${process.platform}-${process.arch}`,d=l[r];if(d)for(let t of d){let a=[e(c,"..","node_modules",t,"bin",n),e(c,"..","..","node_modules",t,"bin",n),e(c,"..","..","..","node_modules",t,"bin",n),e(c,"..","..","..","..","node_modules",t,"bin",n)];for(let u of a)if(g(u))return{cmd:u,args:[]}}let p=[e(c,"bin",n),e(c,"..","bin",n),e(c,"..","..","..","..","v16-runner","dist",n),e(c,"..","..","..","v16-runner","dist",n),e(process.cwd(),"v16-runner","dist",n),e(process.cwd(),"..","v16-runner","dist",n)];for(let t of p)if(g(t))return{cmd:t,args:[]};let s=[e(c,"..","..","..","..","v16-runner"),e(c,"..","..","..","v16-runner"),e(process.cwd(),"v16-runner"),e(process.cwd(),"..","v16-runner")];for(let t of s)if(g(e(t,"main.py"))){for(let u of[e(t,".venv","bin","python"),e(t,"..","browser-agent",".venv","bin","python")])if(g(u))return{cmd:u,args:["main.py"],cwd:t};let a=O();if(a)return{cmd:a,args:["main.py"],cwd:t}}return null}function G(i,n){let l=C();if(!l)throw new Error("v16-runner not found. Build the binary with `cd v16-runner && python build.py` or ensure Python is available.");let r={...process.env};n?.environment&&(r.TESTMUAI_ENV=n.environment),r.TESTMUAI_SOURCE="kane-cli",process.platform==="win32"&&(r.PYTHONIOENCODING="utf-8");let d=v(n?.environment);r.V16_SERVER_API_HOST=d.v16ServerHost,r.ATMS_URL=d.tmsBaseUrl.replace(/\/api\/?$/,""),i.username&&i.access_key&&(r.LT_USERNAME=i.username,r.LT_ACCESS_KEY=i.access_key),i.session_id&&(r.TESTMUAI_SESSION_ID=i.session_id);let p=w(n?.mode??"testing");Object.assign(r,p.set);for(let o of p.unset)delete r[o];let s=x(l.cmd,l.args,{stdio:["pipe","pipe","pipe"],env:r,cwd:l.cwd});s.stdin.on("error",()=>{}),s.stdin.write(JSON.stringify(i)+`
|
|
3
|
-
`);let t=1e5,a="";s.stderr.on("data",o=>{a+=o.toString(),a.length>t&&(a=a.slice(-t))}),s.on("error",o=>{n?.log?.("error","RUNNER_SPAWN_ERROR","Runner spawn error",{error:o.message})});let u=null,f=null,R=new Promise(o=>{s.on("close",(m,y)=>{u=m,f=y?String(y):null,n?.log?.("info","RUNNER_EXIT","Runner exited",{code:m,signal:f??"none"}),o({code:m,signal:f})})}),_=E(s.stdout);return{child:s,events:_,sendUserResponse(o){let m=JSON.stringify({type:"user_response",answer:o});try{s.stdin.write(m+`
|
|
4
|
-
`)}catch{}},sendCancel(o){let m=JSON.stringify({type:"cancel",reason:o});try{s.stdin.write(m+`
|
|
5
|
-
`)}catch{}},cancel(){s.kill("SIGTERM")},get stderr(){return a},get exitCode(){return u},get exitSignal(){return f},exited:R}}export{C as a,G as b};
|
package/dist/chunk-GCAHPH2E.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as o}from"./chunk-JI7KJKG4.js";import{a as c}from"./chunk-KKZRPFWO.js";import{a as n}from"./chunk-V7QXJKX7.js";var l=class{constructor(t,e,r,s){this.controllerBaseUrl=t;this.getOAuthToken=e;this.directBasicAuth=r;this.log=s}_cached=null;_revoked=!1;revoke(){this._revoked=!0,this._cached=null}get revoked(){return this._revoked}get cached(){return this._cached}async resolve(t=!1){if(this._cached&&!t)return this._cached;try{let e;if(this.directBasicAuth)e=new o(this.controllerBaseUrl,{username:this.directBasicAuth.username,accessKey:this.directBasicAuth.access_key});else{let s=await this.getOAuthToken();if(!s)return null;e=new o(this.controllerBaseUrl,s)}let r=await e.getTmsCredentials();return this.directBasicAuth&&!r.access_key&&(r.access_key=this.directBasicAuth.access_key),this._cached=r,this.log?.("info","AUTH_RESOLVE_OK","Auth resolved",{username:r.username,org_id:r.org_id,user_id:r.user_id}),r}catch(e){return this.log?.("warn","AUTH_RESOLVE_FAILED","Auth resolve failed",{error:e instanceof Error?e.message:String(e)}),null}}async fetch(t,e={}){if(this._revoked)throw new Error("Resolver has been revoked \u2014 identity changed");let r=await this.resolve();if(!r)throw new Error("Not authenticated \u2014 no credentials resolved");let s=i=>({...e,headers:{...e.headers,Authorization:c(i.username,i.access_key)}}),a=await n(t,s(r));if(a.status===401){if(this._revoked)throw new Error("Resolver has been revoked \u2014 identity changed");this.log?.("warn","AUTH_RESOLVE_401","Got 401, re-resolving",{url:t});let i=await this.resolve(!0);if(!i)throw new Error("Re-authentication failed after 401");return n(t,s(i))}return a}};export{l as a};
|
package/dist/chunk-HZUU7USC.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as u,g as p}from"./chunk-FOT6AMNP.js";import{a as f}from"./chunk-V7QXJKX7.js";var n=class{config;buffer=[];stepBuffer=new Map;flushTimer=null;currentRunIndex=null;stopped=!1;_droppedBatches=0;_droppedEntries=0;constructor(e){this.config=e}start(){if(this.flushTimer)return;let e=this.config.flushIntervalMs??5e3;this.flushTimer=setInterval(()=>{this.flush().catch(()=>{})},e),this.flushTimer.unref&&this.flushTimer.unref()}setRunIndex(e){this.currentRunIndex=e}log(e,t,i,s={}){if(this.stopped)return;let r=this.buildEntry(e,t,i,s);this.buffer.push(r)}logStep(e,t,i,s={}){if(this.stopped)return;let r=this.buildEntry("debug",t,i,s);r.run_index=e,this.stepBuffer.has(e)||this.stepBuffer.set(e,[]),this.stepBuffer.get(e).push(r)}escalate(e){let t=this.stepBuffer.get(e);t&&t.length>0&&this.buffer.push(...t),this.stepBuffer.delete(e)}discardSteps(e){this.stepBuffer.delete(e)}async flush(){if(this.buffer.length===0)return;let e=this.buffer.splice(0),t=null;try{t=await this.config.getToken()}catch{this.buffer.unshift(...e);return}let i={"Content-Type":"application/json"};t&&(i.Authorization=`Bearer ${t}`);let s=JSON.stringify(e);for(let r=0;r<3;r++){try{let h=new AbortController,d=setTimeout(()=>h.abort(),1e4),l=await f(this.config.proxyUrl,{method:"POST",headers:i,body:s,signal:h.signal});if(clearTimeout(d),l.ok)return}catch{}r<2&&await new Promise(h=>setTimeout(h,1e3*Math.pow(2,r)))}this._droppedBatches++,this._droppedEntries+=e.length}get droppedBatches(){return this._droppedBatches}get droppedEntries(){return this._droppedEntries}async shutdown(){this._droppedBatches>0&&this.log("warn","LOG_DROPS",`Dropped ${this._droppedEntries} entries in ${this._droppedBatches} batches`,{dropped_batches:this._droppedBatches,dropped_entries:this._droppedEntries}),this.stopped=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),await this.flush()}shutdownSync(){this.stopped=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}get bufferSize(){return this.buffer.length}stepBufferSize(e){return this.stepBuffer.get(e)?.length??0}buildEntry(e,t,i,s){return{hostname:"kane-cli",service:"kane-cli",ddsource:"kane-cli",ddtags:`version:${this.config.device.cli_version}`,level:e,event:t,message:i,session_id:this.config.sessionId,run_index:this.currentRunIndex,identity:this.config.identity,device:this.config.device,context:s,timestamp:new Date().toISOString()}}};import{platform as g,arch as a}from"os";function L(o){let e={proxyUrl:p,sessionId:o.sessionId,identity:o.identity,device:{cli_version:u,platform:g(),arch:a()},getToken:o.getToken};return new n(e)}export{n as a,L as b};
|
package/dist/chunk-IFWLAQ3L.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{execSync as c}from"child_process";import{readFileSync as o}from"fs";import{createHash as a}from"crypto";import{hostname as u,platform as f,arch as m}from"os";var t=null;function g(){return t||(t=s(),t)}function s(){let r=f();if(r==="darwin")try{let n=c("ioreg -rd1 -c IOPlatformExpertDevice",{encoding:"utf-8",timeout:5e3}).match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);if(n?.[1])return n[1]}catch{}if(r==="linux")try{let e=o("/etc/machine-id","utf-8").trim();if(e)return e}catch{}let i=`${u()}:${r}:${m()}`;return a("sha256").update(i).digest("hex").slice(0,32)}function x(){t=null}export{g as a,x as b};
|
package/dist/chunk-JI7KJKG4.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{b as a}from"./chunk-KKZRPFWO.js";import{a as s}from"./chunk-V7QXJKX7.js";var i=class extends a{constructor(e,r){super(e,r)}headers(){return{Authorization:this.authHeader,"Content-Type":"application/json"}}async getTmsCredentials(){let e=await s(`${this.baseUrl}/auth/tms-credentials`,{method:"GET",headers:this.headers()});if(!e.ok)throw new Error(`Credential exchange failed: ${e.status} ${await e.text()}`);return await e.json()}async getPresignedUrls(e,r,n){let t=await s(`${this.baseUrl}/upload/presign`,{method:"POST",headers:this.headers(),body:JSON.stringify({test_id:e,session_id:r,files:n})});if(!t.ok)throw new Error(`Presign request failed: ${t.status} ${await t.text()}`);return await t.json()}async getScreenshotSas(){let e=await s(`${this.baseUrl}/upload/screenshot-sas`,{method:"GET",headers:this.headers()});if(!e.ok)throw new Error(`Screenshot SAS request failed: ${e.status} ${await e.text()}`);return await e.json()}async getCreditBalance(){let e=await s(`${this.baseUrl}/credits/balance`,{method:"GET",headers:this.headers()});if(!e.ok)throw new Error(`Credit balance request failed: ${e.status} ${await e.text()}`);return await e.json()}};export{i as a};
|
package/dist/chunk-V7QXJKX7.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
var o=new Set(["UNABLE_TO_VERIFY_LEAF_SIGNATURE","UNABLE_TO_GET_ISSUER_CERT","UNABLE_TO_GET_ISSUER_CERT_LOCALLY","CERT_SIGNATURE_FAILURE","CERT_NOT_YET_VALID","CERT_HAS_EXPIRED","CERT_REVOKED","CERT_REJECTED","CERT_UNTRUSTED","DEPTH_ZERO_SELF_SIGNED_CERT","SELF_SIGNED_CERT_IN_CHAIN","CERT_CHAIN_TOO_LONG","PATH_LENGTH_EXCEEDED","ERR_TLS_CERT_ALTNAME_INVALID","HOSTNAME_MISMATCH","ERR_TLS_HANDSHAKE_TIMEOUT","ERR_SSL_WRONG_VERSION_NUMBER","ERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MAC"]),E="https://github.com/LambdaTest/kane-cli/blob/main/docs/user-guide/troubleshooting.md";function _(t){let e=t;for(let n=0;e&&n<5;n++){if(e instanceof Error&&"code"in e&&typeof e.code=="string"&&o.has(e.code))return e.code;if(e instanceof Error&&e.cause&&e.cause!==e)e=e.cause;else break}return null}function s(t){try{return typeof t=="string"?new URL(t).host:t instanceof URL?t.host:t instanceof Request?new URL(t.url).host:String(t)}catch{return String(t)}}function R(t,e){return[`TLS certificate verification failed (${t}) when connecting to ${s(e)}.`,"","Node uses its bundled Mozilla CA list and doesn't read the OS keychain by default,","so this usually shows up behind corporate endpoint security or TLS-inspecting proxies","where browsers and curl work but Node doesn't.","","Quickest fix \u2014 tell Node to also trust the system keychain (Node 22.19+ / 24.6+):"," export NODE_USE_SYSTEM_CA=1","","Or point at a CA bundle from your IT/security team:"," export NODE_EXTRA_CA_CERTS=/path/to/corp-ca.pem","",`Then re-run the command. Details: ${E}`].join(`
|
|
3
|
-
`)}async function i(t,e){try{return await fetch(t,e)}catch(n){let r=_(n);throw r?new Error(R(r,t),{cause:n}):n}}export{i as a};
|
package/dist/logging-M7EYIZTV.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a}from"./chunk-6JONCMIS.js";import"./chunk-PQLKQKQH.js";import"./chunk-CBDUXGVQ.js";import"./chunk-FOT6AMNP.js";import"./chunk-V7QXJKX7.js";import"./chunk-UR6MHSHU.js";export{a as LoginFlow};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a}from"./chunk-V7M72PLH.js";import"./chunk-MDBXYXSC.js";import"./chunk-JI7KJKG4.js";import"./chunk-LIJX5PIV.js";import"./chunk-KKZRPFWO.js";import"./chunk-V7QXJKX7.js";import"./chunk-UR6MHSHU.js";export{a as UploadPipeline};
|