specrails-desktop 2.12.0 → 2.13.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/README.md +3 -2
- package/client/dist/assets/ActivityFeedPage-D0-P3PsD.js +1 -0
- package/client/dist/assets/AgentsPage-BZa3lhQM.js +86 -0
- package/client/dist/assets/AnalyticsPage-CgaEg-lx.js +1 -0
- package/client/dist/assets/BarChart-D9vfeilz.js +33 -0
- package/client/dist/assets/CodePage-2GUsF_JS.js +2 -0
- package/client/dist/assets/DesktopAnalyticsPage-C6Qccm5E.js +1 -0
- package/client/dist/assets/DocsDialog-BAmtk9Jc.js +11 -0
- package/client/dist/assets/DocsPage-CJwnpB57.js +11 -0
- package/client/dist/assets/{ExportDropdown-I_8R48Yq.js → ExportDropdown-DMJ__Yui.js} +1 -1
- package/client/dist/assets/IntegrationsPage-CP2VcOpr.js +3 -0
- package/client/dist/assets/JobDetailPage-Bk6tQTew.js +16 -0
- package/client/dist/assets/JobsPage-BvbeqWjS.js +1 -0
- package/client/dist/assets/LoopBuilderPage-BS3enu9N.js +7 -0
- package/client/dist/assets/LoopBuilderPage-DtxX27Jz.css +1 -0
- package/client/dist/assets/LoopsPage-B0pgvoky.js +2 -0
- package/client/dist/assets/analytics-BHApBnUn.js +1 -0
- package/client/dist/assets/analytics-BUxrug9J.js +1 -0
- package/client/dist/assets/analytics-Cy6DTfO-.js +1 -0
- package/client/dist/assets/analytics-DMJxD9FD.js +1 -0
- package/client/dist/assets/analytics-DgrBuxla.js +1 -0
- package/client/dist/assets/analytics-DwxT1CS8.js +1 -0
- package/client/dist/assets/analytics-GrLc-SMr.js +1 -0
- package/client/dist/assets/analytics-qvPq4T4h.js +1 -0
- package/client/dist/assets/atom-one-dark-DrWoEEbZ.js +1 -0
- package/client/dist/assets/auth-Cvsb7-Ek.js +1 -0
- package/client/dist/assets/{cssMode-DzNPAYFh.js → cssMode-DSHXamUH.js} +1 -1
- package/client/dist/assets/dashboard-8FSyxKGV.js +1 -0
- package/client/dist/assets/dashboard-A9XQUfdS.js +1 -0
- package/client/dist/assets/dashboard-BFktSDsV.js +1 -0
- package/client/dist/assets/dashboard-C1PKCXLs.js +1 -0
- package/client/dist/assets/dashboard-DNf0czU-.js +1 -0
- package/client/dist/assets/dashboard-DQQCOVfu.js +1 -0
- package/client/dist/assets/dashboard-DxFqeHZk.js +1 -0
- package/client/dist/assets/dashboard-WvPGhbbi.js +1 -0
- package/client/dist/assets/{dist-js-DXfIbU9U.js → dist-js-_oLAsZQ4.js} +1 -1
- package/client/dist/assets/{dist-js-CtdZvl0R.js → dist-js-o4iwbCuN.js} +1 -1
- package/client/dist/assets/{editor.main-C7Rmw-hR.js → editor.main-Cd8qBRAT.js} +2 -2
- package/client/dist/assets/{freemarker2-Cszs4SVo.js → freemarker2-CkEKTBm2.js} +1 -1
- package/client/dist/assets/{handlebars-Dp7Lsuym.js → handlebars-BRGx0JpL.js} +1 -1
- package/client/dist/assets/{html-BURidrEm.js → html-BfRIaGgN.js} +1 -1
- package/client/dist/assets/{htmlMode--k5M7GjZ.js → htmlMode-BTpSnsDE.js} +1 -1
- package/client/dist/assets/index-DrFJinsI.css +2 -0
- package/client/dist/assets/index-QEeqwz4v.js +143 -0
- package/client/dist/assets/{javascript-kJQz__44.js → javascript-DMmE2kKN.js} +1 -1
- package/client/dist/assets/{jsonMode-v5JYPpnz.js → jsonMode-hYuaUleY.js} +1 -1
- package/client/dist/assets/{lib-BBoUS-5a.js → lib-CVrpo1ac.js} +2 -2
- package/client/dist/assets/{liquid-Dl9I6gWt.js → liquid-C-VbuTr7.js} +1 -1
- package/client/dist/assets/loops-B1ZQCKEk.js +1 -0
- package/client/dist/assets/loops-Bp5yTSic.js +1 -0
- package/client/dist/assets/loops-BvoL_LAc.js +1 -0
- package/client/dist/assets/loops-BwgehdXY.js +1 -0
- package/client/dist/assets/loops-CMLUqUpc.js +1 -0
- package/client/dist/assets/loops-CW69VvTI.js +1 -0
- package/client/dist/assets/loops-DkV2RhEb.js +1 -0
- package/client/dist/assets/loops-arQ602Zm.js +1 -0
- package/client/dist/assets/{lspLanguageFeatures-CPlEe0NK.js → lspLanguageFeatures-BALx-vjn.js} +1 -1
- package/client/dist/assets/{mdx-Byl7TtzQ.js → mdx-Cs8MNCzn.js} +1 -1
- package/client/dist/assets/{monaco.contribution-YMAkHQcQ.js → monaco.contribution-CIvCAJs4.js} +2 -2
- package/client/dist/assets/nav-B5W9IMnf.js +1 -0
- package/client/dist/assets/nav-CCz4krPP.js +1 -0
- package/client/dist/assets/nav-CrG_mYRr.js +1 -0
- package/client/dist/assets/nav-Cw3_40fA.js +1 -0
- package/client/dist/assets/nav-DNDJ3H-_.js +1 -0
- package/client/dist/assets/nav-DVp1nEsi.js +1 -0
- package/client/dist/assets/nav-DbAbG5_k.js +1 -0
- package/client/dist/assets/nav-_0vAgZ_k.js +1 -0
- package/client/dist/assets/{python-jWQwT6j2.js → python-CGShLxuI.js} +1 -1
- package/client/dist/assets/{razor-BWS3sP-E.js → razor-CvOBQGd5.js} +1 -1
- package/client/dist/assets/{setup-Cpu17hJv.js → setup-BOmQ4vh2.js} +1 -1
- package/client/dist/assets/setup-BwO2-kuK.js +1 -0
- package/client/dist/assets/{setup-D-1r0uSx.js → setup-CUTNWz-0.js} +1 -1
- package/client/dist/assets/{setup-BHroXlke.js → setup-Cf3hjChU.js} +1 -1
- package/client/dist/assets/{setup-BIXsWUp1.js → setup-CsuXrbJ2.js} +1 -1
- package/client/dist/assets/{setup-B6egeeTM.js → setup-Df4cJOqu.js} +1 -1
- package/client/dist/assets/{setup-C0rVGnCy.js → setup-Do0fWx6W.js} +1 -1
- package/client/dist/assets/{setup-BJRdg1iE.js → setup-GlkDhBlJ.js} +1 -1
- package/client/dist/assets/{tsMode-BbOGOuSV.js → tsMode-04uOpiiP.js} +1 -1
- package/client/dist/assets/{typescript-eBtFQJLs.js → typescript-CX0CwyIZ.js} +1 -1
- package/client/dist/assets/upload-Dn9N1ESQ.js +1 -0
- package/client/dist/assets/value-Bd3Cf9Sr.js +1 -0
- package/client/dist/assets/{workers-BvicOoDf.js → workers-yr2u4c3C.js} +1 -1
- package/client/dist/assets/{xml-BJepAPyM.js → xml-C0OFlt5X.js} +1 -1
- package/client/dist/assets/{yaml-DabgV-eA.js → yaml-DgabaPs5.js} +1 -1
- package/client/dist/index.html +28 -26
- package/docs/getting-started.md +3 -2
- package/docs/guide/de/pipeline/1-rails-and-jobs.md +27 -22
- package/docs/guide/de/pipeline/5-the-loop-builder.md +91 -0
- package/docs/guide/en/pipeline/1-rails-and-jobs.md +11 -6
- package/docs/guide/en/pipeline/5-the-loop-builder.md +91 -0
- package/docs/guide/es/pipeline/1-rails-and-jobs.md +11 -6
- package/docs/guide/es/pipeline/5-the-loop-builder.md +91 -0
- package/docs/guide/fr/pipeline/1-rails-and-jobs.md +40 -35
- package/docs/guide/fr/pipeline/5-the-loop-builder.md +91 -0
- package/docs/guide/it/pipeline/1-rails-and-jobs.md +11 -6
- package/docs/guide/it/pipeline/5-the-loop-builder.md +91 -0
- package/docs/guide/ja/pipeline/1-rails-and-jobs.md +11 -6
- package/docs/guide/ja/pipeline/5-the-loop-builder.md +91 -0
- package/docs/guide/pt/pipeline/1-rails-and-jobs.md +50 -45
- package/docs/guide/pt/pipeline/5-the-loop-builder.md +91 -0
- package/docs/guide/zh/pipeline/1-rails-and-jobs.md +13 -8
- package/docs/guide/zh/pipeline/5-the-loop-builder.md +91 -0
- package/docs/internals/companion-rails-as-loops-contract.md +199 -0
- package/docs/internals/global-artifacts-alignment-contract.md +2 -0
- package/docs/running-pipelines.md +25 -14
- package/package.json +1 -1
- package/server/dist/ai-invocations.js +5 -3
- package/server/dist/db.js +45 -0
- package/server/dist/desktop-db.js +48 -0
- package/server/dist/desktop-router.js +10 -0
- package/server/dist/feature-flags.js +13 -0
- package/server/dist/loop-command-catalog.js +145 -0
- package/server/dist/loop-constants.js +82 -0
- package/server/dist/loop-decider.js +66 -0
- package/server/dist/loop-executors.js +193 -0
- package/server/dist/loop-factory.js +56 -0
- package/server/dist/loop-graph.js +144 -0
- package/server/dist/loop-preview.js +69 -0
- package/server/dist/loop-run-manager.js +407 -0
- package/server/dist/loop-runs-store.js +69 -0
- package/server/dist/loop-templates.js +137 -0
- package/server/dist/loops-router.js +302 -0
- package/server/dist/loops-store.js +137 -0
- package/server/dist/mobile/mobile-router.js +22 -0
- package/server/dist/mobile/mobile-ws.js +17 -1
- package/server/dist/project-registry.js +103 -1
- package/server/dist/project-router-jobs.js +11 -1
- package/server/dist/project-router-loop-runs.js +102 -0
- package/server/dist/project-router.js +2 -0
- package/server/dist/providers/claude-adapter.js +4 -0
- package/server/dist/providers/codex-adapter.js +21 -0
- package/server/dist/providers/gemini-adapter.js +4 -0
- package/server/dist/rails-router.js +175 -6
- package/server/dist/spending.js +5 -2
- package/server/dist/util/cli-prompt.js +6 -3
- package/client/dist/assets/ActivityFeedPage-B9-UAGS7.js +0 -1
- package/client/dist/assets/AgentsPage-Bz9rophT.js +0 -86
- package/client/dist/assets/AnalyticsPage-D3ynQwGd.js +0 -1
- package/client/dist/assets/BarChart-Cwp6VuED.js +0 -33
- package/client/dist/assets/CodePage-CO_TLOvi.js +0 -2
- package/client/dist/assets/DesktopAnalyticsPage-BMDqiAbw.js +0 -1
- package/client/dist/assets/DocsDialog-B-chJn-f.js +0 -11
- package/client/dist/assets/DocsPage-BcJwYo20.js +0 -11
- package/client/dist/assets/IntegrationsPage-Bd4l3L6u.js +0 -3
- package/client/dist/assets/JobDetailPage-Dt3jLjS4.js +0 -16
- package/client/dist/assets/JobsPage-DcWpJbBc.js +0 -1
- package/client/dist/assets/analytics-BeTyviO8.js +0 -1
- package/client/dist/assets/analytics-C4eEO260.js +0 -1
- package/client/dist/assets/analytics-C67cIA1b.js +0 -1
- package/client/dist/assets/analytics-CAguvW28.js +0 -1
- package/client/dist/assets/analytics-DBtt8Mgk.js +0 -1
- package/client/dist/assets/analytics-DMCto-TF.js +0 -1
- package/client/dist/assets/analytics-DUPtODxX.js +0 -1
- package/client/dist/assets/analytics-YIpQvPAc.js +0 -1
- package/client/dist/assets/dashboard--Ahnvfr3.js +0 -1
- package/client/dist/assets/dashboard-BN1C2pEh.js +0 -1
- package/client/dist/assets/dashboard-BZs_EzAn.js +0 -1
- package/client/dist/assets/dashboard-Bsw44L8_.js +0 -1
- package/client/dist/assets/dashboard-Bw3VECgY.js +0 -1
- package/client/dist/assets/dashboard-CuOshSHn.js +0 -1
- package/client/dist/assets/dashboard-DfouCM3_.js +0 -1
- package/client/dist/assets/dashboard-Pp5hwnZB.js +0 -1
- package/client/dist/assets/index-BEGU2TCx.js +0 -143
- package/client/dist/assets/index-B_Zqeoa5.css +0 -2
- package/client/dist/assets/nav-B05EYB0b.js +0 -1
- package/client/dist/assets/nav-BNGCq-0y.js +0 -1
- package/client/dist/assets/nav-BRInPX8a.js +0 -1
- package/client/dist/assets/nav-Bf87DRHD.js +0 -1
- package/client/dist/assets/nav-BkVzzFpc.js +0 -1
- package/client/dist/assets/nav-BzFLtS1W.js +0 -1
- package/client/dist/assets/nav-DBDbQOYn.js +0 -1
- package/client/dist/assets/nav-X9sVtUWC.js +0 -1
- package/client/dist/assets/setup-Dn2-veYO.js +0 -1
- /package/client/dist/assets/{abap-s65oMlhi.js → abap-CK68cr9-.js} +0 -0
- /package/client/dist/assets/{activity-Cyy07Tgo.js → activity-B2MvEH54.js} +0 -0
- /package/client/dist/assets/{activity-qFTcMyW9.js → activity-BbNkUmW4.js} +0 -0
- /package/client/dist/assets/{activity-DlbWCa4y.js → activity-C7VdmeGb.js} +0 -0
- /package/client/dist/assets/{activity-Dv6H7wEr.js → activity-Ca2XoBi-.js} +0 -0
- /package/client/dist/assets/{activity-C8qqEIoP.js → activity-D4dhNEwO.js} +0 -0
- /package/client/dist/assets/{activity-Dwq0heud.js → activity-DHjfmAyT.js} +0 -0
- /package/client/dist/assets/{activity-CZVM4nlJ.js → activity-Di2f50_Z.js} +0 -0
- /package/client/dist/assets/{activity-BqqwnH_h.js → activity-usnNa7FX.js} +0 -0
- /package/client/dist/assets/{addon-image-CpF0L0jM.js → addon-image-biWX2UUm.js} +0 -0
- /package/client/dist/assets/{addon-ligatures-hXysGZrA.js → addon-ligatures-D4EiDb5r.js} +0 -0
- /package/client/dist/assets/{addon-webgl-Cn1slavz.js → addon-webgl-CDCIZQ03.js} +0 -0
- /package/client/dist/assets/{addspec-RuL8Zd7w.js → addspec-1HEtmLv1.js} +0 -0
- /package/client/dist/assets/{addspec-DDvvnE6N.js → addspec-BxMn39wn.js} +0 -0
- /package/client/dist/assets/{addspec-xjDbYZWL.js → addspec-CNyAUGz_.js} +0 -0
- /package/client/dist/assets/{addspec-CIGb34PS.js → addspec-CO1xv6BL.js} +0 -0
- /package/client/dist/assets/{addspec-BErjOdNK.js → addspec-DAveBiCE.js} +0 -0
- /package/client/dist/assets/{addspec-C_3NBarY.js → addspec-DE_VfIyP.js} +0 -0
- /package/client/dist/assets/{addspec-B-BKlvDj.js → addspec-DfuR6EAl.js} +0 -0
- /package/client/dist/assets/{addspec-rmhOaH7N.js → addspec-IozoiiGs.js} +0 -0
- /package/client/dist/assets/{agents-BDx1RXcl.js → agents-1lhqEcXH.js} +0 -0
- /package/client/dist/assets/{agents-BFr3kUhK.js → agents-BYjUOrLD.js} +0 -0
- /package/client/dist/assets/{agents-CMxtJMLD.js → agents-CIhRSOna.js} +0 -0
- /package/client/dist/assets/{agents-DcxZHzNr.js → agents-CQlu1nOm.js} +0 -0
- /package/client/dist/assets/{agents-BlPnx-mz.js → agents-DCX9D3-Q.js} +0 -0
- /package/client/dist/assets/{agents-23iPejcA.js → agents-DVYpVGur.js} +0 -0
- /package/client/dist/assets/{agents-B_1L9xRg.js → agents-DcoUUFZl.js} +0 -0
- /package/client/dist/assets/{agents-G3shOewU.js → agents-Jc-CjBDB.js} +0 -0
- /package/client/dist/assets/{agentstudio-kk9RB7Se.js → agentstudio-1E-bag77.js} +0 -0
- /package/client/dist/assets/{agentstudio-Bk1eZcv4.js → agentstudio-9NbsoGXk.js} +0 -0
- /package/client/dist/assets/{agentstudio-Y3G0ddJ2.js → agentstudio-B-jQgYV-.js} +0 -0
- /package/client/dist/assets/{agentstudio-B-CMAQqy.js → agentstudio-B1y0JWY-.js} +0 -0
- /package/client/dist/assets/{agentstudio-DpP9caEE.js → agentstudio-Bwa72b1S.js} +0 -0
- /package/client/dist/assets/{agentstudio-CxlUllqI.js → agentstudio-DCTpIqOx.js} +0 -0
- /package/client/dist/assets/{agentstudio-DNlme601.js → agentstudio-DCyDW8sy.js} +0 -0
- /package/client/dist/assets/{agentstudio-ChxNuGAu.js → agentstudio-Q0Sq_jTg.js} +0 -0
- /package/client/dist/assets/{aiedit-DrfzQroF.js → aiedit-CGxeml8D.js} +0 -0
- /package/client/dist/assets/{aiedit-De0SOH6S.js → aiedit-CfBNanHE.js} +0 -0
- /package/client/dist/assets/{aiedit-BBCrOpHq.js → aiedit-CvSspQmE.js} +0 -0
- /package/client/dist/assets/{aiedit-fMltW101.js → aiedit-DSLtsYIu.js} +0 -0
- /package/client/dist/assets/{aiedit-BMtcGYNE.js → aiedit-DUpe7NxI.js} +0 -0
- /package/client/dist/assets/{aiedit-TTwzL1TS.js → aiedit-Dirqf3Bm.js} +0 -0
- /package/client/dist/assets/{aiedit-5ETerMK1.js → aiedit-kAU7KADg.js} +0 -0
- /package/client/dist/assets/{aiedit-D9ddlgkM.js → aiedit-qTGI_PGs.js} +0 -0
- /package/client/dist/assets/{apex-BLUBIldB.js → apex-BHHyAVNb.js} +0 -0
- /package/client/dist/assets/{attachments-CHaDUfjB.js → attachments-3CuBBRFu.js} +0 -0
- /package/client/dist/assets/{attachments-DazTVJbH.js → attachments-BLqqPGyy.js} +0 -0
- /package/client/dist/assets/{attachments-CCWasu-P.js → attachments-BNgH6Tcu.js} +0 -0
- /package/client/dist/assets/{attachments-BIsSSnHJ.js → attachments-C2JPppoP.js} +0 -0
- /package/client/dist/assets/{attachments-CVSAbGNl.js → attachments-CppM7de8.js} +0 -0
- /package/client/dist/assets/{attachments-Chg5poG1.js → attachments-D5fVsMgb.js} +0 -0
- /package/client/dist/assets/{attachments-Dn-JImAK.js → attachments-UJtEq892.js} +0 -0
- /package/client/dist/assets/{attachments-LDA9kp2X.js → attachments-pW3zm9nu.js} +0 -0
- /package/client/dist/assets/{azcli-DuWxh9mO.js → azcli-C56lfIEP.js} +0 -0
- /package/client/dist/assets/{bat-UKoTejQm.js → bat-BLamSaf-.js} +0 -0
- /package/client/dist/assets/{bicep-4sTT4B3D.js → bicep-lrOcEItS.js} +0 -0
- /package/client/dist/assets/{browser-D2Y_UAKA.js → browser-B7i7Ysc8.js} +0 -0
- /package/client/dist/assets/{browser-BDd1dbFa.js → browser-BVQgd1_1.js} +0 -0
- /package/client/dist/assets/{browser-Dxc_VIRK.js → browser-C91MQBxx.js} +0 -0
- /package/client/dist/assets/{browser-DH9SGVfM.js → browser-C__Vz7KR.js} +0 -0
- /package/client/dist/assets/{browser-lTQwcDCI.js → browser-DhwTc0ry.js} +0 -0
- /package/client/dist/assets/{browser-Qya9cARy.js → browser-Dpo_ug4c.js} +0 -0
- /package/client/dist/assets/{browser-BWSgbfdX.js → browser-DwE289IS.js} +0 -0
- /package/client/dist/assets/{browser-DWOVYMlg.js → browser-EFmPpkvO.js} +0 -0
- /package/client/dist/assets/{cameligo-CAAryRYO.js → cameligo-BK_p0bgU.js} +0 -0
- /package/client/dist/assets/{chat-UVVZqA57.js → chat-9RcD5Lcn.js} +0 -0
- /package/client/dist/assets/{chat-CUrG1eVg.js → chat-BXVx6rb5.js} +0 -0
- /package/client/dist/assets/{chat-CPgmgZOj.js → chat-BnJPyeUK.js} +0 -0
- /package/client/dist/assets/{chat-CvOOKB2s.js → chat-C5nJF6L0.js} +0 -0
- /package/client/dist/assets/{chat-BO9MvVID.js → chat-CE8bx6Rz.js} +0 -0
- /package/client/dist/assets/{chat-DIh3hr6y.js → chat-PVakYp92.js} +0 -0
- /package/client/dist/assets/{chat-mPn3UlMl.js → chat-UMl6H55K.js} +0 -0
- /package/client/dist/assets/{chat-BsbNGPW9.js → chat-mq1x9cxZ.js} +0 -0
- /package/client/dist/assets/{clojure-BlMERO1w.js → clojure-BQ7JOykv.js} +0 -0
- /package/client/dist/assets/{clsx-CnH-HMk3.js → clsx-CjLeUJfG.js} +0 -0
- /package/client/dist/assets/{code-BwIz8agY.js → code-BPMR8_Vp.js} +0 -0
- /package/client/dist/assets/{code-CDFlxUFC.js → code-BsOBm1Fb.js} +0 -0
- /package/client/dist/assets/{code-CY85RXZU.js → code-DtIatVES.js} +0 -0
- /package/client/dist/assets/{code-DtZBQTi9.js → code-Lg4awa35.js} +0 -0
- /package/client/dist/assets/{code-CD7yNSK0.js → code-OoLqhjoI.js} +0 -0
- /package/client/dist/assets/{code-D24e1Crx.js → code-aCUqkVN_.js} +0 -0
- /package/client/dist/assets/{code-Cp3Fdng-.js → code-eh4vO2-_.js} +0 -0
- /package/client/dist/assets/{code-nKa0fkm_.js → code-u9Sg9ohM.js} +0 -0
- /package/client/dist/assets/{coffee-Cj8D-Wl1.js → coffee-BD3DiL5s.js} +0 -0
- /package/client/dist/assets/{commands-t4frzhB0.js → commands-B9XEyMj-.js} +0 -0
- /package/client/dist/assets/{commands-BR1kDkHQ.js → commands-BI1Ta-E7.js} +0 -0
- /package/client/dist/assets/{commands-DWgp-8W1.js → commands-BdI0CtOL.js} +0 -0
- /package/client/dist/assets/{commands-ddsl1V91.js → commands-C2ewlyXo.js} +0 -0
- /package/client/dist/assets/{commands-IXMOKBYt.js → commands-CwypztRT.js} +0 -0
- /package/client/dist/assets/{commands-Cb21pDlG.js → commands-DSX3yJyr.js} +0 -0
- /package/client/dist/assets/{commands-B-MVT-2F.js → commands-Ic1DJDxm.js} +0 -0
- /package/client/dist/assets/{commands-B0yFTp7e.js → commands-yNn4IA4C.js} +0 -0
- /package/client/dist/assets/{common-CTEbWVZS.js → common-BhFasU8N.js} +0 -0
- /package/client/dist/assets/{common-CALKUpYm.js → common-CnrZ9gCZ.js} +0 -0
- /package/client/dist/assets/{common-B4sqsKp7.js → common-CwhHWbTD.js} +0 -0
- /package/client/dist/assets/{common-wA36jmj1.js → common-D9GAPxeN.js} +0 -0
- /package/client/dist/assets/{common-5ilvMOcH.js → common-DI4jE5y-.js} +0 -0
- /package/client/dist/assets/{common-DQiza2Xp.js → common-DS8zKLQT.js} +0 -0
- /package/client/dist/assets/{common-BKpVwUIf.js → common-DTHzyfYC.js} +0 -0
- /package/client/dist/assets/{common-BzEC3kJU.js → common-DY4nzbWC.js} +0 -0
- /package/client/dist/assets/{cpp-BPfKnaj_.js → cpp-splnCwCh.js} +0 -0
- /package/client/dist/assets/{csharp-gX-x5uD6.js → csharp-BCpsl-o3.js} +0 -0
- /package/client/dist/assets/{csp-DKGVt8SM.js → csp-tkCWrZmb.js} +0 -0
- /package/client/dist/assets/{css-CPMdnAVq.js → css-B_xdnReq.js} +0 -0
- /package/client/dist/assets/{cypher-ClMDrj9S.js → cypher-OL1zq-y3.js} +0 -0
- /package/client/dist/assets/{dart-C4zbzpVv.js → dart-CtTlOkrm.js} +0 -0
- /package/client/dist/assets/{dockerfile-D9xw73D1.js → dockerfile-DcQ5CNiW.js} +0 -0
- /package/client/dist/assets/{ecl-gqO8tIR9.js → ecl-DZpiDRt6.js} +0 -0
- /package/client/dist/assets/{editor.api2-BPnIxMjz.js → editor.api2-Cwla1nvV.js} +0 -0
- /package/client/dist/assets/{elixir-DSAhVF3_.js → elixir-Dzj2lqtK.js} +0 -0
- /package/client/dist/assets/{explore-8gMBVmkp.js → explore-4SD1DxR0.js} +0 -0
- /package/client/dist/assets/{explore-vdBm_Re8.js → explore-B2n8r9Ye.js} +0 -0
- /package/client/dist/assets/{explore-BkWTnLi3.js → explore-BxR9q8Hq.js} +0 -0
- /package/client/dist/assets/{explore-CQUCw9ci.js → explore-CBYU76JD.js} +0 -0
- /package/client/dist/assets/{explore-Dbac0ErD.js → explore-CCcPXrHg.js} +0 -0
- /package/client/dist/assets/{explore-DUU36tcH.js → explore-CZt4Ncpa.js} +0 -0
- /package/client/dist/assets/{explore-DlKgN7D-.js → explore-DQ0XEjed.js} +0 -0
- /package/client/dist/assets/{explore-COaUKI0t.js → explore-xQoaak6e.js} +0 -0
- /package/client/dist/assets/{flow9-DeQCSPOd.js → flow9-CFENCHIZ.js} +0 -0
- /package/client/dist/assets/{format-command-CZsy-vHq.js → format-command-CMsBTOPN.js} +0 -0
- /package/client/dist/assets/{fsharp-CEfaXL-S.js → fsharp-D-4bv7FB.js} +0 -0
- /package/client/dist/assets/{go-Xp1OkZCh.js → go-djxbTJq7.js} +0 -0
- /package/client/dist/assets/{graphql-BwRXrUwe.js → graphql-DHIFrkZ6.js} +0 -0
- /package/client/dist/assets/{hcl-u06DtVFk.js → hcl-CXVoowNb.js} +0 -0
- /package/client/dist/assets/{ini-AmeIpFND.js → ini-Crzc5kly.js} +0 -0
- /package/client/dist/assets/{integrations-B9CEpNF0.js → integrations-9qxUNhPD.js} +0 -0
- /package/client/dist/assets/{integrations-DWz1eU_K.js → integrations-A9f08E0o.js} +0 -0
- /package/client/dist/assets/{integrations-BlvAdewo.js → integrations-B17KyA-i.js} +0 -0
- /package/client/dist/assets/{integrations-Bw8UM9Xd.js → integrations-B46ac3sf.js} +0 -0
- /package/client/dist/assets/{integrations-7YyTBuU9.js → integrations-C7u7SInG.js} +0 -0
- /package/client/dist/assets/{integrations-DiPR8Fzp.js → integrations-DkBi-Gsh.js} +0 -0
- /package/client/dist/assets/{integrations-C5SxNKnG.js → integrations-DwSVdCpf.js} +0 -0
- /package/client/dist/assets/{integrations-CJQKMmdW.js → integrations-jJGaKwff.js} +0 -0
- /package/client/dist/assets/{java-CyDbRQjX.js → java-CYLaJrdE.js} +0 -0
- /package/client/dist/assets/{jira-DOw8bkIR.js → jira-01H1RfQj.js} +0 -0
- /package/client/dist/assets/{jira-DKImM1YH.js → jira-0ldfMByG.js} +0 -0
- /package/client/dist/assets/{jira-Fob8EGxN.js → jira-4Fin3fu7.js} +0 -0
- /package/client/dist/assets/{jira-xZA2lixb.js → jira-BpnpUFlb.js} +0 -0
- /package/client/dist/assets/{jira-C-ATCti0.js → jira-BwACz875.js} +0 -0
- /package/client/dist/assets/{jira-DlA-wGp-.js → jira-CBU0200d.js} +0 -0
- /package/client/dist/assets/{jira-D7bkKAX8.js → jira-Dht8qNck.js} +0 -0
- /package/client/dist/assets/{jira-CmVfRM-b.js → jira-DzIVvNmy.js} +0 -0
- /package/client/dist/assets/{jobs-DAF8AGy5.js → jobs-BF9raUkL.js} +0 -0
- /package/client/dist/assets/{jobs-D93lG6If.js → jobs-Bw4hqEro.js} +0 -0
- /package/client/dist/assets/{jobs-F5PGJwbW.js → jobs-DM9owF1j.js} +0 -0
- /package/client/dist/assets/{jobs-Db3xrsp_.js → jobs-DRInW0AE.js} +0 -0
- /package/client/dist/assets/{jobs-fYWWxCUV.js → jobs-DcCONARH.js} +0 -0
- /package/client/dist/assets/{jobs-Brp44JDd.js → jobs-Oz3UtLQn.js} +0 -0
- /package/client/dist/assets/{jobs-Do4Ltqdj.js → jobs-jEQidSIb.js} +0 -0
- /package/client/dist/assets/{jobs-BGkI19S_.js → jobs-ym72SIR9.js} +0 -0
- /package/client/dist/assets/{julia-BqialFRG.js → julia-BJ7tUU-T.js} +0 -0
- /package/client/dist/assets/{kotlin-Dzz8TWAt.js → kotlin-CeWcU3lC.js} +0 -0
- /package/client/dist/assets/{less-DHRJD3TR.js → less-CviwWNG4.js} +0 -0
- /package/client/dist/assets/{lexon-5Y3QgTmT.js → lexon-Dt28jqDS.js} +0 -0
- /package/client/dist/assets/{lua-sKvhfPn5.js → lua-B6AOaJSi.js} +0 -0
- /package/client/dist/assets/{m3-DWDVwkFG.js → m3-VnMkHJcy.js} +0 -0
- /package/client/dist/assets/{markdown-CD_aSBxW.js → markdown-8vKNdvIM.js} +0 -0
- /package/client/dist/assets/{mips-687T03hg.js → mips-DoEcuzan.js} +0 -0
- /package/client/dist/assets/{msdax-C1St-dIV.js → msdax-CNzvHyEp.js} +0 -0
- /package/client/dist/assets/{mysql-BG7r8oBS.js → mysql-Buk3vUtL.js} +0 -0
- /package/client/dist/assets/{objective-c-Ds1-m05L.js → objective-c-DfOmda-5.js} +0 -0
- /package/client/dist/assets/{pascal-BKK9FpIi.js → pascal-DoAA2yjy.js} +0 -0
- /package/client/dist/assets/{pascaligo-SRS3nwtO.js → pascaligo-C65Vn1fu.js} +0 -0
- /package/client/dist/assets/{perl-B2hTOlrF.js → perl-INlfQ_ro.js} +0 -0
- /package/client/dist/assets/{pgsql-DIQJYNpL.js → pgsql-DtwRzglx.js} +0 -0
- /package/client/dist/assets/{php-BEaVe8X2.js → php-DfHqVNet.js} +0 -0
- /package/client/dist/assets/{pla-oPLHpZ-Q.js → pla-D3dNVRYk.js} +0 -0
- /package/client/dist/assets/{postiats-D_vzrAzD.js → postiats-UKXD1rM4.js} +0 -0
- /package/client/dist/assets/{powerquery-BKG6w-FH.js → powerquery-zE3E3O7s.js} +0 -0
- /package/client/dist/assets/{powershell-B3dLhDt4.js → powershell-Df9b3zQl.js} +0 -0
- /package/client/dist/assets/{protobuf-DC8SGjcl.js → protobuf-BF0nUVrW.js} +0 -0
- /package/client/dist/assets/{pug-D5E-4fI0.js → pug-Bj6Yikv_.js} +0 -0
- /package/client/dist/assets/{qsharp-6vJAWv0x.js → qsharp-BI4h-raZ.js} +0 -0
- /package/client/dist/assets/{r-CDwsEcbM.js → r-DhpnmaXx.js} +0 -0
- /package/client/dist/assets/{redis-CuQbbESS.js → redis-DwYYPr4d.js} +0 -0
- /package/client/dist/assets/{redshift-B9e1k-qI.js → redshift-D2f3Bc-4.js} +0 -0
- /package/client/dist/assets/{restructuredtext-BiJ5IwaU.js → restructuredtext-Dkiif6fe.js} +0 -0
- /package/client/dist/assets/{ruby-B0UAHY9b.js → ruby-C6hLmHy0.js} +0 -0
- /package/client/dist/assets/{rust-Dg_spmFr.js → rust-X8WAGtxB.js} +0 -0
- /package/client/dist/assets/{sb-DjU66I8Q.js → sb-4M2la0Kr.js} +0 -0
- /package/client/dist/assets/{scala-qvStIdfG.js → scala-CaCXz58E.js} +0 -0
- /package/client/dist/assets/{scheme-FstEk5Rh.js → scheme-CMdjpmP7.js} +0 -0
- /package/client/dist/assets/{scss-w0U3rQLK.js → scss-QopmvPyp.js} +0 -0
- /package/client/dist/assets/{settings-CewqtD9V.js → settings-0m2iuTzd.js} +0 -0
- /package/client/dist/assets/{settings-Puea5c8v.js → settings-BA1V6KdK.js} +0 -0
- /package/client/dist/assets/{settings-Cx97tHs5.js → settings-BN7OusER.js} +0 -0
- /package/client/dist/assets/{settings-BwMQ1lx5.js → settings-Bi5FFkIw.js} +0 -0
- /package/client/dist/assets/{settings-EMaKBwE0.js → settings-CRJxyTNN.js} +0 -0
- /package/client/dist/assets/{settings-DkB9Wh-f.js → settings-DyBxunCh.js} +0 -0
- /package/client/dist/assets/{settings-CqCY8gZq.js → settings-fk-WlnUt.js} +0 -0
- /package/client/dist/assets/{settings-CyixAx0X.js → settings-iQe5Dim-.js} +0 -0
- /package/client/dist/assets/{shell-DJ78wREd.js → shell-CDBchS00.js} +0 -0
- /package/client/dist/assets/{solidity-1aGIVsdX.js → solidity-DvBfi5mC.js} +0 -0
- /package/client/dist/assets/{sophia-40LqcGjB.js → sophia-HSnXR17u.js} +0 -0
- /package/client/dist/assets/{sparql-Cz5dqG_g.js → sparql-DhG_ppup.js} +0 -0
- /package/client/dist/assets/{specs-DfwDeADE.js → specs-Bku8SypT.js} +0 -0
- /package/client/dist/assets/{specs-B4GuOzuZ.js → specs-BvsFNKTs.js} +0 -0
- /package/client/dist/assets/{specs-ghyBMnib.js → specs-C2wW5bq8.js} +0 -0
- /package/client/dist/assets/{specs-VK-zXv7x.js → specs-CUE3xSFM.js} +0 -0
- /package/client/dist/assets/{specs-D-Sb6dre.js → specs-C_8j4ELZ.js} +0 -0
- /package/client/dist/assets/{specs-C62F2CDv.js → specs-CnH7dOiF.js} +0 -0
- /package/client/dist/assets/{specs-DFSkAeK8.js → specs-D4ORogcT.js} +0 -0
- /package/client/dist/assets/{specs-BVLKe2n5.js → specs-D6Y76Bgi.js} +0 -0
- /package/client/dist/assets/{sql-64f62Ni4.js → sql-DHeIS-tf.js} +0 -0
- /package/client/dist/assets/{st-gJe2yG8J.js → st-CMWchiRU.js} +0 -0
- /package/client/dist/assets/{swift-C6ME22mv.js → swift-CDXvBefj.js} +0 -0
- /package/client/dist/assets/{systemverilog-CEWz259w.js → systemverilog-0RTukYUE.js} +0 -0
- /package/client/dist/assets/{tcl-CcLVIi3m.js → tcl-CbBF_Ttl.js} +0 -0
- /package/client/dist/assets/{terminal-CPpK58RC.js → terminal-BLh00ouM.js} +0 -0
- /package/client/dist/assets/{terminal-CdxkpafL.js → terminal-BTanJIt_.js} +0 -0
- /package/client/dist/assets/{terminal-DHIkiWcs.js → terminal-CB33IsO1.js} +0 -0
- /package/client/dist/assets/{terminal-Ciia0wh2.js → terminal-CR6t-Oey.js} +0 -0
- /package/client/dist/assets/{terminal-DY42QANg.js → terminal-CY_sPfdD.js} +0 -0
- /package/client/dist/assets/{terminal-C0xx0SjA.js → terminal-Cj4HzP3p.js} +0 -0
- /package/client/dist/assets/{terminal-BYtreaaF.js → terminal-Cz_Puz0q.js} +0 -0
- /package/client/dist/assets/{terminal-DoxtVdma.js → terminal-DFEH9XTQ.js} +0 -0
- /package/client/dist/assets/{tickets-D5MSAPe_.js → tickets-BFrVcXAI.js} +0 -0
- /package/client/dist/assets/{tickets-DBV3wgQZ.js → tickets-C3gG--yT.js} +0 -0
- /package/client/dist/assets/{tickets-r4-oNV0R.js → tickets-Cfhwbdxj.js} +0 -0
- /package/client/dist/assets/{tickets-RZ0LyeQe.js → tickets-DcggvP3k.js} +0 -0
- /package/client/dist/assets/{tickets-d1A6EOHa.js → tickets-EnP6m_Ao.js} +0 -0
- /package/client/dist/assets/{tickets-Q0_pONEh.js → tickets-IbYhlr-6.js} +0 -0
- /package/client/dist/assets/{tickets-CVJQ-vRm.js → tickets-ZS5EsDxn.js} +0 -0
- /package/client/dist/assets/{tickets-CG_mo-Bg.js → tickets-lJR7pWNI.js} +0 -0
- /package/client/dist/assets/{twig-DvsO-WjW.js → twig-DCcGd8FE.js} +0 -0
- /package/client/dist/assets/{typespec-Brkt3IAA.js → typespec-HTphp-Uh.js} +0 -0
- /package/client/dist/assets/{vb-r121Uzxt.js → vb-Cb_yUcVd.js} +0 -0
- /package/client/dist/assets/{wgsl-BRX8uYh4.js → wgsl-DrKU3YXj.js} +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Il Loop Builder
|
|
2
|
+
|
|
3
|
+
Un **rail esegue un Loop**. I loop integrati (`Implement`, `Batch`, `Ultracode`) coprono i casi di tutti i giorni, ma il **Loop Builder** ti permette di progettare i tuoi — un editor visuale in stile n8n per automazioni che si ripetono finché un obiettivo non è raggiunto. Questa pagina spiega cos'è un loop, come costruirne uno e come eseguirlo su un rail.
|
|
4
|
+
|
|
5
|
+
## Loop e rail — la relazione
|
|
6
|
+
|
|
7
|
+
Un **loop** è la *ricetta* del lavoro; un **rail** è la *corsia* che lo esegue sulle tue spec.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Loop Builder (sidebar sinistra) Rail (destra)
|
|
11
|
+
─────────────────────────── ─────────────
|
|
12
|
+
Implement (integrato) Rail 1
|
|
13
|
+
Batch (integrato) scegli su ► Loop: Verify-until-green
|
|
14
|
+
Ultracode (integrato) ▶ Play
|
|
15
|
+
Verify-until-green (tuo)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- I loop vivono nella sezione **Loops** (sidebar sinistra, accanto ai tuoi progetti) — sono **globali**, condivisi tra tutti i progetti.
|
|
19
|
+
- Un rail **sceglie un loop** nel suo header (il selettore Loop) e lo esegue quando premi Play.
|
|
20
|
+
- È il **rail** a decidere provider, modello e reasoning effort — *non* gli step del loop. Lo stesso loop gira su Claude, Codex o Gemini a seconda del rail.
|
|
21
|
+
|
|
22
|
+
Quindi: costruisci un loop una volta, poi scegli quel loop su qualsiasi rail in qualsiasi progetto.
|
|
23
|
+
|
|
24
|
+
## Aprire il builder
|
|
25
|
+
|
|
26
|
+
Clicca **Loops** nella sidebar sinistra per vedere la libreria: i tre loop integrati più tutti i tuoi. Aprine uno per visualizzarlo, oppure clicca **New loop** per partire da una tela bianca.
|
|
27
|
+
|
|
28
|
+
Non puoi modificare facilmente un integrato in modo diretto — invece fanne un **Fork**. Ti dà una copia modificabile di un grafo funzionante da cui partire, ed è il modo più semplice per imparare.
|
|
29
|
+
|
|
30
|
+
## Di cosa è fatto un loop
|
|
31
|
+
|
|
32
|
+
Un loop è un grafo di **nodi** collegati da **archi** (le frecce). Ogni nodo è uno step:
|
|
33
|
+
|
|
34
|
+
| Nodo | Cosa fa |
|
|
35
|
+
|------|--------------|
|
|
36
|
+
| **Start** | Dove inizia l'esecuzione. Esattamente uno per loop. |
|
|
37
|
+
| **AI Step** | Esegue un turno AI — un prompt che scrivi tu, o un *magic command* come `{{cmd:implement}}`, `{{cmd:verify}}`, `{{cmd:fix}}`. È qui che accade il lavoro vero. |
|
|
38
|
+
| **Shell** | Esegue un comando shell (es. `npm test`) e ne cattura l'output per gli step successivi. |
|
|
39
|
+
| **Loop Decider** | Il cervello di un loop. A ogni passaggio legge un **obiettivo** che scrivi tu e decide **continue** (torna indietro e riprova) o **stop** (esci). È ciò che alimenta *verify → fix → verify finché non è verde*. |
|
|
40
|
+
| **End** | Un nodo terminale. Marca l'esecuzione come successo o fallimento. |
|
|
41
|
+
|
|
42
|
+
Gli archi collegano gli step in ordine. Il **Loop Decider** ha due uscite etichettate — **continue** e **stop** — così colleghi "non ancora finito" di nuovo nel lavoro e "fatto" verso un End.
|
|
43
|
+
|
|
44
|
+
### Scrivere il testo di uno step
|
|
45
|
+
|
|
46
|
+
Dentro qualsiasi AI Step o Decider puoi fare riferimento a:
|
|
47
|
+
|
|
48
|
+
- **Dati della spec** — `{{spec.title}}`, `{{spec.description}}`, `{{spec.ids}}` (gli ID dei ticket del rail). Riempiti dalle spec sul rail al momento dell'esecuzione.
|
|
49
|
+
- **Magic command** — `{{cmd:implement}}` e simili si espandono nel comando della pipeline corrispondente.
|
|
50
|
+
- **Costanti** — `{{const:NAME}}` attinge dalla **libreria di costanti** globale (trascinale dalla palette). Sentinelle integrate come i marcatori PASS/FAIL di verifica sono sempre disponibili; puoi aggiungere le tue e riusarle in ogni loop.
|
|
51
|
+
|
|
52
|
+
## Tenere un loop entro i limiti
|
|
53
|
+
|
|
54
|
+
Un loop che non si ferma mai brucerebbe soldi per sempre, quindi ogni esecuzione ha tre guardie (impostate nella toolbar del builder):
|
|
55
|
+
|
|
56
|
+
| Guardia | Cosa fa |
|
|
57
|
+
|-------|--------------|
|
|
58
|
+
| **Max iterations** | Tetto massimo di quante volte il Decider può tornare indietro, indipendentemente dal suo verdetto. |
|
|
59
|
+
| **Timeout (min)** | Limite di tempo reale per l'intera esecuzione. |
|
|
60
|
+
| **Max cost ($)** | *Opzionale.* Ferma il loop quando il costo accumulato supera il tuo budget. Controllato **tra uno step e l'altro** (il costo di uno step si conosce solo quando finisce), quindi può sforare di uno step. Su Claude il costo è esatto; su Codex e Gemini è una stima. Lascialo vuoto per nessun tetto. |
|
|
61
|
+
|
|
62
|
+
## Costruire con sicurezza
|
|
63
|
+
|
|
64
|
+
Il builder ti aiuta a far girare bene un loop prima ancora che venga eseguito:
|
|
65
|
+
|
|
66
|
+
- **Validazione dal vivo** — i problemi (nessuno Start, uno step orfano, un prompt vuoto, un Decider con rami mancanti) sono segnalati sulla tela e in un pannello dei problemi.
|
|
67
|
+
- **Anteprima dry-run** — risolve il testo esatto di ogni step (dati della spec, costanti, comandi tutti espansi) **senza avviare nulla**, così vedi con precisione cosa invierebbe ogni step.
|
|
68
|
+
- **Auto-arrange** — riordina la tela in verticale, orizzontale o a griglia; la tua scelta è salvata per loop.
|
|
69
|
+
- **Copia / incolla** — `Cmd/Ctrl + C` / `V` per copiare step dentro o tra i loop.
|
|
70
|
+
- **Import / export** — salva i loop in un file `.json` e reimportali (i nomi duplicati vengono saltati, il resto viene importato).
|
|
71
|
+
- **Rinomina step** — dai a ogni nodo un'etichetta personalizzata così il grafo si legge chiaro.
|
|
72
|
+
|
|
73
|
+
## Pubblicare ed eseguire
|
|
74
|
+
|
|
75
|
+
Un loop nasce come **Draft**. Quando il grafo è valido, fai **Publish** — i loop pubblicati sono quelli che compaiono nel selettore Loop di un rail. (Fai Unpublish per toglierlo dalla circolazione senza eliminarlo.)
|
|
76
|
+
|
|
77
|
+
Per eseguire un loop personalizzato:
|
|
78
|
+
|
|
79
|
+
1. Apri un progetto e trascina una spec su un rail.
|
|
80
|
+
2. Nell'header del rail, apri il **selettore Loop** e scegli il tuo loop pubblicato.
|
|
81
|
+
3. Premi **▶ Play**.
|
|
82
|
+
|
|
83
|
+
L'esecuzione scorre dal vivo nella vista **Jobs** esattamente come un job di rail integrato — stessi log, stesse metriche, stesso tracciamento del costo. Un loop che si ferma perché ha raggiunto il suo tetto di iterazioni o di costo viene riportato con quell'esito anziché con un semplice successo.
|
|
84
|
+
|
|
85
|
+
> **Attenzione mentre un loop gira.** Non puoi modificare o eliminare un loop mentre una delle sue esecuzioni è in corso — ferma prima l'esecuzione.
|
|
86
|
+
|
|
87
|
+
## Dove andare poi
|
|
88
|
+
|
|
89
|
+
- [Rail e job](rails-and-jobs) — avviare i rail e la coda dei job.
|
|
90
|
+
- [La vista Dettaglio job](the-job-detail-view) — seguire un'esecuzione dal vivo.
|
|
91
|
+
- [Scegliere un engine per rail](picking-an-engine-per-rail) — è il rail (non il loop) a scegliere il provider.
|
|
@@ -23,7 +23,7 @@ SpecsBoard(左) レール(右)
|
|
|
23
23
|
## スペックでレールを起動する
|
|
24
24
|
|
|
25
25
|
1. **スペックカードをドラッグ**して、SpecsBoard からレールへ移します。スペックの ID がそのレールのスペック一覧に表示されます。(ドラッグが苦手ですか? スペックカードの **レールに移動** ポップオーバーを使えば、レールごとにステータスのドットが表示されるので、ふさがっているレーンに作業を落としてしまう心配がありません。)
|
|
26
|
-
2.
|
|
26
|
+
2. レールヘッダーで **Loop を選びます**。レールは **Loop** を実行します — それがレールの行う作業そのものです。デフォルトは組み込みの `Implement` Loop ですが、`Batch`、`Ultracode`、あるいは自分で作ったカスタム Loop を選ぶこともできます。[Loop Builder](the-loop-builder) を参照してください。
|
|
27
27
|
3. **▶ Play を押します。**
|
|
28
28
|
|
|
29
29
|
これだけです。レールがあなたのプロジェクト内で AI CLI プロセスを立ち上げ、パイプラインを開始します。
|
|
@@ -34,20 +34,24 @@ SpecsBoard(左) レール(右)
|
|
|
34
34
|
|---------|--------------|
|
|
35
35
|
| **ステータスピル** | `idle`、`running`、`failed` のいずれか。「completed」という別ステータスはありません — ジョブがきれいに完了すると、レールは `idle` に戻ります。 |
|
|
36
36
|
| **スペック一覧** | このレールに割り当てられた ID。さらにドラッグして追加したり、ドラッグして外したりできます。 |
|
|
37
|
-
|
|
|
37
|
+
| **Loop ピッカー** | このレールが実行する Loop — 組み込み(`Implement` / `Batch` / `Ultracode`)かカスタム Loop。下の表を参照してください。レールごとに保持されます。 |
|
|
38
38
|
| **プロファイルピッカー** | どのエージェントプロファイルを実行するか(Claude レール限定)。プロジェクトにプロファイルが 1 つ以上あるときだけ表示されます。 |
|
|
39
39
|
| **エンジンセレクター** | このレールをどのインストール済みプロバイダーで実行するか — Claude、Codex、Gemini。プロジェクトに複数のプロバイダーがある場合だけ表示されます。[レールごとのエンジン選択](picking-an-engine-per-rail) を参照してください。 |
|
|
40
40
|
| **▶ Play / ■ Stop** | 開始またはキャンセル。 |
|
|
41
41
|
|
|
42
|
-
###
|
|
42
|
+
### レールが実行するもの: Loop
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
レールは **Loop** を実行します — それが作業のレシピです。3 つの Loop が **組み込み** で、よくあるケースをカバーします。
|
|
45
|
+
|
|
46
|
+
| 組み込み Loop | コマンド | 役割 |
|
|
45
47
|
|------|---------|--------------|
|
|
46
48
|
| **Implement** | `/specrails:implement` | レール上のすべてのスペックをまとめた 1 つのジョブ。Architect → Developer → Reviewer → Ship のフルパイプラインを実行します。日常的に使うデフォルトです。 |
|
|
47
49
|
| **Batch** | `/specrails:batch-implement` | レール上のスペックを、依存関係を考慮したウェーブで順番に処理する 1 つのジョブ。関連する複数のスペックに最適です。 |
|
|
48
|
-
| **
|
|
50
|
+
| **Ultracode** | Ultracode | Claude が各スペックをパイプラインを**バイパス**して自律的に実装します。スペックごとに独立したジョブが 1 つずつ作られます。Claude 専用。 |
|
|
51
|
+
|
|
52
|
+
Ultracode は少し毛色が違います。エージェントチェーンを飛ばし、生のスペックを Claude に渡してネイティブツールで作業させます。自由度が高いぶん、Play を押すとまず確認ダイアログが開き、レールごとのモデルピッカーで Haiku / Sonnet / Opus を選べます。Ultracode はレールのエンジンが Claude のときだけ表示されます。
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
組み込みのほかにも、**自分だけの Loop を作る** ことができます — verify → fix → verify のサイクルを目標が達成されるまで繰り返したり、AI ステップの間にシェルコマンドを連ねたり、さらにいろいろなことができます。そうしたカスタム Loop は同じ Loop ピッカーに表示されます。それが次の大きなアイデア、[Loop Builder](the-loop-builder) です。
|
|
51
55
|
|
|
52
56
|
## ジョブのキュー
|
|
53
57
|
|
|
@@ -89,6 +93,7 @@ CLI がマシンにインストールされていないエンジンを選ぶと
|
|
|
89
93
|
|
|
90
94
|
## 次に読むもの
|
|
91
95
|
|
|
96
|
+
- [Loop Builder](the-loop-builder) — レールが実行するもの、そして自分だけの Loop を作る方法。
|
|
92
97
|
- [ジョブ詳細ビュー](the-job-detail-view) — フェーズ、ライブメトリクス、チケットカード。
|
|
93
98
|
- [バッチ実装とマルチフィーチャー](batch-implement-and-multi-feature) — 複数のスペックをまとめて実行する。
|
|
94
99
|
- [レールごとのエンジン選択](picking-an-engine-per-rail) — Claude / Codex / Gemini の使い分け。
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Loop Builder
|
|
2
|
+
|
|
3
|
+
**レールは Loop を実行します。** 組み込みの Loop(`Implement`、`Batch`、`Ultracode`)は日常的なケースをカバーしますが、**Loop Builder** を使えば自分だけの Loop を設計できます — 目標が達成されるまで繰り返す自動化のための、n8n スタイルのビジュアルエディターです。このページでは、Loop とは何か、どう作るのか、そしてレールでどう実行するのかを説明します。
|
|
4
|
+
|
|
5
|
+
## Loop とレール — その関係
|
|
6
|
+
|
|
7
|
+
**Loop** は作業の *レシピ* で、**レール** はそれをあなたのスペックに対して実行する *レーン* です。
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Loop Builder(左サイドバー) レール(右)
|
|
11
|
+
─────────────────────────── ─────────────
|
|
12
|
+
Implement (組み込み) レール 1
|
|
13
|
+
Batch (組み込み) ► で選ぶ Loop: Verify-until-green
|
|
14
|
+
Ultracode (組み込み) ▶ Play
|
|
15
|
+
Verify-until-green (あなたの作ったもの)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- Loop は **Loops** セクション(左サイドバー、プロジェクトの隣)にあります — これらは **グローバル** で、すべてのプロジェクトで共有されます。
|
|
19
|
+
- レールはヘッダー(Loop ピッカー)で **Loop を選び**、Play を押すとそれを実行します。
|
|
20
|
+
- プロバイダー、モデル、推論の労力(reasoning effort)を決めるのは **レール** であって、Loop のステップではありません。同じ Loop が、レール次第で Claude、Codex、Gemini のいずれでも実行されます。
|
|
21
|
+
|
|
22
|
+
つまり、Loop を一度作ってしまえば、どのプロジェクトのどのレールでもそれを選べます。
|
|
23
|
+
|
|
24
|
+
## ビルダーを開く
|
|
25
|
+
|
|
26
|
+
左サイドバーの **Loops** をクリックすると、ライブラリが表示されます。3 つの組み込み Loop に加えて、あなた自身の Loop が並びます。どれかを開いて中身を見るか、**New loop** をクリックして真っ白なキャンバスから始めます。
|
|
27
|
+
|
|
28
|
+
組み込みの Loop を直接編集するのは簡単ではありません — 代わりに **Fork** します。そうすると、ちゃんと動くグラフの編集可能なコピーが手に入るので、そこから始められます。これが一番手っ取り早い学び方です。
|
|
29
|
+
|
|
30
|
+
## Loop を構成するもの
|
|
31
|
+
|
|
32
|
+
Loop は **ノード** を **エッジ**(矢印)でつないだグラフです。各ノードが 1 つのステップです。
|
|
33
|
+
|
|
34
|
+
| ノード | 役割 |
|
|
35
|
+
|------|--------------|
|
|
36
|
+
| **Start** | 実行が始まる場所。1 つの Loop につきちょうど 1 つ。 |
|
|
37
|
+
| **AI Step** | AI のターンを実行します — あなたが書くプロンプト、または `{{cmd:implement}}`、`{{cmd:verify}}`、`{{cmd:fix}}` のような *マジックコマンド*。ここで本物の作業が行われます。 |
|
|
38
|
+
| **Shell** | シェルコマンド(例: `npm test`)を実行し、その出力を後続のステップ用にキャプチャします。 |
|
|
39
|
+
| **Loop Decider** | Loop の頭脳。各パスで、あなたが書いた **目標(goal)** を読み、**continue**(ループバックしてもう一度試す)か **stop**(抜ける)かを判断します。*verify → fix → verify until green* を動かしているのがこれです。 |
|
|
40
|
+
| **End** | 終端ノード。実行を成功または失敗としてマークします。 |
|
|
41
|
+
|
|
42
|
+
エッジはステップを順番につなぎます。**Loop Decider** には **continue** と **stop** という 2 つのラベル付き出力があるので、「まだ終わっていない」を作業へ配線して戻し、「終わった」を End へ配線して出します。
|
|
43
|
+
|
|
44
|
+
### ステップのテキストを書く
|
|
45
|
+
|
|
46
|
+
AI Step や Decider の中では、次のものを参照できます。
|
|
47
|
+
|
|
48
|
+
- **スペックデータ** — `{{spec.title}}`、`{{spec.description}}`、`{{spec.ids}}`(レールのチケット ID)。実行時にレール上のスペックから埋め込まれます。
|
|
49
|
+
- **マジックコマンド** — `{{cmd:implement}}` とその仲間は、対応するパイプラインコマンドに展開されます。
|
|
50
|
+
- **定数(Constants)** — `{{const:NAME}}` はグローバルな **定数ライブラリ** から値を引き込みます(パレットからドラッグして追加します)。検証の PASS/FAIL マーカーのような組み込みのセンチネルは常に利用できます。自分で追加して、すべての Loop で再利用することもできます。
|
|
51
|
+
|
|
52
|
+
## Loop を有界に保つ
|
|
53
|
+
|
|
54
|
+
止まらない Loop はお金を永遠に燃やし続けてしまうので、すべての実行に 3 つのガードがあります(ビルダーのツールバーで設定します)。
|
|
55
|
+
|
|
56
|
+
| ガード | 役割 |
|
|
57
|
+
|-------|--------------|
|
|
58
|
+
| **Max iterations** | Decider が判断にかかわらずループバックできる回数のハードキャップ。 |
|
|
59
|
+
| **Timeout (min)** | 実行全体に対する実時間(壁時計)の上限。 |
|
|
60
|
+
| **Max cost ($)** | *任意。* 累積コストが予算を超えた時点で Loop を停止します。**ステップとステップの間** でチェックされるため(あるステップのコストはそれが終わってからしかわかりません)、1 ステップ分だけオーバーシュートすることがあります。Claude ではコストは正確で、Codex と Gemini では見積もりです。上限を設けないなら空のままにしておきます。 |
|
|
61
|
+
|
|
62
|
+
## 自信を持って組み立てる
|
|
63
|
+
|
|
64
|
+
ビルダーは、Loop が実行される前に正しく仕上げる手助けをしてくれます。
|
|
65
|
+
|
|
66
|
+
- **ライブバリデーション** — 問題(Start がない、孤立したステップ、空のプロンプト、ブランチの欠けた Decider など)がキャンバス上と問題パネルにフラグ表示されます。
|
|
67
|
+
- **ドライランプレビュー** — **何も起動せずに** 各ステップの正確なテキスト(スペックデータ、定数、コマンドがすべて展開された状態)を解決するので、各ステップが何を送ることになるのかを正確に確認できます。
|
|
68
|
+
- **自動整列(Auto-arrange)** — キャンバスを縦・横・グリッドのいずれかにすっきり並べます。選択は Loop ごとに保存されます。
|
|
69
|
+
- **コピー / ペースト** — `Cmd/Ctrl + C` / `V` で、Loop の内部や Loop をまたいでステップをコピーします。
|
|
70
|
+
- **インポート / エクスポート** — Loop を `.json` ファイルに保存し、また読み込めます(名前が重複するものはスキップされ、残りはインポートされます)。
|
|
71
|
+
- **ステップの名前変更** — 各ノードにカスタムラベルを付けて、グラフが読みやすくなるようにします。
|
|
72
|
+
|
|
73
|
+
## 公開して実行する
|
|
74
|
+
|
|
75
|
+
Loop は最初は **Draft** です。グラフが有効になったら **Publish** します — 公開された Loop が、レールの Loop ピッカーに表示されるものです。(削除せずに流通から外したいときは Unpublish します。)
|
|
76
|
+
|
|
77
|
+
カスタム Loop を実行するには、
|
|
78
|
+
|
|
79
|
+
1. プロジェクトを開いて、スペックをレールにドラッグします。
|
|
80
|
+
2. レールヘッダーで **Loop ピッカー** を開き、公開したあなたの Loop を選びます。
|
|
81
|
+
3. **▶ Play** を押します。
|
|
82
|
+
|
|
83
|
+
実行は **ジョブ** ビューで、組み込みのレールジョブとまったく同じようにライブでストリーミングされます — 同じログ、同じメトリクス、同じコストトラッキングです。反復回数やコストの上限に達して停止した Loop は、ただの成功ではなく、その結果とともに報告されます。
|
|
84
|
+
|
|
85
|
+
> **Loop の実行中の注意点。** いずれかの実行が動いている間は、その Loop を編集したり削除したりできません — 先に実行を止めてください。
|
|
86
|
+
|
|
87
|
+
## 次に読むもの
|
|
88
|
+
|
|
89
|
+
- [レールとジョブ](rails-and-jobs) — レールの起動とジョブのキュー。
|
|
90
|
+
- [ジョブ詳細ビュー](the-job-detail-view) — 実行をライブで見守る。
|
|
91
|
+
- [レールごとのエンジン選択](picking-an-engine-per-rail) — プロバイダーを選ぶのは(Loop ではなく)レール。
|
|
@@ -1,94 +1,99 @@
|
|
|
1
1
|
# Rails e jobs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Você já tem specs no quadro. É aqui que elas viram código. Um **rail** é a pista que conduz uma spec por todo o pipeline — Architect → Developer → Reviewer → Ship — executando agentes de IA reais dentro do diretório do seu projeto. Esta página cobre como lançar um rail, a fila de jobs e como acompanhar o trabalho acontecendo ao vivo.
|
|
4
4
|
|
|
5
5
|
## O que é um rail
|
|
6
6
|
|
|
7
|
-
Imagine
|
|
7
|
+
Imagine sua tela dividida em duas:
|
|
8
8
|
|
|
9
9
|
```
|
|
10
10
|
SpecsBoard (esquerda) Rails (direita)
|
|
11
11
|
───────────────── ─────────────────
|
|
12
12
|
#1 Login flow ─┐
|
|
13
|
-
#2 Webhook retry │
|
|
13
|
+
#2 Webhook retry │ arraste para
|
|
14
14
|
#3 Cost limits │ ────────────► Rail 1 ▶ Play
|
|
15
15
|
#4 Audit log │
|
|
16
16
|
└────────────► Rail 2 ▶ Play
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Um rail é uma **
|
|
19
|
+
Um rail é uma **pista de execução**. Você arrasta um cartão de spec do SpecsBoard para um rail e depois aperta **▶ Play**. O rail dispara o pipeline e trabalha a spec de ponta a ponta, bem no diretório de trabalho do seu projeto — editando arquivos, rodando testes, tudo.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Você pode ter vários rails para organizar o trabalho em pistas nomeadas (uma para a feature em que está focado, outra na fila atrás dela). Mais sobre multi-rail e batching em [Batch implement e multi-feature](batch-implement-and-multi-feature).
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Lançando um rail sobre uma spec
|
|
24
24
|
|
|
25
|
-
1. **Arraste um cartão de spec** do SpecsBoard para um rail. O ID da spec aparece na lista de specs do rail. (Prefere não arrastar? Use o popover **Mover para
|
|
26
|
-
2. **Escolha um
|
|
27
|
-
3. **
|
|
25
|
+
1. **Arraste um cartão de spec** do SpecsBoard para um rail. O ID da spec aparece na lista de specs do rail. (Prefere não arrastar? Use o popover **Mover para o rail** no cartão da spec — ele mostra um indicador de status por rail, para você não soltar trabalho numa pista ocupada.)
|
|
26
|
+
2. **Escolha um Loop** no cabeçalho do rail. Um rail roda um **Loop** — é o trabalho que ele realiza. O padrão é o Loop `Implement` embutido; você também pode escolher `Batch`, `Ultracode` ou um loop personalizado que você mesmo construiu. Veja [O Loop Builder](the-loop-builder).
|
|
27
|
+
3. **Aperte ▶ Play.**
|
|
28
28
|
|
|
29
|
-
É
|
|
29
|
+
É isso. O rail sobe um processo de CLI de IA no seu projeto e começa o pipeline.
|
|
30
30
|
|
|
31
|
-
### O que
|
|
31
|
+
### O que tem no cabeçalho de um rail
|
|
32
32
|
|
|
33
|
-
|
|
|
33
|
+
| Controle | O que faz |
|
|
34
34
|
|---------|--------------|
|
|
35
|
-
| **Pílula de
|
|
36
|
-
| **Lista de specs** | Os IDs atribuídos a este rail. Arraste mais para dentro, arraste para fora para
|
|
37
|
-
| **
|
|
38
|
-
| **Seletor de perfil** |
|
|
39
|
-
| **Seletor de motor** |
|
|
35
|
+
| **Pílula de status** | `idle`, `running` ou `failed`. Não há um "completed" separado — um rail volta para `idle` quando seu job termina sem erros. |
|
|
36
|
+
| **Lista de specs** | Os IDs atribuídos a este rail. Arraste mais para dentro, arraste para fora para desanexar. |
|
|
37
|
+
| **Seletor de Loop** | O Loop que este rail roda — um embutido (`Implement` / `Batch` / `Ultracode`) ou um loop personalizado. Veja a tabela abaixo. Persistido por rail. |
|
|
38
|
+
| **Seletor de perfil** | Qual perfil de agente roda (apenas rails Claude). Só aparece quando o projeto tem ao menos um perfil. |
|
|
39
|
+
| **Seletor de motor** | Qual provedor instalado roda este rail — Claude, Codex ou Gemini. Só é renderizado quando o projeto tem mais de um provedor. Veja [Escolhendo um motor por rail](picking-an-engine-per-rail). |
|
|
40
40
|
| **▶ Play / ■ Stop** | Iniciar ou cancelar. |
|
|
41
41
|
|
|
42
|
-
###
|
|
42
|
+
### O que um rail roda: Loops
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
Um rail roda um **Loop** — a receita do trabalho. Três loops são **embutidos** e cobrem os casos comuns:
|
|
45
|
+
|
|
46
|
+
| Loop embutido | Comando | O que faz |
|
|
45
47
|
|------|---------|--------------|
|
|
46
|
-
| **Implement** | `/specrails:implement` | Um
|
|
47
|
-
| **Batch** | `/specrails:batch-implement` | Um
|
|
48
|
-
| **
|
|
48
|
+
| **Implement** | `/specrails:implement` | Um job cobrindo todas as specs do rail. Roda o pipeline completo Architect → Developer → Reviewer → Ship. O padrão do dia a dia. |
|
|
49
|
+
| **Batch** | `/specrails:batch-implement` | Um job que percorre as specs do rail sequencialmente, em ondas que respeitam as dependências. Melhor para várias specs relacionadas. |
|
|
50
|
+
| **Ultracode** | Ultracode | O Claude implementa cada spec de forma autônoma, **ignorando** o pipeline. Um job independente por spec. Apenas Claude. |
|
|
51
|
+
|
|
52
|
+
O Ultracode é o caso atípico: ele pula a cadeia de agentes e entrega a spec crua ao Claude para trabalhar com suas ferramentas nativas. É aberto, então apertar Play abre primeiro uma confirmação, e um seletor de modelo por rail deixa você escolher Haiku / Sonnet / Opus. Ele só aparece quando o motor do rail é o Claude.
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
Além dos embutidos, você pode **construir seus próprios loops** — repetir um ciclo verify → fix → verify até atingir uma meta, encadear comandos de shell entre AI Steps e muito mais. Esses loops personalizados aparecem no mesmo seletor de Loop. Essa é a próxima grande ideia: [O Loop Builder](the-loop-builder).
|
|
51
55
|
|
|
52
56
|
## A fila de jobs
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
Toda vez que você aperta Play, a execução do rail vira um **job**. A regra mais importante para internalizar:
|
|
55
59
|
|
|
56
|
-
> **Um job de cada vez, por projeto.** Cada projeto tem uma única fila. Dentro de um projeto, só um job de rail
|
|
60
|
+
> **Um job de cada vez, por projeto.** Cada projeto tem uma única fila. Dentro de um projeto, só um job de rail roda por vez — o resto fica na fila atrás dele e inicia automaticamente conforme os slots ficam livres.
|
|
57
61
|
|
|
58
|
-
|
|
62
|
+
Isso surpreende quem adiciona três rails esperando que rodem em paralelo. Eles não vão — não dentro do mesmo projeto. Adicionar rails *organiza* seu trabalho em pistas; isso não faz essas pistas rodarem de forma concorrente.
|
|
59
63
|
|
|
60
|
-
**O paralelismo
|
|
64
|
+
**O paralelismo de verdade é entre projetos.** Cada projeto tem sua própria fila independente, então um rail no Projeto A e um rail no Projeto B rodam ao mesmo tempo sem disputar recursos. Quer mais throughput? Abra mais projetos.
|
|
61
65
|
|
|
62
|
-
Não há um botão global de concorrência para
|
|
66
|
+
Não há um botão global de concorrência para ajustar. O único limite automático é baseado em orçamento: se você definiu um orçamento diário (do projeto ou da app), a fila se autopausa assim que o gasto do dia atinge o teto.
|
|
63
67
|
|
|
64
|
-
##
|
|
68
|
+
## Acompanhando a execução
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
Encontre todos os jobs em **Jobs**, na barra lateral direita do projeto — uma lista de cartões, os mais recentes primeiro. Cada cartão mostra um selo de status, o selo de perfil, um selo de prioridade, duração, custo e o comando lançado. Acima da lista:
|
|
67
71
|
|
|
68
|
-
- **Chips de filtro
|
|
69
|
-
- **Filtro por intervalo de datas** — restringe a uma janela
|
|
70
|
-
- **Comparar** —
|
|
72
|
+
- **Chips de filtro de status** — mostram apenas jobs em um dado status.
|
|
73
|
+
- **Filtro por intervalo de datas** — restringe a uma janela de tempo.
|
|
74
|
+
- **Comparar** — escolha dois jobs e veja-os lado a lado.
|
|
71
75
|
|
|
72
|
-
Clique em qualquer cartão para abrir a **vista de detalhe do
|
|
76
|
+
Clique em qualquer cartão para abrir a **vista de detalhe do Job**, onde ficam o log em streaming ao vivo e as métricas ao vivo. Essa é a próxima página: [A vista de detalhe do job](the-job-detail-view).
|
|
73
77
|
|
|
74
|
-
##
|
|
78
|
+
## Cancelando um job
|
|
75
79
|
|
|
76
|
-
|
|
80
|
+
Clique em **■ Stop** no cabeçalho do rail. A app envia `SIGTERM` ao subprocesso, espera **5 segundos** por uma saída limpa e então faz `SIGKILL`. Nada fica spawnado pela metade.
|
|
77
81
|
|
|
78
|
-
## Se um rail não
|
|
82
|
+
## Se um rail não lançar
|
|
79
83
|
|
|
80
|
-
Se escolher um motor cuja CLI não está instalada na sua máquina, o lançamento **falha
|
|
84
|
+
Se você escolher um motor cuja CLI não está instalada na sua máquina, o lançamento **falha rápido** em vez de iniciar um job quebrado — nada é spawnado. Instale a CLI do provedor que falta ([Usando Codex](../integrations/using-codex), [Usando Gemini](../integrations/using-gemini)) e lance de novo. Claude ou Codex ausentes dão uma mensagem precisa "*<provider> CLI not found*"; o Gemini ausente exibe um erro genérico de lançamento por enquanto, mas o resultado é o mesmo.
|
|
81
85
|
|
|
82
|
-
##
|
|
86
|
+
## Parando tudo
|
|
83
87
|
|
|
84
88
|
Se algo parecer errado:
|
|
85
89
|
|
|
86
|
-
- **Um rail** —
|
|
87
|
-
- **
|
|
88
|
-
- **Tudo** — feche
|
|
90
|
+
- **Um rail** — clique em **■ Stop** no cabeçalho dele.
|
|
91
|
+
- **Autopausa por orçamento** — defina um orçamento diário e a fila se pausa sozinha quando o gasto do dia atinge o teto.
|
|
92
|
+
- **Tudo** — feche o app desktop, ou rode `specrails-desktop stop`.
|
|
89
93
|
|
|
90
|
-
## Para onde ir
|
|
94
|
+
## Para onde ir agora
|
|
91
95
|
|
|
96
|
+
- [O Loop Builder](the-loop-builder) — o que um rail roda, e como construir seus próprios loops.
|
|
92
97
|
- [A vista de detalhe do job](the-job-detail-view) — fases, métricas ao vivo, cartões de ticket.
|
|
93
|
-
- [Batch implement e multi-feature](batch-implement-and-multi-feature) —
|
|
94
|
-
- [
|
|
98
|
+
- [Batch implement e multi-feature](batch-implement-and-multi-feature) — rode várias specs de uma vez.
|
|
99
|
+
- [Escolhendo um motor por rail](picking-an-engine-per-rail) — Claude vs Codex vs Gemini.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# O Loop Builder
|
|
2
|
+
|
|
3
|
+
Um **rail roda um Loop**. Os loops embutidos (`Implement`, `Batch`, `Ultracode`) cobrem os casos do dia a dia, mas o **Loop Builder** deixa você desenhar os seus próprios — um editor visual, no estilo n8n, para automação que se repete até atingir uma meta. Esta página explica o que é um loop, como construir um e como rodá-lo em um rail.
|
|
4
|
+
|
|
5
|
+
## Loops e rails — a relação
|
|
6
|
+
|
|
7
|
+
Um **loop** é a *receita* do trabalho; um **rail** é a *pista* que o roda contra as suas specs.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Loop Builder (barra lateral esq.) Rails (direita)
|
|
11
|
+
─────────────────────────── ─────────────
|
|
12
|
+
Implement (embutido) Rail 1
|
|
13
|
+
Batch (embutido) escolha ► Loop: Verify-until-green
|
|
14
|
+
Ultracode (embutido) ▶ Play
|
|
15
|
+
Verify-until-green (seu)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- Os loops vivem na seção **Loops** (barra lateral esquerda, ao lado dos seus projetos) — eles são **globais**, compartilhados por todos os projetos.
|
|
19
|
+
- Um rail **escolhe um loop** no cabeçalho (o seletor de Loop) e o roda quando você aperta Play.
|
|
20
|
+
- O **rail** decide o provedor, o modelo e o esforço de raciocínio — *não* os passos do loop. O mesmo loop roda em Claude, Codex ou Gemini dependendo do rail.
|
|
21
|
+
|
|
22
|
+
Ou seja: construa um loop uma vez e depois escolha-o em qualquer rail, em qualquer projeto.
|
|
23
|
+
|
|
24
|
+
## Abrindo o builder
|
|
25
|
+
|
|
26
|
+
Clique em **Loops** na barra lateral esquerda para ver a biblioteca: os três loops embutidos mais os seus próprios. Abra um para vê-lo, ou clique em **New loop** para começar de uma tela em branco.
|
|
27
|
+
|
|
28
|
+
Você não consegue editar um embutido diretamente com facilidade — em vez disso, faça **Fork** dele. Isso te dá uma cópia editável de um grafo que funciona como ponto de partida, que é a forma mais fácil de aprender.
|
|
29
|
+
|
|
30
|
+
## Do que um loop é feito
|
|
31
|
+
|
|
32
|
+
Um loop é um grafo de **nós** conectados por **arestas** (as setas). Cada nó é um passo:
|
|
33
|
+
|
|
34
|
+
| Nó | O que faz |
|
|
35
|
+
|------|--------------|
|
|
36
|
+
| **Start** | Onde a execução começa. Exatamente um por loop. |
|
|
37
|
+
| **AI Step** | Roda um turno de IA — um prompt que você escreve, ou um *comando mágico* como `{{cmd:implement}}`, `{{cmd:verify}}`, `{{cmd:fix}}`. É aqui que o trabalho de verdade acontece. |
|
|
38
|
+
| **Shell** | Roda um comando de shell (ex.: `npm test`) e captura sua saída para passos posteriores. |
|
|
39
|
+
| **Loop Decider** | O cérebro de um loop. A cada passagem ele lê uma **meta** que você escreve e decide **continue** (voltar e tentar de novo) ou **stop** (sair). É isto que faz funcionar o *verify → fix → verify até ficar verde*. |
|
|
40
|
+
| **End** | Um nó terminal. Marca a execução como sucesso ou falha. |
|
|
41
|
+
|
|
42
|
+
As arestas conectam os passos em ordem. O **Loop Decider** tem duas saídas rotuladas — **continue** e **stop** — então você liga o "ainda não terminei" de volta ao trabalho e o "terminei" para um End.
|
|
43
|
+
|
|
44
|
+
### Escrevendo o texto dos passos
|
|
45
|
+
|
|
46
|
+
Dentro de qualquer AI Step ou Decider você pode referenciar:
|
|
47
|
+
|
|
48
|
+
- **Dados da spec** — `{{spec.title}}`, `{{spec.description}}`, `{{spec.ids}}` (os IDs dos tickets do rail). Preenchidos a partir da(s) spec(s) do rail em tempo de execução.
|
|
49
|
+
- **Comandos mágicos** — `{{cmd:implement}}` e seus companheiros expandem para o comando de pipeline correspondente.
|
|
50
|
+
- **Constantes** — `{{const:NAME}}` puxa da **biblioteca de constantes** global (arraste-as da paleta). Sentinelas embutidos como os marcadores de PASS/FAIL da verificação estão sempre disponíveis; você pode adicionar os seus e reutilizá-los em todos os loops.
|
|
51
|
+
|
|
52
|
+
## Mantendo um loop limitado
|
|
53
|
+
|
|
54
|
+
Um loop que nunca para queimaria dinheiro para sempre, então toda execução tem três proteções (definidas na barra de ferramentas do builder):
|
|
55
|
+
|
|
56
|
+
| Proteção | O que faz |
|
|
57
|
+
|-------|--------------|
|
|
58
|
+
| **Max iterations** | Teto rígido de quantas vezes o Decider pode voltar atrás, independentemente do seu veredito. |
|
|
59
|
+
| **Timeout (min)** | Limite de tempo de relógio para toda a execução. |
|
|
60
|
+
| **Max cost ($)** | *Opcional.* Para o loop quando o custo acumulado cruza o seu orçamento. Verificado **entre passos** (o custo de um passo só é conhecido quando ele termina), então pode ultrapassar em um passo. No Claude o custo é exato; no Codex e no Gemini é uma estimativa. Deixe vazio para não ter teto. |
|
|
61
|
+
|
|
62
|
+
## Construindo com confiança
|
|
63
|
+
|
|
64
|
+
O builder ajuda você a acertar um loop antes mesmo de ele rodar:
|
|
65
|
+
|
|
66
|
+
- **Validação ao vivo** — problemas (sem Start, um passo órfão, um prompt vazio, um Decider com ramos faltando) são sinalizados na tela e em um painel de problemas.
|
|
67
|
+
- **Pré-visualização de dry-run** — resolve o texto exato de cada passo (dados da spec, constantes e comandos todos expandidos) **sem spawnar nada**, para você ver com precisão o que cada passo enviaria.
|
|
68
|
+
- **Auto-arrange** — organize a tela na vertical, na horizontal ou em grade; sua escolha é salva por loop.
|
|
69
|
+
- **Copiar / colar** — `Cmd/Ctrl + C` / `V` para copiar passos dentro de um loop ou entre loops.
|
|
70
|
+
- **Importar / exportar** — salve loops em um arquivo `.json` e importe-os de volta (nomes duplicados são ignorados, o resto é importado).
|
|
71
|
+
- **Renomear passos** — dê a cada nó um rótulo personalizado para que o grafo fique legível.
|
|
72
|
+
|
|
73
|
+
## Publicando e rodando
|
|
74
|
+
|
|
75
|
+
Um loop começa como um **Draft**. Quando o grafo está válido, faça **Publish** — os loops publicados são os que aparecem no seletor de Loop de um rail. (Faça Unpublish para tirá-lo de circulação sem apagá-lo.)
|
|
76
|
+
|
|
77
|
+
Para rodar um loop personalizado:
|
|
78
|
+
|
|
79
|
+
1. Abra um projeto e arraste uma spec para um rail.
|
|
80
|
+
2. No cabeçalho do rail, abra o **seletor de Loop** e escolha o seu loop publicado.
|
|
81
|
+
3. Aperte **▶ Play**.
|
|
82
|
+
|
|
83
|
+
A execução transmite ao vivo na vista **Jobs**, exatamente como um job de rail embutido — mesmos logs, mesmas métricas, mesmo rastreamento de custo. Um loop que para porque atingiu seu teto de iterações ou de custo é reportado com esse resultado, em vez de um simples sucesso.
|
|
84
|
+
|
|
85
|
+
> **Atenção enquanto um loop roda.** Você não pode editar nem apagar um loop enquanto uma de suas execuções está rodando — pare a execução primeiro.
|
|
86
|
+
|
|
87
|
+
## Para onde ir agora
|
|
88
|
+
|
|
89
|
+
- [Rails e jobs](rails-and-jobs) — lançando rails e a fila de jobs.
|
|
90
|
+
- [A vista de detalhe do job](the-job-detail-view) — acompanhando uma execução ao vivo.
|
|
91
|
+
- [Escolhendo um motor por rail](picking-an-engine-per-rail) — o rail (não o loop) escolhe o provedor.
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
可以把你的屏幕想象成左右两半:
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
SpecsBoard (
|
|
10
|
+
SpecsBoard (左) Rails (右)
|
|
11
11
|
───────────────── ─────────────────
|
|
12
12
|
#1 Login flow ─┐
|
|
13
|
-
#2 Webhook retry │
|
|
13
|
+
#2 Webhook retry │ 拖拽到
|
|
14
14
|
#3 Cost limits │ ────────────► Rail 1 ▶ Play
|
|
15
15
|
#4 Audit log │
|
|
16
16
|
└────────────► Rail 2 ▶ Play
|
|
@@ -23,7 +23,7 @@ rail 是一条**执行通道**。你从 SpecsBoard 上拖一张 spec 卡片放
|
|
|
23
23
|
## 在某个 spec 上启动一条 rail
|
|
24
24
|
|
|
25
25
|
1. **把一张 spec 卡片拖**到某条 rail 上。该 spec 的 ID 会出现在这条 rail 的 spec 列表里。(不想拖?用 spec 卡片上的 **放入 Rail** 弹窗——它会为每条 rail 显示一个状态圆点,避免你把活儿丢进一条正忙的通道。)
|
|
26
|
-
2.
|
|
26
|
+
2. **在 rail 头部挑一个 Loop。** 一条 rail 运行的是一个 **Loop**——也就是它要做的活儿。默认是内置的 `Implement` loop;你也可以挑 `Batch`、`Ultracode`,或者你自己搭的某个自定义 loop。见 [Loop Builder](the-loop-builder)。
|
|
27
27
|
3. **按下 ▶ Play。**
|
|
28
28
|
|
|
29
29
|
就这么简单。rail 会在你的项目里启动一个 AI CLI 进程,开始跑流水线。
|
|
@@ -34,20 +34,24 @@ rail 是一条**执行通道**。你从 SpecsBoard 上拖一张 spec 卡片放
|
|
|
34
34
|
|---------|--------------|
|
|
35
35
|
| **状态标签** | `idle`、`running` 或 `failed`。这里没有单独的"completed"——任务干净地跑完后,rail 会回到 `idle`。 |
|
|
36
36
|
| **spec 列表** | 分配给这条 rail 的 ID。可以再拖进来,也可以拖出去解除关联。 |
|
|
37
|
-
|
|
|
37
|
+
| **Loop 选择器** | 这条 rail 运行的 Loop——内置的(`Implement` / `Batch` / `Ultracode`)或某个自定义 loop。见下表。按 rail 单独记忆。 |
|
|
38
38
|
| **Profile 选择器** | 运行哪个 Agent Profile(仅限 Claude rail)。只有当项目至少有一个 Profile 时才会出现。 |
|
|
39
39
|
| **引擎选择器** | 这条 rail 用哪个已安装的提供方来跑——Claude、Codex 或 Gemini。仅当项目装有不止一个提供方时才显示。见 [为每条 rail 选择引擎](picking-an-engine-per-rail)。 |
|
|
40
40
|
| **▶ Play / ■ Stop** | 启动或取消。 |
|
|
41
41
|
|
|
42
|
-
###
|
|
42
|
+
### rail 运行的是什么:Loop
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
一条 rail 运行的是一个 **Loop**——干活的配方。有三个 loop 是**内置**的,覆盖了常见情况:
|
|
45
|
+
|
|
46
|
+
| 内置 loop | 命令 | 作用 |
|
|
45
47
|
|------|---------|--------------|
|
|
46
48
|
| **Implement** | `/specrails:implement` | 一个任务覆盖这条 rail 上的所有 spec。跑完整的 Architect → Developer → Reviewer → Ship 流水线。日常默认选项。 |
|
|
47
49
|
| **Batch** | `/specrails:batch-implement` | 一个任务,按依赖感知的批次(wave)依次处理 rail 上的各个 spec。最适合一组相关的 spec。 |
|
|
48
|
-
| **
|
|
50
|
+
| **Ultracode** | Ultracode | Claude 自主实现每个 spec,**绕过**流水线。每个 spec 一个独立任务。仅限 Claude。 |
|
|
51
|
+
|
|
52
|
+
Ultracode 是个特例:它跳过 Agent 链条,把原始 spec 直接交给 Claude,让它用自己的原生工具去做。因为它比较"放飞",所以按下 Play 会先弹出一个确认框,而且有一个按 rail 单独的模型选择器,让你在 Haiku / Sonnet / Opus 之间挑选。只有当 rail 的引擎是 Claude 时它才会出现。
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
除了这些内置 loop,你还可以**搭建自己的 loop**——重复一个 verify → fix → verify 的循环直到目标达成、在 AI 步骤之间串联 shell 命令,等等。这些自定义 loop 会出现在同一个 Loop 选择器里。这就是下一个大点子:[Loop Builder](the-loop-builder)。
|
|
51
55
|
|
|
52
56
|
## 任务队列
|
|
53
57
|
|
|
@@ -89,6 +93,7 @@ Ultra 是个特例:它跳过 Agent 链条,把原始 spec 直接交给 Claude
|
|
|
89
93
|
|
|
90
94
|
## 接下来去哪儿
|
|
91
95
|
|
|
96
|
+
- [Loop Builder](the-loop-builder)——rail 运行的是什么,以及如何搭建你自己的 loop。
|
|
92
97
|
- [任务详情视图](the-job-detail-view)——阶段、实时指标、工单卡片。
|
|
93
98
|
- [批量实现与多功能](batch-implement-and-multi-feature)——一次跑多个 spec。
|
|
94
99
|
- [为每条 rail 选择引擎](picking-an-engine-per-rail)——Claude、Codex 还是 Gemini。
|