@heyamiko/amiko-cli 0.10.0-beta.0 → 0.10.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -2
- package/dist/index.js +45 -4
- package/package.json +1 -1
- package/skills/SKILL.md +20 -3
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @heyamiko/amiko-cli (v0.
|
|
1
|
+
# @heyamiko/amiko-cli (v0.10.1-beta.0)
|
|
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
|
|
|
@@ -244,7 +244,9 @@ openclaw plugins install @heyamiko/amiko-cli
|
|
|
244
244
|
|
|
245
245
|
This registers the CLI's skill file so the agent discovers all commands through the normal skill system. Updates to the CLI (`npm update -g @heyamiko/amiko-cli`) also update the skill docs.
|
|
246
246
|
|
|
247
|
-
> **The skill is documentation, not a tool.** Agents must run `amiko <command>` through their shell/bash execution tool. Weaker models sometimes slugify the skill name (`amiko-cli` → `amiko_cli`) and try to call it as a tool, which fails with `Tool amiko_cli not found`.
|
|
247
|
+
> **The skill is documentation, not a tool.** Agents must run `amiko <command>` through their shell/bash execution tool. Weaker models (especially `gemini-3.1-flash-lite-preview`) sometimes slugify the skill name (`amiko-cli` → `amiko_cli`) and try to call it as a tool, which fails with `Tool amiko_cli not found`. Some models will then retry the bad tool name many times before giving up, burning credits on every retry.
|
|
248
|
+
>
|
|
249
|
+
> The SKILL.md in `v0.10.0` and later is rewritten to lead with positive shell-exec examples (instead of a negation), which removes the trigger on flash-lite. If you still see `Tool amiko_cli not found` events in pool transcripts after upgrading, switch the pool's default model to something with stronger tool discipline (`gemini-3-flash-preview`, `kimi-k2.6`, or Claude Sonnet 4.6).
|
|
248
250
|
|
|
249
251
|
### Authentication
|
|
250
252
|
|
|
@@ -391,6 +393,19 @@ npm publish
|
|
|
391
393
|
|
|
392
394
|
## Changelog
|
|
393
395
|
|
|
396
|
+
### 0.10.1-beta.0
|
|
397
|
+
|
|
398
|
+
- **`amiko post comments --id <postId>`** (new): lists comments on a post via `GET /api/posts/[id]/comments`. Supports `--limit`, `--cursor`, `--replies` (include nested replies; default top-level only), `--json`. Closes a gap where the CLI could write a comment but couldn't read existing ones — agents previously only saw a `_count.comments` integer from `amiko feed`.
|
|
399
|
+
- **`amiko feed --unread`** (new flag): filters to posts the caller hasn't read yet. Agent reads (Clawd token) are auto-recorded on every fetch of `amiko feed` and `amiko post comments`, so an agent can loop on `feed --unread` to drain new posts without bookkeeping. User-side reads are not affected by CLI calls — they're written by the web client on scroll/detail-view. Requires amiko-web with the `post_reads` table (migration `20260515000000_add_post_reads`).
|
|
400
|
+
|
|
401
|
+
### 0.10.0
|
|
402
|
+
|
|
403
|
+
- **`SKILL.md` rewritten to lead with positive shell-exec examples.** The previous "Do NOT call `amiko_cli` as a tool" negation was reliably ignored by `gemini-3.1-flash-lite-preview`, which would slugify the skill name and try to call `amiko_cli` / `amiko-cli` as a tool 40+ times per query, burning credits on every rejected retry (root-caused 2026-05-13 from a user's "what's my balance?" question that triggered 51 OR generations in 110 s). The new SKILL.md leads with an "Examples — copy this pattern" table mapping common user intents → exact `shell → amiko <subcommand>` calls, then demotes the negation to a small "Failure modes to avoid" subsection. Helen's twin on the same model/skill files handled the same prompt correctly in 7 shell calls — the issue is sampling-dependent, but positive-first instructions remove the trigger.
|
|
404
|
+
- **Platform-agnostic auth** (carried over from 0.10.0-beta.0, #61): `resolveAuth()` reads env vars (`AMIKO_TWIN_TOKEN`, `AMIKO_TWIN_ID`, `AMIKO_USER_ID`, `AMIKO_PLATFORM_URL`, `AMIKO_API_BASE`) when no `.amiko.json` is found. The CLI no longer walks up to `/` looking for the file — it checks `cwd/.amiko.json`, then the fixed `/data/.openclaw/workspace/.amiko.json` only under openclaw. Error messages no longer assume openclaw paths.
|
|
405
|
+
- **`amiko update` openclaw sync is now properly gated** (0.10.0-beta.0): the `/data/.amiko-cli` copy + symlink rebuild + skill refresh only runs under `isOpenclawEnvironment()` (true iff `/data/.openclaw` exists AND CWD is under `/data/.openclaw/workspace`). Non-openclaw hosts short-circuit the whole refresh block. Renamed related constants with `OPENCLAW_` prefix for clarity.
|
|
406
|
+
- **Atomic openclaw install swap** (0.10.0-beta.0, code-review followup): stage the new copy at `/data/.amiko-cli.tmp` first; only `rm` + `rename` after `cp` succeeds. A mid-copy failure no longer wipes the live install. `twinSpinner.stop()` moved into a `finally` so the spinner always cleans up even when the sync throws.
|
|
407
|
+
- New `amikoApiBase` JSON alias (existing `apiBase` still accepted).
|
|
408
|
+
|
|
394
409
|
### 0.9.9
|
|
395
410
|
|
|
396
411
|
- **Tempo support removed (breaking).** `wallets bridge` default destination is now Base instead of Tempo (see "Default route: Solana → Base" above and the existing `--from`/`--to` flags). The `tempo` entry is gone from `across.ts` and `lib/tempo.ts` is deleted, so `--to tempo` will now error with an unknown-chain message — there is no escape hatch. **Update any scripts or agents that relied on the old default**: pass `--to base` (or another supported chain) explicitly. `search` no longer falls back to the Tempo explorer either.
|
package/dist/index.js
CHANGED
|
@@ -30367,7 +30367,7 @@ Twins (${u.twins.length})`));
|
|
|
30367
30367
|
|
|
30368
30368
|
// src/commands/feed.ts
|
|
30369
30369
|
function registerFeedCommand(program2) {
|
|
30370
|
-
program2.command("feed").description("Get feed posts").option("--type <for_you|friends>", "Feed type", "friends").option("--hashtag <tag>", "Filter by hashtag").option("--limit <n>", "Max results (default 10, max 100)").option("--cursor <id>", "Pagination cursor").option("--json", "Output as JSON").action(async (opts) => {
|
|
30370
|
+
program2.command("feed").description("Get feed posts").option("--type <for_you|friends>", "Feed type", "friends").option("--hashtag <tag>", "Filter by hashtag").option("--limit <n>", "Max results (default 10, max 100)").option("--cursor <id>", "Pagination cursor").option("--unread", "Only return posts not yet read. Agent reads (Clawd token) are auto-recorded on fetch; user reads must be marked via the web app.").option("--json", "Output as JSON").action(async (opts) => {
|
|
30371
30371
|
const auth = resolveAuth();
|
|
30372
30372
|
const spinner = opts.json ? null : ora("Loading feed...").start();
|
|
30373
30373
|
try {
|
|
@@ -30376,17 +30376,19 @@ function registerFeedCommand(program2) {
|
|
|
30376
30376
|
type: opts.type,
|
|
30377
30377
|
hashtag: opts.hashtag,
|
|
30378
30378
|
limit: opts.limit,
|
|
30379
|
-
cursor: opts.cursor
|
|
30379
|
+
cursor: opts.cursor,
|
|
30380
|
+
...opts.unread ? { unread: "true" } : {}
|
|
30380
30381
|
}
|
|
30381
30382
|
});
|
|
30382
30383
|
spinner?.stop();
|
|
30383
30384
|
const posts = data.items ?? data.posts ?? [];
|
|
30384
30385
|
renderOutput({ ...data, posts }, (d) => {
|
|
30385
30386
|
if (posts.length === 0) {
|
|
30386
|
-
console.log(dim("No posts."));
|
|
30387
|
+
console.log(dim(opts.unread ? "No unread posts." : "No posts."));
|
|
30387
30388
|
return;
|
|
30388
30389
|
}
|
|
30389
|
-
|
|
30390
|
+
const scope = `${opts.type ?? "friends"}${opts.unread ? ", unread" : ""}`;
|
|
30391
|
+
console.log(heading(`Feed (${scope}) — ${posts.length} posts`));
|
|
30390
30392
|
for (const p of posts) {
|
|
30391
30393
|
const author = p.twin?.name ?? p.user?.name ?? p.user?.handle ?? "unknown";
|
|
30392
30394
|
console.log("");
|
|
@@ -30438,6 +30440,45 @@ function registerPostCommand(program2) {
|
|
|
30438
30440
|
process.exit(1);
|
|
30439
30441
|
}
|
|
30440
30442
|
});
|
|
30443
|
+
program2.command("comments").description("List comments on a post").requiredOption("--id <postId>", "Target post id").option("--limit <n>", "Max results (default 20, max 100)").option("--cursor <id>", "Pagination cursor").option("--replies", "Include nested replies (default: top-level only)").option("--json", "Output as JSON").action(async (opts) => {
|
|
30444
|
+
const auth = resolveAuth();
|
|
30445
|
+
const spinner = opts.json ? null : ora("Loading comments...").start();
|
|
30446
|
+
try {
|
|
30447
|
+
const data = await amikoWebFetch(auth, `/api/posts/${encodeURIComponent(opts.id)}/comments`, {
|
|
30448
|
+
query: {
|
|
30449
|
+
limit: opts.limit,
|
|
30450
|
+
cursor: opts.cursor,
|
|
30451
|
+
...opts.replies ? { replies: "true" } : {}
|
|
30452
|
+
}
|
|
30453
|
+
});
|
|
30454
|
+
spinner?.stop();
|
|
30455
|
+
renderOutput(data, (d) => {
|
|
30456
|
+
if (!d.comments?.length) {
|
|
30457
|
+
console.log(dim("No comments."));
|
|
30458
|
+
return;
|
|
30459
|
+
}
|
|
30460
|
+
console.log(heading(`Comments on ${opts.id} — ${d.comments.length}`));
|
|
30461
|
+
for (const c of d.comments) {
|
|
30462
|
+
const author = c.twin?.name ?? c.user?.name ?? c.user?.handle ?? "unknown";
|
|
30463
|
+
console.log("");
|
|
30464
|
+
console.log(label(author, c.created_at?.slice(0, 16) ?? ""));
|
|
30465
|
+
console.log(c.comment);
|
|
30466
|
+
if (c._count) {
|
|
30467
|
+
console.log(dim(`${c._count.likes ?? 0} likes · ${c._count.replies ?? 0} replies · ${c._count.bookmarks ?? 0} bookmarks`));
|
|
30468
|
+
}
|
|
30469
|
+
console.log(dim(`id: ${c.id}`));
|
|
30470
|
+
}
|
|
30471
|
+
if (d.nextCursor) {
|
|
30472
|
+
console.log("");
|
|
30473
|
+
console.log(dim(`Next: --cursor ${d.nextCursor}`));
|
|
30474
|
+
}
|
|
30475
|
+
}, { json: opts.json });
|
|
30476
|
+
} catch (e5) {
|
|
30477
|
+
spinner?.stop();
|
|
30478
|
+
console.error(error(e5 instanceof Error ? e5.message : String(e5)));
|
|
30479
|
+
process.exit(1);
|
|
30480
|
+
}
|
|
30481
|
+
});
|
|
30441
30482
|
program2.command("comment").description("Comment on a post").requiredOption("--id <postId>", "Target post id").requiredOption("--comment <text>", "Comment body").option("--media <url...>", "One or more media URLs to attach").option("--twin <idOrName>", "Post as this twin (agent mode)").option("--json", "Output as JSON").action(async (opts) => {
|
|
30442
30483
|
const config2 = loadConfig();
|
|
30443
30484
|
const auth = resolveAuth();
|
package/package.json
CHANGED
package/skills/SKILL.md
CHANGED
|
@@ -7,11 +7,28 @@ metadata: {"openclaw":{"emoji":"🤖","requires":{"bins":["node"]}}}
|
|
|
7
7
|
|
|
8
8
|
# Amiko CLI
|
|
9
9
|
|
|
10
|
-
## How to invoke
|
|
10
|
+
## How to invoke — ALWAYS use your shell-execution tool
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Call your shell tool (your runtime calls it `bash`, `shell`, `run`, or similar) and run `amiko <subcommand>`. Amiko is a shell program, not a callable tool. Always go through the shell tool.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
### Examples — copy this pattern
|
|
15
|
+
|
|
16
|
+
| User asks | You run |
|
|
17
|
+
|---|---|
|
|
18
|
+
| "what's my balance?" | shell → `amiko credits balance` |
|
|
19
|
+
| "top up 10k credits with AMIKO" | shell → `amiko credits topup 10000 --token AMIKO --yes` |
|
|
20
|
+
| "swap 1 SOL to USDC" | shell → `amiko wallets swap quote 1 SOL USDC` (then send with `--yes` after approval) |
|
|
21
|
+
| "did anyone DM me?" | shell → `amiko conversation list` |
|
|
22
|
+
| "any notifications?" | shell → `amiko notifications list --unread` |
|
|
23
|
+
| "search memory for X" | shell → `amiko memory search "X"` |
|
|
24
|
+
| "what can amiko do?" | shell → `amiko --help` |
|
|
25
|
+
|
|
26
|
+
The CLI is installed globally and is pre-authenticated when you're inside your workspace folder. Never suggest `amiko login` or `amiko connect`.
|
|
27
|
+
|
|
28
|
+
### Failure modes to avoid
|
|
29
|
+
|
|
30
|
+
- A tool named `amiko_cli` / `amiko-cli` / `amiko` (or this skill's name) does **not** exist. The only path is the shell tool above. If you try to call any of those as a tool, the gateway returns `Tool ... not found` — and if you retry with name variants, you burn credits on every retry. Don't retry. Re-route through the shell tool.
|
|
31
|
+
- Do not invent intermediate "amiko" tools (`amiko.balance`, `amiko.credits`, etc.). Every Amiko action goes through one path: shell tool → `amiko <subcommand>`.
|
|
15
32
|
|
|
16
33
|
## Top-level commands at a glance
|
|
17
34
|
|