@heyamiko/amiko-cli 0.10.1-beta.3 → 0.10.1-beta.4

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @heyamiko/amiko-cli (v0.10.1-beta.3)
1
+ # @heyamiko/amiko-cli (v0.10.1-beta.4)
2
2
 
3
3
  Manage wallets, credits, swaps, MPP marketplace services, and your Amiko twin (identity, documents, voice, avatar, friends, feed, Composio apps) from the terminal. Works for both human users and AI agents running on OpenClaw.
4
4
 
@@ -393,6 +393,10 @@ npm publish
393
393
 
394
394
  ## Changelog
395
395
 
396
+ ### 0.10.1-beta.4
397
+
398
+ - **`amiko conversation` removed (breaking).** DMs / chat history are now served by the openhermit gateway's built-in `session_list` / `session_read` tools (unified view across the agent's local sessions and platform DMs), so the CLI no longer needs `conversation list / find / create / read / send`. `src/commands/conversation.ts` deleted; index registration + command group removed; SKILL.md frontmatter and Conversations section rewritten to route DM questions to the gateway tools and the remaining notifications-only block renamed `## Notifications`. Skill description and command-groups paragraph updated; the "did anyone DM me?" example row dropped from the cold-start examples table. Update any scripts that ran `amiko conversation` — there is no shim, the command returns "unknown command".
399
+
396
400
  ### 0.10.1-beta.3
397
401
 
398
402
  - **`amiko drive` namespace** replaces `amiko docs` (kept as a `.alias("docs")` so existing scripts and agents keep working). Tracks the [Amiko Drive API](https://github.com/HCF-STUDIOS/amiko-platform/blob/main/amiko-web/docs/api/drive.md): files live under twin-scoped folders, every upload kicks off async RAG parsing, and search hits parsed content once processing completes. Commands:
package/dist/index.js CHANGED
@@ -30951,187 +30951,6 @@ function registerComposioCommand(program2) {
30951
30951
  });
30952
30952
  }
30953
30953
 
