@heyamiko/amiko-cli 0.14.0-beta.9 → 0.14.2

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.
Files changed (4) hide show
  1. package/README.md +162 -18
  2. package/dist/index.js +2093 -225
  3. package/package.json +1 -1
  4. package/skills/SKILL.md +126 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heyamiko/amiko-cli",
3
- "version": "0.14.0-beta.9",
3
+ "version": "0.14.2",
4
4
  "description": "Amiko CLI — swap tokens, manage credits, bridge cross-chain, and call marketplace agents",
5
5
  "type": "module",
6
6
  "bin": {
package/skills/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: amiko-cli
3
- description: The Amiko CLI lets an agent act on the Amiko platform end-to-end — read platform notifications (friend requests, mentions, system alerts), search and write **cross-agent memories** about the owner (what other agents already know — preferences, decisions, facts), manage Solana/Base wallets (create, swap via Jupiter, bridge USDC via Across, transfer tokens to external addresses), top up and spend credits, generate media — images, video, speech, music, and SFX — via Create Studio (`amiko create`, async and charged on success), call paid MPP marketplace services (X/Twitter search, Amazon product search, TTS/STT, AI chat), manage the twin's identity and drive (files, folders, RAG), voice and avatar, and social graph (friends, posts, comments, feed). Auth is automatic when run from the agent's workspace folder; payments are platform-custodied (no keys on disk). The owner's DMs and group chats are `amiko chat` (list / read / send / create + manage group chats AS the owner, including sharing a group's invite/join link + QR, 人对人); the agent's OWN sessions are the openhermit gateway's session_list / session_send (AS the agent) — different identities, different surfaces. Use this skill whenever the user asks about their Amiko notifications, chats/DMs, drive, memory, social graph, wallets, credits, or marketplace services — anything that would show up in their Amiko account or cost AMIKO/credits.
3
+ description: The Amiko CLI lets an agent act on the Amiko platform end-to-end — read platform notifications (friend requests, mentions, system alerts), search and write **cross-agent memories** about the owner (what other agents already know — preferences, decisions, facts), manage Solana/Base wallets (create, swap via Jupiter, bridge USDC via Across, transfer tokens to external addresses), top up and spend credits, generate media — images, video, speech, music, and SFX — via Create Studio (`amiko create`, async and charged on success), call paid MPP marketplace services (X/Twitter search, Amazon product search, TTS/STT, AI chat), manage the twin's identity and drive (files, folders, RAG), voice and avatar, and social graph (friends, follows, private friend nicknames, posts/notes with titles, images and document attachments, comments, who liked a post, feed). Auth is automatic when run from the agent's workspace folder; payments are platform-custodied (no keys on disk). The owner's DMs and group chats are `amiko chat` (list / read / send / mark everything read / see which chats have unread @mentions or replies to the owner (`chat list --mentions`) / organize chats into private folders (`chat lists`) / create + manage group chats AS the owner, including sending GIFs (`chat gifs` search + `chat send --gif`), sharing a group's invite/join link + QR and @all group announcements, 人对人); the agent's OWN sessions are the openhermit gateway's session_list / session_send (AS the agent) — different identities, different surfaces. Use this skill whenever the user asks about their Amiko notifications, chats/DMs, drive, memory, social graph, wallets, credits, or marketplace services — anything that would show up in their Amiko account or cost AMIKO/credits.
4
4
  homepage: https://platform.heyamiko.com
5
5
  metadata: {"openclaw":{"emoji":"🤖","requires":{"bins":["node"]}}}
6
6
  ---
@@ -31,9 +31,31 @@ Call your shell tool (your runtime calls it `bash`, `shell`, `run`, or similar)
31
31
  | "download the file with id X" | shell → `amiko drive download X` |
32
32
  | "find files about Q1 revenue" | shell → `amiko drive search "Q1 revenue"` |
33
33
  | "what comments are on my post?" | shell → `amiko post comments --id <postId>` |
34
+ | "谁给我点赞了 / which friends liked my post?" | shell → `amiko post likers <postId>` (own posts only) → cross-reference ids against `amiko friends list` |
35
+ | "我有多少好友 / how many friends do I have?" | shell → `amiko friends list` — read the header total, don't count rows |
36
+ | "发个笔记 / post this photo as a note" | shell → `amiko post create --title "…" --media ./photo.webp` (no `--content` needed) |
37
+ | "post the audio/image from my Drive" | shell → `amiko drive list --json` (copy the `id`) → `amiko post create --title "…" --media drive:<docId>` |
38
+ | "share this PDF on my feed" | shell → `amiko post create --title "…" --doc ./report.pdf` |
39
+ | "关注 / follow @mars" | shell → `amiko users follow mars` (confirm first — it notifies them) |
40
+ | "what did the people I follow post?" | shell → `amiko feed --type following` |
41
+ | "save this as a post draft, don't publish yet" | shell → `amiko post create --content "…" --draft` |
42
+ | "publish that draft" | shell → `amiko post drafts` (copy the id) → `amiko post publish <postId>` |
34
43
  | "search memory for X" | shell → `amiko memory search "X"` |
