specrails-desktop 2.16.0 → 2.18.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-mGnv5SOe.js} +1 -1
- package/client/dist/assets/AgentsPage-BH1isg5j.js +86 -0
- package/client/dist/assets/AnalyticsPage-ByyshYRI.js +1 -0
- package/client/dist/assets/{BarChart-Dq1h8eYR.js → BarChart-BqHUOnl9.js} +3 -3
- package/client/dist/assets/CodePage-CU7T_HYs.js +2 -0
- package/client/dist/assets/{DesktopAnalyticsPage-CYhXhJoQ.js → DesktopAnalyticsPage-CR-m97Ui.js} +1 -1
- package/client/dist/assets/DocsDialog-CEmZp_8V.js +11 -0
- package/client/dist/assets/DocsPage-DYbAQ1AT.js +11 -0
- package/client/dist/assets/{ExportDropdown-DdB2ncYh.js → ExportDropdown-C-o1Q4ef.js} +1 -1
- package/client/dist/assets/IntegrationsPage-C6fKdwVH.js +3 -0
- package/client/dist/assets/JobDetailPage-CKfIfBgE.js +16 -0
- package/client/dist/assets/JobsPage-nBng0riZ.js +1 -0
- package/client/dist/assets/LoopBuilderPage-Co_TYqYk.js +7 -0
- package/client/dist/assets/LoopsPage-a2hd37Ya.js +1 -0
- package/client/dist/assets/{activity-Ca2XoBi-.js → activity-D8vQJrpW.js} +1 -1
- package/client/dist/assets/{addon-image-biWX2UUm.js → addon-image-Ba-TY3wr.js} +1 -1
- package/client/dist/assets/{addon-ligatures-D4EiDb5r.js → addon-ligatures-T4ARLiuu.js} +1 -1
- package/client/dist/assets/{addon-webgl-CDCIZQ03.js → addon-webgl-Cd73n8eh.js} +1 -1
- package/client/dist/assets/{addspec-DE_VfIyP.js → addspec-BloGn_ey.js} +1 -1
- package/client/dist/assets/agent-9WdSxPU5.js +1 -0
- package/client/dist/assets/agent-ASIyVcg0.js +1 -0
- package/client/dist/assets/agent-Bm2tPrdr.js +1 -0
- package/client/dist/assets/agent-C4bO1l_v.js +1 -0
- package/client/dist/assets/agent-CgKsh88Z2.js +1 -0
- package/client/dist/assets/agent-DMUrz9ZS2.js +1 -0
- package/client/dist/assets/agent-Dwkz5mPS.js +1 -0
- package/client/dist/assets/agent-pO8x4jbR.js +1 -0
- package/client/dist/assets/{agents-DcoUUFZl.js → agents-52t8NVpS.js} +1 -1
- package/client/dist/assets/{agents-DCX9D3-Q.js → agents-BAxAwHy-.js} +1 -1
- package/client/dist/assets/{agents-Jc-CjBDB.js → agents-BUYBb825.js} +1 -1
- package/client/dist/assets/{agents-CIhRSOna.js → agents-BjT_xLjv.js} +1 -1
- package/client/dist/assets/{agents-BYjUOrLD.js → agents-C07al8rI.js} +1 -1
- package/client/dist/assets/{agents-1lhqEcXH.js → agents-DfGvYtpq2.js} +1 -1
- package/client/dist/assets/{agents-CQlu1nOm.js → agents-Dli56gr82.js} +1 -1
- package/client/dist/assets/{agents-DVYpVGur.js → agents-Eqw_AQ6H.js} +1 -1
- package/client/dist/assets/{agentstudio-DCTpIqOx.js → agentstudio-CZm2rOzt.js} +1 -1
- package/client/dist/assets/{aiedit-Dirqf3Bm.js → aiedit-DYtnZU9H.js} +1 -1
- package/client/dist/assets/{analytics-BE49LbUk.js → analytics-B4FJ_pry.js} +1 -1
- package/client/dist/assets/{attachments-C2JPppoP.js → attachments-Ci6_42Kh.js} +1 -1
- package/client/dist/assets/{browser-Dpo_ug4c.js → browser-ZB1afzjZ.js} +1 -1
- package/client/dist/assets/{chat-mq1x9cxZ.js → chat-VMflhzxn.js} +1 -1
- package/client/dist/assets/chunk-BNv3lrIs.js +1 -0
- package/client/dist/assets/{code-DtIatVES.js → code-wtcs0ivb.js} +1 -1
- package/client/dist/assets/commands-Bc8y9eNo2.js +1 -0
- package/client/dist/assets/commands-Bl3-KVfj.js +1 -0
- package/client/dist/assets/commands-C5WQ9blx2.js +1 -0
- package/client/dist/assets/commands-CM99Upsz2.js +1 -0
- package/client/dist/assets/commands-Cc2WpuXa.js +1 -0
- package/client/dist/assets/commands-CckaBWdV.js +1 -0
- package/client/dist/assets/commands-DASXJD-l.js +1 -0
- package/client/dist/assets/commands-k9wbNYoi.js +1 -0
- package/client/dist/assets/{common-kftoE0Q-.js → common-BPQQkgJZ.js} +1 -1
- package/client/dist/assets/{cssMode-DSHXamUH.js → cssMode-DsArsSCT.js} +1 -1
- package/client/dist/assets/{dashboard-BQ3Oa8CE.js → dashboard-Cyzp4ox9.js} +1 -1
- package/client/dist/assets/{dist-js-Ele_sHO7.js → dist-js-BHhtSerX.js} +1 -1
- package/client/dist/assets/{dist-js-D27I-bfi.js → dist-js-CUegfF6k.js} +1 -1
- package/client/dist/assets/{editor.api2-Cwla1nvV.js → editor.api2-T7u8kQWG.js} +1 -1
- package/client/dist/assets/{editor.main-Cd8qBRAT.js → editor.main-G3Sl9C67.js} +2 -2
- package/client/dist/assets/{explore-CBYU76JD.js → explore-BKVV5JSu.js} +1 -1
- package/client/dist/assets/{freemarker2-CkEKTBm2.js → freemarker2-pBzQNgFi.js} +1 -1
- package/client/dist/assets/{handlebars-BRGx0JpL.js → handlebars-CtBTCnBI.js} +1 -1
- package/client/dist/assets/{html-BfRIaGgN.js → html-Dx3DYBzY.js} +1 -1
- package/client/dist/assets/{htmlMode-BTpSnsDE.js → htmlMode-In7frFOo.js} +1 -1
- package/client/dist/assets/index-B0FxQALR.css +2 -0
- package/client/dist/assets/index-B7vB20Jw.js +152 -0
- package/client/dist/assets/{integrations-jJGaKwff.js → integrations-CuWnMR5L.js} +1 -1
- package/client/dist/assets/{javascript-DMmE2kKN.js → javascript-BKcn-YkN.js} +1 -1
- package/client/dist/assets/{jira-BwACz875.js → jira-DXMoAKWD.js} +1 -1
- package/client/dist/assets/{jobs-DRInW0AE.js → jobs---dwa4Nf.js} +1 -1
- package/client/dist/assets/{jsonMode-hYuaUleY.js → jsonMode-jNREoQ3C.js} +1 -1
- package/client/dist/assets/{lib-qdRfWwE1.js → lib-PQoHlR5u.js} +2 -2
- package/client/dist/assets/{liquid-C-VbuTr7.js → liquid-CtRkGqBu.js} +1 -1
- package/client/dist/assets/{loops-DfGadne0.js → loops-D8Iu6Jss.js} +1 -1
- package/client/dist/assets/{lspLanguageFeatures-BALx-vjn.js → lspLanguageFeatures-Cl3gvD_W.js} +1 -1
- package/client/dist/assets/mcp-B4irfLJ2.js +1 -0
- package/client/dist/assets/mcp-B6nwJJmR.js +1 -0
- package/client/dist/assets/mcp-BOoEGTSQ.js +1 -0
- package/client/dist/assets/mcp-BP7PpbDr2.js +1 -0
- package/client/dist/assets/mcp-CIH0pH1K.js +1 -0
- package/client/dist/assets/mcp-CNgFiTEh.js +1 -0
- package/client/dist/assets/mcp-D3E4_Mmk2.js +1 -0
- package/client/dist/assets/mcp-mupPuPDO2.js +1 -0
- package/client/dist/assets/{mdx-Cs8MNCzn.js → mdx-B_nJldHz.js} +1 -1
- package/client/dist/assets/{monaco.contribution-CIvCAJs4.js → monaco.contribution-PUeaZk8T.js} +2 -2
- package/client/dist/assets/{nav-CCz4krPP.js → nav-DE3yWQw6.js} +1 -1
- package/client/dist/assets/{python-CGShLxuI.js → python-DS1Ce-A6.js} +1 -1
- package/client/dist/assets/{razor-CvOBQGd5.js → razor-L41Qg9OK.js} +1 -1
- package/client/dist/assets/settings-BKmORxlB2.js +1 -0
- package/client/dist/assets/settings-BVv2JgQ8.js +1 -0
- package/client/dist/assets/settings-Bghm3pAV.js +1 -0
- package/client/dist/assets/settings-BuC_aplX.js +1 -0
- package/client/dist/assets/settings-Bw_Qk8E32.js +1 -0
- package/client/dist/assets/settings-CAKgJv7p.js +1 -0
- package/client/dist/assets/settings-CEUgk1Ck.js +1 -0
- package/client/dist/assets/settings-C_PDE20s2.js +1 -0
- package/client/dist/assets/setup-4us-Bz3H.js +1 -0
- package/client/dist/assets/setup-BYoDYoPY2.js +1 -0
- package/client/dist/assets/setup-Bf9eLKxU.js +1 -0
- package/client/dist/assets/setup-C5UbM0RP.js +1 -0
- package/client/dist/assets/setup-CqGrWb6G.js +1 -0
- package/client/dist/assets/setup-JFkWWZnR.js +1 -0
- package/client/dist/assets/setup-faMApo0U2.js +1 -0
- package/client/dist/assets/setup-tloaTobG2.js +1 -0
- package/client/dist/assets/{specs-C_8j4ELZ.js → specs-BYeAbIEy.js} +1 -1
- package/client/dist/assets/{terminal-Cj4HzP3p.js → terminal-DFPNRLKp.js} +1 -1
- package/client/dist/assets/{tickets-DBQXMYYA.js → tickets-CkfbISuK.js} +1 -1
- package/client/dist/assets/{tsMode-04uOpiiP.js → tsMode-BC1g186U.js} +1 -1
- package/client/dist/assets/{typescript-CX0CwyIZ.js → typescript-BGlRGvJW.js} +1 -1
- package/client/dist/assets/upload-PnJDPHZH.js +1 -0
- package/client/dist/assets/{value-BRVOAvhY.js → value-BTDefcOV.js} +1 -1
- package/client/dist/assets/{workers-yr2u4c3C.js → workers-CXcXtO3b.js} +1 -1
- package/client/dist/assets/{xml-C0OFlt5X.js → xml-JdZZaIhJ.js} +1 -1
- package/client/dist/assets/{yaml-DgabaPs5.js → yaml-Cm82BVBt.js} +1 -1
- package/client/dist/index.html +30 -28
- package/docs/README.md +2 -0
- package/docs/guide/de/integrations/5-mcp-server.md +74 -0
- package/docs/guide/de/integrations/6-agent-chat.md +64 -0
- package/docs/guide/en/integrations/5-mcp-server.md +74 -0
- package/docs/guide/en/integrations/6-agent-chat.md +64 -0
- package/docs/guide/es/integrations/5-mcp-server.md +74 -0
- package/docs/guide/es/integrations/6-agent-chat.md +64 -0
- package/docs/guide/fr/integrations/5-mcp-server.md +74 -0
- package/docs/guide/fr/integrations/6-agent-chat.md +64 -0
- package/docs/guide/it/integrations/5-mcp-server.md +74 -0
- package/docs/guide/it/integrations/6-agent-chat.md +64 -0
- package/docs/guide/ja/integrations/5-mcp-server.md +74 -0
- package/docs/guide/ja/integrations/6-agent-chat.md +64 -0
- package/docs/guide/pt/integrations/5-mcp-server.md +74 -0
- package/docs/guide/pt/integrations/6-agent-chat.md +64 -0
- package/docs/guide/zh/integrations/5-mcp-server.md +74 -0
- package/docs/guide/zh/integrations/6-agent-chat.md +64 -0
- package/docs/mcp.md +249 -0
- package/package.json +8 -5
- package/server/dist/agent-chat-manager.js +224 -0
- package/server/dist/agent-chat-router.js +148 -0
- package/server/dist/agent-cwd-manager.js +94 -0
- package/server/dist/agent-mcp-config.js +208 -0
- package/server/dist/agent-store.js +59 -0
- package/server/dist/agent-tier.js +86 -0
- package/server/dist/desktop-db.js +27 -0
- package/server/dist/index.js +38 -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 +167 -0
- package/server/dist/mcp/tools/specs.js +327 -0
- package/server/dist/mcp/tools/types.js +156 -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-setup.js +15 -1
- package/server/dist/project-router-tickets.js +2 -2
- package/server/dist/providers/codex-adapter.js +19 -3
- package/server/dist/rails-router.js +5 -0
- package/server/dist/setup-manager.js +28 -0
- package/server/dist/spawn-lifecycle.js +21 -13
- package/server/dist/workspace-manager.js +11 -0
- package/client/dist/assets/AgentsPage-jcPUtPhP.js +0 -86
- package/client/dist/assets/AnalyticsPage-DZkVU3yd.js +0 -1
- package/client/dist/assets/CodePage-BcbZT88K.js +0 -2
- package/client/dist/assets/DocsDialog-CS3Syf61.js +0 -11
- package/client/dist/assets/DocsPage-l3ZcTO2E.js +0 -11
- package/client/dist/assets/IntegrationsPage-CJ_Om1zu.js +0 -3
- 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/chunk-CilyBKbf.js +0 -1
- package/client/dist/assets/commands-B9XEyMj-.js +0 -1
- package/client/dist/assets/commands-BI1Ta-E7.js +0 -1
- package/client/dist/assets/commands-BdI0CtOL.js +0 -1
- package/client/dist/assets/commands-C2ewlyXo.js +0 -1
- package/client/dist/assets/commands-CwypztRT.js +0 -1
- package/client/dist/assets/commands-DSX3yJyr.js +0 -1
- package/client/dist/assets/commands-Ic1DJDxm.js +0 -1
- package/client/dist/assets/commands-yNn4IA4C.js +0 -1
- package/client/dist/assets/index-BRMyOS1B.css +0 -2
- package/client/dist/assets/index-meTWPBzY.js +0 -144
- package/client/dist/assets/settings-0m2iuTzd.js +0 -1
- package/client/dist/assets/settings-BA1V6KdK.js +0 -1
- package/client/dist/assets/settings-BN7OusER.js +0 -1
- package/client/dist/assets/settings-Bi5FFkIw.js +0 -1
- package/client/dist/assets/settings-CRJxyTNN.js +0 -1
- package/client/dist/assets/settings-DyBxunCh.js +0 -1
- package/client/dist/assets/settings-fk-WlnUt.js +0 -1
- package/client/dist/assets/settings-iQe5Dim-.js +0 -1
- 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/upload-DPG87J4t.js +0 -1
- /package/client/dist/assets/{abap-CK68cr9-.js → abap-CpHUwCVK.js} +0 -0
- /package/client/dist/assets/{activity-Di2f50_Z.js → activity-B82z3Pna.js} +0 -0
- /package/client/dist/assets/{activity-B2MvEH54.js → activity-BId0pwuS2.js} +0 -0
- /package/client/dist/assets/{activity-D4dhNEwO.js → activity-BVpZrs0J.js} +0 -0
- /package/client/dist/assets/{activity-DHjfmAyT.js → activity-BySXFT2J2.js} +0 -0
- /package/client/dist/assets/{activity-usnNa7FX.js → activity-DIWnV0Pl.js} +0 -0
- /package/client/dist/assets/{activity-C7VdmeGb.js → activity-Uj576ckT.js} +0 -0
- /package/client/dist/assets/{activity-BbNkUmW4.js → activity-w1qMFwxh.js} +0 -0
- /package/client/dist/assets/{addspec-CO1xv6BL.js → addspec-B9dY_F5T.js} +0 -0
- /package/client/dist/assets/{addspec-CNyAUGz_.js → addspec-B9nhMikb.js} +0 -0
- /package/client/dist/assets/{addspec-IozoiiGs.js → addspec-BtNaJHu2.js} +0 -0
- /package/client/dist/assets/{addspec-BxMn39wn.js → addspec-D43TlMVp2.js} +0 -0
- /package/client/dist/assets/{addspec-1HEtmLv1.js → addspec-DfgIZ5lO.js} +0 -0
- /package/client/dist/assets/{addspec-DfuR6EAl.js → addspec-W0r16BOC2.js} +0 -0
- /package/client/dist/assets/{addspec-DAveBiCE.js → addspec-tbxr3sHa.js} +0 -0
- /package/client/dist/assets/{agentstudio-DCyDW8sy.js → agentstudio-0o3XKrcy.js} +0 -0
- /package/client/dist/assets/{agentstudio-9NbsoGXk.js → agentstudio-Bu8m5jDw.js} +0 -0
- /package/client/dist/assets/{agentstudio-B1y0JWY-.js → agentstudio-C7xxqVWn.js} +0 -0
- /package/client/dist/assets/{agentstudio-1E-bag77.js → agentstudio-D-UoNAIA.js} +0 -0
- /package/client/dist/assets/{agentstudio-B-jQgYV-.js → agentstudio-OJjjz6Uf2.js} +0 -0
- /package/client/dist/assets/{agentstudio-Q0Sq_jTg.js → agentstudio-ObTpVbBP.js} +0 -0
- /package/client/dist/assets/{agentstudio-Bwa72b1S.js → agentstudio-PzFB3vfh2.js} +0 -0
- /package/client/dist/assets/{aiedit-DUpe7NxI.js → aiedit-BIQqv2XM2.js} +0 -0
- /package/client/dist/assets/{aiedit-kAU7KADg.js → aiedit-BaLZalLa.js} +0 -0
- /package/client/dist/assets/{aiedit-CvSspQmE.js → aiedit-BjlUzasF.js} +0 -0
- /package/client/dist/assets/{aiedit-DSLtsYIu.js → aiedit-BmDufyGU.js} +0 -0
- /package/client/dist/assets/{aiedit-qTGI_PGs.js → aiedit-DAM_WRAl2.js} +0 -0
- /package/client/dist/assets/{aiedit-CfBNanHE.js → aiedit-DRrNiaB4.js} +0 -0
- /package/client/dist/assets/{aiedit-CGxeml8D.js → aiedit-sP_iao2j.js} +0 -0
- /package/client/dist/assets/{analytics-CgEkAUiP.js → analytics-BDqqCzN9.js} +0 -0
- /package/client/dist/assets/{analytics-DEsEAJZL.js → analytics-B_rxNC9X.js} +0 -0
- /package/client/dist/assets/{analytics-D1ElChhs.js → analytics-C4z_NgJZ.js} +0 -0
- /package/client/dist/assets/{analytics-DDqve9Ma.js → analytics-DL2vJCbq.js} +0 -0
- /package/client/dist/assets/{analytics-CQqu1yE5.js → analytics-Ds_PNxtO2.js} +0 -0
- /package/client/dist/assets/{analytics-BDlELxc7.js → analytics-MVJRjcY52.js} +0 -0
- /package/client/dist/assets/{analytics-DBGO8B6-.js → analytics-e1mkNTgy2.js} +0 -0
- /package/client/dist/assets/{apex-BHHyAVNb.js → apex-DlD7oJX6.js} +0 -0
- /package/client/dist/assets/{atom-one-dark-DrWoEEbZ.js → atom-one-dark-BrRN8wBy.js} +0 -0
- /package/client/dist/assets/{attachments-BNgH6Tcu.js → attachments-8QCKHCEF2.js} +0 -0
- /package/client/dist/assets/{attachments-BLqqPGyy.js → attachments-BP0Ac1yt.js} +0 -0
- /package/client/dist/assets/{attachments-UJtEq892.js → attachments-CJaO1vCH.js} +0 -0
- /package/client/dist/assets/{attachments-D5fVsMgb.js → attachments-CPBVeHX72.js} +0 -0
- /package/client/dist/assets/{attachments-3CuBBRFu.js → attachments-CV2uaTGE.js} +0 -0
- /package/client/dist/assets/{attachments-CppM7de8.js → attachments-CaOjdN332.js} +0 -0
- /package/client/dist/assets/{attachments-pW3zm9nu.js → attachments-Db7JfA8a.js} +0 -0
- /package/client/dist/assets/{azcli-C56lfIEP.js → azcli-CmXFAbc-.js} +0 -0
- /package/client/dist/assets/{bat-BLamSaf-.js → bat-DdNJq4hH.js} +0 -0
- /package/client/dist/assets/{bicep-lrOcEItS.js → bicep-Bppz7WOA.js} +0 -0
- /package/client/dist/assets/{browser-C__Vz7KR.js → browser-0xeW8fUa2.js} +0 -0
- /package/client/dist/assets/{browser-EFmPpkvO.js → browser-543jbxE4.js} +0 -0
- /package/client/dist/assets/{browser-DhwTc0ry.js → browser-C9rUUxo4.js} +0 -0
- /package/client/dist/assets/{browser-C91MQBxx.js → browser-CEqx11iy.js} +0 -0
- /package/client/dist/assets/{browser-B7i7Ysc8.js → browser-CLC0etB_2.js} +0 -0
- /package/client/dist/assets/{browser-DwE289IS.js → browser-DyG2l9Wa.js} +0 -0
- /package/client/dist/assets/{browser-BVQgd1_1.js → browser-ExmELH702.js} +0 -0
- /package/client/dist/assets/{cameligo-BK_p0bgU.js → cameligo-0MRMdSmg.js} +0 -0
- /package/client/dist/assets/{chat-C5nJF6L0.js → chat-CCytD3P8.js} +0 -0
- /package/client/dist/assets/{chat-UMl6H55K.js → chat-CN8BMAMc.js} +0 -0
- /package/client/dist/assets/{chat-BXVx6rb5.js → chat-Cu6F3d6g2.js} +0 -0
- /package/client/dist/assets/{chat-CE8bx6Rz.js → chat-DagUyoVA.js} +0 -0
- /package/client/dist/assets/{chat-PVakYp92.js → chat-IjutwlBg.js} +0 -0
- /package/client/dist/assets/{chat-9RcD5Lcn.js → chat-NQPCBQo72.js} +0 -0
- /package/client/dist/assets/{chat-BnJPyeUK.js → chat-vVpwkOp52.js} +0 -0
- /package/client/dist/assets/{clojure-BQ7JOykv.js → clojure-B5dKj863.js} +0 -0
- /package/client/dist/assets/{clsx-CjLeUJfG.js → clsx-1dnHRn8W.js} +0 -0
- /package/client/dist/assets/{code-OoLqhjoI.js → code-32l6Naxu2.js} +0 -0
- /package/client/dist/assets/{code-Lg4awa35.js → code-BaG05zK62.js} +0 -0
- /package/client/dist/assets/{code-BPMR8_Vp.js → code-C5cibF2F.js} +0 -0
- /package/client/dist/assets/{code-aCUqkVN_.js → code-Ce-nBIwj.js} +0 -0
- /package/client/dist/assets/{code-BsOBm1Fb.js → code-Dap54vOb.js} +0 -0
- /package/client/dist/assets/{code-u9Sg9ohM.js → code-Dhb6jbAU.js} +0 -0
- /package/client/dist/assets/{code-eh4vO2-_.js → code-_NOCo-Ol2.js} +0 -0
- /package/client/dist/assets/{coffee-BD3DiL5s.js → coffee-DSbWjzk7.js} +0 -0
- /package/client/dist/assets/{common-C9VyfY7g.js → common-0aY9HQBP.js} +0 -0
- /package/client/dist/assets/{common-LDwESeCX.js → common-5jScBJqt.js} +0 -0
- /package/client/dist/assets/{common-ULlk84G4.js → common-BdaRciTu.js} +0 -0
- /package/client/dist/assets/{common-CzCQ0rpW.js → common-CHARW6MZ2.js} +0 -0
- /package/client/dist/assets/{common-CNoRVpnA.js → common-CQCJzAQq2.js} +0 -0
- /package/client/dist/assets/{common-Dmpyh323.js → common-DNhhqjlJ.js} +0 -0
- /package/client/dist/assets/{common-CcHFVATT.js → common-YdyZtmaI2.js} +0 -0
- /package/client/dist/assets/{cpp-splnCwCh.js → cpp-SBF8SAh9.js} +0 -0
- /package/client/dist/assets/{csharp-BCpsl-o3.js → csharp-Lzuq_1t-.js} +0 -0
- /package/client/dist/assets/{csp-tkCWrZmb.js → csp-BEzxZqi1.js} +0 -0
- /package/client/dist/assets/{css-B_xdnReq.js → css-C3D3PKln.js} +0 -0
- /package/client/dist/assets/{cypher-OL1zq-y3.js → cypher-CQ3dEPmv.js} +0 -0
- /package/client/dist/assets/{dart-CtTlOkrm.js → dart-DCPmxolI.js} +0 -0
- /package/client/dist/assets/{dashboard-C52PElPV.js → dashboard-BTiH361F.js} +0 -0
- /package/client/dist/assets/{dashboard-C-dXxut-.js → dashboard-COSm_14E.js} +0 -0
- /package/client/dist/assets/{dashboard-CUjyhohl.js → dashboard-CfOs70FN2.js} +0 -0
- /package/client/dist/assets/{dashboard-zH9quXks.js → dashboard-CzHDp14_2.js} +0 -0
- /package/client/dist/assets/{dashboard-03EpOoMM.js → dashboard-D6Woy2B5.js} +0 -0
- /package/client/dist/assets/{dashboard-C2owt3eN.js → dashboard-DwbH4oVH.js} +0 -0
- /package/client/dist/assets/{dashboard-Ch6H-457.js → dashboard-cWhU3krA2.js} +0 -0
- /package/client/dist/assets/{dockerfile-DcQ5CNiW.js → dockerfile-B_2_aaTO.js} +0 -0
- /package/client/dist/assets/{ecl-DZpiDRt6.js → ecl-rADUeXsV.js} +0 -0
- /package/client/dist/assets/{elixir-Dzj2lqtK.js → elixir-DOd-TuJO.js} +0 -0
- /package/client/dist/assets/{explore-CCcPXrHg.js → explore-B82VMUJ_.js} +0 -0
- /package/client/dist/assets/{explore-DQ0XEjed.js → explore-BGz1rvQE.js} +0 -0
- /package/client/dist/assets/{explore-xQoaak6e.js → explore-BzdMEpuf.js} +0 -0
- /package/client/dist/assets/{explore-B2n8r9Ye.js → explore-CbW0381i2.js} +0 -0
- /package/client/dist/assets/{explore-4SD1DxR0.js → explore-ChtxIiSM.js} +0 -0
- /package/client/dist/assets/{explore-BxR9q8Hq.js → explore-DfcUfiPw2.js} +0 -0
- /package/client/dist/assets/{explore-CZt4Ncpa.js → explore-yRF7wFSp2.js} +0 -0
- /package/client/dist/assets/{flow9-CFENCHIZ.js → flow9-Bf7zg_j0.js} +0 -0
- /package/client/dist/assets/{format-command-CMsBTOPN.js → format-command-D96da4fZ.js} +0 -0
- /package/client/dist/assets/{fsharp-D-4bv7FB.js → fsharp-BqROZjbA.js} +0 -0
- /package/client/dist/assets/{go-djxbTJq7.js → go-oQTP5uLe.js} +0 -0
- /package/client/dist/assets/{graphql-DHIFrkZ6.js → graphql-CSHfTU3q.js} +0 -0
- /package/client/dist/assets/{hcl-CXVoowNb.js → hcl-CeG-RoFJ.js} +0 -0
- /package/client/dist/assets/{ini-Crzc5kly.js → ini-B2Dv4ohc.js} +0 -0
- /package/client/dist/assets/{integrations-C7u7SInG.js → integrations-B0OBPU9_.js} +0 -0
- /package/client/dist/assets/{integrations-B17KyA-i.js → integrations-BA5pM05t.js} +0 -0
- /package/client/dist/assets/{integrations-DkBi-Gsh.js → integrations-BJvrlcc7.js} +0 -0
- /package/client/dist/assets/{integrations-DwSVdCpf.js → integrations-CPKYkG36.js} +0 -0
- /package/client/dist/assets/{integrations-A9f08E0o.js → integrations-CnrX7vqw2.js} +0 -0
- /package/client/dist/assets/{integrations-9qxUNhPD.js → integrations-DBou159M2.js} +0 -0
- /package/client/dist/assets/{integrations-B46ac3sf.js → integrations-DeJFRyXz2.js} +0 -0
- /package/client/dist/assets/{java-CYLaJrdE.js → java-aUDDeufb.js} +0 -0
- /package/client/dist/assets/{jira-Dht8qNck.js → jira-BDgxAFTF2.js} +0 -0
- /package/client/dist/assets/{jira-4Fin3fu7.js → jira-BwLBgmfI2.js} +0 -0
- /package/client/dist/assets/{jira-0ldfMByG.js → jira-D3GGzXOI.js} +0 -0
- /package/client/dist/assets/{jira-BpnpUFlb.js → jira-DeotPx6P2.js} +0 -0
- /package/client/dist/assets/{jira-DzIVvNmy.js → jira-NwlUCcQD.js} +0 -0
- /package/client/dist/assets/{jira-CBU0200d.js → jira-Srx2P5zS.js} +0 -0
- /package/client/dist/assets/{jira-01H1RfQj.js → jira-mi37H4Kt.js} +0 -0
- /package/client/dist/assets/{jobs-jEQidSIb.js → jobs-B56vQEkh2.js} +0 -0
- /package/client/dist/assets/{jobs-DM9owF1j.js → jobs-BYIk6Tg_.js} +0 -0
- /package/client/dist/assets/{jobs-Bw4hqEro.js → jobs-C-lM-iax2.js} +0 -0
- /package/client/dist/assets/{jobs-BF9raUkL.js → jobs-CYdevGgT.js} +0 -0
- /package/client/dist/assets/{jobs-ym72SIR9.js → jobs-D8adm2BX.js} +0 -0
- /package/client/dist/assets/{jobs-DcCONARH.js → jobs-K_Y8KAZ2.js} +0 -0
- /package/client/dist/assets/{jobs-Oz3UtLQn.js → jobs-OwM0ZWhI2.js} +0 -0
- /package/client/dist/assets/{julia-BJ7tUU-T.js → julia-C5LbruO5.js} +0 -0
- /package/client/dist/assets/{kotlin-CeWcU3lC.js → kotlin-C6mOuSKk.js} +0 -0
- /package/client/dist/assets/{less-CviwWNG4.js → less-D5qC3caW.js} +0 -0
- /package/client/dist/assets/{lexon-Dt28jqDS.js → lexon-Dr2La-fj.js} +0 -0
- /package/client/dist/assets/{loops-DE-2cmLw.js → loops-BDhEfnx82.js} +0 -0
- /package/client/dist/assets/{loops-mcoeFMat.js → loops-BM5QggwH.js} +0 -0
- /package/client/dist/assets/{loops-D_ZxkD4l.js → loops-CPjLAAxj.js} +0 -0
- /package/client/dist/assets/{loops-BYNUJVyD.js → loops-DKnk79TB2.js} +0 -0
- /package/client/dist/assets/{loops-B_gS4Pqu.js → loops-DLW0aFMm.js} +0 -0
- /package/client/dist/assets/{loops-Fv4Bs-9A.js → loops-Dcv3dFy_2.js} +0 -0
- /package/client/dist/assets/{loops-B_w7STrw.js → loops-y7wFRx6M.js} +0 -0
- /package/client/dist/assets/{lua-B6AOaJSi.js → lua-Zy6u5z6Z.js} +0 -0
- /package/client/dist/assets/{m3-VnMkHJcy.js → m3-C7XHeDz_.js} +0 -0
- /package/client/dist/assets/{markdown-8vKNdvIM.js → markdown-PiF7r-2h.js} +0 -0
- /package/client/dist/assets/{mips-DoEcuzan.js → mips-nn07GiyE.js} +0 -0
- /package/client/dist/assets/{msdax-CNzvHyEp.js → msdax-DaKFVMST.js} +0 -0
- /package/client/dist/assets/{mysql-Buk3vUtL.js → mysql-C6d6xrbU.js} +0 -0
- /package/client/dist/assets/{nav-Cw3_40fA.js → nav-1hj2izqB2.js} +0 -0
- /package/client/dist/assets/{nav-DNDJ3H-_.js → nav-BBUKMAu-2.js} +0 -0
- /package/client/dist/assets/{nav-CrG_mYRr.js → nav-CLqkP-26.js} +0 -0
- /package/client/dist/assets/{nav-DVp1nEsi.js → nav-Cv46L837.js} +0 -0
- /package/client/dist/assets/{nav-DbAbG5_k.js → nav-DgA-rjLk2.js} +0 -0
- /package/client/dist/assets/{nav-B5W9IMnf.js → nav-EG2pr6vN.js} +0 -0
- /package/client/dist/assets/{nav-_0vAgZ_k.js → nav-r3mIJVfU.js} +0 -0
- /package/client/dist/assets/{objective-c-DfOmda-5.js → objective-c-B6KMtI-k.js} +0 -0
- /package/client/dist/assets/{pascal-DoAA2yjy.js → pascal-DYr8MPE7.js} +0 -0
- /package/client/dist/assets/{pascaligo-C65Vn1fu.js → pascaligo-B3pd-jJ_.js} +0 -0
- /package/client/dist/assets/{perl-INlfQ_ro.js → perl-z2xUzoaL.js} +0 -0
- /package/client/dist/assets/{pgsql-DtwRzglx.js → pgsql-DUvT-09-.js} +0 -0
- /package/client/dist/assets/{php-DfHqVNet.js → php-CGyOmJfy.js} +0 -0
- /package/client/dist/assets/{pla-D3dNVRYk.js → pla-CMqgvyD0.js} +0 -0
- /package/client/dist/assets/{postiats-UKXD1rM4.js → postiats-Dx5LUn4Z.js} +0 -0
- /package/client/dist/assets/{powerquery-zE3E3O7s.js → powerquery-DazYxvJ6.js} +0 -0
- /package/client/dist/assets/{powershell-Df9b3zQl.js → powershell-B3nwlDka.js} +0 -0
- /package/client/dist/assets/{protobuf-BF0nUVrW.js → protobuf-BGuu2u2s.js} +0 -0
- /package/client/dist/assets/{pug-Bj6Yikv_.js → pug-Dbte1MXA.js} +0 -0
- /package/client/dist/assets/{qsharp-BI4h-raZ.js → qsharp-DJLwBOvG.js} +0 -0
- /package/client/dist/assets/{r-DhpnmaXx.js → r-DmGBRSHj.js} +0 -0
- /package/client/dist/assets/{redis-DwYYPr4d.js → redis-VvUYn0a4.js} +0 -0
- /package/client/dist/assets/{redshift-D2f3Bc-4.js → redshift-6GdDrxg3.js} +0 -0
- /package/client/dist/assets/{restructuredtext-Dkiif6fe.js → restructuredtext-CfAB8aRU.js} +0 -0
- /package/client/dist/assets/{ruby-C6hLmHy0.js → ruby-CIYK6MXY.js} +0 -0
- /package/client/dist/assets/{rust-X8WAGtxB.js → rust-CTHZfjj9.js} +0 -0
- /package/client/dist/assets/{sb-4M2la0Kr.js → sb-CkKTdkz_.js} +0 -0
- /package/client/dist/assets/{scala-CaCXz58E.js → scala-Bx-Wr9TM.js} +0 -0
- /package/client/dist/assets/{scheme-CMdjpmP7.js → scheme-Dcfi6f83.js} +0 -0
- /package/client/dist/assets/{scss-QopmvPyp.js → scss-ByL-7PFQ.js} +0 -0
- /package/client/dist/assets/{shell-CDBchS00.js → shell-Csnb9Yqd.js} +0 -0
- /package/client/dist/assets/{solidity-DvBfi5mC.js → solidity-Dbw5-0QP.js} +0 -0
- /package/client/dist/assets/{sophia-HSnXR17u.js → sophia-ZQ3saZQx.js} +0 -0
- /package/client/dist/assets/{sparql-DhG_ppup.js → sparql-BEtOel8u.js} +0 -0
- /package/client/dist/assets/{specs-CUE3xSFM.js → specs-B5XOoH-02.js} +0 -0
- /package/client/dist/assets/{specs-C2wW5bq8.js → specs-B8mwScoM2.js} +0 -0
- /package/client/dist/assets/{specs-Bku8SypT.js → specs-Bj_3fDrQ.js} +0 -0
- /package/client/dist/assets/{specs-CnH7dOiF.js → specs-CWNKAScX2.js} +0 -0
- /package/client/dist/assets/{specs-BvsFNKTs.js → specs-D4z5d8uq.js} +0 -0
- /package/client/dist/assets/{specs-D4ORogcT.js → specs-DgvIRZtM.js} +0 -0
- /package/client/dist/assets/{specs-D6Y76Bgi.js → specs-DuRzE5wE.js} +0 -0
- /package/client/dist/assets/{sql-DHeIS-tf.js → sql-DGPDbzB7.js} +0 -0
- /package/client/dist/assets/{st-CMWchiRU.js → st-GeW2MOgh.js} +0 -0
- /package/client/dist/assets/{swift-CDXvBefj.js → swift-BVYTN8jq.js} +0 -0
- /package/client/dist/assets/{systemverilog-0RTukYUE.js → systemverilog-Deg2a8Lr.js} +0 -0
- /package/client/dist/assets/{tcl-CbBF_Ttl.js → tcl-6DnLmROF.js} +0 -0
- /package/client/dist/assets/{terminal-BLh00ouM.js → terminal-B2sExUis.js} +0 -0
- /package/client/dist/assets/{terminal-Cz_Puz0q.js → terminal-CH0fdHvP.js} +0 -0
- /package/client/dist/assets/{terminal-DFEH9XTQ.js → terminal-CPMigUX7.js} +0 -0
- /package/client/dist/assets/{terminal-CB33IsO1.js → terminal-DOwfkxqa2.js} +0 -0
- /package/client/dist/assets/{terminal-CR6t-Oey.js → terminal-DjSSa5qP.js} +0 -0
- /package/client/dist/assets/{terminal-CY_sPfdD.js → terminal-DoMTHedv2.js} +0 -0
- /package/client/dist/assets/{terminal-BTanJIt_.js → terminal-w0i-OCp32.js} +0 -0
- /package/client/dist/assets/{tickets-D6f3GSYn.js → tickets-CQTana1u.js} +0 -0
- /package/client/dist/assets/{tickets-blQnNA4N.js → tickets-D00mSt832.js} +0 -0
- /package/client/dist/assets/{tickets-68LH1xp6.js → tickets-D7CSuWjO.js} +0 -0
- /package/client/dist/assets/{tickets-OrJwUxJR.js → tickets-Dq7HDy8n.js} +0 -0
- /package/client/dist/assets/{tickets-PtHNxQo5.js → tickets-DvbFg_-c2.js} +0 -0
- /package/client/dist/assets/{tickets-REr-EQx9.js → tickets-heDAaj8C2.js} +0 -0
- /package/client/dist/assets/{tickets-jxsTrApR.js → tickets-onKZz6Dd.js} +0 -0
- /package/client/dist/assets/{twig-DCcGd8FE.js → twig-XbbXW9Yz.js} +0 -0
- /package/client/dist/assets/{typespec-HTphp-Uh.js → typespec-CRlV8GhI.js} +0 -0
- /package/client/dist/assets/{vb-Cb_yUcVd.js → vb-BHE2izPH.js} +0 -0
- /package/client/dist/assets/{wgsl-DrKU3YXj.js → wgsl-Bf5vkfmY.js} +0 -0
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loopsTools = loopsTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
/**
|
|
7
|
+
* Loops — the GLOBAL (cross-project) visual loop-builder library. Routes live at
|
|
8
|
+
* `/api/loops*` and `/api/loop-templates` (NOT under `/projects` — no projectId).
|
|
9
|
+
* Gated server-side by SPECRAILS_LOOPS_SECTION (every route 404s when off).
|
|
10
|
+
*
|
|
11
|
+
* A single domain-facade tool with an `action` enum and a dynamic tier:
|
|
12
|
+
* - read: list, get, templates, factory, commands, constants_list, preview
|
|
13
|
+
* - write: constant_create, constant_update, import, create, from_template,
|
|
14
|
+
* fork, update, publish, unpublish, duplicate
|
|
15
|
+
* - destructive: constant_delete, delete
|
|
16
|
+
*/
|
|
17
|
+
function loopsTools() {
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
name: 'specrails_loops',
|
|
21
|
+
title: 'Loops',
|
|
22
|
+
description: 'Manage the global (cross-project) loop library and its templates/factory/constants. ' +
|
|
23
|
+
'Loops are visual builder graphs reused across projects; this is an APP-LEVEL domain (no projectId). ' +
|
|
24
|
+
'Actions: ' +
|
|
25
|
+
'list (all saved loops), ' +
|
|
26
|
+
'get (one loop by id), ' +
|
|
27
|
+
'templates (built-in template catalog with graphs), ' +
|
|
28
|
+
'factory (built-in locked factory loops), ' +
|
|
29
|
+
'commands (magic-command catalog for the builder palette), ' +
|
|
30
|
+
'constants_list (global cross-loop constants), ' +
|
|
31
|
+
'constant_create (write), constant_update (write), constant_delete (destructive), ' +
|
|
32
|
+
'preview (dry-run resolve tokens of a graph — no spawn), ' +
|
|
33
|
+
'import (import loops from an export envelope), ' +
|
|
34
|
+
'create (new Draft loop), ' +
|
|
35
|
+
'from_template (instantiate from a template), ' +
|
|
36
|
+
'fork (fork a factory loop into an editable Draft), ' +
|
|
37
|
+
'update (name/description/graph — reverts to Draft, 409 while running), ' +
|
|
38
|
+
'publish (graph-validated), unpublish (409 while running), ' +
|
|
39
|
+
'duplicate (copy a loop), ' +
|
|
40
|
+
'delete (destructive — 409 while running).',
|
|
41
|
+
hintTier: 'read',
|
|
42
|
+
tier: (a) => {
|
|
43
|
+
const action = a.action;
|
|
44
|
+
if (action === 'delete' || action === 'constant_delete')
|
|
45
|
+
return 'destructive';
|
|
46
|
+
if ([
|
|
47
|
+
'constant_create',
|
|
48
|
+
'constant_update',
|
|
49
|
+
'import',
|
|
50
|
+
'create',
|
|
51
|
+
'from_template',
|
|
52
|
+
'fork',
|
|
53
|
+
'update',
|
|
54
|
+
'publish',
|
|
55
|
+
'unpublish',
|
|
56
|
+
'duplicate',
|
|
57
|
+
].includes(action)) {
|
|
58
|
+
return 'write';
|
|
59
|
+
}
|
|
60
|
+
return 'read';
|
|
61
|
+
},
|
|
62
|
+
inputSchema: {
|
|
63
|
+
action: zod_1.z
|
|
64
|
+
.enum([
|
|
65
|
+
'list',
|
|
66
|
+
'get',
|
|
67
|
+
'templates',
|
|
68
|
+
'factory',
|
|
69
|
+
'commands',
|
|
70
|
+
'constants_list',
|
|
71
|
+
'constant_create',
|
|
72
|
+
'constant_update',
|
|
73
|
+
'constant_delete',
|
|
74
|
+
'preview',
|
|
75
|
+
'import',
|
|
76
|
+
'create',
|
|
77
|
+
'from_template',
|
|
78
|
+
'fork',
|
|
79
|
+
'update',
|
|
80
|
+
'publish',
|
|
81
|
+
'unpublish',
|
|
82
|
+
'duplicate',
|
|
83
|
+
'delete',
|
|
84
|
+
])
|
|
85
|
+
.describe('Operation to perform'),
|
|
86
|
+
loopId: zod_1.z.string().optional().describe('Loop id (for get / update / publish / unpublish / duplicate / delete)'),
|
|
87
|
+
constantId: zod_1.z.string().optional().describe('Constant id (for constant_update / constant_delete)'),
|
|
88
|
+
templateId: zod_1.z.string().optional().describe('Template id (for from_template)'),
|
|
89
|
+
factoryId: zod_1.z.string().optional().describe('Factory loop id (for fork)'),
|
|
90
|
+
name: zod_1.z
|
|
91
|
+
.string()
|
|
92
|
+
.optional()
|
|
93
|
+
.describe('Loop or constant name (required for create / constant_create; optional override for from_template / fork / duplicate / update)'),
|
|
94
|
+
description: zod_1.z.string().optional().describe('Loop description (for create / update)'),
|
|
95
|
+
graph: zod_1.z
|
|
96
|
+
.record(zod_1.z.unknown())
|
|
97
|
+
.optional()
|
|
98
|
+
.describe('Loop graph object { nodes, edges, ... } (for create / update; required for preview)'),
|
|
99
|
+
value: zod_1.z.string().optional().describe('Constant value (for constant_create / constant_update)'),
|
|
100
|
+
provider: zod_1.z.string().optional().describe('Provider for token resolution in preview (default "claude")'),
|
|
101
|
+
loops: zod_1.z.array(zod_1.z.unknown()).optional().describe('Array of loop export envelopes (for import)'),
|
|
102
|
+
},
|
|
103
|
+
async handler(ctx, args) {
|
|
104
|
+
const action = args.action;
|
|
105
|
+
const loopId = args.loopId;
|
|
106
|
+
const constantId = args.constantId;
|
|
107
|
+
switch (action) {
|
|
108
|
+
// ── Reads ──────────────────────────────────────────────────────────
|
|
109
|
+
case 'list':
|
|
110
|
+
return (0, types_1.apiCall)(ctx, 'GET', '/loops');
|
|
111
|
+
case 'get': {
|
|
112
|
+
if (!loopId)
|
|
113
|
+
throw new Error('get requires a "loopId".');
|
|
114
|
+
return (0, types_1.apiCall)(ctx, 'GET', `/loops/${encodeURIComponent(loopId)}`);
|
|
115
|
+
}
|
|
116
|
+
case 'templates':
|
|
117
|
+
return (0, types_1.apiCall)(ctx, 'GET', '/loop-templates');
|
|
118
|
+
case 'factory':
|
|
119
|
+
return (0, types_1.apiCall)(ctx, 'GET', '/loops/factory');
|
|
120
|
+
case 'commands':
|
|
121
|
+
return (0, types_1.apiCall)(ctx, 'GET', '/loops/commands');
|
|
122
|
+
case 'constants_list':
|
|
123
|
+
return (0, types_1.apiCall)(ctx, 'GET', '/loops/constants');
|
|
124
|
+
case 'preview': {
|
|
125
|
+
const graph = args.graph;
|
|
126
|
+
if (!graph)
|
|
127
|
+
throw new Error('preview requires a "graph".');
|
|
128
|
+
return (0, types_1.apiCall)(ctx, 'POST', '/loops/preview', {
|
|
129
|
+
graph,
|
|
130
|
+
...(args.provider !== undefined ? { provider: args.provider } : {}),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// ── Constants (write / destructive) ─────────────────────────────────
|
|
134
|
+
case 'constant_create': {
|
|
135
|
+
const name = args.name;
|
|
136
|
+
if (!name)
|
|
137
|
+
throw new Error('constant_create requires a "name".');
|
|
138
|
+
return (0, types_1.apiCall)(ctx, 'POST', '/loops/constants', {
|
|
139
|
+
name,
|
|
140
|
+
value: args.value ?? '',
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
case 'constant_update': {
|
|
144
|
+
if (!constantId)
|
|
145
|
+
throw new Error('constant_update requires a "constantId".');
|
|
146
|
+
return (0, types_1.apiCall)(ctx, 'PUT', `/loops/constants/${encodeURIComponent(constantId)}`, {
|
|
147
|
+
value: args.value ?? '',
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
case 'constant_delete': {
|
|
151
|
+
if (!constantId)
|
|
152
|
+
throw new Error('constant_delete requires a "constantId".');
|
|
153
|
+
return (0, types_1.apiCall)(ctx, 'DELETE', `/loops/constants/${encodeURIComponent(constantId)}`);
|
|
154
|
+
}
|
|
155
|
+
// ── Loops (write) ───────────────────────────────────────────────────
|
|
156
|
+
case 'import': {
|
|
157
|
+
const loops = args.loops;
|
|
158
|
+
if (!Array.isArray(loops))
|
|
159
|
+
throw new Error('import requires a "loops" array.');
|
|
160
|
+
return (0, types_1.apiCall)(ctx, 'POST', '/loops/import', { loops });
|
|
161
|
+
}
|
|
162
|
+
case 'create': {
|
|
163
|
+
const name = args.name;
|
|
164
|
+
if (!name)
|
|
165
|
+
throw new Error('create requires a "name".');
|
|
166
|
+
return (0, types_1.apiCall)(ctx, 'POST', '/loops', {
|
|
167
|
+
name,
|
|
168
|
+
...(args.description !== undefined ? { description: args.description } : {}),
|
|
169
|
+
...(args.graph !== undefined ? { graph: args.graph } : {}),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
case 'from_template': {
|
|
173
|
+
const templateId = args.templateId;
|
|
174
|
+
if (!templateId)
|
|
175
|
+
throw new Error('from_template requires a "templateId".');
|
|
176
|
+
return (0, types_1.apiCall)(ctx, 'POST', `/loops/from-template/${encodeURIComponent(templateId)}`, {
|
|
177
|
+
...(args.name !== undefined ? { name: args.name } : {}),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
case 'fork': {
|
|
181
|
+
const factoryId = args.factoryId;
|
|
182
|
+
if (!factoryId)
|
|
183
|
+
throw new Error('fork requires a "factoryId".');
|
|
184
|
+
return (0, types_1.apiCall)(ctx, 'POST', `/loops/factory/${encodeURIComponent(factoryId)}/fork`, {
|
|
185
|
+
...(args.name !== undefined ? { name: args.name } : {}),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
case 'update': {
|
|
189
|
+
if (!loopId)
|
|
190
|
+
throw new Error('update requires a "loopId".');
|
|
191
|
+
const body = {};
|
|
192
|
+
if (args.name !== undefined)
|
|
193
|
+
body.name = args.name;
|
|
194
|
+
if (args.description !== undefined)
|
|
195
|
+
body.description = args.description;
|
|
196
|
+
if (args.graph !== undefined)
|
|
197
|
+
body.graph = args.graph;
|
|
198
|
+
return (0, types_1.apiCall)(ctx, 'PUT', `/loops/${encodeURIComponent(loopId)}`, body);
|
|
199
|
+
}
|
|
200
|
+
case 'publish': {
|
|
201
|
+
if (!loopId)
|
|
202
|
+
throw new Error('publish requires a "loopId".');
|
|
203
|
+
return (0, types_1.apiCall)(ctx, 'POST', `/loops/${encodeURIComponent(loopId)}/publish`);
|
|
204
|
+
}
|
|
205
|
+
case 'unpublish': {
|
|
206
|
+
if (!loopId)
|
|
207
|
+
throw new Error('unpublish requires a "loopId".');
|
|
208
|
+
return (0, types_1.apiCall)(ctx, 'POST', `/loops/${encodeURIComponent(loopId)}/unpublish`);
|
|
209
|
+
}
|
|
210
|
+
case 'duplicate': {
|
|
211
|
+
if (!loopId)
|
|
212
|
+
throw new Error('duplicate requires a "loopId".');
|
|
213
|
+
return (0, types_1.apiCall)(ctx, 'POST', `/loops/${encodeURIComponent(loopId)}/duplicate`, {
|
|
214
|
+
...(args.name !== undefined ? { name: args.name } : {}),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
// ── Destructive ─────────────────────────────────────────────────────
|
|
218
|
+
case 'delete': {
|
|
219
|
+
if (!loopId)
|
|
220
|
+
throw new Error('delete requires a "loopId".');
|
|
221
|
+
return (0, types_1.apiCall)(ctx, 'DELETE', `/loops/${encodeURIComponent(loopId)}`);
|
|
222
|
+
}
|
|
223
|
+
default:
|
|
224
|
+
throw new Error(`Unknown action "${action}".`);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
];
|
|
229
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.metaTools = metaTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const guide_1 = require("../guide");
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
/**
|
|
8
|
+
* Meta tools that teach the platform and aid discovery.
|
|
9
|
+
* `getSpecs` returns the full catalog (passed lazily to avoid a cycle).
|
|
10
|
+
*/
|
|
11
|
+
function metaTools(getSpecs) {
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
name: 'specrails_guide',
|
|
15
|
+
title: 'Platform guide',
|
|
16
|
+
description: 'Returns a self-contained guide to Specrails: concepts, workflow, invariants, and how to use these tools. Read this first.',
|
|
17
|
+
tier: 'read',
|
|
18
|
+
inputSchema: {},
|
|
19
|
+
handler: () => guide_1.SPECRAILS_GUIDE,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'specrails_search',
|
|
23
|
+
title: 'Search tools',
|
|
24
|
+
description: 'Find the right Specrails tool/action for an intent. Returns matching tools with their descriptions.',
|
|
25
|
+
tier: 'read',
|
|
26
|
+
inputSchema: {
|
|
27
|
+
query: zod_1.z.string().describe('Natural-language intent, e.g. "launch the pipeline for a ticket"'),
|
|
28
|
+
},
|
|
29
|
+
handler: (_ctx, args) => {
|
|
30
|
+
const q = String(args.query ?? '').toLowerCase().trim();
|
|
31
|
+
const terms = q.split(/\s+/).filter(Boolean);
|
|
32
|
+
const scored = getSpecs()
|
|
33
|
+
.filter((s) => s.name !== 'specrails_search')
|
|
34
|
+
.map((s) => {
|
|
35
|
+
const hay = `${s.name} ${s.title} ${s.description}`.toLowerCase();
|
|
36
|
+
const score = terms.reduce((acc, t) => acc + (hay.includes(t) ? 1 : 0), 0);
|
|
37
|
+
return { name: s.name, title: s.title, description: s.description, score };
|
|
38
|
+
})
|
|
39
|
+
.filter((r) => r.score > 0)
|
|
40
|
+
.sort((a, b) => b.score - a.score)
|
|
41
|
+
.slice(0, 8);
|
|
42
|
+
return scored.length ? scored : { hint: 'No direct match. Call specrails_guide for an overview, or list all tools.' };
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'specrails_describe',
|
|
47
|
+
title: 'Describe a tool',
|
|
48
|
+
description: 'Return the full description and input schema summary for a named Specrails tool.',
|
|
49
|
+
tier: 'read',
|
|
50
|
+
inputSchema: {
|
|
51
|
+
name: zod_1.z.string().describe('Tool name, e.g. "specrails_rails"'),
|
|
52
|
+
},
|
|
53
|
+
handler: (_ctx, args) => {
|
|
54
|
+
const name = String(args.name ?? '');
|
|
55
|
+
const spec = getSpecs().find((s) => s.name === name);
|
|
56
|
+
if (!spec)
|
|
57
|
+
throw new Error(`Unknown tool "${name}". Use specrails_search to find one.`);
|
|
58
|
+
return {
|
|
59
|
+
name: spec.name,
|
|
60
|
+
title: spec.title,
|
|
61
|
+
description: spec.description,
|
|
62
|
+
inputFields: Object.keys(spec.inputSchema),
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'specrails_select_project',
|
|
68
|
+
title: 'Select active project',
|
|
69
|
+
description: 'Set the active project so subsequent per-project tools may omit projectId. Pass an id or a path. Pass null to clear.',
|
|
70
|
+
tier: 'read',
|
|
71
|
+
inputSchema: {
|
|
72
|
+
projectId: zod_1.z.string().nullable().optional().describe('Project id to make active, or null to clear'),
|
|
73
|
+
path: zod_1.z.string().optional().describe('Resolve+select a project by filesystem path instead of id'),
|
|
74
|
+
},
|
|
75
|
+
handler: (ctx, args) => {
|
|
76
|
+
if (args.path) {
|
|
77
|
+
const pc = ctx.registry.getContextByPath(String(args.path));
|
|
78
|
+
if (!pc)
|
|
79
|
+
throw new Error(`No project registered at path "${args.path}".`);
|
|
80
|
+
(0, types_1.setActiveProject)(pc.project.id);
|
|
81
|
+
return { active: pc.project.id, name: pc.project.name };
|
|
82
|
+
}
|
|
83
|
+
if (args.projectId === null) {
|
|
84
|
+
(0, types_1.setActiveProject)(null);
|
|
85
|
+
return { active: null };
|
|
86
|
+
}
|
|
87
|
+
const id = args.projectId;
|
|
88
|
+
if (!id)
|
|
89
|
+
throw new Error('Provide a projectId, a path, or null.');
|
|
90
|
+
const pc = (0, types_1.requireProject)(ctx, id);
|
|
91
|
+
(0, types_1.setActiveProject)(pc.project.id);
|
|
92
|
+
return { active: pc.project.id, name: pc.project.name };
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
}
|