bazilion 0.8.0 → 0.9.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 (163) hide show
  1. package/README.md +47 -5
  2. package/dist/cli.js +1184 -628
  3. package/dist/cli.js.map +1 -1
  4. package/dist/daemon.js +5194 -1574
  5. package/dist/daemon.js.map +1 -1
  6. package/dist/migrations/0001_init.sql +318 -88
  7. package/dist/web/client/assets/{FieldRow-CNKma5LE.js → FieldRow-DmwAFfbF.js} +1 -1
  8. package/dist/web/client/assets/ProductionTeamPolicyEditor-1a5jQqUB.js +7 -0
  9. package/dist/web/client/assets/ProductionTeamPolicyEditor-DLioOiRN.css +1 -0
  10. package/dist/web/client/assets/ProfileCommunicationEditor-D1OZ8WE5.js +1 -0
  11. package/dist/web/client/assets/RecoveryState-QfMSuwy3.js +1 -0
  12. package/dist/web/client/assets/TeamTabs-BViZ4sti.js +1 -0
  13. package/dist/web/client/assets/TemplatesTabs-DVcY9pMD.js +1 -0
  14. package/dist/web/client/assets/_id-8P7brhGy.js +1 -0
  15. package/dist/web/client/assets/_id-C3o3MHq8.js +1 -0
  16. package/dist/web/client/assets/_id-DGRrSF1e.js +1 -0
  17. package/dist/web/client/assets/_id-DGyKURCp.js +1 -0
  18. package/dist/web/client/assets/_id-KnJe-aW9.js +1 -0
  19. package/dist/web/client/assets/activity-DJuhhQCb.js +1 -0
  20. package/dist/web/client/assets/activity-WWvJSo4t.js +1 -0
  21. package/dist/web/client/assets/agents-C32T1voV.js +1 -0
  22. package/dist/web/client/assets/agents-nH4m4gZ1.js +1 -0
  23. package/dist/web/client/assets/approvals-DGi0PSx8.js +1 -0
  24. package/dist/web/client/assets/approvals-l8jIZjqz.js +1 -0
  25. package/dist/web/client/assets/{config-DIuEc5bm.js → config-C7wvi1nR.js} +2 -2
  26. package/dist/web/client/assets/context-BEGWE3RC.js +1 -0
  27. package/dist/web/client/assets/inbox--4aBaAgG.js +1 -0
  28. package/dist/web/client/assets/index-BCXoh1c8.js +12 -0
  29. package/dist/web/client/assets/{login-CawJX16E.js → login-Bk2wwIHQ.js} +1 -1
  30. package/dist/web/client/assets/{mcp-DIrh9-v_.js → mcp-vM7xgh9e.js} +1 -1
  31. package/dist/web/client/assets/members-cPKfnrSL.js +1 -0
  32. package/dist/web/client/assets/memory-BOcsaemD.js +1 -0
  33. package/dist/web/client/assets/policy-BGLCJYvS.js +1 -0
  34. package/dist/web/client/assets/policy-K4hIbbIN.js +1 -0
  35. package/dist/web/client/assets/{preload-helper-CvnapA2_.js → preload-helper-eOOCz1Fu.js} +1 -1
  36. package/dist/web/client/assets/routes-DnrP3dwv.js +1 -0
  37. package/dist/web/client/assets/services-C2_O3ifw.js +1 -0
  38. package/dist/web/client/assets/{skills-Da0MURjY.js → skills-B__fLZjx.js} +1 -1
  39. package/dist/web/client/assets/styles-Dn24-ZvP.css +2 -0
  40. package/dist/web/client/assets/team-policy-BdX340m4.js +1 -0
  41. package/dist/web/client/assets/teams-CSNyLz3l.js +1 -0
  42. package/dist/web/client/assets/teams-DZMB4_iw.js +1 -0
  43. package/dist/web/client/assets/teams-rpaYKNIb.js +1 -0
  44. package/dist/web/client/assets/telegram-B1O4Ko0V.js +1 -0
  45. package/dist/web/client/assets/{tokens-E_JvO5JN.js → tokens-D7FH9VgA.js} +1 -1
  46. package/dist/web/client/assets/triggers-3PLy2_Fo.js +1 -0
  47. package/dist/web/client/assets/welcome-B-QQobzq.js +1 -0
  48. package/dist/web/client/assets/{ChatPane-DzEgOEqS.js → wire-constants-BY9Q9Z7d.js} +4 -4
  49. package/dist/web/server/assets/{ChatPane-BvpswYvF.js → ChatPane-Dh3qxzdb.js} +23 -12
  50. package/dist/web/server/assets/ProductionTeamPolicyEditor-Bke5doyl.js +1009 -0
  51. package/dist/web/server/assets/ProfileCommunicationEditor-C2RU-2QB.js +107 -0
  52. package/dist/web/server/assets/RecoveryState-B2SG-mrY.js +37 -0
  53. package/dist/web/server/assets/{Sidebar-DmEiewRN.js → Sidebar-CGmtCnYU.js} +372 -48
  54. package/dist/web/server/assets/TeamTabs-BPxDBfqy.js +50 -0
  55. package/dist/web/server/assets/{TemplatesTabs---7h5GYa.js → TemplatesTabs-zf4YhStd.js} +6 -6
  56. package/dist/web/server/assets/{_id-CXg-Blec.js → _id-5lLzLwcv.js} +52 -40
  57. package/dist/web/server/assets/_id-A8Xiv6Lc.js +11 -0
  58. package/dist/web/server/assets/{_id-BqnDy_Ca.js → _id-B04VaQlh.js} +6 -5
  59. package/dist/web/server/assets/{_id-BdRiQb2H.js → _id-B6g9wmPR.js} +126 -27
  60. package/dist/web/server/assets/_id-ButXHnRH.js +14 -0
  61. package/dist/web/server/assets/_id-C4AOhstq.js +44 -0
  62. package/dist/web/server/assets/{_id-DDixKEud.js → _id-CCHA0gdR.js} +72 -12
  63. package/dist/web/server/assets/{_id-D_Ew11ED.js → _id-CUWgTqMS.js} +8 -8
  64. package/dist/web/server/assets/_id-DJkzwHjM.js +42 -0
  65. package/dist/web/server/assets/{_id-CnQflrRv.js → _id-DdC9wpNN.js} +5 -5
  66. package/dist/web/server/assets/{_id-DUIrFV3G.js → _id-DkFgCIb-.js} +9 -1
  67. package/dist/web/server/assets/{_id-D8duqgd5.js → _id-_nFwi9gD.js} +5 -4
  68. package/dist/web/server/assets/{_id-Sjw0zhA6.js → _id-fpFQ9_Ya.js} +4 -4
  69. package/dist/web/server/assets/_tanstack-start-manifest_v-Div-TukY.js +241 -0
  70. package/dist/web/server/assets/activity-C2ZKg1Q9.js +170 -0
  71. package/dist/web/server/assets/activity-CGCf8BQf.js +11 -0
  72. package/dist/web/server/assets/activity-DedraoFj.js +14 -0
  73. package/dist/web/server/assets/activity-GPx8NCeB.js +12 -0
  74. package/dist/web/server/assets/{profiles-CZ5NkmVw.js → agents-B8kinIPW.js} +4 -4
  75. package/dist/web/server/assets/{agents-k5QURC4I.js → agents-BR2qXlXF.js} +4 -4
  76. package/dist/web/server/assets/{agents-ChcAJUI5.js → agents-Bp1nsVs2.js} +1 -1
  77. package/dist/web/server/assets/{profiles-LxcC_L6n.js → agents-CUQmWhTp.js} +36 -10
  78. package/dist/web/server/assets/{agents-C7SBPN0M.js → agents-DU9Hqs58.js} +51 -12
  79. package/dist/web/server/assets/{profiles-C6a3RKgu.js → agents-LHowEI6S.js} +4 -4
  80. package/dist/web/server/assets/approvals-CbFXFvG8.js +11 -0
  81. package/dist/web/server/assets/approvals-DHgARzd8.js +242 -0
  82. package/dist/web/server/assets/approvals-Dw2LJoSA.js +14 -0
  83. package/dist/web/server/assets/approvals-VPc0YpLN.js +12 -0
  84. package/dist/web/server/assets/{auth-DzRAMwVt.js → auth-l-Vf8wlu.js} +5 -1
  85. package/dist/web/server/assets/{config-CdVjqjin.js → config-BvKctDOX.js} +4 -4
  86. package/dist/web/server/assets/{config-Bq3o924J.js → config-QvHaxGlP.js} +1 -1
  87. package/dist/web/server/assets/context-5lrf2ame.js +12 -0
  88. package/dist/web/server/assets/context-CEr4-xiA.js +49 -0
  89. package/dist/web/server/assets/context-D3Egm-vY.js +12 -0
  90. package/dist/web/server/assets/members-40DxRdVj.js +48 -0
  91. package/dist/web/server/assets/members-DlGBKZNl.js +12 -0
  92. package/dist/web/server/assets/members-ksELRsyk.js +12 -0
  93. package/dist/web/server/assets/{memory-Ns2-Z31p.js → memory-B5moRnnp.js} +5 -5
  94. package/dist/web/server/assets/{memory-BaYnfm7K.js → memory-CO0jKGzJ.js} +8 -8
  95. package/dist/web/server/assets/memory-CiTl4cN9.js +289 -0
  96. package/dist/web/server/assets/policy-BYVXqsan.js +11 -0
  97. package/dist/web/server/assets/policy-DNcGZLOB.js +21 -0
  98. package/dist/web/server/assets/policy-Dr55y-Mh.js +496 -0
  99. package/dist/web/server/assets/policy-Dxs78_GO.js +40 -0
  100. package/dist/web/server/assets/{router-BrDascdO.js → router-_izWQUeG.js} +156 -101
  101. package/dist/web/server/assets/{routes-Ce2VWrU9.js → routes-BSSKp3Rv.js} +4 -4
  102. package/dist/web/server/assets/{routes-C61gBiXa.js → routes-BrTOoeth.js} +5 -5
  103. package/dist/web/server/assets/{routes-V9URcp1v.js → routes-DOj6ljcm.js} +1 -1
  104. package/dist/web/server/assets/{services-B91w2f-X.js → services-CHe4ihJk.js} +11 -11
  105. package/dist/web/server/assets/{services-Ccc5s2bS.js → services-Pv_V88VA.js} +3 -3
  106. package/dist/web/server/assets/{start-CYDpZ6cb.js → start-DlHq0RaQ.js} +1 -1
  107. package/dist/web/server/assets/team-policy-Csvc5EDd.js +180 -0
  108. package/dist/web/server/assets/teams-35Oprf6e.js +14 -0
  109. package/dist/web/server/assets/teams-3im0oQnS.js +11 -0
  110. package/dist/web/server/assets/teams-B5IF65p2.js +12 -0
  111. package/dist/web/server/assets/teams-B9O-WDH5.js +108 -0
  112. package/dist/web/server/assets/teams-DFkN7ic7.js +36 -0
  113. package/dist/web/server/assets/teams-DH1CvWmT.js +12 -0
  114. package/dist/web/server/assets/teams-zcm9XaQU.js +174 -0
  115. package/dist/web/server/assets/{telegram-DfAddLdv.js → telegram-C9sQFwWj.js} +7 -7
  116. package/dist/web/server/assets/{telegram-T3l9KtiE.js → telegram-mTnJCOmn.js} +1 -1
  117. package/dist/web/server/assets/{welcome-CP4CZ9B6.js → welcome-CDGE2Sdk.js} +2 -2
  118. package/dist/web/server/assets/{wire-constants-Deb4NxBb.js → wire-constants-C8nBJcU3.js} +3 -3
  119. package/dist/web/server/server.js +64 -42
  120. package/dist/worker.js +180 -128
  121. package/dist/worker.js.map +1 -1
  122. package/package.json +7 -7
  123. package/dist/migrations/0002_profile_groups.sql +0 -38
  124. package/dist/migrations/0003_agent_telegram.sql +0 -40
  125. package/dist/migrations/0004_agent_mirror_mode.sql +0 -17
  126. package/dist/migrations/0005_group_topic_name_format.sql +0 -15
  127. package/dist/migrations/0006_telegram_acl.sql +0 -18
  128. package/dist/migrations/0007_mcp_servers.sql +0 -30
  129. package/dist/migrations/0008_seed_user_md.sql +0 -39
  130. package/dist/web/client/assets/MembersEditor-C6UpqDdV.js +0 -1
  131. package/dist/web/client/assets/SpawnTeamModal-BEkNCKXm.js +0 -1
  132. package/dist/web/client/assets/TemplatesTabs-UM04RMO9.js +0 -1
  133. package/dist/web/client/assets/_id-BNJapCT4.js +0 -1
  134. package/dist/web/client/assets/_id-CjGoV8Mr.js +0 -1
  135. package/dist/web/client/assets/_id-DehuCHUw.js +0 -1
  136. package/dist/web/client/assets/_id-Dz9fjcCM.js +0 -1
  137. package/dist/web/client/assets/agents-M6omAXcZ.js +0 -1
  138. package/dist/web/client/assets/groups-DpE2d2zZ.js +0 -1
  139. package/dist/web/client/assets/inbox-BPnLsRNf.js +0 -1
  140. package/dist/web/client/assets/index-MAJuXnie.js +0 -12
  141. package/dist/web/client/assets/memory-BpHbdKsd.js +0 -1
  142. package/dist/web/client/assets/profile-groups-ByoKak0c.js +0 -1
  143. package/dist/web/client/assets/profiles-BEjv8LGo.js +0 -1
  144. package/dist/web/client/assets/routes-D2COHy7v.js +0 -1
  145. package/dist/web/client/assets/services-D212jSK_.js +0 -1
  146. package/dist/web/client/assets/styles-BgE5bCHA.css +0 -2
  147. package/dist/web/client/assets/telegram-Czh2MdVm.js +0 -1
  148. package/dist/web/client/assets/triggers-BBRZQOm7.js +0 -1
  149. package/dist/web/client/assets/welcome-Dn-zvmBE.js +0 -1
  150. package/dist/web/client/assets/wire-constants-BkT5-597.js +0 -1
  151. package/dist/web/server/assets/MembersEditor-BWQztvrX.js +0 -131
  152. package/dist/web/server/assets/SpawnTeamModal-dSN421k_.js +0 -107
  153. package/dist/web/server/assets/_id-BKev9H1p.js +0 -12
  154. package/dist/web/server/assets/_id-BNwlbWHP.js +0 -24
  155. package/dist/web/server/assets/_id-CRqqi8IE.js +0 -161
  156. package/dist/web/server/assets/_tanstack-start-manifest_v-D9FLKShQ.js +0 -178
  157. package/dist/web/server/assets/groups-CbSwND2r.js +0 -12
  158. package/dist/web/server/assets/groups-CeRRlZaZ.js +0 -150
  159. package/dist/web/server/assets/groups-pk4CYSuf.js +0 -21
  160. package/dist/web/server/assets/memory-CQaqWnyM.js +0 -284
  161. package/dist/web/server/assets/profile-groups-CiU06yN1.js +0 -28
  162. package/dist/web/server/assets/profile-groups-D21MYoLM.js +0 -208
  163. package/dist/web/server/assets/profile-groups-aoJleXHP.js +0 -12
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.9.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,9 +49,9 @@ 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
57
  "@tanstack/react-router": "1.170.16",
