@bevel-software/platform-core-backend 0.33.0 → 0.35.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 (602) hide show
  1. package/agent-guide/access-control.md +146 -289
  2. package/agent-guide/conventions.md +23 -25
  3. package/agent-guide/directory-structure.md +72 -120
  4. package/agent-guide/drafts-and-change-requests.md +92 -0
  5. package/agent-guide/for-git-users.md +47 -0
  6. package/agent-guide/glossary.md +36 -0
  7. package/agent-guide/how-agents-find-things.md +49 -0
  8. package/agent-guide/html-views.md +239 -8
  9. package/agent-guide/new-knowledge-base.md +9 -8
  10. package/agent-guide/skills.md +67 -42
  11. package/agent-guide/start-here.md +65 -0
  12. package/agent-guide/tool-manuals.md +133 -155
  13. package/agent-guide/tools.md +67 -0
  14. package/agent-guide/where-a-new-file-goes.md +45 -28
  15. package/dist/core/catalog-revision.d.ts +12 -1
  16. package/dist/core/catalog-revision.d.ts.map +1 -1
  17. package/dist/core/catalog-revision.js +23 -3
  18. package/dist/core/catalog-revision.js.map +1 -1
  19. package/dist/core/core-ports.d.ts +41 -0
  20. package/dist/core/core-ports.d.ts.map +1 -1
  21. package/dist/core/core-ports.js.map +1 -1
  22. package/dist/core/create-core-server.d.ts.map +1 -1
  23. package/dist/core/create-core-server.js +15 -8
  24. package/dist/core/create-core-server.js.map +1 -1
  25. package/dist/core/create-core-services.d.ts +22 -5
  26. package/dist/core/create-core-services.d.ts.map +1 -1
  27. package/dist/core/create-core-services.js +44 -16
  28. package/dist/core/create-core-services.js.map +1 -1
  29. package/dist/core/lifecycle.d.ts +16 -0
  30. package/dist/core/lifecycle.d.ts.map +1 -1
  31. package/dist/core/lifecycle.js +12 -2
  32. package/dist/core/lifecycle.js.map +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/modules/access/access-control.interface.d.ts +39 -9
  37. package/dist/modules/access/access-control.interface.d.ts.map +1 -1
  38. package/dist/modules/access/access-control.service.d.ts +15 -3
  39. package/dist/modules/access/access-control.service.d.ts.map +1 -1
  40. package/dist/modules/access/access-control.service.js +239 -75
  41. package/dist/modules/access/access-control.service.js.map +1 -1
  42. package/dist/modules/access/access-mutation.service.d.ts +22 -24
  43. package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
  44. package/dist/modules/access/access-mutation.service.js +48 -51
  45. package/dist/modules/access/access-mutation.service.js.map +1 -1
  46. package/dist/modules/access/access-view.d.ts.map +1 -1
  47. package/dist/modules/access/access-view.js +12 -11
  48. package/dist/modules/access/access-view.js.map +1 -1
  49. package/dist/modules/access/access.routes.d.ts +3 -0
  50. package/dist/modules/access/access.routes.d.ts.map +1 -1
  51. package/dist/modules/access/access.routes.js +58 -33
  52. package/dist/modules/access/access.routes.js.map +1 -1
  53. package/dist/modules/access/groups-admin.routes.d.ts.map +1 -1
  54. package/dist/modules/access/groups-admin.routes.js +4 -2
  55. package/dist/modules/access/groups-admin.routes.js.map +1 -1
  56. package/dist/modules/access/groups-admin.service.d.ts +44 -13
  57. package/dist/modules/access/groups-admin.service.d.ts.map +1 -1
  58. package/dist/modules/access/groups-admin.service.js +80 -38
  59. package/dist/modules/access/groups-admin.service.js.map +1 -1
  60. package/dist/modules/access/groups-edit.d.ts +1 -1
  61. package/dist/modules/access/groups-edit.d.ts.map +1 -1
  62. package/dist/modules/access/groups-edit.js +1 -1
  63. package/dist/modules/access/groups-edit.js.map +1 -1
  64. package/dist/modules/access/index.d.ts +1 -1
  65. package/dist/modules/access/index.d.ts.map +1 -1
  66. package/dist/modules/access/reference-scan.d.ts +116 -24
  67. package/dist/modules/access/reference-scan.d.ts.map +1 -1
  68. package/dist/modules/access/reference-scan.js +305 -44
  69. package/dist/modules/access/reference-scan.js.map +1 -1
  70. package/dist/modules/access/roles-admin.service.d.ts +17 -8
  71. package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
  72. package/dist/modules/access/roles-admin.service.js +32 -23
  73. package/dist/modules/access/roles-admin.service.js.map +1 -1
  74. package/dist/modules/access-model/access-grammar.d.ts +35 -10
  75. package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
  76. package/dist/modules/access-model/access-grammar.js +60 -20
  77. package/dist/modules/access-model/access-grammar.js.map +1 -1
  78. package/dist/modules/access-model/access-splice.d.ts +22 -18
  79. package/dist/modules/access-model/access-splice.d.ts.map +1 -1
  80. package/dist/modules/access-model/access-splice.js +20 -14
  81. package/dist/modules/access-model/access-splice.js.map +1 -1
  82. package/dist/modules/access-model/group-files.d.ts +1 -0
  83. package/dist/modules/access-model/group-files.d.ts.map +1 -1
  84. package/dist/modules/access-model/group-files.js +5 -1
  85. package/dist/modules/access-model/group-files.js.map +1 -1
  86. package/dist/modules/agent-guide/agent-guide.d.ts +47 -7
  87. package/dist/modules/agent-guide/agent-guide.d.ts.map +1 -1
  88. package/dist/modules/agent-guide/agent-guide.js +103 -13
  89. package/dist/modules/agent-guide/agent-guide.js.map +1 -1
  90. package/dist/modules/agent-guide/agent-guide.tools.d.ts +6 -2
  91. package/dist/modules/agent-guide/agent-guide.tools.d.ts.map +1 -1
  92. package/dist/modules/agent-guide/agent-guide.tools.js +46 -22
  93. package/dist/modules/agent-guide/agent-guide.tools.js.map +1 -1
  94. package/dist/modules/agent-guide/guide-budget.d.ts +48 -0
  95. package/dist/modules/agent-guide/guide-budget.d.ts.map +1 -0
  96. package/dist/modules/agent-guide/guide-budget.js +67 -0
  97. package/dist/modules/agent-guide/guide-budget.js.map +1 -0
  98. package/dist/modules/agent-guide/index.d.ts +2 -1
  99. package/dist/modules/agent-guide/index.d.ts.map +1 -1
  100. package/dist/modules/agent-guide/index.js +2 -1
  101. package/dist/modules/agent-guide/index.js.map +1 -1
  102. package/dist/modules/agent-instructions/compose.d.ts +3 -1
  103. package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
  104. package/dist/modules/agent-instructions/compose.js +7 -1
  105. package/dist/modules/agent-instructions/compose.js.map +1 -1
  106. package/dist/modules/agent-instructions/shared-file-rules.d.ts +5 -1
  107. package/dist/modules/agent-instructions/shared-file-rules.d.ts.map +1 -1
  108. package/dist/modules/agent-instructions/shared-file-rules.js +26 -9
  109. package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
  110. package/dist/modules/agent-scope/agent-scope.contract.d.ts +67 -0
  111. package/dist/modules/agent-scope/agent-scope.contract.d.ts.map +1 -0
  112. package/dist/modules/agent-scope/agent-scope.contract.js +27 -0
  113. package/dist/modules/agent-scope/agent-scope.contract.js.map +1 -0
  114. package/dist/modules/agent-scope/connection-scope.d.ts +111 -0
  115. package/dist/modules/agent-scope/connection-scope.d.ts.map +1 -0
  116. package/dist/modules/agent-scope/connection-scope.js +165 -0
  117. package/dist/modules/agent-scope/connection-scope.js.map +1 -0
  118. package/dist/modules/agent-scope/index.d.ts +3 -0
  119. package/dist/modules/agent-scope/index.d.ts.map +1 -0
  120. package/dist/modules/agent-scope/index.js +3 -0
  121. package/dist/modules/agent-scope/index.js.map +1 -0
  122. package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
  123. package/dist/modules/audit/agent-audit.service.js +2 -0
  124. package/dist/modules/audit/agent-audit.service.js.map +1 -1
  125. package/dist/modules/audit/audit.contract.d.ts +6 -0
  126. package/dist/modules/audit/audit.contract.d.ts.map +1 -1
  127. package/dist/modules/audit/audit.contract.js.map +1 -1
  128. package/dist/modules/auth/account-admission.d.ts +12 -0
  129. package/dist/modules/auth/account-admission.d.ts.map +1 -1
  130. package/dist/modules/auth/account-admission.js +15 -0
  131. package/dist/modules/auth/account-admission.js.map +1 -1
  132. package/dist/modules/auth/auth.middleware.d.ts +27 -1
  133. package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
  134. package/dist/modules/auth/auth.middleware.js +42 -4
  135. package/dist/modules/auth/auth.middleware.js.map +1 -1
  136. package/dist/modules/auth/auth.routes.d.ts +13 -9
  137. package/dist/modules/auth/auth.routes.d.ts.map +1 -1
  138. package/dist/modules/auth/auth.routes.js +35 -29
  139. package/dist/modules/auth/auth.routes.js.map +1 -1
  140. package/dist/modules/auth/auth.service.d.ts +55 -6
  141. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  142. package/dist/modules/auth/auth.service.js +128 -34
  143. package/dist/modules/auth/auth.service.js.map +1 -1
  144. package/dist/modules/auth/index.d.ts +1 -1
  145. package/dist/modules/auth/index.d.ts.map +1 -1
  146. package/dist/modules/auth/index.js +1 -1
  147. package/dist/modules/auth/index.js.map +1 -1
  148. package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
  149. package/dist/modules/auth/oidc-auth-provider.js +2 -9
  150. package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
  151. package/dist/modules/code-mode/code-mode.tool.js +2 -2
  152. package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
  153. package/dist/modules/connection-probe/connection-probe.service.d.ts +0 -12
  154. package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
  155. package/dist/modules/connection-probe/connection-probe.service.js +1 -38
  156. package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
  157. package/dist/modules/database/core-schema.d.ts +68 -0
  158. package/dist/modules/database/core-schema.d.ts.map +1 -1
  159. package/dist/modules/database/core-schema.js +33 -0
  160. package/dist/modules/database/core-schema.js.map +1 -1
  161. package/dist/modules/declared-variables/declared-variables.routes.d.ts +8 -1
  162. package/dist/modules/declared-variables/declared-variables.routes.d.ts.map +1 -1
  163. package/dist/modules/declared-variables/declared-variables.routes.js +13 -2
  164. package/dist/modules/declared-variables/declared-variables.routes.js.map +1 -1
  165. package/dist/modules/embed/embed.tools.d.ts.map +1 -1
  166. package/dist/modules/embed/embed.tools.js +5 -0
  167. package/dist/modules/embed/embed.tools.js.map +1 -1
  168. package/dist/modules/kb-fs/index.d.ts +2 -0
  169. package/dist/modules/kb-fs/index.d.ts.map +1 -1
  170. package/dist/modules/kb-fs/index.js +1 -0
  171. package/dist/modules/kb-fs/index.js.map +1 -1
  172. package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
  173. package/dist/modules/kb-fs/locking-filesystem.js +7 -1
  174. package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
  175. package/dist/modules/kb-fs/repo-path.d.ts +26 -6
  176. package/dist/modules/kb-fs/repo-path.d.ts.map +1 -1
  177. package/dist/modules/kb-fs/repo-path.js +22 -7
  178. package/dist/modules/kb-fs/repo-path.js.map +1 -1
  179. package/dist/modules/kb-fs/tmp-ref.d.ts +36 -0
  180. package/dist/modules/kb-fs/tmp-ref.d.ts.map +1 -0
  181. package/dist/modules/kb-fs/tmp-ref.js +76 -0
  182. package/dist/modules/kb-fs/tmp-ref.js.map +1 -0
  183. package/dist/modules/mcp/mcp-auth.middleware.d.ts +7 -0
  184. package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
  185. package/dist/modules/mcp/mcp-auth.middleware.js +14 -1
  186. package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
  187. package/dist/modules/mcp/mcp.routes.d.ts +7 -1
  188. package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
  189. package/dist/modules/mcp/mcp.routes.js +39 -4
  190. package/dist/modules/mcp/mcp.routes.js.map +1 -1
  191. package/dist/modules/mcp/mcp.service.d.ts +11 -0
  192. package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
  193. package/dist/modules/mcp/mcp.service.js +74 -48
  194. package/dist/modules/mcp/mcp.service.js.map +1 -1
  195. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +24 -1
  196. package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
  197. package/dist/modules/mcp/oauth/bevel-oauth-provider.js +45 -10
  198. package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
  199. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +9 -0
  200. package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -1
  201. package/dist/modules/mcp/oauth/oauth-consent.routes.js +34 -1
  202. package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -1
  203. package/dist/modules/plugins/index.d.ts +1 -1
  204. package/dist/modules/plugins/index.d.ts.map +1 -1
  205. package/dist/modules/plugins/index.js.map +1 -1
  206. package/dist/modules/plugins/plugin-links.d.ts +18 -2
  207. package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
  208. package/dist/modules/plugins/plugin-links.js.map +1 -1
  209. package/dist/modules/plugins/plugins.routes.d.ts +5 -1
  210. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  211. package/dist/modules/plugins/plugins.routes.js +32 -5
  212. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  213. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +11 -1
  214. package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -1
  215. package/dist/modules/secrets-vault/db-secrets-vault.service.js +159 -24
  216. package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -1
  217. package/dist/modules/secrets-vault/index.d.ts +1 -1
  218. package/dist/modules/secrets-vault/index.d.ts.map +1 -1
  219. package/dist/modules/secrets-vault/index.js +1 -1
  220. package/dist/modules/secrets-vault/index.js.map +1 -1
  221. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts +53 -11
  222. package/dist/modules/secrets-vault/secrets-vault.contract.d.ts.map +1 -1
  223. package/dist/modules/secrets-vault/secrets-vault.contract.js +27 -0
  224. package/dist/modules/secrets-vault/secrets-vault.contract.js.map +1 -1
  225. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +9 -0
  226. package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
  227. package/dist/modules/secrets-vault/secrets-vault.routes.js +100 -42
  228. package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
  229. package/dist/modules/settings/oidc-check.d.ts.map +1 -1
  230. package/dist/modules/settings/oidc-check.js +5 -17
  231. package/dist/modules/settings/oidc-check.js.map +1 -1
  232. package/dist/modules/skills/index.d.ts +3 -3
  233. package/dist/modules/skills/index.d.ts.map +1 -1
  234. package/dist/modules/skills/index.js +0 -2
  235. package/dist/modules/skills/index.js.map +1 -1
  236. package/dist/modules/skills/skills.contract.d.ts +16 -0
  237. package/dist/modules/skills/skills.contract.d.ts.map +1 -1
  238. package/dist/modules/skills/skills.service.d.ts.map +1 -1
  239. package/dist/modules/skills/skills.service.js +6 -1
  240. package/dist/modules/skills/skills.service.js.map +1 -1
  241. package/dist/modules/skills/skills.tools.d.ts.map +1 -1
  242. package/dist/modules/skills/skills.tools.js +25 -13
  243. package/dist/modules/skills/skills.tools.js.map +1 -1
  244. package/dist/modules/tool-auth/external-api-key.interface.d.ts +11 -0
  245. package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
  246. package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -1
  247. package/dist/modules/tool-auth/external-api-key.service.d.ts +1 -0
  248. package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
  249. package/dist/modules/tool-auth/external-api-key.service.js +4 -1
  250. package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
  251. package/dist/modules/tool-auth/index.d.ts +1 -1
  252. package/dist/modules/tool-auth/index.d.ts.map +1 -1
  253. package/dist/modules/tool-auth/internal-token.service.d.ts +9 -0
  254. package/dist/modules/tool-auth/internal-token.service.d.ts.map +1 -1
  255. package/dist/modules/tool-auth/internal-token.service.js +1 -0
  256. package/dist/modules/tool-auth/internal-token.service.js.map +1 -1
  257. package/dist/modules/tool-auth/tool-auth.middleware.d.ts +27 -3
  258. package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
  259. package/dist/modules/tool-auth/tool-auth.middleware.js +32 -6
  260. package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
  261. package/dist/modules/tool-helpers/tool-context.d.ts +7 -0
  262. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
  263. package/dist/modules/tool-helpers/tool-context.js +3 -0
  264. package/dist/modules/tool-helpers/tool-context.js.map +1 -1
  265. package/dist/modules/tool-helpers/tool-def.js +1 -1
  266. package/dist/modules/tool-helpers/tool-def.js.map +1 -1
  267. package/dist/modules/tool-helpers/tool-handler.d.ts +15 -0
  268. package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
  269. package/dist/modules/tool-helpers/tool-handler.js +19 -0
  270. package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
  271. package/dist/modules/tool-helpers/tool.contract.d.ts +10 -0
  272. package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
  273. package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
  274. package/dist/modules/tool-helpers/validate-token.d.ts +3 -1
  275. package/dist/modules/tool-helpers/validate-token.d.ts.map +1 -1
  276. package/dist/modules/tool-helpers/validate-token.js +1 -1
  277. package/dist/modules/tool-helpers/validate-token.js.map +1 -1
  278. package/dist/modules/tool-manuals/index.d.ts +3 -3
  279. package/dist/modules/tool-manuals/index.d.ts.map +1 -1
  280. package/dist/modules/tool-manuals/index.js +0 -2
  281. package/dist/modules/tool-manuals/index.js.map +1 -1
  282. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +7 -1
  283. package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
  284. package/dist/modules/tool-manuals/mcp-json-discovery.js +69 -38
  285. package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
  286. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +46 -6
  287. package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
  288. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +7 -1
  289. package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
  290. package/dist/modules/tool-manuals/tool-manuals.routes.js +41 -4
  291. package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
  292. package/dist/modules/tool-manuals/tool-manuals.service.d.ts +24 -13
  293. package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
  294. package/dist/modules/tool-manuals/tool-manuals.service.js +138 -59
  295. package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
  296. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +8 -2
  297. package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
  298. package/dist/modules/tool-manuals/tool-manuals.tools.js +56 -20
  299. package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
  300. package/dist/modules/tool-registry/manual.routes.d.ts +8 -1
  301. package/dist/modules/tool-registry/manual.routes.d.ts.map +1 -1
  302. package/dist/modules/tool-registry/manual.routes.js +27 -7
  303. package/dist/modules/tool-registry/manual.routes.js.map +1 -1
  304. package/dist/modules/tool-registry/tool.contract.d.ts +7 -0
  305. package/dist/modules/tool-registry/tool.contract.d.ts.map +1 -1
  306. package/dist/modules/tool-registry/tool.contract.js.map +1 -1
  307. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  308. package/dist/modules/workflow/agent-tools/workflow.tools.js +36 -27
  309. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  310. package/dist/modules/workflow/git/git.service.d.ts +2 -2
  311. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  312. package/dist/modules/workflow/git/git.service.js +20 -35
  313. package/dist/modules/workflow/git/git.service.js.map +1 -1
  314. package/dist/modules/workflow/workflow.service.d.ts +2 -1
  315. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  316. package/dist/modules/workflow/workflow.service.js +3 -0
  317. package/dist/modules/workflow/workflow.service.js.map +1 -1
  318. package/dist/modules/workspace/agent-access.gate.d.ts +1 -1
  319. package/dist/modules/workspace/agent-access.gate.d.ts.map +1 -1
  320. package/dist/modules/workspace/agent-access.gate.js +1 -1
  321. package/dist/modules/workspace/agent-access.gate.js.map +1 -1
  322. package/dist/modules/workspace/file-readers/doc-extract.service.d.ts +28 -4
  323. package/dist/modules/workspace/file-readers/doc-extract.service.d.ts.map +1 -1
  324. package/dist/modules/workspace/file-readers/doc-extract.service.js +61 -40
  325. package/dist/modules/workspace/file-readers/doc-extract.service.js.map +1 -1
  326. package/dist/modules/workspace/index.d.ts +8 -0
  327. package/dist/modules/workspace/index.d.ts.map +1 -1
  328. package/dist/modules/workspace/index.js +8 -0
  329. package/dist/modules/workspace/index.js.map +1 -1
  330. package/dist/modules/workspace/nul-scan.d.ts +19 -0
  331. package/dist/modules/workspace/nul-scan.d.ts.map +1 -0
  332. package/dist/modules/workspace/nul-scan.js +55 -0
  333. package/dist/modules/workspace/nul-scan.js.map +1 -0
  334. package/dist/modules/workspace/pattern-matcher.contract.d.ts +110 -27
  335. package/dist/modules/workspace/pattern-matcher.contract.d.ts.map +1 -1
  336. package/dist/modules/workspace/pattern-matcher.contract.js +30 -13
  337. package/dist/modules/workspace/pattern-matcher.contract.js.map +1 -1
  338. package/dist/modules/workspace/ripgrep-search.d.ts +54 -0
  339. package/dist/modules/workspace/ripgrep-search.d.ts.map +1 -0
  340. package/dist/modules/workspace/ripgrep-search.js +657 -0
  341. package/dist/modules/workspace/ripgrep-search.js.map +1 -0
  342. package/dist/modules/workspace/ripgrep-version.d.ts +15 -0
  343. package/dist/modules/workspace/ripgrep-version.d.ts.map +1 -0
  344. package/dist/modules/workspace/ripgrep-version.js +31 -0
  345. package/dist/modules/workspace/ripgrep-version.js.map +1 -0
  346. package/dist/modules/workspace/startup/beside-checkout.d.ts +8 -5
  347. package/dist/modules/workspace/startup/beside-checkout.d.ts.map +1 -1
  348. package/dist/modules/workspace/startup/beside-checkout.js +14 -5
  349. package/dist/modules/workspace/startup/beside-checkout.js.map +1 -1
  350. package/dist/modules/workspace/worker-pool.d.ts +3 -4
  351. package/dist/modules/workspace/worker-pool.d.ts.map +1 -1
  352. package/dist/modules/workspace/worker-pool.js.map +1 -1
  353. package/dist/modules/workspace/workspace-tmp.d.ts +146 -0
  354. package/dist/modules/workspace/workspace-tmp.d.ts.map +1 -0
  355. package/dist/modules/workspace/workspace-tmp.js +435 -0
  356. package/dist/modules/workspace/workspace-tmp.js.map +1 -0
  357. package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
  358. package/dist/modules/workspace/workspace.routes.js +5 -26
  359. package/dist/modules/workspace/workspace.routes.js.map +1 -1
  360. package/dist/modules/workspace/workspace.service.d.ts +47 -6
  361. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  362. package/dist/modules/workspace/workspace.service.js +86 -6
  363. package/dist/modules/workspace/workspace.service.js.map +1 -1
  364. package/dist/modules/workspace/workspace.tools.d.ts +3 -2
  365. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  366. package/dist/modules/workspace/workspace.tools.js +531 -137
  367. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  368. package/dist/shared/oauth-token-error.d.ts +23 -0
  369. package/dist/shared/oauth-token-error.d.ts.map +1 -0
  370. package/dist/shared/oauth-token-error.js +47 -0
  371. package/dist/shared/oauth-token-error.js.map +1 -0
  372. package/dist/shared/path-order.d.ts +28 -8
  373. package/dist/shared/path-order.d.ts.map +1 -1
  374. package/dist/shared/path-order.js +37 -8
  375. package/dist/shared/path-order.js.map +1 -1
  376. package/dist/shared/read-capped.d.ts +19 -0
  377. package/dist/shared/read-capped.d.ts.map +1 -0
  378. package/dist/shared/read-capped.js +45 -0
  379. package/dist/shared/read-capped.js.map +1 -0
  380. package/migrations/0022_session_version.sql +6 -0
  381. package/migrations/0023_agent_path.sql +3 -0
  382. package/migrations/meta/0022_snapshot.json +2360 -0
  383. package/migrations/meta/0023_snapshot.json +2378 -0
  384. package/migrations/meta/_journal.json +14 -0
  385. package/package.json +4 -3
  386. package/src/__tests__/hexis-catalog.ts +144 -0
  387. package/src/__tests__/pg-scratch.test.ts +69 -0
  388. package/src/__tests__/pg-scratch.ts +31 -0
  389. package/src/__tests__/real-disk.ts +21 -0
  390. package/src/__tests__/slow-ripgrep.ts +65 -0
  391. package/src/__tests__/tokens.ts +19 -0
  392. package/src/__tests__/tool-manuals.ts +32 -0
  393. package/src/__tests__/tool-wiring.ts +25 -0
  394. package/src/core/__tests__/boot-without-ripgrep.test.ts +34 -0
  395. package/src/core/__tests__/catalog-revision.test.ts +89 -0
  396. package/src/core/__tests__/damaged-document.tools.test.ts +2 -2
  397. package/src/core/__tests__/gated-boot.test.ts +8 -1
  398. package/src/core/__tests__/lifecycle.test.ts +46 -13
  399. package/src/core/__tests__/oauth-sign-in-real-file.test.ts +179 -0
  400. package/src/core/catalog-revision.ts +24 -2
  401. package/src/core/core-ports.ts +42 -0
  402. package/src/core/create-core-server.ts +14 -1
  403. package/src/core/create-core-services.ts +62 -15
  404. package/src/core/lifecycle.ts +26 -2
  405. package/src/index.ts +1 -1
  406. package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +12 -0
  407. package/src/modules/access/__tests__/access-control.colliding-name-cases.test.ts +113 -0
  408. package/src/modules/access/__tests__/access-control.frontmatter-head.test.ts +117 -0
  409. package/src/modules/access/__tests__/access-control.group-named-admin.test.ts +122 -0
  410. package/src/modules/access/__tests__/access-control.preview-relocation.test.ts +50 -0
  411. package/src/modules/access/__tests__/access-declarations.test.ts +19 -0
  412. package/src/modules/access/__tests__/access-groups.test.ts +55 -22
  413. package/src/modules/access/__tests__/access-mutation.service.test.ts +85 -59
  414. package/src/modules/access/__tests__/access-restrict-here.test.ts +7 -5
  415. package/src/modules/access/__tests__/access.routes.admins.test.ts +1 -0
  416. package/src/modules/access/__tests__/access.routes.batch.test.ts +2 -0
  417. package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +2 -0
  418. package/src/modules/access/__tests__/access.routes.group-grant.test.ts +50 -14
  419. package/src/modules/access/__tests__/access.routes.overrides.test.ts +2 -1
  420. package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +1 -0
  421. package/src/modules/access/__tests__/access.routes.prospective.test.ts +52 -10
  422. package/src/modules/access/__tests__/access.routes.revoke.test.ts +18 -13
  423. package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -0
  424. package/src/modules/access/__tests__/grant-sources.test.ts +20 -15
  425. package/src/modules/access/__tests__/groups-admin.routes.test.ts +61 -0
  426. package/src/modules/access/__tests__/groups-admin.service.test.ts +211 -18
  427. package/src/modules/access/__tests__/holder-changes.test.ts +127 -0
  428. package/src/modules/access/__tests__/reference-scan.test.ts +366 -14
  429. package/src/modules/access/__tests__/roles-admin.security.test.ts +1 -1
  430. package/src/modules/access/__tests__/roles-admin.service.test.ts +43 -22
  431. package/src/modules/access/__tests__/roles-capabilities.test.ts +6 -2
  432. package/src/modules/access/__tests__/roles.routes.test.ts +1 -1
  433. package/src/modules/access/access-control.interface.ts +43 -10
  434. package/src/modules/access/access-control.service.ts +250 -72
  435. package/src/modules/access/access-mutation.service.ts +48 -53
  436. package/src/modules/access/access-view.ts +12 -10
  437. package/src/modules/access/access.routes.ts +66 -37
  438. package/src/modules/access/groups-admin.routes.ts +4 -2
  439. package/src/modules/access/groups-admin.service.ts +114 -44
  440. package/src/modules/access/groups-edit.ts +1 -1
  441. package/src/modules/access/index.ts +1 -1
  442. package/src/modules/access/reference-scan.ts +319 -46
  443. package/src/modules/access/roles-admin.service.ts +43 -26
  444. package/src/modules/access/synced-groups-writer.ts +1 -1
  445. package/src/modules/access-model/__tests__/access-grammar.test.ts +38 -1
  446. package/src/modules/access-model/__tests__/access-splice.test.ts +50 -8
  447. package/src/modules/access-model/access-grammar.ts +65 -20
  448. package/src/modules/access-model/access-splice.ts +31 -23
  449. package/src/modules/access-model/group-files.ts +5 -0
  450. package/src/modules/agent-guide/__tests__/agent-guide.test.ts +110 -25
  451. package/src/modules/agent-guide/__tests__/agent-guide.tools.test.ts +38 -11
  452. package/src/modules/agent-guide/__tests__/guide-budget.test.ts +95 -0
  453. package/src/modules/agent-guide/__tests__/guide-eval.test.ts +182 -0
  454. package/src/modules/agent-guide/__tests__/guide-matches-code.test.ts +263 -0
  455. package/src/modules/agent-guide/__tests__/tool-surface.json +514 -0
  456. package/src/modules/agent-guide/__tests__/tool-surface.test.ts +75 -0
  457. package/src/modules/agent-guide/agent-guide.tools.ts +51 -22
  458. package/src/modules/agent-guide/agent-guide.ts +120 -13
  459. package/src/modules/agent-guide/guide-budget.ts +73 -0
  460. package/src/modules/agent-guide/index.ts +12 -0
  461. package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +5 -4
  462. package/src/modules/agent-instructions/compose.ts +7 -1
  463. package/src/modules/agent-instructions/shared-file-rules.ts +27 -9
  464. package/src/modules/agent-scope/__tests__/agent-surfaces.connect-as.test.ts +421 -0
  465. package/src/modules/agent-scope/__tests__/connection-scope.test.ts +46 -0
  466. package/src/modules/agent-scope/__tests__/in-memory-kb.ts +148 -0
  467. package/src/modules/agent-scope/agent-scope.contract.ts +83 -0
  468. package/src/modules/agent-scope/connection-scope.ts +199 -0
  469. package/src/modules/agent-scope/index.ts +15 -0
  470. package/src/modules/audit/agent-audit.service.ts +2 -0
  471. package/src/modules/audit/audit.contract.ts +6 -0
  472. package/src/modules/auth/__tests__/auth.middleware.test.ts +30 -2
  473. package/src/modules/auth/__tests__/auth.routes.test.ts +71 -5
  474. package/src/modules/auth/__tests__/auth.service.test.ts +90 -9
  475. package/src/modules/auth/__tests__/password-change-sessions.pg.test.ts +269 -0
  476. package/src/modules/auth/account-admission.ts +19 -0
  477. package/src/modules/auth/auth.middleware.ts +45 -4
  478. package/src/modules/auth/auth.routes.ts +46 -29
  479. package/src/modules/auth/auth.service.ts +135 -34
  480. package/src/modules/auth/index.ts +2 -0
  481. package/src/modules/auth/oidc-auth-provider.ts +2 -9
  482. package/src/modules/code-mode/code-mode.tool.ts +2 -2
  483. package/src/modules/connection-probe/__tests__/connection-probe.service.test.ts +5 -24
  484. package/src/modules/connection-probe/connection-probe.service.ts +1 -34
  485. package/src/modules/database/__tests__/session-version-migration.pg.test.ts +133 -0
  486. package/src/modules/database/core-schema.ts +33 -0
  487. package/src/modules/declared-variables/__tests__/declared-variables.route.test.ts +44 -1
  488. package/src/modules/declared-variables/declared-variables.routes.ts +12 -1
  489. package/src/modules/embed/__tests__/embed.tools.test.ts +12 -0
  490. package/src/modules/embed/embed.tools.ts +5 -0
  491. package/src/modules/kb-fs/__tests__/locking-filesystem.test.ts +25 -0
  492. package/src/modules/kb-fs/__tests__/repo-path.test.ts +53 -8
  493. package/src/modules/kb-fs/index.ts +2 -0
  494. package/src/modules/kb-fs/locking-filesystem.ts +7 -1
  495. package/src/modules/kb-fs/repo-path.ts +33 -7
  496. package/src/modules/kb-fs/tmp-ref.ts +81 -0
  497. package/src/modules/mcp/__tests__/connect-as.pg.test.ts +137 -0
  498. package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +29 -5
  499. package/src/modules/mcp/__tests__/mcp-routes-harness.ts +8 -0
  500. package/src/modules/mcp/__tests__/mcp.connect-as.test.ts +195 -0
  501. package/src/modules/mcp/__tests__/mcp.routes.connect-as.test.ts +192 -0
  502. package/src/modules/mcp/__tests__/oauth-consent.connect-as.test.ts +146 -0
  503. package/src/modules/mcp/mcp-auth.middleware.ts +19 -2
  504. package/src/modules/mcp/mcp.routes.ts +39 -3
  505. package/src/modules/mcp/mcp.service.ts +112 -52
  506. package/src/modules/mcp/oauth/bevel-oauth-provider.ts +46 -8
  507. package/src/modules/mcp/oauth/oauth-consent.routes.ts +41 -1
  508. package/src/modules/plugins/__tests__/plugins.tools.test.ts +38 -2
  509. package/src/modules/plugins/index.ts +1 -1
  510. package/src/modules/plugins/plugin-links.ts +19 -2
  511. package/src/modules/plugins/plugins.routes.ts +35 -4
  512. package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +113 -0
  513. package/src/modules/secrets-vault/__tests__/db-secrets-vault.oauth.test.ts +430 -3
  514. package/src/modules/secrets-vault/__tests__/oauth-live-declaration.route.test.ts +218 -0
  515. package/src/modules/secrets-vault/__tests__/oauth-return-to.route.test.ts +39 -6
  516. package/src/modules/secrets-vault/db-secrets-vault.service.ts +170 -27
  517. package/src/modules/secrets-vault/index.ts +1 -1
  518. package/src/modules/secrets-vault/secrets-vault.contract.ts +61 -11
  519. package/src/modules/secrets-vault/secrets-vault.routes.ts +114 -42
  520. package/src/modules/settings/oidc-check.ts +5 -18
  521. package/src/modules/skills/__tests__/skills.service.test.ts +34 -0
  522. package/src/modules/skills/index.ts +7 -2
  523. package/src/modules/skills/skills.contract.ts +17 -0
  524. package/src/modules/skills/skills.service.ts +5 -1
  525. package/src/modules/skills/skills.tools.ts +45 -14
  526. package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +4 -0
  527. package/src/modules/tool-auth/external-api-key.interface.ts +11 -1
  528. package/src/modules/tool-auth/external-api-key.service.ts +5 -2
  529. package/src/modules/tool-auth/index.ts +1 -1
  530. package/src/modules/tool-auth/internal-token.service.ts +10 -0
  531. package/src/modules/tool-auth/tool-auth.middleware.ts +45 -3
  532. package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +19 -11
  533. package/src/modules/tool-helpers/__tests__/can-write.tools.test.ts +3 -1
  534. package/src/modules/tool-helpers/__tests__/route-tool-schemas.catalog.test.ts +38 -0
  535. package/src/modules/tool-helpers/tool-context.ts +10 -0
  536. package/src/modules/tool-helpers/tool-def.ts +1 -1
  537. package/src/modules/tool-helpers/tool-handler.ts +34 -0
  538. package/src/modules/tool-helpers/tool.contract.ts +10 -0
  539. package/src/modules/tool-helpers/validate-token.ts +4 -2
  540. package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +80 -4
  541. package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +197 -11
  542. package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +42 -0
  543. package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +99 -8
  544. package/src/modules/tool-manuals/index.ts +6 -2
  545. package/src/modules/tool-manuals/mcp-json-discovery.ts +73 -34
  546. package/src/modules/tool-manuals/tool-manuals.contract.ts +40 -6
  547. package/src/modules/tool-manuals/tool-manuals.routes.ts +40 -3
  548. package/src/modules/tool-manuals/tool-manuals.service.ts +169 -61
  549. package/src/modules/tool-manuals/tool-manuals.tools.ts +81 -25
  550. package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +6 -113
  551. package/src/modules/tool-registry/manual.routes.ts +26 -5
  552. package/src/modules/tool-registry/tool.contract.ts +7 -0
  553. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +1 -1
  554. package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +1 -1
  555. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +54 -3
  556. package/src/modules/workflow/agent-tools/workflow.tools.ts +36 -27
  557. package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +130 -3
  558. package/src/modules/workflow/git/git.service.ts +29 -48
  559. package/src/modules/workflow/workflow.service.ts +5 -0
  560. package/src/modules/workspace/__tests__/git-internals.security.test.ts +2 -2
  561. package/src/modules/workspace/__tests__/holds-nul.test.ts +66 -0
  562. package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +3 -3
  563. package/src/modules/workspace/__tests__/ripgrep-search.test.ts +570 -0
  564. package/src/modules/workspace/__tests__/ripgrep-version.test.ts +29 -0
  565. package/src/modules/workspace/__tests__/workspace-tmp.tools.test.ts +928 -0
  566. package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +17 -37
  567. package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +20 -8
  568. package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +10 -12
  569. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +22 -10
  570. package/src/modules/workspace/__tests__/workspace.tools.test.ts +549 -162
  571. package/src/modules/workspace/agent-access.gate.ts +1 -1
  572. package/src/modules/workspace/file-readers/__tests__/doc-extract.service.test.ts +10 -0
  573. package/src/modules/workspace/file-readers/doc-extract.service.ts +71 -38
  574. package/src/modules/workspace/index.ts +20 -0
  575. package/src/modules/workspace/nul-scan.ts +50 -0
  576. package/src/modules/workspace/pattern-matcher.contract.ts +123 -32
  577. package/src/modules/workspace/ripgrep-search.ts +715 -0
  578. package/src/modules/workspace/ripgrep-version.ts +35 -0
  579. package/src/modules/workspace/startup/__tests__/beside-checkout.test.ts +11 -0
  580. package/src/modules/workspace/startup/beside-checkout.ts +13 -5
  581. package/src/modules/workspace/worker-pool.ts +3 -4
  582. package/src/modules/workspace/workspace-tmp.ts +457 -0
  583. package/src/modules/workspace/workspace.routes.ts +6 -27
  584. package/src/modules/workspace/workspace.service.ts +92 -15
  585. package/src/modules/workspace/workspace.tools.ts +574 -176
  586. package/src/shared/__tests__/read-capped.test.ts +68 -0
  587. package/src/shared/oauth-token-error.ts +46 -0
  588. package/src/shared/path-order.ts +37 -8
  589. package/src/shared/read-capped.ts +40 -0
  590. package/starter-packs/engineering/Plugins/engineering-starter/access.md +1 -1
  591. package/starter-packs/general/Plugins/general-starter/access.md +1 -1
  592. package/starter-packs/operations/Plugins/operations-starter/access.md +1 -1
  593. package/starter-packs/sales/Plugins/sales-starter/access.md +1 -1
  594. package/starter-packs/support/Plugins/support-starter/access.md +1 -1
  595. package/agent-guide/finding-things.md +0 -7
  596. package/agent-guide/introduction.md +0 -27
  597. package/dist/modules/workspace/bounded-matcher.d.ts +0 -73
  598. package/dist/modules/workspace/bounded-matcher.d.ts.map +0 -1
  599. package/dist/modules/workspace/bounded-matcher.js +0 -200
  600. package/dist/modules/workspace/bounded-matcher.js.map +0 -1
  601. package/src/modules/workspace/__tests__/bounded-matcher.test.ts +0 -213
  602. package/src/modules/workspace/bounded-matcher.ts +0 -271
