@andespindola/brainlink 0.1.0-beta.1 → 0.1.0-beta.11

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +241 -10
  3. package/dist/application/add-note.js +62 -13
  4. package/dist/application/analyze-vault.js +104 -9
  5. package/dist/application/frontend/client-css.js +154 -71
  6. package/dist/application/frontend/client-html.js +42 -33
  7. package/dist/application/frontend/client-js.js +316 -84
  8. package/dist/application/get-graph-layout.js +22 -7
  9. package/dist/application/get-graph-node.js +12 -0
  10. package/dist/application/get-graph-summary.js +12 -0
  11. package/dist/application/index-vault.js +7 -0
  12. package/dist/application/migrate-vault.js +91 -0
  13. package/dist/application/search-graph-node-ids.js +12 -0
  14. package/dist/application/search-knowledge.js +74 -4
  15. package/dist/application/server/routes.js +27 -1
  16. package/dist/cli/commands/agent-commands.js +412 -0
  17. package/dist/cli/commands/config-commands.js +167 -0
  18. package/dist/cli/commands/read-commands.js +25 -8
  19. package/dist/cli/commands/write-commands.js +173 -4
  20. package/dist/cli/main.js +4 -0
  21. package/dist/cli/runtime.js +5 -2
  22. package/dist/domain/embeddings.js +2 -1
  23. package/dist/domain/graph-layout.js +20 -14
  24. package/dist/domain/markdown.js +36 -4
  25. package/dist/infrastructure/config.js +94 -8
  26. package/dist/infrastructure/file-system-vault.js +15 -0
  27. package/dist/infrastructure/paths.js +9 -1
  28. package/dist/infrastructure/search-packs.js +151 -0
  29. package/dist/infrastructure/session-state.js +172 -0
  30. package/dist/infrastructure/sqlite/graph-reader.js +252 -105
  31. package/dist/infrastructure/sqlite/recovery.js +83 -0
  32. package/dist/infrastructure/sqlite/schema.js +4 -1
  33. package/dist/infrastructure/sqlite/search-reader.js +104 -72
  34. package/dist/infrastructure/sqlite-index.js +16 -3
  35. package/dist/mcp/main.js +11 -3
  36. package/dist/mcp/server.js +17 -2
  37. package/dist/mcp/startup.js +35 -0
  38. package/dist/mcp/tools.js +571 -19
  39. package/docs/AGENT_USAGE.md +87 -3
  40. package/docs/ARCHITECTURE.md +16 -1
  41. package/docs/QUICKSTART.md +104 -0
  42. package/docs/RELEASE.md +3 -3
  43. package/package.json +1 -1
@@ -32,8 +32,6 @@ select {
32
32
  }
33
33
 
