@nikcli-ai/app 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +661 -0
- package/.turbo/turbo-typecheck.log +1 -0
- package/AGENTS.md +30 -0
- package/README.md +51 -0
- package/dist/_headers +17 -0
- package/dist/apple-touch-icon-v3.png +0 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/assets/BlexMonoNerdFontMono-Bold-B8jzonSj.woff2 +0 -0
- package/dist/assets/BlexMonoNerdFontMono-Medium-BvtJB5kd.woff2 +0 -0
- package/dist/assets/BlexMonoNerdFontMono-Regular-DSJ7IWr2.woff2 +0 -0
- package/dist/assets/CaskaydiaCoveNerdFontMono-Bold-CxABrWmj.woff2 +0 -0
- package/dist/assets/CaskaydiaCoveNerdFontMono-Regular-C_H0OSLN.woff2 +0 -0
- package/dist/assets/FiraCodeNerdFontMono-Bold-BjAeM3gJ.woff2 +0 -0
- package/dist/assets/FiraCodeNerdFontMono-Regular-io3c92n9.woff2 +0 -0
- package/dist/assets/HackNerdFontMono-Bold-BNG4kp7w.woff2 +0 -0
- package/dist/assets/HackNerdFontMono-Regular-IcpSchWC.woff2 +0 -0
- package/dist/assets/InconsolataNerdFontMono-Bold-oTRjQesI.woff2 +0 -0
- package/dist/assets/InconsolataNerdFontMono-Regular-CRHGEvh2.woff2 +0 -0
- package/dist/assets/IntoneMonoNerdFontMono-Bold-BL6LrHzx.woff2 +0 -0
- package/dist/assets/IntoneMonoNerdFontMono-Regular-BwjBdmsJ.woff2 +0 -0
- package/dist/assets/JetBrainsMonoNerdFontMono-Bold-CU80ifuM.woff2 +0 -0
- package/dist/assets/JetBrainsMonoNerdFontMono-Regular-QVq88ZfU.woff2 +0 -0
- package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/assets/MesloLGSNerdFontMono-Bold-CrpVO3ec.woff2 +0 -0
- package/dist/assets/MesloLGSNerdFontMono-Regular-j-nTZDWZ.woff2 +0 -0
- package/dist/assets/RobotoMonoNerdFontMono-Bold-DNxuDepp.woff2 +0 -0
- package/dist/assets/RobotoMonoNerdFontMono-Regular-DvxS3QZC.woff2 +0 -0
- package/dist/assets/SauceCodeProNerdFontMono-Bold-DloEeUVQ.woff2 +0 -0
- package/dist/assets/SauceCodeProNerdFontMono-Regular-Ba96Bdne.woff2 +0 -0
- package/dist/assets/UbuntuMonoNerdFontMono-Bold-wLXUURqB.woff2 +0 -0
- package/dist/assets/UbuntuMonoNerdFontMono-Regular-tdnXLyap.woff2 +0 -0
- package/dist/assets/abap-BXYWi5l2.js +1 -0
- package/dist/assets/abap-BdImnpbu.js +1 -0
- package/dist/assets/actionscript-3-CfeIJUat.js +1 -0
- package/dist/assets/actionscript-3-LjD3sNyx.js +1 -0
- package/dist/assets/ada-DeReRNhg.js +1 -0
- package/dist/assets/ada-bCR0ucgS.js +1 -0
- package/dist/assets/alert-01-BuOD_o_q.aac +0 -0
- package/dist/assets/alert-02-CS75AsoP.aac +0 -0
- package/dist/assets/alert-04-CaGsIGFP.aac +0 -0
- package/dist/assets/alert-05-D2gbGoRH.aac +0 -0
- package/dist/assets/alert-06-GK5Tqy6u.aac +0 -0
- package/dist/assets/alert-07-0r0kiLGz.aac +0 -0
- package/dist/assets/alert-08-CZowNquU.aac +0 -0
- package/dist/assets/alert-10-Ck5hR7zH.aac +0 -0
- package/dist/assets/android-studio-D0DqtVA4.svg +1 -0
- package/dist/assets/andromeeda-C-Jbm3Hp.js +1 -0
- package/dist/assets/angular-html-6NEUuZou.js +1 -0
- package/dist/assets/angular-html-CU67Zn6k.js +1 -0
- package/dist/assets/angular-ts-BfBSdvnY.js +1 -0
- package/dist/assets/angular-ts-BwZT4LLn.js +1 -0
- package/dist/assets/antigravity-XfClf80L.svg +1 -0
- package/dist/assets/apache-CCUDgqAf.js +1 -0
- package/dist/assets/apache-Pmp26Uib.js +1 -0
- package/dist/assets/apex-DDbsPZ6N.js +1 -0
- package/dist/assets/apex-ynV6aGfE.js +1 -0
- package/dist/assets/apl-C-KxP0FL.js +1 -0
- package/dist/assets/apl-dKokRX4l.js +1 -0
- package/dist/assets/applescript-Co6uUVPk.js +1 -0
- package/dist/assets/applescript-Dd26Nb5t.js +1 -0
- package/dist/assets/ara-BRHolxvo.js +1 -0
- package/dist/assets/ara-D6vCOKVX.js +1 -0
- package/dist/assets/asciidoc-DZ9uQOoP.js +1 -0
- package/dist/assets/asciidoc-Dv7Oe6Be.js +1 -0
- package/dist/assets/asm-CbVMAfFB.js +1 -0
- package/dist/assets/asm-D_Q5rh1f.js +1 -0
- package/dist/assets/astro-CbQHKStN.js +1 -0
- package/dist/assets/astro-OEl6i-aI.js +1 -0
- package/dist/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/dist/assets/awk-DMzUqQB5.js +1 -0
- package/dist/assets/awk-UmR4Ublb.js +1 -0
- package/dist/assets/ayu-dark-Cv9koXgw.js +1 -0
- package/dist/assets/ballerina-BFfxhgS-.js +1 -0
- package/dist/assets/ballerina-BMbY-1wP.js +1 -0
- package/dist/assets/bat-BkioyH1T.js +1 -0
- package/dist/assets/bat-Dcnh2ot_.js +1 -0
- package/dist/assets/beancount-B92nBv9q.js +1 -0
- package/dist/assets/beancount-k_qm7-4y.js +1 -0
- package/dist/assets/berry-C9fz7p0n.js +1 -0
- package/dist/assets/berry-uYugtg8r.js +1 -0
- package/dist/assets/bibtex-CHM0blh-.js +1 -0
- package/dist/assets/bibtex-DELXwv0g.js +1 -0
- package/dist/assets/bicep-Bmn6On1c.js +1 -0
- package/dist/assets/bicep-D2njIRU5.js +1 -0
- package/dist/assets/bip-bop-03-DXp7Zb0f.aac +0 -0
- package/dist/assets/bip-bop-04-CfVtpI7z.aac +0 -0
- package/dist/assets/bip-bop-06-BuvNosjK.aac +0 -0
- package/dist/assets/bip-bop-08-DBf7Bwjz.aac +0 -0
- package/dist/assets/bip-bop-09-CxEgoAHQ.aac +0 -0
- package/dist/assets/blade-CwZbp2Ca.js +1 -0
- package/dist/assets/blade-DVc8C-J4.js +1 -0
- package/dist/assets/bsl-BO_Y6i37.js +1 -0
- package/dist/assets/bsl-C4qeDxuX.js +1 -0
- package/dist/assets/c-BIGW1oBm.js +1 -0
- package/dist/assets/c-CyUOlKFr.js +1 -0
- package/dist/assets/cadence-Bv_4Rxtq.js +1 -0
- package/dist/assets/cadence-bIHbUj02.js +1 -0
- package/dist/assets/cairo-C_mOTUpN.js +1 -0
- package/dist/assets/cairo-KRGpt6FW.js +1 -0
- package/dist/assets/catppuccin-frappe-DFWUc33u.js +1 -0
- package/dist/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
- package/dist/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
- package/dist/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
- package/dist/assets/clarity-A4x-rz24.js +1 -0
- package/dist/assets/clarity-D53aC0YG.js +1 -0
- package/dist/assets/clojure-Bb2-3A0I.js +1 -0
- package/dist/assets/clojure-P80f7IUj.js +1 -0
- package/dist/assets/cmake-Cv5ljclQ.js +1 -0
- package/dist/assets/cmake-D1j8_8rp.js +1 -0
- package/dist/assets/cobol-Cg3yRVOY.js +1 -0
- package/dist/assets/cobol-nwyudZeR.js +1 -0
- package/dist/assets/codeowners-Bp6g37R7.js +1 -0
- package/dist/assets/codeowners-CKT8dJip.js +1 -0
- package/dist/assets/codeql-DXd8ggn3.js +1 -0
- package/dist/assets/codeql-DsOJ9woJ.js +1 -0
- package/dist/assets/coffee-CSg58a7P.js +1 -0
- package/dist/assets/coffee-Ch7k5sss.js +1 -0
- package/dist/assets/common-lisp-Cg-RD9OK.js +1 -0
- package/dist/assets/common-lisp-v102bg8X.js +1 -0
- package/dist/assets/coq-CxCehFeR.js +1 -0
- package/dist/assets/coq-DkFqJrB1.js +1 -0
- package/dist/assets/cpp-C28rag7_.js +1 -0
- package/dist/assets/cpp-CofmeUqb.js +1 -0
- package/dist/assets/crystal-kLfOnxTY.js +1 -0
- package/dist/assets/crystal-tKQVLTB8.js +1 -0
- package/dist/assets/csharp-DFQpaWb6.js +1 -0
- package/dist/assets/csharp-K5feNrxe.js +1 -0
- package/dist/assets/css-BSK200cd.js +1 -0
- package/dist/assets/css-DPfMkruS.js +1 -0
- package/dist/assets/csv-AZNL9t8Q.js +1 -0
- package/dist/assets/csv-fuZLfV_i.js +1 -0
- package/dist/assets/cue-D82EKSYY.js +1 -0
- package/dist/assets/cue-nzsbQn5T.js +1 -0
- package/dist/assets/cypher-BM7Pwunj.js +1 -0
- package/dist/assets/cypher-COkxafJQ.js +1 -0
- package/dist/assets/d-85-TOEBH.js +1 -0
- package/dist/assets/d-TG9YRPoI.js +1 -0
- package/dist/assets/dark-plus-C3mMm8J8.js +1 -0
- package/dist/assets/dart-CF10PKvl.js +1 -0
- package/dist/assets/dart-DArdxSyj.js +1 -0
- package/dist/assets/dax-B28Cho4e.js +1 -0
- package/dist/assets/dax-CEL-wOlO.js +1 -0
- package/dist/assets/desktop-BmXAJ9_W.js +1 -0
- package/dist/assets/desktop-Z9LhWKWr.js +1 -0
- package/dist/assets/diff-BlzBhZx2.js +1 -0
- package/dist/assets/diff-D97Zzqfu.js +1 -0
- package/dist/assets/docker-BcOcwvcX.js +1 -0
- package/dist/assets/docker-DIG_IqVK.js +1 -0
- package/dist/assets/dotenv-Bf0GLMGc.js +1 -0
- package/dist/assets/dotenv-Da5cRb03.js +1 -0
- package/dist/assets/dracula-BzJJZx-M.js +1 -0
- package/dist/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/dist/assets/dream-maker-BtqSS_iP.js +1 -0
- package/dist/assets/dream-maker-DBhfoDN-.js +1 -0
- package/dist/assets/edge-BkV0erSs.js +1 -0
- package/dist/assets/edge-C9mkmEUa.js +1 -0
- package/dist/assets/elixir-B1OcFvXE.js +1 -0
- package/dist/assets/elixir-CDX3lj18.js +1 -0
- package/dist/assets/elm-BX_9EnK8.js +1 -0
- package/dist/assets/elm-DbKCFpqz.js +1 -0
- package/dist/assets/emacs-lisp-C9XAeP06.js +1 -0
- package/dist/assets/emacs-lisp-fXIB3QbG.js +1 -0
- package/dist/assets/erb-BOJIQeun.js +1 -0
- package/dist/assets/erb-CjsbKF3w.js +1 -0
- package/dist/assets/erlang-Dh270pQQ.js +1 -0
- package/dist/assets/erlang-DsQrWhSR.js +1 -0
- package/dist/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/dist/assets/everforest-light-C8M2exoo.js +1 -0
- package/dist/assets/fennel-BYunw83y.js +1 -0
- package/dist/assets/fennel-CKW7gc4E.js +1 -0
- package/dist/assets/finder-CGxGn0h3.png +0 -0
- package/dist/assets/fish-BiaFC76h.js +1 -0
- package/dist/assets/fish-BvzEVeQv.js +1 -0
- package/dist/assets/fluent-C1VbA1FI.js +1 -0
- package/dist/assets/fluent-C4IJs8-o.js +1 -0
- package/dist/assets/fortran-fixed-form-BZjJHVRy.js +1 -0
- package/dist/assets/fortran-fixed-form-VBUom2Po.js +1 -0
- package/dist/assets/fortran-free-form-D22FLkUw.js +1 -0
- package/dist/assets/fortran-free-form-xZZnushS.js +1 -0
- package/dist/assets/fsharp-B6CigNpP.js +1 -0
- package/dist/assets/fsharp-CXgrBDvD.js +1 -0
- package/dist/assets/gdresource-B57lXvxj.js +1 -0
- package/dist/assets/gdresource-B7Tvp0Sc.js +1 -0
- package/dist/assets/gdscript-DTMYz4Jt.js +1 -0
- package/dist/assets/gdscript-etqGfJNh.js +1 -0
- package/dist/assets/gdshader-DkwncUOv.js +1 -0
- package/dist/assets/gdshader-MbeiIFWW.js +1 -0
- package/dist/assets/genie-CTXGoN_z.js +1 -0
- package/dist/assets/genie-D0YGMca9.js +1 -0
- package/dist/assets/gherkin-DQeIZrj7.js +1 -0
- package/dist/assets/gherkin-DyxjwDmM.js +1 -0
- package/dist/assets/ghostty-web-CsYhFgbJ.js +13 -0
- package/dist/assets/git-commit-BicZTByO.js +1 -0
- package/dist/assets/git-commit-F4YmCXRG.js +1 -0
- package/dist/assets/git-rebase-Bzlpfr7M.js +1 -0
- package/dist/assets/git-rebase-r7XF79zn.js +1 -0
- package/dist/assets/github-dark-DHJKELXO.js +1 -0
- package/dist/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/dist/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/dist/assets/github-light-DAi9KRSo.js +1 -0
- package/dist/assets/github-light-default-D7oLnXFd.js +1 -0
- package/dist/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/dist/assets/gleam-B-IqXlZK.js +1 -0
- package/dist/assets/gleam-BspZqrRM.js +1 -0
- package/dist/assets/glimmer-js-Rg0-pVw9.js +1 -0
- package/dist/assets/glimmer-js-cZi37nA1.js +1 -0
- package/dist/assets/glimmer-ts-BY3QTAW9.js +1 -0
- package/dist/assets/glimmer-ts-U6CK756n.js +1 -0
- package/dist/assets/glsl-Bk7TyU8J.js +1 -0
- package/dist/assets/glsl-DplSGwfg.js +1 -0
- package/dist/assets/gnuplot-BBjkHhdK.js +1 -0
- package/dist/assets/gnuplot-DdkO51Og.js +1 -0
- package/dist/assets/go-BYCC9JQ2.js +1 -0
- package/dist/assets/go-Dn2_MT6a.js +1 -0
- package/dist/assets/graphql-By4-2MiP.js +1 -0
- package/dist/assets/graphql-ChdNCCLP.js +1 -0
- package/dist/assets/groovy-DjMbfbx0.js +1 -0
- package/dist/assets/groovy-gcz8RCvz.js +1 -0
- package/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
- package/dist/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
- package/dist/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
- package/dist/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
- package/dist/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
- package/dist/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
- package/dist/assets/hack-CaT9iCJl.js +1 -0
- package/dist/assets/hack-Ce3HFLQu.js +1 -0
- package/dist/assets/haml-B8DHNrY2.js +1 -0
- package/dist/assets/haml-C-C08OMF.js +1 -0
- package/dist/assets/handlebars-BFxKmXBZ.js +1 -0
- package/dist/assets/handlebars-BL8al0AC.js +1 -0
- package/dist/assets/haskell-Df6bDoY_.js +1 -0
- package/dist/assets/haskell-DtebQ3Kv.js +1 -0
- package/dist/assets/haxe-CzTSHFRz.js +1 -0
- package/dist/assets/haxe-n0Q_eay_.js +1 -0
- package/dist/assets/hcl-BWvSN4gD.js +1 -0
- package/dist/assets/hcl-shhv74hy.js +1 -0
- package/dist/assets/hjson-BEMFYqr7.js +1 -0
- package/dist/assets/hjson-D5-asLiD.js +1 -0
- package/dist/assets/hlsl-D3lLCCz7.js +1 -0
- package/dist/assets/hlsl-Pefxhtaj.js +1 -0
- package/dist/assets/home-DDFZTO3p.js +1 -0
- package/dist/assets/houston-DnULxvSX.js +1 -0
- package/dist/assets/html-DBrZJmtb.js +1 -0
- package/dist/assets/html-GMplVEZG.js +1 -0
- package/dist/assets/html-derivative-BFtXZ54Q.js +1 -0
- package/dist/assets/html-derivative-DgyNW28a.js +1 -0
- package/dist/assets/http-D0p2QOuJ.js +1 -0
- package/dist/assets/http-jrhK8wxY.js +1 -0
- package/dist/assets/hurl-CeF7EoTQ.js +1 -0
- package/dist/assets/hurl-irOxFIW8.js +1 -0
- package/dist/assets/hxml-B_SuSTPP.js +1 -0
- package/dist/assets/hxml-Bvhsp5Yf.js +1 -0
- package/dist/assets/hy-CTpXmg0M.js +1 -0
- package/dist/assets/hy-DFXneXwc.js +1 -0
- package/dist/assets/imba-DGztddWO.js +1 -0
- package/dist/assets/imba-z_cUhu9e.js +1 -0
- package/dist/assets/index-D0jX0BNw.js +1844 -0
- package/dist/assets/index-DDCRe3lm.css +1 -0
- package/dist/assets/ini-BEwlwnbL.js +1 -0
- package/dist/assets/ini-DOGW4-0C.js +1 -0
- package/dist/assets/inter-FIwubZjA.woff2 +0 -0
- package/dist/assets/iosevka-nerd-font-DKH7rjGs.woff2 +0 -0
- package/dist/assets/iosevka-nerd-font-bold-BObfzjZJ.woff2 +0 -0
- package/dist/assets/java-B2AjWfgk.js +1 -0
- package/dist/assets/java-CylS5w8V.js +1 -0
- package/dist/assets/javascript-XPxc2APE.js +1 -0
- package/dist/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/assets/jinja-4LBKfQ-Z.js +1 -0
- package/dist/assets/jinja-DlBE7Xgz.js +1 -0
- package/dist/assets/jison-DRGa8fbr.js +1 -0
- package/dist/assets/jison-wvAkD_A8.js +1 -0
- package/dist/assets/json-CjLXzM_z.js +1 -0
- package/dist/assets/json-Cp-IABpG.js +1 -0
- package/dist/assets/json5-C9tS-k6U.js +1 -0
- package/dist/assets/json5-DE06a0U2.js +1 -0
- package/dist/assets/jsonc-BYi4HS05.js +1 -0
- package/dist/assets/jsonc-Des-eS-w.js +1 -0
- package/dist/assets/jsonl-CuhIcKDk.js +1 -0
- package/dist/assets/jsonl-DcaNXYhu.js +1 -0
- package/dist/assets/jsonnet-DFQXde-d.js +1 -0
- package/dist/assets/jsonnet-DtQdHwK-.js +1 -0
- package/dist/assets/jssm-BlhucWo7.js +1 -0
- package/dist/assets/jssm-C2t-YnRu.js +1 -0
- package/dist/assets/jsx-BGEKFWBk.js +1 -0
- package/dist/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/assets/julia-Bh5qjrIj.js +1 -0
- package/dist/assets/julia-C8NyazO9.js +1 -0
- package/dist/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
- package/dist/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
- package/dist/assets/kanagawa-wave-DWedfzmr.js +1 -0
- package/dist/assets/kdl-DJsF4U57.js +1 -0
- package/dist/assets/kdl-DV7GczEv.js +1 -0
- package/dist/assets/kotlin-BdnUsdx6.js +1 -0
- package/dist/assets/kotlin-DwKqsDKK.js +1 -0
- package/dist/assets/kusto-BvAqAH-y.js +1 -0
- package/dist/assets/kusto-w7PrLrBe.js +1 -0
- package/dist/assets/laserwave-DUszq2jm.js +1 -0
- package/dist/assets/latex-BdAV_C_H.js +1 -0
- package/dist/assets/latex-BuzO6rjU.js +1 -0
- package/dist/assets/lean-Bc6EcWN3.js +1 -0
- package/dist/assets/lean-Dle5D8N4.js +1 -0
- package/dist/assets/less-B1dDrJ26.js +1 -0
- package/dist/assets/less-C76OjOdF.js +1 -0
- package/dist/assets/light-plus-B7mTdjB0.js +1 -0
- package/dist/assets/liquid-DYVedYrR.js +1 -0
- package/dist/assets/liquid-DdraCjph.js +1 -0
- package/dist/assets/llvm-BtvRca6l.js +1 -0
- package/dist/assets/llvm-s1WuUfOe.js +1 -0
- package/dist/assets/log-2UxHyX5q.js +1 -0
- package/dist/assets/log-CbW7hOWU.js +1 -0
- package/dist/assets/logo-BbooMuDm.js +1 -0
- package/dist/assets/logo-BtOb2qkB.js +1 -0
- package/dist/assets/lua-BbnMAYS6.js +1 -0
- package/dist/assets/lua-tkfysgZP.js +1 -0
- package/dist/assets/luau-CBwFb-vO.js +1 -0
- package/dist/assets/luau-CXu1NL6O.js +1 -0
- package/dist/assets/make-CHLpvVh8.js +1 -0
- package/dist/assets/make-s9FKP0VE.js +1 -0
- package/dist/assets/markdown-CKXSK5AY.js +1 -0
- package/dist/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/assets/marko-BsqRlKIY.js +1 -0
- package/dist/assets/marko-CPi9NSCl.js +1 -0
- package/dist/assets/material-theme-D5KoaKCx.js +1 -0
- package/dist/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/dist/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/dist/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/dist/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/dist/assets/matlab-BQKM-LA_.js +1 -0
- package/dist/assets/matlab-D7o27uSR.js +1 -0
- package/dist/assets/mdc-BBM-UqJy.js +1 -0
- package/dist/assets/mdc-DUICxH0z.js +1 -0
- package/dist/assets/mdx-BWRhHdFl.js +1 -0
- package/dist/assets/mdx-Cmh6b_Ma.js +1 -0
- package/dist/assets/mermaid-DKYwYmdq.js +1 -0
- package/dist/assets/mermaid-DrapLM8U.js +1 -0
- package/dist/assets/min-dark-CafNBF8u.js +1 -0
- package/dist/assets/min-light-CTRr51gU.js +1 -0
- package/dist/assets/mipsasm-BElnB_7Q.js +1 -0
- package/dist/assets/mipsasm-CKIfxQSi.js +1 -0
- package/dist/assets/mojo-1DNp92w6.js +1 -0
- package/dist/assets/mojo-Dz6zCmiK.js +1 -0
- package/dist/assets/monokai-D4h5O-jR.js +1 -0
- package/dist/assets/move-Bu9oaDYs.js +1 -0
- package/dist/assets/move-Dvu4btzz.js +1 -0
- package/dist/assets/narrat-Cy2k80UN.js +1 -0
- package/dist/assets/narrat-DRg8JJMk.js +1 -0
- package/dist/assets/nextflow-BO4ujnzu.js +1 -0
- package/dist/assets/nextflow-BrzmwbiE.js +1 -0
- package/dist/assets/nginx-DknmC5AR.js +1 -0
- package/dist/assets/nginx-XmDIhN78.js +1 -0
- package/dist/assets/night-owl-C39BiMTA.js +1 -0
- package/dist/assets/nim-CVrawwO9.js +1 -0
- package/dist/assets/nim-Cm6-Nayq.js +1 -0
- package/dist/assets/nix-DcZRBjkC.js +1 -0
- package/dist/assets/nix-c8nO5XWb.js +1 -0
- package/dist/assets/nope-02-EygnDbCM.aac +0 -0
- package/dist/assets/nope-05-DZsXzrQW.aac +0 -0
- package/dist/assets/nope-08-COPo0uNf.aac +0 -0
- package/dist/assets/nope-11-CVdXg8G-.aac +0 -0
- package/dist/assets/nope-12-BJR1Ka3c.aac +0 -0
- package/dist/assets/nord-Ddv68eIx.js +1 -0
- package/dist/assets/nushell-C-sUppwS.js +1 -0
- package/dist/assets/nushell-Dqv-0Q5X.js +1 -0
- package/dist/assets/objective-c-DXmwc3jG.js +1 -0
- package/dist/assets/objective-c-sgtl-PdD.js +1 -0
- package/dist/assets/objective-cpp-BTQ37cYs.js +1 -0
- package/dist/assets/objective-cpp-CLxacb5B.js +1 -0
- package/dist/assets/ocaml-BvBP9Lm0.js +1 -0
- package/dist/assets/ocaml-C0hk2d4L.js +1 -0
- package/dist/assets/one-dark-pro-DVMEJ2y_.js +1 -0
- package/dist/assets/one-light-PoHY5YXO.js +1 -0
- package/dist/assets/openscad-C4EeE6gA.js +1 -0
- package/dist/assets/openscad-Dmi2c_42.js +1 -0
- package/dist/assets/pascal-D93ZcfNL.js +1 -0
- package/dist/assets/pascal-DYjw0AuS.js +1 -0
- package/dist/assets/perl-C0TMdlhV.js +1 -0
- package/dist/assets/perl-Djxv1YJ9.js +1 -0
- package/dist/assets/php-CDn_0X-4.js +1 -0
- package/dist/assets/php-DEfiO3Bd.js +1 -0
- package/dist/assets/pierre-dark-BXuwtOqb.js +1 -0
- package/dist/assets/pierre-light-dckrK0oj.js +1 -0
- package/dist/assets/pkl-Cij4Vm9z.js +1 -0
- package/dist/assets/pkl-u5AG7uiY.js +1 -0
- package/dist/assets/plastic-3e1v2bzS.js +1 -0
- package/dist/assets/plsql-Bd6NdBJI.js +1 -0
- package/dist/assets/plsql-ChMvpjG-.js +1 -0
- package/dist/assets/po-BTJTHyun.js +1 -0
- package/dist/assets/po-CUhVi7la.js +1 -0
- package/dist/assets/poimandres-CS3Unz2-.js +1 -0
- package/dist/assets/polar-B-qJ3AIy.js +1 -0
- package/dist/assets/polar-C0HS_06l.js +1 -0
- package/dist/assets/postcss-BSGhOJ4k.js +1 -0
- package/dist/assets/postcss-CXtECtnM.js +1 -0
- package/dist/assets/powerquery-CC1XieQO.js +1 -0
- package/dist/assets/powerquery-CEu0bR-o.js +1 -0
- package/dist/assets/powershell-DdRAnR4Z.js +1 -0
- package/dist/assets/powershell-Dpen1YoG.js +1 -0
- package/dist/assets/prisma-C0hJlfqX.js +1 -0
- package/dist/assets/prisma-Dd19v3D-.js +1 -0
- package/dist/assets/prolog-CbFg5uaA.js +1 -0
- package/dist/assets/prolog-bSi0SE3D.js +1 -0
- package/dist/assets/proto-DIGPV07t.js +1 -0
- package/dist/assets/proto-DyJlTyXw.js +1 -0
- package/dist/assets/pug-CGlum2m_.js +1 -0
- package/dist/assets/pug-ClQUpJlV.js +1 -0
- package/dist/assets/puppet-BMWR74SV.js +1 -0
- package/dist/assets/puppet-ja2MI9-b.js +1 -0
- package/dist/assets/purescript-CklMAg4u.js +1 -0
- package/dist/assets/purescript-CxgsQa43.js +1 -0
- package/dist/assets/python-B6aJPvgy.js +1 -0
- package/dist/assets/python-DgE28U1V.js +1 -0
- package/dist/assets/qml-3beO22l8.js +1 -0
- package/dist/assets/qml-BEkX6VoX.js +1 -0
- package/dist/assets/qmldir-C8lEn-DE.js +1 -0
- package/dist/assets/qmldir-DNYHzgow.js +1 -0
- package/dist/assets/qss-BZsEMKxJ.js +1 -0
- package/dist/assets/qss-IeuSbFQv.js +1 -0
- package/dist/assets/r-BfG_C0qz.js +1 -0
- package/dist/assets/r-DiinP2Uv.js +1 -0
- package/dist/assets/racket-BqYA7rlc.js +1 -0
- package/dist/assets/racket-CzHBKLyy.js +1 -0
- package/dist/assets/raku-CPccoUN1.js +1 -0
- package/dist/assets/raku-DXvB9xmW.js +1 -0
- package/dist/assets/razor-8rj0VRTp.js +1 -0
- package/dist/assets/razor-CE9lU5zL.js +1 -0
- package/dist/assets/red-bN70gL4F.js +1 -0
- package/dist/assets/reg-C-SQnVFl.js +1 -0
- package/dist/assets/reg-DkqHJyC0.js +1 -0
- package/dist/assets/regexp-BW_zLBm-.js +1 -0
- package/dist/assets/regexp-CDVJQ6XC.js +1 -0
- package/dist/assets/rel-BIqKdwke.js +1 -0
- package/dist/assets/rel-C3B-1QV4.js +1 -0
- package/dist/assets/riscv-BM1_JUlF.js +1 -0
- package/dist/assets/riscv-s6spwTFp.js +1 -0
- package/dist/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
- package/dist/assets/rose-pine-moon-D4_iv3hh.js +1 -0
- package/dist/assets/rose-pine-qdsjHGoJ.js +1 -0
- package/dist/assets/rosmsg-BJDFO7_C.js +1 -0
- package/dist/assets/rosmsg-TcL_zzr8.js +1 -0
- package/dist/assets/rst-8IYWyo0X.js +1 -0
- package/dist/assets/rst-B0xPkSld.js +1 -0
- package/dist/assets/ruby-BvKwtOVI.js +1 -0
- package/dist/assets/ruby-CHyTNJrF.js +1 -0
- package/dist/assets/rust-B1yitclQ.js +1 -0
- package/dist/assets/rust-DJErdhjk.js +1 -0
- package/dist/assets/sas-BZeeyq_z.js +1 -0
- package/dist/assets/sas-cz2c8ADy.js +1 -0
- package/dist/assets/sass-CIfQ9yqV.js +1 -0
- package/dist/assets/sass-Cj5Yp3dK.js +1 -0
- package/dist/assets/scala-C151Ov-r.js +1 -0
- package/dist/assets/scala-CWwlNtab.js +1 -0
- package/dist/assets/scheme-ByM66cy_.js +1 -0
- package/dist/assets/scheme-C98Dy4si.js +1 -0
- package/dist/assets/scss-Dk05w39G.js +1 -0
- package/dist/assets/scss-OYdSNvt2.js +1 -0
- package/dist/assets/sdbl-C5Q1usnU.js +1 -0
- package/dist/assets/sdbl-DVxCFoDh.js +1 -0
- package/dist/assets/session-fRmszlju.js +41 -0
- package/dist/assets/shaderlab-DNkMdb2B.js +1 -0
- package/dist/assets/shaderlab-Dg9Lc6iA.js +1 -0
- package/dist/assets/shellscript-CE-5zpiL.js +1 -0
- package/dist/assets/shellscript-Yzrsuije.js +1 -0
- package/dist/assets/shellsession-BADoaaVG.js +1 -0
- package/dist/assets/shellsession-BhddCRKA.js +1 -0
- package/dist/assets/slack-dark-BthQWCQV.js +1 -0
- package/dist/assets/slack-ochin-DqwNpetd.js +1 -0
- package/dist/assets/smalltalk-BERRCDM3.js +1 -0
- package/dist/assets/smalltalk-GKfhTxrk.js +1 -0
- package/dist/assets/snazzy-light-Bw305WKR.js +1 -0
- package/dist/assets/solarized-dark-DXbdFlpD.js +1 -0
- package/dist/assets/solarized-light-L9t79GZl.js +1 -0
- package/dist/assets/solidity-DanOLEvk.js +1 -0
- package/dist/assets/solidity-rGO070M0.js +1 -0
- package/dist/assets/soy-Brmx7dQM.js +1 -0
- package/dist/assets/soy-C6ERzLIv.js +1 -0
- package/dist/assets/sparql-CHK3vDkL.js +1 -0
- package/dist/assets/sparql-rVzFXLq3.js +1 -0
- package/dist/assets/splunk-BtCnVYZw.js +1 -0
- package/dist/assets/splunk-YU1HCmJX.js +1 -0
- package/dist/assets/sprite-BxALe73Z.svg +882 -0
- package/dist/assets/sprite-Fb-TFjRY.svg +11707 -0
- package/dist/assets/sql-BLtJtn59.js +1 -0
- package/dist/assets/sql-CKXjX23X.js +1 -0
- package/dist/assets/ssh-config-Cpnw3KEt.js +1 -0
- package/dist/assets/ssh-config-_ykCGR6B.js +1 -0
- package/dist/assets/staplebops-03-Aug82oH0.aac +0 -0
- package/dist/assets/staplebops-04-olyHi8qQ.aac +0 -0
- package/dist/assets/staplebops-06-Cj_2vOI4.aac +0 -0
- package/dist/assets/staplebops-07-cqQEvbIf.aac +0 -0
- package/dist/assets/stata-BH5u7GGu.js +1 -0
- package/dist/assets/stata-BJqnY-gO.js +1 -0
- package/dist/assets/stylus-BEDo0Tqx.js +1 -0
- package/dist/assets/stylus-CHekGIgu.js +1 -0
- package/dist/assets/svelte-3Dk4HxPD.js +1 -0
- package/dist/assets/svelte-DmnhoTkn.js +1 -0
- package/dist/assets/swift-Deru3G9w.js +1 -0
- package/dist/assets/swift-Dg5xB15N.js +1 -0
- package/dist/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/dist/assets/system-verilog-CnnmHF94.js +1 -0
- package/dist/assets/system-verilog-rKNYENrf.js +1 -0
- package/dist/assets/systemd-4A_iFExJ.js +1 -0
- package/dist/assets/systemd-C1FfcI00.js +1 -0
- package/dist/assets/talonscript-CkByrt1z.js +1 -0
- package/dist/assets/talonscript-bksoRmW6.js +1 -0
- package/dist/assets/tasl-Bl4tsGRM.js +1 -0
- package/dist/assets/tasl-QIJgUcNo.js +1 -0
- package/dist/assets/tcl-B2_VAYrd.js +1 -0
- package/dist/assets/tcl-dwOrl1Do.js +1 -0
- package/dist/assets/templ-CyHhV9jl.js +1 -0
- package/dist/assets/templ-W15q3VgB.js +1 -0
- package/dist/assets/terminal-Cpd_WDea.png +0 -0
- package/dist/assets/terraform-BETggiCN.js +1 -0
- package/dist/assets/terraform-Ba94thAr.js +1 -0
- package/dist/assets/tex-CxkMU7Pf.js +1 -0
- package/dist/assets/tex-DZ7Smwga.js +1 -0
- package/dist/assets/textmate-B-hymv65.png +0 -0
- package/dist/assets/tokyo-night-hegEt444.js +1 -0
- package/dist/assets/toml-Btlk-g9G.js +1 -0
- package/dist/assets/toml-vGWfd6FD.js +1 -0
- package/dist/assets/ts-tags-DMPjx__B.js +1 -0
- package/dist/assets/ts-tags-zn1MmPIZ.js +1 -0
- package/dist/assets/tsv-B_m7g4N7.js +1 -0
- package/dist/assets/tsv-DYfmKMIW.js +1 -0
- package/dist/assets/tsx-COt5Ahok.js +1 -0
- package/dist/assets/tsx-Dio8iE-N.js +1 -0
- package/dist/assets/turtle-BsS91CYL.js +1 -0
- package/dist/assets/turtle-whXsfw69.js +1 -0
- package/dist/assets/twig-CO9l9SDP.js +1 -0
- package/dist/assets/twig-vsFUeHgy.js +1 -0
- package/dist/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/assets/typescript-DttGkNCf.js +1 -0
- package/dist/assets/typespec-BGHnOYBU.js +1 -0
- package/dist/assets/typespec-C_z-8Pri.js +1 -0
- package/dist/assets/typst-D2RORpaG.js +1 -0
- package/dist/assets/typst-DHCkPAjA.js +1 -0
- package/dist/assets/v-BcVCzyr7.js +1 -0
- package/dist/assets/v-CvM42WIw.js +1 -0
- package/dist/assets/vala-B_5xOBNr.js +1 -0
- package/dist/assets/vala-CsfeWuGM.js +1 -0
- package/dist/assets/vb-BVDm3zBt.js +1 -0
- package/dist/assets/vb-D17OF-Vu.js +1 -0
- package/dist/assets/verilog-BQ8w6xss.js +1 -0
- package/dist/assets/verilog-D5iownw6.js +1 -0
- package/dist/assets/vesper-DU1UobuO.js +1 -0
- package/dist/assets/vhdl-Bmgbkl_-.js +1 -0
- package/dist/assets/vhdl-CeAyd5Ju.js +1 -0
- package/dist/assets/viml-3ZODU9FQ.js +1 -0
- package/dist/assets/viml-CJc9bBzg.js +1 -0
- package/dist/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/dist/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/dist/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/dist/assets/vue-BJuclMoA.js +1 -0
- package/dist/assets/vue-DnHKYNfI.js +1 -0
- package/dist/assets/vue-html-CChd_i61.js +1 -0
- package/dist/assets/vue-html-CRAum25o.js +1 -0
- package/dist/assets/vue-vine-8moa0y9V.js +1 -0
- package/dist/assets/vue-vine-CDS6dxm6.js +1 -0
- package/dist/assets/vyper-B6NKdirK.js +1 -0
- package/dist/assets/vyper-CDx5xZoG.js +1 -0
- package/dist/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/assets/wasm-LUzQYg3H.js +1 -0
- package/dist/assets/wasm-MzD3tlZU.js +1 -0
- package/dist/assets/wenyan-8fXatRyt.js +1 -0
- package/dist/assets/wenyan-BV7otONQ.js +1 -0
- package/dist/assets/wgsl-CECC3vJ5.js +1 -0
- package/dist/assets/wgsl-Dx-B1_4e.js +1 -0
- package/dist/assets/wikitext-BaRWL9sq.js +1 -0
- package/dist/assets/wikitext-BhOHFoWU.js +1 -0
- package/dist/assets/wit-5i3qLPDT.js +1 -0
- package/dist/assets/wit-MEd50GYB.js +1 -0
- package/dist/assets/wolfram-CmMaIVaG.js +1 -0
- package/dist/assets/wolfram-lXgVvXCa.js +1 -0
- package/dist/assets/worker-CKpRWWws.js +153 -0
- package/dist/assets/xcode-4zqeTePl.png +0 -0
- package/dist/assets/xml-DtyAt_xK.js +1 -0
- package/dist/assets/xml-sdJ4AIDG.js +1 -0
- package/dist/assets/xsl-Btrj9DhN.js +1 -0
- package/dist/assets/xsl-CtQFsRM5.js +1 -0
- package/dist/assets/yaml-B92AUxDB.js +1 -0
- package/dist/assets/yaml-Buea-lGh.js +1 -0
- package/dist/assets/yup-01-BtRq6dLN.aac +0 -0
- package/dist/assets/yup-03-BHLEoqSS.aac +0 -0
- package/dist/assets/yup-04-C7yadpJT.aac +0 -0
- package/dist/assets/yup-05-CuuaeyjC.aac +0 -0
- package/dist/assets/zenscript-DVFEvuxE.js +1 -0
- package/dist/assets/zenscript-Dja4fBOE.js +1 -0
- package/dist/assets/zig-LhWa2ADv.js +1 -0
- package/dist/assets/zig-VOosw3JB.js +1 -0
- package/dist/favicon-96x96-v3.png +0 -0
- package/dist/favicon-96x96.png +0 -0
- package/dist/favicon-v3.ico +0 -0
- package/dist/favicon-v3.svg +7 -0
- package/dist/favicon.ico +0 -0
- package/dist/favicon.svg +7 -0
- package/dist/index.html +24 -0
- package/dist/oc-theme-preload.js +28 -0
- package/dist/site.webmanifest +21 -0
- package/dist/social-share-zen.png +0 -0
- package/dist/social-share.png +0 -0
- package/dist/web-app-manifest-192x192.png +0 -0
- package/dist/web-app-manifest-512x512.png +0 -0
- package/e2e/AGENTS.md +176 -0
- package/e2e/actions.ts +421 -0
- package/e2e/app/home.spec.ts +21 -0
- package/e2e/app/navigation.spec.ts +10 -0
- package/e2e/app/palette.spec.ts +11 -0
- package/e2e/app/server-default.spec.ts +55 -0
- package/e2e/app/session.spec.ts +16 -0
- package/e2e/app/titlebar-history.spec.ts +42 -0
- package/e2e/files/file-open.spec.ts +18 -0
- package/e2e/files/file-tree.spec.ts +37 -0
- package/e2e/files/file-viewer.spec.ts +26 -0
- package/e2e/fixtures.ts +87 -0
- package/e2e/models/model-picker.spec.ts +42 -0
- package/e2e/models/models-visibility.spec.ts +61 -0
- package/e2e/projects/project-edit.spec.ts +53 -0
- package/e2e/projects/projects-close.spec.ts +74 -0
- package/e2e/projects/projects-switch.spec.ts +35 -0
- package/e2e/projects/workspaces.spec.ts +333 -0
- package/e2e/prompt/context.spec.ts +40 -0
- package/e2e/prompt/prompt-mention.spec.ts +26 -0
- package/e2e/prompt/prompt-slash-open.spec.ts +22 -0
- package/e2e/prompt/prompt.spec.ts +58 -0
- package/e2e/selectors.ts +57 -0
- package/e2e/session/session.spec.ts +157 -0
- package/e2e/settings/settings-keybinds.spec.ts +320 -0
- package/e2e/settings/settings-models.spec.ts +122 -0
- package/e2e/settings/settings-providers.spec.ts +136 -0
- package/e2e/settings/settings.spec.ts +292 -0
- package/e2e/sidebar/sidebar-session-links.spec.ts +31 -0
- package/e2e/sidebar/sidebar.spec.ts +14 -0
- package/e2e/status/status-popover.spec.ts +94 -0
- package/e2e/terminal/terminal-init.spec.ts +26 -0
- package/e2e/terminal/terminal.spec.ts +17 -0
- package/e2e/thinking-level.spec.ts +25 -0
- package/e2e/tsconfig.json +8 -0
- package/e2e/utils.ts +35 -0
- package/happydom.ts +75 -0
- package/index.html +23 -0
- package/package.json +72 -0
- package/playwright.config.ts +43 -0
- package/public/_headers +17 -0
- package/public/oc-theme-preload.js +28 -0
- package/script/e2e-local.ts +140 -0
- package/src/addons/serialize.test.ts +319 -0
- package/src/addons/serialize.ts +634 -0
- package/src/app.tsx +170 -0
- package/src/components/dialog-connect-provider.tsx +456 -0
- package/src/components/dialog-custom-provider.tsx +424 -0
- package/src/components/dialog-edit-project.tsx +245 -0
- package/src/components/dialog-fork.tsx +100 -0
- package/src/components/dialog-manage-models.tsx +76 -0
- package/src/components/dialog-release-notes.tsx +158 -0
- package/src/components/dialog-select-directory.tsx +326 -0
- package/src/components/dialog-select-file.tsx +404 -0
- package/src/components/dialog-select-mcp.tsx +96 -0
- package/src/components/dialog-select-model-unpaid.tsx +132 -0
- package/src/components/dialog-select-model.tsx +271 -0
- package/src/components/dialog-select-provider.tsx +87 -0
- package/src/components/dialog-select-server.tsx +536 -0
- package/src/components/dialog-settings.tsx +82 -0
- package/src/components/file-tree.test.ts +77 -0
- package/src/components/file-tree.tsx +468 -0
- package/src/components/link.tsx +17 -0
- package/src/components/model-tooltip.tsx +91 -0
- package/src/components/prompt-input/attachments.ts +145 -0
- package/src/components/prompt-input/build-request-parts.test.ts +277 -0
- package/src/components/prompt-input/build-request-parts.ts +190 -0
- package/src/components/prompt-input/context-items.tsx +82 -0
- package/src/components/prompt-input/drag-overlay.tsx +20 -0
- package/src/components/prompt-input/editor-dom.test.ts +51 -0
- package/src/components/prompt-input/editor-dom.ts +135 -0
- package/src/components/prompt-input/history.test.ts +69 -0
- package/src/components/prompt-input/history.ts +160 -0
- package/src/components/prompt-input/image-attachments.tsx +51 -0
- package/src/components/prompt-input/placeholder.test.ts +35 -0
- package/src/components/prompt-input/placeholder.ts +13 -0
- package/src/components/prompt-input/slash-popover.tsx +144 -0
- package/src/components/prompt-input/submit.ts +411 -0
- package/src/components/prompt-input.tsx +1199 -0
- package/src/components/question-dock.tsx +295 -0
- package/src/components/server/server-row.tsx +77 -0
- package/src/components/session/index.ts +5 -0
- package/src/components/session/session-context-metrics.test.ts +93 -0
- package/src/components/session/session-context-metrics.ts +94 -0
- package/src/components/session/session-context-tab.tsx +400 -0
- package/src/components/session/session-header.tsx +571 -0
- package/src/components/session/session-new-view.tsx +78 -0
- package/src/components/session/session-sortable-tab.tsx +63 -0
- package/src/components/session/session-sortable-terminal-tab.tsx +190 -0
- package/src/components/session-context-usage.tsx +100 -0
- package/src/components/settings-agents.tsx +15 -0
- package/src/components/settings-commands.tsx +15 -0
- package/src/components/settings-general.tsx +434 -0
- package/src/components/settings-keybinds.tsx +435 -0
- package/src/components/settings-mcp.tsx +15 -0
- package/src/components/settings-models.tsx +130 -0
- package/src/components/settings-permissions.tsx +228 -0
- package/src/components/settings-providers.tsx +264 -0
- package/src/components/status-popover.tsx +371 -0
- package/src/components/terminal.tsx +464 -0
- package/src/components/titlebar-history.test.ts +63 -0
- package/src/components/titlebar-history.ts +57 -0
- package/src/components/titlebar.tsx +261 -0
- package/src/context/command-keybind.test.ts +43 -0
- package/src/context/command.test.ts +25 -0
- package/src/context/command.tsx +365 -0
- package/src/context/comments.test.ts +111 -0
- package/src/context/comments.tsx +185 -0
- package/src/context/file/content-cache.ts +88 -0
- package/src/context/file/path.test.ts +352 -0
- package/src/context/file/path.ts +143 -0
- package/src/context/file/tree-store.ts +170 -0
- package/src/context/file/types.ts +41 -0
- package/src/context/file/view-cache.ts +136 -0
- package/src/context/file/watcher.test.ts +118 -0
- package/src/context/file/watcher.ts +52 -0
- package/src/context/file-content-eviction-accounting.test.ts +65 -0
- package/src/context/file.tsx +263 -0
- package/src/context/global-sdk.tsx +108 -0
- package/src/context/global-sync/bootstrap.ts +195 -0
- package/src/context/global-sync/child-store.ts +263 -0
- package/src/context/global-sync/event-reducer.test.ts +201 -0
- package/src/context/global-sync/event-reducer.ts +319 -0
- package/src/context/global-sync/eviction.ts +28 -0
- package/src/context/global-sync/queue.ts +83 -0
- package/src/context/global-sync/session-load.ts +26 -0
- package/src/context/global-sync/session-trim.test.ts +59 -0
- package/src/context/global-sync/session-trim.ts +56 -0
- package/src/context/global-sync/types.ts +134 -0
- package/src/context/global-sync/utils.ts +25 -0
- package/src/context/global-sync.test.ts +136 -0
- package/src/context/global-sync.tsx +365 -0
- package/src/context/highlights.tsx +225 -0
- package/src/context/language.tsx +226 -0
- package/src/context/layout-scroll.test.ts +36 -0
- package/src/context/layout-scroll.ts +118 -0
- package/src/context/layout.test.ts +69 -0
- package/src/context/layout.tsx +844 -0
- package/src/context/local.tsx +229 -0
- package/src/context/models.tsx +140 -0
- package/src/context/notification-index.ts +66 -0
- package/src/context/notification.test.ts +73 -0
- package/src/context/notification.tsx +199 -0
- package/src/context/permission.tsx +186 -0
- package/src/context/platform.tsx +75 -0
- package/src/context/prompt.tsx +246 -0
- package/src/context/sdk.tsx +48 -0
- package/src/context/server.tsx +208 -0
- package/src/context/settings.tsx +177 -0
- package/src/context/sync-optimistic.test.ts +56 -0
- package/src/context/sync.tsx +358 -0
- package/src/context/terminal.test.ts +38 -0
- package/src/context/terminal.tsx +283 -0
- package/src/entry.tsx +104 -0
- package/src/env.d.ts +8 -0
- package/src/hooks/use-providers.ts +31 -0
- package/src/i18n/ar.ts +716 -0
- package/src/i18n/br.ts +722 -0
- package/src/i18n/bs.ts +749 -0
- package/src/i18n/da.ts +721 -0
- package/src/i18n/de.ts +766 -0
- package/src/i18n/en.ts +792 -0
- package/src/i18n/es.ts +727 -0
- package/src/i18n/fr.ts +733 -0
- package/src/i18n/ja.ts +715 -0
- package/src/i18n/ko.ts +720 -0
- package/src/i18n/no.ts +723 -0
- package/src/i18n/parity.test.ts +31 -0
- package/src/i18n/pl.ts +723 -0
- package/src/i18n/ru.ts +727 -0
- package/src/i18n/th.ts +714 -0
- package/src/i18n/zh.ts +754 -0
- package/src/i18n/zht.ts +752 -0
- package/src/index.css +1 -0
- package/src/index.ts +3 -0
- package/src/pages/directory-layout.tsx +71 -0
- package/src/pages/error.tsx +290 -0
- package/src/pages/home.tsx +126 -0
- package/src/pages/layout/deep-links.ts +26 -0
- package/src/pages/layout/helpers.test.ts +63 -0
- package/src/pages/layout/helpers.ts +65 -0
- package/src/pages/layout/inline-editor.tsx +113 -0
- package/src/pages/layout/sidebar-items.tsx +328 -0
- package/src/pages/layout/sidebar-project-helpers.test.ts +63 -0
- package/src/pages/layout/sidebar-project-helpers.ts +11 -0
- package/src/pages/layout/sidebar-project.tsx +283 -0
- package/src/pages/layout/sidebar-shell-helpers.ts +1 -0
- package/src/pages/layout/sidebar-shell.test.ts +13 -0
- package/src/pages/layout/sidebar-shell.tsx +109 -0
- package/src/pages/layout/sidebar-workspace-helpers.ts +2 -0
- package/src/pages/layout/sidebar-workspace.test.ts +13 -0
- package/src/pages/layout/sidebar-workspace.tsx +410 -0
- package/src/pages/layout.tsx +1996 -0
- package/src/pages/session/file-tab-scroll.test.ts +40 -0
- package/src/pages/session/file-tab-scroll.ts +67 -0
- package/src/pages/session/file-tabs.tsx +516 -0
- package/src/pages/session/helpers.test.ts +61 -0
- package/src/pages/session/helpers.ts +38 -0
- package/src/pages/session/message-gesture.test.ts +62 -0
- package/src/pages/session/message-gesture.ts +21 -0
- package/src/pages/session/message-timeline.tsx +348 -0
- package/src/pages/session/review-tab.tsx +158 -0
- package/src/pages/session/scroll-spy.test.ts +127 -0
- package/src/pages/session/scroll-spy.ts +274 -0
- package/src/pages/session/session-command-helpers.ts +10 -0
- package/src/pages/session/session-mobile-tabs.tsx +36 -0
- package/src/pages/session/session-prompt-dock.test.ts +22 -0
- package/src/pages/session/session-prompt-dock.tsx +137 -0
- package/src/pages/session/session-prompt-helpers.ts +4 -0
- package/src/pages/session/session-side-panel.tsx +319 -0
- package/src/pages/session/terminal-label.ts +16 -0
- package/src/pages/session/terminal-panel.test.ts +25 -0
- package/src/pages/session/terminal-panel.tsx +169 -0
- package/src/pages/session/use-session-commands.test.ts +44 -0
- package/src/pages/session/use-session-commands.tsx +455 -0
- package/src/pages/session/use-session-hash-scroll.test.ts +16 -0
- package/src/pages/session/use-session-hash-scroll.ts +174 -0
- package/src/pages/session.tsx +1755 -0
- package/src/sst-env.d.ts +12 -0
- package/src/utils/agent.ts +11 -0
- package/src/utils/aim.ts +138 -0
- package/src/utils/base64.ts +10 -0
- package/src/utils/dom.ts +51 -0
- package/src/utils/id.ts +99 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/perf.ts +135 -0
- package/src/utils/persist.ts +451 -0
- package/src/utils/prompt.ts +203 -0
- package/src/utils/runtime-adapters.test.ts +62 -0
- package/src/utils/runtime-adapters.ts +39 -0
- package/src/utils/same.ts +6 -0
- package/src/utils/scoped-cache.test.ts +69 -0
- package/src/utils/scoped-cache.ts +104 -0
- package/src/utils/server-health.test.ts +42 -0
- package/src/utils/server-health.ts +29 -0
- package/src/utils/solid-dnd.tsx +55 -0
- package/src/utils/sound.ts +117 -0
- package/src/utils/speech.ts +326 -0
- package/src/utils/time.ts +14 -0
- package/src/utils/worktree.test.ts +46 -0
- package/src/utils/worktree.ts +73 -0
- package/sst-env.d.ts +10 -0
- package/tsconfig.json +26 -0
- package/vite.config.ts +15 -0
- package/vite.js +26 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { test, expect } from "../fixtures"
|
|
2
|
+
import { promptSelector } from "../selectors"
|
|
3
|
+
import { withSession } from "../actions"
|
|
4
|
+
|
|
5
|
+
test("context panel can be opened from the prompt", async ({ page, sdk, gotoSession }) => {
|
|
6
|
+
const title = `e2e smoke context ${Date.now()}`
|
|
7
|
+
|
|
8
|
+
await withSession(sdk, title, async (session) => {
|
|
9
|
+
await sdk.session.promptAsync({
|
|
10
|
+
sessionID: session.id,
|
|
11
|
+
noReply: true,
|
|
12
|
+
parts: [
|
|
13
|
+
{
|
|
14
|
+
type: "text",
|
|
15
|
+
text: "seed context",
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
await expect
|
|
21
|
+
.poll(async () => {
|
|
22
|
+
const messages = await sdk.session.messages({ sessionID: session.id, limit: 1 }).then((r) => r.data ?? [])
|
|
23
|
+
return messages.length
|
|
24
|
+
})
|
|
25
|
+
.toBeGreaterThan(0)
|
|
26
|
+
|
|
27
|
+
await gotoSession(session.id)
|
|
28
|
+
|
|
29
|
+
const contextButton = page
|
|
30
|
+
.locator('[data-component="button"]')
|
|
31
|
+
.filter({ has: page.locator('[data-component="progress-circle"]').first() })
|
|
32
|
+
.first()
|
|
33
|
+
|
|
34
|
+
await expect(contextButton).toBeVisible()
|
|
35
|
+
await contextButton.click()
|
|
36
|
+
|
|
37
|
+
const tabs = page.locator('[data-component="tabs"][data-variant="normal"]')
|
|
38
|
+
await expect(tabs.getByRole("tab", { name: "Context" })).toBeVisible()
|
|
39
|
+
})
|
|
40
|
+
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { test, expect } from "../fixtures"
|
|
2
|
+
import { promptSelector } from "../selectors"
|
|
3
|
+
|
|
4
|
+
test("smoke @mention inserts file pill token", async ({ page, gotoSession }) => {
|
|
5
|
+
await gotoSession()
|
|
6
|
+
|
|
7
|
+
await page.locator(promptSelector).click()
|
|
8
|
+
const sep = process.platform === "win32" ? "\\" : "/"
|
|
9
|
+
const file = ["packages", "app", "package.json"].join(sep)
|
|
10
|
+
const filePattern = /packages[\\/]+app[\\/]+\s*package\.json/
|
|
11
|
+
|
|
12
|
+
await page.keyboard.type(`@${file}`)
|
|
13
|
+
|
|
14
|
+
const suggestion = page.getByRole("button", { name: filePattern }).first()
|
|
15
|
+
await expect(suggestion).toBeVisible()
|
|
16
|
+
await suggestion.hover()
|
|
17
|
+
|
|
18
|
+
await page.keyboard.press("Tab")
|
|
19
|
+
|
|
20
|
+
const pill = page.locator(`${promptSelector} [data-type="file"]`).first()
|
|
21
|
+
await expect(pill).toBeVisible()
|
|
22
|
+
await expect(pill).toHaveAttribute("data-path", filePattern)
|
|
23
|
+
|
|
24
|
+
await page.keyboard.type(" ok")
|
|
25
|
+
await expect(page.locator(promptSelector)).toContainText("ok")
|
|
26
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { test, expect } from "../fixtures"
|
|
2
|
+
import { promptSelector } from "../selectors"
|
|
3
|
+
|
|
4
|
+
test("smoke /open opens file picker dialog", async ({ page, gotoSession }) => {
|
|
5
|
+
await gotoSession()
|
|
6
|
+
|
|
7
|
+
await page.locator(promptSelector).click()
|
|
8
|
+
await page.keyboard.type("/open")
|
|
9
|
+
|
|
10
|
+
const command = page.locator('[data-slash-id="file.open"]')
|
|
11
|
+
await expect(command).toBeVisible()
|
|
12
|
+
await command.hover()
|
|
13
|
+
|
|
14
|
+
await page.keyboard.press("Enter")
|
|
15
|
+
|
|
16
|
+
const dialog = page.getByRole("dialog")
|
|
17
|
+
await expect(dialog).toBeVisible()
|
|
18
|
+
await expect(dialog.getByRole("textbox").first()).toBeVisible()
|
|
19
|
+
|
|
20
|
+
await page.keyboard.press("Escape")
|
|
21
|
+
await expect(dialog).toHaveCount(0)
|
|
22
|
+
})
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { test, expect } from "../fixtures"
|
|
2
|
+
import { promptSelector } from "../selectors"
|
|
3
|
+
import { sessionIDFromUrl, withSession } from "../actions"
|
|
4
|
+
|
|
5
|
+
test("can send a prompt and receive a reply", async ({ page, sdk, gotoSession }) => {
|
|
6
|
+
test.setTimeout(120_000)
|
|
7
|
+
|
|
8
|
+
const pageErrors: string[] = []
|
|
9
|
+
const onPageError = (err: Error) => {
|
|
10
|
+
pageErrors.push(err.message)
|
|
11
|
+
}
|
|
12
|
+
page.on("pageerror", onPageError)
|
|
13
|
+
|
|
14
|
+
await gotoSession()
|
|
15
|
+
|
|
16
|
+
const token = `E2E_OK_${Date.now()}`
|
|
17
|
+
|
|
18
|
+
const prompt = page.locator(promptSelector)
|
|
19
|
+
await prompt.click()
|
|
20
|
+
await page.keyboard.type(`Reply with exactly: ${token}`)
|
|
21
|
+
await page.keyboard.press("Enter")
|
|
22
|
+
|
|
23
|
+
await expect(page).toHaveURL(/\/session\/[^/?#]+/, { timeout: 30_000 })
|
|
24
|
+
|
|
25
|
+
const sessionID = (() => {
|
|
26
|
+
const id = sessionIDFromUrl(page.url())
|
|
27
|
+
if (!id) throw new Error(`Failed to parse session id from url: ${page.url()}`)
|
|
28
|
+
return id
|
|
29
|
+
})()
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
await expect
|
|
33
|
+
.poll(
|
|
34
|
+
async () => {
|
|
35
|
+
const messages = await sdk.session.messages({ sessionID, limit: 50 }).then((r) => r.data ?? [])
|
|
36
|
+
return messages
|
|
37
|
+
.filter((m) => m.info.role === "assistant")
|
|
38
|
+
.flatMap((m) => m.parts)
|
|
39
|
+
.filter((p) => p.type === "text")
|
|
40
|
+
.map((p) => p.text)
|
|
41
|
+
.join("\n")
|
|
42
|
+
},
|
|
43
|
+
{ timeout: 90_000 },
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
.toContain(token)
|
|
47
|
+
|
|
48
|
+
const reply = page.locator('[data-slot="session-turn-summary-section"]').filter({ hasText: token }).first()
|
|
49
|
+
await expect(reply).toBeVisible({ timeout: 90_000 })
|
|
50
|
+
} finally {
|
|
51
|
+
page.off("pageerror", onPageError)
|
|
52
|
+
await sdk.session.delete({ sessionID }).catch(() => undefined)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (pageErrors.length > 0) {
|
|
56
|
+
throw new Error(`Page error(s):\n${pageErrors.join("\n")}`)
|
|
57
|
+
}
|
|
58
|
+
})
|
package/e2e/selectors.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export const promptSelector = '[data-component="prompt-input"]'
|
|
2
|
+
export const terminalSelector = '[data-component="terminal"]'
|
|
3
|
+
|
|
4
|
+
export const modelVariantCycleSelector = '[data-action="model-variant-cycle"]'
|
|
5
|
+
export const settingsLanguageSelectSelector = '[data-action="settings-language"]'
|
|
6
|
+
export const settingsColorSchemeSelector = '[data-action="settings-color-scheme"]'
|
|
7
|
+
export const settingsThemeSelector = '[data-action="settings-theme"]'
|
|
8
|
+
export const settingsFontSelector = '[data-action="settings-font"]'
|
|
9
|
+
export const settingsNotificationsAgentSelector = '[data-action="settings-notifications-agent"]'
|
|
10
|
+
export const settingsNotificationsPermissionsSelector = '[data-action="settings-notifications-permissions"]'
|
|
11
|
+
export const settingsNotificationsErrorsSelector = '[data-action="settings-notifications-errors"]'
|
|
12
|
+
export const settingsSoundsAgentSelector = '[data-action="settings-sounds-agent"]'
|
|
13
|
+
export const settingsSoundsPermissionsSelector = '[data-action="settings-sounds-permissions"]'
|
|
14
|
+
export const settingsSoundsErrorsSelector = '[data-action="settings-sounds-errors"]'
|
|
15
|
+
export const settingsUpdatesStartupSelector = '[data-action="settings-updates-startup"]'
|
|
16
|
+
export const settingsReleaseNotesSelector = '[data-action="settings-release-notes"]'
|
|
17
|
+
|
|
18
|
+
export const sidebarNavSelector = '[data-component="sidebar-nav-desktop"]'
|
|
19
|
+
|
|
20
|
+
export const projectSwitchSelector = (slug: string) =>
|
|
21
|
+
`${sidebarNavSelector} [data-action="project-switch"][data-project="${slug}"]`
|
|
22
|
+
|
|
23
|
+
export const projectCloseHoverSelector = (slug: string) => `[data-action="project-close-hover"][data-project="${slug}"]`
|
|
24
|
+
|
|
25
|
+
export const projectMenuTriggerSelector = (slug: string) =>
|
|
26
|
+
`${sidebarNavSelector} [data-action="project-menu"][data-project="${slug}"]`
|
|
27
|
+
|
|
28
|
+
export const projectCloseMenuSelector = (slug: string) => `[data-action="project-close-menu"][data-project="${slug}"]`
|
|
29
|
+
|
|
30
|
+
export const projectWorkspacesToggleSelector = (slug: string) =>
|
|
31
|
+
`[data-action="project-workspaces-toggle"][data-project="${slug}"]`
|
|
32
|
+
|
|
33
|
+
export const titlebarRightSelector = "#nikcli-titlebar-right"
|
|
34
|
+
|
|
35
|
+
export const popoverBodySelector = '[data-slot="popover-body"]'
|
|
36
|
+
|
|
37
|
+
export const dropdownMenuTriggerSelector = '[data-slot="dropdown-menu-trigger"]'
|
|
38
|
+
|
|
39
|
+
export const dropdownMenuContentSelector = '[data-component="dropdown-menu-content"]'
|
|
40
|
+
|
|
41
|
+
export const inlineInputSelector = '[data-component="inline-input"]'
|
|
42
|
+
|
|
43
|
+
export const sessionItemSelector = (sessionID: string) => `${sidebarNavSelector} [data-session-id="${sessionID}"]`
|
|
44
|
+
|
|
45
|
+
export const workspaceItemSelector = (slug: string) =>
|
|
46
|
+
`${sidebarNavSelector} [data-component="workspace-item"][data-workspace="${slug}"]`
|
|
47
|
+
|
|
48
|
+
export const workspaceMenuTriggerSelector = (slug: string) =>
|
|
49
|
+
`${sidebarNavSelector} [data-action="workspace-menu"][data-workspace="${slug}"]`
|
|
50
|
+
|
|
51
|
+
export const listItemSelector = '[data-slot="list-item"]'
|
|
52
|
+
|
|
53
|
+
export const listItemKeyStartsWithSelector = (prefix: string) => `${listItemSelector}[data-key^="${prefix}"]`
|
|
54
|
+
|
|
55
|
+
export const listItemKeySelector = (key: string) => `${listItemSelector}[data-key="${key}"]`
|
|
56
|
+
|
|
57
|
+
export const keybindButtonSelector = (id: string) => `[data-keybind-id="${id}"]`
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { test, expect } from "../fixtures"
|
|
2
|
+
import {
|
|
3
|
+
openSidebar,
|
|
4
|
+
openSessionMoreMenu,
|
|
5
|
+
clickMenuItem,
|
|
6
|
+
confirmDialog,
|
|
7
|
+
openSharePopover,
|
|
8
|
+
withSession,
|
|
9
|
+
} from "../actions"
|
|
10
|
+
import { sessionItemSelector, inlineInputSelector } from "../selectors"
|
|
11
|
+
|
|
12
|
+
const shareDisabled = process.env.NIKCLI_DISABLE_SHARE === "true" || process.env.NIKCLI_DISABLE_SHARE === "1"
|
|
13
|
+
|
|
14
|
+
type Sdk = Parameters<typeof withSession>[0]
|
|
15
|
+
|
|
16
|
+
async function seedMessage(sdk: Sdk, sessionID: string) {
|
|
17
|
+
await sdk.session.promptAsync({
|
|
18
|
+
sessionID,
|
|
19
|
+
noReply: true,
|
|
20
|
+
parts: [{ type: "text", text: "e2e seed" }],
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
await expect
|
|
24
|
+
.poll(
|
|
25
|
+
async () => {
|
|
26
|
+
const messages = await sdk.session.messages({ sessionID, limit: 1 }).then((r) => r.data ?? [])
|
|
27
|
+
return messages.length
|
|
28
|
+
},
|
|
29
|
+
{ timeout: 30_000 },
|
|
30
|
+
)
|
|
31
|
+
.toBeGreaterThan(0)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
test("session can be renamed via header menu", async ({ page, sdk, gotoSession }) => {
|
|
35
|
+
const stamp = Date.now()
|
|
36
|
+
const originalTitle = `e2e rename test ${stamp}`
|
|
37
|
+
const newTitle = `e2e renamed ${stamp}`
|
|
38
|
+
|
|
39
|
+
await withSession(sdk, originalTitle, async (session) => {
|
|
40
|
+
await seedMessage(sdk, session.id)
|
|
41
|
+
await gotoSession(session.id)
|
|
42
|
+
|
|
43
|
+
const menu = await openSessionMoreMenu(page, session.id)
|
|
44
|
+
await clickMenuItem(menu, /rename/i)
|
|
45
|
+
|
|
46
|
+
const input = page.locator(".session-scroller").locator(inlineInputSelector).first()
|
|
47
|
+
await expect(input).toBeVisible()
|
|
48
|
+
await input.fill(newTitle)
|
|
49
|
+
await input.press("Enter")
|
|
50
|
+
|
|
51
|
+
await expect(page.getByRole("heading", { level: 1 }).first()).toContainText(newTitle)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test("session can be archived via header menu", async ({ page, sdk, gotoSession }) => {
|
|
56
|
+
const stamp = Date.now()
|
|
57
|
+
const title = `e2e archive test ${stamp}`
|
|
58
|
+
|
|
59
|
+
await withSession(sdk, title, async (session) => {
|
|
60
|
+
await seedMessage(sdk, session.id)
|
|
61
|
+
await gotoSession(session.id)
|
|
62
|
+
const menu = await openSessionMoreMenu(page, session.id)
|
|
63
|
+
await clickMenuItem(menu, /archive/i)
|
|
64
|
+
|
|
65
|
+
await expect
|
|
66
|
+
.poll(
|
|
67
|
+
async () => {
|
|
68
|
+
const data = await sdk.session.get({ sessionID: session.id }).then((r) => r.data)
|
|
69
|
+
return data?.time?.archived
|
|
70
|
+
},
|
|
71
|
+
{ timeout: 30_000 },
|
|
72
|
+
)
|
|
73
|
+
.not.toBeUndefined()
|
|
74
|
+
|
|
75
|
+
await openSidebar(page)
|
|
76
|
+
await expect(page.locator(sessionItemSelector(session.id))).toHaveCount(0)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test("session can be deleted via header menu", async ({ page, sdk, gotoSession }) => {
|
|
81
|
+
const stamp = Date.now()
|
|
82
|
+
const title = `e2e delete test ${stamp}`
|
|
83
|
+
|
|
84
|
+
await withSession(sdk, title, async (session) => {
|
|
85
|
+
await seedMessage(sdk, session.id)
|
|
86
|
+
await gotoSession(session.id)
|
|
87
|
+
const menu = await openSessionMoreMenu(page, session.id)
|
|
88
|
+
await clickMenuItem(menu, /delete/i)
|
|
89
|
+
await confirmDialog(page, /delete/i)
|
|
90
|
+
|
|
91
|
+
await expect
|
|
92
|
+
.poll(
|
|
93
|
+
async () => {
|
|
94
|
+
const data = await sdk.session
|
|
95
|
+
.get({ sessionID: session.id })
|
|
96
|
+
.then((r) => r.data)
|
|
97
|
+
.catch(() => undefined)
|
|
98
|
+
return data?.id
|
|
99
|
+
},
|
|
100
|
+
{ timeout: 30_000 },
|
|
101
|
+
)
|
|
102
|
+
.toBeUndefined()
|
|
103
|
+
|
|
104
|
+
await openSidebar(page)
|
|
105
|
+
await expect(page.locator(sessionItemSelector(session.id))).toHaveCount(0)
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
test("session can be shared and unshared via header button", async ({ page, sdk, gotoSession }) => {
|
|
110
|
+
test.skip(shareDisabled, "Share is disabled in this environment (NIKCLI_DISABLE_SHARE).")
|
|
111
|
+
|
|
112
|
+
const stamp = Date.now()
|
|
113
|
+
const title = `e2e share test ${stamp}`
|
|
114
|
+
|
|
115
|
+
await withSession(sdk, title, async (session) => {
|
|
116
|
+
await seedMessage(sdk, session.id)
|
|
117
|
+
await gotoSession(session.id)
|
|
118
|
+
|
|
119
|
+
const { rightSection, popoverBody } = await openSharePopover(page)
|
|
120
|
+
await popoverBody.getByRole("button", { name: "Publish" }).first().click()
|
|
121
|
+
|
|
122
|
+
await expect
|
|
123
|
+
.poll(
|
|
124
|
+
async () => {
|
|
125
|
+
const data = await sdk.session.get({ sessionID: session.id }).then((r) => r.data)
|
|
126
|
+
return data?.share?.url || undefined
|
|
127
|
+
},
|
|
128
|
+
{ timeout: 30_000 },
|
|
129
|
+
)
|
|
130
|
+
.not.toBeUndefined()
|
|
131
|
+
|
|
132
|
+
const copyButton = rightSection.locator('button[aria-label="Copy link"]').first()
|
|
133
|
+
await expect(copyButton).toBeVisible({ timeout: 30_000 })
|
|
134
|
+
|
|
135
|
+
const sharedPopover = await openSharePopover(page)
|
|
136
|
+
const unpublish = sharedPopover.popoverBody.getByRole("button", { name: "Unpublish" }).first()
|
|
137
|
+
await expect(unpublish).toBeVisible({ timeout: 30_000 })
|
|
138
|
+
await unpublish.click()
|
|
139
|
+
|
|
140
|
+
await expect
|
|
141
|
+
.poll(
|
|
142
|
+
async () => {
|
|
143
|
+
const data = await sdk.session.get({ sessionID: session.id }).then((r) => r.data)
|
|
144
|
+
return data?.share?.url || undefined
|
|
145
|
+
},
|
|
146
|
+
{ timeout: 30_000 },
|
|
147
|
+
)
|
|
148
|
+
.toBeUndefined()
|
|
149
|
+
|
|
150
|
+
await expect(copyButton).not.toBeVisible({ timeout: 30_000 })
|
|
151
|
+
|
|
152
|
+
const unsharedPopover = await openSharePopover(page)
|
|
153
|
+
await expect(unsharedPopover.popoverBody.getByRole("button", { name: "Publish" }).first()).toBeVisible({
|
|
154
|
+
timeout: 30_000,
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
})
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { test, expect } from "../fixtures"
|
|
2
|
+
import { openSettings, closeDialog, withSession } from "../actions"
|
|
3
|
+
import { keybindButtonSelector, terminalSelector } from "../selectors"
|
|
4
|
+
import { modKey } from "../utils"
|
|
5
|
+
|
|
6
|
+
test("changing sidebar toggle keybind works", async ({ page, gotoSession }) => {
|
|
7
|
+
await gotoSession()
|
|
8
|
+
|
|
9
|
+
const dialog = await openSettings(page)
|
|
10
|
+
await dialog.getByRole("tab", { name: "Shortcuts" }).click()
|
|
11
|
+
|
|
12
|
+
const keybindButton = dialog.locator(keybindButtonSelector("sidebar.toggle"))
|
|
13
|
+
await expect(keybindButton).toBeVisible()
|
|
14
|
+
|
|
15
|
+
const initialKeybind = await keybindButton.textContent()
|
|
16
|
+
expect(initialKeybind).toContain("B")
|
|
17
|
+
|
|
18
|
+
await keybindButton.click()
|
|
19
|
+
await expect(keybindButton).toHaveText(/press/i)
|
|
20
|
+
|
|
21
|
+
await page.keyboard.press(`${modKey}+Shift+KeyH`)
|
|
22
|
+
await page.waitForTimeout(100)
|
|
23
|
+
|
|
24
|
+
const newKeybind = await keybindButton.textContent()
|
|
25
|
+
expect(newKeybind).toContain("H")
|
|
26
|
+
|
|
27
|
+
const stored = await page.evaluate(() => {
|
|
28
|
+
const raw = localStorage.getItem("settings.v3")
|
|
29
|
+
return raw ? JSON.parse(raw) : null
|
|
30
|
+
})
|
|
31
|
+
expect(stored?.keybinds?.["sidebar.toggle"]).toBe("mod+shift+h")
|
|
32
|
+
|
|
33
|
+
await closeDialog(page, dialog)
|
|
34
|
+
|
|
35
|
+
const main = page.locator("main")
|
|
36
|
+
const initialClasses = (await main.getAttribute("class")) ?? ""
|
|
37
|
+
const initiallyClosed = initialClasses.includes("xl:border-l")
|
|
38
|
+
|
|
39
|
+
await page.keyboard.press(`${modKey}+Shift+H`)
|
|
40
|
+
await page.waitForTimeout(100)
|
|
41
|
+
|
|
42
|
+
const afterToggleClasses = (await main.getAttribute("class")) ?? ""
|
|
43
|
+
const afterToggleClosed = afterToggleClasses.includes("xl:border-l")
|
|
44
|
+
expect(afterToggleClosed).toBe(!initiallyClosed)
|
|
45
|
+
|
|
46
|
+
await page.keyboard.press(`${modKey}+Shift+H`)
|
|
47
|
+
await page.waitForTimeout(100)
|
|
48
|
+
|
|
49
|
+
const finalClasses = (await main.getAttribute("class")) ?? ""
|
|
50
|
+
const finalClosed = finalClasses.includes("xl:border-l")
|
|
51
|
+
expect(finalClosed).toBe(initiallyClosed)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test("resetting all keybinds to defaults works", async ({ page, gotoSession }) => {
|
|
55
|
+
await page.addInitScript(() => {
|
|
56
|
+
localStorage.setItem("settings.v3", JSON.stringify({ keybinds: { "sidebar.toggle": "mod+shift+x" } }))
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
await gotoSession()
|
|
60
|
+
|
|
61
|
+
const dialog = await openSettings(page)
|
|
62
|
+
await dialog.getByRole("tab", { name: "Shortcuts" }).click()
|
|
63
|
+
|
|
64
|
+
const keybindButton = dialog.locator(keybindButtonSelector("sidebar.toggle"))
|
|
65
|
+
await expect(keybindButton).toBeVisible()
|
|
66
|
+
|
|
67
|
+
const customKeybind = await keybindButton.textContent()
|
|
68
|
+
expect(customKeybind).toContain("X")
|
|
69
|
+
|
|
70
|
+
const resetButton = dialog.getByRole("button", { name: "Reset to defaults" })
|
|
71
|
+
await expect(resetButton).toBeVisible()
|
|
72
|
+
await expect(resetButton).toBeEnabled()
|
|
73
|
+
await resetButton.click()
|
|
74
|
+
await page.waitForTimeout(100)
|
|
75
|
+
|
|
76
|
+
const restoredKeybind = await keybindButton.textContent()
|
|
77
|
+
expect(restoredKeybind).toContain("B")
|
|
78
|
+
|
|
79
|
+
const stored = await page.evaluate(() => {
|
|
80
|
+
const raw = localStorage.getItem("settings.v3")
|
|
81
|
+
return raw ? JSON.parse(raw) : null
|
|
82
|
+
})
|
|
83
|
+
expect(stored?.keybinds?.["sidebar.toggle"]).toBeUndefined()
|
|
84
|
+
|
|
85
|
+
await closeDialog(page, dialog)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
test("clearing a keybind works", async ({ page, gotoSession }) => {
|
|
89
|
+
await gotoSession()
|
|
90
|
+
|
|
91
|
+
const dialog = await openSettings(page)
|
|
92
|
+
await dialog.getByRole("tab", { name: "Shortcuts" }).click()
|
|
93
|
+
|
|
94
|
+
const keybindButton = dialog.locator(keybindButtonSelector("sidebar.toggle"))
|
|
95
|
+
await expect(keybindButton).toBeVisible()
|
|
96
|
+
|
|
97
|
+
const initialKeybind = await keybindButton.textContent()
|
|
98
|
+
expect(initialKeybind).toContain("B")
|
|
99
|
+
|
|
100
|
+
await keybindButton.click()
|
|
101
|
+
await expect(keybindButton).toHaveText(/press/i)
|
|
102
|
+
|
|
103
|
+
await page.keyboard.press("Delete")
|
|
104
|
+
await page.waitForTimeout(100)
|
|
105
|
+
|
|
106
|
+
const clearedKeybind = await keybindButton.textContent()
|
|
107
|
+
expect(clearedKeybind).toMatch(/unassigned|press/i)
|
|
108
|
+
|
|
109
|
+
const stored = await page.evaluate(() => {
|
|
110
|
+
const raw = localStorage.getItem("settings.v3")
|
|
111
|
+
return raw ? JSON.parse(raw) : null
|
|
112
|
+
})
|
|
113
|
+
expect(stored?.keybinds?.["sidebar.toggle"]).toBe("none")
|
|
114
|
+
|
|
115
|
+
await closeDialog(page, dialog)
|
|
116
|
+
|
|
117
|
+
await page.keyboard.press(`${modKey}+B`)
|
|
118
|
+
await page.waitForTimeout(100)
|
|
119
|
+
|
|
120
|
+
const stillOnSession = page.url().includes("/session")
|
|
121
|
+
expect(stillOnSession).toBe(true)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
test("changing settings open keybind works", async ({ page, gotoSession }) => {
|
|
125
|
+
await gotoSession()
|
|
126
|
+
|
|
127
|
+
const dialog = await openSettings(page)
|
|
128
|
+
await dialog.getByRole("tab", { name: "Shortcuts" }).click()
|
|
129
|
+
|
|
130
|
+
const keybindButton = dialog.locator(keybindButtonSelector("settings.open"))
|
|
131
|
+
await expect(keybindButton).toBeVisible()
|
|
132
|
+
|
|
133
|
+
const initialKeybind = await keybindButton.textContent()
|
|
134
|
+
expect(initialKeybind).toContain(",")
|
|
135
|
+
|
|
136
|
+
await keybindButton.click()
|
|
137
|
+
await expect(keybindButton).toHaveText(/press/i)
|
|
138
|
+
|
|
139
|
+
await page.keyboard.press(`${modKey}+Slash`)
|
|
140
|
+
await page.waitForTimeout(100)
|
|
141
|
+
|
|
142
|
+
const newKeybind = await keybindButton.textContent()
|
|
143
|
+
expect(newKeybind).toContain("/")
|
|
144
|
+
|
|
145
|
+
const stored = await page.evaluate(() => {
|
|
146
|
+
const raw = localStorage.getItem("settings.v3")
|
|
147
|
+
return raw ? JSON.parse(raw) : null
|
|
148
|
+
})
|
|
149
|
+
expect(stored?.keybinds?.["settings.open"]).toBe("mod+/")
|
|
150
|
+
|
|
151
|
+
await closeDialog(page, dialog)
|
|
152
|
+
|
|
153
|
+
const settingsDialog = page.getByRole("dialog")
|
|
154
|
+
await expect(settingsDialog).toHaveCount(0)
|
|
155
|
+
|
|
156
|
+
await page.keyboard.press(`${modKey}+Slash`)
|
|
157
|
+
await page.waitForTimeout(100)
|
|
158
|
+
|
|
159
|
+
await expect(settingsDialog).toBeVisible()
|
|
160
|
+
|
|
161
|
+
await closeDialog(page, settingsDialog)
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
test("changing new session keybind works", async ({ page, sdk, gotoSession }) => {
|
|
165
|
+
await withSession(sdk, "test session for keybind", async (session) => {
|
|
166
|
+
await gotoSession(session.id)
|
|
167
|
+
|
|
168
|
+
const initialUrl = page.url()
|
|
169
|
+
expect(initialUrl).toContain(`/session/${session.id}`)
|
|
170
|
+
|
|
171
|
+
const dialog = await openSettings(page)
|
|
172
|
+
await dialog.getByRole("tab", { name: "Shortcuts" }).click()
|
|
173
|
+
|
|
174
|
+
const keybindButton = dialog.locator(keybindButtonSelector("session.new"))
|
|
175
|
+
await expect(keybindButton).toBeVisible()
|
|
176
|
+
|
|
177
|
+
await keybindButton.click()
|
|
178
|
+
await expect(keybindButton).toHaveText(/press/i)
|
|
179
|
+
|
|
180
|
+
await page.keyboard.press(`${modKey}+Shift+KeyN`)
|
|
181
|
+
await page.waitForTimeout(100)
|
|
182
|
+
|
|
183
|
+
const newKeybind = await keybindButton.textContent()
|
|
184
|
+
expect(newKeybind).toContain("N")
|
|
185
|
+
|
|
186
|
+
const stored = await page.evaluate(() => {
|
|
187
|
+
const raw = localStorage.getItem("settings.v3")
|
|
188
|
+
return raw ? JSON.parse(raw) : null
|
|
189
|
+
})
|
|
190
|
+
expect(stored?.keybinds?.["session.new"]).toBe("mod+shift+n")
|
|
191
|
+
|
|
192
|
+
await closeDialog(page, dialog)
|
|
193
|
+
|
|
194
|
+
await page.keyboard.press(`${modKey}+Shift+N`)
|
|
195
|
+
await page.waitForTimeout(200)
|
|
196
|
+
|
|
197
|
+
const newUrl = page.url()
|
|
198
|
+
expect(newUrl).toMatch(/\/session\/?$/)
|
|
199
|
+
expect(newUrl).not.toContain(session.id)
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
test("changing file open keybind works", async ({ page, gotoSession }) => {
|
|
204
|
+
await gotoSession()
|
|
205
|
+
|
|
206
|
+
const dialog = await openSettings(page)
|
|
207
|
+
await dialog.getByRole("tab", { name: "Shortcuts" }).click()
|
|
208
|
+
|
|
209
|
+
const keybindButton = dialog.locator(keybindButtonSelector("file.open"))
|
|
210
|
+
await expect(keybindButton).toBeVisible()
|
|
211
|
+
|
|
212
|
+
const initialKeybind = await keybindButton.textContent()
|
|
213
|
+
expect(initialKeybind).toContain("P")
|
|
214
|
+
|
|
215
|
+
await keybindButton.click()
|
|
216
|
+
await expect(keybindButton).toHaveText(/press/i)
|
|
217
|
+
|
|
218
|
+
await page.keyboard.press(`${modKey}+Shift+KeyF`)
|
|
219
|
+
await page.waitForTimeout(100)
|
|
220
|
+
|
|
221
|
+
const newKeybind = await keybindButton.textContent()
|
|
222
|
+
expect(newKeybind).toContain("F")
|
|
223
|
+
|
|
224
|
+
const stored = await page.evaluate(() => {
|
|
225
|
+
const raw = localStorage.getItem("settings.v3")
|
|
226
|
+
return raw ? JSON.parse(raw) : null
|
|
227
|
+
})
|
|
228
|
+
expect(stored?.keybinds?.["file.open"]).toBe("mod+shift+f")
|
|
229
|
+
|
|
230
|
+
await closeDialog(page, dialog)
|
|
231
|
+
|
|
232
|
+
const filePickerDialog = page.getByRole("dialog").filter({ has: page.getByPlaceholder(/search files/i) })
|
|
233
|
+
await expect(filePickerDialog).toHaveCount(0)
|
|
234
|
+
|
|
235
|
+
await page.keyboard.press(`${modKey}+Shift+F`)
|
|
236
|
+
await page.waitForTimeout(100)
|
|
237
|
+
|
|
238
|
+
await expect(filePickerDialog).toBeVisible()
|
|
239
|
+
|
|
240
|
+
await page.keyboard.press("Escape")
|
|
241
|
+
await expect(filePickerDialog).toHaveCount(0)
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
test("changing terminal toggle keybind works", async ({ page, gotoSession }) => {
|
|
245
|
+
await gotoSession()
|
|
246
|
+
|
|
247
|
+
const dialog = await openSettings(page)
|
|
248
|
+
await dialog.getByRole("tab", { name: "Shortcuts" }).click()
|
|
249
|
+
|
|
250
|
+
const keybindButton = dialog.locator(keybindButtonSelector("terminal.toggle"))
|
|
251
|
+
await expect(keybindButton).toBeVisible()
|
|
252
|
+
|
|
253
|
+
await keybindButton.click()
|
|
254
|
+
await expect(keybindButton).toHaveText(/press/i)
|
|
255
|
+
|
|
256
|
+
await page.keyboard.press(`${modKey}+KeyY`)
|
|
257
|
+
await page.waitForTimeout(100)
|
|
258
|
+
|
|
259
|
+
const newKeybind = await keybindButton.textContent()
|
|
260
|
+
expect(newKeybind).toContain("Y")
|
|
261
|
+
|
|
262
|
+
const stored = await page.evaluate(() => {
|
|
263
|
+
const raw = localStorage.getItem("settings.v3")
|
|
264
|
+
return raw ? JSON.parse(raw) : null
|
|
265
|
+
})
|
|
266
|
+
expect(stored?.keybinds?.["terminal.toggle"]).toBe("mod+y")
|
|
267
|
+
|
|
268
|
+
await closeDialog(page, dialog)
|
|
269
|
+
|
|
270
|
+
const terminal = page.locator(terminalSelector)
|
|
271
|
+
await expect(terminal).not.toBeVisible()
|
|
272
|
+
|
|
273
|
+
await page.keyboard.press(`${modKey}+Y`)
|
|
274
|
+
await expect(terminal).toBeVisible()
|
|
275
|
+
|
|
276
|
+
await page.keyboard.press(`${modKey}+Y`)
|
|
277
|
+
await expect(terminal).not.toBeVisible()
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
test("changing command palette keybind works", async ({ page, gotoSession }) => {
|
|
281
|
+
await gotoSession()
|
|
282
|
+
|
|
283
|
+
const dialog = await openSettings(page)
|
|
284
|
+
await dialog.getByRole("tab", { name: "Shortcuts" }).click()
|
|
285
|
+
|
|
286
|
+
const keybindButton = dialog.locator(keybindButtonSelector("command.palette"))
|
|
287
|
+
await expect(keybindButton).toBeVisible()
|
|
288
|
+
|
|
289
|
+
const initialKeybind = await keybindButton.textContent()
|
|
290
|
+
expect(initialKeybind).toContain("P")
|
|
291
|
+
|
|
292
|
+
await keybindButton.click()
|
|
293
|
+
await expect(keybindButton).toHaveText(/press/i)
|
|
294
|
+
|
|
295
|
+
await page.keyboard.press(`${modKey}+Shift+KeyK`)
|
|
296
|
+
await page.waitForTimeout(100)
|
|
297
|
+
|
|
298
|
+
const newKeybind = await keybindButton.textContent()
|
|
299
|
+
expect(newKeybind).toContain("K")
|
|
300
|
+
|
|
301
|
+
const stored = await page.evaluate(() => {
|
|
302
|
+
const raw = localStorage.getItem("settings.v3")
|
|
303
|
+
return raw ? JSON.parse(raw) : null
|
|
304
|
+
})
|
|
305
|
+
expect(stored?.keybinds?.["command.palette"]).toBe("mod+shift+k")
|
|
306
|
+
|
|
307
|
+
await closeDialog(page, dialog)
|
|
308
|
+
|
|
309
|
+
const palette = page.getByRole("dialog").filter({ has: page.getByRole("textbox").first() })
|
|
310
|
+
await expect(palette).toHaveCount(0)
|
|
311
|
+
|
|
312
|
+
await page.keyboard.press(`${modKey}+Shift+K`)
|
|
313
|
+
await page.waitForTimeout(100)
|
|
314
|
+
|
|
315
|
+
await expect(palette).toBeVisible()
|
|
316
|
+
await expect(palette.getByRole("textbox").first()).toBeVisible()
|
|
317
|
+
|
|
318
|
+
await page.keyboard.press("Escape")
|
|
319
|
+
await expect(palette).toHaveCount(0)
|
|
320
|
+
})
|