@chainingintention/pi-web-cn 2.202610.4 → 2.202611.1
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-D9e-Nrxi.js +3952 -0
- package/dist/client/assets/SettingsDialog-BvlvoXvD.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-Bawe0tSn.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-0z4D-18M.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-DDgPZEYp.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-ZZOwUcbr.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/relayDiscovery.js +5 -1
- 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/README.md +2 -0
- package/dist/pi-web-plugins/custom-ui-codex/chat-settings.css +15 -2
- 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 +256 -242
- 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 +75 -46
- package/dist/pi-web-plugins/workspace-tasks/workspaceTasksClient.js +7 -33
- package/dist/pi-web-plugins/zh-cn/bundled.json +31 -18
- package/dist/pi-web-plugins/zh-cn/catalogs.json +1803 -0
- package/dist/pi-web-plugins/zh-cn/components.json +2 -0
- package/dist/pi-web-plugins/zh-cn/files.json +7 -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-main.json +4 -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 +202 -8
- 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 +48 -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/managementAgents.js +179 -0
- package/dist/server/managementAgents.js.map +1 -0
- package/dist/server/managementAgentsRoutes.js +42 -0
- package/dist/server/managementAgentsRoutes.js.map +1 -0
- package/dist/server/managementEmbed.js +27 -44
- 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 +20 -1
- 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 +55 -11
- 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 +46 -15
- 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 +500 -259
- 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 -1
- 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 +11 -0
- package/dist/server/storage/navigationPreferenceStore.js.map +1 -1
- package/dist/server/storage/sessionPinStore.js +95 -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/workspaceExplorerRoutes.js +3 -1
- package/dist/server/workspaceExplorerRoutes.js.map +1 -1
- 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 +4 -0
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +6 -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 +13 -1
- 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/managedAgents.js +2 -0
- package/dist/shared/managedAgents.js.map +1 -0
- 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 +49 -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 +196 -56
- package/docs/plugins.md +370 -26
- package/docs/scheduled-tasks.md +127 -0
- package/package.json +43 -19
- package/dist/client/assets/CommandPicker-gK2biReF.js +0 -70
- package/dist/client/assets/PiWebApp-Do_8tp5d.js +0 -3761
- package/dist/client/assets/SettingsDialog-vGDo1-BJ.js +0 -1015
- package/dist/client/assets/index-Ura0RJyr.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/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,6 +1,11 @@
|
|
|
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";
|
|
@@ -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";
|
|
@@ -37,16 +42,18 @@ import { resolveWebProjectTrusted } from "./projectTrust.js";
|
|
|
37
42
|
import { createPiSessionManagerGateway } from "./piSessionManagerGateway.js";
|
|
38
43
|
import { SessionPinStore } from "./sessionPinStore.js";
|
|
39
44
|
import { SessionActivityCoordinator } from "./sessionActivityCoordinator.js";
|
|
40
|
-
import { searchSessionContent } from "./sessionContentSearch.js";
|
|
45
|
+
import { compileSessionContentQuery, searchSessionContent } from "./sessionContentSearch.js";
|
|
41
46
|
import { createLocalOnlyModelRuntime, modelRuntimeAuthPath } from "./authService.js";
|
|
42
47
|
import { canonicalizeStoredCwd, cwdPathsEqual } from "../workingDirectory.js";
|
|
43
48
|
import { clearSessionFileParent, readSessionHeaderSummary } from "./sessionFileHeader.js";
|
|
44
|
-
import { isManagedAgentsFile, workbenchAccessHandle } from "../managementEmbed.js";
|
|
49
|
+
import { assertManagedCwd, isManagedAgentsFile, workbenchAccessHandle } from "../managementEmbed.js";
|
|
45
50
|
import { managementPrivilegeRequested, managementPrivileges, managementUsesNormalPermissions } from "../managementPrivileges.js";
|
|
46
51
|
import { DEFAULT_EXTENSION_DIALOGS_TIMEOUT_MS, piWebDataDir } from "../../config.js";
|
|
47
52
|
import { createScopedSettingsManager, resolveSettingsScopeDirectory } from "./projectSettingsScope.js";
|
|
48
53
|
import { parseSessionDefaults, parseSessionDefaultsUpdate } from "../../shared/sessionDefaults.js";
|
|
49
54
|
import { createAskUserToolDefinition } from "./askUserTool.js";
|
|
55
|
+
import { createRequestHumanInterventionToolDefinition } from "./requestHumanInterventionTool.js";
|
|
56
|
+
import { requestsHumanIntervention, SESSION_INTERVENTION_CUSTOM_TYPE, sessionInterventionRequired } from "./sessionIntervention.js";
|
|
50
57
|
import { createAskUserOutcome, renderAskUserAnswersText, resolveAskUserRequest } from "./askUserDomain.js";
|
|
51
58
|
import { createSubsessionCompletionDelivery } from "./subsessionCompletionDelivery.js";
|
|
52
59
|
import { completionReceiptIds, persistedSubsessionCompletions, renderSubsessionCompletions, SUBSESSION_COMPLETION_ENTRY_TYPE, SUBSESSION_NOTIFICATION_CUSTOM_TYPE, SUBSESSION_RECEIPT_ENTRY_TYPE, SubsessionCompletionInbox } from "./subsessionCompletionInbox.js";
|
|
@@ -56,6 +63,7 @@ import { ExtensionDialogWaiters, effectiveExtensionDialogTimeoutMs, extensionDia
|
|
|
56
63
|
import { createSpawnSessionToolDefinition } from "./spawnSessionTool.js";
|
|
57
64
|
import { createSubsessionToolDefinitions } from "./spawnSubsessionTool.js";
|
|
58
65
|
import { buildTranscriptView } from "./subsessionTranscript.js";
|
|
66
|
+
import { createSendSessionMessageToolDefinition } from "./sendSessionMessageTool.js";
|
|
59
67
|
import { planSessionCleanup, summarizeSessionCleanupExecution } from "./sessionCleanup.js";
|
|
60
68
|
import { createManagedAgentToolOptions, createManagedBashToolDefinition, createManagedPythonToolDefinition } from "./managementAgentTools.js";
|
|
61
69
|
import { PI_PERMISSION_SYSTEM_POLICY_AGENT_DIR, managementAgentToolNames, privilegedManagementToolNames, withRuntimeCreationEnvironment, writeManagementPermissionSystemPolicy } from "./managementPermissionSystem.js";
|
|
@@ -311,7 +319,8 @@ export function collectRuntimeWarnings(runtime) {
|
|
|
311
319
|
/**
|
|
312
320
|
* Verbatim TUI wording for the Anthropic subscription-auth billing notice. Kept
|
|
313
321
|
* character-for-character in sync with `ANTHROPIC_SUBSCRIPTION_AUTH_WARNING` in
|
|
314
|
-
* the SDK's interactive mode
|
|
322
|
+
* the SDK's interactive mode as the wire fallback. Browser presentation metadata
|
|
323
|
+
* allows translation without matching this English string.
|
|
315
324
|
*/
|
|
316
325
|
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
326
|
/** Mirror of the SDK TUI `isAnthropicSubscriptionAuthKey` (subscription API keys start with `sk-ant-oat`). */
|
|
@@ -352,6 +361,7 @@ export function anthropicSubscriptionWarning(session, authPath) {
|
|
|
352
361
|
return {
|
|
353
362
|
severity: "warning",
|
|
354
363
|
message: ANTHROPIC_SUBSCRIPTION_AUTH_WARNING,
|
|
364
|
+
presentation: { kind: "anthropicSubscriptionAuth" },
|
|
355
365
|
source: "anthropic",
|
|
356
366
|
dismiss: { id: ANTHROPIC_EXTRA_USAGE_DISMISS_ID },
|
|
357
367
|
};
|
|
@@ -438,11 +448,11 @@ async function createNormalPermissionSessionServices(options) {
|
|
|
438
448
|
});
|
|
439
449
|
return { services, projectTrustDiagnostics };
|
|
440
450
|
}
|
|
441
|
-
function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, managementModelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled = false, workbench, logger = noopLogger, managementAudit, managementProjectIdForCwd, appendSystemPromptSections = [], managementAllowPrivileged = false) {
|
|
451
|
+
function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, managementModelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled = false, workbench, logger = noopLogger, managementAudit, managementProjectIdForCwd, appendSystemPromptSections = [], managementAllowPrivileged = false, messaging) {
|
|
442
452
|
return async ({ cwd, agentDir, sessionManager, sessionStartEvent, managementContext, initialModel, initialThinkingLevel, delegationToolsEnabled }) => {
|
|
443
453
|
const scopedModelRuntime = managementContext === undefined ? await normalModelRuntimeForCwd(cwd) : await managementModelRuntime();
|
|
444
454
|
if (managementContext !== undefined) {
|
|
445
|
-
return createManagementRuntimeFactory(scopedModelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled, managementContext, workbench, logger, managementAudit, managementProjectIdForCwd, managementAllowPrivileged, appendSystemPromptSections)({
|
|
455
|
+
return createManagementRuntimeFactory(scopedModelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled, managementContext, workbench, logger, managementAudit, managementProjectIdForCwd, managementAllowPrivileged, appendSystemPromptSections, messaging)({
|
|
446
456
|
cwd,
|
|
447
457
|
agentDir,
|
|
448
458
|
sessionManager,
|
|
@@ -454,6 +464,8 @@ function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, ma
|
|
|
454
464
|
}
|
|
455
465
|
// Resource loaders may read process.env; wait for managed overrides to be restored.
|
|
456
466
|
return withRuntimeCreationEnvironment({}, async () => {
|
|
467
|
+
const parentSessionFile = sessionManager.getHeader()?.parentSession;
|
|
468
|
+
const parentHeader = parentSessionFile === undefined ? undefined : await readSessionHeaderSummary(parentSessionFile);
|
|
457
469
|
const projectTrustRequiring = hasTrustRequiringProjectResources(cwd);
|
|
458
470
|
const settingsManager = await createScopedSettingsManager({
|
|
459
471
|
cwd,
|
|
@@ -473,7 +485,10 @@ function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, ma
|
|
|
473
485
|
modelRuntime: scopedModelRuntime,
|
|
474
486
|
settingsManager,
|
|
475
487
|
projectTrustRequiring,
|
|
476
|
-
appendSystemPromptSections
|
|
488
|
+
appendSystemPromptSections: [
|
|
489
|
+
...appendSystemPromptSections,
|
|
490
|
+
...(parentHeader === undefined ? [] : [`<pi_web_session_context>\nParent session ID: ${parentHeader.id}\n</pi_web_session_context>`]),
|
|
491
|
+
],
|
|
477
492
|
eventBus,
|
|
478
493
|
mcpScope: { directory: mcpOAuthStorageDirectory(await resolveSettingsScope(cwd, "normal")) },
|
|
479
494
|
extensionFactories: [sessionDispatch, ...(subsessions === undefined ? [] : [createSubsessionCompletionDelivery(subsessions)])],
|
|
@@ -488,7 +503,7 @@ function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, ma
|
|
|
488
503
|
const resolvedDelegationToolsEnabled = delegationToolsEnabled
|
|
489
504
|
?? await sessionAllowsDelegationTools(sessionManager, sessionManagers);
|
|
490
505
|
dispatchEnabled = resolvedDelegationToolsEnabled;
|
|
491
|
-
const customTools = createPiWebCustomToolDefinitions(cwd, resolvedDelegationToolsEnabled, spawn, subsessions, askUserEnabled);
|
|
506
|
+
const customTools = createPiWebCustomToolDefinitions(cwd, resolvedDelegationToolsEnabled, spawn, subsessions, askUserEnabled, messaging);
|
|
492
507
|
const result = await createAgentSessionFromServices({
|
|
493
508
|
services,
|
|
494
509
|
sessionManager,
|
|
@@ -505,7 +520,7 @@ function createDefaultRuntimeFactory(sessionEvents, normalModelRuntimeForCwd, ma
|
|
|
505
520
|
});
|
|
506
521
|
};
|
|
507
522
|
}
|
|
508
|
-
function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled, managementContext, workbench, logger, managementAudit, managementProjectIdForCwd, managementAllowPrivileged = false, appendSystemPromptSections = []) {
|
|
523
|
+
function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sessionManagers, spawn, subsessions, askUserEnabled, managementContext, workbench, logger, managementAudit, managementProjectIdForCwd, managementAllowPrivileged = false, appendSystemPromptSections = [], messaging) {
|
|
509
524
|
return async ({ cwd, agentDir, sessionManager, sessionStartEvent, initialModel, initialThinkingLevel, delegationToolsEnabled }) => {
|
|
510
525
|
const normalPermissions = managementUsesNormalPermissions(managementContext, { allowPrivileged: managementAllowPrivileged });
|
|
511
526
|
const privileges = managementPrivileges(managementContext, { allowPrivileged: managementAllowPrivileged });
|
|
@@ -541,10 +556,16 @@ function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sess
|
|
|
541
556
|
const scopedSpawn = spawn === undefined
|
|
542
557
|
? undefined
|
|
543
558
|
: (input) => spawn({ ...input, managementContext });
|
|
559
|
+
const scopedMessaging = messaging === undefined ? undefined : {
|
|
560
|
+
send: (input) => messaging.send(input, managementContext),
|
|
561
|
+
};
|
|
544
562
|
const scopedSubsessions = subsessions === undefined
|
|
545
563
|
? undefined
|
|
546
564
|
: {
|
|
547
565
|
spawn: (input) => subsessions.spawn({ ...input, managementContext }),
|
|
566
|
+
archive: (parentSessionId, sessionId, parentSessionFile) => subsessions.archive(parentSessionId, sessionId, parentSessionFile, managementContext),
|
|
567
|
+
stop: (parentSessionId, sessionId, parentSessionFile) => subsessions.stop(parentSessionId, sessionId, parentSessionFile, managementContext),
|
|
568
|
+
resume: (parentSessionId, sessionId, prompt, parentSessionFile) => subsessions.resume(parentSessionId, sessionId, prompt, parentSessionFile, managementContext),
|
|
548
569
|
list: (parentSessionId, parentSessionFile) => subsessions.list(parentSessionId, parentSessionFile, managementContext),
|
|
549
570
|
join: (parentSessionId, parentSessionFile, toolCallId) => subsessions.join(parentSessionId, parentSessionFile, toolCallId, managementContext),
|
|
550
571
|
prepare: (parentSessionId, parentSessionFile) => subsessions.prepare(parentSessionId, parentSessionFile, managementContext),
|
|
@@ -552,10 +573,16 @@ function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sess
|
|
|
552
573
|
read: (parentSessionId, sessionId, query, parentSessionFile, toolCallId) => subsessions.read(parentSessionId, sessionId, query, parentSessionFile, toolCallId, managementContext),
|
|
553
574
|
};
|
|
554
575
|
const managementFactories = [
|
|
555
|
-
|
|
576
|
+
createExtensionSessionDispatch(cwd, {
|
|
577
|
+
...(scopedSpawn === undefined ? {} : { spawn: scopedSpawn }),
|
|
578
|
+
isEnabled: () => resolvedDelegationToolsEnabled
|
|
579
|
+
&& (normalPermissions || managementContext.tools?.deny?.includes("dispatch_relay") !== true),
|
|
580
|
+
}),
|
|
556
581
|
...(scopedSubsessions === undefined ? [] : [createSubsessionCompletionDelivery(scopedSubsessions)]),
|
|
557
582
|
];
|
|
558
583
|
const controlledManagementTools = [
|
|
584
|
+
defineTool(createRequestHumanInterventionToolDefinition()),
|
|
585
|
+
...(scopedMessaging === undefined ? [] : [defineTool(createSendSessionMessageToolDefinition(cwd, scopedMessaging))]),
|
|
559
586
|
...(resolvedDelegationToolsEnabled && scopedSpawn !== undefined ? [defineTool(createSpawnSessionToolDefinition(cwd, { spawn: scopedSpawn }))] : []),
|
|
560
587
|
...(resolvedDelegationToolsEnabled && scopedSubsessions !== undefined ? createSubsessionToolDefinitions(cwd, scopedSubsessions).map((tool) => defineTool(tool)) : []),
|
|
561
588
|
...(askUserEnabled ? [createAskUserToolDefinition()] : []),
|
|
@@ -569,7 +596,11 @@ function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sess
|
|
|
569
596
|
requestedNetwork: managementContext.privileged?.network === true,
|
|
570
597
|
}, "management privileged grant ignored because managementEmbed.allowPrivileged is disabled");
|
|
571
598
|
}
|
|
572
|
-
const extraToolNames = [
|
|
599
|
+
const extraToolNames = [
|
|
600
|
+
...controlledManagementToolNames,
|
|
601
|
+
...(resolvedDelegationToolsEnabled && scopedSpawn !== undefined ? ["dispatch_relay"] : []),
|
|
602
|
+
...privilegedManagementToolNames(privileges),
|
|
603
|
+
];
|
|
573
604
|
const policyAgentDir = normalPermissions ? undefined : await writeManagementPermissionSystemPolicy(agentDir, cwd, managementContext, extraToolNames, privileges);
|
|
574
605
|
const resourceEnvironment = normalPermissions ? {} : { [PI_PERMISSION_SYSTEM_POLICY_AGENT_DIR]: policyAgentDir };
|
|
575
606
|
return withRuntimeCreationEnvironment(resourceEnvironment, async () => {
|
|
@@ -613,7 +644,7 @@ function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sess
|
|
|
613
644
|
...(initialThinkingLevel === undefined ? {} : { initialThinkingLevel }),
|
|
614
645
|
});
|
|
615
646
|
services.diagnostics.push(...modelOptions.diagnostics);
|
|
616
|
-
const customTools = normalPermissions ? createPiWebCustomToolDefinitions(cwd, resolvedDelegationToolsEnabled, scopedSpawn, scopedSubsessions, askUserEnabled) : [
|
|
647
|
+
const customTools = normalPermissions ? createPiWebCustomToolDefinitions(cwd, resolvedDelegationToolsEnabled, scopedSpawn, scopedSubsessions, askUserEnabled, scopedMessaging) : [
|
|
617
648
|
...managedAgentToolDefinitions(cwd, createManagedAgentToolOptions(cwd)),
|
|
618
649
|
createManagedPythonToolDefinition(cwd, managementContext, { network: privileges.network }),
|
|
619
650
|
createManagedBashToolDefinition(cwd, managementContext, { network: privileges.network, hostFilesystem: privileges.bash }),
|
|
@@ -643,9 +674,11 @@ function createManagementRuntimeFactory(modelRuntime, resolveSettingsScope, sess
|
|
|
643
674
|
});
|
|
644
675
|
};
|
|
645
676
|
}
|
|
646
|
-
export function createPiWebCustomToolDefinitions(cwd, delegationEnabled, spawn, subsessions, askUserEnabled = false) {
|
|
677
|
+
export function createPiWebCustomToolDefinitions(cwd, delegationEnabled, spawn, subsessions, askUserEnabled = false, messaging) {
|
|
647
678
|
return [
|
|
648
679
|
...managedAgentToolDefinitions(cwd),
|
|
680
|
+
defineTool(createRequestHumanInterventionToolDefinition()),
|
|
681
|
+
...(messaging === undefined ? [] : [defineTool(createSendSessionMessageToolDefinition(cwd, messaging))]),
|
|
649
682
|
...(delegationEnabled && spawn !== undefined ? [defineTool(createSpawnSessionToolDefinition(cwd, { spawn }))] : []),
|
|
650
683
|
...(delegationEnabled && subsessions !== undefined ? createSubsessionToolDefinitions(cwd, subsessions).map((tool) => defineTool(tool)) : []),
|
|
651
684
|
...(askUserEnabled ? [createAskUserToolDefinition()] : []),
|
|
@@ -678,7 +711,7 @@ function createPiWebEditToolDefinition(cwd, options) {
|
|
|
678
711
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
679
712
|
const preview = await computeEditPreview(params.path, params.edits, cwd);
|
|
680
713
|
if (signal?.aborted !== true) {
|
|
681
|
-
onUpdate?.({ content: [{ type: "text", text: "Edit preview computed." }], details: { preview } });
|
|
714
|
+
onUpdate?.({ content: [{ type: "text", text: "Edit preview computed." }], details: { preview, presentation: { kind: "editPreviewComputed" } } });
|
|
682
715
|
}
|
|
683
716
|
return editTool.execute(toolCallId, params, signal, onUpdate, ctx);
|
|
684
717
|
},
|
|
@@ -697,12 +730,19 @@ export class PiSessionService {
|
|
|
697
730
|
this.activities = new SessionActivityCoordinator();
|
|
698
731
|
/** Runtime-identity gate held while Pi may await abandoned-branch summarization. */
|
|
699
732
|
this.treeNavigations = new WeakSet();
|
|
733
|
+
this.publishedSessionNames = new WeakMap();
|
|
734
|
+
/**
|
|
735
|
+
* Bare live leaf selected without an appended summary entry. Recording that
|
|
736
|
+
* leaf distinguishes the unpersisted move from a later runtime append that
|
|
737
|
+
* can anchor the selected branch on disk.
|
|
738
|
+
*/
|
|
700
739
|
this.unpersistedTreeBranchLeaves = new WeakMap();
|
|
701
740
|
/** Counts async operations that may append an entry before they settle. */
|
|
702
741
|
this.sessionEntryMutationCounts = new WeakMap();
|
|
703
742
|
this.manualCompactionEnded = new WeakSet();
|
|
704
743
|
this.extensionCommandExecution = new AsyncLocalStorage();
|
|
705
744
|
this.runtimeMessageCounts = new WeakMap();
|
|
745
|
+
this.interventionStates = new WeakMap();
|
|
706
746
|
this.snapshotMessageCounts = new WeakMap();
|
|
707
747
|
this.pendingPromptEchoes = new WeakMap();
|
|
708
748
|
this.publishedAssistantPartials = new WeakMap();
|
|
@@ -722,7 +762,6 @@ export class PiSessionService {
|
|
|
722
762
|
this.subsessionStoppedParents = new WeakSet();
|
|
723
763
|
this.subsessionDeliveringParents = new WeakSet();
|
|
724
764
|
this.subsessionDeliveryScheduled = new WeakSet();
|
|
725
|
-
this.deferredGeneratedSessionNames = new WeakMap();
|
|
726
765
|
this.compactionPromptQueues = new Map();
|
|
727
766
|
this.compactionDrainTimers = new Map();
|
|
728
767
|
this.authLossWarnings = new Set();
|
|
@@ -752,6 +791,7 @@ export class PiSessionService {
|
|
|
752
791
|
this.mcpAuthOwners = new WeakMap();
|
|
753
792
|
this.notificationGenerationBySession = new WeakMap();
|
|
754
793
|
this.idleSessionFileResolutions = new WeakMap();
|
|
794
|
+
this.unreadEligibilityRevision = 0;
|
|
755
795
|
/** The parked extension Promise resolvers behind the store's open dialogs. */
|
|
756
796
|
this.dialogWaiters = new ExtensionDialogWaiters();
|
|
757
797
|
this.pendingUnreadMutations = [];
|
|
@@ -760,6 +800,7 @@ export class PiSessionService {
|
|
|
760
800
|
this.t = deps.translator ?? loadNodeTranslator("server");
|
|
761
801
|
this.managementAllowPrivileged = deps.managementAllowPrivileged === true;
|
|
762
802
|
this.archiveStore = deps.archiveStore ?? new SessionArchiveStore();
|
|
803
|
+
this.sessionPins = deps.sessionPins;
|
|
763
804
|
this.pinStore = deps.pinStore ?? new SessionPinStore(join(deps.dataDir ?? piWebDataDir(), "session-pins.json"));
|
|
764
805
|
this.agentDir = deps.agentDir ?? getAgentDir();
|
|
765
806
|
this.dataDir = deps.dataDir ?? piWebDataDir();
|
|
@@ -781,6 +822,7 @@ export class PiSessionService {
|
|
|
781
822
|
? resolveDefaultModelRuntime
|
|
782
823
|
: () => Promise.resolve(managementModelRuntime);
|
|
783
824
|
this.spawnTargets = deps.spawnTargets;
|
|
825
|
+
this.messageTargets = deps.sessionMessagesEnabled === false ? undefined : deps.messageTargets ?? deps.spawnTargets;
|
|
784
826
|
this.logger = deps.logger ?? noopLogger;
|
|
785
827
|
this.normalToolAudit = deps.normalToolAudit;
|
|
786
828
|
this.managementAudit = deps.managementAudit;
|
|
@@ -805,20 +847,24 @@ export class PiSessionService {
|
|
|
805
847
|
this.sessionEvents = deps.sessionEvents ?? new PiSessionEventConnections();
|
|
806
848
|
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 : {
|
|
807
849
|
spawn: (input) => this.spawnSubsession(input),
|
|
850
|
+
archive: (parentSessionId, sessionId, parentSessionFile, context) => this.archiveSubsession(parentSessionId, sessionId, parentSessionFile, context),
|
|
851
|
+
stop: (parentSessionId, sessionId, parentSessionFile, context) => this.stopSubsession(parentSessionId, sessionId, parentSessionFile, context),
|
|
852
|
+
resume: (parentSessionId, sessionId, prompt, parentSessionFile, context) => this.resumeSubsession(parentSessionId, sessionId, prompt, parentSessionFile, context),
|
|
808
853
|
list: (parentSessionId, parentSessionFile, managementContext) => this.listSubsessions(parentSessionId, parentSessionFile, managementContext),
|
|
809
854
|
join: (parentSessionId, parentSessionFile, toolCallId, managementContext) => this.joinSubsessions(parentSessionId, parentSessionFile, toolCallId, managementContext),
|
|
810
855
|
prepare: (parentSessionId, parentSessionFile, managementContext) => this.prepareSubsessionDelivery(parentSessionId, parentSessionFile, managementContext),
|
|
811
856
|
check: (parentSessionId, sessionId, parentSessionFile, toolCallId, managementContext) => this.checkSubsession(parentSessionId, sessionId, parentSessionFile, toolCallId, managementContext),
|
|
812
857
|
read: (parentSessionId, sessionId, query, parentSessionFile, toolCallId, managementContext) => this.readSubsession(parentSessionId, sessionId, query, parentSessionFile, toolCallId, managementContext),
|
|
813
|
-
}, deps.askUserEnabled === true, deps.workbench, this.logger, this.managementAudit, this.managementProjectIdForCwd, deps.appendSystemPromptSections ?? [], deps.managementAllowPrivileged === true);
|
|
858
|
+
}, 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) });
|
|
814
859
|
this.createAgentRuntime = deps.createAgentRuntime ?? defaultCreateAgentRuntime;
|
|
815
860
|
this.workspaceActivity = deps.workspaceActivity;
|
|
816
861
|
this.heartbeat = setInterval(() => { this.publishHeartbeats(); }, deps.heartbeatIntervalMs ?? 2000);
|
|
817
862
|
this.commandService = new SessionCommandService((sessionId, eventScope) => this.getActiveForCommand(sessionId, eventScope), (sessionId, text, eventScope) => this.submitCommandPrompt(sessionId, text, eventScope), events, {
|
|
863
|
+
onSessionNameChanged: (session) => { this.publishSessionName(session); },
|
|
818
864
|
onCompactionStart: (session) => {
|
|
819
865
|
this.beginSessionEntryMutation(session, this.t("session.action.compact", "compact the session"));
|
|
820
866
|
this.manualCompactionEnded.delete(session);
|
|
821
|
-
this.publishActivity(session,
|
|
867
|
+
this.publishActivity(session, { kind: "compacting" }, "active");
|
|
822
868
|
this.publishStatus(session);
|
|
823
869
|
},
|
|
824
870
|
onCompactionEnd: (session, result, detail) => {
|
|
@@ -858,43 +904,25 @@ export class PiSessionService {
|
|
|
858
904
|
return previewResponseFromPlan(await this.cleanupPlan(request));
|
|
859
905
|
}
|
|
860
906
|
async cleanup(request, context) {
|
|
861
|
-
const scope = eventScopeFromManagementContext(context);
|
|
862
907
|
const plan = await this.cleanupPlan(request);
|
|
863
908
|
if (plan.deleteRecords.length > 0 && this.archiveStore.deleteArchived === undefined && this.archiveStore.deleteArchivedMany === undefined)
|
|
864
909
|
throw new Error(this.t("session.archiveDeleteUnsupported", "The archive store does not support deletion"));
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
}
|
|
875
|
-
await this.closeActive(input.sessionId, { kind: "clear", reason: "archive" }, scope);
|
|
876
|
-
readyArchiveInputs.push(input);
|
|
877
|
-
}
|
|
878
|
-
await this.archiveStoreArchiveMany(readyArchiveInputs);
|
|
879
|
-
archiveInputs.push(...readyArchiveInputs);
|
|
880
|
-
await this.forgetUnreadSessions(readyArchiveInputs, scope);
|
|
881
|
-
for (const record of plan.deleteRecords) {
|
|
882
|
-
if (this.activeSessionHasWork(record.sessionId)) {
|
|
883
|
-
skippedBusySessionIds.add(record.sessionId);
|
|
884
|
-
continue;
|
|
885
|
-
}
|
|
886
|
-
await this.closeActive(record.sessionId, { kind: "clear", reason: "delete" }, scope);
|
|
887
|
-
readyDeleteRecords.push(record);
|
|
888
|
-
}
|
|
889
|
-
const deletedSessionIds = new Set(await this.archiveStoreDeleteArchivedMany(readyDeleteRecords.map((record) => record.sessionId)));
|
|
890
|
-
deleteRecords.push(...readyDeleteRecords.filter((record) => deletedSessionIds.has(record.sessionId)));
|
|
891
|
-
await this.forgetUnreadSessions(deleteRecords, scope);
|
|
910
|
+
const archived = await this.executeArchiveBatch(plan.archiveInputs, context);
|
|
911
|
+
if (archived.failures.length > 0)
|
|
912
|
+
throw new Error(archived.failures.map((failure) => `${failure.sessionId}: ${failure.error}`).join("; "));
|
|
913
|
+
const deleted = await this.executeDeleteArchivedBatch(plan.deleteRecords, context);
|
|
914
|
+
if (deleted.failures.length > 0)
|
|
915
|
+
throw new Error(deleted.failures.map((failure) => `${failure.sessionId}: ${failure.error}`).join("; "));
|
|
916
|
+
const archiveInputs = archived.successes;
|
|
917
|
+
const deleteRecords = deleted.successes;
|
|
918
|
+
const skippedBusySessionIds = new Set([...plan.skippedBusySessionIds, ...archived.skippedBusySessionIds, ...deleted.skippedBusySessionIds]);
|
|
892
919
|
return summarizeSessionCleanupExecution({
|
|
893
920
|
archiveInputs,
|
|
894
921
|
deleteRecords,
|
|
895
922
|
thresholds: plan.thresholds,
|
|
896
923
|
generatedAt: plan.generatedAt,
|
|
897
924
|
skippedBusySessionIds: [...skippedBusySessionIds],
|
|
925
|
+
...(plan.skippedPinnedSessionIds === undefined ? {} : { skippedPinnedSessionIds: plan.skippedPinnedSessionIds }),
|
|
898
926
|
});
|
|
899
927
|
}
|
|
900
928
|
async dispose() {
|
|
@@ -948,6 +976,18 @@ export class PiSessionService {
|
|
|
948
976
|
});
|
|
949
977
|
await this.publishUnreadMutations([]);
|
|
950
978
|
}
|
|
979
|
+
/** Recover cold-session intervention flags without opening agent runtimes. */
|
|
980
|
+
async restoreInterventionState() {
|
|
981
|
+
const [sessions, archives] = await Promise.all([this.sessionManager.listAll(), this.archiveStore.list()]);
|
|
982
|
+
const archived = new Set(archives.map((record) => record.sessionId));
|
|
983
|
+
for (const session of sessions) {
|
|
984
|
+
if (!await normalSessionReadAllowed(session.cwd, this.projectPathForCwd, this.managementProjectRoot))
|
|
985
|
+
continue;
|
|
986
|
+
if (archived.has(session.id) || this.activeForLookup({ id: session.id, cwd: session.cwd }) !== undefined)
|
|
987
|
+
continue;
|
|
988
|
+
this.workspaceActivity?.applySessionIntervention(session.cwd, session.id, session.interventionRequired === true);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
951
991
|
async list(cwd, managementContext) {
|
|
952
992
|
return (await this.listWorkspaceSessions(cwd, managementContext)).sessions;
|
|
953
993
|
}
|
|
@@ -963,17 +1003,28 @@ export class PiSessionService {
|
|
|
963
1003
|
if (normalizedQuery === "")
|
|
964
1004
|
return { results: [], matchCount: 0, truncated: false };
|
|
965
1005
|
const maxMatches = 200;
|
|
966
|
-
const
|
|
967
|
-
const
|
|
1006
|
+
const listing = await this.listWorkspaceSessions(cwd, managementContext);
|
|
1007
|
+
const matchText = compileSessionContentQuery(normalizedQuery);
|
|
1008
|
+
const candidates = [];
|
|
968
1009
|
let matchCount = 0;
|
|
969
|
-
for (const session of sessions) {
|
|
970
|
-
const
|
|
971
|
-
const
|
|
972
|
-
const view = searchSessionContent(messages, normalizedQuery, Math.max(1, remaining));
|
|
1010
|
+
for (const session of listing.sessions) {
|
|
1011
|
+
const messages = await this.searchableSessionHistory(session, listing, managementContext);
|
|
1012
|
+
const view = searchSessionContent(messages, matchText, maxMatches);
|
|
973
1013
|
matchCount += view.matchCount;
|
|
974
|
-
|
|
975
|
-
|
|
1014
|
+
candidates.push(...view.matches.map((match) => ({ session, match })));
|
|
1015
|
+
candidates.sort((left, right) => left.match.rank - right.match.rank);
|
|
1016
|
+
candidates.length = Math.min(candidates.length, maxMatches);
|
|
1017
|
+
}
|
|
1018
|
+
const grouped = new Map();
|
|
1019
|
+
for (const { session, match } of candidates) {
|
|
1020
|
+
let result = grouped.get(session.id);
|
|
1021
|
+
if (result === undefined) {
|
|
1022
|
+
result = { session, matches: [] };
|
|
1023
|
+
grouped.set(session.id, result);
|
|
1024
|
+
}
|
|
1025
|
+
result.matches.push({ messageIndex: match.messageIndex, role: match.role, excerpts: match.excerpts, occurrenceCount: match.occurrenceCount });
|
|
976
1026
|
}
|
|
1027
|
+
const results = [...grouped.values()];
|
|
977
1028
|
return { results, matchCount, truncated: matchCount > maxMatches };
|
|
978
1029
|
}
|
|
979
1030
|
async listPinned(cwd, managementContext) {
|
|
@@ -1017,11 +1068,17 @@ export class PiSessionService {
|
|
|
1017
1068
|
const listed = unarchivedById.get(session.sessionId);
|
|
1018
1069
|
const tracked = this.subsessionLinkForActiveChild(session) !== undefined;
|
|
1019
1070
|
if (listed !== undefined) {
|
|
1020
|
-
|
|
1021
|
-
|
|
1071
|
+
// Match the file too: a clone with the same id must not inherit a
|
|
1072
|
+
// live runtime's classification. Disk rows otherwise use the scanner.
|
|
1073
|
+
if (session.sessionFile !== undefined && sessionPathsEqual(listed.path, session.sessionFile)) {
|
|
1074
|
+
if (tracked)
|
|
1075
|
+
listed.agentSubsession = true;
|
|
1076
|
+
listed.interventionRequired = this.statusFromSession(session).interventionRequired === true;
|
|
1077
|
+
}
|
|
1022
1078
|
continue;
|
|
1023
1079
|
}
|
|
1024
1080
|
const info = clientSessionFromActiveSession(session);
|
|
1081
|
+
info.interventionRequired = this.statusFromSession(session).interventionRequired === true;
|
|
1025
1082
|
if (tracked)
|
|
1026
1083
|
info.agentSubsession = true;
|
|
1027
1084
|
unarchivedById.set(session.sessionId, info);
|
|
@@ -1032,6 +1089,10 @@ export class PiSessionService {
|
|
|
1032
1089
|
if (managementContext === undefined) {
|
|
1033
1090
|
await this.publishUnreadMutations(this.unreadForScope(eventScopeFromManagementContext(managementContext)).reconcileCwd(canonicalizeStoredCwd(cwd), reconcilableSessionIds));
|
|
1034
1091
|
}
|
|
1092
|
+
for (const session of unarchivedSessions) {
|
|
1093
|
+
if (this.activeForLookup({ id: session.id, cwd }, managementContext) === undefined)
|
|
1094
|
+
this.workspaceActivity?.applySessionIntervention(cwd, session.id, session.interventionRequired === true, eventScopeFromManagementContext(managementContext));
|
|
1095
|
+
}
|
|
1035
1096
|
const archivedSessions = archivedForCwd
|
|
1036
1097
|
.map((record) => clientSessionFromArchivedRecord(record, sessionsById.get(record.sessionId)))
|
|
1037
1098
|
.filter(isDefined)
|
|
@@ -1066,18 +1127,41 @@ export class PiSessionService {
|
|
|
1066
1127
|
continue;
|
|
1067
1128
|
const row = rows.get(session.sessionId);
|
|
1068
1129
|
// A disk clone with the same id must not inherit another file's runtime.
|
|
1069
|
-
if (row !== undefined && (session.sessionFile === undefined || !sessionPathsEqual(row.path, session.sessionFile)))
|
|
1130
|
+
if (row !== undefined && (row.path === undefined || session.sessionFile === undefined || !sessionPathsEqual(row.path, session.sessionFile)))
|
|
1070
1131
|
continue;
|
|
1071
1132
|
runtimes.set(session.sessionId, session);
|
|
1072
|
-
|
|
1133
|
+
const headerCreated = session.sessionManager.getHeader?.()?.timestamp;
|
|
1134
|
+
const metadata = readSessionUiMetadata(session.sessionManager.getEntries?.() ?? session.sessionManager.getBranch());
|
|
1135
|
+
const created = row?.created ?? (headerCreated !== undefined && Number.isFinite(Date.parse(headerCreated)) ? new Date(headerCreated).toISOString() : undefined);
|
|
1136
|
+
// Scanner dates match native cleanup eligibility. A hosted-only runtime's
|
|
1137
|
+
// header records creation, not its most recent activity.
|
|
1138
|
+
rows.set(session.sessionId, {
|
|
1139
|
+
id: session.sessionId,
|
|
1140
|
+
cwd: session.sessionManager.getCwd(),
|
|
1141
|
+
...(session.sessionName === undefined ? {} : { name: session.sessionName }),
|
|
1142
|
+
...(metadata === undefined ? {} : { metadata }),
|
|
1143
|
+
...(created === undefined ? {} : { created }),
|
|
1144
|
+
...(row?.modified === undefined ? {} : { modified: row.modified }),
|
|
1145
|
+
});
|
|
1073
1146
|
}
|
|
1074
1147
|
const entriesById = new Map(entries.map((entry) => [entry.id, entry]));
|
|
1075
1148
|
for (const record of archived) {
|
|
1076
|
-
const
|
|
1077
|
-
|
|
1078
|
-
|
|
1149
|
+
const entry = entriesById.get(record.sessionId);
|
|
1150
|
+
const created = record.created ?? entry?.created.toISOString();
|
|
1151
|
+
const modified = record.modified ?? entry?.modified.toISOString();
|
|
1152
|
+
// Legacy records may lack transcript/path fields required by the client
|
|
1153
|
+
// list helper; their archive identity and known dates are still usable.
|
|
1154
|
+
const row = clientSessionFromArchivedRecord(record, entry) ?? {
|
|
1155
|
+
id: record.sessionId,
|
|
1156
|
+
cwd: record.cwd,
|
|
1157
|
+
...(created === undefined ? {} : { created }),
|
|
1158
|
+
...(modified === undefined ? {} : { modified }),
|
|
1159
|
+
archived: true,
|
|
1160
|
+
archivedAt: record.archivedAt,
|
|
1161
|
+
};
|
|
1162
|
+
rows.set(row.id, row);
|
|
1079
1163
|
}
|
|
1080
|
-
return [...rows.values()].sort((a, b) => Date.parse(b.modified) - Date.parse(a.modified)).map((row) => {
|
|
1164
|
+
return [...rows.values()].sort((a, b) => (b.modified === undefined ? 0 : Date.parse(b.modified)) - (a.modified === undefined ? 0 : Date.parse(a.modified))).map((row) => {
|
|
1081
1165
|
const runtime = runtimes.get(row.id);
|
|
1082
1166
|
return Object.freeze({
|
|
1083
1167
|
id: row.id,
|
|
@@ -1085,6 +1169,9 @@ export class PiSessionService {
|
|
|
1085
1169
|
...(row.name === undefined ? {} : { name: row.name }),
|
|
1086
1170
|
...(row.metadata === undefined ? {} : { metadata: structuredClone(row.metadata) }),
|
|
1087
1171
|
archived: row.archived === true,
|
|
1172
|
+
created: row.created ?? null,
|
|
1173
|
+
modified: row.modified ?? null,
|
|
1174
|
+
archivedAt: row.archived === true ? row.archivedAt ?? null : null,
|
|
1088
1175
|
runtime: runtime === undefined ? "not-hosted" : this.hasActiveWork(runtime) ? "busy" : "idle",
|
|
1089
1176
|
});
|
|
1090
1177
|
});
|
|
@@ -1100,24 +1187,56 @@ export class PiSessionService {
|
|
|
1100
1187
|
return Object.freeze({ id: created.id });
|
|
1101
1188
|
}
|
|
1102
1189
|
/** Atomically start and prompt one visible normal-mode, non-delegating session. */
|
|
1103
|
-
async startOneShotRun(cwd, text, signal) {
|
|
1190
|
+
async startOneShotRun(cwd, text, signal, options = {}) {
|
|
1104
1191
|
const promptText = requirePromptText(text, this.t);
|
|
1105
|
-
return this.startManagedSession(cwd, signal, promptText);
|
|
1192
|
+
return this.startManagedSession(cwd, signal, promptText, options);
|
|
1106
1193
|
}
|
|
1107
|
-
async startManagedSession(cwd, signal, promptText) {
|
|
1194
|
+
async startManagedSession(cwd, signal, promptText, options = {}) {
|
|
1108
1195
|
signal.throwIfAborted();
|
|
1109
|
-
await this.normalModelRuntimeForCwd(cwd);
|
|
1110
|
-
|
|
1196
|
+
const modelRuntime = await this.normalModelRuntimeForCwd(cwd);
|
|
1197
|
+
let initialModel;
|
|
1198
|
+
if (options.model !== undefined) {
|
|
1199
|
+
await modelRuntime.refresh({ allowNetwork: false });
|
|
1200
|
+
signal.throwIfAborted();
|
|
1201
|
+
// Catalog membership alone does not mean the provider still has credentials
|
|
1202
|
+
// or is configured. Host overrides must be available after the refresh.
|
|
1203
|
+
initialModel = modelRuntime.getAvailableSnapshot().find((model) => modelScopeId(model) === options.model);
|
|
1204
|
+
if (initialModel === undefined) {
|
|
1205
|
+
throw Object.assign(new Error(`Model unavailable: ${options.model}`), { code: "PI_SESSION_MODEL_UNAVAILABLE" });
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
const active = await this.create(this.sessionManager.create(cwd), cwd, {
|
|
1209
|
+
startupIntent: "create", creationProvenance: "host-one-shot", startupSignal: signal,
|
|
1210
|
+
...(initialModel === undefined ? {} : { initialModel }),
|
|
1211
|
+
});
|
|
1111
1212
|
const { session } = active.runtime;
|
|
1112
1213
|
try {
|
|
1113
1214
|
signal.throwIfAborted();
|
|
1114
|
-
|
|
1115
|
-
|
|
1215
|
+
// Startup extensions may change the model. Never submit with a fallback
|
|
1216
|
+
// when the caller requested an exact model.
|
|
1217
|
+
if (options.model !== undefined && (session.model === undefined || modelScopeId(session.model) !== options.model)) {
|
|
1218
|
+
throw Object.assign(new Error(`Requested model is not active: ${options.model}`), { code: "PI_SESSION_MODEL_UNAVAILABLE" });
|
|
1219
|
+
}
|
|
1220
|
+
if (options.thinkingLevel !== undefined) {
|
|
1221
|
+
// Do not pass requested thinking into startup: the SDK can silently
|
|
1222
|
+
// clamp it before we have the actual model's supported levels.
|
|
1223
|
+
if (!session.getAvailableThinkingLevels().includes(options.thinkingLevel)) {
|
|
1224
|
+
throw Object.assign(new Error(`Thinking level unavailable: ${options.thinkingLevel}`), { code: "PI_SESSION_THINKING_UNAVAILABLE" });
|
|
1225
|
+
}
|
|
1226
|
+
session.setThinkingLevel(options.thinkingLevel);
|
|
1227
|
+
if (session.thinkingLevel !== options.thinkingLevel) {
|
|
1228
|
+
throw Object.assign(new Error(`Thinking level was not applied: ${options.thinkingLevel}`), { code: "PI_SESSION_THINKING_UNAVAILABLE" });
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
const settings = {
|
|
1232
|
+
...(session.model === undefined ? {} : { model: modelScopeId(session.model) }),
|
|
1233
|
+
thinkingLevel: session.thinkingLevel,
|
|
1234
|
+
};
|
|
1116
1235
|
const created = this.announceCreatedSession(active, cwd);
|
|
1117
1236
|
// Publication transfers lifetime ownership to normal hosting. Plugin
|
|
1118
1237
|
// cancellation after this point must not abort this or later user work.
|
|
1119
1238
|
const completion = promptText === undefined ? Promise.resolve() : this.submitInitialRunPrompt(session, promptText);
|
|
1120
|
-
return Object.freeze({ id: created.id, completion });
|
|
1239
|
+
return Object.freeze({ id: created.id, completion, ...settings });
|
|
1121
1240
|
}
|
|
1122
1241
|
catch (error) {
|
|
1123
1242
|
try {
|
|
@@ -1510,6 +1629,96 @@ export class PiSessionService {
|
|
|
1510
1629
|
...(outcome.answer === undefined ? {} : { answer: outcome.answer }),
|
|
1511
1630
|
}, this.eventScopeForSession(session));
|
|
1512
1631
|
}
|
|
1632
|
+
/** Interrupt a direct child's current run without closing its conversation. */
|
|
1633
|
+
async stopSubsession(parentSessionId, sessionId, parentSessionFile, managementContext) {
|
|
1634
|
+
const child = await this.openSubsession(parentSessionId, sessionId, parentSessionFile, managementContext);
|
|
1635
|
+
const cwd = child.sessionManager.getCwd();
|
|
1636
|
+
await this.abort({ id: sessionId, cwd }, managementContext);
|
|
1637
|
+
return { sessionId, cwd, status: this.subsessionStatus(child) };
|
|
1638
|
+
}
|
|
1639
|
+
/** Start another run in a direct child's conversation, without prompt expansion. */
|
|
1640
|
+
async resumeSubsession(parentSessionId, sessionId, prompt, parentSessionFile, managementContext) {
|
|
1641
|
+
const child = await this.openSubsession(parentSessionId, sessionId, parentSessionFile, managementContext);
|
|
1642
|
+
const cwd = child.sessionManager.getCwd();
|
|
1643
|
+
await this.assertWritable({ id: sessionId, cwd }, managementContext);
|
|
1644
|
+
this.assertTreeNavigationInactive(child, "resume a subsession");
|
|
1645
|
+
if (this.hasActiveWork(child))
|
|
1646
|
+
throw new Error("Subsession is already working");
|
|
1647
|
+
const text = requirePromptText(prompt ?? "Continue your previous task from the current conversation and workspace state. Check any interrupted work before repeating it.", this.t);
|
|
1648
|
+
void this.beginPromptSubmission(child, text, undefined, [], true, { expandPromptTemplates: false }).catch(() => undefined);
|
|
1649
|
+
return { sessionId, cwd, status: "working" };
|
|
1650
|
+
}
|
|
1651
|
+
/** Archive a direct child using the same idle-only operation as the browser. */
|
|
1652
|
+
async archiveSubsession(parentSessionId, sessionId, parentSessionFile, managementContext) {
|
|
1653
|
+
const child = await this.openSubsession(parentSessionId, sessionId, parentSessionFile, managementContext);
|
|
1654
|
+
await this.archive({ id: sessionId, cwd: child.sessionManager.getCwd() }, managementContext);
|
|
1655
|
+
}
|
|
1656
|
+
/** Send content, not control authority, to a named session in the same project. */
|
|
1657
|
+
async sendSessionMessage(input, managementContext) {
|
|
1658
|
+
if (this.messageTargets === undefined)
|
|
1659
|
+
throw new Error("Session messaging is unavailable");
|
|
1660
|
+
const message = requirePromptText(input.message, this.t);
|
|
1661
|
+
if (managementContext === undefined)
|
|
1662
|
+
await this.assertNormalSessionReadAccess(input.sendingCwd);
|
|
1663
|
+
else
|
|
1664
|
+
await this.getActive({ id: input.sendingSessionId, cwd: input.sendingCwd }, managementContext);
|
|
1665
|
+
const active = this.activeForLookup(input.sessionId, managementContext);
|
|
1666
|
+
const target = active === undefined
|
|
1667
|
+
? (await this.sessionManager.listAll()).find((entry) => entry.id === input.sessionId)
|
|
1668
|
+
: { id: input.sessionId, cwd: active.runtime.cwd };
|
|
1669
|
+
if (target === undefined)
|
|
1670
|
+
throw new Error("Session not found");
|
|
1671
|
+
if (active === undefined && this.activeSessionsForId(input.sessionId).some((entry) => cwdPathsEqual(entry.runtime.cwd, target.cwd)))
|
|
1672
|
+
throw new Error("Session not found");
|
|
1673
|
+
const decision = await this.messageTargets.resolveSpawnTarget(input.sendingCwd, target.cwd, eventScopeFromManagementContext(managementContext));
|
|
1674
|
+
if (!decision.allowed)
|
|
1675
|
+
throw new Error("Session messaging is limited to sessions in the same registered project");
|
|
1676
|
+
if (managementContext === undefined)
|
|
1677
|
+
await this.assertNormalSessionReadAccess(decision.cwd);
|
|
1678
|
+
else {
|
|
1679
|
+
if (this.managementProjectRoot === undefined)
|
|
1680
|
+
throw new Error("Managed session messaging requires a project root");
|
|
1681
|
+
await assertManagedCwd(this.managementProjectRoot, managementContext, decision.cwd, { create: false });
|
|
1682
|
+
}
|
|
1683
|
+
const ref = { id: input.sessionId, cwd: decision.cwd };
|
|
1684
|
+
await this.assertWritable(ref, managementContext);
|
|
1685
|
+
const session = await this.getOrOpen(ref, managementContext);
|
|
1686
|
+
this.assertTreeNavigationInactive(session, "receive a session message");
|
|
1687
|
+
const delivery = this.hasActiveWork(session) ? "queued" : "started";
|
|
1688
|
+
let agentStarted = false;
|
|
1689
|
+
const unsubscribe = session.subscribe((event) => {
|
|
1690
|
+
if (getString(event, "type") === "agent_start")
|
|
1691
|
+
agentStarted = true;
|
|
1692
|
+
});
|
|
1693
|
+
// A custom-message turn may run for minutes. Never wait for its answer in
|
|
1694
|
+
// the sender: reciprocal messages must not deadlock their tool calls.
|
|
1695
|
+
void this.runSessionEntryMutation(session, "receive a session message", async () => {
|
|
1696
|
+
if (session.isCompacting || session.isBashRunning)
|
|
1697
|
+
await session.waitForIdle();
|
|
1698
|
+
if (!this.isCurrentActiveSession(session))
|
|
1699
|
+
throw new Error("Session was closed before message delivery");
|
|
1700
|
+
await session.sendCustomMessage({
|
|
1701
|
+
customType: "session.message",
|
|
1702
|
+
content: `Message from session ${input.sendingSessionId}:\n\n${message}`,
|
|
1703
|
+
display: true,
|
|
1704
|
+
details: { sendingSessionId: input.sendingSessionId },
|
|
1705
|
+
}, { triggerTurn: true, deliverAs: "steer" });
|
|
1706
|
+
}).catch((error) => {
|
|
1707
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
1708
|
+
this.logger.info({ sessionId: input.sessionId, sendingSessionId: input.sendingSessionId, error: detail }, "session message delivery failed");
|
|
1709
|
+
if (!this.isCurrentActiveSession(session))
|
|
1710
|
+
return;
|
|
1711
|
+
this.publishActivity(session, { kind: "error" }, "error", detail);
|
|
1712
|
+
const scope = this.eventScopeForSession(session);
|
|
1713
|
+
this.events.publish(session.sessionId, { type: "session.error", message: detail }, scope);
|
|
1714
|
+
if (!agentStarted && this.subsessionLinkForActiveChild(session) !== undefined)
|
|
1715
|
+
this.subsessionNotifyArmed.set(activeSessionKey(session.sessionId, scope), true);
|
|
1716
|
+
this.updateSubsessionTracking(session);
|
|
1717
|
+
this.publishStatus(session);
|
|
1718
|
+
}).finally(unsubscribe);
|
|
1719
|
+
this.logger.info({ sendingSessionId: input.sendingSessionId, sessionId: input.sessionId, delivery }, "session message accepted");
|
|
1720
|
+
return { sessionId: input.sessionId, delivery };
|
|
1721
|
+
}
|
|
1513
1722
|
/** Summaries of the tracked subsessions spawned by `parentSessionId`. */
|
|
1514
1723
|
async listSubsessions(parentSessionId, parentSessionFile, managementContext) {
|
|
1515
1724
|
const parentFile = nonEmptyString(parentSessionFile);
|
|
@@ -2007,13 +2216,17 @@ export class PiSessionService {
|
|
|
2007
2216
|
}));
|
|
2008
2217
|
return { listing, sessions: matches.filter(isDefined) };
|
|
2009
2218
|
}
|
|
2010
|
-
searchableSessionHistory(session, listing, managementContext) {
|
|
2219
|
+
async searchableSessionHistory(session, listing, managementContext) {
|
|
2011
2220
|
const eventScope = eventScopeFromManagementContext(managementContext);
|
|
2012
2221
|
const active = this.activeForSessionIdAndScope(session.id, eventScope);
|
|
2013
2222
|
if (active !== undefined && cwdPathsEqual(active.runtime.cwd, session.cwd))
|
|
2014
2223
|
return historyMessages(active.runtime.session);
|
|
2015
2224
|
const path = listing.archivedById.get(session.id)?.archivePath ?? listing.entriesById.get(session.id)?.path;
|
|
2016
|
-
|
|
2225
|
+
if (path === undefined)
|
|
2226
|
+
return [];
|
|
2227
|
+
if (this.sessionManager.readBranch !== undefined)
|
|
2228
|
+
return historyMessagesFromEntries(await this.sessionManager.readBranch(path) ?? []);
|
|
2229
|
+
return historyMessagesFromManager(this.sessionManager.open(path));
|
|
2017
2230
|
}
|
|
2018
2231
|
async streamSnapshot(ref, managementContext) {
|
|
2019
2232
|
const session = await this.getOrOpen(ref, managementContext);
|
|
@@ -2151,7 +2364,7 @@ export class PiSessionService {
|
|
|
2151
2364
|
if (model === undefined)
|
|
2152
2365
|
throw new Error(this.t("model.notFound", "Model not found: {value0}/{value1}", { value0: provider, value1: modelId }));
|
|
2153
2366
|
await this.runSessionEntryMutation(session, this.t("server.main.130226a572df", "change models"), () => session.setModel(model));
|
|
2154
|
-
this.publishActivity(session,
|
|
2367
|
+
this.publishActivity(session, { kind: "model", value: model.id }, "idle", model.provider);
|
|
2155
2368
|
this.publishStatus(session);
|
|
2156
2369
|
return this.statusFromSession(session);
|
|
2157
2370
|
}
|
|
@@ -2165,7 +2378,7 @@ export class PiSessionService {
|
|
|
2165
2378
|
});
|
|
2166
2379
|
if (result === undefined)
|
|
2167
2380
|
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"));
|
|
2168
|
-
this.publishActivity(session,
|
|
2381
|
+
this.publishActivity(session, { kind: "model", value: result.model.id }, "idle", result.model.provider);
|
|
2169
2382
|
this.publishStatus(session);
|
|
2170
2383
|
return this.statusFromSession(session);
|
|
2171
2384
|
}
|
|
@@ -2187,7 +2400,7 @@ export class PiSessionService {
|
|
|
2187
2400
|
session.setThinkingLevel(match);
|
|
2188
2401
|
return Promise.resolve();
|
|
2189
2402
|
});
|
|
2190
|
-
this.publishActivity(session,
|
|
2403
|
+
this.publishActivity(session, { kind: "thinking", value: session.thinkingLevel }, "idle");
|
|
2191
2404
|
this.publishStatus(session);
|
|
2192
2405
|
return this.statusFromSession(session);
|
|
2193
2406
|
}
|
|
@@ -2197,7 +2410,7 @@ export class PiSessionService {
|
|
|
2197
2410
|
const level = await this.runSessionEntryMutation(session, this.t("session.action.changeThinking", "change the thinking level"), () => Promise.resolve(session.cycleThinkingLevel()));
|
|
2198
2411
|
if (level === undefined)
|
|
2199
2412
|
throw new Error(this.t("model.thinkingUnsupported", "The current model does not support thinking"));
|
|
2200
|
-
this.publishActivity(session,
|
|
2413
|
+
this.publishActivity(session, { kind: "thinking", value: level }, "idle");
|
|
2201
2414
|
this.publishStatus(session);
|
|
2202
2415
|
return this.statusFromSession(session);
|
|
2203
2416
|
}
|
|
@@ -2233,11 +2446,10 @@ export class PiSessionService {
|
|
|
2233
2446
|
await this.assertWritable(ref, options?.managementContext);
|
|
2234
2447
|
const session = await this.getOrOpen(ref, options?.managementContext);
|
|
2235
2448
|
this.assertTreeNavigationInactive(session, this.t("server.main.94306b2fc35c", "send a prompt"));
|
|
2236
|
-
this.maybeGenerateSessionName(session, promptText);
|
|
2237
2449
|
const isQueued = session.isStreaming || session.isCompacting;
|
|
2238
2450
|
const behavior = isQueued ? requestedBehavior ?? "followUp" : undefined;
|
|
2239
2451
|
if (isQueued && images.length === 0 && this.hasQueuedMessageText(session, promptText)) {
|
|
2240
|
-
this.publishActivity(session,
|
|
2452
|
+
this.publishActivity(session, { kind: "duplicateQueuedMessage" }, "active");
|
|
2241
2453
|
this.publishStatus(session);
|
|
2242
2454
|
return;
|
|
2243
2455
|
}
|
|
@@ -2259,7 +2471,7 @@ export class PiSessionService {
|
|
|
2259
2471
|
beginPromptSubmission(session, text, behavior, images = [], echoUserMessage = true, options = {}) {
|
|
2260
2472
|
if (options.auditUserPrompt !== false)
|
|
2261
2473
|
this.auditUserPrompt(session, text);
|
|
2262
|
-
this.publishActivity(session, behavior === "steer" ?
|
|
2474
|
+
this.publishActivity(session, behavior === "steer" ? { kind: "steeringQueued" } : behavior === "followUp" ? { kind: "messageQueued" } : { kind: "promptAccepted" }, "active");
|
|
2263
2475
|
const eventScope = this.eventScopeForSession(session);
|
|
2264
2476
|
const echoes = this.pendingPromptEchoes.get(session) ?? [];
|
|
2265
2477
|
const userCount = historyMessagesFromEntries(session.sessionManager.getBranch()).filter((message) => isRecord(message) && message["role"] === "user").length;
|
|
@@ -2300,7 +2512,7 @@ export class PiSessionService {
|
|
|
2300
2512
|
void promptPromise.catch((error) => {
|
|
2301
2513
|
this.subsessionStoppedParents.add(session);
|
|
2302
2514
|
const message = error instanceof Error ? error.message : String(error);
|
|
2303
|
-
this.publishActivity(session,
|
|
2515
|
+
this.publishActivity(session, { kind: "error" }, "error", message);
|
|
2304
2516
|
this.events.publish(session.sessionId, { type: "session.error", message }, eventScope);
|
|
2305
2517
|
if (this.isCurrentActiveSession(session)) {
|
|
2306
2518
|
const link = this.subsessionLinkForActiveChild(session);
|
|
@@ -2364,7 +2576,7 @@ export class PiSessionService {
|
|
|
2364
2576
|
const queue = this.compactionPromptQueues.get(sessionKey) ?? [];
|
|
2365
2577
|
queue.push({ kind, text, ...(images.length > 0 ? { images } : {}), ...(echoUserMessage ? {} : { echoUserMessage: false }) });
|
|
2366
2578
|
this.compactionPromptQueues.set(sessionKey, queue);
|
|
2367
|
-
this.publishActivity(session,
|
|
2579
|
+
this.publishActivity(session, { kind: "queuedDuringCompaction" }, "active");
|
|
2368
2580
|
this.publishStatus(session);
|
|
2369
2581
|
}
|
|
2370
2582
|
async saveAttachments(ref, attachments, folder, managementContext) {
|
|
@@ -2378,8 +2590,8 @@ export class PiSessionService {
|
|
|
2378
2590
|
return saveAttachmentsToWorkspace(cwd, parsed, effectiveFolder === undefined ? {} : { folder: effectiveFolder });
|
|
2379
2591
|
}
|
|
2380
2592
|
async workspaceAttachmentsConfig(cwd) {
|
|
2381
|
-
const
|
|
2382
|
-
return loadEffectiveProjectAttachmentsConfig(cwd,
|
|
2593
|
+
const response = this.config === undefined ? undefined : await this.config.read();
|
|
2594
|
+
return loadEffectiveProjectAttachmentsConfig(cwd, response?.effectiveConfig ?? {}, response?.enforcedSettings);
|
|
2383
2595
|
}
|
|
2384
2596
|
async shell(ref, text, managementContext) {
|
|
2385
2597
|
await this.assertWritable(ref, managementContext);
|
|
@@ -2393,11 +2605,11 @@ export class PiSessionService {
|
|
|
2393
2605
|
if (session.isBashRunning)
|
|
2394
2606
|
throw new Error(this.t("shell.alreadyRunning", "A bash command is already running"));
|
|
2395
2607
|
const eventScope = active.eventScope;
|
|
2396
|
-
this.publishActivity(session,
|
|
2608
|
+
this.publishActivity(session, { kind: "runningBash" }, "active", command);
|
|
2397
2609
|
this.events.publish(session.sessionId, { type: "shell.start", command, excludeFromContext: isExcluded }, eventScope);
|
|
2398
2610
|
void this.runSessionEntryMutation(session, this.t("session.action.shell", "run a shell command"), () => session.executeBash(command, (chunk) => {
|
|
2399
2611
|
this.events.publish(session.sessionId, { type: "shell.chunk", chunk }, eventScope);
|
|
2400
|
-
this.publishActivity(session,
|
|
2612
|
+
this.publishActivity(session, { kind: "runningBash" }, "active", command);
|
|
2401
2613
|
this.publishStatus(session);
|
|
2402
2614
|
}, { excludeFromContext: isExcluded })).then((result) => {
|
|
2403
2615
|
this.events.publish(session.sessionId, {
|
|
@@ -2408,13 +2620,13 @@ export class PiSessionService {
|
|
|
2408
2620
|
truncated: result.truncated,
|
|
2409
2621
|
...(result.fullOutputPath === undefined ? {} : { fullOutputPath: result.fullOutputPath }),
|
|
2410
2622
|
}, eventScope);
|
|
2411
|
-
this.publishActivity(session,
|
|
2623
|
+
this.publishActivity(session, { kind: "bashComplete" }, result.exitCode === 0 ? "idle" : "error", command);
|
|
2412
2624
|
this.publishStatus(session);
|
|
2413
2625
|
}).catch((error) => {
|
|
2414
2626
|
const message = userFacingErrorMessage(error, this.t);
|
|
2415
2627
|
this.events.publish(session.sessionId, { type: "shell.end", output: message, isError: true }, eventScope);
|
|
2416
2628
|
this.events.publish(session.sessionId, { type: "session.error", message }, eventScope);
|
|
2417
|
-
this.publishActivity(session,
|
|
2629
|
+
this.publishActivity(session, { kind: "bashFailed" }, "error", message);
|
|
2418
2630
|
this.publishStatus(session);
|
|
2419
2631
|
});
|
|
2420
2632
|
}
|
|
@@ -2461,7 +2673,7 @@ export class PiSessionService {
|
|
|
2461
2673
|
if (retainCustomMessage && options.summarize === true)
|
|
2462
2674
|
throw new Error(this.t("session.checkpointSummary", "Retaining a custom-message checkpoint requires navigation without a branch summary"));
|
|
2463
2675
|
const activeEditableTargetParentId = retainCustomMessage ? undefined : activeEditableTreeTargetParentId(session.sessionManager, targetId, oldLeafId);
|
|
2464
|
-
this.publishActivity(session, options.summarize === true ?
|
|
2676
|
+
this.publishActivity(session, options.summarize === true ? { kind: "summarizingBranch" } : { kind: "navigatingTree" }, "active");
|
|
2465
2677
|
this.publishStatus(session);
|
|
2466
2678
|
let result = retainCustomMessage
|
|
2467
2679
|
? await navigateTreeRetainingCustomMessage(session.sessionManager, targetId, checkpointTail["parentId"], () => navigateTree(targetId, options))
|
|
@@ -2482,7 +2694,7 @@ export class PiSessionService {
|
|
|
2482
2694
|
}
|
|
2483
2695
|
if (result.cancelled) {
|
|
2484
2696
|
if (this.isCurrentActiveSession(session)) {
|
|
2485
|
-
this.publishActivity(session, result.aborted === true ?
|
|
2697
|
+
this.publishActivity(session, result.aborted === true ? { kind: "branchSummaryAborted" } : { kind: "treeNavigationCancelled" }, "idle");
|
|
2486
2698
|
}
|
|
2487
2699
|
return { cancelled: true, ...(result.aborted === undefined ? {} : { aborted: result.aborted }) };
|
|
2488
2700
|
}
|
|
@@ -2497,13 +2709,13 @@ export class PiSessionService {
|
|
|
2497
2709
|
this.setSuggestedInput(session, result.editorText);
|
|
2498
2710
|
this.events.publish(session.sessionId, { type: "session.tree.changed" }, this.eventScopeForSession(session));
|
|
2499
2711
|
if (this.isCurrentActiveSession(session))
|
|
2500
|
-
this.publishActivity(session,
|
|
2712
|
+
this.publishActivity(session, { kind: "treeNavigated" }, "idle");
|
|
2501
2713
|
return { cancelled: false, ...(result.editorText === undefined ? {} : { editorText: result.editorText }) };
|
|
2502
2714
|
}
|
|
2503
2715
|
catch (error) {
|
|
2504
2716
|
const message = userFacingErrorMessage(error, this.t);
|
|
2505
2717
|
if (this.isCurrentActiveSession(session)) {
|
|
2506
|
-
this.publishActivity(session,
|
|
2718
|
+
this.publishActivity(session, { kind: "treeNavigationFailed" }, "error", message);
|
|
2507
2719
|
this.events.publish(session.sessionId, { type: "session.error", message }, this.eventScopeForSession(session));
|
|
2508
2720
|
}
|
|
2509
2721
|
throw error;
|
|
@@ -2516,7 +2728,6 @@ export class PiSessionService {
|
|
|
2516
2728
|
this.publishStatus(session);
|
|
2517
2729
|
}
|
|
2518
2730
|
else {
|
|
2519
|
-
this.deferredGeneratedSessionNames.delete(session);
|
|
2520
2731
|
this.subsessionInbox(session.sessionId, session.sessionFile, this.eventScopeForSession(session)).releaseClaims();
|
|
2521
2732
|
}
|
|
2522
2733
|
}
|
|
@@ -2543,7 +2754,7 @@ export class PiSessionService {
|
|
|
2543
2754
|
const sourceSessionId = session.sessionId;
|
|
2544
2755
|
const sourceEventScope = this.eventScopeForSession(session);
|
|
2545
2756
|
const sourceCwd = session.sessionManager.getCwd();
|
|
2546
|
-
this.publishActivity(session,
|
|
2757
|
+
this.publishActivity(session, { kind: "forking" }, "active");
|
|
2547
2758
|
this.publishStatus(session);
|
|
2548
2759
|
try {
|
|
2549
2760
|
const entryId = request.retainCheckpoint === true ? messageHistoryTargetId(session.sessionManager.getBranch(), request.entryId) : request.entryId;
|
|
@@ -2556,7 +2767,7 @@ export class PiSessionService {
|
|
|
2556
2767
|
throw new Error(this.t("server.main.0246b6af6843", "Session fork is unavailable"));
|
|
2557
2768
|
if (result.session === undefined) {
|
|
2558
2769
|
if (this.isCurrentActiveSession(session)) {
|
|
2559
|
-
this.publishActivity(session,
|
|
2770
|
+
this.publishActivity(session, { kind: "forkCancelled" }, "idle");
|
|
2560
2771
|
this.publishStatus(session);
|
|
2561
2772
|
}
|
|
2562
2773
|
return { cancelled: true };
|
|
@@ -2566,7 +2777,7 @@ export class PiSessionService {
|
|
|
2566
2777
|
this.setSuggestedInput(forked, result.promptDraft);
|
|
2567
2778
|
this.events.publish(sourceSessionId, { type: "session.tree.changed" }, sourceEventScope);
|
|
2568
2779
|
if (forked !== undefined && this.isCurrentActiveSession(forked)) {
|
|
2569
|
-
this.publishActivity(forked,
|
|
2780
|
+
this.publishActivity(forked, { kind: "forked" }, "idle");
|
|
2570
2781
|
this.publishStatus(forked);
|
|
2571
2782
|
}
|
|
2572
2783
|
if (result.session.id !== sourceSessionId)
|
|
@@ -2580,7 +2791,7 @@ export class PiSessionService {
|
|
|
2580
2791
|
catch (error) {
|
|
2581
2792
|
const message = userFacingErrorMessage(error, this.t);
|
|
2582
2793
|
if (this.isCurrentActiveSession(session)) {
|
|
2583
|
-
this.publishActivity(session,
|
|
2794
|
+
this.publishActivity(session, { kind: "forkFailed" }, "error", message);
|
|
2584
2795
|
this.events.publish(session.sessionId, { type: "session.error", message }, sourceEventScope);
|
|
2585
2796
|
this.publishStatus(session);
|
|
2586
2797
|
}
|
|
@@ -2591,7 +2802,7 @@ export class PiSessionService {
|
|
|
2591
2802
|
const sessionKey = activeSessionKey(sessionId, eventScope);
|
|
2592
2803
|
if (this.activities.get(sessionKey)?.phase === "active") {
|
|
2593
2804
|
const at = new Date().toISOString();
|
|
2594
|
-
const stored = { phase: "idle", label:
|
|
2805
|
+
const stored = { phase: "idle", label: "idle", at, runtimePresentation: { kind: "idle" } };
|
|
2595
2806
|
this.activities.set(sessionKey, stored);
|
|
2596
2807
|
const activity = { sessionId, ...stored };
|
|
2597
2808
|
this.events.publish(sessionId, { type: "activity.update", activity }, eventScope);
|
|
@@ -2607,6 +2818,7 @@ export class PiSessionService {
|
|
|
2607
2818
|
const archiveInput = await this.archiveInputForSession(session);
|
|
2608
2819
|
await this.closeActiveSession(active);
|
|
2609
2820
|
await this.archiveStore.archive(archiveInput);
|
|
2821
|
+
this.workspaceActivity?.removeSession(archiveInput.sessionId, archiveInput.cwd, active.eventScope);
|
|
2610
2822
|
await this.forgetUnreadSessions([archiveInput], active.eventScope);
|
|
2611
2823
|
});
|
|
2612
2824
|
}
|
|
@@ -2650,43 +2862,10 @@ export class PiSessionService {
|
|
|
2650
2862
|
failures.push({ sessionId: resolvedSessionId, error: errorMessage(error, this.t) });
|
|
2651
2863
|
}
|
|
2652
2864
|
}
|
|
2653
|
-
const
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
failures.push({ sessionId: item.input.sessionId, error: this.t("session.stopBeforeArchive", "Stop current session activity before archiving") });
|
|
2658
|
-
continue;
|
|
2659
|
-
}
|
|
2660
|
-
readyPlanItems.push(active === undefined ? item : { ...item, active });
|
|
2661
|
-
}
|
|
2662
|
-
const readyInputs = [];
|
|
2663
|
-
const archivedSessionIds = [...alreadyArchivedSessionIds];
|
|
2664
|
-
await this.runTreeExclusiveOperation(readyPlanItems.map(({ input, active }) => ({
|
|
2665
|
-
sessionId: input.sessionId,
|
|
2666
|
-
...(active === undefined ? {} : { session: active.runtime.session, runtime: active.runtime }),
|
|
2667
|
-
})), this.t("session.stopBeforeArchive", "Stop current session activity before archiving"), async () => {
|
|
2668
|
-
for (const item of readyPlanItems) {
|
|
2669
|
-
try {
|
|
2670
|
-
if (item.active !== undefined)
|
|
2671
|
-
await this.closeActiveSession(item.active);
|
|
2672
|
-
else
|
|
2673
|
-
await this.closeActiveInScope(item.input.sessionId, eventScopeFromManagementContext(managementContext));
|
|
2674
|
-
readyInputs.push(item.input);
|
|
2675
|
-
}
|
|
2676
|
-
catch (error) {
|
|
2677
|
-
failures.push({ sessionId: item.input.sessionId, error: errorMessage(error, this.t) });
|
|
2678
|
-
}
|
|
2679
|
-
}
|
|
2680
|
-
try {
|
|
2681
|
-
const archived = await this.archiveStoreArchiveMany(readyInputs);
|
|
2682
|
-
archivedSessionIds.push(...archived.map((record) => record.sessionId));
|
|
2683
|
-
unreadArchivedIdentities.push(...archived);
|
|
2684
|
-
}
|
|
2685
|
-
catch (error) {
|
|
2686
|
-
for (const input of readyInputs)
|
|
2687
|
-
failures.push({ sessionId: input.sessionId, error: errorMessage(error, this.t) });
|
|
2688
|
-
}
|
|
2689
|
-
});
|
|
2865
|
+
const execution = await this.executeArchiveBatch(planItems.map((item) => item.input), managementContext);
|
|
2866
|
+
failures.push(...execution.failures);
|
|
2867
|
+
failures.push(...execution.skippedBusySessionIds.map((sessionId) => ({ sessionId, error: this.t("session.stopBeforeArchive", "Stop current session activity before archiving") })));
|
|
2868
|
+
const archivedSessionIds = [...alreadyArchivedSessionIds, ...execution.successes.map((input) => input.sessionId)];
|
|
2690
2869
|
await this.forgetUnreadSessions(unreadArchivedIdentities, eventScopeFromManagementContext(managementContext));
|
|
2691
2870
|
return {
|
|
2692
2871
|
archived: true,
|
|
@@ -2714,7 +2893,9 @@ export class PiSessionService {
|
|
|
2714
2893
|
}
|
|
2715
2894
|
for (const input of archiveInputs)
|
|
2716
2895
|
await this.closeActiveInScope(input.sessionId, eventScopeFromManagementContext(managementContext));
|
|
2717
|
-
await this.archiveStoreArchiveMany(archiveInputs);
|
|
2896
|
+
const archived = await this.archiveStoreArchiveMany(archiveInputs);
|
|
2897
|
+
for (const record of archived)
|
|
2898
|
+
this.workspaceActivity?.removeSession(record.sessionId, record.cwd, eventScopeFromManagementContext(managementContext));
|
|
2718
2899
|
});
|
|
2719
2900
|
await this.forgetUnreadSessions(plan.targets.map((target) => ({ sessionId: target.id, cwd: target.cwd })), eventScopeFromManagementContext(managementContext));
|
|
2720
2901
|
return {
|
|
@@ -2727,10 +2908,15 @@ export class PiSessionService {
|
|
|
2727
2908
|
async restore(ref, managementContext) {
|
|
2728
2909
|
const archived = await this.getArchived(ref);
|
|
2729
2910
|
if (archived === undefined)
|
|
2730
|
-
throw new Error(
|
|
2731
|
-
|
|
2732
|
-
await this.
|
|
2733
|
-
|
|
2911
|
+
throw new Error("Session not found");
|
|
2912
|
+
const active = this.activeForLookup({ id: archived.sessionId, cwd: archived.cwd }, managementContext);
|
|
2913
|
+
await this.runTreeExclusiveOperation([{ sessionId: archived.sessionId, ...(active === undefined ? {} : { session: active.runtime.session, runtime: active.runtime }) }], "Stop current session activity before restoring archived session", async () => {
|
|
2914
|
+
await this.closeActiveInScope(archived.sessionId, eventScopeFromManagementContext(managementContext));
|
|
2915
|
+
await this.archiveStore.restore(archived.sessionId);
|
|
2916
|
+
const restored = (await this.sessionManager.list(archived.cwd)).find((entry) => entry.id === archived.sessionId);
|
|
2917
|
+
this.workspaceActivity?.applySessionIntervention(archived.cwd, archived.sessionId, restored?.interventionRequired === true, eventScopeFromManagementContext(managementContext));
|
|
2918
|
+
await this.forgetUnreadSessions([archived], eventScopeFromManagementContext(managementContext));
|
|
2919
|
+
});
|
|
2734
2920
|
}
|
|
2735
2921
|
async deleteArchived(ref, managementContext) {
|
|
2736
2922
|
const record = await this.getArchived(ref);
|
|
@@ -2762,27 +2948,10 @@ export class PiSessionService {
|
|
|
2762
2948
|
}
|
|
2763
2949
|
planItems.push({ record });
|
|
2764
2950
|
}
|
|
2765
|
-
const
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
readyRecords.push(item.record);
|
|
2770
|
-
}
|
|
2771
|
-
catch (error) {
|
|
2772
|
-
failures.push({ sessionId: item.record.sessionId, error: errorMessage(error, this.t) });
|
|
2773
|
-
}
|
|
2774
|
-
}
|
|
2775
|
-
const deleteIds = readyRecords.map((record) => record.sessionId);
|
|
2776
|
-
let deletedSessionIds = [];
|
|
2777
|
-
try {
|
|
2778
|
-
deletedSessionIds = await this.archiveStoreDeleteArchivedMany(deleteIds);
|
|
2779
|
-
}
|
|
2780
|
-
catch (error) {
|
|
2781
|
-
for (const sessionId of deleteIds)
|
|
2782
|
-
failures.push({ sessionId, error: errorMessage(error, this.t) });
|
|
2783
|
-
}
|
|
2784
|
-
const deletedIdSet = new Set(deletedSessionIds);
|
|
2785
|
-
await this.forgetUnreadSessions(readyRecords.filter((record) => deletedIdSet.has(record.sessionId)), eventScopeFromManagementContext(managementContext));
|
|
2951
|
+
const execution = await this.executeDeleteArchivedBatch(planItems.map((item) => item.record), managementContext);
|
|
2952
|
+
failures.push(...execution.failures);
|
|
2953
|
+
failures.push(...execution.skippedBusySessionIds.map((sessionId) => ({ sessionId, error: this.t("session.stopBeforeDeleteArchive", "Stop current session activity before deleting archived session") })));
|
|
2954
|
+
const deletedSessionIds = execution.successes.map((record) => record.sessionId);
|
|
2786
2955
|
return {
|
|
2787
2956
|
deleted: true,
|
|
2788
2957
|
deletedSessionIds,
|
|
@@ -2852,11 +3021,11 @@ export class PiSessionService {
|
|
|
2852
3021
|
this.abortRunScopedExtensionDialogs(active.runtime.session);
|
|
2853
3022
|
try {
|
|
2854
3023
|
await this.abortSessionOperations(active.runtime.session);
|
|
2855
|
-
this.publishActivity(active.runtime.session,
|
|
3024
|
+
this.publishActivity(active.runtime.session, { kind: "stopped" }, "idle");
|
|
2856
3025
|
}
|
|
2857
3026
|
catch (error) {
|
|
2858
3027
|
const message = userFacingErrorMessage(error, this.t);
|
|
2859
|
-
this.publishActivity(active.runtime.session,
|
|
3028
|
+
this.publishActivity(active.runtime.session, { kind: "stopFailed" }, "error", message);
|
|
2860
3029
|
throw error;
|
|
2861
3030
|
}
|
|
2862
3031
|
finally {
|
|
@@ -3017,6 +3186,58 @@ export class PiSessionService {
|
|
|
3017
3186
|
const entries = await Promise.all(uniqueCwds.map(async (cwd) => [cwd, await this.sessionManager.list(cwd)]));
|
|
3018
3187
|
return new Map(entries);
|
|
3019
3188
|
}
|
|
3189
|
+
executeArchiveBatch(inputs, context) {
|
|
3190
|
+
return this.executeSessionLifecycleBatch(inputs, "archive", async (ready) => (await this.archiveStoreArchiveMany(ready)).map((record) => record.sessionId), context);
|
|
3191
|
+
}
|
|
3192
|
+
executeDeleteArchivedBatch(records, context) {
|
|
3193
|
+
return this.executeSessionLifecycleBatch(records, "delete", (ready) => this.archiveStoreDeleteArchivedMany(ready.map((record) => record.sessionId)), context);
|
|
3194
|
+
}
|
|
3195
|
+
async executeSessionLifecycleBatch(items, reason, persist, context) {
|
|
3196
|
+
const scope = eventScopeFromManagementContext(context);
|
|
3197
|
+
const result = { successes: [], failures: [], skippedBusySessionIds: [] };
|
|
3198
|
+
const targets = [];
|
|
3199
|
+
const idleItems = [];
|
|
3200
|
+
// Check and reserve synchronously before any teardown can yield. Identity
|
|
3201
|
+
// reservations also protect unloaded sessions for the full persistence span.
|
|
3202
|
+
for (const item of items) {
|
|
3203
|
+
const active = this.activeForLookup({ id: item.sessionId, cwd: item.cwd }, context);
|
|
3204
|
+
if (this.isTreeExclusiveSessionIdentityActive(item.sessionId)
|
|
3205
|
+
|| (active !== undefined && this.hasActiveWork(active.runtime.session))) {
|
|
3206
|
+
result.skippedBusySessionIds.push(item.sessionId);
|
|
3207
|
+
continue;
|
|
3208
|
+
}
|
|
3209
|
+
idleItems.push(item);
|
|
3210
|
+
targets.push({ sessionId: item.sessionId, ...(active === undefined ? {} : { session: active.runtime.session, runtime: active.runtime }) });
|
|
3211
|
+
}
|
|
3212
|
+
await this.runTreeExclusiveOperation(targets, "Stop current session activity before changing session lifecycle", async () => {
|
|
3213
|
+
const ready = [];
|
|
3214
|
+
for (const item of idleItems) {
|
|
3215
|
+
try {
|
|
3216
|
+
await this.closeActive(item.sessionId, { kind: "clear", reason }, scope);
|
|
3217
|
+
ready.push(item);
|
|
3218
|
+
}
|
|
3219
|
+
catch (error) {
|
|
3220
|
+
result.failures.push({ sessionId: item.sessionId, error: errorMessage(error) });
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
try {
|
|
3224
|
+
const persistedIds = await persist(ready);
|
|
3225
|
+
const readyById = new Map(ready.map((item) => [item.sessionId, item]));
|
|
3226
|
+
result.successes = persistedIds.flatMap((sessionId) => {
|
|
3227
|
+
const item = readyById.get(sessionId);
|
|
3228
|
+
return item === undefined ? [] : [item];
|
|
3229
|
+
});
|
|
3230
|
+
}
|
|
3231
|
+
catch (error) {
|
|
3232
|
+
for (const item of ready)
|
|
3233
|
+
result.failures.push({ sessionId: item.sessionId, error: errorMessage(error) });
|
|
3234
|
+
}
|
|
3235
|
+
for (const item of result.successes)
|
|
3236
|
+
this.workspaceActivity?.removeSession(item.sessionId, item.cwd, scope);
|
|
3237
|
+
await this.forgetUnreadSessions(result.successes, scope);
|
|
3238
|
+
});
|
|
3239
|
+
return result;
|
|
3240
|
+
}
|
|
3020
3241
|
async archiveStoreArchiveMany(inputs) {
|
|
3021
3242
|
if (inputs.length === 0)
|
|
3022
3243
|
return [];
|
|
@@ -3040,6 +3261,9 @@ export class PiSessionService {
|
|
|
3040
3261
|
return [...sessionIds];
|
|
3041
3262
|
}
|
|
3042
3263
|
async cleanupPlan(request) {
|
|
3264
|
+
if (request.skipPinned === true && this.sessionPins === undefined)
|
|
3265
|
+
throw new Error("Authoritative session pin store is unavailable");
|
|
3266
|
+
const excludedPinnedSessionIds = request.skipPinned === true ? await this.sessionPins?.pinnedSessionIds() : undefined;
|
|
3043
3267
|
const [sessions, archivedRecords, scopedSessions] = await Promise.all([
|
|
3044
3268
|
this.sessionManager.listAll(),
|
|
3045
3269
|
this.archiveStore.list(),
|
|
@@ -3052,6 +3276,7 @@ export class PiSessionService {
|
|
|
3052
3276
|
archivedRecords,
|
|
3053
3277
|
activeSessions: this.cleanupActiveSessionStatuses(),
|
|
3054
3278
|
thresholds: request.thresholds,
|
|
3279
|
+
...(excludedPinnedSessionIds === undefined ? {} : { excludedPinnedSessionIds }),
|
|
3055
3280
|
...(request.projectCwds === undefined ? {} : { projectCwds: request.projectCwds }),
|
|
3056
3281
|
now: this.now(),
|
|
3057
3282
|
});
|
|
@@ -3183,6 +3408,10 @@ export class PiSessionService {
|
|
|
3183
3408
|
this.events.mediaIndex.forgetSession({ id: sessionId, cwd: active.runtime.session.sessionManager.getCwd(), eventScope: active.eventScope });
|
|
3184
3409
|
this.activities.delete(activeSessionKey(sessionId, active.eventScope));
|
|
3185
3410
|
this.workspaceActivity?.removeSession(sessionId, active.runtime.session.sessionManager.getCwd(), active.eventScope);
|
|
3411
|
+
const session = active.runtime.session;
|
|
3412
|
+
if (sessionFileExists(session.sessionFile) && this.interventionRequired(session)) {
|
|
3413
|
+
this.workspaceActivity?.applySessionIntervention(session.sessionManager.getCwd(), sessionId, true, active.eventScope);
|
|
3414
|
+
}
|
|
3186
3415
|
this.clearAuthLossWarningsForSession(sessionId);
|
|
3187
3416
|
this.clearCompactionPromptQueue(active.runtime.session);
|
|
3188
3417
|
// Disarm subsession notification before teardown so the abort below cannot
|
|
@@ -3437,7 +3666,7 @@ export class PiSessionService {
|
|
|
3437
3666
|
operation.error(message);
|
|
3438
3667
|
return;
|
|
3439
3668
|
}
|
|
3440
|
-
this.publishActivity(session,
|
|
3669
|
+
this.publishActivity(session, { kind: "extensionError" }, "error", message);
|
|
3441
3670
|
this.events.publish(session.sessionId, { type: "session.error", message }, owner.eventScope);
|
|
3442
3671
|
},
|
|
3443
3672
|
});
|
|
@@ -3493,7 +3722,7 @@ export class PiSessionService {
|
|
|
3493
3722
|
if (current !== undefined && this.isCurrentActiveSession(current)) {
|
|
3494
3723
|
const message = userFacingErrorMessage(error, this.t);
|
|
3495
3724
|
current.extensionRunner.getUIContext().notify(message, "error");
|
|
3496
|
-
this.publishActivity(current,
|
|
3725
|
+
this.publishActivity(current, { kind: "extensionCallbackFailed" }, "error", message);
|
|
3497
3726
|
this.events.publish(current.sessionId, { type: "session.error", message }, this.eventScopeForSession(current));
|
|
3498
3727
|
}
|
|
3499
3728
|
throw error;
|
|
@@ -3546,12 +3775,17 @@ export class PiSessionService {
|
|
|
3546
3775
|
}
|
|
3547
3776
|
this.reconcileRuntimeMessageCount(session);
|
|
3548
3777
|
this.restoreSubsessionReceipts(session);
|
|
3778
|
+
this.interventionStates.set(session, sessionInterventionRequired(session.sessionManager.getEntries?.() ?? session.sessionManager.getBranch()));
|
|
3779
|
+
this.publishedSessionNames.set(session, { sessionId: session.sessionId, name: session.sessionName });
|
|
3549
3780
|
const unsubscribe = session.subscribe((event) => {
|
|
3550
3781
|
const eventType = getString(event, "type");
|
|
3782
|
+
if (eventType === "session_info_changed")
|
|
3783
|
+
this.publishSessionName(session);
|
|
3551
3784
|
const message = getProperty(event, "message");
|
|
3552
3785
|
const entry = getProperty(event, "entry");
|
|
3553
3786
|
const inbox = this.subsessionInbox(session.sessionId, session.sessionFile, active.eventScope);
|
|
3554
3787
|
if (eventType === "agent_start") {
|
|
3788
|
+
this.setInterventionRequired(session, false);
|
|
3555
3789
|
this.restoreSubsessionReceipts(session, false);
|
|
3556
3790
|
this.subsessionStoppedParents.delete(session);
|
|
3557
3791
|
}
|
|
@@ -3566,6 +3800,8 @@ export class PiSessionService {
|
|
|
3566
3800
|
if (eventType === "agent_settled")
|
|
3567
3801
|
this.scheduleSubsessionDelivery(session);
|
|
3568
3802
|
const role = getString(message, "role");
|
|
3803
|
+
if (eventType === "message_end" && requestsHumanIntervention(message))
|
|
3804
|
+
this.setInterventionRequired(session, true);
|
|
3569
3805
|
if ((eventType === "message_end" && (role === "user" || role === "assistant" || role === "toolResult" || role === "system"))
|
|
3570
3806
|
|| (eventType === "entry_appended" && getString(entry, "type") === "message")) {
|
|
3571
3807
|
this.runtimeMessageCounts.set(session, this.runtimeMessageCount(session) + 1);
|
|
@@ -3622,18 +3858,21 @@ export class PiSessionService {
|
|
|
3622
3858
|
const aborted = getBoolean(event, "aborted") === true;
|
|
3623
3859
|
const errorMessage = getString(event, "errorMessage");
|
|
3624
3860
|
const automatic = getString(event, "reason") !== "manual";
|
|
3625
|
-
const
|
|
3626
|
-
?
|
|
3627
|
-
: errorMessage === undefined ? undefined :
|
|
3861
|
+
const presentation = aborted
|
|
3862
|
+
? { kind: automatic ? "automaticCompactionCancelled" : "compactionCancelled" }
|
|
3863
|
+
: errorMessage === undefined ? undefined : { kind: "compactionFailed" };
|
|
3864
|
+
const message = presentation === undefined ? undefined : sessionNotificationSources[presentation.kind];
|
|
3628
3865
|
if (!aborted && errorMessage !== undefined) {
|
|
3629
3866
|
this.events.publish(session.sessionId, { type: "session.diagnostic", message: errorMessage }, this.eventScopeForSession(session));
|
|
3630
3867
|
}
|
|
3631
|
-
this.publishActivity(session, aborted
|
|
3868
|
+
this.publishActivity(session, aborted
|
|
3869
|
+
? { kind: "compactionCancelled", detailKind: automatic ? "automaticCompactionCancelled" : "compactionCancelled" }
|
|
3870
|
+
: errorMessage === undefined ? { kind: "compactionComplete" } : { kind: "compactionFailed", detailKind: "compactionFailed" }, !aborted && errorMessage !== undefined ? "error" : "idle", message);
|
|
3632
3871
|
// Successful compaction already has a canonical summary in the transcript.
|
|
3633
3872
|
// Keep cancellation/failure feedback in the refresh-safe session inbox only.
|
|
3634
3873
|
const generation = this.notificationGenerationBySession.get(session);
|
|
3635
3874
|
if (message !== undefined && generation !== undefined) {
|
|
3636
|
-
this.publishNotificationMutations(this.notificationsForSession(session).addNotification(generation, message, aborted ? "info" : "error").mutations);
|
|
3875
|
+
this.publishNotificationMutations(this.notificationsForSession(session).addNotification(generation, message, aborted ? "info" : "error", presentation).mutations);
|
|
3637
3876
|
}
|
|
3638
3877
|
}
|
|
3639
3878
|
scheduleCompactionQueueDrain(session, delayMs = 0) {
|
|
@@ -3711,43 +3950,6 @@ export class PiSessionService {
|
|
|
3711
3950
|
clearTimeout(timer);
|
|
3712
3951
|
this.compactionDrainTimers.clear();
|
|
3713
3952
|
}
|
|
3714
|
-
maybeGenerateSessionName(session, firstMessage) {
|
|
3715
|
-
if (session.sessionName !== undefined || session.messages.length !== 0 || session.isStreaming || session.isCompacting)
|
|
3716
|
-
return;
|
|
3717
|
-
void this.generateSessionName(session, firstMessage).then((name) => {
|
|
3718
|
-
if (name === undefined)
|
|
3719
|
-
this.logger.info({ sessionId: session.sessionId }, "Session naming returned no title; using the first-message fallback");
|
|
3720
|
-
this.applyGeneratedSessionName(session, name ?? fallbackSessionName(firstMessage));
|
|
3721
|
-
}).catch((error) => {
|
|
3722
|
-
const errorCategory = error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError") ? "timeout" : "generation";
|
|
3723
|
-
this.logger.info({ sessionId: session.sessionId, errorCategory }, "Session naming failed; using the first-message fallback");
|
|
3724
|
-
this.applyGeneratedSessionName(session, fallbackSessionName(firstMessage));
|
|
3725
|
-
});
|
|
3726
|
-
}
|
|
3727
|
-
async generateSessionName(session, firstMessage) {
|
|
3728
|
-
// One request keeps its settings even if the operator edits the config while it runs.
|
|
3729
|
-
const naming = this.config === undefined ? {} : (await this.config.read()).effectiveConfig.sessionNaming ?? {};
|
|
3730
|
-
let model = session.model;
|
|
3731
|
-
if (naming.model !== undefined) {
|
|
3732
|
-
const parsed = parseModelSpec(naming.model);
|
|
3733
|
-
model = parsed === undefined ? undefined : session.modelRuntime.getModel(parsed.provider, parsed.modelId);
|
|
3734
|
-
if (model === undefined)
|
|
3735
|
-
throw new Error("Configured session naming model is unavailable");
|
|
3736
|
-
}
|
|
3737
|
-
if (model === undefined)
|
|
3738
|
-
return undefined;
|
|
3739
|
-
return generateShortSessionName(session.agent.streamFunction, model, firstMessage, naming);
|
|
3740
|
-
}
|
|
3741
|
-
applyGeneratedSessionName(session, name) {
|
|
3742
|
-
if (name === undefined || session.sessionName !== undefined)
|
|
3743
|
-
return;
|
|
3744
|
-
if (this.treeNavigations.has(session)) {
|
|
3745
|
-
this.deferredGeneratedSessionNames.set(session, name);
|
|
3746
|
-
return;
|
|
3747
|
-
}
|
|
3748
|
-
session.setSessionName(name);
|
|
3749
|
-
this.publishSessionName(session);
|
|
3750
|
-
}
|
|
3751
3953
|
applyAuthChange(change) {
|
|
3752
3954
|
const changedRuntime = change.modelRuntime;
|
|
3753
3955
|
for (const active of this.active.values()) {
|
|
@@ -3778,7 +3980,8 @@ export class PiSessionService {
|
|
|
3778
3980
|
this.events.publish(session.sessionId, {
|
|
3779
3981
|
type: "command.output",
|
|
3780
3982
|
level: "error",
|
|
3781
|
-
message:
|
|
3983
|
+
message: `Authentication for ${model.provider}/${model.id} was removed. Use /model to select another model.`,
|
|
3984
|
+
presentation: { kind: "modelAuthRemoved", provider: model.provider, model: model.id },
|
|
3782
3985
|
}, eventScope);
|
|
3783
3986
|
}
|
|
3784
3987
|
clearAuthLossWarningsForSession(sessionId) {
|
|
@@ -3788,6 +3991,10 @@ export class PiSessionService {
|
|
|
3788
3991
|
}
|
|
3789
3992
|
}
|
|
3790
3993
|
publishSessionName(session) {
|
|
3994
|
+
const previous = this.publishedSessionNames.get(session);
|
|
3995
|
+
if (previous?.sessionId === session.sessionId && previous.name === session.sessionName)
|
|
3996
|
+
return;
|
|
3997
|
+
this.publishedSessionNames.set(session, { sessionId: session.sessionId, name: session.sessionName });
|
|
3791
3998
|
const event = session.sessionName === undefined
|
|
3792
3999
|
? { type: "session.name", sessionId: session.sessionId }
|
|
3793
4000
|
: { type: "session.name", sessionId: session.sessionId, name: session.sessionName };
|
|
@@ -3811,25 +4018,25 @@ export class PiSessionService {
|
|
|
3811
4018
|
}
|
|
3812
4019
|
this.publishStatus(session);
|
|
3813
4020
|
if (activity?.phase === "active")
|
|
3814
|
-
this.publishActivity(session, activity.
|
|
4021
|
+
this.publishActivity(session, activity.runtimePresentation, "active", activity.detail);
|
|
3815
4022
|
else
|
|
3816
|
-
this.publishActivity(session, this.
|
|
4023
|
+
this.publishActivity(session, this.activityPresentationFromStatus(session), "active");
|
|
3817
4024
|
}
|
|
3818
4025
|
}
|
|
3819
|
-
|
|
4026
|
+
activityPresentationFromStatus(session) {
|
|
3820
4027
|
if (this.treeNavigations.has(session))
|
|
3821
|
-
return
|
|
4028
|
+
return { kind: "navigatingTree" };
|
|
3822
4029
|
if (this.isSessionEntryMutationActive(session))
|
|
3823
|
-
return
|
|
4030
|
+
return { kind: "updatingSession" };
|
|
3824
4031
|
if (session.isCompacting)
|
|
3825
|
-
return
|
|
4032
|
+
return { kind: "compacting" };
|
|
3826
4033
|
if (session.isBashRunning)
|
|
3827
|
-
return
|
|
4034
|
+
return { kind: "runningBash" };
|
|
3828
4035
|
if (session.isStreaming)
|
|
3829
|
-
return
|
|
4036
|
+
return { kind: "agentRunning" };
|
|
3830
4037
|
if (this.pendingMessageCount(session) > 0)
|
|
3831
|
-
return
|
|
3832
|
-
return
|
|
4038
|
+
return { kind: "queued" };
|
|
4039
|
+
return { kind: "active" };
|
|
3833
4040
|
}
|
|
3834
4041
|
hasActiveWork(session) {
|
|
3835
4042
|
const execution = this.extensionCommandExecution.getStore();
|
|
@@ -3934,56 +4141,56 @@ export class PiSessionService {
|
|
|
3934
4141
|
if (eventType === undefined)
|
|
3935
4142
|
return;
|
|
3936
4143
|
if (eventType === "agent_start") {
|
|
3937
|
-
this.publishActivity(session,
|
|
4144
|
+
this.publishActivity(session, { kind: "agentRunning" }, "active");
|
|
3938
4145
|
return;
|
|
3939
4146
|
}
|
|
3940
4147
|
if (eventType === "agent_end") {
|
|
3941
|
-
this.publishActivity(session,
|
|
4148
|
+
this.publishActivity(session, { kind: "idle" }, "idle");
|
|
3942
4149
|
const eventScope = this.eventScopeForSession(session);
|
|
3943
4150
|
const sessionKey = activeSessionKey(session.sessionId, eventScope);
|
|
3944
4151
|
this.activities.scheduleSettledRefresh(sessionKey, () => {
|
|
3945
4152
|
if (this.active.get(sessionKey)?.runtime.session !== session)
|
|
3946
4153
|
return;
|
|
3947
|
-
this.publishActivity(session,
|
|
4154
|
+
this.publishActivity(session, { kind: "idle" }, "idle");
|
|
3948
4155
|
this.publishStatus(session);
|
|
3949
4156
|
}, 250);
|
|
3950
4157
|
return;
|
|
3951
4158
|
}
|
|
3952
4159
|
if (eventType === "turn_end") {
|
|
3953
|
-
this.publishActivity(session,
|
|
4160
|
+
this.publishActivity(session, { kind: "turnComplete" }, "idle");
|
|
3954
4161
|
return;
|
|
3955
4162
|
}
|
|
3956
4163
|
if (eventType === "message_start") {
|
|
3957
|
-
this.publishActivity(session,
|
|
4164
|
+
this.publishActivity(session, { kind: "messageStarted" }, "active");
|
|
3958
4165
|
return;
|
|
3959
4166
|
}
|
|
3960
4167
|
if (eventType === "message_end") {
|
|
3961
|
-
this.publishActivity(session,
|
|
4168
|
+
this.publishActivity(session, { kind: "messageComplete" }, "idle");
|
|
3962
4169
|
return;
|
|
3963
4170
|
}
|
|
3964
4171
|
if (eventType === "message_update") {
|
|
3965
|
-
this.publishActivity(session,
|
|
4172
|
+
this.publishActivity(session, { kind: "receivingResponse" }, "active");
|
|
3966
4173
|
return;
|
|
3967
4174
|
}
|
|
3968
4175
|
if (eventType === "tool_execution_start") {
|
|
3969
|
-
this.publishActivity(session,
|
|
4176
|
+
this.publishActivity(session, { kind: "runningTool" }, "active", getString(event, "toolName"));
|
|
3970
4177
|
return;
|
|
3971
4178
|
}
|
|
3972
4179
|
if (eventType === "tool_execution_end") {
|
|
3973
4180
|
const isError = getBoolean(event, "isError") === true;
|
|
3974
|
-
this.publishActivity(session, isError ?
|
|
4181
|
+
this.publishActivity(session, isError ? { kind: "toolFailed" } : { kind: "toolComplete" }, isError ? "error" : "idle", getString(event, "toolName"));
|
|
3975
4182
|
return;
|
|
3976
4183
|
}
|
|
3977
4184
|
if (eventType === "bash_execution_start") {
|
|
3978
|
-
this.publishActivity(session,
|
|
4185
|
+
this.publishActivity(session, { kind: "runningBash" }, "active");
|
|
3979
4186
|
return;
|
|
3980
4187
|
}
|
|
3981
4188
|
if (eventType === "bash_execution_end") {
|
|
3982
|
-
this.publishActivity(session,
|
|
4189
|
+
this.publishActivity(session, { kind: "bashComplete" }, "idle");
|
|
3983
4190
|
return;
|
|
3984
4191
|
}
|
|
3985
4192
|
if (this.hasActiveWork(session))
|
|
3986
|
-
this.publishActivity(session,
|
|
4193
|
+
this.publishActivity(session, { kind: "event", value: eventType }, "active");
|
|
3987
4194
|
}
|
|
3988
4195
|
auditToolExecutionEvent(active, event) {
|
|
3989
4196
|
const eventType = getString(event, "type");
|
|
@@ -4080,23 +4287,23 @@ export class PiSessionService {
|
|
|
4080
4287
|
const sessionId = sessionManager.getSessionId();
|
|
4081
4288
|
if (sessionId === "")
|
|
4082
4289
|
return { report: noop, end: noop };
|
|
4083
|
-
const label = intent === "create" ?
|
|
4290
|
+
const label = intent === "create" ? "Creating session" : "Opening session";
|
|
4084
4291
|
return {
|
|
4085
|
-
report: (
|
|
4292
|
+
report: (stage) => {
|
|
4293
|
+
const catalogRefreshing = this.catalogRefreshStatus?.isRefreshInFlight() === true;
|
|
4294
|
+
const phase = stage === "runtime" ? STARTUP_PHASE_RUNTIME : STARTUP_PHASE_EXTENSIONS;
|
|
4295
|
+
const detail = catalogRefreshing ? `${phase} · ${STARTUP_CONCURRENT_CATALOG_REFRESH}` : phase;
|
|
4296
|
+
this.publishStartupProgress(sessionId, startupToken, label, "active", detail, eventScope, { intent, stage, catalogRefreshing });
|
|
4297
|
+
},
|
|
4086
4298
|
end: () => {
|
|
4087
4299
|
// A real activity published during the window (an extension error, say)
|
|
4088
4300
|
// is the truth about this session and must survive the clear.
|
|
4089
4301
|
if (this.activities.get(activeSessionKey(sessionId, eventScope)) !== undefined)
|
|
4090
4302
|
return;
|
|
4091
|
-
this.publishStartupProgress(sessionId, startupToken,
|
|
4303
|
+
this.publishStartupProgress(sessionId, startupToken, "Idle", "idle", undefined, eventScope);
|
|
4092
4304
|
},
|
|
4093
4305
|
};
|
|
4094
4306
|
}
|
|
4095
|
-
startupDetail(phase) {
|
|
4096
|
-
return this.catalogRefreshStatus?.isRefreshInFlight() === true
|
|
4097
|
-
? `${phase} · ${this.t("startup.catalogRefresh", "Provider model catalog is refreshing")}`
|
|
4098
|
-
: phase;
|
|
4099
|
-
}
|
|
4100
4307
|
/**
|
|
4101
4308
|
* Report startup progress on the global channel only, echoing the caller's
|
|
4102
4309
|
* correlation token so a waiting browser row recognises its own construction.
|
|
@@ -4110,17 +4317,21 @@ export class PiSessionService {
|
|
|
4110
4317
|
* that sets the marker, and because it writes no `activities` entry no later
|
|
4111
4318
|
* heartbeat re-publication can carry it.
|
|
4112
4319
|
*/
|
|
4113
|
-
publishStartupProgress(sessionId, startupToken, label, phase, detail, eventScope) {
|
|
4320
|
+
publishStartupProgress(sessionId, startupToken, label, phase, detail, eventScope, startupPresentation) {
|
|
4114
4321
|
const at = new Date().toISOString();
|
|
4115
|
-
const activity =
|
|
4322
|
+
const activity = { sessionId, phase, label, at, startup: true,
|
|
4323
|
+
...(detail === undefined ? {} : { detail }),
|
|
4324
|
+
...(startupPresentation === undefined ? {} : { startupPresentation }),
|
|
4325
|
+
};
|
|
4116
4326
|
this.events.publishGlobal(startupToken === undefined ? { type: "session.startup", activity } : { type: "session.startup", startupToken, activity }, eventScope);
|
|
4117
4327
|
}
|
|
4118
|
-
publishActivity(session,
|
|
4328
|
+
publishActivity(session, runtimePresentation, phase, detail) {
|
|
4119
4329
|
const at = new Date().toISOString();
|
|
4120
|
-
const
|
|
4330
|
+
const label = runtimeActivityFallbackLabel(runtimePresentation);
|
|
4331
|
+
const stored = { phase, label, at, runtimePresentation, ...(detail === undefined ? {} : { detail }) };
|
|
4121
4332
|
const eventScope = this.eventScopeForSession(session);
|
|
4122
4333
|
this.activities.set(activeSessionKey(session.sessionId, eventScope), stored);
|
|
4123
|
-
const activity =
|
|
4334
|
+
const activity = { sessionId: session.sessionId, ...stored };
|
|
4124
4335
|
this.workspaceActivity?.applySessionActivity(session.sessionManager.getCwd(), activity, eventScope);
|
|
4125
4336
|
this.events.publish(session.sessionId, { type: "activity.update", activity }, eventScope);
|
|
4126
4337
|
this.events.publishGlobal({ type: "activity.update", activity }, eventScope);
|
|
@@ -4145,6 +4356,26 @@ export class PiSessionService {
|
|
|
4145
4356
|
if (path !== undefined)
|
|
4146
4357
|
this.managementMediaFiles.add(path);
|
|
4147
4358
|
}
|
|
4359
|
+
interventionRequired(session) {
|
|
4360
|
+
return this.interventionStates.get(session)
|
|
4361
|
+
?? sessionInterventionRequired(session.sessionManager.getEntries?.() ?? session.sessionManager.getBranch());
|
|
4362
|
+
}
|
|
4363
|
+
setInterventionRequired(session, required) {
|
|
4364
|
+
const previous = this.interventionRequired(session);
|
|
4365
|
+
if (previous === required)
|
|
4366
|
+
return;
|
|
4367
|
+
if (session.sessionManager.appendCustomEntry === undefined)
|
|
4368
|
+
throw new Error("Session manager cannot persist intervention state");
|
|
4369
|
+
// Update before append: the SDK emits entry_appended synchronously.
|
|
4370
|
+
this.interventionStates.set(session, required);
|
|
4371
|
+
try {
|
|
4372
|
+
session.sessionManager.appendCustomEntry(SESSION_INTERVENTION_CUSTOM_TYPE, { version: 1, required });
|
|
4373
|
+
}
|
|
4374
|
+
catch (error) {
|
|
4375
|
+
this.interventionStates.set(session, previous);
|
|
4376
|
+
throw error;
|
|
4377
|
+
}
|
|
4378
|
+
}
|
|
4148
4379
|
publishStatus(session) {
|
|
4149
4380
|
this.rememberManagementMediaFile(session, this.eventScopeForSession(session));
|
|
4150
4381
|
void this.refreshActivityMarker(session);
|
|
@@ -4162,7 +4393,7 @@ export class PiSessionService {
|
|
|
4162
4393
|
if (current?.phase !== "active" || this.hasActiveWork(session))
|
|
4163
4394
|
return;
|
|
4164
4395
|
const at = new Date().toISOString();
|
|
4165
|
-
const stored = { phase: "idle", label:
|
|
4396
|
+
const stored = { phase: "idle", label: "idle", at, runtimePresentation: { kind: "idle" } };
|
|
4166
4397
|
this.activities.set(activeSessionKey(session.sessionId, eventScope), stored);
|
|
4167
4398
|
const activity = { sessionId: session.sessionId, ...stored };
|
|
4168
4399
|
this.events.publish(session.sessionId, { type: "activity.update", activity }, eventScope);
|
|
@@ -4233,6 +4464,7 @@ export class PiSessionService {
|
|
|
4233
4464
|
sessionId: session.sessionId,
|
|
4234
4465
|
persisted: sessionFileExists(session.sessionFile),
|
|
4235
4466
|
recentlyActiveElsewhere: this.eventScopeForSession(session) === NORMAL_SESSION_EVENT_SCOPE && this.activityMarker.isActiveElsewhere(session.sessionFile),
|
|
4467
|
+
interventionRequired: this.interventionRequired(session) || pendingDialogs.length > 0,
|
|
4236
4468
|
...(model === undefined ? {} : { model }),
|
|
4237
4469
|
thinkingLevel: session.thinkingLevel,
|
|
4238
4470
|
isStreaming: session.isStreaming,
|
|
@@ -4314,8 +4546,22 @@ export class PiSessionService {
|
|
|
4314
4546
|
return this.unreadForScope(eventScope).durableCatalogSnapshot();
|
|
4315
4547
|
}
|
|
4316
4548
|
async reconcileUnreadWorkspaces(cwds) {
|
|
4549
|
+
this.unreadEligibilityRevision += 1;
|
|
4317
4550
|
await this.publishUnreadMutations(this.unreadStore.reconcileWorkspaces(cwds));
|
|
4318
4551
|
}
|
|
4552
|
+
async markUnread(sessionId, cwd, context) {
|
|
4553
|
+
const canonicalCwd = canonicalizeStoredCwd(cwd);
|
|
4554
|
+
const eligibilityRevision = this.unreadEligibilityRevision;
|
|
4555
|
+
const rows = await this.list(canonicalCwd, context);
|
|
4556
|
+
const row = rows.find((candidate) => candidate.id === sessionId && cwdPathsEqual(candidate.cwd, canonicalCwd));
|
|
4557
|
+
if (eligibilityRevision !== this.unreadEligibilityRevision
|
|
4558
|
+
|| row === undefined || row.archived === true || row.persisted !== true || row.agentSubsession === true) {
|
|
4559
|
+
throw new Error("Session is not eligible to be marked unread");
|
|
4560
|
+
}
|
|
4561
|
+
const store = this.unreadForScope(eventScopeFromManagementContext(context));
|
|
4562
|
+
await this.publishUnreadMutations(store.markUnread(sessionId, canonicalCwd));
|
|
4563
|
+
return store.durableCatalogSnapshot();
|
|
4564
|
+
}
|
|
4319
4565
|
async acknowledgeUnread(sessionId, request, context) {
|
|
4320
4566
|
const store = this.unreadForScope(eventScopeFromManagementContext(context));
|
|
4321
4567
|
const result = store.acknowledge(sessionId, {
|
|
@@ -4345,7 +4591,7 @@ export class PiSessionService {
|
|
|
4345
4591
|
if (this.hasActiveWork(session))
|
|
4346
4592
|
throw new Error(this.t("session.stopBeforeReload", "Stop current session activity before reloading"));
|
|
4347
4593
|
await this.runTreeExclusiveOperation([{ sessionId: session.sessionId, session }], this.t("session.stopBeforeReload", "Stop current session activity before reloading"), async () => {
|
|
4348
|
-
this.publishActivity(session,
|
|
4594
|
+
this.publishActivity(session, { kind: "reloading" }, "active");
|
|
4349
4595
|
const priorGeneration = this.notificationGenerationBySession.get(session);
|
|
4350
4596
|
let candidateGeneration;
|
|
4351
4597
|
const reloadBoundary = { beforeSessionStart: false };
|
|
@@ -4365,7 +4611,7 @@ export class PiSessionService {
|
|
|
4365
4611
|
if (candidateGeneration !== undefined) {
|
|
4366
4612
|
this.publishNotificationMutations(this.notificationsForSession(session).commitReplacement(candidateGeneration));
|
|
4367
4613
|
}
|
|
4368
|
-
this.publishActivity(session,
|
|
4614
|
+
this.publishActivity(session, { kind: "reloaded" }, "idle");
|
|
4369
4615
|
this.publishStatus(session);
|
|
4370
4616
|
}
|
|
4371
4617
|
catch (error) {
|
|
@@ -4376,7 +4622,7 @@ export class PiSessionService {
|
|
|
4376
4622
|
this.notificationGenerationBySession.set(session, candidateGeneration);
|
|
4377
4623
|
}
|
|
4378
4624
|
const message = error instanceof Error ? error.message : String(error);
|
|
4379
|
-
this.publishActivity(session,
|
|
4625
|
+
this.publishActivity(session, { kind: "reloadFailed" }, "error", message);
|
|
4380
4626
|
this.events.publish(session.sessionId, { type: "session.error", message }, this.eventScopeForSession(session));
|
|
4381
4627
|
this.publishStatus(session);
|
|
4382
4628
|
throw error;
|
|
@@ -4396,7 +4642,7 @@ export class PiSessionService {
|
|
|
4396
4642
|
return [...this.active.values()].some((active) => active.runtime.session === session);
|
|
4397
4643
|
}
|
|
4398
4644
|
async createSessionRuntime(sessionManager, cwd, options, startup) {
|
|
4399
|
-
startup.report(
|
|
4645
|
+
startup.report("runtime");
|
|
4400
4646
|
options.startupSignal?.throwIfAborted();
|
|
4401
4647
|
// Ordinary local sessions (undefined provenance) keep the current rule.
|
|
4402
4648
|
// Only an explicit host one-shot forces delegation off; do not treat every
|
|
@@ -4463,7 +4709,7 @@ export class PiSessionService {
|
|
|
4463
4709
|
await this.recoverSubsessionTrackingForOpenedSession(runtime.session);
|
|
4464
4710
|
}
|
|
4465
4711
|
startupSignal?.throwIfAborted();
|
|
4466
|
-
startup.report(
|
|
4712
|
+
startup.report("extensions");
|
|
4467
4713
|
// Startup hooks emit through the same scoped stream as hosted turns.
|
|
4468
4714
|
this.bindRuntime(active);
|
|
4469
4715
|
await this.bindSessionExtensions(runtime.session, notificationGeneration, active, startupSignal);
|
|
@@ -4618,12 +4864,15 @@ export class PiSessionService {
|
|
|
4618
4864
|
const nextCwd = canonicalizeStoredCwd(next.sessionManager.getCwd());
|
|
4619
4865
|
if (previous.sessionId === next.sessionId && cwdPathsEqual(previousCwd, nextCwd))
|
|
4620
4866
|
return;
|
|
4867
|
+
this.unreadEligibilityRevision += 1;
|
|
4621
4868
|
await this.publishUnreadMutations(store.forgetSession(previous.sessionId, previousCwd));
|
|
4622
4869
|
}
|
|
4623
4870
|
forgetUnreadActivity(session) {
|
|
4624
4871
|
this.unreadForScope(this.eventScopeForSession(session)).forgetActivity(session.sessionId, canonicalizeStoredCwd(session.sessionManager.getCwd()));
|
|
4625
4872
|
}
|
|
4626
4873
|
async forgetUnreadSessions(identities, scope = NORMAL_SESSION_EVENT_SCOPE) {
|
|
4874
|
+
if (identities.length > 0)
|
|
4875
|
+
this.unreadEligibilityRevision += 1;
|
|
4627
4876
|
const mutations = [];
|
|
4628
4877
|
for (const identity of identities) {
|
|
4629
4878
|
mutations.push(...this.unreadForScope(scope).forgetSession(identity.sessionId, canonicalizeStoredCwd(identity.cwd)));
|
|
@@ -4727,16 +4976,6 @@ export class PiSessionService {
|
|
|
4727
4976
|
this.unreadPublicationRetryDelayMs = this.unreadPublicationRetryInitialMs;
|
|
4728
4977
|
}
|
|
4729
4978
|
flushDeferredTreeNavigationWork(session) {
|
|
4730
|
-
const generatedName = this.deferredGeneratedSessionNames.get(session);
|
|
4731
|
-
this.deferredGeneratedSessionNames.delete(session);
|
|
4732
|
-
if (generatedName !== undefined) {
|
|
4733
|
-
try {
|
|
4734
|
-
this.applyGeneratedSessionName(session, generatedName);
|
|
4735
|
-
}
|
|
4736
|
-
catch (error) {
|
|
4737
|
-
this.logger.info({ sessionId: session.sessionId, error: error instanceof Error ? error.message : String(error) }, "failed to apply deferred session name");
|
|
4738
|
-
}
|
|
4739
|
-
}
|
|
4740
4979
|
this.restoreSubsessionReceipts(session);
|
|
4741
4980
|
this.scheduleSubsessionDelivery(session);
|
|
4742
4981
|
}
|
|
@@ -4875,8 +5114,8 @@ export class PiSessionService {
|
|
|
4875
5114
|
}, 0);
|
|
4876
5115
|
}
|
|
4877
5116
|
assertMcpModeAllowed(managementContext) {
|
|
4878
|
-
if (VERSION !== "1.3.0")
|
|
4879
|
-
throw new UserFacingError("mcpAuth.sdkUnsupported", "Dedicated MCP authentication requires Pi 1.3.0");
|
|
5117
|
+
if (VERSION !== "1.3.0" && VERSION !== "1.4.0")
|
|
5118
|
+
throw new UserFacingError("mcpAuth.sdkUnsupported", "Dedicated MCP authentication requires Pi 1.3.0 or 1.4.0");
|
|
4880
5119
|
if (managementContext !== undefined && !managementUsesNormalPermissions(managementContext, { allowPrivileged: this.managementAllowPrivileged })) {
|
|
4881
5120
|
throw new UserFacingError("mcpAuth.restrictedManagement", "MCP authentication is unavailable in restricted management mode");
|
|
4882
5121
|
}
|
|
@@ -5026,6 +5265,7 @@ function previewResponseFromPlan(plan) {
|
|
|
5026
5265
|
projects: plan.projects,
|
|
5027
5266
|
totals: plan.totals,
|
|
5028
5267
|
...(plan.skippedBusySessionIds.length === 0 ? {} : { skippedBusySessionIds: plan.skippedBusySessionIds }),
|
|
5268
|
+
...(plan.skippedPinnedSessionIds === undefined ? {} : { skippedPinnedSessionIds: plan.skippedPinnedSessionIds }),
|
|
5029
5269
|
};
|
|
5030
5270
|
}
|
|
5031
5271
|
function uniqueBulkSessionRefs(refs) {
|
|
@@ -5113,6 +5353,7 @@ function clientSessionFromListEntry(session) {
|
|
|
5113
5353
|
modified: session.modified.toISOString(),
|
|
5114
5354
|
messageCount: session.messageCount,
|
|
5115
5355
|
firstMessage: clientSessionFirstMessagePreview(session.firstMessage),
|
|
5356
|
+
...(session.interventionRequired === true ? { interventionRequired: true } : {}),
|
|
5116
5357
|
...(session.parentSessionPath === undefined ? {} : { parentSessionPath: session.parentSessionPath }),
|
|
5117
5358
|
};
|
|
5118
5359
|
}
|