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.
- package/README.md +95 -0
- package/dist/access/projectShares.d.ts +48 -0
- package/dist/access/projectShares.d.ts.map +1 -0
- package/dist/access/projectShares.js +203 -0
- package/dist/access/projectShares.js.map +1 -0
- package/dist/access/sharedInstructionsNote.d.ts +37 -0
- package/dist/access/sharedInstructionsNote.d.ts.map +1 -0
- package/dist/access/sharedInstructionsNote.js +76 -0
- package/dist/access/sharedInstructionsNote.js.map +1 -0
- package/dist/admin/seedUsers.d.ts +23 -0
- package/dist/admin/seedUsers.d.ts.map +1 -0
- package/dist/admin/seedUsers.js +168 -0
- package/dist/admin/seedUsers.js.map +1 -0
- package/dist/api/openapi.d.ts +2 -0
- package/dist/api/openapi.d.ts.map +1 -0
- package/dist/api/openapi.js +942 -0
- package/dist/api/openapi.js.map +1 -0
- package/dist/auth/clientStore.d.ts +43 -0
- package/dist/auth/clientStore.d.ts.map +1 -0
- package/dist/auth/clientStore.js +168 -0
- package/dist/auth/clientStore.js.map +1 -0
- package/dist/auth/deleteAccount.d.ts +34 -0
- package/dist/auth/deleteAccount.d.ts.map +1 -0
- package/dist/auth/deleteAccount.js +203 -0
- package/dist/auth/deleteAccount.js.map +1 -0
- package/dist/auth/oauth.d.ts +118 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/oauth.js +491 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/patStore.d.ts +87 -0
- package/dist/auth/patStore.d.ts.map +1 -0
- package/dist/auth/patStore.js +308 -0
- package/dist/auth/patStore.js.map +1 -0
- package/dist/auth/supabase.d.ts +15 -0
- package/dist/auth/supabase.d.ts.map +1 -0
- package/dist/auth/supabase.js +66 -0
- package/dist/auth/supabase.js.map +1 -0
- package/dist/auth/tokenStore.d.ts +73 -0
- package/dist/auth/tokenStore.d.ts.map +1 -0
- package/dist/auth/tokenStore.js +261 -0
- package/dist/auth/tokenStore.js.map +1 -0
- package/dist/backup/drive.d.ts +24 -0
- package/dist/backup/drive.d.ts.map +1 -0
- package/dist/backup/drive.js +70 -0
- package/dist/backup/drive.js.map +1 -0
- package/dist/billing/tierStore.d.ts +59 -0
- package/dist/billing/tierStore.d.ts.map +1 -0
- package/dist/billing/tierStore.js +152 -0
- package/dist/billing/tierStore.js.map +1 -0
- package/dist/digest/activityDigest.d.ts +32 -0
- package/dist/digest/activityDigest.d.ts.map +1 -0
- package/dist/digest/activityDigest.js +299 -0
- package/dist/digest/activityDigest.js.map +1 -0
- package/dist/digest/digestCron.d.ts +40 -0
- package/dist/digest/digestCron.d.ts.map +1 -0
- package/dist/digest/digestCron.js +146 -0
- package/dist/digest/digestCron.js.map +1 -0
- package/dist/digest/digestPreferences.d.ts +25 -0
- package/dist/digest/digestPreferences.d.ts.map +1 -0
- package/dist/digest/digestPreferences.js +79 -0
- package/dist/digest/digestPreferences.js.map +1 -0
- package/dist/digest/emailSender.d.ts +20 -0
- package/dist/digest/emailSender.d.ts.map +1 -0
- package/dist/digest/emailSender.js +35 -0
- package/dist/digest/emailSender.js.map +1 -0
- package/dist/drive/client.d.ts +43 -0
- package/dist/drive/client.d.ts.map +1 -0
- package/dist/drive/client.js +282 -0
- package/dist/drive/client.js.map +1 -0
- package/dist/drive/errors.d.ts +27 -0
- package/dist/drive/errors.d.ts.map +1 -0
- package/dist/drive/errors.js +51 -0
- package/dist/drive/errors.js.map +1 -0
- package/dist/drive/fileCache.d.ts +22 -0
- package/dist/drive/fileCache.d.ts.map +1 -0
- package/dist/drive/fileCache.js +57 -0
- package/dist/drive/fileCache.js.map +1 -0
- package/dist/governance/accessControl.d.ts +87 -0
- package/dist/governance/accessControl.d.ts.map +1 -0
- package/dist/governance/accessControl.js +179 -0
- package/dist/governance/accessControl.js.map +1 -0
- package/dist/html/components.d.ts +8 -0
- package/dist/html/components.d.ts.map +1 -0
- package/dist/html/components.js +19 -0
- package/dist/html/components.js.map +1 -0
- package/dist/html/layout.d.ts +7 -0
- package/dist/html/layout.d.ts.map +1 -0
- package/dist/html/layout.js +24 -0
- package/dist/html/layout.js.map +1 -0
- package/dist/html/metricsUi.d.ts +8 -0
- package/dist/html/metricsUi.d.ts.map +1 -0
- package/dist/html/metricsUi.js +271 -0
- package/dist/html/metricsUi.js.map +1 -0
- package/dist/httpServer.d.ts +19 -0
- package/dist/httpServer.d.ts.map +1 -0
- package/dist/httpServer.js +3913 -0
- package/dist/httpServer.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/jobs/asyncJobRegistry.d.ts +30 -0
- package/dist/jobs/asyncJobRegistry.d.ts.map +1 -0
- package/dist/jobs/asyncJobRegistry.js +70 -0
- package/dist/jobs/asyncJobRegistry.js.map +1 -0
- package/dist/observability/metricsQuery.d.ts +41 -0
- package/dist/observability/metricsQuery.d.ts.map +1 -0
- package/dist/observability/metricsQuery.js +106 -0
- package/dist/observability/metricsQuery.js.map +1 -0
- package/dist/observability/relevanceSignal.d.ts +26 -0
- package/dist/observability/relevanceSignal.d.ts.map +1 -0
- package/dist/observability/relevanceSignal.js +95 -0
- package/dist/observability/relevanceSignal.js.map +1 -0
- package/dist/observability/requestEvents.d.ts +31 -0
- package/dist/observability/requestEvents.d.ts.map +1 -0
- package/dist/observability/requestEvents.js +54 -0
- package/dist/observability/requestEvents.js.map +1 -0
- package/dist/observability/slowQueryAlert.d.ts +25 -0
- package/dist/observability/slowQueryAlert.d.ts.map +1 -0
- package/dist/observability/slowQueryAlert.js +67 -0
- package/dist/observability/slowQueryAlert.js.map +1 -0
- package/dist/observability/zeroResultTriage.d.ts +22 -0
- package/dist/observability/zeroResultTriage.d.ts.map +1 -0
- package/dist/observability/zeroResultTriage.js +116 -0
- package/dist/observability/zeroResultTriage.js.map +1 -0
- package/dist/search/embeddings.d.ts +31 -0
- package/dist/search/embeddings.d.ts.map +1 -0
- package/dist/search/embeddings.js +91 -0
- package/dist/search/embeddings.js.map +1 -0
- package/dist/search/fileWatcher.d.ts +28 -0
- package/dist/search/fileWatcher.d.ts.map +1 -0
- package/dist/search/fileWatcher.js +103 -0
- package/dist/search/fileWatcher.js.map +1 -0
- package/dist/search/hotQueryCache.d.ts +31 -0
- package/dist/search/hotQueryCache.d.ts.map +1 -0
- package/dist/search/hotQueryCache.js +103 -0
- package/dist/search/hotQueryCache.js.map +1 -0
- package/dist/search/postgresIndex.d.ts +439 -0
- package/dist/search/postgresIndex.d.ts.map +1 -0
- package/dist/search/postgresIndex.js +1610 -0
- package/dist/search/postgresIndex.js.map +1 -0
- package/dist/search/sqliteIndex.d.ts +66 -0
- package/dist/search/sqliteIndex.d.ts.map +1 -0
- package/dist/search/sqliteIndex.js +342 -0
- package/dist/search/sqliteIndex.js.map +1 -0
- package/dist/server.d.ts +43 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +532 -0
- package/dist/server.js.map +1 -0
- package/dist/session/bundle.d.ts +53 -0
- package/dist/session/bundle.d.ts.map +1 -0
- package/dist/session/bundle.js +97 -0
- package/dist/session/bundle.js.map +1 -0
- package/dist/storage/client.d.ts +157 -0
- package/dist/storage/client.d.ts.map +1 -0
- package/dist/storage/client.js +825 -0
- package/dist/storage/client.js.map +1 -0
- package/dist/tools/addWebhookPattern.d.ts +15 -0
- package/dist/tools/addWebhookPattern.d.ts.map +1 -0
- package/dist/tools/addWebhookPattern.js +15 -0
- package/dist/tools/addWebhookPattern.js.map +1 -0
- package/dist/tools/appendLog.d.ts +18 -0
- package/dist/tools/appendLog.d.ts.map +1 -0
- package/dist/tools/appendLog.js +18 -0
- package/dist/tools/appendLog.js.map +1 -0
- package/dist/tools/auditIndex.d.ts +15 -0
- package/dist/tools/auditIndex.d.ts.map +1 -0
- package/dist/tools/auditIndex.js +165 -0
- package/dist/tools/auditIndex.js.map +1 -0
- package/dist/tools/batchDeletePages.d.ts +18 -0
- package/dist/tools/batchDeletePages.d.ts.map +1 -0
- package/dist/tools/batchDeletePages.js +143 -0
- package/dist/tools/batchDeletePages.js.map +1 -0
- package/dist/tools/coerce.d.ts +3 -0
- package/dist/tools/coerce.d.ts.map +1 -0
- package/dist/tools/coerce.js +12 -0
- package/dist/tools/coerce.js.map +1 -0
- package/dist/tools/createPage.d.ts +24 -0
- package/dist/tools/createPage.d.ts.map +1 -0
- package/dist/tools/createPage.js +99 -0
- package/dist/tools/createPage.js.map +1 -0
- package/dist/tools/createPages.d.ts +51 -0
- package/dist/tools/createPages.d.ts.map +1 -0
- package/dist/tools/createPages.js +91 -0
- package/dist/tools/createPages.js.map +1 -0
- package/dist/tools/deletePage.d.ts +19 -0
- package/dist/tools/deletePage.d.ts.map +1 -0
- package/dist/tools/deletePage.js +127 -0
- package/dist/tools/deletePage.js.map +1 -0
- package/dist/tools/exportWiki.d.ts +48 -0
- package/dist/tools/exportWiki.d.ts.map +1 -0
- package/dist/tools/exportWiki.js +233 -0
- package/dist/tools/exportWiki.js.map +1 -0
- package/dist/tools/extractLinks.d.ts +14 -0
- package/dist/tools/extractLinks.d.ts.map +1 -0
- package/dist/tools/extractLinks.js +25 -0
- package/dist/tools/extractLinks.js.map +1 -0
- package/dist/tools/generateClaudeInstructions.d.ts +27 -0
- package/dist/tools/generateClaudeInstructions.d.ts.map +1 -0
- package/dist/tools/generateClaudeInstructions.js +263 -0
- package/dist/tools/generateClaudeInstructions.js.map +1 -0
- package/dist/tools/generateGptInstructions.d.ts +27 -0
- package/dist/tools/generateGptInstructions.d.ts.map +1 -0
- package/dist/tools/generateGptInstructions.js +208 -0
- package/dist/tools/generateGptInstructions.js.map +1 -0
- package/dist/tools/getBacklinks.d.ts +12 -0
- package/dist/tools/getBacklinks.d.ts.map +1 -0
- package/dist/tools/getBacklinks.js +13 -0
- package/dist/tools/getBacklinks.js.map +1 -0
- package/dist/tools/getRelated.d.ts +12 -0
- package/dist/tools/getRelated.d.ts.map +1 -0
- package/dist/tools/getRelated.js +13 -0
- package/dist/tools/getRelated.js.map +1 -0
- package/dist/tools/healthCheck.d.ts +5 -0
- package/dist/tools/healthCheck.d.ts.map +1 -0
- package/dist/tools/healthCheck.js +167 -0
- package/dist/tools/healthCheck.js.map +1 -0
- package/dist/tools/importBrainSource.d.ts +36 -0
- package/dist/tools/importBrainSource.d.ts.map +1 -0
- package/dist/tools/importBrainSource.js +314 -0
- package/dist/tools/importBrainSource.js.map +1 -0
- package/dist/tools/importWikiZip.d.ts +60 -0
- package/dist/tools/importWikiZip.d.ts.map +1 -0
- package/dist/tools/importWikiZip.js +379 -0
- package/dist/tools/importWikiZip.js.map +1 -0
- package/dist/tools/initProject.d.ts +34 -0
- package/dist/tools/initProject.d.ts.map +1 -0
- package/dist/tools/initProject.js +443 -0
- package/dist/tools/initProject.js.map +1 -0
- package/dist/tools/instructionContext.d.ts +60 -0
- package/dist/tools/instructionContext.d.ts.map +1 -0
- package/dist/tools/instructionContext.js +210 -0
- package/dist/tools/instructionContext.js.map +1 -0
- package/dist/tools/listArchivedPages.d.ts +17 -0
- package/dist/tools/listArchivedPages.d.ts.map +1 -0
- package/dist/tools/listArchivedPages.js +51 -0
- package/dist/tools/listArchivedPages.js.map +1 -0
- package/dist/tools/listPages.d.ts +28 -0
- package/dist/tools/listPages.d.ts.map +1 -0
- package/dist/tools/listPages.js +166 -0
- package/dist/tools/listPages.js.map +1 -0
- package/dist/tools/listWebhooks.d.ts +7 -0
- package/dist/tools/listWebhooks.d.ts.map +1 -0
- package/dist/tools/listWebhooks.js +10 -0
- package/dist/tools/listWebhooks.js.map +1 -0
- package/dist/tools/movePage.d.ts +18 -0
- package/dist/tools/movePage.d.ts.map +1 -0
- package/dist/tools/movePage.js +182 -0
- package/dist/tools/movePage.js.map +1 -0
- package/dist/tools/pageHistory.d.ts +36 -0
- package/dist/tools/pageHistory.d.ts.map +1 -0
- package/dist/tools/pageHistory.js +60 -0
- package/dist/tools/pageHistory.js.map +1 -0
- package/dist/tools/patchPage.d.ts +141 -0
- package/dist/tools/patchPage.d.ts.map +1 -0
- package/dist/tools/patchPage.js +287 -0
- package/dist/tools/patchPage.js.map +1 -0
- package/dist/tools/pullSessionBundle.d.ts +34 -0
- package/dist/tools/pullSessionBundle.d.ts.map +1 -0
- package/dist/tools/pullSessionBundle.js +432 -0
- package/dist/tools/pullSessionBundle.js.map +1 -0
- package/dist/tools/purgeWiki.d.ts +23 -0
- package/dist/tools/purgeWiki.d.ts.map +1 -0
- package/dist/tools/purgeWiki.js +113 -0
- package/dist/tools/purgeWiki.js.map +1 -0
- package/dist/tools/pushSessionBundle.d.ts +139 -0
- package/dist/tools/pushSessionBundle.d.ts.map +1 -0
- package/dist/tools/pushSessionBundle.js +282 -0
- package/dist/tools/pushSessionBundle.js.map +1 -0
- package/dist/tools/readGovernanceAudit.d.ts +17 -0
- package/dist/tools/readGovernanceAudit.d.ts.map +1 -0
- package/dist/tools/readGovernanceAudit.js +21 -0
- package/dist/tools/readGovernanceAudit.js.map +1 -0
- package/dist/tools/readPage.d.ts +13 -0
- package/dist/tools/readPage.d.ts.map +1 -0
- package/dist/tools/readPage.js +46 -0
- package/dist/tools/readPage.js.map +1 -0
- package/dist/tools/removeWebhook.d.ts +14 -0
- package/dist/tools/removeWebhook.d.ts.map +1 -0
- package/dist/tools/removeWebhook.js +12 -0
- package/dist/tools/removeWebhook.js.map +1 -0
- package/dist/tools/resolveProject.d.ts +58 -0
- package/dist/tools/resolveProject.d.ts.map +1 -0
- package/dist/tools/resolveProject.js +175 -0
- package/dist/tools/resolveProject.js.map +1 -0
- package/dist/tools/restorePage.d.ts +47 -0
- package/dist/tools/restorePage.d.ts.map +1 -0
- package/dist/tools/restorePage.js +111 -0
- package/dist/tools/restorePage.js.map +1 -0
- package/dist/tools/searchPages.d.ts +28 -0
- package/dist/tools/searchPages.d.ts.map +1 -0
- package/dist/tools/searchPages.js +372 -0
- package/dist/tools/searchPages.js.map +1 -0
- package/dist/tools/setWebhook.d.ts +30 -0
- package/dist/tools/setWebhook.d.ts.map +1 -0
- package/dist/tools/setWebhook.js +30 -0
- package/dist/tools/setWebhook.js.map +1 -0
- package/dist/tools/shareProject.d.ts +25 -0
- package/dist/tools/shareProject.d.ts.map +1 -0
- package/dist/tools/shareProject.js +56 -0
- package/dist/tools/shareProject.js.map +1 -0
- package/dist/tools/suggestLinks.d.ts +29 -0
- package/dist/tools/suggestLinks.d.ts.map +1 -0
- package/dist/tools/suggestLinks.js +214 -0
- package/dist/tools/suggestLinks.js.map +1 -0
- package/dist/tools/updatePage.d.ts +27 -0
- package/dist/tools/updatePage.d.ts.map +1 -0
- package/dist/tools/updatePage.js +118 -0
- package/dist/tools/updatePage.js.map +1 -0
- package/dist/webhooks/dispatch.d.ts +49 -0
- package/dist/webhooks/dispatch.d.ts.map +1 -0
- package/dist/webhooks/dispatch.js +159 -0
- package/dist/webhooks/dispatch.js.map +1 -0
- package/dist/webhooks/webhookRules.d.ts +34 -0
- package/dist/webhooks/webhookRules.d.ts.map +1 -0
- package/dist/webhooks/webhookRules.js +129 -0
- package/dist/webhooks/webhookRules.js.map +1 -0
- package/dist/wiki/frontmatter.d.ts +45 -0
- package/dist/wiki/frontmatter.d.ts.map +1 -0
- package/dist/wiki/frontmatter.js +68 -0
- package/dist/wiki/frontmatter.js.map +1 -0
- package/dist/wiki/index.d.ts +22 -0
- package/dist/wiki/index.d.ts.map +1 -0
- package/dist/wiki/index.js +203 -0
- package/dist/wiki/index.js.map +1 -0
- package/dist/wiki/ingestPolicy.d.ts +18 -0
- package/dist/wiki/ingestPolicy.d.ts.map +1 -0
- package/dist/wiki/ingestPolicy.js +64 -0
- package/dist/wiki/ingestPolicy.js.map +1 -0
- package/dist/wiki/layoutLint.d.ts +51 -0
- package/dist/wiki/layoutLint.d.ts.map +1 -0
- package/dist/wiki/layoutLint.js +146 -0
- package/dist/wiki/layoutLint.js.map +1 -0
- package/dist/wiki/links.d.ts +6 -0
- package/dist/wiki/links.d.ts.map +1 -0
- package/dist/wiki/links.js +45 -0
- package/dist/wiki/links.js.map +1 -0
- package/dist/wiki/log.d.ts +58 -0
- package/dist/wiki/log.d.ts.map +1 -0
- package/dist/wiki/log.js +126 -0
- package/dist/wiki/log.js.map +1 -0
- package/dist/wiki/path.d.ts +8 -0
- package/dist/wiki/path.d.ts.map +1 -0
- package/dist/wiki/path.js +25 -0
- package/dist/wiki/path.js.map +1 -0
- package/dist/wiki/storageLimits.d.ts +163 -0
- package/dist/wiki/storageLimits.d.ts.map +1 -0
- package/dist/wiki/storageLimits.js +281 -0
- package/dist/wiki/storageLimits.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { resolveIndexOwnerSubject } from "../storage/client.js";
|
|
3
|
+
import { parsePage, serializePage } from "../wiki/frontmatter.js";
|
|
4
|
+
import { removeIndexEntry } from "../wiki/index.js";
|
|
5
|
+
import { upsertIndexEntry } from "../wiki/index.js";
|
|
6
|
+
import { appendLogEntry } from "../wiki/log.js";
|
|
7
|
+
import { getPostgresSearchIndex } from "../search/postgresIndex.js";
|
|
8
|
+
import { lintLayout } from "../wiki/layoutLint.js";
|
|
9
|
+
export const movePageInputSchema = z.object({
|
|
10
|
+
name: z.string().describe("Current relative path of the page"),
|
|
11
|
+
action: z
|
|
12
|
+
.enum(["archive", "rename"])
|
|
13
|
+
.describe("'archive' moves the page to history/archive-<name> and sets status=archived; 'rename' gives it a new path"),
|
|
14
|
+
newName: z
|
|
15
|
+
.string()
|
|
16
|
+
.regex(/^(?:[a-z0-9-]+\/)*[a-z0-9-]+\.md$/, "newName must be lowercase kebab-case path ending in .md")
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("Required when action='rename'. New relative path (e.g. 'projects/new-name.md')"),
|
|
19
|
+
});
|
|
20
|
+
export async function movePage(drive, input, userId = "") {
|
|
21
|
+
if (input.action === "rename" && !input.newName) {
|
|
22
|
+
throw new Error("newName is required when action='rename'");
|
|
23
|
+
}
|
|
24
|
+
const name = input.name.endsWith(".md") ? input.name : `${input.name}.md`;
|
|
25
|
+
const existing = await drive.readFile(name);
|
|
26
|
+
const { frontmatter, content } = parsePage(existing.content);
|
|
27
|
+
let targetName;
|
|
28
|
+
// Full content (frontmatter included) to store in Postgres — matches patchPage.ts's
|
|
29
|
+
// DB-primary convention, which read_page/patch_page read back as the complete file.
|
|
30
|
+
let finalContent = existing.content;
|
|
31
|
+
let updateResult;
|
|
32
|
+
if (input.action === "archive") {
|
|
33
|
+
const baseName = (name.split("/").pop() ?? name).replace(/\.md$/, "");
|
|
34
|
+
const archiveSlug = baseName.startsWith("archive-") ? baseName : `archive-${baseName}`;
|
|
35
|
+
targetName = `history/${archiveSlug}.md`;
|
|
36
|
+
// Update status in frontmatter
|
|
37
|
+
frontmatter.status = "archived";
|
|
38
|
+
finalContent = serializePage(frontmatter, content);
|
|
39
|
+
updateResult = await drive.updateFile(existing.fileId, finalContent, existing.revision);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
targetName = input.newName;
|
|
43
|
+
}
|
|
44
|
+
// A move to where the page already is must not touch storage or delete an
|
|
45
|
+
// index row — there is nothing to move, and every step of the move is
|
|
46
|
+
// destructive when source and destination are the same object:
|
|
47
|
+
//
|
|
48
|
+
// SupabaseStorageClient.renameFile does uploadObject(new) then
|
|
49
|
+
// deleteObject(old). With one name that deletes the object it just wrote.
|
|
50
|
+
// The index delete then removes the row that was the last surviving copy.
|
|
51
|
+
//
|
|
52
|
+
// Reachable today: archiving a page already at history/archive-<x>.md, where
|
|
53
|
+
// the dedup above leaves targetName identical to name. Also any rename whose
|
|
54
|
+
// newName equals the current path — nothing rejects it.
|
|
55
|
+
//
|
|
56
|
+
// For the archive case the frontmatter edit above has already been written,
|
|
57
|
+
// so the index still needs the refreshed content; only the rename and the
|
|
58
|
+
// delete are skipped.
|
|
59
|
+
const isSelfMove = targetName === name;
|
|
60
|
+
const writeResult = isSelfMove
|
|
61
|
+
? (updateResult ?? { fileId: existing.fileId, revision: existing.revision, modifiedTime: existing.modifiedTime })
|
|
62
|
+
: await drive.renameFile(existing.fileId, targetName);
|
|
63
|
+
// Cross-account sharing (BRA-381): attribute index writes to the true storage
|
|
64
|
+
// owner. A rename that crosses a project-share boundary already throws inside
|
|
65
|
+
// drive.renameFile above, so old/new path resolve to the same owner here.
|
|
66
|
+
const indexOwner = resolveIndexOwnerSubject(drive, name, userId);
|
|
67
|
+
const pgIndex = getPostgresSearchIndex();
|
|
68
|
+
// Insert the new index row BEFORE deleting the old one, and await both.
|
|
69
|
+
//
|
|
70
|
+
// The reverse order — delete awaited, insert fire-and-forget — loses pages.
|
|
71
|
+
// Any upsert failure left the row deleted and never replaced, so the page
|
|
72
|
+
// stayed readable via read_page (which falls back to Storage) while being
|
|
73
|
+
// absent from list_pages, search_pages, tag queries and resolve_project. The
|
|
74
|
+
// tool returned success and emitted no warning, because the failure went into
|
|
75
|
+
// a `.catch(() => {})`. That is how a missing `aliases` column froze the whole
|
|
76
|
+
// production index for an hour without a single error surfacing (#450).
|
|
77
|
+
//
|
|
78
|
+
// Ordering matters more than either call succeeding. Of the reachable states:
|
|
79
|
+
//
|
|
80
|
+
// insert ok, delete fails -> old row is a ghost, page visible at new path.
|
|
81
|
+
// audit_index cleans ghosts. Recoverable.
|
|
82
|
+
// insert fails -> old row deliberately KEPT below, so the page
|
|
83
|
+
// is still indexed under its old name rather
|
|
84
|
+
// than vanishing. Recoverable.
|
|
85
|
+
// (old behaviour) -> deleted and not replaced. Invisible. Lost.
|
|
86
|
+
//
|
|
87
|
+
// So: never delete until the replacement is confirmed.
|
|
88
|
+
const indexInsertError = await pgIndex
|
|
89
|
+
.upsertPage(targetName, frontmatter, finalContent, writeResult.revision, writeResult.modifiedTime, indexOwner)
|
|
90
|
+
.then(() => null)
|
|
91
|
+
.catch((err) => (err instanceof Error ? err.message : String(err)));
|
|
92
|
+
if (indexInsertError !== null) {
|
|
93
|
+
console.error(`[index] upsert failed for '${targetName}' during move from '${name}': ${indexInsertError}`);
|
|
94
|
+
}
|
|
95
|
+
// Only retire the old row once the new one exists. If the insert failed, the
|
|
96
|
+
// stale row is the only thing keeping this page discoverable at all — and on
|
|
97
|
+
// a self-move the "old" row IS the row just written.
|
|
98
|
+
const indexDeleteError = indexInsertError !== null || isSelfMove
|
|
99
|
+
? null
|
|
100
|
+
: await pgIndex
|
|
101
|
+
.deletePage(name, indexOwner)
|
|
102
|
+
.then(() => null)
|
|
103
|
+
.catch((err) => (err instanceof Error ? err.message : String(err)));
|
|
104
|
+
// Fire-and-forget: the link graph is a derived index, and nothing in this
|
|
105
|
+
// response depends on it. Awaiting it put three sequential Supabase round
|
|
106
|
+
// trips (~350-525ms) on the caller's critical path purely to decide whether
|
|
107
|
+
// to attach a cosmetic warning (GH #424). Staleness is self-healing —
|
|
108
|
+
// links_extracted_at drives extract_links' catch-up pass.
|
|
109
|
+
// Skipped when the insert failed: edges for the old source were never removed
|
|
110
|
+
// (the delete was deliberately skipped), so adding edges for the new source
|
|
111
|
+
// would leave the page counted twice in get_backlinks.
|
|
112
|
+
if (indexInsertError === null) {
|
|
113
|
+
pgIndex
|
|
114
|
+
.syncPageLinks(targetName, content, indexOwner)
|
|
115
|
+
.catch((err) => {
|
|
116
|
+
console.warn(`[links] sync failed for '${targetName}'`, err instanceof Error ? err.message : err);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// index.md must not advance past Postgres. If the index insert failed, the
|
|
120
|
+
// authoritative row still names the old path, and moving the human-readable
|
|
121
|
+
// index on to the new one makes the two disagree with no way to tell which is
|
|
122
|
+
// right. On a self-move there is no old entry to remove.
|
|
123
|
+
if (indexInsertError === null) {
|
|
124
|
+
if (!isSelfMove) {
|
|
125
|
+
removeIndexEntry(drive, name).catch((err) => {
|
|
126
|
+
console.warn(`[index.md] remove failed for '${name}'`, err instanceof Error ? err.message : err);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
upsertIndexEntry(drive, {
|
|
130
|
+
name: targetName,
|
|
131
|
+
title: String(frontmatter.title ?? targetName),
|
|
132
|
+
summary: String(frontmatter.summary ?? ""),
|
|
133
|
+
updated: new Date().toISOString().slice(0, 10),
|
|
134
|
+
}).catch((err) => {
|
|
135
|
+
console.warn(`[index.md] upsert failed for '${targetName}'`, err instanceof Error ? err.message : err);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
appendLogEntry(drive, {
|
|
139
|
+
type: "move",
|
|
140
|
+
title: String(frontmatter.title ?? name),
|
|
141
|
+
detail: `Moved ${name} → ${targetName} (${input.action})`,
|
|
142
|
+
}, indexOwner).catch((err) => {
|
|
143
|
+
// Surfaced rather than swallowed: a silent stop here is how an
|
|
144
|
+
// oversized log.md would go unnoticed (GH #417).
|
|
145
|
+
console.warn("[log] append failed:", err instanceof Error ? err.message : err);
|
|
146
|
+
});
|
|
147
|
+
const warnings = [];
|
|
148
|
+
if (indexInsertError !== null) {
|
|
149
|
+
// Loud on purpose, and deliberately not claiming the old row exists. It
|
|
150
|
+
// usually does — the delete is skipped precisely to keep it — but a page
|
|
151
|
+
// created while the index was down has no row to fall back on, and in that
|
|
152
|
+
// case the page is now completely invisible. Asserting a fallback that
|
|
153
|
+
// isn't there would describe the safe outcome while the unsafe one happened.
|
|
154
|
+
warnings.push(`Index insert for '${targetName}' failed: ${indexInsertError}. ` +
|
|
155
|
+
`The page moved in storage but the index was not updated, so search and ` +
|
|
156
|
+
`list_pages will disagree with reality — the page may appear under its old ` +
|
|
157
|
+
`name '${name}', or not at all. Re-run the move, or run audit_index.`);
|
|
158
|
+
}
|
|
159
|
+
if (indexDeleteError !== null) {
|
|
160
|
+
warnings.push(`Index delete for old path failed: ${indexDeleteError}. Run audit_index to clean up.`);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
success: true,
|
|
164
|
+
oldName: name,
|
|
165
|
+
newName: targetName,
|
|
166
|
+
fileId: writeResult.fileId,
|
|
167
|
+
revision: writeResult.revision,
|
|
168
|
+
// Machine-readable, because `warnings` is prose and callers branch on
|
|
169
|
+
// `success`. The storage move genuinely did happen, so success stays true —
|
|
170
|
+
// but an agent summarising this result needs a field it can test to know the
|
|
171
|
+
// index is not consistent with it.
|
|
172
|
+
...(indexInsertError !== null ? { indexHealthy: false } : {}),
|
|
173
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
174
|
+
// A move is the other way a page reaches a path the spec forbids — and the
|
|
175
|
+
// way it happens during exactly the migrations meant to fix layout.
|
|
176
|
+
...(() => {
|
|
177
|
+
const layoutWarnings = lintLayout(targetName);
|
|
178
|
+
return layoutWarnings.length > 0 ? { layoutWarnings } : {};
|
|
179
|
+
})(),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=movePage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"movePage.js","sourceRoot":"","sources":["../../src/tools/movePage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { StorageClient } from "../storage/client.js";
|
|
3
|
+
export declare function versionPath(name: string, ts: string): string;
|
|
4
|
+
/** Saves a snapshot before overwrite. Fire-and-forget — never throws. */
|
|
5
|
+
export declare function snapshotPage(drive: StorageClient, name: string, content: string): Promise<void>;
|
|
6
|
+
export declare const listPageHistoryInputSchema: z.ZodObject<{
|
|
7
|
+
name: z.ZodString;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
name: string;
|
|
10
|
+
}, {
|
|
11
|
+
name: string;
|
|
12
|
+
}>;
|
|
13
|
+
export type ListPageHistoryInput = z.infer<typeof listPageHistoryInputSchema>;
|
|
14
|
+
export interface VersionEntry {
|
|
15
|
+
path: string;
|
|
16
|
+
timestamp: string;
|
|
17
|
+
size: number;
|
|
18
|
+
modifiedTime: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function listPageHistory(drive: StorageClient, input: ListPageHistoryInput): Promise<{
|
|
21
|
+
name: string;
|
|
22
|
+
versions: VersionEntry[];
|
|
23
|
+
}>;
|
|
24
|
+
export declare const readPageVersionInputSchema: z.ZodObject<{
|
|
25
|
+
name: z.ZodString;
|
|
26
|
+
timestamp: z.ZodString;
|
|
27
|
+
}, "strip", z.ZodTypeAny, {
|
|
28
|
+
name: string;
|
|
29
|
+
timestamp: string;
|
|
30
|
+
}, {
|
|
31
|
+
name: string;
|
|
32
|
+
timestamp: string;
|
|
33
|
+
}>;
|
|
34
|
+
export type ReadPageVersionInput = z.infer<typeof readPageVersionInputSchema>;
|
|
35
|
+
export declare function readPageVersion(drive: StorageClient, input: ReadPageVersionInput): Promise<object>;
|
|
36
|
+
//# sourceMappingURL=pageHistory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageHistory.d.ts","sourceRoot":"","sources":["../../src/tools/pageHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAkB1D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,yEAAyE;AACzE,wBAAsB,YAAY,CAChC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,eAAO,MAAM,0BAA0B;;;;;;EAErC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC,CAcrD;AAED,eAAO,MAAM,0BAA0B;;;;;;;;;EAGrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAUjB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const VERSIONS_DIR = "page-versions";
|
|
3
|
+
function slugifyName(name) {
|
|
4
|
+
// canonical/brains-dev.md → canonical-brains-dev
|
|
5
|
+
return name.replace(/\.md$/, "").replace(/\//g, "-").replace(/[^a-z0-9-]/g, "-");
|
|
6
|
+
}
|
|
7
|
+
function timestampKey() {
|
|
8
|
+
// 2026-06-16T12:34:56.789Z → 2026-06-16t123456z
|
|
9
|
+
return new Date().toISOString()
|
|
10
|
+
.replace("T", "t")
|
|
11
|
+
.replace(/:/g, "")
|
|
12
|
+
.replace(/\.\d+/, "")
|
|
13
|
+
.replace("Z", "z");
|
|
14
|
+
}
|
|
15
|
+
export function versionPath(name, ts) {
|
|
16
|
+
return `${VERSIONS_DIR}/${slugifyName(name)}/${ts}.md`;
|
|
17
|
+
}
|
|
18
|
+
/** Saves a snapshot before overwrite. Fire-and-forget — never throws. */
|
|
19
|
+
export async function snapshotPage(drive, name, content) {
|
|
20
|
+
try {
|
|
21
|
+
const ts = timestampKey();
|
|
22
|
+
await drive.createFile(versionPath(name, ts), content);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// best-effort; snapshot failure must never block the write
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export const listPageHistoryInputSchema = z.object({
|
|
29
|
+
name: z.string().describe("Relative path of the page (e.g. 'canonical/brains-dev-workflow.md')"),
|
|
30
|
+
});
|
|
31
|
+
export async function listPageHistory(drive, input) {
|
|
32
|
+
const prefix = `${VERSIONS_DIR}/${slugifyName(input.name)}/`;
|
|
33
|
+
const all = await drive.listFiles();
|
|
34
|
+
const versions = all
|
|
35
|
+
.filter((f) => f.name.startsWith(prefix))
|
|
36
|
+
.map((f) => ({
|
|
37
|
+
path: f.name,
|
|
38
|
+
timestamp: f.name.replace(prefix, "").replace(".md", ""),
|
|
39
|
+
size: f.size,
|
|
40
|
+
modifiedTime: f.modifiedTime,
|
|
41
|
+
}))
|
|
42
|
+
.sort((a, b) => b.timestamp.localeCompare(a.timestamp)); // newest-first
|
|
43
|
+
return { name: input.name, versions };
|
|
44
|
+
}
|
|
45
|
+
export const readPageVersionInputSchema = z.object({
|
|
46
|
+
name: z.string().describe("Relative path of the page"),
|
|
47
|
+
timestamp: z.string().describe("Timestamp key from list_page_history (e.g. '2026-06-16t123456z')"),
|
|
48
|
+
});
|
|
49
|
+
export async function readPageVersion(drive, input) {
|
|
50
|
+
const path = versionPath(input.name, input.timestamp);
|
|
51
|
+
const file = await drive.readFile(path);
|
|
52
|
+
return {
|
|
53
|
+
name: input.name,
|
|
54
|
+
timestamp: input.timestamp,
|
|
55
|
+
path: file.name,
|
|
56
|
+
content: file.content,
|
|
57
|
+
modifiedTime: file.modifiedTime,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=pageHistory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageHistory.js","sourceRoot":"","sources":["../../src/tools/pageHistory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type StorageClient } from "../storage/client.js";
|
|
3
|
+
export declare const patchPageInputSchema: z.ZodObject<{
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
operations: z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
6
|
+
type: z.ZodLiteral<"insert_after">;
|
|
7
|
+
anchor: z.ZodString;
|
|
8
|
+
text: z.ZodString;
|
|
9
|
+
occurrence: z.ZodDefault<z.ZodNumber>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
anchor: string;
|
|
12
|
+
type: "insert_after";
|
|
13
|
+
text: string;
|
|
14
|
+
occurrence: number;
|
|
15
|
+
}, {
|
|
16
|
+
anchor: string;
|
|
17
|
+
type: "insert_after";
|
|
18
|
+
text: string;
|
|
19
|
+
occurrence?: number | undefined;
|
|
20
|
+
}>, z.ZodObject<{
|
|
21
|
+
type: z.ZodLiteral<"insert_before">;
|
|
22
|
+
anchor: z.ZodString;
|
|
23
|
+
text: z.ZodString;
|
|
24
|
+
occurrence: z.ZodDefault<z.ZodNumber>;
|
|
25
|
+
}, "strip", z.ZodTypeAny, {
|
|
26
|
+
anchor: string;
|
|
27
|
+
type: "insert_before";
|
|
28
|
+
text: string;
|
|
29
|
+
occurrence: number;
|
|
30
|
+
}, {
|
|
31
|
+
anchor: string;
|
|
32
|
+
type: "insert_before";
|
|
33
|
+
text: string;
|
|
34
|
+
occurrence?: number | undefined;
|
|
35
|
+
}>, z.ZodObject<{
|
|
36
|
+
type: z.ZodLiteral<"replace">;
|
|
37
|
+
find: z.ZodString;
|
|
38
|
+
replace: z.ZodString;
|
|
39
|
+
occurrence: z.ZodDefault<z.ZodNumber>;
|
|
40
|
+
all: z.ZodDefault<z.ZodBoolean>;
|
|
41
|
+
}, "strip", z.ZodTypeAny, {
|
|
42
|
+
replace: string;
|
|
43
|
+
find: string;
|
|
44
|
+
type: "replace";
|
|
45
|
+
occurrence: number;
|
|
46
|
+
all: boolean;
|
|
47
|
+
}, {
|
|
48
|
+
replace: string;
|
|
49
|
+
find: string;
|
|
50
|
+
type: "replace";
|
|
51
|
+
occurrence?: number | undefined;
|
|
52
|
+
all?: boolean | undefined;
|
|
53
|
+
}>, z.ZodObject<{
|
|
54
|
+
type: z.ZodLiteral<"append">;
|
|
55
|
+
text: z.ZodString;
|
|
56
|
+
}, "strip", z.ZodTypeAny, {
|
|
57
|
+
type: "append";
|
|
58
|
+
text: string;
|
|
59
|
+
}, {
|
|
60
|
+
type: "append";
|
|
61
|
+
text: string;
|
|
62
|
+
}>, z.ZodObject<{
|
|
63
|
+
type: z.ZodLiteral<"replace_lines">;
|
|
64
|
+
startLine: z.ZodNumber;
|
|
65
|
+
endLine: z.ZodNumber;
|
|
66
|
+
text: z.ZodString;
|
|
67
|
+
}, "strip", z.ZodTypeAny, {
|
|
68
|
+
type: "replace_lines";
|
|
69
|
+
text: string;
|
|
70
|
+
startLine: number;
|
|
71
|
+
endLine: number;
|
|
72
|
+
}, {
|
|
73
|
+
type: "replace_lines";
|
|
74
|
+
text: string;
|
|
75
|
+
startLine: number;
|
|
76
|
+
endLine: number;
|
|
77
|
+
}>]>, "many">;
|
|
78
|
+
lineNumbersAre: z.ZodDefault<z.ZodEffects<z.ZodEnum<["file"]>, "file", unknown>>;
|
|
79
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
80
|
+
}, "strip", z.ZodTypeAny, {
|
|
81
|
+
name: string;
|
|
82
|
+
operations: ({
|
|
83
|
+
anchor: string;
|
|
84
|
+
type: "insert_after";
|
|
85
|
+
text: string;
|
|
86
|
+
occurrence: number;
|
|
87
|
+
} | {
|
|
88
|
+
anchor: string;
|
|
89
|
+
type: "insert_before";
|
|
90
|
+
text: string;
|
|
91
|
+
occurrence: number;
|
|
92
|
+
} | {
|
|
93
|
+
replace: string;
|
|
94
|
+
find: string;
|
|
95
|
+
type: "replace";
|
|
96
|
+
occurrence: number;
|
|
97
|
+
all: boolean;
|
|
98
|
+
} | {
|
|
99
|
+
type: "append";
|
|
100
|
+
text: string;
|
|
101
|
+
} | {
|
|
102
|
+
type: "replace_lines";
|
|
103
|
+
text: string;
|
|
104
|
+
startLine: number;
|
|
105
|
+
endLine: number;
|
|
106
|
+
})[];
|
|
107
|
+
lineNumbersAre: "file";
|
|
108
|
+
summary?: string | undefined;
|
|
109
|
+
}, {
|
|
110
|
+
name: string;
|
|
111
|
+
operations: ({
|
|
112
|
+
anchor: string;
|
|
113
|
+
type: "insert_after";
|
|
114
|
+
text: string;
|
|
115
|
+
occurrence?: number | undefined;
|
|
116
|
+
} | {
|
|
117
|
+
anchor: string;
|
|
118
|
+
type: "insert_before";
|
|
119
|
+
text: string;
|
|
120
|
+
occurrence?: number | undefined;
|
|
121
|
+
} | {
|
|
122
|
+
replace: string;
|
|
123
|
+
find: string;
|
|
124
|
+
type: "replace";
|
|
125
|
+
occurrence?: number | undefined;
|
|
126
|
+
all?: boolean | undefined;
|
|
127
|
+
} | {
|
|
128
|
+
type: "append";
|
|
129
|
+
text: string;
|
|
130
|
+
} | {
|
|
131
|
+
type: "replace_lines";
|
|
132
|
+
text: string;
|
|
133
|
+
startLine: number;
|
|
134
|
+
endLine: number;
|
|
135
|
+
})[];
|
|
136
|
+
summary?: string | undefined;
|
|
137
|
+
lineNumbersAre?: unknown;
|
|
138
|
+
}>;
|
|
139
|
+
export type PatchPageInput = z.infer<typeof patchPageInputSchema>;
|
|
140
|
+
export declare function patchPage(drive: StorageClient, input: PatchPageInput, userId?: string): Promise<object>;
|
|
141
|
+
//# sourceMappingURL=patchPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patchPage.d.ts","sourceRoot":"","sources":["../../src/tools/patchPage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,aAAa,EAA4B,MAAM,sBAAsB,CAAC;AA6CpF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiC/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAGlE,wBAAsB,SAAS,CAC7B,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,cAAc,EACrB,MAAM,SAAK,GACV,OAAO,CAAC,MAAM,CAAC,CA6JjB"}
|