@heyamiko/amiko-cli 0.9.3 → 0.9.5
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 +2 -2
- package/dist/index.js +124 -89
- package/package.json +1 -1
- package/skills/SKILL.md +7 -1
package/README.md
CHANGED
|
@@ -138,7 +138,7 @@ amiko wallets swap send 0.5 USDC AMIKO --yes
|
|
|
138
138
|
amiko wallets swap send 100 AMIKO SOL --slippage 100
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
-
Swaps execute via Jupiter on Solana. Supports SOL, USDC, USDT, AMIKO, PYUSD, BONK, JUP, RAY, JitoSOL, mSOL, or any mint address. `swap send` is hard-gated: in a non-interactive shell you must pass `--yes` after quoting the cost to the user (`Solana gas +
|
|
141
|
+
Swaps execute via Jupiter on Solana. Supports SOL, USDC, USDT, AMIKO, PYUSD, BONK, JUP, RAY, JitoSOL, mSOL, or any mint address. `swap send` is hard-gated: in a non-interactive shell you must pass `--yes` after quoting the cost to the user (`Solana gas + Jupiter referral fee`).
|
|
142
142
|
|
|
143
143
|
## Bridge
|
|
144
144
|
|
|
@@ -197,7 +197,7 @@ Every paid / value-moving command (`image`, `search`, `amazon search`, `service
|
|
|
197
197
|
amiko markets image "a sunset over mountains" --yes
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
This makes cost confirmation effectively mandatory regardless of which model drives the agent — weak models can no longer silently burn tokens by ignoring the skill docs. The same refusal fires for `swap send` (Solana gas +
|
|
200
|
+
This makes cost confirmation effectively mandatory regardless of which model drives the agent — weak models can no longer silently burn tokens by ignoring the skill docs. The same refusal fires for `swap send` (Solana gas + Jupiter referral fee) and `bridge send` (Across fee + gas), so an agent cannot move tokens without a round-trip through user approval.
|
|
201
201
|
|
|
202
202
|
## Error Output
|
|
203
203
|
|
package/dist/index.js
CHANGED
|
@@ -5,25 +5,43 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
8
13
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
9
21
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
22
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
23
|
for (let key of __getOwnPropNames(mod))
|
|
12
24
|
if (!__hasOwnProp.call(to, key))
|
|
13
25
|
__defProp(to, key, {
|
|
14
|
-
get: (
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
15
27
|
enumerable: true
|
|
16
28
|
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
17
31
|
return to;
|
|
18
32
|
};
|
|
19
33
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
+
var __returnValue = (v) => v;
|
|
35
|
+
function __exportSetter(name, newValue) {
|
|
36
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
37
|
+
}
|
|
20
38
|
var __export = (target, all) => {
|
|
21
39
|
for (var name in all)
|
|
22
40
|
__defProp(target, name, {
|
|
23
41
|
get: all[name],
|
|
24
42
|
enumerable: true,
|
|
25
43
|
configurable: true,
|
|
26
|
-
set: (
|
|
44
|
+
set: __exportSetter.bind(all, name)
|
|
27
45
|
});
|
|
28
46
|
};
|
|
29
47
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -3515,11 +3533,36 @@ var require_emoji_regex = __commonJS((exports, module) => {
|
|
|
3515
3533
|
};
|
|
3516
3534
|
});
|
|
3517
3535
|
|
|
3518
|
-
// node_modules/mppx/dist/
|
|
3519
|
-
var
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3536
|
+
// node_modules/mppx/dist/Method.js
|
|
3537
|
+
var exports_Method = {};
|
|
3538
|
+
__export(exports_Method, {
|
|
3539
|
+
toServer: () => toServer,
|
|
3540
|
+
toClient: () => toClient,
|
|
3541
|
+
from: () => from
|
|
3542
|
+
});
|
|
3543
|
+
function from(method) {
|
|
3544
|
+
return method;
|
|
3545
|
+
}
|
|
3546
|
+
function toClient(method, options) {
|
|
3547
|
+
const { context, createCredential } = options;
|
|
3548
|
+
return {
|
|
3549
|
+
...method,
|
|
3550
|
+
context,
|
|
3551
|
+
createCredential
|
|
3552
|
+
};
|
|
3553
|
+
}
|
|
3554
|
+
function toServer(method, options) {
|
|
3555
|
+
const { defaults, html, request, respond, transport, verify } = options;
|
|
3556
|
+
return {
|
|
3557
|
+
...method,
|
|
3558
|
+
defaults,
|
|
3559
|
+
html,
|
|
3560
|
+
request,
|
|
3561
|
+
respond,
|
|
3562
|
+
transport,
|
|
3563
|
+
verify
|
|
3564
|
+
};
|
|
3565
|
+
}
|
|
3523
3566
|
|
|
3524
3567
|
// node_modules/mppx/node_modules/zod/v4/core/core.js
|
|
3525
3568
|
function $constructor(name, initializer, params) {
|
|
@@ -16604,89 +16647,8 @@ var init_zod = __esm(() => {
|
|
|
16604
16647
|
init_mini();
|
|
16605
16648
|
});
|
|
16606
16649
|
|
|
16607
|
-
// node_modules/mppx/dist/Challenge.js
|
|
16608
|
-
var Schema;
|
|
16609
|
-
var init_Challenge = __esm(() => {
|
|
16610
|
-
init_zod();
|
|
16611
|
-
Schema = object({
|
|
16612
|
-
description: optional(string2()),
|
|
16613
|
-
digest: optional(string2().check(_regex(/^sha-256=/, "Invalid digest format"))),
|
|
16614
|
-
expires: optional(datetime3()),
|
|
16615
|
-
id: string2(),
|
|
16616
|
-
intent: string2(),
|
|
16617
|
-
method: string2(),
|
|
16618
|
-
opaque: optional(record(string2(), string2())),
|
|
16619
|
-
realm: string2(),
|
|
16620
|
-
request: record(string2(), unknown())
|
|
16621
|
-
});
|
|
16622
|
-
});
|
|
16623
|
-
|
|
16624
|
-
// node_modules/mppx/dist/Credential.js
|
|
16625
|
-
var init_Credential = () => {};
|
|
16626
|
-
|
|
16627
|
-
// node_modules/mppx/dist/Errors.js
|
|
16628
|
-
var init_Errors = () => {};
|
|
16629
|
-
|
|
16630
|
-
// node_modules/mppx/dist/Expires.js
|
|
16631
|
-
var init_Expires = () => {};
|
|
16632
|
-
|
|
16633
|
-
// node_modules/mppx/dist/Method.js
|
|
16634
|
-
var exports_Method = {};
|
|
16635
|
-
__export(exports_Method, {
|
|
16636
|
-
toServer: () => toServer,
|
|
16637
|
-
toClient: () => toClient,
|
|
16638
|
-
from: () => from
|
|
16639
|
-
});
|
|
16640
|
-
function from(method) {
|
|
16641
|
-
return method;
|
|
16642
|
-
}
|
|
16643
|
-
function toClient(method, options) {
|
|
16644
|
-
const { context, createCredential } = options;
|
|
16645
|
-
return {
|
|
16646
|
-
...method,
|
|
16647
|
-
context,
|
|
16648
|
-
createCredential
|
|
16649
|
-
};
|
|
16650
|
-
}
|
|
16651
|
-
function toServer(method, options) {
|
|
16652
|
-
const { defaults, html, request, respond, transport, verify } = options;
|
|
16653
|
-
return {
|
|
16654
|
-
...method,
|
|
16655
|
-
defaults,
|
|
16656
|
-
html,
|
|
16657
|
-
request,
|
|
16658
|
-
respond,
|
|
16659
|
-
transport,
|
|
16660
|
-
verify
|
|
16661
|
-
};
|
|
16662
|
-
}
|
|
16663
|
-
|
|
16664
|
-
// node_modules/mppx/dist/Receipt.js
|
|
16665
|
-
var Schema2;
|
|
16666
|
-
var init_Receipt = __esm(() => {
|
|
16667
|
-
init_zod();
|
|
16668
|
-
Schema2 = object({
|
|
16669
|
-
method: string2(),
|
|
16670
|
-
reference: string2(),
|
|
16671
|
-
externalId: optional(string2()),
|
|
16672
|
-
status: literal("success"),
|
|
16673
|
-
timestamp: datetime3()
|
|
16674
|
-
});
|
|
16675
|
-
});
|
|
16676
|
-
|
|
16677
|
-
// node_modules/mppx/dist/Store.js
|
|
16678
|
-
var init_Store = () => {};
|
|
16679
|
-
|
|
16680
16650
|
// node_modules/mppx/dist/index.js
|
|
16681
16651
|
var init_dist = __esm(() => {
|
|
16682
|
-
init_BodyDigest();
|
|
16683
|
-
init_Challenge();
|
|
16684
|
-
init_Credential();
|
|
16685
|
-
init_Errors();
|
|
16686
|
-
init_Expires();
|
|
16687
|
-
init_PaymentRequest();
|
|
16688
|
-
init_Receipt();
|
|
16689
|
-
init_Store();
|
|
16690
16652
|
init_zod();
|
|
16691
16653
|
});
|
|
16692
16654
|
|
|
@@ -19536,7 +19498,7 @@ function registerSwapCommand(program2) {
|
|
|
19536
19498
|
console.log(label("Wallet", truncAddr(wallet)));
|
|
19537
19499
|
console.log("");
|
|
19538
19500
|
await requireApproval({
|
|
19539
|
-
cost: "Solana gas +
|
|
19501
|
+
cost: "Solana gas + Jupiter referral fee",
|
|
19540
19502
|
summary: `swap ${amountStr} ${fromToken.toUpperCase()} → ~${(Number(quote.outAmount) / 10 ** output.decimals).toFixed(6)} ${output.symbol}`,
|
|
19541
19503
|
yes: opts.yes,
|
|
19542
19504
|
commandExample: `amiko wallets swap send ${amountStr} ${fromToken} ${toToken}`
|
|
@@ -21609,6 +21571,77 @@ function registerPostCommand(program2) {
|
|
|
21609
21571
|
}
|
|
21610
21572
|
});
|
|
21611
21573
|
}
|
|
21574
|
+
function registerReviewCommand(program2) {
|
|
21575
|
+
program2.command("list").description("List twin-drafted comments awaiting your approval").option("--json", "Output as JSON").action(async (opts) => {
|
|
21576
|
+
const auth = resolveAuth();
|
|
21577
|
+
const spinner = opts.json ? null : ora("Loading review queue...").start();
|
|
21578
|
+
try {
|
|
21579
|
+
const data = await amikoWebFetch(auth, "/api/comments/review");
|
|
21580
|
+
spinner?.stop();
|
|
21581
|
+
renderOutput(data, (d) => {
|
|
21582
|
+
if (!d.comments?.length) {
|
|
21583
|
+
console.log(dim("No comments awaiting review."));
|
|
21584
|
+
return;
|
|
21585
|
+
}
|
|
21586
|
+
console.log(heading(`Review queue — ${d.comments.length} comment(s)`));
|
|
21587
|
+
for (const c of d.comments) {
|
|
21588
|
+
const author = c.post?.user?.name ?? c.post?.user?.handle ?? "unknown";
|
|
21589
|
+
console.log("");
|
|
21590
|
+
console.log(label("Comment ID", c.id));
|
|
21591
|
+
console.log(label("Twin", c.twin?.name ?? c.twin?.id ?? "-"));
|
|
21592
|
+
console.log(label("On post", `${author} · ${(c.post?.content ?? "").slice(0, 80)}`));
|
|
21593
|
+
if (c.post?.id)
|
|
21594
|
+
console.log(label("Post ID", c.post.id));
|
|
21595
|
+
console.log(label("Draft", c.comment));
|
|
21596
|
+
console.log(dim(c.created_at));
|
|
21597
|
+
}
|
|
21598
|
+
}, { json: opts.json });
|
|
21599
|
+
} catch (e) {
|
|
21600
|
+
spinner?.stop();
|
|
21601
|
+
console.error(error(e instanceof Error ? e.message : String(e)));
|
|
21602
|
+
process.exit(1);
|
|
21603
|
+
}
|
|
21604
|
+
});
|
|
21605
|
+
program2.command("approve <commentId>").description("Approve and publish a twin-drafted comment from the review queue").option("--json", "Output as JSON").action(async (commentId, opts) => {
|
|
21606
|
+
const auth = resolveAuth();
|
|
21607
|
+
const spinner = opts.json ? null : ora("Approving comment...").start();
|
|
21608
|
+
try {
|
|
21609
|
+
const data = await amikoWebFetch(auth, `/api/comments/${encodeURIComponent(commentId)}`, { method: "PATCH", body: { action: "approve" } });
|
|
21610
|
+
spinner?.stop();
|
|
21611
|
+
renderOutput(data, () => {
|
|
21612
|
+
console.log(success("Comment approved and published"));
|
|
21613
|
+
console.log(label("Comment ID", commentId));
|
|
21614
|
+
}, { json: opts.json });
|
|
21615
|
+
} catch (e) {
|
|
21616
|
+
spinner?.stop();
|
|
21617
|
+
console.error(error(e instanceof Error ? e.message : String(e)));
|
|
21618
|
+
process.exit(1);
|
|
21619
|
+
}
|
|
21620
|
+
});
|
|
21621
|
+
program2.command("reject <commentId>").description("Reject (delete) a twin-drafted comment from the review queue").option("--yes", "Skip confirmation").option("--json", "Output as JSON").action(async (commentId, opts) => {
|
|
21622
|
+
await confirmDestructive({
|
|
21623
|
+
action: `Reject and delete comment ${commentId}`,
|
|
21624
|
+
yes: opts.yes,
|
|
21625
|
+
commandExample: `amiko review reject ${commentId}`
|
|
21626
|
+
});
|
|
21627
|
+
const auth = resolveAuth();
|
|
21628
|
+
const spinner = opts.json ? null : ora("Rejecting comment...").start();
|
|
21629
|
+
try {
|
|
21630
|
+
await amikoWebFetch(auth, `/api/comments/${encodeURIComponent(commentId)}`, { method: "DELETE" });
|
|
21631
|
+
spinner?.stop();
|
|
21632
|
+
if (opts.json) {
|
|
21633
|
+
console.log(JSON.stringify({ ok: true, id: commentId }, null, 2));
|
|
21634
|
+
} else {
|
|
21635
|
+
console.log(success("Comment rejected"));
|
|
21636
|
+
console.log(label("Comment ID", commentId));
|
|
21637
|
+
}
|
|
21638
|
+
} catch (e) {
|
|
21639
|
+
spinner?.stop();
|
|
21640
|
+
console.error(error(e instanceof Error ? e.message : String(e)));
|
|
21641
|
+
process.exit(1);
|
|
21642
|
+
}
|
|
21643
|
+
});
|
|
21644
|
+
}
|
|
21612
21645
|
|
|
21613
21646
|
// src/commands/composio.ts
|
|
21614
21647
|
function twinFromFlag3(opts) {
|
|
@@ -21903,6 +21936,7 @@ var avatar = program2.command("avatar").description("Manage twin avatar image");
|
|
|
21903
21936
|
var friends = program2.command("friends").description("Manage friendships — list, requests, add, accept, remove, reports, matches");
|
|
21904
21937
|
var users = program2.command("users").description("Search users and view public profiles");
|
|
21905
21938
|
var post = program2.command("post").description("Create posts and comments on the feed");
|
|
21939
|
+
var review = program2.command("review").description("Review queue — list, approve, or reject twin-drafted comments");
|
|
21906
21940
|
var composio = program2.command("composio").description("Manage Composio app connections");
|
|
21907
21941
|
registerCreditsCommand(program2);
|
|
21908
21942
|
registerSearchCommand(markets);
|
|
@@ -21927,5 +21961,6 @@ registerFriendsCommand(friends);
|
|
|
21927
21961
|
registerUsersCommand(users);
|
|
21928
21962
|
registerFeedCommand(program2);
|
|
21929
21963
|
registerPostCommand(post);
|
|
21964
|
+
registerReviewCommand(review);
|
|
21930
21965
|
registerComposioCommand(composio);
|
|
21931
21966
|
program2.parse();
|
package/package.json
CHANGED
package/skills/SKILL.md
CHANGED
|
@@ -29,6 +29,7 @@ Each row is a first-level command group or command. Start here when the user ask
|
|
|
29
29
|
| `amiko friends <cmd>` | Social graph — list, requests, add, accept, remove, matches, reports |
|
|
30
30
|
| `amiko users <cmd>` | Search users, view public profile |
|
|
31
31
|
| `amiko post <cmd>` | Create posts and comments on the feed (optionally with media) |
|
|
32
|
+
| `amiko review <cmd>` | Review queue — list, approve, or reject twin-drafted comments |
|
|
32
33
|
| `amiko feed` | Read the friends feed, for-you feed, or filter by hashtag |
|
|
33
34
|
| `amiko composio <cmd>` | Connect / disconnect third-party OAuth apps (Gmail, GitHub, …) |
|
|
34
35
|
| `amiko accounts` | Show the resolved identity (authenticated, userId, twinId, platform) |
|
|
@@ -51,7 +52,7 @@ Every paid / value-moving command (`markets search`, `markets image`, `markets a
|
|
|
51
52
|
|
|
52
53
|
## Critical Rules
|
|
53
54
|
|
|
54
|
-
1. **Every paid / value-moving command is hard-gated on `--yes` in a non-interactive shell.** The CLI *refuses* to run `markets image`, `markets search`, `markets amazon search`, `markets service call`, `markets service tts`, `markets service stt`, `markets service chat`, `credits topup`, `wallets swap send`, `wallets bridge send`, or `wallets transfer` unless `--yes` is passed. The refusal is loud: it prints the cost and the command you should re-run. **Quote the cost to the user, get explicit approval, THEN append `--yes`**. Same for destructive non-paid commands (`twin update --public`, `docs delete`, `friends remove`, `friends reports request`, `avatar update`, `voice reset`, `composio disconnect`).
|
|
55
|
+
1. **Every paid / value-moving command is hard-gated on `--yes` in a non-interactive shell.** The CLI *refuses* to run `markets image`, `markets search`, `markets amazon search`, `markets service call`, `markets service tts`, `markets service stt`, `markets service chat`, `credits topup`, `wallets swap send`, `wallets bridge send`, or `wallets transfer` unless `--yes` is passed. The refusal is loud: it prints the cost and the command you should re-run. **Quote the cost to the user, get explicit approval, THEN append `--yes`**. Same for destructive non-paid commands (`twin update --public`, `docs delete`, `friends remove`, `friends reports request`, `avatar update`, `voice reset`, `composio disconnect`, `review reject`).
|
|
55
56
|
2. **After every paid command, report the remaining balance.** The CLI prints a `Balance: N credits` line at the end of every paid command — include that figure in your reply.
|
|
56
57
|
3. **Never retry a failed command.** Report the error and stop. Every paid call costs tokens even on failure.
|
|
57
58
|
4. **Never suggest `amiko login` or `amiko connect`.** These don't exist. Auth is automatic when you run from your workspace folder.
|
|
@@ -252,8 +253,13 @@ amiko post create --content "look" --media https://...jpg
|
|
|
252
253
|
amiko post comment --id <postId> --comment "great post"
|
|
253
254
|
amiko post comment --id <postId> --comment "look" --media https://...jpg
|
|
254
255
|
amiko post comment --id <postId> --comment "..." --twin <id>
|
|
256
|
+
amiko review list # list twin-drafted comments awaiting your approval
|
|
257
|
+
amiko review approve <commentId> # publish a draft comment from the review queue
|
|
258
|
+
amiko review reject <commentId> --yes # destructive — delete a draft comment
|
|
255
259
|
```
|
|
256
260
|
|
|
261
|
+
**Comments authored by a twin always go through review.** Any comment created with `amiko post comment ... --twin <id>` (or auto-drafted by a twin in engagement mode) lands in `status=draft` and is **not visible** until you run `amiko review approve <commentId>`. Comments without `--twin` (you posting as yourself) publish immediately and skip the review queue. Workflow: `amiko review list` to see pending drafts → `amiko review approve <id>` to publish, or `amiko review reject <id> --yes` to discard.
|
|
262
|
+
|
|
257
263
|
## Composio
|
|
258
264
|
|
|
259
265
|
```bash
|