30954
- // src/commands/conversation.ts
30955
- function describeConversation(c, selfUserId) {
30956
- if (c.title)
30957
- return c.title;
30958
- const others = c.participants?.filter((p) => !(p.participant_type === "user" && p.participant_id === selfUserId)) ?? [];
30959
- return others.map((p) => p.name ?? p.participant_id).join(", ") || c.id;
30960
- }
30961
- function findDirectWithUser(list, selfUserId, otherUserId) {
30962
- return list.find((c) => {
30963
- if (c.conversation_type !== "direct")
30964
- return false;
30965
- const ps = c.participants ?? [];
30966
- const userIds = ps.filter((p) => p.participant_type === "user" && !p.left_at).map((p) => p.participant_id);
30967
- if (userIds.length !== 2)
30968
- return false;
30969
- if (selfUserId && !userIds.includes(selfUserId))
30970
- return false;
30971
- return userIds.includes(otherUserId);
30972
- });
30973
- }
30974
- function registerConversationCommand(program2) {
30975
- program2.command("list").description("List your conversations").option("--archived <state>", "active | archived | all", "active").option("--limit <n>", "Max results (1–100)", "50").option("--offset <n>", "Pagination offset", "0").option("--json", "Output as JSON").action(async (opts) => {
30976
- const auth = resolveAuth();
30977
- const config2 = loadConfig();
30978
- const spinner = opts.json ? null : ora("Loading conversations...").start();
30979
- try {
30980
- const data = await amikoWebFetch(auth, "/api/conversations", {
30981
- query: {
30982
- archived: opts.archived,
30983
- limit: opts.limit,
30984
- offset: opts.offset
30985
- }
30986
- });
30987
- spinner?.stop();
30988
- renderOutput(data, (d) => {
30989
- if (!d.conversations.length) {
30990
- console.log(dim("No conversations."));
30991
- return;
30992
- }
30993
- console.log(heading(`Conversations — ${d.conversations.length} of ${d.pagination.total}`));
30994
- for (const c of d.conversations) {
30995
- console.log("");
30996
- console.log(label("ID", c.id));
30997
- console.log(label("With", describeConversation(c, config2.userId)));
30998
- console.log(label("Type", c.conversation_type));
30999
- if (c.last_activity_at)
31000
- console.log(label("Last activity", c.last_activity_at));
31001
- if (c.unread_count)
31002
- console.log(label("Unread", String(c.unread_count)));
31003
- }
31004
- if (d.pagination.has_more) {
31005
- console.log("");
31006
- console.log(dim(`More available — pass --offset ${Number(opts.offset ?? 0) + d.conversations.length}`));
31007
- }
31008
- }, { json: opts.json });
31009
- } catch (e5) {
31010
- spinner?.stop();
31011
- console.error(error(e5 instanceof Error ? e5.message : String(e5)));
31012
- process.exit(1);
31013
- }
31014
- });
31015
- program2.command("find").description("Find an existing direct conversation with a user").requiredOption("--user-id <id>", "Internal user id of the other party").option("--json", "Output as JSON").action(async (opts) => {
31016
- const auth = resolveAuth();
31017
- const config2 = loadConfig();
31018
- const spinner = opts.json ? null : ora("Searching...").start();
31019
- try {
31020
- const data = await amikoWebFetch(auth, "/api/conversations", { query: { archived: "all", limit: 100 } });
31021
- spinner?.stop();
31022
- const match = findDirectWithUser(data.conversations, config2.userId, opts.userId);
31023
- if (opts.json) {
31024
- console.log(JSON.stringify({ conversation: match ?? null }, null, 2));
31025
- return;
31026
- }
31027
- if (!match) {
31028
- console.log(dim(`No direct conversation with user ${opts.userId}. Run \`amiko conversation create --user-id ${opts.userId}\` to start one.`));
31029
- return;
31030
- }
31031
- console.log(success("Found conversation"));
31032
- console.log(label("ID", match.id));
31033
- console.log(label("With", describeConversation(match, config2.userId)));
31034
- if (match.last_activity_at)
31035
- console.log(label("Last activity", match.last_activity_at));
31036
- } catch (e5) {
31037
- spinner?.stop();
31038
- console.error(error(e5 instanceof Error ? e5.message : String(e5)));
31039
- process.exit(1);
31040
- }
31041
- });
31042
- program2.command("create").description("Create (or reuse) a direct conversation with another user").requiredOption("--user-id <id>", "Internal user id of the other party").option("--json", "Output as JSON").action(async (opts) => {
31043
- const auth = resolveAuth();
31044
- const spinner = opts.json ? null : ora("Creating conversation...").start();
31045
- try {
31046
- const data = await amikoWebFetch(auth, "/api/conversations", {
31047
- method: "POST",
31048
- body: {
31049
- participant_ids: [opts.userId],
31050
- participant_types: ["user"],
31051
- conversation_type: "direct"
31052
- }
31053
- });
31054
- spinner?.stop();
31055
- if (opts.json) {
31056
- console.log(JSON.stringify(data, null, 2));
31057
- return;
31058
- }
31059
- console.log(success(data.reused_existing ? "Reused existing conversation" : "Conversation created"));
31060
- console.log(label("ID", data.conversation.id));
31061
- } catch (e5) {
31062
- spinner?.stop();
31063
- console.error(error(e5 instanceof Error ? e5.message : String(e5)));
31064
- process.exit(1);
31065
- }
31066
- });
31067
- program2.command("read").description("Read messages from a conversation (oldest-first, paginated)").requiredOption("--id <conversationId>", "Target conversation id").option("--limit <n>", "Max messages (1–100)", "50").option("--before-cursor <cursor>", "Page back via next_cursor from a prior call").option("--json", "Output as JSON").action(async (opts) => {
31068
- const auth = resolveAuth();
31069
- const spinner = opts.json ? null : ora("Loading messages...").start();
31070
- try {
31071
- const data = await amikoWebFetch(auth, `/api/conversations/${encodeURIComponent(opts.id)}/messages`, {
31072
- query: {
31073
- limit: opts.limit,
31074
- before_cursor: opts.beforeCursor
31075
- }
31076
- });
31077
- spinner?.stop();
31078
- if (opts.json) {
31079
- console.log(JSON.stringify(data, null, 2));
31080
- return;
31081
- }
31082
- if (!data.messages.length) {
31083
- console.log(dim("No messages."));
31084
- return;
31085
- }
31086
- console.log(heading(`Messages — ${data.messages.length}`));
31087
- for (const m of data.messages) {
31088
- console.log("");
31089
- console.log(label(m.name ?? m.sender_id ?? "?", m.created_at?.slice(0, 19) ?? ""));
31090
- if (m.content)
31091
- console.log(m.content);
31092
- if (m.message_type && m.message_type !== "text")
31093
- console.log(dim(`[${m.message_type}]`));
31094
- console.log(dim(`id: ${m.id}`));
31095
- }
31096
- if (data.has_more && data.next_cursor) {
31097
- console.log("");
31098
- console.log(dim(`Older messages available — pass --before-cursor ${data.next_cursor}`));
31099
- }
31100
- } catch (e5) {
31101
- spinner?.stop();
31102
- console.error(error(e5 instanceof Error ? e5.message : String(e5)));
31103
- process.exit(1);
31104
- }
31105
- });
31106
- program2.command("send").description("Send a message into a conversation").requiredOption("--id <conversationId>", "Target conversation id").requiredOption("--message <text>", "Message body").option("--reply-to <messageId>", "Reply to a specific message").option("--as-agent", "Send as the twin agent (sender_type=agent, is_auto_reply=true). Twin must be a participant.").option("--json", "Output as JSON").action(async (opts) => {
31107
- const auth = requireAuth();
31108
- const spinner = opts.json ? null : ora("Sending message...").start();
31109
- try {
31110
- const data = await amikoWebFetch(auth, `/api/conversations/${encodeURIComponent(opts.id)}/messages`, {
31111
- method: "POST",
31112
- body: {
31113
- content: opts.message,
31114
- message_type: "text",
31115
- ...opts.replyTo ? { reply_to_id: opts.replyTo } : {},
31116
- ...opts.asAgent ? { as_agent: true } : {}
31117
- }
31118
- });
31119
- spinner?.stop();
31120
- if (opts.json) {
31121
- console.log(JSON.stringify(data, null, 2));
31122
- return;
31123
- }
31124
- console.log(success("Message sent"));
31125
- if (data.message?.id)
31126
- console.log(label("Message ID", data.message.id));
31127
- } catch (e5) {
31128
- spinner?.stop();
31129
- console.error(error(e5 instanceof Error ? e5.message : String(e5)));
31130
- process.exit(1);
31131
- }
31132
- });
31133
- }
31134
-
31135
30954
  // src/commands/notifications.ts
