@andespindola/brainlink 0.1.0-alpha.0 → 0.1.0-alpha.2
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 +2 -0
- package/README.md +32 -20
- package/dist/cli/commands/read-commands.js +10 -10
- package/dist/cli/commands/write-commands.js +7 -7
- package/dist/cli/main.js +9 -2
- package/dist/infrastructure/config.js +2 -1
- package/dist/infrastructure/file-system-vault.js +2 -1
- package/dist/infrastructure/paths.js +14 -0
- package/dist/infrastructure/sqlite/schema.js +14 -1
- package/docs/AGENT_USAGE.md +24 -8
- package/docs/RELEASE.md +10 -3
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -20,6 +20,8 @@ npm run dev -- index --vault ./vault
|
|
|
20
20
|
|
|
21
21
|
Do not store permanent knowledge only in SQLite.
|
|
22
22
|
|
|
23
|
+
By default, the installed Brainlink CLI uses `$HOME/.brainlink/vault` as its vault. Passing `--vault` or setting `vault` in `brainlink.config.json` intentionally selects a custom vault such as `./vault`.
|
|
24
|
+
|
|
23
25
|
## Agent Workflow
|
|
24
26
|
|
|
25
27
|
Use this loop when using Brainlink as memory:
|
package/README.md
CHANGED
|
@@ -110,26 +110,33 @@ Then verify:
|
|
|
110
110
|
blink --help
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
-
### 2. Choose A Vault
|
|
113
|
+
### 2. Use The Default Vault Or Choose A Custom Vault
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
By default, Brainlink stores memory in:
|
|
116
116
|
|
|
117
117
|
```bash
|
|
118
|
-
|
|
118
|
+
$HOME/.brainlink/vault
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
-
Use
|
|
121
|
+
Use the default vault when memory should span many projects:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
|
-
|
|
124
|
+
blink init
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
Choose a project-local vault only when memory belongs to one repository:
|
|
128
128
|
|
|
129
129
|
```bash
|
|
130
|
+
BLINK_VAULT=".brainlink-vault"
|
|
130
131
|
blink init "$BLINK_VAULT"
|
|
131
132
|
```
|
|
132
133
|
|
|
134
|
+
You can also set `BRAINLINK_HOME` to move Brainlink's default home directory:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
export BRAINLINK_HOME="/path/to/brainlink-home"
|
|
138
|
+
```
|
|
139
|
+
|
|
133
140
|
### 3. Choose An Agent Namespace
|
|
134
141
|
|
|
135
142
|
Use a stable namespace for yourself:
|
|
@@ -146,7 +153,6 @@ Before answering or changing code, retrieve context:
|
|
|
146
153
|
|
|
147
154
|
```bash
|
|
148
155
|
blink context "What should I know before working on this task?" \
|
|
149
|
-
--vault "$BLINK_VAULT" \
|
|
150
156
|
--agent "$BLINK_AGENT" \
|
|
151
157
|
--json
|
|
152
158
|
```
|
|
@@ -155,7 +161,6 @@ If the context is weak, inspect raw search results:
|
|
|
155
161
|
|
|
156
162
|
```bash
|
|
157
163
|
blink search "architecture conventions tests release" \
|
|
158
|
-
--vault "$BLINK_VAULT" \
|
|
159
164
|
--agent "$BLINK_AGENT" \
|
|
160
165
|
--mode hybrid \
|
|
161
166
|
--limit 10 \
|
|
@@ -168,7 +173,6 @@ Only store knowledge that is likely to matter later:
|
|
|
168
173
|
|
|
169
174
|
```bash
|
|
170
175
|
blink add "Testing Policy" \
|
|
171
|
-
--vault "$BLINK_VAULT" \
|
|
172
176
|
--agent "$BLINK_AGENT" \
|
|
173
177
|
--content "Run npm run check before final delivery. Related: [[Release Checklist]]. #testing #process"
|
|
174
178
|
```
|
|
@@ -176,15 +180,15 @@ blink add "Testing Policy" \
|
|
|
176
180
|
Rebuild the index:
|
|
177
181
|
|
|
178
182
|
```bash
|
|
179
|
-
blink index
|
|
183
|
+
blink index
|
|
180
184
|
```
|
|
181
185
|
|
|
182
186
|
### 6. Validate Memory Health
|
|
183
187
|
|
|
184
188
|
```bash
|
|
185
|
-
blink validate --
|
|
186
|
-
blink broken-links --
|
|
187
|
-
blink orphans --
|
|
189
|
+
blink validate --agent "$BLINK_AGENT" --json
|
|
190
|
+
blink broken-links --agent "$BLINK_AGENT" --json
|
|
191
|
+
blink orphans --agent "$BLINK_AGENT" --json
|
|
188
192
|
```
|
|
189
193
|
|
|
190
194
|
### Agent Operating Loop
|
|
@@ -192,7 +196,7 @@ blink orphans --vault "$BLINK_VAULT" --agent "$BLINK_AGENT" --json
|
|
|
192
196
|
Use this loop during real work:
|
|
193
197
|
|
|
194
198
|
1. Identify the task and choose `BLINK_AGENT`.
|
|
195
|
-
2. Run `blink context "<task>" --
|
|
199
|
+
2. Run `blink context "<task>" --agent "$BLINK_AGENT" --json`.
|
|
196
200
|
3. Use returned sources as project memory.
|
|
197
201
|
4. Perform the task.
|
|
198
202
|
5. Save only durable learnings with `blink add`.
|
|
@@ -229,6 +233,8 @@ Open the graph UI:
|
|
|
229
233
|
http://127.0.0.1:4321
|
|
230
234
|
```
|
|
231
235
|
|
|
236
|
+
When `--vault` is omitted, commands use the default vault at `$HOME/.brainlink/vault`. Pass `--vault` or configure `vault` in `brainlink.config.json` when you want a custom project-local vault.
|
|
237
|
+
|
|
232
238
|
## Core Model
|
|
233
239
|
|
|
234
240
|
```txt
|
|
@@ -314,9 +320,9 @@ An MCP server can use Brainlink by spawning `blink` or `brainlink` as a subproce
|
|
|
314
320
|
Minimum integration contract:
|
|
315
321
|
|
|
316
322
|
```bash
|
|
317
|
-
blink context "<task>" --
|
|
318
|
-
blink add "Decision Title" --
|
|
319
|
-
blink index
|
|
323
|
+
blink context "<task>" --agent "$BLINK_AGENT" --json
|
|
324
|
+
blink add "Decision Title" --agent "$BLINK_AGENT" --content "Durable memory. #decision"
|
|
325
|
+
blink index
|
|
320
326
|
```
|
|
321
327
|
|
|
322
328
|
Example Node.js wrapper inside an external MCP server:
|
|
@@ -357,9 +363,11 @@ Recommended MCP tools exposed by the external server:
|
|
|
357
363
|
Start the local frontend:
|
|
358
364
|
|
|
359
365
|
```bash
|
|
360
|
-
blink server --
|
|
366
|
+
blink server --host 127.0.0.1 --port 4321 --watch
|
|
361
367
|
```
|
|
362
368
|
|
|
369
|
+
By default, the server uses `$HOME/.brainlink/vault`. Pass `--vault ./vault` only when you want to inspect a custom vault.
|
|
370
|
+
|
|
363
371
|
The graph UI shows:
|
|
364
372
|
|
|
365
373
|
- notes as nodes
|
|
@@ -411,14 +419,16 @@ Every command works with either `brainlink` or `blink`.
|
|
|
411
419
|
### `init`
|
|
412
420
|
|
|
413
421
|
```bash
|
|
422
|
+
blink init
|
|
414
423
|
blink init ./vault
|
|
415
424
|
```
|
|
416
425
|
|
|
417
|
-
Initializes vault metadata.
|
|
426
|
+
Initializes vault metadata. Without an argument, Brainlink initializes the default vault at `$HOME/.brainlink/vault`.
|
|
418
427
|
|
|
419
428
|
### `add`
|
|
420
429
|
|
|
421
430
|
```bash
|
|
431
|
+
blink add "Note Title" --agent coding-agent --content "Markdown content"
|
|
422
432
|
blink add "Note Title" --vault ./vault --agent coding-agent --content "Markdown content"
|
|
423
433
|
```
|
|
424
434
|
|
|
@@ -427,6 +437,7 @@ Creates a Markdown note under `agents/<agent-id>/`. Common secret patterns are b
|
|
|
427
437
|
### `index`
|
|
428
438
|
|
|
429
439
|
```bash
|
|
440
|
+
blink index
|
|
430
441
|
blink index --vault ./vault
|
|
431
442
|
```
|
|
432
443
|
|
|
@@ -546,6 +557,7 @@ Watches Markdown files and rebuilds the index when notes change.
|
|
|
546
557
|
### `server`
|
|
547
558
|
|
|
548
559
|
```bash
|
|
560
|
+
blink server --watch
|
|
549
561
|
blink server --vault ./vault --watch
|
|
550
562
|
```
|
|
551
563
|
|
|
@@ -569,7 +581,7 @@ npm run --silent dev -- context "question" --vault ./vault --json
|
|
|
569
581
|
|
|
570
582
|
## Configuration
|
|
571
583
|
|
|
572
|
-
Brainlink reads `brainlink.config.json` or `.brainlink.json` from the current working directory.
|
|
584
|
+
Brainlink reads `brainlink.config.json` or `.brainlink.json` from the current working directory. If no `vault` is configured and no `--vault` flag is passed, Brainlink uses `$HOME/.brainlink/vault`.
|
|
573
585
|
|
|
574
586
|
```json
|
|
575
587
|
{
|
|
@@ -10,7 +10,7 @@ export const registerReadCommands = (program) => {
|
|
|
10
10
|
program
|
|
11
11
|
.command('search')
|
|
12
12
|
.argument('<query>', 'search query')
|
|
13
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
13
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
14
14
|
.option('-a, --agent <agent>', 'filter by agent memory namespace')
|
|
15
15
|
.option('-l, --limit <limit>', 'maximum results', '10')
|
|
16
16
|
.option('-m, --mode <mode>', 'search mode: fts, semantic or hybrid')
|
|
@@ -27,7 +27,7 @@ export const registerReadCommands = (program) => {
|
|
|
27
27
|
});
|
|
28
28
|
program
|
|
29
29
|
.command('links')
|
|
30
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
30
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
31
31
|
.option('-a, --agent <agent>', 'filter by agent memory namespace')
|
|
32
32
|
.option('--json', 'print machine-readable JSON')
|
|
33
33
|
.description('list indexed wiki links')
|
|
@@ -44,7 +44,7 @@ export const registerReadCommands = (program) => {
|
|
|
44
44
|
program
|
|
45
45
|
.command('backlinks')
|
|
46
46
|
.argument('<title>', 'target note title')
|
|
47
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
47
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
48
48
|
.option('-a, --agent <agent>', 'filter by agent memory namespace')
|
|
49
49
|
.option('--json', 'print machine-readable JSON')
|
|
50
50
|
.description('list notes linking to a target note')
|
|
@@ -56,7 +56,7 @@ export const registerReadCommands = (program) => {
|
|
|
56
56
|
program
|
|
57
57
|
.command('context')
|
|
58
58
|
.argument('<query>', 'context query')
|
|
59
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
59
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
60
60
|
.option('-a, --agent <agent>', 'filter by agent memory namespace')
|
|
61
61
|
.option('-l, --limit <limit>', 'maximum search results before context selection', '12')
|
|
62
62
|
.option('-t, --tokens <tokens>', 'maximum estimated context tokens', '2000')
|
|
@@ -71,7 +71,7 @@ export const registerReadCommands = (program) => {
|
|
|
71
71
|
});
|
|
72
72
|
program
|
|
73
73
|
.command('graph')
|
|
74
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
74
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
75
75
|
.option('-a, --agent <agent>', 'filter by agent memory namespace')
|
|
76
76
|
.option('--json', 'print machine-readable JSON')
|
|
77
77
|
.description('print indexed graph data')
|
|
@@ -82,7 +82,7 @@ export const registerReadCommands = (program) => {
|
|
|
82
82
|
});
|
|
83
83
|
program
|
|
84
84
|
.command('agents')
|
|
85
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
85
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
86
86
|
.option('--json', 'print machine-readable JSON')
|
|
87
87
|
.description('list indexed agent memory namespaces')
|
|
88
88
|
.action(async (options) => {
|
|
@@ -92,7 +92,7 @@ export const registerReadCommands = (program) => {
|
|
|
92
92
|
});
|
|
93
93
|
program
|
|
94
94
|
.command('stats')
|
|
95
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
95
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
96
96
|
.option('-a, --agent <agent>', 'filter by agent memory namespace')
|
|
97
97
|
.option('--json', 'print machine-readable JSON')
|
|
98
98
|
.description('print indexed vault statistics')
|
|
@@ -110,7 +110,7 @@ export const registerReadCommands = (program) => {
|
|
|
110
110
|
});
|
|
111
111
|
program
|
|
112
112
|
.command('broken-links')
|
|
113
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
113
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
114
114
|
.option('-a, --agent <agent>', 'filter by agent memory namespace')
|
|
115
115
|
.option('--json', 'print machine-readable JSON')
|
|
116
116
|
.description('list unresolved wiki links')
|
|
@@ -123,7 +123,7 @@ export const registerReadCommands = (program) => {
|
|
|
123
123
|
});
|
|
124
124
|
program
|
|
125
125
|
.command('orphans')
|
|
126
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
126
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
127
127
|
.option('-a, --agent <agent>', 'filter by agent memory namespace')
|
|
128
128
|
.option('--json', 'print machine-readable JSON')
|
|
129
129
|
.description('list indexed notes without incoming or outgoing links')
|
|
@@ -134,7 +134,7 @@ export const registerReadCommands = (program) => {
|
|
|
134
134
|
});
|
|
135
135
|
program
|
|
136
136
|
.command('validate')
|
|
137
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
137
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
138
138
|
.option('-a, --agent <agent>', 'filter by agent memory namespace')
|
|
139
139
|
.option('--json', 'print machine-readable JSON')
|
|
140
140
|
.description('validate indexed vault graph health')
|
|
@@ -9,19 +9,19 @@ import { parsePositiveInteger, print, resolveOptions } from '../runtime.js';
|
|
|
9
9
|
export const registerWriteCommands = (program) => {
|
|
10
10
|
program
|
|
11
11
|
.command('init')
|
|
12
|
-
.argument('[vault]', 'vault directory'
|
|
12
|
+
.argument('[vault]', 'vault directory')
|
|
13
13
|
.option('--json', 'print machine-readable JSON')
|
|
14
14
|
.description('initialize a Brainlink vault')
|
|
15
15
|
.action(async (vault, options) => {
|
|
16
16
|
const config = await loadBrainlinkConfig();
|
|
17
|
-
const path = await ensureVault(assertVaultAllowed(vault, config.allowedVaults));
|
|
17
|
+
const path = await ensureVault(assertVaultAllowed(vault ?? config.vault, config.allowedVaults));
|
|
18
18
|
print(options.json, { path }, () => `Initialized Brainlink vault at ${path}`);
|
|
19
19
|
});
|
|
20
20
|
program
|
|
21
21
|
.command('add')
|
|
22
22
|
.argument('<title>', 'note title')
|
|
23
23
|
.requiredOption('-c, --content <content>', 'markdown content')
|
|
24
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
24
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
25
25
|
.option('-a, --agent <agent>', 'agent memory namespace', 'shared')
|
|
26
26
|
.option('--allow-sensitive', 'allow writing content that looks like a secret')
|
|
27
27
|
.option('--json', 'print machine-readable JSON')
|
|
@@ -35,7 +35,7 @@ export const registerWriteCommands = (program) => {
|
|
|
35
35
|
});
|
|
36
36
|
program
|
|
37
37
|
.command('index')
|
|
38
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
38
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
39
39
|
.option('--json', 'print machine-readable JSON')
|
|
40
40
|
.description('index markdown notes, links, tags and chunks')
|
|
41
41
|
.action(async (options) => {
|
|
@@ -45,7 +45,7 @@ export const registerWriteCommands = (program) => {
|
|
|
45
45
|
});
|
|
46
46
|
program
|
|
47
47
|
.command('doctor')
|
|
48
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
48
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
49
49
|
.option('--json', 'print machine-readable JSON')
|
|
50
50
|
.description('run Brainlink environment and vault checks')
|
|
51
51
|
.action(async (options) => {
|
|
@@ -56,7 +56,7 @@ export const registerWriteCommands = (program) => {
|
|
|
56
56
|
});
|
|
57
57
|
program
|
|
58
58
|
.command('watch')
|
|
59
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
59
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
60
60
|
.option('--json', 'print machine-readable JSON events')
|
|
61
61
|
.description('watch markdown files and reindex on changes')
|
|
62
62
|
.action(async (options) => {
|
|
@@ -84,7 +84,7 @@ export const registerWriteCommands = (program) => {
|
|
|
84
84
|
});
|
|
85
85
|
program
|
|
86
86
|
.command('server')
|
|
87
|
-
.option('-v, --vault <vault>', 'vault directory'
|
|
87
|
+
.option('-v, --vault <vault>', 'vault directory')
|
|
88
88
|
.option('-h, --host <host>', 'server host', '127.0.0.1')
|
|
89
89
|
.option('-p, --port <port>', 'server port', '4321')
|
|
90
90
|
.option('--no-index', 'skip indexing before starting the server')
|
package/dist/cli/main.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import {
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { basename, dirname, join } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
4
6
|
import { registerReadCommands } from './commands/read-commands.js';
|
|
5
7
|
import { registerWriteCommands } from './commands/write-commands.js';
|
|
8
|
+
const readPackageVersion = () => {
|
|
9
|
+
const packagePath = join(dirname(fileURLToPath(import.meta.url)), '../../package.json');
|
|
10
|
+
const metadata = JSON.parse(readFileSync(packagePath, 'utf8'));
|
|
11
|
+
return metadata.version ?? '0.0.0';
|
|
12
|
+
};
|
|
6
13
|
const program = new Command();
|
|
7
14
|
const cliName = basename(process.argv[1] ?? 'brainlink');
|
|
8
15
|
const displayName = cliName === 'blink' ? 'blink' : 'brainlink';
|
|
@@ -11,7 +18,7 @@ program
|
|
|
11
18
|
.name(displayName)
|
|
12
19
|
.alias(aliasName)
|
|
13
20
|
.description('Local-first knowledge memory for agents')
|
|
14
|
-
.version(
|
|
21
|
+
.version(readPackageVersion());
|
|
15
22
|
registerWriteCommands(program);
|
|
16
23
|
registerReadCommands(program);
|
|
17
24
|
program.parseAsync().catch((error) => {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
+
import { getDefaultVaultPath } from './paths.js';
|
|
3
4
|
export const defaultBrainlinkConfig = {
|
|
4
|
-
vault:
|
|
5
|
+
vault: getDefaultVaultPath(),
|
|
5
6
|
host: '127.0.0.1',
|
|
6
7
|
port: 4321,
|
|
7
8
|
allowedVaults: [],
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { chmod, mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, extname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
3
|
+
import { resolvePath } from './paths.js';
|
|
3
4
|
const excludedDirectories = new Set(['.brainlink', '.git', 'node_modules', 'dist']);
|
|
4
5
|
const directoryMode = 0o700;
|
|
5
6
|
const fileMode = 0o600;
|
|
@@ -14,7 +15,7 @@ const walkMarkdownFiles = async (directory) => {
|
|
|
14
15
|
}));
|
|
15
16
|
return nested.flat();
|
|
16
17
|
};
|
|
17
|
-
export const resolveVaultPath = (vaultPath) =>
|
|
18
|
+
export const resolveVaultPath = (vaultPath) => resolvePath(vaultPath);
|
|
18
19
|
const isPathInside = (parent, child) => {
|
|
19
20
|
const path = relative(parent, child);
|
|
20
21
|
return path === '' || (!path.startsWith('..') && !isAbsolute(path));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
3
|
+
const defaultHomeDirectoryName = '.brainlink';
|
|
4
|
+
const defaultVaultDirectoryName = 'vault';
|
|
5
|
+
export const expandHomePath = (path) => path === '~' || path.startsWith('~/') ? join(homedir(), path.slice(2)) : path;
|
|
6
|
+
export const resolvePath = (path, cwd = process.cwd()) => {
|
|
7
|
+
const expandedPath = expandHomePath(path);
|
|
8
|
+
return isAbsolute(expandedPath) ? expandedPath : resolve(cwd, expandedPath);
|
|
9
|
+
};
|
|
10
|
+
export const getBrainlinkHomePath = () => {
|
|
11
|
+
const configuredHome = process.env.BRAINLINK_HOME?.trim();
|
|
12
|
+
return configuredHome ? resolvePath(configuredHome) : join(homedir(), defaultHomeDirectoryName);
|
|
13
|
+
};
|
|
14
|
+
export const getDefaultVaultPath = () => join(getBrainlinkHomePath(), defaultVaultDirectoryName);
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
const schemaVersion = 4;
|
|
2
|
+
const requiredTableColumns = {
|
|
3
|
+
documents: ['id', 'agent_id', 'title', 'path', 'content', 'tags_json', 'frontmatter_json', 'created_at', 'updated_at'],
|
|
4
|
+
chunks: ['id', 'document_id', 'ordinal', 'content', 'token_count', 'embedding_provider', 'embedding_json'],
|
|
5
|
+
chunks_fts: ['chunk_id', 'document_id', 'agent_id', 'title', 'content']
|
|
6
|
+
};
|
|
2
7
|
const getStoredSchemaVersion = (database) => {
|
|
3
8
|
const hasMetadata = database
|
|
4
9
|
.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'metadata'")
|
|
@@ -18,9 +23,17 @@ const dropDerivedSchema = (database) => {
|
|
|
18
23
|
DROP TABLE IF EXISTS documents;
|
|
19
24
|
`);
|
|
20
25
|
};
|
|
26
|
+
const getTableColumns = (database, tableName) => {
|
|
27
|
+
const rows = database.prepare(`SELECT name FROM pragma_table_info(?)`).all(tableName);
|
|
28
|
+
return rows.map((row) => row.name);
|
|
29
|
+
};
|
|
30
|
+
const hasCompatibleSchemaShape = (database) => Object.entries(requiredTableColumns).every(([tableName, requiredColumns]) => {
|
|
31
|
+
const columns = getTableColumns(database, tableName);
|
|
32
|
+
return columns.length === 0 || requiredColumns.every((column) => columns.includes(column));
|
|
33
|
+
});
|
|
21
34
|
export const createSchema = (database) => {
|
|
22
35
|
const storedSchemaVersion = getStoredSchemaVersion(database);
|
|
23
|
-
if (storedSchemaVersion > 0 && storedSchemaVersion < schemaVersion) {
|
|
36
|
+
if ((storedSchemaVersion > 0 && storedSchemaVersion < schemaVersion) || !hasCompatibleSchemaShape(database)) {
|
|
24
37
|
dropDerivedSchema(database);
|
|
25
38
|
}
|
|
26
39
|
database.exec(`
|
package/docs/AGENT_USAGE.md
CHANGED
|
@@ -29,6 +29,18 @@ blink --help
|
|
|
29
29
|
|
|
30
30
|
Use `blink` as the short terminal alias and `brainlink` in documentation when explicit naming is more important.
|
|
31
31
|
|
|
32
|
+
## Default Vault
|
|
33
|
+
|
|
34
|
+
When `--vault` is omitted, Brainlink uses a user-level vault:
|
|
35
|
+
|
|
36
|
+
```txt
|
|
37
|
+
$HOME/.brainlink/vault
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`blink server` follows the same rule, so it serves the default Brainlink vault instead of the current working directory.
|
|
41
|
+
|
|
42
|
+
Use `--vault <path>` for a one-off custom vault, or set `vault` in `brainlink.config.json` / `.brainlink.json` for a workspace-level custom default. Set `BRAINLINK_HOME` when the whole Brainlink home directory should live somewhere else.
|
|
43
|
+
|
|
32
44
|
## Agent Namespaces
|
|
33
45
|
|
|
34
46
|
Each agent writes into a dedicated namespace under `agents/<agent-id>/`:
|
|
@@ -131,7 +143,7 @@ Rules:
|
|
|
131
143
|
Before answering a memory-dependent question, run:
|
|
132
144
|
|
|
133
145
|
```bash
|
|
134
|
-
blink context "<question>" --
|
|
146
|
+
blink context "<question>" --agent coding-agent
|
|
135
147
|
```
|
|
136
148
|
|
|
137
149
|
Use the returned context as source-grounded memory.
|
|
@@ -139,7 +151,7 @@ Use the returned context as source-grounded memory.
|
|
|
139
151
|
For machine-readable output, use:
|
|
140
152
|
|
|
141
153
|
```bash
|
|
142
|
-
blink context "<question>" --
|
|
154
|
+
blink context "<question>" --agent coding-agent --json
|
|
143
155
|
```
|
|
144
156
|
|
|
145
157
|
If the context is empty or weak:
|
|
@@ -158,20 +170,18 @@ These examples assume the agent can run shell commands in the user workspace.
|
|
|
158
170
|
Run this at the start of a task:
|
|
159
171
|
|
|
160
172
|
```bash
|
|
161
|
-
export BLINK_VAULT=".brainlink-vault"
|
|
162
173
|
export BLINK_AGENT="codex"
|
|
163
|
-
blink init
|
|
164
|
-
blink context "$USER_TASK" --
|
|
174
|
+
blink init
|
|
175
|
+
blink context "$USER_TASK" --agent "$BLINK_AGENT" --mode hybrid --json
|
|
165
176
|
```
|
|
166
177
|
|
|
167
178
|
After discovering durable project knowledge:
|
|
168
179
|
|
|
169
180
|
```bash
|
|
170
181
|
blink add "Implementation Boundary" \
|
|
171
|
-
--vault "$BLINK_VAULT" \
|
|
172
182
|
--agent "$BLINK_AGENT" \
|
|
173
183
|
--content "Keep use cases in application and pure transformations in domain. [[Architecture]] #architecture #typescript"
|
|
174
|
-
blink index
|
|
184
|
+
blink index
|
|
175
185
|
```
|
|
176
186
|
|
|
177
187
|
### Claude Code-Style Agent
|
|
@@ -224,16 +234,19 @@ blink index --vault .brainlink-vault
|
|
|
224
234
|
### Initialize A Vault
|
|
225
235
|
|
|
226
236
|
```bash
|
|
237
|
+
blink init
|
|
227
238
|
blink init ./vault
|
|
228
239
|
```
|
|
229
240
|
|
|
230
241
|
Creates:
|
|
231
242
|
|
|
232
243
|
```txt
|
|
233
|
-
vault/
|
|
244
|
+
$HOME/.brainlink/vault/
|
|
234
245
|
.brainlink/
|
|
235
246
|
```
|
|
236
247
|
|
|
248
|
+
`blink init ./vault` creates a custom vault instead.
|
|
249
|
+
|
|
237
250
|
### Add A Note
|
|
238
251
|
|
|
239
252
|
```bash
|
|
@@ -344,11 +357,14 @@ shared: 30 documents
|
|
|
344
357
|
### Start Graph UI
|
|
345
358
|
|
|
346
359
|
```bash
|
|
360
|
+
blink server --host 127.0.0.1 --port 4321
|
|
347
361
|
blink server --vault ./vault --host 127.0.0.1 --port 4321
|
|
348
362
|
```
|
|
349
363
|
|
|
350
364
|
This starts a local frontend for inspecting the knowledge graph.
|
|
351
365
|
|
|
366
|
+
Without `--vault`, the graph UI serves `$HOME/.brainlink/vault`.
|
|
367
|
+
|
|
352
368
|
The frontend includes an agent selector. Selecting an agent calls the same read APIs with `agent=<agent-id>` and renders that namespace instead of merging every agent into one graph.
|
|
353
369
|
|
|
354
370
|
The command reindexes by default, then serves:
|
package/docs/RELEASE.md
CHANGED
|
@@ -39,12 +39,19 @@ blink server --vault ./tmp-vault --host 0.0.0.0
|
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
10. Confirm no test/demo vault files are included in the package tarball.
|
|
42
|
-
11.
|
|
43
|
-
12.
|
|
42
|
+
11. Confirm the repository has an `NPM_TOKEN` secret with publish permission for `@andespindola/brainlink`.
|
|
43
|
+
12. Create the git tag only after the package name is final.
|
|
44
|
+
13. Publish from GitHub Actions by publishing a GitHub Release for the tag.
|
|
44
45
|
|
|
45
46
|
## Publish Commands
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
The preferred path is the `Publish npm` GitHub Actions workflow:
|
|
49
|
+
|
|
50
|
+
- GitHub Release `published`: runs checks, pack smoke, then publishes to npm with provenance.
|
|
51
|
+
- Manual `workflow_dispatch`: runs a dry run by default. Disable `dry_run` only for an intentional manual publish.
|
|
52
|
+
- Prerelease versions publish under their prerelease dist-tag, for example `0.1.0-alpha.1` publishes with `--tag alpha`.
|
|
53
|
+
|
|
54
|
+
For emergency local publishing of scoped public packages:
|
|
48
55
|
|
|
49
56
|
```bash
|
|
50
57
|
npm publish --access public
|
package/package.json
CHANGED