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
package/dist/cli.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { defineCommand as defineCommand23, runCommand, showUsage } from "citty";
4
+ import { defineCommand as defineCommand25, runCommand, showUsage } from "citty";
5
5
 
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "bazilion",
9
- version: "0.8.0",
10
- description: "Multi-agent runtime CLI \u2014 spawn LLM agents, manage profiles/groups/skills, and run the local daemon.",
9
+ version: "0.10.0",
10
+ description: "Multi-agent runtime CLI \u2014 spawn LLM agents, manage profiles/teams/skills, and run the local daemon.",
11
11
  license: "MIT",
12
12
  repository: {
13
13
  type: "git",
@@ -49,11 +49,12 @@ var package_default = {
49
49
  access: "public"
50
50
  },
51
51
  dependencies: {
52
- "@earendil-works/pi-agent-core": "^0.79.10",
53
- "@earendil-works/pi-ai": "^0.79.10",
54
- "@earendil-works/pi-coding-agent": "^0.79.10",
52
+ "@earendil-works/pi-agent-core": "^0.80.6",
53
+ "@earendil-works/pi-ai": "^0.80.6",
54
+ "@earendil-works/pi-coding-agent": "^0.80.6",
55
55
  "@hono/node-server": "^2.0.6",
56
56
  "@mozilla/readability": "^0.6.0",
57
+ "@playwright/browser-chromium": "^1.61.0",
57
58
  "@tanstack/react-router": "1.170.16",
58
59
  "@tobilu/qmd": "^2.5.3",
59
60
  "adm-zip": "^0.5.17",
@@ -277,13 +278,13 @@ function asPaths(v) {
277
278
  return v ? Array.isArray(v) ? v : [v] : [];
278
279
  }
279
280
  var spawnCmd = defineCommand({
280
- meta: { name: "spawn", description: "Spawn an agent from a profile into a group" },
281
+ meta: { name: "spawn", description: "Spawn an agent from a profile into a team" },
281
282
  args: {
282
283
  profile: { type: "string", required: true, description: "Profile id" },
283
284
  name: { type: "string", description: "Agent name (defaults to profile name)" },
284
- group: {
285
+ team: {
285
286
  type: "string",
286
- description: "Group to join (defaults to 'default')"
287
+ description: "Team to join (defaults to 'default')"
287
288
  },
288
289
  model: { type: "string", description: "Override profile default model" },
289
290
  reasoning: {
@@ -293,14 +294,21 @@ var spawnCmd = defineCommand({
293
294
  },
294
295
  async run({ args }) {
295
296
  const client = createClient2();
297
+ const teamId = args.team ?? "default";
298
+ const policy = await client.get(
299
+ `/api/teams/${encodeURIComponent(teamId)}/policy`
300
+ );
296
301
  const body = {
297
302
  profileId: args.profile,
298
303
  name: args.name,
299
304
  model: args.model,
300
305
  reasoningLevel: args.reasoning,
301
- groupId: args.group
306
+ teamId,
307
+ teamExpectedRevision: policy.teamPolicy.revision,
308
+ placement: "profile_defaults"
302
309
  };
303
- const agent = await client.post("/api/agents", body);
310
+ const response = await client.post("/api/agents", body);
311
+ const agent = response.agent;
304
312
  console.log(`spawned agent ${agent.id} (${agent.name})`);
305
313
  console.log(`dir: ${agent.dir}`);
306
314
  }
@@ -364,12 +372,12 @@ var listCmd = defineCommand({
364
372
  async run({ args }) {
365
373
  const client = createClient2();
366
374
  const q = args.all ? "?includeArchived=true" : "";
367
- const list = await client.get(`/api/agents${q}`);
368
- if (list.length === 0) {
375
+ const list3 = await client.get(`/api/agents${q}`);
376
+ if (list3.length === 0) {
369
377
  console.log("(no agents)");
370
378
  return;
371
379
  }
372
- const rows = list.map(
380
+ const rows = list3.map(
373
381
  (a) => args.long ? [a.id, a.status, a.name, a.profileId] : (
374
382
  // Short UUID prefix — all CLI commands accept 4+ char prefixes now.
375
383
  [a.id.slice(0, 8), a.status, a.name]
@@ -392,7 +400,7 @@ var showCmd = defineCommand({
392
400
  console.log(`profile: ${r.profile.id}`);
393
401
  console.log(`model: ${r.model}`);
394
402
  console.log(`dir: ${r.agent.dir}`);
395
- console.log(`group: ${r.group.id} ${r.group.path}`);
403
+ console.log(`team: ${r.team.id} ${r.team.path}`);
396
404
  console.log("skills:");
397
405
  if (r.skills.length === 0) {
398
406
  console.log(" (none)");
@@ -430,7 +438,13 @@ var deleteCmd = defineCommand({
430
438
  },
431
439
  async run({ args }) {
432
440
  const client = createClient2();
433
- await client.del(`/api/agents/${args.id}`);
441
+ const agent = await client.get(`/api/agents/${encodeURIComponent(args.id)}`);
442
+ const policy = await client.get(
443
+ `/api/teams/${encodeURIComponent(agent.team.id)}/policy`
444
+ );
445
+ await client.del(
446
+ `/api/agents/${encodeURIComponent(args.id)}?expectedTeamRevision=${policy.teamPolicy.revision}`
447
+ );
434
448
  console.log(`deleted agent ${args.id}`);
435
449
  }
436
450
  });
@@ -632,8 +646,8 @@ var chatContextCmd = defineCommand({
632
646
  if (ctx.systemPrompt.skillsListChars > 0) {
633
647
  console.log(` skills line: ${ctx.systemPrompt.skillsListChars.toLocaleString()} chars`);
634
648
  }
635
- if (ctx.systemPrompt.groupListChars > 0) {
636
- console.log(` group block: ${ctx.systemPrompt.groupListChars.toLocaleString()} chars`);
649
+ if (ctx.systemPrompt.teamListChars > 0) {
650
+ console.log(` team block: ${ctx.systemPrompt.teamListChars.toLocaleString()} chars`);
637
651
  }
638
652
  if (ctx.systemPrompt.userMdChars > 0) {
639
653
  console.log(` user_md block: ${ctx.systemPrompt.userMdChars.toLocaleString()} chars`);
@@ -662,10 +676,10 @@ var chatContextCmd = defineCommand({
662
676
  }
663
677
  console.log("");
664
678
  }
665
- console.log("## group");
666
- console.log(` - ${ctx.group.id} (${ctx.group.name}): ${ctx.group.path}`);
667
- if (ctx.group.userMdChars > 0) {
668
- console.log(` user_md: ${ctx.group.userMdChars.toLocaleString()} chars`);
679
+ console.log("## team");
680
+ console.log(` - ${ctx.team.id} (${ctx.team.name}): ${ctx.team.path}`);
681
+ if (ctx.team.userMdChars > 0) {
682
+ console.log(` user_md: ${ctx.team.userMdChars.toLocaleString()} chars`);
669
683
  }
670
684
  console.log("");
671
685
  console.log("## history");
@@ -788,16 +802,28 @@ var skillCmd = defineCommand({
788
802
  }
789
803
  });
790
804
  var moveCmd = defineCommand({
791
- meta: { name: "move", description: "Move an agent to a different group" },
805
+ meta: { name: "move", description: "Move an agent to a different team" },
792
806
  args: {
793
807
  agent: { type: "positional", required: true },
794
- group: { type: "positional", required: true }
808
+ team: { type: "positional", required: true }
795
809
  },
796
810
  async run({ args }) {
797
811
  const client = createClient2();
798
- const body = { groupId: args.group };
799
- await client.patch(`/api/agents/${args.agent}/group`, body);
800
- console.log(`moved ${args.agent} to group ${args.group}`);
812
+ const [agent, destination] = await Promise.all([
813
+ client.get(`/api/agents/${encodeURIComponent(args.agent)}`),
814
+ client.get(`/api/teams/${encodeURIComponent(args.team)}/policy`)
815
+ ]);
816
+ const source = await client.get(
817
+ `/api/teams/${encodeURIComponent(agent.team.id)}/policy`
818
+ );
819
+ const body = {
820
+ teamId: args.team,
821
+ sourceExpectedRevision: source.teamPolicy.revision,
822
+ destinationExpectedRevision: destination.teamPolicy.revision,
823
+ placement: "profile_defaults"
824
+ };
825
+ await client.patch(`/api/agents/${args.agent}/team`, body);
826
+ console.log(`moved ${args.agent} to team ${args.team}`);
801
827
  }
802
828
  });
803
829
  var sessionHeadCmd = defineCommand({
@@ -852,15 +878,102 @@ var agentCommand = defineCommand({
852
878
  }
853
879
  });
854
880
 
881
+ // src/commands/approval.ts
882
+ import { defineCommand as defineCommand2 } from "citty";
883
+ var list = defineCommand2({
884
+ meta: { name: "list", description: "List communication approval queue/history" },
885
+ args: {
886
+ status: { type: "string", default: "pending" },
887
+ team: { type: "string" },
888
+ json: { type: "boolean" }
889
+ },
890
+ async run({ args }) {
891
+ const query = new URLSearchParams({ status: args.status, limit: "100" });
892
+ if (args.team) query.set("teamId", args.team);
893
+ const body = await createClient2().get(
894
+ `/api/approvals?${query}`
895
+ );
896
+ if (args.json) return console.log(JSON.stringify(body, null, 2));
897
+ if (!body.approvals.length) return console.log("(no approvals)");
898
+ for (const line of columnize([
899
+ ["id", "status", "path", "origin", "expires"],
900
+ ...body.approvals.map((item) => [
901
+ item.id,
902
+ item.status,
903
+ `${endpoint(item.source)} -> ${endpoint(item.target)}`,
904
+ item.origin,
905
+ new Date(item.expiresAt).toISOString()
906
+ ])
907
+ ]))
908
+ console.log(line);
909
+ }
910
+ });
911
+ var show = defineCommand2({
912
+ meta: { name: "show", description: "Show one approval including payload and audit events" },
913
+ args: { id: { type: "positional", required: true }, json: { type: "boolean" } },
914
+ async run({ args }) {
915
+ const item = await createClient2().get(
916
+ `/api/approvals/${encodeURIComponent(args.id)}`
917
+ );
918
+ if (args.json) return console.log(JSON.stringify(item, null, 2));
919
+ console.log(`# ${item.id}`);
920
+ console.log(`status: ${item.status}`);
921
+ console.log(`attempt: ${item.attemptKind}:${item.attemptId}`);
922
+ console.log(`path: ${endpoint(item.source)} -> ${endpoint(item.target)}`);
923
+ console.log(`origin: ${item.origin}`);
924
+ console.log(`expires: ${new Date(item.expiresAt).toISOString()}`);
925
+ console.log(
926
+ `revisions: ${item.policyRefs.map((ref) => `${ref.teamId}@${ref.revision}`).join(", ")}`
927
+ );
928
+ console.log(`events: ${item.events.map((event) => event.event).join(" -> ")}`);
929
+ }
930
+ });
931
+ function decision(name) {
932
+ return defineCommand2({
933
+ meta: {
934
+ name,
935
+ description: name === "approve" ? "Approve and deliver one captured attempt" : `${name === "deny" ? "Deny" : "Cancel"} one pending attempt`
936
+ },
937
+ args: {
938
+ id: { type: "positional", required: true },
939
+ reason: { type: "string" },
940
+ yes: { type: "boolean", description: "Required explicit non-interactive confirmation" },
941
+ json: { type: "boolean" }
942
+ },
943
+ async run({ args }) {
944
+ if (!args.yes) throw new Error(`refusing ${name}: review with approval show, then pass --yes`);
945
+ const item = await createClient2().post(
946
+ `/api/approvals/${encodeURIComponent(args.id)}/${name}`,
947
+ args.reason ? { reason: args.reason } : {}
948
+ );
949
+ if (args.json) console.log(JSON.stringify(item, null, 2));
950
+ else console.log(`${item.id}: ${item.status}`);
951
+ }
952
+ });
953
+ }
954
+ function endpoint(value) {
955
+ return value.kind === "agent" ? `agent:${value.id}` : value.kind === "user" ? `user:${value.teamId}` : `outside:${value.teamId}`;
956
+ }
957
+ var approvalCommand = defineCommand2({
958
+ meta: { name: "approval", description: "Manage communication approval queue and history" },
959
+ subCommands: {
960
+ list,
961
+ show,
962
+ approve: decision("approve"),
963
+ deny: decision("deny"),
964
+ cancel: decision("cancel")
965
+ }
966
+ });
967
+
855
968
  // src/commands/auth.ts
856
969
  import { loginOpenAICodex } from "@earendil-works/pi-ai/oauth";
857
- import { defineCommand as defineCommand2 } from "citty";
970
+ import { defineCommand as defineCommand3 } from "citty";
858
971
  function formatExpiry(ms) {
859
972
  if (!ms) return "(unknown)";
860
973
  const d = new Date(ms);
861
974
  return d.toISOString().replace(/\.\d+Z$/, "Z");
862
975
  }
863
- var openaiLoginCmd = defineCommand2({
976
+ var openaiLoginCmd = defineCommand3({
864
977
  meta: {
865
978
  name: "login",
866
979
  description: "Connect your ChatGPT account via OAuth (browser sign-in)"
@@ -902,7 +1015,7 @@ var openaiLoginCmd = defineCommand2({
902
1015
  console.log(" bazilion provider models-set openai-codex gpt-5.3-codex-spark");
903
1016
  }
904
1017
  });
905
- var openaiLogoutCmd = defineCommand2({
1018
+ var openaiLogoutCmd = defineCommand3({
906
1019
  meta: {
907
1020
  name: "logout",
908
1021
  description: "Forget the stored ChatGPT OAuth credentials"
@@ -913,7 +1026,7 @@ var openaiLogoutCmd = defineCommand2({
913
1026
  console.log("disconnected ChatGPT OAuth credentials");
914
1027
  }
915
1028
  });
916
- var openaiStatusCmd = defineCommand2({
1029
+ var openaiStatusCmd = defineCommand3({
917
1030
  meta: {
918
1031
  name: "status",
919
1032
  description: "Show ChatGPT OAuth connection status"
@@ -930,7 +1043,7 @@ var openaiStatusCmd = defineCommand2({
930
1043
  console.log(`access token expires: ${formatExpiry(status.expiresAt)}`);
931
1044
  }
932
1045
  });
933
- var openaiCmd = defineCommand2({
1046
+ var openaiCmd = defineCommand3({
934
1047
  meta: {
935
1048
  name: "openai",
936
1049
  description: "Manage ChatGPT (OAuth) authentication"
@@ -941,7 +1054,7 @@ var openaiCmd = defineCommand2({
941
1054
  status: openaiStatusCmd
942
1055
  }
943
1056
  });
944
- var authCommand = defineCommand2({
1057
+ var authCommand = defineCommand3({
945
1058
  meta: {
946
1059
  name: "auth",
947
1060
  description: "OAuth-based provider authentication (ChatGPT account, etc.)"
@@ -957,8 +1070,8 @@ import { createWriteStream, existsSync as existsSync2, mkdirSync, readdirSync, r
957
1070
  import { resolve } from "path";
958
1071
  import { Readable } from "stream";
959
1072
  import { pipeline } from "stream/promises";
960
- import { defineCommand as defineCommand3 } from "citty";
961
- var createCmd = defineCommand3({
1073
+ import { defineCommand as defineCommand4 } from "citty";
1074
+ var createCmd = defineCommand4({
962
1075
  meta: { name: "create", description: "Download a tar.gz backup of ~/.bazilion from the server" },
963
1076
  args: {
964
1077
  output: {
@@ -999,7 +1112,7 @@ async function probeServerRunning(port) {
999
1112
  return false;
1000
1113
  }
1001
1114
  }
1002
- var restoreCmd = defineCommand3({
1115
+ var restoreCmd = defineCommand4({
1003
1116
  meta: {
1004
1117
  name: "restore",
1005
1118
  description: "Extract a backup tar.gz into ~/.bazilion (offline; server must be stopped)"
@@ -1052,7 +1165,7 @@ var restoreCmd = defineCommand3({
1052
1165
  console.log("start the server with: bazilion serve (migrations apply automatically)");
1053
1166
  }
1054
1167
  });
1055
- var backupCommand = defineCommand3({
1168
+ var backupCommand = defineCommand4({
1056
1169
  meta: { name: "backup", description: "Create or restore a ~/.bazilion tar.gz backup" },
1057
1170
  subCommands: {
1058
1171
  create: createCmd,
@@ -1066,7 +1179,7 @@ var backupCommand = defineCommand3({
1066
1179
  });
1067
1180
 
1068
1181
  // src/commands/completion.ts
1069
- import { defineCommand as defineCommand4 } from "citty";
1182
+ import { defineCommand as defineCommand5 } from "citty";
1070
1183
  async function walk(cmd, path, out) {
1071
1184
  const subsRaw = cmd.subCommands ?? {};
1072
1185
  const subNames = Object.keys(subsRaw);
@@ -1171,7 +1284,7 @@ function fishScript(flat) {
1171
1284
  `;
1172
1285
  }
1173
1286
  function completionCommand(main2) {
1174
- return defineCommand4({
1287
+ return defineCommand5({
1175
1288
  meta: {
1176
1289
  name: "completion",
1177
1290
  description: "Print a shell completion script (bash, zsh, or fish)"
@@ -1196,13 +1309,13 @@ function completionCommand(main2) {
1196
1309
  }
1197
1310
 
1198
1311
  // src/commands/config.ts
1199
- import { defineCommand as defineCommand5 } from "citty";
1312
+ import { defineCommand as defineCommand6 } from "citty";
1200
1313
  function displayValue(f) {
1201
1314
  if (!f.set) return "(unset)";
1202
1315
  if (f.kind === "secret") return f.preview ?? "(set)";
1203
1316
  return f.value ?? "(set)";
1204
1317
  }
1205
- var listCmd2 = defineCommand5({
1318
+ var listCmd2 = defineCommand6({
1206
1319
  meta: {
1207
1320
  name: "list",
1208
1321
  description: "List every configurable field (credentials + URLs) across all services"
@@ -1225,7 +1338,7 @@ var listCmd2 = defineCommand5({
1225
1338
  for (const line of columnize(rows)) console.log(line);
1226
1339
  }
1227
1340
  });
1228
- var setCmd = defineCommand5({
1341
+ var setCmd = defineCommand6({
1229
1342
  meta: {
1230
1343
  name: "set",
1231
1344
  description: "Set a configurable field (auto-routes to secrets or plaintext store)"
@@ -1252,7 +1365,7 @@ var setCmd = defineCommand5({
1252
1365
  console.log(`${state.envVar} (${state.kind}): ${displayValue(state)}`);
1253
1366
  }
1254
1367
  });
1255
- var rmCmd = defineCommand5({
1368
+ var rmCmd = defineCommand6({
1256
1369
  meta: { name: "rm", description: "Remove a configurable field value" },
1257
1370
  args: {
1258
1371
  envVar: { type: "positional", required: true, description: "Env var name to clear" }
@@ -1263,7 +1376,7 @@ var rmCmd = defineCommand5({
1263
1376
  console.log(`removed ${args.envVar}`);
1264
1377
  }
1265
1378
  });
1266
- var configCommand = defineCommand5({
1379
+ var configCommand = defineCommand6({
1267
1380
  meta: {
1268
1381
  name: "config",
1269
1382
  description: "Manage service configuration \u2014 credentials (encrypted) and URLs/IDs (plaintext), unified under one CLI"
@@ -1280,7 +1393,7 @@ import { spawn as spawn2 } from "child_process";
1280
1393
  import { existsSync as existsSync3 } from "fs";
1281
1394
  import { connect } from "net";
1282
1395
  import { join as join2 } from "path";
1283
- import { defineCommand as defineCommand6 } from "citty";
1396
+ import { defineCommand as defineCommand7 } from "citty";
1284
1397
  var bundledDaemonEntry = join2(import.meta.dirname, "daemon.js");
1285
1398
  var sourceDaemonEntry = join2(import.meta.dirname, "..", "..", "..", "daemon", "src", "index.ts");
1286
1399
  var daemonEntry = existsSync3(bundledDaemonEntry) ? bundledDaemonEntry : sourceDaemonEntry;
@@ -1374,7 +1487,7 @@ function spawnProcess(label, entry2, env) {
1374
1487
  stdio: "inherit"
1375
1488
  });
1376
1489
  }
1377
- var dashboardCommand = defineCommand6({
1490
+ var dashboardCommand = defineCommand7({
1378
1491
  meta: {
1379
1492
  name: "dashboard",
1380
1493
  description: "Start the bazilion daemon and bundled web UI"
@@ -1493,8 +1606,8 @@ var dashboardCommand = defineCommand6({
1493
1606
  });
1494
1607
 
1495
1608
  // src/commands/doctor.ts
1496
- import { defineCommand as defineCommand7 } from "citty";
1497
- var doctorCommand = defineCommand7({
1609
+ import { defineCommand as defineCommand8 } from "citty";
1610
+ var doctorCommand = defineCommand8({
1498
1611
  meta: { name: "doctor", description: "Diagnose your bazilion install" },
1499
1612
  async run() {
1500
1613
  const client = createClient2();
@@ -1521,7 +1634,7 @@ var doctorCommand = defineCommand7({
1521
1634
  console.log(
1522
1635
  ` ${r.database.activeAgents} active agent(s) (${r.database.totalAgents} total)`
1523
1636
  );
1524
- console.log(` ${r.database.groups} group(s)`);
1637
+ console.log(` ${r.database.teams} team(s)`);
1525
1638
  } else {
1526
1639
  check("open database", false, r.database.error);
1527
1640
  }
@@ -1605,178 +1718,6 @@ var doctorCommand = defineCommand7({
1605
1718
  }
1606
1719
  });
1607
1720
 
1608
- // src/commands/group.ts
1609
- import { readFileSync as readFileSync3 } from "fs";
1610
- import { stdin as stdin2 } from "process";
1611
- import { defineCommand as defineCommand8 } from "citty";
1612
- var addCmd = defineCommand8({
1613
- meta: {
1614
- name: "add",
1615
- description: "Register a group at ~/.bazilion/groups/<slug>/ (use --link to point at an existing tree)"
1616
- },
1617
- args: {
1618
- id: { type: "positional", required: true, description: "Group slug" },
1619
- name: { type: "string", description: "Display name (defaults to slug)" },
1620
- link: {
1621
- type: "string",
1622
- description: "Absolute path of an existing directory; the group slot becomes a symlink to it"
1623
- }
1624
- },
1625
- async run({ args }) {
1626
- const client = createClient2();
1627
- const body = {
1628
- id: args.id,
1629
- ...args.name ? { name: args.name } : {},
1630
- ...args.link ? { link: args.link } : {}
1631
- };
1632
- const g = await client.post("/api/groups", body);
1633
- console.log(`registered group ${g.id} at ${g.path}`);
1634
- }
1635
- });
1636
- var listCmd3 = defineCommand8({
1637
- meta: { name: "list", description: "List groups" },
1638
- async run() {
1639
- const client = createClient2();
1640
- const list = await client.get("/api/groups");
1641
- if (list.length === 0) {
1642
- console.log("(no groups)");
1643
- return;
1644
- }
1645
- const rows = list.map((g) => [g.id, g.path]);
1646
- for (const line of columnize(rows)) console.log(line);
1647
- }
1648
- });
1649
- var rmCmd2 = defineCommand8({
1650
- meta: { name: "rm", description: "Remove a group registration" },
1651
- args: {
1652
- id: { type: "positional", required: true }
1653
- },
1654
- async run({ args }) {
1655
- const client = createClient2();
1656
- await client.del(`/api/groups/${args.id}`);
1657
- console.log(`removed group ${args.id}`);
1658
- }
1659
- });
1660
- async function readStdin() {
1661
- const chunks = [];
1662
- for await (const chunk of stdin2) chunks.push(chunk);
1663
- return Buffer.concat(chunks).toString("utf8");
1664
- }
1665
- var userMdShowCmd = defineCommand8({
1666
- meta: { name: "show", description: "Print the group's USER.md" },
1667
- args: { id: { type: "positional", required: true } },
1668
- async run({ args }) {
1669
- const client = createClient2();
1670
- const g = await client.get(`/api/groups/${args.id}`);
1671
- process.stdout.write(g.userMd);
1672
- if (g.userMd && !g.userMd.endsWith("\n")) process.stdout.write("\n");
1673
- }
1674
- });
1675
- var userMdSetCmd = defineCommand8({
1676
- meta: {
1677
- name: "set",
1678
- description: "Replace the group's USER.md (from --file, --from-stdin, or inline text)"
1679
- },
1680
- args: {
1681
- id: { type: "positional", required: true },
1682
- file: { type: "string", description: "Read content from a file path" },
1683
- "from-stdin": { type: "boolean", description: "Read content from stdin" },
1684
- text: { type: "string", description: "Inline content" }
1685
- },
1686
- async run({ args }) {
1687
- let content;
1688
- if (args["from-stdin"]) content = await readStdin();
1689
- else if (args.file) content = readFileSync3(args.file, "utf8");
1690
- else if (args.text !== void 0) content = args.text;
1691
- else {
1692
- console.error("group user-md set: provide --file, --from-stdin, or --text");
1693
- process.exit(2);
1694
- }
1695
- const client = createClient2();
1696
- const body = { userMd: content };
1697
- await client.put(`/api/groups/${args.id}/user-md`, body);
1698
- console.log(`updated USER.md for group ${args.id} (${content.length} bytes)`);
1699
- }
1700
- });
1701
- var userMdClearCmd = defineCommand8({
1702
- meta: { name: "clear", description: "Clear the group's USER.md to empty" },
1703
- args: { id: { type: "positional", required: true } },
1704
- async run({ args }) {
1705
- const client = createClient2();
1706
- const body = { userMd: "" };
1707
- await client.put(`/api/groups/${args.id}/user-md`, body);
1708
- console.log(`cleared USER.md for group ${args.id}`);
1709
- }
1710
- });
1711
- var userMdCmd = defineCommand8({
1712
- meta: { name: "user-md", description: "View or edit a group's USER.md" },
1713
- subCommands: {
1714
- show: userMdShowCmd,
1715
- set: userMdSetCmd,
1716
- clear: userMdClearCmd
1717
- }
1718
- });
1719
- var topicFormatShowCmd = defineCommand8({
1720
- meta: { name: "show", description: "Print the group's Telegram topic-name template" },
1721
- args: { id: { type: "positional", required: true } },
1722
- async run({ args }) {
1723
- const client = createClient2();
1724
- const g = await client.get(`/api/groups/${args.id}`);
1725
- console.log(g.telegramTopicNameFormat ?? "(default naming)");
1726
- }
1727
- });
1728
- var topicFormatSetCmd = defineCommand8({
1729
- meta: {
1730
- name: "set",
1731
- description: "Set the topic-name template. Tokens: {agent.name} {group.name} {group.slug} (must include {agent.name})"
1732
- },
1733
- args: {
1734
- id: { type: "positional", required: true },
1735
- format: {
1736
- type: "positional",
1737
- required: true,
1738
- description: 'e.g. "{group.name} / {agent.name}"'
1739
- }
1740
- },
1741
- async run({ args }) {
1742
- const client = createClient2();
1743
- const body = { format: args.format };
1744
- const g = await client.put(`/api/groups/${args.id}/topic-format`, body);
1745
- console.log(`set topic-name template for group ${args.id}: ${g.telegramTopicNameFormat}`);
1746
- }
1747
- });
1748
- var topicFormatClearCmd = defineCommand8({
1749
- meta: { name: "clear", description: "Clear the template (revert to built-in naming)" },
1750
- args: { id: { type: "positional", required: true } },
1751
- async run({ args }) {
1752
- const client = createClient2();
1753
- const body = { format: null };
1754
- await client.put(`/api/groups/${args.id}/topic-format`, body);
1755
- console.log(`cleared topic-name template for group ${args.id}`);
1756
- }
1757
- });
1758
- var topicFormatCmd = defineCommand8({
1759
- meta: {
1760
- name: "topic-format",
1761
- description: "View or edit a group's Telegram forum-topic name template"
1762
- },
1763
- subCommands: {
1764
- show: topicFormatShowCmd,
1765
- set: topicFormatSetCmd,
1766
- clear: topicFormatClearCmd
1767
- }
1768
- });
1769
- var groupCommand = defineCommand8({
1770
- meta: { name: "group", description: "Manage groups (collaboration contexts)" },
1771
- subCommands: {
1772
- add: addCmd,
1773
- list: listCmd3,
1774
- rm: rmCmd2,
1775
- "user-md": userMdCmd,
1776
- "topic-format": topicFormatCmd
1777
- }
1778
- });
1779
-
1780
1721
  // src/commands/inbox.ts
1781
1722
  import { defineCommand as defineCommand9 } from "citty";
1782
1723
  function decodeText(payload) {
@@ -1790,11 +1731,11 @@ function decodeText(payload) {
1790
1731
  function messageRow(m) {
1791
1732
  const when = new Date(m.createdAt).toISOString();
1792
1733
  const state = m.readAt ? "read" : "NEW";
1793
- const text = decodeText(m.payload);
1794
- const preview = text.length > 60 ? `${text.slice(0, 60)}\u2026` : text;
1734
+ const text2 = decodeText(m.payload);
1735
+ const preview = text2.length > 60 ? `${text2.slice(0, 60)}\u2026` : text2;
1795
1736
  return [m.id, state, when, `from:${m.fromAgentId.slice(0, 8)}`, `"${preview}"`];
1796
1737
  }
1797
- var listCmd4 = defineCommand9({
1738
+ var listCmd3 = defineCommand9({
1798
1739
  meta: { name: "list", description: "List messages in an agent inbox" },
1799
1740
  args: {
1800
1741
  agent: { type: "positional", required: true, description: "Recipient agent id" },
@@ -1847,14 +1788,14 @@ var readCmd = defineCommand9({
1847
1788
  var inboxCommand = defineCommand9({
1848
1789
  meta: { name: "inbox", description: "Inspect agent inboxes" },
1849
1790
  subCommands: {
1850
- list: listCmd4,
1791
+ list: listCmd3,
1851
1792
  show: showCmd2,
1852
1793
  read: readCmd
1853
1794
  }
1854
1795
  });
1855
1796
 
1856
1797
  // src/commands/login.ts
1857
- import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
1798
+ import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
1858
1799
  import { defineCommand as defineCommand10 } from "citty";
1859
1800
  function normalizeServer(raw) {
1860
1801
  let url;
@@ -1893,7 +1834,7 @@ var loginCommand = defineCommand10({
1893
1834
  `${paths.authFile} not found. Start the daemon with "bazilion serve" first \u2014 login stores the remote there.`
1894
1835
  );
1895
1836
  }
1896
- const auth = JSON.parse(readFileSync4(paths.authFile, "utf8"));
1837
+ const auth = JSON.parse(readFileSync3(paths.authFile, "utf8"));
1897
1838
  if (args.clear) {
1898
1839
  if (!auth.remote) {
1899
1840
  console.log("no remote stored \u2014 nothing to clear");
@@ -1935,7 +1876,7 @@ function serverRow(s) {
1935
1876
  where
1936
1877
  ];
1937
1878
  }
1938
- var addCmd2 = defineCommand11({
1879
+ var addCmd = defineCommand11({
1939
1880
  meta: { name: "add", description: "Register an MCP server" },
1940
1881
  args: {
1941
1882
  name: { type: "positional", required: true, description: "Unique name ([a-zA-Z0-9_])" },
@@ -1962,7 +1903,7 @@ var addCmd2 = defineCommand11({
1962
1903
  console.log(`${server.id} ${server.name} ${server.transport}`);
1963
1904
  }
1964
1905
  });
1965
- var listCmd5 = defineCommand11({
1906
+ var listCmd4 = defineCommand11({
1966
1907
  meta: { name: "list", description: "List MCP servers" },
1967
1908
  async run() {
1968
1909
  const client = createClient2();
@@ -1983,7 +1924,7 @@ var showCmd3 = defineCommand11({
1983
1924
  console.log(JSON.stringify(server, null, 2));
1984
1925
  }
1985
1926
  });
1986
- var rmCmd3 = defineCommand11({
1927
+ var rmCmd2 = defineCommand11({
1987
1928
  meta: { name: "rm", description: "Delete an MCP server" },
1988
1929
  args: { id: { type: "positional", required: true } },
1989
1930
  async run({ args }) {
@@ -2031,10 +1972,10 @@ var testCmd = defineCommand11({
2031
1972
  var mcpCommand = defineCommand11({
2032
1973
  meta: { name: "mcp", description: "Manage MCP servers" },
2033
1974
  subCommands: {
2034
- add: addCmd2,
2035
- list: listCmd5,
1975
+ add: addCmd,
1976
+ list: listCmd4,
2036
1977
  show: showCmd3,
2037
- rm: rmCmd3,
1978
+ rm: rmCmd2,
2038
1979
  enable: enableCmd,
2039
1980
  disable: disableCmd,
2040
1981
  test: testCmd
@@ -2047,39 +1988,39 @@ function encodeKey(key) {
2047
1988
  return key.split("/").map(encodeURIComponent).join("/");
2048
1989
  }
2049
1990
  var writeCmd = defineCommand12({
2050
- meta: { name: "write", description: "Write an entry into a group's shared memory" },
1991
+ meta: { name: "write", description: "Write an entry into a team's shared memory" },
2051
1992
  args: {
2052
- group: { type: "positional", required: true, description: "Group slug" },
1993
+ team: { type: "positional", required: true, description: "Team slug" },
2053
1994
  key: { type: "positional", required: true, description: "Memory key (path under memory/)" },
2054
1995
  content: { type: "positional", required: true, description: "Content to write" }
2055
1996
  },
2056
1997
  async run({ args }) {
2057
1998
  const client = createClient2();
2058
1999
  const entry2 = await client.put(
2059
- `/api/groups/${args.group}/memory/${encodeKey(args.key)}`,
2000
+ `/api/teams/${args.team}/memory/${encodeKey(args.key)}`,
2060
2001
  { content: args.content }
2061
2002
  );
2062
2003
  console.log(`wrote ${entry2.key} (${entry2.content.length} bytes)`);
2063
2004
  }
2064
2005
  });
2065
2006
  var readCmd2 = defineCommand12({
2066
- meta: { name: "read", description: "Read an entry from a group's shared memory" },
2007
+ meta: { name: "read", description: "Read an entry from a team's shared memory" },
2067
2008
  args: {
2068
- group: { type: "positional", required: true, description: "Group slug" },
2009
+ team: { type: "positional", required: true, description: "Team slug" },
2069
2010
  key: { type: "positional", required: true }
2070
2011
  },
2071
2012
  async run({ args }) {
2072
2013
  const client = createClient2();
2073
2014
  const entry2 = await client.get(
2074
- `/api/groups/${args.group}/memory/${encodeKey(args.key)}`
2015
+ `/api/teams/${args.team}/memory/${encodeKey(args.key)}`
2075
2016
  );
2076
2017
  console.log(entry2.content);
2077
2018
  }
2078
2019
  });
2079
2020
  var searchCmd = defineCommand12({
2080
- meta: { name: "search", description: "Search a group's shared memory" },
2021
+ meta: { name: "search", description: "Search a team's shared memory" },
2081
2022
  args: {
2082
- group: { type: "positional", required: true, description: "Group slug" },
2023
+ team: { type: "positional", required: true, description: "Team slug" },
2083
2024
  query: { type: "positional", required: true },
2084
2025
  limit: { type: "string", description: "Max results (default 10)" }
2085
2026
  },
@@ -2087,7 +2028,7 @@ var searchCmd = defineCommand12({
2087
2028
  const client = createClient2();
2088
2029
  const limit = args.limit ? Number.parseInt(args.limit, 10) : 10;
2089
2030
  const params = new URLSearchParams({ q: args.query, limit: String(limit) });
2090
- const hits = await client.get(`/api/groups/${args.group}/memory/search?${params}`);
2031
+ const hits = await client.get(`/api/teams/${args.team}/memory/search?${params}`);
2091
2032
  if (hits.length === 0) {
2092
2033
  console.log("(no matches)");
2093
2034
  return;
@@ -2097,14 +2038,14 @@ var searchCmd = defineCommand12({
2097
2038
  }
2098
2039
  }
2099
2040
  });
2100
- var listCmd6 = defineCommand12({
2101
- meta: { name: "list", description: "List all entries in a group's shared memory" },
2041
+ var listCmd5 = defineCommand12({
2042
+ meta: { name: "list", description: "List all entries in a team's shared memory" },
2102
2043
  args: {
2103
- group: { type: "positional", required: true, description: "Group slug" }
2044
+ team: { type: "positional", required: true, description: "Team slug" }
2104
2045
  },
2105
2046
  async run({ args }) {
2106
2047
  const client = createClient2();
2107
- const all = await client.get(`/api/groups/${args.group}/memory`);
2048
+ const all = await client.get(`/api/teams/${args.team}/memory`);
2108
2049
  if (all.length === 0) {
2109
2050
  console.log("(no memory entries)");
2110
2051
  return;
@@ -2114,36 +2055,36 @@ var listCmd6 = defineCommand12({
2114
2055
  }
2115
2056
  }
2116
2057
  });
2117
- var rmCmd4 = defineCommand12({
2118
- meta: { name: "rm", description: "Remove an entry from a group's shared memory" },
2058
+ var rmCmd3 = defineCommand12({
2059
+ meta: { name: "rm", description: "Remove an entry from a team's shared memory" },
2119
2060
  args: {
2120
- group: { type: "positional", required: true, description: "Group slug" },
2061
+ team: { type: "positional", required: true, description: "Team slug" },
2121
2062
  key: { type: "positional", required: true }
2122
2063
  },
2123
2064
  async run({ args }) {
2124
2065
  const client = createClient2();
2125
- await client.del(`/api/groups/${args.group}/memory/${encodeKey(args.key)}`);
2066
+ await client.del(`/api/teams/${args.team}/memory/${encodeKey(args.key)}`);
2126
2067
  console.log(`removed ${args.key}`);
2127
2068
  }
2128
2069
  });
2129
2070
  var memoryCommand = defineCommand12({
2130
2071
  meta: {
2131
2072
  name: "memory",
2132
- description: "Manage a group's shared memory (BM25-indexed markdown notes)"
2073
+ description: "Manage a team's shared memory (BM25-indexed markdown notes)"
2133
2074
  },
2134
2075
  subCommands: {
2135
2076
  write: writeCmd,
2136
2077
  read: readCmd2,
2137
2078
  search: searchCmd,
2138
- list: listCmd6,
2139
- rm: rmCmd4
2079
+ list: listCmd5,
2080
+ rm: rmCmd3
2140
2081
  }
2141
2082
  });
2142
2083
 
2143
2084
  // src/commands/profile.ts
2144
2085
  import { spawn as spawn3 } from "child_process";
2145
2086
  import { randomBytes } from "crypto";
2146
- import { readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
2087
+ import { readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
2147
2088
  import { tmpdir } from "os";
2148
2089
  import { join as join3 } from "path";
2149
2090
 
@@ -2154,8 +2095,7 @@ var PROFILE_FILES = [
2154
2095
  "IDENTITY.md",
2155
2096
  "BOOTSTRAP.md",
2156
2097
  "AGENTS.md",
2157
- "TOOLS.md",
2158
- "HEARTBEAT.md"
2098
+ "TOOLS.md"
2159
2099
  ];
2160
2100
 
2161
2101
  // src/commands/profile.ts
@@ -2211,15 +2151,11 @@ var createCmd2 = defineCommand13({
2211
2151
  "tools-file": {
2212
2152
  type: "string",
2213
2153
  description: "Path to TOOLS.md content (optional; omit to skip)"
2214
- },
2215
- "heartbeat-file": {
2216
- type: "string",
2217
- description: "Path to HEARTBEAT.md content (optional; omit to skip)"
2218
2154
  }
2219
2155
  },
2220
2156
  async run({ args }) {
2221
2157
  const skillsMode = parseSkillsMode(args["skills-mode"]);
2222
- const readTemplate = (path) => path ? readFileSync5(path, "utf8") : void 0;
2158
+ const readTemplate = (path) => path ? readFileSync4(path, "utf8") : void 0;
2223
2159
  const body = {
2224
2160
  id: args.id,
2225
2161
  name: args.name,
@@ -2230,24 +2166,23 @@ var createCmd2 = defineCommand13({
2230
2166
  identity: readTemplate(args["identity-file"]),
2231
2167
  bootstrap: args["skip-bootstrap"] ? null : readTemplate(args["bootstrap-file"]) ?? void 0,
2232
2168
  agents: readTemplate(args["agents-file"]),
2233
- tools: readTemplate(args["tools-file"]),
2234
- heartbeat: readTemplate(args["heartbeat-file"])
2169
+ tools: readTemplate(args["tools-file"])
2235
2170
  };
2236
2171
  const client = createClient2();
2237
2172
  const profile = await client.post("/api/profiles", body);
2238
2173
  console.log(`created profile ${profile.id} at ${profile.dir}`);
2239
2174
  }
2240
2175
  });
2241
- var listCmd7 = defineCommand13({
2176
+ var listCmd6 = defineCommand13({
2242
2177
  meta: { name: "list", description: "List profiles" },
2243
2178
  async run() {
2244
2179
  const client = createClient2();
2245
- const list = await client.get("/api/profiles");
2246
- if (list.length === 0) {
2180
+ const list3 = await client.get("/api/profiles");
2181
+ if (list3.length === 0) {
2247
2182
  console.log("(no profiles)");
2248
2183
  return;
2249
2184
  }
2250
- const rows = list.map((p) => [p.id, p.defaultModel, p.name]);
2185
+ const rows = list3.map((p) => [p.id, p.defaultModel, p.name]);
2251
2186
  for (const line of columnize(rows)) console.log(line);
2252
2187
  }
2253
2188
  });
@@ -2270,7 +2205,6 @@ var showCmd4 = defineCommand13({
2270
2205
  console.log(`bootstrap: ${loaded.files.bootstrap !== null ? "yes" : "no"}`);
2271
2206
  console.log(`agents: ${loaded.files.agents !== null ? "yes" : "no"}`);
2272
2207
  console.log(`tools: ${loaded.files.tools !== null ? "yes" : "no"}`);
2273
- console.log(`heartbeat: ${loaded.files.heartbeat !== null ? "yes" : "no"}`);
2274
2208
  if (loaded.identity) {
2275
2209
  const fields = Object.entries(loaded.identity).filter(([, v]) => typeof v === "string" && v.length > 0).map(([k, v]) => `${k}=${v}`).join(", ");
2276
2210
  if (fields) console.log(`identity: ${fields}`);
@@ -2306,7 +2240,7 @@ var editCmd2 = defineCommand13({
2306
2240
  child.on("close", (c) => resolve3(c ?? 0));
2307
2241
  });
2308
2242
  if (code !== 0) throw new Error(`editor exited with code ${code}`);
2309
- const updated = readFileSync5(tmpPath, "utf8");
2243
+ const updated = readFileSync4(tmpPath, "utf8");
2310
2244
  if (updated === content) {
2311
2245
  console.log("(no changes)");
2312
2246
  return;
@@ -2371,7 +2305,7 @@ var profileCommand = defineCommand13({
2371
2305
  meta: { name: "profile", description: "Manage profiles" },
2372
2306
  subCommands: {
2373
2307
  create: createCmd2,
2374
- list: listCmd7,
2308
+ list: listCmd6,
2375
2309
  show: showCmd4,
2376
2310
  edit: editCmd2,
2377
2311
  update: updateCmd,
@@ -2379,301 +2313,77 @@ var profileCommand = defineCommand13({
2379
2313
  }
2380
2314
  });
2381
2315
 
2382
- // src/commands/profile-group.ts
2383
- import { spawn as spawn4 } from "child_process";
2384
- import { randomBytes as randomBytes2 } from "crypto";
2385
- import { readFileSync as readFileSync6, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
2386
- import { tmpdir as tmpdir2 } from "os";
2387
- import { join as join4 } from "path";
2316
+ // src/commands/provider.ts
2388
2317
  import { defineCommand as defineCommand14 } from "citty";
2389
- var createCmd3 = defineCommand14({
2390
- meta: { name: "create", description: "Create a new profile group (team template)" },
2318
+ var listCmd7 = defineCommand14({
2319
+ meta: {
2320
+ name: "list",
2321
+ description: "List all providers with enabled/disabled state and curated model counts"
2322
+ },
2391
2323
  args: {
2392
- id: { type: "positional", required: true, description: "Profile group slug" },
2393
- name: { type: "string", description: "Display name (defaults to slug)" },
2394
- "user-md-file": {
2395
- type: "string",
2396
- description: "Path to a starter USER.md; seeded into a freshly-created target group"
2397
- }
2324
+ enabled: { type: "boolean", description: "Show only enabled providers" }
2398
2325
  },
2399
2326
  async run({ args }) {
2400
- const body = { id: args.id };
2401
- if (args.name) body.name = args.name;
2402
- if (args["user-md-file"]) body.userMd = readFileSync6(args["user-md-file"], "utf8");
2403
- const client = createClient2();
2404
- const created = await client.post("/api/profile-groups", body);
2405
- console.log(`created profile group ${created.id}`);
2406
- }
2407
- });
2408
- var listCmd8 = defineCommand14({
2409
- meta: { name: "list", description: "List profile groups" },
2410
- async run() {
2411
2327
  const client = createClient2();
2412
- const list = await client.get("/api/profile-groups");
2413
- if (list.length === 0) {
2414
- console.log("(no profile groups)");
2328
+ const { providers } = await client.get("/api/config/providers");
2329
+ const filtered = args.enabled ? providers.filter((p) => p.enabled) : providers;
2330
+ if (filtered.length === 0) {
2331
+ console.log("(no providers to show)");
2415
2332
  return;
2416
2333
  }
2417
- const rows = list.map((g) => [g.id, String(g.memberCount), g.name]);
2334
+ const rows = filtered.map((p) => [
2335
+ p.id,
2336
+ p.enabled ? "enabled" : "disabled",
2337
+ `${p.curated.length} curated`,
2338
+ `${p.catalog.length} catalog`,
2339
+ p.enabled ? "" : `(set ${p.envHint})`
2340
+ ]);
2418
2341
  for (const line of columnize(rows)) console.log(line);
2419
2342
  }
2420
2343
  });
2421
- var showCmd5 = defineCommand14({
2422
- meta: { name: "show", description: "Show profile group details + members" },
2344
+ var modelsCmd = defineCommand14({
2345
+ meta: {
2346
+ name: "models",
2347
+ description: "Show curated + catalog + live models for one provider"
2348
+ },
2423
2349
  args: {
2424
- id: { type: "positional", required: true },
2425
- json: { type: "boolean", description: "Emit full JSON (members + basics)" }
2350
+ name: { type: "positional", required: true, description: "Provider name" }
2426
2351
  },
2427
2352
  async run({ args }) {
2428
2353
  const client = createClient2();
2429
- const detail = await client.get(`/api/profile-groups/${args.id}`);
2430
- if (args.json) {
2431
- console.log(JSON.stringify(detail, null, 2));
2432
- return;
2354
+ const { providers } = await client.get("/api/config/providers");
2355
+ const p = providers.find((x) => x.id === args.name);
2356
+ if (!p) {
2357
+ console.error(`unknown provider: ${args.name}`);
2358
+ process.exit(1);
2433
2359
  }
2434
- console.log(`# ${detail.group.id}`);
2435
- console.log(`name: ${detail.group.name}`);
2436
- console.log(
2437
- `user-md: ${detail.group.userMd ? `${detail.group.userMd.length} chars` : "(none)"}`
2438
- );
2439
- console.log("");
2440
- if (detail.members.length === 0) {
2441
- console.log("(no members)");
2442
- return;
2360
+ console.log(`# ${p.id} (${p.enabled ? "enabled" : "disabled"})`);
2361
+ if (!p.enabled) console.log(` (set ${p.envHint} to enable)`);
2362
+ console.log("\n## curated");
2363
+ if (p.curated.length === 0) console.log(" (none \u2014 use `provider models-set` to pin some)");
2364
+ else for (const m of p.curated) console.log(` ${m}`);
2365
+ console.log("\n## catalog (from pi-ai)");
2366
+ if (p.catalog.length === 0) console.log(" (empty)");
2367
+ else for (const m of p.catalog) console.log(` ${m}`);
2368
+ if (p.live) {
2369
+ console.log("\n## live (from upstream /v1/models)");
2370
+ if (p.live.error) console.log(` (error: ${p.live.error})`);
2371
+ else if (p.live.models.length === 0) console.log(" (empty)");
2372
+ else for (const m of p.live.models) console.log(` ${m}`);
2443
2373
  }
2444
- console.log("members:");
2445
- const rows = [
2446
- ["#", "profile", "agent-name", "model-override", "reasoning"],
2447
- ...detail.members.map((m) => [
2448
- String(m.position),
2449
- m.profileId,
2450
- m.agentName,
2451
- m.modelOverride ?? "-",
2452
- m.reasoningLevel ?? "-"
2453
- ])
2454
- ];
2455
- for (const line of columnize(rows)) console.log(` ${line}`);
2456
2374
  }
2457
2375
  });
2458
- var updateCmd2 = defineCommand14({
2459
- meta: { name: "update", description: "Update profile group basics (name, user-md)" },
2376
+ var modelsSetCmd = defineCommand14({
2377
+ meta: {
2378
+ name: "models-set",
2379
+ description: "Replace the curated model list for a provider (comma-separated)"
2380
+ },
2460
2381
  args: {
2461
- id: { type: "positional", required: true },
2462
- name: { type: "string", description: "New display name" },
2463
- "user-md-file": {
2464
- type: "string",
2465
- description: "Path to new USER.md content (pass empty string to clear)"
2466
- }
2467
- },
2468
- async run({ args }) {
2469
- const body = {};
2470
- if (args.name !== void 0) body.name = args.name;
2471
- if (args["user-md-file"] !== void 0) {
2472
- body.userMd = args["user-md-file"] === "" ? null : readFileSync6(args["user-md-file"], "utf8");
2473
- }
2474
- if (Object.keys(body).length === 0) {
2475
- throw new Error("nothing to update \u2014 pass at least one of --name/--user-md-file");
2476
- }
2477
- const client = createClient2();
2478
- const updated = await client.patch(`/api/profile-groups/${args.id}`, body);
2479
- console.log(`updated profile group ${updated.id}`);
2480
- }
2481
- });
2482
- var editCmd3 = defineCommand14({
2483
- meta: { name: "edit", description: "Edit the member array in $EDITOR (JSON)" },
2484
- args: {
2485
- id: { type: "positional", required: true }
2486
- },
2487
- async run({ args }) {
2488
- const client = createClient2();
2489
- const detail = await client.get(`/api/profile-groups/${args.id}`);
2490
- const editable = detail.members.map((m) => ({
2491
- profileId: m.profileId,
2492
- agentName: m.agentName,
2493
- modelOverride: m.modelOverride,
2494
- reasoningLevel: m.reasoningLevel
2495
- }));
2496
- const before = `${JSON.stringify(editable, null, 2)}
2497
- `;
2498
- const tmpPath = join4(
2499
- tmpdir2(),
2500
- `bazilion-profile-group-${args.id}-${randomBytes2(4).toString("hex")}.json`
2501
- );
2502
- writeFileSync4(tmpPath, before);
2503
- try {
2504
- const editor = process.env.EDITOR ?? process.env.VISUAL ?? "vi";
2505
- const code = await new Promise((resolve3, reject) => {
2506
- const child = spawn4(editor, [tmpPath], { stdio: "inherit" });
2507
- child.on("error", reject);
2508
- child.on("close", (c) => resolve3(c ?? 0));
2509
- });
2510
- if (code !== 0) throw new Error(`editor exited with code ${code}`);
2511
- const after = readFileSync6(tmpPath, "utf8");
2512
- if (after === before) {
2513
- console.log("(no changes)");
2514
- return;
2515
- }
2516
- let parsed;
2517
- try {
2518
- parsed = JSON.parse(after);
2519
- } catch (err) {
2520
- throw new Error(`invalid JSON: ${err.message}`);
2521
- }
2522
- if (!Array.isArray(parsed)) {
2523
- throw new Error("expected a JSON array of members");
2524
- }
2525
- const body = {
2526
- members: parsed.map((s, i) => {
2527
- const row = s;
2528
- if (!row || typeof row.profileId !== "string" || typeof row.agentName !== "string") {
2529
- throw new Error(`member ${i}: profileId and agentName are required strings`);
2530
- }
2531
- return {
2532
- profileId: row.profileId,
2533
- agentName: row.agentName,
2534
- modelOverride: row.modelOverride ?? null,
2535
- reasoningLevel: row.reasoningLevel === null || row.reasoningLevel === void 0 ? null : row.reasoningLevel
2536
- };
2537
- })
2538
- };
2539
- await client.put(`/api/profile-groups/${args.id}/members`, body);
2540
- console.log(`saved ${body.members.length} member(s)`);
2541
- } finally {
2542
- try {
2543
- rmSync3(tmpPath, { force: true });
2544
- } catch {
2545
- }
2546
- }
2547
- }
2548
- });
2549
- var deleteCmd3 = defineCommand14({
2550
- meta: { name: "delete", description: "Delete a profile group (does not affect spawned agents)" },
2551
- args: {
2552
- id: { type: "positional", required: true }
2553
- },
2554
- async run({ args }) {
2555
- const client = createClient2();
2556
- await client.del(`/api/profile-groups/${args.id}`);
2557
- console.log(`deleted profile group ${args.id}`);
2558
- }
2559
- });
2560
- var spawnCmd2 = defineCommand14({
2561
- meta: { name: "spawn", description: "Spawn the whole team into a group (transactional)" },
2562
- args: {
2563
- id: { type: "positional", required: true },
2564
- group: {
2565
- type: "string",
2566
- description: "Target group slug (overrides the template default)"
2567
- },
2568
- "user-md-file": {
2569
- type: "string",
2570
- description: "Path to USER.md content to seed (only takes effect on a fresh target group)"
2571
- }
2572
- },
2573
- async run({ args }) {
2574
- const body = {};
2575
- if (args.group) body.groupSlug = args.group;
2576
- if (args["user-md-file"]) body.userMd = readFileSync6(args["user-md-file"], "utf8");
2577
- const client = createClient2();
2578
- const result = await client.post(
2579
- `/api/profile-groups/${args.id}/spawn`,
2580
- body
2581
- );
2582
- console.log(`spawned ${result.agents.length} agent(s) into group ${result.groupSlug}`);
2583
- const rows = result.agents.map((a) => [a.id, a.name]);
2584
- for (const line of columnize(rows)) console.log(` ${line}`);
2585
- if (result.orphanAgentIds && result.orphanAgentIds.length > 0) {
2586
- console.error("");
2587
- console.error(`warning: ${result.orphanAgentIds.length} orphan agent dir(s) left on disk:`);
2588
- for (const id of result.orphanAgentIds) console.error(` ${id}`);
2589
- process.exitCode = 1;
2590
- }
2591
- }
2592
- });
2593
- var profileGroupCommand = defineCommand14({
2594
- meta: { name: "profile-group", description: "Manage profile groups" },
2595
- subCommands: {
2596
- create: createCmd3,
2597
- list: listCmd8,
2598
- show: showCmd5,
2599
- update: updateCmd2,
2600
- edit: editCmd3,
2601
- delete: deleteCmd3,
2602
- spawn: spawnCmd2
2603
- }
2604
- });
2605
-
2606
- // src/commands/provider.ts
2607
- import { defineCommand as defineCommand15 } from "citty";
2608
- var listCmd9 = defineCommand15({
2609
- meta: {
2610
- name: "list",
2611
- description: "List all providers with enabled/disabled state and curated model counts"
2612
- },
2613
- args: {
2614
- enabled: { type: "boolean", description: "Show only enabled providers" }
2615
- },
2616
- async run({ args }) {
2617
- const client = createClient2();
2618
- const { providers } = await client.get("/api/config/providers");
2619
- const filtered = args.enabled ? providers.filter((p) => p.enabled) : providers;
2620
- if (filtered.length === 0) {
2621
- console.log("(no providers to show)");
2622
- return;
2623
- }
2624
- const rows = filtered.map((p) => [
2625
- p.id,
2626
- p.enabled ? "enabled" : "disabled",
2627
- `${p.curated.length} curated`,
2628
- `${p.catalog.length} catalog`,
2629
- p.enabled ? "" : `(set ${p.envHint})`
2630
- ]);
2631
- for (const line of columnize(rows)) console.log(line);
2632
- }
2633
- });
2634
- var modelsCmd = defineCommand15({
2635
- meta: {
2636
- name: "models",
2637
- description: "Show curated + catalog + live models for one provider"
2638
- },
2639
- args: {
2640
- name: { type: "positional", required: true, description: "Provider name" }
2641
- },
2642
- async run({ args }) {
2643
- const client = createClient2();
2644
- const { providers } = await client.get("/api/config/providers");
2645
- const p = providers.find((x) => x.id === args.name);
2646
- if (!p) {
2647
- console.error(`unknown provider: ${args.name}`);
2648
- process.exit(1);
2649
- }
2650
- console.log(`# ${p.id} (${p.enabled ? "enabled" : "disabled"})`);
2651
- if (!p.enabled) console.log(` (set ${p.envHint} to enable)`);
2652
- console.log("\n## curated");
2653
- if (p.curated.length === 0) console.log(" (none \u2014 use `provider models-set` to pin some)");
2654
- else for (const m of p.curated) console.log(` ${m}`);
2655
- console.log("\n## catalog (from pi-ai)");
2656
- if (p.catalog.length === 0) console.log(" (empty)");
2657
- else for (const m of p.catalog) console.log(` ${m}`);
2658
- if (p.live) {
2659
- console.log("\n## live (from upstream /v1/models)");
2660
- if (p.live.error) console.log(` (error: ${p.live.error})`);
2661
- else if (p.live.models.length === 0) console.log(" (empty)");
2662
- else for (const m of p.live.models) console.log(` ${m}`);
2663
- }
2664
- }
2665
- });
2666
- var modelsSetCmd = defineCommand15({
2667
- meta: {
2668
- name: "models-set",
2669
- description: "Replace the curated model list for a provider (comma-separated)"
2670
- },
2671
- args: {
2672
- name: { type: "positional", required: true, description: "Provider name" },
2673
- models: {
2674
- type: "positional",
2675
- required: true,
2676
- description: "Comma-separated model list (empty string clears the list)"
2382
+ name: { type: "positional", required: true, description: "Provider name" },
2383
+ models: {
2384
+ type: "positional",
2385
+ required: true,
2386
+ description: "Comma-separated model list (empty string clears the list)"
2677
2387
  }
2678
2388
  },
2679
2389
  async run({ args }) {
@@ -2688,7 +2398,7 @@ var modelsSetCmd = defineCommand15({
2688
2398
  for (const m of saved.models) console.log(` ${m}`);
2689
2399
  }
2690
2400
  });
2691
- var enableCmd2 = defineCommand15({
2401
+ var enableCmd2 = defineCommand14({
2692
2402
  meta: { name: "enable", description: "Toggle a provider on so agents can use it" },
2693
2403
  args: {
2694
2404
  name: { type: "positional", required: true, description: "Provider id (e.g. anthropic)" }
@@ -2702,7 +2412,7 @@ var enableCmd2 = defineCommand15({
2702
2412
  console.log(`${res.name}: enabled`);
2703
2413
  }
2704
2414
  });
2705
- var disableCmd2 = defineCommand15({
2415
+ var disableCmd2 = defineCommand14({
2706
2416
  meta: {
2707
2417
  name: "disable",
2708
2418
  description: "Toggle a provider off \u2014 agents will refuse its model strings"
@@ -2719,7 +2429,7 @@ var disableCmd2 = defineCommand15({
2719
2429
  console.log(`${res.name}: disabled`);
2720
2430
  }
2721
2431
  });
2722
- var testCmd2 = defineCommand15({
2432
+ var testCmd2 = defineCommand14({
2723
2433
  meta: { name: "test", description: "Send a single chat to a model and print the reply" },
2724
2434
  args: {
2725
2435
  model: {
@@ -2740,10 +2450,10 @@ var testCmd2 = defineCommand15({
2740
2450
  }
2741
2451
  }
2742
2452
  });
2743
- var providerCommand = defineCommand15({
2453
+ var providerCommand = defineCommand14({
2744
2454
  meta: { name: "provider", description: "Manage and test LLM providers" },
2745
2455
  subCommands: {
2746
- list: listCmd9,
2456
+ list: listCmd7,
2747
2457
  enable: enableCmd2,
2748
2458
  disable: disableCmd2,
2749
2459
  models: modelsCmd,
@@ -2753,8 +2463,8 @@ var providerCommand = defineCommand15({
2753
2463
  });
2754
2464
 
2755
2465
  // src/commands/send.ts
2756
- import { defineCommand as defineCommand16 } from "citty";
2757
- var sendCommand = defineCommand16({
2466
+ import { defineCommand as defineCommand15 } from "citty";
2467
+ var sendCommand = defineCommand15({
2758
2468
  meta: {
2759
2469
  name: "send",
2760
2470
  description: "Send a message from one agent to another"
@@ -2770,20 +2480,29 @@ var sendCommand = defineCommand16({
2770
2480
  from: args.from,
2771
2481
  payload: { text: args.message }
2772
2482
  };
2773
- const msg = await client.post(`/api/agents/${args.to}/messages`, body);
2774
- console.log(`sent message ${msg.id}`);
2483
+ const result = await client.post(
2484
+ `/api/agents/${args.to}/messages`,
2485
+ body
2486
+ );
2487
+ if ("approvalId" in result) {
2488
+ console.log(
2489
+ `pending approval ${result.approvalId} (expires ${new Date(result.expiresAt).toISOString()})`
2490
+ );
2491
+ return;
2492
+ }
2493
+ console.log(`sent message ${result.id}`);
2775
2494
  }
2776
2495
  });
2777
2496
 
2778
2497
  // src/commands/serve.ts
2779
- import { spawn as spawn5 } from "child_process";
2498
+ import { spawn as spawn4 } from "child_process";
2780
2499
  import { existsSync as existsSync5 } from "fs";
2781
- import { join as join5 } from "path";
2782
- import { defineCommand as defineCommand17 } from "citty";
2783
- var bundledDaemonEntry2 = join5(import.meta.dirname, "daemon.js");
2784
- var sourceDaemonEntry2 = join5(import.meta.dirname, "..", "..", "..", "daemon", "src", "index.ts");
2500
+ import { join as join4 } from "path";
2501
+ import { defineCommand as defineCommand16 } from "citty";
2502
+ var bundledDaemonEntry2 = join4(import.meta.dirname, "daemon.js");
2503
+ var sourceDaemonEntry2 = join4(import.meta.dirname, "..", "..", "..", "daemon", "src", "index.ts");
2785
2504
  var daemonEntry2 = existsSync5(bundledDaemonEntry2) ? bundledDaemonEntry2 : sourceDaemonEntry2;
2786
- var serveCommand = defineCommand17({
2505
+ var serveCommand = defineCommand16({
2787
2506
  meta: {
2788
2507
  name: "serve",
2789
2508
  description: "Start the bazilion daemon (HTTP API)"
@@ -2816,7 +2535,7 @@ var serveCommand = defineCommand17({
2816
2535
  console.log(`starting bazilion daemon at http://${host}:${port}`);
2817
2536
  console.log("(web UI runs separately: cd apps/web && pnpm dev)");
2818
2537
  const nodeArgs2 = daemonEntry2.endsWith(".ts") ? ["--import", "tsx/esm", daemonEntry2] : [daemonEntry2];
2819
- const proc = spawn5("node", nodeArgs2, {
2538
+ const proc = spawn4("node", nodeArgs2, {
2820
2539
  env,
2821
2540
  stdio: "inherit"
2822
2541
  });
@@ -2850,16 +2569,16 @@ var serveCommand = defineCommand17({
2850
2569
  });
2851
2570
 
2852
2571
  // src/commands/skill.ts
2853
- import { existsSync as existsSync6, readFileSync as readFileSync7, statSync } from "fs";
2572
+ import { existsSync as existsSync6, readFileSync as readFileSync5, statSync } from "fs";
2854
2573
  import { basename as basename2, resolve as resolve2 } from "path";
2855
- import { defineCommand as defineCommand18 } from "citty";
2574
+ import { defineCommand as defineCommand17 } from "citty";
2856
2575
  function printFindings(findings, prefix = " ") {
2857
2576
  for (const f of findings) {
2858
2577
  const line = f.line ? ` line ${f.line}` : "";
2859
2578
  console.log(`${prefix}${f.severity}: ${f.code}${line} - ${f.message}`);
2860
2579
  }
2861
2580
  }
2862
- var listCmd10 = defineCommand18({
2581
+ var listCmd8 = defineCommand17({
2863
2582
  meta: { name: "list", description: "List installed skills (or those attached to an agent)" },
2864
2583
  args: {
2865
2584
  agent: { type: "string", description: "Filter to skills attached to this agent" }
@@ -2900,7 +2619,7 @@ var listCmd10 = defineCommand18({
2900
2619
  }
2901
2620
  }
2902
2621
  });
2903
- var importCmd = defineCommand18({
2622
+ var importCmd = defineCommand17({
2904
2623
  meta: {
2905
2624
  name: "import",
2906
2625
  description: "Import skills from openclaw, a directory, or a local .zip archive"
@@ -2920,7 +2639,7 @@ var importCmd = defineCommand18({
2920
2639
  let result;
2921
2640
  try {
2922
2641
  if (isLocalZip) {
2923
- const bytes = readFileSync7(absFrom);
2642
+ const bytes = readFileSync5(absFrom);
2924
2643
  const file = new File([bytes], basename2(absFrom), { type: "application/zip" });
2925
2644
  const fd = new FormData();
2926
2645
  fd.set("file", file);
@@ -2969,7 +2688,7 @@ var importCmd = defineCommand18({
2969
2688
  }
2970
2689
  }
2971
2690
  });
2972
- var rmCmd5 = defineCommand18({
2691
+ var rmCmd4 = defineCommand17({
2973
2692
  meta: { name: "rm", description: "Remove an installed skill" },
2974
2693
  args: {
2975
2694
  name: { type: "positional", required: true }
@@ -2980,18 +2699,844 @@ var rmCmd5 = defineCommand18({
2980
2699
  console.log(`removed skill ${args.name}`);
2981
2700
  }
2982
2701
  });
2983
- var skillCommand = defineCommand18({
2702
+ var skillCommand = defineCommand17({
2984
2703
  meta: { name: "skill", description: "Manage the skill library" },
2985
2704
  subCommands: {
2986
- list: listCmd10,
2705
+ list: listCmd8,
2987
2706
  import: importCmd,
2988
- rm: rmCmd5
2707
+ rm: rmCmd4
2989
2708
  }
2990
2709
  });
2991
2710
 
2992
- // src/commands/telegram.ts
2711
+ // src/commands/team.ts
2712
+ import { readFileSync as readFileSync7 } from "fs";
2713
+ import { stdin as stdin2 } from "process";
2993
2714
  import { defineCommand as defineCommand19 } from "citty";
2994
- var setCmd2 = defineCommand19({
2715
+
2716
+ // src/commands/team-policy.ts
2717
+ import { readFileSync as readFileSync6 } from "fs";
2718
+ import { defineCommand as defineCommand18 } from "citty";
2719
+
2720
+ // src/team-interchange.ts
2721
+ var TEAM_POLICY_INTERCHANGE_VERSION = 1;
2722
+ var TEAM_DOCUMENT_KIND = "bazilion.team-template";
2723
+ var TEAM_POLICY_DOCUMENT_KIND = "bazilion.team-policy";
2724
+ var reasoning = /* @__PURE__ */ new Set(["off", "minimal", "low", "medium", "high", "xhigh"]);
2725
+ var templateKinds = /* @__PURE__ */ new Set(["user", "outside_team", "slot"]);
2726
+ var liveKinds = /* @__PURE__ */ new Set(["user", "outside_team", "agent"]);
2727
+ function object(value, label) {
2728
+ if (!value || typeof value !== "object" || Array.isArray(value))
2729
+ throw new Error(`${label} must be an object`);
2730
+ return value;
2731
+ }
2732
+ function text(value, label) {
2733
+ if (typeof value !== "string" || !value.trim()) throw new Error(`${label} is required`);
2734
+ return value.trim();
2735
+ }
2736
+ function nullableText(value, label) {
2737
+ if (value === null || value === void 0) return null;
2738
+ if (typeof value !== "string") throw new Error(`${label} must be a string or null`);
2739
+ return value;
2740
+ }
2741
+ function endpointKey(kind, key) {
2742
+ return `${kind}:${key ?? "-"}`;
2743
+ }
2744
+ function exportTeamDocument(detail) {
2745
+ const keyById = new Map(detail.slots.map((slot, index) => [slot.slotId, `slot-${index + 1}`]));
2746
+ return {
2747
+ version: TEAM_POLICY_INTERCHANGE_VERSION,
2748
+ kind: TEAM_DOCUMENT_KIND,
2749
+ template: {
2750
+ id: detail.template.id,
2751
+ name: detail.template.name,
2752
+ userMd: detail.template.userMd
2753
+ },
2754
+ slots: detail.slots.map((slot) => ({
2755
+ key: keyById.get(slot.slotId),
2756
+ profileId: slot.profileId,
2757
+ agentName: slot.agentName,
2758
+ modelOverride: slot.modelOverride,
2759
+ reasoningLevel: slot.reasoningLevel,
2760
+ layoutPosition: slot.layoutPosition,
2761
+ display: slot.display
2762
+ })),
2763
+ edges: detail.edges.map((edge) => ({
2764
+ sourceKind: edge.sourceKind,
2765
+ sourceKey: edge.sourceKind === "slot" ? keyById.get(edge.sourceId ?? "") ?? null : null,
2766
+ targetKind: edge.targetKind,
2767
+ targetKey: edge.targetKind === "slot" ? keyById.get(edge.targetId ?? "") ?? null : null,
2768
+ posture: edge.posture
2769
+ }))
2770
+ };
2771
+ }
2772
+ function parseTeamDocument(value) {
2773
+ const root = object(value, "document");
2774
+ if (root.version !== TEAM_POLICY_INTERCHANGE_VERSION)
2775
+ throw new Error(`unsupported Team Policy document version: ${String(root.version)}`);
2776
+ if (root.kind !== TEAM_DOCUMENT_KIND)
2777
+ throw new Error(`invalid document kind: expected ${TEAM_DOCUMENT_KIND}`);
2778
+ const meta = object(root.template, "template");
2779
+ const rawSlots = Array.isArray(root.slots) ? root.slots : null;
2780
+ const rawEdges = Array.isArray(root.edges) ? root.edges : null;
2781
+ if (!rawSlots || !rawEdges) throw new Error("slots and edges must be arrays");
2782
+ const keys = /* @__PURE__ */ new Set();
2783
+ const slots = rawSlots.map((raw, index) => {
2784
+ const slot = object(raw, `slot ${index}`);
2785
+ const key = text(slot.key, `slot ${index} key`);
2786
+ if (keys.has(key)) throw new Error(`duplicate slot key: ${key}`);
2787
+ keys.add(key);
2788
+ const level = slot.reasoningLevel;
2789
+ if (level !== null && level !== void 0 && !reasoning.has(level))
2790
+ throw new Error(`slot ${index} has invalid reasoningLevel`);
2791
+ const position = slot.layoutPosition;
2792
+ if (position !== null && position !== void 0 && (!position || typeof position !== "object" || Array.isArray(position) || !Number.isFinite(position.x) || !Number.isFinite(position.y)))
2793
+ throw new Error(`slot ${index} has invalid layoutPosition`);
2794
+ const display = slot.display;
2795
+ if (display !== null && display !== void 0 && (!display || typeof display !== "object" || Array.isArray(display)))
2796
+ throw new Error(`slot ${index} has invalid display`);
2797
+ return {
2798
+ key,
2799
+ profileId: text(slot.profileId, `slot ${index} profileId`),
2800
+ agentName: text(slot.agentName, `slot ${index} agentName`),
2801
+ modelOverride: nullableText(slot.modelOverride, `slot ${index} modelOverride`),
2802
+ reasoningLevel: level ?? null,
2803
+ layoutPosition: position ?? null,
2804
+ display: display ?? null
2805
+ };
2806
+ });
2807
+ const seen = /* @__PURE__ */ new Set();
2808
+ const edges = rawEdges.map((raw, index) => {
2809
+ const edge = object(raw, `edge ${index}`);
2810
+ if (!templateKinds.has(String(edge.sourceKind)) || !templateKinds.has(String(edge.targetKind)))
2811
+ throw new Error(`edge ${index} has invalid endpoint kind`);
2812
+ const sourceKind = edge.sourceKind;
2813
+ const targetKind = edge.targetKind;
2814
+ const sourceKey = nullableText(edge.sourceKey, `edge ${index} sourceKey`);
2815
+ const targetKey = nullableText(edge.targetKey, `edge ${index} targetKey`);
2816
+ const posture = edge.posture === void 0 || edge.posture === "allow" ? "allow" : edge.posture === "approval_required" ? "approval_required" : null;
2817
+ if (!posture) throw new Error(`edge ${index} has invalid posture`);
2818
+ if (sourceKind === "slot" !== Boolean(sourceKey))
2819
+ throw new Error(`edge ${index} source slot key is missing or invalid`);
2820
+ if (targetKind === "slot" !== Boolean(targetKey))
2821
+ throw new Error(`edge ${index} target slot key is missing or invalid`);
2822
+ if (sourceKey && !keys.has(sourceKey))
2823
+ throw new Error(`edge ${index} references missing slot ${sourceKey}`);
2824
+ if (targetKey && !keys.has(targetKey))
2825
+ throw new Error(`edge ${index} references missing slot ${targetKey}`);
2826
+ const signature = `${endpointKey(sourceKind, sourceKey)}->${endpointKey(targetKind, targetKey)}`;
2827
+ if (endpointKey(sourceKind, sourceKey) === endpointKey(targetKind, targetKey))
2828
+ throw new Error(`edge ${index} is a self edge`);
2829
+ if (seen.has(signature)) throw new Error(`duplicate edge: ${signature}`);
2830
+ seen.add(signature);
2831
+ return { sourceKind, sourceKey, targetKind, targetKey, posture };
2832
+ });
2833
+ return {
2834
+ version: 1,
2835
+ kind: TEAM_DOCUMENT_KIND,
2836
+ template: {
2837
+ id: text(meta.id, "template id"),
2838
+ name: text(meta.name, "template name"),
2839
+ userMd: nullableText(meta.userMd, "template userMd")
2840
+ },
2841
+ slots,
2842
+ edges
2843
+ };
2844
+ }
2845
+ function teamImportBody(document, existing) {
2846
+ const currentByKey = existing ? new Map(existing.slots.map((slot, index) => [`slot-${index + 1}`, slot.slotId])) : /* @__PURE__ */ new Map();
2847
+ const slots = document.slots.map((slot) => ({
2848
+ ...currentByKey.has(slot.key) ? { slotId: currentByKey.get(slot.key) } : { clientKey: slot.key },
2849
+ profileId: slot.profileId,
2850
+ agentName: slot.agentName,
2851
+ modelOverride: slot.modelOverride,
2852
+ reasoningLevel: slot.reasoningLevel,
2853
+ layoutPosition: slot.layoutPosition,
2854
+ display: slot.display
2855
+ }));
2856
+ const idByKey = new Map(
2857
+ slots.map((slot, index) => [
2858
+ document.slots[index]?.key,
2859
+ slot.slotId ?? slot.clientKey ?? null
2860
+ ])
2861
+ );
2862
+ const edges = document.edges.map((edge) => ({
2863
+ sourceKind: edge.sourceKind,
2864
+ sourceId: edge.sourceKind === "slot" ? idByKey.get(edge.sourceKey ?? "") : null,
2865
+ targetKind: edge.targetKind,
2866
+ targetId: edge.targetKind === "slot" ? idByKey.get(edge.targetKey ?? "") : null,
2867
+ posture: edge.posture
2868
+ }));
2869
+ return { slots, edges };
2870
+ }
2871
+ function parseTeamPolicyDocument(value) {
2872
+ const root = object(value, "document");
2873
+ if (root.version !== 1)
2874
+ throw new Error(`unsupported Team Policy document version: ${String(root.version)}`);
2875
+ if (root.kind !== TEAM_POLICY_DOCUMENT_KIND)
2876
+ throw new Error(`invalid document kind: expected ${TEAM_POLICY_DOCUMENT_KIND}`);
2877
+ if (!Number.isInteger(root.expectedRevision) || Number(root.expectedRevision) < 1)
2878
+ throw new Error("expectedRevision must be a positive integer");
2879
+ if (!Array.isArray(root.edges)) throw new Error("edges must be an array");
2880
+ const seen = /* @__PURE__ */ new Set();
2881
+ const edges = root.edges.map((raw, index) => {
2882
+ const edge = object(raw, `edge ${index}`);
2883
+ if (!liveKinds.has(String(edge.sourceKind)) || !liveKinds.has(String(edge.targetKind)))
2884
+ throw new Error(`edge ${index} has invalid endpoint kind`);
2885
+ const sourceKind = edge.sourceKind;
2886
+ const targetKind = edge.targetKind;
2887
+ const sourceId = nullableText(edge.sourceId, `edge ${index} sourceId`);
2888
+ const targetId = nullableText(edge.targetId, `edge ${index} targetId`);
2889
+ if (sourceKind === "agent" !== Boolean(sourceId) || targetKind === "agent" !== Boolean(targetId))
2890
+ throw new Error(`edge ${index} Agent id is missing or invalid`);
2891
+ const signature = `${endpointKey(sourceKind, sourceId)}->${endpointKey(targetKind, targetId)}`;
2892
+ if (endpointKey(sourceKind, sourceId) === endpointKey(targetKind, targetId))
2893
+ throw new Error(`edge ${index} is a self edge`);
2894
+ if (seen.has(signature)) throw new Error(`duplicate edge: ${signature}`);
2895
+ seen.add(signature);
2896
+ return { sourceKind, sourceId, targetKind, targetId };
2897
+ });
2898
+ return {
2899
+ version: 1,
2900
+ kind: TEAM_POLICY_DOCUMENT_KIND,
2901
+ teamId: text(root.teamId, "teamId"),
2902
+ expectedRevision: Number(root.expectedRevision),
2903
+ edges
2904
+ };
2905
+ }
2906
+ function exportTeamPolicy(teamId, revision, edges) {
2907
+ return {
2908
+ version: 1,
2909
+ kind: TEAM_POLICY_DOCUMENT_KIND,
2910
+ teamId,
2911
+ expectedRevision: revision,
2912
+ edges: edges.map(({ sourceKind, sourceId, targetKind, targetId, posture }) => ({
2913
+ sourceKind,
2914
+ sourceId,
2915
+ targetKind,
2916
+ targetId,
2917
+ posture
2918
+ }))
2919
+ };
2920
+ }
2921
+ function edgeDiff(before, after) {
2922
+ const signature = (edge) => `${endpointKey(edge.sourceKind, edge.sourceId ?? null)} -> ${endpointKey(edge.targetKind, edge.targetId ?? null)} [${edge.posture ?? "allow"}]`;
2923
+ const left = new Set(before.map(signature));
2924
+ const right = new Set(after.map(signature));
2925
+ return {
2926
+ added: [...right].filter((value) => !left.has(value)).sort(),
2927
+ removed: [...left].filter((value) => !right.has(value)).sort()
2928
+ };
2929
+ }
2930
+
2931
+ // src/commands/team-policy.ts
2932
+ function readJson(path) {
2933
+ try {
2934
+ return JSON.parse(readFileSync6(path, "utf8"));
2935
+ } catch (error) {
2936
+ throw new Error(`invalid JSON: ${error.message}`);
2937
+ }
2938
+ }
2939
+ function endpoint2(value, teamId) {
2940
+ if (value === "user") return { kind: "user", teamId };
2941
+ if (value.startsWith("agent:") && value.length > 6) return { kind: "agent", id: value.slice(6) };
2942
+ if (value.startsWith("outside:") && value.length > 8)
2943
+ return { kind: "outside_team", teamId: value.slice(8) };
2944
+ throw new Error("endpoint must be user, agent:<id>, or outside:<team-id>");
2945
+ }
2946
+ function printPolicy(detail) {
2947
+ console.log(`# Team ${detail.teamPolicy.teamId} policy`);
2948
+ console.log(`revision: ${detail.teamPolicy.revision}`);
2949
+ console.log(
2950
+ `baseline: ${detail.baseline ? `${detail.baseline.templateId}@${detail.baseline.templateRevision}` : "(none)"}`
2951
+ );
2952
+ console.log(`members: ${detail.members.length}`);
2953
+ console.log(`edges: ${detail.edges.length}`);
2954
+ if (detail.edges.length) {
2955
+ console.log("");
2956
+ for (const line of columnize([
2957
+ ["source", "target"],
2958
+ ...detail.edges.map((edge) => [
2959
+ `${edge.sourceKind}:${edge.sourceId ?? "-"}`,
2960
+ `${edge.targetKind}:${edge.targetId ?? "-"}`
2961
+ ])
2962
+ ]))
2963
+ console.log(line);
2964
+ }
2965
+ }
2966
+ var show2 = defineCommand18({
2967
+ meta: { name: "show", description: "Show the one effective live policy for a Team" },
2968
+ args: {
2969
+ team: { type: "positional", required: true },
2970
+ json: { type: "boolean", description: "Emit the canonical aggregate as JSON" }
2971
+ },
2972
+ async run({ args }) {
2973
+ const detail = await createClient2().get(
2974
+ `/api/teams/${encodeURIComponent(args.team)}/policy`
2975
+ );
2976
+ if (args.json) console.log(JSON.stringify(detail, null, 2));
2977
+ else printPolicy(detail);
2978
+ }
2979
+ });
2980
+ var exportCommand = defineCommand18({
2981
+ meta: { name: "export", description: "Export a revisioned Team policy document" },
2982
+ args: { team: { type: "positional", required: true } },
2983
+ async run({ args }) {
2984
+ const detail = await createClient2().get(
2985
+ `/api/teams/${encodeURIComponent(args.team)}/policy`
2986
+ );
2987
+ console.log(
2988
+ JSON.stringify(
2989
+ exportTeamPolicy(args.team, detail.teamPolicy.revision, detail.edges),
2990
+ null,
2991
+ 2
2992
+ )
2993
+ );
2994
+ }
2995
+ });
2996
+ function printEdgeDiff(current, edges) {
2997
+ const diff2 = edgeDiff(current.edges, edges);
2998
+ console.log(`Team: ${current.teamPolicy.teamId}`);
2999
+ console.log(`Revision: ${current.teamPolicy.revision}`);
3000
+ console.log(`Edges: +${diff2.added.length} -${diff2.removed.length}`);
3001
+ for (const value of diff2.added) console.log(` + ${value}`);
3002
+ for (const value of diff2.removed) console.log(` - ${value}`);
3003
+ }
3004
+ var importCommand = defineCommand18({
3005
+ meta: {
3006
+ name: "import",
3007
+ description: "Validate, diff, and explicitly replace a Team policy"
3008
+ },
3009
+ args: {
3010
+ team: { type: "positional", required: true },
3011
+ file: { type: "positional", required: true },
3012
+ "dry-run": { type: "boolean", description: "Validate and print the diff only" },
3013
+ apply: { type: "boolean", description: "Apply non-interactively after printing the diff" },
3014
+ "expected-revision": {
3015
+ type: "string",
3016
+ description: "Expected current Team revision (defaults to document revision)"
3017
+ },
3018
+ force: {
3019
+ type: "boolean",
3020
+ description: "Refetch current revision; requires --apply and still uses optimistic locking"
3021
+ },
3022
+ "confirm-current-revision": {
3023
+ type: "string",
3024
+ description: "Second force confirmation: the freshly displayed current revision"
3025
+ }
3026
+ },
3027
+ async run({ args }) {
3028
+ if (args.force && !args.apply)
3029
+ throw new Error("--force requires --apply (interactive force is intentionally unsupported)");
3030
+ const document = parseTeamPolicyDocument(readJson(args.file));
3031
+ if (document.teamId !== args.team)
3032
+ throw new Error(`document belongs to Team ${document.teamId}, not ${args.team}`);
3033
+ const client = createClient2();
3034
+ const current = await client.get(
3035
+ `/api/teams/${encodeURIComponent(args.team)}/policy`
3036
+ );
3037
+ printEdgeDiff(current, document.edges);
3038
+ if (args["dry-run"]) return console.log("valid: no changes applied");
3039
+ if (!args.apply) throw new Error("refusing mutation: review the diff, then pass --apply");
3040
+ const supplied = args["expected-revision"] ? Number.parseInt(args["expected-revision"], 10) : document.expectedRevision;
3041
+ const expectedRevision = args.force ? current.teamPolicy.revision : supplied;
3042
+ if (args.force && Number.parseInt(args["confirm-current-revision"] ?? "", 10) !== current.teamPolicy.revision)
3043
+ throw new Error(
3044
+ `--force requires --confirm-current-revision ${current.teamPolicy.revision} after reviewing the fresh diff`
3045
+ );
3046
+ if (!Number.isInteger(expectedRevision) || expectedRevision < 1)
3047
+ throw new Error("expected revision must be a positive integer");
3048
+ const body = {
3049
+ expectedRevision,
3050
+ edges: document.edges
3051
+ };
3052
+ const updated = await client.put(
3053
+ `/api/teams/${encodeURIComponent(args.team)}/policy`,
3054
+ body
3055
+ );
3056
+ console.log(`updated Team ${args.team} policy to revision ${updated.teamPolicy.revision}`);
3057
+ }
3058
+ });
3059
+ var diff = defineCommand18({
3060
+ meta: { name: "diff", description: "Compare live policy with its retained baseline source" },
3061
+ args: {
3062
+ team: { type: "positional", required: true },
3063
+ json: { type: "boolean", description: "Emit canonical diff JSON" }
3064
+ },
3065
+ async run({ args }) {
3066
+ const result = await createClient2().get(
3067
+ `/api/teams/${encodeURIComponent(args.team)}/policy/diff`
3068
+ );
3069
+ if (args.json) return console.log(JSON.stringify(result, null, 2));
3070
+ console.log(`# Team ${args.team} source diff`);
3071
+ console.log(
3072
+ `status: ${result.baseline ? result.sourceDiverged ? "source diverged" : "source current" : "no baseline"}`
3073
+ );
3074
+ console.log(`revision: ${result.liveRevision}`);
3075
+ console.log(
3076
+ `edges: +${result.comparison.addedSinceBaseline.length} -${result.comparison.removedSinceBaseline.length}`
3077
+ );
3078
+ console.log(
3079
+ `slots: +${result.comparison.currentSourceAddedSlotIds.length} -${result.comparison.currentSourceRemovedSlotIds.length}`
3080
+ );
3081
+ }
3082
+ });
3083
+ var evaluate = defineCommand18({
3084
+ meta: {
3085
+ name: "evaluate",
3086
+ description: "Evaluate a communication path without sending or recording a block"
3087
+ },
3088
+ args: {
3089
+ team: { type: "positional", required: true, description: "Owning Team for context" },
3090
+ source: { type: "string", required: true, description: "user | agent:<id> | outside:<team>" },
3091
+ target: { type: "string", required: true, description: "user | agent:<id> | outside:<team>" },
3092
+ origin: { type: "string", default: "cli-diagnostic" },
3093
+ json: { type: "boolean", description: "Emit decision JSON" }
3094
+ },
3095
+ async run({ args }) {
3096
+ const result = await createClient2().post(
3097
+ "/api/communication/evaluate",
3098
+ {
3099
+ source: endpoint2(args.source, args.team),
3100
+ target: endpoint2(args.target, args.team),
3101
+ origin: args.origin,
3102
+ attemptKind: "cli_evaluate",
3103
+ attemptId: `diagnostic:${args.team}`
3104
+ }
3105
+ );
3106
+ if (args.json) return console.log(JSON.stringify(result, null, 2));
3107
+ console.log(`${result.decision.toUpperCase()} ${result.channel}: ${result.reasonCode}`);
3108
+ console.log(result.reason);
3109
+ console.log(
3110
+ `policy revisions: ${result.policyRefs.map((ref) => `${ref.teamId}@${ref.revision}`).join(", ") || "-"}`
3111
+ );
3112
+ }
3113
+ });
3114
+ var blocks = defineCommand18({
3115
+ meta: { name: "blocks", description: "List paginated durable communication denials" },
3116
+ args: {
3117
+ team: { type: "positional", required: true },
3118
+ limit: { type: "string", default: "50" },
3119
+ cursor: { type: "string" },
3120
+ source: { type: "string" },
3121
+ target: { type: "string" },
3122
+ channel: { type: "string" },
3123
+ origin: { type: "string" },
3124
+ reason: { type: "string", description: "Reason code" },
3125
+ from: { type: "string", description: "Epoch milliseconds or ISO timestamp" },
3126
+ to: { type: "string", description: "Epoch milliseconds or ISO timestamp" },
3127
+ json: { type: "boolean", description: "Emit page JSON including nextCursor" }
3128
+ },
3129
+ async run({ args }) {
3130
+ const query = new URLSearchParams({ limit: args.limit });
3131
+ for (const [key, value] of [
3132
+ ["cursor", args.cursor],
3133
+ ["source", args.source],
3134
+ ["target", args.target],
3135
+ ["channel", args.channel],
3136
+ ["origin", args.origin],
3137
+ ["reasonCode", args.reason],
3138
+ ["from", args.from],
3139
+ ["to", args.to]
3140
+ ])
3141
+ if (value) query.set(key, value);
3142
+ const page = await createClient2().get(
3143
+ `/api/teams/${encodeURIComponent(args.team)}/policy/blocks?${query}`
3144
+ );
3145
+ if (args.json) return console.log(JSON.stringify(page, null, 2));
3146
+ if (!page.blocks.length) console.log("(no blocks)");
3147
+ else
3148
+ for (const line of columnize([
3149
+ ["time", "source", "target", "channel", "origin", "reason"],
3150
+ ...page.blocks.map((block) => [
3151
+ new Date(block.created_at).toISOString(),
3152
+ `${block.source_kind}:${block.source_id ?? "-"}`,
3153
+ `${block.target_kind}:${block.target_id ?? "-"}`,
3154
+ block.channel,
3155
+ block.origin,
3156
+ block.reason_code
3157
+ ])
3158
+ ]))
3159
+ console.log(line);
3160
+ if (page.nextCursor) console.log(`next cursor: ${page.nextCursor}`);
3161
+ }
3162
+ });
3163
+ var teamPolicyCommand = defineCommand18({
3164
+ meta: { name: "policy", description: "Inspect and manage the Team-owned live policy" },
3165
+ subCommands: {
3166
+ show: show2,
3167
+ export: exportCommand,
3168
+ import: importCommand,
3169
+ diff,
3170
+ evaluate,
3171
+ blocks
3172
+ }
3173
+ });
3174
+
3175
+ // src/commands/team.ts
3176
+ var addCmd2 = defineCommand19({
3177
+ meta: {
3178
+ name: "add",
3179
+ description: "Register a team at ~/.bazilion/teams/<slug>/ (use --link to point at an existing tree)"
3180
+ },
3181
+ args: {
3182
+ id: { type: "positional", required: true, description: "Team slug" },
3183
+ name: { type: "string", description: "Display name (defaults to slug)" },
3184
+ link: {
3185
+ type: "string",
3186
+ description: "Absolute path of an existing directory; the team slot becomes a symlink to it"
3187
+ }
3188
+ },
3189
+ async run({ args }) {
3190
+ const client = createClient2();
3191
+ const body = {
3192
+ id: args.id,
3193
+ ...args.name ? { name: args.name } : {},
3194
+ ...args.link ? { link: args.link } : {}
3195
+ };
3196
+ const g = await client.post("/api/teams", body);
3197
+ console.log(`registered team ${g.id} at ${g.path}`);
3198
+ }
3199
+ });
3200
+ var listCmd9 = defineCommand19({
3201
+ meta: { name: "list", description: "List teams" },
3202
+ async run() {
3203
+ const client = createClient2();
3204
+ const list3 = await client.get("/api/teams");
3205
+ if (list3.length === 0) {
3206
+ console.log("(no teams)");
3207
+ return;
3208
+ }
3209
+ const rows = list3.map((g) => [g.id, g.path]);
3210
+ for (const line of columnize(rows)) console.log(line);
3211
+ }
3212
+ });
3213
+ var rmCmd5 = defineCommand19({
3214
+ meta: { name: "rm", description: "Remove a team registration" },
3215
+ args: {
3216
+ id: { type: "positional", required: true }
3217
+ },
3218
+ async run({ args }) {
3219
+ const client = createClient2();
3220
+ const policy = await client.get(
3221
+ `/api/teams/${encodeURIComponent(args.id)}/policy`
3222
+ );
3223
+ await client.del(
3224
+ `/api/teams/${encodeURIComponent(args.id)}?expectedTeamPolicyRevision=${policy.teamPolicy.revision}`
3225
+ );
3226
+ console.log(`removed team ${args.id}`);
3227
+ }
3228
+ });
3229
+ async function readStdin() {
3230
+ const chunks = [];
3231
+ for await (const chunk of stdin2) chunks.push(chunk);
3232
+ return Buffer.concat(chunks).toString("utf8");
3233
+ }
3234
+ var userMdShowCmd = defineCommand19({
3235
+ meta: { name: "show", description: "Print the team's USER.md" },
3236
+ args: { id: { type: "positional", required: true } },
3237
+ async run({ args }) {
3238
+ const client = createClient2();
3239
+ const g = await client.get(`/api/teams/${args.id}`);
3240
+ process.stdout.write(g.userMd);
3241
+ if (g.userMd && !g.userMd.endsWith("\n")) process.stdout.write("\n");
3242
+ }
3243
+ });
3244
+ var userMdSetCmd = defineCommand19({
3245
+ meta: {
3246
+ name: "set",
3247
+ description: "Replace the team's USER.md (from --file, --from-stdin, or inline text)"
3248
+ },
3249
+ args: {
3250
+ id: { type: "positional", required: true },
3251
+ file: { type: "string", description: "Read content from a file path" },
3252
+ "from-stdin": { type: "boolean", description: "Read content from stdin" },
3253
+ text: { type: "string", description: "Inline content" }
3254
+ },
3255
+ async run({ args }) {
3256
+ let content;
3257
+ if (args["from-stdin"]) content = await readStdin();
3258
+ else if (args.file) content = readFileSync7(args.file, "utf8");
3259
+ else if (args.text !== void 0) content = args.text;
3260
+ else {
3261
+ console.error("team user-md set: provide --file, --from-stdin, or --text");
3262
+ process.exit(2);
3263
+ }
3264
+ const client = createClient2();
3265
+ const body = { userMd: content };
3266
+ await client.put(`/api/teams/${args.id}/user-md`, body);
3267
+ console.log(`updated USER.md for team ${args.id} (${content.length} bytes)`);
3268
+ }
3269
+ });
3270
+ var userMdClearCmd = defineCommand19({
3271
+ meta: { name: "clear", description: "Clear the team's USER.md to empty" },
3272
+ args: { id: { type: "positional", required: true } },
3273
+ async run({ args }) {
3274
+ const client = createClient2();
3275
+ const body = { userMd: "" };
3276
+ await client.put(`/api/teams/${args.id}/user-md`, body);
3277
+ console.log(`cleared USER.md for team ${args.id}`);
3278
+ }
3279
+ });
3280
+ var userMdCmd = defineCommand19({
3281
+ meta: { name: "user-md", description: "View or edit a team's USER.md" },
3282
+ subCommands: {
3283
+ show: userMdShowCmd,
3284
+ set: userMdSetCmd,
3285
+ clear: userMdClearCmd
3286
+ }
3287
+ });
3288
+ var topicFormatShowCmd = defineCommand19({
3289
+ meta: { name: "show", description: "Print the team's Telegram topic-name template" },
3290
+ args: { id: { type: "positional", required: true } },
3291
+ async run({ args }) {
3292
+ const client = createClient2();
3293
+ const g = await client.get(`/api/teams/${args.id}`);
3294
+ console.log(g.telegramTopicNameFormat ?? "(default naming)");
3295
+ }
3296
+ });
3297
+ var topicFormatSetCmd = defineCommand19({
3298
+ meta: {
3299
+ name: "set",
3300
+ description: "Set the topic-name template. Tokens: {agent.name} {team.name} {team.slug} (must include {agent.name})"
3301
+ },
3302
+ args: {
3303
+ id: { type: "positional", required: true },
3304
+ format: {
3305
+ type: "positional",
3306
+ required: true,
3307
+ description: 'e.g. "{team.name} / {agent.name}"'
3308
+ }
3309
+ },
3310
+ async run({ args }) {
3311
+ const client = createClient2();
3312
+ const body = { format: args.format };
3313
+ const g = await client.put(`/api/teams/${args.id}/topic-format`, body);
3314
+ console.log(`set topic-name template for team ${args.id}: ${g.telegramTopicNameFormat}`);
3315
+ }
3316
+ });
3317
+ var topicFormatClearCmd = defineCommand19({
3318
+ meta: { name: "clear", description: "Clear the template (revert to built-in naming)" },
3319
+ args: { id: { type: "positional", required: true } },
3320
+ async run({ args }) {
3321
+ const client = createClient2();
3322
+ const body = { format: null };
3323
+ await client.put(`/api/teams/${args.id}/topic-format`, body);
3324
+ console.log(`cleared topic-name template for team ${args.id}`);
3325
+ }
3326
+ });
3327
+ var topicFormatCmd = defineCommand19({
3328
+ meta: {
3329
+ name: "topic-format",
3330
+ description: "View or edit a team's Telegram forum-topic name template"
3331
+ },
3332
+ subCommands: {
3333
+ show: topicFormatShowCmd,
3334
+ set: topicFormatSetCmd,
3335
+ clear: topicFormatClearCmd
3336
+ }
3337
+ });
3338
+ var teamCommand = defineCommand19({
3339
+ meta: { name: "team", description: "Manage teams (collaboration contexts)" },
3340
+ subCommands: {
3341
+ add: addCmd2,
3342
+ list: listCmd9,
3343
+ rm: rmCmd5,
3344
+ "user-md": userMdCmd,
3345
+ "topic-format": topicFormatCmd,
3346
+ policy: teamPolicyCommand
3347
+ }
3348
+ });
3349
+
3350
+ // src/commands/team-template.ts
3351
+ import { readFileSync as readFileSync8 } from "fs";
3352
+ import { defineCommand as defineCommand20 } from "citty";
3353
+ function jsonFile(path) {
3354
+ try {
3355
+ return JSON.parse(readFileSync8(path, "utf8"));
3356
+ } catch (error) {
3357
+ throw new Error(`invalid JSON: ${error.message}`);
3358
+ }
3359
+ }
3360
+ function printTeam(detail) {
3361
+ console.log(`# ${detail.template.id} \u2014 ${detail.template.name}`);
3362
+ console.log(`revision: ${detail.template.currentRevision}`);
3363
+ console.log(`slots: ${detail.slots.length}`);
3364
+ console.log(`edges: ${detail.edges.length}`);
3365
+ if (detail.slots.length) {
3366
+ console.log("");
3367
+ for (const line of columnize([
3368
+ ["slot", "profile", "Agent name", "model", "reasoning"],
3369
+ ...detail.slots.map((slot, index) => [
3370
+ String(index + 1),
3371
+ slot.profileId,
3372
+ slot.agentName,
3373
+ slot.modelOverride ?? "-",
3374
+ slot.reasoningLevel ?? "-"
3375
+ ])
3376
+ ]))
3377
+ console.log(line);
3378
+ }
3379
+ }
3380
+ var list2 = defineCommand20({
3381
+ meta: { name: "list", description: "List canonical Team templates" },
3382
+ args: { json: { type: "boolean", description: "Emit stable JSON" } },
3383
+ async run({ args }) {
3384
+ const rows = await createClient2().get("/api/team-templates");
3385
+ if (args.json) return console.log(JSON.stringify(rows, null, 2));
3386
+ if (!rows.length) return console.log("(no Team templates)");
3387
+ for (const line of columnize([
3388
+ ["id", "revision", "slots", "name"],
3389
+ ...rows.map((row) => [row.id, String(row.currentRevision), String(row.slotCount), row.name])
3390
+ ]))
3391
+ console.log(line);
3392
+ }
3393
+ });
3394
+ var show3 = defineCommand20({
3395
+ meta: { name: "show", description: "Show a canonical Team template" },
3396
+ args: {
3397
+ id: { type: "positional", required: true },
3398
+ json: { type: "boolean", description: "Emit the canonical API aggregate" }
3399
+ },
3400
+ async run({ args }) {
3401
+ const detail = await createClient2().get(
3402
+ `/api/team-templates/${encodeURIComponent(args.id)}`
3403
+ );
3404
+ if (args.json) console.log(JSON.stringify(detail, null, 2));
3405
+ else printTeam(detail);
3406
+ }
3407
+ });
3408
+ var exportCommand2 = defineCommand20({
3409
+ meta: {
3410
+ name: "export",
3411
+ description: "Export a portable versioned Team-template document to stdout"
3412
+ },
3413
+ args: { id: { type: "positional", required: true } },
3414
+ async run({ args }) {
3415
+ const detail = await createClient2().get(
3416
+ `/api/team-templates/${encodeURIComponent(args.id)}`
3417
+ );
3418
+ console.log(JSON.stringify(exportTeamDocument(detail), null, 2));
3419
+ }
3420
+ });
3421
+ function printImportDiff(current, document) {
3422
+ const before = current ? exportTeamDocument(current) : null;
3423
+ console.log(`Team: ${current ? current.template.id : "(new)"} -> ${document.template.id}`);
3424
+ console.log(`Roster: ${current?.slots.length ?? 0} -> ${document.slots.length}`);
3425
+ const previousSlots = new Map(before?.slots.map((slot) => [slot.key, slot]) ?? []);
3426
+ const nextSlots = new Map(document.slots.map((slot) => [slot.key, slot]));
3427
+ for (const [key, slot] of nextSlots) {
3428
+ const previous = previousSlots.get(key);
3429
+ if (!previous) console.log(` + ${key}: ${slot.profileId} / ${slot.agentName}`);
3430
+ else if (JSON.stringify(previous) !== JSON.stringify(slot))
3431
+ console.log(
3432
+ ` ~ ${key}: ${previous.profileId} / ${previous.agentName} -> ${slot.profileId} / ${slot.agentName}`
3433
+ );
3434
+ }
3435
+ for (const [key, slot] of previousSlots)
3436
+ if (!nextSlots.has(key)) console.log(` - ${key}: ${slot.profileId} / ${slot.agentName}`);
3437
+ const toEdge = (edge) => ({
3438
+ sourceKind: edge.sourceKind,
3439
+ sourceId: edge.sourceKey,
3440
+ targetKind: edge.targetKind,
3441
+ targetId: edge.targetKey
3442
+ });
3443
+ const diff2 = edgeDiff(before?.edges.map(toEdge) ?? [], document.edges.map(toEdge));
3444
+ console.log(`Edges: +${diff2.added.length} -${diff2.removed.length}`);
3445
+ for (const value of diff2.added) console.log(` + ${value}`);
3446
+ for (const value of diff2.removed) console.log(` - ${value}`);
3447
+ }
3448
+ var importCommand2 = defineCommand20({
3449
+ meta: {
3450
+ name: "import",
3451
+ description: "Validate, diff, and explicitly apply a portable Team-template document"
3452
+ },
3453
+ args: {
3454
+ file: { type: "positional", required: true, description: "JSON document path" },
3455
+ "dry-run": { type: "boolean", description: "Validate and print the resolved diff only" },
3456
+ apply: { type: "boolean", description: "Apply non-interactively after printing the diff" },
3457
+ "expected-revision": {
3458
+ type: "string",
3459
+ description: "Required current revision when replacing an existing Team"
3460
+ },
3461
+ force: {
3462
+ type: "boolean",
3463
+ description: "Refetch current revision; requires --apply and still uses optimistic locking"
3464
+ },
3465
+ "confirm-current-revision": {
3466
+ type: "string",
3467
+ description: "Second force confirmation: the freshly displayed current revision"
3468
+ }
3469
+ },
3470
+ async run({ args }) {
3471
+ if (args.force && !args.apply)
3472
+ throw new Error("--force requires --apply (interactive force is intentionally unsupported)");
3473
+ const document = parseTeamDocument(jsonFile(args.file));
3474
+ const client = createClient2();
3475
+ let current = null;
3476
+ try {
3477
+ current = await client.get(
3478
+ `/api/team-templates/${encodeURIComponent(document.template.id)}`
3479
+ );
3480
+ } catch (error) {
3481
+ if (!(error instanceof ApiClientError) || error.status !== 404) throw error;
3482
+ }
3483
+ printImportDiff(current, document);
3484
+ if (args["dry-run"]) {
3485
+ console.log("valid: no changes applied");
3486
+ return;
3487
+ }
3488
+ if (!args.apply) throw new Error("refusing mutation: review the diff, then pass --apply");
3489
+ if (!current) {
3490
+ const body2 = teamImportBody(document);
3491
+ const created = await client.post("/api/team-templates/import", {
3492
+ id: document.template.id,
3493
+ name: document.template.name,
3494
+ userMd: document.template.userMd,
3495
+ slots: document.slots.map((slot, index) => ({
3496
+ ...body2.slots[index],
3497
+ clientKey: slot.key
3498
+ })),
3499
+ edges: body2.edges
3500
+ });
3501
+ console.log(
3502
+ `created Team ${created.template.id} at revision ${created.template.currentRevision}`
3503
+ );
3504
+ return;
3505
+ }
3506
+ if (document.template.name !== current.template.name || document.template.userMd !== current.template.userMd)
3507
+ throw new Error(
3508
+ "replacement document metadata differs; update Team name/USER.md separately before import"
3509
+ );
3510
+ const supplied = Number.parseInt(args["expected-revision"] ?? "", 10);
3511
+ const expectedRevision = args.force ? current.template.currentRevision : supplied;
3512
+ if (args.force && Number.parseInt(args["confirm-current-revision"] ?? "", 10) !== current.template.currentRevision)
3513
+ throw new Error(
3514
+ `--force requires --confirm-current-revision ${current.template.currentRevision} after reviewing the fresh diff`
3515
+ );
3516
+ if (!Number.isInteger(expectedRevision) || expectedRevision < 1)
3517
+ throw new Error("--expected-revision is required when replacing an existing Team");
3518
+ const definition = teamImportBody(document, current);
3519
+ const body = { expectedRevision, ...definition };
3520
+ const updated = await client.put(
3521
+ `/api/team-templates/${encodeURIComponent(document.template.id)}/definition`,
3522
+ body
3523
+ );
3524
+ console.log(
3525
+ `updated Team ${updated.template.id} to revision ${updated.template.currentRevision}`
3526
+ );
3527
+ }
3528
+ });
3529
+ var teamTemplateCommand = defineCommand20({
3530
+ meta: {
3531
+ name: "team-template",
3532
+ description: "Inspect and exchange canonical Team templates"
3533
+ },
3534
+ subCommands: { list: list2, show: show3, export: exportCommand2, import: importCommand2 }
3535
+ });
3536
+
3537
+ // src/commands/telegram.ts
3538
+ import { defineCommand as defineCommand21 } from "citty";
3539
+ var setCmd2 = defineCommand21({
2995
3540
  meta: {
2996
3541
  name: "set",
2997
3542
  description: "Save bot token + supergroup chat ID (paired write)"
@@ -3009,7 +3554,7 @@ var setCmd2 = defineCommand19({
3009
3554
  console.log(`saved \xB7 token ${state.botTokenPreview} \xB7 chat ${state.chatId}`);
3010
3555
  }
3011
3556
  });
3012
- var clearCmd = defineCommand19({
3557
+ var clearCmd = defineCommand21({
3013
3558
  meta: {
3014
3559
  name: "clear",
3015
3560
  description: "Remove stored bot token + chat ID"
@@ -3020,7 +3565,7 @@ var clearCmd = defineCommand19({
3020
3565
  console.log("cleared");
3021
3566
  }
3022
3567
  });
3023
- var showCmd6 = defineCommand19({
3568
+ var showCmd5 = defineCommand21({
3024
3569
  meta: {
3025
3570
  name: "show",
3026
3571
  description: "Show what credentials are stored (token is masked)"
@@ -3041,7 +3586,7 @@ var showCmd6 = defineCommand19({
3041
3586
  }
3042
3587
  }
3043
3588
  });
3044
- var reconnectCmd = defineCommand19({
3589
+ var reconnectCmd = defineCommand21({
3045
3590
  meta: {
3046
3591
  name: "reconnect",
3047
3592
  description: "Apply a pending supergroup chat-id migration + re-activate the bot"
@@ -3052,7 +3597,7 @@ var reconnectCmd = defineCommand19({
3052
3597
  console.log(`reconnected \xB7 chat ${state.chatId}`);
3053
3598
  }
3054
3599
  });
3055
- var configCmd = defineCommand19({
3600
+ var configCmd = defineCommand21({
3056
3601
  meta: {
3057
3602
  name: "config",
3058
3603
  description: "Manage Telegram credentials (bot token + chat ID)"
@@ -3060,10 +3605,10 @@ var configCmd = defineCommand19({
3060
3605
  subCommands: {
3061
3606
  set: setCmd2,
3062
3607
  clear: clearCmd,
3063
- show: showCmd6
3608
+ show: showCmd5
3064
3609
  }
3065
3610
  });
3066
- var healthCmd = defineCommand19({
3611
+ var healthCmd = defineCommand21({
3067
3612
  meta: {
3068
3613
  name: "health",
3069
3614
  description: "Run the four-step preflight against the Telegram Bot API"
@@ -3097,7 +3642,7 @@ var healthCmd = defineCommand19({
3097
3642
  if (!allOk) process.exitCode = 1;
3098
3643
  }
3099
3644
  });
3100
- var botStatusCmd = defineCommand19({
3645
+ var botStatusCmd = defineCommand21({
3101
3646
  meta: {
3102
3647
  name: "status",
3103
3648
  description: "Show polling state of the live bot"
@@ -3122,7 +3667,7 @@ var botStatusCmd = defineCommand19({
3122
3667
  if (!p.running) process.exitCode = 1;
3123
3668
  }
3124
3669
  });
3125
- var botRestartCmd = defineCommand19({
3670
+ var botRestartCmd = defineCommand21({
3126
3671
  meta: {
3127
3672
  name: "restart",
3128
3673
  description: "Force-restart the bot (tears down + brings up from current creds)"
@@ -3133,7 +3678,7 @@ var botRestartCmd = defineCommand19({
3133
3678
  console.log("restart requested");
3134
3679
  }
3135
3680
  });
3136
- var botCmd = defineCommand19({
3681
+ var botCmd = defineCommand21({
3137
3682
  meta: {
3138
3683
  name: "bot",
3139
3684
  description: "Inspect / control the live polling bot"
@@ -3143,7 +3688,7 @@ var botCmd = defineCommand19({
3143
3688
  restart: botRestartCmd
3144
3689
  }
3145
3690
  });
3146
- var bindCmd = defineCommand19({
3691
+ var bindCmd = defineCommand21({
3147
3692
  meta: {
3148
3693
  name: "bind",
3149
3694
  description: "Create a Telegram topic for an agent (manual fallback for /talk)"
@@ -3161,7 +3706,7 @@ var bindCmd = defineCommand19({
3161
3706
  console.log(` ${result.deepLink}`);
3162
3707
  }
3163
3708
  });
3164
- var unbindCmd = defineCommand19({
3709
+ var unbindCmd = defineCommand21({
3165
3710
  meta: {
3166
3711
  name: "unbind",
3167
3712
  description: "Clear an agent's Telegram topic binding (topic stays in Telegram as orphan)"
@@ -3175,7 +3720,7 @@ var unbindCmd = defineCommand19({
3175
3720
  console.log(`unbound agent ${args.agent}`);
3176
3721
  }
3177
3722
  });
3178
- var listBindingsCmd = defineCommand19({
3723
+ var listBindingsCmd = defineCommand21({
3179
3724
  meta: {
3180
3725
  name: "list",
3181
3726
  description: "List agents and their Telegram topic bindings"
@@ -3192,18 +3737,18 @@ var listBindingsCmd = defineCommand19({
3192
3737
  if (bound.length > 0) {
3193
3738
  console.log("bound:");
3194
3739
  for (const a of bound) {
3195
- console.log(` #${a.telegramTopicId} ${a.name} (group: ${a.groupId})`);
3740
+ console.log(` #${a.telegramTopicId} ${a.name} (team: ${a.teamId})`);
3196
3741
  }
3197
3742
  }
3198
3743
  if (unbound.length > 0) {
3199
3744
  console.log("unbound:");
3200
3745
  for (const a of unbound) {
3201
- console.log(` \u2014 ${a.name} (group: ${a.groupId})`);
3746
+ console.log(` \u2014 ${a.name} (team: ${a.teamId})`);
3202
3747
  }
3203
3748
  }
3204
3749
  }
3205
3750
  });
3206
- var allowCmd = defineCommand19({
3751
+ var allowCmd = defineCommand21({
3207
3752
  meta: { name: "allow", description: "Add a Telegram user id to the allowlist" },
3208
3753
  args: {
3209
3754
  userId: { type: "positional", required: true, description: "Numeric Telegram user id" },
@@ -3220,7 +3765,7 @@ var allowCmd = defineCommand19({
3220
3765
  console.log(`allowed ${u.userId} (${u.role})`);
3221
3766
  }
3222
3767
  });
3223
- var denyCmd = defineCommand19({
3768
+ var denyCmd = defineCommand21({
3224
3769
  meta: { name: "deny", description: "Remove a Telegram user id from the allowlist" },
3225
3770
  args: { userId: { type: "positional", required: true } },
3226
3771
  async run({ args }) {
@@ -3229,7 +3774,7 @@ var denyCmd = defineCommand19({
3229
3774
  console.log(`removed ${args.userId}`);
3230
3775
  }
3231
3776
  });
3232
- var allowedCmd = defineCommand19({
3777
+ var allowedCmd = defineCommand21({
3233
3778
  meta: { name: "allowed", description: "List allowlisted Telegram users" },
3234
3779
  async run() {
3235
3780
  const client = createClient2();
@@ -3244,7 +3789,7 @@ var allowedCmd = defineCommand19({
3244
3789
  }
3245
3790
  }
3246
3791
  });
3247
- var telegramCommand = defineCommand19({
3792
+ var telegramCommand = defineCommand21({
3248
3793
  meta: {
3249
3794
  name: "telegram",
3250
3795
  description: "Telegram integration: credentials, health, bot lifecycle, bindings, access"
@@ -3265,7 +3810,7 @@ var telegramCommand = defineCommand19({
3265
3810
 
3266
3811
  // src/commands/token.ts
3267
3812
  import { networkInterfaces } from "os";
3268
- import { defineCommand as defineCommand20 } from "citty";
3813
+ import { defineCommand as defineCommand22 } from "citty";
3269
3814
  import qrcode from "qrcode-terminal";
3270
3815
  function tokenRow(t) {
3271
3816
  const last = t.lastUsedAt ? new Date(t.lastUsedAt).toISOString() : "(never)";
@@ -3299,7 +3844,7 @@ function resolveQrServer(override) {
3299
3844
  if (detected.warning) console.warn(`\u26A0 ${detected.warning}`);
3300
3845
  return detected.origin;
3301
3846
  }
3302
- var createCmd4 = defineCommand20({
3847
+ var createCmd3 = defineCommand22({
3303
3848
  meta: { name: "create", description: "Mint a new web token (shown once)" },
3304
3849
  args: {
3305
3850
  label: { type: "positional", required: true, description: "Human-readable label" },
@@ -3330,7 +3875,7 @@ var createCmd4 = defineCommand20({
3330
3875
  qrcode.generate(pairUrl, { small: true }, (qr) => console.log(qr));
3331
3876
  }
3332
3877
  });
3333
- var listCmd11 = defineCommand20({
3878
+ var listCmd10 = defineCommand22({
3334
3879
  meta: { name: "list", description: "List web tokens" },
3335
3880
  args: {
3336
3881
  all: { type: "boolean", description: "Include revoked tokens" }
@@ -3346,7 +3891,7 @@ var listCmd11 = defineCommand20({
3346
3891
  for (const line of columnize(tokens.map(tokenRow))) console.log(line);
3347
3892
  }
3348
3893
  });
3349
- var showLocalCmd = defineCommand20({
3894
+ var showLocalCmd = defineCommand22({
3350
3895
  meta: {
3351
3896
  name: "show-local",
3352
3897
  description: "Print the bootstrap web token stored in ~/.bazilion/auth.json"
@@ -3356,7 +3901,7 @@ var showLocalCmd = defineCommand20({
3356
3901
  console.log(readAuthFile(paths.authFile).token);
3357
3902
  }
3358
3903
  });
3359
- var revokeCmd = defineCommand20({
3904
+ var revokeCmd = defineCommand22({
3360
3905
  meta: { name: "revoke", description: "Revoke a web token" },
3361
3906
  args: {
3362
3907
  id: { type: "positional", required: true }
@@ -3367,20 +3912,20 @@ var revokeCmd = defineCommand20({
3367
3912
  console.log(`revoked token ${args.id}`);
3368
3913
  }
3369
3914
  });
3370
- var tokenCommand = defineCommand20({
3915
+ var tokenCommand = defineCommand22({
3371
3916
  meta: { name: "token", description: "Manage web tokens for API/CLI clients" },
3372
3917
  subCommands: {
3373
- create: createCmd4,
3374
- list: listCmd11,
3918
+ create: createCmd3,
3919
+ list: listCmd10,
3375
3920
  revoke: revokeCmd,
3376
3921
  "show-local": showLocalCmd
3377
3922
  }
3378
3923
  });
3379
3924
 
3380
3925
  // src/commands/trigger.ts
3381
- import { defineCommand as defineCommand21 } from "citty";
3382
- var addCmd3 = defineCommand21({
3383
- meta: { name: "add", description: "Add a heartbeat / cron trigger to an agent" },
3926
+ import { defineCommand as defineCommand23 } from "citty";
3927
+ var addCmd3 = defineCommand23({
3928
+ meta: { name: "add", description: "Add an interval / cron trigger to an agent" },
3384
3929
  args: {
3385
3930
  agent: { type: "positional", required: true },
3386
3931
  every: {
@@ -3427,7 +3972,7 @@ function triggerRow(t) {
3427
3972
  const msgPreview = t.message.length > 60 ? `${t.message.slice(0, 60)}\u2026` : t.message;
3428
3973
  return [t.id, state, spec, `last: ${last}`, `"${msgPreview}"`];
3429
3974
  }
3430
- var listCmd12 = defineCommand21({
3975
+ var listCmd11 = defineCommand23({
3431
3976
  meta: { name: "list", description: "List triggers for an agent" },
3432
3977
  args: {
3433
3978
  agent: { type: "positional", required: true }
@@ -3444,7 +3989,7 @@ var listCmd12 = defineCommand21({
3444
3989
  for (const line of columnize(triggers.map(triggerRow))) console.log(line);
3445
3990
  }
3446
3991
  });
3447
- var rmCmd6 = defineCommand21({
3992
+ var rmCmd6 = defineCommand23({
3448
3993
  meta: { name: "rm", description: "Delete a trigger" },
3449
3994
  args: {
3450
3995
  id: { type: "positional", required: true }
@@ -3455,7 +4000,7 @@ var rmCmd6 = defineCommand21({
3455
4000
  console.log(`removed trigger ${args.id}`);
3456
4001
  }
3457
4002
  });
3458
- var enableCmd3 = defineCommand21({
4003
+ var enableCmd3 = defineCommand23({
3459
4004
  meta: { name: "enable", description: "Enable a trigger" },
3460
4005
  args: {
3461
4006
  id: { type: "positional", required: true }
@@ -3467,7 +4012,7 @@ var enableCmd3 = defineCommand21({
3467
4012
  console.log(`enabled trigger ${args.id}`);
3468
4013
  }
3469
4014
  });
3470
- var disableCmd3 = defineCommand21({
4015
+ var disableCmd3 = defineCommand23({
3471
4016
  meta: { name: "disable", description: "Disable a trigger" },
3472
4017
  args: {
3473
4018
  id: { type: "positional", required: true }
@@ -3479,11 +4024,11 @@ var disableCmd3 = defineCommand21({
3479
4024
  console.log(`disabled trigger ${args.id}`);
3480
4025
  }
3481
4026
  });
3482
- var triggerCommand = defineCommand21({
3483
- meta: { name: "trigger", description: "Manage agent heartbeats / cron triggers" },
4027
+ var triggerCommand = defineCommand23({
4028
+ meta: { name: "trigger", description: "Manage scheduled agent triggers" },
3484
4029
  subCommands: {
3485
4030
  add: addCmd3,
3486
- list: listCmd12,
4031
+ list: listCmd11,
3487
4032
  rm: rmCmd6,
3488
4033
  enable: enableCmd3,
3489
4034
  disable: disableCmd3
@@ -3491,9 +4036,9 @@ var triggerCommand = defineCommand21({
3491
4036
  });
3492
4037
 
3493
4038
  // src/commands/uninstall.ts
3494
- import { existsSync as existsSync7, readdirSync as readdirSync2, rmSync as rmSync4 } from "fs";
3495
- import { join as join6 } from "path";
3496
- import { defineCommand as defineCommand22 } from "citty";
4039
+ import { existsSync as existsSync7, readdirSync as readdirSync2, rmSync as rmSync3 } from "fs";
4040
+ import { join as join5 } from "path";
4041
+ import { defineCommand as defineCommand24 } from "citty";
3497
4042
  function makeLineReader() {
3498
4043
  let buffer = "";
3499
4044
  let ended = false;
@@ -3538,10 +4083,10 @@ async function askYes(readLine, prompt) {
3538
4083
  }
3539
4084
  function removePath(p) {
3540
4085
  if (!existsSync7(p)) return false;
3541
- rmSync4(p, { recursive: true, force: true });
4086
+ rmSync3(p, { recursive: true, force: true });
3542
4087
  return true;
3543
4088
  }
3544
- var uninstallCommand = defineCommand22({
4089
+ var uninstallCommand = defineCommand24({
3545
4090
  meta: {
3546
4091
  name: "uninstall",
3547
4092
  description: "Wipe bazilion state from ~/.bazilion (or BAZILION_HOME)"
@@ -3559,26 +4104,19 @@ var uninstallCommand = defineCommand22({
3559
4104
  },
3560
4105
  async run({ args }) {
3561
4106
  const paths = resolveCliPaths(args.home);
3562
- const dbFile = join6(paths.home, "bazilion.db");
3563
- const profilesDir = join6(paths.home, "profiles");
3564
- const agentsDir = join6(paths.home, "agents");
3565
- const groupsDir = join6(paths.home, "groups");
3566
- const skillsDir = join6(paths.home, "skills");
3567
- const logsDir = join6(paths.home, "logs");
4107
+ const dbFile = join5(paths.home, "bazilion.db");
4108
+ const profilesDir = join5(paths.home, "profiles");
4109
+ const agentsDir = join5(paths.home, "agents");
4110
+ const teamsDir = join5(paths.home, "teams");
4111
+ const skillsDir = join5(paths.home, "skills");
4112
+ const logsDir = join5(paths.home, "logs");
3568
4113
  if (!existsSync7(paths.home)) {
3569
4114
  console.log(`nothing to remove: ${paths.home} does not exist`);
3570
4115
  return;
3571
4116
  }
3572
4117
  console.log(`about to uninstall bazilion at ${paths.home}`);
3573
4118
  console.log("");
3574
- const dataTargets = [
3575
- dbFile,
3576
- `${dbFile}-wal`,
3577
- `${dbFile}-shm`,
3578
- profilesDir,
3579
- agentsDir,
3580
- groupsDir
3581
- ];
4119
+ const dataTargets = [dbFile, `${dbFile}-wal`, `${dbFile}-shm`, profilesDir, agentsDir, teamsDir];
3582
4120
  const needsPrompt = !args.yes;
3583
4121
  const readLine = needsPrompt ? makeLineReader() : null;
3584
4122
  const wipeData = args.yes || await askYes(
@@ -3604,7 +4142,7 @@ var uninstallCommand = defineCommand22({
3604
4142
  if (removePath(p)) console.log(`removed ${p}`);
3605
4143
  }
3606
4144
  if (readdirSync2(paths.home).length === 0) {
3607
- rmSync4(paths.home, { recursive: true, force: true });
4145
+ rmSync3(paths.home, { recursive: true, force: true });
3608
4146
  console.log(`removed ${paths.home}`);
3609
4147
  } else {
3610
4148
  console.log(`${paths.home} still has unmanaged files; left in place`);
@@ -3619,7 +4157,7 @@ var uninstallCommand = defineCommand22({
3619
4157
 
3620
4158
  // src/index.ts
3621
4159
  var VERSION = package_default.version;
3622
- var main = defineCommand23({
4160
+ var main = defineCommand25({
3623
4161
  meta: {
3624
4162
  name: "bazilion",
3625
4163
  version: VERSION,
@@ -3628,9 +4166,10 @@ var main = defineCommand23({
3628
4166
  subCommands: {
3629
4167
  login: loginCommand,
3630
4168
  profile: profileCommand,
3631
- "profile-group": profileGroupCommand,
3632
- group: groupCommand,
4169
+ team: teamCommand,
4170
+ "team-template": teamTemplateCommand,
3633
4171
  agent: agentCommand,
4172
+ approval: approvalCommand,
3634
4173
  skill: skillCommand,
3635
4174
  memory: memoryCommand,
3636
4175
  mcp: mcpCommand,
@@ -3685,12 +4224,22 @@ function printError(err) {
3685
4224
  console.error(" hint: host not found. Check BAZILION_SERVER / ~/.bazilion/auth.json.");
3686
4225
  }
3687
4226
  }
4227
+ function exitCodeForError(err) {
4228
+ if (err instanceof ApiClientError) {
4229
+ if (err.status === 401 || err.status === 403) return 4;
4230
+ if (err.status === 409) return 3;
4231
+ if (err.status === 400 || err.status === 422) return 2;
4232
+ return 1;
4233
+ }
4234
+ const message = err instanceof Error ? err.message : String(err);
4235
+ return /invalid|unsupported|must be|require|refusing mutation|document belongs/.test(message) ? 2 : 1;
4236
+ }
3688
4237
  function printTopLevelHelp() {
3689
4238
  console.log(`Multi-agent runtime (bazilion v${VERSION})`);
3690
4239
  console.log("");
3691
4240
  console.log("USAGE bazilion <command> [args]");
3692
4241
  console.log("");
3693
- const groups = [
4242
+ const teams = [
3694
4243
  {
3695
4244
  title: "setup",
3696
4245
  items: [
@@ -3704,8 +4253,8 @@ function printTopLevelHelp() {
3704
4253
  title: "catalog",
3705
4254
  items: [
3706
4255
  ["profile", "Manage profiles (templates agents are spawned from)"],
3707
- ["profile-group", "Manage profile groups (preconfigured team templates)"],
3708
- ["group", "Manage groups (collaboration context \u2014 filesystem root + USER.md + roster)"],
4256
+ ["team-template", "Inspect and exchange reusable Team Templates"],
4257
+ ["team", "Manage teams (collaboration context \u2014 filesystem root + USER.md + roster)"],
3709
4258
  ["skill", "Manage the skill library"],
3710
4259
  ["provider", "Manage and test LLM providers"],
3711
4260
  ["config", "Manage service config (credentials + URLs/IDs)"],
@@ -3715,11 +4264,12 @@ function printTopLevelHelp() {
3715
4264
  {
3716
4265
  title: "agents",
3717
4266
  items: [
4267
+ ["approval", "Review and decide communication approval attempts"],
3718
4268
  ["agent", "Spawn, list, chat, archive agents"],
3719
- ["memory", "Read/write a group's shared memory"],
4269
+ ["memory", "Read/write a team's shared memory"],
3720
4270
  ["send", "Send a message from one agent to another"],
3721
4271
  ["inbox", "Inspect agent inboxes"],
3722
- ["trigger", "Manage agent heartbeats / cron triggers"]
4272
+ ["trigger", "Manage scheduled agent triggers"]
3723
4273
  ]
3724
4274
  },
3725
4275
  {
@@ -3742,8 +4292,8 @@ function printTopLevelHelp() {
3742
4292
  items: [["completion", "Print shell completion script (bash | zsh | fish)"]]
3743
4293
  }
3744
4294
  ];
3745
- const nameWidth = 12;
3746
- for (const g of groups) {
4295
+ const nameWidth = 15;
4296
+ for (const g of teams) {
3747
4297
  console.log(` ${g.title}`);
3748
4298
  for (const [name, desc] of g.items) {
3749
4299
  console.log(` ${name.padEnd(nameWidth)}${desc}`);
@@ -3772,7 +4322,7 @@ async function entry() {
3772
4322
  await runCommand(main, { rawArgs });
3773
4323
  } catch (err) {
3774
4324
  printError(err);
3775
- process.exit(1);
4325
+ process.exit(exitCodeForError(err));
3776
4326
  }
3777
4327
  }
3778
4328
  entry();