brains-mcp 1.61.2

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 (350) hide show
  1. package/README.md +95 -0
  2. package/dist/access/projectShares.d.ts +48 -0
  3. package/dist/access/projectShares.d.ts.map +1 -0
  4. package/dist/access/projectShares.js +203 -0
  5. package/dist/access/projectShares.js.map +1 -0
  6. package/dist/access/sharedInstructionsNote.d.ts +37 -0
  7. package/dist/access/sharedInstructionsNote.d.ts.map +1 -0
  8. package/dist/access/sharedInstructionsNote.js +76 -0
  9. package/dist/access/sharedInstructionsNote.js.map +1 -0
  10. package/dist/admin/seedUsers.d.ts +23 -0
  11. package/dist/admin/seedUsers.d.ts.map +1 -0
  12. package/dist/admin/seedUsers.js +168 -0
  13. package/dist/admin/seedUsers.js.map +1 -0
  14. package/dist/api/openapi.d.ts +2 -0
  15. package/dist/api/openapi.d.ts.map +1 -0
  16. package/dist/api/openapi.js +942 -0
  17. package/dist/api/openapi.js.map +1 -0
  18. package/dist/auth/clientStore.d.ts +43 -0
  19. package/dist/auth/clientStore.d.ts.map +1 -0
  20. package/dist/auth/clientStore.js +168 -0
  21. package/dist/auth/clientStore.js.map +1 -0
  22. package/dist/auth/deleteAccount.d.ts +34 -0
  23. package/dist/auth/deleteAccount.d.ts.map +1 -0
  24. package/dist/auth/deleteAccount.js +203 -0
  25. package/dist/auth/deleteAccount.js.map +1 -0
  26. package/dist/auth/oauth.d.ts +118 -0
  27. package/dist/auth/oauth.d.ts.map +1 -0
  28. package/dist/auth/oauth.js +491 -0
  29. package/dist/auth/oauth.js.map +1 -0
  30. package/dist/auth/patStore.d.ts +87 -0
  31. package/dist/auth/patStore.d.ts.map +1 -0
  32. package/dist/auth/patStore.js +308 -0
  33. package/dist/auth/patStore.js.map +1 -0
  34. package/dist/auth/supabase.d.ts +15 -0
  35. package/dist/auth/supabase.d.ts.map +1 -0
  36. package/dist/auth/supabase.js +66 -0
  37. package/dist/auth/supabase.js.map +1 -0
  38. package/dist/auth/tokenStore.d.ts +73 -0
  39. package/dist/auth/tokenStore.d.ts.map +1 -0
  40. package/dist/auth/tokenStore.js +261 -0
  41. package/dist/auth/tokenStore.js.map +1 -0
  42. package/dist/backup/drive.d.ts +24 -0
  43. package/dist/backup/drive.d.ts.map +1 -0
  44. package/dist/backup/drive.js +70 -0
  45. package/dist/backup/drive.js.map +1 -0
  46. package/dist/billing/tierStore.d.ts +59 -0
  47. package/dist/billing/tierStore.d.ts.map +1 -0
  48. package/dist/billing/tierStore.js +152 -0
  49. package/dist/billing/tierStore.js.map +1 -0
  50. package/dist/digest/activityDigest.d.ts +32 -0
  51. package/dist/digest/activityDigest.d.ts.map +1 -0
  52. package/dist/digest/activityDigest.js +299 -0
  53. package/dist/digest/activityDigest.js.map +1 -0
  54. package/dist/digest/digestCron.d.ts +40 -0
  55. package/dist/digest/digestCron.d.ts.map +1 -0
  56. package/dist/digest/digestCron.js +146 -0
  57. package/dist/digest/digestCron.js.map +1 -0
  58. package/dist/digest/digestPreferences.d.ts +25 -0
  59. package/dist/digest/digestPreferences.d.ts.map +1 -0
  60. package/dist/digest/digestPreferences.js +79 -0
  61. package/dist/digest/digestPreferences.js.map +1 -0
  62. package/dist/digest/emailSender.d.ts +20 -0
  63. package/dist/digest/emailSender.d.ts.map +1 -0
  64. package/dist/digest/emailSender.js +35 -0
  65. package/dist/digest/emailSender.js.map +1 -0
  66. package/dist/drive/client.d.ts +43 -0
  67. package/dist/drive/client.d.ts.map +1 -0
  68. package/dist/drive/client.js +282 -0
  69. package/dist/drive/client.js.map +1 -0
  70. package/dist/drive/errors.d.ts +27 -0
  71. package/dist/drive/errors.d.ts.map +1 -0
  72. package/dist/drive/errors.js +51 -0
  73. package/dist/drive/errors.js.map +1 -0
  74. package/dist/drive/fileCache.d.ts +22 -0
  75. package/dist/drive/fileCache.d.ts.map +1 -0
  76. package/dist/drive/fileCache.js +57 -0
  77. package/dist/drive/fileCache.js.map +1 -0
  78. package/dist/governance/accessControl.d.ts +87 -0
  79. package/dist/governance/accessControl.d.ts.map +1 -0
  80. package/dist/governance/accessControl.js +179 -0
  81. package/dist/governance/accessControl.js.map +1 -0
  82. package/dist/html/components.d.ts +8 -0
  83. package/dist/html/components.d.ts.map +1 -0
  84. package/dist/html/components.js +19 -0
  85. package/dist/html/components.js.map +1 -0
  86. package/dist/html/layout.d.ts +7 -0
  87. package/dist/html/layout.d.ts.map +1 -0
  88. package/dist/html/layout.js +24 -0
  89. package/dist/html/layout.js.map +1 -0
  90. package/dist/html/metricsUi.d.ts +8 -0
  91. package/dist/html/metricsUi.d.ts.map +1 -0
  92. package/dist/html/metricsUi.js +271 -0
  93. package/dist/html/metricsUi.js.map +1 -0
  94. package/dist/httpServer.d.ts +19 -0
  95. package/dist/httpServer.d.ts.map +1 -0
  96. package/dist/httpServer.js +3913 -0
  97. package/dist/httpServer.js.map +1 -0
  98. package/dist/index.d.ts +3 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +40 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/jobs/asyncJobRegistry.d.ts +30 -0
  103. package/dist/jobs/asyncJobRegistry.d.ts.map +1 -0
  104. package/dist/jobs/asyncJobRegistry.js +70 -0
  105. package/dist/jobs/asyncJobRegistry.js.map +1 -0
  106. package/dist/observability/metricsQuery.d.ts +41 -0
  107. package/dist/observability/metricsQuery.d.ts.map +1 -0
  108. package/dist/observability/metricsQuery.js +106 -0
  109. package/dist/observability/metricsQuery.js.map +1 -0
  110. package/dist/observability/relevanceSignal.d.ts +26 -0
  111. package/dist/observability/relevanceSignal.d.ts.map +1 -0
  112. package/dist/observability/relevanceSignal.js +95 -0
  113. package/dist/observability/relevanceSignal.js.map +1 -0
  114. package/dist/observability/requestEvents.d.ts +31 -0
  115. package/dist/observability/requestEvents.d.ts.map +1 -0
  116. package/dist/observability/requestEvents.js +54 -0
  117. package/dist/observability/requestEvents.js.map +1 -0
  118. package/dist/observability/slowQueryAlert.d.ts +25 -0
  119. package/dist/observability/slowQueryAlert.d.ts.map +1 -0
  120. package/dist/observability/slowQueryAlert.js +67 -0
  121. package/dist/observability/slowQueryAlert.js.map +1 -0
  122. package/dist/observability/zeroResultTriage.d.ts +22 -0
  123. package/dist/observability/zeroResultTriage.d.ts.map +1 -0
  124. package/dist/observability/zeroResultTriage.js +116 -0
  125. package/dist/observability/zeroResultTriage.js.map +1 -0
  126. package/dist/search/embeddings.d.ts +31 -0
  127. package/dist/search/embeddings.d.ts.map +1 -0
  128. package/dist/search/embeddings.js +91 -0
  129. package/dist/search/embeddings.js.map +1 -0
  130. package/dist/search/fileWatcher.d.ts +28 -0
  131. package/dist/search/fileWatcher.d.ts.map +1 -0
  132. package/dist/search/fileWatcher.js +103 -0
  133. package/dist/search/fileWatcher.js.map +1 -0
  134. package/dist/search/hotQueryCache.d.ts +31 -0
  135. package/dist/search/hotQueryCache.d.ts.map +1 -0
  136. package/dist/search/hotQueryCache.js +103 -0
  137. package/dist/search/hotQueryCache.js.map +1 -0
  138. package/dist/search/postgresIndex.d.ts +439 -0
  139. package/dist/search/postgresIndex.d.ts.map +1 -0
  140. package/dist/search/postgresIndex.js +1610 -0
  141. package/dist/search/postgresIndex.js.map +1 -0
  142. package/dist/search/sqliteIndex.d.ts +66 -0
  143. package/dist/search/sqliteIndex.d.ts.map +1 -0
  144. package/dist/search/sqliteIndex.js +342 -0
  145. package/dist/search/sqliteIndex.js.map +1 -0
  146. package/dist/server.d.ts +43 -0
  147. package/dist/server.d.ts.map +1 -0
  148. package/dist/server.js +532 -0
  149. package/dist/server.js.map +1 -0
  150. package/dist/session/bundle.d.ts +53 -0
  151. package/dist/session/bundle.d.ts.map +1 -0
  152. package/dist/session/bundle.js +97 -0
  153. package/dist/session/bundle.js.map +1 -0
  154. package/dist/storage/client.d.ts +157 -0
  155. package/dist/storage/client.d.ts.map +1 -0
  156. package/dist/storage/client.js +825 -0
  157. package/dist/storage/client.js.map +1 -0
  158. package/dist/tools/addWebhookPattern.d.ts +15 -0
  159. package/dist/tools/addWebhookPattern.d.ts.map +1 -0
  160. package/dist/tools/addWebhookPattern.js +15 -0
  161. package/dist/tools/addWebhookPattern.js.map +1 -0
  162. package/dist/tools/appendLog.d.ts +18 -0
  163. package/dist/tools/appendLog.d.ts.map +1 -0
  164. package/dist/tools/appendLog.js +18 -0
  165. package/dist/tools/appendLog.js.map +1 -0
  166. package/dist/tools/auditIndex.d.ts +15 -0
  167. package/dist/tools/auditIndex.d.ts.map +1 -0
  168. package/dist/tools/auditIndex.js +165 -0
  169. package/dist/tools/auditIndex.js.map +1 -0
  170. package/dist/tools/batchDeletePages.d.ts +18 -0
  171. package/dist/tools/batchDeletePages.d.ts.map +1 -0
  172. package/dist/tools/batchDeletePages.js +143 -0
  173. package/dist/tools/batchDeletePages.js.map +1 -0
  174. package/dist/tools/coerce.d.ts +3 -0
  175. package/dist/tools/coerce.d.ts.map +1 -0
  176. package/dist/tools/coerce.js +12 -0
  177. package/dist/tools/coerce.js.map +1 -0
  178. package/dist/tools/createPage.d.ts +24 -0
  179. package/dist/tools/createPage.d.ts.map +1 -0
  180. package/dist/tools/createPage.js +99 -0
  181. package/dist/tools/createPage.js.map +1 -0
  182. package/dist/tools/createPages.d.ts +51 -0
  183. package/dist/tools/createPages.d.ts.map +1 -0
  184. package/dist/tools/createPages.js +91 -0
  185. package/dist/tools/createPages.js.map +1 -0
  186. package/dist/tools/deletePage.d.ts +19 -0
  187. package/dist/tools/deletePage.d.ts.map +1 -0
  188. package/dist/tools/deletePage.js +127 -0
  189. package/dist/tools/deletePage.js.map +1 -0
  190. package/dist/tools/exportWiki.d.ts +48 -0
  191. package/dist/tools/exportWiki.d.ts.map +1 -0
  192. package/dist/tools/exportWiki.js +233 -0
  193. package/dist/tools/exportWiki.js.map +1 -0
  194. package/dist/tools/extractLinks.d.ts +14 -0
  195. package/dist/tools/extractLinks.d.ts.map +1 -0
  196. package/dist/tools/extractLinks.js +25 -0
  197. package/dist/tools/extractLinks.js.map +1 -0
  198. package/dist/tools/generateClaudeInstructions.d.ts +27 -0
  199. package/dist/tools/generateClaudeInstructions.d.ts.map +1 -0
  200. package/dist/tools/generateClaudeInstructions.js +263 -0
  201. package/dist/tools/generateClaudeInstructions.js.map +1 -0
  202. package/dist/tools/generateGptInstructions.d.ts +27 -0
  203. package/dist/tools/generateGptInstructions.d.ts.map +1 -0
  204. package/dist/tools/generateGptInstructions.js +208 -0
  205. package/dist/tools/generateGptInstructions.js.map +1 -0
  206. package/dist/tools/getBacklinks.d.ts +12 -0
  207. package/dist/tools/getBacklinks.d.ts.map +1 -0
  208. package/dist/tools/getBacklinks.js +13 -0
  209. package/dist/tools/getBacklinks.js.map +1 -0
  210. package/dist/tools/getRelated.d.ts +12 -0
  211. package/dist/tools/getRelated.d.ts.map +1 -0
  212. package/dist/tools/getRelated.js +13 -0
  213. package/dist/tools/getRelated.js.map +1 -0
  214. package/dist/tools/healthCheck.d.ts +5 -0
  215. package/dist/tools/healthCheck.d.ts.map +1 -0
  216. package/dist/tools/healthCheck.js +167 -0
  217. package/dist/tools/healthCheck.js.map +1 -0
  218. package/dist/tools/importBrainSource.d.ts +36 -0
  219. package/dist/tools/importBrainSource.d.ts.map +1 -0
  220. package/dist/tools/importBrainSource.js +314 -0
  221. package/dist/tools/importBrainSource.js.map +1 -0
  222. package/dist/tools/importWikiZip.d.ts +60 -0
  223. package/dist/tools/importWikiZip.d.ts.map +1 -0
  224. package/dist/tools/importWikiZip.js +379 -0
  225. package/dist/tools/importWikiZip.js.map +1 -0
  226. package/dist/tools/initProject.d.ts +34 -0
  227. package/dist/tools/initProject.d.ts.map +1 -0
  228. package/dist/tools/initProject.js +443 -0
  229. package/dist/tools/initProject.js.map +1 -0
  230. package/dist/tools/instructionContext.d.ts +60 -0
  231. package/dist/tools/instructionContext.d.ts.map +1 -0
  232. package/dist/tools/instructionContext.js +210 -0
  233. package/dist/tools/instructionContext.js.map +1 -0
  234. package/dist/tools/listArchivedPages.d.ts +17 -0
  235. package/dist/tools/listArchivedPages.d.ts.map +1 -0
  236. package/dist/tools/listArchivedPages.js +51 -0
  237. package/dist/tools/listArchivedPages.js.map +1 -0
  238. package/dist/tools/listPages.d.ts +28 -0
  239. package/dist/tools/listPages.d.ts.map +1 -0
  240. package/dist/tools/listPages.js +166 -0
  241. package/dist/tools/listPages.js.map +1 -0
  242. package/dist/tools/listWebhooks.d.ts +7 -0
  243. package/dist/tools/listWebhooks.d.ts.map +1 -0
  244. package/dist/tools/listWebhooks.js +10 -0
  245. package/dist/tools/listWebhooks.js.map +1 -0
  246. package/dist/tools/movePage.d.ts +18 -0
  247. package/dist/tools/movePage.d.ts.map +1 -0
  248. package/dist/tools/movePage.js +182 -0
  249. package/dist/tools/movePage.js.map +1 -0
  250. package/dist/tools/pageHistory.d.ts +36 -0
  251. package/dist/tools/pageHistory.d.ts.map +1 -0
  252. package/dist/tools/pageHistory.js +60 -0
  253. package/dist/tools/pageHistory.js.map +1 -0
  254. package/dist/tools/patchPage.d.ts +141 -0
  255. package/dist/tools/patchPage.d.ts.map +1 -0
  256. package/dist/tools/patchPage.js +287 -0
  257. package/dist/tools/patchPage.js.map +1 -0
  258. package/dist/tools/pullSessionBundle.d.ts +34 -0
  259. package/dist/tools/pullSessionBundle.d.ts.map +1 -0
  260. package/dist/tools/pullSessionBundle.js +432 -0
  261. package/dist/tools/pullSessionBundle.js.map +1 -0
  262. package/dist/tools/purgeWiki.d.ts +23 -0
  263. package/dist/tools/purgeWiki.d.ts.map +1 -0
  264. package/dist/tools/purgeWiki.js +113 -0
  265. package/dist/tools/purgeWiki.js.map +1 -0
  266. package/dist/tools/pushSessionBundle.d.ts +139 -0
  267. package/dist/tools/pushSessionBundle.d.ts.map +1 -0
  268. package/dist/tools/pushSessionBundle.js +282 -0
  269. package/dist/tools/pushSessionBundle.js.map +1 -0
  270. package/dist/tools/readGovernanceAudit.d.ts +17 -0
  271. package/dist/tools/readGovernanceAudit.d.ts.map +1 -0
  272. package/dist/tools/readGovernanceAudit.js +21 -0
  273. package/dist/tools/readGovernanceAudit.js.map +1 -0
  274. package/dist/tools/readPage.d.ts +13 -0
  275. package/dist/tools/readPage.d.ts.map +1 -0
  276. package/dist/tools/readPage.js +46 -0
  277. package/dist/tools/readPage.js.map +1 -0
  278. package/dist/tools/removeWebhook.d.ts +14 -0
  279. package/dist/tools/removeWebhook.d.ts.map +1 -0
  280. package/dist/tools/removeWebhook.js +12 -0
  281. package/dist/tools/removeWebhook.js.map +1 -0
  282. package/dist/tools/resolveProject.d.ts +58 -0
  283. package/dist/tools/resolveProject.d.ts.map +1 -0
  284. package/dist/tools/resolveProject.js +175 -0
  285. package/dist/tools/resolveProject.js.map +1 -0
  286. package/dist/tools/restorePage.d.ts +47 -0
  287. package/dist/tools/restorePage.d.ts.map +1 -0
  288. package/dist/tools/restorePage.js +111 -0
  289. package/dist/tools/restorePage.js.map +1 -0
  290. package/dist/tools/searchPages.d.ts +28 -0
  291. package/dist/tools/searchPages.d.ts.map +1 -0
  292. package/dist/tools/searchPages.js +372 -0
  293. package/dist/tools/searchPages.js.map +1 -0
  294. package/dist/tools/setWebhook.d.ts +30 -0
  295. package/dist/tools/setWebhook.d.ts.map +1 -0
  296. package/dist/tools/setWebhook.js +30 -0
  297. package/dist/tools/setWebhook.js.map +1 -0
  298. package/dist/tools/shareProject.d.ts +25 -0
  299. package/dist/tools/shareProject.d.ts.map +1 -0
  300. package/dist/tools/shareProject.js +56 -0
  301. package/dist/tools/shareProject.js.map +1 -0
  302. package/dist/tools/suggestLinks.d.ts +29 -0
  303. package/dist/tools/suggestLinks.d.ts.map +1 -0
  304. package/dist/tools/suggestLinks.js +214 -0
  305. package/dist/tools/suggestLinks.js.map +1 -0
  306. package/dist/tools/updatePage.d.ts +27 -0
  307. package/dist/tools/updatePage.d.ts.map +1 -0
  308. package/dist/tools/updatePage.js +118 -0
  309. package/dist/tools/updatePage.js.map +1 -0
  310. package/dist/webhooks/dispatch.d.ts +49 -0
  311. package/dist/webhooks/dispatch.d.ts.map +1 -0
  312. package/dist/webhooks/dispatch.js +159 -0
  313. package/dist/webhooks/dispatch.js.map +1 -0
  314. package/dist/webhooks/webhookRules.d.ts +34 -0
  315. package/dist/webhooks/webhookRules.d.ts.map +1 -0
  316. package/dist/webhooks/webhookRules.js +129 -0
  317. package/dist/webhooks/webhookRules.js.map +1 -0
  318. package/dist/wiki/frontmatter.d.ts +45 -0
  319. package/dist/wiki/frontmatter.d.ts.map +1 -0
  320. package/dist/wiki/frontmatter.js +68 -0
  321. package/dist/wiki/frontmatter.js.map +1 -0
  322. package/dist/wiki/index.d.ts +22 -0
  323. package/dist/wiki/index.d.ts.map +1 -0
  324. package/dist/wiki/index.js +203 -0
  325. package/dist/wiki/index.js.map +1 -0
  326. package/dist/wiki/ingestPolicy.d.ts +18 -0
  327. package/dist/wiki/ingestPolicy.d.ts.map +1 -0
  328. package/dist/wiki/ingestPolicy.js +64 -0
  329. package/dist/wiki/ingestPolicy.js.map +1 -0
  330. package/dist/wiki/layoutLint.d.ts +51 -0
  331. package/dist/wiki/layoutLint.d.ts.map +1 -0
  332. package/dist/wiki/layoutLint.js +146 -0
  333. package/dist/wiki/layoutLint.js.map +1 -0
  334. package/dist/wiki/links.d.ts +6 -0
  335. package/dist/wiki/links.d.ts.map +1 -0
  336. package/dist/wiki/links.js +45 -0
  337. package/dist/wiki/links.js.map +1 -0
  338. package/dist/wiki/log.d.ts +58 -0
  339. package/dist/wiki/log.d.ts.map +1 -0
  340. package/dist/wiki/log.js +126 -0
  341. package/dist/wiki/log.js.map +1 -0
  342. package/dist/wiki/path.d.ts +8 -0
  343. package/dist/wiki/path.d.ts.map +1 -0
  344. package/dist/wiki/path.js +25 -0
  345. package/dist/wiki/path.js.map +1 -0
  346. package/dist/wiki/storageLimits.d.ts +163 -0
  347. package/dist/wiki/storageLimits.d.ts.map +1 -0
  348. package/dist/wiki/storageLimits.js +281 -0
  349. package/dist/wiki/storageLimits.js.map +1 -0
  350. package/package.json +81 -0
