@agent-wechat/cli 0.15.0 → 0.15.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 +6 -0
- package/dist/cli.js +32 -9
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -90,6 +90,12 @@ Send options:
|
|
|
90
90
|
|
|
91
91
|
Media options:
|
|
92
92
|
- `--output <path>` — save to a specific file path
|
|
93
|
+
- `--full` — require an original-resolution image
|
|
94
|
+
- `--thumbnail` — save the cached preview
|
|
95
|
+
- `--best` — explicitly choose the default best-available image behavior
|
|
96
|
+
|
|
97
|
+
Media retrieval does not open a chat. Use `wx chats open <chatId>` separately
|
|
98
|
+
if WeChat needs to cache a regular photo's standard-size copy.
|
|
93
99
|
|
|
94
100
|
### Sessions
|
|
95
101
|
|
package/dist/cli.js
CHANGED
|
@@ -7870,11 +7870,15 @@ var getMediaParamsSchema = external_exports.object({
|
|
|
7870
7870
|
quality: external_exports.enum(["full", "thumbnail"]).optional()
|
|
7871
7871
|
});
|
|
7872
7872
|
var mediaResultSchema = external_exports.object({
|
|
7873
|
-
type: external_exports.enum(["image", "emoji", "voice", "video", "file", "pending", "unsupported"]),
|
|
7873
|
+
type: external_exports.enum(["image", "emoji", "voice", "video", "file", "pending", "expired", "unsupported"]),
|
|
7874
7874
|
data: external_exports.string().optional(),
|
|
7875
7875
|
url: external_exports.string().optional(),
|
|
7876
7876
|
format: external_exports.string(),
|
|
7877
|
-
filename: external_exports.string()
|
|
7877
|
+
filename: external_exports.string(),
|
|
7878
|
+
quality: external_exports.enum(["full", "standard", "thumbnail"]).optional(),
|
|
7879
|
+
reason: external_exports.string().optional(),
|
|
7880
|
+
expiresAt: external_exports.number().int().positive().optional(),
|
|
7881
|
+
retryable: external_exports.boolean().optional()
|
|
7878
7882
|
});
|
|
7879
7883
|
var agentConfigSchema = external_exports.object({
|
|
7880
7884
|
maxTurns: external_exports.number().int().positive().default(30),
|
|
@@ -7921,6 +7925,14 @@ function createSubscriptionClient(options) {
|
|
|
7921
7925
|
};
|
|
7922
7926
|
}
|
|
7923
7927
|
|
|
7928
|
+
// src/lib/media-status.ts
|
|
7929
|
+
function expiredMediaMessage(result) {
|
|
7930
|
+
if (result.type !== "expired" || result.data) return void 0;
|
|
7931
|
+
const expiry = typeof result.expiresAt === "number" ? new Date(result.expiresAt * 1e3) : void 0;
|
|
7932
|
+
const when = expiry && Number.isFinite(expiry.getTime()) ? ` (${expiry.toISOString()})` : "";
|
|
7933
|
+
return `Media has expired${when} and no cached copy is available. Ask the sender to resend; automatic retries will not recover it.`;
|
|
7934
|
+
}
|
|
7935
|
+
|
|
7924
7936
|
// src/cli.ts
|
|
7925
7937
|
import { spawn, execSync } from "child_process";
|
|
7926
7938
|
import { randomBytes } from "crypto";
|
|
@@ -7929,7 +7941,7 @@ import qrTerminal from "qrcode-terminal";
|
|
|
7929
7941
|
import os from "os";
|
|
7930
7942
|
import path from "path";
|
|
7931
7943
|
import { fileURLToPath } from "url";
|
|
7932
|
-
var VERSION = "0.15.
|
|
7944
|
+
var VERSION = "0.15.2";
|
|
7933
7945
|
var CONTAINER_NAME = "agent-wechat";
|
|
7934
7946
|
var GHCR_IMAGE = "ghcr.io/thisnick/agent-wechat";
|
|
7935
7947
|
var DEFAULT_PORT = 6174;
|
|
@@ -8075,8 +8087,13 @@ var messagesCmd = program2.command("messages").description("Message commands");
|
|
|
8075
8087
|
messagesCmd.command("list <chatId>").description("List messages for a chat").option("-l, --limit <number>", "Maximum number of messages", "50").option("-o, --offset <number>", "Skip first N messages", "0").option("-j, --json", "Output as JSON").action(async (chatId, opts) => {
|
|
8076
8088
|
await cmdMessages(getClient(), chatId, parseInt(opts.limit, 10), parseInt(opts.offset, 10), opts.json ?? false);
|
|
8077
8089
|
});
|
|
8078
|
-
messagesCmd.command("media <chatId> <localId>").description("Save a media attachment (
|
|
8079
|
-
|
|
8090
|
+
messagesCmd.command("media <chatId> <localId>").description("Save a media attachment (best available image, file, or voice)").option("--full", "Require the original-resolution image").option("--thumbnail", "Retrieve an image thumbnail instead of full resolution").option("--best", "Retrieve the best available image (default)").option("-o, --output <path>", "Output file path").action(async (chatId, localIdStr, opts) => {
|
|
8091
|
+
if (Number(!!opts.full) + Number(!!opts.thumbnail) + Number(!!opts.best) > 1) {
|
|
8092
|
+
console.error("Choose only one of --full, --thumbnail, or --best.");
|
|
8093
|
+
process.exit(1);
|
|
8094
|
+
}
|
|
8095
|
+
const quality = opts.full ? "full" : opts.thumbnail ? "thumbnail" : "best";
|
|
8096
|
+
await cmdMedia(getClient(), chatId, parseInt(localIdStr, 10), opts.output, quality);
|
|
8080
8097
|
});
|
|
8081
8098
|
messagesCmd.command("send <chatId>").description("Send a message to a chat").option("--text <text>", "Text message to send").option("--image <path>", "Image file to send").option("--file <path>", "File to send").option("--voice <path>", "Record audio as one or more voice notes").option("--detach", "Return after the voice job is queued").action(async (chatId, opts) => {
|
|
8082
8099
|
if (!opts.text && !opts.image && !opts.file && !opts.voice) {
|
|
@@ -8390,8 +8407,13 @@ async function cmdMessages(client, chatId, limit = 50, offset = 0, json = false)
|
|
|
8390
8407
|
console.log(`
|
|
8391
8408
|
${messages.length} message(s) shown.`);
|
|
8392
8409
|
}
|
|
8393
|
-
async function cmdMedia(client, chatId, localId, outputPath,
|
|
8394
|
-
const result = await client.getMedia(chatId, localId,
|
|
8410
|
+
async function cmdMedia(client, chatId, localId, outputPath, quality = "best") {
|
|
8411
|
+
const result = await client.getMedia(chatId, localId, quality);
|
|
8412
|
+
const expired = expiredMediaMessage(result);
|
|
8413
|
+
if (expired) {
|
|
8414
|
+
console.error(expired);
|
|
8415
|
+
process.exit(1);
|
|
8416
|
+
}
|
|
8395
8417
|
if (result.type === "unsupported") {
|
|
8396
8418
|
console.error("No media found for this message (unsupported type or not found).");
|
|
8397
8419
|
process.exit(1);
|
|
@@ -8404,9 +8426,10 @@ async function cmdMedia(client, chatId, localId, outputPath, thumbnail = false)
|
|
|
8404
8426
|
if (result.data) {
|
|
8405
8427
|
const buffer = Buffer.from(result.data, "base64");
|
|
8406
8428
|
fs.writeFileSync(outFile, buffer);
|
|
8407
|
-
|
|
8429
|
+
const variant = result.type === "image" && result.quality ? ` (${result.quality})` : "";
|
|
8430
|
+
console.log(`Saved ${result.type}${variant} to ${outFile} (${buffer.length} bytes)`);
|
|
8408
8431
|
} else if (result.type === "image") {
|
|
8409
|
-
console.error(`Requested image ${
|
|
8432
|
+
console.error(`Requested image ${quality} is not yet available.${quality === "full" ? " Regular phone sends may have no Original copy; try without --full." : ""}`);
|
|
8410
8433
|
process.exit(1);
|
|
8411
8434
|
} else if (result.type === "video") {
|
|
8412
8435
|
console.error("Video not yet downloaded by WeChat. Try playing the video in the app first.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-wechat/cli",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"wx": "./dist/cli.js"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@types/node": "^22",
|
|
18
18
|
"@types/qrcode-terminal": "^0.12.2",
|
|
19
19
|
"typescript": "^5.4.5",
|
|
20
|
-
"@agent-wechat/shared": "0.3.
|
|
20
|
+
"@agent-wechat/shared": "0.3.1"
|
|
21
21
|
},
|
|
22
22
|
"publishConfig": {
|
|
23
23
|
"access": "public",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "node build.js",
|
|
33
|
-
"typecheck": "tsc --noEmit"
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"test": "node --test --experimental-strip-types src/lib/*.test.mjs"
|
|
34
35
|
}
|
|
35
36
|
}
|