@desplega.ai/agent-swarm 1.113.0 → 1.115.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 (237) hide show
  1. package/README.md +2 -2
  2. package/dist/{actions-q4n7cz6e.js → actions-17ya5wde.js} +8 -9
  3. package/dist/{app-es4nzc71.js → app-4f718yk0.js} +6 -6
  4. package/dist/{assistant-0x8ey0vs.js → assistant-ah7csnjz.js} +19 -18
  5. package/dist/{boot-reembed-69agkhv6.js → boot-reembed-4jpxhb25.js} +6 -6
  6. package/dist/{boot-reembed-p0ny05t8.js → boot-reembed-qata34xa.js} +5 -5
  7. package/dist/{boot-scrub-logs-yybrkmvr.js → boot-scrub-logs-tv48nn3z.js} +4 -4
  8. package/dist/{claude-adapter-mma9a1yr.js → claude-adapter-3csn5bks.js} +3 -3
  9. package/dist/{claude-managed-adapter-pv2nbqy4.js → claude-managed-adapter-kysmkz89.js} +2 -2
  10. package/dist/cli-0pygq9r1.js +429 -0
  11. package/dist/{cli-hsetkkd3.js → cli-12vb0xg6.js} +33 -9
  12. package/dist/{cli-ncfgsqbd.js → cli-15y7qhzp.js} +262 -33
  13. package/dist/{cli-7ga43spr.js → cli-1yjrbg1f.js} +1 -1
  14. package/dist/{cli-36ymmpmp.js → cli-3samkyap.js} +2 -2
  15. package/dist/cli-52fg7s7x.js +269 -0
  16. package/dist/{cli-hjhvekf4.js → cli-65ekje01.js} +11 -8
  17. package/dist/{cli-h3k622d0.js → cli-6aq8xhvm.js} +90 -3
  18. package/dist/{cli-f3qa069v.js → cli-7xje5amz.js} +1 -1
  19. package/dist/cli-86fdnerz.js +405 -0
  20. package/dist/{cli-9cy6nc5m.js → cli-8fjwym53.js} +1 -1
  21. package/dist/{cli-c3frqf65.js → cli-b23axgz4.js} +3 -3
  22. package/dist/{cli-a0t7vapf.js → cli-bc89my0z.js} +1 -1
  23. package/dist/{cli-bnzbn8j8.js → cli-beea4a3y.js} +73 -24
  24. package/dist/{cli-q21d49ac.js → cli-bw80ck94.js} +1 -1
  25. package/dist/{cli-pwc5e83c.js → cli-cchksf5q.js} +12 -7
  26. package/dist/{cli-30bbaveh.js → cli-cmw9rzy5.js} +2 -2
  27. package/dist/{cli-y6mrptcn.js → cli-cnwssmsr.js} +1 -1
  28. package/dist/{cli-r5g6ngtn.js → cli-dcca6j8m.js} +46 -5
  29. package/dist/{cli-tkmm5nf9.js → cli-e61fs2hp.js} +59 -2
  30. package/dist/{cli-6wscj9z0.js → cli-e7306swv.js} +14 -14
  31. package/dist/{cli-dcfyyh3t.js → cli-ftyf58xj.js} +2 -2
  32. package/dist/{cli-4xyj9jtq.js → cli-hrhye2rm.js} +1062 -478
  33. package/dist/cli-jkhwmmgg.js +136 -0
  34. package/dist/{cli-y4ycrnjc.js → cli-k3y4z3h5.js} +1 -1
  35. package/dist/{cli-6xd0bvf8.js → cli-ma04faw5.js} +1 -1
  36. package/dist/{cli-2fc97xm5.js → cli-mnbgv3w7.js} +4 -4
  37. package/dist/{cli-trmapn9k.js → cli-pet3aev6.js} +95 -10
  38. package/dist/{cli-z46pnksz.js → cli-q1rx7g0d.js} +175 -28
  39. package/dist/{cli-qwgtacd6.js → cli-r9f6ngrf.js} +1244 -336
  40. package/dist/{cli-gtkqc144.js → cli-shvaxw27.js} +13 -7
  41. package/dist/{cli-ywez6yps.js → cli-sq7f72d6.js} +1 -1
  42. package/dist/cli-t0vqevnm.js +393 -0
  43. package/dist/{cli-tbw13sx8.js → cli-tece6zgm.js} +1 -1
  44. package/dist/{cli-bgvskydy.js → cli-tffvrh6j.js} +1 -1
  45. package/dist/cli-wh91zby6.js +187222 -0
  46. package/dist/{cli-anrj584m.js → cli-xz9aq0rf.js} +1 -1
  47. package/dist/{cli-mq580e06.js → cli-zsrdty74.js} +18 -18
  48. package/dist/cli.js +32 -15
  49. package/dist/{codex-adapter-5cmy858w.js → codex-adapter-de3w0nch.js} +10 -10
  50. package/dist/{codex-session-runner-46q8mrba.js → codex-session-runner-bnw8cysk.js} +10 -10
  51. package/dist/{commands-z5dbwta3.js → commands-hch4e2k1.js} +4 -4
  52. package/dist/{db-bbgahh4z.js → db-p3h2j06x.js} +14 -4
  53. package/dist/{handlers-6b44317z.js → handlers-9er4zx9q.js} +17 -31
  54. package/dist/{hook-sbp5fmps.js → hook-4axs756z.js} +7 -7
  55. package/dist/{http-2xz43gz3.js → http-809fvtz2.js} +1934 -886
  56. package/dist/{index-wz1ea15p.js → index-2dgfj9av.js} +3 -3
  57. package/dist/{index-nhat35em.js → index-47em3d2n.js} +14 -11
  58. package/dist/{index-5ghxn8s6.js → index-9fqaktjr.js} +12 -9
  59. package/dist/{index-0gzmqj4k.js → index-9ht8gr56.js} +13 -10
  60. package/dist/{index-vfedgdw6.js → index-rm85cfdx.js} +368 -40
  61. package/dist/{index-ykvs43z4.js → index-t2snazez.js} +4 -4
  62. package/dist/{keepalive-62gfj91d.js → keepalive-3cps6e3e.js} +7 -6
  63. package/dist/{lead-ag0akn0v.js → lead-fkk95wgq.js} +36 -32
  64. package/dist/{maintenance-xxrrzk5x.js → maintenance-fweqh0yj.js} +6 -6
  65. package/dist/{mistral-conversations-26yrnbf1.js → mistral-conversations-7gqnz2wt.js} +7 -7
  66. package/dist/oauth-refresh-sweep-sycqtbph.js +114 -0
  67. package/dist/{onboard-64zyfcbs.js → onboard-cy0rkgvx.js} +2 -2
  68. package/dist/{opencode-adapter-mqsxr170.js → opencode-adapter-p6bxnbm4.js} +2 -2
  69. package/dist/{otel-zjd9zaxs.js → otel-g299k41b.js} +2 -2
  70. package/dist/{otel-impl-b86qseaa.js → otel-impl-wbns8hf7.js} +1 -1
  71. package/dist/{pi-mono-adapter-kxjxpfgy.js → pi-mono-adapter-05sck1ds.js} +17 -109
  72. package/dist/{pricing-refresh-cgtkffpa.js → pricing-refresh-0hvazmkf.js} +6 -6
  73. package/dist/rbac-roles-kfesjy9y.js +28 -0
  74. package/dist/rbac-roles-mwcwhbxc.js +283 -0
  75. package/dist/{seed-pricing-1r1y1xkq.js → seed-pricing-h2kdq4cq.js} +5 -5
  76. package/dist/{setup-mkcgkjf7.js → setup-8506q97w.js} +2 -2
  77. package/dist/{worker-351sze63.js → worker-4r5c6zyb.js} +36 -32
  78. package/openapi.json +1327 -20
  79. package/package.json +3 -3
  80. package/src/agentmail/handlers.ts +16 -6
  81. package/src/agentmail/templates.ts +25 -5
  82. package/src/be/audit-user.ts +28 -4
  83. package/src/be/db-queries/oauth.ts +42 -0
  84. package/src/be/db.ts +314 -28
  85. package/src/be/identity.ts +79 -0
  86. package/src/be/mcp-proxy.ts +132 -0
  87. package/src/be/migrations/109_rbac_roles.sql +79 -0
  88. package/src/be/migrations/111_oauth_credential_bindings.sql +6 -0
  89. package/src/be/migrations/112_script_connections_graphql.sql +96 -0
  90. package/src/be/migrations/113_task_routing_affinity.sql +9 -0
  91. package/src/be/migrations/114_backfill_gpt_5_6_pricing.sql +15 -0
  92. package/src/be/modelsdev-cache.json +135 -0
  93. package/src/be/oauth-credential-bindings.ts +35 -0
  94. package/src/be/oauth-refresh-sweep.ts +159 -0
  95. package/src/be/rbac-audit.ts +52 -13
  96. package/src/be/rbac-roles.ts +424 -0
  97. package/src/be/script-connections.ts +459 -40
  98. package/src/be/script-credential-broker.ts +29 -3
  99. package/src/be/scripts/typecheck.ts +51 -7
  100. package/src/be/seed-scripts/catalog/catalog-report.inline.ts +325 -24
  101. package/src/be/seed-scripts/catalog/catalog-report.ts +325 -24
  102. package/src/be/users.ts +24 -0
  103. package/src/cli.tsx +17 -0
  104. package/src/github/handlers.ts +10 -9
  105. package/src/github/templates.ts +45 -9
  106. package/src/gitlab/handlers.ts +20 -8
  107. package/src/gitlab/templates.ts +18 -6
  108. package/src/heartbeat/heartbeat.ts +143 -21
  109. package/src/http/all-routes.ts +3 -0
  110. package/src/http/approval-requests.ts +12 -0
  111. package/src/http/config.ts +44 -10
  112. package/src/http/core.ts +30 -3
  113. package/src/http/favorites.ts +1 -5
  114. package/src/http/index.ts +25 -1
  115. package/src/http/mcp-oauth.ts +2 -0
  116. package/src/http/mcp-servers.ts +44 -3
  117. package/src/http/oauth-generic.ts +105 -0
  118. package/src/http/poll.ts +20 -3
  119. package/src/http/script-connection-proxy.ts +116 -0
  120. package/src/http/script-connections.ts +1657 -0
  121. package/src/http/scripts.ts +27 -7
  122. package/src/http/skills.ts +11 -0
  123. package/src/http/tasks.ts +27 -13
  124. package/src/http/x.ts +6 -2
  125. package/src/integrations/kapso/inbound.ts +23 -6
  126. package/src/jira/sync.ts +111 -17
  127. package/src/jira/templates.ts +10 -2
  128. package/src/mcp-client/http-client.ts +194 -0
  129. package/src/oauth/app-validation.ts +16 -0
  130. package/src/oauth/ensure-token.ts +69 -14
  131. package/src/oauth/mcp-wrapper.ts +15 -0
  132. package/src/oauth/wrapper.ts +48 -20
  133. package/src/prompts/session-templates.ts +3 -3
  134. package/src/providers/codex-models.ts +100 -30
  135. package/src/providers/modelsdev-reasoning.json +51 -0
  136. package/src/providers/pi-mono-mcp-client.ts +2 -133
  137. package/src/providers/reasoning-effort.ts +11 -5
  138. package/src/rbac/admission.ts +68 -0
  139. package/src/rbac/index.ts +2 -0
  140. package/src/rbac/legacy-policy.ts +12 -0
  141. package/src/rbac/permissions.ts +48 -0
  142. package/src/scheduler/scheduler.ts +9 -1
  143. package/src/scripts-runtime/api-client.ts +151 -19
  144. package/src/scripts-runtime/api-types.ts +38 -6
  145. package/src/scripts-runtime/credential-broker/default-bindings.ts +1 -0
  146. package/src/scripts-runtime/credential-broker/types.ts +8 -0
  147. package/src/scripts-runtime/ctx.ts +11 -1
  148. package/src/scripts-runtime/eval-harness.ts +5 -1
  149. package/src/scripts-runtime/executors/types.ts +2 -1
  150. package/src/scripts-runtime/loader.ts +3 -1
  151. package/src/scripts-runtime/mcp-client.ts +87 -0
  152. package/src/scripts-runtime/sdk-allowlist.ts +1 -0
  153. package/src/scripts-runtime/types/stdlib.d.ts +6 -0
  154. package/src/scripts-runtime/types/swarm-sdk.d.ts +19 -0
  155. package/src/server-user.ts +114 -59
  156. package/src/server.ts +12 -0
  157. package/src/slack/assistant.ts +14 -6
  158. package/src/slack/enrich.ts +17 -0
  159. package/src/slack/handlers.ts +8 -22
  160. package/src/slack/responses.ts +91 -1
  161. package/src/slack/thread-buffer.ts +6 -3
  162. package/src/slack/watcher.ts +9 -6
  163. package/src/tasks/worker-follow-up.ts +100 -3
  164. package/src/tests/agentmail-handlers.test.ts +32 -3
  165. package/src/tests/approval-requests.test.ts +61 -0
  166. package/src/tests/audit-user.test.ts +47 -1
  167. package/src/tests/codex-adapter.test.ts +46 -23
  168. package/src/tests/credential-broker.test.ts +5 -2
  169. package/src/tests/delete-page-tool.test.ts +197 -0
  170. package/src/tests/github-handlers.test.ts +28 -2
  171. package/src/tests/gitlab-handlers.test.ts +125 -0
  172. package/src/tests/heartbeat.test.ts +48 -3
  173. package/src/tests/identity.test.ts +117 -0
  174. package/src/tests/jira-sync.test.ts +99 -1
  175. package/src/tests/kapso-inbound.test.ts +7 -0
  176. package/src/tests/mcp-tools-user.test.ts +60 -6
  177. package/src/tests/model-control.test.ts +8 -2
  178. package/src/tests/oauth-credential-bindings.test.ts +490 -0
  179. package/src/tests/oauth-refresh-sweep.test.ts +160 -0
  180. package/src/tests/pool-affinity.test.ts +401 -0
  181. package/src/tests/prompt-template-remaining.test.ts +2 -2
  182. package/src/tests/rbac-admission-e2e.test.ts +386 -0
  183. package/src/tests/rbac-admission.test.ts +492 -0
  184. package/src/tests/rbac-e2e-helpers.ts +3 -0
  185. package/src/tests/rbac-engine.test.ts +50 -0
  186. package/src/tests/rbac-mcp-admission-e2e.test.ts +362 -0
  187. package/src/tests/rbac-roles.test.ts +328 -0
  188. package/src/tests/reasoning-effort.test.ts +15 -2
  189. package/src/tests/schedule-target-type.test.ts +50 -0
  190. package/src/tests/scheduled-tasks.test.ts +40 -0
  191. package/src/tests/script-apis-mcp.test.ts +37 -13
  192. package/src/tests/script-connections-http.test.ts +1158 -0
  193. package/src/tests/script-connections-mcp.test.ts +894 -0
  194. package/src/tests/script-connections.test.ts +754 -6
  195. package/src/tests/scripts-external-api.test.ts +49 -1
  196. package/src/tests/scripts-runtime-secret-egress.test.ts +1 -0
  197. package/src/tests/scripts-runtime.test.ts +291 -0
  198. package/src/tests/seed-scripts.test.ts +36 -0
  199. package/src/tests/slack-identity-resolution.test.ts +37 -3
  200. package/src/tests/slack-inline-output.test.ts +65 -0
  201. package/src/tests/slack-thread-buffer.test.ts +28 -0
  202. package/src/tests/tool-annotations.test.ts +1 -0
  203. package/src/tests/user-token-rest-auth.test.ts +140 -1
  204. package/src/tests/workflow-swarm-script.test.ts +44 -0
  205. package/src/tests/workflow-triggers-v2.test.ts +300 -1
  206. package/src/tools/credential-bindings/tool.ts +277 -18
  207. package/src/tools/delete-page.ts +145 -0
  208. package/src/tools/mcp-servers/mcp-server-delete.ts +7 -4
  209. package/src/tools/request-human-input.ts +2 -0
  210. package/src/tools/resolve-user.ts +77 -27
  211. package/src/tools/script-apis.ts +62 -3
  212. package/src/tools/script-connections/tool.ts +275 -31
  213. package/src/tools/send-task.ts +15 -1
  214. package/src/tools/task-action.ts +34 -2
  215. package/src/tools/templates.ts +53 -1
  216. package/src/tools/tool-config.ts +2 -1
  217. package/src/tools/utils.ts +2 -0
  218. package/src/tools/workflows/create-workflow.ts +8 -1
  219. package/src/tools/workflows/update-workflow.ts +11 -2
  220. package/src/types.ts +90 -11
  221. package/src/utils/scoped-resource.ts +25 -0
  222. package/src/workflows/executors/human-in-the-loop.ts +1 -0
  223. package/src/workflows/executors/swarm-script.ts +7 -1
  224. package/src/workflows/triggers.ts +146 -18
  225. package/templates/skills/swarm-scripts/content.md +33 -8
  226. package/dist/cli-bgef578c.js +0 -771
  227. package/dist/cli-c9mtm09b.js +0 -43
  228. package/dist/cli-ceewqajw.js +0 -1698
  229. package/dist/{anthropic-messages-8nc6r2dw.js → anthropic-messages-kq3pjhbp.js} +6 -6
  230. package/dist/{azure-openai-responses-6yfzw3qw.js → azure-openai-responses-gm1ejtmn.js} +7 -7
  231. package/dist/{cli-vbraamxr.js → cli-6b4wwmm8.js} +9 -9
  232. package/dist/{cli-2r7s8jhp.js → cli-sznberje.js} +3 -3
  233. package/dist/{google-generative-ai-vfq6ymz9.js → google-generative-ai-hyrra2jm.js} +3 -3
  234. package/dist/{google-vertex-mj5y5rfj.js → google-vertex-8bs2pzgn.js} +3 -3
  235. package/dist/{openai-codex-responses-8h6kvfv8.js → openai-codex-responses-3nkvje79.js} +4 -4
  236. package/dist/{openai-completions-x6kjnqjd.js → openai-completions-0asftkwg.js} +11 -11
  237. package/dist/{openai-responses-7jwyz3ds.js → openai-responses-pmatek45.js} +10 -10