@@ -0,0 +1,432 @@
1
+ import { z } from "zod";
2
+ import matter from "gray-matter";
3
+ import { resolveIndexOwnerSubject } from "../storage/client.js";
4
+ import { serializeBundle, buildBundleHeader } from "../session/bundle.js";
5
+ import { getPostgresSearchIndex } from "../search/postgresIndex.js";
6
+ import { listActiveGrantsForGrantee } from "../access/projectShares.js";
7
+ import { DEFAULT_ACCESS_CONTEXT, isHiveModeEnabled, parseAccessLevel, parseAudience, pagePassesFilter, writeGovernanceAuditEntry, } from "../governance/accessControl.js";
8
+ const MIN_BYTES = 1024;
9
+ const MAX_BYTES = 200_000;
10
+ const DEFAULT_MAX_BYTES = 150_000;
11
+ const DEFAULT_MAX_PAGES = 10;
12
+ const FTS_MAX_RESULTS = 500;
13
+ const SYSTEM_FILES = new Set(["index.md", "log.md"]);
14
+ export const pullSessionBundleInputSchema = z.object({
15
+ folder: z
16
+ .string()
17
+ .optional()
18
+ .describe("Optional path prefix filter (e.g. 'projects/brainsapp')."),
19
+ tags: z
20
+ .array(z.string())
21
+ .optional()
22
+ .describe("Optional tag filter — any-match OR semantics. Pages matching any of the given tags are included."),
23
+ query: z
24
+ .string()
25
+ .optional()
26
+ .describe("Optional full-text query for relevance-ranked selection when Postgres search is enabled."),
27
+ includeSystem: z
28
+ .boolean()
29
+ .default(false)
30
+ .describe("If true, includes system files index.md and log.md."),
31
+ cursor: z
32
+ .string()
33
+ .optional()
34
+ .describe("Opaque continuation token from a prior call's nextCursor. Omit for the first page."),
35
+ maxBytes: z
36
+ .number()
37
+ .default(DEFAULT_MAX_BYTES)
38
+ .describe(`Soft cap on bundle text size in bytes (clamp ${MIN_BYTES}–${MAX_BYTES}). Default: ${DEFAULT_MAX_BYTES}.`),
39
+ maxPages: z
40
+ .number()
41
+ .default(DEFAULT_MAX_PAGES)
42
+ .describe(`Hard cap on pages per slice. Default: ${DEFAULT_MAX_PAGES}.`),
43
+ session_audience: z
44
+ .enum(["internal", "client-safe", "public"])
45
+ .optional()
46
+ .describe("Optional audience constraint for this session. When set, only pages whose audience matches are included. " +
47
+ "'client-safe' → client-safe + public pages. 'public' → public pages only. " +
48
+ "Only effective when BRAINS_HIVE_MODE=true."),
49
+ });
50
+ function encodeCursor(lastName) {
51
+ return Buffer.from(JSON.stringify({ lastName }), "utf8").toString("base64");
52
+ }
53
+ function decodeCursor(cursor) {
54
+ try {
55
+ const parsed = JSON.parse(Buffer.from(cursor, "base64").toString("utf8"));
56
+ if (typeof parsed === "object" &&
57
+ parsed !== null &&
58
+ "lastName" in parsed &&
59
+ typeof parsed.lastName === "string") {
60
+ return parsed;
61
+ }
62
+ throw new Error("missing lastName");
63
+ }
64
+ catch {
65
+ throw new Error("Invalid cursor: malformed or corrupt");
66
+ }
67
+ }
68
+ function pageMatchesFilter(name, content, normalizedFolder, tags) {
69
+ const hasFilter = normalizedFolder !== undefined || (tags !== undefined && tags.length > 0);
70
+ if (!hasFilter)
71
+ return true;
72
+ const matchesFolder = normalizedFolder ? name.startsWith(normalizedFolder) : false;
73
+ if (tags && tags.length > 0) {
74
+ try {
75
+ const parsed = matter(content);
76
+ const pageTags = parsed.data?.tags ?? [];
77
+ if (tags.some((t) => pageTags.includes(t)))
78
+ return true;
79
+ }
80
+ catch {
81
+ // fall through to folder match
82
+ }
83
+ }
84
+ return matchesFolder;
85
+ }
86
+ /**
87
+ * Active project-share grants (BRA-368) for `userId`, narrowed to those
88
+ * relevant to `folder` (if set) so a folder-scoped bundle pull doesn't drag
89
+ * in unrelated shared projects. Without this, a grantee's bundle only ever
90
+ * contains their own pages — the owner's shared content is invisible
91
+ * (BRA-383, mirrors the list_pages/search_pages fix in BRA-379/#380).
92
+ */
93
+ async function grantScopesFor(userId, folder) {
94
+ if (!userId)
95
+ return [];
96
+ // Strip any trailing slash before comparing — callers may pass either
97
+ // form, but a raw trailing slash would double up in the startsWith
98
+ // checks below (e.g. "projects/" -> "projects//") and silently drop
99
+ // otherwise-matching grants.
100
+ const normalizedFolder = folder ? folder.replace(/\/$/, "") : undefined;
101
+ const grants = await listActiveGrantsForGrantee(userId).catch(() => []);
102
+ return grants
103
+ .filter((g) => !normalizedFolder ||
104
+ g.project_path === normalizedFolder ||
105
+ g.project_path.startsWith(`${normalizedFolder}/`) ||
106
+ normalizedFolder.startsWith(`${g.project_path}/`))
107
+ .map((g) => ({ userId: g.owner_subject, folder: g.project_path }));
108
+ }
109
+ function usePostgresIndex() {
110
+ const searchBackend = (process.env.SEARCH_BACKEND ?? "").toLowerCase();
111
+ const storageBackend = (process.env.STORAGE_BACKEND ?? "local").toLowerCase();
112
+ return (storageBackend === "supabase" &&
113
+ searchBackend !== "sqlite" &&
114
+ searchBackend !== "scan");
115
+ }
116
+ /**
117
+ * The files at a project root that every instruction file tells an agent to read
118
+ * first. They are hoisted ahead of the rest of the candidate list so a capped
119
+ * slice cannot drop them.
120
+ *
121
+ * They were being dropped, and the ordering made it systematic rather than
122
+ * unlucky. `listPages` returns `modified.desc.nullslast,name.asc`, so candidate
123
+ * order is newest-touched-first — which means any bulk operation buries the
124
+ * pages that matter most. Measured on `projects/oio` (GH #462): a migration
125
+ * touched 22 pages over seven minutes, and the next `folder=projects/oio` pull
126
+ * returned 20 pages, all of them from that migration window. `status.md` and
127
+ * `readme.md`, untouched two hours earlier, sorted to positions ~27 and ~28 and
128
+ * fell outside the byte cap. The better-maintained the project, the more
129
+ * reliably its entry points get pushed out of its own bundle.
130
+ */
131
+ const CONVENTIONAL_ROOT_FILES = ["readme.md", "status.md", "open-loops.md", "index.md"];
132
+ function conventionalRootPaths(folder) {
133
+ if (!folder)
134
+ return [];
135
+ const prefix = folder.replace(/\/$/, "") + "/";
136
+ return CONVENTIONAL_ROOT_FILES.map((name) => prefix + name);
137
+ }
138
+ function hoistConventionalRootFiles(candidates, folder) {
139
+ const priority = conventionalRootPaths(folder);
140
+ if (priority.length === 0)
141
+ return candidates;
142
+ const rank = new Map(priority.map((name, i) => [name, i]));
143
+ const hoisted = [];
144
+ const rest = [];
145
+ for (const name of candidates) {
146
+ if (rank.has(name))
147
+ hoisted.push(name);
148
+ else
149
+ rest.push(name);
150
+ }
151
+ if (hoisted.length === 0)
152
+ return candidates;
153
+ hoisted.sort((a, b) => rank.get(a) - rank.get(b));
154
+ return [...hoisted, ...rest];
155
+ }
156
+ async function getCandidateNames(drive, folder, tags, query, includeSystem, userId, accessCtx) {
157
+ const normalizedFolder = folder ? folder.replace(/\/$/, "") + "/" : undefined;
158
+ if (usePostgresIndex()) {
159
+ const index = getPostgresSearchIndex();
160
+ const accessLevel = isHiveModeEnabled() ? accessCtx.userAccessLevel : undefined;
161
+ // Folder must be pushed into the query, not applied to the result.
162
+ // Without it these calls fetch every page the user has and filter in JS —
163
+ // but PostgREST caps rows, so the cap truncates before the filter runs and
164
+ // the folder pull silently undercounts. Measured on a 2,750-page wiki:
165
+ // folder=projects/job-search returned 164 of a true 213, losing the 49
166
+ // oldest by modified date, which is the order the cap slices on (GH #432).
167
+ // listPages/search take the prefix without a trailing slash.
168
+ const folderPrefix = folder ? folder.replace(/\/$/, "") : undefined;
169
+ // Cross-account sharing (BRA-383): without this, a grantee's bundle only
170
+ // ever contains pages they authored themselves — the owner's shared
171
+ // content never comes back, same root cause as BRA-379/#380.
172
+ const grantScopes = await grantScopesFor(userId, folder);
173
+ let names;
174
+ const trimmedQuery = query?.trim();
175
+ if (trimmedQuery) {
176
+ let rankedLists;
177
+ if (tags && tags.length > 0) {
178
+ rankedLists = await Promise.all(tags.map((tag) => index.search({ query: trimmedQuery, tag, folder: folderPrefix, maxResults: FTS_MAX_RESULTS, userId, accessLevel, grantScopes })
179
+ .then((result) => result.results.map((r) => r.name))));
180
+ }
181
+ else {
182
+ const searchResult = await index.search({
183
+ query: trimmedQuery,
184
+ folder: folderPrefix,
185
+ maxResults: FTS_MAX_RESULTS,
186
+ userId,
187
+ accessLevel,
188
+ grantScopes,
189
+ });
190
+ rankedLists = [searchResult.results.map((r) => r.name)];
191
+ }
192
+ const seen = new Set();
193
+ names = [];
194
+ for (const list of rankedLists) {
195
+ for (const name of list) {
196
+ if (!seen.has(name)) {
197
+ seen.add(name);
198
+ names.push(name);
199
+ }
200
+ }
201
+ }
202
+ }
203
+ else if (tags && tags.length > 0) {
204
+ const sets = await Promise.all(tags.map((tag) => index.listPages({ tag, folder: folderPrefix, userId, accessLevel, grantScopes }).then((rows) => rows.map((r) => r.name))));
205
+ const union = new Set();
206
+ for (const set of sets)
207
+ for (const name of set)
208
+ union.add(name);
209
+ names = Array.from(union);
210
+ }
211
+ else {
212
+ const rows = await index.listPages({ folder: folderPrefix, userId, accessLevel, grantScopes });
213
+ names = rows.map((r) => r.name);
214
+ }
215
+ // Belt-and-braces: the prefix is already applied server-side above, so this
216
+ // only catches anything a scope merge might reintroduce.
217
+ if (normalizedFolder) {
218
+ names = names.filter((name) => name.startsWith(normalizedFolder));
219
+ }
220
+ // Exclude system files unless includeSystem is set
221
+ if (!includeSystem) {
222
+ names = names.filter((name) => !SYSTEM_FILES.has(name));
223
+ }
224
+ // Exclude version-history snapshots regardless of includeSystem
225
+ names = names.filter((name) => !name.startsWith("page-versions/"));
226
+ return names;
227
+ }
228
+ // Fallback: drive.listFiles() + frontmatter scan for tags
229
+ const allFiles = await drive.listFiles();
230
+ const candidates = [];
231
+ const hasFilter = normalizedFolder !== undefined || (tags !== undefined && tags.length > 0);
232
+ const hiveActive = isHiveModeEnabled();
233
+ /**
234
+ * Check governance access for a file whose content has already been read.
235
+ * Returns false and emits an audit entry when the page should be excluded.
236
+ */
237
+ function passesGovernanceFilter(name, content) {
238
+ if (!hiveActive)
239
+ return true;
240
+ const parsed = matter(content);
241
+ const pageLevel = parseAccessLevel(parsed.data.access_level);
242
+ const pageAudience = parseAudience(parsed.data.audience);
243
+ if (!pagePassesFilter(pageLevel, pageAudience, accessCtx.userAccessLevel, accessCtx.sessionAudience)) {
244
+ writeGovernanceAuditEntry(userId, name, pageLevel, accessCtx.userAccessLevel, accessCtx.sessionAudience, pageLevel > accessCtx.userAccessLevel ? "access_level_exceeded" : "audience_mismatch");
245
+ return false;
246
+ }
247
+ return true;
248
+ }
249
+ for (const entry of allFiles) {
250
+ if (!entry.name.endsWith(".md"))
251
+ continue;
252
+ if (!includeSystem && SYSTEM_FILES.has(entry.name))
253
+ continue;
254
+ if (entry.name.startsWith("page-versions/"))
255
+ continue;
256
+ if (!hasFilter && !hiveActive) {
257
+ candidates.push(entry.name);
258
+ continue;
259
+ }
260
+ // We need to read file content for tag matching or access filtering
261
+ if (tags && tags.length > 0) {
262
+ const file = await drive.readFile(entry.name);
263
+ if (!passesGovernanceFilter(entry.name, file.content))
264
+ continue;
265
+ if (pageMatchesFilter(entry.name, file.content, normalizedFolder, tags)) {
266
+ candidates.push(entry.name);
267
+ }
268
+ }
269
+ else if (normalizedFolder && entry.name.startsWith(normalizedFolder)) {
270
+ if (hiveActive) {
271
+ const file = await drive.readFile(entry.name);
272
+ if (!passesGovernanceFilter(entry.name, file.content))
273
+ continue;
274
+ }
275
+ candidates.push(entry.name);
276
+ }
277
+ else if (!hasFilter) {
278
+ if (hiveActive) {
279
+ const file = await drive.readFile(entry.name);
280
+ if (!passesGovernanceFilter(entry.name, file.content))
281
+ continue;
282
+ }
283
+ candidates.push(entry.name);
284
+ }
285
+ }
286
+ return candidates.sort();
287
+ }
288
+ export async function pullSessionBundle(drive, input, userId = "", accessCtx = DEFAULT_ACCESS_CONTEXT) {
289
+ const maxBytes = Math.min(Math.max(input.maxBytes, MIN_BYTES), MAX_BYTES);
290
+ const maxPages = Math.max(1, input.maxPages);
291
+ // Decode cursor if present
292
+ let lastNameFromCursor;
293
+ if (input.cursor) {
294
+ try {
295
+ const decoded = decodeCursor(input.cursor);
296
+ lastNameFromCursor = decoded.lastName;
297
+ }
298
+ catch (err) {
299
+ return { ok: false, error: err instanceof Error ? err.message : "Invalid cursor" };
300
+ }
301
+ }
302
+ // Merge session_audience from input into the access context
303
+ const effectiveAccessCtx = {
304
+ ...accessCtx,
305
+ sessionAudience: input.session_audience ?? accessCtx.sessionAudience,
306
+ };
307
+ // Get candidate names
308
+ const rawCandidates = await getCandidateNames(drive, input.folder, input.tags, input.query, input.includeSystem, userId, effectiveAccessCtx);
309
+ // Hoist the project's entry points, but only on a plain folder pull. With a
310
+ // query the caller asked for specific content and the list is relevance-ranked;
311
+ // promoting four fixed files ahead of the hits would answer a different
312
+ // question than the one asked.
313
+ const allCandidates = input.query?.trim()
314
+ ? rawCandidates
315
+ : hoistConventionalRootFiles(rawCandidates, input.folder);
316
+ const totalMatchingPages = allCandidates.length;
317
+ // Naming the filter and the match count lets an agent judge whether the bundle
318
+ // plausibly covers what it needs. Without it, an under-matching filter yields a
319
+ // bundle that looks authoritative — see buildBundleHeader's note. Computed
320
+ // before the selection loop because header size counts against maxBytes.
321
+ const filterParts = [];
322
+ if (input.folder)
323
+ filterParts.push(`folder=${input.folder}`);
324
+ if (input.tags && input.tags.length > 0)
325
+ filterParts.push(`tags=[${input.tags.join(", ")}]`);
326
+ if (input.query?.trim())
327
+ filterParts.push(`query="${input.query.trim()}"`);
328
+ const filterDescription = filterParts.length > 0 ? filterParts.join(" ") : "no filter (whole wiki)";
329
+ const candidatePositions = new Map(allCandidates.map((name, index) => [name, index]));
330
+ // Which entry points actually exist for this folder. Hoisting means they are
331
+ // normally all included, so this is a backstop for the cases hoisting does not
332
+ // cover: a query pull, a tags-only pull with no folder, a cap too small to fit
333
+ // even these, or a later slice reached by cursor.
334
+ const conventionalPresent = conventionalRootPaths(input.folder).filter((name) => candidatePositions.has(name));
335
+ // Skip past cursor based on candidate order
336
+ const remaining = (() => {
337
+ if (!lastNameFromCursor)
338
+ return allCandidates;
339
+ const cursorIndex = candidatePositions.get(lastNameFromCursor) ?? -1;
340
+ return cursorIndex >= 0 ? allCandidates.slice(cursorIndex + 1) : allCandidates;
341
+ })();
342
+ // Build bundle slice
343
+ const includedPages = [];
344
+ const bundlePages = [];
345
+ const errors = [];
346
+ let bundleBytes = 0;
347
+ let lastProcessed;
348
+ for (const name of remaining) {
349
+ if (includedPages.length >= maxPages)
350
+ break;
351
+ let file;
352
+ try {
353
+ // Hot path: read from DB row when Postgres is the primary (avoids Storage read on stale mirror).
354
+ // Cross-account sharing (BRA-383): the row (if any) is indexed under the
355
+ // true storage owner, not the raw actor — resolve that first so shared
356
+ // content actually hits the hot path instead of falling back silently.
357
+ const dbRow = usePostgresIndex()
358
+ ? await getPostgresSearchIndex().fetchPageRow(name, resolveIndexOwnerSubject(drive, name, userId)).catch(() => null)
359
+ : null;
360
+ file = dbRow ?? await drive.readFile(name);
361
+ }
362
+ catch (err) {
363
+ errors.push({ name, reason: err instanceof Error ? err.message : String(err) });
364
+ lastProcessed = name;
365
+ continue;
366
+ }
367
+ const delimiter = `===PAGE: ${name}===\n`;
368
+ const pageContrib = (bundlePages.length === 0 ? delimiter : "\n" + delimiter) + file.content;
369
+ const pageBytes = Buffer.byteLength(pageContrib, "utf8");
370
+ // The working-set header ships inside `bundle`, so its bytes count against
371
+ // maxBytes too — it grows by a line per page, so ignoring it would overshoot
372
+ // by more the larger the bundle. Measured against the truncated variant,
373
+ // which is the longer of the two: adding a page can be what causes the next
374
+ // one to be dropped, and the resulting truncation notice must already fit.
375
+ const prospectiveHeaderBytes = Buffer.byteLength(buildBundleHeader([...bundlePages, { name }], {
376
+ truncated: true,
377
+ filter: filterDescription,
378
+ totalMatching: totalMatchingPages,
379
+ // Worst case — assume every entry point ends up omitted, so the estimate
380
+ // is never smaller than the header this bundle actually ships with.
381
+ omittedConventional: conventionalPresent,
382
+ }), "utf8");
383
+ if (prospectiveHeaderBytes + bundleBytes + pageBytes > maxBytes && includedPages.length > 0) {
384
+ // Would exceed soft cap — stop here (but only if we already have at least one page)
385
+ break;
386
+ }
387
+ bundlePages.push({ name, content: file.content });
388
+ includedPages.push({
389
+ name,
390
+ bytes: Buffer.byteLength(file.content, "utf8"),
391
+ modifiedTime: file.modifiedTime,
392
+ revision: file.revision,
393
+ });
394
+ bundleBytes += pageBytes;
395
+ lastProcessed = name;
396
+ }
397
+ // Compute nextCursor: advance past all attempted pages (including those that errored),
398
+ // so subsequent slices don't get stuck on an unreadable page.
399
+ const lastProcessedIndex = lastProcessed === undefined
400
+ ? -1
401
+ : (candidatePositions.get(lastProcessed) ?? -1);
402
+ const hasMore = lastProcessedIndex >= 0 && lastProcessedIndex < allCandidates.length - 1;
403
+ const nextCursor = hasMore ? encodeCursor(lastProcessed) : undefined;
404
+ // Header is composed after hasMore so a truncated bundle can say so — an agent
405
+ // that cannot tell whether a page was included will re-read defensively, which
406
+ // is exactly the behaviour this is meant to remove (GH #426).
407
+ // Naming the filter and the match count lets an agent judge whether the
408
+ // bundle plausibly covers what it needs. Without it, an under-matching filter
409
+ // produces a bundle that looks authoritative — see the header's own note.
410
+ // A count of "20 of 132" does not tell an agent that the 112 it did not get
411
+ // include the two pages its instructions call read-first. Name them.
412
+ const includedNames = new Set(includedPages.map((p) => p.name));
413
+ const omittedConventional = conventionalPresent.filter((name) => !includedNames.has(name));
414
+ const bundle = buildBundleHeader(bundlePages, {
415
+ truncated: hasMore,
416
+ filter: filterDescription,
417
+ totalMatching: totalMatchingPages,
418
+ omittedConventional,
419
+ }) + serializeBundle(bundlePages);
420
+ return {
421
+ ok: true,
422
+ bundle,
423
+ pages: includedPages,
424
+ pageCount: includedPages.length,
425
+ totalMatchingPages,
426
+ bytes: Buffer.byteLength(bundle, "utf8"),
427
+ generatedAt: new Date().toISOString(),
428
+ ...(errors.length > 0 ? { errors } : {}),
429
+ ...(nextCursor !== undefined ? { nextCursor } : {}),
430
+ };
431
+ }
432
+ //# sourceMappingURL=pullSessionBundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pullSessionBundle.js","sourceRoot":"","sources":["../../src/tools/pullSessionBundle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ import type { StorageClient } from "../storage/client.js";
3
+ export declare const purgeWikiInputSchema: z.ZodObject<{
4
+ confirm: z.ZodDefault<z.ZodBoolean>;
5
+ exportBeforeDelete: z.ZodDefault<z.ZodBoolean>;
6
+ exportOutputPath: z.ZodOptional<z.ZodString>;
7
+ includeSystem: z.ZodDefault<z.ZodBoolean>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ includeSystem: boolean;
10
+ confirm: boolean;
11
+ exportBeforeDelete: boolean;
12
+ exportOutputPath?: string | undefined;
13
+ }, {
14
+ includeSystem?: boolean | undefined;
15
+ confirm?: boolean | undefined;
16
+ exportBeforeDelete?: boolean | undefined;
17
+ exportOutputPath?: string | undefined;
18
+ }>;
19
+ export type PurgeWikiInput = z.infer<typeof purgeWikiInputSchema>;
20
+ export declare function purgeWiki(drive: StorageClient, input: PurgeWikiInput, userId?: string, opts?: {
21
+ onProgress?: (processed: number, total: number) => void;
22
+ }): Promise<object>;
23
+ //# sourceMappingURL=purgeWiki.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purgeWiki.d.ts","sourceRoot":"","sources":["../../src/tools/purgeWiki.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK1D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;EA6B/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIlE,wBAAsB,SAAS,CAC9B,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,cAAc,EACrB,MAAM,SAAK,EACX,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAO,GACpE,OAAO,CAAC,MAAM,CAAC,CAkGjB"}
@@ -0,0 +1,113 @@
1
+ import { z } from "zod";
2
+ import { exportWiki } from "./exportWiki.js";
3
+ import { appendLogEntry } from "../wiki/log.js";
4
+ import { getPostgresSearchIndex } from "../search/postgresIndex.js";
5
+ export const purgeWikiInputSchema = z.object({
6
+ confirm: z
7
+ .boolean()
8
+ .default(false)
9
+ .describe("Must be set to true to proceed with deletion. " +
10
+ "If false, returns a warning with the list of files that would be deleted."),
11
+ exportBeforeDelete: z
12
+ .boolean()
13
+ .default(false)
14
+ .describe("If true, runs export_wiki to create a ZIP archive before deleting. " +
15
+ "Requires exportOutputPath to be set."),
16
+ exportOutputPath: z
17
+ .string()
18
+ .optional()
19
+ .describe("Path where the ZIP archive will be written when exportBeforeDelete is true " +
20
+ "(e.g. '/tmp/wiki-backup.zip'). Required when exportBeforeDelete is true."),
21
+ includeSystem: z
22
+ .boolean()
23
+ .default(false)
24
+ .describe("If true, also deletes system files index.md and log.md. " +
25
+ "Default is false to protect system files."),
26
+ });
27
+ const SYSTEM_FILES = new Set(["index.md", "log.md"]);
28
+ export async function purgeWiki(drive, input, userId = "", opts = {}) {
29
+ const files = await drive.listFiles();
30
+ const toDelete = files.filter((f) => input.includeSystem || !SYSTEM_FILES.has(f.name));
31
+ if (!input.confirm) {
32
+ return {
33
+ success: false,
34
+ confirmed: false,
35
+ warning: "This operation will permanently delete all wiki pages. " +
36
+ "Set confirm=true to proceed. " +
37
+ "Set exportBeforeDelete=true with exportOutputPath to create a backup first.",
38
+ fileCount: toDelete.length,
39
+ files: toDelete.map((f) => f.name),
40
+ };
41
+ }
42
+ if (input.exportBeforeDelete) {
43
+ if (!input.exportOutputPath) {
44
+ return {
45
+ success: false,
46
+ error: "exportOutputPath is required when exportBeforeDelete is true. " +
47
+ "Provide a path such as '/tmp/wiki-backup.zip'.",
48
+ };
49
+ }
50
+ await exportWiki(drive, {
51
+ outputPath: input.exportOutputPath,
52
+ includeSystem: true,
53
+ });
54
+ }
55
+ const deleted = [];
56
+ const failures = [];
57
+ // Flush Postgres index deletes every FLUSH_CHUNK files so that if the process is
58
+ // interrupted mid-loop, at most FLUSH_CHUNK ghost rows are left rather than all of them.
59
+ const FLUSH_CHUNK = 50;
60
+ const pgIndex = getPostgresSearchIndex();
61
+ const pgConfigured = pgIndex.isConfigured();
62
+ const pendingIndexDeletes = [];
63
+ async function flushIndexDeletes() {
64
+ if (!pgConfigured || pendingIndexDeletes.length === 0)
65
+ return;
66
+ const names = pendingIndexDeletes.splice(0);
67
+ await pgIndex.deletePages(names, userId).catch((err) => {
68
+ console.error("[purge] Postgres index cleanup failed:", err instanceof Error ? err.message : err);
69
+ });
70
+ }
71
+ let progressProcessed = 0;
72
+ for (const file of toDelete) {
73
+ try {
74
+ await drive.deleteFile(file.name);
75
+ deleted.push(file.name);
76
+ pendingIndexDeletes.push(file.name);
77
+ if (pendingIndexDeletes.length >= FLUSH_CHUNK) {
78
+ await flushIndexDeletes();
79
+ }
80
+ }
81
+ catch (err) {
82
+ failures.push({
83
+ name: file.name,
84
+ error: err instanceof Error ? err.message : String(err),
85
+ });
86
+ }
87
+ opts.onProgress?.(++progressProcessed, toDelete.length);
88
+ }
89
+ // Flush any remaining index deletes.
90
+ await flushIndexDeletes();
91
+ const exportInfo = input.exportBeforeDelete && input.exportOutputPath
92
+ ? { exportedTo: input.exportOutputPath }
93
+ : undefined;
94
+ if (failures.length === 0) {
95
+ await appendLogEntry(drive, {
96
+ type: "update",
97
+ title: "Purge wiki",
98
+ detail: `deleted=${deleted.length}${exportInfo ? `, exportedTo=${exportInfo.exportedTo}` : ""}`,
99
+ }, userId).catch(() => {
100
+ /* non-fatal -- log.md may have been deleted if includeSystem was true */
101
+ });
102
+ }
103
+ return {
104
+ success: failures.length === 0,
105
+ confirmed: true,
106
+ deletedCount: deleted.length,
107
+ failedCount: failures.length,
108
+ deleted,
109
+ failures,
110
+ ...(exportInfo ?? {}),
111
+ };
112
+ }
113
+ //# sourceMappingURL=purgeWiki.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purgeWiki.js","sourceRoot":"","sources":["../../src/tools/purgeWiki.ts"],"names":[],"mappings":"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"}