bazilion 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/README.md +47 -5
  2. package/dist/cli.js +1190 -640
  3. package/dist/cli.js.map +1 -1
  4. package/dist/daemon.js +5165 -1598
  5. package/dist/daemon.js.map +1 -1
  6. package/dist/migrations/0001_init.sql +318 -88
  7. package/dist/web/client/assets/AgentTabs-B3hq5a3e.js +1 -0
  8. package/dist/web/client/assets/ConfigPage-BCwfgyjD.js +1 -0
  9. package/dist/web/client/assets/FieldRow-avAFLgYW.js +1 -0
  10. package/dist/web/client/assets/Page-CwNuDhWz.js +1 -0
  11. package/dist/web/client/assets/ProductionTeamPolicyEditor-CiQ-VVDo.js +7 -0
  12. package/dist/web/client/assets/ProductionTeamPolicyEditor-DLioOiRN.css +1 -0
  13. package/dist/web/client/assets/ProfileCommunicationEditor-D84F5yfr.js +1 -0
  14. package/dist/web/client/assets/RecoveryState-QfMSuwy3.js +1 -0
  15. package/dist/web/client/assets/SectionTabs-DZzy01az.js +1 -0
  16. package/dist/web/client/assets/TeamTabs-Btoe_FAE.js +1 -0
  17. package/dist/web/client/assets/TemplatesTabs-CAYY03F5.js +1 -0
  18. package/dist/web/client/assets/_id-BeauECmk.js +1 -0
  19. package/dist/web/client/assets/_id-BqU2BodK.js +1 -0
  20. package/dist/web/client/assets/_id-CKtoio3t.js +1 -0
  21. package/dist/web/client/assets/_id-DGyKURCp.js +1 -0
  22. package/dist/web/client/assets/_id-Q98Of6k9.js +1 -0
  23. package/dist/web/client/assets/activity-DJuhhQCb.js +1 -0
  24. package/dist/web/client/assets/activity-DXN_N85w.js +1 -0
  25. package/dist/web/client/assets/agents-C5Xsdge1.js +1 -0
  26. package/dist/web/client/assets/agents-Cgxo4H5G.js +1 -0
  27. package/dist/web/client/assets/approvals-BnG7fbw-.js +1 -0
  28. package/dist/web/client/assets/approvals-DGi0PSx8.js +1 -0
  29. package/dist/web/client/assets/chevron-down-BhcBspw3.js +1 -0
  30. package/dist/web/client/assets/config-xw4NyrXF.js +3 -0
  31. package/dist/web/client/assets/context-D2V1Oi4z.js +1 -0
  32. package/dist/web/client/assets/inbox-DK6hWCMp.js +1 -0
  33. package/dist/web/client/assets/index-VdURSoM4.js +12 -0
  34. package/dist/web/client/assets/login-CvptUoMR.js +1 -0
  35. package/dist/web/client/assets/mcp-BDFM_sW-.js +1 -0
  36. package/dist/web/client/assets/members-BJvph_TR.js +1 -0
  37. package/dist/web/client/assets/memory-DRytqZCD.js +1 -0
  38. package/dist/web/client/assets/plus-C9ee3SIO.js +1 -0
  39. package/dist/web/client/assets/policy-CGP50OtQ.js +1 -0
  40. package/dist/web/client/assets/policy-K4hIbbIN.js +1 -0
  41. package/dist/web/client/assets/preload-helper-mNuBjNXU.js +1 -0
  42. package/dist/web/client/assets/react-3W8R1pOO.js +1 -0
  43. package/dist/web/client/assets/routes-DJnWYvC9.js +1 -0
  44. package/dist/web/client/assets/services-DHheiv7L.js +1 -0
  45. package/dist/web/client/assets/skills-DmsitluU.js +1 -0
  46. package/dist/web/client/assets/styles-B5eQAwLP.css +2 -0
  47. package/dist/web/client/assets/team-policy-D0jpnn2b.js +1 -0
  48. package/dist/web/client/assets/teams-BdC4gthq.js +1 -0
  49. package/dist/web/client/assets/teams-CSNyLz3l.js +1 -0
  50. package/dist/web/client/assets/teams-CbxSaorm.js +1 -0
  51. package/dist/web/client/assets/telegram-D61G_alO.js +1 -0
  52. package/dist/web/client/assets/tokens-CjRplDrJ.js +1 -0
  53. package/dist/web/client/assets/triggers-MLzTm_DM.js +1 -0
  54. package/dist/web/client/assets/welcome-wBfX9dAd.js +1 -0
  55. package/dist/web/client/assets/{ChatPane-DzEgOEqS.js → wire-constants-BxfyUMXB.js} +4 -4
  56. package/dist/web/server/assets/{AgentTabs-BOjTN7QF.js → AgentTabs-DoMDJBXH.js} +10 -7
  57. package/dist/web/server/assets/{ChatPane-BvpswYvF.js → ChatPane-eUY_dga3.js} +38 -20
  58. package/dist/web/server/assets/ConfigPage-BKlh5vOU.js +68 -0
  59. package/dist/web/server/assets/{FieldRow-DwyqycWI.js → FieldRow-B4eTegH9.js} +5 -5
  60. package/dist/web/server/assets/Page-LENulSXY.js +111 -0
  61. package/dist/web/server/assets/ProductionTeamPolicyEditor-Y4mzFFvR.js +1009 -0
  62. package/dist/web/server/assets/ProfileCommunicationEditor-C2RU-2QB.js +107 -0
  63. package/dist/web/server/assets/RecoveryState-B2SG-mrY.js +37 -0
  64. package/dist/web/server/assets/SectionTabs-BJTPr5nU.js +8 -0
  65. package/dist/web/server/assets/Sidebar-O_CH1-JD.js +964 -0
  66. package/dist/web/server/assets/TeamTabs-zZzbP1t_.js +51 -0
  67. package/dist/web/server/assets/{TemplatesTabs---7h5GYa.js → TemplatesTabs-CcRxZhJe.js} +9 -8
  68. package/dist/web/server/assets/_id-A8Xiv6Lc.js +11 -0
  69. package/dist/web/server/assets/{_id-Sjw0zhA6.js → _id-BhOB8Umi.js} +5 -5
  70. package/dist/web/server/assets/{_id-DDixKEud.js → _id-C3HY4lWg.js} +77 -20
  71. package/dist/web/server/assets/{_id-BdRiQb2H.js → _id-ClN9hY2x.js} +132 -39
  72. package/dist/web/server/assets/{_id-BqnDy_Ca.js → _id-CwyGjJeP.js} +7 -6
  73. package/dist/web/server/assets/{_id-D8duqgd5.js → _id-D27T85mU.js} +6 -5
  74. package/dist/web/server/assets/_id-D3Ap7zZA.js +377 -0
  75. package/dist/web/server/assets/_id-DinTp_7X.js +14 -0
  76. package/dist/web/server/assets/{_id-CnQflrRv.js → _id-Dj1yZ3zJ.js} +6 -6
  77. package/dist/web/server/assets/{_id-DUIrFV3G.js → _id-DkYodSkG.js} +10 -2
  78. package/dist/web/server/assets/{_id-D_Ew11ED.js → _id-IzadFZV9.js} +9 -9
  79. package/dist/web/server/assets/_id-LrvXU4Nr.js +45 -0
  80. package/dist/web/server/assets/_id-tB47Vsfp.js +42 -0
  81. package/dist/web/server/assets/_tanstack-start-manifest_v-D09Xu_6u.js +286 -0
  82. package/dist/web/server/assets/activity-BCI4mfNS.js +168 -0
  83. package/dist/web/server/assets/activity-CGCf8BQf.js +11 -0
  84. package/dist/web/server/assets/activity-D9SMqBhy.js +14 -0
  85. package/dist/web/server/assets/activity-DohitgwW.js +12 -0
  86. package/dist/web/server/assets/{agents-k5QURC4I.js → agents-BPKOshR5.js} +5 -5
  87. package/dist/web/server/assets/{profiles-C6a3RKgu.js → agents-BY74v7fM.js} +5 -5
  88. package/dist/web/server/assets/{profiles-CZ5NkmVw.js → agents-BvttypqB.js} +5 -5
  89. package/dist/web/server/assets/{agents-ChcAJUI5.js → agents-C9xlWK0Z.js} +2 -2
  90. package/dist/web/server/assets/agents-CgZMHj80.js +265 -0
  91. package/dist/web/server/assets/{profiles-LxcC_L6n.js → agents-DZuFEj0D.js} +87 -79
  92. package/dist/web/server/assets/approvals-BGU-XGIO.js +12 -0
  93. package/dist/web/server/assets/approvals-CWcFHlor.js +14 -0
  94. package/dist/web/server/assets/approvals-CbFXFvG8.js +11 -0
  95. package/dist/web/server/assets/approvals-DCaVw1Mz.js +280 -0
  96. package/dist/web/server/assets/{auth-DzRAMwVt.js → auth-byfSx6Ja.js} +6 -2
  97. package/dist/web/server/assets/{config-CHaCv89D.js → config-BDCJdtj2.js} +1 -1
  98. package/dist/web/server/assets/{config-CdVjqjin.js → config-D2LAsud2.js} +31 -52
  99. package/dist/web/server/assets/{config-Bq3o924J.js → config-TeIoyYYc.js} +2 -2
  100. package/dist/web/server/assets/context-B-XDf6Ym.js +12 -0
  101. package/dist/web/server/assets/context-BXGo5Vfi.js +12 -0
  102. package/dist/web/server/assets/context-DrkrIWun.js +47 -0
  103. package/dist/web/server/assets/{createServerRpc-CeKECg65.js → createServerRpc-pU-IQV2Y.js} +1 -1
  104. package/dist/web/server/assets/{createSsrRpc-ZBGxhl8t.js → createSsrRpc-DFsIAfFd.js} +1 -1
  105. package/dist/web/server/assets/{empty-plugin-adapters-DKUlnwwl.js → empty-plugin-adapters-Cq4--YW-.js} +1 -1
  106. package/dist/web/server/assets/{inbox-CkiSvD14.js → inbox-B3-TRsNI.js} +1 -1
  107. package/dist/web/server/assets/{inbox-Bxb3W04M.js → inbox-BardsGyy.js} +2 -2
  108. package/dist/web/server/assets/inbox-CUIyf9MT.js +131 -0
  109. package/dist/web/server/assets/login-Bx5LEyGP.js +118 -0
  110. package/dist/web/server/assets/login-CmWvxfTK.js +136 -0
  111. package/dist/web/server/assets/{mcp-BsFKEoXt.js → mcp-2pwT9HU8.js} +1 -1
  112. package/dist/web/server/assets/{mcp-BU_kKENi.js → mcp-BJjLIdP0.js} +105 -112
  113. package/dist/web/server/assets/{mcp-CKqwG4mt.js → mcp-DIWTogHM.js} +2 -2
  114. package/dist/web/server/assets/members-CCv17cjQ.js +46 -0
  115. package/dist/web/server/assets/members-CW5aBe81.js +12 -0
  116. package/dist/web/server/assets/members-VdPwD6CE.js +12 -0
  117. package/dist/web/server/assets/{memory-BaYnfm7K.js → memory-Dngc13Nw.js} +9 -9
  118. package/dist/web/server/assets/{memory-CQaqWnyM.js → memory-a8Kz57Kh.js} +22 -19
  119. package/dist/web/server/assets/{memory-Ns2-Z31p.js → memory-pZ4pZT7p.js} +6 -6
  120. package/dist/web/server/assets/policy-BYVXqsan.js +11 -0
  121. package/dist/web/server/assets/policy-Bb-vEgqg.js +40 -0
  122. package/dist/web/server/assets/policy-BcGELcc9.js +490 -0
  123. package/dist/web/server/assets/policy-C30AeFIb.js +21 -0
  124. package/dist/web/server/assets/router-DIdp8ZNt.js +504 -0
  125. package/dist/web/server/assets/{routes-C61gBiXa.js → routes-CXz4hTAr.js} +6 -6
  126. package/dist/web/server/assets/{routes-Ce2VWrU9.js → routes-Jb0zjKav.js} +16 -13
  127. package/dist/web/server/assets/{routes-V9URcp1v.js → routes-lIclH9Br.js} +2 -2
  128. package/dist/web/server/assets/services-B9yBWDX0.js +79 -0
  129. package/dist/web/server/assets/{services-Ccc5s2bS.js → services-C4szdhPx.js} +4 -4
  130. package/dist/web/server/assets/{services-DhRiNeq0.js → services-wG8I06oS.js} +1 -1
  131. package/dist/web/server/assets/skills-BZdqiDig.js +358 -0
  132. package/dist/web/server/assets/{skills-l2cyQ3zS.js → skills-C-UgkuCW.js} +2 -2
  133. package/dist/web/server/assets/{skills-CFIWVg32.js → skills-a9VSWHWq.js} +1 -1
  134. package/dist/web/server/assets/{start-CYDpZ6cb.js → start-WH8WzTL_.js} +1 -1
  135. package/dist/web/server/assets/team-policy-vPG01onj.js +180 -0
  136. package/dist/web/server/assets/teams-3im0oQnS.js +11 -0
  137. package/dist/web/server/assets/teams-CpQ0YgWf.js +112 -0
  138. package/dist/web/server/assets/teams-DEpQR2QA.js +14 -0
  139. package/dist/web/server/assets/teams-DqfrEoH6.js +36 -0
  140. package/dist/web/server/assets/teams-MjqgsmC3.js +12 -0
  141. package/dist/web/server/assets/teams-OIkHuxy1.js +12 -0
  142. package/dist/web/server/assets/teams-jBtvnk59.js +193 -0
  143. package/dist/web/server/assets/{telegram-DfAddLdv.js → telegram-7ub--6xz.js} +44 -56
  144. package/dist/web/server/assets/{telegram-T3l9KtiE.js → telegram-Bazhmpr4.js} +2 -2
  145. package/dist/web/server/assets/{telegram-BdaUIjvs.js → telegram-DNgCWebD.js} +1 -1
  146. package/dist/web/server/assets/{tokens-DdpnfV_Y.js → tokens-BnwFbV7T.js} +2 -2
  147. package/dist/web/server/assets/{tokens-BCz3PSoT.js → tokens-DPDMSN5O.js} +1 -1
  148. package/dist/web/server/assets/tokens-yyTSfBSN.js +186 -0
  149. package/dist/web/server/assets/{triggers-BzJG1nN5.js → triggers-BMpHsGIr.js} +5 -4
  150. package/dist/web/server/assets/{triggers-BcH_6PW1.js → triggers-C_0y6QV9.js} +1 -1
  151. package/dist/web/server/assets/{triggers-BcTTwMfy.js → triggers-Ca57_qym.js} +2 -2
  152. package/dist/web/server/assets/{welcome-CP4CZ9B6.js → welcome-IYHGurWx.js} +23 -15
  153. package/dist/web/server/assets/{wire-constants-Deb4NxBb.js → wire-constants-C8nBJcU3.js} +3 -3
  154. package/dist/web/server/server.js +126 -95
  155. package/dist/worker.js +185 -146
  156. package/dist/worker.js.map +1 -1
  157. package/package.json +8 -7
  158. package/dist/migrations/0002_profile_groups.sql +0 -38
  159. package/dist/migrations/0003_agent_telegram.sql +0 -40
  160. package/dist/migrations/0004_agent_mirror_mode.sql +0 -17
  161. package/dist/migrations/0005_group_topic_name_format.sql +0 -15
  162. package/dist/migrations/0006_telegram_acl.sql +0 -18
  163. package/dist/migrations/0007_mcp_servers.sql +0 -30
  164. package/dist/migrations/0008_seed_user_md.sql +0 -39
  165. package/dist/web/client/assets/AgentTabs-DioGqUVR.js +0 -1
  166. package/dist/web/client/assets/ConfigTabs-pY-V0Rie.js +0 -1
  167. package/dist/web/client/assets/FieldRow-CNKma5LE.js +0 -1
  168. package/dist/web/client/assets/MembersEditor-C6UpqDdV.js +0 -1
  169. package/dist/web/client/assets/SpawnTeamModal-BEkNCKXm.js +0 -1
  170. package/dist/web/client/assets/TemplatesTabs-UM04RMO9.js +0 -1
  171. package/dist/web/client/assets/_id-BNJapCT4.js +0 -1
  172. package/dist/web/client/assets/_id-CjGoV8Mr.js +0 -1
  173. package/dist/web/client/assets/_id-DehuCHUw.js +0 -1
  174. package/dist/web/client/assets/_id-Dz9fjcCM.js +0 -1
  175. package/dist/web/client/assets/agents-M6omAXcZ.js +0 -1
  176. package/dist/web/client/assets/config-DIuEc5bm.js +0 -3
  177. package/dist/web/client/assets/groups-DpE2d2zZ.js +0 -1
  178. package/dist/web/client/assets/inbox-BPnLsRNf.js +0 -1
  179. package/dist/web/client/assets/index-MAJuXnie.js +0 -12
  180. package/dist/web/client/assets/login-CawJX16E.js +0 -1
  181. package/dist/web/client/assets/mcp-DIrh9-v_.js +0 -1
  182. package/dist/web/client/assets/memory-BpHbdKsd.js +0 -1
  183. package/dist/web/client/assets/preload-helper-CvnapA2_.js +0 -1
  184. package/dist/web/client/assets/profile-groups-ByoKak0c.js +0 -1
  185. package/dist/web/client/assets/profiles-BEjv8LGo.js +0 -1
  186. package/dist/web/client/assets/routes-D2COHy7v.js +0 -1
  187. package/dist/web/client/assets/services-D212jSK_.js +0 -1
  188. package/dist/web/client/assets/skills-Da0MURjY.js +0 -1
  189. package/dist/web/client/assets/styles-BgE5bCHA.css +0 -2
  190. package/dist/web/client/assets/telegram-Czh2MdVm.js +0 -1
  191. package/dist/web/client/assets/tokens-E_JvO5JN.js +0 -1
  192. package/dist/web/client/assets/triggers-BBRZQOm7.js +0 -1
  193. package/dist/web/client/assets/welcome-Dn-zvmBE.js +0 -1
  194. package/dist/web/client/assets/wire-constants-BkT5-597.js +0 -1
  195. package/dist/web/server/assets/ConfigTabs-CyuxzesF.js +0 -41
  196. package/dist/web/server/assets/MembersEditor-BWQztvrX.js +0 -131
  197. package/dist/web/server/assets/Sidebar-DmEiewRN.js +0 -529
  198. package/dist/web/server/assets/SpawnTeamModal-dSN421k_.js +0 -107
  199. package/dist/web/server/assets/_id-BKev9H1p.js +0 -12
  200. package/dist/web/server/assets/_id-BNwlbWHP.js +0 -24
  201. package/dist/web/server/assets/_id-CRqqi8IE.js +0 -161
  202. package/dist/web/server/assets/_id-CXg-Blec.js +0 -367
  203. package/dist/web/server/assets/_tanstack-start-manifest_v-D9FLKShQ.js +0 -178
  204. package/dist/web/server/assets/agents-C7SBPN0M.js +0 -210
  205. package/dist/web/server/assets/groups-CbSwND2r.js +0 -12
  206. package/dist/web/server/assets/groups-CeRRlZaZ.js +0 -150
  207. package/dist/web/server/assets/groups-pk4CYSuf.js +0 -21
  208. package/dist/web/server/assets/inbox-DU27iHv_.js +0 -133
  209. package/dist/web/server/assets/login-CNznncgA.js +0 -58
  210. package/dist/web/server/assets/login-CQybKk7Y.js +0 -74
  211. package/dist/web/server/assets/profile-groups-CiU06yN1.js +0 -28
  212. package/dist/web/server/assets/profile-groups-D21MYoLM.js +0 -208
  213. package/dist/web/server/assets/profile-groups-aoJleXHP.js +0 -12
  214. package/dist/web/server/assets/router-BrDascdO.js +0 -460
  215. package/dist/web/server/assets/services-B91w2f-X.js +0 -94
  216. package/dist/web/server/assets/skills-D89ND2kR.js +0 -321
  217. package/dist/web/server/assets/tokens-CkKqrtk-.js +0 -193
