termdock 1.4.43 → 1.4.46
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/.desktop-dist/main.js +95 -27
- package/dist/client/assets/{abnfDiagram-VRR7QNED-B3X7vTL7.js → abnfDiagram-VRR7QNED-In9dJ8xk.js} +1 -1
- package/dist/client/assets/{arc-OmYbmu75.js → arc-OgDXNUfC.js} +1 -1
- package/dist/client/assets/{architectureDiagram-ZJ3FMSHR-CNNIlew_.js → architectureDiagram-ZJ3FMSHR-CUHWXG-6.js} +1 -1
- package/dist/client/assets/{blockDiagram-677ZJIJ3-eoDvsGst.js → blockDiagram-677ZJIJ3-D6iMCZrE.js} +1 -1
- package/dist/client/assets/{c4Diagram-LMCZKHZV-BYElS7nn.js → c4Diagram-LMCZKHZV-BQIYSHIO.js} +1 -1
- package/dist/client/assets/channel-DR9ZrrsH.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-DgBhC1KN.js → chunk-2Q5K7J3B-VrJ2oEjG.js} +1 -1
- package/dist/client/assets/{chunk-32BRIVSS-B4LjEHPP.js → chunk-32BRIVSS-DgE4tlwU.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-BrBK8Xy3.js → chunk-5VM5RSS4-DPL1VUbd.js} +1 -1
- package/dist/client/assets/{chunk-EX3LRPZG-QndtZFQ6.js → chunk-EX3LRPZG-Cnzcl0zo.js} +1 -1
- package/dist/client/assets/{chunk-JWPE2WC7-B8bZHm4g.js → chunk-JWPE2WC7-BwjoHnSm.js} +1 -1
- package/dist/client/assets/{chunk-MOJQB5TN-B5Kzsd5Z.js → chunk-MOJQB5TN-Q1VspcHf.js} +1 -1
- package/dist/client/assets/{chunk-RYQCIY6F-BdNa9gwg.js → chunk-RYQCIY6F-C3B0hROO.js} +1 -1
- package/dist/client/assets/{chunk-V7JOEXUC-DpQA4l-k.js → chunk-V7JOEXUC-CT1WyL44.js} +1 -1
- package/dist/client/assets/{chunk-VR4S4FIN-CtGdy3K8.js → chunk-VR4S4FIN-RHg32W0I.js} +1 -1
- package/dist/client/assets/{chunk-XXDRQBXY-CZBBj4P_.js → chunk-XXDRQBXY-B8nloyVH.js} +1 -1
- package/dist/client/assets/classDiagram-OUVF2IWQ-CSyi0dnm.js +1 -0
- package/dist/client/assets/classDiagram-v2-EOCWNBFH-CSyi0dnm.js +1 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-gtzwCMyn.js → cose-bilkent-JH36ORCC-DM9b-HC2.js} +1 -1
- package/dist/client/assets/{cynefin-VYW2F7L2-B7X5gKj-.js → cynefin-VYW2F7L2-DyfTbIta.js} +1 -1
- package/dist/client/assets/{cynefinDiagram-TSTJHNR4-BoKfaePi.js → cynefinDiagram-TSTJHNR4-B0TfoSKo.js} +1 -1
- package/dist/client/assets/{dagre-VKFMJZFB-Bjh8y-RO.js → dagre-VKFMJZFB-DoYxgTE_.js} +1 -1
- package/dist/client/assets/{diagram-FQU43EPY-Cx8vWSw0.js → diagram-FQU43EPY-BhdYoO5s.js} +1 -1
- package/dist/client/assets/{diagram-G47NLZAW-DyKuyGsn.js → diagram-G47NLZAW-DU-PG20h.js} +1 -1
- package/dist/client/assets/{diagram-NH7WQ7WH-DwnG0pD9.js → diagram-NH7WQ7WH-WcnJXUD6.js} +1 -1
- package/dist/client/assets/{diagram-OA4YK3LP-wn7Eux1Q.js → diagram-OA4YK3LP-N1S0AWUf.js} +1 -1
- package/dist/client/assets/{diagram-WEI45ONY-DNy0FovQ.js → diagram-WEI45ONY-DBhEABdQ.js} +1 -1
- package/dist/client/assets/{ebnfDiagram-CCIWWBDH-TFnZlH4k.js → ebnfDiagram-CCIWWBDH-CPhAEOjW.js} +1 -1
- package/dist/client/assets/{erDiagram-Q63AITRT-Cx3_8T9Q.js → erDiagram-Q63AITRT-416GnX06.js} +1 -1
- package/dist/client/assets/{flowDiagram-23GEKE2U-CZ7KiBe4.js → flowDiagram-23GEKE2U-CQY7Be4e.js} +1 -1
- package/dist/client/assets/{ganttDiagram-NO4QXBWP-BRTRytgo.js → ganttDiagram-NO4QXBWP-CCdUVGY1.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-IHSO6WYX-DyNUwP6-.js → gitGraphDiagram-IHSO6WYX-DihTneNH.js} +1 -1
- package/dist/client/assets/index-DyTRm1PJ.css +1 -0
- package/dist/client/assets/index-SiGQTF6y.js +436 -0
- package/dist/client/assets/{infoDiagram-FWYZ7A6U-ClLiuIL8.js → infoDiagram-FWYZ7A6U-DxVtT8XS.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-FXEZZL3T-CbO_ecRd.js → ishikawaDiagram-FXEZZL3T-CI04eDRq.js} +1 -1
- package/dist/client/assets/{journeyDiagram-5HDEW3XC-YKjq3svJ.js → journeyDiagram-5HDEW3XC-Dku9Ke-J.js} +1 -1
- package/dist/client/assets/{kanban-definition-HUTT4EX6-CcnV3jvx.js → kanban-definition-HUTT4EX6-X-7cHaWp.js} +1 -1
- package/dist/client/assets/{linear-3N9evV-e.js → linear-BfhGmqE2.js} +1 -1
- package/dist/client/assets/{mermaid.core-C8HeTU54.js → mermaid.core-lwiCvpBd.js} +4 -4
- package/dist/client/assets/{mindmap-definition-LN4V7U3C-CgkCCxMO.js → mindmap-definition-LN4V7U3C-DI3swXAM.js} +1 -1
- package/dist/client/assets/{pegDiagram-2B236MQR-CQRK4LBF.js → pegDiagram-2B236MQR-ByBkCa7g.js} +1 -1
- package/dist/client/assets/{pieDiagram-ENE6RG2P-BHrDXKeR.js → pieDiagram-ENE6RG2P-CAbocCk6.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-ABIIQ3AL-CuJ9UyOO.js → quadrantDiagram-ABIIQ3AL-lE4NNIct.js} +1 -1
- package/dist/client/assets/{railroadDiagram-RFXS5EU6-D0lUBYT1.js → railroadDiagram-RFXS5EU6-DVG7K2hA.js} +1 -1
- package/dist/client/assets/{requirementDiagram-TGXJPOKE-s5kYB_Ya.js → requirementDiagram-TGXJPOKE-BhjZccsb.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-HTMAVEWB-Bhw1mAOH.js → sankeyDiagram-HTMAVEWB-BROBV7xf.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-DBY2YBRQ-qnNrmb6g.js → sequenceDiagram-DBY2YBRQ-DCiUXSQK.js} +1 -1
- package/dist/client/assets/{sizeCapture-X5ZJPWSS-DufN5SxK.js → sizeCapture-X5ZJPWSS-wCRp1dLA.js} +1 -1
- package/dist/client/assets/{stateDiagram-2N3HPSRC-Y5rMnVoS.js → stateDiagram-2N3HPSRC-GnItAgu1.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-6OUMAXLB-DodZ2p7d.js +1 -0
- package/dist/client/assets/{swimlanes-5IMT3BWC-Cmrmdfpk.js → swimlanes-5IMT3BWC-DbXlO1IP.js} +2 -2
- package/dist/client/assets/swimlanesDiagram-G3AALYLV-Dh3DdtaE.js +8 -0
- package/dist/client/assets/{timeline-definition-FHXFAJF6-CqHH1NSC.js → timeline-definition-FHXFAJF6-CQjgTVIW.js} +1 -1
- package/dist/client/assets/{vennDiagram-L72KCM5P-C2l_9LuC.js → vennDiagram-L72KCM5P-Bz_Lzf5a.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-EHGQE667-CNf23qHc.js → wardleyDiagram-EHGQE667-Cgw3S7By.js} +1 -1
- package/dist/client/assets/{xychartDiagram-FW5EYKEG-RIp6RoVE.js → xychartDiagram-FW5EYKEG-IyZJ_VfA.js} +1 -1
- package/dist/client/icons/agents/kimi.svg +5 -0
- package/dist/client/index.html +3 -3
- package/dist/client/sw-notifications.js +163 -36
- package/dist/client/sw.js +1 -1
- package/dist/server/agent/installers.js +145 -1
- package/dist/server/agent/registry.js +3 -0
- package/dist/server/cli.js +25 -0
- package/dist/server/entry.js +53 -13
- package/dist/server/notifications/pushService.js +121 -35
- package/dist/server/notifications/pushViewers.js +44 -0
- package/dist/server/ptyHost.js +17 -0
- package/dist/server/ptyhost/manager.js +152 -5
- package/dist/server/quota/tokenDiscovery.js +25 -0
- package/dist/server/routes/filesystem.js +4 -2
- package/dist/server/routes/notifications.js +9 -3
- package/dist/server/routes/terminal.js +82 -106
- package/dist/server/utils/contextDraft.js +36 -0
- package/dist/server/utils/requestDeadline.js +104 -0
- package/dist/server/utils/runtimeClient.js +41 -0
- package/dist/server/utils/settings.js +18 -9
- package/package.json +5 -2
- package/runtime-manifest.json +12 -0
- package/scripts/classify-release.mjs +88 -0
- package/scripts/generate-runtime-manifest.mjs +77 -0
- package/scripts/prepare-desktop-runtime.mjs +27 -3
- package/dist/client/assets/channel-DBZQbHSi.js +0 -1
- package/dist/client/assets/classDiagram-OUVF2IWQ-BsrNzS08.js +0 -1
- package/dist/client/assets/classDiagram-v2-EOCWNBFH-BsrNzS08.js +0 -1
- package/dist/client/assets/index-CbYQuue6.css +0 -1
- package/dist/client/assets/index-DB-0aiWT.js +0 -433
- package/dist/client/assets/stateDiagram-v2-6OUMAXLB-BSqYeylv.js +0 -1
- package/dist/client/assets/swimlanesDiagram-G3AALYLV-CUwNpVXZ.js +0 -8
package/dist/client/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
if(!self.define){let s,e={};const i=(i,l)=>(i=new URL(i+".js",l).href,e[i]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=i,s.onload=e,document.head.appendChild(s)}else s=i,importScripts(i),e()}).then(()=>{let s=e[i];if(!s)throw new Error(`Module ${i} didn’t register its module`);return s}));self.define=(l,n)=>{const r=s||("document"in self?document.currentScript.src:"")||location.href;if(e[r])return;let a={};const o=s=>i(s,r),u={module:{uri:r},exports:a,require:o};e[r]=Promise.all(l.map(s=>u[s]||o(s))).then(s=>(n(...s),a))}}define(["./workbox-9c191d2f"],function(s){"use strict";importScripts("sw-notifications.js"),self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"sw-notifications.js",revision:"2ed386d64dc020bf9a7da8efd9dbea42"},{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"pwa-64x64.png",revision:"c1ca9f6daa67743b38564b230314277a"},{url:"pwa-512x512.svg",revision:"149a151133f52feb34ab6ecedf349936"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"pwa-192x192.svg",revision:"541ace289ca5d6f3d269d1286cde5283"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"index.html",revision:"75a3a2ea7df85d2ed6ccce0deb75df09"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"icons/agents/opencode.svg",revision:"851c2931d95821ba2b39b68587b48976"},{url:"icons/agents/grok.svg",revision:"cd745b0b964545bc7a6b4f36021c3298"},{url:"icons/agents/goose.svg",revision:"c79b927278983c19098d77b4b0c11ab3"},{url:"icons/agents/gemini.svg",revision:"7a64f6d6f80a908255e9c0256903882e"},{url:"icons/agents/droid.svg",revision:"f28723b8c5c115e0908ba3c72613e256"},{url:"icons/agents/cursor.svg",revision:"a1528f3d3cda497f75a5db28defb19de"},{url:"icons/agents/copilot.svg",revision:"dd52e96c1eac0b6ec4bedcd0ddd3b52d"},{url:"icons/agents/codex.svg",revision:"608e55babb0b217e1f2da287342b46d3"},{url:"icons/agents/claude.svg",revision:"08af0225b7acdd8e8f573f3247e5e1c3"},{url:"icons/agents/amp.svg",revision:"af12f8b33faa81e4d46ea7b93c7e43f3"},{url:"fonts/TermdockStarSymbol-Subset.woff2",revision:"853a8d84112dd97a91d6cff1e7ab6bdf"},{url:"fonts/SymbolsNerdFontMono-Regular.woff2",revision:"54113ea8487e607f9d9a482c5877aed4"},{url:"fonts/NotoSansSymbols2-Subset.woff2",revision:"8257a6beabcc8858199b208908a96ee9"},{url:"fonts/NotoSansMonoCJKsc-Subset.woff2",revision:"e52357967aa973c04cce881c50cce0c8"},{url:"fonts/NotoSansMonoCJKsc-Bold-Subset.woff2",revision:"7e37d6b9fb1339898c00ac3b49c8b12e"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Regular.ttf",revision:"ed6fa47e3c1fc9aa68e9015a5300419f"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Italic.ttf",revision:"5624a73ef0a476e93ef5949dd6e452e1"},{url:"fonts/JetBrainsMonoNLNerdFontMono-BoldItalic.ttf",revision:"9b7603423a37fd2f544f75e9669689a0"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Bold.ttf",revision:"7deed80e7a4195a51f2c0b82aa364e97"},{url:"fonts/JetBrainsMonoNL-Regular.woff2",revision:"3bb268888f64810d496dd10295d4337c"},{url:"fonts/JetBrainsMonoNL-Italic.woff2",revision:"e035d3c7673175237d40687fc14d5b40"},{url:"fonts/JetBrainsMonoNL-BoldItalic.woff2",revision:"bc3577cc820eaef00d9a985058bca2b7"},{url:"fonts/JetBrainsMonoNL-Bold.woff2",revision:"7c0305a4db8f2977b061631755556ec0"},{url:"assets/xychartDiagram-FW5EYKEG-RIp6RoVE.js",revision:null},{url:"assets/wardleyDiagram-EHGQE667-CNf23qHc.js",revision:null},{url:"assets/vennDiagram-L72KCM5P-C2l_9LuC.js",revision:null},{url:"assets/timeline-definition-FHXFAJF6-CqHH1NSC.js",revision:null},{url:"assets/terminal-C7X98Amf.js",revision:null},{url:"assets/swimlanesDiagram-G3AALYLV-CUwNpVXZ.js",revision:null},{url:"assets/swimlanes-5IMT3BWC-Cmrmdfpk.js",revision:null},{url:"assets/stateDiagram-v2-6OUMAXLB-BSqYeylv.js",revision:null},{url:"assets/stateDiagram-2N3HPSRC-Y5rMnVoS.js",revision:null},{url:"assets/sizeCapture-X5ZJPWSS-DufN5SxK.js",revision:null},{url:"assets/sequenceDiagram-DBY2YBRQ-qnNrmb6g.js",revision:null},{url:"assets/sankeyDiagram-HTMAVEWB-Bhw1mAOH.js",revision:null},{url:"assets/requirementDiagram-TGXJPOKE-s5kYB_Ya.js",revision:null},{url:"assets/react-XDCjal2T.js",revision:null},{url:"assets/railroadDiagram-RFXS5EU6-D0lUBYT1.js",revision:null},{url:"assets/quadrantDiagram-ABIIQ3AL-CuJ9UyOO.js",revision:null},{url:"assets/purify.es-CC4Brkr_.js",revision:null},{url:"assets/pieDiagram-ENE6RG2P-BHrDXKeR.js",revision:null},{url:"assets/pegDiagram-2B236MQR-CQRK4LBF.js",revision:null},{url:"assets/ordinal-Cboi1Yqb.js",revision:null},{url:"assets/mindmap-definition-LN4V7U3C-CgkCCxMO.js",revision:null},{url:"assets/mermaid.core-C8HeTU54.js",revision:null},{url:"assets/map-BdqsVdb3.js",revision:null},{url:"assets/linear-3N9evV-e.js",revision:null},{url:"assets/layout-1eBIAoSl.js",revision:null},{url:"assets/katex-HP8lGamR.js",revision:null},{url:"assets/katex-DnlPpQZa.js",revision:null},{url:"assets/katex-55ZPZeOF.css",revision:null},{url:"assets/kanban-definition-HUTT4EX6-CcnV3jvx.js",revision:null},{url:"assets/journeyDiagram-5HDEW3XC-YKjq3svJ.js",revision:null},{url:"assets/ishikawaDiagram-FXEZZL3T-CbO_ecRd.js",revision:null},{url:"assets/init-Gi6I4Gst.js",revision:null},{url:"assets/infoDiagram-FWYZ7A6U-ClLiuIL8.js",revision:null},{url:"assets/index-DB-0aiWT.js",revision:null},{url:"assets/index-CbYQuue6.css",revision:null},{url:"assets/index-Ca-rq7yX.js",revision:null},{url:"assets/graph-D2o_JWn5.js",revision:null},{url:"assets/gitGraphDiagram-IHSO6WYX-DyNUwP6-.js",revision:null},{url:"assets/ganttDiagram-NO4QXBWP-BRTRytgo.js",revision:null},{url:"assets/flowDiagram-23GEKE2U-CZ7KiBe4.js",revision:null},{url:"assets/erDiagram-Q63AITRT-Cx3_8T9Q.js",revision:null},{url:"assets/ebnfDiagram-CCIWWBDH-TFnZlH4k.js",revision:null},{url:"assets/dnd-BCFAPC0L.js",revision:null},{url:"assets/diffWorker-BFIcKxCt.js",revision:null},{url:"assets/diagram-WEI45ONY-DNy0FovQ.js",revision:null},{url:"assets/diagram-OA4YK3LP-wn7Eux1Q.js",revision:null},{url:"assets/diagram-NH7WQ7WH-DwnG0pD9.js",revision:null},{url:"assets/diagram-G47NLZAW-DyKuyGsn.js",revision:null},{url:"assets/diagram-FQU43EPY-Cx8vWSw0.js",revision:null},{url:"assets/defaultLocale-CrowFXzY.js",revision:null},{url:"assets/dagre-VKFMJZFB-Bjh8y-RO.js",revision:null},{url:"assets/cytoscape.esm-D3_iZ_3b.js",revision:null},{url:"assets/cynefinDiagram-TSTJHNR4-BoKfaePi.js",revision:null},{url:"assets/cynefin-VYW2F7L2-B7X5gKj-.js",revision:null},{url:"assets/cose-bilkent-JH36ORCC-gtzwCMyn.js",revision:null},{url:"assets/classDiagram-v2-EOCWNBFH-BsrNzS08.js",revision:null},{url:"assets/classDiagram-OUVF2IWQ-BsrNzS08.js",revision:null},{url:"assets/chunk-XXDRQBXY-CZBBj4P_.js",revision:null},{url:"assets/chunk-VR4S4FIN-CtGdy3K8.js",revision:null},{url:"assets/chunk-V7JOEXUC-DpQA4l-k.js",revision:null},{url:"assets/chunk-RYQCIY6F-BdNa9gwg.js",revision:null},{url:"assets/chunk-MOJQB5TN-B5Kzsd5Z.js",revision:null},{url:"assets/chunk-JWPE2WC7-B8bZHm4g.js",revision:null},{url:"assets/chunk-EX3LRPZG-QndtZFQ6.js",revision:null},{url:"assets/chunk-5VM5RSS4-BrBK8Xy3.js",revision:null},{url:"assets/chunk-32BRIVSS-B4LjEHPP.js",revision:null},{url:"assets/chunk-2Q5K7J3B-DgBhC1KN.js",revision:null},{url:"assets/channel-DBZQbHSi.js",revision:null},{url:"assets/c4Diagram-LMCZKHZV-BYElS7nn.js",revision:null},{url:"assets/blockDiagram-677ZJIJ3-eoDvsGst.js",revision:null},{url:"assets/architectureDiagram-ZJ3FMSHR-CNNIlew_.js",revision:null},{url:"assets/arc-OmYbmu75.js",revision:null},{url:"assets/abnfDiagram-VRR7QNED-B3X7vTL7.js",revision:null},{url:"assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf",revision:null},{url:"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2",revision:null},{url:"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2",revision:null},{url:"assets/KaTeX_Size4-Regular-DWFBv043.ttf",revision:null},{url:"assets/KaTeX_Size3-Regular-DgpXs0kz.ttf",revision:null},{url:"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2",revision:null},{url:"assets/KaTeX_Size2-Regular-B7gKUWhC.ttf",revision:null},{url:"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2",revision:null},{url:"assets/KaTeX_Size1-Regular-Dbsnue_I.ttf",revision:null},{url:"assets/KaTeX_Script-Regular-D3wIWfF6.woff2",revision:null},{url:"assets/KaTeX_Script-Regular-C5JkGWo-.ttf",revision:null},{url:"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2",revision:null},{url:"assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf",revision:null},{url:"assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf",revision:null},{url:"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2",revision:null},{url:"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2",revision:null},{url:"assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf",revision:null},{url:"assets/KaTeX_Math-Italic-t53AETM-.woff2",revision:null},{url:"assets/KaTeX_Math-Italic-flOr_0UB.ttf",revision:null},{url:"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2",revision:null},{url:"assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf",revision:null},{url:"assets/KaTeX_Main-Regular-ypZvNtVU.ttf",revision:null},{url:"assets/KaTeX_Main-Regular-B22Nviop.woff2",revision:null},{url:"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2",revision:null},{url:"assets/KaTeX_Main-Italic-3WenGoN9.ttf",revision:null},{url:"assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf",revision:null},{url:"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2",revision:null},{url:"assets/KaTeX_Main-Bold-waoOVXN0.ttf",revision:null},{url:"assets/KaTeX_Main-Bold-Cx986IdX.woff2",revision:null},{url:"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2",revision:null},{url:"assets/KaTeX_Fraktur-Regular-CB_wures.ttf",revision:null},{url:"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2",revision:null},{url:"assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf",revision:null},{url:"assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf",revision:null},{url:"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2",revision:null},{url:"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2",revision:null},{url:"assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf",revision:null},{url:"assets/KaTeX_AMS-Regular-DRggAlZN.ttf",revision:null},{url:"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2",revision:null},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"robots.txt",revision:"d9339907142917dee4aac78494ac9cfe"},{url:"sw-notifications.js",revision:"2ed386d64dc020bf9a7da8efd9dbea42"},{url:"fonts/JetBrainsMonoNL-Bold.woff2",revision:"7c0305a4db8f2977b061631755556ec0"},{url:"fonts/JetBrainsMonoNL-BoldItalic.woff2",revision:"bc3577cc820eaef00d9a985058bca2b7"},{url:"fonts/JetBrainsMonoNL-Italic.woff2",revision:"e035d3c7673175237d40687fc14d5b40"},{url:"fonts/JetBrainsMonoNL-Regular.woff2",revision:"3bb268888f64810d496dd10295d4337c"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Bold.ttf",revision:"7deed80e7a4195a51f2c0b82aa364e97"},{url:"fonts/JetBrainsMonoNLNerdFontMono-BoldItalic.ttf",revision:"9b7603423a37fd2f544f75e9669689a0"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Italic.ttf",revision:"5624a73ef0a476e93ef5949dd6e452e1"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Regular.ttf",revision:"ed6fa47e3c1fc9aa68e9015a5300419f"},{url:"fonts/NotoSansMonoCJKsc-Bold-Subset.woff2",revision:"7e37d6b9fb1339898c00ac3b49c8b12e"},{url:"fonts/NotoSansMonoCJKsc-Subset.woff2",revision:"e52357967aa973c04cce881c50cce0c8"},{url:"fonts/NotoSansSymbols2-Subset.woff2",revision:"8257a6beabcc8858199b208908a96ee9"},{url:"fonts/SymbolsNerdFontMono-Regular.woff2",revision:"54113ea8487e607f9d9a482c5877aed4"},{url:"fonts/TermdockStarSymbol-Subset.woff2",revision:"853a8d84112dd97a91d6cff1e7ab6bdf"},{url:"manifest.webmanifest",revision:"83f9a43b74c236012adafb077fb6d774"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//,/^\/health$/]}))});
|
|
1
|
+
if(!self.define){let s,e={};const i=(i,l)=>(i=new URL(i+".js",l).href,e[i]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=i,s.onload=e,document.head.appendChild(s)}else s=i,importScripts(i),e()}).then(()=>{let s=e[i];if(!s)throw new Error(`Module ${i} didn’t register its module`);return s}));self.define=(l,n)=>{const r=s||("document"in self?document.currentScript.src:"")||location.href;if(e[r])return;let a={};const o=s=>i(s,r),t={module:{uri:r},exports:a,require:o};e[r]=Promise.all(l.map(s=>t[s]||o(s))).then(s=>(n(...s),a))}}define(["./workbox-9c191d2f"],function(s){"use strict";importScripts("sw-notifications.js"),self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"sw-notifications.js",revision:"91964c9b57d28d34a4e9e4911f8d72d8"},{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"pwa-64x64.png",revision:"c1ca9f6daa67743b38564b230314277a"},{url:"pwa-512x512.svg",revision:"149a151133f52feb34ab6ecedf349936"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"pwa-192x192.svg",revision:"541ace289ca5d6f3d269d1286cde5283"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"index.html",revision:"f7ad5f4b46b1b9f639610dac37df8a1b"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"icons/agents/opencode.svg",revision:"851c2931d95821ba2b39b68587b48976"},{url:"icons/agents/kimi.svg",revision:"5366c710f4f763022fe159a69cf17409"},{url:"icons/agents/grok.svg",revision:"cd745b0b964545bc7a6b4f36021c3298"},{url:"icons/agents/goose.svg",revision:"c79b927278983c19098d77b4b0c11ab3"},{url:"icons/agents/gemini.svg",revision:"7a64f6d6f80a908255e9c0256903882e"},{url:"icons/agents/droid.svg",revision:"f28723b8c5c115e0908ba3c72613e256"},{url:"icons/agents/cursor.svg",revision:"a1528f3d3cda497f75a5db28defb19de"},{url:"icons/agents/copilot.svg",revision:"dd52e96c1eac0b6ec4bedcd0ddd3b52d"},{url:"icons/agents/codex.svg",revision:"608e55babb0b217e1f2da287342b46d3"},{url:"icons/agents/claude.svg",revision:"08af0225b7acdd8e8f573f3247e5e1c3"},{url:"icons/agents/amp.svg",revision:"af12f8b33faa81e4d46ea7b93c7e43f3"},{url:"fonts/TermdockStarSymbol-Subset.woff2",revision:"853a8d84112dd97a91d6cff1e7ab6bdf"},{url:"fonts/SymbolsNerdFontMono-Regular.woff2",revision:"54113ea8487e607f9d9a482c5877aed4"},{url:"fonts/NotoSansSymbols2-Subset.woff2",revision:"8257a6beabcc8858199b208908a96ee9"},{url:"fonts/NotoSansMonoCJKsc-Subset.woff2",revision:"e52357967aa973c04cce881c50cce0c8"},{url:"fonts/NotoSansMonoCJKsc-Bold-Subset.woff2",revision:"7e37d6b9fb1339898c00ac3b49c8b12e"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Regular.ttf",revision:"ed6fa47e3c1fc9aa68e9015a5300419f"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Italic.ttf",revision:"5624a73ef0a476e93ef5949dd6e452e1"},{url:"fonts/JetBrainsMonoNLNerdFontMono-BoldItalic.ttf",revision:"9b7603423a37fd2f544f75e9669689a0"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Bold.ttf",revision:"7deed80e7a4195a51f2c0b82aa364e97"},{url:"fonts/JetBrainsMonoNL-Regular.woff2",revision:"3bb268888f64810d496dd10295d4337c"},{url:"fonts/JetBrainsMonoNL-Italic.woff2",revision:"e035d3c7673175237d40687fc14d5b40"},{url:"fonts/JetBrainsMonoNL-BoldItalic.woff2",revision:"bc3577cc820eaef00d9a985058bca2b7"},{url:"fonts/JetBrainsMonoNL-Bold.woff2",revision:"7c0305a4db8f2977b061631755556ec0"},{url:"assets/xychartDiagram-FW5EYKEG-IyZJ_VfA.js",revision:null},{url:"assets/wardleyDiagram-EHGQE667-Cgw3S7By.js",revision:null},{url:"assets/vennDiagram-L72KCM5P-Bz_Lzf5a.js",revision:null},{url:"assets/timeline-definition-FHXFAJF6-CQjgTVIW.js",revision:null},{url:"assets/terminal-C7X98Amf.js",revision:null},{url:"assets/swimlanesDiagram-G3AALYLV-Dh3DdtaE.js",revision:null},{url:"assets/swimlanes-5IMT3BWC-DbXlO1IP.js",revision:null},{url:"assets/stateDiagram-v2-6OUMAXLB-DodZ2p7d.js",revision:null},{url:"assets/stateDiagram-2N3HPSRC-GnItAgu1.js",revision:null},{url:"assets/sizeCapture-X5ZJPWSS-wCRp1dLA.js",revision:null},{url:"assets/sequenceDiagram-DBY2YBRQ-DCiUXSQK.js",revision:null},{url:"assets/sankeyDiagram-HTMAVEWB-BROBV7xf.js",revision:null},{url:"assets/requirementDiagram-TGXJPOKE-BhjZccsb.js",revision:null},{url:"assets/react-XDCjal2T.js",revision:null},{url:"assets/railroadDiagram-RFXS5EU6-DVG7K2hA.js",revision:null},{url:"assets/quadrantDiagram-ABIIQ3AL-lE4NNIct.js",revision:null},{url:"assets/purify.es-CC4Brkr_.js",revision:null},{url:"assets/pieDiagram-ENE6RG2P-CAbocCk6.js",revision:null},{url:"assets/pegDiagram-2B236MQR-ByBkCa7g.js",revision:null},{url:"assets/ordinal-Cboi1Yqb.js",revision:null},{url:"assets/mindmap-definition-LN4V7U3C-DI3swXAM.js",revision:null},{url:"assets/mermaid.core-lwiCvpBd.js",revision:null},{url:"assets/map-BdqsVdb3.js",revision:null},{url:"assets/linear-BfhGmqE2.js",revision:null},{url:"assets/layout-1eBIAoSl.js",revision:null},{url:"assets/katex-HP8lGamR.js",revision:null},{url:"assets/katex-DnlPpQZa.js",revision:null},{url:"assets/katex-55ZPZeOF.css",revision:null},{url:"assets/kanban-definition-HUTT4EX6-X-7cHaWp.js",revision:null},{url:"assets/journeyDiagram-5HDEW3XC-Dku9Ke-J.js",revision:null},{url:"assets/ishikawaDiagram-FXEZZL3T-CI04eDRq.js",revision:null},{url:"assets/init-Gi6I4Gst.js",revision:null},{url:"assets/infoDiagram-FWYZ7A6U-DxVtT8XS.js",revision:null},{url:"assets/index-SiGQTF6y.js",revision:null},{url:"assets/index-DyTRm1PJ.css",revision:null},{url:"assets/index-Ca-rq7yX.js",revision:null},{url:"assets/graph-D2o_JWn5.js",revision:null},{url:"assets/gitGraphDiagram-IHSO6WYX-DihTneNH.js",revision:null},{url:"assets/ganttDiagram-NO4QXBWP-CCdUVGY1.js",revision:null},{url:"assets/flowDiagram-23GEKE2U-CQY7Be4e.js",revision:null},{url:"assets/erDiagram-Q63AITRT-416GnX06.js",revision:null},{url:"assets/ebnfDiagram-CCIWWBDH-CPhAEOjW.js",revision:null},{url:"assets/dnd-BCFAPC0L.js",revision:null},{url:"assets/diffWorker-BFIcKxCt.js",revision:null},{url:"assets/diagram-WEI45ONY-DBhEABdQ.js",revision:null},{url:"assets/diagram-OA4YK3LP-N1S0AWUf.js",revision:null},{url:"assets/diagram-NH7WQ7WH-WcnJXUD6.js",revision:null},{url:"assets/diagram-G47NLZAW-DU-PG20h.js",revision:null},{url:"assets/diagram-FQU43EPY-BhdYoO5s.js",revision:null},{url:"assets/defaultLocale-CrowFXzY.js",revision:null},{url:"assets/dagre-VKFMJZFB-DoYxgTE_.js",revision:null},{url:"assets/cytoscape.esm-D3_iZ_3b.js",revision:null},{url:"assets/cynefinDiagram-TSTJHNR4-B0TfoSKo.js",revision:null},{url:"assets/cynefin-VYW2F7L2-DyfTbIta.js",revision:null},{url:"assets/cose-bilkent-JH36ORCC-DM9b-HC2.js",revision:null},{url:"assets/classDiagram-v2-EOCWNBFH-CSyi0dnm.js",revision:null},{url:"assets/classDiagram-OUVF2IWQ-CSyi0dnm.js",revision:null},{url:"assets/chunk-XXDRQBXY-B8nloyVH.js",revision:null},{url:"assets/chunk-VR4S4FIN-RHg32W0I.js",revision:null},{url:"assets/chunk-V7JOEXUC-CT1WyL44.js",revision:null},{url:"assets/chunk-RYQCIY6F-C3B0hROO.js",revision:null},{url:"assets/chunk-MOJQB5TN-Q1VspcHf.js",revision:null},{url:"assets/chunk-JWPE2WC7-BwjoHnSm.js",revision:null},{url:"assets/chunk-EX3LRPZG-Cnzcl0zo.js",revision:null},{url:"assets/chunk-5VM5RSS4-DPL1VUbd.js",revision:null},{url:"assets/chunk-32BRIVSS-DgE4tlwU.js",revision:null},{url:"assets/chunk-2Q5K7J3B-VrJ2oEjG.js",revision:null},{url:"assets/channel-DR9ZrrsH.js",revision:null},{url:"assets/c4Diagram-LMCZKHZV-BQIYSHIO.js",revision:null},{url:"assets/blockDiagram-677ZJIJ3-D6iMCZrE.js",revision:null},{url:"assets/architectureDiagram-ZJ3FMSHR-CUHWXG-6.js",revision:null},{url:"assets/arc-OgDXNUfC.js",revision:null},{url:"assets/abnfDiagram-VRR7QNED-In9dJ8xk.js",revision:null},{url:"assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf",revision:null},{url:"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2",revision:null},{url:"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2",revision:null},{url:"assets/KaTeX_Size4-Regular-DWFBv043.ttf",revision:null},{url:"assets/KaTeX_Size3-Regular-DgpXs0kz.ttf",revision:null},{url:"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2",revision:null},{url:"assets/KaTeX_Size2-Regular-B7gKUWhC.ttf",revision:null},{url:"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2",revision:null},{url:"assets/KaTeX_Size1-Regular-Dbsnue_I.ttf",revision:null},{url:"assets/KaTeX_Script-Regular-D3wIWfF6.woff2",revision:null},{url:"assets/KaTeX_Script-Regular-C5JkGWo-.ttf",revision:null},{url:"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2",revision:null},{url:"assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf",revision:null},{url:"assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf",revision:null},{url:"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2",revision:null},{url:"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2",revision:null},{url:"assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf",revision:null},{url:"assets/KaTeX_Math-Italic-t53AETM-.woff2",revision:null},{url:"assets/KaTeX_Math-Italic-flOr_0UB.ttf",revision:null},{url:"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2",revision:null},{url:"assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf",revision:null},{url:"assets/KaTeX_Main-Regular-ypZvNtVU.ttf",revision:null},{url:"assets/KaTeX_Main-Regular-B22Nviop.woff2",revision:null},{url:"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2",revision:null},{url:"assets/KaTeX_Main-Italic-3WenGoN9.ttf",revision:null},{url:"assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf",revision:null},{url:"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2",revision:null},{url:"assets/KaTeX_Main-Bold-waoOVXN0.ttf",revision:null},{url:"assets/KaTeX_Main-Bold-Cx986IdX.woff2",revision:null},{url:"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2",revision:null},{url:"assets/KaTeX_Fraktur-Regular-CB_wures.ttf",revision:null},{url:"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2",revision:null},{url:"assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf",revision:null},{url:"assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf",revision:null},{url:"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2",revision:null},{url:"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2",revision:null},{url:"assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf",revision:null},{url:"assets/KaTeX_AMS-Regular-DRggAlZN.ttf",revision:null},{url:"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2",revision:null},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"robots.txt",revision:"d9339907142917dee4aac78494ac9cfe"},{url:"sw-notifications.js",revision:"91964c9b57d28d34a4e9e4911f8d72d8"},{url:"fonts/JetBrainsMonoNL-Bold.woff2",revision:"7c0305a4db8f2977b061631755556ec0"},{url:"fonts/JetBrainsMonoNL-BoldItalic.woff2",revision:"bc3577cc820eaef00d9a985058bca2b7"},{url:"fonts/JetBrainsMonoNL-Italic.woff2",revision:"e035d3c7673175237d40687fc14d5b40"},{url:"fonts/JetBrainsMonoNL-Regular.woff2",revision:"3bb268888f64810d496dd10295d4337c"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Bold.ttf",revision:"7deed80e7a4195a51f2c0b82aa364e97"},{url:"fonts/JetBrainsMonoNLNerdFontMono-BoldItalic.ttf",revision:"9b7603423a37fd2f544f75e9669689a0"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Italic.ttf",revision:"5624a73ef0a476e93ef5949dd6e452e1"},{url:"fonts/JetBrainsMonoNLNerdFontMono-Regular.ttf",revision:"ed6fa47e3c1fc9aa68e9015a5300419f"},{url:"fonts/NotoSansMonoCJKsc-Bold-Subset.woff2",revision:"7e37d6b9fb1339898c00ac3b49c8b12e"},{url:"fonts/NotoSansMonoCJKsc-Subset.woff2",revision:"e52357967aa973c04cce881c50cce0c8"},{url:"fonts/NotoSansSymbols2-Subset.woff2",revision:"8257a6beabcc8858199b208908a96ee9"},{url:"fonts/SymbolsNerdFontMono-Regular.woff2",revision:"54113ea8487e607f9d9a482c5877aed4"},{url:"fonts/TermdockStarSymbol-Subset.woff2",revision:"853a8d84112dd97a91d6cff1e7ab6bdf"},{url:"manifest.webmanifest",revision:"83f9a43b74c236012adafb077fb6d774"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//,/^\/health$/]}))});
|
|
@@ -19,7 +19,7 @@ import path from 'node:path';
|
|
|
19
19
|
import { execFile } from 'node:child_process';
|
|
20
20
|
import { agentBySlug, isPluginAgent } from './registry.js';
|
|
21
21
|
import { loadPlugins, resolveHookTarget } from './plugins.js';
|
|
22
|
-
export const HOOK_AGENTS = ['claude', 'codex', 'copilot', 'opencode', 'pi', 'grok'];
|
|
22
|
+
export const HOOK_AGENTS = ['claude', 'codex', 'copilot', 'opencode', 'pi', 'grok', 'kimi'];
|
|
23
23
|
const DISPLAY_NAMES = {
|
|
24
24
|
claude: 'Claude Code',
|
|
25
25
|
codex: 'Codex',
|
|
@@ -27,6 +27,7 @@ const DISPLAY_NAMES = {
|
|
|
27
27
|
opencode: 'OpenCode',
|
|
28
28
|
pi: 'Pi',
|
|
29
29
|
grok: 'Grok Build',
|
|
30
|
+
kimi: 'Kimi Code',
|
|
30
31
|
};
|
|
31
32
|
// ---------------------------------------------------------------------------
|
|
32
33
|
// Paths and the hook command line
|
|
@@ -58,6 +59,7 @@ function targetPath(agent) {
|
|
|
58
59
|
case 'opencode': return path.join(xdgConfigDir(), 'opencode', 'plugins', OWNED_FILE_STEM_JS);
|
|
59
60
|
case 'pi': return path.join(homeDir(), '.pi', 'agent', 'extensions', 'termdock', 'index.ts');
|
|
60
61
|
case 'grok': return path.join(homeDir(), '.grok', 'hooks', OWNED_FILE_STEM_JSON);
|
|
62
|
+
case 'kimi': return path.join(homeDir(), '.kimi-code', 'config.toml');
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
function abbreviateHome(p) {
|
|
@@ -127,6 +129,29 @@ const CODEX_HOOK_EVENTS = [
|
|
|
127
129
|
['UserPromptSubmit', 'prompt-submit'],
|
|
128
130
|
['Stop', 'stop'],
|
|
129
131
|
];
|
|
132
|
+
/**
|
|
133
|
+
* Kimi Code's hook events (~/.kimi-code/config.toml `[[hooks]]` entries, TOML).
|
|
134
|
+
* `PermissionRequest` is the genuine block (fires right before the approval
|
|
135
|
+
* wait); `PostToolUse` is the way *back* — Kimi has a `PermissionResult`
|
|
136
|
+
* event, but the approved tool completing is the same recovery edge Claude
|
|
137
|
+
* uses, and it keeps the state machine on the shared vocabulary. `Stop` does
|
|
138
|
+
* NOT fire when the user interrupts (Esc) or the turn errors — Kimi sends
|
|
139
|
+
* `Interrupt` / `StopFailure` instead, so both fold onto `stop` to keep the
|
|
140
|
+
* pane from sticking in working.
|
|
141
|
+
*/
|
|
142
|
+
export const KIMI_HOOK_EVENTS = [
|
|
143
|
+
['SessionStart', 'session-start'],
|
|
144
|
+
['UserPromptSubmit', 'prompt-submit'],
|
|
145
|
+
['PermissionRequest', 'permission-request'],
|
|
146
|
+
['PostToolUse', 'tool-complete'],
|
|
147
|
+
['Stop', 'stop'],
|
|
148
|
+
['StopFailure', 'stop'],
|
|
149
|
+
['Interrupt', 'stop'],
|
|
150
|
+
['SessionEnd', 'session-end'],
|
|
151
|
+
];
|
|
152
|
+
/** Seconds Kimi gives one termdock hook before killing it (its default is
|
|
153
|
+
* 30s; ours writes a few bytes). */
|
|
154
|
+
const KIMI_HOOK_TIMEOUT_SECS = 5;
|
|
130
155
|
/**
|
|
131
156
|
* Grok Build's hook events — Claude Code's vocabulary (grok mirrors it
|
|
132
157
|
* deliberately, it even reads ~/.claude/settings.json) — plus the matcher
|
|
@@ -473,6 +498,113 @@ function ownedFileUninstall(file, mark) {
|
|
|
473
498
|
return 'Removed';
|
|
474
499
|
}
|
|
475
500
|
// ---------------------------------------------------------------------------
|
|
501
|
+
// TOML hooks installer (Kimi Code): kimi keeps hooks in `[[hooks]]` array-of-
|
|
502
|
+
// tables inside ~/.kimi-code/config.toml — free-form TOML we must NOT rewrite
|
|
503
|
+
// wholesale (comments, ordering, other tables are the user's). So instead of
|
|
504
|
+
// parsing, the file is treated as a sequence of *sections* (a `[table]` /
|
|
505
|
+
// `[[array]]` header line plus the lines up to the next header); termdock
|
|
506
|
+
// owns exactly the sections whose command carries the marker, appends fresh
|
|
507
|
+
// `[[hooks]]` blocks at the end of the file, and never touches the rest.
|
|
508
|
+
// ---------------------------------------------------------------------------
|
|
509
|
+
/** Split TOML text into sections: everything before the first header is one
|
|
510
|
+
* (preamble) section; each later section starts at its header line.
|
|
511
|
+
* `sections.join('\n')` reproduces the input byte-for-byte. */
|
|
512
|
+
function splitTomlSections(text) {
|
|
513
|
+
const lines = text.split('\n');
|
|
514
|
+
const sections = [];
|
|
515
|
+
let current = [];
|
|
516
|
+
for (const line of lines) {
|
|
517
|
+
if (/^\s*\[/.test(line) && current.length > 0) {
|
|
518
|
+
sections.push(current.join('\n'));
|
|
519
|
+
current = [];
|
|
520
|
+
}
|
|
521
|
+
current.push(line);
|
|
522
|
+
}
|
|
523
|
+
sections.push(current.join('\n'));
|
|
524
|
+
return sections;
|
|
525
|
+
}
|
|
526
|
+
/** The `event = "…"` value of a `[[hooks]]` section, if it declares one. */
|
|
527
|
+
function tomlSectionEvent(section) {
|
|
528
|
+
const m = section.match(/^\s*event\s*=\s*"([^"]+)"\s*(?:#.*)?$/m);
|
|
529
|
+
return m ? m[1] : null;
|
|
530
|
+
}
|
|
531
|
+
/** The `command = '…'` value of a `[[hooks]]` section (literal-string form —
|
|
532
|
+
* the only form termdock writes; the command embeds double quotes). */
|
|
533
|
+
function tomlSectionCommand(section) {
|
|
534
|
+
const m = section.match(/^\s*command\s*=\s*'(.*)'\s*(?:#.*)?$/m);
|
|
535
|
+
return m ? m[1] : null;
|
|
536
|
+
}
|
|
537
|
+
/** One `[[hooks]]` block as termdock writes it. Kimi allows exactly the
|
|
538
|
+
* fields event/matcher/command/timeout. */
|
|
539
|
+
function tomlHookBlock(hookEvent, command) {
|
|
540
|
+
return `[[hooks]]\nevent = "${hookEvent}"\ncommand = '${command}'\ntimeout = ${KIMI_HOOK_TIMEOUT_SECS}`;
|
|
541
|
+
}
|
|
542
|
+
function readTextFile(file) {
|
|
543
|
+
try {
|
|
544
|
+
return fs.readFileSync(file, 'utf8');
|
|
545
|
+
}
|
|
546
|
+
catch {
|
|
547
|
+
return null;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
// Exported for tests — the public entry points are hooksState/installHooks/
|
|
551
|
+
// uninstallHooks; these take an explicit file path so tests can use tmp files.
|
|
552
|
+
export function tomlHooksState(file, agent, events) {
|
|
553
|
+
const text = readTextFile(file);
|
|
554
|
+
if (text === null)
|
|
555
|
+
return 'not-installed';
|
|
556
|
+
const mark = marker(agent);
|
|
557
|
+
const ours = splitTomlSections(text).filter((s) => s.includes(mark));
|
|
558
|
+
if (ours.length === 0)
|
|
559
|
+
return 'not-installed';
|
|
560
|
+
for (const [hookEvent, sentinel] of events) {
|
|
561
|
+
const expected = hookCommand(agent, sentinel);
|
|
562
|
+
const ok = ours.some((s) => tomlSectionEvent(s) === hookEvent && tomlSectionCommand(s) === expected);
|
|
563
|
+
if (!ok)
|
|
564
|
+
return 'outdated';
|
|
565
|
+
}
|
|
566
|
+
return 'installed';
|
|
567
|
+
}
|
|
568
|
+
/** Merge termdock's `[[hooks]]` blocks into config.toml, preserving
|
|
569
|
+
* everything else (including the user's own hooks) byte-for-byte. */
|
|
570
|
+
export function tomlHooksInstall(file, agent, events) {
|
|
571
|
+
const text = readTextFile(file) ?? '';
|
|
572
|
+
const mark = marker(agent);
|
|
573
|
+
// Drop any previous termdock blocks (stale exe path / older event set)…
|
|
574
|
+
const kept = splitTomlSections(text).filter((s) => !s.includes(mark));
|
|
575
|
+
let out = kept.join('\n');
|
|
576
|
+
// …then append the fresh set at the end of the file, where new
|
|
577
|
+
// `[[hooks]]` tables can never swallow the user's trailing keys.
|
|
578
|
+
if (out.length > 0 && !out.endsWith('\n'))
|
|
579
|
+
out += '\n';
|
|
580
|
+
if (out.trim().length > 0)
|
|
581
|
+
out += '\n';
|
|
582
|
+
out += events
|
|
583
|
+
.map(([hookEvent, sentinel]) => tomlHookBlock(hookEvent, hookCommand(agent, sentinel)))
|
|
584
|
+
.join('\n\n');
|
|
585
|
+
out += '\n';
|
|
586
|
+
writeAtomic(file, out);
|
|
587
|
+
}
|
|
588
|
+
/** Remove every termdock `[[hooks]]` block, leaving the rest of the file
|
|
589
|
+
* (user hooks included) untouched. */
|
|
590
|
+
export function tomlHooksUninstall(file, agent) {
|
|
591
|
+
const text = readTextFile(file);
|
|
592
|
+
if (text === null)
|
|
593
|
+
return 'Nothing installed; nothing to remove';
|
|
594
|
+
const mark = marker(agent);
|
|
595
|
+
const sections = splitTomlSections(text);
|
|
596
|
+
const removed = sections.filter((s) => s.includes(mark)).length;
|
|
597
|
+
if (removed === 0)
|
|
598
|
+
return 'No termdock hooks found; nothing to remove';
|
|
599
|
+
const out = sections
|
|
600
|
+
.filter((s) => !s.includes(mark))
|
|
601
|
+
.join('\n')
|
|
602
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
603
|
+
.replace(/\n+$/, '\n');
|
|
604
|
+
writeAtomic(file, out);
|
|
605
|
+
return 'Removed';
|
|
606
|
+
}
|
|
607
|
+
// ---------------------------------------------------------------------------
|
|
476
608
|
// Public API — built-in agents
|
|
477
609
|
// ---------------------------------------------------------------------------
|
|
478
610
|
export function hooksState(agent) {
|
|
@@ -481,6 +613,8 @@ export function hooksState(agent) {
|
|
|
481
613
|
return hookMapState(file, agent, CLAUDE_HOOK_EVENTS);
|
|
482
614
|
if (agent === 'codex')
|
|
483
615
|
return hookMapState(file, agent, CODEX_HOOK_EVENTS);
|
|
616
|
+
if (agent === 'kimi')
|
|
617
|
+
return tomlHooksState(file, agent, KIMI_HOOK_EVENTS);
|
|
484
618
|
const expected = ownedFileContent(agent);
|
|
485
619
|
if (expected === null)
|
|
486
620
|
return 'not-installed';
|
|
@@ -518,6 +652,13 @@ export async function installHooks(agent) {
|
|
|
518
652
|
};
|
|
519
653
|
}
|
|
520
654
|
}
|
|
655
|
+
if (agent === 'kimi') {
|
|
656
|
+
tomlHooksInstall(file, agent, KIMI_HOOK_EVENTS);
|
|
657
|
+
return {
|
|
658
|
+
summary: 'Installed — run /reload in any open Kimi session (or restart it) for hooks to take effect',
|
|
659
|
+
devMode,
|
|
660
|
+
};
|
|
661
|
+
}
|
|
521
662
|
const content = ownedFileContent(agent);
|
|
522
663
|
if (content === null)
|
|
523
664
|
throw new Error(`no owned-file integration for ${agent}`);
|
|
@@ -529,6 +670,9 @@ export async function uninstallHooks(agent) {
|
|
|
529
670
|
if (agent === 'claude' || agent === 'codex') {
|
|
530
671
|
return hookMapUninstall(file, agent);
|
|
531
672
|
}
|
|
673
|
+
if (agent === 'kimi') {
|
|
674
|
+
return tomlHooksUninstall(file, agent);
|
|
675
|
+
}
|
|
532
676
|
return ownedFileUninstall(file, marker(agent));
|
|
533
677
|
}
|
|
534
678
|
/** Collect all plugin agents that define hooks. */
|
|
@@ -18,6 +18,7 @@ const AGENTS = [
|
|
|
18
18
|
{ slug: 'antigravity', displayName: 'Antigravity', aliases: ['agy', 'antigravity'], accentColor: '#2563EB', icon: null },
|
|
19
19
|
{ slug: 'grok', displayName: 'Grok', aliases: ['grok'], accentColor: '#000000', icon: 'grok' },
|
|
20
20
|
{ slug: 'qwen', displayName: 'Qwen Code', aliases: ['qwen', 'qwen-code'], accentColor: '#7C3AED', icon: null },
|
|
21
|
+
{ slug: 'kimi', displayName: 'Kimi Code', aliases: ['kimi', 'kimi-code'], accentColor: '#000000', icon: 'kimi' },
|
|
21
22
|
];
|
|
22
23
|
const BY_ALIAS = new Map();
|
|
23
24
|
const BY_SLUG = new Map();
|
|
@@ -137,6 +138,7 @@ function resumeCommandFor(agent, sessionId, flags) {
|
|
|
137
138
|
case 'cursor': return `cursor-agent${f} --resume ${sessionId}`;
|
|
138
139
|
case 'copilot': return `copilot${f} --resume ${sessionId}`;
|
|
139
140
|
case 'grok': return `grok${f} --resume ${sessionId}`;
|
|
141
|
+
case 'kimi': return `kimi${f} --session ${sessionId}`;
|
|
140
142
|
default: return null;
|
|
141
143
|
}
|
|
142
144
|
}
|
|
@@ -150,6 +152,7 @@ const STALE_SESSION_FLAGS = {
|
|
|
150
152
|
codex: ['--last'],
|
|
151
153
|
grok: ['--resume', '-r', '--load', '--continue', '-c', '--session-id', '-s',
|
|
152
154
|
'--fork-session', '--worktree', '-w', '--worktree-ref', '--ref'],
|
|
155
|
+
kimi: ['--session', '-S', '--continue', '-c'],
|
|
153
156
|
};
|
|
154
157
|
/**
|
|
155
158
|
* The launch-flag tail of argv worth replaying on a resume command, or null
|
package/dist/server/cli.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// libuv 线程池默认只有 4 个线程,慢/挂起的异步 IO(fs.promises、crypto 等)
|
|
3
|
+
// 会把池耗尽,表现为整个服务的 IO 全部卡死。必须在任何异步 fs 调用之前
|
|
4
|
+
// 设置(同步 fs 不占线程池,所以放在文件体顶部仍然足够早)。
|
|
5
|
+
process.env.UV_THREADPOOL_SIZE ||= '16';
|
|
2
6
|
import { config as loadDotenv } from 'dotenv';
|
|
3
7
|
import os from 'os';
|
|
4
8
|
import { resolve } from 'path';
|
|
@@ -1915,6 +1919,26 @@ async function ensureTmuxFocusEvents() {
|
|
|
1915
1919
|
maxBuffer: 64 * 1024,
|
|
1916
1920
|
});
|
|
1917
1921
|
}
|
|
1922
|
+
// Let tmux forward modified Enter keys (Ctrl/Shift/Alt+Enter) to pane apps.
|
|
1923
|
+
// The option only exists in tmux >= 3.2; on older versions the probe fails
|
|
1924
|
+
// and we silently skip.
|
|
1925
|
+
async function ensureTmuxExtendedKeys() {
|
|
1926
|
+
try {
|
|
1927
|
+
const { stdout } = await execFileAsync('tmux', ['show-options', '-gqv', 'extended-keys'], {
|
|
1928
|
+
timeout: 5000,
|
|
1929
|
+
maxBuffer: 64 * 1024,
|
|
1930
|
+
});
|
|
1931
|
+
if (stdout.trim() === 'on')
|
|
1932
|
+
return;
|
|
1933
|
+
await execFileAsync('tmux', ['set-option', '-g', 'extended-keys', 'on'], {
|
|
1934
|
+
timeout: 5000,
|
|
1935
|
+
maxBuffer: 64 * 1024,
|
|
1936
|
+
});
|
|
1937
|
+
}
|
|
1938
|
+
catch {
|
|
1939
|
+
// extended-keys unsupported on this tmux; nothing to do
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1918
1942
|
async function ensureTmuxScrollbackProfile(sessionName) {
|
|
1919
1943
|
await execFileAsync('tmux', ['set-option', '-g', 'history-limit', String(TERMDOCK_TMUX_HISTORY_LIMIT)], {
|
|
1920
1944
|
timeout: 5000,
|
|
@@ -2060,6 +2084,7 @@ async function ensureStampedTmuxSession(sessionName, cwd) {
|
|
|
2060
2084
|
});
|
|
2061
2085
|
}
|
|
2062
2086
|
await ensureTmuxFocusEvents();
|
|
2087
|
+
await ensureTmuxExtendedKeys();
|
|
2063
2088
|
await ensureTmuxColorEnvironment(sessionName);
|
|
2064
2089
|
await ensureTmuxCliSessionOptions(sessionName);
|
|
2065
2090
|
await setTmuxOption(sessionName, '@termdock-version', TERMDOCK_VERSION);
|
package/dist/server/entry.js
CHANGED
|
@@ -22,20 +22,38 @@ import { isUpgradeRequestAuthenticated, requireAuth } from './utils/authProtecti
|
|
|
22
22
|
import { localAccessManager } from './utils/localAccess.js';
|
|
23
23
|
import { isAllowedHost, isUpgradeOriginAllowed, validateHostMiddleware, } from './utils/requestSecurity.js';
|
|
24
24
|
import { getCookieSecurityOptions, setSecureCookieMode } from './utils/cookieSecurity.js';
|
|
25
|
+
import { requestDeadlineMiddleware } from './utils/requestDeadline.js';
|
|
25
26
|
import { startOnboardingServer, stopOnboardingServer, getOnboardingServerUrl } from './onboardingServer.js';
|
|
26
27
|
import { CertificateWatcher } from './certificateWatcher.js';
|
|
27
28
|
import { writeDiffTraceLog, writeErrorLog, writeJsonLog, writeTextLog } from './utils/serverLogger.js';
|
|
29
|
+
import { resolveRuntimeClientDist } from './utils/runtimeClient.js';
|
|
28
30
|
import { getTermdockVersion, TERMDOCK_CAPABILITIES, TERMDOCK_PROTOCOL_VERSION, } from './utils/version.js';
|
|
29
31
|
import { PORT, DEFAULT_HOST } from './config.js';
|
|
30
32
|
const CLIENT_STATE_COOKIE = 'termdock-client';
|
|
31
33
|
export const DEFAULT_PORT = PORT.backend;
|
|
34
|
+
/** Read one cookie from a raw Cookie header (upgrade requests bypass the
|
|
35
|
+
* cookie-parser middleware). Values are percent-encoded. */
|
|
36
|
+
function getCookieValue(cookieHeader, name) {
|
|
37
|
+
if (!cookieHeader)
|
|
38
|
+
return undefined;
|
|
39
|
+
const pattern = new RegExp(`(?:^|;\\s*)${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}=([^;]*)`);
|
|
40
|
+
const match = cookieHeader.match(pattern);
|
|
41
|
+
if (!match)
|
|
42
|
+
return undefined;
|
|
43
|
+
try {
|
|
44
|
+
return decodeURIComponent(match[1]);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return match[1];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
32
50
|
const CLIENT_LOG_DEDUP_WINDOW_MS = 5_000;
|
|
33
51
|
const CLIENT_LOG_RATE_WINDOW_MS = 10_000;
|
|
34
52
|
const CLIENT_LOG_RATE_LIMIT = 120;
|
|
35
53
|
const currentFilePath = fileURLToPath(import.meta.url);
|
|
36
54
|
const currentDirPath = path.dirname(currentFilePath);
|
|
37
|
-
const
|
|
38
|
-
const
|
|
55
|
+
const bundledClientDistPath = path.resolve(currentDirPath, '../client');
|
|
56
|
+
const bundledClientIndexPath = path.join(bundledClientDistPath, 'index.html');
|
|
39
57
|
const clientLogRecent = new Map();
|
|
40
58
|
let clientLogWindowStartedAt = 0;
|
|
41
59
|
let clientLogWindowCount = 0;
|
|
@@ -302,6 +320,9 @@ export function createApp(options = {}) {
|
|
|
302
320
|
});
|
|
303
321
|
next();
|
|
304
322
|
});
|
|
323
|
+
// 全局请求兜底超时:任何 handler 挂起最多活 30s(长连接流按表豁免),
|
|
324
|
+
// 到期销毁 socket 释放浏览器连接槽。必须在所有路由与静态资源之前挂载。
|
|
325
|
+
app.use(requestDeadlineMiddleware());
|
|
305
326
|
app.use('/api', (req, res, next) => {
|
|
306
327
|
// JSON/API responses must never hit browser conditional caching. A 304 with
|
|
307
328
|
// an empty body breaks fetch().json() callers and looks like random IO
|
|
@@ -397,18 +418,36 @@ export function createApp(options = {}) {
|
|
|
397
418
|
app.use('/api/terminal', terminalRoutes);
|
|
398
419
|
// 文件系统路由(继承 /api/terminal 上的 auth + CSRF 保护)
|
|
399
420
|
app.use('/api/terminal/fs', filesystemRoutes);
|
|
400
|
-
if (fs.existsSync(
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
421
|
+
if (fs.existsSync(bundledClientIndexPath)) {
|
|
422
|
+
let cachedClientPath = '';
|
|
423
|
+
let cachedCompression = null;
|
|
424
|
+
let cachedStatic = null;
|
|
425
|
+
const activeClientHandlers = () => {
|
|
426
|
+
const clientPath = resolveRuntimeClientDist(bundledClientDistPath);
|
|
427
|
+
if (clientPath !== cachedClientPath || !cachedCompression || !cachedStatic) {
|
|
428
|
+
cachedClientPath = clientPath;
|
|
429
|
+
cachedCompression = createStaticCompressionMiddleware(clientPath);
|
|
430
|
+
cachedStatic = express.static(clientPath, {
|
|
431
|
+
setHeaders: (res, filePath, stat) => {
|
|
432
|
+
void stat;
|
|
433
|
+
const relativePath = `/${path.relative(clientPath, filePath).split(path.sep).join('/')}`;
|
|
434
|
+
setStaticCacheHeaders({ url: relativePath, path: relativePath }, res);
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
return { clientPath, compression: cachedCompression, staticFiles: cachedStatic };
|
|
439
|
+
};
|
|
440
|
+
app.use((req, res, next) => {
|
|
441
|
+
const handlers = activeClientHandlers();
|
|
442
|
+
handlers.compression(req, res, (compressionError) => {
|
|
443
|
+
if (compressionError)
|
|
444
|
+
return next(compressionError);
|
|
445
|
+
handlers.staticFiles(req, res, next);
|
|
446
|
+
});
|
|
447
|
+
});
|
|
409
448
|
app.get(/^(?!\/api(?:\/|$)|\/health$|\/onboarding(?:\/|$)|\/ca(?:\/|$)).*/, (req, res) => {
|
|
410
449
|
setStaticCacheHeaders(req, res);
|
|
411
|
-
res.sendFile(
|
|
450
|
+
res.sendFile(path.join(activeClientHandlers().clientPath, 'index.html'));
|
|
412
451
|
});
|
|
413
452
|
}
|
|
414
453
|
return app;
|
|
@@ -523,11 +562,12 @@ export function startServer(options = {}) {
|
|
|
523
562
|
}
|
|
524
563
|
const sessionId = match[1];
|
|
525
564
|
const clientId = crypto.randomUUID();
|
|
565
|
+
const pushClientId = getCookieValue(cookieHeader, CLIENT_STATE_COOKIE);
|
|
526
566
|
// 短线重连时客户端会带上 ?since=<lastSeq>,让服务端只补发增量。
|
|
527
567
|
const sinceParam = url.searchParams.get('since');
|
|
528
568
|
const sinceSeq = sinceParam ? Math.max(0, Number.parseInt(sinceParam, 10) || 0) : 0;
|
|
529
569
|
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
530
|
-
handleTerminalWebSocket(ws, sessionId, clientId, { sinceSeq });
|
|
570
|
+
handleTerminalWebSocket(ws, sessionId, clientId, { sinceSeq, pushClientId });
|
|
531
571
|
});
|
|
532
572
|
});
|
|
533
573
|
server.listen(port, host, () => {
|