@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.
Files changed (154) hide show
  1. package/AGENTS.md +101 -32
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +6 -4
  4. package/dist/mcp-server/kobo-tasks-handlers.js +16 -9
  5. package/dist/mcp-server/kobo-tasks-server.js +13 -2
  6. package/dist/mcp-server/workspace-dialogue-client.js +28 -0
  7. package/dist/server/db/mcp-message-schema.js +16 -0
  8. package/dist/server/db/migrations.js +4 -0
  9. package/dist/server/db/schema.js +4 -0
  10. package/dist/server/db/search-schema.js +53 -0
  11. package/dist/server/index.js +17 -86
  12. package/dist/server/middleware/network-auth-middleware.js +5 -1
  13. package/dist/server/routes/changelog.js +4 -49
  14. package/dist/server/routes/git.js +2 -2
  15. package/dist/server/routes/images.js +65 -5
  16. package/dist/server/routes/mcp.js +47 -0
  17. package/dist/server/routes/pull-requests.js +1 -1
  18. package/dist/server/routes/search.js +13 -4
  19. package/dist/server/routes/settings.js +5 -0
  20. package/dist/server/routes/workspaces.js +250 -248
  21. package/dist/server/services/agent/engines/claude-code/engine.js +31 -33
  22. package/dist/server/services/agent/engines/codex/engine.js +37 -8
  23. package/dist/server/services/agent/engines/codex/event-mapper.js +3 -1
  24. package/dist/server/services/agent/engines/codex/options-builder.js +4 -3
  25. package/dist/server/services/agent/engines/codex/server-requests.js +8 -1
  26. package/dist/server/services/agent/orchestrator.js +20 -3
  27. package/dist/server/services/attachment-service.js +122 -0
  28. package/dist/server/services/change-source-branch-service.js +10 -42
  29. package/dist/server/services/chat-receipt-service.js +33 -0
  30. package/dist/server/services/cron-service.js +27 -1
  31. package/dist/server/services/image-service.js +16 -7
  32. package/dist/server/services/mcp-client-context.js +12 -0
  33. package/dist/server/services/mcp-connection-info-service.js +63 -0
  34. package/dist/server/services/mcp-message-delivery-service.js +59 -0
  35. package/dist/server/services/mcp-message-request-service.js +64 -0
  36. package/dist/server/services/pr-checkout-service.js +10 -10
  37. package/dist/server/services/pr-watcher-service.js +14 -9
  38. package/dist/server/services/search/indexer.js +232 -0
  39. package/dist/server/services/search/worker.js +76 -0
  40. package/dist/server/services/search-service.js +104 -110
  41. package/dist/server/services/update-check-service.js +119 -0
  42. package/dist/server/services/websocket-service.js +121 -35
  43. package/dist/server/services/workspace-dialogue-service.js +128 -0
  44. package/dist/server/services/workspace-message-service.js +58 -0
  45. package/dist/server/services/workspace-permission-policy-service.js +33 -3
  46. package/dist/server/services/worktree-restore-service.js +2 -2
  47. package/dist/server/services/worktree-service.js +197 -124
  48. package/dist/server/utils/bounded-process.js +137 -0
  49. package/dist/server/utils/git-ops.js +76 -128
  50. package/dist/server/utils/git-repo-lock.js +27 -13
  51. package/dist/shared/attachments.js +58 -0
  52. package/dist/shared/workspace-dialogue-tools.js +89 -0
  53. package/dist/shared/workspace-message-types.js +19 -0
  54. package/package.json +2 -1
  55. package/src/client/dist/pwa/assets/{ActivityFeed-Chsw1Mh7.css → ActivityFeed-BYR5x7aa.css} +1 -1
  56. package/src/client/dist/pwa/assets/ActivityFeed-DTIe6O9o.js +8 -0
  57. package/src/client/dist/pwa/assets/{ChangelogPage-D8563008.js → ChangelogPage-BWeu0YeI.js} +1 -1
  58. package/src/client/dist/pwa/assets/{ComparisonPanel-Bd0X08sg.js → ComparisonPanel-o_EHlTwV.js} +2 -2
  59. package/src/client/dist/pwa/assets/CreatePage-CGi88k6z.css +1 -0
  60. package/src/client/dist/pwa/assets/CreatePage-DbY5gBv8.js +2 -0
  61. package/src/client/dist/pwa/assets/DashboardPage-CIo_gesD.js +1 -0
  62. package/src/client/dist/pwa/assets/{DiffViewer-DnR79ycb.css → DiffViewer-DEPOa3D7.css} +1 -1
  63. package/src/client/dist/pwa/assets/DiffViewer-DEcf48KI.js +8 -0
  64. package/src/client/dist/pwa/assets/{DocumentsPanel-BJsJ0fNs.js → DocumentsPanel-D9vcB91W.js} +1 -1
  65. package/src/client/dist/pwa/assets/{DrawerToggleButton-BVLO5K5d.js → DrawerToggleButton-Ca0_CxSl.js} +1 -1
  66. package/src/client/dist/pwa/assets/GitPanel-DCmB2R5i.js +3 -0
  67. package/src/client/dist/pwa/assets/{HealthPage-RFZS7Lao.js → HealthPage-_q3vy_xn.js} +1 -1
  68. package/src/client/dist/pwa/assets/MainLayout-Duwnq3cc.js +2 -0
  69. package/src/client/dist/pwa/assets/{QBtnDropdown-X8oNU5Mb.js → QBtnDropdown-BeiZIHVA.js} +1 -1
  70. package/src/client/dist/pwa/assets/{QDrawer-Cij17skX.js → QDrawer-Fj3M9QGD.js} +1 -1
  71. package/src/client/dist/pwa/assets/QSelect-DtSUuK8t.js +1 -0
  72. package/src/client/dist/pwa/assets/{QTooltip-CwcCGSWq.js → QTooltip-DwkX8eQ6.js} +1 -1
  73. package/src/client/dist/pwa/assets/SchedulePanel-BAA4Aajn.css +1 -0
  74. package/src/client/dist/pwa/assets/SchedulePanel-BlZDd7TK.js +1 -0
  75. package/src/client/dist/pwa/assets/SearchPage-BGc1oQSM.css +1 -0
  76. package/src/client/dist/pwa/assets/SearchPage-BGi1yRxU.js +1 -0
  77. package/src/client/dist/pwa/assets/SettingsPage-DnO-ImWE.js +9 -0
  78. package/src/client/dist/pwa/assets/SettingsPage-sVlsJQ0b.css +1 -0
  79. package/src/client/dist/pwa/assets/{SplitWorkspacePage-D7lGFRKs.js → SplitWorkspacePage-vz6jN1DM.js} +1 -1
  80. package/src/client/dist/pwa/assets/{TerminalPanel-DI8DHb9e.js → TerminalPanel-IdPIGp2_.js} +9 -9
  81. package/src/client/dist/pwa/assets/{TouchPan-B3nrkCY8.js → TouchPan-DTJqxVp9.js} +1 -1
  82. package/src/client/dist/pwa/assets/{TourReplayButton-DU1UShMY.js → TourReplayButton-Bj2GGyhU.js} +1 -1
  83. package/src/client/dist/pwa/assets/{WorkspaceAttentionLabels-C-yN5IX8.js → WorkspaceAttentionLabels-BBaGZlwv.js} +1 -1
  84. package/src/client/dist/pwa/assets/WorkspacePage-DCg9zSxz.css +1 -0
  85. package/src/client/dist/pwa/assets/WorkspacePage-Dy0spsfi.js +4 -0
  86. package/src/client/dist/pwa/assets/{browser-f9MHQjfi.js → browser-BFj5wwbS.js} +1 -1
  87. package/src/client/dist/pwa/assets/{build-path-tree-BWBzP8os.js → build-path-tree-C-HSiySk.js} +1 -1
  88. package/src/client/dist/pwa/assets/de-BdLe7apJ.js +17 -0
  89. package/src/client/dist/pwa/assets/{documents-C2cLnEBQ.js → documents-C2Xnjh9Z.js} +1 -1
  90. package/src/client/dist/pwa/assets/{editor.api-sw146MWN.js → editor.api-BbKfnNmv.js} +1 -1
  91. package/src/client/dist/pwa/assets/{efforts-C5ZZgCH4.js → efforts-BM7fdaaL.js} +1 -1
  92. package/src/client/dist/pwa/assets/engineFeatures-b74YRODT.js +1 -0
  93. package/src/client/dist/pwa/assets/es-C1LM-3aq.js +17 -0
  94. package/src/client/dist/pwa/assets/expand-template-DiDWiIkx.js +1 -0
  95. package/src/client/dist/pwa/assets/{format-BwWP6Aay.js → format-CnbUxAmw.js} +1 -1
  96. package/src/client/dist/pwa/assets/{formatters-DyWtO-nR.js → formatters-B2uUIbAY.js} +1 -1
  97. package/src/client/dist/pwa/assets/fr-KCK6r5ga.js +17 -0
  98. package/src/client/dist/pwa/assets/{freemarker2-DZ5Hm8UH.js → freemarker2-Cu1vGY0x.js} +1 -1
  99. package/src/client/dist/pwa/assets/{handlebars-BRUGpTA7.js → handlebars-CETuqLyz.js} +1 -1
  100. package/src/client/dist/pwa/assets/{html-DNOayNNs.js → html-BTNpr39P.js} +1 -1
  101. package/src/client/dist/pwa/assets/i18n-BkUirOzl.js +1 -0
  102. package/src/client/dist/pwa/assets/index-mvh5w1cM.js +20 -0
  103. package/src/client/dist/pwa/assets/it-BM6t0IGU.js +17 -0
  104. package/src/client/dist/pwa/assets/{javascript-C0tDQU3z.js → javascript-C7Ncb6V7.js} +1 -1
  105. package/src/client/dist/pwa/assets/{liquid-CN46O6OF.js → liquid-D0hUdg4x.js} +1 -1
  106. package/src/client/dist/pwa/assets/{mdx-DM-lrr8Q.js → mdx-BK5H1Xst.js} +1 -1
  107. package/src/client/dist/pwa/assets/{monaco-contributions-CkN7y-8c.js → monaco-contributions-BBW6JNgz.js} +1 -1
  108. package/src/client/dist/pwa/assets/{monaco.contribution-2BcAOLjc.js → monaco.contribution-1LZrAlY4.js} +2 -2
  109. package/src/client/dist/pwa/assets/network-auth-CVGS__6a.js +1 -0
  110. package/src/client/dist/pwa/assets/{notify-theme-a91Tcr6o.js → notify-theme-DIKLxr8F.js} +1 -1
  111. package/src/client/dist/pwa/assets/{pending-diff-open-DOtELZfB.js → pending-diff-open-B02zuH1j.js} +1 -1
  112. package/src/client/dist/pwa/assets/{permissionModes-C-9Crj-c.js → permissionModes-C3otN1Vk.js} +1 -1
  113. package/src/client/dist/pwa/assets/{project-color-BRe4oyNx.js → project-color-BUcW_eZA.js} +1 -1
  114. package/src/client/dist/pwa/assets/{python-BRpJG6sZ.js → python-DEeUVvnp.js} +1 -1
  115. package/src/client/dist/pwa/assets/{razor-CehCmvHl.js → razor-CG6cL8ya.js} +1 -1
  116. package/src/client/dist/pwa/assets/{render-chat-markdown-DlbQLZ02.js → render-chat-markdown-Ct_T5TPN.js} +1 -1
  117. package/src/client/dist/pwa/assets/{typescript-Dt_8mVuj.js → typescript-CSQAg5UC.js} +1 -1
  118. package/src/client/dist/pwa/assets/use-search-index-status-DtLzygcy.js +1 -0
  119. package/src/client/dist/pwa/assets/use-tours-_6HwJ_Rp.js +2 -0
  120. package/src/client/dist/pwa/assets/{workspace-templates-GCObcjO6.js → workspace-templates-B8WWsWEI.js} +1 -1
  121. package/src/client/dist/pwa/assets/{xml-_gOwdzB4.js → xml-BSB4-DXR.js} +1 -1
  122. package/src/client/dist/pwa/assets/{yaml-BxeBqpGf.js → yaml-CSGKph85.js} +1 -1
  123. package/src/client/dist/pwa/index.html +1 -1
  124. package/src/client/dist/pwa/sw.js +1 -1
  125. package/src/mcp-server/README.md +169 -9
  126. package/src/mcp-server/kobo-tasks-handlers.ts +14 -11
  127. package/src/mcp-server/kobo-tasks-server.ts +19 -2
  128. package/src/mcp-server/workspace-dialogue-client.ts +34 -0
  129. package/src/client/dist/pwa/assets/ActivityFeed-BzzvcOmq.js +0 -8
  130. package/src/client/dist/pwa/assets/CreatePage-A3pVradx.css +0 -1
  131. package/src/client/dist/pwa/assets/CreatePage-Bon8qIka.js +0 -2
  132. package/src/client/dist/pwa/assets/DashboardPage-DYxdxEul.js +0 -1
  133. package/src/client/dist/pwa/assets/DiffViewer-BpsLNxnj.js +0 -8
  134. package/src/client/dist/pwa/assets/GitPanel-Cal_wzC0.js +0 -3
  135. package/src/client/dist/pwa/assets/MainLayout-vvyiRcql.js +0 -2
  136. package/src/client/dist/pwa/assets/QSelect-xd-AlGo_.js +0 -1
  137. package/src/client/dist/pwa/assets/SchedulePanel-BunlzsOY.css +0 -1
  138. package/src/client/dist/pwa/assets/SchedulePanel-CXRUsz6G.js +0 -1
  139. package/src/client/dist/pwa/assets/SearchPage-CVgRa025.css +0 -1
  140. package/src/client/dist/pwa/assets/SearchPage-DopbgLxh.js +0 -1
  141. package/src/client/dist/pwa/assets/SettingsPage-Do9d0Pov.css +0 -1
  142. package/src/client/dist/pwa/assets/SettingsPage-Jx6TnOzR.js +0 -9
  143. package/src/client/dist/pwa/assets/WorkspacePage-BAC6u9OP.css +0 -1
  144. package/src/client/dist/pwa/assets/WorkspacePage-DKRpdpPg.js +0 -4
  145. package/src/client/dist/pwa/assets/de-QkDLrcGq.js +0 -17
  146. package/src/client/dist/pwa/assets/engineFeatures-CAVMDawq.js +0 -1
  147. package/src/client/dist/pwa/assets/es-BgQFKlo8.js +0 -17
  148. package/src/client/dist/pwa/assets/expand-template-B6xAlAaM.js +0 -1
  149. package/src/client/dist/pwa/assets/fr-DAdLWjNM.js +0 -17
  150. package/src/client/dist/pwa/assets/i18n-CBez_vip.js +0 -1
  151. package/src/client/dist/pwa/assets/index-VL3fI9a3.js +0 -20
  152. package/src/client/dist/pwa/assets/it-Bumaewp1.js +0 -17
  153. package/src/client/dist/pwa/assets/network-auth-KYS4snQH.js +0 -1
  154. 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$/]}))});
