@bevel-software/platform-core-backend 0.19.0 → 0.20.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 (255) hide show
  1. package/dist/core/create-core-server.d.ts.map +1 -1
  2. package/dist/core/create-core-server.js +22 -0
  3. package/dist/core/create-core-server.js.map +1 -1
  4. package/dist/core/create-core-services.d.ts +3 -0
  5. package/dist/core/create-core-services.d.ts.map +1 -1
  6. package/dist/core/create-core-services.js +10 -1
  7. package/dist/core/create-core-services.js.map +1 -1
  8. package/dist/modules/audit/agent-audit.service.d.ts +54 -0
  9. package/dist/modules/audit/agent-audit.service.d.ts.map +1 -0
  10. package/dist/modules/audit/agent-audit.service.js +290 -0
  11. package/dist/modules/audit/agent-audit.service.js.map +1 -0
  12. package/dist/modules/audit/agent-rest-audit.middleware.d.ts +40 -0
  13. package/dist/modules/audit/agent-rest-audit.middleware.d.ts.map +1 -0
  14. package/dist/modules/audit/agent-rest-audit.middleware.js +75 -0
  15. package/dist/modules/audit/agent-rest-audit.middleware.js.map +1 -0
  16. package/dist/modules/audit/audit.contract.d.ts +145 -0
  17. package/dist/modules/audit/audit.contract.d.ts.map +1 -0
  18. package/dist/modules/audit/audit.contract.js +35 -0
  19. package/dist/modules/audit/audit.contract.js.map +1 -0
  20. package/dist/modules/audit/audit.routes.d.ts +21 -0
  21. package/dist/modules/audit/audit.routes.d.ts.map +1 -0
  22. package/dist/modules/audit/audit.routes.js +157 -0
  23. package/dist/modules/audit/audit.routes.js.map +1 -0
  24. package/dist/modules/audit/event-classifier.d.ts +52 -0
  25. package/dist/modules/audit/event-classifier.d.ts.map +1 -0
  26. package/dist/modules/audit/event-classifier.js +123 -0
  27. package/dist/modules/audit/event-classifier.js.map +1 -0
  28. package/dist/modules/audit/index.d.ts +7 -0
  29. package/dist/modules/audit/index.d.ts.map +1 -0
  30. package/dist/modules/audit/index.js +7 -0
  31. package/dist/modules/audit/index.js.map +1 -0
  32. package/dist/modules/audit/request-audit.d.ts +57 -0
  33. package/dist/modules/audit/request-audit.d.ts.map +1 -0
  34. package/dist/modules/audit/request-audit.js +117 -0
  35. package/dist/modules/audit/request-audit.js.map +1 -0
  36. package/dist/modules/database/core-schema.d.ts +414 -0
  37. package/dist/modules/database/core-schema.d.ts.map +1 -1
  38. package/dist/modules/database/core-schema.js +99 -0
  39. package/dist/modules/database/core-schema.js.map +1 -1
  40. package/dist/modules/diff/diff.service.d.ts.map +1 -1
  41. package/dist/modules/diff/diff.service.js +6 -1
  42. package/dist/modules/diff/diff.service.js.map +1 -1
  43. package/dist/modules/kb-fs/git-guarded-filesystem.d.ts +9 -1
  44. package/dist/modules/kb-fs/git-guarded-filesystem.d.ts.map +1 -1
  45. package/dist/modules/kb-fs/git-guarded-filesystem.js +16 -3
  46. package/dist/modules/kb-fs/git-guarded-filesystem.js.map +1 -1
  47. package/dist/modules/mcp/mcp-auth.middleware.d.ts +1 -0
  48. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  49. package/dist/modules/mcp/mcp-auth.middleware.js +32 -0
  50. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  51. package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
  52. package/dist/modules/mcp/mcp.routes.js +8 -1
  53. package/dist/modules/mcp/mcp.routes.js.map +1 -1
  54. package/dist/modules/mcp/mcp.service.d.ts +9 -1
  55. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  56. package/dist/modules/mcp/mcp.service.js +48 -5
  57. package/dist/modules/mcp/mcp.service.js.map +1 -1
  58. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +59 -0
  59. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  60. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +180 -8
  61. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  62. package/dist/modules/settings/deployment-settings.service.d.ts +10 -2
  63. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  64. package/dist/modules/settings/deployment-settings.service.js +32 -6
  65. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  66. package/dist/modules/tool-auth/external-api-key.interface.d.ts +21 -5
  67. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
  68. package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -1
  69. package/dist/modules/tool-auth/external-api-key.service.d.ts +1 -0
  70. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  71. package/dist/modules/tool-auth/external-api-key.service.js +22 -9
  72. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  73. package/dist/modules/tool-auth/internal-token.service.d.ts +10 -0
  74. package/dist/modules/tool-auth/internal-token.service.d.ts.map +1 -1
  75. package/dist/modules/tool-auth/internal-token.service.js +1 -0
  76. package/dist/modules/tool-auth/internal-token.service.js.map +1 -1
  77. package/dist/modules/tool-auth/tool-auth.middleware.d.ts +8 -0
  78. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  79. package/dist/modules/tool-auth/tool-auth.middleware.js +9 -1
  80. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  81. package/dist/modules/workspace/workspace.service.d.ts +8 -0
  82. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  83. package/dist/modules/workspace/workspace.service.js +9 -0
  84. package/dist/modules/workspace/workspace.service.js.map +1 -1
  85. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  86. package/dist/modules/workspace/workspace.tools.js +49 -13
  87. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  88. package/dist/shared/git-internals.d.ts +7 -1
  89. package/dist/shared/git-internals.d.ts.map +1 -1
  90. package/dist/shared/git-internals.js +67 -9
  91. package/dist/shared/git-internals.js.map +1 -1
  92. package/migrations/0012_agent_audit.sql +41 -0
  93. package/migrations/0013_agent_identity_and_key_soft_delete.sql +29 -0
  94. package/migrations/meta/0012_snapshot.json +2247 -0
  95. package/migrations/meta/0013_snapshot.json +2259 -0
  96. package/migrations/meta/_journal.json +14 -0
  97. package/package.json +4 -4
  98. package/src/core/create-core-server.ts +28 -0
  99. package/src/core/create-core-services.ts +13 -0
  100. package/src/modules/audit/__tests__/agent-audit.service.test.ts +370 -0
  101. package/src/modules/audit/__tests__/agent-rest-audit.middleware.test.ts +113 -0
  102. package/src/modules/audit/__tests__/audit.routes.test.ts +201 -0
  103. package/src/modules/audit/__tests__/event-classifier.test.ts +121 -0
  104. package/src/modules/audit/agent-audit.service.ts +316 -0
  105. package/src/modules/audit/agent-rest-audit.middleware.ts +83 -0
  106. package/src/modules/audit/audit.contract.ts +164 -0
  107. package/src/modules/audit/audit.routes.ts +168 -0
  108. package/src/modules/audit/event-classifier.ts +155 -0
  109. package/src/modules/audit/index.ts +14 -0
  110. package/src/modules/audit/request-audit.ts +141 -0
  111. package/src/modules/database/core-schema.ts +104 -0
  112. package/src/modules/diff/diff.service.ts +6 -1
  113. package/src/modules/kb-fs/git-guarded-filesystem.ts +16 -3
  114. package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +183 -13
  115. package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +60 -2
  116. package/src/modules/mcp/__tests__/mcp.routes.local-token.test.ts +24 -4
  117. package/src/modules/mcp/__tests__/mcp.routes.stateless.test.ts +1 -1
  118. package/src/modules/mcp/__tests__/mcp.service.test.ts +120 -3
  119. package/src/modules/mcp/mcp-auth.middleware.ts +31 -0
  120. package/src/modules/mcp/mcp.routes.ts +11 -1
  121. package/src/modules/mcp/mcp.service.ts +62 -4
  122. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +184 -6
  123. package/src/modules/settings/__tests__/deployment-settings.service.test.ts +35 -0
  124. package/src/modules/settings/deployment-settings.service.ts +47 -8
  125. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +29 -8
  126. package/src/modules/tool-auth/__tests__/internal-token.service.test.ts +6 -0
  127. package/src/modules/tool-auth/external-api-key.interface.ts +22 -5
  128. package/src/modules/tool-auth/external-api-key.service.ts +25 -8
  129. package/src/modules/tool-auth/internal-token.service.ts +11 -0
  130. package/src/modules/tool-auth/tool-auth.middleware.ts +17 -1
  131. package/src/modules/workspace/__tests__/git-internals.security.test.ts +135 -44
  132. package/src/modules/workspace/workspace.service.ts +9 -0
  133. package/src/modules/workspace/workspace.tools.ts +47 -11
  134. package/src/shared/__tests__/git-internals.test.ts +41 -0
  135. package/src/shared/git-internals.ts +61 -6
  136. package/dist/modules/access/access-errors.d.ts +0 -34
  137. package/dist/modules/access/access-errors.d.ts.map +0 -1
  138. package/dist/modules/access/access-errors.js +0 -40
  139. package/dist/modules/access/access-errors.js.map +0 -1
  140. package/dist/modules/access/access-splice.d.ts +0 -140
  141. package/dist/modules/access/access-splice.d.ts.map +0 -1
  142. package/dist/modules/access/access-splice.js +0 -389
  143. package/dist/modules/access/access-splice.js.map +0 -1
  144. package/dist/modules/access/group-files.d.ts +0 -83
  145. package/dist/modules/access/group-files.d.ts.map +0 -1
  146. package/dist/modules/access/group-files.js +0 -167
  147. package/dist/modules/access/group-files.js.map +0 -1
  148. package/dist/modules/access/kb-read-filter.d.ts +0 -41
  149. package/dist/modules/access/kb-read-filter.d.ts.map +0 -1
  150. package/dist/modules/access/kb-read-filter.js +0 -60
  151. package/dist/modules/access/kb-read-filter.js.map +0 -1
  152. package/dist/modules/access/render-roles-yaml.d.ts +0 -22
  153. package/dist/modules/access/render-roles-yaml.d.ts.map +0 -1
  154. package/dist/modules/access/render-roles-yaml.js +0 -56
  155. package/dist/modules/access/render-roles-yaml.js.map +0 -1
  156. package/dist/modules/access/roles-yaml-guard.d.ts +0 -56
  157. package/dist/modules/access/roles-yaml-guard.d.ts.map +0 -1
  158. package/dist/modules/access/roles-yaml-guard.js +0 -79
  159. package/dist/modules/access/roles-yaml-guard.js.map +0 -1
  160. package/dist/modules/diff/diff-paths.d.ts +0 -2
  161. package/dist/modules/diff/diff-paths.d.ts.map +0 -1
  162. package/dist/modules/diff/diff-paths.js +0 -9
  163. package/dist/modules/diff/diff-paths.js.map +0 -1
  164. package/dist/modules/groups/group-provision.service.d.ts +0 -130
  165. package/dist/modules/groups/group-provision.service.d.ts.map +0 -1
  166. package/dist/modules/groups/group-provision.service.js +0 -288
  167. package/dist/modules/groups/group-provision.service.js.map +0 -1
  168. package/dist/modules/groups/groups.contract.d.ts +0 -106
  169. package/dist/modules/groups/groups.contract.d.ts.map +0 -1
  170. package/dist/modules/groups/groups.contract.js +0 -36
  171. package/dist/modules/groups/groups.contract.js.map +0 -1
  172. package/dist/modules/groups/groups.routes.d.ts +0 -42
  173. package/dist/modules/groups/groups.routes.d.ts.map +0 -1
  174. package/dist/modules/groups/groups.routes.js +0 -379
  175. package/dist/modules/groups/groups.routes.js.map +0 -1
  176. package/dist/modules/groups/groups.service.d.ts +0 -60
  177. package/dist/modules/groups/groups.service.d.ts.map +0 -1
  178. package/dist/modules/groups/groups.service.js +0 -172
  179. package/dist/modules/groups/groups.service.js.map +0 -1
  180. package/dist/modules/groups/index.d.ts +0 -7
  181. package/dist/modules/groups/index.d.ts.map +0 -1
  182. package/dist/modules/groups/index.js +0 -6
  183. package/dist/modules/groups/index.js.map +0 -1
  184. package/dist/modules/groups/join-proposals.d.ts +0 -53
  185. package/dist/modules/groups/join-proposals.d.ts.map +0 -1
  186. package/dist/modules/groups/join-proposals.js +0 -67
  187. package/dist/modules/groups/join-proposals.js.map +0 -1
  188. package/dist/modules/groups/join-requests.service.d.ts +0 -81
  189. package/dist/modules/groups/join-requests.service.d.ts.map +0 -1
  190. package/dist/modules/groups/join-requests.service.js +0 -135
  191. package/dist/modules/groups/join-requests.service.js.map +0 -1
  192. package/dist/modules/mcp/mcp-session-store.d.ts +0 -74
  193. package/dist/modules/mcp/mcp-session-store.d.ts.map +0 -1
  194. package/dist/modules/mcp/mcp-session-store.js +0 -131
  195. package/dist/modules/mcp/mcp-session-store.js.map +0 -1
  196. package/dist/modules/workflow/file-change-notifier.d.ts +0 -38
  197. package/dist/modules/workflow/file-change-notifier.d.ts.map +0 -1
  198. package/dist/modules/workflow/file-change-notifier.js +0 -22
  199. package/dist/modules/workflow/file-change-notifier.js.map +0 -1
  200. package/dist/modules/workflow/git/branch-name.d.ts +0 -10
  201. package/dist/modules/workflow/git/branch-name.d.ts.map +0 -1
  202. package/dist/modules/workflow/git/branch-name.js +0 -76
  203. package/dist/modules/workflow/git/branch-name.js.map +0 -1
  204. package/dist/modules/workflow/git/clone-config.d.ts +0 -61
  205. package/dist/modules/workflow/git/clone-config.d.ts.map +0 -1
  206. package/dist/modules/workflow/git/clone-config.js +0 -69
  207. package/dist/modules/workflow/git/clone-config.js.map +0 -1
  208. package/dist/modules/workflow/git/mutex.d.ts +0 -11
  209. package/dist/modules/workflow/git/mutex.d.ts.map +0 -1
  210. package/dist/modules/workflow/git/mutex.js +0 -23
  211. package/dist/modules/workflow/git/mutex.js.map +0 -1
  212. package/dist/modules/workflow/locking-filesystem.d.ts +0 -137
  213. package/dist/modules/workflow/locking-filesystem.d.ts.map +0 -1
  214. package/dist/modules/workflow/locking-filesystem.js +0 -553
  215. package/dist/modules/workflow/locking-filesystem.js.map +0 -1
  216. package/dist/modules/workflow/read-only-filesystem.d.ts +0 -24
  217. package/dist/modules/workflow/read-only-filesystem.d.ts.map +0 -1
  218. package/dist/modules/workflow/read-only-filesystem.js +0 -39
  219. package/dist/modules/workflow/read-only-filesystem.js.map +0 -1
  220. package/dist/modules/workflow/workflow.errors.d.ts +0 -197
  221. package/dist/modules/workflow/workflow.errors.d.ts.map +0 -1
  222. package/dist/modules/workflow/workflow.errors.js +0 -298
  223. package/dist/modules/workflow/workflow.errors.js.map +0 -1
  224. package/dist/modules/workspace/bevel-ignore.d.ts +0 -30
  225. package/dist/modules/workspace/bevel-ignore.d.ts.map +0 -1
  226. package/dist/modules/workspace/bevel-ignore.js +0 -61
  227. package/dist/modules/workspace/bevel-ignore.js.map +0 -1
  228. package/dist/modules/workspace/kb-seed.interface.d.ts +0 -36
  229. package/dist/modules/workspace/kb-seed.interface.d.ts.map +0 -1
  230. package/dist/modules/workspace/kb-seed.interface.js +0 -2
  231. package/dist/modules/workspace/kb-seed.interface.js.map +0 -1
  232. package/dist/modules/workspace/kb-seed.service.d.ts +0 -125
  233. package/dist/modules/workspace/kb-seed.service.d.ts.map +0 -1
  234. package/dist/modules/workspace/kb-seed.service.js +0 -535
  235. package/dist/modules/workspace/kb-seed.service.js.map +0 -1
  236. package/dist/modules/workspace/plugins-migration.d.ts +0 -50
  237. package/dist/modules/workspace/plugins-migration.d.ts.map +0 -1
  238. package/dist/modules/workspace/plugins-migration.js +0 -379
  239. package/dist/modules/workspace/plugins-migration.js.map +0 -1
  240. package/dist/shared/fs-errors.d.ts +0 -8
  241. package/dist/shared/fs-errors.d.ts.map +0 -1
  242. package/dist/shared/fs-errors.js +0 -11
  243. package/dist/shared/fs-errors.js.map +0 -1
  244. package/dist/shared/fs-walk.d.ts +0 -23
  245. package/dist/shared/fs-walk.d.ts.map +0 -1
  246. package/dist/shared/fs-walk.js +0 -42
  247. package/dist/shared/fs-walk.js.map +0 -1
  248. package/dist/shared/hash-email.d.ts +0 -11
  249. package/dist/shared/hash-email.d.ts.map +0 -1
  250. package/dist/shared/hash-email.js +0 -14
  251. package/dist/shared/hash-email.js.map +0 -1
  252. package/dist/shared/kb-walk.d.ts +0 -52
  253. package/dist/shared/kb-walk.d.ts.map +0 -1
  254. package/dist/shared/kb-walk.js +0 -76
  255. package/dist/shared/kb-walk.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"group-files.js","sourceRoot":"","sources":["../../../src/modules/access/group-files.ts"],"names":[],"mappings":"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"}
