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
@@ -103,6 +103,8 @@ const OUTCOME_OF_DECISION = {
103
103
  "user-approved": "allowed",
104
104
  "review-would-approve": "allowed",
105
105
  "user-denied": "denied",
106
+ // A person reverted a change that had applied on its own.
107
+ "user-undone": "denied",
106
108
  "review-would-deny": "denied",
107
109
  "card-shown": "waiting",
108
110
  };
@@ -246,33 +246,25 @@ function gitFailure(command, err, stderr, signal) {
246
246
  }
247
247
  /** Run one git command against the shadow repo. cwd is the WORK TREE — the
248
248
  * "." pathspec in add resolves relative to it. Every call carries the
249
- * GIT_TIMEOUT_MS hard timeout. */
250
- function runGit(args, cwd, env, signal) {
249
+ * GIT_TIMEOUT_MS hard timeout. `input` is written to git's stdin.
250
+ * Each call is a process start, which costs tens of milliseconds on Windows,
251
+ * and the turn waits for its snapshot — so a snapshot keeps its calls few
252
+ * (see commitAll). */
253
+ function runGit(args, cwd, env, signal, input) {
251
254
  return new Promise((resolvePromise, rejectPromise) => {
252
255
  signal?.throwIfAborted();
253
- execFile("git", args, { cwd, env, signal, windowsHide: true, encoding: "utf8", timeout: GIT_TIMEOUT_MS, maxBuffer: 16 * 1024 * 1024 }, (err, stdout, stderr) => {
256
+ const child = execFile("git", args, { cwd, env, signal, windowsHide: true, encoding: "utf8", timeout: GIT_TIMEOUT_MS, maxBuffer: 16 * 1024 * 1024 }, (err, stdout, stderr) => {
254
257
  if (err)
255
258
  rejectPromise(gitFailure(args[0], err, stderr, signal));
256
259
  else
257
260
  resolvePromise(stdout);
258
261
  });
259
- });
260
- }
261
- /** `git diff --cached --quiet`: is there anything staged beyond HEAD? Used
262
- * instead of `status --porcelain` emptiness on purpose — a nested repo with
263
- * a dirty work tree shows up in status forever while staging nothing, which
264
- * would either commit empty churn every turn or fail the commit outright. */
265
- function hasStagedChanges(cwd, env, signal) {
266
- return new Promise((resolvePromise, rejectPromise) => {
267
- signal?.throwIfAborted();
268
- execFile("git", ["diff", "--cached", "--quiet", "--ignore-submodules=dirty"], { cwd, env, signal, windowsHide: true, encoding: "utf8", timeout: GIT_TIMEOUT_MS, maxBuffer: 16 * 1024 * 1024 }, (err, _stdout, stderr) => {
269
- if (err === null)
270
- resolvePromise(false);
271
- else if (err.code === 1)
272
- resolvePromise(true);
273
- else
274
- rejectPromise(gitFailure("diff", err, stderr, signal));
275
- });
262
+ if (input !== undefined) {
263
+ // A git that exits before reading reports through its exit status; a
264
+ // broken pipe here must not become an unhandled stream error.
265
+ child.stdin?.on("error", () => { });
266
+ child.stdin?.end(input);
267
+ }
276
268
  });
277
269
  }
278
270
  // One operation at a time per shadow repo: snapshots, diffs and pin releases
@@ -312,6 +304,20 @@ async function sweepLiveRefs(cwd, env, shadow, signal) {
312
304
  droppedPins.add(shadow);
313
305
  sweptShadows.add(shadow);
314
306
  }
307
+ /** One git call, however long the history: HEAD and at most its parent. */
308
+ async function readHead(cwd, env, signal) {
309
+ const out = await runGit(["log", "-2", "--format=%H %T %P", "HEAD"], cwd, env, signal);
310
+ const [head, parent] = out.split("\n").filter(Boolean).map((line) => line.trim().split(" "));
311
+ const [hash, tree, ...parents] = head ?? [];
312
+ if (!hash || !tree)
313
+ throw new Error(`git log: unexpected output ${JSON.stringify(out.slice(0, 200))}`);
314
+ let base = null;
315
+ if (parents.length === 0)
316
+ base = hash;
317
+ else if (parents.length === 1 && parent?.length === 2)
318
+ base = parents[0];
319
+ return { hash, tree, base };
320
+ }
315
321
  /** Create the shadow repo on first use; self-heal its config files on every
316
322
  * use (they are tiny, and rewriting them lets exclude-list updates reach
317
323
  * shadows that already exist). The base commit is an EMPTY marker so HEAD
@@ -349,14 +355,17 @@ async function ensureShadow(cwd, env, shadow, signal) {
349
355
  }
350
356
  }
351
357
  writeFileSync(join(shadow, ".git", "info", "exclude"), EXCLUDES + [...cachePatterns].join("\n") + "\n");
358
+ let head;
352
359
  try {
353
- await runGit(["rev-parse", "--verify", "HEAD"], cwd, env, signal);
360
+ head = await readHead(cwd, env, signal);
354
361
  }
355
362
  catch {
356
363
  // brand-new repo (or a crash between init and first commit)
357
364
  await runGit(["commit", "--no-verify", "--allow-empty", "-m", "checkpoint base"], cwd, env, signal);
365
+ head = await readHead(cwd, env, signal);
358
366
  }
359
367
  await sweepLiveRefs(cwd, env, shadow, signal);
368
+ return head;
360
369
  }
361
370
  /** Folder listings in flight at once (libuv's pool has four threads). */
362
371
  const LISTING_CONCURRENCY = 4;
@@ -469,9 +478,11 @@ async function stageWorkTree(cwd, env, signal) {
469
478
  }
470
479
  /** Capture fully before advancing HEAD: null when the add was partial, so a
471
480
  * partial capture never replaces the last usable checkpoint or authorizes
472
- * removal of its objects. */
473
- async function commitAll(cwd, env, label, signal) {
474
- const previous = (await runGit(["rev-parse", "HEAD"], cwd, env, signal)).trim();
481
+ * removal of its objects. With `pin`, the turn's pin lands on the returned
482
+ * commit in the same ref transaction that moves HEAD.
483
+ * A changed folder costs the shadow `write-tree`, `commit-tree` and one
484
+ * `update-ref` past staging; an unchanged one, `write-tree` alone. */
485
+ async function commitAll(cwd, env, head, label, pin, signal) {
475
486
  try {
476
487
  await stageWorkTree(cwd, env, signal);
477
488
  }
@@ -481,18 +492,25 @@ async function commitAll(cwd, env, label, signal) {
481
492
  throw e;
482
493
  return null;
483
494
  }
484
- const changed = await hasStagedChanges(cwd, env, signal);
485
- const base = (await runGit(["rev-list", "--max-parents=0", "HEAD"], cwd, env, signal)).trim();
486
- const count = (await runGit(["rev-list", "--count", "HEAD"], cwd, env, signal)).trim();
487
- if (!changed && Number(count) <= 2)
488
- return { hash: previous, advanced: false, compacted: false };
495
+ // Is anything staged beyond HEAD? The staged tree is HEAD's tree exactly
496
+ // when nothing is. Only what is staged counts, never work-tree status: a
497
+ // nested repo with a dirty work tree stages nothing (its gitlink is
498
+ // unchanged), so it neither commits empty churn every turn nor fails.
489
499
  const tree = (await runGit(["write-tree"], cwd, env, signal)).trim();
490
- const message = changed ? label : (await runGit(["show", "-s", "--format=%B", "HEAD"], cwd, env, signal)).trim();
491
- // Parent only the empty marker, never the previous snapshot: keeping the
492
- // previous commit as an ancestor would retain every old tree indefinitely.
493
- const hash = (await runGit(["commit-tree", tree, "-p", base, "-m", message], cwd, env, signal)).trim();
494
- await runGit(["update-ref", "HEAD", hash, previous], cwd, env, signal);
495
- return { hash, advanced: true, compacted: Number(count) > 2 };
500
+ const changed = tree !== head.tree;
501
+ let hash = head.hash;
502
+ if (changed || head.base === null) {
503
+ const base = head.base ?? (await runGit(["rev-list", "--max-parents=0", "HEAD"], cwd, env, signal)).trim();
504
+ const message = changed ? label : (await runGit(["show", "-s", "--format=%B", "HEAD"], cwd, env, signal)).trim();
505
+ // Parent only the empty marker, never the previous snapshot: keeping the
506
+ // previous commit as an ancestor would retain every old tree indefinitely.
507
+ hash = (await runGit(["commit-tree", tree, "-p", base, "-m", message], cwd, env, signal)).trim();
508
+ }
509
+ const advanced = hash !== head.hash;
510
+ const updates = [advanced ? `update HEAD ${hash} ${head.hash}\n` : "", pin ? `update ${liveRef(pin)} ${hash}\n` : ""].join("");
511
+ if (updates !== "")
512
+ await runGit(["update-ref", "--stdin"], cwd, env, signal, updates);
513
+ return { hash, advanced, compacted: advanced && head.base === null };
496
514
  }
497
515
  /** HEAD-advancing snapshots per shadow since this process last collected. */
498
516
  const commitsSinceGc = new Map();
@@ -582,12 +600,10 @@ export async function snapshot(botId, cwd, label, signal, opts) {
582
600
  releaseCollection(shadow);
583
601
  return await serialize(shadow, async () => {
584
602
  const env = gitEnv(shadow, worktree);
585
- await ensureShadow(worktree, env, shadow, signal);
586
- const result = await commitAll(worktree, env, label, signal);
603
+ const head = await ensureShadow(worktree, env, shadow, signal);
604
+ const result = await commitAll(worktree, env, head, label, opts?.pin, signal);
587
605
  if (!result)
588
606
  return null;
589
- if (opts?.pin)
590
- await runGit(["update-ref", liveRef(opts.pin), result.hash], worktree, env, signal);
591
607
  // Never awaited by the turn waiting on this snapshot, and held for that
592
608
  // turn's settled diff: diffWorkingTree queues it behind itself, so GC
593
609
  // never eats into the digest's capture window.
@@ -0,0 +1,20 @@
1
+ // Which of a bot's proposed changes apply without a person. One rule for
2
+ // routines, skills, profile and default model, on the desktop, a server and
3
+ // a Cloud home alike:
4
+ // - Full access applies everything it always has, with no new limits;
5
+ // - at any other level a bot's change to ITSELF applies directly (its own
6
+ // routines, skills, profile, model), and the person sees a one-line
7
+ // receipt with Undo. A change for another bot keeps its card.
8
+ // The one exception is a Cloud home's guest-driven turn, which keeps today's
9
+ // card for everything (`blocked`). Team setup and peer approvals are not
10
+ // changes to the bot itself and stay Full access only.
11
+ /** What Undo says, applying nothing, once the thing changed since. */
12
+ export const UNDO_STALE = "Changed since, so it can't be undone here.";
13
+ /** A bot applying its own routines directly keeps at most this many
14
+ * enabled; past it, a create or resume shows today's card instead. */
15
+ export const SELF_ROUTINE_CAP = 20;
16
+ export function directApply(args) {
17
+ if (args.fullAccess)
18
+ return "full-access";
19
+ return args.targetBotId === args.botId && !args.blocked ? "self" : null;
20
+ }
@@ -1243,7 +1243,7 @@ export async function callTool(name, args, context) {
1243
1243
  return `- ${row.action} ${row.name}`;
1244
1244
  }).join("\n")
1245
1245
  : "(none)";
1246
- return { text: `Imported skills:\n${live}\n\nStaged (waiting for the user to confirm):\n${pending}` };
1246
+ return { text: `Imported skills:\n${live}\n\nStaged (waiting for the user's decision):\n${pending}` };
1247
1247
  }
1248
1248
  if (name === "skill_manage") {
1249
1249
  if (args.action !== "create" && args.action !== "update") {
@@ -86,7 +86,7 @@ const ROUTINE_SCHEDULE_SCHEMA = {
86
86
  },
87
87
  starts_at: {
88
88
  type: "string",
89
- description: "Optional for type interval: RFC3339 date-time with an explicit timezone offset that anchors the cadence. Omit to start one interval after the routine is applied (immediately with granted Full Access, otherwise after confirmation).",
89
+ description: "Optional for type interval: RFC3339 date-time with an explicit timezone offset that anchors the cadence. Omit to start one interval after the routine is applied.",
90
90
  },
91
91
  window_start: {
92
92
  type: "string",
@@ -159,6 +159,9 @@ const ROUTINE_FIELDS_SCHEMA = {
159
159
  // Chief is not shown (catalogTools), along with the parameter itself.
160
160
  const CHIEF_PROFILE_TARGET = " A Chief of Staff may pass for_bot_id (from list_bots) for a requested change to another bot in its section.";
161
161
  const PROPOSAL_OUTCOME = " Read the result: granted Full Access may apply the change immediately. If applied, continue the requested work without another confirmation. Only a pending result requires ending the turn and waiting for the in-app decision. Never claim success from the permission mode alone; report failed or cancelled results honestly. This does not elevate another bot's execution permissions.";
162
+ /** Routines, skills, profile and model: a bot's change to itself applies at
163
+ * any level (server/direct-apply.ts). */
164
+ const SELF_CHANGE_OUTCOME = " Read the result: a change to your own routines, skills, profile or model applies immediately, and the person sees it with an Undo; a change for another bot may wait for the person's confirmation. If applied, continue the requested work without another confirmation. Only a pending result requires ending the turn and waiting for the in-app decision. Never claim success without an applied result; report failed or cancelled results honestly. This does not elevate another bot's execution permissions.";
162
165
  /** Every tool, in the order it is listed. Four peer tools are worded
163
166
  * differently for an external runtime, which may poll inside one process. */
164
167
  const toolDefinitions = (externalRuntime) => [
@@ -613,7 +616,7 @@ const toolDefinitions = (externalRuntime) => [
613
616
  },
614
617
  {
615
618
  name: "propose_routine",
616
- description: "Prepare a new routine after the user explicitly asks to schedule recurring or future work. Call list_routines first for relative dates or times so you use its authoritative current time and timezone. Convert calendar requests (monthly dates, last days, nth weekdays) into a validated five-field cron schedule with an explicit IANA timeZone; keep elapsed every-N-minutes work as interval. Never approximate unsupported requests with a different weekly schedule or an AI date-check routine; explain the limitation instead. Resolve ambiguous dates, times, timezone, destination, or instructions with the user first, and always give one-time schedules an explicit RFC3339 offset. If the user asks for the routine to run as ANOTHER bot in your section, call list_bots and pass that bot's id as for_bot_id; each run retains that bot's own permissions." + PROPOSAL_OUTCOME,
619
+ description: "Prepare a new routine after the user explicitly asks to schedule recurring or future work. Call list_routines first for relative dates or times so you use its authoritative current time and timezone. Convert calendar requests (monthly dates, last days, nth weekdays) into a validated five-field cron schedule with an explicit IANA timeZone; keep elapsed every-N-minutes work as interval. Never approximate unsupported requests with a different weekly schedule or an AI date-check routine; explain the limitation instead. Resolve ambiguous dates, times, timezone, destination, or instructions with the user first, and always give one-time schedules an explicit RFC3339 offset. If the user asks for the routine to run as ANOTHER bot in your section, call list_bots and pass that bot's id as for_bot_id; each run retains that bot's own permissions." + SELF_CHANGE_OUTCOME,
617
620
  inputSchema: {
618
621
  type: "object",
619
622
  additionalProperties: false,
@@ -629,7 +632,7 @@ const toolDefinitions = (externalRuntime) => [
629
632
  },
630
633
  {
631
634
  name: "propose_routine_action",
632
- description: "Prepare a user-requested change to one of this bot's existing routines. Use list_routines first to get the routine id. If the user asks to change ANOTHER bot's routine and that bot is in your section, call list_bots and pass that bot's id as for_bot_id; the routine keeps its owner and every run keeps that bot's engine and permissions." + PROPOSAL_OUTCOME,
635
+ description: "Prepare a user-requested change to one of this bot's existing routines. Use list_routines first to get the routine id. If the user asks to change ANOTHER bot's routine and that bot is in your section, call list_bots and pass that bot's id as for_bot_id; the routine keeps its owner and every run keeps that bot's engine and permissions." + SELF_CHANGE_OUTCOME,
633
636
  inputSchema: {
634
637
  type: "object",
635
638
  additionalProperties: false,
@@ -656,7 +659,7 @@ const toolDefinitions = (externalRuntime) => [
656
659
  },
657
660
  {
658
661
  name: "propose_profile",
659
- description: "Submit user-requested changes to your own name, title, description, standing instructions (SOUL.md), working folder (cwd), or your alert and voice toggles (notifications, speakReplies). Keep SOUL.md short — who you are and the rules you never break; put step-by-step procedure into a skill instead." + CHIEF_PROFILE_TARGET + PROPOSAL_OUTCOME,
662
+ description: "Submit user-requested changes to your own name, title, description, standing instructions (SOUL.md), working folder (cwd), or your alert and voice toggles (notifications, speakReplies). Keep SOUL.md short — who you are and the rules you never break; put step-by-step procedure into a skill instead." + CHIEF_PROFILE_TARGET + SELF_CHANGE_OUTCOME,
660
663
  inputSchema: {
661
664
  type: "object",
662
665
  additionalProperties: false,
@@ -668,7 +671,7 @@ const toolDefinitions = (externalRuntime) => [
668
671
  cwd: {
669
672
  type: "string",
670
673
  maxLength: 1024,
671
- description: "Absolute path of the folder your tools read and write in (for example /Users/me/Projects/site). It must already exist. An empty string means your private workspace.",
674
+ description: "Absolute path of the folder your tools read and write in (for example /Users/me/Projects/site). It must already exist. An empty string means your private workspace. A new folder waits for the person's confirmation unless this conversation has Full access.",
672
675
  },
673
676
  notifications: {
674
677
  type: "boolean",
@@ -689,7 +692,7 @@ const toolDefinitions = (externalRuntime) => [
689
692
  },
690
693
  {
691
694
  name: "propose_model",
692
- description: "Submit a user-requested switch of this bot's default engine and model. Use the exact instance and model ids the person named, or for a Chief the ids from the team-setup catalog. The card warns about capabilities the switch gains or loses; existing threads keep their current models." + PROPOSAL_OUTCOME,
695
+ description: "Submit a user-requested switch of this bot's default engine and model. Use the exact instance and model ids the person named, or for a Chief the ids from the team-setup catalog. The result warns about capabilities the switch gains or loses; existing threads keep their current models." + SELF_CHANGE_OUTCOME,
693
696
  inputSchema: {
694
697
  type: "object",
695
698
  additionalProperties: false,
@@ -732,12 +735,12 @@ const toolDefinitions = (externalRuntime) => [
732
735
  },
733
736
  {
734
737
  name: "skills_list",
735
- description: "List this bot's imported skills (enabled and disabled) and any staged skill writes waiting for the user to confirm. Use this before skill_manage to avoid duplicate names. Listing does not enable anything.",
738
+ description: "List this bot's imported skills (enabled and disabled) and any staged skill writes still waiting for the user's decision. Use this before skill_manage to avoid duplicate names. Listing does not enable anything.",
736
739
  inputSchema: { type: "object", additionalProperties: false, properties: {} },
737
740
  },
738
741
  {
739
742
  name: "skill_manage",
740
- description: "Submit a new or updated reusable SKILL.md. Never update unless the user explicitly asked to revise that named skill. While review is pending, a create stays inactive and an update leaves the current version unchanged." + PROPOSAL_OUTCOME,
743
+ description: "Submit a new or updated reusable SKILL.md. Never update unless the user explicitly asked to revise that named skill. If the result is pending, a create stays inactive and an update leaves the current version unchanged." + SELF_CHANGE_OUTCOME,
741
744
  inputSchema: {
742
745
  type: "object",
743
746
  additionalProperties: false,
@@ -10,7 +10,7 @@ import { codexToolSurfaceArgs } from "./codex-tool-surface.js";
10
10
  //
11
11
  // resumeCursor is the codex thread id; a later turn tries thread/resume
12
12
  // and preserves that history or reports a failed resume.
13
- import { existsSync, mkdirSync } from "node:fs";
13
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
14
14
  import { createHash } from "node:crypto";
15
15
  import { join } from "node:path";
16
16
  import { homedir } from "node:os";
@@ -23,7 +23,7 @@ import { ChatGptPlanAuthController } from "./chatgpt-plan-auth.js";
23
23
  import { describeSpawnFailure, execCli, killCliTree, spawnCli } from "../procs.js";
24
24
  import { isHarnessOwnedMcpEnvName } from "../mcp-registry.js";
25
25
  import { newEventId, newId } from "../contracts.js";
26
- import { decodeCodexSelection, readCodexModelCatalog, STATIC_CODEX_MODELS } from "./codex-catalog.js";
26
+ import { decodeCodexSelection, OFFICIAL_CODEX_PROVIDER, readCodexModelCatalog, STATIC_CODEX_MODELS } from "./codex-catalog.js";
27
27
  import { codexLocalProviderArgs } from "./local-inject.js";
28
28
  import { augmentedPath, splitCliString } from "../env-path.js";
29
29
  import { classifyError, computeBackoff, interruptibleDelay, RETRY_MAX_ATTEMPTS } from "./retry.js";
@@ -33,7 +33,8 @@ import { commandSummary, toolDetailPreview } from "../tool-summary.js";
33
33
  import { codexDeveloperInstructions, syncCodexInstructions } from "./codex-instructions.js";
34
34
  import { volatileContextNote, withContextNote } from "./prompt-split.js";
35
35
  import { CodexDeviceAuthController } from "./codex-device-auth.js";
36
- import { codexAccountEmail } from "./codex-identity.js";
36
+ import { codexAccountEmail, codexHome } from "./codex-identity.js";
37
+ import { keyRejected, noteKeyAccepted, noteKeyRejected } from "../key-rejections.js";
37
38
  import { classifyResumeFailure, mayReplay, recoveryPromptFor } from "../resume-recovery.js";
38
39
  import { extractMcpImages } from "../mcp-tool-images.js";
39
40
  import { parseProtocolAskQuestions, questionAnswersById, questionChoices } from "../../shared/ask-question.js";
@@ -54,6 +55,30 @@ export function codexUserError(value, chatgptPlan) {
54
55
  }
55
56
  return value.slice(0, 400);
56
57
  }
58
+ // Codex's own words when OpenAI refuses its stored ChatGPT login (codex-cli
59
+ // 0.160 login/src/auth: workspace routing, token refresh, auth storage).
60
+ const CODEX_SIGN_IN_REFUSED = /workspace routing discovery unauthorized|access token could not be refreshed|authentication session could not be refreshed|ChatGPT login is required|auth data is not available|please (?:log out and )?sign in again/i;
61
+ /** A turn error (TurnError: message, codexErrorInfo) that says Codex's own
62
+ * sign-in was refused: `unauthorized`, a 401 from the model backend, or one
63
+ * of Codex's sign-in messages. A 401 from an MCP server or a tool reaches the
64
+ * model as a tool result, never as a turn error, so it cannot land here. */
65
+ export function codexSignInRefused(error) {
66
+ if (!error || typeof error !== "object")
67
+ return false;
68
+ const { message, codexErrorInfo: info } = error;
69
+ if (info === "unauthorized")
70
+ return true;
71
+ if (info && typeof info === "object" &&
72
+ Object.values(info).some((variant) => variant?.httpStatusCode === 401))
73
+ return true;
74
+ return typeof message === "string" && CODEX_SIGN_IN_REFUSED.test(message);
75
+ }
76
+ export const CODEX_SIGN_IN_EXPIRED = "Codex's ChatGPT sign-in has expired. Sign in again in Settings → Model providers → Codex.";
77
+ /** The plain sentence first, so a peer bot's one-line report keeps it;
78
+ * Codex's own words follow as the detail. */
79
+ export function codexSignInExpired(raw) {
80
+ return `${CODEX_SIGN_IN_EXPIRED} Codex said: ${raw.slice(0, 300)}`;
81
+ }
57
82
  class CodexRpcError extends Error {
58
83
  code;
59
84
  constructor(error) {
@@ -605,10 +630,47 @@ export const CodexDriver = {
605
630
  }
606
631
  else
607
632
  await refreshModels();
633
+ // Codex's own ChatGPT login (not ChatGPT plan, whose tokens OpenMausBot
634
+ // holds, nor Company routing) can be refused by OpenAI while `codex login
635
+ // status` still reports it. A refusal marks it the way a rejected API key
636
+ // is marked (key-rejections.ts): its credential home, plus the stored
637
+ // auth file, so a sign-in made anywhere else starts over. A later turn
638
+ // that succeeds, a new sign-in and sign-out clear it. Only a stored
639
+ // ChatGPT login is marked: an API-key login (`codex login --with-api-key`)
640
+ // cannot be fixed by the ChatGPT sign-in Settings offers.
641
+ const ownLogin = !plan && !config.managed;
642
+ const loginMark = () => {
643
+ const home = ownLogin ? codexHome(childEnv()) : null;
644
+ if (!home)
645
+ return null;
646
+ let stored = "";
647
+ try {
648
+ stored = readFileSync(join(home, "auth.json"), "utf8");
649
+ }
650
+ catch {
651
+ return null; /* keyring, or none */
652
+ }
653
+ try {
654
+ const auth = JSON.parse(stored);
655
+ const chatgpt = typeof auth.auth_mode === "string" ? /chatgpt/i.test(auth.auth_mode) : Boolean(auth.tokens);
656
+ if (!chatgpt)
657
+ return null;
658
+ }
659
+ catch {
660
+ return null;
661
+ }
662
+ return [`codex-login:${home}`, stored];
663
+ };
664
+ const loginRefused = () => { const mark = loginMark(); if (mark)
665
+ noteKeyRejected(...mark); };
666
+ const loginAccepted = (mark = loginMark()) => { if (mark)
667
+ noteKeyAccepted(...mark); };
668
+ const loginRejected = () => { const mark = loginMark(); return mark !== null && keyRejected(...mark); };
608
669
  const authentication = new CodexDeviceAuthController({
609
670
  cli: config.cli,
610
671
  environment: childEnv,
611
- onAuthenticated: refreshModels,
672
+ signInRejected: loginRejected,
673
+ onAuthenticated: async () => { loginAccepted(); await refreshModels(); },
612
674
  });
613
675
  const listeners = new Set();
614
676
  const active = new Map();
@@ -690,6 +752,12 @@ export const CodexDriver = {
690
752
  // a retry relaunches the whole app-server; the backoff is scaled down in
691
753
  // tests so a fake's transient failures don't stall real seconds
692
754
  const retryScale = Number(process.env.FAKE_CODEX_RETRY_SCALE ?? "1");
755
+ // Only a turn on the official provider says anything about Codex's
756
+ // ChatGPT login: a custom provider's 401 is its own key's, and its
757
+ // success proves nothing about ChatGPT. No model means the catalog's
758
+ // default, which is provider-qualified when config.toml picks another.
759
+ const chatgptTurn = ownLogin &&
760
+ decodeCodexSelection(turn.model || models.default).modelProvider === OFFICIAL_CODEX_PROVIDER;
693
761
  const launchAttempt = async (attempt) => {
694
762
  const env = childEnv();
695
763
  if (planToken)
@@ -784,6 +852,13 @@ export const CodexDriver = {
784
852
  const state = {
785
853
  settled: false,
786
854
  lastError: "",
855
+ // whether lastError went out marked setup (a sign-in to fix)
856
+ lastErrorSetup: false,
857
+ // an error Codex said it would retry itself (willRetry), kept only
858
+ // to explain a turn that then fails without words of its own
859
+ retryError: "",
860
+ // Codex started recovering its model provider's sign-in this turn
861
+ authRecovery: false,
787
862
  lastText: "",
788
863
  sawStreamDelta: false,
789
864
  // codex reports token usage as a running total for this app-server
@@ -1122,6 +1197,25 @@ export const CodexDriver = {
1122
1197
  message: `Codex automatic review ${outcome}${target}. Action did not run. Retry stays ${retryMode}. Select Ask for human approval in approval settings.`,
1123
1198
  });
1124
1199
  };
1200
+ // The turn's failure, said once. An error notification and the
1201
+ // turn/completed after it usually carry the same words; the second
1202
+ // only speaks again to deliver a sign-in flag the first lacked.
1203
+ // Codex's own refused sign-in reads as one plain sentence and marks
1204
+ // the login, so Settings asks for a new sign-in too.
1205
+ const turnError = (error) => {
1206
+ const raw = String(error.message);
1207
+ const refused = chatgptTurn && loginMark() !== null && (codexSignInRefused(error) ||
1208
+ (state.authRecovery && !/\b403\b|forbidden/i.test(raw) && /\b401\b|unauthorized/i.test(raw)));
1209
+ if (refused)
1210
+ loginRefused();
1211
+ const message = refused ? codexSignInExpired(raw) : codexUserError(raw, plan);
1212
+ const setup = refused || classifyError({ text: message }).reason === "auth";
1213
+ if (message === state.lastError && (state.lastErrorSetup || !setup))
1214
+ return;
1215
+ state.lastError = message;
1216
+ state.lastErrorSetup ||= setup;
1217
+ emit({ ...base(threadId, turnId), type: "runtime.error", message, ...(setup ? { setup: true } : {}) });
1218
+ };
1125
1219
  const handleNotification = (msg) => {
1126
1220
  const p = msg.params ?? {};
1127
1221
  // An app-server also emits notifications for native helper threads.
@@ -1322,27 +1416,43 @@ export const CodexDriver = {
1322
1416
  if (reviewWarning && !timedOutReview)
1323
1417
  reviewNotice("warning");
1324
1418
  const t = p.turn ?? {};
1325
- const message = typeof t.error?.message === "string" ? codexUserError(t.error.message, plan) : "";
1326
- if (t.status !== "completed" && message && message !== state.lastError) {
1327
- state.lastError = message;
1328
- emit({ ...base(threadId, turnId), type: "runtime.error", message,
1329
- ...(classifyError({ text: message }).reason === "auth" ? { setup: true } : {}),
1330
- });
1419
+ if (t.status === "completed") {
1420
+ if (chatgptTurn)
1421
+ loginAccepted();
1422
+ }
1423
+ else if (typeof t.error?.message === "string") {
1424
+ turnError(t.error);
1425
+ }
1426
+ else if (t.status === "failed" && !state.lastError && state.retryError) {
1427
+ // Codex gave up retrying without a final word: its last one
1428
+ turnError({ message: state.retryError });
1331
1429
  }
1332
1430
  void settle(t.status === "completed", t.status === "completed" ? null :
1333
- (classifyError({ text: message || state.lastError }).reason === "provider_safety" ? "provider_safety" : (message || t.status || "failed")));
1431
+ (classifyError({ text: state.lastError }).reason === "provider_safety" ? "provider_safety" : (state.lastError || t.status || "failed")));
1334
1432
  break;
1335
1433
  }
1336
- case "error":
1337
- // shape drift: 0.144 sends {message}, 0.139 nests it under
1338
- // {error:{message}} — surface either (agentcal armor)
1339
- {
1340
- const message = p.message ?? p.error?.message;
1341
- if (message) {
1342
- state.lastError = codexUserError(String(message), plan);
1343
- emit({ ...base(threadId, turnId), type: "runtime.error", message: state.lastError });
1344
- }
1434
+ case "error": {
1435
+ // shape drift: 0.144 sends {message}, 0.139 and 0.160 nest it
1436
+ // under {error:{message, codexErrorInfo}} — surface either
1437
+ // (agentcal armor)
1438
+ const error = p.error && typeof p.error === "object" ? p.error : { message: p.message };
1439
+ if (!error.message)
1440
+ break;
1441
+ // 0.160 reports each of its own reconnects ("Reconnecting...
1442
+ // 1/5") with willRetry: true. Those are not the turn's failure;
1443
+ // the final error, or turn/completed, says how it ended.
1444
+ if (p.willRetry === true) {
1445
+ state.retryError = String(error.message);
1446
+ break;
1345
1447
  }
1448
+ turnError(error);
1449
+ break;
1450
+ }
1451
+ case "modelProvider/authRecoveryStarted":
1452
+ state.authRecovery = true;
1453
+ break;
1454
+ case "modelProvider/authRecoveryCompleted":
1455
+ state.authRecovery = false;
1346
1456
  break;
1347
1457
  }
1348
1458
  };
@@ -1732,8 +1842,10 @@ export const CodexDriver = {
1732
1842
  }
1733
1843
  catch (e) {
1734
1844
  const failure = e instanceof Error ? e : { text: String(e) };
1735
- const message = codexUserError(e instanceof Error ? e.message : String(e), plan);
1736
- const needsAuth = /(?:\b401\b|unauthorized|missing bearer|authentication required)/i.test(message);
1845
+ const raw = e instanceof Error ? e.message : String(e);
1846
+ const refused = chatgptTurn && loginMark() !== null && codexSignInRefused({ message: raw });
1847
+ const message = refused ? codexSignInExpired(raw) : codexUserError(raw, plan);
1848
+ const needsAuth = refused || /(?:\b401\b|unauthorized|missing bearer|authentication required)/i.test(message);
1737
1849
  const verdict = classifyError(failure);
1738
1850
  // Three guards hold here: main's abandoned attempt never retries,
1739
1851
  // neither does a Company session already recovered once from canonical
@@ -1767,6 +1879,8 @@ export const CodexDriver = {
1767
1879
  // abandoned marks an attempt retired by a retry; its late rpc
1768
1880
  // timeouts must neither report a spurious error nor relaunch again
1769
1881
  if (!state.settled && !abandoned) {
1882
+ if (refused)
1883
+ loginRefused();
1770
1884
  emit({
1771
1885
  ...base(threadId, turnId),
1772
1886
  type: "runtime.error",
@@ -1797,6 +1911,11 @@ export const CodexDriver = {
1797
1911
  const authenticated = await new Promise((resolve) => {
1798
1912
  execCli(config.cli, ["login", "status"], { timeout: 8000, env }, (err, stdout, stderr) => resolve(!err && /^logged in\b/im.test(`${stdout}\n${stderr ?? ""}`)));
1799
1913
  });
1914
+ // Signed in as far as the CLI knows, but OpenAI refused it on a real turn.
1915
+ if (authenticated && loginRejected()) {
1916
+ return { state: "available", version, authenticated: false, reason: CODEX_SIGN_IN_EXPIRED,
1917
+ update: await codexReleaseUpdate(version, config.cli), billing: "subscription" };
1918
+ }
1800
1919
  // Display identity only, so Settings can say whose ChatGPT account the
1801
1920
  // bots run on; the status command above stays the authority on sign-in.
1802
1921
  const email = authenticated ? await codexAccountEmail(config.cli, env) : null;
@@ -1837,8 +1956,12 @@ export const CodexDriver = {
1837
1956
  },
1838
1957
  cancelAuthentication: () => (planAuth ?? authentication).cancel(),
1839
1958
  signOut: async () => {
1840
- if (!planAuth)
1841
- return authentication.signOut();
1959
+ if (!planAuth) {
1960
+ const mark = loginMark();
1961
+ await authentication.signOut();
1962
+ loginAccepted(mark);
1963
+ return;
1964
+ }
1842
1965
  planSigningOut = true;
1843
1966
  planGeneration++;
1844
1967
  try {
@@ -85,19 +85,20 @@ export class DeviceAuthController {
85
85
  flow.startupTimer.unref();
86
86
  this.confirm(flow, env, home, (signedIn) => this.finish(flow, signedIn ? "succeeded" : "failed", `${product} finished sign-in but did not confirm a ${account} account. Refresh Settings and try again.`));
87
87
  }, true);
88
- // Never overwrite a working login just because Connect was clicked twice.
88
+ // Never overwrite a working login just because Connect was clicked
89
+ // twice. One the provider refused is not working, whatever status says.
89
90
  if (!status) {
90
91
  login();
91
92
  return;
92
93
  }
93
94
  this.run(flow, [...status.args], env, home, (code, output) => {
94
95
  const state = status.read(code, output);
95
- if (state === "signed-in")
96
+ if (state === "signed-in" && !this.options.signInRejected?.())
96
97
  this.finish(flow, "succeeded");
98
+ else if (state === "signed-in" || state === "signed-out")
99
+ login();
97
100
  else if (state === "other")
98
101
  this.finish(flow, "failed", `${product} already has a different sign-in method on this server. Ask the server administrator to review it before changing accounts.`);
99
- else if (state === "signed-out")
100
- login();
101
102
  else
102
103
  this.finish(flow, "failed", `${product} could not confirm the existing sign-in on this server. Update ${product} and check its login status before trying again.`);
103
104
  });
@@ -755,10 +755,11 @@ export function createOpenAIChatRuntime(options) {
755
755
  if (failure && (!abort.signal.aborted || cleanupFailed)) {
756
756
  emit({ ...base(turn.threadId, turnId), type: "runtime.error", message: failure, terminal: !abort.signal.aborted });
757
757
  }
758
- // Automatic continuity: a resumable terminal (budget cap or tool
759
- // errors) persists a handoff and raises cap.exhausted so the harness
760
- // can start a `Continue:` thread. Interruptions and provider config
761
- // errors are excluded by classifyContinuable.
758
+ // Automatic continuity: a resumable terminal (the step or tool-call
759
+ // cap) persists a handoff and raises cap.exhausted so the harness
760
+ // can start a `Continue:` thread. Interruptions, tool errors and
761
+ // provider errors (a rate limit included) are excluded by
762
+ // classifyContinuable.
762
763
  if (!ok && !abort.signal.aborted) {
763
764
  const continuable = classifyContinuable(stopReason, failure);
764
765
  if (continuable) {