@andespindola/brainlink 0.1.0-beta.16 → 0.1.0-beta.160
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 +9 -6
- package/CHANGELOG.md +27 -0
- package/COPYRIGHT.md +5 -0
- package/README.md +177 -20
- package/dist/application/add-note.js +13 -44
- package/dist/application/auto-migrate-configured-vault.js +37 -0
- package/dist/application/build-context.js +64 -3
- package/dist/application/canonical-context-links.js +209 -0
- package/dist/application/dedupe-notes.js +226 -0
- package/dist/application/frontend/client-css.js +241 -51
- package/dist/application/frontend/client-html.js +50 -27
- package/dist/application/frontend/client-js.js +1369 -605
- package/dist/application/frontend/client-render-worker-js.js +622 -0
- package/dist/application/frontend/client-worker-js.js +66 -0
- package/dist/application/get-graph-contexts.js +33 -0
- package/dist/application/get-graph-layout.js +62 -8
- package/dist/application/get-graph-stream-chunk.js +326 -0
- package/dist/application/get-graph-view.js +246 -0
- package/dist/application/graph-view-state.js +66 -0
- package/dist/application/import-legacy-sqlite.js +266 -0
- package/dist/application/index-vault.js +262 -23
- package/dist/application/migrate-context-links.js +79 -0
- package/dist/application/offline-pack-backup.js +44 -0
- package/dist/application/search-graph-node-ids.js +63 -3
- package/dist/application/server/routes.js +247 -7
- package/dist/application/start-server.js +75 -4
- package/dist/application/watch-vault.js +23 -2
- package/dist/cli/commands/agent-commands.js +7 -0
- package/dist/cli/commands/write-commands.js +924 -14
- package/dist/cli/runtime.js +10 -2
- package/dist/domain/context.js +54 -11
- package/dist/domain/graph-contexts.js +180 -0
- package/dist/domain/graph-layout.js +389 -18
- package/dist/domain/markdown.js +53 -9
- package/dist/domain/middle-out.js +18 -0
- package/dist/infrastructure/config.js +121 -4
- package/dist/infrastructure/file-index.js +76 -6
- package/dist/infrastructure/file-system-vault.js +15 -0
- package/dist/infrastructure/index-state.js +58 -0
- package/dist/infrastructure/private-pack-codec.js +71 -10
- package/dist/infrastructure/search-packs.js +286 -15
- package/dist/infrastructure/vault-migration-state.js +69 -0
- package/dist/infrastructure/volatile-memory.js +100 -0
- package/dist/mcp/runtime.js +20 -0
- package/dist/mcp/server.js +39 -11
- package/dist/mcp/tools.js +183 -7
- package/docs/AGENT_USAGE.md +96 -5
- package/docs/ARCHITECTURE.md +8 -0
- package/docs/QUICKSTART.md +7 -0
- package/package.json +7 -2
|
@@ -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,12 +39,15 @@ select {
|
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
.shell {
|
|
42
|
+
flex: 1 1 auto;
|
|
35
43
|
width: 100%;
|
|
36
|
-
height:
|
|
44
|
+
min-height: 0;
|
|
37
45
|
overflow: hidden;
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
.workspace {
|
|
49
|
+
display: grid;
|
|
50
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
41
51
|
position: relative;
|
|
42
52
|
width: 100%;
|
|
43
53
|
height: 100%;
|
|
@@ -45,39 +55,134 @@ select {
|
|
|
45
55
|
min-height: 0;
|
|
46
56
|
}
|
|
47
57
|
|
|
48
|
-
|
|
49
|
-
|
|
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
|
+
|
|
80
|
+
.graph-stage {
|
|
81
|
+
position: relative;
|
|
50
82
|
width: 100%;
|
|
51
83
|
height: 100%;
|
|
52
84
|
background:
|
|
53
85
|
radial-gradient(circle at 18% 20%, rgba(53, 208, 162, 0.12), transparent 28rem),
|
|
54
86
|
linear-gradient(135deg, #0d0f12 0%, #12161c 55%, #0a0d10 100%);
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
#graph {
|
|
91
|
+
display: block;
|
|
92
|
+
position: absolute;
|
|
93
|
+
inset: 0;
|
|
94
|
+
width: 100%;
|
|
95
|
+
height: 100%;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#graph {
|
|
55
99
|
cursor: grab;
|
|
56
100
|
}
|
|
57
101
|
|
|
102
|
+
#graph.is-node-hover {
|
|
103
|
+
cursor: pointer;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#graph.is-node-dragging {
|
|
107
|
+
cursor: move;
|
|
108
|
+
}
|
|
109
|
+
|
|
58
110
|
#graph:active {
|
|
59
111
|
cursor: grabbing;
|
|
60
112
|
}
|
|
61
113
|
|
|
62
|
-
.
|
|
114
|
+
.graph-labels {
|
|
63
115
|
position: absolute;
|
|
64
|
-
|
|
65
|
-
left: 18px;
|
|
66
|
-
right: 18px;
|
|
67
|
-
display: flex;
|
|
68
|
-
align-items: center;
|
|
69
|
-
justify-content: space-between;
|
|
70
|
-
gap: 18px;
|
|
116
|
+
inset: 0;
|
|
71
117
|
pointer-events: none;
|
|
118
|
+
overflow: hidden;
|
|
119
|
+
transition: opacity 120ms ease;
|
|
72
120
|
}
|
|
73
121
|
|
|
74
|
-
.
|
|
75
|
-
|
|
76
|
-
align-items: center;
|
|
122
|
+
.graph-labels.is-stale {
|
|
123
|
+
opacity: 0;
|
|
77
124
|
}
|
|
78
125
|
|
|
79
|
-
.
|
|
80
|
-
|
|
126
|
+
.graph-label {
|
|
127
|
+
position: absolute;
|
|
128
|
+
max-width: 220px;
|
|
129
|
+
transform: translate(-50%, calc(-100% - 10px));
|
|
130
|
+
padding: 4px 7px;
|
|
131
|
+
border: 1px solid rgba(129, 146, 170, 0.28);
|
|
132
|
+
border-radius: 6px;
|
|
133
|
+
background: rgba(13, 16, 20, 0.78);
|
|
134
|
+
color: var(--text);
|
|
135
|
+
font-size: 11px;
|
|
136
|
+
line-height: 1.25;
|
|
137
|
+
white-space: nowrap;
|
|
138
|
+
overflow: hidden;
|
|
139
|
+
text-overflow: ellipsis;
|
|
140
|
+
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.28);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.graph-label.is-focused {
|
|
144
|
+
border-color: rgba(53, 208, 162, 0.72);
|
|
145
|
+
color: #dffbf3;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.graph-tooltip {
|
|
149
|
+
position: absolute;
|
|
150
|
+
z-index: 4;
|
|
151
|
+
max-width: min(320px, calc(100vw - 32px));
|
|
152
|
+
padding: 8px 10px;
|
|
153
|
+
border: 1px solid var(--line);
|
|
154
|
+
border-radius: 6px;
|
|
155
|
+
background: rgba(13, 16, 20, 0.94);
|
|
156
|
+
color: var(--text);
|
|
157
|
+
font-size: 12px;
|
|
158
|
+
line-height: 1.35;
|
|
159
|
+
pointer-events: none;
|
|
160
|
+
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.38);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.graph-tooltip strong,
|
|
164
|
+
.graph-tooltip small {
|
|
165
|
+
display: block;
|
|
166
|
+
overflow: hidden;
|
|
167
|
+
text-overflow: ellipsis;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.graph-tooltip small {
|
|
171
|
+
margin-top: 3px;
|
|
172
|
+
color: var(--muted);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.mini-map {
|
|
176
|
+
position: absolute;
|
|
177
|
+
right: 14px;
|
|
178
|
+
bottom: 14px;
|
|
179
|
+
z-index: 3;
|
|
180
|
+
width: 180px;
|
|
181
|
+
height: 120px;
|
|
182
|
+
border: 1px solid rgba(129, 146, 170, 0.28);
|
|
183
|
+
border-radius: 8px;
|
|
184
|
+
background: rgba(13, 16, 20, 0.78);
|
|
185
|
+
box-shadow: 0 16px 42px rgba(0, 0, 0, 0.38);
|
|
81
186
|
}
|
|
82
187
|
|
|
83
188
|
.eyebrow {
|
|
@@ -86,17 +191,25 @@ select {
|
|
|
86
191
|
}
|
|
87
192
|
|
|
88
193
|
.search {
|
|
89
|
-
|
|
90
|
-
|
|
194
|
+
flex: 1 1 320px;
|
|
195
|
+
min-width: 220px;
|
|
91
196
|
}
|
|
92
197
|
|
|
93
|
-
.agent-filter
|
|
198
|
+
.agent-filter,
|
|
199
|
+
.context-filter {
|
|
94
200
|
width: min(220px, 28vw);
|
|
95
|
-
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.header-actions {
|
|
204
|
+
display: flex;
|
|
205
|
+
align-items: center;
|
|
206
|
+
gap: 10px;
|
|
207
|
+
margin-left: auto;
|
|
96
208
|
}
|
|
97
209
|
|
|
98
210
|
.search input,
|
|
99
|
-
.agent-filter select
|
|
211
|
+
.agent-filter select,
|
|
212
|
+
.context-filter select {
|
|
100
213
|
width: 100%;
|
|
101
214
|
height: 40px;
|
|
102
215
|
border: 1px solid var(--line);
|
|
@@ -108,14 +221,12 @@ select {
|
|
|
108
221
|
}
|
|
109
222
|
|
|
110
223
|
.search input:focus,
|
|
111
|
-
.agent-filter select:focus
|
|
224
|
+
.agent-filter select:focus,
|
|
225
|
+
.context-filter select:focus {
|
|
112
226
|
border-color: var(--accent);
|
|
113
227
|
}
|
|
114
228
|
|
|
115
229
|
.toolbar {
|
|
116
|
-
position: absolute;
|
|
117
|
-
left: 18px;
|
|
118
|
-
bottom: 18px;
|
|
119
230
|
display: flex;
|
|
120
231
|
gap: 8px;
|
|
121
232
|
}
|
|
@@ -136,12 +247,9 @@ select {
|
|
|
136
247
|
}
|
|
137
248
|
|
|
138
249
|
.floating-metrics {
|
|
139
|
-
position: absolute;
|
|
140
|
-
top: 66px;
|
|
141
|
-
left: 18px;
|
|
142
250
|
display: flex;
|
|
143
251
|
gap: 10px;
|
|
144
|
-
|
|
252
|
+
flex-wrap: wrap;
|
|
145
253
|
}
|
|
146
254
|
|
|
147
255
|
.metric-chip {
|
|
@@ -234,14 +342,22 @@ li small {
|
|
|
234
342
|
}
|
|
235
343
|
|
|
236
344
|
.content-dialog {
|
|
237
|
-
|
|
238
|
-
|
|
345
|
+
position: fixed;
|
|
346
|
+
top: max(12px, env(safe-area-inset-top));
|
|
347
|
+
right: max(12px, env(safe-area-inset-right));
|
|
348
|
+
margin: 0;
|
|
349
|
+
width: min(760px, calc(100vw - 32px));
|
|
350
|
+
height: min(calc(100vh - 24px), 920px);
|
|
351
|
+
height: min(calc(100dvh - 24px), 920px);
|
|
352
|
+
max-height: calc(100vh - 24px);
|
|
353
|
+
max-height: calc(100dvh - 24px);
|
|
239
354
|
padding: 0;
|
|
240
355
|
border: 1px solid var(--line);
|
|
241
356
|
border-radius: 8px;
|
|
242
357
|
background: var(--panel);
|
|
243
358
|
color: var(--text);
|
|
244
359
|
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.48);
|
|
360
|
+
overflow: hidden;
|
|
245
361
|
}
|
|
246
362
|
|
|
247
363
|
.content-dialog::backdrop {
|
|
@@ -252,7 +368,9 @@ li small {
|
|
|
252
368
|
.content-dialog article {
|
|
253
369
|
display: grid;
|
|
254
370
|
grid-template-rows: auto auto minmax(0, 1fr);
|
|
255
|
-
|
|
371
|
+
height: 100%;
|
|
372
|
+
max-height: 100%;
|
|
373
|
+
min-height: 0;
|
|
256
374
|
}
|
|
257
375
|
|
|
258
376
|
.content-dialog header {
|
|
@@ -262,6 +380,7 @@ li small {
|
|
|
262
380
|
gap: 18px;
|
|
263
381
|
padding: 22px;
|
|
264
382
|
border-bottom: 1px solid var(--line);
|
|
383
|
+
background: var(--panel);
|
|
265
384
|
}
|
|
266
385
|
|
|
267
386
|
.content-dialog h2,
|
|
@@ -271,7 +390,7 @@ li small {
|
|
|
271
390
|
|
|
272
391
|
.content-dialog h2 {
|
|
273
392
|
margin-top: 6px;
|
|
274
|
-
font-size:
|
|
393
|
+
font-size: 19px;
|
|
275
394
|
line-height: 1.15;
|
|
276
395
|
overflow-wrap: anywhere;
|
|
277
396
|
}
|
|
@@ -282,26 +401,45 @@ li small {
|
|
|
282
401
|
overflow-wrap: anywhere;
|
|
283
402
|
}
|
|
284
403
|
|
|
285
|
-
|
|
404
|
+
#contentClose {
|
|
286
405
|
flex: 0 0 auto;
|
|
406
|
+
width: 38px;
|
|
287
407
|
height: 38px;
|
|
288
|
-
padding: 0
|
|
408
|
+
padding: 0;
|
|
289
409
|
border: 1px solid var(--line);
|
|
290
410
|
border-radius: 8px;
|
|
291
411
|
background: var(--panel-strong);
|
|
292
412
|
color: var(--text);
|
|
293
413
|
cursor: pointer;
|
|
414
|
+
font-size: 22px;
|
|
415
|
+
line-height: 1;
|
|
294
416
|
}
|
|
295
417
|
|
|
296
|
-
|
|
297
|
-
|
|
418
|
+
#contentClose:hover,
|
|
419
|
+
#contentClose:focus {
|
|
298
420
|
border-color: var(--accent);
|
|
299
421
|
color: var(--accent);
|
|
300
422
|
}
|
|
301
423
|
|
|
424
|
+
.content-dialog li button {
|
|
425
|
+
width: 100%;
|
|
426
|
+
height: auto;
|
|
427
|
+
padding: 0;
|
|
428
|
+
border: 0;
|
|
429
|
+
border-radius: 0;
|
|
430
|
+
background: transparent;
|
|
431
|
+
color: var(--text);
|
|
432
|
+
text-align: left;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.content-dialog li button:hover,
|
|
436
|
+
.content-dialog li button:focus {
|
|
437
|
+
color: var(--accent);
|
|
438
|
+
}
|
|
439
|
+
|
|
302
440
|
.content-meta {
|
|
303
441
|
display: grid;
|
|
304
|
-
grid-template-columns: repeat(
|
|
442
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
305
443
|
gap: 10px;
|
|
306
444
|
padding: 14px 22px;
|
|
307
445
|
border-bottom: 1px solid var(--line);
|
|
@@ -328,45 +466,86 @@ li small {
|
|
|
328
466
|
|
|
329
467
|
.content-meta-section ul,
|
|
330
468
|
.content-meta-section .tags {
|
|
331
|
-
max-height:
|
|
469
|
+
max-height: 280px;
|
|
332
470
|
overflow: auto;
|
|
333
471
|
align-content: flex-start;
|
|
334
472
|
padding-right: 4px;
|
|
335
473
|
}
|
|
336
474
|
|
|
475
|
+
.content-meta-section:last-child {
|
|
476
|
+
grid-column: span 2;
|
|
477
|
+
}
|
|
478
|
+
|
|
337
479
|
.content-dialog .note-content {
|
|
338
480
|
max-height: none;
|
|
339
481
|
min-height: 0;
|
|
340
482
|
border: 0;
|
|
341
483
|
border-radius: 0;
|
|
342
|
-
padding:
|
|
484
|
+
padding: 14px;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.app-footer {
|
|
488
|
+
flex: 0 0 28px;
|
|
489
|
+
height: 28px;
|
|
490
|
+
display: flex;
|
|
491
|
+
align-items: center;
|
|
492
|
+
justify-content: center;
|
|
493
|
+
background: transparent;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.app-footer small {
|
|
497
|
+
color: var(--muted);
|
|
498
|
+
font-size: 11px;
|
|
499
|
+
letter-spacing: 0.02em;
|
|
343
500
|
}
|
|
344
501
|
|
|
345
502
|
@media (max-width: 860px) {
|
|
346
|
-
.
|
|
503
|
+
.graph-header {
|
|
347
504
|
align-items: stretch;
|
|
348
|
-
flex-
|
|
505
|
+
flex-wrap: wrap;
|
|
506
|
+
padding: 10px 12px;
|
|
507
|
+
min-height: 0;
|
|
349
508
|
}
|
|
350
509
|
|
|
351
510
|
.search {
|
|
352
511
|
width: 100%;
|
|
512
|
+
flex-basis: 100%;
|
|
513
|
+
order: 3;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
.agent-filter,
|
|
517
|
+
.context-filter {
|
|
518
|
+
width: 100%;
|
|
353
519
|
}
|
|
354
520
|
|
|
355
|
-
.
|
|
521
|
+
.header-actions {
|
|
356
522
|
width: 100%;
|
|
523
|
+
margin-left: 0;
|
|
524
|
+
justify-content: space-between;
|
|
525
|
+
order: 4;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.content-dialog {
|
|
529
|
+
inset: 8px;
|
|
530
|
+
inset: max(8px, env(safe-area-inset-top)) max(8px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
|
|
531
|
+
width: auto;
|
|
532
|
+
height: auto;
|
|
533
|
+
max-width: none;
|
|
534
|
+
max-height: none;
|
|
357
535
|
}
|
|
358
536
|
|
|
359
537
|
.content-dialog header {
|
|
360
|
-
align-items:
|
|
361
|
-
|
|
538
|
+
align-items: flex-start;
|
|
539
|
+
gap: 12px;
|
|
540
|
+
padding: 14px;
|
|
362
541
|
}
|
|
363
542
|
|
|
364
|
-
.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
543
|
+
.content-dialog h2 {
|
|
544
|
+
font-size: 16px;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.content-dialog p {
|
|
548
|
+
font-size: 12px;
|
|
370
549
|
}
|
|
371
550
|
|
|
372
551
|
.metric-chip {
|
|
@@ -375,5 +554,16 @@ li small {
|
|
|
375
554
|
|
|
376
555
|
.content-meta {
|
|
377
556
|
grid-template-columns: 1fr;
|
|
557
|
+
max-height: 34dvh;
|
|
558
|
+
overflow: auto;
|
|
559
|
+
padding: 10px 14px;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
.content-meta-section:last-child {
|
|
563
|
+
grid-column: auto;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.content-dialog .note-content {
|
|
567
|
+
padding: 12px;
|
|
378
568
|
}
|
|
379
569
|
}`;
|
|
@@ -9,51 +9,74 @@ 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>
|
|
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>
|
|
16
30
|
</div>
|
|
17
31
|
<label class="search">
|
|
18
32
|
<input id="search" type="search" placeholder="Filter notes, tags or paths" autocomplete="off" />
|
|
19
33
|
</label>
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<strong id="tagCount">0</strong>
|
|
35
|
-
<small>Tags</small>
|
|
34
|
+
<div class="header-actions">
|
|
35
|
+
<label class="agent-filter">
|
|
36
|
+
<select id="agent"></select>
|
|
37
|
+
</label>
|
|
38
|
+
<label class="context-filter">
|
|
39
|
+
<select id="context"></select>
|
|
40
|
+
</label>
|
|
41
|
+
<div class="toolbar" aria-label="Graph controls">
|
|
42
|
+
<button id="zoomIn" type="button" title="Zoom in">+</button>
|
|
43
|
+
<button id="zoomOut" type="button" title="Zoom out">-</button>
|
|
44
|
+
<button id="fit" type="button" title="Focus central hub">◎</button>
|
|
45
|
+
<button id="releaseNode" type="button" title="Release selected node">◇</button>
|
|
46
|
+
<button id="reset" type="button" title="Reset view">⌂</button>
|
|
47
|
+
</div>
|
|
36
48
|
</div>
|
|
37
|
-
</
|
|
38
|
-
<div class="
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
<
|
|
49
|
+
</header>
|
|
50
|
+
<div class="graph-stage">
|
|
51
|
+
<canvas id="graph" aria-label="Brainlink knowledge graph"></canvas>
|
|
52
|
+
<div id="graphLabels" class="graph-labels" aria-hidden="true"></div>
|
|
53
|
+
<div id="graphTooltip" class="graph-tooltip" role="tooltip" hidden></div>
|
|
54
|
+
<canvas id="miniMap" class="mini-map" aria-label="Graph overview"></canvas>
|
|
43
55
|
</div>
|
|
44
56
|
</section>
|
|
45
57
|
</main>
|
|
58
|
+
<footer class="app-footer" aria-label="Copyright notice">
|
|
59
|
+
<small>Copyright © 2026 Substructa</small>
|
|
60
|
+
</footer>
|
|
46
61
|
<dialog id="contentDialog" class="content-dialog" aria-labelledby="contentTitle">
|
|
47
62
|
<article>
|
|
48
63
|
<header>
|
|
49
64
|
<div>
|
|
50
|
-
<span class="eyebrow">
|
|
65
|
+
<span class="eyebrow">Node details</span>
|
|
51
66
|
<h2 id="contentTitle">Selected note</h2>
|
|
52
67
|
<p id="contentPath"></p>
|
|
53
68
|
</div>
|
|
54
|
-
<button id="contentClose" type="button"
|
|
69
|
+
<button id="contentClose" type="button" aria-label="Close node details" title="Close node details">×</button>
|
|
55
70
|
</header>
|
|
56
71
|
<div class="content-meta">
|
|
72
|
+
<section class="content-meta-section">
|
|
73
|
+
<h3>Facts</h3>
|
|
74
|
+
<ul id="contentFacts"></ul>
|
|
75
|
+
</section>
|
|
76
|
+
<section class="content-meta-section">
|
|
77
|
+
<h3>Context Links</h3>
|
|
78
|
+
<ul id="contentContextLinks"></ul>
|
|
79
|
+
</section>
|
|
57
80
|
<section class="content-meta-section">
|
|
58
81
|
<h3>Tags</h3>
|
|
59
82
|
<div id="contentTags" class="tags"></div>
|