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,58 @@
1
+ import { z } from "zod";
2
+ import type { StorageClient } from "../storage/client.js";
3
+ export declare const resolveProjectInputSchema: z.ZodObject<{
4
+ context: z.ZodString;
5
+ platform: z.ZodDefault<z.ZodEnum<["claude", "gpt"]>>;
6
+ limit: z.ZodDefault<z.ZodNumber>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ limit: number;
9
+ platform: "claude" | "gpt";
10
+ context: string;
11
+ }, {
12
+ context: string;
13
+ limit?: number | undefined;
14
+ platform?: "claude" | "gpt" | undefined;
15
+ }>;
16
+ export type ResolveProjectInput = z.infer<typeof resolveProjectInputSchema>;
17
+ export interface ProjectMatch {
18
+ slug: string;
19
+ parentSlug?: string;
20
+ pageCount: number;
21
+ title?: string;
22
+ aliases?: string[];
23
+ instructionsPath: string;
24
+ projectPath: string;
25
+ score: number;
26
+ confidence: "high" | "medium" | "low";
27
+ matchedOn: string[];
28
+ }
29
+ export declare function tokenize(value: string): string[];
30
+ /**
31
+ * Score a project against the context tokens.
32
+ *
33
+ * Ranking follows signal coverage measured across the production wiki, not
34
+ * intuition: the slug is present for 36 of 36 projects, a root readme for 23,
35
+ * a real title for 22, and a summary for only 6 (GH #430). A resolver built on
36
+ * readme metadata — the obvious design — would fail on a third of projects,
37
+ * including the largest. So slug and aliases dominate, content is the fallback
38
+ * that catches nicknames the slug does not contain, and title is a tiebreak.
39
+ */
40
+ export declare function scoreProject(ctxTokens: Set<string>, project: {
41
+ slug: string;
42
+ title?: string;
43
+ aliases?: string[];
44
+ contentHits?: number;
45
+ }): {
46
+ score: number;
47
+ matchedOn: string[];
48
+ };
49
+ /**
50
+ * Resolve freeform context to a project slug and its instruction file.
51
+ *
52
+ * Deliberately does not load anything. Resolution and loading stay separate so
53
+ * a wrong guess costs one call rather than a whole bundle of the wrong
54
+ * project's context, and so the caller can confirm with the user when the
55
+ * result is ambiguous.
56
+ */
57
+ export declare function resolveProject(_drive: StorageClient, input: ResolveProjectInput, userId?: string): Promise<object>;
58
+ //# sourceMappingURL=resolveProject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveProject.d.ts","sourceRoot":"","sources":["../../src/tools/resolveProject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,eAAO,MAAM,yBAAyB;;;;;;;;;;;;EAepC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAUD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAiDxC;AAQD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,mBAAmB,EAC1B,MAAM,SAAK,GACV,OAAO,CAAC,MAAM,CAAC,CAoFjB"}
@@ -0,0 +1,175 @@
1
+ import { z } from "zod";
2
+ import { getPostgresSearchIndex } from "../search/postgresIndex.js";
3
+ export const resolveProjectInputSchema = z.object({
4
+ context: z
5
+ .string()
6
+ .min(1)
7
+ .describe("Freeform text describing what the user is working on — their request, a project name, a nickname, a vehicle or property. Matched against project slugs, aliases, titles and page content."),
8
+ platform: z
9
+ .enum(["claude", "gpt"])
10
+ .default("claude")
11
+ .describe("Which per-project instruction file to report the path of."),
12
+ limit: z
13
+ .number()
14
+ .default(5)
15
+ .describe("Maximum matches to return, best first."),
16
+ });
17
+ /** Words that carry no signal when matching a project. */
18
+ const STOPWORDS = new Set([
19
+ "the", "a", "an", "and", "or", "of", "for", "to", "in", "on", "my", "our",
20
+ "is", "are", "was", "were", "it", "this", "that", "with", "about", "what",
21
+ "how", "can", "you", "i", "we", "me", "please", "help", "need", "want",
22
+ "project", "page", "pages", "note", "notes", "brain", "brains",
23
+ ]);
24
+ export function tokenize(value) {
25
+ return value
26
+ .toLowerCase()
27
+ .split(/[^a-z0-9]+/)
28
+ .filter((t) => t.length > 1 && !STOPWORDS.has(t));
29
+ }
30
+ /**
31
+ * Score a project against the context tokens.
32
+ *
33
+ * Ranking follows signal coverage measured across the production wiki, not
34
+ * intuition: the slug is present for 36 of 36 projects, a root readme for 23,
35
+ * a real title for 22, and a summary for only 6 (GH #430). A resolver built on
36
+ * readme metadata — the obvious design — would fail on a third of projects,
37
+ * including the largest. So slug and aliases dominate, content is the fallback
38
+ * that catches nicknames the slug does not contain, and title is a tiebreak.
39
+ */
40
+ export function scoreProject(ctxTokens, project) {
41
+ const matchedOn = [];
42
+ let score = 0;
43
+ // A sub-project's slug arrives as "parent/child" (e.g. "oio/apex"), and both
44
+ // halves are real signal: "oio apex" should match it as a whole, while a bare
45
+ // "apex" matches partially. tokenize splits on non-alphanumerics, so the
46
+ // slash already yields both.
47
+ const slugTokens = tokenize(project.slug);
48
+ const slugHits = slugTokens.filter((t) => ctxTokens.has(t));
49
+ if (slugHits.length > 0) {
50
+ // A whole-slug match beats a partial one, and among whole matches the more
51
+ // specific slug wins. Without the specificity term, "oio apex" scores
52
+ // oio-apex and oio identically — both are whole matches — and a
53
+ // single-token slug hijacks every context that happens to contain it.
54
+ // Conversely a bare "oio" still resolves to oio, because oio-apex only
55
+ // matches partially there.
56
+ const whole = slugHits.length === slugTokens.length;
57
+ score += whole
58
+ ? 100 + 15 * (slugTokens.length - 1)
59
+ : 60 * (slugHits.length / slugTokens.length);
60
+ matchedOn.push("slug");
61
+ }
62
+ for (const alias of project.aliases ?? []) {
63
+ const aliasTokens = tokenize(alias);
64
+ if (aliasTokens.length > 0 && aliasTokens.every((t) => ctxTokens.has(t))) {
65
+ score += 100;
66
+ matchedOn.push("alias");
67
+ break;
68
+ }
69
+ }
70
+ if (project.title) {
71
+ const titleHits = tokenize(project.title).filter((t) => ctxTokens.has(t));
72
+ if (titleHits.length > 0) {
73
+ score += Math.min(25, titleHits.length * 10);
74
+ matchedOn.push("title");
75
+ }
76
+ }
77
+ if (project.contentHits && project.contentHits > 0) {
78
+ // Capped: a large project will always have more hits than a small one, and
79
+ // volume is not relevance.
80
+ score += Math.min(30, project.contentHits * 6);
81
+ matchedOn.push("content");
82
+ }
83
+ return { score, matchedOn };
84
+ }
85
+ function confidenceFor(score, runnerUp) {
86
+ if (score >= 100 && score - runnerUp >= 40)
87
+ return "high";
88
+ if (score >= 60)
89
+ return "medium";
90
+ return "low";
91
+ }
92
+ /**
93
+ * Resolve freeform context to a project slug and its instruction file.
94
+ *
95
+ * Deliberately does not load anything. Resolution and loading stay separate so
96
+ * a wrong guess costs one call rather than a whole bundle of the wrong
97
+ * project's context, and so the caller can confirm with the user when the
98
+ * result is ambiguous.
99
+ */
100
+ export async function resolveProject(_drive, input, userId = "") {
101
+ const index = getPostgresSearchIndex();
102
+ if (!index.isConfigured()) {
103
+ return {
104
+ ok: false,
105
+ error: "resolve_project requires the Postgres index. Use list_pages with folder='projects' to browse projects instead.",
106
+ };
107
+ }
108
+ const ctxTokens = new Set(tokenize(input.context));
109
+ if (ctxTokens.size === 0) {
110
+ return { ok: true, matches: [], ambiguous: false, note: "No usable terms in context." };
111
+ }
112
+ const inventory = await index.listProjectInventory(userId).catch(() => null);
113
+ if (!inventory) {
114
+ return { ok: false, error: "Could not read project inventory from the index." };
115
+ }
116
+ // Content hits only matter when the slug does not already name the project —
117
+ // this is the "the wagon" -> cressida case. One extra query, and only when
118
+ // needed.
119
+ const strongSlugMatch = inventory.some((p) => {
120
+ const st = tokenize(p.slug);
121
+ return st.length > 0 && st.every((t) => ctxTokens.has(t));
122
+ });
123
+ let contentHitsBySlug = new Map();
124
+ if (!strongSlugMatch) {
125
+ contentHitsBySlug = await index
126
+ .countProjectContentHits(input.context, userId)
127
+ .catch(() => new Map());
128
+ }
129
+ const scored = inventory
130
+ .map((p) => {
131
+ const { score, matchedOn } = scoreProject(ctxTokens, {
132
+ slug: p.slug,
133
+ title: p.title,
134
+ aliases: p.aliases,
135
+ contentHits: contentHitsBySlug.get(p.slug),
136
+ });
137
+ return { ...p, score, matchedOn };
138
+ })
139
+ .filter((p) => p.score > 0)
140
+ .sort((a, b) => b.score - a.score || b.pageCount - a.pageCount);
141
+ const top = scored.slice(0, input.limit);
142
+ const runnerUp = scored[1]?.score ?? 0;
143
+ const matches = top.map((p, i) => ({
144
+ slug: p.slug,
145
+ ...(p.parentSlug ? { parentSlug: p.parentSlug } : {}),
146
+ pageCount: p.pageCount,
147
+ ...(p.title ? { title: p.title } : {}),
148
+ ...(p.aliases && p.aliases.length > 0 ? { aliases: p.aliases } : {}),
149
+ projectPath: p.parentSlug
150
+ ? `projects/${p.parentSlug}/projects/${p.slug.split("/")[1]}`
151
+ : `projects/${p.slug}`,
152
+ instructionsPath: p.parentSlug
153
+ ? `projects/${p.parentSlug}/projects/${p.slug.split("/")[1]}/instructions/${input.platform}.md`
154
+ : `projects/${p.slug}/instructions/${input.platform}.md`,
155
+ score: Math.round(p.score),
156
+ confidence: i === 0 ? confidenceFor(p.score, runnerUp) : "low",
157
+ matchedOn: p.matchedOn,
158
+ }));
159
+ // Close scores mean the context genuinely does not distinguish them. Say so
160
+ // rather than letting the caller act on an arbitrary winner — loading the
161
+ // wrong project's context is quiet and hard for a user to notice.
162
+ const ambiguous = matches.length > 1 && scored[0].score - runnerUp < 40;
163
+ return {
164
+ ok: true,
165
+ matches,
166
+ ambiguous,
167
+ ...(matches.length === 0
168
+ ? { note: "No project matched. Use list_pages with folder='projects' to browse, or ask the user." }
169
+ : {}),
170
+ ...(ambiguous
171
+ ? { note: "Top matches score closely — confirm with the user before loading one." }
172
+ : {}),
173
+ };
174
+ }
175
+ //# sourceMappingURL=resolveProject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveProject.js","sourceRoot":"","sources":["../../src/tools/resolveProject.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import type { StorageClient } from "../storage/client.js";
3
+ export declare const restorePageBaseSchema: z.ZodObject<{
4
+ archiveId: z.ZodOptional<z.ZodString>;
5
+ originalPath: z.ZodOptional<z.ZodString>;
6
+ deletedAt: z.ZodOptional<z.ZodString>;
7
+ targetPath: z.ZodOptional<z.ZodString>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ archiveId?: string | undefined;
10
+ originalPath?: string | undefined;
11
+ deletedAt?: string | undefined;
12
+ targetPath?: string | undefined;
13
+ }, {
14
+ archiveId?: string | undefined;
15
+ originalPath?: string | undefined;
16
+ deletedAt?: string | undefined;
17
+ targetPath?: string | undefined;
18
+ }>;
19
+ export declare const restorePageInputSchema: z.ZodEffects<z.ZodObject<{
20
+ archiveId: z.ZodOptional<z.ZodString>;
21
+ originalPath: z.ZodOptional<z.ZodString>;
22
+ deletedAt: z.ZodOptional<z.ZodString>;
23
+ targetPath: z.ZodOptional<z.ZodString>;
24
+ }, "strip", z.ZodTypeAny, {
25
+ archiveId?: string | undefined;
26
+ originalPath?: string | undefined;
27
+ deletedAt?: string | undefined;
28
+ targetPath?: string | undefined;
29
+ }, {
30
+ archiveId?: string | undefined;
31
+ originalPath?: string | undefined;
32
+ deletedAt?: string | undefined;
33
+ targetPath?: string | undefined;
34
+ }>, {
35
+ archiveId?: string | undefined;
36
+ originalPath?: string | undefined;
37
+ deletedAt?: string | undefined;
38
+ targetPath?: string | undefined;
39
+ }, {
40
+ archiveId?: string | undefined;
41
+ originalPath?: string | undefined;
42
+ deletedAt?: string | undefined;
43
+ targetPath?: string | undefined;
44
+ }>;
45
+ export type RestorePageInput = z.infer<typeof restorePageInputSchema>;
46
+ export declare function restorePage(drive: StorageClient, input: RestorePageInput, userId?: string): Promise<object>;
47
+ //# sourceMappingURL=restorePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restorePage.d.ts","sourceRoot":"","sources":["../../src/tools/restorePage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAc1D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;EAkBhC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;EAMlC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAMtE,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,gBAAgB,EACvB,MAAM,SAAK,GACV,OAAO,CAAC,MAAM,CAAC,CAqFjB"}
@@ -0,0 +1,111 @@
1
+ import { z } from "zod";
2
+ import { parsePage } from "../wiki/frontmatter.js";
3
+ import { upsertIndexEntry } from "../wiki/index.js";
4
+ import { appendLogEntry } from "../wiki/log.js";
5
+ import { assertPageLimit } from "../wiki/storageLimits.js";
6
+ import { getPostgresSearchIndex } from "../search/postgresIndex.js";
7
+ // Plain object shape — published to clients as the tool's JSON Schema.
8
+ // The cross-field "archiveId OR originalPath" rule lives in the .refine() below
9
+ // (restorePageInputSchema). A refined schema is a ZodEffects, not a ZodObject, and
10
+ // zodToJsonSchema can emit an empty `{}` for it at module-load time — which fails
11
+ // MCP client tool-list validation (inputSchema.type must be "object") and drops the
12
+ // ENTIRE tool surface. JSON Schema can't express the OR constraint anyway, so the
13
+ // published schema is generated from this base and the rule is enforced at parse().
14
+ export const restorePageBaseSchema = z.object({
15
+ archiveId: z
16
+ .string()
17
+ .uuid()
18
+ .optional()
19
+ .describe("Archived row ID to restore."),
20
+ originalPath: z
21
+ .string()
22
+ .optional()
23
+ .describe("Original path to restore from when archiveId is not provided."),
24
+ deletedAt: z
25
+ .string()
26
+ .optional()
27
+ .describe("Optional deleted_at timestamp filter (ISO) when restoring by originalPath."),
28
+ targetPath: z
29
+ .string()
30
+ .optional()
31
+ .describe("Optional override path for restore destination (defaults to original path)."),
32
+ });
33
+ export const restorePageInputSchema = restorePageBaseSchema.refine((value) => Boolean(value.archiveId || value.originalPath), {
34
+ message: "Provide either archiveId or originalPath.",
35
+ path: ["archiveId"],
36
+ });
37
+ function normalizePagePath(name) {
38
+ return name.endsWith(".md") ? name : `${name}.md`;
39
+ }
40
+ export async function restorePage(drive, input, userId = "") {
41
+ const pgIndex = getPostgresSearchIndex();
42
+ if (!pgIndex.isConfigured()) {
43
+ return {
44
+ ok: false,
45
+ error: "Postgres archive store not configured. Set SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY.",
46
+ };
47
+ }
48
+ if (!userId) {
49
+ return { ok: false, error: "userId is required to restore archived pages." };
50
+ }
51
+ const archived = await pgIndex.getArchivedPageForRestore({
52
+ userId,
53
+ ...(input.archiveId ? { archiveId: input.archiveId } : {}),
54
+ ...(input.originalPath ? { originalPath: normalizePagePath(input.originalPath) } : {}),
55
+ ...(input.deletedAt ? { deletedAt: input.deletedAt } : {}),
56
+ });
57
+ if (!archived) {
58
+ return { ok: false, error: "Archived page not found for the provided selector." };
59
+ }
60
+ if (archived.restoredAt) {
61
+ return {
62
+ ok: false,
63
+ error: `Archived page was already restored at ${archived.restoredAt}.`,
64
+ archiveId: archived.id,
65
+ restoredAt: archived.restoredAt,
66
+ };
67
+ }
68
+ await assertPageLimit(userId, 1);
69
+ const destination = input.targetPath ? normalizePagePath(input.targetPath) : archived.originalPath;
70
+ const writeResult = await drive.createFile(destination, archived.content);
71
+ const { frontmatter, content } = parsePage(archived.content);
72
+ // Full content (frontmatter included) — matches patchPage.ts's DB-primary
73
+ // convention, which read_page/patch_page read back as the complete file.
74
+ await pgIndex.upsertPage(destination, frontmatter, archived.content, writeResult.revision, writeResult.modifiedTime, userId);
75
+ // Fire-and-forget: the link graph is a derived index, and nothing in this
76
+ // response depends on it. Awaiting it put three sequential Supabase round
77
+ // trips (~350-525ms) on the caller's critical path purely to decide whether
78
+ // to attach a cosmetic warning (GH #424). Staleness is self-healing —
79
+ // links_extracted_at drives extract_links' catch-up pass.
80
+ pgIndex
81
+ .syncPageLinks(destination, content, userId)
82
+ .catch((err) => {
83
+ console.warn(`[links] sync failed for '${destination}'`, err instanceof Error ? err.message : err);
84
+ });
85
+ await pgIndex.markArchivedPageRestored(archived.id, userId, userId);
86
+ upsertIndexEntry(drive, {
87
+ name: destination,
88
+ title: String(frontmatter.title ?? destination),
89
+ summary: String(frontmatter.summary ?? ""),
90
+ updated: new Date().toISOString().slice(0, 10),
91
+ }).catch(() => { });
92
+ appendLogEntry(drive, {
93
+ type: "create",
94
+ title: `Restored ${destination}`,
95
+ detail: `Restored from archive ${archived.id}`,
96
+ }, userId).catch((err) => {
97
+ // Surfaced rather than swallowed: a silent stop here is how an
98
+ // oversized log.md would go unnoticed (GH #417).
99
+ console.warn("[log] append failed:", err instanceof Error ? err.message : err);
100
+ });
101
+ return {
102
+ ok: true,
103
+ restored: true,
104
+ archiveId: archived.id,
105
+ originalPath: archived.originalPath,
106
+ restoredPath: destination,
107
+ revision: writeResult.revision,
108
+ modifiedTime: writeResult.modifiedTime,
109
+ };
110
+ }
111
+ //# sourceMappingURL=restorePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restorePage.js","sourceRoot":"","sources":["../../src/tools/restorePage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+ import type { StorageClient } from "../storage/client.js";
3
+ import { type AccessContext } from "../governance/accessControl.js";
4
+ export declare const searchPagesInputSchema: z.ZodObject<{
5
+ query: z.ZodString;
6
+ tag: z.ZodOptional<z.ZodString>;
7
+ folder: z.ZodOptional<z.ZodString>;
8
+ maxCandidates: z.ZodDefault<z.ZodNumber>;
9
+ maxResults: z.ZodDefault<z.ZodNumber>;
10
+ maxConcurrency: z.ZodDefault<z.ZodNumber>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ query: string;
13
+ maxCandidates: number;
14
+ maxResults: number;
15
+ maxConcurrency: number;
16
+ tag?: string | undefined;
17
+ folder?: string | undefined;
18
+ }, {
19
+ query: string;
20
+ tag?: string | undefined;
21
+ folder?: string | undefined;
22
+ maxCandidates?: number | undefined;
23
+ maxResults?: number | undefined;
24
+ maxConcurrency?: number | undefined;
25
+ }>;
26
+ export type SearchPagesInput = z.infer<typeof searchPagesInputSchema>;
27
+ export declare function searchPages(drive: StorageClient, input: SearchPagesInput, userId?: string, accessCtx?: AccessContext): Promise<object>;
28
+ //# sourceMappingURL=searchPages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchPages.d.ts","sourceRoot":"","sources":["../../src/tools/searchPages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAW1D,OAAO,EACL,KAAK,aAAa,EAOnB,MAAM,gCAAgC,CAAC;AAExC,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;EAoCjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAyBtE,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,gBAAgB,EACvB,MAAM,SAAK,EACX,SAAS,GAAE,aAAsC,GAChD,OAAO,CAAC,MAAM,CAAC,CAmEjB"}