@vividcodeai/embeddedcowork-dev 0.0.3-dev-20260507-b76190e8
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/README.md +173 -0
- package/dist/api-types.js +1 -0
- package/dist/auth/auth-store.js +134 -0
- package/dist/auth/http-auth.js +37 -0
- package/dist/auth/manager.js +140 -0
- package/dist/auth/password-hash.js +32 -0
- package/dist/auth/session-manager.js +17 -0
- package/dist/auth/token-manager.js +27 -0
- package/dist/background-processes/manager.js +576 -0
- package/dist/bin.js +24 -0
- package/dist/clients/connection-manager.js +93 -0
- package/dist/config/location.js +57 -0
- package/dist/config/schema.js +71 -0
- package/dist/events/bus.js +45 -0
- package/dist/filesystem/__tests__/search-cache.test.js +40 -0
- package/dist/filesystem/browser.js +292 -0
- package/dist/filesystem/search-cache.js +43 -0
- package/dist/filesystem/search.js +135 -0
- package/dist/index.js +466 -0
- package/dist/launcher.js +149 -0
- package/dist/loader.js +21 -0
- package/dist/logger.js +109 -0
- package/dist/opencode-config/README.md +32 -0
- package/dist/opencode-config/opencode.jsonc +3 -0
- package/dist/opencode-config/package.json +9 -0
- package/dist/opencode-config/plugin/embeddedcowork.ts +62 -0
- package/dist/opencode-config/plugin/lib/background-process.ts +265 -0
- package/dist/opencode-config/plugin/lib/client.ts +133 -0
- package/dist/opencode-config/plugin/lib/request.ts +214 -0
- package/dist/opencode-config.js +15 -0
- package/dist/plugins/channel.js +40 -0
- package/dist/plugins/handlers.js +17 -0
- package/dist/plugins/voice-mode.js +78 -0
- package/dist/releases/dev-release-monitor.js +75 -0
- package/dist/releases/release-monitor.js +107 -0
- package/dist/runtime-paths.js +67 -0
- package/dist/server/__tests__/network-addresses.test.js +68 -0
- package/dist/server/__tests__/remote-proxy.test.js +204 -0
- package/dist/server/http-server.js +996 -0
- package/dist/server/network-addresses.js +114 -0
- package/dist/server/remote-proxy.js +466 -0
- package/dist/server/routes/auth-pages/login.html +135 -0
- package/dist/server/routes/auth-pages/token.html +93 -0
- package/dist/server/routes/auth.js +149 -0
- package/dist/server/routes/background-processes.js +78 -0
- package/dist/server/routes/events.js +66 -0
- package/dist/server/routes/filesystem.js +43 -0
- package/dist/server/routes/meta.js +44 -0
- package/dist/server/routes/plugin.js +70 -0
- package/dist/server/routes/remote-proxy.js +42 -0
- package/dist/server/routes/remote-servers.js +142 -0
- package/dist/server/routes/settings.js +69 -0
- package/dist/server/routes/sidecars.js +46 -0
- package/dist/server/routes/speech.js +63 -0
- package/dist/server/routes/storage.js +52 -0
- package/dist/server/routes/workspaces.js +221 -0
- package/dist/server/routes/worktrees.js +156 -0
- package/dist/server/tls.js +224 -0
- package/dist/settings/binaries.js +37 -0
- package/dist/settings/merge-patch.js +33 -0
- package/dist/settings/migrate.js +238 -0
- package/dist/settings/public-config.js +33 -0
- package/dist/settings/service.js +101 -0
- package/dist/settings/yaml-doc-store.js +96 -0
- package/dist/sidecars/manager.js +193 -0
- package/dist/speech/providers/openai-compatible.js +189 -0
- package/dist/speech/service.js +58 -0
- package/dist/storage/instance-store.js +56 -0
- package/dist/ui/__tests__/remote-ui.test.js +67 -0
- package/dist/ui/remote-ui.js +462 -0
- package/dist/workspaces/__tests__/spawn.test.js +139 -0
- package/dist/workspaces/git-mutations.js +98 -0
- package/dist/workspaces/git-status.js +323 -0
- package/dist/workspaces/git-worktrees.js +216 -0
- package/dist/workspaces/instance-events.js +180 -0
- package/dist/workspaces/manager.js +420 -0
- package/dist/workspaces/opencode-auth.js +16 -0
- package/dist/workspaces/runtime.js +366 -0
- package/dist/workspaces/spawn.js +219 -0
- package/dist/workspaces/worktree-directory.js +74 -0
- package/dist/workspaces/worktree-map.js +116 -0
- package/package.json +57 -0
- package/public/apple-touch-icon-180x180.png +0 -0
- package/public/assets/ChangesTab-C2DJXDf9.js +2 -0
- package/public/assets/DiffToolbar-De-3SRCF.js +1 -0
- package/public/assets/EmbeddedCowork-Icon-DSw5nKk7.png +0 -0
- package/public/assets/FilesTab-BuQ00MEc.js +2 -0
- package/public/assets/GitChangesTab-D9bf2jkM.js +2 -0
- package/public/assets/SplitFilePanel-B-3h60o2.js +1 -0
- package/public/assets/StatusTab-D5s19fRN.js +1 -0
- package/public/assets/abap-BdImnpbu.js +1 -0
- package/public/assets/actionscript-3-CfeIJUat.js +1 -0
- package/public/assets/ada-bCR0ucgS.js +1 -0
- package/public/assets/andromeeda-C-Jbm3Hp.js +1 -0
- package/public/assets/angular-html-CU67Zn6k.js +1 -0
- package/public/assets/angular-ts-BwZT4LLn.js +1 -0
- package/public/assets/apache-Pmp26Uib.js +1 -0
- package/public/assets/apex-DhZLUxFE.js +1 -0
- package/public/assets/apl-dKokRX4l.js +1 -0
- package/public/assets/applescript-Co6uUVPk.js +1 -0
- package/public/assets/ara-BRHolxvo.js +1 -0
- package/public/assets/asciidoc-Dv7Oe6Be.js +1 -0
- package/public/assets/asm-D_Q5rh1f.js +1 -0
- package/public/assets/astro-CbQHKStN.js +1 -0
- package/public/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/public/assets/awk-DMzUqQB5.js +1 -0
- package/public/assets/ayu-dark-Cv9koXgw.js +1 -0
- package/public/assets/ballerina-BFfxhgS-.js +1 -0
- package/public/assets/bat-BkioyH1T.js +1 -0
- package/public/assets/beancount-k_qm7-4y.js +1 -0
- package/public/assets/berry-D08WgyRC.js +1 -0
- package/public/assets/bibtex-CHM0blh-.js +1 -0
- package/public/assets/bicep-Bmn6On1c.js +1 -0
- package/public/assets/blade-DVc8C-J4.js +1 -0
- package/public/assets/bsl-BO_Y6i37.js +1 -0
- package/public/assets/bundle-full-CdNbUxmo.js +13 -0
- package/public/assets/c-BIGW1oBm.js +1 -0
- package/public/assets/cadence-Bv_4Rxtq.js +1 -0
- package/public/assets/cairo-KRGpt6FW.js +1 -0
- package/public/assets/catppuccin-frappe-DFWUc33u.js +1 -0
- package/public/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
- package/public/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
- package/public/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
- package/public/assets/clarity-D53aC0YG.js +1 -0
- package/public/assets/clojure-P80f7IUj.js +1 -0
- package/public/assets/cmake-D1j8_8rp.js +1 -0
- package/public/assets/cobol-nwyudZeR.js +1 -0
- package/public/assets/codeowners-Bp6g37R7.js +1 -0
- package/public/assets/codeql-DsOJ9woJ.js +1 -0
- package/public/assets/coffee-Ch7k5sss.js +1 -0
- package/public/assets/common-lisp-Cg-RD9OK.js +1 -0
- package/public/assets/coq-DkFqJrB1.js +1 -0
- package/public/assets/core-DhEqZVGG.js +1 -0
- package/public/assets/cpp-CofmeUqb.js +1 -0
- package/public/assets/crystal-tKQVLTB8.js +1 -0
- package/public/assets/csharp-CX12Zw3r.js +1 -0
- package/public/assets/css-DPfMkruS.js +1 -0
- package/public/assets/csv-fuZLfV_i.js +1 -0
- package/public/assets/cue-D82EKSYY.js +1 -0
- package/public/assets/cypher-COkxafJQ.js +1 -0
- package/public/assets/d-85-TOEBH.js +1 -0
- package/public/assets/dark-plus-eOWES_5F.js +1 -0
- package/public/assets/dart-CF10PKvl.js +1 -0
- package/public/assets/dax-CEL-wOlO.js +1 -0
- package/public/assets/desktop-BmXAJ9_W.js +1 -0
- package/public/assets/diff-D97Zzqfu.js +1 -0
- package/public/assets/diff-viewer-B1l_VZc1.js +1 -0
- package/public/assets/docker-BcOcwvcX.js +1 -0
- package/public/assets/dotenv-Da5cRb03.js +1 -0
- package/public/assets/dracula-BzJJZx-M.js +1 -0
- package/public/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/public/assets/dream-maker-BtqSS_iP.js +1 -0
- package/public/assets/edge-BkV0erSs.js +1 -0
- package/public/assets/elixir-CDX3lj18.js +1 -0
- package/public/assets/elm-DbKCFpqz.js +1 -0
- package/public/assets/emacs-lisp-C9XAeP06.js +1 -0
- package/public/assets/erb-BOJIQeun.js +1 -0
- package/public/assets/erlang-DsQrWhSR.js +1 -0
- package/public/assets/event-DjZVAIBO.js +1 -0
- package/public/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/public/assets/everforest-light-C8M2exoo.js +1 -0
- package/public/assets/fast-diff-vendor-DgdwVvTQ.js +1 -0
- package/public/assets/fennel-BYunw83y.js +1 -0
- package/public/assets/fish-BvzEVeQv.js +1 -0
- package/public/assets/fluent-C4IJs8-o.js +1 -0
- package/public/assets/fortran-fixed-form-BZjJHVRy.js +1 -0
- package/public/assets/fortran-free-form-D22FLkUw.js +1 -0
- package/public/assets/fsharp-CXgrBDvD.js +1 -0
- package/public/assets/gdresource-B7Tvp0Sc.js +1 -0
- package/public/assets/gdscript-DTMYz4Jt.js +1 -0
- package/public/assets/gdshader-DkwncUOv.js +1 -0
- package/public/assets/genie-D0YGMca9.js +1 -0
- package/public/assets/gherkin-DyxjwDmM.js +1 -0
- package/public/assets/git-commit-F4YmCXRG.js +1 -0
- package/public/assets/git-diff-vendor-CSgooKT_.js +52 -0
- package/public/assets/git-diff-vendor-HAZkIolJ.css +19 -0
- package/public/assets/git-rebase-r7XF79zn.js +1 -0
- package/public/assets/github-dark-DHJKELXO.js +1 -0
- package/public/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/public/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/public/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/public/assets/github-light-DAi9KRSo.js +1 -0
- package/public/assets/github-light-default-D7oLnXFd.js +1 -0
- package/public/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/public/assets/gleam-BspZqrRM.js +1 -0
- package/public/assets/glimmer-js-Rg0-pVw9.js +1 -0
- package/public/assets/glimmer-ts-U6CK756n.js +1 -0
- package/public/assets/glsl-DplSGwfg.js +1 -0
- package/public/assets/gnuplot-DdkO51Og.js +1 -0
- package/public/assets/go-Dn2_MT6a.js +1 -0
- package/public/assets/graphql-ChdNCCLP.js +1 -0
- package/public/assets/groovy-gcz8RCvz.js +1 -0
- package/public/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
- package/public/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
- package/public/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
- package/public/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
- package/public/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
- package/public/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
- package/public/assets/hack-CaT9iCJl.js +1 -0
- package/public/assets/haml-B8DHNrY2.js +1 -0
- package/public/assets/handlebars-BL8al0AC.js +1 -0
- package/public/assets/haskell-Df6bDoY_.js +1 -0
- package/public/assets/haxe-CzTSHFRz.js +1 -0
- package/public/assets/hcl-BWvSN4gD.js +1 -0
- package/public/assets/highlight-vendor-8FKMu9os.js +10 -0
- package/public/assets/hjson-D5-asLiD.js +1 -0
- package/public/assets/hlsl-D3lLCCz7.js +1 -0
- package/public/assets/houston-DnULxvSX.js +1 -0
- package/public/assets/html-GMplVEZG.js +1 -0
- package/public/assets/html-derivative-BFtXZ54Q.js +1 -0
- package/public/assets/http-jrhK8wxY.js +1 -0
- package/public/assets/hurl-irOxFIW8.js +1 -0
- package/public/assets/hxml-Bvhsp5Yf.js +1 -0
- package/public/assets/hy-DFXneXwc.js +1 -0
- package/public/assets/imba-DGztddWO.js +1 -0
- package/public/assets/index-B2LsA7hD.js +1 -0
- package/public/assets/index-BErmCqgL.js +1 -0
- package/public/assets/index-BKMyzTSR.js +1 -0
- package/public/assets/index-BKvZBimW.js +1 -0
- package/public/assets/index-BQeBs108.js +1 -0
- package/public/assets/index-BqQARTCd.js +1 -0
- package/public/assets/index-C9Tl2tHH.js +2 -0
- package/public/assets/index-CLSJ4cO9.js +1 -0
- package/public/assets/index-DElsPAzQ.css +1 -0
- package/public/assets/index-ixx_g9gD.js +1 -0
- package/public/assets/ini-BEwlwnbL.js +1 -0
- package/public/assets/java-CylS5w8V.js +1 -0
- package/public/assets/javascript-wDzz0qaB.js +1 -0
- package/public/assets/jinja-4LBKfQ-Z.js +1 -0
- package/public/assets/jison-wvAkD_A8.js +1 -0
- package/public/assets/json-Cp-IABpG.js +1 -0
- package/public/assets/json5-C9tS-k6U.js +1 -0
- package/public/assets/jsonc-Des-eS-w.js +1 -0
- package/public/assets/jsonl-DcaNXYhu.js +1 -0
- package/public/assets/jsonnet-DFQXde-d.js +1 -0
- package/public/assets/jssm-C2t-YnRu.js +1 -0
- package/public/assets/jsx-g9-lgVsj.js +1 -0
- package/public/assets/julia-C8NyazO9.js +1 -0
- package/public/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
- package/public/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
- package/public/assets/kanagawa-wave-DWedfzmr.js +1 -0
- package/public/assets/kdl-DV7GczEv.js +1 -0
- package/public/assets/kotlin-BdnUsdx6.js +1 -0
- package/public/assets/kusto-BvAqAH-y.js +1 -0
- package/public/assets/laserwave-DUszq2jm.js +1 -0
- package/public/assets/latex-BUKiar2Z.js +1 -0
- package/public/assets/lean-DP1Csr6i.js +1 -0
- package/public/assets/less-B1dDrJ26.js +1 -0
- package/public/assets/light-plus-B7mTdjB0.js +1 -0
- package/public/assets/liquid-DYVedYrR.js +1 -0
- package/public/assets/llvm-BtvRca6l.js +1 -0
- package/public/assets/loading-CQjaT4lJ.js +2 -0
- package/public/assets/loading-CugGjKDZ.css +1 -0
- package/public/assets/log-2UxHyX5q.js +1 -0
- package/public/assets/logo-BtOb2qkB.js +1 -0
- package/public/assets/lua-BbnMAYS6.js +1 -0
- package/public/assets/luau-CXu1NL6O.js +1 -0
- package/public/assets/main-C1yBw4P8.js +53 -0
- package/public/assets/make-CHLpvVh8.js +1 -0
- package/public/assets/markdown-Cvjx9yec.js +1 -0
- package/public/assets/markdown-D5eIdNMf.js +58 -0
- package/public/assets/marko-CPi9NSCl.js +1 -0
- package/public/assets/material-theme-D5KoaKCx.js +1 -0
- package/public/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/public/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/public/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/public/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/public/assets/matlab-D7o27uSR.js +1 -0
- package/public/assets/mdc-DUICxH0z.js +1 -0
- package/public/assets/mdx-Cmh6b_Ma.js +1 -0
- package/public/assets/mermaid-DKYwYmdq.js +1 -0
- package/public/assets/min-dark-CafNBF8u.js +1 -0
- package/public/assets/min-light-CTRr51gU.js +1 -0
- package/public/assets/mipsasm-CKIfxQSi.js +1 -0
- package/public/assets/mojo-1DNp92w6.js +1 -0
- package/public/assets/monaco-viewer-9Byc1Kpy.js +26 -0
- package/public/assets/monokai-D4h5O-jR.js +1 -0
- package/public/assets/move-Bu9oaDYs.js +1 -0
- package/public/assets/narrat-DRg8JJMk.js +1 -0
- package/public/assets/nextflow-CUEJCptM.js +1 -0
- package/public/assets/nginx-DknmC5AR.js +1 -0
- package/public/assets/night-owl-C39BiMTA.js +1 -0
- package/public/assets/nim-CVrawwO9.js +1 -0
- package/public/assets/nix-BbRYJGeE.js +1 -0
- package/public/assets/nord-Ddv68eIx.js +1 -0
- package/public/assets/nushell-C-sUppwS.js +1 -0
- package/public/assets/objective-c-DXmwc3jG.js +1 -0
- package/public/assets/objective-cpp-CLxacb5B.js +1 -0
- package/public/assets/ocaml-C0hk2d4L.js +1 -0
- package/public/assets/one-dark-pro-DVMEJ2y_.js +1 -0
- package/public/assets/one-light-PoHY5YXO.js +1 -0
- package/public/assets/pascal-D93ZcfNL.js +1 -0
- package/public/assets/perl-C0TMdlhV.js +1 -0
- package/public/assets/php-CDn_0X-4.js +1 -0
- package/public/assets/pkl-u5AG7uiY.js +1 -0
- package/public/assets/plastic-3e1v2bzS.js +1 -0
- package/public/assets/plsql-ChMvpjG-.js +1 -0
- package/public/assets/po-BTJTHyun.js +1 -0
- package/public/assets/poimandres-CS3Unz2-.js +1 -0
- package/public/assets/polar-C0HS_06l.js +1 -0
- package/public/assets/postcss-CXtECtnM.js +1 -0
- package/public/assets/powerquery-CEu0bR-o.js +1 -0
- package/public/assets/powershell-Dpen1YoG.js +1 -0
- package/public/assets/prisma-Dd19v3D-.js +1 -0
- package/public/assets/prolog-CbFg5uaA.js +1 -0
- package/public/assets/proto-DyJlTyXw.js +1 -0
- package/public/assets/pug-CGlum2m_.js +1 -0
- package/public/assets/puppet-BMWR74SV.js +1 -0
- package/public/assets/purescript-CklMAg4u.js +1 -0
- package/public/assets/python-B6aJPvgy.js +1 -0
- package/public/assets/qml-3beO22l8.js +1 -0
- package/public/assets/qmldir-C8lEn-DE.js +1 -0
- package/public/assets/qss-IeuSbFQv.js +1 -0
- package/public/assets/r-DiinP2Uv.js +1 -0
- package/public/assets/racket-BqYA7rlc.js +1 -0
- package/public/assets/raku-DXvB9xmW.js +1 -0
- package/public/assets/razor-WgofotgN.js +1 -0
- package/public/assets/red-bN70gL4F.js +1 -0
- package/public/assets/reg-C-SQnVFl.js +1 -0
- package/public/assets/regexp-CDVJQ6XC.js +1 -0
- package/public/assets/rel-C3B-1QV4.js +1 -0
- package/public/assets/riscv-BM1_JUlF.js +1 -0
- package/public/assets/rose-pine-BHrmToEH.js +1 -0
- package/public/assets/rose-pine-dawn-CnK8MTSM.js +1 -0
- package/public/assets/rose-pine-moon-NleAzG8P.js +1 -0
- package/public/assets/rosmsg-BJDFO7_C.js +1 -0
- package/public/assets/rst-B0xPkSld.js +1 -0
- package/public/assets/ruby-BvKwtOVI.js +1 -0
- package/public/assets/rust-B1yitclQ.js +1 -0
- package/public/assets/sas-cz2c8ADy.js +1 -0
- package/public/assets/sass-Cj5Yp3dK.js +1 -0
- package/public/assets/scala-C151Ov-r.js +1 -0
- package/public/assets/scheme-C98Dy4si.js +1 -0
- package/public/assets/scss-OYdSNvt2.js +1 -0
- package/public/assets/sdbl-DVxCFoDh.js +1 -0
- package/public/assets/shaderlab-Dg9Lc6iA.js +1 -0
- package/public/assets/shellscript-Yzrsuije.js +1 -0
- package/public/assets/shellsession-BADoaaVG.js +1 -0
- package/public/assets/slack-dark-BthQWCQV.js +1 -0
- package/public/assets/slack-ochin-DqwNpetd.js +1 -0
- package/public/assets/smalltalk-BERRCDM3.js +1 -0
- package/public/assets/snazzy-light-Bw305WKR.js +1 -0
- package/public/assets/solarized-dark-DXbdFlpD.js +1 -0
- package/public/assets/solarized-light-L9t79GZl.js +1 -0
- package/public/assets/solidity-BbcW6ACK.js +1 -0
- package/public/assets/soy-Brmx7dQM.js +1 -0
- package/public/assets/sparql-rVzFXLq3.js +1 -0
- package/public/assets/splunk-BtCnVYZw.js +1 -0
- package/public/assets/sql-BLtJtn59.js +1 -0
- package/public/assets/ssh-config-_ykCGR6B.js +1 -0
- package/public/assets/stata-BH5u7GGu.js +1 -0
- package/public/assets/stylus-BEDo0Tqx.js +1 -0
- package/public/assets/svelte-3Dk4HxPD.js +1 -0
- package/public/assets/swift-Dg5xB15N.js +1 -0
- package/public/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/public/assets/system-verilog-CnnmHF94.js +1 -0
- package/public/assets/systemd-4A_iFExJ.js +1 -0
- package/public/assets/talonscript-CkByrt1z.js +1 -0
- package/public/assets/tasl-QIJgUcNo.js +1 -0
- package/public/assets/tcl-dwOrl1Do.js +1 -0
- package/public/assets/templ-W15q3VgB.js +1 -0
- package/public/assets/terraform-BETggiCN.js +1 -0
- package/public/assets/tex-Cppo0RY3.js +1 -0
- package/public/assets/todo-uxdyLWei.js +1 -0
- package/public/assets/tokyo-night-hegEt444.js +1 -0
- package/public/assets/toml-vGWfd6FD.js +1 -0
- package/public/assets/tool-call-C_JEoVSV.js +60 -0
- package/public/assets/ts-tags-zn1MmPIZ.js +1 -0
- package/public/assets/tsv-B_m7g4N7.js +1 -0
- package/public/assets/tsx-COt5Ahok.js +1 -0
- package/public/assets/turtle-BsS91CYL.js +1 -0
- package/public/assets/twig-CO9l9SDP.js +1 -0
- package/public/assets/typescript-BPQ3VLAy.js +1 -0
- package/public/assets/typespec-Df68jz8_.js +1 -0
- package/public/assets/typst-DHCkPAjA.js +1 -0
- package/public/assets/unified-picker-ePaJEYDm.js +1 -0
- package/public/assets/v-BcVCzyr7.js +1 -0
- package/public/assets/vala-CsfeWuGM.js +1 -0
- package/public/assets/vb-D17OF-Vu.js +1 -0
- package/public/assets/verilog-BQ8w6xss.js +1 -0
- package/public/assets/vesper-DU1UobuO.js +1 -0
- package/public/assets/vhdl-CeAyd5Ju.js +1 -0
- package/public/assets/viml-CJc9bBzg.js +1 -0
- package/public/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/public/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/public/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/public/assets/vue-CCoi5OLL.js +1 -0
- package/public/assets/vue-html-DAAvJJDi.js +1 -0
- package/public/assets/vue-vine-_Ih-lPRR.js +1 -0
- package/public/assets/vyper-CDx5xZoG.js +1 -0
- package/public/assets/wasm-CG6Dc4jp.js +1 -0
- package/public/assets/wasm-MzD3tlZU.js +1 -0
- package/public/assets/wenyan-BV7otONQ.js +1 -0
- package/public/assets/wgsl-Dx-B1_4e.js +1 -0
- package/public/assets/wikitext-BhOHFoWU.js +1 -0
- package/public/assets/wit-5i3qLPDT.js +1 -0
- package/public/assets/wolfram-lXgVvXCa.js +1 -0
- package/public/assets/wrap-text-S8HH4qqP.js +1 -0
- package/public/assets/xml-sdJ4AIDG.js +1 -0
- package/public/assets/xsl-CtQFsRM5.js +1 -0
- package/public/assets/yaml-Buea-lGh.js +1 -0
- package/public/assets/zenscript-DVFEvuxE.js +1 -0
- package/public/assets/zig-VOosw3JB.js +1 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +44 -0
- package/public/loading.html +33 -0
- package/public/logo.png +0 -0
- package/public/manifest.webmanifest +1 -0
- package/public/maskable-icon-512x512.png +0 -0
- package/public/monaco/vs/base/browser/ui/codicons/codicon/codicon.ttf +0 -0
- package/public/monaco/vs/base/worker/workerMain.js +31 -0
- package/public/monaco/vs/basic-languages/cpp/cpp.js +10 -0
- package/public/monaco/vs/basic-languages/kotlin/kotlin.js +10 -0
- package/public/monaco/vs/basic-languages/markdown/markdown.js +10 -0
- package/public/monaco/vs/basic-languages/python/python.js +10 -0
- package/public/monaco/vs/editor/editor.main.css +8 -0
- package/public/monaco/vs/editor/editor.main.js +798 -0
- package/public/monaco/vs/language/css/cssMode.js +13 -0
- package/public/monaco/vs/language/css/cssWorker.js +77 -0
- package/public/monaco/vs/language/html/htmlMode.js +13 -0
- package/public/monaco/vs/language/html/htmlWorker.js +454 -0
- package/public/monaco/vs/language/json/jsonMode.js +19 -0
- package/public/monaco/vs/language/json/jsonWorker.js +42 -0
- package/public/monaco/vs/language/typescript/tsMode.js +20 -0
- package/public/monaco/vs/language/typescript/tsWorker.js +51328 -0
- package/public/monaco/vs/loader.js +11 -0
- package/public/monaco.worker.js +7 -0
- package/public/pwa-192x192.png +0 -0
- package/public/pwa-512x512.png +0 -0
- package/public/pwa-64x64.png +0 -0
- package/public/registerSW.js +1 -0
- package/public/sw.js +1 -0
- package/public/ui-version.json +3 -0
- package/public/workbox-60d14903.js +1 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { buildWindowsSpawnSpec, buildWslSignalSpec, parseWslUncPath, resolveWslWorkingDirectory } from "../spawn";
|
|
4
|
+
describe("parseWslUncPath", () => {
|
|
5
|
+
it("parses WSL UNC paths into distro and linux path", () => {
|
|
6
|
+
assert.deepEqual(parseWslUncPath(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`), {
|
|
7
|
+
distro: "Ubuntu",
|
|
8
|
+
linuxPath: "/home/dev/.opencode/bin/opencode",
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
it("supports the legacy wsl$ UNC prefix", () => {
|
|
12
|
+
assert.deepEqual(parseWslUncPath(String.raw `\\wsl$\Ubuntu\home\dev`), {
|
|
13
|
+
distro: "Ubuntu",
|
|
14
|
+
linuxPath: "/home/dev",
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe("resolveWslWorkingDirectory", () => {
|
|
19
|
+
it("keeps WSL workspace folders in the same distro", () => {
|
|
20
|
+
assert.equal(JSON.stringify(resolveWslWorkingDirectory(String.raw `\\wsl.localhost\Ubuntu\home\dev\workspace`, "Ubuntu")), JSON.stringify({ kind: "linux", path: "/home/dev/workspace" }));
|
|
21
|
+
});
|
|
22
|
+
it("keeps Windows drive paths so WSL can resolve them with wslpath", () => {
|
|
23
|
+
assert.equal(JSON.stringify(resolveWslWorkingDirectory(String.raw `C:\Users\dev\workspace`, "Ubuntu")), JSON.stringify({ kind: "windows", path: String.raw `C:\Users\dev\workspace` }));
|
|
24
|
+
});
|
|
25
|
+
it("keeps UNC network paths so WSL can resolve them with wslpath", () => {
|
|
26
|
+
assert.equal(JSON.stringify(resolveWslWorkingDirectory(String.raw `\\server\share\workspace`, "Ubuntu")), JSON.stringify({ kind: "windows", path: String.raw `\\server\share\workspace` }));
|
|
27
|
+
});
|
|
28
|
+
it("rejects WSL workspace folders from a different distro", () => {
|
|
29
|
+
assert.equal(resolveWslWorkingDirectory(String.raw `\\wsl.localhost\Debian\home\dev\workspace`, "Ubuntu"), null);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe("buildWindowsSpawnSpec", () => {
|
|
33
|
+
it("wraps WSL binaries with wsl.exe and propagates required env vars", () => {
|
|
34
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve", "--port", "0"], {
|
|
35
|
+
cwd: String.raw `\\wsl.localhost\Ubuntu\home\dev\workspace`,
|
|
36
|
+
env: {
|
|
37
|
+
OPENCODE_CONFIG_DIR: String.raw `C:\Users\dev\AppData\Roaming\EmbeddedCowork\opencode-config`,
|
|
38
|
+
EMBEDDEDCOWORK_INSTANCE_ID: "workspace-123",
|
|
39
|
+
OPENCODE_SERVER_PASSWORD: "secret",
|
|
40
|
+
},
|
|
41
|
+
propagateEnvKeys: ["OPENCODE_CONFIG_DIR", "EMBEDDEDCOWORK_INSTANCE_ID", "OPENCODE_SERVER_PASSWORD"],
|
|
42
|
+
});
|
|
43
|
+
assert.equal(spec.command, "wsl.exe");
|
|
44
|
+
assert.deepEqual(spec.args, [
|
|
45
|
+
"--distribution",
|
|
46
|
+
"Ubuntu",
|
|
47
|
+
"--cd",
|
|
48
|
+
"/home/dev/workspace",
|
|
49
|
+
"--exec",
|
|
50
|
+
"/home/dev/.opencode/bin/opencode",
|
|
51
|
+
"serve",
|
|
52
|
+
"--port",
|
|
53
|
+
"0",
|
|
54
|
+
]);
|
|
55
|
+
assert.equal(spec.cwd, undefined);
|
|
56
|
+
assert.equal(spec.env?.WSLENV, "OPENCODE_CONFIG_DIR/p:EMBEDDEDCOWORK_INSTANCE_ID:OPENCODE_SERVER_PASSWORD");
|
|
57
|
+
});
|
|
58
|
+
it("upgrades existing WSLENV path entries to include /p", () => {
|
|
59
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve"], {
|
|
60
|
+
env: {
|
|
61
|
+
OPENCODE_CONFIG_DIR: String.raw `C:\Users\dev\AppData\Roaming\EmbeddedCowork\opencode-config`,
|
|
62
|
+
WSLENV: "OPENCODE_CONFIG_DIR:EMBEDDEDCOWORK_INSTANCE_ID/u",
|
|
63
|
+
},
|
|
64
|
+
propagateEnvKeys: ["OPENCODE_CONFIG_DIR", "EMBEDDEDCOWORK_INSTANCE_ID"],
|
|
65
|
+
});
|
|
66
|
+
assert.equal(spec.env?.WSLENV, "OPENCODE_CONFIG_DIR/p:EMBEDDEDCOWORK_INSTANCE_ID/u");
|
|
67
|
+
});
|
|
68
|
+
it("propagates inherited known path variables even when they are not explicitly requested", () => {
|
|
69
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve"], {
|
|
70
|
+
env: {
|
|
71
|
+
NODE_EXTRA_CA_CERTS: String.raw `C:\certs\root.pem`,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
assert.equal(spec.env?.WSLENV, "NODE_EXTRA_CA_CERTS/p");
|
|
75
|
+
});
|
|
76
|
+
it("uses wslpath for Windows workspace folders instead of assuming /mnt", () => {
|
|
77
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve", "--port", "0"], {
|
|
78
|
+
cwd: String.raw `C:\Users\dev\workspace`,
|
|
79
|
+
});
|
|
80
|
+
assert.equal(spec.command, "wsl.exe");
|
|
81
|
+
assert.deepEqual(spec.args, [
|
|
82
|
+
"--distribution",
|
|
83
|
+
"Ubuntu",
|
|
84
|
+
"--exec",
|
|
85
|
+
"sh",
|
|
86
|
+
"-lc",
|
|
87
|
+
'cd "$(wslpath -au "$1")" && shift && exec "$@"',
|
|
88
|
+
"embeddedcowork-wsl-launch",
|
|
89
|
+
String.raw `C:\Users\dev\workspace`,
|
|
90
|
+
"/home/dev/.opencode/bin/opencode",
|
|
91
|
+
"serve",
|
|
92
|
+
"--port",
|
|
93
|
+
"0",
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
it("uses wslpath for UNC network workspace folders", () => {
|
|
97
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve"], {
|
|
98
|
+
cwd: String.raw `\\server\share\workspace`,
|
|
99
|
+
});
|
|
100
|
+
assert.equal(spec.command, "wsl.exe");
|
|
101
|
+
assert.deepEqual(spec.args, [
|
|
102
|
+
"--distribution",
|
|
103
|
+
"Ubuntu",
|
|
104
|
+
"--exec",
|
|
105
|
+
"sh",
|
|
106
|
+
"-lc",
|
|
107
|
+
'cd "$(wslpath -au "$1")" && shift && exec "$@"',
|
|
108
|
+
"embeddedcowork-wsl-launch",
|
|
109
|
+
String.raw `\\server\share\workspace`,
|
|
110
|
+
"/home/dev/.opencode/bin/opencode",
|
|
111
|
+
"serve",
|
|
112
|
+
]);
|
|
113
|
+
});
|
|
114
|
+
it("can wrap WSL launches to emit the Linux PID marker", () => {
|
|
115
|
+
const spec = buildWindowsSpawnSpec(String.raw `\\wsl.localhost\Ubuntu\home\dev\.opencode\bin\opencode`, ["serve"], {
|
|
116
|
+
cwd: String.raw `\\wsl.localhost\Ubuntu\home\dev\workspace`,
|
|
117
|
+
wslPidMarker: "__EMBEDDEDCOWORK_WSL_PID__:",
|
|
118
|
+
});
|
|
119
|
+
assert.equal(spec.command, "wsl.exe");
|
|
120
|
+
assert.deepEqual(spec.args, [
|
|
121
|
+
"--distribution",
|
|
122
|
+
"Ubuntu",
|
|
123
|
+
"--exec",
|
|
124
|
+
"sh",
|
|
125
|
+
"-lc",
|
|
126
|
+
`printf '%s%s\\n' '__EMBEDDEDCOWORK_WSL_PID__:' "$$" && cd "$1" && shift && exec "$@"`,
|
|
127
|
+
"embeddedcowork-wsl-launch",
|
|
128
|
+
"/home/dev/workspace",
|
|
129
|
+
"/home/dev/.opencode/bin/opencode",
|
|
130
|
+
"serve",
|
|
131
|
+
]);
|
|
132
|
+
assert.equal(spec.wsl?.pidMarker, "__EMBEDDEDCOWORK_WSL_PID__:");
|
|
133
|
+
});
|
|
134
|
+
it("builds the WSL kill command for tracked Linux PIDs", () => {
|
|
135
|
+
const spec = buildWslSignalSpec("Ubuntu", 4321, "SIGTERM");
|
|
136
|
+
assert.equal(spec.command, "wsl.exe");
|
|
137
|
+
assert.deepEqual(spec.args, ["--distribution", "Ubuntu", "--exec", "kill", "-TERM", "4321"]);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
class GitMutationError extends Error {
|
|
4
|
+
constructor(message, statusCode = 400) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "GitMutationError";
|
|
7
|
+
this.statusCode = statusCode;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function runGit(args, cwd) {
|
|
11
|
+
return new Promise((resolve) => {
|
|
12
|
+
const child = spawn("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
13
|
+
let stdout = "";
|
|
14
|
+
let stderr = "";
|
|
15
|
+
child.stdout?.on("data", (chunk) => {
|
|
16
|
+
stdout += chunk.toString();
|
|
17
|
+
});
|
|
18
|
+
child.stderr?.on("data", (chunk) => {
|
|
19
|
+
stderr += chunk.toString();
|
|
20
|
+
});
|
|
21
|
+
child.once("error", (error) => {
|
|
22
|
+
resolve({ ok: false, error, stdout, stderr });
|
|
23
|
+
});
|
|
24
|
+
child.once("close", (code) => {
|
|
25
|
+
if (code === 0) {
|
|
26
|
+
resolve({ ok: true, stdout });
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const error = new Error(stderr.trim() || `git ${args.join(" ")} failed with code ${code}`);
|
|
30
|
+
resolve({ ok: false, error, stdout, stderr });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function normalizeGitWorktreeRelativePath(input) {
|
|
36
|
+
const normalized = input.trim().replace(/\\+/g, "/").replace(/^\.\//, "");
|
|
37
|
+
if (!normalized) {
|
|
38
|
+
throw new GitMutationError("Path is required", 400);
|
|
39
|
+
}
|
|
40
|
+
if (path.posix.isAbsolute(normalized) || path.win32.isAbsolute(normalized)) {
|
|
41
|
+
throw new GitMutationError(`Absolute paths are not allowed: ${input}`, 400);
|
|
42
|
+
}
|
|
43
|
+
if (normalized === "." || normalized === "..") {
|
|
44
|
+
throw new GitMutationError(`Invalid path: ${input}`, 400);
|
|
45
|
+
}
|
|
46
|
+
if (normalized.startsWith("../") || normalized.includes("/../") || normalized.endsWith("/..")) {
|
|
47
|
+
throw new GitMutationError(`Path traversal is not allowed: ${input}`, 400);
|
|
48
|
+
}
|
|
49
|
+
return normalized;
|
|
50
|
+
}
|
|
51
|
+
function normalizeGitMutationPaths(paths) {
|
|
52
|
+
const deduped = new Set();
|
|
53
|
+
for (const rawPath of paths) {
|
|
54
|
+
deduped.add(normalizeGitWorktreeRelativePath(rawPath));
|
|
55
|
+
}
|
|
56
|
+
const normalized = Array.from(deduped);
|
|
57
|
+
if (normalized.length === 0) {
|
|
58
|
+
throw new GitMutationError("At least one path is required", 400);
|
|
59
|
+
}
|
|
60
|
+
return normalized;
|
|
61
|
+
}
|
|
62
|
+
async function ensureGitCommandSucceeded(resultPromise, fallbackMessage) {
|
|
63
|
+
const result = await resultPromise;
|
|
64
|
+
if (!result.ok) {
|
|
65
|
+
const message = result.stderr?.trim() || result.error.message || fallbackMessage;
|
|
66
|
+
throw new GitMutationError(message, 409);
|
|
67
|
+
}
|
|
68
|
+
return result.stdout;
|
|
69
|
+
}
|
|
70
|
+
export function isGitMutationError(error) {
|
|
71
|
+
return error instanceof GitMutationError;
|
|
72
|
+
}
|
|
73
|
+
export async function stageWorktreePaths(params) {
|
|
74
|
+
const paths = normalizeGitMutationPaths(params.paths);
|
|
75
|
+
await ensureGitCommandSucceeded(runGit(["add", "--", ...paths], params.workspaceFolder), "Failed to stage files");
|
|
76
|
+
}
|
|
77
|
+
export async function unstageWorktreePaths(params) {
|
|
78
|
+
const paths = normalizeGitMutationPaths(params.paths);
|
|
79
|
+
const headResult = await runGit(["rev-parse", "--verify", "HEAD"], params.workspaceFolder);
|
|
80
|
+
if (headResult.ok) {
|
|
81
|
+
await ensureGitCommandSucceeded(runGit(["restore", "--staged", "--", ...paths], params.workspaceFolder), "Failed to unstage files");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
await ensureGitCommandSucceeded(runGit(["rm", "--cached", "--quiet", "--", ...paths], params.workspaceFolder), "Failed to unstage files");
|
|
85
|
+
}
|
|
86
|
+
export async function commitWorktreeChanges(params) {
|
|
87
|
+
const message = params.message.trim();
|
|
88
|
+
if (!message) {
|
|
89
|
+
throw new GitMutationError("Commit message is required", 400);
|
|
90
|
+
}
|
|
91
|
+
await ensureGitCommandSucceeded(runGit(["commit", "-m", message], params.workspaceFolder), "Failed to create commit");
|
|
92
|
+
const shaResult = await runGit(["rev-parse", "HEAD"], params.workspaceFolder);
|
|
93
|
+
if (!shaResult.ok) {
|
|
94
|
+
return {};
|
|
95
|
+
}
|
|
96
|
+
const commitSha = shaResult.stdout.trim();
|
|
97
|
+
return commitSha ? { commitSha } : {};
|
|
98
|
+
}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
import { readFile } from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { normalizeGitWorktreeRelativePath } from "./git-mutations";
|
|
5
|
+
async function readFileAsDiffText(filePath) {
|
|
6
|
+
return readFile(filePath, "utf-8");
|
|
7
|
+
}
|
|
8
|
+
async function readGitBlobAsDiffText(resultPromise, missingOk = false) {
|
|
9
|
+
const result = await resultPromise;
|
|
10
|
+
if (!result.ok) {
|
|
11
|
+
return decodeGitShowResult(result, missingOk);
|
|
12
|
+
}
|
|
13
|
+
return result.stdout;
|
|
14
|
+
}
|
|
15
|
+
function runGit(args, cwd, acceptedExitCodes = [0]) {
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
const child = spawn("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
18
|
+
let stdout = "";
|
|
19
|
+
let stderr = "";
|
|
20
|
+
child.stdout?.on("data", (chunk) => {
|
|
21
|
+
stdout += chunk.toString();
|
|
22
|
+
});
|
|
23
|
+
child.stderr?.on("data", (chunk) => {
|
|
24
|
+
stderr += chunk.toString();
|
|
25
|
+
});
|
|
26
|
+
child.once("error", (error) => {
|
|
27
|
+
resolve({ ok: false, error, stdout, stderr });
|
|
28
|
+
});
|
|
29
|
+
child.once("close", (code) => {
|
|
30
|
+
if (acceptedExitCodes.includes(code ?? 0)) {
|
|
31
|
+
resolve({ ok: true, stdout });
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const error = new Error(stderr.trim() || `git ${args.join(" ")} failed with code ${code}`);
|
|
35
|
+
resolve({ ok: false, error, stdout, stderr });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function ensureEntry(map, path) {
|
|
41
|
+
const existing = map.get(path);
|
|
42
|
+
if (existing)
|
|
43
|
+
return existing;
|
|
44
|
+
const next = {
|
|
45
|
+
path,
|
|
46
|
+
originalPath: null,
|
|
47
|
+
stagedStatus: null,
|
|
48
|
+
stagedAdditions: 0,
|
|
49
|
+
stagedDeletions: 0,
|
|
50
|
+
unstagedStatus: null,
|
|
51
|
+
unstagedAdditions: 0,
|
|
52
|
+
unstagedDeletions: 0,
|
|
53
|
+
};
|
|
54
|
+
map.set(path, next);
|
|
55
|
+
return next;
|
|
56
|
+
}
|
|
57
|
+
function normalizeGitStatusPath(value) {
|
|
58
|
+
return value.trim().replace(/\\+/g, "/");
|
|
59
|
+
}
|
|
60
|
+
function parseGitChangeKind(code) {
|
|
61
|
+
const normalized = code.trim().toUpperCase();
|
|
62
|
+
if (!normalized)
|
|
63
|
+
return null;
|
|
64
|
+
if (normalized === "A")
|
|
65
|
+
return "added";
|
|
66
|
+
if (normalized === "M")
|
|
67
|
+
return "modified";
|
|
68
|
+
if (normalized === "D")
|
|
69
|
+
return "deleted";
|
|
70
|
+
if (normalized.startsWith("R"))
|
|
71
|
+
return "renamed";
|
|
72
|
+
if (normalized.startsWith("C"))
|
|
73
|
+
return "copied";
|
|
74
|
+
if (normalized === "U")
|
|
75
|
+
return "unmerged";
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
function applyNameStatusOutput(map, output, target) {
|
|
79
|
+
const tokens = output.split("\0");
|
|
80
|
+
let index = 0;
|
|
81
|
+
while (index < tokens.length) {
|
|
82
|
+
const record = tokens[index++] ?? "";
|
|
83
|
+
if (!record)
|
|
84
|
+
continue;
|
|
85
|
+
const parts = record.split("\t");
|
|
86
|
+
const statusCode = parseGitChangeKind(parts[0] ?? "");
|
|
87
|
+
if (!statusCode)
|
|
88
|
+
continue;
|
|
89
|
+
const inlinePath = parts.slice(1).join("\t");
|
|
90
|
+
const firstPath = inlinePath || tokens[index++] || "";
|
|
91
|
+
const secondPath = statusCode === "renamed" || statusCode === "copied" ? tokens[index++] || "" : "";
|
|
92
|
+
const path = statusCode === "renamed" || statusCode === "copied" ? secondPath || firstPath : firstPath;
|
|
93
|
+
const normalizedPath = normalizeGitStatusPath(path);
|
|
94
|
+
if (!normalizedPath)
|
|
95
|
+
continue;
|
|
96
|
+
const entry = ensureEntry(map, normalizedPath);
|
|
97
|
+
entry[target] = statusCode;
|
|
98
|
+
if (statusCode === "renamed" || statusCode === "copied") {
|
|
99
|
+
const originalPath = normalizeGitStatusPath(firstPath);
|
|
100
|
+
entry.originalPath = originalPath || entry.originalPath || null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function applyUntrackedOutput(map, output) {
|
|
105
|
+
for (const rawLine of output.split(/\r?\n/)) {
|
|
106
|
+
const path = normalizeGitStatusPath(rawLine);
|
|
107
|
+
if (!path)
|
|
108
|
+
continue;
|
|
109
|
+
ensureEntry(map, path).unstagedStatus = "untracked";
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function parseSingleNumstat(output) {
|
|
113
|
+
for (const rawLine of output.split(/\r?\n/)) {
|
|
114
|
+
const line = rawLine.trim();
|
|
115
|
+
if (!line)
|
|
116
|
+
continue;
|
|
117
|
+
const parts = rawLine.split("\t");
|
|
118
|
+
const isBinary = parts[0] === "-" || parts[1] === "-";
|
|
119
|
+
return {
|
|
120
|
+
additions: isBinary ? 0 : Number.parseInt(parts[0] ?? "0", 10) || 0,
|
|
121
|
+
deletions: isBinary ? 0 : Number.parseInt(parts[1] ?? "0", 10) || 0,
|
|
122
|
+
isBinary,
|
|
123
|
+
found: true,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return { additions: 0, deletions: 0, isBinary: false, found: false };
|
|
127
|
+
}
|
|
128
|
+
async function getUntrackedFileNumstat(workspaceFolder, relativePath) {
|
|
129
|
+
const absolutePath = path.join(workspaceFolder, relativePath);
|
|
130
|
+
const result = await runGit(["diff", "--numstat", "--no-index", "--", "/dev/null", absolutePath], workspaceFolder, [0, 1]);
|
|
131
|
+
if (!result.ok) {
|
|
132
|
+
throw result.error;
|
|
133
|
+
}
|
|
134
|
+
const parsed = parseSingleNumstat(result.stdout);
|
|
135
|
+
return { additions: parsed.additions, deletions: parsed.deletions };
|
|
136
|
+
}
|
|
137
|
+
async function applyUntrackedFileStats(map, workspaceFolder) {
|
|
138
|
+
const pending = Array.from(map.values())
|
|
139
|
+
.filter((entry) => entry.unstagedStatus === "untracked")
|
|
140
|
+
.map(async (entry) => {
|
|
141
|
+
try {
|
|
142
|
+
const stats = await getUntrackedFileNumstat(workspaceFolder, entry.path);
|
|
143
|
+
entry.unstagedAdditions = stats.additions;
|
|
144
|
+
entry.unstagedDeletions = stats.deletions;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
entry.unstagedAdditions = 0;
|
|
148
|
+
entry.unstagedDeletions = 0;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
await Promise.all(pending);
|
|
152
|
+
}
|
|
153
|
+
function applyNumstatOutput(map, output, target) {
|
|
154
|
+
const tokens = output.split("\0");
|
|
155
|
+
let index = 0;
|
|
156
|
+
while (index < tokens.length) {
|
|
157
|
+
const record = tokens[index++] ?? "";
|
|
158
|
+
if (!record)
|
|
159
|
+
continue;
|
|
160
|
+
const parts = record.split("\t");
|
|
161
|
+
if (parts.length < 3)
|
|
162
|
+
continue;
|
|
163
|
+
const additions = parts[0] === "-" ? 0 : Number.parseInt(parts[0] ?? "0", 10);
|
|
164
|
+
const deletions = parts[1] === "-" ? 0 : Number.parseInt(parts[1] ?? "0", 10);
|
|
165
|
+
const inlinePath = parts.slice(2).join("\t");
|
|
166
|
+
const isRenameLike = inlinePath === "";
|
|
167
|
+
const originalPath = isRenameLike ? normalizeGitStatusPath(tokens[index++] ?? "") : null;
|
|
168
|
+
const normalizedPath = normalizeGitStatusPath(isRenameLike ? tokens[index++] ?? "" : inlinePath);
|
|
169
|
+
if (!normalizedPath)
|
|
170
|
+
continue;
|
|
171
|
+
const entry = ensureEntry(map, normalizedPath);
|
|
172
|
+
if (originalPath) {
|
|
173
|
+
entry.originalPath = originalPath;
|
|
174
|
+
}
|
|
175
|
+
if (target === "staged") {
|
|
176
|
+
entry.stagedAdditions = Number.isFinite(additions) ? additions : 0;
|
|
177
|
+
entry.stagedDeletions = Number.isFinite(deletions) ? deletions : 0;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
entry.unstagedAdditions = Number.isFinite(additions) ? additions : 0;
|
|
181
|
+
entry.unstagedDeletions = Number.isFinite(deletions) ? deletions : 0;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
export async function getWorktreeGitStatus(params) {
|
|
186
|
+
const { workspaceFolder, logger } = params;
|
|
187
|
+
const [stagedResult, unstagedResult, untrackedResult, stagedNumstatResult, unstagedNumstatResult] = await Promise.all([
|
|
188
|
+
runGit(["diff", "--name-status", "-z", "--cached", "--find-renames", "--find-copies"], workspaceFolder),
|
|
189
|
+
runGit(["diff", "--name-status", "-z", "--find-renames", "--find-copies"], workspaceFolder),
|
|
190
|
+
runGit(["ls-files", "--others", "--exclude-standard"], workspaceFolder),
|
|
191
|
+
runGit(["diff", "--numstat", "-z", "--cached", "--find-renames", "--find-copies"], workspaceFolder),
|
|
192
|
+
runGit(["diff", "--numstat", "-z", "--find-renames", "--find-copies"], workspaceFolder),
|
|
193
|
+
]);
|
|
194
|
+
for (const result of [stagedResult, unstagedResult, untrackedResult, stagedNumstatResult, unstagedNumstatResult]) {
|
|
195
|
+
if (!result.ok) {
|
|
196
|
+
logger?.warn?.({ workspaceFolder, err: result.error }, "Failed to read git status for worktree");
|
|
197
|
+
throw result.error;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const stagedOutput = stagedResult.stdout;
|
|
201
|
+
const unstagedOutput = unstagedResult.stdout;
|
|
202
|
+
const untrackedOutput = untrackedResult.stdout;
|
|
203
|
+
const stagedNumstatOutput = stagedNumstatResult.stdout;
|
|
204
|
+
const unstagedNumstatOutput = unstagedNumstatResult.stdout;
|
|
205
|
+
const entries = new Map();
|
|
206
|
+
applyNameStatusOutput(entries, stagedOutput, "stagedStatus");
|
|
207
|
+
applyNameStatusOutput(entries, unstagedOutput, "unstagedStatus");
|
|
208
|
+
applyUntrackedOutput(entries, untrackedOutput);
|
|
209
|
+
applyNumstatOutput(entries, stagedNumstatOutput, "staged");
|
|
210
|
+
applyNumstatOutput(entries, unstagedNumstatOutput, "unstaged");
|
|
211
|
+
await applyUntrackedFileStats(entries, workspaceFolder);
|
|
212
|
+
return Array.from(entries.values()).sort((a, b) => a.path.localeCompare(b.path));
|
|
213
|
+
}
|
|
214
|
+
function decodeGitShowResult(result, missingOk = false) {
|
|
215
|
+
if (result.ok)
|
|
216
|
+
return result.stdout;
|
|
217
|
+
const message = result.stderr?.trim() || result.error.message || "";
|
|
218
|
+
if (missingOk &&
|
|
219
|
+
(message.includes("exists on disk, but not in") ||
|
|
220
|
+
message.includes("Path '") ||
|
|
221
|
+
message.includes("does not exist") ||
|
|
222
|
+
message.includes("unknown revision or path not in the working tree"))) {
|
|
223
|
+
return "";
|
|
224
|
+
}
|
|
225
|
+
throw result.error;
|
|
226
|
+
}
|
|
227
|
+
async function readGitIndexBlob(workspaceFolder, normalizedPath) {
|
|
228
|
+
return runGit(["cat-file", "-p", `:${normalizedPath}`], workspaceFolder);
|
|
229
|
+
}
|
|
230
|
+
async function getTrackedDiffMetadata(params) {
|
|
231
|
+
const args = ["diff", "--numstat"];
|
|
232
|
+
if (params.scope === "staged") {
|
|
233
|
+
args.push("--cached");
|
|
234
|
+
}
|
|
235
|
+
args.push("--find-renames", "--find-copies", "--");
|
|
236
|
+
args.push(params.normalizedPath);
|
|
237
|
+
if (params.normalizedOriginalPath && params.normalizedOriginalPath !== params.normalizedPath) {
|
|
238
|
+
args.push(params.normalizedOriginalPath);
|
|
239
|
+
}
|
|
240
|
+
const result = await runGit(args, params.workspaceFolder);
|
|
241
|
+
if (!result.ok) {
|
|
242
|
+
throw result.error;
|
|
243
|
+
}
|
|
244
|
+
const parsed = parseSingleNumstat(result.stdout);
|
|
245
|
+
return { isBinary: parsed.isBinary, found: parsed.found };
|
|
246
|
+
}
|
|
247
|
+
async function getUntrackedDiffMetadata(params) {
|
|
248
|
+
const absolutePath = path.join(params.workspaceFolder, params.normalizedPath);
|
|
249
|
+
const result = await runGit(["diff", "--numstat", "--no-index", "--", "/dev/null", absolutePath], params.workspaceFolder, [0, 1]);
|
|
250
|
+
if (!result.ok) {
|
|
251
|
+
throw result.error;
|
|
252
|
+
}
|
|
253
|
+
return { isBinary: parseSingleNumstat(result.stdout).isBinary };
|
|
254
|
+
}
|
|
255
|
+
async function resolveUnstagedBeforePath(params) {
|
|
256
|
+
const currentPathResult = await readGitIndexBlob(params.workspaceFolder, params.normalizedPath);
|
|
257
|
+
if (currentPathResult.ok || !params.normalizedOriginalPath || params.normalizedOriginalPath === params.normalizedPath) {
|
|
258
|
+
return currentPathResult;
|
|
259
|
+
}
|
|
260
|
+
return readGitIndexBlob(params.workspaceFolder, params.normalizedOriginalPath);
|
|
261
|
+
}
|
|
262
|
+
export async function getWorktreeGitDiff(params) {
|
|
263
|
+
const normalizedPath = normalizeGitWorktreeRelativePath(params.path);
|
|
264
|
+
const normalizedOriginalPath = params.originalPath ? normalizeGitWorktreeRelativePath(params.originalPath) : null;
|
|
265
|
+
const trackedMetadata = await getTrackedDiffMetadata({
|
|
266
|
+
workspaceFolder: params.workspaceFolder,
|
|
267
|
+
scope: params.scope,
|
|
268
|
+
normalizedPath,
|
|
269
|
+
normalizedOriginalPath,
|
|
270
|
+
});
|
|
271
|
+
const diffMetadata = params.scope === "unstaged" && !trackedMetadata.found
|
|
272
|
+
? await getUntrackedDiffMetadata({
|
|
273
|
+
workspaceFolder: params.workspaceFolder,
|
|
274
|
+
normalizedPath,
|
|
275
|
+
})
|
|
276
|
+
: trackedMetadata;
|
|
277
|
+
if (diffMetadata.isBinary) {
|
|
278
|
+
return {
|
|
279
|
+
path: normalizedPath,
|
|
280
|
+
originalPath: normalizedOriginalPath,
|
|
281
|
+
scope: params.scope,
|
|
282
|
+
before: "",
|
|
283
|
+
after: "",
|
|
284
|
+
isBinary: true,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
if (params.scope === "staged") {
|
|
288
|
+
const [beforeResult, afterResult] = await Promise.all([
|
|
289
|
+
readGitBlobAsDiffText(runGit(["show", `HEAD:${normalizedOriginalPath ?? normalizedPath}`], params.workspaceFolder), true),
|
|
290
|
+
readGitBlobAsDiffText(readGitIndexBlob(params.workspaceFolder, normalizedPath), true),
|
|
291
|
+
]);
|
|
292
|
+
return {
|
|
293
|
+
path: normalizedPath,
|
|
294
|
+
originalPath: normalizedOriginalPath,
|
|
295
|
+
scope: params.scope,
|
|
296
|
+
before: beforeResult,
|
|
297
|
+
after: afterResult,
|
|
298
|
+
isBinary: false,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
const indexResult = await resolveUnstagedBeforePath({
|
|
302
|
+
workspaceFolder: params.workspaceFolder,
|
|
303
|
+
normalizedPath,
|
|
304
|
+
normalizedOriginalPath,
|
|
305
|
+
});
|
|
306
|
+
const beforeResult = await readGitBlobAsDiffText(Promise.resolve(indexResult), true);
|
|
307
|
+
let after = beforeResult;
|
|
308
|
+
const fsPath = path.join(params.workspaceFolder, normalizedPath);
|
|
309
|
+
try {
|
|
310
|
+
after = await readFileAsDiffText(fsPath);
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
after = "";
|
|
314
|
+
}
|
|
315
|
+
return {
|
|
316
|
+
path: normalizedPath,
|
|
317
|
+
originalPath: normalizedOriginalPath,
|
|
318
|
+
scope: params.scope,
|
|
319
|
+
before: beforeResult,
|
|
320
|
+
after,
|
|
321
|
+
isBinary: false,
|
|
322
|
+
};
|
|
323
|
+
}
|