@pmate/cli 0.28.4 → 0.28.6
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 +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +158 -2
- package/package.json +10 -17
package/README.md
CHANGED
|
@@ -52,6 +52,7 @@ pmate im1 health
|
|
|
52
52
|
pmate im1 threads --limit 20
|
|
53
53
|
pmate im1 threads --search "titlte" --limit 5
|
|
54
54
|
pmate im1 messages --thread "<conversationId-or-thread-name>" --limit 50
|
|
55
|
+
pmate im1 pending-mentions --hours 24 --context 10
|
|
55
56
|
pmate im1 reply --thread "<conversationId-or-thread-name>" --text "hello"
|
|
56
57
|
```
|
|
57
58
|
|
package/dist/index.d.ts
CHANGED
|
@@ -628,6 +628,16 @@ type CollectCommandArgs = {
|
|
|
628
628
|
thread: string;
|
|
629
629
|
limit?: number;
|
|
630
630
|
json?: boolean;
|
|
631
|
+
} | {
|
|
632
|
+
type: Command.Collect;
|
|
633
|
+
action: "pending-mentions";
|
|
634
|
+
me: string;
|
|
635
|
+
from?: string;
|
|
636
|
+
to?: string;
|
|
637
|
+
hours: number;
|
|
638
|
+
context: number;
|
|
639
|
+
limit?: number;
|
|
640
|
+
json?: boolean;
|
|
631
641
|
} | {
|
|
632
642
|
type: Command.Collect;
|
|
633
643
|
action: "reply";
|
|
@@ -1044,6 +1054,8 @@ type ServiceCommandArgs = {
|
|
|
1044
1054
|
bump: "patch" | "minor" | "major";
|
|
1045
1055
|
cwd?: string;
|
|
1046
1056
|
force: boolean;
|
|
1057
|
+
releaseNotes?: string;
|
|
1058
|
+
minimumVersionCode?: number;
|
|
1047
1059
|
baseUrl?: string;
|
|
1048
1060
|
json: boolean;
|
|
1049
1061
|
} | {
|
package/dist/index.js
CHANGED
|
@@ -12073,7 +12073,7 @@ var AliyunService = class {
|
|
|
12073
12073
|
static getStaticAssetCacheControl(filePath) {
|
|
12074
12074
|
const normalized = filePath.replace(/\\/g, "/");
|
|
12075
12075
|
const base = import_node_path6.default.posix.basename(normalized).toLowerCase();
|
|
12076
|
-
if (base === "index.html" || base === "200.html" || base === "404.html" || base === "apple-app-site-association") {
|
|
12076
|
+
if (base === "index.html" || base === "200.html" || base === "404.html" || base === "latest.json" || base === "apple-app-site-association") {
|
|
12077
12077
|
return "no-cache, no-store, must-revalidate";
|
|
12078
12078
|
}
|
|
12079
12079
|
if (/[.-][a-z0-9_-]{8,}\./i.test(base)) {
|
|
@@ -16869,6 +16869,16 @@ var Im1BotClient = class {
|
|
|
16869
16869
|
);
|
|
16870
16870
|
return json.messages ?? [];
|
|
16871
16871
|
}
|
|
16872
|
+
async listPendingMentions(input) {
|
|
16873
|
+
const params = new URLSearchParams({
|
|
16874
|
+
me: input.me,
|
|
16875
|
+
from: input.from,
|
|
16876
|
+
to: input.to,
|
|
16877
|
+
context: String(input.context)
|
|
16878
|
+
});
|
|
16879
|
+
if (input.limit) params.set("limit", String(input.limit));
|
|
16880
|
+
return this.request(`/mentions/pending?${params.toString()}`);
|
|
16881
|
+
}
|
|
16872
16882
|
async sendMessage(input) {
|
|
16873
16883
|
return this.request("/messages/send", {
|
|
16874
16884
|
method: "POST",
|
|
@@ -17105,6 +17115,10 @@ var CollectCommandHandler = class {
|
|
|
17105
17115
|
await this.handleBotMessages(args);
|
|
17106
17116
|
return;
|
|
17107
17117
|
}
|
|
17118
|
+
if (args.action === "pending-mentions") {
|
|
17119
|
+
await this.handleBotPendingMentions(args);
|
|
17120
|
+
return;
|
|
17121
|
+
}
|
|
17108
17122
|
if (args.action === "reply") {
|
|
17109
17123
|
await this.handleBotReply(args);
|
|
17110
17124
|
return;
|
|
@@ -17148,6 +17162,32 @@ var CollectCommandHandler = class {
|
|
|
17148
17162
|
ui.plain(formatBotMessage(message));
|
|
17149
17163
|
}
|
|
17150
17164
|
}
|
|
17165
|
+
async handleBotPendingMentions(args) {
|
|
17166
|
+
const to = args.to ? new Date(args.to) : /* @__PURE__ */ new Date();
|
|
17167
|
+
const from = args.from ? new Date(args.from) : new Date(to.getTime() - args.hours * 60 * 60 * 1e3);
|
|
17168
|
+
if (from >= to) throw new Error("Expected --from to be earlier than --to");
|
|
17169
|
+
const result = await new Im1BotClient().listPendingMentions({
|
|
17170
|
+
me: args.me,
|
|
17171
|
+
from: from.toISOString(),
|
|
17172
|
+
to: to.toISOString(),
|
|
17173
|
+
context: args.context,
|
|
17174
|
+
limit: args.limit
|
|
17175
|
+
});
|
|
17176
|
+
if (args.json !== false) {
|
|
17177
|
+
ui.plain(JSON.stringify(result, null, 2));
|
|
17178
|
+
return;
|
|
17179
|
+
}
|
|
17180
|
+
if (result.mentions.length === 0) {
|
|
17181
|
+
ui.plain("No pending mentions found.");
|
|
17182
|
+
return;
|
|
17183
|
+
}
|
|
17184
|
+
for (const mention of result.mentions) {
|
|
17185
|
+
ui.plain(`${mention.sentAt} ${mention.thread?.name ?? mention.conversationId} ${mention.sender ?? "unknown"}: ${mention.body}`);
|
|
17186
|
+
for (const message of mention.context) {
|
|
17187
|
+
ui.plain(` ${message.sentAt} ${message.sender ?? "unknown"}: ${message.body}`);
|
|
17188
|
+
}
|
|
17189
|
+
}
|
|
17190
|
+
}
|
|
17151
17191
|
async handleBotReply(args) {
|
|
17152
17192
|
const client = new Im1BotClient();
|
|
17153
17193
|
const attachment = args.file ? await readOutgoingAttachment(args.file) : void 0;
|
|
@@ -20034,9 +20074,29 @@ var AndroidApkReleaseService = class {
|
|
|
20034
20074
|
ui.warn("APK uploaded but registry artifact record failed", error instanceof Error ? error.message : String(error));
|
|
20035
20075
|
}
|
|
20036
20076
|
}
|
|
20077
|
+
if (options.env === "prod" && options.variant.toLowerCase() === "release") {
|
|
20078
|
+
await this.publishLatestManifest(service, artifact, options);
|
|
20079
|
+
}
|
|
20037
20080
|
ui.success(`Released APK ${artifact.downloadUrl}`);
|
|
20038
20081
|
return artifact;
|
|
20039
20082
|
}
|
|
20083
|
+
async publishLatestManifest(service, artifact, options) {
|
|
20084
|
+
const manifest = buildAndroidLatestManifest(artifact, {
|
|
20085
|
+
releaseNotes: options.releaseNotes,
|
|
20086
|
+
minimumVersionCode: options.minimumVersionCode
|
|
20087
|
+
});
|
|
20088
|
+
const objectKey = buildAndroidLatestManifestObjectKey(service.namespace, service.name);
|
|
20089
|
+
const tempDir = (0, import_node_fs20.mkdtempSync)(import_node_path25.default.join(import_node_os9.default.tmpdir(), "pmate-apk-latest-"));
|
|
20090
|
+
const manifestPath = import_node_path25.default.join(tempDir, "latest.json");
|
|
20091
|
+
try {
|
|
20092
|
+
(0, import_node_fs20.writeFileSync)(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
20093
|
+
`);
|
|
20094
|
+
await AliyunService.uploadFile(manifestPath, ANDROID_APK_BUCKET, objectKey);
|
|
20095
|
+
ui.success(`Published Android update manifest ${ANDROID_APK_PUBLIC_BASE_URL}/${objectKey}`);
|
|
20096
|
+
} finally {
|
|
20097
|
+
(0, import_node_fs20.rmSync)(tempDir, { recursive: true, force: true });
|
|
20098
|
+
}
|
|
20099
|
+
}
|
|
20040
20100
|
async list(service, options) {
|
|
20041
20101
|
const serviceId = service.id;
|
|
20042
20102
|
if (this.registry) {
|
|
@@ -20169,6 +20229,26 @@ function bumpVersionName(versionName, bump) {
|
|
|
20169
20229
|
function buildAndroidApkObjectKey(namespace, serviceName, versionName) {
|
|
20170
20230
|
return `apks/${encodePathSegment(namespace)}/${encodePathSegment(serviceName)}/${encodePathSegment(versionName)}.apk`;
|
|
20171
20231
|
}
|
|
20232
|
+
function buildAndroidLatestManifestObjectKey(namespace, serviceName) {
|
|
20233
|
+
return `apks/${namespace}/${serviceName}/latest.json`;
|
|
20234
|
+
}
|
|
20235
|
+
function buildAndroidLatestManifest(artifact, options = {}) {
|
|
20236
|
+
const minimumVersionCode = options.minimumVersionCode ?? 0;
|
|
20237
|
+
if (!Number.isInteger(minimumVersionCode) || minimumVersionCode < 0 || minimumVersionCode > artifact.versionCode) {
|
|
20238
|
+
throw new Error(`minimumVersionCode must be between 0 and released versionCode ${artifact.versionCode}`);
|
|
20239
|
+
}
|
|
20240
|
+
return {
|
|
20241
|
+
applicationId: artifact.applicationId,
|
|
20242
|
+
versionName: artifact.versionName,
|
|
20243
|
+
versionCode: artifact.versionCode,
|
|
20244
|
+
downloadUrl: artifact.downloadUrl,
|
|
20245
|
+
sha256: artifact.sha256,
|
|
20246
|
+
size: artifact.size,
|
|
20247
|
+
releaseNotes: options.releaseNotes?.trim() ?? "",
|
|
20248
|
+
minimumVersionCode,
|
|
20249
|
+
publishedAt: options.publishedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
20250
|
+
};
|
|
20251
|
+
}
|
|
20172
20252
|
function resolveRepositoryLocalRoot(repository) {
|
|
20173
20253
|
const repoName = repository.replace(/\/+$/, "").split("/").pop()?.replace(/\.git$/i, "");
|
|
20174
20254
|
if (!repoName) {
|
|
@@ -22289,7 +22369,9 @@ var ServiceCommandHandler = class {
|
|
|
22289
22369
|
variant: args.variant,
|
|
22290
22370
|
bump: args.bump,
|
|
22291
22371
|
cwd: args.cwd,
|
|
22292
|
-
force: args.force
|
|
22372
|
+
force: args.force,
|
|
22373
|
+
releaseNotes: args.releaseNotes,
|
|
22374
|
+
minimumVersionCode: args.minimumVersionCode
|
|
22293
22375
|
});
|
|
22294
22376
|
this.renderApkArtifacts([artifact], args.json);
|
|
22295
22377
|
return;
|
|
@@ -26135,6 +26217,8 @@ function parseServiceApkArgs(tokens, defaults) {
|
|
|
26135
26217
|
let force = false;
|
|
26136
26218
|
let major = false;
|
|
26137
26219
|
let minor = false;
|
|
26220
|
+
let releaseNotes;
|
|
26221
|
+
let minimumVersionCode;
|
|
26138
26222
|
while (rest.length > 0) {
|
|
26139
26223
|
const token = rest.shift();
|
|
26140
26224
|
switch (token) {
|
|
@@ -26171,6 +26255,17 @@ function parseServiceApkArgs(tokens, defaults) {
|
|
|
26171
26255
|
}
|
|
26172
26256
|
minor = true;
|
|
26173
26257
|
break;
|
|
26258
|
+
case "--release-notes":
|
|
26259
|
+
if (apkAction !== "release") throw new Error(`Unknown service apk ${apkAction} option: ${token}`);
|
|
26260
|
+
releaseNotes = requireValue6(rest, token);
|
|
26261
|
+
break;
|
|
26262
|
+
case "--minimum-version-code": {
|
|
26263
|
+
if (apkAction !== "release") throw new Error(`Unknown service apk ${apkAction} option: ${token}`);
|
|
26264
|
+
const value = Number(requireValue6(rest, token));
|
|
26265
|
+
if (!Number.isInteger(value) || value < 0) throw new Error("--minimum-version-code must be a non-negative integer");
|
|
26266
|
+
minimumVersionCode = value;
|
|
26267
|
+
break;
|
|
26268
|
+
}
|
|
26174
26269
|
case "--base-url":
|
|
26175
26270
|
baseUrl = requireValue6(rest, token);
|
|
26176
26271
|
break;
|
|
@@ -26205,6 +26300,8 @@ function parseServiceApkArgs(tokens, defaults) {
|
|
|
26205
26300
|
bump: major ? "major" : minor ? "minor" : "patch",
|
|
26206
26301
|
cwd,
|
|
26207
26302
|
force,
|
|
26303
|
+
releaseNotes,
|
|
26304
|
+
minimumVersionCode,
|
|
26208
26305
|
baseUrl,
|
|
26209
26306
|
json
|
|
26210
26307
|
};
|
|
@@ -27610,6 +27707,9 @@ function parseIm1Args(tokens) {
|
|
|
27610
27707
|
if (action === "messages") {
|
|
27611
27708
|
return parseIm1MessagesArgs(rest);
|
|
27612
27709
|
}
|
|
27710
|
+
if (action === "pending-mentions") {
|
|
27711
|
+
return parseIm1PendingMentionsArgs(rest);
|
|
27712
|
+
}
|
|
27613
27713
|
if (action === "reply") {
|
|
27614
27714
|
return parseIm1ReplyArgs(rest);
|
|
27615
27715
|
}
|
|
@@ -27618,6 +27718,51 @@ function parseIm1Args(tokens) {
|
|
|
27618
27718
|
}
|
|
27619
27719
|
throw new Error(`Unknown im1 action: ${action}`);
|
|
27620
27720
|
}
|
|
27721
|
+
function parseIm1PendingMentionsArgs(tokens) {
|
|
27722
|
+
const rest = [...tokens];
|
|
27723
|
+
let me = "Chef Ryan";
|
|
27724
|
+
let from;
|
|
27725
|
+
let to;
|
|
27726
|
+
let hours = 24;
|
|
27727
|
+
let context = 10;
|
|
27728
|
+
let limit;
|
|
27729
|
+
let json = true;
|
|
27730
|
+
while (rest.length > 0) {
|
|
27731
|
+
const token = rest.shift();
|
|
27732
|
+
switch (token) {
|
|
27733
|
+
case "--me":
|
|
27734
|
+
me = requireValue12(rest, token);
|
|
27735
|
+
break;
|
|
27736
|
+
case "--from":
|
|
27737
|
+
from = parseIsoDate(requireValue12(rest, token), token);
|
|
27738
|
+
break;
|
|
27739
|
+
case "--to":
|
|
27740
|
+
to = parseIsoDate(requireValue12(rest, token), token);
|
|
27741
|
+
break;
|
|
27742
|
+
case "--hours":
|
|
27743
|
+
hours = parsePositiveInt2(requireValue12(rest, token), token);
|
|
27744
|
+
break;
|
|
27745
|
+
case "--context":
|
|
27746
|
+
context = parseBoundedPositiveInt(requireValue12(rest, token), token, 50);
|
|
27747
|
+
break;
|
|
27748
|
+
case "--limit":
|
|
27749
|
+
limit = parseBoundedPositiveInt(requireValue12(rest, token), token, 500);
|
|
27750
|
+
break;
|
|
27751
|
+
case "--json":
|
|
27752
|
+
json = true;
|
|
27753
|
+
break;
|
|
27754
|
+
case "--text":
|
|
27755
|
+
json = false;
|
|
27756
|
+
break;
|
|
27757
|
+
default:
|
|
27758
|
+
throw new Error(`Unknown im1 pending-mentions option: ${token}`);
|
|
27759
|
+
}
|
|
27760
|
+
}
|
|
27761
|
+
if (from && !to || !from && to) {
|
|
27762
|
+
throw new Error("Use --from and --to together");
|
|
27763
|
+
}
|
|
27764
|
+
return { type: "collect" /* Collect */, action: "pending-mentions", me, from, to, hours, context, limit, json };
|
|
27765
|
+
}
|
|
27621
27766
|
function parseIm1HealthArgs(tokens) {
|
|
27622
27767
|
const rest = [...tokens];
|
|
27623
27768
|
let json = false;
|
|
@@ -27782,6 +27927,16 @@ function parsePositiveInt2(value, optionName) {
|
|
|
27782
27927
|
}
|
|
27783
27928
|
return parsed;
|
|
27784
27929
|
}
|
|
27930
|
+
function parseBoundedPositiveInt(value, optionName, max) {
|
|
27931
|
+
const parsed = parsePositiveInt2(value, optionName);
|
|
27932
|
+
if (parsed > max) throw new Error(`Invalid value for ${optionName}: ${value} (max ${max})`);
|
|
27933
|
+
return parsed;
|
|
27934
|
+
}
|
|
27935
|
+
function parseIsoDate(value, optionName) {
|
|
27936
|
+
const date = new Date(value);
|
|
27937
|
+
if (!Number.isFinite(date.getTime())) throw new Error(`Invalid value for ${optionName}: ${value}`);
|
|
27938
|
+
return date.toISOString();
|
|
27939
|
+
}
|
|
27785
27940
|
|
|
27786
27941
|
// src/chatRoomCommandParser.ts
|
|
27787
27942
|
function parseChatRoomArgs(tokens) {
|
|
@@ -28007,6 +28162,7 @@ var HELP_TEXT = [
|
|
|
28007
28162
|
` ${import_chalk4.default.gray(" health [--json]")}`,
|
|
28008
28163
|
` ${import_chalk4.default.gray(" threads [--q <keyword>] [--search <title>] [--limit <n>] [--json|--text]")}`,
|
|
28009
28164
|
` ${import_chalk4.default.gray(" messages --thread <name|conversation-id> [--limit <n>] [--json|--text]")}`,
|
|
28165
|
+
` ${import_chalk4.default.gray(" pending-mentions [--me <name>] [--hours <n>|--from <iso> --to <iso>] [--context <1-50>] [--limit <1-500>] [--json|--text]")}`,
|
|
28010
28166
|
` ${import_chalk4.default.gray(" reply --thread <name|conversation-id> [--text <text>] [--file|--image <path>] [--dryrun]")}`,
|
|
28011
28167
|
` ${import_chalk4.default.gray(" react --thread <name|conversation-id> --emoji <emoji> [--message <id|timestamp>] [--remove] [--dryrun]")}`,
|
|
28012
28168
|
` ${import_chalk4.default.cyan("collect")} Legacy alias for CC/yelling collection`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pmate/cli",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.6",
|
|
4
4
|
"description": "CLI utilities for the pMate project",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -11,16 +11,6 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist"
|
|
13
13
|
],
|
|
14
|
-
"scripts": {
|
|
15
|
-
"build": "npm run clean && tsup --config tsup.config.ts && node scripts/copy-templates.js",
|
|
16
|
-
"clean": "rimraf dist",
|
|
17
|
-
"dev": "ts-node src/index.ts",
|
|
18
|
-
"release": "npm publish",
|
|
19
|
-
"start": "node dist/index.js",
|
|
20
|
-
"test": "vitest run src/tests",
|
|
21
|
-
"typecheck": "tsc --noEmit",
|
|
22
|
-
"prepare": "npm run build"
|
|
23
|
-
},
|
|
24
14
|
"keywords": [
|
|
25
15
|
"cli",
|
|
26
16
|
"typescript",
|
|
@@ -67,10 +57,13 @@
|
|
|
67
57
|
"typescript": "^5.9.3",
|
|
68
58
|
"vitest": "^4.0.17"
|
|
69
59
|
},
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "npm run clean && tsup --config tsup.config.ts && node scripts/copy-templates.js",
|
|
62
|
+
"clean": "rimraf dist",
|
|
63
|
+
"dev": "ts-node src/index.ts",
|
|
64
|
+
"release": "pnpm publish",
|
|
65
|
+
"start": "node dist/index.js",
|
|
66
|
+
"test": "vitest run src/tests",
|
|
67
|
+
"typecheck": "tsc --noEmit"
|
|
75
68
|
}
|
|
76
|
-
}
|
|
69
|
+
}
|