@@ -1,41 +0,0 @@
1
- /**
2
- * Shared read-filter primitive.
3
- *
4
- * One place that knows how to turn workspace-relative paths into read verdicts,
5
- * reused by every surface that must hide nodes a user can't read: the agent
6
- * tools (`read_file`/`list_files`/`grep`), the file-explorer tree, the content
7
- * routes, the diff/review routes, and the KB graph.
8
- *
9
- * It deliberately shares only the PRIMITIVE — the path mapping and the batched
10
- * verdict map — NOT the inclusion policy. Callers differ on that: the agent's
11
- * `list_files` keeps directory entries visible (a restricted child is filtered
12
- * when read), whereas the explorer tree hides a restricted directory's whole
13
- * subtree. Each caller applies the verdict to its own policy.
14
- *
15
- * It is parameterized by the access method to call (`ReadBatchFn`); every
16
- * caller — the tree, the agent tools, and the graph — now uses the full
17
- * `canReadBatch` (folder chain + per-node frontmatter `read:` rules), with the
18
- * per-file frontmatter reads memoized inside the access service.
19
- */
20
- /**
21
- * A batched read check over KB-repo-relative paths. Returns a map keyed by the
22
- * input paths. `IAccessControl.canReadBatch` satisfies this shape.
23
- */
24
- export type ReadBatchFn = (workspaceId: string, userEmail: string, kbRelPaths: string[]) => Promise<Map<string, boolean>>;
25
- /**
26
- * Map a workspace-relative path to its KB-repo-relative form (what the access
27
- * tree is keyed on), or null when the path is outside the KB repo — reserved
28
- * workspace files and the KB dir itself carry no `read:` rules and are never
29
- * gated. Tolerates a leading `./` or `/` and a trailing `/`.
30
- */
31
- export declare function toKbRelative(p: string, kbDirName: string): string | null;
32
- /**
33
- * Resolve read verdicts for a set of workspace-relative paths in ONE batched
34
- * access call. Non-KB paths (outside `kbDirName`) are always readable — they
35
- * carry no `read:` rules. KB paths are checked via `batchFn`. Returns a map
36
- * keyed by the original `wsPaths` (so callers can look up by the entry path
37
- * they passed). A path absent from the access verdict resolves to `false`
38
- * (fail-closed) — never silently readable.
39
- */
40
- export declare function resolveReadableMap(batchFn: ReadBatchFn, workspaceId: string, userEmail: string, kbDirName: string, wsPaths: string[]): Promise<Map<string, boolean>>;
41
- //# sourceMappingURL=kb-read-filter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"kb-read-filter.d.ts","sourceRoot":"","sources":["../../../src/modules/access/kb-read-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAAE,KACjB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEnC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxE;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,WAAW,EACpB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAiB/B"}
@@ -1,60 +0,0 @@
1
- /**
2
- * Shared read-filter primitive.
3
- *
4
- * One place that knows how to turn workspace-relative paths into read verdicts,
5
- * reused by every surface that must hide nodes a user can't read: the agent
6
- * tools (`read_file`/`list_files`/`grep`), the file-explorer tree, the content
7
- * routes, the diff/review routes, and the KB graph.
8
- *
9
- * It deliberately shares only the PRIMITIVE — the path mapping and the batched
10
- * verdict map — NOT the inclusion policy. Callers differ on that: the agent's
11
- * `list_files` keeps directory entries visible (a restricted child is filtered
12
- * when read), whereas the explorer tree hides a restricted directory's whole
13
- * subtree. Each caller applies the verdict to its own policy.
14
- *
15
- * It is parameterized by the access method to call (`ReadBatchFn`); every
16
- * caller — the tree, the agent tools, and the graph — now uses the full
17
- * `canReadBatch` (folder chain + per-node frontmatter `read:` rules), with the
18
- * per-file frontmatter reads memoized inside the access service.
19
- */
20
- /**
21
- * Map a workspace-relative path to its KB-repo-relative form (what the access
22
- * tree is keyed on), or null when the path is outside the KB repo — reserved
23
- * workspace files and the KB dir itself carry no `read:` rules and are never
24
- * gated. Tolerates a leading `./` or `/` and a trailing `/`.
25
- */
26
- export function toKbRelative(p, kbDirName) {
27
- const norm = p.replace(/^\.?\/+/, '').replace(/\/+$/, '');
28
- const prefix = `${kbDirName}/`;
29
- if (!norm.startsWith(prefix))
30
- return null;
31
- const rel = norm.slice(prefix.length);
32
- return rel.length > 0 ? rel : null;
33
- }
34
- /**
35
- * Resolve read verdicts for a set of workspace-relative paths in ONE batched
36
- * access call. Non-KB paths (outside `kbDirName`) are always readable — they
37
- * carry no `read:` rules. KB paths are checked via `batchFn`. Returns a map
38
- * keyed by the original `wsPaths` (so callers can look up by the entry path
39
- * they passed). A path absent from the access verdict resolves to `false`
40
- * (fail-closed) — never silently readable.
41
- */
42
- export async function resolveReadableMap(batchFn, workspaceId, userEmail, kbDirName, wsPaths) {
43
- const relByWsPath = new Map();
44
- for (const wp of wsPaths) {
45
- const rel = toKbRelative(wp, kbDirName);
46
- if (rel !== null)
47
- relByWsPath.set(wp, rel);
48
- }
49
- const verdict = relByWsPath.size > 0
50
- ? await batchFn(workspaceId, userEmail, [...new Set(relByWsPath.values())])
51
- : new Map();
52
- const out = new Map();
53
- for (const wp of wsPaths) {
54
- const rel = relByWsPath.get(wp);
55
- // Non-KB path → always readable. KB path → the verdict, fail-closed if absent.
56
- out.set(wp, rel === undefined ? true : verdict.get(rel) === true);
57
- }
58
- return out;
59
- }
60
- //# sourceMappingURL=kb-read-filter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"kb-read-filter.js","sourceRoot":"","sources":["../../../src/modules/access/kb-read-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAYH;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,SAAiB;IACvD,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,GAAG,SAAS,GAAG,CAAC;IAC/B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAoB,EACpB,WAAmB,EACnB,SAAiB,EACjB,SAAiB,EACjB,OAAiB;IAEjB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC9C,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACxC,IAAI,GAAG,KAAK,IAAI;YAAE,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,OAAO,GACX,WAAW,CAAC,IAAI,GAAG,CAAC;QAClB,CAAC,CAAC,MAAM,OAAO,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC3E,CAAC,CAAC,IAAI,GAAG,EAAmB,CAAC;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAmB,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,+EAA+E;QAC/E,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -1,22 +0,0 @@
1
- /**
2
- * Render a `roles.yaml` granting Admin to each email — the ONE renderer every
3
- * generated roles.yaml goes through (empty-remote seeding, the startup
4
- * top-up, and the break-glass recovery), so none of them can drift on
5
- * validation and each fails with the same actionable message.
6
- *
7
- * Each email is validated first, because a malformed one renders a file with
8
- * no working Admin — SILENTLY: a leading `#` turns the entry into a YAML
9
- * comment, an embedded newline breaks the list, an all-whitespace value
10
- * renders an empty entry. A bad ADMIN_EMAIL is operator error, and the
11
- * callers' fail-closed contracts want a message naming the fix instead of an
12
- * un-administrable knowledge base (or a write-validator rejection deep in the
13
- * recovery path).
14
- */
15
- export declare function renderRolesYaml(adminEmails: readonly string[],
16
- /**
17
- * Provenance comment appended to the header. The seed/top-up default names
18
- * where the file came from; recovery passes `null` — claiming "generated at
19
- * KB-seed time" on a recovery-restored file would mislead whoever reads it.
20
- */
21
- provenance?: string | null): string;
22
- //# sourceMappingURL=render-roles-yaml.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"render-roles-yaml.d.ts","sourceRoot":"","sources":["../../../src/modules/access/render-roles-yaml.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,SAAS,MAAM,EAAE;AAC9B;;;;GAIG;AACH,UAAU,GAAE,MAAM,GAAG,IAA0E,GAC9F,MAAM,CAwCR"}
@@ -1,56 +0,0 @@
1
- import { parseRolesYaml } from './access-control.service.js';
2
- /**
3
- * Render a `roles.yaml` granting Admin to each email — the ONE renderer every
4
- * generated roles.yaml goes through (empty-remote seeding, the startup
5
- * top-up, and the break-glass recovery), so none of them can drift on
6
- * validation and each fails with the same actionable message.
7
- *
8
- * Each email is validated first, because a malformed one renders a file with
9
- * no working Admin — SILENTLY: a leading `#` turns the entry into a YAML
10
- * comment, an embedded newline breaks the list, an all-whitespace value
11
- * renders an empty entry. A bad ADMIN_EMAIL is operator error, and the
12
- * callers' fail-closed contracts want a message naming the fix instead of an
13
- * un-administrable knowledge base (or a write-validator rejection deep in the
14
- * recovery path).
15
- */
16
- export function renderRolesYaml(adminEmails,
17
- /**
18
- * Provenance comment appended to the header. The seed/top-up default names
19
- * where the file came from; recovery passes `null` — claiming "generated at
20
- * KB-seed time" on a recovery-restored file would mislead whoever reads it.
21
- */
22
- provenance = 'Generated by the Bevel platform at KB-seed time from ADMIN_EMAIL.') {
23
- const emails = adminEmails.map((raw) => {
24
- const email = raw.trim();
25
- if (email === '') {
26
- throw new Error('Seed admin email is empty — set ADMIN_EMAIL to a real address.');
27
- }
28
- if (email.startsWith('#')) {
29
- throw new Error(`Seed admin email ${JSON.stringify(raw)} starts with "#", which YAML reads as a comment — fix ADMIN_EMAIL.`);
30
- }
31
- if (/\s/.test(email)) {
32
- throw new Error(`Seed admin email ${JSON.stringify(raw)} contains whitespace, which would corrupt roles.yaml — fix ADMIN_EMAIL.`);
33
- }
34
- return email;
35
- });
36
- const lines = emails.map((e) => ` - ${e}`).join('\n');
37
- const text = '# Identity → role mapping for access control.\n' +
38
- '# Role names are case- and whitespace-insensitive. The `Admin` role is special:\n' +
39
- '# only Admins may edit this file, and at least one Admin must always exist.\n' +
40
- (provenance !== null ? `#\n# ${provenance}\n` : '') +
41
- 'roles:\n' +
42
- ' Admin:\n' +
43
- `${lines}\n`;
44
- // Validate by PARSING with the real access parser, not by re-implementing
45
- // its email grammar: whatever the parser would reject (a `<Name <email>`
46
- // shape, a non-email string, tomorrow's new rule) must fail here, before an
47
- // un-administrable roles.yaml gets committed. The checks above exist only
48
- // to give the common mistakes sharper messages.
49
- const parsed = parseRolesYaml(text);
50
- if (!parsed.ok) {
51
- throw new Error(`Generated roles.yaml from ADMIN_EMAIL would not parse — fix the configured address(es). ` +
52
- parsed.errors.join('; '));
53
- }
54
- return text;
55
- }
56
- //# sourceMappingURL=render-roles-yaml.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"render-roles-yaml.js","sourceRoot":"","sources":["../../../src/modules/access/render-roles-yaml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAC7B,WAA8B;AAC9B;;;;GAIG;AACH,aAA4B,mEAAmE;IAE/F,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,oBAAoB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,oEAAoE,CAC5G,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,oBAAoB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,yEAAyE,CACjH,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,MAAM,IAAI,GACR,iDAAiD;QACjD,mFAAmF;QACnF,+EAA+E;QAC/E,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,UAAU,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,UAAU;QACV,YAAY;QACZ,GAAG,KAAK,IAAI,CAAC;IACf,0EAA0E;IAC1E,yEAAyE;IACzE,4EAA4E;IAC5E,0EAA0E;IAC1E,gDAAgD;IAChD,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,0FAA0F;YACxF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAC3B,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1,56 +0,0 @@
1
- /**
2
- * Pre-disk validity gate for `roles.yaml`.
3
- *
4
- * WHY this exists: `roles.yaml` is the single point of failure for the whole
5
- * app. The runtime resolver's `loadModel` HARD-THROWS `AccessConfigError` on a
6
- * parse failure, and `isAdmin` swallows that into `false` for EVERYONE — so a
7
- * single malformed `roles.yaml` is an app-wide, in-app-unrecoverable admin
8
- * lockout. The dedicated Roles & Members service already validates every
9
- * candidate before writing (`assertLoadable`), but the two RAW write paths do
10
- * not:
11
- * - the human editor save (`PUT /workspace/:id/file`)
12
- * - the agent's file tools (`LockingFilesystem.writeFile` / `writeFiles`)
13
- *
14
- * Both of those let an admin (or an admin-driven agent) commit a broken file.
15
- * This guard plugs them: it runs the resolver's OWN parser on the candidate
16
- * BEFORE a byte hits disk, and refuses the write with a 422 on any error. A
17
- * write that passes here is loadable by `loadModel`, so the lockout becomes
18
- * structurally unreachable through normal edits.
19
- *
20
- * The break-glass recovery path (for a file that got broken some OTHER way —
21
- * a direct git push, a pre-guard commit) lives in `roles-admin.service.ts`.
22
- */
23
- import type { FileContent } from '@mastra/core/workspace';
24
- import { WorkflowDomainError } from '../workflow/workflow.errors.js';
25
- /** Repo-relative basename of the roles file (it lives at the KB repo root). */
26
- export declare const ROLES_YAML_BASENAME = "roles.yaml";
27
- /**
28
- * A raw write whose candidate `roles.yaml` would not parse. 422 (bad input) —
29
- * the edit is refused and nothing is written. Carries the parser errors so the
30
- * editor / agent can show exactly what's wrong.
31
- */
32
- export declare class RolesYamlInvalidError extends WorkflowDomainError {
33
- readonly errors: string[];
34
- constructor(errors: string[]);
35
- }
36
- /**
37
- * True iff `workspaceRelPath` targets the KB's `roles.yaml` (the file at
38
- * `<kbDirName>/roles.yaml`). Both the human save route and the agent's
39
- * `LockingFilesystem` speak workspace-relative paths, so this is the form we
40
- * key on. A bare `roles.yaml` (no KB prefix) is also accepted defensively.
41
- */
42
- export declare function isRolesYamlPath(workspaceRelPath: string, kbDirName: string): boolean;
43
- /**
44
- * Throw {@link RolesYamlInvalidError} if `content` does not parse as a valid
45
- * `roles.yaml` per the resolver's own parser. No-op on valid content.
46
- */
47
- export declare function assertRolesYamlParsable(content: string): void;
48
- /**
49
- * A `LockingFilesystem` write-validator scoped to a KB dir: refuses a raw write
50
- * that would leave `roles.yaml` unparseable. Pass the returned closure as the
51
- * filesystem's `validateWrite` hook. Only string writes are checked — every
52
- * code path that writes `roles.yaml` writes it as text; a binary write to that
53
- * path is nonsensical and left alone.
54
- */
55
- export declare function makeRolesYamlWriteValidator(kbDirName: string): (path: string, content: FileContent) => void;
56
- //# sourceMappingURL=roles-yaml-guard.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"roles-yaml-guard.d.ts","sourceRoot":"","sources":["../../../src/modules/access/roles-yaml-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,mBAAmB;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBACd,MAAM,EAAE,MAAM,EAAE;CAS7B;AAOD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAGpF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG7D;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,GAChB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,IAAI,CAM9C"}
@@ -1,79 +0,0 @@
1
- /**
2
- * Pre-disk validity gate for `roles.yaml`.
3
- *
4
- * WHY this exists: `roles.yaml` is the single point of failure for the whole
5
- * app. The runtime resolver's `loadModel` HARD-THROWS `AccessConfigError` on a
6
- * parse failure, and `isAdmin` swallows that into `false` for EVERYONE — so a
7
- * single malformed `roles.yaml` is an app-wide, in-app-unrecoverable admin
8
- * lockout. The dedicated Roles & Members service already validates every
9
- * candidate before writing (`assertLoadable`), but the two RAW write paths do
10
- * not:
11
- * - the human editor save (`PUT /workspace/:id/file`)
12
- * - the agent's file tools (`LockingFilesystem.writeFile` / `writeFiles`)
13
- *
14
- * Both of those let an admin (or an admin-driven agent) commit a broken file.
15
- * This guard plugs them: it runs the resolver's OWN parser on the candidate
16
- * BEFORE a byte hits disk, and refuses the write with a 422 on any error. A
17
- * write that passes here is loadable by `loadModel`, so the lockout becomes
18
- * structurally unreachable through normal edits.
19
- *
20
- * The break-glass recovery path (for a file that got broken some OTHER way —
21
- * a direct git push, a pre-guard commit) lives in `roles-admin.service.ts`.
22
- */
23
- import { parseRolesYaml } from './access-control.service.js';
24
- import { WorkflowDomainError } from '../workflow/workflow.errors.js';
25
- /** Repo-relative basename of the roles file (it lives at the KB repo root). */
26
- export const ROLES_YAML_BASENAME = 'roles.yaml';
27
- /**
28
- * A raw write whose candidate `roles.yaml` would not parse. 422 (bad input) —
29
- * the edit is refused and nothing is written. Carries the parser errors so the
30
- * editor / agent can show exactly what's wrong.
31
- */
32
- export class RolesYamlInvalidError extends WorkflowDomainError {
33
- errors;
34
- constructor(errors) {
35
- super(`roles.yaml would be invalid and was not saved: ${errors.join('; ')}`, 422, { kind: 'roles-yaml-invalid', rolesYamlErrors: errors });
36
- this.name = 'RolesYamlInvalidError';
37
- this.errors = errors;
38
- }
39
- }
40
- /** Normalise a workspace-relative path: backslashes → `/`, strip a leading `./`. */
41
- function normalizeWsPath(p) {
42
- return p.replace(/\\/g, '/').replace(/^\.\//, '');
43
- }
44
- /**
45
- * True iff `workspaceRelPath` targets the KB's `roles.yaml` (the file at
46
- * `<kbDirName>/roles.yaml`). Both the human save route and the agent's
47
- * `LockingFilesystem` speak workspace-relative paths, so this is the form we
48
- * key on. A bare `roles.yaml` (no KB prefix) is also accepted defensively.
49
- */
50
- export function isRolesYamlPath(workspaceRelPath, kbDirName) {
51
- const norm = normalizeWsPath(workspaceRelPath);
52
- return norm === `${kbDirName}/${ROLES_YAML_BASENAME}` || norm === ROLES_YAML_BASENAME;
53
- }
54
- /**
55
- * Throw {@link RolesYamlInvalidError} if `content` does not parse as a valid
56
- * `roles.yaml` per the resolver's own parser. No-op on valid content.
57
- */
58
- export function assertRolesYamlParsable(content) {
59
- const parsed = parseRolesYaml(content);
60
- if (!parsed.ok)
61
- throw new RolesYamlInvalidError(parsed.errors);
62
- }
63
- /**
64
- * A `LockingFilesystem` write-validator scoped to a KB dir: refuses a raw write
65
- * that would leave `roles.yaml` unparseable. Pass the returned closure as the
66
- * filesystem's `validateWrite` hook. Only string writes are checked — every
67
- * code path that writes `roles.yaml` writes it as text; a binary write to that
68
- * path is nonsensical and left alone.
69
- */
70
- export function makeRolesYamlWriteValidator(kbDirName) {
71
- return (path, content) => {
72
- if (typeof content !== 'string')
73
- return;
74
- if (!isRolesYamlPath(path, kbDirName))
75
- return;
76
- assertRolesYamlParsable(content);
77
- };
78
- }
79
- //# sourceMappingURL=roles-yaml-guard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"roles-yaml-guard.js","sourceRoot":"","sources":["../../../src/modules/access/roles-yaml-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAEhD;;;;GAIG;AACH,MAAM,OAAO,qBAAsB,SAAQ,mBAAmB;IACnD,MAAM,CAAW;IAC1B,YAAY,MAAgB;QAC1B,KAAK,CACH,kDAAkD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACrE,GAAG,EACH,EAAE,IAAI,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,EAAE,CACxD,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,oFAAoF;AACpF,SAAS,eAAe,CAAC,CAAS;IAChC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,gBAAwB,EAAE,SAAiB;IACzE,MAAM,IAAI,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAC/C,OAAO,IAAI,KAAK,GAAG,SAAS,IAAI,mBAAmB,EAAE,IAAI,IAAI,KAAK,mBAAmB,CAAC;AACxF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CACzC,SAAiB;IAEjB,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;QACvB,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO;QACxC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC;YAAE,OAAO;QAC9C,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare function assertWithinDirectory(absolutePath: string, dir: string): void;
2
- //# sourceMappingURL=diff-paths.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"diff-paths.d.ts","sourceRoot":"","sources":["../../../src/modules/diff/diff-paths.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAM7E"}
@@ -1,9 +0,0 @@
1
- import path from 'node:path';
2
- export function assertWithinDirectory(absolutePath, dir) {
3
- const resolved = path.resolve(absolutePath);
4
- const root = path.resolve(dir);
5
- if (!resolved.startsWith(root + path.sep) && resolved !== root) {
6
- throw new Error('Path traversal detected');
7
- }
8
- }
9
- //# sourceMappingURL=diff-paths.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"diff-paths.js","sourceRoot":"","sources":["../../../src/modules/diff/diff-paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,qBAAqB,CAAC,YAAoB,EAAE,GAAW;IACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -1,130 +0,0 @@
1
- /**
2
- * Group provisioning — the ONE privileged door for bringing a `Groups/<name>/`
3
- * folder into existence, and (via {@link GroupProvisionService.deleteGroup})
4
- * for taking one back out of it.
5
- *
6
- * Creating a group is the single operation the access model cannot govern
7
- * from inside: the folder that will carry the rules does not exist yet, and
8
- * the root's own rule (`write: Admin`) says no. The old answer was a
9
- * carve-out inside the generic write gate — every write path could claim an
10
- * unused name under `Groups/`, and the gate had to re-derive "is this that
11
- * one blessed case?" on every check. This service replaces that: the generic
12
- * gate is uniformly strict again, and the privilege lives here, named,
13
- * behind its own endpoint.
14
- *
15
- * What a provision IS: one exclusive write of the new folder's `access.md`
16
- * (flag `wx`, so two concurrent creators race for the fs, not for the
17
- * overwrite), then one SYNCHRONOUS commit+push. Synchronous on purpose — the
18
- * write gate reads rules at HEAD, so a creation whose access.md were still
19
- * sitting in the async commit queue would 403 the very next thing its
20
- * creator does (writing the first skill into it).
21
- *
22
- * Two shapes, two templates:
23
- *
24
- * - A NAMED group: discoverable by design. The access.md's own frontmatter
25
- * reads `everyone` — anyone may open the FILE, see the group listed, and
26
- * ask to join — while the BODY (the folder's actual rules) names only
27
- * the creator under read, write and owner.
28
- * - A PERSONAL folder (`personal-<user-id>`): private by design. No
29
- * frontmatter grant at all, so nobody else can even see it exists; the
30
- * body names its owner. Created lazily (ensure semantics) on the first
31
- * personal skill.
32
- */
33
- import { type AuthUser } from '@bevel-software/platform-shared';
34
- import type { WorkspaceService } from '../workspace/workspace.service.js';
35
- import type { IAccessControl } from '../access/access-control.interface.js';
36
- /** Commit machinery the provision rides — the pending-commit pipeline, run inline. */
37
- export interface ProvisionCommitDriver {
38
- runPendingCommit(workspaceId: string, branch: string, targetPath: string, user: AuthUser, opts?: {
39
- systemAuthorized?: boolean;
40
- }): Promise<void>;
41
- }
42
- export interface ProvisionedGroup {
43
- /** The folder name under `Groups/` (not the full path). */
44
- folder: string;
45
- /** False when an ensure found the folder already there. */
46
- created: boolean;
47
- }
48
- /** A refusal the route can pass through: message + HTTP status. */
49
- export declare class GroupProvisionError extends Error {
50
- readonly status: number;
51
- constructor(message: string, status: number);
52
- }
53
- export declare class GroupProvisionService {
54
- private readonly workspaceService;
55
- private readonly commits;
56
- private readonly accessControl;
57
- private readonly kbDirName;
58
- private readonly events?;
59
- /**
60
- * Serialises creations by NORMALIZED (lowercased) folder name. The wx write
61
- * arbitrates same-path races, but on a case-sensitive filesystem `GTM` and
62
- * `gtm` are different paths — without this lock two concurrent requests
63
- * could both pass the collision check and both land, breaking the
64
- * case-insensitive uniqueness the check promises.
65
- */
66
- private readonly creations;
67
- constructor(workspaceService: WorkspaceService, commits: ProvisionCommitDriver, accessControl: IAccessControl, kbDirName: string, events?: {
68
- emit(event: {
69
- kind: "fs-tree-changed";
70
- workspaceId: string;
71
- branch: string;
72
- }): void;
73
- } | undefined);
74
- /**
75
- * Create `Groups/<name>/` for `user`. Throws `GroupProvisionError` 422 on a
76
- * name the filesystem or the model cannot carry, 409 when the name is taken
77
- * (case-insensitively — the workspaces live on case-insensitive
78
- * filesystems too, where `GTM` and `gtm` are one folder).
79
- */
80
- createGroup(user: AuthUser, rawName: string): Promise<ProvisionedGroup>;
81
- /**
82
- * Ensure the caller's personal folder exists — idempotent, keyed to the
83
- * stable user id. Returns `created: false` when it is already there.
84
- */
85
- ensurePersonalGroup(user: AuthUser): Promise<ProvisionedGroup>;
86
- /**
87
- * Delete `Groups/<name>/` — the whole folder, its skills and tools
88
- * included, in ONE commit. MECHANISM only: the route owns the
89
- * authorization (the caller must hold the `owner` verb on the folder;
90
- * this service never re-derives it), exactly as `createGroup` leaves
91
- * "any signed-in user" to its endpoint.
92
- *
93
- * Shape mirrors a provision run in reverse, with the same failure
94
- * contract: the folder is PARKED (renamed to a dot-prefixed sibling the
95
- * scanners ignore) rather than removed, the deletion is committed
96
- * synchronously, and only a landed commit lets the parked bytes go. A
97
- * refused commit renames the folder back, so a failed delete leaves the
98
- * group exactly as it was — never half-gone on disk while origin still
99
- * carries it.
100
- *
101
- * Serialised on the same per-name lock creations use, so a delete can
102
- * never interleave with a re-creation of the same name.
103
- */
104
- deleteGroup(user: AuthUser, rawName: string): Promise<void>;
105
- /** The taken name (in its on-disk casing) colliding with `name`, or null. */
106
- private existingFolder;
107
- private provision;
108
- private readyWorkspaceId;
109
- }
110
- /**
111
- * A named group's access.md: discoverable file (frontmatter `read: everyone`
112
- * — anyone may see the group listed and ask to join), creator-run folder
113
- * (body read/write/owner name the creator). The `read: []` placeholder makes
114
- * the body parse as rules from the first byte, so every later splice targets
115
- * the body rather than the frontmatter.
116
- */
117
- export declare function groupAccessMd(creator: {
118
- name: string;
119
- email: string;
120
- }): string;
121
- /**
122
- * A personal folder's access.md: PRIVATE — no frontmatter grant, so the
123
- * folder is invisible to everyone but its owner; the body names the owner
124
- * under read, write and owner.
125
- */
126
- export declare function personalAccessMd(creator: {
127
- name: string;
128
- email: string;
129
- }): string;
130
- //# sourceMappingURL=group-provision.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"group-provision.service.d.ts","sourceRoot":"","sources":["../../../src/modules/groups/group-provision.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAKH,OAAO,EAML,KAAK,QAAQ,EACd,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAK5E,sFAAsF;AACtF,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,QAAQ,EACd,IAAI,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,mEAAmE;AACnE,qBAAa,mBAAoB,SAAQ,KAAK;IAG1C,QAAQ,CAAC,MAAM,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM;CAK1B;AAED,qBAAa,qBAAqB;IAW9B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAd1B;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;gBAG/B,gBAAgB,EAAE,gBAAgB,EAClC,OAAO,EAAE,qBAAqB,EAC9B,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,iBAAiB,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAA;KAAE,YAAA;IAGnH;;;;;OAKG;IACG,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA8B7E;;;OAGG;IACG,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqBpE;;;;;;;;;;;;;;;;;OAiBG;IACG,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyDjE,6EAA6E;YAC/D,cAAc;YAad,SAAS;YA+CT,gBAAgB;CAI/B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE9E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEjF"}