@cmo-so/cli 0.9.1 → 0.9.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/dist/cmo.mjs +85 -3
- package/package.json +1 -1
package/dist/cmo.mjs
CHANGED
|
@@ -7724,8 +7724,14 @@ function domainApi(api2, domain) {
|
|
|
7724
7724
|
/** How a posted Instagram post is doing (read from Instagram, kept 15 minutes; `refresh` reads again). */
|
|
7725
7725
|
socialInsights: (id, refresh = false) => api2.request(`${base}/social/${id}/insights${refresh ? "?refresh=true" : ""}`),
|
|
7726
7726
|
deletePostedSocial: (id) => api2.request(`${base}/social/${id}/published`, { method: "DELETE" }),
|
|
7727
|
-
/**
|
|
7728
|
-
|
|
7727
|
+
/**
|
|
7728
|
+
* Change a posted post. LinkedIn changes its text in place (likes and comments stay); with `repost`, and on
|
|
7729
|
+
* the other channels, the old one comes down and the new text goes out now.
|
|
7730
|
+
*/
|
|
7731
|
+
republishSocial: (id, socialCopy, repost = false) => post(`${base}/social/${id}/republish`, {
|
|
7732
|
+
...socialCopy ? { social_copy: socialCopy } : {},
|
|
7733
|
+
...repost ? { repost: true } : {}
|
|
7734
|
+
}),
|
|
7729
7735
|
restoreSocial: (id) => post(`${base}/social/${id}/restore`),
|
|
7730
7736
|
pauseSocial: () => post(`${base}/social/pause`),
|
|
7731
7737
|
/**
|
|
@@ -8725,6 +8731,18 @@ var confirmCopy = {
|
|
|
8725
8731
|
return n.length > 1 ? `\u6279\u51C6 ${n.length} \u7BC7\u8CBC\u6587\uFF1A${n.map((i) => `#${i}`).join("\u3001")}\u3002\u6BCF\u7BC7\u5728\u63A5\u4E0B\u4F86\u7684\u767C\u6587\u6642\u9593\u767C\u51FA\uFF0C\u4F60\u7684\u4EBA\u8108\u90FD\u770B\u5F97\u5230\u3002` : `\u6279\u51C6\u8CBC\u6587 #${n[0]}\u3002\u5B83\u6703\u5728\u4E0B\u4E00\u500B\u767C\u6587\u6642\u9593\u767C\u51FA\uFF0C\u4F60\u7684\u4EBA\u8108\u90FD\u770B\u5F97\u5230\u3002`;
|
|
8726
8732
|
}
|
|
8727
8733
|
},
|
|
8734
|
+
social_publish_now: {
|
|
8735
|
+
en: (a) => `Post #${a.id} on its channel now, not at its posting time (even while posting is paused). Everyone who follows you can see it.`,
|
|
8736
|
+
"zh-Hant": (a) => `\u7ACB\u5373\u5728\u5B83\u7684\u983B\u9053\u767C\u51FA\u8CBC\u6587 #${a.id}\uFF0C\u4E0D\u7B49\u767C\u6587\u6642\u9593\uFF08\u66AB\u505C\u767C\u6587\u6642\u4E5F\u6703\u767C\uFF09\u3002\u767C\u51FA\u5F8C\u95DC\u6CE8\u4F60\u7684\u4EBA\u90FD\u770B\u5F97\u5230\u3002`
|
|
8737
|
+
},
|
|
8738
|
+
social_posted_update: {
|
|
8739
|
+
en: (a) => a.repost ? `Take post #${a.id} down (its likes and comments go) and put it up again${a.social_copy ? ` as ${q(a.social_copy)}` : ""}.` : `Change the text of the posted post #${a.id} to ${q(a.social_copy)}. On LinkedIn it stays up with its likes and comments; on other channels it comes down and goes out again.`,
|
|
8740
|
+
"zh-Hant": (a) => a.repost ? `\u64A4\u4E0B\u8CBC\u6587 #${a.id}\uFF08\u8B9A\u548C\u7559\u8A00\u6703\u6D88\u5931\uFF09\uFF0C\u518D\u91CD\u65B0\u767C\u51FA${a.social_copy ? `\uFF0C\u5167\u5BB9\u6539\u70BA ${q(a.social_copy)}` : ""}\u3002` : `\u628A\u5DF2\u767C\u51FA\u7684\u8CBC\u6587 #${a.id} \u6539\u70BA ${q(a.social_copy)}\u3002LinkedIn \u4E0A\u539F\u5730\u4FEE\u6539\uFF0C\u8B9A\u548C\u7559\u8A00\u4FDD\u7559\uFF1B\u5176\u4ED6\u983B\u9053\u6703\u64A4\u4E0B\u5F8C\u91CD\u767C\u3002`
|
|
8741
|
+
},
|
|
8742
|
+
social_posted_delete: {
|
|
8743
|
+
en: (a) => `Take post #${a.id} down from its channel, with its likes and comments. This can't be undone.`,
|
|
8744
|
+
"zh-Hant": (a) => `\u628A\u8CBC\u6587 #${a.id} \u5F9E\u5B83\u7684\u983B\u9053\u64A4\u4E0B\uFF0C\u8B9A\u548C\u7559\u8A00\u4E00\u8D77\u522A\u9664\uFF0C\u7121\u6CD5\u5FA9\u539F\u3002`
|
|
8745
|
+
},
|
|
8728
8746
|
social_skip: { en: (a) => `Skip post #${a.id}.`, "zh-Hant": (a) => `\u8DF3\u904E\u8CBC\u6587 #${a.id}\u3002` },
|
|
8729
8747
|
social_restore: {
|
|
8730
8748
|
en: (a) => `Bring back post #${a.id}.`,
|
|
@@ -11687,6 +11705,59 @@ var socialTools = [
|
|
|
11687
11705
|
return { approved: results.filter((r) => r.ok).length, results };
|
|
11688
11706
|
}
|
|
11689
11707
|
}),
|
|
11708
|
+
tool({
|
|
11709
|
+
name: "social_publish_now",
|
|
11710
|
+
description: "Post one social post on its channel now instead of at its posting time: a draft waiting for approval, a queued post, or one that didn't go out. It goes even while posting is paused. It goes out in the background: the answer says it is publishing; read social_post_get after a minute for its link (or why it couldn't go). Not while its picture is being made.",
|
|
11711
|
+
parameters: { type: "object", properties: { id: { type: "integer" } }, required: ["id"] },
|
|
11712
|
+
group: "social",
|
|
11713
|
+
need: write5,
|
|
11714
|
+
risk: "W3",
|
|
11715
|
+
gates: ["VER"],
|
|
11716
|
+
run: async (ctx, { id }) => {
|
|
11717
|
+
const n = Number(id);
|
|
11718
|
+
if (!Number.isInteger(n) || n <= 0) throw new Error("Which post?");
|
|
11719
|
+
const post = await ws(ctx).publishSocialNow(n, { background: true });
|
|
11720
|
+
return post.status === "published" ? post : { ...post, note: "Posting now. Check social_post_get in a minute for its link." };
|
|
11721
|
+
}
|
|
11722
|
+
}),
|
|
11723
|
+
tool({
|
|
11724
|
+
name: "social_posted_update",
|
|
11725
|
+
description: "Change a social post that has already gone out. On LinkedIn the new text replaces the old in place: the post keeps its likes and comments (its pictures can't change this way). With repost, and on Facebook, Instagram and Google, the old post comes down with its likes and comments and the new version goes out now. Without social_copy and with repost, it goes out again as it is (e.g. after new pictures).",
|
|
11726
|
+
parameters: {
|
|
11727
|
+
type: "object",
|
|
11728
|
+
properties: {
|
|
11729
|
+
id: { type: "integer" },
|
|
11730
|
+
social_copy: { type: "string", description: "The post's new text" },
|
|
11731
|
+
repost: { type: "boolean", description: "Take it down and put it up again instead of editing it" }
|
|
11732
|
+
},
|
|
11733
|
+
required: ["id"]
|
|
11734
|
+
},
|
|
11735
|
+
group: "social",
|
|
11736
|
+
need: write5,
|
|
11737
|
+
risk: "W3",
|
|
11738
|
+
gates: ["VER"],
|
|
11739
|
+
run: async (ctx, { id, social_copy, repost }) => {
|
|
11740
|
+
const n = Number(id);
|
|
11741
|
+
if (!Number.isInteger(n) || n <= 0) throw new Error("Which post?");
|
|
11742
|
+
const copy = typeof social_copy === "string" ? social_copy.trim() : "";
|
|
11743
|
+
if (!copy && repost !== true) throw new Error("Give the new text (social_copy), or repost: true.");
|
|
11744
|
+
return ws(ctx).republishSocial(n, copy || void 0, repost === true);
|
|
11745
|
+
}
|
|
11746
|
+
}),
|
|
11747
|
+
tool({
|
|
11748
|
+
name: "social_posted_delete",
|
|
11749
|
+
description: "Take a social post that has gone out down from its channel (LinkedIn, Facebook, Instagram, Google). Its likes and comments go with it; this can't be undone.",
|
|
11750
|
+
parameters: { type: "object", properties: { id: { type: "integer" } }, required: ["id"] },
|
|
11751
|
+
group: "social",
|
|
11752
|
+
need: write5,
|
|
11753
|
+
risk: "W3",
|
|
11754
|
+
gates: ["VER"],
|
|
11755
|
+
run: async (ctx, { id }) => {
|
|
11756
|
+
const n = Number(id);
|
|
11757
|
+
if (!Number.isInteger(n) || n <= 0) throw new Error("Which post?");
|
|
11758
|
+
return ws(ctx).deletePostedSocial(n);
|
|
11759
|
+
}
|
|
11760
|
+
}),
|
|
11690
11761
|
tool({
|
|
11691
11762
|
name: "social_skip",
|
|
11692
11763
|
description: "Skip a LinkedIn post (it won't be posted; it can be restored).",
|
|
@@ -16545,7 +16616,7 @@ var program = new Command();
|
|
|
16545
16616
|
// package.json
|
|
16546
16617
|
var package_default = {
|
|
16547
16618
|
name: "@cmo-so/cli",
|
|
16548
|
-
version: "0.9.
|
|
16619
|
+
version: "0.9.2",
|
|
16549
16620
|
description: "CMO.so on the command line: your websites, ideas, blog posts, LinkedIn queue and results, plus a local MCP server for Claude Desktop, Cursor and other MCP clients.",
|
|
16550
16621
|
type: "module",
|
|
16551
16622
|
license: "MIT",
|
|
@@ -27571,6 +27642,17 @@ social.command("carousel <id>").description("a LinkedIn post with a set of pictu
|
|
|
27571
27642
|
});
|
|
27572
27643
|
})
|
|
27573
27644
|
);
|
|
27645
|
+
social.command("post-now <id>").description("post it on its channel now, not at its posting time (even while posting is paused)").action(act(async (opts, id) => tool2(opts, "social_publish_now", { id: ids2([id])[0] })));
|
|
27646
|
+
social.command("edit-posted <id> [text...]").description("change a post that has gone out (LinkedIn edits it in place, keeping likes and comments)").option("--repost", "take it down and put it up again instead").action(
|
|
27647
|
+
act(
|
|
27648
|
+
async (opts, id, text3) => tool2(opts, "social_posted_update", {
|
|
27649
|
+
id: ids2([id])[0],
|
|
27650
|
+
...text3.length ? { social_copy: text3.join(" ") } : {},
|
|
27651
|
+
...opts.repost ? { repost: true } : {}
|
|
27652
|
+
})
|
|
27653
|
+
)
|
|
27654
|
+
);
|
|
27655
|
+
social.command("delete-posted <id>").description("take a post that has gone out down from its channel, with its likes and comments").action(act(async (opts, id) => tool2(opts, "social_posted_delete", { id: ids2([id])[0] })));
|
|
27574
27656
|
social.command("skip <id>").description("skip a draft").action(act(async (opts, id) => tool2(opts, "social_skip", { id: ids2([id])[0] })));
|
|
27575
27657
|
social.command("restore <id>").description("bring a skipped draft back").action(act(async (opts, id) => tool2(opts, "social_restore", { id: ids2([id])[0] })));
|
|
27576
27658
|
social.command("draft <topic...>").description("add a post idea for Maggie to write (every connected channel unless --channel)").option("--summary <text>", "what the post should say").option("--channel <names>", "linkedin, facebook, instagram, google_business (comma-separated)").action(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmo-so/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "CMO.so on the command line: your websites, ideas, blog posts, LinkedIn queue and results, plus a local MCP server for Claude Desktop, Cursor and other MCP clients.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|