@cleocode/cleo 2026.9.7 → 2026.9.10
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 +3873 -2234
- 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/{eK8hf4s7.js → BSRBuVG3.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/{DVHIxkgs.js → CLZBEpLY.js} +1 -1
- 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/DX_JOBSO.js +1 -0
- 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/cWVw9W0E.js +3 -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/entry/app.tvu3-wbp.js +2 -0
- package/studio-dist/client/_app/immutable/entry/start.BS-rpdjH.js +1 -0
- package/studio-dist/client/_app/immutable/nodes/{0.CZzEEyVh.js → 0.DMP7swbx.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{1.Bj3Opbua.js → 1.CYZMFpIp.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.Cz1KI9Fv.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{16.mEwy9cqh.js → 16.K9wYQPhb.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{17.DP2QtQGn.js → 17.CtUmdfMg.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{18.Bu0054sX.js → 18.mtosd0sL.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.NJuHLxuS.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.CMuXs5Sy.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/25.DhMBJYAo.js +39 -0
- package/studio-dist/client/_app/immutable/nodes/26.CJ4FA5FS.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.y115j1d5.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-BQvtFOrC.js +41 -0
- package/studio-dist/server/chunks/1-Bx2_yoiK.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-nQTeHGD1.js} +3 -3
- package/studio-dist/server/chunks/{16-De6EzPSa.js → 16-CcTN0e8k.js} +5 -4
- package/studio-dist/server/chunks/{17-CZNsiZhi.js → 17-DWiFnzES.js} +10 -93
- package/studio-dist/server/chunks/{18-CbxxjZox.js → 18-Dcc9GnPo.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-DfQlGHPW.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-EEysaT9T.js +67 -0
- package/studio-dist/server/chunks/{25-CAg6Xcmn.js → 25-CgiYn70L.js} +15 -96
- package/studio-dist/server/chunks/{26-_nfVTvNi.js → 26-Cfd6BaUb.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-E_fWDAkq.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-CL6GfET2.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-tYN7_LXI.js → _page.svelte-B5E6RqVb.js} +9 -11
- package/studio-dist/server/chunks/{_page.svelte-UYiF7YBK.js → _page.svelte-BCRyjlk2.js} +5 -5
- 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-C_VSL8NW.js → _page.svelte-Cgqt7ucn.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-BgwL2Gyu.js → _page.svelte-CvQ2rZZ1.js} +11 -13
- package/studio-dist/server/chunks/{_page.svelte-l4Z_xjl9.js → _page.svelte-CvTyJEyS.js} +9 -11
- package/studio-dist/server/chunks/{_page.svelte-DOWw416I.js → _page.svelte-CvzAttO9.js} +11 -13
- package/studio-dist/server/chunks/{_page.svelte-DYNorA0S.js → _page.svelte-Cx9Ptecp.js} +10 -67
- package/studio-dist/server/chunks/{_page.svelte-Wfx7ww_h.js → _page.svelte-Cx9dPjsT.js} +11 -13
- package/studio-dist/server/chunks/{_page.svelte-2cgtvHwW.js → _page.svelte-DGN5j-At.js} +13 -71
- package/studio-dist/server/chunks/{_page.svelte-BVVTrzTL.js → _page.svelte-DaheDIRs.js} +5 -5
- 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-BIlhmugm.js → _page.svelte-eiomv6Pa.js} +11 -13
- package/studio-dist/server/chunks/{_page.svelte-9OQphlnm.js → _page.svelte-jXJbd8Mx.js} +14 -69
- package/studio-dist/server/chunks/{_page.svelte-CHzXuw2Q.js → _page.svelte-me5SUosG.js} +3 -3
- 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-40h9Y46Y.js +122 -0
- 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-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-BcsqAqXt.js +67 -0
- 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-CH06JVqZ.js +65 -0
- package/studio-dist/server/chunks/_server.ts-CNqcws-M.js +29 -0
- package/studio-dist/server/chunks/{_server.ts-CJA1djzJ.js → _server.ts-CPf8necd.js} +8 -92
- package/studio-dist/server/chunks/{_server.ts-uUx7uT2Y.js → _server.ts-CYv5YuHd.js} +6 -43
- package/studio-dist/server/chunks/{_server.ts-B2E7fxo9.js → _server.ts-CZ5GZRWX.js} +6 -91
- 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-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-BdN4AJ6o.js → _server.ts-VQchZxXq.js} +10 -91
- 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/{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-D71MZ7Vi.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-BzgWhfUR.js +18748 -0
- package/studio-dist/server/chunks/{error.svelte-CplNulnS.js → error.svelte-BIToUowC.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-DPU3HHl2.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-DPnIJYMs.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-BZdYTyl7.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/TX-23QW3.js +0 -3
- 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,2301 +0,0 @@
|
|
|
1
|
-
import { F as getCleoPlatformPaths, W as WHOAMI_ROLE_IDS, o as resolveOrCwd, y as resolveCleoDir } from './paths-CV7S5-Zm.js';
|
|
2
|
-
import { b as runFrontDoorLogin, S as SENTIENT_STATE_FILE } from './local-model-fit2-BMqo6GJm.js';
|
|
3
|
-
import { s as setConfigValue, a as getConfigValue, b as applyStrictnessPreset, l as loadConfig } from './config-DHj9CcFs.js';
|
|
4
|
-
import { b as getCredentialPool, c as addCredential } from './credential-pool-vF6NdtT9.js';
|
|
5
|
-
import { r as resolveProviderDefaultModel, c as catalogKeyForProvider, l as listProviderModels } from './catalog-model-resolver2-Cexk2TN0.js';
|
|
6
|
-
import { dirname, join } from 'node:path';
|
|
7
|
-
import { randomUUID } from 'node:crypto';
|
|
8
|
-
import { readFile, mkdir, writeFile, rename, rm, access } from 'node:fs/promises';
|
|
9
|
-
import { e as err, p as parseJsonBody, i as isParseError, o as ok } from './_lafs-C3_fBF_X.js';
|
|
10
|
-
import { json } from '@sveltejs/kit';
|
|
11
|
-
import { existsSync } from 'node:fs';
|
|
12
|
-
import 'node:os';
|
|
13
|
-
import 'node:events';
|
|
14
|
-
import 'node:diagnostics_channel';
|
|
15
|
-
import 'fs';
|
|
16
|
-
import 'events';
|
|
17
|
-
import 'util';
|
|
18
|
-
import 'path';
|
|
19
|
-
import 'assert';
|
|
20
|
-
import 'worker_threads';
|
|
21
|
-
import 'module';
|
|
22
|
-
import 'node:url';
|
|
23
|
-
import 'url';
|
|
24
|
-
import 'buffer';
|
|
25
|
-
import 'node:module';
|
|
26
|
-
import 'node:child_process';
|
|
27
|
-
import 'node:process';
|
|
28
|
-
import 'node:async_hooks';
|
|
29
|
-
import './chunk-DDP5xfzh.js';
|
|
30
|
-
import './src2-DK8DKufK.js';
|
|
31
|
-
import './branch-lock-Cq7zzmFK.js';
|
|
32
|
-
import './sqlite-Bm5LzbPs.js';
|
|
33
|
-
import './dual-scope-db-DKnWu1KM.js';
|
|
34
|
-
import './indexes-DZ52grq6.js';
|
|
35
|
-
import './utils-BPSZyajG.js';
|
|
36
|
-
import './query-promise-BkPmGPJy.js';
|
|
37
|
-
import './nexus-sqlite2-BBfY2xnY.js';
|
|
38
|
-
import './nexus-schema2-DP0Qd7CA.js';
|
|
39
|
-
import './logger-DQIoyZbq.js';
|
|
40
|
-
import 'node:sqlite';
|
|
41
|
-
import './unique-constraint-BZrrwgwc.js';
|
|
42
|
-
import './lock-CA7d6lj7.js';
|
|
43
|
-
import './index-Dtt_h58T.js';
|
|
44
|
-
import 'constants';
|
|
45
|
-
import 'stream';
|
|
46
|
-
import 'node:util';
|
|
47
|
-
import './index-61916rmV.js';
|
|
48
|
-
import './role-resolver-D9QaDT0e.js';
|
|
49
|
-
import './identity2-DeAB5RXE.js';
|
|
50
|
-
import './json-Bfixam3g.js';
|
|
51
|
-
|
|
52
|
-
/** Default (empty) sentient state for fresh initialisation. */
|
|
53
|
-
var DEFAULT_SENTIENT_STATE = {
|
|
54
|
-
schemaVersion: "1.0",
|
|
55
|
-
pid: null,
|
|
56
|
-
startedAt: null,
|
|
57
|
-
lastTickAt: null,
|
|
58
|
-
lastCronFiredAt: null,
|
|
59
|
-
killSwitch: false,
|
|
60
|
-
killSwitchReason: null,
|
|
61
|
-
pausedByRevert: false,
|
|
62
|
-
revertReceiptId: null,
|
|
63
|
-
stats: {
|
|
64
|
-
tasksPicked: 0,
|
|
65
|
-
tasksCompleted: 0,
|
|
66
|
-
tasksFailed: 0,
|
|
67
|
-
ticksExecuted: 0,
|
|
68
|
-
ticksKilled: 0
|
|
69
|
-
},
|
|
70
|
-
stuckTasks: {},
|
|
71
|
-
stuckTimestamps: [],
|
|
72
|
-
activeTaskId: null,
|
|
73
|
-
tier2Enabled: false,
|
|
74
|
-
tier2Stats: {
|
|
75
|
-
proposalsGenerated: 0,
|
|
76
|
-
proposalsAccepted: 0,
|
|
77
|
-
proposalsRejected: 0
|
|
78
|
-
},
|
|
79
|
-
tier3Enabled: false,
|
|
80
|
-
tier3LastTickAt: null,
|
|
81
|
-
tier3Stats: {
|
|
82
|
-
ticksKilled: 0,
|
|
83
|
-
abortsTotal: 0,
|
|
84
|
-
mergesCompleted: 0
|
|
85
|
-
},
|
|
86
|
-
hygieneLastRunAt: null,
|
|
87
|
-
hygieneSummary: null,
|
|
88
|
-
hygieneStats: {
|
|
89
|
-
projectsChecked: 0,
|
|
90
|
-
projectsHealthy: 0,
|
|
91
|
-
tempGcCandidates: 0,
|
|
92
|
-
duplicateEpicGroups: 0,
|
|
93
|
-
worktreesPruned: 0
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Read the sentient state from disk.
|
|
98
|
-
*
|
|
99
|
-
* Returns the default state if the file does not exist or is malformed.
|
|
100
|
-
* Never throws — absence is not an error.
|
|
101
|
-
*
|
|
102
|
-
* @param statePath - Absolute path to sentient-state.json
|
|
103
|
-
*/
|
|
104
|
-
async function readSentientState(statePath) {
|
|
105
|
-
try {
|
|
106
|
-
const raw = await readFile(statePath, "utf-8");
|
|
107
|
-
const parsed = JSON.parse(raw);
|
|
108
|
-
return {
|
|
109
|
-
...DEFAULT_SENTIENT_STATE,
|
|
110
|
-
...parsed,
|
|
111
|
-
stats: {
|
|
112
|
-
...DEFAULT_SENTIENT_STATE.stats,
|
|
113
|
-
...parsed.stats ?? {}
|
|
114
|
-
},
|
|
115
|
-
stuckTasks: parsed.stuckTasks ?? {},
|
|
116
|
-
stuckTimestamps: parsed.stuckTimestamps ?? [],
|
|
117
|
-
tier2Enabled: parsed.tier2Enabled ?? false,
|
|
118
|
-
tier2Stats: {
|
|
119
|
-
...DEFAULT_SENTIENT_STATE.tier2Stats,
|
|
120
|
-
...parsed.tier2Stats ?? {}
|
|
121
|
-
},
|
|
122
|
-
pausedByRevert: parsed.pausedByRevert ?? false,
|
|
123
|
-
revertReceiptId: parsed.revertReceiptId ?? null,
|
|
124
|
-
tier3Enabled: parsed.tier3Enabled ?? false,
|
|
125
|
-
tier3LastTickAt: parsed.tier3LastTickAt ?? null,
|
|
126
|
-
tier3Stats: {
|
|
127
|
-
...DEFAULT_SENTIENT_STATE.tier3Stats,
|
|
128
|
-
...parsed.tier3Stats ?? {}
|
|
129
|
-
},
|
|
130
|
-
hygieneLastRunAt: parsed.hygieneLastRunAt ?? null,
|
|
131
|
-
hygieneSummary: parsed.hygieneSummary ?? null,
|
|
132
|
-
hygieneStats: {
|
|
133
|
-
...DEFAULT_SENTIENT_STATE.hygieneStats,
|
|
134
|
-
...parsed.hygieneStats ?? {}
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
} catch {
|
|
138
|
-
return { ...DEFAULT_SENTIENT_STATE };
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Write the sentient state to disk atomically via tmp-then-rename.
|
|
143
|
-
*
|
|
144
|
-
* Atomic write prevents partial reads if the daemon crashes mid-write.
|
|
145
|
-
*
|
|
146
|
-
* @param statePath - Absolute path to sentient-state.json
|
|
147
|
-
* @param state - State to persist
|
|
148
|
-
*/
|
|
149
|
-
async function writeSentientState(statePath, state) {
|
|
150
|
-
const dir = dirname(statePath);
|
|
151
|
-
await mkdir(dir, { recursive: true });
|
|
152
|
-
const tmpPath = join(dir, `.sentient-state-${`${process.pid}-${randomUUID()}`}.tmp`);
|
|
153
|
-
await writeFile(tmpPath, JSON.stringify(state, null, 2), "utf-8");
|
|
154
|
-
try {
|
|
155
|
-
await rename(tmpPath, statePath);
|
|
156
|
-
} catch (err) {
|
|
157
|
-
await rm(tmpPath, { force: true }).catch(() => {});
|
|
158
|
-
throw err;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Patch a subset of fields in the sentient state file.
|
|
163
|
-
*
|
|
164
|
-
* Reads current state, merges patch, writes back. Nested `stats` merges
|
|
165
|
-
* with existing stats (never clobbered wholesale).
|
|
166
|
-
*
|
|
167
|
-
* @param statePath - Absolute path to sentient-state.json
|
|
168
|
-
* @param patch - Partial state to merge over the existing state
|
|
169
|
-
* @returns The merged state that was written to disk.
|
|
170
|
-
*/
|
|
171
|
-
async function patchSentientState(statePath, patch) {
|
|
172
|
-
const current = await readSentientState(statePath);
|
|
173
|
-
const updated = {
|
|
174
|
-
...current,
|
|
175
|
-
...patch,
|
|
176
|
-
stats: {
|
|
177
|
-
...current.stats,
|
|
178
|
-
...patch.stats ?? {}
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
await writeSentientState(statePath, updated);
|
|
182
|
-
return updated;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
//#region ../core/dist/setup/sections/brain.js
|
|
186
|
-
/**
|
|
187
|
-
* `brain` setup wizard section (E-CONFIG-AUTH-UNIFY E3 / T9425).
|
|
188
|
-
*
|
|
189
|
-
* Controls how BRAIN context is surfaced inside AGENTS.md by toggling
|
|
190
|
-
* `brain.memoryBridge.mode` across three operator-visible values:
|
|
191
|
-
*
|
|
192
|
-
* - `'digest'` — AGENTS.md gets a `cleo memory digest` directive
|
|
193
|
-
* (no `.cleo/memory-bridge.md` written). Wire value stays
|
|
194
|
-
* `'cli'` so existing project configs continue to resolve
|
|
195
|
-
* correctly; the wizard label was renamed to "digest" to
|
|
196
|
-
* match the user-facing CLI command.
|
|
197
|
-
* - `'file'` — Legacy behaviour: write `.cleo/memory-bridge.md` and
|
|
198
|
-
* `.cleo/nexus-bridge.md` so they get `@`-injected.
|
|
199
|
-
* - `'disabled'` — Suppress BRAIN-driven AGENTS.md augmentation entirely.
|
|
200
|
-
*
|
|
201
|
-
* V2 additions (T9610):
|
|
202
|
-
* - `isConfigured()` — returns `true` when `brain.memoryBridge.mode` is set (BRAIN-6).
|
|
203
|
-
* - Retention days prompt (BRAIN-3).
|
|
204
|
-
* - Embedding toggle prompt (BRAIN-4).
|
|
205
|
-
* - Displays current bridge mode, embedding state, and retention days (BRAIN-1).
|
|
206
|
-
* - Section description printed before prompts (GEN-6).
|
|
207
|
-
*
|
|
208
|
-
* Non-interactive contract:
|
|
209
|
-
* - `options.nonInteractive === true` + `options.brainBridgeMode` →
|
|
210
|
-
* persist that value; no prompts.
|
|
211
|
-
* - Missing `--brain-bridge-mode` under `--non-interactive` →
|
|
212
|
-
* section short-circuits with error.
|
|
213
|
-
*
|
|
214
|
-
* @task T9425
|
|
215
|
-
* @task T9610
|
|
216
|
-
* @epic T9402
|
|
217
|
-
* @epic T9591
|
|
218
|
-
* @see docs/plans/E-CLEO-SETUP-V2.md §4.6 (BRAIN-1 through BRAIN-6)
|
|
219
|
-
* @see docs/plans/E-CONFIG-AUTH-UNIFY.md §5.3 T-E3-6
|
|
220
|
-
*/
|
|
221
|
-
/**
|
|
222
|
-
* Operator-facing mode labels the wizard offers.
|
|
223
|
-
*
|
|
224
|
-
* `'digest'` is a label-only synonym for the on-disk `'cli'` mode — see the
|
|
225
|
-
* file-level doc comment for the rationale. The wizard normalises every
|
|
226
|
-
* answer through {@link toWireMode} before persisting.
|
|
227
|
-
*/
|
|
228
|
-
var WIZARD_MODE_CHOICES = [
|
|
229
|
-
"digest",
|
|
230
|
-
"file",
|
|
231
|
-
"disabled"
|
|
232
|
-
];
|
|
233
|
-
/**
|
|
234
|
-
* Translate an operator-facing label to the wire value persisted into
|
|
235
|
-
* `brain.memoryBridge.mode`.
|
|
236
|
-
*
|
|
237
|
-
* Keeps existing project configs (which use `'cli'`) functioning unchanged
|
|
238
|
-
* while exposing the more discoverable `'digest'` label to operators.
|
|
239
|
-
*
|
|
240
|
-
* @internal
|
|
241
|
-
*/
|
|
242
|
-
function toWireMode(label) {
|
|
243
|
-
switch (label) {
|
|
244
|
-
case "digest": return "cli";
|
|
245
|
-
case "file": return "file";
|
|
246
|
-
case "disabled": return "disabled";
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Translate the on-disk wire value back to its operator-facing label so
|
|
251
|
-
* the wizard can echo the current state without confusing the user with
|
|
252
|
-
* `'cli'`.
|
|
253
|
-
*
|
|
254
|
-
* @internal
|
|
255
|
-
*/
|
|
256
|
-
function fromWireMode(mode) {
|
|
257
|
-
switch (mode) {
|
|
258
|
-
case "file": return "file";
|
|
259
|
-
case "disabled": return "disabled";
|
|
260
|
-
default: return "digest";
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Parse retention days from a string input, returning the numeric value or
|
|
265
|
-
* `null` if the input is invalid.
|
|
266
|
-
*
|
|
267
|
-
* Valid input: non-negative integer (0 = forever).
|
|
268
|
-
*
|
|
269
|
-
* @param raw - String to parse.
|
|
270
|
-
* @returns Parsed non-negative integer or `null` on invalid input.
|
|
271
|
-
* @internal
|
|
272
|
-
*/
|
|
273
|
-
function parseRetentionDays(raw) {
|
|
274
|
-
if (raw.trim() === "") return 0;
|
|
275
|
-
const n = Number(raw.trim());
|
|
276
|
-
if (!Number.isInteger(n) || n < 0 || !Number.isFinite(n)) return null;
|
|
277
|
-
return n;
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Build the `brain` section runner.
|
|
281
|
-
*
|
|
282
|
-
* @returns A {@link WizardSectionRunner} for the BRAIN section.
|
|
283
|
-
* @task T9425
|
|
284
|
-
* @task T9610
|
|
285
|
-
*/
|
|
286
|
-
function createBrainSection() {
|
|
287
|
-
return {
|
|
288
|
-
section: "brain",
|
|
289
|
-
title: "BRAIN memory bridge (digest|file|disabled)",
|
|
290
|
-
optional: true,
|
|
291
|
-
async isConfigured(options) {
|
|
292
|
-
const resolved = await getConfigValue("brain.memoryBridge.mode", options.projectRoot);
|
|
293
|
-
return resolved.source !== "default" && resolved.value !== void 0;
|
|
294
|
-
},
|
|
295
|
-
async run(io, options) {
|
|
296
|
-
io.info("Configures the BRAIN memory bridge mode, retention policy, and embedding index.\nSettings are stored in the global config (~/.cleo/config.json).\n\"digest\" mode injects a live memory digest; \"file\" mode writes static bridge files.");
|
|
297
|
-
const resolved = await getConfigValue("brain.memoryBridge.mode", options.projectRoot);
|
|
298
|
-
const currentLabel = fromWireMode(resolved.value);
|
|
299
|
-
io.info(`Current BRAIN bridge mode: ${currentLabel} (source: ${resolved.source})`);
|
|
300
|
-
const embeddingResolved = await getConfigValue("brain.embedding.enabled", options.projectRoot);
|
|
301
|
-
const embeddingEnabled = embeddingResolved.value ?? false;
|
|
302
|
-
io.info(`Current BRAIN embedding index: ${embeddingEnabled ? "enabled" : "disabled"} (source: ${embeddingResolved.source})`);
|
|
303
|
-
const retentionResolved = await getConfigValue("brain.retention.days", options.projectRoot);
|
|
304
|
-
const retentionDays = retentionResolved.value ?? 0;
|
|
305
|
-
io.info(`Current BRAIN retention: ${retentionDays === 0 ? "forever (0)" : `${retentionDays} days`} (source: ${retentionResolved.source})`);
|
|
306
|
-
let choice;
|
|
307
|
-
let chosenRetentionDays;
|
|
308
|
-
let chosenEmbeddingEnabled;
|
|
309
|
-
if (options.nonInteractive === true) {
|
|
310
|
-
if (!options.brainBridgeMode) throw new Error("E_SETUP_MISSING_FLAG: --section brain --non-interactive requires --brain-bridge-mode <digest|file|disabled>");
|
|
311
|
-
choice = options.brainBridgeMode;
|
|
312
|
-
if (options.brainRetentionDays !== void 0) chosenRetentionDays = options.brainRetentionDays;
|
|
313
|
-
if (options.brainEmbeddingEnabled !== void 0) chosenEmbeddingEnabled = options.brainEmbeddingEnabled;
|
|
314
|
-
} else {
|
|
315
|
-
choice = await io.select("Pick BRAIN memory bridge mode (digest|file|disabled)", WIZARD_MODE_CHOICES);
|
|
316
|
-
let validRetention = false;
|
|
317
|
-
while (!validRetention) {
|
|
318
|
-
const rawDays = await io.prompt("How long should BRAIN retain memory entries? [days, 0 = forever, default 0]");
|
|
319
|
-
const parsed = parseRetentionDays(rawDays);
|
|
320
|
-
if (parsed === null) io.warn(`Invalid value '${rawDays}' — must be a non-negative integer. Try again.`);
|
|
321
|
-
else {
|
|
322
|
-
chosenRetentionDays = parsed;
|
|
323
|
-
validRetention = true;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
chosenEmbeddingEnabled = await io.confirm("Enable BRAIN embedding index (enables semantic search, requires local disk)?", true);
|
|
327
|
-
}
|
|
328
|
-
await setConfigValue("brain.memoryBridge.mode", toWireMode(choice), options.projectRoot, { global: true });
|
|
329
|
-
const fragments = [`set brain.memoryBridge.mode=${choice} (was ${currentLabel})`];
|
|
330
|
-
if (chosenRetentionDays !== void 0) {
|
|
331
|
-
await setConfigValue("brain.retention.days", chosenRetentionDays, options.projectRoot, { global: true });
|
|
332
|
-
fragments.push(`set brain.retention.days=${chosenRetentionDays === 0 ? "forever (0)" : chosenRetentionDays}`);
|
|
333
|
-
}
|
|
334
|
-
if (chosenEmbeddingEnabled !== void 0) {
|
|
335
|
-
await setConfigValue("brain.embedding.enabled", chosenEmbeddingEnabled, options.projectRoot, { global: true });
|
|
336
|
-
fragments.push(`set brain.embedding.enabled=${chosenEmbeddingEnabled}`);
|
|
337
|
-
}
|
|
338
|
-
return {
|
|
339
|
-
changed: true,
|
|
340
|
-
summary: fragments.join(" + ")
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
//#endregion
|
|
346
|
-
//#region ../core/dist/setup/sections/harness.js
|
|
347
|
-
/**
|
|
348
|
-
* `harness` setup wizard section (E-CONFIG-AUTH-UNIFY E3 / T9425).
|
|
349
|
-
*
|
|
350
|
-
* Captures which harness CLEO should consider "active" for spawn-prompt
|
|
351
|
-
* resolution and status reporting. Two operator-visible values are
|
|
352
|
-
* accepted today:
|
|
353
|
-
* - `'pi'` — the native CLEO Pi binary harness (default for
|
|
354
|
-
* headless installs and Docker tasks).
|
|
355
|
-
* - `'claude-code'` — Claude Code CLI as the harness (auto-injects
|
|
356
|
-
* `AGENTS.md`, triggers tier-1 dedup).
|
|
357
|
-
*
|
|
358
|
-
* V2 additions (T9610):
|
|
359
|
-
* - `isConfigured()` — returns `true` when `harness.active` is set (HARN-6).
|
|
360
|
-
* - Pi URL prompt when `pi` is selected (HARN-3).
|
|
361
|
-
* - Claude Code note when `claude-code` is selected (HARN-4).
|
|
362
|
-
* - Section description printed before prompts (GEN-6).
|
|
363
|
-
*
|
|
364
|
-
* The wizard surfaces the *currently active* harness from `CLEO_HARNESS`
|
|
365
|
-
* (falling back to `'unknown'` — mirrors `packages/core/src/status/index.ts`)
|
|
366
|
-
* and then asks the operator to pick the canonical value. The selection
|
|
367
|
-
* lands in the **global** config under `harness.active` via
|
|
368
|
-
* {@link setConfigValue} — the same scope `identity` uses for `agent.name`
|
|
369
|
-
* so the choice persists across projects without leaking into per-project
|
|
370
|
-
* configs.
|
|
371
|
-
*
|
|
372
|
-
* Non-interactive contract:
|
|
373
|
-
* - `options.nonInteractive === true` + `options.harness` →
|
|
374
|
-
* persist that value to global config; no prompts.
|
|
375
|
-
* - Missing `--harness` under `--non-interactive` →
|
|
376
|
-
* section short-circuits with error.
|
|
377
|
-
*
|
|
378
|
-
* @task T9425
|
|
379
|
-
* @task T9610
|
|
380
|
-
* @epic T9402
|
|
381
|
-
* @epic T9591
|
|
382
|
-
* @see docs/plans/E-CLEO-SETUP-V2.md §4.5 (HARN-1 through HARN-6)
|
|
383
|
-
* @see docs/plans/E-CONFIG-AUTH-UNIFY.md §5.3 T-E3-6
|
|
384
|
-
*/
|
|
385
|
-
/**
|
|
386
|
-
* Default Pi process URL (HARN-3).
|
|
387
|
-
*
|
|
388
|
-
* Used as the default when prompting for the Pi URL.
|
|
389
|
-
*/
|
|
390
|
-
var DEFAULT_PI_URL = "http://localhost:7800";
|
|
391
|
-
/**
|
|
392
|
-
* Allowed harness values the wizard offers + persists.
|
|
393
|
-
*
|
|
394
|
-
* Kept aligned with {@link CleoStatus.harness.active} so any value written
|
|
395
|
-
* here round-trips cleanly through `cleo status`.
|
|
396
|
-
*/
|
|
397
|
-
var HARNESS_CHOICES = ["pi", "claude-code"];
|
|
398
|
-
/**
|
|
399
|
-
* Validate a URL string is a valid HTTP(S) URL.
|
|
400
|
-
*
|
|
401
|
-
* Used for Pi URL validation per HARN-3.
|
|
402
|
-
*
|
|
403
|
-
* @param raw - String to validate.
|
|
404
|
-
* @returns `true` when the string is a valid HTTP or HTTPS URL.
|
|
405
|
-
* @internal
|
|
406
|
-
*/
|
|
407
|
-
function isValidHttpUrl$1(raw) {
|
|
408
|
-
try {
|
|
409
|
-
const url = new URL(raw);
|
|
410
|
-
return url.protocol === "http:" || url.protocol === "https:";
|
|
411
|
-
} catch {
|
|
412
|
-
return false;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Build the `harness` section runner.
|
|
417
|
-
*
|
|
418
|
-
* @returns A {@link WizardSectionRunner} for the harness section.
|
|
419
|
-
* @task T9425
|
|
420
|
-
* @task T9610
|
|
421
|
-
*/
|
|
422
|
-
function createHarnessSection() {
|
|
423
|
-
return {
|
|
424
|
-
section: "harness",
|
|
425
|
-
title: "Active harness (Pi vs Claude Code)",
|
|
426
|
-
optional: true,
|
|
427
|
-
async isConfigured(options) {
|
|
428
|
-
const resolved = await getConfigValue("harness.active", options.projectRoot);
|
|
429
|
-
return typeof resolved.value === "string" && resolved.value.trim().length > 0;
|
|
430
|
-
},
|
|
431
|
-
async run(io, options) {
|
|
432
|
-
io.info("Configures the active harness written to `harness.active` in the global config.\nPi harness is recommended for headless/Docker environments.\nClaude Code harness auto-injects AGENTS.md and triggers tier-1 dedup.");
|
|
433
|
-
const current = readActiveHarness();
|
|
434
|
-
io.info(`Current harness: ${current}`);
|
|
435
|
-
let choice;
|
|
436
|
-
if (options.nonInteractive === true) {
|
|
437
|
-
if (!options.harness) throw new Error("E_SETUP_MISSING_FLAG: --section harness --non-interactive requires --harness <pi|claude-code>");
|
|
438
|
-
choice = options.harness;
|
|
439
|
-
} else choice = await io.select("Pick the active harness (pi|claude-code)", HARNESS_CHOICES);
|
|
440
|
-
await setConfigValue("harness.active", choice, options.projectRoot, { global: true });
|
|
441
|
-
const fragments = [`set harness.active=${choice} (was ${current})`];
|
|
442
|
-
if (choice === "pi") if (options.nonInteractive === true) io.info(`Pi URL defaults to ${DEFAULT_PI_URL}. Set CLEO_PI_URL or run 'cleo setup --section harness' to change.`);
|
|
443
|
-
else {
|
|
444
|
-
const currentPiUrl = await getConfigValue("harness.piUrl", options.projectRoot);
|
|
445
|
-
const piUrlDefault = typeof currentPiUrl.value === "string" && currentPiUrl.value.trim().length > 0 ? currentPiUrl.value : DEFAULT_PI_URL;
|
|
446
|
-
io.info(`Current Pi URL: ${piUrlDefault}`);
|
|
447
|
-
const rawPiUrl = (await io.prompt(`Pi process URL [default: ${piUrlDefault}]:`)).trim();
|
|
448
|
-
const piUrl = rawPiUrl === "" ? piUrlDefault : rawPiUrl;
|
|
449
|
-
if (!isValidHttpUrl$1(piUrl)) {
|
|
450
|
-
io.warn(`Invalid Pi URL '${piUrl}' — must be a valid HTTP(S) URL. Using default: ${piUrlDefault}`);
|
|
451
|
-
await setConfigValue("harness.piUrl", piUrlDefault, options.projectRoot, { global: true });
|
|
452
|
-
fragments.push(`set harness.piUrl=${piUrlDefault} (invalid input, used default)`);
|
|
453
|
-
} else {
|
|
454
|
-
await setConfigValue("harness.piUrl", piUrl, options.projectRoot, { global: true });
|
|
455
|
-
fragments.push(`set harness.piUrl=${piUrl}`);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
if (choice === "claude-code") io.info("Ensure `claude` is on your PATH. Run `cleo harness doctor` to verify.");
|
|
459
|
-
return {
|
|
460
|
-
changed: true,
|
|
461
|
-
summary: fragments.join(" + ")
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Read the active harness for display purposes using the same layered chain as
|
|
468
|
-
* {@link detectHarness} in `packages/core/src/status/index.ts`.
|
|
469
|
-
*
|
|
470
|
-
* Synchronous (reads env only; skips the async global-config layer) so the
|
|
471
|
-
* wizard can call it without `await` before the prompt is shown. The
|
|
472
|
-
* full async chain runs at status-snapshot time via `cleo status`.
|
|
473
|
-
*
|
|
474
|
-
* Resolution order (first match wins):
|
|
475
|
-
* 1. `CLEO_HARNESS` env var — explicit override.
|
|
476
|
-
* 2. `CLAUDECODE=1` → `'claude-code'`.
|
|
477
|
-
* 3. `CLEO_PI=1` → `'pi'`.
|
|
478
|
-
* 4. Fallback: `'unknown'`.
|
|
479
|
-
*
|
|
480
|
-
* @internal
|
|
481
|
-
*/
|
|
482
|
-
function readActiveHarness() {
|
|
483
|
-
const raw = process.env["CLEO_HARNESS"];
|
|
484
|
-
if (raw === "pi" || raw === "claude-code") return raw;
|
|
485
|
-
if (process.env["CLAUDECODE"] === "1") return "claude-code";
|
|
486
|
-
if (process.env["CLEO_PI"] === "1") return "pi";
|
|
487
|
-
return "unknown";
|
|
488
|
-
}
|
|
489
|
-
//#endregion
|
|
490
|
-
//#region ../core/dist/setup/sections/identity.js
|
|
491
|
-
/**
|
|
492
|
-
* `identity` setup wizard section (E-CONFIG-AUTH-UNIFY E3 / T9420).
|
|
493
|
-
*
|
|
494
|
-
* Captures the operator-visible agent display name and (optionally)
|
|
495
|
-
* a SOUL.md persona block. Both pieces are stored away from secrets:
|
|
496
|
-
* - `agent.name` lands in the global config via `setConfigValue`.
|
|
497
|
-
* - SOUL.md content lands in `<projectRoot>/.cleo/SOUL.md` so it is
|
|
498
|
-
* scoped to the current project. Future Studio/CLI surfaces can
|
|
499
|
-
* read it via the standard config layer.
|
|
500
|
-
*
|
|
501
|
-
* V2 additions (T9610):
|
|
502
|
-
* - `isConfigured()` — returns `true` when `agent.name` is already set.
|
|
503
|
-
* - Current-value display before prompting (GEN-7).
|
|
504
|
-
* - SignalDock registration note (IDENT-5).
|
|
505
|
-
* - Section description printed before prompts (GEN-6).
|
|
506
|
-
*
|
|
507
|
-
* Non-interactive contract:
|
|
508
|
-
* - `options.nonInteractive === true` + `options.agentName` →
|
|
509
|
-
* writes the name and (optionally) SOUL.md content; no prompts.
|
|
510
|
-
* - Missing `--agent-name` under `--non-interactive` →
|
|
511
|
-
* section short-circuits silently (`changed: false`).
|
|
512
|
-
*
|
|
513
|
-
* @task T9420
|
|
514
|
-
* @task T9610
|
|
515
|
-
* @epic T9402
|
|
516
|
-
* @epic T9591
|
|
517
|
-
* @see docs/plans/E-CLEO-SETUP-V2.md §4.2
|
|
518
|
-
*/
|
|
519
|
-
/** Relative path inside `.cleo/` where SOUL.md is persisted. */
|
|
520
|
-
var SOUL_RELATIVE_PATH = "SOUL.md";
|
|
521
|
-
/**
|
|
522
|
-
* Build the `identity` section runner.
|
|
523
|
-
*
|
|
524
|
-
* @returns A {@link WizardSectionRunner} for the identity section.
|
|
525
|
-
* @task T9420
|
|
526
|
-
* @task T9610
|
|
527
|
-
*/
|
|
528
|
-
function createIdentitySection() {
|
|
529
|
-
return {
|
|
530
|
-
section: "identity",
|
|
531
|
-
title: "Agent identity (name + optional SOUL.md persona)",
|
|
532
|
-
optional: true,
|
|
533
|
-
async isConfigured(options) {
|
|
534
|
-
const resolved = await getConfigValue("agent.name", options.projectRoot);
|
|
535
|
-
return typeof resolved.value === "string" && resolved.value.trim().length > 0;
|
|
536
|
-
},
|
|
537
|
-
async run(io, options) {
|
|
538
|
-
io.info("Configures the agent display name written to `agent.name` in the global config\nand an optional SOUL.md persona block scoped to this project (.cleo/SOUL.md).\nSignalDock identity registration is prompted at the end of this section.");
|
|
539
|
-
const currentName = await getConfigValue("agent.name", options.projectRoot);
|
|
540
|
-
if (typeof currentName.value === "string" && currentName.value.trim().length > 0) io.info(`Current agent name: ${currentName.value} (source: ${currentName.source})`);
|
|
541
|
-
else io.info("Current agent name: (not set)");
|
|
542
|
-
if (options.nonInteractive === true) {
|
|
543
|
-
if (!options.agentName) return {
|
|
544
|
-
changed: false,
|
|
545
|
-
summary: "skipped (non-interactive: --agent-name required)"
|
|
546
|
-
};
|
|
547
|
-
const writes = await applyIdentity(options.agentName, options.soulMdContent ?? null, options.projectRoot);
|
|
548
|
-
if (options.signaldockAutoConnect === true) io.info("To register a SignalDock identity, run: cleo signaldock connect");
|
|
549
|
-
return summariseWrites(writes);
|
|
550
|
-
}
|
|
551
|
-
const name = (await io.prompt("Agent display name (e.g. \"Atlas\")")).trim();
|
|
552
|
-
if (name === "") {
|
|
553
|
-
io.info("No name supplied — leaving identity unchanged.");
|
|
554
|
-
return {
|
|
555
|
-
changed: false,
|
|
556
|
-
summary: "skipped (no name provided)"
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
|
-
let soulContent = null;
|
|
560
|
-
if (await io.confirm("Add a SOUL.md persona block now?", false)) {
|
|
561
|
-
const entered = (await io.prompt("Paste SOUL.md content (single line ok):")).trim();
|
|
562
|
-
soulContent = entered === "" ? null : entered;
|
|
563
|
-
}
|
|
564
|
-
if (await io.confirm("Register a SignalDock identity for this agent?", false)) io.info("To register a SignalDock identity, run: cleo signaldock connect");
|
|
565
|
-
return summariseWrites(await applyIdentity(name, soulContent, options.projectRoot));
|
|
566
|
-
}
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
/**
|
|
570
|
-
* Apply identity writes to disk.
|
|
571
|
-
*
|
|
572
|
-
* Routed through {@link setConfigValue} (global scope) for the name and
|
|
573
|
-
* through a direct atomic file write for SOUL.md. Both writes are best-effort
|
|
574
|
-
* — caller of {@link createIdentitySection} surfaces failures via
|
|
575
|
-
* {@link WizardIO.error} through the {@link WizardRunner} guard.
|
|
576
|
-
*
|
|
577
|
-
* @internal
|
|
578
|
-
*/
|
|
579
|
-
async function applyIdentity(name, soulContent, projectRoot) {
|
|
580
|
-
await setConfigValue("agent.name", name, projectRoot, { global: true });
|
|
581
|
-
let soulPath = null;
|
|
582
|
-
if (soulContent && soulContent.length > 0) {
|
|
583
|
-
soulPath = join(resolveCleoDir(projectRoot), SOUL_RELATIVE_PATH);
|
|
584
|
-
await mkdir(dirname(soulPath), { recursive: true });
|
|
585
|
-
await writeFile(soulPath, soulContent.endsWith("\n") ? soulContent : `${soulContent}\n`, {
|
|
586
|
-
encoding: "utf-8",
|
|
587
|
-
mode: 420
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
return {
|
|
591
|
-
nameWritten: true,
|
|
592
|
-
soulPath
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* Compose a single-line summary from the {@link applyIdentity} write report.
|
|
597
|
-
*
|
|
598
|
-
* @internal
|
|
599
|
-
*/
|
|
600
|
-
function summariseWrites(writes) {
|
|
601
|
-
const fragments = [];
|
|
602
|
-
if (writes.nameWritten) fragments.push("set agent.name");
|
|
603
|
-
if (writes.soulPath !== null) fragments.push(`wrote ${writes.soulPath}`);
|
|
604
|
-
return {
|
|
605
|
-
changed: fragments.length > 0,
|
|
606
|
-
summary: fragments.length > 0 ? fragments.join(" + ") : "no changes"
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
//#endregion
|
|
610
|
-
//#region ../core/dist/setup/sections/integrations.js
|
|
611
|
-
/**
|
|
612
|
-
* `integrations` setup wizard section (E-CLEO-SETUP-V2 / T9608).
|
|
613
|
-
*
|
|
614
|
-
* Captures operator intent for three integration subsystems:
|
|
615
|
-
*
|
|
616
|
-
* 1. **SignalDock** — the cloud messaging transport.
|
|
617
|
-
* - `signaldock.enabled` (global config, boolean)
|
|
618
|
-
* - `signaldock.endpoint` (global config, string — defaults to
|
|
619
|
-
* `http://localhost:4000` when not supplied)
|
|
620
|
-
*
|
|
621
|
-
* 2. **Studio** — the local web UI.
|
|
622
|
-
* - `studio.enabled` (global config, boolean)
|
|
623
|
-
* - After enabling, the section emits: "Start Studio with `cleo studio start`."
|
|
624
|
-
*
|
|
625
|
-
* 3. **Conduit** — the local message-bus DB.
|
|
626
|
-
* - `conduit.dbPath` (project config, string — must be an absolute path)
|
|
627
|
-
* - Blank input ⇒ the built-in default is used; nothing is persisted.
|
|
628
|
-
*
|
|
629
|
-
* The section emits the current state of all three subsystems before
|
|
630
|
-
* prompting so operators can confirm idempotently.
|
|
631
|
-
*
|
|
632
|
-
* No network calls are made inside this section — connectivity validation
|
|
633
|
-
* is delegated to the `verification` section (T9594).
|
|
634
|
-
*
|
|
635
|
-
* Non-interactive contract (INTG-5):
|
|
636
|
-
* - `options.nonInteractive === true` → apply each of
|
|
637
|
-
* `signaldockEnabled`, `signaldockEndpoint`, `studioEnabled`, and
|
|
638
|
-
* `conduitPath` when present; fields not supplied are left untouched.
|
|
639
|
-
* - All four absent under non-interactive → short-circuit silently.
|
|
640
|
-
*
|
|
641
|
-
* `isConfigured()` (INTG-6):
|
|
642
|
-
* - Returns `true` when `signaldock.enabled` is **explicitly set** in
|
|
643
|
-
* the global config (even when the stored value is `false`), because
|
|
644
|
-
* an explicit `false` means the operator intentionally disabled it.
|
|
645
|
-
*
|
|
646
|
-
* @task T9608
|
|
647
|
-
* @epic T9591
|
|
648
|
-
* @see docs/plans/E-CLEO-SETUP-V2.md §4.8, §5.2 T9593
|
|
649
|
-
*/
|
|
650
|
-
/** Default SignalDock endpoint shown to the operator. */
|
|
651
|
-
var DEFAULT_SIGNALDOCK_ENDPOINT = "http://localhost:4000";
|
|
652
|
-
/**
|
|
653
|
-
* Validate that `url` is an HTTP or HTTPS URL.
|
|
654
|
-
*
|
|
655
|
-
* Used to guard the SignalDock endpoint prompt — the section MUST NOT
|
|
656
|
-
* make network calls (INTG-7), so only syntactic validation is performed.
|
|
657
|
-
*
|
|
658
|
-
* @param url - Raw user input to validate.
|
|
659
|
-
* @returns `true` when `url` is a valid HTTP(S) URL.
|
|
660
|
-
* @internal
|
|
661
|
-
*/
|
|
662
|
-
function isValidHttpUrl(url) {
|
|
663
|
-
try {
|
|
664
|
-
const parsed = new URL(url);
|
|
665
|
-
return parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
666
|
-
} catch {
|
|
667
|
-
return false;
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
/**
|
|
671
|
-
* Validate that `path` is an absolute filesystem path.
|
|
672
|
-
*
|
|
673
|
-
* @param p - Raw user input to validate.
|
|
674
|
-
* @returns `true` when `p` starts with `/` (Unix absolute path).
|
|
675
|
-
* @internal
|
|
676
|
-
*/
|
|
677
|
-
function isAbsolutePath(p) {
|
|
678
|
-
return p.startsWith("/");
|
|
679
|
-
}
|
|
680
|
-
/**
|
|
681
|
-
* Build the `integrations` section runner.
|
|
682
|
-
*
|
|
683
|
-
* @returns A {@link WizardSectionRunner} for the integrations section.
|
|
684
|
-
* @task T9608
|
|
685
|
-
*/
|
|
686
|
-
function createIntegrationsSection() {
|
|
687
|
-
return {
|
|
688
|
-
section: "integrations",
|
|
689
|
-
title: "Integrations (SignalDock + Studio + Conduit)",
|
|
690
|
-
optional: true,
|
|
691
|
-
async isConfigured(options) {
|
|
692
|
-
const resolved = await getConfigValue("signaldock.enabled", options.projectRoot);
|
|
693
|
-
return resolved.source !== "default" && resolved.value !== void 0;
|
|
694
|
-
},
|
|
695
|
-
async run(io, options) {
|
|
696
|
-
const [sdEnabled, sdEndpoint, stEnabled] = await Promise.all([
|
|
697
|
-
getConfigValue("signaldock.enabled", options.projectRoot),
|
|
698
|
-
getConfigValue("signaldock.endpoint", options.projectRoot),
|
|
699
|
-
getConfigValue("studio.enabled", options.projectRoot)
|
|
700
|
-
]);
|
|
701
|
-
const sdEnabledLabel = sdEnabled.value === void 0 ? "not set" : String(sdEnabled.value);
|
|
702
|
-
const sdEndpointLabel = sdEndpoint.value ?? "(default)";
|
|
703
|
-
const stEnabledLabel = stEnabled.value === void 0 ? "not set" : String(stEnabled.value);
|
|
704
|
-
io.info(`Current integrations state:\n signaldock.enabled = ${sdEnabledLabel} (source: ${sdEnabled.source})\n signaldock.endpoint = ${sdEndpointLabel} (source: ${sdEndpoint.source})\n studio.enabled = ${stEnabledLabel} (source: ${stEnabled.source})`);
|
|
705
|
-
const fragments = [];
|
|
706
|
-
if (options.nonInteractive === true) {
|
|
707
|
-
const { signaldockEnabled, signaldockEndpoint, studioEnabled, conduitPath } = options;
|
|
708
|
-
if (signaldockEnabled === void 0 && signaldockEndpoint === void 0 && studioEnabled === void 0 && conduitPath === void 0) return {
|
|
709
|
-
changed: false,
|
|
710
|
-
summary: "skipped (non-interactive: no integrations flags supplied)"
|
|
711
|
-
};
|
|
712
|
-
if (signaldockEnabled !== void 0) {
|
|
713
|
-
await setConfigValue("signaldock.enabled", signaldockEnabled, options.projectRoot, { global: true });
|
|
714
|
-
fragments.push(`signaldock.enabled=${signaldockEnabled}`);
|
|
715
|
-
}
|
|
716
|
-
if (signaldockEndpoint !== void 0) {
|
|
717
|
-
if (!isValidHttpUrl(signaldockEndpoint)) throw new Error(`E_SETUP_INVALID_VALUE: signaldockEndpoint '${signaldockEndpoint}' is not a valid HTTP(S) URL`);
|
|
718
|
-
await setConfigValue("signaldock.endpoint", signaldockEndpoint, options.projectRoot, { global: true });
|
|
719
|
-
fragments.push(`signaldock.endpoint=${signaldockEndpoint}`);
|
|
720
|
-
}
|
|
721
|
-
if (studioEnabled !== void 0) {
|
|
722
|
-
await setConfigValue("studio.enabled", studioEnabled, options.projectRoot, { global: true });
|
|
723
|
-
fragments.push(`studio.enabled=${studioEnabled}`);
|
|
724
|
-
if (studioEnabled) io.info("Start Studio with `cleo studio start`.");
|
|
725
|
-
}
|
|
726
|
-
if (conduitPath !== void 0) {
|
|
727
|
-
if (!isAbsolutePath(conduitPath)) throw new Error(`E_SETUP_INVALID_VALUE: conduitPath '${conduitPath}' must be an absolute path`);
|
|
728
|
-
await setConfigValue("conduit.dbPath", conduitPath, options.projectRoot, { global: false });
|
|
729
|
-
fragments.push(`conduit.dbPath=${conduitPath}`);
|
|
730
|
-
}
|
|
731
|
-
return {
|
|
732
|
-
changed: fragments.length > 0,
|
|
733
|
-
summary: fragments.length > 0 ? fragments.join(" + ") : "no changes"
|
|
734
|
-
};
|
|
735
|
-
}
|
|
736
|
-
const wantsSignalDock = await io.confirm("Enable SignalDock transport?", false);
|
|
737
|
-
await setConfigValue("signaldock.enabled", wantsSignalDock, options.projectRoot, { global: true });
|
|
738
|
-
fragments.push(`signaldock.enabled=${wantsSignalDock}`);
|
|
739
|
-
if (wantsSignalDock) {
|
|
740
|
-
let endpoint = "";
|
|
741
|
-
while (true) {
|
|
742
|
-
const raw = (await io.prompt(`SignalDock endpoint URL [${DEFAULT_SIGNALDOCK_ENDPOINT}]:`)).trim();
|
|
743
|
-
endpoint = raw === "" ? DEFAULT_SIGNALDOCK_ENDPOINT : raw;
|
|
744
|
-
if (isValidHttpUrl(endpoint)) break;
|
|
745
|
-
io.warn(`'${endpoint}' is not a valid HTTP(S) URL — please try again.`);
|
|
746
|
-
}
|
|
747
|
-
await setConfigValue("signaldock.endpoint", endpoint, options.projectRoot, { global: true });
|
|
748
|
-
fragments.push(`signaldock.endpoint=${endpoint}`);
|
|
749
|
-
}
|
|
750
|
-
const wantsStudio = await io.confirm("Enable Studio web UI?", false);
|
|
751
|
-
await setConfigValue("studio.enabled", wantsStudio, options.projectRoot, { global: true });
|
|
752
|
-
fragments.push(`studio.enabled=${wantsStudio}`);
|
|
753
|
-
if (wantsStudio) io.info("Start Studio with `cleo studio start`.");
|
|
754
|
-
let conduitWritten = false;
|
|
755
|
-
while (true) {
|
|
756
|
-
const raw = (await io.prompt("Custom Conduit DB path? [leave blank to use default]")).trim();
|
|
757
|
-
if (raw === "") break;
|
|
758
|
-
if (!isAbsolutePath(raw)) {
|
|
759
|
-
io.warn(`'${raw}' is not an absolute path — please supply an absolute path or leave blank.`);
|
|
760
|
-
continue;
|
|
761
|
-
}
|
|
762
|
-
await setConfigValue("conduit.dbPath", raw, options.projectRoot, { global: false });
|
|
763
|
-
fragments.push(`conduit.dbPath=${raw}`);
|
|
764
|
-
conduitWritten = true;
|
|
765
|
-
break;
|
|
766
|
-
}
|
|
767
|
-
if (!conduitWritten) fragments.push("conduit.dbPath=default");
|
|
768
|
-
return {
|
|
769
|
-
changed: true,
|
|
770
|
-
summary: fragments.join(" + ")
|
|
771
|
-
};
|
|
772
|
-
}
|
|
773
|
-
};
|
|
774
|
-
}
|
|
775
|
-
//#endregion
|
|
776
|
-
//#region ../core/dist/setup/sections/llm.js
|
|
777
|
-
/**
|
|
778
|
-
* `llm` setup wizard section (E-CONFIG-AUTH-UNIFY E3 / T9420).
|
|
779
|
-
*
|
|
780
|
-
* Mirrors Hermes Agent's `setup.py` LLM block:
|
|
781
|
-
* 1. Display the current credential pool snapshot (provider/label/source).
|
|
782
|
-
* 2. Prompt for a provider id (or accept `--provider` non-interactively).
|
|
783
|
-
* 3. Accept an API key via `--api-key` *or* via interactive prompt.
|
|
784
|
-
* 4. Write the result to the credential pool — never to config.
|
|
785
|
-
*
|
|
786
|
-
* V2 additions (T9610):
|
|
787
|
-
* - `isConfigured()` — returns `true` when pool has at least one entry (LLM-7).
|
|
788
|
-
* - Bracketed paste sanitization on API key input (LLM-4).
|
|
789
|
-
* - Pool-seeding consent prompt after key entry (LLM-5).
|
|
790
|
-
* - Section description printed before prompts (GEN-6).
|
|
791
|
-
*
|
|
792
|
-
* Non-interactive contract:
|
|
793
|
-
* - `options.nonInteractive === true` + `options.provider` + `options.apiKey`
|
|
794
|
-
* → write key to pool; no prompts.
|
|
795
|
-
* - Missing `--provider` or `--api-key` under `--non-interactive` →
|
|
796
|
-
* section short-circuits silently (`changed: false`).
|
|
797
|
-
*
|
|
798
|
-
* @task T9420
|
|
799
|
-
* @task T9610
|
|
800
|
-
* @epic T9402
|
|
801
|
-
* @epic T9591
|
|
802
|
-
* @see docs/plans/E-CLEO-SETUP-V2.md §4.3
|
|
803
|
-
*/
|
|
804
|
-
/**
|
|
805
|
-
* Provider ids the interactive wizard offers from the menu.
|
|
806
|
-
*
|
|
807
|
-
* Plugin providers are added later in T-E2-3; this list is the safe
|
|
808
|
-
* starter set drawn from `BuiltinProviderId`.
|
|
809
|
-
*/
|
|
810
|
-
var INTERACTIVE_PROVIDERS = [
|
|
811
|
-
"anthropic",
|
|
812
|
-
"openai",
|
|
813
|
-
"gemini",
|
|
814
|
-
"openrouter",
|
|
815
|
-
"moonshot",
|
|
816
|
-
"deepseek",
|
|
817
|
-
"xai",
|
|
818
|
-
"groq",
|
|
819
|
-
"ollama"
|
|
820
|
-
];
|
|
821
|
-
/**
|
|
822
|
-
* Providers that support pool seeding consent prompt (LLM-5).
|
|
823
|
-
*/
|
|
824
|
-
var POOL_SEEDING_PROVIDERS = new Set(["anthropic", "openrouter"]);
|
|
825
|
-
/**
|
|
826
|
-
* Strip bracketed paste mode escape sequences from user input (LLM-4).
|
|
827
|
-
*
|
|
828
|
-
* Terminal emulators wrap pasted content with `\x1b[200~` (start) and
|
|
829
|
-
* `\x1b[201~` (end) when bracketed paste mode is enabled. These must be
|
|
830
|
-
* removed before persisting an API key, otherwise the key will include
|
|
831
|
-
* the raw escape bytes and authentication will fail.
|
|
832
|
-
*
|
|
833
|
-
* @param input - Raw string as received from the readline prompt.
|
|
834
|
-
* @returns Cleaned string with bracketed paste sequences stripped.
|
|
835
|
-
* @internal
|
|
836
|
-
*/
|
|
837
|
-
function stripBracketedPaste(input) {
|
|
838
|
-
return input.replace(/\x1b\[200~/g, "").replace(/\x1b\[201~/g, "");
|
|
839
|
-
}
|
|
840
|
-
/**
|
|
841
|
-
* Build the `llm` section runner.
|
|
842
|
-
*
|
|
843
|
-
* Constructed via a factory so unit tests can swap `getCredentialPool`
|
|
844
|
-
* / `addCredential` references via module mocking without touching the
|
|
845
|
-
* production singleton.
|
|
846
|
-
*
|
|
847
|
-
* @returns A {@link WizardSectionRunner} for the LLM section.
|
|
848
|
-
* @task T9420
|
|
849
|
-
* @task T9610
|
|
850
|
-
*/
|
|
851
|
-
function createLlmSection(deps = {}) {
|
|
852
|
-
const frontDoor = deps.runFrontDoorLogin ?? runFrontDoorLogin;
|
|
853
|
-
return {
|
|
854
|
-
section: "llm",
|
|
855
|
-
title: "LLM provider + API key",
|
|
856
|
-
optional: false,
|
|
857
|
-
async isConfigured(_options) {
|
|
858
|
-
try {
|
|
859
|
-
return (await getCredentialPool().list()).length > 0;
|
|
860
|
-
} catch {
|
|
861
|
-
return false;
|
|
862
|
-
}
|
|
863
|
-
},
|
|
864
|
-
async run(io, options) {
|
|
865
|
-
io.info("Configures LLM provider credentials stored in the credential pool (brain.db).\nCredentials are never written to config files — they live in the encrypted pool.\nSupports: anthropic, openai, gemini, openrouter, moonshot, deepseek, xai, groq, ollama.");
|
|
866
|
-
try {
|
|
867
|
-
const entries = await getCredentialPool().list();
|
|
868
|
-
if (entries.length === 0) io.info("No credentials configured yet.");
|
|
869
|
-
else {
|
|
870
|
-
io.info(`Current credentials (${entries.length}):`);
|
|
871
|
-
for (const entry of entries) {
|
|
872
|
-
const expiry = entry.expiresAt && entry.expiresAt > 0 ? ` exp=${new Date(entry.expiresAt).toISOString()}` : "";
|
|
873
|
-
io.info(` - ${entry.provider}:${entry.label} (${entry.authType}, source=${entry.source ?? "unknown"})${expiry}`);
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
} catch (err) {
|
|
877
|
-
io.warn(`Could not list current credentials: ${err instanceof Error ? err.message : String(err)}`);
|
|
878
|
-
}
|
|
879
|
-
if (options.nonInteractive === true) {
|
|
880
|
-
if (!options.provider || !options.apiKey) return {
|
|
881
|
-
changed: false,
|
|
882
|
-
summary: "skipped (non-interactive: --provider and --api-key required)"
|
|
883
|
-
};
|
|
884
|
-
const cleanKey = stripBracketedPaste(options.apiKey);
|
|
885
|
-
await persistApiKey(options.provider, cleanKey, options.label ?? "cli-input");
|
|
886
|
-
if (options.poolSeedingConsent !== void 0) await setConfigValue("auth.poolSeedingConsent", options.poolSeedingConsent, void 0, { global: true });
|
|
887
|
-
return {
|
|
888
|
-
changed: true,
|
|
889
|
-
summary: `added ${options.provider}:${options.label ?? "cli-input"} to pool`
|
|
890
|
-
};
|
|
891
|
-
}
|
|
892
|
-
const provider = await io.select("Which LLM provider do you want to configure?", INTERACTIVE_PROVIDERS);
|
|
893
|
-
if (await io.select("How will CLEO authenticate to this provider?", ["api_key", "oauth_login"]) === "oauth_login") {
|
|
894
|
-
if (!deps.oauthAcquirer) {
|
|
895
|
-
io.info(`OAuth login for '${provider}' needs an interactive terminal. Run \`cleo login ${provider}\` (or \`cleo llm login ${provider}\`) to complete it.`);
|
|
896
|
-
return {
|
|
897
|
-
changed: false,
|
|
898
|
-
summary: `oauth login pending for ${provider} (run cleo login)`
|
|
899
|
-
};
|
|
900
|
-
}
|
|
901
|
-
const result = await frontDoor(provider, { authMode: "oauth" }, deps.oauthAcquirer);
|
|
902
|
-
if (result.validated) {
|
|
903
|
-
io.info(`Logged in to ${result.provider} — bound ${result.profileName ?? "default"} → ${result.provider}/${result.modelId}.`);
|
|
904
|
-
return {
|
|
905
|
-
changed: true,
|
|
906
|
-
summary: `oauth login complete for ${result.provider} (${result.modelId})`
|
|
907
|
-
};
|
|
908
|
-
}
|
|
909
|
-
const failed = result.steps.find((s) => s.status === "failed");
|
|
910
|
-
io.warn(`OAuth login did not complete: ${failed?.detail ?? "unknown error"}`);
|
|
911
|
-
return {
|
|
912
|
-
changed: false,
|
|
913
|
-
summary: `oauth login failed for ${provider}`
|
|
914
|
-
};
|
|
915
|
-
}
|
|
916
|
-
const label = await io.prompt("Label for this credential [default: cli-input]:") || "cli-input";
|
|
917
|
-
const apiKey = stripBracketedPaste((await io.prompt("API key (input not echoed in production):")).trim());
|
|
918
|
-
if (apiKey === "") {
|
|
919
|
-
io.warn("No API key supplied — leaving section unchanged.");
|
|
920
|
-
return {
|
|
921
|
-
changed: false,
|
|
922
|
-
summary: "skipped (empty api key)"
|
|
923
|
-
};
|
|
924
|
-
}
|
|
925
|
-
await persistApiKey(provider, apiKey, label);
|
|
926
|
-
if (POOL_SEEDING_PROVIDERS.has(provider)) {
|
|
927
|
-
const consent = await io.confirm("Consent to including this key in CLEO's credential pool for multi-agent distribution?", false);
|
|
928
|
-
await setConfigValue("auth.poolSeedingConsent", consent, void 0, { global: true });
|
|
929
|
-
io.info(`Pool-seeding consent: ${consent ? "granted" : "denied"} (saved to auth.poolSeedingConsent)`);
|
|
930
|
-
}
|
|
931
|
-
return {
|
|
932
|
-
changed: true,
|
|
933
|
-
summary: `added ${provider}:${label} to pool`
|
|
934
|
-
};
|
|
935
|
-
}
|
|
936
|
-
};
|
|
937
|
-
}
|
|
938
|
-
/**
|
|
939
|
-
* Upsert an API-key entry into the credential pool.
|
|
940
|
-
*
|
|
941
|
-
* Keeps the policy "secrets live in the pool, never in config" enforced
|
|
942
|
-
* by routing every write through {@link addCredential}.
|
|
943
|
-
*
|
|
944
|
-
* @internal
|
|
945
|
-
*/
|
|
946
|
-
async function persistApiKey(provider, apiKey, label) {
|
|
947
|
-
await addCredential({
|
|
948
|
-
provider,
|
|
949
|
-
label,
|
|
950
|
-
authType: "api_key",
|
|
951
|
-
accessToken: apiKey,
|
|
952
|
-
source: "cli-input"
|
|
953
|
-
});
|
|
954
|
-
}
|
|
955
|
-
//#endregion
|
|
956
|
-
//#region ../core/dist/setup/sections/models-roles.js
|
|
957
|
-
/**
|
|
958
|
-
* `models-roles` setup wizard section (T11726 · M3).
|
|
959
|
-
*
|
|
960
|
-
* Sits immediately after the `llm` section in the canonical order. Where `llm`
|
|
961
|
-
* lands a credential in the pool, this section binds WHAT to use:
|
|
962
|
-
*
|
|
963
|
-
* 1. **default model** — pick the global default model (`cleo llm use`
|
|
964
|
-
* equivalent → `llm.default.model`), sourcing choices from the live
|
|
965
|
-
* models.dev catalog for the default provider.
|
|
966
|
-
* 2. **per-role profiles** — optionally pin each role in the canonical
|
|
967
|
-
* {@link WHOAMI_ROLE_IDS} set to a provider/model (`cleo llm profile`
|
|
968
|
-
* equivalent → `llm.roles.<role>`).
|
|
969
|
-
*
|
|
970
|
-
* ## Non-interactive contract (AC3)
|
|
971
|
-
*
|
|
972
|
-
* Driveable entirely from {@link WizardOptions}:
|
|
973
|
-
* - `options.defaultModel` → write the global default model.
|
|
974
|
-
* - `options.roleBindings[role]` → write `llm.roles.<role>` for each entry.
|
|
975
|
-
* Missing inputs short-circuit cleanly with `changed: false` (never a throw,
|
|
976
|
-
* never a half-written binding).
|
|
977
|
-
*
|
|
978
|
-
* ## Idempotency (AC4)
|
|
979
|
-
*
|
|
980
|
-
* `isConfigured()` returns `true` when a default model OR any role binding is
|
|
981
|
-
* already present in the global config, so the wizard skips the section unless
|
|
982
|
-
* `--reset` is passed.
|
|
983
|
-
*
|
|
984
|
-
* @module setup/sections/models-roles
|
|
985
|
-
* @task T11726
|
|
986
|
-
* @epic T11671 (E6-ONBOARDING-FRONT-DOOR)
|
|
987
|
-
*/
|
|
988
|
-
/**
|
|
989
|
-
* Sentinel option offered in interactive pickers meaning "leave this unset".
|
|
990
|
-
*
|
|
991
|
-
* @internal
|
|
992
|
-
*/
|
|
993
|
-
var SKIP_CHOICE = "(skip)";
|
|
994
|
-
/**
|
|
995
|
-
* Read the current global LLM config block (best-effort — returns `{}` on any
|
|
996
|
-
* read error so the section degrades gracefully on a fresh install).
|
|
997
|
-
*
|
|
998
|
-
* @internal
|
|
999
|
-
*/
|
|
1000
|
-
async function readLlmConfig() {
|
|
1001
|
-
try {
|
|
1002
|
-
const llm = (await loadConfig()).llm;
|
|
1003
|
-
const def = llm?.default;
|
|
1004
|
-
return {
|
|
1005
|
-
defaultProvider: def?.provider,
|
|
1006
|
-
defaultModel: def?.model,
|
|
1007
|
-
roles: llm?.roles ?? {}
|
|
1008
|
-
};
|
|
1009
|
-
} catch {
|
|
1010
|
-
return {};
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
/**
|
|
1014
|
-
* Build the model choice list for a provider from the catalog, capped for a
|
|
1015
|
-
* scannable menu. Always includes the {@link SKIP_CHOICE} sentinel last.
|
|
1016
|
-
*
|
|
1017
|
-
* @internal
|
|
1018
|
-
*/
|
|
1019
|
-
function modelChoicesForProvider(provider) {
|
|
1020
|
-
return [...listProviderModels(catalogKeyForProvider(provider)), SKIP_CHOICE];
|
|
1021
|
-
}
|
|
1022
|
-
/**
|
|
1023
|
-
* Build the `models-roles` section runner (T11726).
|
|
1024
|
-
*
|
|
1025
|
-
* @returns A {@link WizardSectionRunner} for the models/roles section.
|
|
1026
|
-
* @task T11726
|
|
1027
|
-
*/
|
|
1028
|
-
function createModelsRolesSection() {
|
|
1029
|
-
return {
|
|
1030
|
-
section: "models-roles",
|
|
1031
|
-
title: "Default model + per-role profiles",
|
|
1032
|
-
optional: true,
|
|
1033
|
-
async isConfigured(_options) {
|
|
1034
|
-
const cfg = await readLlmConfig();
|
|
1035
|
-
const hasDefaultModel = typeof cfg.defaultModel === "string" && cfg.defaultModel !== "";
|
|
1036
|
-
const hasRole = Boolean(cfg.roles && Object.keys(cfg.roles).length > 0);
|
|
1037
|
-
return hasDefaultModel || hasRole;
|
|
1038
|
-
},
|
|
1039
|
-
async run(io, options) {
|
|
1040
|
-
io.info("Selects the default model (cleo llm use) and optional per-role profiles (cleo llm profile).\nModel choices come from the cached models.dev catalog — run `cleo llm refresh-catalog` to update it.");
|
|
1041
|
-
const cfg = await readLlmConfig();
|
|
1042
|
-
const defaultProvider = options.provider ?? cfg.defaultProvider;
|
|
1043
|
-
const changes = [];
|
|
1044
|
-
if (options.nonInteractive === true) {
|
|
1045
|
-
if (options.defaultModel) {
|
|
1046
|
-
await setConfigValue("llm.default.model", options.defaultModel, void 0, { global: true });
|
|
1047
|
-
if (defaultProvider) await setConfigValue("llm.default.provider", defaultProvider, void 0, { global: true });
|
|
1048
|
-
changes.push(`default model → ${options.defaultModel}`);
|
|
1049
|
-
}
|
|
1050
|
-
for (const [role, binding] of Object.entries(options.roleBindings ?? {})) {
|
|
1051
|
-
if (!isWhoamiRole(role)) continue;
|
|
1052
|
-
let model = binding.model;
|
|
1053
|
-
if (!model) model = resolveProviderDefaultModel(catalogKeyForProvider(binding.provider)) ?? void 0;
|
|
1054
|
-
if (!model) {
|
|
1055
|
-
io.warn(`Skipping role binding ${role} → ${binding.provider}: no model supplied and no catalog default found for '${binding.provider}'. Re-run with {"${role}": {"provider": "${binding.provider}", "model": "<id>"}}.`);
|
|
1056
|
-
continue;
|
|
1057
|
-
}
|
|
1058
|
-
await writeRoleBinding(role, {
|
|
1059
|
-
...binding,
|
|
1060
|
-
model
|
|
1061
|
-
});
|
|
1062
|
-
changes.push(`${role} → ${binding.provider}/${model}`);
|
|
1063
|
-
}
|
|
1064
|
-
if (changes.length === 0) return {
|
|
1065
|
-
changed: false,
|
|
1066
|
-
summary: "skipped (non-interactive: no --default-model / role bindings supplied)"
|
|
1067
|
-
};
|
|
1068
|
-
return {
|
|
1069
|
-
changed: true,
|
|
1070
|
-
summary: changes.join("; ")
|
|
1071
|
-
};
|
|
1072
|
-
}
|
|
1073
|
-
if (!defaultProvider) {
|
|
1074
|
-
io.info("No default provider configured yet — run the LLM section (or `cleo login`) first, then re-run setup to pin models/roles.");
|
|
1075
|
-
return {
|
|
1076
|
-
changed: false,
|
|
1077
|
-
summary: "skipped (no provider configured)"
|
|
1078
|
-
};
|
|
1079
|
-
}
|
|
1080
|
-
if (defaultProvider === "ollama") {
|
|
1081
|
-
const modelPicked = await _pickOllamaModelInteractive(io);
|
|
1082
|
-
if (modelPicked) {
|
|
1083
|
-
await setConfigValue("llm.default.model", modelPicked, void 0, { global: true });
|
|
1084
|
-
await setConfigValue("llm.default.provider", "ollama", void 0, { global: true });
|
|
1085
|
-
changes.push(`default model → ${modelPicked}`);
|
|
1086
|
-
}
|
|
1087
|
-
} else {
|
|
1088
|
-
const modelChoices = modelChoicesForProvider(defaultProvider);
|
|
1089
|
-
if (modelChoices.length > 1) {
|
|
1090
|
-
const picked = await io.select(`Default model for ${defaultProvider}?`, modelChoices);
|
|
1091
|
-
if (picked !== SKIP_CHOICE) {
|
|
1092
|
-
await setConfigValue("llm.default.model", picked, void 0, { global: true });
|
|
1093
|
-
await setConfigValue("llm.default.provider", defaultProvider, void 0, { global: true });
|
|
1094
|
-
changes.push(`default model → ${picked}`);
|
|
1095
|
-
}
|
|
1096
|
-
} else {
|
|
1097
|
-
const latest = resolveProviderDefaultModel(catalogKeyForProvider(defaultProvider));
|
|
1098
|
-
const model = (await io.prompt(`Default model for ${defaultProvider}${latest ? ` [${latest}]` : ""} (blank to skip):`)).trim() || latest || "";
|
|
1099
|
-
if (model) {
|
|
1100
|
-
await setConfigValue("llm.default.model", model, void 0, { global: true });
|
|
1101
|
-
await setConfigValue("llm.default.provider", defaultProvider, void 0, { global: true });
|
|
1102
|
-
changes.push(`default model → ${model}`);
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
if (await io.confirm("Pin per-role profiles now? (advanced)", false)) for (const role of WHOAMI_ROLE_IDS) {
|
|
1107
|
-
const choices = modelChoicesForProvider(defaultProvider);
|
|
1108
|
-
const picked = await io.select(`Model for role '${role}' on ${defaultProvider}?`, choices);
|
|
1109
|
-
if (picked !== SKIP_CHOICE) {
|
|
1110
|
-
await writeRoleBinding(role, {
|
|
1111
|
-
provider: defaultProvider,
|
|
1112
|
-
model: picked
|
|
1113
|
-
});
|
|
1114
|
-
changes.push(`${role} → ${defaultProvider}/${picked}`);
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
if (changes.length === 0) return {
|
|
1118
|
-
changed: false,
|
|
1119
|
-
summary: "no models/roles changes"
|
|
1120
|
-
};
|
|
1121
|
-
return {
|
|
1122
|
-
changed: true,
|
|
1123
|
-
summary: changes.join("; ")
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
};
|
|
1127
|
-
}
|
|
1128
|
-
/**
|
|
1129
|
-
* Narrow an arbitrary string to a {@link RoleName} in the whoami-enumerable set.
|
|
1130
|
-
*
|
|
1131
|
-
* @internal
|
|
1132
|
-
*/
|
|
1133
|
-
function isWhoamiRole(role) {
|
|
1134
|
-
return WHOAMI_ROLE_IDS.includes(role);
|
|
1135
|
-
}
|
|
1136
|
-
/**
|
|
1137
|
-
* Write a per-role binding (`llm.roles.<role>.{provider,model,credentialLabel}`)
|
|
1138
|
-
* to the global config.
|
|
1139
|
-
*
|
|
1140
|
-
* @internal
|
|
1141
|
-
*/
|
|
1142
|
-
async function writeRoleBinding(role, binding) {
|
|
1143
|
-
await setConfigValue(`llm.roles.${role}.provider`, binding.provider, void 0, { global: true });
|
|
1144
|
-
if (binding.model) await setConfigValue(`llm.roles.${role}.model`, binding.model, void 0, { global: true });
|
|
1145
|
-
if (binding.credentialLabel) await setConfigValue(`llm.roles.${role}.credentialLabel`, binding.credentialLabel, void 0, { global: true });
|
|
1146
|
-
}
|
|
1147
|
-
/**
|
|
1148
|
-
* The default ranker used in production: calls the real `rankLocalModelFit`.
|
|
1149
|
-
*
|
|
1150
|
-
* Lazy import keeps this module free of heavy OS-level side effects at parse
|
|
1151
|
-
* time (Gate-13 compliance: no transport construction at import).
|
|
1152
|
-
*
|
|
1153
|
-
* @internal
|
|
1154
|
-
*/
|
|
1155
|
-
async function defaultLocalModelFitRanker() {
|
|
1156
|
-
const { rankLocalModelFit } = await import('./local-model-fit-B0TxifnX.js');
|
|
1157
|
-
return rankLocalModelFit();
|
|
1158
|
-
}
|
|
1159
|
-
/**
|
|
1160
|
-
* Interactive Ollama model picker driven by fit-gated recommendations (T11983).
|
|
1161
|
-
*
|
|
1162
|
-
* Behaviour:
|
|
1163
|
-
* - Calls `rankLocalModelFit` to detect hardware + Ollama state.
|
|
1164
|
-
* - Below the 4 GB floor → informs the user (cloud-only guidance) and returns
|
|
1165
|
-
* `null` (caller skips the binding).
|
|
1166
|
-
* - Above the floor with recommendations → presents a ranked pick list of
|
|
1167
|
-
* 2–3 candidates (never auto-selects, never auto-pulls — RECOMMEND-NEVER-KILL).
|
|
1168
|
-
* - Already-pulled models are surfaced first with a `[pulled]` tag.
|
|
1169
|
-
* - Free-text fallback offered as the last option so the user can type any tag.
|
|
1170
|
-
* - Returns the chosen model tag, or `null` if the user skipped.
|
|
1171
|
-
*
|
|
1172
|
-
* The ranker is injectable so tests can supply a stub envelope without
|
|
1173
|
-
* hitting the OS or network.
|
|
1174
|
-
*
|
|
1175
|
-
* @param io - Wizard I/O surface.
|
|
1176
|
-
* @param ranker - Override the fit ranker for tests (defaults to the real one).
|
|
1177
|
-
* @returns The chosen Ollama model tag, or `null` when the user skipped / below floor.
|
|
1178
|
-
*
|
|
1179
|
-
* @task T11983
|
|
1180
|
-
*/
|
|
1181
|
-
async function _pickOllamaModelInteractive(io, ranker = defaultLocalModelFitRanker) {
|
|
1182
|
-
io.info("Detecting local hardware for Ollama model fit ranking…");
|
|
1183
|
-
let fitEnvelope;
|
|
1184
|
-
try {
|
|
1185
|
-
fitEnvelope = await ranker();
|
|
1186
|
-
} catch (err) {
|
|
1187
|
-
io.warn(`Hardware detection failed: ${err instanceof Error ? err.message : String(err)}. Falling back to manual model entry.`);
|
|
1188
|
-
return (await io.prompt("Enter Ollama model tag (e.g. gemma4:e2b) or blank to skip:")).trim() || null;
|
|
1189
|
-
}
|
|
1190
|
-
const hw = fitEnvelope.hardware;
|
|
1191
|
-
io.info(` Hardware: ${hw.totalRamGb.toFixed(1)} GB RAM, ` + (hw.vramTotalGb !== null ? `${hw.vramTotalGb.toFixed(1)} GB VRAM` : "no GPU detected") + (fitEnvelope.ollamaRunning ? ", Ollama running" : ", Ollama not running"));
|
|
1192
|
-
if (fitEnvelope.noRecommendationReason) {
|
|
1193
|
-
io.warn(`\nLocal model recommendation not available: ${fitEnvelope.noRecommendationReason}\nThis machine has ${hw.totalRamGb.toFixed(1)} GB RAM — local LLM inference requires at least 4 GB.\nPlease use a cloud provider (anthropic, openai, gemini, etc.) instead.`);
|
|
1194
|
-
return null;
|
|
1195
|
-
}
|
|
1196
|
-
const recs = fitEnvelope.recommendations;
|
|
1197
|
-
if (recs.length === 0) {
|
|
1198
|
-
io.warn("No local model candidates fit this machine. Consider a cloud provider.");
|
|
1199
|
-
return (await io.prompt("Enter Ollama model tag manually (blank to skip):")).trim() || null;
|
|
1200
|
-
}
|
|
1201
|
-
io.info("\nRecommended local models (ranked by hardware fit):");
|
|
1202
|
-
const choices = recs.map((r) => {
|
|
1203
|
-
return `${r.candidate.modelTag}${r.alreadyPulled ? " [pulled]" : ""} (${r.fitTier})`;
|
|
1204
|
-
});
|
|
1205
|
-
choices.push("(enter manually)");
|
|
1206
|
-
choices.push(SKIP_CHOICE);
|
|
1207
|
-
const picked = await io.select("Choose a local model for Ollama:", choices);
|
|
1208
|
-
if (picked === SKIP_CHOICE) return null;
|
|
1209
|
-
if (picked === "(enter manually)") return (await io.prompt("Enter Ollama model tag (e.g. gemma4:e2b):")).trim() || null;
|
|
1210
|
-
return picked.split(" ")[0] ?? picked;
|
|
1211
|
-
}
|
|
1212
|
-
//#endregion
|
|
1213
|
-
//#region ../core/dist/setup/sections/project-conventions.js
|
|
1214
|
-
/**
|
|
1215
|
-
* `project-conventions` setup wizard section (E-CONFIG-AUTH-UNIFY E3 / T9420).
|
|
1216
|
-
*
|
|
1217
|
-
* Applies one of CLEO's three strictness presets (`strict` / `standard` /
|
|
1218
|
-
* `minimal`) via the existing {@link applyStrictnessPreset} helper.
|
|
1219
|
-
* Project-scoped: the preset is written to the *project* config so each
|
|
1220
|
-
* repository can have its own enforcement tier.
|
|
1221
|
-
*
|
|
1222
|
-
* V2 additions (T9610):
|
|
1223
|
-
* - `isConfigured()` — returns `true` when project config has at least one
|
|
1224
|
-
* strictness-related key (PROJ-5).
|
|
1225
|
-
* - Current values display before prompting (GEN-7 / PROJ-1).
|
|
1226
|
-
* - AC enforcement mode override prompt (PROJ-3).
|
|
1227
|
-
* - Session auto-start override prompt (PROJ-3).
|
|
1228
|
-
* - Section description printed before prompts (GEN-6).
|
|
1229
|
-
*
|
|
1230
|
-
* Non-interactive contract:
|
|
1231
|
-
* - `options.nonInteractive === true` + `options.strictness` →
|
|
1232
|
-
* apply that preset; no prompts.
|
|
1233
|
-
* - `options.acEnforcementMode` and `options.sessionAutoStart` apply
|
|
1234
|
-
* fine-grained overrides when present (PROJ-4).
|
|
1235
|
-
* - Missing `--strictness` under `--non-interactive` →
|
|
1236
|
-
* section short-circuits silently (`changed: false`).
|
|
1237
|
-
*
|
|
1238
|
-
* @task T9420
|
|
1239
|
-
* @task T9610
|
|
1240
|
-
* @epic T9402
|
|
1241
|
-
* @epic T9591
|
|
1242
|
-
* @see docs/plans/E-CLEO-SETUP-V2.md §4.7 (PROJ-1 through PROJ-5)
|
|
1243
|
-
*/
|
|
1244
|
-
var PRESET_CHOICES = [
|
|
1245
|
-
"strict",
|
|
1246
|
-
"standard",
|
|
1247
|
-
"minimal"
|
|
1248
|
-
];
|
|
1249
|
-
/** AC enforcement mode choices for the override prompt. */
|
|
1250
|
-
var AC_ENFORCEMENT_CHOICES = [
|
|
1251
|
-
"block",
|
|
1252
|
-
"warn",
|
|
1253
|
-
"off",
|
|
1254
|
-
"keep-preset-default"
|
|
1255
|
-
];
|
|
1256
|
-
/** Session auto-start choices for the override prompt. */
|
|
1257
|
-
var SESSION_AUTO_START_CHOICES = [
|
|
1258
|
-
"yes",
|
|
1259
|
-
"no",
|
|
1260
|
-
"keep-preset-default"
|
|
1261
|
-
];
|
|
1262
|
-
/**
|
|
1263
|
-
* Build the `project-conventions` section runner.
|
|
1264
|
-
*
|
|
1265
|
-
* @returns A {@link WizardSectionRunner} for the conventions section.
|
|
1266
|
-
* @task T9420
|
|
1267
|
-
* @task T9610
|
|
1268
|
-
*/
|
|
1269
|
-
function createProjectConventionsSection() {
|
|
1270
|
-
return {
|
|
1271
|
-
section: "project-conventions",
|
|
1272
|
-
title: "Project conventions (strictness preset)",
|
|
1273
|
-
optional: true,
|
|
1274
|
-
async isConfigured(options) {
|
|
1275
|
-
const acMode = await getConfigValue("enforcement.acceptance.mode", options.projectRoot);
|
|
1276
|
-
const requireNotes = await getConfigValue("session.requireNotes", options.projectRoot);
|
|
1277
|
-
const acConfigured = acMode.source !== "default" && acMode.value !== void 0;
|
|
1278
|
-
const notesConfigured = requireNotes.source !== "default" && requireNotes.value !== void 0;
|
|
1279
|
-
return acConfigured || notesConfigured;
|
|
1280
|
-
},
|
|
1281
|
-
async run(io, options) {
|
|
1282
|
-
io.info("Configures project-level enforcement conventions written to `.cleo/config.json`.\nPresets (strict / standard / minimal) control AC enforcement, session policy, and lifecycle.\nFine-grained overrides can be applied after choosing a preset.");
|
|
1283
|
-
const currentAcMode = await getConfigValue("enforcement.acceptance.mode", options.projectRoot);
|
|
1284
|
-
const currentAutoStart = await getConfigValue("session.autoStart", options.projectRoot);
|
|
1285
|
-
io.info(`Current AC enforcement mode: ${currentAcMode.value ?? "(not set)"} (source: ${currentAcMode.source})`);
|
|
1286
|
-
io.info(`Current session auto-start: ${currentAutoStart.value ?? "(not set)"} (source: ${currentAutoStart.source})`);
|
|
1287
|
-
let preset;
|
|
1288
|
-
if (options.nonInteractive === true) {
|
|
1289
|
-
if (!options.strictness) return {
|
|
1290
|
-
changed: false,
|
|
1291
|
-
summary: "skipped (non-interactive: --strictness required)"
|
|
1292
|
-
};
|
|
1293
|
-
preset = options.strictness;
|
|
1294
|
-
} else preset = await io.select("Pick a strictness preset (strict|standard|minimal)", PRESET_CHOICES);
|
|
1295
|
-
const result = await applyStrictnessPreset(preset, options.projectRoot, { global: false });
|
|
1296
|
-
const keyCount = Object.keys(result.applied).length;
|
|
1297
|
-
const fragments = [`applied '${result.preset}' preset (${keyCount} keys to ${result.scope} config)`];
|
|
1298
|
-
let acOverride;
|
|
1299
|
-
if (options.nonInteractive === true) {
|
|
1300
|
-
if (options.acEnforcementMode !== void 0) acOverride = options.acEnforcementMode;
|
|
1301
|
-
} else {
|
|
1302
|
-
const acChoice = await io.select("Override AC enforcement mode? [block / warn / off / keep-preset-default]", AC_ENFORCEMENT_CHOICES);
|
|
1303
|
-
if (acChoice !== "keep-preset-default") acOverride = acChoice;
|
|
1304
|
-
}
|
|
1305
|
-
if (acOverride !== void 0) {
|
|
1306
|
-
await setConfigValue("enforcement.acceptance.mode", acOverride, options.projectRoot, { global: false });
|
|
1307
|
-
fragments.push(`set enforcement.acceptance.mode=${acOverride}`);
|
|
1308
|
-
}
|
|
1309
|
-
let sessionAutoStartOverride;
|
|
1310
|
-
if (options.nonInteractive === true) {
|
|
1311
|
-
if (options.sessionAutoStart !== void 0) sessionAutoStartOverride = options.sessionAutoStart;
|
|
1312
|
-
} else {
|
|
1313
|
-
const sessionChoice = await io.select("Override session auto-start? [yes / no / keep-preset-default]", SESSION_AUTO_START_CHOICES);
|
|
1314
|
-
if (sessionChoice === "yes") sessionAutoStartOverride = true;
|
|
1315
|
-
else if (sessionChoice === "no") sessionAutoStartOverride = false;
|
|
1316
|
-
}
|
|
1317
|
-
if (sessionAutoStartOverride !== void 0) {
|
|
1318
|
-
await setConfigValue("session.autoStart", sessionAutoStartOverride, options.projectRoot, { global: false });
|
|
1319
|
-
fragments.push(`set session.autoStart=${sessionAutoStartOverride}`);
|
|
1320
|
-
}
|
|
1321
|
-
return {
|
|
1322
|
-
changed: true,
|
|
1323
|
-
summary: fragments.join(" + ")
|
|
1324
|
-
};
|
|
1325
|
-
}
|
|
1326
|
-
};
|
|
1327
|
-
}
|
|
1328
|
-
//#endregion
|
|
1329
|
-
//#region ../core/dist/setup/sections/sentient.js
|
|
1330
|
-
/**
|
|
1331
|
-
* `sentient` setup wizard section (E-CONFIG-AUTH-UNIFY E3 / T9420).
|
|
1332
|
-
*
|
|
1333
|
-
* Toggles the two operator-visible sentient knobs:
|
|
1334
|
-
* 1. The daemon kill-switch (`killSwitch: false` ⇒ daemon is allowed
|
|
1335
|
-
* to run; `true` ⇒ paused).
|
|
1336
|
-
* 2. Tier-2 proposal generation (`tier2Enabled`).
|
|
1337
|
-
*
|
|
1338
|
-
* Both fields live in `<projectRoot>/.cleo/sentient-state.json` and are
|
|
1339
|
-
* mutated via {@link patchSentientState} so the on-disk shape matches
|
|
1340
|
-
* the format the daemon expects.
|
|
1341
|
-
*
|
|
1342
|
-
* V2 additions (T9610):
|
|
1343
|
-
* - `isConfigured()` — returns `true` when `sentient-state.json` exists (SENT-5).
|
|
1344
|
-
* - Current state display before prompting (GEN-7 / SENT-1).
|
|
1345
|
-
* - Section description printed before prompts (GEN-6).
|
|
1346
|
-
*
|
|
1347
|
-
* Non-interactive contract:
|
|
1348
|
-
* - `options.nonInteractive === true` → consume
|
|
1349
|
-
* `options.sentientEnabled` / `options.tier2Enabled` when present;
|
|
1350
|
-
* fields not supplied are left untouched.
|
|
1351
|
-
*
|
|
1352
|
-
* @task T9420
|
|
1353
|
-
* @task T9610
|
|
1354
|
-
* @epic T9402
|
|
1355
|
-
* @epic T9591
|
|
1356
|
-
* @see docs/plans/E-CLEO-SETUP-V2.md §4.4
|
|
1357
|
-
*/
|
|
1358
|
-
/**
|
|
1359
|
-
* Build the `sentient` section runner.
|
|
1360
|
-
*
|
|
1361
|
-
* @returns A {@link WizardSectionRunner} for the sentient section.
|
|
1362
|
-
* @task T9420
|
|
1363
|
-
* @task T9610
|
|
1364
|
-
*/
|
|
1365
|
-
function createSentientSection() {
|
|
1366
|
-
return {
|
|
1367
|
-
section: "sentient",
|
|
1368
|
-
title: "Sentient daemon + Tier-2 proposals",
|
|
1369
|
-
optional: true,
|
|
1370
|
-
async isConfigured(options) {
|
|
1371
|
-
return existsSync(join(resolveOrCwd(options.projectRoot), SENTIENT_STATE_FILE));
|
|
1372
|
-
},
|
|
1373
|
-
async run(io, options) {
|
|
1374
|
-
const statePath = join(resolveOrCwd(options.projectRoot), SENTIENT_STATE_FILE);
|
|
1375
|
-
io.info("Configures the CLEO sentient daemon and Tier-2 autonomous proposal generation.\nState is stored in `.cleo/sentient-state.json` in the project root.\nTier-2 proposals are disabled by default for safety.");
|
|
1376
|
-
if (existsSync(statePath)) try {
|
|
1377
|
-
const state = await readSentientState(statePath);
|
|
1378
|
-
const daemonActive = !state.killSwitch;
|
|
1379
|
-
const t2Active = state.tier2Enabled ?? false;
|
|
1380
|
-
const lastTick = state.lastTickAt != null ? new Date(state.lastTickAt).toISOString() : "never";
|
|
1381
|
-
io.info(`Current sentient state: daemon=${daemonActive ? "enabled" : "disabled"}, tier2=${t2Active ? "enabled" : "disabled"}, last-tick=${lastTick}`);
|
|
1382
|
-
} catch {
|
|
1383
|
-
io.info("Current sentient state: (could not read state file)");
|
|
1384
|
-
}
|
|
1385
|
-
else io.info("Current sentient state: (not configured — state file does not exist)");
|
|
1386
|
-
let daemonEnabled;
|
|
1387
|
-
let tier2Enabled;
|
|
1388
|
-
if (options.nonInteractive === true) {
|
|
1389
|
-
daemonEnabled = options.sentientEnabled;
|
|
1390
|
-
tier2Enabled = options.tier2Enabled;
|
|
1391
|
-
if (daemonEnabled === void 0 && tier2Enabled === void 0) throw new Error("E_SETUP_MISSING_FLAG: --section sentient --non-interactive requires --sentient <on|off> or --tier2 <on|off>");
|
|
1392
|
-
} else {
|
|
1393
|
-
daemonEnabled = await io.confirm("Enable the sentient daemon (auto-tick reconciler)?", false);
|
|
1394
|
-
tier2Enabled = await io.confirm("Enable Tier-2 autonomous proposals (off by default)?", false);
|
|
1395
|
-
}
|
|
1396
|
-
const patch = {};
|
|
1397
|
-
if (daemonEnabled !== void 0) {
|
|
1398
|
-
patch.killSwitch = !daemonEnabled;
|
|
1399
|
-
patch.killSwitchReason = daemonEnabled ? void 0 : "cleo setup: operator disabled";
|
|
1400
|
-
}
|
|
1401
|
-
if (tier2Enabled !== void 0) patch.tier2Enabled = tier2Enabled;
|
|
1402
|
-
await patchSentientState(statePath, patch);
|
|
1403
|
-
const fragments = [];
|
|
1404
|
-
if (daemonEnabled !== void 0) fragments.push(`daemon ${daemonEnabled ? "enabled" : "disabled"}`);
|
|
1405
|
-
if (tier2Enabled !== void 0) fragments.push(`tier2 ${tier2Enabled ? "enabled" : "disabled"}`);
|
|
1406
|
-
return {
|
|
1407
|
-
changed: true,
|
|
1408
|
-
summary: fragments.join(" + ")
|
|
1409
|
-
};
|
|
1410
|
-
}
|
|
1411
|
-
};
|
|
1412
|
-
}
|
|
1413
|
-
//#endregion
|
|
1414
|
-
//#region ../core/dist/setup/sections/telemetry.js
|
|
1415
|
-
/**
|
|
1416
|
-
* `telemetry` setup wizard section (E-SKILLS-OWNER-CI / T9673).
|
|
1417
|
-
*
|
|
1418
|
-
* Anonymous skills-usage telemetry is **default-on for new installs**.
|
|
1419
|
-
* This section runs during `cleo setup` to:
|
|
1420
|
-
* 1. Surface the default-on contract to the operator (transparency).
|
|
1421
|
-
* 2. Allow the operator to opt-out interactively.
|
|
1422
|
-
* 3. Persist `telemetry.enabled`, `telemetry.period`, `telemetry.installId`
|
|
1423
|
-
* to the global config.
|
|
1424
|
-
*
|
|
1425
|
-
* The opt-out path is the same single boolean used by `cleo telemetry disable`
|
|
1426
|
-
* (T9666) — the wizard step is convenience, NOT the only surface.
|
|
1427
|
-
*
|
|
1428
|
-
* Payload contract (LOCKED in T9666, enforced by the transport in ADR-074):
|
|
1429
|
-
* { installId, period: 'monthly', skills: { canonicalSkillName, loadCount }[] }
|
|
1430
|
-
* NEVER includes user identity, session IDs, paths, or skill content.
|
|
1431
|
-
*
|
|
1432
|
-
* Non-interactive contract:
|
|
1433
|
-
* - `options.nonInteractive === true` → consume `options.telemetryEnabled`
|
|
1434
|
-
* when present; default to `true` (default-on contract) when absent so
|
|
1435
|
-
* unattended setup runs match interactive defaults.
|
|
1436
|
-
*
|
|
1437
|
-
* @task T9673
|
|
1438
|
-
* @epic T9572
|
|
1439
|
-
* @see packages/cleo/src/cli/commands/telemetry.ts
|
|
1440
|
-
* @see .cleo/adrs/ADR-074-skills-telemetry-pr-diff-transport.md
|
|
1441
|
-
*/
|
|
1442
|
-
/**
|
|
1443
|
-
* Telemetry reporting period — locked to `monthly` in T9666.
|
|
1444
|
-
*
|
|
1445
|
-
* Future periods (weekly, on-demand) MUST be added as a discriminated
|
|
1446
|
-
* union in `packages/cleo/src/cli/commands/telemetry.ts` first; this
|
|
1447
|
-
* section consumes the canonical type rather than re-defining it.
|
|
1448
|
-
*/
|
|
1449
|
-
var TELEMETRY_PERIOD = "monthly";
|
|
1450
|
-
/**
|
|
1451
|
-
* Build the `telemetry` section runner.
|
|
1452
|
-
*
|
|
1453
|
-
* Idempotent — `isConfigured()` returns `true` when `telemetry.enabled` has
|
|
1454
|
-
* been explicitly written to the global config. On a fresh install the key
|
|
1455
|
-
* is absent (not `false`); the wizard runs and writes `true` per the
|
|
1456
|
-
* default-on contract.
|
|
1457
|
-
*
|
|
1458
|
-
* @returns A {@link WizardSectionRunner} for the telemetry section.
|
|
1459
|
-
*/
|
|
1460
|
-
function createTelemetrySection() {
|
|
1461
|
-
return {
|
|
1462
|
-
section: "telemetry",
|
|
1463
|
-
title: "Anonymous skills-usage telemetry",
|
|
1464
|
-
optional: true,
|
|
1465
|
-
async isConfigured() {
|
|
1466
|
-
return typeof (await getConfigValue("telemetry.enabled")).value === "boolean";
|
|
1467
|
-
},
|
|
1468
|
-
async run(io, options) {
|
|
1469
|
-
io.info("CLEO ships anonymous skills-usage telemetry that surfaces the most-loaded\ncanonical skills back to the owner-CI top-N council (T9572 SG-CLEO-SKILLS).\nPayload: { installId, period, skills: [{ canonicalSkillName, loadCount }] }.\nNEVER includes user identity, session IDs, paths, or skill content.\nDefault: enabled. Opt-out anytime via `cleo telemetry disable`.");
|
|
1470
|
-
let enabled;
|
|
1471
|
-
if (options.nonInteractive === true) enabled = options.telemetryEnabled ?? true;
|
|
1472
|
-
else enabled = await io.confirm("Enable anonymous skills-usage telemetry?", true);
|
|
1473
|
-
await setConfigValue("telemetry.enabled", enabled, void 0, { global: true });
|
|
1474
|
-
await setConfigValue("telemetry.period", TELEMETRY_PERIOD, void 0, { global: true });
|
|
1475
|
-
const existingId = await getConfigValue("telemetry.installId");
|
|
1476
|
-
if (typeof existingId.value !== "string" || existingId.value.length === 0) await setConfigValue("telemetry.installId", randomUUID(), void 0, { global: true });
|
|
1477
|
-
return {
|
|
1478
|
-
changed: true,
|
|
1479
|
-
summary: `telemetry ${enabled ? "enabled" : "disabled"} (period=${TELEMETRY_PERIOD})`
|
|
1480
|
-
};
|
|
1481
|
-
}
|
|
1482
|
-
};
|
|
1483
|
-
}
|
|
1484
|
-
//#endregion
|
|
1485
|
-
//#region ../core/dist/setup/sections/verification.js
|
|
1486
|
-
/**
|
|
1487
|
-
* `verification` setup wizard section (E-CLEO-SETUP-V2 / T9594).
|
|
1488
|
-
*
|
|
1489
|
-
* Read-only health-check runner that validates the full CLEO configuration
|
|
1490
|
-
* stack after the wizard has finished writing all other sections. No state
|
|
1491
|
-
* is mutated — this section is a diagnostic surface only.
|
|
1492
|
-
*
|
|
1493
|
-
* The section runs 6 independent checks in order:
|
|
1494
|
-
*
|
|
1495
|
-
* 1. **credential-pool** — at least one entry exists in the pool.
|
|
1496
|
-
* 2. **credential-reach** — first valid credential round-trips to its
|
|
1497
|
-
* provider health endpoint (5 s timeout).
|
|
1498
|
-
* 3. **config-integrity** — global + project config files parse cleanly.
|
|
1499
|
-
* 4. **harness-reach** — detected harness responds:
|
|
1500
|
-
* Pi → HTTP GET `<piUrl>/health` (3 s).
|
|
1501
|
-
* Code → `which claude` exits 0.
|
|
1502
|
-
* 5. **signaldock-reach** — if `signaldock.enabled`, HTTP GET to
|
|
1503
|
-
* `<endpoint>/health` (3 s); SKIP otherwise.
|
|
1504
|
-
* 6. **brain-db** — `brain.db` exists on disk and opens
|
|
1505
|
-
* without error.
|
|
1506
|
-
*
|
|
1507
|
-
* Each check yields a {@link VerificationCheck} carrying `PASS`, `FAIL`, or
|
|
1508
|
-
* `SKIP`. The runner aggregates results and surfaces them via {@link WizardIO}:
|
|
1509
|
-
* - Interactive → formatted text table (one line per check).
|
|
1510
|
-
* - Non-interactive → JSON array of {@link VerificationCheck} entries.
|
|
1511
|
-
*
|
|
1512
|
-
* The section always returns `{changed: false}` (read-only contract, VERIF-1).
|
|
1513
|
-
* `isConfigured()` always returns `false` — verification always runs when
|
|
1514
|
-
* included in a wizard pass (VERIF-6).
|
|
1515
|
-
*
|
|
1516
|
-
* @task T9594
|
|
1517
|
-
* @epic T9591
|
|
1518
|
-
* @see docs/plans/E-CLEO-SETUP-V2.md §4.9, §5.2 T9594
|
|
1519
|
-
*/
|
|
1520
|
-
/**
|
|
1521
|
-
* Check 1 — Credential pool has at least one entry.
|
|
1522
|
-
*
|
|
1523
|
-
* @internal
|
|
1524
|
-
*/
|
|
1525
|
-
async function runCredentialPoolCheck() {
|
|
1526
|
-
const name = "credential-pool";
|
|
1527
|
-
try {
|
|
1528
|
-
const entries = await getCredentialPool().list();
|
|
1529
|
-
if (entries.length === 0) return {
|
|
1530
|
-
name,
|
|
1531
|
-
status: "FAIL",
|
|
1532
|
-
message: "pool is empty — run cleo setup --section llm"
|
|
1533
|
-
};
|
|
1534
|
-
return {
|
|
1535
|
-
name,
|
|
1536
|
-
status: "PASS",
|
|
1537
|
-
message: `${entries.length} credential(s) found`
|
|
1538
|
-
};
|
|
1539
|
-
} catch (err) {
|
|
1540
|
-
return {
|
|
1541
|
-
name,
|
|
1542
|
-
status: "FAIL",
|
|
1543
|
-
message: `pool.list() threw: ${err instanceof Error ? err.message : String(err)}`
|
|
1544
|
-
};
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
/**
|
|
1548
|
-
* Race a promise against a timeout, resolving to `undefined` on expiry.
|
|
1549
|
-
*
|
|
1550
|
-
* @internal
|
|
1551
|
-
*/
|
|
1552
|
-
function withTimeout(promise, ms) {
|
|
1553
|
-
return new Promise((resolve) => {
|
|
1554
|
-
const timer = setTimeout(() => resolve(void 0), ms);
|
|
1555
|
-
promise.then((val) => {
|
|
1556
|
-
clearTimeout(timer);
|
|
1557
|
-
resolve(val);
|
|
1558
|
-
}, () => {
|
|
1559
|
-
clearTimeout(timer);
|
|
1560
|
-
resolve(void 0);
|
|
1561
|
-
});
|
|
1562
|
-
});
|
|
1563
|
-
}
|
|
1564
|
-
/**
|
|
1565
|
-
* Check 2 — First valid credential can reach its provider.
|
|
1566
|
-
*
|
|
1567
|
-
* Uses a best-effort HTTP GET to a known provider health URL when available.
|
|
1568
|
-
* Falls back to a simple fetch attempt and inspects the HTTP status code.
|
|
1569
|
-
* Timeout: 5 s.
|
|
1570
|
-
*
|
|
1571
|
-
* @internal
|
|
1572
|
-
*/
|
|
1573
|
-
async function runCredentialReachabilityCheck() {
|
|
1574
|
-
const name = "credential-reach";
|
|
1575
|
-
try {
|
|
1576
|
-
const entries = await getCredentialPool().list();
|
|
1577
|
-
if (entries.length === 0) return {
|
|
1578
|
-
name,
|
|
1579
|
-
status: "SKIP",
|
|
1580
|
-
message: "no credentials configured"
|
|
1581
|
-
};
|
|
1582
|
-
const provider = entries[0].provider;
|
|
1583
|
-
const probeUrl = {
|
|
1584
|
-
anthropic: "https://api.anthropic.com/v1/models",
|
|
1585
|
-
openai: "https://api.openai.com/v1/models",
|
|
1586
|
-
gemini: "https://generativelanguage.googleapis.com/v1/models",
|
|
1587
|
-
openrouter: "https://openrouter.ai/api/v1/models"
|
|
1588
|
-
}[provider] ?? `https://api.${provider}.com/v1/models`;
|
|
1589
|
-
const response = await withTimeout(fetch(probeUrl, {
|
|
1590
|
-
method: "GET",
|
|
1591
|
-
headers: { "Content-Type": "application/json" },
|
|
1592
|
-
signal: AbortSignal.timeout(5e3)
|
|
1593
|
-
}), 5e3);
|
|
1594
|
-
if (response === void 0) return {
|
|
1595
|
-
name,
|
|
1596
|
-
status: "FAIL",
|
|
1597
|
-
message: `timeout after 5 s probing ${provider} (${probeUrl})`
|
|
1598
|
-
};
|
|
1599
|
-
if (response.ok || response.status === 401 || response.status === 403) return {
|
|
1600
|
-
name,
|
|
1601
|
-
status: "PASS",
|
|
1602
|
-
message: `${provider} endpoint reachable (HTTP ${response.status})`
|
|
1603
|
-
};
|
|
1604
|
-
return {
|
|
1605
|
-
name,
|
|
1606
|
-
status: "FAIL",
|
|
1607
|
-
message: `${provider} returned HTTP ${response.status}`
|
|
1608
|
-
};
|
|
1609
|
-
} catch (err) {
|
|
1610
|
-
return {
|
|
1611
|
-
name,
|
|
1612
|
-
status: "FAIL",
|
|
1613
|
-
message: `fetch failed: ${err instanceof Error ? err.message : String(err)}`
|
|
1614
|
-
};
|
|
1615
|
-
}
|
|
1616
|
-
}
|
|
1617
|
-
/**
|
|
1618
|
-
* Check 3 — Global + project config files parse cleanly.
|
|
1619
|
-
*
|
|
1620
|
-
* Delegates to {@link loadConfig} which already handles missing files
|
|
1621
|
-
* gracefully; we surface any unexpected parsing errors as FAIL.
|
|
1622
|
-
*
|
|
1623
|
-
* @internal
|
|
1624
|
-
*/
|
|
1625
|
-
async function runConfigIntegrityCheck(cwd) {
|
|
1626
|
-
const name = "config-integrity";
|
|
1627
|
-
try {
|
|
1628
|
-
await loadConfig(cwd);
|
|
1629
|
-
return {
|
|
1630
|
-
name,
|
|
1631
|
-
status: "PASS",
|
|
1632
|
-
message: "global + project config parse cleanly"
|
|
1633
|
-
};
|
|
1634
|
-
} catch (err) {
|
|
1635
|
-
return {
|
|
1636
|
-
name,
|
|
1637
|
-
status: "FAIL",
|
|
1638
|
-
message: `config parse error: ${err instanceof Error ? err.message : String(err)}`
|
|
1639
|
-
};
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
/**
|
|
1643
|
-
* Check 4 — Detected harness responds.
|
|
1644
|
-
*
|
|
1645
|
-
* - `pi` (or `piUrl` in config) → HTTP GET `<piUrl>/health` (3 s timeout).
|
|
1646
|
-
* - `claude-code` → resolves `which claude` in PATH.
|
|
1647
|
-
* - `unknown` → SKIP.
|
|
1648
|
-
*
|
|
1649
|
-
* @internal
|
|
1650
|
-
*/
|
|
1651
|
-
async function runHarnessReachabilityCheck(cwd) {
|
|
1652
|
-
const name = "harness-reach";
|
|
1653
|
-
try {
|
|
1654
|
-
let active = process.env["CLEO_HARNESS"];
|
|
1655
|
-
if (!active) if (process.env["CLAUDECODE"] === "1") active = "claude-code";
|
|
1656
|
-
else if (process.env["CLEO_PI"] === "1") active = "pi";
|
|
1657
|
-
else active = (await getConfigValue("harness.active", cwd)).value;
|
|
1658
|
-
if (!active || active === "unknown") return {
|
|
1659
|
-
name,
|
|
1660
|
-
status: "SKIP",
|
|
1661
|
-
message: "no harness configured"
|
|
1662
|
-
};
|
|
1663
|
-
if (active === "claude-code") {
|
|
1664
|
-
const { exec } = await import('node:child_process');
|
|
1665
|
-
const { promisify } = await import('node:util');
|
|
1666
|
-
const execP = promisify(exec);
|
|
1667
|
-
try {
|
|
1668
|
-
await withTimeout(execP("which claude"), 3e3);
|
|
1669
|
-
return {
|
|
1670
|
-
name,
|
|
1671
|
-
status: "PASS",
|
|
1672
|
-
message: "`claude` binary found in PATH"
|
|
1673
|
-
};
|
|
1674
|
-
} catch {
|
|
1675
|
-
return {
|
|
1676
|
-
name,
|
|
1677
|
-
status: "FAIL",
|
|
1678
|
-
message: "`claude` binary not found — install Claude Code"
|
|
1679
|
-
};
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
if (active === "pi") {
|
|
1683
|
-
const piUrlResolved = process.env["CLEO_PI_URL"] ?? (await getConfigValue("harness.piUrl", cwd)).value;
|
|
1684
|
-
const piUrl = typeof piUrlResolved === "string" && piUrlResolved ? piUrlResolved : null;
|
|
1685
|
-
if (!piUrl) return {
|
|
1686
|
-
name,
|
|
1687
|
-
status: "SKIP",
|
|
1688
|
-
message: "pi harness active but piUrl not configured"
|
|
1689
|
-
};
|
|
1690
|
-
const healthUrl = piUrl.replace(/\/$/, "") + "/health";
|
|
1691
|
-
const response = await withTimeout(fetch(healthUrl, { signal: AbortSignal.timeout(3e3) }), 3e3);
|
|
1692
|
-
if (response === void 0) return {
|
|
1693
|
-
name,
|
|
1694
|
-
status: "FAIL",
|
|
1695
|
-
message: `timeout after 3 s (${healthUrl})`
|
|
1696
|
-
};
|
|
1697
|
-
if (response.ok) return {
|
|
1698
|
-
name,
|
|
1699
|
-
status: "PASS",
|
|
1700
|
-
message: `Pi /health returned HTTP ${response.status}`
|
|
1701
|
-
};
|
|
1702
|
-
return {
|
|
1703
|
-
name,
|
|
1704
|
-
status: "FAIL",
|
|
1705
|
-
message: `Pi /health returned HTTP ${response.status}`
|
|
1706
|
-
};
|
|
1707
|
-
}
|
|
1708
|
-
return {
|
|
1709
|
-
name,
|
|
1710
|
-
status: "SKIP",
|
|
1711
|
-
message: `unrecognised harness '${active}'`
|
|
1712
|
-
};
|
|
1713
|
-
} catch (err) {
|
|
1714
|
-
return {
|
|
1715
|
-
name,
|
|
1716
|
-
status: "FAIL",
|
|
1717
|
-
message: `harness check failed: ${err instanceof Error ? err.message : String(err)}`
|
|
1718
|
-
};
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
|
-
/**
|
|
1722
|
-
* Check 5 — SignalDock endpoint is reachable.
|
|
1723
|
-
*
|
|
1724
|
-
* Skipped when `signaldock.enabled` is `false` or not configured.
|
|
1725
|
-
* Timeout: 3 s.
|
|
1726
|
-
*
|
|
1727
|
-
* @internal
|
|
1728
|
-
*/
|
|
1729
|
-
async function runAgentRegistryReachabilityCheck(cwd) {
|
|
1730
|
-
const name = "signaldock-reach";
|
|
1731
|
-
try {
|
|
1732
|
-
if (!(await getConfigValue("signaldock.enabled", cwd)).value) return {
|
|
1733
|
-
name,
|
|
1734
|
-
status: "SKIP",
|
|
1735
|
-
message: "SignalDock not enabled"
|
|
1736
|
-
};
|
|
1737
|
-
const endpoint = (await getConfigValue("signaldock.endpoint", cwd)).value;
|
|
1738
|
-
if (!endpoint || typeof endpoint !== "string") return {
|
|
1739
|
-
name,
|
|
1740
|
-
status: "SKIP",
|
|
1741
|
-
message: "SignalDock endpoint not configured"
|
|
1742
|
-
};
|
|
1743
|
-
const healthUrl = endpoint.replace(/\/$/, "") + "/health";
|
|
1744
|
-
const response = await withTimeout(fetch(healthUrl, { signal: AbortSignal.timeout(3e3) }), 3e3);
|
|
1745
|
-
if (response === void 0) return {
|
|
1746
|
-
name,
|
|
1747
|
-
status: "FAIL",
|
|
1748
|
-
message: `timeout after 3 s (${healthUrl})`
|
|
1749
|
-
};
|
|
1750
|
-
if (response.ok) return {
|
|
1751
|
-
name,
|
|
1752
|
-
status: "PASS",
|
|
1753
|
-
message: `SignalDock /health returned HTTP ${response.status}`
|
|
1754
|
-
};
|
|
1755
|
-
return {
|
|
1756
|
-
name,
|
|
1757
|
-
status: "FAIL",
|
|
1758
|
-
message: `SignalDock /health returned HTTP ${response.status}`
|
|
1759
|
-
};
|
|
1760
|
-
} catch (err) {
|
|
1761
|
-
return {
|
|
1762
|
-
name,
|
|
1763
|
-
status: "FAIL",
|
|
1764
|
-
message: `SignalDock check failed: ${err instanceof Error ? err.message : String(err)}`
|
|
1765
|
-
};
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
/**
|
|
1769
|
-
* Check 6 — BRAIN database is present and opens cleanly.
|
|
1770
|
-
*
|
|
1771
|
-
* We perform a lightweight existence + read-access check rather than a full
|
|
1772
|
-
* Drizzle open (which would trigger migrations). The section must remain
|
|
1773
|
-
* read-only (VERIF-1).
|
|
1774
|
-
*
|
|
1775
|
-
* @internal
|
|
1776
|
-
*/
|
|
1777
|
-
async function runBrainDbCheck(cwd) {
|
|
1778
|
-
const name = "brain-db";
|
|
1779
|
-
try {
|
|
1780
|
-
const dbPath = join(resolveCleoDir(cwd), "brain.db");
|
|
1781
|
-
if (!existsSync(dbPath)) return {
|
|
1782
|
-
name,
|
|
1783
|
-
status: "FAIL",
|
|
1784
|
-
message: `brain.db not found at ${dbPath} — run cleo init`
|
|
1785
|
-
};
|
|
1786
|
-
await access(dbPath);
|
|
1787
|
-
return {
|
|
1788
|
-
name,
|
|
1789
|
-
status: "PASS",
|
|
1790
|
-
message: `brain.db accessible at ${dbPath}`
|
|
1791
|
-
};
|
|
1792
|
-
} catch (err) {
|
|
1793
|
-
return {
|
|
1794
|
-
name,
|
|
1795
|
-
status: "FAIL",
|
|
1796
|
-
message: `brain.db check failed: ${err instanceof Error ? err.message : String(err)}`
|
|
1797
|
-
};
|
|
1798
|
-
}
|
|
1799
|
-
}
|
|
1800
|
-
/**
|
|
1801
|
-
* Build the `verification` section runner.
|
|
1802
|
-
*
|
|
1803
|
-
* The runner is read-only — it never mutates config or DB state (VERIF-1).
|
|
1804
|
-
* `isConfigured()` always returns `false` so the section is never skipped
|
|
1805
|
-
* even when the rest of the wizard short-circuits (VERIF-6).
|
|
1806
|
-
*
|
|
1807
|
-
* @returns A {@link WizardSectionRunner} for the verification section.
|
|
1808
|
-
* @task T9594
|
|
1809
|
-
*/
|
|
1810
|
-
function createVerificationSection() {
|
|
1811
|
-
return {
|
|
1812
|
-
section: "verification",
|
|
1813
|
-
title: "Verification (read-only health checks)",
|
|
1814
|
-
optional: true,
|
|
1815
|
-
async isConfigured() {
|
|
1816
|
-
return false;
|
|
1817
|
-
},
|
|
1818
|
-
async run(io, options) {
|
|
1819
|
-
const cwd = options.projectRoot;
|
|
1820
|
-
io.info("Running health checks — this may take up to 5 s per network check. No state is mutated.");
|
|
1821
|
-
const checks = [];
|
|
1822
|
-
checks.push(await runCredentialPoolCheck());
|
|
1823
|
-
checks.push(await runCredentialReachabilityCheck());
|
|
1824
|
-
checks.push(await runConfigIntegrityCheck(cwd));
|
|
1825
|
-
checks.push(await runHarnessReachabilityCheck(cwd));
|
|
1826
|
-
checks.push(await runAgentRegistryReachabilityCheck(cwd));
|
|
1827
|
-
checks.push(await runBrainDbCheck(cwd));
|
|
1828
|
-
const failCount = checks.filter((c) => c.status === "FAIL").length;
|
|
1829
|
-
const passCount = checks.filter((c) => c.status === "PASS").length;
|
|
1830
|
-
const skipCount = checks.filter((c) => c.status === "SKIP").length;
|
|
1831
|
-
if (options.nonInteractive === true) io.info(JSON.stringify(checks, null, 2));
|
|
1832
|
-
else {
|
|
1833
|
-
const padEnd = (s, n) => s.padEnd(n, " ");
|
|
1834
|
-
const header = ` ${"Check".padEnd(22)} ${"Status".padEnd(6)} Message`;
|
|
1835
|
-
io.info(header);
|
|
1836
|
-
io.info(` ${"─".repeat(22)} ${"─".repeat(6)} ${"─".repeat(50)}`);
|
|
1837
|
-
for (const check of checks) {
|
|
1838
|
-
const statusLabel = check.status === "PASS" ? "PASS" : check.status === "FAIL" ? "FAIL" : "SKIP";
|
|
1839
|
-
io.info(` ${padEnd(check.name, 22)} ${padEnd(statusLabel, 6)} ${check.message}`);
|
|
1840
|
-
}
|
|
1841
|
-
io.info("");
|
|
1842
|
-
io.info(` Summary: ${passCount} PASS, ${failCount} FAIL, ${skipCount} SKIP`);
|
|
1843
|
-
}
|
|
1844
|
-
if (failCount > 0) return {
|
|
1845
|
-
changed: false,
|
|
1846
|
-
summary: `verification: ${failCount} check(s) failed — see output`
|
|
1847
|
-
};
|
|
1848
|
-
return {
|
|
1849
|
-
changed: false,
|
|
1850
|
-
summary: `verification passed: ${passCount} PASS, ${skipCount} SKIP`
|
|
1851
|
-
};
|
|
1852
|
-
}
|
|
1853
|
-
};
|
|
1854
|
-
}
|
|
1855
|
-
//#endregion
|
|
1856
|
-
//#region ../core/dist/setup/wizard.js
|
|
1857
|
-
/**
|
|
1858
|
-
* Core setup wizard engine (E-CONFIG-AUTH-UNIFY E3 / T9420).
|
|
1859
|
-
*
|
|
1860
|
-
* Hermes-style modular wizard: every section (LLM, identity, sentient,
|
|
1861
|
-
* project conventions, …) is an independent {@link WizardSectionRunner}
|
|
1862
|
-
* that can be run on its own, in a fixed pipeline, or via the Studio
|
|
1863
|
-
* `/setup` route — the engine has zero awareness of which surface (CLI
|
|
1864
|
-
* vs. web) is driving the I/O.
|
|
1865
|
-
*
|
|
1866
|
-
* The engine is intentionally I/O-agnostic: callers pass a
|
|
1867
|
-
* {@link WizardIO} implementation (a readline-backed `ConsoleWizardIO`
|
|
1868
|
-
* from the CLI, a stub recorder in tests, a SvelteKit form helper from
|
|
1869
|
-
* the Studio). The runner never imports `node:readline` directly so
|
|
1870
|
-
* unit tests can drive it without a TTY.
|
|
1871
|
-
*
|
|
1872
|
-
* ## Design pointers
|
|
1873
|
-
*
|
|
1874
|
-
* - `run(sections?)` walks every (or a named subset of) section
|
|
1875
|
-
* in declared order, gathering a per-section summary line. The
|
|
1876
|
-
* summary is returned to the caller so `cleo setup` can echo a
|
|
1877
|
-
* final overview before exiting.
|
|
1878
|
-
* - `runSection(name)` resolves the section by `section` field — this
|
|
1879
|
-
* is the field consumers see in `--section <name>` flags.
|
|
1880
|
-
* - The non-interactive mode flag is *plumbed into `WizardOptions`* so
|
|
1881
|
-
* each section can decide whether to prompt or apply CLI flags
|
|
1882
|
-
* silently. Sections that have no non-interactive contract simply
|
|
1883
|
-
* short-circuit with `{ changed: false, summary: 'skipped (non-interactive)' }`.
|
|
1884
|
-
*
|
|
1885
|
-
* ## Section contract
|
|
1886
|
-
*
|
|
1887
|
-
* Built-in sections live under `./sections/` and are exported via
|
|
1888
|
-
* {@link createBuiltinSections}. Each section's `run()` returns a
|
|
1889
|
-
* {@link WizardSectionResult} carrying:
|
|
1890
|
-
* - `changed`: did the section apply any change? Used to label the
|
|
1891
|
-
* summary line.
|
|
1892
|
-
* - `summary`: a single-line human-readable description of what was
|
|
1893
|
-
* done (or skipped).
|
|
1894
|
-
*
|
|
1895
|
-
* @task T9420
|
|
1896
|
-
* @task T9607
|
|
1897
|
-
* @task T9613
|
|
1898
|
-
* @epic T9402
|
|
1899
|
-
* @epic T9591
|
|
1900
|
-
* @see docs/plans/E-CONFIG-AUTH-UNIFY.md §3.3.5, §5.3 T-E3-1
|
|
1901
|
-
* @see docs/plans/E-CLEO-SETUP-V2.md §3.1, §3.2, §3.3, §3.4
|
|
1902
|
-
*/
|
|
1903
|
-
/**
|
|
1904
|
-
* Base class for errors that are fatal to the entire wizard run.
|
|
1905
|
-
*
|
|
1906
|
-
* `WizardRunner.invokeSection` catches and swallows section-level errors so
|
|
1907
|
-
* a single failing section does not abort the rest of the wizard. But some
|
|
1908
|
-
* error conditions (e.g. stdin closed) make further prompting impossible and
|
|
1909
|
-
* must propagate all the way out so the CLI can emit a proper LAFS error
|
|
1910
|
-
* envelope instead of silently continuing with dead prompts.
|
|
1911
|
-
*
|
|
1912
|
-
* CLI-layer error classes (e.g. `StdinClosedError` in
|
|
1913
|
-
* `packages/cleo/src/cli/lib/readline-wizard-io.ts`) extend this class so
|
|
1914
|
-
* the runner recognises them without importing CLI types.
|
|
1915
|
-
*
|
|
1916
|
-
* @task T9599
|
|
1917
|
-
*/
|
|
1918
|
-
var WizardFatalError = class WizardFatalError extends Error {
|
|
1919
|
-
constructor(message) {
|
|
1920
|
-
super(message);
|
|
1921
|
-
this.name = "WizardFatalError";
|
|
1922
|
-
}
|
|
1923
|
-
/**
|
|
1924
|
-
* Type-guard so `invokeSection` can detect subclasses without `instanceof`
|
|
1925
|
-
* across package boundaries.
|
|
1926
|
-
*/
|
|
1927
|
-
static is(err) {
|
|
1928
|
-
return err instanceof WizardFatalError;
|
|
1929
|
-
}
|
|
1930
|
-
};
|
|
1931
|
-
/**
|
|
1932
|
-
* Runs an ordered collection of {@link WizardSectionRunner} instances.
|
|
1933
|
-
*
|
|
1934
|
-
* Stateless: every method takes the registered sections from the
|
|
1935
|
-
* constructor argument and the per-invocation `io`/`options`. The
|
|
1936
|
-
* runner deliberately swallows section-level exceptions so a failing
|
|
1937
|
-
* section never aborts the rest of the wizard — exceptions are logged
|
|
1938
|
-
* via `io.error()` and the section's summary line records `failed`.
|
|
1939
|
-
*
|
|
1940
|
-
* Mirrors Hermes Agent's `setup.py` decomposition.
|
|
1941
|
-
*
|
|
1942
|
-
* @task T9420
|
|
1943
|
-
*/
|
|
1944
|
-
var WizardRunner = class {
|
|
1945
|
-
sectionList;
|
|
1946
|
-
sections;
|
|
1947
|
-
/**
|
|
1948
|
-
* Construct a runner over a fixed section list.
|
|
1949
|
-
*
|
|
1950
|
-
* The list order is preserved as the execution order for {@link run}.
|
|
1951
|
-
* Passing the same `section` id twice throws — every id MUST be unique.
|
|
1952
|
-
*
|
|
1953
|
-
* @param sections - The wizard's section runners in execution order.
|
|
1954
|
-
*/
|
|
1955
|
-
constructor(sectionList) {
|
|
1956
|
-
this.sectionList = sectionList;
|
|
1957
|
-
const map = /* @__PURE__ */ new Map();
|
|
1958
|
-
for (const section of sectionList) {
|
|
1959
|
-
if (map.has(section.section)) throw new Error(`WizardRunner: duplicate section id '${section.section}' — every section id must be unique.`);
|
|
1960
|
-
map.set(section.section, section);
|
|
1961
|
-
}
|
|
1962
|
-
this.sections = map;
|
|
1963
|
-
}
|
|
1964
|
-
/**
|
|
1965
|
-
* Return the registered section runners in declaration order.
|
|
1966
|
-
*
|
|
1967
|
-
* Read-only view — callers MUST NOT mutate.
|
|
1968
|
-
*
|
|
1969
|
-
* @returns Frozen list of section runners.
|
|
1970
|
-
*/
|
|
1971
|
-
list() {
|
|
1972
|
-
return this.sectionList;
|
|
1973
|
-
}
|
|
1974
|
-
/**
|
|
1975
|
-
* Execute every section in declaration order.
|
|
1976
|
-
*
|
|
1977
|
-
* Each section runs against the supplied `io`/`options`. Section
|
|
1978
|
-
* failures are caught and reported via `io.error()`; the next section
|
|
1979
|
-
* still runs.
|
|
1980
|
-
*
|
|
1981
|
-
* ### Skip logic (T9613 / E-CLEO-SETUP-V2 §3.4)
|
|
1982
|
-
*
|
|
1983
|
-
* Before invoking each section, `run()` calls `section.isConfigured?.(options)`.
|
|
1984
|
-
* When that returns `true` and `options.reset` is not set, the section is
|
|
1985
|
-
* bypassed with a `skipped (already configured)` summary line and an info
|
|
1986
|
-
* message directing the user to `--reset` for a full reconfigure.
|
|
1987
|
-
*
|
|
1988
|
-
* ### Progress prefix (T9613 / E-CLEO-SETUP-V2 §3.4)
|
|
1989
|
-
*
|
|
1990
|
-
* Section headers are emitted as `[N/total] title (section-id)` so
|
|
1991
|
-
* scripted consumers can parse progress reliably.
|
|
1992
|
-
*
|
|
1993
|
-
* ### First-run completion (T9613 / E-CLEO-SETUP-V2 §3.4)
|
|
1994
|
-
*
|
|
1995
|
-
* After all sections complete without any `failed:` summary line, this
|
|
1996
|
-
* method writes `auth.firstRunComplete = true` to the global config and
|
|
1997
|
-
* writes a `setup-completed.json` marker to the CLEO data directory.
|
|
1998
|
-
* The returned {@link WizardRunResult.firstRunComplete} flag reflects
|
|
1999
|
-
* whether the marker was written.
|
|
2000
|
-
*
|
|
2001
|
-
* @param io - Prompting surface.
|
|
2002
|
-
* @param options - Pre-parsed flags / programmatic bag.
|
|
2003
|
-
* @returns Aggregate run result with per-section summary lines.
|
|
2004
|
-
*/
|
|
2005
|
-
async run(io, options = {}) {
|
|
2006
|
-
const sectionsRun = [];
|
|
2007
|
-
const summary = [];
|
|
2008
|
-
const total = this.sectionList.length;
|
|
2009
|
-
let index = 0;
|
|
2010
|
-
for (const runner of this.sectionList) {
|
|
2011
|
-
index++;
|
|
2012
|
-
sectionsRun.push(runner.section);
|
|
2013
|
-
io.info(`\n[${index}/${total}] ${runner.title} (${runner.section})`);
|
|
2014
|
-
if (!options.reset && runner.isConfigured) {
|
|
2015
|
-
if (await runner.isConfigured(options)) {
|
|
2016
|
-
io.info(`[skip] ${runner.title} — already configured. Use --reset to reconfigure.`);
|
|
2017
|
-
summary.push(`${runner.section}: skipped (already configured)`);
|
|
2018
|
-
continue;
|
|
2019
|
-
}
|
|
2020
|
-
}
|
|
2021
|
-
const result = await this.invokeSection(runner, io, options);
|
|
2022
|
-
summary.push(`${runner.section}: ${result.summary}`);
|
|
2023
|
-
}
|
|
2024
|
-
if (!summary.some((line) => line.includes(": failed:"))) {
|
|
2025
|
-
try {
|
|
2026
|
-
await setConfigValue("auth.firstRunComplete", true, void 0, { global: true });
|
|
2027
|
-
const dataDir = getCleoPlatformPaths().data;
|
|
2028
|
-
await mkdir(dataDir, { recursive: true });
|
|
2029
|
-
await writeFile(join(dataDir, "setup-completed.json"), JSON.stringify({ completedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
|
|
2030
|
-
} catch {}
|
|
2031
|
-
return {
|
|
2032
|
-
sectionsRun,
|
|
2033
|
-
summary,
|
|
2034
|
-
firstRunComplete: true
|
|
2035
|
-
};
|
|
2036
|
-
}
|
|
2037
|
-
return {
|
|
2038
|
-
sectionsRun,
|
|
2039
|
-
summary,
|
|
2040
|
-
firstRunComplete: false
|
|
2041
|
-
};
|
|
2042
|
-
}
|
|
2043
|
-
/**
|
|
2044
|
-
* Execute a single named section.
|
|
2045
|
-
*
|
|
2046
|
-
* @param name - Section id matching a registered runner's `section` field.
|
|
2047
|
-
* @param io - Prompting surface.
|
|
2048
|
-
* @param options - Pre-parsed flags / programmatic bag.
|
|
2049
|
-
* @returns The section's own {@link WizardSectionResult}.
|
|
2050
|
-
* @throws When `name` is not registered.
|
|
2051
|
-
*/
|
|
2052
|
-
async runSection(name, io, options = {}) {
|
|
2053
|
-
const runner = this.sections.get(name);
|
|
2054
|
-
if (!runner) throw new Error(`WizardRunner.runSection: no section registered for id '${name}'. Known sections: ${Array.from(this.sections.keys()).join(", ") || "(none)"}.`);
|
|
2055
|
-
io.info(`\n── ${runner.title} (${runner.section}) ──`);
|
|
2056
|
-
return this.invokeSection(runner, io, options);
|
|
2057
|
-
}
|
|
2058
|
-
/**
|
|
2059
|
-
* Run one section while shielding the wizard from its exceptions.
|
|
2060
|
-
*
|
|
2061
|
-
* Section bugs surface as `failed: <message>` summary lines rather
|
|
2062
|
-
* than uncaught throws so an `cleo setup` invocation always completes
|
|
2063
|
-
* with a non-fatal report instead of a stack trace.
|
|
2064
|
-
*
|
|
2065
|
-
* **Exception**: {@link WizardFatalError} subclasses (e.g. `StdinClosedError`)
|
|
2066
|
-
* are re-thrown immediately — they signal conditions (stdin EOF, broken pipe)
|
|
2067
|
-
* where further prompting is impossible and the CLI must emit a LAFS error
|
|
2068
|
-
* envelope rather than continuing with a dead I/O surface.
|
|
2069
|
-
*
|
|
2070
|
-
* @internal
|
|
2071
|
-
*/
|
|
2072
|
-
async invokeSection(runner, io, options) {
|
|
2073
|
-
try {
|
|
2074
|
-
return await runner.run(io, options);
|
|
2075
|
-
} catch (err) {
|
|
2076
|
-
if (WizardFatalError.is(err)) throw err;
|
|
2077
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
2078
|
-
io.error(`section '${runner.section}' failed: ${message}`);
|
|
2079
|
-
return {
|
|
2080
|
-
changed: false,
|
|
2081
|
-
summary: `failed: ${message}`
|
|
2082
|
-
};
|
|
2083
|
-
}
|
|
2084
|
-
}
|
|
2085
|
-
};
|
|
2086
|
-
//#endregion
|
|
2087
|
-
//#region ../core/dist/setup/index.js
|
|
2088
|
-
/**
|
|
2089
|
-
* Setup wizard entry point (E-CONFIG-AUTH-UNIFY E3 / T9420).
|
|
2090
|
-
*
|
|
2091
|
-
* Re-exports the engine + every built-in section + a convenience
|
|
2092
|
-
* factory that wires the canonical order. Both `cleo setup` (T9421)
|
|
2093
|
-
* and the Studio `/setup` route (T-E3-8) consume this surface.
|
|
2094
|
-
*
|
|
2095
|
-
* V2 additions (T9607): re-exports {@link WizardInterruptError}.
|
|
2096
|
-
* V2 additions (T9608): re-exports {@link createIntegrationsSection}.
|
|
2097
|
-
*
|
|
2098
|
-
* @task T9420
|
|
2099
|
-
* @task T9607
|
|
2100
|
-
* @task T9608
|
|
2101
|
-
* @epic T9402
|
|
2102
|
-
* @epic T9591
|
|
2103
|
-
*/
|
|
2104
|
-
/**
|
|
2105
|
-
* Construct every built-in {@link WizardSectionRunner} in canonical order.
|
|
2106
|
-
*
|
|
2107
|
-
* Order matters: `cleo setup` walks the list verbatim. The current
|
|
2108
|
-
* order is:
|
|
2109
|
-
* 1. `llm` — credentials are the prerequisite for everything else
|
|
2110
|
-
* 2. `models-roles` — default model + per-role profiles (T11726)
|
|
2111
|
-
* 3. `identity` — agent name / SOUL.md before any agent dispatch
|
|
2112
|
-
* 4. `sentient` — daemon enablement after credentials exist
|
|
2113
|
-
* 5. `project-conventions` — strictness preset before harness/brain layering
|
|
2114
|
-
* 6. `harness` — operator selects Pi vs Claude Code (T9425)
|
|
2115
|
-
* 7. `brain` — BRAIN memory bridge mode (T9425)
|
|
2116
|
-
* 8. `integrations` — SignalDock + Studio + Conduit (T9608)
|
|
2117
|
-
* 9. `telemetry` — anonymous skills-usage telemetry (T9673)
|
|
2118
|
-
* 10. `verification` — read-only health checks (T9594)
|
|
2119
|
-
*
|
|
2120
|
-
* @param llmDeps - Optional dependencies forwarded to the `llm` section — most
|
|
2121
|
-
* notably the interactive OAuth token acquirer (T11727). The CLI surface
|
|
2122
|
-
* passes the real acquirer so the wizard OAuth path runs the inline engine;
|
|
2123
|
-
* programmatic callers omit it (OAuth path points the user at `cleo login`).
|
|
2124
|
-
* @returns Fresh array of section runner instances.
|
|
2125
|
-
* @task T9420
|
|
2126
|
-
* @task T9425
|
|
2127
|
-
* @task T9594
|
|
2128
|
-
* @task T9608
|
|
2129
|
-
* @task T9673
|
|
2130
|
-
* @task T11726
|
|
2131
|
-
* @task T11727
|
|
2132
|
-
*/
|
|
2133
|
-
function createBuiltinSections(llmDeps = {}) {
|
|
2134
|
-
return [
|
|
2135
|
-
createLlmSection(llmDeps),
|
|
2136
|
-
createModelsRolesSection(),
|
|
2137
|
-
createIdentitySection(),
|
|
2138
|
-
createSentientSection(),
|
|
2139
|
-
createProjectConventionsSection(),
|
|
2140
|
-
createHarnessSection(),
|
|
2141
|
-
createBrainSection(),
|
|
2142
|
-
createIntegrationsSection(),
|
|
2143
|
-
createTelemetrySection(),
|
|
2144
|
-
createVerificationSection()
|
|
2145
|
-
];
|
|
2146
|
-
}
|
|
2147
|
-
//#endregion
|
|
2148
|
-
//#region src/routes/api/setup/section/[name]/+server.ts
|
|
2149
|
-
/**
|
|
2150
|
-
* POST /api/setup/section/:name — run a single wizard section.
|
|
2151
|
-
*
|
|
2152
|
-
* Bridges the Studio `/setup` UI to the canonical {@link WizardSectionRunner}
|
|
2153
|
-
* pipeline shipped from `@cleocode/core/setup`. The browser supplies a
|
|
2154
|
-
* single JSON payload describing how the section should behave; the
|
|
2155
|
-
* server constructs a {@link WizardOptions} bag plus a queue-backed
|
|
2156
|
-
* `WizardIO` and invokes the matching section runner from
|
|
2157
|
-
* {@link createBuiltinSections}.
|
|
2158
|
-
*
|
|
2159
|
-
* Request body:
|
|
2160
|
-
* ```
|
|
2161
|
-
* {
|
|
2162
|
-
* nonInteractive?: boolean,
|
|
2163
|
-
* provider?: string, apiKey?: string, label?: string,
|
|
2164
|
-
* agentName?: string, soulMdContent?: string,
|
|
2165
|
-
* sentientEnabled?: boolean, tier2Enabled?: boolean,
|
|
2166
|
-
* strictness?: 'strict' | 'standard' | 'minimal',
|
|
2167
|
-
* harness?: 'pi' | 'claude-code',
|
|
2168
|
-
* brainBridgeMode?: 'digest' | 'file' | 'disabled',
|
|
2169
|
-
* projectRoot?: string,
|
|
2170
|
-
* }
|
|
2171
|
-
* ```
|
|
2172
|
-
*
|
|
2173
|
-
* Response (LAFS):
|
|
2174
|
-
* ```
|
|
2175
|
-
* { success: true, data: { section, success, changes, summary } }
|
|
2176
|
-
* ```
|
|
2177
|
-
*
|
|
2178
|
-
* - `section` — echoed section id so the client can correlate
|
|
2179
|
-
* - `success` — `true` when the runner returned without surfacing
|
|
2180
|
-
* any `io.error()` lines (i.e. no recoverable failure)
|
|
2181
|
-
* - `changes` — `result.changed` from the section runner
|
|
2182
|
-
* - `summary` — `result.summary` line from the section runner
|
|
2183
|
-
*
|
|
2184
|
-
* The endpoint is intentionally write-only against the section: it never
|
|
2185
|
-
* echoes back secret material, never returns the request payload, and
|
|
2186
|
-
* never reads credentials. The `/keys` route remains the single read
|
|
2187
|
-
* surface for credential listings.
|
|
2188
|
-
*
|
|
2189
|
-
* SECURITY: the LLM section route is bypassed by the Studio UI in favour
|
|
2190
|
-
* of POST /api/credentials directly (T9426) so that the only place the
|
|
2191
|
-
* API key crosses the wire is the dedicated credential endpoint. This
|
|
2192
|
-
* handler still supports `llm` for parity with `cleo setup --section llm`
|
|
2193
|
-
* but the API key, when supplied, is forwarded straight to the wizard
|
|
2194
|
-
* section which routes it through `addCredential` — same persistence
|
|
2195
|
-
* path as POST /api/credentials.
|
|
2196
|
-
*
|
|
2197
|
-
* @task T9427
|
|
2198
|
-
* @epic E-CONFIG-AUTH-UNIFY (E3 §5.3 T-E3-8)
|
|
2199
|
-
*/
|
|
2200
|
-
var ALLOWED_SECTIONS = new Set([
|
|
2201
|
-
"llm",
|
|
2202
|
-
"identity",
|
|
2203
|
-
"harness",
|
|
2204
|
-
"sentient",
|
|
2205
|
-
"project-conventions",
|
|
2206
|
-
"brain"
|
|
2207
|
-
]);
|
|
2208
|
-
/**
|
|
2209
|
-
* Headless {@link WizardIO} implementation for the HTTP path.
|
|
2210
|
-
*
|
|
2211
|
-
* The Studio `/setup` flow operates in **non-interactive** mode: every
|
|
2212
|
-
* answer the section needs is supplied up-front via `WizardOptions`.
|
|
2213
|
-
* If a section nevertheless asks a question (an unforeseen path),
|
|
2214
|
-
* `prompt`/`confirm`/`select` throw so the failure surfaces as a
|
|
2215
|
-
* deterministic 500 instead of hanging.
|
|
2216
|
-
*
|
|
2217
|
-
* `info` / `warn` / `error` messages are captured so the response
|
|
2218
|
-
* `success` field can flip to `false` when the section surfaced a
|
|
2219
|
-
* recoverable error via `io.error()`.
|
|
2220
|
-
*
|
|
2221
|
-
* @internal
|
|
2222
|
-
*/
|
|
2223
|
-
var HttpWizardIO = class {
|
|
2224
|
-
/** Captured info/warn/error lines, in emission order. */
|
|
2225
|
-
errors = [];
|
|
2226
|
-
warns = [];
|
|
2227
|
-
async prompt(question) {
|
|
2228
|
-
throw new Error(`HttpWizardIO: section attempted an interactive prompt ('${question}') but the Studio /setup flow only supports non-interactive section runs. Pass the required field via the POST body.`);
|
|
2229
|
-
}
|
|
2230
|
-
async confirm(question) {
|
|
2231
|
-
throw new Error(`HttpWizardIO: section attempted an interactive confirm ('${question}') but the Studio /setup flow only supports non-interactive section runs.`);
|
|
2232
|
-
}
|
|
2233
|
-
async select(question) {
|
|
2234
|
-
throw new Error(`HttpWizardIO: section attempted an interactive select ('${question}') but the Studio /setup flow only supports non-interactive section runs.`);
|
|
2235
|
-
}
|
|
2236
|
-
info(_message) {}
|
|
2237
|
-
warn(message) {
|
|
2238
|
-
this.warns.push(message);
|
|
2239
|
-
}
|
|
2240
|
-
error(message) {
|
|
2241
|
-
this.errors.push(message);
|
|
2242
|
-
}
|
|
2243
|
-
};
|
|
2244
|
-
/**
|
|
2245
|
-
* Narrow a parsed JSON body into a {@link WizardOptions} bag.
|
|
2246
|
-
*
|
|
2247
|
-
* Each field is pulled defensively — unknown types collapse to
|
|
2248
|
-
* `undefined` rather than propagating to the section. The wizard
|
|
2249
|
-
* sections themselves enforce that their required inputs are present
|
|
2250
|
-
* (e.g. `llm` requires `provider` + `apiKey`).
|
|
2251
|
-
*
|
|
2252
|
-
* @internal
|
|
2253
|
-
*/
|
|
2254
|
-
function buildOptions(body) {
|
|
2255
|
-
const options = {};
|
|
2256
|
-
if (body["nonInteractive"] !== false) options.nonInteractive = true;
|
|
2257
|
-
else options.nonInteractive = false;
|
|
2258
|
-
if (typeof body["provider"] === "string") options.provider = body["provider"];
|
|
2259
|
-
if (typeof body["apiKey"] === "string") options.apiKey = body["apiKey"];
|
|
2260
|
-
if (typeof body["label"] === "string") options.label = body["label"];
|
|
2261
|
-
if (typeof body["agentName"] === "string") options.agentName = body["agentName"];
|
|
2262
|
-
if (typeof body["soulMdContent"] === "string") options.soulMdContent = body["soulMdContent"];
|
|
2263
|
-
if (typeof body["sentientEnabled"] === "boolean") options.sentientEnabled = body["sentientEnabled"];
|
|
2264
|
-
if (typeof body["tier2Enabled"] === "boolean") options.tier2Enabled = body["tier2Enabled"];
|
|
2265
|
-
const strictness = body["strictness"];
|
|
2266
|
-
if (strictness === "strict" || strictness === "standard" || strictness === "minimal") options.strictness = strictness;
|
|
2267
|
-
const harness = body["harness"];
|
|
2268
|
-
if (harness === "pi" || harness === "claude-code") options.harness = harness;
|
|
2269
|
-
const bridgeMode = body["brainBridgeMode"];
|
|
2270
|
-
if (bridgeMode === "digest" || bridgeMode === "file" || bridgeMode === "disabled") options.brainBridgeMode = bridgeMode;
|
|
2271
|
-
if (typeof body["projectRoot"] === "string") options.projectRoot = body["projectRoot"];
|
|
2272
|
-
return options;
|
|
2273
|
-
}
|
|
2274
|
-
/**
|
|
2275
|
-
* POST /api/setup/section/:name — run the named wizard section.
|
|
2276
|
-
*
|
|
2277
|
-
* @task T9427
|
|
2278
|
-
*/
|
|
2279
|
-
var POST = async ({ request, params }) => {
|
|
2280
|
-
const name = params.name;
|
|
2281
|
-
if (!name || typeof name !== "string" || !ALLOWED_SECTIONS.has(name)) return json(err("E_VALIDATION", `Unknown wizard section '${String(name)}'. Allowed: ${Array.from(ALLOWED_SECTIONS).join(", ")}.`), { status: 400 });
|
|
2282
|
-
const section = name;
|
|
2283
|
-
const body = await parseJsonBody(request);
|
|
2284
|
-
if (isParseError(body)) return json(err("E_VALIDATION", body._parseError), { status: 400 });
|
|
2285
|
-
const options = buildOptions(body);
|
|
2286
|
-
const io = new HttpWizardIO();
|
|
2287
|
-
try {
|
|
2288
|
-
const result = await new WizardRunner(createBuiltinSections()).runSection(section, io, options);
|
|
2289
|
-
return json(ok({
|
|
2290
|
-
section,
|
|
2291
|
-
success: io.errors.length === 0,
|
|
2292
|
-
changes: result.changed,
|
|
2293
|
-
summary: result.summary
|
|
2294
|
-
}));
|
|
2295
|
-
} catch (e) {
|
|
2296
|
-
return json(err("E_SECTION_FAILED", `Section '${section}' failed: ${e instanceof Error ? e.message : String(e)}`), { status: 500 });
|
|
2297
|
-
}
|
|
2298
|
-
};
|
|
2299
|
-
|
|
2300
|
-
export { POST };
|
|
2301
|
-
//# sourceMappingURL=_server.ts-CDMurH5m.js.map
|