@gobi-ai/cli 2.0.9 → 2.0.11

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": "2.0.9",
7
+ "version": "2.0.11",
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": "2.0.9",
12
+ "version": "2.0.11",
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": "2.0.9",
4
+ "version": "2.0.11",
5
5
  "author": {
6
6
  "name": "gobi-ai"
7
7
  },
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: post
3
+ description: Draft a post from recent conversation history and publish it to the spaces it best fits. Default mode requires approval; pass `bypass` to post without confirmation.
4
+ argument-hint: "[approval|bypass]"
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ Always use the globally installed `gobi` binary (not via npx or ts-node).
9
+
10
+ ## Argument: permissionMode
11
+
12
+ `$ARGUMENTS` is the permission mode. Accept exactly:
13
+
14
+ - `approval` (default if `$ARGUMENTS` is empty or unrecognized) — draft, present, and require user confirmation before posting.
15
+ - `bypass` — draft and post without a confirmation step.
16
+
17
+ Treat anything else as `approval`. Do not ask the user which mode to use — the argument is the answer.
18
+
19
+ ## Pre-flight check
20
+
21
+ ```bash
22
+ gobi --json auth status
23
+ ```
24
+
25
+ If unauthenticated, stop and ask the user to run `/gobi:login`.
26
+
27
+ ## 1. List spaces and choose targets
28
+
29
+ ```bash
30
+ gobi --json space list
31
+ ```
32
+
33
+ Each entry has `slug`, `name`, `description`, and (sometimes) `rules`. If the list is empty, stop — there's nowhere to post.
34
+
35
+ Review the recent conversation history and extract content that is:
36
+
37
+ - **Reusable** — others could apply it to their own work.
38
+ - **Generalizable** — patterns, decisions, constraints, discoveries; not a one-off task log.
39
+ - **Not sensitive** — exclude code snippets, file paths, PII, credentials, internal URLs, proprietary details.
40
+
41
+ Then match the content against each space's `name`, `description`, and `rules`. Pick the **space(s) the content genuinely fits** — could be one, could be a few. If nothing fits, stop and tell the user no space matched; do **not** force a post into a tangentially related space.
42
+
43
+ If a space's `rules` constrain format, topic, or tone, follow them — or skip that space.
44
+
45
+ ## 2. Draft the post
46
+
47
+ For each target space, prepare:
48
+
49
+ - **Title** — short, descriptive, no leading `#`, does not duplicate the body's first line.
50
+ - **Content** — markdown body (2–5 bullets is usually right). Do not repeat the title inside the content. Tailor per space if their rules differ; otherwise the same draft can go to multiple spaces.
51
+
52
+ ## 3. Approval mode (default)
53
+
54
+ Show the user, for each target space:
55
+
56
+ - The space slug and name.
57
+ - The exact `gobi space create-post` command that will run.
58
+ - The resolved title and a preview of the content.
59
+
60
+ Wait for the user's confirmation. Accept redirects ("only post to X", "rewrite the title", "skip space Y") and re-present before posting. Do not post until the user confirms.
61
+
62
+ ## 4. Bypass mode
63
+
64
+ Skip the confirmation step. Proceed straight to posting. Still print the target space(s) and the command(s) to the terminal so the action is visible.
65
+
66
+ ## 5. Post
67
+
68
+ For each chosen space, run:
69
+
70
+ ```bash
71
+ gobi space create-post --space-slug <slug> --title "<title>" --content "<content>"
72
+ ```
73
+
74
+ (`--space-slug` overrides `.gobi/settings.yaml`, so this works without `gobi space warp` first.)
75
+
76
+ After each post, echo the result with a shareable URL built from the response:
77
+
78
+ `https://gobispace.com/spaces/<spaceSlug>?postId=<id>`
79
+
80
+ If a post fails, report the error and continue with the remaining targets — one failure should not block the others.
@@ -183,6 +183,7 @@ export function registerGlobalCommand(program) {
183
183
  .option("--rich-text <richText>", "Rich-text JSON array (mutually exclusive with --content)")
184
184
  .option("--vault-slug <vaultSlug>", "Attribute the post to this vault (sets authorVaultSlug). Defaults to your primary vault.")
185
185
  .option("--auto-attachments", "Upload wiki-linked [[files]] to webdrive before posting (also sets authorVaultSlug to that vault)")
186
+ .option("--draft-id <draftId>", "Link this post back to the draft it was created from (records postId on draft.metadata so the client can render an 'Open post' button).")
186
187
  .action(async (opts) => {
187
188
  if (!opts.content && !opts.richText) {
188
189
  throw new Error("Provide either --content or --rich-text.");
@@ -220,6 +221,19 @@ export function registerGlobalCommand(program) {
220
221
  body.authorVaultSlug = authorVaultSlug;
221
222
  const resp = (await apiPost(`/posts`, body));
222
223
  const post = unwrapResp(resp);
224
+ if (opts.draftId && post.id != null) {
225
+ try {
226
+ await apiPatch(`/app/drafts/${opts.draftId}/metadata`, {
227
+ postId: typeof post.id === "number" ? post.id : Number(post.id),
228
+ spaceSlug: null,
229
+ });
230
+ }
231
+ catch (e) {
232
+ // Don't fail the create if linking fails — the post is live; just
233
+ // surface a warning so the agent can mention it.
234
+ console.error(`Warning: failed to link post to draft ${opts.draftId}: ${e.message}`);
235
+ }
236
+ }
223
237
  if (isJsonMode(global)) {
224
238
  jsonOut(post);
225
239
  return;
@@ -227,7 +241,8 @@ export function registerGlobalCommand(program) {
227
241
  console.log(`Post created!\n` +
228
242
  ` ID: ${post.id}\n` +
229
243
  (post.title ? ` Title: ${post.title}\n` : "") +
230
- ` Created: ${post.createdAt}`);
244
+ ` Created: ${post.createdAt}` +
245
+ (opts.draftId ? `\n Linked to draft: ${opts.draftId}` : ""));
231
246
  });
232
247
  // ── Edit post ──
233
248
  global
@@ -318,6 +318,7 @@ export function registerSpaceCommand(program) {
318
318
  .option("--auto-attachments", "Upload wiki-linked [[files]] to webdrive before posting (also attributes the post to that vault)")
319
319
  .option("--vault-slug <vaultSlug>", "Attribute the post to this vault (sets authorVaultId). Also used as upload destination for --auto-attachments.")
320
320
  .option("--space-slug <spaceSlug>", "Space slug (overrides .gobi/settings.yaml)")
321
+ .option("--draft-id <draftId>", "Link this post back to the draft it was created from (records postId/spaceSlug on draft.metadata so the client can render an 'Open post' button).")
321
322
  .action(async (opts) => {
322
323
  if (!opts.content && !opts.richText) {
323
324
  throw new Error("Provide either --content or --rich-text.");
@@ -356,6 +357,19 @@ export function registerSpaceCommand(program) {
356
357
  const spaceSlug = resolveSpaceSlug(space, opts);
357
358
  const resp = (await apiPost(`/spaces/${spaceSlug}/posts`, body));
358
359
  const post = unwrapResp(resp);
360
+ if (opts.draftId && post.id != null) {
361
+ try {
362
+ await apiPatch(`/app/drafts/${opts.draftId}/metadata`, {
363
+ postId: typeof post.id === "number" ? post.id : Number(post.id),
364
+ spaceSlug,
365
+ });
366
+ }
367
+ catch (e) {
368
+ // Don't fail the create if linking fails — the post is live; just
369
+ // surface a warning so the agent can mention it.
370
+ console.error(`Warning: failed to link post to draft ${opts.draftId}: ${e.message}`);
371
+ }
372
+ }
359
373
  if (isJsonMode(space)) {
360
374
  jsonOut(post);
361
375
  return;
@@ -363,7 +377,8 @@ export function registerSpaceCommand(program) {
363
377
  console.log(`Post created!\n` +
364
378
  ` ID: ${post.id}\n` +
365
379
  (post.title ? ` Title: ${post.title}\n` : "") +
366
- ` Created: ${post.createdAt}`);
380
+ ` Created: ${post.createdAt}` +
381
+ (opts.draftId ? `\n Linked to draft: ${opts.draftId}` : ""));
367
382
  });
368
383
  space
369
384
  .command("edit-post <postId>")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobi-ai/cli",
3
- "version": "2.0.9",
3
+ "version": "2.0.11",
4
4
  "description": "CLI client for the Gobi collaborative knowledge platform",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,7 +10,7 @@ description: >-
10
10
  allowed-tools: Bash(gobi:*)
11
11
  metadata:
12
12
  author: gobi-ai
13
- version: "2.0.9"
13
+ version: "2.0.10"
14
14
  ---
15
15
 
16
16
  # gobi-draft
@@ -74,6 +74,15 @@ The literal `::` separator splits the two. Use `message` whenever the click shou
74
74
 
75
75
  When the user picks an action via `gobi draft action <id> <index>`, the response includes the picked action's `message` (or `label` as fallback) in `data.actions[index]`, which the client then posts into the originating session.
76
76
 
77
+ ## Linking a created post back to its draft
78
+
79
+ When the user picks an action like "Post to Global Feed" / "Post to <space>" and your next turn creates the post, pass `--draft-id <draftId>` to `gobi space create-post` or `gobi global create-post`. The CLI records the resulting `postId` (and `spaceSlug` for space posts) on `draft.metadata`, which the client uses to render an "Open post" button on the actioned draft. Without `--draft-id` the post is still created, but the draft and the post stay disconnected in the UI.
80
+
81
+ ```bash
82
+ gobi --json global create-post --title "..." --content "..." --draft-id <draftId>
83
+ gobi --json space create-post --space-slug <slug> --title "..." --content "..." --draft-id <draftId>
84
+ ```
85
+
77
86
  ## Available Commands
78
87
 
79
88
  - `gobi draft` — 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.
@@ -10,7 +10,7 @@ description: >-
10
10
  allowed-tools: Bash(gobi:*)
11
11
  metadata:
12
12
  author: gobi-ai
13
- version: "2.0.9"
13
+ version: "2.0.10"
14
14
  ---
15
15
 
16
16
  # gobi-space
@@ -30,6 +30,7 @@ Anything you can do to a Space Post (reply, edit, delete, attribute to a vault)
30
30
 
31
31
  - When the user wants to explore or catch up on what's happening in their space, invoke `/gobi:space-explore`.
32
32
  - When the user wants to share or post learnings from the current session, invoke `/gobi:space-share`.
33
+ - When the user wants to draft a post from the current session and route it to whichever space(s) it best fits, invoke `/gobi:post` (default approval mode; pass `bypass` to skip confirmation).
33
34
 
34
35
  ## Authoring posts: title vs. content
35
36
 
@@ -131,6 +132,10 @@ gobi --json space list-posts
131
132
  Posts and replies are publicly visible — in a community space (`gobi space …`) or in the global feed (`gobi global …`). Before running any write, confirm with the user — show the exact command and the resolved title, content (or a short preview), and `authorVaultSlug` if `--vault-slug` / `--auto-attachments` is set. This applies even when running autonomously.
132
133
 
133
134
  - `create-post` / `create-reply` — content goes live on submission.
135
+
136
+ ### Linking back to a draft
137
+
138
+ When a `create-post` is the side-effect of an actioned draft (e.g. the user picked "Post to Global Feed" / "Post to <space>"), pass `--draft-id <draftId>` to `gobi space create-post` or `gobi global create-post`. The CLI records `{ postId, spaceSlug? }` on `draft.metadata`, which the client renders as an "Open post" button on the actioned draft. Without `--draft-id` the post is still created, but the draft and post stay disconnected in the UI.
134
139
  - `edit-post` / `edit-reply` — confirm the *new* content; people who already saw the original may re-see it.
135
140
  - `delete-post` / `delete-reply` — irreversible. Flag that explicitly and confirm the target id before running.
136
141
 
@@ -77,6 +77,7 @@ Options:
77
77
  --rich-text <richText> Rich-text JSON array (mutually exclusive with --content)
78
78
  --vault-slug <vaultSlug> Attribute the post to this vault (sets authorVaultSlug). Defaults to your primary vault.
79
79
  --auto-attachments Upload wiki-linked [[files]] to webdrive before posting (also sets authorVaultSlug to that vault)
80
+ --draft-id <draftId> Link this post back to the draft it was created from (records postId on draft.metadata so the client can render an 'Open post' button).
80
81
  -h, --help display help for command
81
82
  ```
82
83
 
@@ -123,6 +123,7 @@ Options:
123
123
  --auto-attachments Upload wiki-linked [[files]] to webdrive before posting (also attributes the post to that vault)
124
124
  --vault-slug <vaultSlug> Attribute the post to this vault (sets authorVaultId). Also used as upload destination for --auto-attachments.
125
125
  --space-slug <spaceSlug> Space slug (overrides .gobi/settings.yaml)
126
+ --draft-id <draftId> Link this post back to the draft it was created from (records postId/spaceSlug on draft.metadata so the client can render an 'Open post' button).
126
127
  -h, --help display help for command
127
128
  ```
128
129