@@ -0,0 +1,283 @@
1
+ import {
2
+ PermissionVerbSchema
3
+ } from "./cli-86fdnerz.js";
4
+ import {
5
+ getDb,
6
+ init_db
7
+ } from "./cli-15y7qhzp.js";
8
+ import"./cli-z2zcxes1.js";
9
+ import"./cli-bw80ck94.js";
10
+ import"./cli-xz9aq0rf.js";
11
+ import"./cli-b23axgz4.js";
12
+ import"./cli-4j2mrzag.js";
13
+ import"./cli-p9swy5t3.js";
14
+
15
+ // src/be/rbac-roles.ts
16
+ init_db();
17
+ var DEFAULT_ROLE_ID = "rbac-role-admin";
18
+ var BUILTIN_ROLES = [
19
+ {
20
+ id: DEFAULT_ROLE_ID,
21
+ name: "admin",
22
+ description: "Full access including verb-less routes (legacy-equivalent default).",
23
+ isBuiltin: true,
24
+ grantsAll: true,
25
+ verbs: []
26
+ },
27
+ {
28
+ id: "rbac-role-requester",
29
+ name: "requester",
30
+ description: "Own-task lifecycle: what legacy policy grants user principals.",
31
+ isBuiltin: true,
32
+ grantsAll: false,
33
+ verbs: [
34
+ "task.create.own",
35
+ "task.read.own",
36
+ "task.cancel.own",
37
+ "task.action.own",
38
+ "task.fs.mutate",
39
+ "favorite.write.own"
40
+ ]
41
+ }
42
+ ];
43
+ var CREATE_USER_DEFAULT_ROLE_TRIGGER_SQL = `
44
+ CREATE TRIGGER IF NOT EXISTS trg_users_default_role
45
+ AFTER INSERT ON users
46
+ BEGIN
47
+ INSERT OR IGNORE INTO principal_roles (principalType, principalId, roleId)
48
+ SELECT 'user', NEW.id, 'rbac-role-admin'
49
+ WHERE EXISTS (SELECT 1 FROM roles WHERE id = 'rbac-role-admin');
50
+ END;
51
+ `;
52
+ function roleRowToUserRole(row) {
53
+ return {
54
+ id: row.id,
55
+ name: row.name,
56
+ description: row.description,
57
+ isBuiltin: row.isBuiltin === 1,
58
+ grantsAll: row.grantsAll === 1,
59
+ createdAt: row.createdAt
60
+ };
61
+ }
62
+ function requireRoleId(roleName) {
63
+ const row = getDb().prepare("SELECT id FROM roles WHERE name = ?").get(roleName);
64
+ if (!row) {
65
+ throw new Error(`Unknown RBAC role: ${roleName}`);
66
+ }
67
+ return row.id;
68
+ }
69
+ function validateBuiltinVerb(roleName, verb) {
70
+ const parsed = PermissionVerbSchema.safeParse(verb);
71
+ if (!parsed.success) {
72
+ throw new Error(`Invalid RBAC permission verb "${verb}" in built-in role "${roleName}"`);
73
+ }
74
+ return parsed.data;
75
+ }
76
+ function validatedBuiltinVerbSets() {
77
+ const byRoleId = new Map;
78
+ for (const role of BUILTIN_ROLES) {
79
+ const verbs = new Set;
80
+ for (const verb of role.verbs) {
81
+ verbs.add(validateBuiltinVerb(role.name, verb));
82
+ }
83
+ byRoleId.set(role.id, verbs);
84
+ }
85
+ return byRoleId;
86
+ }
87
+ var loggedInvalidGrantVerbs = new Set;
88
+ function parseDatabaseGrantVerb(roleId, verb) {
89
+ const parsed = PermissionVerbSchema.safeParse(verb);
90
+ if (parsed.success) {
91
+ return parsed.data;
92
+ }
93
+ const logKey = `${roleId}:${verb}`;
94
+ if (!loggedInvalidGrantVerbs.has(logKey)) {
95
+ loggedInvalidGrantVerbs.add(logKey);
96
+ console.error(`[rbac] Ignoring invalid role_permissions verb "${verb}" for roleId="${roleId}". ` + "Invalid RBAC verbs grant nothing; remove or repair the row.");
97
+ }
98
+ return null;
99
+ }
100
+ function getUserGrant(userId) {
101
+ const rows = getDb().prepare(`SELECT r.id AS roleId, r.grantsAll, rp.verb
102
+ FROM principal_roles pr
103
+ JOIN roles r ON r.id = pr.roleId
104
+ LEFT JOIN role_permissions rp ON rp.roleId = r.id
105
+ WHERE pr.principalType = 'user' AND pr.principalId = ?
106
+ ORDER BY r.grantsAll DESC`).all(userId);
107
+ if (rows.length === 0) {
108
+ return { grantsAll: false, verbs: new Set };
109
+ }
110
+ const verbs = new Set;
111
+ for (const row of rows) {
112
+ if (row.grantsAll === 1) {
113
+ return { grantsAll: true, verbs: new Set };
114
+ }
115
+ if (row.verb) {
116
+ const verb = parseDatabaseGrantVerb(row.roleId, row.verb);
117
+ if (verb) {
118
+ verbs.add(verb);
119
+ }
120
+ }
121
+ }
122
+ return { grantsAll: false, verbs };
123
+ }
124
+ function attachRole(userId, roleName) {
125
+ const db = getDb();
126
+ db.transaction(() => {
127
+ const roleId = requireRoleId(roleName);
128
+ db.prepare(`INSERT OR IGNORE INTO principal_roles (principalType, principalId, roleId)
129
+ VALUES ('user', ?, ?)`).run(userId, roleId);
130
+ })();
131
+ }
132
+ function detachRole(userId, roleName) {
133
+ const db = getDb();
134
+ db.transaction(() => {
135
+ const roleId = requireRoleId(roleName);
136
+ db.prepare(`DELETE FROM principal_roles
137
+ WHERE principalType = 'user' AND principalId = ? AND roleId = ?`).run(userId, roleId);
138
+ })();
139
+ }
140
+ function listUserRoles(userId) {
141
+ return getDb().prepare(`SELECT r.id, r.name, r.description, r.isBuiltin, r.grantsAll, r.createdAt
142
+ FROM principal_roles pr
143
+ JOIN roles r ON r.id = pr.roleId
144
+ WHERE pr.principalType = 'user' AND pr.principalId = ?
145
+ ORDER BY r.name`).all(userId).map(roleRowToUserRole);
146
+ }
147
+ function ensureRbacSeedsSynced(opts) {
148
+ const db = getDb();
149
+ const desiredVerbsByRoleId = validatedBuiltinVerbSets();
150
+ const insertRole = db.prepare(`INSERT OR IGNORE INTO roles (id, name, description, isBuiltin, grantsAll)
151
+ VALUES (?, ?, ?, 1, ?)`);
152
+ const updateRole = db.prepare(`UPDATE roles
153
+ SET name = ?, description = ?, isBuiltin = 1, grantsAll = ?, lastUpdatedAt = CURRENT_TIMESTAMP
154
+ WHERE id = ?
155
+ AND (
156
+ name <> ?
157
+ OR COALESCE(description, '') <> COALESCE(?, '')
158
+ OR isBuiltin <> 1
159
+ OR grantsAll <> ?
160
+ )`);
161
+ const selectRoleById = db.prepare("SELECT id, name FROM roles WHERE id = ?");
162
+ const selectRoleByName = db.prepare("SELECT id, name FROM roles WHERE name = ?");
163
+ const selectRolePermissions = db.prepare("SELECT verb FROM role_permissions WHERE roleId = ?");
164
+ const deleteRolePermission = db.prepare("DELETE FROM role_permissions WHERE roleId = ? AND verb = ?");
165
+ const insertRolePermission = db.prepare("INSERT OR IGNORE INTO role_permissions (roleId, verb) VALUES (?, ?)");
166
+ const backfillDefaultRoleForZeroRoleUsers = db.prepare(`INSERT OR IGNORE INTO principal_roles (principalType, principalId, roleId)
167
+ SELECT 'user', u.id, ?
168
+ FROM users u
169
+ WHERE NOT EXISTS (
170
+ SELECT 1
171
+ FROM principal_roles pr
172
+ WHERE pr.principalType = 'user'
173
+ AND pr.principalId = u.id
174
+ )`);
175
+ const stats = {
176
+ rolesInserted: 0,
177
+ rolesUpdated: 0,
178
+ permissionsInserted: 0,
179
+ permissionsDeleted: 0,
180
+ usersBackfilled: 0
181
+ };
182
+ db.transaction(() => {
183
+ for (const role of BUILTIN_ROLES) {
184
+ const grantsAll = role.grantsAll ? 1 : 0;
185
+ const insertResult = insertRole.run(role.id, role.name, role.description, grantsAll);
186
+ stats.rolesInserted += insertResult.changes;
187
+ if (insertResult.changes === 0) {
188
+ const updateResult = updateRole.run(role.name, role.description, grantsAll, role.id, role.name, role.description, grantsAll);
189
+ stats.rolesUpdated += updateResult.changes;
190
+ }
191
+ }
192
+ for (const role of BUILTIN_ROLES) {
193
+ const row = selectRoleById.get(role.id);
194
+ if (row) {
195
+ continue;
196
+ }
197
+ const colliding = selectRoleByName.get(role.name);
198
+ if (colliding) {
199
+ throw new Error(`RBAC built-in role "${role.name}" (${role.id}) is missing because role ` + `"${colliding.name}" (${colliding.id}) already uses that name. ` + "Rename or remove the conflicting role, then rerun `rbac bootstrap`.");
200
+ }
201
+ throw new Error(`RBAC built-in role "${role.name}" (${role.id}) is missing after seed sync. ` + "Rerun `rbac bootstrap`; if it still fails, inspect the roles table.");
202
+ }
203
+ for (const role of BUILTIN_ROLES) {
204
+ const desiredVerbs = desiredVerbsByRoleId.get(role.id) ?? new Set;
205
+ const existingRows = selectRolePermissions.all(role.id);
206
+ for (const row of existingRows) {
207
+ if (!desiredVerbs.has(row.verb)) {
208
+ stats.permissionsDeleted += deleteRolePermission.run(role.id, row.verb).changes;
209
+ }
210
+ }
211
+ for (const verb of desiredVerbs) {
212
+ stats.permissionsInserted += insertRolePermission.run(role.id, verb).changes;
213
+ }
214
+ }
215
+ db.run(CREATE_USER_DEFAULT_ROLE_TRIGGER_SQL);
216
+ stats.usersBackfilled += backfillDefaultRoleForZeroRoleUsers.run(DEFAULT_ROLE_ID).changes;
217
+ })();
218
+ if (!opts?.quiet) {
219
+ console.log(`[rbac] seed sync: roles inserted=${stats.rolesInserted}, updated=${stats.rolesUpdated}; permissions inserted=${stats.permissionsInserted}, deleted=${stats.permissionsDeleted}; trigger=ensured; users backfilled=${stats.usersBackfilled}`);
220
+ }
221
+ return stats;
222
+ }
223
+ function describeRbacFlag() {
224
+ const raw = process.env.RBAC_ENABLED;
225
+ if (raw === undefined)
226
+ return "unset (off)";
227
+ return `${raw} (${raw === "true" ? "on" : "off"})`;
228
+ }
229
+ function printRolesTable(rows) {
230
+ const tableRows = rows.map((row) => [
231
+ row.name,
232
+ row.isBuiltin === 1 ? "yes" : "no",
233
+ row.grantsAll === 1 ? "yes" : "no",
234
+ String(row.verbCount),
235
+ String(row.attachedUserCount)
236
+ ]);
237
+ const headers = ["name", "builtin", "grantsAll", "verbs", "attachedUsers"];
238
+ const widths = headers.map((header, column) => Math.max(header.length, ...tableRows.map((row) => row[column]?.length ?? 0)));
239
+ const format = (row) => row.map((cell, column) => cell.padEnd(widths[column] ?? cell.length)).join(" ");
240
+ console.log("Roles:");
241
+ console.log(format(headers));
242
+ console.log(format(widths.map((width) => "-".repeat(width))));
243
+ for (const row of tableRows) {
244
+ console.log(format(row));
245
+ }
246
+ }
247
+ function getRbacRoleSummary() {
248
+ return getDb().prepare(`SELECT
249
+ r.name,
250
+ r.isBuiltin,
251
+ r.grantsAll,
252
+ COUNT(DISTINCT rp.verb) AS verbCount,
253
+ COUNT(DISTINCT CASE WHEN pr.principalType = 'user' THEN pr.principalId END)
254
+ AS attachedUserCount
255
+ FROM roles r
256
+ LEFT JOIN role_permissions rp ON rp.roleId = r.id
257
+ LEFT JOIN principal_roles pr ON pr.roleId = r.id
258
+ GROUP BY r.id, r.name, r.isBuiltin, r.grantsAll
259
+ ORDER BY r.isBuiltin DESC, r.name`).all();
260
+ }
261
+ async function runRbacCliCommand(args) {
262
+ const subcommand = args[0];
263
+ if (args.length !== 1 || subcommand !== "bootstrap") {
264
+ throw new Error(`Unknown RBAC command: ${args.join(" ") || "(none)"}`);
265
+ }
266
+ const stats = ensureRbacSeedsSynced({ quiet: true });
267
+ const roles = getRbacRoleSummary();
268
+ console.log("RBAC bootstrap complete");
269
+ console.log(`RBAC_ENABLED: ${describeRbacFlag()}`);
270
+ console.log(`Users backfilled this run: ${stats.usersBackfilled}`);
271
+ console.log("");
272
+ printRolesTable(roles);
273
+ }
274
+ export {
275
+ runRbacCliCommand,
276
+ listUserRoles,
277
+ getUserGrant,
278
+ ensureRbacSeedsSynced,
279
+ detachRole,
280
+ attachRole,
281
+ DEFAULT_ROLE_ID,
282
+ BUILTIN_ROLES
283
+ };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  buildModelsDevSeedRows,
3
3
  seedPricingFromModelsDev