@@ -32,7 +32,7 @@ import type { WorkflowHooks } from '../workflow/index.js';
32
32
  * takes, so a run's reads and its questions share one conversation.
33
33
  */
34
34
  export const SESSION_ID_DESCRIPTION =
35
- "This conversation's id, so the server can tell one run's calls apart. External agents (direct MCP calls and `call_tool_chain` alike): call the `start_session` tool ONCE at the very start of your work to obtain it, then pass that id here — the same id `ask` takes. The in-process agent runtime supplies this automatically (do not set it yourself).";
35
+ "This conversation's id: call `start_session` once, at the start of your work, and pass its id here, inside `call_tool_chain` too (and to `ask`, where the deployment offers it). The in-process agent runtime sets it itself.";
36
36
 
37
37
  /**
38
38
  * The `sessionId` input every gated tool declares. The description a MOUNTED
@@ -152,6 +152,16 @@ describe('DocExtractService — how long a failure is remembered', () => {
152
152
  expect(told).toHaveLength(1);
153
153
  });
154
154
 
155
+ it('two reads of the same bytes at different paths share one extraction, and each marker names its own path', async () => {
156
+ const extractor = scriptedExtractor(() => ({ ok: true, summary: '1 page', text: '[page 1]\nshared' }));
157
+ const service = new DocExtractService(cacheRoot, extractor, { now, onUnreadable });
158
+ const bytes = Buffer.from('same bytes, two names');
159
+ const [a, b] = await Promise.all([service.extract('a/deck.pdf', bytes, ORIGIN), service.extract('b/copy.pdf', bytes, ORIGIN)]);
160
+ expect(extractor.calls).toBe(1);
161
+ expect(a).toEqual({ ok: true, marker: '[extracted text of a/deck.pdf — 1 page]', text: '[page 1]\nshared' });
162
+ expect(b).toEqual({ ok: true, marker: '[extracted text of b/copy.pdf — 1 page]', text: '[page 1]\nshared' });
163
+ });
164
+
155
165
  it('still answers the read when whoever is told throws', async () => {
156
166
  const extractor = scriptedExtractor(() => TIMEOUT);
157
167
  const service = new DocExtractService(cacheRoot, extractor, {
@@ -1,5 +1,5 @@
1
- import type { IDocumentExtractor, IsolatedExtraction } from './document-extractor.contract.js';
2
- import { extractionMarker, fileExtension } from './doc-extract.types.js';
1
+ import type { IDocumentExtractor } from './document-extractor.contract.js';
2
+ import { extractionMarker, fileExtension, type ExtractedDoc } from './doc-extract.types.js';
3
3
  import { DocExtractionCache, gitBlobSha } from './extraction-cache.js';
4
4
  import type { ReadOrigin } from './file-reader.js';
5
5
 
@@ -15,6 +15,18 @@ export type DocExtractOutcome =
15
15
  | ({ ok: true } & DocExtraction)
16
16
  | { ok: false; message: string };
17
17
 
18
+ /**
19
+ * What one read of some bytes answers before any path names it: the cache's
20
+ * own shape (an extraction, or a failure's message). `named` turns it into
21
+ * what `extract` returns for the path it was asked about.
22
+ */
23
+ type RawOutcome = ({ ok: true } & ExtractedDoc) | { ok: false; message: string };
24
+
25
+ /** `raw` as the answer for `path`: its marker names that path. */
26
+ function named(path: string, raw: RawOutcome): DocExtractOutcome {
27
+ return raw.ok ? { ok: true, marker: extractionMarker(path, raw.summary), text: raw.text } : raw;
28
+ }
29
+
18
30
  /** A document whose extraction just failed, as the people looking at it are told. */
