bazilion 0.7.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 (166) hide show
  1. package/README.md +47 -5
  2. package/dist/cli.js +1257 -638
  3. package/dist/cli.js.map +1 -1
  4. package/dist/daemon.js +5334 -1594
  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-BSAVT-17.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-D8lNr2SX.js → login-Bk2wwIHQ.js} +1 -1
  30. package/dist/web/client/assets/{mcp-BLnngDsj.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-B__fLZjx.js +1 -0
  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-D2_O9ARe.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-D0ytyXGY.js → _id-B6g9wmPR.js} +167 -31
  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-81NrHA5d.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-BpBZgRwn.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/{skills-dLyBZb3B.js → skills-D89ND2kR.js} +67 -7
  107. package/dist/web/server/assets/{skills-CpsyR_WA.js → skills-l2cyQ3zS.js} +1 -1
  108. package/dist/web/server/assets/{start-CYDpZ6cb.js → start-DlHq0RaQ.js} +1 -1
  109. package/dist/web/server/assets/team-policy-Csvc5EDd.js +180 -0
  110. package/dist/web/server/assets/teams-35Oprf6e.js +14 -0
  111. package/dist/web/server/assets/teams-3im0oQnS.js +11 -0
  112. package/dist/web/server/assets/teams-B5IF65p2.js +12 -0
  113. package/dist/web/server/assets/teams-B9O-WDH5.js +108 -0
  114. package/dist/web/server/assets/teams-DFkN7ic7.js +36 -0
  115. package/dist/web/server/assets/teams-DH1CvWmT.js +12 -0
  116. package/dist/web/server/assets/teams-zcm9XaQU.js +174 -0
  117. package/dist/web/server/assets/{telegram-DfAddLdv.js → telegram-C9sQFwWj.js} +7 -7
  118. package/dist/web/server/assets/{telegram-T3l9KtiE.js → telegram-mTnJCOmn.js} +1 -1
  119. package/dist/web/server/assets/{welcome-CP4CZ9B6.js → welcome-CDGE2Sdk.js} +2 -2
  120. package/dist/web/server/assets/{wire-constants-Deb4NxBb.js → wire-constants-C8nBJcU3.js} +3 -3
  121. package/dist/web/server/server.js +64 -42
  122. package/dist/worker.js +180 -128
  123. package/dist/worker.js.map +1 -1
  124. package/package.json +7 -7
  125. package/dist/migrations/0002_profile_groups.sql +0 -38
  126. package/dist/migrations/0003_agent_telegram.sql +0 -40
  127. package/dist/migrations/0004_agent_mirror_mode.sql +0 -17
  128. package/dist/migrations/0005_group_topic_name_format.sql +0 -15
  129. package/dist/migrations/0006_telegram_acl.sql +0 -18
  130. package/dist/migrations/0007_mcp_servers.sql +0 -30
  131. package/dist/migrations/0008_seed_user_md.sql +0 -39
  132. package/dist/web/client/assets/MembersEditor-C6UpqDdV.js +0 -1
  133. package/dist/web/client/assets/SpawnTeamModal-BEkNCKXm.js +0 -1
  134. package/dist/web/client/assets/TemplatesTabs-Da7mg9FI.js +0 -1
  135. package/dist/web/client/assets/_id-BdKmo0gb.js +0 -1
  136. package/dist/web/client/assets/_id-LT6Ejjr0.js +0 -1
  137. package/dist/web/client/assets/_id-MR2XjWh0.js +0 -1
  138. package/dist/web/client/assets/_id-_6jIt0_-.js +0 -1
  139. package/dist/web/client/assets/agents-0arKbVYG.js +0 -1
  140. package/dist/web/client/assets/groups-BqTkhHes.js +0 -1
  141. package/dist/web/client/assets/inbox-ozoCXzr5.js +0 -1
  142. package/dist/web/client/assets/index-iayCEuU2.js +0 -12
  143. package/dist/web/client/assets/memory-D1GQjEvN.js +0 -1
  144. package/dist/web/client/assets/profile-groups-C2yJPTaE.js +0 -1
  145. package/dist/web/client/assets/profiles-BV7AAZjj.js +0 -1
  146. package/dist/web/client/assets/routes-DSHQLA7K.js +0 -1
  147. package/dist/web/client/assets/services-BbCJe1Du.js +0 -1
  148. package/dist/web/client/assets/skills-C6czKR5I.js +0 -1
  149. package/dist/web/client/assets/styles-C06axZZk.css +0 -2
  150. package/dist/web/client/assets/telegram-gE4j8gte.js +0 -1
  151. package/dist/web/client/assets/triggers-WljnfEfJ.js +0 -1
  152. package/dist/web/client/assets/welcome-Dn-zvmBE.js +0 -1
  153. package/dist/web/client/assets/wire-constants-BkT5-597.js +0 -1
  154. package/dist/web/server/assets/MembersEditor-BWQztvrX.js +0 -131
  155. package/dist/web/server/assets/SpawnTeamModal-dSN421k_.js +0 -107
  156. package/dist/web/server/assets/_id-BKev9H1p.js +0 -12
  157. package/dist/web/server/assets/_id-BNwlbWHP.js +0 -24
  158. package/dist/web/server/assets/_id-CRqqi8IE.js +0 -161
  159. package/dist/web/server/assets/_tanstack-start-manifest_v-DBlFH2gg.js +0 -178
  160. package/dist/web/server/assets/groups-CbSwND2r.js +0 -12
  161. package/dist/web/server/assets/groups-CeRRlZaZ.js +0 -150
  162. package/dist/web/server/assets/groups-pk4CYSuf.js +0 -21
  163. package/dist/web/server/assets/memory-CQaqWnyM.js +0 -284
  164. package/dist/web/server/assets/profile-groups-CiU06yN1.js +0 -28
  165. package/dist/web/server/assets/profile-groups-D21MYoLM.js +0 -208
  166. package/dist/web/server/assets/profile-groups-aoJleXHP.js +0 -12
package/dist/worker.js CHANGED
@@ -1,93 +1,99 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // ../daemon/src/runtime/worker/entry.ts
4
- import { randomUUID as randomUUID6 } from "crypto";
5
- import { join as join16 } from "path";
4
+ import { randomUUID as randomUUID14 } from "crypto";
5
+ import { join as join17 } from "path";
6
6
 