4
- } from "./cli-tbw13sx8.js";
5
- import"./cli-ncfgsqbd.js";
4
+ } from "./cli-tece6zgm.js";
5
+ import"./cli-15y7qhzp.js";
6
6
  import"./cli-z2zcxes1.js";
7
- import"./cli-q21d49ac.js";
8
- import"./cli-anrj584m.js";
9
- import"./cli-c3frqf65.js";
7
+ import"./cli-bw80ck94.js";
8
+ import"./cli-xz9aq0rf.js";
9
+ import"./cli-b23axgz4.js";
10
10
  import"./cli-4j2mrzag.js";
11
11
  import"./cli-p9swy5t3.js";
12
12
  export {
@@ -4,14 +4,14 @@ import {
4
4
  createDefaultMcpJson,
5
5
  createDefaultSettingsLocal,
6
6
  createHooksConfig
7
- } from "./cli-y6mrptcn.js";
7
+ } from "./cli-cnwssmsr.js";
8
8
  import {
9
9
  require_jsx_dev_runtime
10
10
  } from "./cli-wx82tw1k.js";
11
11
  import {
12
12
  getApiKey
13
13
  } from "./cli-f14fvzag.js";
14
- import"./cli-c3frqf65.js";
14
+ import"./cli-b23axgz4.js";
15
15
  import {
16
16
  Box_default,
17
17
  Spinner,
@@ -1,63 +1,67 @@
1
1
  import {
2
2
  runAgent
3
- } from "./cli-mq580e06.js";
4
- import"./cli-ceewqajw.js";
5
- import"./cli-6wscj9z0.js";
6
- import"./cli-2r7s8jhp.js";
7
- import"./cli-07er7wrs.js";
8
- import"./cli-yv9dttkh.js";
3
+ } from "./cli-zsrdty74.js";
9
4
  import"./cli-tyfxrrdd.js";
