@testmuai/kane-cli 0.3.2 → 0.3.3
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-ETBZA64A.js → ChromeProfilePicker-J6QIIHIE.js} +1 -1
- package/dist/{CliFeedbackPrompt-S7RZGMBQ.js → CliFeedbackPrompt-SEH4MXTF.js} +1 -1
- package/dist/{CliUploadProgress-TPWX5ARU.js → CliUploadProgress-U6QLD76Y.js} +1 -1
- package/dist/{ConfigView-BSIS2LOH.js → ConfigView-5ZCHVYM2.js} +1 -1
- package/dist/FolderPicker-VYJDEDN7.js +2 -0
- package/dist/{HelpView-MUIOT5UN.js → HelpView-3ESCWBPB.js} +1 -1
- package/dist/{InfoBox-3EY4ARJG.js → InfoBox-OVAOOQHC.js} +1 -1
- package/dist/{LinksBox-UD364LBX.js → LinksBox-P3VETMP6.js} +1 -1
- package/dist/{ProfilesView-UOJP2KA2.js → ProfilesView-UBVNEYVE.js} +1 -1
- package/dist/{ProjectPicker-5ZPZNRSS.js → ProjectPicker-NJKUWRET.js} +1 -1
- package/dist/{SaveSessionPrompt-D4PETK7B.js → SaveSessionPrompt-S5RCU5DX.js} +1 -1
- package/dist/SingleShotApp-WOJWOQSV.js +2 -0
- package/dist/{SummaryBox-L4ZXY4S4.js → SummaryBox-M4UFKKMD.js} +1 -1
- package/dist/{TestMdRunView-YD3Z6MCR.js → TestMdRunView-PI433EGP.js} +1 -1
- package/dist/{WhoamiView-ZZUFXKDU.js → WhoamiView-VJBEYTCF.js} +1 -1
- package/dist/{changelog-H2RXH4LH.js → changelog-EFAQANXW.js} +1 -1
- package/dist/{chunk-477FDDDW.js → chunk-4QLJMIBA.js} +1 -1
- package/dist/{chunk-BSHGW3QM.js → chunk-53K3BK7I.js} +1 -1
- package/dist/{chunk-E7QWDV7M.js → chunk-D4P6GLSX.js} +1 -1
- package/dist/{chunk-V4S5H6O2.js → chunk-FAPS5ACQ.js} +2 -2
- package/dist/{chunk-7JB4RPI2.js → chunk-FSIJOBVB.js} +1 -1
- package/dist/{chunk-FMMDLDDI.js → chunk-G5HHHYH7.js} +1 -1
- package/dist/{chunk-3YGQYJ3D.js → chunk-H33BV5YV.js} +1 -1
- package/dist/{chunk-PAQGYV5G.js → chunk-HNIH3GSQ.js} +1 -1
- package/dist/{chunk-MVX3N7GI.js → chunk-IROWNPDG.js} +1 -1
- package/dist/{chunk-ZB72T6HB.js → chunk-IXWVTWOR.js} +1 -1
- package/dist/{chunk-AH7HH3OE.js → chunk-J3SCNSXX.js} +1 -1
- package/dist/{chunk-7ECMUWV2.js → chunk-JPEICMHK.js} +1 -1
- package/dist/{chunk-EZJNX4VE.js → chunk-L3MOXBKE.js} +1 -1
- package/dist/{chunk-AMCAQCEV.js → chunk-N7YALZKA.js} +1 -1
- package/dist/{chunk-RVQBAKOK.js → chunk-NOQKUOEK.js} +1 -1
- package/dist/{chunk-KGZATJQN.js → chunk-PNQ5YMED.js} +1 -1
- package/dist/{chunk-3UDKGPAS.js → chunk-RHXWME7G.js} +1 -1
- package/dist/{chunk-OQ64GUQE.js → chunk-RURXFEOD.js} +1 -1
- package/dist/{chunk-HXIGYD2T.js → chunk-SR5UDUMJ.js} +1 -1
- package/dist/{chunk-XUDEM7I6.js → chunk-TEH6AVF4.js} +1 -1
- package/dist/{chunk-2FCAWRCU.js → chunk-TL4SB7MQ.js} +1 -1
- package/dist/{chunk-RBED7RVV.js → chunk-U4QMSR5Z.js} +1 -1
- package/dist/{chunk-O22K3JLR.js → chunk-WM6GZFTC.js} +1 -1
- package/dist/{chunk-WCRLZETG.js → chunk-XM4H4TJD.js} +1 -1
- package/dist/{chunk-RDJPZQBU.js → chunk-YF4OL463.js} +1 -1
- package/dist/{chunk-XK33C64U.js → chunk-YVLFHMUW.js} +1 -1
- package/dist/{chunk-4GQZBMTW.js → chunk-ZYVYAIBS.js} +1 -1
- package/dist/index.js +7 -7
- package/dist/{logging-RMC6R23F.js → logging-AIQHWRNQ.js} +1 -1
- package/dist/{login-flow-NL3LNSP5.js → login-flow-E6WMJ25A.js} +1 -1
- package/dist/{persist-recorded-session-GG732QRB.js → persist-recorded-session-V5DXMRKC.js} +1 -1
- package/dist/{recording-banner-LAAAMKIM.js → recording-banner-7ZKIORL5.js} +1 -1
- package/dist/run-test-md-BQS5SZ7E.js +65 -0
- package/dist/{testmd-actions-5O7F22EC.js → testmd-actions-322GQYAH.js} +2 -2
- package/dist/{validate-basic-NIEIKFGP.js → validate-basic-XKTSGLFO.js} +1 -1
- package/dist/{version-check-WHWTPX6C.js → version-check-LUCKH72U.js} +1 -1
- package/package.json +5 -5
- package/dist/FolderPicker-7FXP3PIM.js +0 -2
- package/dist/SingleShotApp-N4AGSAPW.js +0 -2
- package/dist/run-test-md-IAEJXIVK.js +0 -65
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
3
|
-
import{a as Eo,b as Sr}from"./chunk-3MSXQU2C.js";import{a as Hr}from"./chunk-
|
|
3
|
+
import{a as Eo,b as Sr}from"./chunk-3MSXQU2C.js";import{a as Hr}from"./chunk-RHXWME7G.js";import{a as Pn,b as On,c as Dn,d as Mn,e as an,f as Nt,g as Gr}from"./chunk-U4QMSR5Z.js";import{a as Hn,b as Ur,c as Ao}from"./chunk-RURXFEOD.js";import{a as So}from"./chunk-XM4H4TJD.js";import{a as on,b as rn,c as jr,d as Fn,e as Br,f as Nn,g as Mt,h as At,i as ln,j as Un,k as Wn,o as qn,p as Kn,q as Gn,r as zn,v as cn,w as dn,x as Xn,y as Xr,z as Do}from"./chunk-4QLJMIBA.js";import{b as $r}from"./chunk-L3MOXBKE.js";import{a as Pr,b as zr,c as Oo,d as Jr}from"./chunk-G5HHHYH7.js";import{a as Mr}from"./chunk-UFNKCPUB.js";import"./chunk-MDBXYXSC.js";import{a as Io}from"./chunk-J3SCNSXX.js";import{a as Wr,b as Po}from"./chunk-ZYVYAIBS.js";import"./chunk-S3DAAAE5.js";import"./chunk-X7VI7KK3.js";import"./chunk-AH4AXJML.js";import{a as qr,d as Jn}from"./chunk-FSIJOBVB.js";import{a as kr,b as Rr,c as jn,d as Vr,e as Lr,f as Kr}from"./chunk-FAPS5ACQ.js";import{a as nn}from"./chunk-N7YALZKA.js";import{a as Ln,d as nt,e as Rt,f as q,g as sn,h as Ro,i as Dr}from"./chunk-G7VF5SDK.js";import"./chunk-L5LI2JF4.js";import{a as Be}from"./chunk-PNQ5YMED.js";import{b as Lt}from"./chunk-53K3BK7I.js";import{b as Ft}from"./chunk-YF4OL463.js";import"./chunk-YCCUBQY4.js";import"./chunk-JPEICMHK.js";import{a as Te,b as he,c as Bn,d as Ar}from"./chunk-VE3SUJMA.js";import{a as $n}from"./chunk-WM6GZFTC.js";import{a as Le,b as Ir}from"./chunk-IXWVTWOR.js";import{a as me}from"./chunk-HNIH3GSQ.js";import{a as Vn}from"./chunk-GCAHPH2E.js";import{a as Or}from"./chunk-JI7KJKG4.js";import{b as Fr}from"./chunk-H33BV5YV.js";import{a as Nr}from"./chunk-IFWLAQ3L.js";import"./chunk-E47GFYXA.js";import{a as Tr}from"./chunk-IROWNPDG.js";import"./chunk-SR5UDUMJ.js";import{b as ko}from"./chunk-NOQKUOEK.js";import{c as To}from"./chunk-TEH6AVF4.js";import{a as $t}from"./chunk-YVLFHMUW.js";import{a as X}from"./chunk-HCBYKLMW.js";import{a as st,c as xe,h as at,t as g}from"./chunk-TL4SB7MQ.js";import{a as b,b as l,c as tn,d as An,i as He,j as In,k as Er}from"./chunk-C44QQJR4.js";import{a as Ye}from"./chunk-6YGTRKDT.js";import{a as Vt}from"./chunk-YZTCCQHR.js";import"./chunk-KKZRPFWO.js";import"./chunk-V7QXJKX7.js";import{a as en,c as Tt,e as H}from"./chunk-UR6MHSHU.js";var vn=Tt(Xo=>{"use strict";var so=class extends Error{constructor(e,t,n){super(n),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=t,this.exitCode=e,this.nestedError=void 0}},zo=class extends so{constructor(e){super(1,"commander.invalidArgument",e),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}};Xo.CommanderError=so;Xo.InvalidArgumentError=zo});var ao=Tt(Yo=>{"use strict";var{InvalidArgumentError:Ss}=vn(),Jo=class{constructor(e,t){switch(this.description=t||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,e[0]){case"<":this.required=!0,this._name=e.slice(1,-1);break;case"[":this.required=!1,this._name=e.slice(1,-1);break;default:this.required=!0,this._name=e;break}this._name.length>3&&this._name.slice(-3)==="..."&&(this.variadic=!0,this._name=this._name.slice(0,-3))}name(){return this._name}_concatValue(e,t){return t===this.defaultValue||!Array.isArray(t)?[e]:t.concat(e)}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}argParser(e){return this.parseArg=e,this}choices(e){return this.argChoices=e.slice(),this.parseArg=(t,n)=>{if(!this.argChoices.includes(t))throw new Ss(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._concatValue(t,n):t},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}};function ks(a){let e=a.name()+(a.variadic===!0?"...":"");return a.required?"<"+e+">":"["+e+"]"}Yo.Argument=Jo;Yo.humanReadableArgName=ks});var Zo=Tt(xi=>{"use strict";var{humanReadableArgName:Ts}=ao(),Qo=class{constructor(){this.helpWidth=void 0,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}visibleCommands(e){let t=e.commands.filter(o=>!o._hidden),n=e._getHelpCommand();return n&&!n._hidden&&t.push(n),this.sortSubcommands&&t.sort((o,r)=>o.name().localeCompare(r.name())),t}compareOptions(e,t){let n=o=>o.short?o.short.replace(/^-/,""):o.long.replace(/^--/,"");return n(e).localeCompare(n(t))}visibleOptions(e){let t=e.options.filter(o=>!o.hidden),n=e._getHelpOption();if(n&&!n.hidden){let o=n.short&&e._findOption(n.short),r=n.long&&e._findOption(n.long);!o&&!r?t.push(n):n.long&&!r?t.push(e.createOption(n.long,n.description)):n.short&&!o&&t.push(e.createOption(n.short,n.description))}return this.sortOptions&&t.sort(this.compareOptions),t}visibleGlobalOptions(e){if(!this.showGlobalOptions)return[];let t=[];for(let n=e.parent;n;n=n.parent){let o=n.options.filter(r=>!r.hidden);t.push(...o)}return this.sortOptions&&t.sort(this.compareOptions),t}visibleArguments(e){return e._argsDescription&&e.registeredArguments.forEach(t=>{t.description=t.description||e._argsDescription[t.name()]||""}),e.registeredArguments.find(t=>t.description)?e.registeredArguments:[]}subcommandTerm(e){let t=e.registeredArguments.map(n=>Ts(n)).join(" ");return e._name+(e._aliases[0]?"|"+e._aliases[0]:"")+(e.options.length?" [options]":"")+(t?" "+t:"")}optionTerm(e){return e.flags}argumentTerm(e){return e.name()}longestSubcommandTermLength(e,t){return t.visibleCommands(e).reduce((n,o)=>Math.max(n,t.subcommandTerm(o).length),0)}longestOptionTermLength(e,t){return t.visibleOptions(e).reduce((n,o)=>Math.max(n,t.optionTerm(o).length),0)}longestGlobalOptionTermLength(e,t){return t.visibleGlobalOptions(e).reduce((n,o)=>Math.max(n,t.optionTerm(o).length),0)}longestArgumentTermLength(e,t){return t.visibleArguments(e).reduce((n,o)=>Math.max(n,t.argumentTerm(o).length),0)}commandUsage(e){let t=e._name;e._aliases[0]&&(t=t+"|"+e._aliases[0]);let n="";for(let o=e.parent;o;o=o.parent)n=o.name()+" "+n;return n+t+" "+e.usage()}commandDescription(e){return e.description()}subcommandDescription(e){return e.summary()||e.description()}optionDescription(e){let t=[];return e.argChoices&&t.push(`choices: ${e.argChoices.map(n=>JSON.stringify(n)).join(", ")}`),e.defaultValue!==void 0&&(e.required||e.optional||e.isBoolean()&&typeof e.defaultValue=="boolean")&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),e.presetArg!==void 0&&e.optional&&t.push(`preset: ${JSON.stringify(e.presetArg)}`),e.envVar!==void 0&&t.push(`env: ${e.envVar}`),t.length>0?`${e.description} (${t.join(", ")})`:e.description}argumentDescription(e){let t=[];if(e.argChoices&&t.push(`choices: ${e.argChoices.map(n=>JSON.stringify(n)).join(", ")}`),e.defaultValue!==void 0&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),t.length>0){let n=`(${t.join(", ")})`;return e.description?`${e.description} ${n}`:n}return e.description}formatHelp(e,t){let n=t.padWidth(e,t),o=t.helpWidth||80,r=2,s=2;function m(h,T){if(T){let V=`${h.padEnd(n+s)}${T}`;return t.wrap(V,o-r,n+s)}return h}function d(h){return h.join(`
|
|
4
4
|
`).replace(/^/gm," ".repeat(r))}let u=[`Usage: ${t.commandUsage(e)}`,""],i=t.commandDescription(e);i.length>0&&(u=u.concat([t.wrap(i,o,0),""]));let c=t.visibleArguments(e).map(h=>m(t.argumentTerm(h),t.argumentDescription(h)));c.length>0&&(u=u.concat(["Arguments:",d(c),""]));let _=t.visibleOptions(e).map(h=>m(t.optionTerm(h),t.optionDescription(h)));if(_.length>0&&(u=u.concat(["Options:",d(_),""])),this.showGlobalOptions){let h=t.visibleGlobalOptions(e).map(T=>m(t.optionTerm(T),t.optionDescription(T)));h.length>0&&(u=u.concat(["Global Options:",d(h),""]))}let P=t.visibleCommands(e).map(h=>m(t.subcommandTerm(h),t.subcommandDescription(h)));return P.length>0&&(u=u.concat(["Commands:",d(P),""])),u.join(`
|
|
5
5
|
`)}padWidth(e,t){return Math.max(t.longestOptionTermLength(e,t),t.longestGlobalOptionTermLength(e,t),t.longestSubcommandTermLength(e,t),t.longestArgumentTermLength(e,t))}wrap(e,t,n,o=40){let r=" \\f\\t\\v\xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF",s=new RegExp(`[\\n][${r}]+`);if(e.match(s))return e;let m=t-n;if(m<o)return e;let d=e.slice(0,n),u=e.slice(n).replace(`\r
|
|
6
6
|
`,`
|
|
@@ -25,10 +25,10 @@ Expecting one of '${n.join("', '")}'`);let o=`${e}Help`;return this.on(o,r=>{let
|
|
|
25
25
|
`)})}}},[$.bifurcationInfo,i,ce]);let ho=k.default.useRef(null),vo=k.default.useRef(0),wo=k.default.useRef(0);(0,k.useEffect)(()=>{if($.lastRunEnd&&$.lastRunEnd!==ho.current){ho.current=$.lastRunEnd;let{status:p,duration:v,summary:f,reason:w,context:S}=$.lastRunEnd,{passed:O,failed:B,total:F}=an($.steps);vo.current+=F,wo.current+=v??0,qe({status:p,duration:v??0,summary:f??"",stepsPassed:O,stepsFailed:B,stepsTotal:F,reason:w,finalState:$.lastRunEnd?.final_state,creditsConsumed:$.lastRunEnd?.credits_consumed}),i.logRunEnd(Me.current,p,v,f);let U=$.bifurcationInfo,J=U&&!U.isSingleFlow?U.flows:null,de=on($.lastRunEnd,Me.current,J),je=rn($.lastRunEnd,yt.current,Me.current,de);i.addRunResult(je,$.lastRunEnd?.total_runs);let pt=$.lastRunEnd?.per_flow_metadata;if(U&&!U.isSingleFlow&&pt&&pt.length>1)for(let ze=0;ze<pt.length;ze++){let jt=pt[ze],Zt=$.steps[ze],Bt=Zt?.children??[],Rn=Bt.filter(kt=>kt.status==="passed").length,fe=Bt.filter(kt=>kt.status==="failed").length,Xe=Bt.reduce((kt,Co)=>kt+(Co.duration??0),0),Je=Zt?.status==="failed"?"failed":"passed",tt=U.flows[ze]??Zt?.objective??yt.current;i.addFlow({runIndex:Me.current,flowId:U.flows[ze],objective:tt,status:Je,summary:jt.summary??"",duration:Xe,steps:Rn+fe,stepsPassed:Rn,stepsFailed:fe,reason:jt.error_message??void 0,creditsConsumed:jt.credits_consumed??void 0})}else i.addFlow({runIndex:Me.current,objective:yt.current,status:p,summary:f??"",duration:v??0,steps:F,stepsPassed:O,stepsFailed:B,reason:w,creditsConsumed:$.lastRunEnd?.credits_consumed})}},[$.lastRunEnd,i,ce]);let xo=(0,k.useRef)(null);(0,k.useEffect)(()=>{$.askingUser&&(xo.current=$.askingUser)},[$.askingUser]);let bo=(0,k.useRef)(null);(0,k.useEffect)(()=>{if(Ee&&!$.isRunning&&$.lastRunEnd){if(bo.current===$.lastRunEnd)return;bo.current=$.lastRunEnd,Q((0,y.jsxs)(b,{flexDirection:"column",children:[(0,y.jsx)(gi,{status:Ee.status,steps:Ee.stepsTotal,duration:Ee.duration,creditsConsumed:Ee.creditsConsumed,reason:Ee.reason}),(0,y.jsx)(hi,{})]})),qe(null)}},[Ee,$.isRunning,$.lastRunEnd,Q]),(0,k.useEffect)(()=>{M.current?.setRunActive($.isRunning)},[$.isRunning]),(0,k.useEffect)(()=>{if($.runError&&!$.isRunning){let p=$.runError.trim();i.log("error","RUNNER_ERROR","Runner error occurred",{error:p}),i.escalateRun(i.nextRunIndex()-1);let f=p.split(`
|
|
26
26
|
`).slice(-8).join(`
|
|
27
27
|
`);ce({type:"error",text:`Runner error:
|
|
28
|
-
${f}`})}},[$.runError,$.isRunning,ce,i]);let En=(0,k.useCallback)(async()=>{i.log("info","EXIT_UPLOAD_START","Starting exit upload pipeline"),Kt(Hn()),xt({status:"uploading"});let p=x.getResolvedBasicAuth(),v=null;if(!p&&(v=await x.getToken(),!v))return i.log("warn","EXIT_UPLOAD_ABORTED","Exit upload aborted \u2014 no auth available"),null;let f=Ze??await Et();if(!f)return i.log("warn","EXIT_UPLOAD_ABORTED","Exit upload aborted \u2014 no TMS credentials"),i.setUploadStatus("failed","Could not get TMS credentials"),null;i.log("info","EXIT_UPLOAD_CONFIG","Exit upload configuration",{test_id:i.testId,commit_id:i.sessionId,project_id:I.project_id,session_dir:i.sessionDir,run_dirs:i.getRunDirs()});let w={basicAuth:p??null,token:v,resolver:x.getResolver(),resolvedCreds:f};it.current&&(i.log("info","SCREENSHOT_UPLOAD_DRAIN","Draining screenshot queue before pipeline"),await it.current.drain(),i.log("info","SCREENSHOT_UPLOAD_DRAINED","Screenshot queue drained"));let S=cn({session:i,env:le,auth:w,variables:Ct.current??{raw:{},auteur:{},auteurObjective:"",secretEntries:[],nonSecretEntries:[]},variableIds:D.current,projectId:I.project_id,folderId:I.folder_id,totalSteps:vo.current,totalDuration:wo.current,codeExport:dn({codeExport:e,codeLanguage:t,skipCodeValidation:n},I.code_export),onProgress:(F,U,J)=>{i.log("info","EXIT_PROGRESS","Upload progress",{step:F,status:U,detail:J}),Kt(de=>Ur(de,F,U,J))},log:(F,U,J,de)=>i.log(F,U,J,de),shouldUploadArtifacts:!0,shouldReplaceLocalOutput:!1,shouldCommit:!1,isFirstRun:!0}),B=await new Mr(S).execute();if(B.success){i.log("info","EXIT_UPLOAD_OK","Exit upload succeeded",{test_id:B.testId,testcase_id:B.testcaseId??null,share_id:B.shareId??null}),i.setUploadStatus("uploaded"),B.testId&&i.setTestId(B.testId),B.testcaseId&&i.setTestcaseId(B.testcaseId);let F=me(le),U=I.project_id,J=B.testcaseId&&B.shareId&&U?At(F.testManagerUiUrl,U,B.testcaseId,B.shareId):void 0,de=B.testcaseId&&U?ln(F.testManagerUiUrl,U,B.testcaseId):void 0;xt({status:"success",testUrl:J,testCaseLink:de,codeExportDir:B.codeExportDir}),pi({shareableLink:J,testCaseLink:de,codeExportDir:B.codeExportDir})}else i.log("error","EXIT_UPLOAD_FAILED","Exit upload failed",{error:B.error}),i.setUploadStatus("failed",B.error),xt({status:"failed",error:B.error});return B},[x,le,i,I,Ze,Et]),Sn=(0,k.useCallback)(async()=>{i.log("info","SESSION_RESET_START","Starting session reset via /new"),L(!0);let p=i.getFlows();p.length>0&&Q((0,y.jsx)(Go,{flows:p}));let v=null;if(!a)try{v=await En()??null}catch(S){i.log("error","SESSION_RESET_UPLOAD_FAILED","Upload failed during /new",{error:String(S)}),ce({type:"error",text:"Upload failed \u2014 session data saved locally."})}let f=null;try{let{persistRecordedSession:S}=await import("./persist-recorded-session-GG732QRB.js");f=S(i,{testcaseId:i.testcaseId??void 0,projectId:I.project_id??void 0,folderId:I.folder_id??void 0,codeExportDir:v?.codeExportDir})}catch(S){i.log("error","SESSION_RESET_PERSIST_FAILED","Persist failed during /new",{error:String(S)})}if(v?.success&&v.testcaseId||f){let S=me(le),O=I.project_id,B=v?.testcaseId;Q((0,y.jsx)(Io,{recordedTestPath:f?.recordedTestPath,outputDir:f?.outputDir,shareableLink:B&&v?.shareId&&O?At(S.testManagerUiUrl,O,B,v.shareId):void 0,testCaseLink:B&&O?ln(S.testManagerUiUrl,O,B):void 0,codeExportDir:v?.codeExportDir,autoExit:!1}))}i.testId&&Ie(S=>[...S,{testId:i.testId,runCount:j}]),Cn.killChrome(),await i.finish("complete");let w=new nn;w.start({model:I.model,environment:le,profile:Dt??null}),m.current=w,u(S=>S+1),i.log("info","SESSION_RESET_COMPLETE","Session reset complete",{new_session_id:w.sessionId}),W(0),vo.current=0,wo.current=0,Me.current=0,yt.current="",Ct.current=null,D.current={},it.current=null,Tn.current=0,yo.current=0,xo.current=null,bo.current=null,ho.current=null,go.current=null,qe(null),A(null),xt(null),Kt(Hn()),L(!1),Q((0,y.jsxs)(b,{flexDirection:"column",marginY:1,children:[(0,y.jsx)(l,{color:g.dimmed,children:"\u2500".repeat(44)}),(0,y.jsx)(l,{color:g.green,bold:!0,children:"New session started"})]}))},[i,ce,Q,a,En,Cn,j,I,le,Dt]),br=(0,k.useCallback)(async()=>{if(!(i.nextRunIndex()>0)){ce({type:"info",text:"No runs in current session."});return}if($.isRunning){ce({type:"error",text:"Cannot reset while a run is in progress. Cancel the run first."});return}if(I.mode==="testing"&&!i.sessionName){pe("new"),Ke(Po());return}await Sn()},[i,$,ce,I.mode,Sn]),_r=(0,k.useCallback)(async()=>{await i.finish("complete"),q(0,"Session complete")},[i]),Qi=(0,k.useCallback)(async p=>{Gt(!1);let v=i.testId??(we.length>0?we[we.length-1].testId:null);if(p&&v){i.log("info","EXIT_FEEDBACK_SUBMIT","Submitting session feedback",{choice:p});try{let f=me(le),w=x.getResolvedBasicAuth();w&&await io({tmsBaseUrl:f.tmsBaseUrl,username:w.username,accessKey:w.access_key,testId:v,feedbackType:p,log:(S,O,B,F)=>i.log(S,O,B,F)})}catch(f){i.log("error","EXIT_FEEDBACK_FAILED","Feedback submission failed",{error:String(f)})}}else i.log("info","EXIT_FEEDBACK_SKIPPED","Feedback skipped");_r()},[le,x,i,_r,we]),kn=(0,k.useCallback)(async()=>{let p=i.nextRunIndex()>0,v=null;if(p&&!a){i.log("info","EXIT_WITH_ACTIVE_SESSION","Exit with active session \u2014 uploading first"),Ae(!0);try{v=await En()??null}catch(w){i.log("error","EXIT_UPLOAD_FAILED","Exit upload failed",{error:String(w)})}i.testId&&Ie(w=>[...w,{testId:i.testId,runCount:j}])}try{let{persistRecordedSession:w}=await import("./persist-recorded-session-GG732QRB.js"),S=w(i,{testcaseId:i.testcaseId??void 0,projectId:I.project_id??void 0,folderId:I.folder_id??void 0,codeExportDir:v?.codeExportDir});S&&Xt(S)}catch(w){i.log("error","EXIT_PERSIST_FAILED","Persist failed during /exit",{error:String(w)})}if(p&&!a&&await i.finish("complete"),!(i.testId??(we.length>0?we[we.length-1].testId:null))||a){await i.finish("complete"),q(0,"No test ID \u2014 quick exit");return}Ae(!0),Gt(!0)},[i,a,En,j,we,I]),St=(0,k.useCallback)(async()=>{if(re)return;i.log("info","EXIT_START","TUI exit initiated");let p=I.mode==="testing",v=i.nextRunIndex()>0;if(p&&v&&!i.sessionName){pe("exit"),Ke(Po());return}await kn()},[re,i,I.mode,kn]),Zi=(0,k.useCallback)(p=>{p&&i.setSessionName(p);let v=zt;Ke(null),pe(null),v==="new"?Sn():kn()},[i,zt,kn,Sn]);(0,k.useEffect)(()=>{if(!re)return;let p=300*1e3,v=setTimeout(async()=>{i.setUploadStatus("failed","Upload timed out after 5m"),await i.finish("complete"),q(0,"Upload timed out after 5m")},p);return()=>clearTimeout(v)},[re,i]);let Tn=k.default.useRef(0),_o=k.default.useRef(null),yo=k.default.useRef(0);He((p,v)=>{if(v.ctrl&&p==="c"){if(re){yo.current+=1,yo.current>=2&&(i.setUploadStatus("pending","Force exit by user"),i.finish("complete"),q(0,"Force exit by user"));return}if($.isRunning){$.cancelRun(),ce({type:"info",text:"Run cancelled."}),Tn.current++,_o.current&&clearTimeout(_o.current),_o.current=setTimeout(()=>{Tn.current=0},2e3),Tn.current>=2&&St();return}St()}});let yr=k.default.useMemo(()=>{let p=x.creds.getActiveProfile()??"none",v=x.creds.getDefaultEnv();return[{id:"run",label:"Run",type:"submenu",children:[{id:"run-start",label:"Start Run",type:"action"},{id:"run-config",label:"Run Config",type:"submenu",children:[{id:"run-headless",label:"Headless",type:"select",currentValue:Z.headless?"on":"off",options:[{label:"off",value:"off"},{label:"on",value:"on"}],onValue:f=>{Qt(w=>({...w,headless:f==="on"}))}},{id:"run-max-steps",label:"Max Steps",type:"text-input",currentValue:String(Z.maxSteps),onValue:f=>{let w=parseInt(f,10);w>0&&Qt(S=>({...S,maxSteps:w}))}},{id:"run-timeout",label:"Timeout (sec)",type:"text-input",currentValue:Z.timeout?String(Z.timeout):"",placeholder:"0 = no timeout",onValue:f=>{let w=parseInt(f,10);Qt(S=>({...S,timeout:isNaN(w)?0:w}))}},{id:"run-cdp",label:"CDP Endpoint",type:"text-input",currentValue:Z.cdpEndpoint,placeholder:"http://127.0.0.1:9222",onValue:f=>{Qt(w=>({...w,cdpEndpoint:f}))}},{id:"run-ws",label:"WS Endpoint",type:"text-input",currentValue:Z.wsEndpoint,placeholder:"wss://...",onValue:f=>{Qt(w=>({...w,wsEndpoint:f}))}}]}]},{id:"auth",label:"Auth",type:"submenu",children:[{id:"login",label:"Login",type:"action",onLoginWizard:()=>{}},{id:"logout",label:"Logout",type:"action",onAction:()=>{x.logout().then(f=>{Ve();let w=x.creds.getActiveProfile(),S=x.creds.getDefaultEnv();et(w,S),mt().catch(()=>{}),f?K("ok","/logout",`Logged out: ${f.profile} [${f.env}]`):K("ok","/logout","No active profile")}).catch(()=>{K("error","/logout","Logout failed")})}},{id:"whoami",label:"Who Am I",type:"action",onInfo:()=>{let f=x.creds.getActiveProfile()??"none",w=x.creds.getDefaultEnv(),S=x.creds.loadBasicAuth(f,w),O=S?"basic":x.creds.loadCredentials(f,w)?"oauth":"not configured";return{title:"Who Am I",sections:[{label:"Identity",entries:[{key:"Profile",value:f},{key:"Environment",value:w}]},{label:"Authentication",entries:[{key:"Method",value:O},...S?[{key:"Username",value:S.username}]:[]]},{label:"Token",entries:[{key:"Status",value:x.tokenValid?"valid":"not logged in",color:x.tokenValid?g.statusPass:g.statusFail}]}]}}},{id:"balance",label:"Credit Balance",type:"action",suppressFeedback:!0,onAction:()=>{(async()=>{let f=x.creds.getActiveProfile()??"default",w=x.creds.getDefaultEnv(),S=me(w);try{let O=x.getBasicAuth(),B=O?null:await x.getToken();if(!O&&!B){ie({text:"Not authenticated. Run /login first.",color:g.red});return}let{ControllerClient:F}=await import("./controller-client-OMKEBP4B.js"),J=await(O?new F(S.controllerBaseUrl,{username:O.username,accessKey:O.access_key}):new F(S.controllerBaseUrl,B)).getCreditBalance();ie({text:`Credits \u2014 available: ${J.available_credits}, total: ${J.total_credits} (${f} / ${w})`,color:g.green})}catch(O){ie({text:`Balance check failed: ${O instanceof Error?O.message:String(O)}`,color:g.red})}Qe.current&&clearTimeout(Qe.current),Qe.current=setTimeout(()=>{ie(null),Qe.current=null},5e3)})()}},{id:"profiles",label:"Profiles",type:"action",onProfilesView:()=>{}}]},{id:"config",label:"Config",type:"submenu",children:[{id:"config-show",label:"Show",type:"action",onInfo:()=>({title:"Show Config",sections:[{label:"General",entries:[{key:"Model",value:"v16-alpha"},{key:"Mode",value:I.mode}]},{label:"Browser",entries:[{key:"Window",value:`${I.window_size.width}x${I.window_size.height}`},{key:"Chrome Profile",value:I.chrome_profile_path?I.chrome_profile_path.split("/").pop()??I.chrome_profile_path:"(temporary)"}]},{label:"Project",entries:[{key:"Project",value:I.project_name?`${I.project_name} (${I.project_id})`:I.project_id??"(none)"},{key:"Folder",value:I.folder_name?`${I.folder_name} (${I.folder_id})`:I.folder_id??"(none)"},{key:"Default URL",value:at}]},{label:"Code Export",entries:[{key:"Enabled",value:I.code_export.enabled?"yes":"no"},{key:"Language",value:I.code_export.language},{key:"Skip Validation",value:I.code_export.skip_validation?"yes":"no"}]}]})},{id:"config-chrome",label:"Chrome Profile",type:"action",onChromeProfilePicker:()=>{}},{id:"config-project",label:"Project",type:"action",onProjectPicker:()=>{}},{id:"config-folder",label:"Folder",type:"action",...I.project_id?{onFolderPicker:()=>{}}:{onInfo:()=>({title:"Folder",sections:[{entries:[{key:"Status",value:"Select a project first",color:g.dim}]}]})}},{id:"config-window",label:"Window Size",type:"action",currentValue:`${I.window_size.width}x${I.window_size.height}`,onWindowSizePicker:()=>{}},{id:"config-mode",label:"Mode",type:"select",currentValue:I.mode,options:[{label:"testing",value:"testing"},{label:"action",value:"action"}],onValue:f=>{(f==="action"||f==="testing")&&(c.set("mode",f),De(c.load()),K("ok","/config set-mode",f))}},{id:"config-code-export",label:"Code Export",type:"submenu",currentValue:I.code_export.enabled?"enabled":"disabled",children:[{id:"config-code-export-enabled",label:"Enabled",type:"select",currentValue:I.code_export.enabled?"on":"off",options:[{label:"off",value:"off"},{label:"on",value:"on"}],onValue:f=>{c.set("code_export",{...I.code_export,enabled:f==="on"}),De(c.load()),K("ok","/config code-export enabled",f)}},{id:"config-code-export-language",label:"Language",type:"select",currentValue:I.code_export.language,options:[{label:"python",value:"python"},{label:"javascript",value:"javascript"}],onValue:f=>{f!=="python"&&f!=="javascript"||(c.set("code_export",{...I.code_export,language:f}),De(c.load()),K("ok","/config code-export language",f))}},{id:"config-code-export-skip-validation",label:"Skip Validation",type:"select",currentValue:I.code_export.skip_validation?"on":"off",options:[{label:"off",value:"off"},{label:"on",value:"on"}],onValue:f=>{c.set("code_export",{...I.code_export,skip_validation:f==="on"}),De(c.load()),K("ok","/config code-export skip-validation",f)}}]}]},{id:"exit",label:"Exit",type:"action",onAction:()=>{St()}}]},[x,c,I,ce,St,Z,Ve,K]),es=(0,k.useCallback)(p=>{if($.askingUser){let f=$.askingUser;Q((0,y.jsxs)(b,{flexDirection:"column",marginLeft:2,paddingLeft:1,marginTop:1,children:[(0,y.jsx)(b,{marginLeft:1,children:(0,y.jsx)(l,{color:g.primary,bold:!0,children:"Agent Question"})}),(0,y.jsxs)(b,{borderStyle:"round",borderColor:g.primary,flexDirection:"column",paddingX:2,paddingY:1,width:70,children:[(0,y.jsxs)(b,{children:[(0,y.jsx)(b,{width:3,children:(0,y.jsx)(l,{color:g.primary,bold:!0,children:"?"})}),(0,y.jsx)(b,{flexShrink:1,children:(0,y.jsx)(l,{wrap:"wrap",children:f})})]}),(0,y.jsxs)(b,{marginTop:1,children:[(0,y.jsx)(b,{width:3,children:(0,y.jsx)(l,{color:g.dim,bold:!0,children:"\u2192"})}),(0,y.jsx)(b,{flexShrink:1,children:(0,y.jsx)(l,{color:g.accent,wrap:"wrap",children:p})})]})]})]})),xo.current=null,$.sendAnswer(p);return}if(i.logCommand(p),$.isRunning){ce({type:"error",text:"Run in progress. Ctrl+C to cancel."});return}let v=ci(p);if(v)switch(v.command){case"login":case"logout":case"whoami":case"profiles":case"balance":case"auth":Ot("auth");return;case"config":Ot("config");return;case"help":pr(!0);return;case"update":{(async()=>{let{getUpdateCommand:f}=await import("./version-check-WHWTPX6C.js");K("ok","/update",`To update kane-cli, run: ${f()}`)})();return}case"summary":{let f=i.getFlows();if(f.length===0){K("ok","/summary","No runs yet in this session.");return}let w=v.args.index?parseInt(v.args.index,10):void 0;if(w!==void 0&&!i.getFlow(w)){K("error","/summary",`No flow at index ${w}`,`${f.length} flow${f.length===1?"":"s"} available. Use /summary to see all.`);return}Q((0,y.jsx)(Go,{flows:f,filterIndex:w})),K("ok","/summary",w!==void 0?`Flow ${w}`:`${f.length} flow${f.length===1?"":"s"}`);return}case"new":br(),K("ok","/new","Session reset");return;case"name":{let f=v.raw.replace(/^\/name\s*/,"").trim();if(!f){K("error","/name","Usage: /name <new-name>");return}(async()=>{let{validateNameOrThrow:w}=await import("./name-validator-5YGJXLZ7.js");try{w(f),i.setSessionName(f),K("ok","/name",`Session name set: ${f}`)}catch(S){K("error","/name",S.message)}})();return}case"cancel":$.cancelRun(),K("ok","/cancel","Run cancelled");return;case"clear":K("ok","/clear","Chat cleared");return;case"exit":St();return;default:K("error",`/${v.command}`,"Unknown command");return}if(p.trim().toLowerCase()==="exit"){St();return}Q((0,y.jsxs)(b,{children:[(0,y.jsx)(l,{color:"#b388ff",children:"\u276F "}),(0,y.jsx)(l,{children:p})]})),xr(p,at)},[$,ce,K,Q,i,xr,St,br]),Cr=x.getAuthInfo(),ts=Cr?Cr.method==="basic"?"basic auth":"oauth":"not logged in",ns=(()=>{if(yn)return["help"];if(R)return R.phase==="wizard"?["auth","login"]:R.phase==="project"?["auth","login","project"]:R.phase==="folder"?["auth","login","folder"]:["auth","login"];let p={infoView:"info",loginWizard:"login",profilesView:"profiles",chromeProfilePicker:"chrome-profile",projectPicker:"project",folderPicker:"folder",windowSizePicker:"set-window"};return Ge==="auth"?_n?["auth",p[_n]]:["auth"]:Ge==="config"?_n?["config",p[_n]]:["config"]:Ge==="help"?["help"]:$.askingUser?["agent question"]:[]})();return(0,y.jsxs)(b,{flexDirection:"column",children:[Y.length>0&&(0,y.jsx)(An,{items:Y,children:p=>(0,y.jsx)(b,{paddingX:1,children:p.content},p.id)}),!h&&!Se&&(0,y.jsx)(oi,{onComplete:()=>{let p=x.creds.getActiveProfile(),v=x.creds.getDefaultEnv(),f=p?x.creds.loadCredentials(p,v):null,w=p?x.creds.loadBasicAuth(p,v):null,S=!!(f||w),O=w?.username??p??null;Q((0,y.jsx)(Qn,{size:"full",helmetVisibleRows:8,textVisibleRows:7,showMeta:!0,version:st,authenticated:S,user:O})),Oe(!0);let B=(F,U,J,de)=>{i.log(F,U,J,de)};if(Lr(x.creds,B).then(F=>{if(F.status==="authenticated"){let{profile:U,env:J,tmsCreds:de}=F.result;x.creds.setActiveProfile(U),x.creds.setDefaultEnv(J),Ve(),bt(de),ne("ready"),T(!0)}else F.status==="needs_pick"?(ae(F.profiles),ne("pick")):ne("login")}).catch(F=>{i.log("error","STARTUP_GATE_ERROR","Auth gate failed",{error:String(F)}),ne("login")}),o&&o.then(async F=>{if(F){let{getUpdateCommand:U}=await import("./version-check-WHWTPX6C.js");K("ok","update available",`${F.current} \u2192 ${F.latest}`,`Run: ${U()}`)}}).catch(()=>{}),r&&r.changes.length>0){let F=`kane-cli updated to ${r.toVersion}. Default settings changed:`,U=[...r.changes.map(J=>`\u2022 ${J.description} (${J.field}: ${JSON.stringify(J.from)} \u2192 ${JSON.stringify(J.to)})`),"","Use /config to review or revert any of these."].join(`
|
|
29
|
-
`);K("ok","defaults updated",F,U)}}}),!h&&se==="booting"&&Se&&(0,y.jsx)(b,{paddingX:1,children:(0,y.jsx)(l,{color:"yellow",children:"Checking authentication..."})}),!h&&se==="pick"&&(0,y.jsx)(Es,{profiles:oe,onCancel:()=>ne("login"),onSelect:async(p,v)=>{x.creds.setActiveProfile(p),x.creds.setDefaultEnv(v),Ve(),Ue(!0);let f=(w,S,O,B)=>{i.log(w,S,O,B)};try{let w=await Vr(x.creds,p,v,f);Ue(!1),w.status==="authenticated"?(et(p,v),ne("ready"),T(!0)):ne("login")}catch{Ue(!1),ne("login")}},validating:Pe}),!h&&se==="login"&&!R&&(0,y.jsx)(jn,{devMode:process.env.KANE_DEV_MODE==="1",profiles:x.creds.listProfiles(),onBasicLogin:async(p,v,f,w)=>{let{validateBasicAuth:S}=await import("./validate-basic-NIEIKFGP.js");await S(v,f,w),x.creds.saveBasicAuth(p,v,{username:f,access_key:w}),x.creds.setActiveProfile(p),x.creds.setDefaultEnv(v),Te(x.creds,c,p,v),x.setTokenValid(!0),Ve()},onOAuthLogin:async(p,v)=>{x.creds.setDefaultEnv(v),await x.login(p),Te(x.creds,c,p,v),Ve()},onComplete:(p,v)=>{mt(v).then(()=>{Ve(),ge({phase:"project",profile:p,env:v})}).catch(()=>{ge({phase:"project",profile:p,env:v})})},onCancel:()=>{q(0,"Login cancelled at startup")}}),!h&&se==="login"&&R?.phase==="project"&&(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:null,env:R.env,onSelect:(p,v)=>{x.creds.saveProfileConfig(R.profile,R.env,{project_id:p,project_name:v}),K("ok","/config project",v,`id: ${p}`),ge({...R,phase:"folder"})},onCancel:async()=>{let p=await mo(R.profile,R.env);p&&(he(x.creds,c,R.profile,R.env,{projectId:p.id,projectName:p.name}),K("ok","/config project",p.name,`id: ${p.id}`),ge({...R,phase:"folder"}))}}),!h&&se==="login"&&R?.phase==="folder"&&(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:x.creds.loadProfileConfig(R.profile,R.env)?.project_id??"",currentFolderId:null,env:R.env,onSelect:(p,v)=>{x.creds.saveProfileConfig(R.profile,R.env,{folder_id:p,folder_name:v}),K("ok","/config folder",v,`id: ${p}`),et(R.profile,R.env),ge(null),ne("ready"),T(!0)},onCancel:async()=>{let p=x.creds.loadProfileConfig(R.profile,R.env);if(!p?.project_id)return;let v=await po(R.env,p.project_id);v&&(he(x.creds,c,R.profile,R.env,{folderId:v.id,folderName:v.name}),K("ok","/config folder",v.name,`id: ${v.id}`),et(R.profile,R.env),ge(null),ne("ready"),T(!0))}}),h&&ke==="menu"&&!re&&(0,y.jsx)(b,{marginBottom:1,children:(0,y.jsxs)(b,{borderStyle:"round",borderColor:"#dc4e08",paddingX:2,children:[(0,y.jsx)(l,{color:"#ff9500",bold:!0,children:"KaneAI CLI"}),(0,y.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,y.jsx)(l,{color:"#ff9500",children:I.model}),(0,y.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,y.jsx)(l,{color:g.dimmed,children:ts}),(0,y.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,y.jsxs)(l,{color:g.dimmed,children:[Dt??"no profile","/",le]})]})}),h&&!re&&(0,y.jsxs)(b,{flexDirection:"column",flexGrow:1,children:[ke==="menu"&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(Mo,{items:yr,onRunSelected:()=>Yt("chat"),onActiveViewChange:mr,renderLoginWizard:p=>{let v=R?.phase??"wizard";if(v==="project")return(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:null,env:R.env,onSelect:(f,w)=>{x.creds.saveProfileConfig(R.profile,R.env,{project_id:f,project_name:w}),K("ok","/config project",w,`id: ${f}`),ge(S=>S?{...S,phase:"folder"}:null)},onCancel:async()=>{if(!R)return;let f=await mo(R.profile,R.env);f&&(he(x.creds,c,R.profile,R.env,{projectId:f.id,projectName:f.name}),K("ok","/config project",f.name,`id: ${f.id}`),ge(w=>w?{...w,phase:"folder"}:null))}});if(v==="folder"){let f=x.creds.loadProfileConfig(R.profile,R.env);return(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:f?.project_id??"",currentFolderId:null,env:R.env,onSelect:(w,S)=>{x.creds.saveProfileConfig(R.profile,R.env,{folder_id:w,folder_name:S}),K("ok","/config folder",S,`id: ${w}`),et(R.profile,R.env),ge(null),p()},onCancel:async()=>{if(!R)return;let w=x.creds.loadProfileConfig(R.profile,R.env);if(!w?.project_id)return;let S=await po(R.env,w.project_id);S&&(he(x.creds,c,R.profile,R.env,{folderId:S.id,folderName:S.name}),K("ok","/config folder",S.name,`id: ${S.id}`),et(R.profile,R.env),ge(null),p())}})}return(0,y.jsx)(jn,{devMode:process.env.KANE_DEV_MODE==="1",profiles:x.creds.listProfiles(),onBasicLogin:async(f,w,S,O)=>{let{validateBasicAuth:B}=await import("./validate-basic-NIEIKFGP.js");await B(w,S,O),x.creds.saveBasicAuth(f,w,{username:S,access_key:O}),x.creds.setActiveProfile(f),x.creds.setDefaultEnv(w),Te(x.creds,c,f,w),x.setTokenValid(!0),Ve()},onOAuthLogin:async(f,w)=>{x.creds.setDefaultEnv(w),await x.login(f),Te(x.creds,c,f,w),Ve()},onComplete:(f,w)=>{mt(w).then(()=>{ge({phase:"project",profile:f,env:w})}).catch(()=>{ge({phase:"project",profile:f,env:w})})},onCancel:()=>{ge(null),p()}})},renderProfilesView:p=>(0,y.jsx)(ko,{creds:x.creds,onSwitch:(v,f)=>{let w=x.creds.getActiveProfile()??"(none)";x.creds.setActiveProfile(v),x.creds.setDefaultEnv(f),Te(x.creds,c,v,f),et(v,f),Ve(),mt(f).catch(()=>{}),K("ok","/profiles switch",`${w} \u2192 ${v} [${f}]`)},onCancel:p}),renderChromeProfilePicker:p=>(0,y.jsx)(To,{currentPath:I.chrome_profile_path,onSelect:v=>{c.set("chrome_profile_path",v),De(c.load()),K("ok","/config chrome-profile",v),p()},onCancel:p}),renderProjectPicker:p=>(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:I.project_id,env:le,onSelect:(v,f)=>{he(x.creds,c,x.creds.getActiveProfile()??"default",x.creds.getDefaultEnv(),{projectId:v,projectName:f}),K("ok","/config project",f,`id: ${v}`),De(c.load()),p()},onCancel:p}),renderFolderPicker:p=>(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:I.project_id??"",currentFolderId:I.folder_id,env:le,onSelect:(v,f)=>{he(x.creds,c,x.creds.getActiveProfile()??"default",x.creds.getDefaultEnv(),{folderId:v,folderName:f}),K("ok","/config folder",f,`id: ${v}`),De(c.load()),p()},onCancel:p}),renderWindowSizePicker:p=>(0,y.jsx)(Ko,{currentWidth:I.window_size.width,currentHeight:I.window_size.height,onSelect:(v,f)=>{c.set("window_size",{width:v,height:f}),De(c.load()),K("ok","/config set-window",`${v} \xD7 ${f}`),p()},onCancel:p})}),Ne&&(0,y.jsx)(b,{paddingX:1,marginTop:1,children:(0,y.jsx)(l,{color:Ne.color,children:Ne.text})})]}),ke==="chat"&&(0,y.jsxs)(y.Fragment,{children:[(()=>{let p=Dn({isRunning:$.isRunning,bifurcationInfo:$.bifurcationInfo,steps:$.steps,cmInitCounts:$.cmInitCounts,replayInfo:$.replayInfo});return p?(0,y.jsx)(On,{label:p.label,hasBifurcation:p.hasBifurcation}):null})(),$.isRunning&&$.steps.length>0&&(0,y.jsx)(Pn,{steps:$.steps,bifurcated:!!$.bifurcationInfo&&!$.bifurcationInfo.isSingleFlow,flows:$.bifurcationInfo?.flows,cmInitCounts:$.cmInitCounts,onStepCommit:Q},`run-${Me.current}`),yn&&(0,y.jsx)(mi,{onClose:()=>pr(!1),version:st,environment:x.creds.getDefaultEnv(),sessionId:i.sessionId,runUrl:I.default_url??at}),Ge&&!$.isRunning&&(()=>{let p=yr.find(v=>v.id===Ge);return p?.children?(0,y.jsx)(Mo,{items:p.children,onRunSelected:()=>Ot(null),onDismiss:()=>Ot(null),onActiveViewChange:mr,renderLoginWizard:v=>{let f=R?.phase??"wizard";if(f==="project")return(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:null,env:R.env,onSelect:(w,S)=>{x.creds.saveProfileConfig(R.profile,R.env,{project_id:w,project_name:S}),K("ok","/config project",S,`id: ${w}`),ge(O=>O?{...O,phase:"folder"}:null)},onCancel:async()=>{if(!R)return;let w=await mo(R.profile,R.env);w&&(he(x.creds,c,R.profile,R.env,{projectId:w.id,projectName:w.name}),K("ok","/config project",w.name,`id: ${w.id}`),ge(S=>S?{...S,phase:"folder"}:null))}});if(f==="folder"){let w=x.creds.loadProfileConfig(R.profile,R.env);return(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:w?.project_id??"",currentFolderId:null,env:R.env,onSelect:(S,O)=>{x.creds.saveProfileConfig(R.profile,R.env,{folder_id:S,folder_name:O}),K("ok","/config folder",O,`id: ${S}`),et(R.profile,R.env),ge(null),v()},onCancel:async()=>{if(!R)return;let S=x.creds.loadProfileConfig(R.profile,R.env);if(!S?.project_id)return;let O=await po(R.env,S.project_id);O&&(he(x.creds,c,R.profile,R.env,{folderId:O.id,folderName:O.name}),K("ok","/config folder",O.name,`id: ${O.id}`),et(R.profile,R.env),ge(null),v())}})}return(0,y.jsx)(jn,{devMode:process.env.KANE_DEV_MODE==="1",profiles:x.creds.listProfiles(),onBasicLogin:async(w,S,O,B)=>{let{validateBasicAuth:F}=await import("./validate-basic-NIEIKFGP.js");await F(S,O,B),x.creds.saveBasicAuth(w,S,{username:O,access_key:B}),x.creds.setActiveProfile(w),x.creds.setDefaultEnv(S),Te(x.creds,c,w,S),x.setTokenValid(!0),Ve()},onOAuthLogin:async(w,S)=>{x.creds.setDefaultEnv(S),await x.login(w),Te(x.creds,c,w,S),Ve()},onComplete:(w,S)=>{mt(S).then(()=>{ge({phase:"project",profile:w,env:S})}).catch(()=>{ge({phase:"project",profile:w,env:S})})},onCancel:()=>{ge(null),v()}})},renderProfilesView:v=>(0,y.jsx)(ko,{creds:x.creds,onSwitch:(f,w)=>{let S=x.creds.getActiveProfile()??"(none)";x.creds.setActiveProfile(f),x.creds.setDefaultEnv(w),Te(x.creds,c,f,w),et(f,w),Ve(),mt(w).catch(()=>{}),K("ok","/profiles switch",`${S} \u2192 ${f} [${w}]`),v()},onCancel:v}),renderChromeProfilePicker:v=>(0,y.jsx)(To,{currentPath:I.chrome_profile_path,onSelect:f=>{c.save({chrome_profile_path:f}),De(c.load()),K("ok","/config chrome-profile",f),v()},onCancel:v}),renderProjectPicker:v=>(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:I.project_id,env:le,onSelect:(f,w)=>{he(x.creds,c,x.creds.getActiveProfile()??"default",x.creds.getDefaultEnv(),{projectId:f,projectName:w}),De(c.load()),K("ok","/config project",w,`id: ${f}`),v()},onCancel:v}),renderFolderPicker:v=>(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:I.project_id??"",currentFolderId:I.folder_id,env:le,onSelect:(f,w)=>{he(x.creds,c,x.creds.getActiveProfile()??"default",x.creds.getDefaultEnv(),{folderId:f,folderName:w}),De(c.load()),K("ok","/config folder",w,`id: ${f}`),v()},onCancel:v}),renderWindowSizePicker:v=>(0,y.jsx)(Ko,{currentWidth:I.window_size.width,currentHeight:I.window_size.height,onSelect:(f,w)=>{c.set("window_size",{width:f,height:w}),De(c.load()),K("ok","/config set-window",`${f} \xD7 ${w}`),v()},onCancel:v})},Ge):null})(),Ge&&Ne&&(0,y.jsx)(b,{paddingX:1,marginTop:1,children:(0,y.jsx)(l,{color:Ne.color,children:Ne.text})}),!Ge&&!yn&&!_t&&$.askingUser&&(0,y.jsxs)(b,{flexDirection:"column",marginLeft:2,paddingLeft:1,marginTop:1,children:[(0,y.jsx)(b,{marginLeft:1,children:(0,y.jsx)(l,{color:g.primary,bold:!0,children:"Agent Question"})}),(0,y.jsx)(b,{borderStyle:"round",borderColor:g.primary,flexDirection:"column",paddingX:2,paddingY:1,width:70,children:(0,y.jsxs)(b,{children:[(0,y.jsx)(b,{width:3,children:(0,y.jsx)(l,{color:g.primary,bold:!0,children:"?"})}),(0,y.jsx)(b,{flexShrink:1,children:(0,y.jsx)(l,{wrap:"wrap",children:$.askingUser})})]})})]}),!Ge&&!yn&&!_t&&(0,y.jsx)(Rr,{onSubmit:es,onEscape:void 0,history:Ki,commands:to,placeholder:$.askingUser?"Type your answer...":$.isRunning?"Run in progress... Ctrl+C to cancel":"Type an objective... (/ = commands)"})]})]}),h&&re&&te&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(Ao,{steps:wn,status:te.status,testUrl:te.testUrl,error:te.error}),te.status==="success"&&(0,y.jsx)(Io,{recordedTestPath:ft?.recordedTestPath,outputDir:ft?.outputDir,shareableLink:te.testUrl,testCaseLink:te.testCaseLink,codeExportDir:te.codeExportDir,autoExit:!1})]}),_t&&(0,y.jsx)(Wr,{defaultName:_t,onSubmit:Zi}),bn&&(0,y.jsx)(Hr,{onSubmit:Qi}),xn&&te&&(0,y.jsx)(Ao,{steps:wn,status:te.status,error:te.error}),h&&!re&&(0,y.jsx)(ei,{profile:Dt,environment:le,model:I.model,tokenValid:x.tokenValid,sessionId:i.sessionId,runCount:j,viewMode:ke,breadcrumb:ns})]})}function Es({profiles:a,onSelect:e,onCancel:t,validating:n}){let[o,r]=(0,k.useState)(0);return He((s,m)=>{if(!n){if(m.escape){t();return}if(m.upArrow&&o>0&&r(d=>d-1),m.downArrow&&o<a.length-1&&r(d=>d+1),m.return){let d=a[o];e(d.profile,d.env)}}}),(0,y.jsxs)(b,{flexDirection:"column",paddingX:1,children:[(0,y.jsx)(l,{color:"#ff9500",bold:!0,children:"Select a profile:"}),(0,y.jsx)(b,{marginTop:1,flexDirection:"column",children:a.map((s,m)=>(0,y.jsxs)(l,{children:[m===o?"\u276F ":" ",(0,y.jsx)(l,{color:m===o?"#ff9500":"white",bold:m===o,children:s.profile}),(0,y.jsxs)(l,{color:"gray",children:[" [",s.env,"]"]})]},`${s.profile}-${s.env}`))}),n&&(0,y.jsx)(b,{marginTop:1,children:(0,y.jsx)(l,{color:"yellow",children:"Validating credentials..."})}),!n&&(0,y.jsx)(b,{marginTop:1,children:(0,y.jsx)(l,{color:"gray",children:"Esc = new login"})})]})}var Pi=H(Ii(),1),{program:Wc,createCommand:qc,createArgument:Kc,createOption:Gc,CommanderError:zc,InvalidArgumentError:Xc,InvalidOptionArgumentError:Jc,Command:Oi,Argument:Yc,Option:rt,Help:Qc}=Pi.default;import{join as ut}from"path";var Vi=H(Ye(),1);var Fe=H(Ye(),1);var vt=H(X(),1);function Di({steps:a,bifurcationInfo:e,perFlowMetadata:t}){return!e||e.isSingleFlow||!t||t.length<=1?null:(0,vt.jsx)(b,{flexDirection:"column",children:t.map((n,o)=>{let r=a[o],s=r?.children??[],m=s.filter(P=>P.status==="passed").length,d=s.filter(P=>P.status==="failed").length,u=m+d,i=s.reduce((P,h)=>P+(h.duration??0),0),c=r?.status==="failed"?"failed":"passed",_=e.flows[o]??r?.objective??`Flow ${o+1}`;return(0,vt.jsxs)(b,{flexDirection:"column",marginTop:o>0?1:0,children:[(0,vt.jsxs)(b,{marginLeft:1,children:[(0,vt.jsx)(l,{color:"#b388ff",bold:!0,children:"Flow "+(o+1)+": "}),(0,vt.jsx)(l,{color:"#b388ff",children:_})]}),(0,vt.jsx)(Nt,{status:c,summary:n?.summary??"",duration:i,steps:u,stepsPassed:m,stepsFailed:d,reason:n?.error_message??void 0,creditsConsumed:n?.credits_consumed??void 0})]},`flow-summary-${o}`)})})}var ve=H(X(),1);function ji({config:a,spawnOpts:e,cancelRef:t,banner:n,onComplete:o,onStepEnd:r,onReasoning:s,onStepComplete:m}){let{exit:d}=In(),u=Mn(r,void 0,s,m),i=(0,Fe.useRef)(!1),c=(0,Fe.useRef)(!1),[_,P]=(0,Fe.useState)("");(0,Fe.useEffect)(()=>{i.current||(i.current=!0,u.startRun(a,e))},[a,e,u]),(0,Fe.useEffect)(()=>{t&&(t.current=()=>u.cancelRun())},[t,u]);let h=(0,Fe.useRef)(0);He((A,E)=>{E.ctrl&&A==="c"&&(u.isRunning?(h.current++,h.current>=2?d():u.cancelRun()):d())}),He((A,E)=>{u.askingUser&&(E.return?(u.sendAnswer(_),P("")):E.backspace||E.delete?P(N=>N.slice(0,-1)):A&&!E.ctrl&&!E.meta&&P(N=>N+A))},{isActive:!!u.askingUser}),(0,Fe.useEffect)(()=>{if(!u.isRunning&&u.lastRunEnd&&!c.current){c.current=!0;let{passed:A,failed:E,total:N}=an(u.steps),j=u.bifurcationInfo;o({lastRunEnd:u.lastRunEnd,stepsPassed:A,stepsFailed:E,stepsTotal:N,hadError:!1,bifurcationFlows:j&&!j.isSingleFlow?j.flows:null}),d()}},[u.isRunning,u.lastRunEnd,u.steps,o,d]),(0,Fe.useEffect)(()=>{u.runError&&!u.isRunning&&!c.current&&(c.current=!0,o({lastRunEnd:null,stepsPassed:0,stepsFailed:0,stepsTotal:0,hadError:!0,bifurcationFlows:null}),d())},[u.runError,u.isRunning,o,d]);let T=u.lastRunEnd?(()=>{let{passed:A,failed:E,total:N}=an(u.steps);return{status:u.lastRunEnd.status,duration:u.lastRunEnd.duration??0,summary:u.lastRunEnd.summary??"",stepsPassed:A,stepsFailed:E,stepsTotal:N,reason:u.lastRunEnd.reason,finalState:u.lastRunEnd.final_state,creditsConsumed:u.lastRunEnd.credits_consumed}})():null,V=(0,Fe.useMemo)(()=>n?[{key:"banner",...n}]:[],[n]);return(0,ve.jsxs)(b,{flexDirection:"column",children:[(0,ve.jsx)(An,{items:V,children:A=>(0,ve.jsxs)(b,{flexDirection:"column",marginBottom:1,children:[(0,ve.jsxs)(b,{borderStyle:"round",borderColor:"#dc4e08",paddingX:2,children:[(0,ve.jsx)(l,{color:"#ff9500",bold:!0,children:"KaneAI CLI"}),(0,ve.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,ve.jsx)(l,{color:g.cyan,children:A.model}),(0,ve.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,ve.jsx)(l,{color:g.dimmed,children:A.auth})]}),A.status?.map((E,N)=>(0,ve.jsx)(l,{color:g.dimmed,children:E},N))]},A.key)}),(()=>{let A=Dn({isRunning:u.isRunning,bifurcationInfo:u.bifurcationInfo,steps:u.steps,cmInitCounts:u.cmInitCounts,replayInfo:u.replayInfo});return A?(0,ve.jsx)(On,{label:A.label,hasBifurcation:A.hasBifurcation}):null})(),u.steps.length>0&&(0,ve.jsx)(Pn,{steps:u.steps,bifurcated:!!u.bifurcationInfo&&!u.bifurcationInfo.isSingleFlow,flows:u.bifurcationInfo?.flows,cmInitCounts:u.cmInitCounts,staticSteps:!0}),u.askingUser&&(0,ve.jsxs)(b,{flexDirection:"column",marginTop:1,children:[(0,ve.jsxs)(l,{color:g.yellow,children:['Agent is asking: "',u.askingUser,'"']}),(0,ve.jsxs)(l,{children:["> ",_,"\u2588"]})]}),u.runError&&(0,ve.jsx)(Gr,{message:u.runError,code:"RUNNER_ERROR"}),T&&u.lastRunEnd&&(0,ve.jsx)(Di,{steps:u.steps,bifurcationInfo:u.bifurcationInfo,perFlowMetadata:u.lastRunEnd.per_flow_metadata??[]}),T&&(0,ve.jsx)(Nt,{status:T.status==="passed"?"passed":"failed",summary:T.summary??"",duration:T.duration,steps:T.stepsTotal,stepsPassed:T.stepsPassed,stepsFailed:T.stepsFailed,reason:T.reason,creditsConsumed:T.creditsConsumed})]})}import{createInterface as Ns}from"readline";function Wt(a){process.stdout.write(JSON.stringify(a)+`
|
|
28
|
+
${f}`})}},[$.runError,$.isRunning,ce,i]);let En=(0,k.useCallback)(async()=>{i.log("info","EXIT_UPLOAD_START","Starting exit upload pipeline"),Kt(Hn()),xt({status:"uploading"});let p=x.getResolvedBasicAuth(),v=null;if(!p&&(v=await x.getToken(),!v))return i.log("warn","EXIT_UPLOAD_ABORTED","Exit upload aborted \u2014 no auth available"),null;let f=Ze??await Et();if(!f)return i.log("warn","EXIT_UPLOAD_ABORTED","Exit upload aborted \u2014 no TMS credentials"),i.setUploadStatus("failed","Could not get TMS credentials"),null;i.log("info","EXIT_UPLOAD_CONFIG","Exit upload configuration",{test_id:i.testId,commit_id:i.sessionId,project_id:I.project_id,session_dir:i.sessionDir,run_dirs:i.getRunDirs()});let w={basicAuth:p??null,token:v,resolver:x.getResolver(),resolvedCreds:f};it.current&&(i.log("info","SCREENSHOT_UPLOAD_DRAIN","Draining screenshot queue before pipeline"),await it.current.drain(),i.log("info","SCREENSHOT_UPLOAD_DRAINED","Screenshot queue drained"));let S=cn({session:i,env:le,auth:w,variables:Ct.current??{raw:{},auteur:{},auteurObjective:"",secretEntries:[],nonSecretEntries:[]},variableIds:D.current,projectId:I.project_id,folderId:I.folder_id,totalSteps:vo.current,totalDuration:wo.current,codeExport:dn({codeExport:e,codeLanguage:t,skipCodeValidation:n},I.code_export),onProgress:(F,U,J)=>{i.log("info","EXIT_PROGRESS","Upload progress",{step:F,status:U,detail:J}),Kt(de=>Ur(de,F,U,J))},log:(F,U,J,de)=>i.log(F,U,J,de),shouldUploadArtifacts:!0,shouldReplaceLocalOutput:!1,shouldCommit:!1,isFirstRun:!0}),B=await new Mr(S).execute();if(B.success){i.log("info","EXIT_UPLOAD_OK","Exit upload succeeded",{test_id:B.testId,testcase_id:B.testcaseId??null,share_id:B.shareId??null}),i.setUploadStatus("uploaded"),B.testId&&i.setTestId(B.testId),B.testcaseId&&i.setTestcaseId(B.testcaseId);let F=me(le),U=I.project_id,J=B.testcaseId&&B.shareId&&U?At(F.testManagerUiUrl,U,B.testcaseId,B.shareId):void 0,de=B.testcaseId&&U?ln(F.testManagerUiUrl,U,B.testcaseId):void 0;xt({status:"success",testUrl:J,testCaseLink:de,codeExportDir:B.codeExportDir}),pi({shareableLink:J,testCaseLink:de,codeExportDir:B.codeExportDir})}else i.log("error","EXIT_UPLOAD_FAILED","Exit upload failed",{error:B.error}),i.setUploadStatus("failed",B.error),xt({status:"failed",error:B.error});return B},[x,le,i,I,Ze,Et]),Sn=(0,k.useCallback)(async()=>{i.log("info","SESSION_RESET_START","Starting session reset via /new"),L(!0);let p=i.getFlows();p.length>0&&Q((0,y.jsx)(Go,{flows:p}));let v=null;if(!a)try{v=await En()??null}catch(S){i.log("error","SESSION_RESET_UPLOAD_FAILED","Upload failed during /new",{error:String(S)}),ce({type:"error",text:"Upload failed \u2014 session data saved locally."})}let f=null;try{let{persistRecordedSession:S}=await import("./persist-recorded-session-V5DXMRKC.js");f=S(i,{testcaseId:i.testcaseId??void 0,projectId:I.project_id??void 0,folderId:I.folder_id??void 0,codeExportDir:v?.codeExportDir})}catch(S){i.log("error","SESSION_RESET_PERSIST_FAILED","Persist failed during /new",{error:String(S)})}if(v?.success&&v.testcaseId||f){let S=me(le),O=I.project_id,B=v?.testcaseId;Q((0,y.jsx)(Io,{recordedTestPath:f?.recordedTestPath,outputDir:f?.outputDir,shareableLink:B&&v?.shareId&&O?At(S.testManagerUiUrl,O,B,v.shareId):void 0,testCaseLink:B&&O?ln(S.testManagerUiUrl,O,B):void 0,codeExportDir:v?.codeExportDir,autoExit:!1}))}i.testId&&Ie(S=>[...S,{testId:i.testId,runCount:j}]),Cn.killChrome(),await i.finish("complete");let w=new nn;w.start({model:I.model,environment:le,profile:Dt??null}),m.current=w,u(S=>S+1),i.log("info","SESSION_RESET_COMPLETE","Session reset complete",{new_session_id:w.sessionId}),W(0),vo.current=0,wo.current=0,Me.current=0,yt.current="",Ct.current=null,D.current={},it.current=null,Tn.current=0,yo.current=0,xo.current=null,bo.current=null,ho.current=null,go.current=null,qe(null),A(null),xt(null),Kt(Hn()),L(!1),Q((0,y.jsxs)(b,{flexDirection:"column",marginY:1,children:[(0,y.jsx)(l,{color:g.dimmed,children:"\u2500".repeat(44)}),(0,y.jsx)(l,{color:g.green,bold:!0,children:"New session started"})]}))},[i,ce,Q,a,En,Cn,j,I,le,Dt]),br=(0,k.useCallback)(async()=>{if(!(i.nextRunIndex()>0)){ce({type:"info",text:"No runs in current session."});return}if($.isRunning){ce({type:"error",text:"Cannot reset while a run is in progress. Cancel the run first."});return}if(I.mode==="testing"&&!i.sessionName){pe("new"),Ke(Po());return}await Sn()},[i,$,ce,I.mode,Sn]),_r=(0,k.useCallback)(async()=>{await i.finish("complete"),q(0,"Session complete")},[i]),Qi=(0,k.useCallback)(async p=>{Gt(!1);let v=i.testId??(we.length>0?we[we.length-1].testId:null);if(p&&v){i.log("info","EXIT_FEEDBACK_SUBMIT","Submitting session feedback",{choice:p});try{let f=me(le),w=x.getResolvedBasicAuth();w&&await io({tmsBaseUrl:f.tmsBaseUrl,username:w.username,accessKey:w.access_key,testId:v,feedbackType:p,log:(S,O,B,F)=>i.log(S,O,B,F)})}catch(f){i.log("error","EXIT_FEEDBACK_FAILED","Feedback submission failed",{error:String(f)})}}else i.log("info","EXIT_FEEDBACK_SKIPPED","Feedback skipped");_r()},[le,x,i,_r,we]),kn=(0,k.useCallback)(async()=>{let p=i.nextRunIndex()>0,v=null;if(p&&!a){i.log("info","EXIT_WITH_ACTIVE_SESSION","Exit with active session \u2014 uploading first"),Ae(!0);try{v=await En()??null}catch(w){i.log("error","EXIT_UPLOAD_FAILED","Exit upload failed",{error:String(w)})}i.testId&&Ie(w=>[...w,{testId:i.testId,runCount:j}])}try{let{persistRecordedSession:w}=await import("./persist-recorded-session-V5DXMRKC.js"),S=w(i,{testcaseId:i.testcaseId??void 0,projectId:I.project_id??void 0,folderId:I.folder_id??void 0,codeExportDir:v?.codeExportDir});S&&Xt(S)}catch(w){i.log("error","EXIT_PERSIST_FAILED","Persist failed during /exit",{error:String(w)})}if(p&&!a&&await i.finish("complete"),!(i.testId??(we.length>0?we[we.length-1].testId:null))||a){await i.finish("complete"),q(0,"No test ID \u2014 quick exit");return}Ae(!0),Gt(!0)},[i,a,En,j,we,I]),St=(0,k.useCallback)(async()=>{if(re)return;i.log("info","EXIT_START","TUI exit initiated");let p=I.mode==="testing",v=i.nextRunIndex()>0;if(p&&v&&!i.sessionName){pe("exit"),Ke(Po());return}await kn()},[re,i,I.mode,kn]),Zi=(0,k.useCallback)(p=>{p&&i.setSessionName(p);let v=zt;Ke(null),pe(null),v==="new"?Sn():kn()},[i,zt,kn,Sn]);(0,k.useEffect)(()=>{if(!re)return;let p=300*1e3,v=setTimeout(async()=>{i.setUploadStatus("failed","Upload timed out after 5m"),await i.finish("complete"),q(0,"Upload timed out after 5m")},p);return()=>clearTimeout(v)},[re,i]);let Tn=k.default.useRef(0),_o=k.default.useRef(null),yo=k.default.useRef(0);He((p,v)=>{if(v.ctrl&&p==="c"){if(re){yo.current+=1,yo.current>=2&&(i.setUploadStatus("pending","Force exit by user"),i.finish("complete"),q(0,"Force exit by user"));return}if($.isRunning){$.cancelRun(),ce({type:"info",text:"Run cancelled."}),Tn.current++,_o.current&&clearTimeout(_o.current),_o.current=setTimeout(()=>{Tn.current=0},2e3),Tn.current>=2&&St();return}St()}});let yr=k.default.useMemo(()=>{let p=x.creds.getActiveProfile()??"none",v=x.creds.getDefaultEnv();return[{id:"run",label:"Run",type:"submenu",children:[{id:"run-start",label:"Start Run",type:"action"},{id:"run-config",label:"Run Config",type:"submenu",children:[{id:"run-headless",label:"Headless",type:"select",currentValue:Z.headless?"on":"off",options:[{label:"off",value:"off"},{label:"on",value:"on"}],onValue:f=>{Qt(w=>({...w,headless:f==="on"}))}},{id:"run-max-steps",label:"Max Steps",type:"text-input",currentValue:String(Z.maxSteps),onValue:f=>{let w=parseInt(f,10);w>0&&Qt(S=>({...S,maxSteps:w}))}},{id:"run-timeout",label:"Timeout (sec)",type:"text-input",currentValue:Z.timeout?String(Z.timeout):"",placeholder:"0 = no timeout",onValue:f=>{let w=parseInt(f,10);Qt(S=>({...S,timeout:isNaN(w)?0:w}))}},{id:"run-cdp",label:"CDP Endpoint",type:"text-input",currentValue:Z.cdpEndpoint,placeholder:"http://127.0.0.1:9222",onValue:f=>{Qt(w=>({...w,cdpEndpoint:f}))}},{id:"run-ws",label:"WS Endpoint",type:"text-input",currentValue:Z.wsEndpoint,placeholder:"wss://...",onValue:f=>{Qt(w=>({...w,wsEndpoint:f}))}}]}]},{id:"auth",label:"Auth",type:"submenu",children:[{id:"login",label:"Login",type:"action",onLoginWizard:()=>{}},{id:"logout",label:"Logout",type:"action",onAction:()=>{x.logout().then(f=>{Ve();let w=x.creds.getActiveProfile(),S=x.creds.getDefaultEnv();et(w,S),mt().catch(()=>{}),f?K("ok","/logout",`Logged out: ${f.profile} [${f.env}]`):K("ok","/logout","No active profile")}).catch(()=>{K("error","/logout","Logout failed")})}},{id:"whoami",label:"Who Am I",type:"action",onInfo:()=>{let f=x.creds.getActiveProfile()??"none",w=x.creds.getDefaultEnv(),S=x.creds.loadBasicAuth(f,w),O=S?"basic":x.creds.loadCredentials(f,w)?"oauth":"not configured";return{title:"Who Am I",sections:[{label:"Identity",entries:[{key:"Profile",value:f},{key:"Environment",value:w}]},{label:"Authentication",entries:[{key:"Method",value:O},...S?[{key:"Username",value:S.username}]:[]]},{label:"Token",entries:[{key:"Status",value:x.tokenValid?"valid":"not logged in",color:x.tokenValid?g.statusPass:g.statusFail}]}]}}},{id:"balance",label:"Credit Balance",type:"action",suppressFeedback:!0,onAction:()=>{(async()=>{let f=x.creds.getActiveProfile()??"default",w=x.creds.getDefaultEnv(),S=me(w);try{let O=x.getBasicAuth(),B=O?null:await x.getToken();if(!O&&!B){ie({text:"Not authenticated. Run /login first.",color:g.red});return}let{ControllerClient:F}=await import("./controller-client-OMKEBP4B.js"),J=await(O?new F(S.controllerBaseUrl,{username:O.username,accessKey:O.access_key}):new F(S.controllerBaseUrl,B)).getCreditBalance();ie({text:`Credits \u2014 available: ${J.available_credits}, total: ${J.total_credits} (${f} / ${w})`,color:g.green})}catch(O){ie({text:`Balance check failed: ${O instanceof Error?O.message:String(O)}`,color:g.red})}Qe.current&&clearTimeout(Qe.current),Qe.current=setTimeout(()=>{ie(null),Qe.current=null},5e3)})()}},{id:"profiles",label:"Profiles",type:"action",onProfilesView:()=>{}}]},{id:"config",label:"Config",type:"submenu",children:[{id:"config-show",label:"Show",type:"action",onInfo:()=>({title:"Show Config",sections:[{label:"General",entries:[{key:"Model",value:"v16-alpha"},{key:"Mode",value:I.mode}]},{label:"Browser",entries:[{key:"Window",value:`${I.window_size.width}x${I.window_size.height}`},{key:"Chrome Profile",value:I.chrome_profile_path?I.chrome_profile_path.split("/").pop()??I.chrome_profile_path:"(temporary)"}]},{label:"Project",entries:[{key:"Project",value:I.project_name?`${I.project_name} (${I.project_id})`:I.project_id??"(none)"},{key:"Folder",value:I.folder_name?`${I.folder_name} (${I.folder_id})`:I.folder_id??"(none)"},{key:"Default URL",value:at}]},{label:"Code Export",entries:[{key:"Enabled",value:I.code_export.enabled?"yes":"no"},{key:"Language",value:I.code_export.language},{key:"Skip Validation",value:I.code_export.skip_validation?"yes":"no"}]}]})},{id:"config-chrome",label:"Chrome Profile",type:"action",onChromeProfilePicker:()=>{}},{id:"config-project",label:"Project",type:"action",onProjectPicker:()=>{}},{id:"config-folder",label:"Folder",type:"action",...I.project_id?{onFolderPicker:()=>{}}:{onInfo:()=>({title:"Folder",sections:[{entries:[{key:"Status",value:"Select a project first",color:g.dim}]}]})}},{id:"config-window",label:"Window Size",type:"action",currentValue:`${I.window_size.width}x${I.window_size.height}`,onWindowSizePicker:()=>{}},{id:"config-mode",label:"Mode",type:"select",currentValue:I.mode,options:[{label:"testing",value:"testing"},{label:"action",value:"action"}],onValue:f=>{(f==="action"||f==="testing")&&(c.set("mode",f),De(c.load()),K("ok","/config set-mode",f))}},{id:"config-code-export",label:"Code Export",type:"submenu",currentValue:I.code_export.enabled?"enabled":"disabled",children:[{id:"config-code-export-enabled",label:"Enabled",type:"select",currentValue:I.code_export.enabled?"on":"off",options:[{label:"off",value:"off"},{label:"on",value:"on"}],onValue:f=>{c.set("code_export",{...I.code_export,enabled:f==="on"}),De(c.load()),K("ok","/config code-export enabled",f)}},{id:"config-code-export-language",label:"Language",type:"select",currentValue:I.code_export.language,options:[{label:"python",value:"python"},{label:"javascript",value:"javascript"}],onValue:f=>{f!=="python"&&f!=="javascript"||(c.set("code_export",{...I.code_export,language:f}),De(c.load()),K("ok","/config code-export language",f))}},{id:"config-code-export-skip-validation",label:"Skip Validation",type:"select",currentValue:I.code_export.skip_validation?"on":"off",options:[{label:"off",value:"off"},{label:"on",value:"on"}],onValue:f=>{c.set("code_export",{...I.code_export,skip_validation:f==="on"}),De(c.load()),K("ok","/config code-export skip-validation",f)}}]}]},{id:"exit",label:"Exit",type:"action",onAction:()=>{St()}}]},[x,c,I,ce,St,Z,Ve,K]),es=(0,k.useCallback)(p=>{if($.askingUser){let f=$.askingUser;Q((0,y.jsxs)(b,{flexDirection:"column",marginLeft:2,paddingLeft:1,marginTop:1,children:[(0,y.jsx)(b,{marginLeft:1,children:(0,y.jsx)(l,{color:g.primary,bold:!0,children:"Agent Question"})}),(0,y.jsxs)(b,{borderStyle:"round",borderColor:g.primary,flexDirection:"column",paddingX:2,paddingY:1,width:70,children:[(0,y.jsxs)(b,{children:[(0,y.jsx)(b,{width:3,children:(0,y.jsx)(l,{color:g.primary,bold:!0,children:"?"})}),(0,y.jsx)(b,{flexShrink:1,children:(0,y.jsx)(l,{wrap:"wrap",children:f})})]}),(0,y.jsxs)(b,{marginTop:1,children:[(0,y.jsx)(b,{width:3,children:(0,y.jsx)(l,{color:g.dim,bold:!0,children:"\u2192"})}),(0,y.jsx)(b,{flexShrink:1,children:(0,y.jsx)(l,{color:g.accent,wrap:"wrap",children:p})})]})]})]})),xo.current=null,$.sendAnswer(p);return}if(i.logCommand(p),$.isRunning){ce({type:"error",text:"Run in progress. Ctrl+C to cancel."});return}let v=ci(p);if(v)switch(v.command){case"login":case"logout":case"whoami":case"profiles":case"balance":case"auth":Ot("auth");return;case"config":Ot("config");return;case"help":pr(!0);return;case"update":{(async()=>{let{getUpdateCommand:f}=await import("./version-check-LUCKH72U.js");K("ok","/update",`To update kane-cli, run: ${f()}`)})();return}case"summary":{let f=i.getFlows();if(f.length===0){K("ok","/summary","No runs yet in this session.");return}let w=v.args.index?parseInt(v.args.index,10):void 0;if(w!==void 0&&!i.getFlow(w)){K("error","/summary",`No flow at index ${w}`,`${f.length} flow${f.length===1?"":"s"} available. Use /summary to see all.`);return}Q((0,y.jsx)(Go,{flows:f,filterIndex:w})),K("ok","/summary",w!==void 0?`Flow ${w}`:`${f.length} flow${f.length===1?"":"s"}`);return}case"new":br(),K("ok","/new","Session reset");return;case"name":{let f=v.raw.replace(/^\/name\s*/,"").trim();if(!f){K("error","/name","Usage: /name <new-name>");return}(async()=>{let{validateNameOrThrow:w}=await import("./name-validator-5YGJXLZ7.js");try{w(f),i.setSessionName(f),K("ok","/name",`Session name set: ${f}`)}catch(S){K("error","/name",S.message)}})();return}case"cancel":$.cancelRun(),K("ok","/cancel","Run cancelled");return;case"clear":K("ok","/clear","Chat cleared");return;case"exit":St();return;default:K("error",`/${v.command}`,"Unknown command");return}if(p.trim().toLowerCase()==="exit"){St();return}Q((0,y.jsxs)(b,{children:[(0,y.jsx)(l,{color:"#b388ff",children:"\u276F "}),(0,y.jsx)(l,{children:p})]})),xr(p,at)},[$,ce,K,Q,i,xr,St,br]),Cr=x.getAuthInfo(),ts=Cr?Cr.method==="basic"?"basic auth":"oauth":"not logged in",ns=(()=>{if(yn)return["help"];if(R)return R.phase==="wizard"?["auth","login"]:R.phase==="project"?["auth","login","project"]:R.phase==="folder"?["auth","login","folder"]:["auth","login"];let p={infoView:"info",loginWizard:"login",profilesView:"profiles",chromeProfilePicker:"chrome-profile",projectPicker:"project",folderPicker:"folder",windowSizePicker:"set-window"};return Ge==="auth"?_n?["auth",p[_n]]:["auth"]:Ge==="config"?_n?["config",p[_n]]:["config"]:Ge==="help"?["help"]:$.askingUser?["agent question"]:[]})();return(0,y.jsxs)(b,{flexDirection:"column",children:[Y.length>0&&(0,y.jsx)(An,{items:Y,children:p=>(0,y.jsx)(b,{paddingX:1,children:p.content},p.id)}),!h&&!Se&&(0,y.jsx)(oi,{onComplete:()=>{let p=x.creds.getActiveProfile(),v=x.creds.getDefaultEnv(),f=p?x.creds.loadCredentials(p,v):null,w=p?x.creds.loadBasicAuth(p,v):null,S=!!(f||w),O=w?.username??p??null;Q((0,y.jsx)(Qn,{size:"full",helmetVisibleRows:8,textVisibleRows:7,showMeta:!0,version:st,authenticated:S,user:O})),Oe(!0);let B=(F,U,J,de)=>{i.log(F,U,J,de)};if(Lr(x.creds,B).then(F=>{if(F.status==="authenticated"){let{profile:U,env:J,tmsCreds:de}=F.result;x.creds.setActiveProfile(U),x.creds.setDefaultEnv(J),Ve(),bt(de),ne("ready"),T(!0)}else F.status==="needs_pick"?(ae(F.profiles),ne("pick")):ne("login")}).catch(F=>{i.log("error","STARTUP_GATE_ERROR","Auth gate failed",{error:String(F)}),ne("login")}),o&&o.then(async F=>{if(F){let{getUpdateCommand:U}=await import("./version-check-LUCKH72U.js");K("ok","update available",`${F.current} \u2192 ${F.latest}`,`Run: ${U()}`)}}).catch(()=>{}),r&&r.changes.length>0){let F=`kane-cli updated to ${r.toVersion}. Default settings changed:`,U=[...r.changes.map(J=>`\u2022 ${J.description} (${J.field}: ${JSON.stringify(J.from)} \u2192 ${JSON.stringify(J.to)})`),"","Use /config to review or revert any of these."].join(`
|
|
29
|
+
`);K("ok","defaults updated",F,U)}}}),!h&&se==="booting"&&Se&&(0,y.jsx)(b,{paddingX:1,children:(0,y.jsx)(l,{color:"yellow",children:"Checking authentication..."})}),!h&&se==="pick"&&(0,y.jsx)(Es,{profiles:oe,onCancel:()=>ne("login"),onSelect:async(p,v)=>{x.creds.setActiveProfile(p),x.creds.setDefaultEnv(v),Ve(),Ue(!0);let f=(w,S,O,B)=>{i.log(w,S,O,B)};try{let w=await Vr(x.creds,p,v,f);Ue(!1),w.status==="authenticated"?(et(p,v),ne("ready"),T(!0)):ne("login")}catch{Ue(!1),ne("login")}},validating:Pe}),!h&&se==="login"&&!R&&(0,y.jsx)(jn,{devMode:process.env.KANE_DEV_MODE==="1",profiles:x.creds.listProfiles(),onBasicLogin:async(p,v,f,w)=>{let{validateBasicAuth:S}=await import("./validate-basic-XKTSGLFO.js");await S(v,f,w),x.creds.saveBasicAuth(p,v,{username:f,access_key:w}),x.creds.setActiveProfile(p),x.creds.setDefaultEnv(v),Te(x.creds,c,p,v),x.setTokenValid(!0),Ve()},onOAuthLogin:async(p,v)=>{x.creds.setDefaultEnv(v),await x.login(p),Te(x.creds,c,p,v),Ve()},onComplete:(p,v)=>{mt(v).then(()=>{Ve(),ge({phase:"project",profile:p,env:v})}).catch(()=>{ge({phase:"project",profile:p,env:v})})},onCancel:()=>{q(0,"Login cancelled at startup")}}),!h&&se==="login"&&R?.phase==="project"&&(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:null,env:R.env,onSelect:(p,v)=>{x.creds.saveProfileConfig(R.profile,R.env,{project_id:p,project_name:v}),K("ok","/config project",v,`id: ${p}`),ge({...R,phase:"folder"})},onCancel:async()=>{let p=await mo(R.profile,R.env);p&&(he(x.creds,c,R.profile,R.env,{projectId:p.id,projectName:p.name}),K("ok","/config project",p.name,`id: ${p.id}`),ge({...R,phase:"folder"}))}}),!h&&se==="login"&&R?.phase==="folder"&&(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:x.creds.loadProfileConfig(R.profile,R.env)?.project_id??"",currentFolderId:null,env:R.env,onSelect:(p,v)=>{x.creds.saveProfileConfig(R.profile,R.env,{folder_id:p,folder_name:v}),K("ok","/config folder",v,`id: ${p}`),et(R.profile,R.env),ge(null),ne("ready"),T(!0)},onCancel:async()=>{let p=x.creds.loadProfileConfig(R.profile,R.env);if(!p?.project_id)return;let v=await po(R.env,p.project_id);v&&(he(x.creds,c,R.profile,R.env,{folderId:v.id,folderName:v.name}),K("ok","/config folder",v.name,`id: ${v.id}`),et(R.profile,R.env),ge(null),ne("ready"),T(!0))}}),h&&ke==="menu"&&!re&&(0,y.jsx)(b,{marginBottom:1,children:(0,y.jsxs)(b,{borderStyle:"round",borderColor:"#dc4e08",paddingX:2,children:[(0,y.jsx)(l,{color:"#ff9500",bold:!0,children:"KaneAI CLI"}),(0,y.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,y.jsx)(l,{color:"#ff9500",children:I.model}),(0,y.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,y.jsx)(l,{color:g.dimmed,children:ts}),(0,y.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,y.jsxs)(l,{color:g.dimmed,children:[Dt??"no profile","/",le]})]})}),h&&!re&&(0,y.jsxs)(b,{flexDirection:"column",flexGrow:1,children:[ke==="menu"&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(Mo,{items:yr,onRunSelected:()=>Yt("chat"),onActiveViewChange:mr,renderLoginWizard:p=>{let v=R?.phase??"wizard";if(v==="project")return(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:null,env:R.env,onSelect:(f,w)=>{x.creds.saveProfileConfig(R.profile,R.env,{project_id:f,project_name:w}),K("ok","/config project",w,`id: ${f}`),ge(S=>S?{...S,phase:"folder"}:null)},onCancel:async()=>{if(!R)return;let f=await mo(R.profile,R.env);f&&(he(x.creds,c,R.profile,R.env,{projectId:f.id,projectName:f.name}),K("ok","/config project",f.name,`id: ${f.id}`),ge(w=>w?{...w,phase:"folder"}:null))}});if(v==="folder"){let f=x.creds.loadProfileConfig(R.profile,R.env);return(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:f?.project_id??"",currentFolderId:null,env:R.env,onSelect:(w,S)=>{x.creds.saveProfileConfig(R.profile,R.env,{folder_id:w,folder_name:S}),K("ok","/config folder",S,`id: ${w}`),et(R.profile,R.env),ge(null),p()},onCancel:async()=>{if(!R)return;let w=x.creds.loadProfileConfig(R.profile,R.env);if(!w?.project_id)return;let S=await po(R.env,w.project_id);S&&(he(x.creds,c,R.profile,R.env,{folderId:S.id,folderName:S.name}),K("ok","/config folder",S.name,`id: ${S.id}`),et(R.profile,R.env),ge(null),p())}})}return(0,y.jsx)(jn,{devMode:process.env.KANE_DEV_MODE==="1",profiles:x.creds.listProfiles(),onBasicLogin:async(f,w,S,O)=>{let{validateBasicAuth:B}=await import("./validate-basic-XKTSGLFO.js");await B(w,S,O),x.creds.saveBasicAuth(f,w,{username:S,access_key:O}),x.creds.setActiveProfile(f),x.creds.setDefaultEnv(w),Te(x.creds,c,f,w),x.setTokenValid(!0),Ve()},onOAuthLogin:async(f,w)=>{x.creds.setDefaultEnv(w),await x.login(f),Te(x.creds,c,f,w),Ve()},onComplete:(f,w)=>{mt(w).then(()=>{ge({phase:"project",profile:f,env:w})}).catch(()=>{ge({phase:"project",profile:f,env:w})})},onCancel:()=>{ge(null),p()}})},renderProfilesView:p=>(0,y.jsx)(ko,{creds:x.creds,onSwitch:(v,f)=>{let w=x.creds.getActiveProfile()??"(none)";x.creds.setActiveProfile(v),x.creds.setDefaultEnv(f),Te(x.creds,c,v,f),et(v,f),Ve(),mt(f).catch(()=>{}),K("ok","/profiles switch",`${w} \u2192 ${v} [${f}]`)},onCancel:p}),renderChromeProfilePicker:p=>(0,y.jsx)(To,{currentPath:I.chrome_profile_path,onSelect:v=>{c.set("chrome_profile_path",v),De(c.load()),K("ok","/config chrome-profile",v),p()},onCancel:p}),renderProjectPicker:p=>(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:I.project_id,env:le,onSelect:(v,f)=>{he(x.creds,c,x.creds.getActiveProfile()??"default",x.creds.getDefaultEnv(),{projectId:v,projectName:f}),K("ok","/config project",f,`id: ${v}`),De(c.load()),p()},onCancel:p}),renderFolderPicker:p=>(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:I.project_id??"",currentFolderId:I.folder_id,env:le,onSelect:(v,f)=>{he(x.creds,c,x.creds.getActiveProfile()??"default",x.creds.getDefaultEnv(),{folderId:v,folderName:f}),K("ok","/config folder",f,`id: ${v}`),De(c.load()),p()},onCancel:p}),renderWindowSizePicker:p=>(0,y.jsx)(Ko,{currentWidth:I.window_size.width,currentHeight:I.window_size.height,onSelect:(v,f)=>{c.set("window_size",{width:v,height:f}),De(c.load()),K("ok","/config set-window",`${v} \xD7 ${f}`),p()},onCancel:p})}),Ne&&(0,y.jsx)(b,{paddingX:1,marginTop:1,children:(0,y.jsx)(l,{color:Ne.color,children:Ne.text})})]}),ke==="chat"&&(0,y.jsxs)(y.Fragment,{children:[(()=>{let p=Dn({isRunning:$.isRunning,bifurcationInfo:$.bifurcationInfo,steps:$.steps,cmInitCounts:$.cmInitCounts,replayInfo:$.replayInfo});return p?(0,y.jsx)(On,{label:p.label,hasBifurcation:p.hasBifurcation}):null})(),$.isRunning&&$.steps.length>0&&(0,y.jsx)(Pn,{steps:$.steps,bifurcated:!!$.bifurcationInfo&&!$.bifurcationInfo.isSingleFlow,flows:$.bifurcationInfo?.flows,cmInitCounts:$.cmInitCounts,onStepCommit:Q},`run-${Me.current}`),yn&&(0,y.jsx)(mi,{onClose:()=>pr(!1),version:st,environment:x.creds.getDefaultEnv(),sessionId:i.sessionId,runUrl:I.default_url??at}),Ge&&!$.isRunning&&(()=>{let p=yr.find(v=>v.id===Ge);return p?.children?(0,y.jsx)(Mo,{items:p.children,onRunSelected:()=>Ot(null),onDismiss:()=>Ot(null),onActiveViewChange:mr,renderLoginWizard:v=>{let f=R?.phase??"wizard";if(f==="project")return(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:null,env:R.env,onSelect:(w,S)=>{x.creds.saveProfileConfig(R.profile,R.env,{project_id:w,project_name:S}),K("ok","/config project",S,`id: ${w}`),ge(O=>O?{...O,phase:"folder"}:null)},onCancel:async()=>{if(!R)return;let w=await mo(R.profile,R.env);w&&(he(x.creds,c,R.profile,R.env,{projectId:w.id,projectName:w.name}),K("ok","/config project",w.name,`id: ${w.id}`),ge(S=>S?{...S,phase:"folder"}:null))}});if(f==="folder"){let w=x.creds.loadProfileConfig(R.profile,R.env);return(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:w?.project_id??"",currentFolderId:null,env:R.env,onSelect:(S,O)=>{x.creds.saveProfileConfig(R.profile,R.env,{folder_id:S,folder_name:O}),K("ok","/config folder",O,`id: ${S}`),et(R.profile,R.env),ge(null),v()},onCancel:async()=>{if(!R)return;let S=x.creds.loadProfileConfig(R.profile,R.env);if(!S?.project_id)return;let O=await po(R.env,S.project_id);O&&(he(x.creds,c,R.profile,R.env,{folderId:O.id,folderName:O.name}),K("ok","/config folder",O.name,`id: ${O.id}`),et(R.profile,R.env),ge(null),v())}})}return(0,y.jsx)(jn,{devMode:process.env.KANE_DEV_MODE==="1",profiles:x.creds.listProfiles(),onBasicLogin:async(w,S,O,B)=>{let{validateBasicAuth:F}=await import("./validate-basic-XKTSGLFO.js");await F(S,O,B),x.creds.saveBasicAuth(w,S,{username:O,access_key:B}),x.creds.setActiveProfile(w),x.creds.setDefaultEnv(S),Te(x.creds,c,w,S),x.setTokenValid(!0),Ve()},onOAuthLogin:async(w,S)=>{x.creds.setDefaultEnv(S),await x.login(w),Te(x.creds,c,w,S),Ve()},onComplete:(w,S)=>{mt(S).then(()=>{ge({phase:"project",profile:w,env:S})}).catch(()=>{ge({phase:"project",profile:w,env:S})})},onCancel:()=>{ge(null),v()}})},renderProfilesView:v=>(0,y.jsx)(ko,{creds:x.creds,onSwitch:(f,w)=>{let S=x.creds.getActiveProfile()??"(none)";x.creds.setActiveProfile(f),x.creds.setDefaultEnv(w),Te(x.creds,c,f,w),et(f,w),Ve(),mt(w).catch(()=>{}),K("ok","/profiles switch",`${S} \u2192 ${f} [${w}]`),v()},onCancel:v}),renderChromeProfilePicker:v=>(0,y.jsx)(To,{currentPath:I.chrome_profile_path,onSelect:f=>{c.save({chrome_profile_path:f}),De(c.load()),K("ok","/config chrome-profile",f),v()},onCancel:v}),renderProjectPicker:v=>(0,y.jsx)(Lt,{resolver:x.getResolver(),currentProjectId:I.project_id,env:le,onSelect:(f,w)=>{he(x.creds,c,x.creds.getActiveProfile()??"default",x.creds.getDefaultEnv(),{projectId:f,projectName:w}),De(c.load()),K("ok","/config project",w,`id: ${f}`),v()},onCancel:v}),renderFolderPicker:v=>(0,y.jsx)(Ft,{resolver:x.getResolver(),projectId:I.project_id??"",currentFolderId:I.folder_id,env:le,onSelect:(f,w)=>{he(x.creds,c,x.creds.getActiveProfile()??"default",x.creds.getDefaultEnv(),{folderId:f,folderName:w}),De(c.load()),K("ok","/config folder",w,`id: ${f}`),v()},onCancel:v}),renderWindowSizePicker:v=>(0,y.jsx)(Ko,{currentWidth:I.window_size.width,currentHeight:I.window_size.height,onSelect:(f,w)=>{c.set("window_size",{width:f,height:w}),De(c.load()),K("ok","/config set-window",`${f} \xD7 ${w}`),v()},onCancel:v})},Ge):null})(),Ge&&Ne&&(0,y.jsx)(b,{paddingX:1,marginTop:1,children:(0,y.jsx)(l,{color:Ne.color,children:Ne.text})}),!Ge&&!yn&&!_t&&$.askingUser&&(0,y.jsxs)(b,{flexDirection:"column",marginLeft:2,paddingLeft:1,marginTop:1,children:[(0,y.jsx)(b,{marginLeft:1,children:(0,y.jsx)(l,{color:g.primary,bold:!0,children:"Agent Question"})}),(0,y.jsx)(b,{borderStyle:"round",borderColor:g.primary,flexDirection:"column",paddingX:2,paddingY:1,width:70,children:(0,y.jsxs)(b,{children:[(0,y.jsx)(b,{width:3,children:(0,y.jsx)(l,{color:g.primary,bold:!0,children:"?"})}),(0,y.jsx)(b,{flexShrink:1,children:(0,y.jsx)(l,{wrap:"wrap",children:$.askingUser})})]})})]}),!Ge&&!yn&&!_t&&(0,y.jsx)(Rr,{onSubmit:es,onEscape:void 0,history:Ki,commands:to,placeholder:$.askingUser?"Type your answer...":$.isRunning?"Run in progress... Ctrl+C to cancel":"Type an objective... (/ = commands)"})]})]}),h&&re&&te&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(Ao,{steps:wn,status:te.status,testUrl:te.testUrl,error:te.error}),te.status==="success"&&(0,y.jsx)(Io,{recordedTestPath:ft?.recordedTestPath,outputDir:ft?.outputDir,shareableLink:te.testUrl,testCaseLink:te.testCaseLink,codeExportDir:te.codeExportDir,autoExit:!1})]}),_t&&(0,y.jsx)(Wr,{defaultName:_t,onSubmit:Zi}),bn&&(0,y.jsx)(Hr,{onSubmit:Qi}),xn&&te&&(0,y.jsx)(Ao,{steps:wn,status:te.status,error:te.error}),h&&!re&&(0,y.jsx)(ei,{profile:Dt,environment:le,model:I.model,tokenValid:x.tokenValid,sessionId:i.sessionId,runCount:j,viewMode:ke,breadcrumb:ns})]})}function Es({profiles:a,onSelect:e,onCancel:t,validating:n}){let[o,r]=(0,k.useState)(0);return He((s,m)=>{if(!n){if(m.escape){t();return}if(m.upArrow&&o>0&&r(d=>d-1),m.downArrow&&o<a.length-1&&r(d=>d+1),m.return){let d=a[o];e(d.profile,d.env)}}}),(0,y.jsxs)(b,{flexDirection:"column",paddingX:1,children:[(0,y.jsx)(l,{color:"#ff9500",bold:!0,children:"Select a profile:"}),(0,y.jsx)(b,{marginTop:1,flexDirection:"column",children:a.map((s,m)=>(0,y.jsxs)(l,{children:[m===o?"\u276F ":" ",(0,y.jsx)(l,{color:m===o?"#ff9500":"white",bold:m===o,children:s.profile}),(0,y.jsxs)(l,{color:"gray",children:[" [",s.env,"]"]})]},`${s.profile}-${s.env}`))}),n&&(0,y.jsx)(b,{marginTop:1,children:(0,y.jsx)(l,{color:"yellow",children:"Validating credentials..."})}),!n&&(0,y.jsx)(b,{marginTop:1,children:(0,y.jsx)(l,{color:"gray",children:"Esc = new login"})})]})}var Pi=H(Ii(),1),{program:Wc,createCommand:qc,createArgument:Kc,createOption:Gc,CommanderError:zc,InvalidArgumentError:Xc,InvalidOptionArgumentError:Jc,Command:Oi,Argument:Yc,Option:rt,Help:Qc}=Pi.default;import{join as ut}from"path";var Vi=H(Ye(),1);var Fe=H(Ye(),1);var vt=H(X(),1);function Di({steps:a,bifurcationInfo:e,perFlowMetadata:t}){return!e||e.isSingleFlow||!t||t.length<=1?null:(0,vt.jsx)(b,{flexDirection:"column",children:t.map((n,o)=>{let r=a[o],s=r?.children??[],m=s.filter(P=>P.status==="passed").length,d=s.filter(P=>P.status==="failed").length,u=m+d,i=s.reduce((P,h)=>P+(h.duration??0),0),c=r?.status==="failed"?"failed":"passed",_=e.flows[o]??r?.objective??`Flow ${o+1}`;return(0,vt.jsxs)(b,{flexDirection:"column",marginTop:o>0?1:0,children:[(0,vt.jsxs)(b,{marginLeft:1,children:[(0,vt.jsx)(l,{color:"#b388ff",bold:!0,children:"Flow "+(o+1)+": "}),(0,vt.jsx)(l,{color:"#b388ff",children:_})]}),(0,vt.jsx)(Nt,{status:c,summary:n?.summary??"",duration:i,steps:u,stepsPassed:m,stepsFailed:d,reason:n?.error_message??void 0,creditsConsumed:n?.credits_consumed??void 0})]},`flow-summary-${o}`)})})}var ve=H(X(),1);function ji({config:a,spawnOpts:e,cancelRef:t,banner:n,onComplete:o,onStepEnd:r,onReasoning:s,onStepComplete:m}){let{exit:d}=In(),u=Mn(r,void 0,s,m),i=(0,Fe.useRef)(!1),c=(0,Fe.useRef)(!1),[_,P]=(0,Fe.useState)("");(0,Fe.useEffect)(()=>{i.current||(i.current=!0,u.startRun(a,e))},[a,e,u]),(0,Fe.useEffect)(()=>{t&&(t.current=()=>u.cancelRun())},[t,u]);let h=(0,Fe.useRef)(0);He((A,E)=>{E.ctrl&&A==="c"&&(u.isRunning?(h.current++,h.current>=2?d():u.cancelRun()):d())}),He((A,E)=>{u.askingUser&&(E.return?(u.sendAnswer(_),P("")):E.backspace||E.delete?P(N=>N.slice(0,-1)):A&&!E.ctrl&&!E.meta&&P(N=>N+A))},{isActive:!!u.askingUser}),(0,Fe.useEffect)(()=>{if(!u.isRunning&&u.lastRunEnd&&!c.current){c.current=!0;let{passed:A,failed:E,total:N}=an(u.steps),j=u.bifurcationInfo;o({lastRunEnd:u.lastRunEnd,stepsPassed:A,stepsFailed:E,stepsTotal:N,hadError:!1,bifurcationFlows:j&&!j.isSingleFlow?j.flows:null}),d()}},[u.isRunning,u.lastRunEnd,u.steps,o,d]),(0,Fe.useEffect)(()=>{u.runError&&!u.isRunning&&!c.current&&(c.current=!0,o({lastRunEnd:null,stepsPassed:0,stepsFailed:0,stepsTotal:0,hadError:!0,bifurcationFlows:null}),d())},[u.runError,u.isRunning,o,d]);let T=u.lastRunEnd?(()=>{let{passed:A,failed:E,total:N}=an(u.steps);return{status:u.lastRunEnd.status,duration:u.lastRunEnd.duration??0,summary:u.lastRunEnd.summary??"",stepsPassed:A,stepsFailed:E,stepsTotal:N,reason:u.lastRunEnd.reason,finalState:u.lastRunEnd.final_state,creditsConsumed:u.lastRunEnd.credits_consumed}})():null,V=(0,Fe.useMemo)(()=>n?[{key:"banner",...n}]:[],[n]);return(0,ve.jsxs)(b,{flexDirection:"column",children:[(0,ve.jsx)(An,{items:V,children:A=>(0,ve.jsxs)(b,{flexDirection:"column",marginBottom:1,children:[(0,ve.jsxs)(b,{borderStyle:"round",borderColor:"#dc4e08",paddingX:2,children:[(0,ve.jsx)(l,{color:"#ff9500",bold:!0,children:"KaneAI CLI"}),(0,ve.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,ve.jsx)(l,{color:g.cyan,children:A.model}),(0,ve.jsx)(l,{color:g.dimmed,children:" \u2502 "}),(0,ve.jsx)(l,{color:g.dimmed,children:A.auth})]}),A.status?.map((E,N)=>(0,ve.jsx)(l,{color:g.dimmed,children:E},N))]},A.key)}),(()=>{let A=Dn({isRunning:u.isRunning,bifurcationInfo:u.bifurcationInfo,steps:u.steps,cmInitCounts:u.cmInitCounts,replayInfo:u.replayInfo});return A?(0,ve.jsx)(On,{label:A.label,hasBifurcation:A.hasBifurcation}):null})(),u.steps.length>0&&(0,ve.jsx)(Pn,{steps:u.steps,bifurcated:!!u.bifurcationInfo&&!u.bifurcationInfo.isSingleFlow,flows:u.bifurcationInfo?.flows,cmInitCounts:u.cmInitCounts,staticSteps:!0}),u.askingUser&&(0,ve.jsxs)(b,{flexDirection:"column",marginTop:1,children:[(0,ve.jsxs)(l,{color:g.yellow,children:['Agent is asking: "',u.askingUser,'"']}),(0,ve.jsxs)(l,{children:["> ",_,"\u2588"]})]}),u.runError&&(0,ve.jsx)(Gr,{message:u.runError,code:"RUNNER_ERROR"}),T&&u.lastRunEnd&&(0,ve.jsx)(Di,{steps:u.steps,bifurcationInfo:u.bifurcationInfo,perFlowMetadata:u.lastRunEnd.per_flow_metadata??[]}),T&&(0,ve.jsx)(Nt,{status:T.status==="passed"?"passed":"failed",summary:T.summary??"",duration:T.duration,steps:T.stepsTotal,stepsPassed:T.stepsPassed,stepsFailed:T.stepsFailed,reason:T.reason,creditsConsumed:T.creditsConsumed})]})}import{createInterface as Ns}from"readline";function Wt(a){process.stdout.write(JSON.stringify(a)+`
|
|
30
30
|
`)}async function Bi(a,e,t){let n=$r(a,e);Jn().then(c=>{c&&Wt({type:"update_available",current:c.current,latest:c.latest,severity:c.severity})}).catch(()=>{});let o=Ns({input:process.stdin});o.on("line",c=>{try{let _=JSON.parse(c);_.type==="user_response"?n.sendUserResponse(_.answer??""):_.type==="cancel"&&n.sendCancel(_.reason??"")}catch{}});let r=null,s=!1,m=0,d=null,u=0,i=!1;for await(let c of n.events)switch(c.type){case"run_start":i&&u++;break;case"step_start":{let _=c;t?.onStepLog?.("STEP_START",`Step ${_.index} started`,{index:_.index,objective:_.objective,child_id:_.child_id});let P={step:_.index+1,status:"running",remark:_.objective??`Step ${_.index+1}`};_.child_id&&(P.child_id=_.child_id),Wt(P);break}case"step_event":c.event==="reasoning"&&c.detail&&c.detail!=="reasoning"&&t?.onReasoning?.(c.detail),t?.onStepLog?.("STEP_EVENT",`Step ${c.index} ${c.event}`,{index:c.index,phase:c.event,action_type:c.action_type,detail:c.detail,child_id:c.child_id});break;case"step_end":{let _=c;t?.onStepLog?.("STEP_END",`Step ${_.index} ${_.status}`,{index:_.index,status:_.status,duration:_.duration,summary:_.summary,child_id:_.child_id}),t?.onStepComplete?.(),m++;let P={step:_.index+1,status:_.status==="passed"?"done":"failed",remark:_.summary??""};_.child_id&&(P.child_id=_.child_id),Wt(P);let h=i?Math.max(0,u-1):0;t?.onStepEnd?.(_.index,h);break}case"bifurcation":{let _=c,P=_.flows??[],h=_.count??P.length;(_.is_single_flow??h<=1)||(d=P,i=!0,u=0),Wt({type:"bifurcation",flows:P,count:h});break}case"ask_user":{let _=c;Wt({type:"ask_user",question:_.question,step_index:_.step_index,..._.options?{options:_.options}:{}});break}case"run_end":{r=c;break}case"error":{s=!0,Wt({type:"error",message:c.message});break}default:break}return o.close(),await n.exited,{lastRunEnd:r,stepsTotal:m,hadError:s,bifurcationFlows:d}}import{join as Ms}from"path";function $i(a){let e=a.command("testmd").description("Manage test.md files (run, list, status, delete, export)").action(async()=>{process.stdin.isTTY||(process.stderr.write(`error: testmd requires a sub-action in non-TTY mode (run | list | status | delete | export)
|
|
31
|
-
`),process.exit(2));let{runListTui:t,resolveCurrentOrgId:n}=await import("./testmd-actions-5O7F22EC.js"),o=await n({});o.ok||process.exit(o.code),process.exit(await t(o.orgId))});Hs(e),Ws(e),qs(e),Ks(e),Gs(e)}function Us(a,e){return e.concat(a)}function Hs(a){a.command("run <path>").description("Run a test from a *_test.md file").option("--headless","Run Chrome in headless mode").option("--max-steps <n>","Max agent steps","30").option("--timeout <seconds>","Kill after N seconds").option("--cdp-endpoint <url>","Connect to existing Chrome via CDP").option("--ws-endpoint <url>","Playwright WebSocket endpoint").option("--global-context <file>",`Override global context (default: ${Ms(xe,"global-memory.md")})`).option("--local-context <file>","Override local context (default: .testmuai/context.md in cwd)").addOption(new rt("--model <name>","Model override").hideHelp()).option("--variables <json>","Inline variables JSON").option("--variables-file <path>","Load variables from file").option("--session-context <json>","Session context JSON (prior runs)").addOption(new rt("--cft","Use Playwright Chromium instead of managed Chrome").hideHelp()).option("--username <user>","Basic auth username (skip OAuth)").option("--access-key <key>","Basic auth access key").option("--env <name>","Environment (prod or stage)").option("--mode <name>","Run mode: action | testing").option("--agent","Agent mode: plain NDJSON output, no colors/UI").option("--task-skills","Enable domain-specific task skills (experimental)").addOption(new rt("--local","Skip TMS integration (no uploads, no variables/secrets push)").hideHelp()).option("--code-export","Generate code export after upload").option("--code-language <lang>","Code-export language (python|javascript)").option("--name <name>","Persist session under this name").option("--skip-code-validation","Skip post-codegen validation").option("--no-skip-code-validation","Force post-codegen validation").option("--on-lock-conflict <mode>","lock conflict policy: readonly|fail|wait",e=>{if(e!=="readonly"&&e!=="fail"&&e!=="wait")throw new Error(`--on-lock-conflict must be readonly|fail|wait, got: ${e}`);return e}).option("--push","always commit at end-of-run (no retry semantics)").option("--retry","on replay failure, full-restart with shrinking replay window; falls back to complete re-author after --retry-count attempts").option("--retry-count <n>","max replay restart attempts before falling back to complete re-author (default: 3)",e=>{let t=parseInt(e,10);if(Number.isNaN(t)||t<0)throw new Error(`--retry-count must be a non-negative integer, got: ${e}`);return e}).option("--author","bypass walker; force fresh test+testcase in TMS; replace local output entirely").action(async(e,t)=>{let{runTestMdFile:n}=await import("./run-test-md-IAEJXIVK.js"),o=await n(e,t);process.exit(o)})}function Ws(a){a.command("list").description("List *_test.md files in the working directory (recursive)").option("--root <dir>","Root directory to scan (default: cwd)").option("--ignore <name>","Skip a directory by name (repeatable)",Us,[]).option("--json","Force NDJSON output even on TTY").action(async e=>{let{runListAction:t,resolveCurrentOrgId:n}=await import("./testmd-actions-5O7F22EC.js"),o=await n({json:!!e.json});o.ok||process.exit(o.code),process.exit(await t(e,o.orgId))})}function qs(a){a.command("status <path>").description("Print local meta.json for a *_test.md (no live TMS check in v1)").action(async e=>{let{runStatusAction:t,resolveCurrentOrgId:n}=await import("./testmd-actions-5O7F22EC.js"),o=await n({});o.ok||process.exit(o.code),process.exit(await t(e,o.orgId))})}function Ks(a){a.command("delete <path>").description("Remove output-<stem>/ and the *_test.md source file (TMS untouched)").option("--yes","Skip confirmation prompt (required in non-TTY)").action(async(e,t)=>{let{runDeleteAction:n,resolveCurrentOrgId:o}=await import("./testmd-actions-5O7F22EC.js"),r=await o({});r.ok||process.exit(r.code),process.exit(await n(e,!!t.yes,r.orgId))})}function Gs(a){a.command("export <path>").description("Generate standalone test code (Playwright)").option("--language <lang>","python|javascript (falls back to tui-config)").option("--output <dir>","Override output dir (default: output-<stem>/playwright-<lang>-code/)").option("--force","Overwrite an existing local export").action(async(e,t)=>{let{runExportAction:n,resolveCurrentOrgId:o}=await import("./testmd-actions-5O7F22EC.js"),r=await o({});r.ok||process.exit(r.code),process.exit(await n(e,t,r.orgId))})}function qt(a){let e=new Oi;if(e.name("kane-cli").version(st).showHelpAfterError("(run `kane-cli --help` to see all commands; `-h` and `help` also work)"),e.on("command:*",n=>{e.error(`error: unknown command '${n[0]}'`,{exitCode:2,code:"commander.unknownCommand"})}),a[0]==="--help"||a[0]==="-h"||a[0]==="help"){(async()=>{let{HelpView:n}=await import("./HelpView-MUIOT5UN.js"),{render:o}=await import("./build-JIKYOZUH.js"),r=await import("./react-QWOAB3TB.js"),{waitUntilExit:s}=o(r.default.createElement(n));await s(),q(0,"Help displayed")})();return}e.command("login").option("--oauth","Login via OAuth (opens browser)").option("--username <user>","Basic auth username").option("--access-key <key>","Basic auth access key").addOption(new rt("--env <name>","Environment (prod or stage)").default("prod").hideHelp()).option("--profile <name>","Profile name","default").option("--project-id <id>","Project ID (skip picker)").option("--folder-id <id>","Folder ID (skip picker)").addOption(new rt("--model <name>","Model").default("v16-alpha").hideHelp()).option("--chrome-profile <path>","Chrome profile path").action(async n=>{let o=new Le,r=new Be,s=n.env,m=n.profile;if(!process.stdin.isTTY||n.oauth||n.username){if(o.setDefaultEnv(s),n.oauth)await new $n(m,s,o).login(),console.log(`Logged in as ${m} [${s}] via OAuth`);else if(n.username&&n.accessKey){try{let{validateBasicAuth:V}=await import("./validate-basic-NIEIKFGP.js");await V(s,n.username,n.accessKey)}catch{console.error("Credentials not valid. Please use valid credentials."),q(1,"Invalid basic-auth credentials");return}o.saveBasicAuth(m,s,{username:n.username,access_key:n.accessKey}),console.log(`Logged in as ${m} [${s}] via basic auth`)}else console.error("Provide --oauth, or --username and --access-key"),q(1,"Missing --oauth or credentials for login");o.setActiveProfile(m),r.set("model",n.model),n.chromeProfile&&r.set("chrome_profile_path",n.chromeProfile);let T=null;if(n.username&&n.accessKey)T={username:n.username,access_key:n.accessKey};else try{let A=await Oo({creds:o,env:s,log:()=>{}});A.resolvedCreds&&(T={username:A.resolvedCreds.username,access_key:A.resolvedCreds.access_key})}catch{}if(n.projectId&&(he(o,r,m,s,{projectId:n.projectId}),console.log(`Project set to ${n.projectId}`)),n.folderId&&(he(o,r,m,s,{folderId:n.folderId}),console.log(`Folder set to ${n.folderId}`)),T&&(!n.projectId||!n.folderId))try{let V=await Do({creds:o,config:r,profile:m,env:s,tmsCreds:T,log:()=>{}});n.projectId||console.log(`Auto-selected project: ${V.projectName} (${V.projectId})`),n.folderId||console.log(`Auto-selected folder: ${V.folderName} (${V.folderId})`)}catch(V){console.warn(`Could not auto-select project/folder: ${V instanceof Error?V.message:V}`)}Te(o,r,m,s),console.log("Setup complete."),q(0,"Setup complete")}let{SingleShotApp:d}=await import("./SingleShotApp-N4AGSAPW.js"),{render:u}=await import("./build-JIKYOZUH.js"),i=await import("./react-QWOAB3TB.js"),c={current:null},_={current:!1},{waitUntilExit:P,unmount:h}=u(i.default.createElement(d,{resultRef:c,mode:"login",loginCompleteRef:_}),{exitOnCtrlC:!1});sn(()=>h()),await P();try{process.stdin.setRawMode?.(!1)}catch{}process.stdout.write("\x1B[?25h"),_.current&&console.log("Login setup complete."),process.exit(0)}),e.command("logout").action(async()=>{let n=new Le,o=n.getActiveProfile();if(!o){console.log("No active profile to logout");return}let r=n.getDefaultEnv(),s=await Zn(n,o,r),m=new Be;s.switchedTo?(Te(n,m,s.switchedTo.profile,s.switchedTo.env),console.log(`Logged out ${s.profile} [${s.env}]. Switched to ${s.switchedTo.profile} [${s.switchedTo.env}]`)):(m.save({project_id:null,project_name:null,folder_id:null,folder_name:null}),console.log(`Logged out ${s.profile} [${s.env}]. No profiles remaining.`))}),e.command("whoami").option("--profile <name>","Profile name").action(async n=>{let o=new Le,r=n.profile??o.getActiveProfile()??"default",s=o.getDefaultEnv(),m=o.loadCredentials(r,s),d=o.loadBasicAuth(r,s),u="none",i,c,_;if(d)u="basic",i=d.username;else if(m){u="oauth";let A=m.expires_at,E=Date.now()/1e3;c=A>E?"valid":"expired",_=new Date(A*1e3).toISOString().slice(0,10)}else c="missing";let{WhoamiView:P}=await import("./WhoamiView-ZZUFXKDU.js"),{render:h}=await import("./build-JIKYOZUH.js"),T=await import("./react-QWOAB3TB.js"),{waitUntilExit:V}=h(T.default.createElement(P,{profile:r,env:s,authenticated:u!=="none",authMethod:u,username:i,tokenStatus:c,expiresAt:_}));await V()}),e.command("config <action> [value]").action(async(n,o)=>{let r=new Be,s=new Le;if(n==="show"){let m=r.load(),d=s.getActiveProfile()??"default",u=s.getDefaultEnv(),i=s.loadBasicAuth(d,u),c=s.loadCredentials(d,u),_=i?`basic (${i.username})`:c?"oauth":"not configured",{ConfigView:P}=await import("./ConfigView-BSIS2LOH.js"),{render:h}=await import("./build-JIKYOZUH.js"),T=await import("./react-QWOAB3TB.js"),{waitUntilExit:V}=h(T.default.createElement(P,{model:m.model,authLabel:_,profile:d,env:u,defaultUrl:at,projectId:m.project_id,projectName:m.project_name,folderId:m.folder_id,windowSize:`${m.window_size.width}x${m.window_size.height}`,chromeProfile:m.chrome_profile_path}));await V()}else if(n==="set-window"&&o){let m=o.split("x").map(Number),[d,u]=m;!d||!u||!Number.isInteger(d)||!Number.isInteger(u)?console.error("Invalid format. Use: kane-cli config set-window WIDTHxHEIGHT"):d<800||d>3840?console.error(`Width must be between 800 and 3840 (got ${d})`):u<600||u>2160?console.error(`Height must be between 600 and 2160 (got ${u})`):(r.set("window_size",{width:d,height:u}),console.log(`Window size set to ${d}x${u}`))}else if(n==="set-mode"){if(o!=="action"&&o!=="testing"){console.error("Mode must be 'action' or 'testing'."),q(1,"Invalid mode");return}r.set("mode",o),console.log(`Mode set to ${o}`)}else if(n==="chrome-profile"){if(o||!process.stdin.isTTY){o||(console.error("Usage: kane-cli config chrome-profile <path>"),q(1,"Missing chrome-profile path")),r.set("chrome_profile_path",o),console.log(`Chrome profile set to ${o}`);return}let{ChromeProfilePicker:m}=await import("./ChromeProfilePicker-ETBZA64A.js"),{render:d}=await import("./build-JIKYOZUH.js"),u=await import("./react-QWOAB3TB.js");await new Promise(i=>{let{unmount:c}=d(u.default.createElement(m,{currentPath:r.load().chrome_profile_path,onSelect:_=>{r.set("chrome_profile_path",_),console.log(`Chrome profile set to ${_}`),c(),i()},onCancel:()=>{c(),i()}}))})}else if(n==="project"){if(o||!process.stdin.isTTY){o||(console.error("Usage: kane-cli config project <project-id>"),q(1,"Missing project ID"));let T=s.getActiveProfile()??"default",V=s.getDefaultEnv();he(s,r,T,V,{projectId:o}),console.log(`Project set to ${o}`);return}let m=s.getDefaultEnv(),d=me(m),u=s.loadBasicAuth(s.getActiveProfile()??"default",m);if(!u){console.log("Login first to browse projects");return}let{ProjectPicker:i}=await import("./ProjectPicker-5ZPZNRSS.js"),{AuthResolver:c}=await import("./resolver-F6HCOZOX.js"),{render:_}=await import("./build-JIKYOZUH.js"),P=await import("./react-QWOAB3TB.js"),h=new c(d.controllerBaseUrl,async()=>null,u);await h.resolve(),await new Promise(T=>{let{unmount:V}=_(P.default.createElement(i,{resolver:h,currentProjectId:r.load().project_id,env:m,onSelect:(A,E)=>{let N=s.getActiveProfile()??"default",j=s.getDefaultEnv();he(s,r,N,j,{projectId:A,projectName:E}),console.log(`Project set to ${E} (${A})`),V(),T()},onCancel:()=>{V(),T()}}))})}else if(n==="folder"){if(o||!process.stdin.isTTY){if(o||(console.error("Usage: kane-cli config folder <folder-id>"),q(1,"Missing folder ID")),!r.load().project_id){console.log("Select a project first: kane-cli config project <id>");return}let A=s.getActiveProfile()??"default",E=s.getDefaultEnv();he(s,r,A,E,{folderId:o}),console.log(`Folder set to ${o}`);return}let m=r.load();if(!m.project_id){console.log("Select a project first: kane-cli config project");return}let d=s.getDefaultEnv(),u=me(d),i=s.loadBasicAuth(s.getActiveProfile()??"default",d);if(!i){console.log("Login first to browse folders");return}let{FolderPicker:c}=await import("./FolderPicker-7FXP3PIM.js"),{AuthResolver:_}=await import("./resolver-F6HCOZOX.js"),{render:P}=await import("./build-JIKYOZUH.js"),h=await import("./react-QWOAB3TB.js"),T=new _(u.controllerBaseUrl,async()=>null,i);await T.resolve(),await new Promise(V=>{let{unmount:A}=P(h.default.createElement(c,{resolver:T,projectId:m.project_id,currentFolderId:m.folder_id,env:d,onSelect:(E,N)=>{let j=s.getActiveProfile()??"default",W=s.getDefaultEnv();he(s,r,j,W,{folderId:E,folderName:N}),console.log(`Folder set to ${N} (${E})`),A(),V()},onCancel:()=>{A(),V()}}))})}else console.log("Usage: kane-cli config show|set-window|set-mode|chrome-profile|project|folder")}),e.command("run").argument("<objective>","Test objective (use {{var}} to reference variables)").option("--headless","Run Chrome in headless mode").option("--max-steps <n>","Maximum agent steps","30").option("--timeout <seconds>","Kill run after N seconds").option("--cdp-endpoint <url>","Connect to existing Chrome CDP endpoint").option("--ws-endpoint <url>","Connect via Playwright WebSocket (e.g. LambdaTest wss:// URL)").option("--global-context <file>",`Override global context markdown (default: ${ut(xe,"global-memory.md")})`).option("--local-context <file>","Override local context markdown (default: .testmuai/context.md in cwd)").addOption(new rt("--model <name>","Model override").hideHelp()).option("--variables <json>",`Inline variables JSON, e.g. '{"user": {"value": "alice"}}'`).option("--variables-file <path>","Load variables from a JSON file").option("--session-context <json>","Session context JSON (prior runs)").addOption(new rt("--cft","Use Playwright Chromium instead of managed Chrome").hideHelp()).option("--username <user>","Basic auth username (skip OAuth)").option("--access-key <key>","Basic auth access key (skip OAuth)").option("--env <name>","Environment (prod or stage)").option("--mode <name>","Run mode: 'action' (strict \u2014 hard-stop on auth/blocked/error) or 'testing' (lenient \u2014 fall through). Overrides config; default: testing.").option("--agent","Agent mode: plain NDJSON output, no colors/UI").option("--task-skills","Enable domain-specific task skills (experimental)").addOption(new rt("--local","Skip TMS integration (no uploads, no variables/secrets push)").hideHelp()).option("--code-export","Generate code export after upload").option("--code-language <lang>","Code export language: python (default) | javascript").option("--name <name>","Persist the session under this name (validated [a-zA-Z0-9_-]+)").option("--skip-code-validation","Skip post-codegen worker-side validation").option("--no-skip-code-validation","Force post-codegen worker-side validation").addHelpText("after",`
|
|
31
|
+
`),process.exit(2));let{runListTui:t,resolveCurrentOrgId:n}=await import("./testmd-actions-322GQYAH.js"),o=await n({});o.ok||process.exit(o.code),process.exit(await t(o.orgId))});Hs(e),Ws(e),qs(e),Ks(e),Gs(e)}function Us(a,e){return e.concat(a)}function Hs(a){a.command("run <path>").description("Run a test from a *_test.md file").option("--headless","Run Chrome in headless mode").option("--max-steps <n>","Max agent steps","30").option("--timeout <seconds>","Kill after N seconds").option("--cdp-endpoint <url>","Connect to existing Chrome via CDP").option("--ws-endpoint <url>","Playwright WebSocket endpoint").option("--global-context <file>",`Override global context (default: ${Ms(xe,"global-memory.md")})`).option("--local-context <file>","Override local context (default: .testmuai/context.md in cwd)").addOption(new rt("--model <name>","Model override").hideHelp()).option("--variables <json>","Inline variables JSON").option("--variables-file <path>","Load variables from file").option("--session-context <json>","Session context JSON (prior runs)").addOption(new rt("--cft","Use Playwright Chromium instead of managed Chrome").hideHelp()).option("--username <user>","Basic auth username (skip OAuth)").option("--access-key <key>","Basic auth access key").option("--env <name>","Environment (prod or stage)").option("--mode <name>","Run mode: action | testing").option("--agent","Agent mode: plain NDJSON output, no colors/UI").option("--task-skills","Enable domain-specific task skills (experimental)").addOption(new rt("--local","Skip TMS integration (no uploads, no variables/secrets push)").hideHelp()).option("--code-export","Generate code export after upload").option("--code-language <lang>","Code-export language (python|javascript)").option("--name <name>","Persist session under this name").option("--skip-code-validation","Skip post-codegen validation").option("--no-skip-code-validation","Force post-codegen validation").option("--on-lock-conflict <mode>","lock conflict policy: readonly|fail|wait",e=>{if(e!=="readonly"&&e!=="fail"&&e!=="wait")throw new Error(`--on-lock-conflict must be readonly|fail|wait, got: ${e}`);return e}).option("--push","always commit at end-of-run (no retry semantics)").option("--retry","on replay failure, full-restart with shrinking replay window; falls back to complete re-author after --retry-count attempts").option("--retry-count <n>","max replay restart attempts before falling back to complete re-author (default: 3)",e=>{let t=parseInt(e,10);if(Number.isNaN(t)||t<0)throw new Error(`--retry-count must be a non-negative integer, got: ${e}`);return e}).option("--author","bypass walker; force fresh test+testcase in TMS; replace local output entirely").action(async(e,t)=>{let{runTestMdFile:n}=await import("./run-test-md-BQS5SZ7E.js"),o=await n(e,t);process.exit(o)})}function Ws(a){a.command("list").description("List *_test.md files in the working directory (recursive)").option("--root <dir>","Root directory to scan (default: cwd)").option("--ignore <name>","Skip a directory by name (repeatable)",Us,[]).option("--json","Force NDJSON output even on TTY").action(async e=>{let{runListAction:t,resolveCurrentOrgId:n}=await import("./testmd-actions-322GQYAH.js"),o=await n({json:!!e.json});o.ok||process.exit(o.code),process.exit(await t(e,o.orgId))})}function qs(a){a.command("status <path>").description("Print local meta.json for a *_test.md (no live TMS check in v1)").action(async e=>{let{runStatusAction:t,resolveCurrentOrgId:n}=await import("./testmd-actions-322GQYAH.js"),o=await n({});o.ok||process.exit(o.code),process.exit(await t(e,o.orgId))})}function Ks(a){a.command("delete <path>").description("Remove output-<stem>/ and the *_test.md source file (TMS untouched)").option("--yes","Skip confirmation prompt (required in non-TTY)").action(async(e,t)=>{let{runDeleteAction:n,resolveCurrentOrgId:o}=await import("./testmd-actions-322GQYAH.js"),r=await o({});r.ok||process.exit(r.code),process.exit(await n(e,!!t.yes,r.orgId))})}function Gs(a){a.command("export <path>").description("Generate standalone test code (Playwright)").option("--language <lang>","python|javascript (falls back to tui-config)").option("--output <dir>","Override output dir (default: output-<stem>/playwright-<lang>-code/)").option("--force","Overwrite an existing local export").action(async(e,t)=>{let{runExportAction:n,resolveCurrentOrgId:o}=await import("./testmd-actions-322GQYAH.js"),r=await o({});r.ok||process.exit(r.code),process.exit(await n(e,t,r.orgId))})}function qt(a){let e=new Oi;if(e.name("kane-cli").version(st).showHelpAfterError("(run `kane-cli --help` to see all commands; `-h` and `help` also work)"),e.on("command:*",n=>{e.error(`error: unknown command '${n[0]}'`,{exitCode:2,code:"commander.unknownCommand"})}),a[0]==="--help"||a[0]==="-h"||a[0]==="help"){(async()=>{let{HelpView:n}=await import("./HelpView-3ESCWBPB.js"),{render:o}=await import("./build-JIKYOZUH.js"),r=await import("./react-QWOAB3TB.js"),{waitUntilExit:s}=o(r.default.createElement(n));await s(),q(0,"Help displayed")})();return}e.command("login").option("--oauth","Login via OAuth (opens browser)").option("--username <user>","Basic auth username").option("--access-key <key>","Basic auth access key").addOption(new rt("--env <name>","Environment (prod or stage)").default("prod").hideHelp()).option("--profile <name>","Profile name","default").option("--project-id <id>","Project ID (skip picker)").option("--folder-id <id>","Folder ID (skip picker)").addOption(new rt("--model <name>","Model").default("v16-alpha").hideHelp()).option("--chrome-profile <path>","Chrome profile path").action(async n=>{let o=new Le,r=new Be,s=n.env,m=n.profile;if(!process.stdin.isTTY||n.oauth||n.username){if(o.setDefaultEnv(s),n.oauth)await new $n(m,s,o).login(),console.log(`Logged in as ${m} [${s}] via OAuth`);else if(n.username&&n.accessKey){try{let{validateBasicAuth:V}=await import("./validate-basic-XKTSGLFO.js");await V(s,n.username,n.accessKey)}catch{console.error("Credentials not valid. Please use valid credentials."),q(1,"Invalid basic-auth credentials");return}o.saveBasicAuth(m,s,{username:n.username,access_key:n.accessKey}),console.log(`Logged in as ${m} [${s}] via basic auth`)}else console.error("Provide --oauth, or --username and --access-key"),q(1,"Missing --oauth or credentials for login");o.setActiveProfile(m),r.set("model",n.model),n.chromeProfile&&r.set("chrome_profile_path",n.chromeProfile);let T=null;if(n.username&&n.accessKey)T={username:n.username,access_key:n.accessKey};else try{let A=await Oo({creds:o,env:s,log:()=>{}});A.resolvedCreds&&(T={username:A.resolvedCreds.username,access_key:A.resolvedCreds.access_key})}catch{}if(n.projectId&&(he(o,r,m,s,{projectId:n.projectId}),console.log(`Project set to ${n.projectId}`)),n.folderId&&(he(o,r,m,s,{folderId:n.folderId}),console.log(`Folder set to ${n.folderId}`)),T&&(!n.projectId||!n.folderId))try{let V=await Do({creds:o,config:r,profile:m,env:s,tmsCreds:T,log:()=>{}});n.projectId||console.log(`Auto-selected project: ${V.projectName} (${V.projectId})`),n.folderId||console.log(`Auto-selected folder: ${V.folderName} (${V.folderId})`)}catch(V){console.warn(`Could not auto-select project/folder: ${V instanceof Error?V.message:V}`)}Te(o,r,m,s),console.log("Setup complete."),q(0,"Setup complete")}let{SingleShotApp:d}=await import("./SingleShotApp-WOJWOQSV.js"),{render:u}=await import("./build-JIKYOZUH.js"),i=await import("./react-QWOAB3TB.js"),c={current:null},_={current:!1},{waitUntilExit:P,unmount:h}=u(i.default.createElement(d,{resultRef:c,mode:"login",loginCompleteRef:_}),{exitOnCtrlC:!1});sn(()=>h()),await P();try{process.stdin.setRawMode?.(!1)}catch{}process.stdout.write("\x1B[?25h"),_.current&&console.log("Login setup complete."),process.exit(0)}),e.command("logout").action(async()=>{let n=new Le,o=n.getActiveProfile();if(!o){console.log("No active profile to logout");return}let r=n.getDefaultEnv(),s=await Zn(n,o,r),m=new Be;s.switchedTo?(Te(n,m,s.switchedTo.profile,s.switchedTo.env),console.log(`Logged out ${s.profile} [${s.env}]. Switched to ${s.switchedTo.profile} [${s.switchedTo.env}]`)):(m.save({project_id:null,project_name:null,folder_id:null,folder_name:null}),console.log(`Logged out ${s.profile} [${s.env}]. No profiles remaining.`))}),e.command("whoami").option("--profile <name>","Profile name").action(async n=>{let o=new Le,r=n.profile??o.getActiveProfile()??"default",s=o.getDefaultEnv(),m=o.loadCredentials(r,s),d=o.loadBasicAuth(r,s),u="none",i,c,_;if(d)u="basic",i=d.username;else if(m){u="oauth";let A=m.expires_at,E=Date.now()/1e3;c=A>E?"valid":"expired",_=new Date(A*1e3).toISOString().slice(0,10)}else c="missing";let{WhoamiView:P}=await import("./WhoamiView-VJBEYTCF.js"),{render:h}=await import("./build-JIKYOZUH.js"),T=await import("./react-QWOAB3TB.js"),{waitUntilExit:V}=h(T.default.createElement(P,{profile:r,env:s,authenticated:u!=="none",authMethod:u,username:i,tokenStatus:c,expiresAt:_}));await V()}),e.command("config <action> [value]").action(async(n,o)=>{let r=new Be,s=new Le;if(n==="show"){let m=r.load(),d=s.getActiveProfile()??"default",u=s.getDefaultEnv(),i=s.loadBasicAuth(d,u),c=s.loadCredentials(d,u),_=i?`basic (${i.username})`:c?"oauth":"not configured",{ConfigView:P}=await import("./ConfigView-5ZCHVYM2.js"),{render:h}=await import("./build-JIKYOZUH.js"),T=await import("./react-QWOAB3TB.js"),{waitUntilExit:V}=h(T.default.createElement(P,{model:m.model,authLabel:_,profile:d,env:u,defaultUrl:at,projectId:m.project_id,projectName:m.project_name,folderId:m.folder_id,windowSize:`${m.window_size.width}x${m.window_size.height}`,chromeProfile:m.chrome_profile_path}));await V()}else if(n==="set-window"&&o){let m=o.split("x").map(Number),[d,u]=m;!d||!u||!Number.isInteger(d)||!Number.isInteger(u)?console.error("Invalid format. Use: kane-cli config set-window WIDTHxHEIGHT"):d<800||d>3840?console.error(`Width must be between 800 and 3840 (got ${d})`):u<600||u>2160?console.error(`Height must be between 600 and 2160 (got ${u})`):(r.set("window_size",{width:d,height:u}),console.log(`Window size set to ${d}x${u}`))}else if(n==="set-mode"){if(o!=="action"&&o!=="testing"){console.error("Mode must be 'action' or 'testing'."),q(1,"Invalid mode");return}r.set("mode",o),console.log(`Mode set to ${o}`)}else if(n==="chrome-profile"){if(o||!process.stdin.isTTY){o||(console.error("Usage: kane-cli config chrome-profile <path>"),q(1,"Missing chrome-profile path")),r.set("chrome_profile_path",o),console.log(`Chrome profile set to ${o}`);return}let{ChromeProfilePicker:m}=await import("./ChromeProfilePicker-J6QIIHIE.js"),{render:d}=await import("./build-JIKYOZUH.js"),u=await import("./react-QWOAB3TB.js");await new Promise(i=>{let{unmount:c}=d(u.default.createElement(m,{currentPath:r.load().chrome_profile_path,onSelect:_=>{r.set("chrome_profile_path",_),console.log(`Chrome profile set to ${_}`),c(),i()},onCancel:()=>{c(),i()}}))})}else if(n==="project"){if(o||!process.stdin.isTTY){o||(console.error("Usage: kane-cli config project <project-id>"),q(1,"Missing project ID"));let T=s.getActiveProfile()??"default",V=s.getDefaultEnv();he(s,r,T,V,{projectId:o}),console.log(`Project set to ${o}`);return}let m=s.getDefaultEnv(),d=me(m),u=s.loadBasicAuth(s.getActiveProfile()??"default",m);if(!u){console.log("Login first to browse projects");return}let{ProjectPicker:i}=await import("./ProjectPicker-NJKUWRET.js"),{AuthResolver:c}=await import("./resolver-F6HCOZOX.js"),{render:_}=await import("./build-JIKYOZUH.js"),P=await import("./react-QWOAB3TB.js"),h=new c(d.controllerBaseUrl,async()=>null,u);await h.resolve(),await new Promise(T=>{let{unmount:V}=_(P.default.createElement(i,{resolver:h,currentProjectId:r.load().project_id,env:m,onSelect:(A,E)=>{let N=s.getActiveProfile()??"default",j=s.getDefaultEnv();he(s,r,N,j,{projectId:A,projectName:E}),console.log(`Project set to ${E} (${A})`),V(),T()},onCancel:()=>{V(),T()}}))})}else if(n==="folder"){if(o||!process.stdin.isTTY){if(o||(console.error("Usage: kane-cli config folder <folder-id>"),q(1,"Missing folder ID")),!r.load().project_id){console.log("Select a project first: kane-cli config project <id>");return}let A=s.getActiveProfile()??"default",E=s.getDefaultEnv();he(s,r,A,E,{folderId:o}),console.log(`Folder set to ${o}`);return}let m=r.load();if(!m.project_id){console.log("Select a project first: kane-cli config project");return}let d=s.getDefaultEnv(),u=me(d),i=s.loadBasicAuth(s.getActiveProfile()??"default",d);if(!i){console.log("Login first to browse folders");return}let{FolderPicker:c}=await import("./FolderPicker-VYJDEDN7.js"),{AuthResolver:_}=await import("./resolver-F6HCOZOX.js"),{render:P}=await import("./build-JIKYOZUH.js"),h=await import("./react-QWOAB3TB.js"),T=new _(u.controllerBaseUrl,async()=>null,i);await T.resolve(),await new Promise(V=>{let{unmount:A}=P(h.default.createElement(c,{resolver:T,projectId:m.project_id,currentFolderId:m.folder_id,env:d,onSelect:(E,N)=>{let j=s.getActiveProfile()??"default",W=s.getDefaultEnv();he(s,r,j,W,{folderId:E,folderName:N}),console.log(`Folder set to ${N} (${E})`),A(),V()},onCancel:()=>{A(),V()}}))})}else console.log("Usage: kane-cli config show|set-window|set-mode|chrome-profile|project|folder")}),e.command("run").argument("<objective>","Test objective (use {{var}} to reference variables)").option("--headless","Run Chrome in headless mode").option("--max-steps <n>","Maximum agent steps","30").option("--timeout <seconds>","Kill run after N seconds").option("--cdp-endpoint <url>","Connect to existing Chrome CDP endpoint").option("--ws-endpoint <url>","Connect via Playwright WebSocket (e.g. LambdaTest wss:// URL)").option("--global-context <file>",`Override global context markdown (default: ${ut(xe,"global-memory.md")})`).option("--local-context <file>","Override local context markdown (default: .testmuai/context.md in cwd)").addOption(new rt("--model <name>","Model override").hideHelp()).option("--variables <json>",`Inline variables JSON, e.g. '{"user": {"value": "alice"}}'`).option("--variables-file <path>","Load variables from a JSON file").option("--session-context <json>","Session context JSON (prior runs)").addOption(new rt("--cft","Use Playwright Chromium instead of managed Chrome").hideHelp()).option("--username <user>","Basic auth username (skip OAuth)").option("--access-key <key>","Basic auth access key (skip OAuth)").option("--env <name>","Environment (prod or stage)").option("--mode <name>","Run mode: 'action' (strict \u2014 hard-stop on auth/blocked/error) or 'testing' (lenient \u2014 fall through). Overrides config; default: testing.").option("--agent","Agent mode: plain NDJSON output, no colors/UI").option("--task-skills","Enable domain-specific task skills (experimental)").addOption(new rt("--local","Skip TMS integration (no uploads, no variables/secrets push)").hideHelp()).option("--code-export","Generate code export after upload").option("--code-language <lang>","Code export language: python (default) | javascript").option("--name <name>","Persist the session under this name (validated [a-zA-Z0-9_-]+)").option("--skip-code-validation","Skip post-codegen worker-side validation").option("--no-skip-code-validation","Force post-codegen worker-side validation").addHelpText("after",`
|
|
32
32
|
Variables:
|
|
33
33
|
Variables are loaded in order (later wins):
|
|
34
34
|
1. Global: ${ut(xe,"variables")}/*.json
|
|
@@ -52,9 +52,9 @@ Context Files:
|
|
|
52
52
|
Override with --global-context / --local-context flags.
|
|
53
53
|
`).action(async(n,o)=>{try{if(o.name){let{validateNameOrThrow:D}=await import("./name-validator-5YGJXLZ7.js");try{D(o.name)}catch(M){console.error(`error: ${M.message}`),q(2,"Invalid --name");return}}n&&n.endsWith(".md")&&!n.startsWith("-")&&(process.stderr.write(`error: '.md' files are no longer accepted by 'kane run'.
|
|
54
54
|
Use 'kane-cli testmd run <path>' instead.
|
|
55
|
-
`),process.exit(2));let r=new Le,s=new Be,m=s.load(),d;if(o.mode===void 0)d=m.mode==="action"?"action":"testing";else if(o.mode==="action"||o.mode==="testing")d=o.mode;else{console.error("Invalid --mode. Must be 'action' or 'testing'."),q(2,"Invalid --mode");return}let u=new nn,{printRecordingBanner:i}=await import("./recording-banner-
|
|
56
|
-
`)};Ie?.setRunActive(!0);let M;try{M=await Bi(_t,{environment:h,mode:d,log:(oe,ae,Pe,Ue)=>L.log(oe,ae,Pe,Ue)},{onStepEnd:zt,onStepLog:(oe,ae,Pe)=>L.logStep(oe,ae,Pe),onReasoning:oe=>Ie?.setStepText(oe),onStepComplete:()=>Ie?.setStepComplete()})}finally{Ie?.setRunActive(!1)}let{lastRunEnd:G,stepsTotal:Y,hadError:$e,bifurcationFlows:Q}=M;if($e&&L.escalateRun(0),G){let oe=on(G,0,Q);L.addRunResult(rn(G,te.auteurObjective,0,oe),G.total_runs);let ae=G.status==="passed"?"passed":$e?"error":"failed";L.addFlow({runIndex:0,objective:te.auteurObjective,status:ae,summary:G.summary??"",duration:G.duration??0,steps:Y,stepsPassed:ae==="passed"?Y:0,stepsFailed:ae==="passed"?0:Y,reason:G.reason,creditsConsumed:G.credits_consumed})}Rt("chrome","Agent run completed");let se;if(L.log("info","DIRECT_UPLOAD_START","Starting direct upload (agent mode)",{agent_mode:!0,last_run_end:!!G,local:!!o.local}),G&&!o.local)try{let oe=me(h),ae=ie.project_id;if(E.basicAuth){let{UploadPipeline:Pe}=await import("./pipeline-EUZIM2ZO.js");Ke&&await Ke.drain();let Ue=cn({session:L,env:h,auth:E,variables:te,variableIds:bn,projectId:ae,folderId:ie.folder_id,totalSteps:Y,totalDuration:G.duration??0,codeExport:dn({codeExport:o.codeExport,codeLanguage:o.codeLanguage,skipCodeValidation:o.skipCodeValidation},m.code_export),onProgress:()=>{},log:(ke,Yt,Ge,Ot)=>L.log(ke,Yt,Ge,Ot),shouldUploadArtifacts:!o.local,shouldReplaceLocalOutput:!1,shouldCommit:!1,isFirstRun:!0}),Oe=await new Pe(Ue).execute();Oe.success&&(Oe.testcaseId&&L.setTestcaseId(Oe.testcaseId),Oe.testcaseId&&Oe.shareId&&ae&&(se=At(oe.testManagerUiUrl,ae,Oe.testcaseId,Oe.shareId)));try{let{persistRecordedSession:ke}=await import("./persist-recorded-session-
|
|
57
|
-
Timeout: ${o.timeout}s exceeded \u2014 cancelling...`),Me.current?.()},D)}Ie?.setRunActive(!0);try{await yt()}finally{Ie?.setRunActive(!1)}if(Jt&&clearTimeout(Jt),pe){let D=on(pe,0,it);L.addRunResult(rn(pe,te.auteurObjective,0,D),pe.total_runs);let M=pe.status==="passed"?"passed":Xt?"error":"failed";L.addFlow({runIndex:0,objective:te.auteurObjective,status:M,summary:pe.summary??"",duration:pe.duration??0,steps:ft,stepsPassed:M==="passed"?ft:0,stepsFailed:M==="passed"?0:ft,reason:pe.reason,creditsConsumed:pe.credits_consumed})}if(Rt("chrome","Ink run completed"),L.log("info","DIRECT_UPLOAD_START","Starting direct upload (ink mode)",{ink_mode:!0,last_event:!!pe,local:!!o.local}),pe&&!o.local)try{let D=me(h),M=ie.project_id;if(E.basicAuth){let{UploadPipeline:G}=await import("./pipeline-EUZIM2ZO.js");Ke&&(L.log("info","SCREENSHOT_UPLOAD_DRAIN","Draining screenshot upload queue before pipeline"),await Ke.drain(),L.log("info","SCREENSHOT_UPLOAD_DRAINED","Screenshot upload queue drained"));let Y=cn({session:L,env:h,auth:E,variables:te,variableIds:bn,projectId:ie.project_id,folderId:ie.folder_id,totalSteps:ft,totalDuration:pe.duration??0,codeExport:dn({codeExport:o.codeExport,codeLanguage:o.codeLanguage,skipCodeValidation:o.skipCodeValidation},m.code_export),onProgress:()=>{},log:(ne,oe,ae,Pe)=>L.log(ne,oe,ae,Pe),shouldUploadArtifacts:!o.local,shouldReplaceLocalOutput:!1,shouldCommit:!1,isFirstRun:!0}),$e=new G(Y),{renderUploadProgress:Q}=await import("./CliUploadProgress-TPWX5ARU.js"),se=await Q($e,ne=>{if(ne.testcaseId&&ne.shareId&&M)return At(D.testManagerUiUrl,M,ne.testcaseId,ne.shareId)});if(se.success){se.testcaseId&&L.setTestcaseId(se.testcaseId);let ne=d==="testing",oe=L.nextRunIndex()>0;if(ne&&!o.name&&oe&&process.stdin.isTTY)try{let{renderSavePrompt:Se,defaultSessionTimestamp:Oe}=await import("./SaveSessionPrompt-D4PETK7B.js"),ke=await Se(Oe());ke&&L.setSessionName(ke)}catch(Se){L.log("warn","DIRECT_SAVE_PROMPT_FAILED","Save prompt failed",{error:String(Se)})}let ae=null;try{let{persistRecordedSession:Se}=await import("./persist-recorded-session-GG732QRB.js");ae=Se(L,{testcaseId:L.testcaseId??void 0,projectId:ie.project_id??void 0,folderId:ie.folder_id??void 0,codeExportDir:se.codeExportDir})}catch(Se){L.log("error","DIRECT_PERSIST_ERROR","Persist failed in ink mode",{error:String(Se)})}let Pe=se.testcaseId&&se.shareId&&M?At(D.testManagerUiUrl,M,se.testcaseId,se.shareId):void 0,Ue=se.testcaseId&&M?ln(D.testManagerUiUrl,M,se.testcaseId):void 0;if(Pe||Ue||se.codeExportDir||ae){let{LinksBox:Se}=await import("./LinksBox-UD364LBX.js"),{render:Oe}=await import("./build-JIKYOZUH.js"),ke=await import("./react-QWOAB3TB.js"),{waitUntilExit:Yt}=Oe(ke.default.createElement(Se,{recordedTestPath:ae?.recordedTestPath,outputDir:ae?.outputDir,shareableLink:Pe,testCaseLink:Ue,codeExportDir:se.codeExportDir}),{stdout:process.stderr});await Yt()}}if(L.testId){let{renderFeedbackPrompt:ne}=await import("./CliFeedbackPrompt-S7RZGMBQ.js"),oe=await ne();if(oe)try{await io({tmsBaseUrl:D.tmsBaseUrl,username:E.basicAuth.username,accessKey:E.basicAuth.access_key,testId:L.testId,feedbackType:oe,log:(ae,Pe,Ue,Se)=>L.log(ae,Pe,Ue,Se)})}catch(ae){L.log("warn","FEEDBACK_FAILED","Feedback submission failed",{error:String(ae)})}}}}catch(D){L.log("error","DIRECT_UPLOAD_FAILED","Direct upload failed (ink mode)",{error:D instanceof Error?D.stack??D.message:String(D)}),console.error(`Upload failed: ${D}`)}await L.finish("complete"),pe||q(Xt?2:1,"Run ended with no result");let Ct=pe.reason??"";(Ct.includes("Cancel")||Ct.includes("Timeout"))&&q(3,`Run: ${Ct}`),pe.status==="passed"&&q(0,"Run passed"),q(1,"Run failed")}catch(r){q(2,`CLI error: ${r instanceof Error?r.message:String(r)}`)}}),$i(e),e.command("profiles [action] [name]").option("--env <name>","Environment for switch/delete").action(async(n,o,r)=>{let s=new Le;if(n==="list"||!n&&!process.stdin.isTTY){let i=s.listProfiles();if(i.length===0){console.log("No profiles configured. Run: kane-cli login");return}let c=s.getActiveProfile(),_=s.getDefaultEnv();for(let P of i){let h=P.profile===c&&P.env===_?" (active)":"";console.log(`${P.profile} [${P.env}]${h}`)}return}if(n==="switch"&&o){let i=r?.env??s.getDefaultEnv();s.setActiveProfile(o),s.setDefaultEnv(i),Te(s,new Be,o,i),console.log(`Switched to ${o} [${i}]`);return}if(n==="delete"&&o){let i=r?.env??s.getDefaultEnv();s.deleteProfileFull(o,i),console.log(`Deleted profile ${o} [${i}]`);return}process.stdin.isTTY||(console.error("Usage: kane-cli profiles list|switch|delete <name> [--env <env>]"),q(1,"Invalid profiles usage"));let{ProfilesView:m}=await import("./ProfilesView-UOJP2KA2.js"),{render:d}=await import("./build-JIKYOZUH.js"),u=await import("./react-QWOAB3TB.js");await new Promise(i=>{let{unmount:c}=d(u.default.createElement(m,{creds:s,onSwitch:(_,P)=>{s.setActiveProfile(_),s.setDefaultEnv(P),console.log(`Switched to ${_} [${P}]`)},onCancel:()=>{c(),i()}}))})}),e.command("feedback").requiredOption("--test-id <id>","Test ID").requiredOption("--feedback-type <type>","Feedback type: positive or negative").option("--details <text>","Feedback details (max 500 characters)").option("--username <user>","Basic auth username").option("--access-key <key>","Basic auth access key").option("--env <name>","Environment (prod or stage)").action(async n=>{n.feedbackType!=="positive"&&n.feedbackType!=="negative"&&(console.error('Error: --feedback-type must be "positive" or "negative"'),q(1,'Invalid --feedback-type (must be "positive" or "negative")')),n.details&&n.details.length>500&&(console.error("Error: --details must be 500 characters or fewer"),q(1,"--details exceeds 500 character limit"));let o=new Le,r=n.env??o.getDefaultEnv(),s=me(r),m=!1,d=n.username,u=n.accessKey,i;if(n.username&&n.accessKey)m=!0;else{let A=o.resolveAuth();A?.method==="basic"&&(m=!0,d=A.username,u=A.access_key)}if(!m){let{credentials:A}=o.getActiveCredentials();A||(console.error("Not authenticated. Run: kane-cli login"),q(2,"Not authenticated for feedback")),i=A.access_token}let c=async()=>i??null,_=m&&d&&u?{username:d,access_key:u}:null,h=await new Vn(s.controllerBaseUrl,c,_).resolve(),T=h?.username??d,V=h?.access_key??u;(!T||!V)&&(console.error(JSON.stringify({error:"Could not resolve TMS credentials"})),q(1,"Could not resolve TMS credentials for feedback"));try{let{TmsClient:A}=await import("./tms-client-XOARLBEP.js"),N=await new A(s.tmsBaseUrl,T,V).submitFeedback({instruction_id:"",test_id:n.testId,feedback_type:n.feedbackType,details:n.details,mode:"agent"});console.log(JSON.stringify(N)),q(0,"Feedback submitted")}catch(A){console.error(JSON.stringify({error:A instanceof Error?A.message:String(A)})),q(1,`Feedback failed: ${A instanceof Error?A.message:String(A)}`)}}),e.command("balance").description("Check credit balance").option("--profile <name>","Profile name").option("--username <user>","Basic auth username").option("--access-key <key>","Basic auth access key").option("--env <name>","Environment (prod or stage)").action(async n=>{let o=new Le,r=n.profile??o.getActiveProfile()??"default",s=n.env??o.getDefaultEnv(),m=me(s),d=o.loadBasicAuth(r,s),u=null;if(n.username&&n.accessKey)u={username:n.username,accessKey:n.accessKey};else if(d)u={username:d.username,accessKey:d.access_key};else{let i=o.loadCredentials(r,s);i||(console.error(`No credentials for profile "${r}" [${s}]. Run "kane-cli login" first.`),q(2,`No credentials for profile "${r}" [${s}]`)),u=i.access_token}try{let{ControllerClient:i}=await import("./controller-client-OMKEBP4B.js"),_=await new i(m.controllerBaseUrl,u).getCreditBalance();console.log(`Available credits: ${_.available_credits}`),console.log(`Total credits: ${_.total_credits}`),q(0,"Balance retrieved")}catch(i){console.error(`Error: ${i instanceof Error?i.message:String(i)}`),q(1,`Balance check failed: ${i instanceof Error?i.message:String(i)}`)}}),e.command("help").action(()=>{e.help()}),e.command("changelog").description("Show recent release notes").option("--all","Show all releases instead of latest 5").action(async n=>{let{fetchChangelog:o,formatChangelog:r}=await import("./changelog-H2RXH4LH.js"),s=await o({all:n.all});console.log(r(s))}),e.parse(["node","kane-cli",...a])}function Li(a){let e,t,n,o=[];for(let r=0;r<a.length;r++){let s=a[r];if(s==="--code-export")e=!0;else if(s==="--skip-code-validation")n=!0;else if(s==="--no-skip-code-validation")n=!1;else if(s==="--code-language"){let m=a[r+1];m!==void 0&&(t=m,r++)}else s.startsWith("--code-language=")?t=s.slice(16):o.push(s)}return{codeExport:e,codeLanguage:t,skipCodeValidation:n,filteredArgs:o}}function lo(a,e){let t=a.split(".").map(o=>Number(o)||0),n=e.split(".").map(o=>Number(o)||0);for(let o=0;o<3;o++){let r=t[o]??0,s=n[o]??0;if(r<s)return-1;if(r>s)return 1}return 0}var zs=[{version:"0.2.11",description:"Code export is now enabled by default (Python remains the default language; JavaScript is also available). Default run mode is now 'testing'.",apply:a=>{let e=[];return a.code_export.enabled===!1&&e.push({field:"code_export.enabled",from:!1,to:!0,description:"Code export is now enabled by default."}),a.mode==="action"&&e.push({field:"mode",from:"action",to:"testing",description:"Default run mode is now 'testing'."}),{cfg:{...a,code_export:{...a.code_export,enabled:!0},mode:"testing"},changes:e}}}];function Fi(a,e=st,t=zs){let n=a.exists(),o=a.load();if(!n)return a.set("last_seen_version",e),{changes:[],fromVersion:e,toVersion:e,appliedVersions:[]};let r=o.last_seen_version||"0.0.0";if(lo(r,e)>=0)return{changes:[],fromVersion:r,toVersion:r,appliedVersions:[]};let s=t.filter(c=>lo(r,c.version)<0&&lo(c.version,e)<=0).sort((c,_)=>lo(c.version,_.version)),m=o,d=[],u=[];for(let c of s){let{cfg:_,changes:P}=c.apply(m);m=_,d.push(...P),u.push(c.version)}let i={...m,last_seen_version:e};return a.writeRaw(i),{changes:d,fromVersion:r,toVersion:e,appliedVersions:u}}function Ni(a){return a.changes.length===0?"":[`kane-cli updated to ${a.toVersion}. Default settings changed:`,...a.changes.map(t=>` \u2022 ${t.description} (${t.field}: ${JSON.stringify(t.from)} \u2192 ${JSON.stringify(t.to)})`),"","Use /config to review or revert any of these."].join(`
|
|
55
|
+
`),process.exit(2));let r=new Le,s=new Be,m=s.load(),d;if(o.mode===void 0)d=m.mode==="action"?"action":"testing";else if(o.mode==="action"||o.mode==="testing")d=o.mode;else{console.error("Invalid --mode. Must be 'action' or 'testing'."),q(2,"Invalid --mode");return}let u=new nn,{printRecordingBanner:i}=await import("./recording-banner-7ZKIORL5.js");await i({isAgent:!!o.agent||!process.stdin.isTTY,sessionId:u.sessionId,sessionName:o.name??null,testPath:o.name?ut(process.cwd(),".testmuai","tests",`${o.name}_test.md`):null,outputPath:o.name?ut(process.cwd(),".testmuai","tests",`output-${o.name}`):null});let c=!!(o.username&&o.accessKey);if(await Jr({isInteractive:!!process.stdin.isTTY&&!o.agent&&!c,creds:r,config:s}),!c){let D=r.getActiveProfile(),M=r.getDefaultEnv();D&&(r.loadBasicAuth(D,M)||r.loadCredentials(D,M))||(console.error("Not authenticated. Run: kane-cli login --oauth, or kane-cli login --username <user> --access-key <key>"),q(1,"Not authenticated"))}let _=`${r.getActiveProfile()??"no profile"}/${r.getDefaultEnv()}`,P=[],h=o.env??r.getDefaultEnv(),T=null,V=[],A=(D,M,G,Y)=>{T?T(D,M,G,Y):V.push([D,M,G,Y])},E;try{E=await Oo({creds:r,env:h,usernameFlag:o.username,accessKeyFlag:o.accessKey,log:A})}catch(D){throw D instanceof zr&&(console.error(D.code==="not_authenticated"?"Not authenticated. Run: kane-cli login":"Token refresh failed. Run: kane-cli login"),q(2,D.code==="not_authenticated"?"Not authenticated":"Token refresh failed")),D}let N=!!E.basicAuth,j=E.basicAuth?.username,W=E.basicAuth?.access_key,re=E.token,Ae=E.resolver,Ee=E.resolvedCreds;E.basicAuth&&P.push(`Auth: ${E.basicAuth.username}`);let qe=r.getActiveProfile()??"default",Ne=r.getDefaultEnv();Bn(r,s,qe,Ne);let ie=s.load();if(!o.local&&!Ar({projectId:ie.project_id,projectName:ie.project_name,folderId:ie.folder_id,folderName:ie.folder_name})){let D=E.basicAuth??(E.resolvedCreds?{username:E.resolvedCreds.username,access_key:E.resolvedCreds.access_key}:null);if(D)try{await Do({creds:r,config:s,profile:qe,env:Ne,tmsCreds:D,log:A}),ie=s.load()}catch(M){console.error(`Could not auto-configure project/folder: ${M instanceof Error?M.message:M}`),q(2,"Project/folder auto-configure failed")}else console.error("Project and folder must be configured. Run `kane-cli login` to set up defaults, or `kane-cli config project <id>` and `kane-cli config folder <id>` to set them manually."),q(2,"Project/folder not configured")}let Qe=at,te=Kn({objective:n,globalDir:ut(xe,"variables"),localDir:ut(process.cwd(),".testmuai","variables"),file:o.variablesFile,inline:o.variables,onLoadError:D=>console.error(D)}),xt;if(o.sessionContext)try{xt=JSON.parse(o.sessionContext)}catch{console.error("Invalid --session-context JSON"),q(2,"Invalid --session-context JSON")}let wn=o.globalContext??ut(xe,"global-memory.md"),Kt=o.localContext??ut(process.cwd(),".testmuai","context.md"),Ze=Mt(wn),bt=Mt(Kt),we;try{we=await Xr({config:m,startUrl:Qe??void 0,headless:o.headless,cft:o.cft,wsEndpoint:o.wsEndpoint,cdpEndpoint:o.cdpEndpoint})}catch(D){console.error(Fn(D));let M=D instanceof jr?"Chrome not found at standard paths":`Chrome failed: ${D instanceof Error?D.message:D}`;q(2,M)}we.instance&&nt("chrome",()=>{we.instance.kill()});let Ie=null,xn=we.cdpEndpoint??o.cdpEndpoint;xn&&!o.cft&&!o.wsEndpoint&&(Ie=Nn({headless:o.headless,cdpEndpoint:xn,chromePid:we.instance?.process.pid}),Ie&&nt("marker-overlay",()=>Ie.kill())),o.cft?P.push("CfT mode: Playwright will manage its own browser"):o.wsEndpoint?P.push(`Playwright WS endpoint (${o.wsEndpoint.slice(0,60)}...)`):o.cdpEndpoint?P.push(`CDP connected (${o.cdpEndpoint})`):we.cdpEndpoint&&P.push(`Chrome ready (${we.cdpEndpoint})`);let L=u;L.start({model:o.model??m.model,environment:h,profile:r.getActiveProfile()}),o.name&&L.setSessionName(o.name),E.resolvedCreds?.org_id!==void 0&&L.setOrgId(String(E.resolvedCreds.org_id)),T=(D,M,G,Y)=>L.log(D,M,G,Y);for(let D of V)L.log(...D);if(V.length=0,E.resolvedCreds){let{createRemoteLogger:D}=await import("./logging-AIQHWRNQ.js"),{getMachineId:M}=await import("./machine-id-DZN4MYOO.js"),G=D({sessionId:L.sessionId,identity:{org_id:String(E.resolvedCreds.org_id??""),user_id:String(E.resolvedCreds.user_id??""),machine_id:M(),email:E.resolvedCreds.email??null,email_domain:E.resolvedCreds.email_domain??"unknown",user_type:E.resolvedCreds.user_type??"unknown",env:h},getToken:async()=>E.token});L.setRemoteLogger(G),G.start(),nt("remote-logger",()=>G.shutdownSync()),Ln(G)}let bn=E.basicAuth&&!o.local?await Gn({variables:te,auth:E.basicAuth,orgId:String(E.resolvedCreds?.org_id??""),env:h,localMode:!!o.local,log:(D,M,G,Y)=>L.log(D,M,G,Y)}):{};if(L.setAuteurVariables(te.auteur),L.setFirstRun(te.auteurObjective,at),!o.local&&E.basicAuth&&ie.project_id){let D=me(h),M=await Xn({tmsBaseUrl:D.tmsBaseUrl,auth:E.basicAuth,objective:te.auteurObjective,url:at,projectId:ie.project_id,folderId:ie.folder_id??"",hasCustomProfile:!!m.chrome_profile_path,log:(G,Y,$e,Q)=>L.log(G,Y,$e,Q)});M&&L.setTestId(M)}L.setResolvedGlobal({mode:d,max_steps:parseInt(o.maxSteps,10),timeout:o.timeout?parseInt(o.timeout,10):void 0,target:we.instance?"chrome":o.cdpEndpoint?"cdp":o.wsEndpoint?"ws":void 0,chrome_profile:ie.chrome_profile_path||void 0,cdp_endpoint:o.cdpEndpoint||void 0,ws_endpoint:o.wsEndpoint||void 0,headless:o.headless,global_context:Ze??void 0,local_context:bt??void 0,variables:Object.keys(te.auteur).length>0?te.auteur:void 0});let Gt=qn(te.auteur,te.auteurObjective),_t=zn({objective:te.auteurObjective,url:Qe??void 0,model:o.model??m.model,chrome:we,auth:E,sessionId:L.sessionId,runIndex:0,windowSize:m.window_size,maxSteps:parseInt(o.maxSteps,10),headless:o.headless,disableAskUser:!process.stdin.isTTY,enableTaskSkills:o.taskSkills,variables:Object.keys(Gt).length>0?Gt:void 0,globalContext:Ze??void 0,localContext:bt??void 0,sessionContext:xt}),Ke=null;if(!o.local)try{let{ControllerClient:D}=await import("./controller-client-OMKEBP4B.js"),M;if(N&&j&&W)M={username:j,accessKey:W};else if(re)M=re;else throw new Error("No auth available");let Y=await new D(me(h).controllerBaseUrl,M).getScreenshotSas();L.setScreenshotSas(Y),Ke=new Wn(Y,3,($e,Q,se,ne)=>L.log($e,Q,se,ne)),L.log("info","SCREENSHOT_SAS_OK","Screenshot SAS token fetched",{base_url:Y.base_url,container:Y.container,expiry:Y.expiry})}catch(D){L.log("warn","SCREENSHOT_SAS_FAIL","Screenshot SAS token fetch failed",{error:D instanceof Error?D.message:String(D)})}let zt=Ke?(D,M,G)=>{Un(L.sessionDir,M,D,Ke,(Y,$e,Q,se)=>L.log(Y,$e,Q,se),G)}:void 0;if(!process.stdin.isTTY&&!o.agent&&(o.agent=!0),o.agent){let D=oe=>{process.stdout.write(JSON.stringify(oe)+`
|
|
56
|
+
`)};Ie?.setRunActive(!0);let M;try{M=await Bi(_t,{environment:h,mode:d,log:(oe,ae,Pe,Ue)=>L.log(oe,ae,Pe,Ue)},{onStepEnd:zt,onStepLog:(oe,ae,Pe)=>L.logStep(oe,ae,Pe),onReasoning:oe=>Ie?.setStepText(oe),onStepComplete:()=>Ie?.setStepComplete()})}finally{Ie?.setRunActive(!1)}let{lastRunEnd:G,stepsTotal:Y,hadError:$e,bifurcationFlows:Q}=M;if($e&&L.escalateRun(0),G){let oe=on(G,0,Q);L.addRunResult(rn(G,te.auteurObjective,0,oe),G.total_runs);let ae=G.status==="passed"?"passed":$e?"error":"failed";L.addFlow({runIndex:0,objective:te.auteurObjective,status:ae,summary:G.summary??"",duration:G.duration??0,steps:Y,stepsPassed:ae==="passed"?Y:0,stepsFailed:ae==="passed"?0:Y,reason:G.reason,creditsConsumed:G.credits_consumed})}Rt("chrome","Agent run completed");let se;if(L.log("info","DIRECT_UPLOAD_START","Starting direct upload (agent mode)",{agent_mode:!0,last_run_end:!!G,local:!!o.local}),G&&!o.local)try{let oe=me(h),ae=ie.project_id;if(E.basicAuth){let{UploadPipeline:Pe}=await import("./pipeline-EUZIM2ZO.js");Ke&&await Ke.drain();let Ue=cn({session:L,env:h,auth:E,variables:te,variableIds:bn,projectId:ae,folderId:ie.folder_id,totalSteps:Y,totalDuration:G.duration??0,codeExport:dn({codeExport:o.codeExport,codeLanguage:o.codeLanguage,skipCodeValidation:o.skipCodeValidation},m.code_export),onProgress:()=>{},log:(ke,Yt,Ge,Ot)=>L.log(ke,Yt,Ge,Ot),shouldUploadArtifacts:!o.local,shouldReplaceLocalOutput:!1,shouldCommit:!1,isFirstRun:!0}),Oe=await new Pe(Ue).execute();Oe.success&&(Oe.testcaseId&&L.setTestcaseId(Oe.testcaseId),Oe.testcaseId&&Oe.shareId&&ae&&(se=At(oe.testManagerUiUrl,ae,Oe.testcaseId,Oe.shareId)));try{let{persistRecordedSession:ke}=await import("./persist-recorded-session-V5DXMRKC.js");ke(L,{testcaseId:L.testcaseId??void 0,projectId:ie.project_id??void 0,folderId:ie.folder_id??void 0,codeExportDir:Oe.codeExportDir})}catch(ke){L.log("error","DIRECT_PERSIST_ERROR","Persist failed in agent mode",{error:String(ke)})}}}catch(oe){L.log("error","DIRECT_UPLOAD_ERROR","Upload failed in agent mode",{error:oe instanceof Error?oe.message:String(oe)})}if(G){let oe={...G};se&&(oe.test_url=se),D(oe)}await L.finish("complete"),G||q($e?2:1,"Agent run ended with no result");let ne=G.reason??"";(ne.includes("Cancel")||ne.includes("Timeout"))&&q(3,`Agent run: ${ne}`),G.status==="passed"&&q(0,"Agent run passed"),q(1,"Agent run failed")}let pe=null,ft=0,Xt=!1,it=null,Me={current:null},{waitUntilExit:yt}=tn(Vi.default.createElement(ji,{config:_t,spawnOpts:{environment:h,mode:d,log:(D,M,G,Y)=>L.log(D,M,G,Y)},cancelRef:Me,banner:{model:o.model??m.model,auth:_,status:P},onComplete:D=>{pe=D.lastRunEnd,ft=D.stepsTotal,Xt=D.hadError,it=D.bifurcationFlows},onStepEnd:zt,onReasoning:D=>Ie?.setStepText(D),onStepComplete:()=>Ie?.setStepComplete()}),{stdout:process.stderr,exitOnCtrlC:!1}),Jt;if(o.timeout){let D=parseInt(o.timeout,10)*1e3;Jt=setTimeout(()=>{console.error(`
|
|
57
|
+
Timeout: ${o.timeout}s exceeded \u2014 cancelling...`),Me.current?.()},D)}Ie?.setRunActive(!0);try{await yt()}finally{Ie?.setRunActive(!1)}if(Jt&&clearTimeout(Jt),pe){let D=on(pe,0,it);L.addRunResult(rn(pe,te.auteurObjective,0,D),pe.total_runs);let M=pe.status==="passed"?"passed":Xt?"error":"failed";L.addFlow({runIndex:0,objective:te.auteurObjective,status:M,summary:pe.summary??"",duration:pe.duration??0,steps:ft,stepsPassed:M==="passed"?ft:0,stepsFailed:M==="passed"?0:ft,reason:pe.reason,creditsConsumed:pe.credits_consumed})}if(Rt("chrome","Ink run completed"),L.log("info","DIRECT_UPLOAD_START","Starting direct upload (ink mode)",{ink_mode:!0,last_event:!!pe,local:!!o.local}),pe&&!o.local)try{let D=me(h),M=ie.project_id;if(E.basicAuth){let{UploadPipeline:G}=await import("./pipeline-EUZIM2ZO.js");Ke&&(L.log("info","SCREENSHOT_UPLOAD_DRAIN","Draining screenshot upload queue before pipeline"),await Ke.drain(),L.log("info","SCREENSHOT_UPLOAD_DRAINED","Screenshot upload queue drained"));let Y=cn({session:L,env:h,auth:E,variables:te,variableIds:bn,projectId:ie.project_id,folderId:ie.folder_id,totalSteps:ft,totalDuration:pe.duration??0,codeExport:dn({codeExport:o.codeExport,codeLanguage:o.codeLanguage,skipCodeValidation:o.skipCodeValidation},m.code_export),onProgress:()=>{},log:(ne,oe,ae,Pe)=>L.log(ne,oe,ae,Pe),shouldUploadArtifacts:!o.local,shouldReplaceLocalOutput:!1,shouldCommit:!1,isFirstRun:!0}),$e=new G(Y),{renderUploadProgress:Q}=await import("./CliUploadProgress-U6QLD76Y.js"),se=await Q($e,ne=>{if(ne.testcaseId&&ne.shareId&&M)return At(D.testManagerUiUrl,M,ne.testcaseId,ne.shareId)});if(se.success){se.testcaseId&&L.setTestcaseId(se.testcaseId);let ne=d==="testing",oe=L.nextRunIndex()>0;if(ne&&!o.name&&oe&&process.stdin.isTTY)try{let{renderSavePrompt:Se,defaultSessionTimestamp:Oe}=await import("./SaveSessionPrompt-S5RCU5DX.js"),ke=await Se(Oe());ke&&L.setSessionName(ke)}catch(Se){L.log("warn","DIRECT_SAVE_PROMPT_FAILED","Save prompt failed",{error:String(Se)})}let ae=null;try{let{persistRecordedSession:Se}=await import("./persist-recorded-session-V5DXMRKC.js");ae=Se(L,{testcaseId:L.testcaseId??void 0,projectId:ie.project_id??void 0,folderId:ie.folder_id??void 0,codeExportDir:se.codeExportDir})}catch(Se){L.log("error","DIRECT_PERSIST_ERROR","Persist failed in ink mode",{error:String(Se)})}let Pe=se.testcaseId&&se.shareId&&M?At(D.testManagerUiUrl,M,se.testcaseId,se.shareId):void 0,Ue=se.testcaseId&&M?ln(D.testManagerUiUrl,M,se.testcaseId):void 0;if(Pe||Ue||se.codeExportDir||ae){let{LinksBox:Se}=await import("./LinksBox-P3VETMP6.js"),{render:Oe}=await import("./build-JIKYOZUH.js"),ke=await import("./react-QWOAB3TB.js"),{waitUntilExit:Yt}=Oe(ke.default.createElement(Se,{recordedTestPath:ae?.recordedTestPath,outputDir:ae?.outputDir,shareableLink:Pe,testCaseLink:Ue,codeExportDir:se.codeExportDir}),{stdout:process.stderr});await Yt()}}if(L.testId){let{renderFeedbackPrompt:ne}=await import("./CliFeedbackPrompt-SEH4MXTF.js"),oe=await ne();if(oe)try{await io({tmsBaseUrl:D.tmsBaseUrl,username:E.basicAuth.username,accessKey:E.basicAuth.access_key,testId:L.testId,feedbackType:oe,log:(ae,Pe,Ue,Se)=>L.log(ae,Pe,Ue,Se)})}catch(ae){L.log("warn","FEEDBACK_FAILED","Feedback submission failed",{error:String(ae)})}}}}catch(D){L.log("error","DIRECT_UPLOAD_FAILED","Direct upload failed (ink mode)",{error:D instanceof Error?D.stack??D.message:String(D)}),console.error(`Upload failed: ${D}`)}await L.finish("complete"),pe||q(Xt?2:1,"Run ended with no result");let Ct=pe.reason??"";(Ct.includes("Cancel")||Ct.includes("Timeout"))&&q(3,`Run: ${Ct}`),pe.status==="passed"&&q(0,"Run passed"),q(1,"Run failed")}catch(r){q(2,`CLI error: ${r instanceof Error?r.message:String(r)}`)}}),$i(e),e.command("profiles [action] [name]").option("--env <name>","Environment for switch/delete").action(async(n,o,r)=>{let s=new Le;if(n==="list"||!n&&!process.stdin.isTTY){let i=s.listProfiles();if(i.length===0){console.log("No profiles configured. Run: kane-cli login");return}let c=s.getActiveProfile(),_=s.getDefaultEnv();for(let P of i){let h=P.profile===c&&P.env===_?" (active)":"";console.log(`${P.profile} [${P.env}]${h}`)}return}if(n==="switch"&&o){let i=r?.env??s.getDefaultEnv();s.setActiveProfile(o),s.setDefaultEnv(i),Te(s,new Be,o,i),console.log(`Switched to ${o} [${i}]`);return}if(n==="delete"&&o){let i=r?.env??s.getDefaultEnv();s.deleteProfileFull(o,i),console.log(`Deleted profile ${o} [${i}]`);return}process.stdin.isTTY||(console.error("Usage: kane-cli profiles list|switch|delete <name> [--env <env>]"),q(1,"Invalid profiles usage"));let{ProfilesView:m}=await import("./ProfilesView-UBVNEYVE.js"),{render:d}=await import("./build-JIKYOZUH.js"),u=await import("./react-QWOAB3TB.js");await new Promise(i=>{let{unmount:c}=d(u.default.createElement(m,{creds:s,onSwitch:(_,P)=>{s.setActiveProfile(_),s.setDefaultEnv(P),console.log(`Switched to ${_} [${P}]`)},onCancel:()=>{c(),i()}}))})}),e.command("feedback").requiredOption("--test-id <id>","Test ID").requiredOption("--feedback-type <type>","Feedback type: positive or negative").option("--details <text>","Feedback details (max 500 characters)").option("--username <user>","Basic auth username").option("--access-key <key>","Basic auth access key").option("--env <name>","Environment (prod or stage)").action(async n=>{n.feedbackType!=="positive"&&n.feedbackType!=="negative"&&(console.error('Error: --feedback-type must be "positive" or "negative"'),q(1,'Invalid --feedback-type (must be "positive" or "negative")')),n.details&&n.details.length>500&&(console.error("Error: --details must be 500 characters or fewer"),q(1,"--details exceeds 500 character limit"));let o=new Le,r=n.env??o.getDefaultEnv(),s=me(r),m=!1,d=n.username,u=n.accessKey,i;if(n.username&&n.accessKey)m=!0;else{let A=o.resolveAuth();A?.method==="basic"&&(m=!0,d=A.username,u=A.access_key)}if(!m){let{credentials:A}=o.getActiveCredentials();A||(console.error("Not authenticated. Run: kane-cli login"),q(2,"Not authenticated for feedback")),i=A.access_token}let c=async()=>i??null,_=m&&d&&u?{username:d,access_key:u}:null,h=await new Vn(s.controllerBaseUrl,c,_).resolve(),T=h?.username??d,V=h?.access_key??u;(!T||!V)&&(console.error(JSON.stringify({error:"Could not resolve TMS credentials"})),q(1,"Could not resolve TMS credentials for feedback"));try{let{TmsClient:A}=await import("./tms-client-XOARLBEP.js"),N=await new A(s.tmsBaseUrl,T,V).submitFeedback({instruction_id:"",test_id:n.testId,feedback_type:n.feedbackType,details:n.details,mode:"agent"});console.log(JSON.stringify(N)),q(0,"Feedback submitted")}catch(A){console.error(JSON.stringify({error:A instanceof Error?A.message:String(A)})),q(1,`Feedback failed: ${A instanceof Error?A.message:String(A)}`)}}),e.command("balance").description("Check credit balance").option("--profile <name>","Profile name").option("--username <user>","Basic auth username").option("--access-key <key>","Basic auth access key").option("--env <name>","Environment (prod or stage)").action(async n=>{let o=new Le,r=n.profile??o.getActiveProfile()??"default",s=n.env??o.getDefaultEnv(),m=me(s),d=o.loadBasicAuth(r,s),u=null;if(n.username&&n.accessKey)u={username:n.username,accessKey:n.accessKey};else if(d)u={username:d.username,accessKey:d.access_key};else{let i=o.loadCredentials(r,s);i||(console.error(`No credentials for profile "${r}" [${s}]. Run "kane-cli login" first.`),q(2,`No credentials for profile "${r}" [${s}]`)),u=i.access_token}try{let{ControllerClient:i}=await import("./controller-client-OMKEBP4B.js"),_=await new i(m.controllerBaseUrl,u).getCreditBalance();console.log(`Available credits: ${_.available_credits}`),console.log(`Total credits: ${_.total_credits}`),q(0,"Balance retrieved")}catch(i){console.error(`Error: ${i instanceof Error?i.message:String(i)}`),q(1,`Balance check failed: ${i instanceof Error?i.message:String(i)}`)}}),e.command("help").action(()=>{e.help()}),e.command("changelog").description("Show recent release notes").option("--all","Show all releases instead of latest 5").action(async n=>{let{fetchChangelog:o,formatChangelog:r}=await import("./changelog-EFAQANXW.js"),s=await o({all:n.all});console.log(r(s))}),e.parse(["node","kane-cli",...a])}function Li(a){let e,t,n,o=[];for(let r=0;r<a.length;r++){let s=a[r];if(s==="--code-export")e=!0;else if(s==="--skip-code-validation")n=!0;else if(s==="--no-skip-code-validation")n=!1;else if(s==="--code-language"){let m=a[r+1];m!==void 0&&(t=m,r++)}else s.startsWith("--code-language=")?t=s.slice(16):o.push(s)}return{codeExport:e,codeLanguage:t,skipCodeValidation:n,filteredArgs:o}}function lo(a,e){let t=a.split(".").map(o=>Number(o)||0),n=e.split(".").map(o=>Number(o)||0);for(let o=0;o<3;o++){let r=t[o]??0,s=n[o]??0;if(r<s)return-1;if(r>s)return 1}return 0}var zs=[{version:"0.2.11",description:"Code export is now enabled by default (Python remains the default language; JavaScript is also available). Default run mode is now 'testing'.",apply:a=>{let e=[];return a.code_export.enabled===!1&&e.push({field:"code_export.enabled",from:!1,to:!0,description:"Code export is now enabled by default."}),a.mode==="action"&&e.push({field:"mode",from:"action",to:"testing",description:"Default run mode is now 'testing'."}),{cfg:{...a,code_export:{...a.code_export,enabled:!0},mode:"testing"},changes:e}}}];function Fi(a,e=st,t=zs){let n=a.exists(),o=a.load();if(!n)return a.set("last_seen_version",e),{changes:[],fromVersion:e,toVersion:e,appliedVersions:[]};let r=o.last_seen_version||"0.0.0";if(lo(r,e)>=0)return{changes:[],fromVersion:r,toVersion:r,appliedVersions:[]};let s=t.filter(c=>lo(r,c.version)<0&&lo(c.version,e)<=0).sort((c,_)=>lo(c.version,_.version)),m=o,d=[],u=[];for(let c of s){let{cfg:_,changes:P}=c.apply(m);m=_,d.push(...P),u.push(c.version)}let i={...m,last_seen_version:e};return a.writeRaw(i),{changes:d,fromVersion:r,toVersion:e,appliedVersions:u}}function Ni(a){return a.changes.length===0?"":[`kane-cli updated to ${a.toVersion}. Default settings changed:`,...a.changes.map(t=>` \u2022 ${t.description} (${t.field}: ${JSON.stringify(t.from)} \u2192 ${JSON.stringify(t.to)})`),"","Use /config to review or revert any of these."].join(`
|
|
58
58
|
`)}Dr();Yr();var Wi=Jn().catch(()=>null),co=null,qi=()=>co||(co=Fi(new Be),co),uo=Ce.argv.slice(2),Xs=uo.includes("--dev"),cr=uo.includes("--local"),Js=uo.includes("--tui");Xs&&(Ce.env.KANE_DEV_MODE="1");var Ys=uo.filter(a=>!["--dev","--local","--tui"].includes(a));function Qs(a){let e=[],t;for(let n=0;n<a.length;n++){let o=a[n];if(o==="--name"&&n+1<a.length){t=a[n+1],n++;continue}if(o.startsWith("--name=")){t=o.slice(7);continue}e.push(o)}return{name:t,rest:e}}var fo=Li(Ys),wt=fo.filteredArgs,Mi=fo.codeExport,dr=fo.codeLanguage,ur=fo.skipCodeValidation,Ui=()=>{Wi.then(a=>{a&&Ce.stderr.write(`
|
|
59
59
|
Update available: ${a.current} \u2192 ${a.latest} \u2014 run \`${qr()}\` to update
|
|
60
60
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a,b}from"./chunk-
|
|
2
|
+
import{a,b}from"./chunk-H33BV5YV.js";import"./chunk-TL4SB7MQ.js";import"./chunk-V7QXJKX7.js";import"./chunk-UR6MHSHU.js";export{a as RemoteLogger,b as createRemoteLogger};
|
|
@@ -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-WM6GZFTC.js";import"./chunk-IXWVTWOR.js";import"./chunk-HNIH3GSQ.js";import"./chunk-TL4SB7MQ.js";import"./chunk-V7QXJKX7.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-PNQ5YMED.js";import"./chunk-TL4SB7MQ.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};
|
|
@@ -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-OVAOOQHC.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};
|