@testmuai/kane-cli 0.8.14 → 0.8.16
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/{ChatSurface-AVL3TJA2.js → ChatSurface-5JEEFY34.js} +1 -1
- package/dist/{ChromeProfilePicker-WJZJOZ6Z.js → ChromeProfilePicker-6IVAYCWJ.js} +1 -1
- package/dist/{CliFeedbackPrompt-65BQF5G5.js → CliFeedbackPrompt-K4IN7S6J.js} +1 -1
- package/dist/{CliUploadProgress-HEBZYKGN.js → CliUploadProgress-MI4H4LKT.js} +1 -1
- package/dist/{ConfigView-JEVQ2SO4.js → ConfigView-CJY5MB6H.js} +1 -1
- package/dist/EvidenceViewOffer-ABKTGD4K.js +2 -0
- package/dist/FolderPicker-RQIVS7ZR.js +2 -0
- package/dist/{InfoBox-KM5DLBCV.js → InfoBox-RP6RDCG7.js} +1 -1
- package/dist/{LinksBox-FQA36GTV.js → LinksBox-QOQJ3S2I.js} +1 -1
- package/dist/{ProfilesView-76KGHTMK.js → ProfilesView-BZEBT6R5.js} +1 -1
- package/dist/{ProjectPicker-65YOU46H.js → ProjectPicker-J42MEJRQ.js} +1 -1
- package/dist/{SaveSessionPrompt-QD6BNTWO.js → SaveSessionPrompt-MKAIUVX7.js} +1 -1
- package/dist/SingleShotApp-TZZ2J7ZO.js +2 -0
- package/dist/{SummaryBox-N2B6DUDD.js → SummaryBox-JQJKGYDM.js} +1 -1
- package/dist/TestMdRunView-2YVGGFLU.js +2 -0
- package/dist/{TestrunEvidenceTable-3WLQVTF4.js → TestrunEvidenceTable-FYDS3ZVU.js} +1 -1
- package/dist/{WhoamiView-T26HA4ZZ.js → WhoamiView-F4PPB7SN.js} +1 -1
- package/dist/{app-download-XKZWFMEK.js → app-download-RA4CGTC5.js} +1 -1
- package/dist/{auth-PPJANIMZ.js → auth-TAT427C3.js} +1 -1
- package/dist/{binary-DKWWODT2.js → binary-OFPMBJ34.js} +1 -1
- package/dist/{bind-62AZYFAY.js → bind-LY362KX7.js} +2 -2
- package/dist/{bootstrap-6IJNZIPT.js → bootstrap-RCDB5OWA.js} +1 -1
- package/dist/bridge-E2NGMJYM.js +2 -0
- package/dist/{changelog-UTGJ7FSP.js → changelog-ZC3LHV2Z.js} +1 -1
- package/dist/{chunk-O5AS2ZIX.js → chunk-23MVD7GY.js} +1 -1
- package/dist/{chunk-X74PP5NJ.js → chunk-2GWMENG5.js} +1 -1
- package/dist/{chunk-75I46VTM.js → chunk-3AVBUEBL.js} +2 -2
- package/dist/chunk-3LXN6AV5.js +5 -0
- package/dist/{chunk-NOLYYHVG.js → chunk-3MVEGB2I.js} +1 -1
- package/dist/{chunk-42FHKRPA.js → chunk-4LVZLLTN.js} +3 -3
- package/dist/{chunk-73ULUGBM.js → chunk-4PWYSDZR.js} +1 -1
- package/dist/{chunk-7RAI77XD.js → chunk-4WEVTED6.js} +1 -1
- package/dist/{chunk-CGT4NFQN.js → chunk-5ACSALRU.js} +3 -3
- package/dist/{chunk-SX56MVUO.js → chunk-5VZAWKDF.js} +1 -1
- package/dist/{chunk-2BFXT7VQ.js → chunk-6HCY5LJO.js} +14 -14
- package/dist/{chunk-XGHMZJGI.js → chunk-7P6FSGRD.js} +2 -2
- package/dist/{chunk-UXH3RMQ7.js → chunk-7QUFOWMU.js} +1 -1
- package/dist/{chunk-O2APH6TZ.js → chunk-7XMDCGIZ.js} +1 -1
- package/dist/{chunk-LL5DQO6V.js → chunk-AAT4O22C.js} +1 -1
- package/dist/{chunk-FFFB5BXL.js → chunk-AGKE5WF3.js} +1 -1
- package/dist/{chunk-OH2NSBO6.js → chunk-BCJNIDS3.js} +1 -1
- package/dist/{chunk-3BHRGHIZ.js → chunk-BK42G6RI.js} +1 -1
- package/dist/{chunk-YHR2YAN5.js → chunk-BY2MU3ZS.js} +1 -1
- package/dist/{chunk-AC7BPO4X.js → chunk-C6JFTSIQ.js} +1 -1
- package/dist/chunk-CAOZKSQ3.js +8 -0
- package/dist/{chunk-DA57DXCF.js → chunk-CDWUZ54U.js} +1 -1
- package/dist/{chunk-3YX3RQXO.js → chunk-CR7UWQ76.js} +1 -1
- package/dist/{chunk-LR5DJ6EN.js → chunk-CVNHUDT4.js} +1 -1
- package/dist/{chunk-MLRO7OH3.js → chunk-DSWHEEHN.js} +1 -1
- package/dist/{chunk-6LGED4FC.js → chunk-E44OHYDS.js} +2 -2
- package/dist/{chunk-BJYGWXVP.js → chunk-ECIGXPLN.js} +1 -1
- package/dist/{chunk-QJ5O27SJ.js → chunk-EMAKLNDV.js} +1 -1
- package/dist/{chunk-B2ZGG7WM.js → chunk-F2XTOZTN.js} +1 -1
- package/dist/{chunk-ARG56PJG.js → chunk-FQFVAFWK.js} +1 -1
- package/dist/{chunk-SFTFHFG3.js → chunk-FWPRUGJJ.js} +1 -1
- package/dist/{chunk-4K5XTIJ6.js → chunk-FYJ62EVY.js} +1 -1
- package/dist/{chunk-N7ZRF5K3.js → chunk-G2ZMNVYN.js} +1 -1
- package/dist/{chunk-J7NRD4Q7.js → chunk-GCMJDOAE.js} +1 -1
- package/dist/{chunk-WBHSPN55.js → chunk-GGD7NKPL.js} +2 -2
- package/dist/{chunk-WOA7VCGA.js → chunk-H6S7L2I2.js} +1 -1
- package/dist/{chunk-RBHQXWR7.js → chunk-HBMNUT6E.js} +1 -1
- package/dist/{chunk-ZWHPIR2Z.js → chunk-HYCOX7AB.js} +2 -2
- package/dist/{chunk-RQLU4NDG.js → chunk-ICUTARPB.js} +1 -1
- package/dist/{chunk-YHVG7V3E.js → chunk-IJTSA34Q.js} +1 -1
- package/dist/chunk-IQDZ6YMY.js +18 -0
- package/dist/{chunk-ZA4M4O7E.js → chunk-IYOPWIG4.js} +2 -2
- package/dist/{chunk-7L25ZNNP.js → chunk-IZ5CTC6M.js} +1 -1
- package/dist/{chunk-GKZ2KVE6.js → chunk-J2LWXO55.js} +1 -1
- package/dist/{chunk-BAKJPQGU.js → chunk-KPL2XHYF.js} +1 -1
- package/dist/{chunk-WR42Q3HU.js → chunk-KYZKPNPQ.js} +1 -1
- package/dist/chunk-L45HDSJ7.js +15 -0
- package/dist/{chunk-4BBDKWM3.js → chunk-MD3S2RXN.js} +1 -1
- package/dist/{chunk-JH6E632O.js → chunk-MU3I453X.js} +1 -1
- package/dist/{chunk-C74ABM24.js → chunk-MZYPDLD3.js} +1 -1
- package/dist/{chunk-GESG672R.js → chunk-NADKZKGS.js} +1 -1
- package/dist/{chunk-2RMHDOP4.js → chunk-NMBFAIXZ.js} +1 -1
- package/dist/chunk-NN6UG2BE.js +11 -0
- package/dist/chunk-NPKB7EK3.js +7 -0
- package/dist/{chunk-MNE5VMHT.js → chunk-O3ZKP4DY.js} +1 -1
- package/dist/{chunk-KOL6ZWOQ.js → chunk-OUWOLCCS.js} +1 -1
- package/dist/{chunk-GPIXV7AV.js → chunk-OYY566GN.js} +1 -1
- package/dist/{chunk-3SPOJWRA.js → chunk-PDTFQGQF.js} +1 -1
- package/dist/{chunk-Q7XBMBMR.js → chunk-Q7LZ5QJV.js} +1 -1
- package/dist/{chunk-X5276I5H.js → chunk-QMZLIHBS.js} +2 -2
- package/dist/chunk-QXUPBIV3.js +93 -0
- package/dist/{chunk-SQDQADWD.js → chunk-RCYYE6ED.js} +1 -1
- package/dist/{chunk-6F6YI3ZG.js → chunk-SF5QPR6T.js} +1 -1
- package/dist/{chunk-22QIVSQR.js → chunk-SWTJMTBY.js} +1 -1
- package/dist/{chunk-O6U2HU5M.js → chunk-TBYYPGHF.js} +1 -1
- package/dist/{chunk-SGHP44WS.js → chunk-TGBXIV7O.js} +1 -1
- package/dist/{chunk-P3JUE2RM.js → chunk-TWZ6NZWE.js} +4 -4
- package/dist/{chunk-L6MOO4WT.js → chunk-U466V5JN.js} +1 -1
- package/dist/{chunk-OO5GMBVI.js → chunk-U7BVK5IX.js} +1 -1
- package/dist/{chunk-IQ7NGOAT.js → chunk-UAFCBZ3P.js} +1 -1
- package/dist/{chunk-JKX57HA7.js → chunk-UEG4LJD6.js} +1 -1
- package/dist/{chunk-NBMLBCJ3.js → chunk-ULGFPKC7.js} +1 -1
- package/dist/{chunk-KOPP4CJW.js → chunk-V4JR5JCK.js} +1 -1
- package/dist/{chunk-ZKEOPIQ3.js → chunk-VATOIZYG.js} +1 -1
- package/dist/{chunk-WILT62DP.js → chunk-VOTIGXQ4.js} +1 -1
- package/dist/chunk-VWOAEF7J.js +2 -0
- package/dist/{chunk-VNFCX2SH.js → chunk-W4Y3PG7F.js} +1 -1
- package/dist/{chunk-RH6KFHJB.js → chunk-WECVT7WE.js} +1 -1
- package/dist/{chunk-QPUVOVD7.js → chunk-WML5KSGQ.js} +1 -1
- package/dist/{chunk-PGU64EWQ.js → chunk-WPNNRMTP.js} +1 -1
- package/dist/{chunk-IQ7GPETF.js → chunk-XGL3RSI5.js} +1 -1
- package/dist/{chunk-JJJSDDQ2.js → chunk-Z2GDSCPS.js} +1 -1
- package/dist/chunk-Z4KRSLAM.js +2 -0
- package/dist/{chunk-EMSLJTYN.js → chunk-Z5DGFN7R.js} +1 -1
- package/dist/{chunk-NDCRJXYF.js → chunk-ZLIYWELJ.js} +1 -1
- package/dist/{chunk-K7K23DIQ.js → chunk-ZYEFWJNZ.js} +1 -1
- package/dist/{config-3AKWRTFS.js → config-WETHR632.js} +1 -1
- package/dist/{cover-cmd-ZLAWMEC2.js → cover-cmd-J3CTQT3R.js} +1 -1
- package/dist/{credentials-Q4WH5CBN.js → credentials-RQPAP5KY.js} +1 -1
- package/dist/{deps-bundle-RVZK6LZJ.js → deps-bundle-F47ZDYIM.js} +1 -1
- package/dist/{deps-resolve-6F2U4TJP.js → deps-resolve-URKD4QCB.js} +1 -1
- package/dist/{dispatch-46BETGXY.js → dispatch-KOZAJQDW.js} +1 -1
- package/dist/{doctor-WRPG56HH.js → doctor-J44UKALC.js} +1 -1
- package/dist/{evidence-XWR32HWP.js → evidence-KRNDKDCT.js} +1 -1
- package/dist/{evolve-cmd-27ZQN6YB.js → evolve-cmd-CEYGGIWA.js} +1 -1
- package/dist/{explain-cmd-JCJTXVZY.js → explain-cmd-USGRZFBY.js} +1 -1
- package/dist/{extract-bind-D5BYYGYA.js → extract-bind-X4QRQX53.js} +2 -2
- package/dist/{extract-cmd-CCYW7FIY.js → extract-cmd-RKEE32FN.js} +1 -1
- package/dist/{gaps-cmd-3VJKQ25D.js → gaps-cmd-WL6P6YKS.js} +1 -1
- package/dist/{generate-headless-2M6UT3IK.js → generate-headless-LSQHOR3G.js} +2 -2
- package/dist/index.js +147 -149
- package/dist/{ingest-cmd-HVTUK264.js → ingest-cmd-TQ4ARSDE.js} +1 -1
- package/dist/install-47CRHVU6.js +2 -0
- package/dist/{interactive-bind-OJCYNQPI.js → interactive-bind-FPC4RYEW.js} +3 -3
- package/dist/{lifecycle-cmd-GWFGUGTC.js → lifecycle-cmd-DB5EFO2O.js} +1 -1
- package/dist/{list-cmd-AXDW64OY.js → list-cmd-UWGJRGKF.js} +1 -1
- package/dist/{list-commands-YNZ6EFIF.js → list-commands-Q77CAQJ2.js} +1 -1
- package/dist/login-flow-RSNR5HY2.js +2 -0
- package/dist/{maintenance-cmd-QEMK6YNV.js → maintenance-cmd-EJ2RAMWB.js} +1 -1
- package/dist/{mobile-prompts-OXHA5GHJ.js → mobile-prompts-PPPPKRS2.js} +1 -1
- package/dist/objective-variable-gate-BCKULIFQ.js +2 -0
- package/dist/{open-provider-E5VUGFNE.js → open-provider-XIGABCD3.js} +1 -1
- package/dist/{persist-recorded-session-KWPH37HI.js → persist-recorded-session-MK4HCDOY.js} +1 -1
- package/dist/pipeline-XDWHEZ5S.js +2 -0
- package/dist/prepare-target-NR3MTLLI.js +2 -0
- package/dist/{reconcile-cmd-V7TDYETT.js → reconcile-cmd-VJPEY7YD.js} +1 -1
- package/dist/{reconcile-deps-X6IGH4CA.js → reconcile-deps-T5YX6HRG.js} +2 -2
- package/dist/{reconcile-engine-OGXSIE7O.js → reconcile-engine-GELPXSLV.js} +1 -1
- package/dist/{recording-banner-IZWN2XFY.js → recording-banner-3ET3PMSV.js} +1 -1
- package/dist/registry-3XMA4FOC.js +2 -0
- package/dist/{require-project-folder-PEEUITK6.js → require-project-folder-ZLKONKKP.js} +1 -1
- package/dist/{resolve-run-intent-JGXXE45Y.js → resolve-run-intent-3SXUS676.js} +1 -1
- package/dist/{resolver-TY7XLJBN.js → resolver-G7NGWACO.js} +1 -1
- package/dist/{review-cmd-74YTPT7E.js → review-cmd-6DNGXV5E.js} +1 -1
- package/dist/{run-DN4XARP2.js → run-MUVZVTTC.js} +1 -1
- package/dist/{run-GRYWYKIH.js → run-UJLRTKTO.js} +1 -1
- package/dist/{run-test-md-DFCKCQ4T.js → run-test-md-RI5RXVFU.js} +2 -2
- package/dist/{skill-installer-GRU3HOYF.js → skill-installer-CAO2NJZP.js} +1 -1
- package/dist/{spawner-LNMD4NJF.js → spawner-H6IDWY5U.js} +1 -1
- package/dist/{store-guard-Q4MYZQHF.js → store-guard-PIA2DYZX.js} +1 -1
- package/dist/{sync-cmd-H6Y5EB3L.js → sync-cmd-VFVTFIIJ.js} +1 -1
- package/dist/{sync-setup-THGRBKTA.js → sync-setup-R7BZDE24.js} +1 -1
- package/dist/tcg-generate-QADJKNYZ.js +2 -0
- package/dist/testmd-actions-EXSVQRHQ.js +2 -0
- package/dist/testmd-sync-2CXNIPJ7.js +2 -0
- package/dist/token-refresh-5TVNSL4U.js +2 -0
- package/dist/{validate-basic-RCBEELSB.js → validate-basic-MN5NDCT2.js} +1 -1
- package/dist/{variable-receipt-JHRW73Z6.js → variable-receipt-SIABUC74.js} +1 -1
- package/dist/{verdicts-XFXDRND4.js → verdicts-ZXXBKTOZ.js} +1 -1
- package/dist/{version-check-Z774UWW3.js → version-check-TDGK5REB.js} +1 -1
- package/dist/{view-cmd-I4LQGJ2X.js → view-cmd-RLO7AP4X.js} +1 -1
- package/dist/{walk-session-FP52IGLB.js → walk-session-ATWNUGHX.js} +1 -1
- package/dist/{with-telemetry-P6RUPWBH.js → with-telemetry-CLSDKQAG.js} +1 -1
- package/package.json +11 -11
- package/dist/EvidenceViewOffer-5MB4ZXKM.js +0 -2
- package/dist/FolderPicker-SYFXH6D5.js +0 -2
- package/dist/SingleShotApp-U54ETXS3.js +0 -2
- package/dist/TestMdRunView-WA4TC5PT.js +0 -2
- package/dist/bridge-X5DEJL6F.js +0 -2
- package/dist/chunk-53MPG2J3.js +0 -11
- package/dist/chunk-IICQ5KRD.js +0 -5
- package/dist/chunk-KN65CUNT.js +0 -15
- package/dist/chunk-L4M7753M.js +0 -2
- package/dist/chunk-LBNADEQN.js +0 -8
- package/dist/chunk-LNV7C2YO.js +0 -6
- package/dist/chunk-M7DN6FO3.js +0 -17
- package/dist/chunk-ZZTZJPT2.js +0 -88
- package/dist/install-5WJLE7XT.js +0 -2
- package/dist/login-flow-PRXFPRYZ.js +0 -2
- package/dist/objective-variable-gate-76GYUHEP.js +0 -2
- package/dist/pipeline-A2OGF4XW.js +0 -2
- package/dist/prepare-target-P6BWJZBZ.js +0 -2
- package/dist/registry-GOLIFVK5.js +0 -2
- package/dist/tcg-generate-SZZ7MJXY.js +0 -2
- package/dist/testmd-actions-MRIUOOXO.js +0 -2
- package/dist/testmd-sync-UYVJ47BN.js +0 -2
- package/dist/token-refresh-KN5JK2U4.js +0 -2
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import{a as Ar,b as To,c as Do,d as Bt,e as at,f as Lo,g as No,h as Pr,i as Tr,j as Dr,k as Bo,l as $o}from"./chunk-NPKB7EK3.js";import{T as zo}from"./chunk-E44OHYDS.js";import{c as Go}from"./chunk-H6TNBKGR.js";import{a as Ro}from"./chunk-WD52ZNQY.js";import{a as lt,b as Oo,c as xr}from"./chunk-BHSHGWBL.js";import{c as jo}from"./chunk-S3DAAAE5.js";import{e as Fo,g as Uo}from"./chunk-5VZAWKDF.js";import{c as Mo}from"./chunk-3LXN6AV5.js";import{a as Sr}from"./chunk-PDXZROJM.js";import{b as Lr,c as Or}from"./chunk-NN6UG2BE.js";import{c as Vo,g as Ko,i as Ho,j as qo}from"./chunk-Z4KRSLAM.js";import{A as mo,B as fo,C as po,D as go,F as Ir,G as ho,I as vo,R as wo,X as Io,Y as _o,g as lo,i as Ut,v as co,w as uo}from"./chunk-5ACSALRU.js";import{c as yo,d as bo}from"./chunk-VOTIGXQ4.js";import{a as _r}from"./chunk-CH273NAE.js";import{b as $e}from"./chunk-IQDZ6YMY.js";import{a as st,b as Wn,c as Jn,d as Qn,e as Zn,f as Xn,g as yr,i as eo}from"./chunk-VWOAEF7J.js";import{d as Nt,e as Po}from"./chunk-WECVT7WE.js";import{a as it,b as ee,c as ko,e as ve,f as Me,g as kr,k as So,m as Co,n as Ao,o as Rr,p as fe,q as Er,s as Cr,u as xo}from"./chunk-L45HDSJ7.js";import{b as Eo}from"./chunk-NBXYL2JT.js";import{a as jt,c as Ft,d as wr}from"./chunk-OYY566GN.js";import{a as Lt,c as oo,d as so,e as Ot}from"./chunk-OUWOLCCS.js";import{c as io,e as ao}from"./chunk-P7YZ3PU3.js";import{a as br,b as vr}from"./chunk-4PMZ5FCD.js";import{a as no}from"./chunk-2YEHV2CX.js";import{i as zn,m as Yn}from"./chunk-SF5QPR6T.js";import{g as to,h as ro}from"./chunk-TGBXIV7O.js";import{a as Dt}from"./chunk-BPMSNGXQ.js";import{j as Kn,l as hr,m as Hn,n as Tt,o as qn,p as Gn}from"./chunk-RSSOJ3L2.js";import{a as Mn}from"./chunk-Z7S3IWUX.js";import{d as Vn}from"./chunk-4JOD47QI.js";import{a as X}from"./chunk-BCJNIDS3.js";import{a as xe}from"./chunk-DHJSM5DT.js";import{a as xt,b as Pt}from"./chunk-NLCCBXXV.js";import{a as Y}from"./chunk-RZ4F3BHX.js";import{a as Bn}from"./chunk-E47GFYXA.js";import{a as Ct,b as At,i as $n,j as ot,k as pr,l as gr}from"./chunk-F2XTOZTN.js";import{join as ge,basename as mt}from"path";import{existsSync as Ia,readFileSync as ri}from"fs";function Yo(e,t){if(process.env.KANE_REPLAY_TRACE==="1")for(let r=0;r<e.steps.length;r++){let n=e.steps[r],o=t[r],s=" ".repeat(n.trace.length-1),l=`step ${n.flatIndex}`;if(o.kind==="replay"){let f=o.replayOnly?` [replay-only @${o.replayOnly}]`:"";process.stderr.write(`[replay-trace] ${s}${l}: REPLAY${f} (would skip; v1 always authors)
|
|
3
|
+
`)}else process.stderr.write(`[replay-trace] ${s}${l}: AUTHOR (${o.reason})
|
|
4
|
+
`)}}function Pe(e){process.env.KANE_REPLAY_TRACE==="1"&&process.stderr.write(e)}function Wo(e,t){let r=e===0?"(none)":`0..${e-1}`,n=e>=t?"(none)":`${e}..${t-1}`;Pe(`[replay-trace] phase: replay ${r}, author ${n}
|
|
5
|
+
`)}function Jo(e,t){Pe(`[replay-trace] step ${e}: REPLAY ${t==="ok"?"OK":"FAILED"}
|
|
6
|
+
`)}function Qo(e,t,r){Pe(`[replay-trace] shrink ${e}/${t} \u2192 new boundary ${r}
|
|
7
|
+
`)}function Zo(e,t){Pe(`[replay-trace] complete-reauthor (${e} shrinks exhausted of ${t})
|
|
8
|
+
`)}function jr(){Pe(`[replay-trace] force-author (--author) \u2014 walker bypassed; identity kept
|
|
9
|
+
`)}function Xo(e){Pe(`[replay-trace] cancelled at step ${e}
|
|
10
|
+
`)}function Te(e,t){Pe(`[replay-trace] step ${e}: replay-only @${t} failed \u2014 adaptive heal cannot re-author it; the run fails here
|
|
11
|
+
`)}import{join as es}from"path";function Fr(e){let t=Lo(e.decision),r={objective:e.step.objective,model:"v16-alpha",width:e.windowSize.width,height:e.windowSize.height,session_id:e.sessionId,run_index:e.runIndex,mode:"replay",replay:{recording_path:t[0],...t.length>1?{recording_paths:t}:{},step_label:e.step.objective,...e.investigationAsync?{investigation:"async"}:{}},screenshot_dir:e.evidence?es(e.sessionDir,"scratch",String(e.runIndex)):es(e.sessionDir,"runs",String(e.runIndex)),run_id:"run",test_id:"test"};return e.forceNavigateUrl&&(r.url=e.forceNavigateUrl),e.chrome.wsEndpoint?r.ws_endpoint=e.chrome.wsEndpoint:e.chrome.cdpEndpoint&&(r.cdp_endpoint=e.chrome.cdpEndpoint),e.auth.basicAuth?(r.username=e.auth.basicAuth.username,r.access_key=e.auth.basicAuth.access_key):e.auth.token&&(r.auth={type:"bearer",token:e.auth.token}),e.auth.resolvedCreds?.org_id&&(r.org_id=String(e.auth.resolvedCreds.org_id)),e.environmentId&&(r.environment_id=e.environmentId),e.variables&&Object.keys(e.variables).length>0&&(r.variables=e.variables),e.sessionContext&&(r.session_context=e.sessionContext),e.device&&(r.device=e.device),e.evidence&&(r.evidence=Ut(e.evidence.packTestDir,e.evidence.ordinalOffset)),r}async function ts(e){let t=e.forceAuthor?0:at(e.decisions),r=0,n=!1;for(;;){let o=e.session.snapshot(),s=e.accumulator.snapshot(),l=await e.runReplayPhase(t);if(l.cancelled)return n=!0,Xo(l.failedAt??0),{authorBoundary:t,cancelledInPhase:n,shrinkCount:r};if(l.failedAt===null)return{authorBoundary:t,cancelledInPhase:n,shrinkCount:r};let f=e.decisions[l.failedAt],i=f?.kind==="replay"?f.replayOnly:void 0,c=Oo({failedAt:l.failedAt,shrinkCount:r,hasRetry:e.hasRetry,maxShrinks:e.maxShrinks,failedAtReplayOnly:i});if(c.kind==="fail")return c.replayOnly&&(Te(l.failedAt,c.replayOnly),e.onReplayOnlyFail?.(l.failedAt,c.replayOnly)),{authorBoundary:-1,cancelledInPhase:n,shrinkCount:r};if(e.acquireLockIfNeeded&&!await e.acquireLockIfNeeded())return{authorBoundary:-1,cancelledInPhase:n,shrinkCount:r};if(e.recycleBrowser&&!await e.recycleBrowser())return{authorBoundary:-1,cancelledInPhase:n,shrinkCount:r};if(e.archiveAttempt&&await e.archiveAttempt(l.failedAt),e.session.rollback(o),e.accumulator.rollback(s),c.kind==="complete-reauthor")return Zo(r+1,e.maxShrinks),{authorBoundary:0,cancelledInPhase:n,shrinkCount:r};r++,Qo(r,lt.maxShrinks,c.newAuthorBoundary),t=c.newAuthorBoundary}}var vi=15e3,Ur=3,rs=[500,1e3];async function Nr(e){if(process.env.KANE_LOCK_CONFLICT_SIMULATE==="1")return{ok:!1,reason:"concurrent",httpStatus:409,message:"simulated contention (KANE_LOCK_CONFLICT_SIMULATE=1)"};let t=`${e.baseUrl}/test/${encodeURIComponent(e.testId)}/playground`,r=await $t(t,{from_commit_id:e.fromCommitId,new_commit_id:e.newCommitId},e.auth);return r.ok?{ok:!0,sessionExpiresAt:W(r.body,"session_expires_at")??""}:{ok:!1,...wi(r)}}function wi(e){let t=W(e.body,"error")??W(e.body,"code")??"",r=W(e.body,"message")??W(e.body,"detail")??e.text??`HTTP ${e.status}`,n;return e.status===0?n="network":e.status===401||e.status===403?n="auth":e.status===409&&t==="PlaygroundBaseCommitMismatch"?n="base_mismatch":e.status===409?n="concurrent":e.status===422?n="disabled":e.status===400&&/no committed/i.test(r)?n="no_commits":e.status===400?n="missing_field":e.status>=500||e.status===408||e.status===429?n="network":n="other",{reason:n,httpStatus:e.status,message:r}}async function os(e){let t=`${e.baseUrl}/test/${encodeURIComponent(e.testId)}/playground/reserve`,r=await $t(t,void 0,e.auth);return r.ok?{ok:!0,sessionExpiresAt:W(r.body,"session_expires_at")??""}:{ok:!1,expired:r.status===404,httpStatus:r.status,message:W(r.body,"message")??W(r.body,"detail")??r.text??`HTTP ${r.status}`}}async function Br(e){let t=`${e.baseUrl}/test/${encodeURIComponent(e.testId)}/commit`,r={commit_id:e.body.commitId,from_commit_id:e.body.fromCommitId,commit_message:e.body.commitMessage,total_steps:e.body.totalSteps};e.body.timeTaken!==void 0&&(r.time_taken=e.body.timeTaken),e.body.objectives!==void 0&&(r.objectives=e.body.objectives),e.body.testInstanceId!==void 0&&(r.test_instance_id=e.body.testInstanceId),e.body.trigger!==void 0&&(r.trigger=e.body.trigger);let n=await $t(t,r,e.auth);return n.ok?{ok:!0,testId:W(n.body,"test_id")??e.testId,testcaseId:W(n.body,"testcase_id")??"",projectId:W(n.body,"project_id"),isTestCaseDeleted:typeof n.body?.is_test_case_deleted=="boolean"?n.body.is_test_case_deleted:void 0}:{ok:!1,...Ii(n)}}function Ii(e){let t=W(e.body,"error")??W(e.body,"code")??"",r=W(e.body,"message")??W(e.body,"detail")??e.text??`HTTP ${e.status}`,n;return e.status===0?n="network":e.status===401||e.status===403?n="auth":e.status===409&&t==="PlaygroundBaseCommitMismatch"?n="base_mismatch":e.status===409&&t==="PlaygroundCommitLockMismatch"?n="lock_mismatch":e.status===409?n="expired":e.status===422?n="not_found":e.status>=500||e.status===408||e.status===429?n="network":n="other",{reason:n,httpStatus:e.status,message:r}}async function De(e){let t=`${e.baseUrl}/test/${encodeURIComponent(e.testId)}/commit`,r={discard:!0,commit_id:e.body.commitId,from_commit_id:e.body.fromCommitId,commit_message:"(discarded)",total_steps:1},n=await $t(t,r,e.auth);return n.ok?{ok:!0}:{ok:!1,reason:W(n.body,"error")??"other",httpStatus:n.status,message:W(n.body,"message")??W(n.body,"detail")??n.text??`HTTP ${n.status}`}}async function $t(e,t,r){let n=null;for(let o=1;o<=Ur;o++){let s=new AbortController,l=setTimeout(()=>s.abort(),vi);try{let f=await Y(e,{method:"POST",headers:{Authorization:xt(r.username,r.accessKey),"Content-Type":"application/json",Accept:"application/json"},...t!==void 0?{body:JSON.stringify(t)}:{},signal:s.signal});clearTimeout(l);let i=await f.text(),c=null;if(i)try{c=JSON.parse(i)}catch{}let v=f.status>=500||f.status===408||f.status===429;if(f.ok||!v)return{ok:f.ok,status:f.status,body:c,text:i};if(o<Ur){await ns(rs[o-1]??1e3);continue}return{ok:!1,status:f.status,body:c,text:i}}catch(f){if(clearTimeout(l),n=f,o<Ur){await ns(rs[o-1]??1e3);continue}}}return{ok:!1,status:0,body:null,text:n?.message??"exhausted retries"}}function ns(e){return new Promise(t=>setTimeout(t,e))}function W(e,t){if(typeof e!="object"||e===null)return;let r=e[t];return typeof r=="string"?r:void 0}var _i=60*1e3,ss="lock-heartbeat",ke=new Map,dt=null,ki={register:(e,t)=>Tt(e,t),deregister:e=>qn(e),cleanup:(e,t)=>Gn(e,t),remoteLogger:null};function is(e){if(e!==void 0){let t=ke.get(e);t!==void 0&&(clearInterval(t),ke.delete(e));return}for(let t of ke.values())clearInterval(t);ke.clear()}function Mt(e){if(ke.has(e.testId))return;let t=e.lifecycle??ki,r=setInterval(async()=>{let n=await os({baseUrl:e.baseUrl,testId:e.testId,auth:e.auth});if(!n.ok){let o=n.expired?"session expired":n.message;process.stderr.write(`[lock] heartbeat failed (${e.testId}): ${o}; continuing run
|
|
12
|
+
`)}},_i);ke.set(e.testId,r),dt===null&&(dt=t,t.register(ss,()=>is()))}function pe(e){ke.size!==0&&(is(e),ke.size===0&&dt!==null&&(dt.deregister(ss),dt=null))}import{readFileSync as as,readdirSync as ls,existsSync as Le,promises as $r}from"fs";import{join as de}from"path";async function Si(e,t){let r=de(e,"steps",`${t.ordinal}-${t.id}`),n,o=null,s=[];try{n=JSON.parse(await $r.readFile(de(r,"step.json"),"utf8")),o=n.action_id??null,Array.isArray(n.analyze_action_ids)&&(s=n.analyze_action_ids.filter(l=>typeof l=="string"))}catch{}if(typeof n?.screenshot=="string"&&/^screenshot\.(?:png|jpg)$/i.test(n.screenshot)){let l=n.screenshot;try{return{png:await $r.readFile(de(r,l)),filename:l,actionId:o,analyzeActionIds:s}}catch{}}for(let l of["screenshot.png","screenshot.jpg"])try{return{png:await $r.readFile(de(r,l)),filename:l,actionId:o,analyzeActionIds:s}}catch{}return null}function Qa(){let e=[];return{track:t=>{e.push(t.catch(()=>{}))},settle:async()=>{await Promise.all(e)}}}async function ds(e,t,r,n){try{let o=await Si(e,t);if(!o){n("warn","SCREENSHOT_SKIP","Pack step folder or screenshot not found",{ordinal:t.ordinal,id:t.id,reason:"pack_step_not_found"});return}let s=new Set;o.actionId&&s.add(o.actionId);for(let l of o.analyzeActionIds)s.add(l);if(s.size===0){n("warn","SCREENSHOT_SKIP","No action_id in step.json",{ordinal:t.ordinal,id:t.id,reason:"no_action_id"});return}for(let l of s)r.enqueue(l,o.png);n("info","SCREENSHOT_ENQUEUED","Screenshot enqueued",{ordinal:t.ordinal,id:t.id,action_id:o.actionId,action_ids:[...s],screenshot:o.filename,size:o.png.length})}catch(o){n("error","SCREENSHOT_DISPATCH_ERROR","Screenshot dispatch error",{ordinal:t.ordinal,id:t.id,error:o instanceof Error?o.message:String(o)})}}function cs(e,t,r,n,o,s){try{let l=de(e,"runs",String(t),"run-test");if(!Le(l)){o("warn","SCREENSHOT_SKIP","Runs dir not found",{step_index:r,reason:"runsDir_not_found",path:l});return}let f=l;if(s){let S=de(l,`child-${s}`);if(!Le(S)){o("warn","SCREENSHOT_SKIP","Child dir not found",{step_index:r,child_id:s,reason:"child_dir_not_found",path:S});return}let R=ls(S).filter(d=>Le(de(S,d,"screenshots")));if(R.length===0){o("warn","SCREENSHOT_SKIP","No screenshots dir under child",{step_index:r,child_id:s,reason:"no_child_screenshots_dir"});return}f=de(S,R[0])}else if(!Le(de(l,"screenshots"))){let S=ls(l).filter(R=>Le(de(l,R,"screenshots")));if(S.length===0){o("warn","SCREENSHOT_SKIP","No screenshots dir found",{step_index:r,reason:"no_screenshots_dir"});return}f=de(l,S[0])}let i=de(f,"screenshots",`step_${String(r).padStart(3,"0")}.png`);if(!Le(i)){o("warn","SCREENSHOT_SKIP","Screenshot not found",{step_index:r,child_id:s,reason:"screenshot_not_found",path:i});return}let c=de(l,"actions.ndjson");if(!Le(c)){o("warn","SCREENSHOT_SKIP","NDJSON not found",{step_index:r,reason:"ndjson_not_found"});return}let v=as(c,"utf-8").trim().split(`
|
|
13
|
+
`),m=v[v.length-1];if(!m){o("warn","SCREENSHOT_SKIP","NDJSON empty",{step_index:r,reason:"ndjson_empty"});return}let I=JSON.parse(m).action_id;if(!I){o("warn","SCREENSHOT_SKIP","No action_id in NDJSON",{step_index:r,reason:"no_action_id"});return}let A=as(i);n.enqueue(I,A),o("info","SCREENSHOT_ENQUEUED","Screenshot enqueued",{step_index:r,child_id:s,action_id:I,size:A.length})}catch(l){o("error","SCREENSHOT_DISPATCH_ERROR","Screenshot dispatch error",{step_index:r,error:l instanceof Error?l.message:String(l)})}}import{dirname as Ri,join as Ei}from"path";function us(e,t,r){let n=e.total_runs??1,o=e.run_dir,s,l;if(n>1&&o){let f=Ri(o);s=Array.from({length:n},(i,c)=>Ei(f,String(t+c))),r&&r.length===n&&(l=r)}return{allRunDirs:s,flowObjectives:l}}function ms(e,t,r,n){return{index:r,objective:t,summary:e.summary,oneLiner:e.one_liner,status:e.status,resultCode:e.result_code,reasonCode:e.reason_code,perFlowMetadata:e.per_flow_metadata,context:e.context??{memory:{},variables:{},pointer:""},run_dir:e.run_dir,run_dirs:n.allRunDirs,flow_objectives:n.flowObjectives}}var Vt=class{constructor(t){this.resolved=t;this.outcomes=t.rootSteps.map(r=>({rootStepIndex:r.index,status:"skipped"}))}outcomes;skipRoot=null;overallHalted=!1;shouldRunFlatStep(t){if(this.overallHalted)return!1;let r=t.trace[0].stepIndex;return!(this.skipRoot!==null&&r===this.skipRoot)}recordStep(t,r){let n=t.trace[0].stepIndex,o=this.outcomes.find(i=>i.rootStepIndex===n),s=this.resolved.rootSteps.find(i=>i.index===n),l=s.body.kind!=="objective";return l&&(o.refKind="import",o.refLabel=s.body.path,o.inlinedCount=(o.inlinedCount??0)+1,o.duration_s=(o.duration_s??0)+r.duration_s),r.status==="passed"?(l?o.status!=="failed"&&(o.status="passed"):(o.status="passed",o.duration_s=r.duration_s),{continueOverall:!0}):t.optional?(o.softFailures=o.softFailures??[],o.softFailures.push({subStepIndex:t.trace[t.trace.length-1].stepIndex,reason:r.reason}),{continueOverall:!0}):(o.status="failed",o.duration_s=l?o.duration_s:r.duration_s,o.failedSubStepIndex=l?t.trace.slice(1).map(i=>i.stepIndex):void 0,o.reason=r.reason,this.skipRoot=n,s.optional??!1?(o.softFailed=!0,{continueOverall:!0}):(this.overallHalted=!0,{continueOverall:!1}))}snapshotOutcomes(){return[...this.outcomes]}snapshot(){return{outcomes:this.outcomes.map(t=>({...t,softFailures:t.softFailures?[...t.softFailures]:void 0})),skipRoot:this.skipRoot,overallHalted:this.overallHalted}}rollback(t){this.outcomes=t.outcomes.map(r=>({...r,softFailures:r.softFailures?[...r.softFailures]:void 0})),this.skipRoot=t.skipRoot,this.overallHalted=t.overallHalted}finalize(){let t=this.outcomes.some(n=>n.status==="failed"&&!n.softFailed)?"failed":"passed",r=this.outcomes.reduce((n,o)=>n+(o.duration_s??0),0);return{overallStatus:t,outcomes:this.outcomes,totalDurationS:r}}};function Mr(e){if(!e)return null;let t=e.trim();return t?/^https?:\/\//i.test(t)?t:`https://${t}`:null}function fs(e){return Mr(e.flag)??Mr(e.frontmatter)??(e.configDefault&&e.configDefault!==ot?Mr(e.configDefault):null)}function ps(e){return e.resolvedUrl!==null?!1:!((!!e.local||!!e.allowMissingUrl)&&!e.isTTY)}import{spawn as Ci}from"child_process";async function gs(e,t,r=100){let n=`${e.replace(/\/+$/,"")}/json/version`,o=await Y(n);if(!o.ok)throw new Error(`CDP /json/version returned ${o.status}`);let s=await o.json();if(!s.webSocketDebuggerUrl)throw new Error("CDP /json/version missing webSocketDebuggerUrl");let l=new Bn(s.webSocketDebuggerUrl);await new Promise((h,E)=>{l.once("open",h),l.once("error",E)});let f=1,i=new Map;l.on("message",h=>{let E;try{E=JSON.parse(h.toString())}catch{return}if(E.id==null)return;let M=i.get(E.id);M&&(i.delete(E.id),E.error?M.reject(new Error(E.error.message)):M.resolve(E.result))});function c(h,E){let M=f++;return new Promise((Se,oe)=>{i.set(M,{resolve:te=>Se(te),reject:oe});let se={id:M,method:h};E&&(se.params=E),l.send(JSON.stringify(se))})}let m=(await c("Target.getTargets")).targetInfos.find(h=>h.type==="page");if(!m)throw l.close(),new Error("CDP: no page target found");let I=(await c("Browser.getWindowForTarget",{targetId:m.targetId})).windowId,A="",S=!1,R=null,d=!1;l.on("close",()=>{d=!0}),l.on("error",()=>{d=!0});async function F(){if(!S){if(d){S=!0;return}try{let E=(await c("Browser.getWindowBounds",{windowId:I})).bounds,M=`${E.left}:${E.top}:${E.width}:${E.height}`;M!==A&&(A=M,t({left:E.left,top:E.top,width:E.width,height:E.height}))}catch{}S||(R=setTimeout(F,r))}}return F(),{stop(){if(!S){S=!0,R&&clearTimeout(R);try{l.close()}catch{}}}}}var Ai=new Set(["1","true","yes"]);function Vr(e){if(e?.headless)return null;let t=process.env.KANE_CLI_DISABLE_MARKER;if(t!=null&&Ai.has(t.toLowerCase()))return null;let r=Lt();if(!r)return null;let n=[...r.args,"overlay"];e?.text&&n.push(e.text);let o;try{o=Ci(r.cmd,n,{cwd:r.cwd,stdio:["pipe","ignore","ignore"],detached:!1,windowsHide:!0})}catch{return null}o.stdin?.on("error",()=>{});let s=!1;o.on("exit",()=>{s=!0}),o.on("error",()=>{s=!0});function l(c){if(!(s||!o.stdin||o.stdin.destroyed))try{o.stdin.write(JSON.stringify(c)+`
|
|
14
|
+
`)}catch{}}e?.chromePid&&e.chromePid>0&&l({type:"chrome_pid",pid:e.chromePid});let f=null;e?.cdpEndpoint&&gs(e.cdpEndpoint,c=>l({type:"bounds",...c})).then(c=>{f=c.stop}).catch(()=>{});let i=!1;return{setRunActive(c){i||l({type:"run_active",active:c})},setStepText(c){if(i)return;let v=c.trim();v&&l({type:"step_text",text:v})},setStepComplete(){i||l({type:"step_complete"})},kill(){if(!i){i=!0,f?.();try{o.stdin?.end()}catch{}try{o.kill("SIGTERM")}catch{}}}}}function hs(e,t,r){return`${e}/projects/${t}/test-cases/${r}`}function Kt(e,t,r,n){return`${hs(e,t,r)}/dashboard/share/${n}?type=summary&agentView=true&fqdn=summary-page`}function ys(e,t,r,n){if(!(!t||!r||!n))return Kt(e,t,r,n)}function bs(e,t,r){return`${hs(e,t,r)}/dashboard?type=summary&agentView=true&fqdn=summary-page`}import{mkdtempSync as Vi,rmSync as Ki}from"fs";import{join as Hi}from"path";import{tmpdir as qi}from"os";import{spawn as Is,spawnSync as xi}from"child_process";import{existsSync as Kr}from"fs";import{createConnection as Pi}from"net";import{homedir as Ve,platform as ut}from"os";import{join as Ke}from"path";var Ti=new Set(["1","true","yes"]),Ht=class extends Error{constructor(t){super(t),this.name="ChromeNotFoundError"}};function wl(e){return e instanceof Ht?e.message:`Chrome failed: ${e instanceof Error?e.message:String(e)}`}var qt={darwin:["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",Ke(Ve(),"Applications/Google Chrome.app/Contents/MacOS/Google Chrome"),"/Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing",Ke(Ve(),"Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"),"/Applications/Chromium.app/Contents/MacOS/Chromium"],linux:["/usr/bin/google-chrome","/usr/bin/google-chrome-stable","/usr/bin/google-chrome-for-testing","/usr/local/bin/google-chrome-for-testing",Ke(Ve(),"chrome-for-testing/chrome-linux64/chrome"),"/usr/bin/chromium","/usr/bin/chromium-browser","/snap/bin/chromium"],win32:["C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe","C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",Ke(Ve(),"AppData\\Local\\Google\\Chrome\\Application\\chrome.exe"),"C:\\chrome-for-testing\\chrome-win64\\chrome.exe",Ke(Ve(),"AppData\\Local\\chrome-for-testing\\chrome-win64\\chrome.exe"),Ke(Ve(),"AppData\\Local\\kane-chrome\\chrome.exe")]};function _s(){let e=process.env.KANE_CLI_CHROME_PATH?.trim();return e||void 0}function Di(){let e=_s();if(e)return e;let t=ut(),r=qt[t]??qt.linux;for(let n of r)if(Kr(n))return n;return t==="win32"?"chrome.exe":"google-chrome"}function Li(){let e=_s();if(e)return Kr(e);let t=ut();if((qt[t]??qt.linux).some(s=>Kr(s)))return!0;let n=t==="win32"?"chrome.exe":"google-chrome",o=t==="win32"?"where":"which";try{return xi(o,[n],{stdio:"ignore"}).status===0}catch{return!1}}function Oi(){let e=ut();return e==="darwin"?["Google Chrome is required but was not found at any standard path.","","Install via Homebrew (recommended):"," brew install --cask google-chrome","","Or download:"," https://www.google.com/chrome/","","Then re-run your command. Set KANE_CLI_CHROME_PATH=/path/to/chrome","to point at a non-standard install."].join(`
|
|
15
|
+
`):e==="linux"?["Google Chrome is required but was not found at /usr/bin/google-chrome.","(amd64 / x86_64 only \u2014 Google does not ship Chrome for Linux ARM.)","","Debian / Ubuntu (any version):"," wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"," sudo apt install -y ./google-chrome-stable_current_amd64.deb","","Fedora / RHEL / AlmaLinux / Rocky:"," sudo dnf install -y https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm","","Then re-run your command. Set KANE_CLI_CHROME_PATH=/path/to/chrome","to point at a non-standard install."].join(`
|
|
16
|
+
`):e==="win32"?["Google Chrome is required but was not found in Program Files or AppData.","","Install via winget (Windows 10 1809+):"," winget install --id Google.Chrome -e --silent","","Or download:"," https://www.google.com/chrome/","","Then re-run your command. Set KANE_CLI_CHROME_PATH=C:\\path\\to\\chrome.exe","to point at a non-standard install."].join(`
|
|
17
|
+
`):["Google Chrome is required.","Install from https://www.google.com/chrome/","(Note: no official Chrome builds for BSD or Alpine/musl Linux.)"].join(`
|
|
18
|
+
`)}function ji(e){let t=ut(),r=[`--remote-debugging-port=${e.port}`,`--user-data-dir=${e.userDataDir}`,`--window-size=${e.width},${e.height}`,"--no-first-run","--no-default-browser-check","--disable-blink-features=AutomationControlled","--disable-features=DownloadBubble,DownloadBubbleV2","--safebrowsing-disable-download-protection","--disable-popup-blocking","--disable-notifications","--disable-infobars","--disable-translate","--disable-prompt-on-repost","--disable-background-networking","--disable-client-side-phishing-detection","--disable-default-apps","--disable-hang-monitor","--disable-sync","--metrics-recording-only","--safebrowsing-disable-auto-update","--disable-backgrounding-occluded-windows","--disable-background-timer-throttling","--test-type=webdriver","--allow-pre-commit-input","--enable-logging","--v=1"];return t==="linux"&&(r.push("--no-sandbox"),r.push("--disable-dev-shm-usage"),r.push("--password-store=basic")),t==="darwin"&&r.push("--use-mock-keychain"),e.headless&&r.push("--headless=new"),r}function Fi(e){return new Promise(t=>{let r=Pi({port:e,host:"127.0.0.1"});r.setTimeout(1e3),r.on("connect",()=>{r.destroy(),t(!0)}),r.on("timeout",()=>{r.destroy(),t(!1)}),r.on("error",()=>{r.destroy(),t(!1)})})}async function Ui(){for(let e=pr;e<=gr;e++)if(!await Fi(e))return e;throw new Error(`All CDP ports ${pr}-${gr} are in use. Close other Chrome instances.`)}var ct=class extends Error{constructor(t){super(t),this.name="CdpReadinessError"}};async function Ni(e,t){let r=Date.now(),n=`http://127.0.0.1:${e}/json/version`;for(;Date.now()-r<t;){try{if((await Y(n)).ok)return`http://127.0.0.1:${e}`}catch{}await new Promise(o=>setTimeout(o,200))}throw new ct(`Chrome CDP not ready after ${t}ms on port ${e}`)}var Bi=3e4,$i=2;function vs(e,t,r){let n=process.env[e];if(n==null||n.trim()==="")return t;let o=Number(n);return!Number.isInteger(o)||o<r?t:o}function Mi(e){return Math.min(500*e,3e3)}function ws(e,t){try{if(e.pid)if(t==="win32")Is("taskkill",["/pid",String(e.pid),"/T","/F"],{stdio:"ignore"});else try{process.kill(-e.pid,"SIGKILL")}catch{e.kill("SIGKILL")}else e.kill("SIGKILL")}catch{}}async function ks(e){let t=process.env.KANE_CLI_SKIP_BROWSER_DOWNLOAD;if(!(t!=null&&Ti.has(t.toLowerCase()))&&!Li())throw hr()?.log("error","CHROME_NOT_FOUND","Startup gate: Chrome unavailable at standard system paths",{platform:process.platform,kane_cli_chrome_path:process.env.KANE_CLI_CHROME_PATH??null,skip_browser_download:process.env.KANE_CLI_SKIP_BROWSER_DOWNLOAD??null}),new Ht(Oi());let n=ut(),o=Di(),s=vs("KANE_CLI_CDP_TIMEOUT_MS",Bi,1),f=vs("KANE_CLI_CDP_RETRIES",$i,0)+1,i;for(let c=1;c<=f;c++){let v=await Ui(),m=ji({port:v,...e});e.startUrl&&m.push(e.startUrl);let y=Is(o,m,{stdio:"ignore",detached:!0});y.unref();try{let I=await new Promise((A,S)=>{y.on("error",R=>{S(new Error(`Failed to launch Chrome: ${R.message}. Is Chrome installed at ${o}?`))}),y.on("close",R=>{R!==null&&R!==0&&S(new ct(`Chrome exited during startup with code ${R}`))}),Ni(v,s).then(A,S)});return{process:y,port:v,cdpEndpoint:I,kill(){ws(y,n)}}}catch(I){if(i=I,!(I instanceof ct))throw I;ws(y,n),hr()?.log("warn","CHROME_CDP_LAUNCH_RETRY",`Chrome CDP launch attempt ${c}/${f} failed`,{attempt:c,max_attempts:f,port:v,timeout_ms:s,headless:e.headless??!1,error:I.message}),c<f&&await new Promise(A=>setTimeout(A,Mi(c)))}}throw i??new Error("Chrome launch failed after retries")}async function Hr(e){if(e.cft)return{instance:null,tempDir:null};if(e.wsEndpoint)return{wsEndpoint:e.wsEndpoint,instance:null,tempDir:null};if(e.cdpEndpoint){let o=await Y(`${e.cdpEndpoint}/json/version`);if(!o.ok)throw new Error(`CDP endpoint not reachable: ${e.cdpEndpoint} (${o.status})`);return{cdpEndpoint:e.cdpEndpoint,instance:null,tempDir:null}}let t,r=null;if(e.config.chrome_profile_path)t=e.config.chrome_profile_path.replace("~",process.env.HOME??"~");else{r=Vi(Hi(qi(),"kane-clean-")),t=r;let o=r;Tt("tempDir",()=>{try{Ki(o,{recursive:!0,force:!0})}catch{}})}let n=await ks({userDataDir:t,width:e.config.window_size.width,height:e.config.window_size.height,startUrl:e.startUrl,headless:e.headless});return{cdpEndpoint:n.cdpEndpoint,instance:n,tempDir:r}}async function Ss(e,t){if(e==="device"){let{device:r,appRef:n,appId:o}=await t.prepareDevice();return{kind:"device",device:r,...n?{appRef:n}:{},...o?{appId:o}:{}}}return{kind:"web",chrome:await t.prepareWeb()}}function Pl(e,t={}){if(e.kind==="device"){let r=e.device.target_kind;return r==="emulator"||r==="simulator"?r:void 0}if(e.chrome.instance)return"chrome";if(t.cdpEndpoint)return"cdp";if(t.wsEndpoint)return"ws"}function Tl(e,t){if(!(e.kind!=="device"||e.device.target_kind!=="simulator"))return t?Mn(t):void 0}function Dl(e){if(e.kind!=="device")return;let t=e.device.target_kind;if(!(t!=="emulator"&&t!=="simulator"))return e.appRef??""}function qr(e){let t={objective:e.objective,model:e.model,width:e.windowSize.width,height:e.windowSize.height,session_id:e.sessionId,run_index:e.runIndex,max_steps:e.maxSteps??30,headless:e.headless??!1};return e.conditions&&e.conditions.length>0&&(t.conditions=[...e.conditions]),e.url&&(t.url=e.url),e.requireStartUrl&&(t.require_start_url=!0),e.chrome.wsEndpoint?t.ws_endpoint=e.chrome.wsEndpoint:e.chrome.cdpEndpoint&&(t.cdp_endpoint=e.chrome.cdpEndpoint),e.auth.basicAuth?(t.username=e.auth.basicAuth.username,t.access_key=e.auth.basicAuth.access_key):e.auth.token&&(t.auth={type:"bearer",token:e.auth.token}),e.auth.resolvedCreds?.org_id&&(t.org_id=String(e.auth.resolvedCreds.org_id)),e.disableAskUser&&(t.disable_ask_user=!0),e.enableTaskSkills&&(t.enable_task_skills=!0),e.networkWs&&(t.network_ws=!0),e.networkSse&&(t.network_sse=!0),(e.bugDetection==="stop"||e.bugDetection==="continue")&&(t.bug_detection=e.bugDetection),e.variables&&Object.keys(e.variables).length>0&&(t.variables=e.variables),e.globalContext&&(t.global_context=e.globalContext),e.localContext&&(t.local_context=e.localContext),e.sessionContext&&(t.session_context=e.sessionContext),e.device&&(t.device=e.device),e.evidence&&(t.evidence=Ut(e.evidence.packTestDir,e.evidence.ordinalOffset)),t}import{existsSync as Gi,readFileSync as zi}from"fs";import{join as Yi}from"path";var Gt={max_retries:5,settle_ms:500,on_exhaust:"fail"},He=class{constructor(t,r,n){this.steps=t;this.decisions=r;this.deps=n;for(let o=0;o<t.length;o++){let s=t[o];if(s.controlFlow!=="if"&&s.controlFlow!=="while")continue;let l=s.block,f=t.map((y,I)=>[y,I]).filter(([y])=>y.block?.id===l.id&&y.block.depth===l.depth),i=f.find(([y])=>y.block.branch===-1)[1],c=f.filter(([y])=>y.controlFlow!==void 0&&y.block.branch!==-1).map(([,y])=>y),v=c.filter(y=>t[y].controlFlow!=="else").map(y=>t[y].objective),m={kind:s.controlFlow,opener:o,closer:i,markers:c,conditions:v,hasElse:t[c[c.length-1]].controlFlow==="else"};this.blocks.set(o,m),this.closers.set(i,m)}}blocks=new Map;closers=new Map;skip=new Set;attempts=new Map;taken=new Map;whileRuns=new Map;static hasBlocks(t){return t.some(r=>r.block!==void 0)}reset(){this.skip.clear(),this.attempts.clear(),this.taken.clear(),this.whileRuns.clear()}outcomes(){let t={};for(let[n,o]of this.taken)t[this.steps[n].flatIndex]=o;let r={};for(let[n,o]of this.whileRuns)r[this.steps[n].flatIndex]={...o};return{taken:t,whileRuns:r}}range(t,r){let n=t.markers[r]+1,o=r+1<t.markers.length?t.markers[r+1]:t.closer,s=[];for(let l=n;l<o;l++)s.push(l);return s}skipBranch(t,r){for(let n of this.range(t,r))this.skip.add(n)}unskipBody(t){for(let r=t.opener+1;r<t.closer;r++)this.skip.delete(r)}async judge(t){let r=await this.deps.evaluate(t),n=r.findIndex(o=>o==null);return n!==-1||r.length<t.length?{fail:`condition could not be judged: ${t[n===-1?r.length:n]}`}:r}async before(t){if(this.skip.has(t))return{action:"skip"};let n=this.steps[t].controlFlow;if(n==="if"){let s=this.blocks.get(t),l=await this.judge(s.conditions);if("fail"in l)return{action:"fail",reason:l.fail};let f=l.findIndex(i=>i===!0);f===-1&&s.hasElse&&(f=s.markers.length-1),this.taken.set(t,f);for(let i=0;i<s.markers.length;i++)i!==f&&this.skipBranch(s,i);return{action:"structural"}}if(n==="while"){let s=this.blocks.get(t);this.attempts.set(t,0);let l=await this.judge(s.conditions);return"fail"in l?{action:"fail",reason:l.fail}:(this.whileRuns.set(t,{iterations:l[0]?1:0,condition_met:!l[0]}),l[0]||this.skipBranch(s,0),{action:"structural"})}if(n==="end-while"){let s=this.closers.get(t);if(!(s.opener+1===s.closer)&&this.skip.has(s.opener+1))return{action:"structural"};let f=this.deps.whileConfig(s.opener),i=(this.attempts.get(s.opener)??0)+1;this.attempts.set(s.opener,i);let c=this.whileRuns.get(s.opener)??{iterations:i,condition_met:!1};if(c.iterations=i,this.whileRuns.set(s.opener,c),i>=f.max_retries)return f.on_exhaust==="fail"?{action:"fail",reason:`while exhausted after ${i} iteration(s): ${s.conditions[0]}`}:{action:"structural"};await this.deps.sleep(f.settle_ms);let v=await this.judge(s.conditions);return"fail"in v?{action:"fail",reason:v.fail}:v[0]?(this.unskipBody(s),c.iterations=i+1,{action:"jump",to:s.opener+1}):(c.condition_met=!0,{action:"structural"})}if(n!==void 0)return{action:"structural"};let o=this.decisions[t];return o?.kind==="replay"&&o.unrecorded?{action:"author"}:{action:"run"}}};function Gr(e){try{let t=Co(e),r=So(e.owningFile,e.trace[e.trace.length-1].stepIndex,t.slice(0,8)),n=Yi(r,"flows","0","actions.ndjson");if(!Gi(n))return null;let o=zi(n,"utf8").split(`
|
|
19
|
+
`).find(s=>s.trim().length>0);return o?JSON.parse(o):null}catch{return null}}function zt(e){let t=Gr(e);if(!t||t.action_type!=="while")return{...Gt};let r=t.action_params??{};return{max_retries:typeof r.max_retries=="number"&&r.max_retries>0?r.max_retries:Gt.max_retries,settle_ms:typeof r.settle_ms=="number"&&r.settle_ms>=0?r.settle_ms:Gt.settle_ms,on_exhaust:typeof r.on_exhaust=="string"&&r.on_exhaust?r.on_exhaust:Gt.on_exhaust}}import{readdirSync as Wi,readFileSync as Es,existsSync as Cs}from"fs";import{join as Ji}from"path";function zr(e,t){let r=t.type==="parameter";return{value:typeof t.value=="number"?String(t.value):t.value,secret:t.secret??!1,syntax:t.syntax??(r?"${"+e+"}":`{{${e}}}`),...typeof t.type=="string"?{type:t.type}:{},...typeof t.description=="string"?{description:t.description}:{}}}function Rs(e,t){if(!Cs(e))return{};let r={},n;try{n=Wi(e).filter(o=>o.endsWith(".json")).sort()}catch{return{}}for(let o of n)try{let s=Es(Ji(e,o),"utf-8"),l=JSON.parse(s);if(l&&typeof l=="object")for(let[f,i]of Object.entries(l))i&&typeof i=="object"&&"value"in i&&(r[f]=zr(f,i))}catch{t?t("warn","VARIABLE_PARSE_FAILED","Skipping invalid variables file",{file:o}):process.stderr.write(`[variables] Warning: skipping invalid variables file: ${o}
|
|
20
|
+
`)}return r}function As(e){if(!Cs(e))throw new Error(`Variables file not found: ${e}`);let t=Es(e,"utf-8"),r=JSON.parse(t),n={};if(r&&typeof r=="object")for(let[o,s]of Object.entries(r))s&&typeof s=="object"&&"value"in s&&(n[o]=zr(o,s));return n}function xs(e){let t;try{t=JSON.parse(e)}catch{throw new Error("Invalid --variables JSON")}let r={};if(t&&typeof t=="object")for(let[n,o]of Object.entries(t))o&&typeof o=="object"&&"value"in o&&(r[n]=zr(n,o));return r}function Ps(e,t,r){let n=Rs(e,r),o=Rs(t,r);return{...n,...o}}var qe=class{constructor(t){this.baseUrl=t}async pushSecret(t){let r=xt(t.username,t.accessKey),n=await Y(`${this.baseUrl}/logistics/v1.0/secrets/create`,{method:"PUT",headers:{Authorization:r,"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({secretKey:t.secretKey,secretValue:t.secretValue,orgId:t.orgId,username:t.username,scope:"user",type:"user",accessKey:t.accessKey})});if(!n.ok)throw new Error(`Push secret failed: ${n.status} ${await n.text()}`)}static extractVariableKeys(t){let r=t.matchAll(/\{\{([a-zA-Z_][a-zA-Z0-9_]*)\}\}/g),n=new Set;for(let o of r)n.add(o[1]);return[...n]}};var Ge=class extends Pt{constructor(t,r,n){super(t,{username:r,accessKey:n})}async upsertVariable(t){let r=t.environmentId??0,n=await Y(`${this.baseUrl}/v1/variables`,{method:"POST",headers:this.headers(),body:JSON.stringify({name:t.name,value:String(t.value),type:"variable",value_type:"string",is_persist:t.isPersist??!1,environment_id:r})});if(n.ok){let i=await n.json().catch(()=>({}));if(i.type==="Success"&&i.id!=null)return{id:Number(i.id)||0}}let o=await Y(`${this.baseUrl}/v1/variables/${encodeURIComponent(t.name)}?environment_id=${r}`,{method:"GET",headers:this.headers()});if(!o.ok)return{id:0};let l=(await o.json().catch(()=>({}))).data?.id;return l==null?{id:0}:(await Y(`${this.baseUrl}/v1/variables/${l}`,{method:"PUT",headers:this.headers(),body:JSON.stringify({value:String(t.value),value_type:"string"})})).ok?{id:Number(l)||0}:{id:0}}};function Ts(e,t){if(Object.keys(e).length===0)return{};let r={};for(let[n,o]of Object.entries(e)){let s=o.syntax??`{{${n}}}`;Zi(t,s)&&(r[n]=o)}return r}function Qi(e){let t=e.trim();return t.startsWith("{{")&&t.endsWith("}}")?t.slice(2,-2).trim():t.startsWith("${")&&t.endsWith("}")?t.slice(2,-1).trim():t}function Zi(e,t){if(!t||!e)return!1;if(e.includes(t))return!0;let r=Qi(t);if(!r)return!1;let n=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(?:\\{\\{|\\$\\{)\\s*${n}(?=\\s*\\}|[.\\[])`).test(e)}function Ds(e){let t=Ps(e.globalDir,e.localDir,e.onLoadError),r=e.file?As(e.file):{},n=e.inline?xs(e.inline):{},o={...t,...r,...n,...e.parameters??{}},s=Object.keys(o).length>0,{variables:l,objective:f}=s?$e(o,e.objective):{variables:{},objective:e.objective};return{raw:o,auteur:l,auteurObjective:f,...Yr(o)}}function Yr(e){let t=Object.entries(e),r=t.filter(([,o])=>st(o)),n=t.filter(([,o])=>!st(o));return{secretEntries:n.filter(([,o])=>o.secret),nonSecretEntries:n.filter(([,o])=>!o.secret),parameterEntries:r}}async function Ls(e){if(e.localMode)return{};let t=X(e.env);if(e.variables.secretEntries.length>0){let n=new qe(t.secretsBaseUrl);for(let[o,s]of e.variables.secretEntries)n.pushSecret({secretKey:o,secretValue:s.value,username:e.auth.username,accessKey:e.auth.access_key,orgId:e.orgId}).then(()=>e.log("info","SECRET_PUSH_OK","Secret pushed",{key:o})).catch(l=>e.log("error","SECRET_PUSH_FAILED","Secret push failed",{key:o,error:String(l)}))}let r={};if(e.variables.nonSecretEntries.length>0){let n=new Ge(t.tmsBaseUrl,e.auth.username,e.auth.access_key);for(let[o,s]of e.variables.nonSecretEntries)try{let l=await n.upsertVariable({name:o,value:s.value});r[o]=l.id,e.log("info","VAR_PUSH_OK","Variable pushed",{name:o,id:l.id})}catch(l){e.log("error","VAR_PUSH_FAILED","Variable push failed",{name:o,error:String(l)})}}return r}import{mkdirSync as Xi,writeFileSync as ea}from"fs";import{join as Os}from"path";var Yt=class extends Pt{constructor(t,r,n){super(t,{username:r,accessKey:n})}async getDataset(t,r){let n=`/v1/dataset/${encodeURIComponent(t)}`,o=r?.versionId?`?version_id=${encodeURIComponent(r.versionId)}`:"",s=await Y(`${this.baseUrl}${n}${o}`,{method:"GET",headers:this.headers()}),l=await s.text();if(!s.ok){let c=l.trim();try{let v=JSON.parse(l);typeof v.message=="string"&&v.message&&(c=v.message)}catch{}throw new Error(`GET ${n} failed: ${s.status} ${c}`)}let f;try{f=JSON.parse(l)}catch{throw new Error(`dataset ${t}: response is not JSON`)}let i=f;if(!i||!Array.isArray(i.headers)||!Array.isArray(i.rows))throw new Error(`dataset ${t}: response carries no headers / rows`);return i}};async function js(e){let{id:t,row:r}=e.selection,n=new Yt(e.tmsBaseUrl,e.auth.username,e.auth.access_key),o;try{o=await n.getDataset(t)}catch(v){throw new Error(`dataset ${t}: ${v.message}`)}let s=Os(e.saveDir,"dataset"),l=Os(s,`${t}.json`);try{Xi(s,{recursive:!0}),ea(l,JSON.stringify(o,null,2)+`
|
|
21
|
+
`,"utf8")}catch(v){e.log?.("warn","DATASET_SAVE_FAILED","Could not save the fetched dataset",{path:l,error:String(v)})}let f;try{f=Wn(o,r)}catch(v){throw new Error(`dataset ${t}: ${v.message}`)}let i=Jn(o,f.row),c=typeof o.latest_version_id=="string"&&o.latest_version_id?o.latest_version_id:void 0;return e.log?.("info","DATASET_ROW_LOADED","Dataset row loaded as parameters",{dataset_id:t,row_id:f.id,row_index:f.index,columns:Object.keys(i)}),{selection:e.selection,dataset:o,rowIndex:f.index,rowId:f.id,versionId:c,externalId:eo(t,f.id,c),parameters:i,testParams:Qn(o,f.row),columns:new Set(Object.keys(i)),savedPath:l}}import{readFileSync as ta,existsSync as ra}from"fs";function Wr(e){if(!ra(e))return null;try{return ta(e,"utf-8").trim()||null}catch{return null}}var na=()=>{};async function Fs(e,t,r){let n=t.log??na,o=e.session.testId??null,s=null,l=null,f=null;if(!r.localMode&&t.performUpload)try{s=await t.performUpload(),s?.success&&(s.testId&&(o=s.testId),s.testcaseId&&e.session.setTestcaseId(s.testcaseId))}catch(i){n("error","FINALIZE_UPLOAD_ERROR","Upload pipeline threw",{error:String(i)})}if(t.renderFeedbackPrompt)try{l=await t.renderFeedbackPrompt(),l&&o&&t.submitFeedback&&t.submitFeedback(o,l).catch(i=>{n("error","FINALIZE_FEEDBACK_SUBMIT_ERROR","Feedback submit failed",{error:String(i)})})}catch(i){n("error","FINALIZE_FEEDBACK_RENDER_ERROR","Feedback prompt threw",{error:String(i)})}if(e.session.flushRecorder(),r.skipLocalWrites)n("info","FINALIZE_SKIP_LOCAL_WRITES","Skipping local writes (testmd flow handles via staging)");else if(r.sourcePath&&r.rootSteps&&r.outcomes){try{f=Ar({sourcePath:r.sourcePath,title:r.title,rootSteps:r.rootSteps,outcomes:r.outcomes,overallStatus:r.overallStatus,startedISO:r.startedISO,durationS:r.durationS,sessionId:e.session.sessionId})}catch(i){n("error","FINALIZE_RESULT_MD_ERROR","_Result.md write failed",{error:String(i)})}try{Er({sourcePath:r.sourcePath,commitId:e.session.sessionId,testId:o??void 0,testcaseId:e.session.testcaseId??void 0,projectId:e.tuiConfig.project_id??void 0,folderId:e.tuiConfig.folder_id??void 0,orgId:e.session.orgId??void 0,sessionName:e.session.sessionName??it(r.sourcePath),plan:e.session.plan??void 0,media:Tr({priorMetaPath:ve(r.sourcePath),recordFiles:Pr(e.session.sessionDir)}),tcId:Rr(r.sourcePath)})}catch(i){n("error","FINALIZE_META_WRITE_ERROR","meta.json write failed",{error:String(i)})}if(s?.codeExportDir)try{let i=Sr(e.tuiConfig.code_export?.language??"python",r.mobile);Dr(s.codeExportDir,kr(r.sourcePath,i.framework,i.language))}catch(i){n("error","FINALIZE_CODE_COPY_ERROR","code-export copy failed",{error:String(i)})}}else if(e.session.recorder?.lastWrittenPath){let i=e.session.recorder.lastWrittenPath,c=e.session.getFlows(),v=c.map((I,A)=>({index:A+1,heading:`Step ${A+1}`,verifies:[],headingLine:0,body:{kind:"objective",text:I.objective}})),m=c.map((I,A)=>({rootStepIndex:A+1,status:I.status==="passed"?"passed":I.status==="failed"?"failed":"skipped",duration_s:I.duration,reason:I.reason})),y=m.some(I=>I.status==="failed")?"failed":"passed";try{f=Ar({sourcePath:i,title:e.session.sessionName??"Session",rootSteps:v,outcomes:m,overallStatus:y,startedISO:e.session.startedAt,durationS:m.reduce((I,A)=>I+(A.duration_s??0),0),sessionId:e.session.sessionId})}catch(I){n("error","FINALIZE_TUI_RESULT_MD_ERROR","TUI _Result.md write failed",{error:String(I)})}try{Er({sourcePath:i,commitId:e.session.sessionId,testId:o??void 0,testcaseId:e.session.testcaseId??void 0,sessionName:e.session.sessionName??void 0,projectId:e.tuiConfig.project_id??void 0,folderId:e.tuiConfig.folder_id??void 0,plan:e.session.plan??void 0,media:Tr({priorMetaPath:ve(i),recordFiles:Pr(e.session.sessionDir)}),tcId:Rr(i)})}catch(I){n("error","FINALIZE_TUI_META_WRITE_ERROR","TUI meta.json write failed",{error:String(I)})}if(s?.codeExportDir)try{let I=Sr(e.tuiConfig.code_export?.language??"python",r.mobile);Dr(s.codeExportDir,kr(i,I.framework,I.language))}catch(I){n("error","FINALIZE_TUI_CODE_COPY_ERROR","TUI code-export copy failed",{error:String(I)})}e.session.recorder.lastCollisionSuffixed&&process.stderr.write(`Saved to ${i} (renamed: ${e.session.sessionName}_test.md already existed)
|
|
22
|
+
`)}try{t.runCleanup?.()}catch(i){n("error","FINALIZE_CLEANUP_ERROR","Cleanup hook threw",{error:String(i)})}try{await e.session.finish("complete")}catch(i){n("error","FINALIZE_SESSION_FINISH_ERROR","session.finish threw",{error:String(i)})}return{uploadResult:s,feedbackChoice:l,resultMdPath:f}}import{readFileSync as Qr,writeFileSync as Zr,existsSync as Vs}from"fs";function Us(e,t,r){if(r.forceAuthor)return"re-recorded from scratch";if(r.retryTriggered)return"re-recorded after retry";if(t.length>0&&t.every(l=>l.kind==="author"&&l.reason==="no-result-md"))return"initial recording";if(t.length>0&&t.every(l=>l.kind==="replay"))return r.wantsPush?"re-recorded (no source changes)":"no changes";let n=[];for(let l=0;l<t.length;l++){let f=t[l];if(!f||f.kind!=="author"||f.reason==="downstream-of-divergence"||f.reason==="no-result-md")continue;let i=oa(e,e.steps[l]);switch(f.reason){case"structure-mismatch":n.push(`added/removed: ${i}`);break;case"md5-mismatch":n.push(`modified: ${i}`);break;case"missing-recording":n.push(`re-recorded: ${i}`);break;case"recorded-failed":n.push(`re-authored after failure: ${i}`);break}}if(n.length===0)return"automated commit";let o=n.filter((l,f)=>f===0||n[f-1]!==l),s=o.slice(0,3).join("; ");return o.length>3?`${s}; +${o.length-3} more`:s}function oa(e,t){if(!t)return"unknown step";let r=t.trace[0]?.stepIndex;if(r==null)return"unknown step";let o=e.rootSteps[r-1]?.heading?.trim()??"";return t.trace.length>1?o?`imported step in "${o}"`:`imported step ${r}`:o||`step ${r}`}import{existsSync as sa}from"fs";function ia(e){return!!e&&typeof e.module_id=="string"&&e.module_id.trim()!==""}function Jr(e){return`warn: ${e}: *_module.md without a cloud meta.json module_id \u2014 it ran as a module, but its steps upload as plain blocks (no module_block)`}function Ns(e,t,r={}){let n=r.tapePresent??(y=>sa(ko(y))),o=r.readMeta??(y=>fe(y)),s=r.onMissingIdentity??(y=>{process.stderr.write(`${Jr(y)}
|
|
23
|
+
`)}),l=new Set,f=new Set(e.unitFiles.filter(y=>y.kind==="module").map(y=>y.file)),i=new Map,c=[];for(let y of e.steps){let I=y.flatIndex,A,S="";for(let R=0;R+1<y.trace.length;R++){let d=y.trace[R],F=y.trace[R+1].file;if(S=S?`${S}>${d.file}#${d.stepIndex}`:`${d.file}#${d.stepIndex}`,!f.has(F))continue;let h=i.get(S);if(!h){let E=o(F);if(!ia(E)){l.has(F)||(l.add(F),s(F));continue}h={key:S,file:F,meta:E,flatFrom:I,flatTo:I,dirty:!1,children:[]},i.set(S,h),(A?A.children:c).push(h)}h.flatFrom=Math.min(h.flatFrom,I),h.flatTo=Math.max(h.flatTo,I),A=h}}let v=y=>{for(let I=y.flatFrom;I<=y.flatTo;I++)if(t.has(I))return!0;return!1},m=y=>{for(let I of y)I.dirty=n(I.file)&&v(I),m(I.children)};return m(c),c}function Bs(e){let t={};for(let r of e)for(let n=0;n<Math.max(1,r.totalRunDirs);n++)t[r.runIndex+n]=r.testmdStepIndex;return t}function Ms(e,t){let r=e.steps,n=[],o=[];for(let s=0;s<r.length;s++){let l=r[s],f=l.controlFlow;if(f==="if"||f==="while"){let i=aa(l,f,t);(o.length?o[o.length-1].children:n).push(i),o.push(i);continue}if(f==="elif"||f==="else"){let i=o[o.length-1];$s(i,l.flatIndex-1),i.branches.push({branch_type:f,condition:f==="else"?"":l.objective,flatFrom:l.flatIndex+1,flatTo:l.flatIndex,taken:!1});continue}if(f==="end-if"||f==="end-while"){let i=o.pop();$s(i,l.flatIndex-1),i.flatTo=l.flatIndex,la(i,t);continue}}return n}function aa(e,t,r){let n=Gr(e),o=n?.action_params??{},s=typeof o.block_id=="string"?o.block_id:"",l=n?.action_instruction&&n.action_instruction.trim()||e.objective,f={kind:t,blockId:s,instruction:l,flatFrom:e.flatIndex,flatTo:e.flatIndex,branches:[{branch_type:"if",condition:e.objective,flatFrom:e.flatIndex+1,flatTo:e.flatIndex,taken:!1}],children:[]};if(t==="while"){let i=zt(e),c=r?.whileRuns[e.flatIndex];f.whileCfg={...i,iterations:c?.iterations??0,condition_met:c?.condition_met??!1}}return f}function $s(e,t){let r=e.branches[e.branches.length-1];r.flatTo=t}function la(e,t){if(e.kind==="while"){e.branches[0].taken=(e.whileCfg?.iterations??0)>0;return}let r=t?.taken[e.flatFrom];typeof r=="number"&&r>=0&&r<e.branches.length&&(e.branches[r].taken=!0)}function da(e,t){if(!(!e.shouldReplaceLocalOutput||!e.resolvedTest||!e.sourcePath||!e.stepRunRecords||!e.outcomes||!e.overallStatus))return async()=>{let{changedUnitFiles:r,legacySweep:n}=await Bo({resolvedTest:e.resolvedTest,sessionDir:e.session.sessionDir,stepRunRecords:e.stepRunRecords,outcomes:e.outcomes,overallStatus:e.overallStatus,startedISO:e.startedISO??new Date().toISOString(),durationS:e.durationS??0,sessionId:e.session.sessionId,commitId:e.fromCommitId??"",tmsIds:e.tmsIds??{},codeExportDir:e.codeExportDir,packTestDir:e.evidence?.packTestDir??e.evidenceRead?.packTestDir,authoredFlatIdx:new Set(e.authoredFlatIdx??[])});t.files=r;for(let o of r){let s=ee(o);if(Vs(`${s}.staging`)){Ro(s);let l=n.find(f=>f.unitFile===o);l&&$o(l.dirs)}}}}function ca(e,t){if(!e.shouldCommit||e.isFirstRun||!e.tmsBaseUrl||!e.testId||!e.fromCommitId||!e.newCommitId||!e.basicAuth||!e.resolvedTest||!e.decisions)return;let r=(o,s)=>Nt({sourcePath:o,testId:s,sessionId:e.session.sessionId,commitId:e.newCommitId,identityOverride:{commit_id:e.newCommitId},controller:new xe(X(e.env).controllerBaseUrl,{username:e.basicAuth.username,accessKey:e.basicAuth.access_key})}),n=(o,s)=>e.onAgentEvent?.({type:"test_md_bundle_sync",status:s.ok?"ok":"failed",commit_id:e.newCommitId,path:o,...s.ok?{bytes:s.bytes}:{stage:s.stage}});return async()=>{let o;if(e.testmdSync===!1)e.log?.("info","BUNDLE_SYNC_SKIPPED","testmd bundle sync skipped",{reason:"flag",commit_id:e.newCommitId});else{if(!e.sourcePath){let m="bundle sync requires a source path";return e.log?.("warn","BUNDLE_SYNC_FAILED","testmd bundle sync failed",{commit_id:e.newCommitId,stage:"collect",error:m}),{ok:!1,reason:"bundle_sync_failed",message:m}}if(o=await r(e.sourcePath,e.testId),!o.ok)return e.log?.("warn","BUNDLE_SYNC_FAILED","testmd bundle sync failed",{commit_id:e.newCommitId,stage:o.stage,error:o.error}),n(e.sourcePath,o),process.stderr.write(` \u26A0 bundle sync failed (${o.stage}): ${o.error} \u2014 commit not attempted; the local tape is kept, run again with --push once fixed
|
|
24
|
+
`),{ok:!1,reason:"bundle_sync_failed",message:o.error}}let s=Us(e.resolvedTest,e.decisions,{wantsPush:e.wantsPush??!1,retryTriggered:e.retryTriggered??!1,forceAuthor:e.forceAuthor??!1}),l=e.resolvedTest.steps.map(m=>m.objective).filter(m=>typeof m=="string"&&m.length>0).slice(0,50),f=e.forceAuthor?"always_reauthor":e.retryTriggered?"adaptive_heal":void 0,i=lo().testInstanceId,c={...i?{testInstanceId:i}:{},...f?{trigger:f}:{}},v=await Br({baseUrl:`${e.tmsBaseUrl}/kane-cli/v1`,testId:e.testId,body:{commitId:e.newCommitId,fromCommitId:e.fromCommitId,commitMessage:s,totalSteps:e.resolvedTest.steps.length,timeTaken:Math.round(e.durationS??0),objectives:l,...c},auth:{username:e.basicAuth.username,accessKey:e.basicAuth.access_key}});if(v.ok&&e.commitBox&&(e.commitBox.committed=!0,e.commitBox.testcaseId=v.testcaseId||void 0),v.ok&&o?.ok&&e.sourcePath&&(e.log?.("info","BUNDLE_SYNC_OK","testmd bundle pushed",{commit_id:e.newCommitId,bytes:o.bytes}),n(e.sourcePath,o)),v.ok&&e.sourcePath){let m=ve(e.sourcePath);try{let y=JSON.parse(Qr(m,"utf8"));y.commit_id=e.newCommitId,Zr(m,JSON.stringify(y,null,2)+`
|
|
25
|
+
`,"utf8")}catch(y){process.stderr.write(`warn: failed to update meta.json commit_id: ${y.message}
|
|
26
|
+
`)}}if(v.ok)for(let m of e.unitLocks??[]){if(!t.files.includes(m.file)){await De({baseUrl:`${e.tmsBaseUrl}/kane-cli/v1`,testId:m.testId,body:{commitId:e.newCommitId,fromCommitId:m.fromCommitId},auth:{username:e.basicAuth.username,accessKey:e.basicAuth.access_key}}),pe(m.testId);continue}let y;if(e.testmdSync!==!1&&(y=await r(m.file,m.testId),!y.ok)){e.log?.("warn","BUNDLE_SYNC_FAILED","unit bundle sync failed",{commit_id:e.newCommitId,path:m.file,stage:y.stage,error:y.error}),n(m.file,y),process.stderr.write(`warn: unit bundle sync failed (${m.file}): ${y.stage}: ${y.error} \u2014 unit not committed
|
|
27
|
+
`),await De({baseUrl:`${e.tmsBaseUrl}/kane-cli/v1`,testId:m.testId,body:{commitId:e.newCommitId,fromCommitId:m.fromCommitId},auth:{username:e.basicAuth.username,accessKey:e.basicAuth.access_key}}),pe(m.testId);continue}let I=e.resolvedTest.steps.filter(R=>R.owningFile===m.file),A=I.map(R=>R.objective).filter(R=>typeof R=="string"&&R.length>0).slice(0,50),S=await Br({baseUrl:`${e.tmsBaseUrl}/kane-cli/v1`,testId:m.testId,body:{commitId:e.newCommitId,fromCommitId:m.fromCommitId,commitMessage:`healed via importer ${e.sourcePath??""}`,totalSteps:I.length,timeTaken:0,objectives:A,...c},auth:{username:e.basicAuth.username,accessKey:e.basicAuth.access_key}});if(S.ok){let R=ve(m.file);try{let d=JSON.parse(Qr(R,"utf8"));d.commit_id=e.newCommitId,Zr(R,JSON.stringify(d,null,2)+`
|
|
28
|
+
`,"utf8")}catch(d){process.stderr.write(`warn: failed to update unit meta commit_id (${m.file}): ${d.message}
|
|
29
|
+
`)}y?.ok&&(e.log?.("info","BUNDLE_SYNC_OK","unit bundle pushed",{commit_id:e.newCommitId,path:m.file,bytes:y.bytes}),n(m.file,y))}else process.stderr.write(`warn: unit self-commit failed (${m.file}): ${S.reason??""} ${S.message??""} \u2014 unit lock released
|
|
30
|
+
`),e.log?.("warn","UNIT_COMMIT_FAILED","Imported unit commit failed; lock discarded",{path:m.file,test_id:m.testId,reason:S.reason,message:S.message}),await De({baseUrl:`${e.tmsBaseUrl}/kane-cli/v1`,testId:m.testId,body:{commitId:e.newCommitId,fromCommitId:m.fromCommitId},auth:{username:e.basicAuth.username,accessKey:e.basicAuth.access_key}}),pe(m.testId)}return v.ok?{...v,...c}:v}}function ua(e){if(!(!e.isFirstRun||!e.sourcePath))return async t=>{if(!e.sourcePath)return;let r=ve(e.sourcePath);try{let n=Vs(r)?JSON.parse(Qr(r,"utf8")):{};e.session.sessionId&&(n.commit_id=e.session.sessionId),t&&(n.testcase_id=t),e.tmsIds?.testId&&(n.test_id=e.tmsIds.testId),e.tmsIds?.projectId&&(n.project_id=e.tmsIds.projectId),e.tmsIds?.folderId&&(n.folder_id=e.tmsIds.folderId),e.tmsIds?.orgId&&(n.org_id=e.tmsIds.orgId),e.tmsIds?.sessionName&&(n.session_name=e.tmsIds.sessionName),Zr(r,JSON.stringify(n,null,2)+`
|
|
31
|
+
`,"utf8")}catch(n){process.stderr.write(`warn: failed to update meta.json after endTest: ${n.message}
|
|
32
|
+
`)}}}function ma(e){let t=e.decisions,r=e.resolvedTest?.steps,n=e.sourcePath;if(!t||!r||!n)return;let o=[];if(t.forEach((s,l)=>{s.kind==="replay"&&s.replayOnly&&o.push(r[l]?.flatIndex??l+1)}),o.length!==0)return{authoredExecutionPath:Me(n),flatIndices:o}}function Ks(e){let t=ma(e),r=X(e.env),n=e.resolvedTest,o=!!n&&Array.isArray(n.unitFiles)&&(e.stepRunRecords?.length??0)>0,s=o?Ns(n,new Set(e.authoredFlatIdx??[]),{onMissingIdentity:oe=>{e.log?.("warn","MODULE_IDENTITY_MISSING","*_module.md without a cloud module_id; its blocks upload unfolded",{path:oe}),process.stderr.write(`${Jr(oe)}
|
|
33
|
+
`)}}):void 0,l=o?Bs(e.stepRunRecords):void 0,f=!!n&&n.steps.some(oe=>oe.block!==void 0),i=o&&f?Ms(n,e.blockOutcomes):void 0,c=i?.length&&e.sourcePath?Me(e.sourcePath):void 0,v={files:[]},{session:m,auth:y}=e,I=y.basicAuth?{username:y.basicAuth.username,accessKey:y.basicAuth.access_key}:y.token,A=y.resolvedCreds?.username??y.basicAuth?.username??"",S=y.resolvedCreds?.access_key??y.basicAuth?.access_key??"",R=y.resolvedCreds?.org_id??0,d=y.resolvedCreds?.user_id??0,F=[];for(let oe of Object.keys(m.auteurVariables))oe.startsWith("secrets.user.")&&F.push({key_name:oe.replace("secrets.user.",""),scope:"user"});let E=m.getContext().prior_runs.map(oe=>oe.status),M=m.auteurVariables,Se=Object.keys(M).length>0;return{controllerBaseUrl:r.controllerBaseUrl,tmsBaseUrl:r.tmsBaseUrl,auth:I,authResolver:y.resolver,sessionId:m.sessionId,sessionDir:m.sessionDir,testId:m.testId,commitId:m.sessionId,apMode:m.apMode,projectId:e.projectId,folderId:e.folderId,firstObjective:m.firstObjective??"KaneAI Test",firstUrl:m.firstUrl??"",runDirs:m.getRunDirs(),runObjectives:m.getRunObjectives(),runMetadata:m.getRunMetadata(),startedAt:m.startedAt,endedAt:new Date().toISOString(),totalSteps:e.totalSteps,totalDuration:e.totalDuration,runStatuses:E,orgId:R,userId:d,tmsUsername:A,tmsAccessKey:S,screenshotBaseUrl:m.screenshotBaseUrl,screenshotExtMap:e.screenshotExtMap,shareApiBaseUrl:r.shareApiBaseUrl,variables:Se?M:void 0,variableIds:e.variableIds,...e.testParams?{testParams:e.testParams}:{},secrets:F,codeExport:e.codeExport,...e.mobile?{mobile:!0}:{},onProgress:e.onProgress,log:e.log,shouldUploadArtifacts:e.shouldUploadArtifacts,shouldReplaceLocalOutput:e.shouldReplaceLocalOutput,shouldCommit:e.shouldCommit,isFirstRun:e.isFirstRun,onAtomicReplace:da(e,v),onCommitLock:ca(e,v),onFinalizeSuccess:ua(e),evidence:e.evidence,evidenceRead:e.evidenceRead,...s?{moduleSpans:s}:{},...i?.length?{blockSpans:i,blockAuthoredExecutionPath:c}:{},...l?{runFlatIndex:l}:{},authoredExecutionPath:e.authoredExecutionPath,...t?{replayOnlyPassthrough:t}:{}}}function Hs(e,t=process.env){return t.KANE_MOBILE_APP_BASE_URL||X(e).mobileAppBaseUrl}var qs=["python","javascript"];function fa(e){if(e!==void 0){if(!qs.includes(e))throw new Error(`--code-language must be one of: ${qs.join(", ")} (got "${e}")`);return e}}function Gs(e,t){let r=fa(e.codeLanguage);return{enabled:e.codeExport??t.enabled,language:r??t.language,skipValidation:e.skipCodeValidation??t.skip_validation}}function zs(e){return{platform:e.platform??"",...e.appId?{appId:e.appId}:{},...e.deviceName?{deviceName:e.deviceName}:{},...e.osVersion?{osVersion:e.osVersion}:{},...e.udid?{udid:e.udid}:{}}}async function Ys(e){try{let t=new Dt(e.tmsBaseUrl,e.auth.username,e.auth.access_key);if(e.mobile){if(!e.mobile.appId)return e.log("warn","ATM_CREATE_SKIPPED","Mobile test not registered in TMS",{reason:"no cloud app id for the build under test"}),null;let n=await t.createMobileAtmTest({objective:e.objective.slice(0,100),creation_mode:"KANECLI",playground_disabled:e.hasCustomProfile,mobile_browser:!1,os:e.mobile.platform.toLowerCase(),app_id:e.mobile.appId,project_id:e.projectId,folder_id:e.folderId,authoring_version:4,...e.mobile.deviceName?{deviceName:e.mobile.deviceName}:{},...e.mobile.osVersion?{osVersion:e.mobile.osVersion}:{},...e.mobile.udid?{udid:e.mobile.udid}:{}});return e.log("info","ATM_CREATE_OK","Mobile test created",{test_id:n}),n}let r=await t.createAtmTest({objective:e.objective.slice(0,100),creation_mode:"KANECLI",playground_disabled:e.hasCustomProfile,testURL:e.url,project_id:e.projectId,folder_id:e.folderId,authoring_version:4});return e.log("info","ATM_CREATE_OK","Test created",{test_id:r}),r}catch(t){return e.log("error","ATM_CREATE_FAILED","Test creation failed",{error:t instanceof Error?t.message:String(t)}),null}}var pa=null,ga=()=>pa??=import("sharp").then(e=>e.default??e).catch(()=>null),Wt=class{maxWorkers;maxRetries=2;queue=[];activeCount=0;drainResolvers=[];sas;log;uploadedExt=new Map;constructor(t,r=3,n){this.sas=t,this.maxWorkers=r,this.log=n}updateSas(t){this.sas=t}enqueue(t,r){this.queue.push({operationId:t,buffer:r}),this.pump()}async drain(t=3e4){if(!(this.queue.length===0&&this.activeCount===0))return new Promise(r=>{this.drainResolvers.push(r),setTimeout(()=>{r()},t)})}pump(){for(;this.activeCount<this.maxWorkers&&this.queue.length>0;){let t=this.queue.shift();this.activeCount++,this.processJob(t).finally(()=>{if(this.activeCount--,this.pump(),this.queue.length===0&&this.activeCount===0){for(let r of this.drainResolvers)r();this.drainResolvers=[]}})}}async processJob(t){let r,n="image/webp",o=await ga();if(o)try{let i=await o(t.buffer).webp({quality:80}).toBuffer();r=new Uint8Array(i)}catch(i){r=new Uint8Array(t.buffer),n="image/png",this.log?.("warn","SCREENSHOT_CONVERT_FAILED","WebP conversion failed, using PNG",{operation_id:t.operationId,error:i instanceof Error?i.message:String(i)})}else r=new Uint8Array(t.buffer),n="image/png";let s=n==="image/webp"?"webp":"png",l=`test_screenshots/untagged_screenshot/${t.operationId}.${s}`,f=`${this.sas.base_url}/${this.sas.container}/${l}?${this.sas.sas_token}`;for(let i=0;i<=this.maxRetries;i++)try{let c=await Y(f,{method:"PUT",headers:{"Content-Type":n,"x-ms-blob-type":"BlockBlob"},body:r});if(c.ok){this.uploadedExt.set(t.operationId,s);return}if(i<this.maxRetries){await this.backoff(i);continue}this.log?.("warn","SCREENSHOT_UPLOAD_FAILED","Screenshot upload failed after retries",{operation_id:t.operationId,status:c.status,attempts:this.maxRetries+1})}catch{if(i<this.maxRetries){await this.backoff(i);continue}this.log?.("warn","SCREENSHOT_UPLOAD_FAILED","Screenshot upload failed (network error)",{operation_id:t.operationId,error:"network",attempts:this.maxRetries+1})}}backoff(t){let r=t===0?1e3:3e3;return new Promise(n=>setTimeout(n,r))}getExt(t){return this.uploadedExt.get(t)??"png"}getExtMap(){return this.uploadedExt}isNearExpiry(){if(!this.sas.expiry)return!1;let t=new Date(this.sas.expiry).getTime();return Date.now()>t-5*6e4}};import{platform as ha,arch as ya}from"os";function Ws(e){let t={proxyUrl:$n,sessionId:e.sessionId,identity:e.identity,device:{cli_version:Ct,platform:ha(),arch:ya(),host_agent:vr(),invocation_mode:e.invocationMode},getToken:e.getToken};return new br(t)}async function ba(e){try{let t=X(e.env),n=await new xe(t.controllerBaseUrl,e.auth).getScreenshotSas();return e.session.setScreenshotSas(n),e.log("info","SCREENSHOT_SAS_OK","Screenshot SAS fetched",{base_url:n.base_url,container:n.container,expiry:n.expiry}),new Wt(n,3,e.log)}catch(t){return e.log("warn","SCREENSHOT_SAS_FAIL","Screenshot SAS fetch failed",{error:t instanceof Error?t.message:String(t)}),null}}async function va(e){if(e.session.hasRemoteLogger||!e.tmsCreds)return null;let t=e.tmsCreds,r=Ws({sessionId:e.session.sessionId,identity:{org_id:String(t.org_id??""),user_id:String(t.user_id??""),machine_id:no(),email:t.email??null,email_domain:t.email_domain??"unknown",user_type:t.user_type??"unknown",env:e.env,plan:t.plan??"unknown"},invocationMode:e.invocationMode,getToken:e.getToken});return e.session.setRemoteLogger(r),r.start(),r}async function rn(e){let[t,r]=await Promise.allSettled([e.skipScreenshotQueue?Promise.resolve(null):ba({env:e.env,auth:e.auth,session:e.session,log:e.log}),va({env:e.env,tmsCreds:e.tmsCreds,getToken:e.getToken,session:e.session,invocationMode:e.invocationMode})]);return{resolver:e.resolver,screenshotQueue:t.status==="fulfilled"?t.value:null,remoteLogger:r.status==="fulfilled"?r.value:null}}async function Xr(e){await Promise.allSettled([e.screenshotQueue?.drain(),e.remoteLogger?.shutdown()])}async function ic(e,t){switch(e.kind){case"boot":{if(t.state.identityServicesRef.current)return t.state.identityServicesRef.current;let r=t.auth.initResolver(e.env);r.prime(e.tmsCreds),t.state.setTmsCredsCache(e.tmsCreds);let n=await en(e.env,e.tmsCreds,r,t);return tn(n,t),n}case"login":case"switch":{let r=t.state.identityServicesRef.current;r&&(await Xr(r),r.resolver.revoke()),t.state.identityServicesRef.current=null,t.state.screenshotQueueRef.current=null,t.state.setTmsCredsCache(null);let n=t.auth.initResolver(e.env),o=await n.resolve(!0).catch(()=>null);if(!o)return t.log("warn","IDENTITY_VALIDATE_FAILED","Identity validation failed",{kind:e.kind,env:e.env}),null;t.state.setTmsCredsCache(o);let s=await en(e.env,o,n,t);return tn(s,t),s}case"logout":{let r=t.state.identityServicesRef.current;return r&&(await Xr(r),r.resolver.revoke()),t.state.identityServicesRef.current=null,t.state.screenshotQueueRef.current=null,t.state.setTmsCredsCache(null),null}case"resessionize":{let r=t.state.identityServicesRef.current;r&&await Xr(r),t.state.identityServicesRef.current=null,t.state.screenshotQueueRef.current=null;let n=t.state.getTmsCredsCache(),o=t.auth.getResolver(),s=o??t.auth.initResolver(e.env);!o&&n&&s.prime(n);let l=await en(e.env,n,s,t);return tn(l,t),l}}}async function en(e,t,r,n){!n.options?.localMode&&t?.user_id!==void 0&&n.getSession().setCompletionIdentity(Number(t.user_id));let o=n.auth.getBasicAuth(),s=o?null:await n.auth.getToken(),l=o?{username:o.username,accessKey:o.access_key}:s??null;return l===null?{resolver:r,screenshotQueue:null,remoteLogger:null}:rn({env:e,tmsCreds:t,resolver:r,auth:l,getToken:()=>n.auth.getToken(),session:n.getSession(),log:n.log,skipScreenshotQueue:n.options?.localMode,invocationMode:"tui"})}function tn(e,t){t.state.identityServicesRef.current=e,t.state.screenshotQueueRef.current=e.screenshotQueue,e.remoteLogger&&(t.exit.registerCleanup("remote-logger",()=>e.remoteLogger.shutdownSync()),t.exit.setExitRemoteLogger(e.remoteLogger))}function Js(e){if(!e.executionId)return;let t={executionId:e.executionId,published:e.published};return e.testId&&(t.testId=e.testId),e.testcaseId&&(t.testcaseId=e.testcaseId),e.commitId&&(t.commitId=e.commitId),t}import{relative as _a}from"path";import{readFile as wa}from"fs/promises";function Qs(e){return e.shouldUploadArtifacts&&!e.lockHeld&&!e.isFirstRun&&e.sealed&&!!e.testId}var nn=e=>e instanceof Error?e.message:String(e);async function Zs(e){let{controller:t,tms:r,testId:n,sessionId:o,executionId:s,sealedPackPath:l,projectId:f}=e,i;try{let c={key:"evidence",content_type:"application/zip",filename:`${s}.evidence`},m=(await t.getPresignedUrls(n,o,[c])).urls?.evidence?.upload_url;if(!m)return{ok:!1,stage:"presign",error:"presign response missing evidence upload_url"};i=m}catch(c){return{ok:!1,stage:"presign",error:nn(c)}}try{let c=await wa(l);await Eo(i,c,"application/zip")}catch(c){return{ok:!1,stage:"upload",error:nn(c)}}try{await r.ingestEvidence(s,f)}catch(c){return{ok:!1,stage:"ingest",error:nn(c)}}return{ok:!0}}function Xs(e){return e.isFirstRun||Bt(e.decisions)||e.push===!0||e.author===!0}function ei(e,t){return{projectId:e?.project_id??t.project_id??null,folderId:e?.folder_id??t.folder_id??null}}function on(e){return e?"author":"replay"}function ka(e,t){return e?{session:e,ownsLifecycle:!1}:{session:t,ownsLifecycle:!0}}function Jt(e,t){return e?.total_runs??t?.length??1}function Sa(e){let t=(e?.per_flow_metadata??[]).map(r=>({resultCode:r?.result_code!=null?Number(r.result_code):null}));return{resultCode:e?.result_code!=null?Number(e.result_code):null,...t.length?{perFlow:t}:{}}}var Qt=["target","chrome_profile","cdp_endpoint","ws_endpoint","headless"];async function xu(e,t,r){let{path:n,cwd:o,opts:s,isAgent:l,disableAskUser:f,resolved:i,resolvedAuth:c,cliOverrides:v,environment:m,envConfig:y,profile:I,model:A,creds:S,configStore:R,session:d}=e,F=!1,h=await xa(n,i,s,{resolvedAuth:c,tmsBaseUrl:y.tmsBaseUrl},d.sessionId,r);if(h.abort)return{overallStatus:"failed",exitCode:h.abort.exitCode,outputDir:ee(n),durationS:0,uploadResult:null};let E=h.lockAcquired,M=!1;try{let cr=function(a,u){let p=i.steps[a],b=ti(p.config,v),w=ze(Ce.raw,b.variables,p.objective);return qr({objective:w.objective,url:P.kind==="device"?void 0:Xt(a)?Ie??void 0:p.unitEntryUrl,requireStartUrl:P.kind==="web"&&Xt(a)&&di,model:A,chrome:G,device:P.kind==="device"?P.device:void 0,auth:c,sessionId:d.sessionId,runIndex:u,windowSize:{width:1920,height:1080},maxSteps:b.max_steps??ci??30,headless:V.headless??!1,disableAskUser:!0,variables:Object.keys(w.variables).length>0?w.variables:void 0,globalContext:b.global_context??bn,localContext:b.local_context??vn,sessionContext:d.getContext(),bugDetection:s.bugDetection??K.bug_detection,evidence:dr()})},rt=function(a){let p=i.steps[a].trace[0].stepIndex,b=i.rootSteps.find(g=>g.index===p);i.steps.slice(0,a).some(g=>g.trace[0].stepIndex===p)||t.onAgentEvent({type:"test_md_step_start",step_index:p,heading:b.heading,ref:b.body.kind==="import_ref"?{kind:"import",label:b.body.path,unit_kind:Cr(b.body.path)}:null,...b.replayOnly?{replay_only:b.replayOnly}:{}})},It=function(a,u,p,b,w,g){let _=i.steps[a],D=_.trace[0].stepIndex,N=!i.steps.slice(a+1).some($=>$.trace[0].stepIndex===D),C=p?.status==="passed"?"passed":"failed",T=p?.reason??w??void 0,L=p?.duration??g,k=p?.verdict;if(k&&typeof k=="object"){let $=typeof k.one_liner=="string"?k.one_liner:"",U=typeof k.bug_title=="string"&&k.bug_title?k.bug_title:$;if(U&&C==="failed"){let me=[k.family,k.category].filter(Boolean).join("/"),Et=typeof k.confidence=="number"?`, confidence ${k.confidence.toFixed(2)}`:"";T=`${T??"failed"} \u2014 bug verdict: ${U}${me?` [${me}${Et}]`:""}`}let nt=typeof k.category_proposal=="string"?k.category_proposal:"";nt&&C==="failed"&&(T=`${T??"failed"}; category proposal: ${nt} \u2014 consider adding to taxonomy`),t.onAgentEvent({type:"test_md_bug_verdict",step_index:_.trace[0].stepIndex,confirmed:k.confirmed===!0,bug_title:U||null,family:k.family??null,category:k.category??null,category_proposal:nt||null,severity:k.severity??null,confidence:typeof k.confidence=="number"?k.confidence:null,one_liner:$||null})}let{continueOverall:B}=ae.recordStep(_,{status:C,duration_s:L,reason:T}),Z=ti(_.config,v),x=ze(Ce.raw,Z.variables,_.objective).objective;if(p){let $=us(p,u,b);d.addRunResult(ms(p,x,u,$),p.total_runs)}else d.addRunResult({index:u,objective:x,status:C,summary:"",context:{memory:{},variables:{},pointer:""}},1);if(N||!B){let $=ae.snapshotOutcomes().find(U=>U.rootStepIndex===D);t.onAgentEvent({type:"test_md_step_end",step_index:D,status:$.status,duration_s:$.duration_s??0,ref_kind:$.refKind??null,unit_kind:$.refKind==="import"?Cr($.refLabel??""):null,inlined_count:$.inlinedCount??null,failed_sub_step_index:$.failedSubStepIndex??null})}return B},Ne=function(a,u){let p=i.steps[a],b=p.trace[p.trace.length-1].heading;process.stderr.write(`\u{1FA79} step ${p.flatIndex} "${b}" @${u} broke on replay \u2014 adaptive heal cannot re-author a replay-only step; the run fails here
|
|
34
|
+
`),d.log("warn","REPLAY_ONLY_STEP_FAILED","Replay-only step failed on replay; heal not attempted",{flat_index:p.flatIndex,marker:u})};var Se=cr,oe=rt,se=It,te=Ne;let Zt={committed:!1},ue=!1,pt=new Set,Je=0,oi=i.steps.some(a=>a.block!==void 0),Xt=a=>oi?Je===0:a===0,he=!1,gt=!1,Qe=s.author===!0?0:at(h.decisions),er=0,tr=0,Oe=0,Ze=a=>typeof a?.credits_consumed=="number"&&Number.isFinite(a.credits_consumed)?a.credits_consumed:0;{let a;try{a=typeof s.sessionContext=="string"?JSON.parse(s.sessionContext):void 0}catch{a=void 0}let u=Ra({resolved:i,cwd:o,globalDir:ge(At,"variables"),opts:s,authorFrom:Qe,produced:qo(a)});u&&(l?t.onAgentEvent(u.event):process.stderr.write(u.text))}E&&t.onLockState({phase:"acquired",scope:"preemptive"}),d.start({model:A,environment:m,profile:I}),d.setRecordingEnabled(!1);let ht=0,an=c.basicAuth?{username:c.basicAuth.username,accessKey:c.basicAuth.access_key}:c.token??null,Xe=null;if(an!==null){let a=await rn({env:m,tmsCreds:c.resolvedCreds??null,resolver:c.resolver,auth:an,getToken:async()=>c.token??null,session:d,log:(u,p,b,w)=>d.log(u,p,b,w),skipScreenshotQueue:!!s.local||!c.basicAuth,invocationMode:l?"agent":"cli"});Xe=a.screenshotQueue,a.remoteLogger&&(r.register("remote-logger",()=>a.remoteLogger.shutdownSync()),r.remoteLogger=a.remoteLogger,e.skipGlobalRemoteLogger||Kn(a.remoteLogger))}if(s.name){try{jo(s.name)}catch(a){return process.stderr.write(`error: ${a.message}
|
|
35
|
+
`),{overallStatus:"failed",exitCode:2,outputDir:ee(n),durationS:0,uploadResult:null}}d.setSessionName(s.name)}let rr={};for(let[a,u]of Object.entries(i.rootGlobal))Qt.includes(a)||(rr[a]=u);for(let[a,u]of Object.entries(v))Qt.includes(a)||u!==void 0&&(rr[a]=u);let V={...i.chrome};for(let a of Qt){let u=v[a];u!==void 0&&(V[a]=u)}let et={...rr,...V},je=Fo({flags:{target:s.target,deviceName:s.deviceName,osVersion:s.osVersion,app:s.app},file:{target:i.rootGlobal.target,device_name:i.rootGlobal.device_name,os_version:i.rootGlobal.os_version,app:i.rootGlobal.app,no_reset:i.rootGlobal.no_reset}});if(je.kind==="invalid")return process.stderr.write(`error: ${je.message}
|
|
36
|
+
`),await d.finish("complete"),{overallStatus:"failed",exitCode:2,outputDir:ee(n),durationS:0,uploadResult:null};for(let a of je.warnings)process.stderr.write(`warning: ${a}
|
|
37
|
+
`);let ye=je.kind==="mobile"?je:null;if(d.setCompletionMetadata({runType:i.rootGlobal.assurance?.id?"assurance":"testmd",target:ye?.target??"desktop"}),je.kind==="web"&&i.rootGlobal.target===void 0){let u=i.rootSteps.map(b=>b.body).find(b=>b.kind==="objective")?.text??"",p=/^\s*\[mobile:\s*(emulator|simulator)\]/.exec(u);if(p)return process.stderr.write(`error: this test was designed for a mobile ${p[1]} but its frontmatter has no target: \u2014 add \`target: ${p[1]}\` and \`app: <path-to-build | AppId>\` to the file (or re-design it with the app named in the design chat: kane-cli design tests --use-case <uc> --force), then run again
|
|
38
|
+
`),await d.finish("complete"),{overallStatus:"failed",exitCode:2,outputDir:ee(n),durationS:0,uploadResult:null}}ye?(et.target=ye.target,ye.app&&(et.app=ye.app)):(i.rootGlobal.target==="emulator"||i.rootGlobal.target==="simulator")&&(delete et.app,delete et.no_reset),d.setResolvedGlobal(et);let Re=null;{let a=p=>(process.stderr.write(`error: ${p}
|
|
39
|
+
`),{overallStatus:"failed",exitCode:2,outputDir:ee(n),durationS:0,uploadResult:null}),u;try{u=Zn({datasetId:s.datasetId,datasetRow:s.datasetRow},i.rootGlobal.dataset)}catch(p){return a(p.message)}if(u){if(!c.basicAuth)return a("--dataset-id needs Test Manager credentials \u2014 run 'kane-cli login' or pass --username/--access-key");try{Re=await js({selection:u,tmsBaseUrl:X(m).tmsBaseUrl,auth:c.basicAuth,saveDir:d.sessionDir,log:(b,w,g,_)=>d.log(b,w,g,_)})}catch(b){return a(b.message)}d.setResolvedGlobal({dataset:Xn(u.id,Re.rowId)});let p=Ko(i.steps.filter(b=>b.flatIndex-1>=Qe).map(b=>({text:b.objective,usedBy:{file:mt(b.sourceFile),step:b.flatIndex}})),Re.columns,u.id);p.length>0&&(l?t.onAgentEvent(Or(p,{cwd:o})):process.stderr.write(Lr(p,{cwd:o,entryFile:mt(i.rootPath)})))}}let ln=S.getActiveProfile()??"default",dn=S.getDefaultEnv(),{rehydrateIfStale:si}=await import("./profile-sync-DTTRRIVP.js");si(S,R,ln,dn);let K=R.load(),cn=(v.assertion_mode??K.assertion_mode)==="dom"?"dom":"visual",un=v.final_validation,mn=un===void 0?void 0:un==="on",q=K.project_id??null,we=K.folder_id??null,fn=fe(n),pn=fn?.environment_id,ii=Ao(fn?.tc_id),gn=Xs({isFirstRun:h.isFirstRun,decisions:h.decisions,push:s.push===!0,author:s.author===!0});if(gn){if(c.basicAuth){let a=await ro({creds:S,config:R,profile:ln,env:dn,tmsCreds:c.basicAuth,isLocal:!!s.local,log:(u,p,b,w)=>d.log(u,p,b,w),onAnnounce:e.onAnnounce,onFatalExit:e.onFatalExit});if(a.status==="ok"){q=a.projectId,we=a.folderId,K=R.load();let u=fe(n);u?.project_id&&(q=u.project_id,we=u.folder_id??we),l&&a.autoDefaulted&&t.onAgentEvent(to(a.autoDefaulted))}else if(a.status==="cancelled"){process.stderr.write(`error: project/folder configuration failed. See remediation above, or use --local.
|
|
40
|
+
`);let{shutdown:u}=await import("./exit-manager-ZLDO54S4.js");return u(2,"project/folder gate failed"),{}}}}else{let a=fe(n);({projectId:q,folderId:we}=ei(a,{project_id:K.project_id??null,folder_id:K.folder_id??null})),d.log("info","GATE_SKIP_REPLAY","Project/folder gate skipped (planned pure replay)",{meta_project:!!a?.project_id,config_project:!!K.project_id})}{let a=xo(i),u=c.resolvedCreds?.org_id!=null?String(c.resolvedCreds.org_id):void 0,p=a.find(g=>g.project_id&&q&&g.project_id!==String(q)||g.org_id&&u&&g.org_id!==u),b=new Set(a.map(g=>g.project_id).filter(Boolean)),w=new Set(a.map(g=>g.org_id).filter(Boolean));if(p||b.size>1||w.size>1){let g=p??a[0];return process.stderr.write(`error: tenant mismatch \u2014 imported test '${g.file}' was authored under project ${g.project_id??"?"} / org ${g.org_id??"?"}, which differs from the run's project/org (or another imported test). Cross-tenant imports are not allowed.
|
|
41
|
+
`),await d.finish("complete"),{overallStatus:"failed",exitCode:2,outputDir:ee(n),durationS:0,uploadResult:null}}}let Ee={},P;try{P=await Ss(ye?"device":"web",{prepareDevice:async()=>{let a=ye,u=await Yn({platform:a.platform,...a.deviceSelector?{device:a.deviceSelector}:{},...a.app?{app:a.app}:{},...a.noReset!==void 0?{noReset:a.noReset}:{},defaults:K.mobile,interactive:Go()&&!l,agent:l,...!s.local&&c.basicAuth&&c.resolvedCreds?.org_id?{cloudUpload:{env:m,orgId:String(c.resolvedCreds.org_id),userId:String(c.resolvedCreds.user_id??""),baseUrl:Hs(m),auth:{username:c.basicAuth.username,accessKey:c.basicAuth.access_key}}}:{},onProgress:p=>process.stderr.write(`${p}
|
|
42
|
+
`)});return Ee.deviceName=u.target.displayName,u.target.osVersion&&(Ee.osVersion=u.target.osVersion),u.target.modelIdentifier&&(Ee.modelIdentifier=u.target.modelIdentifier),{device:u.device,...u.appRef?{appRef:u.appRef}:{},...u.appId?{appId:u.appId}:{}}},prepareWeb:()=>Hr({config:{chrome_profile_path:V.chrome_profile??null,window_size:{width:1920,height:1080}},startUrl:ot,headless:V.headless??!1,wsEndpoint:V.ws_endpoint,cdpEndpoint:V.cdp_endpoint})})}catch(a){if(ye){let u=a instanceof zn?`${a.doctorText}
|
|
43
|
+
${a.message}`:a.message;process.stderr.write(`error: mobile target preparation failed: ${u}
|
|
44
|
+
`)}else process.stderr.write(`error: Chrome launch failed: ${a.message}
|
|
45
|
+
`);return await d.finish("complete"),{overallStatus:"failed",exitCode:2,outputDir:ee(n),durationS:0,uploadResult:null}}if(P.kind==="device"&&!P.device.app_package)return process.stderr.write(`error: ${Uo(ye.target,"app")}
|
|
46
|
+
`),await d.finish("complete"),{overallStatus:"failed",exitCode:2,outputDir:ee(n),durationS:0,uploadResult:null};let G=P.kind==="web"?P.chrome:{instance:null,tempDir:null},be=G.instance;be&&r.register("chrome",()=>{try{be?.kill()}catch{}});let nr=Ir(G.cdpEndpoint),H=null,hn=!1,yt=()=>{if(!H?.diedUnexpectedly)return!1;if(!hn){hn=!0;let a=H.stderr.slice(-500);d.log("error","RUNNER_FATAL_DEATH","v16-runner exited unexpectedly mid-session",{stderr_tail:a}),process.stderr.write(`error: v16-runner exited unexpectedly mid-session \u2014 remaining steps skipped.
|
|
47
|
+
`)}return!0},z=null,yn=G.cdpEndpoint??V.cdp_endpoint;if(yn&&!V.ws_endpoint&&!V.headless&&!e.isAgent)try{z=Vr({headless:V.headless??!1,cdpEndpoint:yn,chromePid:be?.process.pid}),z&&r.register("marker-overlay",()=>z?.kill())}catch(a){d.log("warn","OVERLAY_SPAWN_FAILED","Marker overlay spawn failed",{error:String(a)})}c.resolvedCreds?.org_id!==void 0&&d.setOrgId(String(c.resolvedCreds.org_id)),!s.local&&c.resolvedCreds?.user_id!==void 0&&d.setCompletionIdentity(Number(c.resolvedCreds.user_id)),d.setUserIdentity(c.resolvedCreds?.username??null,c.resolvedCreds?.email??null);let Ce=Ds({objective:"",globalDir:ge(At,"variables"),localDir:ge(o,".testmuai","variables"),file:s.variablesFile,inline:s.variables,parameters:Re?.parameters}),ai=i.rootGlobal.variables??{},ie=Ea(Ce.raw,ai);d.setAuteurVariables(ie.auteur);let bn=Wr(ge(At,"global-memory.md"))??void 0,vn=Wr(ge(o,".testmuai","context.md"))??void 0;s.local?process.stderr.write(`info: --local \u2014 cloud upload skipped
|
|
48
|
+
`):c.basicAuth?q||(gn?process.stderr.write(`warn: cloud upload skipped \u2014 no project configured.
|
|
49
|
+
`):process.stderr.write(`warn: evidence publish will be skipped \u2014 no project_id in meta.json or config.
|
|
50
|
+
`)):process.stderr.write(`warn: cloud upload skipped \u2014 TMS credentials could not be resolved.
|
|
51
|
+
Run 'kane-cli login' (OAuth) or 'kane-cli config set-username/set-access-key' (basic auth).
|
|
52
|
+
`);let Fe=!s.local&&!!c.basicAuth&&q!=null;if(d.log("info","PIPELINE_GATE_STATE","Initial gate state (run-start)",{phase:"run-start",shouldUploadArtifacts:Fe,lockHeld:E,isFirstRun:h.isFirstRun,hasAuth:h.hasAuth}),Fe&&h.testId==null&&!h.degradedReadonly){let a=X(m);try{let u=await Ys({tmsBaseUrl:a.tmsBaseUrl,auth:c.basicAuth,objective:i.steps[0].objective,url:"",projectId:q,folderId:we??"",hasCustomProfile:!!V.chrome_profile,...P.kind==="device"?{mobile:zs({platform:P.device.platform,appId:P.appId,deviceName:Ee.deviceName,osVersion:Ee.osVersion,udid:P.device.udid})}:{},log:(p,b,w,g)=>d.log(p,b,w,g)});u&&d.setTestId(u)}catch(u){process.stderr.write(`warn: ATM test creation failed: ${u.message}
|
|
53
|
+
`)}}else h.testId&&d.setTestId(h.testId);let bt={};if(c.basicAuth&&!s.local&&(ie.secretEntries.length>0||ie.nonSecretEntries.length>0))try{bt=await Ls({variables:ie,auth:c.basicAuth,orgId:String(c.resolvedCreds?.org_id??""),env:m,localMode:!!s.local,log:(a,u,p,b)=>d.log(a,u,p,b)})}catch(a){process.stderr.write(`warn: variable/secret push failed: ${a.message}
|
|
54
|
+
`)}let or=new Map;for(let[a,u]of ie.nonSecretEntries)or.set(a,u.value);let sr=new Map;for(let[a,u]of ie.secretEntries)sr.set(a,u.value);async function ir(a){if(!c.basicAuth||s.local)return;let u=[],p=[];for(let[w,g]of Object.entries(a))if(!st(g))if(g.secret){if(sr.get(w)===g.value)continue;p.push([w,g])}else{if(or.get(w)===g.value)continue;u.push([w,g])}if(u.length===0&&p.length===0)return;let b=X(m);if(u.length>0){let w=new Ge(b.tmsBaseUrl,c.basicAuth.username,c.basicAuth.access_key);for(let[g,_]of u)try{let D=await w.upsertVariable({name:g,value:_.value});bt[g]=D.id,or.set(g,_.value),d.log("info","VAR_PUSH_STEP","Variable updated mid-run",{name:g})}catch(D){d.log("warn","VAR_PUSH_STEP_FAILED","Mid-run variable push failed",{name:g,error:String(D)})}}if(p.length>0){let w=new qe(b.secretsBaseUrl);for(let[g,_]of p)try{await w.pushSecret({secretKey:g,secretValue:_.value,username:c.basicAuth.username,accessKey:c.basicAuth.access_key,orgId:String(c.resolvedCreds?.org_id??"")}),sr.set(g,_.value),d.log("info","SECRET_PUSH_STEP","Secret updated mid-run",{name:g})}catch(D){d.log("warn","SECRET_PUSH_STEP_FAILED","Mid-run secret push failed",{name:g,error:String(D)})}}}let tt=Xe?(a,u,p,b)=>{if(!(E||h.isFirstRun))return;if(O&&b){ds(O.packTestDir,b,Xe,(g,_,D,N)=>d.log(g,_,D,N));return}let w=ht+u;cs(d.sessionDir,w,a,Xe,(g,_,D,N)=>d.log(g,_,D,N),p)}:void 0,wn=i.rootTitle??i.rootSteps[0]?.heading??mt(n),li=Object.keys(ie.raw).length>0?$e(ie.raw,wn).objective:wn,Ie=fs({flag:s.url,frontmatter:i.rootGlobal?.url,configDefault:R.load().default_url}),di=ps({resolvedUrl:Ie,local:!!s.local,allowMissingUrl:!!s.allowMissingUrl,isTTY:!!process.stdin.isTTY});d.setFirstRun(li,Ie??"");let ae=new Vt(i),vt=new Date().toISOString(),In=Date.now(),ar=e.evidenceAttach?null:new ho({origin:"testmd",runKind:"author",pid:process.pid,title:i.rootTitle??mt(n),started:vt,producerVersion:Ct,surfaces:Ie?[Ie]:void 0,testmdRelPath:_a(o,n),definition:{path:"test.md",content:ri(n,"utf8")},cwd:o,packRootDir:ge(d.sessionDir,"evidence")}),Q=ka(e.evidenceAttach,ar),J=Q.session,O=null;if(e.evidenceAttach)O={executionId:e.evidenceAttach.id,testId:e.evidenceAttach.test,packTestDir:e.evidenceAttach.packTestDir};else if(ar)try{O=await ar.start()}catch(a){d.log("warn","EVIDENCE_START_FAILED","Evidence pack creation failed",{error:String(a)})}let Ae=[],wt=[],_n,Ue,lr=(a,u,p,b,w)=>{if(!O)return;J.noteSpawn(w?.length?{...a,steps:a.steps.map(_=>({..._,verifies:w}))}:a),a.resolution&&(_n=a.resolution),Ue=io(Ue,a.runnerEnvironment),Ae.push(Sa(u));let g=Jt(u,b);for(let _=0;_<g;_++)wt.push(p+_)},dr=()=>O?{packTestDir:O.packTestDir,ordinalOffset:J.nextOrdinalOffset()}:void 0,kn=async a=>{if(!O||!J)return;let u=co(Ae.length?Ae:[{resultCode:null}]);await J.archiveAttempt(u,a,{log:(p,b,w,g)=>d.log(p,b,w,g)}),Ae.length=0,wt.length=0},ci=typeof s.maxSteps=="string"&&s.maxSteps!==""?parseInt(s.maxSteps,10):void 0,ur=[],_t=He.hasBlocks(i.steps)?new He(i.steps,h.decisions,{evaluate:async a=>{let u=d.nextRunIndex(),p=Je===0,w={...qr({objective:a.join(`
|
|
55
|
+
`),conditions:a,url:p&&P.kind!=="device"?Ie??void 0:void 0,model:A,chrome:G,auth:c,sessionId:d.sessionId,runIndex:u,windowSize:{width:1920,height:1080},maxSteps:1,headless:V.headless??!1,disableAskUser:!0})};delete w.run_id,Ot(w,{environment:m});let g=null;try{for await(let _ of H.run(`run-${u}`,"evaluate",w)){if(t.onAgentEvent(_),_.type==="run_end"){g=_;break}if(_.type==="error")break}}catch(_){d.log("error","BLOCK_CONDITION_JUDGE_FAILED","evaluate run failed",{error:_.message})}return p&&g&&Je++,d.log("info","BLOCK_CONDITION_JUDGED","Control-flow conditions judged",{conditions:a,results:g?.condition_results??null,reasons:g?.condition_reasons??null}),g?.condition_results??a.map(()=>null)},whileConfig:a=>zt(i.steps[a]),sleep:a=>new Promise(u=>setTimeout(u,a))}):null;async function Sn(a){if(!_t)return null;let u=await _t.before(a),p=i.steps[a];switch(u.action){case"run":return null;case"author":return{kind:"author"};case"skip":return{kind:"done",stop:null};case"structural":return rt(a),ae.recordStep(p,{status:"passed",duration_s:0}),d.log("info","BLOCK_STRUCTURAL_STEP","Control-flow marker step",{step:p.flatIndex,marker:p.controlFlow}),{kind:"done",stop:null};case"jump":return d.log("info","BLOCK_WHILE_REENTER","While condition holds \u2014 re-entering the body",{from:p.flatIndex,to:u.to+1}),{kind:"jump",to:u.to};case"fail":return rt(a),ae.recordStep(p,{status:"failed",duration_s:0,reason:u.reason}),d.log("error","BLOCK_STEP_FAILED",u.reason,{step:p.flatIndex}),{kind:"done",stop:{failedAt:a,cancelled:!1}}}}async function Rn(a){let u=i.steps[a];rt(a),Je++,ue=!0,pt.add(i.steps[a].flatIndex);let p=d.nextRunIndex();ht=p,await ir(ze(Ce.raw,u.config.variables,u.objective).raw);let b=cr(a,p),w=Date.now(),g=null,_=null,D=null,N=!1,C=0,T=Ft(),L={...b};delete L.run_id,Ot(L,{environment:m});let k=`run-${p}`;try{z?.setRunActive(!0);try{for await(let x of H.run(k,"author",L)){if(t.onAgentEvent(x),T=wr(T,x),x.type==="bifurcation"){let $=x.count??x.flows?.length??0;(x.is_single_flow??$<=1)||(D=x.flows??null,N=!0,C=0)}else if(x.type==="run_start"&&N)C++;else if(x.type==="step_event"&&x.event==="reasoning")z?.setStepText(x.detail);else if(x.type==="step_end"&&(x.status==="passed"&&z?.setStepComplete(),tt)){let $=N?Math.max(0,C-1):0;tt(x.index,$,x.child_id,typeof x.ordinal=="number"&&x.id?{ordinal:x.ordinal,id:x.id}:void 0)}if(x.type==="run_end"){g=x;break}if(x.type==="error"){_=x.message??"runner error";break}}}finally{z?.setRunActive(!1)}}catch(x){_=x.message}H.diedUnexpectedly&&yt();let B=Math.round((Date.now()-w)/1e3),Z=It(a,p,g,D,_,B);return d.recordStepRun({testmdStepIndex:i.steps[a].flatIndex,runIndex:p,totalRunDirs:Jt(g,D)}),tr+=Ze(g),Oe+=Ze(g),lr(T,g,p,D,i.steps[a].verifies),{continueOverall:Z}}async function En(a){if(F||e.signal?.aborted)return{failedAt:a,cancelled:!0};if(yt())return{failedAt:a,cancelled:!1};let u=i.steps[a],p=h.decisions[a];if(p.kind!=="replay")return process.stderr.write(`error: runReplayPhase invoked on a non-replay decision at step ${a}
|
|
56
|
+
`),{failedAt:a,cancelled:!1};let b=d.nextRunIndex();ht=b;let w=Xt(a)?Ie??void 0:i.steps[a].unitEntryUrl,g={width:K.window_size.width,height:K.window_size.height},_=ze(Ce.raw,u.config.variables,u.objective),D=Fr({step:u,decision:p,chrome:G,device:P.kind==="device"?P.device:void 0,auth:c,sessionId:d.sessionId,runIndex:b,sessionDir:d.sessionDir,windowSize:g,environmentId:pn,forceNavigateUrl:P.kind==="device"?void 0:w,sessionContext:d.getContext(),variables:Object.keys(_.variables).length>0?_.variables:void 0,evidence:dr(),investigationAsync:!Q.ownsLifecycle});await ir(_.raw),rt(a),Je++;let N=Date.now(),C=null,T=null,L=Ft(),k={...D};delete k.run_id,Ot(k,{environment:m});let B=`run-${b}`;try{z?.setRunActive(!0);try{for await(let U of H.run(B,"replay",k)){if(t.onAgentEvent(U),L=wr(L,U),U.type==="step_event"&&U.event==="reasoning"?z?.setStepText(U.detail):U.type==="step_end"&&(U.status==="passed"&&z?.setStepComplete(),tt&&tt(U.index,0,U.child_id,typeof U.ordinal=="number"&&U.id?{ordinal:U.ordinal,id:U.id}:void 0)),U.type==="run_end"){C=U;break}if(U.type==="error"){T=U.message??"runner error";break}}!Q.ownsLifecycle&&C?.status==="failed"&&ur.push({exited:H.exited.then(()=>{}).catch(()=>{}),cancel:()=>{try{H?.cancel()}catch{}}})}finally{z?.setRunActive(!1)}}catch(U){T=U.message}if(H.diedUnexpectedly&&yt(),F)return{failedAt:a,cancelled:!0};let Z=Math.round((Date.now()-N)/1e3),x=It(a,b,C,null,T,Z);d.recordStepRun({testmdStepIndex:i.steps[a].flatIndex,runIndex:b,totalRunDirs:Jt(C,null)}),lr(L,C,b,null,i.steps[a].verifies),Oe+=Ze(C);let $=!!T||C?.status==="failed";return Jo(a,$?"failed":"ok"),$||!x?{failedAt:a,cancelled:!1}:null}async function ui(a){Wo(a,i.steps.length),_t?.reset();for(let u=0;u<a;u++){let p=await Sn(u);if(p?.kind==="done"){if(p.stop)return p.stop;continue}if(p?.kind==="jump"){u=p.to-1;continue}if(p?.kind==="author"){let w=i.steps[u];if(w.replayOnly)return Te(u,w.replayOnly),Ne(u,w.replayOnly),ae.recordStep(w,{status:"failed",duration_s:0,reason:`replay-only step @${w.replayOnly} has no recording`}),{failedAt:u,cancelled:!1};if(!(await Rn(u)).continueOverall)return{failedAt:u,cancelled:!1};continue}let b=await En(u);if(b)return b}return{failedAt:null,cancelled:!1}}let Cn=async()=>{if(E||h.degradedReadonly)return!0;let a=c.basicAuth;if(!a){let g=await c.resolver.resolve(!0);g?.username&&g?.access_key&&(a={username:g.username,access_key:g.access_key},c.basicAuth=a)}if(!h.testId||!h.fromCommitId||!a)return process.stderr.write(`error: cannot acquire lock \u2014 missing required state
|
|
57
|
+
`),!1;let u=d.sessionId,p=s.onLockConflict??i.rootGlobal.on_lock_conflict??"readonly",b=await sn({tmsBaseUrl:y.tmsBaseUrl,testId:h.testId,fromCommitId:h.fromCommitId,newCommitId:u,basicAuth:a,onLockConflict:p}),w=b.outcome;if(w==="ok"){E=!0,h.newCommitId=u,d.log("info","MID_RUN_LOCK_ACQUIRED","Mid-run lock acquired",{test_id:h.testId}),l&&t.onLockState({phase:"acquired",scope:"mid_run"}),Mt({baseUrl:Ye(y.tmsBaseUrl),testId:h.testId,auth:We(a),lifecycle:r});let g=await ni({resolved:i,decisions:h.decisions,tmsBaseUrl:y.tmsBaseUrl,newCommitId:u,basicAuth:a,mode:p,lifecycle:r,alreadyLocked:h.unitLocks,allUnits:!0});return g.outcome==="ok"?h.unitLocks.push(...g.locks):process.stderr.write(`warn: mid-run unit lock acquisition degraded (${g.outcome}) \u2014 affected units will not self-commit
|
|
58
|
+
`),!0}if(b.outcome==="readonly"){h.degradedReadonly=!0;let g=b.reason==="disabled"?"playground disabled for this test":b.reason==="base_mismatch"?"base commit mismatch":"concurrent session";return d.log("warn","MID_RUN_LOCK_READONLY","Mid-run lock unavailable; healing continues in readonly (no commit)",{test_id:h.testId,reason:b.reason}),l&&t.onLockState({phase:"conflict",scope:"mid_run",reason:"readonly"}),process.stderr.write(`[lock] mid-run ${g} \u2014 healing continues in readonly mode (no commit)
|
|
59
|
+
`),!0}return d.log("error","MID_RUN_LOCK_CONFLICT","Mid-run lock acquisition failed",{reason:w}),l&&t.onLockState({phase:"conflict",scope:"mid_run",reason:w}),process.stderr.write(`error: mid-run lock acquisition failed (${w})
|
|
60
|
+
`),!1},An=async()=>{try{z?.kill(),z=null,be?.kill(),G=await Hr({config:{chrome_profile_path:V.chrome_profile??null,window_size:{width:1920,height:1080}},startUrl:ot,headless:V.headless??!1,wsEndpoint:V.ws_endpoint,cdpEndpoint:V.cdp_endpoint}),be=G.instance,nr=Ir(G.cdpEndpoint);let a=G.cdpEndpoint??V.cdp_endpoint;if(a&&!V.ws_endpoint&&!V.headless&&!e.isAgent)try{z=Vr({headless:V.headless??!1,cdpEndpoint:a,chromePid:be?.process.pid})}catch(u){d.log("warn","OVERLAY_SPAWN_FAILED","Marker overlay respawn failed",{error:String(u)})}return d.log("info","BROWSER_RECYCLED","Fresh browser brought up for the replay re-attempt",{cdp_endpoint:G.cdpEndpoint}),!0}catch(a){return d.log("error","RECYCLE_FAILED","Could not bring up a fresh browser for the replay re-attempt",{error:a.message}),process.stderr.write(`error: could not recycle the browser for the replay re-attempt: ${a.message}
|
|
61
|
+
`),!1}},xn=async()=>{if(P.kind!=="device"||P.device.target_kind!=="simulator"||P.device.no_reset===!0||!P.device.udid)return;let a=await Vn("xcrun",["simctl","keychain",P.device.udid,"reset"],{timeoutMs:3e4});a.code===0?d.log("info","SIM_KEYCHAIN_RESET","Simulator keychain reset for the replay re-attempt"):d.log("warn","SIM_KEYCHAIN_RESET_FAILED","Could not reset the simulator keychain; keychain-backed login state may survive the recycle",{error:a.stderr.trim()||a.stdout.trim()})};if(l){let a=Lt();if(!a)return process.stderr.write("error: v16-runner not found. Build the binary with `cd v16-runner && python build.py` or ensure Python is available.\n"),r.cleanup("marker-overlay","v16-runner not found"),r.cleanup("chrome","v16-runner not found"),await d.finish("complete"),{overallStatus:"failed",exitCode:2,outputDir:ee(n),durationS:0,uploadResult:null};let u=so({environment:m,mode:v.mode??"testing",assertionMode:cn,finalValidation:mn,username:c.basicAuth?.username,accessKey:c.basicAuth?.access_key,sessionId:d.sessionId});P.kind==="device"&&await oo(u,P.device),H=new jt({env:u,runner:a,log:(C,T,L,k)=>d.log(C,T,L,k),sessionId:d.sessionId}),r.register("runner",()=>{(Hn()||e.signal?.aborted)&&(F=!0);try{H?.kill()}catch{}});let p=C=>{let T={...P.kind==="device"?{device:P.device}:{},cdp_endpoint:C.cdpEndpoint,ws_endpoint:C.wsEndpoint,width:K.window_size.width,height:K.window_size.height,headless:V.headless??!1,model:A,session_id:d.sessionId,disable_ask_user:!0},L=No(fe(i.rootPath));return L.length>0&&(T.media_info=L),c.basicAuth?(T.username=c.basicAuth.username,T.access_key=c.basicAuth.access_key):c.token&&(T.auth={type:"bearer",token:c.token}),T};await H.start(p(G));let b=async()=>{try{await H?.shutdown()}catch{}if(!await An())return!1;try{return H=new jt({env:u,runner:a,log:(C,T,L,k)=>d.log(C,T,L,k),sessionId:d.sessionId}),await H.start(p(G)),!0}catch(C){return d.log("error","RECYCLE_FAILED","Could not restart the persistent runner after recycle",{error:C.message}),process.stderr.write(`error: could not restart the runner for the replay re-attempt: ${C.message}
|
|
62
|
+
`),!1}},w=async()=>{try{await H?.shutdown()}catch{}await xn();try{return H=new jt({env:u,runner:a,log:(C,T,L,k)=>d.log(C,T,L,k),sessionId:d.sessionId}),await H.start(p(G)),P.kind==="device"&&P.device.no_reset===!0&&d.log("warn","DEVICE_RECYCLED_DIRTY","no_reset: true \u2014 the re-attempt keeps the app state the broken replay left behind"),d.log("info","DEVICE_RECYCLED","Fresh device session brought up for the replay re-attempt"),!0}catch(C){return d.log("error","RECYCLE_FAILED","Could not bring up a fresh device session for the replay re-attempt",{error:C.message}),process.stderr.write(`error: could not recycle the device session for the replay re-attempt: ${C.message}
|
|
63
|
+
`),!1}},g=s.author===!0;g&&(jr(),d.log("info","FORCE_AUTHOR_RUN","--author flag set; walker bypassed; identity kept"));let{authorBoundary:_,cancelledInPhase:D,shrinkCount:N}=await ts({decisions:h.decisions,forceAuthor:g,hasRetry:xr(s),onReplayOnlyFail:Ne,maxShrinks:lt.maxShrinks,runReplayPhase:ui,session:d,accumulator:ae,acquireLockIfNeeded:Cn,archiveAttempt:kn,recycleBrowser:P.kind==="web"&&be&&Q.ownsLifecycle?b:P.kind==="device"&&Q.ownsLifecycle?w:void 0});if(gt=N>0,Qe=_,er=N,N>0&&(d.log("info","ADAPTIVE_HEAL_TRIGGERED","Adaptive heal engaged",{shrink_count:N,final_author_boundary:_}),t.onAdaptiveHeal({shrink_count:N,final_author_boundary:_,complete_reauthor:_===0})),_===0&&N>0&&d.log("info","COMPLETE_REAUTHOR_TRIGGERED","Complete reauthor fallback",{shrink_count:N}),!D&&_>=0)for(let C=_;C<i.steps.length&&!e.signal?.aborted;C++){let T=i.steps[C],L=await Sn(C);if(L?.kind==="done"){if(L.stop)break;continue}if(L?.kind==="jump"){C=L.to-1;continue}if(L?.kind==="author"&&T.replayOnly){Te(C,T.replayOnly),Ne(C,T.replayOnly),ae.recordStep(T,{status:"failed",duration_s:0,reason:`replay-only step @${T.replayOnly} has no recording`});break}if(yt()){ae.recordStep(T,{status:"failed",duration_s:0,reason:"v16-runner exited unexpectedly mid-session"});break}if(!ae.shouldRunFlatStep(T))continue;let k=h.decisions[C];if(k?.kind==="replay"&&k.replayOnly){let Z=await En(C);if(Z){Z.cancelled||(Te(C,k.replayOnly),Ne(C,k.replayOnly));break}continue}let{continueOverall:B}=await Rn(C);if(!B||F||e.signal?.aborted)break}}else{if(He.hasBlocks(i.steps))return process.stderr.write(`error: this test has if/else or while blocks (@if \u2026 @end-if, @while \u2026 @end-while), which run in agent mode only \u2014 re-run with --agent
|
|
64
|
+
`),r.cleanup("marker-overlay","control-flow blocks need agent mode"),r.cleanup("chrome","control-flow blocks need agent mode"),await d.finish("complete"),{overallStatus:"failed",exitCode:2,outputDir:ee(n),durationS:0,uploadResult:null};let{effectiveDecisions:a}=await import("./effective-decisions-UNE2TFVA.js"),{decideRetry:u}=await import("./replay-policy-A62KXE6Y.js"),p=xr(s),b=lt.maxShrinks,w=s.author===!0;w&&(jr(),d.log("info","FORCE_AUTHOR_RUN","--author flag set; walker bypassed; identity kept"));let g=w?0:at(h.decisions),_=0,D=null,N=P.kind==="device"?P.device.no_reset:void 0,C=0,T=()=>C++===0?N??!1:!0,L=h.decisions.filter(x=>x.kind==="replay").length,k=h.decisions.length-L,B=[];s.push&&B.push("--push"),p||B.push("--no-adaptive-heal"),w&&B.push("--author");let Z={source:n,steps:{total:h.decisions.length,replay:L,author:k},model:A,viewport:{width:K.window_size.width,height:K.window_size.height},chrome:G.cdpEndpoint??G.wsEndpoint??"managed",session:d.sessionName??"ephemeral",variables:{count:Object.keys(ie.raw).length,secrets:Object.values(ie.raw).filter(x=>x.secret).length,names:Object.keys(ie.raw)},flags:B,mode:v.mode??"testing"};for(;;){let x=d.snapshot(),$=ae.snapshot();C=0;let U=a(h.decisions,g,w);if(_>=1){let j=g===0?`\u{1FA79} Healing \u2014 full re-author, heal budget exhausted (${_}/${b})`:`\u{1FA79} Healing ${_}/${b} \u2014 replay 0..${g-1}, re-author ${g}..${h.decisions.length-1}
|
|
65
|
+
reason: replay miss at step ${(D??0)+1}`;process.stderr.write(j+`
|
|
66
|
+
`)}let nt=_>=1&&g>0&&D!==null?{startIdx:0,endIdx:D,count:D}:void 0;z?.setRunActive(!0);let me=await Da({decisions:U,resolved:i,session:d,accumulator:ae,tuiConfig:K,globalConfig:Z,buildStepConfigAt:(j,le)=>{let ne=cr(j,le);return P.kind==="device"&&ne.device&&(ne.device={...ne.device,no_reset:T()}),ne},buildReplayConfig:j=>{let le=h.decisions[j];if(le.kind!=="replay")throw new Error("expected replay decision at index "+j);let ne=i.steps[j];return Fr({step:ne,decision:le,chrome:G,device:P.kind==="device"?{...P.device,no_reset:T()}:void 0,auth:c,sessionId:d.sessionId,runIndex:d.nextRunIndex(),sessionDir:d.sessionDir,windowSize:{width:K.window_size.width,height:K.window_size.height},environmentId:pn,forceNavigateUrl:P.kind==="device"?void 0:j===0?Ie??void 0:ne.unitEntryUrl,sessionContext:d.getContext(),variables:Ca(Ce.raw,ne.config.variables,ne.objective),evidence:dr()})},onAnyAuthorStep:j=>{ue=!0,pt.add(i.steps[j].flatIndex)},onCancel:()=>{he=!0},topBannerModel:A,topBannerAuth:`${S.getActiveProfile()??"no profile"}/${m}`,spawnOpts:{environment:m,mode:v.mode??"testing",assertionMode:cn,finalValidation:mn,log:(j,le,ne,fr)=>d.log(j,le,ne,fr)},priorAttemptRollup:nt,pushStepLevelDelta:(j,le)=>ir(ze(Ce.raw,j,le).raw),onSequencerStepEnd:(j,le,ne,fr)=>{let hi=Math.round((Date.now()-fr)/1e3),yi=j.hadError?j.reason??"runner error":null,bi=It(le,ne,j.runEnd,j.bifurcationFlows??null,yi,hi);return d.recordStepRun({testmdStepIndex:i.steps[le].flatIndex,runIndex:ne,totalRunDirs:Jt(j.runEnd,j.bifurcationFlows)}),lr(j.evidence??Ft(),j.runEnd,ne,j.bifurcationFlows,i.steps[le].verifies),Oe+=Ze(j.runEnd),U[le]?.kind==="author"&&(tr+=Ze(j.runEnd)),bi},screenshotDispatcher:tt,onReasoning:j=>z?.setStepText(j),onStepComplete:()=>z?.setStepComplete(),onSpawnStart:j=>{ht=j},host:t});if(z?.setRunActive(!1),me.cancelled){r.cleanup("marker-overlay","user cancelled run"),r.cleanup("chrome","user cancelled run");break}if(me.failedAt===null)break;let Et=h.decisions[me.failedAt],Be=u({failedAt:me.failedAt,shrinkCount:_,hasRetry:p,maxShrinks:b,failedAtReplayOnly:Et?.kind==="replay"?Et.replayOnly:void 0});if(Be.kind==="fail"){Be.replayOnly&&(Te(me.failedAt,Be.replayOnly),Ne(me.failedAt,Be.replayOnly));break}if(!E&&!await Cn()||P.kind==="web"&&be&&Q.ownsLifecycle&&!await An())break;P.kind==="device"&&Q.ownsLifecycle&&await xn(),await kn(me.failedAt),d.rollback(x),ae.rollback($),Be.kind==="complete-reauthor"?g=0:(g=Be.newAuthorBoundary,_++),gt=!0,d.log("info","RETRY_TRIGGERED","Retry loop triggered (TTY)",{shrink_count:_,failed_at:D}),g===0&&d.log("info","COMPLETE_REAUTHOR_TRIGGERED","Complete reauthor fallback (TTY)",{shrink_count:_}),D=me.failedAt}Qe=g,er=_}let re=ae.finalize(),_e=Math.round((Date.now()-In)/1e3),mi={session:d,resolvedAuth:c,chromeResult:G,chromeInstance:be??null,testId:d.testId??null,preparedVariables:ie,variableIds:bt,globalContext:bn,localContext:vn,tuiConfig:K,env:m,localMode:!!s.local},Pn=!1,Tn=!1,Dn=!1,mr=!1,Ln=async(a={})=>{if(!O)return!1;if(Q.ownsLifecycle?Pn:Dn)return!0;try{let u=await nr(),p=on(ue)==="replay",b=Me(n),w=ge(d.sessionDir,"execution.json"),g=wo(O.packTestDir,p?[b,w]:[w,b],(k,B,Z,x)=>d.log(k,B,Z,x)),{ids:_,linear:D}=g?_o(O.packTestDir):{ids:[],linear:!0},{steps:N,tail:C,unjoined:T}=Io(J.steps,_,p,D);g?T?d.log("warn","SKIPPED_TAIL_UNJOINED","Executed records don't align with the authored blob \u2014 skipped tail withheld",{executed:J.steps.length,leaves:_.length}):C.length>0&&d.log("info","SKIPPED_TAIL_APPENDED","Unexecuted authored actions recorded as skipped",{count:C.length}):d.log("warn","SKIPPED_TAIL_NO_BLOB","No auteur blob in pack \u2014 unexecuted actions cannot be recorded as skipped",{});let L=await J.writeResult({steps:[...N,...C],heal:{shrinkCount:er,authorBoundary:Qe,totalSteps:h.decisions.length,forced:s.author===!0,creditsConsumed:tr},spawns:Ae.length?Ae:[{resultCode:null}],tags:i.rootGlobal.tags,externalIdInput:{...Re?Re.externalId:{},execution_id:O.executionId,session_id:d.sessionId,commit_id:p?h.fromCommitId??d.sessionId:d.sessionId,test_id:h.testId??d.testId??void 0,testcase_id:a.testcaseId||h.testcaseId||d.testcaseId||void 0,tc_id:ii,project_id:q??void 0,folder_id:we??void 0,org_id:d.orgId!=null?String(d.orgId):void 0,session_name:d.sessionName??it(n),user_name:d.userName??void 0,user_email:d.userEmail??void 0,sharable_link:ys(X(m).testManagerUiUrl,q,a.testcaseId??h.testcaseId??d.testcaseId,a.shareId)},runnerEnv:go({cdpBrowser:u,resolution:_n,runnerEnvironment:Ue,deviceName:Ee.deviceName,deviceModel:Ee.modelIdentifier,pixelResolution:O?await po(O.packTestDir):void 0}),intentEnv:ao(A,Ue,Q.ownsLifecycle?void 0:on(ue)),durationMs:Date.now()-In,log:(k,B,Z,x)=>d.log(k,B,Z,x)});if(!Q.ownsLifecycle)return await mo(J.pack,O.testId,ge(d.sessionDir,"tui.log"),{requireRealLog:!!Ue?.native_platform,appiumMarks:J.appiumMarks}),Dn=!0,d.log("info","EVIDENCE_RESULT_WRITTEN","Member result.yaml written",{execution_id:O.executionId,verdict:L}),!0;if(!Tn)try{await zo(_r(process.cwd()),B=>d.log("warn","SYNC_BEHIND",B,{}));let k=bo({cwd:process.cwd(),members:[{path:n,verdict:L,executionId:O.executionId,startedAt:new Date().toISOString(),acs:yo(J.steps),mode:"testmd",local:!!s.local}]});Tn=!0;for(let B of k.warnings)d.log("warn","EXEC_SYNC",B,{});k.synced>0&&d.log("info","EXEC_SYNC",`context sync: ${k.synced} fact(s), ${k.superseded} supersession(s)`,{})}catch(k){d.log("warn","EXEC_SYNC",`exec-sync failed: ${k instanceof Error?k.message:String(k)}`,{})}try{let k=vo(J.pack,_r(process.cwd()));k.status==="skipped"&&d.log("warn","EVIDENCE_COVERAGE_SKIPPED",`coverage/usecases.yaml not written: ${k.reason}`,{})}catch(k){d.log("warn","EVIDENCE_COVERAGE_SKIPPED","coverage writer threw",{error:String(k)})}return await fo({executionId:O.executionId,testId:O.testId,saved:!0,runKind:on(ue),verdict:L,outputStemDir:ee(n),cwd:o,packDir:J.pack,tuiLogPath:ge(d.sessionDir,"tui.log"),expectStatusDisagrees:(s.bugDetection??K.bug_detection)==="continue",log:(k,B,Z,x)=>d.log(k,B,Z,x),surface:"testmd",requireRealLog:!!Ue?.native_platform,appiumMarks:J.appiumMarks}),Pn=!0,d.log("info","EVIDENCE_SEALED","Evidence pack sealed",{execution_id:O.executionId,verdict:L}),!0}catch(u){return d.log("warn","EVIDENCE_SEAL_FAILED","Evidence pack seal failed",{error:String(u)}),!1}},kt=Fe&&(E||h.isFirstRun)&&!h.degradedReadonly,fi=async()=>{if(!c.basicAuth)return null;let a=X(m),u=(ue||s.push===!0)&&!he,p=(E||h.isFirstRun)&&!he&&re.overallStatus==="passed"&&!h.degradedReadonly;d.log("info","PIPELINE_GATE_STATE","Derived gate state (finalize)",{phase:"finalize",shouldUploadArtifacts:Fe,shouldUploadPipeline:kt,shouldReplaceLocalOutput:u,shouldCommit:p,lockHeld:E,anyAuthorStepRan:ue,cancelled:he,overallStatus:re.overallStatus});let b=Ks({mobile:P.kind==="device",session:d,env:m,auth:c,variables:ie,variableIds:bt,testParams:Re?.testParams,projectId:q,folderId:we,totalSteps:re.outcomes.length,totalDuration:_e,screenshotExtMap:Xe?.getExtMap(),codeExport:Gs({codeExport:s.codeExport,codeLanguage:s.codeLanguage,skipCodeValidation:s.skipCodeValidation},K.code_export),onProgress:()=>{},log:(g,_,D,N)=>d.log(g,_,D,N),shouldUploadArtifacts:kt,shouldReplaceLocalOutput:u,shouldCommit:p,isFirstRun:h.isFirstRun,resolvedTest:i,sourcePath:n,stepRunRecords:d.getStepRunRecords(),authoredFlatIdx:[...pt],blockOutcomes:_t?.outcomes(),unitLocks:h.unitLocks,outcomes:re.outcomes,overallStatus:re.overallStatus,fromCommitId:h.fromCommitId,startedISO:vt,durationS:_e,tmsIds:{testId:h.testId??d.testId??void 0,testcaseId:h.testcaseId??d.testcaseId??void 0,projectId:q??void 0,folderId:we??void 0,orgId:d.orgId??void 0,sessionName:d.sessionName??it(n)},tmsBaseUrl:y.tmsBaseUrl,testId:h.testId??void 0,newCommitId:h.newCommitId??void 0,basicAuth:c.basicAuth??void 0,decisions:h.decisions,wantsPush:s.push===!0,retryTriggered:gt,forceAuthor:s.author===!0,commitBox:Zt,testmdSync:s.testmdSync!==!1,onAgentEvent:g=>t.onAgentEvent(g),evidence:O&&Q.ownsLifecycle?{executionId:O.executionId,packTestDir:O.packTestDir,sealedPackPath:J.pack,cwd:o,runIndices:wt,sealFn:Ln}:void 0,evidenceRead:O&&!Q.ownsLifecycle?{packTestDir:O.packTestDir,runIndices:wt}:void 0,authoredExecutionPath:ue?void 0:Me(n)});h.newCommitId!=null&&(b.skipTmsFinalize=!0);let w=new Mo(b);return l?await w.execute():await t.runUpload(w,g=>{if(g.testcaseId&&g.shareId&&q)return Kt(a.testManagerUiUrl,q,g.testcaseId,g.shareId)})};O&&await nr(),H&&(await H.shutdown(),r.cleanup("runner","test.md run complete"));let ce=await Fs(mi,{performUpload:fi,runCleanup:()=>{r.cleanup("chrome","test.md run complete")},log:(a,u,p,b)=>d.log(a,u,p,b)},{overallStatus:re.overallStatus,outcomes:re.outcomes,sourcePath:n,title:i.rootTitle,rootSteps:i.rootSteps,startedISO:vt,durationS:_e,localMode:!!s.local,skipLocalWrites:!0,mobile:P.kind==="device"});Q.ownsLifecycle&&kt&&ce.uploadResult?.success&&(mr=!0);let On=await Ln({testcaseId:ce.uploadResult?.testcaseId,shareId:ce.uploadResult?.shareId}),jn=s.evidencePublish===!1,Fn=Q.ownsLifecycle&&!!O&&!!c.basicAuth&&Qs({shouldUploadArtifacts:Fe,lockHeld:E,isFirstRun:h.isFirstRun,sealed:On,testId:h.testId});if(Fn&&jn)d.log("info","EVIDENCE_PUBLISH_SKIPPED","Replay evidence publish skipped (--no-evidence-publish)",{execution_id:O.executionId}),process.stderr.write(`info: evidence publish skipped (--no-evidence-publish)
|
|
67
|
+
`);else if(jn&&(E||h.isFirstRun))process.stderr.write(`note: --no-evidence-publish has no effect on author/commit runs
|
|
68
|
+
`);else if(Fn){let a=c.basicAuth,u=O,p=q,b=await Zs({controller:new xe(y.controllerBaseUrl,{username:a.username,accessKey:a.access_key}),tms:new Dt(y.tmsBaseUrl,c.resolvedCreds?.username??a.username,c.resolvedCreds?.access_key??a.access_key),testId:h.testId,sessionId:d.sessionId,executionId:u.executionId,sealedPackPath:J.pack,projectId:p});mr=b.ok,b.ok?d.log("info","EVIDENCE_INGESTED","Replay evidence uploaded and ingested",{execution_id:u.executionId,project_id:p}):(d.log("warn","EVIDENCE_PUBLISH_FAILED","Replay evidence publish failed",{execution_id:u.executionId,stage:b.stage,error:b.error}),process.stderr.write(` \u26A0 evidence publish failed (${b.stage}): ${b.error}
|
|
69
|
+
`)),t.onAgentEvent({type:"test_md_evidence_ingest",status:b.ok?"ok":"failed",evidence_id:u.executionId,...b.ok?{}:{stage:b.stage}})}if(M=!0,await Pa(n,h,d,re.outcomes,re.overallStatus,vt,_e,ce.uploadResult,K,s,{resolvedAuth:c,tmsBaseUrl:y.tmsBaseUrl},E,he,Zt.committed),h.isFirstRun&&s.testmdSync!==!1)try{let a=fe(n);if(Po({shouldUploadPipeline:kt,uploadSucceeded:!!ce.uploadResult?.success,metaCommitId:a?.commit_id,metaTestId:a?.test_id})){let u=await Nt({sourcePath:n,testId:a.test_id,sessionId:d.sessionId,commitId:a.commit_id,controller:new xe(y.controllerBaseUrl,{username:c.basicAuth.username,accessKey:c.basicAuth.access_key})});u.ok?d.log("info","BUNDLE_SYNC_OK","testmd bundle pushed",{commit_id:a.commit_id,bytes:u.bytes}):(d.log("warn","BUNDLE_SYNC_FAILED","testmd bundle sync failed",{commit_id:a.commit_id,stage:u.stage,error:u.error}),process.stderr.write(` \u26A0 bundle sync failed (${u.stage}): ${u.error}
|
|
70
|
+
`)),t.onAgentEvent({type:"test_md_bundle_sync",status:u.ok?"ok":"failed",commit_id:a.commit_id,path:n,...u.ok?{bytes:u.bytes}:{stage:u.stage}})}}catch(a){d.log("warn","BUNDLE_SYNC_FAILED","testmd bundle sync threw",{error:a instanceof Error?a.message:String(a)})}else h.isFirstRun&&d.log("info","BUNDLE_SYNC_SKIPPED","testmd bundle sync skipped",{reason:"flag"});let Un=X(m),St=ce.uploadResult?.testcaseId,Rt=St&&ce.uploadResult?.shareId&&q?Kt(Un.testManagerUiUrl,q,St,ce.uploadResult.shareId):void 0,pi=i.unitFiles.filter(a=>a.file!==i.rootPath).map(a=>{let u=i.steps.filter(g=>g.owningFile===a.file),p=u.filter(g=>pt.has(g.flatIndex)).length,w=(a.kind==="test"?fe(a.file):null)?.commit_id===d.sessionId;return{path:a.file,kind:a.kind,replayed:u.length-p,authored:p,committed:w,...w?{commit_id:d.sessionId}:{}}}),Nn={overallStatus:re.overallStatus,durationS:_e,creditsConsumed:Oe,decisions:h.decisions,outcomes:re.outcomes,cancelled:he,retryTriggered:gt,lockHeld:E,anyAuthorStepRan:ue,isFirstRun:h.isFirstRun,wantsPush:s.push===!0,uploadResult:ce.uploadResult,shouldUploadArtifacts:Fe,shouldReplaceLocalOutput:ue&&!he,shouldCommit:(E||h.isFirstRun)&&!he&&re.overallStatus==="passed"&&!h.degradedReadonly,committed:Zt.committed,shareUrl:Rt,imports:pi},{buildSummaryEvent:gi}=await import("./SummaryBox-JQJKGYDM.js");if(l?t.onAgentEvent(gi(Nn)):await t.onSummary(Nn),!l){let a=St&&q?bs(Un.testManagerUiUrl,q,St):void 0;await t.onLinks({recordedTestPath:n,outputDir:ee(n),shareableLink:Rt,testCaseLink:a,codeExportDir:ce.uploadResult?.codeExportDir})}if(Q.ownsLifecycle&&J&&On&&!e.suppressEvidenceOffer){let{offerEvidenceView:a}=await import("./evidence-KRNDKDCT.js");await a({packPath:J.pack,env:m,isTTY:!l&&!he&&!!process.stdin.isTTY&&!!process.stderr.isTTY,log:u=>process.stderr.write(u+`
|
|
71
|
+
`)})}return t.onAgentEvent({type:"test_md_done",overall_status:re.overallStatus,duration_s:_e,session_id:d.sessionId,...Rt?{share_url:Rt}:{}}),await d.reportCompletedSession({runsCompleted:d.getStepRunRecords().length,creditsConsumed:Oe,durationSeconds:_e}),{overallStatus:re.overallStatus,exitCode:re.overallStatus==="passed"?0:1,outputDir:ee(n),durationS:_e,creditsConsumed:Oe,uploadResult:ce.uploadResult,anyAuthorStepRan:ue,resultCode:uo(Ae),...ur.length?{pendingInvestigations:ur}:{},ownPack:Q.ownsLifecycle?Js({executionId:O?.executionId,testId:h.testId??O?.testId,testcaseId:ce?.uploadResult?.testcaseId,commitId:d.sessionId,published:mr}):void 0}}finally{!M&&(E||h.unitLocks.length>0)&&await Ta(h,d,E,{resolvedAuth:c,tmsBaseUrl:y.tmsBaseUrl})}}function Ra(e){if((e.env??process.env).KANE_CLI_MODE==="hyperexecute")return null;let t=Vo({globalDir:e.globalDir,localDir:ge(e.cwd,".testmuai","variables"),file:e.opts.variablesFile,inline:e.opts.variables}),r=Ho(e.resolved,t,{authorFrom:e.authorFrom,produced:e.produced});return r.length===0?null:{text:Lr(r,{cwd:e.cwd,entryFile:mt(e.resolved.rootPath)}),event:Or(r,{cwd:e.cwd})}}function Ea(e,t){let r={...e,...t,...yr(e)},n=Object.keys(r).length>0?$e(r,""):{variables:{},objective:"",keyMap:{}};return{raw:r,auteur:n.variables,auteurObjective:"",...Yr(r)}}function ze(e,t,r){let n={...e,...t??{},...yr(e)};if(Object.keys(n).length===0)return{raw:n,variables:{},objective:r};let o=$e(n,r);return{raw:n,variables:Ts(o.variables,o.objective),objective:o.objective}}function Ca(e,t,r){let n=ze(e,t,r).variables;return Object.keys(n).length>0?n:void 0}function ti(e,t){let r=new Set(Qt),n={...e};for(let[o,s]of Object.entries(t))r.has(o)||o!=="variables"&&s!==void 0&&e[o]===void 0&&(n[o]=s);return n}function Aa(e,t){return e.length<=t?e:e.slice(0,t-1)+"\u2026"}async function xa(e,t,r,n,o,s){let l=Do(t);Yo(t,l);let f=ve(e),i=Ia(f)?JSON.parse(ri(f,"utf8")):null,c=i?.testcase_id,v=i?.test_id,m=i?.commit_id,y=r.push===!0,I=r.author===!0;y&&!c&&process.stderr.write(`[--push] no meta.json yet \u2014 flag is a no-op on first run
|
|
72
|
+
`);let A=n.resolvedAuth.basicAuth;if(!A){let te=await n.resolvedAuth.resolver.resolve(!0);te?.username&&te?.access_key&&(A={username:te.username,access_key:te.access_key},n.resolvedAuth.basicAuth=A)}let S=!!A,R=!r.local&&S&&v!=null&&m!=null&&c!=null,d=R&&(Bt(l)||y||I),F=To(t,l);if(F.length>0)return process.stderr.write(`error: replay-only step(s) cannot be replayed \u2014 the agent cannot author them, so the run will not start:
|
|
73
|
+
`+F.map(se=>` step ${se.flatIndex} "${se.heading}" @${se.kind} \u2014 ${se.reason} (${se.file})`).join(`
|
|
74
|
+
`)+`
|
|
75
|
+
Regenerate the test from KaneAI, or drop the marker to let the agent author the step.
|
|
76
|
+
`),{resolved:t,decisions:l,testId:v,testcaseId:c,fromCommitId:m,newCommitId:null,isFirstRun:!1,hasAuth:S,canLock:R,lockAcquired:!1,unitLocks:[],degradedReadonly:!1,abort:{exitCode:2}};if(y&&!R)return process.stderr.write(`error: --push requires authenticated credentials for the lock API. Run 'kane-cli login' (OAuth) or pass --username/--access-key inline.
|
|
77
|
+
`),{resolved:t,decisions:l,testId:v,testcaseId:c,fromCommitId:m,newCommitId:null,isFirstRun:!1,hasAuth:S,canLock:R,lockAcquired:!1,unitLocks:[],degradedReadonly:!1,abort:{exitCode:2}};if(I&&!S)return process.stderr.write(`error: --author requires authenticated credentials for the TMS API. Run 'kane-cli login' (OAuth) or pass --username/--access-key inline.
|
|
78
|
+
`),{resolved:t,decisions:l,testId:v,testcaseId:c,fromCommitId:m,newCommitId:null,isFirstRun:!1,hasAuth:S,canLock:R,lockAcquired:!1,unitLocks:[],degradedReadonly:!1,abort:{exitCode:2}};let h=null,E=!1,M=!1;if(d){h=o;let se=r.onLockConflict??t.rootGlobal.on_lock_conflict??"readonly",te=await sn({tmsBaseUrl:n.tmsBaseUrl,testId:v,fromCommitId:m,newCommitId:h,basicAuth:A,onLockConflict:se});if(te.outcome==="ok")E=!0,Mt({baseUrl:Ye(n.tmsBaseUrl),testId:v,auth:We(A),lifecycle:s});else{if(te.outcome==="abort")return{resolved:t,decisions:l,testId:v,testcaseId:c,fromCommitId:m,newCommitId:null,isFirstRun:!1,hasAuth:S,canLock:R,lockAcquired:!1,unitLocks:[],degradedReadonly:!1,abort:{exitCode:2}};h=null,M=!0,I&&process.stderr.write(te.reason==="disabled"?`[lock] --author: re-authoring locally in readonly mode (not committed); this test cannot be evolved, so the changes stay local
|
|
79
|
+
`:`[lock] --author: re-authoring locally in readonly mode (not committed); run again with --push once the playground is free
|
|
80
|
+
`)}}let Se=[],oe=d&&!E;if(!r.local&&S&&!oe){let se=r.onLockConflict??t.rootGlobal.on_lock_conflict??"readonly",te=await ni({resolved:t,decisions:l,allUnits:I,tmsBaseUrl:n.tmsBaseUrl,newCommitId:h??o,basicAuth:A,mode:se,lifecycle:s});if(te.outcome==="ok")Se=te.locks;else{if(E&&v&&m&&h&&await ft(n,v,m,h),pe(),te.outcome==="abort")return{resolved:t,decisions:l,testId:v,testcaseId:c,fromCommitId:m,newCommitId:null,isFirstRun:c==null,hasAuth:S,canLock:R,lockAcquired:!1,unitLocks:[],degradedReadonly:!1,abort:{exitCode:2}};process.stderr.write(`[lock] imported-unit conflict \u2014 whole run degrades to readonly (no commits, no uploads)
|
|
81
|
+
`),h=null,E=!1,M=!0}}return{resolved:t,decisions:l,testId:v,testcaseId:c,fromCommitId:m,newCommitId:h,isFirstRun:c==null,hasAuth:S,canLock:R,lockAcquired:E,unitLocks:Se,degradedReadonly:M}}async function ni(e){let t=new Set(e.resolved.steps.filter((n,o)=>e.decisions[o]?.kind==="author").map(n=>n.owningFile)),r=[];for(let n of e.resolved.unitFiles){if(n.kind!=="test"||n.file===e.resolved.rootPath||!e.allUnits&&!t.has(n.file)||e.alreadyLocked?.some(l=>l.file===n.file))continue;let o=fe(n.file);if(!o?.test_id||!o?.commit_id)continue;let s=await sn({tmsBaseUrl:e.tmsBaseUrl,testId:String(o.test_id),fromCommitId:String(o.commit_id),newCommitId:e.newCommitId,basicAuth:e.basicAuth,onLockConflict:e.mode});if(s.outcome==="ok"){r.push({file:n.file,testId:String(o.test_id),fromCommitId:String(o.commit_id)}),Mt({baseUrl:Ye(e.tmsBaseUrl),testId:String(o.test_id),auth:We(e.basicAuth),lifecycle:e.lifecycle});continue}if(s.outcome==="readonly"&&s.reason==="disabled"){process.stderr.write(`[lock] ${n.file}: playground disabled \u2014 this unit will not be committed
|
|
82
|
+
`);continue}for(let l of r)await De({baseUrl:Ye(e.tmsBaseUrl),testId:l.testId,body:{commitId:e.newCommitId,fromCommitId:l.fromCommitId},auth:We(e.basicAuth)}),pe(l.testId);return{outcome:s.outcome,locks:[]}}return{outcome:"ok",locks:r}}function Ye(e){return`${e}/kane-cli/v1`}function We(e){return{username:e.username,accessKey:e.access_key}}async function sn(e){let t=Ye(e.tmsBaseUrl),r=We(e.basicAuth),n={baseUrl:t,testId:e.testId,fromCommitId:e.fromCommitId,newCommitId:e.newCommitId,auth:r},o=await Nr(n);if(o.ok)return{outcome:"ok"};if(o.reason==="disabled")return process.stderr.write(`[lock] ${o.message}
|
|
83
|
+
[lock] running in readonly mode (no commit)
|
|
84
|
+
`),{outcome:"readonly",reason:"disabled"};if(!(o.reason==="concurrent"||o.reason==="base_mismatch"))return process.stderr.write(`[lock] acquire failed: ${o.reason} (HTTP ${o.httpStatus}): ${o.message}
|
|
85
|
+
`),{outcome:"abort"};let l=o.reason,f=o.reason==="concurrent"?"concurrent session":"base commit mismatch (pull latest)";if(e.onLockConflict==="fail")return process.stderr.write(`[lock] ${f}; aborting (--on-lock-conflict fail)
|
|
86
|
+
`),{outcome:"abort"};if(e.onLockConflict==="wait"){if(o.reason==="base_mismatch")return process.stderr.write(`[lock] base commit mismatch \u2014 pull latest; aborting
|
|
87
|
+
`),{outcome:"abort"};for(;;){process.stderr.write(`[lock] waiting (concurrent session)...
|
|
88
|
+
`),await new Promise(c=>setTimeout(c,3e4));let i=await Nr(n);if(i.ok)return{outcome:"ok"};if(i.reason!=="concurrent")return process.stderr.write(`[lock] wait drifted to ${i.reason} (HTTP ${i.httpStatus}): ${i.message}; aborting
|
|
89
|
+
`),{outcome:"abort"}}}return process.stderr.write(`[lock] ${f} \u2014 running in readonly mode (no commit)
|
|
90
|
+
`),{outcome:"readonly",reason:l}}async function Pa(e,t,r,n,o,s,l,f,i,c,v,m,y,I){let{decisions:A,testId:S,testcaseId:R,fromCommitId:d,newCommitId:F}=t,h=o==="passed";if(!I){let E=y?"cancelled":h?"commit did not land":o;m&&S&&d&&F&&(process.stderr.write(`[lock] run not committed (${E}); discarding playground lock
|
|
91
|
+
`),await ft(v,S,d,F));for(let M of t.unitLocks)await ft(v,M.testId,M.fromCommitId,F??r.sessionId);pe();return}pe()}async function Ta(e,t,r,n){let o=e.newCommitId??t.sessionId,s=e.unitLocks.length;process.stderr.write(`[lock] run exited before finalize; discarding playground lock${s?` + ${s} unit lock${s===1?"":"s"}`:""}
|
|
92
|
+
`);try{t.log("warn","LOCKS_RELEASED_EARLY_EXIT","Run exited before finalize; discarding held playground locks",{test_id:e.testId??null,unit_locks:s})}catch{}try{r&&e.testId&&e.fromCommitId&&await ft(n,e.testId,e.fromCommitId,o);for(let l of e.unitLocks)await ft(n,l.testId,l.fromCommitId,o)}finally{pe()}}async function ft(e,t,r,n){let o=e.resolvedAuth.basicAuth;if(!o){let l=await e.resolvedAuth.resolver.resolve(!0);l?.username&&l?.access_key&&(o={username:l.username,access_key:l.access_key},e.resolvedAuth.basicAuth=o)}if(!o)return;let s=await De({baseUrl:Ye(e.tmsBaseUrl),testId:t,body:{commitId:n,fromCommitId:r},auth:We(o)});s.ok||process.stderr.write(`warn: discardLock failed: ${s.reason} (HTTP ${s.httpStatus}): ${s.message}
|
|
93
|
+
`)}async function Da(e){let t=null,r=!1,n=0,o=-1,s=-1,l=0,f=async i=>{if(i&&i.status==="failed")return n>0&&e.decisions[n-1].kind==="replay"&&(t=n-1),null;for(;n<e.decisions.length&&!e.accumulator.shouldRunFlatStep(e.resolved.steps[n]);)n++;if(n>=e.decisions.length)return null;let c=e.decisions[n],v=e.resolved.steps[n],m=n;n++;let y=e.session.nextRunIndex();o=m,s=y,l=Date.now(),e.onSpawnStart?.(y),c.kind==="author"&&e.onAnyAuthorStep(m),await e.pushStepLevelDelta(v.config.variables,v.objective);let I=c.kind==="replay"?e.buildReplayConfig(m):e.buildStepConfigAt(m,y),A=c.kind==="replay"?"md5-match":c.reason,S=v.config??{},R={};for(let[d,F]of Object.entries(S))F!=null&&d!=="variables"&&d!=="assurance"&&(R[d]=F);return{config:I,banner:{stepLabel:`Step ${m+1}/${e.decisions.length}`,objective:Aa(v.objective,100)},mode:c.kind,modeReason:A,perStepOverrides:Object.keys(R).length>0?R:void 0}};return await e.host.runSteps({topBanner:{model:e.topBannerModel,auth:e.topBannerAuth},globalConfig:e.globalConfig,getNextStep:f,onStepEnd:i=>(i.status==="failed"&&o>=0&&e.decisions[o]?.kind==="replay"&&(t=o),e.onSequencerStepEnd(i,o,s,l)),onAllComplete:()=>{},onCancel:()=>{r=!0,e.onCancel()},spawnOpts:e.spawnOpts,priorAttemptRollup:e.priorAttemptRollup,screenshotDispatcher:e.screenshotDispatcher,onReasoning:e.onReasoning,onStepComplete:e.onStepComplete}),{failedAt:t,cancelled:r}}export{Hs as a,us as b,ms as c,Ht as d,wl as e,ks as f,Vr as g,Qa as h,ds as i,cs as j,Mr as k,fs as l,ps as m,Kt as n,ys as o,bs as p,Hr as q,Ss as r,Pl as s,Tl as t,Dl as u,qr as v,qe as w,Ts as x,Ds as y,Ls as z,js as A,Wr as B,Ks as C,Gs as D,zs as E,Ys as F,Ws as G,rn as H,ic as I,Zs as J,on as K,xu as L,Ea as M,ze as N,Ca as O,ti as P};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{b as G}from"./chunk-O3XBIURC.js";import{a as A,b as C}from"./chunk-UJZZDPDY.js";import{a as x}from"./chunk-BZAGVBCX.js";import{a as S}from"./chunk-JUJ4SAGH.js";import{P as v,Q as w,S as U}from"./chunk-
|
|
2
|
+
import{b as G}from"./chunk-O3XBIURC.js";import{a as A,b as C}from"./chunk-UJZZDPDY.js";import{a as x}from"./chunk-BZAGVBCX.js";import{a as S}from"./chunk-JUJ4SAGH.js";import{P as v,Q as w,S as U}from"./chunk-E44OHYDS.js";import{C as E,E as $}from"./chunk-GP7WD4UY.js";import{d,e as m}from"./chunk-AKX4VRRR.js";var k=new Set([d.USECASE,d.SCENARIO,d.AC,d.TEST]);function b(e,t){return!e.superseded.has(t)&&e.trust.get(t)!=="archived"}function h(e,t,n){let s=e.edgesFrom(t).find(o=>o.type===n);return s?e.tipOf(s.dst):null}function O(e,t,n){if(n===d.USECASE)return t;if(n===d.SCENARIO)return h(e,t,m.BELONGS_TO);if(n===d.AC){let s=h(e,t,m.SCOPED_TO);return s?e.nodeLabel.get(s)===d.USECASE?s:h(e,s,m.BELONGS_TO):null}if(n===d.TEST){let s=h(e,t,m.AUTOMATES);return s?h(e,s,m.BELONGS_TO):null}return null}function L(e,t){let n=e.nameOf.get(t);if(n)return n;for(let[s,o]of e.names)if(e.tipOf(o)===t)return s;return t}function F(e,t){return{ucTip:t,display:L(e,t),seamRef:e.nameOf.get(t)??t}}function N(e,t){let n=e.resolve(t);if(!n)return{ok:!1,message:`unknown ref '${t}' \u2014 no test/scenario/ac/use-case by that id or cid`};let s=n.tip,o=e.nodeLabel.get(s);if(!o||!k.has(o))return{ok:!1,message:`'${t}' is a ${o??"missing node"} \u2014 evolve takes a test, scenario, acceptance criterion, or use-case`};let a=O(e,s,o);return!a||e.nodeLabel.get(a)!==d.USECASE?{ok:!1,message:`cannot resolve '${t}' to a parent use-case \u2014 its ${o} chain is broken`}:e.superseded.has(a)?{ok:!1,message:`use-case ${L(e,a)} was removed \u2014 nothing to evolve`}:{ok:!0,target:F(e,a)}}function Z(e,t){return D(e,t)}function D(e,t){let n=[];for(let{cid:o}of e.byLabel(d.SCENARIO)){if(!b(e,o)||!e.edgesFrom(o).some(r=>r.type===m.BELONGS_TO&&e.tipOf(r.dst)===t))continue;let a=e.edgesInto(o).filter(r=>r.type===m.AUTOMATES&&b(e,r.src));if(a.length===0)n.push({scenario:o,test:null});else for(let r of a)n.push({scenario:o,test:r.src})}let s=new Map;for(let{cid:o}of e.byLabel(d.AC)){if(!b(e,o)||O(e,o,d.AC)!==t)continue;let a=e.edgesInto(o).filter(r=>r.type===m.VERIFIES&&b(e,r.src)).map(r=>r.src).sort();s.set(o,a)}return{pairs:n,verifies:s}}function B(e,t){let n=r=>`${r.scenario}\0${r.test??""}`,s=new Set(e.pairs.map(n)),o=new Set(t.pairs.map(n)),a=[];for(let[r,i]of e.verifies){let u=t.verifies.get(r);u&&(i.length===u.length&&i.every((l,g)=>l===u[g])||a.push({ac:r,before:i,after:u}))}return{superseded:e.pairs.filter(r=>!o.has(n(r))),minted:t.pairs.filter(r=>!s.has(n(r))),retained:t.pairs.filter(r=>s.has(n(r))),moves:a}}function _(e,t,n,s,o){let a=i=>t.nameOf.get(i)??i,r=i=>` - ${a(i.scenario)} \xB7 ${i.test?a(i.test):"(no test)"}`;e.out(`evolved: use-case ${n} \u2014 design record ${s.before} \u2192 ${s.after}`),e.out(` superseded ${o.superseded.length} pair(s)`);for(let i of o.superseded)e.out(r(i));e.out(` minted ${o.minted.length} pair(s)`);for(let i of o.minted)e.out(r(i));e.out(` retained ${o.retained.length} pair(s)`);for(let i of o.retained)e.out(r(i));if(o.moves.length===0)e.out(" verifies none moved");else{e.out(" verifies moved:");for(let i of o.moves){let u=l=>l.length>0?l.map(a).join(" + "):"(none)";e.out(` - ${a(i.ac)}: ${u(i.before)} \u2192 ${u(i.after)}`)}}}async function R(e,t,n,s,o,a,r){let i=E(e),u=S(i,t.ucTip);if(!u)return a==="batch"?(s.out(`note: ${t.display} has no design output \u2014 nothing to evolve; run kane-cli design tests --use-case ${t.display} first`),{code:0,outcome:"no-design"}):(v(s,`nothing to evolve \u2014 run kane-cli design tests --use-case ${t.display} first (no design output)`),{code:2,outcome:"no-design"});let l=D(i,t.ucTip),g=[`evolve ${t.display}`,` re-designs use-case ${t.display}`,` affects ${l.pairs.length} pair(s)`,...n.because?[` because ${n.because}`]:[]];if(n.yes)for(let y of g)s.out(y);else{for(let I of g)s.out(I);if(!await s.confirm(`proceed with the re-design of ${t.display}?`))return s.out(a==="batch"?`skipped ${t.display}`:"declined \u2014 nothing evolved"),{code:0,outcome:"declined"}}let p=G(e,i,t.ucTip,n.because),c=await A(r,{verb:"evolve",subject:t.display},()=>o(t.seamRef,{yes:!!n.yes,...n.mode?{mode:n.mode}:{},...n.because?{because:n.because}:{},...p!==void 0?{changeDelta:p.change_delta,priorDesign:p.prior_design}:{}}),y=>({ok:y===0,exitCode:y}));if(c===3)return s.out(`design session for ${t.display} paused \u2014 resume with \`kane-cli design tests --resume\`, then re-run evolve for the diff`),{code:c,outcome:"paused"};if(c!==0)return v(s,`design run for ${t.display} ended with exit code ${c} \u2014 no diff to report`),{code:c,outcome:"failed"};let f=E(e),T=f.tipOf(t.ucTip),P=S(f,T)?.seq;return _(s,f,t.display,{before:u.seq,after:P??"?"},B(l,D(f,T))),{code:0,outcome:"evolved"}}function j(e){let t=new Map,n=0;for(let{cid:o,state:a}of e.staleList()){if(a==="superseded")continue;let r=e.nodeLabel.get(o);if(!r||!k.has(r)||!b(e,o)||!$(e,o))continue;let i=O(e,o,r);!i||e.nodeLabel.get(i)!==d.USECASE||e.superseded.has(i)||(n++,t.has(i)||t.set(i,F(e,i)))}return{targets:[...t.values()].sort((o,a)=>o.display<a.display?-1:o.display>a.display?1:0),staleCount:n}}function M(e,t){for(let{cid:n,state:s}of e.staleList()){if(s==="superseded")continue;let o=e.nodeLabel.get(n);if(!(!o||!k.has(o)||!b(e,n))&&$(e,n)&&O(e,n,o)===t)return!0}return!1}async function q(e,t,n,s={},o=process.cwd()){if(e&&t.fromStale)return v(n,"pass a <ref> OR --from-stale, not both"),2;if(!e&&!t.fromStale)return v(n,"evolve needs a <ref> or --from-stale"),2;let a=w(o,n);if(!a)return 2;let r=s.runDesignForUc??Y,i=s.onChild??(n.isTTY?V(n):void 0);n.out(`evolving ${e??"stale use-cases"}: reading the graph\u2026`);let u=E(a),l,g=null;if(e){let c=N(u,e);if(!c.ok)return v(n,c.message),2;if(!t.because&&S(u,c.target.ucTip)&&!M(u,c.target.ucTip))return v(n,`nothing changed underneath ${e} \u2014 its sources and requirements are current; use --because "<reason>" to re-design anyway`),2;l=[c.target]}else{let{targets:c,staleCount:f}=j(u);if(c.length===0)return n.out("nothing stale \u2014 nothing to evolve"),0;g=`from-stale: ${f} stale node(s) \u2192 ${c.length} use-case(s)`,l=c}if(!t.yes&&!n.isTTY)return v(n,"evolve needs a TTY \u2014 the blast-radius confirm is the point; headless evolution rides `kane-cli maintain reconcile`"),2;if(g&&n.out(g),e){let c=await R(a,l[0],t,n,r,"single",i);return c.outcome==="evolved"&&t.because&&x(a,{ts:new Date().toISOString(),command:"evolve",id:e,verdict:"gap-resolved-evolve",polarity:"preference",by:{kind:"human",id:process.env.USER??"operator"},target:e,reason:t.because}),c.code}let p=0;for(let c of l){let{code:f}=await R(a,c,t,n,r,"batch",i);f!==0&&p===0&&(p=f)}return p}function V(e){let t="",n="evolve";return s=>{s.kind==="start"?(t=s.subject,n=s.verb,e.out(`\u25CF ${C(s.verb).ing} ${s.subject}`)):s.kind==="end"&&e.out(s.ok?`\u25CF ${C(n).ed} ${t} \u2014 ${s.durS}s`:`\u25CF ${n} failed \u2014 ${s.exitCode!=null?`exited ${s.exitCode}`:"error"}${s.fixCmd?` \xB7 ${s.fixCmd}`:""}`)}}var Y=async(e,t)=>{let{designTestsCommand:n}=await import("./bind-LY362KX7.js"),s=()=>n({useCase:e,force:!0,...t.mode?{mode:t.mode}:t.yes?{mode:"override"}:{},...t.because?{because:t.because}:{},...t.changeDelta!==void 0?{changeDelta:t.changeDelta}:{},...t.priorDesign!==void 0?{priorDesign:t.priorDesign}:{}});if(t.mode!=="agent")return s();let o=process.stdout.write;process.stdout.write=((...a)=>!0);try{return await s()}finally{process.stdout.write=o}};async function ee(e,t){return q(e,t,U(),{})}export{N as a,Z as b,R as c,j as d,q as e,Y as f,ee as g};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{d as G,f as q,h as H}from"./chunk-
|
|
2
|
+
import{d as G,f as q,h as H}from"./chunk-BK42G6RI.js";import{a as j,b as z,c as K}from"./chunk-Z2GDSCPS.js";import{d as B,f as O}from"./chunk-ICUTARPB.js";import{a as N}from"./chunk-MMBBQ4OZ.js";import{b as F,c as $,j as R}from"./chunk-GGD7NKPL.js";import{a as L}from"./chunk-TZXXJWHA.js";import{n as T}from"./chunk-RSSOJ3L2.js";import{a as Y,b as C,c as V}from"./chunk-C6JFTSIQ.js";import{h as J}from"./chunk-TAOHYWEO.js";import{e as E}from"./chunk-Z7S3IWUX.js";import{b as M}from"./chunk-F2XTOZTN.js";function X(e){return e.kind==="simulator"?e.id:e.virtualName??e.id}function Z(e,r,t={}){let o={platform:e.platform,udid:e.id,target_kind:e.kind};return r&&(o.app_package=r),t.noReset!==void 0&&(o.no_reset=t.noReset),t.appiumUrl&&(o.appium_url=t.appiumUrl),e.platform==="android"&&t.autoGrantPermissions!==void 0&&(o.auto_grant_permissions=t.autoGrantPermissions),e.platform==="ios"&&t.autoAcceptAlerts!==void 0&&(o.auto_accept_alerts=t.autoAcceptAlerts),o}function Q(e=process.env){let r=e.KANE_APPIUM_URL?.trim();return r||null}import{createHash as De}from"crypto";import{readdir as ke,stat as xe}from"fs/promises";import{basename as g,extname as Ie,join as Ue,relative as Se}from"path";import{createHash as ge}from"crypto";import{createReadStream as fe}from"fs";import{mkdir as me,readFile as he,rename as ve,writeFile as we}from"fs/promises";import{dirname as be,join as ye}from"path";var Pe=60,Te=5;function W(){return{entries:[]}}function ee(){return ye(M,"mobile","app-cache.json")}async function A(e){let r=ge("sha256");for await(let t of fe(e))r.update(t);return r.digest("hex")}function Ce(){return{readFile:e=>he(e,"utf8"),writeFile:async(e,r)=>{await me(be(e),{recursive:!0});let t=`${e}.tmp`;await we(t,r),await ve(t,e)},hashFile:A,now:()=>new Date}}function D(e){if(!e)return;let r=/\/(\d{4})\/(\d{2})\/(\d{2})\//.exec(e);if(!r)return;let[,t,o,a]=r,s=new Date(`${t}-${o}-${a}T00:00:00Z`);return Number.isNaN(s.getTime())?void 0:s.toISOString()}function Ae(e,r){if(!e.storedAt)return!0;let t=new Date(e.storedAt).getTime();return Number.isNaN(t)?!0:(r.getTime()-t)/864e5>=Pe-Te}var u=class{deps;constructor(r={}){this.deps={...Ce(),...r}}async read(){try{let r=JSON.parse(await this.deps.readFile(ee()));if(!r||typeof r!="object")return W();let t=r;return{entries:Array.isArray(t.entries)?t.entries:[]}}catch{return W()}}async write(r){await this.deps.writeFile(ee(),JSON.stringify(r,null,2))}async hashOf(r){return this.deps.hashFile(r)}async lookup(r){return(await this.read()).entries.find(o=>o.sha256===r.sha256&&o.env===r.env&&o.orgId===r.orgId&&o.type===r.type)}async remember(r){let t=await this.read();t.entries=[...t.entries.filter(o=>!(o.sha256===r.sha256&&o.env===r.env&&o.orgId===r.orgId&&o.type===r.type)),r],await this.write(t)}async forget(r){let t=await this.read(),o=t.entries.length;t.entries=t.entries.filter(a=>!(a.sha256===r.sha256&&a.env===r.env&&a.orgId===r.orgId&&a.type===r.type)),t.entries.length!==o&&await this.write(t)}isNearExpiry(r){return Ae(r,this.deps.now())}};var re={emulator:[".apk"],simulator:[".zip"]};function te(e){return e.skipped===!0}function _e(e,r){let t=Ie(e).toLowerCase();return t===".ipa"?`${g(e)} is a device build \u2014 .ipa is not accepted for ${r} runs.`:re[r].includes(t)?null:`${g(e)} cannot be uploaded for a ${r} run \u2014 expected one of ${re[r].join(", ")}.`}async function k(e,r){if(!(await xe(e)).isDirectory())return r.hashOf(e);let o=[],a=async p=>{for(let i of await ke(p,{withFileTypes:!0})){let n=Ue(p,i.name);i.isDirectory()?await a(n):i.isFile()&&o.push(n)}};await a(e),o.sort();let s=De("sha256");for(let p of o)s.update(Se(e,p)),s.update("\0"),s.update(await A(p)),s.update("\0");return s.digest("hex")}async function oe(e){let r=_e(e.path,e.type);if(r)return{skipped:!0,reason:r};let t=e.cache??new u,o=e.client??new J(e.baseUrl,{...e.auth,orgId:e.orgId}),a;try{a=await k(e.path,t)}catch(i){return{skipped:!0,reason:`could not read ${g(e.path)}: ${i.message}`}}let s={sha256:a,env:e.env,orgId:e.orgId,type:e.type},p=await t.lookup(s);if(p){if(await o.liveness(p.appId)!=="gone")return{appId:p.appId,...p.appUrl?{appUrl:p.appUrl}:{},fromCache:!0};e.onProgress?.(`${p.appId} is no longer in the cloud \u2014 uploading again`),await t.forget(s)}try{e.onProgress?.(`uploading ${g(e.path)}\u2026`);let i=await o.upload(e.path,e.type);return await t.remember({sha256:a,env:e.env,orgId:e.orgId,type:e.type,appId:i.appId,...i.appUrl?{appUrl:i.appUrl}:{},...D(i.url)?{storedAt:D(i.url)}:{},sourcePath:e.path}),e.onProgress?.(i.cached?`${g(e.path)} already in the cloud (${i.appId})`:`${g(e.path)} uploaded (${i.appId})`),{appId:i.appId,...i.appUrl?{appUrl:i.appUrl}:{},fromCache:!1}}catch(i){return{skipped:!0,reason:i.message}}}function v(e){return`${e.platform}|${X(e)}`}var m=new Map,ae=new Set;function ie(e){return ae.has(v(e))}function nr(e,r,t){r.state==="stopped"&&(m.has(v(r))||se(e,r,t))}async function ne(e,r,t){let o=m.get(v(r));return o?(t?.(`waiting for ${r.displayName} to finish booting\u2026`),o):se(e,r,t)}function se(e,r,t){let o=v(r),a=e.prepare(r,t);m.set(o,a),r.state==="stopped"&&a.then(()=>ae.add(o),()=>{});let s=()=>{m.get(o)===a&&m.delete(o)};return a.then(s,s),a.catch(()=>{}),a}import{basename as Me}from"path";import{spawnSync as Ee}from"child_process";async function Fe(e,r,t){if(!e.teardownPlan||!t.appPackage&&!t.shutdown)return;let o;try{o=await e.teardownPlan(r,t)}catch{return}o.length!==0&&T(`device:${r.id}`,()=>{G({udid:r.id,displayName:r.displayName});for(let a of o)try{Ee(a.file,a.args,{timeout:3e4,stdio:"ignore"})}catch{}})}var pe={emulator:[".apk"],simulator:[".zip"]};async function $e(e,r,t,o){if(e.kind==="package")return e;if(e.kind==="app_id"){let a=r.cloudUpload;if(!a)throw new Error(`${e.value} is an app id, which needs an account to download it. Log in, or pass a path to a local build instead.`);let s=await V({appId:e.value,baseUrl:a.baseUrl,auth:a.auth,...pe[t]?{accepts:pe[t]}:{},...o?{onProgress:o}:{}}),p=I(s.path);if(!p||p.kind==="app_id")throw new Error(`${s.name} is not a build this CLI can install (from ${e.value}).`);return p}try{let a=new u,s=await k(e.value,a),p=new Y;await p.find(s)||o?.(`copying ${Me(e.value)} into the local app store\u2026`);let n=await p.put({key:s,sourcePath:e.value,source:"local"});return{...e,value:n.path}}catch{return e}}function Re(e){T(`appium:${e}`,()=>{H({deviceClass:e,owner:process.pid})})}var x=class extends Error{constructor(r){super(r),this.name="MobileHostUnsupportedError"}},w=class extends Error{constructor(t,o){super(t);this.doctorText=o;this.name="MobilePreflightError"}};async function Ne(e,r,t){let o=t.cloudUpload,a=await oe({path:e,type:r,env:o.env,orgId:o.orgId,userId:o.userId,auth:o.auth,baseUrl:o.baseUrl,...t.onProgress?{onProgress:t.onProgress}:{}});if(te(a)){t.onProgress?.(`app not uploaded \u2014 ${a.reason}`);return}return a.appId}var Be="app must be a build (.apk for an emulator, .zip of the .app bundle for a simulator) or an app id from your cloud uploads \u2014 a package id names something already installed on one device, so it cannot be uploaded, exported as code, or run anywhere else.",de=/\.(apk|zip)$/i;function I(e){let r=e.trim();if(C(r))return{kind:"app_id",value:r};let t=de.exec(r)?.[1]?.toLowerCase();return t?{kind:t,value:r}:null}function Oe(e){return!!e&&(de.test(e)||C(e.trim()))}function Le(e){return e.filter(r=>r.required&&r.status==="fail")}function je(e,r){return!!r&&E(e,r)}async function Dr(e){let r=L();if(!r.supported)throw new x(r.reason);let t=Q()??e.appiumUrl??e.defaults?.appium_url,o=!!(e.agent||!e.interactive),a=R(),s=!!N();o&&e.platform?.toLowerCase()!=="ios"&&!s&&((await a.status("emulator")).installed||await a.ensure("emulator",{automatic:!0,onProgress:e.onProgress}));let p=await j(e.platform,{appiumUrl:t});if(K(p)){let d=p.sections.flatMap(P=>Le(P.checks)).map(P=>P.label).join(", ");throw new w(`Mobile toolchain not ready (${d}). Run \`kane-cli doctor --target ${e.platform?.toLowerCase()==="ios"?"simulator":e.platform?.toLowerCase()==="android"?"emulator":"<emulator|simulator>"}\` for details.`,z(p))}let i=await O({device:e.device,platform:e.platform,defaultTarget:e.defaults?.default_target,interactive:e.interactive}),n;if(i.ok)n=i.target;else if(i.reason==="needs-picker"&&e.pickTarget){let d=await e.pickTarget(i.candidates);if(!d)throw new Error("Target selection cancelled");n=d}else throw new Error(i.message);let f=B(n.platform);if(!f)throw new Error(`No provider for platform "${n.platform}"`);let l=F(n);if(!l)throw new Error(`No managed dependencies serve ${n.platform} ${n.kind} targets yet.`);if(!(s&&n.platform.toLowerCase()==="android"))try{await a.ensure(l,{automatic:o,onProgress:e.onProgress})}catch(d){throw d instanceof $?new w(d.message,d.message):d}let le=n.state!=="ready"||ie(n);n=await ne(f,n,e.onProgress);let ce=await q(l,{...t?{appiumUrl:t}:{},device:{udid:n.id,displayName:n.displayName},onProgress:e.onProgress});Re(l);let U=je(n,e.defaults?.default_target)?e.defaults?.default_app:void 0,h=e.app??(Oe(U)?U:void 0);if(e.app&&!I(e.app))throw new Error(`${e.app}: ${Be}`);let c=h?I(h):null,S=c?await $e(c,e,l,e.onProgress):null,b=S?await f.ensureApp(n,S,e.onProgress):void 0,y=c?.kind==="app_id"?c.value:e.cloudUpload&&c&&h?await Ne(c.value,l,e):void 0;await Fe(f,n,{shutdown:le,...b?{appPackage:b}:{}});let ue=Z(n,b,{noReset:e.noReset??e.defaults?.no_reset,appiumUrl:ce.url,autoGrantPermissions:e.defaults?.auto_grant_permissions,autoAcceptAlerts:e.defaults?.auto_accept_alerts}),_=y??h;return{device:ue,target:n,provider:f,...y?{appId:y}:{},..._?{appRef:_}:{}}}export{X as a,Z as b,te as c,_e as d,oe as e,nr as f,ne as g,x as h,w as i,Be as j,I as k,Oe as l,Dr as m};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{d as w}from"./chunk-
|
|
2
|
+
import{d as w}from"./chunk-CAOZKSQ3.js";import{b,c as v}from"./chunk-VZ7KXRXB.js";import{b as $}from"./chunk-3N6IAVD5.js";import{b as E}from"./chunk-FQNQVC5O.js";var _=new Set(["delta","state-transition"]),N=/^capture baseline:/i;function R(e){return typeof e=="string"?e:e.text}function j(e){return typeof e=="object"&&e.baseline===!0||N.test(R(e).trim())}function T(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&"derived"in e}function M(e,i){if(e.check_prose)return e.check_prose;let t=i.find(o=>o.ref===e.check.verified_against),n=t?.text?` \u2014 the stated promise: ${t.text}`:"",s=String(e.check.operand??e.check.within??e.check.metric??"");return e.check.kind==="forbidden-presence"?`Confirm '${s}' does NOT appear (forbidden-presence)${n}`:`Confirm ${e.check.kind} check: ${s} (${e.check.operator})${n}`}var F=/^## Step \d+ — assert\s*$/;function ae(e,i){let t=e.split(`
|
|
3
3
|
`),n=!1;for(let s=0;s<t.length;s++){let o=/^(##\s.*?)\s@verifies\s+(.+?)\s*$/.exec(t[s]);if(!o)continue;n=!0;let c=o[2].split(",").map(a=>a.trim()).filter(Boolean).map(a=>{let r=i(a)??(a.startsWith("ac-")?a:null);if(!r)throw new Error(`@verifies ref '${a}' does not resolve to a committed AC`);return r});t[s]=`${o[1]} @verifies ${c.join(", ")}`}return{md:t.join(`
|
|
4
4
|
`),tagged:n}}function de(e,i){if(i.length!==0&&!e.split(`
|
|
5
5
|
`).some(t=>/^##\s/.test(t)&&w.test(t)))throw new Error("generated body has no @verifies binding for its ACs \u2014 the emitter contract is broken")}function ue(e){let i=e.split(`
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as S}from"./chunk-
|
|
2
|
+
import{a as S}from"./chunk-IZ5CTC6M.js";import{y as o}from"./chunk-F2XTOZTN.js";import{a as R}from"./chunk-HCBYKLMW.js";import{a as y,b as c,j as x}from"./chunk-C44QQJR4.js";import{a as w}from"./chunk-6YGTRKDT.js";import{e as b}from"./chunk-UR6MHSHU.js";var k=b(w(),1);var i=b(R(),1);function A(e){let t=e.decisions.filter(l=>l.kind==="replay").length,s=e.decisions.filter(l=>l.kind==="author").length,d=e.outcomes.filter(l=>l.status==="passed").length,f=e.outcomes.filter(l=>l.status==="failed").length,h=e.outcomes.filter(l=>l.status==="skipped").length,a=o.green,u;e.cancelled||e.overallStatus==="interrupted"?(a=o.orange,u="CANCELLED"):e.overallStatus==="failed"?(a=o.red,u="FAILED"):u="PASSED";let r=`${u} \xB7 ${e.durationS}s \xB7 ${e.outcomes.length} steps (${d} passed, ${f} failed, ${h} skipped)`,T=`${t} replay \xB7 ${s} author`,C=e.retryTriggered,_="yes \u2014 healed after a replay miss",n,p=o.dim;if(e.cancelled)n="\u2013 not committed (cancellation)";else if(e.overallStatus==="failed")n="\u2013 not committed (run failed)",p=o.red;else if(!e.shouldCommit)e.isFirstRun?n="\u2013 not committed (first run skipped commit)":e.lockHeld?n="\u2013 not committed":n="\u2013 not committed (readonly fallback / no lock)";else if(e.committed===!1&&!e.uploadResult?.testcaseId)n="\u2013 not committed (commit did not land)",p=o.red;else{let l=e.uploadResult?.testcaseId;n=l?`\u2713 pushed (testcase=${l})`:"\u2713 pushed",p=o.green}let v=e.shouldReplaceLocalOutput?"output dir replaced":e.anyAuthorStepRan?"untouched (cancellation or no replace)":"untouched (replay-only)",m,g=o.dim;return e.shouldUploadArtifacts?e.uploadResult?.success?(m="\u2713 TMS",g=o.green):e.uploadResult?(m=`\u2717 failed${e.uploadResult.error?`: ${e.uploadResult.error}`:""}`,g=o.red):m="\u2013 not run":m="\u2013 skipped (--local or no auth)",{resultLine:{color:a,text:r},breakdown:T,showRetries:C,retriesText:_,commitText:n,commitColor:p,artifactsText:v,uploadText:m,uploadColor:g}}function I(e){let t=e.decisions.filter(r=>r.kind==="replay").length,s=e.decisions.filter(r=>r.kind==="author").length,d=e.outcomes.filter(r=>r.status==="passed").length,f=e.outcomes.filter(r=>r.status==="failed").length,h=e.outcomes.filter(r=>r.status==="skipped").length,a,u=!1;return e.cancelled?a="cancellation":e.overallStatus==="failed"?a="run_failed":e.shouldCommit&&(e.committed===!0||e.uploadResult?.testcaseId)?(a="ok",u=!0):!e.shouldCommit&&!e.lockHeld&&!e.isFirstRun?a="readonly_fallback":a="not_committed",{type:"test_md_summary",overall_status:e.overallStatus,duration_s:e.durationS,steps:{total:e.outcomes.length,passed:d,failed:f,skipped:h,replay_decisions:t,author_decisions:s},adaptive_heal:{triggered:e.retryTriggered},commit:{committed:u,reason:a,...e.uploadResult?.testcaseId?{testcase_id:e.uploadResult.testcaseId}:{}},artifacts:{replaced:e.shouldReplaceLocalOutput},upload:{performed:e.shouldUploadArtifacts,...e.uploadResult?{succeeded:!!e.uploadResult.success}:{}},...e.shareUrl?{share_url:e.shareUrl}:{},cancelled:e.cancelled,...e.imports&&e.imports.length>0?{imports:e.imports}:{}}}function D({data:e}){let t=A(e),s=[{label:"result",value:(0,i.jsx)(c,{color:t.resultLine.color,bold:!0,children:t.resultLine.text})},{label:"breakdown",value:(0,i.jsx)(c,{color:o.dim,children:t.breakdown})}];return t.showRetries&&s.push({label:"adaptive heal",value:(0,i.jsx)(c,{color:o.orange,children:t.retriesText})}),s.push({label:"commit",value:(0,i.jsx)(c,{color:t.commitColor,children:t.commitText})}),s.push({label:"artifacts",value:(0,i.jsx)(c,{color:o.dim,children:t.artifactsText})}),s.push({label:"upload",value:(0,i.jsx)(c,{color:t.uploadColor,children:t.uploadText})}),(0,i.jsx)(S,{title:"Run summary",titleColor:"#ff9500",rows:s})}function O({data:e}){let{exit:t}=x();return(0,k.useEffect)(()=>{let s=setTimeout(()=>t(),50);return()=>clearTimeout(s)},[t]),(0,i.jsx)(y,{flexDirection:"column",children:(0,i.jsx)(D,{data:e})})}export{A as a,I as b,D as c,O as d};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as g}from"./chunk-BPMSNGXQ.js";import{b as f,c as j}from"./chunk-VE3SUJMA.js";import{a as m}from"./chunk-
|
|
2
|
+
import{a as g}from"./chunk-BPMSNGXQ.js";import{b as f,c as j}from"./chunk-VE3SUJMA.js";import{a as m}from"./chunk-BCJNIDS3.js";var _="KaneAI Generated",E="Untitled";async function p(e){let r=e.config.load(),d=new g(m(e.env).tmsBaseUrl,e.tmsCreds.username,e.tmsCreds.access_key),n=e.projectName??_,o=e.folderName??E,t=r.project_id??null,s=r.project_name??null;if(!t){let a=(await d.listProjects()).find(l=>l.name===n);if(a)t=a.project_id,s=a.name,e.log("info","ENSURE_PROJECT_FOUND","Found default project",{project_id:t,name:s});else{let l=await d.createProject(n);t=l.id,s=l.name,e.log("info","ENSURE_PROJECT_CREATED","Created default project",{project_id:t,name:s})}f(e.creds,e.config,e.profile,e.env,{projectId:t,projectName:s})}let c=r.folder_id??null,i=r.folder_name??null,u=!r.project_id;if(!c||u){let a=(await d.listFolders(t)).find(l=>l.name===o);if(a)c=a.id,i=a.name,e.log("info","ENSURE_FOLDER_FOUND","Found default folder",{folder_id:c,name:i});else{let l=await d.createFolder(t,o);c=l.id,i=l.name,e.log("info","ENSURE_FOLDER_CREATED","Created default folder",{folder_id:c,name:i})}f(e.creds,e.config,e.profile,e.env,{folderId:c,folderName:i})}return{projectId:t,projectName:s??n,folderId:c,folderName:i??o}}function A(e,r,d){let n=e.loadProfileConfig(r,d)??{};return{projectId:n.project_id??null,folderId:n.folder_id??null}}function N(e,r){return e.projectId===null||e.folderId===null||r===null?"needs-picker":r.project==="ok"&&r.folder==="ok"?"ok":r.project==="error"&&r.folder==="error"?"ok-tms-degraded":"needs-picker"}var k=(e,r)=>`error: profile "${e}" (${r}) has no project/folder configured AND no TMS credentials were available to auto-configure one.
|
|
3
3
|
|
|
4
4
|
discover IDs:
|
|
5
5
|
kane-cli projects list --search "<keyword>" --limit 10
|