10
- import"./cli-a0t7vapf.js";
5
+ import"./cli-bc89my0z.js";
11
6
  import"./cli-yazx6hap.js";
7
+ import"./cli-wh91zby6.js";
12
8
  import"./cli-r94z9p1z.js";
13
- import"./cli-d6n0thxw.js";
9
+ import"./cli-e7306swv.js";
14
10
  import"./cli-hx1dcevq.js";
11
+ import"./cli-sznberje.js";
12
+ import"./cli-07er7wrs.js";
13
+ import"./cli-d6n0thxw.js";
14
+ import"./cli-yv9dttkh.js";
15
15
  import {
16
16
  getEnabledCapabilities
17
- } from "./cli-4xyj9jtq.js";
17
+ } from "./cli-hrhye2rm.js";
18
18
  import"./cli-1z7048dy.js";
19
- import"./cli-dcfyyh3t.js";
19
+ import"./cli-ftyf58xj.js";
20
20
  import"./cli-tk9vyqzh.js";
21
21
  import"./cli-gz9sbyk3.js";
22
- import"./cli-2fc97xm5.js";
23
- import"./cli-psrqtw2m.js";
22
+ import"./cli-mnbgv3w7.js";
24
23
  import"./cli-tng3131n.js";
24
+ import"./cli-psrqtw2m.js";
25
25
  import"./cli-zm7njwzd.js";
