kanna-code 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/assets/abap-BdImnpbu.js +1 -0
- package/dist/client/assets/actionscript-3-CoDkCxhg.js +1 -0
- package/dist/client/assets/ada-bCR0ucgS.js +1 -0
- package/dist/client/assets/andromeeda-C4gqWexZ.js +1 -0
- package/dist/client/assets/angular-html-CU67Zn6k.js +1 -0
- package/dist/client/assets/angular-ts-BwZT4LLn.js +1 -0
- package/dist/client/assets/apache-Pmp26Uib.js +1 -0
- package/dist/client/assets/apex-D8_7TLub.js +1 -0
- package/dist/client/assets/apl-dKokRX4l.js +1 -0
- package/dist/client/assets/applescript-Co6uUVPk.js +1 -0
- package/dist/client/assets/ara-BRHolxvo.js +1 -0
- package/dist/client/assets/asciidoc-Ve4PFQV2.js +1 -0
- package/dist/client/assets/asm-D_Q5rh1f.js +1 -0
- package/dist/client/assets/astro-CbQHKStN.js +1 -0
- package/dist/client/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/dist/client/assets/awk-DMzUqQB5.js +1 -0
- package/dist/client/assets/ayu-dark-DYE7WIF3.js +1 -0
- package/dist/client/assets/ayu-light-BA47KaF1.js +1 -0
- package/dist/client/assets/ayu-mirage-32ctXXKs.js +1 -0
- package/dist/client/assets/ballerina-BFfxhgS-.js +1 -0
- package/dist/client/assets/bat-BkioyH1T.js +1 -0
- package/dist/client/assets/beancount-k_qm7-4y.js +1 -0
- package/dist/client/assets/berry-uYugtg8r.js +1 -0
- package/dist/client/assets/bibtex-CHM0blh-.js +1 -0
- package/dist/client/assets/bicep-Bmn6On1c.js +1 -0
- package/dist/client/assets/bird2-DPOp833l.js +1 -0
- package/dist/client/assets/blade-D4QpJJKB.js +1 -0
- package/dist/client/assets/bsl-BO_Y6i37.js +1 -0
- package/dist/client/assets/c-BIGW1oBm.js +1 -0
- package/dist/client/assets/c3-eo99z4R2.js +1 -0
- package/dist/client/assets/cadence-Bv_4Rxtq.js +1 -0
- package/dist/client/assets/cairo-KRGpt6FW.js +1 -0
- package/dist/client/assets/catppuccin-frappe-DFWUc33u.js +1 -0
- package/dist/client/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
- package/dist/client/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
- package/dist/client/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
- package/dist/client/assets/clarity-D53aC0YG.js +1 -0
- package/dist/client/assets/clojure-P80f7IUj.js +1 -0
- package/dist/client/assets/cmake-D1j8_8rp.js +1 -0
- package/dist/client/assets/cobol-nwyudZeR.js +1 -0
- package/dist/client/assets/codeowners-Bp6g37R7.js +1 -0
- package/dist/client/assets/codeql-DsOJ9woJ.js +1 -0
- package/dist/client/assets/coffee-Ch7k5sss.js +1 -0
- package/dist/client/assets/common-lisp-Cg-RD9OK.js +1 -0
- package/dist/client/assets/coq-DkFqJrB1.js +1 -0
- package/dist/client/assets/cpp-CofmeUqb.js +1 -0
- package/dist/client/assets/crystal-tKQVLTB8.js +1 -0
- package/dist/client/assets/csharp-COcwbKMJ.js +1 -0
- package/dist/client/assets/css-DPfMkruS.js +1 -0
- package/dist/client/assets/csv-fuZLfV_i.js +1 -0
- package/dist/client/assets/cue-D82EKSYY.js +1 -0
- package/dist/client/assets/cypher-COkxafJQ.js +1 -0
- package/dist/client/assets/d-85-TOEBH.js +1 -0
- package/dist/client/assets/dark-plus-C3mMm8J8.js +1 -0
- package/dist/client/assets/dart-CF10PKvl.js +1 -0
- package/dist/client/assets/dax-CEL-wOlO.js +1 -0
- package/dist/client/assets/desktop-BmXAJ9_W.js +1 -0
- package/dist/client/assets/diff-D97Zzqfu.js +1 -0
- package/dist/client/assets/docker-BcOcwvcX.js +1 -0
- package/dist/client/assets/dotenv-Da5cRb03.js +1 -0
- package/dist/client/assets/dracula-BzJJZx-M.js +1 -0
- package/dist/client/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/dist/client/assets/dream-maker-BtqSS_iP.js +1 -0
- package/dist/client/assets/edge-BkV0erSs.js +1 -0
- package/dist/client/assets/elixir-CDX3lj18.js +1 -0
- package/dist/client/assets/elm-DbKCFpqz.js +1 -0
- package/dist/client/assets/emacs-lisp-C9XAeP06.js +1 -0
- package/dist/client/assets/erb-B12qg9BL.js +1 -0
- package/dist/client/assets/erlang-DsQrWhSR.js +1 -0
- package/dist/client/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/dist/client/assets/everforest-light-C8M2exoo.js +1 -0
- package/dist/client/assets/fennel-BYunw83y.js +1 -0
- package/dist/client/assets/fish-BvzEVeQv.js +1 -0
- package/dist/client/assets/fluent-C4IJs8-o.js +1 -0
- package/dist/client/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
- package/dist/client/assets/fortran-free-form-BxgE0vQu.js +1 -0
- package/dist/client/assets/fsharp-CXgrBDvD.js +1 -0
- package/dist/client/assets/gdresource-BOOCDP_w.js +1 -0
- package/dist/client/assets/gdscript-C5YyOfLZ.js +1 -0
- package/dist/client/assets/gdshader-DkwncUOv.js +1 -0
- package/dist/client/assets/genie-D0YGMca9.js +1 -0
- package/dist/client/assets/gherkin-DyxjwDmM.js +1 -0
- package/dist/client/assets/git-commit-F4YmCXRG.js +1 -0
- package/dist/client/assets/git-rebase-r7XF79zn.js +1 -0
- package/dist/client/assets/github-dark-DHJKELXO.js +1 -0
- package/dist/client/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/dist/client/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/dist/client/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/dist/client/assets/github-light-DAi9KRSo.js +1 -0
- package/dist/client/assets/github-light-default-D7oLnXFd.js +1 -0
- package/dist/client/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/dist/client/assets/gleam-BspZqrRM.js +1 -0
- package/dist/client/assets/glimmer-js-Rg0-pVw9.js +1 -0
- package/dist/client/assets/glimmer-ts-U6CK756n.js +1 -0
- package/dist/client/assets/glsl-DplSGwfg.js +1 -0
- package/dist/client/assets/gn-n2N0HUVH.js +1 -0
- package/dist/client/assets/gnuplot-DdkO51Og.js +1 -0
- package/dist/client/assets/go-CxLEBnE3.js +1 -0
- package/dist/client/assets/graphql-ChdNCCLP.js +1 -0
- package/dist/client/assets/groovy-gcz8RCvz.js +1 -0
- package/dist/client/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
- package/dist/client/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
- package/dist/client/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
- package/dist/client/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
- package/dist/client/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
- package/dist/client/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
- package/dist/client/assets/hack-CaT9iCJl.js +1 -0
- package/dist/client/assets/haml-B8DHNrY2.js +1 -0
- package/dist/client/assets/handlebars-BL8al0AC.js +1 -0
- package/dist/client/assets/haskell-Df6bDoY_.js +1 -0
- package/dist/client/assets/haxe-CzTSHFRz.js +1 -0
- package/dist/client/assets/hcl-BWvSN4gD.js +1 -0
- package/dist/client/assets/hjson-D5-asLiD.js +1 -0
- package/dist/client/assets/hlsl-D3lLCCz7.js +1 -0
- package/dist/client/assets/horizon-BUw7H-hv.js +1 -0
- package/dist/client/assets/horizon-bright-Cn-bp-IR.js +1 -0
- package/dist/client/assets/houston-DnULxvSX.js +1 -0
- package/dist/client/assets/html-GMplVEZG.js +1 -0
- package/dist/client/assets/html-derivative-BFtXZ54Q.js +1 -0
- package/dist/client/assets/http-jrhK8wxY.js +1 -0
- package/dist/client/assets/hurl-irOxFIW8.js +1 -0
- package/dist/client/assets/hxml-Bvhsp5Yf.js +1 -0
- package/dist/client/assets/hy-DFXneXwc.js +1 -0
- package/dist/client/assets/imba-DGztddWO.js +1 -0
- package/dist/client/assets/index-B-8fHyaU.css +32 -0
- package/dist/client/assets/index-DrUC3AGz.js +2502 -0
- package/dist/client/assets/ini-BEwlwnbL.js +1 -0
- package/dist/client/assets/java-CylS5w8V.js +1 -0
- package/dist/client/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/client/assets/jinja-4LBKfQ-Z.js +1 -0
- package/dist/client/assets/jison-wvAkD_A8.js +1 -0
- package/dist/client/assets/json-Cp-IABpG.js +1 -0
- package/dist/client/assets/json5-C9tS-k6U.js +1 -0
- package/dist/client/assets/jsonc-Des-eS-w.js +1 -0
- package/dist/client/assets/jsonl-DcaNXYhu.js +1 -0
- package/dist/client/assets/jsonnet-DFQXde-d.js +1 -0
- package/dist/client/assets/jssm-C2t-YnRu.js +1 -0
- package/dist/client/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/client/assets/julia-CxzCAyBv.js +1 -0
- package/dist/client/assets/just-Cw27pwNe.js +1 -0
- package/dist/client/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
- package/dist/client/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
- package/dist/client/assets/kanagawa-wave-DWedfzmr.js +1 -0
- package/dist/client/assets/kdl-DV7GczEv.js +1 -0
- package/dist/client/assets/kotlin-BdnUsdx6.js +1 -0
- package/dist/client/assets/kusto-DZf3V79B.js +1 -0
- package/dist/client/assets/laserwave-DUszq2jm.js +1 -0
- package/dist/client/assets/latex-CWtU0Tv5.js +1 -0
- package/dist/client/assets/lean-BZvkOJ9d.js +1 -0
- package/dist/client/assets/less-B1dDrJ26.js +1 -0
- package/dist/client/assets/light-plus-B7mTdjB0.js +1 -0
- package/dist/client/assets/liquid-DYVedYrR.js +1 -0
- package/dist/client/assets/llvm-DjAJT7YJ.js +1 -0
- package/dist/client/assets/log-2UxHyX5q.js +1 -0
- package/dist/client/assets/logo-BtOb2qkB.js +1 -0
- package/dist/client/assets/lua-BaeVxFsk.js +1 -0
- package/dist/client/assets/luau-C-HG3fhB.js +1 -0
- package/dist/client/assets/make-CHLpvVh8.js +1 -0
- package/dist/client/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/client/assets/marko-CnJfTvn9.js +1 -0
- package/dist/client/assets/material-theme-D5KoaKCx.js +1 -0
- package/dist/client/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/dist/client/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/dist/client/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/dist/client/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/dist/client/assets/matlab-D7o27uSR.js +1 -0
- package/dist/client/assets/mdc-BMNejdWA.js +1 -0
- package/dist/client/assets/mdx-Cmh6b_Ma.js +1 -0
- package/dist/client/assets/mermaid-mWjccvbQ.js +1 -0
- package/dist/client/assets/min-dark-CafNBF8u.js +1 -0
- package/dist/client/assets/min-light-CTRr51gU.js +1 -0
- package/dist/client/assets/mipsasm-CKIfxQSi.js +1 -0
- package/dist/client/assets/mojo-rZm6bMo-.js +1 -0
- package/dist/client/assets/monokai-D4h5O-jR.js +1 -0
- package/dist/client/assets/moonbit-_H4v1dQx.js +1 -0
- package/dist/client/assets/move-IF9eRakj.js +1 -0
- package/dist/client/assets/narrat-DRg8JJMk.js +1 -0
- package/dist/client/assets/nextflow-Zz6hmt5N.js +1 -0
- package/dist/client/assets/nextflow-groovy-BeH2EWoN.js +1 -0
- package/dist/client/assets/nginx-BpAMiNFr.js +1 -0
- package/dist/client/assets/night-owl-C39BiMTA.js +1 -0
- package/dist/client/assets/night-owl-light-CMTm3GFP.js +1 -0
- package/dist/client/assets/nim-CVrawwO9.js +1 -0
- package/dist/client/assets/nix-CwoSXNpI.js +1 -0
- package/dist/client/assets/nord-Ddv68eIx.js +1 -0
- package/dist/client/assets/nushell-Cz2AlsmD.js +1 -0
- package/dist/client/assets/objective-c-DXmwc3jG.js +1 -0
- package/dist/client/assets/objective-cpp-CLxacb5B.js +1 -0
- package/dist/client/assets/ocaml-C0hk2d4L.js +1 -0
- package/dist/client/assets/odin-BBf5iR-q.js +1 -0
- package/dist/client/assets/one-dark-pro-DVMEJ2y_.js +1 -0
- package/dist/client/assets/one-light-C3Wv6jpd.js +1 -0
- package/dist/client/assets/openscad-C4EeE6gA.js +1 -0
- package/dist/client/assets/pascal-D93ZcfNL.js +1 -0
- package/dist/client/assets/perl-C0TMdlhV.js +1 -0
- package/dist/client/assets/php-Dhbhpdrm.js +1 -0
- package/dist/client/assets/pierre-dark-DF2SEV7i.js +1 -0
- package/dist/client/assets/pierre-light-DOlZxES8.js +1 -0
- package/dist/client/assets/pkl-u5AG7uiY.js +1 -0
- package/dist/client/assets/plastic-3e1v2bzS.js +1 -0
- package/dist/client/assets/plsql-ChMvpjG-.js +1 -0
- package/dist/client/assets/po-BTJTHyun.js +1 -0
- package/dist/client/assets/poimandres-CS3Unz2-.js +1 -0
- package/dist/client/assets/polar-C0HS_06l.js +1 -0
- package/dist/client/assets/postcss-CXtECtnM.js +1 -0
- package/dist/client/assets/powerquery-CEu0bR-o.js +1 -0
- package/dist/client/assets/powershell-Dpen1YoG.js +1 -0
- package/dist/client/assets/prisma-Dd19v3D-.js +1 -0
- package/dist/client/assets/prolog-CbFg5uaA.js +1 -0
- package/dist/client/assets/proto-C7zT0LnQ.js +1 -0
- package/dist/client/assets/pug-CGlum2m_.js +1 -0
- package/dist/client/assets/puppet-BMWR74SV.js +1 -0
- package/dist/client/assets/purescript-CklMAg4u.js +1 -0
- package/dist/client/assets/python-B6aJPvgy.js +1 -0
- package/dist/client/assets/qml-3beO22l8.js +1 -0
- package/dist/client/assets/qmldir-C8lEn-DE.js +1 -0
- package/dist/client/assets/qss-IeuSbFQv.js +1 -0
- package/dist/client/assets/r-Dspwwk_N.js +1 -0
- package/dist/client/assets/racket-BqYA7rlc.js +1 -0
- package/dist/client/assets/raku-DXvB9xmW.js +1 -0
- package/dist/client/assets/razor-Uh8Bk_45.js +1 -0
- package/dist/client/assets/red-bN70gL4F.js +1 -0
- package/dist/client/assets/reg-C-SQnVFl.js +1 -0
- package/dist/client/assets/regexp-CDVJQ6XC.js +1 -0
- package/dist/client/assets/rel-C3B-1QV4.js +1 -0
- package/dist/client/assets/riscv-BM1_JUlF.js +1 -0
- package/dist/client/assets/ron-D8l8udqQ.js +1 -0
- package/dist/client/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
- package/dist/client/assets/rose-pine-moon-D4_iv3hh.js +1 -0
- package/dist/client/assets/rose-pine-qdsjHGoJ.js +1 -0
- package/dist/client/assets/rosmsg-BJDFO7_C.js +1 -0
- package/dist/client/assets/rst-BrH8l1NY.js +1 -0
- package/dist/client/assets/ruby-Dw2BHqvy.js +1 -0
- package/dist/client/assets/rust-B1yitclQ.js +1 -0
- package/dist/client/assets/sas-cz2c8ADy.js +1 -0
- package/dist/client/assets/sass-Cj5Yp3dK.js +1 -0
- package/dist/client/assets/scala-C151Ov-r.js +1 -0
- package/dist/client/assets/scheme-C98Dy4si.js +1 -0
- package/dist/client/assets/scss-OYdSNvt2.js +1 -0
- package/dist/client/assets/sdbl-DVxCFoDh.js +1 -0
- package/dist/client/assets/shaderlab-Dg9Lc6iA.js +1 -0
- package/dist/client/assets/shellscript-Yzrsuije.js +1 -0
- package/dist/client/assets/shellsession-BADoaaVG.js +1 -0
- package/dist/client/assets/slack-dark-BthQWCQV.js +1 -0
- package/dist/client/assets/slack-ochin-DqwNpetd.js +1 -0
- package/dist/client/assets/smalltalk-BERRCDM3.js +1 -0
- package/dist/client/assets/snazzy-light-Bw305WKR.js +1 -0
- package/dist/client/assets/solarized-dark-DXbdFlpD.js +1 -0
- package/dist/client/assets/solarized-light-L9t79GZl.js +1 -0
- package/dist/client/assets/solidity-rGO070M0.js +1 -0
- package/dist/client/assets/soy-Brmx7dQM.js +1 -0
- package/dist/client/assets/sparql-rVzFXLq3.js +1 -0
- package/dist/client/assets/splunk-BtCnVYZw.js +1 -0
- package/dist/client/assets/sql-BLtJtn59.js +1 -0
- package/dist/client/assets/ssh-config-_ykCGR6B.js +1 -0
- package/dist/client/assets/stata-BH5u7GGu.js +1 -0
- package/dist/client/assets/stylus-BEDo0Tqx.js +1 -0
- package/dist/client/assets/surrealql-Bq5Q-fJD.js +1 -0
- package/dist/client/assets/svelte-C_ipcX3V.js +1 -0
- package/dist/client/assets/swift-D82vCrfD.js +1 -0
- package/dist/client/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/dist/client/assets/system-verilog-CnnmHF94.js +1 -0
- package/dist/client/assets/systemd-4A_iFExJ.js +1 -0
- package/dist/client/assets/talonscript-CkByrt1z.js +1 -0
- package/dist/client/assets/tasl-QIJgUcNo.js +1 -0
- package/dist/client/assets/tcl-dwOrl1Do.js +1 -0
- package/dist/client/assets/templ-P3uqSqPl.js +1 -0
- package/dist/client/assets/terraform-BETggiCN.js +1 -0
- package/dist/client/assets/tex-idrVyKtj.js +1 -0
- package/dist/client/assets/tokyo-night-hegEt444.js +1 -0
- package/dist/client/assets/toml-vGWfd6FD.js +1 -0
- package/dist/client/assets/ts-tags-zn1MmPIZ.js +1 -0
- package/dist/client/assets/tsv-B_m7g4N7.js +1 -0
- package/dist/client/assets/tsx-COt5Ahok.js +1 -0
- package/dist/client/assets/turtle-BsS91CYL.js +1 -0
- package/dist/client/assets/twig-DNn4PbVi.js +1 -0
- package/dist/client/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/client/assets/typespec-BGHnOYBU.js +1 -0
- package/dist/client/assets/typst-DHCkPAjA.js +1 -0
- package/dist/client/assets/v-BcVCzyr7.js +1 -0
- package/dist/client/assets/vala-CsfeWuGM.js +1 -0
- package/dist/client/assets/vb-D17OF-Vu.js +1 -0
- package/dist/client/assets/verilog-BQ8w6xss.js +1 -0
- package/dist/client/assets/vesper-DU1UobuO.js +1 -0
- package/dist/client/assets/vhdl-CeAyd5Ju.js +1 -0
- package/dist/client/assets/viml-CJc9bBzg.js +1 -0
- package/dist/client/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/dist/client/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/dist/client/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/dist/client/assets/vue-DN_0RTcg.js +1 -0
- package/dist/client/assets/vue-html-AaS7Mt5G.js +1 -0
- package/dist/client/assets/vue-vine-CQOfvN7w.js +1 -0
- package/dist/client/assets/vyper-CDx5xZoG.js +1 -0
- package/dist/client/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/client/assets/wasm-MzD3tlZU.js +1 -0
- package/dist/client/assets/wenyan-BV7otONQ.js +1 -0
- package/dist/client/assets/wgsl-Dx-B1_4e.js +1 -0
- package/dist/client/assets/wikitext-BhOHFoWU.js +1 -0
- package/dist/client/assets/wit-5i3qLPDT.js +1 -0
- package/dist/client/assets/wolfram-lXgVvXCa.js +1 -0
- package/dist/client/assets/xml-sdJ4AIDG.js +1 -0
- package/dist/client/assets/xsl-CtQFsRM5.js +1 -0
- package/dist/client/assets/yaml-Buea-lGh.js +1 -0
- package/dist/client/assets/zenscript-DVFEvuxE.js +1 -0
- package/dist/client/assets/zig-VOosw3JB.js +1 -0
- package/dist/client/index.html +2 -2
- package/package.json +2 -1
- package/src/server/agent.test.ts +45 -1
- package/src/server/agent.ts +141 -8
- package/src/server/codex-app-server-protocol.ts +28 -0
- package/src/server/codex-app-server.test.ts +88 -0
- package/src/server/codex-app-server.ts +71 -1
- package/src/server/diff-store.test.ts +126 -0
- package/src/server/diff-store.ts +365 -0
- package/src/server/generate-commit-message.test.ts +59 -0
- package/src/server/generate-commit-message.ts +121 -0
- package/src/server/read-models.test.ts +1 -1
- package/src/server/read-models.ts +4 -1
- package/src/server/server.ts +60 -1
- package/src/server/terminal-manager.test.ts +37 -4
- package/src/server/uploads.ts +4 -0
- package/src/server/ws-router.ts +118 -7
- package/src/shared/protocol.ts +3 -0
- package/src/shared/types.ts +50 -0
- package/dist/client/assets/index-Cdjl9mRd.js +0 -606
- package/dist/client/assets/index-D6aACRxb.css +0 -32
package/src/server/server.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { APP_NAME, getRuntimeProfile } from "../shared/branding"
|
|
|
4
4
|
import type { ChatAttachment } from "../shared/types"
|
|
5
5
|
import { EventStore } from "./event-store"
|
|
6
6
|
import { AgentCoordinator } from "./agent"
|
|
7
|
+
import { DiffStore } from "./diff-store"
|
|
7
8
|
import { discoverProjects, type DiscoveredProject } from "./discovery"
|
|
8
9
|
import { KeybindingsManager } from "./keybindings"
|
|
9
10
|
import { getMachineDisplayName } from "./machine-name"
|
|
@@ -11,7 +12,7 @@ import { TerminalManager } from "./terminal-manager"
|
|
|
11
12
|
import { UpdateManager } from "./update-manager"
|
|
12
13
|
import type { UpdateInstallAttemptResult } from "./cli-runtime"
|
|
13
14
|
import { createWsRouter, type ClientState } from "./ws-router"
|
|
14
|
-
import { deleteProjectUpload, inferAttachmentContentType, persistProjectUpload } from "./uploads"
|
|
15
|
+
import { deleteProjectUpload, inferAttachmentContentType, inferProjectFileContentType, persistProjectUpload } from "./uploads"
|
|
15
16
|
import { getProjectUploadDir } from "./paths"
|
|
16
17
|
|
|
17
18
|
const MAX_UPLOAD_FILES = 10
|
|
@@ -68,8 +69,10 @@ export async function startKannaServer(options: StartKannaServerOptions = {}) {
|
|
|
68
69
|
const hostname = options.host ?? "127.0.0.1"
|
|
69
70
|
const strictPort = options.strictPort ?? false
|
|
70
71
|
const store = new EventStore()
|
|
72
|
+
const diffStore = new DiffStore(store.dataDir)
|
|
71
73
|
const machineDisplayName = getMachineDisplayName()
|
|
72
74
|
await store.initialize()
|
|
75
|
+
await diffStore.initialize()
|
|
73
76
|
await store.migrateLegacyTranscripts(options.onMigrationProgress)
|
|
74
77
|
let discoveredProjects: DiscoveredProject[] = []
|
|
75
78
|
|
|
@@ -101,6 +104,7 @@ export async function startKannaServer(options: StartKannaServerOptions = {}) {
|
|
|
101
104
|
})
|
|
102
105
|
router = createWsRouter({
|
|
103
106
|
store,
|
|
107
|
+
diffStore,
|
|
104
108
|
agent,
|
|
105
109
|
terminals,
|
|
106
110
|
keybindings,
|
|
@@ -127,6 +131,7 @@ export async function startKannaServer(options: StartKannaServerOptions = {}) {
|
|
|
127
131
|
const upgraded = serverInstance.upgrade(req, {
|
|
128
132
|
data: {
|
|
129
133
|
subscriptions: new Map(),
|
|
134
|
+
snapshotSignatures: new Map(),
|
|
130
135
|
},
|
|
131
136
|
})
|
|
132
137
|
return upgraded ? undefined : new Response("WebSocket upgrade failed", { status: 400 })
|
|
@@ -151,6 +156,11 @@ export async function startKannaServer(options: StartKannaServerOptions = {}) {
|
|
|
151
156
|
return attachmentContentResponse
|
|
152
157
|
}
|
|
153
158
|
|
|
159
|
+
const projectFileContentResponse = await handleProjectFileContent(req, url, store)
|
|
160
|
+
if (projectFileContentResponse) {
|
|
161
|
+
return projectFileContentResponse
|
|
162
|
+
}
|
|
163
|
+
|
|
154
164
|
return serveStatic(distDir, url.pathname)
|
|
155
165
|
},
|
|
156
166
|
websocket: {
|
|
@@ -191,6 +201,7 @@ export async function startKannaServer(options: StartKannaServerOptions = {}) {
|
|
|
191
201
|
return {
|
|
192
202
|
port: actualPort,
|
|
193
203
|
store,
|
|
204
|
+
diffStore,
|
|
194
205
|
updateManager,
|
|
195
206
|
stop: shutdown,
|
|
196
207
|
}
|
|
@@ -289,6 +300,54 @@ async function handleAttachmentContent(req: Request, url: URL, store: EventStore
|
|
|
289
300
|
})
|
|
290
301
|
}
|
|
291
302
|
|
|
303
|
+
async function handleProjectFileContent(req: Request, url: URL, store: EventStore) {
|
|
304
|
+
const match = url.pathname.match(/^\/api\/projects\/([^/]+)\/files\/([^/]+)\/content$/)
|
|
305
|
+
if (!match) {
|
|
306
|
+
return null
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (req.method !== "GET") {
|
|
310
|
+
return new Response(null, {
|
|
311
|
+
status: 405,
|
|
312
|
+
headers: {
|
|
313
|
+
Allow: "GET",
|
|
314
|
+
},
|
|
315
|
+
})
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const project = store.getProject(match[1])
|
|
319
|
+
if (!project) {
|
|
320
|
+
return Response.json({ error: "Project not found" }, { status: 404 })
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const relativePath = path.posix.normalize(decodeURIComponent(match[2]).replaceAll("\\", "/"))
|
|
324
|
+
if (!relativePath || relativePath === "." || relativePath.startsWith("../") || relativePath.includes("/../") || path.posix.isAbsolute(relativePath)) {
|
|
325
|
+
return Response.json({ error: "Invalid project file path" }, { status: 400 })
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const filePath = path.resolve(project.localPath, relativePath)
|
|
329
|
+
const projectRoot = path.resolve(project.localPath)
|
|
330
|
+
if (filePath !== projectRoot && !filePath.startsWith(`${projectRoot}${path.sep}`)) {
|
|
331
|
+
return Response.json({ error: "Invalid project file path" }, { status: 400 })
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const file = Bun.file(filePath)
|
|
335
|
+
try {
|
|
336
|
+
const info = await stat(filePath)
|
|
337
|
+
if (!info.isFile()) {
|
|
338
|
+
return Response.json({ error: "File not found" }, { status: 404 })
|
|
339
|
+
}
|
|
340
|
+
} catch {
|
|
341
|
+
return Response.json({ error: "File not found" }, { status: 404 })
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return new Response(file, {
|
|
345
|
+
headers: {
|
|
346
|
+
"Content-Type": inferProjectFileContentType(relativePath, file.type),
|
|
347
|
+
},
|
|
348
|
+
})
|
|
349
|
+
}
|
|
350
|
+
|
|
292
351
|
async function handleProjectUploadDelete(req: Request, url: URL, store: EventStore) {
|
|
293
352
|
if (req.method !== "DELETE") {
|
|
294
353
|
return null
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { afterEach, beforeAll, describe, expect, test } from "bun:test"
|
|
2
|
-
import { mkdtemp, rm } from "node:fs/promises"
|
|
1
|
+
import { afterAll, afterEach, beforeAll, describe, expect, test } from "bun:test"
|
|
2
|
+
import { mkdtemp, mkdir, rm } from "node:fs/promises"
|
|
3
3
|
import os from "node:os"
|
|
4
4
|
import path from "node:path"
|
|
5
5
|
import { TerminalManager } from "./terminal-manager"
|
|
@@ -13,10 +13,19 @@ const isSupportedPlatform = process.platform !== "win32" && typeof Bun.Terminal
|
|
|
13
13
|
const describeIfSupported = isSupportedPlatform ? describe : describe.skip
|
|
14
14
|
|
|
15
15
|
let tempProjectPath = ""
|
|
16
|
+
let tempHomePath = ""
|
|
17
|
+
const originalHome = process.env.HOME
|
|
18
|
+
const originalZdotdir = process.env.ZDOTDIR
|
|
19
|
+
const originalHistfile = process.env.HISTFILE
|
|
16
20
|
|
|
17
21
|
beforeAll(async () => {
|
|
18
22
|
if (!isSupportedPlatform) return
|
|
19
23
|
tempProjectPath = await mkdtemp(path.join(os.tmpdir(), "kanna-terminal-manager-"))
|
|
24
|
+
tempHomePath = await mkdtemp(path.join(os.tmpdir(), "kanna-terminal-home-"))
|
|
25
|
+
await mkdir(path.join(tempHomePath, ".config"), { recursive: true })
|
|
26
|
+
process.env.HOME = tempHomePath
|
|
27
|
+
process.env.ZDOTDIR = tempHomePath
|
|
28
|
+
process.env.HISTFILE = path.join(tempHomePath, ".zsh_history")
|
|
20
29
|
})
|
|
21
30
|
|
|
22
31
|
afterEach(async () => {
|
|
@@ -25,6 +34,30 @@ afterEach(async () => {
|
|
|
25
34
|
tempProjectPath = await mkdtemp(path.join(os.tmpdir(), "kanna-terminal-manager-"))
|
|
26
35
|
})
|
|
27
36
|
|
|
37
|
+
afterAll(async () => {
|
|
38
|
+
if (originalHome === undefined) {
|
|
39
|
+
delete process.env.HOME
|
|
40
|
+
} else {
|
|
41
|
+
process.env.HOME = originalHome
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (originalZdotdir === undefined) {
|
|
45
|
+
delete process.env.ZDOTDIR
|
|
46
|
+
} else {
|
|
47
|
+
process.env.ZDOTDIR = originalZdotdir
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (originalHistfile === undefined) {
|
|
51
|
+
delete process.env.HISTFILE
|
|
52
|
+
} else {
|
|
53
|
+
process.env.HISTFILE = originalHistfile
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (tempHomePath) {
|
|
57
|
+
await rm(tempHomePath, { recursive: true, force: true })
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
28
61
|
async function waitFor(check: () => boolean, timeoutMs: number, intervalMs = 25) {
|
|
29
62
|
const startedAt = Date.now()
|
|
30
63
|
while (Date.now() - startedAt < timeoutMs) {
|
|
@@ -70,8 +103,8 @@ describeIfSupported("TerminalManager", () => {
|
|
|
70
103
|
const { manager, getOutput } = await createSession(terminalId)
|
|
71
104
|
|
|
72
105
|
try {
|
|
73
|
-
manager.write(terminalId,
|
|
74
|
-
await waitFor(() => getOutput().includes("
|
|
106
|
+
manager.write(terminalId, `python3 -c "import time; print('__KANNA_SLEEP__', flush=True); time.sleep(30)"\r`)
|
|
107
|
+
await waitFor(() => getOutput().includes("__KANNA_SLEEP__"), COMMAND_TIMEOUT_MS)
|
|
75
108
|
|
|
76
109
|
manager.write(terminalId, "\x03")
|
|
77
110
|
manager.write(terminalId, "printf '__KANNA_AFTER_INT__\\n'\r")
|
package/src/server/uploads.ts
CHANGED
|
@@ -108,6 +108,10 @@ export function inferAttachmentContentType(fileName: string, fallbackType?: stri
|
|
|
108
108
|
return fallbackType || DEFAULT_BINARY_MIME_TYPE
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
export function inferProjectFileContentType(fileName: string, fallbackType?: string): string {
|
|
112
|
+
return inferAttachmentContentType(fileName, fallbackType)
|
|
113
|
+
}
|
|
114
|
+
|
|
111
115
|
export async function deleteProjectUpload(args: {
|
|
112
116
|
localPath: string
|
|
113
117
|
storedName: string
|
package/src/server/ws-router.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { ClientEnvelope, ServerEnvelope, SubscriptionTopic } from "../share
|
|
|
4
4
|
import { isClientEnvelope } from "../shared/protocol"
|
|
5
5
|
import type { AgentCoordinator } from "./agent"
|
|
6
6
|
import type { DiscoveredProject } from "./discovery"
|
|
7
|
+
import { DiffStore } from "./diff-store"
|
|
7
8
|
import { EventStore } from "./event-store"
|
|
8
9
|
import { openExternal } from "./external-open"
|
|
9
10
|
import { KeybindingsManager } from "./keybindings"
|
|
@@ -14,10 +15,12 @@ import { deriveChatSnapshot, deriveLocalProjectsSnapshot, deriveSidebarData } fr
|
|
|
14
15
|
|
|
15
16
|
export interface ClientState {
|
|
16
17
|
subscriptions: Map<string, SubscriptionTopic>
|
|
18
|
+
snapshotSignatures: Map<string, string>
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
interface CreateWsRouterArgs {
|
|
20
22
|
store: EventStore
|
|
23
|
+
diffStore?: Pick<DiffStore, "getSnapshot" | "refreshSnapshot" | "generateCommitMessage" | "commitFiles">
|
|
21
24
|
agent: AgentCoordinator
|
|
22
25
|
terminals: TerminalManager
|
|
23
26
|
keybindings: KeybindingsManager
|
|
@@ -31,8 +34,17 @@ function send(ws: ServerWebSocket<ClientState>, message: ServerEnvelope) {
|
|
|
31
34
|
ws.send(JSON.stringify(message))
|
|
32
35
|
}
|
|
33
36
|
|
|
37
|
+
function ensureSnapshotSignatures(ws: ServerWebSocket<ClientState>) {
|
|
38
|
+
if (!ws.data.snapshotSignatures) {
|
|
39
|
+
ws.data.snapshotSignatures = new Map()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return ws.data.snapshotSignatures
|
|
43
|
+
}
|
|
44
|
+
|
|
34
45
|
export function createWsRouter({
|
|
35
46
|
store,
|
|
47
|
+
diffStore,
|
|
36
48
|
agent,
|
|
37
49
|
terminals,
|
|
38
50
|
keybindings,
|
|
@@ -42,6 +54,12 @@ export function createWsRouter({
|
|
|
42
54
|
updateManager,
|
|
43
55
|
}: CreateWsRouterArgs) {
|
|
44
56
|
const sockets = new Set<ServerWebSocket<ClientState>>()
|
|
57
|
+
const resolvedDiffStore = diffStore ?? {
|
|
58
|
+
getSnapshot: () => ({ status: "unknown", branchName: undefined, files: [] as const }),
|
|
59
|
+
refreshSnapshot: async () => false,
|
|
60
|
+
generateCommitMessage: async () => ({ subject: "Update selected files", body: "", usedFallback: true, failureMessage: null }),
|
|
61
|
+
commitFiles: async () => false,
|
|
62
|
+
}
|
|
45
63
|
|
|
46
64
|
function createEnvelope(id: string, topic: SubscriptionTopic): ServerEnvelope {
|
|
47
65
|
if (topic.type === "sidebar") {
|
|
@@ -121,14 +139,28 @@ export function createWsRouter({
|
|
|
121
139
|
id,
|
|
122
140
|
snapshot: {
|
|
123
141
|
type: "chat",
|
|
124
|
-
data: deriveChatSnapshot(
|
|
142
|
+
data: deriveChatSnapshot(
|
|
143
|
+
store.state,
|
|
144
|
+
agent.getActiveStatuses(),
|
|
145
|
+
agent.getDrainingChatIds(),
|
|
146
|
+
topic.chatId,
|
|
147
|
+
(chatId) => store.getMessages(chatId),
|
|
148
|
+
(chatId) => resolvedDiffStore.getSnapshot(chatId)
|
|
149
|
+
),
|
|
125
150
|
},
|
|
126
151
|
}
|
|
127
152
|
}
|
|
128
153
|
|
|
129
154
|
function pushSnapshots(ws: ServerWebSocket<ClientState>) {
|
|
155
|
+
const snapshotSignatures = ensureSnapshotSignatures(ws)
|
|
130
156
|
for (const [id, topic] of ws.data.subscriptions.entries()) {
|
|
131
|
-
|
|
157
|
+
const envelope = createEnvelope(id, topic)
|
|
158
|
+
const signature = JSON.stringify(envelope.snapshot)
|
|
159
|
+
if (snapshotSignatures.get(id) === signature) {
|
|
160
|
+
continue
|
|
161
|
+
}
|
|
162
|
+
snapshotSignatures.set(id, signature)
|
|
163
|
+
send(ws, envelope)
|
|
132
164
|
}
|
|
133
165
|
}
|
|
134
166
|
|
|
@@ -150,9 +182,14 @@ export function createWsRouter({
|
|
|
150
182
|
|
|
151
183
|
function pushTerminalSnapshot(terminalId: string) {
|
|
152
184
|
for (const ws of sockets) {
|
|
185
|
+
const snapshotSignatures = ensureSnapshotSignatures(ws)
|
|
153
186
|
for (const [id, topic] of ws.data.subscriptions.entries()) {
|
|
154
187
|
if (topic.type !== "terminal" || topic.terminalId !== terminalId) continue
|
|
155
|
-
|
|
188
|
+
const envelope = createEnvelope(id, topic)
|
|
189
|
+
const signature = JSON.stringify(envelope.snapshot)
|
|
190
|
+
if (snapshotSignatures.get(id) === signature) continue
|
|
191
|
+
snapshotSignatures.set(id, signature)
|
|
192
|
+
send(ws, envelope)
|
|
156
193
|
}
|
|
157
194
|
}
|
|
158
195
|
}
|
|
@@ -177,18 +214,28 @@ export function createWsRouter({
|
|
|
177
214
|
|
|
178
215
|
const disposeKeybindingEvents = keybindings.onChange(() => {
|
|
179
216
|
for (const ws of sockets) {
|
|
217
|
+
const snapshotSignatures = ensureSnapshotSignatures(ws)
|
|
180
218
|
for (const [id, topic] of ws.data.subscriptions.entries()) {
|
|
181
219
|
if (topic.type !== "keybindings") continue
|
|
182
|
-
|
|
220
|
+
const envelope = createEnvelope(id, topic)
|
|
221
|
+
const signature = JSON.stringify(envelope.snapshot)
|
|
222
|
+
if (snapshotSignatures.get(id) === signature) continue
|
|
223
|
+
snapshotSignatures.set(id, signature)
|
|
224
|
+
send(ws, envelope)
|
|
183
225
|
}
|
|
184
226
|
}
|
|
185
227
|
})
|
|
186
228
|
|
|
187
229
|
const disposeUpdateEvents = updateManager?.onChange(() => {
|
|
188
230
|
for (const ws of sockets) {
|
|
231
|
+
const snapshotSignatures = ensureSnapshotSignatures(ws)
|
|
189
232
|
for (const [id, topic] of ws.data.subscriptions.entries()) {
|
|
190
233
|
if (topic.type !== "update") continue
|
|
191
|
-
|
|
234
|
+
const envelope = createEnvelope(id, topic)
|
|
235
|
+
const signature = JSON.stringify(envelope.snapshot)
|
|
236
|
+
if (snapshotSignatures.get(id) === signature) continue
|
|
237
|
+
snapshotSignatures.set(id, signature)
|
|
238
|
+
send(ws, envelope)
|
|
192
239
|
}
|
|
193
240
|
}
|
|
194
241
|
}) ?? (() => {})
|
|
@@ -299,6 +346,60 @@ export function createWsRouter({
|
|
|
299
346
|
send(ws, { v: PROTOCOL_VERSION, type: "ack", id, result })
|
|
300
347
|
break
|
|
301
348
|
}
|
|
349
|
+
case "chat.refreshDiffs": {
|
|
350
|
+
const chat = store.getChat(command.chatId)
|
|
351
|
+
if (!chat) {
|
|
352
|
+
throw new Error("Chat not found")
|
|
353
|
+
}
|
|
354
|
+
const project = store.getProject(chat.projectId)
|
|
355
|
+
if (!project) {
|
|
356
|
+
throw new Error("Project not found")
|
|
357
|
+
}
|
|
358
|
+
const changed = await resolvedDiffStore.refreshSnapshot(command.chatId, project.localPath)
|
|
359
|
+
send(ws, { v: PROTOCOL_VERSION, type: "ack", id })
|
|
360
|
+
if (changed) {
|
|
361
|
+
broadcastSnapshots()
|
|
362
|
+
}
|
|
363
|
+
return
|
|
364
|
+
}
|
|
365
|
+
case "chat.generateCommitMessage": {
|
|
366
|
+
const chat = store.getChat(command.chatId)
|
|
367
|
+
if (!chat) {
|
|
368
|
+
throw new Error("Chat not found")
|
|
369
|
+
}
|
|
370
|
+
const project = store.getProject(chat.projectId)
|
|
371
|
+
if (!project) {
|
|
372
|
+
throw new Error("Project not found")
|
|
373
|
+
}
|
|
374
|
+
const result = await resolvedDiffStore.generateCommitMessage({
|
|
375
|
+
projectPath: project.localPath,
|
|
376
|
+
paths: command.paths,
|
|
377
|
+
})
|
|
378
|
+
send(ws, { v: PROTOCOL_VERSION, type: "ack", id, result })
|
|
379
|
+
return
|
|
380
|
+
}
|
|
381
|
+
case "chat.commitDiffs": {
|
|
382
|
+
const chat = store.getChat(command.chatId)
|
|
383
|
+
if (!chat) {
|
|
384
|
+
throw new Error("Chat not found")
|
|
385
|
+
}
|
|
386
|
+
const project = store.getProject(chat.projectId)
|
|
387
|
+
if (!project) {
|
|
388
|
+
throw new Error("Project not found")
|
|
389
|
+
}
|
|
390
|
+
const changed = await resolvedDiffStore.commitFiles({
|
|
391
|
+
chatId: command.chatId,
|
|
392
|
+
projectPath: project.localPath,
|
|
393
|
+
paths: command.paths,
|
|
394
|
+
summary: command.summary,
|
|
395
|
+
description: command.description,
|
|
396
|
+
})
|
|
397
|
+
send(ws, { v: PROTOCOL_VERSION, type: "ack", id })
|
|
398
|
+
if (changed) {
|
|
399
|
+
broadcastSnapshots()
|
|
400
|
+
}
|
|
401
|
+
return
|
|
402
|
+
}
|
|
302
403
|
case "chat.cancel": {
|
|
303
404
|
await agent.cancel(command.chatId)
|
|
304
405
|
send(ws, { v: PROTOCOL_VERSION, type: "ack", id })
|
|
@@ -350,6 +451,11 @@ export function createWsRouter({
|
|
|
350
451
|
broadcastSnapshots()
|
|
351
452
|
} catch (error) {
|
|
352
453
|
const messageText = error instanceof Error ? error.message : String(error)
|
|
454
|
+
console.error("[ws-router] command failed", {
|
|
455
|
+
id,
|
|
456
|
+
type: command.type,
|
|
457
|
+
message: messageText,
|
|
458
|
+
})
|
|
353
459
|
send(ws, { v: PROTOCOL_VERSION, type: "error", id, message: messageText })
|
|
354
460
|
}
|
|
355
461
|
}
|
|
@@ -377,20 +483,25 @@ export function createWsRouter({
|
|
|
377
483
|
}
|
|
378
484
|
|
|
379
485
|
if (parsed.type === "subscribe") {
|
|
486
|
+
const snapshotSignatures = ensureSnapshotSignatures(ws)
|
|
380
487
|
ws.data.subscriptions.set(parsed.id, parsed.topic)
|
|
488
|
+
snapshotSignatures.delete(parsed.id)
|
|
381
489
|
if (parsed.topic.type === "local-projects") {
|
|
382
490
|
void refreshDiscovery().then(() => {
|
|
383
491
|
if (ws.data.subscriptions.has(parsed.id)) {
|
|
384
|
-
|
|
492
|
+
pushSnapshots(ws)
|
|
385
493
|
}
|
|
386
494
|
})
|
|
495
|
+
return
|
|
387
496
|
}
|
|
388
|
-
|
|
497
|
+
pushSnapshots(ws)
|
|
389
498
|
return
|
|
390
499
|
}
|
|
391
500
|
|
|
392
501
|
if (parsed.type === "unsubscribe") {
|
|
502
|
+
const snapshotSignatures = ensureSnapshotSignatures(ws)
|
|
393
503
|
ws.data.subscriptions.delete(parsed.id)
|
|
504
|
+
snapshotSignatures.delete(parsed.id)
|
|
394
505
|
send(ws, { v: PROTOCOL_VERSION, type: "ack", id: parsed.id })
|
|
395
506
|
return
|
|
396
507
|
}
|
package/src/shared/protocol.ts
CHANGED
|
@@ -75,6 +75,9 @@ export type ClientCommand =
|
|
|
75
75
|
effort?: string
|
|
76
76
|
planMode?: boolean
|
|
77
77
|
}
|
|
78
|
+
| { type: "chat.refreshDiffs"; chatId: string }
|
|
79
|
+
| { type: "chat.generateCommitMessage"; chatId: string; paths: string[] }
|
|
80
|
+
| { type: "chat.commitDiffs"; chatId: string; paths: string[]; summary: string; description?: string }
|
|
78
81
|
| { type: "chat.cancel"; chatId: string }
|
|
79
82
|
| { type: "chat.stopDraining"; chatId: string }
|
|
80
83
|
| { type: "chat.respondTool"; chatId: string; toolUseId: string; result: unknown }
|
package/src/shared/types.ts
CHANGED
|
@@ -171,6 +171,16 @@ export function resolveClaudeApiModelId(modelId: string, contextWindow?: ClaudeC
|
|
|
171
171
|
return contextWindow === "1m" ? `${modelId}[1m]` : modelId
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
export function resolveClaudeContextWindowTokens(contextWindow: ClaudeContextWindow): number {
|
|
175
|
+
switch (contextWindow) {
|
|
176
|
+
case "1m":
|
|
177
|
+
return 1_000_000
|
|
178
|
+
case "200k":
|
|
179
|
+
default:
|
|
180
|
+
return 200_000
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
174
184
|
export type KannaStatus =
|
|
175
185
|
| "idle"
|
|
176
186
|
| "starting"
|
|
@@ -440,6 +450,43 @@ export interface StatusEntry extends TranscriptEntryBase {
|
|
|
440
450
|
status: string
|
|
441
451
|
}
|
|
442
452
|
|
|
453
|
+
export interface ContextWindowUsageSnapshot {
|
|
454
|
+
usedTokens: number
|
|
455
|
+
totalProcessedTokens?: number
|
|
456
|
+
maxTokens?: number
|
|
457
|
+
inputTokens?: number
|
|
458
|
+
cachedInputTokens?: number
|
|
459
|
+
outputTokens?: number
|
|
460
|
+
reasoningOutputTokens?: number
|
|
461
|
+
lastUsedTokens?: number
|
|
462
|
+
lastInputTokens?: number
|
|
463
|
+
lastCachedInputTokens?: number
|
|
464
|
+
lastOutputTokens?: number
|
|
465
|
+
lastReasoningOutputTokens?: number
|
|
466
|
+
toolUses?: number
|
|
467
|
+
durationMs?: number
|
|
468
|
+
compactsAutomatically: boolean
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
export interface ChatDiffFile {
|
|
472
|
+
path: string
|
|
473
|
+
changeType: "added" | "deleted" | "modified" | "renamed"
|
|
474
|
+
patch: string
|
|
475
|
+
mimeType?: string
|
|
476
|
+
size?: number
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export interface ChatDiffSnapshot {
|
|
480
|
+
status: "unknown" | "ready" | "no_repo"
|
|
481
|
+
branchName?: string
|
|
482
|
+
files: ChatDiffFile[]
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export interface ContextWindowUpdatedEntry extends TranscriptEntryBase {
|
|
486
|
+
kind: "context_window_updated"
|
|
487
|
+
usage: ContextWindowUsageSnapshot
|
|
488
|
+
}
|
|
489
|
+
|
|
443
490
|
export interface CompactBoundaryEntry extends TranscriptEntryBase {
|
|
444
491
|
kind: "compact_boundary"
|
|
445
492
|
}
|
|
@@ -466,6 +513,7 @@ export type TranscriptEntry =
|
|
|
466
513
|
| ToolResultEntry
|
|
467
514
|
| ResultEntry
|
|
468
515
|
| StatusEntry
|
|
516
|
+
| ContextWindowUpdatedEntry
|
|
469
517
|
| CompactBoundaryEntry
|
|
470
518
|
| CompactSummaryEntry
|
|
471
519
|
| ContextClearedEntry
|
|
@@ -579,6 +627,7 @@ export type HydratedTranscriptMessage =
|
|
|
579
627
|
| ({ kind: "assistant_text"; text: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
|
|
580
628
|
| ({ kind: "result"; success: boolean; cancelled?: boolean; result: string; durationMs: number; costUsd?: number; id: string; messageId?: string; timestamp: string; hidden?: boolean })
|
|
581
629
|
| ({ kind: "status"; status: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
|
|
630
|
+
| ({ kind: "context_window_updated"; usage: ContextWindowUsageSnapshot; id: string; messageId?: string; timestamp: string; hidden?: boolean })
|
|
582
631
|
| ({ kind: "compact_boundary"; id: string; messageId?: string; timestamp: string; hidden?: boolean })
|
|
583
632
|
| ({ kind: "compact_summary"; summary: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
|
|
584
633
|
| ({ kind: "context_cleared"; id: string; messageId?: string; timestamp: string; hidden?: boolean })
|
|
@@ -601,6 +650,7 @@ export interface ChatRuntime {
|
|
|
601
650
|
export interface ChatSnapshot {
|
|
602
651
|
runtime: ChatRuntime
|
|
603
652
|
messages: TranscriptEntry[]
|
|
653
|
+
diffs: ChatDiffSnapshot
|
|
604
654
|
availableProviders: ProviderCatalogEntry[]
|
|
605
655
|
}
|
|
606
656
|
|