34
34
  .shell {
35
- display: grid;
36
- grid-template-columns: minmax(0, 1fr) 360px;
37
35
  width: 100%;
38
36
  height: 100svh;
39
37
  overflow: hidden;
@@ -73,17 +71,14 @@ select {
73
71
 
74
72
  .topbar > div {
75
73
  display: flex;
76
- align-items: baseline;
77
- gap: 12px;
74
+ align-items: center;
78
75
  }
79
76
 
80
77
  .topbar strong {
81
78
  font-size: 18px;
82
79
  }
83
80
 
84
- .topbar span,
85
- .eyebrow,
86
- .inspector small {
81
+ .eyebrow {
87
82
  color: var(--muted);
88
83
  font-size: 12px;
89
84
  }
@@ -138,70 +133,37 @@ select {
138
133
  color: var(--accent);
139
134
  }
140
135
 
141
- .inspector {
142
- display: grid;
143
- grid-template-rows: auto auto auto auto auto 1fr 1fr;
144
- gap: 22px;
145
- min-width: 0;
146
- height: 100%;
147
- padding: 24px;
148
- border-left: 1px solid var(--line);
149
- background: var(--panel);
150
- overflow: auto;
136
+ .floating-metrics {
137
+ position: absolute;
138
+ top: 66px;
139
+ left: 18px;
140
+ display: flex;
141
+ gap: 10px;
142
+ pointer-events: none;
151
143
  }
152
144
 
153
- .inspector h1,
154
- .inspector h2,
155
- .inspector p {
156
- margin: 0;
145
+ .metric-chip {
146
+ min-width: 94px;
147
+ padding: 10px 12px;
148
+ border: 1px solid var(--line);
149
+ border-radius: 10px;
150
+ background: rgba(21, 25, 31, 0.88);
151
+ display: grid;
152
+ gap: 3px;
157
153
  }
158
154
 
159
- .inspector h1 {
160
- margin-top: 6px;
155
+ .metric-chip strong {
161
156
  font-size: 26px;
162
- line-height: 1.12;
163
- overflow-wrap: anywhere;
157
+ line-height: 1;
164
158
  }
165
159
 
166
- .inspector h2 {
167
- margin-bottom: 10px;
160
+ .metric-chip small {
168
161
  color: var(--muted);
169
- font-size: 12px;
170
- font-weight: 700;
162
+ font-size: 11px;
163
+ letter-spacing: 0.03em;
171
164
  text-transform: uppercase;
172
165
  }
173
166
 
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
167
  .tags {
206
168
  display: flex;
207
169
  flex-wrap: wrap;
@@ -215,6 +177,7 @@ select {
215
177
  background: var(--accent-weak);
216
178
  color: var(--accent);
217
179
  font-size: 12px;
180
+ word-break: break-word;
218
181
  overflow-wrap: anywhere;
219
182
  }
220
183
 
@@ -230,6 +193,7 @@ li {
230
193
  padding: 10px 0;
231
194
  border-bottom: 1px solid var(--line);
232
195
  color: var(--text);
196
+ word-break: break-word;
233
197
  overflow-wrap: anywhere;
234
198
  }
235
199
 
@@ -253,7 +217,7 @@ li small {
253
217
  }
254
218
 
255
219
  .note-content {
256
- max-height: 32svh;
220
+ max-height: min(68svh, 760px);
257
221
  margin: 0;
258
222
  padding: 12px;
259
223
  border: 1px solid var(--line);
@@ -267,18 +231,116 @@ li small {
267
231
  line-height: 1.5;
268
232
  }
269
233
 
270
- @media (max-width: 860px) {
271
- .shell {
272
- grid-template-columns: 1fr;
273
- grid-template-rows: minmax(0, 1fr) 42svh;
274
- }
234
+ .content-dialog {
235
+ width: min(920px, calc(100vw - 32px));
236
+ max-height: calc(100svh - 32px);
237
+ padding: 0;
238
+ border: 1px solid var(--line);
239
+ border-radius: 8px;
240
+ background: var(--panel);
241
+ color: var(--text);
242
+ box-shadow: 0 24px 80px rgba(0, 0, 0, 0.48);
243
+ }
275
244
 
276
- .inspector {
277
- border-left: 0;
278
- border-top: 1px solid var(--line);
279
- padding: 18px;
280
- }
245
+ .content-dialog::backdrop {
246
+ background: rgba(4, 7, 10, 0.72);
247
+ backdrop-filter: blur(4px);
248
+ }
281
249
 
250
+ .content-dialog article {
251
+ display: grid;
252
+ grid-template-rows: auto auto minmax(0, 1fr);
253
+ max-height: calc(100svh - 34px);
254
+ }
255
+
256
+ .content-dialog header {
257
+ display: flex;
258
+ align-items: flex-start;
259
+ justify-content: space-between;
260
+ gap: 18px;
261
+ padding: 22px;
262
+ border-bottom: 1px solid var(--line);
263
+ }
264
+
265
+ .content-dialog h2,
266
+ .content-dialog p {
267
+ margin: 0;
268
+ }
269
+
270
+ .content-dialog h2 {
271
+ margin-top: 6px;
272
+ font-size: 24px;
273
+ line-height: 1.15;
274
+ overflow-wrap: anywhere;
275
+ }
276
+
277
+ .content-dialog p {
278
+ margin-top: 8px;
279
+ color: var(--muted);
280
+ overflow-wrap: anywhere;
281
+ }
282
+
283
+ .content-dialog button {
284
+ flex: 0 0 auto;
285
+ height: 38px;
286
+ padding: 0 14px;
287
+ border: 1px solid var(--line);
288
+ border-radius: 8px;
289
+ background: var(--panel-strong);
290
+ color: var(--text);
291
+ cursor: pointer;
292
+ }
293
+
294
+ .content-dialog button:hover,
295
+ .content-dialog button:focus {
296
+ border-color: var(--accent);
297
+ color: var(--accent);
298
+ }
299
+
300
+ .content-meta {
301
+ display: grid;
302
+ grid-template-columns: repeat(3, minmax(0, 1fr));
303
+ gap: 10px;
304
+ padding: 14px 22px;
305
+ border-bottom: 1px solid var(--line);
306
+ }
307
+
308
+ .content-meta-section {
309
+ min-height: 0;
310
+ padding: 10px;
311
+ border: 1px solid var(--line);
312
+ border-radius: 8px;
313
+ background: var(--panel-strong);
314
+ display: grid;
315
+ grid-template-rows: auto minmax(0, 1fr);
316
+ gap: 8px;
317
+ }
318
+
319
+ .content-meta-section h3 {
320
+ margin: 0;
321
+ color: var(--muted);
322
+ font-size: 11px;
323
+ font-weight: 700;
324
+ text-transform: uppercase;
325
+ }
326
+
327
+ .content-meta-section ul,
328
+ .content-meta-section .tags {
329
+ max-height: 140px;
330
+ overflow: auto;
331
+ align-content: flex-start;
332
+ padding-right: 4px;
333
+ }
334
+
335
+ .content-dialog .note-content {
336
+ max-height: none;
337
+ min-height: 0;
338
+ border: 0;
339
+ border-radius: 0;
340
+ padding: 22px;
341
+ }
342
+
343
+ @media (max-width: 860px) {
282
344
  .topbar {
283
345
  align-items: stretch;
284
346
  flex-direction: column;
@@ -291,4 +353,25 @@ li small {
291
353
  .agent-filter {
292
354
  width: 100%;
293
355
  }
356
+
357
+ .content-dialog header {
358
+ align-items: stretch;
359
+ flex-direction: column;
360
+ }
361
+
362
+ .floating-metrics {
363
+ top: 116px;
364
+ right: 18px;
365
+ left: 18px;
366
+ justify-content: flex-start;
367
+ flex-wrap: wrap;
368
+ }
369
+
370
+ .metric-chip {
371
+ min-width: 82px;
372
+ }
373
+
374
+ .content-meta {
375
+ grid-template-columns: 1fr;
376
+ }
294
377
  }`;
@@ -13,7 +13,6 @@ export const createClientHtml = () => `<!doctype html>
13
13
  <div class="topbar">
14
14
  <div>
15
15
  <strong>Brainlink</strong>
16
- <span id="stats">Loading graph</span>
17
16
  </div>
18
17
  <label class="search">
19
18
  <input id="search" type="search" placeholder="Filter notes, tags or paths" autocomplete="off" />
@@ -22,45 +21,55 @@ export const createClientHtml = () => `<!doctype html>
22
21
  <select id="agent"></select>
23
22
  </label>
24
23
  </div>
24
+ <div class="floating-metrics" aria-label="Graph totals">
25
+ <div class="metric-chip">
26
+ <strong id="nodeCount">0</strong>
27
+ <small>Notes</small>
28
+ </div>
29
+ <div class="metric-chip">
30
+ <strong id="edgeCount">0</strong>
31
+ <small>Links</small>
32
+ </div>
33
+ <div class="metric-chip">
34
+ <strong id="tagCount">0</strong>
35
+ <small>Tags</small>
36
+ </div>
37
+ </div>
25
38
  <div class="toolbar" aria-label="Graph controls">
26
39
  <button id="zoomIn" type="button" title="Zoom in">+</button>
27
40
  <button id="zoomOut" type="button" title="Zoom out">-</button>
41
+ <button id="fit" type="button" title="Fit visible nodes">◎</button>
28
42
  <button id="reset" type="button" title="Reset view">⌂</button>
29
43
  </div>
30
44
  </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>Content</h2>
52
- <pre id="content" class="note-content"></pre>
53
- </section>
54
- <section>
55
- <h2>Outgoing</h2>
56
- <ul id="outgoing"></ul>
57
- </section>
58
- <section>
59
- <h2>Backlinks</h2>
60
- <ul id="incoming"></ul>
61
- </section>
62
- </aside>
63
45
  </main>
46
+ <dialog id="contentDialog" class="content-dialog" aria-labelledby="contentTitle">
47
+ <article>
48
+ <header>
49
+ <div>
50
+ <span class="eyebrow">Markdown content</span>
51
+ <h2 id="contentTitle">Selected note</h2>
52
+ <p id="contentPath"></p>
53
+ </div>
54
+ <button id="contentClose" type="button">Close</button>
55
+ </header>
56
+ <div class="content-meta">
57
+ <section class="content-meta-section">
58
+ <h3>Tags</h3>
59
+ <div id="contentTags" class="tags"></div>
60
+ </section>
61
+ <section class="content-meta-section">
62
+ <h3>Outgoing</h3>
63
+ <ul id="contentOutgoing"></ul>
64
+ </section>
65
+ <section class="content-meta-section">
66
+ <h3>Backlinks</h3>
67
+ <ul id="contentIncoming"></ul>
68
+ </section>
69
+ </div>
70
+ <pre id="contentBody" class="note-content"></pre>
71
+ </article>
72
+ </dialog>
64
73
  <script src="/app.js"></script>
65
74
  </body>
66
75
  </html>`;