26
26
  import"./cli-tghre7g6.js";
27
- import"./cli-tkmm5nf9.js";
28
- import"./cli-bgef578c.js";
29
- import"./cli-36ymmpmp.js";
30
- import"./cli-tbw13sx8.js";
31
- import"./cli-r5g6ngtn.js";
27
+ import"./cli-e61fs2hp.js";
28
+ import"./cli-3samkyap.js";
29
+ import"./cli-tece6zgm.js";
30
+ import"./cli-52fg7s7x.js";
31
+ import"./cli-86fdnerz.js";
32
+ import"./cli-dcca6j8m.js";
32
33
  import"./cli-fad8m16k.js";
33
- import"./cli-gtkqc144.js";
34
- import"./cli-z46pnksz.js";
34
+ import"./cli-shvaxw27.js";
35
+ import"./cli-q1rx7g0d.js";
35
36
  import"./cli-f14fvzag.js";
36
- import"./cli-qwgtacd6.js";
37
- import"./cli-30bbaveh.js";
38
- import"./cli-f3qa069v.js";
37
+ import"./cli-r9f6ngrf.js";
38
+ import"./cli-jkhwmmgg.js";
39
+ import"./cli-cmw9rzy5.js";
40
+ import"./cli-7xje5amz.js";
39
41
  import"./cli-q25ejbyn.js";
