@cleocode/cleo 2026.9.7 → 2026.9.9
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/dist/cli/index.js +3766 -2232
- package/package.json +14 -13
- package/scripts/check-cleo-tarball-size.mjs +105 -0
- package/scripts/copy-studio-dist.mjs +33 -9
- package/studio-dist/client/_app/immutable/chunks/{wI_OOyoh.js → BB7zPpV2.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{D8NsLz6i.js → BOnrCZaR.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{TX-23QW3.js → BiaAd37T.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/C6jhAnil.js +1 -0
- package/studio-dist/client/_app/immutable/chunks/C87Q3uxm.js +1 -0
- package/studio-dist/client/_app/immutable/chunks/{CqF5Lomf.js → CTLGzgdN.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{o1PZ6Kzq.js → CY3heNub.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{RptFUp2P.js → Cge6qiwc.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{BRgWBQlV.js → CnwXLaZJ.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{Bxz2A0ZC.js → DEH43YwF.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/DGftG5oL.js +3 -0
- package/studio-dist/client/_app/immutable/chunks/{DVHIxkgs.js → DV2HHHkd.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{eK8hf4s7.js → DXxEgUey.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{CEqOYim7.js → DZrdToAH.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/EZwHPWle.js +2 -0
- package/studio-dist/client/_app/immutable/chunks/{B9psmq5-.js → rB_71s8h.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{JPJd4fEI.js → rUtW7Hx6.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/zWFSpNUo.js +1 -0
- package/studio-dist/client/_app/immutable/entry/app.AR3q6Ydw.js +2 -0
- package/studio-dist/client/_app/immutable/entry/start.Cf2RUEwO.js +1 -0
- package/studio-dist/client/_app/immutable/nodes/{0.CZzEEyVh.js → 0.BEkWfyyt.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{1.Bj3Opbua.js → 1.DfbrPFgR.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{10.xe_Mc2Ko.js → 10.3rxHNnSx.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{11.DuKPA7JD.js → 11.B6jWv3Kz.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{12.BoZ_QrUS.js → 12.BrDHeTEq.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{13.DFJiUiv8.js → 13.CE5bd4JV.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{14.eaAlFU4w.js → 14.DgXD2LRx.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{15.BfXgiwMC.js → 15.CdRO2NCB.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{16.mEwy9cqh.js → 16.Cr01BBgh.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{17.DP2QtQGn.js → 17.PZ1GrCot.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{18.Bu0054sX.js → 18.Crly2qhe.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{19.UWt6QbCm.js → 19.su55K8y_.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{2.y5jKpHiR.js → 2.mqgFVWFQ.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{20.B1AIHdkP.js → 20.DqQjto4P.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{21.CpAN71H8.js → 21.BhwhdQCq.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{22.CrYKrN4c.js → 22.BmJEWwER.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{23.pGRaHQjq.js → 23.CAVIJEH-.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{24.BUoUu37z.js → 24.BIypnou8.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/25.CllbQ5CT.js +39 -0
- package/studio-dist/client/_app/immutable/nodes/26.DILkE52_.js +1 -0
- package/studio-dist/client/_app/immutable/nodes/{28.DcmYM7lb.js → 28.D64RBcfs.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{29.lbHbMqNO.js → 29.yfuBeH1x.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{3.Dyir4xXj.js → 3.ChHbetZy.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{30.DXj0Wm2A.js → 30.1WUv5bh9.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/4.D6vXYBoQ.js +1 -0
- package/studio-dist/client/_app/immutable/nodes/{5.VWSdP7oc.js → 5.hjw2O-4e.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{6.Dl-XLwOj.js → 6.CAoDfDt6.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{7.CFuC5L-y.js → 7.CLgPSQ8Z.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{8.BCJ0DhOb.js → 8.zuaO1Hik.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{9.Bq4SUzL9.js → 9.Cdsd85m2.js} +1 -1
- package/studio-dist/client/_app/version.json +1 -1
- package/studio-dist/server/chunks/0-BvvArN5K.js +41 -0
- package/studio-dist/server/chunks/1-rLPlIpIR.js +9 -0
- package/studio-dist/server/chunks/{10-DvOD4ksa.js → 10-CYLc3d5x.js} +3 -3
- package/studio-dist/server/chunks/{11-DMnBZ02H.js → 11-DcIYR5vm.js} +3 -3
- package/studio-dist/server/chunks/{12-CCyRyRWX.js → 12-WE1u104t.js} +3 -3
- package/studio-dist/server/chunks/{13-Dx1c3a_X.js → 13-joBDoxhK.js} +3 -3
- package/studio-dist/server/chunks/{14-Bo-dTCaZ.js → 14-Doj5F4uJ.js} +3 -3
- package/studio-dist/server/chunks/{15-BvUNl3KL.js → 15-BlL3H5S5.js} +3 -3
- package/studio-dist/server/chunks/{16-De6EzPSa.js → 16-C-UvTi7Z.js} +5 -4
- package/studio-dist/server/chunks/{17-CZNsiZhi.js → 17-C790IKoE.js} +10 -93
- package/studio-dist/server/chunks/{18-CbxxjZox.js → 18-6VS9Vgfx.js} +5 -4
- package/studio-dist/server/chunks/{19-DqHyladS.js → 19-BAQHPrMB.js} +3 -3
- package/studio-dist/server/chunks/{2-COvmA-ZA.js → 2-DXSVVaej.js} +10 -93
- package/studio-dist/server/chunks/20-DUG4_xXL.js +57 -0
- package/studio-dist/server/chunks/{21-DXK9ptAC.js → 21-qhGjkW41.js} +4 -31
- package/studio-dist/server/chunks/{22-DD5CLWJC.js → 22-Byy16hFA.js} +3 -3
- package/studio-dist/server/chunks/23-CZpFrGp4.js +97 -0
- package/studio-dist/server/chunks/24-CkIGZX8S.js +67 -0
- package/studio-dist/server/chunks/{25-CAg6Xcmn.js → 25-CHBaeXym.js} +15 -96
- package/studio-dist/server/chunks/{26-_nfVTvNi.js → 26-BbDd--8j.js} +12 -93
- package/studio-dist/server/chunks/{27-C9edghG4.js → 27-Cqzlh9gZ.js} +3 -2
- package/studio-dist/server/chunks/{28-VemTJGyc.js → 28-DeYe2rpm.js} +8 -62
- package/studio-dist/server/chunks/{29-CXP-m29t.js → 29-6pjLM0Z1.js} +10 -93
- package/studio-dist/server/chunks/{3-B8KhfvHp.js → 3-DMSsQV71.js} +9 -25
- package/studio-dist/server/chunks/{30-QiM1S4cJ.js → 30-Dw317sSW.js} +10 -93
- package/studio-dist/server/chunks/{31-BwdY9NnB.js → 31-Q4kHbp8j.js} +3 -2
- package/studio-dist/server/chunks/{4-CSaG4HjO.js → 4-C9BMSh4K.js} +4 -3
- package/studio-dist/server/chunks/{5-i5ry4y3C.js → 5-C0CF4WKG.js} +3 -3
- package/studio-dist/server/chunks/{6-DR1GWBMT.js → 6-BWyOJust.js} +3 -3
- package/studio-dist/server/chunks/{7-DSNwn3aQ.js → 7-CK4MK5gy.js} +3 -3
- package/studio-dist/server/chunks/{8-Bj0bx07K.js → 8-CiX7Xk9k.js} +3 -3
- package/studio-dist/server/chunks/{9-B3Tz0mZq.js → 9-Be5118w4.js} +3 -3
- package/studio-dist/server/chunks/{HeroHeader-v4Q9vaGr.js → HeroHeader-BrGN5WPw.js} +2 -2
- package/studio-dist/server/chunks/{Sparkline-BJ-GuhRd.js → Sparkline-DU_NVxz9.js} +2 -2
- package/studio-dist/server/chunks/{StatBlock-DHJMmOCx.js → StatBlock-jNsxycS1.js} +2 -2
- package/studio-dist/server/chunks/{Tabs-DzG6Bn9a.js → Tabs-DQKDflnT.js} +2 -2
- package/studio-dist/server/chunks/_dispatch-DTWViLGL.js +145 -0
- package/studio-dist/server/chunks/{_layout.svelte-BEIGQcIv.js → _layout.svelte-BjSWu4Fw.js} +7 -9
- package/studio-dist/server/chunks/{_page.svelte-al08ovKm.js → _page.svelte-6iMiGR11.js} +5 -5
- package/studio-dist/server/chunks/{_page.svelte-Byz2djto.js → _page.svelte-B-YXGvAW.js} +5 -5
- package/studio-dist/server/chunks/{_page.svelte-UYiF7YBK.js → _page.svelte-BCRyjlk2.js} +5 -5
- package/studio-dist/server/chunks/{_page.svelte-2cgtvHwW.js → _page.svelte-BdkomWnj.js} +13 -71
- package/studio-dist/server/chunks/{_page.svelte-CCoTp89s.js → _page.svelte-BoYafqft.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-nzffIbBP.js → _page.svelte-C7Wm6_HB.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-Wfx7ww_h.js → _page.svelte-CIyzbngu.js} +11 -13
- package/studio-dist/server/chunks/{_page.svelte-C_VSL8NW.js → _page.svelte-CmbOzJ6A.js} +13 -71
- package/studio-dist/server/chunks/{_page.svelte-CophUar3.js → _page.svelte-CqI6hqMm.js} +5 -5
- package/studio-dist/server/chunks/{_page.svelte-tYN7_LXI.js → _page.svelte-CtSwzG-R.js} +9 -11
- package/studio-dist/server/chunks/{_page.svelte-DYNorA0S.js → _page.svelte-Cx9Ptecp.js} +10 -67
- package/studio-dist/server/chunks/{_page.svelte-9OQphlnm.js → _page.svelte-D4Uf5q1X.js} +14 -69
- package/studio-dist/server/chunks/{_page.svelte-BIlhmugm.js → _page.svelte-DRjD44sK.js} +11 -13
- package/studio-dist/server/chunks/{_page.svelte-BVVTrzTL.js → _page.svelte-DaheDIRs.js} +5 -5
- package/studio-dist/server/chunks/{_page.svelte-DOWw416I.js → _page.svelte-DfIiE7gL.js} +11 -13
- package/studio-dist/server/chunks/{_page.svelte-M5D2QnMS.js → _page.svelte-Dm8y5a8S.js} +10 -67
- package/studio-dist/server/chunks/{_page.svelte-B_pq-Z98.js → _page.svelte-DqXxyNsF.js} +7 -7
- package/studio-dist/server/chunks/{_page.svelte-C3aIui4o.js → _page.svelte-DqsbnAhk.js} +4 -4
- package/studio-dist/server/chunks/{_page.svelte-ksTJUXce.js → _page.svelte-Dt0_c1T-.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-bGhsrIjS.js → _page.svelte-Dv6iwhu7.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-BXyoMME1.js → _page.svelte-GPiHej3P.js} +5 -5
- package/studio-dist/server/chunks/{_page.svelte-CYDjW1R0.js → _page.svelte-LuRm8XxE.js} +5 -5
- package/studio-dist/server/chunks/{_page.svelte-Clbkk1gm.js → _page.svelte-Z7nL9SC-.js} +8 -9
- package/studio-dist/server/chunks/{_page.svelte-DUWbZjC7.js → _page.svelte-_kntHS6v.js} +4 -4
- package/studio-dist/server/chunks/{_page.svelte-l4Z_xjl9.js → _page.svelte-k-4NCnbz.js} +9 -11
- package/studio-dist/server/chunks/{_page.svelte-CHzXuw2Q.js → _page.svelte-me5SUosG.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-BgwL2Gyu.js → _page.svelte-sHj6UAzC.js} +11 -13
- package/studio-dist/server/chunks/{_server.ts-DSzRdt1U.js → _server.ts--2m_U4SL.js} +11 -94
- package/studio-dist/server/chunks/{_server.ts-ujoDR2_g.js → _server.ts--sGLmBsz.js} +10 -92
- package/studio-dist/server/chunks/{_server.ts-k2fApwOp.js → _server.ts-0ukyuE0I.js} +5 -60
- package/studio-dist/server/chunks/_server.ts-1eW2mTeh.js +40 -0
- package/studio-dist/server/chunks/{_server.ts-Bfr4u3EP.js → _server.ts-3LzqLzt0.js} +10 -92
- package/studio-dist/server/chunks/_server.ts-5euivmMj.js +38 -0
- package/studio-dist/server/chunks/{_server.ts-CShsBkeE.js → _server.ts-B0uoay97.js} +7 -23
- package/studio-dist/server/chunks/{_server.ts-hL92cV7Z.js → _server.ts-B5vYKkI6.js} +9 -63
- package/studio-dist/server/chunks/{_server.ts-_RJXtmfi.js → _server.ts-B8dTbPHd.js} +8 -23
- package/studio-dist/server/chunks/{_server.ts-C3Jo-ju8.js → _server.ts-BA8Xdegq.js} +10 -92
- package/studio-dist/server/chunks/_server.ts-BBClE0n9.js +54 -0
- package/studio-dist/server/chunks/{_server.ts-CJA1djzJ.js → _server.ts-BCnr9uaO.js} +8 -92
- package/studio-dist/server/chunks/{_server.ts-ZS1_yMwR.js → _server.ts-BDwMoyZ_.js} +6 -32
- package/studio-dist/server/chunks/{_server.ts-sv4pA808.js → _server.ts-BE-Uhx4N.js} +5 -46
- package/studio-dist/server/chunks/{_server.ts-DV6pzF-M.js → _server.ts-BSHADOUJ.js} +4 -3
- package/studio-dist/server/chunks/{_server.ts-BdN4AJ6o.js → _server.ts-BSgLJPPQ.js} +10 -91
- package/studio-dist/server/chunks/_server.ts-Bl9tMqwZ.js +159 -0
- package/studio-dist/server/chunks/_server.ts-BlzDnRI0.js +51 -0
- package/studio-dist/server/chunks/{_server.ts-DnE0f-iC.js → _server.ts-BtuemCsf.js} +4 -3
- package/studio-dist/server/chunks/{_server.ts-BPcErnS0.js → _server.ts-C2nYqbd9.js} +10 -92
- package/studio-dist/server/chunks/{_server.ts-4p6cp9ke.js → _server.ts-C6IDM_3I.js} +10 -92
- package/studio-dist/server/chunks/_server.ts-C8Z32vuL.js +45 -0
- package/studio-dist/server/chunks/_server.ts-CBXyadsy.js +26 -0
- package/studio-dist/server/chunks/{_server.ts-Do9RIPRo.js → _server.ts-CE6h2ATE.js} +5 -32
- package/studio-dist/server/chunks/_server.ts-CGROl_5b.js +122 -0
- package/studio-dist/server/chunks/_server.ts-CH06JVqZ.js +65 -0
- package/studio-dist/server/chunks/_server.ts-CNqcws-M.js +29 -0
- package/studio-dist/server/chunks/{_server.ts-uUx7uT2Y.js → _server.ts-CYv5YuHd.js} +6 -43
- package/studio-dist/server/chunks/{_server.ts-DSAv66wD.js → _server.ts-CbThsyhY.js} +4 -3
- package/studio-dist/server/chunks/{_server.ts-DgbY5EB3.js → _server.ts-CeQolQOK.js} +10 -92
- package/studio-dist/server/chunks/_server.ts-ChoGyX5C.js +61 -0
- package/studio-dist/server/chunks/_server.ts-CjJYkLJH.js +61 -0
- package/studio-dist/server/chunks/{_server.ts-lPlBUIJX.js → _server.ts-CtjArzxf.js} +5 -60
- package/studio-dist/server/chunks/{_server.ts-Cq60m8Pw.js → _server.ts-D3QWZwt_.js} +4 -3
- package/studio-dist/server/chunks/{_server.ts-CkoJ2HCW.js → _server.ts-D6wP5bCh.js} +10 -92
- package/studio-dist/server/chunks/{_server.ts-DwTRjS4y.js → _server.ts-D7JwQTun.js} +10 -93
- package/studio-dist/server/chunks/_server.ts-DKFJdXPK.js +97 -0
- package/studio-dist/server/chunks/_server.ts-DNAPGKEF.js +55 -0
- package/studio-dist/server/chunks/_server.ts-DQiTiY3E.js +78 -0
- package/studio-dist/server/chunks/{_server.ts-B2E7fxo9.js → _server.ts-DUPODxVZ.js} +6 -91
- package/studio-dist/server/chunks/{_server.ts-BT0Uq2yq.js → _server.ts-DUyeSXbV.js} +10 -92
- package/studio-dist/server/chunks/{_server.ts-DRVz9D-J.js → _server.ts-DY7BwZCv.js} +9 -24
- package/studio-dist/server/chunks/{_server.ts-Cz0zgaUV.js → _server.ts-D_E276ms.js} +3 -2
- package/studio-dist/server/chunks/{_server.ts-B5g3eScF.js → _server.ts-DgtmTAp5.js} +5 -60
- package/studio-dist/server/chunks/{_server.ts-CboRJY0Q.js → _server.ts-DhTKaw7h.js} +10 -63
- package/studio-dist/server/chunks/_server.ts-DqKBSCPT.js +31 -0
- package/studio-dist/server/chunks/{_server.ts-CpmMp5D8.js → _server.ts-DyXBNnRD.js} +4 -3
- package/studio-dist/server/chunks/_server.ts-DzjUpduu.js +25 -0
- package/studio-dist/server/chunks/{_server.ts-CGiAXy5i.js → _server.ts-Dznqw6Dg.js} +8 -23
- package/studio-dist/server/chunks/{_server.ts-tKMjUFUP.js → _server.ts-EVwS7UXb.js} +4 -3
- package/studio-dist/server/chunks/_server.ts-J17j25VG.js +62 -0
- package/studio-dist/server/chunks/{_server.ts-C4BcDGqS.js → _server.ts-XLV5SvjH.js} +7 -63
- package/studio-dist/server/chunks/_server.ts-jZgqFIJz.js +45 -0
- package/studio-dist/server/chunks/{_server.ts-Bw7A4zgb.js → _server.ts-lyiGGv7w.js} +5 -3
- package/studio-dist/server/chunks/_server.ts-n0fpsfkk.js +67 -0
- package/studio-dist/server/chunks/{brain-CXR7ZT7S.js → brain-xt_NeshR.js} +2 -2
- package/studio-dist/server/chunks/cleo-home-_XIqkZaL.js +109 -0
- package/studio-dist/server/chunks/{cli-action-DQcaqcfn.js → cli-action-VJPEn1pY.js} +2 -2
- package/studio-dist/server/chunks/{client-CgX38JBu.js → client-CrfCXSXZ.js} +5 -6
- package/studio-dist/server/chunks/cluster-label-layer-CysRMvhi.js +6721 -0
- package/studio-dist/server/chunks/connections-CWLPjwBP.js +15 -0
- package/studio-dist/server/chunks/{connections2-mi7mZqJM.js → connections2-DHVs5ytW.js} +32 -19
- package/studio-dist/server/chunks/{dev-BNpEUZI3.js → dev-Br5zieNA.js} +2 -2
- package/studio-dist/server/chunks/dist-BR1f34Gj.js +18726 -0
- package/studio-dist/server/chunks/{error.svelte-CplNulnS.js → error.svelte-CmR0NUCQ.js} +6 -8
- package/studio-dist/server/chunks/{explorer-loader-BN_mkt3_.js → explorer-loader-B_uCSs9_.js} +2 -2
- package/studio-dist/server/chunks/exports-Dg-gdPPq.js +124 -0
- package/studio-dist/server/chunks/{hooks.server-DBsyphiX.js → hooks.server-CWBRp8NI.js} +10 -93
- package/studio-dist/server/chunks/{http-CRTZe306.js → http-Dso0FRxT.js} +3 -4
- package/studio-dist/server/chunks/{index-server-DocJvixA.js → index-server-BgfA6C0S.js} +17 -4
- package/studio-dist/server/chunks/{internal-D6eWgsHJ.js → internal-DYUO6aQs.js} +56 -92
- package/studio-dist/server/chunks/{memory2-Cgc_4D5q.js → memory-BZHnDZzu.js} +4 -4
- package/studio-dist/server/chunks/{nexus-adapter-9EL_VlGI.js → nexus-adapter-D1ryYG1Z.js} +5 -5
- package/studio-dist/server/chunks/{no-face-up-DcejJLy-.js → no-face-up-B_3h6Hgs.js} +2 -2
- package/studio-dist/server/chunks/project-context-BAXQmgch.js +188 -0
- package/studio-dist/server/chunks/{src-BUqGet2c.js → src-D2rW9bIF.js} +422 -5
- package/studio-dist/server/chunks/{stores-5DmdjPCH.js → stores-CS6eY2sx.js} +3 -3
- package/studio-dist/server/chunks/{tasks2-Bf9VHrv-.js → tasks-sWuEmiGW.js} +2349 -9
- package/studio-dist/server/chunks/{ui-DR8zOSpC.js → ui-CkQ-pCs3.js} +2 -2
- package/studio-dist/server/chunks/utils-g564cUMV.js +151 -0
- package/studio-dist/server/index.js +5 -16
- package/studio-dist/server/manifest.js +88 -88
- package/dist/cli/index.js.map +0 -6
- package/studio-dist/client/_app/immutable/assets/parse-worker.CSEr67Qi.js +0 -1127
- package/studio-dist/client/_app/immutable/chunks/2mEksghu2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/3KebaI-z.js +0 -53
- package/studio-dist/client/_app/immutable/chunks/3y2yNYEk2.js +0 -3
- package/studio-dist/client/_app/immutable/chunks/7UXYlaI1.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/83VLmCvk.js +0 -4
- package/studio-dist/client/_app/immutable/chunks/84Rhmi6r.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/9CV9TXTg2.js +0 -92
- package/studio-dist/client/_app/immutable/chunks/9LFtcz24.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/9bLMgKwu2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/9kKqohVR2.js +0 -37
- package/studio-dist/client/_app/immutable/chunks/B-Ye28EY.js +0 -7
- package/studio-dist/client/_app/immutable/chunks/B-jnUl7o.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/B0ORuy8x2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/B0xCM1wN2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/B0zCN4sX.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/B1wt-iGW.js +0 -7
- package/studio-dist/client/_app/immutable/chunks/B2F3KUIU.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/B2_6RrlL2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/B2qKEYxA2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/B2u2rNyI2.js +0 -8
- package/studio-dist/client/_app/immutable/chunks/B3_X3Lhd2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/B3sNtbqf.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/B4NQP1Ax2.js +0 -6
- package/studio-dist/client/_app/immutable/chunks/BAtZg5v5.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BB6WKLm82.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BBX8UDtn.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BBs1U1iU.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BEli_4Jp2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BEt2wIUt.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BEyM8qSW2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BFZA3Dsk2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BGdPweG1.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BGiusSqE.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BGmpyfzD.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BH5rhSIR.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BHciFt922.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BHnFwTQY.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BIvye3XP2.js +0 -59
- package/studio-dist/client/_app/immutable/chunks/BJ8mcpQA2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BK17qSHw.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BLkgUtyb.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BMUko3r62.js +0 -5
- package/studio-dist/client/_app/immutable/chunks/BMwzdEaa.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BQZx6brg.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BUPJTTTd.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BVNGAeZe2.js +0 -146
- package/studio-dist/client/_app/immutable/chunks/BWfLryGm.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BXIfeogw.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BXTfFyUU.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BYJC6_MM.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BZV1ZJzH.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BZu9rehd.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Bbzm48C52.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BfGnlwjH.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Bfjb9LPp.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BieFfu-R.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Bmv63uXe2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BtBW1A0u.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/BxISGQCl2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/ByNR_KvT.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BzjhD6Hr2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/BzpWnq0c2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/C-yJVcyI2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/C0cQ-8kS2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/C1vWmhYe.js +0 -48
- package/studio-dist/client/_app/immutable/chunks/C1w6bBje.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/C243sn7r.js +0 -4
- package/studio-dist/client/_app/immutable/chunks/C2oZaDvt.js +0 -67
- package/studio-dist/client/_app/immutable/chunks/C3OziSQx.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/C3hFPbMK.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/C4P9oFvU2.js +0 -6
- package/studio-dist/client/_app/immutable/chunks/C5Nlanei.js +0 -8
- package/studio-dist/client/_app/immutable/chunks/C6KBAXPl.js +0 -15
- package/studio-dist/client/_app/immutable/chunks/C8MZnWta.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CAoan3K12.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CBpcINYH.js +0 -29
- package/studio-dist/client/_app/immutable/chunks/CE7phgWq.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CFb4Co_K.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/CGWoRK3t2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CH3t4xo1.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CHJgk6g-.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CHgPjuDQ.js +0 -17
- package/studio-dist/client/_app/immutable/chunks/CHkCZrnr.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CI_91WUN.js +0 -4
- package/studio-dist/client/_app/immutable/chunks/CJ7-hP0H.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CKIrNnkY2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CKoQ7Ko5.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CM8O4zqs.js +0 -56
- package/studio-dist/client/_app/immutable/chunks/CMz3AVRO.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CNToUR3P.js +0 -13
- package/studio-dist/client/_app/immutable/chunks/CNuQG1yl2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CQLIZtxj.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/CQYVNgM0.js +0 -20
- package/studio-dist/client/_app/immutable/chunks/CQeVOmFO2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CSPHHq09.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CTJEdbIn.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CTTT3wYw.js +0 -35
- package/studio-dist/client/_app/immutable/chunks/CV4ck7fz.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/CXQrVnHf.js +0 -11
- package/studio-dist/client/_app/immutable/chunks/CXTCtOUQ.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/C_CsU7Qq.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/C_IZx3682.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/CbTnu2Po2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Cba8RZ1a2.js +0 -8
- package/studio-dist/client/_app/immutable/chunks/Cc8xxDr5.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CdPxoldu.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CdqDTozW.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CdsmcCfC.js +0 -25
- package/studio-dist/client/_app/immutable/chunks/CeYPAoY9.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Cf4kGS9y.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CfWEqXtJ2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Cg7Wj2b9.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/CgTpKZfi2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Chpy9ca7.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/CiLKuLrQ.js +0 -4
- package/studio-dist/client/_app/immutable/chunks/CjNDJjwu.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Cjde0ZKr2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Cjgnade02.js +0 -3
- package/studio-dist/client/_app/immutable/chunks/Ckp90om52.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/ClAPVhCD.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/ClT89UdO.js +0 -11
- package/studio-dist/client/_app/immutable/chunks/CnJf5tML.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CpF4Rrcc2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CqCka5yX2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CqtqZrOl.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CrJdywQt.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Cs0zC2l2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CsMn5fBs.js +0 -141
- package/studio-dist/client/_app/immutable/chunks/CsvKLHQQ2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/Ctaresvj.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Ctetf8vc2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/Cv7yW6MG.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CxRIz-Zd.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/CxbvtjIH.js +0 -3
- package/studio-dist/client/_app/immutable/chunks/CxfeoXkZ.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/CySLscL2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/D0PKQAbM.js +0 -87
- package/studio-dist/client/_app/immutable/chunks/D0WQsLTu.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/D1LBVx6r2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/D1NlFXu9.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/D1QfC4hu2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/D1yrHAn72.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/D2pa4reh.js +0 -7
- package/studio-dist/client/_app/immutable/chunks/D3QsWcIw2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/D4OkQuPl2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/D6UDnATk2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/D7w7HllH.js +0 -38
- package/studio-dist/client/_app/immutable/chunks/D93KpglN.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/D99fQj2G2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DB5ifLM-.js +0 -3
- package/studio-dist/client/_app/immutable/chunks/DBhP8ifO2.js +0 -15
- package/studio-dist/client/_app/immutable/chunks/DF_4OWhj.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/DFpNK1vs2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DGRYMk-W.js +0 -142
- package/studio-dist/client/_app/immutable/chunks/DH3CcQwq.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DHQfJeLU.js +0 -4
- package/studio-dist/client/_app/immutable/chunks/DL89yEDy2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DLRku_0p2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/DMZkjPYT2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DNP72foU.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DO2GztVm.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DOVNXmCK2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DOqzs8kl2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DQnR63hh2.js +0 -7
- package/studio-dist/client/_app/immutable/chunks/DTxtWPkw.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DVDgCC9A2.js +0 -20
- package/studio-dist/client/_app/immutable/chunks/DVVCJYjz.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DWRhYUMj2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DWavBJBI.js +0 -4
- package/studio-dist/client/_app/immutable/chunks/DXDSWRw-.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DXoHaH4a.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/DXpCX2Hi.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DYP3EJMY.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DYQphR_V.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DYUlIivP.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DYo2ye8X2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DYxFu8yV.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DZ66sRb6.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/D_XTiylm2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DaRv9jn22.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DaXb9i_E.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Dccf4VP2.js +0 -24
- package/studio-dist/client/_app/immutable/chunks/DdODs-Sb.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DdekYWer.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/DeHaovsF.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DeRRkRO52.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DeWI5qCn.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DfivR-Md.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DgmxpSo7.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DhPLWrun2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DhhrVdfi.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/Djr2dbcc2.js +0 -37
- package/studio-dist/client/_app/immutable/chunks/DjuRo5vv.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Djz4EDzO.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DkRfaw-K2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DksB5g4W2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Dmqenb5z2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DnbToVyf.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/DpGZwlmj.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Dq0lE5C32.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Dq54XqHT2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DqK84mbb.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DqjFtSJD.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/DrKWWDpL.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DsQIgu-4.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DsqdgJHS2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DtNkZUkq.js +0 -17
- package/studio-dist/client/_app/immutable/chunks/DutIls4V2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DvxYFW4C.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Dwp-76GQ.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/DxSZd548.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DxiUMhk0.js +0 -5
- package/studio-dist/client/_app/immutable/chunks/DxslLswf.js +0 -23
- package/studio-dist/client/_app/immutable/chunks/Dy7EjGgb2.js +0 -9
- package/studio-dist/client/_app/immutable/chunks/DyGQ_VXC.js +0 -3
- package/studio-dist/client/_app/immutable/chunks/DySe3kTV2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DyzE2Uxw.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/DzhuJaxE2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/FmMHyrh6.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Gxs0J274.js +0 -5
- package/studio-dist/client/_app/immutable/chunks/HwtzDYxN.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/ITRz_Q7H2.js +0 -15
- package/studio-dist/client/_app/immutable/chunks/KDNP98XY2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/LmVjFhpk2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/MiAejGV_.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Ml4JR6Jz2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/NU5S3nNs2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/Oh5zPjv3.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/QZkvJ9vi.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Rbn8UpBm.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/SPX3gYwn2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/UyeQuL132.js +0 -12
- package/studio-dist/client/_app/immutable/chunks/VQszoXcV.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/VtZsEMxD.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/W2IeK61p2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Wadww7ZG.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/WgfA1zWk2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/WxIgAS1f.js +0 -21
- package/studio-dist/client/_app/immutable/chunks/XrsBoOj9.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/Y3PX4poR.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/YxfwqiF32.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/Z7uO1YaO.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/_4ykQk_8.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/_kRcZFVn.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/aQNM7eVA2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/bHKz_Fb2.js +0 -45
- package/studio-dist/client/_app/immutable/chunks/bJRyRGSZ.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/dlzF6lnR.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/fjRbpfEr2.js +0 -26
- package/studio-dist/client/_app/immutable/chunks/imLk4if5.js +0 -3
- package/studio-dist/client/_app/immutable/chunks/lgRG0R-32.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/mFhCjxQJ2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/mgnH6qYg.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/n6M_5LoW.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/nLIOiDZp2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/nab7WB3u2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/orUmAKoW2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/p-fLQDfY2.js +0 -63
- package/studio-dist/client/_app/immutable/chunks/s0-WkOGk2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/sPuXfbUF.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/t4h0vrqR2.js +0 -2
- package/studio-dist/client/_app/immutable/chunks/uE83FKL-.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/uzhXlm0g2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/vTrEsGlD2.js +0 -1
- package/studio-dist/client/_app/immutable/chunks/xJgCk3dx2.js +0 -28
- package/studio-dist/client/_app/immutable/chunks/z0Mt579s2.js +0 -13
- package/studio-dist/client/_app/immutable/entry/app.BoQ7cgT2.js +0 -2
- package/studio-dist/client/_app/immutable/entry/start.Cg1v8DU4.js +0 -1
- package/studio-dist/client/_app/immutable/nodes/25.ddZ1_EFk.js +0 -1
- package/studio-dist/client/_app/immutable/nodes/26.6OcmQbLV.js +0 -1
- package/studio-dist/client/_app/immutable/nodes/4.CCjOEwVU.js +0 -1
- package/studio-dist/server/chunks/0-CvsKDxQ6.js +0 -126
- package/studio-dist/server/chunks/1-ck_x2Hf0.js +0 -9
- package/studio-dist/server/chunks/20-DVU22np7.js +0 -142
- package/studio-dist/server/chunks/23-D_tUnnoc.js +0 -181
- package/studio-dist/server/chunks/24-CVlymvLF.js +0 -151
- package/studio-dist/server/chunks/AwsRestJsonProtocol-BZuoNBmL.js +0 -416
- package/studio-dist/server/chunks/UnionSerde-BflIkhKj.js +0 -2653
- package/studio-dist/server/chunks/_dispatch-ncuRztUQ.js +0 -5597
- package/studio-dist/server/chunks/_server.ts-4NyKAneX.js +0 -116
- package/studio-dist/server/chunks/_server.ts-7hGdxdEI.js +0 -136
- package/studio-dist/server/chunks/_server.ts-B6b3b-yA.js +0 -131
- package/studio-dist/server/chunks/_server.ts-BOgGqaZp.js +0 -144
- package/studio-dist/server/chunks/_server.ts-BV1HiKZ0.js +0 -120
- package/studio-dist/server/chunks/_server.ts-BWp3g6Cr.js +0 -110
- package/studio-dist/server/chunks/_server.ts-C5NF-UgC.js +0 -122
- package/studio-dist/server/chunks/_server.ts-CDMurH5m.js +0 -2301
- package/studio-dist/server/chunks/_server.ts-COJHCgbq.js +0 -127
- package/studio-dist/server/chunks/_server.ts-CUl-Utkt.js +0 -148
- package/studio-dist/server/chunks/_server.ts-D0GAFJRb.js +0 -156
- package/studio-dist/server/chunks/_server.ts-DA6p3pmi.js +0 -117
- package/studio-dist/server/chunks/_server.ts-DThYFaZj.js +0 -160
- package/studio-dist/server/chunks/_server.ts-D_3Pm0gr.js +0 -179
- package/studio-dist/server/chunks/_server.ts-DcHxdMsm.js +0 -144
- package/studio-dist/server/chunks/_server.ts-Dlfadh2I.js +0 -144
- package/studio-dist/server/chunks/_server.ts-JallJnps.js +0 -240
- package/studio-dist/server/chunks/_server.ts-NEFTbJpM.js +0 -142
- package/studio-dist/server/chunks/_server.ts-d-2NvRwX.js +0 -122
- package/studio-dist/server/chunks/_server.ts-rUWMLkIw.js +0 -146
- package/studio-dist/server/chunks/abort-events-CDRAJSqb.js +0 -30
- package/studio-dist/server/chunks/adapters-BkMgPNUM.js +0 -359
- package/studio-dist/server/chunks/adapters2-CQ3PzoaK.js +0 -28
- package/studio-dist/server/chunks/api-mode2-3W-I1-XO.js +0 -36
- package/studio-dist/server/chunks/api2-CmNQzb0b.js +0 -96
- package/studio-dist/server/chunks/attention-consolidate-CidG1jfH.js +0 -485
- package/studio-dist/server/chunks/audit3-DMO_fUGp.js +0 -52
- package/studio-dist/server/chunks/auto-extract-B84La1Vs.js +0 -34
- package/studio-dist/server/chunks/brain-consolidator-JGm6mzFf.js +0 -373
- package/studio-dist/server/chunks/brain-doctor-Dc2WqVbs.js +0 -311
- package/studio-dist/server/chunks/brain-embedding-Djw9ekXu.js +0 -42
- package/studio-dist/server/chunks/brain-lifecycle-BOOa876K.js +0 -969
- package/studio-dist/server/chunks/brain-maintenance-U6VvsvmK.js +0 -133
- package/studio-dist/server/chunks/brain-maintenance2-CwVSmfDT.js +0 -43
- package/studio-dist/server/chunks/brain-retrieval2-exR8mdgh.js +0 -751
- package/studio-dist/server/chunks/brain-search-CpSh-SNi.js +0 -48
- package/studio-dist/server/chunks/brain-search2-CwI2cXgg.js +0 -716
- package/studio-dist/server/chunks/brain-similarity-DI4yzm9e.js +0 -113
- package/studio-dist/server/chunks/brain-stdp2-BxSBIlSr.js +0 -960
- package/studio-dist/server/chunks/brain-writer-handlers-Dwu0QCAA.js +0 -188
- package/studio-dist/server/chunks/brain-writer-thread-6n7wI7Gy.js +0 -360
- package/studio-dist/server/chunks/branch-lock-Cq7zzmFK.js +0 -1118
- package/studio-dist/server/chunks/branch-lock2-CmDc4CZW.js +0 -45
- package/studio-dist/server/chunks/cancelled-child-waiver-audit-DkesrN83.js +0 -54
- package/studio-dist/server/chunks/catalog-model-resolver-Bas9qnoP.js +0 -9
- package/studio-dist/server/chunks/catalog-model-resolver2-Cexk2TN0.js +0 -237
- package/studio-dist/server/chunks/catalog-resolver-CLot3XJO.js +0 -260
- package/studio-dist/server/chunks/catalog-resolver2-JmKb91kY.js +0 -33
- package/studio-dist/server/chunks/chunk-DDP5xfzh.js +0 -39
- package/studio-dist/server/chunks/cleo-home-CCfe6kAQ.js +0 -64
- package/studio-dist/server/chunks/concrete-session2-bb_vxJ2N.js +0 -43
- package/studio-dist/server/chunks/config-DHj9CcFs.js +0 -386
- package/studio-dist/server/chunks/config2-F6PPIn7D.js +0 -35
- package/studio-dist/server/chunks/connections-BMGJVYcS.js +0 -98
- package/studio-dist/server/chunks/credential-pool-vF6NdtT9.js +0 -4600
- package/studio-dist/server/chunks/credentials-C7EJFf5O.js +0 -35
- package/studio-dist/server/chunks/credentials-store-CFygIuB2.js +0 -35
- package/studio-dist/server/chunks/cross-db-cleanup-1LWTUKPi.js +0 -147
- package/studio-dist/server/chunks/data-accessor-CWgVndbR.js +0 -72
- package/studio-dist/server/chunks/data-safety-central-DaFxK27G.js +0 -683
- package/studio-dist/server/chunks/decisions-CmVXV2-H.js +0 -574
- package/studio-dist/server/chunks/decisions2-XQsSYdxa.js +0 -48
- package/studio-dist/server/chunks/depends-waiver-audit-CUmlBYHx.js +0 -56
- package/studio-dist/server/chunks/dialectic-evaluator2-BOyyXhdI.js +0 -96
- package/studio-dist/server/chunks/dist-es2-DQy2Mjn_.js +0 -43
- package/studio-dist/server/chunks/dist-es3-CBygU4n5.js +0 -365
- package/studio-dist/server/chunks/dist-es4-CavbNu4B.js +0 -162
- package/studio-dist/server/chunks/dist-es5-Crpm8Wsl.js +0 -465
- package/studio-dist/server/chunks/dist-es6-CgePHzh4.js +0 -99
- package/studio-dist/server/chunks/dist-es7-k6c5GEd7.js +0 -311
- package/studio-dist/server/chunks/dist-es8-Bd9v0_pE.js +0 -91
- package/studio-dist/server/chunks/dist3-23bsJhRw.js +0 -27
- package/studio-dist/server/chunks/dist4-DmC1zSXi.js +0 -35618
- package/studio-dist/server/chunks/dual-scope-db-DKnWu1KM.js +0 -5672
- package/studio-dist/server/chunks/dual-scope-db2-Dht3luRw.js +0 -31
- package/studio-dist/server/chunks/duplicate-bypass-audit-BN5w1H2y.js +0 -36
- package/studio-dist/server/chunks/duplicate-detector-CaVFMKdE.js +0 -692
- package/studio-dist/server/chunks/edge-types-CgBvb0w1.js +0 -28
- package/studio-dist/server/chunks/embedding-local-xEnym8Ho.js +0 -92
- package/studio-dist/server/chunks/event-streams-Bi2p_fVo.js +0 -232
- package/studio-dist/server/chunks/execution-learning-BVCw7Plq.js +0 -278
- package/studio-dist/server/chunks/exodus-BBuuN6aA.js +0 -2594
- package/studio-dist/server/chunks/externalDataInterceptor-C3C4cObe.js +0 -21
- package/studio-dist/server/chunks/extraction-gate-DDNBq7gu.js +0 -48
- package/studio-dist/server/chunks/extraction-gate2-D77EZBQ6.js +0 -375
- package/studio-dist/server/chunks/getSSOTokenFromFile-yZAJxDci.js +0 -21
- package/studio-dist/server/chunks/governor2-CtfV3wfX.js +0 -923
- package/studio-dist/server/chunks/graph-auto-populate-Dmsr9ZJM.js +0 -42
- package/studio-dist/server/chunks/graph-auto-populate2-Cz0qeebM.js +0 -156
- package/studio-dist/server/chunks/graph-memory-bridge-CY8ft_d7.js +0 -43
- package/studio-dist/server/chunks/graph-memory-bridge2-Cd0XZwqc.js +0 -429
- package/studio-dist/server/chunks/handler-helpers-AANBGA_p.js +0 -49
- package/studio-dist/server/chunks/hash-Cm6yMET4.js +0 -14
- package/studio-dist/server/chunks/health-monitor-FepUZN1m.js +0 -106
- package/studio-dist/server/chunks/identity-DRpurt56.js +0 -30
- package/studio-dist/server/chunks/identity2-DeAB5RXE.js +0 -114
- package/studio-dist/server/chunks/index-61916rmV.js +0 -632
- package/studio-dist/server/chunks/index-DAgVDouG.js +0 -268
- package/studio-dist/server/chunks/index-Dtt_h58T.js +0 -2116
- package/studio-dist/server/chunks/indexes-DZ52grq6.js +0 -615
- package/studio-dist/server/chunks/json-Bfixam3g.js +0 -126
- package/studio-dist/server/chunks/learnings-D6Y3YGMU.js +0 -47
- package/studio-dist/server/chunks/learnings2-MwBdR9vb.js +0 -171
- package/studio-dist/server/chunks/lifecycle-ops2-V2CR5-7X.js +0 -121
- package/studio-dist/server/chunks/list-BhObczvn.js +0 -229
- package/studio-dist/server/chunks/living-brain2-j0B_Ir8j.js +0 -285
- package/studio-dist/server/chunks/llm-backend-resolver-D4ANvUPL.js +0 -295
- package/studio-dist/server/chunks/llm-extraction-DVCu4heR.js +0 -408
- package/studio-dist/server/chunks/loadSharedConfigFiles-umvW7kuz.js +0 -73
- package/studio-dist/server/chunks/loadSso-iidd5iKx.js +0 -599
- package/studio-dist/server/chunks/local-model-fit-B0TxifnX.js +0 -53
- package/studio-dist/server/chunks/local-model-fit2-BMqo6GJm.js +0 -2664
- package/studio-dist/server/chunks/lock-CA7d6lj7.js +0 -57
- package/studio-dist/server/chunks/logger-DQIoyZbq.js +0 -34
- package/studio-dist/server/chunks/memory-BUbicBbE.js +0 -618
- package/studio-dist/server/chunks/memory-accessor-i3P-RHSg.js +0 -42
- package/studio-dist/server/chunks/memory-accessor2-B981tHDR.js +0 -467
- package/studio-dist/server/chunks/memory-bridge-BOlEWg9w.js +0 -424
- package/studio-dist/server/chunks/memory-sqlite2-B7dq8doO.js +0 -42
- package/studio-dist/server/chunks/model-runner2-B71xjp4y.js +0 -43
- package/studio-dist/server/chunks/mvi-helpers-BNsJ8ZpQ.js +0 -59
- package/studio-dist/server/chunks/nexus-plasticity-BTfU8cW_.js +0 -269
- package/studio-dist/server/chunks/nexus-risk-audit-p379-TU5.js +0 -54
- package/studio-dist/server/chunks/nexus-schema-zeygY8OD.js +0 -11
- package/studio-dist/server/chunks/nexus-schema2-DP0Qd7CA.js +0 -444
- package/studio-dist/server/chunks/nexus-sqlite-BVNIpwc7.js +0 -36
- package/studio-dist/server/chunks/nexus-sqlite2-BBfY2xnY.js +0 -1103
- package/studio-dist/server/chunks/node-http-handler-CJI8kn7X.js +0 -386
- package/studio-dist/server/chunks/observe-Bo9veHGe.js +0 -47
- package/studio-dist/server/chunks/observe2-wzO0MaMY.js +0 -245
- package/studio-dist/server/chunks/observer-reflector-BwNOuq1d.js +0 -62
- package/studio-dist/server/chunks/observer-reflector2-ggtC1hmk.js +0 -478
- package/studio-dist/server/chunks/on-open-Wpcw7DV4.js +0 -740
- package/studio-dist/server/chunks/open-cleo-db--8sYNaYY.js +0 -70
- package/studio-dist/server/chunks/parseKnownFiles-Dg0pMFcT.js +0 -18
- package/studio-dist/server/chunks/parseUrl-qgGfl-Vh.js +0 -120
- package/studio-dist/server/chunks/paths-CV7S5-Zm.js +0 -30012
- package/studio-dist/server/chunks/patterns-lh5kn13I.js +0 -48
- package/studio-dist/server/chunks/patterns2-CzIcT-ai.js +0 -177
- package/studio-dist/server/chunks/pipeline-stage-IB_pOft-.js +0 -63
- package/studio-dist/server/chunks/prediction-D1lSGJ4c.js +0 -217
- package/studio-dist/server/chunks/premature-close-audit-VG09uAco.js +0 -53
- package/studio-dist/server/chunks/project-context-BjiqfEBi.js +0 -166
- package/studio-dist/server/chunks/provider-registry2-Cu7rAF0R.js +0 -35
- package/studio-dist/server/chunks/quality-feedback-CuCGEI6S.js +0 -371
- package/studio-dist/server/chunks/quality-scoring-CCPuRQmJ.js +0 -160
- package/studio-dist/server/chunks/query-ops-DCrjbZb9.js +0 -78
- package/studio-dist/server/chunks/query-promise-BkPmGPJy.js +0 -1257
- package/studio-dist/server/chunks/readFile-CxwXhymG.js +0 -31
- package/studio-dist/server/chunks/registry-CL2gN1zd.js +0 -27
- package/studio-dist/server/chunks/registry2-DoPYJnUW.js +0 -233
- package/studio-dist/server/chunks/registry3-BajEb-ll.js +0 -42
- package/studio-dist/server/chunks/registry4-DCqffZkT.js +0 -142
- package/studio-dist/server/chunks/retry-B3oEKYpp.js +0 -105
- package/studio-dist/server/chunks/role-executor-CC8BU54L.js +0 -25379
- package/studio-dist/server/chunks/role-resolver-D9QaDT0e.js +0 -6544
- package/studio-dist/server/chunks/role-resolver2-nkhzS1oy.js +0 -37
- package/studio-dist/server/chunks/rollup-CiefjN_Y.js +0 -194
- package/studio-dist/server/chunks/safety-data-accessor-CniDmGJO.js +0 -276
- package/studio-dist/server/chunks/service-connections-accessor-yBCdcgU-.js +0 -282
- package/studio-dist/server/chunks/session-factory-vbengc42.js +0 -96
- package/studio-dist/server/chunks/session-grade-BF4ZZtN_.js +0 -244
- package/studio-dist/server/chunks/session-journal-Bvey70Ur.js +0 -235
- package/studio-dist/server/chunks/session-narrative-BirZINSU.js +0 -304
- package/studio-dist/server/chunks/session-store--N_xHxUH.js +0 -557
- package/studio-dist/server/chunks/session-store2-DAM-eVTH.js +0 -43
- package/studio-dist/server/chunks/sessions-33DD4hkt.js +0 -2273
- package/studio-dist/server/chunks/sessions2-BHswKRDP.js +0 -50
- package/studio-dist/server/chunks/sigil-B-RznFXz.js +0 -33
- package/studio-dist/server/chunks/sigil2-jRMG5DuR.js +0 -47
- package/studio-dist/server/chunks/signin-BAsW3mM8.js +0 -644
- package/studio-dist/server/chunks/sleep-consolidation-BnSwXrvq.js +0 -823
- package/studio-dist/server/chunks/specialists-B_ZbpQlK.js +0 -441
- package/studio-dist/server/chunks/sqlite-Bm5LzbPs.js +0 -5977
- package/studio-dist/server/chunks/sqlite-backup-CFG1-b2e.js +0 -42
- package/studio-dist/server/chunks/sqlite-data-accessor-DD_RFX6r.js +0 -987
- package/studio-dist/server/chunks/sqlite-data-accessor2-CRmgNBnq.js +0 -44
- package/studio-dist/server/chunks/sqlite-native-BwlIqtbs.js +0 -42
- package/studio-dist/server/chunks/sqlite2-CUPut2fh.js +0 -42
- package/studio-dist/server/chunks/src2-DK8DKufK.js +0 -290
- package/studio-dist/server/chunks/src3-BJjf7XRG.js +0 -798
- package/studio-dist/server/chunks/src4-DNleK_t_.js +0 -28
- package/studio-dist/server/chunks/sso-oidc-eUvwseuL.js +0 -861
- package/studio-dist/server/chunks/storage-B9UA3BHR.js +0 -198
- package/studio-dist/server/chunks/sts-g7LDMLEd.js +0 -4655
- package/studio-dist/server/chunks/surprisal-CwTfWQi8.js +0 -224
- package/studio-dist/server/chunks/surprisal-tree-7dfHsuw1.js +0 -230
- package/studio-dist/server/chunks/system-resolver2-Bzhue_zQ.js +0 -53
- package/studio-dist/server/chunks/tasks-SHX7UPGY.js +0 -19694
- package/studio-dist/server/chunks/tasks-schema2-CTMoQKQy.js +0 -42
- package/studio-dist/server/chunks/temporal-supersession-DP4GPG_B.js +0 -298
- package/studio-dist/server/chunks/token-cAhAD9f9.js +0 -139
- package/studio-dist/server/chunks/token-util-D6drEz8_.js +0 -353
- package/studio-dist/server/chunks/token-util2-8UPSGvbb.js +0 -97
- package/studio-dist/server/chunks/transcript-scanner-kJWhWmlg.js +0 -53
- package/studio-dist/server/chunks/transformers.node-_xbxmK5p.js +0 -38475
- package/studio-dist/server/chunks/typed-query-l1D_QElt.js +0 -18
- package/studio-dist/server/chunks/unique-constraint-BZrrwgwc.js +0 -88
- package/studio-dist/server/chunks/update-B2YVBZG0.js +0 -1594
- package/studio-dist/server/chunks/user-profile-B61ZhVmC.js +0 -89
- package/studio-dist/server/chunks/utils-BPSZyajG.js +0 -1176
- package/studio-dist/server/chunks/validation-rules-CE27rtoF.js +0 -44
- package/studio-dist/server/chunks/zod-DsAeKNLm.js +0 -141
- /package/studio-dist/client/_app/immutable/chunks/{CQCxd1p9.js → B8WnZMYa.js} +0 -0
- /package/studio-dist/client/_app/immutable/chunks/{D13Quv9e2.js → B_0_YCYG.js} +0 -0
- /package/studio-dist/client/_app/immutable/chunks/{djL6V-tr.js → CqgtdAx_.js} +0 -0
- /package/studio-dist/client/_app/immutable/chunks/{_FU7h_8p2.js → KrUPZzXZ.js} +0 -0
|
@@ -1,1594 +0,0 @@
|
|
|
1
|
-
import { d as CleoError, E as ExitCode, n as isAllowedWorkGraphParentType, T as TERMINAL_TASK_STATUSES, c as getProjectRoot, o as resolveOrCwd, b as getLogger } from './paths-CV7S5-Zm.js';
|
|
2
|
-
import { g as getTaskAccessor } from './data-accessor-CWgVndbR.js';
|
|
3
|
-
import { w as wrapWithAgentSession } from './sessions-33DD4hkt.js';
|
|
4
|
-
import './branch-lock-Cq7zzmFK.js';
|
|
5
|
-
import { a as getNexusNativeDb } from './nexus-sqlite2-BBfY2xnY.js';
|
|
6
|
-
import { l as loadConfig, g as getRawConfigValue } from './config-DHj9CcFs.js';
|
|
7
|
-
import { t as typedAll } from './typed-query-l1D_QElt.js';
|
|
8
|
-
import { r as requireActiveSession, f as createAcceptanceEnforcement, v as validateTitle, h as validateStatus, n as normalizePriority, i as validateTaskType, j as validateSize, k as validateLabels, l as validatePipelineTransition, m as validateEpicStageAdvancement, o as findEpicAncestor, p as validateChildStageCeiling, q as resolveHierarchyPolicy, u as planAcUpdate, w as applyAcPlan, x as rebuildChildProjectionAc, y as trackBackgroundOp, z as isValidPipelineStage, A as isTerminalPipelineStage } from './tasks-SHX7UPGY.js';
|
|
9
|
-
import { f as findSagasGroupingTask, b as buildSagaAutoCloseEvidence } from './storage-B9UA3BHR.js';
|
|
10
|
-
import './session-store--N_xHxUH.js';
|
|
11
|
-
import { mkdirSync, appendFileSync } from 'node:fs';
|
|
12
|
-
import { join, dirname } from 'node:path';
|
|
13
|
-
import { mkdir, appendFile } from 'node:fs/promises';
|
|
14
|
-
|
|
15
|
-
//#region ../core/dist/tasks/ac-coverage-gate.js
|
|
16
|
-
/**
|
|
17
|
-
* AC-coverage gate — the load-bearing IVTR-closure piece.
|
|
18
|
-
*
|
|
19
|
-
* Runs inside `cleo complete <tid>` BEFORE the status flip and refuses to
|
|
20
|
-
* mark a task done when any acceptance criterion has zero
|
|
21
|
-
* `evidence_ac_bindings` rows pointing at it. Closes the rubber-stamp
|
|
22
|
-
* loophole that let workers complete tasks whose ACs were never tied to
|
|
23
|
-
* evidence.
|
|
24
|
-
*
|
|
25
|
-
* # Binding semantics
|
|
26
|
-
*
|
|
27
|
-
* An AC is "covered" when at least one of the following kinds of binding
|
|
28
|
-
* row exists for its `ac_id`:
|
|
29
|
-
* - `direct` — Worker's own evidence atom emitted by the owning task
|
|
30
|
-
* - `satisfies` — Cross-task atom via ADR-079-r2 `satisfies:<task>#<ac>`
|
|
31
|
-
* - `coverage` — Validator-computed transitive coverage marker
|
|
32
|
-
*
|
|
33
|
-
* All three counts contribute equally. Per ADR-079-r4 §3.
|
|
34
|
-
*
|
|
35
|
-
* # Override paths
|
|
36
|
-
*
|
|
37
|
-
* The gate is hard: programmatic evidence is the canonical satisfaction
|
|
38
|
-
* path. Two audited override paths exist for legitimate exceptions:
|
|
39
|
-
* 1. `--waive-ac "<csv>" --waive-reason "<text>"` — per-AC waiver
|
|
40
|
-
* logged to `.cleo/audit/ac-waiver.jsonl`. Waivers are scoped to a
|
|
41
|
-
* single `cleo complete` call; the unsatisfied AC list is
|
|
42
|
-
* recomputed AFTER applying the waiver set so partially-waived
|
|
43
|
-
* tasks fail when any AC is left unaddressed.
|
|
44
|
-
* 2. `CLEO_OWNER_OVERRIDE=1` (+ `CLEO_OWNER_OVERRIDE_REASON=<text>`)
|
|
45
|
-
* — full bypass logged to `.cleo/audit/force-bypass.jsonl` per
|
|
46
|
-
* existing convention (ADR-051 §6.2).
|
|
47
|
-
*
|
|
48
|
-
* # Tasks with zero ACs
|
|
49
|
-
*
|
|
50
|
-
* The gate is a no-op for tasks that declare zero acceptance criteria
|
|
51
|
-
* — nothing to satisfy means nothing to enforce. Operators that want
|
|
52
|
-
* "every task must have ACs" should turn on the existing
|
|
53
|
-
* `enforcement.acceptance.mode='block'` config knob, which fires
|
|
54
|
-
* earlier in the pipeline.
|
|
55
|
-
*
|
|
56
|
-
* # Transactional safety
|
|
57
|
-
*
|
|
58
|
-
* The coverage check is run as a pre-condition inside the caller's
|
|
59
|
-
* transaction context, BEFORE any state mutation. The DB read uses the
|
|
60
|
-
* same accessor handle as the subsequent writes so SQLite snapshot
|
|
61
|
-
* isolation pins the AC + binding rows for the duration of the
|
|
62
|
-
* completion call.
|
|
63
|
-
*
|
|
64
|
-
* @task T10509
|
|
65
|
-
* @saga T10377 (SG-IVTR-AC-BINDING)
|
|
66
|
-
* @epic T10381 (E-AC-MIGRATION)
|
|
67
|
-
* @adr ADR-079-r4
|
|
68
|
-
*/
|
|
69
|
-
/**
|
|
70
|
-
* Compute coverage for a task. Returns `{ok:true}` when every AC has
|
|
71
|
-
* at least one binding OR the task declared zero ACs; otherwise
|
|
72
|
-
* `{ok:false}` with the offending AC rows.
|
|
73
|
-
*
|
|
74
|
-
* @param taskId - The task being completed.
|
|
75
|
-
* @param accessor - DataAccessor used for the AC + binding reads.
|
|
76
|
-
* @returns Coverage outcome.
|
|
77
|
-
*/
|
|
78
|
-
async function computeAcCoverage(taskId, accessor) {
|
|
79
|
-
const acRows = await accessor.getAcRows(taskId);
|
|
80
|
-
if (acRows.length === 0) return { ok: true };
|
|
81
|
-
const acIds = acRows.map((r) => r.id);
|
|
82
|
-
const bindings = await accessor.getAcBindings(acIds);
|
|
83
|
-
const covered = /* @__PURE__ */ new Set();
|
|
84
|
-
for (const b of bindings) covered.add(b.acId);
|
|
85
|
-
const unsatisfied = acRows.filter((r) => !covered.has(r.id)).map((r) => ({
|
|
86
|
-
acId: r.id,
|
|
87
|
-
alias: `AC${r.ordinal}`,
|
|
88
|
-
text: r.text
|
|
89
|
-
}));
|
|
90
|
-
if (unsatisfied.length === 0) return { ok: true };
|
|
91
|
-
return {
|
|
92
|
-
ok: false,
|
|
93
|
-
unsatisfied
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Resolve the comma-separated `--waive-ac` token list against the
|
|
98
|
-
* task's AC rows. Tokens may be:
|
|
99
|
-
* - A canonical UUIDv4 (`task_acceptance_criteria.id`)
|
|
100
|
-
* - A display alias (`AC<ordinal>`)
|
|
101
|
-
*
|
|
102
|
-
* Tokens that resolve to neither are surfaced on `unresolved` so the
|
|
103
|
-
* caller can warn — they are NOT silently dropped, but they also do
|
|
104
|
-
* not fail the gate by themselves. The caller decides.
|
|
105
|
-
*
|
|
106
|
-
* @param waiveCsv - Comma-separated token list (may be empty / undefined).
|
|
107
|
-
* @param acRows - The task's AC rows (from `accessor.getAcRows`).
|
|
108
|
-
* @returns Resolved waiver descriptor.
|
|
109
|
-
*/
|
|
110
|
-
function resolveWaivers(waiveCsv, acRows) {
|
|
111
|
-
if (waiveCsv === void 0 || waiveCsv.trim().length === 0) return {
|
|
112
|
-
acIds: [],
|
|
113
|
-
aliases: [],
|
|
114
|
-
texts: [],
|
|
115
|
-
unresolved: []
|
|
116
|
-
};
|
|
117
|
-
const tokens = waiveCsv.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
118
|
-
const byUuid = /* @__PURE__ */ new Map();
|
|
119
|
-
const byAlias = /* @__PURE__ */ new Map();
|
|
120
|
-
for (const row of acRows) {
|
|
121
|
-
byUuid.set(row.id.toLowerCase(), row);
|
|
122
|
-
byAlias.set(`AC${row.ordinal}`.toLowerCase(), row);
|
|
123
|
-
}
|
|
124
|
-
const acIds = [];
|
|
125
|
-
const aliases = [];
|
|
126
|
-
const texts = [];
|
|
127
|
-
const unresolved = [];
|
|
128
|
-
const seen = /* @__PURE__ */ new Set();
|
|
129
|
-
for (const token of tokens) {
|
|
130
|
-
const key = token.toLowerCase();
|
|
131
|
-
const row = byUuid.get(key) ?? byAlias.get(key);
|
|
132
|
-
if (row === void 0) {
|
|
133
|
-
unresolved.push(token);
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
if (seen.has(row.id)) continue;
|
|
137
|
-
seen.add(row.id);
|
|
138
|
-
acIds.push(row.id);
|
|
139
|
-
aliases.push(`AC${row.ordinal}`);
|
|
140
|
-
texts.push(row.text);
|
|
141
|
-
}
|
|
142
|
-
return {
|
|
143
|
-
acIds,
|
|
144
|
-
aliases,
|
|
145
|
-
texts,
|
|
146
|
-
unresolved
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Subtract a waiver set from an unsatisfied list. Returns the residual
|
|
151
|
-
* unsatisfied ACs. When the residual is empty, the gate passes; when
|
|
152
|
-
* non-empty the caller surfaces `E_AC_COVERAGE_INCOMPLETE` with the
|
|
153
|
-
* residual.
|
|
154
|
-
*
|
|
155
|
-
* @param unsatisfied - From {@link computeAcCoverage}.
|
|
156
|
-
* @param waivedAcIds - Set of canonical AC UUIDs the operator waived.
|
|
157
|
-
* @returns Residual unsatisfied list (ACs not covered AND not waived).
|
|
158
|
-
*/
|
|
159
|
-
function applyWaivers(unsatisfied, waivedAcIds) {
|
|
160
|
-
if (waivedAcIds.size === 0) return [...unsatisfied];
|
|
161
|
-
return unsatisfied.filter((u) => !waivedAcIds.has(u.acId));
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Append a single waiver entry to `.cleo/audit/ac-waiver.jsonl`. Creates
|
|
165
|
-
* the audit directory on first use. Errors propagate — failure to write
|
|
166
|
-
* the audit row MUST block the completion since the audit trail is the
|
|
167
|
-
* forensic guarantee that backs the override.
|
|
168
|
-
*
|
|
169
|
-
* @param entry - Pre-built audit entry.
|
|
170
|
-
* @param projectRoot - Absolute path to the project root.
|
|
171
|
-
*/
|
|
172
|
-
async function appendAcWaiverAudit(entry, projectRoot) {
|
|
173
|
-
const auditDir = join(projectRoot, ".cleo", "audit");
|
|
174
|
-
await mkdir(auditDir, { recursive: true });
|
|
175
|
-
await appendFile(join(auditDir, "ac-waiver.jsonl"), `${JSON.stringify(entry)}\n`, { encoding: "utf8" });
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Append an AC-coverage force-bypass entry to `.cleo/audit/force-bypass.jsonl`.
|
|
179
|
-
* Re-uses the canonical force-bypass log per ADR-051 §6.2; the `kind`
|
|
180
|
-
* discriminator on the entry distinguishes AC-coverage bypasses from
|
|
181
|
-
* existing evidence-gate bypasses.
|
|
182
|
-
*
|
|
183
|
-
* Errors propagate — like {@link appendAcWaiverAudit} the audit trail
|
|
184
|
-
* is load-bearing.
|
|
185
|
-
*
|
|
186
|
-
* @param entry - Pre-built audit entry.
|
|
187
|
-
* @param projectRoot - Absolute path to the project root.
|
|
188
|
-
*/
|
|
189
|
-
async function appendAcCoverageForceBypass(entry, projectRoot) {
|
|
190
|
-
const auditDir = join(projectRoot, ".cleo", "audit");
|
|
191
|
-
await mkdir(auditDir, { recursive: true });
|
|
192
|
-
await appendFile(join(auditDir, "force-bypass.jsonl"), `${JSON.stringify(entry)}\n`, { encoding: "utf8" });
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Inspect the runtime env for the canonical `CLEO_OWNER_OVERRIDE=1`
|
|
196
|
-
* + `CLEO_OWNER_OVERRIDE_REASON=<text>` pair. Returns the reason when
|
|
197
|
-
* BOTH are present; returns `null` when override is off or the reason
|
|
198
|
-
* is missing/blank.
|
|
199
|
-
*
|
|
200
|
-
* Centralised here so the gate, the audit writer, and the dispatch
|
|
201
|
-
* layer agree on the exact semantics. Mirrors the convention used by
|
|
202
|
-
* `gate-audit.ts`.
|
|
203
|
-
*/
|
|
204
|
-
function readOwnerOverride(env = process.env) {
|
|
205
|
-
const flag = env["CLEO_OWNER_OVERRIDE"];
|
|
206
|
-
if (flag !== "1" && flag !== "true") return null;
|
|
207
|
-
const reason = env["CLEO_OWNER_OVERRIDE_REASON"];
|
|
208
|
-
if (typeof reason !== "string") return null;
|
|
209
|
-
const trimmed = reason.trim();
|
|
210
|
-
if (trimmed.length === 0) return null;
|
|
211
|
-
return trimmed;
|
|
212
|
-
}
|
|
213
|
-
//#endregion
|
|
214
|
-
//#region ../core/dist/tasks/coordination-parent.js
|
|
215
|
-
/**
|
|
216
|
-
* Coordination parent detection and rollup evidence synthesis.
|
|
217
|
-
*
|
|
218
|
-
* A "coordination parent" is a task that:
|
|
219
|
-
* 1. Has no files of its own (`files` is absent, null, or empty).
|
|
220
|
-
* 2. Has at least one registered child.
|
|
221
|
-
* 3. Has `noAutoComplete` unset or `false`.
|
|
222
|
-
*
|
|
223
|
-
* These tasks act purely as scope containers — their scope was delivered
|
|
224
|
-
* entirely by their children (e.g. T1916/T1918/T1919 in T1910). Before T9040,
|
|
225
|
-
* they required manual evidence atoms and stayed `pending` forever unless the
|
|
226
|
-
* orchestrator performed an expensive workaround.
|
|
227
|
-
*
|
|
228
|
-
* This module provides:
|
|
229
|
-
* - {@link isCoordinationParent} — predicate used by the completion path.
|
|
230
|
-
* - {@link buildRollupEvidence} — synthesizes verification evidence by
|
|
231
|
-
* aggregating children's gate state.
|
|
232
|
-
*
|
|
233
|
-
* @task T9040
|
|
234
|
-
*/
|
|
235
|
-
/**
|
|
236
|
-
* Determine whether a task is a "coordination parent".
|
|
237
|
-
*
|
|
238
|
-
* A coordination parent has NO own implementation files but DOES own children.
|
|
239
|
-
* This pattern arises when a task was added as a scope container for a wave of
|
|
240
|
-
* subtasks, with no code changes on the parent itself.
|
|
241
|
-
*
|
|
242
|
-
* Rules:
|
|
243
|
-
* - `task.files` is absent, `null`, or an empty array.
|
|
244
|
-
* - `childrenCount > 0` (caller must pass the actual children length).
|
|
245
|
-
* - `task.noAutoComplete` is NOT `true` (respects the existing opt-out flag).
|
|
246
|
-
*
|
|
247
|
-
* Both epic and non-epic tasks can be coordination parents. Epics already have
|
|
248
|
-
* their own rollup path in `completeTask`; this helper is primarily used for
|
|
249
|
-
* `type='task'` nodes that act as group containers within a larger epic.
|
|
250
|
-
*
|
|
251
|
-
* @param task - The task to test.
|
|
252
|
-
* @param childrenCount - Number of registered children for the task.
|
|
253
|
-
* @returns `true` when the task is a coordination parent.
|
|
254
|
-
*
|
|
255
|
-
* @task T9040
|
|
256
|
-
*/
|
|
257
|
-
function isCoordinationParent(task, childrenCount) {
|
|
258
|
-
if (task.noAutoComplete === true) return false;
|
|
259
|
-
if (childrenCount === 0) return false;
|
|
260
|
-
return !(Array.isArray(task.files) && task.files.length > 0);
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Standard verification gates synthesized during parent rollup.
|
|
264
|
-
*
|
|
265
|
-
* Order mirrors the canonical gate sequence from the verification module.
|
|
266
|
-
*/
|
|
267
|
-
var ROLLUP_GATES = [
|
|
268
|
-
"implemented",
|
|
269
|
-
"testsPassed",
|
|
270
|
-
"qaPassed",
|
|
271
|
-
"cleanupDone",
|
|
272
|
-
"securityPassed",
|
|
273
|
-
"documented"
|
|
274
|
-
];
|
|
275
|
-
/**
|
|
276
|
-
* Synthesize a {@link TaskVerification} for a coordination parent by
|
|
277
|
-
* aggregating the verification state of all non-cancelled children.
|
|
278
|
-
*
|
|
279
|
-
* Gate synthesis rules:
|
|
280
|
-
* - `implemented` — always `true` (children carried the scope).
|
|
281
|
-
* - `testsPassed`, `qaPassed`, `cleanupDone`, `securityPassed`, `documented`
|
|
282
|
-
* — `true` when ALL non-cancelled children have the gate set to `true`, OR
|
|
283
|
-
* when no child has any verification metadata (best-effort rollup for
|
|
284
|
-
* projects without strict enforcement).
|
|
285
|
-
* - `passed` — always `true` for a coordination parent whose children are all
|
|
286
|
-
* done/cancelled (the caller has already confirmed terminal state).
|
|
287
|
-
*
|
|
288
|
-
* The `evidence` block on each gate carries a `note` atom explaining that this
|
|
289
|
-
* is a synthesized rollup, and a second `note` atom referencing the child IDs
|
|
290
|
-
* that delivered the scope.
|
|
291
|
-
*
|
|
292
|
-
* @param parentId - ID of the coordination parent (used in evidence notes).
|
|
293
|
-
* @param children - All registered children of the parent (including cancelled).
|
|
294
|
-
* @returns A fully synthesized {@link TaskVerification} ready for upsert.
|
|
295
|
-
*
|
|
296
|
-
* @task T9040
|
|
297
|
-
*/
|
|
298
|
-
function buildRollupEvidence(parentId, children) {
|
|
299
|
-
const nonCancelled = children.filter((c) => c.status !== "cancelled");
|
|
300
|
-
const childIds = nonCancelled.map((c) => c.id).join(",");
|
|
301
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
302
|
-
/**
|
|
303
|
-
* Return true when the given gate passes for ALL non-cancelled children.
|
|
304
|
-
* Children without any verification record are treated as passing so that
|
|
305
|
-
* coordination parents in non-enforcement projects can still roll up.
|
|
306
|
-
*/
|
|
307
|
-
function childrenPassGate(gate) {
|
|
308
|
-
if (nonCancelled.length === 0) return true;
|
|
309
|
-
return nonCancelled.every((c) => {
|
|
310
|
-
if (!c.verification) return true;
|
|
311
|
-
return c.verification.gates?.[gate] === true;
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Build a single gate's evidence record with two note atoms:
|
|
316
|
-
* 1. A note describing the rollup provenance.
|
|
317
|
-
* 2. A note listing the child task IDs that delivered this gate.
|
|
318
|
-
*/
|
|
319
|
-
function makeGateEvidence(gate, passed) {
|
|
320
|
-
return {
|
|
321
|
-
atoms: [{
|
|
322
|
-
kind: "note",
|
|
323
|
-
note: `coordination-rollup:${parentId}:${gate}=${String(passed)}`
|
|
324
|
-
}, {
|
|
325
|
-
kind: "note",
|
|
326
|
-
note: `linked_tasks:${childIds}`
|
|
327
|
-
}],
|
|
328
|
-
capturedAt: now,
|
|
329
|
-
capturedBy: "system:coordination-rollup"
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
const gates = { implemented: true };
|
|
333
|
-
const evidence = {};
|
|
334
|
-
evidence.implemented = makeGateEvidence("implemented", true);
|
|
335
|
-
for (const gate of ROLLUP_GATES) {
|
|
336
|
-
if (gate === "implemented") continue;
|
|
337
|
-
const passed = childrenPassGate(gate);
|
|
338
|
-
gates[gate] = passed;
|
|
339
|
-
evidence[gate] = makeGateEvidence(gate, passed);
|
|
340
|
-
}
|
|
341
|
-
return {
|
|
342
|
-
round: 1,
|
|
343
|
-
passed: true,
|
|
344
|
-
gates: {
|
|
345
|
-
implemented: true,
|
|
346
|
-
testsPassed: gates.testsPassed ?? false,
|
|
347
|
-
qaPassed: gates.qaPassed ?? false,
|
|
348
|
-
cleanupDone: gates.cleanupDone ?? false,
|
|
349
|
-
securityPassed: gates.securityPassed ?? false,
|
|
350
|
-
documented: gates.documented ?? false
|
|
351
|
-
},
|
|
352
|
-
evidence,
|
|
353
|
-
lastAgent: null,
|
|
354
|
-
lastUpdated: now,
|
|
355
|
-
failureLog: [],
|
|
356
|
-
initializedAt: now
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
//#endregion
|
|
360
|
-
//#region ../core/dist/tasks/nexus-impact-gate.js
|
|
361
|
-
/**
|
|
362
|
-
* IVTR Breaking-Change Gate — blocks completion when task touches CRITICAL-risk symbols.
|
|
363
|
-
*
|
|
364
|
-
* Implements EP3-T8 from T1042 living-brain decomposition. The gate reads the task's
|
|
365
|
-
* `files` field, queries nexus for symbols in those files, calls `reasonImpactOfChange()`
|
|
366
|
-
* for each symbol, and fails if any symbol returns `mergedRiskScore === 'CRITICAL'`.
|
|
367
|
-
*
|
|
368
|
-
* Gate is OPT-IN via `CLEO_NEXUS_IMPACT_GATE=1` env var to prevent surprise breakage.
|
|
369
|
-
*
|
|
370
|
-
* @task T1073
|
|
371
|
-
* @epic T1042
|
|
372
|
-
*/
|
|
373
|
-
/**
|
|
374
|
-
* Validate the nexusImpact gate for a task.
|
|
375
|
-
*
|
|
376
|
-
* If `CLEO_NEXUS_IMPACT_GATE` env var is not set to '1', returns passed=true
|
|
377
|
-
* with a note that the gate is disabled (prevents surprise breakage).
|
|
378
|
-
*
|
|
379
|
-
* When enabled, reads the task's `files` array, queries nexus for all symbols
|
|
380
|
-
* in those files, and calls `reasonImpactOfChange()` for each. If any symbol
|
|
381
|
-
* returns `mergedRiskScore === 'CRITICAL'`, the gate fails with a list of
|
|
382
|
-
* critical symbols.
|
|
383
|
-
*
|
|
384
|
-
* @param task - The task to validate
|
|
385
|
-
* @param projectRoot - Absolute path to project root
|
|
386
|
-
* @returns Gate result with pass/fail status and evidence
|
|
387
|
-
*/
|
|
388
|
-
async function validateNexusImpactGate(task, projectRoot) {
|
|
389
|
-
if (!(process.env.CLEO_NEXUS_IMPACT_GATE === "1")) return {
|
|
390
|
-
passed: true,
|
|
391
|
-
narrative: "CLEO_NEXUS_IMPACT_GATE is disabled (gate skipped, set env var to 1 to enable)"
|
|
392
|
-
};
|
|
393
|
-
const filesToCheck = task.files ?? [];
|
|
394
|
-
if (filesToCheck.length === 0) return {
|
|
395
|
-
passed: true,
|
|
396
|
-
narrative: "No files touched in task.files (no impact analysis needed)"
|
|
397
|
-
};
|
|
398
|
-
let symbolsInFiles = [];
|
|
399
|
-
try {
|
|
400
|
-
const nexusNative = getNexusNativeDb();
|
|
401
|
-
if (nexusNative) {
|
|
402
|
-
const placeholders = filesToCheck.map(() => "?").join(", ");
|
|
403
|
-
symbolsInFiles = typedAll(nexusNative.prepare(`SELECT id, name, file_path
|
|
404
|
-
FROM nexus_nodes
|
|
405
|
-
WHERE file_path IN (${placeholders}) AND kind NOT IN ('folder', 'community', 'process')
|
|
406
|
-
ORDER BY file_path, name`), ...filesToCheck);
|
|
407
|
-
}
|
|
408
|
-
} catch (err) {
|
|
409
|
-
console.warn("[nexus-impact-gate] nexus symbol lookup failed:", err instanceof Error ? err.message : String(err));
|
|
410
|
-
return {
|
|
411
|
-
passed: true,
|
|
412
|
-
narrative: "nexus symbol lookup failed; gate disabled (inspect error logs for details)"
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
if (symbolsInFiles.length === 0) return {
|
|
416
|
-
passed: true,
|
|
417
|
-
narrative: `No symbols found in touched files (${filesToCheck.length} files checked, 0 symbols)`
|
|
418
|
-
};
|
|
419
|
-
const criticalSymbols = [];
|
|
420
|
-
for (const symbol of symbolsInFiles) {
|
|
421
|
-
let impact;
|
|
422
|
-
try {
|
|
423
|
-
const { reasonImpactOfChange } = await import('./living-brain2-j0B_Ir8j.js');
|
|
424
|
-
impact = await reasonImpactOfChange(symbol.id, projectRoot);
|
|
425
|
-
} catch (err) {
|
|
426
|
-
console.warn(`[nexus-impact-gate] reasonImpactOfChange failed for ${symbol.id}:`, err instanceof Error ? err.message : String(err));
|
|
427
|
-
continue;
|
|
428
|
-
}
|
|
429
|
-
if (impact.mergedRiskScore === "CRITICAL") criticalSymbols.push({
|
|
430
|
-
symbolId: symbol.id,
|
|
431
|
-
symbolName: symbol.name,
|
|
432
|
-
filePath: symbol.file_path,
|
|
433
|
-
mergedRiskScore: impact.mergedRiskScore,
|
|
434
|
-
narrative: impact.narrative
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
if (criticalSymbols.length === 0) return {
|
|
438
|
-
passed: true,
|
|
439
|
-
narrative: `All ${symbolsInFiles.length} symbols have acceptable risk levels (no CRITICAL)`
|
|
440
|
-
};
|
|
441
|
-
const symbolList = criticalSymbols.map((s) => `${s.symbolName}(${s.symbolId})`).join(", ");
|
|
442
|
-
return {
|
|
443
|
-
passed: false,
|
|
444
|
-
exitCode: ExitCode.NEXUS_IMPACT_CRITICAL,
|
|
445
|
-
error: `Task ${task.id} touches ${criticalSymbols.length} CRITICAL-risk symbol${criticalSymbols.length !== 1 ? "s" : ""}: ${symbolList}. Use --acknowledge-risk "<reason>" to bypass.`,
|
|
446
|
-
criticalSymbols,
|
|
447
|
-
narrative: `CRITICAL impact detected on ${criticalSymbols.length} symbol${criticalSymbols.length !== 1 ? "s" : ""}. ${symbolList}`
|
|
448
|
-
};
|
|
449
|
-
}
|
|
450
|
-
//#endregion
|
|
451
|
-
//#region ../core/dist/tasks/complete.js
|
|
452
|
-
/**
|
|
453
|
-
* Task completion logic.
|
|
454
|
-
* @task T4461
|
|
455
|
-
* @epic T4454
|
|
456
|
-
*/
|
|
457
|
-
/**
|
|
458
|
-
* IVTR execution stages — tasks in these stages auto-advance to 'release'
|
|
459
|
-
* when marked complete (cleo complete TXXX). T719.
|
|
460
|
-
*
|
|
461
|
-
* Historical note: prior to T871 this set drove the only pipeline-stage
|
|
462
|
-
* side-effect of `cleo complete`. T871 adds a second (always-fires) step
|
|
463
|
-
* that sets `pipelineStage='contribution'` so status and pipeline_stage
|
|
464
|
-
* stay in sync — the Studio pipeline DONE column depends on this.
|
|
465
|
-
*/
|
|
466
|
-
var EXECUTION_STAGES_FOR_RELEASE = new Set([
|
|
467
|
-
"implementation",
|
|
468
|
-
"validation",
|
|
469
|
-
"testing"
|
|
470
|
-
]);
|
|
471
|
-
var DEFAULT_VERIFICATION_REQUIRED_GATES = [
|
|
472
|
-
"implemented",
|
|
473
|
-
"testsPassed",
|
|
474
|
-
"qaPassed",
|
|
475
|
-
"securityPassed",
|
|
476
|
-
"documented"
|
|
477
|
-
];
|
|
478
|
-
var VERIFICATION_GATES = new Set([
|
|
479
|
-
"implemented",
|
|
480
|
-
"testsPassed",
|
|
481
|
-
"qaPassed",
|
|
482
|
-
"cleanupDone",
|
|
483
|
-
"securityPassed",
|
|
484
|
-
"documented"
|
|
485
|
-
]);
|
|
486
|
-
function isVerificationGate(value) {
|
|
487
|
-
return VERIFICATION_GATES.has(value);
|
|
488
|
-
}
|
|
489
|
-
async function loadCompletionEnforcement(cwd) {
|
|
490
|
-
const isTest = !!process.env.VITEST;
|
|
491
|
-
const config = await loadConfig(cwd);
|
|
492
|
-
const acceptance = config.enforcement?.acceptance;
|
|
493
|
-
const verificationCfg = config.verification;
|
|
494
|
-
const acceptanceMode = acceptance?.mode ?? (isTest ? "off" : "block");
|
|
495
|
-
const acceptanceRequiredForPriorities = acceptance?.requiredForPriorities ?? (isTest ? [] : [
|
|
496
|
-
"critical",
|
|
497
|
-
"high",
|
|
498
|
-
"medium",
|
|
499
|
-
"low"
|
|
500
|
-
]);
|
|
501
|
-
const rawVerificationEnabled = await getRawConfigValue("verification.enabled", cwd);
|
|
502
|
-
return {
|
|
503
|
-
acceptanceMode,
|
|
504
|
-
acceptanceRequiredForPriorities,
|
|
505
|
-
verificationEnabled: rawVerificationEnabled !== void 0 ? rawVerificationEnabled : !isTest,
|
|
506
|
-
verificationRequiredGates: (verificationCfg?.requiredGates ?? []).filter(isVerificationGate).length > 0 ? (verificationCfg?.requiredGates ?? []).filter(isVerificationGate) : DEFAULT_VERIFICATION_REQUIRED_GATES,
|
|
507
|
-
verificationMaxRounds: verificationCfg?.maxRounds ?? 5,
|
|
508
|
-
lifecycleMode: config.lifecycle?.mode ?? (isTest ? "off" : "strict")
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Check whether an epic has sufficient evidence to complete.
|
|
513
|
-
*
|
|
514
|
-
* An epic satisfies the evidence requirement if ANY of the following is true:
|
|
515
|
-
* 1. It has at least one direct evidence atom on any verification gate.
|
|
516
|
-
* 2. All of its children (excluding cancelled) have `status='done'` AND
|
|
517
|
-
* `verification.passed=true`.
|
|
518
|
-
*
|
|
519
|
-
* Returns `true` when the epic may proceed; `false` when it must be rejected.
|
|
520
|
-
*
|
|
521
|
-
* @param task - The epic task to check.
|
|
522
|
-
* @param acc - Data accessor used to load children.
|
|
523
|
-
* @returns `true` when evidence is sufficient; `false` otherwise.
|
|
524
|
-
* @task T1404
|
|
525
|
-
*/
|
|
526
|
-
async function verifyEpicHasEvidence(task, acc) {
|
|
527
|
-
if (task.verification?.evidence) {
|
|
528
|
-
const gates = task.verification.evidence;
|
|
529
|
-
if (Object.values(gates).some((gateEvidence) => gateEvidence != null && gateEvidence.atoms.length > 0)) return true;
|
|
530
|
-
}
|
|
531
|
-
const nonCancelled = (await acc.getChildren(task.id)).filter((c) => c.status !== "cancelled");
|
|
532
|
-
if (nonCancelled.length > 0 && nonCancelled.every((c) => c.status === "done" && c.verification?.passed === true)) return true;
|
|
533
|
-
return false;
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Resolve the absolute project root to write audit logs to. The gate
|
|
537
|
-
* call site has `cwd` as an optional parameter; we re-use the same
|
|
538
|
-
* canonical fallback the rest of `completeTask` uses ({@link getProjectRoot}).
|
|
539
|
-
*
|
|
540
|
-
* @internal
|
|
541
|
-
* @task T10509
|
|
542
|
-
*/
|
|
543
|
-
function projectRootForGate(cwd) {
|
|
544
|
-
return cwd ?? getProjectRoot();
|
|
545
|
-
}
|
|
546
|
-
async function enforceAcCoverageGate(options, projectRoot, accessor) {
|
|
547
|
-
const waiveCsv = options.waiveAc?.trim();
|
|
548
|
-
if (waiveCsv !== void 0 && waiveCsv.length > 0) {
|
|
549
|
-
if ((options.waiveReason?.trim() ?? "").length === 0) throw new CleoError(ExitCode.AC_COVERAGE_INCOMPLETE, "--waive-ac requires --waive-reason \"<text>\" — the reason is the audit anchor.", {
|
|
550
|
-
fix: "Re-run with --waive-reason \"<justification>\" (the reason is captured in .cleo/audit/ac-waiver.jsonl).",
|
|
551
|
-
details: {
|
|
552
|
-
field: "waiveReason",
|
|
553
|
-
codeName: "E_AC_COVERAGE_INCOMPLETE",
|
|
554
|
-
missingFlag: "waiveReason"
|
|
555
|
-
}
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
const coverage = await computeAcCoverage(options.taskId, accessor);
|
|
559
|
-
if (coverage.ok) return;
|
|
560
|
-
const ownerReason = readOwnerOverride();
|
|
561
|
-
if (ownerReason !== null) {
|
|
562
|
-
await appendAcCoverageForceBypass({
|
|
563
|
-
kind: "ac-coverage",
|
|
564
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
565
|
-
taskId: options.taskId,
|
|
566
|
-
reason: ownerReason,
|
|
567
|
-
actor: process.env["CLEO_AGENT_ID"] ?? "cleo",
|
|
568
|
-
unsatisfied: coverage.unsatisfied
|
|
569
|
-
}, projectRoot);
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
let residual = coverage.unsatisfied;
|
|
573
|
-
let unresolvedTokens = [];
|
|
574
|
-
if (waiveCsv !== void 0 && waiveCsv.length > 0) {
|
|
575
|
-
const resolved = resolveWaivers(waiveCsv, await accessor.getAcRows(options.taskId));
|
|
576
|
-
unresolvedTokens = resolved.unresolved;
|
|
577
|
-
residual = applyWaivers(coverage.unsatisfied, new Set(resolved.acIds));
|
|
578
|
-
await appendAcWaiverAudit({
|
|
579
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
580
|
-
taskId: options.taskId,
|
|
581
|
-
waivedAcs: resolved.acIds,
|
|
582
|
-
waivedAliases: resolved.aliases,
|
|
583
|
-
reason: (options.waiveReason ?? "").trim(),
|
|
584
|
-
actor: process.env["CLEO_AGENT_ID"] ?? "cleo",
|
|
585
|
-
unresolvedTokens
|
|
586
|
-
}, projectRoot);
|
|
587
|
-
if (residual.length === 0 && unresolvedTokens.length === 0) return;
|
|
588
|
-
}
|
|
589
|
-
const offenderList = residual.map((u) => `${u.alias} (${u.acId})`).join(", ");
|
|
590
|
-
const unresolvedHint = unresolvedTokens.length > 0 ? ` Unresolved waive tokens: ${unresolvedTokens.join(", ")}.` : "";
|
|
591
|
-
throw new CleoError(ExitCode.AC_COVERAGE_INCOMPLETE, `Task ${options.taskId} cannot complete — ${residual.length} acceptance criterion/criteria have no evidence bindings: ${offenderList}.${unresolvedHint}`, {
|
|
592
|
-
fix: "Either (1) record evidence via `cleo verify <taskId> --gate … --evidence …` so a binding row is written, (2) pass `--waive-ac \"<csv>\" --waive-reason \"<text>\"` to record an audited waiver, or (3) set CLEO_OWNER_OVERRIDE=1 + CLEO_OWNER_OVERRIDE_REASON=<text> for a full bypass.",
|
|
593
|
-
details: {
|
|
594
|
-
field: "acceptance",
|
|
595
|
-
codeName: "E_AC_COVERAGE_INCOMPLETE",
|
|
596
|
-
unsatisfied: residual,
|
|
597
|
-
unresolvedTokens
|
|
598
|
-
}
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Execute the task-completion critical section under the tasks DB write lock.
|
|
603
|
-
*
|
|
604
|
-
* The concrete SQLite accessor backs `transaction()` with `BEGIN IMMEDIATE` at
|
|
605
|
-
* the outermost boundary, so the AC completion gate and status/autoclose writes
|
|
606
|
-
* run in one atomic write transaction instead of validating on a stale read
|
|
607
|
-
* snapshot and flipping `status='done'` later.
|
|
608
|
-
*
|
|
609
|
-
* @task T10595
|
|
610
|
-
*/
|
|
611
|
-
async function withTaskWriteTransaction(accessor, fn) {
|
|
612
|
-
return accessor.transaction(fn);
|
|
613
|
-
}
|
|
614
|
-
/**
|
|
615
|
-
* Complete a task by ID.
|
|
616
|
-
* Handles dependency checking and optional auto-completion of epics.
|
|
617
|
-
* @task T4461
|
|
618
|
-
*/
|
|
619
|
-
async function completeTask(options, cwd, accessor) {
|
|
620
|
-
const acc = accessor ?? await getTaskAccessor(cwd);
|
|
621
|
-
const task = await acc.loadSingleTask(options.taskId);
|
|
622
|
-
if (!task) throw new CleoError(ExitCode.NOT_FOUND, `Task not found: ${options.taskId}`, { fix: `Use 'cleo find "${options.taskId}"' to search` });
|
|
623
|
-
if (task.status === "done") return {
|
|
624
|
-
task,
|
|
625
|
-
alreadyCompleted: true
|
|
626
|
-
};
|
|
627
|
-
await requireActiveSession("tasks.complete", cwd, "Verification gates already recorded via cleo verify are preserved — do NOT re-verify them. Recovery: start a session, then re-run this cleo complete command.");
|
|
628
|
-
const enforcement = await loadCompletionEnforcement(cwd);
|
|
629
|
-
if (task.depends?.length) {
|
|
630
|
-
const unresolvedDeps = (await acc.loadTasks(task.depends)).filter((d) => !TERMINAL_TASK_STATUSES.has(d.status)).map((d) => ({
|
|
631
|
-
id: d.id,
|
|
632
|
-
status: d.status
|
|
633
|
-
}));
|
|
634
|
-
if (unresolvedDeps.length > 0) {
|
|
635
|
-
const waiverReason = options.waiveDependsReason?.trim();
|
|
636
|
-
if (!waiverReason) {
|
|
637
|
-
const offenders = unresolvedDeps.map((d) => `${d.id} (${d.status})`).join(", ");
|
|
638
|
-
throw new CleoError(ExitCode.DEPENDENCY_ERROR, `Task ${options.taskId} has unresolved dependencies: ${offenders}`, {
|
|
639
|
-
fix: `Complete the dependencies first (${unresolvedDeps.map((d) => `cleo complete ${d.id}`).join(", ")}), OR — if the edge is stale/over-specified and this task's own work is done — drop it with 'cleo update ${options.taskId} --remove-depends <id>', OR record an audited one-shot override: 'cleo complete ${options.taskId} --waive-depends "<reason>"' (audited to .cleo/audit/depends-waiver.jsonl).`,
|
|
640
|
-
details: {
|
|
641
|
-
field: "depends",
|
|
642
|
-
unresolvedDeps
|
|
643
|
-
}
|
|
644
|
-
});
|
|
645
|
-
}
|
|
646
|
-
try {
|
|
647
|
-
const { appendDependsWaiverAudit } = await import('./depends-waiver-audit-CUmlBYHx.js');
|
|
648
|
-
await appendDependsWaiverAudit({
|
|
649
|
-
taskId: options.taskId,
|
|
650
|
-
unresolvedDeps,
|
|
651
|
-
waiverReason,
|
|
652
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
653
|
-
agent: process.env["CLEO_AGENT_ID"] ?? "cleo"
|
|
654
|
-
}, cwd);
|
|
655
|
-
} catch (err) {
|
|
656
|
-
console.warn("[complete] failed to write depends-waiver audit:", err instanceof Error ? err.message : String(err));
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
const completionValidation = (await createAcceptanceEnforcement(cwd)).validateCompletion(task);
|
|
661
|
-
if (!completionValidation.valid) throw new CleoError(completionValidation.exitCode ?? ExitCode.VALIDATION_ERROR, completionValidation.error, { fix: completionValidation.fix });
|
|
662
|
-
if (enforcement.verificationEnabled && task.type !== "epic") {
|
|
663
|
-
if (!task.verification) throw new CleoError(ExitCode.VERIFICATION_INIT_FAILED, `Task ${options.taskId} is missing verification metadata`, { fix: `Initialize verification for ${options.taskId} before completion` });
|
|
664
|
-
if (task.verification.round > enforcement.verificationMaxRounds) throw new CleoError(ExitCode.MAX_ROUNDS_EXCEEDED, `Task ${options.taskId} exceeded verification max rounds (${enforcement.verificationMaxRounds})`, { fix: `Review failure log and resolve blockers before retrying completion` });
|
|
665
|
-
const missingRequiredGates = enforcement.verificationRequiredGates.filter((gate) => task.verification?.gates?.[gate] !== true);
|
|
666
|
-
if (missingRequiredGates.length > 0 || task.verification.passed !== true) throw new CleoError(enforcement.lifecycleMode === "strict" ? ExitCode.LIFECYCLE_GATE_FAILED : ExitCode.GATE_DEPENDENCY, `Task ${options.taskId} failed verification gates: ${missingRequiredGates.join(", ") || "verification.passed=false"}`, { fix: `Set required verification gates before completion: ${enforcement.verificationRequiredGates.join(", ")}` });
|
|
667
|
-
}
|
|
668
|
-
if (enforcement.verificationEnabled && enforcement.lifecycleMode === "strict" && task.type === "epic") {
|
|
669
|
-
if (!await verifyEpicHasEvidence(task, acc)) throw new CleoError(ExitCode.LIFECYCLE_GATE_FAILED, `Epic ${options.taskId} cannot complete without direct evidence atoms or verified children`, { fix: `Either add direct evidence via 'cleo verify ${options.taskId} --gate implemented --evidence "..."' or ensure all children have status=done with verification.passed=true.` });
|
|
670
|
-
}
|
|
671
|
-
const projectRoot = cwd ?? getProjectRoot();
|
|
672
|
-
const gateResult = await validateNexusImpactGate(task, projectRoot);
|
|
673
|
-
if (!gateResult.passed && !options.acknowledgeRisk) throw new CleoError(gateResult.exitCode ?? ExitCode.NEXUS_IMPACT_CRITICAL, gateResult.error ?? "CRITICAL impact risk detected", {
|
|
674
|
-
fix: "Either fix the CRITICAL symbols or pass --acknowledge-risk \"<reason>\" to bypass the gate",
|
|
675
|
-
details: {
|
|
676
|
-
field: "criticalSymbols",
|
|
677
|
-
criticalSymbols: gateResult.criticalSymbols?.map((s) => ({
|
|
678
|
-
symbol: s.symbolName ?? s.symbolId,
|
|
679
|
-
risk: s.mergedRiskScore,
|
|
680
|
-
narrative: s.narrative
|
|
681
|
-
}))
|
|
682
|
-
}
|
|
683
|
-
});
|
|
684
|
-
if (options.acknowledgeRisk && gateResult.criticalSymbols && gateResult.criticalSymbols.length > 0) try {
|
|
685
|
-
const { appendNexusRiskAck } = await import('./nexus-risk-audit-p379-TU5.js');
|
|
686
|
-
await appendNexusRiskAck({
|
|
687
|
-
taskId: options.taskId,
|
|
688
|
-
symbols: gateResult.criticalSymbols.map((s) => ({
|
|
689
|
-
symbolId: s.symbolId,
|
|
690
|
-
symbolName: s.symbolName ?? void 0,
|
|
691
|
-
risk: s.mergedRiskScore
|
|
692
|
-
})),
|
|
693
|
-
reason: options.acknowledgeRisk,
|
|
694
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
695
|
-
agent: process.env.CLEO_AGENT_ID ?? "cleo"
|
|
696
|
-
});
|
|
697
|
-
} catch (err) {
|
|
698
|
-
console.warn("[complete] failed to audit nexus risk acknowledgment:", err instanceof Error ? err.message : String(err));
|
|
699
|
-
}
|
|
700
|
-
const children = await acc.getChildren(options.taskId);
|
|
701
|
-
const pendingChildren = children.filter((c) => c.status !== "done" && c.status !== "cancelled");
|
|
702
|
-
if (pendingChildren.length > 0 && task.type === "epic") {
|
|
703
|
-
if (!options.overrideReason) throw new CleoError(ExitCode.EPIC_HAS_PENDING_CHILDREN, `Epic ${options.taskId} has ${pendingChildren.length} pending/active children: ${pendingChildren.map((c) => c.id).join(", ")}`, { fix: "Complete all children first, or pass --override-reason \"<reason>\" to bypass (audited to .cleo/audit/premature-close.jsonl)." });
|
|
704
|
-
try {
|
|
705
|
-
const { appendPrematureCloseAudit } = await import('./premature-close-audit-VG09uAco.js');
|
|
706
|
-
await appendPrematureCloseAudit({
|
|
707
|
-
epicId: options.taskId,
|
|
708
|
-
pendingChildIds: pendingChildren.map((c) => c.id),
|
|
709
|
-
overrideReason: options.overrideReason,
|
|
710
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
711
|
-
agent: process.env["CLEO_AGENT_ID"] ?? "cleo"
|
|
712
|
-
}, cwd);
|
|
713
|
-
} catch (err) {
|
|
714
|
-
console.warn("[complete] failed to write premature-close audit:", err instanceof Error ? err.message : String(err));
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
const cancelledChildren = children.filter((c) => c.status === "cancelled");
|
|
718
|
-
if (cancelledChildren.length > 0) {
|
|
719
|
-
const waiverReason = options.cancelledChildWaiverReason?.trim();
|
|
720
|
-
if (!waiverReason) throw new CleoError(ExitCode.CANCELLED_CHILD_NO_WAIVER, `Task ${options.taskId} has ${cancelledChildren.length} cancelled child${cancelledChildren.length === 1 ? "" : "ren"} that must be waived or replaced before completion: ${cancelledChildren.map((c) => c.id).join(", ")}`, {
|
|
721
|
-
fix: `Cancelled children represent work that was NOT done — they cannot silently satisfy parent completion. Either re-open and finish the work, replace it with a done child, or record an audited waiver: 'cleo complete ${options.taskId} --waive-cancelled-children "<reason>"' (cite the replacement task id in the reason when applicable; audited to .cleo/audit/cancelled-child-waiver.jsonl).`,
|
|
722
|
-
details: {
|
|
723
|
-
field: "cancelledChildIds",
|
|
724
|
-
cancelledChildIds: cancelledChildren.map((c) => c.id)
|
|
725
|
-
}
|
|
726
|
-
});
|
|
727
|
-
try {
|
|
728
|
-
const { appendCancelledChildWaiverAudit } = await import('./cancelled-child-waiver-audit-DkesrN83.js');
|
|
729
|
-
await appendCancelledChildWaiverAudit({
|
|
730
|
-
parentId: options.taskId,
|
|
731
|
-
cancelledChildIds: cancelledChildren.map((c) => c.id),
|
|
732
|
-
waiverReason,
|
|
733
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
734
|
-
agent: process.env["CLEO_AGENT_ID"] ?? "cleo"
|
|
735
|
-
}, cwd);
|
|
736
|
-
} catch (err) {
|
|
737
|
-
console.warn("[complete] failed to write cancelled-child-waiver audit:", err instanceof Error ? err.message : String(err));
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
741
|
-
const before = { ...task };
|
|
742
|
-
const autoCompleted = [];
|
|
743
|
-
const autoCompletedTasks = [];
|
|
744
|
-
const { receipt } = await wrapWithAgentSession({
|
|
745
|
-
sessionId: typeof process.env.CLEO_SESSION_ID === "string" && process.env.CLEO_SESSION_ID.length > 0 ? process.env.CLEO_SESSION_ID : void 0,
|
|
746
|
-
agentId: process.env.CLEO_AGENT_ID ?? "cleo",
|
|
747
|
-
projectRoot: resolveOrCwd(cwd),
|
|
748
|
-
label: `complete:${options.taskId}`
|
|
749
|
-
}, async () => withTaskWriteTransaction(acc, async (tx) => {
|
|
750
|
-
if (task.verification?.passed === true) {
|
|
751
|
-
const acRows = await acc.getAcRows(options.taskId);
|
|
752
|
-
if (acRows.length > 0) {
|
|
753
|
-
const acIds = acRows.map((ac) => ac.id);
|
|
754
|
-
const bindings = await acc.getAcBindings(acIds);
|
|
755
|
-
const boundAcIds = new Set(bindings.map((b) => b.acId));
|
|
756
|
-
const unbound = acRows.filter((ac) => !boundAcIds.has(ac.id));
|
|
757
|
-
if (unbound.length > 0) await tx.insertAcBindings(unbound.map((ac) => ({
|
|
758
|
-
id: `auto-coverage-${ac.id.slice(0, 8)}`,
|
|
759
|
-
evidenceAtomId: "auto-coverage-verification-passed",
|
|
760
|
-
acId: ac.id,
|
|
761
|
-
bindingType: "coverage"
|
|
762
|
-
})));
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
await enforceAcCoverageGate(options, projectRootForGate(cwd), tx);
|
|
766
|
-
const completionStage = task.pipelineStage;
|
|
767
|
-
if (completionStage && isValidPipelineStage(completionStage) && EXECUTION_STAGES_FOR_RELEASE.has(completionStage)) task.pipelineStage = "release";
|
|
768
|
-
if (!isTerminalPipelineStage(task.pipelineStage)) task.pipelineStage = "contribution";
|
|
769
|
-
task.status = "done";
|
|
770
|
-
task.completedAt = now;
|
|
771
|
-
task.updatedAt = now;
|
|
772
|
-
if (options.notes) {
|
|
773
|
-
const timestampedNote = `${(/* @__PURE__ */ new Date()).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC")}: ${options.notes}`;
|
|
774
|
-
if (!task.notes) task.notes = [];
|
|
775
|
-
task.notes.push(timestampedNote);
|
|
776
|
-
}
|
|
777
|
-
if (options.changeset) {
|
|
778
|
-
if (!task.notes) task.notes = [];
|
|
779
|
-
task.notes.push(`Changeset: ${options.changeset}`);
|
|
780
|
-
}
|
|
781
|
-
if (task.parentId) {
|
|
782
|
-
const parent = await acc.loadSingleTask(task.parentId);
|
|
783
|
-
if (parent && parent.type === "epic" && !parent.noAutoComplete) {
|
|
784
|
-
const siblings = await acc.getChildren(parent.id);
|
|
785
|
-
const allDone = siblings.length > 0 && siblings.every((c) => c.id === task.id || c.status === "done" || c.status === "cancelled");
|
|
786
|
-
const hasCancelledSibling = siblings.some((c) => c.id !== task.id && c.status === "cancelled");
|
|
787
|
-
if (allDone && hasCancelledSibling) getLogger("engine:complete").info({
|
|
788
|
-
epicId: parent.id,
|
|
789
|
-
completedChild: task.id
|
|
790
|
-
}, "[complete] suppressing epic auto-close: un-waived cancelled children require `cleo complete --waive-cancelled-children`");
|
|
791
|
-
if (allDone && !hasCancelledSibling) {
|
|
792
|
-
if (enforcement.verificationEnabled && enforcement.lifecycleMode === "strict" ? await verifyEpicHasEvidence(parent, {
|
|
793
|
-
...acc,
|
|
794
|
-
getChildren: async (parentId) => {
|
|
795
|
-
if (parentId !== parent.id) return acc.getChildren(parentId);
|
|
796
|
-
return siblings.map((c) => {
|
|
797
|
-
if (c.id !== task.id) return c;
|
|
798
|
-
return {
|
|
799
|
-
...c,
|
|
800
|
-
status: "done",
|
|
801
|
-
verification: c.verification ?? task.verification ?? void 0
|
|
802
|
-
};
|
|
803
|
-
});
|
|
804
|
-
}
|
|
805
|
-
}) : true) {
|
|
806
|
-
parent.status = "done";
|
|
807
|
-
parent.completedAt = now;
|
|
808
|
-
parent.updatedAt = now;
|
|
809
|
-
if (!isTerminalPipelineStage(parent.pipelineStage)) parent.pipelineStage = "contribution";
|
|
810
|
-
autoCompleted.push(parent.id);
|
|
811
|
-
autoCompletedTasks.push(parent);
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
if (task.parentId) {
|
|
817
|
-
const coordinationParent = await acc.loadSingleTask(task.parentId);
|
|
818
|
-
if (coordinationParent && coordinationParent.type !== "epic" && coordinationParent.type !== "saga" && !autoCompleted.includes(coordinationParent.id)) {
|
|
819
|
-
const cpChildren = await acc.getChildren(coordinationParent.id);
|
|
820
|
-
if (cpChildren.length > 0 && isCoordinationParent(coordinationParent, cpChildren.length)) {
|
|
821
|
-
const allCpDone = cpChildren.every((c) => c.id === task.id || c.status === "done" || c.status === "cancelled");
|
|
822
|
-
const cpHasCancelledChild = cpChildren.some((c) => c.id !== task.id && c.status === "cancelled");
|
|
823
|
-
if (allCpDone && cpHasCancelledChild) getLogger("engine:complete").info({
|
|
824
|
-
parentId: coordinationParent.id,
|
|
825
|
-
completedChild: task.id
|
|
826
|
-
}, "[complete] suppressing coordination-parent auto-close: un-waived cancelled children require `cleo complete --waive-cancelled-children`");
|
|
827
|
-
if (allCpDone && !cpHasCancelledChild) {
|
|
828
|
-
const childrenForRollup = cpChildren.map((c) => c.id === task.id ? {
|
|
829
|
-
...c,
|
|
830
|
-
status: "done"
|
|
831
|
-
} : c);
|
|
832
|
-
coordinationParent.verification = buildRollupEvidence(coordinationParent.id, childrenForRollup);
|
|
833
|
-
coordinationParent.status = "done";
|
|
834
|
-
coordinationParent.completedAt = now;
|
|
835
|
-
coordinationParent.updatedAt = now;
|
|
836
|
-
if (!isTerminalPipelineStage(coordinationParent.pipelineStage)) coordinationParent.pipelineStage = "contribution";
|
|
837
|
-
autoCompleted.push(coordinationParent.id);
|
|
838
|
-
autoCompletedTasks.push(coordinationParent);
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
const sagasGroupingThisTask = await findSagasGroupingTask(acc, task.id);
|
|
844
|
-
for (const saga of sagasGroupingThisTask) {
|
|
845
|
-
if (saga.status === "done" || saga.status === "cancelled") continue;
|
|
846
|
-
if (autoCompleted.includes(saga.id)) continue;
|
|
847
|
-
const memberTasks = (await acc.queryTasks({ parentId: saga.id })).tasks;
|
|
848
|
-
if (memberTasks.map((member) => member.id).length === 0) continue;
|
|
849
|
-
if (!memberTasks.every((m) => {
|
|
850
|
-
if (m.id === task.id) return true;
|
|
851
|
-
return m.status === "done" || m.status === "cancelled";
|
|
852
|
-
})) continue;
|
|
853
|
-
const terminalMemberIds = memberTasks.filter((m) => m.id === task.id || m.status === "done" || m.status === "cancelled").map((m) => m.id);
|
|
854
|
-
saga.verification = buildSagaAutoCloseEvidence(saga.id, terminalMemberIds, now);
|
|
855
|
-
saga.status = "done";
|
|
856
|
-
saga.completedAt = now;
|
|
857
|
-
saga.updatedAt = now;
|
|
858
|
-
if (!isTerminalPipelineStage(saga.pipelineStage)) saga.pipelineStage = "contribution";
|
|
859
|
-
autoCompleted.push(saga.id);
|
|
860
|
-
autoCompletedTasks.push(saga);
|
|
861
|
-
}
|
|
862
|
-
await tx.upsertSingleTask(task);
|
|
863
|
-
for (const parentTask of autoCompletedTasks) await tx.upsertSingleTask(parentTask);
|
|
864
|
-
await tx.appendLog({
|
|
865
|
-
id: `log-${Math.floor(Date.now() / 1e3)}-${(await import('node:crypto')).randomBytes(3).toString("hex")}`,
|
|
866
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
867
|
-
action: "task_completed",
|
|
868
|
-
taskId: options.taskId,
|
|
869
|
-
actor: "system",
|
|
870
|
-
details: {
|
|
871
|
-
title: task.title,
|
|
872
|
-
previousStatus: before.status
|
|
873
|
-
},
|
|
874
|
-
before: null,
|
|
875
|
-
after: {
|
|
876
|
-
title: task.title,
|
|
877
|
-
previousStatus: before.status
|
|
878
|
-
}
|
|
879
|
-
});
|
|
880
|
-
return {};
|
|
881
|
-
}));
|
|
882
|
-
const dependents = await acc.getDependents(options.taskId);
|
|
883
|
-
const unblockedTasks = [];
|
|
884
|
-
for (const dep of dependents) {
|
|
885
|
-
if (dep.status === "done" || dep.status === "cancelled" || dep.status === "archived") continue;
|
|
886
|
-
if (dep.depends?.length) {
|
|
887
|
-
if ((await acc.loadTasks(dep.depends)).filter((d) => d.id !== options.taskId && d.status !== "done" && d.status !== "cancelled" && d.status !== "archived").length === 0) unblockedTasks.push({
|
|
888
|
-
id: dep.id,
|
|
889
|
-
title: dep.title
|
|
890
|
-
});
|
|
891
|
-
} else unblockedTasks.push({
|
|
892
|
-
id: dep.id,
|
|
893
|
-
title: dep.title
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
try {
|
|
897
|
-
const { completeAgentWorktreeIntegration } = await import('./branch-lock2-CmDc4CZW.js');
|
|
898
|
-
const integration = completeAgentWorktreeIntegration(options.taskId, projectRoot, { taskTitle: task.title });
|
|
899
|
-
if (integration.nothingToIntegrate) getLogger("tasks:complete").debug({ taskId: options.taskId }, "[T12153] no task branch or worktree for this task — nothing to integrate");
|
|
900
|
-
else if (!integration.merged && integration.error) getLogger("tasks:complete").warn({
|
|
901
|
-
taskId: options.taskId,
|
|
902
|
-
mergeError: integration.error,
|
|
903
|
-
worktreeRemoved: integration.worktreeRemoved
|
|
904
|
-
}, "[T9175] worktree integration failed — branch + worktree preserved for manual recovery");
|
|
905
|
-
} catch (err) {
|
|
906
|
-
getLogger("tasks:complete").debug({ err: err instanceof Error ? err.message : String(err) }, "[T9175] worktree integration helper unavailable — skipping");
|
|
907
|
-
}
|
|
908
|
-
trackBackgroundOp(import('./graph-auto-populate-Dmsr9ZJM.js').then(({ upsertGraphNode, addGraphEdge }) => (async () => {
|
|
909
|
-
const projectRoot = resolveOrCwd(cwd);
|
|
910
|
-
await upsertGraphNode(projectRoot, `task:${task.id}`, "task", `${task.id}: ${task.title}`.substring(0, 200), 1, task.title, {
|
|
911
|
-
status: "done",
|
|
912
|
-
priority: task.priority
|
|
913
|
-
});
|
|
914
|
-
if (task.parentId) {
|
|
915
|
-
await upsertGraphNode(projectRoot, `epic:${task.parentId}`, "epic", task.parentId, 1, "");
|
|
916
|
-
await addGraphEdge(projectRoot, `task:${task.id}`, `epic:${task.parentId}`, "part_of", 1, "auto:task-complete");
|
|
917
|
-
}
|
|
918
|
-
})()).catch(() => {}));
|
|
919
|
-
try {
|
|
920
|
-
const { hooks } = await import('./registry-CL2gN1zd.js');
|
|
921
|
-
await hooks.dispatch("PostToolUse", resolveOrCwd(cwd), {
|
|
922
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
923
|
-
taskId: options.taskId,
|
|
924
|
-
taskTitle: task.title,
|
|
925
|
-
status: "done",
|
|
926
|
-
metadata: {
|
|
927
|
-
previousStatus: before.status,
|
|
928
|
-
unblockedCount: unblockedTasks.length
|
|
929
|
-
}
|
|
930
|
-
}).catch(() => {});
|
|
931
|
-
} catch {}
|
|
932
|
-
const receiptSummary = receipt !== null ? {
|
|
933
|
-
receiptId: receipt.sessionId,
|
|
934
|
-
...receipt.signature ? { signature: receipt.signature } : {}
|
|
935
|
-
} : void 0;
|
|
936
|
-
return {
|
|
937
|
-
task,
|
|
938
|
-
...autoCompleted.length > 0 && { autoCompleted },
|
|
939
|
-
...unblockedTasks.length > 0 && { unblockedTasks },
|
|
940
|
-
...receiptSummary ? { receipt: receiptSummary } : {}
|
|
941
|
-
};
|
|
942
|
-
}
|
|
943
|
-
//#endregion
|
|
944
|
-
//#region ../core/dist/tasks/ac-immutability.js
|
|
945
|
-
/**
|
|
946
|
-
* Acceptance-criteria immutability guard.
|
|
947
|
-
*
|
|
948
|
-
* Locks `task.acceptance` once a task enters the implementation pipeline
|
|
949
|
-
* stage (or any later stage). Prevents the "T-THIN-WRAPPER feature-complete"
|
|
950
|
-
* anti-pattern where acceptance criteria are silently reframed after work
|
|
951
|
-
* has shipped to match what was actually built.
|
|
952
|
-
*
|
|
953
|
-
* The lock can be overridden by supplying an explicit operator `reason`,
|
|
954
|
-
* which is appended to an append-only audit log at
|
|
955
|
-
* `.cleo/audit/ac-changes.jsonl` together with the before/after AC, the
|
|
956
|
-
* stage at which the override occurred, the timestamp and the agent
|
|
957
|
-
* identifier.
|
|
958
|
-
*
|
|
959
|
-
* Locked stages: implementation, validation, testing, release, contribution.
|
|
960
|
-
*
|
|
961
|
-
* @epic T1586 Foundation Lockdown (Wave A)
|
|
962
|
-
* @task T1590
|
|
963
|
-
*/
|
|
964
|
-
/**
|
|
965
|
-
* Pipeline stages at which acceptance criteria are considered locked.
|
|
966
|
-
*
|
|
967
|
-
* Once a task crosses into `implementation`, AC are treated as a binding
|
|
968
|
-
* contract — any subsequent change must be operator-approved with a
|
|
969
|
-
* written reason that is captured in the audit log.
|
|
970
|
-
*
|
|
971
|
-
* @task T1590
|
|
972
|
-
*/
|
|
973
|
-
var AC_LOCKED_STAGES = new Set([
|
|
974
|
-
"implementation",
|
|
975
|
-
"validation",
|
|
976
|
-
"testing",
|
|
977
|
-
"release",
|
|
978
|
-
"contribution"
|
|
979
|
-
]);
|
|
980
|
-
/** Relative path within project root for the AC-changes audit log. */
|
|
981
|
-
var AC_CHANGES_AUDIT_FILE = ".cleo/audit/ac-changes.jsonl";
|
|
982
|
-
/**
|
|
983
|
-
* Check whether a task's pipeline stage locks acceptance-criteria changes.
|
|
984
|
-
*
|
|
985
|
-
* @param stage - Current pipeline stage of the task (may be null/undefined).
|
|
986
|
-
* @returns True if the stage is in {@link AC_LOCKED_STAGES}.
|
|
987
|
-
*
|
|
988
|
-
* @example
|
|
989
|
-
* ```ts
|
|
990
|
-
* isAcceptanceLocked('research'); // => false
|
|
991
|
-
* isAcceptanceLocked('implementation'); // => true
|
|
992
|
-
* ```
|
|
993
|
-
*
|
|
994
|
-
* @task T1590
|
|
995
|
-
*/
|
|
996
|
-
function isAcceptanceLocked(stage) {
|
|
997
|
-
return !!stage && AC_LOCKED_STAGES.has(stage);
|
|
998
|
-
}
|
|
999
|
-
/**
|
|
1000
|
-
* Determine whether two acceptance-criteria arrays are structurally equal.
|
|
1001
|
-
*
|
|
1002
|
-
* Used to suppress the lock when the caller passes an unchanged AC payload
|
|
1003
|
-
* (a no-op should never trip the immutability guard).
|
|
1004
|
-
*
|
|
1005
|
-
* @param a - First criteria array (or null/undefined).
|
|
1006
|
-
* @param b - Second criteria array (or null/undefined).
|
|
1007
|
-
* @returns True if both arrays have identical length and elements.
|
|
1008
|
-
*
|
|
1009
|
-
* @task T1590
|
|
1010
|
-
*/
|
|
1011
|
-
function acceptanceEquals(a, b) {
|
|
1012
|
-
const aArr = a ?? [];
|
|
1013
|
-
const bArr = b ?? [];
|
|
1014
|
-
if (aArr.length !== bArr.length) return false;
|
|
1015
|
-
for (let i = 0; i < aArr.length; i++) {
|
|
1016
|
-
const left = aArr[i];
|
|
1017
|
-
const right = bArr[i];
|
|
1018
|
-
if (typeof left === "string" && typeof right === "string") {
|
|
1019
|
-
if (left !== right) return false;
|
|
1020
|
-
continue;
|
|
1021
|
-
}
|
|
1022
|
-
if (JSON.stringify(left) !== JSON.stringify(right)) return false;
|
|
1023
|
-
}
|
|
1024
|
-
return true;
|
|
1025
|
-
}
|
|
1026
|
-
/**
|
|
1027
|
-
* Does this task have no acceptance criteria at all?
|
|
1028
|
-
*
|
|
1029
|
-
* Treats `undefined`, `null`, an empty list, and a list whose entries are all
|
|
1030
|
-
* blank as equally empty — to an operator, a task whose AC column holds `[]`
|
|
1031
|
-
* and one holding `['']` both have no criteria, and the guard must not
|
|
1032
|
-
* distinguish them.
|
|
1033
|
-
*
|
|
1034
|
-
* @param acceptance - The task's current acceptance criteria.
|
|
1035
|
-
* @returns `true` when there is nothing for the immutability guard to protect.
|
|
1036
|
-
*
|
|
1037
|
-
* @task T12153 (gh#1235)
|
|
1038
|
-
*/
|
|
1039
|
-
function isAcceptanceEmpty(acceptance) {
|
|
1040
|
-
if (!acceptance || acceptance.length === 0) return true;
|
|
1041
|
-
return acceptance.every((item) => typeof item === "string" && item.trim().length === 0);
|
|
1042
|
-
}
|
|
1043
|
-
/**
|
|
1044
|
-
* Enforce the AC-immutability guard for a task update.
|
|
1045
|
-
*
|
|
1046
|
-
* Behaviour:
|
|
1047
|
-
* - When `newAcceptance` is `undefined`, the call is a no-op.
|
|
1048
|
-
* - When the task is not in a locked stage, the call is a no-op.
|
|
1049
|
-
* - When the new AC is structurally identical to the existing AC, the call
|
|
1050
|
-
* is a no-op (idempotent updates are always allowed).
|
|
1051
|
-
* - When the task is in a locked stage and `reason` is missing or empty,
|
|
1052
|
-
* a {@link CleoError} with {@link ExitCode.AC_LOCKED} is thrown.
|
|
1053
|
-
* - When the task is in a locked stage and `reason` is provided, an audit
|
|
1054
|
-
* entry is appended to `.cleo/audit/ac-changes.jsonl`.
|
|
1055
|
-
*
|
|
1056
|
-
* @param options - {@link EnforceAcceptanceImmutabilityOptions}.
|
|
1057
|
-
* @throws CleoError(AC_LOCKED) when the AC are locked and no reason is given.
|
|
1058
|
-
*
|
|
1059
|
-
* @example
|
|
1060
|
-
* ```ts
|
|
1061
|
-
* enforceAcceptanceImmutability({
|
|
1062
|
-
* task,
|
|
1063
|
-
* newAcceptance: ['AC1', 'AC2', 'AC3'],
|
|
1064
|
-
* reason: 'operator approved scope expansion',
|
|
1065
|
-
* projectRoot: '/project',
|
|
1066
|
-
* });
|
|
1067
|
-
* ```
|
|
1068
|
-
*
|
|
1069
|
-
* @task T1590
|
|
1070
|
-
*/
|
|
1071
|
-
function enforceAcceptanceImmutability(options) {
|
|
1072
|
-
const { task, newAcceptance, reason, projectRoot } = options;
|
|
1073
|
-
if (newAcceptance === void 0) return;
|
|
1074
|
-
if (!isAcceptanceLocked(task.pipelineStage)) return;
|
|
1075
|
-
if (acceptanceEquals(task.acceptance, newAcceptance)) return;
|
|
1076
|
-
if (isAcceptanceEmpty(task.acceptance)) return;
|
|
1077
|
-
const trimmedReason = typeof reason === "string" ? reason.trim() : "";
|
|
1078
|
-
if (!trimmedReason) throw new CleoError(ExitCode.AC_LOCKED, `Acceptance criteria locked at stage ${task.pipelineStage}. Reframing AC after implementation is anti-pattern. Use --reason '<X>' to override with audit log entry.`, {
|
|
1079
|
-
fix: `cleo update ${task.id} --acceptance "..." --reason "<why this change is acceptable>"`,
|
|
1080
|
-
details: {
|
|
1081
|
-
field: "acceptance",
|
|
1082
|
-
stage: task.pipelineStage ?? null,
|
|
1083
|
-
taskId: task.id
|
|
1084
|
-
}
|
|
1085
|
-
});
|
|
1086
|
-
appendAcceptanceChangeAudit({
|
|
1087
|
-
projectRoot: resolveOrCwd(projectRoot),
|
|
1088
|
-
taskId: task.id,
|
|
1089
|
-
stage: task.pipelineStage ?? "",
|
|
1090
|
-
reason: trimmedReason,
|
|
1091
|
-
oldAcceptance: task.acceptance ?? [],
|
|
1092
|
-
newAcceptance
|
|
1093
|
-
});
|
|
1094
|
-
}
|
|
1095
|
-
/**
|
|
1096
|
-
* Append a single {@link AcceptanceChangeAuditEntry} to
|
|
1097
|
-
* `.cleo/audit/ac-changes.jsonl`.
|
|
1098
|
-
*
|
|
1099
|
-
* Errors are deliberately swallowed (best-effort write) so audit failures
|
|
1100
|
-
* never block a legitimate operator-approved update. The path mirrors
|
|
1101
|
-
* `force-bypass.jsonl` and `contract-violations.jsonl` (ADR-039).
|
|
1102
|
-
*
|
|
1103
|
-
* @task T1590
|
|
1104
|
-
*/
|
|
1105
|
-
function appendAcceptanceChangeAudit(input) {
|
|
1106
|
-
try {
|
|
1107
|
-
const filePath = join(input.projectRoot, AC_CHANGES_AUDIT_FILE);
|
|
1108
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
1109
|
-
const entry = {
|
|
1110
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1111
|
-
taskId: input.taskId,
|
|
1112
|
-
stage: input.stage,
|
|
1113
|
-
reason: input.reason,
|
|
1114
|
-
oldAcceptance: JSON.parse(JSON.stringify(input.oldAcceptance)),
|
|
1115
|
-
newAcceptance: JSON.parse(JSON.stringify(input.newAcceptance)),
|
|
1116
|
-
agent: process.env["CLEO_AGENT_ID"] ?? "cleo"
|
|
1117
|
-
};
|
|
1118
|
-
appendFileSync(filePath, `${JSON.stringify(entry)}\n`, { encoding: "utf-8" });
|
|
1119
|
-
} catch {}
|
|
1120
|
-
}
|
|
1121
|
-
//#endregion
|
|
1122
|
-
//#region ../core/dist/tasks/child-disposition.js
|
|
1123
|
-
/**
|
|
1124
|
-
* Shared child-disposition guard for terminal-status writers (T11811 AC2).
|
|
1125
|
-
*
|
|
1126
|
-
* Three writers can drive a task into a terminal state: `coreTaskCancel`
|
|
1127
|
-
* (`cleo cancel`), `updateTask` with `status='cancelled'`
|
|
1128
|
-
* (`cleo update --status cancelled`), and `archiveTasks` (`cleo archive`).
|
|
1129
|
-
* Historically only `coreTaskCancel` consulted the child set before
|
|
1130
|
-
* terminalising a parent — the other two flipped the parent and SILENTLY
|
|
1131
|
-
* STRANDED its still-active children under a terminal (or removed) parent
|
|
1132
|
-
* (the T9031/T9044 strand class).
|
|
1133
|
-
*
|
|
1134
|
-
* The orphan-prevention guard collapses that to ONE decision: before any
|
|
1135
|
-
* terminal-status writer terminalises a parent, it MUST consult this module.
|
|
1136
|
-
* The lowest-blast-radius default — matching {@link coreTaskCancel}'s own
|
|
1137
|
-
* `children: 'block'` default — is to REFUSE the write when the parent still
|
|
1138
|
-
* has active (non-terminal) children, surfacing {@link ExitCode.HAS_CHILDREN}
|
|
1139
|
-
* and pointing the operator at `cleo cancel <id> --children …`, where the full
|
|
1140
|
-
* `block | cascade | reparent` disposition matrix lives.
|
|
1141
|
-
*
|
|
1142
|
-
* This is a read-only guard: it queries the child set and throws on violation;
|
|
1143
|
-
* it performs no writes. The actual child disposition (cascade/reparent) is
|
|
1144
|
-
* owned by `cleo cancel` via {@link coreTaskCancel} so there is exactly one
|
|
1145
|
-
* place that mutates children on cancellation.
|
|
1146
|
-
*
|
|
1147
|
-
* @task T11811 — orphan-prevention guard (AC2: one disposition path)
|
|
1148
|
-
* @saga T10400
|
|
1149
|
-
*/
|
|
1150
|
-
/**
|
|
1151
|
-
* Refuse to terminalise a parent that still has active children.
|
|
1152
|
-
*
|
|
1153
|
-
* Counts the parent's non-terminal children via
|
|
1154
|
-
* {@link DataAccessor.countActiveChildren} (the canonical "active" =
|
|
1155
|
-
* not-in-`TERMINAL_TASK_STATUSES` count). When that count is non-zero the
|
|
1156
|
-
* function throws {@link CleoError} with {@link ExitCode.HAS_CHILDREN}, a
|
|
1157
|
-
* `fix:` that routes the operator to `cleo cancel <id> --children …`, and a
|
|
1158
|
-
* structured `details` payload carrying the live child count. When the parent
|
|
1159
|
-
* has zero active children it returns normally and the caller proceeds with
|
|
1160
|
-
* the terminal write — no strand is possible.
|
|
1161
|
-
*
|
|
1162
|
-
* Routing every terminal-status writer through this single guard means the
|
|
1163
|
-
* child-disposition decision lives in exactly one place (AC2): the only way to
|
|
1164
|
-
* dispose of active children on cancellation is the explicit
|
|
1165
|
-
* `cleo cancel <id> --children cascade|reparent` surface.
|
|
1166
|
-
*
|
|
1167
|
-
* @param accessor - Open data accessor for the active task store.
|
|
1168
|
-
* @param taskId - The parent task ID being terminalised.
|
|
1169
|
-
* @param verb - Which terminal write is being attempted (`cancel`/`archive`).
|
|
1170
|
-
* @throws {CleoError} {@link ExitCode.HAS_CHILDREN} when the parent has ≥ 1
|
|
1171
|
-
* active (non-terminal) child.
|
|
1172
|
-
*
|
|
1173
|
-
* @example
|
|
1174
|
-
* ```typescript
|
|
1175
|
-
* // Inside the update --status cancelled path:
|
|
1176
|
-
* await assertNoActiveChildrenForTerminal(accessor, taskId, 'cancel');
|
|
1177
|
-
* // …only reached when the parent has no active children to strand.
|
|
1178
|
-
* ```
|
|
1179
|
-
*/
|
|
1180
|
-
async function assertNoActiveChildrenForTerminal(accessor, taskId, verb) {
|
|
1181
|
-
const activeChildCount = await accessor.countActiveChildren(taskId);
|
|
1182
|
-
if (activeChildCount === 0) return;
|
|
1183
|
-
const verbNoun = "Cancelling";
|
|
1184
|
-
throw new CleoError(ExitCode.HAS_CHILDREN, `${verbNoun} ${taskId} would strand ${activeChildCount} active child task(s). Dispose of the children first via \`cleo cancel ${taskId} --children cascade\` (cancel the whole subtree) or \`cleo cancel ${taskId} --children reparent --to <epicId>\` (move them under another parent).`, {
|
|
1185
|
-
fix: `cleo cancel ${taskId} --children cascade # cancel the subtree, or\ncleo cancel ${taskId} --children reparent --to <epicId> # move children elsewhere`,
|
|
1186
|
-
details: {
|
|
1187
|
-
field: "status",
|
|
1188
|
-
taskId,
|
|
1189
|
-
activeChildCount,
|
|
1190
|
-
verb
|
|
1191
|
-
}
|
|
1192
|
-
});
|
|
1193
|
-
}
|
|
1194
|
-
//#endregion
|
|
1195
|
-
//#region ../core/dist/tasks/update.js
|
|
1196
|
-
/**
|
|
1197
|
-
* Task update logic.
|
|
1198
|
-
* @task T4461
|
|
1199
|
-
* @epic T4454
|
|
1200
|
-
*/
|
|
1201
|
-
var NON_STATUS_DONE_FIELDS = [
|
|
1202
|
-
"title",
|
|
1203
|
-
"priority",
|
|
1204
|
-
"type",
|
|
1205
|
-
"size",
|
|
1206
|
-
"phase",
|
|
1207
|
-
"description",
|
|
1208
|
-
"labels",
|
|
1209
|
-
"addLabels",
|
|
1210
|
-
"removeLabels",
|
|
1211
|
-
"depends",
|
|
1212
|
-
"addDepends",
|
|
1213
|
-
"removeDepends",
|
|
1214
|
-
"notes",
|
|
1215
|
-
"acceptance",
|
|
1216
|
-
"files",
|
|
1217
|
-
"addFiles",
|
|
1218
|
-
"removeFiles",
|
|
1219
|
-
"blockedBy",
|
|
1220
|
-
"clearBlockedBy",
|
|
1221
|
-
"parentId",
|
|
1222
|
-
"noAutoComplete",
|
|
1223
|
-
"pipelineStage",
|
|
1224
|
-
"kind",
|
|
1225
|
-
"scope",
|
|
1226
|
-
"severity",
|
|
1227
|
-
"relates",
|
|
1228
|
-
"addRelates",
|
|
1229
|
-
"removeRelates"
|
|
1230
|
-
];
|
|
1231
|
-
function typeForParent(parentType, currentType) {
|
|
1232
|
-
if (currentType === "saga") return "saga";
|
|
1233
|
-
if (currentType === "epic") return "epic";
|
|
1234
|
-
if (parentType === "task") return "subtask";
|
|
1235
|
-
if (parentType === "epic") return "task";
|
|
1236
|
-
return currentType === "subtask" ? "task" : currentType ?? "task";
|
|
1237
|
-
}
|
|
1238
|
-
function hasNonStatusDoneFields(options) {
|
|
1239
|
-
return NON_STATUS_DONE_FIELDS.some((field) => options[field] !== void 0);
|
|
1240
|
-
}
|
|
1241
|
-
/**
|
|
1242
|
-
* Update a task's fields.
|
|
1243
|
-
* @task T4461
|
|
1244
|
-
*/
|
|
1245
|
-
async function updateTask(options, cwd, accessor) {
|
|
1246
|
-
const acc = accessor ?? await getTaskAccessor(cwd);
|
|
1247
|
-
const task = await acc.loadSingleTask(options.taskId);
|
|
1248
|
-
if (!task) throw new CleoError(ExitCode.NOT_FOUND, `Task not found: ${options.taskId}`, { fix: `Use 'cleo find "${options.taskId}"' to search` });
|
|
1249
|
-
await requireActiveSession("tasks.update", cwd);
|
|
1250
|
-
const changes = [];
|
|
1251
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1252
|
-
const originalParentId = task.parentId ?? null;
|
|
1253
|
-
let lifecycleEvent = null;
|
|
1254
|
-
let lifecycleBeforeStatus = null;
|
|
1255
|
-
let lifecycleAfterStatus = null;
|
|
1256
|
-
if (options.status === "done" && task.status !== "done" && !hasNonStatusDoneFields(options)) return {
|
|
1257
|
-
task: (await completeTask({ taskId: options.taskId }, cwd, accessor)).task,
|
|
1258
|
-
changes: ["status"]
|
|
1259
|
-
};
|
|
1260
|
-
if (options.status === "done" && task.status !== "done") throw new CleoError(ExitCode.VALIDATION_ERROR, "status=done must use complete flow; do not combine with other update fields", { fix: `Run 'cleo complete ${options.taskId}' first, then apply additional updates with 'cleo update ${options.taskId} ...'` });
|
|
1261
|
-
const updateValidation = (await createAcceptanceEnforcement(cwd)).validateUpdate(task, { acceptance: options.acceptance });
|
|
1262
|
-
if (!updateValidation.valid) throw new CleoError(updateValidation.exitCode ?? ExitCode.VALIDATION_ERROR, updateValidation.error, { fix: updateValidation.fix });
|
|
1263
|
-
enforceAcceptanceImmutability({
|
|
1264
|
-
task,
|
|
1265
|
-
newAcceptance: options.acceptance,
|
|
1266
|
-
reason: options.reason,
|
|
1267
|
-
projectRoot: cwd
|
|
1268
|
-
});
|
|
1269
|
-
if (options.title !== void 0) {
|
|
1270
|
-
validateTitle(options.title);
|
|
1271
|
-
task.title = options.title;
|
|
1272
|
-
changes.push("title");
|
|
1273
|
-
}
|
|
1274
|
-
if (options.status !== void 0) {
|
|
1275
|
-
validateStatus(options.status);
|
|
1276
|
-
const { validateStatusTransition } = await import('./validation-rules-CE27rtoF.js');
|
|
1277
|
-
const transitionViolations = validateStatusTransition(task.status, options.status);
|
|
1278
|
-
if (transitionViolations.length > 0) throw new CleoError(ExitCode.VALIDATION_ERROR, transitionViolations[0].message, {
|
|
1279
|
-
fix: `Valid transitions from '${task.status}': see cleo update --help`,
|
|
1280
|
-
details: {
|
|
1281
|
-
field: transitionViolations[0].field ?? "status",
|
|
1282
|
-
expected: `valid transition from ${task.status}`,
|
|
1283
|
-
actual: options.status
|
|
1284
|
-
}
|
|
1285
|
-
});
|
|
1286
|
-
if (options.status === "cancelled" && task.status !== "cancelled") await assertNoActiveChildrenForTerminal(acc, options.taskId, "cancel");
|
|
1287
|
-
const oldStatus = task.status;
|
|
1288
|
-
task.status = options.status;
|
|
1289
|
-
changes.push("status");
|
|
1290
|
-
lifecycleBeforeStatus = oldStatus;
|
|
1291
|
-
lifecycleAfterStatus = options.status;
|
|
1292
|
-
if (options.status === "done" && oldStatus !== "done") {
|
|
1293
|
-
task.completedAt = now;
|
|
1294
|
-
lifecycleEvent = "task_completed";
|
|
1295
|
-
}
|
|
1296
|
-
if ((options.status === "pending" || options.status === "active") && oldStatus === "done") lifecycleEvent = "task_reopened";
|
|
1297
|
-
if (options.status === "pending" && oldStatus === "cancelled") lifecycleEvent = "task_uncancelled";
|
|
1298
|
-
if (options.status === "cancelled" && oldStatus !== "cancelled") {
|
|
1299
|
-
task.cancelledAt = now;
|
|
1300
|
-
lifecycleEvent = "task_cancelled";
|
|
1301
|
-
if (task.pipelineStage !== "cancelled") {
|
|
1302
|
-
task.pipelineStage = "cancelled";
|
|
1303
|
-
if (!changes.includes("pipelineStage")) changes.push("pipelineStage");
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
if (options.priority !== void 0) {
|
|
1308
|
-
task.priority = normalizePriority(options.priority);
|
|
1309
|
-
changes.push("priority");
|
|
1310
|
-
}
|
|
1311
|
-
if (options.type !== void 0) {
|
|
1312
|
-
validateTaskType(options.type);
|
|
1313
|
-
task.type = options.type;
|
|
1314
|
-
changes.push("type");
|
|
1315
|
-
}
|
|
1316
|
-
if (options.size !== void 0) {
|
|
1317
|
-
validateSize(options.size);
|
|
1318
|
-
task.size = options.size;
|
|
1319
|
-
changes.push("size");
|
|
1320
|
-
}
|
|
1321
|
-
if (options.phase !== void 0) {
|
|
1322
|
-
task.phase = options.phase;
|
|
1323
|
-
changes.push("phase");
|
|
1324
|
-
}
|
|
1325
|
-
if (options.description !== void 0) {
|
|
1326
|
-
task.description = options.description;
|
|
1327
|
-
changes.push("description");
|
|
1328
|
-
}
|
|
1329
|
-
if (options.labels !== void 0) {
|
|
1330
|
-
if (options.labels.length) validateLabels(options.labels);
|
|
1331
|
-
task.labels = options.labels;
|
|
1332
|
-
changes.push("labels");
|
|
1333
|
-
}
|
|
1334
|
-
if (options.addLabels?.length) {
|
|
1335
|
-
validateLabels(options.addLabels);
|
|
1336
|
-
const existing = new Set(task.labels ?? []);
|
|
1337
|
-
for (const l of options.addLabels) existing.add(l.trim());
|
|
1338
|
-
task.labels = [...existing];
|
|
1339
|
-
changes.push("labels");
|
|
1340
|
-
}
|
|
1341
|
-
if (options.removeLabels?.length) {
|
|
1342
|
-
const toRemove = new Set(options.removeLabels.map((l) => l.trim()));
|
|
1343
|
-
task.labels = (task.labels ?? []).filter((l) => !toRemove.has(l));
|
|
1344
|
-
changes.push("labels");
|
|
1345
|
-
}
|
|
1346
|
-
if (options.depends !== void 0) {
|
|
1347
|
-
task.depends = options.depends;
|
|
1348
|
-
changes.push("depends");
|
|
1349
|
-
}
|
|
1350
|
-
if (options.addDepends?.length) {
|
|
1351
|
-
const existing = new Set(task.depends ?? []);
|
|
1352
|
-
for (const d of options.addDepends) existing.add(d.trim());
|
|
1353
|
-
task.depends = [...existing];
|
|
1354
|
-
changes.push("depends");
|
|
1355
|
-
}
|
|
1356
|
-
if (options.removeDepends?.length) {
|
|
1357
|
-
const toRemove = new Set(options.removeDepends.map((d) => d.trim()));
|
|
1358
|
-
task.depends = (task.depends ?? []).filter((d) => !toRemove.has(d));
|
|
1359
|
-
changes.push("depends");
|
|
1360
|
-
}
|
|
1361
|
-
if (options.notes !== void 0) {
|
|
1362
|
-
const timestampedNote = `${(/* @__PURE__ */ new Date()).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC")}: ${options.notes}`;
|
|
1363
|
-
if (!task.notes) task.notes = [];
|
|
1364
|
-
task.notes.push(timestampedNote);
|
|
1365
|
-
changes.push("notes");
|
|
1366
|
-
}
|
|
1367
|
-
if (options.acceptance !== void 0) {
|
|
1368
|
-
task.acceptance = options.acceptance;
|
|
1369
|
-
changes.push("acceptance");
|
|
1370
|
-
}
|
|
1371
|
-
if (options.files !== void 0) {
|
|
1372
|
-
task.files = options.files;
|
|
1373
|
-
changes.push("files");
|
|
1374
|
-
}
|
|
1375
|
-
if (options.addFiles?.length) {
|
|
1376
|
-
const existing = new Set(task.files ?? []);
|
|
1377
|
-
for (const f of options.addFiles) existing.add(f.trim());
|
|
1378
|
-
task.files = [...existing];
|
|
1379
|
-
changes.push("files");
|
|
1380
|
-
}
|
|
1381
|
-
if (options.removeFiles?.length) {
|
|
1382
|
-
const toRemove = new Set(options.removeFiles.map((f) => f.trim()));
|
|
1383
|
-
task.files = (task.files ?? []).filter((f) => !toRemove.has(f));
|
|
1384
|
-
changes.push("files");
|
|
1385
|
-
}
|
|
1386
|
-
if (options.blockedBy !== void 0) {
|
|
1387
|
-
task.blockedBy = options.blockedBy === "" ? void 0 : options.blockedBy;
|
|
1388
|
-
changes.push("blockedBy");
|
|
1389
|
-
}
|
|
1390
|
-
if (options.clearBlockedBy === true) {
|
|
1391
|
-
task.blockedBy = void 0;
|
|
1392
|
-
if (!changes.includes("blockedBy")) changes.push("blockedBy");
|
|
1393
|
-
}
|
|
1394
|
-
if (options.noAutoComplete !== void 0) {
|
|
1395
|
-
task.noAutoComplete = options.noAutoComplete;
|
|
1396
|
-
changes.push("noAutoComplete");
|
|
1397
|
-
}
|
|
1398
|
-
if (options.kind !== void 0) {
|
|
1399
|
-
task.kind = options.kind;
|
|
1400
|
-
changes.push("kind");
|
|
1401
|
-
}
|
|
1402
|
-
if (options.scope !== void 0) {
|
|
1403
|
-
task.scope = options.scope;
|
|
1404
|
-
changes.push("scope");
|
|
1405
|
-
}
|
|
1406
|
-
if (options.severity !== void 0) {
|
|
1407
|
-
task.severity = options.severity;
|
|
1408
|
-
changes.push("severity");
|
|
1409
|
-
}
|
|
1410
|
-
if (options.relates !== void 0) {
|
|
1411
|
-
task.relates = options.relates.map((r) => ({
|
|
1412
|
-
taskId: r.taskId,
|
|
1413
|
-
type: r.type,
|
|
1414
|
-
...r.reason ? { reason: r.reason } : {}
|
|
1415
|
-
}));
|
|
1416
|
-
changes.push("relates");
|
|
1417
|
-
}
|
|
1418
|
-
if (options.addRelates?.length) {
|
|
1419
|
-
const existing = new Map((task.relates ?? []).map((r) => [r.taskId, r]));
|
|
1420
|
-
for (const r of options.addRelates) existing.set(r.taskId, {
|
|
1421
|
-
taskId: r.taskId,
|
|
1422
|
-
type: r.type,
|
|
1423
|
-
...r.reason ? { reason: r.reason } : {}
|
|
1424
|
-
});
|
|
1425
|
-
task.relates = [...existing.values()];
|
|
1426
|
-
changes.push("relates");
|
|
1427
|
-
}
|
|
1428
|
-
if (options.removeRelates?.length) {
|
|
1429
|
-
const toRemove = new Set(options.removeRelates.map((id) => id.trim()));
|
|
1430
|
-
task.relates = (task.relates ?? []).filter((r) => !toRemove.has(r.taskId));
|
|
1431
|
-
changes.push("relates");
|
|
1432
|
-
}
|
|
1433
|
-
if (options.pipelineStage !== void 0) {
|
|
1434
|
-
validatePipelineTransition(task.pipelineStage, options.pipelineStage);
|
|
1435
|
-
if (task.type === "epic" && task.pipelineStage) await validateEpicStageAdvancement({
|
|
1436
|
-
epicId: task.id,
|
|
1437
|
-
currentStage: task.pipelineStage,
|
|
1438
|
-
newStage: options.pipelineStage
|
|
1439
|
-
}, acc, cwd);
|
|
1440
|
-
if (task.type !== "epic") {
|
|
1441
|
-
const epicAncestor = task.parentId ? await findEpicAncestor(task.parentId, acc) : null;
|
|
1442
|
-
const directParent = task.parentId ? await acc.loadSingleTask(task.parentId) : null;
|
|
1443
|
-
const epicToCheck = directParent?.type === "epic" ? directParent : epicAncestor;
|
|
1444
|
-
if (epicToCheck) await validateChildStageCeiling({
|
|
1445
|
-
childStage: options.pipelineStage,
|
|
1446
|
-
epicId: epicToCheck.id
|
|
1447
|
-
}, acc, cwd);
|
|
1448
|
-
}
|
|
1449
|
-
task.pipelineStage = options.pipelineStage;
|
|
1450
|
-
changes.push("pipelineStage");
|
|
1451
|
-
}
|
|
1452
|
-
if (options.parentId !== void 0) {
|
|
1453
|
-
const newParentId = options.parentId || null;
|
|
1454
|
-
if (newParentId !== (task.parentId ?? null)) {
|
|
1455
|
-
const originalType = task.type;
|
|
1456
|
-
if (!newParentId) {
|
|
1457
|
-
task.parentId = null;
|
|
1458
|
-
if (task.type === "subtask") task.type = "task";
|
|
1459
|
-
changes.push("parentId");
|
|
1460
|
-
if (task.type !== originalType) changes.push("type");
|
|
1461
|
-
} else {
|
|
1462
|
-
const newParent = await acc.loadSingleTask(newParentId);
|
|
1463
|
-
if (!newParent) throw new CleoError(ExitCode.PARENT_NOT_FOUND, `Parent task ${newParentId} not found`, {
|
|
1464
|
-
fix: `Use 'cleo find "${newParentId}"' to search or remove --parent flag`,
|
|
1465
|
-
details: {
|
|
1466
|
-
field: "parentId",
|
|
1467
|
-
actual: newParentId
|
|
1468
|
-
}
|
|
1469
|
-
});
|
|
1470
|
-
const newParentType = newParent.type ?? "task";
|
|
1471
|
-
const updatedType = typeForParent(newParentType, task.type);
|
|
1472
|
-
if (!isAllowedWorkGraphParentType(updatedType, newParentType)) throw new CleoError(ExitCode.INVALID_PARENT_TYPE, `Invalid parent type for ${updatedType}: parent ${newParentId} has type '${newParentType}'.`, {
|
|
1473
|
-
fix: "Use Saga→Epic, Epic→Task, and Task→Subtask containment.",
|
|
1474
|
-
details: {
|
|
1475
|
-
field: "parentId",
|
|
1476
|
-
expected: "saga->epic | epic->task | task->subtask",
|
|
1477
|
-
actual: {
|
|
1478
|
-
parentType: newParentType,
|
|
1479
|
-
childType: updatedType
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
});
|
|
1483
|
-
if ((await acc.getSubtree(options.taskId)).some((t) => t.id === newParentId)) throw new CleoError(ExitCode.CIRCULAR_REFERENCE, `Moving '${options.taskId}' under '${newParentId}' would create a circular reference`, {
|
|
1484
|
-
fix: `Choose a parent that is not a descendant of ${options.taskId}`,
|
|
1485
|
-
details: {
|
|
1486
|
-
field: "parentId",
|
|
1487
|
-
actual: newParentId
|
|
1488
|
-
}
|
|
1489
|
-
});
|
|
1490
|
-
const parentDepth = (await acc.getAncestorChain(newParentId)).length;
|
|
1491
|
-
const policy = resolveHierarchyPolicy(await loadConfig(cwd));
|
|
1492
|
-
if (parentDepth + 1 >= policy.maxDepth) throw new CleoError(ExitCode.DEPTH_EXCEEDED, `Maximum nesting depth ${policy.maxDepth} would be exceeded`, {
|
|
1493
|
-
fix: "Choose a parent at a shallower level in the hierarchy",
|
|
1494
|
-
details: {
|
|
1495
|
-
field: "parentId",
|
|
1496
|
-
expected: `depth < ${policy.maxDepth}`,
|
|
1497
|
-
actual: parentDepth + 1
|
|
1498
|
-
}
|
|
1499
|
-
});
|
|
1500
|
-
task.parentId = newParentId;
|
|
1501
|
-
task.type = updatedType;
|
|
1502
|
-
changes.push("parentId");
|
|
1503
|
-
if (task.type !== originalType) changes.push("type");
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
if (changes.length === 0) throw new CleoError(ExitCode.NO_CHANGE, "No changes specified", {
|
|
1508
|
-
fix: `Provide at least one field to update (e.g. cleo update ${options.taskId} --status active)`,
|
|
1509
|
-
details: { field: "options" }
|
|
1510
|
-
});
|
|
1511
|
-
task.updatedAt = now;
|
|
1512
|
-
const finalRelates = task.relates ?? [];
|
|
1513
|
-
const isRelatesChange = changes.includes("relates");
|
|
1514
|
-
const isAcceptanceChange = changes.includes("acceptance");
|
|
1515
|
-
const isReparent = changes.includes("parentId");
|
|
1516
|
-
await acc.transaction(async (tx) => {
|
|
1517
|
-
await tx.upsertSingleTask(task);
|
|
1518
|
-
if (isRelatesChange) if (options.relates !== void 0) {
|
|
1519
|
-
await tx.clearRelations(options.taskId);
|
|
1520
|
-
for (const r of finalRelates) await tx.addRelation(options.taskId, r.taskId, r.type, r.reason);
|
|
1521
|
-
} else {
|
|
1522
|
-
if (options.addRelates?.length) for (const r of options.addRelates) await tx.addRelation(options.taskId, r.taskId, r.type, r.reason);
|
|
1523
|
-
if (options.removeRelates?.length) for (const id of options.removeRelates) await tx.removeRelation(options.taskId, id.trim());
|
|
1524
|
-
}
|
|
1525
|
-
if (isAcceptanceChange && options.acceptance !== void 0) {
|
|
1526
|
-
const existing = await tx.getAcRows(options.taskId);
|
|
1527
|
-
const plan = planAcUpdate(options.taskId, existing, options.acceptance);
|
|
1528
|
-
await applyAcPlan(tx, options.taskId, plan);
|
|
1529
|
-
}
|
|
1530
|
-
if (isReparent) {
|
|
1531
|
-
const parentIds = [originalParentId, task.parentId ?? null].filter((parentId) => parentId !== null);
|
|
1532
|
-
const uniqueParentIds = [...new Set(parentIds)];
|
|
1533
|
-
const projectionAudits = [];
|
|
1534
|
-
for (const parentId of uniqueParentIds) {
|
|
1535
|
-
const audit = await rebuildChildProjectionAc(tx, parentId, (await tx.getChildren(parentId)).map((child) => ({
|
|
1536
|
-
id: child.id,
|
|
1537
|
-
title: child.title
|
|
1538
|
-
})), now);
|
|
1539
|
-
projectionAudits.push(audit);
|
|
1540
|
-
}
|
|
1541
|
-
await tx.appendLog({
|
|
1542
|
-
id: `log-${Math.floor(Date.now() / 1e3)}-${(await import('node:crypto')).randomBytes(3).toString("hex")}`,
|
|
1543
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1544
|
-
action: "ac_projection_rebuilt",
|
|
1545
|
-
taskId: options.taskId,
|
|
1546
|
-
actor: "system",
|
|
1547
|
-
details: {
|
|
1548
|
-
reason: "reparent",
|
|
1549
|
-
oldParentId: originalParentId,
|
|
1550
|
-
newParentId: task.parentId ?? null,
|
|
1551
|
-
audits: projectionAudits
|
|
1552
|
-
},
|
|
1553
|
-
before: null,
|
|
1554
|
-
after: { parentIds: uniqueParentIds }
|
|
1555
|
-
});
|
|
1556
|
-
}
|
|
1557
|
-
if (lifecycleEvent) await tx.appendLog({
|
|
1558
|
-
id: `log-${Math.floor(Date.now() / 1e3)}-${(await import('node:crypto')).randomBytes(3).toString("hex")}`,
|
|
1559
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1560
|
-
action: lifecycleEvent,
|
|
1561
|
-
taskId: options.taskId,
|
|
1562
|
-
actor: "system",
|
|
1563
|
-
details: {
|
|
1564
|
-
title: task.title,
|
|
1565
|
-
changes
|
|
1566
|
-
},
|
|
1567
|
-
before: { status: lifecycleBeforeStatus },
|
|
1568
|
-
after: { status: lifecycleAfterStatus }
|
|
1569
|
-
});
|
|
1570
|
-
await tx.appendLog({
|
|
1571
|
-
id: `log-${Math.floor(Date.now() / 1e3)}-${(await import('node:crypto')).randomBytes(3).toString("hex")}`,
|
|
1572
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1573
|
-
action: "task_updated",
|
|
1574
|
-
taskId: options.taskId,
|
|
1575
|
-
actor: "system",
|
|
1576
|
-
details: {
|
|
1577
|
-
changes,
|
|
1578
|
-
title: task.title
|
|
1579
|
-
},
|
|
1580
|
-
before: null,
|
|
1581
|
-
after: {
|
|
1582
|
-
changes,
|
|
1583
|
-
title: task.title
|
|
1584
|
-
}
|
|
1585
|
-
});
|
|
1586
|
-
});
|
|
1587
|
-
return {
|
|
1588
|
-
task,
|
|
1589
|
-
changes
|
|
1590
|
-
};
|
|
1591
|
-
}
|
|
1592
|
-
|
|
1593
|
-
export { updateTask as u };
|
|
1594
|
-
//# sourceMappingURL=update-B2YVBZG0.js.map
|