openmausbot 0.1.97 → 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.
- package/dist/assets/ActivityPanel-CgUgtumZ.js +1 -0
- package/dist/assets/BotSettingsDialog-lJj6oiir.js +7 -0
- package/dist/assets/CloudBackendPicker-C5-_arUz.js +1 -0
- package/dist/assets/ComputerPanel-euJ2CSlH.js +1 -0
- package/dist/assets/DesktopViewer-XCln1Pn_.js +5 -0
- package/dist/assets/InspectorPanel-DKYyQZlo.js +5 -0
- package/dist/assets/KeyboardShortcutsModal-DkkZWZRI.js +1 -0
- package/dist/assets/LocalVmWorkspace-Cwt3_XSx.js +1 -0
- package/dist/assets/MacLocalControl-B28RbdCS.js +1 -0
- package/dist/assets/NewBotDialog-dMWDs5xm.js +2 -0
- package/dist/assets/RemoteAgentSettingsPanel-B5KWXnqH.js +1 -0
- package/dist/assets/RoutinesPage-DOosRYDK.js +1 -0
- package/dist/assets/RoutinesSection-uOfOTfkB.js +1 -0
- package/dist/assets/SettingsModal-BTGkFbj1.js +11 -0
- package/dist/assets/TeamMapPage-DqNdJn96.js +8 -0
- package/dist/assets/TriggersPanel-c6xkG9mi.js +1 -0
- package/dist/assets/VisibilitySection-DD4ffIR5.js +12 -0
- package/dist/assets/WebhooksPanel-Cz17K-_O.js +3 -0
- package/dist/assets/{abnfDiagram-O67JEVCF-k1UCNXb7.js → abnfDiagram-O67JEVCF-CX6tDpkg.js} +1 -1
- package/dist/assets/activity-BAVWO0Zj.js +1 -0
- package/dist/assets/{arc-BUWGa9UU.js → arc-h45-9NFk.js} +1 -1
- package/dist/assets/architectureDiagram-NJMV4G6O-CgLFXbg6.js +36 -0
- package/dist/assets/{blockDiagram-BEXU5L5S-Ag9nLW4H.js → blockDiagram-BEXU5L5S-DGDFFc9M.js} +1 -1
- package/dist/assets/brain-CeCdoTb2.js +1 -0
- package/dist/assets/{c4Diagram-YGBWAQC7-Bh0sjgUa.js → c4Diagram-YGBWAQC7-B9aklAUj.js} +1 -1
- package/dist/assets/channel-TsOXCiPg.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-BFBcIIqu.js → chunk-2Q5K7J3B-BC0KmWsM.js} +1 -1
- package/dist/assets/{chunk-3FUC2YCW-Dvfpex-f.js → chunk-3FUC2YCW-BbDFHsJ1.js} +2 -2
- package/dist/assets/{chunk-5VM5RSS4-CMjP2YZW.js → chunk-5VM5RSS4-DtGbsjOM.js} +1 -1
- package/dist/assets/{chunk-GTNCS2PH-BryoeTc7.js → chunk-GTNCS2PH-VMghMcEl.js} +1 -1
- package/dist/assets/{chunk-GWA4HPMP-BhfvcchO.js → chunk-GWA4HPMP-BP_JyGWQ.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-bcCVp8rp.js → chunk-JWPE2WC7-CYFyzgAU.js} +1 -1
- package/dist/assets/{chunk-NETBCI7D-yKIjIlkQ.js → chunk-NETBCI7D-DBNa_kqm.js} +1 -1
- package/dist/assets/{chunk-WEXAMYUT-D3Zqbmup.js → chunk-WEXAMYUT-BKEeM7CJ.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-CjVoIMG6.js → chunk-XXDRQBXY-C__m3ZXl.js} +1 -1
- package/dist/assets/{classDiagram-v2-NBCMYWYE-mUCWdVyH.js → classDiagram-v2-NBCMYWYE-CBUrTSAX.js} +1 -1
- package/dist/assets/computer-control-NLov352p.js +1 -0
- package/dist/assets/core-6lvx-ypA.js +12 -0
- package/dist/assets/cose-bilkent-JH36ORCC-GRfL-1Vb.js +1 -0
- package/dist/assets/cpp-DddhVWhK.js +1 -0
- package/dist/assets/{cynefin-OW5HDTMX-BpRrxoO4.js → cynefin-OW5HDTMX-LopwGUjm.js} +1 -1
- package/dist/assets/{cynefinDiagram-VND7K2PF-D3VBWCPK.js → cynefinDiagram-VND7K2PF-DSB8ZRNS.js} +1 -1
- package/dist/assets/{dagre-6A5THRUB-DxEIACOO.js → dagre-6A5THRUB-DL3Kgdfk.js} +1 -1
- package/dist/assets/{diagram-22UHCM2B-BANgZEOS.js → diagram-22UHCM2B-DIxN34BM.js} +1 -1
- package/dist/assets/{diagram-3UASUU5V-Cnq7nJir.js → diagram-3UASUU5V-CJnSvXaI.js} +1 -1
- package/dist/assets/{diagram-ATOU4E4O-4TBDIWnz.js → diagram-ATOU4E4O-C-XF-lO8.js} +1 -1
- package/dist/assets/{diagram-CDSNMT55-CD_B39D4.js → diagram-CDSNMT55-Df2yZPi_.js} +1 -1
- package/dist/assets/{diagram-MLGK6HIB-CzvnFhEC.js → diagram-MLGK6HIB-BBs9oZFs.js} +1 -1
- package/dist/assets/{diagram-MPIPVDR6-C4w2SNml.js → diagram-MPIPVDR6-CEbK11mM.js} +1 -1
- package/dist/assets/{ebnfDiagram-ZINNZB2B-gkUEBm2s.js → ebnfDiagram-ZINNZB2B-BNq6Yv3C.js} +1 -1
- package/dist/assets/{elk-276RUBZZ-B_56X6mw.js → elk-276RUBZZ-CFbQ2bGm.js} +1 -1
- package/dist/assets/engine-javascript-D5Xfc425.js +141 -0
- package/dist/assets/{erDiagram-OPXOYQCR-C_oByoDS.js → erDiagram-OPXOYQCR-Bz8vmjN4.js} +1 -1
- package/dist/assets/{flowDiagram-KWPJA3E3-CR9xXJkC.js → flowDiagram-KWPJA3E3-cQUfEYrx.js} +1 -1
- package/dist/assets/ganttDiagram-FUAMR5RP-BY8n9tbI.js +292 -0
- package/dist/assets/{gitGraphDiagram-X574FWY7-VJ6-Tp_p.js → gitGraphDiagram-X574FWY7-KduSOMDN.js} +1 -1
- package/dist/assets/image-plus-DNIWU160.js +1 -0
- package/dist/assets/index-C8xb62XS.js +585 -0
- package/dist/assets/index-DbN_Hfjs.css +1 -0
- package/dist/assets/{infoDiagram-VRGFBTTK-2Lu9te4D.js → infoDiagram-VRGFBTTK-xBKgUkpL.js} +1 -1
- package/dist/assets/{ishikawaDiagram-OU5B5YK6-DR49XY-e.js → ishikawaDiagram-OU5B5YK6-_ei09tAJ.js} +1 -1
- package/dist/assets/{journeyDiagram-ZHPQQLJL-ZoR0M305.js → journeyDiagram-ZHPQQLJL-Fp49MkSp.js} +1 -1
- package/dist/assets/{kanban-definition-PNTS6WVX-DLKHxrO-.js → kanban-definition-PNTS6WVX-CY9lLm7V.js} +1 -1
- package/dist/assets/{linear-BASsfWly.js → linear-D2ai4eM2.js} +1 -1
- package/dist/assets/{mermaid.core-BVidiPkk.js → mermaid.core-DP6qPqu1.js} +5 -5
- package/dist/assets/{mindmap-definition-NLK3R4M7-g_Qx0U5C.js → mindmap-definition-NLK3R4M7-g1ynEw_d.js} +1 -1
- package/dist/assets/module-DCUsy2BQ.js +3 -0
- package/dist/assets/page-visible-BZn8304W.js +1 -0
- package/dist/assets/{pegDiagram-GJSIUBJH-DI9Cjs8w.js → pegDiagram-GJSIUBJH-Bt4ObsZj.js} +1 -1
- package/dist/assets/{pieDiagram-5QR66LMP-sRI0Uhr5.js → pieDiagram-5QR66LMP-CeLld8bY.js} +1 -1
- package/dist/assets/{quadrantDiagram-O4NWA36T-CamKTby3.js → quadrantDiagram-O4NWA36T-D4WWZw3x.js} +1 -1
- package/dist/assets/{railroadDiagram-XR7U4H2S-DOLlkbf3.js → railroadDiagram-XR7U4H2S-D95P5NqU.js} +1 -1
- package/dist/assets/remote-desktop-panel-DOIMmT4T.js +1 -0
- package/dist/assets/{requirementDiagram-PLB6GJNP-DrRQ5r97.js → requirementDiagram-PLB6GJNP-D12p3RhR.js} +1 -1
- package/dist/assets/ruby-Ct1eTYOr.js +1 -0
- package/dist/assets/{sankeyDiagram-IPEJSGJF-DGS_lXcX.js → sankeyDiagram-IPEJSGJF-Co26Dwcs.js} +1 -1
- package/dist/assets/{sequenceDiagram-PO4LG4MO-CkjWqwtf.js → sequenceDiagram-PO4LG4MO-y5YxaDKt.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-CepRgful.js → sizeCapture-INFHLROL-D49hZ8U5.js} +1 -1
- package/dist/assets/{stateDiagram-v2-GCMORJYK-hykr-9RS.js → stateDiagram-v2-GCMORJYK-C0sylr-r.js} +1 -1
- package/dist/assets/{swimlanes-2SLR337P-CKOHEZbI.js → swimlanes-2SLR337P-DmRWsDIs.js} +1 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-DzhbBHtd.js +8 -0
- package/dist/assets/table-file.worker-KkMx-SNx.js +10 -0
- package/dist/assets/{timeline-definition-EJHVYXUP-CB8pJ6AC.js → timeline-definition-EJHVYXUP-DVmHYs3w.js} +1 -1
- package/dist/assets/{usecaseDiagram-POWQR4AR-DrclJHdl.js → usecaseDiagram-POWQR4AR-BQ1q0VV6.js} +1 -1
- package/dist/assets/user-B9lohN4n.js +1 -0
- package/dist/assets/{vennDiagram-UO4OBE2U-zS23qjv8.js → vennDiagram-UO4OBE2U-C_cnfST0.js} +1 -1
- package/dist/assets/{wardleyDiagram-VNRHLVJA-52jgeKxz.js → wardleyDiagram-VNRHLVJA-Bb3BSu12.js} +1 -1
- package/dist/assets/{xychartDiagram-PMCCYNJV-DSdl9rQ8.js → xychartDiagram-PMCCYNJV-CcwEuuEi.js} +1 -1
- package/dist/index.html +2 -2
- package/dist-server/cloud-home-start.js +19 -8
- package/dist-server/container-mcp.js +8 -0
- package/dist-server/desktop-entry.mjs +54 -0
- package/dist-server/drivers/agents-proxy.js +30 -12
- package/dist-server/index.js +2745 -1487
- package/dist-server/openmausbot.js +1004 -642
- package/dist-server/pair-cli.js +1004 -642
- package/dist-server/permission-proxy.js +2 -0
- package/dist-server/server/activity.js +2 -0
- package/dist-server/server/atomic.js +70 -2
- package/dist-server/server/checkpoints.js +55 -39
- package/dist-server/server/cloud-home-start.js +3 -3
- package/dist-server/server/config.js +22 -1
- package/dist-server/server/connector-card-text.js +15 -0
- package/dist-server/server/default-model-selection.js +7 -4
- package/dist-server/server/direct-apply.js +20 -0
- package/dist-server/server/drivers/acp/core.js +10 -0
- package/dist-server/server/drivers/acp/grok.js +47 -5
- package/dist-server/server/drivers/agents-call.js +1 -1
- package/dist-server/server/drivers/agents-catalog.js +34 -11
- package/dist-server/server/drivers/agents-proxy.js +1 -0
- package/dist-server/server/drivers/chat-mcp-tools.js +5 -3
- package/dist-server/server/drivers/claude-login-auth.js +1 -1
- package/dist-server/server/drivers/claude.js +35 -11
- package/dist-server/server/drivers/codex-device-auth.js +27 -319
- package/dist-server/server/drivers/codex.js +147 -24
- package/dist-server/server/drivers/device-auth.js +343 -0
- package/dist-server/server/drivers/openai-chat.js +17 -8
- package/dist-server/server/fleet-agent.js +18 -5
- package/dist-server/server/harness/http.js +5 -2
- package/dist-server/server/harness/registry.js +82 -45
- package/dist-server/server/harness-capabilities.js +7 -4
- package/dist-server/server/hosted-models.js +3 -1
- package/dist-server/server/index.js +471 -77
- package/dist-server/server/key-rejections.js +57 -0
- package/dist-server/server/mcp-oauth.js +125 -47
- package/dist-server/server/message-file.js +102 -7
- package/dist-server/server/model-requests.js +55 -4
- package/dist-server/server/permission-proxy.js +4 -0
- package/dist-server/server/profile-requests.js +80 -4
- package/dist-server/server/provider-key-check.js +5 -1
- package/dist-server/server/request-auth.js +2 -1
- package/dist-server/server/room-turn-timeout.js +28 -0
- package/dist-server/server/routes/thread-models.js +36 -0
- package/dist-server/server/routes/undo.js +17 -0
- package/dist-server/server/routine-requests.js +210 -6
- package/dist-server/server/routines.js +2 -2
- package/dist-server/server/setup-mode.js +1 -1
- package/dist-server/server/skill-learn.js +2 -2
- package/dist-server/server/skills.js +33 -2
- package/dist-server/server/store.js +148 -60
- package/dist-server/server/system-prompt.js +1 -1
- package/dist-server/server/team-backup.js +19 -4
- package/dist-server/server/thread-model.js +25 -0
- package/dist-server/server/turn-continuation.js +17 -16
- package/dist-server/server/webhook-ingress.js +8 -3
- package/dist-server/server/webhooks.js +40 -5
- package/dist-server/server/workspace-backup.js +6 -1
- package/dist-server/shared/device-sign-in.js +57 -0
- package/dist-server/shared/team-backup.js +2 -0
- package/dist-server/shared/thread-model.js +13 -0
- package/dist-server/vps-container-mcp.js +8 -0
- package/dist-server/workspace-backup.worker.js +42 -23
- 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/DesktopViewer-CPidMCtt.js +0 -5
- 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/architectureDiagram-NJMV4G6O-DiPor3UT.js +0 -36
- 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-DR8eD6QW.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/cose-bilkent-JH36ORCC-BBmR1bbX.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/ganttDiagram-FUAMR5RP-gtYBTu0B.js +0 -292
- 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-Cp4S4NOL.js +0 -153
- package/dist/assets/index-CpaIXRLp.js +0 -614
- package/dist/assets/index-Z81SMsgR.css +0 -1
- 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-D-8vqZ4-.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
|
@@ -26,6 +26,7 @@ export function catalogProfileFromEnv(env) {
|
|
|
26
26
|
voiceNotes: env.OMB_VOICE_NOTES === "1",
|
|
27
27
|
cloudHome: env.OMB_CLOUD_HOME === "1",
|
|
28
28
|
memoryEnabled: env.OMB_MEMORY_ENABLED !== "0",
|
|
29
|
+
chief: env.OMB_CHIEF_OF_STAFF === "1",
|
|
29
30
|
botId: env.OMB_BOT_ID ?? "",
|
|
30
31
|
};
|
|
31
32
|
}
|
|
@@ -85,7 +86,7 @@ const ROUTINE_SCHEDULE_SCHEMA = {
|
|
|
85
86
|
},
|
|
86
87
|
starts_at: {
|
|
87
88
|
type: "string",
|
|
88
|
-
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
|
|
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.",
|
|
89
90
|
},
|
|
90
91
|
window_start: {
|
|
91
92
|
type: "string",
|
|
@@ -146,7 +147,7 @@ const ROUTINE_FIELDS_SCHEMA = {
|
|
|
146
147
|
},
|
|
147
148
|
continuity: {
|
|
148
149
|
type: "boolean",
|
|
149
|
-
description: "Opt in to using the latest completed run's bounded report as historical context. Defaults to false; set false in an update to start fresh again. Included in the applied result or pending confirmation.",
|
|
150
|
+
description: "Opt in to using the latest completed run's bounded report as historical context. Use it for recurring work that builds on last time, such as QA passes, monitoring or follow-ups. Defaults to false; set false in an update to start fresh again. Included in the applied result or pending confirmation.",
|
|
150
151
|
},
|
|
151
152
|
overlap: {
|
|
152
153
|
type: "string",
|
|
@@ -154,7 +155,13 @@ const ROUTINE_FIELDS_SCHEMA = {
|
|
|
154
155
|
description: "While this routine is still working, skip scheduled occurrences (default) or queue at most one run. Queue skips further occurrences until the pending run starts; it never builds an unlimited backlog. Manual and webhook requests are separate.",
|
|
155
156
|
},
|
|
156
157
|
};
|
|
158
|
+
// propose_profile's one sentence about for_bot_id, which a bot that is not a
|
|
159
|
+
// Chief is not shown (catalogTools), along with the parameter itself.
|
|
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.";
|
|
157
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.";
|
|
158
165
|
/** Every tool, in the order it is listed. Four peer tools are worded
|
|
159
166
|
* differently for an external runtime, which may poll inside one process. */
|
|
160
167
|
const toolDefinitions = (externalRuntime) => [
|
|
@@ -609,7 +616,7 @@ const toolDefinitions = (externalRuntime) => [
|
|
|
609
616
|
},
|
|
610
617
|
{
|
|
611
618
|
name: "propose_routine",
|
|
612
|
-
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." +
|
|
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,
|
|
613
620
|
inputSchema: {
|
|
614
621
|
type: "object",
|
|
615
622
|
additionalProperties: false,
|
|
@@ -625,7 +632,7 @@ const toolDefinitions = (externalRuntime) => [
|
|
|
625
632
|
},
|
|
626
633
|
{
|
|
627
634
|
name: "propose_routine_action",
|
|
628
|
-
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." +
|
|
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,
|
|
629
636
|
inputSchema: {
|
|
630
637
|
type: "object",
|
|
631
638
|
additionalProperties: false,
|
|
@@ -652,7 +659,7 @@ const toolDefinitions = (externalRuntime) => [
|
|
|
652
659
|
},
|
|
653
660
|
{
|
|
654
661
|
name: "propose_profile",
|
|
655
|
-
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.
|
|
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,
|
|
656
663
|
inputSchema: {
|
|
657
664
|
type: "object",
|
|
658
665
|
additionalProperties: false,
|
|
@@ -664,7 +671,7 @@ const toolDefinitions = (externalRuntime) => [
|
|
|
664
671
|
cwd: {
|
|
665
672
|
type: "string",
|
|
666
673
|
maxLength: 1024,
|
|
667
|
-
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.",
|
|
668
675
|
},
|
|
669
676
|
notifications: {
|
|
670
677
|
type: "boolean",
|
|
@@ -685,7 +692,7 @@ const toolDefinitions = (externalRuntime) => [
|
|
|
685
692
|
},
|
|
686
693
|
{
|
|
687
694
|
name: "propose_model",
|
|
688
|
-
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
|
|
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,
|
|
689
696
|
inputSchema: {
|
|
690
697
|
type: "object",
|
|
691
698
|
additionalProperties: false,
|
|
@@ -728,12 +735,12 @@ const toolDefinitions = (externalRuntime) => [
|
|
|
728
735
|
},
|
|
729
736
|
{
|
|
730
737
|
name: "skills_list",
|
|
731
|
-
description: "List this bot's imported skills (enabled and disabled) and any staged skill writes waiting for the user
|
|
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.",
|
|
732
739
|
inputSchema: { type: "object", additionalProperties: false, properties: {} },
|
|
733
740
|
},
|
|
734
741
|
{
|
|
735
742
|
name: "skill_manage",
|
|
736
|
-
description: "Submit a new or updated reusable SKILL.md. Never update unless the user explicitly asked to revise that named skill.
|
|
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,
|
|
737
744
|
inputSchema: {
|
|
738
745
|
type: "object",
|
|
739
746
|
additionalProperties: false,
|
|
@@ -842,6 +849,14 @@ export const SHARED_COMPUTER_TOOL_NAMES = new Set(["list_shared_computers", "sha
|
|
|
842
849
|
// tool whose every call would end in a setup error. The route behind it
|
|
843
850
|
// refuses regardless; this keeps the catalog honest about what can work.
|
|
844
851
|
const VOICE_TOOL_NAMES = new Set(["send_voice_note"]);
|
|
852
|
+
// And for a role: every route behind these refuses a bot that is not its
|
|
853
|
+
// section's Chief of Staff, as it does a for_bot_id naming another bot on
|
|
854
|
+
// propose_profile or propose_model. (A routine's for_bot_id is open to any
|
|
855
|
+
// bot that can reach that peer, so it stays.)
|
|
856
|
+
const CHIEF_ONLY_TOOL_NAMES = new Set([
|
|
857
|
+
"create_bot", "list_team_setup", "propose_team_setup", "propose_bot_deletion", "create_room", "manage_room", "retry_thread",
|
|
858
|
+
]);
|
|
859
|
+
const CHIEF_TARGET_TOOL_NAMES = new Set(["propose_profile", "propose_model"]);
|
|
845
860
|
// One teamwork path in room turns; keep all unrelated integrations available.
|
|
846
861
|
// Ordinary direct chats use this same bounded coordinator. Goal-owned turns
|
|
847
862
|
// retain their independent loop and cannot start a second coordinator.
|
|
@@ -878,10 +893,18 @@ function catalogTools(profile) {
|
|
|
878
893
|
const VOICE_READY_TOOLS = profile.voiceNotes
|
|
879
894
|
? SHAREABLE_TOOLS
|
|
880
895
|
: SHAREABLE_TOOLS.filter((tool) => !VOICE_TOOL_NAMES.has(tool.name));
|
|
896
|
+
const ROLE_TOOLS = profile.chief
|
|
897
|
+
? VOICE_READY_TOOLS
|
|
898
|
+
: VOICE_READY_TOOLS.filter((tool) => !CHIEF_ONLY_TOOL_NAMES.has(tool.name)).map((tool) => {
|
|
899
|
+
if (!CHIEF_TARGET_TOOL_NAMES.has(tool.name))
|
|
900
|
+
return tool;
|
|
901
|
+
const properties = Object.fromEntries(Object.entries(tool.inputSchema.properties).filter(([key]) => key !== "for_bot_id"));
|
|
902
|
+
return { ...tool, description: tool.description.replace(CHIEF_PROFILE_TARGET, ""), inputSchema: { ...tool.inputSchema, properties } };
|
|
903
|
+
});
|
|
881
904
|
return profile.externalRuntime
|
|
882
905
|
? BOT_SCOPED_TOOLS.filter(tool => EXTERNAL_TOOL_NAMES.has(tool.name))
|
|
883
906
|
: profile.coordinating
|
|
884
|
-
?
|
|
907
|
+
? ROLE_TOOLS.filter(tool => !ROOM_REPLACED_TOOLS.has(tool.name) || (tool.name === "start_thread" && profile.ownThreadCreation))
|
|
885
908
|
.map(tool => tool.name === "start_thread" ? {
|
|
886
909
|
...tool,
|
|
887
910
|
description: "Open a separate job on yourself with its own history and run, without switching the person's selected conversation. Use only when the user requests independent jobs (for example one review per pull request). Give a short specific title and complete instructions; you can open at most five per turn. This is not a teammate handoff: use coordinate_bots for teammates and their automatic replies. Self-opened jobs cannot recursively open more jobs. If refused, do not retry; explain what remains.",
|
|
@@ -889,5 +912,5 @@ function catalogTools(profile) {
|
|
|
889
912
|
bot_id: { type: "string", enum: [profile.botId], description: "Leave out, or use your own bot ID. For teammates use coordinate_bots." },
|
|
890
913
|
} },
|
|
891
914
|
} : tool)
|
|
892
|
-
:
|
|
915
|
+
: ROLE_TOOLS.filter(tool => !ROOM_ONLY_TOOLS.has(tool.name));
|
|
893
916
|
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// OMB_COMMS_TOKEN shared secret for the localhost-only internal endpoints
|
|
13
13
|
// OMB_TURN_DEPTH this turn's comms depth (the harness refuses recursion)
|
|
14
14
|
// OMB_EXTERNAL_RUNTIME "1" for a standing process: peer tools and polling only
|
|
15
|
+
// OMB_CHIEF_OF_STAFF "1" for a Chief of Staff, the only bot shown the Chief-only tools
|
|
15
16
|
//
|
|
16
17
|
// This file is the stdio front end only. What the tools are and which a turn
|
|
17
18
|
// sees: agents-catalog.ts. What a call does: agents-call.ts. How the harness
|
|
@@ -14,7 +14,9 @@ import { allowsTool, canUseMcpServer, parseToolScope } from "../../shared/tool-s
|
|
|
14
14
|
export class ChatToolSessionError extends Error {
|
|
15
15
|
}
|
|
16
16
|
const STARTUP_MS = 8_000;
|
|
17
|
-
|
|
17
|
+
/** Historic per-call ceiling for a bot's MCP tools; a turn can override it
|
|
18
|
+
* with SendTurnInput.mcpCallTimeoutMs (server config `mcp.callTimeoutMinutes`). */
|
|
19
|
+
const DEFAULT_CALL_MS = 10 * 60_000;
|
|
18
20
|
const FRAME_BYTES = 2 * 1024 * 1024;
|
|
19
21
|
const OUTPUT_BYTES = 50 * 1024;
|
|
20
22
|
const TOOL_COUNT = 128;
|
|
@@ -283,7 +285,7 @@ function omitBlankDefaults(builtInBrowser, tool, args) {
|
|
|
283
285
|
delete args[field];
|
|
284
286
|
}
|
|
285
287
|
}
|
|
286
|
-
export async function mountChatTools(integrations, signal, computerUse = false, toolScope) {
|
|
288
|
+
export async function mountChatTools(integrations, signal, computerUse = false, toolScope, callTimeoutMs = DEFAULT_CALL_MS) {
|
|
287
289
|
const parsed = parseToolScope(toolScope);
|
|
288
290
|
if (!parsed.ok)
|
|
289
291
|
throw new Error(parsed.error);
|
|
@@ -411,7 +413,7 @@ export async function mountChatTools(integrations, signal, computerUse = false,
|
|
|
411
413
|
}
|
|
412
414
|
const tool = registered.get(name);
|
|
413
415
|
try {
|
|
414
|
-
const result = await tool.client.call("tools/call", { name: tool.name, arguments: args }, AbortSignal.any([signal, callSignal]),
|
|
416
|
+
const result = await tool.client.call("tools/call", { name: tool.name, arguments: args }, AbortSignal.any([signal, callSignal]), callTimeoutMs);
|
|
415
417
|
if (signal.aborted || callSignal.aborted)
|
|
416
418
|
throw aborted();
|
|
417
419
|
if (!object(result) || !Array.isArray(result.content) || (result.isError !== undefined && typeof result.isError !== "boolean"))
|
|
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { isAbsolute, join, resolve } from "node:path";
|
|
4
4
|
import { stripVTControlCharacters } from "node:util";
|
|
5
5
|
import { killCliTree, spawnCli } from "../procs.js";
|
|
6
|
-
import { canonicalPath } from "./
|
|
6
|
+
import { canonicalPath } from "./device-auth.js";
|
|
7
7
|
const MAX_OUTPUT = 32_768;
|
|
8
8
|
/** Where Anthropic's sign-in lives. Anything else in the CLI's output is not a link we show. */
|
|
9
9
|
const SIGN_IN_HOSTS = ["claude.com", "claude.ai", "console.anthropic.com", "platform.claude.com"];
|
|
@@ -15,7 +15,7 @@ import { createServer as createNetServer } from "node:net";
|
|
|
15
15
|
import { homedir, tmpdir } from "node:os";
|
|
16
16
|
import { join, dirname, isAbsolute, normalize } from "node:path";
|
|
17
17
|
import { DATA_DIR, stripWorkspaceCredentialEnv } from "../config.js";
|
|
18
|
-
import { writeFileAtomic } from "../atomic.js";
|
|
18
|
+
import { writeFileAtomic, writeFileAtomicIfChanged } from "../atomic.js";
|
|
19
19
|
import { augmentedPath } from "../env-path.js";
|
|
20
20
|
import { brokerSocketPath, describeSpawnFailure, execCli, killCliTree, spawnCli } from "../procs.js";
|
|
21
21
|
import { classifyResumeFailure, mayReplay, recoveryPromptFor } from "../resume-recovery.js";
|
|
@@ -599,6 +599,9 @@ export async function createPermissionBroker(opts) {
|
|
|
599
599
|
let boundPath = opts.socketPaths[0] ?? "";
|
|
600
600
|
const connectionHandler = (conn) => {
|
|
601
601
|
conn.on("error", () => { });
|
|
602
|
+
// An ask carries the whole tool input (a Write's file content), so one
|
|
603
|
+
// line spans many reads. Decode as a stream so no character is split.
|
|
604
|
+
conn.setEncoding("utf8");
|
|
602
605
|
let buf = "";
|
|
603
606
|
conn.on("data", (chunk) => {
|
|
604
607
|
buf += chunk;
|
|
@@ -932,8 +935,10 @@ function recordCostState(sessionId, state) {
|
|
|
932
935
|
const ids = Object.keys(history);
|
|
933
936
|
for (const id of ids.slice(0, Math.max(0, ids.length - COST_HISTORY_SESSIONS)))
|
|
934
937
|
delete history[id];
|
|
938
|
+
// Written after every turn, so not fsynced: what a power cut could lose is
|
|
939
|
+
// the same thing a failed write already gives up (below).
|
|
935
940
|
try {
|
|
936
|
-
writeFileAtomic(COST_HISTORY_FILE, JSON.stringify(history), { mode: 0o600 });
|
|
941
|
+
writeFileAtomic(COST_HISTORY_FILE, JSON.stringify(history), { mode: 0o600, durable: false });
|
|
937
942
|
}
|
|
938
943
|
catch {
|
|
939
944
|
// a lost state only means a later resume keeps its whole figure
|
|
@@ -1051,6 +1056,26 @@ export const ClaudeDriver = {
|
|
|
1051
1056
|
const readCliVersion = (env) => new Promise((resolve) => {
|
|
1052
1057
|
execCli(config.cli, ["--version"], { timeout: 8000, env }, (err, stdout) => resolve(err ? null : stdout.trim() || null));
|
|
1053
1058
|
});
|
|
1059
|
+
// The --help read while it runs: snapshots that overlap (the server's
|
|
1060
|
+
// read at start and the app's first one) share it.
|
|
1061
|
+
let helpRead = null;
|
|
1062
|
+
const readCliHelp = (version, env) => {
|
|
1063
|
+
if (helpRead?.version === version)
|
|
1064
|
+
return helpRead.done;
|
|
1065
|
+
const read = {
|
|
1066
|
+
version,
|
|
1067
|
+
done: new Promise((resolve) => {
|
|
1068
|
+
execCli(config.cli, ["--help"], { timeout: 8000, env }, (err, stdout) => resolve(err ? null : stdout));
|
|
1069
|
+
}).then((help) => {
|
|
1070
|
+
cliHasAutocompact = help === null ? null : /^\s*--autocompact\b/m.test(help);
|
|
1071
|
+
cliHelpVersion = version;
|
|
1072
|
+
if (helpRead === read)
|
|
1073
|
+
helpRead = null;
|
|
1074
|
+
}),
|
|
1075
|
+
};
|
|
1076
|
+
helpRead = read;
|
|
1077
|
+
return read.done;
|
|
1078
|
+
};
|
|
1054
1079
|
const listeners = new Set();
|
|
1055
1080
|
// one active turn per thread; a second send while busy is a caller bug
|
|
1056
1081
|
const active = new Map();
|
|
@@ -1411,14 +1436,18 @@ export const ClaudeDriver = {
|
|
|
1411
1436
|
? readClaudeAuthSettings(env, input.environment) : {};
|
|
1412
1437
|
// Harness hooks (item 0.2): one helper command for the events the
|
|
1413
1438
|
// harness observes. The helper reads its bearer from a per-thread file
|
|
1414
|
-
// the harness
|
|
1439
|
+
// the harness refreshes every turn, so a long-lived CLI process never
|
|
1415
1440
|
// presents a stale token. Registered through the same private
|
|
1416
1441
|
// --settings file as the auth override; both are 0600 and per launch.
|
|
1417
1442
|
const hooks = turn.integrations?.hooks;
|
|
1418
1443
|
const hookTokenPath = hooks ? hookTokenFile(threadId, botId) : null;
|
|
1419
1444
|
if (hooks && hookTokenPath) {
|
|
1420
1445
|
mkdirSync(dirname(hookTokenPath), { recursive: true, mode: 0o700 });
|
|
1421
|
-
|
|
1446
|
+
// The bearer is usually the same as last turn, and it only lives in
|
|
1447
|
+
// this process's memory, so a restart invalidates the file anyway:
|
|
1448
|
+
// skip identical bytes and the fsync. A rotated bearer differs from
|
|
1449
|
+
// what is on disk, so it is always written before the CLI launches.
|
|
1450
|
+
writeFileAtomicIfChanged(hookTokenPath, hooks.token, { mode: 0o600, durable: false });
|
|
1422
1451
|
env.OMB_HOOK_URL = hooks.url;
|
|
1423
1452
|
env.OMB_HOOK_TOKEN_FILE = hookTokenPath;
|
|
1424
1453
|
env.OMB_HOOK_NODE = process.execPath;
|
|
@@ -2303,13 +2332,8 @@ export const ClaudeDriver = {
|
|
|
2303
2332
|
return { state: "unavailable", reason: `\`${config.cli}\` CLI not found` };
|
|
2304
2333
|
cliVersion = parseClaudeCliVersion(version);
|
|
2305
2334
|
cliVersionChecked = true;
|
|
2306
|
-
if (version !== cliHelpVersion)
|
|
2307
|
-
|
|
2308
|
-
execCli(config.cli, ["--help"], { timeout: 8000, env }, (err, stdout) => resolve(err ? null : stdout));
|
|
2309
|
-
});
|
|
2310
|
-
cliHasAutocompact = help === null ? null : /^\s*--autocompact\b/m.test(help);
|
|
2311
|
-
cliHelpVersion = version;
|
|
2312
|
-
}
|
|
2335
|
+
if (version !== cliHelpVersion)
|
|
2336
|
+
await readCliHelp(version, env);
|
|
2313
2337
|
const update = claudeCliUpdate(version, config.cli);
|
|
2314
2338
|
const warning = claudeInheritWarning(env);
|
|
2315
2339
|
if (config.requireApiKey) {
|
|
@@ -1,35 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// Codex's half of the in-app device-code sign-in (device-auth.ts): `codex
|
|
2
|
+
// login --device-auth` for a ChatGPT account, with `codex login status` to
|
|
3
|
+
// keep a working login and to confirm the new one, and `codex logout` for
|
|
4
|
+
// Settings' sign-out.
|
|
5
5
|
import { stripVTControlCharacters } from "node:util";
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
const MAX_OUTPUT = 16_384;
|
|
9
|
-
// Two configured instances can use the same on-disk login. Only the auth
|
|
10
|
-
// operation is exclusive: normal turns are not blocked by this lock.
|
|
11
|
-
const authenticatingHomes = new Set();
|
|
12
|
-
/** The real path of a credential home, so two spellings of one home share
|
|
13
|
-
* one sign-in lock. A missing tail keeps its name under its real parent. */
|
|
14
|
-
export function canonicalPath(path) {
|
|
15
|
-
try {
|
|
16
|
-
return realpathSync(path);
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
const parent = dirname(path);
|
|
20
|
-
return parent === path ? path : join(canonicalPath(parent), basename(path));
|
|
21
|
-
}
|
|
22
|
-
}
|
|
6
|
+
import { deviceSignInPrompt } from "../../shared/device-sign-in.js";
|
|
7
|
+
import { DeviceAuthController } from "./device-auth.js";
|
|
23
8
|
export function codexDevicePrompt(output) {
|
|
24
|
-
|
|
25
|
-
// Chunks may stop halfway through a code. Never publish the incomplete
|
|
26
|
-
// final line before its newline arrives.
|
|
27
|
-
const lines = clean.split(/\r?\n/).slice(0, -1).map((line) => line.trim());
|
|
28
|
-
// Do not turn arbitrary output into a link, or pass through query tokens.
|
|
29
|
-
if (!lines.some((line) => /^https:\/\/auth\.openai\.com\/codex\/device\/?$/.test(line)))
|
|
30
|
-
return null;
|
|
31
|
-
const userCode = lines.find((line) => /^[A-Z0-9]{4,8}-[A-Z0-9]{4,8}$/.test(line));
|
|
32
|
-
return userCode ? { authorizationUrl: DEVICE_URL, userCode } : null;
|
|
9
|
+
return deviceSignInPrompt("codex", stripVTControlCharacters(output));
|
|
33
10
|
}
|
|
34
11
|
function loginFailure(output) {
|
|
35
12
|
if (/(unexpected argument|unrecognized (argument|option)|unknown option).*device-auth/i.test(output)) {
|
|
@@ -43,293 +20,24 @@ function loginFailure(output) {
|
|
|
43
20
|
}
|
|
44
21
|
return "ChatGPT sign-in did not finish. Check the server's connection and that device-code login is enabled in ChatGPT, then try again.";
|
|
45
22
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const home = env.HOME || env.USERPROFILE || homedir();
|
|
67
|
-
if (!isAbsolute(home) || (env.CODEX_HOME && !isAbsolute(env.CODEX_HOME))) {
|
|
68
|
-
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing in.");
|
|
69
|
-
}
|
|
70
|
-
const homeKey = canonicalPath(resolve(env.CODEX_HOME || join(home, ".codex")));
|
|
71
|
-
if (authenticatingHomes.has(homeKey)) {
|
|
72
|
-
throw new Error("A ChatGPT sign-in is already running for this server account. Finish or cancel it before starting another.");
|
|
73
|
-
}
|
|
74
|
-
authenticatingHomes.add(homeKey);
|
|
75
|
-
return new Promise((resolveStart, reject) => {
|
|
76
|
-
const flow = {
|
|
77
|
-
status: {
|
|
78
|
-
phase: "waiting", flowId: randomUUID(), authorizationUrl: null,
|
|
79
|
-
expiresAt: new Date(Date.now() + (this.options.lifetimeMs ?? 15 * 60_000)).toISOString(),
|
|
80
|
-
},
|
|
81
|
-
child: null, ready: false, resolve: resolveStart, reject, homeKey,
|
|
82
|
-
startupTimer: setTimeout(() => this.finish(flow, "failed", "Codex did not provide a sign-in code in time. Check the server connection and update Codex, then try again."), this.options.startupTimeoutMs ?? 30_000),
|
|
83
|
-
expiryTimer: setTimeout(() => this.finish(flow, "expired", "The ChatGPT sign-in code expired. Start sign-in again."), this.options.lifetimeMs ?? 15 * 60_000),
|
|
84
|
-
};
|
|
85
|
-
flow.startupTimer.unref();
|
|
86
|
-
flow.expiryTimer.unref();
|
|
87
|
-
this.flow = flow;
|
|
88
|
-
// Never overwrite a working login just because Connect was clicked twice.
|
|
89
|
-
this.run(flow, ["login", "status"], env, home, (code, output) => {
|
|
90
|
-
if (code === 0 && /^logged in.*chatgpt\b/im.test(output)) {
|
|
91
|
-
this.finish(flow, "succeeded");
|
|
92
|
-
}
|
|
93
|
-
else if (code === 0 && /^logged in\b/im.test(output)) {
|
|
94
|
-
this.finish(flow, "failed", "Codex already has a different sign-in method on this server. Ask the server administrator to review it before changing accounts.");
|
|
95
|
-
}
|
|
96
|
-
else if (code !== 0 && /^not logged in\b/im.test(output)) {
|
|
97
|
-
this.run(flow, ["login", "--device-auth"], env, home, (loginCode, loginOutput) => {
|
|
98
|
-
if (loginCode !== 0 || !flow.ready) {
|
|
99
|
-
this.finish(flow, "failed", loginFailure(loginOutput));
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
// A successful command is not enough: verify credentials using the
|
|
103
|
-
// same executable and environment that will run this client's bots.
|
|
104
|
-
flow.startupTimer = setTimeout(() => this.finish(flow, "failed", "Codex finished sign-in but could not confirm the account. Refresh Settings and try again."), this.options.startupTimeoutMs ?? 30_000);
|
|
105
|
-
flow.startupTimer.unref();
|
|
106
|
-
this.run(flow, ["login", "status"], env, home, (statusCode, statusOutput) => {
|
|
107
|
-
this.finish(flow, statusCode === 0 && /^logged in.*chatgpt\b/im.test(statusOutput) ? "succeeded" : "failed", "Codex finished sign-in but did not confirm a ChatGPT account. Refresh Settings and try again.");
|
|
108
|
-
});
|
|
109
|
-
}, true);
|
|
110
|
-
}
|
|
111
|
-
else
|
|
112
|
-
this.finish(flow, "failed", "Codex could not confirm the existing sign-in on this server. Update Codex and check its login status before trying again.");
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
async get(flowId) {
|
|
117
|
-
if (!flowId || this.flow?.status.flowId !== flowId)
|
|
118
|
-
throw new Error("This sign-in is no longer available. Start sign-in again.");
|
|
119
|
-
return { ...this.flow.status };
|
|
120
|
-
}
|
|
121
|
-
async cancel() {
|
|
122
|
-
if (this.flow?.status.phase === "waiting")
|
|
123
|
-
this.finish(this.flow, "cancelled", "ChatGPT sign-in cancelled.");
|
|
124
|
-
await this.flow?.stopping;
|
|
125
|
-
if (this.flow?.terminationFailed)
|
|
126
|
-
throw new Error(this.flow.status.message);
|
|
127
|
-
if (this.command && !await this.stopChild(this.command)) {
|
|
128
|
-
throw new Error("Codex could not be stopped on this server. Ask the server administrator to stop the account command before trying again.");
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
async dispose() {
|
|
132
|
-
this.disposed = true;
|
|
133
|
-
await this.cancel();
|
|
134
|
-
this.flow = null;
|
|
135
|
-
}
|
|
136
|
-
/** Remove the ChatGPT sign-in Codex stores for this server account so a
|
|
137
|
-
* different account can connect. A sign-in in progress is never pulled
|
|
138
|
-
* away underneath the browser completing it. */
|
|
139
|
-
async signOut() {
|
|
140
|
-
if (this.disposed)
|
|
141
|
-
throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
142
|
-
if (this.flow?.status.phase === "waiting")
|
|
143
|
-
throw new Error("Finish or cancel the ChatGPT sign-in in progress before signing out.");
|
|
144
|
-
await this.flow?.stopping;
|
|
145
|
-
if (this.disposed)
|
|
146
|
-
throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
147
|
-
const env = this.options.environment();
|
|
148
|
-
const home = env.HOME || env.USERPROFILE || homedir();
|
|
149
|
-
if (!isAbsolute(home) || (env.CODEX_HOME && !isAbsolute(env.CODEX_HOME))) {
|
|
150
|
-
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing out.");
|
|
151
|
-
}
|
|
152
|
-
const homeKey = canonicalPath(resolve(env.CODEX_HOME || join(home, ".codex")));
|
|
153
|
-
if (authenticatingHomes.has(homeKey)) {
|
|
154
|
-
throw new Error("A ChatGPT sign-in is running for this server account. Finish or cancel it before signing out.");
|
|
155
|
-
}
|
|
156
|
-
authenticatingHomes.add(homeKey);
|
|
157
|
-
try {
|
|
158
|
-
const before = await this.exec(["login", "status"], env, home);
|
|
159
|
-
if (before.code === 1 && /^not logged in\b/im.test(before.output))
|
|
160
|
-
return;
|
|
161
|
-
if (before.code !== 0 || !/^logged in.*chatgpt\b/im.test(before.output)) {
|
|
162
|
-
throw new Error("Codex did not confirm a ChatGPT sign-in. Other authentication methods will not be removed; ask the server administrator to check the account.");
|
|
163
|
-
}
|
|
164
|
-
const logout = await this.exec(["logout"], env, home);
|
|
165
|
-
if (logout.code !== 0)
|
|
166
|
-
throw new Error("Codex could not remove the sign-in on this server. Check the server's Codex installation and try again.");
|
|
167
|
-
// The command's own report is not enough: confirm with the same status
|
|
168
|
-
// check that decides whether bots may run on this account.
|
|
169
|
-
const status = await this.exec(["login", "status"], env, home);
|
|
170
|
-
if (status.code !== 1 || !/^not logged in\b/im.test(status.output)) {
|
|
171
|
-
throw new Error("Codex still reports a sign-in on this server. Update Codex and check its login status before trying again.");
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
finally {
|
|
175
|
-
// If the OS cannot stop a command, it may still change credentials.
|
|
176
|
-
// Keep the home reserved until that exact child actually exits.
|
|
177
|
-
const child = this.command;
|
|
178
|
-
if (child && child.exitCode === null && child.signalCode === null) {
|
|
179
|
-
child.once("close", () => authenticatingHomes.delete(homeKey));
|
|
180
|
-
}
|
|
181
|
-
else
|
|
182
|
-
authenticatingHomes.delete(homeKey);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
/** One bounded, non-interactive Codex command. Its output stays here;
|
|
186
|
-
* callers see an exit code and a status-line match, never the text. */
|
|
187
|
-
exec(args, env, cwd) {
|
|
188
|
-
return new Promise((resolveExec, rejectExec) => {
|
|
189
|
-
if (this.disposed) {
|
|
190
|
-
rejectExec(new Error("This provider was removed. Refresh Settings before signing out."));
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
let child;
|
|
194
|
-
try {
|
|
195
|
-
child = spawnCli(this.options.cli, args, { env: { ...env, NO_COLOR: "1" }, cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
196
|
-
}
|
|
197
|
-
catch {
|
|
198
|
-
rejectExec(new Error("Codex could not start on this server. Install or update the configured Codex CLI, then try again."));
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
this.command = child;
|
|
202
|
-
child.stdin.end();
|
|
203
|
-
let output = "";
|
|
204
|
-
const receive = (chunk) => {
|
|
205
|
-
if (output.length < MAX_OUTPUT)
|
|
206
|
-
output += chunk.toString("utf8").slice(0, MAX_OUTPUT - output.length);
|
|
207
|
-
};
|
|
208
|
-
child.stdout.on("data", receive);
|
|
209
|
-
child.stderr.on("data", receive);
|
|
210
|
-
// A hung CLI must not hold the credential-home lock forever.
|
|
211
|
-
const timer = setTimeout(() => {
|
|
212
|
-
void this.stopChild(child).catch(() => false).then((stopped) => {
|
|
213
|
-
if (!stopped)
|
|
214
|
-
rejectExec(new Error("Codex could not be stopped on this server. Ask the server administrator to stop the account command before trying again."));
|
|
215
|
-
});
|
|
216
|
-
}, this.options.startupTimeoutMs ?? 30_000);
|
|
217
|
-
timer.unref();
|
|
218
|
-
child.once("error", (error) => {
|
|
219
|
-
clearTimeout(timer);
|
|
220
|
-
rejectExec(new Error(error.code === "ENOENT"
|
|
221
|
-
? "Codex is not installed on this server. Run npm install -g @openai/codex@latest on the server, then try again."
|
|
222
|
-
: "Codex could not start on this server. Check the configured CLI path and its executable permissions."));
|
|
223
|
-
});
|
|
224
|
-
child.once("close", (code) => {
|
|
225
|
-
clearTimeout(timer);
|
|
226
|
-
if (this.command === child)
|
|
227
|
-
this.command = null;
|
|
228
|
-
resolveExec({ code, output: stripVTControlCharacters(output) });
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
run(flow, args, env, cwd, done, parsePrompt = false) {
|
|
233
|
-
if (flow.status.phase !== "waiting")
|
|
234
|
-
return;
|
|
235
|
-
let child;
|
|
236
|
-
try {
|
|
237
|
-
child = spawnCli(this.options.cli, args, { env: { ...env, NO_COLOR: "1" }, cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
238
|
-
}
|
|
239
|
-
catch {
|
|
240
|
-
this.finish(flow, "failed", "Codex could not start on this server. Install or update the configured Codex CLI, then try again.");
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
flow.child = child;
|
|
244
|
-
child.stdin.end();
|
|
245
|
-
let output = "";
|
|
246
|
-
const receive = (chunk) => {
|
|
247
|
-
if (flow.status.phase !== "waiting")
|
|
248
|
-
return;
|
|
249
|
-
if (output.length + chunk.length > MAX_OUTPUT) {
|
|
250
|
-
this.finish(flow, "failed", "Codex returned an unexpected sign-in response. Update the server's Codex CLI and try again.");
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
output += chunk.toString("utf8");
|
|
254
|
-
const prompt = parsePrompt && !flow.ready ? codexDevicePrompt(output) : null;
|
|
255
|
-
if (prompt) {
|
|
256
|
-
flow.status = { ...flow.status, ...prompt };
|
|
257
|
-
flow.ready = true;
|
|
258
|
-
clearTimeout(flow.startupTimer);
|
|
259
|
-
flow.resolve({ ...flow.status, phase: "waiting" });
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
child.stdout.on("data", receive);
|
|
263
|
-
child.stderr.on("data", receive);
|
|
264
|
-
child.once("error", (error) => {
|
|
265
|
-
const message = error.code === "ENOENT"
|
|
266
|
-
? "Codex is not installed on this server. Run npm install -g @openai/codex@latest on the server, then try again."
|
|
267
|
-
: "Codex could not start on this server. Check the configured CLI path and its executable permissions.";
|
|
268
|
-
this.finish(flow, "failed", message);
|
|
269
|
-
});
|
|
270
|
-
child.once("close", (code) => {
|
|
271
|
-
if (flow.child === child)
|
|
272
|
-
flow.child = null;
|
|
273
|
-
if (flow.status.phase === "waiting")
|
|
274
|
-
done(code, stripVTControlCharacters(output));
|
|
275
|
-
output = "";
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
finish(flow, phase, message) {
|
|
279
|
-
if (flow.status.phase !== "waiting")
|
|
280
|
-
return;
|
|
281
|
-
clearTimeout(flow.startupTimer);
|
|
282
|
-
clearTimeout(flow.expiryTimer);
|
|
283
|
-
flow.status = {
|
|
284
|
-
phase, flowId: flow.status.flowId, authorizationUrl: null, expiresAt: null,
|
|
285
|
-
...(phase !== "succeeded" && message ? { message } : {}),
|
|
286
|
-
};
|
|
287
|
-
if (!flow.ready) {
|
|
288
|
-
if (phase === "succeeded")
|
|
289
|
-
flow.resolve({ ...flow.status, phase });
|
|
290
|
-
else
|
|
291
|
-
flow.reject(new Error(message ?? "ChatGPT sign-in did not finish."));
|
|
292
|
-
}
|
|
293
|
-
flow.stopping = this.stopChild(flow.child).catch(() => false).then((stopped) => {
|
|
294
|
-
const release = () => authenticatingHomes.delete(flow.homeKey);
|
|
295
|
-
if (stopped) {
|
|
296
|
-
release();
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
flow.terminationFailed = true;
|
|
300
|
-
flow.status = { ...flow.status, phase: "failed", message: "Codex could not be stopped on this server. Ask the server administrator to stop the login process before trying again." };
|
|
301
|
-
// Retain the credential-home lock until the OS actually reports exit.
|
|
302
|
-
const child = flow.child;
|
|
303
|
-
if (!child || child.exitCode !== null || child.signalCode !== null)
|
|
304
|
-
release();
|
|
305
|
-
else
|
|
306
|
-
child.once("close", release);
|
|
307
|
-
});
|
|
308
|
-
if (phase === "succeeded")
|
|
309
|
-
void this.options.onAuthenticated?.().catch(() => { });
|
|
310
|
-
}
|
|
311
|
-
async stopChild(child) {
|
|
312
|
-
if (!child || await killCliTree(child, this.options.terminateTimeoutMs ?? 1500))
|
|
313
|
-
return true;
|
|
314
|
-
// A broken CLI may ignore SIGTERM. Do not leave a stale device flow able
|
|
315
|
-
// to write credentials after the user cancelled it.
|
|
316
|
-
if (process.platform !== "win32" && child.pid) {
|
|
317
|
-
try {
|
|
318
|
-
process.kill(-child.pid, "SIGKILL");
|
|
319
|
-
}
|
|
320
|
-
catch {
|
|
321
|
-
child.kill("SIGKILL");
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
else
|
|
325
|
-
child.kill("SIGKILL");
|
|
326
|
-
await new Promise((resolveStop) => {
|
|
327
|
-
if (child.exitCode !== null || child.signalCode !== null)
|
|
328
|
-
return resolveStop();
|
|
329
|
-
const timer = setTimeout(resolveStop, 1500);
|
|
330
|
-
timer.unref();
|
|
331
|
-
child.once("close", () => { clearTimeout(timer); resolveStop(); });
|
|
332
|
-
});
|
|
333
|
-
return child.exitCode !== null || child.signalCode !== null;
|
|
334
|
-
}
|
|
23
|
+
export const CODEX_DEVICE_SIGN_IN = {
|
|
24
|
+
provider: "codex",
|
|
25
|
+
product: "Codex",
|
|
26
|
+
account: "ChatGPT",
|
|
27
|
+
homeEnv: "CODEX_HOME",
|
|
28
|
+
homeDir: ".codex",
|
|
29
|
+
loginArgs: ["login", "--device-auth"],
|
|
30
|
+
install: "Run npm install -g @openai/codex@latest on the server, then try again.",
|
|
31
|
+
failure: loginFailure,
|
|
32
|
+
status: {
|
|
33
|
+
args: ["login", "status"],
|
|
34
|
+
read: (code, output) => code === 0 && /^logged in.*chatgpt\b/im.test(output) ? "signed-in"
|
|
35
|
+
: code === 0 && /^logged in\b/im.test(output) ? "other"
|
|
36
|
+
: code !== 0 && /^not logged in\b/im.test(output) ? "signed-out"
|
|
37
|
+
: "unknown",
|
|
38
|
+
},
|
|
39
|
+
logoutArgs: ["logout"],
|
|
40
|
+
};
|
|
41
|
+
export class CodexDeviceAuthController extends DeviceAuthController {
|
|
42
|
+
constructor(options) { super(CODEX_DEVICE_SIGN_IN, options); }
|
|
335
43
|
}
|