40
- import"./cli-bgvskydy.js";
41
- import"./cli-trmapn9k.js";
42
+ import"./cli-t0vqevnm.js";
43
+ import"./cli-0pygq9r1.js";
44
+ import"./cli-tffvrh6j.js";
45
+ import"./cli-pet3aev6.js";
42
46
  import"./cli-rkndnn90.js";
43
47
  import"./cli-b0p7rfnd.js";
44
- import"./cli-h3k622d0.js";
45
- import"./cli-6xd0bvf8.js";
48
+ import"./cli-6aq8xhvm.js";
49
+ import"./cli-ma04faw5.js";
46
50
  import"./cli-wspgs9bt.js";
47
- import"./cli-y4ycrnjc.js";
51
+ import"./cli-k3y4z3h5.js";
48
52
  import"./cli-dh55d5fg.js";
49
- import"./cli-ncfgsqbd.js";
53
+ import"./cli-15y7qhzp.js";
50
54
  import"./cli-z2zcxes1.js";
51
- import"./cli-q21d49ac.js";
52
- import"./cli-anrj584m.js";
53
- import"./cli-c3frqf65.js";
55
+ import"./cli-bw80ck94.js";
56
+ import"./cli-xz9aq0rf.js";
57
+ import"./cli-b23axgz4.js";
54
58
  import"./cli-4j2mrzag.js";
55
59
  import"./cli-e15jhafb.js";
56
60
  import"./cli-9aryf9tv.js";
57
61
  import"./cli-7zd05xb4.js";
58
62
  import"./cli-xw7p4wkq.js";
59
- import"./cli-4wgngmwv.js";
60
63
  import"./cli-zyxs93y9.js";
64
+ import"./cli-4wgngmwv.js";
61
65
  import"./cli-m6pzzhqr.js";
62
66
  import"./cli-7wmybrt5.js";
63
67
  import"./cli-p9swy5t3.js";