@@ -277,13 +277,13 @@ function asPaths(v) {
277
277
  return v ? Array.isArray(v) ? v : [v] : [];
278
278
  }
279
279
  var spawnCmd = defineCommand({
280
- meta: { name: "spawn", description: "Spawn an agent from a profile into a group" },
280
+ meta: { name: "spawn", description: "Spawn an agent from a profile into a team" },
281
281
  args: {
282
282
  profile: { type: "string", required: true, description: "Profile id" },
283
283
  name: { type: "string", description: "Agent name (defaults to profile name)" },
284
- group: {
284
+ team: {
285
285
  type: "string",
286
- description: "Group to join (defaults to 'default')"
286
+ description: "Team to join (defaults to 'default')"
287
287
  },
288
288
  model: { type: "string", description: "Override profile default model" },
289
289
  reasoning: {
@@ -293,14 +293,21 @@ var spawnCmd = defineCommand({
293
293
  },
294
294
  async run({ args }) {
295
295
  const client = createClient2();
296
+ const teamId = args.team ?? "default";
297
+ const policy = await client.get(
298
+ `/api/teams/${encodeURIComponent(teamId)}/policy`
299
+ );
296
300
  const body = {
297
301
  profileId: args.profile,
298
302
  name: args.name,
299
303
  model: args.model,
300
304
  reasoningLevel: args.reasoning,
301
- groupId: args.group
305
+ teamId,
306
+ teamExpectedRevision: policy.teamPolicy.revision,
307
+ placement: "open"
302
308
  };
303
- const agent = await client.post("/api/agents", body);
309
+ const response = await client.post("/api/agents", body);
310
+ const agent = response.agent;
304
311
  console.log(`spawned agent ${agent.id} (${agent.name})`);
305
312
  console.log(`dir: ${agent.dir}`);
306
313
  }
@@ -364,12 +371,12 @@ var listCmd = defineCommand({
364
371
  async run({ args }) {
365
372
  const client = createClient2();
366
373
  const q = args.all ? "?includeArchived=true" : "";
367
- const list = await client.get(`/api/agents${q}`);
368
- if (list.length === 0) {
374
+ const list3 = await client.get(`/api/agents${q}`);
375
+ if (list3.length === 0) {
369
376
  console.log("(no agents)");
370
377
  return;
371
378
  }
372
- const rows = list.map(
379
+ const rows = list3.map(
373
380
  (a) => args.long ? [a.id, a.status, a.name, a.profileId] : (
374
381
  // Short UUID prefix — all CLI commands accept 4+ char prefixes now.
375
382
  [a.id.slice(0, 8), a.status, a.name]
@@ -392,7 +399,7 @@ var showCmd = defineCommand({
392
399
  console.log(`profile: ${r.profile.id}`);
393
400
  console.log(`model: ${r.model}`);
394
401
  console.log(`dir: ${r.agent.dir}`);
395
- console.log(`group: ${r.group.id} ${r.group.path}`);
402
+ console.log(`team: ${r.team.id} ${r.team.path}`);
396
403
  console.log("skills:");
397
404
  if (r.skills.length === 0) {
398
405
  console.log(" (none)");
@@ -430,7 +437,13 @@ var deleteCmd = defineCommand({
430
437
  },
431
438
  async run({ args }) {
432
439
  const client = createClient2();
433
- await client.del(`/api/agents/${args.id}`);
440
+ const agent = await client.get(`/api/agents/${encodeURIComponent(args.id)}`);
441
+ const policy = await client.get(
442
+ `/api/teams/${encodeURIComponent(agent.team.id)}/policy`
443
+ );
444
+ await client.del(
445
+ `/api/agents/${encodeURIComponent(args.id)}?expectedTeamRevision=${policy.teamPolicy.revision}`
446
+ );
434
447
  console.log(`deleted agent ${args.id}`);
435
448
  }
436
449
  });
@@ -632,8 +645,8 @@ var chatContextCmd = defineCommand({
632
645
  if (ctx.systemPrompt.skillsListChars > 0) {
633
646
  console.log(` skills line: ${ctx.systemPrompt.skillsListChars.toLocaleString()} chars`);
634
647
  }
635
- if (ctx.systemPrompt.groupListChars > 0) {
636
- console.log(` group block: ${ctx.systemPrompt.groupListChars.toLocaleString()} chars`);
648
+ if (ctx.systemPrompt.teamListChars > 0) {
649
+ console.log(` team block: ${ctx.systemPrompt.teamListChars.toLocaleString()} chars`);
637
650
  }
638
651
  if (ctx.systemPrompt.userMdChars > 0) {
639
652
  console.log(` user_md block: ${ctx.systemPrompt.userMdChars.toLocaleString()} chars`);
@@ -662,10 +675,10 @@ var chatContextCmd = defineCommand({
662
675
  }
663
676
  console.log("");
664
677
  }
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`);
678
+ console.log("## team");
679
+ console.log(` - ${ctx.team.id} (${ctx.team.name}): ${ctx.team.path}`);
680
+ if (ctx.team.userMdChars > 0) {
681
+ console.log(` user_md: ${ctx.team.userMdChars.toLocaleString()} chars`);
669
682
  }
670
683
  console.log("");
671
684
  console.log("## history");
@@ -788,16 +801,28 @@ var skillCmd = defineCommand({
788
801
  }
789
802
  });
790
803
  var moveCmd = defineCommand({
791
- meta: { name: "move", description: "Move an agent to a different group" },
804
+ meta: { name: "move", description: "Move an agent to a different team" },
792
805
  args: {
793
806
  agent: { type: "positional", required: true },
794
- group: { type: "positional", required: true }
807
+ team: { type: "positional", required: true }
795
808
  },
796
809
  async run({ args }) {
797
810
  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}`);
811
+ const [agent, destination] = await Promise.all([
812
+ client.get(`/api/agents/${encodeURIComponent(args.agent)}`),
813
+ client.get(`/api/teams/${encodeURIComponent(args.team)}/policy`)
814
+ ]);
815
+ const source = await client.get(
816
+ `/api/teams/${encodeURIComponent(agent.team.id)}/policy`
817
+ );
818
+ const body = {
819
+ teamId: args.team,
820
+ sourceExpectedRevision: source.teamPolicy.revision,
821
+ destinationExpectedRevision: destination.teamPolicy.revision,
822
+ placement: "open"
823
+ };
824
+ await client.patch(`/api/agents/${args.agent}/team`, body);
825
+ console.log(`moved ${args.agent} to team ${args.team}`);
801
826
  }
802
827
  });
803
828
  var sessionHeadCmd = defineCommand({
@@ -852,15 +877,102 @@ var agentCommand = defineCommand({
852
877
  }
853
878
  });
854
879
 
880
+ // src/commands/approval.ts
881
+ import { defineCommand as defineCommand2 } from "citty";
882
+ var list = defineCommand2({
883
+ meta: { name: "list", description: "List communication approval queue/history" },
884
+ args: {
885
+ status: { type: "string", default: "pending" },
886
+ team: { type: "string" },
887
+ json: { type: "boolean" }
888
+ },
889
+ async run({ args }) {
890
+ const query = new URLSearchParams({ status: args.status, limit: "100" });
891
+ if (args.team) query.set("teamId", args.team);
892
+ const body = await createClient2().get(
893
+ `/api/approvals?${query}`
894
+ );
895
+ if (args.json) return console.log(JSON.stringify(body, null, 2));
896
+ if (!body.approvals.length) return console.log("(no approvals)");
897
+ for (const line of columnize([
898
+ ["id", "status", "path", "origin", "expires"],
899
+ ...body.approvals.map((item) => [
900
+ item.id,
901
+ item.status,
902
+ `${endpoint(item.source)} -> ${endpoint(item.target)}`,
903
+ item.origin,
904
+ new Date(item.expiresAt).toISOString()
905
+ ])
906
+ ]))
907
+ console.log(line);
908
+ }
909
+ });
910
+ var show = defineCommand2({
911
+ meta: { name: "show", description: "Show one approval including payload and audit events" },
912
+ args: { id: { type: "positional", required: true }, json: { type: "boolean" } },
913
+ async run({ args }) {
914
+ const item = await createClient2().get(
915
+ `/api/approvals/${encodeURIComponent(args.id)}`
916
+ );
917
+ if (args.json) return console.log(JSON.stringify(item, null, 2));
918
+ console.log(`# ${item.id}`);
919
+ console.log(`status: ${item.status}`);
920
+ console.log(`attempt: ${item.attemptKind}:${item.attemptId}`);
921
+ console.log(`path: ${endpoint(item.source)} -> ${endpoint(item.target)}`);
922
+ console.log(`origin: ${item.origin}`);
923
+ console.log(`expires: ${new Date(item.expiresAt).toISOString()}`);
924
+ console.log(
925
+ `revisions: ${item.policyRefs.map((ref) => `${ref.teamId}@${ref.revision}`).join(", ")}`
926
+ );
927
+ console.log(`events: ${item.events.map((event) => event.event).join(" -> ")}`);
928
+ }
929
+ });
930
+ function decision(name) {
931
+ return defineCommand2({
932
+ meta: {
933
+ name,
934
+ description: name === "approve" ? "Approve and deliver one captured attempt" : `${name === "deny" ? "Deny" : "Cancel"} one pending attempt`
935
+ },
936
+ args: {
937
+ id: { type: "positional", required: true },
938
+ reason: { type: "string" },
939
+ yes: { type: "boolean", description: "Required explicit non-interactive confirmation" },
940
+ json: { type: "boolean" }
941
+ },
942
+ async run({ args }) {
943
+ if (!args.yes) throw new Error(`refusing ${name}: review with approval show, then pass --yes`);
944
+ const item = await createClient2().post(
945
+ `/api/approvals/${encodeURIComponent(args.id)}/${name}`,
946
+ args.reason ? { reason: args.reason } : {}
947
+ );
948
+ if (args.json) console.log(JSON.stringify(item, null, 2));
949
+ else console.log(`${item.id}: ${item.status}`);
950
+ }
951
+ });
952
+ }
953
+ function endpoint(value) {
954
+ return value.kind === "agent" ? `agent:${value.id}` : value.kind === "user" ? `user:${value.teamId}` : `outside:${value.teamId}`;
955
+ }
956
+ var approvalCommand = defineCommand2({
957
+ meta: { name: "approval", description: "Manage communication approval queue and history" },
958
+ subCommands: {
959
+ list,
960
+ show,
961
+ approve: decision("approve"),
962
+ deny: decision("deny"),
963
+ cancel: decision("cancel")
964
+ }
965
+ });
966
+
855
967
  // src/commands/auth.ts
856
968
  import { loginOpenAICodex } from "@earendil-works/pi-ai/oauth";
857
- import { defineCommand as defineCommand2 } from "citty";
969
+ import { defineCommand as defineCommand3 } from "citty";
858
970
  function formatExpiry(ms) {
859
971
  if (!ms) return "(unknown)";
860
972
  const d = new Date(ms);
861
973
  return d.toISOString().replace(/\.\d+Z$/, "Z");
862
974
  }
863
- var openaiLoginCmd = defineCommand2({
975
+ var openaiLoginCmd = defineCommand3({
864
976
  meta: {
865
977
  name: "login",
866
978
  description: "Connect your ChatGPT account via OAuth (browser sign-in)"
@@ -902,7 +1014,7 @@ var openaiLoginCmd = defineCommand2({
902
1014
  console.log(" bazilion provider models-set openai-codex gpt-5.3-codex-spark");
903
1015
  }
904
1016
  });
905
- var openaiLogoutCmd = defineCommand2({
1017
+ var openaiLogoutCmd = defineCommand3({
906
1018
  meta: {
907
1019
  name: "logout",
908
1020
  description: "Forget the stored ChatGPT OAuth credentials"
@@ -913,7 +1025,7 @@ var openaiLogoutCmd = defineCommand2({
913
1025
  console.log("disconnected ChatGPT OAuth credentials");
914
1026
  }
915
1027
  });
916
- var openaiStatusCmd = defineCommand2({
1028
+ var openaiStatusCmd = defineCommand3({
917
1029
  meta: {
918
1030
  name: "status",
919
1031
  description: "Show ChatGPT OAuth connection status"
@@ -930,7 +1042,7 @@ var openaiStatusCmd = defineCommand2({
930
1042
  console.log(`access token expires: ${formatExpiry(status.expiresAt)}`);
931
1043
  }
932
1044
  });
933
- var openaiCmd = defineCommand2({
1045
+ var openaiCmd = defineCommand3({
934
1046
  meta: {
935
1047
  name: "openai",
936
1048
  description: "Manage ChatGPT (OAuth) authentication"
@@ -941,7 +1053,7 @@ var openaiCmd = defineCommand2({
941
1053
  status: openaiStatusCmd
942
1054
  }
943
1055
  });
944
- var authCommand = defineCommand2({
1056
+ var authCommand = defineCommand3({
945
1057
  meta: {
946
1058
  name: "auth",
947
1059
  description: "OAuth-based provider authentication (ChatGPT account, etc.)"
@@ -957,8 +1069,8 @@ import { createWriteStream, existsSync as existsSync2, mkdirSync, readdirSync, r
957
1069
  import { resolve } from "path";
958
1070
  import { Readable } from "stream";
959
1071
  import { pipeline } from "stream/promises";
960
- import { defineCommand as defineCommand3 } from "citty";
961
- var createCmd = defineCommand3({
1072
+ import { defineCommand as defineCommand4 } from "citty";
1073
+ var createCmd = defineCommand4({
962
1074
  meta: { name: "create", description: "Download a tar.gz backup of ~/.bazilion from the server" },
963
1075
  args: {
964
1076
  output: {
@@ -999,7 +1111,7 @@ async function probeServerRunning(port) {
999
1111
  return false;
1000
1112
  }
1001
1113
  }
1002
- var restoreCmd = defineCommand3({
1114
+ var restoreCmd = defineCommand4({
1003
1115
  meta: {
1004
1116
  name: "restore",
1005
1117
  description: "Extract a backup tar.gz into ~/.bazilion (offline; server must be stopped)"
@@ -1052,7 +1164,7 @@ var restoreCmd = defineCommand3({
1052
1164
  console.log("start the server with: bazilion serve (migrations apply automatically)");
1053
1165
  }
1054
1166
  });
1055
- var backupCommand = defineCommand3({
1167
+ var backupCommand = defineCommand4({
1056
1168
  meta: { name: "backup", description: "Create or restore a ~/.bazilion tar.gz backup" },
1057
1169
  subCommands: {
1058
1170
  create: createCmd,
@@ -1066,7 +1178,7 @@ var backupCommand = defineCommand3({
1066
1178
  });
1067
1179
 
1068
1180
  // src/commands/completion.ts
1069
- import { defineCommand as defineCommand4 } from "citty";
1181
+ import { defineCommand as defineCommand5 } from "citty";
1070
1182
  async function walk(cmd, path, out) {
1071
1183
  const subsRaw = cmd.subCommands ?? {};
1072
1184
  const subNames = Object.keys(subsRaw);
@@ -1171,7 +1283,7 @@ function fishScript(flat) {
1171
1283
  `;
1172
1284
  }
1173
1285
  function completionCommand(main2) {
1174
- return defineCommand4({
1286
+ return defineCommand5({
1175
1287
  meta: {
1176
1288
  name: "completion",
1177
1289
  description: "Print a shell completion script (bash, zsh, or fish)"
@@ -1196,13 +1308,13 @@ function completionCommand(main2) {
1196
1308
  }
1197
1309
 
1198
1310
  // src/commands/config.ts
1199
- import { defineCommand as defineCommand5 } from "citty";
1311
+ import { defineCommand as defineCommand6 } from "citty";
1200
1312
  function displayValue(f) {
1201
1313
  if (!f.set) return "(unset)";
1202
1314
  if (f.kind === "secret") return f.preview ?? "(set)";
1203
1315
  return f.value ?? "(set)";
1204
1316
  }
1205
- var listCmd2 = defineCommand5({
1317
+ var listCmd2 = defineCommand6({
1206
1318
  meta: {
1207
1319
  name: "list",
1208
1320
  description: "List every configurable field (credentials + URLs) across all services"
@@ -1225,7 +1337,7 @@ var listCmd2 = defineCommand5({
1225
1337
  for (const line of columnize(rows)) console.log(line);
1226
1338
  }
1227
1339
  });
1228
- var setCmd = defineCommand5({
1340
+ var setCmd = defineCommand6({
1229
1341
  meta: {
1230
1342
  name: "set",
1231
1343
  description: "Set a configurable field (auto-routes to secrets or plaintext store)"
@@ -1252,7 +1364,7 @@ var setCmd = defineCommand5({
1252
1364
  console.log(`${state.envVar} (${state.kind}): ${displayValue(state)}`);
1253
1365
  }
1254
1366
  });
1255
- var rmCmd = defineCommand5({
1367
+ var rmCmd = defineCommand6({
1256
1368
  meta: { name: "rm", description: "Remove a configurable field value" },
1257
1369
  args: {
1258
1370
  envVar: { type: "positional", required: true, description: "Env var name to clear" }
@@ -1263,7 +1375,7 @@ var rmCmd = defineCommand5({
1263
1375
  console.log(`removed ${args.envVar}`);
1264
1376
  }
1265
1377
  });
1266
- var configCommand = defineCommand5({
1378
+ var configCommand = defineCommand6({
1267
1379
  meta: {
1268
1380
  name: "config",
1269
1381
  description: "Manage service configuration \u2014 credentials (encrypted) and URLs/IDs (plaintext), unified under one CLI"
@@ -1280,7 +1392,7 @@ import { spawn as spawn2 } from "child_process";
1280
1392
  import { existsSync as existsSync3 } from "fs";
1281
1393
  import { connect } from "net";
1282
1394
  import { join as join2 } from "path";
1283
- import { defineCommand as defineCommand6 } from "citty";
1395
+ import { defineCommand as defineCommand7 } from "citty";
1284
1396
  var bundledDaemonEntry = join2(import.meta.dirname, "daemon.js");
1285
1397
  var sourceDaemonEntry = join2(import.meta.dirname, "..", "..", "..", "daemon", "src", "index.ts");
1286
1398
  var daemonEntry = existsSync3(bundledDaemonEntry) ? bundledDaemonEntry : sourceDaemonEntry;
@@ -1374,7 +1486,7 @@ function spawnProcess(label, entry2, env) {
1374
1486
  stdio: "inherit"
1375
1487
  });
1376
1488
  }
1377
- var dashboardCommand = defineCommand6({
1489
+ var dashboardCommand = defineCommand7({
1378
1490
  meta: {
1379
1491
  name: "dashboard",
1380
1492
  description: "Start the bazilion daemon and bundled web UI"
@@ -1493,8 +1605,8 @@ var dashboardCommand = defineCommand6({
1493
1605
  });
1494
1606
 
1495
1607
  // src/commands/doctor.ts
1496
- import { defineCommand as defineCommand7 } from "citty";
1497
- var doctorCommand = defineCommand7({
1608
+ import { defineCommand as defineCommand8 } from "citty";
1609
+ var doctorCommand = defineCommand8({
1498
1610
  meta: { name: "doctor", description: "Diagnose your bazilion install" },
1499
1611
  async run() {
1500
1612
  const client = createClient2();
@@ -1521,7 +1633,7 @@ var doctorCommand = defineCommand7({
1521
1633
  console.log(
1522
1634
  ` ${r.database.activeAgents} active agent(s) (${r.database.totalAgents} total)`
1523
1635
  );
1524
- console.log(` ${r.database.groups} group(s)`);
1636
+ console.log(` ${r.database.teams} team(s)`);
1525
1637
  } else {
1526
1638
  check("open database", false, r.database.error);
1527
1639
  }
@@ -1605,178 +1717,6 @@ var doctorCommand = defineCommand7({
1605
1717
  }
1606
1718
  });
1607
1719
 
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
1720
  // src/commands/inbox.ts
1781
1721
  import { defineCommand as defineCommand9 } from "citty";
1782
1722
  function decodeText(payload) {
@@ -1790,11 +1730,11 @@ function decodeText(payload) {
1790
1730
  function messageRow(m) {
1791
1731
  const when = new Date(m.createdAt).toISOString();
1792
1732
  const state = m.readAt ? "read" : "NEW";
1793
- const text = decodeText(m.payload);
1794
- const preview = text.length > 60 ? `${text.slice(0, 60)}\u2026` : text;
1733
+ const text2 = decodeText(m.payload);
1734
+ const preview = text2.length > 60 ? `${text2.slice(0, 60)}\u2026` : text2;
1795
1735
  return [m.id, state, when, `from:${m.fromAgentId.slice(0, 8)}`, `"${preview}"`];
1796
1736
  }
1797
- var listCmd4 = defineCommand9({
1737
+ var listCmd3 = defineCommand9({
1798
1738
  meta: { name: "list", description: "List messages in an agent inbox" },
1799
1739
  args: {
1800
1740
  agent: { type: "positional", required: true, description: "Recipient agent id" },
@@ -1847,14 +1787,14 @@ var readCmd = defineCommand9({
1847
1787
  var inboxCommand = defineCommand9({
1848
1788
  meta: { name: "inbox", description: "Inspect agent inboxes" },
1849
1789
  subCommands: {
1850
- list: listCmd4,
1790
+ list: listCmd3,
1851
1791
  show: showCmd2,
1852
1792
  read: readCmd
1853
1793
  }
1854
1794
  });
1855
1795
 
1856
1796
  // src/commands/login.ts
1857
- import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
1797
+ import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
1858
1798
  import { defineCommand as defineCommand10 } from "citty";
1859
1799
  function normalizeServer(raw) {
1860
1800
  let url;
@@ -1893,7 +1833,7 @@ var loginCommand = defineCommand10({
1893
1833
  `${paths.authFile} not found. Start the daemon with "bazilion serve" first \u2014 login stores the remote there.`
1894
1834
  );
1895
1835
  }
1896
- const auth = JSON.parse(readFileSync4(paths.authFile, "utf8"));
1836
+ const auth = JSON.parse(readFileSync3(paths.authFile, "utf8"));
1897
1837
  if (args.clear) {
1898
1838
  if (!auth.remote) {
1899
1839
  console.log("no remote stored \u2014 nothing to clear");
@@ -1935,7 +1875,7 @@ function serverRow(s) {
1935
1875
  where
1936
1876
  ];
1937
1877
  }
1938
- var addCmd2 = defineCommand11({
1878
+ var addCmd = defineCommand11({
1939
1879
  meta: { name: "add", description: "Register an MCP server" },
1940
1880
  args: {
1941
1881
  name: { type: "positional", required: true, description: "Unique name ([a-zA-Z0-9_])" },
@@ -1962,7 +1902,7 @@ var addCmd2 = defineCommand11({
1962
1902
  console.log(`${server.id} ${server.name} ${server.transport}`);
1963
1903
  }
1964
1904
  });
1965
- var listCmd5 = defineCommand11({
1905
+ var listCmd4 = defineCommand11({
1966
1906
  meta: { name: "list", description: "List MCP servers" },
1967
1907
  async run() {
1968
1908
  const client = createClient2();
@@ -1983,7 +1923,7 @@ var showCmd3 = defineCommand11({
1983
1923
  console.log(JSON.stringify(server, null, 2));
1984
1924
  }
1985
1925
  });
1986
- var rmCmd3 = defineCommand11({
1926
+ var rmCmd2 = defineCommand11({
1987
1927
  meta: { name: "rm", description: "Delete an MCP server" },
1988
1928
  args: { id: { type: "positional", required: true } },
1989
1929
  async run({ args }) {
@@ -2031,10 +1971,10 @@ var testCmd = defineCommand11({
2031
1971
  var mcpCommand = defineCommand11({
2032
1972
  meta: { name: "mcp", description: "Manage MCP servers" },
2033
1973
  subCommands: {
2034
- add: addCmd2,
2035
- list: listCmd5,
1974
+ add: addCmd,
1975
+ list: listCmd4,
2036
1976
  show: showCmd3,
2037
- rm: rmCmd3,
1977
+ rm: rmCmd2,
2038
1978
  enable: enableCmd,
2039
1979
  disable: disableCmd,
2040
1980
  test: testCmd
@@ -2047,39 +1987,39 @@ function encodeKey(key) {
2047
1987
  return key.split("/").map(encodeURIComponent).join("/");
2048
1988
  }
2049
1989
  var writeCmd = defineCommand12({
2050
- meta: { name: "write", description: "Write an entry into a group's shared memory" },
1990
+ meta: { name: "write", description: "Write an entry into a team's shared memory" },
2051
1991
  args: {
2052
- group: { type: "positional", required: true, description: "Group slug" },
1992
+ team: { type: "positional", required: true, description: "Team slug" },
2053
1993
  key: { type: "positional", required: true, description: "Memory key (path under memory/)" },
2054
1994
  content: { type: "positional", required: true, description: "Content to write" }
2055
1995
  },
2056
1996
  async run({ args }) {
2057
1997
  const client = createClient2();
2058
1998
  const entry2 = await client.put(
2059
- `/api/groups/${args.group}/memory/${encodeKey(args.key)}`,
1999
+ `/api/teams/${args.team}/memory/${encodeKey(args.key)}`,
2060
2000
  { content: args.content }
2061
2001
  );
2062
2002
  console.log(`wrote ${entry2.key} (${entry2.content.length} bytes)`);
2063
2003
  }
2064
2004
  });
2065
2005
  var readCmd2 = defineCommand12({
2066
- meta: { name: "read", description: "Read an entry from a group's shared memory" },
2006
+ meta: { name: "read", description: "Read an entry from a team's shared memory" },
2067
2007
  args: {
2068
- group: { type: "positional", required: true, description: "Group slug" },
2008
+ team: { type: "positional", required: true, description: "Team slug" },
2069
2009
  key: { type: "positional", required: true }
2070
2010
  },
2071
2011
  async run({ args }) {
2072
2012
  const client = createClient2();
2073
2013
  const entry2 = await client.get(
2074
- `/api/groups/${args.group}/memory/${encodeKey(args.key)}`
2014
+ `/api/teams/${args.team}/memory/${encodeKey(args.key)}`
2075
2015
  );
2076
2016
  console.log(entry2.content);
2077
2017
  }
2078
2018
  });
2079
2019
  var searchCmd = defineCommand12({
2080
- meta: { name: "search", description: "Search a group's shared memory" },
2020
+ meta: { name: "search", description: "Search a team's shared memory" },
2081
2021
  args: {
2082
- group: { type: "positional", required: true, description: "Group slug" },
2022
+ team: { type: "positional", required: true, description: "Team slug" },
2083
2023
  query: { type: "positional", required: true },
2084
2024
  limit: { type: "string", description: "Max results (default 10)" }
2085
2025
  },
@@ -2087,7 +2027,7 @@ var searchCmd = defineCommand12({
2087
2027
  const client = createClient2();
2088
2028
  const limit = args.limit ? Number.parseInt(args.limit, 10) : 10;
2089
2029
  const params = new URLSearchParams({ q: args.query, limit: String(limit) });
2090
- const hits = await client.get(`/api/groups/${args.group}/memory/search?${params}`);
2030
+ const hits = await client.get(`/api/teams/${args.team}/memory/search?${params}`);
2091
2031
  if (hits.length === 0) {
2092
2032
  console.log("(no matches)");
2093
2033
  return;
@@ -2097,14 +2037,14 @@ var searchCmd = defineCommand12({
2097
2037
  }
2098
2038
  }
2099
2039
  });
2100
- var listCmd6 = defineCommand12({
2101
- meta: { name: "list", description: "List all entries in a group's shared memory" },
2040
+ var listCmd5 = defineCommand12({
2041
+ meta: { name: "list", description: "List all entries in a team's shared memory" },
2102
2042
  args: {
2103
- group: { type: "positional", required: true, description: "Group slug" }
2043
+ team: { type: "positional", required: true, description: "Team slug" }
2104
2044
  },
2105
2045
  async run({ args }) {
2106
2046
  const client = createClient2();
2107
- const all = await client.get(`/api/groups/${args.group}/memory`);
2047
+ const all = await client.get(`/api/teams/${args.team}/memory`);
2108
2048
  if (all.length === 0) {
2109
2049
  console.log("(no memory entries)");
2110
2050
  return;
@@ -2114,36 +2054,36 @@ var listCmd6 = defineCommand12({
2114
2054
  }
2115
2055
  }
2116
2056
  });
2117
- var rmCmd4 = defineCommand12({
2118
- meta: { name: "rm", description: "Remove an entry from a group's shared memory" },
2057
+ var rmCmd3 = defineCommand12({
2058
+ meta: { name: "rm", description: "Remove an entry from a team's shared memory" },
2119
2059
  args: {
2120
- group: { type: "positional", required: true, description: "Group slug" },
2060
+ team: { type: "positional", required: true, description: "Team slug" },
2121
2061
  key: { type: "positional", required: true }
2122
2062
  },
2123
2063
  async run({ args }) {
2124
2064
  const client = createClient2();
2125
- await client.del(`/api/groups/${args.group}/memory/${encodeKey(args.key)}`);
2065
+ await client.del(`/api/teams/${args.team}/memory/${encodeKey(args.key)}`);
2126
2066
  console.log(`removed ${args.key}`);
2127
2067
  }
2128
2068
  });
2129
2069
  var memoryCommand = defineCommand12({
2130
2070
  meta: {
2131
2071
  name: "memory",
2132
- description: "Manage a group's shared memory (BM25-indexed markdown notes)"
2072
+ description: "Manage a team's shared memory (BM25-indexed markdown notes)"
2133
2073
  },
2134
2074
  subCommands: {
2135
2075
  write: writeCmd,
2136
2076
  read: readCmd2,
2137
2077
  search: searchCmd,
2138
- list: listCmd6,
2139
- rm: rmCmd4
2078
+ list: listCmd5,
2079
+ rm: rmCmd3
2140
2080
  }
2141
2081
  });
2142
2082
 
2143
2083
  // src/commands/profile.ts
2144
2084
  import { spawn as spawn3 } from "child_process";
2145
2085
  import { randomBytes } from "crypto";
2146
- import { readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
2086
+ import { readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
2147
2087
  import { tmpdir } from "os";
2148
2088
  import { join as join3 } from "path";
2149
2089
 
@@ -2219,7 +2159,7 @@ var createCmd2 = defineCommand13({
2219
2159
  },
2220
2160
  async run({ args }) {
2221
2161
  const skillsMode = parseSkillsMode(args["skills-mode"]);
2222
- const readTemplate = (path) => path ? readFileSync5(path, "utf8") : void 0;
2162
+ const readTemplate = (path) => path ? readFileSync4(path, "utf8") : void 0;
2223
2163
  const body = {
2224
2164
  id: args.id,
2225
2165
  name: args.name,
@@ -2238,16 +2178,16 @@ var createCmd2 = defineCommand13({
2238
2178
  console.log(`created profile ${profile.id} at ${profile.dir}`);
2239
2179
  }
2240
2180
  });
2241
- var listCmd7 = defineCommand13({
2181
+ var listCmd6 = defineCommand13({
2242
2182
  meta: { name: "list", description: "List profiles" },
2243
2183
  async run() {
2244
2184
  const client = createClient2();
2245
- const list = await client.get("/api/profiles");
2246
- if (list.length === 0) {
2185
+ const list3 = await client.get("/api/profiles");
2186
+ if (list3.length === 0) {
2247
2187
  console.log("(no profiles)");
2248
2188
  return;
2249
2189
  }
2250
- const rows = list.map((p) => [p.id, p.defaultModel, p.name]);
2190
+ const rows = list3.map((p) => [p.id, p.defaultModel, p.name]);
2251
2191
  for (const line of columnize(rows)) console.log(line);
2252
2192
  }
2253
2193
  });
@@ -2306,7 +2246,7 @@ var editCmd2 = defineCommand13({
2306
2246
  child.on("close", (c) => resolve3(c ?? 0));
2307
2247
  });
2308
2248
  if (code !== 0) throw new Error(`editor exited with code ${code}`);
2309
- const updated = readFileSync5(tmpPath, "utf8");
2249
+ const updated = readFileSync4(tmpPath, "utf8");
2310
2250
  if (updated === content) {
2311
2251
  console.log("(no changes)");
2312
2252
  return;
@@ -2371,7 +2311,7 @@ var profileCommand = defineCommand13({
2371
2311
  meta: { name: "profile", description: "Manage profiles" },
2372
2312
  subCommands: {
2373
2313
  create: createCmd2,
2374
- list: listCmd7,
2314
+ list: listCmd6,
2375
2315
  show: showCmd4,
2376
2316
  edit: editCmd2,
2377
2317
  update: updateCmd,
@@ -2379,301 +2319,77 @@ var profileCommand = defineCommand13({
2379
2319
  }
2380
2320
  });
2381
2321
 
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";
2322
+ // src/commands/provider.ts
2388
2323
  import { defineCommand as defineCommand14 } from "citty";
2389
- var createCmd3 = defineCommand14({
2390
- meta: { name: "create", description: "Create a new profile group (team template)" },
2324
+ var listCmd7 = defineCommand14({
2325
+ meta: {
2326
+ name: "list",
2327
+ description: "List all providers with enabled/disabled state and curated model counts"
2328
+ },
2391
2329
  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
- }
2330
+ enabled: { type: "boolean", description: "Show only enabled providers" }
2398
2331
  },
2399
2332
  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
2333
  const client = createClient2();
2412
- const list = await client.get("/api/profile-groups");
2413
- if (list.length === 0) {
2414
- console.log("(no profile groups)");
2334
+ const { providers } = await client.get("/api/config/providers");
2335
+ const filtered = args.enabled ? providers.filter((p) => p.enabled) : providers;
2336
+ if (filtered.length === 0) {
2337
+ console.log("(no providers to show)");
2415
2338
  return;
2416
2339
  }
2417
- const rows = list.map((g) => [g.id, String(g.memberCount), g.name]);
2340
+ const rows = filtered.map((p) => [
2341
+ p.id,
2342
+ p.enabled ? "enabled" : "disabled",
2343
+ `${p.curated.length} curated`,
2344
+ `${p.catalog.length} catalog`,
2345
+ p.enabled ? "" : `(set ${p.envHint})`
2346
+ ]);
2418
2347
  for (const line of columnize(rows)) console.log(line);
2419
2348
  }
2420
2349
  });
2421
- var showCmd5 = defineCommand14({
2422
- meta: { name: "show", description: "Show profile group details + members" },
2350
+ var modelsCmd = defineCommand14({
2351
+ meta: {
2352
+ name: "models",
2353
+ description: "Show curated + catalog + live models for one provider"
2354
+ },
2423
2355
  args: {
2424
- id: { type: "positional", required: true },
2425
- json: { type: "boolean", description: "Emit full JSON (members + basics)" }
2356
+ name: { type: "positional", required: true, description: "Provider name" }
2426
2357
  },
2427
2358
  async run({ args }) {
2428
2359
  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;
2360
+ const { providers } = await client.get("/api/config/providers");
2361
+ const p = providers.find((x) => x.id === args.name);
2362
+ if (!p) {
2363
+ console.error(`unknown provider: ${args.name}`);
2364
+ process.exit(1);
2433
2365
  }
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;
2366
+ console.log(`# ${p.id} (${p.enabled ? "enabled" : "disabled"})`);
2367
+ if (!p.enabled) console.log(` (set ${p.envHint} to enable)`);
2368
+ console.log("\n## curated");
2369
+ if (p.curated.length === 0) console.log(" (none \u2014 use `provider models-set` to pin some)");
2370
+ else for (const m of p.curated) console.log(` ${m}`);
2371
+ console.log("\n## catalog (from pi-ai)");
2372
+ if (p.catalog.length === 0) console.log(" (empty)");
2373
+ else for (const m of p.catalog) console.log(` ${m}`);
2374
+ if (p.live) {
2375
+ console.log("\n## live (from upstream /v1/models)");
2376
+ if (p.live.error) console.log(` (error: ${p.live.error})`);
2377
+ else if (p.live.models.length === 0) console.log(" (empty)");
2378
+ else for (const m of p.live.models) console.log(` ${m}`);
2443
2379
  }
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
2380
  }
2457
2381
  });
2458
- var updateCmd2 = defineCommand14({
2459
- meta: { name: "update", description: "Update profile group basics (name, user-md)" },
2382
+ var modelsSetCmd = defineCommand14({
2383
+ meta: {
2384
+ name: "models-set",
2385
+ description: "Replace the curated model list for a provider (comma-separated)"
2386
+ },
2460
2387
  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)"
2388
+ name: { type: "positional", required: true, description: "Provider name" },
2389
+ models: {
2390
+ type: "positional",
2391
+ required: true,
2392
+ description: "Comma-separated model list (empty string clears the list)"
2677
2393
  }
2678
2394
  },
2679
2395
  async run({ args }) {
@@ -2688,7 +2404,7 @@ var modelsSetCmd = defineCommand15({
2688
2404
  for (const m of saved.models) console.log(` ${m}`);
2689
2405
  }
2690
2406
  });
2691
- var enableCmd2 = defineCommand15({
2407
+ var enableCmd2 = defineCommand14({
2692
2408
  meta: { name: "enable", description: "Toggle a provider on so agents can use it" },
2693
2409
  args: {
2694
2410
  name: { type: "positional", required: true, description: "Provider id (e.g. anthropic)" }
@@ -2702,7 +2418,7 @@ var enableCmd2 = defineCommand15({
2702
2418
  console.log(`${res.name}: enabled`);
2703
2419
  }
2704
2420
  });
2705
- var disableCmd2 = defineCommand15({
2421
+ var disableCmd2 = defineCommand14({
2706
2422
  meta: {
2707
2423
  name: "disable",
2708
2424
  description: "Toggle a provider off \u2014 agents will refuse its model strings"
@@ -2719,7 +2435,7 @@ var disableCmd2 = defineCommand15({
2719
2435
  console.log(`${res.name}: disabled`);
2720
2436
  }
2721
2437
  });
2722
- var testCmd2 = defineCommand15({
2438
+ var testCmd2 = defineCommand14({
2723
2439
  meta: { name: "test", description: "Send a single chat to a model and print the reply" },
2724
2440
  args: {
2725
2441
  model: {
@@ -2740,10 +2456,10 @@ var testCmd2 = defineCommand15({
2740
2456
  }
2741
2457
  }
2742
2458
  });
2743
- var providerCommand = defineCommand15({
2459
+ var providerCommand = defineCommand14({
2744
2460
  meta: { name: "provider", description: "Manage and test LLM providers" },
2745
2461
  subCommands: {
2746
- list: listCmd9,
2462
+ list: listCmd7,
2747
2463
  enable: enableCmd2,
2748
2464
  disable: disableCmd2,
2749
2465
  models: modelsCmd,
@@ -2753,8 +2469,8 @@ var providerCommand = defineCommand15({
2753
2469
  });
2754
2470
 
2755
2471
  // src/commands/send.ts
2756
- import { defineCommand as defineCommand16 } from "citty";
2757
- var sendCommand = defineCommand16({
2472
+ import { defineCommand as defineCommand15 } from "citty";
2473
+ var sendCommand = defineCommand15({
2758
2474
  meta: {
2759
2475
  name: "send",
2760
2476
  description: "Send a message from one agent to another"
@@ -2770,20 +2486,29 @@ var sendCommand = defineCommand16({
2770
2486
  from: args.from,
2771
2487
  payload: { text: args.message }
2772
2488
  };
2773
- const msg = await client.post(`/api/agents/${args.to}/messages`, body);
2774
- console.log(`sent message ${msg.id}`);
2489
+ const result = await client.post(
2490
+ `/api/agents/${args.to}/messages`,
2491
+ body
2492
+ );
2493
+ if ("approvalId" in result) {
2494
+ console.log(
2495
+ `pending approval ${result.approvalId} (expires ${new Date(result.expiresAt).toISOString()})`
2496
+ );
2497
+ return;
2498
+ }
2499
+ console.log(`sent message ${result.id}`);
2775
2500
  }
2776
2501
  });
2777
2502
 
2778
2503
  // src/commands/serve.ts
2779
- import { spawn as spawn5 } from "child_process";
2504
+ import { spawn as spawn4 } from "child_process";
2780
2505
  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");
2506
+ import { join as join4 } from "path";
2507
+ import { defineCommand as defineCommand16 } from "citty";
2508
+ var bundledDaemonEntry2 = join4(import.meta.dirname, "daemon.js");
2509
+ var sourceDaemonEntry2 = join4(import.meta.dirname, "..", "..", "..", "daemon", "src", "index.ts");
2785
2510
  var daemonEntry2 = existsSync5(bundledDaemonEntry2) ? bundledDaemonEntry2 : sourceDaemonEntry2;
2786
- var serveCommand = defineCommand17({
2511
+ var serveCommand = defineCommand16({
2787
2512
  meta: {
2788
2513
  name: "serve",
2789
2514
  description: "Start the bazilion daemon (HTTP API)"
@@ -2816,7 +2541,7 @@ var serveCommand = defineCommand17({
2816
2541
  console.log(`starting bazilion daemon at http://${host}:${port}`);
2817
2542
  console.log("(web UI runs separately: cd apps/web && pnpm dev)");
2818
2543
  const nodeArgs2 = daemonEntry2.endsWith(".ts") ? ["--import", "tsx/esm", daemonEntry2] : [daemonEntry2];
2819
- const proc = spawn5("node", nodeArgs2, {
2544
+ const proc = spawn4("node", nodeArgs2, {
2820
2545
  env,
2821
2546
  stdio: "inherit"
2822
2547
  });
@@ -2850,16 +2575,16 @@ var serveCommand = defineCommand17({
2850
2575
  });
2851
2576
 
2852
2577
  // src/commands/skill.ts
2853
- import { existsSync as existsSync6, readFileSync as readFileSync7, statSync } from "fs";
2578
+ import { existsSync as existsSync6, readFileSync as readFileSync5, statSync } from "fs";
2854
2579
  import { basename as basename2, resolve as resolve2 } from "path";
2855
- import { defineCommand as defineCommand18 } from "citty";
2580
+ import { defineCommand as defineCommand17 } from "citty";
2856
2581
  function printFindings(findings, prefix = " ") {
2857
2582
  for (const f of findings) {
2858
2583
  const line = f.line ? ` line ${f.line}` : "";
2859
2584
  console.log(`${prefix}${f.severity}: ${f.code}${line} - ${f.message}`);
2860
2585
  }
2861
2586
  }
2862
- var listCmd10 = defineCommand18({
2587
+ var listCmd8 = defineCommand17({
2863
2588
  meta: { name: "list", description: "List installed skills (or those attached to an agent)" },
2864
2589
  args: {
2865
2590
  agent: { type: "string", description: "Filter to skills attached to this agent" }
@@ -2900,7 +2625,7 @@ var listCmd10 = defineCommand18({
2900
2625
  }
2901
2626
  }
2902
2627
  });
2903
- var importCmd = defineCommand18({
2628
+ var importCmd = defineCommand17({
2904
2629
  meta: {
2905
2630
  name: "import",
2906
2631
  description: "Import skills from openclaw, a directory, or a local .zip archive"
@@ -2920,7 +2645,7 @@ var importCmd = defineCommand18({
2920
2645
  let result;
2921
2646
  try {
2922
2647
  if (isLocalZip) {
2923
- const bytes = readFileSync7(absFrom);
2648
+ const bytes = readFileSync5(absFrom);
2924
2649
  const file = new File([bytes], basename2(absFrom), { type: "application/zip" });
2925
2650
  const fd = new FormData();
2926
2651
  fd.set("file", file);
@@ -2969,7 +2694,7 @@ var importCmd = defineCommand18({
2969
2694
  }
2970
2695
  }
2971
2696
  });
2972
- var rmCmd5 = defineCommand18({
2697
+ var rmCmd4 = defineCommand17({
2973
2698
  meta: { name: "rm", description: "Remove an installed skill" },
2974
2699
  args: {
2975
2700
  name: { type: "positional", required: true }
@@ -2980,18 +2705,844 @@ var rmCmd5 = defineCommand18({
2980
2705
  console.log(`removed skill ${args.name}`);
2981
2706
  }
2982
2707
  });
2983
- var skillCommand = defineCommand18({
2708
+ var skillCommand = defineCommand17({
2984
2709
  meta: { name: "skill", description: "Manage the skill library" },
2985
2710
  subCommands: {
2986
- list: listCmd10,
2711
+ list: listCmd8,
2987
2712
  import: importCmd,
2988
- rm: rmCmd5
2713
+ rm: rmCmd4
2989
2714
  }
2990
2715
  });
2991
2716
 
2992
- // src/commands/telegram.ts
2717
+ // src/commands/team.ts
2718
+ import { readFileSync as readFileSync7 } from "fs";
2719
+ import { stdin as stdin2 } from "process";
2993
2720
  import { defineCommand as defineCommand19 } from "citty";
2994
- var setCmd2 = defineCommand19({
2721
+
2722
+ // src/commands/team-policy.ts
2723
+ import { readFileSync as readFileSync6 } from "fs";
2724
+ import { defineCommand as defineCommand18 } from "citty";
2725
+
2726
+ // src/team-interchange.ts
2727
+ var TEAM_POLICY_INTERCHANGE_VERSION = 1;
2728
+ var TEAM_DOCUMENT_KIND = "bazilion.team-template";
2729
+ var TEAM_POLICY_DOCUMENT_KIND = "bazilion.team-policy";
2730
+ var reasoning = /* @__PURE__ */ new Set(["off", "minimal", "low", "medium", "high", "xhigh"]);
2731
+ var templateKinds = /* @__PURE__ */ new Set(["user", "outside_team", "slot"]);
2732
+ var liveKinds = /* @__PURE__ */ new Set(["user", "outside_team", "agent"]);
2733
+ function object(value, label) {
2734
+ if (!value || typeof value !== "object" || Array.isArray(value))
2735
+ throw new Error(`${label} must be an object`);
2736
+ return value;
2737
+ }
2738
+ function text(value, label) {
2739
+ if (typeof value !== "string" || !value.trim()) throw new Error(`${label} is required`);
2740
+ return value.trim();
2741
+ }
2742
+ function nullableText(value, label) {
2743
+ if (value === null || value === void 0) return null;
2744
+ if (typeof value !== "string") throw new Error(`${label} must be a string or null`);
2745
+ return value;
2746
+ }
2747
+ function endpointKey(kind, key) {
2748
+ return `${kind}:${key ?? "-"}`;
2749
+ }
2750
+ function exportTeamDocument(detail) {
2751
+ const keyById = new Map(detail.slots.map((slot, index) => [slot.slotId, `slot-${index + 1}`]));
2752
+ return {
2753
+ version: TEAM_POLICY_INTERCHANGE_VERSION,
2754
+ kind: TEAM_DOCUMENT_KIND,
2755
+ template: {
2756
+ id: detail.template.id,
2757
+ name: detail.template.name,
2758
+ userMd: detail.template.userMd
2759
+ },
2760
+ slots: detail.slots.map((slot) => ({
2761
+ key: keyById.get(slot.slotId),
2762
+ profileId: slot.profileId,
2763
+ agentName: slot.agentName,
2764
+ modelOverride: slot.modelOverride,
2765
+ reasoningLevel: slot.reasoningLevel,
2766
+ layoutPosition: slot.layoutPosition,
2767
+ display: slot.display
2768
+ })),
2769
+ edges: detail.edges.map((edge) => ({
2770
+ sourceKind: edge.sourceKind,
2771
+ sourceKey: edge.sourceKind === "slot" ? keyById.get(edge.sourceId ?? "") ?? null : null,
2772
+ targetKind: edge.targetKind,
2773
+ targetKey: edge.targetKind === "slot" ? keyById.get(edge.targetId ?? "") ?? null : null,
2774
+ posture: edge.posture
2775
+ }))
2776
+ };
2777
+ }
2778
+ function parseTeamDocument(value) {
2779
+ const root = object(value, "document");
2780
+ if (root.version !== TEAM_POLICY_INTERCHANGE_VERSION)
2781
+ throw new Error(`unsupported Team Policy document version: ${String(root.version)}`);
2782
+ if (root.kind !== TEAM_DOCUMENT_KIND)
2783
+ throw new Error(`invalid document kind: expected ${TEAM_DOCUMENT_KIND}`);
2784
+ const meta = object(root.template, "template");
2785
+ const rawSlots = Array.isArray(root.slots) ? root.slots : null;
2786
+ const rawEdges = Array.isArray(root.edges) ? root.edges : null;
2787
+ if (!rawSlots || !rawEdges) throw new Error("slots and edges must be arrays");
2788
+ const keys = /* @__PURE__ */ new Set();
2789
+ const slots = rawSlots.map((raw, index) => {
2790
+ const slot = object(raw, `slot ${index}`);
2791
+ const key = text(slot.key, `slot ${index} key`);
2792
+ if (keys.has(key)) throw new Error(`duplicate slot key: ${key}`);
2793
+ keys.add(key);
2794
+ const level = slot.reasoningLevel;
2795
+ if (level !== null && level !== void 0 && !reasoning.has(level))
2796
+ throw new Error(`slot ${index} has invalid reasoningLevel`);
2797
+ const position = slot.layoutPosition;
2798
+ if (position !== null && position !== void 0 && (!position || typeof position !== "object" || Array.isArray(position) || !Number.isFinite(position.x) || !Number.isFinite(position.y)))
2799
+ throw new Error(`slot ${index} has invalid layoutPosition`);
2800
+ const display = slot.display;
2801
+ if (display !== null && display !== void 0 && (!display || typeof display !== "object" || Array.isArray(display)))
2802
+ throw new Error(`slot ${index} has invalid display`);
2803
+ return {
2804
+ key,
2805
+ profileId: text(slot.profileId, `slot ${index} profileId`),
2806
+ agentName: text(slot.agentName, `slot ${index} agentName`),
2807
+ modelOverride: nullableText(slot.modelOverride, `slot ${index} modelOverride`),
2808
+ reasoningLevel: level ?? null,
2809
+ layoutPosition: position ?? null,
2810
+ display: display ?? null
2811
+ };
2812
+ });
2813
+ const seen = /* @__PURE__ */ new Set();
2814
+ const edges = rawEdges.map((raw, index) => {
2815
+ const edge = object(raw, `edge ${index}`);
2816
+ if (!templateKinds.has(String(edge.sourceKind)) || !templateKinds.has(String(edge.targetKind)))
2817
+ throw new Error(`edge ${index} has invalid endpoint kind`);
2818
+ const sourceKind = edge.sourceKind;
2819
+ const targetKind = edge.targetKind;
2820
+ const sourceKey = nullableText(edge.sourceKey, `edge ${index} sourceKey`);
2821
+ const targetKey = nullableText(edge.targetKey, `edge ${index} targetKey`);
2822
+ const posture = edge.posture === void 0 || edge.posture === "allow" ? "allow" : edge.posture === "approval_required" ? "approval_required" : null;
2823
+ if (!posture) throw new Error(`edge ${index} has invalid posture`);
2824
+ if (sourceKind === "slot" !== Boolean(sourceKey))
2825
+ throw new Error(`edge ${index} source slot key is missing or invalid`);
2826
+ if (targetKind === "slot" !== Boolean(targetKey))
2827
+ throw new Error(`edge ${index} target slot key is missing or invalid`);
2828
+ if (sourceKey && !keys.has(sourceKey))
2829
+ throw new Error(`edge ${index} references missing slot ${sourceKey}`);
2830
+ if (targetKey && !keys.has(targetKey))
2831
+ throw new Error(`edge ${index} references missing slot ${targetKey}`);
2832
+ const signature = `${endpointKey(sourceKind, sourceKey)}->${endpointKey(targetKind, targetKey)}`;
2833
+ if (endpointKey(sourceKind, sourceKey) === endpointKey(targetKind, targetKey))
2834
+ throw new Error(`edge ${index} is a self edge`);
2835
+ if (seen.has(signature)) throw new Error(`duplicate edge: ${signature}`);
2836
+ seen.add(signature);
2837
+ return { sourceKind, sourceKey, targetKind, targetKey, posture };
2838
+ });
2839
+ return {
2840
+ version: 1,
2841
+ kind: TEAM_DOCUMENT_KIND,
2842
+ template: {
2843
+ id: text(meta.id, "template id"),
2844
+ name: text(meta.name, "template name"),
2845
+ userMd: nullableText(meta.userMd, "template userMd")
2846
+ },
2847
+ slots,
2848
+ edges
2849
+ };
2850
+ }
2851
+ function teamImportBody(document, existing) {
2852
+ const currentByKey = existing ? new Map(existing.slots.map((slot, index) => [`slot-${index + 1}`, slot.slotId])) : /* @__PURE__ */ new Map();
2853
+ const slots = document.slots.map((slot) => ({
2854
+ ...currentByKey.has(slot.key) ? { slotId: currentByKey.get(slot.key) } : { clientKey: slot.key },
2855
+ profileId: slot.profileId,
2856
+ agentName: slot.agentName,
2857
+ modelOverride: slot.modelOverride,
2858
+ reasoningLevel: slot.reasoningLevel,
2859
+ layoutPosition: slot.layoutPosition,
2860
+ display: slot.display
2861
+ }));
2862
+ const idByKey = new Map(
2863
+ slots.map((slot, index) => [
2864
+ document.slots[index]?.key,
2865
+ slot.slotId ?? slot.clientKey ?? null
2866
+ ])
2867
+ );
2868
+ const edges = document.edges.map((edge) => ({
2869
+ sourceKind: edge.sourceKind,
2870
+ sourceId: edge.sourceKind === "slot" ? idByKey.get(edge.sourceKey ?? "") : null,
2871
+ targetKind: edge.targetKind,
2872
+ targetId: edge.targetKind === "slot" ? idByKey.get(edge.targetKey ?? "") : null,
2873
+ posture: edge.posture
2874
+ }));
2875
+ return { slots, edges };
2876
+ }
2877
+ function parseTeamPolicyDocument(value) {
2878
+ const root = object(value, "document");
2879
+ if (root.version !== 1)
2880
+ throw new Error(`unsupported Team Policy document version: ${String(root.version)}`);
2881
+ if (root.kind !== TEAM_POLICY_DOCUMENT_KIND)
2882
+ throw new Error(`invalid document kind: expected ${TEAM_POLICY_DOCUMENT_KIND}`);
2883
+ if (!Number.isInteger(root.expectedRevision) || Number(root.expectedRevision) < 1)
2884
+ throw new Error("expectedRevision must be a positive integer");
2885
+ if (!Array.isArray(root.edges)) throw new Error("edges must be an array");
2886
+ const seen = /* @__PURE__ */ new Set();
2887
+ const edges = root.edges.map((raw, index) => {
2888
+ const edge = object(raw, `edge ${index}`);
2889
+ if (!liveKinds.has(String(edge.sourceKind)) || !liveKinds.has(String(edge.targetKind)))
2890
+ throw new Error(`edge ${index} has invalid endpoint kind`);
2891
+ const sourceKind = edge.sourceKind;
2892
+ const targetKind = edge.targetKind;
2893
+ const sourceId = nullableText(edge.sourceId, `edge ${index} sourceId`);
2894
+ const targetId = nullableText(edge.targetId, `edge ${index} targetId`);
2895
+ if (sourceKind === "agent" !== Boolean(sourceId) || targetKind === "agent" !== Boolean(targetId))
2896
+ throw new Error(`edge ${index} Agent id is missing or invalid`);
2897
+ const signature = `${endpointKey(sourceKind, sourceId)}->${endpointKey(targetKind, targetId)}`;
2898
+ if (endpointKey(sourceKind, sourceId) === endpointKey(targetKind, targetId))
2899
+ throw new Error(`edge ${index} is a self edge`);
2900
+ if (seen.has(signature)) throw new Error(`duplicate edge: ${signature}`);
2901
+ seen.add(signature);
2902
+ return { sourceKind, sourceId, targetKind, targetId };
2903
+ });
2904
+ return {
2905
+ version: 1,
2906
+ kind: TEAM_POLICY_DOCUMENT_KIND,
2907
+ teamId: text(root.teamId, "teamId"),
2908
+ expectedRevision: Number(root.expectedRevision),
2909
+ edges
2910
+ };
2911
+ }
2912
+ function exportTeamPolicy(teamId, revision, edges) {
2913
+ return {
2914
+ version: 1,
2915
+ kind: TEAM_POLICY_DOCUMENT_KIND,
2916
+ teamId,
2917
+ expectedRevision: revision,
2918
+ edges: edges.map(({ sourceKind, sourceId, targetKind, targetId, posture }) => ({
2919
+ sourceKind,
2920
+ sourceId,
2921
+ targetKind,
2922
+ targetId,
2923
+ posture
2924
+ }))
2925
+ };
2926
+ }
2927
+ function edgeDiff(before, after) {
2928
+ const signature = (edge) => `${endpointKey(edge.sourceKind, edge.sourceId ?? null)} -> ${endpointKey(edge.targetKind, edge.targetId ?? null)} [${edge.posture ?? "allow"}]`;
2929
+ const left = new Set(before.map(signature));
2930
+ const right = new Set(after.map(signature));
2931
+ return {
2932
+ added: [...right].filter((value) => !left.has(value)).sort(),
2933
+ removed: [...left].filter((value) => !right.has(value)).sort()
2934
+ };
2935
+ }
2936
+
2937
+ // src/commands/team-policy.ts
2938
+ function readJson(path) {
2939
+ try {
2940
+ return JSON.parse(readFileSync6(path, "utf8"));
2941
+ } catch (error) {
2942
+ throw new Error(`invalid JSON: ${error.message}`);
2943
+ }
2944
+ }
2945
+ function endpoint2(value, teamId) {
2946
+ if (value === "user") return { kind: "user", teamId };
2947
+ if (value.startsWith("agent:") && value.length > 6) return { kind: "agent", id: value.slice(6) };
2948
+ if (value.startsWith("outside:") && value.length > 8)
2949
+ return { kind: "outside_team", teamId: value.slice(8) };
2950
+ throw new Error("endpoint must be user, agent:<id>, or outside:<team-id>");
2951
+ }
2952
+ function printPolicy(detail) {
2953
+ console.log(`# Team ${detail.teamPolicy.teamId} policy`);
2954
+ console.log(`revision: ${detail.teamPolicy.revision}`);
2955
+ console.log(
2956
+ `baseline: ${detail.baseline ? `${detail.baseline.templateId}@${detail.baseline.templateRevision}` : "(none)"}`
2957
+ );
2958
+ console.log(`members: ${detail.members.length}`);
2959
+ console.log(`edges: ${detail.edges.length}`);
2960
+ if (detail.edges.length) {
2961
+ console.log("");
2962
+ for (const line of columnize([
2963
+ ["source", "target"],
2964
+ ...detail.edges.map((edge) => [
2965
+ `${edge.sourceKind}:${edge.sourceId ?? "-"}`,
2966
+ `${edge.targetKind}:${edge.targetId ?? "-"}`
2967
+ ])
2968
+ ]))
2969
+ console.log(line);
2970
+ }
2971
+ }
2972
+ var show2 = defineCommand18({
2973
+ meta: { name: "show", description: "Show the one effective live policy for a Team" },
2974
+ args: {
2975
+ team: { type: "positional", required: true },
2976
+ json: { type: "boolean", description: "Emit the canonical aggregate as JSON" }
2977
+ },
2978
+ async run({ args }) {
2979
+ const detail = await createClient2().get(
2980
+ `/api/teams/${encodeURIComponent(args.team)}/policy`
2981
+ );
2982
+ if (args.json) console.log(JSON.stringify(detail, null, 2));
2983
+ else printPolicy(detail);
2984
+ }
2985
+ });
2986
+ var exportCommand = defineCommand18({
2987
+ meta: { name: "export", description: "Export a revisioned Team policy document" },
2988
+ args: { team: { type: "positional", required: true } },
2989
+ async run({ args }) {
2990
+ const detail = await createClient2().get(
2991
+ `/api/teams/${encodeURIComponent(args.team)}/policy`
2992
+ );
2993
+ console.log(
2994
+ JSON.stringify(
2995
+ exportTeamPolicy(args.team, detail.teamPolicy.revision, detail.edges),
2996
+ null,
2997
+ 2
2998
+ )
2999
+ );
3000
+ }
3001
+ });
3002
+ function printEdgeDiff(current, edges) {
3003
+ const diff2 = edgeDiff(current.edges, edges);
3004
+ console.log(`Team: ${current.teamPolicy.teamId}`);
3005
+ console.log(`Revision: ${current.teamPolicy.revision}`);
3006
+ console.log(`Edges: +${diff2.added.length} -${diff2.removed.length}`);
3007
+ for (const value of diff2.added) console.log(` + ${value}`);
3008
+ for (const value of diff2.removed) console.log(` - ${value}`);
3009
+ }
3010
+ var importCommand = defineCommand18({
3011
+ meta: {
3012
+ name: "import",
3013
+ description: "Validate, diff, and explicitly replace a Team policy"
3014
+ },
3015
+ args: {
3016
+ team: { type: "positional", required: true },
3017
+ file: { type: "positional", required: true },
3018
+ "dry-run": { type: "boolean", description: "Validate and print the diff only" },
3019
+ apply: { type: "boolean", description: "Apply non-interactively after printing the diff" },
3020
+ "expected-revision": {
3021
+ type: "string",
3022
+ description: "Expected current Team revision (defaults to document revision)"
3023
+ },
3024
+ force: {
3025
+ type: "boolean",
3026
+ description: "Refetch current revision; requires --apply and still uses optimistic locking"
3027
+ },
3028
+ "confirm-current-revision": {
3029
+ type: "string",
3030
+ description: "Second force confirmation: the freshly displayed current revision"
3031
+ }
3032
+ },
3033
+ async run({ args }) {
3034
+ if (args.force && !args.apply)
3035
+ throw new Error("--force requires --apply (interactive force is intentionally unsupported)");
3036
+ const document = parseTeamPolicyDocument(readJson(args.file));
3037
+ if (document.teamId !== args.team)
3038
+ throw new Error(`document belongs to Team ${document.teamId}, not ${args.team}`);
3039
+ const client = createClient2();
3040
+ const current = await client.get(
3041
+ `/api/teams/${encodeURIComponent(args.team)}/policy`
3042
+ );
3043
+ printEdgeDiff(current, document.edges);
3044
+ if (args["dry-run"]) return console.log("valid: no changes applied");
3045
+ if (!args.apply) throw new Error("refusing mutation: review the diff, then pass --apply");
3046
+ const supplied = args["expected-revision"] ? Number.parseInt(args["expected-revision"], 10) : document.expectedRevision;
3047
+ const expectedRevision = args.force ? current.teamPolicy.revision : supplied;
3048
+ if (args.force && Number.parseInt(args["confirm-current-revision"] ?? "", 10) !== current.teamPolicy.revision)
3049
+ throw new Error(
3050
+ `--force requires --confirm-current-revision ${current.teamPolicy.revision} after reviewing the fresh diff`
3051
+ );
3052
+ if (!Number.isInteger(expectedRevision) || expectedRevision < 1)
3053
+ throw new Error("expected revision must be a positive integer");
3054
+ const body = {
3055
+ expectedRevision,
3056
+ edges: document.edges
3057
+ };
3058
+ const updated = await client.put(
3059
+ `/api/teams/${encodeURIComponent(args.team)}/policy`,
3060
+ body
3061
+ );
3062
+ console.log(`updated Team ${args.team} policy to revision ${updated.teamPolicy.revision}`);
3063
+ }
3064
+ });
3065
+ var diff = defineCommand18({
3066
+ meta: { name: "diff", description: "Compare live policy with its retained baseline source" },
3067
+ args: {
3068
+ team: { type: "positional", required: true },
3069
+ json: { type: "boolean", description: "Emit canonical diff JSON" }
3070
+ },
3071
+ async run({ args }) {
3072
+ const result = await createClient2().get(
3073
+ `/api/teams/${encodeURIComponent(args.team)}/policy/diff`
3074
+ );
3075
+ if (args.json) return console.log(JSON.stringify(result, null, 2));
3076
+ console.log(`# Team ${args.team} source diff`);
3077
+ console.log(
3078
+ `status: ${result.baseline ? result.sourceDiverged ? "source diverged" : "source current" : "no baseline"}`
3079
+ );
3080
+ console.log(`revision: ${result.liveRevision}`);
3081
+ console.log(
3082
+ `edges: +${result.comparison.addedSinceBaseline.length} -${result.comparison.removedSinceBaseline.length}`
3083
+ );
3084
+ console.log(
3085
+ `slots: +${result.comparison.currentSourceAddedSlotIds.length} -${result.comparison.currentSourceRemovedSlotIds.length}`
3086
+ );
3087
+ }
3088
+ });
3089
+ var evaluate = defineCommand18({
3090
+ meta: {
3091
+ name: "evaluate",
3092
+ description: "Evaluate a communication path without sending or recording a block"
3093
+ },
3094
+ args: {
3095
+ team: { type: "positional", required: true, description: "Owning Team for context" },
3096
+ source: { type: "string", required: true, description: "user | agent:<id> | outside:<team>" },
3097
+ target: { type: "string", required: true, description: "user | agent:<id> | outside:<team>" },
3098
+ origin: { type: "string", default: "cli-diagnostic" },
3099
+ json: { type: "boolean", description: "Emit decision JSON" }
3100
+ },
3101
+ async run({ args }) {
3102
+ const result = await createClient2().post(
3103
+ "/api/communication/evaluate",
3104
+ {
3105
+ source: endpoint2(args.source, args.team),
3106
+ target: endpoint2(args.target, args.team),
3107
+ origin: args.origin,
3108
+ attemptKind: "cli_evaluate",
3109
+ attemptId: `diagnostic:${args.team}`
3110
+ }
3111
+ );
3112
+ if (args.json) return console.log(JSON.stringify(result, null, 2));
3113
+ console.log(`${result.decision.toUpperCase()} ${result.channel}: ${result.reasonCode}`);
3114
+ console.log(result.reason);
3115
+ console.log(
3116
+ `policy revisions: ${result.policyRefs.map((ref) => `${ref.teamId}@${ref.revision}`).join(", ") || "-"}`
3117
+ );
3118
+ }
3119
+ });
3120
+ var blocks = defineCommand18({
3121
+ meta: { name: "blocks", description: "List paginated durable communication denials" },
3122
+ args: {
3123
+ team: { type: "positional", required: true },
3124
+ limit: { type: "string", default: "50" },
3125
+ cursor: { type: "string" },
3126
+ source: { type: "string" },
3127
+ target: { type: "string" },
3128
+ channel: { type: "string" },
3129
+ origin: { type: "string" },
3130
+ reason: { type: "string", description: "Reason code" },
3131
+ from: { type: "string", description: "Epoch milliseconds or ISO timestamp" },
3132
+ to: { type: "string", description: "Epoch milliseconds or ISO timestamp" },
3133
+ json: { type: "boolean", description: "Emit page JSON including nextCursor" }
3134
+ },
3135
+ async run({ args }) {
3136
+ const query = new URLSearchParams({ limit: args.limit });
3137
+ for (const [key, value] of [
3138
+ ["cursor", args.cursor],
3139
+ ["source", args.source],
3140
+ ["target", args.target],
3141
+ ["channel", args.channel],
3142
+ ["origin", args.origin],
3143
+ ["reasonCode", args.reason],
3144
+ ["from", args.from],
3145
+ ["to", args.to]
3146
+ ])
3147
+ if (value) query.set(key, value);
3148
+ const page = await createClient2().get(
3149
+ `/api/teams/${encodeURIComponent(args.team)}/policy/blocks?${query}`
3150
+ );
3151
+ if (args.json) return console.log(JSON.stringify(page, null, 2));
3152
+ if (!page.blocks.length) console.log("(no blocks)");
3153
+ else
3154
+ for (const line of columnize([
3155
+ ["time", "source", "target", "channel", "origin", "reason"],
3156
+ ...page.blocks.map((block) => [
3157
+ new Date(block.created_at).toISOString(),
3158
+ `${block.source_kind}:${block.source_id ?? "-"}`,
3159
+ `${block.target_kind}:${block.target_id ?? "-"}`,
3160
+ block.channel,
3161
+ block.origin,
3162
+ block.reason_code
3163
+ ])
3164
+ ]))
3165
+ console.log(line);
3166
+ if (page.nextCursor) console.log(`next cursor: ${page.nextCursor}`);
3167
+ }
3168
+ });
3169
+ var teamPolicyCommand = defineCommand18({
3170
+ meta: { name: "policy", description: "Inspect and manage the Team-owned live policy" },
3171
+ subCommands: {
3172
+ show: show2,
3173
+ export: exportCommand,
3174
+ import: importCommand,
3175
+ diff,
3176
+ evaluate,
3177
+ blocks
3178
+ }
3179
+ });
3180
+
3181
+ // src/commands/team.ts
3182
+ var addCmd2 = defineCommand19({
3183
+ meta: {
3184
+ name: "add",
3185
+ description: "Register a team at ~/.bazilion/teams/<slug>/ (use --link to point at an existing tree)"
3186
+ },
3187
+ args: {
3188
+ id: { type: "positional", required: true, description: "Team slug" },
3189
+ name: { type: "string", description: "Display name (defaults to slug)" },
3190
+ link: {
3191
+ type: "string",
3192
+ description: "Absolute path of an existing directory; the team slot becomes a symlink to it"
3193
+ }
3194
+ },
3195
+ async run({ args }) {
3196
+ const client = createClient2();
3197
+ const body = {
3198
+ id: args.id,
3199
+ ...args.name ? { name: args.name } : {},
3200
+ ...args.link ? { link: args.link } : {}
3201
+ };
3202
+ const g = await client.post("/api/teams", body);
3203
+ console.log(`registered team ${g.id} at ${g.path}`);
3204
+ }
3205
+ });
3206
+ var listCmd9 = defineCommand19({
3207
+ meta: { name: "list", description: "List teams" },
3208
+ async run() {
3209
+ const client = createClient2();
3210
+ const list3 = await client.get("/api/teams");
3211
+ if (list3.length === 0) {
3212
+ console.log("(no teams)");
3213
+ return;
3214
+ }
3215
+ const rows = list3.map((g) => [g.id, g.path]);
3216
+ for (const line of columnize(rows)) console.log(line);
3217
+ }
3218
+ });
3219
+ var rmCmd5 = defineCommand19({
3220
+ meta: { name: "rm", description: "Remove a team registration" },
3221
+ args: {
3222
+ id: { type: "positional", required: true }
3223
+ },
3224
+ async run({ args }) {
3225
+ const client = createClient2();
3226
+ const policy = await client.get(
3227
+ `/api/teams/${encodeURIComponent(args.id)}/policy`
3228
+ );
3229
+ await client.del(
3230
+ `/api/teams/${encodeURIComponent(args.id)}?expectedTeamPolicyRevision=${policy.teamPolicy.revision}`
3231
+ );
3232
+ console.log(`removed team ${args.id}`);
3233
+ }
3234
+ });
3235
+ async function readStdin() {
3236
+ const chunks = [];
3237
+ for await (const chunk of stdin2) chunks.push(chunk);
3238
+ return Buffer.concat(chunks).toString("utf8");
3239
+ }
3240
+ var userMdShowCmd = defineCommand19({
3241
+ meta: { name: "show", description: "Print the team's USER.md" },
3242
+ args: { id: { type: "positional", required: true } },
3243
+ async run({ args }) {
3244
+ const client = createClient2();
3245
+ const g = await client.get(`/api/teams/${args.id}`);
3246
+ process.stdout.write(g.userMd);
3247
+ if (g.userMd && !g.userMd.endsWith("\n")) process.stdout.write("\n");
3248
+ }
3249
+ });
3250
+ var userMdSetCmd = defineCommand19({
3251
+ meta: {
3252
+ name: "set",
3253
+ description: "Replace the team's USER.md (from --file, --from-stdin, or inline text)"
3254
+ },
3255
+ args: {
3256
+ id: { type: "positional", required: true },
3257
+ file: { type: "string", description: "Read content from a file path" },
3258
+ "from-stdin": { type: "boolean", description: "Read content from stdin" },
3259
+ text: { type: "string", description: "Inline content" }
3260
+ },
3261
+ async run({ args }) {
3262
+ let content;
3263
+ if (args["from-stdin"]) content = await readStdin();
3264
+ else if (args.file) content = readFileSync7(args.file, "utf8");
3265
+ else if (args.text !== void 0) content = args.text;
3266
+ else {
3267
+ console.error("team user-md set: provide --file, --from-stdin, or --text");
3268
+ process.exit(2);
3269
+ }
3270
+ const client = createClient2();
3271
+ const body = { userMd: content };
3272
+ await client.put(`/api/teams/${args.id}/user-md`, body);
3273
+ console.log(`updated USER.md for team ${args.id} (${content.length} bytes)`);
3274
+ }
3275
+ });
3276
+ var userMdClearCmd = defineCommand19({
3277
+ meta: { name: "clear", description: "Clear the team's USER.md to empty" },
3278
+ args: { id: { type: "positional", required: true } },
3279
+ async run({ args }) {
3280
+ const client = createClient2();
3281
+ const body = { userMd: "" };
3282
+ await client.put(`/api/teams/${args.id}/user-md`, body);
3283
+ console.log(`cleared USER.md for team ${args.id}`);
3284
+ }
3285
+ });
3286
+ var userMdCmd = defineCommand19({
3287
+ meta: { name: "user-md", description: "View or edit a team's USER.md" },
3288
+ subCommands: {
3289
+ show: userMdShowCmd,
3290
+ set: userMdSetCmd,
3291
+ clear: userMdClearCmd
3292
+ }
3293
+ });
3294
+ var topicFormatShowCmd = defineCommand19({
3295
+ meta: { name: "show", description: "Print the team's Telegram topic-name template" },
3296
+ args: { id: { type: "positional", required: true } },
3297
+ async run({ args }) {
3298
+ const client = createClient2();
3299
+ const g = await client.get(`/api/teams/${args.id}`);
3300
+ console.log(g.telegramTopicNameFormat ?? "(default naming)");
3301
+ }
3302
+ });
3303
+ var topicFormatSetCmd = defineCommand19({
3304
+ meta: {
3305
+ name: "set",
3306
+ description: "Set the topic-name template. Tokens: {agent.name} {team.name} {team.slug} (must include {agent.name})"
3307
+ },
3308
+ args: {
3309
+ id: { type: "positional", required: true },
3310
+ format: {
3311
+ type: "positional",
3312
+ required: true,
3313
+ description: 'e.g. "{team.name} / {agent.name}"'
3314
+ }
3315
+ },
3316
+ async run({ args }) {
3317
+ const client = createClient2();
3318
+ const body = { format: args.format };
3319
+ const g = await client.put(`/api/teams/${args.id}/topic-format`, body);
3320
+ console.log(`set topic-name template for team ${args.id}: ${g.telegramTopicNameFormat}`);
3321
+ }
3322
+ });
3323
+ var topicFormatClearCmd = defineCommand19({
3324
+ meta: { name: "clear", description: "Clear the template (revert to built-in naming)" },
3325
+ args: { id: { type: "positional", required: true } },
3326
+ async run({ args }) {
3327
+ const client = createClient2();
3328
+ const body = { format: null };
3329
+ await client.put(`/api/teams/${args.id}/topic-format`, body);
3330
+ console.log(`cleared topic-name template for team ${args.id}`);
3331
+ }
3332
+ });
3333
+ var topicFormatCmd = defineCommand19({
3334
+ meta: {
3335
+ name: "topic-format",
3336
+ description: "View or edit a team's Telegram forum-topic name template"
3337
+ },
3338
+ subCommands: {
3339
+ show: topicFormatShowCmd,
3340
+ set: topicFormatSetCmd,
3341
+ clear: topicFormatClearCmd
3342
+ }
3343
+ });
3344
+ var teamCommand = defineCommand19({
3345
+ meta: { name: "team", description: "Manage teams (collaboration contexts)" },
3346
+ subCommands: {
3347
+ add: addCmd2,
3348
+ list: listCmd9,
3349
+ rm: rmCmd5,
3350
+ "user-md": userMdCmd,
3351
+ "topic-format": topicFormatCmd,
3352
+ policy: teamPolicyCommand
3353
+ }
3354
+ });
3355
+
3356
+ // src/commands/team-template.ts
3357
+ import { readFileSync as readFileSync8 } from "fs";
3358
+ import { defineCommand as defineCommand20 } from "citty";
3359
+ function jsonFile(path) {
3360
+ try {
3361
+ return JSON.parse(readFileSync8(path, "utf8"));
3362
+ } catch (error) {
3363
+ throw new Error(`invalid JSON: ${error.message}`);
3364
+ }
3365
+ }
3366
+ function printTeam(detail) {
3367
+ console.log(`# ${detail.template.id} \u2014 ${detail.template.name}`);
3368
+ console.log(`revision: ${detail.template.currentRevision}`);
3369
+ console.log(`slots: ${detail.slots.length}`);
3370
+ console.log(`edges: ${detail.edges.length}`);
3371
+ if (detail.slots.length) {
3372
+ console.log("");
3373
+ for (const line of columnize([
3374
+ ["slot", "profile", "Agent name", "model", "reasoning"],
3375
+ ...detail.slots.map((slot, index) => [
3376
+ String(index + 1),
3377
+ slot.profileId,
3378
+ slot.agentName,
3379
+ slot.modelOverride ?? "-",
3380
+ slot.reasoningLevel ?? "-"
3381
+ ])
3382
+ ]))
3383
+ console.log(line);
3384
+ }
3385
+ }
3386
+ var list2 = defineCommand20({
3387
+ meta: { name: "list", description: "List canonical Team templates" },
3388
+ args: { json: { type: "boolean", description: "Emit stable JSON" } },
3389
+ async run({ args }) {
3390
+ const rows = await createClient2().get("/api/team-templates");
3391
+ if (args.json) return console.log(JSON.stringify(rows, null, 2));
3392
+ if (!rows.length) return console.log("(no Team templates)");
3393
+ for (const line of columnize([
3394
+ ["id", "revision", "slots", "name"],
3395
+ ...rows.map((row) => [row.id, String(row.currentRevision), String(row.slotCount), row.name])
3396
+ ]))
3397
+ console.log(line);
3398
+ }
3399
+ });
3400
+ var show3 = defineCommand20({
3401
+ meta: { name: "show", description: "Show a canonical Team template" },
3402
+ args: {
3403
+ id: { type: "positional", required: true },
3404
+ json: { type: "boolean", description: "Emit the canonical API aggregate" }
3405
+ },
3406
+ async run({ args }) {
3407
+ const detail = await createClient2().get(
3408
+ `/api/team-templates/${encodeURIComponent(args.id)}`
3409
+ );
3410
+ if (args.json) console.log(JSON.stringify(detail, null, 2));
3411
+ else printTeam(detail);
3412
+ }
3413
+ });
3414
+ var exportCommand2 = defineCommand20({
3415
+ meta: {
3416
+ name: "export",
3417
+ description: "Export a portable versioned Team-template document to stdout"
3418
+ },
3419
+ args: { id: { type: "positional", required: true } },
3420
+ async run({ args }) {
3421
+ const detail = await createClient2().get(
3422
+ `/api/team-templates/${encodeURIComponent(args.id)}`
3423
+ );
3424
+ console.log(JSON.stringify(exportTeamDocument(detail), null, 2));
3425
+ }
3426
+ });
3427
+ function printImportDiff(current, document) {
3428
+ const before = current ? exportTeamDocument(current) : null;
3429
+ console.log(`Team: ${current ? current.template.id : "(new)"} -> ${document.template.id}`);
3430
+ console.log(`Roster: ${current?.slots.length ?? 0} -> ${document.slots.length}`);
3431
+ const previousSlots = new Map(before?.slots.map((slot) => [slot.key, slot]) ?? []);
3432
+ const nextSlots = new Map(document.slots.map((slot) => [slot.key, slot]));
3433
+ for (const [key, slot] of nextSlots) {
3434
+ const previous = previousSlots.get(key);
3435
+ if (!previous) console.log(` + ${key}: ${slot.profileId} / ${slot.agentName}`);
3436
+ else if (JSON.stringify(previous) !== JSON.stringify(slot))
3437
+ console.log(
3438
+ ` ~ ${key}: ${previous.profileId} / ${previous.agentName} -> ${slot.profileId} / ${slot.agentName}`
3439
+ );
3440
+ }
3441
+ for (const [key, slot] of previousSlots)
3442
+ if (!nextSlots.has(key)) console.log(` - ${key}: ${slot.profileId} / ${slot.agentName}`);
3443
+ const toEdge = (edge) => ({
3444
+ sourceKind: edge.sourceKind,
3445
+ sourceId: edge.sourceKey,
3446
+ targetKind: edge.targetKind,
3447
+ targetId: edge.targetKey
3448
+ });
3449
+ const diff2 = edgeDiff(before?.edges.map(toEdge) ?? [], document.edges.map(toEdge));
3450
+ console.log(`Edges: +${diff2.added.length} -${diff2.removed.length}`);
3451
+ for (const value of diff2.added) console.log(` + ${value}`);
3452
+ for (const value of diff2.removed) console.log(` - ${value}`);
3453
+ }
3454
+ var importCommand2 = defineCommand20({
3455
+ meta: {
3456
+ name: "import",
3457
+ description: "Validate, diff, and explicitly apply a portable Team-template document"
3458
+ },
3459
+ args: {
3460
+ file: { type: "positional", required: true, description: "JSON document path" },
3461
+ "dry-run": { type: "boolean", description: "Validate and print the resolved diff only" },
3462
+ apply: { type: "boolean", description: "Apply non-interactively after printing the diff" },
3463
+ "expected-revision": {
3464
+ type: "string",
3465
+ description: "Required current revision when replacing an existing Team"
3466
+ },
3467
+ force: {
3468
+ type: "boolean",
3469
+ description: "Refetch current revision; requires --apply and still uses optimistic locking"
3470
+ },
3471
+ "confirm-current-revision": {
3472
+ type: "string",
3473
+ description: "Second force confirmation: the freshly displayed current revision"
3474
+ }
3475
+ },
3476
+ async run({ args }) {
3477
+ if (args.force && !args.apply)
3478
+ throw new Error("--force requires --apply (interactive force is intentionally unsupported)");
3479
+ const document = parseTeamDocument(jsonFile(args.file));
3480
+ const client = createClient2();
3481
+ let current = null;
3482
+ try {
3483
+ current = await client.get(
3484
+ `/api/team-templates/${encodeURIComponent(document.template.id)}`
3485
+ );
3486
+ } catch (error) {
3487
+ if (!(error instanceof ApiClientError) || error.status !== 404) throw error;
3488
+ }
3489
+ printImportDiff(current, document);
3490
+ if (args["dry-run"]) {
3491
+ console.log("valid: no changes applied");
3492
+ return;
3493
+ }
3494
+ if (!args.apply) throw new Error("refusing mutation: review the diff, then pass --apply");
3495
+ if (!current) {
3496
+ const body2 = teamImportBody(document);
3497
+ const created = await client.post("/api/team-templates/import", {
3498
+ id: document.template.id,
3499
+ name: document.template.name,
3500
+ userMd: document.template.userMd,
3501
+ slots: document.slots.map((slot, index) => ({
3502
+ ...body2.slots[index],
3503
+ clientKey: slot.key
3504
+ })),
3505
+ edges: body2.edges
3506
+ });
3507
+ console.log(
3508
+ `created Team ${created.template.id} at revision ${created.template.currentRevision}`
3509
+ );
3510
+ return;
3511
+ }
3512
+ if (document.template.name !== current.template.name || document.template.userMd !== current.template.userMd)
3513
+ throw new Error(
3514
+ "replacement document metadata differs; update Team name/USER.md separately before import"
3515
+ );
3516
+ const supplied = Number.parseInt(args["expected-revision"] ?? "", 10);
3517
+ const expectedRevision = args.force ? current.template.currentRevision : supplied;
3518
+ if (args.force && Number.parseInt(args["confirm-current-revision"] ?? "", 10) !== current.template.currentRevision)
3519
+ throw new Error(
3520
+ `--force requires --confirm-current-revision ${current.template.currentRevision} after reviewing the fresh diff`
3521
+ );
3522
+ if (!Number.isInteger(expectedRevision) || expectedRevision < 1)
3523
+ throw new Error("--expected-revision is required when replacing an existing Team");
3524
+ const definition = teamImportBody(document, current);
3525
+ const body = { expectedRevision, ...definition };
3526
+ const updated = await client.put(
3527
+ `/api/team-templates/${encodeURIComponent(document.template.id)}/definition`,
3528
+ body
3529
+ );
3530
+ console.log(
3531
+ `updated Team ${updated.template.id} to revision ${updated.template.currentRevision}`
3532
+ );
3533
+ }
3534
+ });
3535
+ var teamTemplateCommand = defineCommand20({
3536
+ meta: {
3537
+ name: "team-template",
3538
+ description: "Inspect and exchange canonical Team templates"
3539
+ },
3540
+ subCommands: { list: list2, show: show3, export: exportCommand2, import: importCommand2 }
3541
+ });
3542
+
3543
+ // src/commands/telegram.ts
3544
+ import { defineCommand as defineCommand21 } from "citty";
3545
+ var setCmd2 = defineCommand21({
2995
3546
  meta: {
2996
3547
  name: "set",
2997
3548
  description: "Save bot token + supergroup chat ID (paired write)"
@@ -3009,7 +3560,7 @@ var setCmd2 = defineCommand19({
3009
3560
  console.log(`saved \xB7 token ${state.botTokenPreview} \xB7 chat ${state.chatId}`);
3010
3561
  }
3011
3562
  });
3012
- var clearCmd = defineCommand19({
3563
+ var clearCmd = defineCommand21({
3013
3564
  meta: {
3014
3565
  name: "clear",
3015
3566
  description: "Remove stored bot token + chat ID"
@@ -3020,7 +3571,7 @@ var clearCmd = defineCommand19({
3020
3571
  console.log("cleared");
3021
3572
  }
3022
3573
  });
3023
- var showCmd6 = defineCommand19({
3574
+ var showCmd5 = defineCommand21({
3024
3575
  meta: {
3025
3576
  name: "show",
3026
3577
  description: "Show what credentials are stored (token is masked)"
@@ -3041,7 +3592,7 @@ var showCmd6 = defineCommand19({
3041
3592
  }
3042
3593
  }
3043
3594
  });
3044
- var reconnectCmd = defineCommand19({
3595
+ var reconnectCmd = defineCommand21({
3045
3596
  meta: {
3046
3597
  name: "reconnect",
3047
3598
  description: "Apply a pending supergroup chat-id migration + re-activate the bot"
@@ -3052,7 +3603,7 @@ var reconnectCmd = defineCommand19({
3052
3603
  console.log(`reconnected \xB7 chat ${state.chatId}`);
3053
3604
  }
3054
3605
  });
3055
- var configCmd = defineCommand19({
3606
+ var configCmd = defineCommand21({
3056
3607
  meta: {
3057
3608
  name: "config",
3058
3609
  description: "Manage Telegram credentials (bot token + chat ID)"
@@ -3060,10 +3611,10 @@ var configCmd = defineCommand19({
3060
3611
  subCommands: {
3061
3612
  set: setCmd2,
3062
3613
  clear: clearCmd,
3063
- show: showCmd6
3614
+ show: showCmd5
3064
3615
  }
3065
3616
  });
3066
- var healthCmd = defineCommand19({
3617
+ var healthCmd = defineCommand21({
3067
3618
  meta: {
3068
3619
  name: "health",
3069
3620
  description: "Run the four-step preflight against the Telegram Bot API"
@@ -3097,7 +3648,7 @@ var healthCmd = defineCommand19({
3097
3648
  if (!allOk) process.exitCode = 1;
3098
3649
  }
3099
3650
  });
3100
- var botStatusCmd = defineCommand19({
3651
+ var botStatusCmd = defineCommand21({
3101
3652
  meta: {
3102
3653
  name: "status",
3103
3654
  description: "Show polling state of the live bot"
@@ -3122,7 +3673,7 @@ var botStatusCmd = defineCommand19({
3122
3673
  if (!p.running) process.exitCode = 1;
3123
3674
  }
3124
3675
  });
3125
- var botRestartCmd = defineCommand19({
3676
+ var botRestartCmd = defineCommand21({
3126
3677
  meta: {
3127
3678
  name: "restart",
3128
3679
  description: "Force-restart the bot (tears down + brings up from current creds)"
@@ -3133,7 +3684,7 @@ var botRestartCmd = defineCommand19({
3133
3684
  console.log("restart requested");
3134
3685
  }
3135
3686
  });
3136
- var botCmd = defineCommand19({
3687
+ var botCmd = defineCommand21({
3137
3688
  meta: {
3138
3689
  name: "bot",
3139
3690
  description: "Inspect / control the live polling bot"
@@ -3143,7 +3694,7 @@ var botCmd = defineCommand19({
3143
3694
  restart: botRestartCmd
3144
3695
  }
3145
3696
  });
3146
- var bindCmd = defineCommand19({
3697
+ var bindCmd = defineCommand21({
3147
3698
  meta: {
3148
3699
  name: "bind",
3149
3700
  description: "Create a Telegram topic for an agent (manual fallback for /talk)"
@@ -3161,7 +3712,7 @@ var bindCmd = defineCommand19({
3161
3712
  console.log(` ${result.deepLink}`);
3162
3713
  }
3163
3714
  });
3164
- var unbindCmd = defineCommand19({
3715
+ var unbindCmd = defineCommand21({
3165
3716
  meta: {
3166
3717
  name: "unbind",
3167
3718
  description: "Clear an agent's Telegram topic binding (topic stays in Telegram as orphan)"
@@ -3175,7 +3726,7 @@ var unbindCmd = defineCommand19({
3175
3726
  console.log(`unbound agent ${args.agent}`);
3176
3727
  }
3177
3728
  });
3178
- var listBindingsCmd = defineCommand19({
3729
+ var listBindingsCmd = defineCommand21({
3179
3730
  meta: {
3180
3731
  name: "list",
3181
3732
  description: "List agents and their Telegram topic bindings"
@@ -3192,18 +3743,18 @@ var listBindingsCmd = defineCommand19({
3192
3743
  if (bound.length > 0) {
3193
3744
  console.log("bound:");
3194
3745
  for (const a of bound) {
3195
- console.log(` #${a.telegramTopicId} ${a.name} (group: ${a.groupId})`);
3746
+ console.log(` #${a.telegramTopicId} ${a.name} (team: ${a.teamId})`);
3196
3747
  }
3197
3748
  }
3198
3749
  if (unbound.length > 0) {
3199
3750
  console.log("unbound:");
3200
3751
  for (const a of unbound) {
3201
- console.log(` \u2014 ${a.name} (group: ${a.groupId})`);
3752
+ console.log(` \u2014 ${a.name} (team: ${a.teamId})`);
3202
3753
  }
3203
3754
  }
3204
3755
  }
3205
3756
  });
3206
- var allowCmd = defineCommand19({
3757
+ var allowCmd = defineCommand21({
3207
3758
  meta: { name: "allow", description: "Add a Telegram user id to the allowlist" },
3208
3759
  args: {
3209
3760
  userId: { type: "positional", required: true, description: "Numeric Telegram user id" },
@@ -3220,7 +3771,7 @@ var allowCmd = defineCommand19({
3220
3771
  console.log(`allowed ${u.userId} (${u.role})`);
3221
3772
  }
3222
3773
  });
3223
- var denyCmd = defineCommand19({
3774
+ var denyCmd = defineCommand21({
3224
3775
  meta: { name: "deny", description: "Remove a Telegram user id from the allowlist" },
3225
3776
  args: { userId: { type: "positional", required: true } },
3226
3777
  async run({ args }) {
@@ -3229,7 +3780,7 @@ var denyCmd = defineCommand19({
3229
3780
  console.log(`removed ${args.userId}`);
3230
3781
  }
3231
3782
  });
3232
- var allowedCmd = defineCommand19({
3783
+ var allowedCmd = defineCommand21({
3233
3784
  meta: { name: "allowed", description: "List allowlisted Telegram users" },
3234
3785
  async run() {
3235
3786
  const client = createClient2();
@@ -3244,7 +3795,7 @@ var allowedCmd = defineCommand19({
3244
3795
  }
3245
3796
  }
3246
3797
  });
3247
- var telegramCommand = defineCommand19({
3798
+ var telegramCommand = defineCommand21({
3248
3799
  meta: {
3249
3800
  name: "telegram",
3250
3801
  description: "Telegram integration: credentials, health, bot lifecycle, bindings, access"
@@ -3265,7 +3816,7 @@ var telegramCommand = defineCommand19({
3265
3816
 
3266
3817
  // src/commands/token.ts
3267
3818
  import { networkInterfaces } from "os";
3268
- import { defineCommand as defineCommand20 } from "citty";
3819
+ import { defineCommand as defineCommand22 } from "citty";
3269
3820
  import qrcode from "qrcode-terminal";
3270
3821
  function tokenRow(t) {
3271
3822
  const last = t.lastUsedAt ? new Date(t.lastUsedAt).toISOString() : "(never)";
@@ -3299,7 +3850,7 @@ function resolveQrServer(override) {
3299
3850
  if (detected.warning) console.warn(`\u26A0 ${detected.warning}`);
3300
3851
  return detected.origin;
3301
3852
  }
3302
- var createCmd4 = defineCommand20({
3853
+ var createCmd3 = defineCommand22({
3303
3854
  meta: { name: "create", description: "Mint a new web token (shown once)" },
3304
3855
  args: {
3305
3856
  label: { type: "positional", required: true, description: "Human-readable label" },
@@ -3330,7 +3881,7 @@ var createCmd4 = defineCommand20({
3330
3881
  qrcode.generate(pairUrl, { small: true }, (qr) => console.log(qr));
3331
3882
  }
3332
3883
  });
3333
- var listCmd11 = defineCommand20({
3884
+ var listCmd10 = defineCommand22({
3334
3885
  meta: { name: "list", description: "List web tokens" },
3335
3886
  args: {
3336
3887
  all: { type: "boolean", description: "Include revoked tokens" }
@@ -3346,7 +3897,7 @@ var listCmd11 = defineCommand20({
3346
3897
  for (const line of columnize(tokens.map(tokenRow))) console.log(line);
3347
3898
  }
3348
3899
  });
3349
- var showLocalCmd = defineCommand20({
3900
+ var showLocalCmd = defineCommand22({
3350
3901
  meta: {
3351
3902
  name: "show-local",
3352
3903
  description: "Print the bootstrap web token stored in ~/.bazilion/auth.json"
@@ -3356,7 +3907,7 @@ var showLocalCmd = defineCommand20({
3356
3907
  console.log(readAuthFile(paths.authFile).token);
3357
3908
  }
3358
3909
  });
3359
- var revokeCmd = defineCommand20({
3910
+ var revokeCmd = defineCommand22({
3360
3911
  meta: { name: "revoke", description: "Revoke a web token" },
3361
3912
  args: {
3362
3913
  id: { type: "positional", required: true }
@@ -3367,19 +3918,19 @@ var revokeCmd = defineCommand20({
3367
3918
  console.log(`revoked token ${args.id}`);
3368
3919
  }
3369
3920
  });
3370
- var tokenCommand = defineCommand20({
3921
+ var tokenCommand = defineCommand22({
3371
3922
  meta: { name: "token", description: "Manage web tokens for API/CLI clients" },
3372
3923
  subCommands: {
3373
- create: createCmd4,
3374
- list: listCmd11,
3924
+ create: createCmd3,
3925
+ list: listCmd10,
3375
3926
  revoke: revokeCmd,
3376
3927
  "show-local": showLocalCmd
3377
3928
  }
3378
3929
  });
3379
3930
 
3380
3931
  // src/commands/trigger.ts
3381
- import { defineCommand as defineCommand21 } from "citty";
3382
- var addCmd3 = defineCommand21({
3932
+ import { defineCommand as defineCommand23 } from "citty";
3933
+ var addCmd3 = defineCommand23({
3383
3934
  meta: { name: "add", description: "Add a heartbeat / cron trigger to an agent" },
3384
3935
  args: {
3385
3936
  agent: { type: "positional", required: true },
@@ -3427,7 +3978,7 @@ function triggerRow(t) {
3427
3978
  const msgPreview = t.message.length > 60 ? `${t.message.slice(0, 60)}\u2026` : t.message;
3428
3979
  return [t.id, state, spec, `last: ${last}`, `"${msgPreview}"`];
3429
3980
  }
3430
- var listCmd12 = defineCommand21({
3981
+ var listCmd11 = defineCommand23({
3431
3982
  meta: { name: "list", description: "List triggers for an agent" },
3432
3983
  args: {
3433
3984
  agent: { type: "positional", required: true }
@@ -3444,7 +3995,7 @@ var listCmd12 = defineCommand21({
3444
3995
  for (const line of columnize(triggers.map(triggerRow))) console.log(line);
3445
3996
  }
3446
3997
  });
3447
- var rmCmd6 = defineCommand21({
3998
+ var rmCmd6 = defineCommand23({
3448
3999
  meta: { name: "rm", description: "Delete a trigger" },
3449
4000
  args: {
3450
4001
  id: { type: "positional", required: true }
@@ -3455,7 +4006,7 @@ var rmCmd6 = defineCommand21({
3455
4006
  console.log(`removed trigger ${args.id}`);
3456
4007
  }
3457
4008
  });
3458
- var enableCmd3 = defineCommand21({
4009
+ var enableCmd3 = defineCommand23({
3459
4010
  meta: { name: "enable", description: "Enable a trigger" },
3460
4011
  args: {
3461
4012
  id: { type: "positional", required: true }
@@ -3467,7 +4018,7 @@ var enableCmd3 = defineCommand21({
3467
4018
  console.log(`enabled trigger ${args.id}`);
3468
4019
  }
3469
4020
  });
3470
- var disableCmd3 = defineCommand21({
4021
+ var disableCmd3 = defineCommand23({
3471
4022
  meta: { name: "disable", description: "Disable a trigger" },
3472
4023
  args: {
3473
4024
  id: { type: "positional", required: true }
@@ -3479,11 +4030,11 @@ var disableCmd3 = defineCommand21({
3479
4030
  console.log(`disabled trigger ${args.id}`);
3480
4031
  }
3481
4032
  });
3482
- var triggerCommand = defineCommand21({
4033
+ var triggerCommand = defineCommand23({
3483
4034
  meta: { name: "trigger", description: "Manage agent heartbeats / cron triggers" },
3484
4035
  subCommands: {
3485
4036
  add: addCmd3,
3486
- list: listCmd12,
4037
+ list: listCmd11,
3487
4038
  rm: rmCmd6,
3488
4039
  enable: enableCmd3,
3489
4040
  disable: disableCmd3
@@ -3491,9 +4042,9 @@ var triggerCommand = defineCommand21({
3491
4042
  });
3492
4043
 
3493
4044
  // 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";
4045
+ import { existsSync as existsSync7, readdirSync as readdirSync2, rmSync as rmSync3 } from "fs";
4046
+ import { join as join5 } from "path";
4047
+ import { defineCommand as defineCommand24 } from "citty";
3497
4048
  function makeLineReader() {
3498
4049
  let buffer = "";
3499
4050
  let ended = false;
@@ -3538,10 +4089,10 @@ async function askYes(readLine, prompt) {
3538
4089
  }
3539
4090
  function removePath(p) {
3540
4091
  if (!existsSync7(p)) return false;
3541
- rmSync4(p, { recursive: true, force: true });
4092
+ rmSync3(p, { recursive: true, force: true });
3542
4093
  return true;
3543
4094
  }
3544
- var uninstallCommand = defineCommand22({
4095
+ var uninstallCommand = defineCommand24({
3545
4096
  meta: {
3546
4097
  name: "uninstall",
3547
4098
  description: "Wipe bazilion state from ~/.bazilion (or BAZILION_HOME)"
@@ -3559,26 +4110,19 @@ var uninstallCommand = defineCommand22({
3559
4110
  },
3560
4111
  async run({ args }) {
3561
4112
  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");
4113
+ const dbFile = join5(paths.home, "bazilion.db");
4114
+ const profilesDir = join5(paths.home, "profiles");
4115
+ const agentsDir = join5(paths.home, "agents");
4116
+ const teamsDir = join5(paths.home, "teams");
4117
+ const skillsDir = join5(paths.home, "skills");
4118
+ const logsDir = join5(paths.home, "logs");
3568
4119
  if (!existsSync7(paths.home)) {
3569
4120
  console.log(`nothing to remove: ${paths.home} does not exist`);
3570
4121
  return;
3571
4122
  }
3572
4123
  console.log(`about to uninstall bazilion at ${paths.home}`);
3573
4124
  console.log("");
3574
- const dataTargets = [
3575
- dbFile,
3576
- `${dbFile}-wal`,
3577
- `${dbFile}-shm`,
3578
- profilesDir,
3579
- agentsDir,
3580
- groupsDir
3581
- ];
4125
+ const dataTargets = [dbFile, `${dbFile}-wal`, `${dbFile}-shm`, profilesDir, agentsDir, teamsDir];
3582
4126
  const needsPrompt = !args.yes;
3583
4127
  const readLine = needsPrompt ? makeLineReader() : null;
3584
4128
  const wipeData = args.yes || await askYes(
@@ -3604,7 +4148,7 @@ var uninstallCommand = defineCommand22({
3604
4148
  if (removePath(p)) console.log(`removed ${p}`);
3605
4149
  }
3606
4150
  if (readdirSync2(paths.home).length === 0) {
3607
- rmSync4(paths.home, { recursive: true, force: true });
4151
+ rmSync3(paths.home, { recursive: true, force: true });
3608
4152
  console.log(`removed ${paths.home}`);
3609
4153
  } else {
3610
4154
  console.log(`${paths.home} still has unmanaged files; left in place`);
@@ -3619,7 +4163,7 @@ var uninstallCommand = defineCommand22({
3619
4163
 
3620
4164
  // src/index.ts
3621
4165
  var VERSION = package_default.version;
3622
- var main = defineCommand23({
4166
+ var main = defineCommand25({
3623
4167
  meta: {
3624
4168
  name: "bazilion",
3625
4169
  version: VERSION,
@@ -3628,9 +4172,10 @@ var main = defineCommand23({
3628
4172
  subCommands: {
3629
4173
  login: loginCommand,
3630
4174
  profile: profileCommand,
3631
- "profile-group": profileGroupCommand,
3632
- group: groupCommand,
4175
+ team: teamCommand,
4176
+ "team-template": teamTemplateCommand,
3633
4177
  agent: agentCommand,
4178
+ approval: approvalCommand,
3634
4179
  skill: skillCommand,
3635
4180
  memory: memoryCommand,
3636
4181
  mcp: mcpCommand,
@@ -3685,12 +4230,22 @@ function printError(err) {
3685
4230
  console.error(" hint: host not found. Check BAZILION_SERVER / ~/.bazilion/auth.json.");
3686
4231
  }
3687
4232
  }
4233
+ function exitCodeForError(err) {
4234
+ if (err instanceof ApiClientError) {
4235
+ if (err.status === 401 || err.status === 403) return 4;
4236
+ if (err.status === 409) return 3;
4237
+ if (err.status === 400 || err.status === 422) return 2;
4238
+ return 1;
4239
+ }
4240
+ const message = err instanceof Error ? err.message : String(err);
4241
+ return /invalid|unsupported|must be|require|refusing mutation|document belongs/.test(message) ? 2 : 1;
4242
+ }
3688
4243
  function printTopLevelHelp() {
3689
4244
  console.log(`Multi-agent runtime (bazilion v${VERSION})`);
3690
4245
  console.log("");
3691
4246
  console.log("USAGE bazilion <command> [args]");
3692
4247
  console.log("");
3693
- const groups = [
4248
+ const teams = [
3694
4249
  {
3695
4250
  title: "setup",
3696
4251
  items: [
@@ -3704,8 +4259,8 @@ function printTopLevelHelp() {
3704
4259
  title: "catalog",
3705
4260
  items: [
3706
4261
  ["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)"],
4262
+ ["team-template", "Inspect and exchange reusable Team Templates"],
4263
+ ["team", "Manage teams (collaboration context \u2014 filesystem root + USER.md + roster)"],
3709
4264
  ["skill", "Manage the skill library"],
3710
4265
  ["provider", "Manage and test LLM providers"],
3711
4266
  ["config", "Manage service config (credentials + URLs/IDs)"],
@@ -3715,8 +4270,9 @@ function printTopLevelHelp() {
3715
4270
  {
3716
4271
  title: "agents",
3717
4272
  items: [
4273
+ ["approval", "Review and decide communication approval attempts"],
3718
4274
  ["agent", "Spawn, list, chat, archive agents"],
3719
- ["memory", "Read/write a group's shared memory"],
4275
+ ["memory", "Read/write a team's shared memory"],
3720
4276
  ["send", "Send a message from one agent to another"],
3721
4277
  ["inbox", "Inspect agent inboxes"],
3722
4278
  ["trigger", "Manage agent heartbeats / cron triggers"]
@@ -3742,8 +4298,8 @@ function printTopLevelHelp() {
3742
4298
  items: [["completion", "Print shell completion script (bash | zsh | fish)"]]
3743
4299
  }
3744
4300
  ];
3745
- const nameWidth = 12;
3746
- for (const g of groups) {
4301
+ const nameWidth = 15;
4302
+ for (const g of teams) {
3747
4303
  console.log(` ${g.title}`);
3748
4304
  for (const [name, desc] of g.items) {
3749
4305
  console.log(` ${name.padEnd(nameWidth)}${desc}`);
@@ -3772,7 +4328,7 @@ async function entry() {
3772
4328
  await runCommand(main, { rawArgs });
3773
4329
  } catch (err) {
3774
4330
  printError(err);
3775
- process.exit(1);
4331
+ process.exit(exitCodeForError(err));
3776
4332
  }
3777
4333
  }
3778
4334
  entry();