@chainingintention/pi-web-cn 2.202610.5 → 2.202611.2
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 +4 -2
- package/dist/bin/pi-web-server.sh +91 -0
- package/dist/bin/pi-web-sessiond.sh +91 -0
- package/dist/bin/pi-web.sh +91 -0
- package/dist/cli.js +33 -29
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/3d-Dr68X8h8.svg +1 -0
- package/dist/client/assets/PiWebApp-Dur6Wi62.js +3952 -0
- package/dist/client/assets/SettingsDialog-SOljSiee.js +1129 -0
- package/dist/client/assets/abap-uAHVFerN.svg +1 -0
- package/dist/client/assets/abc-CXjdSXsv.svg +1 -0
- package/dist/client/assets/actionscript-BCkIwjgm.svg +1 -0
- package/dist/client/assets/ada-GL6JWmc_.svg +1 -0
- package/dist/client/assets/adobe-illustrator-DhGvkpwi.svg +1 -0
- package/dist/client/assets/adobe-photoshop-0hmnA7cm.svg +1 -0
- package/dist/client/assets/adobe-swc-myFGSGFT.svg +1 -0
- package/dist/client/assets/adonis-SdGYdzCA.svg +1 -0
- package/dist/client/assets/advpl-BWLgf_Ky.svg +1 -0
- package/dist/client/assets/advpl-include-DYgH3R0u.svg +1 -0
- package/dist/client/assets/advpl-ptm-C5Y5ffZi.svg +1 -0
- package/dist/client/assets/advpl-tlpp-BAlVwpPL.svg +1 -0
- package/dist/client/assets/agent-DAWBwR7s.svg +1 -0
- package/dist/client/assets/amplify-BAWPaFFb.svg +1 -0
- package/dist/client/assets/android-TigHCxTb.svg +1 -0
- package/dist/client/assets/angular-D2ijCUIg.svg +1 -0
- package/dist/client/assets/angular-component-eczQQRE6.svg +1 -0
- package/dist/client/assets/angular-directive-C_jq8cjP.svg +1 -0
- package/dist/client/assets/angular-guard-B4iC5rXF.svg +1 -0
- package/dist/client/assets/angular-interceptor-CJvi6DuQ.svg +1 -0
- package/dist/client/assets/angular-pipe-BQZMATB_.svg +1 -0
- package/dist/client/assets/angular-service-DHYn6jIk.svg +1 -0
- package/dist/client/assets/antlr-DkzdiGgY.svg +1 -0
- package/dist/client/assets/apiblueprint-BDRvCIBM.svg +1 -0
- package/dist/client/assets/apollo-BAVoyYDs.svg +1 -0
- package/dist/client/assets/applescript-Bm_R8YT0.svg +1 -0
- package/dist/client/assets/apps-script-6efl-CXu.svg +1 -0
- package/dist/client/assets/appveyor-6B1suIBr.svg +1 -0
- package/dist/client/assets/appwrite-D7AlK8SW.svg +1 -0
- package/dist/client/assets/architecture-CtuqF8rD.svg +1 -0
- package/dist/client/assets/arduino-DFxCIupZ.svg +1 -0
- package/dist/client/assets/asciidoc-DUAdVwVP.svg +1 -0
- package/dist/client/assets/assembly-BKikEKKy.svg +1 -0
- package/dist/client/assets/astro-Bivf18eC.svg +1 -0
- package/dist/client/assets/astro-config-Cr5suFul.svg +1 -0
- package/dist/client/assets/astyle-BiqOWu-0.svg +1 -0
- package/dist/client/assets/audio-B4FatEUD.svg +1 -0
- package/dist/client/assets/aurelia-CnUjHPcZ.svg +1 -0
- package/dist/client/assets/authors-DdaDoKVR.svg +1 -0
- package/dist/client/assets/auto-BOO_fhxh.svg +1 -0
- package/dist/client/assets/autohotkey-D87F33UG.svg +1 -0
- package/dist/client/assets/autoit-DQTGS66r.svg +1 -0
- package/dist/client/assets/azure-DMSkMABH.svg +1 -0
- package/dist/client/assets/azure-pipelines-CcGJw3Rl.svg +1 -0
- package/dist/client/assets/babel-DFMbiqHA.svg +1 -0
- package/dist/client/assets/ballerina-BT8MyHl8.svg +1 -0
- package/dist/client/assets/bashly-settings-Ch9mIpw9.svg +1 -0
- package/dist/client/assets/bazel-CPXexffJ.svg +1 -0
- package/dist/client/assets/bbx-CB-6IYxw.svg +1 -0
- package/dist/client/assets/beancount-DR_GSwds.svg +1 -0
- package/dist/client/assets/bench-js-DOHd4EZB.svg +1 -0
- package/dist/client/assets/bench-jsx-CLJJl81D.svg +1 -0
- package/dist/client/assets/bench-ts-BM8GsfrF.svg +1 -0
- package/dist/client/assets/bibliography-D3emS1pd.svg +1 -0
- package/dist/client/assets/bibtex-style-CVY4tTiP.svg +1 -0
- package/dist/client/assets/bicep-BMMGt18P.svg +1 -0
- package/dist/client/assets/biome-Bf2373dl.svg +1 -0
- package/dist/client/assets/bitbucket-BQr8Az5R.svg +1 -0
- package/dist/client/assets/bithound-BOh7-s-G.svg +1 -0
- package/dist/client/assets/blender-B7Vz8gxa.svg +1 -0
- package/dist/client/assets/blink-DVWcfhba.svg +1 -0
- package/dist/client/assets/blitz-B4hhOxPa.svg +1 -0
- package/dist/client/assets/bower-CkFcC1Ou.svg +1 -0
- package/dist/client/assets/brainfuck-BXozg9z7.svg +1 -0
- package/dist/client/assets/browserlist-CUbhNMS9.svg +1 -0
- package/dist/client/assets/bruno-CoSNrNfv.svg +1 -0
- package/dist/client/assets/buck-BRuOl0ko.svg +1 -0
- package/dist/client/assets/bucklescript-TfoVgTnq.svg +1 -0
- package/dist/client/assets/buildkite-BrDKWLhW.svg +1 -0
- package/dist/client/assets/bun-CZtgPBjt.svg +1 -0
- package/dist/client/assets/c-CCkhSkL9.svg +1 -0
- package/dist/client/assets/c3-J0cVtsWq.svg +1 -0
- package/dist/client/assets/cabal-CQb4_DnV.svg +1 -0
- package/dist/client/assets/caddy-ywaArsUF.svg +1 -0
- package/dist/client/assets/cadence-BRBsaulT.svg +1 -0
- package/dist/client/assets/cairo-Cls19dwE.svg +1 -0
- package/dist/client/assets/cake-DpuWz3gE.svg +1 -0
- package/dist/client/assets/capacitor-CugB3p3d.svg +1 -0
- package/dist/client/assets/capnp-DtxOZ2_z.svg +1 -0
- package/dist/client/assets/cbx-QvSmyWq4.svg +1 -0
- package/dist/client/assets/cds-Bi3ghsEA.svg +1 -0
- package/dist/client/assets/certificate-B5QPOK_C.svg +1 -0
- package/dist/client/assets/changelog-mhp3hE32.svg +1 -0
- package/dist/client/assets/chess-4hVz24Rg.svg +1 -0
- package/dist/client/assets/chromatic-DRZoj4Hg.svg +1 -0
- package/dist/client/assets/chrome-ox3b9yI4.svg +1 -0
- package/dist/client/assets/circleci-DubwoSEv.svg +1 -0
- package/dist/client/assets/citation-ldCt-JF8.svg +1 -0
- package/dist/client/assets/clangd-bL8W2_13.svg +1 -0
- package/dist/client/assets/claude-DypBvzkn.svg +1 -0
- package/dist/client/assets/cline-Dd7x4bMT.svg +1 -0
- package/dist/client/assets/clojure-wfCfR06G.svg +1 -0
- package/dist/client/assets/cloudfoundry-BS-9yLUv.svg +1 -0
- package/dist/client/assets/cmake-B7q-R28A.svg +1 -0
- package/dist/client/assets/coala-D4YHPVOS.svg +1 -0
- package/dist/client/assets/cobol-wDz3o6g-.svg +1 -0
- package/dist/client/assets/coconut-C7cPswso.svg +1 -0
- package/dist/client/assets/code-climate-BJrwzyOv.svg +1 -0
- package/dist/client/assets/codecov-CXg1oY95.svg +1 -0
- package/dist/client/assets/codeowners-D_rztV49.svg +1 -0
- package/dist/client/assets/coderabbit-ai-DGoTDlyw.svg +1 -0
- package/dist/client/assets/coffee-D5JGmA63.svg +1 -0
- package/dist/client/assets/coldfusion-DhOnvVS_.svg +1 -0
- package/dist/client/assets/coloredpetrinets-DY894G_S.svg +1 -0
- package/dist/client/assets/command-Df3AkI2A.svg +1 -0
- package/dist/client/assets/commitizen-9SU1u7to.svg +1 -0
- package/dist/client/assets/commitlint-3vvjpxJt.svg +1 -0
- package/dist/client/assets/composerShortcuts-BggqvE9J.js +31 -0
- package/dist/client/assets/concourse-DAGkX2vY.svg +1 -0
- package/dist/client/assets/conduct-2Bm8RK0N.svg +1 -0
- package/dist/client/assets/console-pcgGAn8Z.svg +1 -0
- package/dist/client/assets/contentlayer-vXTwXOHk.svg +1 -0
- package/dist/client/assets/context-CebLrksE.svg +1 -0
- package/dist/client/assets/contributing-DLcmDS34.svg +1 -0
- package/dist/client/assets/controller-Doc75EnV.svg +1 -0
- package/dist/client/assets/copilot-DBlNrZ6L.svg +1 -0
- package/dist/client/assets/cpp-DT2939hp.svg +1 -0
- package/dist/client/assets/craco-BySmcQ23.svg +1 -0
- package/dist/client/assets/credits-GALyqcNu.svg +1 -0
- package/dist/client/assets/crystal-BbNQlJLs.svg +1 -0
- package/dist/client/assets/csharp-D5ZKsaqY.svg +1 -0
- package/dist/client/assets/css-JKwEyWYb.svg +1 -0
- package/dist/client/assets/css-map-Ctu4D9Ve.svg +1 -0
- package/dist/client/assets/cucumber-B3ZYwjRe.svg +1 -0
- package/dist/client/assets/cuda-CRW2z42A.svg +1 -0
- package/dist/client/assets/cue-ni2TTLiZ.svg +1 -0
- package/dist/client/assets/cursor-CJahHGg2.svg +1 -0
- package/dist/client/assets/cypress-DR0JRbfI.svg +1 -0
- package/dist/client/assets/d-B87zyVMx.svg +1 -0
- package/dist/client/assets/dart-Dx2oVcaR.svg +1 -0
- package/dist/client/assets/dart_generated-Wk58pte9.svg +1 -0
- package/dist/client/assets/database-B_oKaDcf.svg +1 -0
- package/dist/client/assets/deepsource-DUTIJ9mv.svg +1 -0
- package/dist/client/assets/denizenscript-BJc2vgOS.svg +1 -0
- package/dist/client/assets/deno-CyFvrzCm.svg +1 -0
- package/dist/client/assets/dependabot-BgJkJLU3.svg +1 -0
- package/dist/client/assets/dependencies-update-CdGy9ujO.svg +1 -0
- package/dist/client/assets/dhall-Dmhh82EO.svg +1 -0
- package/dist/client/assets/diff-6SXDCokN.svg +1 -0
- package/dist/client/assets/dinophp-D9hQnqAR.svg +1 -0
- package/dist/client/assets/disc-h_dLNGEL.svg +1 -0
- package/dist/client/assets/django-N1UNAXk1.svg +1 -0
- package/dist/client/assets/dll-1DkaBp0q.svg +1 -0
- package/dist/client/assets/docker-CfHcr61D.svg +1 -0
- package/dist/client/assets/doctex-installer-Cs7SA-ct.svg +1 -0
- package/dist/client/assets/document-o-3iA9GQ.svg +1 -0
- package/dist/client/assets/dotjs-DIyH7Gzv.svg +1 -0
- package/dist/client/assets/drawio-2RVDLi9g.svg +1 -0
- package/dist/client/assets/drizzle-hhBCZx1t.svg +1 -0
- package/dist/client/assets/drone-KvQ2n-xY.svg +1 -0
- package/dist/client/assets/dtx-DdGk8fFj.svg +1 -0
- package/dist/client/assets/duc-CHcAZQos.svg +1 -0
- package/dist/client/assets/dune-DuGO6qDA.svg +1 -0
- package/dist/client/assets/edge-ChHKXrYp.svg +1 -0
- package/dist/client/assets/editorconfig-BUzUAwRX.svg +1 -0
- package/dist/client/assets/ejs-D_Li05n3.svg +1 -0
- package/dist/client/assets/elixir-75mYTx2s.svg +1 -0
- package/dist/client/assets/elm-DE_LIp02.svg +1 -0
- package/dist/client/assets/email-G8mUttGa.svg +1 -0
- package/dist/client/assets/ember-B1y9-Oks.svg +1 -0
- package/dist/client/assets/epub-DPvrBCNf.svg +1 -0
- package/dist/client/assets/erlang-DosS6spf.svg +1 -0
- package/dist/client/assets/esbuild-DV6xNZ-T.svg +1 -0
- package/dist/client/assets/eslint-IU_g232-.svg +1 -0
- package/dist/client/assets/excalidraw-BllKd-7L.svg +1 -0
- package/dist/client/assets/exe-SfcXmkQy.svg +1 -0
- package/dist/client/assets/expo-B4PonO4I.svg +1 -0
- package/dist/client/assets/external-DjGXa4ZP.js +1 -0
- package/dist/client/assets/fastlane-C4SZDg50.svg +1 -0
- package/dist/client/assets/favicon-VsCcG-A-.svg +1 -0
- package/dist/client/assets/figma-C8Gjq2Xj.svg +1 -0
- package/dist/client/assets/file-BEIHQH8Q.svg +256 -0
- package/dist/client/assets/firebase-DHIO0glR.svg +1 -0
- package/dist/client/assets/flash-Dck7x_rj.svg +1 -0
- package/dist/client/assets/flow-DD4KQiTg.svg +1 -0
- package/dist/client/assets/font-ChbWr8nk.svg +1 -0
- package/dist/client/assets/forth-C3qwGqMh.svg +1 -0
- package/dist/client/assets/fortran-B0jORJ3v.svg +1 -0
- package/dist/client/assets/foxpro-D3Wp1B1h.svg +1 -0
- package/dist/client/assets/freemarker-BLonnh3h.svg +1 -0
- package/dist/client/assets/fsharp-QwwPC8x_.svg +1 -0
- package/dist/client/assets/fusebox-DqjzyXyI.svg +1 -0
- package/dist/client/assets/gamemaker-C82Pt646.svg +1 -0
- package/dist/client/assets/garden-BUsWpFKW.svg +1 -0
- package/dist/client/assets/gatsby-OA1TADMJ.svg +1 -0
- package/dist/client/assets/gcp-CW2RG_Wp.svg +1 -0
- package/dist/client/assets/gemfile-1RY6BqSx.svg +1 -0
- package/dist/client/assets/gemini-CIgUY8Tg.svg +1 -0
- package/dist/client/assets/gemini-ai-Bwe7HeFb.svg +1 -0
- package/dist/client/assets/git-BEMs8TOZ.svg +1 -0
- package/dist/client/assets/gitlab-zt07_Oa4.svg +1 -0
- package/dist/client/assets/gitpod-BtZJQuF0.svg +1 -0
- package/dist/client/assets/gleam-CKPcrRAD.svg +1 -0
- package/dist/client/assets/gnuplot-BvFqM0ms.svg +1 -0
- package/dist/client/assets/go-ByY4sxRu.svg +1 -0
- package/dist/client/assets/go-mod-CB6BWQDr.svg +1 -0
- package/dist/client/assets/godot-C1EmL4jR.svg +1 -0
- package/dist/client/assets/godot-assets-D-FMsuJX.svg +1 -0
- package/dist/client/assets/google-BnrMOJ4V.svg +1 -0
- package/dist/client/assets/gradle-zsQ12U1q.svg +1 -0
- package/dist/client/assets/grafana-alloy-D2DQ33BM.svg +1 -0
- package/dist/client/assets/grain-5NkvKROL.svg +1 -0
- package/dist/client/assets/graphcool-CInCTIdE.svg +1 -0
- package/dist/client/assets/graphql-DnNt2maR.svg +1 -0
- package/dist/client/assets/gridsome-C2H5SpaD.svg +1 -0
- package/dist/client/assets/groovy-B93RxI7a.svg +1 -0
- package/dist/client/assets/grunt-cwitasVS.svg +1 -0
- package/dist/client/assets/gulp-BIZ8EAl0.svg +1 -0
- package/dist/client/assets/h-1bd73y8t.svg +1 -0
- package/dist/client/assets/hack-Bsd1y9bu.svg +1 -0
- package/dist/client/assets/hadolint-D1aEtESc.svg +1 -0
- package/dist/client/assets/haml-BKq8hU-U.svg +1 -0
- package/dist/client/assets/handlebars-Dem98Ago.svg +1 -0
- package/dist/client/assets/happo-B64XokX0.svg +1 -0
- package/dist/client/assets/hardhat-ByFzkuf4.svg +1 -0
- package/dist/client/assets/harmonix-CUh3S11M.svg +1 -0
- package/dist/client/assets/haskell-C6GxEwdX.svg +1 -0
- package/dist/client/assets/haxe-DdxZWPQy.svg +1 -0
- package/dist/client/assets/hcl-BJiZ3gWE.svg +1 -0
- package/dist/client/assets/helm-CF4Mi35z.svg +1 -0
- package/dist/client/assets/heroku-B6vPz_TJ.svg +1 -0
- package/dist/client/assets/hex-BuGJuqn1.svg +1 -0
- package/dist/client/assets/hip-DB4xe1Ab.svg +1 -0
- package/dist/client/assets/histoire-BMTufysg.svg +1 -0
- package/dist/client/assets/hjson-Dl4ZTgK4.svg +1 -0
- package/dist/client/assets/horusec-z6vyrVAy.svg +1 -0
- package/dist/client/assets/hosts-BydfWJ9z.svg +1 -0
- package/dist/client/assets/hpp-HerxyIaC.svg +1 -0
- package/dist/client/assets/html-BNRzQ3jk.svg +1 -0
- package/dist/client/assets/http-Cp7RCu8F.svg +1 -0
- package/dist/client/assets/huff-t3uGT10D.svg +1 -0
- package/dist/client/assets/hurl-S3Fvmz3R.svg +1 -0
- package/dist/client/assets/husky-A0ALYNcp.svg +1 -0
- package/dist/client/assets/i18n-BezCQ09L.svg +1 -0
- package/dist/client/assets/idris-CfHPjxcM.svg +1 -0
- package/dist/client/assets/ifanr-cloud-DnqgZYHA.svg +1 -0
- package/dist/client/assets/image-DYZiZ4CP.svg +1 -0
- package/dist/client/assets/imba-C1Q6aK1I.svg +1 -0
- package/dist/client/assets/index-CInvlJKI.js +2 -0
- package/dist/client/assets/installation-p19cVXO7.svg +1 -0
- package/dist/client/assets/instructions-CaWEzdge.svg +1 -0
- package/dist/client/assets/ionic-Xp-47Icg.svg +1 -0
- package/dist/client/assets/istanbul-DJKvMwnq.svg +1 -0
- package/dist/client/assets/jar-BaN44U3v.svg +1 -0
- package/dist/client/assets/java-QyMrrPma.svg +1 -0
- package/dist/client/assets/javaclass-BU8_3KBR.svg +1 -0
- package/dist/client/assets/javascript-CQjpTQab.svg +1 -0
- package/dist/client/assets/javascript-map-BQGiWnDM.svg +1 -0
- package/dist/client/assets/jenkins-Bf7aNz-w.svg +1 -0
- package/dist/client/assets/jest-BgbiFFEd.svg +1 -0
- package/dist/client/assets/jinja-4WR9tA6i.svg +1 -0
- package/dist/client/assets/jsconfig-ZAi6fTF1.svg +1 -0
- package/dist/client/assets/json-NsberLUP.svg +1 -0
- package/dist/client/assets/json_schema-sOuobP_H.svg +1 -0
- package/dist/client/assets/jsr-CWVSPSyV.svg +1 -0
- package/dist/client/assets/julia-DCKDSo9T.svg +1 -0
- package/dist/client/assets/jupyter-BKV2q0IB.svg +1 -0
- package/dist/client/assets/just-WQgcj-TR.svg +1 -0
- package/dist/client/assets/karma-Dm3AtiMd.svg +1 -0
- package/dist/client/assets/kcl-CyzArNE1.svg +1 -0
- package/dist/client/assets/key-CrFjkQiv.svg +1 -0
- package/dist/client/assets/keystatic-BECeLiHJ.svg +1 -0
- package/dist/client/assets/kivy-baDYR7ar.svg +1 -0
- package/dist/client/assets/kl-Dy3qeUbd.svg +1 -0
- package/dist/client/assets/knip-BWpBMXqu.svg +1 -0
- package/dist/client/assets/kotlin-DcjME28v.svg +1 -0
- package/dist/client/assets/kubernetes-B5EEXb3e.svg +1 -0
- package/dist/client/assets/kusto-CIjvTfRW.svg +1 -0
- package/dist/client/assets/label-AKZOJqFh.svg +1 -0
- package/dist/client/assets/laravel-DWauj5w4.svg +1 -0
- package/dist/client/assets/latexmk-DQ0u8QMa.svg +1 -0
- package/dist/client/assets/lbx-BMCQe48q.svg +1 -0
- package/dist/client/assets/lean-COOrALn9.svg +1 -0
- package/dist/client/assets/lefthook-DClcp3br.svg +1 -0
- package/dist/client/assets/lerna-BsWY3uYS.svg +1 -0
- package/dist/client/assets/less-0c0PeB1Z.svg +1 -0
- package/dist/client/assets/liara-CSN9sJzE.svg +1 -0
- package/dist/client/assets/lib-B-NXM8aC.svg +1 -0
- package/dist/client/assets/license-DmydDYqK.svg +1 -0
- package/dist/client/assets/lighthouse-CtbIoCdK.svg +1 -0
- package/dist/client/assets/lilypond-CBSm3LFL.svg +1 -0
- package/dist/client/assets/lintstaged-Bj1Eddi5.svg +1 -0
- package/dist/client/assets/liquid-ClnkrScY.svg +1 -0
- package/dist/client/assets/lisp-CMn3epg5.svg +1 -0
- package/dist/client/assets/lit-CJ6w1GHF.js +2 -0
- package/dist/client/assets/livescript-B5PkWD8e.svg +1 -0
- package/dist/client/assets/lock-DRloBj1S.svg +1 -0
- package/dist/client/assets/log-Db6NwxHZ.svg +1 -0
- package/dist/client/assets/lolcode-C6q6fY1O.svg +1 -0
- package/dist/client/assets/lottie-ExyLYhtq.svg +1 -0
- package/dist/client/assets/lua-CUh_Iwk8.svg +1 -0
- package/dist/client/assets/luau-De_4eP_9.svg +1 -0
- package/dist/client/assets/lynx-B49IBNBN.svg +1 -0
- package/dist/client/assets/lyric-Bm3UlVp3.svg +1 -0
- package/dist/client/assets/macaulay2-0YotwNnE.svg +1 -0
- package/dist/client/assets/main-CWcn0Deu.js +2 -0
- package/dist/client/assets/makefile-B2WlY55Y.svg +1 -0
- package/dist/client/assets/markdoc-DjROVW5I.svg +1 -0
- package/dist/client/assets/markdoc-config-BpVRhg1B.svg +1 -0
- package/dist/client/assets/markdown-Bm_LLmmi.svg +1 -0
- package/dist/client/assets/markdownlint-D4M2LXbH.svg +1 -0
- package/dist/client/assets/markojs-BohUrSLp.svg +1 -0
- package/dist/client/assets/mathematica-BGWNQXSR.svg +1 -0
- package/dist/client/assets/maven-BffVB5hm.svg +1 -0
- package/dist/client/assets/mdsvex-Dc9CFJJa.svg +1 -0
- package/dist/client/assets/mdx-D6qa5U8C.svg +1 -0
- package/dist/client/assets/mercurial-BDoD6ubd.svg +1 -0
- package/dist/client/assets/merlin-D5wTXfO4.svg +1 -0
- package/dist/client/assets/mermaid-BTscZDRS.svg +1 -0
- package/dist/client/assets/meson-dcvm8lmo.svg +1 -0
- package/dist/client/assets/metro-XIyWX0Go.svg +1 -0
- package/dist/client/assets/minecraft-CE8xXE3-.svg +1 -0
- package/dist/client/assets/minecraft-fabric-wG6LwgIf.svg +1 -0
- package/dist/client/assets/mint-Cb-YXACo.svg +1 -0
- package/dist/client/assets/mist-DAm4UkTw.svg +1 -0
- package/dist/client/assets/mjml-C_r30C5E.svg +1 -0
- package/dist/client/assets/mocha-BF5_j65C.svg +1 -0
- package/dist/client/assets/modernizr-89IMS8eL.svg +1 -0
- package/dist/client/assets/mojo-CscjT2Jm.svg +1 -0
- package/dist/client/assets/moon-_L_nTq1_.svg +1 -0
- package/dist/client/assets/moonscript-Ayut2PrD.svg +1 -0
- package/dist/client/assets/mrpack-BVpGpKVf.svg +1 -0
- package/dist/client/assets/mxml-B21Nbdgw.svg +1 -0
- package/dist/client/assets/nano-staged-CAVSFkY8.svg +1 -0
- package/dist/client/assets/ndst-DpYLiHkx.svg +1 -0
- package/dist/client/assets/nest-CUu_iPqI.svg +1 -0
- package/dist/client/assets/netlify-Bb7vRMfV.svg +1 -0
- package/dist/client/assets/next-2gAImGWJ.svg +1 -0
- package/dist/client/assets/nextflow-dPJG5e3G.svg +1 -0
- package/dist/client/assets/nginx-Ss9U_SJ3.svg +1 -0
- package/dist/client/assets/nim-CXHB5kuH.svg +1 -0
- package/dist/client/assets/nix-DoxxkZ2k.svg +1 -0
- package/dist/client/assets/nodejs-Czg5JT6z.svg +1 -0
- package/dist/client/assets/nodemon-CprsexAJ.svg +1 -0
- package/dist/client/assets/npm-BSKPS9CC.svg +1 -0
- package/dist/client/assets/nuget-D_mqKH22.svg +1 -0
- package/dist/client/assets/nunjucks-CSL1En7R.svg +1 -0
- package/dist/client/assets/nuxt-BszScKzK.svg +1 -0
- package/dist/client/assets/nx-CTIqtdbG.svg +1 -0
- package/dist/client/assets/objective-c-3E5wWl6u.svg +1 -0
- package/dist/client/assets/objective-cpp-DjpoLOMo.svg +1 -0
- package/dist/client/assets/ocaml-T4fLeZFT.svg +1 -0
- package/dist/client/assets/odin-DlWnbZWN.svg +1 -0
- package/dist/client/assets/onnx-C6WInyrb.svg +1 -0
- package/dist/client/assets/opa-D5GoZW5M.svg +1 -0
- package/dist/client/assets/opam-3IZadro4.svg +1 -0
- package/dist/client/assets/openapi-DjlVyoOp.svg +1 -0
- package/dist/client/assets/opencode-BaYncWio.svg +1 -0
- package/dist/client/assets/opentofu-jFw9lQBP.svg +1 -0
- package/dist/client/assets/otne-SLiO8whA.svg +1 -0
- package/dist/client/assets/oxc-DN6_023j.svg +1 -0
- package/dist/client/assets/packship-UyLXQ_8n.svg +1 -0
- package/dist/client/assets/palette-C0GOsJgu.svg +1 -0
- package/dist/client/assets/panda-D469wGns.svg +1 -0
- package/dist/client/assets/parcel-BrXQSBYb.svg +1 -0
- package/dist/client/assets/pascal-oxGvvJ_x.svg +1 -0
- package/dist/client/assets/pawn-BvapPd-t.svg +1 -0
- package/dist/client/assets/payload-Cks6N40-.svg +1 -0
- package/dist/client/assets/pdf-DtjgBDdX.svg +1 -0
- package/dist/client/assets/pdm-CbwhGqOl.svg +1 -0
- package/dist/client/assets/peg-BJdFn78b.svg +1 -0
- package/dist/client/assets/percy-CWbuYL05.svg +1 -0
- package/dist/client/assets/perl-DUX0zwsQ.svg +1 -0
- package/dist/client/assets/php-5lebFt-d.svg +1 -0
- package/dist/client/assets/php-cs-fixer-D3Vv91zO.svg +1 -0
- package/dist/client/assets/phpstan-D9FJYotS.svg +1 -0
- package/dist/client/assets/phpunit-BlNyjrEw.svg +1 -0
- package/dist/client/assets/pinejs-CDuWmsOY.svg +1 -0
- package/dist/client/assets/pipeline-CCHJ-CIC.svg +1 -0
- package/dist/client/assets/pkl-CzHZDqdt.svg +1 -0
- package/dist/client/assets/plastic-CvMMB3c5.svg +1 -0
- package/dist/client/assets/playwright-C8c_RKic.svg +1 -0
- package/dist/client/assets/plop-D4uymN-_.svg +1 -0
- package/dist/client/assets/pm2-ecosystem-Cv28zGx9.svg +1 -0
- package/dist/client/assets/pnpm-ndvMXYUu.svg +1 -0
- package/dist/client/assets/poetry-ClZfXo_0.svg +1 -0
- package/dist/client/assets/postcss-g3C3DDoi.svg +1 -0
- package/dist/client/assets/posthtml-BkDCsIkz.svg +1 -0
- package/dist/client/assets/powerpoint-CCXYfzLu.svg +1 -0
- package/dist/client/assets/powershell-DnXi9Rjx.svg +1 -0
- package/dist/client/assets/pre-commit-DXbl2unR.svg +1 -0
- package/dist/client/assets/preload-helper-CRzLMJPS.js +1 -0
- package/dist/client/assets/prettier-DFxlFAp4.svg +1 -0
- package/dist/client/assets/prisma-BgG1MIwh.svg +1 -0
- package/dist/client/assets/processing-B1bs0VmW.svg +1 -0
- package/dist/client/assets/prolog-CxwCfnlm.svg +1 -0
- package/dist/client/assets/prompt-7jgVTNou.svg +1 -0
- package/dist/client/assets/proto-Bv4-L0XU.svg +1 -0
- package/dist/client/assets/protractor-CJWv1lK-.svg +1 -0
- package/dist/client/assets/pug-BXlORXuH.svg +1 -0
- package/dist/client/assets/puppet-CKCVJvZX.svg +1 -0
- package/dist/client/assets/puppeteer-DDZkfQNZ.svg +1 -0
- package/dist/client/assets/purescript-CUdIfJrp.svg +1 -0
- package/dist/client/assets/python-misc-BZ5TXfdG.svg +1 -0
- package/dist/client/assets/python-oHA753pt.svg +1 -0
- package/dist/client/assets/pytorch-f0udCMaw.svg +1 -0
- package/dist/client/assets/qsharp-BaFNvoXS.svg +1 -0
- package/dist/client/assets/quarto-zhC7oGOB.svg +1 -0
- package/dist/client/assets/quasar-BXE2pW5w.svg +1 -0
- package/dist/client/assets/quokka-DrMOw93T.svg +1 -0
- package/dist/client/assets/r-AQewf3lz.svg +1 -0
- package/dist/client/assets/racket-BCyLzvrP.svg +1 -0
- package/dist/client/assets/raml-WDbT4cRb.svg +1 -0
- package/dist/client/assets/razor-BAUCpTxC.svg +1 -0
- package/dist/client/assets/rbxmk-CZ9pB7X6.svg +1 -0
- package/dist/client/assets/rc-BDgxm_A8.svg +1 -0
- package/dist/client/assets/react-CdMrIyLK.svg +1 -0
- package/dist/client/assets/react_ts-9WeLJBIj.svg +1 -0
- package/dist/client/assets/readme-BSIQKZwq.svg +1 -0
- package/dist/client/assets/reason-m9vOqeqw.svg +1 -0
- package/dist/client/assets/red-Dzf3O8j4.svg +1 -0
- package/dist/client/assets/regedit-DJzxfiQN.svg +1 -0
- package/dist/client/assets/remark-C55cxr93.svg +1 -0
- package/dist/client/assets/remix-Bk2h4zH7.svg +1 -0
- package/dist/client/assets/renovate-zzi8oRFv.svg +1 -0
- package/dist/client/assets/replit-BpeMxcBh.svg +1 -0
- package/dist/client/assets/requiredTerminalPlugin-B-0wkiKe.js +3 -0
- package/dist/client/assets/rescript-interface-a87dYX5u.svg +1 -0
- package/dist/client/assets/rescript-qPAwtDLa.svg +1 -0
- package/dist/client/assets/restql-CnZcZpny.svg +1 -0
- package/dist/client/assets/riot-DjRzaRVp.svg +1 -0
- package/dist/client/assets/roadmap-DWpVc5P5.svg +1 -0
- package/dist/client/assets/roblox-Bv5zbklC.svg +1 -0
- package/dist/client/assets/robot-Cto_i8jo.svg +1 -0
- package/dist/client/assets/robots-COnOCAqh.svg +1 -0
- package/dist/client/assets/rocket-CAmUpMm6.svg +1 -0
- package/dist/client/assets/rolldown-Cy_4AzVW.svg +1 -0
- package/dist/client/assets/rollup-2ZkmBeWV.svg +1 -0
- package/dist/client/assets/rome-Cq3lb2xY.svg +1 -0
- package/dist/client/assets/routing-BNxHhbXZ.svg +1 -0
- package/dist/client/assets/rspec-CoEmfx5H.svg +1 -0
- package/dist/client/assets/rstack-DzJ3cPXM.svg +1 -0
- package/dist/client/assets/rubocop-CokGq15J.svg +1 -0
- package/dist/client/assets/ruby-DTGQ4xCM.svg +1 -0
- package/dist/client/assets/ruff-BN0KpNzC.svg +1 -0
- package/dist/client/assets/rust-B122pUHY.svg +1 -0
- package/dist/client/assets/salt-B8j0OVNV.svg +1 -0
- package/dist/client/assets/san-C0UnyaU4.svg +1 -0
- package/dist/client/assets/sas-RNoBA0-Y.svg +1 -0
- package/dist/client/assets/sass-B7y5mYt_.svg +1 -0
- package/dist/client/assets/sbt-DosCci-d.svg +1 -0
- package/dist/client/assets/scala-CsGkKwl5.svg +1 -0
- package/dist/client/assets/scheme-CS2UbTis.svg +1 -0
- package/dist/client/assets/scons-CyqfFgvx.svg +1 -0
- package/dist/client/assets/screwdriver-DjTKuDz7.svg +1 -0
- package/dist/client/assets/search-fq7VxV09.svg +1 -0
- package/dist/client/assets/semantic-release-BbLzZX96.svg +1 -0
- package/dist/client/assets/semgrep-Cl6VUQtd.svg +1 -0
- package/dist/client/assets/sentry-MrouyD-P.svg +1 -0
- package/dist/client/assets/sequelize-BQWikTCs.svg +1 -0
- package/dist/client/assets/serverless-C7Jdn6_T.svg +1 -0
- package/dist/client/assets/settings-CtzL1evz.svg +1 -0
- package/dist/client/assets/shader-BZXKDeiD.svg +1 -0
- package/dist/client/assets/shellcheck-BgWOclub.svg +1 -0
- package/dist/client/assets/simulink-yQnKyx__.svg +1 -0
- package/dist/client/assets/siyuan-CPWD86-6.svg +1 -0
- package/dist/client/assets/sketch-NbltjaPf.svg +1 -0
- package/dist/client/assets/skill-BThvgH87.svg +1 -0
- package/dist/client/assets/slim-CTjdZAfz.svg +1 -0
- package/dist/client/assets/slint-B0xbkqgr.svg +1 -0
- package/dist/client/assets/slug-CWkQgR9s.svg +1 -0
- package/dist/client/assets/smarty-BXDiLQNt.svg +1 -0
- package/dist/client/assets/sml-DMkoWEN5.svg +1 -0
- package/dist/client/assets/snakemake-xG7xUrdI.svg +1 -0
- package/dist/client/assets/snapcraft-zvgAcZ4p.svg +1 -0
- package/dist/client/assets/snowpack-l0uHt304.svg +1 -0
- package/dist/client/assets/snyk-DCW3rtvv.svg +1 -0
- package/dist/client/assets/solidity-C4TQWJKU.svg +1 -0
- package/dist/client/assets/sonarcloud-ClLIXGyx.svg +1 -0
- package/dist/client/assets/spwn-31WG9ftR.svg +1 -0
- package/dist/client/assets/stackblitz-ZX6aBRKb.svg +1 -0
- package/dist/client/assets/stan-CPcUXbxB.svg +1 -0
- package/dist/client/assets/steadybit-BZtlLY-3.svg +1 -0
- package/dist/client/assets/stencil-D0FNO32O.svg +1 -0
- package/dist/client/assets/stitches-BYlEJvuz.svg +1 -0
- package/dist/client/assets/storybook-KxGhpZYa.svg +1 -0
- package/dist/client/assets/stryker-CYflxT_R.svg +1 -0
- package/dist/client/assets/sty-C4HqHV4z.svg +1 -0
- package/dist/client/assets/stylable-Bi9Gr97T.svg +1 -0
- package/dist/client/assets/styleSources-CdF2T_pj.js +1 -0
- package/dist/client/assets/stylelint-JSbd-yhE.svg +1 -0
- package/dist/client/assets/styles-BwN5rgmt.js +10 -0
- package/dist/client/assets/styles-DK4aKhCE.js +1 -0
- package/dist/client/assets/stylus-ZoqbP9jE.svg +1 -0
- package/dist/client/assets/sublime-DFvp_Ess.svg +1 -0
- package/dist/client/assets/subtitles-BNOc1mEf.svg +1 -0
- package/dist/client/assets/supabase-CX7cap86.svg +1 -0
- package/dist/client/assets/svelte-B8HKO6BX.svg +1 -0
- package/dist/client/assets/svelte_js-C_RKcwSP.svg +1 -0
- package/dist/client/assets/svelte_ts-APH7lcVp.svg +1 -0
- package/dist/client/assets/svg-DVy7iktw.svg +1 -0
- package/dist/client/assets/svgo-CJXaeDEN.svg +1 -0
- package/dist/client/assets/svgr-Dn8OFGar.svg +1 -0
- package/dist/client/assets/swagger-Dqyrwr4g.svg +1 -0
- package/dist/client/assets/sway-C1Kkif7r.svg +1 -0
- package/dist/client/assets/swc-BUhoW8cb.svg +1 -0
- package/dist/client/assets/swift-D4_pkWil.svg +1 -0
- package/dist/client/assets/syncpack-DtZ994Gf.svg +1 -0
- package/dist/client/assets/table-YhsaNNk_.svg +1 -0
- package/dist/client/assets/tailwindcss-DODJSdj1.svg +1 -0
- package/dist/client/assets/tape-DGYhnMht.svg +1 -0
- package/dist/client/assets/taskfile-f5DM79_-.svg +1 -0
- package/dist/client/assets/tauri-DBBtDoCo.svg +1 -0
- package/dist/client/assets/taze-BPR9LgXp.svg +1 -0
- package/dist/client/assets/tcl-CiAJKGaA.svg +1 -0
- package/dist/client/assets/teal-WyfAQok0.svg +1 -0
- package/dist/client/assets/templ-BHla0pe-.svg +1 -0
- package/dist/client/assets/template-qJWiB5gQ.svg +1 -0
- package/dist/client/assets/terraform-R86_iPhv.svg +1 -0
- package/dist/client/assets/test-js-A34KrdbK.svg +1 -0
- package/dist/client/assets/test-jsx-C2PQBkQP.svg +1 -0
- package/dist/client/assets/test-ts-fdt299ek.svg +1 -0
- package/dist/client/assets/tex-DpewR4UN.svg +1 -0
- package/dist/client/assets/textlint-pjwsbDhs.svg +1 -0
- package/dist/client/assets/themeCatalog-B3yda95n.js +1 -0
- package/dist/client/assets/themePreference-BBiJxLjs.js +1 -0
- package/dist/client/assets/themeStartup-0b02tNrh.js +2 -0
- package/dist/client/assets/tilt-Dwon5dv-.svg +1 -0
- package/dist/client/assets/tldraw-BnDJmluq.svg +1 -0
- package/dist/client/assets/tobi-CQ-666uh.svg +1 -0
- package/dist/client/assets/tobimake-DzDbTYW1.svg +1 -0
- package/dist/client/assets/toc-nUTycYjl.svg +1 -0
- package/dist/client/assets/todo-CpcorlsE.svg +1 -0
- package/dist/client/assets/toml-DvUt-GOd.svg +1 -0
- package/dist/client/assets/toon-CGe9RDKY.svg +1 -0
- package/dist/client/assets/travis-CH6zNy43.svg +1 -0
- package/dist/client/assets/tree-epW9JaxP.svg +1 -0
- package/dist/client/assets/trigger-CqdxCyG0.svg +1 -0
- package/dist/client/assets/tsconfig-ROp_YdWL.svg +1 -0
- package/dist/client/assets/tsdoc-BEXcYgLD.svg +1 -0
- package/dist/client/assets/tsdown-B96z16my.svg +1 -0
- package/dist/client/assets/tsil-D-U9yWS8.svg +1 -0
- package/dist/client/assets/tune-DISlqKNZ.svg +1 -0
- package/dist/client/assets/turborepo-CWNwoZtI.svg +1 -0
- package/dist/client/assets/twig-CA70AYNK.svg +1 -0
- package/dist/client/assets/twine-BPJsGZd2.svg +1 -0
- package/dist/client/assets/typedoc-FY7jFoGW.svg +1 -0
- package/dist/client/assets/typescript-DjjXqw-n.svg +1 -0
- package/dist/client/assets/typescript-def-CTN5WM5i.svg +1 -0
- package/dist/client/assets/typst-CnDSkp_i.svg +1 -0
- package/dist/client/assets/uiua-BOsurlxn.svg +1 -0
- package/dist/client/assets/umi-DYOjFi8w.svg +1 -0
- package/dist/client/assets/uml-CYijxuna.svg +1 -0
- package/dist/client/assets/unity-CRNCEoK6.svg +1 -0
- package/dist/client/assets/unlicense-DG_b3BEE.svg +1 -0
- package/dist/client/assets/unocss-MqLuLfeL.svg +1 -0
- package/dist/client/assets/url-hE4h5p6b.svg +1 -0
- package/dist/client/assets/uv-DRTOVSi_.svg +1 -0
- package/dist/client/assets/vagrant-YnxMTuKe.svg +1 -0
- package/dist/client/assets/vala-m_i2ZWns.svg +1 -0
- package/dist/client/assets/vanilla-extract-76H6-A4R.svg +1 -0
- package/dist/client/assets/varnish-CX3oiNcp.svg +1 -0
- package/dist/client/assets/vedic-D6-oQUka.svg +1 -0
- package/dist/client/assets/velite-nLLNxKBA.svg +1 -0
- package/dist/client/assets/velocity-CSvfE9yM.svg +1 -0
- package/dist/client/assets/vercel-CgKLo9IO.svg +1 -0
- package/dist/client/assets/verdaccio-gsdiCbvv.svg +1 -0
- package/dist/client/assets/verified-BFLtqroG.svg +1 -0
- package/dist/client/assets/verilog-CbZvRaae.svg +1 -0
- package/dist/client/assets/verse-D_RZ0Bz0.svg +1 -0
- package/dist/client/assets/vfl-8CAM-hjs.svg +1 -0
- package/dist/client/assets/video-qxpJXkH6.svg +1 -0
- package/dist/client/assets/vim-CB8qTVuS.svg +1 -0
- package/dist/client/assets/virtual-Hoc2XbZN.svg +1 -0
- package/dist/client/assets/visualstudio-BHj2x5q7.svg +1 -0
- package/dist/client/assets/vite-JKzchVew.svg +1 -0
- package/dist/client/assets/vitest-Cl4_wKFu.svg +1 -0
- package/dist/client/assets/vlang-C3-DMUIm.svg +1 -0
- package/dist/client/assets/vscode-BtTXhPua.svg +1 -0
- package/dist/client/assets/vue-BlenztPP.svg +1 -0
- package/dist/client/assets/vue-config-o7yPAADv.svg +1 -0
- package/dist/client/assets/wakatime-DNz7qcxZ.svg +1 -0
- package/dist/client/assets/wallaby-C0UIkEOa.svg +1 -0
- package/dist/client/assets/wally-Ds1quKSG.svg +1 -0
- package/dist/client/assets/warp-B3X5Zoeh.svg +1 -0
- package/dist/client/assets/watchman-7EFq9LSa.svg +1 -0
- package/dist/client/assets/webassembly-Bs4UtU2T.svg +1 -0
- package/dist/client/assets/webhint-B4I6V0Ee.svg +1 -0
- package/dist/client/assets/webpack-zo2uWGOg.svg +1 -0
- package/dist/client/assets/wepy-Cho54Qlr.svg +1 -0
- package/dist/client/assets/werf-BW9FiKe5.svg +1 -0
- package/dist/client/assets/windicss-C_8y516i.svg +1 -0
- package/dist/client/assets/wolframlanguage-D6C1WBYh.svg +1 -0
- package/dist/client/assets/word-BcPLm6YH.svg +1 -0
- package/dist/client/assets/wrangler-CjgAkoTg.svg +1 -0
- package/dist/client/assets/wxt-c6drtC9H.svg +1 -0
- package/dist/client/assets/xaml-DE72OHNQ.svg +1 -0
- package/dist/client/assets/xmake-4WNmmIJj.svg +1 -0
- package/dist/client/assets/xml-S4aCxoUr.svg +1 -0
- package/dist/client/assets/yaml-DPTMsOTP.svg +1 -0
- package/dist/client/assets/yang-N-7dP4WI.svg +1 -0
- package/dist/client/assets/yarn-Cios8OFX.svg +1 -0
- package/dist/client/assets/zeabur-kqbNXTTH.svg +1 -0
- package/dist/client/assets/zig-CdphsgLN.svg +1 -0
- package/dist/client/assets/zip-GDnEynqi.svg +1 -0
- package/dist/client/assets/zizmor-IsFFdy6W.svg +1 -0
- package/dist/client/index.html +12 -6
- package/dist/config.js +233 -87
- package/dist/config.js.map +1 -1
- package/dist/configSessionNamingMigration.js +63 -0
- package/dist/configSessionNamingMigration.js.map +1 -0
- package/dist/nativeServices/serviceDoctor.js +3 -3
- package/dist/nativeServices/serviceDoctor.js.map +1 -1
- package/dist/nativeServices/servicePlan.js +53 -23
- package/dist/nativeServices/servicePlan.js.map +1 -1
- package/dist/nativeServices/serviceProbe.js +27 -7
- package/dist/nativeServices/serviceProbe.js.map +1 -1
- package/dist/pi-packages/relays/markdownDocument.js +8 -9
- package/dist/pi-packages/relays/pi-web-plugin.js +11 -11
- package/dist/pi-packages/relays/relays.messages.js +38 -0
- package/dist/pi-packages/relays/relaysLocalization.js +19 -0
- package/dist/pi-packages/relays/relaysPanelElement.js +151 -96
- package/dist/pi-packages/scheduled-tasks/browser/pi-web-plugin.js +1135 -0
- package/dist/pi-packages/scheduled-tasks/domain.js +63 -0
- package/dist/pi-packages/scheduled-tasks/extensions/index.js +710 -0
- package/dist/pi-packages/scheduled-tasks/package.json +30 -0
- package/dist/pi-packages/scheduled-tasks/scheduler.js +89 -0
- package/dist/pi-packages/scheduled-tasks/server-plugin.js +9872 -0
- package/dist/pi-packages/scheduled-tasks/service.js +178 -0
- package/dist/pi-packages/scheduled-tasks/skills/scheduled-tasks/SKILL.md +30 -0
- package/dist/pi-packages/scheduled-tasks/sqlite.js +18 -0
- package/dist/pi-packages/scheduled-tasks/store.js +230 -0
- package/dist/pi-packages/scheduled-tasks/vite.browser.config.mjs +16 -0
- package/dist/pi-packages/scheduled-tasks/vite.companion.config.mjs +17 -0
- package/dist/pi-packages/scheduled-tasks/vite.config.mjs +17 -0
- package/dist/pi-packages/session-naming/config.js +78 -0
- package/dist/pi-packages/session-naming/extensions/index.js +74 -0
- package/dist/pi-packages/session-naming/generator.js +76 -0
- package/dist/pi-packages/session-naming/package.json +15 -0
- package/dist/pi-packages/workflows/browser/pi-web-plugin.js +10 -7
- package/dist/pi-packages/workflows/browser/workflows.messages.js +32 -0
- package/dist/pi-packages/workflows/browser/worktreeDialog.js +71 -50
- package/dist/pi-packages/workflows/server-plugin.js +137 -23
- package/dist/pi-web-plugins/audio/audioElement.js +61 -0
- package/dist/pi-web-plugins/audio/audioFormats.js +18 -0
- package/dist/pi-web-plugins/audio/byteRange.js +21 -0
- package/dist/pi-web-plugins/audio/package.json +10 -0
- package/dist/pi-web-plugins/audio/pi-web-plugin.js +39 -0
- package/dist/pi-web-plugins/audio/server.js +71 -0
- package/dist/pi-web-plugins/code-highlight/browser/pi-web-plugin.js +4 -4
- package/dist/pi-web-plugins/custom-ui-codex/codex.css +8 -0
- package/dist/pi-web-plugins/custom-ui-codex/fileIcons.js +30 -0
- package/dist/pi-web-plugins/custom-ui-codex/package.json +8 -1
- package/dist/pi-web-plugins/custom-ui-codex/pi-web-plugin.js +8 -8
- package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +236 -259
- package/dist/pi-web-plugins/git/browser/git-panel.js +138 -59
- package/dist/pi-web-plugins/git/browser/git.messages.js +47 -0
- package/dist/pi-web-plugins/git/browser/gitFileIcon.js +71 -0
- package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +21 -4
- package/dist/pi-web-plugins/git/server-plugin.js +5 -3
- package/dist/pi-web-plugins/info/info.messages.js +66 -0
- package/dist/pi-web-plugins/info/infoInternals.js +217 -217
- package/dist/pi-web-plugins/info/pi-web-plugin.js +19 -14
- package/dist/pi-web-plugins/language-spanish/catalogs.js +1896 -0
- package/dist/pi-web-plugins/language-spanish/package.json +14 -0
- package/dist/pi-web-plugins/language-spanish/pi-web-plugin.js +90 -0
- package/dist/pi-web-plugins/language-swedish/catalogs.js +1896 -0
- package/dist/pi-web-plugins/language-swedish/package.json +14 -0
- package/dist/pi-web-plugins/language-swedish/pi-web-plugin.js +89 -0
- package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +4 -4
- package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +71 -66
- package/dist/pi-web-plugins/terminal/bunPtyProvider.js +109 -0
- package/dist/pi-web-plugins/terminal/nodePtyProvider.js +75 -0
- package/dist/pi-web-plugins/terminal/nodePtySpawnHelper.js +36 -0
- package/dist/pi-web-plugins/terminal/ptyComposition.js +12 -0
- package/dist/pi-web-plugins/terminal/ptyProvider.js +2 -0
- package/dist/pi-web-plugins/terminal/server-plugin.js +42 -14
- package/dist/pi-web-plugins/terminal/terminalService.js +218 -76
- package/dist/pi-web-plugins/themes/assets/graphite.css +56 -0
- package/dist/pi-web-plugins/themes/assets/paper.css +56 -0
- package/dist/pi-web-plugins/themes/package.json +21 -0
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +200 -155
- package/dist/pi-web-plugins/updates/updates.messages.js +59 -0
- package/dist/pi-web-plugins/updates/updatesLogic.js +27 -29
- package/dist/pi-web-plugins/workspace-tasks/config.js +18 -19
- package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +13 -8
- package/dist/pi-web-plugins/workspace-tasks/tasks.messages.js +45 -0
- package/dist/pi-web-plugins/workspace-tasks/tasksLocalization.js +33 -0
- package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +56 -42
- package/dist/pi-web-plugins/workspace-tasks/workspaceTasksClient.js +7 -33
- package/dist/pi-web-plugins/zh-cn/catalogs.json +1803 -0
- package/dist/pi-web-plugins/zh-cn/main.json +5 -1
- package/dist/pi-web-plugins/zh-cn/management-errors.json +6 -0
- package/dist/pi-web-plugins/zh-cn/pi-web-plugin.js +13 -4
- package/dist/pi-web-plugins/zh-cn/server.json +1 -1
- package/dist/piWebVersionReport.js +2 -0
- package/dist/piWebVersionReport.js.map +1 -1
- package/dist/plugin-api.d.ts +194 -9
- package/dist/runtimePreflight.js +14 -0
- package/dist/runtimePreflight.js.map +1 -0
- package/dist/server/activity/workspaceActivityService.js +18 -1
- package/dist/server/activity/workspaceActivityService.js.map +1 -1
- package/dist/server/app.js +45 -10
- package/dist/server/app.js.map +1 -1
- package/dist/server/configRoutes.js +117 -139
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/configUpdates.js +104 -0
- package/dist/server/configUpdates.js.map +1 -0
- package/dist/server/deploymentIdentity.js +12 -10
- package/dist/server/deploymentIdentity.js.map +1 -1
- package/dist/server/deploymentIdentityRoutes.js +2 -1
- package/dist/server/deploymentIdentityRoutes.js.map +1 -1
- package/dist/server/diagnostics/nodePtyNativeModule.js +0 -18
- package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -1
- package/dist/server/diagnostics/terminalPrerequisites.js +54 -0
- package/dist/server/diagnostics/terminalPrerequisites.js.map +1 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/knownAutoInstallPiPackages.js +6 -0
- package/dist/server/knownAutoInstallPiPackages.js.map +1 -1
- package/dist/server/knownPiPackages.js +4 -4
- package/dist/server/knownPiPackages.js.map +1 -1
- package/dist/server/machines/machineClient.js +39 -17
- package/dist/server/machines/machineClient.js.map +1 -1
- package/dist/server/machines/machinePluginProxyRoutes.js +3 -1
- package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineProxyRoutes.js +60 -9
- package/dist/server/machines/machineProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineService.js +81 -13
- package/dist/server/machines/machineService.js.map +1 -1
- package/dist/server/machines/machineStore.js.map +1 -1
- package/dist/server/managementEmbed.js +4 -1
- package/dist/server/managementEmbed.js.map +1 -1
- package/dist/server/managementEntryRoutes.js +51 -0
- package/dist/server/managementEntryRoutes.js.map +1 -0
- package/dist/server/managementEntryTickets.js +46 -0
- package/dist/server/managementEntryTickets.js.map +1 -0
- package/dist/server/managementTransportLimits.js +5 -0
- package/dist/server/managementTransportLimits.js.map +1 -0
- package/dist/server/navigationPreferenceRoutes.js +58 -2
- package/dist/server/navigationPreferenceRoutes.js.map +1 -1
- package/dist/server/normalAuth.js +3 -1
- package/dist/server/normalAuth.js.map +1 -1
- package/dist/server/notices/serverNoticeStore.js +4 -0
- package/dist/server/notices/serverNoticeStore.js.map +1 -1
- package/dist/server/piPackageService.js +15 -1
- package/dist/server/piPackageService.js.map +1 -1
- package/dist/server/piWebPluginCatalog.js +23 -11
- package/dist/server/piWebPluginCatalog.js.map +1 -1
- package/dist/server/piWebPluginLifecycle.js +14 -4
- package/dist/server/piWebPluginLifecycle.js.map +1 -1
- package/dist/server/piWebPluginService.js +11 -5
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/piWebStatus.js +12 -10
- package/dist/server/piWebStatus.js.map +1 -1
- package/dist/server/piWebStatusCache.js +3 -1
- package/dist/server/piWebStatusCache.js.map +1 -1
- package/dist/server/plugins/pluginBackendRegistry.js +229 -4
- package/dist/server/plugins/pluginBackendRegistry.js.map +1 -1
- package/dist/server/plugins/pluginBackendResourceProxyRoutes.js +40 -0
- package/dist/server/plugins/pluginBackendResourceProxyRoutes.js.map +1 -0
- package/dist/server/plugins/pluginBackendResourceResponse.js +84 -0
- package/dist/server/plugins/pluginBackendResourceResponse.js.map +1 -0
- package/dist/server/plugins/projectPluginSettings.js +9 -2
- package/dist/server/plugins/projectPluginSettings.js.map +1 -1
- package/dist/server/plugins/serverPluginCatalogCapability.js +7 -2
- package/dist/server/plugins/serverPluginCatalogCapability.js.map +1 -1
- package/dist/server/plugins/serverPluginPiSessionsCapability.js +16 -3
- package/dist/server/plugins/serverPluginPiSessionsCapability.js.map +1 -1
- package/dist/server/plugins/serverPluginRuntime.js +25 -9
- package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
- package/dist/server/plugins/serverPluginSessionLifecycleCapability.js +87 -0
- package/dist/server/plugins/serverPluginSessionLifecycleCapability.js.map +1 -0
- package/dist/server/requestLogging.js +1 -1
- package/dist/server/requestLogging.js.map +1 -1
- package/dist/server/sessiond/agentHttpDispatcher.js +14 -7
- package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -1
- package/dist/server/sessiond/autoInstallPiPackageSources.js +54 -0
- package/dist/server/sessiond/autoInstallPiPackageSources.js.map +1 -0
- package/dist/server/sessiond/autoInstallPiPackages.js +77 -30
- package/dist/server/sessiond/autoInstallPiPackages.js.map +1 -1
- package/dist/server/sessiond/pluginBackendChannelRoutes.js +3 -13
- package/dist/server/sessiond/pluginBackendChannelRoutes.js.map +1 -1
- package/dist/server/sessiond/pluginBackendResourceRoutes.js +62 -0
- package/dist/server/sessiond/pluginBackendResourceRoutes.js.map +1 -0
- package/dist/server/sessiond/pluginSessionLifecycleRoutes.js +45 -0
- package/dist/server/sessiond/pluginSessionLifecycleRoutes.js.map +1 -0
- package/dist/server/sessiond/sessionProxyRoutes.js +76 -12
- package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
- package/dist/server/sessiond/sessionServiceDependencies.js +3 -0
- package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
- package/dist/server/sessiond.js +47 -16
- package/dist/server/sessiond.js.map +1 -1
- package/dist/server/sessions/askUserDomain.js +24 -2
- package/dist/server/sessions/askUserDomain.js.map +1 -1
- package/dist/server/sessions/askUserTool.js +1 -1
- package/dist/server/sessions/askUserTool.js.map +1 -1
- package/dist/server/sessions/dockerEnvironmentFacts.js +10 -9
- package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -1
- package/dist/server/sessions/mcpOAuthCredentialAdapter.js +4 -4
- package/dist/server/sessions/mcpOAuthCredentialAdapter.js.map +1 -1
- package/dist/server/sessions/piSessionService.js +491 -283
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/requestHumanInterventionTool.js +27 -0
- package/dist/server/sessions/requestHumanInterventionTool.js.map +1 -0
- package/dist/server/sessions/sendSessionMessageTool.js +32 -0
- package/dist/server/sessions/sendSessionMessageTool.js.map +1 -0
- package/dist/server/sessions/sessionActivityCoordinator.js.map +1 -1
- package/dist/server/sessions/sessionCleanup.js +18 -1
- package/dist/server/sessions/sessionCleanup.js.map +1 -1
- package/dist/server/sessions/sessionCommandService.js +58 -52
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionContentSearch.js +103 -30
- package/dist/server/sessions/sessionContentSearch.js.map +1 -1
- package/dist/server/sessions/sessionIntervention.js +29 -0
- package/dist/server/sessions/sessionIntervention.js.map +1 -0
- package/dist/server/sessions/sessionNameGenerator.js +0 -60
- package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
- package/dist/server/sessions/sessionNotificationStore.js +2 -1
- package/dist/server/sessions/sessionNotificationStore.js.map +1 -1
- package/dist/server/sessions/sessionRoutes.js +25 -28
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/sessionSummaryScanner.js +8 -0
- package/dist/server/sessions/sessionSummaryScanner.js.map +1 -1
- package/dist/server/sessions/sessionTreeProjection.js +108 -97
- package/dist/server/sessions/sessionTreeProjection.js.map +1 -1
- package/dist/server/sessions/sessionUiEvents.js +2 -0
- package/dist/server/sessions/sessionUiEvents.js.map +1 -1
- package/dist/server/sessions/sessionUnreadStore.js +11 -1
- package/dist/server/sessions/sessionUnreadStore.js.map +1 -1
- package/dist/server/sessions/spawnSubsessionTool.js +66 -15
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
- package/dist/server/sessions/subsessionCompletionDelivery.js +6 -3
- package/dist/server/sessions/subsessionCompletionDelivery.js.map +1 -1
- package/dist/server/sessions/subsessionCompletionInbox.js +6 -9
- package/dist/server/sessions/subsessionCompletionInbox.js.map +1 -1
- package/dist/server/status/machineStatusService.js +15 -3
- package/dist/server/status/machineStatusService.js.map +1 -1
- package/dist/server/storage/navigationPreferenceStore.js +19 -2
- package/dist/server/storage/navigationPreferenceStore.js.map +1 -1
- package/dist/server/storage/sessionPinStore.js +101 -0
- package/dist/server/storage/sessionPinStore.js.map +1 -0
- package/dist/server/terminals/maintenanceExecutionContext.js +18 -0
- package/dist/server/terminals/maintenanceExecutionContext.js.map +1 -0
- package/dist/server/terminals/maintenanceTerminalCapability.js +25 -0
- package/dist/server/terminals/maintenanceTerminalCapability.js.map +1 -0
- package/dist/server/terminals/requiredTerminalService.js.map +1 -1
- package/dist/server/terminals/terminalStatusRoutes.js +22 -0
- package/dist/server/terminals/terminalStatusRoutes.js.map +1 -0
- package/dist/server/themeBootstrap.js +123 -0
- package/dist/server/themeBootstrap.js.map +1 -0
- package/dist/server/themeCatalog.js +206 -0
- package/dist/server/themeCatalog.js.map +1 -0
- package/dist/server/themeMetadata.js +74 -0
- package/dist/server/themeMetadata.js.map +1 -0
- package/dist/server/webSocketBridge.js +16 -12
- package/dist/server/webSocketBridge.js.map +1 -1
- package/dist/server/webSocketPayloadLimit.js +17 -0
- package/dist/server/webSocketPayloadLimit.js.map +1 -0
- package/dist/server/workspaces/effectivePathAccess.js +1 -1
- package/dist/server/workspaces/effectivePathAccess.js.map +1 -1
- package/dist/server/workspaces/projectPiWebConfig.js +30 -7
- package/dist/server/workspaces/projectPiWebConfig.js.map +1 -1
- package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js +2 -0
- package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js.map +1 -1
- package/dist/server/workspaces/workspaceProviderRegistry.js +6 -2
- package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -1
- package/dist/server/workspaces/workspaceRemovalService.js +6 -4
- package/dist/server/workspaces/workspaceRemovalService.js.map +1 -1
- package/dist/server-plugin-api.d.ts +39 -1
- package/dist/server-plugin-api.js +18 -3
- package/dist/server-plugin-api.js.map +1 -1
- package/dist/sessiond/sessionDaemonClient.js +7 -1
- package/dist/sessiond/sessionDaemonClient.js.map +1 -1
- package/dist/sessiond/sessionDaemonTerminalStatus.js +27 -0
- package/dist/sessiond/sessionDaemonTerminalStatus.js.map +1 -0
- package/dist/shared/apiTypes.js +5 -0
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +9 -0
- package/dist/shared/capabilities.js.map +1 -1
- package/dist/shared/commandOutputPresentation.js +17 -0
- package/dist/shared/commandOutputPresentation.js.map +1 -0
- package/dist/shared/commandResultPresentation.js +51 -0
- package/dist/shared/commandResultPresentation.js.map +1 -0
- package/dist/shared/configResolution.js +99 -0
- package/dist/shared/configResolution.js.map +1 -0
- package/dist/shared/defaultLocalization.js +60 -0
- package/dist/shared/defaultLocalization.js.map +1 -0
- package/dist/shared/federatedRoutes.js +11 -4
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/dist/shared/installationName.js +21 -0
- package/dist/shared/installationName.js.map +1 -0
- package/dist/shared/localization.d.ts +55 -0
- package/dist/shared/localization.js +4 -0
- package/dist/shared/machineStatus.js +2 -0
- package/dist/shared/machineStatus.js.map +1 -1
- package/dist/shared/piWebConfigParsing.js +16 -30
- package/dist/shared/piWebConfigParsing.js.map +1 -1
- package/dist/shared/piWebRuntime.js +17 -0
- package/dist/shared/piWebRuntime.js.map +1 -0
- package/dist/shared/piWebStatusParsing.js +5 -0
- package/dist/shared/piWebStatusParsing.js.map +1 -1
- package/dist/shared/pluginApiTypes.d.ts +35 -7
- package/dist/shared/pluginBackendProtocol.js +24 -0
- package/dist/shared/pluginBackendProtocol.js.map +1 -1
- package/dist/shared/pluginCatalogTypes.d.ts +8 -0
- package/dist/shared/pluginCatalogTypes.js +15 -0
- package/dist/shared/pluginCatalogTypes.js.map +1 -1
- package/dist/shared/pluginResourceMetadata.js +58 -0
- package/dist/shared/pluginResourceMetadata.js.map +1 -0
- package/dist/shared/pluginSessionLifecycleTypes.d.ts +24 -0
- package/dist/shared/pluginSessionLifecycleTypes.js +56 -0
- package/dist/shared/pluginSessionLifecycleTypes.js.map +1 -0
- package/dist/shared/serverNoticePresentation.d.ts +9 -0
- package/dist/shared/serverNoticePresentation.js +12 -0
- package/dist/shared/serverNoticePresentation.js.map +1 -0
- package/dist/shared/sessionActivityPresentation.js +73 -0
- package/dist/shared/sessionActivityPresentation.js.map +1 -0
- package/dist/shared/sessionNotificationPresentation.js +16 -0
- package/dist/shared/sessionNotificationPresentation.js.map +1 -0
- package/dist/shared/terminalCommandRun.js +4 -0
- package/dist/shared/terminalCommandRun.js.map +1 -1
- package/dist/shared/terminalServiceStatus.js +14 -0
- package/dist/shared/terminalServiceStatus.js.map +1 -0
- package/dist/shared/terminalTitlePresentation.d.ts +10 -0
- package/dist/shared/terminalTitlePresentation.js +13 -0
- package/dist/shared/terminalTitlePresentation.js.map +1 -0
- package/dist/shared/themeCatalog.js +2 -0
- package/dist/shared/themeCatalog.js.map +1 -0
- package/dist/shared/themePreference.js +1 -0
- package/dist/shared/themePreference.js.map +1 -1
- package/dist/shared/thinkingLevels.d.ts +29 -0
- package/dist/shared/thinkingLevels.js +6 -4
- package/dist/shared/thinkingLevels.js.map +1 -1
- package/dist/shared/versionCheckPolicy.js +10 -0
- package/dist/shared/versionCheckPolicy.js.map +1 -0
- package/dist/shared/workspaceRemovalPresentation.d.ts +8 -0
- package/dist/shared/workspaceRemovalPresentation.js +10 -0
- package/dist/shared/workspaceRemovalPresentation.js.map +1 -0
- package/docs/README.md +7 -3
- package/docs/assets/pi-web-desktop-graphite.png +0 -0
- package/docs/assets/pi-web-desktop-paper.png +0 -0
- package/docs/assets/pi-web-desktop-pi-web-dark.png +0 -0
- package/docs/assets/pi-web-desktop-pi-web-light.png +0 -0
- package/docs/assets/pi-web-desktop.png +0 -0
- package/docs/assets/pi-web-mobile-graphite.png +0 -0
- package/docs/assets/pi-web-mobile-paper.png +0 -0
- package/docs/assets/pi-web-mobile-pi-web-dark.png +0 -0
- package/docs/assets/pi-web-mobile-pi-web-light.png +0 -0
- package/docs/assets/pi-web-mobile-themes.gif +0 -0
- package/docs/assets/pi-web-mobile.png +0 -0
- package/docs/assets/pi-web-tablet-graphite.png +0 -0
- package/docs/assets/pi-web-tablet-paper.png +0 -0
- package/docs/assets/pi-web-tablet-pi-web-dark.png +0 -0
- package/docs/assets/pi-web-tablet-pi-web-light.png +0 -0
- package/docs/assets/pi-web-tablet-themes.gif +0 -0
- package/docs/assets/pi-web-tablet.png +0 -0
- package/docs/assets/pi-web-themes.gif +0 -0
- package/docs/config.md +193 -55
- package/docs/plugins.md +350 -21
- package/docs/scheduled-tasks.md +127 -0
- package/package.json +43 -19
- package/dist/client/assets/CommandPicker-8oDe6AaV.js +0 -70
- package/dist/client/assets/PiWebApp-TCQVYghs.js +0 -3761
- package/dist/client/assets/SettingsDialog-DFUpwUyp.js +0 -1015
- package/dist/client/assets/index-DzMPXVth.js +0 -2
- package/dist/client/assets/managementEmbed-Bx8Mwzdw.js +0 -2
- package/dist/client/assets/preload-helper-XpATwJ5c.js +0 -1
- package/dist/pi-packages/captains-log/README.md +0 -11
- package/dist/pi-packages/captains-log/dist/browser/channelProtocol.js +0 -29
- package/dist/pi-packages/captains-log/dist/browser/index.js +0 -143
- package/dist/pi-packages/captains-log/dist/browser/markdown.js +0 -68
- package/dist/pi-packages/captains-log/dist/browser/panel.js +0 -148
- package/dist/pi-packages/captains-log/dist/browser/protocol.js +0 -26
- package/dist/pi-packages/captains-log/dist/companion.js +0 -126
- package/dist/pi-packages/captains-log/dist/roundtrip.js +0 -62
- package/dist/pi-packages/captains-log/dist/server.js +0 -210
- package/dist/pi-packages/captains-log/dist/store.js +0 -75
- package/dist/pi-packages/captains-log/docs/usage.md +0 -29
- package/dist/pi-packages/captains-log/i18n.js +0 -7
- package/dist/pi-packages/captains-log/package.json +0 -35
- package/dist/pi-packages/captains-log/tsconfig.json +0 -21
- package/dist/pi-packages/captains-log/vite.config.mjs +0 -28
- package/dist/server/sessions/sessionPinStore.js +0 -109
- package/dist/server/sessions/sessionPinStore.js.map +0 -1
- package/examples/session-bridge-plugin/README.md +0 -20
- package/examples/session-bridge-plugin/docs/usage.md +0 -54
- package/examples/session-bridge-plugin/package.json +0 -26
- package/examples/session-bridge-plugin/src/browser/index.ts +0 -87
- package/examples/session-bridge-plugin/src/browser/protocol.ts +0 -24
- package/examples/session-bridge-plugin/src/companion.ts +0 -65
- package/examples/session-bridge-plugin/src/reviewRun.ts +0 -39
- package/examples/session-bridge-plugin/src/server.ts +0 -85
- package/examples/session-bridge-plugin/src/store.ts +0 -80
- package/examples/session-bridge-plugin/tsconfig.json +0 -21
- /package/dist/{client/assets/classic-CyM97Akm.css → pi-web-plugins/themes/assets/classic.css} +0 -0
- /package/dist/{client/assets/pi-web-dark-D_KtbM95.css → pi-web-plugins/themes/assets/pi-web-dark.css} +0 -0
- /package/dist/{client/assets/pi-web-light-DSNLMIBI.css → pi-web-plugins/themes/assets/pi-web-light.css} +0 -0
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { parsePersistedChildSubsessionLink, parsePersistedParentSubsessionLink } from "./subsessionProvenance.js";
|
|
2
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
|
+
import { sessionNotificationSources } from "../../shared/sessionNotificationPresentation.js";
|
|
5
|
+
import { runtimeActivityFallbackLabel } from "../../shared/sessionActivityPresentation.js";
|
|
6
|
+
const STARTUP_PHASE_RUNTIME = "Starting the Pi session";
|
|
7
|
+
const STARTUP_PHASE_EXTENSIONS = "Loading session extensions";
|
|
8
|
+
const STARTUP_CONCURRENT_CATALOG_REFRESH = "provider model lists are refreshing";
|
|
4
9
|
import { readSessionUiMetadata, requireSessionUiMetadata, SESSION_UI_METADATA_CUSTOM_TYPE } from "./sessionMetadata.js";
|
|
5
10
|
import { UserFacingError, createTranslator, userFacingErrorMessage } from "../../shared/i18n.js";
|
|
6
11
|
import { realpathSync, statSync } from "node:fs";
|
|
7
12
|
import { clientSessionFirstMessagePreview } from "./clientSessionPreview.js";
|
|
8
13
|
import { readFile } from "node:fs/promises";
|
|
9
|
-
import { basename, dirname, isAbsolute,
|
|
14
|
+
import { basename, dirname, isAbsolute, relative, resolve } from "node:path";
|
|
10
15
|
import { QueueCompatibilityGuard, mirroredQueueEntries, mutableQueueAgent, mutableTextMirror, parseQueueMessageMutation, queuedMessageAttachmentCount, queuedMessageAttachmentCounts, snapshotAgentQueues } from "./queuedMessageMutation.js";
|
|
11
16
|
import { createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, createEventBus, createEditToolDefinition, createFindToolDefinition, createGrepToolDefinition, getAgentDir, createLsToolDefinition, createReadToolDefinition, createWriteToolDefinition, defineTool, loadSkills, ProjectTrustStore, hasTrustRequiringProjectResources, readStoredCredential, SessionManager, VERSION, } from "../../piSdk.js";
|
|
12
17
|
import { projectBrowserMessage } from "../browserMessageProjection.js";
|
|
@@ -26,7 +31,7 @@ import { SessionActivityMarker } from "./sessionActivityMarker.js";
|
|
|
26
31
|
import { projectSessionTree } from "./sessionTreeProjection.js";
|
|
27
32
|
import { SessionArchiveStore } from "./sessionArchiveStore.js";
|
|
28
33
|
import { findArchiveCandidateByExactId, planSessionArchiveTree } from "./sessionArchiveTree.js";
|
|
29
|
-
import {
|
|
34
|
+
import { requireInitialSessionName } from "./sessionNameGenerator.js";
|
|
30
35
|
import { computeEditPreview } from "./editPreview.js";
|
|
31
36
|
import { attachmentsToInlineImages, saveAttachmentsToWorkspace } from "./attachmentService.js";
|
|
32
37
|
import { loadEffectiveProjectAttachmentsConfig } from "../workspaces/projectPiWebConfig.js";
|
|
@@ -35,18 +40,19 @@ import { ASK_USER_ANSWERS_CUSTOM_TYPE, SESSION_TREE_CUSTOM_INSTRUCTIONS_MAX_LENG
|
|
|
35
40
|
import { PiSessionEventConnections } from "./piSessionEventConnections.js";
|
|
36
41
|
import { resolveWebProjectTrusted } from "./projectTrust.js";
|
|
37
42
|
import { createPiSessionManagerGateway } from "./piSessionManagerGateway.js";
|
|
38
|
-
import { SessionPinStore } from "./sessionPinStore.js";
|
|
39
43
|
import { SessionActivityCoordinator } from "./sessionActivityCoordinator.js";
|
|
40
|
-
import { searchSessionContent } from "./sessionContentSearch.js";
|
|
44
|
+
import { compileSessionContentQuery, searchSessionContent } from "./sessionContentSearch.js";
|
|
41
45
|
import { createLocalOnlyModelRuntime, modelRuntimeAuthPath } from "./authService.js";
|
|
42
46
|
import { canonicalizeStoredCwd, cwdPathsEqual } from "../workingDirectory.js";
|
|
43
47
|
import { clearSessionFileParent, readSessionHeaderSummary } from "./sessionFileHeader.js";
|
|
44
|
-
import { isManagedAgentsFile, workbenchAccessHandle } from "../managementEmbed.js";
|
|
48
|
+
import { assertManagedCwd, isManagedAgentsFile, workbenchAccessHandle } from "../managementEmbed.js";
|
|
45
49
|
import { managementPrivilegeRequested, managementPrivileges, managementUsesNormalPermissions } from "../managementPrivileges.js";
|
|
46
50
|
import { DEFAULT_EXTENSION_DIALOGS_TIMEOUT_MS, piWebDataDir } from "../../config.js";
|
|
47
51
|
import { createScopedSettingsManager, resolveSettingsScopeDirectory } from "./projectSettingsScope.js";
|
|
48
52
|
import { parseSessionDefaults, parseSessionDefaultsUpdate } from "../../shared/sessionDefaults.js";
|
|
49
53
|
import { createAskUserToolDefinition } from "./askUserTool.js";
|
|
54
|
+
import { createRequestHumanInterventionToolDefinition } from "./requestHumanInterventionTool.js";
|
|
55
|
+
import { requestsHumanIntervention, SESSION_INTERVENTION_CUSTOM_TYPE, sessionInterventionRequired } from "./sessionIntervention.js";
|
|
50
56
|
import { createAskUserOutcome, renderAskUserAnswersText, resolveAskUserRequest } from "./askUserDomain.js";
|
|
51
57
|
import { createSubsessionCompletionDelivery } from "./subsessionCompletionDelivery.js";
|
|
52
58
|
import { completionReceiptIds, persistedSubsessionCompletions, renderSubsessionCompletions, SUBSESSION_COMPLETION_ENTRY_TYPE, SUBSESSION_NOTIFICATION_CUSTOM_TYPE, SUBSESSION_RECEIPT_ENTRY_TYPE, SubsessionCompletionInbox } from "./subsessionCompletionInbox.js";
|
|
@@ -56,6 +62,7 @@ import { ExtensionDialogWaiters, effectiveExtensionDialogTimeoutMs, extensionDia
|
|
|
56
62
|
import { createSpawnSessionToolDefinition } from "./spawnSessionTool.js";
|
|
57
63
|
import { createSubsessionToolDefinitions } from "./spawnSubsessionTool.js";
|
|
58
64
|
import { buildTranscriptView } from "./subsessionTranscript.js";
|
|
65
|
+
import { createSendSessionMessageToolDefinition } from "./sendSessionMessageTool.js";
|
|
59
66
|
import { planSessionCleanup, summarizeSessionCleanupExecution } from "./sessionCleanup.js";
|
|
60
67
|
import { createManagedAgentToolOptions, createManagedBashToolDefinition, createManagedPythonToolDefinition } from "./managementAgentTools.js";
|
|
61
68
|
import { PI_PERMISSION_SYSTEM_POLICY_AGENT_DIR, managementAgentToolNames, privilegedManagementToolNames, withRuntimeCreationEnvironment, writeManagementPermissionSystemPolicy } from "./managementPermissionSystem.js";
|
|
@@ -311,7 +318,8 @@ export function collectRuntimeWarnings(runtime) {
|
|
|
311
318
|
/**
|
|
312
319
|
* Verbatim TUI wording for the Anthropic subscription-auth billing notice. Kept
|
|
313
320
|
* character-for-character in sync with `ANTHROPIC_SUBSCRIPTION_AUTH_WARNING` in
|
|
314
|
-
* the SDK's interactive mode
|
|
321
|
+
* the SDK's interactive mode as the wire fallback. Browser presentation metadata
|
|
322
|
+
* allows translation without matching this English string.
|
|
315
323
|
*/
|
|
316
324
|
const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.";
|
|
317
325
|
/** Mirror of the SDK TUI `isAnthropicSubscriptionAuthKey` (subscription API keys start with `sk-ant-oat`). */
|
|
@@ -352,6 +360,7 @@ export function anthropicSubscriptionWarning(session, authPath) {
|
|
|
352
360
|
return {
|
|
353
361
|
severity: "warning",
|
|
354
362
|
message: ANTHROPIC_SUBSCRIPTION_AUTH_WARNING,
|
|
363
|
+
presentation: { kind: "anthropicSubscriptionAuth" },
|
|
355
364
|
source: "anthropic",
|
|
356
365
|
dismiss: { id: ANTHROPIC_EXTRA_USAGE_DISMISS_ID },
|
|
357
366
|
};
|
|
@@ -438,11 +447,11 @@ async function createNormalPermissionSessionServices(options) {
|
|
|
438
447
|
});
|
|
439
448
|
return { services, projectTrustDiagnostics };
|
|
440
449
|
}
|
|
441
|
-
function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, managementModelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled = false, workbench, logger = noopLogger, managementAudit, managementProjectIdForCwd, appendSystemPromptSections = [], managementAllowPrivileged = false) {
|
|
450
|
+
function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, managementModelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled = false, workbench, logger = noopLogger, managementAudit, managementProjectIdForCwd, appendSystemPromptSections = [], managementAllowPrivileged = false, messaging) {
|
|
442
451
|
return async ({ cwd, agentDir, sessionManager, sessionStartEvent, managementContext, initialModel, initialThinkingLevel, delegationToolsEnabled }) => {
|
|
443
452
|
const scopedModelRuntime = managementContext === undefined ? await normalModelRuntimeForCwd(cwd) : await managementModelRuntime();
|
|
444
453
|
if (managementContext !== undefined) {
|
|
445
|
-
return createManagementRuntimeFactory(scopedModelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled, managementContext, workbench, logger, managementAudit, managementProjectIdForCwd, managementAllowPrivileged, appendSystemPromptSections)({
|
|
454
|
+
return createManagementRuntimeFactory(scopedModelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled, managementContext, workbench, logger, managementAudit, managementProjectIdForCwd, managementAllowPrivileged, appendSystemPromptSections, messaging)({
|
|
446
455
|
cwd,
|
|
447
456
|
agentDir,
|
|
448
457
|
sessionManager,
|
|
@@ -454,6 +463,8 @@ function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, ma
|
|
|
454
463
|
}
|
|
455
464
|
// Resource loaders may read process.env; wait for managed overrides to be restored.
|
|
456
465
|
return withRuntimeCreationEnvironment({}, async () => {
|
|
466
|
+
const parentSessionFile = sessionManager.getHeader()?.parentSession;
|
|
467
|
+
const parentHeader = parentSessionFile === undefined ? undefined : await readSessionHeaderSummary(parentSessionFile);
|
|
457
468
|
const projectTrustRequiring = hasTrustRequiringProjectResources(cwd);
|
|
458
469
|
const settingsManager = await createScopedSettingsManager({
|
|
459
470
|
cwd,
|
|
@@ -473,7 +484,10 @@ function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, ma
|
|
|
473
484
|
modelRuntime: scopedModelRuntime,
|
|
474
485
|
settingsManager,
|
|
475
486
|
projectTrustRequiring,
|
|
476
|
-
appendSystemPromptSections
|
|
487
|
+
appendSystemPromptSections: [
|
|
488
|
+
...appendSystemPromptSections,
|
|
489
|
+
...(parentHeader === undefined ? [] : [`<pi_web_session_context>\nParent session ID: ${parentHeader.id}\n</pi_web_session_context>`]),
|
|
490
|
+
],
|
|
477
491
|
eventBus,
|
|
478
492
|
mcpScope: { directory: mcpOAuthStorageDirectory(await resolveSettingsScope(cwd, "normal")) },
|
|
479
493
|
extensionFactories: [sessionDispatch, ...(subsessions === undefined ? [] : [createSubsessionCompletionDelivery(subsessions)])],
|
|
@@ -488,7 +502,7 @@ function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, ma
|
|
|
488
502
|
const resolvedDelegationToolsEnabled = delegationToolsEnabled
|
|
489
503
|
?? await sessionAllowsDelegationTools(sessionManager, sessionManagers);
|
|
490
504
|
dispatchEnabled = resolvedDelegationToolsEnabled;
|
|
491
|
-
const customTools = createPiWebCustomToolDefinitions(cwd, resolvedDelegationToolsEnabled, spawn, subsessions, askUserEnabled);
|
|
505
|
+
const customTools = createPiWebCustomToolDefinitions(cwd, resolvedDelegationToolsEnabled, spawn, subsessions, askUserEnabled, messaging);
|
|
492
506
|
const result = await createAgentSessionFromServices({
|
|
493
507
|
services,
|
|
494
508
|
sessionManager,
|
|
@@ -505,7 +519,7 @@ function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, ma
|
|
|
505
519
|
});
|
|
506
520
|
};
|
|
507
521
|
}
|
|
508
|
-
function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled, managementContext, workbench, logger, managementAudit, managementProjectIdForCwd, managementAllowPrivileged = false, appendSystemPromptSections = []) {
|
|
522
|
+
function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled, managementContext, workbench, logger, managementAudit, managementProjectIdForCwd, managementAllowPrivileged = false, appendSystemPromptSections = [], messaging) {
|
|
509
523
|
return async ({ cwd, agentDir, sessionManager, sessionStartEvent, initialModel, initialThinkingLevel, delegationToolsEnabled }) => {
|
|
510
524
|
const normalPermissions = managementUsesNormalPermissions(managementContext, { allowPrivileged: managementAllowPrivileged });
|
|
511
525
|
const privileges = managementPrivileges(managementContext, { allowPrivileged: managementAllowPrivileged });
|
|
@@ -541,10 +555,16 @@ function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sess
|
|
|
541
555
|
const scopedSpawn = spawn === undefined
|
|
542
556
|
? undefined
|
|
543
557
|
: (input) => spawn({ ...input, managementContext });
|
|
558
|
+
const scopedMessaging = messaging === undefined ? undefined : {
|
|
559
|
+
send: (input) => messaging.send(input, managementContext),
|
|
560
|
+
};
|
|
544
561
|
const scopedSubsessions = subsessions === undefined
|
|
545
562
|
? undefined
|
|
546
563
|
: {
|
|
547
564
|
spawn: (input) => subsessions.spawn({ ...input, managementContext }),
|
|
565
|
+
archive: (parentSessionId, sessionId, parentSessionFile) => subsessions.archive(parentSessionId, sessionId, parentSessionFile, managementContext),
|
|
566
|
+
stop: (parentSessionId, sessionId, parentSessionFile) => subsessions.stop(parentSessionId, sessionId, parentSessionFile, managementContext),
|
|
567
|
+
resume: (parentSessionId, sessionId, prompt, parentSessionFile) => subsessions.resume(parentSessionId, sessionId, prompt, parentSessionFile, managementContext),
|
|
548
568
|
list: (parentSessionId, parentSessionFile) => subsessions.list(parentSessionId, parentSessionFile, managementContext),
|
|
549
569
|
join: (parentSessionId, parentSessionFile, toolCallId) => subsessions.join(parentSessionId, parentSessionFile, toolCallId, managementContext),
|
|
550
570
|
prepare: (parentSessionId, parentSessionFile) => subsessions.prepare(parentSessionId, parentSessionFile, managementContext),
|
|
@@ -560,6 +580,8 @@ function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sess
|
|
|
560
580
|
...(scopedSubsessions === undefined ? [] : [createSubsessionCompletionDelivery(scopedSubsessions)]),
|
|
561
581
|
];
|
|
562
582
|
const controlledManagementTools = [
|
|
583
|
+
defineTool(createRequestHumanInterventionToolDefinition()),
|
|
584
|
+
...(scopedMessaging === undefined ? [] : [defineTool(createSendSessionMessageToolDefinition(cwd, scopedMessaging))]),
|
|
563
585
|
...(resolvedDelegationToolsEnabled && scopedSpawn !== undefined ? [defineTool(createSpawnSessionToolDefinition(cwd, { spawn: scopedSpawn }))] : []),
|
|
564
586
|
...(resolvedDelegationToolsEnabled && scopedSubsessions !== undefined ? createSubsessionToolDefinitions(cwd, scopedSubsessions).map((tool) => defineTool(tool)) : []),
|
|
565
587
|
...(askUserEnabled ? [createAskUserToolDefinition()] : []),
|
|
@@ -621,7 +643,7 @@ function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sess
|
|
|
621
643
|
...(initialThinkingLevel === undefined ? {} : { initialThinkingLevel }),
|
|
622
644
|
});
|
|
623
645
|
services.diagnostics.push(...modelOptions.diagnostics);
|
|
624
|
-
const customTools = normalPermissions ? createPiWebCustomToolDefinitions(cwd, resolvedDelegationToolsEnabled, scopedSpawn, scopedSubsessions, askUserEnabled) : [
|
|
646
|
+
const customTools = normalPermissions ? createPiWebCustomToolDefinitions(cwd, resolvedDelegationToolsEnabled, scopedSpawn, scopedSubsessions, askUserEnabled, scopedMessaging) : [
|
|
625
647
|
...managedAgentToolDefinitions(cwd, createManagedAgentToolOptions(cwd)),
|
|
626
648
|
createManagedPythonToolDefinition(cwd, managementContext, { network: privileges.network }),
|
|
627
649
|
createManagedBashToolDefinition(cwd, managementContext, { network: privileges.network, hostFilesystem: privileges.bash }),
|
|
@@ -651,9 +673,11 @@ function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sess
|
|
|
651
673
|
});
|
|
652
674
|
};
|
|
653
675
|
}
|
|
654
|
-
export function createPiWebCustomToolDefinitions(cwd, delegationEnabled, spawn, subsessions, askUserEnabled = false) {
|
|
676
|
+
export function createPiWebCustomToolDefinitions(cwd, delegationEnabled, spawn, subsessions, askUserEnabled = false, messaging) {
|
|
655
677
|
return [
|
|
656
678
|
...managedAgentToolDefinitions(cwd),
|
|
679
|
+
defineTool(createRequestHumanInterventionToolDefinition()),
|
|
680
|
+
...(messaging === undefined ? [] : [defineTool(createSendSessionMessageToolDefinition(cwd, messaging))]),
|
|
657
681
|
...(delegationEnabled && spawn !== undefined ? [defineTool(createSpawnSessionToolDefinition(cwd, { spawn }))] : []),
|
|
658
682
|
...(delegationEnabled && subsessions !== undefined ? createSubsessionToolDefinitions(cwd, subsessions).map((tool) => defineTool(tool)) : []),
|
|
659
683
|
...(askUserEnabled ? [createAskUserToolDefinition()] : []),
|
|
@@ -686,7 +710,7 @@ function createPiWebEditToolDefinition(cwd, options) {
|
|
|
686
710
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
687
711
|
const preview = await computeEditPreview(params.path, params.edits, cwd);
|
|
688
712
|
if (signal?.aborted !== true) {
|
|
689
|
-
onUpdate?.({ content: [{ type: "text", text: "Edit preview computed." }], details: { preview } });
|
|
713
|
+
onUpdate?.({ content: [{ type: "text", text: "Edit preview computed." }], details: { preview, presentation: { kind: "editPreviewComputed" } } });
|
|
690
714
|
}
|
|
691
715
|
return editTool.execute(toolCallId, params, signal, onUpdate, ctx);
|
|
692
716
|
},
|
|
@@ -705,12 +729,19 @@ export class PiSessionService {
|
|
|
705
729
|
this.activities = new SessionActivityCoordinator();
|
|
706
730
|
/** Runtime-identity gate held while Pi may await abandoned-branch summarization. */
|
|
707
731
|
this.treeNavigations = new WeakSet();
|
|
732
|
+
this.publishedSessionNames = new WeakMap();
|
|
733
|
+
/**
|
|
734
|
+
* Bare live leaf selected without an appended summary entry. Recording that
|
|
735
|
+
* leaf distinguishes the unpersisted move from a later runtime append that
|
|
736
|
+
* can anchor the selected branch on disk.
|
|
737
|
+
*/
|
|
708
738
|
this.unpersistedTreeBranchLeaves = new WeakMap();
|
|
709
739
|
/** Counts async operations that may append an entry before they settle. */
|
|
710
740
|
this.sessionEntryMutationCounts = new WeakMap();
|
|
711
741
|
this.manualCompactionEnded = new WeakSet();
|
|
712
742
|
this.extensionCommandExecution = new AsyncLocalStorage();
|
|
713
743
|
this.runtimeMessageCounts = new WeakMap();
|
|
744
|
+
this.interventionStates = new WeakMap();
|
|
714
745
|
this.snapshotMessageCounts = new WeakMap();
|
|
715
746
|
this.pendingPromptEchoes = new WeakMap();
|
|
716
747
|
this.publishedAssistantPartials = new WeakMap();
|
|
@@ -730,7 +761,6 @@ export class PiSessionService {
|
|
|
730
761
|
this.subsessionStoppedParents = new WeakSet();
|
|
731
762
|
this.subsessionDeliveringParents = new WeakSet();
|
|
732
763
|
this.subsessionDeliveryScheduled = new WeakSet();
|
|
733
|
-
this.deferredGeneratedSessionNames = new WeakMap();
|
|
734
764
|
this.compactionPromptQueues = new Map();
|
|
735
765
|
this.compactionDrainTimers = new Map();
|
|
736
766
|
this.authLossWarnings = new Set();
|
|
@@ -760,6 +790,7 @@ export class PiSessionService {
|
|
|
760
790
|
this.mcpAuthOwners = new WeakMap();
|
|
761
791
|
this.notificationGenerationBySession = new WeakMap();
|
|
762
792
|
this.idleSessionFileResolutions = new WeakMap();
|
|
793
|
+
this.unreadEligibilityRevision = 0;
|
|
763
794
|
/** The parked extension Promise resolvers behind the store's open dialogs. */
|
|
764
795
|
this.dialogWaiters = new ExtensionDialogWaiters();
|
|
765
796
|
this.pendingUnreadMutations = [];
|
|
@@ -768,7 +799,7 @@ export class PiSessionService {
|
|
|
768
799
|
this.t = deps.translator ?? loadNodeTranslator("server");
|
|
769
800
|
this.managementAllowPrivileged = deps.managementAllowPrivileged === true;
|
|
770
801
|
this.archiveStore = deps.archiveStore ?? new SessionArchiveStore();
|
|
771
|
-
this.
|
|
802
|
+
this.sessionPins = deps.sessionPins;
|
|
772
803
|
this.agentDir = deps.agentDir ?? getAgentDir();
|
|
773
804
|
this.dataDir = deps.dataDir ?? piWebDataDir();
|
|
774
805
|
this.projectPathForCwd = deps.projectPathForCwd;
|
|
@@ -789,6 +820,7 @@ export class PiSessionService {
|
|
|
789
820
|
? resolveDefaultModelRuntime
|
|
790
821
|
: () => Promise.resolve(managementModelRuntime);
|
|
791
822
|
this.spawnTargets = deps.spawnTargets;
|
|
823
|
+
this.messageTargets = deps.sessionMessagesEnabled === false ? undefined : deps.messageTargets ?? deps.spawnTargets;
|
|
792
824
|
this.logger = deps.logger ?? noopLogger;
|
|
793
825
|
this.normalToolAudit = deps.normalToolAudit;
|
|
794
826
|
this.managementAudit = deps.managementAudit;
|
|
@@ -813,20 +845,24 @@ export class PiSessionService {
|
|
|
813
845
|
this.sessionEvents = deps.sessionEvents ?? new PiSessionEventConnections();
|
|
814
846
|
this.createRuntime = deps.createRuntime ?? createDefaultRuntimeFactory(this.sessionEvents, this.normalModelRuntimeForCwd, this.managementModelRuntime, (cwd, mode) => this.resolveSettingsScopeDirectory(cwd, mode), this.sessionManager, this.spawnTargets === undefined ? undefined : (input) => this.spawnSession(input), !subsessionsActive ? undefined : {
|
|
815
847
|
spawn: (input) => this.spawnSubsession(input),
|
|
848
|
+
archive: (parentSessionId, sessionId, parentSessionFile, context) => this.archiveSubsession(parentSessionId, sessionId, parentSessionFile, context),
|
|
849
|
+
stop: (parentSessionId, sessionId, parentSessionFile, context) => this.stopSubsession(parentSessionId, sessionId, parentSessionFile, context),
|
|
850
|
+
resume: (parentSessionId, sessionId, prompt, parentSessionFile, context) => this.resumeSubsession(parentSessionId, sessionId, prompt, parentSessionFile, context),
|
|
816
851
|
list: (parentSessionId, parentSessionFile, managementContext) => this.listSubsessions(parentSessionId, parentSessionFile, managementContext),
|
|
817
852
|
join: (parentSessionId, parentSessionFile, toolCallId, managementContext) => this.joinSubsessions(parentSessionId, parentSessionFile, toolCallId, managementContext),
|
|
818
853
|
prepare: (parentSessionId, parentSessionFile, managementContext) => this.prepareSubsessionDelivery(parentSessionId, parentSessionFile, managementContext),
|
|
819
854
|
check: (parentSessionId, sessionId, parentSessionFile, toolCallId, managementContext) => this.checkSubsession(parentSessionId, sessionId, parentSessionFile, toolCallId, managementContext),
|
|
820
855
|
read: (parentSessionId, sessionId, query, parentSessionFile, toolCallId, managementContext) => this.readSubsession(parentSessionId, sessionId, query, parentSessionFile, toolCallId, managementContext),
|
|
821
|
-
}, deps.askUserEnabled === true, deps.workbench, this.logger, this.managementAudit, this.managementProjectIdForCwd, deps.appendSystemPromptSections ?? [], deps.managementAllowPrivileged === true);
|
|
856
|
+
}, deps.askUserEnabled === true, deps.workbench, this.logger, this.managementAudit, this.managementProjectIdForCwd, deps.appendSystemPromptSections ?? [], deps.managementAllowPrivileged === true, this.messageTargets === undefined ? undefined : { send: (input, context) => this.sendSessionMessage(input, context) });
|
|
822
857
|
this.createAgentRuntime = deps.createAgentRuntime ?? defaultCreateAgentRuntime;
|
|
823
858
|
this.workspaceActivity = deps.workspaceActivity;
|
|
824
859
|
this.heartbeat = setInterval(() => { this.publishHeartbeats(); }, deps.heartbeatIntervalMs ?? 2000);
|
|
825
860
|
this.commandService = new SessionCommandService((sessionId, eventScope) => this.getActiveForCommand(sessionId, eventScope), (sessionId, text, eventScope) => this.submitCommandPrompt(sessionId, text, eventScope), events, {
|
|
861
|
+
onSessionNameChanged: (session) => { this.publishSessionName(session); },
|
|
826
862
|
onCompactionStart: (session) => {
|
|
827
863
|
this.beginSessionEntryMutation(session, this.t("session.action.compact", "compact the session"));
|
|
828
864
|
this.manualCompactionEnded.delete(session);
|
|
829
|
-
this.publishActivity(session,
|
|
865
|
+
this.publishActivity(session, { kind: "compacting" }, "active");
|
|
830
866
|
this.publishStatus(session);
|
|
831
867
|
},
|
|
832
868
|
onCompactionEnd: (session, result, detail) => {
|
|
@@ -866,43 +902,25 @@ export class PiSessionService {
|
|
|
866
902
|
return previewResponseFromPlan(await this.cleanupPlan(request));
|
|
867
903
|
}
|
|
868
904
|
async cleanup(request, context) {
|
|
869
|
-
const scope = eventScopeFromManagementContext(context);
|
|
870
905
|
const plan = await this.cleanupPlan(request);
|
|
871
906
|
if (plan.deleteRecords.length > 0 && this.archiveStore.deleteArchived === undefined && this.archiveStore.deleteArchivedMany === undefined)
|
|
872
907
|
throw new Error(this.t("session.archiveDeleteUnsupported", "The archive store does not support deletion"));
|
|
873
|
-
const
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
const
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
}
|
|
883
|
-
await this.closeActive(input.sessionId, { kind: "clear", reason: "archive" }, scope);
|
|
884
|
-
readyArchiveInputs.push(input);
|
|
885
|
-
}
|
|
886
|
-
await this.archiveStoreArchiveMany(readyArchiveInputs);
|
|
887
|
-
archiveInputs.push(...readyArchiveInputs);
|
|
888
|
-
await this.forgetUnreadSessions(readyArchiveInputs, scope);
|
|
889
|
-
for (const record of plan.deleteRecords) {
|
|
890
|
-
if (this.activeSessionHasWork(record.sessionId)) {
|
|
891
|
-
skippedBusySessionIds.add(record.sessionId);
|
|
892
|
-
continue;
|
|
893
|
-
}
|
|
894
|
-
await this.closeActive(record.sessionId, { kind: "clear", reason: "delete" }, scope);
|
|
895
|
-
readyDeleteRecords.push(record);
|
|
896
|
-
}
|
|
897
|
-
const deletedSessionIds = new Set(await this.archiveStoreDeleteArchivedMany(readyDeleteRecords.map((record) => record.sessionId)));
|
|
898
|
-
deleteRecords.push(...readyDeleteRecords.filter((record) => deletedSessionIds.has(record.sessionId)));
|
|
899
|
-
await this.forgetUnreadSessions(deleteRecords, scope);
|
|
908
|
+
const archived = await this.executeArchiveBatch(plan.archiveInputs, context);
|
|
909
|
+
if (archived.failures.length > 0)
|
|
910
|
+
throw new Error(archived.failures.map((failure) => `${failure.sessionId}: ${failure.error}`).join("; "));
|
|
911
|
+
const deleted = await this.executeDeleteArchivedBatch(plan.deleteRecords, context);
|
|
912
|
+
if (deleted.failures.length > 0)
|
|
913
|
+
throw new Error(deleted.failures.map((failure) => `${failure.sessionId}: ${failure.error}`).join("; "));
|
|
914
|
+
const archiveInputs = archived.successes;
|
|
915
|
+
const deleteRecords = deleted.successes;
|
|
916
|
+
const skippedBusySessionIds = new Set([...plan.skippedBusySessionIds, ...archived.skippedBusySessionIds, ...deleted.skippedBusySessionIds]);
|
|
900
917
|
return summarizeSessionCleanupExecution({
|
|
901
918
|
archiveInputs,
|
|
902
919
|
deleteRecords,
|
|
903
920
|
thresholds: plan.thresholds,
|
|
904
921
|
generatedAt: plan.generatedAt,
|
|
905
922
|
skippedBusySessionIds: [...skippedBusySessionIds],
|
|
923
|
+
...(plan.skippedPinnedSessionIds === undefined ? {} : { skippedPinnedSessionIds: plan.skippedPinnedSessionIds }),
|
|
906
924
|
});
|
|
907
925
|
}
|
|
908
926
|
async dispose() {
|
|
@@ -956,6 +974,18 @@ export class PiSessionService {
|
|
|
956
974
|
});
|
|
957
975
|
await this.publishUnreadMutations([]);
|
|
958
976
|
}
|
|
977
|
+
/** Recover cold-session intervention flags without opening agent runtimes. */
|
|
978
|
+
async restoreInterventionState() {
|
|
979
|
+
const [sessions, archives] = await Promise.all([this.sessionManager.listAll(), this.archiveStore.list()]);
|
|
980
|
+
const archived = new Set(archives.map((record) => record.sessionId));
|
|
981
|
+
for (const session of sessions) {
|
|
982
|
+
if (!await normalSessionReadAllowed(session.cwd, this.projectPathForCwd, this.managementProjectRoot))
|
|
983
|
+
continue;
|
|
984
|
+
if (archived.has(session.id) || this.activeForLookup({ id: session.id, cwd: session.cwd }) !== undefined)
|
|
985
|
+
continue;
|
|
986
|
+
this.workspaceActivity?.applySessionIntervention(session.cwd, session.id, session.interventionRequired === true);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
959
989
|
async list(cwd, managementContext) {
|
|
960
990
|
return (await this.listWorkspaceSessions(cwd, managementContext)).sessions;
|
|
961
991
|
}
|
|
@@ -971,37 +1001,30 @@ export class PiSessionService {
|
|
|
971
1001
|
if (normalizedQuery === "")
|
|
972
1002
|
return { results: [], matchCount: 0, truncated: false };
|
|
973
1003
|
const maxMatches = 200;
|
|
974
|
-
const
|
|
975
|
-
const
|
|
1004
|
+
const listing = await this.listWorkspaceSessions(cwd, managementContext);
|
|
1005
|
+
const matchText = compileSessionContentQuery(normalizedQuery);
|
|
1006
|
+
const candidates = [];
|
|
976
1007
|
let matchCount = 0;
|
|
977
|
-
for (const session of sessions) {
|
|
978
|
-
const
|
|
979
|
-
const
|
|
980
|
-
const view = searchSessionContent(messages, normalizedQuery, Math.max(1, remaining));
|
|
1008
|
+
for (const session of listing.sessions) {
|
|
1009
|
+
const messages = await this.searchableSessionHistory(session, listing, managementContext);
|
|
1010
|
+
const view = searchSessionContent(messages, matchText, maxMatches);
|
|
981
1011
|
matchCount += view.matchCount;
|
|
982
|
-
|
|
983
|
-
|
|
1012
|
+
candidates.push(...view.matches.map((match) => ({ session, match })));
|
|
1013
|
+
candidates.sort((left, right) => left.match.rank - right.match.rank);
|
|
1014
|
+
candidates.length = Math.min(candidates.length, maxMatches);
|
|
1015
|
+
}
|
|
1016
|
+
const grouped = new Map();
|
|
1017
|
+
for (const { session, match } of candidates) {
|
|
1018
|
+
let result = grouped.get(session.id);
|
|
1019
|
+
if (result === undefined) {
|
|
1020
|
+
result = { session, matches: [] };
|
|
1021
|
+
grouped.set(session.id, result);
|
|
1022
|
+
}
|
|
1023
|
+
result.matches.push({ messageIndex: match.messageIndex, role: match.role, excerpts: match.excerpts, occurrenceCount: match.occurrenceCount });
|
|
984
1024
|
}
|
|
1025
|
+
const results = [...grouped.values()];
|
|
985
1026
|
return { results, matchCount, truncated: matchCount > maxMatches };
|
|
986
1027
|
}
|
|
987
|
-
async listPinned(cwd, managementContext) {
|
|
988
|
-
const listing = await this.listWorkspaceSessions(cwd, managementContext);
|
|
989
|
-
const scope = sessionPinScope(cwd, managementContext);
|
|
990
|
-
const sessionIds = await this.pinStore.prune(scope, new Set(listing.sessions.map((session) => session.id)));
|
|
991
|
-
return { sessionIds };
|
|
992
|
-
}
|
|
993
|
-
async setPinned(ref, pinned, managementContext) {
|
|
994
|
-
if (ref.cwd === "")
|
|
995
|
-
throw new Error(this.t("session.pinWorkspaceRequired", "A workspace is required to pin a session"));
|
|
996
|
-
const sessions = await this.list(ref.cwd, managementContext);
|
|
997
|
-
const session = sessions.find((candidate) => candidate.id === ref.id);
|
|
998
|
-
if (session === undefined)
|
|
999
|
-
throw new Error(this.t("session.notFound", "Session not found"));
|
|
1000
|
-
if (session.archived !== true && session.persisted === false)
|
|
1001
|
-
throw new Error(this.t("session.pinPersistedOnly", "Only persisted sessions can be pinned"));
|
|
1002
|
-
await this.pinStore.set(sessionPinScope(ref.cwd, managementContext), session.id, pinned);
|
|
1003
|
-
return { pinned };
|
|
1004
|
-
}
|
|
1005
1028
|
async listWorkspaceSessions(cwd, managementContext) {
|
|
1006
1029
|
if (managementContext === undefined)
|
|
1007
1030
|
await this.normalModelRuntimeForCwd(cwd);
|
|
@@ -1025,11 +1048,17 @@ export class PiSessionService {
|
|
|
1025
1048
|
const listed = unarchivedById.get(session.sessionId);
|
|
1026
1049
|
const tracked = this.subsessionLinkForActiveChild(session) !== undefined;
|
|
1027
1050
|
if (listed !== undefined) {
|
|
1028
|
-
|
|
1029
|
-
|
|
1051
|
+
// Match the file too: a clone with the same id must not inherit a
|
|
1052
|
+
// live runtime's classification. Disk rows otherwise use the scanner.
|
|
1053
|
+
if (session.sessionFile !== undefined && sessionPathsEqual(listed.path, session.sessionFile)) {
|
|
1054
|
+
if (tracked)
|
|
1055
|
+
listed.agentSubsession = true;
|
|
1056
|
+
listed.interventionRequired = this.statusFromSession(session).interventionRequired === true;
|
|
1057
|
+
}
|
|
1030
1058
|
continue;
|
|
1031
1059
|
}
|
|
1032
1060
|
const info = clientSessionFromActiveSession(session);
|
|
1061
|
+
info.interventionRequired = this.statusFromSession(session).interventionRequired === true;
|
|
1033
1062
|
if (tracked)
|
|
1034
1063
|
info.agentSubsession = true;
|
|
1035
1064
|
unarchivedById.set(session.sessionId, info);
|
|
@@ -1040,6 +1069,10 @@ export class PiSessionService {
|
|
|
1040
1069
|
if (managementContext === undefined) {
|
|
1041
1070
|
await this.publishUnreadMutations(this.unreadForScope(eventScopeFromManagementContext(managementContext)).reconcileCwd(canonicalizeStoredCwd(cwd), reconcilableSessionIds));
|
|
1042
1071
|
}
|
|
1072
|
+
for (const session of unarchivedSessions) {
|
|
1073
|
+
if (this.activeForLookup({ id: session.id, cwd }, managementContext) === undefined)
|
|
1074
|
+
this.workspaceActivity?.applySessionIntervention(cwd, session.id, session.interventionRequired === true, eventScopeFromManagementContext(managementContext));
|
|
1075
|
+
}
|
|
1043
1076
|
const archivedSessions = archivedForCwd
|
|
1044
1077
|
.map((record) => clientSessionFromArchivedRecord(record, sessionsById.get(record.sessionId)))
|
|
1045
1078
|
.filter(isDefined)
|
|
@@ -1074,18 +1107,41 @@ export class PiSessionService {
|
|
|
1074
1107
|
continue;
|
|
1075
1108
|
const row = rows.get(session.sessionId);
|
|
1076
1109
|
// A disk clone with the same id must not inherit another file's runtime.
|
|
1077
|
-
if (row !== undefined && (session.sessionFile === undefined || !sessionPathsEqual(row.path, session.sessionFile)))
|
|
1110
|
+
if (row !== undefined && (row.path === undefined || session.sessionFile === undefined || !sessionPathsEqual(row.path, session.sessionFile)))
|
|
1078
1111
|
continue;
|
|
1079
1112
|
runtimes.set(session.sessionId, session);
|
|
1080
|
-
|
|
1113
|
+
const headerCreated = session.sessionManager.getHeader?.()?.timestamp;
|
|
1114
|
+
const metadata = readSessionUiMetadata(session.sessionManager.getEntries?.() ?? session.sessionManager.getBranch());
|
|
1115
|
+
const created = row?.created ?? (headerCreated !== undefined && Number.isFinite(Date.parse(headerCreated)) ? new Date(headerCreated).toISOString() : undefined);
|
|
1116
|
+
// Scanner dates match native cleanup eligibility. A hosted-only runtime's
|
|
1117
|
+
// header records creation, not its most recent activity.
|
|
1118
|
+
rows.set(session.sessionId, {
|
|
1119
|
+
id: session.sessionId,
|
|
1120
|
+
cwd: session.sessionManager.getCwd(),
|
|
1121
|
+
...(session.sessionName === undefined ? {} : { name: session.sessionName }),
|
|
1122
|
+
...(metadata === undefined ? {} : { metadata }),
|
|
1123
|
+
...(created === undefined ? {} : { created }),
|
|
1124
|
+
...(row?.modified === undefined ? {} : { modified: row.modified }),
|
|
1125
|
+
});
|
|
1081
1126
|
}
|
|
1082
1127
|
const entriesById = new Map(entries.map((entry) => [entry.id, entry]));
|
|
1083
1128
|
for (const record of archived) {
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
|
|
1129
|
+
const entry = entriesById.get(record.sessionId);
|
|
1130
|
+
const created = record.created ?? entry?.created.toISOString();
|
|
1131
|
+
const modified = record.modified ?? entry?.modified.toISOString();
|
|
1132
|
+
// Legacy records may lack transcript/path fields required by the client
|
|
1133
|
+
// list helper; their archive identity and known dates are still usable.
|
|
1134
|
+
const row = clientSessionFromArchivedRecord(record, entry) ?? {
|
|
1135
|
+
id: record.sessionId,
|
|
1136
|
+
cwd: record.cwd,
|
|
1137
|
+
...(created === undefined ? {} : { created }),
|
|
1138
|
+
...(modified === undefined ? {} : { modified }),
|
|
1139
|
+
archived: true,
|
|
1140
|
+
archivedAt: record.archivedAt,
|
|
1141
|
+
};
|
|
1142
|
+
rows.set(row.id, row);
|
|
1087
1143
|
}
|
|
1088
|
-
return [...rows.values()].sort((a, b) => Date.parse(b.modified) - Date.parse(a.modified)).map((row) => {
|
|
1144
|
+
return [...rows.values()].sort((a, b) => (b.modified === undefined ? 0 : Date.parse(b.modified)) - (a.modified === undefined ? 0 : Date.parse(a.modified))).map((row) => {
|
|
1089
1145
|
const runtime = runtimes.get(row.id);
|
|
1090
1146
|
return Object.freeze({
|
|
1091
1147
|
id: row.id,
|
|
@@ -1093,6 +1149,9 @@ export class PiSessionService {
|
|
|
1093
1149
|
...(row.name === undefined ? {} : { name: row.name }),
|
|
1094
1150
|
...(row.metadata === undefined ? {} : { metadata: structuredClone(row.metadata) }),
|
|
1095
1151
|
archived: row.archived === true,
|
|
1152
|
+
created: row.created ?? null,
|
|
1153
|
+
modified: row.modified ?? null,
|
|
1154
|
+
archivedAt: row.archived === true ? row.archivedAt ?? null : null,
|
|
1096
1155
|
runtime: runtime === undefined ? "not-hosted" : this.hasActiveWork(runtime) ? "busy" : "idle",
|
|
1097
1156
|
});
|
|
1098
1157
|
});
|
|
@@ -1108,24 +1167,56 @@ export class PiSessionService {
|
|
|
1108
1167
|
return Object.freeze({ id: created.id });
|
|
1109
1168
|
}
|
|
1110
1169
|
/** Atomically start and prompt one visible normal-mode, non-delegating session. */
|
|
1111
|
-
async startOneShotRun(cwd, text, signal) {
|
|
1170
|
+
async startOneShotRun(cwd, text, signal, options = {}) {
|
|
1112
1171
|
const promptText = requirePromptText(text, this.t);
|
|
1113
|
-
return this.startManagedSession(cwd, signal, promptText);
|
|
1172
|
+
return this.startManagedSession(cwd, signal, promptText, options);
|
|
1114
1173
|
}
|
|
1115
|
-
async startManagedSession(cwd, signal, promptText) {
|
|
1174
|
+
async startManagedSession(cwd, signal, promptText, options = {}) {
|
|
1116
1175
|
signal.throwIfAborted();
|
|
1117
|
-
await this.normalModelRuntimeForCwd(cwd);
|
|
1118
|
-
|
|
1176
|
+
const modelRuntime = await this.normalModelRuntimeForCwd(cwd);
|
|
1177
|
+
let initialModel;
|
|
1178
|
+
if (options.model !== undefined) {
|
|
1179
|
+
await modelRuntime.refresh({ allowNetwork: false });
|
|
1180
|
+
signal.throwIfAborted();
|
|
1181
|
+
// Catalog membership alone does not mean the provider still has credentials
|
|
1182
|
+
// or is configured. Host overrides must be available after the refresh.
|
|
1183
|
+
initialModel = modelRuntime.getAvailableSnapshot().find((model) => modelScopeId(model) === options.model);
|
|
1184
|
+
if (initialModel === undefined) {
|
|
1185
|
+
throw Object.assign(new Error(`Model unavailable: ${options.model}`), { code: "PI_SESSION_MODEL_UNAVAILABLE" });
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
const active = await this.create(this.sessionManager.create(cwd), cwd, {
|
|
1189
|
+
startupIntent: "create", creationProvenance: "host-one-shot", startupSignal: signal,
|
|
1190
|
+
...(initialModel === undefined ? {} : { initialModel }),
|
|
1191
|
+
});
|
|
1119
1192
|
const { session } = active.runtime;
|
|
1120
1193
|
try {
|
|
1121
1194
|
signal.throwIfAborted();
|
|
1122
|
-
|
|
1123
|
-
|
|
1195
|
+
// Startup extensions may change the model. Never submit with a fallback
|
|
1196
|
+
// when the caller requested an exact model.
|
|
1197
|
+
if (options.model !== undefined && (session.model === undefined || modelScopeId(session.model) !== options.model)) {
|
|
1198
|
+
throw Object.assign(new Error(`Requested model is not active: ${options.model}`), { code: "PI_SESSION_MODEL_UNAVAILABLE" });
|
|
1199
|
+
}
|
|
1200
|
+
if (options.thinkingLevel !== undefined) {
|
|
1201
|
+
// Do not pass requested thinking into startup: the SDK can silently
|
|
1202
|
+
// clamp it before we have the actual model's supported levels.
|
|
1203
|
+
if (!session.getAvailableThinkingLevels().includes(options.thinkingLevel)) {
|
|
1204
|
+
throw Object.assign(new Error(`Thinking level unavailable: ${options.thinkingLevel}`), { code: "PI_SESSION_THINKING_UNAVAILABLE" });
|
|
1205
|
+
}
|
|
1206
|
+
session.setThinkingLevel(options.thinkingLevel);
|
|
1207
|
+
if (session.thinkingLevel !== options.thinkingLevel) {
|
|
1208
|
+
throw Object.assign(new Error(`Thinking level was not applied: ${options.thinkingLevel}`), { code: "PI_SESSION_THINKING_UNAVAILABLE" });
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
const settings = {
|
|
1212
|
+
...(session.model === undefined ? {} : { model: modelScopeId(session.model) }),
|
|
1213
|
+
thinkingLevel: session.thinkingLevel,
|
|
1214
|
+
};
|
|
1124
1215
|
const created = this.announceCreatedSession(active, cwd);
|
|
1125
1216
|
// Publication transfers lifetime ownership to normal hosting. Plugin
|
|
1126
1217
|
// cancellation after this point must not abort this or later user work.
|
|
1127
1218
|
const completion = promptText === undefined ? Promise.resolve() : this.submitInitialRunPrompt(session, promptText);
|
|
1128
|
-
return Object.freeze({ id: created.id, completion });
|
|
1219
|
+
return Object.freeze({ id: created.id, completion, ...settings });
|
|
1129
1220
|
}
|
|
1130
1221
|
catch (error) {
|
|
1131
1222
|
try {
|
|
@@ -1518,6 +1609,96 @@ export class PiSessionService {
|
|
|
1518
1609
|
...(outcome.answer === undefined ? {} : { answer: outcome.answer }),
|
|
1519
1610
|
}, this.eventScopeForSession(session));
|
|
1520
1611
|
}
|
|
1612
|
+
/** Interrupt a direct child's current run without closing its conversation. */
|
|
1613
|
+
async stopSubsession(parentSessionId, sessionId, parentSessionFile, managementContext) {
|
|
1614
|
+
const child = await this.openSubsession(parentSessionId, sessionId, parentSessionFile, managementContext);
|
|
1615
|
+
const cwd = child.sessionManager.getCwd();
|
|
1616
|
+
await this.abort({ id: sessionId, cwd }, managementContext);
|
|
1617
|
+
return { sessionId, cwd, status: this.subsessionStatus(child) };
|
|
1618
|
+
}
|
|
1619
|
+
/** Start another run in a direct child's conversation, without prompt expansion. */
|
|
1620
|
+
async resumeSubsession(parentSessionId, sessionId, prompt, parentSessionFile, managementContext) {
|
|
1621
|
+
const child = await this.openSubsession(parentSessionId, sessionId, parentSessionFile, managementContext);
|
|
1622
|
+
const cwd = child.sessionManager.getCwd();
|
|
1623
|
+
await this.assertWritable({ id: sessionId, cwd }, managementContext);
|
|
1624
|
+
this.assertTreeNavigationInactive(child, "resume a subsession");
|
|
1625
|
+
if (this.hasActiveWork(child))
|
|
1626
|
+
throw new Error("Subsession is already working");
|
|
1627
|
+
const text = requirePromptText(prompt ?? "Continue your previous task from the current conversation and workspace state. Check any interrupted work before repeating it.", this.t);
|
|
1628
|
+
void this.beginPromptSubmission(child, text, undefined, [], true, { expandPromptTemplates: false }).catch(() => undefined);
|
|
1629
|
+
return { sessionId, cwd, status: "working" };
|
|
1630
|
+
}
|
|
1631
|
+
/** Archive a direct child using the same idle-only operation as the browser. */
|
|
1632
|
+
async archiveSubsession(parentSessionId, sessionId, parentSessionFile, managementContext) {
|
|
1633
|
+
const child = await this.openSubsession(parentSessionId, sessionId, parentSessionFile, managementContext);
|
|
1634
|
+
await this.archive({ id: sessionId, cwd: child.sessionManager.getCwd() }, managementContext);
|
|
1635
|
+
}
|
|
1636
|
+
/** Send content, not control authority, to a named session in the same project. */
|
|
1637
|
+
async sendSessionMessage(input, managementContext) {
|
|
1638
|
+
if (this.messageTargets === undefined)
|
|
1639
|
+
throw new Error("Session messaging is unavailable");
|
|
1640
|
+
const message = requirePromptText(input.message, this.t);
|
|
1641
|
+
if (managementContext === undefined)
|
|
1642
|
+
await this.assertNormalSessionReadAccess(input.sendingCwd);
|
|
1643
|
+
else
|
|
1644
|
+
await this.getActive({ id: input.sendingSessionId, cwd: input.sendingCwd }, managementContext);
|
|
1645
|
+
const active = this.activeForLookup(input.sessionId, managementContext);
|
|
1646
|
+
const target = active === undefined
|
|
1647
|
+
? (await this.sessionManager.listAll()).find((entry) => entry.id === input.sessionId)
|
|
1648
|
+
: { id: input.sessionId, cwd: active.runtime.cwd };
|
|
1649
|
+
if (target === undefined)
|
|
1650
|
+
throw new Error("Session not found");
|
|
1651
|
+
if (active === undefined && this.activeSessionsForId(input.sessionId).some((entry) => cwdPathsEqual(entry.runtime.cwd, target.cwd)))
|
|
1652
|
+
throw new Error("Session not found");
|
|
1653
|
+
const decision = await this.messageTargets.resolveSpawnTarget(input.sendingCwd, target.cwd, eventScopeFromManagementContext(managementContext));
|
|
1654
|
+
if (!decision.allowed)
|
|
1655
|
+
throw new Error("Session messaging is limited to sessions in the same registered project");
|
|
1656
|
+
if (managementContext === undefined)
|
|
1657
|
+
await this.assertNormalSessionReadAccess(decision.cwd);
|
|
1658
|
+
else {
|
|
1659
|
+
if (this.managementProjectRoot === undefined)
|
|
1660
|
+
throw new Error("Managed session messaging requires a project root");
|
|
1661
|
+
await assertManagedCwd(this.managementProjectRoot, managementContext, decision.cwd, { create: false });
|
|
1662
|
+
}
|
|
1663
|
+
const ref = { id: input.sessionId, cwd: decision.cwd };
|
|
1664
|
+
await this.assertWritable(ref, managementContext);
|
|
1665
|
+
const session = await this.getOrOpen(ref, managementContext);
|
|
1666
|
+
this.assertTreeNavigationInactive(session, "receive a session message");
|
|
1667
|
+
const delivery = this.hasActiveWork(session) ? "queued" : "started";
|
|
1668
|
+
let agentStarted = false;
|
|
1669
|
+
const unsubscribe = session.subscribe((event) => {
|
|
1670
|
+
if (getString(event, "type") === "agent_start")
|
|
1671
|
+
agentStarted = true;
|
|
1672
|
+
});
|
|
1673
|
+
// A custom-message turn may run for minutes. Never wait for its answer in
|
|
1674
|
+
// the sender: reciprocal messages must not deadlock their tool calls.
|
|
1675
|
+
void this.runSessionEntryMutation(session, "receive a session message", async () => {
|
|
1676
|
+
if (session.isCompacting || session.isBashRunning)
|
|
1677
|
+
await session.waitForIdle();
|
|
1678
|
+
if (!this.isCurrentActiveSession(session))
|
|
1679
|
+
throw new Error("Session was closed before message delivery");
|
|
1680
|
+
await session.sendCustomMessage({
|
|
1681
|
+
customType: "session.message",
|
|
1682
|
+
content: `Message from session ${input.sendingSessionId}:\n\n${message}`,
|
|
1683
|
+
display: true,
|
|
1684
|
+
details: { sendingSessionId: input.sendingSessionId },
|
|
1685
|
+
}, { triggerTurn: true, deliverAs: "steer" });
|
|
1686
|
+
}).catch((error) => {
|
|
1687
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
1688
|
+
this.logger.info({ sessionId: input.sessionId, sendingSessionId: input.sendingSessionId, error: detail }, "session message delivery failed");
|
|
1689
|
+
if (!this.isCurrentActiveSession(session))
|
|
1690
|
+
return;
|
|
1691
|
+
this.publishActivity(session, { kind: "error" }, "error", detail);
|
|
1692
|
+
const scope = this.eventScopeForSession(session);
|
|
1693
|
+
this.events.publish(session.sessionId, { type: "session.error", message: detail }, scope);
|
|
1694
|
+
if (!agentStarted && this.subsessionLinkForActiveChild(session) !== undefined)
|
|
1695
|
+
this.subsessionNotifyArmed.set(activeSessionKey(session.sessionId, scope), true);
|
|
1696
|
+
this.updateSubsessionTracking(session);
|
|
1697
|
+
this.publishStatus(session);
|
|
1698
|
+
}).finally(unsubscribe);
|
|
1699
|
+
this.logger.info({ sendingSessionId: input.sendingSessionId, sessionId: input.sessionId, delivery }, "session message accepted");
|
|
1700
|
+
return { sessionId: input.sessionId, delivery };
|
|
1701
|
+
}
|
|
1521
1702
|
/** Summaries of the tracked subsessions spawned by `parentSessionId`. */
|
|
1522
1703
|
async listSubsessions(parentSessionId, parentSessionFile, managementContext) {
|
|
1523
1704
|
const parentFile = nonEmptyString(parentSessionFile);
|
|
@@ -2015,13 +2196,17 @@ export class PiSessionService {
|
|
|
2015
2196
|
}));
|
|
2016
2197
|
return { listing, sessions: matches.filter(isDefined) };
|
|
2017
2198
|
}
|
|
2018
|
-
searchableSessionHistory(session, listing, managementContext) {
|
|
2199
|
+
async searchableSessionHistory(session, listing, managementContext) {
|
|
2019
2200
|
const eventScope = eventScopeFromManagementContext(managementContext);
|
|
2020
2201
|
const active = this.activeForSessionIdAndScope(session.id, eventScope);
|
|
2021
2202
|
if (active !== undefined && cwdPathsEqual(active.runtime.cwd, session.cwd))
|
|
2022
2203
|
return historyMessages(active.runtime.session);
|
|
2023
2204
|
const path = listing.archivedById.get(session.id)?.archivePath ?? listing.entriesById.get(session.id)?.path;
|
|
2024
|
-
|
|
2205
|
+
if (path === undefined)
|
|
2206
|
+
return [];
|
|
2207
|
+
if (this.sessionManager.readBranch !== undefined)
|
|
2208
|
+
return historyMessagesFromEntries(await this.sessionManager.readBranch(path) ?? []);
|
|
2209
|
+
return historyMessagesFromManager(this.sessionManager.open(path));
|
|
2025
2210
|
}
|
|
2026
2211
|
async streamSnapshot(ref, managementContext) {
|
|
2027
2212
|
const session = await this.getOrOpen(ref, managementContext);
|
|
@@ -2159,7 +2344,7 @@ export class PiSessionService {
|
|
|
2159
2344
|
if (model === undefined)
|
|
2160
2345
|
throw new Error(this.t("model.notFound", "Model not found: {value0}/{value1}", { value0: provider, value1: modelId }));
|
|
2161
2346
|
await this.runSessionEntryMutation(session, this.t("server.main.130226a572df", "change models"), () => session.setModel(model));
|
|
2162
|
-
this.publishActivity(session,
|
|
2347
|
+
this.publishActivity(session, { kind: "model", value: model.id }, "idle", model.provider);
|
|
2163
2348
|
this.publishStatus(session);
|
|
2164
2349
|
return this.statusFromSession(session);
|
|
2165
2350
|
}
|
|
@@ -2173,7 +2358,7 @@ export class PiSessionService {
|
|
|
2173
2358
|
});
|
|
2174
2359
|
if (result === undefined)
|
|
2175
2360
|
throw new Error(session.scopedModels.length > 0 ? this.t("model.oneScoped", "Only one scoped model is available") : this.t("model.oneAvailable", "Only one model is available"));
|
|
2176
|
-
this.publishActivity(session,
|
|
2361
|
+
this.publishActivity(session, { kind: "model", value: result.model.id }, "idle", result.model.provider);
|
|
2177
2362
|
this.publishStatus(session);
|
|
2178
2363
|
return this.statusFromSession(session);
|
|
2179
2364
|
}
|
|
@@ -2195,7 +2380,7 @@ export class PiSessionService {
|
|
|
2195
2380
|
session.setThinkingLevel(match);
|
|
2196
2381
|
return Promise.resolve();
|
|
2197
2382
|
});
|
|
2198
|
-
this.publishActivity(session,
|
|
2383
|
+
this.publishActivity(session, { kind: "thinking", value: session.thinkingLevel }, "idle");
|
|
2199
2384
|
this.publishStatus(session);
|
|
2200
2385
|
return this.statusFromSession(session);
|
|
2201
2386
|
}
|
|
@@ -2205,7 +2390,7 @@ export class PiSessionService {
|
|
|
2205
2390
|
const level = await this.runSessionEntryMutation(session, this.t("session.action.changeThinking", "change the thinking level"), () => Promise.resolve(session.cycleThinkingLevel()));
|
|
2206
2391
|
if (level === undefined)
|
|
2207
2392
|
throw new Error(this.t("model.thinkingUnsupported", "The current model does not support thinking"));
|
|
2208
|
-
this.publishActivity(session,
|
|
2393
|
+
this.publishActivity(session, { kind: "thinking", value: level }, "idle");
|
|
2209
2394
|
this.publishStatus(session);
|
|
2210
2395
|
return this.statusFromSession(session);
|
|
2211
2396
|
}
|
|
@@ -2241,11 +2426,10 @@ export class PiSessionService {
|
|
|
2241
2426
|
await this.assertWritable(ref, options?.managementContext);
|
|
2242
2427
|
const session = await this.getOrOpen(ref, options?.managementContext);
|
|
2243
2428
|
this.assertTreeNavigationInactive(session, this.t("server.main.94306b2fc35c", "send a prompt"));
|
|
2244
|
-
this.maybeGenerateSessionName(session, promptText);
|
|
2245
2429
|
const isQueued = session.isStreaming || session.isCompacting;
|
|
2246
2430
|
const behavior = isQueued ? requestedBehavior ?? "followUp" : undefined;
|
|
2247
2431
|
if (isQueued && images.length === 0 && this.hasQueuedMessageText(session, promptText)) {
|
|
2248
|
-
this.publishActivity(session,
|
|
2432
|
+
this.publishActivity(session, { kind: "duplicateQueuedMessage" }, "active");
|
|
2249
2433
|
this.publishStatus(session);
|
|
2250
2434
|
return;
|
|
2251
2435
|
}
|
|
@@ -2267,7 +2451,7 @@ export class PiSessionService {
|
|
|
2267
2451
|
beginPromptSubmission(session, text, behavior, images = [], echoUserMessage = true, options = {}) {
|
|
2268
2452
|
if (options.auditUserPrompt !== false)
|
|
2269
2453
|
this.auditUserPrompt(session, text);
|
|
2270
|
-
this.publishActivity(session, behavior === "steer" ?
|
|
2454
|
+
this.publishActivity(session, behavior === "steer" ? { kind: "steeringQueued" } : behavior === "followUp" ? { kind: "messageQueued" } : { kind: "promptAccepted" }, "active");
|
|
2271
2455
|
const eventScope = this.eventScopeForSession(session);
|
|
2272
2456
|
const echoes = this.pendingPromptEchoes.get(session) ?? [];
|
|
2273
2457
|
const userCount = historyMessagesFromEntries(session.sessionManager.getBranch()).filter((message) => isRecord(message) && message["role"] === "user").length;
|
|
@@ -2308,7 +2492,7 @@ export class PiSessionService {
|
|
|
2308
2492
|
void promptPromise.catch((error) => {
|
|
2309
2493
|
this.subsessionStoppedParents.add(session);
|
|
2310
2494
|
const message = error instanceof Error ? error.message : String(error);
|
|
2311
|
-
this.publishActivity(session,
|
|
2495
|
+
this.publishActivity(session, { kind: "error" }, "error", message);
|
|
2312
2496
|
this.events.publish(session.sessionId, { type: "session.error", message }, eventScope);
|
|
2313
2497
|
if (this.isCurrentActiveSession(session)) {
|
|
2314
2498
|
const link = this.subsessionLinkForActiveChild(session);
|
|
@@ -2372,7 +2556,7 @@ export class PiSessionService {
|
|
|
2372
2556
|
const queue = this.compactionPromptQueues.get(sessionKey) ?? [];
|
|
2373
2557
|
queue.push({ kind, text, ...(images.length > 0 ? { images } : {}), ...(echoUserMessage ? {} : { echoUserMessage: false }) });
|
|
2374
2558
|
this.compactionPromptQueues.set(sessionKey, queue);
|
|
2375
|
-
this.publishActivity(session,
|
|
2559
|
+
this.publishActivity(session, { kind: "queuedDuringCompaction" }, "active");
|
|
2376
2560
|
this.publishStatus(session);
|
|
2377
2561
|
}
|
|
2378
2562
|
async saveAttachments(ref, attachments, folder, managementContext) {
|
|
@@ -2386,8 +2570,8 @@ export class PiSessionService {
|
|
|
2386
2570
|
return saveAttachmentsToWorkspace(cwd, parsed, effectiveFolder === undefined ? {} : { folder: effectiveFolder });
|
|
2387
2571
|
}
|
|
2388
2572
|
async workspaceAttachmentsConfig(cwd) {
|
|
2389
|
-
const
|
|
2390
|
-
return loadEffectiveProjectAttachmentsConfig(cwd,
|
|
2573
|
+
const response = this.config === undefined ? undefined : await this.config.read();
|
|
2574
|
+
return loadEffectiveProjectAttachmentsConfig(cwd, response?.effectiveConfig ?? {}, response?.enforcedSettings);
|
|
2391
2575
|
}
|
|
2392
2576
|
async shell(ref, text, managementContext) {
|
|
2393
2577
|
await this.assertWritable(ref, managementContext);
|
|
@@ -2401,11 +2585,11 @@ export class PiSessionService {
|
|
|
2401
2585
|
if (session.isBashRunning)
|
|
2402
2586
|
throw new Error(this.t("shell.alreadyRunning", "A bash command is already running"));
|
|
2403
2587
|
const eventScope = active.eventScope;
|
|
2404
|
-
this.publishActivity(session,
|
|
2588
|
+
this.publishActivity(session, { kind: "runningBash" }, "active", command);
|
|
2405
2589
|
this.events.publish(session.sessionId, { type: "shell.start", command, excludeFromContext: isExcluded }, eventScope);
|
|
2406
2590
|
void this.runSessionEntryMutation(session, this.t("session.action.shell", "run a shell command"), () => session.executeBash(command, (chunk) => {
|
|
2407
2591
|
this.events.publish(session.sessionId, { type: "shell.chunk", chunk }, eventScope);
|
|
2408
|
-
this.publishActivity(session,
|
|
2592
|
+
this.publishActivity(session, { kind: "runningBash" }, "active", command);
|
|
2409
2593
|
this.publishStatus(session);
|
|
2410
2594
|
}, { excludeFromContext: isExcluded })).then((result) => {
|
|
2411
2595
|
this.events.publish(session.sessionId, {
|
|
@@ -2416,13 +2600,13 @@ export class PiSessionService {
|
|
|
2416
2600
|
truncated: result.truncated,
|
|
2417
2601
|
...(result.fullOutputPath === undefined ? {} : { fullOutputPath: result.fullOutputPath }),
|
|
2418
2602
|
}, eventScope);
|
|
2419
|
-
this.publishActivity(session,
|
|
2603
|
+
this.publishActivity(session, { kind: "bashComplete" }, result.exitCode === 0 ? "idle" : "error", command);
|
|
2420
2604
|
this.publishStatus(session);
|
|
2421
2605
|
}).catch((error) => {
|
|
2422
2606
|
const message = userFacingErrorMessage(error, this.t);
|
|
2423
2607
|
this.events.publish(session.sessionId, { type: "shell.end", output: message, isError: true }, eventScope);
|
|
2424
2608
|
this.events.publish(session.sessionId, { type: "session.error", message }, eventScope);
|
|
2425
|
-
this.publishActivity(session,
|
|
2609
|
+
this.publishActivity(session, { kind: "bashFailed" }, "error", message);
|
|
2426
2610
|
this.publishStatus(session);
|
|
2427
2611
|
});
|
|
2428
2612
|
}
|
|
@@ -2469,7 +2653,7 @@ export class PiSessionService {
|
|
|
2469
2653
|
if (retainCustomMessage && options.summarize === true)
|
|
2470
2654
|
throw new Error(this.t("session.checkpointSummary", "Retaining a custom-message checkpoint requires navigation without a branch summary"));
|
|
2471
2655
|
const activeEditableTargetParentId = retainCustomMessage ? undefined : activeEditableTreeTargetParentId(session.sessionManager, targetId, oldLeafId);
|
|
2472
|
-
this.publishActivity(session, options.summarize === true ?
|
|
2656
|
+
this.publishActivity(session, options.summarize === true ? { kind: "summarizingBranch" } : { kind: "navigatingTree" }, "active");
|
|
2473
2657
|
this.publishStatus(session);
|
|
2474
2658
|
let result = retainCustomMessage
|
|
2475
2659
|
? await navigateTreeRetainingCustomMessage(session.sessionManager, targetId, checkpointTail["parentId"], () => navigateTree(targetId, options))
|
|
@@ -2490,7 +2674,7 @@ export class PiSessionService {
|
|
|
2490
2674
|
}
|
|
2491
2675
|
if (result.cancelled) {
|
|
2492
2676
|
if (this.isCurrentActiveSession(session)) {
|
|
2493
|
-
this.publishActivity(session, result.aborted === true ?
|
|
2677
|
+
this.publishActivity(session, result.aborted === true ? { kind: "branchSummaryAborted" } : { kind: "treeNavigationCancelled" }, "idle");
|
|
2494
2678
|
}
|
|
2495
2679
|
return { cancelled: true, ...(result.aborted === undefined ? {} : { aborted: result.aborted }) };
|
|
2496
2680
|
}
|
|
@@ -2505,13 +2689,13 @@ export class PiSessionService {
|
|
|
2505
2689
|
this.setSuggestedInput(session, result.editorText);
|
|
2506
2690
|
this.events.publish(session.sessionId, { type: "session.tree.changed" }, this.eventScopeForSession(session));
|
|
2507
2691
|
if (this.isCurrentActiveSession(session))
|
|
2508
|
-
this.publishActivity(session,
|
|
2692
|
+
this.publishActivity(session, { kind: "treeNavigated" }, "idle");
|
|
2509
2693
|
return { cancelled: false, ...(result.editorText === undefined ? {} : { editorText: result.editorText }) };
|
|
2510
2694
|
}
|
|
2511
2695
|
catch (error) {
|
|
2512
2696
|
const message = userFacingErrorMessage(error, this.t);
|
|
2513
2697
|
if (this.isCurrentActiveSession(session)) {
|
|
2514
|
-
this.publishActivity(session,
|
|
2698
|
+
this.publishActivity(session, { kind: "treeNavigationFailed" }, "error", message);
|
|
2515
2699
|
this.events.publish(session.sessionId, { type: "session.error", message }, this.eventScopeForSession(session));
|
|
2516
2700
|
}
|
|
2517
2701
|
throw error;
|
|
@@ -2524,7 +2708,6 @@ export class PiSessionService {
|
|
|
2524
2708
|
this.publishStatus(session);
|
|
2525
2709
|
}
|
|
2526
2710
|
else {
|
|
2527
|
-
this.deferredGeneratedSessionNames.delete(session);
|
|
2528
2711
|
this.subsessionInbox(session.sessionId, session.sessionFile, this.eventScopeForSession(session)).releaseClaims();
|
|
2529
2712
|
}
|
|
2530
2713
|
}
|
|
@@ -2551,7 +2734,7 @@ export class PiSessionService {
|
|
|
2551
2734
|
const sourceSessionId = session.sessionId;
|
|
2552
2735
|
const sourceEventScope = this.eventScopeForSession(session);
|
|
2553
2736
|
const sourceCwd = session.sessionManager.getCwd();
|
|
2554
|
-
this.publishActivity(session,
|
|
2737
|
+
this.publishActivity(session, { kind: "forking" }, "active");
|
|
2555
2738
|
this.publishStatus(session);
|
|
2556
2739
|
try {
|
|
2557
2740
|
const entryId = request.retainCheckpoint === true ? messageHistoryTargetId(session.sessionManager.getBranch(), request.entryId) : request.entryId;
|
|
@@ -2564,7 +2747,7 @@ export class PiSessionService {
|
|
|
2564
2747
|
throw new Error(this.t("server.main.0246b6af6843", "Session fork is unavailable"));
|
|
2565
2748
|
if (result.session === undefined) {
|
|
2566
2749
|
if (this.isCurrentActiveSession(session)) {
|
|
2567
|
-
this.publishActivity(session,
|
|
2750
|
+
this.publishActivity(session, { kind: "forkCancelled" }, "idle");
|
|
2568
2751
|
this.publishStatus(session);
|
|
2569
2752
|
}
|
|
2570
2753
|
return { cancelled: true };
|
|
@@ -2574,7 +2757,7 @@ export class PiSessionService {
|
|
|
2574
2757
|
this.setSuggestedInput(forked, result.promptDraft);
|
|
2575
2758
|
this.events.publish(sourceSessionId, { type: "session.tree.changed" }, sourceEventScope);
|
|
2576
2759
|
if (forked !== undefined && this.isCurrentActiveSession(forked)) {
|
|
2577
|
-
this.publishActivity(forked,
|
|
2760
|
+
this.publishActivity(forked, { kind: "forked" }, "idle");
|
|
2578
2761
|
this.publishStatus(forked);
|
|
2579
2762
|
}
|
|
2580
2763
|
if (result.session.id !== sourceSessionId)
|
|
@@ -2588,7 +2771,7 @@ export class PiSessionService {
|
|
|
2588
2771
|
catch (error) {
|
|
2589
2772
|
const message = userFacingErrorMessage(error, this.t);
|
|
2590
2773
|
if (this.isCurrentActiveSession(session)) {
|
|
2591
|
-
this.publishActivity(session,
|
|
2774
|
+
this.publishActivity(session, { kind: "forkFailed" }, "error", message);
|
|
2592
2775
|
this.events.publish(session.sessionId, { type: "session.error", message }, sourceEventScope);
|
|
2593
2776
|
this.publishStatus(session);
|
|
2594
2777
|
}
|
|
@@ -2599,7 +2782,7 @@ export class PiSessionService {
|
|
|
2599
2782
|
const sessionKey = activeSessionKey(sessionId, eventScope);
|
|
2600
2783
|
if (this.activities.get(sessionKey)?.phase === "active") {
|
|
2601
2784
|
const at = new Date().toISOString();
|
|
2602
|
-
const stored = { phase: "idle", label:
|
|
2785
|
+
const stored = { phase: "idle", label: "idle", at, runtimePresentation: { kind: "idle" } };
|
|
2603
2786
|
this.activities.set(sessionKey, stored);
|
|
2604
2787
|
const activity = { sessionId, ...stored };
|
|
2605
2788
|
this.events.publish(sessionId, { type: "activity.update", activity }, eventScope);
|
|
@@ -2615,6 +2798,7 @@ export class PiSessionService {
|
|
|
2615
2798
|
const archiveInput = await this.archiveInputForSession(session);
|
|
2616
2799
|
await this.closeActiveSession(active);
|
|
2617
2800
|
await this.archiveStore.archive(archiveInput);
|
|
2801
|
+
this.workspaceActivity?.removeSession(archiveInput.sessionId, archiveInput.cwd, active.eventScope);
|
|
2618
2802
|
await this.forgetUnreadSessions([archiveInput], active.eventScope);
|
|
2619
2803
|
});
|
|
2620
2804
|
}
|
|
@@ -2658,43 +2842,10 @@ export class PiSessionService {
|
|
|
2658
2842
|
failures.push({ sessionId: resolvedSessionId, error: errorMessage(error, this.t) });
|
|
2659
2843
|
}
|
|
2660
2844
|
}
|
|
2661
|
-
const
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
failures.push({ sessionId: item.input.sessionId, error: this.t("session.stopBeforeArchive", "Stop current session activity before archiving") });
|
|
2666
|
-
continue;
|
|
2667
|
-
}
|
|
2668
|
-
readyPlanItems.push(active === undefined ? item : { ...item, active });
|
|
2669
|
-
}
|
|
2670
|
-
const readyInputs = [];
|
|
2671
|
-
const archivedSessionIds = [...alreadyArchivedSessionIds];
|
|
2672
|
-
await this.runTreeExclusiveOperation(readyPlanItems.map(({ input, active }) => ({
|
|
2673
|
-
sessionId: input.sessionId,
|
|
2674
|
-
...(active === undefined ? {} : { session: active.runtime.session, runtime: active.runtime }),
|
|
2675
|
-
})), this.t("session.stopBeforeArchive", "Stop current session activity before archiving"), async () => {
|
|
2676
|
-
for (const item of readyPlanItems) {
|
|
2677
|
-
try {
|
|
2678
|
-
if (item.active !== undefined)
|
|
2679
|
-
await this.closeActiveSession(item.active);
|
|
2680
|
-
else
|
|
2681
|
-
await this.closeActiveInScope(item.input.sessionId, eventScopeFromManagementContext(managementContext));
|
|
2682
|
-
readyInputs.push(item.input);
|
|
2683
|
-
}
|
|
2684
|
-
catch (error) {
|
|
2685
|
-
failures.push({ sessionId: item.input.sessionId, error: errorMessage(error, this.t) });
|
|
2686
|
-
}
|
|
2687
|
-
}
|
|
2688
|
-
try {
|
|
2689
|
-
const archived = await this.archiveStoreArchiveMany(readyInputs);
|
|
2690
|
-
archivedSessionIds.push(...archived.map((record) => record.sessionId));
|
|
2691
|
-
unreadArchivedIdentities.push(...archived);
|
|
2692
|
-
}
|
|
2693
|
-
catch (error) {
|
|
2694
|
-
for (const input of readyInputs)
|
|
2695
|
-
failures.push({ sessionId: input.sessionId, error: errorMessage(error, this.t) });
|
|
2696
|
-
}
|
|
2697
|
-
});
|
|
2845
|
+
const execution = await this.executeArchiveBatch(planItems.map((item) => item.input), managementContext);
|
|
2846
|
+
failures.push(...execution.failures);
|
|
2847
|
+
failures.push(...execution.skippedBusySessionIds.map((sessionId) => ({ sessionId, error: this.t("session.stopBeforeArchive", "Stop current session activity before archiving") })));
|
|
2848
|
+
const archivedSessionIds = [...alreadyArchivedSessionIds, ...execution.successes.map((input) => input.sessionId)];
|
|
2698
2849
|
await this.forgetUnreadSessions(unreadArchivedIdentities, eventScopeFromManagementContext(managementContext));
|
|
2699
2850
|
return {
|
|
2700
2851
|
archived: true,
|
|
@@ -2722,7 +2873,9 @@ export class PiSessionService {
|
|
|
2722
2873
|
}
|
|
2723
2874
|
for (const input of archiveInputs)
|
|
2724
2875
|
await this.closeActiveInScope(input.sessionId, eventScopeFromManagementContext(managementContext));
|
|
2725
|
-
await this.archiveStoreArchiveMany(archiveInputs);
|
|
2876
|
+
const archived = await this.archiveStoreArchiveMany(archiveInputs);
|
|
2877
|
+
for (const record of archived)
|
|
2878
|
+
this.workspaceActivity?.removeSession(record.sessionId, record.cwd, eventScopeFromManagementContext(managementContext));
|
|
2726
2879
|
});
|
|
2727
2880
|
await this.forgetUnreadSessions(plan.targets.map((target) => ({ sessionId: target.id, cwd: target.cwd })), eventScopeFromManagementContext(managementContext));
|
|
2728
2881
|
return {
|
|
@@ -2735,10 +2888,15 @@ export class PiSessionService {
|
|
|
2735
2888
|
async restore(ref, managementContext) {
|
|
2736
2889
|
const archived = await this.getArchived(ref);
|
|
2737
2890
|
if (archived === undefined)
|
|
2738
|
-
throw new Error(
|
|
2739
|
-
|
|
2740
|
-
await this.
|
|
2741
|
-
|
|
2891
|
+
throw new Error("Session not found");
|
|
2892
|
+
const active = this.activeForLookup({ id: archived.sessionId, cwd: archived.cwd }, managementContext);
|
|
2893
|
+
await this.runTreeExclusiveOperation([{ sessionId: archived.sessionId, ...(active === undefined ? {} : { session: active.runtime.session, runtime: active.runtime }) }], "Stop current session activity before restoring archived session", async () => {
|
|
2894
|
+
await this.closeActiveInScope(archived.sessionId, eventScopeFromManagementContext(managementContext));
|
|
2895
|
+
await this.archiveStore.restore(archived.sessionId);
|
|
2896
|
+
const restored = (await this.sessionManager.list(archived.cwd)).find((entry) => entry.id === archived.sessionId);
|
|
2897
|
+
this.workspaceActivity?.applySessionIntervention(archived.cwd, archived.sessionId, restored?.interventionRequired === true, eventScopeFromManagementContext(managementContext));
|
|
2898
|
+
await this.forgetUnreadSessions([archived], eventScopeFromManagementContext(managementContext));
|
|
2899
|
+
});
|
|
2742
2900
|
}
|
|
2743
2901
|
async deleteArchived(ref, managementContext) {
|
|
2744
2902
|
const record = await this.getArchived(ref);
|
|
@@ -2770,27 +2928,10 @@ export class PiSessionService {
|
|
|
2770
2928
|
}
|
|
2771
2929
|
planItems.push({ record });
|
|
2772
2930
|
}
|
|
2773
|
-
const
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
readyRecords.push(item.record);
|
|
2778
|
-
}
|
|
2779
|
-
catch (error) {
|
|
2780
|
-
failures.push({ sessionId: item.record.sessionId, error: errorMessage(error, this.t) });
|
|
2781
|
-
}
|
|
2782
|
-
}
|
|
2783
|
-
const deleteIds = readyRecords.map((record) => record.sessionId);
|
|
2784
|
-
let deletedSessionIds = [];
|
|
2785
|
-
try {
|
|
2786
|
-
deletedSessionIds = await this.archiveStoreDeleteArchivedMany(deleteIds);
|
|
2787
|
-
}
|
|
2788
|
-
catch (error) {
|
|
2789
|
-
for (const sessionId of deleteIds)
|
|
2790
|
-
failures.push({ sessionId, error: errorMessage(error, this.t) });
|
|
2791
|
-
}
|
|
2792
|
-
const deletedIdSet = new Set(deletedSessionIds);
|
|
2793
|
-
await this.forgetUnreadSessions(readyRecords.filter((record) => deletedIdSet.has(record.sessionId)), eventScopeFromManagementContext(managementContext));
|
|
2931
|
+
const execution = await this.executeDeleteArchivedBatch(planItems.map((item) => item.record), managementContext);
|
|
2932
|
+
failures.push(...execution.failures);
|
|
2933
|
+
failures.push(...execution.skippedBusySessionIds.map((sessionId) => ({ sessionId, error: this.t("session.stopBeforeDeleteArchive", "Stop current session activity before deleting archived session") })));
|
|
2934
|
+
const deletedSessionIds = execution.successes.map((record) => record.sessionId);
|
|
2794
2935
|
return {
|
|
2795
2936
|
deleted: true,
|
|
2796
2937
|
deletedSessionIds,
|
|
@@ -2860,11 +3001,11 @@ export class PiSessionService {
|
|
|
2860
3001
|
this.abortRunScopedExtensionDialogs(active.runtime.session);
|
|
2861
3002
|
try {
|
|
2862
3003
|
await this.abortSessionOperations(active.runtime.session);
|
|
2863
|
-
this.publishActivity(active.runtime.session,
|
|
3004
|
+
this.publishActivity(active.runtime.session, { kind: "stopped" }, "idle");
|
|
2864
3005
|
}
|
|
2865
3006
|
catch (error) {
|
|
2866
3007
|
const message = userFacingErrorMessage(error, this.t);
|
|
2867
|
-
this.publishActivity(active.runtime.session,
|
|
3008
|
+
this.publishActivity(active.runtime.session, { kind: "stopFailed" }, "error", message);
|
|
2868
3009
|
throw error;
|
|
2869
3010
|
}
|
|
2870
3011
|
finally {
|
|
@@ -3025,6 +3166,58 @@ export class PiSessionService {
|
|
|
3025
3166
|
const entries = await Promise.all(uniqueCwds.map(async (cwd) => [cwd, await this.sessionManager.list(cwd)]));
|
|
3026
3167
|
return new Map(entries);
|
|
3027
3168
|
}
|
|
3169
|
+
executeArchiveBatch(inputs, context) {
|
|
3170
|
+
return this.executeSessionLifecycleBatch(inputs, "archive", async (ready) => (await this.archiveStoreArchiveMany(ready)).map((record) => record.sessionId), context);
|
|
3171
|
+
}
|
|
3172
|
+
executeDeleteArchivedBatch(records, context) {
|
|
3173
|
+
return this.executeSessionLifecycleBatch(records, "delete", (ready) => this.archiveStoreDeleteArchivedMany(ready.map((record) => record.sessionId)), context);
|
|
3174
|
+
}
|
|
3175
|
+
async executeSessionLifecycleBatch(items, reason, persist, context) {
|
|
3176
|
+
const scope = eventScopeFromManagementContext(context);
|
|
3177
|
+
const result = { successes: [], failures: [], skippedBusySessionIds: [] };
|
|
3178
|
+
const targets = [];
|
|
3179
|
+
const idleItems = [];
|
|
3180
|
+
// Check and reserve synchronously before any teardown can yield. Identity
|
|
3181
|
+
// reservations also protect unloaded sessions for the full persistence span.
|
|
3182
|
+
for (const item of items) {
|
|
3183
|
+
const active = this.activeForLookup({ id: item.sessionId, cwd: item.cwd }, context);
|
|
3184
|
+
if (this.isTreeExclusiveSessionIdentityActive(item.sessionId)
|
|
3185
|
+
|| (active !== undefined && this.hasActiveWork(active.runtime.session))) {
|
|
3186
|
+
result.skippedBusySessionIds.push(item.sessionId);
|
|
3187
|
+
continue;
|
|
3188
|
+
}
|
|
3189
|
+
idleItems.push(item);
|
|
3190
|
+
targets.push({ sessionId: item.sessionId, ...(active === undefined ? {} : { session: active.runtime.session, runtime: active.runtime }) });
|
|
3191
|
+
}
|
|
3192
|
+
await this.runTreeExclusiveOperation(targets, "Stop current session activity before changing session lifecycle", async () => {
|
|
3193
|
+
const ready = [];
|
|
3194
|
+
for (const item of idleItems) {
|
|
3195
|
+
try {
|
|
3196
|
+
await this.closeActive(item.sessionId, { kind: "clear", reason }, scope);
|
|
3197
|
+
ready.push(item);
|
|
3198
|
+
}
|
|
3199
|
+
catch (error) {
|
|
3200
|
+
result.failures.push({ sessionId: item.sessionId, error: errorMessage(error) });
|
|
3201
|
+
}
|
|
3202
|
+
}
|
|
3203
|
+
try {
|
|
3204
|
+
const persistedIds = await persist(ready);
|
|
3205
|
+
const readyById = new Map(ready.map((item) => [item.sessionId, item]));
|
|
3206
|
+
result.successes = persistedIds.flatMap((sessionId) => {
|
|
3207
|
+
const item = readyById.get(sessionId);
|
|
3208
|
+
return item === undefined ? [] : [item];
|
|
3209
|
+
});
|
|
3210
|
+
}
|
|
3211
|
+
catch (error) {
|
|
3212
|
+
for (const item of ready)
|
|
3213
|
+
result.failures.push({ sessionId: item.sessionId, error: errorMessage(error) });
|
|
3214
|
+
}
|
|
3215
|
+
for (const item of result.successes)
|
|
3216
|
+
this.workspaceActivity?.removeSession(item.sessionId, item.cwd, scope);
|
|
3217
|
+
await this.forgetUnreadSessions(result.successes, scope);
|
|
3218
|
+
});
|
|
3219
|
+
return result;
|
|
3220
|
+
}
|
|
3028
3221
|
async archiveStoreArchiveMany(inputs) {
|
|
3029
3222
|
if (inputs.length === 0)
|
|
3030
3223
|
return [];
|
|
@@ -3048,6 +3241,9 @@ export class PiSessionService {
|
|
|
3048
3241
|
return [...sessionIds];
|
|
3049
3242
|
}
|
|
3050
3243
|
async cleanupPlan(request) {
|
|
3244
|
+
if (request.skipPinned === true && this.sessionPins === undefined)
|
|
3245
|
+
throw new Error("Authoritative session pin store is unavailable");
|
|
3246
|
+
const excludedPinnedSessionIds = request.skipPinned === true ? await this.sessionPins?.pinnedSessionIds() : undefined;
|
|
3051
3247
|
const [sessions, archivedRecords, scopedSessions] = await Promise.all([
|
|
3052
3248
|
this.sessionManager.listAll(),
|
|
3053
3249
|
this.archiveStore.list(),
|
|
@@ -3060,6 +3256,7 @@ export class PiSessionService {
|
|
|
3060
3256
|
archivedRecords,
|
|
3061
3257
|
activeSessions: this.cleanupActiveSessionStatuses(),
|
|
3062
3258
|
thresholds: request.thresholds,
|
|
3259
|
+
...(excludedPinnedSessionIds === undefined ? {} : { excludedPinnedSessionIds }),
|
|
3063
3260
|
...(request.projectCwds === undefined ? {} : { projectCwds: request.projectCwds }),
|
|
3064
3261
|
now: this.now(),
|
|
3065
3262
|
});
|
|
@@ -3191,6 +3388,10 @@ export class PiSessionService {
|
|
|
3191
3388
|
this.events.mediaIndex.forgetSession({ id: sessionId, cwd: active.runtime.session.sessionManager.getCwd(), eventScope: active.eventScope });
|
|
3192
3389
|
this.activities.delete(activeSessionKey(sessionId, active.eventScope));
|
|
3193
3390
|
this.workspaceActivity?.removeSession(sessionId, active.runtime.session.sessionManager.getCwd(), active.eventScope);
|
|
3391
|
+
const session = active.runtime.session;
|
|
3392
|
+
if (sessionFileExists(session.sessionFile) && this.interventionRequired(session)) {
|
|
3393
|
+
this.workspaceActivity?.applySessionIntervention(session.sessionManager.getCwd(), sessionId, true, active.eventScope);
|
|
3394
|
+
}
|
|
3194
3395
|
this.clearAuthLossWarningsForSession(sessionId);
|
|
3195
3396
|
this.clearCompactionPromptQueue(active.runtime.session);
|
|
3196
3397
|
// Disarm subsession notification before teardown so the abort below cannot
|
|
@@ -3445,7 +3646,7 @@ export class PiSessionService {
|
|
|
3445
3646
|
operation.error(message);
|
|
3446
3647
|
return;
|
|
3447
3648
|
}
|
|
3448
|
-
this.publishActivity(session,
|
|
3649
|
+
this.publishActivity(session, { kind: "extensionError" }, "error", message);
|
|
3449
3650
|
this.events.publish(session.sessionId, { type: "session.error", message }, owner.eventScope);
|
|
3450
3651
|
},
|
|
3451
3652
|
});
|
|
@@ -3501,7 +3702,7 @@ export class PiSessionService {
|
|
|
3501
3702
|
if (current !== undefined && this.isCurrentActiveSession(current)) {
|
|
3502
3703
|
const message = userFacingErrorMessage(error, this.t);
|
|
3503
3704
|
current.extensionRunner.getUIContext().notify(message, "error");
|
|
3504
|
-
this.publishActivity(current,
|
|
3705
|
+
this.publishActivity(current, { kind: "extensionCallbackFailed" }, "error", message);
|
|
3505
3706
|
this.events.publish(current.sessionId, { type: "session.error", message }, this.eventScopeForSession(current));
|
|
3506
3707
|
}
|
|
3507
3708
|
throw error;
|
|
@@ -3554,12 +3755,17 @@ export class PiSessionService {
|
|
|
3554
3755
|
}
|
|
3555
3756
|
this.reconcileRuntimeMessageCount(session);
|
|
3556
3757
|
this.restoreSubsessionReceipts(session);
|
|
3758
|
+
this.interventionStates.set(session, sessionInterventionRequired(session.sessionManager.getEntries?.() ?? session.sessionManager.getBranch()));
|
|
3759
|
+
this.publishedSessionNames.set(session, { sessionId: session.sessionId, name: session.sessionName });
|
|
3557
3760
|
const unsubscribe = session.subscribe((event) => {
|
|
3558
3761
|
const eventType = getString(event, "type");
|
|
3762
|
+
if (eventType === "session_info_changed")
|
|
3763
|
+
this.publishSessionName(session);
|
|
3559
3764
|
const message = getProperty(event, "message");
|
|
3560
3765
|
const entry = getProperty(event, "entry");
|
|
3561
3766
|
const inbox = this.subsessionInbox(session.sessionId, session.sessionFile, active.eventScope);
|
|
3562
3767
|
if (eventType === "agent_start") {
|
|
3768
|
+
this.setInterventionRequired(session, false);
|
|
3563
3769
|
this.restoreSubsessionReceipts(session, false);
|
|
3564
3770
|
this.subsessionStoppedParents.delete(session);
|
|
3565
3771
|
}
|
|
@@ -3574,6 +3780,8 @@ export class PiSessionService {
|
|
|
3574
3780
|
if (eventType === "agent_settled")
|
|
3575
3781
|
this.scheduleSubsessionDelivery(session);
|
|
3576
3782
|
const role = getString(message, "role");
|
|
3783
|
+
if (eventType === "message_end" && requestsHumanIntervention(message))
|
|
3784
|
+
this.setInterventionRequired(session, true);
|
|
3577
3785
|
if ((eventType === "message_end" && (role === "user" || role === "assistant" || role === "toolResult" || role === "system"))
|
|
3578
3786
|
|| (eventType === "entry_appended" && getString(entry, "type") === "message")) {
|
|
3579
3787
|
this.runtimeMessageCounts.set(session, this.runtimeMessageCount(session) + 1);
|
|
@@ -3630,18 +3838,21 @@ export class PiSessionService {
|
|
|
3630
3838
|
const aborted = getBoolean(event, "aborted") === true;
|
|
3631
3839
|
const errorMessage = getString(event, "errorMessage");
|
|
3632
3840
|
const automatic = getString(event, "reason") !== "manual";
|
|
3633
|
-
const
|
|
3634
|
-
?
|
|
3635
|
-
: errorMessage === undefined ? undefined :
|
|
3841
|
+
const presentation = aborted
|
|
3842
|
+
? { kind: automatic ? "automaticCompactionCancelled" : "compactionCancelled" }
|
|
3843
|
+
: errorMessage === undefined ? undefined : { kind: "compactionFailed" };
|
|
3844
|
+
const message = presentation === undefined ? undefined : sessionNotificationSources[presentation.kind];
|
|
3636
3845
|
if (!aborted && errorMessage !== undefined) {
|
|
3637
3846
|
this.events.publish(session.sessionId, { type: "session.diagnostic", message: errorMessage }, this.eventScopeForSession(session));
|
|
3638
3847
|
}
|
|
3639
|
-
this.publishActivity(session, aborted
|
|
3848
|
+
this.publishActivity(session, aborted
|
|
3849
|
+
? { kind: "compactionCancelled", detailKind: automatic ? "automaticCompactionCancelled" : "compactionCancelled" }
|
|
3850
|
+
: errorMessage === undefined ? { kind: "compactionComplete" } : { kind: "compactionFailed", detailKind: "compactionFailed" }, !aborted && errorMessage !== undefined ? "error" : "idle", message);
|
|
3640
3851
|
// Successful compaction already has a canonical summary in the transcript.
|
|
3641
3852
|
// Keep cancellation/failure feedback in the refresh-safe session inbox only.
|
|
3642
3853
|
const generation = this.notificationGenerationBySession.get(session);
|
|
3643
3854
|
if (message !== undefined && generation !== undefined) {
|
|
3644
|
-
this.publishNotificationMutations(this.notificationsForSession(session).addNotification(generation, message, aborted ? "info" : "error").mutations);
|
|
3855
|
+
this.publishNotificationMutations(this.notificationsForSession(session).addNotification(generation, message, aborted ? "info" : "error", presentation).mutations);
|
|
3645
3856
|
}
|
|
3646
3857
|
}
|
|
3647
3858
|
scheduleCompactionQueueDrain(session, delayMs = 0) {
|
|
@@ -3719,43 +3930,6 @@ export class PiSessionService {
|
|
|
3719
3930
|
clearTimeout(timer);
|
|
3720
3931
|
this.compactionDrainTimers.clear();
|
|
3721
3932
|
}
|
|
3722
|
-
maybeGenerateSessionName(session, firstMessage) {
|
|
3723
|
-
if (session.sessionName !== undefined || session.messages.length !== 0 || session.isStreaming || session.isCompacting)
|
|
3724
|
-
return;
|
|
3725
|
-
void this.generateSessionName(session, firstMessage).then((name) => {
|
|
3726
|
-
if (name === undefined)
|
|
3727
|
-
this.logger.info({ sessionId: session.sessionId }, "Session naming returned no title; using the first-message fallback");
|
|
3728
|
-
this.applyGeneratedSessionName(session, name ?? fallbackSessionName(firstMessage));
|
|
3729
|
-
}).catch((error) => {
|
|
3730
|
-
const errorCategory = error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError") ? "timeout" : "generation";
|
|
3731
|
-
this.logger.info({ sessionId: session.sessionId, errorCategory }, "Session naming failed; using the first-message fallback");
|
|
3732
|
-
this.applyGeneratedSessionName(session, fallbackSessionName(firstMessage));
|
|
3733
|
-
});
|
|
3734
|
-
}
|
|
3735
|
-
async generateSessionName(session, firstMessage) {
|
|
3736
|
-
// One request keeps its settings even if the operator edits the config while it runs.
|
|
3737
|
-
const naming = this.config === undefined ? {} : (await this.config.read()).effectiveConfig.sessionNaming ?? {};
|
|
3738
|
-
let model = session.model;
|
|
3739
|
-
if (naming.model !== undefined) {
|
|
3740
|
-
const parsed = parseModelSpec(naming.model);
|
|
3741
|
-
model = parsed === undefined ? undefined : session.modelRuntime.getModel(parsed.provider, parsed.modelId);
|
|
3742
|
-
if (model === undefined)
|
|
3743
|
-
throw new Error("Configured session naming model is unavailable");
|
|
3744
|
-
}
|
|
3745
|
-
if (model === undefined)
|
|
3746
|
-
return undefined;
|
|
3747
|
-
return generateShortSessionName(session.agent.streamFunction, model, firstMessage, naming);
|
|
3748
|
-
}
|
|
3749
|
-
applyGeneratedSessionName(session, name) {
|
|
3750
|
-
if (name === undefined || session.sessionName !== undefined)
|
|
3751
|
-
return;
|
|
3752
|
-
if (this.treeNavigations.has(session)) {
|
|
3753
|
-
this.deferredGeneratedSessionNames.set(session, name);
|
|
3754
|
-
return;
|
|
3755
|
-
}
|
|
3756
|
-
session.setSessionName(name);
|
|
3757
|
-
this.publishSessionName(session);
|
|
3758
|
-
}
|
|
3759
3933
|
applyAuthChange(change) {
|
|
3760
3934
|
const changedRuntime = change.modelRuntime;
|
|
3761
3935
|
for (const active of this.active.values()) {
|
|
@@ -3786,7 +3960,8 @@ export class PiSessionService {
|
|
|
3786
3960
|
this.events.publish(session.sessionId, {
|
|
3787
3961
|
type: "command.output",
|
|
3788
3962
|
level: "error",
|
|
3789
|
-
message:
|
|
3963
|
+
message: `Authentication for ${model.provider}/${model.id} was removed. Use /model to select another model.`,
|
|
3964
|
+
presentation: { kind: "modelAuthRemoved", provider: model.provider, model: model.id },
|
|
3790
3965
|
}, eventScope);
|
|
3791
3966
|
}
|
|
3792
3967
|
clearAuthLossWarningsForSession(sessionId) {
|
|
@@ -3796,6 +3971,10 @@ export class PiSessionService {
|
|
|
3796
3971
|
}
|
|
3797
3972
|
}
|
|
3798
3973
|
publishSessionName(session) {
|
|
3974
|
+
const previous = this.publishedSessionNames.get(session);
|
|
3975
|
+
if (previous?.sessionId === session.sessionId && previous.name === session.sessionName)
|
|
3976
|
+
return;
|
|
3977
|
+
this.publishedSessionNames.set(session, { sessionId: session.sessionId, name: session.sessionName });
|
|
3799
3978
|
const event = session.sessionName === undefined
|
|
3800
3979
|
? { type: "session.name", sessionId: session.sessionId }
|
|
3801
3980
|
: { type: "session.name", sessionId: session.sessionId, name: session.sessionName };
|
|
@@ -3819,25 +3998,25 @@ export class PiSessionService {
|
|
|
3819
3998
|
}
|
|
3820
3999
|
this.publishStatus(session);
|
|
3821
4000
|
if (activity?.phase === "active")
|
|
3822
|
-
this.publishActivity(session, activity.
|
|
4001
|
+
this.publishActivity(session, activity.runtimePresentation, "active", activity.detail);
|
|
3823
4002
|
else
|
|
3824
|
-
this.publishActivity(session, this.
|
|
4003
|
+
this.publishActivity(session, this.activityPresentationFromStatus(session), "active");
|
|
3825
4004
|
}
|
|
3826
4005
|
}
|
|
3827
|
-
|
|
4006
|
+
activityPresentationFromStatus(session) {
|
|
3828
4007
|
if (this.treeNavigations.has(session))
|
|
3829
|
-
return
|
|
4008
|
+
return { kind: "navigatingTree" };
|
|
3830
4009
|
if (this.isSessionEntryMutationActive(session))
|
|
3831
|
-
return
|
|
4010
|
+
return { kind: "updatingSession" };
|
|
3832
4011
|
if (session.isCompacting)
|
|
3833
|
-
return
|
|
4012
|
+
return { kind: "compacting" };
|
|
3834
4013
|
if (session.isBashRunning)
|
|
3835
|
-
return
|
|
4014
|
+
return { kind: "runningBash" };
|
|
3836
4015
|
if (session.isStreaming)
|
|
3837
|
-
return
|
|
4016
|
+
return { kind: "agentRunning" };
|
|
3838
4017
|
if (this.pendingMessageCount(session) > 0)
|
|
3839
|
-
return
|
|
3840
|
-
return
|
|
4018
|
+
return { kind: "queued" };
|
|
4019
|
+
return { kind: "active" };
|
|
3841
4020
|
}
|
|
3842
4021
|
hasActiveWork(session) {
|
|
3843
4022
|
const execution = this.extensionCommandExecution.getStore();
|
|
@@ -3942,56 +4121,56 @@ export class PiSessionService {
|
|
|
3942
4121
|
if (eventType === undefined)
|
|
3943
4122
|
return;
|
|
3944
4123
|
if (eventType === "agent_start") {
|
|
3945
|
-
this.publishActivity(session,
|
|
4124
|
+
this.publishActivity(session, { kind: "agentRunning" }, "active");
|
|
3946
4125
|
return;
|
|
3947
4126
|
}
|
|
3948
4127
|
if (eventType === "agent_end") {
|
|
3949
|
-
this.publishActivity(session,
|
|
4128
|
+
this.publishActivity(session, { kind: "idle" }, "idle");
|
|
3950
4129
|
const eventScope = this.eventScopeForSession(session);
|
|
3951
4130
|
const sessionKey = activeSessionKey(session.sessionId, eventScope);
|
|
3952
4131
|
this.activities.scheduleSettledRefresh(sessionKey, () => {
|
|
3953
4132
|
if (this.active.get(sessionKey)?.runtime.session !== session)
|
|
3954
4133
|
return;
|
|
3955
|
-
this.publishActivity(session,
|
|
4134
|
+
this.publishActivity(session, { kind: "idle" }, "idle");
|
|
3956
4135
|
this.publishStatus(session);
|
|
3957
4136
|
}, 250);
|
|
3958
4137
|
return;
|
|
3959
4138
|
}
|
|
3960
4139
|
if (eventType === "turn_end") {
|
|
3961
|
-
this.publishActivity(session,
|
|
4140
|
+
this.publishActivity(session, { kind: "turnComplete" }, "idle");
|
|
3962
4141
|
return;
|
|
3963
4142
|
}
|
|
3964
4143
|
if (eventType === "message_start") {
|
|
3965
|
-
this.publishActivity(session,
|
|
4144
|
+
this.publishActivity(session, { kind: "messageStarted" }, "active");
|
|
3966
4145
|
return;
|
|
3967
4146
|
}
|
|
3968
4147
|
if (eventType === "message_end") {
|
|
3969
|
-
this.publishActivity(session,
|
|
4148
|
+
this.publishActivity(session, { kind: "messageComplete" }, "idle");
|
|
3970
4149
|
return;
|
|
3971
4150
|
}
|
|
3972
4151
|
if (eventType === "message_update") {
|
|
3973
|
-
this.publishActivity(session,
|
|
4152
|
+
this.publishActivity(session, { kind: "receivingResponse" }, "active");
|
|
3974
4153
|
return;
|
|
3975
4154
|
}
|
|
3976
4155
|
if (eventType === "tool_execution_start") {
|
|
3977
|
-
this.publishActivity(session,
|
|
4156
|
+
this.publishActivity(session, { kind: "runningTool" }, "active", getString(event, "toolName"));
|
|
3978
4157
|
return;
|
|
3979
4158
|
}
|
|
3980
4159
|
if (eventType === "tool_execution_end") {
|
|
3981
4160
|
const isError = getBoolean(event, "isError") === true;
|
|
3982
|
-
this.publishActivity(session, isError ?
|
|
4161
|
+
this.publishActivity(session, isError ? { kind: "toolFailed" } : { kind: "toolComplete" }, isError ? "error" : "idle", getString(event, "toolName"));
|
|
3983
4162
|
return;
|
|
3984
4163
|
}
|
|
3985
4164
|
if (eventType === "bash_execution_start") {
|
|
3986
|
-
this.publishActivity(session,
|
|
4165
|
+
this.publishActivity(session, { kind: "runningBash" }, "active");
|
|
3987
4166
|
return;
|
|
3988
4167
|
}
|
|
3989
4168
|
if (eventType === "bash_execution_end") {
|
|
3990
|
-
this.publishActivity(session,
|
|
4169
|
+
this.publishActivity(session, { kind: "bashComplete" }, "idle");
|
|
3991
4170
|
return;
|
|
3992
4171
|
}
|
|
3993
4172
|
if (this.hasActiveWork(session))
|
|
3994
|
-
this.publishActivity(session,
|
|
4173
|
+
this.publishActivity(session, { kind: "event", value: eventType }, "active");
|
|
3995
4174
|
}
|
|
3996
4175
|
auditToolExecutionEvent(active, event) {
|
|
3997
4176
|
const eventType = getString(event, "type");
|
|
@@ -4088,23 +4267,23 @@ export class PiSessionService {
|
|
|
4088
4267
|
const sessionId = sessionManager.getSessionId();
|
|
4089
4268
|
if (sessionId === "")
|
|
4090
4269
|
return { report: noop, end: noop };
|
|
4091
|
-
const label = intent === "create" ?
|
|
4270
|
+
const label = intent === "create" ? "Creating session" : "Opening session";
|
|
4092
4271
|
return {
|
|
4093
|
-
report: (
|
|
4272
|
+
report: (stage) => {
|
|
4273
|
+
const catalogRefreshing = this.catalogRefreshStatus?.isRefreshInFlight() === true;
|
|
4274
|
+
const phase = stage === "runtime" ? STARTUP_PHASE_RUNTIME : STARTUP_PHASE_EXTENSIONS;
|
|
4275
|
+
const detail = catalogRefreshing ? `${phase} · ${STARTUP_CONCURRENT_CATALOG_REFRESH}` : phase;
|
|
4276
|
+
this.publishStartupProgress(sessionId, startupToken, label, "active", detail, eventScope, { intent, stage, catalogRefreshing });
|
|
4277
|
+
},
|
|
4094
4278
|
end: () => {
|
|
4095
4279
|
// A real activity published during the window (an extension error, say)
|
|
4096
4280
|
// is the truth about this session and must survive the clear.
|
|
4097
4281
|
if (this.activities.get(activeSessionKey(sessionId, eventScope)) !== undefined)
|
|
4098
4282
|
return;
|
|
4099
|
-
this.publishStartupProgress(sessionId, startupToken,
|
|
4283
|
+
this.publishStartupProgress(sessionId, startupToken, "Idle", "idle", undefined, eventScope);
|
|
4100
4284
|
},
|
|
4101
4285
|
};
|
|
4102
4286
|
}
|
|
4103
|
-
startupDetail(phase) {
|
|
4104
|
-
return this.catalogRefreshStatus?.isRefreshInFlight() === true
|
|
4105
|
-
? `${phase} · ${this.t("startup.catalogRefresh", "Provider model catalog is refreshing")}`
|
|
4106
|
-
: phase;
|
|
4107
|
-
}
|
|
4108
4287
|
/**
|
|
4109
4288
|
* Report startup progress on the global channel only, echoing the caller's
|
|
4110
4289
|
* correlation token so a waiting browser row recognises its own construction.
|
|
@@ -4118,17 +4297,21 @@ export class PiSessionService {
|
|
|
4118
4297
|
* that sets the marker, and because it writes no `activities` entry no later
|
|
4119
4298
|
* heartbeat re-publication can carry it.
|
|
4120
4299
|
*/
|
|
4121
|
-
publishStartupProgress(sessionId, startupToken, label, phase, detail, eventScope) {
|
|
4300
|
+
publishStartupProgress(sessionId, startupToken, label, phase, detail, eventScope, startupPresentation) {
|
|
4122
4301
|
const at = new Date().toISOString();
|
|
4123
|
-
const activity =
|
|
4302
|
+
const activity = { sessionId, phase, label, at, startup: true,
|
|
4303
|
+
...(detail === undefined ? {} : { detail }),
|
|
4304
|
+
...(startupPresentation === undefined ? {} : { startupPresentation }),
|
|
4305
|
+
};
|
|
4124
4306
|
this.events.publishGlobal(startupToken === undefined ? { type: "session.startup", activity } : { type: "session.startup", startupToken, activity }, eventScope);
|
|
4125
4307
|
}
|
|
4126
|
-
publishActivity(session,
|
|
4308
|
+
publishActivity(session, runtimePresentation, phase, detail) {
|
|
4127
4309
|
const at = new Date().toISOString();
|
|
4128
|
-
const
|
|
4310
|
+
const label = runtimeActivityFallbackLabel(runtimePresentation);
|
|
4311
|
+
const stored = { phase, label, at, runtimePresentation, ...(detail === undefined ? {} : { detail }) };
|
|
4129
4312
|
const eventScope = this.eventScopeForSession(session);
|
|
4130
4313
|
this.activities.set(activeSessionKey(session.sessionId, eventScope), stored);
|
|
4131
|
-
const activity =
|
|
4314
|
+
const activity = { sessionId: session.sessionId, ...stored };
|
|
4132
4315
|
this.workspaceActivity?.applySessionActivity(session.sessionManager.getCwd(), activity, eventScope);
|
|
4133
4316
|
this.events.publish(session.sessionId, { type: "activity.update", activity }, eventScope);
|
|
4134
4317
|
this.events.publishGlobal({ type: "activity.update", activity }, eventScope);
|
|
@@ -4153,6 +4336,26 @@ export class PiSessionService {
|
|
|
4153
4336
|
if (path !== undefined)
|
|
4154
4337
|
this.managementMediaFiles.add(path);
|
|
4155
4338
|
}
|
|
4339
|
+
interventionRequired(session) {
|
|
4340
|
+
return this.interventionStates.get(session)
|
|
4341
|
+
?? sessionInterventionRequired(session.sessionManager.getEntries?.() ?? session.sessionManager.getBranch());
|
|
4342
|
+
}
|
|
4343
|
+
setInterventionRequired(session, required) {
|
|
4344
|
+
const previous = this.interventionRequired(session);
|
|
4345
|
+
if (previous === required)
|
|
4346
|
+
return;
|
|
4347
|
+
if (session.sessionManager.appendCustomEntry === undefined)
|
|
4348
|
+
throw new Error("Session manager cannot persist intervention state");
|
|
4349
|
+
// Update before append: the SDK emits entry_appended synchronously.
|
|
4350
|
+
this.interventionStates.set(session, required);
|
|
4351
|
+
try {
|
|
4352
|
+
session.sessionManager.appendCustomEntry(SESSION_INTERVENTION_CUSTOM_TYPE, { version: 1, required });
|
|
4353
|
+
}
|
|
4354
|
+
catch (error) {
|
|
4355
|
+
this.interventionStates.set(session, previous);
|
|
4356
|
+
throw error;
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4156
4359
|
publishStatus(session) {
|
|
4157
4360
|
this.rememberManagementMediaFile(session, this.eventScopeForSession(session));
|
|
4158
4361
|
void this.refreshActivityMarker(session);
|
|
@@ -4170,7 +4373,7 @@ export class PiSessionService {
|
|
|
4170
4373
|
if (current?.phase !== "active" || this.hasActiveWork(session))
|
|
4171
4374
|
return;
|
|
4172
4375
|
const at = new Date().toISOString();
|
|
4173
|
-
const stored = { phase: "idle", label:
|
|
4376
|
+
const stored = { phase: "idle", label: "idle", at, runtimePresentation: { kind: "idle" } };
|
|
4174
4377
|
this.activities.set(activeSessionKey(session.sessionId, eventScope), stored);
|
|
4175
4378
|
const activity = { sessionId: session.sessionId, ...stored };
|
|
4176
4379
|
this.events.publish(session.sessionId, { type: "activity.update", activity }, eventScope);
|
|
@@ -4241,6 +4444,7 @@ export class PiSessionService {
|
|
|
4241
4444
|
sessionId: session.sessionId,
|
|
4242
4445
|
persisted: sessionFileExists(session.sessionFile),
|
|
4243
4446
|
recentlyActiveElsewhere: this.eventScopeForSession(session) === NORMAL_SESSION_EVENT_SCOPE && this.activityMarker.isActiveElsewhere(session.sessionFile),
|
|
4447
|
+
interventionRequired: this.interventionRequired(session) || pendingDialogs.length > 0,
|
|
4244
4448
|
...(model === undefined ? {} : { model }),
|
|
4245
4449
|
thinkingLevel: session.thinkingLevel,
|
|
4246
4450
|
isStreaming: session.isStreaming,
|
|
@@ -4322,8 +4526,22 @@ export class PiSessionService {
|
|
|
4322
4526
|
return this.unreadForScope(eventScope).durableCatalogSnapshot();
|
|
4323
4527
|
}
|
|
4324
4528
|
async reconcileUnreadWorkspaces(cwds) {
|
|
4529
|
+
this.unreadEligibilityRevision += 1;
|
|
4325
4530
|
await this.publishUnreadMutations(this.unreadStore.reconcileWorkspaces(cwds));
|
|
4326
4531
|
}
|
|
4532
|
+
async markUnread(sessionId, cwd, context) {
|
|
4533
|
+
const canonicalCwd = canonicalizeStoredCwd(cwd);
|
|
4534
|
+
const eligibilityRevision = this.unreadEligibilityRevision;
|
|
4535
|
+
const rows = await this.list(canonicalCwd, context);
|
|
4536
|
+
const row = rows.find((candidate) => candidate.id === sessionId && cwdPathsEqual(candidate.cwd, canonicalCwd));
|
|
4537
|
+
if (eligibilityRevision !== this.unreadEligibilityRevision
|
|
4538
|
+
|| row === undefined || row.archived === true || row.persisted !== true || row.agentSubsession === true) {
|
|
4539
|
+
throw new Error("Session is not eligible to be marked unread");
|
|
4540
|
+
}
|
|
4541
|
+
const store = this.unreadForScope(eventScopeFromManagementContext(context));
|
|
4542
|
+
await this.publishUnreadMutations(store.markUnread(sessionId, canonicalCwd));
|
|
4543
|
+
return store.durableCatalogSnapshot();
|
|
4544
|
+
}
|
|
4327
4545
|
async acknowledgeUnread(sessionId, request, context) {
|
|
4328
4546
|
const store = this.unreadForScope(eventScopeFromManagementContext(context));
|
|
4329
4547
|
const result = store.acknowledge(sessionId, {
|
|
@@ -4353,7 +4571,7 @@ export class PiSessionService {
|
|
|
4353
4571
|
if (this.hasActiveWork(session))
|
|
4354
4572
|
throw new Error(this.t("session.stopBeforeReload", "Stop current session activity before reloading"));
|
|
4355
4573
|
await this.runTreeExclusiveOperation([{ sessionId: session.sessionId, session }], this.t("session.stopBeforeReload", "Stop current session activity before reloading"), async () => {
|
|
4356
|
-
this.publishActivity(session,
|
|
4574
|
+
this.publishActivity(session, { kind: "reloading" }, "active");
|
|
4357
4575
|
const priorGeneration = this.notificationGenerationBySession.get(session);
|
|
4358
4576
|
let candidateGeneration;
|
|
4359
4577
|
const reloadBoundary = { beforeSessionStart: false };
|
|
@@ -4373,7 +4591,7 @@ export class PiSessionService {
|
|
|
4373
4591
|
if (candidateGeneration !== undefined) {
|
|
4374
4592
|
this.publishNotificationMutations(this.notificationsForSession(session).commitReplacement(candidateGeneration));
|
|
4375
4593
|
}
|
|
4376
|
-
this.publishActivity(session,
|
|
4594
|
+
this.publishActivity(session, { kind: "reloaded" }, "idle");
|
|
4377
4595
|
this.publishStatus(session);
|
|
4378
4596
|
}
|
|
4379
4597
|
catch (error) {
|
|
@@ -4384,7 +4602,7 @@ export class PiSessionService {
|
|
|
4384
4602
|
this.notificationGenerationBySession.set(session, candidateGeneration);
|
|
4385
4603
|
}
|
|
4386
4604
|
const message = error instanceof Error ? error.message : String(error);
|
|
4387
|
-
this.publishActivity(session,
|
|
4605
|
+
this.publishActivity(session, { kind: "reloadFailed" }, "error", message);
|
|
4388
4606
|
this.events.publish(session.sessionId, { type: "session.error", message }, this.eventScopeForSession(session));
|
|
4389
4607
|
this.publishStatus(session);
|
|
4390
4608
|
throw error;
|
|
@@ -4404,7 +4622,7 @@ export class PiSessionService {
|
|
|
4404
4622
|
return [...this.active.values()].some((active) => active.runtime.session === session);
|
|
4405
4623
|
}
|
|
4406
4624
|
async createSessionRuntime(sessionManager, cwd, options, startup) {
|
|
4407
|
-
startup.report(
|
|
4625
|
+
startup.report("runtime");
|
|
4408
4626
|
options.startupSignal?.throwIfAborted();
|
|
4409
4627
|
// Ordinary local sessions (undefined provenance) keep the current rule.
|
|
4410
4628
|
// Only an explicit host one-shot forces delegation off; do not treat every
|
|
@@ -4471,7 +4689,7 @@ export class PiSessionService {
|
|
|
4471
4689
|
await this.recoverSubsessionTrackingForOpenedSession(runtime.session);
|
|
4472
4690
|
}
|
|
4473
4691
|
startupSignal?.throwIfAborted();
|
|
4474
|
-
startup.report(
|
|
4692
|
+
startup.report("extensions");
|
|
4475
4693
|
// Startup hooks emit through the same scoped stream as hosted turns.
|
|
4476
4694
|
this.bindRuntime(active);
|
|
4477
4695
|
await this.bindSessionExtensions(runtime.session, notificationGeneration, active, startupSignal);
|
|
@@ -4626,12 +4844,15 @@ export class PiSessionService {
|
|
|
4626
4844
|
const nextCwd = canonicalizeStoredCwd(next.sessionManager.getCwd());
|
|
4627
4845
|
if (previous.sessionId === next.sessionId && cwdPathsEqual(previousCwd, nextCwd))
|
|
4628
4846
|
return;
|
|
4847
|
+
this.unreadEligibilityRevision += 1;
|
|
4629
4848
|
await this.publishUnreadMutations(store.forgetSession(previous.sessionId, previousCwd));
|
|
4630
4849
|
}
|
|
4631
4850
|
forgetUnreadActivity(session) {
|
|
4632
4851
|
this.unreadForScope(this.eventScopeForSession(session)).forgetActivity(session.sessionId, canonicalizeStoredCwd(session.sessionManager.getCwd()));
|
|
4633
4852
|
}
|
|
4634
4853
|
async forgetUnreadSessions(identities, scope = NORMAL_SESSION_EVENT_SCOPE) {
|
|
4854
|
+
if (identities.length > 0)
|
|
4855
|
+
this.unreadEligibilityRevision += 1;
|
|
4635
4856
|
const mutations = [];
|
|
4636
4857
|
for (const identity of identities) {
|
|
4637
4858
|
mutations.push(...this.unreadForScope(scope).forgetSession(identity.sessionId, canonicalizeStoredCwd(identity.cwd)));
|
|
@@ -4735,16 +4956,6 @@ export class PiSessionService {
|
|
|
4735
4956
|
this.unreadPublicationRetryDelayMs = this.unreadPublicationRetryInitialMs;
|
|
4736
4957
|
}
|
|
4737
4958
|
flushDeferredTreeNavigationWork(session) {
|
|
4738
|
-
const generatedName = this.deferredGeneratedSessionNames.get(session);
|
|
4739
|
-
this.deferredGeneratedSessionNames.delete(session);
|
|
4740
|
-
if (generatedName !== undefined) {
|
|
4741
|
-
try {
|
|
4742
|
-
this.applyGeneratedSessionName(session, generatedName);
|
|
4743
|
-
}
|
|
4744
|
-
catch (error) {
|
|
4745
|
-
this.logger.info({ sessionId: session.sessionId, error: error instanceof Error ? error.message : String(error) }, "failed to apply deferred session name");
|
|
4746
|
-
}
|
|
4747
|
-
}
|
|
4748
4959
|
this.restoreSubsessionReceipts(session);
|
|
4749
4960
|
this.scheduleSubsessionDelivery(session);
|
|
4750
4961
|
}
|
|
@@ -4883,8 +5094,8 @@ export class PiSessionService {
|
|
|
4883
5094
|
}, 0);
|
|
4884
5095
|
}
|
|
4885
5096
|
assertMcpModeAllowed(managementContext) {
|
|
4886
|
-
if (VERSION !== "1.3.0")
|
|
4887
|
-
throw new UserFacingError("mcpAuth.sdkUnsupported", "Dedicated MCP authentication requires Pi 1.3.0");
|
|
5097
|
+
if (VERSION !== "1.3.0" && VERSION !== "1.4.0")
|
|
5098
|
+
throw new UserFacingError("mcpAuth.sdkUnsupported", "Dedicated MCP authentication requires Pi 1.3.0 or 1.4.0");
|
|
4888
5099
|
if (managementContext !== undefined && !managementUsesNormalPermissions(managementContext, { allowPrivileged: this.managementAllowPrivileged })) {
|
|
4889
5100
|
throw new UserFacingError("mcpAuth.restrictedManagement", "MCP authentication is unavailable in restricted management mode");
|
|
4890
5101
|
}
|
|
@@ -5034,6 +5245,7 @@ function previewResponseFromPlan(plan) {
|
|
|
5034
5245
|
projects: plan.projects,
|
|
5035
5246
|
totals: plan.totals,
|
|
5036
5247
|
...(plan.skippedBusySessionIds.length === 0 ? {} : { skippedBusySessionIds: plan.skippedBusySessionIds }),
|
|
5248
|
+
...(plan.skippedPinnedSessionIds === undefined ? {} : { skippedPinnedSessionIds: plan.skippedPinnedSessionIds }),
|
|
5037
5249
|
};
|
|
5038
5250
|
}
|
|
5039
5251
|
function uniqueBulkSessionRefs(refs) {
|
|
@@ -5121,6 +5333,7 @@ function clientSessionFromListEntry(session) {
|
|
|
5121
5333
|
modified: session.modified.toISOString(),
|
|
5122
5334
|
messageCount: session.messageCount,
|
|
5123
5335
|
firstMessage: clientSessionFirstMessagePreview(session.firstMessage),
|
|
5336
|
+
...(session.interventionRequired === true ? { interventionRequired: true } : {}),
|
|
5124
5337
|
...(session.parentSessionPath === undefined ? {} : { parentSessionPath: session.parentSessionPath }),
|
|
5125
5338
|
};
|
|
5126
5339
|
}
|
|
@@ -5252,11 +5465,6 @@ function sessionFileExists(sessionFile) {
|
|
|
5252
5465
|
return false;
|
|
5253
5466
|
}
|
|
5254
5467
|
}
|
|
5255
|
-
function sessionPinScope(cwd, managementContext) {
|
|
5256
|
-
return managementContext === undefined
|
|
5257
|
-
? { mode: "normal", cwd }
|
|
5258
|
-
: { mode: "management", rootUserId: managementContext.user.rootUserId, userId: managementContext.user.id, cwd };
|
|
5259
|
-
}
|
|
5260
5468
|
async function readArchivedSessionText(path) {
|
|
5261
5469
|
try {
|
|
5262
5470
|
return await readFile(path, "utf8");
|