specrails-desktop 2.64.1 → 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/openspec-shim.js +1 -1
- 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,376 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.baseRunId = baseRunId;
|
|
4
|
+
exports.actorOf = actorOf;
|
|
5
|
+
exports.collectSpecHistory = collectSpecHistory;
|
|
6
|
+
const delivery_evidence_1 = require("../../delivery/runtime/delivery-evidence");
|
|
7
|
+
const sqlite_1 = require("../../recovery/adapters/sqlite");
|
|
8
|
+
const audit_1 = require("../../audit");
|
|
9
|
+
const spec_addenda_core_1 = require("./spec-addenda-core");
|
|
10
|
+
const timeline_1 = require("../domain/timeline");
|
|
11
|
+
/** Hard bounds so a pathological history cannot blow up one request. */
|
|
12
|
+
const MAX_INVOCATIONS = 2000;
|
|
13
|
+
const MAX_RUNS = 200;
|
|
14
|
+
const MAX_DELIVERIES = 50;
|
|
15
|
+
const SPEC_AI_SURFACES = new Set(['ai-edit', 'quick-spec', 'smash', 'triage', 'spec-launcher']);
|
|
16
|
+
const MISSION_SURFACES = new Set(['explore-spec', 'chat-sidebar', 'flow']);
|
|
17
|
+
function placeholders(count) {
|
|
18
|
+
return Array.from({ length: count }, () => '?').join(', ');
|
|
19
|
+
}
|
|
20
|
+
function chunk(items, size) {
|
|
21
|
+
const out = [];
|
|
22
|
+
for (let i = 0; i < items.length; i += size)
|
|
23
|
+
out.push(items.slice(i, i + size));
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
function parseJson(raw, fallback) {
|
|
27
|
+
if (!raw)
|
|
28
|
+
return fallback;
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(raw);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return fallback;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** `job-1#t7` and `job-1:merge:step` rows belong to job `job-1`. */
|
|
37
|
+
function baseRunId(refId) {
|
|
38
|
+
if (!refId)
|
|
39
|
+
return null;
|
|
40
|
+
return refId.replace(/#t\d+$/, '').replace(/:merge:.*$/, '') || null;
|
|
41
|
+
}
|
|
42
|
+
function actorOf(createdBy, provider = null) {
|
|
43
|
+
const by = (createdBy ?? '').trim();
|
|
44
|
+
if (by === 'mcp')
|
|
45
|
+
return { type: 'mcp', label: 'mcp', provider };
|
|
46
|
+
if (by === 'user' || by === 'manual' || by === '')
|
|
47
|
+
return { type: 'user', label: 'user', provider: null };
|
|
48
|
+
if (by === 'agent' || by.startsWith('sr') || by.startsWith('specrails'))
|
|
49
|
+
return { type: 'agent', label: by.replace(/^(?:specrails:|sr:|sr-)/, '') || 'agent', provider };
|
|
50
|
+
return { type: 'system', label: by, provider };
|
|
51
|
+
}
|
|
52
|
+
/** Markdown to plain prose, so a summary never shows `**Tracker:**` or `## Heading` literally. */
|
|
53
|
+
function plain(text) {
|
|
54
|
+
if (typeof text !== 'string')
|
|
55
|
+
return text;
|
|
56
|
+
return text
|
|
57
|
+
.replace(/`([^`]+)`/g, '$1')
|
|
58
|
+
.replace(/\*\*([^*]+)\*\*/g, '$1')
|
|
59
|
+
.replace(/^\s*[-*#>]+\s*/gm, '')
|
|
60
|
+
.replace(/\s+/g, ' ');
|
|
61
|
+
}
|
|
62
|
+
function clean(text, max = 240) {
|
|
63
|
+
const flat = (0, timeline_1.oneLine)(plain(text), max);
|
|
64
|
+
return flat === null ? null : (0, audit_1.redactProse)(flat);
|
|
65
|
+
}
|
|
66
|
+
function runTone(status, outcome) {
|
|
67
|
+
if (status === 'running' || status === 'queued' || status === 'paused')
|
|
68
|
+
return 'neutral';
|
|
69
|
+
if (outcome === 'failed' || outcome === 'blocked' || outcome === 'stalled' || status === 'failed' || status === 'canceled' || status === 'aborted')
|
|
70
|
+
return 'failure';
|
|
71
|
+
return 'ok';
|
|
72
|
+
}
|
|
73
|
+
function collectSpecHistory(db, ticket) {
|
|
74
|
+
const ticketId = ticket.id;
|
|
75
|
+
const entries = [];
|
|
76
|
+
const specLink = { place: 'spec', id: String(ticketId) };
|
|
77
|
+
// ─── Ticket: creation, last edit, comments ────────────────────────────────
|
|
78
|
+
entries.push({
|
|
79
|
+
id: 'spec:created', at: (0, timeline_1.utc)(ticket.created_at), kind: 'spec_edit', event: 'spec.created',
|
|
80
|
+
params: { source: ticket.source }, title: 'Spec created', summary: clean(ticket.title),
|
|
81
|
+
actor: actorOf(ticket.created_by), tone: 'neutral', provider: null,
|
|
82
|
+
link: ticket.origin_conversation_id ? { place: 'mission', id: ticket.origin_conversation_id } : specLink,
|
|
83
|
+
});
|
|
84
|
+
const updatedMs = Date.parse((0, timeline_1.utc)(ticket.updated_at));
|
|
85
|
+
if (Number.isFinite(updatedMs) && updatedMs - Date.parse((0, timeline_1.utc)(ticket.created_at)) > 1000) {
|
|
86
|
+
entries.push({
|
|
87
|
+
id: 'spec:updated', at: (0, timeline_1.utc)(ticket.updated_at), kind: 'spec_edit', event: 'spec.updated',
|
|
88
|
+
params: { status: ticket.status }, title: 'Spec last edited', summary: null,
|
|
89
|
+
actor: null, tone: 'neutral', provider: null, link: specLink,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
for (const comment of ticket.comments ?? []) {
|
|
93
|
+
entries.push({
|
|
94
|
+
id: `spec:comment:${comment.id}`, at: (0, timeline_1.utc)(comment.created_at), kind: 'spec_edit', event: 'spec.comment',
|
|
95
|
+
params: {}, title: 'Comment', summary: clean(comment.body, 400), actor: actorOf(comment.created_by),
|
|
96
|
+
tone: 'neutral', provider: null, link: specLink,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// ─── Addenda ───────────────────────────────────────────────────────────────
|
|
100
|
+
for (const addendum of (0, spec_addenda_core_1.readSpecAddenda)(ticket.addenda)) {
|
|
101
|
+
entries.push({
|
|
102
|
+
id: `addendum:${addendum.id}:created`, at: (0, timeline_1.utc)(addendum.created_at), kind: 'addendum', event: 'addendum.created',
|
|
103
|
+
params: { addendumKind: addendum.kind }, title: clean(addendum.title, 200) ?? addendum.kind,
|
|
104
|
+
summary: clean(addendum.body, 400), actor: actorOf(addendum.created_by), tone: 'neutral', provider: null,
|
|
105
|
+
link: addendum.origin_conversation_id ? { place: 'mission', id: addendum.origin_conversation_id } : specLink,
|
|
106
|
+
});
|
|
107
|
+
if (addendum.status !== 'open') {
|
|
108
|
+
entries.push({
|
|
109
|
+
id: `addendum:${addendum.id}:${addendum.status}`, at: (0, timeline_1.utc)(addendum.applied_at ?? addendum.updated_at), kind: 'addendum',
|
|
110
|
+
event: `addendum.${addendum.status}`, params: { addendumKind: addendum.kind }, title: clean(addendum.title, 200) ?? addendum.kind,
|
|
111
|
+
summary: null, actor: null, tone: addendum.status === 'applied' ? 'ok' : 'neutral', provider: null,
|
|
112
|
+
link: addendum.run_id ? { place: 'job', id: addendum.run_id } : specLink,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ─── Invocation ledger: the spine for cost, missions, AI edits and runs ───
|
|
117
|
+
const invocationRows = db.prepare(`
|
|
118
|
+
SELECT id, surface, surface_ref_id, conversation_id, loop_run_id, provider, model, status, started_at,
|
|
119
|
+
total_cost_usd, total_cost_usd_estimated, num_turns
|
|
120
|
+
FROM ai_invocations WHERE ticket_id = ? ORDER BY started_at DESC LIMIT ${MAX_INVOCATIONS}
|
|
121
|
+
`).all(ticketId);
|
|
122
|
+
const invocations = invocationRows.map((row) => ({
|
|
123
|
+
id: row.id, surface: row.surface, refId: row.surface_ref_id, conversationId: row.conversation_id, loopRunId: row.loop_run_id,
|
|
124
|
+
provider: row.provider, model: row.model, status: row.status, startedAt: (0, timeline_1.utc)(row.started_at),
|
|
125
|
+
costUsd: row.total_cost_usd, estimated: row.total_cost_usd_estimated === 1, turns: row.num_turns,
|
|
126
|
+
}));
|
|
127
|
+
const costOf = (rows) => (0, timeline_1.foldCost)(rows.map((r) => ({ provider: r.provider, costUsd: r.costUsd, estimated: r.estimated, turns: r.turns })));
|
|
128
|
+
const providerOf = (rows) => {
|
|
129
|
+
const set = new Set(rows.map((r) => r.provider).filter((p) => !!p));
|
|
130
|
+
return set.size === 1 ? [...set][0] : null;
|
|
131
|
+
};
|
|
132
|
+
// AI edits and generation touching the spec: one entry each (low volume).
|
|
133
|
+
for (const inv of invocations) {
|
|
134
|
+
if (!SPEC_AI_SURFACES.has(inv.surface))
|
|
135
|
+
continue;
|
|
136
|
+
const cost = costOf([inv]);
|
|
137
|
+
entries.push({
|
|
138
|
+
id: `ai:${inv.id}`, at: inv.startedAt, kind: 'spec_edit', event: `spec.ai.${inv.surface}`,
|
|
139
|
+
params: { surface: inv.surface, status: inv.status }, title: `AI ${inv.surface}`, summary: null,
|
|
140
|
+
actor: { type: 'agent', label: inv.surface, provider: inv.provider }, tone: inv.status === 'failed' ? 'failure' : 'neutral',
|
|
141
|
+
provider: inv.provider, ...cost, link: specLink,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
// Mission turns: grouped per conversation.
|
|
145
|
+
const byConversation = new Map();
|
|
146
|
+
for (const inv of invocations) {
|
|
147
|
+
if (!inv.conversationId || !MISSION_SURFACES.has(inv.surface))
|
|
148
|
+
continue;
|
|
149
|
+
const list = byConversation.get(inv.conversationId) ?? [];
|
|
150
|
+
list.push(inv);
|
|
151
|
+
byConversation.set(inv.conversationId, list);
|
|
152
|
+
}
|
|
153
|
+
const conversationIds = [...byConversation.keys()];
|
|
154
|
+
const titles = new Map();
|
|
155
|
+
for (const ids of chunk(conversationIds, 500)) {
|
|
156
|
+
const rows = db.prepare(`SELECT id, title FROM chat_conversations WHERE id IN (${placeholders(ids.length)})`).all(...ids);
|
|
157
|
+
for (const row of rows)
|
|
158
|
+
titles.set(row.id, row.title);
|
|
159
|
+
}
|
|
160
|
+
for (const [conversationId, rows] of byConversation) {
|
|
161
|
+
if (!titles.has(conversationId))
|
|
162
|
+
continue; // conversation was deleted: nothing to link to, nothing to show
|
|
163
|
+
const sorted = [...rows].sort((a, b) => (a.startedAt < b.startedAt ? 1 : -1));
|
|
164
|
+
const items = sorted.slice(0, timeline_1.TIMELINE_MAX_ITEMS).map((inv) => ({
|
|
165
|
+
at: inv.startedAt, label: inv.surface, detail: inv.model, ...(inv.status === 'failed' ? { tone: 'failure' } : {}),
|
|
166
|
+
}));
|
|
167
|
+
entries.push({
|
|
168
|
+
id: `mission:${conversationId}`, at: sorted[0].startedAt, kind: 'mission_turn', event: 'mission.turns',
|
|
169
|
+
params: { turns: rows.length }, title: clean(titles.get(conversationId) ?? null, 160) ?? 'Mission', summary: null,
|
|
170
|
+
actor: { type: 'agent', label: 'mission', provider: providerOf(rows) }, tone: 'neutral', provider: providerOf(rows),
|
|
171
|
+
...costOf(rows), link: { place: 'mission', id: conversationId }, count: rows.length, items,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// ─── Deliveries (needed to find runs too) ─────────────────────────────────
|
|
175
|
+
const deliveryRows = db.prepare(`
|
|
176
|
+
SELECT * FROM rail_pr_deliveries
|
|
177
|
+
WHERE parent_delivery_id IS NULL
|
|
178
|
+
AND EXISTS (SELECT 1 FROM json_each(rail_pr_deliveries.ticket_ids) WHERE value = ?)
|
|
179
|
+
ORDER BY created_at DESC LIMIT ${MAX_DELIVERIES}
|
|
180
|
+
`).all(ticketId);
|
|
181
|
+
const deliveries = deliveryRows.map((row) => {
|
|
182
|
+
const evidence = (0, delivery_evidence_1.readSettleEvidence)(row.settle_evidence);
|
|
183
|
+
const unit = evidence?.units.find((u) => u.ticketId === ticketId) ?? null;
|
|
184
|
+
return {
|
|
185
|
+
id: String(row.id), loopName: String(row.loop_name ?? ''), decision: String(row.decision), statusCode: row.status_code ?? null,
|
|
186
|
+
statusDetail: row.status_detail ?? null, branch: row.branch ?? null, baseBranch: String(row.base_branch ?? ''),
|
|
187
|
+
prUrl: row.pr_url ?? null, prNumber: row.pr_number ?? null, prState: String(row.pr_state ?? 'none'),
|
|
188
|
+
originConversationId: row.origin_conversation_id ?? null, createdAt: (0, timeline_1.utc)(String(row.created_at)),
|
|
189
|
+
onReviewAt: (0, timeline_1.utc)(row.on_review_at ?? null), publishedAt: (0, timeline_1.utc)(row.published_at ?? null),
|
|
190
|
+
mergedAt: (0, timeline_1.utc)(row.merged_at ?? null), decidedAt: (0, timeline_1.utc)(row.decided_at ?? null), updatedAt: (0, timeline_1.utc)(String(row.updated_at)),
|
|
191
|
+
ticketIds: parseJson(row.ticket_ids, []),
|
|
192
|
+
review: unit && evidence ? reviewFact(unit.runtime ?? null, unit.sentinel, unit.sentinelDetail, (0, timeline_1.utc)(evidence.harvestedAt)) : null,
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
const deliveryRunIds = deliveryRows.flatMap((row) => parseJson(row.run_ids, []).filter((v) => typeof v === 'string'));
|
|
196
|
+
// ─── Runs and jobs ────────────────────────────────────────────────────────
|
|
197
|
+
const runIdSet = new Set();
|
|
198
|
+
for (const inv of invocations) {
|
|
199
|
+
if (inv.surface === 'job') {
|
|
200
|
+
const id = baseRunId(inv.refId);
|
|
201
|
+
if (id)
|
|
202
|
+
runIdSet.add(id);
|
|
203
|
+
}
|
|
204
|
+
if (inv.loopRunId)
|
|
205
|
+
runIdSet.add(inv.loopRunId);
|
|
206
|
+
}
|
|
207
|
+
for (const id of deliveryRunIds)
|
|
208
|
+
runIdSet.add(id);
|
|
209
|
+
const loopRunMatches = db.prepare(`
|
|
210
|
+
SELECT id FROM loop_runs
|
|
211
|
+
WHERE ticket_id = ? OR EXISTS (SELECT 1 FROM json_each(COALESCE(loop_runs.ticket_ids_json, '[]')) WHERE value = ?)
|
|
212
|
+
ORDER BY started_at DESC LIMIT ${MAX_RUNS}
|
|
213
|
+
`).all(ticketId, ticketId);
|
|
214
|
+
for (const row of loopRunMatches)
|
|
215
|
+
runIdSet.add(row.id);
|
|
216
|
+
const runs = [];
|
|
217
|
+
for (const ids of chunk([...runIdSet], 400)) {
|
|
218
|
+
const marks = placeholders(ids.length);
|
|
219
|
+
const loopRows = db.prepare(`SELECT id, loop_name, provider, model, status, final_outcome, started_at, finished_at FROM loop_runs WHERE id IN (${marks})`).all(...ids);
|
|
220
|
+
for (const row of loopRows)
|
|
221
|
+
runs.push({ ...row, started_at: (0, timeline_1.utc)(row.started_at), finished_at: (0, timeline_1.utc)(row.finished_at), source: 'run', command: null });
|
|
222
|
+
const seen = new Set(loopRows.map((r) => r.id));
|
|
223
|
+
const rest = ids.filter((id) => !seen.has(id));
|
|
224
|
+
if (rest.length > 0) {
|
|
225
|
+
const jobRows = db.prepare(`SELECT id, command, provider, model, status, started_at, finished_at FROM jobs WHERE id IN (${placeholders(rest.length)})`).all(...rest);
|
|
226
|
+
for (const row of jobRows)
|
|
227
|
+
runs.push({ id: row.id, loop_name: null, provider: row.provider, model: row.model, status: row.status, final_outcome: null, started_at: (0, timeline_1.utc)(row.started_at), finished_at: (0, timeline_1.utc)(row.finished_at), source: 'job', command: row.command });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
runs.sort((a, b) => (a.started_at < b.started_at ? 1 : -1));
|
|
231
|
+
const shownRuns = runs.slice(0, MAX_RUNS);
|
|
232
|
+
const runIds = shownRuns.map((r) => r.id);
|
|
233
|
+
const invocationsOfRun = (id) => invocations.filter((inv) => baseRunId(inv.refId) === id || inv.loopRunId === id);
|
|
234
|
+
for (const run of shownRuns) {
|
|
235
|
+
const mine = invocationsOfRun(run.id);
|
|
236
|
+
const tone = runTone(run.status, run.final_outcome);
|
|
237
|
+
const diagnosis = tone === 'failure' ? safeDiagnosis(db, run.id, run.status) : null;
|
|
238
|
+
const duration = run.finished_at ? Math.max(0, Date.parse(run.finished_at) - Date.parse(run.started_at)) : null;
|
|
239
|
+
entries.push({
|
|
240
|
+
id: `job:${run.id}`, at: run.started_at, kind: 'job', event: 'job.run',
|
|
241
|
+
params: { status: run.status, outcome: run.final_outcome, durationMs: Number.isFinite(duration) ? duration : null, failureKind: diagnosis?.kind ?? null },
|
|
242
|
+
title: clean(run.loop_name ?? run.command ?? run.id, 160) ?? run.id,
|
|
243
|
+
summary: clean(diagnosis?.detail ?? null),
|
|
244
|
+
actor: { type: 'agent', label: run.loop_name ? 'loop' : 'job', provider: run.provider ?? providerOf(mine) },
|
|
245
|
+
tone, provider: run.provider ?? providerOf(mine), ...costOf(mine), link: { place: 'job', id: run.id },
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
// Phases: grouped per job.
|
|
249
|
+
if (runIds.length > 0) {
|
|
250
|
+
const phaseRows = [];
|
|
251
|
+
for (const ids of chunk(runIds, 400)) {
|
|
252
|
+
phaseRows.push(...db.prepare(`SELECT job_id, phase, state, updated_at FROM job_phases WHERE job_id IN (${placeholders(ids.length)})`).all(...ids));
|
|
253
|
+
}
|
|
254
|
+
const byJob = new Map();
|
|
255
|
+
for (const row of phaseRows) {
|
|
256
|
+
const l = byJob.get(row.job_id) ?? [];
|
|
257
|
+
l.push(row);
|
|
258
|
+
byJob.set(row.job_id, l);
|
|
259
|
+
}
|
|
260
|
+
for (const [jobId, rows] of byJob) {
|
|
261
|
+
rows.sort((a, b) => (a.updated_at < b.updated_at ? -1 : 1));
|
|
262
|
+
const failed = rows.filter((r) => r.state === 'failed' || r.state === 'error').length;
|
|
263
|
+
entries.push({
|
|
264
|
+
id: `phases:${jobId}`, at: (0, timeline_1.utc)(rows[rows.length - 1].updated_at), kind: 'phase', event: 'phase.group',
|
|
265
|
+
params: { count: rows.length, failed }, title: `${rows.length} phases`, summary: clean(rows.map((r) => r.phase).join(' → '), 200),
|
|
266
|
+
actor: null, tone: failed > 0 ? 'failure' : 'neutral', provider: null, link: { place: 'job', id: jobId }, count: rows.length,
|
|
267
|
+
items: rows.slice(0, timeline_1.TIMELINE_MAX_ITEMS).map((r) => ({ at: (0, timeline_1.utc)(r.updated_at), label: r.phase, detail: r.state, ...(r.state === 'failed' || r.state === 'error' ? { tone: 'failure' } : {}) })),
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
// Agent actions audit: grouped per run.
|
|
271
|
+
const actionRows = [];
|
|
272
|
+
for (const ids of chunk(runIds, 200)) {
|
|
273
|
+
const marks = placeholders(ids.length);
|
|
274
|
+
actionRows.push(...db.prepare(`SELECT run_id, job_id, role, kind, target, ts FROM agent_actions WHERE run_id IN (${marks}) OR job_id IN (${marks}) ORDER BY ts DESC LIMIT 5000`).all(...ids, ...ids));
|
|
275
|
+
}
|
|
276
|
+
const known = new Set(runIds);
|
|
277
|
+
const byRun = new Map();
|
|
278
|
+
for (const row of actionRows) {
|
|
279
|
+
const key = known.has(row.run_id) ? row.run_id : row.job_id && known.has(row.job_id) ? row.job_id : null;
|
|
280
|
+
if (!key)
|
|
281
|
+
continue;
|
|
282
|
+
const l = byRun.get(key) ?? [];
|
|
283
|
+
l.push(row);
|
|
284
|
+
byRun.set(key, l);
|
|
285
|
+
}
|
|
286
|
+
for (const [runId, rows] of byRun) {
|
|
287
|
+
const counts = { read: 0, write: 0, exec: 0, mcp: 0, network: 0 };
|
|
288
|
+
for (const row of rows)
|
|
289
|
+
counts[row.kind] = (counts[row.kind] ?? 0) + 1;
|
|
290
|
+
// Reads dominate and say little: details lead with what changed or ran.
|
|
291
|
+
const notable = rows.filter((r) => r.kind !== 'read');
|
|
292
|
+
const roles = [...new Set(rows.map((r) => r.role))];
|
|
293
|
+
entries.push({
|
|
294
|
+
id: `audit:${runId}`, at: (0, timeline_1.utc)(rows.reduce((max, r) => (r.ts > max ? r.ts : max), rows[0].ts)), kind: 'audit', event: 'audit.group',
|
|
295
|
+
params: { count: rows.length, ...counts }, title: `${rows.length} agent actions`, summary: null,
|
|
296
|
+
actor: roles.length === 1 ? { type: 'agent', label: roles[0], provider: null } : null, tone: 'neutral', provider: null,
|
|
297
|
+
link: { place: 'job', id: runId }, count: rows.length,
|
|
298
|
+
items: notable.slice(0, timeline_1.TIMELINE_MAX_ITEMS).map((r) => ({ at: (0, timeline_1.utc)(r.ts), label: r.kind, detail: clean(r.target, 200), })),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// ─── PR events and review ─────────────────────────────────────────────────
|
|
303
|
+
for (const d of deliveries) {
|
|
304
|
+
const link = { place: 'review', id: d.id };
|
|
305
|
+
const failed = d.decision === 'implementation_failed' || d.decision === 'pr_failed';
|
|
306
|
+
entries.push({
|
|
307
|
+
id: `pr:${d.id}:created`, at: d.createdAt, kind: 'pr_event', event: 'pr.delivery_started', params: { loop: d.loopName },
|
|
308
|
+
title: 'Delivery started', summary: clean(d.loopName), actor: null, tone: 'neutral', provider: null, link,
|
|
309
|
+
});
|
|
310
|
+
if (d.onReviewAt) {
|
|
311
|
+
entries.push({ id: `pr:${d.id}:review`, at: d.onReviewAt, kind: 'pr_event', event: 'pr.ready_for_review', params: {}, title: 'Ready for review', summary: null, actor: null, tone: 'review', provider: null, link });
|
|
312
|
+
}
|
|
313
|
+
if (d.publishedAt) {
|
|
314
|
+
entries.push({
|
|
315
|
+
id: `pr:${d.id}:published`, at: d.publishedAt, kind: 'pr_event', event: 'pr.published', params: { prNumber: d.prNumber },
|
|
316
|
+
title: d.prNumber ? `PR #${d.prNumber}` : 'PR published', summary: clean(d.branch), actor: null, tone: 'ok', provider: null, link, url: d.prUrl,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
if (d.mergedAt) {
|
|
320
|
+
entries.push({ id: `pr:${d.id}:merged`, at: d.mergedAt, kind: 'pr_event', event: 'pr.merged', params: { prNumber: d.prNumber }, title: 'Merged', summary: null, actor: null, tone: 'ok', provider: null, link, url: d.prUrl });
|
|
321
|
+
}
|
|
322
|
+
else if (d.decidedAt && (failed || d.decision === 'discarded' || d.decision === 'superseded')) {
|
|
323
|
+
entries.push({
|
|
324
|
+
id: `pr:${d.id}:closed`, at: d.decidedAt, kind: 'pr_event', event: `pr.${failed ? 'failed' : d.decision}`, params: { decision: d.decision },
|
|
325
|
+
title: failed ? 'Delivery failed' : d.decision, summary: clean(d.statusDetail), actor: null, tone: failed ? 'failure' : 'neutral', provider: null, link,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
if (d.review) {
|
|
329
|
+
const r = d.review;
|
|
330
|
+
const verdict = r.approved === true ? 'approved' : r.approved === false ? 'changes_requested' : r.sentinel === 'fail' ? 'failed' : 'recorded';
|
|
331
|
+
entries.push({
|
|
332
|
+
id: `review:${d.id}`, at: r.harvestedAt, kind: 'review', event: 'review.verdict',
|
|
333
|
+
params: { verdict, findings: r.findings.length, score: r.score },
|
|
334
|
+
title: `Review: ${verdict}`, summary: clean(r.summary ?? r.sentinelDetail, 400),
|
|
335
|
+
actor: { type: 'agent', label: 'reviewer', provider: null }, tone: r.approved === true && r.findings.length === 0 ? 'ok' : 'review', provider: null,
|
|
336
|
+
link, count: r.findings.length || undefined,
|
|
337
|
+
items: r.findings.slice(0, timeline_1.TIMELINE_MAX_ITEMS).map((f) => ({ at: null, label: f.text, detail: f.location, tone: 'review' })),
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return { entries: (0, timeline_1.sortTimeline)(entries), invocations, deliveries, runIds };
|
|
342
|
+
}
|
|
343
|
+
function safeDiagnosis(db, runId, status) {
|
|
344
|
+
try {
|
|
345
|
+
const d = (0, sqlite_1.readJobDiagnosis)(db, runId, status);
|
|
346
|
+
return d ? { kind: d.kind, detail: d.detail } : null;
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function reviewFact(runtime, sentinel, sentinelDetail, harvestedAt) {
|
|
353
|
+
const findingTexts = runtime?.findings ?? [];
|
|
354
|
+
const locations = new Map();
|
|
355
|
+
for (const loc of runtime?.findingLocations ?? []) {
|
|
356
|
+
if (!locations.has(loc.finding)) {
|
|
357
|
+
const text = (0, timeline_1.formatLocation)(loc);
|
|
358
|
+
if (text)
|
|
359
|
+
locations.set(loc.finding, text);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
const issues = runtime?.review?.issues ?? [];
|
|
363
|
+
const hasSignal = runtime?.review || findingTexts.length > 0 || sentinel !== 'absent';
|
|
364
|
+
if (!hasSignal)
|
|
365
|
+
return null;
|
|
366
|
+
return {
|
|
367
|
+
harvestedAt,
|
|
368
|
+
approved: runtime?.review?.approved ?? null,
|
|
369
|
+
score: runtime?.review?.score ?? null,
|
|
370
|
+
summary: runtime?.review?.summary ?? null,
|
|
371
|
+
issues: issues.map((i) => (0, audit_1.redactProse)(String(i))).slice(0, 20),
|
|
372
|
+
findings: findingTexts.slice(0, 50).map((text, index) => ({ text: (0, audit_1.redactProse)((0, timeline_1.oneLine)(text, 300) ?? ''), location: locations.get(index) ?? null })),
|
|
373
|
+
sentinel: sentinel === 'absent' ? null : sentinel,
|
|
374
|
+
sentinelDetail: sentinelDetail ? (0, audit_1.redactProse)(sentinelDetail) : null,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
@@ -13,6 +13,7 @@ const providers_1 = require("../../../providers");
|
|
|
13
13
|
const result_event_1 = require("../../accounting/runtime/result-event");
|
|
14
14
|
const ai_invocations_1 = require("../../accounting/runtime/ai-invocations");
|
|
15
15
|
const runtime_1 = require("../../../providers/runtime");
|
|
16
|
+
const project_env_1 = require("../../../project-env");
|
|
16
17
|
const loop_command_catalog_1 = require("../../loops/runtime/loop-command-catalog");
|
|
17
18
|
const workspace_resolution_1 = require("../../../workspace-resolution");
|
|
18
19
|
// ─── SpecLauncherManager ──────────────────────────────────────────────────────
|
|
@@ -159,7 +160,7 @@ class SpecLauncherManager {
|
|
|
159
160
|
? `${(0, loop_command_catalog_1.expandCommands)('{{cmd:opsx:ff}}', { provider: this._adapter.id })} ${description}`
|
|
160
161
|
: resolvedPrompt;
|
|
161
162
|
if (providerCommand === rawCommand) {
|
|
162
|
-
this._broadcastError(launchId, 'This project does not have the /opsx:ff command installed.
|
|
163
|
+
this._broadcastError(launchId, 'This project does not have the /opsx:ff command installed. Update Specrails Core from Settings → Updates.');
|
|
163
164
|
return;
|
|
164
165
|
}
|
|
165
166
|
let prompt;
|
|
@@ -180,10 +181,10 @@ class SpecLauncherManager {
|
|
|
180
181
|
};
|
|
181
182
|
const args = this._adapter.buildArgs('spec-gen', spawnOptions);
|
|
182
183
|
const child = (0, cli_prompt_1.spawnAiCli)(this._adapter.binary, args, {
|
|
183
|
-
env: (0, runtime_1.buildProviderEnv)(this._adapter, spawnOptions, {
|
|
184
|
+
env: (0, runtime_1.buildProviderEnv)(this._adapter, spawnOptions, (0, project_env_1.projectAgentSourceEnv)(this._db, (0, runtime_1.providerEnvAllowlist)(this._adapter), {
|
|
184
185
|
...process.env,
|
|
185
186
|
...execution.env,
|
|
186
|
-
}),
|
|
187
|
+
})),
|
|
187
188
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
188
189
|
cwd: execution.cwd,
|
|
189
190
|
});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SPEC_SEARCH_MAX_LIMIT = exports.SPEC_SEARCH_DEFAULT_LIMIT = void 0;
|
|
4
|
+
exports.searchSpecs = searchSpecs;
|
|
5
|
+
// Spec search for the ⌘K `#` scope (CD6). Specs live in the project's ticket
|
|
6
|
+
// store (a JSON file Core also writes), not in SQLite, so an FTS table would be
|
|
7
|
+
// a second copy to keep in step with external writers. A project holds tens to
|
|
8
|
+
// a few hundred specs: a folded-substring scan over title, summary, description,
|
|
9
|
+
// labels, non-goals, addenda and comments is exact, always current, and cheap.
|
|
10
|
+
// Matching ignores case and diacritics; snippets share the mission highlight
|
|
11
|
+
// shape (text + ranges) so the client renders every scope the same way.
|
|
12
|
+
const ticket_store_1 = require("./ticket-store");
|
|
13
|
+
exports.SPEC_SEARCH_DEFAULT_LIMIT = 8;
|
|
14
|
+
exports.SPEC_SEARCH_MAX_LIMIT = 30;
|
|
15
|
+
const CONTEXT = 60;
|
|
16
|
+
/** Fold to lowercase without diacritics, keeping a map back to original offsets. */
|
|
17
|
+
function foldWithMap(text) {
|
|
18
|
+
let folded = '';
|
|
19
|
+
const map = [];
|
|
20
|
+
let offset = 0;
|
|
21
|
+
for (const ch of text) {
|
|
22
|
+
const piece = ch.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase();
|
|
23
|
+
for (let i = 0; i < piece.length; i++)
|
|
24
|
+
map.push(offset);
|
|
25
|
+
folded += piece;
|
|
26
|
+
offset += ch.length;
|
|
27
|
+
}
|
|
28
|
+
map.push(offset);
|
|
29
|
+
return { folded, map };
|
|
30
|
+
}
|
|
31
|
+
function foldPlain(text) {
|
|
32
|
+
return foldWithMap(text).folded;
|
|
33
|
+
}
|
|
34
|
+
/** Window of ~CONTEXT characters on each side of the first match, with its range. */
|
|
35
|
+
function snippetAround(text, needle) {
|
|
36
|
+
const { folded, map } = foldWithMap(text);
|
|
37
|
+
const at = folded.indexOf(needle);
|
|
38
|
+
if (at < 0)
|
|
39
|
+
return null;
|
|
40
|
+
const matchStart = map[at];
|
|
41
|
+
const matchEnd = map[Math.min(at + needle.length, folded.length)];
|
|
42
|
+
const start = Math.max(0, matchStart - CONTEXT);
|
|
43
|
+
const end = Math.min(text.length, matchEnd + CONTEXT);
|
|
44
|
+
const prefix = start > 0 ? '…' : '';
|
|
45
|
+
const suffix = end < text.length ? '…' : '';
|
|
46
|
+
// Whitespace collapsing keeps ranges honest by working segment by segment.
|
|
47
|
+
const before = text.slice(start, matchStart).replace(/\s+/g, ' ');
|
|
48
|
+
const hit = text.slice(matchStart, matchEnd).replace(/\s+/g, ' ');
|
|
49
|
+
const after = text.slice(matchEnd, end).replace(/\s+/g, ' ');
|
|
50
|
+
const lead = prefix + before;
|
|
51
|
+
return { text: lead + hit + after + suffix, ranges: [[lead.length, lead.length + hit.length]] };
|
|
52
|
+
}
|
|
53
|
+
function candidates(ticket) {
|
|
54
|
+
const out = [{ field: 'title', text: ticket.title ?? '' }];
|
|
55
|
+
if (ticket.short_summary)
|
|
56
|
+
out.push({ field: 'summary', text: ticket.short_summary });
|
|
57
|
+
if (ticket.description)
|
|
58
|
+
out.push({ field: 'description', text: ticket.description });
|
|
59
|
+
for (const label of ticket.labels ?? [])
|
|
60
|
+
out.push({ field: 'label', text: label });
|
|
61
|
+
for (const goal of ticket.nonGoals ?? [])
|
|
62
|
+
out.push({ field: 'nonGoal', text: goal });
|
|
63
|
+
for (const addendum of ticket.addenda ?? []) {
|
|
64
|
+
out.push({ field: 'addendum', text: addendum.title });
|
|
65
|
+
out.push({ field: 'addendum', text: addendum.body });
|
|
66
|
+
}
|
|
67
|
+
for (const comment of ticket.comments ?? [])
|
|
68
|
+
out.push({ field: 'comment', text: comment.body });
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
const FIELD_RANK = {
|
|
72
|
+
id: 0, title: 1, summary: 2, label: 3, description: 4, nonGoal: 5, addendum: 6, comment: 7,
|
|
73
|
+
};
|
|
74
|
+
function searchSpecs(tickets, rawQuery, limit = exports.SPEC_SEARCH_DEFAULT_LIMIT) {
|
|
75
|
+
const query = rawQuery.trim().replace(/^#/, '').trim();
|
|
76
|
+
if (!query)
|
|
77
|
+
return [];
|
|
78
|
+
const cap = Math.max(1, Math.min(exports.SPEC_SEARCH_MAX_LIMIT, Math.floor(limit)));
|
|
79
|
+
const needle = foldPlain(query);
|
|
80
|
+
const idQuery = /^\d+$/.test(query) ? Number(query) : null;
|
|
81
|
+
const scored = [];
|
|
82
|
+
for (const ticket of tickets) {
|
|
83
|
+
if ((0, ticket_store_1.isFlowHeldTicket)(ticket))
|
|
84
|
+
continue;
|
|
85
|
+
let best = null;
|
|
86
|
+
if (idQuery !== null && ticket.id === idQuery) {
|
|
87
|
+
best = { field: 'id', text: ticket.title };
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
for (const c of candidates(ticket)) {
|
|
91
|
+
if (!foldPlain(c.text).includes(needle))
|
|
92
|
+
continue;
|
|
93
|
+
if (!best || FIELD_RANK[c.field] < FIELD_RANK[best.field])
|
|
94
|
+
best = c;
|
|
95
|
+
if (best.field === 'title')
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (!best)
|
|
100
|
+
continue;
|
|
101
|
+
const startsWithTitle = best.field === 'title' && foldPlain(ticket.title).startsWith(needle);
|
|
102
|
+
scored.push({
|
|
103
|
+
hit: {
|
|
104
|
+
id: ticket.id,
|
|
105
|
+
title: ticket.title,
|
|
106
|
+
status: ticket.status,
|
|
107
|
+
priority: ticket.priority,
|
|
108
|
+
field: best.field,
|
|
109
|
+
snippet: best.field === 'id' ? null : snippetAround(best.text, needle),
|
|
110
|
+
},
|
|
111
|
+
rank: FIELD_RANK[best.field] * 2 + (startsWithTitle ? 0 : 1),
|
|
112
|
+
updated: ticket.updated_at ?? '',
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
scored.sort((a, b) => a.rank - b.rank || b.updated.localeCompare(a.updated) || b.hit.id - a.hit.id);
|
|
116
|
+
return scored.slice(0, cap).map((s) => s.hit);
|
|
117
|
+
}
|
|
@@ -3,9 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.SHORT_SUMMARY_MAX_LEN = exports.CURRENT_SCHEMA_VERSION = void 0;
|
|
6
|
+
exports.REGRESSION_OF_MAX_LEN = exports.SHORT_SUMMARY_MAX_LEN = exports.CURRENT_SCHEMA_VERSION = void 0;
|
|
7
|
+
exports.isFlowHeldTicket = isFlowHeldTicket;
|
|
8
|
+
exports.normalizeRegressionOfMetadata = normalizeRegressionOfMetadata;
|
|
9
|
+
exports.listRegressionLinks = listRegressionLinks;
|
|
7
10
|
exports.clampShortSummary = clampShortSummary;
|
|
8
11
|
exports.resolveTicketStoragePath = resolveTicketStoragePath;
|
|
12
|
+
exports.acquireFileLock = acquireLock;
|
|
13
|
+
exports.releaseFileLock = releaseLock;
|
|
9
14
|
exports.validateEpicChildIntegrity = validateEpicChildIntegrity;
|
|
10
15
|
exports.readStore = readStore;
|
|
11
16
|
exports.applyJobOutcomeToTickets = applyJobOutcomeToTickets;
|
|
@@ -20,10 +25,46 @@ exports.validatePriorityForStatus = validatePriorityForStatus;
|
|
|
20
25
|
const fs_1 = __importDefault(require("fs"));
|
|
21
26
|
const path_1 = __importDefault(require("path"));
|
|
22
27
|
const spec_addenda_core_1 = require("./spec-addenda-core");
|
|
28
|
+
const non_goals_1 = require("../domain/non-goals");
|
|
29
|
+
/** True while a spec belongs to a live Flow: no Jira write may create or
|
|
30
|
+
* update an issue for it until the Flow -> Spec rail settles. */
|
|
31
|
+
function isFlowHeldTicket(ticket) {
|
|
32
|
+
const state = ticket?.metadata?.flow?.state;
|
|
33
|
+
return state === 'active' || state === 'paused';
|
|
34
|
+
}
|
|
23
35
|
const VALID_STATUSES = new Set(['draft', 'todo', 'in_progress', 'on_review', 'done', 'cancelled']);
|
|
24
36
|
const VALID_PRIORITIES = new Set(['critical', 'high', 'medium', 'low']);
|
|
25
|
-
exports.CURRENT_SCHEMA_VERSION = '1.
|
|
37
|
+
exports.CURRENT_SCHEMA_VERSION = '1.5';
|
|
26
38
|
exports.SHORT_SUMMARY_MAX_LEN = 240;
|
|
39
|
+
exports.REGRESSION_OF_MAX_LEN = 200;
|
|
40
|
+
/**
|
|
41
|
+
* Validate the `regressionOf` key of an incoming metadata patch. Absent ⇒
|
|
42
|
+
* untouched; `null`/empty ⇒ cleared (key removed); a non-empty string ≤
|
|
43
|
+
* REGRESSION_OF_MAX_LEN ⇒ trimmed; anything else ⇒ error. Returns the
|
|
44
|
+
* metadata to merge plus the keys to delete after merging.
|
|
45
|
+
*/
|
|
46
|
+
function normalizeRegressionOfMetadata(metadata) {
|
|
47
|
+
if (!Object.prototype.hasOwnProperty.call(metadata, 'regressionOf'))
|
|
48
|
+
return { ok: true, metadata, clear: false };
|
|
49
|
+
const { regressionOf, ...rest } = metadata;
|
|
50
|
+
if (regressionOf === null || (typeof regressionOf === 'string' && regressionOf.trim() === '')) {
|
|
51
|
+
return { ok: true, metadata: rest, clear: true };
|
|
52
|
+
}
|
|
53
|
+
if (typeof regressionOf !== 'string' || regressionOf.trim().length > exports.REGRESSION_OF_MAX_LEN) {
|
|
54
|
+
return { ok: false, error: `metadata.regressionOf must be a delivery id string (max ${exports.REGRESSION_OF_MAX_LEN} chars) or null` };
|
|
55
|
+
}
|
|
56
|
+
return { ok: true, metadata: { ...rest, regressionOf: regressionOf.trim() }, clear: false };
|
|
57
|
+
}
|
|
58
|
+
/** Every ticket's escaped-defect link (`metadata.regressionOf`). */
|
|
59
|
+
function listRegressionLinks(store) {
|
|
60
|
+
const links = [];
|
|
61
|
+
for (const ticket of Object.values(store.tickets)) {
|
|
62
|
+
const deliveryId = ticket?.metadata?.regressionOf;
|
|
63
|
+
if (typeof deliveryId === 'string' && deliveryId.length > 0)
|
|
64
|
+
links.push({ ticketId: ticket.id, deliveryId });
|
|
65
|
+
}
|
|
66
|
+
return links;
|
|
67
|
+
}
|
|
27
68
|
/**
|
|
28
69
|
* Sanitize a `shortSummary` value coming from an AI response or external input.
|
|
29
70
|
* - Returns `null` for nullish, non-string, or empty-after-trim values.
|
|
@@ -222,6 +263,10 @@ function normalizeTicket(t) {
|
|
|
222
263
|
// Schema 1.4 field: spec addenda. Absent ⇒ [], and a malformed entry is
|
|
223
264
|
// dropped rather than crashing the whole store read.
|
|
224
265
|
t.addenda = (0, spec_addenda_core_1.readSpecAddenda)(t.addenda);
|
|
266
|
+
// Non-goals (3.2): present ⇒ cleaned and bounded; absent stays absent so
|
|
267
|
+
// older tickets round-trip byte-identically.
|
|
268
|
+
if (t.nonGoals !== undefined)
|
|
269
|
+
t.nonGoals = (0, non_goals_1.normalizeNonGoals)(t.nonGoals);
|
|
225
270
|
return t;
|
|
226
271
|
}
|
|
227
272
|
/**
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.finalizeTrashedTicket = finalizeTrashedTicket;
|
|
4
|
+
exports.purgeProjectTrash = purgeProjectTrash;
|
|
5
|
+
exports.startProjectTrashPurge = startProjectTrashPurge;
|
|
6
|
+
const db_1 = require("../../../db");
|
|
7
|
+
const ticket_store_1 = require("./ticket-store");
|
|
8
|
+
const ticket_trash_1 = require("./ticket-trash");
|
|
9
|
+
/**
|
|
10
|
+
* Run the cascade a hard delete used to run inline: attachments, and the Explore
|
|
11
|
+
* conversation of a draft nothing else references. Skips a spec that is live
|
|
12
|
+
* again (a crash leftover) so purge never strips a restored spec of its files.
|
|
13
|
+
*/
|
|
14
|
+
async function finalizeTrashedTicket(deps, entry) {
|
|
15
|
+
const ticket = entry.ticket;
|
|
16
|
+
const store = (0, ticket_store_1.readStore)(deps.ticketStorePath());
|
|
17
|
+
if (store.tickets[String(ticket.id)])
|
|
18
|
+
return;
|
|
19
|
+
await deps.deleteAttachments(String(ticket.id)).catch((e) => {
|
|
20
|
+
console.error('[ticket-trash] attachment cascade delete failed:', e);
|
|
21
|
+
});
|
|
22
|
+
const conversationId = ticket.status === 'draft' ? ticket.origin_conversation_id : null;
|
|
23
|
+
if (!conversationId)
|
|
24
|
+
return;
|
|
25
|
+
const stillReferenced = Object.values(store.tickets).some((other) => other.origin_conversation_id === conversationId);
|
|
26
|
+
if (stillReferenced)
|
|
27
|
+
return;
|
|
28
|
+
try {
|
|
29
|
+
const conv = (0, db_1.getConversation)(deps.db, conversationId);
|
|
30
|
+
if (conv && conv.kind === 'explore') {
|
|
31
|
+
(0, db_1.deleteConversation)(deps.db, conversationId);
|
|
32
|
+
deps.forgetExploreConversation?.(conversationId);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
console.error('[ticket-trash] orphan conversation cleanup failed:', err);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Purge every expired spec of one project and run their cascades. Idempotent. */
|
|
40
|
+
async function purgeProjectTrash(deps, now = new Date(), retentionMs = ticket_trash_1.TRASH_RETENTION_MS) {
|
|
41
|
+
let expired;
|
|
42
|
+
try {
|
|
43
|
+
expired = (0, ticket_trash_1.purgeExpiredTickets)(deps.ticketStorePath(), now, retentionMs);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error('[ticket-trash] purge failed:', err);
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
for (const entry of expired)
|
|
50
|
+
await finalizeTrashedTicket(deps, entry);
|
|
51
|
+
return expired.length;
|
|
52
|
+
}
|
|
53
|
+
const PURGE_INTERVAL_MS = 6 * 60 * 60 * 1000;
|
|
54
|
+
/** Purge now (startup) and every few hours while the project is loaded. */
|
|
55
|
+
function startProjectTrashPurge(deps) {
|
|
56
|
+
const run = () => { void purgeProjectTrash(deps); };
|
|
57
|
+
const first = setTimeout(run, 5_000);
|
|
58
|
+
const timer = setInterval(run, PURGE_INTERVAL_MS);
|
|
59
|
+
first.unref?.();
|
|
60
|
+
timer.unref?.();
|
|
61
|
+
return { stop: () => { clearTimeout(first); clearInterval(timer); } };
|
|
62
|
+
}
|