@@ -1,22 +1,179 @@
1
1
  # Kōbō Tasks MCP Server
2
2
 
3
- Standalone MCP (Model Context Protocol) server spawned by Kōbō for each Claude Code 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.
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
- Kōbō's Claude Code engine (under `src/server/services/agent/engines/claude-code/`) writes a `.mcp.json` file into each worktree and passes it to Claude Code via `--mcp-config`. Claude spawns this server as a child process with stdio transport and injects these environment variables:
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 all queries. Optional: when unset, the server runs in "global" mode (see [Global tools](#global-tools-workspace-less-mode) below) and only exposes the workspace-management tools; workspace-scoped tools are omitted from the tool list entirely. |
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 read-only queries, writes directly for task CRUD, and calls the backend HTTP API for anything that touches runtime processes (dev server) or state transitions requiring validation.
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
- Check whether the dev server is running for the current workspace. Reads `dev_server_status` from the DB.
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:** `{ workspaceId, status }`
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 Claude Code session that Kōbō did NOT spawn (e.g. a standalone terminal session) discover and manage workspaces instead of being bound to one.
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
- Force-stop the currently running agent session on a workspace, like the red "Arrêter" button in the chat header. Requires the backend to be running. Safe to call when nothing is running.
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(worktreePath, '.ai', 'thoughts', 'logs')
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
- fs.writeFileSync(abs, header + content + (content.endsWith('\n') ? '' : '\n'), 'utf-8')
622
-
623
- return { path: relPath }
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 init: RequestInit = { method }
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
- init.headers = { 'Content-Type': 'application/json' }
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)?`![${r}](${`/api/workspaces/${encodeURIComponent(t)}/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}}