@testmuai/kane-cli 0.8.6 → 0.8.8
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/bin/kane-cli.cjs +5 -1
- package/dist/{ChatSurface-S2P7WMBI.js → ChatSurface-LS3KF7XY.js} +1 -1
- package/dist/{ChromeProfilePicker-7DTJK2QW.js → ChromeProfilePicker-UIJ5ZBLY.js} +1 -1
- package/dist/{CliFeedbackPrompt-Y3OYZX54.js → CliFeedbackPrompt-EIQQBWDY.js} +1 -1
- package/dist/{CliUploadProgress-I3N5WDNJ.js → CliUploadProgress-6U77ZBAX.js} +1 -1
- package/dist/ConfigView-MVFLCF5N.js +2 -0
- package/dist/EvidenceViewOffer-ANVEOXJA.js +2 -0
- package/dist/FolderPicker-HVI6KITN.js +2 -0
- package/dist/{InfoBox-QBXPPMM2.js → InfoBox-57MRRSJI.js} +1 -1
- package/dist/{LinksBox-L24KON4U.js → LinksBox-RKAEQBFS.js} +1 -1
- package/dist/{ProfilesView-H6XCTIXI.js → ProfilesView-RQCQFIXH.js} +1 -1
- package/dist/{ProjectPicker-F6JGF2B3.js → ProjectPicker-5JEEHLY3.js} +1 -1
- package/dist/{SaveSessionPrompt-QGO65DZN.js → SaveSessionPrompt-TQROE5JM.js} +1 -1
- package/dist/SingleShotApp-VJVY3F4H.js +2 -0
- package/dist/{SummaryBox-OZIZQY4B.js → SummaryBox-C4UY6R65.js} +1 -1
- package/dist/TestMdRunView-X3CCNYV5.js +2 -0
- package/dist/{TestrunEvidenceTable-A7WTTKTV.js → TestrunEvidenceTable-LY24PK3T.js} +1 -1
- package/dist/{WhoamiView-EB5AV27X.js → WhoamiView-2FIHHS4G.js} +1 -1
- package/dist/{app-download-SQ4RDY3E.js → app-download-TO672LBR.js} +1 -1
- package/dist/{auth-TW24FZQF.js → auth-EVXJVU72.js} +1 -1
- package/dist/{binary-5LMQJ3CZ.js → binary-Y4DKNDQH.js} +1 -1
- package/dist/{bind-SJ6DOVQ4.js → bind-FVCVYYL3.js} +3 -3
- package/dist/{bootstrap-BTEXO6HX.js → bootstrap-4XBQFKWF.js} +1 -1
- package/dist/bridge-6DCBL3GY.js +2 -0
- package/dist/{changelog-JLSLSA3Y.js → changelog-LAQ2VGK6.js} +1 -1
- package/dist/chat-committer-K3NOTLOU.js +2 -0
- package/dist/chat-controller-YJCNU76T.js +2 -0
- package/dist/chunk-2MQP4SSF.js +20 -0
- package/dist/{chunk-S66MCU2Y.js → chunk-36ZVMJTJ.js} +1 -1
- package/dist/{chunk-USI2WMAK.js → chunk-3GZ4FQ4L.js} +1 -1
- package/dist/{chunk-CLLQQPBZ.js → chunk-4BIJCAR4.js} +1 -1
- package/dist/chunk-4PMZ5FCD.js +2 -0
- package/dist/{chunk-2DCNCH32.js → chunk-54JZ6VEW.js} +1 -1
- package/dist/{chunk-ZGBSGZZM.js → chunk-5G22NOZK.js} +1 -1
- package/dist/{chunk-YEQVJWEF.js → chunk-5LYPSIBC.js} +1 -1
- package/dist/{chunk-RDNKYRKY.js → chunk-5M5BG4MT.js} +1 -1
- package/dist/{chunk-YHTYPTDD.js → chunk-5YCOYFZH.js} +1 -1
- package/dist/chunk-6FCPS2VT.js +4 -0
- package/dist/{chunk-4NSP2NPT.js → chunk-6LYQ4MJH.js} +1 -1
- package/dist/{chunk-XY325HDJ.js → chunk-6T3DWH56.js} +1 -1
- package/dist/{chunk-D4SRHIJ5.js → chunk-6TVNJDSE.js} +1 -1
- package/dist/{chunk-P3RKXL3V.js → chunk-7CXIOJB3.js} +1 -1
- package/dist/{chunk-RZLD7TPG.js → chunk-7RTITBZG.js} +1 -1
- package/dist/{chunk-JCD6FP7A.js → chunk-7UCICMK7.js} +3 -3
- package/dist/{chunk-SS5TOK2J.js → chunk-7UYSTQMI.js} +1 -1
- package/dist/chunk-7YX2HUHY.js +2 -0
- package/dist/chunk-AKX4VRRR.js +2 -0
- package/dist/{chunk-KQ2MYMOS.js → chunk-AO5QH6UU.js} +1 -1
- package/dist/{chunk-YZ45OEH3.js → chunk-AS5UKK27.js} +1 -1
- package/dist/{chunk-JN44V63O.js → chunk-ATIX6CVS.js} +2 -2
- package/dist/{chunk-TDS6LG6T.js → chunk-AZ73FJRK.js} +1 -1
- package/dist/{chunk-ZRKPZLLG.js → chunk-BAKOH2BR.js} +1 -1
- package/dist/{chunk-Z35BUPZT.js → chunk-BRE426DP.js} +1 -1
- package/dist/{chunk-IGJIDN4U.js → chunk-BYOXTXLC.js} +1 -1
- package/dist/{chunk-JFAFKHDX.js → chunk-BZAGVBCX.js} +1 -1
- package/dist/{chunk-FYS5VIOG.js → chunk-CQCV2RJK.js} +2 -2
- package/dist/{chunk-FJYDEWOA.js → chunk-DHPBVHED.js} +1 -1
- package/dist/{chunk-7KORP5FF.js → chunk-EEFZXZTZ.js} +1 -1
- package/dist/{chunk-GFKCTYCA.js → chunk-EV64VI66.js} +1 -1
- package/dist/{chunk-IWM5EZC3.js → chunk-FGRTNRBS.js} +2 -2
- package/dist/{chunk-NT3UETTV.js → chunk-FL6TCYA5.js} +1 -1
- package/dist/{chunk-IMR64OCZ.js → chunk-GX3FPJUG.js} +1 -1
- package/dist/{chunk-FUNKVREV.js → chunk-GZLQ2AR6.js} +1 -1
- package/dist/chunk-H4WIA4IP.js +26 -0
- package/dist/{chunk-ZLSWHCWO.js → chunk-H6YGG3GC.js} +1 -1
- package/dist/chunk-HJOGBE23.js +26 -0
- package/dist/{chunk-DN3E6RT6.js → chunk-HK3FFI7Y.js} +2 -2
- package/dist/{chunk-TYI4MLFJ.js → chunk-HPBI3P6I.js} +3 -3
- package/dist/{chunk-FMUCZWS3.js → chunk-HZDNGNO2.js} +1 -1
- package/dist/chunk-IPEA7ZOF.js +8 -0
- package/dist/{chunk-6KPPGMO2.js → chunk-IVQX3AKL.js} +1 -1
- package/dist/chunk-IWVA37B6.js +5 -0
- package/dist/chunk-JE6OO2Q6.js +8 -0
- package/dist/{chunk-PT7V5WDQ.js → chunk-JPGRUMCS.js} +1 -1
- package/dist/chunk-JQW2QFSX.js +2 -0
- package/dist/{chunk-JZ26R6UL.js → chunk-JUJ4SAGH.js} +1 -1
- package/dist/chunk-K5DL7CZ4.js +2 -0
- package/dist/{chunk-TKYJTXWL.js → chunk-K6JRFRGS.js} +1 -1
- package/dist/chunk-KAZGHWGK.js +5 -0
- package/dist/{chunk-AFPHLUQ5.js → chunk-KGKJU27A.js} +1 -1
- package/dist/{chunk-E5S4BASB.js → chunk-LI5FMAUO.js} +1 -1
- package/dist/{chunk-INK66XQS.js → chunk-LMYE3M75.js} +1 -1
- package/dist/{chunk-OFW3ZVTP.js → chunk-LPH4TERT.js} +1 -1
- package/dist/chunk-N5I2QYFD.js +2 -0
- package/dist/chunk-N7Z7BQYO.js +3 -0
- package/dist/{chunk-EXERQHXV.js → chunk-NAZ36RKI.js} +1 -1
- package/dist/chunk-O4IEPE3T.js +4 -0
- package/dist/{chunk-CLGC7VEO.js → chunk-O5U6EAL3.js} +1 -1
- package/dist/chunk-OGJR5VIG.js +363 -0
- package/dist/{chunk-A44G533S.js → chunk-OO7LFDET.js} +1 -1
- package/dist/chunk-OQAN2WYO.js +26 -0
- package/dist/{chunk-GC5U55MW.js → chunk-P67CGWD6.js} +1 -1
- package/dist/{chunk-C4WTZSX4.js → chunk-PQYBIWZH.js} +1 -1
- package/dist/chunk-PYHWCV2V.js +2 -0
- package/dist/{chunk-AO3PBE2V.js → chunk-Q6743UUQ.js} +1 -1
- package/dist/{chunk-5DBK6QNS.js → chunk-QQ5MHSSY.js} +1 -1
- package/dist/{chunk-DZCG7FFP.js → chunk-QVR2PB6Y.js} +1 -1
- package/dist/{chunk-WMQJBEQP.js → chunk-QXLX6LMJ.js} +1 -1
- package/dist/{chunk-VOBXYDJW.js → chunk-R4PLEH2A.js} +47 -47
- package/dist/{chunk-TQKIE7AX.js → chunk-RHL7KZNC.js} +1 -1
- package/dist/chunk-RSSOJ3L2.js +21 -0
- package/dist/{chunk-VMCSRLRC.js → chunk-S6M36UIV.js} +1 -1
- package/dist/{chunk-SQC4P2Q7.js → chunk-SQWVGI3J.js} +1 -1
- package/dist/{chunk-ATWDQCDA.js → chunk-UDW4ZZAW.js} +7 -7
- package/dist/{chunk-CUM23TLF.js → chunk-UH2ZTX4E.js} +1 -1
- package/dist/{chunk-XJILZ2WN.js → chunk-UPHF2J5E.js} +1 -1
- package/dist/{chunk-SQGBFCFO.js → chunk-UY2ES2Z6.js} +1 -1
- package/dist/{chunk-3LEVCW6R.js → chunk-UYLNH4SH.js} +1 -1
- package/dist/{chunk-OYJBABRV.js → chunk-V5DYLGAM.js} +1 -1
- package/dist/{chunk-7VZCXW74.js → chunk-VCDXUUJQ.js} +1 -1
- package/dist/{chunk-5COGCNED.js → chunk-VQVERWC3.js} +1 -1
- package/dist/chunk-W3Z7AZNT.js +4 -0
- package/dist/{chunk-BN6AHQL7.js → chunk-WALVOFKR.js} +4 -4
- package/dist/{chunk-3UUPP5W3.js → chunk-WDOEMLFZ.js} +1 -1
- package/dist/chunk-WHEWZR2C.js +15 -0
- package/dist/{chunk-VRVFPMCR.js → chunk-WIAZN7G4.js} +1 -1
- package/dist/{chunk-AWD56KGX.js → chunk-WPSQYEBP.js} +2 -2
- package/dist/{chunk-RX5TZZNQ.js → chunk-WRIPTYSN.js} +1 -1
- package/dist/{chunk-GELPKSLC.js → chunk-WYOEOJM2.js} +1 -1
- package/dist/{chunk-B4Q6FMIP.js → chunk-XFTF7OOY.js} +3 -3
- package/dist/{chunk-QISE272H.js → chunk-XJ4TJARR.js} +1 -1
- package/dist/{chunk-KDXQNLVV.js → chunk-XLVH4CIZ.js} +3 -3
- package/dist/{chunk-DUAXZYAD.js → chunk-XMTSHHYQ.js} +3 -3
- package/dist/{chunk-XWKUZJCP.js → chunk-YMLC55J4.js} +1 -1
- package/dist/chunk-Z7S3IWUX.js +2 -0
- package/dist/chunk-ZDAO5D6D.js +16 -0
- package/dist/{chunk-TZFT7R7B.js → chunk-ZHKBSKCB.js} +1 -1
- package/dist/chunk-ZIJLOYXX.js +21 -0
- package/dist/{chunk-4ONGF4NT.js → chunk-ZKRL6HMY.js} +2 -2
- package/dist/{chunk-2R7KL7YG.js → chunk-ZSFOANLG.js} +1 -1
- package/dist/committer-C6UCDYMC.js +2 -0
- package/dist/{config-6TQIMTNB.js → config-5UNFAVY6.js} +1 -1
- package/dist/cover-cmd-5LPHIOSI.js +3 -0
- package/dist/{credentials-ZSNM4BTD.js → credentials-64JYS7AQ.js} +1 -1
- package/dist/{deps-bundle-D2ZC2SPT.js → deps-bundle-5JPHXHQV.js} +1 -1
- package/dist/{deps-resolve-VRBMFUTX.js → deps-resolve-WFZZ22XH.js} +1 -1
- package/dist/descriptor-PWUUNYV7.js +2 -0
- package/dist/design-committer-UPC6NZUF.js +2 -0
- package/dist/device-ref-LAZWPRQN.js +2 -0
- package/dist/dispatch-JLMCXOSK.js +2 -0
- package/dist/doctor-KJMR7NRK.js +2 -0
- package/dist/dossier-Y6TJWFZU.js +3 -0
- package/dist/evidence-OFTY5U4X.js +2 -0
- package/dist/evolve-cmd-LU6LPT4F.js +2 -0
- package/dist/exit-manager-ZLDO54S4.js +2 -0
- package/dist/{explain-UAAQWHYR.js → explain-3HAZY7Q6.js} +1 -1
- package/dist/{explain-cmd-EX24XKD6.js → explain-cmd-RMJPXD4U.js} +1 -1
- package/dist/{explain-cmd-2TKO7GRW.js → explain-cmd-XCRO4AS6.js} +1 -1
- package/dist/{extract-bind-TJ2STXV5.js → extract-bind-YYIOEAYR.js} +3 -3
- package/dist/{extract-cmd-FLOYO6HL.js → extract-cmd-Q7OG6RY6.js} +2 -2
- package/dist/{feeder-C3TOJPKK.js → feeder-IOR3XRNF.js} +1 -1
- package/dist/gaps-cmd-JIUM5YDY.js +3 -0
- package/dist/{gate-54BRAE7N.js → gate-E3BLIUEA.js} +1 -1
- package/dist/{generate-headless-DBT4MKQT.js → generate-headless-NCVM643E.js} +2 -2
- package/dist/index.js +137 -131
- package/dist/ingest-TTUQ7UDK.js +2 -0
- package/dist/ingest-cmd-42VRDSPV.js +2 -0
- package/dist/install-5NMP6ZV4.js +2 -0
- package/dist/{interactive-bind-7UDJY4CF.js → interactive-bind-ZDJS7PCV.js} +4 -4
- package/dist/lifecycle-cmd-KSMETBPP.js +2 -0
- package/dist/list-cmd-V3HJ5K4O.js +3 -0
- package/dist/{list-commands-DA4ZXOPJ.js → list-commands-3IKFZSGB.js} +1 -1
- package/dist/logical-ids-MLXAH45L.js +2 -0
- package/dist/login-flow-UXUQ7GQT.js +2 -0
- package/dist/{maintenance-cmd-6XSVO6FO.js → maintenance-cmd-VFYGKY3X.js} +1 -1
- package/dist/{mobile-prompts-JS7GPVKS.js → mobile-prompts-XPQSRBIW.js} +1 -1
- package/dist/persist-recorded-session-MFQ7JCLJ.js +3 -0
- package/dist/phase-seed-BMOSAA74.js +2 -0
- package/dist/pipeline-2XITQU5W.js +2 -0
- package/dist/prepare-target-CKRWHYXS.js +2 -0
- package/dist/readmodel-TDRFVDVI.js +2 -0
- package/dist/reconcile-cmd-BKIJFVQT.js +2 -0
- package/dist/reconcile-deps-Y5G456WD.js +4 -0
- package/dist/reconcile-engine-WDC2MEOY.js +2 -0
- package/dist/{recording-banner-YMKWR3M3.js → recording-banner-P3RUW62P.js} +1 -1
- package/dist/records-JLS63SDI.js +2 -0
- package/dist/registry-OEY4IXB6.js +2 -0
- package/dist/{require-project-folder-3KS7KTME.js → require-project-folder-ZGQLWZV5.js} +1 -1
- package/dist/resolve-run-intent-DHZD6A4B.js +2 -0
- package/dist/{resolver-V5VP5FLT.js → resolver-W54NOQXY.js} +1 -1
- package/dist/revert-PRR3D4XM.js +2 -0
- package/dist/review-cmd-SAGIKWEW.js +4 -0
- package/dist/run-7TZTUTTU.js +2 -0
- package/dist/run-BGQTRIU4.js +2 -0
- package/dist/{run-test-md-FO2RNNOD.js → run-test-md-WO2UDYPM.js} +2 -2
- package/dist/{sessions-cmd-ZZIZN2VB.js → sessions-cmd-VDQGRBEM.js} +1 -1
- package/dist/{skill-installer-W4TT5MST.js → skill-installer-UTVUPOTD.js} +1 -1
- package/dist/{spawner-ZSYJQGQW.js → spawner-SHCGHLQS.js} +1 -1
- package/dist/{structured-answers-5EY2AZN7.js → structured-answers-YAVW65G4.js} +1 -1
- package/dist/tcg-generate-YDNE643C.js +2 -0
- package/dist/testmd-actions-UCJ4ULSX.js +2 -0
- package/dist/token-refresh-ZNV2OSZC.js +2 -0
- package/dist/{validate-basic-727KRHX6.js → validate-basic-XEPS5I6V.js} +1 -1
- package/dist/verdicts-SOX22V6V.js +2 -0
- package/dist/{version-check-A2JQYRI2.js → version-check-LWDLMWBJ.js} +1 -1
- package/dist/{view-cmd-KPJTP4DI.js → view-cmd-SXXNDZIC.js} +1 -1
- package/dist/walk-session-M3OIWR5K.js +2 -0
- package/dist/with-telemetry-SF5RHYQE.js +2 -0
- package/package.json +11 -14
- package/dist/ConfigView-EOYCKYJS.js +0 -2
- package/dist/EvidenceViewOffer-AQ3KB3EN.js +0 -2
- package/dist/FolderPicker-RCHRYYC4.js +0 -2
- package/dist/SingleShotApp-AY3XFEYT.js +0 -2
- package/dist/TestMdRunView-RPW4MIJA.js +0 -2
- package/dist/bridge-GQJ35GTL.js +0 -2
- package/dist/chat-committer-ZWWCLJFD.js +0 -2
- package/dist/chat-controller-R4THYYPU.js +0 -2
- package/dist/chunk-3Q6WAK6P.js +0 -2
- package/dist/chunk-56PAQAX5.js +0 -19
- package/dist/chunk-B5QGIUJA.js +0 -26
- package/dist/chunk-BRTARADN.js +0 -4
- package/dist/chunk-CZUOGGUK.js +0 -2
- package/dist/chunk-DEZ7CXGM.js +0 -21
- package/dist/chunk-ESC7AOCX.js +0 -2
- package/dist/chunk-KLTKEGDH.js +0 -355
- package/dist/chunk-LN7233E2.js +0 -20
- package/dist/chunk-LQQXPY5B.js +0 -4
- package/dist/chunk-MKSTP2XN.js +0 -26
- package/dist/chunk-Q4V2GK5U.js +0 -2
- package/dist/chunk-QBG7XEGQ.js +0 -15
- package/dist/chunk-QQAAPFIR.js +0 -2
- package/dist/chunk-R5T4RLF5.js +0 -2
- package/dist/chunk-SORVX3KI.js +0 -7
- package/dist/chunk-TH47OOBV.js +0 -4
- package/dist/chunk-TRJUD3XJ.js +0 -5
- package/dist/chunk-V444REBC.js +0 -11
- package/dist/chunk-VAYBKR76.js +0 -4
- package/dist/chunk-WXHQYYD5.js +0 -2
- package/dist/chunk-XQFITNA3.js +0 -2
- package/dist/chunk-ZSXDZI56.js +0 -20
- package/dist/committer-SWEWEYNX.js +0 -2
- package/dist/cover-cmd-7JILZJUK.js +0 -3
- package/dist/descriptor-OEUZZCOK.js +0 -2
- package/dist/design-committer-VYT6NU3T.js +0 -2
- package/dist/dispatch-2PBSJ7YW.js +0 -2
- package/dist/doctor-OWRRDA4Z.js +0 -2
- package/dist/dossier-KTLTGT2X.js +0 -3
- package/dist/evidence-NDAKCCHQ.js +0 -2
- package/dist/evolve-cmd-DIA5EWUT.js +0 -2
- package/dist/exit-manager-3FVBTNYR.js +0 -2
- package/dist/gaps-cmd-3ZX3PZF4.js +0 -3
- package/dist/ingest-JO5NJENZ.js +0 -2
- package/dist/ingest-cmd-T6HM3AHK.js +0 -2
- package/dist/install-NIVU4XVS.js +0 -2
- package/dist/lifecycle-cmd-O2324GN6.js +0 -2
- package/dist/list-cmd-N4KMA34H.js +0 -3
- package/dist/logical-ids-TEBCQJGO.js +0 -2
- package/dist/login-flow-NHBJVDW6.js +0 -2
- package/dist/persist-recorded-session-LE3LGFOS.js +0 -3
- package/dist/phase-seed-DIRETNU6.js +0 -2
- package/dist/pipeline-MTAZDCZR.js +0 -2
- package/dist/prepare-target-YK2DLDWB.js +0 -2
- package/dist/readmodel-XOYGGQ3S.js +0 -2
- package/dist/reconcile-cmd-CYRYVS5B.js +0 -2
- package/dist/reconcile-deps-FYXRAMF2.js +0 -4
- package/dist/reconcile-engine-6AT6EVGS.js +0 -2
- package/dist/records-IOZTZUZV.js +0 -2
- package/dist/registry-V45ZQ6Q5.js +0 -2
- package/dist/resolve-run-intent-W32G6WM6.js +0 -2
- package/dist/revert-NQ7GEVSE.js +0 -2
- package/dist/review-cmd-DQRKQUMG.js +0 -4
- package/dist/run-26IR3CKX.js +0 -2
- package/dist/run-5IYI2TJI.js +0 -2
- package/dist/tcg-generate-ONLV5GXG.js +0 -2
- package/dist/testmd-actions-NPILETCQ.js +0 -2
- package/dist/token-refresh-G2CSTY4B.js +0 -2
- package/dist/types-O23GN2YM.js +0 -2
- package/dist/verdicts-TDJLJJ3F.js +0 -2
- package/dist/walk-session-HB3OOWVR.js +0 -2
- package/dist/with-telemetry-HSD6CXDS.js +0 -2
package/dist/chunk-BRTARADN.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as u,c as f}from"./chunk-EYOCNMUM.js";import{c as _,j as g}from"./chunk-OFW3ZVTP.js";import{readFileSync as c,writeFileSync as m,mkdirSync as b,existsSync as h}from"fs";import{dirname as v}from"path";var s={window_size:{width:1920,height:1080},chrome_profile_path:"",default_url:g,model:"v16-alpha",project_id:null,project_name:null,folder_id:null,folder_name:null,mode:"testing",assertion_mode:"dom",network_ws:!1,network_sse:!1,bug_detection:"off",final_validation:!1,code_export:{enabled:!0,language:"python",skip_validation:!0},generate:{scenario_limit:2,per_scenario_limit:3,memory_enabled:!1},last_seen_version:"",hints_enabled:!0};function w(r){let{mobile:e,...i}=r,t={...i};delete t.target,delete t.device,delete t.app;let n=e??{};n.tui_target&&(t.target=n.tui_target);let o=n.default_target?.id?.trim();o&&(t.device=o),n.default_app&&(t.app=n.default_app);let a={};return n.no_reset!==void 0&&(a.no_reset=n.no_reset),n.appium_url!==void 0&&(a.appium_url=n.appium_url),n.auto_grant_permissions!==void 0&&(a.auto_grant_permissions=n.auto_grant_permissions),n.auto_accept_alerts!==void 0&&(a.auto_accept_alerts=n.auto_accept_alerts),Object.keys(a).length>0&&(t.mobile=a),t}function C(r){let e=r.mobile??{},i=typeof r.target=="string"?r.target:void 0,t=typeof r.device=="string"&&r.device.trim()!==""?r.device.trim():void 0,n=typeof r.app=="string"&&r.app!==""?r.app:void 0,o={},a=i??e.tui_target;if(a&&(o.tui_target=a),t){let d=u(a,void 0);(d.kind==="emulator"||d.kind==="simulator")&&(o.default_target={platform:f(d.kind),kind:d.kind,id:t})}else e.default_target?.id?.trim()&&(o.default_target=e.default_target);let l=n??e.default_app;return l&&(o.default_app=l),e.no_reset!==void 0&&(o.no_reset=e.no_reset),e.appium_url!==void 0&&(o.appium_url=e.appium_url),e.auto_grant_permissions!==void 0&&(o.auto_grant_permissions=e.auto_grant_permissions),e.auto_accept_alerts!==void 0&&(o.auto_accept_alerts=e.auto_accept_alerts),Object.keys(o).length>0?o:void 0}var p=class{constructor(e=_){this.path=e}exists(){return h(this.path)}load(){try{let e=c(this.path,"utf-8"),i=JSON.parse(e),t=C(i),{target:n,device:o,app:a,...l}=i;return{...s,...l,...t?{mobile:t}:{},code_export:{...s.code_export,...i.code_export??{}},generate:{...s.generate,...i.generate??{}}}}catch{return{...s,code_export:{...s.code_export},generate:{...s.generate}}}}write(e){try{b(v(this.path),{recursive:!0}),m(this.path,JSON.stringify(w(e),null,2)+`
|
|
3
|
-
`)}catch(i){let t=i instanceof Error?i.message:String(i);process.stderr.write(`[config] Failed to save config: ${t}
|
|
4
|
-
`)}}set(e,i){let t=this.load();t[e]=i,this.write(t)}save(e){this.write({...this.load(),...e})}getMobile(){return this.load().mobile??{}}setMobile(e){let i={...this.getMobile()};for(let t of Object.keys(e)){let n=e[t];n===void 0?delete i[t]:i[t]=n}this.set("mobile",Object.keys(i).length>0?i:void 0)}writeRaw(e){this.write(e)}};export{p as a};
|
package/dist/chunk-CZUOGGUK.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as R}from"./chunk-AO3PBE2V.js";import{x as i}from"./chunk-OFW3ZVTP.js";import{a as X}from"./chunk-HCBYKLMW.js";import{a,b as l,i as p}from"./chunk-C44QQJR4.js";import{a as G}from"./chunk-6YGTRKDT.js";import{e as P}from"./chunk-UR6MHSHU.js";var x=P(G(),1);var e=P(X(),1),f=5;function K(t,I){if(!I)return t;let c=I.toLowerCase();return t.filter(B=>B.label.toLowerCase().includes(c))}function J(t){let{title:I,items:c,loading:B=!1,loadingText:Y,error:L=null,itemNoun:v="items",onSelect:F,onCancel:E,defaultActiveId:w,onTab:y,extraHint:H}=t,[g,d]=(0,x.useState)(0),[S,u]=(0,x.useState)(0),[s,A]=(0,x.useState)(""),[C,h]=(0,x.useState)(null);(0,x.useEffect)(()=>{if(c.length===0)return;if(t.preserveSelectionById&&C!==null){let o=c.findIndex(n=>n.id===C);if(o>=0){u(Math.floor(o/f)),d(o%f);return}}let r=w?c.findIndex(o=>o.id===w):c.findIndex(o=>o.isActive);r>=0?(u(Math.floor(r/f)),d(r%f),t.preserveSelectionById&&h(c[r].id)):t.preserveSelectionById&&(u(0),d(0),h(c[0]?.id??null))},[c,w,t.preserveSelectionById,C]),(0,x.useEffect)(()=>{if(!t.onSearch)return;let r=setTimeout(()=>t.onSearch(s),t.searchDebounceMs??250);return()=>clearTimeout(r)},[s,t.onSearch,t.searchDebounceMs]);let b=t.onSearch?c:K(c,s),D=S*f,N=Math.min(D+f,b.length),M=Math.ceil(b.length/f),O=N-D,T=b.slice(D,N);return p((r,o)=>{if(L){o.escape&&E();return}if(o.escape){s?(A(""),d(0),u(0)):E();return}if(o.tab&&y){y();return}if(o.upArrow){if(g>0){let n=g-1;d(n),t.preserveSelectionById&&h(T[n]?.id??null)}else if(S>0){let n=S-1,m=f-1;u(n),d(m),t.preserveSelectionById&&h(b[n*f+m]?.id??null)}return}if(o.downArrow){if(g<O-1){let n=g+1;d(n),t.preserveSelectionById&&h(T[n]?.id??null)}else if(S<M-1){let n=S+1,m=0;u(n),d(m),t.preserveSelectionById&&h(b[n*f+m]?.id??null)}return}if(o.return&&T[g]){if(T[g].disabled)return;F(T[g]);return}if(o.backspace||o.delete){A(n=>n.slice(0,-1)),d(0),u(0);return}r&&!o.ctrl&&!o.meta&&(A(n=>n+r),d(0),u(0))},{isActive:!B}),B?(0,e.jsxs)(a,{flexDirection:"column",borderStyle:"round",borderColor:i.orange,paddingX:2,paddingY:1,children:[(0,e.jsx)(l,{color:i.orange,bold:!0,children:I}),(0,e.jsx)(a,{marginTop:1,children:(0,e.jsx)(l,{color:i.secondary,children:Y??`Loading ${v}\u2026`})})]}):L?(0,e.jsxs)(a,{flexDirection:"column",borderStyle:"round",borderColor:i.red,paddingX:2,paddingY:1,children:[(0,e.jsx)(l,{color:i.red,bold:!0,children:I}),(0,e.jsx)(a,{marginTop:1,children:(0,e.jsx)(l,{color:i.red,children:L})}),(0,e.jsx)(R,{bindings:[]})]}):(0,e.jsxs)(a,{flexDirection:"column",borderStyle:"round",borderColor:i.orange,paddingX:2,paddingY:1,children:[(0,e.jsxs)(a,{children:[(0,e.jsx)(l,{color:i.orange,bold:!0,children:I}),(0,e.jsxs)(l,{color:i.dim,children:[" (",b.length,!t.onSearch&&s?`/${c.length}`:""," ",v,t.loadingMore?" \xB7 loading more":"",")"]})]}),(0,e.jsxs)(a,{marginTop:1,children:[(0,e.jsx)(l,{color:i.secondary,children:s?"filter: ":""}),s?(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(l,{children:s}),(0,e.jsx)(l,{inverse:!0,children:" "})]}):(0,e.jsxs)(e.Fragment,{children:[(0,e.jsxs)(l,{color:i.dim,children:["Search ",v,"\u2026"]}),(0,e.jsx)(l,{inverse:!0,children:" "})]})]}),(0,e.jsx)(a,{flexDirection:"column",marginTop:1,children:t.searching?(0,e.jsxs)(l,{color:i.secondary,children:["Searching ",v,"\u2026"]}):b.length===0?(0,e.jsxs)(l,{color:i.dim,children:["No ",v,' match "',s,'"']}):T.map((r,o)=>{let n=o===g,m=n?"\u276F ":" ",$=r.disabled?i.muted:r.isActive?i.green:n?i.orange:void 0;return(0,e.jsxs)(a,{flexDirection:"column",children:[(0,e.jsxs)(l,{color:$,children:[m,r.label,r.isActive&&!r.disabled?" \u25CF selected":""]}),n&&r.disabled&&r.disabledHint&&(0,e.jsxs)(l,{color:i.red,children:[" ",r.disabledHint]})]},r.id)})}),!t.searching&&M>1&&(0,e.jsx)(a,{marginTop:1,children:(0,e.jsxs)(l,{color:i.dim,children:["Page ",S+1,"/",M]})}),t.footer&&(0,e.jsx)(a,{marginTop:1,flexDirection:"column",children:t.footer}),(0,e.jsx)(R,{bindings:[{keys:"\u2191\u2193",label:"navigate"},{keys:"type",label:"to search"},{keys:"\u21B5",label:"select"},...y&&H?[{keys:"tab",label:H}]:[]],escBackLabel:s?"clear":"back to chat"})]})}export{J as a};
|
package/dist/chunk-DEZ7CXGM.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{b as j}from"./chunk-VZ7KXRXB.js";import{c as C}from"./chunk-EYOCNMUM.js";import{dirname as z,basename as U,join as y}from"path";function Z(e){let t=U(e);return t.endsWith("_test.md")?t.slice(0,-8):t.endsWith(".md")?t.slice(0,-3):t}function k(e){return y(z(e),`output-${Z(e)}`)}function Te(e){return y(k(e),"Result.md")}function T(e){return y(k(e),".internal")}function O(e){return y(T(e),"meta.json")}function Ae(e,t,r){return y(k(e),`${t}-${r}-code`)}function Ie(e){return y(k(e),"generated-code")}function Le(e){return k(e)+".staging"}function Q(e){return y(T(e),"steps")}function Pe(e,t,r){return y(Q(e),`${t}-${r}`)}import{existsSync as u,renameSync as S,rmSync as _}from"fs";function Ke(e){let t=`${e}.staging`,r=`${e}.bak`;if(!u(t))throw new Error(`atomicReplaceDir: staging missing: ${t}`);if(process.platform==="win32"){u(e)&&_(e,{recursive:!0,force:!0}),S(t,e);return}u(e)&&(u(r)&&_(r,{recursive:!0,force:!0}),S(e,r)),S(t,e),u(r)&&_(r,{recursive:!0,force:!0})}function Ge(e){let t=`${e}.staging`,r=`${e}.bak`;if(process.platform==="win32"){u(t)&&(u(e)?_(t,{recursive:!0,force:!0}):S(t,e));return}if(u(r)&&!u(e)){S(r,e),u(t)&&_(t,{recursive:!0,force:!0});return}u(r)&&u(e)&&_(r,{recursive:!0,force:!0}),u(t)&&u(e)&&_(t,{recursive:!0,force:!0})}import{readFileSync as Se,existsSync as xe}from"fs";import{basename as N,dirname as Re,isAbsolute as $e,resolve as J}from"path";import{dirname as X,isAbsolute as ee,resolve as te}from"path";var d=class extends Error{constructor(r,o,n){super(`[${o}${n!=null?`:${n}`:""}] ${r}`);this.file=o;this.line=n;this.name="TestMdParseError"}},ne=new Set(["username","access_key","oauth","profile","project_id","folder_id"]),A=new Set(["mode","max_steps","timeout","global_context","local_context","variables","session_context","code_export","code_language","url","target","chrome_profile","cdp_endpoint","ws_endpoint","headless","app","no_reset","os_version","on_lock_conflict","tags","assurance"]),I=new Set(["optional"]),re=new Set(["optional","variables"]),oe=new Set(["target","chrome_profile","cdp_endpoint","ws_endpoint","headless"]),ie=new Set(["app","no_reset","os_version"]),se=new Set(["mode","on_lock_conflict","tags","assurance"]);function L(e,t){let r=t.split(`
|
|
3
|
-
`),{global:o,bodyStartLine:n}=ae(e,r),{title:a,steps:s}=be(e,r,n);return{path:e,title:a,global:o,steps:s}}function ae(e,t){if(t[0]?.trim()!=="---")return{global:{},bodyStartLine:0};let r=-1;for(let c=1;c<t.length;c++)if(t[c].trim()==="---"){r=c;break}if(r===-1)throw new d("frontmatter is missing closing '---'",e,1);let o=t.slice(1,r).join(`
|
|
4
|
-
`),n;try{n=j(o)??{}}catch(c){throw new d(`invalid YAML in frontmatter: ${c.message}`,e,1)}if(V(e,n,"frontmatter",1),n.on_lock_conflict!==void 0){let c=n.on_lock_conflict;if(c!=="readonly"&&c!=="fail"&&c!=="wait")throw new d(`on_lock_conflict must be 'readonly' | 'fail' | 'wait', got: ${JSON.stringify(c)}`,e,1)}if(F(e,n,1),n.assurance!==void 0){let c=n.assurance;if(c===null||typeof c!="object"||Array.isArray(c))throw new d("assurance must be a mapping with sub-keys {id, base}",e,1);let f=c;for(let g of Object.keys(f))if(g!=="id"&&g!=="base")throw new d(`unknown assurance sub-key '${g}' \u2014 the engine block allows only {id, base}`,e,1);if(typeof f.id!="string"||f.id.length===0)throw new d("assurance.id must be a non-empty string (logical id)",e,1);if(f.base!==void 0&&!(typeof f.base=="string"&&/^sha256:[0-9a-f]+$/.test(f.base)))throw new d("assurance.base must be a 'sha256:<hex>' string",e,1)}if(n.tags!==void 0){let c=n.tags,f=Array.isArray(c)?c.map(g=>String(g)).join(","):String(c);n.tags=ce(f,e,1)}if(n.target!==void 0&&(n.target=le(n.target,e,1)),n.app!==void 0&&(n.app=ge(n.app,e,1)),n.no_reset!==void 0&&typeof n.no_reset!="boolean")throw new d(`no_reset must be boolean: got ${typeof n.no_reset}`,e,1);if(n.os_version!==void 0&&typeof n.os_version!="string")if(typeof n.os_version=="number")n.os_version=String(n.os_version);else throw new d(`os_version must be a string: got ${typeof n.os_version}`,e,1);let a=n.target,s=a==="emulator"||a==="simulator";if(s&&n.app===void 0)throw new d(`target: ${String(a)} needs an app \u2014 add \`app: <path-to-build | APPid>\``,e,1);if(!s&&n.app!==void 0)throw new d("app requires a mobile target \u2014 add `target: emulator` or `target: simulator`",e,1);if(!s&&n.no_reset!==void 0)throw new d("no_reset requires a mobile target \u2014 add `target: emulator` or `target: simulator`",e,1);if(!s&&n.os_version!==void 0)throw new d("os_version requires a mobile target \u2014 add `target: emulator` or `target: simulator`",e,1);return{global:n,bodyStartLine:r+1}}function ce(e,t,r){let n=e.trim().replace(/^\[/,"").replace(/\]$/,"").split(",").map(a=>a.trim().toLowerCase());if(n.length===0||n.some(a=>a.length===0))throw new d("tags must be a non-empty list of non-empty strings",t,r);return[...new Set(n)]}var de=new Set(["chrome","cdp","ws","emulator","simulator"]),fe="target must be one of 'chrome' | 'cdp' | 'ws' (web) or 'emulator' | 'simulator' (mobile, with a root `app:` key)";function le(e,t,r){if(typeof e=="string"&&de.has(e))return e;throw e!==null&&typeof e=="object"&&!Array.isArray(e)?new d(`the mapping form of target is no longer accepted \u2014 write flat keys:
|
|
5
|
-
target: emulator | simulator
|
|
6
|
-
app: <path-to-build | APPid>`,t,r):new d(`${fe} \u2014 got: ${JSON.stringify(e)}`,t,r)}function ge(e,t,r){if(typeof e!="string"||e.trim().length===0)throw new d("app must be a build (e.g. ./builds/app-debug.apk) or an app id from your cloud uploads",t,r);let o=e.trim();if(!/\.(apk|zip)$/i.test(o)&&!/^APP\d{6,}$/.test(o))throw new d(`app '${o}' is not a build \u2014 expected a path ending in .apk or .zip, or an app id from your cloud uploads.`,t,r);return ue(o,t)}function ue(e,t){return/^APP[0-9A-Za-z_-]+$/.test(e)||ee(e)?e:te(X(t),e)}function We(e){let t=e.target;if(!(t!=="emulator"&&t!=="simulator"))return{platform:C(t)??"",app:e.app??"",...e.no_reset!==void 0?{no_reset:e.no_reset}:{}}}function P(e){let t=e.target;return t==="chrome"||t==="cdp"||t==="ws"?t:void 0}var pe=/\s@verifies\s+(ac-[\w.:\/-]+(?:\s*,\s*ac-[\w.:\/-]+)*)\s*$/;function me(e,t,r){let o=pe.exec(t);if(o)return{label:t.slice(0,o.index).trim(),verifies:o[1].split(",").map(a=>a.trim())};let n=t.lastIndexOf("@verifies");if(n>0&&/\s/.test(t[n-1])){let a=t.slice(n+9).split(/[\s,]+/).filter(s=>s.length>0);if(a.length===0||a.every(s=>s.startsWith("ac-")))throw new d("malformed @verifies directive \u2014 expected '@verifies ac-<id>[, ac-<id>\u2026]' at the end of the heading",e,r)}return{label:t,verifies:[]}}function be(e,t,r){let o,n=r;for(;n<t.length&&t[n].trim()==="";)n++;let a=n<t.length?/^#\s+(.+?)\s*$/.exec(t[n]):null;a&&(o=a[1],n++);let s=[];for(let f=n;f<t.length;f++)/^##\s/.test(t[f])&&s.push(f);let c=[];for(let f=0;f<s.length;f++){let g=s[f],p=s[f+1]??t.length,h=t[g].replace(/^##\s+/,"").trim(),{label:i,verifies:l}=me(e,h,g+1),m=t.slice(g+1,p),{config:b,body:w,optional:R}=he(e,g+1,m);c.push({index:f+1,heading:i,verifies:l,config:b,body:w,headingLine:g+1,optional:R})}return{title:o,steps:c}}function he(e,t,r){let o=0;for(;o<r.length&&r[o].trim()==="";)o++;let n,a=t;if(o<r.length&&/^```yaml\s*$/.test(r[o])){let l=o;a=t+l,o++;let m=-1;for(;o<r.length;){if(/^```\s*$/.test(r[o])){m=o;break}o++}if(m===-1)throw new d("step-config fenced ```yaml block is not closed",e,a);let b=r.slice(l+1,m).join(`
|
|
7
|
-
`);try{n=j(b)??{}}catch(w){throw new d(`invalid YAML in step config: ${w.message}`,e,a)}o=m+1}let s=we(r.slice(o)),c=s.filter(l=>l.trim()!=="");if(c.length>0&&/^@session\s+/.test(c[0].trim()))throw new d("@session is no longer supported (iteration 3); use @import instead",e,t);let f=/^@import\s+(\S.*)$/,p=s.filter(l=>f.test(l.trim())).length>0;if(p&&c.length!==1)throw new d("step body must be exactly one of prose / @import",e,t);let h=!1,i;if(n){if(V(e,n,p?"step config (ref)":"step config (objective)",a),F(e,n,a),typeof n.optional=="boolean")h=n.optional;else if(n.optional!==void 0)throw new d(`step config 'optional' must be boolean: got ${typeof n.optional}`,e,a);let l={...n};delete l.optional,p&&delete l.variables,!p&&Object.keys(l).length>0&&(i=l)}if(p){let m=f.exec(c[0].trim())[1].trim(),b=n?.variables;return{body:{kind:"import_ref",path:m,...b&&Object.keys(b).length>0?{bindings:b}:{}},optional:h}}return{body:{kind:"objective",text:s.join(`
|
|
8
|
-
`).trim()},config:i,optional:h}}function we(e){let t=0,r=e.length;for(;t<r&&e[t].trim()==="";)t++;for(;r>t&&e[r-1].trim()==="";)r--;return e.slice(t,r)}function F(e,t,r){let o=t.variables;if(o==null)return;if(typeof o!="object"||Array.isArray(o))throw new d("variables must be an object map",e,r);let n={};for(let[a,s]of Object.entries(o))if(typeof s=="string")n[a]={value:s};else if(s&&typeof s=="object"&&!Array.isArray(s)&&typeof s.value=="string")n[a]=s;else throw new d(`variable '${a}' must be a string or { value: ... } object`,e,r);t.variables=n}function V(e,t,r,o){for(let n of Object.keys(t)){if(ne.has(n))throw new d(`auth/identity keys are CLI-only: ${n}`,e,o);if(r==="frontmatter"){if(I.has(n))throw new d(`step-only key in frontmatter: ${n}`,e,o);if(!A.has(n))throw new d(`unknown config key: ${n}`,e,o)}else if(r==="step config (objective)"){if(!A.has(n)&&!I.has(n))throw new d(`unknown config key: ${n}`,e,o);if(oe.has(n))throw new d(`chrome config is global-only: ${n}`,e,o);if(ie.has(n))throw new d(`'${n}' is global-only: the whole run drives one app`,e,o);if(se.has(n))throw new d(`'${n}' is run-level and cannot be set per-step`,e,o)}else if(!re.has(n))throw new d(`step config on @import may only contain 'optional' / 'variables': got ${n}`,e,o)}}import{createHash as K}from"crypto";function x(e){if(e==null)return null;if(Array.isArray(e))return e.map(x);if(typeof e=="object"){let t={};for(let r of Object.keys(e).sort()){let o=e[r];o!==void 0&&(t[r]=x(o))}return t}return e}function ye(e){if(e.body.kind!=="objective")throw new Error("stepMd5: only objective steps have an md5; @import rows do not");let t={...e.config??{},optional:e.optional??!1},r=JSON.stringify(x(t));return K("md5").update(e.body.text).update(`
|
|
9
|
-
`).update(r).digest("hex")}function G(e){let t={};for(let[o,n]of Object.entries(e.bindings??{}))t[o]={value:n.value,...n.secret===!0?{secret:!0}:{},...n.syntax?{syntax:n.syntax}:{}};let r=JSON.stringify(x({bindings:t,optional:e.optional}));return K("md5").update(e.path).update(`
|
|
10
|
-
`).update(r).digest("hex")}function qe(e){return ye({index:e.trace[e.trace.length-1].stepIndex,heading:e.trace[e.trace.length-1].heading,verifies:[],body:{kind:"objective",text:e.objective},config:e.parsedConfig,headingLine:1,optional:e.optional})}import{writeFileSync as _e,mkdirSync as ve,readFileSync as ke}from"fs";import{dirname as Y}from"path";function D(e){try{return JSON.parse(ke(O(e),"utf8"))}catch{return null}}function Xe(e){let t=O(e.sourcePath);try{ve(Y(t),{recursive:!0})}catch(o){return process.stderr.write(`
|
|
11
|
-
\u26A0 Failed to create output directory.
|
|
12
|
-
${o.message}
|
|
13
|
-
Path: ${Y(t)}
|
|
14
|
-
|
|
15
|
-
`),t}let r={commit_id:e.commitId};e.testId!==void 0&&(r.test_id=e.testId),e.testcaseId!==void 0&&(r.testcase_id=e.testcaseId),e.projectId!==void 0&&(r.project_id=e.projectId),e.folderId!==void 0&&(r.folder_id=e.folderId),e.orgId!==void 0&&(r.org_id=e.orgId),e.sessionName!==void 0&&(r.session_name=e.sessionName),e.plan!==void 0&&(r.plan=e.plan);try{_e(t,JSON.stringify(r,null,2)+`
|
|
16
|
-
`,"utf8")}catch(o){process.stderr.write(`
|
|
17
|
-
\u26A0 Failed to write meta.json.
|
|
18
|
-
${o.message}
|
|
19
|
-
Path: ${t}
|
|
20
|
-
|
|
21
|
-
`)}return t}var W=["target","chrome_profile","cdp_endpoint","ws_endpoint","headless"],je=["app","no_reset","os_version"],Oe=["mode","on_lock_conflict","tags","target","chrome_profile","cdp_endpoint","ws_endpoint","headless","app","no_reset","os_version"],v=class extends Error{constructor(t){super(t),this.name="TestMdResolveError"}};function E(e){return N(e).endsWith("_test.md")?"test":"helper"}function st(e){let t=J(e),r=B(t),o=Ee(r.global),n=[],a=[],s=[{file:t,kind:E(t)}],c=[];return H(r,a,n,[],t,{},s,c,{}),n.forEach((g,p)=>g.flatIndex=p+1),{rootPath:t,rootTitle:r.title,rootGlobal:r.global,rootSteps:r.steps,chrome:o,steps:n,unitFiles:s,warnings:c}}function at(e){let t=[];for(let r of e.unitFiles){if(r.kind!=="test")continue;let o=D(r.file);o&&t.push({file:r.file,...o.project_id?{project_id:String(o.project_id)}:{},...o.org_id?{org_id:String(o.org_id)}:{}})}return t}function B(e){if(!xe(e))throw new v(`@import path not found: ${e}`);let t=Se(e,"utf8");return L(e,t)}function H(e,t,r,o,n,a,s,c,f){if(t.includes(e.path)){let i=[...t,e.path].map(l=>N(l)).join(" \u2192 ");throw new v(`cyclic reference: ${i}`)}t.push(e.path);let g=o.length===0,p=e.global.variables??{};for(let i of Object.keys(a))if(Object.hasOwn(p,i))throw new v(`callsite binding '${i}' collides with a declared variable in ${e.path} (frontmatter variables are pinned; parameters are its undeclared names)`);let h=e.global;if(!g){let i={...e.global};for(let l of Oe)i[l]!==void 0&&(c.push(`${e.path}: '${l}' is root-governed on imported units \u2014 ignored`),delete i[l]);i.url!==void 0&&(f.pending=String(i.url),delete i.url),h=i}for(let i of e.steps){let l=i.body.kind!=="objective";if(i.optional&&l&&!g)throw new v(`intermediate-ref 'optional' is not supported in v1: ${e.path}:${i.headingLine}`);if(i.body.kind==="objective"){let $={file:e.path,stepIndex:i.index,heading:i.heading,optional:i.optional??!1},q=Me(h,i.config,a),M={flatIndex:0,objective:i.body.text,sourceFile:e.path,trace:[...o,$],config:q,parsedConfig:i.config,optional:i.optional??!1,verifies:i.verifies,owningFile:e.path,unitKind:E(e.path)};f.pending&&(M.unitEntryUrl=f.pending,f.pending=void 0),r.push(M);continue}let m={file:e.path,stepIndex:i.index,heading:i.heading,optional:i.optional??!1,rowMd5:G({path:i.body.path,bindings:i.body.bindings,optional:i.optional??!1})},b=Re(e.path),w=$e(i.body.path)?i.body.path:J(b,i.body.path),R=B(w);s.some($=>$.file===w)||s.push({file:w,kind:E(w)}),H(R,t,r,[...o,m],n,i.body.bindings??{},s,c,f)}g||(f.pending=void 0),t.pop()}function Ee(e){let t={};for(let r of W){if(r==="target"){let o=P(e);o!==void 0&&(t.target=o);continue}e[r]!==void 0&&(t[r]=e[r])}return t}function Me(e,t,r){let o={};for(let[s,c]of Object.entries(e))W.includes(s)||je.includes(s)||(o[s]=c);let n={...o,...t??{}},a={...r,...e.variables??{},...t?.variables??{}};return Object.keys(a).length>0?n.variables=a:delete n.variables,n}export{Z as a,k as b,Te as c,T as d,O as e,Ae as f,Ie as g,Le as h,Q as i,Pe as j,Ke as k,Ge as l,L as m,We as n,G as o,qe as p,D as q,Xe as r,v as s,st as t,at as u};
|
package/dist/chunk-ESC7AOCX.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{b as V,c as H,d as W,e as re,f as ie}from"./chunk-FJYDEWOA.js";import{a as se}from"./chunk-CLLQQPBZ.js";import{c as ee}from"./chunk-A44G533S.js";import{a as te}from"./chunk-BRTARADN.js";import{a as oe}from"./chunk-SQGBFCFO.js";import{b as Y}from"./chunk-TZFT7R7B.js";import{b as Z}from"./chunk-QISE272H.js";import{a as L}from"./chunk-BPMSNGXQ.js";import{a as T,b as j,d as ne}from"./chunk-VE3SUJMA.js";import{b as J}from"./chunk-TZXXJWHA.js";import{p as b}from"./chunk-56PAQAX5.js";import{b as Q}from"./chunk-XY325HDJ.js";import{a as D}from"./chunk-OYJBABRV.js";import{a as B,e as K}from"./chunk-EYOCNMUM.js";import{a as z}from"./chunk-ZLSWHCWO.js";import{a as q}from"./chunk-HCBYKLMW.js";import{a as c,b as u,i as I,j as G}from"./chunk-C44QQJR4.js";import{a as me}from"./chunk-6YGTRKDT.js";import{e as F}from"./chunk-UR6MHSHU.js";var s=F(me(),1);import{basename as ve}from"path";var o=F(q(),1);function Ne({resultRef:x,mode:g="singleshot",loginCompleteRef:d}){let{exit:m}=G(),A=(0,s.useRef)(new z),E=(0,s.useRef)(new te),v=(0,s.useRef)(new ee),n=A.current,l=E.current,O=v.current,le=V(),[h,f]=(0,s.useState)(g==="login"?"login":"gate"),[M,ae]=(0,s.useState)(null),[xe,R]=(0,s.useState)(null),[Pe,$]=(0,s.useState)(null),[X,ce]=(0,s.useState)(null),[N,_]=(0,s.useState)([]),P=(0,s.useCallback)((e,t,i,r)=>O.log(e,t,i,r),[O]),we=(0,s.useCallback)((e,t)=>{e?T(n,l,e,t):l.save({project_id:null,project_name:null,folder_id:null,folder_name:null})},[n,l]),C=(0,s.useCallback)(()=>{if(g==="login")d&&(d.current=!0),m();else{let e=l.load().mobile,t=B(e?.tui_target,e?.default_target?.kind),i=(t.kind==="unset"||t.kind==="choose-mobile")&&J();f(i?"target":"input")}},[g,m,d,l]),S=(0,s.useCallback)((e,t)=>{let i=T(n,l,e,t);if(g==="login"){f("ensure-project");return}ne(i)?C():i.projectId?f("ensure-folder"):f("ensure-project")},[n,l,C,g]);I((e,t)=>{t.ctrl&&e==="c"&&b(0,"Ctrl+C exit")});let U=(0,s.useRef)(!1);s.default.useEffect(()=>{U.current||(U.current=!0,g!=="login"&&ie(n,P).then(e=>{ae(e),e.status==="authenticated"?S(e.result.profile,e.result.env):e.status==="needs_pick"?f("pick"):(R(e.profile??null),$(e.env??null),f("login"))}).catch(e=>{ce(`Auth check failed: ${e instanceof Error?e.message:String(e)}`)}))},[n,P]);let ue=(0,s.useCallback)(e=>{x.current={objective:e},m()},[x,m]),fe=(0,s.useCallback)(async(e,t)=>{n.setActiveProfile(e),n.setDefaultEnv(t),(await re(n,e,t,P)).status==="authenticated"?S(e,t):(R(e),$(t),f("login"))},[n,P,S]),w=(0,s.useCallback)(()=>{let e=n.getActiveProfile(),t=n.getDefaultEnv();if(!e)return null;let i=D(t),r=n.loadBasicAuth(e,t);return new oe(i.controllerBaseUrl,async()=>n.loadCredentials(e,t)?.access_token??null,r,P)},[n,P]),de=(0,s.useCallback)(async()=>{let e=w();if(!e)return null;let t=e.cached??await e.resolve();if(!t)return null;let i=D(n.getDefaultEnv()),r=new L(i.tmsBaseUrl,t.username,t.access_key);try{let p=(await r.listProjects()).find(k=>k.name==="KaneAI Generated");if(p)return{id:p.project_id,name:p.name};let y=await r.createProject("KaneAI Generated");return{id:y.id,name:y.name}}catch{return null}},[w,n]),ge=(0,s.useCallback)(async e=>{let t=w();if(!t)return null;let i=t.cached??await t.resolve();if(!i)return null;let r=D(n.getDefaultEnv()),a=new L(r.tmsBaseUrl,i.username,i.access_key);try{let y=(await a.listFolders(e)).find(pe=>pe.name==="Untitled");if(y)return{id:y.id,name:y.name};let k=await a.createFolder(e,"Untitled");return{id:k.id,name:k.name}}catch{return null}},[w,n]);if(h==="gate")return(0,o.jsx)(c,{paddingX:1,children:(0,o.jsx)(u,{color:"yellow",children:"Checking authentication..."})});if(X)return(0,o.jsxs)(c,{flexDirection:"column",paddingX:1,children:[(0,o.jsx)(u,{color:"red",children:X}),(0,o.jsx)(u,{color:"gray",children:"Press Ctrl+C to exit."})]});if(h==="pick"&&M?.status==="needs_pick")return(0,o.jsx)(he,{profiles:M.profiles,onSelect:fe});if(h==="login")return(0,o.jsx)(W,{devMode:process.env.KANE_DEV_MODE==="1",profiles:n.listProfiles(),onBasicLogin:async(e,t,i,r)=>{let{validateBasicAuth:a}=await import("./validate-basic-727KRHX6.js");await a(t,i,r),n.saveBasicAuth(e,t,{username:i,access_key:r}),n.setActiveProfile(e),n.setDefaultEnv(t)},onOAuthLogin:async(e,t)=>{let{LoginFlow:i}=await import("./login-flow-NHBJVDW6.js");n.setDefaultEnv(t),n.setActiveProfile(e),await new i(e,t,n).login()},onComplete:(e,t)=>{R(e),$(t),n.setActiveProfile(e),n.setDefaultEnv(t),S(e,t)},onCancel:()=>{b(0,"Login cancelled")}});if(h==="ensure-project"){let e=n.getActiveProfile()??"default",t=n.getDefaultEnv(),i=()=>{if(g==="login"){f("ensure-folder");return}T(n,l,e,t).folderId?C():f("ensure-folder")};return(0,o.jsxs)(c,{flexDirection:"column",children:[(0,o.jsx)(c,{paddingX:1,marginBottom:1,children:(0,o.jsx)(u,{color:"yellow",children:"Project & folder are required to save tests \xB7 Esc to use defaults \xB7 Ctrl+C to exit"})}),(0,o.jsx)(Y,{resolver:w(),currentProjectId:l.load().project_id,env:t,onSelect:(r,a)=>{j(n,l,e,t,{projectId:r,projectName:a}),_(p=>[...p,`\u2713 Project: ${a} (${r})`]),i()},onCancel:async()=>{let r=await de();r&&(j(n,l,e,t,{projectId:r.id,projectName:r.name}),_(a=>[...a,`\u2713 Default project: ${r.name} (${r.id})`]),i())}})]})}if(h==="ensure-folder"){let e=n.getActiveProfile()??"default",t=n.getDefaultEnv(),i=n.loadProfileConfig(e,t);return(0,o.jsxs)(c,{flexDirection:"column",children:[(0,o.jsx)(c,{paddingX:1,marginBottom:1,children:(0,o.jsx)(u,{color:"yellow",children:"Project & folder are required to save tests \xB7 Esc to use defaults \xB7 Ctrl+C to exit"})}),(0,o.jsx)(Z,{resolver:w(),projectId:i?.project_id??"",currentFolderId:l.load().folder_id,env:t,onSelect:(r,a)=>{j(n,l,e,t,{folderId:r,folderName:a}),_(p=>[...p,`\u2713 Folder: ${a} (${r})`]),C()},onCancel:async()=>{if(!i?.project_id)return;let r=await ge(i.project_id);r&&(j(n,l,e,t,{folderId:r.id,folderName:r.name}),_(a=>[...a,`\u2713 Default folder: ${r.name} (${r.id})`]),C())}})]})}if(h==="target"){let e=B(l.load().mobile?.tui_target,l.load().mobile?.default_target?.kind).kind==="choose-mobile";return(0,o.jsx)(c,{paddingX:1,children:(0,o.jsx)(se,{mode:e?"mobile-only":"all",onSelect:t=>{l.setMobile({tui_target:t}),f("input")},onCancel:()=>f("input")})})}if(h==="input"){let e=l.load().mobile,t=B(e?.tui_target,e?.default_target?.kind),i=(()=>{if(t.kind==="emulator"||t.kind==="simulator"){let r=e?.default_target?.id??"(no device)",a=e?.default_app?Q(e.default_app)?e.default_app:ve(e.default_app):"(no app)";return`Config: ${K(t.kind)} \xB7 ${r} \xB7 ${a}`}return"Config: Desktop \xB7 Chrome"})();return(0,o.jsxs)(c,{flexDirection:"column",children:[N.length>0&&(0,o.jsx)(c,{flexDirection:"column",paddingX:1,marginBottom:1,children:N.map((r,a)=>(0,o.jsx)(u,{color:"green",children:r},a))}),(0,o.jsx)(c,{paddingX:1,children:(0,o.jsx)(u,{color:"gray",children:i})}),(0,o.jsx)(H,{onSubmit:ue,onEscape:()=>b(0,"User pressed Escape"),history:le,placeholder:"Type an objective..."})]})}return(0,o.jsx)(o.Fragment,{})}function he({profiles:x,onSelect:g}){let[d,m]=(0,s.useState)(0),[A,E]=(0,s.useState)(!1);return I((v,n)=>{if(!A){if(n.escape){b(0,"Profile picker cancelled");return}if(n.upArrow&&d>0&&m(l=>l-1),n.downArrow&&d<x.length-1&&m(l=>l+1),n.return){E(!0);let l=x[d];g(l.profile,l.env).catch(()=>E(!1))}}}),(0,o.jsxs)(c,{flexDirection:"column",paddingX:1,children:[(0,o.jsx)(u,{color:"#ff9500",bold:!0,children:"Select a profile:"}),(0,o.jsx)(c,{marginTop:1,flexDirection:"column",children:x.map((v,n)=>(0,o.jsxs)(u,{children:[n===d?"\u276F ":" ",(0,o.jsx)(u,{color:n===d?"#ff9500":"white",bold:n===d,children:v.profile}),(0,o.jsxs)(u,{color:"gray",children:[" [",v.env,"]"]})]},`${v.profile}-${v.env}`))}),A&&(0,o.jsx)(c,{marginTop:1,children:(0,o.jsx)(u,{color:"yellow",children:"Validating credentials..."})})]})}export{Ne as a};
|
package/dist/chunk-KLTKEGDH.js
DELETED
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as Ke}from"./chunk-ZKSN2SJ7.js";import{a as ze,b as ue}from"./chunk-3Q6WAK6P.js";import{a as Ue,b as We}from"./chunk-JZ26R6UL.js";import{a as Z,b as Le,e as le,f as de,g as Be,h as He}from"./chunk-ATWDQCDA.js";import{a as Ne,c as je,d as Fe,e as me,f as Ge}from"./chunk-ZGBSGZZM.js";import{a as Ae,b as Ie,c as Oe}from"./chunk-EXERQHXV.js";import{a as Re,b as Ce,c as Te}from"./chunk-BB2W35TW.js";import{a as qe}from"./chunk-L2TV4G56.js";import{c as Pe}from"./chunk-6KPPGMO2.js";import{a as $e,e as Ee}from"./chunk-GFKCTYCA.js";import{a as Me}from"./chunk-IMR64OCZ.js";import{c as Ve}from"./chunk-V444REBC.js";import{b as ye,c as we,d as ve,e as ae,h as oe,i as ce}from"./chunk-ZSXDZI56.js";import{b as ne}from"./chunk-VZ7KXRXB.js";import{a as be,b as re}from"./chunk-IDX3TOPY.js";import{A as U}from"./chunk-TH47OOBV.js";import{f as De}from"./chunk-DUAXZYAD.js";import{a as ke,e as xe,f as Se}from"./chunk-DBIBROYW.js";import{d as z,e as X}from"./chunk-WXHQYYD5.js";import{a as _e}from"./chunk-5EOX4MEY.js";import{mkdirSync as St,appendFileSync as Dt,rmdirSync as dt}from"fs";import{randomBytes as $t}from"crypto";import{dirname as mt,join as he}from"path";function Qe(t,e){let n=[];for(let i of e??[]){let g=t.resolve(i.ref)?.tip??null;g!==i.cid&&n.push({ref:i.ref,pinned:i.cid,now:g})}return n}import{existsSync as ge,readFileSync as pe,readdirSync as pt}from"fs";import{join as te}from"path";var Ye=`
|
|
3
|
-
version: 1
|
|
4
|
-
techniques:
|
|
5
|
-
- id: eqp
|
|
6
|
-
name: "Equivalence partitioning"
|
|
7
|
-
applies_hint: "any constrained input"
|
|
8
|
-
emits: [absolute, forbidden-presence]
|
|
9
|
-
- id: bva
|
|
10
|
-
name: "Boundary value analysis"
|
|
11
|
-
applies_hint: "input has an ordered range or length"
|
|
12
|
-
emits: [absolute, forbidden-presence]
|
|
13
|
-
- id: negative
|
|
14
|
-
name: "Negative / error"
|
|
15
|
-
applies_hint: "any input or action that can fail"
|
|
16
|
-
emits: [forbidden-presence]
|
|
17
|
-
- id: state_flow
|
|
18
|
-
name: "State / flow"
|
|
19
|
-
applies_hint: "the AC sits in a multi-step flow"
|
|
20
|
-
emits: [state-transition]
|
|
21
|
-
- id: crud
|
|
22
|
-
name: "CRUD round-trip"
|
|
23
|
-
applies_hint: "AC touches a persisted resource"
|
|
24
|
-
emits: [delta, presence, forbidden-presence]
|
|
25
|
-
- id: auth
|
|
26
|
-
name: "Auth / permission"
|
|
27
|
-
applies_hint: "AC is behind a gate or role"
|
|
28
|
-
emits: [forbidden-presence, presence]
|
|
29
|
-
- id: api_contract
|
|
30
|
-
name: "API-contract"
|
|
31
|
-
applies_hint: "surface is REST/GraphQL"
|
|
32
|
-
emits: [absolute]
|
|
33
|
-
- id: concurrency
|
|
34
|
-
name: "Concurrency / race"
|
|
35
|
-
applies_hint: "high-risk (money / data-loss) or shared-resource AC"
|
|
36
|
-
emits: [state-transition, forbidden-presence]
|
|
37
|
-
- id: idempotency
|
|
38
|
-
name: "Idempotency / retry"
|
|
39
|
-
applies_hint: "money or write operations"
|
|
40
|
-
emits: [delta]
|
|
41
|
-
- id: i18n
|
|
42
|
-
name: "i18n / l10n"
|
|
43
|
-
applies_hint: "AC renders user text or formats numbers/dates/currency"
|
|
44
|
-
emits: [presence, absolute]
|
|
45
|
-
- id: a11y
|
|
46
|
-
name: "a11y"
|
|
47
|
-
applies_hint: "any rendered surface"
|
|
48
|
-
emits: [presence, absolute]
|
|
49
|
-
- id: responsiveness
|
|
50
|
-
name: "Responsiveness / layout"
|
|
51
|
-
applies_hint: "rendered surface"
|
|
52
|
-
emits: [presence, forbidden-presence]
|
|
53
|
-
- id: empty_state
|
|
54
|
-
name: "Empty / null / zero state"
|
|
55
|
-
applies_hint: "list / search / collection AC"
|
|
56
|
-
emits: [presence]
|
|
57
|
-
- id: overflow_underflow
|
|
58
|
-
name: "Overflow / underflow"
|
|
59
|
-
applies_hint: "numeric or quantity AC (R9: explicit underflow/overflow)"
|
|
60
|
-
emits: [forbidden-presence]
|
|
61
|
-
- id: persistence
|
|
62
|
-
name: "Persistence / refresh"
|
|
63
|
-
applies_hint: "AC asserts durable state"
|
|
64
|
-
emits: [absolute]
|
|
65
|
-
- id: temporal
|
|
66
|
-
name: "Time / timezone / expiry"
|
|
67
|
-
applies_hint: "AC involves dates, TTLs, schedules"
|
|
68
|
-
emits: [state-transition, forbidden-presence]
|
|
69
|
-
- id: currency
|
|
70
|
-
name: "Currency / rounding"
|
|
71
|
-
applies_hint: "money AC"
|
|
72
|
-
emits: [absolute]
|
|
73
|
-
- id: pagination
|
|
74
|
-
name: "Pagination / sort / filter"
|
|
75
|
-
applies_hint: "list / search AC"
|
|
76
|
-
emits: [absolute, presence]
|
|
77
|
-
- id: file_media
|
|
78
|
-
name: "File / media"
|
|
79
|
-
applies_hint: "upload surface"
|
|
80
|
-
emits: [forbidden-presence]
|
|
81
|
-
- id: notification
|
|
82
|
-
name: "Notification / async-effect"
|
|
83
|
-
applies_hint: "AC produces an out-of-band effect (email/SMS/push)"
|
|
84
|
-
emits: [presence, delta]
|
|
85
|
-
`;var Je={"web-form":`
|
|
86
|
-
id: web-form
|
|
87
|
-
name: "Web form"
|
|
88
|
-
version: 1
|
|
89
|
-
applies_when: >
|
|
90
|
-
The AC concerns a data-entry form: input fields, required fields, submit,
|
|
91
|
-
validation messages.
|
|
92
|
-
candidate_checks:
|
|
93
|
-
- id: field-validation
|
|
94
|
-
family: negative
|
|
95
|
-
measurable_example: "Enter 'abc' in a numeric quantity field \u2192 inline error 'must be a number', value not accepted"
|
|
96
|
-
emits: forbidden-presence
|
|
97
|
-
- id: required-fields
|
|
98
|
-
family: negative
|
|
99
|
-
measurable_example: "Submit with a required field empty \u2192 submit blocked, field flagged"
|
|
100
|
-
emits: forbidden-presence
|
|
101
|
-
- id: formats
|
|
102
|
-
family: negative
|
|
103
|
-
measurable_example: "Email without @ rejected; valid accepted"
|
|
104
|
-
emits: forbidden-presence
|
|
105
|
-
- id: empty-state
|
|
106
|
-
family: empty_state
|
|
107
|
-
measurable_example: "First load: no stale values, placeholders shown"
|
|
108
|
-
emits: presence
|
|
109
|
-
- id: error-messages
|
|
110
|
-
family: negative
|
|
111
|
-
measurable_example: "Each error is specific and tied to its field"
|
|
112
|
-
emits: presence
|
|
113
|
-
- id: a11y
|
|
114
|
-
family: a11y
|
|
115
|
-
measurable_example: "Every input has a programmatic label; keyboard-only submit works"
|
|
116
|
-
emits: presence
|
|
117
|
-
- id: responsiveness
|
|
118
|
-
family: responsiveness
|
|
119
|
-
measurable_example: "No field overlap at 1280/768/375 px"
|
|
120
|
-
emits: forbidden-presence
|
|
121
|
-
`,"rest-graphql-api":`
|
|
122
|
-
id: rest-graphql-api
|
|
123
|
-
name: "REST / GraphQL API"
|
|
124
|
-
version: 1
|
|
125
|
-
applies_when: >
|
|
126
|
-
The surface is an HTTP/GraphQL endpoint.
|
|
127
|
-
candidate_checks:
|
|
128
|
-
- id: response-shape
|
|
129
|
-
family: api_contract
|
|
130
|
-
measurable_example: "Body validates against the declared schema"
|
|
131
|
-
emits: absolute
|
|
132
|
-
- id: status-codes
|
|
133
|
-
family: api_contract
|
|
134
|
-
measurable_example: "GET 200, POST 201, missing 404, bad 400, unauth 401"
|
|
135
|
-
emits: absolute
|
|
136
|
-
- id: verbs
|
|
137
|
-
family: idempotency
|
|
138
|
-
measurable_example: "PUT is idempotent, POST is not"
|
|
139
|
-
emits: delta
|
|
140
|
-
- id: bad-payloads
|
|
141
|
-
family: negative
|
|
142
|
-
measurable_example: "Malformed JSON \u2192 400, never 500"
|
|
143
|
-
emits: absolute
|
|
144
|
-
- id: idempotency
|
|
145
|
-
family: idempotency
|
|
146
|
-
measurable_example: "Same POST with idempotency-key twice \u2192 one effect"
|
|
147
|
-
emits: delta
|
|
148
|
-
- id: pagination
|
|
149
|
-
family: pagination
|
|
150
|
-
measurable_example: "Page beyond last \u2192 empty list, not error; cursor stable"
|
|
151
|
-
emits: absolute
|
|
152
|
-
- id: versioning
|
|
153
|
-
family: api_contract
|
|
154
|
-
measurable_example: "v1 contract unchanged after v2 ships"
|
|
155
|
-
emits: absolute
|
|
156
|
-
- id: rate-limits
|
|
157
|
-
family: api_contract
|
|
158
|
-
measurable_example: "Over the limit \u2192 429 with retry-after"
|
|
159
|
-
emits: absolute
|
|
160
|
-
`,"mobile-native":`
|
|
161
|
-
id: mobile-native
|
|
162
|
-
name: "Mobile native"
|
|
163
|
-
version: 2
|
|
164
|
-
applies_when: >
|
|
165
|
-
iOS/Android native surface.
|
|
166
|
-
candidate_checks:
|
|
167
|
-
- id: interruptions
|
|
168
|
-
family: state_flow
|
|
169
|
-
measurable_example: "Incoming call mid-flow \u2192 state preserved on return \u2014 no device control: promises here become gaps, not tests"
|
|
170
|
-
emits: state-transition
|
|
171
|
-
- id: network-transitions
|
|
172
|
-
family: state_flow
|
|
173
|
-
measurable_example: "wifi\u2192cellular\u21924G drop: no data loss, graceful retry \u2014 no connectivity control: promises here become gaps, not tests"
|
|
174
|
-
emits: state-transition
|
|
175
|
-
- id: permissions
|
|
176
|
-
family: negative
|
|
177
|
-
measurable_example: "Deny camera \u2192 feature degrades, no crash \u2014 the OS dialog is tappable UI (exercise Allow/Deny on screen); only programmatic grant/deny or pre-seeded permission state has no control"
|
|
178
|
-
emits: forbidden-presence
|
|
179
|
-
- id: orientation
|
|
180
|
-
family: persistence
|
|
181
|
-
measurable_example: "Rotate mid-form \u2192 input preserved"
|
|
182
|
-
emits: absolute
|
|
183
|
-
- id: deep-links
|
|
184
|
-
family: state_flow
|
|
185
|
-
measurable_example: "Cold-start deep link lands on the right screen with auth \u2014 legal when the test states the exact link target"
|
|
186
|
-
emits: state-transition
|
|
187
|
-
- id: state-persistence
|
|
188
|
-
family: persistence
|
|
189
|
-
measurable_example: "Kill + relaunch \u2192 resume where left off"
|
|
190
|
-
emits: absolute
|
|
191
|
-
- id: localization
|
|
192
|
-
family: i18n
|
|
193
|
-
measurable_example: "Device locale switch reformats and re-translates \u2014 no device control: promises here become gaps, not tests"
|
|
194
|
-
emits: presence
|
|
195
|
-
`,"stateful-flow":`
|
|
196
|
-
id: stateful-flow
|
|
197
|
-
name: "Stateful flow"
|
|
198
|
-
version: 1
|
|
199
|
-
applies_when: >
|
|
200
|
-
Multi-step wizard / checkout / onboarding.
|
|
201
|
-
candidate_checks:
|
|
202
|
-
- id: valid-transitions
|
|
203
|
-
family: state_flow
|
|
204
|
-
measurable_example: "Each step advances only when its precondition is met"
|
|
205
|
-
emits: state-transition
|
|
206
|
-
- id: invalid-transitions
|
|
207
|
-
family: state_flow
|
|
208
|
-
measurable_example: "Can't jump to step 3 with step 2 incomplete"
|
|
209
|
-
emits: forbidden-presence
|
|
210
|
-
- id: back-and-abandon
|
|
211
|
-
family: state_flow
|
|
212
|
-
measurable_example: "Back from step 3, then abandon \u2192 no partial commit"
|
|
213
|
-
emits: forbidden-presence
|
|
214
|
-
- id: refresh-persistence
|
|
215
|
-
family: persistence
|
|
216
|
-
measurable_example: "Reload at step 2 \u2192 still at step 2 with data"
|
|
217
|
-
emits: absolute
|
|
218
|
-
- id: resume
|
|
219
|
-
family: persistence
|
|
220
|
-
measurable_example: "Return later \u2192 resume the saved flow"
|
|
221
|
-
emits: absolute
|
|
222
|
-
- id: double-submission
|
|
223
|
-
family: idempotency
|
|
224
|
-
measurable_example: "Double-click submit \u2192 exactly one submission"
|
|
225
|
-
emits: delta
|
|
226
|
-
`,"data-crud":`
|
|
227
|
-
id: data-crud
|
|
228
|
-
name: "Data CRUD"
|
|
229
|
-
version: 1
|
|
230
|
-
applies_when: >
|
|
231
|
-
A persisted record.
|
|
232
|
-
candidate_checks:
|
|
233
|
-
- id: crud-round-trip
|
|
234
|
-
family: crud
|
|
235
|
-
measurable_example: "Create \u2192 read shows it \u2192 update \u2192 read shows the change \u2192 delete \u2192 read 404"
|
|
236
|
-
emits: state-transition
|
|
237
|
-
- id: retry-safety
|
|
238
|
-
family: idempotency
|
|
239
|
-
measurable_example: "Retried create with same key \u2192 one row"
|
|
240
|
-
emits: delta
|
|
241
|
-
- id: concurrency-lost-update
|
|
242
|
-
family: concurrency
|
|
243
|
-
measurable_example: "Two writers, last must not silently clobber \u2192 conflict surfaced"
|
|
244
|
-
emits: forbidden-presence
|
|
245
|
-
- id: delete-cascade
|
|
246
|
-
family: crud
|
|
247
|
-
measurable_example: "Delete parent \u2192 children handled per rule"
|
|
248
|
-
emits: state-transition
|
|
249
|
-
- id: referential-consistency
|
|
250
|
-
family: crud
|
|
251
|
-
measurable_example: "Can't create a child for a missing parent"
|
|
252
|
-
emits: forbidden-presence
|
|
253
|
-
`,"auth-gated":`
|
|
254
|
-
id: auth-gated
|
|
255
|
-
name: "Auth gated"
|
|
256
|
-
version: 1
|
|
257
|
-
applies_when: >
|
|
258
|
-
Behind login/role.
|
|
259
|
-
candidate_checks:
|
|
260
|
-
- id: login-gate
|
|
261
|
-
family: auth
|
|
262
|
-
measurable_example: "Anonymous \u2192 redirected to login, not the resource"
|
|
263
|
-
emits: forbidden-presence
|
|
264
|
-
- id: role-permission-matrix
|
|
265
|
-
family: auth
|
|
266
|
-
measurable_example: "For each role \xD7 action: allowed/denied as specified"
|
|
267
|
-
emits: absolute
|
|
268
|
-
- id: cross-user-record
|
|
269
|
-
family: auth
|
|
270
|
-
measurable_example: "User A cannot read/edit user B's record by id"
|
|
271
|
-
emits: forbidden-presence
|
|
272
|
-
- id: token-session-expiry
|
|
273
|
-
family: auth
|
|
274
|
-
measurable_example: "Expired token \u2192 401/redirect, no stale access"
|
|
275
|
-
emits: forbidden-presence
|
|
276
|
-
- id: privilege-escalation
|
|
277
|
-
family: auth
|
|
278
|
-
measurable_example: "Non-admin cannot reach an admin action by direct URL/API"
|
|
279
|
-
emits: forbidden-presence
|
|
280
|
-
`,"search-list":`
|
|
281
|
-
id: search-list
|
|
282
|
-
name: "Search / list"
|
|
283
|
-
version: 1
|
|
284
|
-
applies_when: >
|
|
285
|
-
Search results / list views.
|
|
286
|
-
candidate_checks:
|
|
287
|
-
- id: pagination
|
|
288
|
-
family: pagination
|
|
289
|
-
measurable_example: "First/last/empty page correct; total accurate"
|
|
290
|
-
emits: absolute
|
|
291
|
-
- id: sorting
|
|
292
|
-
family: pagination
|
|
293
|
-
measurable_example: "Sort asc/desc actually orders; ties stable"
|
|
294
|
-
emits: absolute
|
|
295
|
-
- id: filtering
|
|
296
|
-
family: pagination
|
|
297
|
-
measurable_example: "Each filter narrows correctly; combined filters AND"
|
|
298
|
-
emits: absolute
|
|
299
|
-
- id: empty-state
|
|
300
|
-
family: empty_state
|
|
301
|
-
measurable_example: "No results \u2192 friendly empty state, not blank/error"
|
|
302
|
-
emits: presence
|
|
303
|
-
- id: invalid-input
|
|
304
|
-
family: negative
|
|
305
|
-
measurable_example: "Garbage query \u2192 no crash, sane result"
|
|
306
|
-
emits: forbidden-presence
|
|
307
|
-
- id: length-limits
|
|
308
|
-
family: bva
|
|
309
|
-
measurable_example: "Max-length query handled"
|
|
310
|
-
emits: absolute
|
|
311
|
-
- id: locale
|
|
312
|
-
family: i18n
|
|
313
|
-
measurable_example: "Locale-correct collation/casing"
|
|
314
|
-
emits: presence
|
|
315
|
-
`};var Xe=`
|
|
316
|
-
version: 2
|
|
317
|
-
principles:
|
|
318
|
-
- "Each step is one complete OBJECTIVE the executing agent achieves autonomously \u2014 state the goal and the path, never low-level actions (the agent emits its own actions)."
|
|
319
|
-
- "One objective (or tightly-related items of one goal) per step; unrelated goals split."
|
|
320
|
-
- "Verbose path: name site or app, page or screen, section, panel, control, state \u2014 'On the search results page for Noida, in the filter panel's Budget section, set min to 50L and max to 1Cr'."
|
|
321
|
-
- "Self-contained: concrete values inline; never 'as defined in the scenario' \u2014 the agent cannot see the graph."
|
|
322
|
-
- "Two surfaces: WEB tests run in the kane-cli browser agent; MOBILE tests run in the kane-cli mobile agent on a local Android emulator / iOS simulator (native app). One surface per test; imports/reuse only same-surface units."
|
|
323
|
-
- "In scope: web-browser behavior, mobile emulator/simulator native-app behavior, and direct API calls. NOT in scope: out-of-band email/SMS, backend state with no web, app-screen, or API surface."
|
|
324
|
-
verification:
|
|
325
|
-
- "Phrase checks against what the test's own surface can observe:"
|
|
326
|
-
- "WEB Visual \u2014 visible text, labels, counts, prices ('verify the price is 29.99', 'the Sold out label is shown')."
|
|
327
|
-
- "WEB Textual/DOM \u2014 element states/attributes ('the Add button is disabled', 'the placeholder of the search box is \u2026')."
|
|
328
|
-
- "WEB URL \u2014 'URL contains /checkout'. Title \u2014 'page title contains \u2026'."
|
|
329
|
-
- "WEB DevTools/Network \u2014 'no API calls returned 5xx', 'the POST /api/login returned 200'. Console \u2014 'no console errors'. Performance \u2014 'LCP under 2500ms'. Cookies/localStorage \u2014 'a cookie named session_id exists'."
|
|
330
|
-
- "MOBILE Visual \u2014 on-screen text, labels, counts, states ('the Upcoming list shows 2 reservations', 'a Booking cancelled toast is shown')."
|
|
331
|
-
- "MOBILE Element \u2014 native accessibility-tree states ('the Pay button is disabled', 'the Remember me switch is on')."
|
|
332
|
-
- "MOBILE Network (environment-dependent) \u2014 the app's own captured traffic ('the POST /api/login returned 200') and direct API calls ('call GET /api/bookings and verify the cancelled booking is absent') need a capture/API-wired run environment; when the promise is observable on-screen, prefer the screen."
|
|
333
|
-
- "MOBILE Lifecycle \u2014 background/foreground, terminate/relaunch (only when the objective closes the app), orientation, deep links with a stated target ('background the app and return; the draft is preserved'). OS permission dialogs are tappable UI \u2014 exercising Allow/Deny on screen is legal."
|
|
334
|
-
- "MOBILE ILLEGAL \u2014 URL, page Title, browser console, page-performance: none exist on a native app. Cookies/localStorage: WebView-only AND write-only \u2014 never a read check. Keyboard-visibility: illegal on Android (default sessions suppress the soft keyboard); iOS renders it as ordinary elements. No control exists \u2192 gap, never a test: incoming call/SMS, posting notifications, wifi/airplane switches, locale/timezone, clipboard reads, on-device DB/file reads (the db-query tool reads a configured backend DB, never the device), geolocation, biometrics, programmatic permission pre-seeding. Platform-conditional: notification-shade observation and tab handling are Android-only \u2014 gap iOS notification promises."
|
|
335
|
-
- "Assertions: 'Assert/Verify/Confirm \u2026'. Extractions: 'Store \u2026 as name' \u2014 vague verbs (read/tell/report) do NOT persist values."
|
|
336
|
-
- "Baselines/deltas are EXTRACTIONS on both surfaces: 'store the result count as baseline_count' BEFORE the action; compare after. Never an abstract 'capture the state'."
|
|
337
|
-
variables:
|
|
338
|
-
- "Credentials and environment values are {{name}} variables; concrete domain values from the source stay literal."
|
|
339
|
-
- "A value no evidence supplies (start URL, test account, seed data) is ASKED for \u2014 actual value or a variable name \u2014 never invented."
|
|
340
|
-
pitfalls:
|
|
341
|
-
- "A WEB test without a starting URL cannot run \u2014 its first step names it."
|
|
342
|
-
- "A MOBILE test's first step BEGINS with its marker, then launches the app ('[mobile: emulator] Launch the <App> app; from its entry screen, \u2026') \u2014 never a URL. App data PERSISTS between runs (no reset): never assume first-install or signed-out state. The minted file needs target:/app: frontmatter attached before it can run on a device."
|
|
343
|
-
- "'Test the checkout flow' has no end state \u2014 state what done looks like."
|
|
344
|
-
- "Do not cram many unrelated operations into one step; do not reference data outside the step."
|
|
345
|
-
`;var ft=["presence","forbidden-presence","count","delta","state-transition","absolute","bound","propagation","latency","graded"];function tt(t,e){for(let n of t)if(!ft.includes(n))throw new Error(`${e}: emits '${n}' is not an oracle kind`)}function Ze(t,e){let n=ne(t);if(!n||!Array.isArray(n.techniques))throw new Error(`${e}: expected { techniques: [...] }`);for(let i of n.techniques){if(!i.id||!i.name||!i.applies_hint||!Array.isArray(i.emits))throw new Error(`${e}: technique '${i?.id??"?"}' missing id/name/applies_hint/emits`);tt(i.emits,`${e}: technique '${i.id}'`)}return n.techniques}function et(t,e){let n=ne(t);if(!n||!n.id||!n.name||!n.applies_when||!Array.isArray(n.candidate_checks))throw new Error(`${e}: profile missing id/name/applies_when/candidate_checks`);for(let i of n.candidate_checks){if(!i.id||!i.family||!i.measurable_example||!i.emits)throw new Error(`${e}: candidate_check '${i?.id??"?"}' missing id/family/measurable_example/emits`);tt([i.emits],`${e}: check '${i.id}'`)}return n}function st(t){let e=new Map(Ze(Ye,"packaged techniques").map(i=>[i.id,i])),n=te(t,"design","techniques.yaml");if(ge(n))for(let i of Ze(pe(n,"utf8"),n))e.set(i.id,i);return[...e.values()]}function it(t){let e=new Map(Object.entries(Je).map(([i,g])=>[i,et(g,`packaged profile '${i}'`)])),n=te(t,"design","profiles");if(ge(n))for(let i of pt(n).filter(g=>g.endsWith(".yaml")||g.endsWith(".yml")).sort()){let g=et(pe(te(n,i),"utf8"),te(n,i));e.set(g.id,g)}return[...e.values()]}function nt(t){let e=te(t,"design","runner-grammar.yaml");return ge(e)?pe(e,"utf8"):Xe}function se(t,e){return!t.superseded.has(e)}function fe(t,e,n){return{cid:e,logical_id:t.nameOf.get(e)??null,content:n}}async function rt(t,e,n,i,g){let r=await Le(t,"search_similar",{text:e,label:n,k:i},g);return r.ok&&Array.isArray(r.result)?r.result:[]}async function at(t,e,n={}){let i=U(t),g=i.resolve(e);if(!g)throw new Error(`assembleDesignContext: unknown use-case '${e}' (run designGate first)`);let r=g.tip,w=i.getNode(r);if(!w||w.label!==z.USECASE)throw new Error(`assembleDesignContext: '${e}' is not a use-case (run designGate first)`);let I=i.derivesInto(r).map(u=>({source_id:u.props.source_id??null,anchor:u.props.anchor??null})),k=[],T=new Set;for(let{cid:u,content:f}of i.byLabel(z.SCENARIO))se(i,u)&&i.edgesFrom(u).some(y=>y.type===X.BELONGS_TO&&y.dst===r)&&(k.push(fe(i,u,f)),T.add(u));let x=[];for(let{cid:u,content:f}of i.byLabel(z.AC)){if(!se(i,u))continue;let y=i.edgesFrom(u).find($=>$.type===X.SCOPED_TO);!y||y.dst!==r&&!T.has(y.dst)||x.push({...fe(i,u,f),scoped_to:y.dst})}let b=Array.isArray(w.content.criteria)?w.content.criteria:[],h=[w.content.title,w.content.description,...b].filter(Boolean).join(`
|
|
346
|
-
`),M=(await rt(i,h,z.SCENARIO,10,n.embedSearch)).filter(u=>!T.has(u.cid)),j=[],S=new Set,P=[],c=[r],N=new Set([r]);for(;c.length>0;){let u=c.shift();for(let f of i.edgesFrom(u)){if(f.type!==X.DEPENDS_ON||i.nodeLabel.get(f.dst)!==z.USECASE)continue;let y=i.tipOf(f.dst);N.has(y)||(N.add(y),P.push(y),c.push(y))}}for(let u of P){let f=`depends_on ${i.nameOf.get(u)??u.slice(0,19)}`;for(let{cid:y}of i.byLabel(z.SCENARIO))if(se(i,y)&&i.edgesFrom(y).some($=>$.type===X.BELONGS_TO&&$.dst===u))for(let $ of i.edgesInto(y)){if($.type!==X.AUTOMATES||!se(i,$.src)||S.has($.src))continue;S.add($.src);let V=String(i.getNode($.src)?.content.title??"");j.push({cid:$.src,logical_id:i.nameOf.get($.src)??null,title:V,via:f})}}for(let u of await rt(i,h,z.TEST,5,n.embedSearch)){let{cid:f,title:y}=u;S.has(f)||(S.add(f),j.push({cid:f,logical_id:i.nameOf.get(f)??null,title:y??"",via:"similar"}))}let v=i.byLabel(z.STYLENOTE).filter(u=>se(i,u.cid)).sort((u,f)=>u.cid<f.cid?-1:1).slice(0,5).map(u=>`${String(u.content.statement)} [${String(u.content.learned_from_kind)}]`);return{usecase:fe(i,r,w.content),cites:I,committed_acs:x,existing:{scenarios:k,reuse_candidates:M},import_candidates:j,style_notes:v,techniques:st(t),profiles:it(t),runner_grammar:nt(t),budget:{...n.max!=null?{max_pairs:n.max}:{},...n.strength!=null?{strength_override:n.strength}:{}},design_of:(()=>{let u=Ue(i,r);return u?{engine:u.engine,seq:u.seq}:null})()}}function ot(t){let e=n=>{if(Array.isArray(n))return n.map(e);if(n!==null&&typeof n=="object"){let i={};for(let g of Object.keys(n).sort())i[g]=e(n[g]);return i}return n};return JSON.stringify(e(t),null,1)}import{basename as _t,dirname as bt,resolve as yt}from"path";var ht=oe,wt=new Set(["narrative","acs","scenarios","tests","exercises","gaps","scoped_to_repoints","judgements","phase"]);function vt(t){let e=/strength=(\d+)\s*(?:—|-)?\s*(.*)/.exec(t??"");return e?{strength:Number(e[1]),reason:e[2]||t||""}:{strength:2,reason:t??""}}function kt(t,e,n=new Set,i=0){return ht(e,ce(t),n,i)}function xt(t,e,n,i){let g=e.scenarios?.find(b=>b.temp_ref===n.automates)??(()=>{let b=t.resolve(n.automates),h=b?t.getNode(b.tip)?.content:void 0;return h?{title:String(h.title??""),intent:String(h.intent??""),technique_notes:String(h.technique_notes??"")}:{}})(),r=[...(e.acs??[]).map(b=>({ref:b.temp_ref,text:b.text})),...n.verifies.filter(b=>!(e.acs??[]).some(h=>h.temp_ref===b)).map(b=>{let h=t.resolve(b);return{ref:b,text:h?String(t.getNode(h.tip)?.content.text??""):""}})],{test_md:w,objectives_yaml:I}=ve({title:n.title,steps:n.steps,check:n.check,check_prose:n.check_prose,reuses:n.reuses},{title:g.title,intent:g.intent},r),k=ae(kt(t,w)),T=n.check,x={technique:g.technique_notes??"",profile_family:e.judgements?.find(b=>b.kind==="profile_family"&&(b.target===n.temp_ref||b.target===n.automates))?.rationale??"unspecified",anchor:T.verified_against,expected_how:e.judgements?.find(b=>b.kind==="expected_how"&&b.target===T.verified_against)?.rationale??`expected_mode: ${T.expected_mode??"inferred"}`,combinatorial:vt(g.technique_notes),surface_state:"absent",deferred_bindings:T.expected_mode==="runtime-derived"?1:0};return i.push({definitionId:k,rationale:x,anchorRef:T.verified_against,tempRef:n.temp_ref}),{temp_ref:n.temp_ref,title:n.title,automates:n.automates,verifies:n.verifies,check:n.check,definitionId:k,test_md_blob:w,objectives_blob:I,...n.reuses?.length?{reuses:n.reuses}:{},...n.surface_required!==void 0?{surface_required:n.surface_required}:{}}}function ct(t){let e=0,n=t.forceScope??null;return{terminalEventType:"design",async onProposalEvent(i){let g=a=>t.steer?(t.steer(`[auto-repair] ${a} \u2014 please re-finalize with this fixed.`),{proposal:null,error:null}):{proposal:null,error:a};if(i==null||typeof i!="object")return g("finalize_design payload is not an object");let r=i,w=Object.keys(r).filter(a=>!wt.has(a));if(w.length>0)return g(`finalize_design carries ungated/unknown section(s): ${w.join(", ")} \u2014 mintable here: acs, scenarios, tests (+gaps)`);let I=new Map;for(let a of r.tests??[]){let p=I.get(a.automates);if(p)return g(`strict 1:1 violated in-payload: ${p} and ${a.temp_ref} both automate ${a.automates}`);I.set(a.automates,a.temp_ref)}let k=U(t.contextDir);t.force&&!t.resuming&&e===0&&n===null&&(n=ze(k,t.ucRef));let T=k.resolve(t.ucRef),x=T?String(k.getNode(T.tip)?.content.risk??"med"):"med",b=[],h=new Set([t.ucRef,T?.cid,T?.tip].filter(Boolean)),M=a=>{if(h.has(a))return!0;let p=k.resolve(a);return p!=null&&(h.has(p.cid)||h.has(p.tip))},j;try{j={...r.acs?.length?{acs:r.acs.map(a=>({temp_ref:a.temp_ref,text:a.text,kind:a.kind,risk:a.risk??x,...a.expected_answer?{expected_answer:a.expected_answer}:{},...a.scoped_to&&!M(a.scoped_to)?{scope:{type:"scenario",ref:a.scoped_to}}:{}}))}:{},...r.scenarios?.length?{scenarios:r.scenarios}:{},...r.tests?.length?{tests:r.tests.map(a=>xt(k,r,a,b))}:{},...r.exercises?.length?{exercises:r.exercises}:{},...r.gaps?.length?{gaps:r.gaps}:{},...r.scoped_to_repoints?.length?{scoped_to_repoints:r.scoped_to_repoints}:{},...r.judgements?.length?{judgements:r.judgements}:{}}}catch(a){return g(a instanceof Error?a.message:String(a))}let S=r.phase??(r.tests?.length?"tests":r.scenarios?.length?"scenarios":r.acs?.length?"acs":"design"),P=(a,p={})=>({contextDir:t.contextDir,graph:a,ucRef:t.ucRef,sections:j,by:t.by,phase:S,...p,...t.templateVersion?{templateVersion:t.templateVersion()}:{},...t.engine?{engine:t.engine}:{},...n?.length?{forceScope:n}:{},...t.because?{reason:t.because}:{},finalizeTestBody:(()=>{let E=new Map((j.tests??[]).map(A=>[A.temp_ref,A])),R=new Map,K=(A,F,O)=>{let G=E.get(A);if(!G?.test_md_blob)return null;let W=R.get(A);if(W!==void 0)return W;if(O.has(A))return G.test_md_blob;O.add(A);let Q=new Map;for(let q of G.reuses??[]){K(q,F,O);let J=F(q);J!==null&&J!==q&&Q.set(q,J)}let Y=G.verifies.map(F).filter(q=>q!==null),H=ye(we(G.test_md_blob,Q),Y);return R.set(A,H),H};return(A,F)=>{if(!A.test_md_blob)return null;let O=K(A.temp_ref,F,new Set)??A.test_md_blob;if(O===A.test_md_blob)return null;let G=W=>{for(let Q of E.keys())if(F(Q)===W){let Y=K(Q,F,new Set);if(Y!==null)return{body:Y,cycleKey:`batch:${W}`,next:G}}return ce(k)(W)};return{test_md_blob:O,definitionId:ae(oe(O,G))}}})()}),c;if(t.protocol){let a=t.generationTicket,p=await Ae(t.protocol,{verb:"design",ucTargets:[{ref:t.ucRef}],newBuCandidates:[],sourcePins:[],readBasis:k.latestHash,...a?{generationTicket:a}:{}},E=>{let R=ue(P(E.graph,{eventIds:E.eventIds("design",1),sid:E.sid,...a&&!t.generationStamped?{generationTicket:a}:{}}));return R.errors!==null?{errors:R.errors}:{result:R,record:R.record}});p.ok&&"result"in p?(c=p.result,a&&!t.generationStamped&&(t.generationStamped=!0,t.generationTicket={...a,expected_prev_gen:a.next_gen})):p.ok?c={record:null,errors:null,minted:{},logicalIds:{},superseded:[],warnings:["commit already applied (recommit)"],finalizedTests:{}}:c={record:null,errors:p.kind==="validation"?p.errors:p.kind==="contended"?[{code:p.err.code,detail:`${t.ucRef} is held by ${p.err.holder?.owner_sid??"another session"}${p.err.holder?.alive?" (live)":" (stale)"} \u2014 try another use-case or wait for it to free`}]:p.kind==="drifted"?p.asks.map(R=>({code:"DRIFTED",detail:R.detail})):[{code:"UNSETTLED",detail:`concurrent activity kept moving the store (${p.attempts} attempts) \u2014 retry when the store is quieter`}],minted:{},logicalIds:{},superseded:[],warnings:[],finalizedTests:{}}}else c=ue(P(k));if(c.errors)return g("design commit failed: "+c.errors.map(a=>`${a.code}: ${a.detail}`).join("; "));let N=c.warnings.filter(a=>a.includes("\u2014 committed anyway; approve"));for(let a of c.warnings)(!N.includes(a)||N.length===1)&&t.note(`warning: ${a}`);N.length>1&&t.note(`warning: ${N.length} test link(s) refer to items still awaiting approval \u2014 saved anyway; review and approve those items in chat or via kane-cli context review`);let v=(a,p)=>a?`${a} ${p}${a>1?"s":""}`:null,u=[v(r.acs?.length,"AC"),v(r.scenarios?.length,"scenario"),v(r.tests?.length,"test"),v(r.gaps?.length,"gap")].filter(Boolean);t.aliases?.(Object.entries(c.minted).map(([a,p])=>({ref:a,cid:p,...c.logicalIds[a]?{id:c.logicalIds[a]}:{}})));{let a=`saved ${u.join(" \xB7 ")||"judgements/wiring"} as drafts`;(t.commitLine??t.note)(a)}let f=U(t.contextDir);t.onCommitted?.(f);for(let a of b){let p=c.logicalIds[a.anchorRef]??c.minted[a.anchorRef];Ke(t.contextDir,c.finalizedTests[a.tempRef]??a.definitionId,{...a.rationale,anchor:p??a.rationale.anchor})}try{let a=Object.values(c.minted).filter(p=>f.getNode(p)?.label==="test");if(a.length>0){let p=bt(yt(t.contextDir)),E=Ve({graph:f,cids:a,cwd:p});E.wrote.length>0&&t.note(`\u2692 wrote ${E.wrote.map(R=>_t(R.path)).join(" \xB7 ")}`);for(let R of E.refused)t.note(`warning: could not create the test file for ${R.id} \u2014 ${R.reason}`)}}catch(a){t.note(`warning: the design was saved, but its test file could not be created (${a instanceof Error?a.message:String(a)})`)}t.event?.({type:"commit",acs:r.acs?.length??0,scenarios:r.scenarios?.length??0,tests:r.tests?.length??0,gaps:r.gaps?.length??0,warnings:c.warnings.length,minted:Object.entries(c.minted).map(([a,p])=>({temp_ref:a,cid:p,...c.logicalIds[a]?{logical_id:c.logicalIds[a]}:{}}))}),e+=1,n!==null&&(n=c.forceScopeRemaining??n,t.onForceScope?.(n));let y=qe({verb:"design",commitN:e,ucRef:t.ucRef,phase:S,committed:Object.entries(c.minted).map(([a,p])=>({temp_ref:a,cid:p,...c.logicalIds[a]?{logical_id:c.logicalIds[a]}:{}})),warnings:c.warnings},f),$=y.event.parity?.missing??[],V=!!r.tests?.length&&$.length===0;return{proposal:c,error:null,receipt:y,...V?{sessionComplete:V}:{}}}}}function lt(t,e){return{type:"run_config",version:1,session_id:e.session_id,mode:e.mode,source:{source_id:`design:${t.usecase.logical_id??e.ucCid.slice(0,19)}`,source_cid:e.ucCid,kind:"design_context",numbered_text:ot({...t,session_mode:e.mode})},existing_use_cases:[],read_basis:e.readBasis,max_free_text_rounds:2,graph_reads:!0,verb:"design",chat:!0,design_budget:t.budget,topology:e.topology}}var ut=Symbol("design-out-tee");function Et(t,e,n,i){return{terminalEventType:"design",async onProposalEvent(g){let r=g??{},w=["acs","scenarios","tests","gaps"].map(I=>r[I]?.length?`${r[I].length} ${I}`:null).filter(Boolean).join(" \xB7 ");return n?.("plan_payload",{payload:r}),t(`plan: finalize_design \u2014 ${w||"wiring/judgements only"} (nothing committed${i?`; full payload: ${Z(i)}`:""})`),e?.({type:"plan",payload:r}),{proposal:r,error:null}}}}async function Es(t,e){let n=U(e.contextDir),i=null,g=null,r=t.useCase;if(t.resume){try{{let m=await Ge(e.contextDir,t.resume,n,{deps:{onWarn:_=>e.out(`note: ${_}`)}});g=m,i=m.handle,m.drift.length>0&&(e.out(`note: sources changed since the pause: ${m.drift.map(_=>_.subject).join(", ")} \u2014 the design continues against the current versions`),e.emit?.({type:"stale_basis",sources:m.drift.map(_=>_.subject)}))}}catch(m){if(m instanceof be||m instanceof me)return e.out(`error: ${m.message}`),e.emit?.({type:"error",message:`error: ${m.message}`}),m instanceof me||m.code==="SESSION_MISSING"||m.code==="SESSION_EXPIRED"?2:1;throw m}let s=i.state,d=Ne(s.verb,"design",t.resume);if(d)return e.out(d.message),e.emit?.({type:"error",message:d.message,code:d.code}),i.release(),2;if(r&&s.use_case&&r!==s.use_case){let m=`session ${t.resume} was designing ${s.use_case}; --use-case ${r} RETARGETS it`;if(!(t.confirmRetarget?await t.confirmRetarget(`${m} \u2014 continue with the new target?`):!1))return e.out(`error: ${m} \u2014 resume without --use-case to continue ${s.use_case}, or start a fresh session on ${r}`),e.emit?.({type:"error",code:"RETARGET_MISMATCH",message:m}),i.release(),2}if(r=r??s.use_case,s.uc_tip&&r){let m=n.resolve(r)?.tip;if(m&&m!==s.uc_tip){let _=`the use-case changed since the pause (${s.uc_tip.slice(0,19)}\u2026 \u2192 ${m.slice(0,19)}\u2026)`;if(!(t.confirmRetarget?await t.confirmRetarget(`${_} \u2014 re-ground and continue against the new version?`):!1))return e.out(`error: ${_} \u2014 resume interactively to re-ground, or abandon this session`),e.emit?.({type:"error",code:"UC_TIP_MOVED",message:_}),i.release(),2;e.emit?.({type:"stale_basis",usecase:r})}}let l=Qe(n,s.target_pins);if(l.length>0){let m=`items this session pinned have changed since it paused: ${l.map(C=>`${C.ref}${C.now===null?" (now gone)":""}`).join(", ")}`;if(!(t.confirmRetarget?await t.confirmRetarget(`${m} \u2014 re-ground and continue?`):!1))return e.out(`error: ${m} \u2014 resume interactively to re-ground, or abandon`),e.emit?.({type:"error",code:"TARGET_PIN_MOVED",message:m}),i.release(),2;i.save({target_pins:(s.target_pins??[]).map(C=>({ref:C.ref,cid:n.resolve(C.ref)?.tip??C.cid}))})}let o=[...new Set([...i.state.held_receipts??[],...g?.view.kane?.held_receipts??[]])];if(o.length>0)if(e.chat?.holdReceipt)for(let m of o)e.chat.holdReceipt(m);else e={...e,initialMessage:[o.join(`
|
|
347
|
-
|
|
348
|
-
`),e.initialMessage].filter(Boolean).join(`
|
|
349
|
-
|
|
350
|
-
`)};if(!r)return e.out(`error: session ${t.resume} predates use-case persistence \u2014 re-supply --use-case <ref>`),e.emit?.({type:"error",message:`error: session ${t.resume} predates use-case persistence \u2014 re-supply --use-case <ref>`}),i.release(),2}let w=t.resume?void 0:t.phase,I=!1;if(w!==void 0){let{checkPhaseEntry:s,phaseEntryCmd:d,phaseLadderFor:l}=await import("./phase-seed-DIRETNU6.js");I=l(e.contextDir,n,r).length>0;let o=s(e.contextDir,n,r,w);if(!o.ok&&o.code==="UNKNOWN_PHASE")return e.out(`error: ${o.message}`),e.emit?.({type:"error",code:"UNKNOWN_PHASE",message:o.message}),i?.release(),2;if(!o.ok&&o.code==="PHASE_ORDER"){let m=t.askPhaseEntry?await t.askPhaseEntry({message:o.message,earliest:o.earliest}):"cancel";if(m==="earliest")e.out(`starting at ${o.earliest} instead (${o.missing.join(", ")} not committed yet)`),w=o.earliest;else if(m==="proceed")e.out(`note: entering at ${w} with ${o.missing.join(", ")} uncommitted \u2014 proceeding on your say-so`),e.emit?.({type:"phase_entry_override",phase:w,missing:o.missing});else{let _=(t.mode??"interactive")==="agent",C=d(r,o.earliest,_);return e.out(`error: ${o.message}`),e.emit?.({type:"error",code:"PHASE_ORDER",message:o.message,next:[{cmd:C,why:`${o.earliest} is the earliest uncommitted phase for ${r}`,title:`Start at ${o.earliest}`}]}),i?.release(),2}}}let k=!!(t.force||i?.state.force),T=!!(t.resume&&i),x=We(n,r,k||T||I);if(!x.ok){let s=(t.mode??"interactive")==="interactive";if(x.wall&&s&&t.askDesignEntry){let{captureForceScope:d}=await import("./design-committer-VYT6NU3T.js"),l=d(n,r).length,o=await t.askDesignEntry({wall:x.wall.kind,message:x.message,display:x.wall.display,impactPairs:l});if(o.pick==="redesign"||o.pick==="proceed"){if(!o.because.trim())return e.out("a redesign needs a reason (--because) \u2014 nothing executed"),i?.release(),2;e.out(o.pick==="redesign"?`redesigning ${x.wall.display} (${l} pair(s) superseded) \u2014 because: ${o.because.trim()}`:`proceeding against the stale design (noted) \u2014 because: ${o.because.trim()}`),t={...t,force:!0,because:t.because??o.because.trim()},k=!0}else return o.pick==="view"?(e.out(`view the existing design: kane-cli context view ${x.wall.display}`),i?.release(),0):o.pick==="refresh"?(e.out(`refresh it first: kane-cli maintain evolve ${x.wall.display}`),i?.release(),0):(e.out("nothing executed \u2014 list use-cases: kane-cli context list"),i?.release(),0)}else{e.out(`design: ${x.message}`);let d=x.wall&&t.mode==="agent"?[{cmd:`kane-cli context view ${x.wall.display}`,why:"view the existing design",title:"View the design"},...x.wall.kind==="designed-stale"?[{cmd:`kane-cli maintain evolve ${x.wall.display}`,why:"the use-case moved since the design \u2014 evolve refreshes it",title:"Evolve the design"}]:[],{cmd:`kane-cli design tests --use-case ${x.wall.display} --force --mode agent`,why:"redesign \u2014 supersedes the live scenario+test pairs",title:"Redesign"}]:void 0;return e.emit?.({type:"gate_refused",message:x.message,...d?{next:d}:{}}),i?.release(),x.code}}if(e.preflightTurn){let s=await e.preflightTurn();if(!s.ok)return e.out(s.message??"error: turn-endpoint preflight failed"),e.emit?.({type:"error",message:s.message??"error: turn-endpoint preflight failed",code:"PREFLIGHT"}),i?.release(),2}let b={contextDir:e.contextDir,resolveAlias:s=>Ie(s,{env:process.env,auth:e.auth}),embed:(s,d)=>Oe(s,d,{env:process.env,auth:e.auth})};e.chat?.setWorking?.("assembling context\u2026");let h=await at(e.contextDir,r,{max:t.max,strength:t.strength,embedSearch:b});if(t.priorDesign!==void 0&&(h.prior_design=t.priorDesign),t.changeDelta!==void 0&&(h.change_delta=t.changeDelta),t.because&&(h.because=t.because),w!==void 0){let{buildPhaseSeed:s}=await import("./phase-seed-DIRETNU6.js"),d=s(e.contextDir,n,r,w);h.prior_design===void 0&&d.priorDesign!==void 0&&(h.prior_design=d.priorDesign),h.entry_phase=w,d.phaseLadder.length>0&&(h.phase_ladder=d.phaseLadder)}let M=e.now?.()??new Date,j=`${M.toISOString().replace(/[-:]/g,"").slice(0,15)}-${$t(2).toString("hex")}`,S=t.mode??"interactive",P=S==="interactive"&&!!e.chat&&!e.nested,c=g?{...g.spawnConfig,mode:S}:lt(h,{session_id:t.resume??`design-${j}`,mode:S,ucCid:h.usecase.cid,readBasis:n.latestHash,topology:Me("design")}),N={current:null};if(c.resume&&"schema"in c.resume){let s=c.resume.binding?.template_version;typeof s=="string"&&(N.current=s)}t.plan?c.chat=!1:c.chat=!0;let v=e.telemetry?.enabled?e.telemetry:void 0,u=v?_e(v.ids.context_instance_id??null,"design",v.ids.session_id):he(e.contextDir,"logs",`design-${j}.log`);St(mt(u),{recursive:!0}),P||e.out(`trace: ${Z(u)}`),e.emit?.({type:"run_start",mode:S,trace:u,use_case:r,...v?{session:v.ids.session_id}:{}});let f=(s,d,l)=>{try{Dt(u,JSON.stringify({ts:new Date().toISOString(),level:s==="error"?"error":"info",run_id:v?.ids.operation_id,...v?{user_session_id:v.ids.session_id}:{},kind:s,session_id:l,data:d})+`
|
|
351
|
-
`)}catch{}v?.wireTrace(s,d,l)};{let s=e.out;if(s[ut]!==!0){let d=l=>{f("transcript",{line:l}),s(l)};d[ut]=!0,e.out=d}}if(t.resume&&i){g||(c.resume={agent_state:i.state.agent_state}),e.out(`resuming design session ${t.resume}`),i.state.assumed.length>0&&e.out(`note: ${i.state.assumed.length} default(s) were assumed while you were away \u2014 kane-cli context sessions show ${t.resume} lists them`);try{let{readRecords:s}=await import("./records-IOZTZUZV.js"),d=s(e.contextDir).records.filter(l=>l.sid===t.resume).map(l=>l.design_phase).filter(l=>l!=null&&typeof l.phase=="string");if(d.length>0){let l=d.map(m=>`${m.phase}${m.completeness==="partial"?" (partial)":""}`).join(" \u2192 "),o=`[kane] durable record for this session (${t.resume}) on ${r}: design phases already COMMITTED \u2014 ${l}. Those finalizes landed; do not re-send them. Continue from the next uncommitted phase, or finish if the design is complete.`;e={...e,initialMessage:[e.initialMessage,o].filter(Boolean).join(`
|
|
352
|
-
|
|
353
|
-
`)}}}catch{}t.message&&(e={...e,initialMessage:[e.initialMessage,t.message].filter(Boolean).join(`
|
|
354
|
-
|
|
355
|
-
`)})}let y=null,$={current:n},V={detach:null},a=()=>{let s=V.detach;V.detach=null,s&&s()},p=(s,d)=>{let l=i;if(!l)return{};let o=s.ask,m=Be({contextDir:s.contextDir,cwd:mt(s.contextDir),handle:l,note:_=>s.chat?s.chat.note(_):s.out(_),graphSlot:d,...s.now?{now:s.now}:{}});if(s.chat?.attachIngest){let _=s.chat;V.detach=_.attachIngest(async C=>{try{l.save({ingest_registry:de(l.state.ingest_registry,C,s.now?.()??new Date)});let L=await m({id:`attach-${l.state.sid}-${(l.state.ingest_registry??[]).length}`,ref:C,purpose:null});return L.ok?(_.deferBatch({source_id:L.result.source_id,cid:L.result.cid}),{ok:!0}):{ok:!1,error:L.error.message}}catch(L){return{ok:!1,error:L instanceof Error?L.message:String(L)}}})}return{ask:async _=>{let C=await o(_);if(Array.isArray(C)){let L=C.filter(B=>{if(B.free_text==null||B.free_text.trim()==="")return!1;let ie=_.find(gt=>gt.id===B.id);return B.selected_index!=null&&ie?.options[B.selected_index]?.input===!0}).map(B=>B.free_text.trim());if(L.length>0){let B=l.state.ingest_registry;for(let ie of L)B=de(B,ie,s.now?.()??new Date);l.save({ingest_registry:B})}}return C},ingest:m}};e.nested||e.chat?.attachOnCommitted?.(s=>{$.current=s});let E="";if(e.chat&&!t.plan&&!e.nested){let s=Pe({contextDir:e.contextDir,graph:U(e.contextDir),sessionStamp:c.session_id,by:e.by??{kind:"human",id:"owner"}});s.errors===null||s.errors[0]?.code==="CONV_SOURCE_EXISTS"?(E=s.sourceId,e.chat.attachConversationSource?.(E),$.current=U(e.contextDir)):e.out(`warning: notes you add in chat can't be saved to the context this session (${s.errors[0]?.detail})`)}let R=U(e.contextDir),K;if(!t.plan){let s=Ce(R,r);if(T&&s!==null&&s.live){let d=R.resolve(r);K={uc_root:Re(R,d.cid),next_gen:s.gen,expected_prev_gen:s.gen}}else{let d=Te(R,r,{...k?{force:!0}:{},because:t.because??(k?"forced redesign (--force)":void 0)});if("error"in d)return e.out(`design: ${d.error.detail}`),e.emit?.({type:"gate_refused",message:d.error.detail,code:d.error.code}),i?.release(),2;K=d}}let A=xe(e.contextDir,c.session_id),F=null,O=()=>{try{F?.release()}catch{}};if(!t.plan)try{F=A.acquire([Se(R,r).key],{hold:"session",verb:"design"})}catch(s){if(s instanceof ke&&s.code==="UC_HELD"){let d=s.holder,l=`design: ${r} is being designed by another session${d?.alive===!1?` \u2014 that session looks stopped; resume it with kane-cli design tests --resume ${d?.owner_sid??"<session>"}`:""} \u2014 pick another use-case (kane-cli design tests) or wait for it to finish`;return e.out(l),e.emit?.({type:"error",code:"UC_HELD",message:l}),i?.release(),2}throw s}let G={contextDir:e.contextDir,rootSid:c.session_id,locks:A,probe:{batchSimilar:async()=>({hits:[],degraded:!1,probeBasis:null}),recheckLocal:()=>({hits:[],uncachedNewNodes:[]})}},W=!t.plan&&S!=="ci",Q=()=>Object.fromEntries((n.resolve(r)?n.edgesInto(n.resolve(r).tip):[]).filter(s=>s.type==="DERIVES"&&typeof s.props.source_id=="string").map(s=>[String(s.props.source_id),n.heads.get(String(s.props.source_id))??null])),Y=!1;W&&!i&&(Y=!0,i=re(e.contextDir,{sid:c.session_id,mode:"agent",created_at:M.toISOString(),expires_at:new Date(M.getTime()+1440*60*1e3).toISOString(),agent_state:{schema:2,items:[],provider_state:""},pending:{questions:[],proposals:[]},read_basis:Q(),assumed:[],corpus_cursor:{remaining:[]},conv_source:E,target_pins:n.resolve(r)?[{ref:r,cid:n.resolve(r).tip}]:[],verb:"design",use_case:r,...n.resolve(r)?.tip?{uc_tip:n.resolve(r).tip}:{},...k?{force:!0}:{},...v?{user_session_id:v.ids.session_id}:{}}));let H;if(W&&i){let{resume:s,...d}=c;Ee(e.contextDir,c.session_id,{schema:$e,kind:"base",sid:c.session_id,verb:"design",mode:S,created_at:M.toISOString(),run_config:d,conv_source:E||i.state.conv_source||"",...r?{use_case:r}:{},...n.resolve(r)?.tip?{uc_tip:n.resolve(r).tip}:{},store_watermark:De(e.contextDir)}),c.checkpoints=!0,t.resume&&f("resume_kind",{kind:g?g.view.pointer===null?"bare-base":g.view.pointer.at==="final"?"pause":"crash":"v1-shim"},c.session_id);let l=g?0:i.state.checkpoint?.seq??0,o=i;H=Fe({contextDir:e.contextDir,handle:o,seqBase:()=>l,peekHeldReceipts:()=>e.chat?.peekHeldReceipts?.()??[],readBasis:()=>Q(),corpusCursor:()=>({remaining:[]}),onSoftCap:_=>e.out(_),onStat:_=>f("ckpt_stat",_,c.session_id),...e.now?{now:e.now}:{}});let m=H;H={...m,persist:_=>{let C=_.binding?.template_version;return typeof C=="string"&&C&&(N.current=C),m.persist(_)}}}let q=()=>{if(!i)return;let s=i.state.checkpoint;if(s){let d=S!=="interactive"?` --mode ${S}`:"";e.out(`session ${i.state.sid} kept its last checkpoint (seq ${s.seq}, ${s.ts}) \u2014 resume with: kane-cli design tests --resume ${i.state.sid}${d}`),i.release()}else if(Y){try{i.complete()}catch{i.release()}try{dt(he(e.contextDir,"sessions"))}catch{}}else i.release();i=null},J=t.plan?Et(e.out,e.emit,f,u):ct({templateVersion:()=>N.current,contextDir:e.contextDir,ucRef:r,by:{kind:"ai",id:"design-agent"},force:k,engine:"design@1",note:s=>e.chat?e.chat.note(s):e.out(s),commitLine:s=>e.chat?e.chat.ledger({kind:"commit",ok:!0,line:s}):e.out(s),steer:e.chat?s=>e.chat.submit(s):void 0,event:e.emit,resuming:T,...i?.state.force_scope?.length?{forceScope:i.state.force_scope}:{},onForceScope:s=>{y=s},...t.because?{because:t.because}:{},aliases:e.chat?s=>e.chat.registerAliases?.(s):void 0,onCommitted:s=>{$.current=s},protocol:G,...K?{generationTicket:K}:{},...T?{generationStamped:!0}:{}});e.chat||(f("design_budget",{max_pairs:h.budget.max_pairs??null,strength:h.budget.strength_override??null}),e.out(`designing: ${h.usecase.logical_id??r}`)),e.chat?.setWorking?.(`designing ${h.usecase.logical_id??r}\u2026`);let D;try{D=await le(c,{...e,graphSlot:$,...p(e,$),...H?{checkpoint:H}:{}},new Map,n,f,J)}catch(s){throw f("error",{message:s instanceof Error?s.message:String(s),stack:s instanceof Error?s.stack:void 0},c.session_id),q(),s}finally{e.chat?.setWorking?.(null),a()}if(D.errorCode==="binding_mismatch"&&g){let s=await e.ask([{id:"binding-mismatch",text:"this session's saved conversation is no longer accepted by the service \u2014 start the conversation fresh (committed work is kept), or stop and keep the session?",risk:"high",rationale:"the service refused the saved conversation on the first turn after resume",options:[{label:"start fresh",detail:"continue with a fresh conversation \u2014 earlier answers may be re-asked"},{label:"stop",detail:"stop here; the session stays resumable"}],recommended_index:1,allow_free_text:!1}]);if((Array.isArray(s)?s.find(o=>o.id==="binding-mismatch"):void 0)?.selected_index!==0){let o=`resume abandoned: binding mismatch on session ${c.session_id} \u2014 the session is preserved`;return e.out(o),e.emit?.({type:"error",message:o,code:"BINDING_MISMATCH"}),i?.release(),2}f("binding_migrate",{sid:c.session_id},c.session_id);let l=c.resume&&"schema"in c.resume?{...c.resume,binding:{}}:void 0;try{D=await le({...c,...l?{resume:l}:{}},{...e,graphSlot:$,...p(e,$),...H?{checkpoint:H}:{}},new Map,n,f,J)}catch(o){throw f("error",{message:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0},c.session_id),q(),o}finally{e.chat?.setWorking?.(null),a()}}if(D.highRisk)return e.out(`error: ${D.highRisk.length} high-risk decision${D.highRisk.length===1?"":"s"} need a human \u2014 ci mode won't guess. Re-run with --mode agent to pause for review.`),e.emit?.({type:"error",message:`error: high-risk question(s) in ci mode (fail-closed): ${D.highRisk.map(s=>s.id).join(", ")}`,code:"HIGH_RISK_CI"}),q(),O(),1;if(D.paused){let s=i;s||(s=re(e.contextDir,{sid:c.session_id,mode:"agent",created_at:M.toISOString(),expires_at:new Date(M.getTime()+1440*60*1e3).toISOString(),agent_state:D.paused.agent_state,pending:{questions:[],proposals:[]},read_basis:Object.fromEntries((n.resolve(r)?n.edgesInto(n.resolve(r).tip):[]).filter(o=>o.type==="DERIVES"&&typeof o.props.source_id=="string").map(o=>[String(o.props.source_id),n.heads.get(String(o.props.source_id))??null])),assumed:[],corpus_cursor:{remaining:[]},conv_source:E,target_pins:n.resolve(r)?[{ref:r,cid:n.resolve(r).tip}]:[],verb:"design",use_case:r,...n.resolve(r)?.tip?{uc_tip:n.resolve(r).tip}:{},...k?{force:!0}:{},...v?{user_session_id:v.ids.session_id}:{}}));try{k&&!s.state.force&&s.save({force:!0}),v&&s.state.user_session_id!==v.ids.session_id&&s.save({user_session_id:v.ids.session_id}),E&&s.state.conv_source!==E&&s.save({conv_source:E});let o=e.chat?.drainHeldReceipts?.()??[];(o.length>0||(s.state.held_receipts?.length??0)>0)&&s.save({held_receipts:o}),y!==null&&s.save({force_scope:y}),je(s,D.paused)}catch(o){let m=s.state.checkpoint,_=`error: couldn't persist the pause for session ${s.state.sid}`+(m?` \u2014 last durable checkpoint: seq ${m.seq} @ ${m.ts}`:" \u2014 no durable checkpoint exists")+` (${o instanceof Error?o.message:String(o)})`;return e.out(_),e.emit?.({type:"error",message:_,code:"PAUSE_PERSIST_FAILED",sid:s.state.sid}),1}f("session_paused",{sid:s.state.sid},c.session_id);let d=S!=="interactive"?` --mode ${S}`:"",l=`kane-cli design tests --resume ${s.state.sid}${d}`;if(P||e.out(`paused \u2014 resume with: ${l}`),e.emit?.({type:"session_paused",sid:s.state.sid,mode:S,resume:l,expires_at:s.state.expires_at,pending_questions:D.paused.pending.questions}),P){let o=e.chat?.state.credits?.total;e.onSummary?.({state:"paused",reason:"ctrl+c",facts:[`session ${s.state.sid} saved \u2014 designing ${h.usecase.logical_id??r}`,...s.state.expires_at?[`expires: ${s.state.expires_at}`]:[],...o!==void 0?[`credits used: ${o.toFixed(1)}`]:[]],resume:l,resumeMessage:`${l} --message "<your words>"`,tracePath:Z(u)})}return O(),3}if(D.crashed&&i?.state.checkpoint){let s=i.state.checkpoint,d=S!=="interactive"?` --mode ${S}`:"",l=`kane-cli design tests --resume ${i.state.sid}${d}`;if(f("agent_crashed_resumable",{sid:i.state.sid,seq:s.seq},c.session_id),P||e.out(`agent crashed \u2014 session ${i.state.sid} is resumable at checkpoint seq ${s.seq} (at most the in-flight turn lost); resume with: ${l}`),e.emit?.({type:"session_paused",sid:i.state.sid,mode:S,resume:l,expires_at:i.state.expires_at,crashed:!0}),P){let o=e.chat?.state.credits?.total;e.onSummary?.({state:"crashed",facts:[`agent crashed \u2014 session ${i.state.sid} is resumable at checkpoint seq ${s.seq}`,"at most the in-flight turn was lost",...o!==void 0?[`credits used: ${o.toFixed(1)}`]:[]],resume:l,resumeMessage:`${l} --message "<your words>"`,tracePath:Z(u)})}return i.release(),i=null,3}if(D.error)return e.out(`error: design agent failed: ${D.error}`),e.emit?.({type:"error",message:`error: design agent failed: ${D.error}`}),q(),O(),1;if(D.proposal==null&&S!=="interactive")return e.out(`error: the design session stopped before saving anything \u2014 nothing committed (trace: ${u})`),e.emit?.({type:"error",message:`error: the design session stopped before saving anything \u2014 nothing committed (trace: ${u})`}),q(),O(),1;let ee=0;if(D.proposal==null)try{let{readRecords:s}=await import("./records-IOZTZUZV.js"),d=t.resume??c.session_id;ee=s(e.contextDir).records.filter(l=>l.sid===d).reduce((l,o)=>l+o.nodes.filter(m=>m.label!=="source").length,0)}catch{}if(D.proposal==null&&e.out(ee>0?`done \u2014 ${ee} item(s) committed in this session (earlier legs included); nothing new since the resume`:"done \u2014 nothing designed this session (no finalize before the session ended)"),D.assumedDefaults&&e.out(`assumed: ${D.assumedDefaults} default(s) taken while unattended`),i&&e.emit?.({type:"session_complete",sid:t.resume??c.session_id}),v?.event("ASR_SESSION_COMPLETE",{}),i?.complete(),Y)try{dt(he(e.contextDir,"sessions"))}catch{}if(P){let s=e.chat.state.ledger.filter(o=>o.kind==="answer"&&o.receipt.form==="assumed").length??0,d=(D.assumedDefaults??0)+s,l=e.chat.state.credits?.total??D.creditsTotal;e.onSummary?.({state:"complete",facts:[`designed: ${h.usecase.logical_id??r}${D.proposal==null?ee>0?` (${ee} item(s) committed across this session)`:" (nothing committed this session)":""}`,...d>0?[`${d} assumed default(s)`]:[],...l!==void 0?[`credits used: ${l.toFixed(1)}`]:[]],tracePath:Z(u)})}return t.plan||He(e.contextDir),O(),0}export{Es as a};
|
package/dist/chunk-LN7233E2.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{a as G}from"./chunk-MMBBQ4OZ.js";import{j as O}from"./chunk-DN3E6RT6.js";import{d as E,e as z}from"./chunk-4JOD47QI.js";import{a as X}from"./chunk-RZ4F3BHX.js";import{spawn as Ie}from"child_process";import{existsSync as $e,readFileSync as Ne}from"fs";import{homedir as Ee}from"os";import{dirname as Q,join as S}from"path";import{access as we,mkdir as W,readFile as be}from"fs/promises";import{homedir as ye}from"os";import{arch as Ae,platform as xe}from"process";import{join as D}from"path";var Se=35,ke="google_apis",Te="KaneCLI_Pixel_API35",De="KaneAI_Pixel_API35";function yt(t){return t===De?Te:t}var Pe=1;function Me(t,e){return t==="darwin"&&e==="arm64"?"arm64-v8a":"x86_64"}function _e(){return{home:ye(),os:xe,arch:Ae}}async function Y(t){try{return await we(t),!0}catch{return!1}}var V=class{deps;constructor(e={}){this.deps={..._e(),...e}}paths(){let e=D(this.deps.home,".testmuai","kaneai","mobile"),r=D(e,"android-sdk");return{root:r,emulatorDir:D(r,"emulator"),systemImageDir:D(r,"system-images",`android-${Se}`,ke,Me(this.deps.os,this.deps.arch)),avdHome:D(e,"avd"),manifest:D(r,"sdk-manifest.json")}}environment(){let e=this.paths();return{ANDROID_HOME:e.root,ANDROID_SDK_ROOT:e.root,ANDROID_AVD_HOME:e.avdHome}}async ensureSdkRootMarkers(){let e=this.paths().root;await W(D(e,"platforms"),{recursive:!0}),await W(D(e,"platform-tools"),{recursive:!0})}async status(){let e=this.paths(),r=null;try{r=JSON.parse(await be(e.manifest,"utf8"))}catch{}if(!r||r.schemaVersion!==Pe)return{emulator:!1,systemImage:!1};let o=this.deps.os==="win32"?"emulator.exe":"emulator";return{emulator:!!r.components.emulator&&await Y(D(e.emulatorDir,o)),systemImage:!!r.components.systemImage&&await Y(D(e.systemImageDir,"system.img"))}}},Z;function L(){return Z??=new V,Z}var H="android",Oe="http://127.0.0.1:4723/status",Re=2e3,ee=12e4,Ce=1e3,Le=3e5;var Fe=5,te="Run `kane-cli doctor --target emulator --install` to install the managed Appium tree.",Be={device:"ready",unauthorized:"unauthorized",offline:"offline"};function Ue(t){let e={};for(let r of t){let o=r.indexOf(":");o<=0||(e[r.slice(0,o)]=r.slice(o+1))}return e}function qe(t){let e=[];for(let r of t.split(`
|
|
3
|
-
`)){let o=r.trim();if(!o||o.startsWith("*"))continue;let c=o.toLowerCase();if(c.startsWith("list of devices")||c.startsWith("adb server"))continue;let f=o.split(/\s+/),p=f[0],v=f[1];if(!p||!v||!p.startsWith("emulator-"))continue;let h=Ue(f.slice(2)),b=h.model?h.model.replace(/_/g," "):void 0;e.push({platform:H,kind:"emulator",id:p,displayName:b??p,state:Be[v]??"offline"})}return e}function ie(t){let e=[];for(let r of t.split(`
|
|
4
|
-
`)){let o=r.trim();o&&/^[A-Za-z0-9._-]+$/.test(o)&&(e.includes(o)||e.push(o))}return e}function Ve(t){for(let e of t.split(`
|
|
5
|
-
`)){let r=e.trim();if(!(!r||r==="OK"))return r}}function He(t){let e=/^Version\s+(\S+)/m.exec(t);return e?.[1]?e[1].split("-")[0]:/Android Debug Bridge version\s+(\S+)/.exec(t)?.[1]}function je(t){let e=[];for(let r of t.split(`
|
|
6
|
-
`)){let o=r.trim();if(!o.startsWith("package:"))continue;let c=o.slice(8).trim();c&&!e.includes(c)&&e.push(c)}return e.sort()}function Je(t){let e=Number(t.trim());return Number.isInteger(e)&&e>0?e:void 0}function Ke(t){return[...new Set(t.split(",").map(e=>e.trim()).filter(Boolean))]}var Xe=[{match:/INSTALL_FAILED_VERIFICATION|verif(?:ier|ication)/i,hint:`Package verification blocked the install. Disable it for adb installs:
|
|
7
|
-
adb -s <device> shell settings put global verifier_verify_adb_installs 0`},{match:/INSTALL_FAILED_UPDATE_INCOMPATIBLE|INSTALL_FAILED_VERSION_DOWNGRADE|signatures do not match/i,hint:`A different build of this package is already installed. Uninstall it first:
|
|
8
|
-
adb -s <device> uninstall <package>`},{match:/INSUFFICIENT_STORAGE/i,hint:"The device is out of storage. Free space on the device and retry."}];function ze(t){for(let{match:e,hint:r}of Xe)if(e.test(t))return r}function j(t,e,r=Fe){let o=t.toLowerCase(),c=e.filter(v=>v.toLowerCase().includes(o)),f=Math.max(6,Math.floor(o.length/2)),p=e.filter(v=>!c.includes(v)&&Ge(v.toLowerCase(),o)>=f);return[...c,...p].slice(0,r)}function Ge(t,e){let r=Math.min(t.length,e.length),o=0;for(;o<r&&t[o]===e[o];)o++;return o}function ne(t){return t&&/^hw\.device\.name\s*=\s*(.+)\s*$/m.exec(t)?.[1]?.trim()||void 0}function We(){return X(Oe,{signal:AbortSignal.timeout(Re)}).then(t=>t.ok,()=>!1)}function Ye(t,e,r){Ie(t,e,{stdio:"ignore",detached:!0,...r?{env:{...process.env,...r}}:{}}).unref()}function Ze(){return{exec:E,spawnDetached:Ye,fileExists:$e,env:process.env,home:Ee(),os:process.platform,probeAppiumServer:We,now:()=>Date.now(),sleep:z,mobileDeps:{status:t=>O().status(t),environment:t=>O().environment(t)},sdkSuite:{status:()=>L().status(),environment:()=>L().environment(),emulatorPath:()=>{let t=L().paths().emulatorDir;return S(t,process.platform==="win32"?"emulator.exe":"emulator")},ensureSdkRootMarkers:()=>L().ensureSdkRootMarkers()}}}function re(t={}){let e={...Ze(),...t},r={},o=new Set;function c(i){return e.os==="win32"?`${i}.exe`:i}function f(i){if(e.readAvdConfig)return e.readAvdConfig(i);let n=[e.env.ANDROID_AVD_HOME,S(e.home,".android","avd"),e.sdkSuite.environment().ANDROID_AVD_HOME];for(let s of n){if(!s)continue;let a=S(s,`${i}.avd`,"config.ini");try{if(e.fileExists(a))return Ne(a,"utf8")}catch{}}}function p(){return e.os==="win32"?"appium.cmd":"appium"}function v(){let i=[];for(let n of["ANDROID_HOME","ANDROID_SDK_ROOT"]){let s=e.env[n];s&&s.trim()!==""&&i.push(s.trim())}return e.os==="darwin"?i.push(S(e.home,"Library","Android","sdk")):e.os==="win32"?i.push(S(e.home,"AppData","Local","Android","Sdk")):i.push(S(e.home,"Android","Sdk")),i}function h(i){let n=i==="adb"?"platform-tools":"emulator";return v().map(s=>S(s,n,c(i)))}async function b(i){let n=e.os==="win32"?"where":"which",s=await e.exec(n,[c(i)],{timeoutMs:5e3});if(s.code!==0)return null;let a=s.stdout.split(`
|
|
9
|
-
`)[0]?.trim();return a&&a!==""?a:null}async function $(i){let n=await e.exec(i,["-version"],{timeoutMs:1e4});return/Android emulator version/i.test(`${n.stdout}
|
|
10
|
-
${n.stderr}`)}async function M(i){if(i==="adb"){let n=G(e.env);if(n){let a=S(n.platformToolsDir,c("adb"));if(e.fileExists(a)){let d={path:a,source:"sdk"};return r[i]=d,d}return delete r[i],null}if((await e.mobileDeps.status("emulator")).installed){let a=await e.mobileDeps.environment("emulator");if(a.platformToolsDir){let d={path:S(a.platformToolsDir,c("adb")),source:"local"};return r[i]=d,d}}return delete r[i],null}if(i==="emulator"){if((await e.sdkSuite.status()).emulator){let d={path:e.sdkSuite.emulatorPath(),source:"local"};return r[i]=d,d}let s=h(i).filter(d=>e.fileExists(d)),a=await b(i);a&&!s.includes(a)&&s.push(a);for(let d of s){if(!await $(d))continue;let m={path:d,source:"sdk"};return r[i]=m,m}}return delete r[i],null}async function l(){let i=await M("adb");if(!i)throw new Error("Managed adb is not installed.\nRun `kane-cli doctor --target emulator --install` to install the pinned Android platform-tools.");return i.path}async function u(i){let n=await e.exec(i,["devices","-l"],{timeoutMs:2e4});return qe(n.stdout)}async function g(i,n){let s=await e.exec(i,["-s",n,"shell","getprop","ro.boot.qemu.avd_name"],{timeoutMs:1e4});if(s.code===0){let d=s.stdout.split(`
|
|
11
|
-
`)[0]?.trim();if(d)return d}let a=await e.exec(i,["-s",n,"emu","avd","name"],{timeoutMs:1e4});if(a.code===0)return Ve(a.stdout)}async function y(i){let n=await M("emulator");if(!n)return[];let s=await e.exec(n.path,["-list-avds"],{timeoutMs:2e4}),a=s.code===0?ie(s.stdout):[];if(o.clear(),(await e.sdkSuite.status()).emulator){let m=await e.exec(n.path,["-list-avds"],{timeoutMs:2e4,env:{...e.env,...e.sdkSuite.environment()}});if(m.code===0)for(let w of ie(m.stdout))o.add(w),a.includes(w)||a.push(w)}return a.filter(m=>!i.has(m)).map(m=>{let w=ne(f(m));return{platform:H,kind:"emulator",id:m,displayName:m,state:"stopped",virtualName:m,...w?{modelIdentifier:w}:{}}})}async function k(){let i=await M("adb");if(!i)return[];let n=await u(i.path),s=new Set;for(let d of n){if(d.kind!=="emulator"||d.state!=="ready")continue;let m=await g(i.path,d.id);if(!m)continue;d.virtualName=m,d.displayName=m;let w=ne(f(m));w&&(d.modelIdentifier=w),s.add(m)}let a=await y(s);return[...n,...a]}function A(i,n){return[`${i} did not finish booting within ${ee/1e3}s.`,n?`It attached as ${n} but never reported sys.boot_completed=1.`:"It never attached to adb.","The emulator process is still running \u2014 check its window for errors.","Common causes: no hardware acceleration (install the Android Emulator","hypervisor driver / enable KVM), or a corrupt AVD (recreate it in","Android Studio's Device Manager)."].join(`
|
|
12
|
-
`)}async function _(i,n,s){let a=await M("emulator");if(!a)throw new Error("The Android `emulator` binary was not found, so AVDs cannot be booted.\nInstall it via Android Studio's SDK Manager (Android Emulator) and set ANDROID_HOME.");let d=new Set((await u(i)).map(B=>B.id)),m=o.has(n);m&&await e.sdkSuite.ensureSdkRootMarkers();let w=m?{...e.env,...e.sdkSuite.environment()}:void 0;e.spawnDetached(a.path,["-avd",n],w),s?.(`booting ${n}\u2026`);let T=e.now()+ee,x;for(;e.now()<T;){if(await e.sleep(Ce),!x){let I=(await u(i)).find(C=>C.kind==="emulator"&&!d.has(C.id));I&&(x=I.id,s?.(`${n} attached as ${x}, waiting for boot\u2026`));continue}if((await e.exec(i,["-s",x,"shell","getprop","sys.boot_completed"],{timeoutMs:1e4})).stdout.trim()==="1")return x}throw new Error(A(n,x))}async function P(i,n){let s=await l();if(i.state==="ready")return N(i,s);if(i.state==="unauthorized")throw new Error(`${i.displayName} (${i.id}) is UNAUTHORIZED. Accept the USB-debugging prompt on the device, then retry.`);if(i.state==="offline")throw new Error(`${i.displayName} (${i.id}) is offline. Reconnect it (USB) or re-run \`adb connect ${i.id}\` (wireless), then retry.`);let a=i.virtualName??i.id,d=await _(s,a,n);return N({...i,kind:"emulator",id:d,displayName:a,state:"ready",virtualName:a},s)}async function N(i,n){let[s,a,d,m]=await Promise.all([e.exec(n,["-s",i.id,"shell","getprop","ro.build.version.sdk"],{timeoutMs:1e4}),e.exec(n,["-s",i.id,"shell","getprop","ro.build.version.release"],{timeoutMs:1e4}),e.exec(n,["-s",i.id,"shell","getprop","ro.product.cpu.abilist"],{timeoutMs:1e4}),e.exec(n,["-s",i.id,"shell","getprop","ro.product.cpu.abi"],{timeoutMs:1e4})]),w=s.code===0?Je(s.stdout):void 0,T=a.code===0?a.stdout.trim():"",x=Ke(d.code===0&&d.stdout.trim()!==""?d.stdout:m.stdout);return{...i,...w!==void 0?{androidApiLevel:w}:{},...T!==""?{osVersion:T}:{},...x.length>0?{androidAbis:x}:{}}}async function F(i){let n=await l(),s=await e.exec(n,["-s",i.id,"shell","pm","list","packages","-3"],{timeoutMs:3e4});if(s.code!==0)throw new Error(`Could not list installed packages on ${i.id}: ${s.stderr.trim()||`adb exited ${s.code}`}`);return je(s.stdout)}async function ce(i){let n;try{let{default:s}=await import("./adbkit-apkreader-ORZBGCJQ.js");n=(await(await s.open(i)).readManifest())?.package}catch(s){let a=s instanceof Error?s.message:String(s);throw new Error(`Could not read the package name from ${i} (${a}).
|
|
13
|
-
Pass the package name explicitly with --app <package>.`)}if(typeof n!="string"||n.trim()==="")throw new Error(`${i} has no package name in its manifest.
|
|
14
|
-
Pass the package name explicitly with --app <package>.`);return n.trim()}async function me(i,n,s){let a=await l();s?.(`installing ${n} on ${i.id}\u2026`);let d=await e.exec(a,["-s",i.id,"install","-r",n],{timeoutMs:Le}),m=`${d.stdout}
|
|
15
|
-
${d.stderr}`;if(d.code===0&&!/\bFailure\b/i.test(m))return;let w=ze(m),T=[`Installing ${n} on ${i.id} failed (adb exited ${d.code}).`,m.trim()];throw w&&T.push("",w),new Error(T.filter(x=>x!=="").join(`
|
|
16
|
-
`))}async function pe(i,n,s){if(n.kind==="package"){let a=await F(i);if(a.includes(n.value))return n.value;let d=j(n.value,a),m=[`${n.value} is not installed on ${i.displayName} (${i.id}).`];throw d.length>0?m.push("Close matches:",...d.map(w=>` ${w}`)):m.push("Pass a local .apk path to --app to install it instead."),new Error(m.join(`
|
|
17
|
-
`))}if(n.kind!=="apk"){let a=n.kind==="aab"?"Android app bundles are not directly installable; build an APK first.":n.kind==="apks"?"Split bundles are not supported yet.":`${n.kind} artifacts are not installable on Android.`;throw new Error(a)}return await me(i,n.value,s),ce(n.value)}async function fe(){let i=await e.mobileDeps.status("emulator");return i.installed?{status:i,env:await e.mobileDeps.environment("emulator")}:null}async function ge(i={}){let n=[],s=await fe(),a=await e.mobileDeps.status("emulator"),d=await M("adb");if(d){let I=await e.exec(d.path,["version"],{timeoutMs:1e4}),C=He(I.stdout);n.push({id:"android.adb",fixedByBundle:!0,label:"adb",required:!0,status:"pass",detail:C?`platform-tools ${C} \xB7 ${d.path}`:d.path})}else n.push({id:"android.adb",fixedByBundle:!0,label:"adb",required:!0,status:"fail",detail:a.corrupt??"managed mobile dependencies are not installed",fixText:"Run `kane-cli doctor --target emulator --install` to download the managed mobile deps bundle under ~/.testmuai/kaneai/mobile."});let m=!i.appiumUrl;s?.env.appiumHome?n.push({id:"android.appium",fixedByBundle:!0,label:"Appium",required:m,status:"pass",detail:S(Q(s.env.appiumHome),"appium","node_modules",".bin",p())}):n.push({id:"android.appium",fixedByBundle:!0,label:"Appium",required:m,status:m?"fail":"info",detail:i.appiumUrl?`managed Appium not required because --appium-url is set (${i.appiumUrl})`:a.corrupt??"managed Appium is not installed",...m?{fixText:te}:{}}),n.push({id:"android.uiautomator2",fixedByBundle:!0,label:"uiautomator2 driver",required:m,status:s?"pass":m?"fail":"info",detail:s?"bundled in the managed mobile deps":i.appiumUrl?"managed driver not required because --appium-url is set":"not installed in the managed deps tree",...s||!m?{}:{fixText:te}});let w=S(e.home,".testmuai","kaneai","mobile","trees");e.fileExists(w)&&n.push({id:"android.legacy-trees",label:"legacy toolchain trees",required:!1,status:"info",detail:`${w} predates the deps bundle \u2014 removed automatically by the next bundle install`});let T=await b("adb");T&&n.push({id:"android.system-adb",label:"system adb",required:!1,status:"info",detail:`${T} (ignored; managed adb always wins and may restart its server)`});let x=await b("appium");x&&n.push({id:"android.system-appium",label:"system Appium",required:!1,status:"info",detail:`${x} (ignored; managed Appium always wins)`});let B=await e.sdkSuite.status(),q=await M("emulator");if(B.emulator?n.push({id:"android.emulator",label:"emulator",required:!1,status:"pass",detail:`managed emulator \xB7 ${e.sdkSuite.emulatorPath()}`}):q?n.push({id:"android.emulator",label:"emulator",required:!1,status:"info",detail:`${q.path} (system install)`}):n.push({id:"android.emulator",label:"emulator",required:!1,status:"info",detail:"not installed, so stopped AVDs are not listed. Install it with the Android SDK (Android Studio \u2192 SDK Manager \u2192 Android Emulator)."}),e.os==="darwin"){let I=await e.exec("sysctl",["-n","kern.hv_support"],{timeoutMs:5e3});n.push({id:"android.virtualization",label:"virtualization",required:!1,status:"info",detail:I.code===0&&I.stdout.trim()==="1"?"Hypervisor.framework available":"Hypervisor.framework not reported \u2014 emulator boots may hang"})}else e.os==="linux"?n.push({id:"android.virtualization",label:"virtualization",required:!1,status:"info",detail:e.fileExists("/dev/kvm")?"/dev/kvm present":"/dev/kvm missing \u2014 enable KVM or emulator boots will hang"}):n.push({id:"android.virtualization",label:"virtualization",required:!1,status:"info",detail:"not checked on this host"});return n}async function he(i){let n=await e.mobileDeps.environment("emulator"),s=[...n.dirs],a=r.emulator,d=a?.source==="sdk"?Q(a.path):void 0;return d&&!s.includes(d)&&s.push(d),{...n,dirs:s}}async function ve(i,n){let s=await l(),a=[];return n.appPackage&&a.push({label:`closing ${n.appPackage}`,file:s,args:["-s",i.id,"shell","am","force-stop",n.appPackage]}),n.shutdown&&a.push({label:`shutting down ${i.displayName}`,file:s,args:["-s",i.id,"emu","kill"]}),a}return{platform:H,available:()=>!0,checks:ge,discover:k,prepare:P,listApps:F,ensureApp:pe,teardownPlan:ve,toolEnv:he}}import{mkdtemp as se,readdir as Qe,rm as oe,writeFile as et}from"fs/promises";import{tmpdir as ae}from"os";import{join as R}from"path";var de="ios",tt=12e4,it=3e5,nt="an .ipa cannot be installed on a simulator \u2014 use a .zip of the .app build";function rt(t){let e=/\.iOS-(\d+)-(\d+)$/.exec(t);return e?`${e[1]}.${e[2]}`:void 0}function st(t){let e;try{e=JSON.parse(t)}catch{return[]}let r=[];for(let[o,c]of Object.entries(e.devices??{})){let f=rt(o);for(let p of c??[]){let v=typeof p.udid=="string"?p.udid:void 0,h=typeof p.name=="string"?p.name:void 0;if(!v||!h)continue;let b=p.state==="Booted"?"ready":p.state==="Shutdown"?"stopped":"offline",$=typeof p.deviceTypeIdentifier=="string"?p.deviceTypeIdentifier.replace(/^com\.apple\.CoreSimulator\.SimDeviceType\./,""):void 0;r.push({platform:de,kind:"simulator",id:v,displayName:f?`${h} (iOS ${f})`:h,state:b,virtualName:h,...f?{osVersion:f}:{},...$?{modelIdentifier:$}:{}})}}return r}function ot(t){let e;try{e=JSON.parse(t)}catch{return[]}let r=[];for(let[o,c]of Object.entries(e)){if(c?.ApplicationType!=="User")continue;let f=c.CFBundleIdentifier??o;r.includes(f)||r.push(f)}return r.sort()}function at(t){let e;try{e=JSON.parse(t)}catch{return[]}let r=[];for(let[o,c]of Object.entries(e)){let f=c?.CFBundleIdentifier??o;f&&!r.includes(f)&&r.push(f)}return r.sort()}var J=16;function dt(t){return/^Xcode (\d+(?:\.\d+)*)/m.exec(t)?.[1]}async function lt(t){let e=await se(R(ae(),"kane-app-unzip-")),r=()=>oe(e,{recursive:!0,force:!0}),o=await E("unzip",["-q",t,"-d",e],{timeoutMs:10*6e4});if(o.code!==0)throw await r(),new Error(`Could not unpack ${t}: ${o.stderr.trim()||`unzip exited ${o.code}`}`);for(let c of[e,R(e,"Payload")]){let f;try{f=await Qe(c)}catch{continue}let p=f.find(v=>v.toLowerCase().endsWith(".app"));if(p)return{appPath:R(c,p),cleanup:r}}throw await r(),new Error(`${t} does not contain a .app bundle.`)}async function ut(t){let e=await se(R(ae(),"kane-plist-"));try{let r=R(e,"input.plist");await et(r,t);let o=await E("plutil",["-convert","json","-o","-",r],{timeoutMs:15e3});if(o.code!==0)throw new Error(`plutil could not convert simctl output: ${o.stderr.trim()}`);return o.stdout}finally{await oe(e,{recursive:!0,force:!0})}}function ct(){return{exec:E,os:process.platform,convertPlistToJson:ut,mobileDeps:{status:()=>O().status("simulator"),environment:()=>O().environment("simulator")}}}function le(t={}){let e={...ct(),...t};async function r(l,u=3e4){return e.exec("xcrun",["simctl",...l],{timeoutMs:u})}async function o(){let l=await r(["list","devices","available","--json"]);return l.code!==0?[]:st(l.stdout)}async function c(){return o()}async function f(l,u){let g=await e.exec("open",["-a","Simulator","--args","-CurrentDeviceUDID",l],{timeoutMs:15e3});g.code!==0&&u?.(`could not open Simulator.app (${g.stderr.trim()||`exit ${g.code}`}); the device is booted and the run continues headless`)}async function p(l,u){if(l.state!=="ready"&&l.state!=="stopped")throw new Error(`${l.displayName} (${l.id}) is ${l.state}; open Simulator.app to inspect it, then retry.`);l.kind==="simulator"&&await f(l.id,u),l.state==="stopped"&&u?.(`booting ${l.displayName}\u2026`);let g=await r(["bootstatus",l.id,"-b"],tt);if(g.code!==0)throw new Error(`Could not boot ${l.displayName}: ${g.stderr.trim()||g.stdout.trim()||`simctl bootstatus exited ${g.code}`}`);let y=(await o()).find(k=>k.id===l.id);if(y?.state==="ready")return y;throw new Error(`${l.displayName} finished booting but simctl still reports it as ${y?.state??"missing"}.`)}async function v(l){let u=await r(["listapps",l.id]);if(u.code!==0)throw new Error(`Could not list apps on ${l.displayName}: ${u.stderr.trim()||`simctl exited ${u.code}`}`);return ot(await e.convertPlistToJson(u.stdout))}async function h(l){let u=R(l,"Info.plist"),g=await e.exec("plutil",["-convert","json","-o","-",u],{timeoutMs:15e3});if(g.code!==0)throw new Error(`${l} Info.plist could not be read: ${g.stderr.trim()||`plutil exited ${g.code}`}`);let y;try{y=JSON.parse(g.stdout)}catch{throw new Error(`${l} Info.plist did not contain valid JSON from plutil.`)}if(!y.CFBundleIdentifier)throw new Error(`${l} has no CFBundleIdentifier in its Info.plist.`);return y.CFBundleIdentifier}async function b(l,u,g){if(u.kind==="package"){let A=await r(["listapps",l.id]);if(A.code!==0)throw new Error(`Could not list apps on ${l.displayName}: ${A.stderr.trim()||`simctl exited ${A.code}`}`);let _=at(await e.convertPlistToJson(A.stdout));if(_.includes(u.value))return u.value;let P=j(u.value,_),N=[`${u.value} is not installed on ${l.displayName} (${l.id}).`];throw P.length>0?N.push("Close matches:",...P.map(F=>` ${F}`)):N.push("Pass a .zip of the .app bundle to install it instead."),new Error(N.join(`
|
|
18
|
-
`))}if(u.kind==="ipa")throw new Error(`${nt}.`);if(u.kind!=="app"&&u.kind!=="zip")throw new Error(`${u.kind} artifacts are Android-only and not installable on iOS.`);let y=u.value,k;if(u.kind==="zip"){g?.(`unpacking ${u.value}\u2026`);let A=await lt(u.value);y=A.appPath,k=A.cleanup}g?.(`installing ${y} on ${l.displayName}\u2026`);try{let A=await r(["install",l.id,y],it);if(A.code!==0)throw new Error(`Installing ${u.value} on ${l.displayName} failed: ${A.stderr.trim()||A.stdout.trim()}`);return await h(y)}finally{await k?.()}}async function $(l={}){let u=[],g=await e.exec("xcode-select",["-p"],{timeoutMs:1e4});if(g.code===0&&g.stdout.trim()!==""){let _=await e.exec("xcodebuild",["-version"],{timeoutMs:3e4}),P=_.code===0?dt(_.stdout):void 0;P?Number(P.split(".")[0])<J?u.push({id:"ios.xcode",label:"Xcode",required:!0,status:"fail",detail:`Xcode ${P} is older than the required Xcode ${J}`,fixText:`Update Xcode to ${J} or newer from the App Store.`}):u.push({id:"ios.xcode",label:"Xcode",required:!0,status:"pass",detail:`Xcode ${P} \xB7 ${g.stdout.trim()}`}):u.push({id:"ios.xcode",label:"Xcode",required:!0,status:"fail",detail:`${g.stdout.trim()} has no usable xcodebuild (Command Line Tools only?)`,fixText:"Install full Xcode from the App Store, then run `sudo xcode-select -s /Applications/Xcode.app/Contents/Developer`."})}else u.push({id:"ios.xcode",label:"Xcode",required:!0,status:"fail",detail:"xcode-select reports no developer directory",fixText:"Install Xcode from the App Store, then run `xcode-select --install`."});let y=await e.exec("xcrun",["simctl","help"],{timeoutMs:15e3});u.push(y.code===0?{id:"ios.xcrun",label:"xcrun",required:!0,status:"pass",detail:"simctl reachable"}:{id:"ios.xcrun",label:"xcrun",required:!0,status:"fail",detail:`xcrun cannot run simctl: ${y.stderr.trim()||y.stdout.trim()||`exit ${y.code}`}`,fixText:"Run `xcode-select --install`, then confirm with `xcrun simctl list devices`. If Xcode is installed, `sudo xcode-select -s /Applications/Xcode.app/Contents/Developer` repoints it."});let k=!l.appiumUrl,A=await e.mobileDeps.status();return u.push({id:"ios.xcuitest",fixedByBundle:!0,label:"xcuitest driver",required:k,status:A.installed?"pass":k?"fail":"info",detail:A.installed?"bundled in the managed mobile deps (with prebuilt WDA)":l.appiumUrl?"managed driver not required because --appium-url is set":A.corrupt??"the simulator deps bundle is not installed",...A.installed||!k?{}:{fixText:"Run `kane-cli doctor --target simulator --install` to download the simulator deps bundle."}}),u}async function M(l,u){let g=[];return u.appPackage&&g.push({label:`closing ${u.appPackage}`,file:"xcrun",args:["simctl","terminate",l.id,u.appPackage]}),u.shutdown&&g.push({label:`shutting down ${l.displayName}`,file:"xcrun",args:["simctl","shutdown",l.id]}),g}return{platform:de,available:()=>e.os==="darwin",checks:$,discover:c,prepare:p,listApps:v,ensureApp:b,teardownPlan:M,toolEnv:()=>e.mobileDeps.environment()}}var ue=[re(),le()];function U(){return ue.filter(t=>t.available())}function Vt(){return U().map(t=>t.platform)}function Ht(){return ue.map(t=>t.platform)}function mt(t){let e=t.toLowerCase();return U().find(r=>r.platform.toLowerCase()===e)}async function pt(t){let e=t?U().filter(o=>o.platform.toLowerCase()===t.toLowerCase()):U(),r=[];for(let o of e)try{r.push(...await o.discover())}catch{}return r}function ft(t,e){let r=e.toLowerCase();return t.id.toLowerCase()===r||t.virtualName?.toLowerCase()===r}function gt(t){let e=t.virtualName&&t.virtualName!==t.id?`${t.displayName} (${t.virtualName})`:t.displayName;return`${t.id} \u2014 ${e} [${t.platform} \xB7 ${t.kind} \xB7 ${t.state}]`}function K(t){return t.length===0?"":`
|
|
19
|
-
${t.map(e=>` ${gt(e)}`).join(`
|
|
20
|
-
`)}`}async function jt(t,e={}){let r=e.discover??pt,o=e.providerFor??mt,c=await r(t.platform),f=h=>{let b=o(h.platform);return b?{ok:!0,target:h,provider:b}:{ok:!1,reason:"not-found",candidates:c,message:`No provider is registered for platform '${h.platform}'.`}};if(t.device){let h=c.filter(b=>ft(b,t.device));return h.length===0?{ok:!1,reason:"not-found",candidates:c,message:`No target matches --device '${t.device}'.`+(c.length>0?` Available:${K(c)}`:" No targets were found \u2014 run `kane-cli doctor --target <emulator|simulator>`.")}:f(h.find(b=>b.state==="ready")??h[0])}let p=t.defaultTarget;if(p&&(!t.platform||t.platform.toLowerCase()===p.platform.toLowerCase())){let h=c.find(b=>b.platform===p.platform&&b.kind===p.kind&&(b.id===p.id||b.virtualName===p.id));return h?f(h):{ok:!1,reason:t.interactive?"needs-picker":"not-found",candidates:c,message:`The saved default target '${p.id}' (${p.platform} \xB7 ${p.kind}) is not connected. `+(t.interactive?"Pick a target to bind this run.":"Pass --device <id> explicitly \u2014 kane-cli never binds a different device on its own.")+(c.length>0?` Available:${K(c)}`:"")}}if(c.length===0)return{ok:!1,reason:"none-found",candidates:[],message:"No emulator or simulator found. Start an Android emulator or boot an iOS simulator, then run `kane-cli devices list --target <emulator|simulator>`."};let v=c.filter(h=>h.state==="ready");return v.length===1?f(v[0]):t.interactive?{ok:!1,reason:"needs-picker",candidates:c,message:v.length===0?"No target is ready \u2014 pick one to prepare it.":"More than one target is ready \u2014 pick one."}:{ok:!1,reason:"ambiguous",candidates:c,message:(v.length===0?"No target is ready.":`${v.length} targets are ready.`)+` Pass --device <id>:${K(c)}`}}export{yt as a,Vt as b,Ht as c,mt as d,pt as e,jt as f};
|