@gobi-ai/cli 1.3.7 → 2.0.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.
- package/.claude-plugin/marketplace.json +6 -7
- package/.claude-plugin/plugin.json +4 -5
- package/README.md +78 -89
- package/commands/space-explore.md +10 -10
- package/commands/space-share.md +13 -7
- package/dist/commands/draft.js +213 -0
- package/dist/commands/global.js +205 -70
- package/dist/commands/init.js +5 -5
- package/dist/commands/{notes.js → saved.js} +112 -19
- package/dist/commands/space.js +92 -97
- package/dist/commands/sync.js +2 -56
- package/dist/commands/vault.js +113 -0
- package/dist/main.js +6 -10
- package/package.json +2 -2
- package/skills/gobi-core/SKILL.md +5 -7
- package/skills/gobi-core/references/space.md +18 -19
- package/skills/gobi-draft/SKILL.md +74 -0
- package/skills/gobi-draft/references/draft.md +109 -0
- package/skills/gobi-homepage/SKILL.md +16 -16
- package/skills/gobi-saved/SKILL.md +59 -0
- package/skills/gobi-saved/references/saved.md +52 -0
- package/skills/gobi-space/SKILL.md +34 -31
- package/skills/gobi-space/references/global.md +84 -24
- package/skills/gobi-space/references/space.md +45 -57
- package/skills/gobi-vault/SKILL.md +92 -0
- package/skills/{gobi-core/references/sync.md → gobi-vault/references/vault.md} +41 -2
- package/dist/commands/brain.js +0 -141
- package/dist/commands/feed.js +0 -148
- package/dist/commands/proposal.js +0 -185
- package/skills/gobi-brain/SKILL.md +0 -100
- package/skills/gobi-brain/references/brain.md +0 -66
- package/skills/gobi-feed/SKILL.md +0 -43
- package/skills/gobi-feed/references/feed.md +0 -80
- package/skills/gobi-notes/SKILL.md +0 -52
- package/skills/gobi-notes/references/notes.md +0 -82
- package/skills/gobi-proposal/SKILL.md +0 -66
- package/skills/gobi-proposal/references/proposal.md +0 -116
|
@@ -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.3.
|
|
7
|
+
"version": "1.3.8",
|
|
8
8
|
"plugins": [
|
|
9
9
|
{
|
|
10
10
|
"name": "gobi",
|
|
11
|
-
"description": "Manage the Gobi collaborative knowledge platform from the command line.
|
|
12
|
-
"version": "1.3.
|
|
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": "1.3.8",
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "gobi-ai"
|
|
15
15
|
},
|
|
@@ -18,10 +18,9 @@
|
|
|
18
18
|
"skills": [
|
|
19
19
|
"./skills/gobi-core",
|
|
20
20
|
"./skills/gobi-space",
|
|
21
|
-
"./skills/gobi-
|
|
22
|
-
"./skills/gobi-
|
|
23
|
-
"./skills/gobi-
|
|
24
|
-
"./skills/gobi-proposal",
|
|
21
|
+
"./skills/gobi-vault",
|
|
22
|
+
"./skills/gobi-saved",
|
|
23
|
+
"./skills/gobi-draft",
|
|
25
24
|
"./skills/gobi-media",
|
|
26
25
|
"./skills/gobi-sense",
|
|
27
26
|
"./skills/gobi-homepage"
|
|
@@ -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.3.
|
|
4
|
+
"version": "1.3.8",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "gobi-ai"
|
|
7
7
|
},
|
|
@@ -9,10 +9,9 @@
|
|
|
9
9
|
"skills": [
|
|
10
10
|
"./skills/gobi-core",
|
|
11
11
|
"./skills/gobi-space",
|
|
12
|
-
"./skills/gobi-
|
|
13
|
-
"./skills/gobi-
|
|
14
|
-
"./skills/gobi-
|
|
15
|
-
"./skills/gobi-proposal",
|
|
12
|
+
"./skills/gobi-vault",
|
|
13
|
+
"./skills/gobi-saved",
|
|
14
|
+
"./skills/gobi-draft",
|
|
16
15
|
"./skills/gobi-media",
|
|
17
16
|
"./skills/gobi-sense",
|
|
18
17
|
"./skills/gobi-homepage"
|
package/README.md
CHANGED
|
@@ -34,17 +34,21 @@ npm link
|
|
|
34
34
|
## Quick start
|
|
35
35
|
|
|
36
36
|
```sh
|
|
37
|
-
# Initialize — logs in and sets up your vault
|
|
37
|
+
# Initialize — logs in and sets up your vault (creates PUBLISH.md)
|
|
38
38
|
gobi init
|
|
39
39
|
|
|
40
40
|
# Select a space
|
|
41
41
|
gobi space warp
|
|
42
42
|
|
|
43
|
-
#
|
|
44
|
-
gobi
|
|
43
|
+
# Publish your vault profile (after editing PUBLISH.md frontmatter)
|
|
44
|
+
gobi vault publish
|
|
45
45
|
|
|
46
|
-
#
|
|
47
|
-
gobi
|
|
46
|
+
# Sync local files with the webdrive
|
|
47
|
+
gobi vault sync
|
|
48
|
+
|
|
49
|
+
# Browse the global feed and create a post
|
|
50
|
+
gobi global feed
|
|
51
|
+
gobi global create-post --title "Hello" --content "Trying gobi"
|
|
48
52
|
```
|
|
49
53
|
|
|
50
54
|
## Commands
|
|
@@ -61,22 +65,34 @@ gobi brain ask --vault-slug my-vault --question "What is RAG?"
|
|
|
61
65
|
|
|
62
66
|
| Command | Description |
|
|
63
67
|
|---------|-------------|
|
|
64
|
-
| `gobi init` | Log in (if needed) and select or create a vault |
|
|
68
|
+
| `gobi init` | Log in (if needed) and select or create a vault. Creates `PUBLISH.md` if missing. |
|
|
65
69
|
| `gobi space list` | List spaces you are a member of |
|
|
66
70
|
| `gobi space warp [spaceSlug]` | Select the active space (interactive if slug omitted) |
|
|
67
71
|
|
|
68
|
-
###
|
|
72
|
+
### Vault
|
|
69
73
|
|
|
70
74
|
| Command | Description |
|
|
71
75
|
|---------|-------------|
|
|
72
|
-
| `gobi
|
|
73
|
-
| `gobi
|
|
74
|
-
| `gobi
|
|
75
|
-
| `gobi brain unpublish` | Remove `BRAIN.md` from your vault |
|
|
76
|
+
| `gobi vault publish` | Upload `PUBLISH.md` to your vault. Triggers profile/metadata refresh. |
|
|
77
|
+
| `gobi vault unpublish` | Remove `PUBLISH.md` from your vault. |
|
|
78
|
+
| `gobi vault sync` | Sync local vault files with Gobi Webdrive. |
|
|
76
79
|
|
|
77
|
-
Public
|
|
80
|
+
Public vaults are accessible at `https://gobispace.com/@{vaultSlug}`.
|
|
78
81
|
|
|
79
|
-
`
|
|
82
|
+
`vault sync` options:
|
|
83
|
+
|
|
84
|
+
| Option | Description |
|
|
85
|
+
|--------|-------------|
|
|
86
|
+
| `--upload-only` | Only upload local changes to server |
|
|
87
|
+
| `--download-only` | Only download server changes to local |
|
|
88
|
+
| `--conflict <strategy>` | Conflict resolution: `ask` (default), `server`, `client`, `skip` |
|
|
89
|
+
| `--dir <path>` | Local vault directory (default: current directory) |
|
|
90
|
+
| `--dry-run` | Preview changes without making them |
|
|
91
|
+
| `--full` | Full sync: ignore cursor and hash cache, re-check every file |
|
|
92
|
+
| `--path <path>` | Restrict sync to specific file/folder (repeatable) |
|
|
93
|
+
| `--plan-file <path>` | Write dry-run plan to file, or read plan to execute |
|
|
94
|
+
| `--execute` | Execute a previously written plan file (requires `--plan-file`) |
|
|
95
|
+
| `--conflict-choices <json>` | Per-file conflict resolutions as JSON (use with `--execute`) |
|
|
80
96
|
|
|
81
97
|
### Spaces
|
|
82
98
|
|
|
@@ -85,52 +101,33 @@ Public brains are accessible at `https://gobispace.com/@{vaultSlug}`.
|
|
|
85
101
|
| Command | Description |
|
|
86
102
|
|---------|-------------|
|
|
87
103
|
| `gobi space get [spaceSlug]` | Show space details (uses current space if slug omitted) |
|
|
88
|
-
| `gobi space
|
|
89
|
-
| `gobi space
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
|
94
|
-
|
|
95
|
-
| `gobi
|
|
96
|
-
| `gobi
|
|
97
|
-
| `gobi feed post-reply <updateId> --content <c>` | Post a reply to a brain update in the feed |
|
|
98
|
-
| `gobi feed edit-reply <replyId> --content <c>` | Edit a reply you authored |
|
|
99
|
-
| `gobi feed delete-reply <replyId>` | Delete a reply you authored |
|
|
100
|
-
|
|
101
|
-
`feed list` and `feed get` accept `--limit`/`--cursor` for pagination.
|
|
102
|
-
|
|
103
|
-
### Threads
|
|
104
|
-
|
|
105
|
-
> **Migration note:** Brain-update commands have been removed. To post user-level content, use `gobi global create-thread` (global space) or `gobi space create-thread` (a specific space).
|
|
106
|
-
|
|
107
|
-
| Command | Description |
|
|
108
|
-
|---------|-------------|
|
|
109
|
-
| `gobi space list-threads` | List threads in the current space |
|
|
110
|
-
| `gobi space get-thread <id>` | Get a thread and its replies |
|
|
111
|
-
| `gobi space create-thread --title <t> --content <c>` | Create a thread |
|
|
112
|
-
| `gobi space edit-thread <id> [--title <t>] [--content <c>]` | Edit a thread (at least one required) |
|
|
113
|
-
| `gobi space delete-thread <id>` | Delete a thread |
|
|
114
|
-
|
|
115
|
-
### Replies
|
|
116
|
-
|
|
117
|
-
| Command | Description |
|
|
118
|
-
|---------|-------------|
|
|
119
|
-
| `gobi space create-reply <threadId> --content <c>` | Reply to a thread |
|
|
104
|
+
| `gobi space feed` | Unified feed (posts + replies, newest first) in the space |
|
|
105
|
+
| `gobi space list-topics` | List topics in the space, ordered by most recent linkage |
|
|
106
|
+
| `gobi space list-topic-posts <topicSlug>` | List posts tagged with a topic |
|
|
107
|
+
| `gobi space list-posts` | List posts in the space |
|
|
108
|
+
| `gobi space get-post <postId>` | Get a post with its ancestors and replies |
|
|
109
|
+
| `gobi space create-post --title <t> --content <c>` | Create a post |
|
|
110
|
+
| `gobi space edit-post <postId> [--title <t>] [--content <c>]` | Edit a post (at least one required) |
|
|
111
|
+
| `gobi space delete-post <postId>` | Delete a post |
|
|
112
|
+
| `gobi space create-reply <postId> --content <c>` | Reply to a post |
|
|
120
113
|
| `gobi space edit-reply <replyId> --content <c>` | Edit a reply |
|
|
121
114
|
| `gobi space delete-reply <replyId>` | Delete a reply |
|
|
122
115
|
|
|
123
|
-
### Global
|
|
116
|
+
### Global feed
|
|
124
117
|
|
|
125
|
-
The global
|
|
118
|
+
The global feed is the public, slugless feed of vault-authored posts visible across all spaces.
|
|
126
119
|
|
|
127
120
|
| Command | Description |
|
|
128
121
|
|---------|-------------|
|
|
129
|
-
| `gobi global
|
|
130
|
-
| `gobi global
|
|
131
|
-
| `gobi global
|
|
132
|
-
| `gobi global create-
|
|
133
|
-
| `gobi global
|
|
122
|
+
| `gobi global feed` | List the global public feed (posts + replies, newest first) |
|
|
123
|
+
| `gobi global list-posts [--mine] [--vault-slug <slug>]` | List posts in the global feed |
|
|
124
|
+
| `gobi global get-post <postId>` | Get a global post with its ancestors and replies |
|
|
125
|
+
| `gobi global create-post [--title <t>] (--content <c> \| --rich-text <json>)` | Create a post in the global feed |
|
|
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 global post |
|
|
129
|
+
| `gobi global edit-reply <replyId> --content <c>` | Edit a reply you authored |
|
|
130
|
+
| `gobi global delete-reply <replyId>` | Delete a reply you authored |
|
|
134
131
|
|
|
135
132
|
### Sessions
|
|
136
133
|
|
|
@@ -151,53 +148,44 @@ The global thread space is a slugless message feed visible across all spaces.
|
|
|
151
148
|
|
|
152
149
|
Times are ISO 8601 UTC (e.g. `2026-03-20T00:00:00Z`).
|
|
153
150
|
|
|
154
|
-
###
|
|
151
|
+
### Saved
|
|
152
|
+
|
|
153
|
+
`gobi saved` is the user's personal saved-knowledge collection — notes you author and posts you bookmark.
|
|
154
|
+
|
|
155
|
+
#### Saved notes
|
|
155
156
|
|
|
156
157
|
| Command | Description |
|
|
157
158
|
|---------|-------------|
|
|
158
|
-
| `gobi
|
|
159
|
-
| `gobi
|
|
160
|
-
| `gobi
|
|
161
|
-
| `gobi
|
|
162
|
-
| `gobi
|
|
163
|
-
|
|
164
|
-
`notes list` and `notes create` accept `--timezone <iana>` (default: system timezone) for day boundaries.
|
|
165
|
-
`notes list` also accepts `--limit`/`--cursor` for pagination.
|
|
159
|
+
| `gobi saved note list [--date YYYY-MM-DD]` | List your notes (recent via cursor, or all for a day) |
|
|
160
|
+
| `gobi saved note get <id>` | Get a single note |
|
|
161
|
+
| `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 (at least one required; `--agent-id null` clears the link) |
|
|
163
|
+
| `gobi saved note delete <id>` | Delete a note you authored |
|
|
166
164
|
|
|
167
|
-
|
|
165
|
+
`saved note list` and `saved note create` accept `--timezone <iana>` (default: system timezone).
|
|
168
166
|
|
|
169
|
-
|
|
167
|
+
#### Saved posts
|
|
170
168
|
|
|
171
169
|
| Command | Description |
|
|
172
170
|
|---------|-------------|
|
|
173
|
-
| `gobi
|
|
174
|
-
| `gobi
|
|
175
|
-
| `gobi
|
|
176
|
-
| `gobi
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
| `gobi proposal revise <id> <comment>` | Mark for revision and record the user's comment |
|
|
182
|
-
|
|
183
|
-
### Sync
|
|
171
|
+
| `gobi saved post list [--type all\|article\|space-post]` | List posts you've saved |
|
|
172
|
+
| `gobi saved post get <postId>` | Get a saved post snapshot |
|
|
173
|
+
| `gobi saved post create --source <id>` | Save a post or reply by id |
|
|
174
|
+
| `gobi saved post delete <postId>` | Remove a post from your saved collection |
|
|
175
|
+
|
|
176
|
+
### Drafts
|
|
177
|
+
|
|
178
|
+
Drafts are authored by your agent during chat (or by external agents using `gobi draft add` as their tool layer). Each draft carries 0–3 AI-suggested actions the user can pick from. The top 5 pending drafts (lowest priority first) feed the agent's system prompt every turn. Every draft is anchored to the chat session that produced it.
|
|
184
179
|
|
|
185
180
|
| Command | Description |
|
|
186
181
|
|---------|-------------|
|
|
187
|
-
| `gobi
|
|
188
|
-
|
|
189
|
-
|
|
|
190
|
-
|
|
191
|
-
|
|
|
192
|
-
|
|
|
193
|
-
|
|
|
194
|
-
| `--dir <path>` | Local vault directory (default: current directory) |
|
|
195
|
-
| `--dry-run` | Preview changes without making them |
|
|
196
|
-
| `--full` | Full sync: ignore cursor and hash cache, re-check every file |
|
|
197
|
-
| `--path <path>` | Restrict sync to specific file/folder (repeatable) |
|
|
198
|
-
| `--plan-file <path>` | Write dry-run plan to file, or read plan to execute |
|
|
199
|
-
| `--execute` | Execute a previously written plan file (requires `--plan-file`) |
|
|
200
|
-
| `--conflict-choices <json>` | Per-file conflict resolutions as JSON (use with `--execute`) |
|
|
182
|
+
| `gobi draft list [--limit N]` | List drafts (priority ASC, then newest first) |
|
|
183
|
+
| `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 to attach AI-suggested actions. `--session` falls back to `$GOBI_SESSION_ID`. Use `-` for content to read from stdin. |
|
|
185
|
+
| `gobi draft delete <id>` | Delete a draft |
|
|
186
|
+
| `gobi draft prioritize <id> <priority>` | Set priority (lower = higher) |
|
|
187
|
+
| `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
|
+
| `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 |
|
|
201
189
|
|
|
202
190
|
### Global options
|
|
203
191
|
|
|
@@ -205,7 +193,7 @@ Proposals are authored by your agent during chat (or by external agents using `g
|
|
|
205
193
|
|--------|-------|-------------|
|
|
206
194
|
| `--json` | All commands | Output results as JSON |
|
|
207
195
|
| `--space-slug <slug>` | `space` commands | Override the default space (from `.gobi/settings.yaml`) |
|
|
208
|
-
| `--vault-slug <slug>` | Per-command | Override the default vault; available on
|
|
196
|
+
| `--vault-slug <slug>` | Per-command | Override the default vault; available on post/reply commands that upload attachments and on `global create-post` |
|
|
209
197
|
|
|
210
198
|
## Configuration
|
|
211
199
|
|
|
@@ -222,6 +210,7 @@ Proposals are authored by your agent during chat (or by external agents using `g
|
|
|
222
210
|
|------|-------------|
|
|
223
211
|
| `~/.gobi/credentials.json` | Stored authentication tokens |
|
|
224
212
|
| `.gobi/settings.yaml` | Per-project vault and space configuration |
|
|
213
|
+
| `PUBLISH.md` | Vault profile document with YAML frontmatter, published via `gobi vault publish` |
|
|
225
214
|
|
|
226
215
|
## Development
|
|
227
216
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: space-explore
|
|
3
|
-
description: Explore what's happening in the active Gobi space —
|
|
3
|
+
description: Explore what's happening in the active Gobi space — posts and learnings shared by others.
|
|
4
4
|
argument-hint: "[topic or keyword]"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
Always use the globally installed `gobi` binary (not via npx or ts-node).
|
|
8
8
|
|
|
9
|
-
Explore the active Gobi space to surface
|
|
9
|
+
Explore the active Gobi space to surface posts, topics, and learnings from others:
|
|
10
10
|
|
|
11
11
|
1. Run these three commands in parallel:
|
|
12
|
-
- `gobi --json space list-
|
|
13
|
-
- `gobi --json space list-topics` — available topics
|
|
14
|
-
- `gobi --json feed
|
|
15
|
-
2. Display results in a readable summary, grouped by type (Topics /
|
|
16
|
-
3. If `$ARGUMENTS` is provided, filter or highlight entries relevant to that topic or keyword. If a matching topic is found, also run `gobi --json space list-topic-
|
|
12
|
+
- `gobi --json space list-posts` — recent posts in the space
|
|
13
|
+
- `gobi --json space list-topics` — available topics in the space
|
|
14
|
+
- `gobi --json global feed` — recent posts and replies shared by members across the platform
|
|
15
|
+
2. Display results in a readable summary, grouped by type (Topics / Space posts / Global feed).
|
|
16
|
+
3. If `$ARGUMENTS` is provided, filter or highlight entries relevant to that topic or keyword. If a matching topic is found, also run `gobi --json space list-topic-posts <topicSlug>` to show posts tagged with that topic.
|
|
17
17
|
4. Ask the user if they'd like to read anything in full:
|
|
18
|
-
- For a topic: run `gobi space list-topic-
|
|
19
|
-
- For a
|
|
20
|
-
- For a feed
|
|
18
|
+
- For a topic: run `gobi space list-topic-posts <topicSlug>` and show the posts.
|
|
19
|
+
- For a space post: run `gobi space get-post <postId>` and show it with ancestors and replies.
|
|
20
|
+
- For a global feed post: run `gobi global get-post <postId>` to show it with ancestors and replies.
|
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 vault post to share to the global feed.
|
|
4
4
|
argument-hint: "[context]"
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -8,15 +8,15 @@ Always use the globally installed `gobi` binary (not via npx or ts-node).
|
|
|
8
8
|
|
|
9
9
|
## Pre-flight check
|
|
10
10
|
|
|
11
|
-
First, verify the user is
|
|
11
|
+
First, verify the user is set up:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
gobi --json auth status
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Check that `.gobi/settings.yaml` exists and contains both `vaultSlug` and `selectedSpaceSlug`. If not
|
|
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 vault 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
|
|
|
@@ -34,12 +34,18 @@ Focus on:
|
|
|
34
34
|
|
|
35
35
|
## Present to the user
|
|
36
36
|
|
|
37
|
-
Format the draft as a short
|
|
37
|
+
Format the draft as a short post (2–5 bullet points max). Show it to the user and ask for confirmation before posting.
|
|
38
38
|
|
|
39
|
-
Once confirmed, post it:
|
|
39
|
+
Once confirmed, post it to the global feed:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
gobi
|
|
42
|
+
gobi global create-post --title "<short title>" --content "<confirmed content>"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or to the active space:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
gobi space create-post --title "<short title>" --content "<confirmed content>"
|
|
43
49
|
```
|
|
44
50
|
|
|
45
51
|
Confirm success and show the user the result.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { readFileSync } from "fs";
|
|
2
|
+
import { apiDelete, apiGet, apiPatch, apiPost } from "../client.js";
|
|
3
|
+
import { isJsonMode, jsonOut, unwrapResp } from "./utils.js";
|
|
4
|
+
function readContent(value) {
|
|
5
|
+
if (value === "-")
|
|
6
|
+
return readFileSync("/dev/stdin", "utf8");
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
function snippet(content, max = 80) {
|
|
10
|
+
const single = content.replace(/\s+/g, " ");
|
|
11
|
+
return single.length > max ? `${single.slice(0, max)}…` : single;
|
|
12
|
+
}
|
|
13
|
+
function parseActionFlags(values) {
|
|
14
|
+
if (!values)
|
|
15
|
+
return [];
|
|
16
|
+
return values
|
|
17
|
+
.map((v) => v.trim())
|
|
18
|
+
.filter(Boolean)
|
|
19
|
+
.slice(0, 3)
|
|
20
|
+
.map((label) => ({ label }));
|
|
21
|
+
}
|
|
22
|
+
function formatDraftLine(d) {
|
|
23
|
+
const status = d.status === "pending" ? "·" : "✓";
|
|
24
|
+
const actionCount = d.actions.length;
|
|
25
|
+
return `- [${status}] p${d.priority} rev${d.revision} ${d.draftId.slice(0, 8)} ${snippet(d.title)} (${actionCount} action${actionCount === 1 ? "" : "s"})`;
|
|
26
|
+
}
|
|
27
|
+
export function registerDraftCommand(program) {
|
|
28
|
+
// The draft command surface is designed for agent use: every subcommand
|
|
29
|
+
// accepts `--json` (set globally) and returns the same envelope shape, and
|
|
30
|
+
// the agent-authoring flow funnels through `add` + `revise` while user-
|
|
31
|
+
// facing decisions go through `action` and `revise` (with --comment).
|
|
32
|
+
const draft = program
|
|
33
|
+
.command("draft")
|
|
34
|
+
.description("Drafts authored by your agent during chat. Each carries up to 3 AI-suggested actions. Top-5 pending feed the system prompt; picking an action posts a synthesized message into the originating session.");
|
|
35
|
+
// ── List ──
|
|
36
|
+
draft
|
|
37
|
+
.command("list")
|
|
38
|
+
.description("List drafts (priority ASC, then newest first).")
|
|
39
|
+
.option("--limit <number>", "Max drafts to return (1-200)", "50")
|
|
40
|
+
.action(async (opts) => {
|
|
41
|
+
const params = { limit: parseInt(opts.limit, 10) };
|
|
42
|
+
const resp = (await apiGet("/app/drafts", params));
|
|
43
|
+
const items = (resp.data || []);
|
|
44
|
+
if (isJsonMode(draft)) {
|
|
45
|
+
jsonOut(items);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (!items.length) {
|
|
49
|
+
console.log("No drafts.");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
console.log(`Drafts (${items.length}):`);
|
|
53
|
+
for (const d of items)
|
|
54
|
+
console.log(formatDraftLine(d));
|
|
55
|
+
});
|
|
56
|
+
// ── Get ──
|
|
57
|
+
draft
|
|
58
|
+
.command("get <draftId>")
|
|
59
|
+
.description("Show one draft with its history and suggested actions.")
|
|
60
|
+
.action(async (draftId) => {
|
|
61
|
+
const resp = (await apiGet(`/app/drafts/${draftId}`));
|
|
62
|
+
const d = unwrapResp(resp);
|
|
63
|
+
if (isJsonMode(draft)) {
|
|
64
|
+
jsonOut(d);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
console.log(`Draft ${d.draftId}`);
|
|
68
|
+
console.log(` title: ${d.title}`);
|
|
69
|
+
console.log(` status: ${d.status}`);
|
|
70
|
+
console.log(` priority: ${d.priority}`);
|
|
71
|
+
console.log(` revision: ${d.revision}`);
|
|
72
|
+
console.log(` session: ${d.sessionId}`);
|
|
73
|
+
console.log(` created: ${d.createdAt}`);
|
|
74
|
+
console.log("");
|
|
75
|
+
console.log("Content:");
|
|
76
|
+
console.log(d.content);
|
|
77
|
+
if (d.actions.length) {
|
|
78
|
+
console.log("");
|
|
79
|
+
console.log("Suggested actions:");
|
|
80
|
+
d.actions.forEach((a, i) => console.log(` [${i}] ${a.label}`));
|
|
81
|
+
}
|
|
82
|
+
if (d.history.length) {
|
|
83
|
+
console.log("");
|
|
84
|
+
console.log("History:");
|
|
85
|
+
for (const h of d.history) {
|
|
86
|
+
console.log(` ${h.createdAt} rev${h.revision} ${h.type}`);
|
|
87
|
+
if (h.type === "created" || h.type === "revised") {
|
|
88
|
+
if (h.title !== undefined)
|
|
89
|
+
console.log(` title: ${h.title}`);
|
|
90
|
+
if (h.content !== undefined) {
|
|
91
|
+
console.log(` content: ${snippet(h.content, 200)}`);
|
|
92
|
+
}
|
|
93
|
+
if (h.actions !== undefined && h.actions.length) {
|
|
94
|
+
console.log(` actions: ${h.actions.map((a) => a.label).join(" | ")}`);
|
|
95
|
+
}
|
|
96
|
+
if (h.comment !== undefined)
|
|
97
|
+
console.log(` comment: ${h.comment}`);
|
|
98
|
+
}
|
|
99
|
+
else if (h.type === "prioritized" && h.priority !== undefined) {
|
|
100
|
+
console.log(` priority=${h.priority}`);
|
|
101
|
+
}
|
|
102
|
+
else if (h.type === "actioned") {
|
|
103
|
+
console.log(` action[${h.actionIndex}]=${h.actionLabel}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
// ── Add ──
|
|
109
|
+
draft
|
|
110
|
+
.command("add <title> <content>")
|
|
111
|
+
.description("Add a draft. Pass '-' for content to read from stdin. Pass --action up to 3 times to attach AI-suggested actions. Requires a chat session — the agent runtime exports GOBI_SESSION_ID automatically; outside that, pass --session.")
|
|
112
|
+
.option("--session <sessionId>", "Originating chat session UUID. Falls back to $GOBI_SESSION_ID when set.")
|
|
113
|
+
.option("--priority <number>", "Priority (lower = higher), default 100")
|
|
114
|
+
.option("--action <label>", "Suggested action label (repeatable, max 3). Each label is what the user sees on the button.", (value, prev = []) => [...prev, value], [])
|
|
115
|
+
.action(async (title, content, opts) => {
|
|
116
|
+
const sessionId = opts.session || process.env.GOBI_SESSION_ID || "";
|
|
117
|
+
if (!sessionId) {
|
|
118
|
+
console.error("Error: missing session id. Pass --session <uuid> or set GOBI_SESSION_ID in the environment.");
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
const body = {
|
|
122
|
+
title,
|
|
123
|
+
content: readContent(content),
|
|
124
|
+
sessionId,
|
|
125
|
+
};
|
|
126
|
+
if (opts.priority)
|
|
127
|
+
body.priority = parseInt(opts.priority, 10);
|
|
128
|
+
const actions = parseActionFlags(opts.action);
|
|
129
|
+
if (actions.length)
|
|
130
|
+
body.actions = actions;
|
|
131
|
+
const resp = (await apiPost("/app/drafts", body));
|
|
132
|
+
const d = unwrapResp(resp);
|
|
133
|
+
if (isJsonMode(draft)) {
|
|
134
|
+
jsonOut(d);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
console.log(`Created ${d.draftId} (priority ${d.priority}, ${d.actions.length} action${d.actions.length === 1 ? "" : "s"}).`);
|
|
138
|
+
});
|
|
139
|
+
// ── Delete ──
|
|
140
|
+
draft
|
|
141
|
+
.command("delete <draftId>")
|
|
142
|
+
.description("Delete a draft.")
|
|
143
|
+
.action(async (draftId) => {
|
|
144
|
+
await apiDelete(`/app/drafts/${draftId}`);
|
|
145
|
+
if (isJsonMode(draft)) {
|
|
146
|
+
jsonOut({ deleted: draftId });
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
console.log(`Deleted ${draftId}.`);
|
|
150
|
+
});
|
|
151
|
+
// ── Prioritize ──
|
|
152
|
+
draft
|
|
153
|
+
.command("prioritize <draftId> <priority>")
|
|
154
|
+
.description("Set priority (lower = higher). Top 5 feed the system prompt.")
|
|
155
|
+
.action(async (draftId, priority) => {
|
|
156
|
+
const resp = (await apiPatch(`/app/drafts/${draftId}/priority`, {
|
|
157
|
+
priority: parseInt(priority, 10),
|
|
158
|
+
}));
|
|
159
|
+
const d = unwrapResp(resp);
|
|
160
|
+
if (isJsonMode(draft)) {
|
|
161
|
+
jsonOut(d);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
console.log(`Set ${d.draftId} priority to ${d.priority}.`);
|
|
165
|
+
});
|
|
166
|
+
// ── Action ──
|
|
167
|
+
draft
|
|
168
|
+
.command("action <draftId> <actionIndex>")
|
|
169
|
+
.description("Take one of the draft's suggested actions by 0-based index. Marks the draft 'actioned' and the client posts the synthesized message into the originating session.")
|
|
170
|
+
.action(async (draftId, actionIndex) => {
|
|
171
|
+
const idx = parseInt(actionIndex, 10);
|
|
172
|
+
if (Number.isNaN(idx) || idx < 0 || idx > 2) {
|
|
173
|
+
console.error("Error: actionIndex must be 0, 1, or 2.");
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
const resp = (await apiPost(`/app/drafts/${draftId}/action`, {
|
|
177
|
+
actionIndex: idx,
|
|
178
|
+
}));
|
|
179
|
+
const d = unwrapResp(resp);
|
|
180
|
+
if (isJsonMode(draft)) {
|
|
181
|
+
jsonOut(d);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const label = d.actions[idx]?.label ?? `action ${idx}`;
|
|
185
|
+
console.log(`Took action "${label}" on ${d.draftId}.`);
|
|
186
|
+
});
|
|
187
|
+
// ── Revise ──
|
|
188
|
+
draft
|
|
189
|
+
.command("revise <draftId> <comment>")
|
|
190
|
+
.description("Bump the draft to a new revision. Comment is required. Pass --title, --content, and/or --action to update the draft in the same call (--action repeatable, max 3, replaces all). Pass '-' for any of comment/title/content to read from stdin.")
|
|
191
|
+
.option("--title <title>", "Replacement title")
|
|
192
|
+
.option("--content <content>", "Replacement content; pass '-' to read from stdin")
|
|
193
|
+
.option("--action <label>", "Replacement suggested action label (repeatable, max 3). When passed, replaces the entire actions array.", (value, prev = []) => [...prev, value], [])
|
|
194
|
+
.action(async (draftId, comment, opts) => {
|
|
195
|
+
const body = {
|
|
196
|
+
comment: readContent(comment),
|
|
197
|
+
};
|
|
198
|
+
if (opts.title !== undefined)
|
|
199
|
+
body.title = opts.title;
|
|
200
|
+
if (opts.content !== undefined)
|
|
201
|
+
body.content = readContent(opts.content);
|
|
202
|
+
if (opts.action && opts.action.length > 0) {
|
|
203
|
+
body.actions = parseActionFlags(opts.action);
|
|
204
|
+
}
|
|
205
|
+
const resp = (await apiPost(`/app/drafts/${draftId}/revise`, body));
|
|
206
|
+
const d = unwrapResp(resp);
|
|
207
|
+
if (isJsonMode(draft)) {
|
|
208
|
+
jsonOut(d);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
console.log(`Revised ${d.draftId} → rev${d.revision}.`);
|
|
212
|
+
});
|
|
213
|
+
}
|