openmausbot 0.1.98 → 0.1.99

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 (396) hide show
  1. package/dist/assets/{ActivityPanel-H6D3SD39.js → ActivityPanel-CgUgtumZ.js} +1 -1
  2. package/dist/assets/BotSettingsDialog-lJj6oiir.js +7 -0
  3. package/dist/assets/{CloudBackendPicker-iezpJFpF.js → CloudBackendPicker-C5-_arUz.js} +1 -1
  4. package/dist/assets/{ComputerPanel-DZPj-IWu.js → ComputerPanel-euJ2CSlH.js} +1 -1
  5. package/dist/assets/{DesktopViewer-utONms1p.js → DesktopViewer-XCln1Pn_.js} +1 -1
  6. package/dist/assets/InspectorPanel-DKYyQZlo.js +5 -0
  7. package/dist/assets/{KeyboardShortcutsModal-gk9mvHj_.js → KeyboardShortcutsModal-DkkZWZRI.js} +1 -1
  8. package/dist/assets/{LocalVmWorkspace-DLIvd2kC.js → LocalVmWorkspace-Cwt3_XSx.js} +1 -1
  9. package/dist/assets/{MacLocalControl-bJv8yiPB.js → MacLocalControl-B28RbdCS.js} +1 -1
  10. package/dist/assets/NewBotDialog-dMWDs5xm.js +2 -0
  11. package/dist/assets/RemoteAgentSettingsPanel-B5KWXnqH.js +1 -0
  12. package/dist/assets/RoutinesPage-DOosRYDK.js +1 -0
  13. package/dist/assets/{RoutinesSection-Dny9ra-c.js → RoutinesSection-uOfOTfkB.js} +1 -1
  14. package/dist/assets/{SettingsModal-gC6XJJmt.js → SettingsModal-BTGkFbj1.js} +3 -3
  15. package/dist/assets/{TeamMapPage-B6fuu4r_.js → TeamMapPage-DqNdJn96.js} +1 -1
  16. package/dist/assets/{TriggersPanel-j0qTP2CO.js → TriggersPanel-c6xkG9mi.js} +1 -1
  17. package/dist/assets/{VisibilitySection-DT0FqPvu.js → VisibilitySection-DD4ffIR5.js} +1 -1
  18. package/dist/assets/WebhooksPanel-Cz17K-_O.js +3 -0
  19. package/dist/assets/{abnfDiagram-O67JEVCF-BsjcFX0-.js → abnfDiagram-O67JEVCF-CX6tDpkg.js} +1 -1
  20. package/dist/assets/{activity-BxOkayvD.js → activity-BAVWO0Zj.js} +1 -1
  21. package/dist/assets/{arc-CJNA94c6.js → arc-h45-9NFk.js} +1 -1
  22. package/dist/assets/{architectureDiagram-NJMV4G6O-dz2ud7lP.js → architectureDiagram-NJMV4G6O-CgLFXbg6.js} +1 -1
  23. package/dist/assets/{blockDiagram-BEXU5L5S-ChBEALoR.js → blockDiagram-BEXU5L5S-DGDFFc9M.js} +1 -1
  24. package/dist/assets/{brain-CFZ7PEXc.js → brain-CeCdoTb2.js} +1 -1
  25. package/dist/assets/{c4Diagram-YGBWAQC7-KZNRKDQe.js → c4Diagram-YGBWAQC7-B9aklAUj.js} +1 -1
  26. package/dist/assets/channel-TsOXCiPg.js +1 -0
  27. package/dist/assets/{chunk-2Q5K7J3B-BLLwmCET.js → chunk-2Q5K7J3B-BC0KmWsM.js} +1 -1
  28. package/dist/assets/{chunk-3FUC2YCW-CQxyreBZ.js → chunk-3FUC2YCW-BbDFHsJ1.js} +2 -2
  29. package/dist/assets/{chunk-5VM5RSS4-D6sFMW0u.js → chunk-5VM5RSS4-DtGbsjOM.js} +1 -1
  30. package/dist/assets/{chunk-GTNCS2PH-BaZ1YgLF.js → chunk-GTNCS2PH-VMghMcEl.js} +1 -1
  31. package/dist/assets/{chunk-GWA4HPMP-CcalphmC.js → chunk-GWA4HPMP-BP_JyGWQ.js} +1 -1
  32. package/dist/assets/{chunk-JWPE2WC7-CSk8R3ve.js → chunk-JWPE2WC7-CYFyzgAU.js} +1 -1
  33. package/dist/assets/{chunk-NETBCI7D-CTmLjA57.js → chunk-NETBCI7D-DBNa_kqm.js} +1 -1
  34. package/dist/assets/{chunk-WEXAMYUT-CM9Z77Ne.js → chunk-WEXAMYUT-BKEeM7CJ.js} +1 -1
  35. package/dist/assets/{chunk-XXDRQBXY-B1fxpMS2.js → chunk-XXDRQBXY-C__m3ZXl.js} +1 -1
  36. package/dist/assets/{classDiagram-v2-NBCMYWYE-DCCyoLpj.js → classDiagram-v2-NBCMYWYE-CBUrTSAX.js} +1 -1
  37. package/dist/assets/core-6lvx-ypA.js +12 -0
  38. package/dist/assets/{cose-bilkent-JH36ORCC-KyImBKvE.js → cose-bilkent-JH36ORCC-GRfL-1Vb.js} +1 -1
  39. package/dist/assets/cpp-DddhVWhK.js +1 -0
  40. package/dist/assets/{cynefin-OW5HDTMX-fsZc6MGa.js → cynefin-OW5HDTMX-LopwGUjm.js} +1 -1
  41. package/dist/assets/{cynefinDiagram-VND7K2PF-CGmHsShB.js → cynefinDiagram-VND7K2PF-DSB8ZRNS.js} +1 -1
  42. package/dist/assets/{dagre-6A5THRUB-Dah1h-CH.js → dagre-6A5THRUB-DL3Kgdfk.js} +1 -1
  43. package/dist/assets/{diagram-22UHCM2B-BIu71OyV.js → diagram-22UHCM2B-DIxN34BM.js} +1 -1
  44. package/dist/assets/{diagram-3UASUU5V-gxhUB_Mu.js → diagram-3UASUU5V-CJnSvXaI.js} +1 -1
  45. package/dist/assets/{diagram-ATOU4E4O-CBhusUBn.js → diagram-ATOU4E4O-C-XF-lO8.js} +1 -1
  46. package/dist/assets/{diagram-CDSNMT55-BdPrc86x.js → diagram-CDSNMT55-Df2yZPi_.js} +1 -1
  47. package/dist/assets/{diagram-MLGK6HIB-Clp110R_.js → diagram-MLGK6HIB-BBs9oZFs.js} +1 -1
  48. package/dist/assets/{diagram-MPIPVDR6-DJKfbugw.js → diagram-MPIPVDR6-CEbK11mM.js} +1 -1
  49. package/dist/assets/{ebnfDiagram-ZINNZB2B-DnsltoBu.js → ebnfDiagram-ZINNZB2B-BNq6Yv3C.js} +1 -1
  50. package/dist/assets/{elk-276RUBZZ-jWdq6gqH.js → elk-276RUBZZ-CFbQ2bGm.js} +1 -1
  51. package/dist/assets/engine-javascript-D5Xfc425.js +141 -0
  52. package/dist/assets/{erDiagram-OPXOYQCR-DArPVf8u.js → erDiagram-OPXOYQCR-Bz8vmjN4.js} +1 -1
  53. package/dist/assets/{flowDiagram-KWPJA3E3-D2HZ-2f7.js → flowDiagram-KWPJA3E3-cQUfEYrx.js} +1 -1
  54. package/dist/assets/{ganttDiagram-FUAMR5RP--o0KIxEo.js → ganttDiagram-FUAMR5RP-BY8n9tbI.js} +1 -1
  55. package/dist/assets/{gitGraphDiagram-X574FWY7-CsoXr2D7.js → gitGraphDiagram-X574FWY7-KduSOMDN.js} +1 -1
  56. package/dist/assets/{image-plus-BbVjGHin.js → image-plus-DNIWU160.js} +1 -1
  57. package/dist/assets/{index-C3NqfdVU.js → index-C8xb62XS.js} +205 -205
  58. package/dist/assets/{index-BrPW5HDO.css → index-DbN_Hfjs.css} +1 -1
  59. package/dist/assets/{infoDiagram-VRGFBTTK-g-6lNp7r.js → infoDiagram-VRGFBTTK-xBKgUkpL.js} +1 -1
  60. package/dist/assets/{ishikawaDiagram-OU5B5YK6-B1d6qVTV.js → ishikawaDiagram-OU5B5YK6-_ei09tAJ.js} +1 -1
  61. package/dist/assets/{journeyDiagram-ZHPQQLJL-BTPuiU6T.js → journeyDiagram-ZHPQQLJL-Fp49MkSp.js} +1 -1
  62. package/dist/assets/{kanban-definition-PNTS6WVX-bDDuRJvP.js → kanban-definition-PNTS6WVX-CY9lLm7V.js} +1 -1
  63. package/dist/assets/{linear-BVVKbEMy.js → linear-D2ai4eM2.js} +1 -1
  64. package/dist/assets/{mermaid.core-JJdoKyKB.js → mermaid.core-DP6qPqu1.js} +5 -5
  65. package/dist/assets/{mindmap-definition-NLK3R4M7-B4aE3T0q.js → mindmap-definition-NLK3R4M7-g1ynEw_d.js} +1 -1
  66. package/dist/assets/{page-visible-BBo_Zm8g.js → page-visible-BZn8304W.js} +1 -1
  67. package/dist/assets/{pegDiagram-GJSIUBJH-DFKQWpR7.js → pegDiagram-GJSIUBJH-Bt4ObsZj.js} +1 -1
  68. package/dist/assets/{pieDiagram-5QR66LMP-Iv7OKVJi.js → pieDiagram-5QR66LMP-CeLld8bY.js} +1 -1
  69. package/dist/assets/{quadrantDiagram-O4NWA36T-U2YnfwBk.js → quadrantDiagram-O4NWA36T-D4WWZw3x.js} +1 -1
  70. package/dist/assets/{railroadDiagram-XR7U4H2S-CuPy6RqM.js → railroadDiagram-XR7U4H2S-D95P5NqU.js} +1 -1
  71. package/dist/assets/{remote-desktop-panel-BNEj7tUx.js → remote-desktop-panel-DOIMmT4T.js} +1 -1
  72. package/dist/assets/{requirementDiagram-PLB6GJNP-bMI5AK7T.js → requirementDiagram-PLB6GJNP-D12p3RhR.js} +1 -1
  73. package/dist/assets/ruby-Ct1eTYOr.js +1 -0
  74. package/dist/assets/{sankeyDiagram-IPEJSGJF-BKcFE2WQ.js → sankeyDiagram-IPEJSGJF-Co26Dwcs.js} +1 -1
  75. package/dist/assets/{sequenceDiagram-PO4LG4MO-Bn9q88kl.js → sequenceDiagram-PO4LG4MO-y5YxaDKt.js} +1 -1
  76. package/dist/assets/{sizeCapture-INFHLROL-Cvmdq9HD.js → sizeCapture-INFHLROL-D49hZ8U5.js} +1 -1
  77. package/dist/assets/{stateDiagram-v2-GCMORJYK-JJQYw3eQ.js → stateDiagram-v2-GCMORJYK-C0sylr-r.js} +1 -1
  78. package/dist/assets/{swimlanes-2SLR337P-BkSCBEwp.js → swimlanes-2SLR337P-DmRWsDIs.js} +1 -1
  79. package/dist/assets/swimlanesDiagram-TC7HE7FX-DzhbBHtd.js +8 -0
  80. package/dist/assets/{timeline-definition-EJHVYXUP-DsaM4GHr.js → timeline-definition-EJHVYXUP-DVmHYs3w.js} +1 -1
  81. package/dist/assets/{usecaseDiagram-POWQR4AR-3FOwLq7B.js → usecaseDiagram-POWQR4AR-BQ1q0VV6.js} +1 -1
  82. package/dist/assets/{user-DcZBnAuv.js → user-B9lohN4n.js} +1 -1
  83. package/dist/assets/{vennDiagram-UO4OBE2U-DyNjJsKt.js → vennDiagram-UO4OBE2U-C_cnfST0.js} +1 -1
  84. package/dist/assets/{wardleyDiagram-VNRHLVJA-Y4ZMcnBC.js → wardleyDiagram-VNRHLVJA-Bb3BSu12.js} +1 -1
  85. package/dist/assets/{xychartDiagram-PMCCYNJV-BXZpg955.js → xychartDiagram-PMCCYNJV-CcwEuuEi.js} +1 -1
  86. package/dist/index.html +2 -2
  87. package/dist-server/drivers/agents-proxy.js +10 -9
  88. package/dist-server/index.js +1474 -807
  89. package/dist-server/openmausbot.js +248 -152
  90. package/dist-server/pair-cli.js +248 -152
  91. package/dist-server/server/activity.js +2 -0
  92. package/dist-server/server/checkpoints.js +55 -39
  93. package/dist-server/server/direct-apply.js +20 -0
  94. package/dist-server/server/drivers/agents-call.js +1 -1
  95. package/dist-server/server/drivers/agents-catalog.js +11 -8
  96. package/dist-server/server/drivers/codex.js +147 -24
  97. package/dist-server/server/drivers/device-auth.js +5 -4
  98. package/dist-server/server/drivers/openai-chat.js +5 -4
  99. package/dist-server/server/harness/registry.js +63 -45
  100. package/dist-server/server/index.js +203 -23
  101. package/dist-server/server/mcp-oauth.js +125 -47
  102. package/dist-server/server/message-file.js +95 -3
  103. package/dist-server/server/model-requests.js +55 -4
  104. package/dist-server/server/profile-requests.js +80 -4
  105. package/dist-server/server/request-auth.js +1 -0
  106. package/dist-server/server/routes/undo.js +17 -0
  107. package/dist-server/server/routine-requests.js +210 -6
  108. package/dist-server/server/setup-mode.js +1 -1
  109. package/dist-server/server/skill-learn.js +2 -2
  110. package/dist-server/server/skills.js +30 -0
  111. package/dist-server/server/system-prompt.js +1 -1
  112. package/dist-server/server/turn-continuation.js +13 -18
  113. package/dist-server/server/workspace-backup.js +6 -1
  114. package/dist-server/workspace-backup.worker.js +1 -1
  115. package/package.json +1 -1
  116. package/skills/create-verification-skill/SKILL.md +9 -8
  117. package/skills/create-verification-skill/manifest.json +1 -1
  118. package/dist/assets/BotSettingsDialog-Dqz_AiBZ.js +0 -7
  119. package/dist/assets/InspectorPanel-OVaBVrzC.js +0 -5
  120. package/dist/assets/NewBotDialog-1qGOAdUM.js +0 -2
  121. package/dist/assets/RemoteAgentSettingsPanel-DqKr0HkO.js +0 -1
  122. package/dist/assets/RoutinesPage-BM2D4qGi.js +0 -1
  123. package/dist/assets/WebhooksPanel--YQyCjKO.js +0 -3
  124. package/dist/assets/abap-BdImnpbu.js +0 -1
  125. package/dist/assets/actionscript-3-B3316cI-.js +0 -1
  126. package/dist/assets/ada-bCR0ucgS.js +0 -1
  127. package/dist/assets/ahk-CsyLZFj1.js +0 -1
  128. package/dist/assets/ahk2-8Zs4aa1G.js +0 -1
  129. package/dist/assets/andromeeda-C4gqWexZ.js +0 -1
  130. package/dist/assets/angular-html-DA-rfuFy.js +0 -1
  131. package/dist/assets/angular-ts-BrjP3tb8.js +0 -1
  132. package/dist/assets/apache-Pmp26Uib.js +0 -1
  133. package/dist/assets/apex-DhZFqWV2.js +0 -1
  134. package/dist/assets/apl-CORt7UWP.js +0 -1
  135. package/dist/assets/applescript-Co6uUVPk.js +0 -1
  136. package/dist/assets/ara-BRHolxvo.js +0 -1
  137. package/dist/assets/asciidoc-CSVQ5wI8.js +0 -1
  138. package/dist/assets/asm-D_Q5rh1f.js +0 -1
  139. package/dist/assets/astro-HNnZUWAn.js +0 -1
  140. package/dist/assets/aurora-x-D-2ljcwZ.js +0 -1
  141. package/dist/assets/awk-DMzUqQB5.js +0 -1
  142. package/dist/assets/ayu-dark-DYE7WIF3.js +0 -1
  143. package/dist/assets/ayu-light-BA47KaF1.js +0 -1
  144. package/dist/assets/ayu-mirage-32ctXXKs.js +0 -1
  145. package/dist/assets/ballerina-BFfxhgS-.js +0 -1
  146. package/dist/assets/bat-CickPsom.js +0 -1
  147. package/dist/assets/beancount-k_qm7-4y.js +0 -1
  148. package/dist/assets/berry-uYugtg8r.js +0 -1
  149. package/dist/assets/bibtex-CHM0blh-.js +0 -1
  150. package/dist/assets/bicep-Bmn6On1c.js +0 -1
  151. package/dist/assets/bird2-Bx8U0n9b.js +0 -1
  152. package/dist/assets/blade-2xfisSek.js +0 -1
  153. package/dist/assets/bsl-DlhNcFeZ.js +0 -1
  154. package/dist/assets/c3-Dp5svz6Z.js +0 -1
  155. package/dist/assets/cadence-Bv_4Rxtq.js +0 -1
  156. package/dist/assets/cairo-KRGpt6FW.js +0 -1
  157. package/dist/assets/catppuccin-frappe-CZL1YF0i.js +0 -1
  158. package/dist/assets/catppuccin-latte-DH-8KZSZ.js +0 -1
  159. package/dist/assets/catppuccin-macchiato-B7yYVSCf.js +0 -1
  160. package/dist/assets/catppuccin-mocha-Ct7hS0mc.js +0 -1
  161. package/dist/assets/channel-WhFyujhZ.js +0 -1
  162. package/dist/assets/chapel-DTp_pixX.js +0 -1
  163. package/dist/assets/clarity-Dn5IMItf.js +0 -1
  164. package/dist/assets/clojure-P80f7IUj.js +0 -1
  165. package/dist/assets/cmake-D1j8_8rp.js +0 -1
  166. package/dist/assets/cobol-nBiQ_Alo.js +0 -1
  167. package/dist/assets/codeowners-Bp6g37R7.js +0 -1
  168. package/dist/assets/codeql-DsOJ9woJ.js +0 -1
  169. package/dist/assets/coffee-Ch7k5sss.js +0 -1
  170. package/dist/assets/common-lisp-Cg-RD9OK.js +0 -1
  171. package/dist/assets/coq-C7JzOVbR.js +0 -1
  172. package/dist/assets/cpp-BMRokrvK.js +0 -1
  173. package/dist/assets/crystal-DGywbUpC.js +0 -1
  174. package/dist/assets/csv-fuZLfV_i.js +0 -1
  175. package/dist/assets/cue-D82EKSYY.js +0 -1
  176. package/dist/assets/cypher-COkxafJQ.js +0 -1
  177. package/dist/assets/d-85-TOEBH.js +0 -1
  178. package/dist/assets/dark-plus-C3mMm8J8.js +0 -1
  179. package/dist/assets/dax-CEL-wOlO.js +0 -1
  180. package/dist/assets/desktop-BmXAJ9_W.js +0 -1
  181. package/dist/assets/dotenv-Da5cRb03.js +0 -1
  182. package/dist/assets/dracula-BzJJZx-M.js +0 -1
  183. package/dist/assets/dracula-soft-BXkSAIEj.js +0 -1
  184. package/dist/assets/dream-maker-BtqSS_iP.js +0 -1
  185. package/dist/assets/edge-FbVlp4U3.js +0 -1
  186. package/dist/assets/elixir-CkH2-t6x.js +0 -1
  187. package/dist/assets/elm-DbKCFpqz.js +0 -1
  188. package/dist/assets/emacs-lisp-C_m_b--Z.js +0 -1
  189. package/dist/assets/erb-DXfck5VN.js +0 -1
  190. package/dist/assets/erlang-DsQrWhSR.js +0 -1
  191. package/dist/assets/everforest-dark-BgDCqdQA.js +0 -1
  192. package/dist/assets/everforest-light-C8M2exoo.js +0 -1
  193. package/dist/assets/fennel-BYunw83y.js +0 -1
  194. package/dist/assets/fluent-C4IJs8-o.js +0 -1
  195. package/dist/assets/fortran-fixed-form-CkoXwp7k.js +0 -1
  196. package/dist/assets/fortran-free-form-BxgE0vQu.js +0 -1
  197. package/dist/assets/fsharp-CXgrBDvD.js +0 -1
  198. package/dist/assets/gdresource-TyuKm33G.js +0 -1
  199. package/dist/assets/gdscript-DqcFQ5yU.js +0 -1
  200. package/dist/assets/gdshader-DkwncUOv.js +0 -1
  201. package/dist/assets/genie-D0YGMca9.js +0 -1
  202. package/dist/assets/gherkin-DyxjwDmM.js +0 -1
  203. package/dist/assets/git-commit-F4YmCXRG.js +0 -1
  204. package/dist/assets/git-rebase-r7XF79zn.js +0 -1
  205. package/dist/assets/github-dark-DHJKELXO.js +0 -1
  206. package/dist/assets/github-dark-dimmed-DH5Ifo-i.js +0 -1
  207. package/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -1
  208. package/dist/assets/github-light-DAi9KRSo.js +0 -1
  209. package/dist/assets/github-light-high-contrast-BfjtVDDH.js +0 -1
  210. package/dist/assets/gleam-BspZqrRM.js +0 -1
  211. package/dist/assets/glimmer-js-ByusRIyA.js +0 -1
  212. package/dist/assets/glimmer-ts-BfAWNZQY.js +0 -1
  213. package/dist/assets/glsl-DplSGwfg.js +0 -1
  214. package/dist/assets/gn-n2N0HUVH.js +0 -1
  215. package/dist/assets/gnuplot-DdkO51Og.js +0 -1
  216. package/dist/assets/groovy-gcz8RCvz.js +0 -1
  217. package/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -1
  218. package/dist/assets/gruvbox-dark-medium-GsRaNv29.js +0 -1
  219. package/dist/assets/gruvbox-dark-soft-CVdnzihN.js +0 -1
  220. package/dist/assets/gruvbox-light-hard-CH1njM8p.js +0 -1
  221. package/dist/assets/gruvbox-light-medium-DRw_LuNl.js +0 -1
  222. package/dist/assets/gruvbox-light-soft-hJgmCMqR.js +0 -1
  223. package/dist/assets/hack-BWmVpMyf.js +0 -1
  224. package/dist/assets/haml-D5jkg6IW.js +0 -1
  225. package/dist/assets/handlebars-BpdQsYii.js +0 -1
  226. package/dist/assets/haskell-Df6bDoY_.js +0 -1
  227. package/dist/assets/haxe-CfZj7gIn.js +0 -1
  228. package/dist/assets/hcl-BWvSN4gD.js +0 -1
  229. package/dist/assets/hjson-D5-asLiD.js +0 -1
  230. package/dist/assets/hlsl-D3lLCCz7.js +0 -1
  231. package/dist/assets/horizon-BUw7H-hv.js +0 -1
  232. package/dist/assets/horizon-bright-CUuTKBJd.js +0 -1
  233. package/dist/assets/houston-DnULxvSX.js +0 -1
  234. package/dist/assets/html-derivative-DlHx6ybY.js +0 -1
  235. package/dist/assets/http-jrhK8wxY.js +0 -1
  236. package/dist/assets/hurl-irOxFIW8.js +0 -1
  237. package/dist/assets/hxml-2-FPmUDs.js +0 -1
  238. package/dist/assets/hy-DFXneXwc.js +0 -1
  239. package/dist/assets/imba-DGztddWO.js +0 -1
  240. package/dist/assets/index-CJTp9JEp.js +0 -153
  241. package/dist/assets/ini-BEwlwnbL.js +0 -1
  242. package/dist/assets/jinja-f2NsQr07.js +0 -1
  243. package/dist/assets/jison-wvAkD_A8.js +0 -1
  244. package/dist/assets/jsonl-DcaNXYhu.js +0 -1
  245. package/dist/assets/jsonnet-DFQXde-d.js +0 -1
  246. package/dist/assets/jssm-C2t-YnRu.js +0 -1
  247. package/dist/assets/julia-5Bft2YPA.js +0 -1
  248. package/dist/assets/just-Cwhn7H3k.js +0 -1
  249. package/dist/assets/kanagawa-dragon-BuwD2xS4.js +0 -1
  250. package/dist/assets/kanagawa-lotus-C3DzagqV.js +0 -1
  251. package/dist/assets/kanagawa-wave-DFGoQZhC.js +0 -1
  252. package/dist/assets/kdl-DV7GczEv.js +0 -1
  253. package/dist/assets/kusto-wEQ09or8.js +0 -1
  254. package/dist/assets/laserwave-DUszq2jm.js +0 -1
  255. package/dist/assets/latex-D5pSuvFb.js +0 -1
  256. package/dist/assets/lean-BZvkOJ9d.js +0 -1
  257. package/dist/assets/light-plus-B7mTdjB0.js +0 -1
  258. package/dist/assets/liquid-C0sCDyMI.js +0 -1
  259. package/dist/assets/llvm-BZoOZj88.js +0 -1
  260. package/dist/assets/log-2UxHyX5q.js +0 -1
  261. package/dist/assets/logo-BtOb2qkB.js +0 -1
  262. package/dist/assets/luau-BnpPk5vE.js +0 -1
  263. package/dist/assets/marko-DjSrsDqO.js +0 -1
  264. package/dist/assets/material-theme-D5KoaKCx.js +0 -1
  265. package/dist/assets/material-theme-darker-BfHTSMKl.js +0 -1
  266. package/dist/assets/material-theme-lighter-B0m2ddpp.js +0 -1
  267. package/dist/assets/material-theme-ocean-CyktbL80.js +0 -1
  268. package/dist/assets/material-theme-palenight-Csfq5Kiy.js +0 -1
  269. package/dist/assets/matlab-D7o27uSR.js +0 -1
  270. package/dist/assets/mdc-D1_yUvq7.js +0 -1
  271. package/dist/assets/mermaid-CQcHuHx7.js +0 -1
  272. package/dist/assets/min-dark-CafNBF8u.js +0 -1
  273. package/dist/assets/min-light-CTRr51gU.js +0 -1
  274. package/dist/assets/mipsasm-CKIfxQSi.js +0 -1
  275. package/dist/assets/mojo-DJz3ZmWd.js +0 -1
  276. package/dist/assets/monokai-BRVnQi9A.js +0 -1
  277. package/dist/assets/moonbit-CHtswR0a.js +0 -1
  278. package/dist/assets/move-el3G9tDJ.js +0 -1
  279. package/dist/assets/narrat-DRg8JJMk.js +0 -1
  280. package/dist/assets/nextflow-C-mBbutL.js +0 -1
  281. package/dist/assets/nextflow-groovy-vE_lwT2v.js +0 -1
  282. package/dist/assets/nginx-BpAMiNFr.js +0 -1
  283. package/dist/assets/night-owl-C39BiMTA.js +0 -1
  284. package/dist/assets/night-owl-light-CMTm3GFP.js +0 -1
  285. package/dist/assets/nim-BIad80T-.js +0 -1
  286. package/dist/assets/nix-CwoSXNpI.js +0 -1
  287. package/dist/assets/nord-Ddv68eIx.js +0 -1
  288. package/dist/assets/nsis-BlV79W_Q.js +0 -1
  289. package/dist/assets/nushell-D3jzshHO.js +0 -1
  290. package/dist/assets/objective-c-DXmwc3jG.js +0 -1
  291. package/dist/assets/objective-cpp-CLxacb5B.js +0 -1
  292. package/dist/assets/ocaml-C0hk2d4L.js +0 -1
  293. package/dist/assets/odin-BBf5iR-q.js +0 -1
  294. package/dist/assets/one-dark-pro-DVMEJ2y_.js +0 -1
  295. package/dist/assets/one-light-C3Wv6jpd.js +0 -1
  296. package/dist/assets/openscad-C4EeE6gA.js +0 -1
  297. package/dist/assets/org-DM6o9KBp.js +0 -1
  298. package/dist/assets/pascal-D93ZcfNL.js +0 -1
  299. package/dist/assets/perl-B9cMNwum.js +0 -1
  300. package/dist/assets/pkl-u5AG7uiY.js +0 -1
  301. package/dist/assets/plastic-3e1v2bzS.js +0 -1
  302. package/dist/assets/plsql-ChMvpjG-.js +0 -1
  303. package/dist/assets/po-BTJTHyun.js +0 -1
  304. package/dist/assets/poimandres-CS3Unz2-.js +0 -1
  305. package/dist/assets/polar-C0HS_06l.js +0 -1
  306. package/dist/assets/postcss-CXtECtnM.js +0 -1
  307. package/dist/assets/powerquery-CEu0bR-o.js +0 -1
  308. package/dist/assets/prisma-Vru482bI.js +0 -1
  309. package/dist/assets/prolog-CbFg5uaA.js +0 -1
  310. package/dist/assets/pug-DKIMFp6K.js +0 -1
  311. package/dist/assets/puppet-BMWR74SV.js +0 -1
  312. package/dist/assets/purescript-CklMAg4u.js +0 -1
  313. package/dist/assets/qml-3beO22l8.js +0 -1
  314. package/dist/assets/qmldir-C8lEn-DE.js +0 -1
  315. package/dist/assets/qss-IeuSbFQv.js +0 -1
  316. package/dist/assets/racket-BqYA7rlc.js +0 -1
  317. package/dist/assets/raku-DXvB9xmW.js +0 -1
  318. package/dist/assets/razor-BjBPvh-w.js +0 -1
  319. package/dist/assets/rbs-CpoqiR4B.js +0 -1
  320. package/dist/assets/red-hvxz__6c.js +0 -1
  321. package/dist/assets/reg-C-SQnVFl.js +0 -1
  322. package/dist/assets/regexp-CDVJQ6XC.js +0 -1
  323. package/dist/assets/rel-C3B-1QV4.js +0 -1
  324. package/dist/assets/riscv-BM1_JUlF.js +0 -1
  325. package/dist/assets/ron-D8l8udqQ.js +0 -1
  326. package/dist/assets/rose-pine-5qJOZa0Y.js +0 -1
  327. package/dist/assets/rose-pine-dawn-zx0QlTCp.js +0 -1
  328. package/dist/assets/rose-pine-moon-C9pEdX9L.js +0 -1
  329. package/dist/assets/rosmsg-BJDFO7_C.js +0 -1
  330. package/dist/assets/rst-bs7f0vWN.js +0 -1
  331. package/dist/assets/ruby-C0TQ7zu5.js +0 -1
  332. package/dist/assets/sas-DEy46yEz.js +0 -1
  333. package/dist/assets/scala-CqE71os6.js +0 -1
  334. package/dist/assets/scheme-C98Dy4si.js +0 -1
  335. package/dist/assets/sdbl-DVxCFoDh.js +0 -1
  336. package/dist/assets/shaderlab-Dg9Lc6iA.js +0 -1
  337. package/dist/assets/shellsession-BADoaaVG.js +0 -1
  338. package/dist/assets/slack-dark-BthQWCQV.js +0 -1
  339. package/dist/assets/slack-ochin-DqwNpetd.js +0 -1
  340. package/dist/assets/smalltalk-BOQMe2GC.js +0 -1
  341. package/dist/assets/smithy-cds9vsN8.js +0 -1
  342. package/dist/assets/snazzy-light-Bw305WKR.js +0 -1
  343. package/dist/assets/solarized-dark-CpvCGNkr.js +0 -1
  344. package/dist/assets/solarized-light-Dlz6yCKv.js +0 -1
  345. package/dist/assets/solidity-DijEV5ha.js +0 -1
  346. package/dist/assets/soy-8wufbnw4.js +0 -1
  347. package/dist/assets/sparql-rVzFXLq3.js +0 -1
  348. package/dist/assets/splunk-BtCnVYZw.js +0 -1
  349. package/dist/assets/ssh-config-_ykCGR6B.js +0 -1
  350. package/dist/assets/stata-DI20mbqo.js +0 -1
  351. package/dist/assets/stylus-BEDo0Tqx.js +0 -1
  352. package/dist/assets/surrealql-Cjom0U5J.js +0 -1
  353. package/dist/assets/svelte-Cy7k_4gC.js +0 -1
  354. package/dist/assets/swimlanesDiagram-TC7HE7FX-CmTirbVT.js +0 -8
  355. package/dist/assets/synthwave-84-CbfX1IO0.js +0 -1
  356. package/dist/assets/system-verilog-0hqHdDBg.js +0 -1
  357. package/dist/assets/systemd-4A_iFExJ.js +0 -1
  358. package/dist/assets/talonscript-CkByrt1z.js +0 -1
  359. package/dist/assets/tasl-QIJgUcNo.js +0 -1
  360. package/dist/assets/tcl-dwOrl1Do.js +0 -1
  361. package/dist/assets/templ-DhtptRzy.js +0 -1
  362. package/dist/assets/terraform-BETggiCN.js +0 -1
  363. package/dist/assets/tex-D96PA37w.js +0 -1
  364. package/dist/assets/tokyo-night-hegEt444.js +0 -1
  365. package/dist/assets/ts-tags-D351s5mN.js +0 -1
  366. package/dist/assets/tsv-B_m7g4N7.js +0 -1
  367. package/dist/assets/turtle-BsS91CYL.js +0 -1
  368. package/dist/assets/twig-27uCiNez.js +0 -1
  369. package/dist/assets/typespec-CAFt9gP4.js +0 -1
  370. package/dist/assets/typst-BUadGCkm.js +0 -1
  371. package/dist/assets/v-BGw2Nkan.js +0 -1
  372. package/dist/assets/vala-CsfeWuGM.js +0 -1
  373. package/dist/assets/vb-Cu-pLBUe.js +0 -1
  374. package/dist/assets/verilog-nZwndyjY.js +0 -1
  375. package/dist/assets/vesper-DRje8inN.js +0 -1
  376. package/dist/assets/vhdl-CeAyd5Ju.js +0 -1
  377. package/dist/assets/viml-CJc9bBzg.js +0 -1
  378. package/dist/assets/vitesse-black-Bkuqu6BP.js +0 -1
  379. package/dist/assets/vitesse-dark-D0r3Knsf.js +0 -1
  380. package/dist/assets/vitesse-light-CVO1_9PV.js +0 -1
  381. package/dist/assets/vue-BqiEGhQt.js +0 -1
  382. package/dist/assets/vue-html-AaS7Mt5G.js +0 -1
  383. package/dist/assets/vue-vine-BoDAl6tE.js +0 -1
  384. package/dist/assets/vyper-CDx5xZoG.js +0 -1
  385. package/dist/assets/wasm-CG6Dc4jp.js +0 -1
  386. package/dist/assets/wenyan-BV7otONQ.js +0 -1
  387. package/dist/assets/wgsl-Dx-B1_4e.js +0 -1
  388. package/dist/assets/wikitext-BhOHFoWU.js +0 -1
  389. package/dist/assets/wit-5i3qLPDT.js +0 -1
  390. package/dist/assets/wolfram-lXgVvXCa.js +0 -1
  391. package/dist/assets/xsl-CtQFsRM5.js +0 -1
  392. package/dist/assets/zenscript-DVFEvuxE.js +0 -1
  393. package/dist/assets/zig-VOosw3JB.js +0 -1
  394. /package/dist/assets/{shellscript-Yzrsuije.js → bash-Yzrsuije.js} +0 -0
  395. /package/dist/assets/{docker-BcOcwvcX.js → dockerfile-BcOcwvcX.js} +0 -0
  396. /package/dist/assets/{make-CHLpvVh8.js → makefile-CHLpvVh8.js} +0 -0
