@andespindola/brainlink 1.6.14 → 1.7.0
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/CHANGELOG.md +8 -0
- package/dist/application/frontend/auth-styles.js +180 -0
- package/dist/application/frontend/client/account-menu.js +21 -16
- package/dist/application/frontend/client/graph-renderer.js +20 -17
- package/dist/application/frontend/client/rendering.js +5 -5
- package/dist/application/frontend/client/scope-theme.js +23 -18
- package/dist/application/frontend/client-css.js +56 -36
- package/dist/application/frontend/login-page.js +9 -163
- package/dist/application/frontend/neon-theme.js +110 -0
- package/dist/application/frontend/settings-page.js +76 -52
- package/dist/application/get-image.js +63 -0
- package/dist/mcp/oauth-authorize-page.js +11 -130
- package/dist/mcp/server.js +6 -1
- package/dist/mcp/tools/read-tools.js +26 -0
- package/dist/mcp/tools.js +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// Self-contained branded OAuth authorization/consent page for the Brainlink MCP
|
|
2
|
-
// server. Served as a plain string (inline <style>, no external assets
|
|
3
|
-
// framework, no JavaScript) so it works
|
|
4
|
-
// The visual identity
|
|
5
|
-
//
|
|
6
|
-
//
|
|
2
|
+
// server. Served as a plain string (inline <style>, no external assets beyond
|
|
3
|
+
// the shared Google Fonts @import, no framework, no JavaScript) so it works
|
|
4
|
+
// identically for a global npm install. The visual identity is the unified neon
|
|
5
|
+
// system shared with the SaaS app and the graph client (see neon-theme.ts /
|
|
6
|
+
// auth-styles.ts): #0a0e1a base, faint cyber grid, cyan #22d3ee + violet
|
|
7
|
+
// #8b5cf6, Space Grotesk headings / DM Sans body, glass card + gradient
|
|
8
|
+
// wordmark, so the SSO consent step reads as part of one product.
|
|
9
|
+
import { authSharedStyles } from '../application/frontend/auth-styles.js';
|
|
7
10
|
// HTML-escape dynamic values. clientName arrives from an untrusted OAuth client
|
|
8
11
|
// and hidden values carry OAuth params, so both must never allow HTML injection.
|
|
9
12
|
const escapeHtml = (value) => value
|
|
@@ -12,85 +15,14 @@ const escapeHtml = (value) => value
|
|
|
12
15
|
.replace(/>/g, '>')
|
|
13
16
|
.replace(/"/g, '"')
|
|
14
17
|
.replace(/'/g, ''');
|
|
15
|
-
const authorizeStyles = () =>
|
|
16
|
-
color-scheme: dark;
|
|
17
|
-
--bg: #08131d;
|
|
18
|
-
--panel: #0d1823;
|
|
19
|
-
--panel-strong: #112130;
|
|
20
|
-
--line: rgba(143, 172, 204, 0.18);
|
|
21
|
-
--text: #edf4ff;
|
|
22
|
-
--muted: #97a9bd;
|
|
23
|
-
--accent: #5aa8ff;
|
|
24
|
-
--accent-weak: rgba(90, 168, 255, 0.18);
|
|
25
|
-
--danger: #ff6b6b;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
* {
|
|
29
|
-
box-sizing: border-box;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
html,
|
|
33
|
-
body {
|
|
34
|
-
width: 100%;
|
|
35
|
-
min-height: 100%;
|
|
36
|
-
margin: 0;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
body {
|
|
40
|
-
display: flex;
|
|
41
|
-
align-items: center;
|
|
42
|
-
justify-content: center;
|
|
43
|
-
min-height: 100vh;
|
|
44
|
-
min-height: 100dvh;
|
|
45
|
-
padding: 24px;
|
|
46
|
-
color: var(--text);
|
|
47
|
-
font-family: "Crowquill Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
|
48
|
-
background:
|
|
49
|
-
linear-gradient(rgba(164, 197, 230, 0.05) 1px, transparent 1px),
|
|
50
|
-
linear-gradient(90deg, rgba(164, 197, 230, 0.05) 1px, transparent 1px),
|
|
51
|
-
radial-gradient(circle at top, rgba(43, 93, 143, 0.22), transparent 44%),
|
|
52
|
-
#08131d;
|
|
53
|
-
background-size: 28px 28px, 28px 28px, auto;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
button,
|
|
57
|
-
input {
|
|
58
|
-
font: inherit;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.auth-card {
|
|
62
|
-
width: 100%;
|
|
63
|
-
max-width: 400px;
|
|
64
|
-
padding: 32px 28px;
|
|
65
|
-
border: 1px solid var(--line);
|
|
66
|
-
border-radius: 14px;
|
|
67
|
-
background: rgba(13, 24, 35, 0.92);
|
|
68
|
-
box-shadow: 0 24px 80px rgba(1, 6, 13, 0.48);
|
|
69
|
-
backdrop-filter: blur(8px);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.auth-brand {
|
|
73
|
-
display: grid;
|
|
74
|
-
gap: 4px;
|
|
75
|
-
margin-bottom: 20px;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.auth-brand strong {
|
|
79
|
-
font-size: 26px;
|
|
80
|
-
letter-spacing: 0.01em;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.auth-brand span {
|
|
84
|
-
color: var(--muted);
|
|
85
|
-
font-size: 13px;
|
|
86
|
-
}
|
|
18
|
+
const authorizeStyles = () => `${authSharedStyles(400)}
|
|
87
19
|
|
|
88
20
|
.auth-consent {
|
|
89
21
|
margin: 0 0 20px;
|
|
90
22
|
padding: 12px 14px;
|
|
91
23
|
border: 1px solid var(--line);
|
|
92
|
-
border-radius:
|
|
93
|
-
background: rgba(
|
|
24
|
+
border-radius: 12px;
|
|
25
|
+
background: rgba(19, 26, 42, 0.55);
|
|
94
26
|
color: var(--text);
|
|
95
27
|
font-size: 13px;
|
|
96
28
|
line-height: 1.5;
|
|
@@ -101,58 +33,7 @@ input {
|
|
|
101
33
|
color: var(--accent);
|
|
102
34
|
}
|
|
103
35
|
|
|
104
|
-
.auth-form {
|
|
105
|
-
display: grid;
|
|
106
|
-
gap: 16px;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
.auth-field {
|
|
110
|
-
display: grid;
|
|
111
|
-
gap: 7px;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.auth-field label {
|
|
115
|
-
color: var(--muted);
|
|
116
|
-
font-size: 12px;
|
|
117
|
-
letter-spacing: 0.02em;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.auth-field input {
|
|
121
|
-
width: 100%;
|
|
122
|
-
height: 42px;
|
|
123
|
-
padding: 0 14px;
|
|
124
|
-
border: 1px solid var(--line);
|
|
125
|
-
border-radius: 8px;
|
|
126
|
-
outline: none;
|
|
127
|
-
background: rgba(12, 24, 36, 0.94);
|
|
128
|
-
color: var(--text);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
.auth-field input:focus {
|
|
132
|
-
border-color: var(--accent);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
.auth-submit {
|
|
136
|
-
height: 44px;
|
|
137
|
-
margin-top: 4px;
|
|
138
|
-
border: 1px solid var(--accent);
|
|
139
|
-
border-radius: 8px;
|
|
140
|
-
background: var(--accent-weak);
|
|
141
|
-
color: var(--text);
|
|
142
|
-
cursor: pointer;
|
|
143
|
-
transition: background 120ms ease, opacity 120ms ease;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.auth-submit:hover,
|
|
147
|
-
.auth-submit:focus {
|
|
148
|
-
background: rgba(90, 168, 255, 0.3);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
36
|
.auth-message {
|
|
152
|
-
margin: 0;
|
|
153
|
-
font-size: 12px;
|
|
154
|
-
line-height: 1.4;
|
|
155
|
-
overflow-wrap: anywhere;
|
|
156
37
|
color: var(--danger);
|
|
157
38
|
}`;
|
|
158
39
|
const consentLine = (clientName) => {
|
package/dist/mcp/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { addNoteInputSchema, addFileInputSchema, addFileTool, addImageInputSchema, addImageTool, addNoteTool, addNotesInputSchema, addNotesTool, deleteNoteInputSchema, deleteNoteTool, deleteNotesInputSchema, deleteNotesTool, volatileAddInputSchema, volatileAddTool, volatileClearInputSchema, volatileClearTool, dedupeInputSchema, dedupeResolveInputSchema, dedupeResolveTool, dedupeTool, brokenLinksInputSchema, brokenLinksTool, bootstrapInputSchema, bootstrapTool, canonicalizeContextLinksInputSchema, canonicalizeContextLinksTool, contextInputSchema, contextPacksInputSchema, contextPacksTool, contextTool, doctorActionsInputSchema, doctorActionsTool, graphContextsInputSchema, graphContextsTool, graphInputSchema, graphTool, explainInputSchema, explainTool, indexInputSchema, indexTool, inboxAddInputSchema, inboxAddTool, inboxListInputSchema, inboxListTool, inboxProcessInputSchema, inboxProcessTool, orphansInputSchema, orphansTool, policyInputSchema, policyTool, projectInitInputSchema, projectInitTool, recommendationsInputSchema, recommendationsTool, rememberInputSchema, rememberTool, repairLinksInputSchema, repairLinksTool, searchInputSchema, searchTool, similarNotesInputSchema, similarNotesTool, sessionCloseInputSchema, sessionCloseTool, statsInputSchema, statsTool, suggestLinksInputSchema, suggestLinksTool, syncInputSchema, syncTool, validateInputSchema, validateTool, vaultBundleListInputSchema, vaultBundleListTool, vaultCommitInputSchema, vaultCommitTool, vaultExportBundleInputSchema, vaultExportBundleTool, vaultExportInputSchema, vaultExportTool, vaultHistoryInputSchema, vaultHistoryTool, vaultImportBundleInputSchema, vaultImportBundleTool, vaultImportInputSchema, vaultImportTool, vaultInitInputSchema, vaultInitTool, vaultMergeAgentsInputSchema, vaultMergeAgentsTool, vaultProvisionInputSchema, vaultProvisionTool, vaultPullInputSchema, vaultPullTool, vaultRestoreInputSchema, vaultRestoreTool, vaultStatusInputSchema, vaultStatusTool, versionInputSchema, versionTool } from './tools.js';
|
|
2
|
+
import { addNoteInputSchema, addFileInputSchema, addFileTool, addImageInputSchema, addImageTool, addNoteTool, addNotesInputSchema, addNotesTool, deleteNoteInputSchema, deleteNoteTool, deleteNotesInputSchema, deleteNotesTool, volatileAddInputSchema, volatileAddTool, volatileClearInputSchema, volatileClearTool, dedupeInputSchema, dedupeResolveInputSchema, dedupeResolveTool, dedupeTool, brokenLinksInputSchema, brokenLinksTool, bootstrapInputSchema, bootstrapTool, canonicalizeContextLinksInputSchema, canonicalizeContextLinksTool, contextInputSchema, contextPacksInputSchema, contextPacksTool, contextTool, doctorActionsInputSchema, doctorActionsTool, graphContextsInputSchema, graphContextsTool, graphInputSchema, graphTool, getImageInputSchema, getImageTool, explainInputSchema, explainTool, indexInputSchema, indexTool, inboxAddInputSchema, inboxAddTool, inboxListInputSchema, inboxListTool, inboxProcessInputSchema, inboxProcessTool, orphansInputSchema, orphansTool, policyInputSchema, policyTool, projectInitInputSchema, projectInitTool, recommendationsInputSchema, recommendationsTool, rememberInputSchema, rememberTool, repairLinksInputSchema, repairLinksTool, searchInputSchema, searchTool, similarNotesInputSchema, similarNotesTool, sessionCloseInputSchema, sessionCloseTool, statsInputSchema, statsTool, suggestLinksInputSchema, suggestLinksTool, syncInputSchema, syncTool, validateInputSchema, validateTool, vaultBundleListInputSchema, vaultBundleListTool, vaultCommitInputSchema, vaultCommitTool, vaultExportBundleInputSchema, vaultExportBundleTool, vaultExportInputSchema, vaultExportTool, vaultHistoryInputSchema, vaultHistoryTool, vaultImportBundleInputSchema, vaultImportBundleTool, vaultImportInputSchema, vaultImportTool, vaultInitInputSchema, vaultInitTool, vaultMergeAgentsInputSchema, vaultMergeAgentsTool, vaultProvisionInputSchema, vaultProvisionTool, vaultPullInputSchema, vaultPullTool, vaultRestoreInputSchema, vaultRestoreTool, vaultStatusInputSchema, vaultStatusTool, versionInputSchema, versionTool } from './tools.js';
|
|
3
3
|
import { getRuntimeVersion } from './runtime.js';
|
|
4
4
|
import { brainlinkServerInstructions } from './server-instructions.js';
|
|
5
5
|
import { guardToolHandler } from './tool-guard.js';
|
|
@@ -131,6 +131,11 @@ export const createBrainlinkMcpServer = () => {
|
|
|
131
131
|
description: 'Store an image in the vault (encrypted at rest when vault encryption is on) and address it by a stable vault-relative path. Provide imageBase64 or filePath. Optionally pass noteTitle to create a note that embeds the image so retrieval can surface it in context. Alt text is included in the returned context descriptor.',
|
|
132
132
|
inputSchema: addImageInputSchema
|
|
133
133
|
}, addImageTool);
|
|
134
|
+
server.registerTool('brainlink_get_image', {
|
|
135
|
+
title: 'Get Brainlink Image',
|
|
136
|
+
description: 'Retrieve the raw bytes of an image stored in the vault by a stable vault-relative asset path (as returned by brainlink_add_image). Returns the descriptor plus base64-encoded bytes so a second agent can fetch and use an image another agent added to the shared vault. Decrypts transparently when the vault stores images encrypted at rest; the path must resolve inside .brainlink/assets.',
|
|
137
|
+
inputSchema: getImageInputSchema
|
|
138
|
+
}, getImageTool);
|
|
134
139
|
server.registerTool('brainlink_canonicalize_context_links', {
|
|
135
140
|
title: 'Canonicalize Brainlink Context Links',
|
|
136
141
|
description: 'Ensure notes have canonical Context Links to inferred context hubs. Supports dry-run and can create missing hub notes.',
|
|
@@ -3,6 +3,7 @@ import { getBrokenLinksReport, getOrphansReport, getStats, validateVault } from
|
|
|
3
3
|
import { buildContextPackage, readContextDataSignature, readVolatileSignature } from '../../application/build-context.js';
|
|
4
4
|
import { getGraph } from '../../application/get-graph.js';
|
|
5
5
|
import { getGraphContexts } from '../../application/get-graph-contexts.js';
|
|
6
|
+
import { getImage } from '../../application/get-image.js';
|
|
6
7
|
import { explainSearchResults, suggestBrokenLinkFixes, suggestContextLinks } from '../../application/memory-suggestions.js';
|
|
7
8
|
import { buildActionableDoctor } from '../../application/operational-workflows.js';
|
|
8
9
|
import { searchKnowledge } from '../../application/search-knowledge.js';
|
|
@@ -539,3 +540,28 @@ export const recommendationsTool = async (input) => {
|
|
|
539
540
|
recommendations
|
|
540
541
|
});
|
|
541
542
|
};
|
|
543
|
+
export const getImageInputSchema = {
|
|
544
|
+
...vaultInput,
|
|
545
|
+
...agentInput,
|
|
546
|
+
path: z
|
|
547
|
+
.string()
|
|
548
|
+
.min(1)
|
|
549
|
+
.describe('Vault-relative asset path to fetch, as returned by brainlink_add_image (e.g. ".brainlink/assets/shared/<sha>.png"). Must resolve inside the vault .brainlink/assets tree.'),
|
|
550
|
+
alt: z.string().min(1).optional().describe('Optional alt text / description to echo back in the descriptor.')
|
|
551
|
+
};
|
|
552
|
+
// Fetch the raw bytes of a stored image so another agent can retrieve and use an
|
|
553
|
+
// image a first agent added to the shared vault. Decrypts transparently when the
|
|
554
|
+
// bytes are stored encrypted-at-rest, and rejects paths outside .brainlink/assets.
|
|
555
|
+
export const getImageTool = async (input) => {
|
|
556
|
+
const context = await resolveExecutionContext(input);
|
|
557
|
+
const image = await getImage({
|
|
558
|
+
vaultPath: context.vault,
|
|
559
|
+
path: input.path,
|
|
560
|
+
alt: input.alt
|
|
561
|
+
});
|
|
562
|
+
return jsonResult({
|
|
563
|
+
vault: context.vault,
|
|
564
|
+
agent: context.agent,
|
|
565
|
+
image
|
|
566
|
+
});
|
|
567
|
+
};
|
package/dist/mcp/tools.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { brokenLinksInputSchema, brokenLinksTool, contextInputSchema, contextPacksInputSchema, contextPacksTool, contextTool, doctorActionsInputSchema, doctorActionsTool, explainInputSchema, explainTool, graphContextsInputSchema, graphContextsTool, graphInputSchema, graphTool, orphansInputSchema, orphansTool, recommendationsInputSchema, recommendationsTool, searchInputSchema, searchTool, similarNotesInputSchema, similarNotesTool, statsInputSchema, statsTool, suggestLinksInputSchema, suggestLinksTool, validateInputSchema, validateTool, versionInputSchema, versionTool } from './tools/read-tools.js';
|
|
1
|
+
export { brokenLinksInputSchema, brokenLinksTool, contextInputSchema, contextPacksInputSchema, contextPacksTool, contextTool, doctorActionsInputSchema, doctorActionsTool, explainInputSchema, explainTool, graphContextsInputSchema, graphContextsTool, graphInputSchema, graphTool, getImageInputSchema, getImageTool, orphansInputSchema, orphansTool, recommendationsInputSchema, recommendationsTool, searchInputSchema, searchTool, similarNotesInputSchema, similarNotesTool, statsInputSchema, statsTool, suggestLinksInputSchema, suggestLinksTool, validateInputSchema, validateTool, versionInputSchema, versionTool } from './tools/read-tools.js';
|
|
2
2
|
export { addFileInputSchema, addFileTool, addImageInputSchema, addImageTool, addNoteInputSchema, addNoteTool, addNotesInputSchema, addNotesTool, deleteNoteInputSchema, deleteNoteTool, deleteNotesInputSchema, deleteNotesTool, inboxAddInputSchema, inboxAddTool, inboxListInputSchema, inboxListTool, inboxProcessInputSchema, inboxProcessTool, rememberInputSchema, rememberTool, volatileAddInputSchema, volatileAddTool, volatileClearInputSchema, volatileClearTool } from './tools/write-tools.js';
|
|
3
3
|
export { bootstrapInputSchema, bootstrapTool, canonicalizeContextLinksInputSchema, canonicalizeContextLinksTool, dedupeInputSchema, dedupeResolveInputSchema, dedupeResolveTool, dedupeTool, indexInputSchema, indexTool, policyInputSchema, policyTool, projectInitInputSchema, projectInitTool, repairLinksInputSchema, repairLinksTool, sessionCloseInputSchema, sessionCloseTool, syncInputSchema, syncTool } from './tools/maintenance-tools.js';
|
|
4
4
|
export { vaultBundleListInputSchema, vaultBundleListTool, vaultCommitInputSchema, vaultCommitTool, vaultExportBundleInputSchema, vaultExportBundleTool, vaultExportInputSchema, vaultExportTool, vaultHistoryInputSchema, vaultHistoryTool, vaultImportBundleInputSchema, vaultImportBundleTool, vaultImportInputSchema, vaultImportTool, vaultInitInputSchema, vaultInitTool, vaultMergeAgentsInputSchema, vaultMergeAgentsTool, vaultProvisionInputSchema, vaultProvisionTool, vaultPullInputSchema, vaultPullTool, vaultRestoreInputSchema, vaultRestoreTool, vaultStatusInputSchema, vaultStatusTool } from './tools/vault-tools.js';
|
package/package.json
CHANGED