@wirecat/cli-core 0.445.0 → 0.447.0

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/CHANGELOG.md CHANGED
@@ -5,6 +5,30 @@ Notable changes to `@wirecat/cli-core` (`@wirecat/cli-messaging` up to 0.261.0,
5
5
  minor version may break callers, and says how under "Changed — may break callers". `pnpm docs:check` checks the
6
6
  shape of this file.
7
7
 
8
+ ## 0.447.0 — 26.10.2026
9
+
10
+ ### Added
11
+
12
+ - **The parity manifest knows `session start --answer-stdin`**, in tg and max: the flag that lets WireCat Desktop
13
+ answer a sign-in's questions on stdin (`signInSteps`, 0.443.0). WhatsApp's QR sign-in asks nothing, so wa does not
14
+ take it yet.
15
+
16
+ ### Fixed
17
+
18
+ - **`--discover`'s reranker reads only the first 300 characters of the message a hit replies to.** The parent came
19
+ first in full, and a long one filled the reranker's 512 tokens, so the hit itself was cut off and the model scored
20
+ the parent instead (18 of 119 replies in one real chat). With the parent cut, the six known questions on that
21
+ chat kept every answer in the first five, and the reranker does about 40% less work.
22
+
23
+ ## 0.446.0 — 26.10.2026
24
+
25
+ ### Fixed
26
+
27
+ - **`checkGuide` accepts a step that runs a group with an action of its own**, such as `mcp` now that it has
28
+ `mcp server`; before, it asked for one of the group's subcommands.
29
+ - **The `mcp server` group states its effects** (reads locally), as a CLI that requires effects on every command
30
+ expects.
31
+
8
32
  ## 0.445.0 — 26.10.2026
9
33
 
10
34
  ### Added
package/dist/cli/guide.js CHANGED
@@ -291,7 +291,9 @@ export const checkStep = (program, run) => {
291
291
  const beforeDashes = rest.slice(index, rest.includes("--") ? rest.indexOf("--") : undefined);
292
292
  if (help && beforeDashes.some((word) => word === help.long || word === help.short))
293
293
  return [];
294
- if (at.commands.length > 0)
294
+ // A group with an action of its own runs as typed: `mcp` serves, `mcp server start` is its child.
295
+ const runsItself = at._actionHandler != null;
296
+ if (at.commands.length > 0 && !runsItself)
295
297
  return [`needs one of: ${at.commands.map((one) => one.name()).join(", ")}`];
296
298
  for (const command of chain)
297
299
  silent(command);
@@ -46,7 +46,7 @@ const clientLines = (clients) => clients.length === 0
46
46
  * None of it is offered over MCP: status holds a live login code.
47
47
  */
48
48
  export const mcpServerCommand = ({ example, defaultPort = MCP_HTTP_DEFAULT_PORT, target, answer, system, }) => {
49
- const command = annotate(new Command("server"), { mcp: false })
49
+ const command = annotate(new Command("server"), { effects: LOCAL_READ, mcp: false })
50
50
  .summary("run the HTTP MCP server in the background")
51
51
  .description("start, stop and check `mcp --http` in the background; status shows the login code for a browser app");
52
52
  const machine = (self) => system?.(self) ?? thisMachine();
@@ -54,3 +54,11 @@ export declare const searchDiscovery: (store: MessageStore, account: AccountKey,
54
54
  export declare const nearEligible: (store: MessageStore, account: AccountKey, request: SearchQuery, messenger: Partial<Pick<MessengerTraits, "savedChatId" | "app" | "history" | "provider">>, ranked: MeaningRanked, scope: string) => Promise<(FoundMessage & {
55
55
  cosine: number;
56
56
  })[]>;
57
+ /** What the reranker reads of a hit, as the benchmark gave it: its reply parent first, each line headed by where, who and when. */
58
+ type Said = {
59
+ senderName: string | null;
60
+ timestamp: string | null;
61
+ text: string;
62
+ };
63
+ export declare const pairInput: (hit: FoundMessage, parent: Said | null | undefined) => string;
64
+ export {};
@@ -289,9 +289,14 @@ const fusedWithMeaning = (words, near, described) => {
289
289
  });
290
290
  return [...merged.values()].sort((a, b) => b.rrf - a.rrf).map(({ hit, rrf }) => ({ ...hit, score: rrf }));
291
291
  };
292
- const pairInput = (hit, parent) => {
292
+ /**
293
+ * Only the start of the parent: whole, a long one filled the model's 512 tokens and cut off the hit it was scoring
294
+ * (18 of 119 replies in one real chat). Cut to 300 characters, every answer on the six known questions stayed.
295
+ */
296
+ const PARENT_CHARACTERS = 300;
297
+ export const pairInput = (hit, parent) => {
293
298
  const line = (m) => `[${hit.chatTitle ?? hit.chatId} · ${m.senderName ?? "unknown"} · ${m.timestamp?.slice(0, 10) ?? "undated"}] ${m.text}`;
294
- return (parent ? [parent, hit] : [hit]).map(line).join("\n");
299
+ return (parent ? [line(parent).slice(0, PARENT_CHARACTERS), line(hit)] : [line(hit)]).join("\n");
295
300
  };
296
301
  const accountOfHit = (hit) => {
297
302
  const { provider, account } = parseLocator(hit.locator);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-core",
3
- "version": "0.445.0",
3
+ "version": "0.447.0",
4
4
  "description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Viacheslav Ptsarev",
package/parity.json CHANGED
@@ -68,6 +68,9 @@
68
68
  "value": "<model>",
69
69
  "meaning": "only the stored answers this model gave"
70
70
  },
71
+ "--answer-stdin": {
72
+ "meaning": "with --json and no terminal: print each question as a `needs` line on stderr and read its answer, one line, from stdin"
73
+ },
71
74
  "--answerer": {
72
75
  "value": "<person>",
73
76
  "meaning": "stored name, alias, @username, ID or scoped person locator; ambiguous names require a choice; repeat it for more"
@@ -4193,6 +4196,10 @@
4193
4196
  "session start": {
4194
4197
  "in": "all",
4195
4198
  "options": {
4199
+ "--answer-stdin": {
4200
+ "in": ["tg", "max"],
4201
+ "reason": "only tg and max ask questions during sign-in (app keys, codes, a 2FA or cloud password); WhatsApp's QR sign-in asks nothing, and its phone login is not ported to signInSteps yet"
4202
+ },
4196
4203
  "--app": {
4197
4204
  "in": ["tg"],
4198
4205
  "reason": "Telegram asks each client for its own app from my.telegram.org; MAX has no such step; WhatsApp has no application registration"