@gobi-ai/cli 1.0.0 → 1.1.0

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.
@@ -4,12 +4,12 @@
4
4
  "name": "gobi-ai"
5
5
  },
6
6
  "description": "Claude Code plugin for the Gobi collaborative knowledge platform CLI",
7
- "version": "1.0.0",
7
+ "version": "1.1.0",
8
8
  "plugins": [
9
9
  {
10
10
  "name": "gobi",
11
11
  "description": "Manage the Gobi collaborative knowledge platform from the command line. Search and ask vaults, publish vault documents, create threads, manage sessions, generate images and videos.",
12
- "version": "1.0.0",
12
+ "version": "1.1.0",
13
13
  "author": {
14
14
  "name": "gobi-ai"
15
15
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gobi",
3
3
  "description": "Manage the Gobi collaborative knowledge platform from the command line",
4
- "version": "1.0.0",
4
+ "version": "1.1.0",
5
5
  "author": {
6
6
  "name": "gobi-ai"
7
7
  },
package/README.md CHANGED
@@ -71,8 +71,8 @@ gobi vault ask --vault-slug my-vault --question "What is RAG?"
71
71
  |---------|-------------|
72
72
  | `gobi vault search --query <q>` | Search public vaults by text and semantic similarity |
73
73
  | `gobi vault ask --vault-slug <slug> --question <q>` | Ask a vault a question (creates a 1:1 session) |
74
- | `gobi vault publish` | Upload `BRAIN.md` to your vault |
75
- | `gobi vault unpublish` | Remove `BRAIN.md` from your vault |
74
+ | `gobi vault publish` | Upload `PUBLISH.md` to your vault |
75
+ | `gobi vault unpublish` | Remove `PUBLISH.md` from your vault |
76
76
 
77
77
  Public vaults are accessible at `https://gobispace.com/@{vaultSlug}`.
78
78
 
@@ -90,7 +90,7 @@ Public vaults are accessible at `https://gobispace.com/@{vaultSlug}`.
90
90
 
91
91
  ### Threads
92
92
 
93
- > **Migration note:** Brain-update commands have been removed. To post user-level content, use `gobi global create-thread` (platform-wide global) or `gobi space create-thread` (a specific space).
93
+ > **Migration note:** Vault-update (formerly brain-update) commands have been removed. To post user-level content, use `gobi global create-thread` (platform-wide global) or `gobi space create-thread` (a specific space).
94
94
 
95
95
  | Command | Description |
96
96
  |---------|-------------|
@@ -205,11 +205,11 @@ export async function runInitFlow() {
205
205
  writeVaultSetting(vaultId);
206
206
  console.log(`Vault set to "${vaultName}" (${vaultId})`);
207
207
  console.log(`Updated ${SETTINGS_DIR}/${SETTINGS_FILE}`);
208
- // Create default BRAIN.md if it doesn't exist
209
- const brainPath = join(process.cwd(), "BRAIN.md");
210
- if (!existsSync(brainPath)) {
211
- writeFileSync(brainPath, `---\ntitle: ${vaultName}\ntags: []\ndescription:\nthumbnail:\nprompt:\n---\n`, "utf-8");
212
- console.log("Created BRAIN.md");
208
+ // Create default PUBLISH.md if it doesn't exist
209
+ const publishMdPath = join(process.cwd(), "PUBLISH.md");
210
+ if (!existsSync(publishMdPath)) {
211
+ writeFileSync(publishMdPath, `---\ntitle: ${vaultName}\ntags: []\ndescription:\nthumbnail:\nprompt:\n---\n`, "utf-8");
212
+ console.log("Created PUBLISH.md");
213
213
  }
214
214
  }
215
215
  export function registerInitCommand(program) {
@@ -8,7 +8,7 @@ import { isJsonMode, jsonOut, unwrapResp } from "./utils.js";
8
8
  export function registerVaultCommand(program) {
9
9
  const vaultCmd = program
10
10
  .command("vault")
11
- .description("Vault commands. A Vault is your personal knowledge container — search public vaults, ask them questions, and publish your BRAIN.md profile.");
11
+ .description("Vault commands. A Vault is your personal knowledge container — search public vaults, ask them questions, and publish a PUBLISH.md to make a vault public.");
12
12
  // ── Search ──
13
13
  vaultCmd
14
14
  .command("search")
@@ -88,20 +88,18 @@ export function registerVaultCommand(program) {
88
88
  ` Question sent.`);
89
89
  });
90
90
  // ── Publish ──
91
- // Note: file is still named BRAIN.md on webdrive — the post-processing pipeline
92
- // (gobi-webdrive) hardcodes the filename. Rename the file here once that ships.
93
91
  vaultCmd
94
92
  .command("publish")
95
- .description("Upload BRAIN.md to the vault root on webdrive. Triggers post-processing (vault sync, metadata update, Discord notification).")
93
+ .description("Upload PUBLISH.md to the vault root on webdrive. Triggers post-processing (vault sync, metadata update, Discord notification).")
96
94
  .action(async () => {
97
95
  const vaultId = getVaultSlug();
98
- const filePath = join(process.cwd(), "BRAIN.md");
96
+ const filePath = join(process.cwd(), "PUBLISH.md");
99
97
  if (!existsSync(filePath)) {
100
- throw new Error(`BRAIN.md not found in ${process.cwd()}`);
98
+ throw new Error(`PUBLISH.md not found in ${process.cwd()}`);
101
99
  }
102
100
  const content = readFileSync(filePath, "utf-8");
103
101
  const token = await getValidToken();
104
- const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultId}/file/BRAIN.md`;
102
+ const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultId}/file/PUBLISH.md`;
105
103
  const res = await fetch(url, {
106
104
  method: "PUT",
107
105
  headers: {
@@ -117,16 +115,16 @@ export function registerVaultCommand(program) {
117
115
  jsonOut({ vaultId });
118
116
  return;
119
117
  }
120
- console.log(`Published BRAIN.md to vault "${vaultId}"`);
118
+ console.log(`Published PUBLISH.md to vault "${vaultId}"`);
121
119
  });
122
120
  // ── Unpublish ──
123
121
  vaultCmd
124
122
  .command("unpublish")
125
- .description("Delete BRAIN.md from the vault on webdrive.")
123
+ .description("Delete PUBLISH.md from the vault on webdrive.")
126
124
  .action(async () => {
127
125
  const vaultId = getVaultSlug();
128
126
  const token = await getValidToken();
129
- const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultId}/file/BRAIN.md`;
127
+ const url = `${WEBDRIVE_BASE_URL}/api/v1/vaults/${vaultId}/file/PUBLISH.md`;
130
128
  const res = await fetch(url, {
131
129
  method: "DELETE",
132
130
  headers: { Authorization: `Bearer ${token}` },
@@ -138,6 +136,6 @@ export function registerVaultCommand(program) {
138
136
  jsonOut({ vaultId });
139
137
  return;
140
138
  }
141
- console.log(`Deleted BRAIN.md from vault "${vaultId}"`);
139
+ console.log(`Deleted PUBLISH.md from vault "${vaultId}"`);
142
140
  });
143
141
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobi-ai/cli",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "CLI client for the Gobi collaborative knowledge platform",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -39,7 +39,7 @@ brew tap gobi-ai/tap && brew install gobi
39
39
  ## Key Concepts
40
40
 
41
41
  - **Space**: A shared space for a group or community. A logged-in user can be a member of one or more spaces. A space contains threads, sessions, and connected vaults.
42
- - **Vault**: A personal knowledge container — a filetree storage of information and knowledge that can also be searched and asked questions like a knowledge base. A local directory becomes a vault when it contains `.gobi/settings.yaml` with a vault slug and a space slug. Each vault is identified by a slug (e.g. `brave-path-zr962w`). Publish a `BRAIN.md` document at the vault root to configure the vault's public profile and AI agent.
42
+ - **Vault**: A personal knowledge container — a filetree storage of information and knowledge that can also be searched and asked questions like a knowledge base. A local directory becomes a vault when it contains `.gobi/settings.yaml` with a vault slug and a space slug. Each vault is identified by a slug (e.g. `brave-path-zr962w`). Publish a `PUBLISH.md` document at the vault root to configure the vault's public profile and AI agent.
43
43
 
44
44
  ## First-Time Setup
45
45
 
@@ -55,7 +55,7 @@ This is an **interactive** command that:
55
55
  1. Logs in automatically if not already authenticated (opens a browser URL for Google OAuth)
56
56
  2. Prompts the user to select an existing vault or create a new one
57
57
  3. Writes `.gobi/settings.yaml` in the current directory with the chosen vault slug
58
- 4. Creates a `BRAIN.md` file if one doesn't exist
58
+ 4. Creates a `PUBLISH.md` file if one doesn't exist
59
59
 
60
60
  ### Step 2: Select a Space
61
61
 
@@ -127,7 +127,7 @@ JSON responses have the shape `{ "success": true, "data": ... }` on success or `
127
127
  |------|-------------|
128
128
  | `~/.gobi/credentials.json` | Stored authentication tokens (auto-managed) |
129
129
  | `.gobi/settings.yaml` | Per-project vault and space configuration |
130
- | `BRAIN.md` | Vault profile document with YAML frontmatter, published via `gobi vault publish` |
130
+ | `PUBLISH.md` | Vault profile document with YAML frontmatter, published via `gobi vault publish` |
131
131
 
132
132
  ## Environment Variables
133
133
 
@@ -8,7 +8,7 @@ description: >-
8
8
 
9
9
  # Gobi Homepage Developer Guide
10
10
 
11
- A **Gobi Homepage** is a custom HTML page hosted on a vault's webdrive and served as its public homepage at `https://gobispace.com/@{vaultSlug}`. Gobi injects a `window.gobi` bridge before any scripts run, giving the homepage access to vault data, files, brain updates, and chat.
11
+ A **Gobi Homepage** is a custom HTML page hosted on a vault's webdrive and served as its public homepage at `https://gobispace.com/@{vaultSlug}`. Gobi injects a `window.gobi` bridge before any scripts run, giving the homepage access to vault data, files, and chat.
12
12
 
13
13
  > **Sandbox:** The homepage runs in a sandboxed iframe with `origin: null`. Direct `fetch()` / `XMLHttpRequest` calls are blocked by CORS. All data access must go through `window.gobi.*`.
14
14
 
@@ -20,7 +20,7 @@ A **Gobi Homepage** is a custom HTML page hosted on a vault's webdrive and serve
20
20
  ```bash
21
21
  gobi sync
22
22
  ```
23
- 2. Set `homepage` in BRAIN.md (homepage property):
23
+ 2. Set `homepage` in PUBLISH.md (homepage property):
24
24
  - `homepage: "[[app/home.html]]"` — Gobi sidebars visible alongside the homepage
25
25
  - `homepage: "[[app/home.html?nav=false]]"` — full-screen, no Gobi chrome
26
26
 
@@ -67,31 +67,6 @@ function getFileUrl(path) {
67
67
  }
68
68
  ```
69
69
 
70
- ### Brain Updates
71
-
72
- ```js
73
- const { data: updates, pagination } = await gobi.listBrainUpdates({ limit: 10, cursor: null });
74
- // updates[i] → {
75
- // id: 42,
76
- // title: 'New insights',
77
- // content: '## ...', // markdown — MAY contain ![[file|width]] wiki image embeds
78
- // topics: [{ id: 3, name: 'AI', slug: 'ai' }],
79
- // createdAt: '2025-03-01T12:00:00Z'
80
- // }
81
- // pagination → { hasMore: true, nextCursor: 'abc...' }
82
-
83
- // ⚠️ Always call resolveWikiImages() on content before rendering — see Rendering Markdown below.
84
- for (const u of updates) {
85
- el.innerHTML += marked.parse(resolveWikiImages(u.content));
86
- }
87
-
88
- // Pagination — load the next page using the cursor
89
- if (pagination.hasMore) {
90
- const { data: moreUpdates, pagination: nextPage } =
91
- await gobi.listBrainUpdates({ limit: 10, cursor: pagination.nextCursor });
92
- }
93
- ```
94
-
95
70
  ### Chat (login required)
96
71
 
97
72
  `getSessions`, `loadMessages`, and `sendMessage` require the visitor to be logged in. `getSessions` returns an empty array when not logged in — **but also when logged in with no prior sessions**. Don't use it as a definitive auth check.
@@ -119,7 +94,7 @@ const { messages, hasMore, nextCursor } = await gobi.loadMessages('sess_abc', {
119
94
  // sendMessage(sessionId, text, options, onDelta) → Promise<{ content }>
120
95
  //
121
96
  // options.context tells the AI what the user is looking at:
122
- // { brainUpdateId?: number, brainUpdateTitle?: string, filePath?: string }
97
+ // { filePath?: string }
123
98
 
124
99
  let reply = '';
125
100
  await gobi.sendMessage(sessionId, 'Hello', (delta) => {
@@ -128,10 +103,6 @@ await gobi.sendMessage(sessionId, 'Hello', (delta) => {
128
103
  });
129
104
 
130
105
  // With context
131
- await gobi.sendMessage(sessionId, 'Tell me more', {
132
- context: { brainUpdateId: 42, brainUpdateTitle: 'New insights' }
133
- }, (delta) => { reply += delta; renderReply(reply); });
134
-
135
106
  await gobi.sendMessage(sessionId, 'Explain this', {
136
107
  context: { filePath: 'notes/research.md' }
137
108
  }, (delta) => { reply += delta; renderReply(reply); });
@@ -144,7 +115,7 @@ sessionId = crypto.randomUUID();
144
115
 
145
116
  ## Rendering Markdown
146
117
 
147
- Brain update `content` and any markdown read via `readFile` may contain Obsidian-style wiki embeds (`![[path|width]]`). Resolve them before passing to a renderer.
118
+ Markdown read via `readFile` may contain Obsidian-style wiki embeds (`![[path|width]]`). Resolve them before passing to a renderer.
148
119
 
149
120
  The examples below use [marked](https://cdn.jsdelivr.net/npm/marked/marked.min.js) — include it in your `<head>`:
150
121
 
@@ -162,7 +133,7 @@ function resolveWikiImages(md) {
162
133
  });
163
134
  }
164
135
 
165
- const html = marked.parse(resolveWikiImages(update.content));
136
+ const html = marked.parse(resolveWikiImages(text));
166
137
  ```
167
138
 
168
139
  **Open links in a new tab.** The homepage runs in a sandboxed iframe — clicking a rendered link replaces the iframe with the external page. Override the renderer so every `<a>` opens in a new tab:
@@ -175,7 +146,7 @@ renderer.link = (href, title, text) =>
175
146
  marked.setOptions({ renderer });
176
147
  ```
177
148
 
178
- **Plain-text previews.** For BU list cards, render a truncated preview with `escapeHtml(content.substring(0, 200))` — don't run markdown on a random substring, it produces broken HTML. Use `marked.parse(resolveWikiImages(content))` only for the full expanded view. Same for chat: `marked.parse(content)` for assistant messages, `escapeHtml(content)` for human messages.
149
+ **Plain-text previews.** For preview cards, render a truncated preview with `escapeHtml(content.substring(0, 200))` — don't run markdown on a random substring, it produces broken HTML. Use `marked.parse(resolveWikiImages(content))` only for the full expanded view. Same for chat: `marked.parse(content)` for assistant messages, `escapeHtml(content)` for human messages.
179
150
 
180
151
  ---
181
152
 
@@ -202,58 +173,9 @@ Centralize colors and spacing in CSS custom properties so restyling is a one-lin
202
173
 
203
174
  Pair with Google Fonts (e.g. Space Grotesk for headings, IBM Plex Mono for meta, Inter for body) via CDN `<link>`.
204
175
 
205
- ### Knowledge Graph from BU topics
206
-
207
- Brain updates carry a `topics` array. Treat each topic as a node and any two topics co-occurring in the same BU as an edge — you get a force-directed graph of the vault's themes for free. Use [d3](https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js).
208
-
209
- ```js
210
- // Separate data-building from rendering so the same graph can be drawn at multiple sizes.
211
- function buildGraphData(updates) {
212
- const counts = new Map(); // name → frequency
213
- const edges = new Map(); // "a|b" → weight
214
- for (const u of updates) {
215
- const names = (u.topics || []).map(t => t.name);
216
- for (const n of names) counts.set(n, (counts.get(n) || 0) + 1);
217
- for (let i = 0; i < names.length; i++)
218
- for (let j = i + 1; j < names.length; j++) {
219
- const key = [names[i], names[j]].sort().join('|');
220
- edges.set(key, (edges.get(key) || 0) + 1);
221
- }
222
- }
223
- // Top 20 by frequency, then drop orphans (nodes with no surviving edges).
224
- const top = [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 20).map(([n]) => n);
225
- const keep = new Set(top);
226
- const links = [...edges].flatMap(([k, w]) => {
227
- const [a, b] = k.split('|');
228
- return keep.has(a) && keep.has(b) ? [{ source: a, target: b, weight: w }] : [];
229
- });
230
- const connected = new Set(links.flatMap(l => [l.source, l.target]));
231
- const nodes = top.filter(n => connected.has(n)).map(n => ({ id: n, count: counts.get(n) }));
232
- return { nodes, links };
233
- }
234
-
235
- function drawGraph(containerId, w, h, data, opts = {}) {
236
- const { nodeRange = [4, 16], fontSize = '9px', distance = 60, charge = -80 } = opts;
237
- const max = Math.max(...data.nodes.map(n => n.count), 1);
238
- const r = d3.scaleSqrt().domain([1, max]).range(nodeRange);
239
- const svg = d3.select('#' + containerId).append('svg').attr('width', w).attr('height', h);
240
- // ... standard d3.forceSimulation with link/charge/center, then clamp in tick:
241
- // node.attr('cx', d => d.x = Math.max(20, Math.min(w - 20, d.x)))
242
- // node.attr('cy', d => d.y = Math.max(20, Math.min(h - 20, d.y)))
243
- // Node fill: accent with opacity 0.3 + 0.7 * (count/max).
244
- // Call d3.drag() on nodes so visitors can rearrange the graph.
245
- }
246
- ```
247
-
248
- Tips:
249
- - **Enrich the data.** One page of 8 BUs makes a sparse graph. Paginate 3–4 times (cap at ~32 BUs) before building.
250
- - **Cache the built data** in a module-level variable so the full-screen overlay can reuse it without refetching.
251
- - **Mini vs full presets.** Pass different `opts` — e.g. mini `{nodeRange:[4,16], fontSize:'9px', distance:60, charge:-80}`, full `{nodeRange:[8,32], fontSize:'12px', distance:120, charge:-200}`.
252
- - Run a **separate simulation** for the full-scale instance — copy the nodes/links rather than sharing references, otherwise both graphs fight over the same positions.
253
-
254
176
  ### Full-screen overlay
255
177
 
256
- Useful for expanding the K-Graph (or any small component) into a focused view:
178
+ Useful for expanding any small component into a focused view:
257
179
 
258
180
  ```js
259
181
  function openOverlay(renderInto) {
@@ -272,27 +194,12 @@ function openOverlay(renderInto) {
272
194
 
273
195
  Always restore `body.overflow` on close, and always remove the `keydown` listener.
274
196
 
275
- ### Brain update card — preview/full toggle
276
-
277
- Show a truncated card that expands in place on click:
278
-
279
- ```js
280
- card.onclick = (event) => {
281
- // Link click guard — don't toggle when the user clicked a link inside the card.
282
- if (event.target.closest('a')) return;
283
- card.classList.toggle('expanded');
284
- card.querySelector('.body').innerHTML = card.classList.contains('expanded')
285
- ? marked.parse(resolveWikiImages(update.content))
286
- : escapeHtml(update.content.substring(0, 200));
287
- };
288
- ```
289
-
290
197
  ### Chat suggestion chips
291
198
 
292
199
  Empty chat looks dead. Show clickable prompt chips until the first message is sent:
293
200
 
294
201
  ```js
295
- const prompts = ['What is this brain about?', 'Summarize the latest update', 'What topics come up most?'];
202
+ const prompts = ['What is this vault about?', 'Summarize the latest notes', 'What topics come up most?'];
296
203
  chips.innerHTML = prompts.map(p => `<button class="chip">${escapeHtml(p)}</button>`).join('');
297
204
  chips.querySelectorAll('.chip').forEach((btn, i) => {
298
205
  btn.onclick = () => { input.value = prompts[i]; chips.remove(); input.focus(); };
@@ -317,7 +224,7 @@ Single breakpoint at `768px` is enough for most homepages:
317
224
 
318
225
  ```css
319
226
  @media (max-width: 768px) {
320
- .hero-grid, .updates-grid { grid-template-columns: 1fr; }
227
+ .hero-grid { grid-template-columns: 1fr; }
321
228
  .hero-content { flex-direction: column; }
322
229
  .btn { width: 100%; }
323
230
  }
@@ -336,9 +243,9 @@ Single breakpoint at `768px` is enough for most homepages:
336
243
  <style>
337
244
  * { box-sizing: border-box; margin: 0; padding: 0; }
338
245
  body { font-family: system-ui, sans-serif; max-width: 720px; margin: 0 auto; padding: 24px; }
339
- .update { margin-bottom: 32px; }
340
- .update h2 { margin-bottom: 8px; }
341
- .update img { border-radius: 8px; }
246
+ .hero { margin-bottom: 32px; }
247
+ .hero h1 { margin-bottom: 8px; }
248
+ .hero p { color: #555; }
342
249
  #chat { margin-top: 40px; border-top: 1px solid #ddd; padding-top: 24px; }
343
250
  .message { margin-bottom: 12px; padding: 8px 12px; border-radius: 8px; }
344
251
  .message[data-role="human"] { background: #e8f0fe; }
@@ -351,7 +258,10 @@ Single breakpoint at `768px` is enough for most homepages:
351
258
  </style>
352
259
  </head>
353
260
  <body>
354
- <div id="updates"></div>
261
+ <div class="hero">
262
+ <h1 id="title"></h1>
263
+ <p id="description"></p>
264
+ </div>
355
265
  <div id="chat">
356
266
  <div id="messages"></div>
357
267
  <div id="chat-input">
@@ -361,7 +271,9 @@ Single breakpoint at `768px` is enough for most homepages:
361
271
  </div>
362
272
 
363
273
  <script>
364
- document.title = gobi.vault.title || 'Brain';
274
+ document.title = gobi.vault.title || 'Vault';
275
+ document.getElementById('title').textContent = gobi.vault.title || '';
276
+ document.getElementById('description').textContent = gobi.vault.description || '';
365
277
 
366
278
  // ── Helpers ──────────────────────────────────────
367
279
 
@@ -389,23 +301,6 @@ Single breakpoint at `768px` is enough for most homepages:
389
301
  `https://gobispace.com/login?redirect_uri=${encodeURIComponent(window.location.href)}`;
390
302
  }
391
303
 
392
- // ── Brain updates ────────────────────────────────
393
-
394
- async function loadUpdates() {
395
- try {
396
- const { data: updates } = await gobi.listBrainUpdates({ limit: 5 });
397
- const el = document.getElementById('updates');
398
- for (const u of updates) {
399
- const div = document.createElement('div');
400
- div.className = 'update';
401
- div.innerHTML = `<h2>${escapeHtml(u.title)}</h2>${marked.parse(resolveWikiImages(u.content))}`;
402
- el.appendChild(div);
403
- }
404
- } catch (err) {
405
- console.error('Failed to load brain updates:', err);
406
- }
407
- }
408
-
409
304
  // ── Chat ─────────────────────────────────────────
410
305
 
411
306
  let sessionId = null;
@@ -466,7 +361,6 @@ Single breakpoint at `768px` is enough for most homepages:
466
361
 
467
362
  // ─────────────────────────────────────────────────
468
363
 
469
- loadUpdates();
470
364
  initChat();
471
365
  </script>
472
366
  </body>
@@ -3,23 +3,23 @@ name: gobi-vault
3
3
  description: >-
4
4
  Gobi vault commands for knowledge management: search public vaults by text
5
5
  and semantic similarity, ask vaults questions, and publish/unpublish
6
- BRAIN.md. Use when the user wants to search knowledge, ask a vault, or
6
+ PUBLISH.md. Use when the user wants to search knowledge, ask a vault, or
7
7
  publish their vault document.
8
8
  allowed-tools: Bash(gobi:*)
9
9
  metadata:
10
10
  author: gobi-ai
11
- version: "1.0.0"
11
+ version: "1.1.0"
12
12
  ---
13
13
 
14
14
  # gobi-vault
15
15
 
16
- Gobi vault commands for knowledge management (v1.0.0).
16
+ Gobi vault commands for knowledge management (v1.1.0).
17
17
 
18
18
  Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
19
19
 
20
20
  ## Gobi Vault — Knowledge Management
21
21
 
22
- `gobi vault` commands manage your vault: search public vaults, ask them questions, and publish/unpublish your `BRAIN.md`. Public vaults are accessible at `https://gobispace.com/@{vaultSlug}`.
22
+ `gobi vault` commands manage your vault: search public vaults, ask them questions, and publish/unpublish your `PUBLISH.md`. Public vaults are accessible at `https://gobispace.com/@{vaultSlug}`.
23
23
 
24
24
  > **Vault updates have moved to threads.** To post user-level content, use `gobi global create-thread` (platform-wide global) or `gobi space create-thread` (a specific space). See the **gobi-space** skill.
25
25
 
@@ -35,12 +35,12 @@ gobi --json vault search --query "machine learning"
35
35
 
36
36
  - `gobi vault search` — Search public vaults by text and semantic similarity.
37
37
  - `gobi vault ask` — Ask a vault a question. Creates a targeted session (1:1 conversation).
38
- - `gobi vault publish` — Upload BRAIN.md to the vault root on webdrive. Triggers post-processing (vault sync, metadata update, Discord notification).
39
- - `gobi vault unpublish` — Delete BRAIN.md from the vault on webdrive.
38
+ - `gobi vault publish` — Upload PUBLISH.md to the vault root on webdrive. Triggers post-processing (vault sync, metadata update, Discord notification).
39
+ - `gobi vault unpublish` — Delete PUBLISH.md from the vault on webdrive.
40
40
 
41
- ## BRAIN.md Frontmatter Reference
41
+ ## PUBLISH.md Frontmatter Reference
42
42
 
43
- `BRAIN.md` is the metadata file at the root of every vault. Its YAML frontmatter controls the vault's public profile, homepage, and AI agent behavior. Example:
43
+ `PUBLISH.md` is the metadata file at the root of every vault. Its YAML frontmatter controls the vault's public profile, homepage, and AI agent behavior. Example:
44
44
 
45
45
  ```yaml
46
46
  ---
@@ -49,7 +49,7 @@ tags:
49
49
  - topic1
50
50
  - topic2
51
51
  description: A short description of what this vault is about.
52
- thumbnail: "[[BRAIN.png]]"
52
+ thumbnail: "[[VAULT.png]]"
53
53
  homepage: "[[app/home.html?nav=false]]"
54
54
  prompt: "[[system-prompt.md]]"
55
55
  ---
@@ -69,7 +69,7 @@ prompt: "[[system-prompt.md]]"
69
69
  # Inline array
70
70
  tags: [ambient ai, wearables]
71
71
  ```
72
- - **`thumbnail`** — Profile image for the vault card. Uses wiki-link syntax pointing to an image file in the vault (e.g. `"[[BRAIN.png]]"`).
72
+ - **`thumbnail`** — Profile image for the vault card. Uses wiki-link syntax pointing to an image file in the vault (e.g. `"[[VAULT.png]]"`).
73
73
  - **`homepage`** — Custom HTML page to serve as the vault's public homepage at `gobispace.com/@{vaultSlug}`. Uses wiki-link syntax pointing to an HTML file in the vault. Supports a `nav` query parameter to control Gobi's sidebar navigation:
74
74
  - `"[[app/home.html]]"` — Shows the Gobi sidebar alongside the homepage (default)
75
75
  - `"[[app/home.html?nav=false]]"` — Full-screen, no Gobi sidebar/chrome
@@ -79,9 +79,9 @@ prompt: "[[system-prompt.md]]"
79
79
 
80
80
  ## Publishing Workflow
81
81
 
82
- After editing `BRAIN.md` frontmatter, follow these steps to make your changes live:
82
+ After editing `PUBLISH.md` frontmatter, follow these steps to make your changes live:
83
83
 
84
- 1. **Edit `BRAIN.md`** in the vault root with the desired frontmatter fields.
84
+ 1. **Edit `PUBLISH.md`** in the vault root with the desired frontmatter fields.
85
85
  2. **Sync referenced files** — if the homepage HTML, thumbnail image, or prompt file is new or updated, upload them first:
86
86
  ```bash
87
87
  gobi sync
@@ -90,10 +90,10 @@ After editing `BRAIN.md` frontmatter, follow these steps to make your changes li
90
90
  ```bash
91
91
  gobi vault publish
92
92
  ```
93
- This uploads `BRAIN.md` to webdrive, triggers post-processing that extracts metadata (title, description, tags, thumbnail, homepage path), updates the vault's public profile, and sends a Discord notification.
93
+ This uploads `PUBLISH.md` to webdrive, triggers post-processing that extracts metadata (title, description, tags, thumbnail, homepage path), updates the vault's public profile, and sends a Discord notification.
94
94
  4. The vault is now live at `https://gobispace.com/@{vaultSlug}`.
95
95
 
96
- > **Important:** Any time you change `BRAIN.md` frontmatter (e.g. adding or updating `homepage`), you must re-run `gobi vault publish` for the changes to take effect.
96
+ > **Important:** Any time you change `PUBLISH.md` frontmatter (e.g. adding or updating `homepage`), you must re-run `gobi vault publish` for the changes to take effect.
97
97
 
98
98
  ## Reference Documentation
99
99
 
@@ -3,7 +3,7 @@
3
3
  ```
4
4
  Usage: gobi vault [options] [command]
5
5
 
6
- Vault commands. A Vault is your personal knowledge container — search public vaults, ask them questions, and publish your BRAIN.md profile.
6
+ Vault commands. A Vault is your personal knowledge container — search public vaults, ask them questions, and publish a PUBLISH.md to make a vault public.
7
7
 
8
8
  Options:
9
9
  -h, --help display help for command
@@ -11,8 +11,8 @@ Options:
11
11
  Commands:
12
12
  search [options] Search public vaults by text and semantic similarity.
13
13
  ask [options] Ask a vault a question. Creates a targeted session (1:1 conversation).
14
- publish Upload BRAIN.md to the vault root on webdrive. Triggers post-processing (vault sync, metadata update, Discord notification).
15
- unpublish Delete BRAIN.md from the vault on webdrive.
14
+ publish Upload PUBLISH.md to the vault root on webdrive. Triggers post-processing (vault sync, metadata update, Discord notification).
15
+ unpublish Delete PUBLISH.md from the vault on webdrive.
16
16
  help [command] display help for command
17
17
  ```
18
18
 
@@ -48,7 +48,7 @@ Options:
48
48
  ```
49
49
  Usage: gobi vault publish [options]
50
50
 
51
- Upload BRAIN.md to the vault root on webdrive. Triggers post-processing (vault sync, metadata update, Discord notification).
51
+ Upload PUBLISH.md to the vault root on webdrive. Triggers post-processing (vault sync, metadata update, Discord notification).
52
52
 
53
53
  Options:
54
54
  -h, --help display help for command
@@ -59,7 +59,7 @@ Options:
59
59
  ```
60
60
  Usage: gobi vault unpublish [options]
61
61
 
62
- Delete BRAIN.md from the vault on webdrive.
62
+ Delete PUBLISH.md from the vault on webdrive.
63
63
 
64
64
  Options:
65
65
  -h, --help display help for command