7
7
  // ../daemon/src/core/agent/delete.ts
8
- import { existsSync, rmSync } from "fs";
8
+ import { randomUUID } from "crypto";
9
+ import { existsSync, renameSync, rmSync } from "fs";
9
10
 
10
- // ../daemon/src/core/agent/resolve.ts
11
+ // ../daemon/src/core/agent/move.ts
12
+ import { readFileSync, writeFileSync } from "fs";
11
13
  import { join } from "path";
12
14
 
15
+ // ../daemon/src/core/agent/resolve.ts
16
+ import { join as join2 } from "path";
17
+
13
18
  // ../daemon/src/core/profile/identity.ts
14
- import { readFileSync } from "fs";
19
+ import { readFileSync as readFileSync2 } from "fs";
15
20
 
16
21
  // ../daemon/src/core/agent/spawn.ts
17
- import { randomUUID } from "crypto";
18
- import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
19
- import { join as join6 } from "path";
22
+ import { randomUUID as randomUUID2 } from "crypto";
23
+ import { mkdirSync as mkdirSync3, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
24
+ import { join as join7 } from "path";
20
25
 
21
26
  // ../daemon/src/core/profile/load.ts
22
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
23
- import { join as join2 } from "path";
27
+ import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
28
+ import { join as join3 } from "path";
24
29
 
25
30
  // ../daemon/src/core/profile/seed.ts
26
- import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
27
- import { join as join4 } from "path";
31
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
32
+ import { join as join5 } from "path";
28
33
 
29
- // ../daemon/src/core/group/register.ts
30
- import { existsSync as existsSync3, mkdirSync, statSync, symlinkSync } from "fs";
34
+ // ../daemon/src/core/team/register.ts
35
+ import { existsSync as existsSync3, mkdirSync, rmSync as rmSync2, statSync, symlinkSync } from "fs";
31
36
  import { resolve } from "path";
32
37
 
33
38
  // ../daemon/src/core/profile/create.ts
34
- import { mkdirSync as mkdirSync2, writeFileSync } from "fs";
35
- import { join as join3 } from "path";
39
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
40
+ import { join as join4 } from "path";
36
41
 
37
42
  // ../daemon/src/core/skills/discover.ts
38
43
  import { existsSync as existsSync5, readdirSync } from "fs";
39
- import { join as join5 } from "path";
44
+ import { join as join6 } from "path";
40
45
 
41
46
  // ../daemon/src/core/db/client.ts
42
47
  import { DatabaseSync } from "node:sqlite";
43
48
 
44
49
  // ../daemon/src/core/db/migrate.ts
45
- import { readdirSync as readdirSync2, readFileSync as readFileSync4 } from "fs";
46
- import { dirname, join as join7 } from "path";
50
+ import { readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
51
+ import { dirname, join as join8 } from "path";
47
52
  import { fileURLToPath } from "url";
48
- var migrationsDir = join7(dirname(fileURLToPath(import.meta.url)), "migrations");
53
+ var migrationsDir = join8(dirname(fileURLToPath(import.meta.url)), "migrations");
49
54
 
50
55
  // ../daemon/src/core/paths.ts
51
56
  import { homedir } from "os";
52
- import { join as join8 } from "path";
57
+ import { join as join9 } from "path";
53
58
  function resolvePaths(home) {
54
- const root = home ?? process.env.BAZILION_HOME ?? join8(homedir(), ".bazilion");
59
+ const root = home ?? process.env.BAZILION_HOME ?? join9(homedir(), ".bazilion");
55
60
  return {
56
61
  home: root,
57
- db: join8(root, "bazilion.db"),
58
- authFile: join8(root, "auth.json"),
59
- profilesDir: join8(root, "profiles"),
60
- agentsDir: join8(root, "agents"),
61
- skillsDir: join8(root, "skills"),
62
- groupsDir: join8(root, "groups"),
63
- logsDir: join8(root, "logs"),
62
+ db: join9(root, "bazilion.db"),
63
+ authFile: join9(root, "auth.json"),
64
+ profilesDir: join9(root, "profiles"),
65
+ agentsDir: join9(root, "agents"),
66
+ skillsDir: join9(root, "skills"),
67
+ teamsDir: join9(root, "teams"),
68
+ logsDir: join9(root, "logs"),
64
69
  profileDir(id) {
65
- return join8(root, "profiles", id);
70
+ return join9(root, "profiles", id);
66
71
  },
67
72
  agentDir(id) {
68
- return join8(root, "agents", id);
73
+ return join9(root, "agents", id);
69
74
  },
70
75
  skillDir(name) {
71
- return join8(root, "skills", name);
76
+ return join9(root, "skills", name);
72
77
  },
73
- groupDir(slug) {
74
- return join8(root, "groups", slug);
78
+ teamDir(slug) {
79
+ return join9(root, "teams", slug);
75
80
  }
76
81
  };
77
82
  }
78
83
 
79
84
  // ../daemon/src/core/profile/delete.ts
80
- import { existsSync as existsSync6, rmSync as rmSync2 } from "fs";
85
+ import { existsSync as existsSync6, rmSync as rmSync4 } from "fs";
81
86
 
82
- // ../daemon/src/core/profile/update.ts
83
- import { writeFileSync as writeFileSync4 } from "fs";
84
- import { join as join9 } from "path";
87
+ // ../daemon/src/core/repos/teamTemplates.ts
88
+ import { randomUUID as randomUUID3 } from "crypto";
85
89
 
86
- // ../daemon/src/core/profile-group/spawn.ts
87
- import { readdirSync as readdirSync3, rmSync as rmSync4 } from "fs";
90
+ // ../daemon/src/core/profile/update.ts
91
+ import { writeFileSync as writeFileSync5 } from "fs";
92
+ import { join as join10 } from "path";
88
93
 
89
- // ../daemon/src/core/profile-group/rm-with-retry.ts
90
- import { rmSync as rmSync3 } from "fs";
94
+ // ../daemon/src/core/repos/communicationApprovals.ts
95
+ import { createHash, randomUUID as randomUUID4 } from "crypto";
96
+ var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
91
97
 
92
98
  // ../daemon/src/core/services.ts
93
99
  var SERVICES = [
@@ -448,7 +454,7 @@ var SERVICES = [
448
454
  id: "firecrawl",
449
455
  displayName: "Firecrawl",
450
456
  category: "service",
451
- group: "Web Search",
457
+ team: "Web Search",
452
458
  hint: "web_fetch fallback for JS-heavy/blocked pages \xB7 firecrawl.dev (free tier available)",
453
459
  fields: [
454
460
  {
@@ -470,7 +476,7 @@ var SERVICES = [
470
476
  id: "brave-search",
471
477
  displayName: "Brave Search",
472
478
  category: "service",
473
- group: "Web Search",
479
+ team: "Web Search",
474
480
  hint: "Web search tool \xB7 free tier at brave.com/search/api/",
475
481
  fields: [{ envVar: "BRAVE_API_KEY", kind: "secret", label: "API key", placeholder: "BSA..." }]
476
482
  },
@@ -478,7 +484,7 @@ var SERVICES = [
478
484
  id: "searxng",
479
485
  displayName: "SearXNG",
480
486
  category: "service",
481
- group: "Web Search",
487
+ team: "Web Search",
482
488
  hint: "Self-hosted meta-search engine \xB7 searxng.org",
483
489
  fields: [
484
490
  {
@@ -493,7 +499,7 @@ var SERVICES = [
493
499
  id: "browser",
494
500
  displayName: "Browser Automation",
495
501
  category: "service",
496
- group: "Browser",
502
+ team: "Browser",
497
503
  hint: "Playwright-driven browser tools (navigate, snapshot, click, screenshot). Run `pnpm exec playwright install chromium` once.",
498
504
  fields: [
499
505
  {
@@ -591,44 +597,64 @@ var CONFIG_KEYS = [
591
597
  var CONFIG_KEY_SET = new Set(CONFIG_KEYS);
592
598
 
593
599
  // ../daemon/src/core/repos/mcpServers.ts
594
- import { randomUUID as randomUUID2 } from "crypto";
600
+ import { randomUUID as randomUUID5 } from "crypto";
595
601
 
596
602
  // ../daemon/src/core/repos/messages.ts
597
- import { randomUUID as randomUUID3 } from "crypto";
603
+ import { randomUUID as randomUUID6 } from "crypto";
598
604
 
599
605
  // ../daemon/src/core/repos/secrets.ts
600
606
  import { createCipheriv, createDecipheriv, pbkdf2Sync, randomBytes } from "crypto";
601
607
 
602
608
  // ../daemon/src/core/repos/triggers.ts
603
- import { randomUUID as randomUUID4 } from "crypto";
609
+ import { randomUUID as randomUUID7 } from "crypto";
604
610
 
605
611
  // ../daemon/src/core/repos/webTokens.ts
606
- import { createHash, randomBytes as randomBytes2, randomUUID as randomUUID5 } from "crypto";
612
+ import { createHash as createHash2, randomBytes as randomBytes2, randomUUID as randomUUID8 } from "crypto";
607
613
 
608
614
  // ../daemon/src/core/secrets.ts
609
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
615
+ import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
610
616
 
611
617
  // ../daemon/src/core/skills/import.ts
612
- import { cpSync, existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync4, rmSync as rmSync5, statSync as statSync2 } from "fs";
618
+ import { cpSync, existsSync as existsSync8, mkdtempSync, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync2 } from "fs";
613
619
  import { tmpdir } from "os";
614
- import { basename, join as join10, resolve as resolve2, sep } from "path";
620
+ import { basename, join as join11, resolve as resolve2, sep } from "path";
615
621
  import AdmZip from "adm-zip";
616
622
 
617
623
  // ../daemon/src/core/skills/parse.ts
618
- import { readFileSync as readFileSync6 } from "fs";
624
+ import { readFileSync as readFileSync7 } from "fs";
619
625
  import { parse as parseYaml } from "yaml";
620
626
 
627
+ // ../daemon/src/core/team/delete.ts
628
+ import { randomUUID as randomUUID9 } from "crypto";
629
+ import { existsSync as existsSync9, renameSync as renameSync2, rmSync as rmSync6 } from "fs";
630
+
631
+ // ../daemon/src/core/team-policy/adopt.ts
632
+ import { randomUUID as randomUUID10 } from "crypto";
633
+
634
+ // ../daemon/src/core/team-policy/authorization.ts
635
+ import { createHash as createHash3, randomUUID as randomUUID11 } from "crypto";
636
+
637
+ // ../daemon/src/core/team-policy/source.ts
638
+ import { randomUUID as randomUUID12 } from "crypto";
639
+
640
+ // ../daemon/src/core/team-policy/spawn.ts
641
+ import { randomUUID as randomUUID13 } from "crypto";
642
+ import { readdirSync as readdirSync4, rmSync as rmSync8 } from "fs";
643
+
644
+ // ../daemon/src/core/team-policy/rm-with-retry.ts
645
+ import { rmSync as rmSync7 } from "fs";
646
+
621
647
  // ../daemon/src/runtime/memory/qmd.ts
622
648
  import {
623
- existsSync as existsSync9,
649
+ existsSync as existsSync10,
624
650
  mkdirSync as mkdirSync4,
625
651
  readdirSync as readdirSync5,
626
- readFileSync as readFileSync7,
627
- rmSync as rmSync6,
652
+ readFileSync as readFileSync8,
653
+ rmSync as rmSync9,
628
654
  statSync as statSync3,
629
- writeFileSync as writeFileSync5
655
+ writeFileSync as writeFileSync6
630
656
  } from "fs";
631
- import { dirname as dirname2, join as join11 } from "path";
657
+ import { dirname as dirname2, join as join12 } from "path";
632
658
  import { createStore, extractSnippet } from "@tobilu/qmd";
633
659
  var INDEX_FILENAME = ".qmd-index.sqlite";
634
660
  var COLLECTION_NAME = "memory";
@@ -638,7 +664,7 @@ function getStore(dir) {
638
664
  let p = storeCache.get(dir);
639
665
  if (!p) {
640
666
  p = createStore({
641
- dbPath: join11(dir, INDEX_FILENAME),
667
+ dbPath: join12(dir, INDEX_FILENAME),
642
668
  config: {
643
669
  collections: {
644
670
  [COLLECTION_NAME]: { path: dir, pattern: PATTERN }
@@ -653,13 +679,13 @@ function safeKey(root, key) {
653
679
  if (key.includes("..") || key.startsWith("/") || key.includes("\0")) {
654
680
  throw new Error(`unsafe memory key: ${key}`);
655
681
  }
656
- return join11(root, key);
682
+ return join12(root, key);
657
683
  }
658
684
  function walkMd(dir, prefix, out) {
659
- if (!existsSync9(dir)) return;
685
+ if (!existsSync10(dir)) return;
660
686
  for (const e of readdirSync5(dir, { withFileTypes: true })) {
661
687
  if (e.name.startsWith(".")) continue;
662
- const full = join11(dir, e.name);
688
+ const full = join12(dir, e.name);
663
689
  const key = prefix ? `${prefix}/${e.name}` : e.name;
664
690
  if (e.isDirectory()) {
665
691
  walkMd(full, key, out);
@@ -667,7 +693,7 @@ function walkMd(dir, prefix, out) {
667
693
  const stats = statSync3(full);
668
694
  out.push({
669
695
  key,
670
- content: readFileSync7(full, "utf8"),
696
+ content: readFileSync8(full, "utf8"),
671
697
  updatedAt: stats.mtimeMs
672
698
  });
673
699
  }
@@ -682,20 +708,20 @@ function qmdBackend(root) {
682
708
  },
683
709
  async read(key) {
684
710
  const path = safeKey(root, key);
685
- if (!existsSync9(path)) {
711
+ if (!existsSync10(path)) {
686
712
  throw new Error(`memory entry not found: ${key}`);
687
713
  }
688
714
  const stats = statSync3(path);
689
715
  return {
690
716
  key,
691
- content: readFileSync7(path, "utf8"),
717
+ content: readFileSync8(path, "utf8"),
692
718
  updatedAt: stats.mtimeMs
693
719
  };
694
720
  },
695
721
  async write(key, content) {
696
722
  const path = safeKey(root, key);
697
723
  mkdirSync4(dirname2(path), { recursive: true });
698
- writeFileSync5(path, content);
724
+ writeFileSync6(path, content);
699
725
  const stats = statSync3(path);
700
726
  const store = await getStore(root);
701
727
  await store.update();
@@ -715,7 +741,7 @@ function qmdBackend(root) {
715
741
  let content = r.body ?? "";
716
742
  if (!content) {
717
743
  try {
718
- content = readFileSync7(join11(root, key), "utf8");
744
+ content = readFileSync8(join12(root, key), "utf8");
719
745
  } catch {
720
746
  content = "";
721
747
  }
@@ -732,7 +758,7 @@ function qmdBackend(root) {
732
758
  },
733
759
  async remove(key) {
734
760
  const path = safeKey(root, key);
735
- if (existsSync9(path)) rmSync6(path);
761
+ if (existsSync10(path)) rmSync9(path);
736
762
  const store = await getStore(root);
737
763
  await store.update();
738
764
  }
@@ -889,8 +915,8 @@ function piMessagesToProviderView(messages) {
889
915
  }
890
916
 
891
917
  // ../daemon/src/runtime/pi/session.ts
892
- import { existsSync as existsSync12, mkdirSync as mkdirSync5, readdirSync as readdirSync7, statSync as statSync6 } from "fs";
893
- import { basename as basename3, join as join15 } from "path";
918
+ import { existsSync as existsSync13, mkdirSync as mkdirSync5, readdirSync as readdirSync7, statSync as statSync6 } from "fs";
919
+ import { basename as basename3, join as join16 } from "path";
894
920
  import {
895
921
  AuthStorage,
896
922
  createAgentSession,
@@ -905,7 +931,7 @@ import {
905
931
  getModel,
906
932
  streamSimple,
907
933
  Type
908
- } from "@earendil-works/pi-ai";
934
+ } from "@earendil-works/pi-ai/compat";
909
935
  function defaultBaseUrlFor(providerName) {
910
936
  switch (providerName) {
911
937
  case "lmstudio":
@@ -950,8 +976,8 @@ function resolveModel(cfg, modelId) {
950
976
  import { loginOpenAICodex, refreshOpenAICodexToken } from "@earendil-works/pi-ai/oauth";
951
977
 
952
978
  // ../daemon/src/runtime/session/prompt.ts
953
- import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
954
- import { join as join12 } from "path";
979
+ import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
980
+ import { join as join13 } from "path";
955
981
  var CONTEXT_FILE_ORDER = [
956
982
  "AGENTS.md",
957
983
  "SOUL.md",
@@ -963,9 +989,9 @@ function buildSystemPrompt(agent) {
963
989
  const parts = [];
964
990
  const contextBlocks = [];
965
991
  for (const file of CONTEXT_FILE_ORDER) {
966
- const path = join12(agent.agent.dir, file);
967
- if (!existsSync10(path)) continue;
968
- const content = readFileSync8(path, "utf8").trimEnd();
992
+ const path = join13(agent.agent.dir, file);
993
+ if (!existsSync11(path)) continue;
994
+ const content = readFileSync9(path, "utf8").trimEnd();
969
995
  if (!content) continue;
970
996
  contextBlocks.push(`## ${file}
971
997
 
@@ -976,9 +1002,9 @@ ${content}`);
976
1002
 
977
1003
  ${contextBlocks.join("\n\n")}`);
978
1004
  }
979
- const bootstrapPath = join12(agent.agent.dir, "BOOTSTRAP.md");
980
- if (existsSync10(bootstrapPath)) {
981
- const bootstrap = readFileSync8(bootstrapPath, "utf8").trimEnd();
1005
+ const bootstrapPath = join13(agent.agent.dir, "BOOTSTRAP.md");
1006
+ if (existsSync11(bootstrapPath)) {
1007
+ const bootstrap = readFileSync9(bootstrapPath, "utf8").trimEnd();
982
1008
  if (bootstrap) {
983
1009
  parts.push(
984
1010
  [
@@ -1017,31 +1043,31 @@ ${contextBlocks.join("\n\n")}`);
1017
1043
  You have access to the following skills: ${agent.skills.join(", ")}.`
1018
1044
  );
1019
1045
  }
1020
- const groupLines = [
1021
- "# Group",
1046
+ const teamLines = [
1047
+ "# Team",
1022
1048
  "",
1023
- `- ${agent.group.id} (${agent.group.name}): ${agent.group.path}`,
1049
+ `- ${agent.team.id} (${agent.team.name}): ${agent.team.path}`,
1024
1050
  "",
1025
- "Your group is where work product lives \u2014 code, docs, artefacts, shared scratch. It may be shared with other agents in the same group. Your coding tools (`read`, `bash`, `edit`, `write`, `grep`, `find`, `ls`) are rooted at the group directory. Never use these tools to edit your identity/soul/behaviour files \u2014 those live in your home and are reached via `home_write` / `home_read`."
1051
+ "Your team is where work product lives \u2014 code, docs, artefacts, shared scratch. It may be shared with other agents in the same team. Your coding tools (`read`, `bash`, `edit`, `write`, `grep`, `find`, `ls`) are rooted at the team directory. Never use these tools to edit your identity/soul/behaviour files \u2014 those live in your home and are reached via `home_write` / `home_read`."
1026
1052
  ];
1027
- parts.push(groupLines.join("\n"));
1028
- if (agent.group.userMd.trim()) {
1053
+ parts.push(teamLines.join("\n"));
1054
+ if (agent.team.userMd.trim()) {
1029
1055
  parts.push(
1030
1056
  `# About the User
1031
1057
 
1032
- Shared context about the human you're working with in this group. Both you and the human curate it. To update: call \`user_md_get\` (returns current content + an etag), merge your change into the full text, then call \`user_md_write\` with the merged content and the etag. Use this for STABLE user-specific facts (preferences, role, working hours, how they like to be addressed) \u2014 and to CORRECT stale entries when the human tells you something different from what's recorded. For project knowledge use \`memory_write\` instead; for personal notes about yourself use \`home_write\` on IDENTITY.md. **Do NOT send peer messages announcing USER.md changes \u2014 every agent in the group sees the new content in their system prompt on their next turn automatically.**
1058
+ Shared context about the human you're working with in this team. Both you and the human curate it. To update: call \`user_md_get\` (returns current content + an etag), merge your change into the full text, then call \`user_md_write\` with the merged content and the etag. Use this for STABLE user-specific facts (preferences, role, working hours, how they like to be addressed) \u2014 and to CORRECT stale entries when the human tells you something different from what's recorded. For project knowledge use \`memory_write\` instead; for personal notes about yourself use \`home_write\` on IDENTITY.md. **Do NOT send peer messages announcing USER.md changes \u2014 every agent in the team sees the new content in their system prompt on their next turn automatically.**
1033
1059
 
1034
- ${agent.group.userMd.trim()}`
1060
+ ${agent.team.userMd.trim()}`
1035
1061
  );
1036
1062
  } else {
1037
1063
  parts.push(
1038
1064
  `# About the User
1039
1065
 
1040
- This group's USER.md is empty. As you learn STABLE facts about the human (preferences, role, working hours, how they like to be addressed), populate it via \`user_md_get\` then \`user_md_write\` (always get first \u2014 you need the etag). Reserve this for things you're confident are durable \u2014 project knowledge belongs in \`memory_write\`, personal notes about yourself in \`home_write\` on IDENTITY.md. **Do NOT send peer messages announcing USER.md changes \u2014 every agent in the group sees the new content in their system prompt on their next turn automatically.**`
1066
+ This team's USER.md is empty. As you learn STABLE facts about the human (preferences, role, working hours, how they like to be addressed), populate it via \`user_md_get\` then \`user_md_write\` (always get first \u2014 you need the etag). Reserve this for things you're confident are durable \u2014 project knowledge belongs in \`memory_write\`, personal notes about yourself in \`home_write\` on IDENTITY.md. **Do NOT send peer messages announcing USER.md changes \u2014 every agent in the team sees the new content in their system prompt on their next turn automatically.**`
1041
1067
  );
1042
1068
  }
1043
1069
  parts.push(
1044
- "# Memory\n\nYou share a persistent memory backend with every other agent in this group. Use `memory_write` to remember things across sessions, and `memory_search` / `memory_read` / `memory_list` to recall them. This memory is for project knowledge \u2014 codebase notes, decisions, things the user told you about the work. For personal notes about yourself (preferences, persona quirks), use `home_write` on IDENTITY.md instead. Always check memory at the start of a session: another agent in the group may have already learned something useful. **Do NOT send peer messages announcing memory writes \u2014 every agent has access to the same store via `memory_search` and will find your note when they need it.**"
1070
+ "# Memory\n\nYou share a persistent memory backend with every other agent in this team. Use `memory_write` to remember things across sessions, and `memory_search` / `memory_read` / `memory_list` to recall them. This memory is for project knowledge \u2014 codebase notes, decisions, things the user told you about the work. For personal notes about yourself (preferences, persona quirks), use `home_write` on IDENTITY.md instead. Always check memory at the start of a session: another agent in the team may have already learned something useful. **Do NOT send peer messages announcing memory writes \u2014 every agent has access to the same store via `memory_search` and will find your note when they need it.**"
1045
1071
  );
1046
1072
  return parts.join("\n\n---\n\n");
1047
1073
  }
@@ -1050,8 +1076,8 @@ This group's USER.md is empty. As you learn STABLE facts about the human (prefer
1050
1076
  import { Type as Type2 } from "typebox";
1051
1077
 
1052
1078
  // ../daemon/src/runtime/tools/bootstrap.ts
1053
- import { existsSync as existsSync11, rmSync as rmSync7 } from "fs";
1054
- import { join as join13 } from "path";
1079
+ import { existsSync as existsSync12, rmSync as rmSync10 } from "fs";
1080
+ import { join as join14 } from "path";
1055
1081
  function bootstrapTool(agentDir) {
1056
1082
  return {
1057
1083
  def: {
@@ -1060,9 +1086,9 @@ function bootstrapTool(agentDir) {
1060
1086
  parameters: { type: "object", properties: {} }
1061
1087
  },
1062
1088
  async invoke() {
1063
- const path = join13(agentDir, "BOOTSTRAP.md");
1064
- if (existsSync11(path)) {
1065
- rmSync7(path);
1089
+ const path = join14(agentDir, "BOOTSTRAP.md");
1090
+ if (existsSync12(path)) {
1091
+ rmSync10(path);
1066
1092
  return "BOOTSTRAP.md removed. Bootstrap is complete.";
1067
1093
  }
1068
1094
  return "BOOTSTRAP.md was already removed.";
@@ -1200,7 +1226,7 @@ function browserTools(host, agentId) {
1200
1226
  }
1201
1227
 
1202
1228
  // ../daemon/src/runtime/tools/deliver-file.ts
1203
- import { readFileSync as readFileSync9, statSync as statSync4 } from "fs";
1229
+ import { readFileSync as readFileSync10, statSync as statSync4 } from "fs";
1204
1230
  import { basename as basename2, extname, isAbsolute, resolve as resolve3 } from "path";
1205
1231
  var MAX_DELIVER_BYTES = 25 * 1024 * 1024;
1206
1232
  var MIME = {
@@ -1251,15 +1277,15 @@ function deliverFileTool(cwd, sink) {
1251
1277
  }
1252
1278
  const name = basename2(abs);
1253
1279
  const mimeType = MIME[extname(abs).toLowerCase()] ?? "application/octet-stream";
1254
- sink({ name, mimeType, data: readFileSync9(abs).toString("base64") });
1280
+ sink({ name, mimeType, data: readFileSync10(abs).toString("base64") });
1255
1281
  return `Delivered "${name}" (${mimeType}) to the user.`;
1256
1282
  }
1257
1283
  };
1258
1284
  }
1259
1285
 
1260
1286
  // ../daemon/src/runtime/tools/home.ts
1261
- import { readdirSync as readdirSync6, readFileSync as readFileSync10, statSync as statSync5, writeFileSync as writeFileSync6 } from "fs";
1262
- import { join as join14 } from "path";
1287
+ import { readdirSync as readdirSync6, readFileSync as readFileSync11, statSync as statSync5, writeFileSync as writeFileSync7 } from "fs";
1288
+ import { join as join15 } from "path";
1263
1289
  var HOME_FILES_READABLE = [
1264
1290
  "IDENTITY.md",
1265
1291
  "SOUL.md",
@@ -1296,9 +1322,9 @@ function homeTools(agentDir) {
1296
1322
  `home_read: "file" must be one of ${HOME_FILES_READABLE.join(", ")}; got "${file}"`
1297
1323
  );
1298
1324
  }
1299
- const path = join14(agentDir, file);
1325
+ const path = join15(agentDir, file);
1300
1326
  try {
1301
- return readFileSync10(path, "utf8");
1327
+ return readFileSync11(path, "utf8");
1302
1328
  } catch (err) {
1303
1329
  const msg = err instanceof Error ? err.message : String(err);
1304
1330
  throw new Error(`home_read: could not read ${file}: ${msg}`);
@@ -1308,7 +1334,7 @@ function homeTools(agentDir) {
1308
1334
  {
1309
1335
  def: {
1310
1336
  name: "home_write",
1311
- description: "Overwrite one of your own home files. Use this to update your name, personality, or persistent self-definition. Do NOT use this for work output (use `write` / `edit` \u2014 those land in your group's shared directory) or for facts you want to remember (use `memory_write`). BOOTSTRAP.md is not writable here; call `bootstrap_done` to retire it.",
1337
+ description: "Overwrite one of your own home files. Use this to update your name, personality, or persistent self-definition. Do NOT use this for work output (use `write` / `edit` \u2014 those land in your team's shared directory) or for facts you want to remember (use `memory_write`). BOOTSTRAP.md is not writable here; call `bootstrap_done` to retire it.",
1312
1338
  parameters: {
1313
1339
  type: "object",
1314
1340
  properties: {
@@ -1326,8 +1352,8 @@ function homeTools(agentDir) {
1326
1352
  );
1327
1353
  }
1328
1354
  const content = typeof args.content === "string" ? args.content : "";
1329
- const path = join14(agentDir, file);
1330
- writeFileSync6(path, content, "utf8");
1355
+ const path = join15(agentDir, file);
1356
+ writeFileSync7(path, content, "utf8");
1331
1357
  return `wrote ${file} (${Buffer.byteLength(content, "utf8")} bytes)`;
1332
1358
  }
1333
1359
  },
@@ -1340,7 +1366,7 @@ function homeTools(agentDir) {
1340
1366
  async invoke() {
1341
1367
  const entries = [];
1342
1368
  for (const file of HOME_FILES_READABLE) {
1343
- const path = join14(agentDir, file);
1369
+ const path = join15(agentDir, file);
1344
1370
  try {
1345
1371
  const s = statSync5(path);
1346
1372
  entries.push(`${file} (${s.size}b)`);
@@ -1381,7 +1407,7 @@ function memoryTools(memory) {
1381
1407
  {
1382
1408
  def: {
1383
1409
  name: "memory_write",
1384
- description: 'Write or update a memory note in the GROUP-SHARED memory. All agents in this group can read what you write. Use it for project knowledge, codebase notes, decisions, and findings \u2014 anything other agents in the group should benefit from. For personal notes about yourself (preferences, persona) use `home_write` on IDENTITY.md. For STABLE facts about the human you\'re working with (their preferences, role, working hours, how they like to be addressed) use `user_md_get` then `user_md_write` \u2014 those land in every agent\'s system prompt directly. Key is a path-like string with a markdown extension, e.g. "auth-flow.md" or "decisions/2026-05-migration.md".',
1410
+ description: 'Write or update a memory note in the GROUP-SHARED memory. All agents in this team can read what you write. Use it for project knowledge, codebase notes, decisions, and findings \u2014 anything other agents in the team should benefit from. For personal notes about yourself (preferences, persona) use `home_write` on IDENTITY.md. For STABLE facts about the human you\'re working with (their preferences, role, working hours, how they like to be addressed) use `user_md_get` then `user_md_write` \u2014 those land in every agent\'s system prompt directly. Key is a path-like string with a markdown extension, e.g. "auth-flow.md" or "decisions/2026-05-migration.md".',
1385
1411
  parameters: {
1386
1412
  type: "object",
1387
1413
  properties: {
@@ -1402,7 +1428,7 @@ function memoryTools(memory) {
1402
1428
  {
1403
1429
  def: {
1404
1430
  name: "memory_search",
1405
- description: "Search the group-shared memory by substring. Returns matching entry keys with short snippets around the match.",
1431
+ description: "Search the team-shared memory by substring. Returns matching entry keys with short snippets around the match.",
1406
1432
  parameters: {
1407
1433
  type: "object",
1408
1434
  properties: {
@@ -1424,7 +1450,7 @@ function memoryTools(memory) {
1424
1450
  {
1425
1451
  def: {
1426
1452
  name: "memory_read",
1427
- description: "Read a single entry from the group-shared memory by key.",
1453
+ description: "Read a single entry from the team-shared memory by key.",
1428
1454
  parameters: {
1429
1455
  type: "object",
1430
1456
  properties: { key: { type: "string" } },
@@ -1441,7 +1467,7 @@ function memoryTools(memory) {
1441
1467
  {
1442
1468
  def: {
1443
1469
  name: "memory_list",
1444
- description: "List every entry in the group-shared memory with its byte size.",
1470
+ description: "List every entry in the team-shared memory with its byte size.",
1445
1471
  parameters: { type: "object", properties: {} }
1446
1472
  },
1447
1473
  async invoke() {
@@ -1467,7 +1493,7 @@ function messagingTools(host, fromAgentId) {
1467
1493
  {
1468
1494
  def: {
1469
1495
  name: "send_message",
1470
- description: `Send a message to another agent. Use the recipient's agent id (UUID). Use this ONLY for things the recipient needs to ACT on: delegating a task, asking a peer for information you cannot get yourself, escalating a decision. Do NOT use it for status updates or to announce changes to group-shared resources \u2014 USER.md and the group memory backend both propagate to every agent in the group automatically on their next turn, so messages like "I updated USER.md" or "I wrote a new memory note" are pure noise and will trigger an inbox-wake loop on the recipient.`,
1496
+ description: `Send a message to another agent. Use the recipient's agent id (UUID). Use this ONLY for things the recipient needs to ACT on: delegating a task, asking a peer for information you cannot get yourself, escalating a decision. Do NOT use it for status updates or to announce changes to team-shared resources \u2014 USER.md and the team memory backend both propagate to every agent in the team automatically on their next turn, so messages like "I updated USER.md" or "I wrote a new memory note" are pure noise and will trigger an inbox-wake loop on the recipient.`,
1471
1497
  parameters: {
1472
1498
  type: "object",
1473
1499
  properties: {
@@ -1499,6 +1525,31 @@ function messagingTools(host, fromAgentId) {
1499
1525
  return `sent message ${messageId}`;
1500
1526
  }
1501
1527
  },
1528
+ {
1529
+ def: {
1530
+ name: "approval_status",
1531
+ description: "Check the current status of a communication approval request that you created.",
1532
+ parameters: {
1533
+ type: "object",
1534
+ properties: {
1535
+ approval_id: {
1536
+ type: "string",
1537
+ description: "Approval request id returned by a protected communication attempt"
1538
+ }
1539
+ },
1540
+ required: ["approval_id"]
1541
+ }
1542
+ },
1543
+ async invoke(args) {
1544
+ const approvalId = String(args.approval_id ?? "");
1545
+ if (!approvalId) throw new Error('approval_status: "approval_id" is required');
1546
+ const approval = await host.approvalStatus(fromAgentId, approvalId);
1547
+ if (!approval) throw new Error(`approval_status: approval not found: ${approvalId}`);
1548
+ const decision = approval.decidedBy ? `; decided by ${approval.decidedBy}${approval.decisionReason ? ` (${approval.decisionReason})` : ""}` : "";
1549
+ const failure = approval.deliveryError ? `; delivery error: ${approval.deliveryError}` : "";
1550
+ return `approval ${approval.id}: ${approval.status}; expires ${approval.expiresAt}${decision}${failure}`;
1551
+ }
1552
+ },
1502
1553
  {
1503
1554
  def: {
1504
1555
  name: "read_inbox",
@@ -1572,19 +1623,19 @@ function messagingTools(host, fromAgentId) {
1572
1623
  }
1573
1624
 
1574
1625
  // ../daemon/src/runtime/tools/user-md.ts
1575
- function userMdTools(host, groupId) {
1626
+ function userMdTools(host, teamId) {
1576
1627
  return [
1577
1628
  {
1578
1629
  def: {
1579
1630
  name: "user_md_get",
1580
- description: "Read the group-shared USER.md (facts every agent in the group knows about the human). Returns the current content followed by an `etag:` line \u2014 you MUST pass that etag back as `if_match` on the next `user_md_write` so the daemon can detect concurrent edits by other agents in the group. Always call this immediately before any `user_md_write`.",
1631
+ description: "Read the team-shared USER.md (facts every agent in the team knows about the human). Returns the current content followed by an `etag:` line \u2014 you MUST pass that etag back as `if_match` on the next `user_md_write` so the daemon can detect concurrent edits by other agents in the team. Always call this immediately before any `user_md_write`.",
1581
1632
  parameters: {
1582
1633
  type: "object",
1583
1634
  properties: {}
1584
1635
  }
1585
1636
  },
1586
1637
  async invoke() {
1587
- const { content, etag } = await host.get(groupId);
1638
+ const { content, etag } = await host.get(teamId);
1588
1639
  const body = content.length > 0 ? content : "(USER.md is empty)";
1589
1640
  return `${body}
1590
1641
 
@@ -1595,7 +1646,7 @@ etag: ${etag}`;
1595
1646
  {
1596
1647
  def: {
1597
1648
  name: "user_md_write",
1598
- description: "Replace the group-shared USER.md with new content. Use this for STABLE user-specific facts (preferences, role, working hours, how the human likes to be addressed). MANDATORY workflow: (1) call `user_md_get` first, (2) integrate your change into the full content preserving everything unrelated, (3) call `user_md_write` with the merged content and the etag you got from `user_md_get`. If another agent in the group wrote to USER.md between your get and write, this returns an etag-mismatch error \u2014 just call `user_md_get` again and retry the merge. The full result must fit under 12 KB. For project knowledge use `memory_write`; for notes about yourself use `home_write` on IDENTITY.md.",
1649
+ description: "Replace the team-shared USER.md with new content. Use this for STABLE user-specific facts (preferences, role, working hours, how the human likes to be addressed). MANDATORY workflow: (1) call `user_md_get` first, (2) integrate your change into the full content preserving everything unrelated, (3) call `user_md_write` with the merged content and the etag you got from `user_md_get`. If another agent in the team wrote to USER.md between your get and write, this returns an etag-mismatch error \u2014 just call `user_md_get` again and retry the merge. The full result must fit under 12 KB. For project knowledge use `memory_write`; for notes about yourself use `home_write` on IDENTITY.md.",
1599
1650
  parameters: {
1600
1651
  type: "object",
1601
1652
  properties: {
@@ -1619,7 +1670,7 @@ etag: ${etag}`;
1619
1670
  'user_md_write: "if_match" is required \u2014 call user_md_get first to obtain the current etag.'
1620
1671
  );
1621
1672
  }
1622
- const { etag, totalBytes } = await host.write(groupId, content, ifMatch);
1673
+ const { etag, totalBytes } = await host.write(teamId, content, ifMatch);
1623
1674
  return `wrote USER.md (${totalBytes} bytes, new etag: ${etag})`;
1624
1675
  }
1625
1676
  }
@@ -2225,7 +2276,7 @@ function createBazilionCustomTools(opts) {
2225
2276
  handlers.push(...messagingTools(opts.messagingHost, opts.agent.agent.id));
2226
2277
  }
2227
2278
  if (opts.userMdHost) {
2228
- handlers.push(...userMdTools(opts.userMdHost, opts.agent.group.id));
2279
+ handlers.push(...userMdTools(opts.userMdHost, opts.agent.team.id));
2229
2280
  }
2230
2281
  if (opts.browserHost) {
2231
2282
  handlers.push(...browserTools(opts.browserHost, opts.agent.agent.id));
@@ -2234,7 +2285,7 @@ function createBazilionCustomTools(opts) {
2234
2285
  handlers.push(...mcpProxyTools(opts.mcpHost, opts.mcpTools));
2235
2286
  }
2236
2287
  if (opts.fileSink) {
2237
- handlers.push(deliverFileTool(opts.agent.group.path, opts.fileSink));
2288
+ handlers.push(deliverFileTool(opts.agent.team.path, opts.fileSink));
2238
2289
  }
2239
2290
  return handlers.map(ourToolToPiTool);
2240
2291
  }
@@ -2284,9 +2335,9 @@ async function createBazilionSession(opts) {
2284
2335
  apiKey: apiKey ?? "dummy"
2285
2336
  });
2286
2337
  }
2287
- const cwd = agent.group.path;
2288
- if (!existsSync12(cwd)) mkdirSync5(cwd, { recursive: true });
2289
- const sessionDir = join15(paths.agentDir(agent.agent.id), "sessions");
2338
+ const cwd = agent.team.path;
2339
+ if (!existsSync13(cwd)) mkdirSync5(cwd, { recursive: true });
2340
+ const sessionDir = join16(paths.agentDir(agent.agent.id), "sessions");
2290
2341
  mkdirSync5(sessionDir, { recursive: true });
2291
2342
  const existing = findMostRecent(sessionDir);
2292
2343
  const sessionManager = existing ? SessionManager.open(existing, sessionDir, cwd) : SessionManager.create(cwd, sessionDir);
@@ -2316,7 +2367,7 @@ async function createBazilionSession(opts) {
2316
2367
  const allowedTools = [...BUILTIN_TOOL_NAMES, ...customTools.map((t) => t.name)];
2317
2368
  const { session } = await createAgentSession({
2318
2369
  cwd,
2319
- agentDir: join15(paths.home, "pi"),
2370
+ agentDir: join16(paths.home, "pi"),
2320
2371
  model,
2321
2372
  thinkingLevel: toPiThinkingLevel(agent.reasoningLevel),
2322
2373
  tools: allowedTools,
@@ -2442,11 +2493,11 @@ function createBazilionResourceLoader(appendSystemPrompt) {
2442
2493
  };
2443
2494
  }
2444
2495
  function findMostRecent(sessionDir) {
2445
- if (!existsSync12(sessionDir)) return null;
2496
+ if (!existsSync13(sessionDir)) return null;
2446
2497
  let newest = null;
2447
2498
  for (const entry of readdirSync7(sessionDir)) {
2448
2499
  if (!entry.endsWith(".jsonl")) continue;
2449
- const path = join15(sessionDir, entry);
2500
+ const path = join16(sessionDir, entry);
2450
2501
  try {
2451
2502
  const s = statSync6(path);
2452
2503
  if (!newest || s.mtimeMs > newest.mtimeMs) newest = { path, mtimeMs: s.mtimeMs };
@@ -2490,7 +2541,7 @@ function createIpcClient() {
2490
2541
  if (!process.send) {
2491
2542
  return Promise.reject(new Error("worker: no IPC channel \u2014 daemon must spawn with stdio:ipc"));
2492
2543
  }
2493
- const id = randomUUID6();
2544
+ const id = randomUUID14();
2494
2545
  const message = { type: "rpc", id, method, args };
2495
2546
  return new Promise((resolve4, reject) => {
2496
2547
  pending.set(id, { resolve: (v) => resolve4(v), reject });
@@ -2511,13 +2562,14 @@ function createIpcMessagingHost(call) {
2511
2562
  markRead: async (messageId) => {
2512
2563
  await call("markRead", { messageId });
2513
2564
  },
2514
- findReplies: (agentId, replyTo) => call("findReplies", { agentId, replyTo })
2565
+ findReplies: (agentId, replyTo) => call("findReplies", { agentId, replyTo }),
2566
+ approvalStatus: (agentId, approvalId) => call("approvalStatus", { agentId, approvalId })
2515
2567
  };
2516
2568
  }
2517
2569
  function createIpcUserMdHost(call) {
2518
2570
  return {
2519
- get: (groupId) => call("userMdGet", { groupId }),
2520
- write: (groupId, content, ifMatch) => call("userMdWrite", { groupId, content, ifMatch })
2571
+ get: (teamId) => call("userMdGet", { teamId }),
2572
+ write: (teamId, content, ifMatch) => call("userMdWrite", { teamId, content, ifMatch })
2521
2573
  };
2522
2574
  }
2523
2575
  function createIpcBrowserHost(call) {
@@ -2554,7 +2606,7 @@ async function main() {
2554
2606
  process.on("SIGINT", onSignal);
2555
2607
  const { agent, message, enabledProviders, apiKey, browserEnabled, mcpTools, images } = await readInput();
2556
2608
  const paths = resolvePaths();
2557
- const memory = qmdBackend(join16(agent.group.path, "memory"));
2609
+ const memory = qmdBackend(join17(agent.team.path, "memory"));
2558
2610
  await memory.init();
2559
2611
  const ipcCall = createIpcClient();
2560
2612
  const messagingHost = createIpcMessagingHost(ipcCall);