@andespindola/brainlink 0.1.0-beta.7 → 0.1.0-beta.71
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/AGENTS.md +8 -5
- package/CHANGELOG.md +58 -2
- package/CONTRIBUTING.md +2 -2
- package/COPYRIGHT.md +5 -0
- package/README.md +266 -20
- package/SECURITY.md +1 -1
- package/dist/application/add-note.js +62 -13
- package/dist/application/analyze-vault.js +95 -8
- package/dist/application/build-context.js +56 -1
- package/dist/application/dedupe-notes.js +226 -0
- package/dist/application/frontend/client-css.js +138 -103
- package/dist/application/frontend/client-html.js +47 -41
- package/dist/application/frontend/client-js.js +2120 -128
- package/dist/application/frontend/client-worker-js.js +66 -0
- package/dist/application/get-graph-layout.js +18 -6
- package/dist/application/get-graph-node.js +12 -0
- package/dist/application/get-graph-summary.js +12 -0
- package/dist/application/get-graph.js +3 -3
- package/dist/application/import-legacy-sqlite.js +296 -0
- package/dist/application/index-vault.js +252 -19
- package/dist/application/list-agents.js +3 -3
- package/dist/application/list-links.js +5 -5
- package/dist/application/migrate-vault.js +91 -0
- package/dist/application/offline-pack-backup.js +44 -0
- package/dist/application/search-graph-node-ids.js +12 -0
- package/dist/application/search-knowledge.js +75 -5
- package/dist/application/server/routes.js +102 -1
- package/dist/application/start-server.js +75 -4
- package/dist/application/watch-vault.js +23 -2
- package/dist/benchmarks/large-vault.js +1 -1
- package/dist/cli/commands/agent-commands.js +419 -0
- package/dist/cli/commands/config-commands.js +167 -0
- package/dist/cli/commands/read-commands.js +25 -8
- package/dist/cli/commands/write-commands.js +989 -10
- package/dist/cli/main.js +4 -0
- package/dist/cli/runtime.js +5 -2
- package/dist/domain/context.js +53 -11
- package/dist/domain/embeddings.js +2 -1
- package/dist/domain/graph-layout.js +62 -15
- package/dist/domain/markdown.js +36 -4
- package/dist/domain/middle-out.js +18 -0
- package/dist/infrastructure/config.js +132 -8
- package/dist/infrastructure/file-index.js +358 -0
- package/dist/infrastructure/file-system-vault.js +30 -0
- package/dist/infrastructure/index-state.js +56 -0
- package/dist/infrastructure/paths.js +9 -1
- package/dist/infrastructure/private-pack-codec.js +134 -0
- package/dist/infrastructure/search-packs.js +452 -0
- package/dist/infrastructure/session-state.js +172 -0
- package/dist/mcp/main.js +11 -3
- package/dist/mcp/server.js +27 -2
- package/dist/mcp/startup.js +35 -0
- package/dist/mcp/tools.js +633 -19
- package/docs/AGENT_USAGE.md +178 -16
- package/docs/ARCHITECTURE.md +37 -26
- package/docs/QUICKSTART.md +111 -0
- package/package.json +6 -4
- package/dist/infrastructure/sqlite/document-writer.js +0 -51
- package/dist/infrastructure/sqlite/graph-reader.js +0 -120
- package/dist/infrastructure/sqlite/schema.js +0 -111
- package/dist/infrastructure/sqlite/search-reader.js +0 -156
- package/dist/infrastructure/sqlite/types.js +0 -1
- package/dist/infrastructure/sqlite-index.js +0 -25
|
@@ -25,6 +25,13 @@ body {
|
|
|
25
25
|
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
body {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
min-height: 100vh;
|
|
32
|
+
min-height: 100dvh;
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
button,
|
|
29
36
|
input,
|
|
30
37
|
select {
|
|
@@ -32,19 +39,44 @@ select {
|
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
.shell {
|
|
35
|
-
|
|
36
|
-
grid-template-columns: minmax(0, 1fr) 360px;
|
|
42
|
+
flex: 1 1 auto;
|
|
37
43
|
width: 100%;
|
|
38
|
-
height:
|
|
44
|
+
min-height: 0;
|
|
39
45
|
overflow: hidden;
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
.workspace {
|
|
49
|
+
display: grid;
|
|
50
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
43
51
|
position: relative;
|
|
52
|
+
width: 100%;
|
|
53
|
+
height: 100%;
|
|
44
54
|
min-width: 0;
|
|
45
55
|
min-height: 0;
|
|
46
56
|
}
|
|
47
57
|
|
|
58
|
+
.graph-header {
|
|
59
|
+
z-index: 5;
|
|
60
|
+
display: flex;
|
|
61
|
+
align-items: center;
|
|
62
|
+
gap: 12px;
|
|
63
|
+
min-height: 72px;
|
|
64
|
+
padding: 10px 16px;
|
|
65
|
+
border-bottom: 1px solid var(--line);
|
|
66
|
+
background: linear-gradient(180deg, rgba(17, 21, 27, 0.96) 0%, rgba(17, 21, 27, 0.86) 100%);
|
|
67
|
+
backdrop-filter: blur(8px);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.brand-block {
|
|
71
|
+
display: grid;
|
|
72
|
+
gap: 2px;
|
|
73
|
+
min-width: max-content;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.brand-block strong {
|
|
77
|
+
font-size: 18px;
|
|
78
|
+
}
|
|
79
|
+
|
|
48
80
|
#graph {
|
|
49
81
|
display: block;
|
|
50
82
|
width: 100%;
|
|
@@ -59,43 +91,25 @@ select {
|
|
|
59
91
|
cursor: grabbing;
|
|
60
92
|
}
|
|
61
93
|
|
|
62
|
-
.
|
|
63
|
-
position: absolute;
|
|
64
|
-
top: 18px;
|
|
65
|
-
left: 18px;
|
|
66
|
-
right: 18px;
|
|
67
|
-
display: flex;
|
|
68
|
-
align-items: center;
|
|
69
|
-
justify-content: space-between;
|
|
70
|
-
gap: 18px;
|
|
71
|
-
pointer-events: none;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.topbar > div {
|
|
75
|
-
display: flex;
|
|
76
|
-
align-items: baseline;
|
|
77
|
-
gap: 12px;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.topbar strong {
|
|
81
|
-
font-size: 18px;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.topbar span,
|
|
85
|
-
.eyebrow,
|
|
86
|
-
.inspector small {
|
|
94
|
+
.eyebrow {
|
|
87
95
|
color: var(--muted);
|
|
88
96
|
font-size: 12px;
|
|
89
97
|
}
|
|
90
98
|
|
|
91
99
|
.search {
|
|
92
|
-
|
|
93
|
-
|
|
100
|
+
flex: 1 1 320px;
|
|
101
|
+
min-width: 220px;
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
.agent-filter {
|
|
97
105
|
width: min(220px, 28vw);
|
|
98
|
-
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.header-actions {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
gap: 10px;
|
|
112
|
+
margin-left: auto;
|
|
99
113
|
}
|
|
100
114
|
|
|
101
115
|
.search input,
|
|
@@ -116,9 +130,6 @@ select {
|
|
|
116
130
|
}
|
|
117
131
|
|
|
118
132
|
.toolbar {
|
|
119
|
-
position: absolute;
|
|
120
|
-
left: 18px;
|
|
121
|
-
bottom: 18px;
|
|
122
133
|
display: flex;
|
|
123
134
|
gap: 8px;
|
|
124
135
|
}
|
|
@@ -138,70 +149,34 @@ select {
|
|
|
138
149
|
color: var(--accent);
|
|
139
150
|
}
|
|
140
151
|
|
|
141
|
-
.
|
|
142
|
-
display:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
min-width: 0;
|
|
146
|
-
height: 100%;
|
|
147
|
-
padding: 24px;
|
|
148
|
-
border-left: 1px solid var(--line);
|
|
149
|
-
background: var(--panel);
|
|
150
|
-
overflow: auto;
|
|
152
|
+
.floating-metrics {
|
|
153
|
+
display: flex;
|
|
154
|
+
gap: 10px;
|
|
155
|
+
flex-wrap: wrap;
|
|
151
156
|
}
|
|
152
157
|
|
|
153
|
-
.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
158
|
+
.metric-chip {
|
|
159
|
+
min-width: 94px;
|
|
160
|
+
padding: 10px 12px;
|
|
161
|
+
border: 1px solid var(--line);
|
|
162
|
+
border-radius: 10px;
|
|
163
|
+
background: rgba(21, 25, 31, 0.88);
|
|
164
|
+
display: grid;
|
|
165
|
+
gap: 3px;
|
|
157
166
|
}
|
|
158
167
|
|
|
159
|
-
.
|
|
160
|
-
margin-top: 6px;
|
|
168
|
+
.metric-chip strong {
|
|
161
169
|
font-size: 26px;
|
|
162
|
-
line-height: 1
|
|
163
|
-
overflow-wrap: anywhere;
|
|
170
|
+
line-height: 1;
|
|
164
171
|
}
|
|
165
172
|
|
|
166
|
-
.
|
|
167
|
-
margin-bottom: 10px;
|
|
173
|
+
.metric-chip small {
|
|
168
174
|
color: var(--muted);
|
|
169
|
-
font-size:
|
|
170
|
-
|
|
175
|
+
font-size: 11px;
|
|
176
|
+
letter-spacing: 0.03em;
|
|
171
177
|
text-transform: uppercase;
|
|
172
178
|
}
|
|
173
179
|
|
|
174
|
-
#path {
|
|
175
|
-
margin-top: 10px;
|
|
176
|
-
color: var(--muted);
|
|
177
|
-
line-height: 1.45;
|
|
178
|
-
overflow-wrap: anywhere;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
.metrics {
|
|
182
|
-
display: grid;
|
|
183
|
-
grid-template-columns: repeat(3, 1fr);
|
|
184
|
-
border: 1px solid var(--line);
|
|
185
|
-
border-radius: 8px;
|
|
186
|
-
overflow: hidden;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
.metrics div {
|
|
190
|
-
display: grid;
|
|
191
|
-
gap: 4px;
|
|
192
|
-
padding: 14px;
|
|
193
|
-
background: var(--panel-strong);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
.metrics div + div {
|
|
197
|
-
border-left: 1px solid var(--line);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
.metrics span {
|
|
201
|
-
font-size: 22px;
|
|
202
|
-
font-weight: 700;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
180
|
.tags {
|
|
206
181
|
display: flex;
|
|
207
182
|
flex-wrap: wrap;
|
|
@@ -215,6 +190,7 @@ select {
|
|
|
215
190
|
background: var(--accent-weak);
|
|
216
191
|
color: var(--accent);
|
|
217
192
|
font-size: 12px;
|
|
193
|
+
word-break: break-word;
|
|
218
194
|
overflow-wrap: anywhere;
|
|
219
195
|
}
|
|
220
196
|
|
|
@@ -230,6 +206,7 @@ li {
|
|
|
230
206
|
padding: 10px 0;
|
|
231
207
|
border-bottom: 1px solid var(--line);
|
|
232
208
|
color: var(--text);
|
|
209
|
+
word-break: break-word;
|
|
233
210
|
overflow-wrap: anywhere;
|
|
234
211
|
}
|
|
235
212
|
|
|
@@ -268,8 +245,8 @@ li small {
|
|
|
268
245
|
}
|
|
269
246
|
|
|
270
247
|
.content-dialog {
|
|
271
|
-
width: min(
|
|
272
|
-
max-height: calc(100svh -
|
|
248
|
+
width: min(1240px, calc(100vw - 24px));
|
|
249
|
+
max-height: calc(100svh - 20px);
|
|
273
250
|
padding: 0;
|
|
274
251
|
border: 1px solid var(--line);
|
|
275
252
|
border-radius: 8px;
|
|
@@ -285,8 +262,8 @@ li small {
|
|
|
285
262
|
|
|
286
263
|
.content-dialog article {
|
|
287
264
|
display: grid;
|
|
288
|
-
grid-template-rows: auto minmax(0, 1fr);
|
|
289
|
-
max-height: calc(100svh -
|
|
265
|
+
grid-template-rows: auto auto minmax(0, 1fr);
|
|
266
|
+
max-height: calc(100svh - 22px);
|
|
290
267
|
}
|
|
291
268
|
|
|
292
269
|
.content-dialog header {
|
|
@@ -333,6 +310,41 @@ li small {
|
|
|
333
310
|
color: var(--accent);
|
|
334
311
|
}
|
|
335
312
|
|
|
313
|
+
.content-meta {
|
|
314
|
+
display: grid;
|
|
315
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
316
|
+
gap: 10px;
|
|
317
|
+
padding: 14px 22px;
|
|
318
|
+
border-bottom: 1px solid var(--line);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.content-meta-section {
|
|
322
|
+
min-height: 0;
|
|
323
|
+
padding: 10px;
|
|
324
|
+
border: 1px solid var(--line);
|
|
325
|
+
border-radius: 8px;
|
|
326
|
+
background: var(--panel-strong);
|
|
327
|
+
display: grid;
|
|
328
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
329
|
+
gap: 8px;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.content-meta-section h3 {
|
|
333
|
+
margin: 0;
|
|
334
|
+
color: var(--muted);
|
|
335
|
+
font-size: 11px;
|
|
336
|
+
font-weight: 700;
|
|
337
|
+
text-transform: uppercase;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.content-meta-section ul,
|
|
341
|
+
.content-meta-section .tags {
|
|
342
|
+
max-height: 220px;
|
|
343
|
+
overflow: auto;
|
|
344
|
+
align-content: flex-start;
|
|
345
|
+
padding-right: 4px;
|
|
346
|
+
}
|
|
347
|
+
|
|
336
348
|
.content-dialog .note-content {
|
|
337
349
|
max-height: none;
|
|
338
350
|
min-height: 0;
|
|
@@ -341,33 +353,56 @@ li small {
|
|
|
341
353
|
padding: 22px;
|
|
342
354
|
}
|
|
343
355
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
356
|
+
.app-footer {
|
|
357
|
+
flex: 0 0 28px;
|
|
358
|
+
height: 28px;
|
|
359
|
+
display: flex;
|
|
360
|
+
align-items: center;
|
|
361
|
+
justify-content: center;
|
|
362
|
+
background: transparent;
|
|
363
|
+
}
|
|
349
364
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
365
|
+
.app-footer small {
|
|
366
|
+
color: var(--muted);
|
|
367
|
+
font-size: 11px;
|
|
368
|
+
letter-spacing: 0.02em;
|
|
369
|
+
}
|
|
355
370
|
|
|
356
|
-
|
|
371
|
+
@media (max-width: 860px) {
|
|
372
|
+
.graph-header {
|
|
357
373
|
align-items: stretch;
|
|
358
|
-
flex-
|
|
374
|
+
flex-wrap: wrap;
|
|
375
|
+
padding: 10px 12px;
|
|
376
|
+
min-height: 0;
|
|
359
377
|
}
|
|
360
378
|
|
|
361
379
|
.search {
|
|
362
380
|
width: 100%;
|
|
381
|
+
flex-basis: 100%;
|
|
382
|
+
order: 3;
|
|
363
383
|
}
|
|
364
384
|
|
|
365
385
|
.agent-filter {
|
|
366
386
|
width: 100%;
|
|
367
387
|
}
|
|
368
388
|
|
|
389
|
+
.header-actions {
|
|
390
|
+
width: 100%;
|
|
391
|
+
margin-left: 0;
|
|
392
|
+
justify-content: space-between;
|
|
393
|
+
order: 4;
|
|
394
|
+
}
|
|
395
|
+
|
|
369
396
|
.content-dialog header {
|
|
370
397
|
align-items: stretch;
|
|
371
398
|
flex-direction: column;
|
|
372
399
|
}
|
|
400
|
+
|
|
401
|
+
.metric-chip {
|
|
402
|
+
min-width: 82px;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.content-meta {
|
|
406
|
+
grid-template-columns: 1fr;
|
|
407
|
+
}
|
|
373
408
|
}`;
|
|
@@ -9,54 +9,46 @@ export const createClientHtml = () => `<!doctype html>
|
|
|
9
9
|
<body>
|
|
10
10
|
<main class="shell">
|
|
11
11
|
<section class="workspace" aria-label="Knowledge graph">
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
<div>
|
|
12
|
+
<header class="graph-header" aria-label="Graph actions">
|
|
13
|
+
<div class="brand-block">
|
|
15
14
|
<strong>Brainlink</strong>
|
|
16
|
-
<span
|
|
15
|
+
<span class="eyebrow">Knowledge Graph</span>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="floating-metrics" aria-label="Graph totals">
|
|
18
|
+
<div class="metric-chip">
|
|
19
|
+
<strong id="nodeCount">0</strong>
|
|
20
|
+
<small>Notes</small>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="metric-chip">
|
|
23
|
+
<strong id="edgeCount">0</strong>
|
|
24
|
+
<small>Links</small>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="metric-chip">
|
|
27
|
+
<strong id="tagCount">0</strong>
|
|
28
|
+
<small>Tags</small>
|
|
29
|
+
</div>
|
|
17
30
|
</div>
|
|
18
31
|
<label class="search">
|
|
19
32
|
<input id="search" type="search" placeholder="Filter notes, tags or paths" autocomplete="off" />
|
|
20
33
|
</label>
|
|
21
|
-
<
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
<div class="header-actions">
|
|
35
|
+
<label class="agent-filter">
|
|
36
|
+
<select id="agent"></select>
|
|
37
|
+
</label>
|
|
38
|
+
<div class="toolbar" aria-label="Graph controls">
|
|
39
|
+
<button id="zoomIn" type="button" title="Zoom in">+</button>
|
|
40
|
+
<button id="zoomOut" type="button" title="Zoom out">-</button>
|
|
41
|
+
<button id="fit" type="button" title="Focus central hub">◎</button>
|
|
42
|
+
<button id="reset" type="button" title="Reset view">⌂</button>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</header>
|
|
46
|
+
<canvas id="graph" aria-label="Brainlink knowledge graph"></canvas>
|
|
30
47
|
</section>
|
|
31
|
-
<aside class="inspector" aria-label="Selected note">
|
|
32
|
-
<div>
|
|
33
|
-
<span class="eyebrow">Selected note</span>
|
|
34
|
-
<h1 id="title">Graph Overview</h1>
|
|
35
|
-
<p id="path">Select a node to inspect links and backlinks.</p>
|
|
36
|
-
</div>
|
|
37
|
-
<div class="metrics">
|
|
38
|
-
<div><span id="nodeCount">0</span><small>Notes</small></div>
|
|
39
|
-
<div><span id="edgeCount">0</span><small>Links</small></div>
|
|
40
|
-
<div><span id="tagCount">0</span><small>Tags</small></div>
|
|
41
|
-
</div>
|
|
42
|
-
<section>
|
|
43
|
-
<h2>Tags</h2>
|
|
44
|
-
<div id="tags" class="tags"></div>
|
|
45
|
-
</section>
|
|
46
|
-
<section>
|
|
47
|
-
<h2>Notes</h2>
|
|
48
|
-
<ul id="notes"></ul>
|
|
49
|
-
</section>
|
|
50
|
-
<section>
|
|
51
|
-
<h2>Outgoing</h2>
|
|
52
|
-
<ul id="outgoing"></ul>
|
|
53
|
-
</section>
|
|
54
|
-
<section>
|
|
55
|
-
<h2>Backlinks</h2>
|
|
56
|
-
<ul id="incoming"></ul>
|
|
57
|
-
</section>
|
|
58
|
-
</aside>
|
|
59
48
|
</main>
|
|
49
|
+
<footer class="app-footer" aria-label="Copyright notice">
|
|
50
|
+
<small>Copyright © 2026 Substructa</small>
|
|
51
|
+
</footer>
|
|
60
52
|
<dialog id="contentDialog" class="content-dialog" aria-labelledby="contentTitle">
|
|
61
53
|
<article>
|
|
62
54
|
<header>
|
|
@@ -67,6 +59,20 @@ export const createClientHtml = () => `<!doctype html>
|
|
|
67
59
|
</div>
|
|
68
60
|
<button id="contentClose" type="button">Close</button>
|
|
69
61
|
</header>
|
|
62
|
+
<div class="content-meta">
|
|
63
|
+
<section class="content-meta-section">
|
|
64
|
+
<h3>Tags</h3>
|
|
65
|
+
<div id="contentTags" class="tags"></div>
|
|
66
|
+
</section>
|
|
67
|
+
<section class="content-meta-section">
|
|
68
|
+
<h3>Outgoing</h3>
|
|
69
|
+
<ul id="contentOutgoing"></ul>
|
|
70
|
+
</section>
|
|
71
|
+
<section class="content-meta-section">
|
|
72
|
+
<h3>Backlinks</h3>
|
|
73
|
+
<ul id="contentIncoming"></ul>
|
|
74
|
+
</section>
|
|
75
|
+
</div>
|
|
70
76
|
<pre id="contentBody" class="note-content"></pre>
|
|
71
77
|
</article>
|
|
72
78
|
</dialog>
|