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,233 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import AdmZip from "adm-zip";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import matter from "gray-matter";
|
|
6
|
+
import { getPostgresSearchIndex } from "../search/postgresIndex.js";
|
|
7
|
+
import { listActiveGrantsForGrantee } from "../access/projectShares.js";
|
|
8
|
+
// Concurrency for parallel Supabase reads during export. Tunable via env var.
|
|
9
|
+
export const READ_CONCURRENCY = Math.max(1, parseInt(process.env.PULL_WIKI_READ_CONCURRENCY ?? "20", 10));
|
|
10
|
+
// Base64-encoding a ZIP adds ~33% overhead; large wikis can produce a response
|
|
11
|
+
// that silently overflows MCP client buffers (observed at ~3-5.5 MB). Reject
|
|
12
|
+
// before encoding and point the caller at the HTTP async export endpoint instead.
|
|
13
|
+
export const INLINE_ZIP_SIZE_LIMIT_BYTES = 3 * 1024 * 1024;
|
|
14
|
+
export const exportWikiInputSchema = z.object({
|
|
15
|
+
outputPath: z
|
|
16
|
+
.string()
|
|
17
|
+
.min(1)
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Optional: absolute or relative path where the ZIP archive will be written (e.g. '/tmp/wiki-export.zip'). When omitted, the ZIP is returned as a base64-encoded string in the response — no server filesystem access required."),
|
|
20
|
+
includeSystem: z
|
|
21
|
+
.boolean()
|
|
22
|
+
.default(true)
|
|
23
|
+
.describe("If true, includes system files index.md and log.md in the archive"),
|
|
24
|
+
folder: z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("Optional: filter to only pages whose path starts with this prefix (e.g. 'projects/brainsapp')"),
|
|
28
|
+
tags: z
|
|
29
|
+
.array(z.string())
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Optional: filter to only pages that have at least one of these tags in their frontmatter"),
|
|
32
|
+
});
|
|
33
|
+
function pageMatchesFilter(name, content, folder, tags) {
|
|
34
|
+
const hasFilter = folder !== undefined || (tags !== undefined && tags.length > 0);
|
|
35
|
+
if (!hasFilter)
|
|
36
|
+
return true;
|
|
37
|
+
const normalizedFolder = folder ? folder.replace(/\/$/, "") + "/" : undefined;
|
|
38
|
+
const matchesFolder = normalizedFolder ? name.startsWith(normalizedFolder) : false;
|
|
39
|
+
if (tags && tags.length > 0) {
|
|
40
|
+
try {
|
|
41
|
+
const parsed = matter(content);
|
|
42
|
+
const pageTags = parsed.data?.tags ?? [];
|
|
43
|
+
const matchesTags = tags.some((t) => pageTags.includes(t));
|
|
44
|
+
if (matchesTags)
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// If frontmatter parsing fails, fall through to folder check only
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return matchesFolder;
|
|
52
|
+
}
|
|
53
|
+
// Returns false when the file can be skipped without a content read.
|
|
54
|
+
function namePassesPreFilter(name, includeSystem, folder, tags) {
|
|
55
|
+
if (!includeSystem && (name === "index.md" || name === "log.md"))
|
|
56
|
+
return false;
|
|
57
|
+
// When a folder filter is set with no tags filter, we can reject by name alone.
|
|
58
|
+
if (folder && !(tags && tags.length > 0)) {
|
|
59
|
+
const normalizedFolder = folder.replace(/\/$/, "") + "/";
|
|
60
|
+
if (!name.startsWith(normalizedFolder))
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
// Run `fn` over `items` with at most `concurrency` items in-flight at a time.
|
|
66
|
+
export async function mapConcurrent(items, concurrency, fn) {
|
|
67
|
+
const results = new Array(items.length);
|
|
68
|
+
let nextIndex = 0;
|
|
69
|
+
const worker = async () => {
|
|
70
|
+
let index = nextIndex++;
|
|
71
|
+
while (index < items.length) {
|
|
72
|
+
results[index] = await fn(items[index]);
|
|
73
|
+
index = nextIndex++;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const workers = Array.from({ length: Math.min(concurrency, items.length) }, worker);
|
|
77
|
+
await Promise.all(workers);
|
|
78
|
+
return results;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Active project-share grants (BRA-368) for `userId`, narrowed to those
|
|
82
|
+
* relevant to `folder` (if set). Without this, the delta/`changedAfter` export
|
|
83
|
+
* path queries the Postgres index by owner subject only and silently drops
|
|
84
|
+
* pages from projects shared to `userId` — same root cause as BRA-379/#380
|
|
85
|
+
* and BRA-383/#384.
|
|
86
|
+
*/
|
|
87
|
+
async function grantScopesFor(userId, folder) {
|
|
88
|
+
if (!userId)
|
|
89
|
+
return [];
|
|
90
|
+
const normalizedFolder = folder ? folder.replace(/\/$/, "") : undefined;
|
|
91
|
+
const grants = await listActiveGrantsForGrantee(userId);
|
|
92
|
+
return grants
|
|
93
|
+
.filter((g) => !normalizedFolder ||
|
|
94
|
+
g.project_path === normalizedFolder ||
|
|
95
|
+
g.project_path.startsWith(`${normalizedFolder}/`) ||
|
|
96
|
+
normalizedFolder.startsWith(`${g.project_path}/`))
|
|
97
|
+
.map((g) => ({ userId: g.owner_subject, folder: g.project_path }));
|
|
98
|
+
}
|
|
99
|
+
export async function buildExportZip(drive, options) {
|
|
100
|
+
const exportedAt = new Date().toISOString();
|
|
101
|
+
const includeSystem = options.includeSystem ?? false;
|
|
102
|
+
// Fetch Postgres content-modified timestamps when available — real edit dates
|
|
103
|
+
// rather than Supabase storage upload times (identical for all pages after bulk import).
|
|
104
|
+
const storageBackend = (process.env.STORAGE_BACKEND ?? "local").toLowerCase();
|
|
105
|
+
const pgIndex = getPostgresSearchIndex();
|
|
106
|
+
const usePg = storageBackend === "supabase" && pgIndex.isConfigured();
|
|
107
|
+
let pgTimestamps = null;
|
|
108
|
+
let changedSet = null;
|
|
109
|
+
if (usePg) {
|
|
110
|
+
try {
|
|
111
|
+
const grantScopes = await grantScopesFor(options.userId ?? "", options.folder);
|
|
112
|
+
const rows = await pgIndex.listPages({
|
|
113
|
+
userId: options.userId ?? "",
|
|
114
|
+
changedAfter: options.changedAfter,
|
|
115
|
+
compact: true,
|
|
116
|
+
grantScopes,
|
|
117
|
+
});
|
|
118
|
+
pgTimestamps = new Map(rows.map((r) => [r.name, r.modified]));
|
|
119
|
+
if (options.changedAfter) {
|
|
120
|
+
changedSet = new Set(rows.map((r) => r.name));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Non-fatal — fall back to storage modifiedTime
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const allEntries = await drive.listFiles();
|
|
128
|
+
// Pre-filter by name, Postgres delta set, or storage mtime.
|
|
129
|
+
const preFiltered = allEntries.filter((e) => {
|
|
130
|
+
if (!namePassesPreFilter(e.name, includeSystem, options.folder, options.tags))
|
|
131
|
+
return false;
|
|
132
|
+
if (changedSet !== null && !changedSet.has(e.name))
|
|
133
|
+
return false;
|
|
134
|
+
if (options.changedAfter && !usePg) {
|
|
135
|
+
const mtime = new Date(e.modifiedTime).getTime();
|
|
136
|
+
const cursor = new Date(options.changedAfter).getTime();
|
|
137
|
+
if (!isNaN(mtime) && !isNaN(cursor) && mtime <= cursor)
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
});
|
|
142
|
+
const nameSkipped = allEntries.length - preFiltered.length;
|
|
143
|
+
const readResults = await mapConcurrent(preFiltered, READ_CONCURRENCY, async (entry) => {
|
|
144
|
+
try {
|
|
145
|
+
const file = await drive.readFile(entry.name);
|
|
146
|
+
return { ok: true, name: entry.name, content: file.content, modifiedTime: file.modifiedTime };
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
return { ok: false, name: entry.name, reason: err instanceof Error ? err.message : String(err) };
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
const zip = new AdmZip();
|
|
153
|
+
const index = [];
|
|
154
|
+
const errors = [];
|
|
155
|
+
let included = 0;
|
|
156
|
+
let skipped = nameSkipped;
|
|
157
|
+
for (const result of readResults) {
|
|
158
|
+
if (!result.ok) {
|
|
159
|
+
errors.push({ name: result.name, reason: result.reason });
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (!pageMatchesFilter(result.name, result.content, options.folder, options.tags)) {
|
|
163
|
+
skipped++;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const contentBuffer = Buffer.from(result.content, "utf8");
|
|
167
|
+
zip.addFile(result.name, contentBuffer);
|
|
168
|
+
// Use Postgres content-modified time over storage upload time
|
|
169
|
+
const modifiedTime = pgTimestamps?.get(result.name) || result.modifiedTime;
|
|
170
|
+
index.push({ name: result.name, size: contentBuffer.length, modifiedTime });
|
|
171
|
+
included++;
|
|
172
|
+
}
|
|
173
|
+
// Generate export-index.json inside the archive
|
|
174
|
+
const exportIndex = { exportedAt, fileCount: included, files: index };
|
|
175
|
+
if (options.changedAfter)
|
|
176
|
+
exportIndex.since = options.changedAfter;
|
|
177
|
+
zip.addFile("export-index.json", Buffer.from(JSON.stringify(exportIndex, null, 2), "utf8"));
|
|
178
|
+
return {
|
|
179
|
+
buffer: zip.toBuffer(),
|
|
180
|
+
pageCount: included,
|
|
181
|
+
skippedCount: skipped,
|
|
182
|
+
generatedAt: exportedAt,
|
|
183
|
+
...(options.changedAfter ? { since: options.changedAfter } : {}),
|
|
184
|
+
files: index,
|
|
185
|
+
errors,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
export async function exportWiki(drive, input) {
|
|
189
|
+
const startMs = Date.now();
|
|
190
|
+
const { buffer, pageCount, skippedCount, generatedAt, files, errors } = await buildExportZip(drive, {
|
|
191
|
+
includeSystem: input.includeSystem,
|
|
192
|
+
folder: input.folder,
|
|
193
|
+
tags: input.tags,
|
|
194
|
+
});
|
|
195
|
+
const durationMs = Date.now() - startMs;
|
|
196
|
+
const base = {
|
|
197
|
+
success: errors.length === 0,
|
|
198
|
+
exportedAt: generatedAt,
|
|
199
|
+
durationMs,
|
|
200
|
+
fileCount: pageCount,
|
|
201
|
+
skippedCount,
|
|
202
|
+
archiveSizeBytes: buffer.length,
|
|
203
|
+
files,
|
|
204
|
+
...(errors.length > 0 ? { errors } : {}),
|
|
205
|
+
};
|
|
206
|
+
if (!input.outputPath) {
|
|
207
|
+
// Agent-friendly mode: return the zip as base64, no server filesystem write.
|
|
208
|
+
if (buffer.length > INLINE_ZIP_SIZE_LIMIT_BYTES) {
|
|
209
|
+
return {
|
|
210
|
+
...base,
|
|
211
|
+
success: false,
|
|
212
|
+
error: `Export ZIP is ${(buffer.length / (1024 * 1024)).toFixed(1)} MB, which exceeds the ${INLINE_ZIP_SIZE_LIMIT_BYTES / (1024 * 1024)} MB limit for inline base64 responses and would silently overflow the response buffer. ` +
|
|
213
|
+
`Use the HTTP async export endpoint instead: POST /api/v1/export followed by GET /api/v1/export/download, ` +
|
|
214
|
+
`or pass an outputPath to write the ZIP to a local file.`,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return { ...base, zipData: buffer.toString("base64") };
|
|
218
|
+
}
|
|
219
|
+
// File-path mode: write to disk and return path metadata.
|
|
220
|
+
// Only here do we signal local-mode — a ZIP now exists on the local
|
|
221
|
+
// filesystem the agent can unpack and work on. (Not in base64 mode,
|
|
222
|
+
// where nothing is written to disk.)
|
|
223
|
+
const resolvedOutput = path.resolve(input.outputPath);
|
|
224
|
+
await fs.mkdir(path.dirname(resolvedOutput), { recursive: true });
|
|
225
|
+
await fs.writeFile(resolvedOutput, buffer);
|
|
226
|
+
return {
|
|
227
|
+
...base,
|
|
228
|
+
outputPath: resolvedOutput,
|
|
229
|
+
local_mode: true,
|
|
230
|
+
_local_mode_instructions: `Wiki exported as a ZIP archive at ${resolvedOutput} (not an extracted folder). To edit locally: unzip it, then use filesystem ops on the extracted markdown — Read instead of read_page, Write/Edit instead of update_page/patch_page, Glob/Grep instead of search_pages/list_pages. When done, re-zip the files and call import_wiki with zipPath pointing to that ZIP to sync changes back.`,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=exportWiki.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exportWiki.js","sourceRoot":"","sources":["../../src/tools/exportWiki.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const extractLinksInputSchema: z.ZodObject<{
|
|
3
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
4
|
+
folder: z.ZodOptional<z.ZodString>;
|
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
|
6
|
+
tags?: string[] | undefined;
|
|
7
|
+
folder?: string | undefined;
|
|
8
|
+
}, {
|
|
9
|
+
tags?: string[] | undefined;
|
|
10
|
+
folder?: string | undefined;
|
|
11
|
+
}>;
|
|
12
|
+
export type ExtractLinksInput = z.infer<typeof extractLinksInputSchema>;
|
|
13
|
+
export declare function extractLinks(input: ExtractLinksInput, userId?: string): Promise<object>;
|
|
14
|
+
//# sourceMappingURL=extractLinks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractLinks.d.ts","sourceRoot":"","sources":["../../src/tools/extractLinks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,uBAAuB;;;;;;;;;EASlC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,EACxB,MAAM,SAAK,GACV,OAAO,CAAC,MAAM,CAAC,CAWjB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getPostgresSearchIndex } from "../search/postgresIndex.js";
|
|
3
|
+
export const extractLinksInputSchema = z.object({
|
|
4
|
+
tags: z
|
|
5
|
+
.array(z.string())
|
|
6
|
+
.optional()
|
|
7
|
+
.describe("Filter pages by tag (any match). At least one of tags or folder is required."),
|
|
8
|
+
folder: z
|
|
9
|
+
.string()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe("Filter pages by name prefix (e.g. 'projects/brainsapp')."),
|
|
12
|
+
});
|
|
13
|
+
export async function extractLinks(input, userId = "") {
|
|
14
|
+
const tags = (input.tags ?? []).map((t) => t.trim()).filter((t) => t.length > 0);
|
|
15
|
+
const folder = input.folder?.trim();
|
|
16
|
+
if (tags.length === 0 && !folder) {
|
|
17
|
+
throw new Error("At least one filter is required: tags or folder");
|
|
18
|
+
}
|
|
19
|
+
return await getPostgresSearchIndex().extractLinksForStalePages({
|
|
20
|
+
tags,
|
|
21
|
+
folder,
|
|
22
|
+
userId,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=extractLinks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractLinks.js","sourceRoot":"","sources":["../../src/tools/extractLinks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,IAAI,EAAE,CAAC;SACJ,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,8EAA8E,CAAC;IAC3F,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,0DAA0D,CAAC;CACxE,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAwB,EACxB,MAAM,GAAG,EAAE;IAEX,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,MAAM,sBAAsB,EAAE,CAAC,yBAAyB,CAAC;QAC9D,IAAI;QACJ,MAAM;QACN,MAAM;KACP,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type StorageClient } from "../storage/client.js";
|
|
3
|
+
export declare const generateClaudeInstructionsInputSchema: z.ZodObject<{
|
|
4
|
+
projectName: z.ZodString;
|
|
5
|
+
variant: z.ZodDefault<z.ZodEnum<["minimal", "extended", "pointer"]>>;
|
|
6
|
+
projectPage: z.ZodOptional<z.ZodString>;
|
|
7
|
+
inScopePaths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
8
|
+
materialOutcomeDefinition: z.ZodOptional<z.ZodString>;
|
|
9
|
+
includeExamples: z.ZodDefault<z.ZodBoolean>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
projectName: string;
|
|
12
|
+
variant: "minimal" | "extended" | "pointer";
|
|
13
|
+
includeExamples: boolean;
|
|
14
|
+
projectPage?: string | undefined;
|
|
15
|
+
inScopePaths?: string[] | undefined;
|
|
16
|
+
materialOutcomeDefinition?: string | undefined;
|
|
17
|
+
}, {
|
|
18
|
+
projectName: string;
|
|
19
|
+
variant?: "minimal" | "extended" | "pointer" | undefined;
|
|
20
|
+
projectPage?: string | undefined;
|
|
21
|
+
inScopePaths?: string[] | undefined;
|
|
22
|
+
materialOutcomeDefinition?: string | undefined;
|
|
23
|
+
includeExamples?: boolean | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
export type GenerateClaudeInstructionsInput = z.infer<typeof generateClaudeInstructionsInputSchema>;
|
|
26
|
+
export declare function generateClaudeInstructions(input: GenerateClaudeInstructionsInput, drive?: StorageClient, userId?: string): Promise<object>;
|
|
27
|
+
//# sourceMappingURL=generateClaudeInstructions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateClaudeInstructions.d.ts","sourceRoot":"","sources":["../../src/tools/generateClaudeInstructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA0C1D,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;;EA+BhD,CAAC;AAEH,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAgMpG,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,+BAA+B,EACtC,KAAK,CAAC,EAAE,aAAa,EACrB,MAAM,SAAK,GACV,OAAO,CAAC,MAAM,CAAC,CA2CjB"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { gatherProjectContext, } from "./instructionContext.js";
|
|
3
|
+
function slugifyProjectName(value) {
|
|
4
|
+
const slug = value
|
|
5
|
+
.trim()
|
|
6
|
+
.toLowerCase()
|
|
7
|
+
.replace(/[^a-z0-9-]+/g, "-")
|
|
8
|
+
.replace(/-+/g, "-")
|
|
9
|
+
.replace(/^-|-$/g, "");
|
|
10
|
+
return slug || "project";
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The project's real slug.
|
|
14
|
+
*
|
|
15
|
+
* Prefer deriving it from projectPage, which callers set to the actual project
|
|
16
|
+
* location, over slugifying the display name. init_project accepts an explicit
|
|
17
|
+
* projectSlug that need not match slugify(projectName) — and when it did not,
|
|
18
|
+
* every write-back target in the emitted block pointed at a folder that does
|
|
19
|
+
* not exist. That is the "slug drift from generation" seen on cressida, whose
|
|
20
|
+
* block referenced projects/cressida-wagon/. Reproduced deterministically:
|
|
21
|
+
* projectSlug "index-probe-tmp" with projectName "Index Probe" emitted targets
|
|
22
|
+
* under projects/index-probe/ (GH #436).
|
|
23
|
+
*
|
|
24
|
+
* Handles both shapes callers pass: "projects/<slug>/readme.md" and the
|
|
25
|
+
* defaultProjectPage form "projects/<slug>/readme.md".
|
|
26
|
+
*/
|
|
27
|
+
function resolveSlug(projectName, projectPage) {
|
|
28
|
+
const match = projectPage?.trim().match(/^projects\/([^/]+?)(?:\.md)?(?:\/|$)/);
|
|
29
|
+
return match ? match[1] : slugifyProjectName(projectName);
|
|
30
|
+
}
|
|
31
|
+
function defaultProjectPage(projectName) {
|
|
32
|
+
return `projects/${slugifyProjectName(projectName)}/readme.md`;
|
|
33
|
+
}
|
|
34
|
+
export const generateClaudeInstructionsInputSchema = z.object({
|
|
35
|
+
projectName: z
|
|
36
|
+
.string()
|
|
37
|
+
.min(1)
|
|
38
|
+
.describe("Project name to include in generated instructions."),
|
|
39
|
+
variant: z
|
|
40
|
+
.enum(["minimal", "extended", "pointer"])
|
|
41
|
+
.default("extended")
|
|
42
|
+
.describe("Instruction verbosity level. 'extended' is recommended for the wiki instruction file. 'pointer' emits a short system-prompt block (identity, activation gate, one boot sequence, and a pointer to the wiki instruction file) for pasting into a Claude Project."),
|
|
43
|
+
projectPage: z
|
|
44
|
+
.string()
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("Project page path for project-specific write-back (for example: projects/my-project.md)."),
|
|
47
|
+
inScopePaths: z
|
|
48
|
+
.array(z.string())
|
|
49
|
+
.optional()
|
|
50
|
+
.describe("Folders/pages in scope. Omit to derive them from what the project actually contains — the old default named global instructions/, which brain-structure.md invariant 4 reserves against project content (D14)."),
|
|
51
|
+
materialOutcomeDefinition: z
|
|
52
|
+
.string()
|
|
53
|
+
.optional()
|
|
54
|
+
.describe("What counts as a material outcome. Omit for a domain-neutral definition; the old default described software delivery and was emitted verbatim into projects that ship videos, not code (D14)."),
|
|
55
|
+
includeExamples: z
|
|
56
|
+
.boolean()
|
|
57
|
+
.default(true)
|
|
58
|
+
.describe("If true, include concrete write-back snippets in extended output."),
|
|
59
|
+
});
|
|
60
|
+
function renderPointer(input) {
|
|
61
|
+
const slug = resolveSlug(input.projectName, input.projectPage);
|
|
62
|
+
const instructionFile = `projects/${slug}/instructions/claude.md`;
|
|
63
|
+
return [
|
|
64
|
+
`# ${input.projectName} Agent Instructions`,
|
|
65
|
+
"",
|
|
66
|
+
"**Brain-First:** Brains is the first source of truth. Read before acting.",
|
|
67
|
+
"",
|
|
68
|
+
"**Only run this sequence if these instructions are present in your project system prompt.** When Brains MCP is connected but these instructions are not in the system prompt, tools are available passively — do not run any startup reads automatically.",
|
|
69
|
+
"",
|
|
70
|
+
"## Boot Sequence",
|
|
71
|
+
"At the start of every chat:",
|
|
72
|
+
"1. Determine session mode: targeted (1–2 known pages) or bundle (exploratory/cross-page).",
|
|
73
|
+
`2. If bundle mode: \`pull_session_bundle(folder: "projects/${slug}", maxBytes: 150000, maxPages: 30)\` — this is your working set.`,
|
|
74
|
+
"3. If targeted mode: `read_page` on the specific page(s).",
|
|
75
|
+
`4. Read \`${instructionFile}\` and follow it.`,
|
|
76
|
+
"Do not begin work until these reads complete.",
|
|
77
|
+
].join("\n");
|
|
78
|
+
}
|
|
79
|
+
function renderMinimal(projectName) {
|
|
80
|
+
return [
|
|
81
|
+
`# ${projectName} Agent Instructions`,
|
|
82
|
+
"",
|
|
83
|
+
"Brains-first always. Determine mode at session open: targeted (1–2 known pages → `read_page`/`patch_page`) or bundle (exploratory → `pull_session_bundle`, work in memory, push at close-out). Bundle text is your wiki for the session — do not call `read_page` on bundled pages mid-session. No guessing: if missing, log as open loop. After material work, write back decisions + open loops. Push bundle at close-out or work is lost.",
|
|
84
|
+
].join("\n");
|
|
85
|
+
}
|
|
86
|
+
function renderExtended(input, ctx) {
|
|
87
|
+
const slug = resolveSlug(input.projectName, input.projectPage);
|
|
88
|
+
// "exists" vs "created on first use", per target. Silence here is what let a
|
|
89
|
+
// maintainer read the correct spec paths as invented ones (D13).
|
|
90
|
+
const mark = (path) => ctx.existingPaths.has(path) ? `\`${path}\` *(exists)*` : `\`${path}\` *(created on first use)*`;
|
|
91
|
+
const openLoopRollup = `projects/${slug}/open-loops.md`;
|
|
92
|
+
const decisionsLog = `projects/${slug}/decisions/decisions-log.md`;
|
|
93
|
+
const nextActions = `projects/${slug}/state/next-actions.md`;
|
|
94
|
+
// Rolling-state page lives at the project root as status.md, not under
|
|
95
|
+
// state/. brain-structure.md already sanctioned status.md as an allowed
|
|
96
|
+
// loose file at a project root and the structure audit enforces that list,
|
|
97
|
+
// while separately describing state/current-state.md — two conventions for
|
|
98
|
+
// one page, which is exactly how projects drifted apart (D4, GH #439).
|
|
99
|
+
const statusPage = `projects/${slug}/status.md`;
|
|
100
|
+
const lines = [
|
|
101
|
+
`# ${input.projectName} Agent Instructions`,
|
|
102
|
+
"",
|
|
103
|
+
"## Activation Gate",
|
|
104
|
+
"**Brain-First rule:** Brains is the first source of truth. Read relevant brain pages before planning, coding, or answering.",
|
|
105
|
+
"",
|
|
106
|
+
"**Only run the startup ritual in this file if these instructions are present in your project system prompt.** When Brains MCP is connected but these instructions are not in the system prompt, tools are available passively — do not invoke any Brains tools at startup.",
|
|
107
|
+
"",
|
|
108
|
+
"## Boot Sequence",
|
|
109
|
+
"At the start of every chat:",
|
|
110
|
+
// health_check is deliberately absent: brains-protocol.md reserves it for
|
|
111
|
+
// post-deploy verification, "not every cold start". It costs two Supabase
|
|
112
|
+
// round trips (~370ms) and proves nothing any other call does not (GH #434).
|
|
113
|
+
"1. Determine session mode from the task (see Session Mode below).",
|
|
114
|
+
`2. \`list_pages folder=projects/${slug}\` — get inventory.`,
|
|
115
|
+
`3. If bundle mode: \`pull_session_bundle(folder: "projects/${slug}", maxBytes: 150000, maxPages: 30)\` — this is your working set for the session.`,
|
|
116
|
+
"4. If targeted mode: `read_page` on the specific known page(s).",
|
|
117
|
+
"Do not begin work until retrieval is complete.",
|
|
118
|
+
"",
|
|
119
|
+
"## Session Mode",
|
|
120
|
+
"| Signal | Mode | Tools |",
|
|
121
|
+
"|---|---|---|",
|
|
122
|
+
"| Task names 1–2 specific pages | Targeted | `read_page` → edit → `update_page` or `patch_page` |",
|
|
123
|
+
`| Task is exploratory, cross-page, or uses "look through / find / review / what do I have / dig for" | Bundle | \`pull_session_bundle\` → work in memory → \`push_session_bundle\` |`,
|
|
124
|
+
"| Quick question, no writes | Remote-only | MCP reads directly |",
|
|
125
|
+
"",
|
|
126
|
+
"**When in doubt, use bundle mode.**",
|
|
127
|
+
"",
|
|
128
|
+
"## Working Set Contract (Bundle Mode)",
|
|
129
|
+
"- The bundle text IS your wiki for this session.",
|
|
130
|
+
"- Do NOT call `read_page` on pages already in the bundle.",
|
|
131
|
+
"- Do NOT call `patch_page` or `update_page` mid-session on bundle pages.",
|
|
132
|
+
"- Edit the bundle text in memory. Push the full modified bundle at close-out.",
|
|
133
|
+
"- New pages created mid-session (not in bundle) may be written via `create_page` immediately.",
|
|
134
|
+
"",
|
|
135
|
+
"## Project Scope",
|
|
136
|
+
`- Active project slug: \`${slug}\``,
|
|
137
|
+
ctx.subdirs.length > 0
|
|
138
|
+
? `- Subdirs in use: ${ctx.subdirs.map((d) => `\`${d}/\``).join(", ")}.`
|
|
139
|
+
: "- Subdirs: `canonical/`, `decisions/`, `data/`, `history/`, `state/`, plus any the project needs (e.g. `events/`, `scripts/`, `resources/`).",
|
|
140
|
+
...(ctx.subProjects.length > 0
|
|
141
|
+
? [`- Sub-projects: ${ctx.subProjects.map((s) => `\`projects/${s}/\``).join(", ")}. Their pages count toward this project and arrive in a folder-scoped bundle for it.`]
|
|
142
|
+
: []),
|
|
143
|
+
`- All new pages must live under \`projects/${slug}/...\`.`,
|
|
144
|
+
"- Full layout spec: `instructions/brain-structure.md`.",
|
|
145
|
+
"",
|
|
146
|
+
"In-scope folders/pages:",
|
|
147
|
+
...(input.inScopePaths && input.inScopePaths.length > 0
|
|
148
|
+
? input.inScopePaths.map((p) => `- ${p}`)
|
|
149
|
+
: [
|
|
150
|
+
`- \`projects/${slug}/\` — everything this project owns`,
|
|
151
|
+
`- \`projects/${slug}/instructions/claude.md\` — this file`,
|
|
152
|
+
]),
|
|
153
|
+
"",
|
|
154
|
+
`Material outcome: ${input.materialOutcomeDefinition ?? "Any result that changes this project's state, plans, or committed decisions — not a question answered or a page merely read."}`,
|
|
155
|
+
"",
|
|
156
|
+
"## Write-Back (mandatory after material work)",
|
|
157
|
+
// init_project scaffolds only readme.md and the instruction file. The
|
|
158
|
+
// targets below are created on first use, which the block previously left
|
|
159
|
+
// unsaid — an agent told to append to a decisions log would reach for
|
|
160
|
+
// patch_page, which fails on a page that does not exist, and could read
|
|
161
|
+
// that as being in the wrong project (D1).
|
|
162
|
+
//
|
|
163
|
+
// Stated rather than scaffolded: bundles now select by folder, so empty
|
|
164
|
+
// stubs would be pulled into every session for the project's whole life.
|
|
165
|
+
ctx.exists
|
|
166
|
+
? "Each target below is marked with whether it exists right now. Use `create_page` for one that does not — `patch_page` fails on a missing page, and that failure reads like being in the wrong project."
|
|
167
|
+
: "**These pages are created on first use.** Only `readme.md` and this instruction file exist after `init_project`. Use `create_page` for a target that does not exist yet, and `patch_page` only once it does — `patch_page` fails on a missing page.",
|
|
168
|
+
"",
|
|
169
|
+
"After any session with writes, record:",
|
|
170
|
+
`- Decisions → ${mark(decisionsLog)} (append-only) + \`projects/${slug}/decisions/<topic>.md\` for rationale-heavy ones`,
|
|
171
|
+
`- Open loops → detail at \`projects/${slug}/open-loops/<loop-slug>.md\` (one page per loop) + one-line entry in ${mark(openLoopRollup)} (project rollup)`,
|
|
172
|
+
`- Next actions → ${mark(nextActions)}`,
|
|
173
|
+
`- Current state changes → ${mark(statusPage)}`,
|
|
174
|
+
"- Unanswered questions → inline as `- [ ] Question:` in the relevant project page",
|
|
175
|
+
`- Raw ingest → \`projects/${slug}/data/<file>.md\``,
|
|
176
|
+
`- Stable facts → \`projects/${slug}/canonical/<file>.md\``,
|
|
177
|
+
"",
|
|
178
|
+
"Hub-and-spoke for loops: detail page + rollup entry. No standalone aggregate files at brain root.",
|
|
179
|
+
"",
|
|
180
|
+
"## Close-Out Ritual",
|
|
181
|
+
'Before ending any session where writes were made:',
|
|
182
|
+
'1. Summarise what changed: "Here\'s what we did: X. Ready to push?"',
|
|
183
|
+
'2. On confirmation: push in pages mode, carrying each page\'s `revision` token from the pull so concurrent writes are detected:',
|
|
184
|
+
' `push_session_bundle(pages: [{name: "...", content: "...", revision: "<revision-from-pull>"}])`',
|
|
185
|
+
"3. Local work does not persist between chats — push or lose it.",
|
|
186
|
+
"",
|
|
187
|
+
"## Completion Gate",
|
|
188
|
+
"- [ ] Read relevant brain pages first (from bundle or targeted reads)",
|
|
189
|
+
"- [ ] No unsupported assumptions",
|
|
190
|
+
"- [ ] Decisions and open loops written back",
|
|
191
|
+
"- [ ] If bundle session: full modified bundle pushed via `push_session_bundle`",
|
|
192
|
+
"",
|
|
193
|
+
"Failure condition: write-back skipped, bundle not pushed — task is not done.",
|
|
194
|
+
"",
|
|
195
|
+
"## Scope Creep",
|
|
196
|
+
"If a new feature idea or architectural direction emerges mid-session that isn't already an open loop — name it, log it, do not design or implement it now.",
|
|
197
|
+
"",
|
|
198
|
+
"## API Notes",
|
|
199
|
+
"- **`patch_page` ops** — field sets vary by type:",
|
|
200
|
+
" - `replace`: `find`, `replace` (optionally `occurrence`, `all`)",
|
|
201
|
+
" - `insert_after` / `insert_before`: `anchor`, `text` (optionally `occurrence`)",
|
|
202
|
+
" - `append`: `text`",
|
|
203
|
+
" - `replace_lines`: `startLine`, `endLine`, `text`",
|
|
204
|
+
];
|
|
205
|
+
if (input.includeExamples) {
|
|
206
|
+
lines.push("", "## Write-Back Snippets", "### Decision", "**Decision:** [what was decided]", "**Why:** [reason]", "**Implications:** [what changes now]", "", "### Open Loop", `- [ ] [what is unresolved] → detail at \`projects/${slug}/open-loops/<loop-slug>.md\``, "", "### Next Action", `- [ ] [single concrete action, owner if known] → \`${nextActions}\``);
|
|
207
|
+
}
|
|
208
|
+
// A declared filing system means this project is audited against that skill's
|
|
209
|
+
// layout, not the Operator invariants the block above assumes. Say so rather
|
|
210
|
+
// than quietly handing it the wrong write-back table.
|
|
211
|
+
if (ctx.filing) {
|
|
212
|
+
lines.push("", "## Filing Override", `This project declares \`filing: ${ctx.filing}\` in its readme, so it is governed and audited by that skill, **not** by the Operator layout. Treat the write-back paths above as Operator defaults that may not apply — follow \`${ctx.filing}\`'s own layout where they differ.`);
|
|
213
|
+
}
|
|
214
|
+
// Anything hand-written survives regeneration. Without this, a refresh returns
|
|
215
|
+
// a block with the project's voice, contacts and conventions missing — so
|
|
216
|
+
// nobody refreshes, the file rots, and the drift this generator exists to
|
|
217
|
+
// prevent happens to the generator's own output (D13).
|
|
218
|
+
if (ctx.preservedRegion) {
|
|
219
|
+
lines.push("", ctx.preservedRegion);
|
|
220
|
+
}
|
|
221
|
+
return lines.join("\n");
|
|
222
|
+
}
|
|
223
|
+
export async function generateClaudeInstructions(input, drive, userId = "") {
|
|
224
|
+
const projectPage = input.projectPage?.trim() || defaultProjectPage(input.projectName);
|
|
225
|
+
const slug = resolveSlug(input.projectName, input.projectPage);
|
|
226
|
+
const openLoopRollup = `projects/${slug}/open-loops.md`;
|
|
227
|
+
const decisionsLog = `projects/${slug}/decisions/decisions-log.md`;
|
|
228
|
+
const nextActions = `projects/${slug}/state/next-actions.md`;
|
|
229
|
+
const statusPage = `projects/${slug}/status.md`;
|
|
230
|
+
const candidatePaths = [decisionsLog, openLoopRollup, nextActions, statusPage, projectPage];
|
|
231
|
+
// Only the extended variant renders write-back targets or scope, so the
|
|
232
|
+
// minimal and pointer variants stay free of wiki round trips.
|
|
233
|
+
const ctx = drive && input.variant === "extended"
|
|
234
|
+
? await gatherProjectContext(drive, slug, "claude", candidatePaths, userId)
|
|
235
|
+
: { exists: false, pageCount: 0, subdirs: [], subProjects: [], existingPaths: new Set() };
|
|
236
|
+
const markdown = input.variant === "minimal"
|
|
237
|
+
? renderMinimal(input.projectName)
|
|
238
|
+
: input.variant === "pointer"
|
|
239
|
+
? renderPointer(input)
|
|
240
|
+
: renderExtended(input, ctx);
|
|
241
|
+
return {
|
|
242
|
+
success: true,
|
|
243
|
+
platform: "claude",
|
|
244
|
+
variant: input.variant,
|
|
245
|
+
projectName: input.projectName,
|
|
246
|
+
projectPage,
|
|
247
|
+
writeBackTargets: [decisionsLog, openLoopRollup, projectPage],
|
|
248
|
+
// Reported alongside the block so a caller can see what the generator knew,
|
|
249
|
+
// rather than having to infer it from the prose.
|
|
250
|
+
projectContext: {
|
|
251
|
+
exists: ctx.exists,
|
|
252
|
+
pageCount: ctx.pageCount,
|
|
253
|
+
subdirs: ctx.subdirs,
|
|
254
|
+
subProjects: ctx.subProjects,
|
|
255
|
+
...(ctx.filing ? { filing: ctx.filing } : {}),
|
|
256
|
+
existingTargets: candidatePaths.filter((p) => ctx.existingPaths.has(p)),
|
|
257
|
+
missingTargets: candidatePaths.filter((p) => !ctx.existingPaths.has(p)),
|
|
258
|
+
preservedDomainContext: ctx.preservedRegion !== undefined,
|
|
259
|
+
},
|
|
260
|
+
markdown,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=generateClaudeInstructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateClaudeInstructions.js","sourceRoot":"","sources":["../../src/tools/generateClaudeInstructions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type StorageClient } from "../storage/client.js";
|
|
3
|
+
export declare const generateGptInstructionsInputSchema: z.ZodObject<{
|
|
4
|
+
projectName: z.ZodString;
|
|
5
|
+
variant: z.ZodDefault<z.ZodEnum<["minimal", "extended", "pointer"]>>;
|
|
6
|
+
projectPage: z.ZodOptional<z.ZodString>;
|
|
7
|
+
inScopePaths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
8
|
+
materialOutcomeDefinition: z.ZodOptional<z.ZodString>;
|
|
9
|
+
includeExamples: z.ZodDefault<z.ZodBoolean>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
projectName: string;
|
|
12
|
+
variant: "minimal" | "extended" | "pointer";
|
|
13
|
+
includeExamples: boolean;
|
|
14
|
+
projectPage?: string | undefined;
|
|
15
|
+
inScopePaths?: string[] | undefined;
|
|
16
|
+
materialOutcomeDefinition?: string | undefined;
|
|
17
|
+
}, {
|
|
18
|
+
projectName: string;
|
|
19
|
+
variant?: "minimal" | "extended" | "pointer" | undefined;
|
|
20
|
+
projectPage?: string | undefined;
|
|
21
|
+
inScopePaths?: string[] | undefined;
|
|
22
|
+
materialOutcomeDefinition?: string | undefined;
|
|
23
|
+
includeExamples?: boolean | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
export type GenerateGptInstructionsInput = z.infer<typeof generateGptInstructionsInputSchema>;
|
|
26
|
+
export declare function generateGptInstructions(input: GenerateGptInstructionsInput, drive?: StorageClient, userId?: string): Promise<object>;
|
|
27
|
+
//# sourceMappingURL=generateGptInstructions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateGptInstructions.d.ts","sourceRoot":"","sources":["../../src/tools/generateGptInstructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAqC1D,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;EA2B7C,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AA4I9F,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,4BAA4B,EACnC,KAAK,CAAC,EAAE,aAAa,EACrB,MAAM,SAAK,GACV,OAAO,CAAC,MAAM,CAAC,CAuCjB"}
|