@wirecat/cli-core 0.461.0 → 0.462.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
|
@@ -7,6 +7,25 @@ shape of this file.
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.462.0 — 27.10.2026
|
|
11
|
+
|
|
12
|
+
### Changed — may break callers
|
|
13
|
+
|
|
14
|
+
- **`skill show`, `skill status` and `skill install` answer `--json` in the one-thing envelope**
|
|
15
|
+
([WC-OUT-4](https://github.com/WireCatLabs/cli-base/blob/main/docs/standards/output.md#wc-out-4--answer-every-json-request-with-one-envelope-a-list-or-one-thing)),
|
|
16
|
+
`{ item, meta }`, and `--jsonl` as one item line and the end line, like every other command and as their declared
|
|
17
|
+
output schema already said; they printed the bare object. MCP tool answers change the same way. `commands --json`
|
|
18
|
+
does not change. A caller reads the old fields under `item`: the `install/windows.ps1` installers of tg-cli, max-cli
|
|
19
|
+
and whatsapp-cli read `$skill.written`, and tests in tg-cli (`src/archive.test.ts`), max-cli
|
|
20
|
+
(`src/commands/skill.test.ts`) and cli-template (`src/roots.test.ts`) read the bare shape.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **An empty `messages` search no longer suggests `messages sync --all --background`.** `coverage.next` and the
|
|
25
|
+
`messages.sync` step now name one chat (`<cli> messages sync <chat>`: the selected chat, or the most active one
|
|
26
|
+
that was never fetched or is behind), and the search help says to offer it and run it only after the owner
|
|
27
|
+
approves. A sync downloads from the owner's account, so an agent must not start an unbounded one on its own.
|
|
28
|
+
|
|
10
29
|
## 0.461.0 — 27.10.2026
|
|
11
30
|
|
|
12
31
|
### Changed — may break callers
|
|
@@ -43,9 +43,9 @@ export const messagesSearchCommand = (messenger) => {
|
|
|
43
43
|
.option("--timezone <zone>", "the IANA timezone for calendar date boundaries")
|
|
44
44
|
.addHelpText("after", SAVE_HELP)
|
|
45
45
|
.addHelpText("after", `${syncsFirst(messenger)
|
|
46
|
-
? `Search reads the local archive: a chat never fetched is not searched.
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
? `Search reads the local archive: a chat never fetched is not searched. The answer's coverage says what was
|
|
47
|
+
searched and coverage.next names one chat that would improve it. A sync downloads from the owner's account, so
|
|
48
|
+
offer \`${messenger.app.command} messages sync <chat>\` and run it only once the owner approves.`
|
|
49
49
|
: `Search reads the local archive: what \`${messenger.app.command} serve\` has kept since the account was linked.
|
|
50
50
|
Keep serve running so new messages are searchable.`} Notes are
|
|
51
51
|
\`${messenger.app.command} search notes\`, messages and notes at once \`${messenger.app.command} search all\`; for mail,
|
|
@@ -72,12 +72,9 @@ export const coverageGaps = (found, shown) => {
|
|
|
72
72
|
const stale = found.refreshed?.complete === false;
|
|
73
73
|
if (!coverage?.next && !stale)
|
|
74
74
|
return { next: [], missing: [] };
|
|
75
|
+
const chat = coverage?.chat ?? coverage?.attention[0]?.chatId;
|
|
75
76
|
return {
|
|
76
|
-
next: [
|
|
77
|
-
nextStep("messages.sync", {
|
|
78
|
-
args: coverage?.chat === undefined ? { all: true, background: true } : { chat: coverage.chat },
|
|
79
|
-
}),
|
|
80
|
-
],
|
|
77
|
+
next: chat === undefined ? [] : [nextStep("messages.sync", { args: { chat } })],
|
|
81
78
|
missing: [
|
|
82
79
|
{
|
|
83
80
|
field: "coverage",
|
|
@@ -2,6 +2,7 @@ import { annotate } from "@wirecat/cli-base/commands";
|
|
|
2
2
|
import { skillCommand as sharedSkillCommand } from "@wirecat/cli-base/skill";
|
|
3
3
|
import { environmentOf, outputFor } from "./context.js";
|
|
4
4
|
import { grantsAuthority } from "./effects.js";
|
|
5
|
+
import { printItem } from "./envelope.js";
|
|
5
6
|
/**
|
|
6
7
|
* `skill show` and `skill install`. `skill` is the CLI's own SKILL.md, shipped beside `dist/` in the
|
|
7
8
|
* package and in a checkout alike, so the skill printed is always this version's.
|
|
@@ -9,7 +10,10 @@ import { grantsAuthority } from "./effects.js";
|
|
|
9
10
|
export const skillCommand = (app, skill) => {
|
|
10
11
|
const command = sharedSkillCommand(app, skill, (command) => {
|
|
11
12
|
const { env } = environmentOf(command);
|
|
12
|
-
|
|
13
|
+
const output = outputFor(command);
|
|
14
|
+
// cli-base prints each answer bare; the envelope is cli-core's.
|
|
15
|
+
const renderer = { ...output.renderer, result: (value) => printItem(output, value) };
|
|
16
|
+
return { ...output, renderer, ...(env ? { env } : {}) };
|
|
13
17
|
}, SHARED_SKILLS);
|
|
14
18
|
// An installed skill is instructions every later agent follows.
|
|
15
19
|
const install = command.commands.find((sub) => sub.name() === "install");
|
|
@@ -235,12 +235,9 @@ export const coverageOf = async (store, { scopeAccounts, selectedChat }, messeng
|
|
|
235
235
|
const completeness = [];
|
|
236
236
|
const stats = new Map();
|
|
237
237
|
let inventoryComplete = scopeAccounts.length > 0;
|
|
238
|
-
let ownInventory = true;
|
|
239
238
|
for (const selected of scopeAccounts) {
|
|
240
239
|
if (!(await store.sync.syncState(selected, CHAT_LIST_KEY))) {
|
|
241
240
|
inventoryComplete = false;
|
|
242
|
-
if (messenger.provider === undefined || selected.provider === messenger.provider)
|
|
243
|
-
ownInventory = false;
|
|
244
241
|
}
|
|
245
242
|
const chatIds = selectedChat
|
|
246
243
|
? selected.provider === selectedChat.account.provider && selected.account === selectedChat.account.account
|
|
@@ -274,15 +271,11 @@ export const coverageOf = async (store, { scopeAccounts, selectedChat }, messeng
|
|
|
274
271
|
const behindCount = own.filter(behind).length;
|
|
275
272
|
// A chat held back to a window stays partial for good, so only what a fetch would change is advised.
|
|
276
273
|
const command = messenger.app?.command;
|
|
277
|
-
|
|
274
|
+
// One named chat, never `--all`: a download is the owner's call and stays bounded to what they approve.
|
|
275
|
+
const syncChat = selectedChat ? (neverFetched || behindCount ? selectedChat : null) : (attention[0] ?? null);
|
|
276
|
+
const next = command === undefined || !syncChat || !syncsOneChat(messenger)
|
|
278
277
|
? null
|
|
279
|
-
:
|
|
280
|
-
? (neverFetched || behindCount) && syncsOneChat(messenger)
|
|
281
|
-
? `${command} messages sync ${selectedChat.chatId}`
|
|
282
|
-
: null
|
|
283
|
-
: (neverFetched || behindCount || !ownInventory) && messenger.history !== "store"
|
|
284
|
-
? `${command} messages sync --all --background`
|
|
285
|
-
: null;
|
|
278
|
+
: `${command} messages sync ${syncChat.chatId}`;
|
|
286
279
|
const state = selectedChat && completeness.length > 0 && completeness.every(({ state }) => state === "complete")
|
|
287
280
|
? "complete"
|
|
288
281
|
: completeness.some(({ state }) => state !== "unknown")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.462.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",
|