@gobi-ai/cli 2.0.14 → 2.0.16
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/dist/attachments.js +97 -2
- package/dist/commands/global.js +11 -1
- package/dist/commands/space.js +11 -1
- package/package.json +1 -1
- package/skills/gobi-media/SKILL.md +14 -7
- package/skills/gobi-space/SKILL.md +8 -0
- package/skills/gobi-space/references/global.md +3 -0
- package/skills/gobi-space/references/space.md +3 -0
|
@@ -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.
|
|
7
|
+
"version": "2.0.16",
|
|
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.
|
|
12
|
+
"version": "2.0.16",
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "gobi-ai"
|
|
15
15
|
},
|
package/dist/attachments.js
CHANGED
|
@@ -1,8 +1,103 @@
|
|
|
1
|
-
import { existsSync, readFileSync, appendFileSync } from "fs";
|
|
1
|
+
import { existsSync, readFileSync, appendFileSync, statSync } from "fs";
|
|
2
2
|
import { EOL } from "os";
|
|
3
|
-
import { join, extname } from "path";
|
|
3
|
+
import { basename, join, extname, isAbsolute, resolve } from "path";
|
|
4
4
|
import ignore from "ignore";
|
|
5
5
|
import { WEBDRIVE_BASE_URL } from "./constants.js";
|
|
6
|
+
import { apiPost } from "./client.js";
|
|
7
|
+
// Best-effort extension → MIME mapping. Anything we don't recognize falls
|
|
8
|
+
// back to `application/octet-stream`; the backend caps size per content-type
|
|
9
|
+
// tier (5MB photos / 15MB GIFs / 512MB video) so it's the authority on what's
|
|
10
|
+
// allowed. We're just trying to set a usable Content-Type for the S3 PUT.
|
|
11
|
+
const POST_MEDIA_MIME_MAP = {
|
|
12
|
+
".jpg": "image/jpeg",
|
|
13
|
+
".jpeg": "image/jpeg",
|
|
14
|
+
".png": "image/png",
|
|
15
|
+
".gif": "image/gif",
|
|
16
|
+
".webp": "image/webp",
|
|
17
|
+
".heic": "image/heic",
|
|
18
|
+
".heif": "image/heif",
|
|
19
|
+
".avif": "image/avif",
|
|
20
|
+
".svg": "image/svg+xml",
|
|
21
|
+
".bmp": "image/bmp",
|
|
22
|
+
".tiff": "image/tiff",
|
|
23
|
+
".mp4": "video/mp4",
|
|
24
|
+
".mov": "video/quicktime",
|
|
25
|
+
".webm": "video/webm",
|
|
26
|
+
".m4v": "video/x-m4v",
|
|
27
|
+
".pdf": "application/pdf",
|
|
28
|
+
};
|
|
29
|
+
// X-style cap: 4 photos OR 1 GIF OR 1 video. Anything not photo/gif/video
|
|
30
|
+
// is treated as "photo" for cap purposes so misclassified files still get
|
|
31
|
+
// the 4-cap rather than slipping through unlimited.
|
|
32
|
+
export function assertPostAttachmentMix(paths) {
|
|
33
|
+
let photos = 0;
|
|
34
|
+
let gifs = 0;
|
|
35
|
+
let videos = 0;
|
|
36
|
+
for (const p of paths) {
|
|
37
|
+
const ext = extname(p).toLowerCase();
|
|
38
|
+
if (ext === ".gif")
|
|
39
|
+
gifs += 1;
|
|
40
|
+
else if ([".mp4", ".mov", ".webm", ".m4v"].includes(ext))
|
|
41
|
+
videos += 1;
|
|
42
|
+
else
|
|
43
|
+
photos += 1;
|
|
44
|
+
}
|
|
45
|
+
if (videos > 1)
|
|
46
|
+
throw new Error("Only 1 video allowed per post");
|
|
47
|
+
if (gifs > 1)
|
|
48
|
+
throw new Error("Only 1 GIF allowed per post");
|
|
49
|
+
if (photos > 4)
|
|
50
|
+
throw new Error("Up to 4 photos allowed per post");
|
|
51
|
+
if (videos > 0 && (gifs > 0 || photos > 0)) {
|
|
52
|
+
throw new Error("A video can't be combined with other media");
|
|
53
|
+
}
|
|
54
|
+
if (gifs > 0 && (videos > 0 || photos > 0)) {
|
|
55
|
+
throw new Error("A GIF can't be combined with other media");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Upload a single local file as a post attachment.
|
|
60
|
+
* init (`POST /posts/upload-url`) → PUT to S3 → return `{ mediaUrl, mediaKey }`
|
|
61
|
+
* suitable for the `attachments` array on create-post.
|
|
62
|
+
*/
|
|
63
|
+
export async function uploadPostAttachment(filePath) {
|
|
64
|
+
const abs = isAbsolute(filePath) ? filePath : resolve(process.cwd(), filePath);
|
|
65
|
+
if (!existsSync(abs)) {
|
|
66
|
+
throw new Error(`Attachment not found: ${filePath}`);
|
|
67
|
+
}
|
|
68
|
+
const ext = extname(abs).toLowerCase();
|
|
69
|
+
const contentType = POST_MEDIA_MIME_MAP[ext] || "application/octet-stream";
|
|
70
|
+
const fileSize = statSync(abs).size;
|
|
71
|
+
const initResp = (await apiPost("/posts/upload-url", {
|
|
72
|
+
fileName: basename(abs),
|
|
73
|
+
contentType,
|
|
74
|
+
fileSize,
|
|
75
|
+
}));
|
|
76
|
+
const data = (initResp.data ?? initResp);
|
|
77
|
+
const uploadUrl = data.uploadUrl;
|
|
78
|
+
const mediaUrl = data.mediaUrl;
|
|
79
|
+
const mediaKey = data.mediaKey;
|
|
80
|
+
if (!uploadUrl || !mediaUrl || !mediaKey) {
|
|
81
|
+
throw new Error("Upload init returned an incomplete payload");
|
|
82
|
+
}
|
|
83
|
+
const body = readFileSync(abs);
|
|
84
|
+
const putRes = await fetch(uploadUrl, {
|
|
85
|
+
method: "PUT",
|
|
86
|
+
headers: { "Content-Type": contentType },
|
|
87
|
+
body,
|
|
88
|
+
});
|
|
89
|
+
if (!putRes.ok) {
|
|
90
|
+
throw new Error(`Failed to PUT ${filePath} to S3: HTTP ${putRes.status}`);
|
|
91
|
+
}
|
|
92
|
+
return { mediaUrl, mediaKey };
|
|
93
|
+
}
|
|
94
|
+
export async function uploadPostAttachments(paths) {
|
|
95
|
+
const out = [];
|
|
96
|
+
for (const p of paths) {
|
|
97
|
+
out.push(await uploadPostAttachment(p));
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
6
101
|
export function extractWikiLinks(content) {
|
|
7
102
|
const seen = new Set();
|
|
8
103
|
const results = [];
|
package/dist/commands/global.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { apiGet, apiPost, apiPatch, apiDelete } from "../client.js";
|
|
2
2
|
import { fetchDraftSummary, isJsonMode, jsonOut, readStdin, resolveVaultSlug, unwrapResp, } from "./utils.js";
|
|
3
|
-
import { extractWikiLinks, uploadAttachments } from "../attachments.js";
|
|
3
|
+
import { extractWikiLinks, uploadAttachments, uploadPostAttachments, assertPostAttachmentMix, } from "../attachments.js";
|
|
4
4
|
import { getValidToken } from "../auth/manager.js";
|
|
5
5
|
function readContent(value) {
|
|
6
6
|
if (value === "-")
|
|
@@ -184,6 +184,7 @@ export function registerGlobalCommand(program) {
|
|
|
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
186
|
.option("--draft-id <draftId>", "Use this draft as the source of title and content (mutually exclusive with --title/--content/--rich-text). On success, links the post back by recording postId on draft.metadata so the client can render an 'Open post' button. The draft's vaultSlug seeds --vault-slug when not given explicitly.")
|
|
187
|
+
.option("--attach <file>", "Local media file to attach. Repeatable. X-style mix rule: up to 4 photos OR 1 GIF OR 1 video. Size ceilings: 5MB photos / 15MB GIFs / 512MB video.", (value, prev = []) => [...prev, value], [])
|
|
187
188
|
.action(async (opts) => {
|
|
188
189
|
if (opts.draftId) {
|
|
189
190
|
if (opts.title || opts.content || opts.richText) {
|
|
@@ -230,6 +231,10 @@ export function registerGlobalCommand(program) {
|
|
|
230
231
|
}
|
|
231
232
|
if (authorVaultSlug)
|
|
232
233
|
body.authorVaultSlug = authorVaultSlug;
|
|
234
|
+
if (opts.attach && opts.attach.length > 0) {
|
|
235
|
+
assertPostAttachmentMix(opts.attach);
|
|
236
|
+
body.attachments = await uploadPostAttachments(opts.attach);
|
|
237
|
+
}
|
|
233
238
|
const resp = (await apiPost(`/posts`, body));
|
|
234
239
|
const post = unwrapResp(resp);
|
|
235
240
|
if (opts.draftId && post.id != null) {
|
|
@@ -331,6 +336,7 @@ export function registerGlobalCommand(program) {
|
|
|
331
336
|
.option("--rich-text <richText>", "Rich-text JSON array (mutually exclusive with --content)")
|
|
332
337
|
.option("--vault-slug <vaultSlug>", "Attribute the reply to this vault (sets authorVaultSlug). Also used as upload destination for --auto-attachments.")
|
|
333
338
|
.option("--auto-attachments", "Upload wiki-linked [[files]] to webdrive before posting (also attributes the reply to that vault)")
|
|
339
|
+
.option("--attach <file>", "Local media file to attach to this reply. Repeatable. X-style mix rule: up to 4 photos OR 1 GIF OR 1 video. Size ceilings: 5MB photos / 15MB GIFs / 512MB video.", (value, prev = []) => [...prev, value], [])
|
|
334
340
|
.action(async (postId, opts) => {
|
|
335
341
|
if (!opts.content && !opts.richText) {
|
|
336
342
|
throw new Error("Provide either --content or --rich-text.");
|
|
@@ -364,6 +370,10 @@ export function registerGlobalCommand(program) {
|
|
|
364
370
|
}
|
|
365
371
|
if (authorVaultSlug)
|
|
366
372
|
body.authorVaultSlug = authorVaultSlug;
|
|
373
|
+
if (opts.attach && opts.attach.length > 0) {
|
|
374
|
+
assertPostAttachmentMix(opts.attach);
|
|
375
|
+
body.attachments = await uploadPostAttachments(opts.attach);
|
|
376
|
+
}
|
|
367
377
|
const resp = (await apiPost(`/posts/${postId}/replies`, body));
|
|
368
378
|
const reply = unwrapResp(resp);
|
|
369
379
|
if (isJsonMode(global)) {
|
package/dist/commands/space.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { apiGet, apiPost, apiPatch, apiDelete } from "../client.js";
|
|
2
2
|
import { requireSpace, selectSpace, setSpaceRequirement, writeSpaceSetting, } from "./init.js";
|
|
3
3
|
import { fetchDraftSummary, isJsonMode, jsonOut, readStdin, resolveSpaceSlug, resolveVaultSlug, unwrapResp, } from "./utils.js";
|
|
4
|
-
import { extractWikiLinks, uploadAttachments } from "../attachments.js";
|
|
4
|
+
import { extractWikiLinks, uploadAttachments, uploadPostAttachments, assertPostAttachmentMix, } from "../attachments.js";
|
|
5
5
|
import { getValidToken } from "../auth/manager.js";
|
|
6
6
|
function readContent(value) {
|
|
7
7
|
if (value === "-")
|
|
@@ -319,6 +319,7 @@ export function registerSpaceCommand(program) {
|
|
|
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
321
|
.option("--draft-id <draftId>", "Use this draft as the source of title and content (mutually exclusive with --title/--content/--rich-text). On success, links the post back by recording postId/spaceSlug on draft.metadata so the client can render an 'Open post' button. The draft's vaultSlug seeds --vault-slug when not given explicitly.")
|
|
322
|
+
.option("--attach <file>", "Local media file to attach. Repeatable. X-style mix rule: up to 4 photos OR 1 GIF OR 1 video. Size ceilings: 5MB photos / 15MB GIFs / 512MB video.", (value, prev = []) => [...prev, value], [])
|
|
322
323
|
.action(async (opts) => {
|
|
323
324
|
if (opts.draftId) {
|
|
324
325
|
if (opts.title || opts.content || opts.richText) {
|
|
@@ -365,6 +366,10 @@ export function registerSpaceCommand(program) {
|
|
|
365
366
|
}
|
|
366
367
|
if (authorVaultSlug)
|
|
367
368
|
body.authorVaultSlug = authorVaultSlug;
|
|
369
|
+
if (opts.attach && opts.attach.length > 0) {
|
|
370
|
+
assertPostAttachmentMix(opts.attach);
|
|
371
|
+
body.attachments = await uploadPostAttachments(opts.attach);
|
|
372
|
+
}
|
|
368
373
|
const spaceSlug = resolveSpaceSlug(space, opts);
|
|
369
374
|
const resp = (await apiPost(`/spaces/${spaceSlug}/posts`, body));
|
|
370
375
|
const post = unwrapResp(resp);
|
|
@@ -473,6 +478,7 @@ export function registerSpaceCommand(program) {
|
|
|
473
478
|
.option("--auto-attachments", "Upload wiki-linked [[files]] to webdrive before posting (also attributes the reply to that vault)")
|
|
474
479
|
.option("--vault-slug <vaultSlug>", "Attribute the reply to this vault (sets authorVaultSlug). Also used as upload destination for --auto-attachments.")
|
|
475
480
|
.option("--space-slug <spaceSlug>", "Space slug (overrides .gobi/settings.yaml)")
|
|
481
|
+
.option("--attach <file>", "Local media file to attach to this reply. Repeatable. X-style mix rule: up to 4 photos OR 1 GIF OR 1 video. Size ceilings: 5MB photos / 15MB GIFs / 512MB video.", (value, prev = []) => [...prev, value], [])
|
|
476
482
|
.action(async (postId, opts) => {
|
|
477
483
|
if (!opts.content && !opts.richText) {
|
|
478
484
|
throw new Error("Provide either --content or --rich-text.");
|
|
@@ -506,6 +512,10 @@ export function registerSpaceCommand(program) {
|
|
|
506
512
|
}
|
|
507
513
|
if (authorVaultSlug)
|
|
508
514
|
body.authorVaultSlug = authorVaultSlug;
|
|
515
|
+
if (opts.attach && opts.attach.length > 0) {
|
|
516
|
+
assertPostAttachmentMix(opts.attach);
|
|
517
|
+
body.attachments = await uploadPostAttachments(opts.attach);
|
|
518
|
+
}
|
|
509
519
|
const spaceSlug = resolveSpaceSlug(space, opts);
|
|
510
520
|
const resp = (await apiPost(`/spaces/${spaceSlug}/posts/${postId}/replies`, body));
|
|
511
521
|
const msg = unwrapResp(resp);
|
package/package.json
CHANGED
|
@@ -40,18 +40,25 @@ Replace `<RATIO>` with the desired aspect ratio: `1:1`, `16:9`, `9:16`, `4:3`, o
|
|
|
40
40
|
|
|
41
41
|
The `-o` flag implies `--wait` and downloads the image when done.
|
|
42
42
|
|
|
43
|
-
**
|
|
43
|
+
**Where you reference the downloaded file depends on what you're doing with it:**
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
- **Chat / vault note (vault is mounted, ![[wikilinks]] resolve):** use Obsidian wiki-link syntax:
|
|
46
|
+
```
|
|
47
|
+
![[media/<NAME>.png]]
|
|
48
|
+
```
|
|
49
|
+
- **Post or reply (any flow that goes through `gobi <scope> create-post` or `gobi <scope> create-reply`):** do NOT embed the image in `--content`. Pass the file as a first-class attachment:
|
|
50
|
+
```bash
|
|
51
|
+
gobi space create-post --title "<TITLE>" --content "<BODY>" --attach media/<NAME>.png
|
|
52
|
+
gobi space create-reply <postId> --content "<BODY>" --attach media/<NAME>.png
|
|
53
|
+
```
|
|
54
|
+
This uploads the file to the CDN and renders it as a slider on the post card. The `--attach` flag is repeatable; mix rule is **4 photos OR 1 GIF OR 1 video**.
|
|
48
55
|
|
|
49
|
-
|
|
56
|
+
In particular, when you're answering a post-mention (`@gobi` / `@space:<slug>` on a thread) and need to send media, **call `gobi <scope> create-reply <postId> --attach <file>` yourself** — your text-only assistant body is auto-posted only if you don't call create-reply this turn, so calling it explicitly is the only way to land media on the thread.
|
|
50
57
|
|
|
51
58
|
### Key rules
|
|
52
59
|
- Replace `<NAME>` with a descriptive slug — NEVER use example names like `sunset.png` literally.
|
|
53
60
|
- `--name` is **optional** — auto-derived from prompt if omitted.
|
|
54
|
-
- Do NOT use the `downloadUrl` from the response — it is a
|
|
61
|
+
- Do NOT use the `downloadUrl` from the response — it is a Miraflow-internal path, not a public link. Always download with `-o` then either wiki-link (chat/vault) or `--attach` (post/reply).
|
|
55
62
|
- `download-image` takes a **positional** jobId (NOT `--job-id`): `gobi media download-image <jobId>`
|
|
56
63
|
- The `jobId` (or `id`) field is what you pass to `download-image` / `get-image-status` — NOT `mediaId`.
|
|
57
64
|
|
|
@@ -133,7 +140,7 @@ gobi --json media get-avatar-job-status <jobId> --wait
|
|
|
133
140
|
![[media/<NAME>.mp4]]
|
|
134
141
|
```
|
|
135
142
|
|
|
136
|
-
Do NOT use markdown image/link syntax `` or `gobi://` URLs.
|
|
143
|
+
Do NOT use markdown image/link syntax `` or `gobi://` URLs in chat. For posts/replies use `--attach media/<NAME>.mp4` instead — see the image workflow above for details.
|
|
137
144
|
|
|
138
145
|
## Available Commands
|
|
139
146
|
|
|
@@ -51,6 +51,14 @@ Both `gobi space create-post` / `edit-post` and `gobi global create-post` / `edi
|
|
|
51
51
|
|
|
52
52
|
> **Before using `--auto-attachments`, check that the target vault is published.** Run `gobi --json vault status` (or `gobi vault status --vault-slug <slug>`) and verify `isPublished: true`. Files uploaded to a non-public vault are stored on webdrive but are not reachable at `gobispace.com/@{vaultSlug}` — readers will see broken `[[wikilinks]]`. If the status reports unpublished, ask the user to run `gobi vault publish` first (it requires `title` and `description` in `PUBLISH.md`). See the **gobi-vault** skill.
|
|
53
53
|
|
|
54
|
+
## Post media attachments (`--attach`)
|
|
55
|
+
|
|
56
|
+
Separate from `--auto-attachments`, `gobi space create-post` and `gobi global create-post` accept `--attach <file>` (repeatable) for inline post media — the photos/GIF/video that render in-feed alongside the post body. The CLI uploads each file to S3 via `POST /posts/upload-url` and passes the resulting `{ mediaUrl, mediaKey }` array as the post's `attachments`.
|
|
57
|
+
|
|
58
|
+
X-style mix rule (enforced client-side before upload): up to **4 photos** OR **1 GIF** OR **1 video** — they don't combine. Server-side ceilings: 5MB photos, 15MB GIFs, 512MB video.
|
|
59
|
+
|
|
60
|
+
Use `--attach` for media you want shown in the post itself; use `--auto-attachments` for `[[wikilinks]]` to vault files referenced in the body.
|
|
61
|
+
|
|
54
62
|
## Public link formats
|
|
55
63
|
|
|
56
64
|
Once a post is created, you can build a shareable URL from the response:
|
|
@@ -79,6 +79,7 @@ Options:
|
|
|
79
79
|
--auto-attachments Upload wiki-linked [[files]] to webdrive before posting (also sets authorVaultSlug to that vault)
|
|
80
80
|
--draft-id <draftId> Use this draft as the source of title and content (mutually exclusive with --title/--content/--rich-text). On success, links the post back by recording postId on
|
|
81
81
|
draft.metadata so the client can render an 'Open post' button. The draft's vaultSlug seeds --vault-slug when not given explicitly.
|
|
82
|
+
--attach <file> Local media file to attach. Repeatable. X-style mix rule: up to 4 photos OR 1 GIF OR 1 video. Size ceilings: 5MB photos / 15MB GIFs / 512MB video. (default: [])
|
|
82
83
|
-h, --help display help for command
|
|
83
84
|
```
|
|
84
85
|
|
|
@@ -121,6 +122,8 @@ Options:
|
|
|
121
122
|
--rich-text <richText> Rich-text JSON array (mutually exclusive with --content)
|
|
122
123
|
--vault-slug <vaultSlug> Attribute the reply to this vault (sets authorVaultSlug). Also used as upload destination for --auto-attachments.
|
|
123
124
|
--auto-attachments Upload wiki-linked [[files]] to webdrive before posting (also attributes the reply to that vault)
|
|
125
|
+
--attach <file> Local media file to attach to this reply. Repeatable. X-style mix rule: up to 4 photos OR 1 GIF OR 1 video. Size ceilings: 5MB photos / 15MB GIFs / 512MB video. (default:
|
|
126
|
+
[])
|
|
124
127
|
-h, --help display help for command
|
|
125
128
|
```
|
|
126
129
|
|
|
@@ -125,6 +125,7 @@ Options:
|
|
|
125
125
|
--space-slug <spaceSlug> Space slug (overrides .gobi/settings.yaml)
|
|
126
126
|
--draft-id <draftId> Use this draft as the source of title and content (mutually exclusive with --title/--content/--rich-text). On success, links the post back by recording postId/spaceSlug on
|
|
127
127
|
draft.metadata so the client can render an 'Open post' button. The draft's vaultSlug seeds --vault-slug when not given explicitly.
|
|
128
|
+
--attach <file> Local media file to attach. Repeatable. X-style mix rule: up to 4 photos OR 1 GIF OR 1 video. Size ceilings: 5MB photos / 15MB GIFs / 512MB video. (default: [])
|
|
128
129
|
-h, --help display help for command
|
|
129
130
|
```
|
|
130
131
|
|
|
@@ -170,6 +171,8 @@ Options:
|
|
|
170
171
|
--auto-attachments Upload wiki-linked [[files]] to webdrive before posting (also attributes the reply to that vault)
|
|
171
172
|
--vault-slug <vaultSlug> Attribute the reply to this vault (sets authorVaultSlug). Also used as upload destination for --auto-attachments.
|
|
172
173
|
--space-slug <spaceSlug> Space slug (overrides .gobi/settings.yaml)
|
|
174
|
+
--attach <file> Local media file to attach to this reply. Repeatable. X-style mix rule: up to 4 photos OR 1 GIF OR 1 video. Size ceilings: 5MB photos / 15MB GIFs / 512MB video. (default:
|
|
175
|
+
[])
|
|
173
176
|
-h, --help display help for command
|
|
174
177
|
```
|
|
175
178
|
|