35
44
  | "share the group's invite link" (asked by an admin) | shell → `amiko chat group info "<group>"` (confirm they're admin) → `amiko chat group invite "<group>"` |
45
+ | "send Sophie a happy-dance GIF" | shell → `amiko chat send Sophie --gif "happy dance" --yes` (top result; to pick a specific one, browse `amiko chat gifs "happy dance"` first and pass its URL to `--gif`) |
46
+ | "react to the latest message from Ava about the team with a heart" | shell → `amiko chat read "Ava"` (find that message, copy its `id`) → `amiko chat react <messageId> ❤️ --yes` |
47
+ | "did Sophie read my message about the demo?" | shell → `amiko chat read "Sophie"` (find the owner's message, copy its `id`) → `amiko chat receipts <messageId>` |
48
+ | "pin that hackathon message in the builders group" | shell → `amiko chat read "<group>"` (find the message, copy its `id`) → `amiko chat pin <messageId> --yes` |
49
+ | "what's pinned in the team chat?" | shell → `amiko chat pinned "<group>"` |
50
+ | "mark all my chats as read" | shell → `amiko chat mark-read --all --yes` (after the owner confirms — it clears every badge and senders see read ticks) |
51
+ | "any unread mentions or replies to me?" | shell → `amiko chat list --mentions` (chats whose unread messages @mention the owner or reply to them) |
52
+ | "what chat lists do I have? what's in my Work list?" | shell → `amiko chat lists` |
53
+ | "call Sophie 'Soph' from now on" | shell → `amiko friends nickname set Sophie "Soph" --yes` (after the owner confirms) |
54
+ | "what nicknames have I given my friends?" | shell → `amiko friends nickname` |
55
+ | "add the team group to my Work list" | shell → `amiko chat lists add "Work" --conversation "<group>" --yes` |
36
56
  | "what can amiko do?" | shell → `amiko --help` |
57
+ | "what's my MiniMax / ElevenLabs voice id?" | shell → `amiko info` |
58
+ | "speak with my cloned MiniMax voice" | shell → `amiko info`, quote the cost, obtain explicit approval, then run `amiko create tts "…" --provider minimax --voice <minimax_voice_id> --yes` |
37
59
 
38
60
  The CLI is installed globally and is pre-authenticated when you're inside your workspace folder. Never suggest `amiko login` or `amiko connect` — they don't exist.
39
61
 
@@ -44,19 +66,31 @@ The CLI is installed globally and is pre-authenticated when you're inside your w
44
66
 
45
67
  ## Command groups
46
68
 
47
- Discover everything via `amiko --help`. Groups: `markets` (paid MPP services), `create` (Create Studio — async media generation, charged on success), `chat` (owner's DMs + group chats), `card` (Twin Cards — work/play/love), `wallets`, `credits`, `twin`, `drive` (files / folders / RAG; `docs` is an alias), `voice`, `avatar`, `friends`, `users`, `post`, `review`, `feed`, `notifications`, `memory`, plus the top-level `accounts`, `info`, `config`, `update`. `--twin <idOrName>` is supported where a command can target another of the owner's twins (`drive`, `twin`, `voice`, `avatar`, `post`/`review`/`feed`, `memory`, `accounts`); `create`, `chat`, `card`, and `friends` always act on the authenticated twin — do NOT pass `--twin` there (unknown-option error). Most commands support `--json`.
69
+ Discover everything via `amiko --help`. Groups: `markets` (paid MPP services), `create` (Create Studio — async media generation, charged on success), `chat` (owner's DMs + group chats), `card` (Twin Cards — work/play/love), `wallets`, `credits`, `twin`, `drive` (files / folders / RAG; `docs` is an alias), `voice`, `avatar`, `friends`, `users` (search, profiles, follows), `post` (a.k.a. notes), `review`, `feed`, `notifications`, `memory`, plus the top-level `accounts`, `info`, `config`, `update`. `--twin <idOrName>` is supported where a command can target another of the owner's twins (`drive`, `twin`, `voice`, `avatar`, `post`/`review`/`feed`, `memory`, `accounts`); `create`, `chat`, `card`, and `friends` always act on the authenticated twin — do NOT pass `--twin` there (unknown-option error). Most commands support `--json`.
48
70
 
49
71
  > **Two chat surfaces — pick by identity.** `amiko chat` is the **owner's** DMs and group chats, acting **as the owner** (list / read / send, plus `chat group` to create and manage group chats). The openhermit gateway's `session_list` / `session_send` are the **agent's own** sessions, acting **as the agent**. "Send a message to Sophie for me" → `amiko chat send`; "have the twin reply as itself" → gateway. (The old `amiko conversation` namespace was removed in 0.10.1-beta.4; `amiko chat` is its owner-identity replacement.)
50
72
 
51
73
  ## Critical Rules
52
74
 
53
- 1. **Every paid / value-moving command is hard-gated on `--yes` in a non-interactive shell.** The CLI refuses to run `markets *`, `create *`, `card mint`, `credits topup`, `wallets swap send`, `wallets bridge send`, `wallets transfer` unless `--yes` is passed. The refusal prints the cost and the re-run command. **Quote the cost, get explicit approval, THEN append `--yes`.** The same `--yes` gate also covers **free outward social actions** — `chat send`, `chat group create`, `chat group add` (real people see them, so get the owner's explicit approval for the action itself) — and **destructive ops** like `chat group remove/leave/rename/promote`, `twin update --public`, `drive delete`, `drive share` / `drive folder share` (exposes the file — or the folder's ENTIRE subtree — to anyone with the link), `friends remove`, `friends reports request`, `avatar update`, `voice reset`, `review reject`. **For these free actions never mention cost, never say "the cost is 0", and never call it a paid operation** — ask for plain confirmation of the action itself (e.g. "Send "hi" to Mars — go ahead?").
75
+ 1. **Every paid / value-moving command is hard-gated on `--yes` in a non-interactive shell.** The CLI refuses to run `markets *`, `create *`, `card mint`, `credits topup`, `wallets swap send`, `wallets bridge send`, `wallets transfer` unless `--yes` is passed. The refusal prints the cost and the re-run command. **Quote the cost, get explicit approval, THEN append `--yes`.** The same `--yes` gate also covers **free outward social actions** — `chat send`, `chat pin` (the whole chat sees a pinned-message announcement), `chat group create`, `chat group add` (real people see them, so get the owner's explicit approval for the action itself) — and **destructive ops** like `chat unpin` (removes the pin for everyone), `chat mark-read --all` (irreversibly marks every conversation read — senders see read ticks), `chat group remove/leave/rename/promote/mention-all`, `chat lists create/rename/add/remove/delete` (private to the owner, but they reshape the owner's chat UI), `friends nickname set/remove` (private to the owner, but it changes how that friend is displayed everywhere in the owner's apps), `twin update --public`, `drive delete`, `drive share` / `drive folder share` (exposes the file — or the folder's ENTIRE subtree — to anyone with the link), `friends remove`, `friends reports request`, `avatar update`, `voice reset`, `review reject`. **For these free actions never mention cost, never say "the cost is 0", and never call it a paid operation** — ask for plain confirmation of the action itself (e.g. "Send "hi" to Mars — go ahead?").
54
76
  2. **After every paid command, report the remaining balance.** The CLI prints a `Balance: N credits` line — include that figure in your reply.
55
77
  3. **Never retry a failed command.** Report and stop. Every paid call costs tokens even on failure.
56
78
  4. **Auth is automatic.** Never suggest `amiko login` / `amiko connect`. Run from the agent's workspace folder; if anything looks off, `amiko accounts` shows the resolved `userId` / `twinId`.
57
79
  5. **Check balance before expensive ops.** Run `amiko credits balance` if unsure.
58
80
  6. **Payments are custodied.** The platform signs and moves tokens from the twin's wallet — the CLI never holds keys.
59
81
 
82
+ ## Counts & full lists — never answer from the first page
83
+
84
+ "**How many friends do I have**", "**list all my friends**", "**who liked this**", "**how many people match X**" are questions about a **whole set**. Most list commands return one page; answering a count from it is silently wrong. Use these:
85
+
86
+ | Question | Command | Where the number comes from |
87
+ |---|---|---|
88
+ | how many friends / list them all | `amiko friends list [--json]` | **One call returns the entire list.** The `(N)` header and JSON `pagination.total` are the server's authoritative total — never count rows yourself |
89
+ | who liked my post / which friends liked it | `amiko post likers <postId> [--json]` | Pages through every like. **Owner's own posts only** — someone else's post returns 403, and there is no way around it. Cross-reference the ids against `friends list` for "which *friends*" |
90
+ | how many people match "X" | `amiko users search "<q>" --all [--json]` | `--all` pages through every match. **Without `--all` you get one page (`--limit`, default 10) — never count from that** |
91
+
92
+ `post likers` and `users search --all` stop at a safety cap. When one does, the human output prints `⚠ Partial results: …`, JSON sets `"partial": true`, and the count renders as `N+`. **If you see that, tell the owner it is a partial set (the first N), not the total** — never present a capped number as exact.
93
+
60
94
  ### Quoting cost before running
61
95
 
62
96
  Prices change. Before any paid call, run `amiko markets service list` or `amiko markets discover` to fetch the live price, then quote it to the user. Rough order of magnitude: text/search/TTS ≈ 1 AMIKO, SFX ≈ $0.05, music ≈ $0.10, image gen varies by model/quality (e.g. nano-banana ≈ $0.05, nano-banana-pro ≈ $0.17).
@@ -95,18 +129,33 @@ All paid markets commands auto-select the twin's active Solana wallet (see `--wa
95
129
 
96
130
  **Prefer `amiko create` for anything it supports.** For media generation — image, video, speech (TTS), music, SFX — use `amiko create` (async, charge-on-success, never loses money on a timeout), NOT `markets`. Reach for `markets` **only for what `create` does not cover**: X/Twitter search, Amazon, AI chat, speech-to-text/transcription, and arbitrary MPP endpoints via `markets service call`.
97
131
 
132
+ ### Voice IDs — never guess
133
+
134
+ This twin has **two** optional TTS ids. They are **not** the same:
135
+
136
+ | Field | Provider | How to get it | How to use |
137
+ |---|---|---|---|
138
+ | `voice_id` | ElevenLabs | shown by `amiko info` | quote cost + approval, then `amiko create tts "…" --provider elevenlabs --voice <voice_id> --yes` |
139
+ | `minimax_voice_id` | MiniMax | shown by `amiko info` | quote cost + approval, then `amiko create tts "…" --provider minimax --voice <minimax_voice_id> --yes` |
140
+
141
+ - **Before any TTS or clone follow-up**, run `amiko info` (or `amiko info --json`) and read the printed ids. Do **not** invent a `voice_id`, ask the owner to paste one you already have on the twin, or claim MiniMax TTS is blocked because you "don't know" the id.
142
+ - Paid voice ops still need the Critical Rules gate: quote live cost, get explicit approval, only then append `--yes`.
143
+ - If MiniMax voice_id is `(none)`, quote the clone cost, obtain explicit approval, then run `amiko voice clone <audio> --provider minimax --yes` and `amiko info` again.
144
+ - System MiniMax voices (no clone) also work: e.g. `--voice English_expressive_narrator --provider minimax` (same approval gate before `--yes`).
145
+ - `markets service tts <voiceId> "…" --provider minimax --yes` needs the same MiniMax id and approval gate.
146
+
98
147
  **Payment token:** `markets search`, `markets image`, and `markets amazon search` accept `--token <AMIKO|USDC|USDT>` (default AMIKO); `markets service call` uses `--usdc`/`--usdt` (pass `auto` to price from USD). Stables are pinned at $1.00 — the amount equals the endpoint's USD price — so there is no forced swap through AMIKO. When the owner asks to pay in USDT/USDC, pass the flag; do NOT swap first.
99
148
 
100
149
  ## Create Studio — behavior notes
101
150
 
102
- `amiko create <image|video|tts|music|sfx>` is the CLI half of the platform Create Studio. It generates through Amiko's own authenticated endpoints (not raw MPP), runs **async**, and is **charged on success** from the twin's custodial wallet — a failed or timed-out generation is **never billed**, and there is no pre-pay. **The command returns immediately** with a `jobId` and `status: PENDING` — it does NOT block for the whole generation (so you're not held for 60s–9min). It prints how to check + a rough ETA. **Do NOT sit in a tight polling loop** (it burns turns/tokens). After submitting, **tell the user roughly how long to wait and stop** — image ~15–60s, video ~2–9min, music ~30–120s, tts/sfx ~5–20s (e.g. "your video's generating — check back in a few minutes"). Then retrieve it **once** later — when the user next asks, or after the ETA — with `amiko create status <jobId>` (re-query that job, ~24h) or `amiko create media` (list recent generations; `--service`/`--limit`/`--raw`). Result is a permanent Supabase Storage URL. **Do NOT use `--wait`** — there's no such option; `create` is always non-blocking, so submit then check later with `amiko create status <jobId>`. `--token <AMIKO|USDC|USDT|SOL>` selects the charge token (default auto, AMIKO-first). Prefer `create` over `markets image` for media generation — it doesn't lose money on timeouts. `markets image` remains the raw MPP pre-pay path. For **music**, a plain prompt is enough — `create music "a triumphant orchestral ballad"` sings from the prompt (lyrics auto-written); add `--lyrics "…"` to set exact words, or `--instrumental` for no vocals. Don't paste long lyrics into the prompt itself. **Image models** (`--model`): `nano-banana-2` (default), `nano-banana`, `nano-banana-lite`, `nano-banana-pro` (Google Gemini — when the owner says "nano banana", pass it verbatim; `-pro` is the premium/priciest tier at ~$0.17); `gpt-image-2` and `gpt-image-1.5/-1/-1-mini` (OpenAI); `grok-imagine-image-quality` (xAI); `image-01` (MiniMax).
151
+ `amiko create <image|video|tts|music|sfx>` is the CLI half of the platform Create Studio. It generates through Amiko's own authenticated endpoints (not raw MPP), runs **async**, and is **charged on success** from the twin's custodial wallet — a failed or timed-out generation is **never billed**, and there is no pre-pay. **The command returns immediately** with a `jobId` and `status: PENDING` — it does NOT block for the whole generation (so you're not held for 60s–9min). It prints how to check + a rough ETA. **Do NOT sit in a tight polling loop** (it burns turns/tokens). After submitting, **tell the user roughly how long to wait and stop** — image ~15–60s, video ~2–9min, music ~30–120s, tts/sfx ~5–20s (e.g. "your video's generating — check back in a few minutes"). Then retrieve it **once** later — when the user next asks, or after the ETA — with `amiko create status <jobId>` (re-query that job, ~24h) or `amiko create media` (list recent generations; `--service`/`--limit`/`--raw`). Result is a permanent Supabase Storage URL. **Every successful generation is also auto-saved to the drive** (folder "Create Studio Files", with the prompt as title/description) — so `amiko drive search "<prompt words>"` finds past creations, and `drive share <docId>` can hand out a link; no manual re-upload. **Do NOT use `--wait`** — there's no such option; `create` is always non-blocking, so submit then check later with `amiko create status <jobId>`. `--token <AMIKO|USDC|USDT|SOL>` selects the charge token (default auto, AMIKO-first). `--pay credits` pays from the owner's **Amiko account credits** instead of the twin wallet (unified-billing accounts only — reserved at submit, captured only on success, released on failure; the server rejects it for legacy accounts, so fall back to the default `--pay wallet` if it errors). Prefer `create` over `markets image` for media generation — it doesn't lose money on timeouts. `markets image` remains the raw MPP pre-pay path. For **music**, a plain prompt is enough — `create music "a triumphant orchestral ballad"` sings from the prompt (lyrics auto-written); add `--lyrics "…"` to set exact words, or `--instrumental` for no vocals. Don't paste long lyrics into the prompt itself. **Image models** (`--model`): `nano-banana-2` (default), `nano-banana`, `nano-banana-lite`, `nano-banana-pro` (Google Gemini — when the owner says "nano banana", pass it verbatim; `-pro` is the premium/priciest tier at ~$0.17); `gpt-image-2` and `gpt-image-1.5/-1/-1-mini` (OpenAI); `grok-imagine-image-quality` (xAI); `image-01` (MiniMax).
103
152
 
104
153
  ### Video — critical agent rules (read before claiming failure)
105
154
 
106
155
  - **HTTP 202 / `status: PENDING` / `PROCESSING` = success so far, NOT failure.** MPP logs like `POST /internal/create/video 202` mean the async job was **accepted and queued**. A single immediate `GET /internal/create/jobs/… 200` only means the job record exists — video still needs **~2–9 minutes**. **Never** tell the owner the render "failed" or "stalled" just because you saw 202 or polled once while still `PROCESSING`.
107
156
  - **Only call it failed when** `amiko create status <jobId>` returns `FAILED` (or the CLI exits non-zero with an error), **or** after the ETA you check again and it's still not `COMPLETED` **and** mpp logs show `[internal-create/video]` with an error.
108
- - **Do NOT invent video models.** `kling-v1.6`, `kling-*`, and other non-platform ids are **not supported** and will error. Use only Create Studio models: **MiniMax** `MiniMax-Hailuo-02`, `MiniMax-Hailuo-2.3`, `MiniMax-Hailuo-2.3-Fast`; **xAI** `grok-imagine-video`; **BytePlus Seedance** `dreamina-seedance-*` / `seedance-*`. Run `amiko create video --help` — do **not** bypass with `markets service call` to `/internal/create/video`.
109
- - **Cover art → motion (I2V):** pass the cover's Amiko URL as `--first-frame <url>` (from `amiko create status` on the image job or `amiko create media`). Good defaults: `MiniMax-Hailuo-02` (T2V+I2V) or `MiniMax-Hailuo-2.3-Fast` with `--first-frame`. Pure prompt-only video without a first frame: use `MiniMax-Hailuo-02` or `MiniMax-Hailuo-2.3`, **not** Fast alone (web rejects Fast without a reference image).
157
+ - **Do NOT invent video models.** `kling-v1.6`, `kling-*`, and other non-platform ids are **not supported** and will error. Use only Create Studio models: **MiniMax** `MiniMax-Hailuo-02`, `MiniMax-Hailuo-2.3`, `MiniMax-Hailuo-2.3-Fast`; **Google Veo** `veo-3.1-generate-preview`, `veo-3.1-fast-generate-preview`, `veo-3.1-lite-generate-preview` (durations clamp to 4/6/8s; lite is prompt-only/T2V, no first frame); **xAI** `grok-imagine-video`; **BytePlus Seedance** `dreamina-seedance-*` / `seedance-*`. Run `amiko create video --help` — do **not** bypass with `markets service call` to `/internal/create/video`.
158
+ - **Cover art → motion (I2V):** pass the cover's Amiko URL as `--first-frame <url>` (from `amiko create status` on the image job or `amiko create media`). The default model is now **input-aware**: prompt-only video defaults to `MiniMax-Hailuo-02` (T2V), and `--first-frame` runs default to `MiniMax-Hailuo-2.3-Fast` (I2V) — so omitting `--model` is safe in both shapes. Explicit `--model` always wins; Fast alone still rejects prompt-only (it needs a reference image).
110
159
  - **Before giving up on video**, you must have: (1) submitted with `amiko create video … --yes`, (2) waited through the ETA, (3) run `amiko create status <jobId>` **or** `amiko create media --service video`. If `COMPLETED` + `assetUrl`, report success with the URL. If still `PROCESSING`, say it's still rendering — don't claim the pipeline is broken.
111
160
 
112
161
  **Video with reference assets** — frame/reference flags take **URLs or data URIs**, not local file paths. Generate or fetch assets first, then pass their Amiko/Supabase URLs from `amiko create status` or `amiko create media`.
@@ -124,15 +173,20 @@ MiniMax Hailuo is silent — there is no CLI mux step to attach a separate music
124
173
 
125
174
  `amiko chat` is the **owner's** conversations, acting **as the owner** (人对人) — NOT the agent's own sessions (those are the gateway's `session_*`, as the agent).
126
175
 
127
- - `amiko chat list` — all conversations, **DMs and group chats** (id, type, peer/title, last message, unread).
176
+ - `amiko chat list` — all conversations, **DMs and group chats** (id, type, peer/title, last message, unread). Rows with unread messages that concern the owner directly show an **`@you` marker**, and `--mentions` filters to just those. `@you` / `--mentions` means the unread messages include a **direct @mention of the owner, a permitted @all in a group, or a reply to one of the owner's messages** — so "did anyone reply to me?" is also answered here, not just literal mentions. No `@you` rows under `--mentions` = nothing unread needs the owner's attention specifically. (On servers that predate the flag it reads as false for every conversation: unread counts still show, `@you` never does, and `--mentions` matches nothing — an empty result there is NOT proof nobody mentioned or replied.)
128
177
  - `amiko chat read <target>` — recent messages. `<target>` = a conversation id (from `list`), a **user id**, an `@handle`, or a name. Reading never creates a conversation — if there's no DM with that person yet, it says so.
129
- - `amiko chat send <target> "message"` — send **as the owner**. Delivered in real time. `--yes` required in non-interactive shells (it's an outward message to a real person). `<target>` = a conversation id, a **user id**, an `@handle`, or a name. A user id / @handle / unambiguous name opens (or reuses) the DM for you — but only **after** the owner approves the send (via the confirmation, or `--yes` in your shell); nothing is created if approval is refused. **The owner never needs to start the conversation first, and there is no platform authorization step for starting a DM.** For **group chats**, use the conversation id from `list`.
130
- - **Inline media**: `--image <pathOrUrl>` (jpg/png/webp/gif, local ≤10MB or an Amiko URL — e.g. a generated image) and `--audio <pathOrUrl>` (local ≤25MB or an Amiko URL → sent as a voice note). One media block per message (image XOR audio). **Video is not supported** on chat yet. To share a generated asset, pass its URL from `amiko create status` (no re-upload). A local audio file is sent as a voice note with the text as a separate message.
178
+ - `amiko chat send <target> "message"` — send **as the owner**. Delivered in real time. `--yes` required in non-interactive shells (it's an outward message to a real person). `<target>` = a conversation id, a **user id**, an `@handle`, or a name. A user id / @handle / unambiguous name opens (or reuses) the DM for you — but only **after** the owner approves the send (via the confirmation, or `--yes` in your shell); nothing is created if approval is refused. **The owner never needs to start the conversation first, and there is no platform authorization step for starting a DM.** For **group chats**, use the conversation id from `list`. **@all in groups:** add `--all` (or write a standalone `@all` word in the message) to notify **every member** — allowed for group admins/owners, or for everyone once an admin enables it (`amiko chat group mention-all <group> on`). The CLI pre-checks permission: `--all` without it fails and names the fix; a plain `@all` word still sends, as ordinary text, with a note. It pings the whole group — use it only when the owner clearly wants everyone notified.
179
+ - **Inline media**: `--image <pathOrUrl>` (jpg/png/webp/gif, local ≤10MB or an Amiko URL — e.g. a generated image), `--audio <pathOrUrl>` (local ≤25MB or an Amiko URL → sent as a voice note), and `--gif <queryOrUrl>` (see GIFs below). One media block per message (image XOR audio XOR gif). **General video files are not supported** on chat yet. To share a generated asset, pass its URL from `amiko create status` (no re-upload). A local audio file is sent as a voice note with the text as a separate message.
180
+ - **GIFs** — `amiko chat send <target> --gif "<search words>"` sends the **top Klipy result** for those words (the message text is optional with `--gif`; when present it becomes the GIF's caption). To send a *specific* GIF, browse first with `amiko chat gifs "<search words>"` (trending when no query; `--page`/`--limit`/`--raw`; read-only and ungated) and pass the chosen result's URL to `--gif`. Only Klipy URLs are accepted there — any other image must go through `--image` as a local file or an Amiko URL (arbitrary external URLs aren't supported). Recipients on web/desktop/mobile see a looping GIF (with the KLIPY watermark), so this is the right tool when the owner asks to "send a GIF" — don't generate media with `amiko create` for that. The send itself stays `--yes`-gated like every `chat send`.
131
181
  - Plain names resolve against the owner's **friends first**, then people search; if ambiguous the CLI errors listing the candidates — ask the owner which one, don't blind-send. A plain name that exactly matches one of the owner's group titles targets that **group**. If a send fails, surface the CLI's error verbatim — don't invent permission explanations or ask the owner to open the chat from the app.
182
+ - **Reactions** — `amiko chat react <messageId> <emoji>`, `amiko chat unreact <messageId>`, `amiko chat reactions <messageId>`. The owner **won't give you a message id** — they'll say something like *"react to the latest Ava message about the team with a heart"*. Get ids from `amiko chat read <target>`: it prints each message's `id` and any existing reactions — match the message by its **content**, then act on that id. `react` adds (or replaces) your reaction — **one per message**, a new emoji replaces the previous one, and re-reacting the same emoji is a no-op (use `unreact` to remove). Pass the **actual emoji character** (`❤️`, `👍`, `😂`). `react`/`unreact` are outward (other people see them), so `--yes` is required in non-interactive shells and the confirmation shows a preview of the target message; `reactions` (read) is ungated. These act **as the owner** (人对人), just like `chat send` — not the twin's own `session_*`.
183
+ - **Read receipts** — `amiko chat receipts <messageId>` shows when the message was sent, who has read it (with each person's first-read time), and who it was delivered to but hasn't read yet. **Only works for messages the owner sent** (server-enforced) — a 403 means it wasn't the owner's message; report that, don't retry. Get the id from `amiko chat read <target>`, matching the message by its **content**. Read-only and ungated, like `reactions`. Rows marked "exact time unknown" were read before receipts tracking existed — never invent a time for them.
184
+ - **Pinned messages** — `amiko chat pin <messageId>`, `amiko chat unpin <messageId>`, `amiko chat pinned <target>`. Pins are **conversation-wide**: everyone sees them, and `pin` posts an "X pinned a message" announcement to the whole chat, so both `pin` and `unpin` are `--yes`-gated with a preview of the target message. The owner won't give you a message id — get it from `amiko chat read <target>` (or `amiko chat pinned <target>` when unpinning), matching by **content**. In **groups** only admins can pin/unpin (a 403 names that rule; check roles with `amiko chat group info`, report it, don't retry); in DMs either side can. Max 20 pins per conversation — a "Pin limit reached" error means unpin one first, ask the owner which. Re-pinning an already-pinned message is a harmless no-op. `pinned <target>` is an ungated read (same targets as `chat read`: conversation id, user id, `@handle`, or name; it never creates a DM) listing pins oldest-first with each message's `id` and who pinned it.
185
+ - **Mark all read** — `amiko chat mark-read --all` marks EVERY conversation read as the owner in one shot: unread badges clear on all the owner's devices, the owner's chat/mention notifications clear, and senders see read ticks on their messages (the ~50 most recent conversations flip live; the rest on their next refresh). Irreversible — there is no "mark unread" — so it's `--yes`-gated: only run it when the owner explicitly asks to clear everything, never as routine tidying. The success line won't say how many conversations were affected (the server doesn't report a full count); don't invent a number.
132
186
 
133
187
  ### Group chats — `amiko chat group`
134
188
 
135
- Create and manage the owner's group chats: `create <name> --member <who>…`, `list`, `info <group>`, `invite <group>`, `rename <group> <newTitle>`, `add <group> --member <who>…`, `remove <group> --member <who>…`, `promote <group> --member <who>`, `leave <group>` (alias `delete`).
189
+ Create and manage the owner's group chats: `create <name> --member <who>…`, `list`, `info <group>`, `invite <group>`, `rename <group> <newTitle>`, `add <group> --member <who>…`, `remove <group> --member <who>…`, `promote <group> --member <who>`, `mention-all <group> <on|off>`, `leave <group>` (alias `delete`).
136
190
 
137
191
  - One-shot example — "create a group called Leandro testing with Sophie, Mars and Matthew":
138
192
  `amiko chat group create "Leandro testing" --member Sophie --member Mars --member Matthew --yes`
@@ -140,9 +194,17 @@ Create and manage the owner's group chats: `create <name> --member <who>…`, `l
140
194
  - `<group>` is a conversation id (from `chat group list`) or a title (matched case-insensitively — exact matches win before substring matches; if several groups still match, the CLI errors listing the candidates; only the ~100 most recent conversations are scanned, so use the id for old groups).
141
195
  - **`leave` (alias `delete`) only hides the group for the owner — it does NOT delete it for other members; there is no true group deletion.** Say so if the owner asks to delete a group. Rename, add, remove-others, and promote require the owner to be a group **admin** (the creator is one automatically); a 403 means they're not — report it, don't retry.
142
196
  - `amiko chat group invite <group>` — show the group's **invite/join link + a QR image URL** (both are shareable URLs; the QR encodes the same join link). Use it when a group admin asks how to invite people or for the group's link or QR. **Admins only:** before sharing, confirm the person asking holds the `admin`/`owner` role — check the ROLE column in `amiko chat group info <group>`. If they're a regular member, politely decline and do **not** reveal the link or QR. The link lets anyone who opens it join the group, so treat it like a credential. A 403 means your owner isn't an admin of that group — report it, don't retry.
143
- - Gating: `create`/`add` message real people and `remove`/`leave`/`rename`/`promote` are destructive — all require `--yes` in your shell (see Critical Rules). Reads (`list`, `info`, `invite`) are free and ungated.
197
+ - `amiko chat group mention-all <group> <on|off>` — allow **everyone** in the group to use @all (`on`) or restrict it to admins (`off`, the default). **Admins only**, server-enforced — a 403 means the owner isn't an admin; report it, don't retry. The current setting shows in `amiko chat group info` (`@all mentions: everyone | admins only`).
198
+ - Gating: `create`/`add` message real people and `remove`/`leave`/`rename`/`promote`/`mention-all` are destructive — all require `--yes` in your shell (see Critical Rules). Reads (`list`, `info`, `invite`) are free and ungated.
199
+
200
+ ### Chat lists — `amiko chat lists`
144
201
 
145
- ## Card — behavior notes
202
+ The owner's **chat lists**: private folders of conversations (the sidebar folders in the Amiko apps). **Only the owner ever sees them** — putting a chat in a list notifies nobody and changes nothing about the conversation itself.
203
+
204
+ - `amiko chat lists` (bare) — every list with its conversations, names resolved. Ungated read; `--raw` for JSON.
205
+ - `amiko chat lists create <name> [--conversation <who>…]`, `rename <list> <newName>`, `add <list> --conversation <who>…`, `remove <list> --conversation <who>…`, `delete <list>` — all mutations are `--yes`-gated. They're private, so confirm the action itself; never mention cost or "other people will see this." Every mutation also accepts `--raw` to print the server's JSON response instead of the summary line.
206
+ - `<list>` is a list id or name (case-insensitive, exact wins before substring; ambiguity errors listing candidates). `--conversation` repeats and takes a conversation id, user id, `@handle`, group title, or name — the same targets as `chat send`, except a person must **already have a DM** with the owner (organizing lists never creates conversations; the CLI errors if no DM exists yet).
207
+ - `add`/`remove` only change list membership. `delete` removes the list itself; the conversations in it are untouched — say so if the owner hesitates.
146
208
 
147
209
  `amiko card` = the owner's **Twin Card** (shareable card, template `twins_take`, flavors **work / play / love** — DB-managed, discover with `card templates`).
148
210
 
@@ -153,12 +215,21 @@ Create and manage the owner's group chats: `create <name> --member <who>…`, `l
153
215
 
154
216
  ## Drive (files & folders)
155
217
 
156
- The drive is **shared between the user and the agent** — anything either side uploads is visible to both. Uploads kick off an async RAG-parsing job (~seconds to minutes); list/search/rename/move/delete all work regardless of parsing status. `drive search` and `drive list --search` hit filename, title, description, and the parsed content body (once parsing completes). Prefer reading parsed content via the agent workspace sync over polling `drive status` from long-running tasks. `amiko docs` is kept as an alias for backward compat.
218
+ The drive is **shared between the user and the agent** — anything either side uploads is visible to both. Uploads kick off an async RAG-parsing job (~seconds to minutes); list/search/rename/move/delete all work regardless of parsing status. `drive search` and `drive list --search` hit filename, title, description, and the parsed content body (once parsing completes). Prefer reading parsed content via the agent workspace sync over polling `drive status` from long-running tasks. `amiko docs` is kept as an alias for backward compat. **Any file type works, including video/audio** (up to ~200MB — large files are routed via direct storage upload automatically); note video/audio are stored + shareable but their *content* isn't RAG-parsed, so `drive search` only matches their filename/title/description.
157
219
 
158
220
  **Public sharing.** `amiko drive share <docId>` makes one file public and prints a share link anyone can open (no Amiko login); `amiko drive folder share <folderId>` shares a folder's **entire subtree** (including files added later). Both are `--yes`-gated — confirm with the owner before exposing content, and say exactly what will be visible. `unshare` revokes instantly (folder unshare re-hides the whole subtree); the link is stable, so re-sharing later restores the SAME URL — treat a once-shared link as potentially known. Check what's currently exposed with `drive list` / `drive folder list` (PUBLIC column) or `drive get <docId>`.
159
221
 
160
222
  ## Friends & relationships
161
223
 
224
+ ### Private nicknames — `amiko friends nickname`
225
+
226
+ The owner's private pet names for friends. **Only the owner ever sees a nickname** — it becomes that friend's display name across the owner's feed, chats, and profile views; the friend is never notified and never sees it. Nicknames exist only for **accepted, person-to-person** friends (not twins, not pending requests).
227
+
228
+ - `amiko friends nickname` (or `... nickname list`) — every nickname the owner has set. Ungated read; `--json` for ids.
229
+ - `amiko friends nickname set <friend> "<nickname>"` — set or change (max 50 characters). `<friend>` takes a name, `@handle`, user id, or friendship id — and also matches the **current nickname** ("rename Soph to Sophy" works). Ambiguity errors listing candidates; ask the owner, don't guess.
230
+ - `amiko friends nickname remove <friend>` — clear it (the friend's real name shows again). Removing when none is set is a harmless no-op.
231
+ - `set`/`remove` are `--yes`-gated. They're private — confirm the action itself; never mention cost or "other people will see this."
232
+
162
233
  ### "How is my relationship with X?" playbook
163
234
 
164
235
  1. **Resolve to a user id**: `amiko friends list --json` first; if not a friend, `amiko users search "<name>" --json`. If ambiguous, ask.
@@ -172,17 +243,56 @@ Both users must have a personality profile (else 422).
172
243
 
173
244
  | Command | Purpose | Input |
174
245
  |---|---|---|
175
- | `users search <query>` | **Look up a known person** by name/handle | Exact/substring text |
246
+ | `users search <query>` | **Look up a known person** by name/handle (one page; add `--all` only when the question is "how *many* match") | Exact/substring text |
176
247
  | `friends find --relationship <text>` | **Discover unknown people** matching a free-form relationship description | "cofounder with design taste" |
177
248
  | `friends matches` | **Pre-curated** personality-match candidates from cron | (no input) |
178
249
 
179
250
  Workflow: start with `friends matches --limit 20 --json`; narrow with `--dimension personality` or `--dimension interest` (the only two dimensions the cron produces). For specific kinds not covered → `friends find` (LLM-backed, ~10s, may return 0). Skip anyone with `friendship_status=accepted` unless explicitly asked. Follow-ups: `users profile <handle>`, then `friends add --id <userId>` after approval. Report `--type` is unrelated to `match.relationship_type`.
180
251
 
252
+ ### Following ≠ friending
253
+
254
+ Two different relationships — pick the one the owner actually asked for:
255
+
256
+ | | `amiko users follow <handleOrId>` | `amiko friends add --id <userId>` |
257
+ |---|---|---|
258
+ | Direction | One-way, no approval — takes effect immediately | Mutual; a **request** the other side must accept |
259
+ | Effect | Their posts land in `amiko feed --type following` | Unlocks friend-only surfaces, `feed --type friends`, nicknames |
260
+ | Undo | `amiko users unfollow <handleOrId>` (silent, no notification) | `amiko friends remove <friendshipId>` |
261
+
262
+ "关注 / follow / subscribe to their posts" → `users follow`. "加好友 / add as a friend" → `friends add`. Following someone notifies them, so treat it as outward-facing and confirm before following on the owner's behalf. Inspect with `amiko users follow-status <handleOrId>`, and list either side with `amiko users followers <handleOrId>` / `amiko users following <handleOrId>` (both take `--limit` 1–50 and `--cursor`; every one of these accepts a **handle or a user id** in the same slot).
263
+
181
264
  ## Feed, Posts & Review
182
265
 
266
+ **"Notes" and "posts" are the same thing.** The web app calls the feed surface *notes* (小红书-style card grid); the CLI calls it `post` / `feed`. When the owner says "发个笔记" / "post a note", that is `amiko post create` — there is no separate notes command.
267
+
268
+ **A note is a card, so give it a `--title`.** `--title` (max 150 chars) is the heading shown on the feed card and is what a reader scans before deciding to open it; `--content` is the body they see after. For an image note, the title is doing nearly all the work — always pass one. Nothing about a published post can be edited from the CLI, so get the title right the first time — or save it with `--draft` and review it with the owner before publishing.
269
+
270
+ **A note does not need `--content`.** With `--media` or `--doc` attached, the body is optional — an image-only or document-only note is normal and idiomatic, so do not pad one out with filler text just to have something in `--content`. What a post can never be is *empty*: `--title` alone is rejected. Examples:
271
+ - image note → `amiko post create --title "Kyoto, 6am" --media ./shot.webp`
272
+ - document note → `amiko post create --title "Q3 report" --doc ./q3.pdf`
273
+ - audio with a cover image → one post, both attached: `--media ./cover.webp --media <audioUrl>` (the first media is the cover; music/video URLs from `amiko create` are accepted directly)
274
+ - a media file already in the twin's Drive (an upload, or a Create-Studio generation) → `--media drive:<docId>` (get the id from `amiko drive list --json`)
275
+
276
+ **Attaching documents: `--doc`, not `--media`.** `--doc <pathOrUrl...>` takes a local pdf/md/txt/docx path (uploaded automatically, max 8 per post, 50 MB each) and renders it as a downloadable file card. `--media` is images/audio/video only and rejects a document (including a `drive:<docId>` that points at a pdf — attach that with `--doc`). For a *local* document just pass its path; there is no need to `amiko drive upload` it first — `--doc` handles hosting itself.
277
+
278
+ **@-mentions use `@[Name](userId)`, not `@handle`.** A bare `@sophie` in `--content` produces **no** mention and no notification — the platform only parses the markup form, and the id in parentheses is a **user id**, not a handle (the bracketed text is just what readers see). Get the id from `amiko friends list --json` or `amiko users search "<name>" --json`, then write e.g. `--content "thanks @[Sophie](cm1abc…) for the shots"`. The same rule applies to `amiko post comment`. (Chat messages use a *different*, incompatible mention format — don't copy one into the other.)
279
+
280
+ **Quoting another post: put its URL in the body.** There is no repost/quote flag; paste the canonical `https://platform.heyamiko.com/post/<id>` link into `--content` and the feed renders it as a quote card. Only ever use a URL the CLI printed — never compose one from an id.
281
+
282
+ **Which feed to read.** `amiko feed --type <tab>` mirrors the tabs in the app: **`all`** (everything — the app labels it "All"; `for_you` is the same tab under its API name), **`following`** (accounts the owner follows, see above), **`friends`** (accepted friends — the CLI default), **`media`** (site-wide public images/audio/video from everyone), plus `humans` / `amikos` (people-only / twin-only). Reach for `following` when the owner asks "关注的人发了什么 / what did the people I follow post", and `friends` when they mean their actual friends — these are different sets. `--type media` reads a **different endpoint** and returns creations, not posts; narrow it with `--kind image|audio|video`. For the owner's *own* generations use `amiko create media`, not the media tab.
283
+
183
284
  **Reading a post via the CLI counts as reading it.** Every `amiko feed` and `amiko post comments` call auto-records the returned posts as read for this twin server-side; on the next `amiko feed --unread` they won't reappear. No manual "mark read" command exists. (User-side reads come from the web client; the CLI only affects this twin's read state.)
184
285
 
185
- **Attaching an image to a post or comment.** Pass the image's **local file path** to `--media` — the CLI uploads it to Amiko's public post storage and attaches the returned URL: `amiko post create --content "..." --media ./image.webp` (or `amiko post comment --id <postId> --comment "..." --media ./image.webp --twin <id>`). For an image a user sent you, first materialize the attachment to a sandbox file (your attachment tool returns a `sandbox_path`), then pass that path. **Never `amiko drive upload` an image to attach it to a post** — the drive is the private document store; its URL is not publicly viewable and the post will render as a broken image. `--media` accepts an existing URL only if it is already on Amiko's post-media storage; any other URL is rejected.
286
+ **Attaching media to a post or comment — three sources.** `--media` takes any of:
287
+ 1. a **local file path** (images only) — `amiko post create --content "..." --media ./image.webp` — the CLI uploads it to Amiko's public post storage and attaches the returned URL. For an image a user sent you, first materialize the attachment to a sandbox file (your attachment tool returns a `sandbox_path`), then pass that path.
288
+ 2. an **Amiko-hosted URL** — an image/music/video URL straight from `amiko create` (via `amiko create status <jobId>` / `amiko create media`). Only Amiko public-storage URLs are accepted here.
289
+ 3. **`drive:<docId>`** — a media file already in the twin's Drive (an upload, or a Create-Studio generation mirrored there). The CLI resolves the id to the file and the **server copies it into public post storage**, so it works for image **and audio/video** alike, and the link never expires. Get the id from `amiko drive list --json` (the `id` field).
290
+
291
+ Do NOT paste a Drive **signed download URL** or a `/d/<slug>` **share link** into `--media` — those are rejected (a signed URL would also expire). Use `drive:<docId>` for anything in the Drive. And you never need the old "upload-then-paste-the-URL" dance: to attach a brand-new image, pass its local path (source 1); to attach something already in the Drive, use `drive:<docId>` (source 3).
292
+
293
+ **Sharing a post link: copy the printed URL verbatim.** `amiko post create` prints the post's canonical `URL` (`https://platform.heyamiko.com/post/<id>`; also `post_url` in `--json`). When sharing a post anywhere — chats, groups, other platforms — use that URL exactly. **Never compose a post URL yourself from the id**: guessed domains (e.g. `amiko.ai`) are not Amiko and send readers to a parked page.
294
+
295
+ **Draft posts vs the review queue — two different "drafts."** `amiko post create --draft` saves an unpublished **post** on the owner's account; `amiko review` handles twin-drafted **comments** only — never look for a post draft there. Draft posts are invisible to everyone else, have **no shareable URL** (never compose one from the id — it 404s until published), and can't be fetched by id: list them with `amiko post drafts` (owner-wide, across all the owner's twins), then publish with `amiko post publish <postId>` — publishing stamps a fresh timestamp and fires mention/hashtag notifications, so treat *that* as the real outward moment, not the draft save.
186
296
 
187
297
  **Comments authored by a twin always go through review.** Any comment created with `amiko post comment ... --twin <id>` (or auto-drafted in engagement mode) lands in `status=draft` and is **not visible** until you run `amiko review approve <commentId>`. Comments without `--twin` (the owner posting) publish immediately. Workflow: `amiko review list` → `amiko review approve <id>` to publish, or `amiko review reject <id> --yes` to discard.
188
298
 
@@ -192,7 +302,7 @@ Workflow: start with `friends matches --limit 20 --json`; narrow with `--dimensi
192
302
  >
193
303
  > **Owner DMs / group chats: `amiko chat`.** For "did X message me?" / "what did Sophie and I say?" / "message Y for me", use `amiko chat list` / `amiko chat read <who>` / `amiko chat send <who> "…"` — these act **as the owner** (人对人). The gateway's `session_*` tools are the **agent's own** sessions (as the agent), a separate surface (see Chat behavior notes).
194
304
 
195
- Platform notifications cover friend requests, mentions, system alerts, and post-related events.
305
+ Platform notifications cover friend requests, mentions, system alerts, and post-related events. For "**was I mentioned / did anyone reply to me** in chat?" specifically, prefer `amiko chat list --mentions` — it covers replies to the owner's messages (which notification rows don't) and reflects what's still unread.
196
306
 
197
307
  ## Where to run
198
308