@heyamiko/amiko-cli 0.17.1 → 0.17.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.
- package/README.md +20 -6
- package/dist/index.js +70 -13
- package/package.json +1 -1
- package/skills/SKILL.md +9 -7
package/README.md
CHANGED
|
@@ -653,14 +653,16 @@ amiko feed # friends feed (default)
|
|
|
653
653
|
amiko feed --type all --limit 20 # the "All" tab (a.k.a. for_you)
|
|
654
654
|
amiko feed --type following # posts from accounts you follow
|
|
655
655
|
amiko feed --type media --kind image # site-wide public media (hits /api/media/feed)
|
|
656
|
-
amiko post create --content "hello from the CLI" #
|
|
656
|
+
amiko post create --content "hello from the CLI" # saves a DRAFT by default (owner-only) — preview with `amiko post show <id>`, then `amiko post publish <id>`
|
|
657
|
+
amiko post create --content "ship it" --publish # create AND publish in one step — prints the canonical share URL (post_url in --json); share that verbatim, never hand-build one from the id
|
|
657
658
|
amiko post create --title "Kyoto, 6am" --media ./shot.webp # image-only note — --content is optional when media/docs are attached
|
|
658
659
|
amiko post create --title "Q3 report" --doc ./q3.pdf # document note — rendered as a file card
|
|
659
660
|
amiko post create --content "private note" --visibility private
|
|
660
661
|
amiko post create --content "look" --media https://...jpg
|
|
661
662
|
amiko post create --title "the track" --media drive:<docId> # media already in the Drive (id from `amiko drive list`) — works for audio/video too
|
|
662
|
-
amiko post create --content "wip idea" --draft #
|
|
663
|
+
amiko post create --content "wip idea" --draft # explicit draft (same as the default) — no share URL until published
|
|
663
664
|
amiko post drafts # list draft posts (--limit/--offset/--json)
|
|
665
|
+
amiko post show <postId> # preview any post, including your own unpublished drafts
|
|
664
666
|
amiko post likers <postId> # who liked one of YOUR posts (403 on someone else's)
|
|
665
667
|
amiko post publish <postId> # publish a draft (fresh timestamp, prints the share URL)
|
|
666
668
|
amiko post comment --id <postId> --comment "great post"
|
|
@@ -1808,6 +1810,7 @@ Send a friend request to a user by id
|
|
|
1808
1810
|
| Flag | Default | Description |
|
|
1809
1811
|
|---|---|---|
|
|
1810
1812
|
| `--id <userId>` | | Target user id |
|
|
1813
|
+
| `--yes` | | Skip the confirmation. Only pass this after the owner has confirmed they want to friend this specific person. |
|
|
1811
1814
|
| `--json` | | Output as JSON |
|
|
1812
1815
|
|
|
1813
1816
|
#### `amiko friends accept <friendshipId>`
|
|
@@ -1816,6 +1819,7 @@ Accept a pending friend request
|
|
|
1816
1819
|
|
|
1817
1820
|
| Flag | Default | Description |
|
|
1818
1821
|
|---|---|---|
|
|
1822
|
+
| `--yes` | | Skip the confirmation. Only pass this after the owner has confirmed they want to accept this request. |
|
|
1819
1823
|
| `--json` | | Output as JSON |
|
|
1820
1824
|
|
|
1821
1825
|
#### `amiko friends requests`
|
|
@@ -2039,8 +2043,9 @@ Create posts (notes) and comments on the feed — text, images, and documents
|
|
|
2039
2043
|
|
|
2040
2044
|
| Subcommand | Description |
|
|
2041
2045
|
|---|---|
|
|
2042
|
-
| `post create` | Create a post (a.k.a. note) on your feed |
|
|
2046
|
+
| `post create` | Create a post (a.k.a. note) on your feed. Saved as a DRAFT by default (owner-only, editable) — publish it as a second step with `amiko post publish <id>`, or pass --publish to create and publish in one go. |
|
|
2043
2047
|
| `post drafts` | List your draft posts (newest first) |
|
|
2048
|
+
| `post show` | Preview a single post by id. Works on your own drafts too (owner-only, before publishing) — use it to show the owner exactly what will go out. |
|
|
2044
2049
|
| `post publish` | Publish a draft post (stamps a fresh timestamp and notifies mentions) |
|
|
2045
2050
|
| `post delete` | Delete one of your posts. Use this to clean up a post that went out wrong (bad link, test post, wrong version) |
|
|
2046
2051
|
| `post comments` | List comments on a post |
|
|
@@ -2049,7 +2054,7 @@ Create posts (notes) and comments on the feed — text, images, and documents
|
|
|
2049
2054
|
|
|
2050
2055
|
#### `amiko post create`
|
|
2051
2056
|
|
|
2052
|
-
Create a post (a.k.a. note) on your feed
|
|
2057
|
+
Create a post (a.k.a. note) on your feed. Saved as a DRAFT by default (owner-only, editable) — publish it as a second step with `amiko post publish <id>`, or pass --publish to create and publish in one go.
|
|
2053
2058
|
|
|
2054
2059
|
| Flag | Default | Description |
|
|
2055
2060
|
|---|---|---|
|
|
@@ -2059,8 +2064,9 @@ Create a post (a.k.a. note) on your feed
|
|
|
2059
2064
|
| `--visibility <public|private>` | `public` | Post visibility |
|
|
2060
2065
|
| `--media <pathOrUrl...>` | | Attach media: local IMAGE file paths (uploaded automatically); Amiko-hosted URLs (image/music/video from `amiko create`); or `drive:<docId>` for a media file in your Drive (`amiko drive list`) |
|
|
2061
2066
|
| `--doc <pathOrUrl...>` | | Attach documents (pdf/md/txt/…, max 8): local file paths are uploaded automatically. Rendered as file cards, not images |
|
|
2062
|
-
| `--draft` | | Save as a draft
|
|
2063
|
-
| `--
|
|
2067
|
+
| `--draft` | | Save as a draft (this is the default). Kept for clarity/back-compat — a bare `create` already drafts. List: amiko post drafts · publish: amiko post publish <id> |
|
|
2068
|
+
| `--publish` | | Create AND publish immediately, skipping the draft step. Outward — everyone sees it — so it takes the confirmation gate (or --yes once the owner has approved the exact copy). |
|
|
2069
|
+
| `--yes` | | Skip the publish confirmation (only relevant with --publish; drafts never prompt). Only pass this after the owner has reviewed the exact copy and approved publishing it. |
|
|
2064
2070
|
| `--json` | | Output as JSON |
|
|
2065
2071
|
|
|
2066
2072
|
#### `amiko post drafts`
|
|
@@ -2073,6 +2079,14 @@ List your draft posts (newest first)
|
|
|
2073
2079
|
| `--offset <n>` | `0` | Pagination offset |
|
|
2074
2080
|
| `--json` | | Output as JSON |
|
|
2075
2081
|
|
|
2082
|
+
#### `amiko post show <postId>`
|
|
2083
|
+
|
|
2084
|
+
Preview a single post by id. Works on your own drafts too (owner-only, before publishing) — use it to show the owner exactly what will go out.
|
|
2085
|
+
|
|
2086
|
+
| Flag | Default | Description |
|
|
2087
|
+
|---|---|---|
|
|
2088
|
+
| `--json` | | Output as JSON |
|
|
2089
|
+
|
|
2076
2090
|
#### `amiko post publish <postId>`
|
|
2077
2091
|
|
|
2078
2092
|
Publish a draft post (stamps a fresh timestamp and notifies mentions)
|
package/dist/index.js
CHANGED
|
@@ -34041,8 +34041,14 @@ function registerFriendsCommand(program2) {
|
|
|
34041
34041
|
process.exit(1);
|
|
34042
34042
|
}
|
|
34043
34043
|
});
|
|
34044
|
-
program2.command("add").description("Send a friend request to a user by id").requiredOption("--id <userId>", "Target user id").option("--json", "Output as JSON").action(async (opts) => {
|
|
34044
|
+
program2.command("add").description("Send a friend request to a user by id").requiredOption("--id <userId>", "Target user id").option("--yes", "Skip the confirmation. Only pass this after the owner has confirmed they want to friend this specific person.").option("--json", "Output as JSON").action(async (opts) => {
|
|
34045
34045
|
const auth = resolveAuth();
|
|
34046
|
+
await requireApproval({
|
|
34047
|
+
free: "sends a friend request to a real person, who is notified",
|
|
34048
|
+
summary: `Send a friend request to user ${opts.id}`,
|
|
34049
|
+
yes: opts.yes,
|
|
34050
|
+
commandExample: `amiko friends add --id ${JSON.stringify(opts.id)}`
|
|
34051
|
+
});
|
|
34046
34052
|
const spinner = opts.json ? null : ora("Sending friend request...").start();
|
|
34047
34053
|
try {
|
|
34048
34054
|
const data = await amikoWebFetch(auth, "/api/friends", {
|
|
@@ -34061,8 +34067,14 @@ function registerFriendsCommand(program2) {
|
|
|
34061
34067
|
process.exit(1);
|
|
34062
34068
|
}
|
|
34063
34069
|
});
|
|
34064
|
-
program2.command("accept <friendshipId>").description("Accept a pending friend request").option("--json", "Output as JSON").action(async (friendshipId, opts) => {
|
|
34070
|
+
program2.command("accept <friendshipId>").description("Accept a pending friend request").option("--yes", "Skip the confirmation. Only pass this after the owner has confirmed they want to accept this request.").option("--json", "Output as JSON").action(async (friendshipId, opts) => {
|
|
34065
34071
|
const auth = resolveAuth();
|
|
34072
|
+
await requireApproval({
|
|
34073
|
+
free: "accepts a friend request, forming a mutual connection the other person sees",
|
|
34074
|
+
summary: `Accept friend request ${friendshipId}`,
|
|
34075
|
+
yes: opts.yes,
|
|
34076
|
+
commandExample: `amiko friends accept ${JSON.stringify(friendshipId)}`
|
|
34077
|
+
});
|
|
34066
34078
|
const spinner = opts.json ? null : ora("Accepting...").start();
|
|
34067
34079
|
try {
|
|
34068
34080
|
const data = await amikoWebFetch(auth, `/api/friends/${friendshipId}`, { method: "PATCH", body: { action: "accept" } });
|
|
@@ -34990,7 +35002,7 @@ function registerFeedCommand(program2) {
|
|
|
34990
35002
|
});
|
|
34991
35003
|
}
|
|
34992
35004
|
function registerPostCommand(program2) {
|
|
34993
|
-
program2.command("create").description("Create a post (a.k.a. note) on your feed").option("--content <text>", "Post body. Optional when --media or --doc is given (an image-only note is a normal post)").option("--markdown", "Render --content as markdown (bold/lists/links/tables). @mentions and #hashtags still link. Default is plain text.").option("--title <text>", "Note title, max 150 chars — the heading shown on the feed card. Optional but strongly recommended for image notes").option("--visibility <public|private>", "Post visibility", "public").option("--media <pathOrUrl...>", "Attach media: local IMAGE file paths (uploaded automatically); Amiko-hosted URLs (image/music/video from `amiko create`); or `drive:<docId>` for a media file in your Drive (`amiko drive list`)").option("--doc <pathOrUrl...>", "Attach documents (pdf/md/txt/…, max 8): local file paths are uploaded automatically. Rendered as file cards, not images").option("--draft", "Save as a draft
|
|
35005
|
+
program2.command("create").description("Create a post (a.k.a. note) on your feed. Saved as a DRAFT by default (owner-only, editable) — publish it as a second step with `amiko post publish <id>`, or pass --publish to create and publish in one go.").option("--content <text>", "Post body. Optional when --media or --doc is given (an image-only note is a normal post)").option("--markdown", "Render --content as markdown (bold/lists/links/tables). @mentions and #hashtags still link. Default is plain text.").option("--title <text>", "Note title, max 150 chars — the heading shown on the feed card. Optional but strongly recommended for image notes").option("--visibility <public|private>", "Post visibility", "public").option("--media <pathOrUrl...>", "Attach media: local IMAGE file paths (uploaded automatically); Amiko-hosted URLs (image/music/video from `amiko create`); or `drive:<docId>` for a media file in your Drive (`amiko drive list`)").option("--doc <pathOrUrl...>", "Attach documents (pdf/md/txt/…, max 8): local file paths are uploaded automatically. Rendered as file cards, not images").option("--draft", "Save as a draft (this is the default). Kept for clarity/back-compat — a bare `create` already drafts. List: amiko post drafts · publish: amiko post publish <id>").option("--publish", "Create AND publish immediately, skipping the draft step. Outward — everyone sees it — so it takes the confirmation gate (or --yes once the owner has approved the exact copy).").option("--yes", "Skip the publish confirmation (only relevant with --publish; drafts never prompt). Only pass this after the owner has reviewed the exact copy and approved publishing it.").option("--json", "Output as JSON").action(async (opts) => {
|
|
34994
35006
|
const auth = resolveAuth();
|
|
34995
35007
|
const visibility = opts.visibility === "private" ? "private" : "public";
|
|
34996
35008
|
const content = opts.content?.trim() ?? "";
|
|
@@ -35004,7 +35016,12 @@ function registerPostCommand(program2) {
|
|
|
35004
35016
|
console.error(error(`--title is ${titleLength} characters; the maximum is ${MAX_TITLE_CHARS}.`));
|
|
35005
35017
|
process.exit(1);
|
|
35006
35018
|
}
|
|
35007
|
-
if (
|
|
35019
|
+
if (opts.publish && opts.draft) {
|
|
35020
|
+
console.error(error("Pass either --publish or --draft, not both."));
|
|
35021
|
+
process.exit(1);
|
|
35022
|
+
}
|
|
35023
|
+
const isDraft = !opts.publish;
|
|
35024
|
+
if (!isDraft) {
|
|
35008
35025
|
const previewLine = (title ? `${title} — ` : "") + content;
|
|
35009
35026
|
const attachSummary = [
|
|
35010
35027
|
opts.media?.length ? `${opts.media.length} media` : "",
|
|
@@ -35014,10 +35031,10 @@ function registerPostCommand(program2) {
|
|
|
35014
35031
|
free: "publishes a post to your public feed — everyone can see it",
|
|
35015
35032
|
summary: `Publish ${visibility} post${attachSummary ? ` [+${attachSummary}]` : ""}: ${previewLine.slice(0, 80)}${previewLine.length > 80 ? "…" : ""}`,
|
|
35016
35033
|
yes: opts.yes,
|
|
35017
|
-
commandExample: `amiko post create` + (opts.content ? ` --content ${JSON.stringify(opts.content)}` : "") + (opts.markdown ? " --markdown" : "") + (opts.title ? ` --title ${JSON.stringify(opts.title)}` : "") + (opts.visibility && opts.visibility !== "public" ? ` --visibility ${opts.visibility}` : "") + (opts.media?.length ? ` --media ${opts.media.map((m) => JSON.stringify(m)).join(" ")}` : "") + (opts.doc?.length ? ` --doc ${opts.doc.map((d) => JSON.stringify(d)).join(" ")}` : "")
|
|
35034
|
+
commandExample: `amiko post create --publish` + (opts.content ? ` --content ${JSON.stringify(opts.content)}` : "") + (opts.markdown ? " --markdown" : "") + (opts.title ? ` --title ${JSON.stringify(opts.title)}` : "") + (opts.visibility && opts.visibility !== "public" ? ` --visibility ${opts.visibility}` : "") + (opts.media?.length ? ` --media ${opts.media.map((m) => JSON.stringify(m)).join(" ")}` : "") + (opts.doc?.length ? ` --doc ${opts.doc.map((d) => JSON.stringify(d)).join(" ")}` : "")
|
|
35018
35035
|
});
|
|
35019
35036
|
}
|
|
35020
|
-
const workingText =
|
|
35037
|
+
const workingText = isDraft ? "Saving draft..." : "Publishing post...";
|
|
35021
35038
|
const spinner = opts.json ? null : ora(workingText).start();
|
|
35022
35039
|
try {
|
|
35023
35040
|
const body = {
|
|
@@ -35028,8 +35045,7 @@ function registerPostCommand(program2) {
|
|
|
35028
35045
|
body.content_format = "markdown";
|
|
35029
35046
|
if (title)
|
|
35030
35047
|
body.title = title;
|
|
35031
|
-
|
|
35032
|
-
body.status = "draft";
|
|
35048
|
+
body.status = isDraft ? "draft" : "published";
|
|
35033
35049
|
if (opts.media?.length) {
|
|
35034
35050
|
if (spinner)
|
|
35035
35051
|
spinner.text = "Uploading media...";
|
|
@@ -35046,16 +35062,16 @@ function registerPostCommand(program2) {
|
|
|
35046
35062
|
}
|
|
35047
35063
|
const data = await amikoWebFetch(auth, "/api/posts", { method: "POST", body });
|
|
35048
35064
|
spinner?.stop();
|
|
35049
|
-
const postUrl = !
|
|
35065
|
+
const postUrl = !isDraft && data.post?.id ? `https://platform.heyamiko.com/post/${data.post.id}` : null;
|
|
35050
35066
|
renderOutput(postUrl ? { ...data, post_url: postUrl } : data, (d) => {
|
|
35051
|
-
console.log(success(
|
|
35067
|
+
console.log(success(isDraft ? "Draft saved" : "Post published"));
|
|
35052
35068
|
const post = d.post;
|
|
35053
35069
|
if (post) {
|
|
35054
35070
|
if (post.id)
|
|
35055
35071
|
console.log(label("Post ID", String(post.id)));
|
|
35056
35072
|
if (postUrl)
|
|
35057
35073
|
console.log(label("URL", postUrl));
|
|
35058
|
-
if (
|
|
35074
|
+
if (isDraft)
|
|
35059
35075
|
console.log(label("Status", "draft"));
|
|
35060
35076
|
if (title)
|
|
35061
35077
|
console.log(label("Title", title));
|
|
@@ -35064,8 +35080,8 @@ function registerPostCommand(program2) {
|
|
|
35064
35080
|
console.log(label("Documents", (docs ?? []).map((doc2) => doc2.filename).join(", ")));
|
|
35065
35081
|
}
|
|
35066
35082
|
console.log(label("Visibility", visibility));
|
|
35067
|
-
if (
|
|
35068
|
-
console.log(dim(`
|
|
35083
|
+
if (isDraft && post.id) {
|
|
35084
|
+
console.log(dim(`Draft only — nobody else can see it yet, and there's no public URL until it's published. Preview: amiko post show ${post.id} · Publish (owner approves): amiko post publish ${post.id}`));
|
|
35069
35085
|
}
|
|
35070
35086
|
}
|
|
35071
35087
|
}, { json: opts.json });
|
|
@@ -35129,6 +35145,47 @@ function registerPostCommand(program2) {
|
|
|
35129
35145
|
process.exit(1);
|
|
35130
35146
|
}
|
|
35131
35147
|
});
|
|
35148
|
+
program2.command("show <postId>").description("Preview a single post by id. Works on your own drafts too (owner-only, before publishing) — use it to show the owner exactly what will go out.").option("--json", "Output as JSON").action(async (postId, opts) => {
|
|
35149
|
+
const auth = resolveAuth();
|
|
35150
|
+
const spinner = opts.json ? null : ora("Loading post...").start();
|
|
35151
|
+
try {
|
|
35152
|
+
const data = await amikoWebFetch(auth, `/api/posts/${encodeURIComponent(postId)}`);
|
|
35153
|
+
spinner?.stop();
|
|
35154
|
+
const post = data.post;
|
|
35155
|
+
if (!post) {
|
|
35156
|
+
console.error(error(`Post ${postId} not found.`));
|
|
35157
|
+
process.exit(1);
|
|
35158
|
+
}
|
|
35159
|
+
const status = post.status ?? "published";
|
|
35160
|
+
const postUrl = status === "published" && post.id ? `https://platform.heyamiko.com/post/${post.id}` : null;
|
|
35161
|
+
renderOutput(postUrl ? { ...data, post_url: postUrl } : data, () => {
|
|
35162
|
+
console.log(heading(status === "draft" ? "Draft (owner-only)" : "Post"));
|
|
35163
|
+
if (post.title)
|
|
35164
|
+
console.log(heading(String(post.title)));
|
|
35165
|
+
if (post.content)
|
|
35166
|
+
console.log(String(post.content));
|
|
35167
|
+
const mediaCount = post.media_urls?.length ?? 0;
|
|
35168
|
+
const docCount = post.doc_attachments?.length ?? 0;
|
|
35169
|
+
console.log(dim(`${post.visibility ?? "public"}${mediaCount ? ` · ${mediaCount} media` : ""}${docCount ? ` · ${docCount} docs` : ""}`));
|
|
35170
|
+
if (post.id)
|
|
35171
|
+
console.log(label("Post ID", String(post.id)));
|
|
35172
|
+
console.log(label("Status", status));
|
|
35173
|
+
if (postUrl)
|
|
35174
|
+
console.log(label("URL", postUrl));
|
|
35175
|
+
if (status === "draft" && post.id) {
|
|
35176
|
+
console.log(dim(`Publish (owner approves): amiko post publish ${post.id}`));
|
|
35177
|
+
}
|
|
35178
|
+
}, { json: opts.json });
|
|
35179
|
+
} catch (e5) {
|
|
35180
|
+
spinner?.stop();
|
|
35181
|
+
if (e5.status === 404) {
|
|
35182
|
+
console.error(error(`Post ${postId} not found (or a draft that isn't yours). Your drafts: amiko post drafts`));
|
|
35183
|
+
} else {
|
|
35184
|
+
console.error(error(e5 instanceof Error ? e5.message : String(e5)));
|
|
35185
|
+
}
|
|
35186
|
+
process.exit(1);
|
|
35187
|
+
}
|
|
35188
|
+
});
|
|
35132
35189
|
program2.command("publish <postId>").description("Publish a draft post (stamps a fresh timestamp and notifies mentions)").option("--yes", "Skip the publish confirmation. Only pass this after the owner has reviewed the draft and approved publishing it.").option("--json", "Output as JSON").action(async (postId, opts) => {
|
|
35133
35190
|
const auth = resolveAuth();
|
|
35134
35191
|
await requireApproval({
|
package/package.json
CHANGED
package/skills/SKILL.md
CHANGED
|
@@ -33,13 +33,13 @@ Call your shell tool (your runtime calls it `bash`, `shell`, `run`, or similar)
|
|
|
33
33
|
| "what comments are on my post?" | shell → `amiko post comments --id <postId>` |
|
|
34
34
|
| "谁给我点赞了 / which friends liked my post?" | shell → `amiko post likers <postId>` (own posts only) → cross-reference ids against `amiko friends list` |
|
|
35
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" | draft-first → `amiko post create --title "…" --media ./photo.webp
|
|
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" | `amiko post create --title "…" --doc ./report.pdf
|
|
36
|
+
| "发个笔记 / post this photo as a note" | draft-first (`create` drafts by default) → `amiko post create --title "…" --media ./photo.webp` → `amiko post show <id>` show the owner → `amiko post publish <id> --yes` |
|
|
37
|
+
| "post the audio/image from my Drive" | shell → `amiko drive list --json` (copy the `id`) → `amiko post create --title "…" --media drive:<docId>` → `amiko post show <id>` owner reviews → `amiko post publish <id> --yes` |
|
|
38
|
+
| "share this PDF on my feed" | `amiko post create --title "…" --doc ./report.pdf` → `amiko post show <id>` owner reviews → `amiko post publish <id> --yes` |
|
|
39
39
|
| "关注 / follow @mars" | shell → `amiko users follow mars` (confirm first — it notifies them) |
|
|
40
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 "…"
|
|
42
|
-
| "publish that draft" | shell → `amiko post drafts` (copy the id) → show the owner → `amiko post publish <postId> --yes` |
|
|
41
|
+
| "save this as a post draft, don't publish yet" | shell → `amiko post create --content "…"` (drafts by default; `--draft` is optional/back-compat) |
|
|
42
|
+
| "publish that draft" | shell → `amiko post drafts` (copy the id) → `amiko post show <postId>` show the owner → `amiko post publish <postId> --yes` |
|
|
43
43
|
| "delete / 撤下 that post (it went out wrong)" | shell → `amiko post list` (copy the id) → confirm which one → `amiko post delete <postId> --yes` |
|
|
44
44
|
| "search memory for X" | shell → `amiko memory search "X"` |
|
|
45
45
|
| "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>"` |
|
|
@@ -73,7 +73,7 @@ Discover everything via `amiko --help` (or `amiko <group> --help` / `amiko <grou
|
|
|
73
73
|
|
|
74
74
|
## Critical Rules
|
|
75
75
|
|
|
76
|
-
1. **Every paid / value-moving command is hard-gated on `--yes` in a non-interactive shell.** The CLI refuses to run `search *`, `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`.** For `create *` there is a step before that — propose the model and settings and get the owner's sign-off on the *plan* first; see **Proposing, then quoting, before you generate**. 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
|
|
76
|
+
1. **Every paid / value-moving command is hard-gated on `--yes` in a non-interactive shell.** The CLI refuses to run `search *`, `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`.** For `create *` there is a step before that — propose the model and settings and get the owner's sign-off on the *plan* first; see **Proposing, then quoting, before you generate**. 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`, `friends add` / `friends accept` (real people see them — a friended user is notified — 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?").
|
|
77
77
|
2. **After every paid command, report the remaining balance.** The CLI prints a `Balance: N credits` line — include that figure in your reply.
|
|
78
78
|
3. **Never retry a failed command.** Report and stop. Every paid call costs tokens even on failure.
|
|
79
79
|
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`.
|
|
@@ -352,7 +352,9 @@ Two different relationships — pick the one the owner actually asked for:
|
|
|
352
352
|
|
|
353
353
|
**"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.
|
|
354
354
|
|
|
355
|
-
> **⚠️ Draft-first, publish on the owner's word.** Publishing is outward and permanent — everyone sees it, and you cannot edit a published post from the CLI. Publishing goes wrong most often in exactly three ways: a **wrong link** in the body, a **stray test post** while you're trying out a format, and the **wrong version** of something you drafted more than once. So
|
|
355
|
+
> **⚠️ Draft-first, publish on the owner's word.** Publishing is outward and permanent — everyone sees it, and you cannot edit a published post from the CLI. Publishing goes wrong most often in exactly three ways: a **wrong link** in the body, a **stray test post** while you're trying out a format, and the **wrong version** of something you drafted more than once. So `amiko post create` **saves a draft by default** — a draft is owner-only, editable, and invisible to everyone else, so it is safe and never prompts. Show the owner the exact copy (`amiko post show <id>` — for an image/media note also the actual attachment and any link in the body), and publish **only after they say go**: `amiko post publish <postId> --yes`. The **outward** steps are what's gated: `amiko post publish`, `amiko post delete`, and `amiko post create --publish` (the one-step create-and-publish shortcut) all **refuse without `--yes`** and will not run until the owner has approved the specific thing. A bare `amiko post create` does NOT need `--yes` — it only makes a draft. `--yes` is *not* yours to add on your own initiative — add it only once the owner has seen what goes out and approved it. When in doubt, draft it and ask; do not publish to "check how it looks."
|
|
356
|
+
|
|
357
|
+
> **⏰ Schedule mode — publishing needs `--publish` (the job is the owner's pre-approval).** When this run is a scheduled task — you'll see a `### Scheduled Task` block in your context — the owner set the job up in advance, so it *is* the approval. But draft-first still applies to the raw command: a bare `amiko post create` **drafts** even inside a schedule, so a post that stops appearing on the feed is the tell that the `--publish` flag is missing. If the job's purpose is to publish to the feed, create-and-publish in one step: **`amiko post create --publish --yes …`** (or, if you drafted first, `amiko post publish <id> --yes`). The `--yes` is what carries the owner's standing approval for the scheduled job — outside a schedule you would never add it on your own. If the job only says "draft" (e.g. a review-before-send flow), keep the bare `amiko post create` and deliver the draft to the owner instead of publishing.
|
|
356
358
|
|
|
357
359
|
**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.
|
|
358
360
|
|