@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 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 Path
113
+ ### 2. Use The Default Vault Or Choose A Custom Vault
114
114
 
115
- Prefer a project-local vault when memory belongs to one repository:
115
+ By default, Brainlink stores memory in:
116
116
 
117
117
  ```bash
118
- BLINK_VAULT=".brainlink-vault"
118
+ $HOME/.brainlink/vault
119
119
  ```
120
120
 
121
- Use a user-level vault only when memory should span many projects:
121
+ Use the default vault when memory should span many projects:
122
122
 
123
123
  ```bash
124
- BLINK_VAULT="$HOME/.brainlink/vault"
124
+ blink init
125
125
  ```
126
126
 
127
- Initialize the vault:
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 --vault "$BLINK_VAULT"
183
+ blink index
180
184
  ```
181
185
 
182
186
  ### 6. Validate Memory Health
183
187
 
184
188
  ```bash
185
- blink validate --vault "$BLINK_VAULT" --agent "$BLINK_AGENT" --json
186
- blink broken-links --vault "$BLINK_VAULT" --agent "$BLINK_AGENT" --json
187
- blink orphans --vault "$BLINK_VAULT" --agent "$BLINK_AGENT" --json
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>" --vault "$BLINK_VAULT" --agent "$BLINK_AGENT" --json`.
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>" --vault "$BLINK_VAULT" --agent "$BLINK_AGENT" --json
318
- blink add "Decision Title" --vault "$BLINK_VAULT" --agent "$BLINK_AGENT" --content "Durable memory. #decision"
319
- blink index --vault "$BLINK_VAULT"
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 --vault ./vault --host 127.0.0.1 --port 4321 --watch
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 { basename } from 'node:path';
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('0.1.0');
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) => resolve(process.cwd(), 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(`
@@ -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>" --vault ./vault --agent coding-agent
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>" --vault ./vault --agent coding-agent --json
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 "$BLINK_VAULT"
164
- blink context "$USER_TASK" --vault "$BLINK_VAULT" --agent "$BLINK_AGENT" --mode hybrid --json
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 --vault "$BLINK_VAULT"
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. Create the git tag only after the package name is final.
43
- 12. Publish only from a logged-in npm account with permission for the package name.
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
- For scoped public packages:
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andespindola/brainlink",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.0-alpha.2",
4
4
  "description": "Local-first knowledge memory for agents with Markdown, backlinks, indexing and context retrieval.",
5
5
  "type": "module",
6
6
  "license": "MIT",