@loicngr/kobo 1.11.39 → 1.11.41
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/AGENTS.md +101 -32
- package/CHANGELOG.md +8 -0
- package/README.md +6 -4
- package/dist/mcp-server/kobo-tasks-handlers.js +16 -9
- package/dist/mcp-server/kobo-tasks-server.js +13 -2
- package/dist/mcp-server/workspace-dialogue-client.js +28 -0
- package/dist/server/db/mcp-message-schema.js +16 -0
- package/dist/server/db/migrations.js +4 -0
- package/dist/server/db/schema.js +4 -0
- package/dist/server/db/search-schema.js +53 -0
- package/dist/server/index.js +17 -86
- package/dist/server/middleware/network-auth-middleware.js +5 -1
- package/dist/server/routes/changelog.js +4 -49
- package/dist/server/routes/git.js +2 -2
- package/dist/server/routes/images.js +65 -5
- package/dist/server/routes/mcp.js +47 -0
- package/dist/server/routes/pull-requests.js +1 -1
- package/dist/server/routes/search.js +13 -4
- package/dist/server/routes/settings.js +5 -0
- package/dist/server/routes/workspaces.js +250 -248
- package/dist/server/services/agent/engines/claude-code/engine.js +31 -33
- package/dist/server/services/agent/engines/codex/engine.js +37 -8
- package/dist/server/services/agent/engines/codex/event-mapper.js +3 -1
- package/dist/server/services/agent/engines/codex/options-builder.js +4 -3
- package/dist/server/services/agent/engines/codex/server-requests.js +8 -1
- package/dist/server/services/agent/orchestrator.js +20 -3
- package/dist/server/services/attachment-service.js +122 -0
- package/dist/server/services/change-source-branch-service.js +10 -42
- package/dist/server/services/chat-receipt-service.js +33 -0
- package/dist/server/services/cron-service.js +27 -1
- package/dist/server/services/image-service.js +16 -7
- package/dist/server/services/mcp-client-context.js +12 -0
- package/dist/server/services/mcp-connection-info-service.js +63 -0
- package/dist/server/services/mcp-message-delivery-service.js +59 -0
- package/dist/server/services/mcp-message-request-service.js +64 -0
- package/dist/server/services/pr-checkout-service.js +10 -10
- package/dist/server/services/pr-watcher-service.js +14 -9
- package/dist/server/services/search/indexer.js +232 -0
- package/dist/server/services/search/worker.js +76 -0
- package/dist/server/services/search-service.js +104 -110
- package/dist/server/services/update-check-service.js +119 -0
- package/dist/server/services/websocket-service.js +121 -35
- package/dist/server/services/workspace-dialogue-service.js +128 -0
- package/dist/server/services/workspace-message-service.js +58 -0
- package/dist/server/services/workspace-permission-policy-service.js +33 -3
- package/dist/server/services/worktree-restore-service.js +2 -2
- package/dist/server/services/worktree-service.js +197 -124
- package/dist/server/utils/bounded-process.js +137 -0
- package/dist/server/utils/git-ops.js +76 -128
- package/dist/server/utils/git-repo-lock.js +27 -13
- package/dist/shared/attachments.js +58 -0
- package/dist/shared/workspace-dialogue-tools.js +89 -0
- package/dist/shared/workspace-message-types.js +19 -0
- package/package.json +2 -1
- package/src/client/dist/pwa/assets/{ActivityFeed-Chsw1Mh7.css → ActivityFeed-BYR5x7aa.css} +1 -1
- package/src/client/dist/pwa/assets/ActivityFeed-DTIe6O9o.js +8 -0
- package/src/client/dist/pwa/assets/{ChangelogPage-D8563008.js → ChangelogPage-BWeu0YeI.js} +1 -1
- package/src/client/dist/pwa/assets/{ComparisonPanel-Bd0X08sg.js → ComparisonPanel-o_EHlTwV.js} +2 -2
- package/src/client/dist/pwa/assets/CreatePage-CGi88k6z.css +1 -0
- package/src/client/dist/pwa/assets/CreatePage-DbY5gBv8.js +2 -0
- package/src/client/dist/pwa/assets/DashboardPage-CIo_gesD.js +1 -0
- package/src/client/dist/pwa/assets/{DiffViewer-DnR79ycb.css → DiffViewer-DEPOa3D7.css} +1 -1
- package/src/client/dist/pwa/assets/DiffViewer-DEcf48KI.js +8 -0
- package/src/client/dist/pwa/assets/{DocumentsPanel-BJsJ0fNs.js → DocumentsPanel-D9vcB91W.js} +1 -1
- package/src/client/dist/pwa/assets/{DrawerToggleButton-BVLO5K5d.js → DrawerToggleButton-Ca0_CxSl.js} +1 -1
- package/src/client/dist/pwa/assets/GitPanel-DCmB2R5i.js +3 -0
- package/src/client/dist/pwa/assets/{HealthPage-RFZS7Lao.js → HealthPage-_q3vy_xn.js} +1 -1
- package/src/client/dist/pwa/assets/MainLayout-Duwnq3cc.js +2 -0
- package/src/client/dist/pwa/assets/{QBtnDropdown-X8oNU5Mb.js → QBtnDropdown-BeiZIHVA.js} +1 -1
- package/src/client/dist/pwa/assets/{QDrawer-Cij17skX.js → QDrawer-Fj3M9QGD.js} +1 -1
- package/src/client/dist/pwa/assets/QSelect-DtSUuK8t.js +1 -0
- package/src/client/dist/pwa/assets/{QTooltip-CwcCGSWq.js → QTooltip-DwkX8eQ6.js} +1 -1
- package/src/client/dist/pwa/assets/SchedulePanel-BAA4Aajn.css +1 -0
- package/src/client/dist/pwa/assets/SchedulePanel-BlZDd7TK.js +1 -0
- package/src/client/dist/pwa/assets/SearchPage-BGc1oQSM.css +1 -0
- package/src/client/dist/pwa/assets/SearchPage-BGi1yRxU.js +1 -0
- package/src/client/dist/pwa/assets/SettingsPage-DnO-ImWE.js +9 -0
- package/src/client/dist/pwa/assets/SettingsPage-sVlsJQ0b.css +1 -0
- package/src/client/dist/pwa/assets/{SplitWorkspacePage-D7lGFRKs.js → SplitWorkspacePage-vz6jN1DM.js} +1 -1
- package/src/client/dist/pwa/assets/{TerminalPanel-DI8DHb9e.js → TerminalPanel-IdPIGp2_.js} +9 -9
- package/src/client/dist/pwa/assets/{TouchPan-B3nrkCY8.js → TouchPan-DTJqxVp9.js} +1 -1
- package/src/client/dist/pwa/assets/{TourReplayButton-DU1UShMY.js → TourReplayButton-Bj2GGyhU.js} +1 -1
- package/src/client/dist/pwa/assets/{WorkspaceAttentionLabels-C-yN5IX8.js → WorkspaceAttentionLabels-BBaGZlwv.js} +1 -1
- package/src/client/dist/pwa/assets/WorkspacePage-DCg9zSxz.css +1 -0
- package/src/client/dist/pwa/assets/WorkspacePage-Dy0spsfi.js +4 -0
- package/src/client/dist/pwa/assets/{browser-f9MHQjfi.js → browser-BFj5wwbS.js} +1 -1
- package/src/client/dist/pwa/assets/{build-path-tree-BWBzP8os.js → build-path-tree-C-HSiySk.js} +1 -1
- package/src/client/dist/pwa/assets/de-BdLe7apJ.js +17 -0
- package/src/client/dist/pwa/assets/{documents-C2cLnEBQ.js → documents-C2Xnjh9Z.js} +1 -1
- package/src/client/dist/pwa/assets/{editor.api-sw146MWN.js → editor.api-BbKfnNmv.js} +1 -1
- package/src/client/dist/pwa/assets/{efforts-C5ZZgCH4.js → efforts-BM7fdaaL.js} +1 -1
- package/src/client/dist/pwa/assets/engineFeatures-b74YRODT.js +1 -0
- package/src/client/dist/pwa/assets/es-C1LM-3aq.js +17 -0
- package/src/client/dist/pwa/assets/expand-template-DiDWiIkx.js +1 -0
- package/src/client/dist/pwa/assets/{format-BwWP6Aay.js → format-CnbUxAmw.js} +1 -1
- package/src/client/dist/pwa/assets/{formatters-DyWtO-nR.js → formatters-B2uUIbAY.js} +1 -1
- package/src/client/dist/pwa/assets/fr-KCK6r5ga.js +17 -0
- package/src/client/dist/pwa/assets/{freemarker2-DZ5Hm8UH.js → freemarker2-Cu1vGY0x.js} +1 -1
- package/src/client/dist/pwa/assets/{handlebars-BRUGpTA7.js → handlebars-CETuqLyz.js} +1 -1
- package/src/client/dist/pwa/assets/{html-DNOayNNs.js → html-BTNpr39P.js} +1 -1
- package/src/client/dist/pwa/assets/i18n-BkUirOzl.js +1 -0
- package/src/client/dist/pwa/assets/index-mvh5w1cM.js +20 -0
- package/src/client/dist/pwa/assets/it-BM6t0IGU.js +17 -0
- package/src/client/dist/pwa/assets/{javascript-C0tDQU3z.js → javascript-C7Ncb6V7.js} +1 -1
- package/src/client/dist/pwa/assets/{liquid-CN46O6OF.js → liquid-D0hUdg4x.js} +1 -1
- package/src/client/dist/pwa/assets/{mdx-DM-lrr8Q.js → mdx-BK5H1Xst.js} +1 -1
- package/src/client/dist/pwa/assets/{monaco-contributions-CkN7y-8c.js → monaco-contributions-BBW6JNgz.js} +1 -1
- package/src/client/dist/pwa/assets/{monaco.contribution-2BcAOLjc.js → monaco.contribution-1LZrAlY4.js} +2 -2
- package/src/client/dist/pwa/assets/network-auth-CVGS__6a.js +1 -0
- package/src/client/dist/pwa/assets/{notify-theme-a91Tcr6o.js → notify-theme-DIKLxr8F.js} +1 -1
- package/src/client/dist/pwa/assets/{pending-diff-open-DOtELZfB.js → pending-diff-open-B02zuH1j.js} +1 -1
- package/src/client/dist/pwa/assets/{permissionModes-C-9Crj-c.js → permissionModes-C3otN1Vk.js} +1 -1
- package/src/client/dist/pwa/assets/{project-color-BRe4oyNx.js → project-color-BUcW_eZA.js} +1 -1
- package/src/client/dist/pwa/assets/{python-BRpJG6sZ.js → python-DEeUVvnp.js} +1 -1
- package/src/client/dist/pwa/assets/{razor-CehCmvHl.js → razor-CG6cL8ya.js} +1 -1
- package/src/client/dist/pwa/assets/{render-chat-markdown-DlbQLZ02.js → render-chat-markdown-Ct_T5TPN.js} +1 -1
- package/src/client/dist/pwa/assets/{typescript-Dt_8mVuj.js → typescript-CSQAg5UC.js} +1 -1
- package/src/client/dist/pwa/assets/use-search-index-status-DtLzygcy.js +1 -0
- package/src/client/dist/pwa/assets/use-tours-_6HwJ_Rp.js +2 -0
- package/src/client/dist/pwa/assets/{workspace-templates-GCObcjO6.js → workspace-templates-B8WWsWEI.js} +1 -1
- package/src/client/dist/pwa/assets/{xml-_gOwdzB4.js → xml-BSB4-DXR.js} +1 -1
- package/src/client/dist/pwa/assets/{yaml-BxeBqpGf.js → yaml-CSGKph85.js} +1 -1
- package/src/client/dist/pwa/index.html +1 -1
- package/src/client/dist/pwa/sw.js +1 -1
- package/src/mcp-server/README.md +169 -9
- package/src/mcp-server/kobo-tasks-handlers.ts +14 -11
- package/src/mcp-server/kobo-tasks-server.ts +19 -2
- package/src/mcp-server/workspace-dialogue-client.ts +34 -0
- package/src/client/dist/pwa/assets/ActivityFeed-BzzvcOmq.js +0 -8
- package/src/client/dist/pwa/assets/CreatePage-A3pVradx.css +0 -1
- package/src/client/dist/pwa/assets/CreatePage-Bon8qIka.js +0 -2
- package/src/client/dist/pwa/assets/DashboardPage-DYxdxEul.js +0 -1
- package/src/client/dist/pwa/assets/DiffViewer-BpsLNxnj.js +0 -8
- package/src/client/dist/pwa/assets/GitPanel-Cal_wzC0.js +0 -3
- package/src/client/dist/pwa/assets/MainLayout-vvyiRcql.js +0 -2
- package/src/client/dist/pwa/assets/QSelect-xd-AlGo_.js +0 -1
- package/src/client/dist/pwa/assets/SchedulePanel-BunlzsOY.css +0 -1
- package/src/client/dist/pwa/assets/SchedulePanel-CXRUsz6G.js +0 -1
- package/src/client/dist/pwa/assets/SearchPage-CVgRa025.css +0 -1
- package/src/client/dist/pwa/assets/SearchPage-DopbgLxh.js +0 -1
- package/src/client/dist/pwa/assets/SettingsPage-Do9d0Pov.css +0 -1
- package/src/client/dist/pwa/assets/SettingsPage-Jx6TnOzR.js +0 -9
- package/src/client/dist/pwa/assets/WorkspacePage-BAC6u9OP.css +0 -1
- package/src/client/dist/pwa/assets/WorkspacePage-DKRpdpPg.js +0 -4
- package/src/client/dist/pwa/assets/de-QkDLrcGq.js +0 -17
- package/src/client/dist/pwa/assets/engineFeatures-CAVMDawq.js +0 -1
- package/src/client/dist/pwa/assets/es-BgQFKlo8.js +0 -17
- package/src/client/dist/pwa/assets/expand-template-B6xAlAaM.js +0 -1
- package/src/client/dist/pwa/assets/fr-DAdLWjNM.js +0 -17
- package/src/client/dist/pwa/assets/i18n-CBez_vip.js +0 -1
- package/src/client/dist/pwa/assets/index-VL3fI9a3.js +0 -20
- package/src/client/dist/pwa/assets/it-Bumaewp1.js +0 -17
- package/src/client/dist/pwa/assets/network-auth-KYS4snQH.js +0 -1
- package/src/client/dist/pwa/assets/use-tours-CSVM_54K.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
if(!self.define){let s,e={};const a=(a,r)=>(a=new URL(a+".js",r).href,e[a]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=a,s.onload=e,document.head.appendChild(s)}else s=a,importScripts(a),e()}).then(()=>{let s=e[a];if(!s)throw new Error(`Module ${a} didn’t register its module`);return s}));self.define=(r,i)=>{const d=s||("document"in self?document.currentScript.src:"")||location.href;if(e[d])return;let c={};const f=s=>a(s,d),b={module:{uri:d},exports:c,require:f};e[d]=Promise.all(r.map(s=>b[s]||f(s))).then(s=>(i(...s),c))}}define(["./workbox-778a14ff"],function(s){"use strict";s.setCacheNameDetails({prefix:"kobo-client"}),self.addEventListener("message",s=>{s.data&&"SKIP_WAITING"===s.data.type&&self.skipWaiting()}),s.clientsClaim(),s.precacheAndRoute([{url:"manifest.json",revision:"73f02ba4eb4414fb70bbe5ca76cc9580"},{url:"index.html",revision:"79834ad0479d897318bb969a161432a1"},{url:"favicon.svg",revision:"9d89ef10d49f14d08c25cfca9bd4ea75"},{url:"sounds/yaaa.mp3",revision:"2161c5eb77ac61349f6fe573f62d8404"},{url:"sounds/warcraft-3-humain-travail.mp3",revision:"0b8bd1b9be23803c3ac84eaf0d1b5287"},{url:"sounds/tu-vas-la-fermer.mp3",revision:"1688aaa18b0a307a3016c3fd39321f59"},{url:"sounds/travail_termine.mp3",revision:"a194c4cc479b59ba13746b08bca634b9"},{url:"sounds/ta-gueule.mp3",revision:"44aa9b15c9abe9a846f8034a23482b24"},{url:"sounds/pas-ca-zinedine.mp3",revision:"57ec46faf5b7d1c2f370d7167e284f04"},{url:"sounds/ouais-cest-greg.mp3",revision:"55624f422636b19422b3bc700aa8da9e"},{url:"sounds/nan-wallah-pardon.mp3",revision:"16edfe0a39fde73db0f30a7a067a77ff"},{url:"sounds/nan-tu-degages.mp3",revision:"282678eceb54e09eb8a7edf4f9fb0e21"},{url:"sounds/mais-laisse-moi-dormir-zebi.mp3",revision:"05d8419f91effcf56a6d09ed35544d06"},{url:"sounds/hey.mp3",revision:"e68017c8f32b3e815e339dad099dc830"},{url:"sounds/gta-v-death.mp3",revision:"72eaa8958882d5f2040f4b9b4f3ba620"},{url:"sounds/for-shure.mp3",revision:"71dd2a2c874a04e67613d49045d926e7"},{url:"sounds/faaah.mp3",revision:"a0220dd11038add054573c26d2f0b6ac"},{url:"sounds/dry-fart.mp3",revision:"afdf096e4a705d908392ed9b4f827bc9"},{url:"sounds/ca_va_peter.mp3",revision:"004452d7682a043e1c13e213a1a56766"},{url:"sounds/basic-notification.mp3",revision:"3f6df726a5e85560dfecf4bb592d2fda"},{url:"sounds/bah-alors-on-est-nul.mp3",revision:"b30241371b49465f62997213bcdfe4b2"},{url:"sounds/arretez-les-messages.mp3",revision:"26f667dccdfddb8c534a5482475b729a"},{url:"sounds/arrete-de-mentir.mp3",revision:"1a9b5157f362dd3e0acc479da4fea708"},{url:"sounds/aller-ftg.mp3",revision:"bcc00bd838e61eb9571c8fdc0f400d19"},{url:"sounds/7eme-compagnie-03.mp3",revision:"49ee08dd595e0e9659042e4e854b0141"},{url:"fonts/GeistMono-Variable.woff2",revision:"308360d8a547331fd40bc09a7145d59a"},{url:"fonts/Geist-Variable.woff2",revision:"dfa48d5a853753289194436953e3f202"},{url:"fonts/GEIST-LICENSE.txt",revision:"563d13575f813953c3151e1ecce3b76f"},{url:"assets/yaml-BxeBqpGf.js",revision:"a28b9637c7baca53bedc991cd5f0e7a1"},{url:"assets/xml-_gOwdzB4.js",revision:"dc09aaf8ef632f5fe5a553e7917daa90"},{url:"assets/workspace-templates-GCObcjO6.js",revision:"5cb5a66a1da5927099a2a4b579154a9e"},{url:"assets/workspace-page-layout-Dw9NhZsL.js",revision:"0c933f7b6c6bf3c90ea1875abad85392"},{url:"assets/wgsl-DpFanUEy.js",revision:"4cf32279d7c6a601611a6e32a14f3b1e"},{url:"assets/vb-DV3o63ZY.js",revision:"a5b3a756d667f5e4a5da6da4013d7341"},{url:"assets/use-tours-CTZuBZOi.css",revision:"2f6d79046e1409f0472f65179eaa76f3"},{url:"assets/use-tours-CSVM_54K.js",revision:"ba5aa48efbce9adc734c38834a3d6a1e"},{url:"assets/use-is-mobile-CWjqe8gC.js",revision:"d1c4af193dfd98b8d775c51ddcbd45a0"},{url:"assets/use-id-BIuaWKkB.js",revision:"515b4eadf57c35d0e2b42311ccc01993"},{url:"assets/use-checkbox-FnauAgTp.js",revision:"298e92c55534c2c194c6fa1ef7a9ea6f"},{url:"assets/typespec-B8J7ngcE.js",revision:"6c28560625f59db6a5897aa92de81033"},{url:"assets/typescript-Dt_8mVuj.js",revision:"0b7aedc6082dfdd746cf947ee296816c"},{url:"assets/twig-De2hgUGE.js",revision:"dfb4c76c8ec0d822070abac68d2bd473"},{url:"assets/tcl-DISqw1ZD.js",revision:"6d0ddaebd76ad41c47c96d484af119f8"},{url:"assets/systemverilog-Bz4Y3fRF.js",revision:"18e6d6e82eeb1107458d8d5531f82246"},{url:"assets/swift-Bxkupp3x.js",revision:"65b88f49188974d7c12e1a6cd12a9de5"},{url:"assets/st-DbInun42.js",revision:"d7294c4d47351db4e5edd4d91e445a21"},{url:"assets/sql-NEE52Syq.js",revision:"48352e15fff2141c7deaaab4e51e9565"},{url:"assets/sparql-D_Lu-MrJ.js",revision:"65390637b1a24614803db6844a0db77b"},{url:"assets/sophia-CRfGWb83.js",revision:"a330db913fee26a14679bed631a59043"},{url:"assets/solidity-BEEn4gHE.js",revision:"c2cd02221ec3d86f9a6bb09bfb1f8978"},{url:"assets/shell-CC2rA5mh.js",revision:"8362d325cda511ef760335e0847d3910"},{url:"assets/scss-gp-XZpBa.js",revision:"bf0805dd5cd80d90fef58c9866a7751e"},{url:"assets/scheme-BeGwcela.js",revision:"55c990715708ea012165486d065b3e2c"},{url:"assets/scala-DHpiXF5c.js",revision:"4eeea167d27954255e39d91412b62f87"},{url:"assets/sb-CcwsVR0C.js",revision:"93fc05f23a9cbb96d4f72dbc73e2e53b"},{url:"assets/rust-DdL9SqIa.js",revision:"356bac76300c8d83e8e9d76becf3c9ea"},{url:"assets/runtime-core.esm-bundler-CDnVUfeZ.js",revision:"958c358bc7005237e86c709b3248ae06"},{url:"assets/ruby-DezsRK8O.js",revision:"95c3294c6d6cead3cccd7e4e973ab964"},{url:"assets/restructuredtext-BYgofb2h.js",revision:"f75377ae694f4e8f0bcccd05b5b9e65c"},{url:"assets/render-chat-markdown-DlbQLZ02.js",revision:"fbfd3f0183f4a8b401c1eca88f88ff5b"},{url:"assets/redshift-DT7zqm-g.js",revision:"44e23f67b6a02e60d28c9947cd025207"},{url:"assets/redis-ClamHrr6.js",revision:"e3141183a6756253db43e10f8a305787"},{url:"assets/reactivity.esm-bundler-DEJj9cFv.js",revision:"202b2fcc10c0494e359dc0181e4d28e8"},{url:"assets/razor-CehCmvHl.js",revision:"972ed7d0780d9c9b4f1f1efa77173c3a"},{url:"assets/r-BwWrilGY.js",revision:"f18d3e790ef07bc993539322d29548e4"},{url:"assets/qsharp-DkqhCAOL.js",revision:"c53fe08a83f8fcbcd81723105136a691"},{url:"assets/python-BRpJG6sZ.js",revision:"7c6a52ac78f5311d182da379fc7b79ae"},{url:"assets/pug-Z5eAx3Zn.js",revision:"6e3de6d5214d2cf61b90949e1d383b49"},{url:"assets/protobuf-C531GsRP.js",revision:"04e688a7fef2bde8cef525653497371f"},{url:"assets/project-color-BRe4oyNx.js",revision:"335686f0d733922d809200a073060cf3"},{url:"assets/private.use-form-C7umbGO-.js",revision:"115ec085187459512189754b7325cea5"},{url:"assets/powershell-DmHpPYUd.js",revision:"ff476e9c4398edc9dfd2eb0ee9356352"},{url:"assets/powerquery-D3hlyOfw.js",revision:"0cacccadbe7cd4415f9a3112763c89f3"},{url:"assets/postiats-43DmfD33.js",revision:"b5dbce3331b7ccb325853328702b4bd9"},{url:"assets/pla-CopQ2nXW.js",revision:"b31678678d642accba98d7e7249a20b2"},{url:"assets/pinia-BKqmoVru.js",revision:"309cc3e9d7688b550c4490f51a28959f"},{url:"assets/php-nr791fC2.js",revision:"ee487693840b66c2abf7c2da872dd6a8"},{url:"assets/pgsql-DTj74zXo.js",revision:"75375029d157fc5e789a13718eed9da7"},{url:"assets/permissionModes-C-9Crj-c.js",revision:"949d11916a971d31dcc083b91ff4906a"},{url:"assets/perl-oz_6vUea.js",revision:"fee6d319d328db438b336b52ac07a46a"},{url:"assets/pending-diff-open-DOtELZfB.js",revision:"28c6cd943960db3f61d69cf711a9482a"},{url:"assets/pascaligo-D-ptJ9y-.js",revision:"88be4e81a252f44f049ac92f7b6ea518"},{url:"assets/pascal-DrH0SRf2.js",revision:"0d81121099a69b47e10701bf075fe3cd"},{url:"assets/objective-c-FvmIjYaQ.js",revision:"6d64543dd4430fb71bcd7a5347a0398c"},{url:"assets/notify-theme-a91Tcr6o.js",revision:"189b31fbaeee43ba3fda4d6179047019"},{url:"assets/network-auth-KYS4snQH.js",revision:"8e2f0cb8d15c6f86c68f2464f8e175f6"},{url:"assets/mysql-SOo6toE5.js",revision:"677c089d979324385539e96bd2eb11e4"},{url:"assets/msdax-DauUninz.js",revision:"a63bfea2dd041755a34fe3e307159413"},{url:"assets/monaco.contribution-2BcAOLjc.js",revision:"bf51044863922216b8caac3faeee7172"},{url:"assets/monaco-contributions-CkN7y-8c.js",revision:"fc2879ae74c1a27229656128bc22bc27"},{url:"assets/monaco-contributions-Cb0afGfW.css",revision:"9c8dff3575c2e943e7ad49f78bbdb6d2"},{url:"assets/mips-CIPQ_RoX.js",revision:"b22614ddc8855670a3f76290908877f5"},{url:"assets/mdx-DM-lrr8Q.js",revision:"36360b5c86beb5617853f6c1b45e88fe"},{url:"assets/markdown-Cimd5fb3.js",revision:"38eaa88ca7719b9da2894b7c26f2f65b"},{url:"assets/m3-D-oSqn_W.js",revision:"624c73b0332fe1ddfef6013306c5998d"},{url:"assets/lua-CsQS60Ue.js",revision:"5568edf60b64f912bd17561f26e03d44"},{url:"assets/liquid-CN46O6OF.js",revision:"1ef9a5c36588f1edc5be1945c7d4027a"},{url:"assets/lexon-CfSJPG6W.js",revision:"32b224ffe991474a4cfcbed19971a98d"},{url:"assets/less-B9JPFI3C.js",revision:"c80573ae2313727c545a585d90d3ff36"},{url:"assets/kotlin-BOotOW0E.js",revision:"7c2a31b16b6ddc97b60891b09afa11b1"},{url:"assets/julia-Bri6UV-V.js",revision:"bb5062cdf870c17c7c9be635c1a8a3be"},{url:"assets/javascript-C0tDQU3z.js",revision:"85c66b992a5b51009d674f003beee2f2"},{url:"assets/java-BEtHBSE6.js",revision:"987edcd2170749acca47ea184dd9ab25"},{url:"assets/it-Bumaewp1.js",revision:"a1de7f7c90da3353aa39ab0f0d6ac9f1"},{url:"assets/ini-sBoK_t0W.js",revision:"35f8ec10844ea4f62c2712d3f5c1e129"},{url:"assets/index-VL3fI9a3.js",revision:"5ee96a6aa9b12ffb7013decfebd1a088"},{url:"assets/index-CUoUy6tH.css",revision:"a8c1e129e4ca8531dff2ac89ad0d6778"},{url:"assets/i18n-CBez_vip.js",revision:"98a6d38e2ff01cd2f8df29eeb5c20d2d"},{url:"assets/html-DNOayNNs.js",revision:"0b6c71ea301714cb1353886a82cf039b"},{url:"assets/hcl-CpzslTdj.js",revision:"f9ef1004e908957ec1c3bbea2049a0e9"},{url:"assets/handlebars-BRUGpTA7.js",revision:"1fdfde77037fc8accb12b7abaa2d255f"},{url:"assets/graphql-fmXr3nnJ.js",revision:"a51df1d5dca011f5d85dd09a2ffbe1e5"},{url:"assets/go-C-y9NEjX.js",revision:"9213c8381eb32996b86ca9600ca6a07e"},{url:"assets/fsharp-C8Ef5oNN.js",revision:"72f3de59be781f8a4ec49d16bac02119"},{url:"assets/freemarker2-DZ5Hm8UH.js",revision:"0101edb225bc09e409a5941946f013e6"},{url:"assets/fr-DAdLWjNM.js",revision:"5c85a822e4034fd9a45d0c35bbed3e7c"},{url:"assets/fouet-ahh-DdxrUXRj.mp3",revision:"c6e52ed22d70fa8ca9b4cc57490a463d"},{url:"assets/formatters-DyWtO-nR.js",revision:"644f8a5b296eaa3fb3ba4f7a961fd1ba"},{url:"assets/format-CX6Cv1cD.css",revision:"b9d78ee715ac97d3260f2d90f4481817"},{url:"assets/flow9-C5_-GSwl.js",revision:"0e60dc6453d9684c059f20c846ae0ec4"},{url:"assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ-D-x-0Q06.woff2",revision:"a4160421d2605545f69a4cd6cd642902"},{url:"assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNa-Dr0goTwe.woff",revision:"3e1afe59fa075c9e04c436606b77f640"},{url:"assets/expand-template-CTUNyJrv.css",revision:"a4033bbc7a564e856b2b0c42816a24f7"},{url:"assets/expand-template-B6xAlAaM.js",revision:"8b8e369aa3daa5eeabacbb66ec79d70d"},{url:"assets/es-BgQFKlo8.js",revision:"5d99bcdb2fb41a1670d39233a1c2df09"},{url:"assets/engineFeatures-CAVMDawq.js",revision:"35494443f937972edcd2fcd449597222"},{url:"assets/elixir-6RTg0lbw.js",revision:"fb736f7429d9c6a596ed7905653dbf14"},{url:"assets/efforts-C5ZZgCH4.js",revision:"4920e9b39d56d28648df5d39b113f7f9"},{url:"assets/editor.worker-CwQAd_xr.js",revision:"9e590290a972dd493b8050a29cedd37e"},{url:"assets/editor.api-sw146MWN.js",revision:"77478b9215a01605b5ceb51cb64bd6a6"},{url:"assets/editor-BJU3Xb3h.css",revision:"86feeac14ca8286ed4671fb1321a79ca"},{url:"assets/ecl-D05T4iGw.js",revision:"496ceca3c8bae12c563a8a781cf639f3"},{url:"assets/documents-C2cLnEBQ.js",revision:"7cd149195e3174c5883fecb49dd91ad8"},{url:"assets/dockerfile-DZFCIeNp.js",revision:"6af03903b1e51179ae2120866bb68acd"},{url:"assets/de-QkDLrcGq.js",revision:"164f41b799184dc52a4af7a7a20198b9"},{url:"assets/dart-onAF5SnQ.js",revision:"4fc14a4d2b7e030db6af8025d8fe831b"},{url:"assets/cypher-CVaqCwHa.js",revision:"75a568a8c6b29818b6a6c8675841ebf7"},{url:"assets/css-DIMkf-bt.js",revision:"368cd7c0ef4cdeca015fe9fe40ed1b2c"},{url:"assets/csp-bTuwJoIa.js",revision:"d13f525ef224dae69f8bde261bb48507"},{url:"assets/csharp-BKxtCVv1.js",revision:"e5831c8275e73409bc73a3991ceb194e"},{url:"assets/cpp-C7h46wYY.js",revision:"7fa3a56badaae54657cda12c403da2c7"},{url:"assets/coffee-Ba7i2nA0.js",revision:"1a1012b2a9bd329b3b1794297125c9a9"},{url:"assets/codicon-Brq4_Ui5.ttf",revision:"74c2693fe9bc669ca29eb633486e1813"},{url:"assets/clojure-Cm7r79vr.js",revision:"e3307e92ae8965ebb29ec9c9097774cd"},{url:"assets/clipboard-t9qe6lK7.js",revision:"04f746e11f1ac85a8652dff1abde80f4"},{url:"assets/cameligo-DMUM7wLl.js",revision:"ad01c48b3bff95a5fb691c7cd8427122"},{url:"assets/build-path-tree-BWBzP8os.js",revision:"1b14224e6a3a4d4f0d052da6d0d859e1"},{url:"assets/browser-f9MHQjfi.js",revision:"d2d4deaaa946184c19fed88160651bd4"},{url:"assets/bicep-B5-_aFwp.js",revision:"b2c3f814c02ba6e4672b16282c0a1376"},{url:"assets/bat-i0X4ZdIN.js",revision:"914960f9abae1bfe5a2189a174a1e1c1"},{url:"assets/azcli-Bc_sGQ0U.js",revision:"c1dfc1889c57d0712d6415ecb14b66ed"},{url:"assets/apex-BWPQTe0t.js",revision:"eee56c5abf95c2575e288f36fdbb8737"},{url:"assets/abap-08VXUWAP.js",revision:"08897cd48182b5410786802ea9af6fa2"},{url:"assets/WorkspacePage-DKRpdpPg.js",revision:"db7754b55d4b58100b2576e43c750d17"},{url:"assets/WorkspacePage-BAC6u9OP.css",revision:"24abc82de7b776a50c05b9fdaf4b8dba"},{url:"assets/WorkspaceAttentionLabels-CrLP_I5S.css",revision:"99be445535bc9833b842f72d9e03ee5e"},{url:"assets/WorkspaceAttentionLabels-C-yN5IX8.js",revision:"b7cd6b87b231e8a6771d85a4ef039caf"},{url:"assets/TourReplayButton-DU1UShMY.js",revision:"c058a5c50b5647951ca29818e2fe0f92"},{url:"assets/TouchPan-B3nrkCY8.js",revision:"ad7be827ec98e293abd8ff35e8175b3e"},{url:"assets/TerminalPanel-DbVZk0vD.css",revision:"2ff0ce9e84f1f42b50827288880add0a"},{url:"assets/TerminalPanel-DI8DHb9e.js",revision:"4c8dd1cd4d29b12e9058f1867fd3c5c4"},{url:"assets/SplitWorkspacePage-lWQO8xro.css",revision:"cabea8d2cabbc3e1012ffa88225e04d3"},{url:"assets/SplitWorkspacePage-D7lGFRKs.js",revision:"862d6d178fc5d51a8e2d253184b5761c"},{url:"assets/SettingsPage-Jx6TnOzR.js",revision:"4be540e19958ecf5077116e6dfcf4815"},{url:"assets/SettingsPage-Do9d0Pov.css",revision:"bdfbd6956ef714c43ce45908ec044931"},{url:"assets/SearchPage-DopbgLxh.js",revision:"2defab4b6a13fe63217c2b3c08c00ba0"},{url:"assets/SearchPage-CVgRa025.css",revision:"d2dc0f665bc7b80bd843557ec692e589"},{url:"assets/SchedulePanel-CXRUsz6G.js",revision:"5d10d88da76609e2aeb917cb069e54ba"},{url:"assets/SchedulePanel-BunlzsOY.css",revision:"fb39954065255ecc4ae531f2b9fd90cc"},{url:"assets/QTooltip-CwcCGSWq.js",revision:"8ea08328f2ab275af78535bbc154d77a"},{url:"assets/QSpinnerDots-DnCV3VzI.js",revision:"ba39c5e74830e254c54f4f5d2d46ff13"},{url:"assets/QSelect-xd-AlGo_.js",revision:"152ad1f59e85e1862edd1111bc3dc916"},{url:"assets/QPage-DaX9sMQC.js",revision:"0cd8a797c8ea611956a676655a407ab1"},{url:"assets/QMarkupTable-B9QuKtK_.js",revision:"160920fce69f9b52cee2a90cc4f8279d"},{url:"assets/QList-qupzuEqO.js",revision:"eae772de88e93c272b6c8d80d6067ee7"},{url:"assets/QItemSection-D_5_0UrX.js",revision:"e279fe3c67bf73bd85268799420d7616"},{url:"assets/QDrawer-Cij17skX.js",revision:"ca56a7864ae4f3e11a625183302eca3e"},{url:"assets/QChip-owciRuZu.js",revision:"35fc915f5a427228ea6550737619734e"},{url:"assets/QBtnToggle-BI3k3Ch2.js",revision:"e624fc03b2eb479a25ec72d9f94eb180"},{url:"assets/QBtnGroup-DELKYo3u.js",revision:"26b8a09eebac7031c601caf508e51076"},{url:"assets/QBtnDropdown-X8oNU5Mb.js",revision:"05834a31a75c6cf2ad47de10ab8442ed"},{url:"assets/QBtn-CZaBclNw.js",revision:"c13288d664c03c0519fb5f5744f5e179"},{url:"assets/QBanner-DhqH95GW.js",revision:"90a5f93c977406c288a5d8581e96c9c8"},{url:"assets/QBadge-DbkxGtht.js",revision:"a1d932f64e2db71082894e3fb5a4846b"},{url:"assets/MainLayout-vvyiRcql.js",revision:"c7e5829ee44669e894c9c7365a1db465"},{url:"assets/MainLayout-DxMVVA6f.css",revision:"95561a4b467193187f104722f9a1d91a"},{url:"assets/HealthPage-RFZS7Lao.js",revision:"3c13e74f4ca8f4f226dc2d7bd3265df9"},{url:"assets/HealthPage-CFZ-tdKK.css",revision:"0e6bfb66fa0c3d07a1afa39370e89ec8"},{url:"assets/GitPanel-Cal_wzC0.js",revision:"e03f0654cd666cb0742da25437acfd57"},{url:"assets/GitPanel-BFCnyhE2.css",revision:"bb8c4ad153abd46e8f9ce31d85dc6edf"},{url:"assets/DrawerToggleButton-BVLO5K5d.js",revision:"0345179d200813856690d4b9d6146f6a"},{url:"assets/DocumentsPanel-BJsJ0fNs.js",revision:"3c285becd4876ae059030027de3d38d4"},{url:"assets/DocumentsPanel-B8QY7FTj.css",revision:"676a3a838b07224f48fdd99e0cb6bbc8"},{url:"assets/DiffViewer-DnR79ycb.css",revision:"089b6d3275786d618cd4e82248d71af0"},{url:"assets/DiffViewer-BpsLNxnj.js",revision:"48eeca44d7e990a9c77dc8d8565fe34d"},{url:"assets/DashboardPage-DYxdxEul.js",revision:"81dceefb2231c8f450e09535a781d799"},{url:"assets/DashboardPage-D8g7_r4S.css",revision:"eebdeb183365fe34ed04a5870b839fa4"},{url:"assets/CreatePage-Bon8qIka.js",revision:"e6b2b556676bea3b4a747b8d89186350"},{url:"assets/CreatePage-A3pVradx.css",revision:"749e08a38d84d31f883e4215be60ab70"},{url:"assets/ComparisonPanel-CRRaDs2D.css",revision:"5cf89d70490a6b89a13a2c81360ed983"},{url:"assets/ComparisonPanel-Bd0X08sg.js",revision:"e6bbd898d2313cc8db4e7b5f2d0162b7"},{url:"assets/ClosePopup-BqW5dy-O.js",revision:"c06137af89cb48374856dc5b805c6d36"},{url:"assets/ChangelogPage-DKJkFiU_.css",revision:"6ba32a05b43494414258cbdd88c16e36"},{url:"assets/ChangelogPage-D8563008.js",revision:"ab425461beda277fb6fb869994530cf1"},{url:"assets/ActivityFeed-Chsw1Mh7.css",revision:"4ff0b00dd03465e1da7e87d75e16fb0c"},{url:"assets/ActivityFeed-BzzvcOmq.js",revision:"0181c65b7616e508482d23a8b82eae38"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html"),{denylist:[/sw\.js$/,/workbox-(.)*\.js$/]}))});
|
|
1
|
+
if(!self.define){let s,e={};const a=(a,r)=>(a=new URL(a+".js",r).href,e[a]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=a,s.onload=e,document.head.appendChild(s)}else s=a,importScripts(a),e()}).then(()=>{let s=e[a];if(!s)throw new Error(`Module ${a} didn’t register its module`);return s}));self.define=(r,i)=>{const c=s||("document"in self?document.currentScript.src:"")||location.href;if(e[c])return;let d={};const b=s=>a(s,c),f={module:{uri:c},exports:d,require:b};e[c]=Promise.all(r.map(s=>f[s]||b(s))).then(s=>(i(...s),d))}}define(["./workbox-778a14ff"],function(s){"use strict";s.setCacheNameDetails({prefix:"kobo-client"}),self.addEventListener("message",s=>{s.data&&"SKIP_WAITING"===s.data.type&&self.skipWaiting()}),s.clientsClaim(),s.precacheAndRoute([{url:"manifest.json",revision:"73f02ba4eb4414fb70bbe5ca76cc9580"},{url:"index.html",revision:"f30ae1e4d79f04b7368b83c24664384d"},{url:"favicon.svg",revision:"9d89ef10d49f14d08c25cfca9bd4ea75"},{url:"sounds/yaaa.mp3",revision:"2161c5eb77ac61349f6fe573f62d8404"},{url:"sounds/warcraft-3-humain-travail.mp3",revision:"0b8bd1b9be23803c3ac84eaf0d1b5287"},{url:"sounds/tu-vas-la-fermer.mp3",revision:"1688aaa18b0a307a3016c3fd39321f59"},{url:"sounds/travail_termine.mp3",revision:"a194c4cc479b59ba13746b08bca634b9"},{url:"sounds/ta-gueule.mp3",revision:"44aa9b15c9abe9a846f8034a23482b24"},{url:"sounds/pas-ca-zinedine.mp3",revision:"57ec46faf5b7d1c2f370d7167e284f04"},{url:"sounds/ouais-cest-greg.mp3",revision:"55624f422636b19422b3bc700aa8da9e"},{url:"sounds/nan-wallah-pardon.mp3",revision:"16edfe0a39fde73db0f30a7a067a77ff"},{url:"sounds/nan-tu-degages.mp3",revision:"282678eceb54e09eb8a7edf4f9fb0e21"},{url:"sounds/mais-laisse-moi-dormir-zebi.mp3",revision:"05d8419f91effcf56a6d09ed35544d06"},{url:"sounds/hey.mp3",revision:"e68017c8f32b3e815e339dad099dc830"},{url:"sounds/gta-v-death.mp3",revision:"72eaa8958882d5f2040f4b9b4f3ba620"},{url:"sounds/for-shure.mp3",revision:"71dd2a2c874a04e67613d49045d926e7"},{url:"sounds/faaah.mp3",revision:"a0220dd11038add054573c26d2f0b6ac"},{url:"sounds/dry-fart.mp3",revision:"afdf096e4a705d908392ed9b4f827bc9"},{url:"sounds/ca_va_peter.mp3",revision:"004452d7682a043e1c13e213a1a56766"},{url:"sounds/basic-notification.mp3",revision:"3f6df726a5e85560dfecf4bb592d2fda"},{url:"sounds/bah-alors-on-est-nul.mp3",revision:"b30241371b49465f62997213bcdfe4b2"},{url:"sounds/arretez-les-messages.mp3",revision:"26f667dccdfddb8c534a5482475b729a"},{url:"sounds/arrete-de-mentir.mp3",revision:"1a9b5157f362dd3e0acc479da4fea708"},{url:"sounds/aller-ftg.mp3",revision:"bcc00bd838e61eb9571c8fdc0f400d19"},{url:"sounds/7eme-compagnie-03.mp3",revision:"49ee08dd595e0e9659042e4e854b0141"},{url:"fonts/GeistMono-Variable.woff2",revision:"308360d8a547331fd40bc09a7145d59a"},{url:"fonts/Geist-Variable.woff2",revision:"dfa48d5a853753289194436953e3f202"},{url:"fonts/GEIST-LICENSE.txt",revision:"563d13575f813953c3151e1ecce3b76f"},{url:"assets/yaml-CSGKph85.js",revision:"a9e902827b3a3b6cc84f64ed560e0899"},{url:"assets/xml-BSB4-DXR.js",revision:"99ca1596d7b5302e5ff9420992068e3c"},{url:"assets/workspace-templates-B8WWsWEI.js",revision:"6417d450d3aeb8e5a87f9dab7fde7475"},{url:"assets/workspace-page-layout-Dw9NhZsL.js",revision:"0c933f7b6c6bf3c90ea1875abad85392"},{url:"assets/wgsl-DpFanUEy.js",revision:"4cf32279d7c6a601611a6e32a14f3b1e"},{url:"assets/vb-DV3o63ZY.js",revision:"a5b3a756d667f5e4a5da6da4013d7341"},{url:"assets/use-tours-_6HwJ_Rp.js",revision:"bc2113d3d83bbe5ba62d82cbeaf444e7"},{url:"assets/use-tours-CTZuBZOi.css",revision:"2f6d79046e1409f0472f65179eaa76f3"},{url:"assets/use-search-index-status-DtLzygcy.js",revision:"d6952aee8e5013273ceeb533b4bb822a"},{url:"assets/use-is-mobile-CWjqe8gC.js",revision:"d1c4af193dfd98b8d775c51ddcbd45a0"},{url:"assets/use-id-BIuaWKkB.js",revision:"515b4eadf57c35d0e2b42311ccc01993"},{url:"assets/use-checkbox-FnauAgTp.js",revision:"298e92c55534c2c194c6fa1ef7a9ea6f"},{url:"assets/typespec-B8J7ngcE.js",revision:"6c28560625f59db6a5897aa92de81033"},{url:"assets/typescript-CSQAg5UC.js",revision:"3c1e40c31cbf9dae54b3381907955494"},{url:"assets/twig-De2hgUGE.js",revision:"dfb4c76c8ec0d822070abac68d2bd473"},{url:"assets/tcl-DISqw1ZD.js",revision:"6d0ddaebd76ad41c47c96d484af119f8"},{url:"assets/systemverilog-Bz4Y3fRF.js",revision:"18e6d6e82eeb1107458d8d5531f82246"},{url:"assets/swift-Bxkupp3x.js",revision:"65b88f49188974d7c12e1a6cd12a9de5"},{url:"assets/st-DbInun42.js",revision:"d7294c4d47351db4e5edd4d91e445a21"},{url:"assets/sql-NEE52Syq.js",revision:"48352e15fff2141c7deaaab4e51e9565"},{url:"assets/sparql-D_Lu-MrJ.js",revision:"65390637b1a24614803db6844a0db77b"},{url:"assets/sophia-CRfGWb83.js",revision:"a330db913fee26a14679bed631a59043"},{url:"assets/solidity-BEEn4gHE.js",revision:"c2cd02221ec3d86f9a6bb09bfb1f8978"},{url:"assets/shell-CC2rA5mh.js",revision:"8362d325cda511ef760335e0847d3910"},{url:"assets/scss-gp-XZpBa.js",revision:"bf0805dd5cd80d90fef58c9866a7751e"},{url:"assets/scheme-BeGwcela.js",revision:"55c990715708ea012165486d065b3e2c"},{url:"assets/scala-DHpiXF5c.js",revision:"4eeea167d27954255e39d91412b62f87"},{url:"assets/sb-CcwsVR0C.js",revision:"93fc05f23a9cbb96d4f72dbc73e2e53b"},{url:"assets/rust-DdL9SqIa.js",revision:"356bac76300c8d83e8e9d76becf3c9ea"},{url:"assets/runtime-core.esm-bundler-CDnVUfeZ.js",revision:"958c358bc7005237e86c709b3248ae06"},{url:"assets/ruby-DezsRK8O.js",revision:"95c3294c6d6cead3cccd7e4e973ab964"},{url:"assets/restructuredtext-BYgofb2h.js",revision:"f75377ae694f4e8f0bcccd05b5b9e65c"},{url:"assets/render-chat-markdown-Ct_T5TPN.js",revision:"375f89cc9241ea7ed93ca0e6f3b4d93e"},{url:"assets/redshift-DT7zqm-g.js",revision:"44e23f67b6a02e60d28c9947cd025207"},{url:"assets/redis-ClamHrr6.js",revision:"e3141183a6756253db43e10f8a305787"},{url:"assets/reactivity.esm-bundler-DEJj9cFv.js",revision:"202b2fcc10c0494e359dc0181e4d28e8"},{url:"assets/razor-CG6cL8ya.js",revision:"8e3bb26585605b43c675968352f3e18e"},{url:"assets/r-BwWrilGY.js",revision:"f18d3e790ef07bc993539322d29548e4"},{url:"assets/qsharp-DkqhCAOL.js",revision:"c53fe08a83f8fcbcd81723105136a691"},{url:"assets/python-DEeUVvnp.js",revision:"26693a7f01cfbdc848af6e4585f5f9ac"},{url:"assets/pug-Z5eAx3Zn.js",revision:"6e3de6d5214d2cf61b90949e1d383b49"},{url:"assets/protobuf-C531GsRP.js",revision:"04e688a7fef2bde8cef525653497371f"},{url:"assets/project-color-BUcW_eZA.js",revision:"72db48b1c3993677047aed4a07fea9b5"},{url:"assets/private.use-form-C7umbGO-.js",revision:"115ec085187459512189754b7325cea5"},{url:"assets/powershell-DmHpPYUd.js",revision:"ff476e9c4398edc9dfd2eb0ee9356352"},{url:"assets/powerquery-D3hlyOfw.js",revision:"0cacccadbe7cd4415f9a3112763c89f3"},{url:"assets/postiats-43DmfD33.js",revision:"b5dbce3331b7ccb325853328702b4bd9"},{url:"assets/pla-CopQ2nXW.js",revision:"b31678678d642accba98d7e7249a20b2"},{url:"assets/pinia-BKqmoVru.js",revision:"309cc3e9d7688b550c4490f51a28959f"},{url:"assets/php-nr791fC2.js",revision:"ee487693840b66c2abf7c2da872dd6a8"},{url:"assets/pgsql-DTj74zXo.js",revision:"75375029d157fc5e789a13718eed9da7"},{url:"assets/permissionModes-C3otN1Vk.js",revision:"fdf6c716b01d7d07b6d004b3ad4ca892"},{url:"assets/perl-oz_6vUea.js",revision:"fee6d319d328db438b336b52ac07a46a"},{url:"assets/pending-diff-open-B02zuH1j.js",revision:"81b44af606d6cfcc811485e89a1872e0"},{url:"assets/pascaligo-D-ptJ9y-.js",revision:"88be4e81a252f44f049ac92f7b6ea518"},{url:"assets/pascal-DrH0SRf2.js",revision:"0d81121099a69b47e10701bf075fe3cd"},{url:"assets/objective-c-FvmIjYaQ.js",revision:"6d64543dd4430fb71bcd7a5347a0398c"},{url:"assets/notify-theme-DIKLxr8F.js",revision:"a0aa40213b34f8298a3025b9559fd1de"},{url:"assets/network-auth-CVGS__6a.js",revision:"33b122aaa35af63e39f995836d205b9b"},{url:"assets/mysql-SOo6toE5.js",revision:"677c089d979324385539e96bd2eb11e4"},{url:"assets/msdax-DauUninz.js",revision:"a63bfea2dd041755a34fe3e307159413"},{url:"assets/monaco.contribution-1LZrAlY4.js",revision:"43c14e0e6268edced06caf214bc577bc"},{url:"assets/monaco-contributions-Cb0afGfW.css",revision:"9c8dff3575c2e943e7ad49f78bbdb6d2"},{url:"assets/monaco-contributions-BBW6JNgz.js",revision:"17e5d79f2207945e4d707109c7062020"},{url:"assets/mips-CIPQ_RoX.js",revision:"b22614ddc8855670a3f76290908877f5"},{url:"assets/mdx-BK5H1Xst.js",revision:"95d3b99ce7a2dfa22183a29bb3f515d6"},{url:"assets/markdown-Cimd5fb3.js",revision:"38eaa88ca7719b9da2894b7c26f2f65b"},{url:"assets/m3-D-oSqn_W.js",revision:"624c73b0332fe1ddfef6013306c5998d"},{url:"assets/lua-CsQS60Ue.js",revision:"5568edf60b64f912bd17561f26e03d44"},{url:"assets/liquid-D0hUdg4x.js",revision:"7721fc6dad2a4f39593f727421b46cb1"},{url:"assets/lexon-CfSJPG6W.js",revision:"32b224ffe991474a4cfcbed19971a98d"},{url:"assets/less-B9JPFI3C.js",revision:"c80573ae2313727c545a585d90d3ff36"},{url:"assets/kotlin-BOotOW0E.js",revision:"7c2a31b16b6ddc97b60891b09afa11b1"},{url:"assets/julia-Bri6UV-V.js",revision:"bb5062cdf870c17c7c9be635c1a8a3be"},{url:"assets/javascript-C7Ncb6V7.js",revision:"46171da4cd5f0f23f186f99c847d2bce"},{url:"assets/java-BEtHBSE6.js",revision:"987edcd2170749acca47ea184dd9ab25"},{url:"assets/it-BM6t0IGU.js",revision:"2aaf207f5bc6af31617509b4535f811e"},{url:"assets/ini-sBoK_t0W.js",revision:"35f8ec10844ea4f62c2712d3f5c1e129"},{url:"assets/index-mvh5w1cM.js",revision:"24693ae1d5d750bf483903b20643b95c"},{url:"assets/index-CUoUy6tH.css",revision:"a8c1e129e4ca8531dff2ac89ad0d6778"},{url:"assets/i18n-BkUirOzl.js",revision:"e97e6c0e5a8f6ed329431ad86b75114d"},{url:"assets/html-BTNpr39P.js",revision:"c0e121304c97990146903c27d3dca870"},{url:"assets/hcl-CpzslTdj.js",revision:"f9ef1004e908957ec1c3bbea2049a0e9"},{url:"assets/handlebars-CETuqLyz.js",revision:"f13d3f553e035282d94f2ed7418cf786"},{url:"assets/graphql-fmXr3nnJ.js",revision:"a51df1d5dca011f5d85dd09a2ffbe1e5"},{url:"assets/go-C-y9NEjX.js",revision:"9213c8381eb32996b86ca9600ca6a07e"},{url:"assets/fsharp-C8Ef5oNN.js",revision:"72f3de59be781f8a4ec49d16bac02119"},{url:"assets/freemarker2-Cu1vGY0x.js",revision:"db206f7c3bb54d72b47e07bc2e62e97a"},{url:"assets/fr-KCK6r5ga.js",revision:"6e5990b66ebc1cfa1258fc9abda6fa1a"},{url:"assets/fouet-ahh-DdxrUXRj.mp3",revision:"c6e52ed22d70fa8ca9b4cc57490a463d"},{url:"assets/formatters-B2uUIbAY.js",revision:"4ebc619fc476ffba42a3f8ec6a5f6fc1"},{url:"assets/format-CX6Cv1cD.css",revision:"b9d78ee715ac97d3260f2d90f4481817"},{url:"assets/flow9-C5_-GSwl.js",revision:"0e60dc6453d9684c059f20c846ae0ec4"},{url:"assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ-D-x-0Q06.woff2",revision:"a4160421d2605545f69a4cd6cd642902"},{url:"assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNa-Dr0goTwe.woff",revision:"3e1afe59fa075c9e04c436606b77f640"},{url:"assets/expand-template-DiDWiIkx.js",revision:"a150bd7377cc8965906491554f3ab375"},{url:"assets/expand-template-CTUNyJrv.css",revision:"a4033bbc7a564e856b2b0c42816a24f7"},{url:"assets/es-C1LM-3aq.js",revision:"2b3a9cacbfc6bd2bcf775f5fb0102304"},{url:"assets/engineFeatures-b74YRODT.js",revision:"0fa5b2304dfbb9dc513cc68d1266d873"},{url:"assets/elixir-6RTg0lbw.js",revision:"fb736f7429d9c6a596ed7905653dbf14"},{url:"assets/efforts-BM7fdaaL.js",revision:"f9f2908382424a68dd2848c00ab8ad77"},{url:"assets/editor.worker-CwQAd_xr.js",revision:"9e590290a972dd493b8050a29cedd37e"},{url:"assets/editor.api-BbKfnNmv.js",revision:"1537813682d4eaaaaf69233bb0f4e58c"},{url:"assets/editor-BJU3Xb3h.css",revision:"86feeac14ca8286ed4671fb1321a79ca"},{url:"assets/ecl-D05T4iGw.js",revision:"496ceca3c8bae12c563a8a781cf639f3"},{url:"assets/documents-C2Xnjh9Z.js",revision:"c2004dba1f07b3b03b1c01858dab750b"},{url:"assets/dockerfile-DZFCIeNp.js",revision:"6af03903b1e51179ae2120866bb68acd"},{url:"assets/de-BdLe7apJ.js",revision:"fb440ecd0dfe076a849ba16978924798"},{url:"assets/dart-onAF5SnQ.js",revision:"4fc14a4d2b7e030db6af8025d8fe831b"},{url:"assets/cypher-CVaqCwHa.js",revision:"75a568a8c6b29818b6a6c8675841ebf7"},{url:"assets/css-DIMkf-bt.js",revision:"368cd7c0ef4cdeca015fe9fe40ed1b2c"},{url:"assets/csp-bTuwJoIa.js",revision:"d13f525ef224dae69f8bde261bb48507"},{url:"assets/csharp-BKxtCVv1.js",revision:"e5831c8275e73409bc73a3991ceb194e"},{url:"assets/cpp-C7h46wYY.js",revision:"7fa3a56badaae54657cda12c403da2c7"},{url:"assets/coffee-Ba7i2nA0.js",revision:"1a1012b2a9bd329b3b1794297125c9a9"},{url:"assets/codicon-Brq4_Ui5.ttf",revision:"74c2693fe9bc669ca29eb633486e1813"},{url:"assets/clojure-Cm7r79vr.js",revision:"e3307e92ae8965ebb29ec9c9097774cd"},{url:"assets/clipboard-t9qe6lK7.js",revision:"04f746e11f1ac85a8652dff1abde80f4"},{url:"assets/cameligo-DMUM7wLl.js",revision:"ad01c48b3bff95a5fb691c7cd8427122"},{url:"assets/build-path-tree-C-HSiySk.js",revision:"41c9e7850bf1cb113167ebc5db937e69"},{url:"assets/browser-BFj5wwbS.js",revision:"51d125153e23936edcd8b0b781750006"},{url:"assets/bicep-B5-_aFwp.js",revision:"b2c3f814c02ba6e4672b16282c0a1376"},{url:"assets/bat-i0X4ZdIN.js",revision:"914960f9abae1bfe5a2189a174a1e1c1"},{url:"assets/azcli-Bc_sGQ0U.js",revision:"c1dfc1889c57d0712d6415ecb14b66ed"},{url:"assets/apex-BWPQTe0t.js",revision:"eee56c5abf95c2575e288f36fdbb8737"},{url:"assets/abap-08VXUWAP.js",revision:"08897cd48182b5410786802ea9af6fa2"},{url:"assets/WorkspacePage-Dy0spsfi.js",revision:"53f54d27826028bfdfd97e5b7062c7ce"},{url:"assets/WorkspacePage-DCg9zSxz.css",revision:"8dfcb28752c95d1c4113ff305af2437d"},{url:"assets/WorkspaceAttentionLabels-CrLP_I5S.css",revision:"99be445535bc9833b842f72d9e03ee5e"},{url:"assets/WorkspaceAttentionLabels-BBaGZlwv.js",revision:"9c1310b1db55c1a921a1ae0eea8224de"},{url:"assets/TourReplayButton-Bj2GGyhU.js",revision:"2b1132fabd906e51f296a86993698a40"},{url:"assets/TouchPan-DTJqxVp9.js",revision:"3ddf21c0641bebac58348e59704791d2"},{url:"assets/TerminalPanel-IdPIGp2_.js",revision:"731822017a6d598813e0ac46aee36065"},{url:"assets/TerminalPanel-DbVZk0vD.css",revision:"2ff0ce9e84f1f42b50827288880add0a"},{url:"assets/SplitWorkspacePage-vz6jN1DM.js",revision:"1ca4f22dacd4f0e3e84d7e2f0427cc92"},{url:"assets/SplitWorkspacePage-lWQO8xro.css",revision:"cabea8d2cabbc3e1012ffa88225e04d3"},{url:"assets/SettingsPage-sVlsJQ0b.css",revision:"b3074c2960b985187be63dbcbc261900"},{url:"assets/SettingsPage-DnO-ImWE.js",revision:"9d223e2047b5c7e1d9f302c9f1b653c8"},{url:"assets/SearchPage-BGi1yRxU.js",revision:"c5fb666424ee6602d8b64270ab2957b4"},{url:"assets/SearchPage-BGc1oQSM.css",revision:"d988bd3c7ed5458189b7225097e4cdeb"},{url:"assets/SchedulePanel-BlZDd7TK.js",revision:"acae7c1cd82759b9002930e6e8e782ce"},{url:"assets/SchedulePanel-BAA4Aajn.css",revision:"d35bda7ebb0fa9cb2bfea45d77156611"},{url:"assets/QTooltip-DwkX8eQ6.js",revision:"5e1f2645ad6767dfe26a23ff0c358afd"},{url:"assets/QSpinnerDots-DnCV3VzI.js",revision:"ba39c5e74830e254c54f4f5d2d46ff13"},{url:"assets/QSelect-DtSUuK8t.js",revision:"97afb9f67a129ffe5fb6e015ed72e51d"},{url:"assets/QPage-DaX9sMQC.js",revision:"0cd8a797c8ea611956a676655a407ab1"},{url:"assets/QMarkupTable-B9QuKtK_.js",revision:"160920fce69f9b52cee2a90cc4f8279d"},{url:"assets/QList-qupzuEqO.js",revision:"eae772de88e93c272b6c8d80d6067ee7"},{url:"assets/QItemSection-D_5_0UrX.js",revision:"e279fe3c67bf73bd85268799420d7616"},{url:"assets/QDrawer-Fj3M9QGD.js",revision:"7078db39f14c6635c5f4acfa7b9b6336"},{url:"assets/QChip-owciRuZu.js",revision:"35fc915f5a427228ea6550737619734e"},{url:"assets/QBtnToggle-BI3k3Ch2.js",revision:"e624fc03b2eb479a25ec72d9f94eb180"},{url:"assets/QBtnGroup-DELKYo3u.js",revision:"26b8a09eebac7031c601caf508e51076"},{url:"assets/QBtnDropdown-BeiZIHVA.js",revision:"1b11b2c329505d38a208f88029d20b1e"},{url:"assets/QBtn-CZaBclNw.js",revision:"c13288d664c03c0519fb5f5744f5e179"},{url:"assets/QBanner-DhqH95GW.js",revision:"90a5f93c977406c288a5d8581e96c9c8"},{url:"assets/QBadge-DbkxGtht.js",revision:"a1d932f64e2db71082894e3fb5a4846b"},{url:"assets/MainLayout-DxMVVA6f.css",revision:"95561a4b467193187f104722f9a1d91a"},{url:"assets/MainLayout-Duwnq3cc.js",revision:"e9dcb87d924d5e714fbe62c561d6a480"},{url:"assets/HealthPage-_q3vy_xn.js",revision:"95fc2177708a8a4acd70599d002c1958"},{url:"assets/HealthPage-CFZ-tdKK.css",revision:"0e6bfb66fa0c3d07a1afa39370e89ec8"},{url:"assets/GitPanel-DCmB2R5i.js",revision:"0656ec5db7c84f5e7b0a05af91905e8c"},{url:"assets/GitPanel-BFCnyhE2.css",revision:"bb8c4ad153abd46e8f9ce31d85dc6edf"},{url:"assets/DrawerToggleButton-Ca0_CxSl.js",revision:"3186644ec32bea59abd6d9dbda6b77cd"},{url:"assets/DocumentsPanel-D9vcB91W.js",revision:"6b387ed47a532b2117919a696ed3081d"},{url:"assets/DocumentsPanel-B8QY7FTj.css",revision:"676a3a838b07224f48fdd99e0cb6bbc8"},{url:"assets/DiffViewer-DEcf48KI.js",revision:"06c4272dc46a036ed55329f3c2315e91"},{url:"assets/DiffViewer-DEPOa3D7.css",revision:"7a2be47c13fe02cd2158e94eb0d320c5"},{url:"assets/DashboardPage-D8g7_r4S.css",revision:"eebdeb183365fe34ed04a5870b839fa4"},{url:"assets/DashboardPage-CIo_gesD.js",revision:"30018ae787d6a35e8b236b17da809523"},{url:"assets/CreatePage-DbY5gBv8.js",revision:"dea49e02c159701bbc4ef77af58ba89a"},{url:"assets/CreatePage-CGi88k6z.css",revision:"70c3143382d5cd7453720f5d98b363c1"},{url:"assets/ComparisonPanel-o_EHlTwV.js",revision:"979799d759b86a51f796985608ab5335"},{url:"assets/ComparisonPanel-CRRaDs2D.css",revision:"5cf89d70490a6b89a13a2c81360ed983"},{url:"assets/ClosePopup-BqW5dy-O.js",revision:"c06137af89cb48374856dc5b805c6d36"},{url:"assets/ChangelogPage-DKJkFiU_.css",revision:"6ba32a05b43494414258cbdd88c16e36"},{url:"assets/ChangelogPage-BWeu0YeI.js",revision:"7898c625aacb638c1a4fc2462d897163"},{url:"assets/ActivityFeed-DTIe6O9o.js",revision:"d16e0943851a76f0e5528aa80a3f2e4e"},{url:"assets/ActivityFeed-BYR5x7aa.css",revision:"8fa009894fba587d5602d5a5659f9f0d"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html"),{denylist:[/sw\.js$/,/workbox-(.)*\.js$/]}))});
|
package/src/mcp-server/README.md
CHANGED
|
@@ -1,22 +1,179 @@
|
|
|
1
1
|
# Kōbō Tasks MCP Server
|
|
2
2
|
|
|
3
|
-
Standalone MCP (Model Context Protocol) server
|
|
3
|
+
Standalone MCP (Model Context Protocol) server configured for each Claude Code or Codex agent running inside a workspace. Exposes workspace-scoped tools that the agent can invoke to interact with Kōbō state: tasks, settings, dev server, images, git, etc.
|
|
4
|
+
|
|
5
|
+
Kōbō also exposes conversation tools to external MCP clients over HTTP and through the global stdio server.
|
|
6
|
+
|
|
7
|
+
## Connect an external LLM
|
|
8
|
+
|
|
9
|
+
**Settings → Global → Network access → External LLM access (MCP)** provides this installation's backend URLs and a local stdio configuration. The preview uses a token placeholder; **Copy with token** explicitly includes the current network token. Development configurations use the backend port, independently of the UI port. The JSON examples use a generic `mcpServers` format; adapt the enclosing configuration to your client.
|
|
10
|
+
|
|
11
|
+
### HTTP (local or remote)
|
|
12
|
+
|
|
13
|
+
Connect a client supporting **MCP Streamable HTTP** to the running backend:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
http://127.0.0.1:3000/api/mcp
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Use the backend's actual port (`3300` for the default development server). This endpoint needs no database path or separate MCP process. It supports MCP initialization, tool discovery and JSON responses; conversation updates are retrieved by polling a cursor rather than a persistent event stream.
|
|
20
|
+
|
|
21
|
+
For another machine, enable [Network access](../../CONFIGURATION.md#network-access), restart Kōbō as instructed there, and replace `127.0.0.1` with its reachable address. Configure either header in the MCP client:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
Authorization: Bearer <your Kōbō network access token>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
X-Kobo-Token: <your Kōbō network access token>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Find the token in **Settings → Global → Network access**. The existing Host/Origin checks and reverse-proxy settings also apply to MCP. Local connections need no token unless **Behind a reverse proxy** is enabled. This is shared-token authentication; clients requiring an OAuth authorization flow are not supported. For access outside a trusted LAN, follow the existing reverse-proxy/TLS deployment guidance. Adding this endpoint does not enable network access automatically.
|
|
32
|
+
|
|
33
|
+
The HTTP endpoint exposes `list_workspaces` and the six [conversation tools](#conversation-tools) below. Its discovery response is an array of `{ id, name, status, projectPath, archivedAt }`.
|
|
34
|
+
|
|
35
|
+
### Stdio (local client)
|
|
36
|
+
|
|
37
|
+
The existing global server exposes the same six conversation tools alongside its workspace-management tools. For a local checkout, build Kōbō first and add an entry like this to a client using the `mcpServers` configuration format, replacing the absolute paths:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"mcpServers": {
|
|
42
|
+
"kobo": {
|
|
43
|
+
"command": "node",
|
|
44
|
+
"args": ["/absolute/path/to/Kobo/dist/mcp-server/kobo-tasks-server.js"],
|
|
45
|
+
"env": {
|
|
46
|
+
"KOBO_DB_PATH": "/absolute/path/to/kobo/kobo.db",
|
|
47
|
+
"KOBO_BACKEND_URL": "http://127.0.0.1:3000"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Leave `KOBO_WORKSPACE_ID` unset or empty for an external client. Use the same database and backend instance: the production database defaults to `~/.config/kobo/kobo.db`, while development uses `data/kobo.db`. If the backend requires a token, set `KOBO_NETWORK_TOKEN` for backend calls. Conversation tools always use the running backend to preserve agent ownership and lifecycle checks.
|
|
55
|
+
|
|
56
|
+
### Conversation tools
|
|
57
|
+
|
|
58
|
+
| Tool | Arguments | Result |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `get_workspace` | `workspace_id` | Workspace metadata, tasks and active/latest session. |
|
|
61
|
+
| `list_workspace_sessions` | `workspace_id` | Workspace sessions with their IDs and status. |
|
|
62
|
+
| `read_workspace_messages` | `workspace_id`, optional `session_id`, `after_cursor`, `limit` | Chronological conversation fragments, `nextCursor`, `hasMore`, `workspaceStatus`, `activeSessionId`. |
|
|
63
|
+
| `send_workspace_message` | `workspace_id`, `content`, optional `session_id`, `idempotency_key` | `{ accepted: true, sessionId }`; keyed sends also return `requestId`, `eventId`, and `replayed` on a successful retry. |
|
|
64
|
+
| `get_workspace_questions` | `workspace_id` | Pending `questions` and `requiresHumanApproval` for a permission request at the head of the queue. |
|
|
65
|
+
| `answer_workspace_question` | `workspace_id`, `tool_call_id`, `answers` | `{ accepted: true }` after answering the current question. |
|
|
66
|
+
|
|
67
|
+
Typical dialogue:
|
|
68
|
+
|
|
69
|
+
1. Call `list_workspaces`, then `get_workspace` and optionally `list_workspace_sessions` to select the conversation.
|
|
70
|
+
2. Read existing messages, following `nextCursor` while `hasMore` is true. Keep the final cursor.
|
|
71
|
+
3. Call `send_workspace_message` with the workspace ID and your text. An inactive agent is resumed; a selected session must belong to this workspace and must be the running session if one is already running.
|
|
72
|
+
4. Poll `read_workspace_messages` with the saved cursor for the reply. Acceptance means the message was delivered, not that the agent finished its work. `workspaceStatus` and `get_workspace_questions` expose progress and blockers.
|
|
73
|
+
5. To answer a question, pass the current `toolCallId` as `tool_call_id`, and map its question identifiers to string answers in `answers` (Codex uses question IDs; Claude questions use their question text). Tool permission requests must be approved by the human in Kōbō.
|
|
74
|
+
|
|
75
|
+
Each message fragment has `{ id, sessionId, role, text, messageId, createdAt }`, optionally `source` and `clientMessageId`. Concatenate assistant fragments sharing a `messageId` and `sessionId` in returned order. `limit` bounds **source events scanned**, from 1 to 200 (default 100): a page can contain no text while still advancing its cursor. Session filtering also includes older untagged events (`sessionId: null`). Keep the same session filter when continuing a cursor. Cursors are workspace-specific; if retention removes a cursor, the tool returns an explicit error and reading must restart without it.
|
|
76
|
+
|
|
77
|
+
Messages use the workspace's configured engine and permission mode, and pause an active auto-loop just like chat input. Archived or purged workspaces must be restored first; messages are refused during compaction or while a question/permission is pending. A workspace-bound stdio agent cannot send to itself. Message content is limited to 100,000 characters; HTTP request bodies to 1 MiB.
|
|
78
|
+
|
|
79
|
+
### Retrying messages safely
|
|
80
|
+
|
|
81
|
+
Generate one `idempotency_key` per intended message and reuse it unchanged on retries:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"workspace_id": "<workspace ID>",
|
|
86
|
+
"content": "Investigate the failing test",
|
|
87
|
+
"idempotency_key": "<a UUID generated once for this instruction>"
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The key is scoped to the workspace and remains recorded until that workspace is deleted, independently of chat-history retention. A repeated accepted request returns its original receipt without delivering again, including after backend restart. Reusing the key for different content or a different requested session returns `idempotency_conflict`.
|
|
92
|
+
|
|
93
|
+
Unsuccessful keyed calls set MCP `isError: true` and return `{ accepted: false, requestId, code, message }` in both JSON text and structured content:
|
|
94
|
+
|
|
95
|
+
- `in_progress`: another call still owns the request; poll by repeating the same key.
|
|
96
|
+
- `delivery_rejected`: validation refused the message before engine dispatch; an intentional later attempt needs a new key.
|
|
97
|
+
- `delivery_unknown`: delivery may have occurred, for example if the backend stopped between engine dispatch and receipt persistence. Inspect history before choosing to send another instruction. This key will never automatically dispatch again.
|
|
98
|
+
- `idempotency_conflict`: the same key was used for different input.
|
|
99
|
+
|
|
100
|
+
This prevents duplicate dispatch caused by retrying the same key; it does not guarantee exactly-once execution inside an external engine. Calls without a key retain the original behavior: inspect history before retrying an ambiguous failure. Question answers use the exact pending tool-call ID rather than message idempotency keys.
|
|
101
|
+
|
|
102
|
+
### Identifying the external client
|
|
103
|
+
|
|
104
|
+
HTTP clients can set `X-Kobo-Client-Name`. For Unicode labels, percent-encode the value using `encodeURIComponent` and also send `X-Kobo-Client-Name-Encoding: uri`; the settings panel generates this automatically. Stdio reads the client's initialization name, with an optional `KOBO_MCP_CLIENT_NAME` override. The bridge carries that label into HTTP calls.
|
|
105
|
+
|
|
106
|
+
Messages and question answers carry `source: { kind: "mcp", clientName, transport }` and appear as **External LLM · client name** in live and reloaded conversations. Missing labels become **External MCP client**. Names are bounded to 100 Unicode code points and escaped by the UI. Labels and transport metadata are self-reported provenance, not authenticated identities or permission grants. Older messages without provenance retain their previous presentation.
|
|
107
|
+
|
|
108
|
+
### Live engine validation
|
|
109
|
+
|
|
110
|
+
Normal `make ci` runs deterministic tests without provider credentials. The explicit live test creates a disposable repository/worktree, database and backend, sends an instruction through HTTP, reads a real engine response, checks stdio history, then restarts the backend and verifies receipt replay:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
KOBO_LIVE_ENGINE=codex KOBO_LIVE_MODEL=<available-model-id> npm run test:mcp:live
|
|
114
|
+
KOBO_LIVE_ENGINE=claude-code KOBO_LIVE_MODEL=<available-model-id> make test-mcp-live
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Use a concrete model available to your configured provider. This invokes the real engine and uses its existing credentials; it may consume quota. Cleanup stops the test's owned backend/agents and deletes temporary files. Missing credentials, provider errors and a missing reply fail the explicit test rather than being counted as successful validation.
|
|
4
118
|
|
|
5
119
|
## How it runs
|
|
6
120
|
|
|
7
|
-
|
|
121
|
+
The orchestrator builds the workspace's MCP server specification in
|
|
122
|
+
`buildMcpServers()`. The Claude engine passes it through the SDK's `mcpServers`
|
|
123
|
+
option; the Codex engine supplies it through the app-server thread's
|
|
124
|
+
`config.mcp_servers`. The agent runtime launches the server over stdio with the
|
|
125
|
+
following environment. This wiring does not require writing a `.mcp.json` file
|
|
126
|
+
into the worktree.
|
|
8
127
|
|
|
9
128
|
| Env var | Purpose |
|
|
10
129
|
|---|---|
|
|
11
|
-
| `KOBO_WORKSPACE_ID` | ID of the current workspace — scopes
|
|
130
|
+
| `KOBO_WORKSPACE_ID` | ID of the current workspace — scopes workspace-local queries. Optional: when unset, the server runs in "global" mode (see [Global tools](#global-tools-workspace-less-mode) below) and exposes management and conversation tools; workspace-scoped tools are omitted from the tool list entirely. |
|
|
12
131
|
| `KOBO_DB_PATH` | Absolute path to Kōbō's SQLite DB. **Required**. |
|
|
13
132
|
| `KOBO_SETTINGS_PATH` | Absolute path to Kōbō's `settings.json`. Optional — `get_settings` returns an error shape if absent. |
|
|
14
133
|
| `KOBO_BACKEND_URL` | Base URL of the running Kōbō HTTP backend. Default: `http://localhost:3000`. Used by tools that need runtime state (dev server, git info, workspace transitions). |
|
|
134
|
+
| `KOBO_NETWORK_TOKEN` | Optional network access token sent with backend requests. |
|
|
135
|
+
| `KOBO_MCP_CLIENT_NAME` | Optional display name overriding the external stdio client's initialization name. |
|
|
15
136
|
|
|
16
|
-
The server reads the DB directly for
|
|
137
|
+
The server reads the DB directly for local queries, writes directly for task
|
|
138
|
+
CRUD, and calls the backend HTTP API for runtime processes and validated
|
|
139
|
+
workspace transitions. Conversation tools are defined in
|
|
140
|
+
`src/shared/workspace-dialogue-tools.ts` and forwarded through the backend.
|
|
141
|
+
The stdio server opens an existing database; schema migration belongs to backend
|
|
142
|
+
startup.
|
|
17
143
|
|
|
18
144
|
## Tools
|
|
19
145
|
|
|
146
|
+
The tables below document the workspace tools in addition to the detailed task,
|
|
147
|
+
workspace, dev-server and settings references that follow. Global discovery and
|
|
148
|
+
conversation tools are described separately. The registration schemas in
|
|
149
|
+
`kobo-tasks-server.ts` are the source of truth for arguments.
|
|
150
|
+
|
|
151
|
+
### Automation and workspace metadata
|
|
152
|
+
|
|
153
|
+
| Tool | Input | Purpose |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
| `mark_auto_loop_ready` | None | Mark task grooming complete so the UI can enable auto-loop. |
|
|
156
|
+
| `set_auto_loop` | `enabled` | Enable or disable auto-loop for this workspace on explicit user request. |
|
|
157
|
+
| `set_workspace_agent_description` | `description` | Set the agent's status summary (200 characters maximum); empty clears it. |
|
|
158
|
+
| `set_workspace_name` | `name` | Rename the workspace on explicit user request. |
|
|
159
|
+
| `schedule_wakeup` | `delaySeconds`, `prompt`, optional `reason` | Schedule one follow-up; the delay is clamped to 60–21,600 seconds. Replaces the workspace's pending wakeup. |
|
|
160
|
+
| `cancel_wakeup` | None | Cancel the pending wakeup, if any. |
|
|
161
|
+
| `cron_create` | `expression`, `prompt`, optional `label`, `mode`, `oneShot` | Persist a recurring trigger; mode is `resume` (default) or `fresh`. Accepts five-field cron or the documented hourly/daily/weekly/monthly/yearly aliases. |
|
|
162
|
+
| `cron_list` | None | List this workspace's schedules. |
|
|
163
|
+
| `cron_delete` | `id` | Cancel one of this workspace's schedules. |
|
|
164
|
+
|
|
165
|
+
### Documents, context and history
|
|
166
|
+
|
|
167
|
+
| Tool | Input | Purpose |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| `get_ticket` | None | Read the workspace's Notion or Sentry source context. |
|
|
170
|
+
| `list_documents` | None | List Markdown under `docs/plans/`, `docs/superpowers/`, and `.ai/thoughts/`. |
|
|
171
|
+
| `read_document` | `path` | Read a worktree-relative document within those roots. |
|
|
172
|
+
| `log_thought` | `title`, `content`, optional `tag` | Write a uniquely named decision note under `.ai/thoughts/logs/`. |
|
|
173
|
+
| `search_codebase` | `query`, optional `include_archived`, `scope`, `limit` | Search conversations, not repository source. Scope defaults to `workspace`; `all` searches across workspaces. Limit defaults to 30, maximum 100. |
|
|
174
|
+
| `get_session_usage` | None | Read workspace and active-session usage totals. |
|
|
175
|
+
| `read_workspace_events_csv` | Optional `session_id`, `offset`, `limit` | Read this workspace's conversation as paginated CSV; limit defaults to 100, maximum 500. |
|
|
176
|
+
|
|
20
177
|
### Tasks
|
|
21
178
|
|
|
22
179
|
#### `list_tasks`
|
|
@@ -113,10 +270,13 @@ Get git stats for the current workspace: commit count, files changed, insertions
|
|
|
113
270
|
### Dev server
|
|
114
271
|
|
|
115
272
|
#### `get_dev_server_status`
|
|
116
|
-
|
|
273
|
+
Query the backend for the current workspace's development-server status. If the
|
|
274
|
+
request fails, fall back to the saved database status.
|
|
117
275
|
|
|
118
276
|
**Input:** none
|
|
119
|
-
**Output:** `
|
|
277
|
+
**Output:** `DevServerStatus` — status, instance/project names, HTTP port, URL, and matched containers. See the [Docker status contract](../../CONFIGURATION.md#dev-server).
|
|
278
|
+
Without a configured start command, the backend returns `not_configured` with
|
|
279
|
+
`configured: false`. The database fallback returns `{ workspaceId, status }`.
|
|
120
280
|
|
|
121
281
|
---
|
|
122
282
|
|
|
@@ -142,7 +302,7 @@ Fetch the last N lines of the dev server logs for the current workspace.
|
|
|
142
302
|
**Input:**
|
|
143
303
|
- `tail` (number, optional) — default `200`
|
|
144
304
|
|
|
145
|
-
**Output:** `{ logs: string
|
|
305
|
+
**Output:** `{ logs: string }` — combined Docker log text.
|
|
146
306
|
|
|
147
307
|
---
|
|
148
308
|
|
|
@@ -172,7 +332,7 @@ List all images uploaded to the current workspace via Kōbō's chat paste/upload
|
|
|
172
332
|
|
|
173
333
|
### Global tools (workspace-less mode)
|
|
174
334
|
|
|
175
|
-
These 4 tools are always registered, regardless of whether `KOBO_WORKSPACE_ID` is set — they let a
|
|
335
|
+
These 4 management tools and the 6 [conversation tools](#conversation-tools) are always registered, regardless of whether `KOBO_WORKSPACE_ID` is set — they let a session that Kōbō did NOT spawn (e.g. a standalone terminal session) discover, manage and talk to workspaces instead of being bound to one. The HTTP endpoint exposes discovery and conversation only.
|
|
176
336
|
|
|
177
337
|
#### `list_workspaces`
|
|
178
338
|
List Kōbō workspaces with id, title, status, and creation date. Reads the DB directly — works even when the Kōbō backend server isn't running.
|
|
@@ -208,7 +368,7 @@ Archive a workspace by id, like the "Archiver" action in the workspace context m
|
|
|
208
368
|
---
|
|
209
369
|
|
|
210
370
|
#### `stop_workspace`
|
|
211
|
-
|
|
371
|
+
Stop the currently running agent session on a workspace, like the Stop action in the chat header. Also disables auto-loop and cancels a queued replacement. Requires the backend to be running. Safe to call when nothing is running; an unconfirmed shutdown is reported as an error.
|
|
212
372
|
|
|
213
373
|
**Input:**
|
|
214
374
|
- `workspace_id` (string, required) — from `list_workspaces`
|
|
@@ -5,7 +5,7 @@ import { nanoid } from 'nanoid'
|
|
|
5
5
|
import * as cronService from '../server/services/cron-service.js'
|
|
6
6
|
import * as settingsService from '../server/services/settings-service.js'
|
|
7
7
|
import { slugifyProjectName } from '../server/utils/project-slug.js'
|
|
8
|
-
import { resolveExistingPathInside } from '../server/utils/safe-path.js'
|
|
8
|
+
import { ensureDirectoryInside, resolveExistingPathInside } from '../server/utils/safe-path.js'
|
|
9
9
|
import { resolveWorkspaceWorktreePath } from '../server/utils/worktree-paths.js'
|
|
10
10
|
import { MASKED_SECRET, SECRET_GLOBAL_KEYS } from '../shared/consts.js'
|
|
11
11
|
|
|
@@ -583,7 +583,7 @@ export function readDocumentHandler(worktreePath: string, relPath: string): Docu
|
|
|
583
583
|
|
|
584
584
|
/**
|
|
585
585
|
* Append a thought / decision / note to
|
|
586
|
-
* `.ai/thoughts/logs/<YYYY-MM-DD>-<slug>.md`. Creates the directory if missing.
|
|
586
|
+
* `.ai/thoughts/logs/<YYYY-MM-DD>-<slug>-<timestamp>-<id>.md`. Creates the directory if missing.
|
|
587
587
|
* Returns the path (worktree-relative) of the file actually written — useful
|
|
588
588
|
* for the agent to reference it in chat.
|
|
589
589
|
*
|
|
@@ -600,8 +600,7 @@ export function logThoughtHandler(
|
|
|
600
600
|
const content = data.content?.trim()
|
|
601
601
|
if (!content) throw new Error('content is required')
|
|
602
602
|
|
|
603
|
-
const thoughtsDir = path.join(
|
|
604
|
-
fs.mkdirSync(thoughtsDir, { recursive: true })
|
|
603
|
+
const thoughtsDir = ensureDirectoryInside(worktreePath, path.join('.ai', 'thoughts', 'logs'))
|
|
605
604
|
|
|
606
605
|
const date = new Date().toISOString().slice(0, 10)
|
|
607
606
|
const slug =
|
|
@@ -613,14 +612,18 @@ export function logThoughtHandler(
|
|
|
613
612
|
.replace(/^-+|-+$/g, '')
|
|
614
613
|
.slice(0, 60) || 'note'
|
|
615
614
|
const tagSuffix = data.tag ? `-${data.tag.replace(/[^a-z0-9]+/gi, '-').toLowerCase()}` : ''
|
|
616
|
-
const filename = `${date}-${slug}${tagSuffix}.md`
|
|
617
|
-
const abs = path.join(thoughtsDir, filename)
|
|
618
|
-
const relPath = `.ai/thoughts/logs/${filename}`
|
|
619
|
-
|
|
620
615
|
const header = `# ${title}\n\n_${new Date().toISOString()}_${data.tag ? ` · tag: \`${data.tag}\`` : ''}\n\n`
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
616
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
617
|
+
const filename = `${date}-${slug}${tagSuffix}-${Date.now()}-${nanoid(10)}.md`
|
|
618
|
+
const abs = path.join(thoughtsDir, filename)
|
|
619
|
+
try {
|
|
620
|
+
fs.writeFileSync(abs, header + content + (content.endsWith('\n') ? '' : '\n'), { encoding: 'utf-8', flag: 'wx' })
|
|
621
|
+
return { path: `.ai/thoughts/logs/${filename}` }
|
|
622
|
+
} catch (err) {
|
|
623
|
+
if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
throw new Error('Could not allocate a unique thought filename')
|
|
624
627
|
}
|
|
625
628
|
|
|
626
629
|
// ── Session usage ────────────────────────────────────────────────────────────
|
|
@@ -4,6 +4,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, type Tool } from '@modelcontextprotocol/sdk/types.js'
|
|
5
5
|
import type Database from 'better-sqlite3'
|
|
6
6
|
import { getDb } from '../server/db/index.js'
|
|
7
|
+
import { WORKSPACE_DIALOGUE_TOOLS } from '../shared/workspace-dialogue-tools.js'
|
|
7
8
|
import {
|
|
8
9
|
createTaskHandler,
|
|
9
10
|
cronListHandler,
|
|
@@ -25,6 +26,7 @@ import {
|
|
|
25
26
|
setWorkspaceAgentDescriptionHandler,
|
|
26
27
|
updateTaskHandler,
|
|
27
28
|
} from './kobo-tasks-handlers.js'
|
|
29
|
+
import { callWorkspaceDialogueTool } from './workspace-dialogue-client.js'
|
|
28
30
|
|
|
29
31
|
const workspaceId = process.env.KOBO_WORKSPACE_ID
|
|
30
32
|
const dbPath = process.env.KOBO_DB_PATH
|
|
@@ -122,9 +124,12 @@ async function backendRequest(
|
|
|
122
124
|
body?: unknown,
|
|
123
125
|
): Promise<unknown> {
|
|
124
126
|
const url = `${backendUrl}${pathname}`
|
|
125
|
-
const
|
|
127
|
+
const headers: Record<string, string> = process.env.KOBO_NETWORK_TOKEN
|
|
128
|
+
? { 'X-Kobo-Token': process.env.KOBO_NETWORK_TOKEN }
|
|
129
|
+
: {}
|
|
130
|
+
const init: RequestInit = { method, headers }
|
|
126
131
|
if (body !== undefined) {
|
|
127
|
-
|
|
132
|
+
headers['Content-Type'] = 'application/json'
|
|
128
133
|
init.body = JSON.stringify(body)
|
|
129
134
|
}
|
|
130
135
|
const res = await fetch(url, init)
|
|
@@ -537,6 +542,7 @@ const WORKSPACE_SCOPED_TOOLS: Tool[] = [
|
|
|
537
542
|
]
|
|
538
543
|
|
|
539
544
|
const GLOBAL_TOOLS: typeof WORKSPACE_SCOPED_TOOLS = [
|
|
545
|
+
...WORKSPACE_DIALOGUE_TOOLS,
|
|
540
546
|
{
|
|
541
547
|
name: 'list_workspaces',
|
|
542
548
|
description:
|
|
@@ -668,6 +674,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
668
674
|
}
|
|
669
675
|
|
|
670
676
|
try {
|
|
677
|
+
if (WORKSPACE_DIALOGUE_TOOLS.some((tool) => tool.name === name)) {
|
|
678
|
+
if (workspaceId && a.workspace_id === workspaceId && name === 'send_workspace_message')
|
|
679
|
+
return fail('Use the normal conversation to communicate in your own workspace.')
|
|
680
|
+
return await callWorkspaceDialogueTool(
|
|
681
|
+
backendUrl,
|
|
682
|
+
name,
|
|
683
|
+
a,
|
|
684
|
+
process.env.KOBO_NETWORK_TOKEN,
|
|
685
|
+
process.env.KOBO_MCP_CLIENT_NAME ?? server.getClientVersion()?.name,
|
|
686
|
+
)
|
|
687
|
+
}
|
|
671
688
|
if (name === 'list_tasks') {
|
|
672
689
|
return ok(listTasksHandler(db, workspaceId!))
|
|
673
690
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
|
2
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
|
|
3
|
+
import { validateDialogueArguments } from '../shared/workspace-dialogue-tools.js'
|
|
4
|
+
import { normalizeClientName } from '../shared/workspace-message-types.js'
|
|
5
|
+
|
|
6
|
+
/** Stateless HTTP bridge: external stdio clients never own agent runtime state. */
|
|
7
|
+
export async function callWorkspaceDialogueTool(
|
|
8
|
+
backendUrl: string,
|
|
9
|
+
name: string,
|
|
10
|
+
args: unknown,
|
|
11
|
+
token?: string,
|
|
12
|
+
clientName?: string,
|
|
13
|
+
) {
|
|
14
|
+
const arguments_ = validateDialogueArguments(name, args)
|
|
15
|
+
const client = new Client({ name: 'kobo-stdio-bridge', version: '1.0.0' })
|
|
16
|
+
const signal = AbortSignal.timeout(30_000)
|
|
17
|
+
const transport = new StreamableHTTPClientTransport(new URL(`${backendUrl.replace(/\/$/, '')}/api/mcp`), {
|
|
18
|
+
requestInit: {
|
|
19
|
+
signal,
|
|
20
|
+
headers: {
|
|
21
|
+
...(token ? { 'X-Kobo-Token': token } : {}),
|
|
22
|
+
'X-Kobo-Client-Name': encodeURIComponent(normalizeClientName(clientName)),
|
|
23
|
+
'X-Kobo-Client-Name-Encoding': 'uri',
|
|
24
|
+
'X-Kobo-Client-Transport': 'stdio',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
try {
|
|
29
|
+
await client.connect(transport, { signal })
|
|
30
|
+
return await client.callTool({ name, arguments: arguments_ }, undefined, { signal })
|
|
31
|
+
} finally {
|
|
32
|
+
await client.close()
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import{S as e,ct as t,j as n,ot as r,ut as i,v as a}from"./reactivity.esm-bundler-DEJj9cFv.js";import{C as o,F as s,J as c,L as l,N as u,O as d,P as f,Y as p,_ as m,d as h,f as g,g as _,j as v,k as y,l as b,p as x,r as S,u as C,y as w,z as T}from"./runtime-core.esm-bundler-CDnVUfeZ.js";import{J as E,b as D,ct as O,l as k,pt as A,t as ee,tt as j,w as M,y as N}from"./QBtn-CZaBclNw.js";import{A as te,At as ne,Ct as re,Nt as P,O as F,d as ie,k as ae,m as oe,p as se,q as ce,xt as I}from"./index-VL3fI9a3.js";import{t as le}from"./QSpinnerDots-DnCV3VzI.js";import{t as ue}from"./QList-qupzuEqO.js";import{t as de}from"./QMarkupTable-B9QuKtK_.js";import{c as L,l as R}from"./QSelect-xd-AlGo_.js";import{d as fe}from"./permissionModes-C-9Crj-c.js";import{r as pe,t as z}from"./pending-diff-open-DOtELZfB.js";import{t as B}from"./documents-C2cLnEBQ.js";import{a as V}from"./use-tours-CSVM_54K.js";import{t as H}from"./QTooltip-CwcCGSWq.js";import{i as U,n as me,o as he,r as W,t as ge}from"./render-chat-markdown-DlbQLZ02.js";import{a as _e,i as ve,n as ye,o as be,r as xe,s as Se}from"./WorkspacePage-DKRpdpPg.js";function G(e,t){return o(`div`,e,[o(`table`,{class:`q-table`},t)])}var Ce={list:ue,table:de},we=[`list`,`table`,`__qtable`],Te=j({name:`QVirtualScroll`,props:{...R,type:{type:String,default:`list`,validator:e=>we.includes(e)},items:{type:Array,default:()=>[]},itemsFn:Function,itemsSize:Number,scrollTarget:P},setup(t,{slots:n,attrs:r}){let i,a=e(null),s=b(()=>t.itemsSize>=0&&t.itemsFn!==void 0?Number.parseInt(t.itemsSize,10):Array.isArray(t.items)?t.items.length:0),{virtualScrollSliceRange:l,localResetVirtualScroll:d,padVirtualScroll:p,onVirtualScrollEvt:m}=L({virtualScrollLength:s,getVirtualScrollTarget:S,getVirtualScrollEl:x}),h=b(()=>{if(s.value===0)return[];let e=(e,t)=>({index:l.value.from+t,item:e});return t.itemsFn===void 0?t.items.slice(l.value.from,l.value.to).map(e):t.itemsFn(l.value.from,l.value.to-l.value.from).map(e)}),g=b(()=>`q-virtual-scroll q-virtual-scroll`+(t.virtualScrollHorizontal?`--horizontal`:`--vertical`)+(t.scrollTarget===void 0?` scroll`:``)),_=b(()=>t.scrollTarget===void 0?{tabindex:0}:{});c(s,()=>{d()}),c(()=>t.scrollTarget,()=>{w(),C()});function x(){let e=a.value;return e===null?null:e.$el||e}function S(){return i}function C(){let e=x();e!==null&&(i=ne(e,t.scrollTarget),i.addEventListener(`scroll`,m,E.passive))}function w(){i!==void 0&&(i.removeEventListener(`scroll`,m,E.passive),i=void 0)}function T(){let e=p(t.type===`list`?`div`:`tbody`,h.value.map(n.default));return n.before!==void 0&&(e=n.before().concat(e)),D(n.after,e)}return d(),f(()=>{C()}),y(()=>{C()}),u(()=>{w()}),v(()=>{w()}),()=>{if(n.default===void 0){console.error(`QVirtualScroll: default scoped slot is required for rendering`);return}return t.type===`__qtable`?G({ref:a,class:`q-table__middle `+g.value,tabindex:0},T()):o(Ce[t.type],{...r,ref:a,class:[r.class,g.value],..._.value},T)}}}),K=new Set([`setup`,`cleanup`,`archive`]);function q(e){switch(e.type){case`user`:return e.sender===`system-prompt`?`system-prompt`:K.has(e.sender)||F(e.sender)?`script`:`user`;case`session`:return`session`;default:return`agent`}}function Ee(e){let t=[],n=null,r=null;for(let i of e){let e=q(i),a=e===`session`||e===`system-prompt`,o=e===`script`&&i.type===`user`?`script:${i.sender}`:e;!n||r!==o||a?(n={speaker:e,ts:i.ts,items:[i]},r=o,t.push(n),a&&(n=null)):n.items.push(i)}return t}function De(e){switch(e.type){case`text`:return`text:${e.messageId}`;case`thinking`:return`thinking:${e.messageId}:${e.eventIds?.[0]??e.ts??``}`;case`tool`:return`tool:${e.toolCallId}`;case`session`:return`session:${e.kind}:${e.eventIds?.[0]??e.ts??``}`;case`user`:return`user:${e.eventIds?.[0]??`${e.sender}:${e.ts??``}`}`;case`error`:return`error:${e.eventIds?.[0]??`${e.category}:${e.ts??``}`}`}}function Oe(e){let t=e.items[0];return`${e.speaker}:${t?De(t):`empty`}`}function ke(e,t){let n=Math.min(t,e.length)-1;for(let t=n;t>=0;t--)if(e[t]?.speaker===`user`)return t;return-1}function Ae(e,t,n){return new Promise(r=>{let i=!1,a=null,o=null,s=e=>{i||(i=!0,a!==null&&clearTimeout(a),a=null,o?.(),r(e))};if(o=c(e,e=>{t(e)&&s(!0)},{immediate:!0}),i){o();return}a=setTimeout(()=>s(!1),n)})}var je={class:`agent-error-item`},Me={class:`agent-error-item__body`},Ne={class:`agent-error-item__title`},J={class:`agent-error-item__message`},Pe=V(w({__name:`AgentErrorItem`,props:{item:{}},setup(e){let t=e,{te:n}=I(),r=b(()=>{let e=`agent.error.${t.item.category}`;return n(e)?e:`agent.error.other`});return(t,n)=>(l(),x(`div`,je,[m(k,{name:`error_outline`,size:`16px`,class:`agent-error-item__icon`}),C(`div`,Me,[C(`div`,Ne,i(t.$t(r.value)),1),C(`div`,J,i(e.item.message),1)])]))}}),[[`__scopeId`,`data-v-e98c3c02`]]),Fe={class:`text-caption text-kobo-3`},Y=w({__name:`SessionEventItem`,props:{item:{}},setup(e){let t=e,n=b(()=>{switch(t.item.kind){case`started`:return`session.started`;case`ended`:return Se(t.item.detail);case`compacted`:return`session.compacted`;default:return`session.started`}});return(e,t)=>(l(),x(`span`,Fe,i(e.$t(n.value)),1))}});function Ie(e,t){if(t.length===0||e.length===0)return e;let n=[...t].sort((e,t)=>t.length-e.length),r=new DOMParser().parseFromString(`<div>${e}</div>`,`text/html`),i=r.body.firstChild;if(!i)return e;function a(e){if(e.nodeType===Node.TEXT_NODE){X(e,n,r);return}if(e.nodeName===`A`)return;let t=Array.from(e.childNodes);for(let e of t)a(e)}return a(i),i.innerHTML}function X(e,t,n){let r=e.textContent??``;if(!t.some(e=>r.includes(e)))return;let i=n.createDocumentFragment(),a=0;for(;a<r.length;){let e=Le(r,a,t);if(!e){i.appendChild(n.createTextNode(r.slice(a)));break}e.index>a&&i.appendChild(n.createTextNode(r.slice(a,e.index)));let o=n.createElement(`a`);o.className=`document-link`,o.setAttribute(`data-document-path`,e.path),o.setAttribute(`href`,`#`),o.textContent=e.path,i.appendChild(o),a=e.index+e.path.length}e.parentNode?.replaceChild(i,e)}function Le(e,t,n){let r=null;for(let i of n){let n=e.indexOf(i,t);n<0||(!r||n<r.index||n===r.index&&i.length>r.path.length)&&(r={index:n,path:i})}return r}var Z=[`innerHTML`],Q=V(w({__name:`TextMessageItem`,props:{item:{}},setup(e){let t=e,n=B(),r=se(),i=N(),{t:a}=I(),o=b(()=>{let e=r.selectedWorkspaceId;return e?n.documentsFor(e).map(e=>e.path):[]}),s=b(()=>{let e=t.item;if(e.streaming)return ge(e.text);let n=o.value;return W(`${e.messageId}|${n.join(`,`)}`,e.text,e=>{let t=Ie(he.parse(e,{async:!1,breaks:!0,gfm:!0}),n);return U(t,{addAttr:[`data-document-path`]})})});function c(e){let t=e.target?.closest(`.document-link`);if(!t)return;e.preventDefault();let o=t.getAttribute(`data-document-path`),s=r.selectedWorkspaceId;o&&s&&n.openDocumentByPath(s,o).catch(e=>{console.error(`[TextMessageItem] openDocumentByPath failed:`,e),i.notify({type:`negative`,message:a(`documents.loadFailed`),position:`top`})})}return(t,n)=>(l(),x(`div`,{class:`markdown-message`,onClick:c},[C(`div`,{innerHTML:s.value},null,8,Z),e.item.streaming?(l(),h(M,{key:0,size:`xs`,class:`q-ml-xs`})):g(``,!0)]))}}),[[`__scopeId`,`data-v-99371035`]]);function Re(e,t){let n=e.split(`
|
|
2
|
-
`),r=t.split(`
|
|
3
|
-
`),i=0;for(;i<n.length&&i<r.length&&n[i]===r[i];)i++;let a=n.length,o=r.length;for(;a>i&&o>i&&n[a-1]===r[o-1];)a--,o--;let s=n.slice(0,i).map(e=>({type:`context`,content:e})),c=n.slice(a).map(e=>({type:`context`,content:e})),l=n.slice(i,a),u=r.slice(i,o);return l.length>800||u.length>800?[...s,...l.map(e=>({type:`del`,content:e})),...u.map(e=>({type:`add`,content:e})),...c]:[...s,...$(l,u),...c]}function $(e,t){let n=e.length,r=t.length;if(n===0&&r===0)return[];if(n===0)return t.map(e=>({type:`add`,content:e}));if(r===0)return e.map(e=>({type:`del`,content:e}));let i=r+1,a=new Int32Array((n+1)*i);for(let o=n-1;o>=0;o--)for(let n=r-1;n>=0;n--)a[o*i+n]=e[o]===t[n]?a[(o+1)*i+(n+1)]+1:Math.max(a[(o+1)*i+n],a[o*i+(n+1)]);let o=[],s=0,c=0;for(;s<n&&c<r;)e[s]===t[c]?(o.push({type:`context`,content:e[s]}),s++,c++):a[(s+1)*i+c]>=a[s*i+(c+1)]?(o.push({type:`del`,content:e[s]}),s++):(o.push({type:`add`,content:t[c]}),c++);for(;s<n;)o.push({type:`del`,content:e[s++]});for(;c<r;)o.push({type:`add`,content:t[c++]});return o}function ze(e){let t=e.split(`
|
|
4
|
-
`),n=[],r=!1;for(let e of t){if(e.startsWith(`@@`)){r=!0;continue}(r||!e.startsWith(`+++`)&&!e.startsWith(`---`))&&(e.startsWith(`+`)?n.push({type:`add`,content:e.slice(1)}):e.startsWith(`-`)?n.push({type:`del`,content:e.slice(1)}):e.startsWith(` `)?n.push({type:`context`,content:e.slice(1)}):e.length>0&&n.push({type:`context`,content:e}))}return n}function Be(e,t){if(!t||typeof t!=`object`)return null;let n=t;if(e===`Edit`){let e=n.file_path;if(!e)return null;let t=n.old_string??``,r=n.new_string??``,i=typeof n.diff==`string`?n.diff:``;if(!t&&!r&&i.length>0){let t=ze(i);return{toolName:`Edit`,filePath:e,additions:t.filter(e=>e.type===`add`).length,deletions:t.filter(e=>e.type===`del`).length,diffLines:t}}return{toolName:`Edit`,filePath:e,oldString:t,newString:r,replaceAll:n.replace_all??!1,additions:r?r.split(`
|
|
5
|
-
`).length:0,deletions:t?t.split(`
|
|
6
|
-
`).length:0}}if(e===`Write`){let e=n.file_path;if(!e)return null;let t=n.content??``;return{toolName:`Write`,filePath:e,content:t,additions:t?t.split(`
|
|
7
|
-
`).length:0,deletions:0}}if(e===`Bash`){let e=(n.command??``).match(/^\s*rm\s+(?:-[a-zA-Z]*\s+)*(.+)/);if(e)return{toolName:`Bash:rm`,filePath:e[1].trim().replace(/["']/g,``),additions:0,deletions:1}}return null}function Ve(e,t){if(!e||!t?.projectPath)return e;let n=t.worktreePath;if(n){let t=He(e,n);if(t!==e)return t}let r=He(e,`${t.projectPath}/${te}/${t.workingBranch}`);return r===e?He(e,t.projectPath):r}function He(e,t){if(!t)return e;let n=Ue(t);return n?e.replace(RegExp(`${n}[\\\\/]+`,`g`),``).replace(RegExp(`${n}(?=\\s|$|["'\`])`,`g`),`.`):e}function Ue(e){let t=e.replace(/[\\/]+$/,``);return t?`${/^[\\/]+/.test(t)?`[\\\\/]+`:``}${t.split(/[\\/]+/).filter(Boolean).map(We).join(`[\\\\/]+`)}`:``}function We(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}var Ge={class:`tool-name`},Ke=[`title`],qe={key:0,class:`tool-stat-add`},Je={key:1,class:`tool-stat-del`},Ye={class:`diff-sign`},Xe={class:`tool-name`},Ze=[`title`],Qe=V(w({__name:`ToolCallItem`,props:{item:{}},setup(e){let t=e,o=a(!1),s=se(),{t:u}=I(),d=b(()=>Be(t.item.name,t.item.input)),f=b(()=>d.value?Ve(d.value.filePath,s.selectedWorkspace):``),v={Bash:`terminal`,Read:`description`,Edit:`edit`,Write:`edit_note`,MultiEdit:`edit`,Glob:`folder_open`,Grep:`manage_search`,LS:`list`,Skill:`auto_awesome`,Task:`hub`,Agent:`hub`,TodoWrite:`checklist`,TodoRead:`checklist`,TaskCreate:`add_task`,TaskUpdate:`checklist`,TaskGet:`checklist`,TaskList:`checklist`,ToolSearch:`search`,WebFetch:`public`,WebSearch:`travel_explore`,NotebookRead:`book`,NotebookEdit:`edit_note`,SendMessage:`send`,ExitPlanMode:`check_circle_outline`,KillShell:`stop_circle`,BashOutput:`terminal`},y=b(()=>v[t.item.name]??`build`),w=b(()=>{if(d.value)return``;let e=t.item.input,n=E(e);return n?Ve(n,s.selectedWorkspace):``});function E(e){if(!e||typeof e!=`object`)return typeof e==`string`?e:``;let t=e;for(let e of[`file_path`,`path`,`command`,`pattern`,`query`,`url`,`skill`,`description`,`subject`,`prompt`]){let n=t[e];if(typeof n==`string`&&n.length>0)return n}for(let e of Object.values(t))if(typeof e==`string`&&e.length>0)return e;return``}let D=b(()=>{let e=d.value;return e?e.diffLines?e.diffLines:e.toolName===`Edit`&&e.oldString!==void 0&&e.newString!==void 0?Re(e.oldString,e.newString):e.toolName===`Write`&&e.content!==void 0?e.content.split(`
|
|
8
|
-
`).map(e=>({type:`add`,content:e})):e.toolName===`Bash:rm`?[{type:`del`,content:`File deleted`}]:null:null}),O=b(()=>{let e=t.item.result;if(!e)return``;if(typeof e.output==`string`)return e.output;try{return JSON.stringify(e.output)}catch{return String(e.output)}}),j=new Set([`Read`]),M=b(()=>!!(t.item.result&&O.value)&&(!j.has(t.item.name)||t.item.result?.isError===!0));function N(){o.value=!o.value}function te(){let e=d.value?.filePath,t=s.selectedWorkspace,n=t?.id,r=e?Ve(e,t):``;r&&!/^(?:[A-Za-z]:)?[\\/]/.test(r)&&n&&(z(n,r),window.dispatchEvent(new CustomEvent(`kobo:open-diff`,{detail:{workspaceId:n,path:r}})))}return c(()=>t.item.result?.isError===!0,e=>{e&&(o.value=!0)},{immediate:!0}),(t,a)=>d.value?(l(),x(`div`,{key:0,class:r([`tool-row`,{"tool-row-expanded":o.value}])},[C(`div`,{class:`tool-header`,onClick:N},[m(k,{name:y.value,size:`14px`,class:`tool-icon`},null,8,[`name`]),C(`span`,Ge,i(d.value.toolName===`Bash:rm`?`Bash`:d.value.toolName),1),C(`span`,{class:`tool-path`,title:d.value.filePath},i(f.value),9,Ke),m(ee,{flat:``,dense:``,round:``,size:`xs`,icon:`open_in_new`,class:`tool-open-diff`,onClick:A(te,[`stop`])},{default:p(()=>[m(H,null,{default:p(()=>[_(i(n(u)(`chat.openInGitDiff`)),1)]),_:1})]),_:1}),d.value.additions>0?(l(),x(`span`,qe,`+`+i(d.value.additions),1)):g(``,!0),d.value.deletions>0?(l(),x(`span`,Je,`-`+i(d.value.deletions),1)):g(``,!0),e.item.result?.isError?(l(),h(k,{key:2,name:`error_outline`,color:`negative`,size:`xs`,class:`q-ml-xs`})):e.item.result?(l(),h(k,{key:3,name:`check`,color:`positive`,size:`xs`,class:`q-ml-xs`})):g(``,!0),m(k,{name:o.value?`expand_less`:`expand_more`,size:`xs`,class:`q-ml-auto text-kobo-3`},null,8,[`name`])]),o.value&&D.value?(l(),x(`div`,{key:0,class:`tool-diff`,onClick:a[0]||=A(()=>{},[`stop`])},[(l(!0),x(S,null,T(D.value,(e,t)=>(l(),x(`div`,{key:t,class:r([`diff-line`,{"diff-del":e.type===`del`,"diff-add":e.type===`add`,"diff-context":e.type===`context`}])},[C(`span`,Ye,i(e.type===`del`?`-`:e.type===`add`?`+`:` `),1),_(i(e.content),1)],2))),128))])):g(``,!0)],2)):(l(),x(`div`,{key:1,class:r([`tool-row tool-row-generic`,{"tool-row-expanded":o.value,"tool-row--toggleable":M.value}])},[C(`div`,{class:`tool-header`,onClick:a[1]||=e=>M.value&&N()},[m(k,{name:y.value,size:`14px`,class:`tool-icon`},null,8,[`name`]),C(`span`,Xe,i(e.item.name),1),w.value?(l(),x(`span`,{key:0,class:`tool-arg`,title:E(e.item.input)||w.value},i(w.value),9,Ze)):g(``,!0),e.item.result?.isError?(l(),h(k,{key:1,name:`error_outline`,color:`negative`,size:`xs`,class:`q-ml-auto`})):e.item.result?(l(),h(k,{key:2,name:`check`,color:`positive`,size:`xs`,class:`q-ml-auto`})):g(``,!0),M.value?(l(),h(k,{key:3,name:o.value?`expand_less`:`expand_more`,size:`xs`,class:`q-ml-xs text-kobo-3`},null,8,[`name`])):g(``,!0)]),o.value&&M.value?(l(),x(`div`,{key:0,class:`tool-output`,onClick:a[2]||=A(()=>{},[`stop`])},i(O.value),1)):g(``,!0)],2))}}),[[`__scopeId`,`data-v-2482adfe`]]);function $e(e,t){return t?e.replace(/\[image:\s+([^\]]+)\]/g,(e,n)=>{let r=String(n).trim();return/^(\.ai\/images\/|images\/)/.test(r)?`}/images/file?path=${encodeURIComponent(r)}`})`:e}):e}var et=[`innerHTML`],tt=[`innerHTML`],nt=[`src`],rt=V(w({__name:`UserMessageItem`,props:{item:{}},setup(e){let t=e,n=se(),r=b(()=>t.item.sender===`system-prompt`),i=b(()=>{let e=$e(t.item.content,n.selectedWorkspaceId??``);return me(e)}),o=a(null),s=a(!1);function c(e){let t=e.target;if(t?.tagName!==`IMG`)return;let n=t;n.src&&(o.value=n.src,s.value=!0)}return(e,t)=>(l(),x(S,null,[r.value?(l(),h(fe,{key:0,dense:``,"dense-toggle":``,label:e.$t(`chat.systemPrompt`),"header-class":`text-kobo-2 text-caption`},{default:p(()=>[C(`div`,{class:`q-py-xs markdown-user-prompt`,innerHTML:i.value},null,8,et)]),_:1},8,[`label`])):(l(),x(`div`,{key:1,class:`markdown-message`,onClick:c},[C(`div`,{innerHTML:i.value},null,8,tt)])),m(re,{modelValue:s.value,"onUpdate:modelValue":t[1]||=e=>s.value=e},{default:p(()=>[o.value?(l(),x(`img`,{key:0,src:o.value,alt:``,class:`image-lightbox-img`,onClick:t[0]||=e=>s.value=!1},null,8,nt)):g(``,!0)]),_:1},8,[`modelValue`])],64))}}),[[`__scopeId`,`data-v-7687eb7e`]]),it=[`data-event-ids`],at={class:`turn-header`},ot={key:0,class:`turn-time`},st={class:`turn-time turn-time-updated`},ct={key:2,class:`turn-actions`},lt={class:`turn-body`},ut={key:0,class:`turn-scroll-top`},dt=V(w({__name:`TurnCard`,props:{turn:{},highlighted:{type:Boolean}},emits:[`scrollTo`],setup(e,{emit:o}){let s=e,c=o,{t:u}=I(),d=a(null);function f(){let e=d.value;if(!e)return;let t=e.closest(`.q-scrollarea`)?.querySelector(`.q-scrollarea__content`);if(!t){e.scrollIntoView({behavior:`smooth`,block:`start`});return}let n=e.getBoundingClientRect().top-t.getBoundingClientRect().top;c(`scrollTo`,Math.max(0,n-8))}let v=b(()=>{switch(s.turn.speaker){case`user`:return{label:u(`chat.you`),accent:`var(--kobo-turn-user)`,badgeClass:`turn-badge-user`};case`agent`:return{label:u(`chat.agent`),accent:`var(--kobo-turn-agent)`,badgeClass:`turn-badge-agent`};case`system-prompt`:return{label:u(`chat.systemPrompt`),accent:`var(--kobo-text-3)`,badgeClass:`turn-badge-system`};case`session`:return{label:u(`chat.session`),accent:`var(--kobo-text-3)`,badgeClass:`turn-badge-session`};case`script`:{let e=s.turn.items[0],t=e?.type===`user`?e.sender:``;return{label:F(t)?u(`chat.hookScript`,{event:t.slice(5)}):u(t===`archive`?`chat.archiveScript`:t===`setup`?`chat.setupScript`:`chat.cleanupScript`),accent:`var(--kobo-success)`,badgeClass:`turn-badge-script`}}}});function y(e,t=!1){if(!e)return``;let n=new Date(e);return Number.isNaN(n.getTime())?``:n.toLocaleTimeString(void 0,t?{hour:`2-digit`,minute:`2-digit`,second:`2-digit`}:{hour:`2-digit`,minute:`2-digit`})}let w=b(()=>y(s.turn.ts)),E=b(()=>s.turn.items.flatMap(e=>e.eventIds??[]).join(` `)),D=b(()=>{let e=s.turn.items;if(e.length===0)return null;for(let t=e.length-1;t>=0;t--){let n=e[t].ts;if(n)return n}return null}),O=b(()=>{let e=s.turn.ts,t=D.value;if(!t||!e||t===e)return``;let n=new Date(e).getTime(),r=new Date(t).getTime();return Number.isNaN(n)||Number.isNaN(r)||r<=n?``:y(t,r-n<6e4)}),A=b(()=>O.value!==``),j=b(()=>s.turn.items.filter(e=>e.type===`tool`).length);return(a,o)=>(l(),x(`div`,{ref_key:`cardEl`,ref:d,class:r([`turn-card`,{"turn-card--user":e.turn.speaker===`user`,"turn-card--highlighted":e.highlighted}]),"data-event-ids":E.value,style:t({"--turn-accent":v.value.accent})},[C(`div`,at,[C(`span`,{class:r([`turn-badge`,v.value.badgeClass])},i(v.value.label),3),w.value?(l(),x(`span`,ot,i(w.value),1)):g(``,!0),A.value?(l(),x(S,{key:1},[m(k,{name:`arrow_forward`,size:`10px`,color:`kobo-3`,class:`turn-time-arrow`}),C(`span`,st,[_(i(O.value)+` `,1),m(H,null,{default:p(()=>[_(i(n(u)(`chat.lastUpdatedAt`,{time:O.value})),1)]),_:1})])],64)):g(``,!0),j.value>0?(l(),x(`span`,ct,` · `+i(n(u)(`chat.nActions`,{n:j.value})),1)):g(``,!0)]),C(`div`,lt,[(l(!0),x(S,null,T(e.turn.items,e=>(l(),x(S,{key:n(De)(e)},[e.type===`text`?(l(),h(Q,{key:0,item:e},null,8,[`item`])):e.type===`thinking`?(l(),h(ye,{key:1,item:e},null,8,[`item`])):e.type===`tool`?(l(),h(Qe,{key:2,item:e},null,8,[`item`])):e.type===`user`?(l(),h(rt,{key:3,item:e},null,8,[`item`])):e.type===`session`?(l(),h(Y,{key:4,item:e},null,8,[`item`])):e.type===`error`?(l(),h(Pe,{key:5,item:e},null,8,[`item`])):g(``,!0)],64))),128))]),e.turn.items.length>4?(l(),x(`div`,ut,[m(ee,{flat:``,round:``,dense:``,size:`xs`,icon:`arrow_upward`,color:`kobo-3`,class:`turn-scroll-top-btn`,onClick:f},{default:p(()=>[m(H,null,{default:p(()=>[_(i(n(u)(`chat.scrollToTurnTop`)),1)]),_:1})]),_:1})])):g(``,!0)],14,it))}}),[[`__scopeId`,`data-v-6e61835e`]]),ft={key:0,class:`activity-feed-switching`},pt={key:1,class:`activity-feed-wrap`,"data-tour":`ws-chat`},mt=[`aria-label`],ht={key:0,class:`activity-feed-compacting`},gt={class:`text-caption text-kobo-2`},_t={key:0,class:`text-center q-py-sm text-caption text-kobo-3`},vt={key:1,class:`activity-feed-empty q-pa-md`},yt={class:`activity-feed-empty__title`},bt={class:`activity-feed-empty__hint`},xt={key:2,class:`q-px-md q-pb-md`},St={class:`activity-feed-nav-cluster`},Ct=300,wt=60,Tt=200,Et=180,Dt=V(w({__name:`ActivityFeed`,props:{workspaceId:{}},setup(e){let{t}=I(),r=e,o=ce(),u=ae(),v=se(),y=ie(),w=b(()=>y.isCompacting(r.workspaceId)),E=b(()=>v.selectedSessionId),D=b(()=>v.sessions.find(e=>e.id===E.value)?.engineSessionId??null),A=b(()=>{let e=v.sessions;return e.length!==0&&E.value===e[e.length-1].id});function j(e){return E.value?e?e===E.value||e===D.value:A.value:!0}let N=b(()=>(v.activityFeeds[r.workspaceId]??[]).filter(e=>e.type===`text`&&typeof e.content==`string`&&j(e.sessionId)).map(e=>({content:e.content,sender:e.meta?.sender??`user`,ts:e.timestamp,sessionId:e.sessionId,eventIds:[e.id]}))),te=b(()=>{let e=v.workspaces.find(e=>e.id===r.workspaceId);return oe(e?.status)}),ne=xe(),re=``,P=b(()=>{let e=o.eventsFor(r.workspaceId),t=o.timestampsFor(r.workspaceId),n=o.sessionIdsFor(r.workspaceId),i=o.eventIdsFor(r.workspaceId),a=[],s=[],c=[];for(let r=0;r<e.length;r++)j(n[r])&&(a.push(e[r]),s.push(t[r]),c.push(i[r]??null));let l=`${r.workspaceId}::${E.value??`*`}`;l!==re&&(ne=xe(),re=l);let d=ve(ne,a,s,te.value,c);return Ee(be(d,N.value).filter(e=>e.type===`thinking`?!1:e.type===`session`?e.kind===`ended`?u.showVerboseSystemMessages||!_e(e.detail):u.showVerboseSystemMessages:!0))}),F=b(()=>u.showVerboseSystemMessages?o.eventsFor(r.workspaceId).filter(e=>e.kind===`message:raw`).map(e=>e.content):[]),ue=b(()=>{for(let e=P.value.length-1;e>=0;e--){let n=P.value[e]?.items??[];for(let e=n.length-1;e>=0;e--){let r=n[e];if(r){if(r.type===`text`&&!r.streaming)return{key:`text:${r.messageId}`,text:r.text};if(r.type===`tool`)return r.result?{key:`tool:${r.toolCallId}:end`,text:r.result.isError?t(`activity.a11y.toolFailed`,{name:r.name}):t(`activity.a11y.toolFinished`,{name:r.name})}:{key:`tool:${r.toolCallId}:start`,text:t(`activity.a11y.toolStarted`,{name:r.name})}}}}return null}),de=a(``);c(ue,(e,n)=>{if(!e||e.key===n?.key)return;let r=e.key.startsWith(`text:`)?t(`activity.a11y.agentSaid`,{text:e.text.slice(0,Ct)}):e.text;de.value=r});let L=a(null),R=a(!0),z=a(!1),B=a(null),V=!1,H=a(new Set),U=b(()=>{if(P.value.length>0||F.value.length>0)return!1;let e=r.workspaceId,t=E.value;return!!v.loadingSessions[e]||y.isSyncPending(e)||t!==null&&H.value.has(W(e,t))}),me=a(new Map);function he(e){let t=e.verticalSize-e.verticalPosition-e.verticalContainerSize;R.value=t<=wt,V&&e.verticalPosition<=Tt&&!z.value&&ge()&&Ce()}function W(e,t){return`${e}:${t}`}function ge(){let e=E.value;return e?me.value.get(W(r.workspaceId,e))??!0:o.hasMoreOlderFor(r.workspaceId)}function ye(e,t,n){me.value.set(W(e,t),n)}function Se(e){if(!E.value)return o.oldestIdFor(e);let t=o.eventIdsFor(e),n=o.sessionIdsFor(e);for(let e=0;e<t.length;e++){if(!j(n[e]))continue;let r=t[e];if(r)return r}}let G=null;function Ce(){return G||(G=we().finally(()=>{G=null}),G)}async function we(){let e=r.workspaceId,t=E.value,n=Se(e);if(n){z.value=!0;try{let r=L.value;await d();let i=r?.getScroll().verticalSize??0,a=r?.getScroll().verticalPosition??0,s=new URLSearchParams({before:n,limit:`200`});t&&s.set(`session`,t);let c=await fetch(`/api/workspaces/${e}/events?${s.toString()}`);if(!c.ok){t?ye(e,t,!1):o.prepend(e,[],[],{oldestId:n,hasMoreOlder:!1});return}let l=await c.json(),u=l.events??[],f=u.filter(t=>t.type===`agent:event`&&t.workspaceId===e),p=u.filter(t=>t.type===`user:message`&&t.workspaceId===e),m=f.map(e=>e.payload),h=f.map(e=>e.createdAt),g=f.map(e=>e.sessionId??null),_=f.map(e=>e.id),y=u.length>0?u[0].id:n;t&&ye(e,t,l.hasMore),o.prepend(e,m,h,{oldestId:y,hasMoreOlder:t?o.hasMoreOlderFor(e):l.hasMore,sessionIds:g,eventIds:_});for(let t of p){let n=t.payload;typeof n.content==`string`&&v.addActivityItem(e,{id:t.id,type:`text`,content:n.content,timestamp:t.createdAt,sessionId:t.sessionId??void 0,meta:{sender:n.sender??`user`}})}if(await d(),r){let e=r.getScroll().verticalSize-i;if(e>0){let t=Math.max(a+e,250);r.setScrollPosition(`vertical`,t,0)}}}catch(e){console.error(`[ActivityFeed] failed to load older events:`,e)}finally{z.value=!1}}}async function K(e=0){await d();let t=L.value;if(!t)return;let n=t.getScroll();t.setScrollPosition(`vertical`,n.verticalSize,e)}let q=null,De=0;function je(){if(q!=null)return;let e=performance.now()-De<Et;q=requestAnimationFrame(()=>{q=null,De=performance.now(),K(e?0:180)})}function Me(e){let t=L.value;t&&t.setScrollPosition(`vertical`,Math.max(0,e),250)}function Ne(){let e=window.location.hash,t=e.indexOf(`?`);if(t===-1||!new URLSearchParams(e.slice(t+1)).has(`eventId`))return;let n=e.slice(0,t);window.history.replaceState(window.history.state,``,`${window.location.pathname}${window.location.search}${n}`)}async function J(e){let t=e.detail;if(t?.workspaceId===r.workspaceId&&t.eventId)try{let e=new URLSearchParams({around:t.eventId,limit:`200`});t.sessionId&&e.set(`session`,t.sessionId);let n=await fetch(`/api/workspaces/${r.workspaceId}/events?${e}`);if(!n.ok)return;let i=await n.json(),a=i.events??[],s=a.filter(e=>e.type===`agent:event`&&e.workspaceId===r.workspaceId),c=a.filter(e=>e.type===`user:message`&&e.workspaceId===r.workspaceId);o.reset(r.workspaceId,s.map(e=>e.payload),s.map(e=>e.createdAt),{oldestId:a[0]?.id,hasMoreOlder:i.hasMore??!1,sessionIds:s.map(e=>e.sessionId),eventIds:s.map(e=>e.id)});for(let e of c){let t=e.payload;typeof t.content==`string`&&v.addActivityItem(r.workspaceId,{id:e.id,type:`text`,content:t.content,timestamp:e.createdAt,sessionId:e.sessionId??void 0,meta:{sender:t.sender??`user`}})}await Ae(U,e=>!e,5e3),await d(),await new Promise(e=>requestAnimationFrame(()=>requestAnimationFrame(()=>e())));let l=P.value.findIndex(e=>e.items.some(e=>e.eventIds?.includes(t.eventId)??!1));if(l<0)return;B.value=t.eventId,Pe.value?.scrollTo(l,`center`),Y.value=l,window.setTimeout(()=>{B.value===t.eventId&&(B.value=null)},1800)}catch(e){console.error(`[ActivityFeed] failed to focus history event:`,e)}}let Pe=a(null),Fe=a(null),Y=a(0);function Ie(e){Y.value=e.index}let X=a(!1);async function Le(){if(X.value)return;X.value=!0;let e=r.workspaceId;try{let t=ke(P.value,Y.value);if(t<0)for(let n=0;n<15;n++){if(e!==r.workspaceId)return;if(!ge())break;let n=P.value.length;if(await Ce(),await d(),e!==r.workspaceId)return;if(Y.value+=P.value.length-n,t=ke(P.value,Y.value),t>=0)break}t>=0&&e===r.workspaceId&&(Pe.value?.scrollTo(t,`start`),Y.value=t)}finally{X.value=!1}}async function Z(){V=!1,await d(),await K(0),await new Promise(e=>requestAnimationFrame(()=>requestAnimationFrame(()=>e()))),await K(0),V=!0}let Q=b(()=>{let e=o.sessionIdsFor(r.workspaceId);if(!E.value)return e.length;let t=0;for(let n of e)j(n)&&t++;return t});c(U,async e=>{!e&&Q.value>0&&await Z(),e||d(()=>{Fe.value=L.value?.getScrollTarget()??null})}),f(()=>{window.addEventListener(`kobo:focus-history-event`,J),d(()=>{Fe.value=L.value?.getScrollTarget()??null}),Q.value>0&&Z(),E.value&&ze();let e=new URLSearchParams(window.location.hash.split(`?`)[1]??``).get(`eventId`);e&&(J(new CustomEvent(`kobo:focus-history-event`,{detail:{workspaceId:r.workspaceId,sessionId:E.value,eventId:e}})),Ne())});let Re=Q.value>0;c(Q,async(e,t)=>{if(!z.value){if(!Re&&e>0){Re=!0,await Z();return}e>t&&R.value&&!z.value&&je()}}),s(()=>{window.removeEventListener(`kobo:focus-history-event`,J),q!=null&&(cancelAnimationFrame(q),q=null)}),c(()=>r.workspaceId,()=>{R.value=!0,Re=Q.value>0,V=!1,ze(),Q.value>0&&Z()}),c(()=>v.selectedSessionId,async()=>{R.value=!0,V=!1,ze(),await Z()});let $=new Set;async function ze(){let e=r.workspaceId,t=E.value;if(!t||Q.value>0)return;let n=W(e,t);if(!$.has(n)){$.add(n),H.value.add(n);try{let i=await fetch(`/api/workspaces/${e}/events?session=${encodeURIComponent(t)}&limit=500`);if(!i.ok){$.delete(n);return}let a=await i.json(),s=a.events??[];if(s.length===0)return;let c=s.filter(t=>t.type===`agent:event`&&t.workspaceId===e),l=s.filter(t=>t.type===`user:message`&&t.workspaceId===e),u=c.map(e=>e.payload),f=c.map(e=>e.createdAt),p=c.map(e=>e.sessionId??null),m=c.map(e=>e.id);ye(e,t,a.hasMore),u.length>0&&o.prepend(e,u,f,{oldestId:s[0].id,hasMoreOlder:o.hasMoreOlderFor(e),sessionIds:p,eventIds:m});for(let t of l){let n=t.payload;typeof n.content==`string`&&v.addActivityItem(e,{id:t.id,type:`text`,content:n.content,timestamp:t.createdAt,sessionId:t.sessionId??void 0,meta:{sender:n.sender??`user`}})}await d(),r.workspaceId===e&&E.value===t&&await K(0)}catch(e){console.error(`[ActivityFeed] fetchSessionIfMissing failed:`,e),$.delete(n)}finally{H.value.delete(n)}}}let Be=b(()=>N.value.filter(e=>e.sender!==`system-prompt`).length);c(Be,async(e,t)=>{e>t&&(R.value=!0,await K(180))});async function Ve(){R.value=!0,await K(250)}return(e,t)=>U.value?(l(),x(`div`,ft,[m(le,{size:`40px`,color:`primary`})])):(l(),x(`div`,pt,[C(`div`,{"data-testid":`activity-live-region`,class:`sr-only`,role:`log`,"aria-live":`polite`,"aria-atomic":`true`,"aria-label":e.$t(`activity.a11y.region`)},i(de.value),9,mt),m(O,{name:`fade`},{default:p(()=>[w.value?(l(),x(`div`,ht,[m(le,{size:`18px`,color:`primary`}),C(`span`,gt,i(e.$t(`activity.compacting`)),1)])):g(``,!0)]),_:1}),m(pe,{ref_key:`scrollRef`,ref:L,class:`activity-feed-scroll`,onScroll:he},{default:p(()=>[z.value?(l(),x(`div`,_t,[m(M,{size:`sm`}),_(` `+i(e.$t(`activity.loading_older`)),1)])):g(``,!0),m(Te,{ref_key:`virtualScrollRef`,ref:Pe,class:`q-pa-md`,items:P.value,"scroll-target":Fe.value??void 0,"virtual-scroll-item-size":160,"virtual-scroll-slice-size":20,onVirtualScroll:Ie},{default:p(({item:e,index:t})=>[(l(),h(dt,{key:n(Oe)(e),turn:e,"data-turn-index":t,highlighted:e.items.some(e=>e.eventIds?.includes(B.value??``)??!1),onScrollTo:Me},null,8,[`turn`,`data-turn-index`,`highlighted`]))]),_:1},8,[`items`,`scroll-target`]),P.value.length===0&&F.value.length===0&&!z.value?(l(),x(`div`,vt,[m(k,{name:`forum`,size:`28px`}),C(`div`,yt,i(e.$t(`activity.empty`)),1),C(`div`,bt,i(e.$t(`activity.emptyHint`)),1)])):g(``,!0),F.value.length?(l(),x(`div`,xt,[m(fe,{label:e.$t(`activity.raw_lines`,{n:F.value.length}),dense:``},{default:p(()=>[(l(!0),x(S,null,T(F.value,(e,t)=>(l(),x(`div`,{key:t,class:`text-caption text-kobo-3 q-pa-xs`},i(e),1))),128))]),_:1},8,[`label`])])):g(``,!0)]),_:1},512),C(`div`,St,[R.value?g(``,!0):(l(),h(ee,{key:0,round:``,dense:``,unelevated:``,color:`kobo-surface-2`,"text-color":`kobo-1`,icon:`arrow_downward`,size:`sm`,class:`activity-feed-nav-btn`,title:e.$t(`activity.scroll_to_bottom`),"aria-label":e.$t(`activity.scroll_to_bottom`),onClick:Ve},null,8,[`title`,`aria-label`])),m(ee,{round:``,dense:``,unelevated:``,color:`kobo-surface-2`,"text-color":`kobo-1`,icon:`arrow_upward`,size:`sm`,class:`activity-feed-nav-btn`,title:e.$t(`activity.prev_user_message`),"aria-label":e.$t(`activity.prev_user_message`),loading:X.value,disable:X.value,onClick:Le},null,8,[`title`,`aria-label`,`loading`,`disable`])])]))}}),[[`__scopeId`,`data-v-6611464a`]]);export{Dt as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.pr-picker__list-section[data-v-7f668f35]{max-height:60vh;overflow-y:auto}.pr-picker__item[aria-disabled=true][data-v-7f668f35]{opacity:.5}.create-page[data-v-36b65938]{background:var(--kobo-bg);min-height:100%;padding:48px 24px 80px;position:relative}.create-page__drawer-toggle[data-v-36b65938]{top:var(--kobo-space-md);left:var(--kobo-space-md);z-index:1;position:absolute}.create-page__progress[data-v-36b65938]{align-items:center;gap:var(--kobo-space-sm);color:var(--kobo-text-2);display:flex}.create-page__progress-counter[data-v-36b65938]{font-family:var(--kobo-font-mono);color:var(--kobo-text-3)}.create-page__overrides[data-v-36b65938]{gap:var(--kobo-space-xs);padding:var(--kobo-space-md);border:1px solid var(--kobo-border-subtle);border-radius:var(--kobo-radius-sm);background:var(--kobo-surface-2);flex-direction:column;display:flex}.create-page__overrides-title[data-v-36b65938]{align-items:center;gap:var(--kobo-space-xs);color:var(--kobo-text-2);display:flex}.create-page__overrides-item[data-v-36b65938]{color:var(--kobo-text-3)}.create-inner[data-v-36b65938]{width:100%;max-width:960px}.create-title[data-v-36b65938]{letter-spacing:-.02em;font-size:30px;line-height:1.2}.create-sections[data-v-36b65938]{gap:24px}.responsive-fields[data-v-36b65938]{row-gap:16px}.responsive-fields--sm[data-v-36b65938]{row-gap:8px}.create-section-card[data-v-36b65938],.create-actions-card[data-v-36b65938]{background:var(--kobo-surface);border-color:#ffffff1f}.card-textarea-wrap[data-v-36b65938]{position:relative}.create-textarea[data-v-36b65938] .q-field__control{min-height:220px}.create-textarea[data-v-36b65938] textarea{resize:vertical;line-height:1.6;min-height:180px!important}.create-slash-popup[data-v-36b65938]{z-index:20;position:absolute;top:calc(100% + 4px);left:12px;right:12px}.source-panel[data-v-36b65938]{background:var(--kobo-surface-2);border:1px solid #ffffff1a}.peek-card[data-v-36b65938]{color:var(--kobo-text-2);background:#ffffff06;border-color:#ffffff1a;transition:background .15s,border-color .15s,transform .1s}.peek-card[data-v-36b65938]:hover{background:#ffffff0f;border-color:#818cf880}.peek-card[data-v-36b65938]:active{transform:scale(.99)}.peek-card--active[data-v-36b65938]{border-color:var(--kobo-accent);background:#6366f124;box-shadow:inset 0 0 0 1px #818cf859}.peek-card--active .peek-card-icon[data-v-36b65938]{color:var(--kobo-text-2)}.peek-card-icon[data-v-36b65938]{color:var(--kobo-text-3);flex-shrink:0}.manual-expansion[data-v-36b65938],.advanced-options[data-v-36b65938]{background:var(--kobo-surface-2);border:1px solid #ffffff1a;overflow:hidden}.manual-expansion[data-v-36b65938] .q-expansion-item__content,.advanced-options[data-v-36b65938] .q-expansion-item__content{background:var(--kobo-bg-deep)}.manual-expansion[data-v-36b65938] .q-chip{max-width:100%;height:auto;min-height:32px}.manual-expansion[data-v-36b65938] .q-chip__content{white-space:normal;overflow-wrap:anywhere}.auto-loop-panel[data-v-36b65938]{background:#f59e0b0f;border-top:1px solid #f59e0b38;gap:16px}.auto-loop-session-toggle[data-v-36b65938] .q-btn{min-height:32px;padding-top:4px;padding-bottom:4px}[data-v-36b65938] .agent-config-header{min-height:56px;padding-top:6px;padding-bottom:8px}.agent-summary[data-v-36b65938]{row-gap:4px}.agent-summary[data-v-36b65938] .q-chip{margin:0}.create-actions-card[data-v-36b65938]{z-index:10;position:sticky;bottom:16px;box-shadow:0 10px 36px #00000061}.voice-btn--recording[data-v-36b65938]{animation:1.1s ease-in-out infinite voice-pulse-36b65938}@keyframes voice-pulse-36b65938{0%,to{opacity:1;transform:scale(1)}50%{opacity:.86;transform:scale(1.06)}}.slide-enter-active[data-v-36b65938],.slide-leave-active[data-v-36b65938]{transition:max-height .2s,opacity .2s;overflow:hidden}.slide-enter-from[data-v-36b65938],.slide-leave-to[data-v-36b65938]{opacity:0;max-height:0}.slide-enter-to[data-v-36b65938],.slide-leave-from[data-v-36b65938]{opacity:1;max-height:900px}@media (max-width:599px){.create-page[data-v-36b65938]{padding:28px 12px 56px}.create-title[data-v-36b65938]{font-size:26px}.create-actions-card[data-v-36b65938]{bottom:8px}.create-actions-card[data-v-36b65938] .q-card__section{align-items:stretch}.create-actions[data-v-36b65938]{width:100%}.create-actions .q-btn[data-v-36b65938]:last-child{flex:1}}
|