specrails-desktop 2.64.2 → 2.65.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 +1 -1
- package/cli/dist/status.js +3 -0
- package/client/dist/assets/ActivityFeedPage-ByVKYII-.js +1 -0
- package/client/dist/assets/AgentBrowserCapture-BGUTjhUr.js +1 -0
- package/client/dist/assets/AgentModeAnalyticsPane-CtOLDDjB.js +2 -0
- package/client/dist/assets/AgentModeCodePane-CDhUKarT.js +2 -0
- package/client/dist/assets/AgentModeJobsPane-BAa_oEHJ.js +1 -0
- package/client/dist/assets/AgentsPage-D32hG4Ve.js +120 -0
- package/client/dist/assets/AnalyticsPage-BU50zeG6.js +5 -0
- package/client/dist/assets/BudgetCard-DP_jxwaD.js +55 -0
- package/client/dist/assets/CodePage-jiYnKGpp.js +3 -0
- package/client/dist/assets/CostValue-Bvn8674q.js +1 -0
- package/client/dist/assets/DesktopAnalyticsPage-CF__H4e3.js +1 -0
- package/client/dist/assets/DocView-RrAp70zp.js +11 -0
- package/client/dist/assets/DocsDialog-DkqHU-JF.js +1 -0
- package/client/dist/assets/DocsPage-C6X089zC.js +1 -0
- package/client/dist/assets/ExportDropdown-C5-o8y3K.js +1 -0
- package/client/dist/assets/HelpHint-Crf9_uoR.js +1 -0
- package/client/dist/assets/IntegrationsPage-aflU3KHK.js +1 -0
- package/client/dist/assets/InteractiveJobComposer-CEMMhyyJ.js +19 -0
- package/client/dist/assets/JobDetailModal-BVJ6hyRs.js +1 -0
- package/client/dist/assets/JobDetailPage-DHzBUmox.js +1 -0
- package/client/dist/assets/JobsPage-o-LAqkwC.js +1 -0
- package/client/dist/assets/LoopBuilderPage-DbSVmXBM.js +1 -0
- package/client/dist/assets/LoopPreviewModal-DbJcVyN1.js +1 -0
- package/client/dist/assets/{LoopWindowSurface-DE0v2K1p.js → LoopWindowSurface-Co1ZK26V.js} +1 -1
- package/client/dist/assets/LoopsPage-C4lgkPXB.js +2 -0
- package/client/dist/assets/MinimizedChatsContext-742ypO8n.js +1 -0
- package/client/dist/assets/PluginsPage-Acks9ges.js +2 -0
- package/client/dist/assets/RailTrack-BfLmBzBh.js +1 -0
- package/client/dist/assets/{RepositoryScopeSelector-2eSqR9WK.js → RepositoryScopeSelector-DcxbKI9w.js} +1 -1
- package/client/dist/assets/ReviewPacketPage-CAVSIOAJ.js +7 -0
- package/client/dist/assets/TemplatePreviewModal-C23SYCTm.js +1 -0
- package/client/dist/assets/TicketDetailModalContext-B-Gtm6Ob.js +23 -0
- package/client/dist/assets/Trans-C6J0cLyh.js +1 -0
- package/client/dist/assets/a11y-prefs-BqoP5goK.js +1 -0
- package/client/dist/assets/activity-BBWfoUOG.js +1 -0
- package/client/dist/assets/activity-BM_skann.js +1 -0
- package/client/dist/assets/activity-Cevl82ke.js +1 -0
- package/client/dist/assets/activity-CmACk5W5.js +1 -0
- package/client/dist/assets/activity-D9LBw3PQ.js +1 -0
- package/client/dist/assets/activity-Dspbb9lz.js +1 -0
- package/client/dist/assets/activity-FPjYIjv9.js +1 -0
- package/client/dist/assets/activity-nLCKMUKt.js +1 -0
- package/client/dist/assets/addspec-BI4jDMhA.js +1 -0
- package/client/dist/assets/addspec-BldTv7Tl.js +1 -0
- package/client/dist/assets/addspec-Cdq-2EcC.js +1 -0
- package/client/dist/assets/addspec-DH5M16BQ.js +1 -0
- package/client/dist/assets/addspec-DOFo9pD5.js +1 -0
- package/client/dist/assets/addspec-DPkwhdmL.js +1 -0
- package/client/dist/assets/addspec-Dzy12Pv3.js +1 -0
- package/client/dist/assets/addspec-skTs6EEW.js +1 -0
- package/client/dist/assets/agent-B_UEUy7Y.js +1 -0
- package/client/dist/assets/agent-BarjlhTA.js +1 -0
- package/client/dist/assets/agent-BfqIITo5.js +1 -0
- package/client/dist/assets/agent-Bt9a7Kyj.js +1 -0
- package/client/dist/assets/agent-C3689RwP.js +1 -0
- package/client/dist/assets/agent-CrmboTAi.js +1 -0
- package/client/dist/assets/agent-DcsoTnuE.js +1 -0
- package/client/dist/assets/agent-GDZoYwd4.js +1 -0
- package/client/dist/assets/{agentRuntime-es2ymSl-.js → agentRuntime-BYH70bKY.js} +1 -1
- package/client/dist/assets/agentRuntime-BijLh8I9.js +1 -0
- package/client/dist/assets/{agentRuntime-BzuwQQgn.js → agentRuntime-BvyuETPe.js} +1 -1
- package/client/dist/assets/{agentRuntime-BDvbJMmS.js → agentRuntime-C2WI6HQh.js} +1 -1
- package/client/dist/assets/{agentRuntime-BKJfv5YD.js → agentRuntime-CZPIlQsr.js} +1 -1
- package/client/dist/assets/{agentRuntime-DiCldqGG.js → agentRuntime-D2dDvCyJ.js} +1 -1
- package/client/dist/assets/agentRuntime-DWZedEbn.js +1 -0
- package/client/dist/assets/agentRuntime-DkIruUNw.js +1 -0
- package/client/dist/assets/agents-35_PDKx9.js +1 -0
- package/client/dist/assets/agents-8fZnHhEQ.js +1 -0
- package/client/dist/assets/agents-Bgimtw8z.js +1 -0
- package/client/dist/assets/agents-C4P160Us.js +1 -0
- package/client/dist/assets/agents-Clg67zbp.js +1 -0
- package/client/dist/assets/agents-DJfF4o6G.js +1 -0
- package/client/dist/assets/agents-Dc9-Y5cw.js +1 -0
- package/client/dist/assets/agents-EN1Zl4YZ.js +1 -0
- package/client/dist/assets/agentstudio-Bm4-NYaG.js +1 -0
- package/client/dist/assets/agentstudio-CD1fuj2o.js +1 -0
- package/client/dist/assets/agentstudio-CQGWFSst.js +1 -0
- package/client/dist/assets/agentstudio-CqVSb65S.js +1 -0
- package/client/dist/assets/agentstudio-DIE_HjsX.js +1 -0
- package/client/dist/assets/agentstudio-D_OmQK-k.js +1 -0
- package/client/dist/assets/agentstudio-Djz9aUfb.js +1 -0
- package/client/dist/assets/agentstudio-Qa3v9o5J.js +1 -0
- package/client/dist/assets/{aiedit-DNXxq_Dr.js → aiedit-1VzLs37W.js} +1 -1
- package/client/dist/assets/{aiedit-DCjA7jLJ.js → aiedit-BNp6GSik.js} +1 -1
- package/client/dist/assets/{aiedit-BoG24nlg.js → aiedit-BOY5xRPi.js} +1 -1
- package/client/dist/assets/{aiedit-iIjz2_Qk.js → aiedit-BrqMZvbc.js} +1 -1
- package/client/dist/assets/{aiedit-CjlSRQVP.js → aiedit-CVgtl7hm.js} +1 -1
- package/client/dist/assets/{aiedit-DQ-0_pvE.js → aiedit-CrFW9Jd2.js} +1 -1
- package/client/dist/assets/{aiedit-olnv3QSt.js → aiedit-YE2lILp7.js} +1 -1
- package/client/dist/assets/{aiedit-B0KUbpB6.js → aiedit-iA_R1AVQ.js} +1 -1
- package/client/dist/assets/analytics-3w0t-4ic.js +1 -0
- package/client/dist/assets/analytics-BRi4KQD6.js +1 -0
- package/client/dist/assets/analytics-BtjAqzke.js +1 -0
- package/client/dist/assets/analytics-COSQ1h47.js +1 -0
- package/client/dist/assets/analytics-CP2HjESk.js +1 -0
- package/client/dist/assets/analytics-DY65TC62.js +1 -0
- package/client/dist/assets/analytics-Den_vvxn.js +1 -0
- package/client/dist/assets/analytics-LmBS96O8.js +1 -0
- package/client/dist/assets/api-DOGbyfTO.js +2 -0
- package/client/dist/assets/builder-BMVvSr4v.js +1 -0
- package/client/dist/assets/builder-BN-MuLZt.js +1 -0
- package/client/dist/assets/builder-BQOZi4CF.js +1 -0
- package/client/dist/assets/builder-BjUPjsyu.js +1 -0
- package/client/dist/assets/builder-BoBtN18T.js +1 -0
- package/client/dist/assets/builder-C5g5NhxL.js +1 -0
- package/client/dist/assets/builder-RUHXw3yx.js +1 -0
- package/client/dist/assets/builder-fyS_AiyC.js +1 -0
- package/client/dist/assets/button-CHPkroew.js +1 -0
- package/client/dist/assets/chat-C9L5T7KI.js +1 -0
- package/client/dist/assets/chevron-right-CwMAj0w_.js +1 -0
- package/client/dist/assets/chevron-up-BAMuP0XD.js +1 -0
- package/client/dist/assets/chunk-OB3PAWPO-BBaq6pUk.js +3 -0
- package/client/dist/assets/code-4le5IIbf.js +1 -0
- package/client/dist/assets/code-B-jCVIbm.js +1 -0
- package/client/dist/assets/code-BRfrn5ix.js +1 -0
- package/client/dist/assets/code-CC9NCrDM.js +1 -0
- package/client/dist/assets/code-CK6pm8wY.js +1 -0
- package/client/dist/assets/code-DDiOzd6c.js +1 -0
- package/client/dist/assets/code-tGifiyf5.js +1 -0
- package/client/dist/assets/code-xkn8kQTg.js +1 -0
- package/client/dist/assets/commands-Bv1QshHR.js +1 -0
- package/client/dist/assets/commands-BvxTxboW.js +1 -0
- package/client/dist/assets/commands-C5ORR0fO.js +1 -0
- package/client/dist/assets/commands-CBKMFSTV.js +1 -0
- package/client/dist/assets/commands-CFJIRsJv.js +1 -0
- package/client/dist/assets/commands-D9o3ZcXl.js +1 -0
- package/client/dist/assets/commands-DNox0Edk.js +1 -0
- package/client/dist/assets/commands-DmIUMLdV.js +1 -0
- package/client/dist/assets/common-5H4TkaoI.js +1 -0
- package/client/dist/assets/common-9S3OdPjx.js +1 -0
- package/client/dist/assets/common-BqnwIcjs.js +1 -0
- package/client/dist/assets/common-CQP3VafS.js +1 -0
- package/client/dist/assets/common-CZnAfkB2.js +1 -0
- package/client/dist/assets/common-D5sNttV4.js +1 -0
- package/client/dist/assets/common-k_qX9nlv.js +1 -0
- package/client/dist/assets/common-s4HIi9XI.js +1 -0
- package/client/dist/assets/compass-B7guwBlY.js +1 -0
- package/client/dist/assets/confirm-dialog-ChZdHL3Q.js +1 -0
- package/client/dist/assets/copy-DOPlLymH.js +1 -0
- package/client/dist/assets/core-BozBzB6Y.js +1 -0
- package/client/dist/assets/dashboard-6zGLGcEz.js +1 -0
- package/client/dist/assets/dashboard-8Gi0FBDq.js +1 -0
- package/client/dist/assets/dashboard-B7E5YrSy.js +1 -0
- package/client/dist/assets/dashboard-BhdKV8xK.js +1 -0
- package/client/dist/assets/dashboard-Bu3zzH_s.js +1 -0
- package/client/dist/assets/dashboard-Ce_6rELA.js +1 -0
- package/client/dist/assets/dashboard-DWY-oz8P.js +1 -0
- package/client/dist/assets/dashboard-gUzlWk0o.js +1 -0
- package/client/dist/assets/date-input-Cdlr8kHz.js +1 -0
- package/client/dist/assets/dialog-C23lB2iP.js +5 -0
- package/client/dist/assets/dist-Di-oOFkX.js +1 -0
- package/client/dist/assets/dist-js-CBmS6MsJ.js +1 -0
- package/client/dist/assets/{dist-js-Rlh4FLH5.js → dist-js-DaJmKapi.js} +1 -1
- package/client/dist/assets/dropdown-menu-Bfp2CK6H.js +1 -0
- package/client/dist/assets/empty-state-D5w9OWj-.js +1 -0
- package/client/dist/assets/es2015-DfnECntk.js +41 -0
- package/client/dist/assets/esm-BKF6CE7v.js +1 -0
- package/client/dist/assets/event-BEnMLqAi.js +1 -0
- package/client/dist/assets/explore--NOz9LCN.js +1 -0
- package/client/dist/assets/explore-B2ulH6dO.js +1 -0
- package/client/dist/assets/explore-BD-QiLdg.js +1 -0
- package/client/dist/assets/explore-BOqd4_1j.js +1 -0
- package/client/dist/assets/explore-Be_Zh5zu.js +1 -0
- package/client/dist/assets/explore-CLjzPSKo.js +1 -0
- package/client/dist/assets/explore-D_-vHm29.js +1 -0
- package/client/dist/assets/explore-yEQTF6ro.js +1 -0
- package/client/dist/assets/file-text-CNXzL3wj.js +1 -0
- package/client/dist/assets/format-BODoFIw6.js +1 -0
- package/client/dist/assets/formatDistanceToNow-DLMIOS0N.js +1 -0
- package/client/dist/assets/getTimezoneOffsetInMilliseconds-O61feXch.js +1 -0
- package/client/dist/assets/git-compare-arrows-Cu6tICCq.js +1 -0
- package/client/dist/assets/humanise-command-CB4ybLwq.js +1 -0
- package/client/dist/assets/inbox-BLZ8cm6_.js +1 -0
- package/client/dist/assets/inbox-BQ3VmNYY.js +1 -0
- package/client/dist/assets/inbox-BdcXWCuT.js +1 -0
- package/client/dist/assets/inbox-CF1PHjns.js +1 -0
- package/client/dist/assets/inbox-CFNPDhso.js +1 -0
- package/client/dist/assets/inbox-DIttK_NW.js +1 -0
- package/client/dist/assets/inbox-Dfdv1Ykl.js +1 -0
- package/client/dist/assets/inbox-JS1inmeO.js +1 -0
- package/client/dist/assets/index-4UWY7Xyz.css +2 -0
- package/client/dist/assets/index-DHzB0T26.js +120 -0
- package/client/dist/assets/integrations-BcKgzgPD.js +1 -0
- package/client/dist/assets/integrations-BmX_XyJq.js +1 -0
- package/client/dist/assets/integrations-CHpwMjlY.js +1 -0
- package/client/dist/assets/integrations-CT3kr8e-.js +1 -0
- package/client/dist/assets/integrations-C_5XAkgz.js +1 -0
- package/client/dist/assets/integrations-Ct9zLX7N.js +1 -0
- package/client/dist/assets/integrations-DEYemxUv.js +1 -0
- package/client/dist/assets/integrations-DWvsB_WB.js +1 -0
- package/client/dist/assets/{jira-Cq6yvN4q.js → jira-B_ERkFRv.js} +1 -1
- package/client/dist/assets/jira-Bn-A5lwD.js +1 -0
- package/client/dist/assets/jira-C71Ybnhp.js +1 -0
- package/client/dist/assets/jira-CkwjeJz6.js +1 -0
- package/client/dist/assets/jira-D9pSLXjI.js +1 -0
- package/client/dist/assets/jira-DBRS_lcp.js +1 -0
- package/client/dist/assets/jira-DHS6CsKh.js +1 -0
- package/client/dist/assets/jira-MInHRUb1.js +1 -0
- package/client/dist/assets/jira-api-DHme7Upx.js +1 -0
- package/client/dist/assets/jobs-BMLTDo63.js +1 -0
- package/client/dist/assets/jobs-BO8q4Mi1.js +1 -0
- package/client/dist/assets/jobs-Ck8uOWMM.js +1 -0
- package/client/dist/assets/jobs-CyFfPCpg.js +1 -0
- package/client/dist/assets/jobs-DT5s4fZ6.js +1 -0
- package/client/dist/assets/jobs-DZAgVPcD.js +1 -0
- package/client/dist/assets/jobs-b5gPYaKr.js +1 -0
- package/client/dist/assets/jobs-xsZK1440.js +1 -0
- package/client/dist/assets/launch-forecast-BTa-p3RP.js +1 -0
- package/client/dist/assets/{loop-layout-DtxX27Jz.css → loop-layout-DLioOiRN.css} +1 -1
- package/client/dist/assets/loop-layout-Sl9cfTvs.js +7 -0
- package/client/dist/assets/loops-BEEOVJDR.js +1 -0
- package/client/dist/assets/loops-BcrQ2vk7.js +1 -0
- package/client/dist/assets/loops-BjWxzJIZ.js +1 -0
- package/client/dist/assets/loops-BogV595N.js +1 -0
- package/client/dist/assets/loops-CU0BLZiz.js +1 -0
- package/client/dist/assets/loops-CrNBgi1G.js +1 -0
- package/client/dist/assets/loops-CwalwS_i.js +1 -0
- package/client/dist/assets/loops-_TDVN-fX.js +1 -0
- package/client/dist/assets/mcp-BNs8gxoL.js +1 -0
- package/client/dist/assets/mcp-BvRh_xO5.js +1 -0
- package/client/dist/assets/mcp-C2F1pghi.js +1 -0
- package/client/dist/assets/mcp-D9RLKAs2.js +1 -0
- package/client/dist/assets/mcp-DAghcsR0.js +1 -0
- package/client/dist/assets/mcp-DWWAPi1G.js +1 -0
- package/client/dist/assets/mcp-DbGSFC3f.js +1 -0
- package/client/dist/assets/mcp-FelCicrv.js +1 -0
- package/client/dist/assets/narration-C3NBkAR4.js +1 -0
- package/client/dist/assets/narration-CkoJq-Lf.js +1 -0
- package/client/dist/assets/narration-Cr0NeW9K.js +1 -0
- package/client/dist/assets/narration-DJUXOs-W.js +1 -0
- package/client/dist/assets/narration-DgL8TMvN.js +1 -0
- package/client/dist/assets/narration-DjBafgv0.js +1 -0
- package/client/dist/assets/narration-Dle6Iv0c.js +1 -0
- package/client/dist/assets/narration-MYlfktga.js +1 -0
- package/client/dist/assets/nav-BSQ8KW1c.js +1 -0
- package/client/dist/assets/nav-BauVof8Z.js +1 -0
- package/client/dist/assets/nav-BfOAH1se.js +1 -0
- package/client/dist/assets/nav-D3bOsipX.js +1 -0
- package/client/dist/assets/nav-DOMMhlLx.js +1 -0
- package/client/dist/assets/nav-DPzVlgZU.js +1 -0
- package/client/dist/assets/nav-DZJbFbah.js +1 -0
- package/client/dist/assets/nav-D_5aojd2.js +1 -0
- package/client/dist/assets/notify-error-BsWANx1T.js +1 -0
- package/client/dist/assets/onboarding-BdZQnNm3.js +1 -0
- package/client/dist/assets/onboarding-CJQEv1vp.js +1 -0
- package/client/dist/assets/onboarding-CWJGYUW3.js +1 -0
- package/client/dist/assets/onboarding-ChfYN7dA.js +1 -0
- package/client/dist/assets/onboarding-CjvDUR3V.js +1 -0
- package/client/dist/assets/onboarding-I6vS-zTB.js +1 -0
- package/client/dist/assets/onboarding-dgC_9dTB.js +1 -0
- package/client/dist/assets/onboarding-mlXSyKzX.js +1 -0
- package/client/dist/assets/origin-03nTuaOb.js +1 -0
- package/client/dist/assets/packet-BjpyRnZr.js +1 -0
- package/client/dist/assets/packet-BwgG5mBt.js +1 -0
- package/client/dist/assets/packet-C3eAUFkV.js +1 -0
- package/client/dist/assets/packet-C8wZuSld.js +1 -0
- package/client/dist/assets/packet-CNXEy_85.js +1 -0
- package/client/dist/assets/packet-DsV5Aa_8.js +1 -0
- package/client/dist/assets/packet-aasskOE7.js +1 -0
- package/client/dist/assets/packet-phxCc2gJ.js +1 -0
- package/client/dist/assets/page-header-BStSHkP8.js +1 -0
- package/client/dist/assets/project-repositories-DJPeAVBK.js +1 -0
- package/client/dist/assets/{provider-capabilities-lePfeT_Y.js → provider-capabilities-DtwcTme4.js} +1 -1
- package/client/dist/assets/recovery-BPDOsC92.js +1 -0
- package/client/dist/assets/recovery-BluNHoXM.js +1 -0
- package/client/dist/assets/recovery-CRvEmB0C.js +1 -0
- package/client/dist/assets/recovery-CeIoRnkR.js +1 -0
- package/client/dist/assets/recovery-DHCo8KGi.js +1 -0
- package/client/dist/assets/recovery-OxAIpbBF.js +1 -0
- package/client/dist/assets/recovery-XXexYGOJ.js +1 -0
- package/client/dist/assets/recovery-pITlc--v.js +1 -0
- package/client/dist/assets/refresh-cw-DfyTkbsf.js +1 -0
- package/client/dist/assets/select-xA3pSmqE.js +1 -0
- package/client/dist/assets/settings--yzDbX9r.js +1 -0
- package/client/dist/assets/settings-5_heTv8s.js +1 -0
- package/client/dist/assets/settings-BSf27MDg.js +1 -0
- package/client/dist/assets/settings-BSj6FakR.js +1 -0
- package/client/dist/assets/settings-BZDo_8Nn.js +1 -0
- package/client/dist/assets/settings-BdWgmNc0.js +1 -0
- package/client/dist/assets/settings-DRouxKqb.js +1 -0
- package/client/dist/assets/settings-DnWFoY-F.js +1 -0
- package/client/dist/assets/setup-BJWy62ri.js +1 -0
- package/client/dist/assets/setup-BgKOIuzc.js +1 -0
- package/client/dist/assets/setup-BvVIyUlz.js +1 -0
- package/client/dist/assets/setup-BxCk2pe1.js +1 -0
- package/client/dist/assets/setup-C-xQTL7R.js +1 -0
- package/client/dist/assets/setup-CbaVoiwV.js +1 -0
- package/client/dist/assets/setup-DxTBkX3P.js +1 -0
- package/client/dist/assets/setup-oGoVAzOD.js +1 -0
- package/client/dist/assets/specs-7tAb4IKr.js +1 -0
- package/client/dist/assets/specs-BUcY4s5v.js +1 -0
- package/client/dist/assets/specs-Bk5LeBAA.js +1 -0
- package/client/dist/assets/specs-CAA4Lrlg.js +1 -0
- package/client/dist/assets/specs-CS091AnA.js +1 -0
- package/client/dist/assets/specs-DJ6gmFcK.js +1 -0
- package/client/dist/assets/specs-GfCcrBSC.js +1 -0
- package/client/dist/assets/specs-xQgyc7WL.js +1 -0
- package/client/dist/assets/spending-CVH8VREb.js +1 -0
- package/client/dist/assets/square-Co6h5vZg.js +1 -0
- package/client/dist/assets/tauri-shell-43ixPGfa.js +2 -0
- package/client/dist/assets/terminal-0v9sBylD.js +1 -0
- package/client/dist/assets/terminal-AbUAmCxE.js +1 -0
- package/client/dist/assets/terminal-BJayIbIP.js +1 -0
- package/client/dist/assets/terminal-C2RUlXyi.js +1 -0
- package/client/dist/assets/terminal-CMmSb_Nj.js +1 -0
- package/client/dist/assets/terminal-DKWjj7HJ.js +1 -0
- package/client/dist/assets/terminal-KlFu7_pV.js +1 -0
- package/client/dist/assets/terminal-i99yqFvm.js +1 -0
- package/client/dist/assets/tickets-846Oq3i3.js +1 -0
- package/client/dist/assets/tickets-B5LJTe_b.js +1 -0
- package/client/dist/assets/tickets-Bfo2GGmH.js +1 -0
- package/client/dist/assets/tickets-BhdZ1yY2.js +1 -0
- package/client/dist/assets/tickets-CgjWJHAW.js +1 -0
- package/client/dist/assets/tickets-Ct9DbDUR.js +1 -0
- package/client/dist/assets/tickets-rptLEJB1.js +1 -0
- package/client/dist/assets/tickets-xQ6DpYdu.js +1 -0
- package/client/dist/assets/trending-up-BGvb4zZt.js +1 -0
- package/client/dist/assets/undo-6zuS4-sL.js +1 -0
- package/client/dist/assets/undo-BeM4gDOP.js +1 -0
- package/client/dist/assets/undo-BeppX8xS.js +1 -0
- package/client/dist/assets/undo-BqvNZ5MG.js +1 -0
- package/client/dist/assets/undo-BzwEPf_k.js +1 -0
- package/client/dist/assets/undo-CJ9Cu1NN.js +1 -0
- package/client/dist/assets/undo-ds8nMFbX.js +1 -0
- package/client/dist/assets/undo-x_gA-knG.js +1 -0
- package/client/dist/assets/useDesktop-BuOp2-MR.js +1 -0
- package/client/dist/assets/useRuntimeRuns-BRS6ncnO.js +1 -0
- package/client/dist/assets/utils-ELimjS2Y.js +1 -0
- package/client/dist/assets/wrench-Br2n1Lxd.js +1 -0
- package/client/dist/index.html +75 -60
- package/docs/ci-cd.md +29 -1
- package/docs/cli.md +10 -31
- package/docs/codex.md +1 -1
- package/docs/creating-specs.md +15 -12
- package/docs/customizing.md +16 -13
- package/docs/getting-started.md +12 -11
- package/docs/guide/de/agents/1-meet-the-agents.md +1 -1
- package/docs/guide/de/getting-started/2-installing-and-first-run.md +2 -0
- package/docs/guide/de/getting-started/3-try-the-sample-project.md +35 -0
- package/docs/guide/de/getting-started/{4-the-dashboard-tour.md → 5-the-dashboard-tour.md} +7 -3
- package/docs/guide/de/getting-started/6-universal-search.md +34 -0
- package/docs/guide/de/insights/1-analytics-and-cost-tracking.md +20 -6
- package/docs/guide/de/insights/2-the-integrated-terminal.md +1 -1
- package/docs/guide/de/insights/3-code-explorer.md +1 -1
- package/docs/guide/de/integrations/1-ai-providers.md +1 -1
- package/docs/guide/de/integrations/2-plugins.md +1 -1
- package/docs/guide/de/integrations/3-jira-integration.md +3 -3
- package/docs/guide/de/integrations/4-mobile-companion.md +1 -1
- package/docs/guide/de/integrations/5-mcp-server.md +1 -1
- package/docs/guide/de/integrations/6-agent-chat.md +12 -5
- package/docs/guide/de/integrations/8-flow-mode.md +69 -0
- package/docs/guide/de/pipeline/1-rails-and-jobs.md +21 -1
- package/docs/guide/de/pipeline/2-the-job-detail-view.md +12 -0
- package/docs/guide/de/pipeline/3-reviewing-a-delivery.md +43 -0
- package/docs/guide/de/pipeline/4-picking-an-engine-per-rail.md +2 -2
- package/docs/guide/de/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/de/settings/1-themes.md +1 -1
- package/docs/guide/de/settings/3-pipeline-telemetry-and-diagnostics.md +2 -2
- package/docs/guide/de/settings/5-project-environment.md +1 -1
- package/docs/guide/de/settings/6-updates.md +24 -0
- package/docs/guide/de/settings/7-existing-projects.md +33 -0
- package/docs/guide/de/settings/8-accessibility.md +23 -0
- package/docs/guide/de/specs/1-specs-and-the-backlog.md +41 -3
- package/docs/guide/de/specs/2-add-spec-quick-mode.md +1 -1
- package/docs/guide/de/specs/3-add-spec-explore-mode.md +1 -1
- package/docs/guide/en/agents/1-meet-the-agents.md +1 -1
- package/docs/guide/en/getting-started/1-what-is-specrails.md +1 -1
- package/docs/guide/en/getting-started/2-installing-and-first-run.md +2 -0
- package/docs/guide/en/getting-started/3-try-the-sample-project.md +35 -0
- package/docs/guide/en/getting-started/5-the-dashboard-tour.md +52 -0
- package/docs/guide/en/getting-started/6-universal-search.md +34 -0
- package/docs/guide/en/insights/1-analytics-and-cost-tracking.md +24 -10
- package/docs/guide/en/insights/2-the-integrated-terminal.md +1 -1
- package/docs/guide/en/insights/3-code-explorer.md +5 -5
- package/docs/guide/en/integrations/1-ai-providers.md +1 -1
- package/docs/guide/en/integrations/2-plugins.md +1 -1
- package/docs/guide/en/integrations/3-jira-integration.md +4 -4
- package/docs/guide/en/integrations/4-mobile-companion.md +1 -1
- package/docs/guide/en/integrations/5-mcp-server.md +4 -4
- package/docs/guide/en/integrations/6-agent-chat.md +12 -5
- package/docs/guide/en/integrations/8-flow-mode.md +69 -0
- package/docs/guide/en/pipeline/1-rails-and-jobs.md +22 -3
- package/docs/guide/en/pipeline/2-the-job-detail-view.md +19 -7
- package/docs/guide/en/pipeline/3-reviewing-a-delivery.md +43 -0
- package/docs/guide/en/pipeline/4-picking-an-engine-per-rail.md +2 -2
- package/docs/guide/en/pipeline/5-the-loop-builder.md +2 -2
- package/docs/guide/en/settings/1-themes.md +1 -1
- package/docs/guide/en/settings/3-pipeline-telemetry-and-diagnostics.md +2 -2
- package/docs/guide/en/settings/5-project-environment.md +1 -1
- package/docs/guide/en/settings/6-updates.md +24 -0
- package/docs/guide/en/settings/7-existing-projects.md +33 -0
- package/docs/guide/en/settings/8-accessibility.md +23 -0
- package/docs/guide/en/specs/1-specs-and-the-backlog.md +42 -6
- package/docs/guide/en/specs/2-add-spec-quick-mode.md +1 -1
- package/docs/guide/en/specs/3-add-spec-explore-mode.md +2 -2
- package/docs/guide/es/agents/1-meet-the-agents.md +1 -1
- package/docs/guide/es/agents/2-profiles-and-the-balanced-default.md +1 -1
- package/docs/guide/es/agents/3-customizing-models-per-agent.md +2 -2
- package/docs/guide/es/agents/4-custom-agents-catalog.md +1 -1
- package/docs/guide/es/getting-started/1-what-is-specrails.md +3 -3
- package/docs/guide/es/getting-started/2-installing-and-first-run.md +2 -0
- package/docs/guide/es/getting-started/3-try-the-sample-project.md +35 -0
- package/docs/guide/es/getting-started/5-the-dashboard-tour.md +52 -0
- package/docs/guide/es/getting-started/6-universal-search.md +34 -0
- package/docs/guide/es/insights/1-analytics-and-cost-tracking.md +26 -12
- package/docs/guide/es/insights/2-the-integrated-terminal.md +1 -1
- package/docs/guide/es/insights/3-code-explorer.md +5 -5
- package/docs/guide/es/integrations/1-ai-providers.md +1 -1
- package/docs/guide/es/integrations/2-plugins.md +1 -1
- package/docs/guide/es/integrations/3-jira-integration.md +4 -4
- package/docs/guide/es/integrations/4-mobile-companion.md +1 -1
- package/docs/guide/es/integrations/5-mcp-server.md +4 -4
- package/docs/guide/es/integrations/6-agent-chat.md +14 -7
- package/docs/guide/es/integrations/7-local-engines.md +1 -1
- package/docs/guide/es/integrations/8-flow-mode.md +69 -0
- package/docs/guide/es/pipeline/1-rails-and-jobs.md +33 -13
- package/docs/guide/es/pipeline/2-the-job-detail-view.md +38 -26
- package/docs/guide/es/pipeline/3-reviewing-a-delivery.md +43 -0
- package/docs/guide/es/pipeline/4-picking-an-engine-per-rail.md +2 -2
- package/docs/guide/es/pipeline/5-the-loop-builder.md +4 -4
- package/docs/guide/es/settings/1-themes.md +1 -1
- package/docs/guide/es/settings/3-pipeline-telemetry-and-diagnostics.md +10 -10
- package/docs/guide/es/settings/5-project-environment.md +1 -1
- package/docs/guide/es/settings/6-updates.md +24 -0
- package/docs/guide/es/settings/7-existing-projects.md +33 -0
- package/docs/guide/es/settings/8-accessibility.md +23 -0
- package/docs/guide/es/specs/1-specs-and-the-backlog.md +43 -7
- package/docs/guide/es/specs/2-add-spec-quick-mode.md +1 -1
- package/docs/guide/es/specs/3-add-spec-explore-mode.md +3 -3
- package/docs/guide/fr/agents/1-meet-the-agents.md +1 -1
- package/docs/guide/fr/getting-started/2-installing-and-first-run.md +2 -0
- package/docs/guide/fr/getting-started/3-try-the-sample-project.md +35 -0
- package/docs/guide/fr/getting-started/{4-the-dashboard-tour.md → 5-the-dashboard-tour.md} +7 -3
- package/docs/guide/fr/getting-started/6-universal-search.md +34 -0
- package/docs/guide/fr/insights/1-analytics-and-cost-tracking.md +18 -4
- package/docs/guide/fr/insights/2-the-integrated-terminal.md +1 -1
- package/docs/guide/fr/insights/3-code-explorer.md +1 -1
- package/docs/guide/fr/integrations/1-ai-providers.md +1 -1
- package/docs/guide/fr/integrations/2-plugins.md +1 -1
- package/docs/guide/fr/integrations/3-jira-integration.md +3 -3
- package/docs/guide/fr/integrations/4-mobile-companion.md +1 -1
- package/docs/guide/fr/integrations/5-mcp-server.md +1 -1
- package/docs/guide/fr/integrations/6-agent-chat.md +11 -4
- package/docs/guide/fr/integrations/8-flow-mode.md +69 -0
- package/docs/guide/fr/pipeline/1-rails-and-jobs.md +21 -1
- package/docs/guide/fr/pipeline/2-the-job-detail-view.md +12 -0
- package/docs/guide/fr/pipeline/3-reviewing-a-delivery.md +43 -0
- package/docs/guide/fr/pipeline/4-picking-an-engine-per-rail.md +2 -2
- package/docs/guide/fr/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/fr/settings/1-themes.md +1 -1
- package/docs/guide/fr/settings/3-pipeline-telemetry-and-diagnostics.md +2 -2
- package/docs/guide/fr/settings/5-project-environment.md +1 -1
- package/docs/guide/fr/settings/6-updates.md +24 -0
- package/docs/guide/fr/settings/7-existing-projects.md +33 -0
- package/docs/guide/fr/settings/8-accessibility.md +23 -0
- package/docs/guide/fr/specs/1-specs-and-the-backlog.md +41 -3
- package/docs/guide/fr/specs/2-add-spec-quick-mode.md +1 -1
- package/docs/guide/fr/specs/3-add-spec-explore-mode.md +1 -1
- package/docs/guide/it/agents/1-meet-the-agents.md +1 -1
- package/docs/guide/it/getting-started/2-installing-and-first-run.md +2 -0
- package/docs/guide/it/getting-started/3-try-the-sample-project.md +35 -0
- package/docs/guide/it/getting-started/{4-the-dashboard-tour.md → 5-the-dashboard-tour.md} +7 -3
- package/docs/guide/it/getting-started/6-universal-search.md +34 -0
- package/docs/guide/it/insights/1-analytics-and-cost-tracking.md +18 -4
- package/docs/guide/it/insights/2-the-integrated-terminal.md +1 -1
- package/docs/guide/it/insights/3-code-explorer.md +1 -1
- package/docs/guide/it/integrations/1-ai-providers.md +1 -1
- package/docs/guide/it/integrations/2-plugins.md +1 -1
- package/docs/guide/it/integrations/3-jira-integration.md +3 -3
- package/docs/guide/it/integrations/4-mobile-companion.md +1 -1
- package/docs/guide/it/integrations/5-mcp-server.md +1 -1
- package/docs/guide/it/integrations/6-agent-chat.md +11 -4
- package/docs/guide/it/integrations/8-flow-mode.md +69 -0
- package/docs/guide/it/pipeline/1-rails-and-jobs.md +21 -1
- package/docs/guide/it/pipeline/2-the-job-detail-view.md +12 -0
- package/docs/guide/it/pipeline/3-reviewing-a-delivery.md +43 -0
- package/docs/guide/it/pipeline/4-picking-an-engine-per-rail.md +2 -2
- package/docs/guide/it/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/it/settings/1-themes.md +1 -1
- package/docs/guide/it/settings/3-pipeline-telemetry-and-diagnostics.md +2 -2
- package/docs/guide/it/settings/5-project-environment.md +1 -1
- package/docs/guide/it/settings/6-updates.md +24 -0
- package/docs/guide/it/settings/7-existing-projects.md +33 -0
- package/docs/guide/it/settings/8-accessibility.md +23 -0
- package/docs/guide/it/specs/1-specs-and-the-backlog.md +41 -3
- package/docs/guide/it/specs/2-add-spec-quick-mode.md +1 -1
- package/docs/guide/it/specs/3-add-spec-explore-mode.md +1 -1
- package/docs/guide/ja/agents/1-meet-the-agents.md +1 -1
- package/docs/guide/ja/getting-started/2-installing-and-first-run.md +2 -0
- package/docs/guide/ja/getting-started/3-try-the-sample-project.md +35 -0
- package/docs/guide/ja/getting-started/{4-the-dashboard-tour.md → 5-the-dashboard-tour.md} +7 -3
- package/docs/guide/ja/getting-started/6-universal-search.md +34 -0
- package/docs/guide/ja/insights/1-analytics-and-cost-tracking.md +18 -4
- package/docs/guide/ja/insights/2-the-integrated-terminal.md +1 -1
- package/docs/guide/ja/insights/3-code-explorer.md +1 -1
- package/docs/guide/ja/integrations/1-ai-providers.md +1 -1
- package/docs/guide/ja/integrations/2-plugins.md +1 -1
- package/docs/guide/ja/integrations/3-jira-integration.md +3 -3
- package/docs/guide/ja/integrations/4-mobile-companion.md +1 -1
- package/docs/guide/ja/integrations/5-mcp-server.md +1 -1
- package/docs/guide/ja/integrations/6-agent-chat.md +11 -4
- package/docs/guide/ja/integrations/8-flow-mode.md +69 -0
- package/docs/guide/ja/pipeline/1-rails-and-jobs.md +21 -1
- package/docs/guide/ja/pipeline/2-the-job-detail-view.md +12 -0
- package/docs/guide/ja/pipeline/3-reviewing-a-delivery.md +43 -0
- package/docs/guide/ja/pipeline/4-picking-an-engine-per-rail.md +2 -2
- package/docs/guide/ja/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/ja/settings/1-themes.md +1 -1
- package/docs/guide/ja/settings/3-pipeline-telemetry-and-diagnostics.md +2 -2
- package/docs/guide/ja/settings/5-project-environment.md +1 -1
- package/docs/guide/ja/settings/6-updates.md +24 -0
- package/docs/guide/ja/settings/7-existing-projects.md +33 -0
- package/docs/guide/ja/settings/8-accessibility.md +23 -0
- package/docs/guide/ja/specs/1-specs-and-the-backlog.md +41 -3
- package/docs/guide/ja/specs/2-add-spec-quick-mode.md +1 -1
- package/docs/guide/ja/specs/3-add-spec-explore-mode.md +1 -1
- package/docs/guide/pt/agents/1-meet-the-agents.md +1 -1
- package/docs/guide/pt/getting-started/2-installing-and-first-run.md +2 -0
- package/docs/guide/pt/getting-started/3-try-the-sample-project.md +35 -0
- package/docs/guide/pt/getting-started/{4-the-dashboard-tour.md → 5-the-dashboard-tour.md} +7 -3
- package/docs/guide/pt/getting-started/6-universal-search.md +34 -0
- package/docs/guide/pt/insights/1-analytics-and-cost-tracking.md +18 -4
- package/docs/guide/pt/insights/2-the-integrated-terminal.md +1 -1
- package/docs/guide/pt/insights/3-code-explorer.md +1 -1
- package/docs/guide/pt/integrations/1-ai-providers.md +1 -1
- package/docs/guide/pt/integrations/2-plugins.md +1 -1
- package/docs/guide/pt/integrations/3-jira-integration.md +3 -3
- package/docs/guide/pt/integrations/4-mobile-companion.md +1 -1
- package/docs/guide/pt/integrations/5-mcp-server.md +1 -1
- package/docs/guide/pt/integrations/6-agent-chat.md +12 -5
- package/docs/guide/pt/integrations/8-flow-mode.md +69 -0
- package/docs/guide/pt/pipeline/1-rails-and-jobs.md +21 -1
- package/docs/guide/pt/pipeline/2-the-job-detail-view.md +12 -0
- package/docs/guide/pt/pipeline/3-reviewing-a-delivery.md +43 -0
- package/docs/guide/pt/pipeline/4-picking-an-engine-per-rail.md +2 -2
- package/docs/guide/pt/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/pt/settings/1-themes.md +1 -1
- package/docs/guide/pt/settings/3-pipeline-telemetry-and-diagnostics.md +2 -2
- package/docs/guide/pt/settings/5-project-environment.md +1 -1
- package/docs/guide/pt/settings/6-updates.md +24 -0
- package/docs/guide/pt/settings/7-existing-projects.md +33 -0
- package/docs/guide/pt/settings/8-accessibility.md +23 -0
- package/docs/guide/pt/specs/1-specs-and-the-backlog.md +41 -3
- package/docs/guide/pt/specs/2-add-spec-quick-mode.md +1 -1
- package/docs/guide/pt/specs/3-add-spec-explore-mode.md +1 -1
- package/docs/guide/zh/agents/1-meet-the-agents.md +1 -1
- package/docs/guide/zh/getting-started/2-installing-and-first-run.md +2 -0
- package/docs/guide/zh/getting-started/3-try-the-sample-project.md +35 -0
- package/docs/guide/zh/getting-started/{4-the-dashboard-tour.md → 5-the-dashboard-tour.md} +7 -3
- package/docs/guide/zh/getting-started/6-universal-search.md +34 -0
- package/docs/guide/zh/insights/1-analytics-and-cost-tracking.md +18 -4
- package/docs/guide/zh/insights/2-the-integrated-terminal.md +1 -1
- package/docs/guide/zh/insights/3-code-explorer.md +1 -1
- package/docs/guide/zh/integrations/1-ai-providers.md +1 -1
- package/docs/guide/zh/integrations/2-plugins.md +1 -1
- package/docs/guide/zh/integrations/3-jira-integration.md +3 -3
- package/docs/guide/zh/integrations/4-mobile-companion.md +1 -1
- package/docs/guide/zh/integrations/5-mcp-server.md +1 -1
- package/docs/guide/zh/integrations/6-agent-chat.md +11 -4
- package/docs/guide/zh/integrations/8-flow-mode.md +69 -0
- package/docs/guide/zh/pipeline/1-rails-and-jobs.md +21 -1
- package/docs/guide/zh/pipeline/2-the-job-detail-view.md +12 -0
- package/docs/guide/zh/pipeline/3-reviewing-a-delivery.md +43 -0
- package/docs/guide/zh/pipeline/4-picking-an-engine-per-rail.md +2 -2
- package/docs/guide/zh/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/zh/settings/1-themes.md +1 -1
- package/docs/guide/zh/settings/3-pipeline-telemetry-and-diagnostics.md +2 -2
- package/docs/guide/zh/settings/5-project-environment.md +1 -1
- package/docs/guide/zh/settings/6-updates.md +24 -0
- package/docs/guide/zh/settings/7-existing-projects.md +33 -0
- package/docs/guide/zh/settings/8-accessibility.md +23 -0
- package/docs/guide/zh/specs/1-specs-and-the-backlog.md +41 -3
- package/docs/guide/zh/specs/2-add-spec-quick-mode.md +1 -1
- package/docs/guide/zh/specs/3-add-spec-explore-mode.md +1 -1
- package/docs/internals/README.md +8 -0
- package/docs/internals/adding-a-provider.md +19 -2
- package/docs/internals/agent-actions-audit.md +101 -0
- package/docs/internals/agent-sessions.md +36 -1
- package/docs/internals/api-reference.md +190 -45
- package/docs/internals/architecture.md +53 -47
- package/docs/internals/companion-inbox-decisions.md +42 -0
- package/docs/internals/companion-rails-as-loops-contract.md +17 -6
- package/docs/internals/configuration.md +140 -9
- package/docs/internals/core-runtime-updates.md +4 -4
- package/docs/internals/existing-project-anchoring.md +168 -0
- package/docs/internals/flow-mode.md +668 -0
- package/docs/internals/legacy-implementation-notes.md +13 -0
- package/docs/internals/local-testing-feedback-2026-10.md +210 -0
- package/docs/internals/mcp-mission-audit.md +4 -0
- package/docs/internals/mission-rail-cards.md +10 -5
- package/docs/internals/mission-read-only-policy.md +152 -0
- package/docs/internals/modal-standard.md +181 -0
- package/docs/internals/openspec-workflow.md +32 -0
- package/docs/internals/operations-runbook.md +30 -0
- package/docs/internals/profiles.md +6 -3
- package/docs/internals/programmatic-agent-runtime.md +8 -0
- package/docs/internals/project-builder.md +1 -1
- package/docs/internals/review-packet.md +161 -9
- package/docs/internals/safe-pr-review-flow.md +135 -6
- package/docs/internals/source-map.md +413 -18
- package/docs/internals/spec-addenda.md +10 -0
- package/docs/internals/spec-triage.md +140 -0
- package/docs/internals/visual-design-audit.md +15 -2
- package/docs/local-providers.md +3 -0
- package/docs/mcp.md +21 -3
- package/docs/platforms/macos.md +1 -1
- package/docs/platforms/windows.md +2 -2
- package/docs/running-pipelines.md +22 -6
- package/docs/tracking-cost.md +54 -10
- package/local-runner/dist/specrails-local-runner.js +3851 -1178
- package/mcp-bridge/dist/specrails-mcp.js +3864 -1143
- package/package.json +10 -9
- package/server/dist/agent-mcp-config.js +37 -1
- package/server/dist/api-version.js +19 -0
- package/server/dist/command-resolver.js +4 -2
- package/server/dist/core-compat.js +1 -1
- package/server/dist/core-execution.js +2 -1
- package/server/dist/core-update-manager.js +71 -13
- package/server/dist/db/job-search.js +248 -0
- package/server/dist/db/jobs.js +6 -0
- package/server/dist/db/migrations.js +239 -0
- package/server/dist/db.js +9 -2
- package/server/dist/desktop-db.js +99 -5
- package/server/dist/desktop-router.js +126 -13
- package/server/dist/docs-router.js +67 -1
- package/server/dist/feature-flags.js +22 -0
- package/server/dist/index.js +30 -15
- package/server/dist/jira/jira-adf.js +13 -1
- package/server/dist/jira/jira-clarifications.js +146 -0
- package/server/dist/jira/jira-client.js +8 -1
- package/server/dist/jira/jira-db.js +41 -0
- package/server/dist/jira/jira-sync-manager.js +328 -25
- package/server/dist/mcp/guide.js +17 -7
- package/server/dist/mcp/tools/agents.js +1 -1
- package/server/dist/mcp/tools/analytics.js +15 -3
- package/server/dist/mcp/tools/app-settings.js +14 -1
- package/server/dist/mcp/tools/chat.js +1 -1
- package/server/dist/mcp/tools/env.js +4 -2
- package/server/dist/mcp/tools/jobs.js +96 -7
- package/server/dist/mcp/tools/loops.js +1 -1
- package/server/dist/mcp/tools/meta.js +10 -13
- package/server/dist/mcp/tools/rails.js +15 -1
- package/server/dist/mcp/tools/setup.js +1 -1
- package/server/dist/mcp/tools/specs.js +8 -5
- package/server/dist/mcp/tools/support.js +6 -3
- package/server/dist/mcp/tools/types.js +38 -1
- package/server/dist/mobile/mobile-admin-router.js +0 -16
- package/server/dist/mobile/mobile-gateway.js +0 -18
- package/server/dist/mobile/mobile-inbox.js +240 -0
- package/server/dist/mobile/mobile-missions.js +6 -8
- package/server/dist/mobile/mobile-router.js +9 -9
- package/server/dist/mobile/mobile-webrtc-peer.js +4 -54
- package/server/dist/mobile/mobile-ws.js +27 -4
- package/server/dist/modules/accounting/runtime/ai-invocations.js +4 -0
- package/server/dist/modules/accounting/runtime/decision-times.js +102 -0
- package/server/dist/modules/accounting/runtime/loop-economics.js +284 -0
- package/server/dist/modules/accounting/runtime/spending.js +7 -2
- package/server/dist/modules/accounting/runtime/what-if.js +87 -0
- package/server/dist/modules/agent-runtime/runtime/agent-runtime-bridge.js +86 -5
- package/server/dist/modules/agent-runtime/runtime/agent-runtime-controls.js +28 -2
- package/server/dist/modules/agent-runtime/runtime/agent-runtime-metrics.js +15 -2
- package/server/dist/modules/agent-runtime/runtime/agent-runtime-settings-router.js +21 -2
- package/server/dist/modules/agent-runtime/runtime/core-capabilities.js +55 -0
- package/server/dist/modules/agent-sessions/adapters/host-process.js +1 -1
- package/server/dist/modules/agent-sessions/domain/availability.js +16 -0
- package/server/dist/modules/agent-sessions/domain/protocol.js +8 -1
- package/server/dist/modules/agent-sessions/index.js +3 -1
- package/server/dist/modules/agent-sessions/runtime/core-sessions-availability.js +16 -0
- package/server/dist/modules/agents/runtime/agent-refine-manager.js +3 -1
- package/server/dist/modules/agents/runtime/agent-store.js +60 -73
- package/server/dist/modules/audit/adapters/http.js +66 -0
- package/server/dist/modules/audit/adapters/runtime.js +60 -0
- package/server/dist/modules/audit/adapters/sqlite.js +73 -0
- package/server/dist/modules/audit/application.js +190 -0
- package/server/dist/modules/audit/domain.js +434 -0
- package/server/dist/modules/audit/index.js +27 -0
- package/server/dist/modules/audit/ports.js +2 -0
- package/server/dist/modules/browser/runtime/browser-capture-manager.js +18 -141
- package/server/dist/modules/browser/runtime/browser-capture-types.js +1 -10
- package/server/dist/modules/browser/runtime/browser-playwright.js +0 -19
- package/server/dist/modules/code/runtime/file-provenance.js +23 -0
- package/server/dist/modules/conversations/runtime/chat-manager.js +5 -2
- package/server/dist/modules/delivery/adapters/decisions/chains.js +1 -0
- package/server/dist/modules/delivery/adapters/decisions/create.js +19 -1
- package/server/dist/modules/delivery/adapters/decisions/discard.js +2 -0
- package/server/dist/modules/delivery/adapters/decisions/local-changes.js +427 -0
- package/server/dist/modules/delivery/adapters/decisions/merge-local.js +80 -6
- package/server/dist/modules/delivery/adapters/decisions/observations.js +5 -0
- package/server/dist/modules/delivery/adapters/decisions/ownership.js +2 -1
- package/server/dist/modules/delivery/adapters/decisions/transitions.js +9 -0
- package/server/dist/modules/delivery/adapters/review-wip-store.js +37 -0
- package/server/dist/modules/delivery/domain/review-wip.js +71 -0
- package/server/dist/modules/delivery/index.js +9 -1
- package/server/dist/modules/delivery/runtime/delivery-changes.js +355 -0
- package/server/dist/modules/delivery/runtime/delivery-evidence.js +249 -8
- package/server/dist/modules/delivery/runtime/flow-review-legacy.js +99 -0
- package/server/dist/modules/delivery/runtime/flow-review-outcome.js +107 -0
- package/server/dist/modules/delivery/runtime/flow-worktree-handoff.js +32 -0
- package/server/dist/modules/delivery/runtime/flow-worktree-return.js +87 -0
- package/server/dist/modules/delivery/runtime/isolated-worktree.js +380 -0
- package/server/dist/modules/delivery/runtime/local-restore-branch.js +325 -0
- package/server/dist/modules/delivery/runtime/local-restore-resolver.js +48 -0
- package/server/dist/modules/delivery/runtime/local-stash.js +423 -0
- package/server/dist/modules/delivery/runtime/multi-repo-execution.js +27 -1
- package/server/dist/modules/delivery/runtime/phase3-harvest.js +40 -0
- package/server/dist/modules/delivery/runtime/pr-body.js +50 -0
- package/server/dist/modules/delivery/runtime/rail-isolated-launch.js +169 -166
- package/server/dist/modules/delivery/runtime/rail-launch-parser.js +5 -2
- package/server/dist/modules/delivery/runtime/rail-pr-decision.js +7 -1
- package/server/dist/modules/delivery/runtime/rail-pr-store.js +193 -12
- package/server/dist/modules/delivery/runtime/rails-router.js +267 -5
- package/server/dist/modules/delivery/runtime/review-brief.js +208 -0
- package/server/dist/modules/delivery/runtime/review-packet.js +41 -2
- package/server/dist/modules/delivery/runtime/review-wip-gate.js +67 -0
- package/server/dist/modules/delivery/runtime/run-records.js +267 -0
- package/server/dist/modules/delivery/runtime/run-review-diagnosis.js +102 -0
- package/server/dist/modules/execution/adapters/budget-storage.js +76 -0
- package/server/dist/modules/execution/application/enforce-budget.js +17 -2
- package/server/dist/modules/execution/domain/agent-env.js +98 -0
- package/server/dist/modules/execution/domain/daily-budget.js +36 -0
- package/server/dist/modules/execution/domain/spend-caps.js +166 -0
- package/server/dist/modules/execution/index.js +34 -1
- package/server/dist/modules/execution/runtime/budget-overview.js +76 -0
- package/server/dist/modules/execution/runtime/daily-budget-gate.js +86 -0
- package/server/dist/modules/execution/runtime/interactive-job-session.js +8 -0
- package/server/dist/modules/execution/runtime/launch-forecast.js +33 -0
- package/server/dist/modules/execution/runtime/queue-manager.js +54 -15
- package/server/dist/modules/execution/runtime/run-duration-stats.js +31 -13
- package/server/dist/modules/flow/adapters/bindings.js +1089 -0
- package/server/dist/modules/flow/adapters/http.js +147 -0
- package/server/dist/modules/flow/adapters/sqlite.js +121 -0
- package/server/dist/modules/flow/application.js +805 -0
- package/server/dist/modules/flow/domain.js +790 -0
- package/server/dist/modules/flow/index.js +34 -0
- package/server/dist/modules/flow/ports.js +2 -0
- package/server/dist/modules/inbox/adapters/http.js +21 -0
- package/server/dist/modules/inbox/adapters/project-source.js +233 -0
- package/server/dist/modules/inbox/application.js +28 -0
- package/server/dist/modules/inbox/domain.js +43 -0
- package/server/dist/modules/inbox/index.js +10 -0
- package/server/dist/modules/inbox/ports.js +2 -0
- package/server/dist/modules/loops/runtime/loop-definition-run.js +9 -0
- package/server/dist/modules/loops/runtime/loop-definition.js +5 -2
- package/server/dist/modules/loops/runtime/loop-executors.js +90 -9
- package/server/dist/modules/loops/runtime/loop-factory.js +30 -2
- package/server/dist/modules/loops/runtime/loop-flow-spec-recipe.js +166 -0
- package/server/dist/modules/loops/runtime/loop-graph.js +1 -1
- package/server/dist/modules/loops/runtime/loop-role-engines.js +4 -1
- package/server/dist/modules/loops/runtime/loop-run-manager.js +267 -10
- package/server/dist/modules/loops/runtime/loop-runs-store.js +21 -5
- package/server/dist/modules/loops/runtime/loop-templates.js +55 -12
- package/server/dist/modules/missions/runtime/agent-chat-manager.js +283 -20
- package/server/dist/modules/missions/runtime/agent-chat-router.js +96 -21
- package/server/dist/modules/missions/runtime/agent-failure-briefing.js +11 -3
- package/server/dist/modules/missions/runtime/agent-fence-promotion.js +9 -1
- package/server/dist/modules/missions/runtime/agent-flow-prompt.js +64 -0
- package/server/dist/modules/missions/runtime/agent-input-store.js +9 -4
- package/server/dist/modules/missions/runtime/agent-operator-prompt.js +100 -14
- package/server/dist/modules/missions/runtime/agent-session-store.js +88 -27
- package/server/dist/modules/missions/runtime/core-session-runner.js +89 -9
- package/server/dist/modules/missions/runtime/flow-turn-context.js +17 -0
- package/server/dist/modules/missions/runtime/mission-core-sessions.js +295 -55
- package/server/dist/modules/missions/runtime/mission-run-notify.js +2 -0
- package/server/dist/modules/missions/runtime/mission-session-projector.js +56 -19
- package/server/dist/modules/missions/runtime/mission-tool-policy.js +47 -0
- package/server/dist/modules/onboarding/adapters/http.js +78 -0
- package/server/dist/modules/onboarding/adapters/providers.js +41 -0
- package/server/dist/modules/onboarding/adapters/runtime.js +130 -0
- package/server/dist/modules/onboarding/application.js +133 -0
- package/server/dist/modules/onboarding/catalog.js +217 -0
- package/server/dist/modules/onboarding/domain.js +102 -0
- package/server/dist/modules/onboarding/index.js +20 -0
- package/server/dist/modules/onboarding/ports.js +2 -0
- package/server/dist/modules/project-rules/adapters/http.js +91 -0
- package/server/dist/modules/project-rules/domain.js +122 -0
- package/server/dist/modules/project-rules/runtime/rules-inventory-runs.js +97 -0
- package/server/dist/modules/project-rules/runtime/rules-store.js +109 -0
- package/server/dist/modules/project-settings/adapters/http.js +13 -0
- package/server/dist/modules/project-settings/adapters/sqlite.js +78 -8
- package/server/dist/modules/project-settings/domain.js +47 -1
- package/server/dist/modules/project-settings/index.js +7 -1
- package/server/dist/modules/recovery/adapters/sqlite.js +28 -0
- package/server/dist/modules/recovery/domain.js +162 -0
- package/server/dist/modules/recovery/index.js +16 -0
- package/server/dist/modules/specs/adapters/timeline-http.js +101 -0
- package/server/dist/modules/specs/domain/handoff-labels.js +371 -0
- package/server/dist/modules/specs/domain/handoff.js +260 -0
- package/server/dist/modules/specs/domain/non-goals.js +101 -0
- package/server/dist/modules/specs/domain/timeline.js +164 -0
- package/server/dist/modules/specs/domain/triage.js +320 -0
- package/server/dist/modules/specs/runtime/contract-refine-runner.js +3 -2
- package/server/dist/modules/specs/runtime/generated-spec-parser.js +75 -0
- package/server/dist/modules/specs/runtime/proposal-manager.js +4 -3
- package/server/dist/modules/specs/runtime/smash-runner.js +2 -1
- package/server/dist/modules/specs/runtime/spec-addenda.js +31 -0
- package/server/dist/modules/specs/runtime/spec-draft-parser.js +6 -1
- package/server/dist/modules/specs/runtime/spec-generation.js +431 -0
- package/server/dist/modules/specs/runtime/spec-handoff.js +103 -0
- package/server/dist/modules/specs/runtime/spec-history.js +376 -0
- package/server/dist/modules/specs/runtime/spec-launcher-manager.js +4 -3
- package/server/dist/modules/specs/runtime/spec-search.js +117 -0
- package/server/dist/modules/specs/runtime/ticket-store.js +47 -2
- package/server/dist/modules/specs/runtime/ticket-trash-service.js +62 -0
- package/server/dist/modules/specs/runtime/ticket-trash.js +193 -0
- package/server/dist/modules/specs/runtime/triage-runner.js +171 -0
- package/server/dist/modules/specs/runtime/triage.js +365 -0
- package/server/dist/modules/terminals/domain/app-urls.js +96 -0
- package/server/dist/modules/terminals/runtime/app-urls.js +77 -0
- package/server/dist/modules/terminals/runtime/background-process-service.js +25 -28
- package/server/dist/project-env.js +60 -0
- package/server/dist/project-git.js +65 -0
- package/server/dist/project-registry.js +264 -27
- package/server/dist/project-router-background-processes.js +27 -3
- package/server/dist/project-router-git.js +30 -0
- package/server/dist/project-router-helpers.js +5 -30
- package/server/dist/project-router-jobs.js +49 -1
- package/server/dist/project-router-loop-runs.js +72 -2
- package/server/dist/project-router-rules.js +54 -0
- package/server/dist/project-router-search.js +52 -0
- package/server/dist/project-router-settings.js +6 -0
- package/server/dist/project-router-setup.js +1 -1
- package/server/dist/project-router-spending.js +138 -0
- package/server/dist/project-router-tickets.js +246 -427
- package/server/dist/project-router.js +7 -0
- package/server/dist/providers/claude-adapter.js +25 -3
- package/server/dist/providers/codex-adapter.js +9 -1
- package/server/dist/providers/gemini-adapter.js +6 -1
- package/server/dist/providers/kimi-adapter.js +2 -0
- package/server/dist/providers/local-adapter.js +2 -0
- package/server/dist/providers/runtime.js +8 -0
- package/server/dist/schemas/agent-runtime.schema.json +3 -1
- package/server/dist/schemas/workflow-definition.schema.json +1 -0
- package/server/dist/setup-manager.js +19 -1
- package/server/dist/transient-children.js +25 -8
- package/server/dist/update-channel.js +21 -0
- package/server/dist/util/search-snippet.js +74 -0
- package/server/dist/worktree-manager.js +19 -8
- package/client/dist/assets/ActivityFeedPage-Dtp7EyHc.js +0 -1
- package/client/dist/assets/AgentBrowserCapture-CLqlEFw8.js +0 -1
- package/client/dist/assets/AgentModeAnalyticsPane-B8_hM3Tw.js +0 -2
- package/client/dist/assets/AgentModeCodePane-CNF8ZNjE.js +0 -2
- package/client/dist/assets/AgentModeJobsPane-CJpJbO9m.js +0 -1
- package/client/dist/assets/AgentsPage-BC8XSR79.js +0 -120
- package/client/dist/assets/AnalyticsPage-Cdv4jLtW.js +0 -1
- package/client/dist/assets/BarChart-BDMqVFJy.js +0 -55
- package/client/dist/assets/CodePage-DI1kegAr.js +0 -3
- package/client/dist/assets/DesktopAnalyticsPage-Bdp8E8U6.js +0 -1
- package/client/dist/assets/DocsDialog-Bm4RS7FX.js +0 -11
- package/client/dist/assets/DocsPage-DihYcU8r.js +0 -11
- package/client/dist/assets/ExportDropdown-Bb1lHx3r.js +0 -1
- package/client/dist/assets/IntegrationsPage-EAipiDWm.js +0 -1
- package/client/dist/assets/InteractiveJobComposer-BO6ASN-2.js +0 -19
- package/client/dist/assets/JobDetailModal-CuPYq7tP.js +0 -1
- package/client/dist/assets/JobDetailPage-BusMjJi9.js +0 -1
- package/client/dist/assets/JobsPage-C0QbsF2d.js +0 -1
- package/client/dist/assets/LoopBuilderPage-B7TlU4iS.js +0 -1
- package/client/dist/assets/LoopPreviewModal-BRWtXOD2.js +0 -1
- package/client/dist/assets/LoopsPage-C4q1DmCE.js +0 -2
- package/client/dist/assets/MinimizedChatsContext-DHfigjHS.js +0 -1
- package/client/dist/assets/PluginsPage-Z1JHSMdR.js +0 -2
- package/client/dist/assets/ProjectSettingsDialog-BUNj0tvN.js +0 -1
- package/client/dist/assets/RepositoryDeliveries-B4ybHOyB.js +0 -5
- package/client/dist/assets/ReviewPacketPage-hwfPNjyy.js +0 -4
- package/client/dist/assets/TemplatePreviewModal-V7FpMWuw.js +0 -1
- package/client/dist/assets/TicketDetailModalContext-Dkwo2cDs.js +0 -16
- package/client/dist/assets/Trans-BbFxRFtR.js +0 -1
- package/client/dist/assets/activity-B-rp4h_v.js +0 -1
- package/client/dist/assets/activity-C6kJpm9q.js +0 -1
- package/client/dist/assets/activity-CGx4kb_j.js +0 -1
- package/client/dist/assets/activity-CnoX2bH7.js +0 -1
- package/client/dist/assets/activity-DAyekdlt.js +0 -1
- package/client/dist/assets/activity-DCxtpT7j.js +0 -1
- package/client/dist/assets/activity-DiyjsgQV.js +0 -1
- package/client/dist/assets/activity-JzwRaWPD.js +0 -1
- package/client/dist/assets/addspec-BOvgmcgk.js +0 -1
- package/client/dist/assets/addspec-Clmyfn_R.js +0 -1
- package/client/dist/assets/addspec-CsNaBpHp.js +0 -1
- package/client/dist/assets/addspec-D2tvWmmV.js +0 -1
- package/client/dist/assets/addspec-D3nFwvD0.js +0 -1
- package/client/dist/assets/addspec-DVLEhK3w.js +0 -1
- package/client/dist/assets/addspec-DXbK-tb0.js +0 -1
- package/client/dist/assets/addspec-OHG8DFEn.js +0 -1
- package/client/dist/assets/agent-5bSixVzz.js +0 -1
- package/client/dist/assets/agent-BR4EHfhq.js +0 -1
- package/client/dist/assets/agent-C0IKkJP8.js +0 -1
- package/client/dist/assets/agent-C7li9ayC.js +0 -1
- package/client/dist/assets/agent-D0dRmEen.js +0 -1
- package/client/dist/assets/agent-DZVGHm7H.js +0 -1
- package/client/dist/assets/agent-Dip4h2YE.js +0 -1
- package/client/dist/assets/agent-Pp-P-n1p.js +0 -1
- package/client/dist/assets/agentRuntime-BxF81z52.js +0 -1
- package/client/dist/assets/agentRuntime-BxYS5V7u.js +0 -1
- package/client/dist/assets/agentRuntime-Dc9HG3BA.js +0 -1
- package/client/dist/assets/agents-B6ZsnARo.js +0 -1
- package/client/dist/assets/agents-BORdhe0K.js +0 -1
- package/client/dist/assets/agents-C6aq9Oqs.js +0 -1
- package/client/dist/assets/agents-Cbsc4bcX.js +0 -1
- package/client/dist/assets/agents-D0uYR6hq.js +0 -1
- package/client/dist/assets/agents-Doe1sHY5.js +0 -1
- package/client/dist/assets/agents-DyNi_I9m.js +0 -1
- package/client/dist/assets/agents-StKxiTg0.js +0 -1
- package/client/dist/assets/agentstudio-7cYCXn-L.js +0 -1
- package/client/dist/assets/agentstudio-BHWQh8G3.js +0 -1
- package/client/dist/assets/agentstudio-BjnWHyRs.js +0 -1
- package/client/dist/assets/agentstudio-BkV8vcK4.js +0 -1
- package/client/dist/assets/agentstudio-BzugqB_N.js +0 -1
- package/client/dist/assets/agentstudio-CWbp7KvH.js +0 -1
- package/client/dist/assets/agentstudio-DG6plf5o.js +0 -1
- package/client/dist/assets/agentstudio-DkZVF-Cc.js +0 -1
- package/client/dist/assets/analytics-B1DIQd4m.js +0 -1
- package/client/dist/assets/analytics-BAIZ9vE_.js +0 -1
- package/client/dist/assets/analytics-BTqgmgBd.js +0 -1
- package/client/dist/assets/analytics-BWynXPEm.js +0 -1
- package/client/dist/assets/analytics-DGcUsQ44.js +0 -1
- package/client/dist/assets/analytics-GnSnpJ4W.js +0 -1
- package/client/dist/assets/analytics-TWgYaoO0.js +0 -1
- package/client/dist/assets/analytics-kJy6Tuko.js +0 -1
- package/client/dist/assets/atom-one-dark-qiGhVQxg.js +0 -1
- package/client/dist/assets/builder-B9gorTnT.js +0 -1
- package/client/dist/assets/builder-Bvw5s3Mi.js +0 -1
- package/client/dist/assets/builder-CL5l4dU3.js +0 -1
- package/client/dist/assets/builder-CVDTVrQX.js +0 -1
- package/client/dist/assets/builder-CpS9liE9.js +0 -1
- package/client/dist/assets/builder-DNctIL9Q.js +0 -1
- package/client/dist/assets/builder-De2NxX6o.js +0 -1
- package/client/dist/assets/builder-DeYT7Y-m.js +0 -1
- package/client/dist/assets/button-4FS1ZDTp.js +0 -1
- package/client/dist/assets/chat-D_I7nU5K.js +0 -1
- package/client/dist/assets/chevron-up-6EFqEHBj.js +0 -1
- package/client/dist/assets/chunk-OB3PAWPO-B1EMk45A.js +0 -3
- package/client/dist/assets/clsx-CjueKrWZ.js +0 -1
- package/client/dist/assets/code-B37GRg9C.js +0 -1
- package/client/dist/assets/code-BBOEZbf9.js +0 -1
- package/client/dist/assets/code-BRm-jcyx.js +0 -1
- package/client/dist/assets/code-CF7w62CR.js +0 -1
- package/client/dist/assets/code-CLuvJt2r.js +0 -1
- package/client/dist/assets/code-D0RCm59f.js +0 -1
- package/client/dist/assets/code-DaZ-ZwCT.js +0 -1
- package/client/dist/assets/code-iIHkGaCL.js +0 -1
- package/client/dist/assets/commands-0XjAftla.js +0 -1
- package/client/dist/assets/commands-BAWSYHjQ.js +0 -1
- package/client/dist/assets/commands-BBwowgiE.js +0 -1
- package/client/dist/assets/commands-BacjIZLN.js +0 -1
- package/client/dist/assets/commands-Bs62IAZ3.js +0 -1
- package/client/dist/assets/commands-CLPdh-Hh.js +0 -1
- package/client/dist/assets/commands-DlbFzgrp.js +0 -1
- package/client/dist/assets/commands-LjPSsi5F.js +0 -1
- package/client/dist/assets/common-Bdi0qN4S.js +0 -1
- package/client/dist/assets/common-Bhb9zN1P.js +0 -1
- package/client/dist/assets/common-BykKlZg1.js +0 -1
- package/client/dist/assets/common-CvnNNSJA.js +0 -1
- package/client/dist/assets/common-D5zk_mqq.js +0 -1
- package/client/dist/assets/common-DQNO_al5.js +0 -1
- package/client/dist/assets/common-Dax30Vmp.js +0 -1
- package/client/dist/assets/common-DkllpVSb.js +0 -1
- package/client/dist/assets/core-B3mKBIh5.js +0 -1
- package/client/dist/assets/dashboard-B1ndRHuC.js +0 -1
- package/client/dist/assets/dashboard-BX7KXiqA.js +0 -1
- package/client/dist/assets/dashboard-B_BSNxcN.js +0 -1
- package/client/dist/assets/dashboard-CCeFN7-V.js +0 -1
- package/client/dist/assets/dashboard-CRl0WtFJ.js +0 -1
- package/client/dist/assets/dashboard-XGdQ5mjw.js +0 -1
- package/client/dist/assets/dashboard-_oltA6Jd.js +0 -1
- package/client/dist/assets/dashboard-bAuf5KVk.js +0 -1
- package/client/dist/assets/dialog-DtdR05v1.js +0 -45
- package/client/dist/assets/dist-js-CJ_2XX1Y.js +0 -1
- package/client/dist/assets/event-Bt7f3wXe.js +0 -1
- package/client/dist/assets/explore-BG99VGpL.js +0 -1
- package/client/dist/assets/explore-C0TjprJW.js +0 -1
- package/client/dist/assets/explore-C2dgEo7q.js +0 -1
- package/client/dist/assets/explore-C8NDHbob.js +0 -1
- package/client/dist/assets/explore-CWWgzQGR.js +0 -1
- package/client/dist/assets/explore-CcQXpdtS.js +0 -1
- package/client/dist/assets/explore-DgBACn39.js +0 -1
- package/client/dist/assets/explore-DsXAgnmJ.js +0 -1
- package/client/dist/assets/file-text-C0blZHLh.js +0 -1
- package/client/dist/assets/formatDistanceToNow-NjPHBLfB.js +0 -1
- package/client/dist/assets/getTimezoneOffsetInMilliseconds-vJ7qUoqN.js +0 -1
- package/client/dist/assets/git-branch-yf6LE1Bw.js +0 -1
- package/client/dist/assets/index-BgbCbIua.css +0 -2
- package/client/dist/assets/index-Ce4yZtKf.js +0 -83
- package/client/dist/assets/integrations-BkpRUbvp.js +0 -1
- package/client/dist/assets/integrations-Bo8qbJf4.js +0 -1
- package/client/dist/assets/integrations-CmSrKzZb.js +0 -1
- package/client/dist/assets/integrations-DGtq26Rr.js +0 -1
- package/client/dist/assets/integrations-De38GFnQ.js +0 -1
- package/client/dist/assets/integrations-Dw6zdtb-.js +0 -1
- package/client/dist/assets/integrations-Dwl9KQp0.js +0 -1
- package/client/dist/assets/integrations-Refg_d2I.js +0 -1
- package/client/dist/assets/jira-B6OYw4CJ.js +0 -1
- package/client/dist/assets/jira-BTF6RaOe.js +0 -1
- package/client/dist/assets/jira-CEetIB2q.js +0 -1
- package/client/dist/assets/jira-CIzsZLw5.js +0 -1
- package/client/dist/assets/jira-Daw9tmpI.js +0 -1
- package/client/dist/assets/jira-FXr7u2lh.js +0 -1
- package/client/dist/assets/jira-LaNQn7yl.js +0 -1
- package/client/dist/assets/jira-api-Cabj-H0J.js +0 -1
- package/client/dist/assets/job-time-BCL7wee9.js +0 -1
- package/client/dist/assets/jobs-ARwD85B9.js +0 -1
- package/client/dist/assets/jobs-BMF1w4WT.js +0 -1
- package/client/dist/assets/jobs-CBfzGLwm.js +0 -1
- package/client/dist/assets/jobs-CPjiluBY.js +0 -1
- package/client/dist/assets/jobs-CQQd58pY.js +0 -1
- package/client/dist/assets/jobs-De3EqaO0.js +0 -1
- package/client/dist/assets/jobs-Du9-Ei9a.js +0 -1
- package/client/dist/assets/jobs-qMHbnxwC.js +0 -1
- package/client/dist/assets/layers-BCLTgHXO.js +0 -1
- package/client/dist/assets/loader-circle-BqV9xYGf.js +0 -1
- package/client/dist/assets/loop-layout-CyXj9223.js +0 -7
- package/client/dist/assets/loops-B2PhQLKR.js +0 -1
- package/client/dist/assets/loops-BqbF46st.js +0 -1
- package/client/dist/assets/loops-CINnHbfI.js +0 -1
- package/client/dist/assets/loops-D-3XhH04.js +0 -1
- package/client/dist/assets/loops-DKkEEjZ_.js +0 -1
- package/client/dist/assets/loops-DzWR5-v6.js +0 -1
- package/client/dist/assets/loops-WyWDkhok.js +0 -1
- package/client/dist/assets/loops-scD5fIBf.js +0 -1
- package/client/dist/assets/mcp-6rMoZfEO.js +0 -1
- package/client/dist/assets/mcp-BD8sL5mP.js +0 -1
- package/client/dist/assets/mcp-BkcA3I5s.js +0 -1
- package/client/dist/assets/mcp-CCpSelOh.js +0 -1
- package/client/dist/assets/mcp-CUAN6ORK.js +0 -1
- package/client/dist/assets/mcp-CqbRxRTE.js +0 -1
- package/client/dist/assets/mcp-DP2YfVhO.js +0 -1
- package/client/dist/assets/mcp-DUVQamDz.js +0 -1
- package/client/dist/assets/narration-BEKMVxGm.js +0 -1
- package/client/dist/assets/narration-CjLwGKap.js +0 -1
- package/client/dist/assets/narration-DANWuGsW.js +0 -1
- package/client/dist/assets/narration-DGeEDWiT.js +0 -1
- package/client/dist/assets/narration-DJgpGwIP.js +0 -1
- package/client/dist/assets/narration-DbHnz0qV.js +0 -1
- package/client/dist/assets/narration-bZSsTZG8.js +0 -1
- package/client/dist/assets/narration-i6aKJKEc.js +0 -1
- package/client/dist/assets/nav--u7iPYlS.js +0 -1
- package/client/dist/assets/nav-C5Jgfaby.js +0 -1
- package/client/dist/assets/nav-CAna_Wpt.js +0 -1
- package/client/dist/assets/nav-CCLqeyHo.js +0 -1
- package/client/dist/assets/nav-Cf3c90Jk.js +0 -1
- package/client/dist/assets/nav-DMYQaQjR.js +0 -1
- package/client/dist/assets/nav-Df_PkZ9F.js +0 -1
- package/client/dist/assets/nav-VyNGBJwj.js +0 -1
- package/client/dist/assets/packet-8nn9RsU7.js +0 -1
- package/client/dist/assets/packet-B0H15elv.js +0 -1
- package/client/dist/assets/packet-BQvBgrwh.js +0 -1
- package/client/dist/assets/packet-BR7mO0-a.js +0 -1
- package/client/dist/assets/packet-BgcQ6q_K.js +0 -1
- package/client/dist/assets/packet-D2s92Jnn.js +0 -1
- package/client/dist/assets/packet-YbtcD1HS.js +0 -1
- package/client/dist/assets/packet-c0Qj_9eX.js +0 -1
- package/client/dist/assets/project-repositories-Cnnuj9Ia.js +0 -1
- package/client/dist/assets/rotate-ccw-DalJAQQX.js +0 -1
- package/client/dist/assets/settings-B1NV8Ow9.js +0 -1
- package/client/dist/assets/settings-BQ8XFZeE.js +0 -1
- package/client/dist/assets/settings-BRkxfBbO.js +0 -1
- package/client/dist/assets/settings-C_CcU1dP.js +0 -1
- package/client/dist/assets/settings-Cto9n0eL.js +0 -1
- package/client/dist/assets/settings-Pyw8uYtL.js +0 -1
- package/client/dist/assets/settings-b3HVCNNd.js +0 -1
- package/client/dist/assets/settings-hdive4u6.js +0 -1
- package/client/dist/assets/setup-Be485n2u.js +0 -1
- package/client/dist/assets/setup-CKGUxKr-.js +0 -1
- package/client/dist/assets/setup-Ck1Uwd7_.js +0 -1
- package/client/dist/assets/setup-Cm774a6v.js +0 -1
- package/client/dist/assets/setup-DIqMQpxt.js +0 -1
- package/client/dist/assets/setup-DfCsoNFL.js +0 -1
- package/client/dist/assets/setup-DkeE8mP0.js +0 -1
- package/client/dist/assets/setup-xVntVaz1.js +0 -1
- package/client/dist/assets/specs-Bqvtz2kz.js +0 -1
- package/client/dist/assets/specs-CKes-kz6.js +0 -1
- package/client/dist/assets/specs-CfXxPDNB.js +0 -1
- package/client/dist/assets/specs-CyF9HuTI.js +0 -1
- package/client/dist/assets/specs-DMj035Mt.js +0 -1
- package/client/dist/assets/specs-DfIdoU5L.js +0 -1
- package/client/dist/assets/specs-j5pGLQeU.js +0 -1
- package/client/dist/assets/specs-xW5pkkB7.js +0 -1
- package/client/dist/assets/spending-CQnrWiR3.js +0 -1
- package/client/dist/assets/square-D0JTbRSR.js +0 -1
- package/client/dist/assets/tauri-shell-DE6LfGPw.js +0 -2
- package/client/dist/assets/terminal-BAzpHtpY.js +0 -1
- package/client/dist/assets/terminal-C7dHeR3x.js +0 -1
- package/client/dist/assets/terminal-CMla5Qsz.js +0 -1
- package/client/dist/assets/terminal-CdNXH-n9.js +0 -1
- package/client/dist/assets/terminal-Cw5bZsmV.js +0 -1
- package/client/dist/assets/terminal-DFUP4eNv.js +0 -1
- package/client/dist/assets/terminal-DGqljeK_.js +0 -1
- package/client/dist/assets/terminal-cU70NodO.js +0 -1
- package/client/dist/assets/tickets--tiSOCcn.js +0 -1
- package/client/dist/assets/tickets-BUJ3DMWU.js +0 -1
- package/client/dist/assets/tickets-C1WNPODq.js +0 -1
- package/client/dist/assets/tickets-CDjhWmiE.js +0 -1
- package/client/dist/assets/tickets-CLgPC3uO.js +0 -1
- package/client/dist/assets/tickets-D41ZMQpf.js +0 -1
- package/client/dist/assets/tickets-DEaQC06P.js +0 -1
- package/client/dist/assets/tickets-kcMzbLCp.js +0 -1
- package/client/dist/assets/trash-D8zYUmTg.js +0 -1
- package/client/dist/assets/useDesktop-BjLT0_EE.js +0 -1
- package/client/dist/assets/useRuntimeRuns-C97qEqMg.js +0 -1
- package/client/dist/assets/useSharedWebSocket-Bj4LMp7b.js +0 -2
- package/client/dist/assets/utils-BC4DHlz2.js +0 -1
- package/docs/guide/en/getting-started/4-the-dashboard-tour.md +0 -48
- package/docs/guide/es/getting-started/4-the-dashboard-tour.md +0 -48
- package/server/dist/mobile/mobile-preview-channel.js +0 -179
- package/server/dist/mobile/mobile-preview.js +0 -366
- package/server/dist/modules/browser/domain/preview-origins.js +0 -117
- package/server/dist/modules/browser/runtime/preview-targets.js +0 -80
- /package/client/dist/assets/{atom-one-dark-B-oHczHB.css → DocView-B-oHczHB.css} +0 -0
- /package/docs/guide/de/getting-started/{3-adding-your-first-project.md → 4-adding-your-first-project.md} +0 -0
- /package/docs/guide/en/getting-started/{3-adding-your-first-project.md → 4-adding-your-first-project.md} +0 -0
- /package/docs/guide/es/getting-started/{3-adding-your-first-project.md → 4-adding-your-first-project.md} +0 -0
- /package/docs/guide/fr/getting-started/{3-adding-your-first-project.md → 4-adding-your-first-project.md} +0 -0
- /package/docs/guide/it/getting-started/{3-adding-your-first-project.md → 4-adding-your-first-project.md} +0 -0
- /package/docs/guide/ja/getting-started/{3-adding-your-first-project.md → 4-adding-your-first-project.md} +0 -0
- /package/docs/guide/pt/getting-started/{3-adding-your-first-project.md → 4-adding-your-first-project.md} +0 -0
- /package/docs/guide/zh/getting-started/{3-adding-your-first-project.md → 4-adding-your-first-project.md} +0 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SAMPLE_CATALOG = exports.TIC_TAC_TOE = void 0;
|
|
4
|
+
const LOGIC_JS = `// Pure game rules: no DOM, so they are easy to test.
|
|
5
|
+
export const LINES = [
|
|
6
|
+
[0, 1, 2], [3, 4, 5], [6, 7, 8],
|
|
7
|
+
[0, 3, 6], [1, 4, 7], [2, 5, 8],
|
|
8
|
+
[0, 4, 8], [2, 4, 6],
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
export function winner(board) {
|
|
12
|
+
for (const [a, b, c] of LINES) {
|
|
13
|
+
if (board[a] && board[a] === board[b] && board[a] === board[c]) return board[a]
|
|
14
|
+
}
|
|
15
|
+
return null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function isDraw(board) {
|
|
19
|
+
return board.every(Boolean) && winner(board) === null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function nextPlayer(board) {
|
|
23
|
+
const x = board.filter((cell) => cell === 'X').length
|
|
24
|
+
const o = board.filter((cell) => cell === 'O').length
|
|
25
|
+
return x <= o ? 'X' : 'O'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function play(board, index) {
|
|
29
|
+
if (board[index] || winner(board)) return board
|
|
30
|
+
const next = board.slice()
|
|
31
|
+
next[index] = nextPlayer(board)
|
|
32
|
+
return next
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
const GAME_JS = `import { isDraw, nextPlayer, play, winner } from './logic.js'
|
|
36
|
+
|
|
37
|
+
let board = Array(9).fill(null)
|
|
38
|
+
|
|
39
|
+
const boardEl = document.getElementById('board')
|
|
40
|
+
const statusEl = document.getElementById('status')
|
|
41
|
+
|
|
42
|
+
function statusText() {
|
|
43
|
+
const won = winner(board)
|
|
44
|
+
if (won) return 'Player ' + won + ' wins'
|
|
45
|
+
if (isDraw(board)) return 'It is a draw'
|
|
46
|
+
return 'Player ' + nextPlayer(board) + ' to move'
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function render() {
|
|
50
|
+
boardEl.innerHTML = ''
|
|
51
|
+
board.forEach((cell, index) => {
|
|
52
|
+
const button = document.createElement('button')
|
|
53
|
+
button.className = 'cell'
|
|
54
|
+
button.type = 'button'
|
|
55
|
+
button.textContent = cell || ''
|
|
56
|
+
button.setAttribute('aria-label', 'Cell ' + (index + 1))
|
|
57
|
+
button.addEventListener('click', () => {
|
|
58
|
+
board = play(board, index)
|
|
59
|
+
render()
|
|
60
|
+
})
|
|
61
|
+
boardEl.appendChild(button)
|
|
62
|
+
})
|
|
63
|
+
statusEl.textContent = statusText()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
render()
|
|
67
|
+
`;
|
|
68
|
+
const INDEX_HTML = `<!doctype html>
|
|
69
|
+
<html lang="en">
|
|
70
|
+
<head>
|
|
71
|
+
<meta charset="utf-8" />
|
|
72
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
73
|
+
<title>Tic-tac-toe</title>
|
|
74
|
+
<link rel="stylesheet" href="style.css" />
|
|
75
|
+
</head>
|
|
76
|
+
<body>
|
|
77
|
+
<main>
|
|
78
|
+
<h1>Tic-tac-toe</h1>
|
|
79
|
+
<p id="status" role="status"></p>
|
|
80
|
+
<div id="board" class="board"></div>
|
|
81
|
+
</main>
|
|
82
|
+
<script type="module" src="game.js"></script>
|
|
83
|
+
</body>
|
|
84
|
+
</html>
|
|
85
|
+
`;
|
|
86
|
+
const STYLE_CSS = `body { font-family: system-ui, sans-serif; display: grid; place-items: center; min-height: 100vh; margin: 0; background: #14151f; color: #eceefa; }
|
|
87
|
+
main { text-align: center; }
|
|
88
|
+
.board { display: grid; grid-template-columns: repeat(3, 5.5rem); gap: 0.5rem; justify-content: center; }
|
|
89
|
+
.cell { height: 5.5rem; font-size: 2.25rem; border-radius: 0.5rem; border: 1px solid #3a3d55; background: #1d1f2e; color: inherit; cursor: pointer; }
|
|
90
|
+
.cell:hover { background: #262941; }
|
|
91
|
+
`;
|
|
92
|
+
const LOGIC_TEST_JS = `import test from 'node:test'
|
|
93
|
+
import assert from 'node:assert/strict'
|
|
94
|
+
import { isDraw, nextPlayer, play, winner } from './logic.js'
|
|
95
|
+
|
|
96
|
+
test('X moves first and players alternate', () => {
|
|
97
|
+
const empty = Array(9).fill(null)
|
|
98
|
+
assert.equal(nextPlayer(empty), 'X')
|
|
99
|
+
assert.equal(nextPlayer(play(empty, 0)), 'O')
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('a taken cell cannot be played again', () => {
|
|
103
|
+
const once = play(Array(9).fill(null), 4)
|
|
104
|
+
assert.deepEqual(play(once, 4), once)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
test('three in a row wins and ends the game', () => {
|
|
108
|
+
const board = ['X', 'X', 'X', 'O', 'O', null, null, null, null]
|
|
109
|
+
assert.equal(winner(board), 'X')
|
|
110
|
+
assert.deepEqual(play(board, 8), board)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
test('a full board without a winner is a draw', () => {
|
|
114
|
+
const board = ['X', 'O', 'X', 'X', 'O', 'O', 'O', 'X', 'X']
|
|
115
|
+
assert.equal(winner(board), null)
|
|
116
|
+
assert.equal(isDraw(board), true)
|
|
117
|
+
})
|
|
118
|
+
`;
|
|
119
|
+
const PACKAGE_JSON = `{
|
|
120
|
+
"name": "tic-tac-toe",
|
|
121
|
+
"version": "1.0.0",
|
|
122
|
+
"private": true,
|
|
123
|
+
"type": "module",
|
|
124
|
+
"description": "A tiny browser game used as the Specrails sample project.",
|
|
125
|
+
"scripts": {
|
|
126
|
+
"test": "node --test"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
`;
|
|
130
|
+
const README_MD = `# Tic-tac-toe
|
|
131
|
+
|
|
132
|
+
A tiny browser game, bundled with Specrails Desktop as a sample project.
|
|
133
|
+
|
|
134
|
+
- \`logic.js\` holds the rules (pure functions), \`logic.test.js\` tests them.
|
|
135
|
+
- \`game.js\`, \`index.html\` and \`style.css\` draw the board.
|
|
136
|
+
|
|
137
|
+
Run the tests with \`npm test\`. Open \`index.html\` in a browser to play.
|
|
138
|
+
`;
|
|
139
|
+
const GITIGNORE = `node_modules/
|
|
140
|
+
.specrails/
|
|
141
|
+
.DS_Store
|
|
142
|
+
`;
|
|
143
|
+
const RESTART = {
|
|
144
|
+
en: { title: 'Add a Restart button', summary: 'Let players start a new game without reloading the page.',
|
|
145
|
+
description: 'Add a "Restart" button under the board. Pressing it clears all nine cells and starts a new game with X to move.\n\nKeep the rule in logic.js (for example a newBoard() function) and cover it with a test in logic.test.js.\n\nAcceptance: after Restart the board is empty and the status line says it is X\'s turn; npm test passes.' },
|
|
146
|
+
es: { title: 'Añadir un botón Reiniciar', summary: 'Permite empezar una partida nueva sin recargar la página.',
|
|
147
|
+
description: 'Añade un botón "Reiniciar" bajo el tablero. Al pulsarlo se vacían las nueve casillas y empieza una partida nueva con el turno de X.\n\nMantén la regla en logic.js (por ejemplo una función newBoard()) y cúbrela con un test en logic.test.js.\n\nCriterio de aceptación: tras Reiniciar el tablero está vacío y el estado indica que le toca a X; npm test pasa.' },
|
|
148
|
+
fr: { title: 'Ajouter un bouton Recommencer', summary: 'Permet de lancer une nouvelle partie sans recharger la page.',
|
|
149
|
+
description: 'Ajoute un bouton "Recommencer" sous le plateau. Un clic vide les neuf cases et lance une nouvelle partie avec X qui joue en premier.\n\nGarde la règle dans logic.js (par exemple une fonction newBoard()) et couvre-la par un test dans logic.test.js.\n\nCritère d\'acceptation : après Recommencer, le plateau est vide et le statut indique que c\'est à X de jouer ; npm test réussit.' },
|
|
150
|
+
de: { title: 'Neustart-Button hinzufügen', summary: 'Ein neues Spiel starten, ohne die Seite neu zu laden.',
|
|
151
|
+
description: 'Füge unter dem Spielfeld einen Button "Neustart" hinzu. Ein Klick leert alle neun Felder und startet ein neues Spiel, in dem X beginnt.\n\nHalte die Regel in logic.js (zum Beispiel eine Funktion newBoard()) und decke sie mit einem Test in logic.test.js ab.\n\nAkzeptanzkriterium: Nach dem Neustart ist das Feld leer und die Statuszeile zeigt, dass X am Zug ist; npm test läuft durch.' },
|
|
152
|
+
pt: { title: 'Adicionar um botão Reiniciar', summary: 'Permite começar um novo jogo sem recarregar a página.',
|
|
153
|
+
description: 'Adiciona um botão "Reiniciar" abaixo do tabuleiro. Ao clicar, as nove casas ficam vazias e começa um novo jogo com a vez do X.\n\nMantém a regra em logic.js (por exemplo uma função newBoard()) e cobre-a com um teste em logic.test.js.\n\nCritério de aceitação: depois de Reiniciar o tabuleiro está vazio e o estado indica que é a vez do X; npm test passa.' },
|
|
154
|
+
it: { title: 'Aggiungere un pulsante Ricomincia', summary: 'Permette di iniziare una nuova partita senza ricaricare la pagina.',
|
|
155
|
+
description: 'Aggiungi un pulsante "Ricomincia" sotto la griglia. Premendolo si svuotano le nove caselle e inizia una nuova partita con il turno di X.\n\nMantieni la regola in logic.js (per esempio una funzione newBoard()) e coprila con un test in logic.test.js.\n\nCriterio di accettazione: dopo Ricomincia la griglia è vuota e lo stato indica che tocca a X; npm test passa.' },
|
|
156
|
+
zh: { title: '添加“重新开始”按钮', summary: '无需刷新页面即可开始新一局。',
|
|
157
|
+
description: '在棋盘下方添加“重新开始”按钮。点击后清空九个格子,并以 X 先手开始新的一局。\n\n把规则放在 logic.js 中(例如 newBoard() 函数),并在 logic.test.js 中添加测试。\n\n验收标准:点击后棋盘为空,状态栏显示轮到 X;npm test 通过。' },
|
|
158
|
+
ja: { title: '「もう一度」ボタンを追加', summary: 'ページを再読み込みせずに新しいゲームを始められるようにします。',
|
|
159
|
+
description: '盤面の下に「もう一度」ボタンを追加します。押すと9つのマスがすべて空になり、X の先手で新しいゲームが始まります。\n\nルールは logic.js に置き(例: newBoard() 関数)、logic.test.js でテストします。\n\n受け入れ条件: ボタンを押すと盤面が空になり、ステータスに X の番と表示されること。npm test が通ること。' },
|
|
160
|
+
};
|
|
161
|
+
const WIN_LINE = {
|
|
162
|
+
en: { title: 'Highlight the winning line', summary: 'Show which three cells made the win.',
|
|
163
|
+
description: 'When a player wins, highlight the three winning cells (for example with a background colour).\n\nAdd a winningLine(board) function to logic.js that returns the three indexes, or null when nobody has won, and test it in logic.test.js.\n\nAcceptance: a won game shows exactly three highlighted cells; npm test passes.' },
|
|
164
|
+
es: { title: 'Resaltar la línea ganadora', summary: 'Muestra qué tres casillas dieron la victoria.',
|
|
165
|
+
description: 'Cuando alguien gana, resalta las tres casillas ganadoras (por ejemplo con un color de fondo).\n\nAñade a logic.js una función winningLine(board) que devuelva los tres índices, o null si nadie ha ganado, y pruébala en logic.test.js.\n\nCriterio de aceptación: una partida ganada muestra exactamente tres casillas resaltadas; npm test pasa.' },
|
|
166
|
+
fr: { title: 'Mettre en évidence la ligne gagnante', summary: 'Montre les trois cases qui ont donné la victoire.',
|
|
167
|
+
description: 'Quand un joueur gagne, mets en évidence les trois cases gagnantes (par exemple avec une couleur de fond).\n\nAjoute à logic.js une fonction winningLine(board) qui renvoie les trois indices, ou null si personne n\'a gagné, et teste-la dans logic.test.js.\n\nCritère d\'acceptation : une partie gagnée affiche exactement trois cases en évidence ; npm test réussit.' },
|
|
168
|
+
de: { title: 'Gewinnlinie hervorheben', summary: 'Zeigt, welche drei Felder den Sieg gebracht haben.',
|
|
169
|
+
description: 'Wenn ein Spieler gewinnt, hebe die drei Gewinnfelder hervor (zum Beispiel mit einer Hintergrundfarbe).\n\nFüge logic.js eine Funktion winningLine(board) hinzu, die die drei Indizes zurückgibt, oder null, wenn niemand gewonnen hat, und teste sie in logic.test.js.\n\nAkzeptanzkriterium: Ein gewonnenes Spiel zeigt genau drei hervorgehobene Felder; npm test läuft durch.' },
|
|
170
|
+
pt: { title: 'Destacar a linha vencedora', summary: 'Mostra quais três casas deram a vitória.',
|
|
171
|
+
description: 'Quando alguém ganha, destaca as três casas vencedoras (por exemplo com uma cor de fundo).\n\nAdiciona a logic.js uma função winningLine(board) que devolve os três índices, ou null se ninguém ganhou, e testa-a em logic.test.js.\n\nCritério de aceitação: um jogo ganho mostra exatamente três casas destacadas; npm test passa.' },
|
|
172
|
+
it: { title: 'Evidenziare la linea vincente', summary: 'Mostra quali tre caselle hanno dato la vittoria.',
|
|
173
|
+
description: 'Quando un giocatore vince, evidenzia le tre caselle vincenti (per esempio con un colore di sfondo).\n\nAggiungi a logic.js una funzione winningLine(board) che restituisce i tre indici, oppure null se nessuno ha vinto, e testala in logic.test.js.\n\nCriterio di accettazione: una partita vinta mostra esattamente tre caselle evidenziate; npm test passa.' },
|
|
174
|
+
zh: { title: '高亮获胜连线', summary: '显示是哪三个格子取得了胜利。',
|
|
175
|
+
description: '当有玩家获胜时,高亮显示三个获胜格子(例如使用背景色)。\n\n在 logic.js 中添加 winningLine(board) 函数,返回这三个索引;无人获胜时返回 null,并在 logic.test.js 中测试。\n\n验收标准:获胜的一局恰好显示三个高亮格子;npm test 通过。' },
|
|
176
|
+
ja: { title: '勝利ラインをハイライト', summary: 'どの3マスで勝ったかを表示します。',
|
|
177
|
+
description: '誰かが勝ったら、勝利した3マスをハイライトします(例: 背景色)。\n\nlogic.js に winningLine(board) 関数を追加し、3つのインデックスを返します(勝者がいなければ null)。logic.test.js でテストします。\n\n受け入れ条件: 勝利したゲームでちょうど3マスがハイライトされること。npm test が通ること。' },
|
|
178
|
+
};
|
|
179
|
+
const SCORE = {
|
|
180
|
+
en: { title: 'Keep score across rounds', summary: 'Count wins for X, wins for O and draws.',
|
|
181
|
+
description: 'Show a small scoreboard above the board with wins for X, wins for O and draws. The score carries over when the players press Restart or finish a game, and starts at zero when the page loads.\n\nKeep the counting in logic.js (for example addResult(score, result)) and test it in logic.test.js.\n\nAcceptance: after two X wins and one draw the scoreboard reads X 2, O 0, Draws 1; npm test passes.' },
|
|
182
|
+
es: { title: 'Llevar la puntuación entre partidas', summary: 'Cuenta las victorias de X, las de O y los empates.',
|
|
183
|
+
description: 'Muestra un pequeño marcador sobre el tablero con las victorias de X, las de O y los empates. La puntuación se mantiene al reiniciar o terminar una partida y empieza en cero al cargar la página.\n\nMantén el recuento en logic.js (por ejemplo addResult(score, result)) y pruébalo en logic.test.js.\n\nCriterio de aceptación: tras dos victorias de X y un empate el marcador muestra X 2, O 0, Empates 1; npm test pasa.' },
|
|
184
|
+
fr: { title: 'Garder le score entre les parties', summary: 'Compte les victoires de X, celles de O et les égalités.',
|
|
185
|
+
description: 'Affiche un petit tableau de score au-dessus du plateau avec les victoires de X, celles de O et les égalités. Le score est conservé quand on recommence ou termine une partie, et repart de zéro au chargement de la page.\n\nGarde le décompte dans logic.js (par exemple addResult(score, result)) et teste-le dans logic.test.js.\n\nCritère d\'acceptation : après deux victoires de X et une égalité, le tableau affiche X 2, O 0, Égalités 1 ; npm test réussit.' },
|
|
186
|
+
de: { title: 'Punktestand über Runden führen', summary: 'Zählt Siege von X, Siege von O und Unentschieden.',
|
|
187
|
+
description: 'Zeige über dem Spielfeld eine kleine Anzeige mit den Siegen von X, den Siegen von O und den Unentschieden. Der Stand bleibt beim Neustart oder nach einem beendeten Spiel erhalten und beginnt beim Laden der Seite bei null.\n\nHalte die Zählung in logic.js (zum Beispiel addResult(score, result)) und teste sie in logic.test.js.\n\nAkzeptanzkriterium: Nach zwei Siegen von X und einem Unentschieden zeigt die Anzeige X 2, O 0, Unentschieden 1; npm test läuft durch.' },
|
|
188
|
+
pt: { title: 'Manter a pontuação entre jogos', summary: 'Conta as vitórias do X, as do O e os empates.',
|
|
189
|
+
description: 'Mostra um pequeno placar acima do tabuleiro com as vitórias do X, as do O e os empates. A pontuação mantém-se ao reiniciar ou terminar um jogo e começa em zero quando a página carrega.\n\nMantém a contagem em logic.js (por exemplo addResult(score, result)) e testa-a em logic.test.js.\n\nCritério de aceitação: depois de duas vitórias do X e um empate o placar mostra X 2, O 0, Empates 1; npm test passa.' },
|
|
190
|
+
it: { title: 'Tenere il punteggio tra le partite', summary: 'Conta le vittorie di X, quelle di O e i pareggi.',
|
|
191
|
+
description: 'Mostra un piccolo tabellone sopra la griglia con le vittorie di X, quelle di O e i pareggi. Il punteggio resta quando si ricomincia o si finisce una partita e riparte da zero al caricamento della pagina.\n\nMantieni il conteggio in logic.js (per esempio addResult(score, result)) e testalo in logic.test.js.\n\nCriterio di accettazione: dopo due vittorie di X e un pareggio il tabellone mostra X 2, O 0, Pareggi 1; npm test passa.' },
|
|
192
|
+
zh: { title: '跨局记录比分', summary: '统计 X 的胜场、O 的胜场和平局。',
|
|
193
|
+
description: '在棋盘上方显示一个小计分板,包含 X 的胜场、O 的胜场和平局。重新开始或结束一局后比分保留,页面加载时从零开始。\n\n把计分逻辑放在 logic.js 中(例如 addResult(score, result)),并在 logic.test.js 中测试。\n\n验收标准:X 赢两局、平一局后,计分板显示 X 2、O 0、平局 1;npm test 通过。' },
|
|
194
|
+
ja: { title: 'ラウンドをまたいでスコアを記録', summary: 'X の勝ち、O の勝ち、引き分けを数えます。',
|
|
195
|
+
description: '盤面の上に、X の勝ち・O の勝ち・引き分けを表示する小さなスコアボードを追加します。ゲームを終えたり「もう一度」を押してもスコアは保持され、ページを読み込むと 0 から始まります。\n\n集計は logic.js に置き(例: addResult(score, result))、logic.test.js でテストします。\n\n受け入れ条件: X が2勝して1回引き分けると、X 2・O 0・引き分け 1 と表示されること。npm test が通ること。' },
|
|
196
|
+
};
|
|
197
|
+
exports.TIC_TAC_TOE = {
|
|
198
|
+
id: 'tic-tac-toe',
|
|
199
|
+
name: 'tic-tac-toe',
|
|
200
|
+
commitMessage: 'Initial commit: tic-tac-toe sample',
|
|
201
|
+
files: {
|
|
202
|
+
'index.html': INDEX_HTML,
|
|
203
|
+
'game.js': GAME_JS,
|
|
204
|
+
'logic.js': LOGIC_JS,
|
|
205
|
+
'logic.test.js': LOGIC_TEST_JS,
|
|
206
|
+
'style.css': STYLE_CSS,
|
|
207
|
+
'package.json': PACKAGE_JSON,
|
|
208
|
+
'README.md': README_MD,
|
|
209
|
+
'.gitignore': GITIGNORE,
|
|
210
|
+
},
|
|
211
|
+
specs: [
|
|
212
|
+
{ key: 'restart-button', priority: 'high', labels: ['sample', 'ui'], effort: 'small', text: RESTART },
|
|
213
|
+
{ key: 'winning-line', priority: 'medium', labels: ['sample', 'ui'], effort: 'small', text: WIN_LINE },
|
|
214
|
+
{ key: 'scoreboard', priority: 'medium', labels: ['sample', 'ui'], effort: 'medium', text: SCORE },
|
|
215
|
+
],
|
|
216
|
+
};
|
|
217
|
+
exports.SAMPLE_CATALOG = [exports.TIC_TAC_TOE];
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Sample-project first run: pure vocabulary and rules.
|
|
4
|
+
*
|
|
5
|
+
* The sample is a tiny bundled repository the person can try before pointing
|
|
6
|
+
* Specrails at their own code. Nothing here touches the filesystem, git, SQLite
|
|
7
|
+
* or a provider: those effects live behind {@link ./ports} and the adapters.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SampleError = exports.SAMPLE_PARENT_DIR_NAME = exports.SAMPLE_SETTING_KEY = exports.SAMPLE_ESTIMATE = exports.SAMPLE_RUN_CAP_USD = exports.SAMPLE_LOOP_ID = exports.SAMPLE_LOCALES = void 0;
|
|
11
|
+
exports.normalizeSampleLocale = normalizeSampleLocale;
|
|
12
|
+
exports.cheapestModel = cheapestModel;
|
|
13
|
+
exports.chooseSamplePreset = chooseSamplePreset;
|
|
14
|
+
exports.firstFreeName = firstFreeName;
|
|
15
|
+
exports.isStrictlyInside = isStrictlyInside;
|
|
16
|
+
exports.SAMPLE_LOCALES = ['en', 'es', 'fr', 'de', 'pt', 'it', 'zh', 'ja'];
|
|
17
|
+
function normalizeSampleLocale(raw) {
|
|
18
|
+
if (typeof raw !== 'string')
|
|
19
|
+
return 'en';
|
|
20
|
+
const base = raw.toLowerCase().split('-')[0].trim();
|
|
21
|
+
return exports.SAMPLE_LOCALES.includes(base) ? base : 'en';
|
|
22
|
+
}
|
|
23
|
+
/** The workflow the first run uses: Quick SDD, the shortest factory pipeline. */
|
|
24
|
+
exports.SAMPLE_LOOP_ID = 'factory:sdd-quick-openspec';
|
|
25
|
+
/** Soft cap (USD): the run pauses and asks at this provider-reported cost. */
|
|
26
|
+
exports.SAMPLE_RUN_CAP_USD = 1;
|
|
27
|
+
/** Honest, static envelope for the cost statement (an estimate, never a bill). */
|
|
28
|
+
exports.SAMPLE_ESTIMATE = { minutes: [3, 5], usd: [0.3, 1] };
|
|
29
|
+
/** Settings key (desktop_settings) holding the {@link SampleRecord} JSON. */
|
|
30
|
+
exports.SAMPLE_SETTING_KEY = 'onboarding.sample';
|
|
31
|
+
/** Folder, under the home directory, where samples are created by default. */
|
|
32
|
+
exports.SAMPLE_PARENT_DIR_NAME = 'Specrails Samples';
|
|
33
|
+
function isReady(p) {
|
|
34
|
+
return p.usable && p.authState !== 'unauthenticated';
|
|
35
|
+
}
|
|
36
|
+
/** The cheapest PRICED model; falls back to the provider default when none is priced. */
|
|
37
|
+
function cheapestModel(provider) {
|
|
38
|
+
let best = null;
|
|
39
|
+
for (const model of provider.models) {
|
|
40
|
+
if (model.priceUsdPer1M === null || !Number.isFinite(model.priceUsdPer1M))
|
|
41
|
+
continue;
|
|
42
|
+
if (best === null || model.priceUsdPer1M < best.priceUsdPer1M)
|
|
43
|
+
best = model;
|
|
44
|
+
}
|
|
45
|
+
return best?.value ?? provider.defaultModel;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Decide the first-run configuration: Quick SDD, the cheapest available model
|
|
49
|
+
* of the cheapest ready cloud provider, a per-run soft cap, or a configured
|
|
50
|
+
* local engine (no cap, no dollars). `localPreset` is offered alongside when
|
|
51
|
+
* both exist. Returns a not-ready verdict, with the reason, when nothing can
|
|
52
|
+
* run, so the caller offers the recorded run instead of a run that would fail.
|
|
53
|
+
*/
|
|
54
|
+
function chooseSamplePreset(providers) {
|
|
55
|
+
const ready = providers.filter(isReady);
|
|
56
|
+
if (ready.length === 0) {
|
|
57
|
+
const signedOut = providers.some((p) => p.usable && p.authState === 'unauthenticated');
|
|
58
|
+
return { ready: false, reason: signedOut ? 'not_signed_in' : 'no_provider', preset: null, localPreset: null };
|
|
59
|
+
}
|
|
60
|
+
const price = (p) => {
|
|
61
|
+
const model = cheapestModel(p);
|
|
62
|
+
return p.models.find((m) => m.value === model)?.priceUsdPer1M ?? Number.POSITIVE_INFINITY;
|
|
63
|
+
};
|
|
64
|
+
const cloud = ready.filter((p) => !p.local).sort((a, b) => price(a) - price(b))[0] ?? null;
|
|
65
|
+
const local = ready.find((p) => p.local) ?? null;
|
|
66
|
+
const cloudPreset = cloud
|
|
67
|
+
? { provider: cloud.id, model: cheapestModel(cloud), local: false, loopId: exports.SAMPLE_LOOP_ID, runCapUsd: exports.SAMPLE_RUN_CAP_USD }
|
|
68
|
+
: null;
|
|
69
|
+
const localPreset = local
|
|
70
|
+
? { provider: local.id, model: local.models[0]?.value ?? local.defaultModel, local: true, loopId: exports.SAMPLE_LOOP_ID, runCapUsd: null }
|
|
71
|
+
: null;
|
|
72
|
+
// The default is the cloud choice; a machine with only a local engine runs on it.
|
|
73
|
+
return { ready: true, preset: (cloudPreset ?? localPreset), localPreset: cloudPreset ? localPreset : null };
|
|
74
|
+
}
|
|
75
|
+
// ─── Target directory ────────────────────────────────────────────────────────
|
|
76
|
+
/** `name`, then `name-2`, `name-3`… the first one `taken` does not claim. */
|
|
77
|
+
function firstFreeName(name, taken, limit = 50) {
|
|
78
|
+
if (!taken(name))
|
|
79
|
+
return name;
|
|
80
|
+
for (let n = 2; n <= limit; n += 1) {
|
|
81
|
+
const candidate = `${name}-${n}`;
|
|
82
|
+
if (!taken(candidate))
|
|
83
|
+
return candidate;
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
/** True when `child` is strictly inside `parent` (both absolute, already normalized). */
|
|
88
|
+
function isStrictlyInside(parent, child, sep) {
|
|
89
|
+
const prefix = parent.endsWith(sep) ? parent : parent + sep;
|
|
90
|
+
return child.length > prefix.length && child.startsWith(prefix);
|
|
91
|
+
}
|
|
92
|
+
class SampleError extends Error {
|
|
93
|
+
code;
|
|
94
|
+
status;
|
|
95
|
+
constructor(code, message, status = 400) {
|
|
96
|
+
super(message);
|
|
97
|
+
this.code = code;
|
|
98
|
+
this.status = status;
|
|
99
|
+
this.name = 'SampleError';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.SampleError = SampleError;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeSampleLocale = exports.isStrictlyInside = exports.firstFreeName = exports.chooseSamplePreset = exports.cheapestModel = exports.SampleError = exports.SAMPLE_SETTING_KEY = exports.SAMPLE_RUN_CAP_USD = exports.SAMPLE_LOOP_ID = exports.SAMPLE_LOCALES = exports.SAMPLE_ESTIMATE = exports.removeSample = exports.defaultSampleParent = exports.currentSample = exports.createSample = void 0;
|
|
4
|
+
var application_1 = require("./application");
|
|
5
|
+
Object.defineProperty(exports, "createSample", { enumerable: true, get: function () { return application_1.createSample; } });
|
|
6
|
+
Object.defineProperty(exports, "currentSample", { enumerable: true, get: function () { return application_1.currentSample; } });
|
|
7
|
+
Object.defineProperty(exports, "defaultSampleParent", { enumerable: true, get: function () { return application_1.defaultSampleParent; } });
|
|
8
|
+
Object.defineProperty(exports, "removeSample", { enumerable: true, get: function () { return application_1.removeSample; } });
|
|
9
|
+
var domain_1 = require("./domain");
|
|
10
|
+
Object.defineProperty(exports, "SAMPLE_ESTIMATE", { enumerable: true, get: function () { return domain_1.SAMPLE_ESTIMATE; } });
|
|
11
|
+
Object.defineProperty(exports, "SAMPLE_LOCALES", { enumerable: true, get: function () { return domain_1.SAMPLE_LOCALES; } });
|
|
12
|
+
Object.defineProperty(exports, "SAMPLE_LOOP_ID", { enumerable: true, get: function () { return domain_1.SAMPLE_LOOP_ID; } });
|
|
13
|
+
Object.defineProperty(exports, "SAMPLE_RUN_CAP_USD", { enumerable: true, get: function () { return domain_1.SAMPLE_RUN_CAP_USD; } });
|
|
14
|
+
Object.defineProperty(exports, "SAMPLE_SETTING_KEY", { enumerable: true, get: function () { return domain_1.SAMPLE_SETTING_KEY; } });
|
|
15
|
+
Object.defineProperty(exports, "SampleError", { enumerable: true, get: function () { return domain_1.SampleError; } });
|
|
16
|
+
Object.defineProperty(exports, "cheapestModel", { enumerable: true, get: function () { return domain_1.cheapestModel; } });
|
|
17
|
+
Object.defineProperty(exports, "chooseSamplePreset", { enumerable: true, get: function () { return domain_1.chooseSamplePreset; } });
|
|
18
|
+
Object.defineProperty(exports, "firstFreeName", { enumerable: true, get: function () { return domain_1.firstFreeName; } });
|
|
19
|
+
Object.defineProperty(exports, "isStrictlyInside", { enumerable: true, get: function () { return domain_1.isStrictlyInside; } });
|
|
20
|
+
Object.defineProperty(exports, "normalizeSampleLocale", { enumerable: true, get: function () { return domain_1.normalizeSampleLocale; } });
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerProjectRulesHttp = registerProjectRulesHttp;
|
|
4
|
+
const domain_1 = require("../domain");
|
|
5
|
+
const rules_store_1 = require("../runtime/rules-store");
|
|
6
|
+
const rules_inventory_runs_1 = require("../runtime/rules-inventory-runs");
|
|
7
|
+
/**
|
|
8
|
+
* Project rules (task 4.4):
|
|
9
|
+
* - `GET /:projectId/rules` — the inventory, whether Core supports it, whether a
|
|
10
|
+
* run is in flight and how the last run ended (`lastRun`).
|
|
11
|
+
* - `POST /:projectId/rules/inventory` — re-run Core's inventory (one at a time per project).
|
|
12
|
+
* - `POST /:projectId/rules/specs` — turn an `automatable` rule into a spec (`{ id }` or `{ index }`).
|
|
13
|
+
* Without the Core capability every write answers 409 `rules_inventory_unsupported`
|
|
14
|
+
* and the read reports `supported: false`; an existing file is still shown.
|
|
15
|
+
*/
|
|
16
|
+
function registerProjectRulesHttp(router, portsFor, runs = (0, rules_inventory_runs_1.createRulesInventoryRuns)()) {
|
|
17
|
+
// Shared with the automatic run after project setup (one run per project at a time).
|
|
18
|
+
const read = (ports) => {
|
|
19
|
+
const result = (0, rules_store_1.readProjectRules)(ports.project);
|
|
20
|
+
return result.state === 'ok'
|
|
21
|
+
? { state: 'ok', file: result.file, modifiedAt: result.modifiedAt, inventory: result.inventory }
|
|
22
|
+
: result.state === 'invalid' ? { state: 'invalid', file: result.file, message: result.message } : { state: 'missing' };
|
|
23
|
+
};
|
|
24
|
+
router.get('/:projectId/rules', async (req, res) => {
|
|
25
|
+
try {
|
|
26
|
+
const ports = portsFor(req);
|
|
27
|
+
const lastRun = runs.lastRun(ports.project.id);
|
|
28
|
+
res.json({ supported: await ports.supported(), running: runs.isRunning(ports.project.id), ...(lastRun ? { lastRun } : {}), ...read(ports) });
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('[project-rules] read failed:', error);
|
|
32
|
+
res.status(500).json({ error: 'rules_read_failed' });
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
router.post('/:projectId/rules/inventory', async (req, res) => {
|
|
36
|
+
const ports = portsFor(req);
|
|
37
|
+
if (!(await ports.supported())) {
|
|
38
|
+
res.status(409).json({ error: 'rules_inventory_unsupported', message: 'Update Core to a version with the project rules inventory' });
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const run = await runs.run(ports.project, 'manual', ports.runInventory);
|
|
43
|
+
if (!run) {
|
|
44
|
+
res.status(409).json({ error: 'rules_inventory_running', message: 'The inventory is already running for this project' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const after = read(ports);
|
|
48
|
+
res.status(run.ok ? 200 : 502).json({ ok: run.ok, exitCode: run.exitCode, output: run.output, ...after });
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error('[project-rules] inventory failed:', error);
|
|
52
|
+
res.status(500).json({ error: 'rules_inventory_failed' });
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
router.post('/:projectId/rules/specs', async (req, res) => {
|
|
56
|
+
const ports = portsFor(req);
|
|
57
|
+
if (!(await ports.supported())) {
|
|
58
|
+
res.status(409).json({ error: 'rules_inventory_unsupported', message: 'Update Core to a version with the project rules inventory' });
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Core's stable rule id (preferred) or the rule's position in the file.
|
|
62
|
+
const id = typeof req.body?.id === 'string' && req.body.id.trim() ? req.body.id.trim() : null;
|
|
63
|
+
const index = req.body?.index;
|
|
64
|
+
if (id === null && (typeof index !== 'number' || !Number.isSafeInteger(index) || index < 0)) {
|
|
65
|
+
res.status(400).json({ error: 'id or a non-negative index is required' });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const current = (0, rules_store_1.readProjectRules)(ports.project);
|
|
69
|
+
if (current.state !== 'ok') {
|
|
70
|
+
res.status(404).json({ error: 'rules_missing', message: 'No rules inventory for this project' });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const rule = current.inventory.rules.find((entry) => id !== null ? entry.id === id : entry.index === index);
|
|
74
|
+
if (!rule) {
|
|
75
|
+
res.status(404).json({ error: 'rule_not_found' });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (rule.status !== 'automatable') {
|
|
79
|
+
res.status(400).json({ error: 'rule_not_automatable', message: 'Only automatable rules become specs' });
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const ticket = ports.createRuleSpec({ ...(0, domain_1.specFromRule)(rule), ruleSource: rule.source });
|
|
84
|
+
res.status(201).json({ ticket });
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.error('[project-rules] create spec failed:', error);
|
|
88
|
+
res.status(500).json({ error: 'rule_spec_failed' });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Project rules inventory (feedback-2026-10 task 4.4, annex D.5).
|
|
4
|
+
*
|
|
5
|
+
* Core's rules step writes `.specrails/rules.json`: the gates the project
|
|
6
|
+
* already runs (lint, type checks, architecture tests, hooks, CI, `openspec
|
|
7
|
+
* validate`) and every written rule of CLAUDE.md / AGENTS.md / CONTRIBUTING
|
|
8
|
+
* classified as `enforcedBy` (a check already enforces it), `automatable`
|
|
9
|
+
* (a check could, `proposedCheck` says which) or `humanOnly` (a reviewer must
|
|
10
|
+
* look). Desktop shows it in project settings, turns an automatable rule into
|
|
11
|
+
* a spec in one click, lists human-only rules in the review packet and offers
|
|
12
|
+
* the gates as the default verification plan.
|
|
13
|
+
*
|
|
14
|
+
* Pure: parsing, bounds and derivations only. Zero imports (pinned by the
|
|
15
|
+
* architecture test). Tolerant: a malformed entry is dropped and counted,
|
|
16
|
+
* never fatal; nothing here ever gates a run.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.RULE_STATUSES = exports.RULES_FILE = void 0;
|
|
20
|
+
exports.parseRulesInventory = parseRulesInventory;
|
|
21
|
+
exports.humanOnlyRules = humanOnlyRules;
|
|
22
|
+
exports.gateToVerificationCommand = gateToVerificationCommand;
|
|
23
|
+
exports.specFromRule = specFromRule;
|
|
24
|
+
exports.RULES_FILE = 'rules.json';
|
|
25
|
+
const RULE_TEXT_CAP = 1000;
|
|
26
|
+
const LIST_CAP = 500;
|
|
27
|
+
exports.RULE_STATUSES = ['enforcedBy', 'automatable', 'humanOnly', 'unclassified'];
|
|
28
|
+
function isRecord(value) {
|
|
29
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
30
|
+
}
|
|
31
|
+
function text(value, cap = RULE_TEXT_CAP) {
|
|
32
|
+
return typeof value === 'string' && value.trim() ? value.replace(/\s+/g, ' ').trim().slice(0, cap) : null;
|
|
33
|
+
}
|
|
34
|
+
/** Parse a rules.json document; null when it is not an object with lists. */
|
|
35
|
+
function parseRulesInventory(value) {
|
|
36
|
+
if (!isRecord(value) || (!Array.isArray(value.gates) && !Array.isArray(value.rules)))
|
|
37
|
+
return null;
|
|
38
|
+
if (value.schemaVersion !== undefined && value.schemaVersion !== 1)
|
|
39
|
+
return null;
|
|
40
|
+
let dropped = 0;
|
|
41
|
+
const gates = [];
|
|
42
|
+
for (const raw of Array.isArray(value.gates) ? value.gates : []) {
|
|
43
|
+
const command = isRecord(raw) ? text(raw.command, 500) : null;
|
|
44
|
+
if (!isRecord(raw) || !command) {
|
|
45
|
+
dropped++;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (gates.length >= LIST_CAP)
|
|
49
|
+
continue;
|
|
50
|
+
gates.push({ id: text(raw.id, 120) ?? `gate-${gates.length + 1}`, kind: text(raw.kind, 40) ?? 'other', command, source: text(raw.source, 300) });
|
|
51
|
+
}
|
|
52
|
+
const rules = [];
|
|
53
|
+
const counts = { enforcedBy: 0, automatable: 0, humanOnly: 0, unclassified: 0 };
|
|
54
|
+
const rawRules = Array.isArray(value.rules) ? value.rules : [];
|
|
55
|
+
rawRules.forEach((raw, index) => {
|
|
56
|
+
const ruleText = isRecord(raw) ? text(raw.text) : null;
|
|
57
|
+
if (!isRecord(raw) || !ruleText || !exports.RULE_STATUSES.includes(raw.status)) {
|
|
58
|
+
dropped++;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (rules.length >= LIST_CAP)
|
|
62
|
+
return;
|
|
63
|
+
const status = raw.status;
|
|
64
|
+
counts[status]++;
|
|
65
|
+
rules.push({
|
|
66
|
+
id: text(raw.id, 64) ?? `index-${index}`,
|
|
67
|
+
index,
|
|
68
|
+
text: ruleText,
|
|
69
|
+
source: text(raw.source, 300),
|
|
70
|
+
status,
|
|
71
|
+
enforcedBy: text(raw.enforcedBy, 300),
|
|
72
|
+
proposedCheck: text(raw.proposedCheck),
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
return { generatedAt: text(value.generatedAt, 64), gates, rules, counts, classification: parseClassification(value.classification), dropped };
|
|
76
|
+
}
|
|
77
|
+
const CLASSIFICATION_STATUSES = ['classified', 'cached', 'offline', 'unavailable', 'failed', 'empty'];
|
|
78
|
+
function parseClassification(value) {
|
|
79
|
+
if (!isRecord(value))
|
|
80
|
+
return null;
|
|
81
|
+
const status = CLASSIFICATION_STATUSES.includes(value.status) ? value.status : 'unknown';
|
|
82
|
+
return { status, provider: text(value.provider, 64), model: text(value.model, 128), reason: text(value.reason, 600), classifiedAt: text(value.classifiedAt, 64) };
|
|
83
|
+
}
|
|
84
|
+
/** The rules a reviewer must check by hand ("Needs human eyes"). */
|
|
85
|
+
function humanOnlyRules(inventory) {
|
|
86
|
+
return (inventory?.rules ?? []).filter((rule) => rule.status === 'humanOnly').map(({ text: ruleText, source }) => ({ text: ruleText, source }));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* A gate command as a verification entry, or null when it is not a plain
|
|
90
|
+
* `command arg…` line. Core's verification runner never uses a shell, so a
|
|
91
|
+
* gate with shell syntax (pipes, `&&`, redirections, substitutions, quotes)
|
|
92
|
+
* is not offered rather than run differently than written.
|
|
93
|
+
*/
|
|
94
|
+
function gateToVerificationCommand(gate) {
|
|
95
|
+
if (/[|&;<>`$(){}"'\\*?]/.test(gate.command))
|
|
96
|
+
return null;
|
|
97
|
+
const parts = gate.command.split(/\s+/).filter(Boolean);
|
|
98
|
+
if (parts.length === 0 || parts.length > 32)
|
|
99
|
+
return null;
|
|
100
|
+
return { command: parts[0], args: parts.slice(1) };
|
|
101
|
+
}
|
|
102
|
+
/** Spec fields for "Create spec" on an automatable rule (ticket source `rules`). */
|
|
103
|
+
function specFromRule(rule) {
|
|
104
|
+
const check = rule.proposedCheck ?? 'An automated check that fails when the rule is broken';
|
|
105
|
+
const title = `Enforce: ${rule.text}`.slice(0, 160);
|
|
106
|
+
const description = [
|
|
107
|
+
'## Problem Statement',
|
|
108
|
+
`The project states this rule${rule.source ? ` (${rule.source})` : ''}, but no automated check enforces it today:`,
|
|
109
|
+
'',
|
|
110
|
+
`> ${rule.text}`,
|
|
111
|
+
'',
|
|
112
|
+
'## Proposed Solution',
|
|
113
|
+
`${check}. Run it with the project's existing gates so a violation fails locally and in CI.`,
|
|
114
|
+
'',
|
|
115
|
+
'## Acceptance Criteria',
|
|
116
|
+
'- [ ] The check fails on a deliberate violation of the rule, with a message naming the rule.',
|
|
117
|
+
'- [ ] The check passes on the current codebase (or the existing violations are fixed in this change).',
|
|
118
|
+
'- [ ] The check runs as part of the project\'s verification commands.',
|
|
119
|
+
'- [ ] The rule\'s documentation points to the check that now enforces it.',
|
|
120
|
+
].join('\n');
|
|
121
|
+
return { title, description, labels: ['rules', 'automation'], nonGoals: ['Changing what the rule says', 'Enforcing other rules from the inventory'] };
|
|
122
|
+
}
|