@@ -4,6 +4,7 @@ import { z } from "zod";
4
4
  import { cronScheduleLabel } from "../shared/cron-label.js";
5
5
  import { normalizeCronSchedule, nextCronRuns } from "../shared/routine-schedule.js";
6
6
  import { newId } from "./contracts.js";
7
+ import { SELF_ROUTINE_CAP, UNDO_STALE } from "./direct-apply.js";
7
8
  import { redactSecretsInText } from "./redact.js";
8
9
  import { parseJson, schemaIssue } from "./schema.js";
9
10
  import { intervalHasRestrictions, nextOccurrence, } from "./routines.js";
@@ -200,6 +201,19 @@ const storedOperationSchema = z.discriminatedUnion("action", [
200
201
  z.object({ action: z.literal("run_now"), ...storedManageBase }).strict(),
201
202
  z.object({ action: z.literal("delete"), ...storedManageBase }).strict(),
202
203
  ]);
204
+ const storedSnapshotSchema = storedDefinitionSchema.extend({
205
+ enabled: z.boolean(),
206
+ target: z.literal("room-goal").optional(),
207
+ groupId: z.string().min(1).max(128).optional(),
208
+ resultsThreadId: z.string().min(1).max(128).optional(),
209
+ }).strict();
210
+ const storedUndoSchema = z.object({
211
+ name: z.string().max(200),
212
+ schedule: storedScheduleSchema.optional(),
213
+ appliedUpdatedAt: z.number().int().nonnegative().optional(),
214
+ before: storedSnapshotSchema.optional(),
215
+ ownersBefore: z.boolean().optional(),
216
+ }).strict();
203
217
  const routineRequestCardDataSchema = z.object({
204
218
  version: z.literal(1),
205
219
  requestId: z.string().min(1).max(128),
@@ -209,6 +223,7 @@ const routineRequestCardDataSchema = z.object({
209
223
  operation: storedOperationSchema,
210
224
  appliedAt: z.number().int().nonnegative().optional(),
211
225
  resultId: z.string().min(1).max(128).optional(),
226
+ undo: storedUndoSchema.optional(),
212
227
  }).strict();
213
228
  export class RoutineRequestError extends Error {
214
229
  status;
@@ -896,6 +911,47 @@ function revalidateOperation(operation, manager, botId, now) {
896
911
  }
897
912
  }
898
913
  }
914
+ /** The routine as it stands, kept for Undo. None when it carries what a
915
+ * card cannot hold exactly: attachments, or credential-shaped text the
916
+ * transcript scrubs. */
917
+ function routineSnapshot(routine) {
918
+ if (routine.attachments?.length)
919
+ return undefined;
920
+ if (redactSecretsInText(routine.name) !== routine.name || redactSecretsInText(routine.prompt) !== routine.prompt)
921
+ return undefined;
922
+ const snapshot = {
923
+ name: routine.name,
924
+ instructions: routine.prompt,
925
+ schedule: structuredClone(routine.schedule),
926
+ runOn: routine.runOn,
927
+ durationMinutes: routine.durationMinutes,
928
+ ...(routine.timeoutMinutes === undefined ? {} : { timeoutMinutes: routine.timeoutMinutes }),
929
+ ...(routine.continuity ? { continuity: true } : {}),
930
+ ...(routine.overlap === "queue" ? { overlap: "queue" } : {}),
931
+ enabled: routine.enabled,
932
+ ...(routine.target === "room-goal" ? { target: "room-goal" } : {}),
933
+ ...(routine.groupId ? { groupId: routine.groupId } : {}),
934
+ ...(routine.resultsThreadId ? { resultsThreadId: routine.resultsThreadId } : {}),
935
+ };
936
+ return storedSnapshotSchema.safeParse(snapshot).success ? snapshot : undefined;
937
+ }
938
+ /** Puts an updated routine's definition back exactly: an interval's
939
+ * restrictions are cleared explicitly, since an omitted one is kept. */
940
+ function restorePatch(before, now) {
941
+ const schedule = asSchedule(before.schedule, now);
942
+ return {
943
+ name: before.name,
944
+ prompt: before.instructions,
945
+ runOn: before.runOn,
946
+ schedule: schedule.type === "interval"
947
+ ? { ...schedule, weekdays: schedule.weekdays ?? null, window: schedule.window ?? null, endsAt: schedule.endsAt ?? null }
948
+ : schedule,
949
+ durationMinutes: before.durationMinutes,
950
+ timeoutMinutes: before.timeoutMinutes ?? null,
951
+ continuity: before.continuity === true,
952
+ overlap: before.overlap ?? "skip",
953
+ };
954
+ }
899
955
  export class RoutineRequestService {
900
956
  store;
901
957
  routines;
@@ -968,18 +1024,27 @@ export class RoutineRequestService {
968
1024
  };
969
1025
  if (args.from)
970
1026
  messageInput.from = args.from;
1027
+ // Resolve the current source-thread grant after the asynchronous probe.
1028
+ const owner = operation.forBot?.botId ?? botId;
1029
+ const grant = submitted ? this.autoApply?.(botId, threadId, owner) ?? null : null;
1030
+ // A bot applying its own routines keeps at most SELF_ROUTINE_CAP of them
1031
+ // on; a create or resume past that shows the card, as before. Full
1032
+ // access has no cap.
1033
+ const automatic = grant === "full-access" || (grant === "self" && !this.overSelfCap(operation, owner));
971
1034
  // This check and append are deliberately adjacent and synchronous. JS
972
1035
  // cannot interleave another completed proposal between the capacity /
973
1036
  // ownership decision and the durable transcript write.
974
- const persistence = this.canPersist?.(botId, threadId);
1037
+ const persistence = this.canPersist?.(botId, threadId, !automatic);
975
1038
  if (persistence && !persistence.ok) {
976
1039
  throw new RoutineRequestError(persistence.error, persistence.status);
977
1040
  }
978
1041
  if (args.canCommit && !args.canCommit()) {
979
1042
  throw new RoutineRequestError("The requesting turn ended before this proposal could be saved", 401);
980
1043
  }
981
- // Resolve the current source-thread grant after the asynchronous probe.
982
- const automatic = submitted && this.autoApply?.(botId, threadId) === true;
1044
+ // What Undo puts back, taken before the change.
1045
+ const before = automatic && (operation.action === "update" || operation.action === "delete")
1046
+ ? this.snapshotOf(operation.routineId, owner)
1047
+ : undefined;
983
1048
  if (automatic) {
984
1049
  messageInput.card.options = [];
985
1050
  messageInput.card.dismissed = true;
@@ -1005,8 +1070,10 @@ export class RoutineRequestService {
1005
1070
  catch (error) {
1006
1071
  result = { claimed: true, state: "invalid", error: error instanceof Error ? error.message : String(error), status: error instanceof RoutineRequestError ? error.status : 400 };
1007
1072
  }
1008
- if (result.state === "applied")
1009
- return { ...proposal, result };
1073
+ if (result.state === "applied") {
1074
+ this.recordAutoApplied(threadId, message.id, definition, before);
1075
+ return { ...proposal, result, ...(grant ? { appliedBy: grant } : {}) };
1076
+ }
1010
1077
  // The scheduler commit can succeed even if settling its transcript
1011
1078
  // fails. Report that exact result; a retry only finishes the receipt.
1012
1079
  const receipt = this.routines.routineRequestReceipt(requestId);
@@ -1015,10 +1082,147 @@ export class RoutineRequestService {
1015
1082
  return { ...proposal, result: {
1016
1083
  claimed: true, state: "applied", action: receipt.action, resultId: receipt.resultId,
1017
1084
  settlementPending: true, message: "Routine change applied. Recording the operation receipt could not finish; the change will not be applied again.",
1018
- } };
1085
+ }, ...(grant ? { appliedBy: grant } : {}) };
1019
1086
  }
1020
1087
  throw new RoutineRequestError(result.state === "invalid" ? result.error : "The routine change could not be applied", result.state === "invalid" ? result.status : 409);
1021
1088
  }
1089
+ /** Whether one more enabled routine would take the bot past the cap. */
1090
+ overSelfCap(operation, owner) {
1091
+ if (operation.action !== "create" && operation.action !== "resume")
1092
+ return false;
1093
+ const enabled = this.routines.listRoutines().filter((routine) => routine.botId === owner && routine.enabled).length;
1094
+ return enabled + 1 > SELF_ROUTINE_CAP;
1095
+ }
1096
+ snapshotOf(routineId, owner) {
1097
+ const routine = ownedRoutine(this.routines, routineId, owner);
1098
+ return routine ? routineSnapshot(routine) : undefined;
1099
+ }
1100
+ /** Marks a card whose change applied without a person, with what its
1101
+ * one-line receipt and Undo need. A failure here leaves the change
1102
+ * applied and the card as it was, only without Undo. */
1103
+ recordAutoApplied(threadId, messageId, definition, before) {
1104
+ try {
1105
+ const message = this.store.messagesFor(threadId).find((candidate) => candidate.id === messageId);
1106
+ const card = message?.card;
1107
+ const payload = card?.routineRequest;
1108
+ if (!message || !card || !payload)
1109
+ return;
1110
+ const action = payload.operation.action;
1111
+ const routineId = payload.operation.action === "create" ? payload.resultId : payload.operation.routineId;
1112
+ const after = routineId ? this.routines.listRoutines().find((routine) => routine.id === routineId) : undefined;
1113
+ const undo = {
1114
+ name: redactSecretsInText(after?.name ?? definition?.name ?? before?.name ?? "routine"),
1115
+ ...(action === "create" || action === "update" || action === "resume"
1116
+ ? { schedule: structuredClone(after?.schedule ?? definition?.schedule) }
1117
+ : {}),
1118
+ ...(after && (action === "update" || action === "pause" || action === "resume") ? { appliedUpdatedAt: after.updatedAt } : {}),
1119
+ ...(before ? { before } : {}),
1120
+ };
1121
+ if (!storedUndoSchema.safeParse(undo).success)
1122
+ delete undo.schedule;
1123
+ this.store.patchMessage(threadId, messageId, {
1124
+ card: { ...card, autoApplied: true, routineRequest: { ...payload, undo } },
1125
+ });
1126
+ }
1127
+ catch {
1128
+ // The routine change itself is durable; only its Undo is lost.
1129
+ }
1130
+ }
1131
+ /** Puts back a change that applied without a person. Authorized by the
1132
+ * caller exactly like answering the card; refuses, applying nothing, once
1133
+ * the routine changed since. A second Undo reports already undone. */
1134
+ undo(args) {
1135
+ const message = this.store
1136
+ .messagesFor(args.threadId)
1137
+ .find((candidate) => candidate.card?.requestId === args.requestId && candidate.card.routineRequest);
1138
+ const card = message?.card;
1139
+ if (!message || !card)
1140
+ return { claimed: false };
1141
+ if (card.undone)
1142
+ return { claimed: true, state: "already_undone" };
1143
+ const cannot = (error, status = 409) => ({ claimed: true, state: "invalid", error, status });
1144
+ if (!card.autoApplied || card.answered !== "allow")
1145
+ return cannot("Only a change that applied on its own can be undone here.");
1146
+ const parsed = routineRequestCardDataSchema.safeParse(card.routineRequest);
1147
+ if (!parsed.success)
1148
+ return cannot("This change can't be undone here.");
1149
+ const payload = parsed.data;
1150
+ if (payload.botId !== args.botId || payload.threadId !== args.threadId) {
1151
+ return cannot("This routine change belongs to another conversation", 403);
1152
+ }
1153
+ const operation = payload.operation;
1154
+ const owner = operation.forBot?.botId ?? payload.botId;
1155
+ const undo = payload.undo;
1156
+ const stale = { claimed: true, state: "invalid", error: UNDO_STALE, status: 409, stale: true };
1157
+ const now = this.now();
1158
+ let routineId;
1159
+ let restoredId;
1160
+ try {
1161
+ switch (operation.action) {
1162
+ case "run_now":
1163
+ return cannot("A routine run can't be undone.");
1164
+ case "create": {
1165
+ routineId = payload.resultId ?? "";
1166
+ if (!routineId || !ownedRoutine(this.routines, routineId, owner))
1167
+ return stale;
1168
+ this.routines.remove(routineId);
1169
+ break;
1170
+ }
1171
+ case "update":
1172
+ case "pause":
1173
+ case "resume": {
1174
+ routineId = operation.routineId;
1175
+ if (undo?.appliedUpdatedAt === undefined || (operation.action === "update" && !undo.before)) {
1176
+ return cannot("This change can't be undone here.");
1177
+ }
1178
+ const current = ownedRoutine(this.routines, routineId, owner);
1179
+ if (!current || current.updatedAt !== undo.appliedUpdatedAt)
1180
+ return stale;
1181
+ const patch = operation.action === "update"
1182
+ ? restorePatch(undo.before, now)
1183
+ : { enabled: operation.action === "pause" };
1184
+ if (!this.routines.update(routineId, patch))
1185
+ return stale;
1186
+ break;
1187
+ }
1188
+ case "delete": {
1189
+ routineId = operation.routineId;
1190
+ const before = undo?.before;
1191
+ if (!before)
1192
+ return cannot("This change can't be undone here.");
1193
+ restoredId = this.routines.create({
1194
+ name: before.name,
1195
+ prompt: before.instructions,
1196
+ botId: owner,
1197
+ ...(before.target ? { target: before.target, groupId: before.groupId } : {}),
1198
+ runOn: before.runOn,
1199
+ enabled: before.enabled,
1200
+ schedule: asSchedule(before.schedule, now),
1201
+ durationMinutes: before.durationMinutes,
1202
+ ...(before.timeoutMinutes === undefined ? {} : { timeoutMinutes: before.timeoutMinutes }),
1203
+ ...(before.continuity ? { continuity: true } : {}),
1204
+ ...(before.overlap === "queue" ? { overlap: "queue" } : {}),
1205
+ ...(before.resultsThreadId ? { resultsThreadId: before.resultsThreadId } : {}),
1206
+ }).id;
1207
+ break;
1208
+ }
1209
+ default:
1210
+ return cannot("This change can't be undone here.");
1211
+ }
1212
+ }
1213
+ catch (error) {
1214
+ return cannot(redactSecretsInText(error instanceof Error ? error.message : String(error)).slice(0, 500));
1215
+ }
1216
+ this.store.patchMessage(args.threadId, message.id, { card: { ...card, undone: true } });
1217
+ return {
1218
+ claimed: true,
1219
+ state: "undone",
1220
+ action: operation.action,
1221
+ routineId,
1222
+ ...(restoredId ? { restoredId } : {}),
1223
+ ...(undo?.ownersBefore !== undefined ? { ownersBefore: undo.ownersBefore } : {}),
1224
+ };
1225
+ }
1022
1226
  async requireCloudReadiness(operation, proposerBotId) {
1023
1227
  if (!this.cloudReady || operation.action === "pause" || operation.action === "delete")
1024
1228
  return;
@@ -45,7 +45,7 @@ function folderClause(cwd) {
45
45
  function buildSetupPrompt(profileAside, cwd) {
46
46
  return ("\n\nThe user explicitly asked you to set yourself up. For this setup request, help configure the bot from what the user tells you." +
47
47
  ` First ask at most four questions that change what you would build: what the job is, when it should happen (on demand, on a schedule, or when something arrives), which apps or accounts it touches, and ${folderClause(cwd)}.` +
48
- " Then, before any tool call, tell the user in plain language what you intend: who you will be, what you will do and when, where you will work, what you will need from them, and what you will not do. Ask for missing choices, not an extra yes for already-requested actions under granted Full Access." +
48
+ " Then, before any tool call, tell the user in plain language what you intend: who you will be, what you will do and when, where you will work, what you will need from them, and what you will not do. Ask for missing choices, not an extra yes for already-requested actions: changes to your own profile and routines apply immediately, and the person sees each with an Undo." +
49
49
  " First send one message describing the changes you are about to request, then make the tool calls. Follow each result: if applied, continue without another confirmation; if pending, end the turn and wait for its in-app decision. Do not repeat the list or claim success from the permission mode alone." +
50
50
  ` Use propose_profile for your identity, standing rules ${profileAside}, and the working folder (cwd), propose_routine only for a schedule the user requested, and request_credential for any missing token.` +
51
51
  " Full Access does not supply answers, credentials, or broader permissions for another bot. A credential request still needs the user's secure entry. Report failed or cancelled changes honestly." +
@@ -1,6 +1,6 @@
1
1
  // `/learn` — turn a described workflow, URL, folder, or "what we just did"
2
2
  // into a reusable SKILL.md. The live agent authors the skill with skill_manage;
3
- // the harness applies it under granted Full Access or stages a pending review.
3
+ // the harness applies it (a bot's own skill applies at any level) or stages a pending review.
4
4
  //
5
5
  // There is no separate distillation engine. This module only builds the
6
6
  // prompt and recognises the slash command, so it works on every engine
@@ -61,7 +61,7 @@ export function buildLearnPrompt(userRequest) {
61
61
  "1. Inventory every source the user named, using the tools you already have — file tools for local paths, web fetch for URLs, and this conversation if they referred to something you just did. If the request is ambiguous about scope, make a reasonable choice and note it; do not stall.\n" +
62
62
  "2. Check existing skills with skills_list. If one already covers this topic, leave it alone unless the user explicitly asked to revise that named learned/editable skill. For an explicit revision, read only the exact SKILL.md path listed for that skill in your system prompt (the native .agents/skills/<exact-name>/SKILL.md link is a fallback), preserve every still-valid step, re-verify what changed, then call skill_manage with action=\"update\" and skill_name set to that exact name. If you cannot read or verify the current skill, stop instead of replacing it from memory. For a genuinely new skill, use action=\"create\".\n" +
63
63
  "3. Pass source as the exact URL or folder you used, or \"conversation\" when the conversation is the source.\n" +
64
- "4. Follow the skill_manage result: with granted Full Access it may apply immediately. After an applied result, continue the requested work without another confirmation. If review is pending, a create stays inactive and an update leaves the current version untouched; end the turn and wait for the in-app decision. Never claim success from the permission mode alone, and report failed or cancelled changes honestly.\n\n" +
64
+ "4. Follow the skill_manage result: your own skill changes apply immediately and the person sees them with an Undo. After an applied result, continue the requested work without another confirmation. If review is pending, a create stays inactive and an update leaves the current version untouched; end the turn and wait for the in-app decision. Never claim success from the permission mode alone, and report failed or cancelled changes honestly.\n\n" +
65
65
  AUTHORING_STANDARDS +
66
66
  "\n\nWhen done, tell the user the skill name and a one-line summary of what it captured.");
67
67
  }
@@ -1189,6 +1189,36 @@ export function applySkillWriteWithReceipt(botId, staged, recordApplied) {
1189
1189
  message: "Skill change applied. Recording its receipt or cleaning up staging could not finish; do not apply it again." };
1190
1190
  }
1191
1191
  }
1192
+ /** Undo for a learned-skill write that applied without a person: a create
1193
+ * is removed; an update gets the SKILL.md it replaced back, as a fresh
1194
+ * revision through the same stage and apply path. Only while the skill is
1195
+ * exactly as that write left it; otherwise `stale`, and nothing changes. */
1196
+ export function undoSkillWrite(botId, write) {
1197
+ const entry = readManifest(botId)[write.name];
1198
+ if (!entry || entry.appliedStageId !== write.stagedId || !installedLearnedSkillMatches(botId, write.name, entry)) {
1199
+ return { stale: true };
1200
+ }
1201
+ if (write.action === "create") {
1202
+ const removed = removeSkill(botId, write.name);
1203
+ return "error" in removed ? removed : { undone: true };
1204
+ }
1205
+ if (!write.previous)
1206
+ return { error: "This change can't be undone here." };
1207
+ const staged = stageSkillWrite(botId, {
1208
+ action: "update",
1209
+ targetName: write.name,
1210
+ files: [{ path: "SKILL.md", content: write.previous.skillMd }],
1211
+ source: write.previous.source,
1212
+ });
1213
+ if ("error" in staged)
1214
+ return staged;
1215
+ const applied = applyStagedSkillWrite(botId, staged.id, { expectedSha256: staged.sha256 });
1216
+ if ("error" in applied) {
1217
+ rejectStagedSkillWrite(botId, staged.id);
1218
+ return applied;
1219
+ }
1220
+ return { undone: true };
1221
+ }
1192
1222
  /** The skills block appended to a bot's system prompt: enabled skills only,
1193
1223
  * index lines only — the same progressive-disclosure shape the spec asks
1194
1224
  * agents for. Bodies never ride the prompt; the bot reads the file when a
@@ -123,7 +123,7 @@ export function customMcpPrompt(names) {
123
123
  }
124
124
  export const CREDENTIAL_PROMPT = " If a supported API key is missing for the service actually needed, use request_credential to create a secure credential request. Before requesting a computer-provider key, inspect the configured targets with select_computer; an existing self-hosted VPS does not need Boat credentials. Do not request a different provider's key merely because a task mentions cloud. A freshly QR-paired mobile app or the desktop app can show the secure entry card. Never claim it opened unless the request succeeded, and never ask the user to paste credentials into chat.";
125
125
  export const THREADS_PROMPT = " A thread is one conversation with its own history and its own run; a bot can have several running at once, and the person sees them as rows under that bot. Use start_thread to open one on yourself for separate work, or on a teammate to hand them a job that should run on its own. Use list_threads to see how the ones you opened are going. When you mention a thread to the person, write its title as #Title so it links. Do not use a ticket comment, a note, or a room post as a stand-in for a thread.";
126
- const PROPOSAL_RESULT_PROMPT = " Follow the tool result: with granted Full Access it may report applied immediately; then continue the requested work without asking for another confirmation. If it reports a pending review, end the turn and wait for the in-app decision. Never claim success before an applied result, and report failures honestly. Full Access does not grant another bot broader permissions.";
126
+ const PROPOSAL_RESULT_PROMPT = " Follow the tool result: a change to your own routines, skills, profile or model applies immediately and the person sees it with an Undo; then continue the requested work without asking for another confirmation. A change for another bot may wait for the person. If it reports a pending review, end the turn and wait for the in-app decision. Never claim success before an applied result, and report failures honestly. Full Access does not grant another bot broader permissions.";
127
127
  export const ROUTINE_PROMPT = " If the user explicitly asks to list or review, schedule, run, or change routines, use list_routines and propose_routine or propose_routine_action. Keep run_on omitted or maus to use the bot's current model and configured computer, including its VPS. A routine's box (legacy cloud) destination runs on the bot's cloud computer, not the configured VPS; choose it only when the user explicitly wants the cloud computer. Convert calendar requests such as the first or last day of each month or the second Monday to a five-field cron expression with an explicit IANA timezone; use interval for elapsed every-N-minutes work. Never replace a calendar rule with daily AI date checking or an approximate weekly schedule; clarify ambiguous or unsupported requests." + PROPOSAL_RESULT_PROMPT;
128
128
  export const ROUTINE_EXECUTION_PROMPT = " Execute this routine now: use available peer tools for required handoffs rather than merely announcing that you will wait; after an accepted delegation, end this turn for automatic resumption, and report a concrete blocker if no handoff is possible.";
129
129
  export const LEARN_PROMPT = " If the user sends /learn or asks you to save a reusable procedure from this work, use skills_list and skill_manage. Create new skills; update an existing learned skill only when the user explicitly asks to revise that exact name. Include source provenance." + PROPOSAL_RESULT_PROMPT;
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  /**
5
5
  * Automatic continuity: when a turn ends without a final answer and the work
6
- * is resumable (budget cap or tool errors), persist a structured handoff and
6
+ * is resumable (a budget cap), persist a structured handoff and
7
7
  * let the harness start a `Continue:` thread on the same bot — transparent to
8
8
  * the bot, which just sees a normal new thread seeded with the handoff.
9
9
  *
@@ -82,26 +82,21 @@ export function writeTurnHandoff(input) {
82
82
  return null;
83
83
  }
84
84
  }
85
- /** Provider config errors are not resumable: looping on them burns budget and
86
- * masks the real fix (change the model or the tool set). Everything else that
87
- * stops a turn without a final answer is a candidate for auto-continuation. */
88
- const NOT_RESUMABLE = /not a multimodal model|unknown model|does not support|tool arguments do not match/i;
85
+ /** The harness's own budget stops, in its own words: the chat driver's
86
+ * "Stopped after 64 steps without a final answer…" and the older model-call
87
+ * cap. Matched from the start of the failure, so a provider's error text can
88
+ * never read as one: "upstream HTTP 429: Rate limit reached" is not a spent
89
+ * budget. */
90
+ const CAP_STOP = /^(?:stopped after \d+ [a-z ]+ without a final answer|model-call limit reached)/i;
89
91
  /** Classify a terminal turn as resumable. Returns the reason for the
90
92
  * continuation (`cap` = budget exhausted), or null when the turn must not be
91
- * auto-continued. A tool error is never continued: it includes a person's or
92
- * the approval policy's denial, and a new unattended thread would retry what
93
- * was refused. */
93
+ * auto-continued. Only a cap is continued. A provider error (a rate limit, a
94
+ * quota, a rejected key, a model that cannot take the request) fails the same
95
+ * way in a new thread: continuing would go straight back to the provider that
96
+ * just refused. A tool error includes a person's or the approval policy's
97
+ * denial, and a new unattended thread would retry what was refused. */
94
98
  export function classifyContinuable(_stopReason, failure) {
95
- if (!failure)
96
- return null;
97
- if (NOT_RESUMABLE.test(failure))
98
- return null;
99
- // Only OpenMausBot's own step cap. A provider's "Rate limit reached" or
100
- // "usage limit reached" is not a budget a new thread can continue past:
101
- // continuing would go straight back to the provider that said slow down.
102
- if (/stopped after \d+ steps without a final answer|model-call limit reached/i.test(failure))
103
- return "cap";
104
- return null;
99
+ return failure && CAP_STOP.test(failure) ? "cap" : null;
105
100
  }
106
101
  const CONTINUE_TITLE = /^Continue: /;
107
102
  const MAX_PER_BOT_PER_HOUR = 5;
@@ -338,7 +338,12 @@ export async function createWorkspaceBackupSnapshot(dataDir, options, jobId) {
338
338
  if (existsSync(sourceDb)) {
339
339
  if (lstatSync(sourceDb).isSymbolicLink())
340
340
  throw new Error("The message database must not be a symbolic link.");
341
- const db = new DatabaseSync(sourceDb, { readOnly: true });
341
+ // Another connection may still open this database meanwhile: a copy's
342
+ // status poll counts its chats (cloud-move.ts workspaceContents). Its
343
+ // open (WAL recovery) and close (checkpoint) keep a new reader out for a
344
+ // moment, and without a busy timeout the first backup step fails at once
345
+ // ("database is locked", or Node's "not an error"). Wait that moment out.
346
+ const db = new DatabaseSync(sourceDb, { readOnly: true, timeout: 5_000 });
342
347
  // Node 26's native backup completion can wait for unrelated event-loop
343
348
  // activity after an async scrypt. A scoped pulse prevents an idle server
344
349
  // from waiting indefinitely; it owns no data and always stops here.
@@ -19519,7 +19519,7 @@ async function createWorkspaceBackupSnapshot(dataDir2, options2, jobId2) {
19519
19519
  const sourceDb = join2(root, "messages.db");
19520
19520
  if (existsSync(sourceDb)) {
19521
19521
  if (lstatSync2(sourceDb).isSymbolicLink()) throw new Error("The message database must not be a symbolic link.");
19522
- const db = new DatabaseSync(sourceDb, { readOnly: true });
19522
+ const db = new DatabaseSync(sourceDb, { readOnly: true, timeout: 5e3 });
19523
19523
  const completionPulse = setInterval(() => {
19524
19524
  }, 25);
19525
19525
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmausbot",
3
- "version": "0.1.98",
3
+ "version": "0.1.99",
4
4
  "description": "Run the OpenMausBot server anywhere and pair your devices to it",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: create-verification-skill
3
- description: "Create one reviewed skill that teaches a bot how to launch, drive, and verify a specific app or project. Use only when the user explicitly asks for a verification skill."
3
+ description: "Create one skill that teaches a bot how to launch, drive, and verify a specific app or project. Use only when the user explicitly asks for a verification skill."
4
4
  ---
5
5
 
6
6
  # Create a verification skill
7
7
 
8
- Create one compact, project-specific `SKILL.md` through OpenMausBot's normal
9
- skill review flow. Do not install files directly, enable a skill yourself, or
10
- silently add scripts to the user's project.
8
+ Create one compact, project-specific `SKILL.md` through `skill_manage`, which
9
+ shows the person every change with an Undo. Do not install skill files
10
+ directly or silently add scripts to the user's project.
11
11
 
12
12
  ## 1. Inspect before drafting
13
13
 
@@ -52,13 +52,14 @@ The proposed `SKILL.md` must contain YAML frontmatter and these sections:
52
52
  Keep it concise. Evidence about the user path is input to the draft—not
53
53
  permission to retain secrets, audio, screenshots, or coordinates.
54
54
 
55
- ## 4. Stage it for review
55
+ ## 4. Save it
56
56
 
57
57
  Call `skills_list` first. If an existing skill already covers the project,
58
58
  report that and do not overwrite it. Otherwise call `skill_manage` with
59
59
  `action="create"`, the complete `skill_md`, a short `gist`, and the exact
60
60
  source used (repository path, URL, or `conversation`).
61
61
 
62
- `skill_manage` only stages the proposal. Tell the user its name and that it is
63
- inactive until they approve the in-app review card. Never claim it was enabled
64
- or scheduled automatically.
62
+ Read the `skill_manage` result. If it applied, tell the user the skill's name,
63
+ that it is on, and that they can undo it from the chat. Only if it is pending,
64
+ tell them it stays inactive until they decide on the in-app card. Never claim
65
+ it was enabled without an applied result.
@@ -2,7 +2,7 @@
2
2
  "id": "create-verification-skill",
3
3
  "name": "Create Verification Skill",
4
4
  "version": "0.1.0",
5
- "description": "Stage one reviewed verification skill for a specific app or project.",
5
+ "description": "Write one verification skill for a specific app or project.",
6
6
  "defaultEnabled": true,
7
7
  "triggerTerms": [
8
8
  "/create-verification-skill",