@@ -0,0 +1,964 @@
1
+ import "./wire-constants-C8nBJcU3.js";
2
+ import { t as Button } from "./Button-Dsnw22OF.js";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { Link, useNavigate, useRouter } from "@tanstack/react-router";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { Archive, Bot, ChevronDown, ChevronRight, Pencil, Plus, Send, UsersRound } from "lucide-react";
7
+ //#region src/components/CreateTeamDialog.tsx
8
+ function CreateTeamDialog({ onClose }) {
9
+ const router = useRouter();
10
+ const [id, setId] = useState("");
11
+ const [name, setName] = useState("");
12
+ const [link, setLink] = useState("");
13
+ const [busy, setBusy] = useState(false);
14
+ const [err, setErr] = useState(null);
15
+ async function submit(e) {
16
+ e.preventDefault();
17
+ setErr(null);
18
+ if (!id.trim()) {
19
+ setErr("id is required");
20
+ return;
21
+ }
22
+ setBusy(true);
23
+ try {
24
+ const body = { id: id.trim() };
25
+ if (name.trim()) body.name = name.trim();
26
+ if (link.trim()) body.link = link.trim();
27
+ const res = await fetch("/api/teams", {
28
+ method: "POST",
29
+ headers: { "content-type": "application/json" },
30
+ body: JSON.stringify(body)
31
+ });
32
+ if (!res.ok) {
33
+ const e = await res.json().catch(() => ({}));
34
+ throw new Error(e.error ?? `${res.status} ${res.statusText}`);
35
+ }
36
+ onClose();
37
+ await router.invalidate();
38
+ } catch (e) {
39
+ setErr(e.message);
40
+ setBusy(false);
41
+ }
42
+ }
43
+ return /* @__PURE__ */ jsx("div", {
44
+ onClick: onClose,
45
+ onKeyDown: (event) => {
46
+ if (event.key === "Escape") onClose();
47
+ },
48
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-charcoal/45 p-4 backdrop-blur-sm",
49
+ children: /* @__PURE__ */ jsxs("form", {
50
+ role: "dialog",
51
+ "aria-modal": "true",
52
+ "aria-labelledby": "create-team-title",
53
+ onSubmit: submit,
54
+ onClick: (e) => e.stopPropagation(),
55
+ className: "max-h-[calc(100dvh-2rem)] w-full max-w-lg overflow-y-auto rounded-3xl border border-frost bg-card p-6 shadow-baziu-lg sm:p-7",
56
+ children: [
57
+ /* @__PURE__ */ jsx("h2", {
58
+ id: "create-team-title",
59
+ className: "font-serif text-2xl text-foreground",
60
+ children: "Create a team"
61
+ }),
62
+ /* @__PURE__ */ jsxs("p", {
63
+ className: "text-sm text-muted-foreground mb-4",
64
+ children: [
65
+ "A team is a collaboration context — one filesystem root, one USER.md, one roster. The slot lives at ",
66
+ /* @__PURE__ */ jsx("code", {
67
+ className: "font-mono",
68
+ children: "~/.bazilion/teams/<slug>/"
69
+ }),
70
+ "."
71
+ ]
72
+ }),
73
+ /* @__PURE__ */ jsxs("div", {
74
+ className: "mb-3 grid gap-3 sm:grid-cols-2",
75
+ children: [/* @__PURE__ */ jsxs("label", {
76
+ className: "block text-sm",
77
+ children: ["ID (slug)", /* @__PURE__ */ jsx("input", {
78
+ type: "text",
79
+ value: id,
80
+ onChange: (e) => setId(e.target.value),
81
+ required: true,
82
+ pattern: "[a-z0-9][a-z0-9_-]*",
83
+ placeholder: "myproject",
84
+ autoFocus: true,
85
+ className: "mt-1 block w-full rounded-md border bg-background px-3 py-2 outline-none focus:ring-2 focus:ring-ring/30"
86
+ })]
87
+ }), /* @__PURE__ */ jsxs("label", {
88
+ className: "block text-sm",
89
+ children: [
90
+ "Name ",
91
+ /* @__PURE__ */ jsx("span", {
92
+ className: "text-muted-foreground font-normal",
93
+ children: "(optional)"
94
+ }),
95
+ /* @__PURE__ */ jsx("input", {
96
+ type: "text",
97
+ value: name,
98
+ onChange: (e) => setName(e.target.value),
99
+ className: "mt-1 block w-full rounded-md border bg-background px-3 py-2 outline-none focus:ring-2 focus:ring-ring/30"
100
+ })
101
+ ]
102
+ })]
103
+ }),
104
+ /* @__PURE__ */ jsxs("label", {
105
+ className: "block text-sm mb-3",
106
+ children: [
107
+ "Link target",
108
+ " ",
109
+ /* @__PURE__ */ jsx("span", {
110
+ className: "text-muted-foreground font-normal",
111
+ children: "(optional, absolute path)"
112
+ }),
113
+ /* @__PURE__ */ jsx("input", {
114
+ type: "text",
115
+ value: link,
116
+ onChange: (e) => setLink(e.target.value),
117
+ placeholder: "/home/you/projects/myrepo",
118
+ className: "mt-1 block w-full rounded-md border bg-background px-3 py-2 outline-none focus:ring-2 focus:ring-ring/30"
119
+ }),
120
+ /* @__PURE__ */ jsx("span", {
121
+ className: "mt-1 block text-xs text-muted-foreground",
122
+ children: "Leave blank to create a fresh directory. Supply an absolute path to materialize the slot as a symlink to your existing project tree."
123
+ })
124
+ ]
125
+ }),
126
+ err && /* @__PURE__ */ jsx("p", {
127
+ className: "err mt-2",
128
+ children: err
129
+ }),
130
+ /* @__PURE__ */ jsxs("div", {
131
+ className: "mt-5 flex justify-end gap-2",
132
+ children: [/* @__PURE__ */ jsx(Button, {
133
+ variant: "ghost",
134
+ onClick: onClose,
135
+ children: "Cancel"
136
+ }), /* @__PURE__ */ jsx(Button, {
137
+ variant: "primary",
138
+ type: "submit",
139
+ disabled: busy,
140
+ children: busy ? "Creating…" : "Create"
141
+ })]
142
+ })
143
+ ]
144
+ })
145
+ });
146
+ }
147
+ //#endregion
148
+ //#region src/components/SpawnDialog.tsx
149
+ function SpawnDialog({ profileId, teamHint, teams, onClose }) {
150
+ const navigate = useNavigate();
151
+ const [name, setName] = useState("");
152
+ const [teamId, setTeamId] = useState(teamHint ?? teams.find((team) => team.id === "default")?.id ?? teams[0]?.id ?? "");
153
+ const [placement, setPlacement] = useState("profile_defaults");
154
+ const [busy, setBusy] = useState(false);
155
+ const [err, setErr] = useState(null);
156
+ const [preview, setPreview] = useState(null);
157
+ async function requestBody() {
158
+ const policy = await fetch(`/api/teams/${encodeURIComponent(teamId)}/policy`);
159
+ if (!policy.ok) throw new Error("The selected Team policy is unavailable. Reload and try again.");
160
+ const current = await policy.json();
161
+ return {
162
+ current,
163
+ body: {
164
+ profileId,
165
+ teamId,
166
+ teamExpectedRevision: current.teamPolicy.revision,
167
+ placement
168
+ }
169
+ };
170
+ }
171
+ async function review() {
172
+ setErr(null);
173
+ setBusy(true);
174
+ try {
175
+ const { body } = await requestBody();
176
+ const response = await fetch("/api/agents/placement-preview", {
177
+ method: "POST",
178
+ headers: { "content-type": "application/json" },
179
+ body: JSON.stringify(body)
180
+ });
181
+ if (!response.ok) {
182
+ const value = await response.json().catch(() => null);
183
+ throw new Error(value?.error ?? `Preview failed (${response.status})`);
184
+ }
185
+ setPreview(await response.json());
186
+ } catch (cause) {
187
+ setErr(cause.message);
188
+ } finally {
189
+ setBusy(false);
190
+ }
191
+ }
192
+ async function submit(e) {
193
+ e.preventDefault();
194
+ setErr(null);
195
+ setBusy(true);
196
+ try {
197
+ if (!preview) {
198
+ await review();
199
+ return;
200
+ }
201
+ const body = {
202
+ profile: profileId,
203
+ teamExpectedRevision: preview.currentRevision,
204
+ placement
205
+ };
206
+ if (name.trim()) body.name = name.trim();
207
+ if (teamId) body.teamId = teamId;
208
+ const res = await fetch("/api/agents", {
209
+ method: "POST",
210
+ headers: { "content-type": "application/json" },
211
+ body: JSON.stringify(body)
212
+ });
213
+ if (!res.ok) {
214
+ const e = await res.json().catch(() => ({}));
215
+ throw new Error(e.error ?? `${res.status} ${res.statusText}`);
216
+ }
217
+ const created = (await res.json()).agent;
218
+ onClose();
219
+ await navigate({
220
+ to: "/",
221
+ search: { agent: created.id }
222
+ });
223
+ } catch (e) {
224
+ setErr(e.message);
225
+ setBusy(false);
226
+ }
227
+ }
228
+ return /* @__PURE__ */ jsx(Backdrop, {
229
+ onClose,
230
+ children: /* @__PURE__ */ jsxs("form", {
231
+ role: "dialog",
232
+ "aria-modal": "true",
233
+ "aria-labelledby": "spawn-agent-title",
234
+ onSubmit: submit,
235
+ className: "max-h-[calc(100dvh-2rem)] w-full max-w-lg overflow-y-auto rounded-3xl border border-frost bg-card p-6 shadow-baziu-lg sm:p-7",
236
+ onClick: (e) => e.stopPropagation(),
237
+ children: [
238
+ /* @__PURE__ */ jsx("h3", {
239
+ id: "spawn-agent-title",
240
+ className: "font-serif text-xl text-foreground mb-1",
241
+ children: "Spawn a new agent"
242
+ }),
243
+ /* @__PURE__ */ jsxs("p", {
244
+ className: "text-sm text-muted-foreground mb-4",
245
+ children: ["Profile: ", /* @__PURE__ */ jsx("code", {
246
+ className: "font-mono",
247
+ children: profileId
248
+ })]
249
+ }),
250
+ /* @__PURE__ */ jsxs("label", {
251
+ className: "block text-sm text-foreground mb-3",
252
+ children: [
253
+ "Agent name",
254
+ " ",
255
+ /* @__PURE__ */ jsx("span", {
256
+ className: "text-muted-foreground font-normal",
257
+ children: "(optional — defaults to the profile's name)"
258
+ }),
259
+ /* @__PURE__ */ jsx("input", {
260
+ type: "text",
261
+ value: name,
262
+ onChange: (e) => setName(e.target.value),
263
+ autoFocus: true,
264
+ autoComplete: "off",
265
+ className: "mt-1 block w-full rounded-md border bg-background px-3 py-2 outline-none focus:ring-2 focus:ring-ring/30"
266
+ })
267
+ ]
268
+ }),
269
+ /* @__PURE__ */ jsxs("label", {
270
+ className: "block text-sm text-foreground mb-3",
271
+ children: [
272
+ "Initial policy placement",
273
+ /* @__PURE__ */ jsxs("select", {
274
+ value: placement,
275
+ onChange: (e) => {
276
+ setPlacement(e.target.value);
277
+ setPreview(null);
278
+ },
279
+ className: "mt-1 block w-full rounded-md border bg-background px-3 py-2",
280
+ children: [/* @__PURE__ */ jsx("option", {
281
+ value: "profile_defaults",
282
+ children: "Agent-template defaults"
283
+ }), /* @__PURE__ */ jsx("option", {
284
+ value: "isolated",
285
+ children: "isolated"
286
+ })]
287
+ }),
288
+ /* @__PURE__ */ jsx("span", {
289
+ className: "mt-1 block text-xs text-muted-foreground",
290
+ children: "The current Team revision is checked again when you submit."
291
+ })
292
+ ]
293
+ }),
294
+ /* @__PURE__ */ jsxs("label", {
295
+ className: "block text-sm text-foreground mb-3",
296
+ children: ["Team", /* @__PURE__ */ jsx("select", {
297
+ value: teamId,
298
+ onChange: (e) => {
299
+ setTeamId(e.target.value);
300
+ setPreview(null);
301
+ },
302
+ className: "mt-1 block w-full rounded-md border bg-background px-3 py-2 outline-none focus:ring-2 focus:ring-ring/30",
303
+ children: teams.map((g) => /* @__PURE__ */ jsxs("option", {
304
+ value: g.id,
305
+ children: [g.name, g.id === "default" ? " (default)" : ""]
306
+ }, g.id))
307
+ })]
308
+ }),
309
+ err && /* @__PURE__ */ jsx("p", {
310
+ className: "err mt-2",
311
+ children: err
312
+ }),
313
+ preview && /* @__PURE__ */ jsxs("div", {
314
+ className: "mt-3 rounded-md border border-sapphire-light bg-sapphire-glow p-3 text-sm",
315
+ children: [
316
+ /* @__PURE__ */ jsxs("p", { children: [
317
+ "Creating this Agent advances Team revision ",
318
+ preview.currentRevision,
319
+ " → ",
320
+ /* @__PURE__ */ jsx("strong", { children: preview.resultingRevision }),
321
+ " and adds ",
322
+ /* @__PURE__ */ jsx("strong", { children: preview.addedEdges.length }),
323
+ " directed edges to the existing ",
324
+ preview.existingEdges.length,
325
+ "."
326
+ ] }),
327
+ /* @__PURE__ */ jsx("ul", {
328
+ className: "mt-2 max-h-36 overflow-auto",
329
+ children: preview.addedEdges.map((edge, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("code", { children: [
330
+ edge.sourceKind,
331
+ edge.sourceId ? `:${edge.sourceId}` : "",
332
+ " → ",
333
+ edge.targetKind,
334
+ edge.targetId ? `:${edge.targetId}` : ""
335
+ ] }) }, `${edge.sourceKind}:${edge.sourceId ?? ""}>${edge.targetKind}:${edge.targetId ?? ""}:${index}`))
336
+ }),
337
+ preview.addedEdges.length === 0 && /* @__PURE__ */ jsx("p", {
338
+ className: "mt-2",
339
+ children: "The new Agent starts isolated."
340
+ })
341
+ ]
342
+ }),
343
+ /* @__PURE__ */ jsxs("div", {
344
+ className: "mt-5 flex justify-end gap-2",
345
+ children: [/* @__PURE__ */ jsx(Button, {
346
+ variant: "ghost",
347
+ onClick: onClose,
348
+ children: "Cancel"
349
+ }), /* @__PURE__ */ jsx(Button, {
350
+ variant: "primary",
351
+ type: "submit",
352
+ disabled: busy,
353
+ children: busy ? "Working…" : preview ? "Commit reviewed creation" : "Review exact policy"
354
+ })]
355
+ })
356
+ ]
357
+ })
358
+ });
359
+ }
360
+ function Backdrop({ children, onClose }) {
361
+ return /* @__PURE__ */ jsx("div", {
362
+ onClick: onClose,
363
+ onKeyDown: (event) => {
364
+ if (event.key === "Escape") onClose();
365
+ },
366
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-charcoal/45 p-4 backdrop-blur-sm",
367
+ children
368
+ });
369
+ }
370
+ //#endregion
371
+ //#region src/components/SpawnTeamModal.tsx
372
+ function SpawnTeamModal({ profileGroup: team, teams, onClose, onSpawned }) {
373
+ const [teamId, setTeamId] = useState("");
374
+ const [userMd, setUserMd] = useState("");
375
+ const [error, setError] = useState(null);
376
+ const [busy, setBusy] = useState(false);
377
+ const [preview, setPreview] = useState(null);
378
+ const dialogRef = useRef(null);
379
+ useEffect(() => {
380
+ dialogRef.current?.focus();
381
+ }, []);
382
+ async function requestBody() {
383
+ const target = teamId.trim();
384
+ if (!target) throw new Error("target Team slug is required");
385
+ const existing = teams.find((team) => team.id === target);
386
+ let teamExpectedRevision;
387
+ if (existing) {
388
+ const policyResponse = await fetch(`/api/teams/${encodeURIComponent(target)}/policy`);
389
+ if (!policyResponse.ok) throw new Error("The target Team policy is unavailable.");
390
+ teamExpectedRevision = (await policyResponse.json()).teamPolicy.revision;
391
+ }
392
+ return {
393
+ target,
394
+ body: {
395
+ templateExpectedRevision: team.currentRevision,
396
+ teamId: target,
397
+ ...teamExpectedRevision ? { teamExpectedRevision } : {},
398
+ mode: existing ? "append" : "initialize",
399
+ ...userMd ? { userMd } : {}
400
+ }
401
+ };
402
+ }
403
+ async function review() {
404
+ setBusy(true);
405
+ setError(null);
406
+ setPreview(null);
407
+ try {
408
+ const { body } = await requestBody();
409
+ const response = await fetch(`/api/team-templates/${encodeURIComponent(team.id)}/spawn/preview`, {
410
+ method: "POST",
411
+ headers: { "content-type": "application/json" },
412
+ body: JSON.stringify(body)
413
+ });
414
+ if (!response.ok) throw new Error((await response.json().catch(() => null))?.error ?? response.statusText);
415
+ setPreview(await response.json());
416
+ } catch (cause) {
417
+ setError(cause.message);
418
+ } finally {
419
+ setBusy(false);
420
+ }
421
+ }
422
+ async function spawn() {
423
+ const target = teamId.trim();
424
+ if (!target) {
425
+ setError("target Team slug is required");
426
+ return;
427
+ }
428
+ setBusy(true);
429
+ setError(null);
430
+ try {
431
+ const { body } = await requestBody();
432
+ const response = await fetch(`/api/team-templates/${encodeURIComponent(team.id)}/spawn`, {
433
+ method: "POST",
434
+ headers: { "content-type": "application/json" },
435
+ body: JSON.stringify(body)
436
+ });
437
+ if (!response.ok) throw new Error((await response.json().catch(() => null))?.error ?? response.statusText);
438
+ onSpawned(target);
439
+ } catch (cause) {
440
+ setError(cause.message);
441
+ } finally {
442
+ setBusy(false);
443
+ }
444
+ }
445
+ return /* @__PURE__ */ jsx("div", {
446
+ role: "dialog",
447
+ "aria-modal": "true",
448
+ "aria-labelledby": "spawn-team-title",
449
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-charcoal/45 p-4 backdrop-blur-sm",
450
+ onClick: onClose,
451
+ onKeyDown: (event) => {
452
+ if (event.key === "Escape") onClose();
453
+ },
454
+ children: /* @__PURE__ */ jsxs("div", {
455
+ ref: dialogRef,
456
+ tabIndex: -1,
457
+ className: "max-h-[calc(100dvh-2rem)] w-full max-w-lg overflow-y-auto rounded-3xl border border-frost bg-card p-6 shadow-baziu-lg sm:p-7",
458
+ role: "document",
459
+ onClick: (event) => event.stopPropagation(),
460
+ onKeyDown: (event) => {
461
+ if (event.key !== "Escape") event.stopPropagation();
462
+ },
463
+ children: [
464
+ /* @__PURE__ */ jsxs("h2", {
465
+ id: "spawn-team-title",
466
+ children: ["Spawn team — ", team.name]
467
+ }),
468
+ error && /* @__PURE__ */ jsx("div", {
469
+ className: "err",
470
+ children: error
471
+ }),
472
+ /* @__PURE__ */ jsxs("p", {
473
+ className: "muted",
474
+ children: [
475
+ "Uses immutable Team revision ",
476
+ team.currentRevision,
477
+ ". Existing Teams append at their current reviewed revision; a new Team initializes at revision 1. Conflicts never overwrite newer state."
478
+ ]
479
+ }),
480
+ /* @__PURE__ */ jsxs("label", { children: [
481
+ "target Team slug",
482
+ /* @__PURE__ */ jsx("input", {
483
+ value: teamId,
484
+ onChange: (event) => {
485
+ setTeamId(event.target.value);
486
+ setPreview(null);
487
+ },
488
+ list: "canonical-teams",
489
+ required: true
490
+ }),
491
+ /* @__PURE__ */ jsx("datalist", {
492
+ id: "canonical-teams",
493
+ children: teams.map((team) => /* @__PURE__ */ jsx("option", {
494
+ value: team.id,
495
+ children: team.name
496
+ }, team.id))
497
+ })
498
+ ] }),
499
+ /* @__PURE__ */ jsxs("label", { children: ["starter USER.md (new Team only)", /* @__PURE__ */ jsx("textarea", {
500
+ rows: 3,
501
+ value: userMd,
502
+ onChange: (event) => {
503
+ setUserMd(event.target.value);
504
+ setPreview(null);
505
+ },
506
+ className: "font-mono text-[0.88em] leading-[1.55]"
507
+ })] }),
508
+ preview && /* @__PURE__ */ jsxs("div", {
509
+ className: "mt-4 rounded-md border border-sapphire-light bg-sapphire-glow p-3 text-sm",
510
+ children: [
511
+ /* @__PURE__ */ jsxs("p", { children: [
512
+ /* @__PURE__ */ jsx("strong", { children: preview.mode === "initialize" ? "Initialize" : "Append" }),
513
+ " produces Team revision ",
514
+ preview.resultingRevision,
515
+ ", adds ",
516
+ preview.newMembers.length,
517
+ " Agents, and results in ",
518
+ preview.edges.length,
519
+ " directed allow edges."
520
+ ] }),
521
+ /* @__PURE__ */ jsx("ul", {
522
+ className: "mt-2 max-h-40 overflow-auto",
523
+ children: preview.newMembers.map((member) => /* @__PURE__ */ jsxs("li", { children: [
524
+ member.agentName,
525
+ " · stable source slot ",
526
+ /* @__PURE__ */ jsx("code", { children: member.slotId })
527
+ ] }, member.slotId))
528
+ }),
529
+ /* @__PURE__ */ jsxs("details", {
530
+ className: "mt-2",
531
+ children: [/* @__PURE__ */ jsx("summary", {
532
+ className: "cursor-pointer",
533
+ children: "Review exact edge topology"
534
+ }), /* @__PURE__ */ jsx("ul", {
535
+ className: "mt-2 max-h-40 overflow-auto",
536
+ children: preview.edges.map((edge, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("code", { children: [
537
+ edge.sourceKind,
538
+ edge.sourceId ? `:${edge.sourceId}` : "",
539
+ " → ",
540
+ edge.targetKind,
541
+ edge.targetId ? `:${edge.targetId}` : ""
542
+ ] }) }, `${edge.sourceKind}:${edge.sourceId ?? ""}>${edge.targetKind}:${edge.targetId ?? ""}:${index}`))
543
+ })]
544
+ })
545
+ ]
546
+ }),
547
+ /* @__PURE__ */ jsxs("div", {
548
+ className: "mt-4 flex justify-end gap-2",
549
+ children: [/* @__PURE__ */ jsx(Button, {
550
+ variant: "ghost",
551
+ onClick: onClose,
552
+ children: "cancel"
553
+ }), preview ? /* @__PURE__ */ jsx(Button, {
554
+ variant: "primary",
555
+ onClick: spawn,
556
+ disabled: busy,
557
+ children: busy ? "spawning…" : `commit ${preview.mode}`
558
+ }) : /* @__PURE__ */ jsx(Button, {
559
+ variant: "primary",
560
+ onClick: review,
561
+ disabled: busy || team.slotCount === 0,
562
+ children: busy ? "reviewing…" : "review exact result"
563
+ })]
564
+ })
565
+ ]
566
+ })
567
+ });
568
+ }
569
+ //#endregion
570
+ //#region src/components/Sidebar.tsx
571
+ var SIDEBAR_OPEN_GROUPS_COOKIE = "bz_sidebar_open_groups";
572
+ function writeOpenGroupsCookie(map) {
573
+ if (typeof document === "undefined") return;
574
+ const value = encodeURIComponent(JSON.stringify(map));
575
+ document.cookie = `${SIDEBAR_OPEN_GROUPS_COOKIE}=${value}; Path=/; Max-Age=31536000; SameSite=Lax`;
576
+ }
577
+ function Sidebar({ agents, teams, profiles, profileGroups, selectedAgentId, initialOpenGroups }) {
578
+ const router = useRouter();
579
+ const [spawnFor, setSpawnFor] = useState(null);
580
+ const [spawnTeamFor, setSpawnTeamFor] = useState(null);
581
+ const [createGroupOpen, setCreateGroupOpen] = useState(false);
582
+ const [menuOpen, setMenuOpen] = useState(false);
583
+ const newButtonRef = useRef(null);
584
+ const restoreNewButton = () => window.requestAnimationFrame(() => newButtonRef.current?.focus());
585
+ const [openGroups, setOpenGroups] = useState(() => initialOpenGroups ?? {});
586
+ async function rename(a) {
587
+ const next = window.prompt(`rename "${a.name}" to:`, a.name)?.trim();
588
+ if (!next || next === a.name) return;
589
+ const res = await fetch(`/api/agents/${a.id}`, {
590
+ method: "PATCH",
591
+ headers: { "content-type": "application/json" },
592
+ body: JSON.stringify({ name: next })
593
+ });
594
+ if (!res.ok) {
595
+ const body = await res.json().catch(() => null);
596
+ alert(body?.error ?? res.statusText);
597
+ return;
598
+ }
599
+ await router.invalidate();
600
+ }
601
+ async function archive(a) {
602
+ if (!confirm(`archive "${a.name}"? (reversible — find under "show archived")`)) return;
603
+ const res = await fetch(`/api/agents/${a.id}/archive`, { method: "POST" });
604
+ if (!res.ok && res.status !== 204) {
605
+ alert(res.statusText);
606
+ return;
607
+ }
608
+ await router.invalidate();
609
+ }
610
+ const sortedProfiles = [...profiles].sort((a, b) => {
611
+ if (a.id === "default") return -1;
612
+ if (b.id === "default") return 1;
613
+ return 0;
614
+ });
615
+ const sortedGroups = [...teams].sort((a, b) => {
616
+ if (a.id === "default") return -1;
617
+ if (b.id === "default") return 1;
618
+ return 0;
619
+ });
620
+ const agentsByGroup = /* @__PURE__ */ new Map();
621
+ for (const a of agents) {
622
+ const list = agentsByGroup.get(a.teamId) ?? [];
623
+ list.push(a);
624
+ agentsByGroup.set(a.teamId, list);
625
+ }
626
+ const selectedTeamId = agents.find((a) => a.id === selectedAgentId)?.teamId ?? null;
627
+ return /* @__PURE__ */ jsxs("aside", {
628
+ className: "flex h-full flex-col overflow-hidden rounded-2xl border border-border bg-card shadow-baziu-sm",
629
+ children: [
630
+ /* @__PURE__ */ jsxs("header", {
631
+ className: "flex items-center justify-between gap-3 border-b border-border bg-muted/30 px-3 py-2.5",
632
+ children: [/* @__PURE__ */ jsxs("div", {
633
+ className: "min-w-0",
634
+ children: [/* @__PURE__ */ jsxs("div", {
635
+ className: "flex items-center gap-2 text-sm font-semibold text-foreground",
636
+ children: [/* @__PURE__ */ jsx("span", {
637
+ className: "flex size-7 items-center justify-center rounded-lg bg-accent text-accent-foreground",
638
+ children: /* @__PURE__ */ jsx(Bot, {
639
+ className: "size-4",
640
+ "aria-hidden": "true"
641
+ })
642
+ }), /* @__PURE__ */ jsx("span", { children: "Agents" })]
643
+ }), /* @__PURE__ */ jsxs("p", {
644
+ className: "mt-0.5 truncate pl-9 text-[0.7rem] text-muted-foreground",
645
+ children: [
646
+ agents.length,
647
+ " agent",
648
+ agents.length === 1 ? "" : "s",
649
+ " across ",
650
+ teams.length,
651
+ " team",
652
+ teams.length === 1 ? "" : "s"
653
+ ]
654
+ })]
655
+ }), /* @__PURE__ */ jsxs("div", {
656
+ className: "relative",
657
+ children: [/* @__PURE__ */ jsxs("button", {
658
+ ref: newButtonRef,
659
+ type: "button",
660
+ onClick: () => setMenuOpen((v) => !v),
661
+ "aria-expanded": menuOpen,
662
+ "aria-haspopup": "menu",
663
+ className: "unstyled inline-flex h-8 items-center gap-1 rounded-lg border border-border bg-card px-2.5 text-xs font-semibold text-foreground shadow-baziu-sm transition-colors hover:border-primary/30 hover:bg-accent hover:text-accent-foreground",
664
+ children: [
665
+ /* @__PURE__ */ jsx(Plus, {
666
+ className: "size-3.5",
667
+ "aria-hidden": "true"
668
+ }),
669
+ "New",
670
+ /* @__PURE__ */ jsx(ChevronDown, {
671
+ className: `size-3.5 text-muted-foreground transition-transform ${menuOpen ? "rotate-180" : ""}`,
672
+ "aria-hidden": "true"
673
+ })
674
+ ]
675
+ }), menuOpen && /* @__PURE__ */ jsxs("div", {
676
+ role: "menu",
677
+ className: "absolute right-0 top-[calc(100%+0.4rem)] z-20 w-60 overflow-hidden rounded-xl border border-border bg-popover p-1.5 text-popover-foreground shadow-baziu-lg",
678
+ onMouseLeave: () => setMenuOpen(false),
679
+ children: [
680
+ profiles.length === 0 ? /* @__PURE__ */ jsxs("div", {
681
+ className: "rounded-lg bg-muted/40 px-3 py-2.5 text-xs leading-5 text-muted-foreground",
682
+ children: [
683
+ "No Agent templates yet.",
684
+ " ",
685
+ /* @__PURE__ */ jsx("a", {
686
+ href: "/templates/agents",
687
+ className: "text-primary underline",
688
+ children: "Create one to spawn agents."
689
+ })
690
+ ]
691
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
692
+ className: "flex items-center gap-1.5 px-2.5 pb-1 pt-1 text-[0.68rem] font-semibold uppercase tracking-[0.1em] text-muted-foreground",
693
+ children: [/* @__PURE__ */ jsx(Bot, {
694
+ className: "size-3",
695
+ "aria-hidden": "true"
696
+ }), "Agent templates"]
697
+ }), sortedProfiles.map((p) => /* @__PURE__ */ jsxs("button", {
698
+ type: "button",
699
+ role: "menuitem",
700
+ onClick: () => {
701
+ setMenuOpen(false);
702
+ setSpawnFor({ profileId: p.id });
703
+ },
704
+ className: "unstyled flex min-h-8 w-full items-center gap-2 rounded-lg px-2.5 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
705
+ children: [
706
+ /* @__PURE__ */ jsx("span", {
707
+ className: "flex size-6 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground",
708
+ children: /* @__PURE__ */ jsx(Bot, {
709
+ className: "size-3.5",
710
+ "aria-hidden": "true"
711
+ })
712
+ }),
713
+ /* @__PURE__ */ jsx("span", {
714
+ className: "min-w-0 flex-1 truncate",
715
+ children: p.name || p.id
716
+ }),
717
+ p.id === "default" && /* @__PURE__ */ jsx("span", {
718
+ className: "rounded-full border border-border bg-muted px-1.5 py-0.5 text-[0.65rem] font-semibold text-muted-foreground",
719
+ children: "Default"
720
+ })
721
+ ]
722
+ }, p.id))] }),
723
+ /* @__PURE__ */ jsx("div", { className: "my-1.5 h-px bg-border" }),
724
+ /* @__PURE__ */ jsxs("div", {
725
+ className: "flex items-center gap-1.5 px-2.5 pb-1 pt-1 text-[0.68rem] font-semibold uppercase tracking-[0.1em] text-muted-foreground",
726
+ children: [/* @__PURE__ */ jsx(UsersRound, {
727
+ className: "size-3",
728
+ "aria-hidden": "true"
729
+ }), "Team templates"]
730
+ }),
731
+ profileGroups.length === 0 ? /* @__PURE__ */ jsxs("div", {
732
+ className: "rounded-lg bg-muted/40 px-3 py-2 text-xs leading-5 text-muted-foreground",
733
+ children: [
734
+ "No team templates yet.",
735
+ " ",
736
+ /* @__PURE__ */ jsx("a", {
737
+ href: "/templates/teams",
738
+ className: "text-primary underline",
739
+ children: "Create one"
740
+ }),
741
+ "."
742
+ ]
743
+ }) : profileGroups.map((pg) => /* @__PURE__ */ jsxs("button", {
744
+ type: "button",
745
+ role: "menuitem",
746
+ disabled: pg.slotCount === 0,
747
+ title: pg.slotCount === 0 ? "Add at least one member before spawning" : void 0,
748
+ onClick: () => {
749
+ setMenuOpen(false);
750
+ setSpawnTeamFor(pg);
751
+ },
752
+ className: "unstyled flex min-h-8 w-full items-center gap-2 rounded-lg px-2.5 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent",
753
+ children: [
754
+ /* @__PURE__ */ jsx("span", {
755
+ className: "flex size-6 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground",
756
+ children: /* @__PURE__ */ jsx(UsersRound, {
757
+ className: "size-3.5",
758
+ "aria-hidden": "true"
759
+ })
760
+ }),
761
+ /* @__PURE__ */ jsx("span", {
762
+ className: "min-w-0 flex-1 truncate",
763
+ children: pg.name || pg.id
764
+ }),
765
+ /* @__PURE__ */ jsx("span", {
766
+ className: "inline-flex min-w-6 items-center justify-center rounded-full bg-muted px-1.5 font-mono text-[0.68rem] text-muted-foreground",
767
+ children: pg.slotCount
768
+ })
769
+ ]
770
+ }, pg.id)),
771
+ /* @__PURE__ */ jsx("div", { className: "my-1.5 h-px bg-border" }),
772
+ /* @__PURE__ */ jsxs("button", {
773
+ type: "button",
774
+ onClick: () => {
775
+ setMenuOpen(false);
776
+ setCreateGroupOpen(true);
777
+ },
778
+ className: "unstyled flex min-h-8 w-full items-center gap-2 rounded-lg px-2.5 py-1.5 text-left text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
779
+ children: [/* @__PURE__ */ jsx(Plus, {
780
+ className: "size-3.5",
781
+ "aria-hidden": "true"
782
+ }), "Create a team"]
783
+ })
784
+ ]
785
+ })]
786
+ })]
787
+ }),
788
+ /* @__PURE__ */ jsx("nav", {
789
+ className: "flex-1 overflow-y-auto p-1.5",
790
+ "aria-label": "Teams and agents",
791
+ children: agents.length === 0 && teams.length === 0 ? /* @__PURE__ */ jsxs("div", {
792
+ className: "m-1 flex flex-col items-center rounded-xl border border-dashed border-border bg-muted/30 px-4 py-6 text-center",
793
+ children: [
794
+ /* @__PURE__ */ jsx("span", {
795
+ className: "mb-2 flex size-9 items-center justify-center rounded-full bg-accent text-accent-foreground",
796
+ children: /* @__PURE__ */ jsx(Bot, {
797
+ className: "size-4",
798
+ "aria-hidden": "true"
799
+ })
800
+ }),
801
+ /* @__PURE__ */ jsx("p", {
802
+ className: "text-sm font-semibold text-foreground",
803
+ children: "No agents yet"
804
+ }),
805
+ /* @__PURE__ */ jsx("p", {
806
+ className: "mt-1 text-xs leading-5 text-muted-foreground",
807
+ children: "Spawn your first agent to start a conversation."
808
+ }),
809
+ /* @__PURE__ */ jsxs("a", {
810
+ href: "/agents",
811
+ className: "mt-3 inline-flex items-center gap-1 text-xs font-semibold text-primary hover:text-primary/80",
812
+ children: ["Open agent setup", /* @__PURE__ */ jsx(ChevronRight, {
813
+ className: "size-3.5",
814
+ "aria-hidden": "true"
815
+ })]
816
+ })
817
+ ]
818
+ }) : sortedGroups.map((g) => {
819
+ const teamAgents = agentsByGroup.get(g.id) ?? [];
820
+ const containsSelected = selectedTeamId === g.id;
821
+ const stored = openGroups[g.id];
822
+ return /* @__PURE__ */ jsxs("details", {
823
+ open: stored !== void 0 ? stored : containsSelected || g.id === "default",
824
+ onToggle: (e) => {
825
+ const next = e.currentTarget.open;
826
+ if (openGroups[g.id] === next) return;
827
+ const merged = {
828
+ ...openGroups,
829
+ [g.id]: next
830
+ };
831
+ writeOpenGroupsCookie(merged);
832
+ setOpenGroups(merged);
833
+ router.invalidate();
834
+ },
835
+ className: "team/details mb-1 last:mb-0",
836
+ children: [/* @__PURE__ */ jsxs("summary", {
837
+ className: `flex min-h-8 cursor-pointer list-none items-center gap-1.5 rounded-lg px-2 py-1.5 text-sm transition-colors hover:bg-accent hover:text-accent-foreground ${containsSelected ? "bg-muted/60 text-foreground" : "text-muted-foreground"}`,
838
+ children: [
839
+ /* @__PURE__ */ jsx(ChevronRight, {
840
+ className: "size-3.5 shrink-0 transition-transform team-open/details:rotate-90",
841
+ "aria-hidden": "true"
842
+ }),
843
+ /* @__PURE__ */ jsx("span", {
844
+ className: "flex size-5 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground",
845
+ children: /* @__PURE__ */ jsx(UsersRound, {
846
+ className: "size-3",
847
+ "aria-hidden": "true"
848
+ })
849
+ }),
850
+ /* @__PURE__ */ jsx("span", {
851
+ className: "min-w-0 flex-1 truncate font-medium",
852
+ children: g.name
853
+ }),
854
+ g.id === "default" && /* @__PURE__ */ jsx("span", {
855
+ className: "text-[0.62rem] font-semibold uppercase tracking-wide text-muted-foreground",
856
+ children: "Default"
857
+ }),
858
+ /* @__PURE__ */ jsx("span", {
859
+ className: "inline-flex min-w-6 items-center justify-center rounded-full border border-border bg-card px-1.5 font-mono text-[0.68rem] text-muted-foreground",
860
+ children: teamAgents.length
861
+ })
862
+ ]
863
+ }), teamAgents.length === 0 ? /* @__PURE__ */ jsx("div", {
864
+ className: "py-2 pl-12 pr-2 text-xs text-muted-foreground",
865
+ children: "No agents in this team"
866
+ }) : /* @__PURE__ */ jsx("div", {
867
+ className: "space-y-0.5 py-0.5 pl-2",
868
+ children: teamAgents.map((a) => /* @__PURE__ */ jsxs("div", {
869
+ className: "team/row relative rounded-lg",
870
+ children: [/* @__PURE__ */ jsxs(Link, {
871
+ to: "/",
872
+ search: { agent: a.id },
873
+ "aria-current": a.id === selectedAgentId ? "page" : void 0,
874
+ className: `block min-h-11 rounded-lg border border-transparent py-1.5 pl-2.5 pr-[4.6rem] transition-colors hover:bg-accent/70 ${a.id === selectedAgentId ? "border-primary/20 bg-accent text-accent-foreground shadow-baziu-sm" : "text-foreground"}`,
875
+ children: [/* @__PURE__ */ jsxs("div", {
876
+ className: "flex items-center gap-1.5 text-sm font-medium",
877
+ children: [
878
+ /* @__PURE__ */ jsx("span", {
879
+ className: `size-1.5 shrink-0 rounded-full ${a.id === selectedAgentId ? "bg-primary" : "bg-border"}`,
880
+ "aria-hidden": "true"
881
+ }),
882
+ /* @__PURE__ */ jsx("span", {
883
+ className: "min-w-0 flex-1 truncate",
884
+ children: a.name
885
+ }),
886
+ a.telegramTopicId !== null && /* @__PURE__ */ jsx("span", {
887
+ className: "shrink-0 text-primary",
888
+ title: `Telegram topic #${a.telegramTopicId}`,
889
+ "aria-label": `Bound to Telegram topic ${a.telegramTopicId}`,
890
+ children: /* @__PURE__ */ jsx(Send, {
891
+ className: "size-3",
892
+ "aria-hidden": "true"
893
+ })
894
+ })
895
+ ]
896
+ }), /* @__PURE__ */ jsxs("div", {
897
+ className: "mt-0.5 flex gap-2 pl-3 font-mono text-[0.65rem] text-muted-foreground",
898
+ children: [/* @__PURE__ */ jsx("span", {
899
+ className: "uppercase tracking-wide",
900
+ children: a.status
901
+ }), /* @__PURE__ */ jsx("span", { children: a.id.slice(0, 8) })]
902
+ })]
903
+ }), /* @__PURE__ */ jsxs("div", {
904
+ className: "absolute right-1 top-1/2 z-10 flex -translate-y-1/2 gap-0.5",
905
+ children: [/* @__PURE__ */ jsx("button", {
906
+ type: "button",
907
+ onClick: () => rename(a),
908
+ title: "Rename",
909
+ "aria-label": `Rename ${a.name}`,
910
+ className: "unstyled flex size-8 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-card hover:text-primary focus-visible:bg-card",
911
+ children: /* @__PURE__ */ jsx(Pencil, {
912
+ className: "size-3.5",
913
+ "aria-hidden": "true"
914
+ })
915
+ }), /* @__PURE__ */ jsx("button", {
916
+ type: "button",
917
+ onClick: () => archive(a),
918
+ title: "Archive",
919
+ "aria-label": `Archive ${a.name}`,
920
+ className: "unstyled flex size-8 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive focus-visible:bg-destructive/10 focus-visible:text-destructive",
921
+ children: /* @__PURE__ */ jsx(Archive, {
922
+ className: "size-3.5",
923
+ "aria-hidden": "true"
924
+ })
925
+ })]
926
+ })]
927
+ }, a.id))
928
+ })]
929
+ }, g.id);
930
+ })
931
+ }),
932
+ spawnFor && /* @__PURE__ */ jsx(SpawnDialog, {
933
+ profileId: spawnFor.profileId,
934
+ teamHint: spawnFor.teamHint,
935
+ teams: sortedGroups,
936
+ onClose: () => {
937
+ setSpawnFor(null);
938
+ restoreNewButton();
939
+ }
940
+ }),
941
+ spawnTeamFor && /* @__PURE__ */ jsx(SpawnTeamModal, {
942
+ profileGroup: spawnTeamFor,
943
+ teams: sortedGroups,
944
+ onClose: () => {
945
+ setSpawnTeamFor(null);
946
+ restoreNewButton();
947
+ },
948
+ onSpawned: (slug) => {
949
+ setSpawnTeamFor(null);
950
+ router.navigate({
951
+ to: "/teams/$id",
952
+ params: { id: slug }
953
+ });
954
+ }
955
+ }),
956
+ createGroupOpen && /* @__PURE__ */ jsx(CreateTeamDialog, { onClose: () => {
957
+ setCreateGroupOpen(false);
958
+ restoreNewButton();
959
+ } })
960
+ ]
961
+ });
962
+ }
963
+ //#endregion
964
+ export { Sidebar as n, SIDEBAR_OPEN_GROUPS_COOKIE as t };