mycode-cli 0.6.0__tar.gz → 0.7.0__tar.gz
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.
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/PKG-INFO +2 -2
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/pyproject.toml +2 -2
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/config.py +51 -1
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/main.py +34 -9
- mycode_cli-0.7.0/src/mycode_cli/permissions.py +228 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/runtime.py +6 -1
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/routers/chat.py +26 -2
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/run_manager.py +75 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/schemas.py +11 -0
- mycode_cli-0.6.0/src/mycode_cli/server/static/assets/EditDiff-CyrLN4Wq.js → mycode_cli-0.7.0/src/mycode_cli/server/static/assets/EditDiff-C5JPx5vJ.js +1 -1
- mycode_cli-0.6.0/src/mycode_cli/server/static/assets/index-iNJwUrpx.css → mycode_cli-0.7.0/src/mycode_cli/server/static/assets/index-CbtQLsjO.css +1 -1
- mycode_cli-0.7.0/src/mycode_cli/server/static/assets/index-Dp879Ucn.js +476 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/index.html +2 -2
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/tui/chat.py +32 -1
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/tui/render.py +22 -3
- mycode_cli-0.6.0/src/mycode_cli/server/static/assets/index-Bu2AYfiR.js +0 -476
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/.gitignore +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/LICENSE +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/README.md +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/hatch_build.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/__init__.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/__init__.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/app.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/deps.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/routers/__init__.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/routers/sessions.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/routers/workspaces.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/abap-BdImnpbu.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/actionscript-3-CoDkCxhg.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ada-bCR0ucgS.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/andromeeda-C4gqWexZ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/angular-html-CU67Zn6k.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/angular-ts-BwZT4LLn.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/apache-Pmp26Uib.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/apex-D8_7TLub.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/apl-dKokRX4l.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/applescript-Co6uUVPk.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ara-BRHolxvo.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/asciidoc-Ve4PFQV2.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/asm-D_Q5rh1f.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/astro-CbQHKStN.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/aurora-x-D-2ljcwZ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/awk-DMzUqQB5.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ayu-dark-DYE7WIF3.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ayu-light-BA47KaF1.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ayu-mirage-32ctXXKs.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ballerina-BFfxhgS-.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/bat-BkioyH1T.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/beancount-k_qm7-4y.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/berry-uYugtg8r.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/bibtex-CHM0blh-.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/bicep-Bmn6On1c.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/bird2-DPOp833l.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/blade-D4QpJJKB.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/bsl-BO_Y6i37.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/c-BIGW1oBm.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/c3-eo99z4R2.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/cadence-Bv_4Rxtq.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/cairo-KRGpt6FW.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/catppuccin-frappe-DFWUc33u.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/catppuccin-latte-C9dUb6Cb.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/catppuccin-macchiato-DQyhUUbL.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/catppuccin-mocha-D87Tk5Gz.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/clarity-D53aC0YG.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/clojure-P80f7IUj.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/cmake-D1j8_8rp.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/cobol-nwyudZeR.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/codeowners-Bp6g37R7.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/codeql-DsOJ9woJ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/coffee-Ch7k5sss.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/common-lisp-Cg-RD9OK.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/coq-DkFqJrB1.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/cpp-CofmeUqb.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/crystal-tKQVLTB8.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/csharp-COcwbKMJ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/css-DPfMkruS.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/csv-fuZLfV_i.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/cue-D82EKSYY.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/cypher-COkxafJQ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/d-85-TOEBH.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/dark-plus-C3mMm8J8.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/dart-CF10PKvl.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/dax-CEL-wOlO.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/desktop-BmXAJ9_W.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/diff-D97Zzqfu.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/docker-BcOcwvcX.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/dotenv-Da5cRb03.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/dracula-BzJJZx-M.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/dracula-soft-BXkSAIEj.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/dream-maker-BtqSS_iP.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/edge-BkV0erSs.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/elixir-CDX3lj18.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/elm-DbKCFpqz.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/emacs-lisp-C9XAeP06.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/erb-B12qg9BL.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/erlang-DsQrWhSR.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/everforest-dark-BgDCqdQA.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/everforest-light-C8M2exoo.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/fennel-BYunw83y.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/fish-BvzEVeQv.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/fluent-C4IJs8-o.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/fortran-fixed-form-CkoXwp7k.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/fortran-free-form-BxgE0vQu.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/fsharp-CXgrBDvD.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gdresource-BOOCDP_w.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gdscript-C5YyOfLZ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gdshader-DkwncUOv.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/genie-D0YGMca9.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gherkin-DyxjwDmM.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/git-commit-F4YmCXRG.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/git-rebase-r7XF79zn.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/github-dark-DHJKELXO.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/github-dark-default-Cuk6v7N8.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/github-dark-dimmed-DH5Ifo-i.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/github-light-DAi9KRSo.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/github-light-default-D7oLnXFd.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/github-light-high-contrast-BfjtVDDH.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gleam-BspZqrRM.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/glimmer-js-Rg0-pVw9.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/glimmer-ts-U6CK756n.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/glsl-DplSGwfg.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gn-n2N0HUVH.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gnuplot-DdkO51Og.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/go-CxLEBnE3.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/graphql-ChdNCCLP.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/groovy-gcz8RCvz.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gruvbox-dark-medium-GsRaNv29.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gruvbox-dark-soft-CVdnzihN.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gruvbox-light-hard-CH1njM8p.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gruvbox-light-medium-DRw_LuNl.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/gruvbox-light-soft-hJgmCMqR.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/hack-CaT9iCJl.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/haml-B8DHNrY2.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/handlebars-BL8al0AC.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/haskell-Df6bDoY_.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/haxe-CzTSHFRz.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/hcl-BWvSN4gD.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/hjson-D5-asLiD.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/hlsl-D3lLCCz7.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/horizon-BUw7H-hv.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/horizon-bright-Cn-bp-IR.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/houston-DnULxvSX.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/html-GMplVEZG.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/html-derivative-BFtXZ54Q.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/http-jrhK8wxY.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/hurl-irOxFIW8.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/hxml-Bvhsp5Yf.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/hy-DFXneXwc.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/imba-DGztddWO.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ini-BEwlwnbL.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/java-CylS5w8V.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/javascript-wDzz0qaB.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/jinja-4LBKfQ-Z.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/jison-wvAkD_A8.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/json-Cp-IABpG.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/json5-C9tS-k6U.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/jsonc-Des-eS-w.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/jsonl-DcaNXYhu.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/jsonnet-DFQXde-d.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/jssm-C2t-YnRu.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/jsx-g9-lgVsj.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/julia-CxzCAyBv.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/just-Cw27pwNe.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/kanagawa-dragon-CkXjmgJE.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/kanagawa-lotus-CfQXZHmo.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/kanagawa-wave-DWedfzmr.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/kdl-DV7GczEv.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/kotlin-BdnUsdx6.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/kusto-DZf3V79B.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/laserwave-DUszq2jm.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/latex-CWtU0Tv5.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/lean-BZvkOJ9d.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/less-B1dDrJ26.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/light-plus-B7mTdjB0.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/liquid-DYVedYrR.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/llvm-DjAJT7YJ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/log-2UxHyX5q.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/logo-BtOb2qkB.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/lua-BaeVxFsk.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/luau-C-HG3fhB.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/make-CHLpvVh8.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/markdown-Cvjx9yec.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/marko-CnJfTvn9.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/material-theme-D5KoaKCx.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/material-theme-darker-BfHTSMKl.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/material-theme-lighter-B0m2ddpp.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/material-theme-ocean-CyktbL80.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/material-theme-palenight-Csfq5Kiy.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/matlab-D7o27uSR.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/mdc-BMNejdWA.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/mdx-Cmh6b_Ma.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/mermaid-mWjccvbQ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/min-dark-CafNBF8u.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/min-light-CTRr51gU.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/mipsasm-CKIfxQSi.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/mojo-rZm6bMo-.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/monokai-D4h5O-jR.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/moonbit-_H4v1dQx.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/move-IF9eRakj.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/narrat-DRg8JJMk.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/nextflow-Zz6hmt5N.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/nextflow-groovy-BeH2EWoN.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/nginx-BpAMiNFr.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/night-owl-C39BiMTA.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/night-owl-light-CMTm3GFP.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/nim-CVrawwO9.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/nix-CwoSXNpI.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/nord-Ddv68eIx.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/nushell-Cz2AlsmD.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/objective-c-DXmwc3jG.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/objective-cpp-CLxacb5B.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ocaml-C0hk2d4L.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/odin-BBf5iR-q.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/one-dark-pro-DVMEJ2y_.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/one-light-C3Wv6jpd.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/openscad-C4EeE6gA.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/pascal-D93ZcfNL.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/perl-C0TMdlhV.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/php-Dhbhpdrm.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/pierre-dark-DF2SEV7i.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/pierre-light-DOlZxES8.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/pkl-u5AG7uiY.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/plastic-3e1v2bzS.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/plsql-ChMvpjG-.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/po-BTJTHyun.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/poimandres-CS3Unz2-.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/polar-C0HS_06l.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/postcss-CXtECtnM.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/powerquery-CEu0bR-o.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/powershell-Dpen1YoG.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/prisma-Dd19v3D-.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/prolog-CbFg5uaA.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/proto-C7zT0LnQ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/pug-CGlum2m_.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/puppet-BMWR74SV.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/purescript-CklMAg4u.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/python-B6aJPvgy.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/qml-3beO22l8.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/qmldir-C8lEn-DE.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/qss-IeuSbFQv.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/r-Dspwwk_N.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/racket-BqYA7rlc.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/raku-DXvB9xmW.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/razor-Uh8Bk_45.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/red-bN70gL4F.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/reg-C-SQnVFl.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/regexp-CDVJQ6XC.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/rel-C3B-1QV4.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/riscv-BM1_JUlF.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ron-D8l8udqQ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/rose-pine-dawn-DHQR4-dF.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/rose-pine-moon-D4_iv3hh.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/rose-pine-qdsjHGoJ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/rosmsg-BJDFO7_C.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/rst-BrH8l1NY.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ruby-Dw2BHqvy.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/rust-B1yitclQ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/sas-cz2c8ADy.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/sass-Cj5Yp3dK.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/scala-C151Ov-r.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/scheme-C98Dy4si.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/scss-OYdSNvt2.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/sdbl-DVxCFoDh.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/shaderlab-Dg9Lc6iA.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/shellscript-Yzrsuije.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/shellsession-BADoaaVG.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/slack-dark-BthQWCQV.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/slack-ochin-DqwNpetd.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/smalltalk-BERRCDM3.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/snazzy-light-Bw305WKR.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/solarized-dark-DXbdFlpD.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/solarized-light-L9t79GZl.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/solidity-rGO070M0.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/soy-Brmx7dQM.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/sparql-rVzFXLq3.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/splunk-BtCnVYZw.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/sql-BLtJtn59.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ssh-config-_ykCGR6B.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/stata-BH5u7GGu.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/stylus-BEDo0Tqx.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/surrealql-Bq5Q-fJD.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/svelte-C_ipcX3V.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/swift-D82vCrfD.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/synthwave-84-CbfX1IO0.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/system-verilog-CnnmHF94.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/systemd-4A_iFExJ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/talonscript-CkByrt1z.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/tasl-QIJgUcNo.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/tcl-dwOrl1Do.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/templ-P3uqSqPl.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/terraform-BETggiCN.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/tex-idrVyKtj.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/tokyo-night-hegEt444.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/toml-vGWfd6FD.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/ts-tags-zn1MmPIZ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/tsv-B_m7g4N7.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/tsx-COt5Ahok.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/turtle-BsS91CYL.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/twig-DNn4PbVi.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/typescript-BPQ3VLAy.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/typespec-BGHnOYBU.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/typst-DHCkPAjA.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/v-BcVCzyr7.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vala-CsfeWuGM.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vb-D17OF-Vu.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/verilog-BQ8w6xss.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vesper-DU1UobuO.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vhdl-CeAyd5Ju.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/viml-CJc9bBzg.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vitesse-black-Bkuqu6BP.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vitesse-dark-D0r3Knsf.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vitesse-light-CVO1_9PV.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vue-DN_0RTcg.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vue-html-AaS7Mt5G.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vue-vine-CQOfvN7w.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/vyper-CDx5xZoG.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/wasm-CG6Dc4jp.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/wasm-MzD3tlZU.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/wenyan-BV7otONQ.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/wgsl-Dx-B1_4e.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/wikitext-BhOHFoWU.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/wit-5i3qLPDT.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/wolfram-lXgVvXCa.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/xml-sdJ4AIDG.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/xsl-CtQFsRM5.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/yaml-Buea-lGh.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/zenscript-DVFEvuxE.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/assets/zig-VOosw3JB.js +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/server/static/favicon_slashes.svg +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/system_prompt.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/tui/__init__.py +0 -0
- {mycode_cli-0.6.0 → mycode_cli-0.7.0}/src/mycode_cli/tui/theme.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mycode-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Minimal coding agent CLI and web UI built on mycode-sdk.
|
|
5
5
|
Project-URL: Homepage, https://github.com/legibet/mycode
|
|
6
6
|
Project-URL: Repository, https://github.com/legibet/mycode
|
|
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
22
22
|
Classifier: Topic :: Software Development
|
|
23
23
|
Requires-Python: >=3.12
|
|
24
24
|
Requires-Dist: fastapi>=0.115.0
|
|
25
|
-
Requires-Dist: mycode-sdk==0.
|
|
25
|
+
Requires-Dist: mycode-sdk==0.7.0
|
|
26
26
|
Requires-Dist: prompt-toolkit>=3.0.52
|
|
27
27
|
Requires-Dist: pyyaml>=6.0.0
|
|
28
28
|
Requires-Dist: rich>=14.2.0
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mycode-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.0"
|
|
8
8
|
description = "Minimal coding agent CLI and web UI built on mycode-sdk."
|
|
9
9
|
requires-python = ">=3.12"
|
|
10
10
|
license = "MIT"
|
|
@@ -26,7 +26,7 @@ classifiers = [
|
|
|
26
26
|
]
|
|
27
27
|
keywords = ["agent", "cli", "llm", "coding-agent", "fastapi"]
|
|
28
28
|
dependencies = [
|
|
29
|
-
"mycode-sdk==0.
|
|
29
|
+
"mycode-sdk==0.7.0",
|
|
30
30
|
"fastapi>=0.115.0",
|
|
31
31
|
"uvicorn[standard]>=0.32.0",
|
|
32
32
|
"rich>=14.2.0",
|
|
@@ -8,7 +8,7 @@ import os
|
|
|
8
8
|
import re
|
|
9
9
|
from dataclasses import dataclass, field
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Any
|
|
11
|
+
from typing import Any, Literal
|
|
12
12
|
|
|
13
13
|
from mycode.models import resolve_model_metadata
|
|
14
14
|
from mycode.providers import (
|
|
@@ -42,9 +42,14 @@ _API_KEY_ENV_REF_RE = re.compile(r"^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$")
|
|
|
42
42
|
# Full set of user-facing choices. "auto" means "do not send an explicit effort
|
|
43
43
|
# to the provider" and is represented internally as `None` after normalization.
|
|
44
44
|
REASONING_EFFORT_OPTIONS = ("auto", "none", "low", "medium", "high", "xhigh")
|
|
45
|
+
PERMISSION_LEVEL_OPTIONS = ("readonly", "safe", "standard", "yolo")
|
|
46
|
+
PERMISSION_MODE_OPTIONS = ("ask", "deny")
|
|
45
47
|
_EFFORT_AUTO_ALIASES = frozenset({"", "auto", "default"})
|
|
46
48
|
_EFFORT_OFF_ALIASES = frozenset({"off", "disabled"})
|
|
47
49
|
|
|
50
|
+
PermissionLevel = Literal["readonly", "safe", "standard", "yolo"]
|
|
51
|
+
PermissionMode = Literal["ask", "deny"]
|
|
52
|
+
|
|
48
53
|
|
|
49
54
|
@dataclass(frozen=True)
|
|
50
55
|
class ModelConfig:
|
|
@@ -66,6 +71,12 @@ class ProviderConfig:
|
|
|
66
71
|
reasoning_effort: str | None = None
|
|
67
72
|
|
|
68
73
|
|
|
74
|
+
@dataclass(frozen=True)
|
|
75
|
+
class PermissionConfig:
|
|
76
|
+
level: PermissionLevel = "safe"
|
|
77
|
+
mode: PermissionMode = "ask"
|
|
78
|
+
|
|
79
|
+
|
|
69
80
|
@dataclass(frozen=True)
|
|
70
81
|
class Settings:
|
|
71
82
|
providers: dict[str, ProviderConfig]
|
|
@@ -76,6 +87,7 @@ class Settings:
|
|
|
76
87
|
workspace_root: str
|
|
77
88
|
default_reasoning_effort: str | None = None
|
|
78
89
|
compact_threshold: float | None = None
|
|
90
|
+
permission: PermissionConfig = field(default_factory=PermissionConfig)
|
|
79
91
|
config_paths: list[str] = field(default_factory=list)
|
|
80
92
|
|
|
81
93
|
|
|
@@ -197,6 +209,39 @@ def normalize_reasoning_effort(value: Any) -> str | None:
|
|
|
197
209
|
raise ValueError(f"unsupported reasoning_effort {value!r}; supported: {supported}")
|
|
198
210
|
|
|
199
211
|
|
|
212
|
+
def normalize_permission_level(value: Any) -> PermissionLevel:
|
|
213
|
+
if not isinstance(value, str):
|
|
214
|
+
raise ValueError(f"permission level must be a string, got {type(value).__name__}")
|
|
215
|
+
level = value.strip().lower()
|
|
216
|
+
if level in PERMISSION_LEVEL_OPTIONS:
|
|
217
|
+
return level
|
|
218
|
+
supported = ", ".join(PERMISSION_LEVEL_OPTIONS)
|
|
219
|
+
raise ValueError(f"unsupported permission level {value!r}; supported: {supported}")
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def normalize_permission_mode(value: Any) -> PermissionMode:
|
|
223
|
+
if not isinstance(value, str):
|
|
224
|
+
raise ValueError(f"permission mode must be a string, got {type(value).__name__}")
|
|
225
|
+
mode = value.strip().lower()
|
|
226
|
+
if mode in PERMISSION_MODE_OPTIONS:
|
|
227
|
+
return mode
|
|
228
|
+
supported = ", ".join(PERMISSION_MODE_OPTIONS)
|
|
229
|
+
raise ValueError(f"unsupported permission mode {value!r}; supported: {supported}")
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def parse_permission(value: Any, current: PermissionConfig | None = None) -> PermissionConfig:
|
|
233
|
+
base = current or PermissionConfig()
|
|
234
|
+
if value is None:
|
|
235
|
+
return base
|
|
236
|
+
if isinstance(value, str):
|
|
237
|
+
return PermissionConfig(level=normalize_permission_level(value), mode=base.mode)
|
|
238
|
+
if isinstance(value, dict):
|
|
239
|
+
level = normalize_permission_level(value.get("level")) if "level" in value else base.level
|
|
240
|
+
mode = normalize_permission_mode(value.get("mode")) if "mode" in value else base.mode
|
|
241
|
+
return PermissionConfig(level=level, mode=mode)
|
|
242
|
+
raise ValueError(f"permission must be a string or object, got {type(value).__name__}")
|
|
243
|
+
|
|
244
|
+
|
|
200
245
|
def _config_api_key_from_env_var(provider: ProviderConfig, *, require: bool = False) -> str | None:
|
|
201
246
|
env_name = provider.api_key_env_var
|
|
202
247
|
if not env_name:
|
|
@@ -267,6 +312,7 @@ def get_settings(cwd: str | None = None) -> Settings:
|
|
|
267
312
|
default_model: str | None = None
|
|
268
313
|
default_reasoning_effort: str | None = None
|
|
269
314
|
compact_threshold: float | None = None
|
|
315
|
+
permission = PermissionConfig()
|
|
270
316
|
config_paths: list[str] = []
|
|
271
317
|
|
|
272
318
|
for path in _candidate_config_paths(resolved_cwd):
|
|
@@ -315,12 +361,16 @@ def get_settings(cwd: str | None = None) -> Settings:
|
|
|
315
361
|
if parsed_threshold is not None:
|
|
316
362
|
compact_threshold = parsed_threshold
|
|
317
363
|
|
|
364
|
+
if "permission" in data:
|
|
365
|
+
permission = parse_permission(data.get("permission"), permission)
|
|
366
|
+
|
|
318
367
|
return Settings(
|
|
319
368
|
providers=_build_providers(raw_providers),
|
|
320
369
|
default_provider=default_provider,
|
|
321
370
|
default_model=default_model,
|
|
322
371
|
default_reasoning_effort=normalize_reasoning_effort(default_reasoning_effort),
|
|
323
372
|
compact_threshold=compact_threshold,
|
|
373
|
+
permission=permission,
|
|
324
374
|
port=int(os.environ.get("PORT", "8000")),
|
|
325
375
|
cwd=resolved_cwd,
|
|
326
376
|
workspace_root=str(workspace_root),
|
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import os
|
|
7
7
|
import sys
|
|
8
|
-
from dataclasses import dataclass
|
|
8
|
+
from dataclasses import dataclass, replace
|
|
9
9
|
from typing import Annotated
|
|
10
10
|
|
|
11
11
|
import typer
|
|
@@ -14,7 +14,15 @@ from mycode.agent import Agent
|
|
|
14
14
|
from mycode.messages import ConversationMessage
|
|
15
15
|
from mycode.session import SessionStore
|
|
16
16
|
from mycode_cli import __version__
|
|
17
|
-
from mycode_cli.config import
|
|
17
|
+
from mycode_cli.config import (
|
|
18
|
+
ResolvedProvider,
|
|
19
|
+
Settings,
|
|
20
|
+
get_settings,
|
|
21
|
+
parse_permission,
|
|
22
|
+
resolve_provider,
|
|
23
|
+
resolve_sessions_dir,
|
|
24
|
+
)
|
|
25
|
+
from mycode_cli.permissions import PERMISSION_DENIED_BY_USER_OUTPUT, PERMISSION_DENIED_OUTPUT
|
|
18
26
|
|
|
19
27
|
from .runtime import ResolvedSession, build_agent, resolve_session
|
|
20
28
|
from .tui.chat import TerminalChat
|
|
@@ -46,10 +54,10 @@ async def run_noninteractive(agent: Agent, message: str) -> int:
|
|
|
46
54
|
async for event in agent.achat(message, on_persist=track):
|
|
47
55
|
if event.type == "error":
|
|
48
56
|
error_message = str(event.data.get("message") or "agent error")
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
elif event.type == "tool_done" and event.data.get("is_error"):
|
|
58
|
+
output = str(event.data.get("output") or "")
|
|
59
|
+
if output in {PERMISSION_DENIED_OUTPUT, PERMISSION_DENIED_BY_USER_OUTPUT}:
|
|
60
|
+
error_message = output
|
|
53
61
|
|
|
54
62
|
reply = ""
|
|
55
63
|
if latest_assistant:
|
|
@@ -63,6 +71,12 @@ async def run_noninteractive(agent: Agent, message: str) -> int:
|
|
|
63
71
|
sys.stdout.write(reply)
|
|
64
72
|
if not reply.endswith("\n"):
|
|
65
73
|
sys.stdout.write("\n")
|
|
74
|
+
|
|
75
|
+
if error_message:
|
|
76
|
+
if not reply:
|
|
77
|
+
print(error_message, file=sys.stderr)
|
|
78
|
+
return 1
|
|
79
|
+
|
|
66
80
|
return 0
|
|
67
81
|
|
|
68
82
|
|
|
@@ -83,6 +97,7 @@ def _bootstrap(
|
|
|
83
97
|
session: str | None,
|
|
84
98
|
continue_last: bool,
|
|
85
99
|
max_turns: int | None,
|
|
100
|
+
permission: str | None,
|
|
86
101
|
) -> _BootstrapContext:
|
|
87
102
|
"""Shared setup for the chat and run commands."""
|
|
88
103
|
|
|
@@ -92,9 +107,10 @@ def _bootstrap(
|
|
|
92
107
|
cwd = os.path.abspath(os.getcwd())
|
|
93
108
|
store = SessionStore(data_dir=resolve_sessions_dir())
|
|
94
109
|
view = TerminalView()
|
|
95
|
-
settings = get_settings(cwd)
|
|
96
|
-
|
|
97
110
|
try:
|
|
111
|
+
settings = get_settings(cwd)
|
|
112
|
+
if permission is not None:
|
|
113
|
+
settings = replace(settings, permission=parse_permission(permission, settings.permission))
|
|
98
114
|
resolved_provider = resolve_provider(settings, provider_name=provider, model=model)
|
|
99
115
|
resolved_session = asyncio.run(
|
|
100
116
|
resolve_session(
|
|
@@ -136,6 +152,10 @@ def chat(
|
|
|
136
152
|
provider: Annotated[str | None, typer.Option(help="Provider id or configured alias")] = None,
|
|
137
153
|
model: Annotated[str | None, typer.Option(help="Model name (overrides default)")] = None,
|
|
138
154
|
max_turns: Annotated[int | None, typer.Option(min=1, help="Limit agent loop turns")] = None,
|
|
155
|
+
permission: Annotated[
|
|
156
|
+
str | None,
|
|
157
|
+
typer.Option("--permission", help="Permission level: readonly, safe, standard, yolo"),
|
|
158
|
+
] = None,
|
|
139
159
|
session: Annotated[str | None, typer.Option(help="Resume a specific session id")] = None,
|
|
140
160
|
continue_last: Annotated[bool, typer.Option("--continue", "-c", help="Resume the most recent session")] = False,
|
|
141
161
|
version: Annotated[
|
|
@@ -146,7 +166,6 @@ def chat(
|
|
|
146
166
|
callback=_show_version,
|
|
147
167
|
help="Show version and exit.",
|
|
148
168
|
is_eager=True,
|
|
149
|
-
is_flag=True,
|
|
150
169
|
),
|
|
151
170
|
] = False,
|
|
152
171
|
) -> None:
|
|
@@ -164,6 +183,7 @@ def chat(
|
|
|
164
183
|
session=session,
|
|
165
184
|
continue_last=continue_last,
|
|
166
185
|
max_turns=max_turns,
|
|
186
|
+
permission=permission,
|
|
167
187
|
)
|
|
168
188
|
|
|
169
189
|
setup.view.print_header(
|
|
@@ -197,6 +217,10 @@ def run(
|
|
|
197
217
|
provider: Annotated[str | None, typer.Option(help="Provider id or configured alias")] = None,
|
|
198
218
|
model: Annotated[str | None, typer.Option(help="Model name (overrides default)")] = None,
|
|
199
219
|
max_turns: Annotated[int | None, typer.Option(min=1, help="Limit agent loop turns")] = None,
|
|
220
|
+
permission: Annotated[
|
|
221
|
+
str | None,
|
|
222
|
+
typer.Option("--permission", help="Permission level: readonly, safe, standard, yolo"),
|
|
223
|
+
] = None,
|
|
200
224
|
session: Annotated[str | None, typer.Option(help="Resume a specific session id")] = None,
|
|
201
225
|
continue_last: Annotated[bool, typer.Option("--continue", "-c", help="Resume the most recent session")] = False,
|
|
202
226
|
) -> None:
|
|
@@ -208,6 +232,7 @@ def run(
|
|
|
208
232
|
session=session,
|
|
209
233
|
continue_last=continue_last,
|
|
210
234
|
max_turns=max_turns,
|
|
235
|
+
permission=permission,
|
|
211
236
|
)
|
|
212
237
|
|
|
213
238
|
code = asyncio.run(run_noninteractive(setup.agent, " ".join(message).strip()))
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"""CLI permission policy built on SDK tool hooks."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import shlex
|
|
6
|
+
from collections.abc import Awaitable, Callable
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Literal, NamedTuple
|
|
10
|
+
|
|
11
|
+
from mycode import Hooks, ToolExecutionResult, ToolHookContext
|
|
12
|
+
from mycode.tools import resolve_path
|
|
13
|
+
from mycode_cli.config import PermissionConfig, PermissionLevel, Settings
|
|
14
|
+
from mycode_cli.system_prompt import discover_skills
|
|
15
|
+
|
|
16
|
+
PermissionTier = Literal["readonly", "safe", "standard", "yolo"]
|
|
17
|
+
PermissionDecision = Literal["allow", "ask", "deny"]
|
|
18
|
+
ToolReviewDecision = Literal["allow", "deny"]
|
|
19
|
+
|
|
20
|
+
PERMISSION_DENIED_OUTPUT = "error: permission denied"
|
|
21
|
+
PERMISSION_DENIED_BY_USER_OUTPUT = "error: permission denied by user"
|
|
22
|
+
|
|
23
|
+
_LEVEL_RANK: dict[PermissionLevel, int] = {"readonly": 0, "safe": 1, "standard": 2, "yolo": 3}
|
|
24
|
+
|
|
25
|
+
_SHELL_CONTROL_TOKENS = {
|
|
26
|
+
"&&", "||", ";", "|", "|&", "&",
|
|
27
|
+
">", ">>", ">|", "&>", ">&",
|
|
28
|
+
"<", "<<", "<<<", "<&",
|
|
29
|
+
} # fmt: skip
|
|
30
|
+
|
|
31
|
+
_DANGEROUS_PROGRAMS = {
|
|
32
|
+
"rm", "rmdir", "mv", "cp", "sudo", "chmod", "chown",
|
|
33
|
+
"kill", "pkill", "dd", "mkfs", "mount", "umount", "shutdown", "reboot",
|
|
34
|
+
} # fmt: skip
|
|
35
|
+
_DANGEROUS_GIT_SUBCOMMANDS = {"reset", "clean", "checkout", "restore"}
|
|
36
|
+
|
|
37
|
+
# awk/sed are excluded: both can write files and shell out, and statically
|
|
38
|
+
# parsing their scripts isn't worth it.
|
|
39
|
+
_READONLY_PROGRAMS = {
|
|
40
|
+
"pwd", "ls", "dir", "tree", "rg", "grep", "cat", "head", "tail",
|
|
41
|
+
"wc", "stat", "file", "du", "df", "which", "env", "printenv",
|
|
42
|
+
"date", "uname", "whoami", "id", "hostname", "ps", "uptime",
|
|
43
|
+
"realpath", "dirname", "basename",
|
|
44
|
+
"sort", "uniq", "cut", "tr",
|
|
45
|
+
} # fmt: skip
|
|
46
|
+
_READONLY_GIT_SUBCOMMANDS = {"status", "diff", "log", "show", "rev-parse", "ls-files", "grep", "blame", "describe"}
|
|
47
|
+
_READONLY_BRANCH_FLAGS = {"-a", "-r", "-v", "-vv", "--all", "--remotes", "--verbose", "--show-current"}
|
|
48
|
+
|
|
49
|
+
# find flags that write files or execute commands.
|
|
50
|
+
_FIND_DANGEROUS_FLAGS = {
|
|
51
|
+
"-delete", "-exec", "-execdir", "-ok", "-okdir",
|
|
52
|
+
"-fprint", "-fprint0", "-fprintf", "-fls",
|
|
53
|
+
} # fmt: skip
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class PermissionCheck(NamedTuple):
|
|
57
|
+
tier: PermissionTier
|
|
58
|
+
preview: str
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass(frozen=True)
|
|
62
|
+
class ToolReviewRequest:
|
|
63
|
+
tool_call_id: str
|
|
64
|
+
tool_name: str
|
|
65
|
+
preview: str
|
|
66
|
+
permission: PermissionConfig
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
ToolReviewCallback = Callable[[ToolReviewRequest], Awaitable[ToolReviewDecision]]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def build_permission_hooks(
|
|
73
|
+
settings: Settings,
|
|
74
|
+
*,
|
|
75
|
+
review: ToolReviewCallback | None = None,
|
|
76
|
+
on_user_denied: Callable[[], None] | None = None,
|
|
77
|
+
) -> Hooks:
|
|
78
|
+
hooks = Hooks()
|
|
79
|
+
workspace_root = Path(settings.workspace_root).resolve(strict=False)
|
|
80
|
+
skill_roots = [Path(s.path).parent.resolve(strict=False) for s in discover_skills(settings.cwd)]
|
|
81
|
+
|
|
82
|
+
@hooks.before_tool
|
|
83
|
+
async def check_permission(ctx: ToolHookContext) -> ToolExecutionResult | None:
|
|
84
|
+
check = classify_tool(ctx, cwd=settings.cwd, workspace_root=workspace_root, skill_roots=skill_roots)
|
|
85
|
+
decision = permission_decision(settings.permission, check.tier)
|
|
86
|
+
if decision == "allow":
|
|
87
|
+
return None
|
|
88
|
+
|
|
89
|
+
if decision == "ask" and review is not None:
|
|
90
|
+
review_decision = await review(
|
|
91
|
+
ToolReviewRequest(
|
|
92
|
+
tool_call_id=ctx.tool_call_id,
|
|
93
|
+
tool_name=ctx.tool_name,
|
|
94
|
+
preview=check.preview,
|
|
95
|
+
permission=settings.permission,
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
if review_decision == "allow":
|
|
99
|
+
return None
|
|
100
|
+
if on_user_denied is not None:
|
|
101
|
+
on_user_denied()
|
|
102
|
+
return ToolExecutionResult(output=PERMISSION_DENIED_BY_USER_OUTPUT, is_error=True)
|
|
103
|
+
|
|
104
|
+
return ToolExecutionResult(output=PERMISSION_DENIED_OUTPUT, is_error=True)
|
|
105
|
+
|
|
106
|
+
return hooks
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def permission_decision(permission: PermissionConfig, tier: PermissionTier) -> PermissionDecision:
|
|
110
|
+
if permission.level == "yolo":
|
|
111
|
+
return "allow"
|
|
112
|
+
if tier != "yolo" and _LEVEL_RANK[tier] <= _LEVEL_RANK[permission.level]:
|
|
113
|
+
return "allow"
|
|
114
|
+
return permission.mode
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def classify_tool(
|
|
118
|
+
ctx: ToolHookContext,
|
|
119
|
+
*,
|
|
120
|
+
cwd: str,
|
|
121
|
+
workspace_root: Path,
|
|
122
|
+
skill_roots: list[Path],
|
|
123
|
+
) -> PermissionCheck:
|
|
124
|
+
name = ctx.tool_name.lower()
|
|
125
|
+
|
|
126
|
+
if name == "bash":
|
|
127
|
+
command = str(ctx.tool_input.get("command") or "").strip()
|
|
128
|
+
return PermissionCheck(_classify_bash(command), command)
|
|
129
|
+
|
|
130
|
+
if name in {"read", "write", "edit"}:
|
|
131
|
+
raw = str(ctx.tool_input.get("path") or "")
|
|
132
|
+
path = Path(resolve_path(raw, cwd=cwd)).resolve(strict=False)
|
|
133
|
+
preview = raw or str(path)
|
|
134
|
+
if name == "read" and any(path.is_relative_to(root) for root in skill_roots):
|
|
135
|
+
return PermissionCheck("readonly", preview)
|
|
136
|
+
if not path.is_relative_to(workspace_root):
|
|
137
|
+
return PermissionCheck("yolo", preview)
|
|
138
|
+
return PermissionCheck("readonly" if name == "read" else "safe", preview)
|
|
139
|
+
|
|
140
|
+
return PermissionCheck("yolo", ctx.tool_name)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _classify_bash(command: str) -> PermissionTier:
|
|
144
|
+
if not command:
|
|
145
|
+
return "yolo"
|
|
146
|
+
# Newlines and shell expansion bypass static analysis; treat as compound.
|
|
147
|
+
if "\n" in command or "\r" in command or "$(" in command or "`" in command:
|
|
148
|
+
return "yolo"
|
|
149
|
+
try:
|
|
150
|
+
lexer = shlex.shlex(command, posix=True, punctuation_chars=True)
|
|
151
|
+
lexer.whitespace_split = True
|
|
152
|
+
tokens = list(lexer)
|
|
153
|
+
words = shlex.split(command, posix=True)
|
|
154
|
+
except ValueError:
|
|
155
|
+
return "yolo"
|
|
156
|
+
if not words or any(t in _SHELL_CONTROL_TOKENS for t in tokens):
|
|
157
|
+
return "yolo"
|
|
158
|
+
|
|
159
|
+
program = Path(words[0]).name
|
|
160
|
+
if _is_dangerous(program, words):
|
|
161
|
+
return "yolo"
|
|
162
|
+
if _is_readonly(program, words):
|
|
163
|
+
return "readonly"
|
|
164
|
+
return "standard"
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _is_dangerous(program: str, words: list[str]) -> bool:
|
|
168
|
+
if program in _DANGEROUS_PROGRAMS:
|
|
169
|
+
return True
|
|
170
|
+
if program == "sed" and any(w == "-i" or w.startswith("-i") for w in words[1:]):
|
|
171
|
+
return True
|
|
172
|
+
if program == "find" and any(w in _FIND_DANGEROUS_FLAGS for w in words[1:]):
|
|
173
|
+
return True
|
|
174
|
+
if program != "git":
|
|
175
|
+
return False
|
|
176
|
+
sub = _git_subcommand(words)
|
|
177
|
+
if sub in _DANGEROUS_GIT_SUBCOMMANDS:
|
|
178
|
+
return True
|
|
179
|
+
return sub == "push" and any(w in {"-f", "--force", "--force-with-lease"} for w in words[2:])
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _is_readonly(program: str, words: list[str]) -> bool:
|
|
183
|
+
if len(words) == 2 and words[1] in {"--version", "-v", "version"}:
|
|
184
|
+
return True
|
|
185
|
+
if program in _READONLY_PROGRAMS:
|
|
186
|
+
return True
|
|
187
|
+
if program == "find":
|
|
188
|
+
return True
|
|
189
|
+
if program == "command" and words[1:2] == ["-v"] and len(words) >= 3:
|
|
190
|
+
return True
|
|
191
|
+
if program == "type" and len(words) >= 2:
|
|
192
|
+
return True
|
|
193
|
+
if program != "git":
|
|
194
|
+
return False
|
|
195
|
+
sub = _git_subcommand(words)
|
|
196
|
+
if sub in _READONLY_GIT_SUBCOMMANDS:
|
|
197
|
+
return True
|
|
198
|
+
if sub == "remote":
|
|
199
|
+
return not any(w in {"add", "remove", "rm", "rename", "set-url"} for w in words[2:])
|
|
200
|
+
if sub == "branch":
|
|
201
|
+
return all(w in _READONLY_BRANCH_FLAGS for w in words[2:])
|
|
202
|
+
return False
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _git_subcommand(words: list[str]) -> str | None:
|
|
206
|
+
i = 1
|
|
207
|
+
while i < len(words):
|
|
208
|
+
w = words[i]
|
|
209
|
+
if w in {"-C", "-c", "--git-dir", "--work-tree"}:
|
|
210
|
+
i += 2
|
|
211
|
+
continue
|
|
212
|
+
if w.startswith("-"):
|
|
213
|
+
i += 1
|
|
214
|
+
continue
|
|
215
|
+
return w
|
|
216
|
+
return None
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
__all__ = [
|
|
220
|
+
"PERMISSION_DENIED_BY_USER_OUTPUT",
|
|
221
|
+
"PERMISSION_DENIED_OUTPUT",
|
|
222
|
+
"ToolReviewCallback",
|
|
223
|
+
"ToolReviewDecision",
|
|
224
|
+
"ToolReviewRequest",
|
|
225
|
+
"build_permission_hooks",
|
|
226
|
+
"classify_tool",
|
|
227
|
+
"permission_decision",
|
|
228
|
+
]
|
|
@@ -16,6 +16,7 @@ from mycode.providers import (
|
|
|
16
16
|
from mycode.session import SessionStore
|
|
17
17
|
from mycode.tools import DEFAULT_TOOL_SPECS
|
|
18
18
|
from mycode_cli.config import ModelConfig, ResolvedProvider, Settings, provider_has_api_key
|
|
19
|
+
from mycode_cli.permissions import ToolReviewCallback, build_permission_hooks
|
|
19
20
|
from mycode_cli.system_prompt import build_system_prompt
|
|
20
21
|
|
|
21
22
|
|
|
@@ -51,6 +52,7 @@ def build_agent(
|
|
|
51
52
|
session_id: str,
|
|
52
53
|
max_turns: int | None = None,
|
|
53
54
|
reasoning_effort: str | None = None,
|
|
55
|
+
review: ToolReviewCallback | None = None,
|
|
54
56
|
) -> Agent:
|
|
55
57
|
"""Build an agent from the resolved provider, honoring model config overrides.
|
|
56
58
|
|
|
@@ -59,7 +61,7 @@ def build_agent(
|
|
|
59
61
|
"""
|
|
60
62
|
|
|
61
63
|
model_config = model_config_for(settings, resolved_provider)
|
|
62
|
-
|
|
64
|
+
agent = Agent(
|
|
63
65
|
model=resolved_provider.model,
|
|
64
66
|
provider=resolved_provider.provider,
|
|
65
67
|
cwd=cwd,
|
|
@@ -78,6 +80,8 @@ def build_agent(
|
|
|
78
80
|
system=build_system_prompt(cwd, settings),
|
|
79
81
|
tools=DEFAULT_TOOL_SPECS,
|
|
80
82
|
)
|
|
83
|
+
agent.hooks = build_permission_hooks(settings, review=review, on_user_denied=agent.cancel)
|
|
84
|
+
return agent
|
|
81
85
|
|
|
82
86
|
|
|
83
87
|
def model_config_for(settings: Settings, resolved: ResolvedProvider) -> ModelConfig | None:
|
|
@@ -113,6 +117,7 @@ def clone_agent(agent: Agent, *, store: SessionStore, session_id: str) -> Agent:
|
|
|
113
117
|
supports_pdf_input=agent.supports_pdf_input,
|
|
114
118
|
system=agent.system,
|
|
115
119
|
tools=DEFAULT_TOOL_SPECS,
|
|
120
|
+
hooks=agent.hooks,
|
|
116
121
|
)
|
|
117
122
|
|
|
118
123
|
|
|
@@ -30,10 +30,11 @@ from mycode_cli.config import (
|
|
|
30
30
|
resolve_provider,
|
|
31
31
|
resolve_provider_choices,
|
|
32
32
|
)
|
|
33
|
+
from mycode_cli.permissions import ToolReviewDecision, ToolReviewRequest
|
|
33
34
|
from mycode_cli.runtime import build_agent, model_config_for
|
|
34
35
|
from mycode_cli.server.deps import RunManagerDep, StoreDep
|
|
35
|
-
from mycode_cli.server.run_manager import ActiveRunError, RunState
|
|
36
|
-
from mycode_cli.server.schemas import ChatRequest, StreamEvent
|
|
36
|
+
from mycode_cli.server.run_manager import ActiveRunError, RunManager, RunState
|
|
37
|
+
from mycode_cli.server.schemas import ChatRequest, DecideRequest, StreamEvent
|
|
37
38
|
|
|
38
39
|
router = APIRouter()
|
|
39
40
|
|
|
@@ -224,6 +225,7 @@ async def chat(chat: ChatRequest, store: StoreDep, runs: RunManagerDep):
|
|
|
224
225
|
resolved_provider=resolved,
|
|
225
226
|
session_id=session_id,
|
|
226
227
|
reasoning_effort=reasoning_effort,
|
|
228
|
+
review=_make_review(runs, session_id),
|
|
227
229
|
)
|
|
228
230
|
|
|
229
231
|
try:
|
|
@@ -264,6 +266,28 @@ async def cancel_run(run_id: str, runs: RunManagerDep):
|
|
|
264
266
|
return {"status": "ok", "run": run}
|
|
265
267
|
|
|
266
268
|
|
|
269
|
+
@router.post("/runs/{run_id}/decide")
|
|
270
|
+
async def decide_run(run_id: str, body: DecideRequest, runs: RunManagerDep):
|
|
271
|
+
resolved = await runs.resolve_decision(run_id, body.request_id, body.decision)
|
|
272
|
+
if not resolved:
|
|
273
|
+
raise HTTPException(status_code=404, detail="permission request not found")
|
|
274
|
+
return {"status": "ok"}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def _make_review(runs: RunManager, session_id: str):
|
|
278
|
+
"""Bridge before_tool review waits to SSE events on the active run."""
|
|
279
|
+
|
|
280
|
+
async def review(request: ToolReviewRequest) -> ToolReviewDecision:
|
|
281
|
+
return await runs.request_decision(
|
|
282
|
+
session_id=session_id,
|
|
283
|
+
tool_call_id=request.tool_call_id,
|
|
284
|
+
tool_name=request.tool_name,
|
|
285
|
+
preview=request.preview,
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
return review
|
|
289
|
+
|
|
290
|
+
|
|
267
291
|
@router.get("/config")
|
|
268
292
|
async def get_config(cwd: str | None = None):
|
|
269
293
|
resolved_cwd = os.path.abspath(cwd or os.getcwd())
|
|
@@ -12,6 +12,7 @@ from uuid import uuid4
|
|
|
12
12
|
|
|
13
13
|
from mycode.agent import Event
|
|
14
14
|
from mycode.messages import ConversationMessage
|
|
15
|
+
from mycode_cli.permissions import ToolReviewDecision
|
|
15
16
|
|
|
16
17
|
RunStatus = Literal["running", "completed", "failed", "cancelled"]
|
|
17
18
|
FINISHED_RUN_TTL_SECONDS = 300
|
|
@@ -47,6 +48,7 @@ class RunState:
|
|
|
47
48
|
task: asyncio.Task[None] | None = None
|
|
48
49
|
finished_at: float | None = None
|
|
49
50
|
condition: asyncio.Condition = field(default_factory=asyncio.Condition)
|
|
51
|
+
pending_decisions: dict[str, asyncio.Future[ToolReviewDecision]] = field(default_factory=dict)
|
|
50
52
|
|
|
51
53
|
def info(self) -> dict[str, Any]:
|
|
52
54
|
"""Return the public run payload."""
|
|
@@ -125,12 +127,82 @@ class RunManager:
|
|
|
125
127
|
if not state:
|
|
126
128
|
return None
|
|
127
129
|
state.agent.cancel()
|
|
130
|
+
for fut in state.pending_decisions.values():
|
|
131
|
+
if not fut.done():
|
|
132
|
+
fut.cancel()
|
|
128
133
|
return state.info()
|
|
129
134
|
|
|
130
135
|
async def has_active_run(self, session_id: str) -> bool:
|
|
131
136
|
async with self._lock:
|
|
132
137
|
return session_id in self._active_by_session
|
|
133
138
|
|
|
139
|
+
async def request_decision(
|
|
140
|
+
self,
|
|
141
|
+
*,
|
|
142
|
+
session_id: str,
|
|
143
|
+
tool_call_id: str,
|
|
144
|
+
tool_name: str,
|
|
145
|
+
preview: str,
|
|
146
|
+
) -> ToolReviewDecision:
|
|
147
|
+
"""Emit permission_request, await the user's decision, then emit permission_resolved."""
|
|
148
|
+
|
|
149
|
+
async with self._lock:
|
|
150
|
+
state = self._active_by_session.get(session_id)
|
|
151
|
+
if state is None:
|
|
152
|
+
raise RuntimeError(f"no active run for session {session_id!r}")
|
|
153
|
+
|
|
154
|
+
loop = asyncio.get_running_loop()
|
|
155
|
+
request_id = uuid4().hex
|
|
156
|
+
future: asyncio.Future[ToolReviewDecision] = loop.create_future()
|
|
157
|
+
state.pending_decisions[request_id] = future
|
|
158
|
+
|
|
159
|
+
await self._append_event(
|
|
160
|
+
state,
|
|
161
|
+
Event(
|
|
162
|
+
"permission_request",
|
|
163
|
+
{
|
|
164
|
+
"request_id": request_id,
|
|
165
|
+
"tool_use_id": tool_call_id,
|
|
166
|
+
"tool_name": tool_name,
|
|
167
|
+
"preview": preview,
|
|
168
|
+
},
|
|
169
|
+
),
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
decision: ToolReviewDecision = "deny"
|
|
173
|
+
try:
|
|
174
|
+
decision = await future
|
|
175
|
+
return decision
|
|
176
|
+
except asyncio.CancelledError:
|
|
177
|
+
# Treat cancellation as deny so the agent loop unwinds via its own cancel check.
|
|
178
|
+
return decision
|
|
179
|
+
finally:
|
|
180
|
+
state.pending_decisions.pop(request_id, None)
|
|
181
|
+
await self._append_event(
|
|
182
|
+
state,
|
|
183
|
+
Event(
|
|
184
|
+
"permission_resolved",
|
|
185
|
+
{"request_id": request_id, "decision": decision},
|
|
186
|
+
),
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
async def resolve_decision(
|
|
190
|
+
self,
|
|
191
|
+
run_id: str,
|
|
192
|
+
request_id: str,
|
|
193
|
+
decision: ToolReviewDecision,
|
|
194
|
+
) -> bool:
|
|
195
|
+
"""Resolve a pending permission_request future. Returns whether resolved."""
|
|
196
|
+
|
|
197
|
+
state = await self.get_run(run_id)
|
|
198
|
+
if state is None:
|
|
199
|
+
return False
|
|
200
|
+
future = state.pending_decisions.get(request_id)
|
|
201
|
+
if future is None or future.done():
|
|
202
|
+
return False
|
|
203
|
+
future.set_result(decision)
|
|
204
|
+
return True
|
|
205
|
+
|
|
134
206
|
async def _run(self, state: RunState) -> None:
|
|
135
207
|
"""Run the agent and store streamed events."""
|
|
136
208
|
|
|
@@ -163,6 +235,9 @@ class RunManager:
|
|
|
163
235
|
state.condition.notify_all()
|
|
164
236
|
|
|
165
237
|
async def _finish_run(self, state: RunState, *, status: RunStatus, error: str | None = None) -> None:
|
|
238
|
+
for fut in state.pending_decisions.values():
|
|
239
|
+
if not fut.done():
|
|
240
|
+
fut.cancel()
|
|
166
241
|
async with state.condition:
|
|
167
242
|
state.status = status
|
|
168
243
|
state.error = error
|