specrails-desktop 2.16.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/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/rails-router.js +5 -0
- 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,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.jiraTools = jiraTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
/**
|
|
7
|
+
* Per-project Jira integration facade. Maps each action to the corresponding
|
|
8
|
+
* `/api/projects/:projectId/jira/*` route (server/jira-router.ts). Every op is
|
|
9
|
+
* project-scoped and external-network-bound (live HTTPS to the customer's Jira
|
|
10
|
+
* Cloud / Data Center instance with their stored or supplied credentials).
|
|
11
|
+
*
|
|
12
|
+
* SECURITY: the Jira API token / PAT is a high-value SECRET. It is passed as a
|
|
13
|
+
* plaintext `token` field on test / discover_projects / discover_statuses /
|
|
14
|
+
* connect; never log or echo it, and it is never returned on reads (GET
|
|
15
|
+
* /connection redacts it to `hasToken`).
|
|
16
|
+
*
|
|
17
|
+
* ID SCOPING: spec_details / discard_spec take the LOCAL monotonic ticket id
|
|
18
|
+
* (NOT a Jira `PROJ-123` key); retry_outbox takes the LOCAL outbox row id. Map
|
|
19
|
+
* Jira keys → local ids via the `links` action first.
|
|
20
|
+
*/
|
|
21
|
+
function jiraTools() {
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
name: 'specrails_jira',
|
|
25
|
+
title: 'Jira integration',
|
|
26
|
+
description: 'Manage a project\'s Jira-backed specs (each project syncs with its own Jira board). Read connection/links/outbox, run the connect wizard, sync, and create/discard Jira-backed specs. ' +
|
|
27
|
+
'Actions: connection (get current connection, token redacted), test (validate creds), discover_projects, discover_statuses (with throwaway creds), connect (persist connection — write), update_connection (enable/disable hot-swap + statusMap/discardStatus — write), disconnect (remove connection + restore local write access — destructive), statuses (connected project\'s real statuses), sync (full re-fetch of the board — write, long-running on big boards), resume (drain parked outbox after re-auth — write), outbox (list ops + counts), retry_outbox (re-queue a dead-lettered op — write), create_spec (create a real Jira issue — write), discard_spec (move linked issue to discard status — write), spec_details (read-only Jira fields + dev panel), links (spec↔issue link map). ' +
|
|
28
|
+
'The `token` param is a SECRET (Jira API token / PAT) — only required for test/discover_projects/discover_statuses/connect; it is never returned on reads.',
|
|
29
|
+
hintTier: 'read',
|
|
30
|
+
tier: (a) => {
|
|
31
|
+
const action = a.action;
|
|
32
|
+
if (action === 'disconnect')
|
|
33
|
+
return 'destructive';
|
|
34
|
+
if ([
|
|
35
|
+
'connect',
|
|
36
|
+
'update_connection',
|
|
37
|
+
'sync',
|
|
38
|
+
'resume',
|
|
39
|
+
'retry_outbox',
|
|
40
|
+
'create_spec',
|
|
41
|
+
'discard_spec',
|
|
42
|
+
].includes(action)) {
|
|
43
|
+
return 'write';
|
|
44
|
+
}
|
|
45
|
+
return 'read';
|
|
46
|
+
},
|
|
47
|
+
inputSchema: {
|
|
48
|
+
action: zod_1.z
|
|
49
|
+
.enum([
|
|
50
|
+
'connection',
|
|
51
|
+
'test',
|
|
52
|
+
'discover_projects',
|
|
53
|
+
'discover_statuses',
|
|
54
|
+
'connect',
|
|
55
|
+
'update_connection',
|
|
56
|
+
'disconnect',
|
|
57
|
+
'statuses',
|
|
58
|
+
'sync',
|
|
59
|
+
'resume',
|
|
60
|
+
'outbox',
|
|
61
|
+
'retry_outbox',
|
|
62
|
+
'create_spec',
|
|
63
|
+
'discard_spec',
|
|
64
|
+
'spec_details',
|
|
65
|
+
'links',
|
|
66
|
+
])
|
|
67
|
+
.describe('Jira operation to perform'),
|
|
68
|
+
projectId: zod_1.z.string().optional().describe('Project id (defaults to the active project)'),
|
|
69
|
+
// Credential / probe fields (test, discover_projects, discover_statuses, connect)
|
|
70
|
+
baseUrl: zod_1.z
|
|
71
|
+
.string()
|
|
72
|
+
.optional()
|
|
73
|
+
.describe('Jira base URL, e.g. https://acme.atlassian.net (test / discover_* / connect)'),
|
|
74
|
+
accountEmail: zod_1.z
|
|
75
|
+
.string()
|
|
76
|
+
.optional()
|
|
77
|
+
.describe('Jira account email — required for Cloud Basic auth (test / discover_* / connect)'),
|
|
78
|
+
token: zod_1.z
|
|
79
|
+
.string()
|
|
80
|
+
.optional()
|
|
81
|
+
.describe('SECRET: Jira API token (Cloud) or PAT (Data Center). Required for test / discover_projects / discover_statuses / connect. Never returned on reads.'),
|
|
82
|
+
query: zod_1.z.string().optional().describe('Optional name filter for discover_projects'),
|
|
83
|
+
projectKey: zod_1.z
|
|
84
|
+
.string()
|
|
85
|
+
.optional()
|
|
86
|
+
.describe('Jira project key to inspect statuses for (discover_statuses)'),
|
|
87
|
+
jiraProjectKey: zod_1.z
|
|
88
|
+
.string()
|
|
89
|
+
.optional()
|
|
90
|
+
.describe('Jira project key to connect this project to (connect)'),
|
|
91
|
+
statusMap: zod_1.z
|
|
92
|
+
.record(zod_1.z.string(), zod_1.z.string())
|
|
93
|
+
.optional()
|
|
94
|
+
.describe('Optional map of logical states (todo / in_progress / done / cancelled) → Jira status name (connect / update_connection)'),
|
|
95
|
+
discardStatus: zod_1.z
|
|
96
|
+
.string()
|
|
97
|
+
.optional()
|
|
98
|
+
.describe('Jira status name the discard action moves an issue to; empty string clears it (connect / update_connection)'),
|
|
99
|
+
// update_connection
|
|
100
|
+
enabled: zod_1.z
|
|
101
|
+
.boolean()
|
|
102
|
+
.optional()
|
|
103
|
+
.describe('Hot-swap toggle: true re-arms Jira write-back (read-only local backlog), false restores local write access (update_connection)'),
|
|
104
|
+
// create_spec
|
|
105
|
+
title: zod_1.z.string().optional().describe('Issue summary/title (create_spec)'),
|
|
106
|
+
description: zod_1.z.string().optional().describe('Issue description (create_spec)'),
|
|
107
|
+
labels: zod_1.z.array(zod_1.z.string()).optional().describe('Issue labels (create_spec)'),
|
|
108
|
+
priority: zod_1.z.string().optional().describe('Jira priority name (create_spec)'),
|
|
109
|
+
issueType: zod_1.z.string().optional().describe('Jira issue type; defaults to Task (create_spec)'),
|
|
110
|
+
// discard_spec / spec_details
|
|
111
|
+
localId: zod_1.z
|
|
112
|
+
.number()
|
|
113
|
+
.optional()
|
|
114
|
+
.describe('LOCAL monotonic ticket id (discard_spec / spec_details) — NOT a Jira key; map via the links action'),
|
|
115
|
+
comment: zod_1.z.string().optional().describe('Optional reason comment posted on discard (discard_spec)'),
|
|
116
|
+
// retry_outbox
|
|
117
|
+
opId: zod_1.z
|
|
118
|
+
.number()
|
|
119
|
+
.optional()
|
|
120
|
+
.describe('LOCAL outbox row id of a dead-lettered op to re-queue (retry_outbox)'),
|
|
121
|
+
// outbox
|
|
122
|
+
state: zod_1.z
|
|
123
|
+
.enum(['pending', 'inflight', 'done', 'dead'])
|
|
124
|
+
.optional()
|
|
125
|
+
.describe('Filter outbox ops by state (outbox); omit for all'),
|
|
126
|
+
},
|
|
127
|
+
async handler(ctx, args) {
|
|
128
|
+
const base = `${(0, types_1.projectPath)(ctx, args.projectId)}/jira`;
|
|
129
|
+
const action = args.action;
|
|
130
|
+
switch (action) {
|
|
131
|
+
case 'connection':
|
|
132
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/connection`);
|
|
133
|
+
case 'test':
|
|
134
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/test`, {
|
|
135
|
+
baseUrl: args.baseUrl,
|
|
136
|
+
accountEmail: args.accountEmail,
|
|
137
|
+
token: args.token,
|
|
138
|
+
});
|
|
139
|
+
case 'discover_projects':
|
|
140
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/discover-projects`, {
|
|
141
|
+
baseUrl: args.baseUrl,
|
|
142
|
+
accountEmail: args.accountEmail,
|
|
143
|
+
token: args.token,
|
|
144
|
+
query: args.query,
|
|
145
|
+
});
|
|
146
|
+
case 'discover_statuses':
|
|
147
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/discover-statuses`, {
|
|
148
|
+
baseUrl: args.baseUrl,
|
|
149
|
+
accountEmail: args.accountEmail,
|
|
150
|
+
token: args.token,
|
|
151
|
+
projectKey: args.projectKey,
|
|
152
|
+
});
|
|
153
|
+
case 'connect':
|
|
154
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/connect`, {
|
|
155
|
+
baseUrl: args.baseUrl,
|
|
156
|
+
accountEmail: args.accountEmail,
|
|
157
|
+
token: args.token,
|
|
158
|
+
jiraProjectKey: args.jiraProjectKey,
|
|
159
|
+
statusMap: args.statusMap,
|
|
160
|
+
discardStatus: args.discardStatus,
|
|
161
|
+
});
|
|
162
|
+
case 'update_connection':
|
|
163
|
+
return (0, types_1.apiCall)(ctx, 'PATCH', `${base}/connection`, {
|
|
164
|
+
enabled: args.enabled,
|
|
165
|
+
discardStatus: args.discardStatus,
|
|
166
|
+
statusMap: args.statusMap,
|
|
167
|
+
});
|
|
168
|
+
case 'disconnect':
|
|
169
|
+
return (0, types_1.apiCall)(ctx, 'DELETE', `${base}/connection`);
|
|
170
|
+
case 'statuses':
|
|
171
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/statuses`);
|
|
172
|
+
case 'sync':
|
|
173
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/sync`);
|
|
174
|
+
case 'resume':
|
|
175
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/resume`);
|
|
176
|
+
case 'outbox': {
|
|
177
|
+
const state = args.state;
|
|
178
|
+
const qs = state ? `?state=${encodeURIComponent(state)}` : '';
|
|
179
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/outbox${qs}`);
|
|
180
|
+
}
|
|
181
|
+
case 'retry_outbox': {
|
|
182
|
+
const opId = args.opId;
|
|
183
|
+
if (opId === undefined)
|
|
184
|
+
throw new Error('retry_outbox requires an "opId" (local outbox row id).');
|
|
185
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/outbox/${opId}/retry`);
|
|
186
|
+
}
|
|
187
|
+
case 'create_spec':
|
|
188
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/specs`, {
|
|
189
|
+
title: args.title,
|
|
190
|
+
description: args.description,
|
|
191
|
+
labels: args.labels,
|
|
192
|
+
priority: args.priority,
|
|
193
|
+
issueType: args.issueType,
|
|
194
|
+
});
|
|
195
|
+
case 'discard_spec': {
|
|
196
|
+
const localId = args.localId;
|
|
197
|
+
if (localId === undefined)
|
|
198
|
+
throw new Error('discard_spec requires a "localId" (local ticket id).');
|
|
199
|
+
const r = await (0, types_1.apiCall)(ctx, 'POST', `${base}/specs/${localId}/discard`, {
|
|
200
|
+
comment: args.comment,
|
|
201
|
+
});
|
|
202
|
+
// 202 accepted: the transition + optional comment drain asynchronously.
|
|
203
|
+
return {
|
|
204
|
+
...(typeof r === 'object' && r !== null ? r : { result: r }),
|
|
205
|
+
hint: 'Discard enqueued (202). Use action "outbox" to watch the transition/comment ops drain, or "connection" for live outbox counts.',
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
case 'spec_details': {
|
|
209
|
+
const localId = args.localId;
|
|
210
|
+
if (localId === undefined)
|
|
211
|
+
throw new Error('spec_details requires a "localId" (local ticket id).');
|
|
212
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/specs/${localId}/details`);
|
|
213
|
+
}
|
|
214
|
+
case 'links':
|
|
215
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/links`);
|
|
216
|
+
default:
|
|
217
|
+
throw new Error(`Unknown action "${action}".`);
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
];
|
|
222
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.jobsTools = jobsTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
/**
|
|
7
|
+
* Jobs domain facade. Maps every in-scope jobs/queue action to its REST
|
|
8
|
+
* endpoint on the loopback API (server/project-router-jobs.ts, plus the
|
|
9
|
+
* diagnostic export in server/project-router-settings.ts).
|
|
10
|
+
*
|
|
11
|
+
* Rail-specific operations (launch/stop/set_* on /rails) live in a separate
|
|
12
|
+
* rails tool; this facade covers the project-level job queue and individual
|
|
13
|
+
* job lifecycle. Note: `spawn` here is the rail-bypass `/spawn` endpoint that
|
|
14
|
+
* enqueues an arbitrary slash-command job (incurs token cost, async 202).
|
|
15
|
+
*/
|
|
16
|
+
function jobsTools() {
|
|
17
|
+
return [
|
|
18
|
+
{
|
|
19
|
+
name: 'specrails_jobs',
|
|
20
|
+
title: 'Jobs & Queue',
|
|
21
|
+
description: 'Manage a project\'s AI-pipeline job queue and individual jobs. ' +
|
|
22
|
+
'Actions: list, get, queue, spawn (ai-spawn — enqueues an arbitrary slash-command job, returns {jobId,position}, async), ' +
|
|
23
|
+
'cancel (destructive — cancels a running/queued job or deletes a terminal one), ' +
|
|
24
|
+
'purge (destructive — bulk-delete persisted job rows in a date range), ' +
|
|
25
|
+
'pause / resume (queue), reorder (queued-job order), priority (change a queued job\'s priority), ' +
|
|
26
|
+
'compare (two jobs side-by-side), export (up to 10k rows as JSON/CSV), ' +
|
|
27
|
+
'diagnostic (binary ZIP — returns a note, not the bytes), run_state (project run state), ' +
|
|
28
|
+
'activity (recent activity feed), stats, metrics, default_spec_model, ' +
|
|
29
|
+
'interactive_turn (ai-spawn — send one more prompt to a running interactive ultracode job), ' +
|
|
30
|
+
'finalize (finalize a running interactive job).',
|
|
31
|
+
hintTier: 'read',
|
|
32
|
+
tier: (a) => {
|
|
33
|
+
const action = a.action;
|
|
34
|
+
if (['cancel', 'purge'].includes(action))
|
|
35
|
+
return 'destructive';
|
|
36
|
+
if (['spawn', 'interactive_turn'].includes(action))
|
|
37
|
+
return 'ai-spawn';
|
|
38
|
+
if (['pause', 'resume', 'reorder', 'priority', 'finalize'].includes(action))
|
|
39
|
+
return 'write';
|
|
40
|
+
return 'read';
|
|
41
|
+
},
|
|
42
|
+
inputSchema: {
|
|
43
|
+
action: zod_1.z
|
|
44
|
+
.enum([
|
|
45
|
+
'list',
|
|
46
|
+
'get',
|
|
47
|
+
'queue',
|
|
48
|
+
'spawn',
|
|
49
|
+
'cancel',
|
|
50
|
+
'purge',
|
|
51
|
+
'pause',
|
|
52
|
+
'resume',
|
|
53
|
+
'reorder',
|
|
54
|
+
'priority',
|
|
55
|
+
'compare',
|
|
56
|
+
'export',
|
|
57
|
+
'diagnostic',
|
|
58
|
+
'run_state',
|
|
59
|
+
'activity',
|
|
60
|
+
'stats',
|
|
61
|
+
'metrics',
|
|
62
|
+
'default_spec_model',
|
|
63
|
+
'interactive_turn',
|
|
64
|
+
'finalize',
|
|
65
|
+
])
|
|
66
|
+
.describe('Operation to perform'),
|
|
67
|
+
projectId: zod_1.z.string().optional().describe('Project id (defaults to the active project)'),
|
|
68
|
+
// ── job identity ──
|
|
69
|
+
jobId: zod_1.z
|
|
70
|
+
.string()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe('Job id (for get / cancel / priority / diagnostic / interactive_turn / finalize)'),
|
|
73
|
+
// ── list / export pagination + filters ──
|
|
74
|
+
limit: zod_1.z.number().optional().describe('Page size for list (1-200, default 50) / activity (1-100, default 50)'),
|
|
75
|
+
offset: zod_1.z.number().optional().describe('Page offset for list'),
|
|
76
|
+
status: zod_1.z.string().optional().describe('Filter by job status (list)'),
|
|
77
|
+
from: zod_1.z.string().optional().describe('ISO date lower bound (list / export / purge)'),
|
|
78
|
+
to: zod_1.z.string().optional().describe('ISO date upper bound (list / export / purge)'),
|
|
79
|
+
before: zod_1.z.string().optional().describe('Activity cursor: return rows before this timestamp'),
|
|
80
|
+
// ── spawn (rail-bypass enqueue) ──
|
|
81
|
+
command: zod_1.z.string().optional().describe('Slash-command to enqueue (spawn), e.g. "/specrails:implement #5 --yes"'),
|
|
82
|
+
priority: zod_1.z
|
|
83
|
+
.enum(['low', 'normal', 'high', 'critical'])
|
|
84
|
+
.optional()
|
|
85
|
+
.describe('Priority for spawn / priority action'),
|
|
86
|
+
dependsOnJobId: zod_1.z.string().optional().describe('Make the spawned job depend on this job id'),
|
|
87
|
+
pipelineId: zod_1.z.string().optional().describe('Group the spawned job into this pipeline'),
|
|
88
|
+
profileName: zod_1.z
|
|
89
|
+
.string()
|
|
90
|
+
.optional()
|
|
91
|
+
.describe('Agent profile for spawn (omit = default resolution; pass empty/null upstream forces legacy)'),
|
|
92
|
+
aiEngine: zod_1.z.string().optional().describe('Per-job provider override for spawn (must be installed on the project)'),
|
|
93
|
+
// ── reorder ──
|
|
94
|
+
jobIds: zod_1.z
|
|
95
|
+
.array(zod_1.z.string())
|
|
96
|
+
.optional()
|
|
97
|
+
.describe('reorder: exact set of currently-queued job ids in the desired order; compare: exactly 2 job ids'),
|
|
98
|
+
// ── interactive_turn ──
|
|
99
|
+
text: zod_1.z.string().optional().describe('Prompt text for interactive_turn'),
|
|
100
|
+
// ── export ──
|
|
101
|
+
format: zod_1.z.enum(['json', 'csv']).optional().describe('Export format (default json)'),
|
|
102
|
+
// ── default_spec_model ──
|
|
103
|
+
provider: zod_1.z.string().optional().describe('Provider to resolve the default spec model for (default_spec_model)'),
|
|
104
|
+
},
|
|
105
|
+
async handler(ctx, args) {
|
|
106
|
+
const base = (0, types_1.projectPath)(ctx, args.projectId);
|
|
107
|
+
const action = args.action;
|
|
108
|
+
switch (action) {
|
|
109
|
+
case 'list': {
|
|
110
|
+
const qs = new URLSearchParams();
|
|
111
|
+
if (args.limit !== undefined)
|
|
112
|
+
qs.set('limit', String(args.limit));
|
|
113
|
+
if (args.offset !== undefined)
|
|
114
|
+
qs.set('offset', String(args.offset));
|
|
115
|
+
if (args.status)
|
|
116
|
+
qs.set('status', args.status);
|
|
117
|
+
if (args.from)
|
|
118
|
+
qs.set('from', args.from);
|
|
119
|
+
if (args.to)
|
|
120
|
+
qs.set('to', args.to);
|
|
121
|
+
const q = qs.toString();
|
|
122
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/jobs${q ? `?${q}` : ''}`);
|
|
123
|
+
}
|
|
124
|
+
case 'get': {
|
|
125
|
+
const id = args.jobId;
|
|
126
|
+
if (!id)
|
|
127
|
+
throw new Error('get requires a "jobId".');
|
|
128
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/jobs/${encodeURIComponent(id)}`);
|
|
129
|
+
}
|
|
130
|
+
case 'queue':
|
|
131
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/queue`);
|
|
132
|
+
case 'spawn': {
|
|
133
|
+
const command = args.command;
|
|
134
|
+
if (!command || !command.trim())
|
|
135
|
+
throw new Error('spawn requires a "command".');
|
|
136
|
+
const r = await (0, types_1.apiCall)(ctx, 'POST', `${base}/spawn`, {
|
|
137
|
+
command,
|
|
138
|
+
priority: args.priority,
|
|
139
|
+
dependsOnJobId: args.dependsOnJobId,
|
|
140
|
+
pipelineId: args.pipelineId,
|
|
141
|
+
profileName: args.profileName,
|
|
142
|
+
aiEngine: args.aiEngine,
|
|
143
|
+
});
|
|
144
|
+
return {
|
|
145
|
+
...r,
|
|
146
|
+
hint: 'Spawned an AI CLI job (incurs token cost). Use specrails_watch with the returned jobId to await completion.',
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
case 'cancel': {
|
|
150
|
+
const id = args.jobId;
|
|
151
|
+
if (!id)
|
|
152
|
+
throw new Error('cancel requires a "jobId".');
|
|
153
|
+
return (0, types_1.apiCall)(ctx, 'DELETE', `${base}/jobs/${encodeURIComponent(id)}`);
|
|
154
|
+
}
|
|
155
|
+
case 'purge':
|
|
156
|
+
return (0, types_1.apiCall)(ctx, 'DELETE', `${base}/jobs`, {
|
|
157
|
+
from: args.from,
|
|
158
|
+
to: args.to,
|
|
159
|
+
});
|
|
160
|
+
case 'pause':
|
|
161
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/queue/pause`);
|
|
162
|
+
case 'resume':
|
|
163
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/queue/resume`);
|
|
164
|
+
case 'reorder': {
|
|
165
|
+
const jobIds = args.jobIds;
|
|
166
|
+
if (!Array.isArray(jobIds))
|
|
167
|
+
throw new Error('reorder requires "jobIds" (array of queued job ids).');
|
|
168
|
+
return (0, types_1.apiCall)(ctx, 'PUT', `${base}/queue/reorder`, { jobIds });
|
|
169
|
+
}
|
|
170
|
+
case 'priority': {
|
|
171
|
+
const id = args.jobId;
|
|
172
|
+
if (!id)
|
|
173
|
+
throw new Error('priority requires a "jobId".');
|
|
174
|
+
const priority = args.priority;
|
|
175
|
+
if (!priority)
|
|
176
|
+
throw new Error('priority requires a "priority" (low|normal|high|critical).');
|
|
177
|
+
return (0, types_1.apiCall)(ctx, 'PATCH', `${base}/jobs/${encodeURIComponent(id)}/priority`, { priority });
|
|
178
|
+
}
|
|
179
|
+
case 'compare': {
|
|
180
|
+
const jobIds = args.jobIds;
|
|
181
|
+
if (!Array.isArray(jobIds) || jobIds.length !== 2) {
|
|
182
|
+
throw new Error('compare requires exactly 2 ids in "jobIds".');
|
|
183
|
+
}
|
|
184
|
+
const qs = new URLSearchParams({ jobIds: jobIds.join(',') });
|
|
185
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/jobs/compare?${qs.toString()}`);
|
|
186
|
+
}
|
|
187
|
+
case 'export': {
|
|
188
|
+
const qs = new URLSearchParams();
|
|
189
|
+
qs.set('format', args.format ?? 'json');
|
|
190
|
+
if (args.from)
|
|
191
|
+
qs.set('from', args.from);
|
|
192
|
+
if (args.to)
|
|
193
|
+
qs.set('to', args.to);
|
|
194
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/jobs/export?${qs.toString()}`);
|
|
195
|
+
}
|
|
196
|
+
case 'diagnostic': {
|
|
197
|
+
const id = args.jobId;
|
|
198
|
+
if (!id)
|
|
199
|
+
throw new Error('diagnostic requires a "jobId".');
|
|
200
|
+
// The diagnostic endpoint streams an application/zip (job-metadata.json,
|
|
201
|
+
// telemetry.ndjson, logs.txt, summary.md, profile + plugin snapshot).
|
|
202
|
+
// We do NOT inline binary bytes through the MCP text channel — return a
|
|
203
|
+
// pointer the caller can fetch over the loopback REST API directly.
|
|
204
|
+
return {
|
|
205
|
+
note: 'Binary export (application/zip) — not inlined.',
|
|
206
|
+
jobId: id,
|
|
207
|
+
path: `${base}/jobs/${encodeURIComponent(id)}/diagnostic`,
|
|
208
|
+
hint: 'Requires a telemetry blob to exist for the job (else 404). Fetch the ZIP via the REST endpoint at the given path.',
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
case 'run_state':
|
|
212
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/state`);
|
|
213
|
+
case 'activity': {
|
|
214
|
+
const qs = new URLSearchParams();
|
|
215
|
+
if (args.limit !== undefined)
|
|
216
|
+
qs.set('limit', String(args.limit));
|
|
217
|
+
if (args.before)
|
|
218
|
+
qs.set('before', args.before);
|
|
219
|
+
const q = qs.toString();
|
|
220
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/activity${q ? `?${q}` : ''}`);
|
|
221
|
+
}
|
|
222
|
+
case 'stats':
|
|
223
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/stats`);
|
|
224
|
+
case 'metrics':
|
|
225
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/metrics`);
|
|
226
|
+
case 'default_spec_model': {
|
|
227
|
+
const qs = new URLSearchParams();
|
|
228
|
+
if (args.provider)
|
|
229
|
+
qs.set('provider', args.provider);
|
|
230
|
+
const q = qs.toString();
|
|
231
|
+
return (0, types_1.apiCall)(ctx, 'GET', `${base}/default-spec-model${q ? `?${q}` : ''}`);
|
|
232
|
+
}
|
|
233
|
+
case 'interactive_turn': {
|
|
234
|
+
const id = args.jobId;
|
|
235
|
+
if (!id)
|
|
236
|
+
throw new Error('interactive_turn requires a "jobId".');
|
|
237
|
+
const text = args.text;
|
|
238
|
+
if (!text || !text.trim())
|
|
239
|
+
throw new Error('interactive_turn requires "text".');
|
|
240
|
+
const r = await (0, types_1.apiCall)(ctx, 'POST', `${base}/jobs/${encodeURIComponent(id)}/messages`, { text });
|
|
241
|
+
return {
|
|
242
|
+
...r,
|
|
243
|
+
hint: 'Queued an additional interactive turn (incurs token cost). Use specrails_watch with the jobId to follow the job.',
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
case 'finalize': {
|
|
247
|
+
const id = args.jobId;
|
|
248
|
+
if (!id)
|
|
249
|
+
throw new Error('finalize requires a "jobId".');
|
|
250
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/jobs/${encodeURIComponent(id)}/finalize`);
|
|
251
|
+
}
|
|
252
|
+
default:
|
|
253
|
+
throw new Error(`Unknown action "${action}".`);
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
];
|
|
258
|
+
}
|