specrails-desktop 2.2.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/dist/assets/ActivityFeedPage-DJJlZ3mF.js +1 -0
- package/client/dist/assets/AgentsPage-49JaEDjR.js +86 -0
- package/client/dist/assets/{AnalyticsPage-BD0paa75.js → AnalyticsPage-BUd3gWYC.js} +1 -1
- package/client/dist/assets/{BarChart-D8ZZRab3.js → BarChart-HDe_YoUD.js} +1 -1
- package/client/dist/assets/CodePage-CqPPND47.js +2 -0
- package/client/dist/assets/{DesktopAnalyticsPage-mwd8460_.js → DesktopAnalyticsPage-CgvmSvF0.js} +1 -1
- package/client/dist/assets/DocsDialog-hHFd3Ejs.js +11 -0
- package/client/dist/assets/DocsPage-B4R1aksg.js +11 -0
- package/client/dist/assets/{ExportDropdown-CLYmQhic.js → ExportDropdown-f4dwQjlT.js} +1 -1
- package/client/dist/assets/IntegrationsPage-CX2Ybxx0.js +3 -0
- package/client/dist/assets/JobDetailPage-DN2Jc8Ti.js +16 -0
- package/client/dist/assets/JobsPage-DmdpqijT.js +1 -0
- package/client/dist/assets/code-BwIz8agY.js +1 -0
- package/client/dist/assets/code-CD7yNSK0.js +1 -0
- package/client/dist/assets/code-CDFlxUFC.js +1 -0
- package/client/dist/assets/code-CY85RXZU.js +1 -0
- package/client/dist/assets/code-Cp3Fdng-.js +1 -0
- package/client/dist/assets/code-D24e1Crx.js +1 -0
- package/client/dist/assets/code-DtZBQTi9.js +1 -0
- package/client/dist/assets/code-nKa0fkm_.js +1 -0
- package/client/dist/assets/{cssMode-Cc6ozl-J.js → cssMode-DzNPAYFh.js} +1 -1
- package/client/dist/assets/{dist-js-D3MxtOYa.js → dist-js-COfIfLRE.js} +1 -1
- package/client/dist/assets/{dist-js-BOu_cXw3.js → dist-js-CvScGQU_.js} +1 -1
- package/client/dist/assets/{editor.main-CfXxHimg.js → editor.main-C7Rmw-hR.js} +2 -2
- package/client/dist/assets/{freemarker2-DP7J1gG3.js → freemarker2-Cszs4SVo.js} +1 -1
- package/client/dist/assets/{handlebars-BjRlucw6.js → handlebars-Dp7Lsuym.js} +1 -1
- package/client/dist/assets/{html-OumBQJ-U.js → html-BURidrEm.js} +1 -1
- package/client/dist/assets/{htmlMode-CStc3zXM.js → htmlMode--k5M7GjZ.js} +1 -1
- package/client/dist/assets/index-DBpvYrDK.css +2 -0
- package/client/dist/assets/index-DGIXKRHE.js +142 -0
- package/client/dist/assets/{integrations-Cublz3m6.js → integrations-2C7MkGT0.js} +1 -1
- package/client/dist/assets/{integrations-HIlUxXVs.js → integrations-BDC670cg.js} +1 -1
- package/client/dist/assets/integrations-BqUmRUef.js +1 -0
- package/client/dist/assets/{integrations-DmQYCUvN.js → integrations-C2jQtv-s.js} +1 -1
- package/client/dist/assets/{integrations-DRdbki5W.js → integrations-CB98NeH5.js} +1 -1
- package/client/dist/assets/{integrations-C3p12Ms6.js → integrations-CX4p_bij.js} +1 -1
- package/client/dist/assets/{integrations-DaC4SzzL.js → integrations-_SuVeQIG.js} +1 -1
- package/client/dist/assets/{integrations-Cr6hH7XR.js → integrations-eQPHAYsE.js} +1 -1
- package/client/dist/assets/{javascript-CMk--e7g.js → javascript-kJQz__44.js} +1 -1
- package/client/dist/assets/jira-C-ATCti0.js +1 -0
- package/client/dist/assets/jira-CmVfRM-b.js +1 -0
- package/client/dist/assets/jira-D7bkKAX8.js +1 -0
- package/client/dist/assets/jira-DKImM1YH.js +1 -0
- package/client/dist/assets/jira-DOw8bkIR.js +1 -0
- package/client/dist/assets/jira-DlA-wGp-.js +1 -0
- package/client/dist/assets/jira-Fob8EGxN.js +1 -0
- package/client/dist/assets/jira-xZA2lixb.js +1 -0
- package/client/dist/assets/{jsonMode-C2h3ZcjZ.js → jsonMode-v5JYPpnz.js} +1 -1
- package/client/dist/assets/{lib-DQ2hrj8m.js → lib-Bro9Z0gp.js} +1 -1
- package/client/dist/assets/{liquid-mI3KJrBE.js → liquid-Dl9I6gWt.js} +1 -1
- package/client/dist/assets/{lspLanguageFeatures-DU09ggWi.js → lspLanguageFeatures-CPlEe0NK.js} +1 -1
- package/client/dist/assets/{mdx-C41VDTR_.js → mdx-Byl7TtzQ.js} +1 -1
- package/client/dist/assets/{monaco.contribution-CPObAXMC.js → monaco.contribution-YMAkHQcQ.js} +2 -2
- package/client/dist/assets/{python-Y27rKQtk.js → python-jWQwT6j2.js} +1 -1
- package/client/dist/assets/{razor-Cd5-q9Bp.js → razor-BWS3sP-E.js} +1 -1
- package/client/dist/assets/setup-C0dzw8j4.js +1 -0
- package/client/dist/assets/setup-C1IA-9YS.js +1 -0
- package/client/dist/assets/setup-CpfjaNut.js +1 -0
- package/client/dist/assets/setup-D3rNZA9A.js +1 -0
- package/client/dist/assets/setup-UD2aanGs.js +1 -0
- package/client/dist/assets/setup-WP6WOYQh.js +1 -0
- package/client/dist/assets/setup-gzLG8T6F.js +1 -0
- package/client/dist/assets/setup-pjgmYHx6.js +1 -0
- package/client/dist/assets/specs-4lA_u79w.js +1 -0
- package/client/dist/assets/{specs-D2FzlLn9.js → specs-BHjxcjOf.js} +1 -1
- package/client/dist/assets/{specs-CZ1PsXsC.js → specs-CXNQzPk9.js} +1 -1
- package/client/dist/assets/{specs-Dyc5hYeE.js → specs-DFnc2Huj.js} +1 -1
- package/client/dist/assets/{specs-BFfu3u-a.js → specs-DZCLH2-l.js} +1 -1
- package/client/dist/assets/{specs-B__C8-8a.js → specs-DgmyAE3N.js} +1 -1
- package/client/dist/assets/{specs-DaUTrNF9.js → specs-DicWhvwi.js} +1 -1
- package/client/dist/assets/{specs-k0PyLDVt.js → specs-dkro6lSM.js} +1 -1
- package/client/dist/assets/{tsMode-B0y_xEci.js → tsMode-BbOGOuSV.js} +1 -1
- package/client/dist/assets/{typescript-BzK0OgwW.js → typescript-eBtFQJLs.js} +1 -1
- package/client/dist/assets/{useProjectCache-BxY4aTjd.js → useProjectCache-D9juBhsO.js} +1 -1
- package/client/dist/assets/{workers-rt--R2Qy.js → workers-BvicOoDf.js} +1 -1
- package/client/dist/assets/{xml-eX9QXAmI.js → xml-BJepAPyM.js} +1 -1
- package/client/dist/assets/{yaml-fcsNkpOt.js → yaml-DabgV-eA.js} +1 -1
- package/client/dist/index.html +13 -12
- package/docs/jira-integration-plan.md +321 -0
- package/package.json +1 -1
- package/server/dist/agent-refine-manager.js +128 -153
- package/server/dist/chat-manager.js +242 -0
- package/server/dist/code-explorer-router.js +78 -0
- package/server/dist/command-resolver.js +17 -0
- package/server/dist/contract-refine-runner.js +42 -10
- package/server/dist/db.js +86 -0
- package/server/dist/desktop-db.js +3 -0
- package/server/dist/explore-stdin-session.js +129 -0
- package/server/dist/feature-flags.js +11 -0
- package/server/dist/jira/jira-adf.js +113 -0
- package/server/dist/jira/jira-backlog-config.js +58 -0
- package/server/dist/jira/jira-client.js +279 -0
- package/server/dist/jira/jira-credential-store.js +103 -0
- package/server/dist/jira/jira-db.js +341 -0
- package/server/dist/jira/jira-issue-fields.js +428 -0
- package/server/dist/jira/jira-materializer.js +250 -0
- package/server/dist/jira/jira-status-resolver.js +211 -0
- package/server/dist/jira/jira-sync-manager.js +1014 -0
- package/server/dist/jira/types.js +9 -0
- package/server/dist/jira-router.js +304 -0
- package/server/dist/mobile/mobile-auth.js +16 -0
- package/server/dist/project-registry.js +43 -1
- package/server/dist/project-router-chat.js +218 -0
- package/server/dist/project-router-helpers.js +275 -0
- package/server/dist/project-router-jobs.js +389 -0
- package/server/dist/project-router-settings.js +312 -0
- package/server/dist/project-router-setup.js +456 -0
- package/server/dist/project-router-spending.js +320 -0
- package/server/dist/project-router-terminals.js +312 -0
- package/server/dist/project-router-tickets.js +1815 -0
- package/server/dist/project-router.js +31 -3950
- package/server/dist/providers/claude-adapter.js +23 -0
- package/server/dist/providers/codex-adapter.js +6 -0
- package/server/dist/rails-router.js +12 -0
- package/server/dist/spawn-lifecycle.js +117 -0
- package/client/dist/assets/ActivityFeedPage-BpjXuX2H.js +0 -1
- package/client/dist/assets/AgentsPage-D-7fDbTc.js +0 -86
- package/client/dist/assets/CodePage-B6q6CiYJ.js +0 -2
- package/client/dist/assets/DocsDialog-D_dyF2h9.js +0 -11
- package/client/dist/assets/DocsPage-C9-Ru8wE.js +0 -11
- package/client/dist/assets/IntegrationsPage-3WWtx9hi.js +0 -3
- package/client/dist/assets/JobDetailPage-DgN-79s-.js +0 -16
- package/client/dist/assets/JobsPage-Du8_w1ob.js +0 -1
- package/client/dist/assets/code-AL1rVIMb.js +0 -1
- package/client/dist/assets/code-C0BKpkht.js +0 -1
- package/client/dist/assets/code-C0FTS3ew.js +0 -1
- package/client/dist/assets/code-CPcHxzxw.js +0 -1
- package/client/dist/assets/code-D3ryDniw.js +0 -1
- package/client/dist/assets/code-D3zVVQTj.js +0 -1
- package/client/dist/assets/code-PCmfS3dn.js +0 -1
- package/client/dist/assets/code-exI0G5Wd.js +0 -1
- package/client/dist/assets/index-D17R4Cjc.css +0 -2
- package/client/dist/assets/index-D9G_K4L-.js +0 -142
- package/client/dist/assets/integrations-D28q1kF6.js +0 -1
- package/client/dist/assets/setup--FMCsnQS.js +0 -1
- package/client/dist/assets/setup-B19ZpBNi.js +0 -1
- package/client/dist/assets/setup-BZPmkjSN.js +0 -1
- package/client/dist/assets/setup-BqYA02rS.js +0 -1
- package/client/dist/assets/setup-ChKQDHN9.js +0 -1
- package/client/dist/assets/setup-D2n9jMfM.js +0 -1
- package/client/dist/assets/setup-P3r6YP1D.js +0 -1
- package/client/dist/assets/setup-fnfEbwlv.js +0 -1
- package/client/dist/assets/specs-cKEh2LXt.js +0 -1
- /package/client/dist/assets/{abap-Bw6f2wDG.js → abap-s65oMlhi.js} +0 -0
- /package/client/dist/assets/{activity-BdrPln96.js → activity-BqqwnH_h.js} +0 -0
- /package/client/dist/assets/{activity-BEIp_Y1A.js → activity-C8qqEIoP.js} +0 -0
- /package/client/dist/assets/{activity-CpkRS8Sx.js → activity-CZVM4nlJ.js} +0 -0
- /package/client/dist/assets/{activity-DOUVEjJi.js → activity-Cyy07Tgo.js} +0 -0
- /package/client/dist/assets/{activity-DRwkql_y.js → activity-DlbWCa4y.js} +0 -0
- /package/client/dist/assets/{activity-DKCpESPt.js → activity-Dwq0heud.js} +0 -0
- /package/client/dist/assets/{activity-DcDQ7tjw.js → activity-qFTcMyW9.js} +0 -0
- /package/client/dist/assets/{addon-image-3WCl5Vhd.js → addon-image-CpF0L0jM.js} +0 -0
- /package/client/dist/assets/{addon-ligatures-C5OdliKs.js → addon-ligatures-hXysGZrA.js} +0 -0
- /package/client/dist/assets/{addon-webgl-BbX6pSjl.js → addon-webgl-Cn1slavz.js} +0 -0
- /package/client/dist/assets/{addspec-D33ocMxf.js → addspec-B1FTtI2a.js} +0 -0
- /package/client/dist/assets/{addspec-DFswZ0jK.js → addspec-BCT9vm_c.js} +0 -0
- /package/client/dist/assets/{addspec-DVZ15Jp8.js → addspec-DeDOztDr.js} +0 -0
- /package/client/dist/assets/{addspec-Fkv91Opc.js → addspec-DpRgmfmx.js} +0 -0
- /package/client/dist/assets/{addspec-BEeF5-zc.js → addspec-Dw-0Dg-4.js} +0 -0
- /package/client/dist/assets/{addspec-B5yl4Loj.js → addspec-rp496P_F.js} +0 -0
- /package/client/dist/assets/{addspec-DRE-jZv7.js → addspec-v8j6A7CD.js} +0 -0
- /package/client/dist/assets/{agents-DK-Dlc0i.js → agents-23iPejcA.js} +0 -0
- /package/client/dist/assets/{agents-Q6Ldfpxx.js → agents-BDx1RXcl.js} +0 -0
- /package/client/dist/assets/{agents-TeOSy-ax.js → agents-BFr3kUhK.js} +0 -0
- /package/client/dist/assets/{agents-Bm9rPqnt.js → agents-B_1L9xRg.js} +0 -0
- /package/client/dist/assets/{agents-1nCDWRmP.js → agents-BlPnx-mz.js} +0 -0
- /package/client/dist/assets/{agents-iTqjRajS.js → agents-DcxZHzNr.js} +0 -0
- /package/client/dist/assets/{agents-s87sMGzL.js → agents-G3shOewU.js} +0 -0
- /package/client/dist/assets/{agentstudio-B6Wb59E7.js → agentstudio-B-CMAQqy.js} +0 -0
- /package/client/dist/assets/{agentstudio-D3I62TLJ.js → agentstudio-Bk1eZcv4.js} +0 -0
- /package/client/dist/assets/{agentstudio-DuH9TogZ.js → agentstudio-ChxNuGAu.js} +0 -0
- /package/client/dist/assets/{agentstudio-Kw88_dUF.js → agentstudio-DNlme601.js} +0 -0
- /package/client/dist/assets/{agentstudio-BdidyBzZ.js → agentstudio-DpP9caEE.js} +0 -0
- /package/client/dist/assets/{agentstudio-BSnWLR63.js → agentstudio-Y3G0ddJ2.js} +0 -0
- /package/client/dist/assets/{agentstudio-BADhZ41e.js → agentstudio-kk9RB7Se.js} +0 -0
- /package/client/dist/assets/{aiedit-DJMny-D5.js → aiedit-5ETerMK1.js} +0 -0
- /package/client/dist/assets/{aiedit-D2ji6Qy0.js → aiedit-BBCrOpHq.js} +0 -0
- /package/client/dist/assets/{aiedit-DAhZTvtk.js → aiedit-BMtcGYNE.js} +0 -0
- /package/client/dist/assets/{aiedit-DvrcbwGv.js → aiedit-D9ddlgkM.js} +0 -0
- /package/client/dist/assets/{aiedit-WBSjT_C1.js → aiedit-De0SOH6S.js} +0 -0
- /package/client/dist/assets/{aiedit-BWxHGsYA.js → aiedit-DrfzQroF.js} +0 -0
- /package/client/dist/assets/{aiedit-DOcxERkU.js → aiedit-fMltW101.js} +0 -0
- /package/client/dist/assets/{analytics-C9Zc-rkM.js → analytics-BeTyviO8.js} +0 -0
- /package/client/dist/assets/{analytics-CrPCZRJ-.js → analytics-C4eEO260.js} +0 -0
- /package/client/dist/assets/{analytics-CYj0tfj7.js → analytics-C67cIA1b.js} +0 -0
- /package/client/dist/assets/{analytics-C6EzgtdE.js → analytics-CAguvW28.js} +0 -0
- /package/client/dist/assets/{analytics-CVx3YOc0.js → analytics-DBtt8Mgk.js} +0 -0
- /package/client/dist/assets/{analytics-CnY4kNG3.js → analytics-DUPtODxX.js} +0 -0
- /package/client/dist/assets/{analytics-BIdr0YfL.js → analytics-YIpQvPAc.js} +0 -0
- /package/client/dist/assets/{apex-Cw8_REBo.js → apex-BLUBIldB.js} +0 -0
- /package/client/dist/assets/{attachments-DYHGA2Dj.js → attachments-CCWasu-P.js} +0 -0
- /package/client/dist/assets/{attachments-Dd92KpUH.js → attachments-CHaDUfjB.js} +0 -0
- /package/client/dist/assets/{attachments-DzdU6DV6.js → attachments-CVSAbGNl.js} +0 -0
- /package/client/dist/assets/{attachments-Bcf6BG6V.js → attachments-Chg5poG1.js} +0 -0
- /package/client/dist/assets/{attachments-BW4L3l2L.js → attachments-DazTVJbH.js} +0 -0
- /package/client/dist/assets/{attachments-COcrGRFz.js → attachments-Dn-JImAK.js} +0 -0
- /package/client/dist/assets/{attachments-Bke8sCU4.js → attachments-LDA9kp2X.js} +0 -0
- /package/client/dist/assets/{azcli-Cz6HAoOw.js → azcli-DuWxh9mO.js} +0 -0
- /package/client/dist/assets/{bat-CcJ-xyqL.js → bat-UKoTejQm.js} +0 -0
- /package/client/dist/assets/{bicep-z1WDCKYz.js → bicep-4sTT4B3D.js} +0 -0
- /package/client/dist/assets/{browser-DGITz3fC.js → browser-BDd1dbFa.js} +0 -0
- /package/client/dist/assets/{browser-JsAIGCEW.js → browser-BWSgbfdX.js} +0 -0
- /package/client/dist/assets/{browser-M5-rbPlw.js → browser-D2Y_UAKA.js} +0 -0
- /package/client/dist/assets/{browser-BlYF4OOq.js → browser-DH9SGVfM.js} +0 -0
- /package/client/dist/assets/{browser-Bc-YdlVg.js → browser-DWOVYMlg.js} +0 -0
- /package/client/dist/assets/{browser-CT-ReZGt.js → browser-Dxc_VIRK.js} +0 -0
- /package/client/dist/assets/{browser-5ErDlJoR.js → browser-lTQwcDCI.js} +0 -0
- /package/client/dist/assets/{cameligo-BRewOpfa.js → cameligo-CAAryRYO.js} +0 -0
- /package/client/dist/assets/{chat-DwUm6W9z.js → chat-BO9MvVID.js} +0 -0
- /package/client/dist/assets/{chat-BEGuC03z.js → chat-CPgmgZOj.js} +0 -0
- /package/client/dist/assets/{chat-CboQguCi.js → chat-CUrG1eVg.js} +0 -0
- /package/client/dist/assets/{chat-DRCa9pOt.js → chat-CvOOKB2s.js} +0 -0
- /package/client/dist/assets/{chat-BEW60P_u.js → chat-DIh3hr6y.js} +0 -0
- /package/client/dist/assets/{chat-yoXwguQu.js → chat-UVVZqA57.js} +0 -0
- /package/client/dist/assets/{chat-BQNMD0PL.js → chat-mPn3UlMl.js} +0 -0
- /package/client/dist/assets/{clojure-DBjRWN6g.js → clojure-BlMERO1w.js} +0 -0
- /package/client/dist/assets/{clsx-DnqN-uhr.js → clsx-CnH-HMk3.js} +0 -0
- /package/client/dist/assets/{coffee-Cfk_XHGR.js → coffee-Cj8D-Wl1.js} +0 -0
- /package/client/dist/assets/{commands-sqrqsxyE.js → commands-B-MVT-2F.js} +0 -0
- /package/client/dist/assets/{commands-UD1NzmwX.js → commands-B0yFTp7e.js} +0 -0
- /package/client/dist/assets/{commands-DLrvnPNg.js → commands-BR1kDkHQ.js} +0 -0
- /package/client/dist/assets/{commands-CJxCry-o.js → commands-Cb21pDlG.js} +0 -0
- /package/client/dist/assets/{commands-CfgY-_of.js → commands-DWgp-8W1.js} +0 -0
- /package/client/dist/assets/{commands-B772IyDa.js → commands-ddsl1V91.js} +0 -0
- /package/client/dist/assets/{commands-BDDp6xFG.js → commands-t4frzhB0.js} +0 -0
- /package/client/dist/assets/{common-Dmm1GhdD.js → common-5ilvMOcH.js} +0 -0
- /package/client/dist/assets/{common-DltqHaAe.js → common-B4sqsKp7.js} +0 -0
- /package/client/dist/assets/{common-GbpxfPG8.js → common-BKpVwUIf.js} +0 -0
- /package/client/dist/assets/{common-DeDELLZJ.js → common-BzEC3kJU.js} +0 -0
- /package/client/dist/assets/{common-DnjcgkPH.js → common-CALKUpYm.js} +0 -0
- /package/client/dist/assets/{common-Dard9UNH.js → common-CTEbWVZS.js} +0 -0
- /package/client/dist/assets/{common-DCr6VzJ7.js → common-DQiza2Xp.js} +0 -0
- /package/client/dist/assets/{cpp-BVob6BaP.js → cpp-BPfKnaj_.js} +0 -0
- /package/client/dist/assets/{csharp-C4fbRuOu.js → csharp-gX-x5uD6.js} +0 -0
- /package/client/dist/assets/{csp-DthFP_vT.js → csp-DKGVt8SM.js} +0 -0
- /package/client/dist/assets/{css-CGMH0hcW.js → css-CPMdnAVq.js} +0 -0
- /package/client/dist/assets/{cypher-Pnf68BRV.js → cypher-ClMDrj9S.js} +0 -0
- /package/client/dist/assets/{dart-PMMOtxZX.js → dart-C4zbzpVv.js} +0 -0
- /package/client/dist/assets/{dashboard-BZBADHSj.js → dashboard--Y6yzMlf.js} +0 -0
- /package/client/dist/assets/{dashboard-I19DXBxw.js → dashboard--a4-6oYE.js} +0 -0
- /package/client/dist/assets/{dashboard-CB6Le1yN.js → dashboard-BiJ3CDTG.js} +0 -0
- /package/client/dist/assets/{dashboard-B4ixDVk8.js → dashboard-CiXjk63Z.js} +0 -0
- /package/client/dist/assets/{dashboard-C1MfeUHs.js → dashboard-Cx5VjCea.js} +0 -0
- /package/client/dist/assets/{dashboard-C7SK6xu5.js → dashboard-D7jg25XR.js} +0 -0
- /package/client/dist/assets/{dashboard-CoTpMOBM.js → dashboard-DpGYK2s1.js} +0 -0
- /package/client/dist/assets/{dockerfile-di1nsJCc.js → dockerfile-D9xw73D1.js} +0 -0
- /package/client/dist/assets/{ecl-D_WVcB5M.js → ecl-gqO8tIR9.js} +0 -0
- /package/client/dist/assets/{editor.api2-XLGzZfbc.js → editor.api2-BPnIxMjz.js} +0 -0
- /package/client/dist/assets/{elixir-OAdJEMOn.js → elixir-DSAhVF3_.js} +0 -0
- /package/client/dist/assets/{explore-D2EFgt8J.js → explore-BE5UmlbD.js} +0 -0
- /package/client/dist/assets/{explore-BV5Xxlsn.js → explore-BmTaI8dX.js} +0 -0
- /package/client/dist/assets/{explore-A8Ltoblq.js → explore-CCwkqoWq.js} +0 -0
- /package/client/dist/assets/{explore-4mFpnrKU.js → explore-CMdEoPDx.js} +0 -0
- /package/client/dist/assets/{explore-C3FSE42C.js → explore-CtdCL4QU.js} +0 -0
- /package/client/dist/assets/{explore-B9A3iN2W.js → explore-DHjxSkqQ.js} +0 -0
- /package/client/dist/assets/{explore-BrBJvfjP.js → explore-__BeALjE.js} +0 -0
- /package/client/dist/assets/{flow9-D3QEZjgn.js → flow9-DeQCSPOd.js} +0 -0
- /package/client/dist/assets/{format-command-CwGuwzGA.js → format-command-2VNoNnMv.js} +0 -0
- /package/client/dist/assets/{fsharp-BF0k_8N8.js → fsharp-CEfaXL-S.js} +0 -0
- /package/client/dist/assets/{go-BAQO5Jsz.js → go-Xp1OkZCh.js} +0 -0
- /package/client/dist/assets/{graphql-hdFVFkiV.js → graphql-BwRXrUwe.js} +0 -0
- /package/client/dist/assets/{hcl-DWnl1o-X.js → hcl-u06DtVFk.js} +0 -0
- /package/client/dist/assets/{ini-CB-6OVu3.js → ini-AmeIpFND.js} +0 -0
- /package/client/dist/assets/{java-d1CmfiHX.js → java-CyDbRQjX.js} +0 -0
- /package/client/dist/assets/{jobs-DPPT6bV6.js → jobs-8viuHLDV.js} +0 -0
- /package/client/dist/assets/{jobs-3j3_npyo.js → jobs-AW2eB5D-.js} +0 -0
- /package/client/dist/assets/{jobs-2N3RXDAM.js → jobs-BSm89DL5.js} +0 -0
- /package/client/dist/assets/{jobs-BqEbCCxD.js → jobs-BZ3sQHjZ.js} +0 -0
- /package/client/dist/assets/{jobs-cHYInoau.js → jobs-Bd8AdOTb.js} +0 -0
- /package/client/dist/assets/{jobs-DRzjWI9u.js → jobs-CRtsq_u0.js} +0 -0
- /package/client/dist/assets/{jobs-2f6Hdc72.js → jobs-CSRwFQ6K.js} +0 -0
- /package/client/dist/assets/{jobs-vGfzIDQa.js → jobs-CbEl7WMI.js} +0 -0
- /package/client/dist/assets/{julia-Bgv08lKa.js → julia-BqialFRG.js} +0 -0
- /package/client/dist/assets/{kotlin-u98kaVTf.js → kotlin-Dzz8TWAt.js} +0 -0
- /package/client/dist/assets/{less-CjYwpgg5.js → less-DHRJD3TR.js} +0 -0
- /package/client/dist/assets/{lexon-YTjaAFBB.js → lexon-5Y3QgTmT.js} +0 -0
- /package/client/dist/assets/{lua-BzmkWv27.js → lua-sKvhfPn5.js} +0 -0
- /package/client/dist/assets/{m3-CFwk9fw0.js → m3-DWDVwkFG.js} +0 -0
- /package/client/dist/assets/{markdown-CR5iMpSZ.js → markdown-CD_aSBxW.js} +0 -0
- /package/client/dist/assets/{mips-CcEalc17.js → mips-687T03hg.js} +0 -0
- /package/client/dist/assets/{msdax-BQbkawnr.js → msdax-C1St-dIV.js} +0 -0
- /package/client/dist/assets/{mysql-GTlaaW_P.js → mysql-BG7r8oBS.js} +0 -0
- /package/client/dist/assets/{nav-C2YXcbZS.js → nav-B05EYB0b.js} +0 -0
- /package/client/dist/assets/{nav-D2bOGSEg.js → nav-BNGCq-0y.js} +0 -0
- /package/client/dist/assets/{nav-BEL3MTwK.js → nav-BRInPX8a.js} +0 -0
- /package/client/dist/assets/{nav-CtYwmMgu.js → nav-Bf87DRHD.js} +0 -0
- /package/client/dist/assets/{nav-iH1V5j6o.js → nav-BkVzzFpc.js} +0 -0
- /package/client/dist/assets/{nav-0fwkrgHt.js → nav-BzFLtS1W.js} +0 -0
- /package/client/dist/assets/{nav-ClzOE4mA.js → nav-DBDbQOYn.js} +0 -0
- /package/client/dist/assets/{nav-B_G-TJDW.js → nav-X9sVtUWC.js} +0 -0
- /package/client/dist/assets/{objective-c-Byu1T5if.js → objective-c-Ds1-m05L.js} +0 -0
- /package/client/dist/assets/{pascal-BrfzBfRm.js → pascal-BKK9FpIi.js} +0 -0
- /package/client/dist/assets/{pascaligo-BXXKFUeo.js → pascaligo-SRS3nwtO.js} +0 -0
- /package/client/dist/assets/{perl-B3OikKq-.js → perl-B2hTOlrF.js} +0 -0
- /package/client/dist/assets/{pgsql-CTsa0Acc.js → pgsql-DIQJYNpL.js} +0 -0
- /package/client/dist/assets/{php-DiQh3FUW.js → php-BEaVe8X2.js} +0 -0
- /package/client/dist/assets/{pla-92uH8Fzm.js → pla-oPLHpZ-Q.js} +0 -0
- /package/client/dist/assets/{postiats-BbeWkKUr.js → postiats-D_vzrAzD.js} +0 -0
- /package/client/dist/assets/{powerquery-DgDMzpsm.js → powerquery-BKG6w-FH.js} +0 -0
- /package/client/dist/assets/{powershell-BfdUUzaG.js → powershell-B3dLhDt4.js} +0 -0
- /package/client/dist/assets/{protobuf-BojW2ftW.js → protobuf-DC8SGjcl.js} +0 -0
- /package/client/dist/assets/{pug-BxqTg3IU.js → pug-D5E-4fI0.js} +0 -0
- /package/client/dist/assets/{qsharp-BX_A-MW9.js → qsharp-6vJAWv0x.js} +0 -0
- /package/client/dist/assets/{r-D9BMnxvJ.js → r-CDwsEcbM.js} +0 -0
- /package/client/dist/assets/{redis-5cJqEQJJ.js → redis-CuQbbESS.js} +0 -0
- /package/client/dist/assets/{redshift-d8BBqiwb.js → redshift-B9e1k-qI.js} +0 -0
- /package/client/dist/assets/{restructuredtext-C8a6yIcZ.js → restructuredtext-BiJ5IwaU.js} +0 -0
- /package/client/dist/assets/{ruby-egeh-6KX.js → ruby-B0UAHY9b.js} +0 -0
- /package/client/dist/assets/{rust-a3r9IInB.js → rust-Dg_spmFr.js} +0 -0
- /package/client/dist/assets/{sb-y8iRIDei.js → sb-DjU66I8Q.js} +0 -0
- /package/client/dist/assets/{scala-BPDK2AmK.js → scala-qvStIdfG.js} +0 -0
- /package/client/dist/assets/{scheme-BIWUEoOs.js → scheme-FstEk5Rh.js} +0 -0
- /package/client/dist/assets/{scss-CA-PSzwg.js → scss-w0U3rQLK.js} +0 -0
- /package/client/dist/assets/{settings-CTcwN9RE.js → settings-5tzo0Rn3.js} +0 -0
- /package/client/dist/assets/{settings-D_dujJZI.js → settings-BDAW3trC.js} +0 -0
- /package/client/dist/assets/{settings-Bg0A3zoS.js → settings-BEWv3VEu.js} +0 -0
- /package/client/dist/assets/{settings-BgPqg2nv.js → settings-BORg56um.js} +0 -0
- /package/client/dist/assets/{settings-BSze3_9q.js → settings-D3LurcR5.js} +0 -0
- /package/client/dist/assets/{settings-CSJ0ahZ8.js → settings-DcqWIEM6.js} +0 -0
- /package/client/dist/assets/{settings-DYIV89nV.js → settings-Dfz8QbZS.js} +0 -0
- /package/client/dist/assets/{settings-DDcfx_ca.js → settings-yMubjqYw.js} +0 -0
- /package/client/dist/assets/{shell--LiT1Bja.js → shell-DJ78wREd.js} +0 -0
- /package/client/dist/assets/{solidity-DdqZccZg.js → solidity-1aGIVsdX.js} +0 -0
- /package/client/dist/assets/{sophia-S6-YxNG_.js → sophia-40LqcGjB.js} +0 -0
- /package/client/dist/assets/{sparql-BSf5kMp2.js → sparql-Cz5dqG_g.js} +0 -0
- /package/client/dist/assets/{sql-D7KgjR8G.js → sql-64f62Ni4.js} +0 -0
- /package/client/dist/assets/{st-BnoDa-Ml.js → st-gJe2yG8J.js} +0 -0
- /package/client/dist/assets/{swift-DEUHTkUX.js → swift-C6ME22mv.js} +0 -0
- /package/client/dist/assets/{systemverilog-Tqb_KPnW.js → systemverilog-CEWz259w.js} +0 -0
- /package/client/dist/assets/{tcl-BmBFS2qq.js → tcl-CcLVIi3m.js} +0 -0
- /package/client/dist/assets/{terminal-Bje4ziIa.js → terminal-BYtreaaF.js} +0 -0
- /package/client/dist/assets/{terminal-CSONJOex.js → terminal-C0xx0SjA.js} +0 -0
- /package/client/dist/assets/{terminal-DeWzh6ys.js → terminal-CPpK58RC.js} +0 -0
- /package/client/dist/assets/{terminal-C2WYcFHF.js → terminal-CdxkpafL.js} +0 -0
- /package/client/dist/assets/{terminal-DEqzGtcr.js → terminal-Ciia0wh2.js} +0 -0
- /package/client/dist/assets/{terminal-80yDMgMF.js → terminal-DHIkiWcs.js} +0 -0
- /package/client/dist/assets/{terminal-lkZYR4wJ.js → terminal-DY42QANg.js} +0 -0
- /package/client/dist/assets/{terminal-YOlsJCQj.js → terminal-DoxtVdma.js} +0 -0
- /package/client/dist/assets/{tickets-DYvafSaY.js → tickets-0rM0lIXd.js} +0 -0
- /package/client/dist/assets/{tickets-DNOANUXr.js → tickets-1UIGf_oA.js} +0 -0
- /package/client/dist/assets/{tickets-DlpC_iTg.js → tickets-9kdPXInd.js} +0 -0
- /package/client/dist/assets/{tickets-CF2PYelu.js → tickets-C6pwZwt4.js} +0 -0
- /package/client/dist/assets/{tickets-CB7N30gm.js → tickets-DAjtxAVb.js} +0 -0
- /package/client/dist/assets/{tickets-DU1aqsbr.js → tickets-DNmXcAwu.js} +0 -0
- /package/client/dist/assets/{tickets-clefmXLv.js → tickets-n23kDqJT.js} +0 -0
- /package/client/dist/assets/{tickets-DucYgtdl.js → tickets-tGx5AR5b.js} +0 -0
- /package/client/dist/assets/{twig-BQV8igWC.js → twig-DvsO-WjW.js} +0 -0
- /package/client/dist/assets/{typespec-DlFroUGY.js → typespec-Brkt3IAA.js} +0 -0
- /package/client/dist/assets/{vb-BlrJpIMX.js → vb-r121Uzxt.js} +0 -0
- /package/client/dist/assets/{wgsl-BWgIc6FZ.js → wgsl-BRX8uYh4.js} +0 -0
|
@@ -9,13 +9,12 @@ exports.buildFirstTurnPrompt = buildFirstTurnPrompt;
|
|
|
9
9
|
exports.refineSessionToJson = refineSessionToJson;
|
|
10
10
|
const fs_1 = __importDefault(require("fs"));
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
|
-
const readline_1 = require("readline");
|
|
13
12
|
const crypto_1 = require("crypto");
|
|
14
13
|
const tree_kill_1 = __importDefault(require("tree-kill"));
|
|
15
|
-
const cli_prompt_1 = require("./util/cli-prompt");
|
|
16
14
|
const agent_generator_1 = require("./agent-generator");
|
|
17
15
|
const ai_invocations_1 = require("./ai-invocations");
|
|
18
16
|
const result_event_1 = require("./result-event");
|
|
17
|
+
const spawn_lifecycle_1 = require("./spawn-lifecycle");
|
|
19
18
|
const providers_1 = require("./providers");
|
|
20
19
|
const agent_refine_db_1 = require("./agent-refine-db");
|
|
21
20
|
const CUSTOM_PREFIX = /^custom-[a-z0-9][a-z0-9-]*$/;
|
|
@@ -219,164 +218,140 @@ class AgentRefineManager {
|
|
|
219
218
|
sessionId: session.session_id ?? undefined,
|
|
220
219
|
});
|
|
221
220
|
let drafted = false;
|
|
222
|
-
const child = (0, cli_prompt_1.spawnAiCli)(this._adapter.binary, args, {
|
|
223
|
-
env: process.env,
|
|
224
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
225
|
-
cwd: this._projectPath,
|
|
226
|
-
});
|
|
227
|
-
this._activeProcesses.set(refineId, child);
|
|
228
221
|
this._bodyBuffers.set(refineId, '');
|
|
229
|
-
let capturedSessionId = null;
|
|
230
|
-
const adapterEvents = [];
|
|
231
222
|
const turnStartedAt = new Date().toISOString();
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
this.
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
projectId: '',
|
|
261
|
-
refineId,
|
|
262
|
-
delta: ev.text,
|
|
263
|
-
timestamp: new Date().toISOString(),
|
|
264
|
-
});
|
|
265
|
-
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { draft_body: next });
|
|
266
|
-
break;
|
|
267
|
-
}
|
|
268
|
-
case 'tool-use':
|
|
269
|
-
this._broadcast({
|
|
270
|
-
type: 'agent_refine_stream',
|
|
271
|
-
projectId: '',
|
|
272
|
-
refineId,
|
|
273
|
-
delta: `<!--tool:${ev.name}-->`,
|
|
274
|
-
timestamp: new Date().toISOString(),
|
|
275
|
-
});
|
|
276
|
-
break;
|
|
277
|
-
case 'other':
|
|
278
|
-
break;
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
let stderr = '';
|
|
282
|
-
child.stderr.on('data', (chunk) => { stderr += chunk.toString(); });
|
|
283
|
-
return new Promise((resolve) => {
|
|
284
|
-
child.on('error', (err) => {
|
|
285
|
-
this._activeProcesses.delete(refineId);
|
|
286
|
-
this._bodyBuffers.delete(refineId);
|
|
287
|
-
if (this._disposed) {
|
|
288
|
-
resolve();
|
|
289
|
-
return;
|
|
290
|
-
} // M12: project removed mid-flight; DB closing
|
|
291
|
-
this._emitError(refineId, `Failed to launch claude: ${err.message}`);
|
|
292
|
-
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { status: 'error', phase: 'idle' });
|
|
293
|
-
resolve();
|
|
294
|
-
});
|
|
295
|
-
child.on('close', (code) => {
|
|
296
|
-
this._activeProcesses.delete(refineId);
|
|
297
|
-
const fullDraft = this._bodyBuffers.get(refineId) ?? '';
|
|
298
|
-
this._bodyBuffers.delete(refineId);
|
|
299
|
-
if (this._disposed) {
|
|
300
|
-
resolve();
|
|
301
|
-
return;
|
|
302
|
-
} // M12: project removed mid-flight; DB closing
|
|
303
|
-
// ai_invocations capture (surface='ai-edit'). One row per refine turn.
|
|
304
|
-
if (this._projectId) {
|
|
305
|
-
try {
|
|
306
|
-
const invStatus = code === 0 && fullDraft.trim() ? 'success' : 'failed';
|
|
307
|
-
const { result: normalised, estimated } = (0, result_event_1.finaliseInvocationResult)(this._adapter, adapterEvents, { fallbackModel: refineModel });
|
|
308
|
-
(0, ai_invocations_1.recordInvocation)(this._db, {
|
|
309
|
-
id: (0, crypto_1.randomUUID)(),
|
|
310
|
-
project_id: this._projectId,
|
|
311
|
-
provider: this._adapter.id,
|
|
312
|
-
surface: 'ai-edit',
|
|
313
|
-
surface_ref_id: refineId,
|
|
314
|
-
status: invStatus,
|
|
315
|
-
started_at: turnStartedAt,
|
|
316
|
-
finished_at: new Date().toISOString(),
|
|
317
|
-
total_cost_usd_estimated: estimated,
|
|
318
|
-
...normalised,
|
|
223
|
+
const spawnState = { err: null };
|
|
224
|
+
// Spawn / stream / settlement is owned by the shared spawn-lifecycle; the
|
|
225
|
+
// refine-specific draft buffering, accounting, validation and history all
|
|
226
|
+
// stay here unchanged.
|
|
227
|
+
const run = await (0, spawn_lifecycle_1.runAiCliInvocation)({
|
|
228
|
+
adapter: this._adapter,
|
|
229
|
+
action,
|
|
230
|
+
buildOpts: { prompt, model: refineModel, sessionId: session.session_id ?? undefined },
|
|
231
|
+
cwd: this._projectPath,
|
|
232
|
+
onSpawn: (child) => this._activeProcesses.set(refineId, child),
|
|
233
|
+
onSpawnError: (err) => { spawnState.err = err; },
|
|
234
|
+
onEvent: (ev) => {
|
|
235
|
+
switch (ev.kind) {
|
|
236
|
+
case 'text-delta': {
|
|
237
|
+
if (!drafted) {
|
|
238
|
+
drafted = true;
|
|
239
|
+
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { phase: 'drafting' });
|
|
240
|
+
this._emitPhase(refineId, 'drafting');
|
|
241
|
+
}
|
|
242
|
+
const prev = this._bodyBuffers.get(refineId) ?? '';
|
|
243
|
+
const next = prev + ev.text;
|
|
244
|
+
this._bodyBuffers.set(refineId, next);
|
|
245
|
+
this._broadcast({
|
|
246
|
+
type: 'agent_refine_stream',
|
|
247
|
+
projectId: '',
|
|
248
|
+
refineId,
|
|
249
|
+
delta: ev.text,
|
|
250
|
+
timestamp: new Date().toISOString(),
|
|
319
251
|
});
|
|
320
|
-
|
|
252
|
+
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { draft_body: next });
|
|
253
|
+
break;
|
|
321
254
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
334
|
-
// Validation phase.
|
|
335
|
-
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { phase: 'validating' });
|
|
336
|
-
this._emitPhase(refineId, 'validating');
|
|
337
|
-
const stripped = stripToolMarkers(fullDraft);
|
|
338
|
-
const validation = validateAgentBody(stripped, this._adapter.id);
|
|
339
|
-
if (!validation.ok) {
|
|
340
|
-
this._emitError(refineId, `Frontmatter invalid: ${validation.error}`);
|
|
341
|
-
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { status: 'error', phase: 'idle', draft_body: stripped });
|
|
342
|
-
resolve();
|
|
343
|
-
return;
|
|
255
|
+
case 'tool-use':
|
|
256
|
+
this._broadcast({
|
|
257
|
+
type: 'agent_refine_stream',
|
|
258
|
+
projectId: '',
|
|
259
|
+
refineId,
|
|
260
|
+
delta: `<!--tool:${ev.name}-->`,
|
|
261
|
+
timestamp: new Date().toISOString(),
|
|
262
|
+
});
|
|
263
|
+
break;
|
|
264
|
+
default:
|
|
265
|
+
break;
|
|
344
266
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
this._activeProcesses.delete(refineId);
|
|
270
|
+
const fullDraft = this._bodyBuffers.get(refineId) ?? '';
|
|
271
|
+
this._bodyBuffers.delete(refineId);
|
|
272
|
+
if (this._disposed)
|
|
273
|
+
return; // M12: project removed mid-flight; DB closing
|
|
274
|
+
if (run.spawnFailed) {
|
|
275
|
+
this._emitError(refineId, `Failed to launch claude: ${spawnState.err?.message ?? 'spawn error'}`);
|
|
276
|
+
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { status: 'error', phase: 'idle' });
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const capturedSessionId = run.sessionId;
|
|
280
|
+
const adapterEvents = run.events;
|
|
281
|
+
const code = run.code;
|
|
282
|
+
const stderr = run.stderrTail;
|
|
283
|
+
// ai_invocations capture (surface='ai-edit'). One row per refine turn.
|
|
284
|
+
if (this._projectId) {
|
|
285
|
+
try {
|
|
286
|
+
const invStatus = code === 0 && fullDraft.trim() ? 'success' : 'failed';
|
|
287
|
+
const { result: normalised, estimated } = (0, result_event_1.finaliseInvocationResult)(this._adapter, adapterEvents, { fallbackModel: refineModel });
|
|
288
|
+
(0, ai_invocations_1.recordInvocation)(this._db, {
|
|
289
|
+
id: (0, crypto_1.randomUUID)(),
|
|
290
|
+
project_id: this._projectId,
|
|
291
|
+
provider: this._adapter.id,
|
|
292
|
+
surface: 'ai-edit',
|
|
293
|
+
surface_ref_id: refineId,
|
|
294
|
+
status: invStatus,
|
|
295
|
+
started_at: turnStartedAt,
|
|
296
|
+
finished_at: new Date().toISOString(),
|
|
297
|
+
total_cost_usd_estimated: estimated,
|
|
298
|
+
...normalised,
|
|
364
299
|
});
|
|
365
|
-
this.
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
300
|
+
this._broadcast({ type: 'spending.invalidated', projectId: this._projectId });
|
|
301
|
+
}
|
|
302
|
+
catch (err) {
|
|
303
|
+
console.error('[agent-refine-manager] recordInvocation failed:', err);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
if (code !== 0 || !fullDraft.trim()) {
|
|
307
|
+
this._emitError(refineId, code !== 0
|
|
308
|
+
? `claude exited with code ${code}${stderr ? `: ${stderr.slice(-300)}` : ''}`
|
|
309
|
+
: 'claude returned empty output');
|
|
310
|
+
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { status: 'error', phase: 'idle' });
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
// Validation phase.
|
|
314
|
+
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { phase: 'validating' });
|
|
315
|
+
this._emitPhase(refineId, 'validating');
|
|
316
|
+
const stripped = stripToolMarkers(fullDraft);
|
|
317
|
+
const validation = validateAgentBody(stripped, this._adapter.id);
|
|
318
|
+
if (!validation.ok) {
|
|
319
|
+
this._emitError(refineId, `Frontmatter invalid: ${validation.error}`);
|
|
320
|
+
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { status: 'error', phase: 'idle', draft_body: stripped });
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
// Append assistant turn to history (use stripped body — markers gone).
|
|
324
|
+
this._appendHistory(refineId, {
|
|
325
|
+
role: 'assistant',
|
|
326
|
+
content: stripped,
|
|
327
|
+
timestamp: Date.now(),
|
|
328
|
+
});
|
|
329
|
+
const patch = {
|
|
330
|
+
status: 'ready',
|
|
331
|
+
phase: 'done',
|
|
332
|
+
draft_body: stripped,
|
|
333
|
+
...(capturedSessionId ? { session_id: capturedSessionId } : {}),
|
|
334
|
+
};
|
|
335
|
+
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, patch);
|
|
336
|
+
this._broadcast({
|
|
337
|
+
type: 'agent_refine_ready',
|
|
338
|
+
projectId: '',
|
|
339
|
+
refineId,
|
|
340
|
+
draftBody: stripped,
|
|
341
|
+
timestamp: new Date().toISOString(),
|
|
379
342
|
});
|
|
343
|
+
this._emitPhase(refineId, 'done');
|
|
344
|
+
// Smart-mode auto-test: only run if enabled, body changed since last
|
|
345
|
+
// test, and >5s elapsed. Best-effort; failures are non-fatal.
|
|
346
|
+
const session2 = (0, agent_refine_db_1.getRefineSession)(this._db, refineId);
|
|
347
|
+
if (session2 && session2.auto_test === 1) {
|
|
348
|
+
const draftHash = sha256(stripped);
|
|
349
|
+
const recent = session2.last_test_at !== null && Date.now() - session2.last_test_at < SMART_TEST_DEBOUNCE_MS;
|
|
350
|
+
const sameBody = session2.last_test_hash === draftHash;
|
|
351
|
+
if (!recent && !sameBody) {
|
|
352
|
+
void this._runAutoTest(refineId, session2.agent_id, stripped, draftHash);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
380
355
|
}
|
|
381
356
|
async _runAutoTest(refineId, agentId, draftBody, draftHash) {
|
|
382
357
|
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { phase: 'testing' });
|
|
@@ -20,6 +20,7 @@ const providers_1 = require("./providers");
|
|
|
20
20
|
const context_scope_1 = require("./context-scope");
|
|
21
21
|
const user_mcp_config_1 = require("./user-mcp-config");
|
|
22
22
|
const binary_probe_1 = require("./binary-probe");
|
|
23
|
+
const explore_stdin_session_1 = require("./explore-stdin-session");
|
|
23
24
|
const COMMAND_INSTRUCTION = 'When you want to suggest a SpecRails command for the user to execute, wrap it in a command block like this: ' +
|
|
24
25
|
':::command\n/specrails:implement #42\n::: ' +
|
|
25
26
|
'The user will be prompted to confirm before the command runs.';
|
|
@@ -60,6 +61,9 @@ class ChatManager {
|
|
|
60
61
|
_exploreLifecycle;
|
|
61
62
|
/** FIFO queue of Explore turns waiting for a concurrency slot. */
|
|
62
63
|
_exploreQueue;
|
|
64
|
+
/** Persistent-stdin Explore transport (big bet #3, flag-gated default OFF).
|
|
65
|
+
* Holds long-lived claude children that survive between turns. */
|
|
66
|
+
_stdinSessions = new explore_stdin_session_1.ExploreStdinSessions();
|
|
63
67
|
_cwd;
|
|
64
68
|
_projectName;
|
|
65
69
|
_adapter;
|
|
@@ -142,6 +146,9 @@ class ChatManager {
|
|
|
142
146
|
}
|
|
143
147
|
catch { /* best-effort */ }
|
|
144
148
|
}
|
|
149
|
+
// Persistent-stdin children live OUTSIDE _activeProcesses between turns —
|
|
150
|
+
// idle-kill must reach them too (the next turn re-spawns with --resume).
|
|
151
|
+
this._stdinSessions.kill(conversationId);
|
|
145
152
|
}, exports.EXPLORE_IDLE_KILL_MS);
|
|
146
153
|
}
|
|
147
154
|
/**
|
|
@@ -223,6 +230,8 @@ class ChatManager {
|
|
|
223
230
|
}
|
|
224
231
|
catch { /* best-effort */ }
|
|
225
232
|
}
|
|
233
|
+
// Reclaim the slot from a persistent-stdin child parked between turns.
|
|
234
|
+
this._stdinSessions.kill(victim);
|
|
226
235
|
this._clearIdleTimer(victim);
|
|
227
236
|
this._exploreLifecycle.delete(victim);
|
|
228
237
|
if (this._countStreamingExplore() < exports.EXPLORE_MAX_CONCURRENCY)
|
|
@@ -547,6 +556,19 @@ class ChatManager {
|
|
|
547
556
|
// not pipeline jobs. Telemetry is scoped to QueueManager pipeline runs only.
|
|
548
557
|
// spawnAiCli reroutes multi-line argv values through stdin on Windows.
|
|
549
558
|
const spawnCwd = this._resolveSpawnCwd(conversation.kind, conversationScope, adapter.id);
|
|
559
|
+
// Big bet #3 fast-path: persistent-stdin multi-turn for Explore (claude
|
|
560
|
+
// only, flag-gated default OFF). Reuses a single long-lived child across
|
|
561
|
+
// turns so turns 2+ skip spawn + session rehydration. Full fallback to the
|
|
562
|
+
// legacy spawn-per-turn path below when disabled / unsupported.
|
|
563
|
+
if ((0, explore_stdin_session_1.isExplorePersistentStdinEnabled)() &&
|
|
564
|
+
conversation.kind === 'explore' &&
|
|
565
|
+
adapter.capabilities.persistentStdin === true) {
|
|
566
|
+
return await this._streamPersistentExploreTurn({
|
|
567
|
+
conversationId, conversation, adapter, binary, model, systemPrompt,
|
|
568
|
+
scopeFlags, spawnCwd, promptForAdapter, isFirstTurn, userText,
|
|
569
|
+
lightweight, conversationScope,
|
|
570
|
+
});
|
|
571
|
+
}
|
|
550
572
|
const child = (0, cli_prompt_1.spawnAiCli)(binary, args, {
|
|
551
573
|
env: process.env,
|
|
552
574
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
@@ -866,6 +888,223 @@ class ChatManager {
|
|
|
866
888
|
this._reservedTurns.delete(conversationId);
|
|
867
889
|
}
|
|
868
890
|
}
|
|
891
|
+
/**
|
|
892
|
+
* Persistent-stdin Explore turn (big bet #3). Reuses one long-lived claude
|
|
893
|
+
* child per conversation via `--input-format stream-json`: the user turn is
|
|
894
|
+
* written to the child's stdin, and the turn ends on the `result` event
|
|
895
|
+
* (NOT process close — the child stays alive for the next turn). Mirrors the
|
|
896
|
+
* legacy close-handler's finalisation (spec-draft parse, persist, session
|
|
897
|
+
* capture, chat_done, invocation accounting, lifecycle) without crash-respawn
|
|
898
|
+
* — a dead persistent child is evicted and the next turn re-spawns with
|
|
899
|
+
* `--resume`. Only reached when the flag is on; the legacy path is untouched.
|
|
900
|
+
*/
|
|
901
|
+
async _streamPersistentExploreTurn(p) {
|
|
902
|
+
const { conversationId, conversation, adapter, binary, model, systemPrompt, scopeFlags, spawnCwd, promptForAdapter, isFirstTurn, userText, lightweight, conversationScope, } = p;
|
|
903
|
+
const sessionArgs = adapter.buildArgs('chat-stream', {
|
|
904
|
+
prompt: '',
|
|
905
|
+
systemPrompt,
|
|
906
|
+
model,
|
|
907
|
+
sessionId: conversation.session_id ?? undefined,
|
|
908
|
+
extraArgs: scopeFlags,
|
|
909
|
+
loadUserEnv: adapter.id === 'claude' && !!conversationScope?.userMcp,
|
|
910
|
+
});
|
|
911
|
+
const { child } = this._stdinSessions.getOrSpawn(conversationId, {
|
|
912
|
+
binary, args: sessionArgs, cwd: spawnCwd, env: process.env,
|
|
913
|
+
});
|
|
914
|
+
this._activeProcesses.set(conversationId, child);
|
|
915
|
+
this._buffers.set(conversationId, '');
|
|
916
|
+
this._emittedProposals.set(conversationId, new Set());
|
|
917
|
+
this._streamFilters.set(conversationId, { inBlock: false, pendingTail: '' });
|
|
918
|
+
const adapterEvents = [];
|
|
919
|
+
let capturedSessionId = null;
|
|
920
|
+
let stderrBuf = '';
|
|
921
|
+
const turnStartedAt = new Date().toISOString();
|
|
922
|
+
const emitDelta = (newText) => {
|
|
923
|
+
const prev = this._buffers.get(conversationId) ?? '';
|
|
924
|
+
this._buffers.set(conversationId, prev + newText);
|
|
925
|
+
const filter = this._streamFilters.get(conversationId);
|
|
926
|
+
const visibleDelta = filter ? filterDraftBlocksLive(filter, newText) : newText;
|
|
927
|
+
if (visibleDelta) {
|
|
928
|
+
this._broadcast({
|
|
929
|
+
type: 'chat_stream',
|
|
930
|
+
conversationId,
|
|
931
|
+
delta: visibleDelta,
|
|
932
|
+
timestamp: new Date().toISOString(),
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
const proposals = extractCommandProposals(this._buffers.get(conversationId) ?? '');
|
|
936
|
+
const emitted = this._emittedProposals.get(conversationId);
|
|
937
|
+
if (emitted) {
|
|
938
|
+
for (const proposal of proposals) {
|
|
939
|
+
if (!emitted.has(proposal)) {
|
|
940
|
+
emitted.add(proposal);
|
|
941
|
+
this._broadcast({
|
|
942
|
+
type: 'chat_command_proposal',
|
|
943
|
+
conversationId,
|
|
944
|
+
command: proposal,
|
|
945
|
+
timestamp: new Date().toISOString(),
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
const recordInv = (status) => {
|
|
952
|
+
if (!this._projectId)
|
|
953
|
+
return;
|
|
954
|
+
try {
|
|
955
|
+
const { result, estimated } = (0, result_event_1.finaliseInvocationResult)(adapter, adapterEvents, {
|
|
956
|
+
fallbackModel: model,
|
|
957
|
+
});
|
|
958
|
+
(0, ai_invocations_1.recordInvocation)(this._db, {
|
|
959
|
+
id: (0, crypto_1.randomUUID)(),
|
|
960
|
+
project_id: this._projectId,
|
|
961
|
+
provider: adapter.id,
|
|
962
|
+
surface: 'explore-spec',
|
|
963
|
+
surface_ref_id: conversationId,
|
|
964
|
+
conversation_id: conversationId,
|
|
965
|
+
status,
|
|
966
|
+
started_at: turnStartedAt,
|
|
967
|
+
finished_at: new Date().toISOString(),
|
|
968
|
+
total_cost_usd_estimated: estimated,
|
|
969
|
+
...result,
|
|
970
|
+
});
|
|
971
|
+
this._broadcast({ type: 'spending.invalidated', projectId: this._projectId });
|
|
972
|
+
}
|
|
973
|
+
catch (err) {
|
|
974
|
+
console.error('[chat-manager] recordInvocation failed:', err);
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
const cleanupTurnState = () => {
|
|
978
|
+
this._activeProcesses.delete(conversationId);
|
|
979
|
+
this._buffers.delete(conversationId);
|
|
980
|
+
this._emittedProposals.delete(conversationId);
|
|
981
|
+
this._streamFilters.delete(conversationId);
|
|
982
|
+
};
|
|
983
|
+
const markStreamingEnded = (success) => {
|
|
984
|
+
const life = this._exploreLifecycle.get(conversationId);
|
|
985
|
+
if (life) {
|
|
986
|
+
life.isStreaming = false;
|
|
987
|
+
life.lastActivityAt = Date.now();
|
|
988
|
+
if (success)
|
|
989
|
+
life.crashCount = 0;
|
|
990
|
+
if (life.isMinimized)
|
|
991
|
+
this._startIdleTimer(conversationId);
|
|
992
|
+
}
|
|
993
|
+
this._drainExploreQueue();
|
|
994
|
+
};
|
|
995
|
+
return new Promise((resolve) => {
|
|
996
|
+
let settled = false;
|
|
997
|
+
const finishTurn = () => {
|
|
998
|
+
if (settled)
|
|
999
|
+
return;
|
|
1000
|
+
settled = true;
|
|
1001
|
+
this._stdinSessions.clearHandlers(conversationId);
|
|
1002
|
+
const fullText = this._buffers.get(conversationId) ?? '';
|
|
1003
|
+
const wasAborting = this._abortingConversations.has(conversationId);
|
|
1004
|
+
cleanupTurnState();
|
|
1005
|
+
this._abortingConversations.delete(conversationId);
|
|
1006
|
+
markStreamingEnded(true);
|
|
1007
|
+
recordInv(wasAborting ? 'aborted' : 'success');
|
|
1008
|
+
const parsed = (0, spec_draft_parser_1.parseSpecDraftBlocks)(fullText);
|
|
1009
|
+
const persistedText = parsed.blocks.length > 0 ? parsed.stripped : fullText;
|
|
1010
|
+
if (parsed.blocks.length > 0) {
|
|
1011
|
+
const prevState = this._specDraftStates.get(conversationId);
|
|
1012
|
+
const nextState = (0, spec_draft_parser_1.applyBlocks)(prevState, parsed.blocks);
|
|
1013
|
+
this._specDraftStates.set(conversationId, nextState);
|
|
1014
|
+
this._broadcast({
|
|
1015
|
+
type: 'spec_draft.update',
|
|
1016
|
+
conversationId,
|
|
1017
|
+
draft: nextState.draft,
|
|
1018
|
+
ready: nextState.ready,
|
|
1019
|
+
chips: nextState.chips,
|
|
1020
|
+
changedFields: nextState.lastChangedFields,
|
|
1021
|
+
timestamp: new Date().toISOString(),
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
if (persistedText) {
|
|
1025
|
+
(0, db_1.addMessage)(this._db, { conversation_id: conversationId, role: 'assistant', content: persistedText });
|
|
1026
|
+
}
|
|
1027
|
+
if (capturedSessionId) {
|
|
1028
|
+
(0, db_1.updateConversation)(this._db, conversationId, { session_id: capturedSessionId });
|
|
1029
|
+
}
|
|
1030
|
+
this._broadcast({
|
|
1031
|
+
type: 'chat_done',
|
|
1032
|
+
conversationId,
|
|
1033
|
+
fullText: persistedText,
|
|
1034
|
+
timestamp: new Date().toISOString(),
|
|
1035
|
+
});
|
|
1036
|
+
if (isFirstTurn && fullText && !lightweight) {
|
|
1037
|
+
this._autoTitle(conversationId, userText, fullText);
|
|
1038
|
+
}
|
|
1039
|
+
resolve();
|
|
1040
|
+
};
|
|
1041
|
+
const onClose = (code) => {
|
|
1042
|
+
// The persistent child died (crash / idle-kill / shutdown). If the turn
|
|
1043
|
+
// already finished on its `result` event, ignore. No crash-respawn —
|
|
1044
|
+
// the session is evicted by the transport; the next turn re-spawns with
|
|
1045
|
+
// `--resume`, so no persisted state is lost.
|
|
1046
|
+
if (settled)
|
|
1047
|
+
return;
|
|
1048
|
+
settled = true;
|
|
1049
|
+
this._stdinSessions.clearHandlers(conversationId);
|
|
1050
|
+
const wasAborting = this._abortingConversations.has(conversationId);
|
|
1051
|
+
cleanupTurnState();
|
|
1052
|
+
this._abortingConversations.delete(conversationId);
|
|
1053
|
+
markStreamingEnded(false);
|
|
1054
|
+
recordInv(wasAborting ? 'aborted' : 'failed');
|
|
1055
|
+
if (wasAborting) {
|
|
1056
|
+
resolve();
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
const stderrTail = stderrBuf.trim().slice(-500);
|
|
1060
|
+
this._broadcast({
|
|
1061
|
+
type: 'chat_error',
|
|
1062
|
+
conversationId,
|
|
1063
|
+
error: stderrTail
|
|
1064
|
+
? `${binary} exited with code ${code ?? 'unknown'}: ${stderrTail}`
|
|
1065
|
+
: `Process exited with code ${code ?? 'unknown'}`,
|
|
1066
|
+
timestamp: new Date().toISOString(),
|
|
1067
|
+
});
|
|
1068
|
+
resolve();
|
|
1069
|
+
};
|
|
1070
|
+
const onLine = (line) => {
|
|
1071
|
+
const ev = adapter.parseStreamLine(line);
|
|
1072
|
+
if (!ev)
|
|
1073
|
+
return;
|
|
1074
|
+
adapterEvents.push(ev);
|
|
1075
|
+
switch (ev.kind) {
|
|
1076
|
+
case 'text-delta':
|
|
1077
|
+
emitDelta(ev.text);
|
|
1078
|
+
break;
|
|
1079
|
+
case 'session-started':
|
|
1080
|
+
if (ev.sessionId)
|
|
1081
|
+
capturedSessionId = ev.sessionId;
|
|
1082
|
+
break;
|
|
1083
|
+
case 'result': {
|
|
1084
|
+
const sid = ev.payload.session_id;
|
|
1085
|
+
if (sid)
|
|
1086
|
+
capturedSessionId = sid;
|
|
1087
|
+
finishTurn();
|
|
1088
|
+
break;
|
|
1089
|
+
}
|
|
1090
|
+
default:
|
|
1091
|
+
break;
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
this._stdinSessions.setHandlers(conversationId, {
|
|
1095
|
+
onLine,
|
|
1096
|
+
onStderr: (s) => {
|
|
1097
|
+
stderrBuf += s;
|
|
1098
|
+
console.error(`[chat-manager] ${binary} stderr (${conversationId}):`, s.trim());
|
|
1099
|
+
},
|
|
1100
|
+
onClose,
|
|
1101
|
+
});
|
|
1102
|
+
if (!this._stdinSessions.writeTurn(conversationId, promptForAdapter)) {
|
|
1103
|
+
// stdin already gone (child died between spawn and write) — fail the turn.
|
|
1104
|
+
onClose(null);
|
|
1105
|
+
}
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
869
1108
|
abort(conversationId) {
|
|
870
1109
|
const child = this._activeProcesses.get(conversationId);
|
|
871
1110
|
if (!child || !child.pid)
|
|
@@ -893,6 +1132,7 @@ class ChatManager {
|
|
|
893
1132
|
clearTimeout(this._exploreQueue[idx].timeoutTimer);
|
|
894
1133
|
this._exploreQueue.splice(idx, 1);
|
|
895
1134
|
}
|
|
1135
|
+
this._stdinSessions.kill(conversationId);
|
|
896
1136
|
this._exploreLifecycle.delete(conversationId);
|
|
897
1137
|
}
|
|
898
1138
|
/**
|
|
@@ -911,6 +1151,8 @@ class ChatManager {
|
|
|
911
1151
|
catch { /* best-effort */ }
|
|
912
1152
|
}
|
|
913
1153
|
}
|
|
1154
|
+
// Persistent-stdin children outlive individual turns — tear them down too.
|
|
1155
|
+
this._stdinSessions.killAll();
|
|
914
1156
|
for (const id of this._exploreLifecycle.keys()) {
|
|
915
1157
|
this._clearIdleTimer(id);
|
|
916
1158
|
}
|