specrails-desktop 2.15.0 → 2.17.0
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/client/dist/assets/{ActivityFeedPage-C_clKk8d.js → ActivityFeedPage-BLDMBgwL.js} +1 -1
- package/client/dist/assets/AgentsPage-CFaIiyAA.js +86 -0
- package/client/dist/assets/{AnalyticsPage-DZkVU3yd.js → AnalyticsPage-DY8ECq2R.js} +1 -1
- package/client/dist/assets/{BarChart-Dq1h8eYR.js → BarChart-ouivqe5L.js} +2 -2
- package/client/dist/assets/CodePage-DAFtRafz.js +2 -0
- package/client/dist/assets/{DesktopAnalyticsPage-CYhXhJoQ.js → DesktopAnalyticsPage-DIMhuuv0.js} +1 -1
- package/client/dist/assets/{DocsDialog-CS3Syf61.js → DocsDialog-DBYhv3SM.js} +2 -2
- package/client/dist/assets/{DocsPage-l3ZcTO2E.js → DocsPage-DeLRn8W_.js} +2 -2
- package/client/dist/assets/{ExportDropdown-DdB2ncYh.js → ExportDropdown-2XwQ08sz.js} +1 -1
- package/client/dist/assets/{IntegrationsPage-CJ_Om1zu.js → IntegrationsPage-DB-a4FDV.js} +3 -3
- package/client/dist/assets/JobDetailPage-C3lljMiV.js +16 -0
- package/client/dist/assets/JobsPage-CzquwJ6G.js +1 -0
- package/client/dist/assets/LoopBuilderPage-TkoalfW5.js +7 -0
- package/client/dist/assets/LoopsPage-ypooVAQ5.js +1 -0
- package/client/dist/assets/{agents-CQlu1nOm.js → agents-4fnKlwcG.js} +1 -1
- package/client/dist/assets/{agents-DcoUUFZl.js → agents-B-rVIhuw.js} +1 -1
- package/client/dist/assets/{agents-DVYpVGur.js → agents-BRUz6RJs.js} +1 -1
- package/client/dist/assets/{agents-DCX9D3-Q.js → agents-CZQvKDIb.js} +1 -1
- package/client/dist/assets/{agents-BYjUOrLD.js → agents-CuRY-Zg_.js} +1 -1
- package/client/dist/assets/{agents-Jc-CjBDB.js → agents-D7nWnLg6.js} +1 -1
- package/client/dist/assets/{agents-CIhRSOna.js → agents-DzhSlNZd.js} +1 -1
- package/client/dist/assets/{agents-1lhqEcXH.js → agents-E-42N3b1.js} +1 -1
- package/client/dist/assets/{cssMode-DSHXamUH.js → cssMode-BijCvCxs.js} +1 -1
- package/client/dist/assets/{dist-js-Ele_sHO7.js → dist-js-D7m9--SN.js} +1 -1
- package/client/dist/assets/{dist-js-D27I-bfi.js → dist-js-nZhsq1qo.js} +1 -1
- package/client/dist/assets/{editor.main-Cd8qBRAT.js → editor.main-DMIcqwXb.js} +2 -2
- package/client/dist/assets/{freemarker2-CkEKTBm2.js → freemarker2-CP2AizpZ.js} +1 -1
- package/client/dist/assets/{handlebars-BRGx0JpL.js → handlebars-8ElanPOm.js} +1 -1
- package/client/dist/assets/{html-BfRIaGgN.js → html-Mu3b73tG.js} +1 -1
- package/client/dist/assets/{htmlMode-BTpSnsDE.js → htmlMode-tHprGCEv.js} +1 -1
- package/client/dist/assets/index-CDEQ4aU_.js +144 -0
- package/client/dist/assets/{javascript-DMmE2kKN.js → javascript-DlG0apUe.js} +1 -1
- package/client/dist/assets/{jsonMode-hYuaUleY.js → jsonMode-Cr0T4SXO.js} +1 -1
- package/client/dist/assets/{lib-qdRfWwE1.js → lib-Bu76JzdB.js} +2 -2
- package/client/dist/assets/{liquid-C-VbuTr7.js → liquid-QgTgbClC.js} +1 -1
- package/client/dist/assets/{lspLanguageFeatures-BALx-vjn.js → lspLanguageFeatures-D-BxkRza.js} +1 -1
- package/client/dist/assets/mcp-BSCAtU6Y.js +1 -0
- package/client/dist/assets/mcp-Cb6fUaFJ.js +1 -0
- package/client/dist/assets/mcp-CyP0quZ7.js +1 -0
- package/client/dist/assets/mcp-D-zQCO5E.js +1 -0
- package/client/dist/assets/mcp-DCTNWpfB.js +1 -0
- package/client/dist/assets/mcp-DEFGJ1OJ.js +1 -0
- package/client/dist/assets/mcp-DFG9OEXM.js +1 -0
- package/client/dist/assets/mcp-DyERgHA2.js +1 -0
- package/client/dist/assets/{mdx-Cs8MNCzn.js → mdx-B2QTaeRe.js} +1 -1
- package/client/dist/assets/{monaco.contribution-CIvCAJs4.js → monaco.contribution-CkdGfXCC.js} +2 -2
- package/client/dist/assets/{python-CGShLxuI.js → python-BlF0qnMQ.js} +1 -1
- package/client/dist/assets/{razor-CvOBQGd5.js → razor--3PSy3lb.js} +1 -1
- package/client/dist/assets/setup-BiQ7ut8d.js +1 -0
- package/client/dist/assets/setup-BxvjG5Xp.js +1 -0
- package/client/dist/assets/setup-CQ-F6Ciq.js +1 -0
- package/client/dist/assets/setup-D2JlpJEz.js +1 -0
- package/client/dist/assets/setup-DG1R6J6o.js +1 -0
- package/client/dist/assets/setup-DuFJZJsm.js +1 -0
- package/client/dist/assets/setup-DyJszDqm.js +1 -0
- package/client/dist/assets/setup-Ynw19V8w.js +1 -0
- package/client/dist/assets/{tsMode-04uOpiiP.js → tsMode-CHfsvcOI.js} +1 -1
- package/client/dist/assets/{typescript-CX0CwyIZ.js → typescript-Bjxf6BOp.js} +1 -1
- package/client/dist/assets/{upload-DPG87J4t.js → upload-x42OZJr2.js} +1 -1
- package/client/dist/assets/{value-BRVOAvhY.js → value-fEDhg5Bd.js} +1 -1
- package/client/dist/assets/{workers-yr2u4c3C.js → workers-CAAvSda9.js} +1 -1
- package/client/dist/assets/{xml-C0OFlt5X.js → xml-iYCSJ4oL.js} +1 -1
- package/client/dist/assets/{yaml-DgabaPs5.js → yaml-DtO-_yDY.js} +1 -1
- package/client/dist/index.html +10 -9
- package/docs/README.md +2 -0
- package/docs/guide/de/integrations/5-mcp-server.md +74 -0
- package/docs/guide/en/integrations/5-mcp-server.md +74 -0
- package/docs/guide/es/integrations/5-mcp-server.md +74 -0
- package/docs/guide/fr/integrations/5-mcp-server.md +74 -0
- package/docs/guide/it/integrations/5-mcp-server.md +74 -0
- package/docs/guide/ja/integrations/5-mcp-server.md +74 -0
- package/docs/guide/pt/integrations/5-mcp-server.md +74 -0
- package/docs/guide/zh/integrations/5-mcp-server.md +74 -0
- package/docs/mcp.md +249 -0
- package/package.json +8 -5
- package/server/dist/index.js +30 -0
- package/server/dist/loop-command-catalog.js +30 -1
- package/server/dist/loop-run-manager.js +54 -2
- package/server/dist/loop-templates.js +73 -0
- package/server/dist/mcp/guide.js +82 -0
- package/server/dist/mcp/index.js +21 -0
- package/server/dist/mcp/mcp-admin-router.js +71 -0
- package/server/dist/mcp/mcp-server.js +143 -0
- package/server/dist/mcp/mcp-tiers.js +48 -0
- package/server/dist/mcp/mcp-token.js +119 -0
- package/server/dist/mcp/resources.js +24 -0
- package/server/dist/mcp/tools/agents.js +319 -0
- package/server/dist/mcp/tools/analytics.js +168 -0
- package/server/dist/mcp/tools/app-settings.js +81 -0
- package/server/dist/mcp/tools/catalog.js +45 -0
- package/server/dist/mcp/tools/chat.js +147 -0
- package/server/dist/mcp/tools/code.js +145 -0
- package/server/dist/mcp/tools/jira.js +222 -0
- package/server/dist/mcp/tools/jobs.js +258 -0
- package/server/dist/mcp/tools/loops.js +229 -0
- package/server/dist/mcp/tools/meta.js +96 -0
- package/server/dist/mcp/tools/plugins.js +83 -0
- package/server/dist/mcp/tools/projects.js +62 -0
- package/server/dist/mcp/tools/rails.js +181 -0
- package/server/dist/mcp/tools/setup.js +187 -0
- package/server/dist/mcp/tools/specs.js +327 -0
- package/server/dist/mcp/tools/types.js +137 -0
- package/server/dist/mcp/tools/watch.js +93 -0
- package/server/dist/mobile/mobile-event-bus.js +2 -0
- package/server/dist/project-router-tickets.js +2 -2
- package/server/dist/rail-isolation.js +8 -7
- package/server/dist/rails-router.js +10 -5
- package/server/dist/workspace-manager.js +134 -14
- package/client/dist/assets/AgentsPage-jcPUtPhP.js +0 -86
- package/client/dist/assets/CodePage-BcbZT88K.js +0 -2
- package/client/dist/assets/JobDetailPage-D5Cxw0md.js +0 -16
- package/client/dist/assets/JobsPage-3v_iX83r.js +0 -1
- package/client/dist/assets/LoopBuilderPage-4s_adZy5.js +0 -7
- package/client/dist/assets/LoopsPage-DA94-o0j.js +0 -1
- package/client/dist/assets/index-meTWPBzY.js +0 -144
- package/client/dist/assets/setup-BOmQ4vh2.js +0 -1
- package/client/dist/assets/setup-BwO2-kuK.js +0 -1
- package/client/dist/assets/setup-CUTNWz-0.js +0 -1
- package/client/dist/assets/setup-Cf3hjChU.js +0 -1
- package/client/dist/assets/setup-CsuXrbJ2.js +0 -1
- package/client/dist/assets/setup-Df4cJOqu.js +0 -1
- package/client/dist/assets/setup-Do0fWx6W.js +0 -1
- package/client/dist/assets/setup-GlkDhBlJ.js +0 -1
- /package/client/dist/assets/{abap-CK68cr9-.js → abap-BFJA_Joo.js} +0 -0
- /package/client/dist/assets/{activity-D4dhNEwO.js → activity-BXBMi28x.js} +0 -0
- /package/client/dist/assets/{activity-usnNa7FX.js → activity-By6I70Ws.js} +0 -0
- /package/client/dist/assets/{activity-BbNkUmW4.js → activity-CfedQaof.js} +0 -0
- /package/client/dist/assets/{activity-B2MvEH54.js → activity-D62CDlQz.js} +0 -0
- /package/client/dist/assets/{activity-DHjfmAyT.js → activity-DAFuSwnt.js} +0 -0
- /package/client/dist/assets/{activity-C7VdmeGb.js → activity-Did0FnrH.js} +0 -0
- /package/client/dist/assets/{activity-Di2f50_Z.js → activity-oLgwaVyt.js} +0 -0
- /package/client/dist/assets/{addon-image-biWX2UUm.js → addon-image-bPlduuUZ.js} +0 -0
- /package/client/dist/assets/{addon-ligatures-D4EiDb5r.js → addon-ligatures-BexpF7xb.js} +0 -0
- /package/client/dist/assets/{addon-webgl-CDCIZQ03.js → addon-webgl-Zy4IOieH.js} +0 -0
- /package/client/dist/assets/{addspec-BxMn39wn.js → addspec-B2fTENuq.js} +0 -0
- /package/client/dist/assets/{addspec-DAveBiCE.js → addspec-BmggyuCD.js} +0 -0
- /package/client/dist/assets/{addspec-1HEtmLv1.js → addspec-CFsLeQKV.js} +0 -0
- /package/client/dist/assets/{addspec-DfuR6EAl.js → addspec-CkHI5c5H.js} +0 -0
- /package/client/dist/assets/{addspec-CO1xv6BL.js → addspec-Cvm06hGe.js} +0 -0
- /package/client/dist/assets/{addspec-IozoiiGs.js → addspec-DwoLTocx.js} +0 -0
- /package/client/dist/assets/{addspec-CNyAUGz_.js → addspec-gthH-H1g.js} +0 -0
- /package/client/dist/assets/{agentstudio-Q0Sq_jTg.js → agentstudio-BtASTJl7.js} +0 -0
- /package/client/dist/assets/{agentstudio-9NbsoGXk.js → agentstudio-CIe9C892.js} +0 -0
- /package/client/dist/assets/{agentstudio-B-jQgYV-.js → agentstudio-CYGk-jjo.js} +0 -0
- /package/client/dist/assets/{agentstudio-Bwa72b1S.js → agentstudio-CwiS3BTp.js} +0 -0
- /package/client/dist/assets/{agentstudio-B1y0JWY-.js → agentstudio-D0bQBWpI.js} +0 -0
- /package/client/dist/assets/{agentstudio-DCyDW8sy.js → agentstudio-Dq-bZrI3.js} +0 -0
- /package/client/dist/assets/{agentstudio-1E-bag77.js → agentstudio-n0pmwz2I.js} +0 -0
- /package/client/dist/assets/{aiedit-qTGI_PGs.js → aiedit-1Z-UYKFb.js} +0 -0
- /package/client/dist/assets/{aiedit-CGxeml8D.js → aiedit-BAJM9Cch.js} +0 -0
- /package/client/dist/assets/{aiedit-CfBNanHE.js → aiedit-CYnsp1Iv.js} +0 -0
- /package/client/dist/assets/{aiedit-CvSspQmE.js → aiedit-CZBZAyeK.js} +0 -0
- /package/client/dist/assets/{aiedit-kAU7KADg.js → aiedit-CunYxmW0.js} +0 -0
- /package/client/dist/assets/{aiedit-DUpe7NxI.js → aiedit-s1T1EMK8.js} +0 -0
- /package/client/dist/assets/{aiedit-DSLtsYIu.js → aiedit-uIDh2tlc.js} +0 -0
- /package/client/dist/assets/{analytics-DBGO8B6-.js → analytics-B95FiMuD.js} +0 -0
- /package/client/dist/assets/{analytics-CgEkAUiP.js → analytics-DPIkvuTS.js} +0 -0
- /package/client/dist/assets/{analytics-DDqve9Ma.js → analytics-DPmCEzvJ.js} +0 -0
- /package/client/dist/assets/{analytics-D1ElChhs.js → analytics-DRexho82.js} +0 -0
- /package/client/dist/assets/{analytics-DEsEAJZL.js → analytics-DVFNjjAv.js} +0 -0
- /package/client/dist/assets/{analytics-BDlELxc7.js → analytics-DZKGAUdm.js} +0 -0
- /package/client/dist/assets/{analytics-CQqu1yE5.js → analytics-g9ASAR_r.js} +0 -0
- /package/client/dist/assets/{apex-BHHyAVNb.js → apex-C1f-z6NO.js} +0 -0
- /package/client/dist/assets/{atom-one-dark-DrWoEEbZ.js → atom-one-dark-CT4DolNR.js} +0 -0
- /package/client/dist/assets/{attachments-3CuBBRFu.js → attachments--jr2QLGv.js} +0 -0
- /package/client/dist/assets/{attachments-pW3zm9nu.js → attachments-BgqfeoOx.js} +0 -0
- /package/client/dist/assets/{attachments-BNgH6Tcu.js → attachments-Bj3HHTXV.js} +0 -0
- /package/client/dist/assets/{attachments-D5fVsMgb.js → attachments-C3skjFyH.js} +0 -0
- /package/client/dist/assets/{attachments-UJtEq892.js → attachments-CnPS8YWu.js} +0 -0
- /package/client/dist/assets/{attachments-CppM7de8.js → attachments-DejzxE0C.js} +0 -0
- /package/client/dist/assets/{attachments-BLqqPGyy.js → attachments-FFb2xHc_.js} +0 -0
- /package/client/dist/assets/{azcli-C56lfIEP.js → azcli-Dr0WBJTP.js} +0 -0
- /package/client/dist/assets/{bat-BLamSaf-.js → bat-BKG3k49W.js} +0 -0
- /package/client/dist/assets/{bicep-lrOcEItS.js → bicep-DXs2wTcS.js} +0 -0
- /package/client/dist/assets/{browser-C91MQBxx.js → browser-BS9t1qMc.js} +0 -0
- /package/client/dist/assets/{browser-B7i7Ysc8.js → browser-BpMo-amf.js} +0 -0
- /package/client/dist/assets/{browser-DwE289IS.js → browser-CsC3NOZ-.js} +0 -0
- /package/client/dist/assets/{browser-C__Vz7KR.js → browser-DS6xnywt.js} +0 -0
- /package/client/dist/assets/{browser-DhwTc0ry.js → browser-Dm6F9bqQ.js} +0 -0
- /package/client/dist/assets/{browser-EFmPpkvO.js → browser-Dm_Of27q.js} +0 -0
- /package/client/dist/assets/{browser-BVQgd1_1.js → browser-U3iouSXn.js} +0 -0
- /package/client/dist/assets/{cameligo-BK_p0bgU.js → cameligo-Detknuxp.js} +0 -0
- /package/client/dist/assets/{chat-PVakYp92.js → chat-B2tWTbZL.js} +0 -0
- /package/client/dist/assets/{chat-BnJPyeUK.js → chat-CXOJHDUZ.js} +0 -0
- /package/client/dist/assets/{chat-CE8bx6Rz.js → chat-Cy78lw1n.js} +0 -0
- /package/client/dist/assets/{chat-UMl6H55K.js → chat-D78VMi-v.js} +0 -0
- /package/client/dist/assets/{chat-BXVx6rb5.js → chat-De1RgOXU.js} +0 -0
- /package/client/dist/assets/{chat-C5nJF6L0.js → chat-DyTbH-0F.js} +0 -0
- /package/client/dist/assets/{chat-9RcD5Lcn.js → chat-sqZyn0C4.js} +0 -0
- /package/client/dist/assets/{clojure-BQ7JOykv.js → clojure-CCu4UNKg.js} +0 -0
- /package/client/dist/assets/{clsx-CjLeUJfG.js → clsx-pVRQNNR0.js} +0 -0
- /package/client/dist/assets/{code-u9Sg9ohM.js → code-6LokPmIE.js} +0 -0
- /package/client/dist/assets/{code-OoLqhjoI.js → code-CLTuhuvM.js} +0 -0
- /package/client/dist/assets/{code-Lg4awa35.js → code-CwGlPuwb.js} +0 -0
- /package/client/dist/assets/{code-BPMR8_Vp.js → code-DFCDV5e1.js} +0 -0
- /package/client/dist/assets/{code-eh4vO2-_.js → code-Djq48g0s.js} +0 -0
- /package/client/dist/assets/{code-aCUqkVN_.js → code-Do27r8WG.js} +0 -0
- /package/client/dist/assets/{code-BsOBm1Fb.js → code-Drc7f197.js} +0 -0
- /package/client/dist/assets/{coffee-BD3DiL5s.js → coffee-Bam7Y9IR.js} +0 -0
- /package/client/dist/assets/{commands-B9XEyMj-.js → commands-CxReviyc.js} +0 -0
- /package/client/dist/assets/{commands-Ic1DJDxm.js → commands-CzP1qQyD.js} +0 -0
- /package/client/dist/assets/{commands-BdI0CtOL.js → commands-DGP46UxM.js} +0 -0
- /package/client/dist/assets/{commands-DSX3yJyr.js → commands-DQvoMqa7.js} +0 -0
- /package/client/dist/assets/{commands-yNn4IA4C.js → commands-DeKaz04Q.js} +0 -0
- /package/client/dist/assets/{commands-BI1Ta-E7.js → commands-DwYhwQsF.js} +0 -0
- /package/client/dist/assets/{commands-C2ewlyXo.js → commands-lm6Vlght.js} +0 -0
- /package/client/dist/assets/{common-CzCQ0rpW.js → common-B0crwfK0.js} +0 -0
- /package/client/dist/assets/{common-CNoRVpnA.js → common-BlqmiTj4.js} +0 -0
- /package/client/dist/assets/{common-CcHFVATT.js → common-CIUPtPdu.js} +0 -0
- /package/client/dist/assets/{common-LDwESeCX.js → common-C_-0fZsp.js} +0 -0
- /package/client/dist/assets/{common-C9VyfY7g.js → common-DH9A-wTo.js} +0 -0
- /package/client/dist/assets/{common-Dmpyh323.js → common-DJM41wFl.js} +0 -0
- /package/client/dist/assets/{common-ULlk84G4.js → common-SyTaRc_K.js} +0 -0
- /package/client/dist/assets/{cpp-splnCwCh.js → cpp-BhOkAe-9.js} +0 -0
- /package/client/dist/assets/{csharp-BCpsl-o3.js → csharp-BgHArJNx.js} +0 -0
- /package/client/dist/assets/{csp-tkCWrZmb.js → csp-Xzh56_3-.js} +0 -0
- /package/client/dist/assets/{css-B_xdnReq.js → css-CD7-RYRS.js} +0 -0
- /package/client/dist/assets/{cypher-OL1zq-y3.js → cypher-l2xAdF3X.js} +0 -0
- /package/client/dist/assets/{dart-CtTlOkrm.js → dart-CDOWeyzt.js} +0 -0
- /package/client/dist/assets/{dashboard-C-dXxut-.js → dashboard-B1rs1wki.js} +0 -0
- /package/client/dist/assets/{dashboard-CUjyhohl.js → dashboard-D9QPCmv3.js} +0 -0
- /package/client/dist/assets/{dashboard-C52PElPV.js → dashboard-Dxgb47lO.js} +0 -0
- /package/client/dist/assets/{dashboard-03EpOoMM.js → dashboard-TuElRCZX.js} +0 -0
- /package/client/dist/assets/{dashboard-Ch6H-457.js → dashboard-UWXs9_wy.js} +0 -0
- /package/client/dist/assets/{dashboard-zH9quXks.js → dashboard-ajT8usAi.js} +0 -0
- /package/client/dist/assets/{dashboard-C2owt3eN.js → dashboard-zwN2xswo.js} +0 -0
- /package/client/dist/assets/{dockerfile-DcQ5CNiW.js → dockerfile-Dv8atx7v.js} +0 -0
- /package/client/dist/assets/{ecl-DZpiDRt6.js → ecl-DIYTlbD_.js} +0 -0
- /package/client/dist/assets/{editor.api2-Cwla1nvV.js → editor.api2-CrNrMVfe.js} +0 -0
- /package/client/dist/assets/{elixir-Dzj2lqtK.js → elixir-CR7PLJja.js} +0 -0
- /package/client/dist/assets/{explore-4SD1DxR0.js → explore-BYFCCka4.js} +0 -0
- /package/client/dist/assets/{explore-xQoaak6e.js → explore-CE0wSNV1.js} +0 -0
- /package/client/dist/assets/{explore-CZt4Ncpa.js → explore-CSDcRUNj.js} +0 -0
- /package/client/dist/assets/{explore-DQ0XEjed.js → explore-CvM08PpD.js} +0 -0
- /package/client/dist/assets/{explore-CCcPXrHg.js → explore-Jkw93usp.js} +0 -0
- /package/client/dist/assets/{explore-BxR9q8Hq.js → explore-kK239uoZ.js} +0 -0
- /package/client/dist/assets/{explore-B2n8r9Ye.js → explore-mLI5eXks.js} +0 -0
- /package/client/dist/assets/{flow9-CFENCHIZ.js → flow9-DCK5-6NG.js} +0 -0
- /package/client/dist/assets/{format-command-CMsBTOPN.js → format-command-rVyGPxWE.js} +0 -0
- /package/client/dist/assets/{fsharp-D-4bv7FB.js → fsharp-DJ1xiUVU.js} +0 -0
- /package/client/dist/assets/{go-djxbTJq7.js → go-BEvbHcbb.js} +0 -0
- /package/client/dist/assets/{graphql-DHIFrkZ6.js → graphql-DN1ktXnz.js} +0 -0
- /package/client/dist/assets/{hcl-CXVoowNb.js → hcl-DJaIjIEr.js} +0 -0
- /package/client/dist/assets/{ini-Crzc5kly.js → ini-PlKfLEnb.js} +0 -0
- /package/client/dist/assets/{integrations-A9f08E0o.js → integrations-B8hT0Qf_.js} +0 -0
- /package/client/dist/assets/{integrations-DwSVdCpf.js → integrations-Bdk5dMyv.js} +0 -0
- /package/client/dist/assets/{integrations-B46ac3sf.js → integrations-CYqz7YFS.js} +0 -0
- /package/client/dist/assets/{integrations-9qxUNhPD.js → integrations-Cj_BsXxJ.js} +0 -0
- /package/client/dist/assets/{integrations-B17KyA-i.js → integrations-D8M8eJH2.js} +0 -0
- /package/client/dist/assets/{integrations-DkBi-Gsh.js → integrations-TJuDBl-9.js} +0 -0
- /package/client/dist/assets/{integrations-C7u7SInG.js → integrations-TwQV3sLw.js} +0 -0
- /package/client/dist/assets/{java-CYLaJrdE.js → java-3PUwMlx-.js} +0 -0
- /package/client/dist/assets/{jira-01H1RfQj.js → jira--rI5PfuE.js} +0 -0
- /package/client/dist/assets/{jira-CBU0200d.js → jira-BoRyckbb.js} +0 -0
- /package/client/dist/assets/{jira-BpnpUFlb.js → jira-C95FN3yk.js} +0 -0
- /package/client/dist/assets/{jira-DzIVvNmy.js → jira-CNUUgTs4.js} +0 -0
- /package/client/dist/assets/{jira-Dht8qNck.js → jira-DHFnvEm8.js} +0 -0
- /package/client/dist/assets/{jira-4Fin3fu7.js → jira-NhkbrDXe.js} +0 -0
- /package/client/dist/assets/{jira-0ldfMByG.js → jira-wiIvGma5.js} +0 -0
- /package/client/dist/assets/{jobs-Oz3UtLQn.js → jobs-Bjp7v9aA.js} +0 -0
- /package/client/dist/assets/{jobs-jEQidSIb.js → jobs-Bjt5PyVv.js} +0 -0
- /package/client/dist/assets/{jobs-BF9raUkL.js → jobs-BmTs4Bn3.js} +0 -0
- /package/client/dist/assets/{jobs-DcCONARH.js → jobs-Cchy-18B.js} +0 -0
- /package/client/dist/assets/{jobs-DM9owF1j.js → jobs-D2QVTPbz.js} +0 -0
- /package/client/dist/assets/{jobs-Bw4hqEro.js → jobs-LK1ImiDH.js} +0 -0
- /package/client/dist/assets/{jobs-ym72SIR9.js → jobs-yPz4Dvi-.js} +0 -0
- /package/client/dist/assets/{julia-BJ7tUU-T.js → julia-DC6LnY15.js} +0 -0
- /package/client/dist/assets/{kotlin-CeWcU3lC.js → kotlin-CoGntbZF.js} +0 -0
- /package/client/dist/assets/{less-CviwWNG4.js → less-DCFflTXL.js} +0 -0
- /package/client/dist/assets/{lexon-Dt28jqDS.js → lexon-BTOivnjP.js} +0 -0
- /package/client/dist/assets/{loops-Fv4Bs-9A.js → loops-BFIcYvpy.js} +0 -0
- /package/client/dist/assets/{loops-D_ZxkD4l.js → loops-BU314kSd.js} +0 -0
- /package/client/dist/assets/{loops-DE-2cmLw.js → loops-C3OaXou9.js} +0 -0
- /package/client/dist/assets/{loops-mcoeFMat.js → loops-Cv6Aeszq.js} +0 -0
- /package/client/dist/assets/{loops-B_w7STrw.js → loops-IQe23ef6.js} +0 -0
- /package/client/dist/assets/{loops-BYNUJVyD.js → loops-LqZ4MC6J.js} +0 -0
- /package/client/dist/assets/{loops-B_gS4Pqu.js → loops-SbkOdciY.js} +0 -0
- /package/client/dist/assets/{lua-B6AOaJSi.js → lua-ClKCZMmP.js} +0 -0
- /package/client/dist/assets/{m3-VnMkHJcy.js → m3-25hKFWMb.js} +0 -0
- /package/client/dist/assets/{markdown-8vKNdvIM.js → markdown-BGAj9q0K.js} +0 -0
- /package/client/dist/assets/{mips-DoEcuzan.js → mips-BrVgY2Pf.js} +0 -0
- /package/client/dist/assets/{msdax-CNzvHyEp.js → msdax-7EhcRsm8.js} +0 -0
- /package/client/dist/assets/{mysql-Buk3vUtL.js → mysql-B5_atCBH.js} +0 -0
- /package/client/dist/assets/{nav-_0vAgZ_k.js → nav-B2Cv1vjz.js} +0 -0
- /package/client/dist/assets/{nav-Cw3_40fA.js → nav-Br2AivTc.js} +0 -0
- /package/client/dist/assets/{nav-DNDJ3H-_.js → nav-CFofO7QO.js} +0 -0
- /package/client/dist/assets/{nav-CCz4krPP.js → nav-CyHKTZxn.js} +0 -0
- /package/client/dist/assets/{nav-B5W9IMnf.js → nav-DqyLGJmF.js} +0 -0
- /package/client/dist/assets/{nav-CrG_mYRr.js → nav-_-siCrRv.js} +0 -0
- /package/client/dist/assets/{nav-DbAbG5_k.js → nav-rO4Nqnh-.js} +0 -0
- /package/client/dist/assets/{nav-DVp1nEsi.js → nav-zyBhf29M.js} +0 -0
- /package/client/dist/assets/{objective-c-DfOmda-5.js → objective-c-CLUvUl9T.js} +0 -0
- /package/client/dist/assets/{pascal-DoAA2yjy.js → pascal-BnU1HU42.js} +0 -0
- /package/client/dist/assets/{pascaligo-C65Vn1fu.js → pascaligo-dsKvjFzi.js} +0 -0
- /package/client/dist/assets/{perl-INlfQ_ro.js → perl-CZne1GYG.js} +0 -0
- /package/client/dist/assets/{pgsql-DtwRzglx.js → pgsql-CMa5W_iF.js} +0 -0
- /package/client/dist/assets/{php-DfHqVNet.js → php-Cu4mS35J.js} +0 -0
- /package/client/dist/assets/{pla-D3dNVRYk.js → pla-B7COwnnm.js} +0 -0
- /package/client/dist/assets/{postiats-UKXD1rM4.js → postiats-GLeNtnBQ.js} +0 -0
- /package/client/dist/assets/{powerquery-zE3E3O7s.js → powerquery-BqPf3R1W.js} +0 -0
- /package/client/dist/assets/{powershell-Df9b3zQl.js → powershell-D9btb5su.js} +0 -0
- /package/client/dist/assets/{protobuf-BF0nUVrW.js → protobuf-6GHSuaNm.js} +0 -0
- /package/client/dist/assets/{pug-Bj6Yikv_.js → pug-ct6rYKQd.js} +0 -0
- /package/client/dist/assets/{qsharp-BI4h-raZ.js → qsharp-CIrAQNPy.js} +0 -0
- /package/client/dist/assets/{r-DhpnmaXx.js → r-Bk-a0sON.js} +0 -0
- /package/client/dist/assets/{redis-DwYYPr4d.js → redis-C9yfaWYh.js} +0 -0
- /package/client/dist/assets/{redshift-D2f3Bc-4.js → redshift-DaOT1jRU.js} +0 -0
- /package/client/dist/assets/{restructuredtext-Dkiif6fe.js → restructuredtext-C1t9LQfS.js} +0 -0
- /package/client/dist/assets/{ruby-C6hLmHy0.js → ruby-COiPZJjc.js} +0 -0
- /package/client/dist/assets/{rust-X8WAGtxB.js → rust--gZOJZzj.js} +0 -0
- /package/client/dist/assets/{sb-4M2la0Kr.js → sb-NHf3iazF.js} +0 -0
- /package/client/dist/assets/{scala-CaCXz58E.js → scala-D1nO1TBd.js} +0 -0
- /package/client/dist/assets/{scheme-CMdjpmP7.js → scheme-Bref42s5.js} +0 -0
- /package/client/dist/assets/{scss-QopmvPyp.js → scss-BS9CCLr3.js} +0 -0
- /package/client/dist/assets/{settings-DyBxunCh.js → settings-BN4dufu6.js} +0 -0
- /package/client/dist/assets/{settings-BN7OusER.js → settings-Bap_q3rt.js} +0 -0
- /package/client/dist/assets/{settings-Bi5FFkIw.js → settings-BlYjWMy5.js} +0 -0
- /package/client/dist/assets/{settings-iQe5Dim-.js → settings-C7t_uUz4.js} +0 -0
- /package/client/dist/assets/{settings-fk-WlnUt.js → settings-CIFrUsKt.js} +0 -0
- /package/client/dist/assets/{settings-BA1V6KdK.js → settings-Cbj9VWmI.js} +0 -0
- /package/client/dist/assets/{settings-CRJxyTNN.js → settings-D7saHMU8.js} +0 -0
- /package/client/dist/assets/{settings-0m2iuTzd.js → settings-DrRjM5e8.js} +0 -0
- /package/client/dist/assets/{shell-CDBchS00.js → shell-DT3joMBB.js} +0 -0
- /package/client/dist/assets/{solidity-DvBfi5mC.js → solidity-o2Fm9dvg.js} +0 -0
- /package/client/dist/assets/{sophia-HSnXR17u.js → sophia-Dj1N6Xqb.js} +0 -0
- /package/client/dist/assets/{sparql-DhG_ppup.js → sparql-D2fjpTWm.js} +0 -0
- /package/client/dist/assets/{specs-BvsFNKTs.js → specs-C-WXGBqy.js} +0 -0
- /package/client/dist/assets/{specs-D4ORogcT.js → specs-C57koADY.js} +0 -0
- /package/client/dist/assets/{specs-CnH7dOiF.js → specs-CCXV-eSF.js} +0 -0
- /package/client/dist/assets/{specs-CUE3xSFM.js → specs-CYA5Bv7Q.js} +0 -0
- /package/client/dist/assets/{specs-C2wW5bq8.js → specs-DFCFg51O.js} +0 -0
- /package/client/dist/assets/{specs-C_8j4ELZ.js → specs-Dslng_yW.js} +0 -0
- /package/client/dist/assets/{specs-D6Y76Bgi.js → specs-DwRPiJTc.js} +0 -0
- /package/client/dist/assets/{specs-Bku8SypT.js → specs-DzlROLy7.js} +0 -0
- /package/client/dist/assets/{sql-DHeIS-tf.js → sql-BArhsPUz.js} +0 -0
- /package/client/dist/assets/{st-CMWchiRU.js → st-Bd2-tALj.js} +0 -0
- /package/client/dist/assets/{swift-CDXvBefj.js → swift-DvEpXBKj.js} +0 -0
- /package/client/dist/assets/{systemverilog-0RTukYUE.js → systemverilog-mHEbsnVH.js} +0 -0
- /package/client/dist/assets/{tcl-CbBF_Ttl.js → tcl-DePutp1e.js} +0 -0
- /package/client/dist/assets/{terminal-CB33IsO1.js → terminal-2S-Wsk6L.js} +0 -0
- /package/client/dist/assets/{terminal-Cz_Puz0q.js → terminal-BRQMrU74.js} +0 -0
- /package/client/dist/assets/{terminal-DFEH9XTQ.js → terminal-BTiemy98.js} +0 -0
- /package/client/dist/assets/{terminal-BTanJIt_.js → terminal-CjQeWfpp.js} +0 -0
- /package/client/dist/assets/{terminal-CY_sPfdD.js → terminal-CmP5riTU.js} +0 -0
- /package/client/dist/assets/{terminal-BLh00ouM.js → terminal-CnObBCAh.js} +0 -0
- /package/client/dist/assets/{terminal-CR6t-Oey.js → terminal-DcPKgKMN.js} +0 -0
- /package/client/dist/assets/{terminal-Cj4HzP3p.js → terminal-XciDq6VV.js} +0 -0
- /package/client/dist/assets/{tickets-OrJwUxJR.js → tickets-7kl_0jgM.js} +0 -0
- /package/client/dist/assets/{tickets-68LH1xp6.js → tickets-BSyaZI8d.js} +0 -0
- /package/client/dist/assets/{tickets-blQnNA4N.js → tickets-CcTcvwKS.js} +0 -0
- /package/client/dist/assets/{tickets-D6f3GSYn.js → tickets-D75vyZJj.js} +0 -0
- /package/client/dist/assets/{tickets-PtHNxQo5.js → tickets-D79ZT2SZ.js} +0 -0
- /package/client/dist/assets/{tickets-DBQXMYYA.js → tickets-DbcMWq5L.js} +0 -0
- /package/client/dist/assets/{tickets-jxsTrApR.js → tickets-ZA_2iPd1.js} +0 -0
- /package/client/dist/assets/{tickets-REr-EQx9.js → tickets-mxd23fWX.js} +0 -0
- /package/client/dist/assets/{twig-DCcGd8FE.js → twig-DQ2zIX0b.js} +0 -0
- /package/client/dist/assets/{typespec-HTphp-Uh.js → typespec-DPoaiGTJ.js} +0 -0
- /package/client/dist/assets/{vb-Cb_yUcVd.js → vb-Jo98wdMr.js} +0 -0
- /package/client/dist/assets/{wgsl-DrKU3YXj.js → wgsl-DZc4h_eS.js} +0 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.agentsTools = agentsTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
/**
|
|
7
|
+
* Agents domain — agent PROFILES (declarative per-project routing config) and
|
|
8
|
+
* the agents CATALOG (the `.claude/agents/*.md` definitions: read-only `sr-*`
|
|
9
|
+
* upstream agents + user-authored `custom-*` agents, with AI generate/test/
|
|
10
|
+
* iterative-refine on the custom ones).
|
|
11
|
+
*
|
|
12
|
+
* CLAUDE-ONLY: agent profiles are a Claude concept. On a project whose primary
|
|
13
|
+
* provider (or any installed provider) is codex/gemini, rails force-null the
|
|
14
|
+
* profile and the whole section is hidden client-side — creating profiles for a
|
|
15
|
+
* non-Claude project is mostly inert. The server still validates against that
|
|
16
|
+
* provider's adapter catalog. Prefer using this tool on Claude projects.
|
|
17
|
+
*
|
|
18
|
+
* Every operation is per-project (mounted at /api/projects/:projectId/profiles)
|
|
19
|
+
* and is gated by SPECRAILS_AGENTS_SECTION — a disabled server 404s every route.
|
|
20
|
+
*
|
|
21
|
+
* The catalog `generate`, `test`, `refine_start`, and `refine_turn` actions
|
|
22
|
+
* SPAWN the claude CLI and incur real cost (refine records ai_invocations and
|
|
23
|
+
* streams agent_refine_* WS events). `refine_apply` / `update_custom` /
|
|
24
|
+
* `delete_custom` / `create_custom` mutate `custom-*.md` files on disk.
|
|
25
|
+
*/
|
|
26
|
+
function agentsTools() {
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
name: 'specrails_agents',
|
|
30
|
+
title: 'Agents (Profiles & Catalog)',
|
|
31
|
+
description: 'Manage agent PROFILES and the agents CATALOG for a project (Claude-only — profiles are inert on codex/gemini projects). ' +
|
|
32
|
+
'PROFILE actions: list, get, resolve (preview which profile a rail would resolve to), create, update, delete (destructive — protected default/project-default cannot be deleted), ' +
|
|
33
|
+
'duplicate, rename, migrate (seed a default profile from installed sr-*.md frontmatter), analytics (per-profile metrics), core_version (specrails-core version + 4.1.0 profile-aware check). ' +
|
|
34
|
+
'CATALOG actions: catalog_list, catalog_get (full agent .md body), versions (custom agent edit history), create_custom (custom-*.md), update_custom, delete_custom (destructive), ' +
|
|
35
|
+
'generate (AI-generate a draft custom agent — spawns claude, costs), test (AI smoke-test a draft body — spawns claude, costs), ' +
|
|
36
|
+
'refine_start / refine_turn (AI iterative refine of a custom agent — spawn claude, cost, stream over WS), refine_list, refine_get, refine_patch (toggle autoTest), refine_cancel (kill the spawn), refine_apply (write the refined draft to disk).',
|
|
37
|
+
hintTier: 'read',
|
|
38
|
+
tier: (a) => {
|
|
39
|
+
const action = a.action;
|
|
40
|
+
if (['delete', 'delete_custom'].includes(action))
|
|
41
|
+
return 'destructive';
|
|
42
|
+
if (['generate', 'test', 'refine_start', 'refine_turn'].includes(action))
|
|
43
|
+
return 'ai-spawn';
|
|
44
|
+
if ([
|
|
45
|
+
'create',
|
|
46
|
+
'update',
|
|
47
|
+
'duplicate',
|
|
48
|
+
'rename',
|
|
49
|
+
'migrate',
|
|
50
|
+
'create_custom',
|
|
51
|
+
'update_custom',
|
|
52
|
+
'refine_patch',
|
|
53
|
+
'refine_cancel',
|
|
54
|
+
'refine_apply',
|
|
55
|
+
].includes(action)) {
|
|
56
|
+
return 'write';
|
|
57
|
+
}
|
|
58
|
+
return 'read';
|
|
59
|
+
},
|
|
60
|
+
inputSchema: {
|
|
61
|
+
action: zod_1.z
|
|
62
|
+
.enum([
|
|
63
|
+
// PROFILES
|
|
64
|
+
'list',
|
|
65
|
+
'get',
|
|
66
|
+
'resolve',
|
|
67
|
+
'create',
|
|
68
|
+
'update',
|
|
69
|
+
'delete',
|
|
70
|
+
'duplicate',
|
|
71
|
+
'rename',
|
|
72
|
+
'migrate',
|
|
73
|
+
'analytics',
|
|
74
|
+
'core_version',
|
|
75
|
+
// CATALOG (definitions)
|
|
76
|
+
'catalog_list',
|
|
77
|
+
'catalog_get',
|
|
78
|
+
'versions',
|
|
79
|
+
'create_custom',
|
|
80
|
+
'update_custom',
|
|
81
|
+
'delete_custom',
|
|
82
|
+
'generate',
|
|
83
|
+
'test',
|
|
84
|
+
// CATALOG (AI refine)
|
|
85
|
+
'refine_start',
|
|
86
|
+
'refine_turn',
|
|
87
|
+
'refine_list',
|
|
88
|
+
'refine_get',
|
|
89
|
+
'refine_patch',
|
|
90
|
+
'refine_cancel',
|
|
91
|
+
'refine_apply',
|
|
92
|
+
])
|
|
93
|
+
.describe('Operation to perform (profile or catalog action)'),
|
|
94
|
+
projectId: zod_1.z.string().optional().describe('Project id (defaults to the active project)'),
|
|
95
|
+
// Profile params
|
|
96
|
+
name: zod_1.z
|
|
97
|
+
.string()
|
|
98
|
+
.optional()
|
|
99
|
+
.describe('Profile name (get/update/delete/duplicate/rename source). For duplicate/rename, the NEW name goes in `newName`.'),
|
|
100
|
+
newName: zod_1.z.string().optional().describe('New profile name (for duplicate / rename)'),
|
|
101
|
+
profileName: zod_1.z
|
|
102
|
+
.string()
|
|
103
|
+
.optional()
|
|
104
|
+
.describe('Explicit profile name to preview in `resolve` (omit to resolve the project default)'),
|
|
105
|
+
profile: zod_1.z
|
|
106
|
+
.record(zod_1.z.unknown())
|
|
107
|
+
.optional()
|
|
108
|
+
.describe('Full Profile body for create/update: { schemaVersion:1, name, description?, provider?, orchestrator:{model}, agents:[], routing:[] }'),
|
|
109
|
+
windowDays: zod_1.z.number().int().optional().describe('analytics time window in days (1-365, default 30)'),
|
|
110
|
+
// Catalog params
|
|
111
|
+
agentId: zod_1.z
|
|
112
|
+
.string()
|
|
113
|
+
.optional()
|
|
114
|
+
.describe('Agent id for catalog_get/versions/update_custom/delete_custom and all refine actions (custom-* for mutations, sr-*|custom-* for reads)'),
|
|
115
|
+
body: zod_1.z.string().optional().describe('Agent .md body (for create_custom / update_custom)'),
|
|
116
|
+
agentName: zod_1.z
|
|
117
|
+
.string()
|
|
118
|
+
.optional()
|
|
119
|
+
.describe('New custom agent id for create_custom — must match ^custom-[a-z0-9][a-z0-9-]*$'),
|
|
120
|
+
description: zod_1.z.string().optional().describe('Plain-language description for `generate` (AI draft a custom agent)'),
|
|
121
|
+
draftBody: zod_1.z.string().optional().describe('Draft agent body to smoke-test in `test`'),
|
|
122
|
+
sampleTask: zod_1.z.string().optional().describe('Sample task the `test` action runs the draft against'),
|
|
123
|
+
instruction: zod_1.z.string().optional().describe('Refine instruction (for refine_start / refine_turn)'),
|
|
124
|
+
autoTest: zod_1.z.boolean().optional().describe('Auto-test the refined draft (refine_start default true; refine_patch toggles it)'),
|
|
125
|
+
refineId: zod_1.z.string().optional().describe('Refine session id (for refine_get/refine_turn/refine_patch/refine_cancel/refine_apply)'),
|
|
126
|
+
force: zod_1.z.boolean().optional().describe('Bypass the disk-hash guard when applying a refine draft (refine_apply)'),
|
|
127
|
+
},
|
|
128
|
+
async handler(ctx, args) {
|
|
129
|
+
const base = `${(0, types_1.projectPath)(ctx, args.projectId)}/profiles`;
|
|
130
|
+
const action = args.action;
|
|
131
|
+
const agentId = args.agentId;
|
|
132
|
+
const refineId = args.refineId;
|
|
133
|
+
const profileName = args.name;
|
|
134
|
+
switch (action) {
|
|
135
|
+
// ── PROFILES ────────────────────────────────────────────────────
|
|
136
|
+
case 'list':
|
|
137
|
+
return (0, types_1.apiCall)(ctx, 'GET', base);
|
|
138
|
+
case 'get': {
|
|
139
|
+
if (!profileName)
|
|
140
|
+
throw new Error('get requires a profile "name".');
|
|
141
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/${encodeURIComponent(profileName)}`);
|
|
142
|
+
}
|
|
143
|
+
case 'resolve': {
|
|
144
|
+
const p = args.profileName;
|
|
145
|
+
const qs = p ? `?profile=${encodeURIComponent(p)}` : '';
|
|
146
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/resolve${qs}`);
|
|
147
|
+
}
|
|
148
|
+
case 'create': {
|
|
149
|
+
if (!args.profile)
|
|
150
|
+
throw new Error('create requires a "profile" body.');
|
|
151
|
+
return (0, types_1.apiCall)(ctx, 'POST', base, args.profile);
|
|
152
|
+
}
|
|
153
|
+
case 'update': {
|
|
154
|
+
if (!profileName)
|
|
155
|
+
throw new Error('update requires a profile "name".');
|
|
156
|
+
if (!args.profile)
|
|
157
|
+
throw new Error('update requires a "profile" body (its name must equal "name").');
|
|
158
|
+
return (0, types_1.apiCall)(ctx, 'PATCH', `${base}/${encodeURIComponent(profileName)}`, args.profile);
|
|
159
|
+
}
|
|
160
|
+
case 'delete': {
|
|
161
|
+
if (!profileName)
|
|
162
|
+
throw new Error('delete requires a profile "name".');
|
|
163
|
+
return (0, types_1.apiCall)(ctx, 'DELETE', `${base}/${encodeURIComponent(profileName)}`);
|
|
164
|
+
}
|
|
165
|
+
case 'duplicate': {
|
|
166
|
+
if (!profileName)
|
|
167
|
+
throw new Error('duplicate requires a source profile "name".');
|
|
168
|
+
const newName = args.newName;
|
|
169
|
+
if (!newName)
|
|
170
|
+
throw new Error('duplicate requires a "newName".');
|
|
171
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/${encodeURIComponent(profileName)}/duplicate`, { name: newName });
|
|
172
|
+
}
|
|
173
|
+
case 'rename': {
|
|
174
|
+
if (!profileName)
|
|
175
|
+
throw new Error('rename requires a source profile "name".');
|
|
176
|
+
const newName = args.newName;
|
|
177
|
+
if (!newName)
|
|
178
|
+
throw new Error('rename requires a "newName".');
|
|
179
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/${encodeURIComponent(profileName)}/rename`, { name: newName });
|
|
180
|
+
}
|
|
181
|
+
case 'migrate':
|
|
182
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/migrate-from-settings`);
|
|
183
|
+
case 'analytics': {
|
|
184
|
+
const wd = args.windowDays;
|
|
185
|
+
const qs = typeof wd === 'number' ? `?windowDays=${wd}` : '';
|
|
186
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/analytics${qs}`);
|
|
187
|
+
}
|
|
188
|
+
case 'core_version':
|
|
189
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/core-version`);
|
|
190
|
+
// ── CATALOG: definitions ────────────────────────────────────────
|
|
191
|
+
case 'catalog_list':
|
|
192
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/catalog`);
|
|
193
|
+
case 'catalog_get': {
|
|
194
|
+
if (!agentId)
|
|
195
|
+
throw new Error('catalog_get requires an "agentId".');
|
|
196
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/catalog/${encodeURIComponent(agentId)}`);
|
|
197
|
+
}
|
|
198
|
+
case 'versions': {
|
|
199
|
+
if (!agentId)
|
|
200
|
+
throw new Error('versions requires an "agentId".');
|
|
201
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/catalog/${encodeURIComponent(agentId)}/versions`);
|
|
202
|
+
}
|
|
203
|
+
case 'create_custom': {
|
|
204
|
+
const id = args.agentName;
|
|
205
|
+
const body = args.body;
|
|
206
|
+
if (!id)
|
|
207
|
+
throw new Error('create_custom requires an "agentName" (custom-* id).');
|
|
208
|
+
if (!body)
|
|
209
|
+
throw new Error('create_custom requires a "body".');
|
|
210
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/catalog`, { id, body });
|
|
211
|
+
}
|
|
212
|
+
case 'update_custom': {
|
|
213
|
+
if (!agentId)
|
|
214
|
+
throw new Error('update_custom requires an "agentId" (custom-* only).');
|
|
215
|
+
const body = args.body;
|
|
216
|
+
if (!body)
|
|
217
|
+
throw new Error('update_custom requires a "body".');
|
|
218
|
+
return (0, types_1.apiCall)(ctx, 'PATCH', `${base}/catalog/${encodeURIComponent(agentId)}`, { body });
|
|
219
|
+
}
|
|
220
|
+
case 'delete_custom': {
|
|
221
|
+
if (!agentId)
|
|
222
|
+
throw new Error('delete_custom requires an "agentId" (custom-* only).');
|
|
223
|
+
return (0, types_1.apiCall)(ctx, 'DELETE', `${base}/catalog/${encodeURIComponent(agentId)}`);
|
|
224
|
+
}
|
|
225
|
+
// ── CATALOG: AI spawns (cost) ───────────────────────────────────
|
|
226
|
+
case 'generate': {
|
|
227
|
+
const name = args.agentName;
|
|
228
|
+
const description = args.description;
|
|
229
|
+
if (!name)
|
|
230
|
+
throw new Error('generate requires an "agentName" (custom-* id).');
|
|
231
|
+
if (!description)
|
|
232
|
+
throw new Error('generate requires a "description".');
|
|
233
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/catalog/generate`, { name, description });
|
|
234
|
+
}
|
|
235
|
+
case 'test': {
|
|
236
|
+
const draftBody = args.draftBody;
|
|
237
|
+
const sampleTask = args.sampleTask;
|
|
238
|
+
if (!draftBody)
|
|
239
|
+
throw new Error('test requires a "draftBody".');
|
|
240
|
+
if (!sampleTask)
|
|
241
|
+
throw new Error('test requires a "sampleTask".');
|
|
242
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/catalog/test`, {
|
|
243
|
+
...(agentId ? { agentId } : {}),
|
|
244
|
+
draftBody,
|
|
245
|
+
sampleTask,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
// ── CATALOG: AI refine sessions ─────────────────────────────────
|
|
249
|
+
case 'refine_start': {
|
|
250
|
+
if (!agentId)
|
|
251
|
+
throw new Error('refine_start requires an "agentId" (custom-* only).');
|
|
252
|
+
const instruction = args.instruction;
|
|
253
|
+
if (!instruction)
|
|
254
|
+
throw new Error('refine_start requires an "instruction".');
|
|
255
|
+
const r = await (0, types_1.apiCall)(ctx, 'POST', `${base}/catalog/${encodeURIComponent(agentId)}/refine`, {
|
|
256
|
+
instruction,
|
|
257
|
+
...(typeof args.autoTest === 'boolean' ? { autoTest: args.autoTest } : {}),
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
...r,
|
|
261
|
+
hint: 'Refine streams over WS (agent_refine_* events). Use refine_get with the returned refineId to poll the session, then refine_apply to write the draft to disk.',
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
case 'refine_turn': {
|
|
265
|
+
if (!agentId)
|
|
266
|
+
throw new Error('refine_turn requires an "agentId".');
|
|
267
|
+
if (!refineId)
|
|
268
|
+
throw new Error('refine_turn requires a "refineId".');
|
|
269
|
+
const instruction = args.instruction;
|
|
270
|
+
if (!instruction)
|
|
271
|
+
throw new Error('refine_turn requires an "instruction".');
|
|
272
|
+
const r = await (0, types_1.apiCall)(ctx, 'POST', `${base}/catalog/${encodeURIComponent(agentId)}/refine/${encodeURIComponent(refineId)}/turn`, { instruction });
|
|
273
|
+
return {
|
|
274
|
+
...r,
|
|
275
|
+
hint: 'The turn streams over WS (agent_refine_* events). Use refine_get with the refineId to read the updated draft.',
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
case 'refine_list': {
|
|
279
|
+
if (!agentId)
|
|
280
|
+
throw new Error('refine_list requires an "agentId".');
|
|
281
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/catalog/${encodeURIComponent(agentId)}/refine`);
|
|
282
|
+
}
|
|
283
|
+
case 'refine_get': {
|
|
284
|
+
if (!agentId)
|
|
285
|
+
throw new Error('refine_get requires an "agentId".');
|
|
286
|
+
if (!refineId)
|
|
287
|
+
throw new Error('refine_get requires a "refineId".');
|
|
288
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/catalog/${encodeURIComponent(agentId)}/refine/${encodeURIComponent(refineId)}`);
|
|
289
|
+
}
|
|
290
|
+
case 'refine_patch': {
|
|
291
|
+
if (!agentId)
|
|
292
|
+
throw new Error('refine_patch requires an "agentId".');
|
|
293
|
+
if (!refineId)
|
|
294
|
+
throw new Error('refine_patch requires a "refineId".');
|
|
295
|
+
if (typeof args.autoTest !== 'boolean')
|
|
296
|
+
throw new Error('refine_patch requires a boolean "autoTest".');
|
|
297
|
+
return (0, types_1.apiCall)(ctx, 'PATCH', `${base}/catalog/${encodeURIComponent(agentId)}/refine/${encodeURIComponent(refineId)}`, { autoTest: args.autoTest });
|
|
298
|
+
}
|
|
299
|
+
case 'refine_cancel': {
|
|
300
|
+
if (!agentId)
|
|
301
|
+
throw new Error('refine_cancel requires an "agentId".');
|
|
302
|
+
if (!refineId)
|
|
303
|
+
throw new Error('refine_cancel requires a "refineId".');
|
|
304
|
+
return (0, types_1.apiCall)(ctx, 'DELETE', `${base}/catalog/${encodeURIComponent(agentId)}/refine/${encodeURIComponent(refineId)}`);
|
|
305
|
+
}
|
|
306
|
+
case 'refine_apply': {
|
|
307
|
+
if (!agentId)
|
|
308
|
+
throw new Error('refine_apply requires an "agentId".');
|
|
309
|
+
if (!refineId)
|
|
310
|
+
throw new Error('refine_apply requires a "refineId".');
|
|
311
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/catalog/${encodeURIComponent(agentId)}/refine/${encodeURIComponent(refineId)}/apply`, { ...(typeof args.force === 'boolean' ? { force: args.force } : {}) });
|
|
312
|
+
}
|
|
313
|
+
default:
|
|
314
|
+
throw new Error(`Unknown action "${action}".`);
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
];
|
|
319
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyticsTools = analyticsTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
/**
|
|
7
|
+
* Build a `?a=b&c=d` query string from a flat record, skipping undefined/null/''
|
|
8
|
+
* values. Arrays are joined with commas (the spending router parses CSV for
|
|
9
|
+
* surface/model/modelProvider/provider). Used by the read actions below.
|
|
10
|
+
*/
|
|
11
|
+
function buildQuery(params) {
|
|
12
|
+
const parts = [];
|
|
13
|
+
for (const [k, v] of Object.entries(params)) {
|
|
14
|
+
if (v === undefined || v === null || v === '')
|
|
15
|
+
continue;
|
|
16
|
+
const value = Array.isArray(v) ? v.join(',') : String(v);
|
|
17
|
+
if (value === '')
|
|
18
|
+
continue;
|
|
19
|
+
parts.push(`${encodeURIComponent(k)}=${encodeURIComponent(value)}`);
|
|
20
|
+
}
|
|
21
|
+
return parts.length ? `?${parts.join('&')}` : '';
|
|
22
|
+
}
|
|
23
|
+
function analyticsTools() {
|
|
24
|
+
return [
|
|
25
|
+
{
|
|
26
|
+
name: 'specrails_analytics',
|
|
27
|
+
title: 'Analytics & Spending',
|
|
28
|
+
description: 'Per-project cost analytics over billable AI-CLI invocations (jobs, quick-spec, explore-spec, ai-edit, smash, file-summary, loop). ' +
|
|
29
|
+
'All read-only except set_budget. Actions: ' +
|
|
30
|
+
'spending (full dashboard: cost summary with prev-period delta, by-surface/model/mode/provider breakdowns, daily timeline, cost-vs-turns scatter, top tickets), ' +
|
|
31
|
+
'invocations (paginated raw invocation table), ' +
|
|
32
|
+
'ticket_summary (per-ticket cost aggregate across all surfaces), ' +
|
|
33
|
+
'export (download summary/raw analytics as CSV or JSON — file download, returns a note + headers), ' +
|
|
34
|
+
'budget_get (daily budget, per-job threshold, cost-today, utilization %), ' +
|
|
35
|
+
'budget_set (write — set/clear daily budget cap + per-job cost threshold; a too-low budget pauses the job queue). ' +
|
|
36
|
+
'Prefer spending over invocations/export-raw for token economy. ' +
|
|
37
|
+
'Filters: period(7d|30d|90d|all|custom), from/to (ISO, required for custom), surface[], model[], modelProvider[] (index-aligned to model), provider[], status(success|failed|aborted), minCostUsd, ticketId, tzOffsetMinutes(±840 — pass the user local offset so "today" lines up), sortBy.',
|
|
38
|
+
hintTier: 'read',
|
|
39
|
+
tier: (a) => (a.action === 'budget_set' ? 'write' : 'read'),
|
|
40
|
+
inputSchema: {
|
|
41
|
+
action: zod_1.z
|
|
42
|
+
.enum(['spending', 'invocations', 'ticket_summary', 'export', 'budget_get', 'budget_set'])
|
|
43
|
+
.describe('Operation to perform'),
|
|
44
|
+
projectId: zod_1.z.string().optional().describe('Project id (defaults to the active project)'),
|
|
45
|
+
// ─── Filters shared by spending / invocations / export ────────────────
|
|
46
|
+
period: zod_1.z
|
|
47
|
+
.enum(['7d', '30d', '90d', 'all', 'custom'])
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('Time window (default 30d). "custom" requires from + to.'),
|
|
50
|
+
from: zod_1.z.string().optional().describe('ISO start date (required when period=custom)'),
|
|
51
|
+
to: zod_1.z.string().optional().describe('ISO end date (required when period=custom)'),
|
|
52
|
+
surface: zod_1.z
|
|
53
|
+
.array(zod_1.z.enum(['job', 'quick-spec', 'explore-spec', 'ai-edit', 'smash', 'file-summary', 'loop']))
|
|
54
|
+
.optional()
|
|
55
|
+
.describe('Filter to these surfaces (CSV)'),
|
|
56
|
+
model: zod_1.z.array(zod_1.z.string()).optional().describe('Filter to these model ids (CSV)'),
|
|
57
|
+
modelProvider: zod_1.z
|
|
58
|
+
.array(zod_1.z.string())
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('Providers index-aligned to model[] (scopes each model id to its provider so codex/gemini estimated cost does not merge into a claude bar)'),
|
|
61
|
+
provider: zod_1.z
|
|
62
|
+
.array(zod_1.z.string())
|
|
63
|
+
.optional()
|
|
64
|
+
.describe('Filter to these providers (e.g. claude, codex, gemini) (CSV)'),
|
|
65
|
+
status: zod_1.z.enum(['success', 'failed', 'aborted']).optional().describe('Filter by invocation status'),
|
|
66
|
+
minCostUsd: zod_1.z.number().optional().describe('Only invocations costing at least this many USD'),
|
|
67
|
+
ticketId: zod_1.z.number().int().optional().describe('Scope to a single ticket id'),
|
|
68
|
+
tzOffsetMinutes: zod_1.z
|
|
69
|
+
.number()
|
|
70
|
+
.int()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe('Local UTC offset in minutes (±840) for daily-timeline calendar-day bucketing (default 0 = UTC)'),
|
|
73
|
+
sortBy: zod_1.z.enum(['recency', 'cost']).optional().describe('Sort order'),
|
|
74
|
+
// ─── invocations pagination ───────────────────────────────────────────
|
|
75
|
+
limit: zod_1.z
|
|
76
|
+
.number()
|
|
77
|
+
.int()
|
|
78
|
+
.optional()
|
|
79
|
+
.describe('invocations: max rows (clamped server-side to [1, 10000])'),
|
|
80
|
+
offset: zod_1.z.number().int().optional().describe('invocations: row offset for pagination'),
|
|
81
|
+
// ─── ticket_summary ───────────────────────────────────────────────────
|
|
82
|
+
id: zod_1.z.number().int().optional().describe('ticket_summary: the ticket id to aggregate'),
|
|
83
|
+
// ─── export ───────────────────────────────────────────────────────────
|
|
84
|
+
format: zod_1.z.enum(['csv', 'json']).optional().describe('export: output format (default json)'),
|
|
85
|
+
mode: zod_1.z
|
|
86
|
+
.enum(['summary', 'raw'])
|
|
87
|
+
.optional()
|
|
88
|
+
.describe('export: summary (aggregated dashboard) or raw (up to 10000 invocation rows). Default summary.'),
|
|
89
|
+
// ─── budget_set ───────────────────────────────────────────────────────
|
|
90
|
+
dailyBudgetUsd: zod_1.z
|
|
91
|
+
.number()
|
|
92
|
+
.nullable()
|
|
93
|
+
.optional()
|
|
94
|
+
.describe('budget_set: daily budget cap USD (>0); null clears it'),
|
|
95
|
+
jobCostThresholdUsd: zod_1.z
|
|
96
|
+
.number()
|
|
97
|
+
.nullable()
|
|
98
|
+
.optional()
|
|
99
|
+
.describe('budget_set: per-job cost alert threshold USD (>0); null clears it'),
|
|
100
|
+
},
|
|
101
|
+
async handler(ctx, args) {
|
|
102
|
+
const base = (0, types_1.projectPath)(ctx, args.projectId);
|
|
103
|
+
const action = args.action;
|
|
104
|
+
const filters = {
|
|
105
|
+
period: args.period,
|
|
106
|
+
from: args.from,
|
|
107
|
+
to: args.to,
|
|
108
|
+
surface: args.surface,
|
|
109
|
+
model: args.model,
|
|
110
|
+
modelProvider: args.modelProvider,
|
|
111
|
+
provider: args.provider,
|
|
112
|
+
status: args.status,
|
|
113
|
+
minCostUsd: args.minCostUsd,
|
|
114
|
+
ticketId: args.ticketId,
|
|
115
|
+
tzOffsetMinutes: args.tzOffsetMinutes,
|
|
116
|
+
sortBy: args.sortBy,
|
|
117
|
+
};
|
|
118
|
+
switch (action) {
|
|
119
|
+
case 'spending':
|
|
120
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/spending${buildQuery(filters)}`);
|
|
121
|
+
case 'invocations':
|
|
122
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/invocations${buildQuery({
|
|
123
|
+
...filters,
|
|
124
|
+
limit: args.limit,
|
|
125
|
+
offset: args.offset,
|
|
126
|
+
})}`);
|
|
127
|
+
case 'ticket_summary': {
|
|
128
|
+
const id = args.id;
|
|
129
|
+
if (id === undefined || id === null) {
|
|
130
|
+
throw new Error('ticket_summary requires an "id" (ticket id).');
|
|
131
|
+
}
|
|
132
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/tickets/${id}/spending-summary`);
|
|
133
|
+
}
|
|
134
|
+
case 'export': {
|
|
135
|
+
// GET /analytics/export streams a file download (Content-Disposition).
|
|
136
|
+
// apiCall returns the body text/JSON; for CSV it is the raw CSV string,
|
|
137
|
+
// for JSON the parsed dashboard/invocations object. We surface it
|
|
138
|
+
// inline with a note since there is no file sink over MCP.
|
|
139
|
+
const format = args.format ?? 'json';
|
|
140
|
+
const mode = args.mode ?? 'summary';
|
|
141
|
+
const data = await (0, types_1.apiCall)(ctx, 'GET', `${base}/analytics/export${buildQuery({ ...filters, format, mode })}`);
|
|
142
|
+
return {
|
|
143
|
+
note: `Analytics export (mode=${mode}, format=${format}). This endpoint is normally a file download; the content is returned inline below. Raw mode caps at 10000 rows. Prefer the "spending" action for already-aggregated, bounded data.`,
|
|
144
|
+
format,
|
|
145
|
+
mode,
|
|
146
|
+
data,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
case 'budget_get':
|
|
150
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/budget`);
|
|
151
|
+
case 'budget_set': {
|
|
152
|
+
const body = {};
|
|
153
|
+
if ('dailyBudgetUsd' in args)
|
|
154
|
+
body.dailyBudgetUsd = args.dailyBudgetUsd;
|
|
155
|
+
if ('jobCostThresholdUsd' in args)
|
|
156
|
+
body.jobCostThresholdUsd = args.jobCostThresholdUsd;
|
|
157
|
+
if (Object.keys(body).length === 0) {
|
|
158
|
+
throw new Error('budget_set requires dailyBudgetUsd and/or jobCostThresholdUsd (number>0 to set, null to clear).');
|
|
159
|
+
}
|
|
160
|
+
return (0, types_1.apiCall)(ctx, 'PATCH', `${base}/budget`, body);
|
|
161
|
+
}
|
|
162
|
+
default:
|
|
163
|
+
throw new Error(`Unknown action "${action}".`);
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
];
|
|
168
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.appTools = appTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const desktop_db_1 = require("../../desktop-db");
|
|
6
|
+
const mcp_tiers_1 = require("../mcp-tiers");
|
|
7
|
+
// App-level settings the MCP may read/write. NOTE: the MCP enable flag and the
|
|
8
|
+
// permission-tier toggles are intentionally NOT writable here — an external LLM
|
|
9
|
+
// must never be able to escalate its own permissions. Those are user-only,
|
|
10
|
+
// changed in the Settings ▸ MCP panel.
|
|
11
|
+
const WRITABLE_THEMES = ['specrails', 'dracula', 'aurora-light', 'obsidian-dark', 'matrix'];
|
|
12
|
+
const WRITABLE_LANGS = ['en', 'es', 'fr', 'de', 'pt', 'it', 'zh', 'ja'];
|
|
13
|
+
function appTools() {
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
name: 'specrails_settings',
|
|
17
|
+
title: 'App settings',
|
|
18
|
+
description: 'Read or update app-level Specrails settings (theme, language, daily budget, cost-alert threshold). ' +
|
|
19
|
+
'Actions: get, set. The MCP enable flag and permission tiers are read-only here (user-controlled in the app).',
|
|
20
|
+
hintTier: 'read',
|
|
21
|
+
tier: (args) => (args.action === 'set' ? 'write' : 'read'),
|
|
22
|
+
inputSchema: {
|
|
23
|
+
action: zod_1.z.enum(['get', 'set']).describe('Operation'),
|
|
24
|
+
theme: zod_1.z.enum(WRITABLE_THEMES).optional(),
|
|
25
|
+
language: zod_1.z.enum(WRITABLE_LANGS).optional(),
|
|
26
|
+
dailyBudgetUsd: zod_1.z.number().min(0).nullable().optional(),
|
|
27
|
+
costAlertThresholdUsd: zod_1.z.number().min(0).nullable().optional(),
|
|
28
|
+
},
|
|
29
|
+
handler: (ctx, args) => {
|
|
30
|
+
const db = ctx.desktopDb;
|
|
31
|
+
if (args.action === 'get') {
|
|
32
|
+
return {
|
|
33
|
+
theme: (0, desktop_db_1.getDesktopSetting)(db, 'ui_theme') ?? 'specrails',
|
|
34
|
+
language: (0, desktop_db_1.getDesktopSetting)(db, 'ui_language') ?? null,
|
|
35
|
+
dailyBudgetUsd: num((0, desktop_db_1.getDesktopSetting)(db, 'desktop_daily_budget_usd')),
|
|
36
|
+
costAlertThresholdUsd: num((0, desktop_db_1.getDesktopSetting)(db, 'cost_alert_threshold_usd')),
|
|
37
|
+
mcp: {
|
|
38
|
+
enabled: (0, mcp_tiers_1.isMcpEnabled)(db),
|
|
39
|
+
tierWrite: (0, mcp_tiers_1.isTierEnabled)(db, 'write'),
|
|
40
|
+
tierAiSpawn: (0, mcp_tiers_1.isTierEnabled)(db, 'ai-spawn'),
|
|
41
|
+
tierDestructive: (0, mcp_tiers_1.isTierEnabled)(db, 'destructive'),
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// set
|
|
46
|
+
const changed = [];
|
|
47
|
+
if (args.theme !== undefined) {
|
|
48
|
+
(0, desktop_db_1.setDesktopSetting)(db, 'ui_theme', String(args.theme));
|
|
49
|
+
changed.push('theme');
|
|
50
|
+
}
|
|
51
|
+
if (args.language !== undefined) {
|
|
52
|
+
(0, desktop_db_1.setDesktopSetting)(db, 'ui_language', String(args.language));
|
|
53
|
+
changed.push('language');
|
|
54
|
+
}
|
|
55
|
+
if (args.dailyBudgetUsd !== undefined) {
|
|
56
|
+
writeNumOrClear(db, 'desktop_daily_budget_usd', args.dailyBudgetUsd);
|
|
57
|
+
changed.push('dailyBudgetUsd');
|
|
58
|
+
}
|
|
59
|
+
if (args.costAlertThresholdUsd !== undefined) {
|
|
60
|
+
writeNumOrClear(db, 'cost_alert_threshold_usd', args.costAlertThresholdUsd);
|
|
61
|
+
changed.push('costAlertThresholdUsd');
|
|
62
|
+
}
|
|
63
|
+
if (!changed.length)
|
|
64
|
+
throw new Error('set requires at least one field (theme, language, dailyBudgetUsd, costAlertThresholdUsd).');
|
|
65
|
+
return { ok: true, changed };
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
function num(v) {
|
|
71
|
+
if (v === undefined)
|
|
72
|
+
return null;
|
|
73
|
+
const n = Number(v);
|
|
74
|
+
return Number.isFinite(n) ? n : null;
|
|
75
|
+
}
|
|
76
|
+
function writeNumOrClear(db, key, value) {
|
|
77
|
+
if (value === null)
|
|
78
|
+
(0, desktop_db_1.setDesktopSetting)(db, key, '');
|
|
79
|
+
else
|
|
80
|
+
(0, desktop_db_1.setDesktopSetting)(db, key, String(value));
|
|
81
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildToolSpecs = buildToolSpecs;
|
|
4
|
+
const projects_1 = require("./projects");
|
|
5
|
+
const app_settings_1 = require("./app-settings");
|
|
6
|
+
const watch_1 = require("./watch");
|
|
7
|
+
const meta_1 = require("./meta");
|
|
8
|
+
const specs_1 = require("./specs");
|
|
9
|
+
const rails_1 = require("./rails");
|
|
10
|
+
const jobs_1 = require("./jobs");
|
|
11
|
+
const chat_1 = require("./chat");
|
|
12
|
+
const agents_1 = require("./agents");
|
|
13
|
+
const plugins_1 = require("./plugins");
|
|
14
|
+
const jira_1 = require("./jira");
|
|
15
|
+
const loops_1 = require("./loops");
|
|
16
|
+
const code_1 = require("./code");
|
|
17
|
+
const setup_1 = require("./setup");
|
|
18
|
+
const analytics_1 = require("./analytics");
|
|
19
|
+
/**
|
|
20
|
+
* The full MCP tool catalog. Domain-facade tools each expose an `action` enum
|
|
21
|
+
* and call the app's REST API over loopback (see apiCall). Meta tools receive a
|
|
22
|
+
* lazy getter so `search`/`describe` can see the whole list.
|
|
23
|
+
*/
|
|
24
|
+
function buildToolSpecs() {
|
|
25
|
+
const specs = [];
|
|
26
|
+
// App-level + meta + watch
|
|
27
|
+
specs.push(...(0, projects_1.projectsTools)());
|
|
28
|
+
specs.push(...(0, app_settings_1.appTools)());
|
|
29
|
+
specs.push((0, watch_1.watchTool)());
|
|
30
|
+
// Per-project domains
|
|
31
|
+
specs.push(...(0, specs_1.specsTools)());
|
|
32
|
+
specs.push(...(0, rails_1.railsTools)());
|
|
33
|
+
specs.push(...(0, jobs_1.jobsTools)());
|
|
34
|
+
specs.push(...(0, chat_1.chatTools)());
|
|
35
|
+
specs.push(...(0, agents_1.agentsTools)());
|
|
36
|
+
specs.push(...(0, plugins_1.pluginsTools)());
|
|
37
|
+
specs.push(...(0, jira_1.jiraTools)());
|
|
38
|
+
specs.push(...(0, loops_1.loopsTools)());
|
|
39
|
+
specs.push(...(0, code_1.codeTools)());
|
|
40
|
+
specs.push(...(0, setup_1.setupTools)());
|
|
41
|
+
specs.push(...(0, analytics_1.analyticsTools)());
|
|
42
|
+
// Meta last (needs the full list for search/describe)
|
|
43
|
+
specs.push(...(0, meta_1.metaTools)(() => specs));
|
|
44
|
+
return specs;
|
|
45
|
+
}
|