openmausbot 0.1.98 → 0.1.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{ActivityPanel-H6D3SD39.js → ActivityPanel-CA9zfl3_.js} +1 -1
- package/dist/assets/BotSettingsDialog-3i_izROu.js +7 -0
- package/dist/assets/{CloudBackendPicker-iezpJFpF.js → CloudBackendPicker-BR42-xBg.js} +1 -1
- package/dist/assets/{ComputerPanel-DZPj-IWu.js → ComputerPanel-CvThnFmt.js} +1 -1
- package/dist/assets/{DesktopViewer-utONms1p.js → DesktopViewer-CqovWUic.js} +1 -1
- package/dist/assets/InspectorPanel-Cbjm86gt.js +5 -0
- package/dist/assets/{KeyboardShortcutsModal-gk9mvHj_.js → KeyboardShortcutsModal-X13pVrkh.js} +1 -1
- package/dist/assets/{LocalVmWorkspace-DLIvd2kC.js → LocalVmWorkspace-BGD3Tvd3.js} +1 -1
- package/dist/assets/{MacLocalControl-bJv8yiPB.js → MacLocalControl-ExdXHVUv.js} +1 -1
- package/dist/assets/NewBotDialog-ftDBMjWR.js +2 -0
- package/dist/assets/RemoteAgentSettingsPanel-BUHLV_vC.js +1 -0
- package/dist/assets/RoutinesPage-Buk5-r3o.js +1 -0
- package/dist/assets/{RoutinesSection-Dny9ra-c.js → RoutinesSection-NyReOXr8.js} +1 -1
- package/dist/assets/{SettingsModal-gC6XJJmt.js → SettingsModal-DkkhdxKM.js} +3 -3
- package/dist/assets/{TeamMapPage-B6fuu4r_.js → TeamMapPage-BIxeHoy3.js} +1 -1
- package/dist/assets/{TriggersPanel-j0qTP2CO.js → TriggersPanel-m5iqc43H.js} +1 -1
- package/dist/assets/{VisibilitySection-DT0FqPvu.js → VisibilitySection-y8Adk-c4.js} +1 -1
- package/dist/assets/WebhooksPanel-G_NWjHOP.js +3 -0
- package/dist/assets/{abnfDiagram-O67JEVCF-BsjcFX0-.js → abnfDiagram-O67JEVCF-D56ZgyPf.js} +1 -1
- package/dist/assets/{activity-BxOkayvD.js → activity-D_puBfZo.js} +1 -1
- package/dist/assets/{arc-CJNA94c6.js → arc-DzduGHbq.js} +1 -1
- package/dist/assets/{architectureDiagram-NJMV4G6O-dz2ud7lP.js → architectureDiagram-NJMV4G6O-C4NS6DQF.js} +1 -1
- package/dist/assets/{blockDiagram-BEXU5L5S-ChBEALoR.js → blockDiagram-BEXU5L5S-BNvsskiE.js} +1 -1
- package/dist/assets/{brain-CFZ7PEXc.js → brain-oq48IgWl.js} +1 -1
- package/dist/assets/{c4Diagram-YGBWAQC7-KZNRKDQe.js → c4Diagram-YGBWAQC7-ch3B7xZy.js} +1 -1
- package/dist/assets/channel-CmFDMHrN.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-BLLwmCET.js → chunk-2Q5K7J3B-D9dL9ZS7.js} +1 -1
- package/dist/assets/{chunk-3FUC2YCW-CQxyreBZ.js → chunk-3FUC2YCW-DmLUUuNr.js} +2 -2
- package/dist/assets/{chunk-5VM5RSS4-D6sFMW0u.js → chunk-5VM5RSS4-B90ODeo2.js} +1 -1
- package/dist/assets/{chunk-GTNCS2PH-BaZ1YgLF.js → chunk-GTNCS2PH-BtlGIG3W.js} +1 -1
- package/dist/assets/{chunk-GWA4HPMP-CcalphmC.js → chunk-GWA4HPMP-CurBwFFG.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-CSk8R3ve.js → chunk-JWPE2WC7-DTjNNXcd.js} +1 -1
- package/dist/assets/{chunk-NETBCI7D-CTmLjA57.js → chunk-NETBCI7D-xS7hOqBJ.js} +1 -1
- package/dist/assets/{chunk-WEXAMYUT-CM9Z77Ne.js → chunk-WEXAMYUT-DJZBSyA9.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-B1fxpMS2.js → chunk-XXDRQBXY-CbiNRzjt.js} +1 -1
- package/dist/assets/{classDiagram-v2-NBCMYWYE-DCCyoLpj.js → classDiagram-v2-NBCMYWYE-DyON9tUb.js} +1 -1
- package/dist/assets/core-CRkAXD3N.js +12 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-KyImBKvE.js → cose-bilkent-JH36ORCC-C7UwNnp8.js} +1 -1
- package/dist/assets/cpp-DddhVWhK.js +1 -0
- package/dist/assets/{cynefin-OW5HDTMX-fsZc6MGa.js → cynefin-OW5HDTMX-Dv1GTekc.js} +1 -1
- package/dist/assets/{cynefinDiagram-VND7K2PF-CGmHsShB.js → cynefinDiagram-VND7K2PF-CKgpyZxo.js} +1 -1
- package/dist/assets/{dagre-6A5THRUB-Dah1h-CH.js → dagre-6A5THRUB-BY3cYc8R.js} +1 -1
- package/dist/assets/{diagram-22UHCM2B-BIu71OyV.js → diagram-22UHCM2B-D71jBFCO.js} +1 -1
- package/dist/assets/{diagram-3UASUU5V-gxhUB_Mu.js → diagram-3UASUU5V-Bc3i6JGD.js} +1 -1
- package/dist/assets/{diagram-ATOU4E4O-CBhusUBn.js → diagram-ATOU4E4O-BPDSHISG.js} +1 -1
- package/dist/assets/{diagram-CDSNMT55-BdPrc86x.js → diagram-CDSNMT55-xuCT1v32.js} +1 -1
- package/dist/assets/{diagram-MLGK6HIB-Clp110R_.js → diagram-MLGK6HIB-LEDTXDPg.js} +1 -1
- package/dist/assets/{diagram-MPIPVDR6-DJKfbugw.js → diagram-MPIPVDR6-B0kfscRD.js} +1 -1
- package/dist/assets/{ebnfDiagram-ZINNZB2B-DnsltoBu.js → ebnfDiagram-ZINNZB2B-B-Z0HLzJ.js} +1 -1
- package/dist/assets/{elk-276RUBZZ-jWdq6gqH.js → elk-276RUBZZ-Bzypn7lU.js} +1 -1
- package/dist/assets/engine-javascript-D5Xfc425.js +141 -0
- package/dist/assets/{erDiagram-OPXOYQCR-DArPVf8u.js → erDiagram-OPXOYQCR-vl1xKmbS.js} +1 -1
- package/dist/assets/{flowDiagram-KWPJA3E3-D2HZ-2f7.js → flowDiagram-KWPJA3E3-DQXCXm7z.js} +1 -1
- package/dist/assets/{ganttDiagram-FUAMR5RP--o0KIxEo.js → ganttDiagram-FUAMR5RP-B0wwnP2j.js} +1 -1
- package/dist/assets/{gitGraphDiagram-X574FWY7-CsoXr2D7.js → gitGraphDiagram-X574FWY7-HfEVZRuR.js} +1 -1
- package/dist/assets/{image-plus-BbVjGHin.js → image-plus-D9o3v9bi.js} +1 -1
- package/dist/assets/{index-C3NqfdVU.js → index-CyM91z0J.js} +205 -205
- package/dist/assets/{index-BrPW5HDO.css → index-DbN_Hfjs.css} +1 -1
- package/dist/assets/{infoDiagram-VRGFBTTK-g-6lNp7r.js → infoDiagram-VRGFBTTK-BcCklxlu.js} +1 -1
- package/dist/assets/{ishikawaDiagram-OU5B5YK6-B1d6qVTV.js → ishikawaDiagram-OU5B5YK6-Bw7Fp8yZ.js} +1 -1
- package/dist/assets/{journeyDiagram-ZHPQQLJL-BTPuiU6T.js → journeyDiagram-ZHPQQLJL-BqFaTPiB.js} +1 -1
- package/dist/assets/{kanban-definition-PNTS6WVX-bDDuRJvP.js → kanban-definition-PNTS6WVX-BdGyimUh.js} +1 -1
- package/dist/assets/{linear-BVVKbEMy.js → linear-DezKjgv7.js} +1 -1
- package/dist/assets/{mermaid.core-JJdoKyKB.js → mermaid.core-97L7xtx0.js} +5 -5
- package/dist/assets/{mindmap-definition-NLK3R4M7-B4aE3T0q.js → mindmap-definition-NLK3R4M7-DP6qz87C.js} +1 -1
- package/dist/assets/{page-visible-BBo_Zm8g.js → page-visible-BehtKJDm.js} +1 -1
- package/dist/assets/{pegDiagram-GJSIUBJH-DFKQWpR7.js → pegDiagram-GJSIUBJH-CsYSloVz.js} +1 -1
- package/dist/assets/{pieDiagram-5QR66LMP-Iv7OKVJi.js → pieDiagram-5QR66LMP-CFI2Dcix.js} +1 -1
- package/dist/assets/{quadrantDiagram-O4NWA36T-U2YnfwBk.js → quadrantDiagram-O4NWA36T-DqTdAE5z.js} +1 -1
- package/dist/assets/{railroadDiagram-XR7U4H2S-CuPy6RqM.js → railroadDiagram-XR7U4H2S-t_rszRIF.js} +1 -1
- package/dist/assets/{remote-desktop-panel-BNEj7tUx.js → remote-desktop-panel-WTaz_HI9.js} +1 -1
- package/dist/assets/{requirementDiagram-PLB6GJNP-bMI5AK7T.js → requirementDiagram-PLB6GJNP-1MU-l7p8.js} +1 -1
- package/dist/assets/ruby-Ct1eTYOr.js +1 -0
- package/dist/assets/{sankeyDiagram-IPEJSGJF-BKcFE2WQ.js → sankeyDiagram-IPEJSGJF-CtkrwAvo.js} +1 -1
- package/dist/assets/{sequenceDiagram-PO4LG4MO-Bn9q88kl.js → sequenceDiagram-PO4LG4MO-CJOwBubv.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-Cvmdq9HD.js → sizeCapture-INFHLROL-DhQVhKCc.js} +1 -1
- package/dist/assets/{stateDiagram-v2-GCMORJYK-JJQYw3eQ.js → stateDiagram-v2-GCMORJYK-CaQK9yA9.js} +1 -1
- package/dist/assets/{swimlanes-2SLR337P-BkSCBEwp.js → swimlanes-2SLR337P-Ct8cqf01.js} +1 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-BBUcFKOA.js +8 -0
- package/dist/assets/{timeline-definition-EJHVYXUP-DsaM4GHr.js → timeline-definition-EJHVYXUP-qim2Km3q.js} +1 -1
- package/dist/assets/{usecaseDiagram-POWQR4AR-3FOwLq7B.js → usecaseDiagram-POWQR4AR-BIzcxmgX.js} +1 -1
- package/dist/assets/{user-DcZBnAuv.js → user-EQ8rI0f4.js} +1 -1
- package/dist/assets/{vennDiagram-UO4OBE2U-DyNjJsKt.js → vennDiagram-UO4OBE2U-BFEuz8Ba.js} +1 -1
- package/dist/assets/{wardleyDiagram-VNRHLVJA-Y4ZMcnBC.js → wardleyDiagram-VNRHLVJA-JRkAN01c.js} +1 -1
- package/dist/assets/{xychartDiagram-PMCCYNJV-BXZpg955.js → xychartDiagram-PMCCYNJV-WBsvmu0R.js} +1 -1
- package/dist/index.html +2 -2
- package/dist-server/drivers/agents-proxy.js +10 -9
- package/dist-server/index.js +1483 -813
- package/dist-server/openmausbot.js +248 -152
- package/dist-server/pair-cli.js +248 -152
- package/dist-server/server/activity.js +2 -0
- package/dist-server/server/checkpoints.js +55 -39
- package/dist-server/server/direct-apply.js +20 -0
- package/dist-server/server/drivers/agents-call.js +1 -1
- package/dist-server/server/drivers/agents-catalog.js +11 -8
- package/dist-server/server/drivers/codex.js +147 -24
- package/dist-server/server/drivers/device-auth.js +5 -4
- package/dist-server/server/drivers/openai-chat.js +5 -4
- package/dist-server/server/harness/registry.js +63 -45
- package/dist-server/server/index.js +203 -23
- package/dist-server/server/mcp-oauth.js +125 -47
- package/dist-server/server/mcp-probe.js +18 -10
- package/dist-server/server/message-file.js +95 -3
- package/dist-server/server/model-requests.js +55 -4
- package/dist-server/server/profile-requests.js +80 -4
- package/dist-server/server/request-auth.js +1 -0
- package/dist-server/server/routes/undo.js +17 -0
- package/dist-server/server/routine-requests.js +210 -6
- package/dist-server/server/setup-mode.js +1 -1
- package/dist-server/server/skill-learn.js +2 -2
- package/dist-server/server/skills.js +30 -0
- package/dist-server/server/system-prompt.js +1 -1
- package/dist-server/server/turn-continuation.js +13 -18
- package/dist-server/server/workspace-backup.js +6 -1
- package/dist-server/workspace-backup.worker.js +1 -1
- package/package.json +1 -1
- package/skills/create-verification-skill/SKILL.md +9 -8
- package/skills/create-verification-skill/manifest.json +1 -1
- package/dist/assets/BotSettingsDialog-Dqz_AiBZ.js +0 -7
- package/dist/assets/InspectorPanel-OVaBVrzC.js +0 -5
- package/dist/assets/NewBotDialog-1qGOAdUM.js +0 -2
- package/dist/assets/RemoteAgentSettingsPanel-DqKr0HkO.js +0 -1
- package/dist/assets/RoutinesPage-BM2D4qGi.js +0 -1
- package/dist/assets/WebhooksPanel--YQyCjKO.js +0 -3
- package/dist/assets/abap-BdImnpbu.js +0 -1
- package/dist/assets/actionscript-3-B3316cI-.js +0 -1
- package/dist/assets/ada-bCR0ucgS.js +0 -1
- package/dist/assets/ahk-CsyLZFj1.js +0 -1
- package/dist/assets/ahk2-8Zs4aa1G.js +0 -1
- package/dist/assets/andromeeda-C4gqWexZ.js +0 -1
- package/dist/assets/angular-html-DA-rfuFy.js +0 -1
- package/dist/assets/angular-ts-BrjP3tb8.js +0 -1
- package/dist/assets/apache-Pmp26Uib.js +0 -1
- package/dist/assets/apex-DhZFqWV2.js +0 -1
- package/dist/assets/apl-CORt7UWP.js +0 -1
- package/dist/assets/applescript-Co6uUVPk.js +0 -1
- package/dist/assets/ara-BRHolxvo.js +0 -1
- package/dist/assets/asciidoc-CSVQ5wI8.js +0 -1
- package/dist/assets/asm-D_Q5rh1f.js +0 -1
- package/dist/assets/astro-HNnZUWAn.js +0 -1
- package/dist/assets/aurora-x-D-2ljcwZ.js +0 -1
- package/dist/assets/awk-DMzUqQB5.js +0 -1
- package/dist/assets/ayu-dark-DYE7WIF3.js +0 -1
- package/dist/assets/ayu-light-BA47KaF1.js +0 -1
- package/dist/assets/ayu-mirage-32ctXXKs.js +0 -1
- package/dist/assets/ballerina-BFfxhgS-.js +0 -1
- package/dist/assets/bat-CickPsom.js +0 -1
- package/dist/assets/beancount-k_qm7-4y.js +0 -1
- package/dist/assets/berry-uYugtg8r.js +0 -1
- package/dist/assets/bibtex-CHM0blh-.js +0 -1
- package/dist/assets/bicep-Bmn6On1c.js +0 -1
- package/dist/assets/bird2-Bx8U0n9b.js +0 -1
- package/dist/assets/blade-2xfisSek.js +0 -1
- package/dist/assets/bsl-DlhNcFeZ.js +0 -1
- package/dist/assets/c3-Dp5svz6Z.js +0 -1
- package/dist/assets/cadence-Bv_4Rxtq.js +0 -1
- package/dist/assets/cairo-KRGpt6FW.js +0 -1
- package/dist/assets/catppuccin-frappe-CZL1YF0i.js +0 -1
- package/dist/assets/catppuccin-latte-DH-8KZSZ.js +0 -1
- package/dist/assets/catppuccin-macchiato-B7yYVSCf.js +0 -1
- package/dist/assets/catppuccin-mocha-Ct7hS0mc.js +0 -1
- package/dist/assets/channel-WhFyujhZ.js +0 -1
- package/dist/assets/chapel-DTp_pixX.js +0 -1
- package/dist/assets/clarity-Dn5IMItf.js +0 -1
- package/dist/assets/clojure-P80f7IUj.js +0 -1
- package/dist/assets/cmake-D1j8_8rp.js +0 -1
- package/dist/assets/cobol-nBiQ_Alo.js +0 -1
- package/dist/assets/codeowners-Bp6g37R7.js +0 -1
- package/dist/assets/codeql-DsOJ9woJ.js +0 -1
- package/dist/assets/coffee-Ch7k5sss.js +0 -1
- package/dist/assets/common-lisp-Cg-RD9OK.js +0 -1
- package/dist/assets/coq-C7JzOVbR.js +0 -1
- package/dist/assets/cpp-BMRokrvK.js +0 -1
- package/dist/assets/crystal-DGywbUpC.js +0 -1
- package/dist/assets/csv-fuZLfV_i.js +0 -1
- package/dist/assets/cue-D82EKSYY.js +0 -1
- package/dist/assets/cypher-COkxafJQ.js +0 -1
- package/dist/assets/d-85-TOEBH.js +0 -1
- package/dist/assets/dark-plus-C3mMm8J8.js +0 -1
- package/dist/assets/dax-CEL-wOlO.js +0 -1
- package/dist/assets/desktop-BmXAJ9_W.js +0 -1
- package/dist/assets/dotenv-Da5cRb03.js +0 -1
- package/dist/assets/dracula-BzJJZx-M.js +0 -1
- package/dist/assets/dracula-soft-BXkSAIEj.js +0 -1
- package/dist/assets/dream-maker-BtqSS_iP.js +0 -1
- package/dist/assets/edge-FbVlp4U3.js +0 -1
- package/dist/assets/elixir-CkH2-t6x.js +0 -1
- package/dist/assets/elm-DbKCFpqz.js +0 -1
- package/dist/assets/emacs-lisp-C_m_b--Z.js +0 -1
- package/dist/assets/erb-DXfck5VN.js +0 -1
- package/dist/assets/erlang-DsQrWhSR.js +0 -1
- package/dist/assets/everforest-dark-BgDCqdQA.js +0 -1
- package/dist/assets/everforest-light-C8M2exoo.js +0 -1
- package/dist/assets/fennel-BYunw83y.js +0 -1
- package/dist/assets/fluent-C4IJs8-o.js +0 -1
- package/dist/assets/fortran-fixed-form-CkoXwp7k.js +0 -1
- package/dist/assets/fortran-free-form-BxgE0vQu.js +0 -1
- package/dist/assets/fsharp-CXgrBDvD.js +0 -1
- package/dist/assets/gdresource-TyuKm33G.js +0 -1
- package/dist/assets/gdscript-DqcFQ5yU.js +0 -1
- package/dist/assets/gdshader-DkwncUOv.js +0 -1
- package/dist/assets/genie-D0YGMca9.js +0 -1
- package/dist/assets/gherkin-DyxjwDmM.js +0 -1
- package/dist/assets/git-commit-F4YmCXRG.js +0 -1
- package/dist/assets/git-rebase-r7XF79zn.js +0 -1
- package/dist/assets/github-dark-DHJKELXO.js +0 -1
- package/dist/assets/github-dark-dimmed-DH5Ifo-i.js +0 -1
- package/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -1
- package/dist/assets/github-light-DAi9KRSo.js +0 -1
- package/dist/assets/github-light-high-contrast-BfjtVDDH.js +0 -1
- package/dist/assets/gleam-BspZqrRM.js +0 -1
- package/dist/assets/glimmer-js-ByusRIyA.js +0 -1
- package/dist/assets/glimmer-ts-BfAWNZQY.js +0 -1
- package/dist/assets/glsl-DplSGwfg.js +0 -1
- package/dist/assets/gn-n2N0HUVH.js +0 -1
- package/dist/assets/gnuplot-DdkO51Og.js +0 -1
- package/dist/assets/groovy-gcz8RCvz.js +0 -1
- package/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -1
- package/dist/assets/gruvbox-dark-medium-GsRaNv29.js +0 -1
- package/dist/assets/gruvbox-dark-soft-CVdnzihN.js +0 -1
- package/dist/assets/gruvbox-light-hard-CH1njM8p.js +0 -1
- package/dist/assets/gruvbox-light-medium-DRw_LuNl.js +0 -1
- package/dist/assets/gruvbox-light-soft-hJgmCMqR.js +0 -1
- package/dist/assets/hack-BWmVpMyf.js +0 -1
- package/dist/assets/haml-D5jkg6IW.js +0 -1
- package/dist/assets/handlebars-BpdQsYii.js +0 -1
- package/dist/assets/haskell-Df6bDoY_.js +0 -1
- package/dist/assets/haxe-CfZj7gIn.js +0 -1
- package/dist/assets/hcl-BWvSN4gD.js +0 -1
- package/dist/assets/hjson-D5-asLiD.js +0 -1
- package/dist/assets/hlsl-D3lLCCz7.js +0 -1
- package/dist/assets/horizon-BUw7H-hv.js +0 -1
- package/dist/assets/horizon-bright-CUuTKBJd.js +0 -1
- package/dist/assets/houston-DnULxvSX.js +0 -1
- package/dist/assets/html-derivative-DlHx6ybY.js +0 -1
- package/dist/assets/http-jrhK8wxY.js +0 -1
- package/dist/assets/hurl-irOxFIW8.js +0 -1
- package/dist/assets/hxml-2-FPmUDs.js +0 -1
- package/dist/assets/hy-DFXneXwc.js +0 -1
- package/dist/assets/imba-DGztddWO.js +0 -1
- package/dist/assets/index-CJTp9JEp.js +0 -153
- package/dist/assets/ini-BEwlwnbL.js +0 -1
- package/dist/assets/jinja-f2NsQr07.js +0 -1
- package/dist/assets/jison-wvAkD_A8.js +0 -1
- package/dist/assets/jsonl-DcaNXYhu.js +0 -1
- package/dist/assets/jsonnet-DFQXde-d.js +0 -1
- package/dist/assets/jssm-C2t-YnRu.js +0 -1
- package/dist/assets/julia-5Bft2YPA.js +0 -1
- package/dist/assets/just-Cwhn7H3k.js +0 -1
- package/dist/assets/kanagawa-dragon-BuwD2xS4.js +0 -1
- package/dist/assets/kanagawa-lotus-C3DzagqV.js +0 -1
- package/dist/assets/kanagawa-wave-DFGoQZhC.js +0 -1
- package/dist/assets/kdl-DV7GczEv.js +0 -1
- package/dist/assets/kusto-wEQ09or8.js +0 -1
- package/dist/assets/laserwave-DUszq2jm.js +0 -1
- package/dist/assets/latex-D5pSuvFb.js +0 -1
- package/dist/assets/lean-BZvkOJ9d.js +0 -1
- package/dist/assets/light-plus-B7mTdjB0.js +0 -1
- package/dist/assets/liquid-C0sCDyMI.js +0 -1
- package/dist/assets/llvm-BZoOZj88.js +0 -1
- package/dist/assets/log-2UxHyX5q.js +0 -1
- package/dist/assets/logo-BtOb2qkB.js +0 -1
- package/dist/assets/luau-BnpPk5vE.js +0 -1
- package/dist/assets/marko-DjSrsDqO.js +0 -1
- package/dist/assets/material-theme-D5KoaKCx.js +0 -1
- package/dist/assets/material-theme-darker-BfHTSMKl.js +0 -1
- package/dist/assets/material-theme-lighter-B0m2ddpp.js +0 -1
- package/dist/assets/material-theme-ocean-CyktbL80.js +0 -1
- package/dist/assets/material-theme-palenight-Csfq5Kiy.js +0 -1
- package/dist/assets/matlab-D7o27uSR.js +0 -1
- package/dist/assets/mdc-D1_yUvq7.js +0 -1
- package/dist/assets/mermaid-CQcHuHx7.js +0 -1
- package/dist/assets/min-dark-CafNBF8u.js +0 -1
- package/dist/assets/min-light-CTRr51gU.js +0 -1
- package/dist/assets/mipsasm-CKIfxQSi.js +0 -1
- package/dist/assets/mojo-DJz3ZmWd.js +0 -1
- package/dist/assets/monokai-BRVnQi9A.js +0 -1
- package/dist/assets/moonbit-CHtswR0a.js +0 -1
- package/dist/assets/move-el3G9tDJ.js +0 -1
- package/dist/assets/narrat-DRg8JJMk.js +0 -1
- package/dist/assets/nextflow-C-mBbutL.js +0 -1
- package/dist/assets/nextflow-groovy-vE_lwT2v.js +0 -1
- package/dist/assets/nginx-BpAMiNFr.js +0 -1
- package/dist/assets/night-owl-C39BiMTA.js +0 -1
- package/dist/assets/night-owl-light-CMTm3GFP.js +0 -1
- package/dist/assets/nim-BIad80T-.js +0 -1
- package/dist/assets/nix-CwoSXNpI.js +0 -1
- package/dist/assets/nord-Ddv68eIx.js +0 -1
- package/dist/assets/nsis-BlV79W_Q.js +0 -1
- package/dist/assets/nushell-D3jzshHO.js +0 -1
- package/dist/assets/objective-c-DXmwc3jG.js +0 -1
- package/dist/assets/objective-cpp-CLxacb5B.js +0 -1
- package/dist/assets/ocaml-C0hk2d4L.js +0 -1
- package/dist/assets/odin-BBf5iR-q.js +0 -1
- package/dist/assets/one-dark-pro-DVMEJ2y_.js +0 -1
- package/dist/assets/one-light-C3Wv6jpd.js +0 -1
- package/dist/assets/openscad-C4EeE6gA.js +0 -1
- package/dist/assets/org-DM6o9KBp.js +0 -1
- package/dist/assets/pascal-D93ZcfNL.js +0 -1
- package/dist/assets/perl-B9cMNwum.js +0 -1
- package/dist/assets/pkl-u5AG7uiY.js +0 -1
- package/dist/assets/plastic-3e1v2bzS.js +0 -1
- package/dist/assets/plsql-ChMvpjG-.js +0 -1
- package/dist/assets/po-BTJTHyun.js +0 -1
- package/dist/assets/poimandres-CS3Unz2-.js +0 -1
- package/dist/assets/polar-C0HS_06l.js +0 -1
- package/dist/assets/postcss-CXtECtnM.js +0 -1
- package/dist/assets/powerquery-CEu0bR-o.js +0 -1
- package/dist/assets/prisma-Vru482bI.js +0 -1
- package/dist/assets/prolog-CbFg5uaA.js +0 -1
- package/dist/assets/pug-DKIMFp6K.js +0 -1
- package/dist/assets/puppet-BMWR74SV.js +0 -1
- package/dist/assets/purescript-CklMAg4u.js +0 -1
- package/dist/assets/qml-3beO22l8.js +0 -1
- package/dist/assets/qmldir-C8lEn-DE.js +0 -1
- package/dist/assets/qss-IeuSbFQv.js +0 -1
- package/dist/assets/racket-BqYA7rlc.js +0 -1
- package/dist/assets/raku-DXvB9xmW.js +0 -1
- package/dist/assets/razor-BjBPvh-w.js +0 -1
- package/dist/assets/rbs-CpoqiR4B.js +0 -1
- package/dist/assets/red-hvxz__6c.js +0 -1
- package/dist/assets/reg-C-SQnVFl.js +0 -1
- package/dist/assets/regexp-CDVJQ6XC.js +0 -1
- package/dist/assets/rel-C3B-1QV4.js +0 -1
- package/dist/assets/riscv-BM1_JUlF.js +0 -1
- package/dist/assets/ron-D8l8udqQ.js +0 -1
- package/dist/assets/rose-pine-5qJOZa0Y.js +0 -1
- package/dist/assets/rose-pine-dawn-zx0QlTCp.js +0 -1
- package/dist/assets/rose-pine-moon-C9pEdX9L.js +0 -1
- package/dist/assets/rosmsg-BJDFO7_C.js +0 -1
- package/dist/assets/rst-bs7f0vWN.js +0 -1
- package/dist/assets/ruby-C0TQ7zu5.js +0 -1
- package/dist/assets/sas-DEy46yEz.js +0 -1
- package/dist/assets/scala-CqE71os6.js +0 -1
- package/dist/assets/scheme-C98Dy4si.js +0 -1
- package/dist/assets/sdbl-DVxCFoDh.js +0 -1
- package/dist/assets/shaderlab-Dg9Lc6iA.js +0 -1
- package/dist/assets/shellsession-BADoaaVG.js +0 -1
- package/dist/assets/slack-dark-BthQWCQV.js +0 -1
- package/dist/assets/slack-ochin-DqwNpetd.js +0 -1
- package/dist/assets/smalltalk-BOQMe2GC.js +0 -1
- package/dist/assets/smithy-cds9vsN8.js +0 -1
- package/dist/assets/snazzy-light-Bw305WKR.js +0 -1
- package/dist/assets/solarized-dark-CpvCGNkr.js +0 -1
- package/dist/assets/solarized-light-Dlz6yCKv.js +0 -1
- package/dist/assets/solidity-DijEV5ha.js +0 -1
- package/dist/assets/soy-8wufbnw4.js +0 -1
- package/dist/assets/sparql-rVzFXLq3.js +0 -1
- package/dist/assets/splunk-BtCnVYZw.js +0 -1
- package/dist/assets/ssh-config-_ykCGR6B.js +0 -1
- package/dist/assets/stata-DI20mbqo.js +0 -1
- package/dist/assets/stylus-BEDo0Tqx.js +0 -1
- package/dist/assets/surrealql-Cjom0U5J.js +0 -1
- package/dist/assets/svelte-Cy7k_4gC.js +0 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-CmTirbVT.js +0 -8
- package/dist/assets/synthwave-84-CbfX1IO0.js +0 -1
- package/dist/assets/system-verilog-0hqHdDBg.js +0 -1
- package/dist/assets/systemd-4A_iFExJ.js +0 -1
- package/dist/assets/talonscript-CkByrt1z.js +0 -1
- package/dist/assets/tasl-QIJgUcNo.js +0 -1
- package/dist/assets/tcl-dwOrl1Do.js +0 -1
- package/dist/assets/templ-DhtptRzy.js +0 -1
- package/dist/assets/terraform-BETggiCN.js +0 -1
- package/dist/assets/tex-D96PA37w.js +0 -1
- package/dist/assets/tokyo-night-hegEt444.js +0 -1
- package/dist/assets/ts-tags-D351s5mN.js +0 -1
- package/dist/assets/tsv-B_m7g4N7.js +0 -1
- package/dist/assets/turtle-BsS91CYL.js +0 -1
- package/dist/assets/twig-27uCiNez.js +0 -1
- package/dist/assets/typespec-CAFt9gP4.js +0 -1
- package/dist/assets/typst-BUadGCkm.js +0 -1
- package/dist/assets/v-BGw2Nkan.js +0 -1
- package/dist/assets/vala-CsfeWuGM.js +0 -1
- package/dist/assets/vb-Cu-pLBUe.js +0 -1
- package/dist/assets/verilog-nZwndyjY.js +0 -1
- package/dist/assets/vesper-DRje8inN.js +0 -1
- package/dist/assets/vhdl-CeAyd5Ju.js +0 -1
- package/dist/assets/viml-CJc9bBzg.js +0 -1
- package/dist/assets/vitesse-black-Bkuqu6BP.js +0 -1
- package/dist/assets/vitesse-dark-D0r3Knsf.js +0 -1
- package/dist/assets/vitesse-light-CVO1_9PV.js +0 -1
- package/dist/assets/vue-BqiEGhQt.js +0 -1
- package/dist/assets/vue-html-AaS7Mt5G.js +0 -1
- package/dist/assets/vue-vine-BoDAl6tE.js +0 -1
- package/dist/assets/vyper-CDx5xZoG.js +0 -1
- package/dist/assets/wasm-CG6Dc4jp.js +0 -1
- package/dist/assets/wenyan-BV7otONQ.js +0 -1
- package/dist/assets/wgsl-Dx-B1_4e.js +0 -1
- package/dist/assets/wikitext-BhOHFoWU.js +0 -1
- package/dist/assets/wit-5i3qLPDT.js +0 -1
- package/dist/assets/wolfram-lXgVvXCa.js +0 -1
- package/dist/assets/xsl-CtQFsRM5.js +0 -1
- package/dist/assets/zenscript-DVFEvuxE.js +0 -1
- package/dist/assets/zig-VOosw3JB.js +0 -1
- /package/dist/assets/{shellscript-Yzrsuije.js → bash-Yzrsuije.js} +0 -0
- /package/dist/assets/{docker-BcOcwvcX.js → dockerfile-BcOcwvcX.js} +0 -0
- /package/dist/assets/{make-CHLpvVh8.js → makefile-CHLpvVh8.js} +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PASS } from "./table.js";
|
|
2
|
+
export function createUndoRoutes(deps) {
|
|
3
|
+
return async ({ req, res, path, method, auth, json, readBody }) => {
|
|
4
|
+
const m = path.match(/^\/api\/threads\/([\w-]+)\/undo$/);
|
|
5
|
+
if (!m || method !== "POST")
|
|
6
|
+
return PASS;
|
|
7
|
+
const threadId = m[1];
|
|
8
|
+
const body = await readBody(req);
|
|
9
|
+
const requestId = typeof body?.requestId === "string" ? body.requestId : "";
|
|
10
|
+
if (!requestId)
|
|
11
|
+
return json(res, 400, { error: "requestId is required" });
|
|
12
|
+
const refusal = deps.refusal(auth, threadId, requestId);
|
|
13
|
+
if (refusal)
|
|
14
|
+
return json(res, 403, { error: refusal });
|
|
15
|
+
deps.undo(auth, res, threadId, requestId);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -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
|
-
//
|
|
982
|
-
const
|
|
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
|
-
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
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
|
-
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
|
|
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.
|
|
92
|
-
*
|
|
93
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: create-verification-skill
|
|
3
|
-
description: "Create one
|
|
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
|
|
9
|
-
|
|
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.
|
|
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`
|
|
63
|
-
|
|
64
|
-
|
|
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": "
|
|
5
|
+
"description": "Write one verification skill for a specific app or project.",
|
|
6
6
|
"defaultEnabled": true,
|
|
7
7
|
"triggerTerms": [
|
|
8
8
|
"/create-verification-skill",
|