@pmate/cli 0.25.6 → 0.25.8
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 +37 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +147 -111
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,6 +48,11 @@ pmate notion create --private --title "Private Notes" --file ./notes.md
|
|
|
48
48
|
pmate notion update <page-id-or-url> --file ./notes.md --append
|
|
49
49
|
pmate vercel projects
|
|
50
50
|
pmate vercel deploys --project web --last-week
|
|
51
|
+
pmate im1 health
|
|
52
|
+
pmate im1 threads --limit 20
|
|
53
|
+
pmate im1 threads --search "titlte" --limit 5
|
|
54
|
+
pmate im1 messages --thread "<conversationId-or-thread-name>" --limit 50
|
|
55
|
+
pmate im1 reply --thread "<conversationId-or-thread-name>" --text "hello"
|
|
51
56
|
```
|
|
52
57
|
|
|
53
58
|
Notes:
|
|
@@ -159,6 +164,38 @@ Notes:
|
|
|
159
164
|
- Platform commands such as `pmate sts`, `pmate agent`, and `pmate app` still
|
|
160
165
|
default to the `@pmate/cli` session.
|
|
161
166
|
|
|
167
|
+
## IM1 / CC messages
|
|
168
|
+
|
|
169
|
+
`pmate im1` reads CC messages through the local `cc-bot` service at
|
|
170
|
+
`http://localhost:39223` by default. Override the base URL with
|
|
171
|
+
`PMATE_IM1_BASE_URL` only when debugging another local service instance.
|
|
172
|
+
|
|
173
|
+
Useful commands:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
pmate im1 health
|
|
177
|
+
pmate im1 threads --limit 20
|
|
178
|
+
pmate im1 threads --q Bug --limit 10
|
|
179
|
+
pmate im1 threads --search "titlte" --limit 5
|
|
180
|
+
pmate im1 messages --thread "<conversationId-or-thread-name>" --limit 50
|
|
181
|
+
pmate im1 reply --thread "<conversationId-or-thread-name>" --text "hello"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
`threads` and `messages` output JSON by default. Thread rows include both
|
|
185
|
+
`conversationId` and `threadKey`; prefer `conversationId` when scripting or
|
|
186
|
+
passing a thread back into `messages`/`reply`. Add `--text` for compact
|
|
187
|
+
human-readable output.
|
|
188
|
+
|
|
189
|
+
Use `pmate im1 threads --search "<title>"` for fuzzy title lookup. It compares
|
|
190
|
+
the lowercased search text against thread titles with edit distance, including
|
|
191
|
+
nearby token/window matches for typos such as `titlte` vs `title`. JSON output
|
|
192
|
+
includes `searchDistance` and `searchScore`.
|
|
193
|
+
|
|
194
|
+
CC sync is owned by the background service in `~/dev/pcs/cc-bot`, which runs
|
|
195
|
+
under PM2, keeps TimescaleDB running, listens for new CC messages, and performs
|
|
196
|
+
bounded 3-day backfill. `pmate im1` is CC-only and does not accept `--source`
|
|
197
|
+
or custom `--endpoint` options.
|
|
198
|
+
|
|
162
199
|
## Notion config
|
|
163
200
|
|
|
164
201
|
Add a Notion integration token to `~/.pmate/config.yaml`:
|
package/dist/index.d.ts
CHANGED
|
@@ -550,23 +550,23 @@ type CollectCommandArgs = {
|
|
|
550
550
|
} | {
|
|
551
551
|
type: Command.Collect;
|
|
552
552
|
action: "health";
|
|
553
|
+
json?: boolean;
|
|
553
554
|
} | {
|
|
554
555
|
type: Command.Collect;
|
|
555
556
|
action: "threads";
|
|
556
|
-
source?: "cc";
|
|
557
557
|
query?: string;
|
|
558
|
+
search?: string;
|
|
558
559
|
limit?: number;
|
|
560
|
+
json?: boolean;
|
|
559
561
|
} | {
|
|
560
562
|
type: Command.Collect;
|
|
561
563
|
action: "messages";
|
|
562
|
-
source?: "cc";
|
|
563
564
|
thread: string;
|
|
564
565
|
limit?: number;
|
|
566
|
+
json?: boolean;
|
|
565
567
|
} | {
|
|
566
568
|
type: Command.Collect;
|
|
567
569
|
action: "reply";
|
|
568
|
-
source?: "cc" | "yelling";
|
|
569
|
-
endpoint?: string;
|
|
570
570
|
thread: string;
|
|
571
571
|
text: string;
|
|
572
572
|
dryRun: boolean;
|
package/dist/index.js
CHANGED
|
@@ -15748,21 +15748,15 @@ var CollectCommandHandler = class {
|
|
|
15748
15748
|
await this.handleBotMessages(args);
|
|
15749
15749
|
return;
|
|
15750
15750
|
}
|
|
15751
|
-
if (args.source === "cc" && !args.endpoint) {
|
|
15752
|
-
if (args.action === "sync") {
|
|
15753
|
-
throw new Error(
|
|
15754
|
-
'pmate im1 collect sync has moved to cc-bot. Start ~/dev/pcs/cc-bot and use "pmate im1 threads", "pmate im1 messages", or "pmate im1 reply".'
|
|
15755
|
-
);
|
|
15756
|
-
}
|
|
15757
|
-
if (args.action === "reply") {
|
|
15758
|
-
await this.handleBotReply(args);
|
|
15759
|
-
return;
|
|
15760
|
-
}
|
|
15761
|
-
}
|
|
15762
15751
|
if (args.action === "reply") {
|
|
15763
|
-
await this.
|
|
15752
|
+
await this.handleBotReply(args);
|
|
15764
15753
|
return;
|
|
15765
15754
|
}
|
|
15755
|
+
if (args.source === "cc" && !args.endpoint) {
|
|
15756
|
+
throw new Error(
|
|
15757
|
+
'CC sync has moved to cc-bot. Start ~/dev/pcs/cc-bot and use "pmate im1 threads", "pmate im1 messages", or "pmate im1 reply".'
|
|
15758
|
+
);
|
|
15759
|
+
}
|
|
15766
15760
|
await this.handleSync(args);
|
|
15767
15761
|
}
|
|
15768
15762
|
async handleBotHealth() {
|
|
@@ -15771,14 +15765,24 @@ var CollectCommandHandler = class {
|
|
|
15771
15765
|
}
|
|
15772
15766
|
async handleBotThreads(args) {
|
|
15773
15767
|
const client = new Im1BotClient();
|
|
15774
|
-
const
|
|
15775
|
-
|
|
15768
|
+
const fetchLimit = args.search ? Math.max(args.limit ?? 10, 200) : args.limit;
|
|
15769
|
+
const threads = await client.listThreads({ q: args.query, limit: fetchLimit });
|
|
15770
|
+
const outputThreads = args.search ? rankThreadsByTitleSearch(threads, args.search).slice(0, args.limit ?? 10) : threads;
|
|
15771
|
+
if (args.json !== false) {
|
|
15772
|
+
ui.plain(JSON.stringify({ ok: true, threads: outputThreads }, null, 2));
|
|
15773
|
+
return;
|
|
15774
|
+
}
|
|
15775
|
+
for (const thread of outputThreads) {
|
|
15776
15776
|
ui.plain(formatBotThread(thread));
|
|
15777
15777
|
}
|
|
15778
15778
|
}
|
|
15779
15779
|
async handleBotMessages(args) {
|
|
15780
15780
|
const client = new Im1BotClient();
|
|
15781
15781
|
const messages2 = await client.listMessages({ thread: args.thread, limit: args.limit });
|
|
15782
|
+
if (args.json !== false) {
|
|
15783
|
+
ui.plain(JSON.stringify({ ok: true, messages: messages2 }, null, 2));
|
|
15784
|
+
return;
|
|
15785
|
+
}
|
|
15782
15786
|
for (const message of messages2.reverse()) {
|
|
15783
15787
|
ui.plain(formatBotMessage(message));
|
|
15784
15788
|
}
|
|
@@ -15790,11 +15794,7 @@ var CollectCommandHandler = class {
|
|
|
15790
15794
|
text: args.text,
|
|
15791
15795
|
dryRun: args.dryRun
|
|
15792
15796
|
});
|
|
15793
|
-
|
|
15794
|
-
ui.plain(JSON.stringify(result, null, 2));
|
|
15795
|
-
return;
|
|
15796
|
-
}
|
|
15797
|
-
ui.success("im1 reply sent", { source: "cc", thread: args.thread });
|
|
15797
|
+
ui.plain(JSON.stringify(result, null, 2));
|
|
15798
15798
|
}
|
|
15799
15799
|
async handleSync(args) {
|
|
15800
15800
|
let browser = null;
|
|
@@ -16175,14 +16175,98 @@ function isExternalImageRef(imagePath) {
|
|
|
16175
16175
|
}
|
|
16176
16176
|
function formatBotThread(thread) {
|
|
16177
16177
|
const unread = thread.unread && thread.unread > 0 ? ` unread=${thread.unread}` : "";
|
|
16178
|
+
const distance = typeof thread.searchDistance === "number" ? ` distance=${thread.searchDistance}` : "";
|
|
16178
16179
|
const time = thread.lastMessageAt ? ` ${thread.lastMessageAt}` : "";
|
|
16179
|
-
const preview = thread.preview ? ` - ${thread.preview}` : "";
|
|
16180
|
-
return `${thread.name} (${thread.conversationId})${unread}${time}${preview}`;
|
|
16180
|
+
const preview = thread.preview ? ` - ${truncateCliPreview(thread.preview, 120)}` : "";
|
|
16181
|
+
return `${thread.name} (${thread.conversationId})${unread}${distance}${time}${preview}`;
|
|
16182
|
+
}
|
|
16183
|
+
function rankThreadsByTitleSearch(threads, rawSearch) {
|
|
16184
|
+
const search = normalizeSearchTitle(rawSearch);
|
|
16185
|
+
if (!search) {
|
|
16186
|
+
return threads.map((thread) => ({
|
|
16187
|
+
...thread,
|
|
16188
|
+
search: rawSearch,
|
|
16189
|
+
searchDistance: 0,
|
|
16190
|
+
searchScore: 1
|
|
16191
|
+
}));
|
|
16192
|
+
}
|
|
16193
|
+
return threads.map((thread) => {
|
|
16194
|
+
const title = normalizeSearchTitle(thread.name);
|
|
16195
|
+
const distance = fuzzyTitleDistance(search, title);
|
|
16196
|
+
const score = 1 - distance / Math.max(search.replace(/\s+/g, "").length, 1);
|
|
16197
|
+
return {
|
|
16198
|
+
...thread,
|
|
16199
|
+
search: rawSearch,
|
|
16200
|
+
searchDistance: distance,
|
|
16201
|
+
searchScore: Number(Math.max(0, score).toFixed(4))
|
|
16202
|
+
};
|
|
16203
|
+
}).sort((left, right) => {
|
|
16204
|
+
if ((left.searchDistance ?? 0) !== (right.searchDistance ?? 0)) {
|
|
16205
|
+
return (left.searchDistance ?? 0) - (right.searchDistance ?? 0);
|
|
16206
|
+
}
|
|
16207
|
+
if ((left.searchScore ?? 0) !== (right.searchScore ?? 0)) {
|
|
16208
|
+
return (right.searchScore ?? 0) - (left.searchScore ?? 0);
|
|
16209
|
+
}
|
|
16210
|
+
return compareNullableIsoDesc(left.lastMessageAt, right.lastMessageAt);
|
|
16211
|
+
});
|
|
16212
|
+
}
|
|
16213
|
+
function fuzzyTitleDistance(search, title) {
|
|
16214
|
+
if (!search) return 0;
|
|
16215
|
+
if (!title) return search.length;
|
|
16216
|
+
if (title.includes(search)) return 0;
|
|
16217
|
+
const compactSearch = search.replace(/\s+/g, "");
|
|
16218
|
+
const compactTitle = title.replace(/\s+/g, "");
|
|
16219
|
+
const candidates = /* @__PURE__ */ new Set([title, compactTitle]);
|
|
16220
|
+
for (const token of title.split(/\s+/)) {
|
|
16221
|
+
if (token) candidates.add(token);
|
|
16222
|
+
}
|
|
16223
|
+
if (compactSearch && compactTitle.length >= compactSearch.length) {
|
|
16224
|
+
for (let index = 0; index <= compactTitle.length - compactSearch.length; index += 1) {
|
|
16225
|
+
candidates.add(compactTitle.slice(index, index + compactSearch.length));
|
|
16226
|
+
}
|
|
16227
|
+
}
|
|
16228
|
+
let best = Number.POSITIVE_INFINITY;
|
|
16229
|
+
for (const candidate of candidates) {
|
|
16230
|
+
best = Math.min(best, damerauLevenshteinDistance(compactSearch || search, candidate));
|
|
16231
|
+
}
|
|
16232
|
+
return Number.isFinite(best) ? best : search.length;
|
|
16233
|
+
}
|
|
16234
|
+
function normalizeSearchTitle(value) {
|
|
16235
|
+
return value.toLowerCase().normalize("NFKC").replace(/[\p{P}\p{S}]+/gu, " ").replace(/\s+/g, " ").trim();
|
|
16236
|
+
}
|
|
16237
|
+
function damerauLevenshteinDistance(left, right) {
|
|
16238
|
+
const matrix = Array.from({ length: left.length + 1 }, () => Array(right.length + 1).fill(0));
|
|
16239
|
+
for (let row = 0; row <= left.length; row += 1) matrix[row][0] = row;
|
|
16240
|
+
for (let column = 0; column <= right.length; column += 1) matrix[0][column] = column;
|
|
16241
|
+
for (let row = 1; row <= left.length; row += 1) {
|
|
16242
|
+
for (let column = 1; column <= right.length; column += 1) {
|
|
16243
|
+
const cost = left[row - 1] === right[column - 1] ? 0 : 1;
|
|
16244
|
+
matrix[row][column] = Math.min(
|
|
16245
|
+
matrix[row - 1][column] + 1,
|
|
16246
|
+
matrix[row][column - 1] + 1,
|
|
16247
|
+
matrix[row - 1][column - 1] + cost
|
|
16248
|
+
);
|
|
16249
|
+
if (row > 1 && column > 1 && left[row - 1] === right[column - 2] && left[row - 2] === right[column - 1]) {
|
|
16250
|
+
matrix[row][column] = Math.min(matrix[row][column], matrix[row - 2][column - 2] + 1);
|
|
16251
|
+
}
|
|
16252
|
+
}
|
|
16253
|
+
}
|
|
16254
|
+
return matrix[left.length][right.length];
|
|
16255
|
+
}
|
|
16256
|
+
function compareNullableIsoDesc(left, right) {
|
|
16257
|
+
const leftTime = left ? Date.parse(left) : 0;
|
|
16258
|
+
const rightTime = right ? Date.parse(right) : 0;
|
|
16259
|
+
return rightTime - leftTime;
|
|
16181
16260
|
}
|
|
16182
16261
|
function formatBotMessage(message) {
|
|
16183
16262
|
const sender = message.sender ? `${message.sender}: ` : "";
|
|
16184
16263
|
return `[${message.sentAt}] ${sender}${message.body}`;
|
|
16185
16264
|
}
|
|
16265
|
+
function truncateCliPreview(value, maxLength) {
|
|
16266
|
+
const normalized = value.replace(/\s+/g, " ").replace(/\u200B/g, "").trim();
|
|
16267
|
+
if (normalized.length <= maxLength) return normalized;
|
|
16268
|
+
return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}\u2026`;
|
|
16269
|
+
}
|
|
16186
16270
|
function filterThreadsForSync(threads, target) {
|
|
16187
16271
|
if (!target) {
|
|
16188
16272
|
return threads;
|
|
@@ -25674,13 +25758,10 @@ function parseIm1Args(tokens) {
|
|
|
25674
25758
|
const rest = [...tokens];
|
|
25675
25759
|
const action = rest.shift();
|
|
25676
25760
|
if (!action) {
|
|
25677
|
-
throw new Error("Usage: im1
|
|
25678
|
-
}
|
|
25679
|
-
if (action === "collect") {
|
|
25680
|
-
return parseIm1CollectArgs(rest);
|
|
25761
|
+
throw new Error("Usage: im1 health | im1 threads [--q <keyword>] [--search <title>] | im1 messages --thread <name|conversation-id> | im1 reply --thread <name|conversation-id> --text <text>");
|
|
25681
25762
|
}
|
|
25682
25763
|
if (action === "health") {
|
|
25683
|
-
return
|
|
25764
|
+
return parseIm1HealthArgs(rest);
|
|
25684
25765
|
}
|
|
25685
25766
|
if (action === "threads") {
|
|
25686
25767
|
return parseIm1ThreadsArgs(rest);
|
|
@@ -25693,47 +25774,60 @@ function parseIm1Args(tokens) {
|
|
|
25693
25774
|
}
|
|
25694
25775
|
throw new Error(`Unknown im1 action: ${action}`);
|
|
25695
25776
|
}
|
|
25777
|
+
function parseIm1HealthArgs(tokens) {
|
|
25778
|
+
const rest = [...tokens];
|
|
25779
|
+
let json = false;
|
|
25780
|
+
while (rest.length > 0) {
|
|
25781
|
+
const token = rest.shift();
|
|
25782
|
+
switch (token) {
|
|
25783
|
+
case "--json":
|
|
25784
|
+
json = true;
|
|
25785
|
+
break;
|
|
25786
|
+
default:
|
|
25787
|
+
throw new Error(`Unknown im1 health option: ${token}`);
|
|
25788
|
+
}
|
|
25789
|
+
}
|
|
25790
|
+
return { type: "collect" /* Collect */, action: "health", json };
|
|
25791
|
+
}
|
|
25696
25792
|
function parseIm1ThreadsArgs(tokens) {
|
|
25697
25793
|
const rest = [...tokens];
|
|
25698
25794
|
let query;
|
|
25795
|
+
let search;
|
|
25699
25796
|
let limit;
|
|
25700
|
-
let
|
|
25797
|
+
let json = true;
|
|
25701
25798
|
while (rest.length > 0) {
|
|
25702
25799
|
const token = rest.shift();
|
|
25703
25800
|
switch (token) {
|
|
25704
|
-
case "--source": {
|
|
25705
|
-
const value = requireValue11(rest, token);
|
|
25706
|
-
if (value !== "cc") throw new Error(`Unsupported im1 threads source: ${value}`);
|
|
25707
|
-
source = value;
|
|
25708
|
-
break;
|
|
25709
|
-
}
|
|
25710
25801
|
case "--q":
|
|
25711
25802
|
case "--query":
|
|
25712
25803
|
query = requireValue11(rest, token);
|
|
25713
25804
|
break;
|
|
25805
|
+
case "--search":
|
|
25806
|
+
search = requireValue11(rest, token);
|
|
25807
|
+
break;
|
|
25714
25808
|
case "--limit":
|
|
25715
25809
|
limit = parsePositiveInt2(requireValue11(rest, token), token);
|
|
25716
25810
|
break;
|
|
25811
|
+
case "--json":
|
|
25812
|
+
json = true;
|
|
25813
|
+
break;
|
|
25814
|
+
case "--text":
|
|
25815
|
+
json = false;
|
|
25816
|
+
break;
|
|
25717
25817
|
default:
|
|
25718
25818
|
throw new Error(`Unknown im1 threads option: ${token}`);
|
|
25719
25819
|
}
|
|
25720
25820
|
}
|
|
25721
|
-
return { type: "collect" /* Collect */, action: "threads",
|
|
25821
|
+
return { type: "collect" /* Collect */, action: "threads", query, search, limit, json };
|
|
25722
25822
|
}
|
|
25723
25823
|
function parseIm1MessagesArgs(tokens) {
|
|
25724
25824
|
const rest = [...tokens];
|
|
25725
25825
|
let thread;
|
|
25726
25826
|
let limit;
|
|
25727
|
-
let
|
|
25827
|
+
let json = true;
|
|
25728
25828
|
while (rest.length > 0) {
|
|
25729
25829
|
const token = rest.shift();
|
|
25730
25830
|
switch (token) {
|
|
25731
|
-
case "--source": {
|
|
25732
|
-
const value = requireValue11(rest, token);
|
|
25733
|
-
if (value !== "cc") throw new Error(`Unsupported im1 messages source: ${value}`);
|
|
25734
|
-
source = value;
|
|
25735
|
-
break;
|
|
25736
|
-
}
|
|
25737
25831
|
case "--thread":
|
|
25738
25832
|
case "--channel":
|
|
25739
25833
|
thread = requireValue11(rest, token);
|
|
@@ -25741,6 +25835,12 @@ function parseIm1MessagesArgs(tokens) {
|
|
|
25741
25835
|
case "--limit":
|
|
25742
25836
|
limit = parsePositiveInt2(requireValue11(rest, token), token);
|
|
25743
25837
|
break;
|
|
25838
|
+
case "--json":
|
|
25839
|
+
json = true;
|
|
25840
|
+
break;
|
|
25841
|
+
case "--text":
|
|
25842
|
+
json = false;
|
|
25843
|
+
break;
|
|
25744
25844
|
default:
|
|
25745
25845
|
throw new Error(`Unknown im1 messages option: ${token}`);
|
|
25746
25846
|
}
|
|
@@ -25748,33 +25848,10 @@ function parseIm1MessagesArgs(tokens) {
|
|
|
25748
25848
|
if (!thread) {
|
|
25749
25849
|
throw new Error("Usage: im1 messages --thread <name|conversation-id> [--limit <n>]");
|
|
25750
25850
|
}
|
|
25751
|
-
return { type: "collect" /* Collect */, action: "messages",
|
|
25752
|
-
}
|
|
25753
|
-
function parseIm1CollectArgs(tokens) {
|
|
25754
|
-
const rest = [...tokens];
|
|
25755
|
-
const action = rest.shift();
|
|
25756
|
-
if (action !== "sync") {
|
|
25757
|
-
throw new Error(
|
|
25758
|
-
"Usage: im1 collect sync [--thread <name|conversation-id>] (--source <cc|yelling> | --endpoint <url>)"
|
|
25759
|
-
);
|
|
25760
|
-
}
|
|
25761
|
-
const target = parseTargetOptions(rest);
|
|
25762
|
-
if (!target.source && !target.endpoint) {
|
|
25763
|
-
throw new Error(
|
|
25764
|
-
"Usage: im1 collect sync [--thread <name|conversation-id>] (--source <cc|yelling> | --endpoint <url>)"
|
|
25765
|
-
);
|
|
25766
|
-
}
|
|
25767
|
-
return {
|
|
25768
|
-
type: "collect" /* Collect */,
|
|
25769
|
-
action: "sync",
|
|
25770
|
-
source: target.source,
|
|
25771
|
-
endpoint: target.endpoint,
|
|
25772
|
-
thread: target.thread
|
|
25773
|
-
};
|
|
25851
|
+
return { type: "collect" /* Collect */, action: "messages", thread, limit, json };
|
|
25774
25852
|
}
|
|
25775
25853
|
function parseIm1ReplyArgs(tokens) {
|
|
25776
25854
|
const rest = [...tokens];
|
|
25777
|
-
const targetTokens = [];
|
|
25778
25855
|
let thread;
|
|
25779
25856
|
let text;
|
|
25780
25857
|
let dryRun = false;
|
|
@@ -25791,61 +25868,21 @@ function parseIm1ReplyArgs(tokens) {
|
|
|
25791
25868
|
case "--dry-run":
|
|
25792
25869
|
dryRun = true;
|
|
25793
25870
|
break;
|
|
25794
|
-
case "--source":
|
|
25795
|
-
case "--endpoint":
|
|
25796
|
-
targetTokens.push(token, requireValue11(rest, token));
|
|
25797
|
-
break;
|
|
25798
25871
|
default:
|
|
25799
25872
|
throw new Error(`Unknown im1 reply option: ${token}`);
|
|
25800
25873
|
}
|
|
25801
25874
|
}
|
|
25802
25875
|
if (!thread || !text) {
|
|
25803
|
-
throw new Error("Usage: im1 reply --thread <name> --text <text>
|
|
25804
|
-
}
|
|
25805
|
-
const target = parseTargetOptions(targetTokens);
|
|
25806
|
-
if (!target.source && !target.endpoint) {
|
|
25807
|
-
throw new Error("Usage: im1 reply --thread <name> --text <text> (--source <cc|yelling> | --endpoint <url>)");
|
|
25876
|
+
throw new Error("Usage: im1 reply --thread <name|conversation-id> --text <text>");
|
|
25808
25877
|
}
|
|
25809
25878
|
return {
|
|
25810
25879
|
type: "collect" /* Collect */,
|
|
25811
25880
|
action: "reply",
|
|
25812
|
-
source: target.source,
|
|
25813
|
-
endpoint: target.endpoint,
|
|
25814
25881
|
thread,
|
|
25815
25882
|
text,
|
|
25816
25883
|
dryRun
|
|
25817
25884
|
};
|
|
25818
25885
|
}
|
|
25819
|
-
function parseTargetOptions(tokens) {
|
|
25820
|
-
const rest = [...tokens];
|
|
25821
|
-
const options = {};
|
|
25822
|
-
while (rest.length > 0) {
|
|
25823
|
-
const token = rest.shift();
|
|
25824
|
-
switch (token) {
|
|
25825
|
-
case "--source": {
|
|
25826
|
-
const value = requireValue11(rest, token);
|
|
25827
|
-
if (value !== "cc" && value !== "yelling") {
|
|
25828
|
-
throw new Error(`Unsupported im1 source: ${value}`);
|
|
25829
|
-
}
|
|
25830
|
-
options.source = value;
|
|
25831
|
-
break;
|
|
25832
|
-
}
|
|
25833
|
-
case "--endpoint":
|
|
25834
|
-
options.endpoint = requireValue11(rest, token);
|
|
25835
|
-
break;
|
|
25836
|
-
case "--thread":
|
|
25837
|
-
case "--channel":
|
|
25838
|
-
options.thread = requireValue11(rest, token);
|
|
25839
|
-
break;
|
|
25840
|
-
default:
|
|
25841
|
-
throw new Error(`Unknown im1 option: ${token}`);
|
|
25842
|
-
}
|
|
25843
|
-
}
|
|
25844
|
-
if (options.source && options.endpoint) {
|
|
25845
|
-
throw new Error("Use either --source or --endpoint, not both.");
|
|
25846
|
-
}
|
|
25847
|
-
return options;
|
|
25848
|
-
}
|
|
25849
25886
|
function requireValue11(tokens, optionName) {
|
|
25850
25887
|
const value = tokens.shift();
|
|
25851
25888
|
if (!value || value.startsWith("--")) {
|
|
@@ -26081,11 +26118,10 @@ var HELP_TEXT = [
|
|
|
26081
26118
|
` ${import_chalk4.default.gray(" [--count <n>]")}`,
|
|
26082
26119
|
` ${import_chalk4.default.gray(" --easy [--words <n>] [--digits <n>] [--separator <s>] [--count <n>]")}`,
|
|
26083
26120
|
` ${import_chalk4.default.cyan("im1")} Read and reply to local CC messages through cc-bot`,
|
|
26084
|
-
` ${import_chalk4.default.gray(" health")}`,
|
|
26085
|
-
` ${import_chalk4.default.gray(" threads [--q <keyword>] [--limit <n>]")}`,
|
|
26086
|
-
` ${import_chalk4.default.gray(" messages --thread <name|conversation-id> [--limit <n>]")}`,
|
|
26087
|
-
` ${import_chalk4.default.gray("
|
|
26088
|
-
` ${import_chalk4.default.gray(" reply --thread <name> --text <text> (--source <cc|yelling> | --endpoint <url>)")}`,
|
|
26121
|
+
` ${import_chalk4.default.gray(" health [--json]")}`,
|
|
26122
|
+
` ${import_chalk4.default.gray(" threads [--q <keyword>] [--search <title>] [--limit <n>] [--json|--text]")}`,
|
|
26123
|
+
` ${import_chalk4.default.gray(" messages --thread <name|conversation-id> [--limit <n>] [--json|--text]")}`,
|
|
26124
|
+
` ${import_chalk4.default.gray(" reply --thread <name|conversation-id> --text <text> [--dryrun]")}`,
|
|
26089
26125
|
` ${import_chalk4.default.cyan("collect")} Legacy alias for CC/yelling collection`,
|
|
26090
26126
|
` ${import_chalk4.default.gray(" sync [--thread <name|conversation-id>] (--source <cc|yelling> | --endpoint <url>)")}`,
|
|
26091
26127
|
` ${import_chalk4.default.cyan("chat-room")} Run social chat regression commands with PMate bot key JSON`,
|