@productbrain/mcp 0.0.1-beta.945 → 0.0.1-beta.9452
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 +67 -0
- package/dist/chunk-NCTCZQHK.js +13547 -0
- package/dist/chunk-NCTCZQHK.js.map +1 -0
- package/dist/chunk-Q77SFDBZ.js +1684 -0
- package/dist/chunk-Q77SFDBZ.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/http.js +425 -211
- package/dist/http.js.map +1 -1
- package/dist/index.js +8 -8
- package/dist/{setup-RYYXRDPB.js → setup-6UYW6XKO.js} +35 -26
- package/dist/setup-6UYW6XKO.js.map +1 -0
- package/dist/views/src/entry-cards/index.html +97 -72
- package/dist/views/src/graph-constellation/index.html +90 -65
- package/package.json +4 -3
- package/dist/chunk-VHL3Q5K6.js +0 -15191
- package/dist/chunk-VHL3Q5K6.js.map +0 -1
- package/dist/chunk-YMF3IQ5E.js +0 -465
- package/dist/chunk-YMF3IQ5E.js.map +0 -1
- package/dist/setup-RYYXRDPB.js.map +0 -1
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
DEFAULT_CLOUD_URL,
|
|
3
4
|
MCP_NPX_PACKAGE,
|
|
5
|
+
apiKeysUrl,
|
|
4
6
|
initAnalytics,
|
|
5
7
|
resolveClient,
|
|
6
8
|
shutdownAnalytics,
|
|
7
9
|
trackSetupCompleted,
|
|
8
10
|
trackSetupStarted,
|
|
11
|
+
warnOnProdFallthrough,
|
|
9
12
|
writeClientConfig
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-Q77SFDBZ.js";
|
|
11
14
|
|
|
12
15
|
// src/cli/setup.ts
|
|
13
16
|
import { execSync } from "child_process";
|
|
14
17
|
import { createInterface } from "readline";
|
|
15
18
|
import { existsSync, writeFileSync, mkdirSync } from "fs";
|
|
16
19
|
import { join } from "path";
|
|
17
|
-
var APP_URL = process.env.PRODUCTBRAIN_APP_URL ?? "https://work.productbrain.io";
|
|
18
20
|
function bold(s) {
|
|
19
21
|
return `\x1B[1m${s}\x1B[0m`;
|
|
20
22
|
}
|
|
@@ -69,9 +71,14 @@ function promptChoice(question, choices) {
|
|
|
69
71
|
});
|
|
70
72
|
});
|
|
71
73
|
}
|
|
72
|
-
|
|
74
|
+
function resolveSetupSiteUrl() {
|
|
75
|
+
const explicit = process.env.CONVEX_SITE_URL ?? process.env.PRODUCTBRAIN_URL;
|
|
76
|
+
const url = explicit ?? DEFAULT_CLOUD_URL;
|
|
77
|
+
warnOnProdFallthrough(url, { explicit: explicit != null });
|
|
78
|
+
return url;
|
|
79
|
+
}
|
|
73
80
|
async function verifyWorkspace(apiKey) {
|
|
74
|
-
const siteUrl =
|
|
81
|
+
const siteUrl = resolveSetupSiteUrl();
|
|
75
82
|
try {
|
|
76
83
|
const res = await fetch(`${siteUrl.replace(/\/$/, "")}/api/aki`, {
|
|
77
84
|
method: "POST",
|
|
@@ -94,20 +101,20 @@ async function runSetup() {
|
|
|
94
101
|
log("");
|
|
95
102
|
log(bold(` Product${orange("Brain")} Setup`));
|
|
96
103
|
log(dim(" Connect your AI assistant to your chain\n"));
|
|
97
|
-
const
|
|
104
|
+
const keysUrl = apiKeysUrl();
|
|
98
105
|
log(` ${dim("1. Get your API key from Settings \u2192 API Keys")}`);
|
|
99
|
-
log(` ${dim(
|
|
106
|
+
log(` ${dim(keysUrl)}
|
|
100
107
|
`);
|
|
101
108
|
const openNow = await prompt(` Open this URL in your browser? [Y/n]: `);
|
|
102
109
|
if (openNow.toLowerCase() !== "n" && openNow.toLowerCase() !== "no") {
|
|
103
|
-
openBrowser(
|
|
110
|
+
openBrowser(keysUrl);
|
|
104
111
|
}
|
|
105
112
|
log("");
|
|
106
113
|
log(` ${dim("2. Generate a key (if you don't have one), then copy it.\n")}`);
|
|
107
114
|
const apiKey = await prompt(` Paste your API key (pb_sk_...): `);
|
|
108
115
|
if (!apiKey || !apiKey.startsWith("pb_sk_")) {
|
|
109
116
|
log(` ${orange("!")} Invalid key format. Keys start with pb_sk_.`);
|
|
110
|
-
log(` Get one at ${
|
|
117
|
+
log(` Get one at ${keysUrl}
|
|
111
118
|
`);
|
|
112
119
|
await shutdownAnalytics();
|
|
113
120
|
process.exit(1);
|
|
@@ -117,7 +124,7 @@ async function runSetup() {
|
|
|
117
124
|
if (workspace) {
|
|
118
125
|
log(` ${green("\u2713")} Connected to workspace: ${bold(workspace.name)} ${dim(`(${workspace.slug})`)}`);
|
|
119
126
|
} else {
|
|
120
|
-
log(` ${orange("!")} Could not verify workspace. Check your key at ${
|
|
127
|
+
log(` ${orange("!")} Could not verify workspace. Check your key at ${keysUrl}`);
|
|
121
128
|
}
|
|
122
129
|
log("");
|
|
123
130
|
const CLIENT_NAMES = ["Cursor", "Claude Desktop"];
|
|
@@ -168,7 +175,7 @@ async function writeConfig(client, apiKey) {
|
|
|
168
175
|
}
|
|
169
176
|
}
|
|
170
177
|
function printHelpLink() {
|
|
171
|
-
log(` ${dim(`Need help? See ${
|
|
178
|
+
log(` ${dim(`Need help? See ${apiKeysUrl()}`)}`);
|
|
172
179
|
log("");
|
|
173
180
|
}
|
|
174
181
|
function printConfigSnippet(apiKey) {
|
|
@@ -203,25 +210,24 @@ alwaysApply: true
|
|
|
203
210
|
|
|
204
211
|
Product Brain is your product knowledge base. The Chain is the single source of truth.
|
|
205
212
|
|
|
206
|
-
Every entry is either a **draft** (captured but not
|
|
207
|
-
|
|
213
|
+
Every entry is either a **draft** (captured but not accepted) or **accepted** (on the Chain, SSOT).
|
|
214
|
+
Accepting onto the Chain is the compounding act.
|
|
208
215
|
|
|
209
216
|
## Quick Start
|
|
210
217
|
|
|
211
218
|
Say **"Start PB"** or **"Start Product Brain"** to begin. This single call:
|
|
212
219
|
- Orients you to the workspace (readiness, gaps, planned work)
|
|
213
|
-
- Unlocks write tools for the session
|
|
214
220
|
- Surfaces your next recommended action
|
|
215
221
|
|
|
216
222
|
## Tool Workflow
|
|
217
223
|
|
|
218
|
-
1. **Start here**: \`start\` \u2014 workspace context + next action
|
|
224
|
+
1. **Start here**: \`orient action=start\` \u2014 workspace context + next action
|
|
219
225
|
2. **Search**: \`entries action=search\` \u2014 find entries across all collections
|
|
220
226
|
3. **Drill in**: \`entries action=get\` \u2014 full record with data, labels, relations
|
|
221
227
|
4. **Context**: \`context action=gather\` \u2014 related knowledge around an entry or task
|
|
222
|
-
5. **Capture**: \`capture\` \u2014 create knowledge
|
|
223
|
-
6. **
|
|
224
|
-
7. **Connect**: \`
|
|
228
|
+
5. **Capture**: \`capture\` \u2014 create knowledge (pass \`links\` to relate it; nothing is linked automatically) + quality verdict
|
|
229
|
+
6. **Accept**: \`entries action=commit\` \u2014 promote drafts to SSOT when confirmation is still required
|
|
230
|
+
7. **Connect**: \`relations action=create\` to link the entries you know are related
|
|
225
231
|
|
|
226
232
|
## Bulk Knowledge Input
|
|
227
233
|
|
|
@@ -229,17 +235,19 @@ When given a document or batch of knowledge to capture:
|
|
|
229
235
|
1. Scan the input \u2014 identify all collections needed
|
|
230
236
|
2. Call \`collections action=list\` \u2014 compare against what exists
|
|
231
237
|
3. Propose missing collections to the user for confirmation
|
|
232
|
-
4.
|
|
238
|
+
4. Ask a platform admin to provision each confirmed collection (creating one is no longer
|
|
239
|
+
self-serve \u2014 ask an admin, or enable the module ontology pack that owns the drawer)
|
|
233
240
|
5. Then capture entries into the correct collections
|
|
234
241
|
|
|
235
242
|
Never stuff entries into the wrong collection. Never silently skip knowledge.
|
|
236
243
|
|
|
237
244
|
## Rules
|
|
238
245
|
|
|
239
|
-
- In Open mode, user-authored captures can
|
|
240
|
-
- In consensus/role modes, only call \`commit
|
|
241
|
-
-
|
|
242
|
-
- Collections are dynamic
|
|
246
|
+
- In Open mode, user-authored captures can be accepted immediately unless the user asks to keep them as drafts.
|
|
247
|
+
- In consensus/role modes, only call \`entries action=commit\` when the user confirms.
|
|
248
|
+
- After capturing, link related entries with \`relations action=create\`.
|
|
249
|
+
- Collections are dynamic, but creating a new one is not self-serve \u2014 ask a platform admin to
|
|
250
|
+
provision it, or enable the module ontology pack that owns the drawer.
|
|
243
251
|
- When lost, fetch \`productbrain://orientation\` for the full system map.
|
|
244
252
|
`;
|
|
245
253
|
function isCursorProject() {
|
|
@@ -286,12 +294,13 @@ function printClaudeSnippet() {
|
|
|
286
294
|
log(dim(" Add this line to your ~/.claude/CLAUDE.md:"));
|
|
287
295
|
log("");
|
|
288
296
|
log(` When Product Brain MCP is available, say "Start PB" at the beginning`);
|
|
289
|
-
log(` of each session to orient to the workspace and
|
|
290
|
-
log(` In Open mode, user-authored captures can
|
|
291
|
-
log(` In consensus/role modes, only
|
|
297
|
+
log(` of each session to orient to the workspace; workflow checkpoints and organisation-structure writes require it.`);
|
|
298
|
+
log(` In Open mode, user-authored captures can be accepted immediately unless the user asks to keep drafts.`);
|
|
299
|
+
log(` In consensus/role modes, only accept when the user confirms.`);
|
|
292
300
|
log("");
|
|
293
301
|
}
|
|
294
302
|
export {
|
|
303
|
+
resolveSetupSiteUrl,
|
|
295
304
|
runSetup
|
|
296
305
|
};
|
|
297
|
-
//# sourceMappingURL=setup-
|
|
306
|
+
//# sourceMappingURL=setup-6UYW6XKO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/setup.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * `npx @productbrain/mcp@beta setup`\n *\n * Guided onboarding: get API key from the app, paste it, write MCP config,\n * and optionally install Cursor rules/skills (additive-only).\n */\n\nimport { execSync } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\nimport { existsSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { resolveClient, writeClientConfig, MCP_NPX_PACKAGE, type McpClientInfo } from \"./config-writer.js\";\nimport { initAnalytics, trackSetupStarted, trackSetupCompleted, shutdownAnalytics } from \"../analytics.js\";\nimport { DEFAULT_CLOUD_URL } from \"../client.js\";\nimport { apiKeysUrl } from \"../lib/appUrl.js\";\nimport { warnOnProdFallthrough } from \"../prod-fallthrough.js\";\n\n// ── Helpers ─────────────────────────────────────────────────────────────\n\nfunction bold(s: string) {\n return `\\x1b[1m${s}\\x1b[0m`;\n}\nfunction green(s: string) {\n return `\\x1b[32m${s}\\x1b[0m`;\n}\nfunction dim(s: string) {\n return `\\x1b[2m${s}\\x1b[0m`;\n}\nfunction orange(s: string) {\n return `\\x1b[33m${s}\\x1b[0m`;\n}\n\nfunction log(msg: string) {\n process.stdout.write(`${msg}\\n`);\n}\n\nfunction openBrowser(url: string) {\n const platform = process.platform;\n try {\n if (platform === \"darwin\") execSync(`open \"${url}\"`);\n else if (platform === \"win32\") execSync(`start \"\" \"${url}\"`);\n else execSync(`xdg-open \"${url}\"`);\n } catch {\n log(dim(` Could not open browser automatically.`));\n log(` Open this URL manually: ${url}`);\n }\n}\n\nfunction prompt(question: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nfunction promptChoice(question: string, choices: string[]): Promise<number> {\n return new Promise((resolve) => {\n log(\"\");\n log(bold(question));\n choices.forEach((c, i) => log(` ${i + 1}) ${c}`));\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n rl.question(`\\n ${dim(\"Choice [1]:\")} `, (line) => {\n rl.close();\n const n = parseInt(line.trim(), 10);\n if (isNaN(n) || n < 1 || n > choices.length) {\n resolve(0);\n } else {\n resolve(n - 1);\n }\n });\n });\n}\n\n// ── Workspace Verification ───────────────────────────────────────────────\n\n/**\n * Resolve the gateway URL the setup flow probes. TEN-2382: setup is an\n * independent entry point (no bootstrap), so it warns on silent prod\n * fall-through here. DEFAULT_CLOUD_URL is imported from client.ts (the\n * in-package SSOT) — no local re-declare.\n */\nexport function resolveSetupSiteUrl(): string {\n const explicit = process.env.CONVEX_SITE_URL ?? process.env.PRODUCTBRAIN_URL;\n const url = explicit ?? DEFAULT_CLOUD_URL;\n warnOnProdFallthrough(url, { explicit: explicit != null });\n return url;\n}\n\nasync function verifyWorkspace(\n apiKey: string,\n): Promise<{ name: string; slug: string } | null> {\n const siteUrl = resolveSetupSiteUrl();\n\n try {\n const res = await fetch(`${siteUrl.replace(/\\/$/, \"\")}/api/aki`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ fn: \"resolveWorkspace\", args: {} }),\n });\n\n if (!res.ok) return null;\n const json = (await res.json()) as {\n data?: { name: string; slug: string } | null;\n error?: string;\n };\n return json.data ?? null;\n } catch {\n return null;\n }\n}\n\n// ── Main ────────────────────────────────────────────────────────────────\n\nexport async function runSetup() {\n initAnalytics();\n trackSetupStarted();\n\n log(\"\");\n log(bold(` Product${orange(\"Brain\")} Setup`));\n log(dim(\" Connect your AI assistant to your chain\\n\"));\n\n const keysUrl = apiKeysUrl();\n\n log(` ${dim(\"1. Get your API key from Settings → API Keys\")}`);\n log(` ${dim(keysUrl)}\\n`);\n\n const openNow = await prompt(` Open this URL in your browser? [Y/n]: `);\n if (openNow.toLowerCase() !== \"n\" && openNow.toLowerCase() !== \"no\") {\n openBrowser(keysUrl);\n }\n\n log(\"\");\n log(` ${dim(\"2. Generate a key (if you don't have one), then copy it.\\n\")}`);\n\n const apiKey = await prompt(` Paste your API key (pb_sk_...): `);\n\n if (!apiKey || !apiKey.startsWith(\"pb_sk_\")) {\n log(` ${orange(\"!\")} Invalid key format. Keys start with pb_sk_.`);\n log(` Get one at ${keysUrl}\\n`);\n await shutdownAnalytics();\n process.exit(1);\n }\n\n log(` ${green(\"✓\")} Key received`);\n\n const workspace = await verifyWorkspace(apiKey);\n if (workspace) {\n log(` ${green(\"✓\")} Connected to workspace: ${bold(workspace.name)} ${dim(`(${workspace.slug})`)}`);\n } else {\n log(` ${orange(\"!\")} Could not verify workspace. Check your key at ${keysUrl}`);\n }\n log(\"\");\n\n const CLIENT_NAMES = [\"Cursor\", \"Claude Desktop\"] as const;\n const options = [...CLIENT_NAMES, \"Other\"];\n\n const choice = await promptChoice(\"Where do you want to set up Product Brain?\", options);\n\n if (choice === 2) {\n printConfigSnippet(apiKey);\n trackSetupCompleted(\"Other\", \"snippet_shown\");\n } else {\n const client = resolveClient(CLIENT_NAMES[choice]);\n if (client) {\n const outcome = await writeConfig(client, apiKey);\n trackSetupCompleted(CLIENT_NAMES[choice], outcome);\n } else {\n log(` ${orange(\"!\")} ${CLIENT_NAMES[choice]} config path not available on this platform.`);\n printConfigSnippet(apiKey);\n trackSetupCompleted(CLIENT_NAMES[choice], \"write_error\");\n }\n }\n\n // Cursor-specific: offer to install rule (additive-only)\n if (choice === 0) {\n await offerCursorRulesInstall();\n printDeeplink(apiKey);\n }\n\n // Claude-specific: print snippet (never write to CLAUDE.md)\n if (choice === 1) {\n printClaudeSnippet();\n }\n\n log(\"\");\n log(\n ` ${green(\"✓\")} Done! Restart your AI assistant and try: ${bold('\"Start PB\"')}`,\n );\n printHelpLink();\n await shutdownAnalytics();\n}\n\nasync function writeConfig(\n client: McpClientInfo,\n apiKey: string,\n): Promise<\"config_written\" | \"config_existed\" | \"write_error\"> {\n try {\n const wrote = await writeClientConfig(client, apiKey);\n if (wrote) {\n log(` ${green(\"✓\")} Wrote config to ${dim(client.configPath)}`);\n return \"config_written\";\n } else {\n log(` ${dim(\"ℹ\")} ${client.name} already configured — skipped`);\n return \"config_existed\";\n }\n } catch (err: any) {\n log(` ${orange(\"!\")} Could not write ${client.name} config: ${err.message}`);\n printConfigSnippet(apiKey);\n return \"write_error\";\n }\n}\n\nfunction printHelpLink() {\n log(` ${dim(`Need help? See ${apiKeysUrl()}`)}`);\n log(\"\");\n}\n\nfunction printConfigSnippet(apiKey: string) {\n log(\"\");\n log(bold(\" Add this to your MCP client config:\\n\"));\n const snippet = JSON.stringify(\n {\n mcpServers: {\n \"Product Brain\": {\n command: \"npx\",\n args: [\"-y\", MCP_NPX_PACKAGE],\n env: { PRODUCTBRAIN_API_KEY: apiKey },\n },\n },\n },\n null,\n 2,\n );\n for (const line of snippet.split(\"\\n\")) {\n log(` ${line}`);\n }\n log(\"\");\n}\n\n// ── Cursor Rules/Skills Install (additive-only) ─────────────────────────\n\nconst CURSOR_RULE_FILENAME = \"product-brain.mdc\";\n\nconst CURSOR_RULE_CONTENT = `---\ndescription: Product Brain MCP — single source of truth for product knowledge\nglobs:\nalwaysApply: true\n---\n\n# Product Brain MCP\n\nProduct Brain is your product knowledge base. The Chain is the single source of truth.\n\nEvery entry is either a **draft** (captured but not accepted) or **accepted** (on the Chain, SSOT).\nAccepting onto the Chain is the compounding act.\n\n## Quick Start\n\nSay **\"Start PB\"** or **\"Start Product Brain\"** to begin. This single call:\n- Orients you to the workspace (readiness, gaps, planned work)\n- Surfaces your next recommended action\n\n## Tool Workflow\n\n1. **Start here**: \\`orient action=start\\` — workspace context + next action\n2. **Search**: \\`entries action=search\\` — find entries across all collections\n3. **Drill in**: \\`entries action=get\\` — full record with data, labels, relations\n4. **Context**: \\`context action=gather\\` — related knowledge around an entry or task\n5. **Capture**: \\`capture\\` — create knowledge (pass \\`links\\` to relate it; nothing is linked automatically) + quality verdict\n6. **Accept**: \\`entries action=commit\\` — promote drafts to SSOT when confirmation is still required\n7. **Connect**: \\`relations action=create\\` to link the entries you know are related\n\n## Bulk Knowledge Input\n\nWhen given a document or batch of knowledge to capture:\n1. Scan the input — identify all collections needed\n2. Call \\`collections action=list\\` — compare against what exists\n3. Propose missing collections to the user for confirmation\n4. Ask a platform admin to provision each confirmed collection (creating one is no longer\n self-serve — ask an admin, or enable the module ontology pack that owns the drawer)\n5. Then capture entries into the correct collections\n\nNever stuff entries into the wrong collection. Never silently skip knowledge.\n\n## Rules\n\n- In Open mode, user-authored captures can be accepted immediately unless the user asks to keep them as drafts.\n- In consensus/role modes, only call \\`entries action=commit\\` when the user confirms.\n- After capturing, link related entries with \\`relations action=create\\`.\n- Collections are dynamic, but creating a new one is not self-serve — ask a platform admin to\n provision it, or enable the module ontology pack that owns the drawer.\n- When lost, fetch \\`productbrain://orientation\\` for the full system map.\n`;\n\nfunction isCursorProject(): boolean {\n return existsSync(join(process.cwd(), \".cursor\")) || existsSync(join(process.cwd(), \".cursorignore\"));\n}\n\nasync function offerCursorRulesInstall(): Promise<void> {\n if (!isCursorProject()) return;\n\n const answer = await prompt(`\\n Install Product Brain rule for Cursor? [Y/n]: `);\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n log(dim(\" Skipped rule install.\"));\n return;\n }\n\n const rulesDir = join(process.cwd(), \".cursor\", \"rules\");\n const rulePath = join(rulesDir, CURSOR_RULE_FILENAME);\n\n if (existsSync(rulePath)) {\n log(` ${dim(\"ℹ\")} Rule already exists at ${dim(rulePath)} — skipped`);\n return;\n }\n\n if (!existsSync(rulesDir)) {\n mkdirSync(rulesDir, { recursive: true });\n }\n\n writeFileSync(rulePath, CURSOR_RULE_CONTENT, \"utf-8\");\n log(` ${green(\"✓\")} Installed rule at ${dim(rulePath)}`);\n}\n\nfunction buildDeeplink(apiKey: string): string {\n const config = JSON.stringify({\n command: \"npx\",\n args: [\"-y\", MCP_NPX_PACKAGE],\n env: { PRODUCTBRAIN_API_KEY: apiKey },\n });\n const encoded = Buffer.from(config).toString(\"base64url\");\n return `cursor://anysphere.cursor-deeplink/mcp/install?name=${encodeURIComponent(\"Product Brain\")}&config=${encoded}`;\n}\n\nfunction printDeeplink(apiKey: string): void {\n const link = buildDeeplink(apiKey);\n log(\"\");\n log(` ${dim(\"One-click install for Cursor (paste in browser):\")}`);\n log(` ${link}`);\n}\n\nfunction printClaudeSnippet(): void {\n log(\"\");\n log(bold(\" For Claude Code / CLAUDE.md:\"));\n log(dim(\" Add this line to your ~/.claude/CLAUDE.md:\"));\n log(\"\");\n log(` When Product Brain MCP is available, say \"Start PB\" at the beginning`);\n log(` of each session to orient to the workspace; workflow checkpoints and organisation-structure writes require it.`);\n log(` In Open mode, user-authored captures can be accepted immediately unless the user asks to keep drafts.`);\n log(` In consensus/role modes, only accept when the user confirms.`);\n log(\"\");\n}\n"],"mappings":"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","names":[]}
|