31136
30955
  function registerNotificationsCommand(program2) {
31137
30956
  program2.command("list").description("List platform notifications (friend requests, system alerts, activity)").option("--limit <n>", "Max results (1–100)", "20").option("--cursor <iso>", "Page older items via next_cursor from a prior call").option("--unread", "Show only unread").option("--json", "Output as JSON").action(async (opts) => {
@@ -31804,7 +31623,6 @@ var users = program2.command("users").description("Search users and view public
31804
31623
  var post = program2.command("post").description("Create posts and comments on the feed");
31805
31624
  var review = program2.command("review").description("Review queue — list, approve, or reject twin-drafted comments");
31806
31625
  var composio = program2.command("composio").description("Manage Composio app connections");
31807
- var conversation = program2.command("conversation").description("Conversations — list, find, create, send messages between users/agents");
31808
31626
  var notifications = program2.command("notifications").description("Platform notifications — list, mark as read");
31809
31627
  registerCreditsCommand(program2);
31810
31628
  registerSearchCommand(markets);
@@ -31831,7 +31649,6 @@ registerFeedCommand(program2);
31831
31649
  registerPostCommand(post);
31832
31650
  registerReviewCommand(review);
31833
31651
  registerComposioCommand(composio);
31834
- registerConversationCommand(conversation);
31835
31652
  registerNotificationsCommand(notifications);
31836
31653
  registerMemoryCommand(program2);
31837
31654
  program2.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heyamiko/amiko-cli",
3
- "version": "0.10.1-beta.3",
3
+ "version": "0.10.1-beta.4",
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 and send platform DMs with other users (conversations list/find/read/send, the right tool when the owner asks "did X message me?" or "check my chat history with Y" — NOT the built-in sessions_list/sessions_history, which only see the agent's own local sessions), 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, call paid MPP marketplace services (X/Twitter search, image generation, Amazon product search, TTS/STT, AI chat, SFX/music), manage the twin's identity and RAG documents, voice and avatar, social graph (friends, posts, comments, feed), and Composio OAuth connections. Auth is automatic when run from the agent's workspace folder; payments are platform-custodied (no keys on disk). Use this skill whenever the user asks about their Amiko inbox/DMs/notifications or to do 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, call paid MPP marketplace services (X/Twitter search, image generation, Amazon product search, TTS/STT, AI chat, SFX/music), manage the twin's identity and drive (files, folders, RAG), voice and avatar, social graph (friends, posts, comments, feed), and Composio OAuth connections. Auth is automatic when run from the agent's workspace folder; payments are platform-custodied (no keys on disk). DMs / chat sessions are NOT in this CLI — use the openhermit gateway's built-in session_list / session_read tools for both local sessions and platform DMs. Use this skill whenever the user asks about their Amiko notifications, 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
  ---
@@ -20,7 +20,6 @@ Call your shell tool (your runtime calls it `bash`, `shell`, `run`, or similar)
20
20
  | "what's my balance?" | shell → `amiko credits balance` |
21
21
  | "top up 10k credits with AMIKO" | shell → `amiko credits topup 10000 --token AMIKO --yes` |
22
22
  | "swap 1 SOL to USDC" | shell → `amiko wallets swap quote 1 SOL USDC` (then send with `--yes` after approval) |
23
- | "did anyone DM me?" | shell → `amiko conversation list` |
24
23
  | "any notifications?" | shell → `amiko notifications list --unread` |
25
24
  | "any new posts I haven't seen?" | shell → `amiko feed --unread` |
26
25
  | "upload report.pdf to my drive" | shell → `amiko drive upload ./report.pdf` |
@@ -39,7 +38,9 @@ The CLI is installed globally and is pre-authenticated when you're inside your w
39
38
 
40
39
  ## Command groups
41
40
 
42
- Discover everything via `amiko --help`. Groups: `markets` (paid MPP services), `wallets`, `credits`, `twin`, `drive` (files / folders / RAG; `docs` is an alias), `voice`, `avatar`, `friends`, `users`, `post`, `review`, `feed`, `composio`, `conversation`, `notifications`, `memory`, plus the top-level `accounts`, `info`, `config`, `update`. All twin-scoped commands accept `--twin <id>`. Most commands support `--json`.
41
+ Discover everything via `amiko --help`. Groups: `markets` (paid MPP services), `wallets`, `credits`, `twin`, `drive` (files / folders / RAG; `docs` is an alias), `voice`, `avatar`, `friends`, `users`, `post`, `review`, `feed`, `composio`, `notifications`, `memory`, plus the top-level `accounts`, `info`, `config`, `update`. All twin-scoped commands accept `--twin <id>`. Most commands support `--json`.
42
+
43
+ > **DMs / chat sessions are NOT in this CLI.** Use the openhermit gateway's built-in `session_list` / `session_read` tools for both the agent's local sessions and platform DMs with other users. The previous `amiko conversation` namespace was removed in 0.10.1-beta.4.
43
44
 
44
45
  ## Critical Rules
45
46
 
@@ -117,18 +118,13 @@ Workflow: start with `friends matches --limit 20 --json`; narrow with `--dimensi
117
118
 
118
119
  **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.
119
120
 
120
- ## Conversations & Notifications
121
+ ## Notifications
121
122
 
122
- > **Default platform = Amiko.** When the owner asks about messages/DMs/chats/notifications **without naming a platform**, assume Amiko and answer with `amiko conversation` / `amiko notifications`. Do **not** ask "which platform?". Only ask if they explicitly mention a non-Amiko channel.
123
+ > **Default platform = Amiko.** When the owner asks about notifications **without naming a platform**, assume Amiko and answer with `amiko notifications`. Only ask if they explicitly mention a non-Amiko channel.
123
124
  >
124
- > **For chat history with another person** ("did X message me?", "check my chat with Y"), use `amiko conversation`. Do **NOT** use built-in `sessions_list` / `sessions_history` — those read the agent's *own* local sessions with the owner, not platform DMs with third parties, and will return nothing useful. Typical flow: `amiko users search "<name>"` → `amiko conversation find --user-id <id>` → `amiko conversation read --id <conversationId>`.
125
-
126
- Behavior notes:
127
- - `conversation find` filters client-side for a 2-user direct conversation containing both you and `--user-id`.
128
- - `conversation create` is idempotent — server reuses an existing direct DM (`reused_existing: true`).
129
- - `--user-id` expects the **internal** user id (from `amiko users search`), not a Privy DID or handle.
130
- - `conversation send --as-agent` sends as the twin (`sender_type=agent`).
131
- - Platform notifications cover friend requests, mentions, system alerts, and post-related events. They don't replace `conversation read` for actual chat content.
125
+ > **DMs / chat history are handled by the openhermit gateway**, not the CLI. For "did X message me?" / "check my chat with Y", use the built-in `session_list` / `session_read` tools — they cover both the agent's local sessions and platform DMs in the unified gateway view.
126
+
127
+ Platform notifications cover friend requests, mentions, system alerts, and post-related events.
132
128
 
133
129
  ## Memory (cross-agent) — READ THIS BEFORE ANSWERING ANYTHING ABOUT THE OWNER
134
130