@gobi-ai/cli 2.0.0 → 2.0.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +126 -25
- package/commands/space-share.md +2 -2
- package/dist/attachments.js +2 -1
- package/dist/commands/draft.js +2 -3
- package/dist/commands/global.js +10 -5
- package/dist/commands/saved.js +3 -4
- package/dist/commands/space.js +30 -15
- package/dist/commands/update.js +14 -8
- package/dist/commands/utils.js +6 -0
- package/package.json +1 -1
- package/skills/gobi-core/SKILL.md +17 -11
- package/skills/gobi-draft/SKILL.md +3 -3
- package/skills/gobi-homepage/SKILL.md +14 -12
- package/skills/gobi-media/SKILL.md +2 -2
- package/skills/gobi-saved/SKILL.md +2 -2
- package/skills/gobi-sense/SKILL.md +8 -4
- package/skills/gobi-space/SKILL.md +38 -24
- package/skills/gobi-space/references/global.md +5 -4
- package/skills/gobi-space/references/space.md +4 -4
- package/skills/gobi-vault/SKILL.md +2 -2
|
@@ -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": "
|
|
7
|
+
"version": "2.0.1",
|
|
8
8
|
"plugins": [
|
|
9
9
|
{
|
|
10
10
|
"name": "gobi",
|
|
11
11
|
"description": "Manage the Gobi collaborative knowledge platform from the command line. Publish vault profiles, create posts and replies, manage saved notes and posts, manage sessions, generate images and videos.",
|
|
12
|
-
"version": "
|
|
12
|
+
"version": "2.0.1",
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "gobi-ai"
|
|
15
15
|
},
|
package/README.md
CHANGED
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@gobi-ai/cli)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The programmatic interface to [Gobi](https://gobispace.com) — the agent-facing surface of the ecosystem. The same capabilities the desktop and web clients use (auth, vault sync and publishing, personal posts and replies, saved knowledge, drafts, media generation, activity reads) exposed as composable shell commands so AI agents and developer scripts can participate in a user's Brain.
|
|
8
|
+
|
|
9
|
+
## Why a CLI?
|
|
10
|
+
|
|
11
|
+
Most Gobi capabilities are interactive surfaces (Desktop, Web, Mobile). The CLI flips that: every command is scriptable, returns structured JSON when asked, and uses headless device-code auth so an agent can run it on any host. If you're building an agent that needs to read from or write to a user's Brain — capture notes, post to a community space, save a snippet, draft a suggestion, generate an image — this is the surface.
|
|
8
12
|
|
|
9
13
|
## Installation
|
|
10
14
|
|
|
@@ -34,10 +38,10 @@ npm link
|
|
|
34
38
|
## Quick start
|
|
35
39
|
|
|
36
40
|
```sh
|
|
37
|
-
# Initialize —
|
|
41
|
+
# Initialize — log in and set up your vault (creates PUBLISH.md if missing)
|
|
38
42
|
gobi init
|
|
39
43
|
|
|
40
|
-
# Select a space
|
|
44
|
+
# Select a community space
|
|
41
45
|
gobi space warp
|
|
42
46
|
|
|
43
47
|
# Publish your vault profile (after editing PUBLISH.md frontmatter)
|
|
@@ -46,18 +50,71 @@ gobi vault publish
|
|
|
46
50
|
# Sync local files with the webdrive
|
|
47
51
|
gobi vault sync
|
|
48
52
|
|
|
49
|
-
# Browse the global feed and create a post
|
|
53
|
+
# Browse the global feed and create a personal post
|
|
50
54
|
gobi global feed
|
|
51
|
-
gobi global create-post --title "Hello" --content "Trying gobi"
|
|
55
|
+
gobi global create-post --title "Hello" --content "Trying gobi" --vault-slug my-vault
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Using gobi from an agent
|
|
61
|
+
|
|
62
|
+
Everything below applies whether you're building a Claude Code skill, an autonomous agent, or a shell script. The CLI was designed to be agent-driven first.
|
|
63
|
+
|
|
64
|
+
### JSON envelope
|
|
65
|
+
|
|
66
|
+
Pass `--json` as a **global flag** (before the subcommand) and every command returns a structured envelope:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
gobi --json space list-posts
|
|
70
|
+
# {"success": true, "data": [...]}
|
|
71
|
+
|
|
72
|
+
gobi --json space get-post 99999
|
|
73
|
+
# {"success": false, "error": "Post not found"}
|
|
52
74
|
```
|
|
53
75
|
|
|
76
|
+
`success: true` always carries `data`; `success: false` always carries `error`. Pagination metadata (`pagination: { hasMore, nextCursor }`) ships alongside `data` on list endpoints. Skill docs and the `--help` output describe each command's `data` shape.
|
|
77
|
+
|
|
78
|
+
### Context discovery
|
|
79
|
+
|
|
80
|
+
The CLI looks up two pieces of state:
|
|
81
|
+
|
|
82
|
+
| Path | What | Who manages |
|
|
83
|
+
|------|------|-------------|
|
|
84
|
+
| `~/.gobi/credentials.json` | Auth tokens (`accessToken`, `refreshToken`) | `gobi auth login` writes; `gobi auth logout` clears |
|
|
85
|
+
| `.gobi/settings.yaml` | Per-project `vaultSlug` and `selectedSpaceSlug` | `gobi init` and `gobi space warp` write |
|
|
86
|
+
|
|
87
|
+
An agent should check these before calling commands that need a vault or space:
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
# Are we authenticated?
|
|
91
|
+
gobi --json auth status
|
|
92
|
+
|
|
93
|
+
# Discover the project's defaults
|
|
94
|
+
cat .gobi/settings.yaml 2>/dev/null
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If `.gobi/settings.yaml` is missing, `gobi init` and `gobi space warp` are the interactive entry points — they require user input, so an agent should hand off to the user rather than trying to drive them silently.
|
|
98
|
+
|
|
99
|
+
Every command that depends on a vault or space accepts an explicit override (`--vault-slug`, `--space-slug`) so an agent can act without ambient state.
|
|
100
|
+
|
|
101
|
+
### Headless auth
|
|
102
|
+
|
|
103
|
+
`gobi auth login` is a device-code flow: it prints a URL and a user code to stdout, then polls. An agent can run it as a background task, surface the URL to the user as a clickable link, and wait for the process to exit. See [`commands/login.md`](commands/login.md) for the canonical agent recipe.
|
|
104
|
+
|
|
105
|
+
### Per-session context for drafts
|
|
106
|
+
|
|
107
|
+
When the runtime exports `GOBI_SESSION_ID`, `gobi draft add` picks it up automatically — no need to pass `--session` from inside an agent run. See the **Drafts** section below.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
54
111
|
## Commands
|
|
55
112
|
|
|
56
113
|
### Authentication
|
|
57
114
|
|
|
58
115
|
| Command | Description |
|
|
59
116
|
|---------|-------------|
|
|
60
|
-
| `gobi auth login` | Sign in via device
|
|
117
|
+
| `gobi auth login` | Sign in via device-code flow |
|
|
61
118
|
| `gobi auth status` | Show current auth status |
|
|
62
119
|
| `gobi auth logout` | Sign out and clear credentials |
|
|
63
120
|
|
|
@@ -75,7 +132,7 @@ gobi global create-post --title "Hello" --content "Trying gobi"
|
|
|
75
132
|
|---------|-------------|
|
|
76
133
|
| `gobi vault publish` | Upload `PUBLISH.md` to your vault. Triggers profile/metadata refresh. |
|
|
77
134
|
| `gobi vault unpublish` | Remove `PUBLISH.md` from your vault. |
|
|
78
|
-
| `gobi vault sync` | Sync local vault files with Gobi
|
|
135
|
+
| `gobi vault sync` | Sync local vault files with Gobi WebDrive. |
|
|
79
136
|
|
|
80
137
|
Public vaults are accessible at `https://gobispace.com/@{vaultSlug}`.
|
|
81
138
|
|
|
@@ -96,6 +153,8 @@ Public vaults are accessible at `https://gobispace.com/@{vaultSlug}`.
|
|
|
96
153
|
|
|
97
154
|
### Spaces
|
|
98
155
|
|
|
156
|
+
A *Space* is a community knowledge area. A *Space Post* lives in one space. The same `Post` data type, in a different scope, is a *Personal Post* (see Global feed below) — so anything you can do to a Space Post you can do to a Personal Post.
|
|
157
|
+
|
|
99
158
|
> Space and member administration (creating spaces, inviting/approving members, joining/leaving) is web-UI only and not available in the CLI.
|
|
100
159
|
|
|
101
160
|
| Command | Description |
|
|
@@ -106,29 +165,31 @@ Public vaults are accessible at `https://gobispace.com/@{vaultSlug}`.
|
|
|
106
165
|
| `gobi space list-topic-posts <topicSlug>` | List posts tagged with a topic |
|
|
107
166
|
| `gobi space list-posts` | List posts in the space |
|
|
108
167
|
| `gobi space get-post <postId>` | Get a post with its ancestors and replies |
|
|
109
|
-
| `gobi space create-post --title <t> --content <c
|
|
110
|
-
| `gobi space edit-post <postId> [--title <t>] [--content <c>]` | Edit a post
|
|
111
|
-
| `gobi space delete-post <postId>` | Delete a post |
|
|
112
|
-
| `gobi space create-reply <postId> --content <c>` | Reply to a post |
|
|
168
|
+
| `gobi space create-post --title <t> --content <c> [--vault-slug <slug>] [--auto-attachments]` | Create a space post. `--vault-slug` attributes it to a vault you own; `--auto-attachments` uploads `[[wikilinks]]` to that vault and uses it as `authorVaultSlug`. |
|
|
169
|
+
| `gobi space edit-post <postId> [--title <t>] [--content <c>] [--vault-slug <slug>] [--auto-attachments]` | Edit a space post. `--vault-slug ""` detaches the vault. |
|
|
170
|
+
| `gobi space delete-post <postId>` | Delete a space post |
|
|
171
|
+
| `gobi space create-reply <postId> --content <c>` | Reply to a space post |
|
|
113
172
|
| `gobi space edit-reply <replyId> --content <c>` | Edit a reply |
|
|
114
173
|
| `gobi space delete-reply <replyId>` | Delete a reply |
|
|
115
174
|
|
|
116
|
-
### Global feed
|
|
175
|
+
### Global feed (personal posts)
|
|
117
176
|
|
|
118
|
-
|
|
177
|
+
A *Personal Post* lives on the author's profile (their primary vault) and surfaces in the public global feed. Same `Post` model as a Space Post, scoped to the user instead of a space.
|
|
119
178
|
|
|
120
179
|
| Command | Description |
|
|
121
180
|
|---------|-------------|
|
|
122
181
|
| `gobi global feed` | List the global public feed (posts + replies, newest first) |
|
|
123
|
-
| `gobi global list-posts [--mine] [--vault-slug <slug>]` | List posts
|
|
124
|
-
| `gobi global get-post <postId>` | Get a
|
|
125
|
-
| `gobi global create-post [--title <t>] (--content <c> \| --rich-text <json>)` | Create a post
|
|
126
|
-
| `gobi global edit-post <postId> [--title <t>] [--content <c>]` | Edit a post you authored |
|
|
127
|
-
| `gobi global delete-post <postId>` | Delete a post you authored |
|
|
128
|
-
| `gobi global create-reply <postId> (--content <c> \| --rich-text <json>)` | Reply to a
|
|
182
|
+
| `gobi global list-posts [--mine] [--vault-slug <slug>]` | List personal posts; filter to your own or by author vault |
|
|
183
|
+
| `gobi global get-post <postId>` | Get a personal post with its ancestors and replies |
|
|
184
|
+
| `gobi global create-post [--title <t>] (--content <c> \| --rich-text <json>) [--vault-slug <slug>] [--auto-attachments]` | Create a personal post |
|
|
185
|
+
| `gobi global edit-post <postId> [--title <t>] [--content <c>] [--vault-slug <slug>]` | Edit a personal post you authored. `--vault-slug ""` detaches the vault. |
|
|
186
|
+
| `gobi global delete-post <postId>` | Delete a personal post you authored |
|
|
187
|
+
| `gobi global create-reply <postId> (--content <c> \| --rich-text <json>)` | Reply to a personal post |
|
|
129
188
|
| `gobi global edit-reply <replyId> --content <c>` | Edit a reply you authored |
|
|
130
189
|
| `gobi global delete-reply <replyId>` | Delete a reply you authored |
|
|
131
190
|
|
|
191
|
+
`--vault-slug` requires that the caller hold `role: 'owner'` on the target vault. When set, it becomes the post's `authorVaultSlug`. When `--auto-attachments` is set, the same vault is used both as the upload destination for `[[wikilinks]]` and as `authorVaultSlug`.
|
|
192
|
+
|
|
132
193
|
### Sessions
|
|
133
194
|
|
|
134
195
|
| Command | Description |
|
|
@@ -141,6 +202,8 @@ The global feed is the public, slugless feed of vault-authored posts visible acr
|
|
|
141
202
|
|
|
142
203
|
### Sense
|
|
143
204
|
|
|
205
|
+
Activity and transcription data captured by Gobi Sense (or the mobile app).
|
|
206
|
+
|
|
144
207
|
| Command | Description |
|
|
145
208
|
|---------|-------------|
|
|
146
209
|
| `gobi sense activities --start-time <iso> --end-time <iso>` | Fetch activity records in a time range |
|
|
@@ -159,7 +222,7 @@ Times are ISO 8601 UTC (e.g. `2026-03-20T00:00:00Z`).
|
|
|
159
222
|
| `gobi saved note list [--date YYYY-MM-DD]` | List your notes (recent via cursor, or all for a day) |
|
|
160
223
|
| `gobi saved note get <id>` | Get a single note |
|
|
161
224
|
| `gobi saved note create --content <c>` | Create a note (use `-` to read content from stdin) |
|
|
162
|
-
| `gobi saved note edit <id> [--content <c>] [--agent-id <id>]` | Edit a note (
|
|
225
|
+
| `gobi saved note edit <id> [--content <c>] [--agent-id <id>]` | Edit a note (`--agent-id null` clears the link) |
|
|
163
226
|
| `gobi saved note delete <id>` | Delete a note you authored |
|
|
164
227
|
|
|
165
228
|
`saved note list` and `saved note create` accept `--timezone <iana>` (default: system timezone).
|
|
@@ -170,30 +233,46 @@ Times are ISO 8601 UTC (e.g. `2026-03-20T00:00:00Z`).
|
|
|
170
233
|
|---------|-------------|
|
|
171
234
|
| `gobi saved post list [--type all\|article\|space-post]` | List posts you've saved |
|
|
172
235
|
| `gobi saved post get <postId>` | Get a saved post snapshot |
|
|
173
|
-
| `gobi saved post create --source <id>` | Save a post or reply by id |
|
|
236
|
+
| `gobi saved post create --source <id>` | Save a post or reply by id (records a snapshot) |
|
|
174
237
|
| `gobi saved post delete <postId>` | Remove a post from your saved collection |
|
|
175
238
|
|
|
176
239
|
### Drafts
|
|
177
240
|
|
|
178
|
-
|
|
241
|
+
A *draft* is a unit of standing guidance authored by an agent. Each draft carries 0–3 AI-suggested action labels the user picks from. The top 5 pending drafts (lowest priority first) are injected into the agent's system prompt every turn — drafts turn agent suggestions into running context.
|
|
242
|
+
|
|
243
|
+
When invoked from inside an agent run, the runtime exports `GOBI_SESSION_ID` so `gobi draft add` picks it up automatically; otherwise pass `--session <uuid>`.
|
|
179
244
|
|
|
180
245
|
| Command | Description |
|
|
181
246
|
|---------|-------------|
|
|
182
247
|
| `gobi draft list [--limit N]` | List drafts (priority ASC, then newest first) |
|
|
183
248
|
| `gobi draft get <id>` | Show one draft with its history and suggested actions |
|
|
184
|
-
| `gobi draft add <title> <content> [--session <id>] [--priority N] [--action <label>]…` | Add a draft. Pass `--action` up to 3 times
|
|
249
|
+
| `gobi draft add <title> <content> [--session <id>] [--priority N] [--action <label>]…` | Add a draft. Pass `--action` up to 3 times. `--session` falls back to `$GOBI_SESSION_ID`. Use `-` for content to read from stdin. |
|
|
185
250
|
| `gobi draft delete <id>` | Delete a draft |
|
|
186
251
|
| `gobi draft prioritize <id> <priority>` | Set priority (lower = higher) |
|
|
187
252
|
| `gobi draft action <id> <index>` | Take one of the draft's suggested actions by 0-based index. Marks `actioned` and posts the synthesized message into the originating session. |
|
|
188
253
|
| `gobi draft revise <id> <comment> [--title <t>] [--content <c>] [--action <label>]…` | Bump revision with a comment; optionally replace title / content / actions in the same call |
|
|
189
254
|
|
|
255
|
+
### Media generation
|
|
256
|
+
|
|
257
|
+
Image, video, and avatar generation. See the `gobi-media` skill for full workflows.
|
|
258
|
+
|
|
259
|
+
| Command | Description |
|
|
260
|
+
|---------|-------------|
|
|
261
|
+
| `gobi media image-generate --prompt <p> [--aspect-ratio <r>] [-o <file>]` | Generate an image (use `-o` to wait + download) |
|
|
262
|
+
| `gobi media image-edit --image <f> --prompt <p>` | Edit/inpaint an image |
|
|
263
|
+
| `gobi media video-create --avatar-id <a> --voice-id <v> --script <s>` | Avatar video with voice narration |
|
|
264
|
+
| `gobi media cinematic-create --prompt <p>` | Cinematic video from a text prompt |
|
|
265
|
+
| `gobi media avatar-design / avatar-from-selfie` | Custom avatars from prompts or selfies |
|
|
266
|
+
| `gobi media avatars` / `gobi media voices` | List available avatars and voices |
|
|
267
|
+
| `gobi media upload <file>` | Upload a local file and get a media id |
|
|
268
|
+
|
|
190
269
|
### Global options
|
|
191
270
|
|
|
192
271
|
| Option | Scope | Description |
|
|
193
272
|
|--------|-------|-------------|
|
|
194
|
-
| `--json` | All commands | Output
|
|
273
|
+
| `--json` | All commands | Output structured JSON (`{success, data}` / `{success, error}`) |
|
|
195
274
|
| `--space-slug <slug>` | `space` commands | Override the default space (from `.gobi/settings.yaml`) |
|
|
196
|
-
| `--vault-slug <slug>` | Per-command | Override the default vault
|
|
275
|
+
| `--vault-slug <slug>` | Per-command | Override the default vault — see each command's docs |
|
|
197
276
|
|
|
198
277
|
## Configuration
|
|
199
278
|
|
|
@@ -203,6 +282,7 @@ Drafts are authored by your agent during chat (or by external agents using `gobi
|
|
|
203
282
|
|----------|---------|-------------|
|
|
204
283
|
| `GOBI_BASE_URL` | `https://api.joingobi.com` | API server URL |
|
|
205
284
|
| `GOBI_WEBDRIVE_BASE_URL` | `https://webdrive.joingobi.com` | File storage URL |
|
|
285
|
+
| `GOBI_SESSION_ID` | — | Default `--session` for `gobi draft add` (set automatically inside agent runs) |
|
|
206
286
|
|
|
207
287
|
### Files
|
|
208
288
|
|
|
@@ -210,8 +290,27 @@ Drafts are authored by your agent during chat (or by external agents using `gobi
|
|
|
210
290
|
|------|-------------|
|
|
211
291
|
| `~/.gobi/credentials.json` | Stored authentication tokens |
|
|
212
292
|
| `.gobi/settings.yaml` | Per-project vault and space configuration |
|
|
293
|
+
| `.gobi/syncfiles` | Whitelist patterns for `gobi vault sync` (one per line) |
|
|
294
|
+
| `.gobi/sync.db` | Local sync state (cursor, hash cache) — managed by the CLI |
|
|
213
295
|
| `PUBLISH.md` | Vault profile document with YAML frontmatter, published via `gobi vault publish` |
|
|
214
296
|
|
|
297
|
+
## Claude Code skills
|
|
298
|
+
|
|
299
|
+
The CLI ships a `.claude-plugin/` manifest with eight skills that wrap the command groups for Claude Code agents:
|
|
300
|
+
|
|
301
|
+
| Skill | Covers |
|
|
302
|
+
|-------|--------|
|
|
303
|
+
| `gobi-core` | Auth, init, session, update, space list/warp |
|
|
304
|
+
| `gobi-vault` | `gobi vault publish/unpublish/sync` |
|
|
305
|
+
| `gobi-space` | `gobi space …` and `gobi global …` |
|
|
306
|
+
| `gobi-saved` | `gobi saved note …` and `gobi saved post …` |
|
|
307
|
+
| `gobi-draft` | `gobi draft …` |
|
|
308
|
+
| `gobi-media` | `gobi media …` |
|
|
309
|
+
| `gobi-sense` | `gobi sense activities/transcriptions` |
|
|
310
|
+
| `gobi-homepage` | Building custom HTML homepages with `window.gobi` |
|
|
311
|
+
|
|
312
|
+
Each skill's `SKILL.md` is hand-written orientation; `references/` is regenerated from `--help` output by `npm run generate-skill-docs`.
|
|
313
|
+
|
|
215
314
|
## Development
|
|
216
315
|
|
|
217
316
|
```sh
|
|
@@ -228,6 +327,8 @@ Run from source without compiling:
|
|
|
228
327
|
npm run dev -- auth status
|
|
229
328
|
```
|
|
230
329
|
|
|
330
|
+
Tests run against `dist/*.test.js` (built JS), so `npm run build` is a prerequisite for `npm test`.
|
|
331
|
+
|
|
231
332
|
## License
|
|
232
333
|
|
|
233
334
|
[MIT](LICENSE)
|
package/commands/space-share.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: space-share
|
|
3
|
-
description: Summarize recent learnings from this session and draft a
|
|
3
|
+
description: Summarize recent learnings from this session and draft a personal post to share to the global feed.
|
|
4
4
|
argument-hint: "[context]"
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ gobi --json auth status
|
|
|
16
16
|
|
|
17
17
|
Check that `.gobi/settings.yaml` exists and contains both `vaultSlug` and `selectedSpaceSlug`. If not, stop and ask the user to run `gobi init` and `gobi space warp` first.
|
|
18
18
|
|
|
19
|
-
## Draft a
|
|
19
|
+
## Draft a personal post
|
|
20
20
|
|
|
21
21
|
If `$ARGUMENTS` is provided, treat it as additional context or emphasis to guide the draft (e.g. "Emphasize the auth fix" or "Focus on the API design decision").
|
|
22
22
|
|
package/dist/attachments.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { existsSync, readFileSync, appendFileSync } from "fs";
|
|
2
|
+
import { EOL } from "os";
|
|
2
3
|
import { join, extname } from "path";
|
|
3
4
|
import ignore from "ignore";
|
|
4
5
|
import { WEBDRIVE_BASE_URL } from "./constants.js";
|
|
@@ -33,7 +34,7 @@ function addToLocalSyncfiles(gobiDir, filePath) {
|
|
|
33
34
|
if (isPathCovered(filePath, patterns))
|
|
34
35
|
return;
|
|
35
36
|
const syncfilesPath = join(gobiDir, "syncfiles");
|
|
36
|
-
appendFileSync(syncfilesPath,
|
|
37
|
+
appendFileSync(syncfilesPath, `${EOL}${filePath}`);
|
|
37
38
|
console.log(`Added to syncfiles: ${filePath}`);
|
|
38
39
|
}
|
|
39
40
|
export async function uploadAttachments(vaultSlug, links, token, options) {
|
package/dist/commands/draft.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { readFileSync } from "fs";
|
|
2
1
|
import { apiDelete, apiGet, apiPatch, apiPost } from "../client.js";
|
|
3
|
-
import { isJsonMode, jsonOut, unwrapResp } from "./utils.js";
|
|
2
|
+
import { isJsonMode, jsonOut, readStdin, unwrapResp } from "./utils.js";
|
|
4
3
|
function readContent(value) {
|
|
5
4
|
if (value === "-")
|
|
6
|
-
return
|
|
5
|
+
return readStdin();
|
|
7
6
|
return value;
|
|
8
7
|
}
|
|
9
8
|
function snippet(content, max = 80) {
|
package/dist/commands/global.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { readFileSync } from "fs";
|
|
2
1
|
import { apiGet, apiPost, apiPatch, apiDelete } from "../client.js";
|
|
3
|
-
import { isJsonMode, jsonOut, resolveVaultSlug, unwrapResp } from "./utils.js";
|
|
2
|
+
import { isJsonMode, jsonOut, readStdin, resolveVaultSlug, unwrapResp, } from "./utils.js";
|
|
4
3
|
import { extractWikiLinks, uploadAttachments } from "../attachments.js";
|
|
5
4
|
import { getValidToken } from "../auth/manager.js";
|
|
6
5
|
function readContent(value) {
|
|
7
6
|
if (value === "-")
|
|
8
|
-
return
|
|
7
|
+
return readStdin();
|
|
9
8
|
return value;
|
|
10
9
|
}
|
|
11
10
|
function formatFeedLine(m) {
|
|
@@ -232,9 +231,13 @@ export function registerGlobalCommand(program) {
|
|
|
232
231
|
.option("--title <title>", "New title")
|
|
233
232
|
.option("--content <content>", "New content (markdown supported, use \"-\" for stdin)")
|
|
234
233
|
.option("--rich-text <richText>", "Rich-text JSON array (mutually exclusive with --content)")
|
|
234
|
+
.option("--vault-slug <vaultSlug>", "Attribute the post to this vault (sets authorVaultId). Pass an empty string to detach.")
|
|
235
235
|
.action(async (postId, opts) => {
|
|
236
|
-
if (opts.title == null &&
|
|
237
|
-
|
|
236
|
+
if (opts.title == null &&
|
|
237
|
+
opts.content == null &&
|
|
238
|
+
opts.richText == null &&
|
|
239
|
+
opts.vaultSlug === undefined) {
|
|
240
|
+
throw new Error("Provide at least --title, --content, --rich-text, or --vault-slug to update.");
|
|
238
241
|
}
|
|
239
242
|
if (opts.content && opts.richText) {
|
|
240
243
|
throw new Error("--content and --rich-text are mutually exclusive.");
|
|
@@ -254,6 +257,8 @@ export function registerGlobalCommand(program) {
|
|
|
254
257
|
}
|
|
255
258
|
body.richText = parsed;
|
|
256
259
|
}
|
|
260
|
+
if (opts.vaultSlug !== undefined)
|
|
261
|
+
body.authorVaultSlug = opts.vaultSlug;
|
|
257
262
|
const resp = (await apiPatch(`/posts/${postId}`, body));
|
|
258
263
|
const post = unwrapResp(resp);
|
|
259
264
|
if (isJsonMode(global)) {
|
package/dist/commands/saved.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { readFileSync } from "fs";
|
|
2
1
|
import { apiGet, apiPost, apiPatch, apiDelete } from "../client.js";
|
|
3
|
-
import { isJsonMode, jsonOut, unwrapResp } from "./utils.js";
|
|
2
|
+
import { isJsonMode, jsonOut, readStdin, unwrapResp } from "./utils.js";
|
|
4
3
|
function defaultTimezone() {
|
|
5
4
|
return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
6
5
|
}
|
|
@@ -101,7 +100,7 @@ function registerNoteCommands(saved) {
|
|
|
101
100
|
if (!opts.content) {
|
|
102
101
|
throw new Error("--content is required (use '-' to read from stdin)");
|
|
103
102
|
}
|
|
104
|
-
const content = opts.content === "-" ?
|
|
103
|
+
const content = opts.content === "-" ? readStdin() : opts.content;
|
|
105
104
|
const body = {
|
|
106
105
|
content,
|
|
107
106
|
timezone: opts.timezone || defaultTimezone(),
|
|
@@ -128,7 +127,7 @@ function registerNoteCommands(saved) {
|
|
|
128
127
|
const body = {};
|
|
129
128
|
if (opts.content != null) {
|
|
130
129
|
body.content =
|
|
131
|
-
opts.content === "-" ?
|
|
130
|
+
opts.content === "-" ? readStdin() : opts.content;
|
|
132
131
|
}
|
|
133
132
|
if (opts.agentId != null) {
|
|
134
133
|
body.agentId = opts.agentId === "null" ? null : parseInt(opts.agentId, 10);
|
package/dist/commands/space.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { readFileSync } from "fs";
|
|
2
1
|
import { apiGet, apiPost, apiPatch, apiDelete } from "../client.js";
|
|
3
2
|
import { selectSpace, writeSpaceSetting } from "./init.js";
|
|
4
|
-
import { isJsonMode, jsonOut, resolveSpaceSlug, resolveVaultSlug, unwrapResp } from "./utils.js";
|
|
3
|
+
import { isJsonMode, jsonOut, readStdin, resolveSpaceSlug, resolveVaultSlug, unwrapResp, } from "./utils.js";
|
|
5
4
|
import { extractWikiLinks, uploadAttachments } from "../attachments.js";
|
|
6
5
|
import { getValidToken } from "../auth/manager.js";
|
|
7
6
|
function readContent(value) {
|
|
8
7
|
if (value === "-")
|
|
9
|
-
return
|
|
8
|
+
return readStdin();
|
|
10
9
|
return value;
|
|
11
10
|
}
|
|
12
11
|
function formatFeedLine(m) {
|
|
@@ -295,21 +294,27 @@ export function registerSpaceCommand(program) {
|
|
|
295
294
|
.description("Create a post in a space.")
|
|
296
295
|
.requiredOption("--title <title>", "Title of the post")
|
|
297
296
|
.requiredOption("--content <content>", "Post content (markdown supported)")
|
|
298
|
-
.option("--auto-attachments", "Upload wiki-linked [[files]] to webdrive before posting")
|
|
299
|
-
.option("--vault-slug <vaultSlug>", "
|
|
297
|
+
.option("--auto-attachments", "Upload wiki-linked [[files]] to webdrive before posting (also attributes the post to that vault)")
|
|
298
|
+
.option("--vault-slug <vaultSlug>", "Attribute the post to this vault (sets authorVaultId). Also used as upload destination for --auto-attachments.")
|
|
300
299
|
.action(async (opts) => {
|
|
301
300
|
const content = readContent(opts.content);
|
|
301
|
+
let authorVaultSlug;
|
|
302
|
+
if (opts.vaultSlug || opts.autoAttachments) {
|
|
303
|
+
authorVaultSlug = resolveVaultSlug(opts);
|
|
304
|
+
}
|
|
302
305
|
if (opts.autoAttachments) {
|
|
303
|
-
const vaultSlug = resolveVaultSlug(opts);
|
|
304
306
|
const token = await getValidToken();
|
|
305
307
|
const links = extractWikiLinks(content);
|
|
306
|
-
await uploadAttachments(
|
|
308
|
+
await uploadAttachments(authorVaultSlug, links, token, { addToSyncfiles: true });
|
|
307
309
|
}
|
|
308
310
|
const spaceSlug = resolveSpaceSlug(space);
|
|
309
|
-
const
|
|
311
|
+
const body = {
|
|
310
312
|
title: opts.title,
|
|
311
313
|
content,
|
|
312
|
-
}
|
|
314
|
+
};
|
|
315
|
+
if (authorVaultSlug)
|
|
316
|
+
body.authorVaultSlug = authorVaultSlug;
|
|
317
|
+
const resp = (await apiPost(`/spaces/${spaceSlug}/posts`, body));
|
|
313
318
|
const post = unwrapResp(resp);
|
|
314
319
|
if (isJsonMode(space)) {
|
|
315
320
|
jsonOut(post);
|
|
@@ -325,26 +330,36 @@ export function registerSpaceCommand(program) {
|
|
|
325
330
|
.description("Edit a post. You must be the author.")
|
|
326
331
|
.option("--title <title>", "New title for the post")
|
|
327
332
|
.option("--content <content>", "New content for the post (markdown supported)")
|
|
328
|
-
.option("--auto-attachments", "Upload wiki-linked [[files]] to webdrive before editing")
|
|
329
|
-
.option("--vault-slug <vaultSlug>", "
|
|
333
|
+
.option("--auto-attachments", "Upload wiki-linked [[files]] to webdrive before editing (also attributes the post to that vault)")
|
|
334
|
+
.option("--vault-slug <vaultSlug>", "Attribute the post to this vault (sets authorVaultId). Also used as upload destination for --auto-attachments. Pass an empty string to detach.")
|
|
330
335
|
.action(async (postId, opts) => {
|
|
331
|
-
|
|
332
|
-
|
|
336
|
+
const wantsVaultChange = opts.vaultSlug !== undefined || opts.autoAttachments;
|
|
337
|
+
if (!opts.title && !opts.content && !wantsVaultChange) {
|
|
338
|
+
throw new Error("Provide at least --title, --content, or --vault-slug to update.");
|
|
333
339
|
}
|
|
334
340
|
const spaceSlug = resolveSpaceSlug(space);
|
|
341
|
+
let authorVaultSlug;
|
|
342
|
+
if (opts.vaultSlug !== undefined) {
|
|
343
|
+
// Empty string detaches; non-empty resolves through settings fallback.
|
|
344
|
+
authorVaultSlug = opts.vaultSlug === "" ? "" : resolveVaultSlug(opts);
|
|
345
|
+
}
|
|
346
|
+
else if (opts.autoAttachments) {
|
|
347
|
+
authorVaultSlug = resolveVaultSlug(opts);
|
|
348
|
+
}
|
|
335
349
|
const body = {};
|
|
336
350
|
if (opts.title != null)
|
|
337
351
|
body.title = opts.title;
|
|
338
352
|
if (opts.content != null) {
|
|
339
353
|
const content = readContent(opts.content);
|
|
340
354
|
if (opts.autoAttachments) {
|
|
341
|
-
const vaultSlug = resolveVaultSlug(opts);
|
|
342
355
|
const token = await getValidToken();
|
|
343
356
|
const links = extractWikiLinks(content);
|
|
344
|
-
await uploadAttachments(
|
|
357
|
+
await uploadAttachments(authorVaultSlug, links, token, { addToSyncfiles: true });
|
|
345
358
|
}
|
|
346
359
|
body.content = content;
|
|
347
360
|
}
|
|
361
|
+
if (authorVaultSlug !== undefined)
|
|
362
|
+
body.authorVaultSlug = authorVaultSlug;
|
|
348
363
|
const resp = (await apiPatch(`/spaces/${spaceSlug}/posts/${postId}`, body));
|
|
349
364
|
const post = unwrapResp(resp);
|
|
350
365
|
if (isJsonMode(space)) {
|
package/dist/commands/update.js
CHANGED
|
@@ -10,20 +10,26 @@ async function fetchLatestVersion() {
|
|
|
10
10
|
const data = (await res.json());
|
|
11
11
|
return data.version;
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
// `which` is Unix-only; Windows uses `where`. `where` may print multiple
|
|
14
|
+
// matches on separate lines — take the first one.
|
|
15
|
+
function locateGobi() {
|
|
16
|
+
const cmd = process.platform === "win32" ? "where gobi" : "which gobi";
|
|
14
17
|
try {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
return "brew";
|
|
18
|
-
}
|
|
18
|
+
const out = execSync(cmd, { encoding: "utf-8" }).trim();
|
|
19
|
+
return out.split(/\r?\n/)[0] || null;
|
|
19
20
|
}
|
|
20
21
|
catch {
|
|
21
|
-
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function detectInstallMethod() {
|
|
26
|
+
const gobiBin = locateGobi();
|
|
27
|
+
if (gobiBin && (gobiBin.includes("/Cellar/") || gobiBin.includes("/homebrew/"))) {
|
|
28
|
+
return "brew";
|
|
22
29
|
}
|
|
23
30
|
try {
|
|
24
31
|
const npmGlobalDir = execSync("npm root -g", { encoding: "utf-8" }).trim();
|
|
25
|
-
|
|
26
|
-
if (gobiBin.includes(npmGlobalDir.replace("/lib/node_modules", ""))) {
|
|
32
|
+
if (gobiBin && gobiBin.includes(npmGlobalDir.replace("/lib/node_modules", ""))) {
|
|
27
33
|
return "npm";
|
|
28
34
|
}
|
|
29
35
|
}
|
package/dist/commands/utils.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import { readFileSync } from "fs";
|
|
1
2
|
import { getSpaceSlug, getVaultSlug } from "./init.js";
|
|
3
|
+
// Reads all of stdin synchronously. Uses fd 0 (cross-platform) instead of
|
|
4
|
+
// "/dev/stdin", which doesn't exist on Windows.
|
|
5
|
+
export function readStdin() {
|
|
6
|
+
return readFileSync(0, "utf8");
|
|
7
|
+
}
|
|
2
8
|
export function isJsonMode(cmd) {
|
|
3
9
|
return !!cmd.parent?.opts().json;
|
|
4
10
|
}
|
package/package.json
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
name: gobi-core
|
|
3
3
|
description: >-
|
|
4
4
|
Core Gobi CLI: authentication (login/logout/status), vault initialization
|
|
5
|
-
(gobi init), space selection (gobi space warp/list),
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
(gobi init), space selection (gobi space warp/list), CLI updates (gobi
|
|
6
|
+
update), and session management (list/get/reply to conversations). Use when
|
|
7
|
+
the user needs to set up Gobi, authenticate, manage sessions, or update the
|
|
8
|
+
CLI. File sync is in the gobi-vault skill.
|
|
9
9
|
allowed-tools: Bash(gobi:*)
|
|
10
10
|
metadata:
|
|
11
11
|
author: gobi-ai
|
|
12
|
-
version: "0.
|
|
12
|
+
version: "2.0.0"
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
# gobi-core
|
|
16
16
|
|
|
17
|
-
Core CLI commands for the Gobi collaborative knowledge platform (
|
|
17
|
+
Core CLI commands for the Gobi collaborative knowledge platform (v2.0.0).
|
|
18
18
|
|
|
19
19
|
## Prerequisites
|
|
20
20
|
|
|
@@ -38,8 +38,11 @@ brew tap gobi-ai/tap && brew install gobi
|
|
|
38
38
|
|
|
39
39
|
## Key Concepts
|
|
40
40
|
|
|
41
|
-
- **
|
|
42
|
-
- **
|
|
41
|
+
- **Vault**: A filetree-backed knowledge home. A local directory becomes a vault when it contains `.gobi/settings.yaml` with a `vaultSlug`. Each vault has a slug (e.g. `brave-path-zr962w`); public profile is configured by a `PUBLISH.md` document at the vault root and pushed via `gobi vault publish`.
|
|
42
|
+
- **Personal Post**: A post on the author's profile that surfaces in the public global feed. Same `Post` data model as a Space Post — only the scope differs.
|
|
43
|
+
- **Space Post**: A post inside a community space.
|
|
44
|
+
- **Space**: A shared community knowledge area. A user can be a member of one or more spaces; each space contains posts, replies, sessions, and connected vaults.
|
|
45
|
+
- **Draft**: A unit of standing guidance authored by an agent during chat. Each draft carries 0–3 AI-suggested actions the user picks from. The top 5 pending drafts feed the agent's system prompt every turn.
|
|
43
46
|
|
|
44
47
|
## First-Time Setup
|
|
45
48
|
|
|
@@ -85,7 +88,7 @@ Check auth status anytime:
|
|
|
85
88
|
gobi auth status
|
|
86
89
|
```
|
|
87
90
|
|
|
88
|
-
**Important for agents**: Before running any `space` command, check
|
|
91
|
+
**Important for agents**: Before running any `space` command, check whether `.gobi/settings.yaml` exists in the current directory with both `vaultSlug` and `selectedSpaceSlug`. If the vault is missing, guide the user through `gobi init`. If only the space is missing, guide the user through `gobi space warp`. These commands require user input (interactive prompts), so the agent cannot run them silently. For one-off calls, every command also accepts an explicit `--vault-slug` / `--space-slug` override.
|
|
89
92
|
|
|
90
93
|
## Important: JSON Mode
|
|
91
94
|
|
|
@@ -95,7 +98,7 @@ For programmatic/agent usage, always pass `--json` as a **global** option (befor
|
|
|
95
98
|
gobi --json session list
|
|
96
99
|
```
|
|
97
100
|
|
|
98
|
-
JSON responses have the shape `{ "success": true, "data": ... }` on success or `{ "success": false, "error": "..." }` on failure.
|
|
101
|
+
JSON responses have the shape `{ "success": true, "data": ... }` on success or `{ "success": false, "error": "..." }` on failure. Pagination metadata (`pagination: { hasMore, nextCursor }`) ships alongside `data` on list endpoints.
|
|
99
102
|
|
|
100
103
|
## Available Commands
|
|
101
104
|
|
|
@@ -110,15 +113,17 @@ JSON responses have the shape `{ "success": true, "data": ... }` on success or `
|
|
|
110
113
|
- `gobi session get` — Get a session and its messages (paginated).
|
|
111
114
|
- `gobi session list` — List all sessions you are part of, sorted by most recent activity.
|
|
112
115
|
- `gobi session reply` — Send a human reply to a session you are a member of.
|
|
113
|
-
- `gobi vault sync` — Sync local vault files with Gobi Webdrive.
|
|
114
116
|
- `gobi update` — Update gobi-cli to the latest version.
|
|
115
117
|
|
|
118
|
+
> File sync (`gobi vault sync`) lives in the **gobi-vault** skill.
|
|
119
|
+
|
|
116
120
|
## Reference Documentation
|
|
117
121
|
|
|
118
122
|
- [gobi auth](references/auth.md)
|
|
119
123
|
- [gobi init](references/init.md)
|
|
120
124
|
- [gobi session](references/session.md)
|
|
121
125
|
- [gobi update](references/update.md)
|
|
126
|
+
- [gobi space (list/warp)](references/space.md)
|
|
122
127
|
|
|
123
128
|
## Configuration Files
|
|
124
129
|
|
|
@@ -134,3 +139,4 @@ JSON responses have the shape `{ "success": true, "data": ... }` on success or `
|
|
|
134
139
|
|----------|---------|-------------|
|
|
135
140
|
| `GOBI_BASE_URL` | `https://api.joingobi.com` | API server URL |
|
|
136
141
|
| `GOBI_WEBDRIVE_BASE_URL` | `https://webdrive.joingobi.com` | File storage URL |
|
|
142
|
+
| `GOBI_SESSION_ID` | — | Default `--session` for `gobi draft add` (set automatically inside agent runs) |
|
|
@@ -10,12 +10,12 @@ description: >-
|
|
|
10
10
|
allowed-tools: Bash(gobi:*)
|
|
11
11
|
metadata:
|
|
12
12
|
author: gobi-ai
|
|
13
|
-
version: "
|
|
13
|
+
version: "2.0.0"
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# gobi-draft
|
|
17
17
|
|
|
18
|
-
Gobi draft commands for managing agent-authored drafts (
|
|
18
|
+
Gobi draft commands for managing agent-authored drafts (v2.0.0).
|
|
19
19
|
|
|
20
20
|
Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
|
|
21
21
|
|
|
@@ -52,7 +52,7 @@ For programmatic/agent usage, always pass `--json` as a **global** option (befor
|
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
54
|
gobi --json draft list --limit 20
|
|
55
|
-
gobi --json draft add "Concise titles" "Prefer concise titles for
|
|
55
|
+
gobi --json draft add "Concise titles" "Prefer concise titles for personal posts." --action "Apply" --action "Skip" --priority 50
|
|
56
56
|
gobi --json draft action <draftId> 0
|
|
57
57
|
```
|
|
58
58
|
|
|
@@ -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,
|
|
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, personal posts, 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
|
|
|
@@ -67,10 +67,12 @@ function getFileUrl(path) {
|
|
|
67
67
|
}
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
###
|
|
70
|
+
### Personal posts
|
|
71
|
+
|
|
72
|
+
> `listVaultPosts` is still accepted as a deprecated alias for back-compat with older homepages — existing applets won't break, but new code should use `listPersonalPosts`.
|
|
71
73
|
|
|
72
74
|
```js
|
|
73
|
-
const { data: updates, pagination } = await gobi.
|
|
75
|
+
const { data: updates, pagination } = await gobi.listPersonalPosts({ limit: 10, cursor: null });
|
|
74
76
|
// updates[i] → {
|
|
75
77
|
// id: 42,
|
|
76
78
|
// title: 'New insights',
|
|
@@ -88,7 +90,7 @@ for (const u of updates) {
|
|
|
88
90
|
// Pagination — load the next page using the cursor
|
|
89
91
|
if (pagination.hasMore) {
|
|
90
92
|
const { data: moreUpdates, pagination: nextPage } =
|
|
91
|
-
await gobi.
|
|
93
|
+
await gobi.listPersonalPosts({ limit: 10, cursor: pagination.nextCursor });
|
|
92
94
|
}
|
|
93
95
|
```
|
|
94
96
|
|
|
@@ -175,7 +177,7 @@ renderer.link = (href, title, text) =>
|
|
|
175
177
|
marked.setOptions({ renderer });
|
|
176
178
|
```
|
|
177
179
|
|
|
178
|
-
**Plain-text previews.** For
|
|
180
|
+
**Plain-text previews.** For post 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.
|
|
179
181
|
|
|
180
182
|
---
|
|
181
183
|
|
|
@@ -202,9 +204,9 @@ Centralize colors and spacing in CSS custom properties so restyling is a one-lin
|
|
|
202
204
|
|
|
203
205
|
Pair with Google Fonts (e.g. Space Grotesk for headings, IBM Plex Mono for meta, Inter for body) via CDN `<link>`.
|
|
204
206
|
|
|
205
|
-
### Knowledge Graph from
|
|
207
|
+
### Knowledge Graph from post topics
|
|
206
208
|
|
|
207
|
-
|
|
209
|
+
Personal posts carry a `topics` array. Treat each topic as a node and any two topics co-occurring in the same post 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
210
|
|
|
209
211
|
```js
|
|
210
212
|
// Separate data-building from rendering so the same graph can be drawn at multiple sizes.
|
|
@@ -246,7 +248,7 @@ function drawGraph(containerId, w, h, data, opts = {}) {
|
|
|
246
248
|
```
|
|
247
249
|
|
|
248
250
|
Tips:
|
|
249
|
-
- **Enrich the data.** One page of 8
|
|
251
|
+
- **Enrich the data.** One page of 8 posts makes a sparse graph. Paginate 3–4 times (cap at ~32 posts) before building.
|
|
250
252
|
- **Cache the built data** in a module-level variable so the full-screen overlay can reuse it without refetching.
|
|
251
253
|
- **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
254
|
- 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.
|
|
@@ -272,7 +274,7 @@ function openOverlay(renderInto) {
|
|
|
272
274
|
|
|
273
275
|
Always restore `body.overflow` on close, and always remove the `keydown` listener.
|
|
274
276
|
|
|
275
|
-
###
|
|
277
|
+
### Personal post card — preview/full toggle
|
|
276
278
|
|
|
277
279
|
Show a truncated card that expands in place on click:
|
|
278
280
|
|
|
@@ -389,11 +391,11 @@ Single breakpoint at `768px` is enough for most homepages:
|
|
|
389
391
|
`https://gobispace.com/login?redirect_uri=${encodeURIComponent(window.location.href)}`;
|
|
390
392
|
}
|
|
391
393
|
|
|
392
|
-
// ──
|
|
394
|
+
// ── Personal posts ───────────────────────────────
|
|
393
395
|
|
|
394
396
|
async function loadUpdates() {
|
|
395
397
|
try {
|
|
396
|
-
const { data: updates } = await gobi.
|
|
398
|
+
const { data: updates } = await gobi.listPersonalPosts({ limit: 5 });
|
|
397
399
|
const el = document.getElementById('updates');
|
|
398
400
|
for (const u of updates) {
|
|
399
401
|
const div = document.createElement('div');
|
|
@@ -402,7 +404,7 @@ Single breakpoint at `768px` is enough for most homepages:
|
|
|
402
404
|
el.appendChild(div);
|
|
403
405
|
}
|
|
404
406
|
} catch (err) {
|
|
405
|
-
console.error('Failed to load
|
|
407
|
+
console.error('Failed to load personal posts:', err);
|
|
406
408
|
}
|
|
407
409
|
}
|
|
408
410
|
|
|
@@ -10,12 +10,12 @@ description: >-
|
|
|
10
10
|
allowed-tools: Bash(gobi:*)
|
|
11
11
|
metadata:
|
|
12
12
|
author: gobi-ai
|
|
13
|
-
version: "0.
|
|
13
|
+
version: "2.0.0"
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# gobi-media
|
|
17
17
|
|
|
18
|
-
Gobi media generation commands (
|
|
18
|
+
Gobi media generation commands (v2.0.0).
|
|
19
19
|
|
|
20
20
|
Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
|
|
21
21
|
|
|
@@ -9,12 +9,12 @@ description: >-
|
|
|
9
9
|
allowed-tools: Bash(gobi:*)
|
|
10
10
|
metadata:
|
|
11
11
|
author: gobi-ai
|
|
12
|
-
version: "
|
|
12
|
+
version: "2.0.0"
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
# gobi-saved
|
|
16
16
|
|
|
17
|
-
Gobi saved-knowledge commands (
|
|
17
|
+
Gobi saved-knowledge commands (v2.0.0).
|
|
18
18
|
|
|
19
19
|
Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
|
|
20
20
|
|
|
@@ -7,23 +7,27 @@ description: >-
|
|
|
7
7
|
allowed-tools: Bash(gobi:*)
|
|
8
8
|
metadata:
|
|
9
9
|
author: gobi-ai
|
|
10
|
-
version: "0.
|
|
10
|
+
version: "2.0.0"
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
# gobi-sense
|
|
14
14
|
|
|
15
|
-
Gobi sense commands for activity and transcription data (
|
|
15
|
+
Gobi sense commands for activity and transcription data (v2.0.0).
|
|
16
16
|
|
|
17
|
-
Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
|
|
17
|
+
Requires gobi-cli installed and authenticated. See the **gobi-core** skill for setup.
|
|
18
|
+
|
|
19
|
+
Activities and transcriptions are captured by Gobi Sense (the wearable) and the mobile app, then ingested via the cloud pipeline. The CLI surface is read-only — fetch records in a time range and feed them to whatever analysis you want to run.
|
|
18
20
|
|
|
19
21
|
## Important: JSON Mode
|
|
20
22
|
|
|
21
23
|
For programmatic/agent usage, always pass `--json` as a **global** option (before the subcommand):
|
|
22
24
|
|
|
23
25
|
```bash
|
|
24
|
-
gobi --json sense activities --
|
|
26
|
+
gobi --json sense activities --start-time 2026-04-01T00:00:00Z --end-time 2026-04-08T00:00:00Z
|
|
25
27
|
```
|
|
26
28
|
|
|
29
|
+
Times are ISO 8601 UTC.
|
|
30
|
+
|
|
27
31
|
## Available Commands
|
|
28
32
|
|
|
29
33
|
- `gobi sense activities` — Fetch activity records within a time range.
|
|
@@ -1,29 +1,42 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gobi-space
|
|
3
3
|
description: >-
|
|
4
|
-
Gobi space and global commands: read and write posts and replies, browse
|
|
5
|
-
|
|
6
|
-
public feed
|
|
7
|
-
|
|
4
|
+
Gobi space and global commands: read and write posts and replies, browse the
|
|
5
|
+
unified feed and topic feeds — in a community space (`gobi space`) or in the
|
|
6
|
+
public global feed of personal posts (`gobi global`). Personal Posts and
|
|
7
|
+
Space Posts share the same data model; only the scope differs. Use when the
|
|
8
|
+
user wants to read or write posts and replies. Space and member admin is
|
|
9
|
+
web-UI only.
|
|
8
10
|
allowed-tools: Bash(gobi:*)
|
|
9
11
|
metadata:
|
|
10
12
|
author: gobi-ai
|
|
11
|
-
version: "0.
|
|
13
|
+
version: "2.0.0"
|
|
12
14
|
---
|
|
13
15
|
|
|
14
16
|
# gobi-space
|
|
15
17
|
|
|
16
|
-
Gobi space and global
|
|
18
|
+
Gobi space and global posts (v2.0.0).
|
|
17
19
|
|
|
18
|
-
Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
|
|
20
|
+
Requires gobi-cli installed and authenticated. See the **gobi-core** skill for setup.
|
|
19
21
|
|
|
20
|
-
##
|
|
22
|
+
## Two scopes, one data model
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
The same `Post` data type drives both surfaces — the difference is **scope**:
|
|
25
|
+
|
|
26
|
+
- **Space Post** — `gobi space …` — lives in a community space's feed.
|
|
27
|
+
- **Personal Post** — `gobi global …` — lives on the author's profile (their primary vault) and surfaces in the public global feed.
|
|
28
|
+
|
|
29
|
+
Anything you can do to a Space Post (reply, edit, delete, attribute to a vault) you can do to a Personal Post.
|
|
23
30
|
|
|
24
31
|
- When the user wants to explore or catch up on what's happening in their space, invoke `/gobi:space-explore`.
|
|
25
32
|
- When the user wants to share or post learnings from the current session, invoke `/gobi:space-share`.
|
|
26
33
|
|
|
34
|
+
## Author vault attribution (`--vault-slug`)
|
|
35
|
+
|
|
36
|
+
Both `gobi space create-post` / `edit-post` and `gobi global create-post` / `edit-post` accept `--vault-slug <slug>`. When set, the slug becomes the post's `authorVaultSlug` — the vault the user is posting on behalf of. The caller must hold `role: 'owner'` on that vault. Pass `--vault-slug ""` on edit to detach.
|
|
37
|
+
|
|
38
|
+
`--auto-attachments` resolves a vault for upload and **also** uses it as `authorVaultSlug` automatically — one flag, two effects.
|
|
39
|
+
|
|
27
40
|
## Space Slug Override
|
|
28
41
|
|
|
29
42
|
`gobi space` commands use the space from `.gobi/settings.yaml`. Override it with a parent-level flag:
|
|
@@ -55,28 +68,29 @@ gobi --json space list-posts
|
|
|
55
68
|
### Feed
|
|
56
69
|
- `gobi space feed` — List the unified feed (posts and replies, newest first).
|
|
57
70
|
|
|
58
|
-
###
|
|
71
|
+
### Space posts
|
|
59
72
|
- `gobi space list-posts` — List posts in a space (paginated).
|
|
60
73
|
- `gobi space get-post <postId>` — Get a post with its ancestors and replies (paginated). Ancestors and replies are returned together; there is no separate `ancestors` or `list-replies` command.
|
|
61
|
-
- `gobi space create-post` — Create a post
|
|
62
|
-
- `gobi space edit-post <postId>` — Edit a post. You must be the author.
|
|
63
|
-
- `gobi space delete-post <postId>` — Delete a post. You must be the author.
|
|
74
|
+
- `gobi space create-post` — Create a space post. `--vault-slug` attributes it to a vault you own; `--auto-attachments` uploads `[[wikilinks]]` to that vault and uses it as `authorVaultSlug`.
|
|
75
|
+
- `gobi space edit-post <postId>` — Edit a space post. You must be the author. `--vault-slug ""` detaches the vault.
|
|
76
|
+
- `gobi space delete-post <postId>` — Delete a space post. You must be the author.
|
|
64
77
|
|
|
65
|
-
###
|
|
66
|
-
- `gobi space create-reply <postId>` — Create a reply to a post
|
|
78
|
+
### Space replies
|
|
79
|
+
- `gobi space create-reply <postId>` — Create a reply to a space post.
|
|
67
80
|
- `gobi space edit-reply <replyId>` — Edit a reply. You must be the author.
|
|
68
81
|
- `gobi space delete-reply <replyId>` — Delete a reply. You must be the author.
|
|
69
82
|
|
|
70
|
-
###
|
|
71
|
-
|
|
83
|
+
### Personal posts (global feed)
|
|
84
|
+
|
|
85
|
+
`gobi global` is the same surface for Personal Posts — posts that live on the author's profile and surface in the public global feed.
|
|
72
86
|
|
|
73
|
-
- `gobi global feed` — List the global
|
|
74
|
-
- `gobi global list-posts` — List posts
|
|
75
|
-
- `gobi global get-post <postId>` — Get a
|
|
76
|
-
- `gobi global create-post` — Create a post
|
|
77
|
-
- `gobi global edit-post <postId>` — Edit a post you authored.
|
|
78
|
-
- `gobi global delete-post <postId>` — Delete a post you authored.
|
|
79
|
-
- `gobi global create-reply <postId>` — Reply to a post
|
|
87
|
+
- `gobi global feed` — List the public global feed (posts and replies, newest first).
|
|
88
|
+
- `gobi global list-posts` — List personal posts. `--mine` for your own; `--vault-slug <slug>` to filter by author vault.
|
|
89
|
+
- `gobi global get-post <postId>` — Get a personal post with its ancestors and replies.
|
|
90
|
+
- `gobi global create-post` — Create a personal post. `--vault-slug` and `--auto-attachments` work the same as on `space create-post`.
|
|
91
|
+
- `gobi global edit-post <postId>` — Edit a personal post you authored. `--vault-slug ""` detaches the vault.
|
|
92
|
+
- `gobi global delete-post <postId>` — Delete a personal post you authored.
|
|
93
|
+
- `gobi global create-reply <postId>` — Reply to a personal post.
|
|
80
94
|
- `gobi global edit-reply <replyId>` — Edit a reply you authored.
|
|
81
95
|
- `gobi global delete-reply <replyId>` — Delete a reply you authored.
|
|
82
96
|
|
|
@@ -88,10 +88,11 @@ Usage: gobi global edit-post [options] <postId>
|
|
|
88
88
|
Edit a post you authored in the global feed.
|
|
89
89
|
|
|
90
90
|
Options:
|
|
91
|
-
--title <title>
|
|
92
|
-
--content <content>
|
|
93
|
-
--rich-text <richText>
|
|
94
|
-
-
|
|
91
|
+
--title <title> New title
|
|
92
|
+
--content <content> New content (markdown supported, use "-" for stdin)
|
|
93
|
+
--rich-text <richText> Rich-text JSON array (mutually exclusive with --content)
|
|
94
|
+
--vault-slug <vaultSlug> Attribute the post to this vault (sets authorVaultId). Pass an empty string to detach.
|
|
95
|
+
-h, --help display help for command
|
|
95
96
|
```
|
|
96
97
|
|
|
97
98
|
## delete-post
|
|
@@ -112,8 +112,8 @@ Create a post in a space.
|
|
|
112
112
|
Options:
|
|
113
113
|
--title <title> Title of the post
|
|
114
114
|
--content <content> Post content (markdown supported)
|
|
115
|
-
--auto-attachments Upload wiki-linked [[files]] to webdrive before posting
|
|
116
|
-
--vault-slug <vaultSlug>
|
|
115
|
+
--auto-attachments Upload wiki-linked [[files]] to webdrive before posting (also attributes the post to that vault)
|
|
116
|
+
--vault-slug <vaultSlug> Attribute the post to this vault (sets authorVaultId). Also used as upload destination for --auto-attachments.
|
|
117
117
|
-h, --help display help for command
|
|
118
118
|
```
|
|
119
119
|
|
|
@@ -127,8 +127,8 @@ Edit a post. You must be the author.
|
|
|
127
127
|
Options:
|
|
128
128
|
--title <title> New title for the post
|
|
129
129
|
--content <content> New content for the post (markdown supported)
|
|
130
|
-
--auto-attachments Upload wiki-linked [[files]] to webdrive before editing
|
|
131
|
-
--vault-slug <vaultSlug>
|
|
130
|
+
--auto-attachments Upload wiki-linked [[files]] to webdrive before editing (also attributes the post to that vault)
|
|
131
|
+
--vault-slug <vaultSlug> Attribute the post to this vault (sets authorVaultId). Also used as upload destination for --auto-attachments. Pass an empty string to detach.
|
|
132
132
|
-h, --help display help for command
|
|
133
133
|
```
|
|
134
134
|
|
|
@@ -7,12 +7,12 @@ description: >-
|
|
|
7
7
|
allowed-tools: Bash(gobi:*)
|
|
8
8
|
metadata:
|
|
9
9
|
author: gobi-ai
|
|
10
|
-
version: "0.
|
|
10
|
+
version: "2.0.0"
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
# gobi-vault
|
|
14
14
|
|
|
15
|
-
Gobi vault commands for publishing your vault profile and syncing files (
|
|
15
|
+
Gobi vault commands for publishing your vault profile and syncing files (v2.0.0).
|
|
16
16
|
|
|
17
17
|
Requires gobi-cli installed and authenticated. See gobi-core skill for setup.
|
|
18
18
|
|