@andespindola/brainlink 1.5.0 → 1.6.1
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/README.md +4 -1
- package/assets/brainlink-logo.png +0 -0
- package/assets/brainlink-logo.svg +88 -78
- package/dist/application/index-vault.js +7 -1
- package/dist/infrastructure/config.js +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.1
|
|
4
|
+
|
|
5
|
+
- **Fix the broken README logo on npm.** The logo was referenced via a `raw.githubusercontent.com` URL, which returns 404 for anonymous requests because the source repository is private — so it never rendered on the npm package page. Point it at the public npm CDN (`cdn.jsdelivr.net/npm/...`), which serves the published package's assets regardless of repository visibility, and refresh the brain-as-a-graph artwork.
|
|
6
|
+
|
|
7
|
+
## 1.6.0
|
|
8
|
+
|
|
9
|
+
- **Declarative vault git remote (`vaultRemote`).** New optional config field naming the git remote used to version the vault. When set and `autoVersion` is `true`, Brainlink ensures the vault git repo exists and its `origin` points to that remote before the auto-version push (init + add/update origin, idempotent). When unset, versioning uses whatever `origin` already exists and stays a no-op if there is none — Brainlink never provisions a remote on its own. `autoVersion` still defaults to `false`; inline-credential URLs are rejected.
|
|
10
|
+
|
|
3
11
|
## 1.5.0
|
|
4
12
|
|
|
5
13
|
- **Graph shows every node at any zoom.** The viewport stream previously replaced nodes with per-context clusters below a zoom threshold, so nodes vanished when you zoomed out and reappeared on approach. Graphs that fit a cap (6000 nodes) now render every node in near mode at all zoom levels; larger graphs keep the far/mid/near level-of-detail.
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://
|
|
2
|
+
<img src="https://cdn.jsdelivr.net/npm/@andespindola/brainlink@1.6.1/assets/brainlink-logo.png" alt="Brainlink" width="720">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
# Brainlink
|
|
@@ -1156,6 +1156,8 @@ If no `vault` is configured and no `--vault` flag is passed, Brainlink uses `$HO
|
|
|
1156
1156
|
"defaultAgent": "shared",
|
|
1157
1157
|
"autoIndexOnWrite": true,
|
|
1158
1158
|
"autoCanonicalContextLinks": true,
|
|
1159
|
+
"autoVersion": false,
|
|
1160
|
+
"vaultRemote": "git@github.com:you/brainlink-vault.git",
|
|
1159
1161
|
"autoUpdateCheck": true,
|
|
1160
1162
|
"updateCheckIntervalMs": 86400000,
|
|
1161
1163
|
"defaultSearchLimit": 8,
|
|
@@ -1190,6 +1192,7 @@ If no `vault` is configured and no `--vault` flag is passed, Brainlink uses `$HO
|
|
|
1190
1192
|
|
|
1191
1193
|
`autoIndexOnWrite` is optional and defaults to `true`. Set it to `false` to defer indexing after writes.
|
|
1192
1194
|
`autoVersion` is optional and defaults to `false`. When enabled (e.g. by `blink vault-provision` / `brainlink_vault_provision`), a successful index that changed Markdown commits and pushes the vault to its git remote automatically, best-effort — a git or network failure is logged and never breaks indexing. It is a no-op unless the vault is a git repo with an `origin` remote.
|
|
1195
|
+
`vaultRemote` is optional. When set and `autoVersion` is `true`, Brainlink ensures the vault git repo exists and its `origin` points to this remote before pushing (initializing the repo and adding/updating `origin` as needed). When it is unset, versioning uses whatever `origin` the vault git repo already has, and stays a no-op if there is none — Brainlink never provisions a remote on its own. Inline-credential URLs (e.g. `https://user:token@…`) are rejected; use SSH or a git credential helper.
|
|
1193
1196
|
`vaultEncryption` is optional and defaults to `false`. When enabled, vault versioning commits AES-256-GCM ciphertext (`<note>.md.enc`) and git-ignores the plaintext Markdown, so the repository is opaque to anyone without the key — only a Brainlink instance holding the per-vault key can decrypt it. The key lives at `$BRAINLINK_HOME/keys/vault-versioning-<hash>.key` (outside the vault, never committed) or can be supplied via `BRAINLINK_VAULT_KEY` to restore an encrypted vault on another machine. Pull, restore and clone decrypt back to Markdown before reindexing; encryption is deterministic per note, so unchanged notes add no git churn. `blink vault-provision` enables this by default.
|
|
1194
1197
|
`autoCanonicalContextLinks` is optional and defaults to `true`. When enabled, `blink add`, `brainlink_add_note` and `brainlink_add_file` add a canonical `## Context Links` entry to the inferred context hub, creating that hub when needed.
|
|
1195
1198
|
`autoUpdateCheck` is optional and defaults to `true`. Brainlink checks the npm registry no more often than `updateCheckIntervalMs` and prints an update notice to `stderr`; it never installs updates automatically.
|
|
Binary file
|
|
@@ -1,100 +1,110 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="1280" height="460" viewBox="0 0 1280 460" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
|
|
2
2
|
<title id="title">Brainlink</title>
|
|
3
|
-
<desc id="desc">Brainlink logo: a brain
|
|
3
|
+
<desc id="desc">Brainlink logo: a brain formed by a network graph of connected memory nodes, for AI agents.</desc>
|
|
4
4
|
<defs>
|
|
5
|
-
<radialGradient id="bg" cx="
|
|
6
|
-
<stop offset="0%" stop-color="#
|
|
7
|
-
<stop offset="
|
|
8
|
-
<stop offset="100%" stop-color="#
|
|
5
|
+
<radialGradient id="bg" cx="25%" cy="28%" r="100%">
|
|
6
|
+
<stop offset="0%" stop-color="#0f2637"/>
|
|
7
|
+
<stop offset="52%" stop-color="#0a1a28"/>
|
|
8
|
+
<stop offset="100%" stop-color="#060f18"/>
|
|
9
9
|
</radialGradient>
|
|
10
|
+
<linearGradient id="brainFill" x1="0" y1="0" x2="0.9" y2="1">
|
|
11
|
+
<stop offset="0%" stop-color="#5aa8ff" stop-opacity="0.10"/>
|
|
12
|
+
<stop offset="100%" stop-color="#59d0dd" stop-opacity="0.03"/>
|
|
13
|
+
</linearGradient>
|
|
10
14
|
<linearGradient id="brainStroke" x1="0" y1="0" x2="1" y2="1">
|
|
11
|
-
<stop offset="0%" stop-color="#
|
|
12
|
-
<stop offset="100%" stop-color="#
|
|
15
|
+
<stop offset="0%" stop-color="#7cc0ff"/>
|
|
16
|
+
<stop offset="100%" stop-color="#5ee0d6"/>
|
|
13
17
|
</linearGradient>
|
|
14
18
|
<linearGradient id="wordmark" x1="0" y1="0" x2="0" y2="1">
|
|
15
|
-
<stop offset="0%" stop-color="#
|
|
16
|
-
<stop offset="100%" stop-color="#
|
|
19
|
+
<stop offset="0%" stop-color="#f2f7ff"/>
|
|
20
|
+
<stop offset="100%" stop-color="#b9d2f2"/>
|
|
17
21
|
</linearGradient>
|
|
18
|
-
<filter id="glow" x="-
|
|
19
|
-
<feGaussianBlur stdDeviation="
|
|
20
|
-
<feMerge>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
<filter id="glow" x="-70%" y="-70%" width="240%" height="240%">
|
|
23
|
+
<feGaussianBlur stdDeviation="4.2" result="b"/>
|
|
24
|
+
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
25
|
+
</filter>
|
|
26
|
+
<filter id="softglow" x="-80%" y="-80%" width="260%" height="260%">
|
|
27
|
+
<feGaussianBlur stdDeviation="9" result="b"/>
|
|
28
|
+
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
24
29
|
</filter>
|
|
25
30
|
</defs>
|
|
26
31
|
|
|
27
|
-
<rect width="
|
|
32
|
+
<rect width="1280" height="460" rx="36" fill="url(#bg)"/>
|
|
33
|
+
|
|
34
|
+
<g transform="translate(78 40)">
|
|
35
|
+
<!-- brain silhouette: rounded frontal lobe + bumpy top gyri + cerebellum notch -->
|
|
36
|
+
<path d="M250,40
|
|
37
|
+
C196,26 150,44 132,88
|
|
38
|
+
C96,86 66,118 78,158
|
|
39
|
+
C48,172 44,220 76,242
|
|
40
|
+
C58,266 66,312 100,322
|
|
41
|
+
C104,360 150,384 196,372
|
|
42
|
+
C214,398 268,402 300,382
|
|
43
|
+
C316,404 360,404 380,376
|
|
44
|
+
C420,388 456,362 452,320
|
|
45
|
+
C486,306 492,256 462,238
|
|
46
|
+
C486,220 486,172 452,158
|
|
47
|
+
C466,116 434,80 392,90
|
|
48
|
+
C378,58 344,40 306,52
|
|
49
|
+
C292,40 270,36 250,40 Z"
|
|
50
|
+
fill="url(#brainFill)" stroke="url(#brainStroke)" stroke-width="3" stroke-opacity="0.7" filter="url(#softglow)"/>
|
|
28
51
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
<path d="M268,72 C246,120 300,150 270,196 C242,240 300,272 272,318"
|
|
39
|
-
fill="none" stroke="#5aa8ff" stroke-width="2.2" stroke-opacity="0.32"/>
|
|
40
|
-
<path d="M150,110 C176,128 176,156 150,176" fill="none" stroke="#5aa8ff" stroke-width="2" stroke-opacity="0.2"/>
|
|
41
|
-
<path d="M360,120 C334,140 336,168 362,186" fill="none" stroke="#5aa8ff" stroke-width="2" stroke-opacity="0.2"/>
|
|
42
|
-
<path d="M196,250 C222,262 250,258 268,240" fill="none" stroke="#5aa8ff" stroke-width="2" stroke-opacity="0.2"/>
|
|
52
|
+
<!-- central fissure between hemispheres -->
|
|
53
|
+
<path d="M262,52 C236,104 292,140 260,190 C230,238 296,276 266,338"
|
|
54
|
+
fill="none" stroke="#7cc0ff" stroke-width="2.4" stroke-opacity="0.34"/>
|
|
55
|
+
<!-- gyri folds -->
|
|
56
|
+
<path d="M150,96 C182,116 182,150 150,172" fill="none" stroke="#5aa8ff" stroke-width="2" stroke-opacity="0.20"/>
|
|
57
|
+
<path d="M120,180 C150,196 150,226 118,244" fill="none" stroke="#5aa8ff" stroke-width="2" stroke-opacity="0.18"/>
|
|
58
|
+
<path d="M182,266 C210,284 244,282 262,262" fill="none" stroke="#5aa8ff" stroke-width="2" stroke-opacity="0.18"/>
|
|
59
|
+
<path d="M366,110 C336,132 338,164 368,182" fill="none" stroke="#59d0dd" stroke-width="2" stroke-opacity="0.20"/>
|
|
60
|
+
<path d="M402,196 C374,214 376,246 406,262" fill="none" stroke="#59d0dd" stroke-width="2" stroke-opacity="0.18"/>
|
|
43
61
|
|
|
44
62
|
<!-- graph edges -->
|
|
45
|
-
<g stroke="#
|
|
46
|
-
<line x1="150" y1="
|
|
47
|
-
<line x1="
|
|
48
|
-
<line x1="
|
|
49
|
-
<line x1="
|
|
50
|
-
<line x1="
|
|
51
|
-
<line x1="
|
|
52
|
-
<line x1="
|
|
53
|
-
<line x1="
|
|
54
|
-
<line x1="
|
|
55
|
-
<line x1="
|
|
56
|
-
<line x1="
|
|
57
|
-
<line x1="
|
|
58
|
-
<line x1="
|
|
59
|
-
<line x1="300" y1="112" x2="340" y2="152"/>
|
|
60
|
-
<line x1="300" y1="112" x2="250" y2="150"/>
|
|
61
|
-
<line x1="340" y1="152" x2="315" y2="200"/>
|
|
62
|
-
<line x1="315" y1="200" x2="362" y2="236"/>
|
|
63
|
-
<line x1="362" y1="236" x2="345" y2="292"/>
|
|
64
|
-
<line x1="345" y1="292" x2="300" y2="300"/>
|
|
65
|
-
<line x1="300" y1="300" x2="266" y2="262"/>
|
|
66
|
-
<line x1="300" y1="300" x2="208" y2="298"/>
|
|
67
|
-
<line x1="270" y1="205" x2="300" y2="300"/>
|
|
68
|
-
<line x1="270" y1="205" x2="266" y2="262"/>
|
|
63
|
+
<g stroke="#8fbdec" stroke-width="1.9" stroke-opacity="0.42" stroke-linecap="round">
|
|
64
|
+
<line x1="150" y1="118" x2="212" y2="92"/><line x1="212" y1="92" x2="256" y2="150"/>
|
|
65
|
+
<line x1="150" y1="118" x2="196" y2="168"/><line x1="196" y1="168" x2="256" y2="150"/>
|
|
66
|
+
<line x1="196" y1="168" x2="140" y2="196"/><line x1="140" y1="196" x2="176" y2="248"/>
|
|
67
|
+
<line x1="176" y1="248" x2="228" y2="226"/><line x1="228" y1="226" x2="256" y2="150"/>
|
|
68
|
+
<line x1="176" y1="248" x2="210" y2="300"/><line x1="210" y1="300" x2="268" y2="266"/>
|
|
69
|
+
<line x1="268" y1="266" x2="228" y2="226"/><line x1="256" y1="150" x2="274" y2="208"/>
|
|
70
|
+
<line x1="274" y1="208" x2="320" y2="202"/><line x1="304" y1="112" x2="344" y2="152"/>
|
|
71
|
+
<line x1="304" y1="112" x2="256" y2="150"/><line x1="344" y1="152" x2="320" y2="202"/>
|
|
72
|
+
<line x1="320" y1="202" x2="368" y2="238"/><line x1="368" y1="238" x2="350" y2="296"/>
|
|
73
|
+
<line x1="350" y1="296" x2="304" y2="304"/><line x1="304" y1="304" x2="268" y2="266"/>
|
|
74
|
+
<line x1="304" y1="304" x2="210" y2="300"/><line x1="274" y1="208" x2="304" y2="304"/>
|
|
75
|
+
<line x1="274" y1="208" x2="268" y2="266"/><line x1="344" y1="152" x2="404" y2="150"/>
|
|
76
|
+
<line x1="404" y1="150" x2="420" y2="210"/><line x1="420" y1="210" x2="368" y2="238"/>
|
|
69
77
|
</g>
|
|
70
78
|
|
|
71
79
|
<!-- graph nodes -->
|
|
72
|
-
<g>
|
|
73
|
-
<circle cx="
|
|
74
|
-
<circle cx="
|
|
75
|
-
<circle cx="
|
|
76
|
-
<circle cx="
|
|
77
|
-
<circle cx="
|
|
78
|
-
<circle cx="
|
|
79
|
-
<circle cx="
|
|
80
|
-
<circle cx="
|
|
81
|
-
<circle cx="
|
|
82
|
-
<circle cx="
|
|
83
|
-
<circle cx="
|
|
84
|
-
<circle cx="
|
|
85
|
-
<circle cx="
|
|
86
|
-
<circle cx="
|
|
87
|
-
<circle cx="
|
|
88
|
-
<circle cx="
|
|
80
|
+
<g filter="url(#glow)">
|
|
81
|
+
<circle cx="274" cy="208" r="13" fill="#5aa8ff"/>
|
|
82
|
+
<circle cx="256" cy="150" r="10.5" fill="#7cb6ff"/>
|
|
83
|
+
<circle cx="320" cy="202" r="10.5" fill="#5ecf92"/>
|
|
84
|
+
<circle cx="212" cy="92" r="8" fill="#59d0dd"/>
|
|
85
|
+
<circle cx="150" cy="118" r="7" fill="#5aa8ff"/>
|
|
86
|
+
<circle cx="196" cy="168" r="7" fill="#5ecf92"/>
|
|
87
|
+
<circle cx="140" cy="196" r="7" fill="#5aa8ff"/>
|
|
88
|
+
<circle cx="176" cy="248" r="8.5" fill="#a88fff"/>
|
|
89
|
+
<circle cx="228" cy="226" r="9" fill="#5aa8ff"/>
|
|
90
|
+
<circle cx="210" cy="300" r="7" fill="#ffb65c"/>
|
|
91
|
+
<circle cx="268" cy="266" r="8.5" fill="#59d0dd"/>
|
|
92
|
+
<circle cx="304" cy="112" r="8" fill="#ff7dac"/>
|
|
93
|
+
<circle cx="344" cy="152" r="7.5" fill="#5aa8ff"/>
|
|
94
|
+
<circle cx="368" cy="238" r="7.5" fill="#7cb6ff"/>
|
|
95
|
+
<circle cx="350" cy="296" r="8" fill="#5aa8ff"/>
|
|
96
|
+
<circle cx="304" cy="304" r="9" fill="#ff8f6a"/>
|
|
97
|
+
<circle cx="404" cy="150" r="7.5" fill="#5ecf92"/>
|
|
98
|
+
<circle cx="420" cy="210" r="7" fill="#59d0dd"/>
|
|
89
99
|
</g>
|
|
90
100
|
</g>
|
|
91
101
|
|
|
92
102
|
<!-- wordmark -->
|
|
93
|
-
<g transform="translate(
|
|
94
|
-
<text x="0" y="
|
|
95
|
-
<text x="
|
|
96
|
-
<line x1="
|
|
97
|
-
<line x1="166" y1="
|
|
98
|
-
<line x1="
|
|
103
|
+
<g transform="translate(590 0)" font-family="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif">
|
|
104
|
+
<text x="0" y="222" fill="url(#wordmark)" font-size="120" font-weight="800" letter-spacing="-3.5">Brainlink</text>
|
|
105
|
+
<text x="5" y="272" fill="#88a2d6" font-size="29" font-weight="500">Canonical memory graph for AI agents</text>
|
|
106
|
+
<line x1="7" y1="302" x2="150" y2="302" stroke="#5aa8ff" stroke-width="6" stroke-linecap="round"/>
|
|
107
|
+
<line x1="166" y1="302" x2="240" y2="302" stroke="#59d0dd" stroke-width="6" stroke-linecap="round"/>
|
|
108
|
+
<line x1="256" y1="302" x2="300" y2="302" stroke="#5ecf92" stroke-width="6" stroke-linecap="round"/>
|
|
99
109
|
</g>
|
|
100
110
|
</svg>
|
|
@@ -5,7 +5,7 @@ import { ensureVault, readMarkdownFileSummaries } from '../infrastructure/file-s
|
|
|
5
5
|
import { readIndexState, writeIndexState } from '../infrastructure/index-state.js';
|
|
6
6
|
import { ensureSearchPackManifest } from '../infrastructure/search-packs.js';
|
|
7
7
|
import { openKnowledgeStore } from '../infrastructure/knowledge-store/index.js';
|
|
8
|
-
import { autoVersionVault } from './vault-git-core.js';
|
|
8
|
+
import { autoVersionVault, initVaultGit } from './vault-git-core.js';
|
|
9
9
|
import { assembleIndexedDocuments, createTitleMaps, decidePackRebuild, detectChanges, embedChangedDocuments, rebuildSearchPacksIfNeeded } from './index-vault-phases.js';
|
|
10
10
|
const toIndexResult = (documents) => ({
|
|
11
11
|
documentCount: documents.length,
|
|
@@ -177,6 +177,12 @@ export const indexVaultWithOptions = async (vaultPath, options) => {
|
|
|
177
177
|
// origin remote — commitVault itself skips when nothing is staged.
|
|
178
178
|
if (config.autoVersion && changedDocumentsByPath.size > 0) {
|
|
179
179
|
try {
|
|
180
|
+
// When a remote is configured, ensure the vault git repo exists and its
|
|
181
|
+
// origin points there before pushing. Without it, autoVersionVault falls
|
|
182
|
+
// back to whatever origin already exists (no-op if none).
|
|
183
|
+
if (config.vaultRemote) {
|
|
184
|
+
await initVaultGit(absoluteVaultPath, { remote: config.vaultRemote });
|
|
185
|
+
}
|
|
180
186
|
await autoVersionVault(absoluteVaultPath, `chore(vault): update ${new Date().toISOString()}`);
|
|
181
187
|
}
|
|
182
188
|
catch (error) {
|
|
@@ -16,6 +16,7 @@ export const defaultBrainlinkConfig = {
|
|
|
16
16
|
autoIndexOnWrite: true,
|
|
17
17
|
autoCanonicalContextLinks: true,
|
|
18
18
|
autoVersion: false,
|
|
19
|
+
vaultRemote: undefined,
|
|
19
20
|
vaultEncryption: false,
|
|
20
21
|
autoUpdateCheck: true,
|
|
21
22
|
updateCheckIntervalMs: 86_400_000,
|
|
@@ -218,6 +219,9 @@ const sanitizeConfig = (value) => ({
|
|
|
218
219
|
? value.autoCanonicalContextLinks
|
|
219
220
|
: defaultBrainlinkConfig.autoCanonicalContextLinks,
|
|
220
221
|
autoVersion: typeof value.autoVersion === 'boolean' ? value.autoVersion : defaultBrainlinkConfig.autoVersion,
|
|
222
|
+
vaultRemote: typeof value.vaultRemote === 'string' && value.vaultRemote.trim().length > 0
|
|
223
|
+
? value.vaultRemote.trim()
|
|
224
|
+
: defaultBrainlinkConfig.vaultRemote,
|
|
221
225
|
vaultEncryption: typeof value.vaultEncryption === 'boolean' ? value.vaultEncryption : defaultBrainlinkConfig.vaultEncryption,
|
|
222
226
|
autoUpdateCheck: typeof value.autoUpdateCheck === 'boolean' ? value.autoUpdateCheck : defaultBrainlinkConfig.autoUpdateCheck,
|
|
223
227
|
updateCheckIntervalMs: typeof value.updateCheckIntervalMs === 'number' && Number.isFinite(value.updateCheckIntervalMs) && value.updateCheckIntervalMs > 0
|
package/package.json
CHANGED