19
31
  export interface UnreadableDocument {
20
32
  workspaceId: string;
@@ -94,12 +106,23 @@ export class DocExtractService {
94
106
  private readonly now: () => number;
95
107
  private readonly onUnreadable: ((doc: UnreadableDocument) => void) | undefined;
96
108
  /**
97
- * Cold extractions currently running, by cache key. Two reads of the same
98
- * document arriving together would otherwise BOTH parse it — the expensive
99
- * half of this service, run twice for one answer — because neither had
100
- * written the cache entry yet when the other looked.
109
+ * Reads currently running, by cache key — the cache lookup included, from
110
+ * the moment `extract` is called. Two reads of the same document arriving
111
+ * together would otherwise BOTH parse it — the expensive half of this
112
+ * service, run twice for one answer — because neither had written the
113
+ * cache entry yet when the other looked. The entry is set before anything
114
+ * is awaited: were the lookup awaited first, a second read could miss the
115
+ * cache (its read of the file started before the first read's write) AND
116
+ * the map (the first read finished and left it in that window), and parse
117
+ * the document again, telling the people looking at it twice.
118
+ *
119
+ * What is shared is exactly what the key identifies — the bytes' extraction
120
+ * under a format, which is what the cache holds — and nothing of the read
121
+ * that started it: the key carries no path, so two reads of the same bytes
122
+ * at different paths share one promise, and each names the answer with its
123
+ * own path (`extract`).
101
124
  */
102
- private readonly inFlight = new Map<string, Promise<IsolatedExtraction>>();
125
+ private readonly inFlight = new Map<string, Promise<RawOutcome>>();
103
126
 
104
127
  constructor(
105
128
  cacheRoot: string,
@@ -119,11 +142,8 @@ export class DocExtractService {
119
142
  * only to cold ones; `file_stat` uses it to report a remembered failure.
120
143
  */
121
144
  async getCached(path: string, bytes: Buffer): Promise<DocExtractOutcome | undefined> {
122
- const hit = await this.cache.get(this.cacheKey(path, bytes), this.now());
123
- if (!hit) return undefined;
124
- return hit.failed
125
- ? { ok: false, message: hit.message }
126
- : { ok: true, marker: extractionMarker(path, hit.summary), text: hit.text };
145
+ const hit = await this.remembered(this.cacheKey(path, bytes));
146
+ return hit && named(path, hit);
127
147
  }
128
148
 
129
149
  /**
@@ -132,33 +152,46 @@ export class DocExtractService {
132
152
  * `origin`, when given, is where a fresh failure is reported.
133
153
  */
134
154
  async extract(path: string, bytes: Buffer, origin?: ReadOrigin): Promise<DocExtractOutcome> {
155
+ // The bytes are hashed BEFORE the extractor takes its copy of them.
135
156
  const key = this.cacheKey(path, bytes);
136
- const remembered = await this.getCached(path, bytes);
137
- if (remembered) return remembered;
138
- const running = this.inFlight.get(key);
139
- const result = await (running ??
140
- (() => {
141
- // The cache write stays INSIDE the shared promise: were the entry
142
- // dropped as soon as parsing settled, a read arriving during the
143
- // write would miss both the cache and the in-flight map — and parse
144
- // the same document again. The bytes are hashed (above) BEFORE the
145
- // extractor takes its copy of them.
146
- const started = (async (): Promise<IsolatedExtraction> => {
147
- const res = await this.extractor.extract(fileExtension(path), bytes);
148
- if (res.ok) {
149
- await this.cache.put(key, { summary: res.summary, text: res.text });
150
- } else if (res.failure !== 'busy') {
151
- const until = res.failure === 'parser' ? undefined : this.now() + TIMEOUT_MEMORY_MS;
152
- await this.cache.put(key, { failed: true, message: res.message, ...(until === undefined ? {} : { until }) });
153
- if (origin) this.notifyUnreadable({ workspaceId: origin.workspaceId, path, reason: reasonOf(res.message) });
154
- }
155
- return res;
156
- })().finally(() => this.inFlight.delete(key));
157
- this.inFlight.set(key, started);
158
- return started;
159
- })());
160
- if (!result.ok) return { ok: false, message: result.message };
161
- return { ok: true, marker: extractionMarker(path, result.summary), text: result.text };
157
+ return named(path, await (this.inFlight.get(key) ?? this.read(key, path, bytes, origin)));
158
+ }
159
+
160
+ /** What the cache holds for `key`, or undefined on a miss. */
161
+ private async remembered(key: string): Promise<RawOutcome | undefined> {
162
+ const hit = await this.cache.get(key, this.now());
163
+ if (!hit) return undefined;
164
+ return hit.failed ? { ok: false, message: hit.message } : { ok: true, summary: hit.summary, text: hit.text };
165
+ }
166
+
167
+ /**
168
+ * One read of `bytes`, shared by every `extract` of the same key that
169
+ * arrives before it settles (see `inFlight`): the cache lookup, then the
170
+ * extraction and its cache write. The write stays INSIDE the shared
171
+ * promise: were the entry dropped as soon as parsing settled, a read
172
+ * arriving during the write would miss both the cache and the map — and
173
+ * parse the same document again. A failure is reported to the FIRST
174
+ * read's origin and path, once; `path` otherwise gives only the format,
175
+ * which every read of the key shares.
176
+ */
177
+ private read(key: string, path: string, bytes: Buffer, origin: ReadOrigin | undefined): Promise<RawOutcome> {
178
+ const started = (async (): Promise<RawOutcome> => {
179
+ const hit = await this.remembered(key);
180
+ if (hit) return hit;
181
+ const res = await this.extractor.extract(fileExtension(path), bytes);
182
+ if (res.ok) {
183
+ await this.cache.put(key, { summary: res.summary, text: res.text });
184
+ return { ok: true, summary: res.summary, text: res.text };
185
+ }
186
+ if (res.failure !== 'busy') {
187
+ const until = res.failure === 'parser' ? undefined : this.now() + TIMEOUT_MEMORY_MS;
188
+ await this.cache.put(key, { failed: true, message: res.message, ...(until === undefined ? {} : { until }) });
189
+ if (origin) this.notifyUnreadable({ workspaceId: origin.workspaceId, path, reason: reasonOf(res.message) });
190
+ }
191
+ return { ok: false, message: res.message };
192
+ })().finally(() => this.inFlight.delete(key));
193
+ this.inFlight.set(key, started);
194
+ return started;
162
195
  }
163
196
 
164
197
  /** Best-effort, like every event: a listener that throws never fails the read. */
@@ -45,6 +45,26 @@ export { SpillStore } from './spill-store.js';
45
45
  export { DocExtractService } from './file-readers/doc-extract.service.js';
46
46
  export type { IDocumentExtractor } from './file-readers/document-extractor.contract.js';
47
47
  export { WorkerDocumentExtractor } from './file-readers/extract-in-worker.js';
48
+ /**
49
+ * What `grep` runs a caller's pattern with: the matcher contract, its one
50
+ * implementation (ripgrep), and the boot check that ripgrep is there. The
51
+ * composition root wires them through this surface, as a suite does.
52
+ */
53
+ export {
54
+ compareSearchPaths,
55
+ PATTERN_DIALECT,
56
+ PatternRefusedError,
57
+ PatternTooExpensiveError,
58
+ SearchAbandonedError,
59
+ SearchBusyError,
60
+ type FileMatches,
61
+ type IPatternMatcher,
62
+ type IPatternSearch,
63
+ type TreeScope,
64
+ type TreeSearchOptions,
65
+ } from './pattern-matcher.contract.js';
66
+ export { RipgrepPatternMatcher, type RipgrepPatternMatcherOptions } from './ripgrep-search.js';
67
+ export { assertRipgrep } from './ripgrep-version.js';
48
68
  // Reached by other modules; exported here so they stop importing the files.
49
69
  export { isTextBytes } from './file-readers/text-reader.js';
50
70
  export { isUntouchedStarterPage, knowledgeFolderIsNew } from './first-run.js';
@@ -0,0 +1,50 @@
1
+ import { constants as fsConstants, type Stats } from 'node:fs';
2
+ import nodeFs from 'node:fs/promises';
3
+ import type { IPatternSearch } from './pattern-matcher.contract.js';
4
+
5
+ /** How much of a file {@link holdsNul} holds in memory at once. */
6
+ export const NUL_SCAN_CHUNK = 64 * 1024;
7
+
8
+ /**
9
+ * Whether the file at `absolute` holds a NUL, read a chunk at a time and
10
+ * stopped at the first, under the search's budget: a check that outlives it
11
+ * is answered as the search is, and reads no further. The file is opened
12
+ * without following a link, and only the file that was judged (`judged`, its
13
+ * device and inode) is read: a link or another file swapped in since, here or
14
+ * in a folder above it, is not, and holds nothing.
15
+ *
16
+ * The check a named text file gets from `grep` when ripgrep answers no line
17
+ * from it (see `workspace.tools.ts`, `grepTextFile`): ripgrep stops reading a
18
+ * file at the lines the answer can take, so a NUL past them goes unseen by it,
19
+ * and "no searchable text" must be told from "no match" by this read.
20
+ */
21
+ export async function holdsNul(absolute: string, judged: Stats, search: IPatternSearch): Promise<boolean> {
22
+ let stopped = false;
23
+ try {
24
+ return await search.charged(async () => {
25
+ let handle: nodeFs.FileHandle;
26
+ try {
27
+ handle = await nodeFs.open(absolute, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0));
28
+ } catch (err) {
29
+ // ELOOP: the name is a link now. Anything else is the caller's to answer.
30
+ if ((err as { code?: unknown } | null)?.code === 'ELOOP') return false;
31
+ throw err;
32
+ }
33
+ try {
34
+ const opened = await handle.stat();
35
+ if (!opened.isFile() || opened.dev !== judged.dev || opened.ino !== judged.ino) return false;
36
+ const chunk = Buffer.alloc(NUL_SCAN_CHUNK);
37
+ while (!stopped) {
38
+ const { bytesRead } = await handle.read(chunk, 0, chunk.length, null);
39
+ if (bytesRead === 0) return false;
40
+ if (chunk.subarray(0, bytesRead).includes(0)) return true;
41
+ }
42
+ return false;
43
+ } finally {
44
+ await handle.close();
45
+ }
46
+ });
47
+ } finally {
48
+ stopped = true;
49
+ }
50
+ }
@@ -3,47 +3,123 @@ import { ToolError } from '../tool-helpers/index.js';
3
3
  /**
4
4
  * The contract for running a CALLER'S regular expression: what `grep` (REST,
5
5
  * MCP and `call_tool_chain` alike, one handler) depends on, so it never holds
6
- * a concrete engine. The one implementation is `WorkerPatternMatcher`
7
- * (`bounded-matcher.ts`), owned by the composition root and closed with the
6
+ * a concrete engine. The one implementation is `RipgrepPatternMatcher`
7
+ * (`ripgrep-search.ts`), owned by the composition root and closed with the
8
8
  * graph.
9
9
  *
10
- * JavaScript's engine backtracks, so a pattern like `^(a+)+$` over a line of
11
- * forty `a`s and a `!` never finishes. An implementation must therefore never
12
- * run the pattern on the request thread, must stop a search whose matching
13
- * outlives its budget with {@link PatternTooExpensiveError}, and must refuse
14
- * work it cannot take on with {@link SearchBusyError} rather than queue it
15
- * without bound. Within budget, a pattern matches exactly the lines
16
- * `RegExp#test` does.
10
+ * The engine is ripgrep's default one: linear-time, so no pattern can stall
11
+ * it, and RE2-style, so it refuses look-around and backreferences. It runs in
12
+ * child processes, never on the request thread. An implementation must stop a
13
+ * search that outlives its budget with {@link PatternTooExpensiveError},
14
+ * refuse a pattern its engine refuses with {@link PatternRefusedError}, and
15
+ * refuse work it cannot take on with {@link SearchBusyError} rather than queue
16
+ * it without bound.
17
17
  */
18
18
  export interface IPatternMatcher {
19
19
  /**
20
- * One search's matcher for `source`/`flags`: its budget is spent across
21
- * every call it makes. Throws the 400 `Invalid regex` the caller's syntax
22
- * earns, or the 400 `pattern_too_long` an over-long pattern earns.
20
+ * One search's matcher for `pattern`: its budget is spent across every call
21
+ * it makes. Rejects with the 400 {@link PatternRefusedError} when the engine
22
+ * refuses the pattern, or the 400 `pattern_too_long` an over-long pattern
23
+ * earns, before any file is searched. When `signal` aborts (the caller went
24
+ * away), every run the search has going is killed, and the call it was
25
+ * serving rejects with {@link SearchAbandonedError}.
23
26
  */
24
- search(source: string, flags: string): IPatternSearch;
25
- /** Ends the workers; a search after this is refused. */
27
+ search(pattern: string, opts: { ignoreCase: boolean; signal?: AbortSignal }): Promise<IPatternSearch>;
28
+ /** Ends every running search; a search after this is refused. */
26
29
  close(): Promise<void>;
27
30
  }
28
31
 
29
- /** One search, under one budget. */
32
+ /** Where a tree search runs: a directory, never a file. */
33
+ export interface TreeScope {
34
+ /** Absolute, canonical directory the search runs in. */
35
+ cwd: string;
36
+ /** The directory searched, relative to `cwd` (`.` for `cwd` itself). */
37
+ root: string;
38
+ }
39
+
40
+ /** Which files a tree search opens, and how much of each it keeps. */
41
+ export interface TreeSearchOptions {
42
+ /**
43
+ * The files searched, relative to the scope's `root` as
44
+ * {@link IPatternSearch.list} answers them; no other file is opened. A name
45
+ * holding a line break cannot be named to ripgrep exactly and is refused.
46
+ */
47
+ only: readonly string[];
48
+ /**
49
+ * The most lines one file answers: matching stops at it, so a file of
50
+ * millions of matching lines costs its first few and one look for a NUL
51
+ * in the rest, not a record for every line. A matching line that is not
52
+ * UTF-8 is not answered and does not use up the cap.
53
+ */
54
+ maxLinesPerFile: number;
55
+ }
56
+
57
+ /** One file's matching lines, as a tree search finds them. */
58
+ export interface FileMatches {
59
+ /** The file, relative to the scope's `root`, `/`-separated. */
60
+ path: string;
61
+ /** Its matching lines, in order: 1-based numbers, the whole line without its `\n`. */
62
+ lines: { line: number; text: string }[];
63
+ }
64
+
65
+ /**
66
+ * One search, under one budget.
67
+ *
68
+ * A tree search covers every file under the scope's root: hidden files and
69
+ * folders, files a `.gitignore` or `.ignore` names, untracked files. It never
70
+ * enters a folder named `.git` (in any case), never follows a symbolic link,
71
+ * and reads no configuration of its own. Who may read what is not its
72
+ * business: the caller filters what it answers.
73
+ */
30
74
  export interface IPatternSearch {
31
75
  /**
32
- * The indices of the lines the pattern matches, in order, at most `limit` of
33
- * them (the first `limit`, exactly as a loop that stops at the cap finds).
34
- * Throws {@link PatternTooExpensiveError} once the search's budget is spent.
76
+ * The lines the pattern matches in the `only` files under the scope, one
77
+ * file at a time in {@link compareSearchPaths} order, found by the same walk
78
+ * as {@link list}: a named path that has since become a link is not
79
+ * followed. A file whose content is binary contributes nothing, and neither
80
+ * does a line that is not UTF-8. Each file is answered as soon as ripgrep
81
+ * has finished it (whether a file is binary is known only then), so
82
+ * stopping the iteration stops the search at the file the caller had
83
+ * enough with.
84
+ */
85
+ files(scope: TreeScope, opts: TreeSearchOptions): AsyncIterable<FileMatches>;
86
+ /**
87
+ * Every file under the scope, relative to the root, in
88
+ * {@link compareSearchPaths} order: the walk {@link files} makes, without
89
+ * opening a file — what a caller judges before choosing what is searched.
90
+ */
91
+ list(scope: TreeScope): Promise<string[]>;
92
+ /**
93
+ * For each of `texts`, the 0-based indices of its lines (split on `\n`) that
94
+ * the pattern matches, in order.
95
+ */
96
+ matchingLines(texts: readonly string[]): Promise<number[][]>;
97
+ /**
98
+ * Run `work` the search waits on between its runs (judging which files the
99
+ * caller may read) under the search's one budget: the time it takes is
100
+ * spent from it, and work still running when the budget is gone is
101
+ * answered with {@link PatternTooExpensiveError} — or
102
+ * {@link SearchAbandonedError} when the caller has gone — at once, whatever
103
+ * `work` itself does after.
35
104
  */
36
- matchingLines(lines: string[], limit: number): Promise<number[]>;
105
+ charged<T>(work: () => Promise<T>): Promise<T>;
37
106
  }
38
107
 
39
- /** A pattern stopped for taking too long — a 400, worded for the caller. */
108
+ /**
109
+ * The order every search answers in: ripgrep's, path segment by segment, each
110
+ * compared by its UTF-8 bytes. Defined beside the platform's own walk order
111
+ * in `shared/path-order.ts`, which says how the two differ and why the search
112
+ * has one of its own; re-exported here because it is part of this contract.
113
+ */
114
+ export { compareSearchPaths } from '../../shared/path-order.js';
115
+
116
+ /** A search stopped for taking too long — a 400, worded for the caller. */
40
117
  export class PatternTooExpensiveError extends ToolError {
41
118
  constructor(pattern: string, budgetMs: number) {
42
119
  super(
43
- `Pattern too expensive: /${pattern.length > 80 ? `${pattern.slice(0, 80)}…` : pattern}/ did not finish matching within this search's ${budgetMs / 1000} s budget, ` +
44
- 'so it was stopped and nothing was returned. Patterns with nested or overlapping repetition such as ' +
45
- '`(a+)+` or `(a|aa)*` can take exponential time on some lines. Use a simpler pattern — a literal, ' +
46
- 'an anchor, a character class, a single repetition — or narrow `path`.',
120
+ `Pattern too expensive: /${shown(pattern)}/ did not finish within this search's ${budgetMs / 1000} s budget, ` +
121
+ 'so it was stopped and nothing was returned. Narrow `path` to the folder you mean, or use a more ' +
122
+ 'specific pattern.',
47
123
  400,
48
124
  { code: 'pattern_too_expensive' },
49
125
  );
@@ -51,7 +127,19 @@ export class PatternTooExpensiveError extends ToolError {
51
127
  }
52
128
  }
53
129
 
54
- /** Every worker busy and the queue for one full — a 503, so the caller retries rather than reads a partial answer. */
130
+ /** What the engine accepts, as every refusal and the tool's description say it. */
131
+ export const PATTERN_DIALECT =
132
+ "grep runs ripgrep's default regex engine, which takes RE2-style patterns: no look-around and no backreferences.";
133
+
134
+ /** A pattern the engine refuses — a 400 quoting the engine's own reason. */
135
+ export class PatternRefusedError extends ToolError {
136
+ constructor(reason: string) {
137
+ super(`Invalid regex: ${reason}\n${PATTERN_DIALECT}`, 400, { code: 'invalid_pattern' });
138
+ this.name = 'PatternRefusedError';
139
+ }
140
+ }
141
+
142
+ /** Every search slot busy and the queue for one full — a 503, so the caller retries rather than reads a partial answer. */
55
143
  export class SearchBusyError extends ToolError {
56
144
  constructor() {
57
145
  super('Too many searches are running at once; try again in a few seconds.', 503, { code: 'search_busy' });
@@ -59,11 +147,14 @@ export class SearchBusyError extends ToolError {
59
147
  }
60
148
  }
61
149
 
62
- /**
63
- * Whether `err` ends a whole search rather than one file's part of it: a
64
- * directory walk that skipped a file for either would answer an incomplete
65
- * result as if it were the whole one.
66
- */
67
- export function endsTheSearch(err: unknown): boolean {
68
- return err instanceof PatternTooExpensiveError || err instanceof SearchBusyError;
150
+ /** A search whose caller went away: its runs were killed, and nobody is waiting for the answer. */
151
+ export class SearchAbandonedError extends ToolError {
152
+ constructor() {
153
+ super('The search was stopped because its caller went away.', 499, { code: 'search_abandoned' });
154
+ this.name = 'SearchAbandonedError';
155
+ }
156
+ }
157
+
158
+ function shown(pattern: string): string {
159
+ return pattern.length > 80 ? `${pattern.slice(0, 80)}…` : pattern;
69
160
  }