@wirecat/cli-core 0.397.0 → 0.398.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 +41 -0
- package/README.md +12 -9
- package/dist/cli/bot/admins.js +2 -2
- package/dist/cli/bot/command.js +2 -2
- package/dist/cli/bot/setup.js +3 -3
- package/dist/cli/commands-command.js +1 -1
- package/dist/cli/config-command.js +1 -1
- package/dist/cli/guide.js +0 -1
- package/dist/cli/help/command-help.d.ts +9 -2
- package/dist/cli/help/command-help.js +22 -4
- package/dist/cli/help/first-screen.js +3 -3
- package/dist/cli/messenger/account-command.js +2 -1
- package/dist/cli/messenger/archive-commands.js +2 -2
- package/dist/cli/messenger/backfill-command.js +3 -3
- package/dist/cli/messenger/catch-up-answers.d.ts +2 -0
- package/dist/cli/messenger/catch-up-answers.js +5 -1
- package/dist/cli/messenger/chats-command.js +2 -1
- package/dist/cli/messenger/complete-command.js +5 -1
- package/dist/cli/messenger/contacts-command.js +2 -1
- package/dist/cli/messenger/context.d.ts +5 -0
- package/dist/cli/messenger/doctor-command.js +2 -2
- package/dist/cli/messenger/flood-command.js +1 -1
- package/dist/cli/messenger/inbox.js +1 -0
- package/dist/cli/messenger/lacks.d.ts +7 -0
- package/dist/cli/messenger/lacks.js +18 -1
- package/dist/cli/messenger/media-archive-move-command.js +0 -1
- package/dist/cli/messenger/media-archive-timer-command.js +2 -2
- package/dist/cli/messenger/messages-command.js +2 -1
- package/dist/cli/messenger/models-command.js +5 -2
- package/dist/cli/messenger/replies-command.js +1 -1
- package/dist/cli/messenger/review.js +7 -2
- package/dist/cli/messenger/schedule-command.js +3 -3
- package/dist/cli/messenger/search-command.js +2 -2
- package/dist/cli/messenger/serve-command.js +5 -1
- package/dist/cli/messenger/serve-relay.d.ts +1 -0
- package/dist/cli/messenger/server-command.js +12 -3
- package/dist/cli/messenger/store-maintenance-command.js +3 -3
- package/dist/cli/messenger/watch-command.js +5 -1
- package/dist/cli/runs/command.js +2 -3
- package/dist/cli/skill-command.js +1 -1
- package/dist/domain/models.d.ts +2 -0
- package/dist/services/deps.d.ts +1 -1
- package/dist/services/deps.js +1 -1
- package/dist/services/inbox.js +5 -5
- package/dist/services/search-kind.js +1 -1
- package/package.json +2 -2
- package/parity.json +66 -192
|
@@ -58,7 +58,7 @@ const modelLine = (item, width) => `${item.default ? "*" : " "} ${item.id.padEnd
|
|
|
58
58
|
(item.downloaded ? "downloaded" : "—".padEnd(10));
|
|
59
59
|
export const modelsCommand = (messenger) => {
|
|
60
60
|
const tool = `${messenger.app.command} personal`;
|
|
61
|
-
const models =
|
|
61
|
+
const models = new Command("models").description("models that run on this machine");
|
|
62
62
|
const audio = models.command("audio").description("speech models for transcribing voice messages");
|
|
63
63
|
withQuery(annotate(audio.command("list"), { effects: LOCAL_READ, examples: [`${tool} models audio list`] }), MODELS_QUERY)
|
|
64
64
|
.summary("speech models and their download status")
|
|
@@ -76,6 +76,7 @@ export const modelsCommand = (messenger) => {
|
|
|
76
76
|
});
|
|
77
77
|
});
|
|
78
78
|
reachesOtherService(annotate(audio.command("download"), {
|
|
79
|
+
mcp: false,
|
|
79
80
|
effects: FETCH,
|
|
80
81
|
output: { entity: "model" },
|
|
81
82
|
examples: [`${tool} models audio download parakeet-v3`],
|
|
@@ -123,6 +124,7 @@ export const modelsCommand = (messenger) => {
|
|
|
123
124
|
});
|
|
124
125
|
});
|
|
125
126
|
reachesOtherService(annotate(text.command("download"), {
|
|
127
|
+
mcp: false,
|
|
126
128
|
effects: FETCH,
|
|
127
129
|
output: { entity: "model" },
|
|
128
130
|
examples: [`${tool} models text download ${DEFAULT_TEXT_MODEL}`],
|
|
@@ -171,7 +173,7 @@ export const modelsCommand = (messenger) => {
|
|
|
171
173
|
/** `images models`: registered with picture search, the only thing these models serve. */
|
|
172
174
|
export const imageModelsCommand = (messenger) => {
|
|
173
175
|
const tool = messenger.app.command;
|
|
174
|
-
const image =
|
|
176
|
+
const image = new Command("models").description("models that read pictures, for `images embed` and picture search");
|
|
175
177
|
withQuery(annotate(image.command("list"), { effects: LOCAL_READ, examples: [`${tool} images models list`] }), MODELS_QUERY)
|
|
176
178
|
.description("the picture models, which are downloaded, and which one is the default")
|
|
177
179
|
.action(async function (words) {
|
|
@@ -187,6 +189,7 @@ export const imageModelsCommand = (messenger) => {
|
|
|
187
189
|
});
|
|
188
190
|
});
|
|
189
191
|
reachesOtherService(annotate(image.command("download"), {
|
|
192
|
+
mcp: false,
|
|
190
193
|
effects: FETCH,
|
|
191
194
|
output: { entity: "model" },
|
|
192
195
|
examples: [`${tool} images models download ${DEFAULT_IMAGE_MODEL}`],
|
|
@@ -14,7 +14,7 @@ import { replyConsentsCommand } from "./replies-consents-command.js";
|
|
|
14
14
|
import { addReplyEditors } from "./replies-edit-command.js";
|
|
15
15
|
/** `replies`: rules that answer messages for the owner, from `serve`, and only to the people and chats the audience allows. */
|
|
16
16
|
export const repliesCommand = (messenger) => {
|
|
17
|
-
const replies =
|
|
17
|
+
const replies = new Command("replies").description("rules that answer messages for you, kept in a file of this profile");
|
|
18
18
|
if (messenger.autoReplies === false)
|
|
19
19
|
replies.hook("preAction", () => {
|
|
20
20
|
throw new CliError("validation_error", `${messenger.name ?? messenger.app.command} cannot send automatic replies`);
|
|
@@ -10,7 +10,7 @@ import { REMOTE_READ } from "../effects.js";
|
|
|
10
10
|
import { renderAnswer } from "../envelope.js";
|
|
11
11
|
import { queryHelp } from "../list-query.js";
|
|
12
12
|
import { pointsOf } from "./catch-up.js";
|
|
13
|
-
import { catchUpQuery, REVIEW_QUERY, reviewAnswer } from "./catch-up-answers.js";
|
|
13
|
+
import { catchUpQuery, OFFLINE_REVIEW, REVIEW_QUERY, reviewAnswer } from "./catch-up-answers.js";
|
|
14
14
|
import { messengerContext } from "./context.js";
|
|
15
15
|
import { heardItems, hearForCommand, MODEL_OPTION, spokenItems, TRANSCRIBE_OPTION } from "./hearing-command.js";
|
|
16
16
|
import { PARTIAL_NOTE } from "./inbox.js";
|
|
@@ -25,6 +25,7 @@ export const unansweredHours = (value, flag = "--unanswered") => value === true
|
|
|
25
25
|
* tasks in the local store from what it read (`../../services/task-rules.ts`); nothing reaches the messenger.
|
|
26
26
|
*/
|
|
27
27
|
export const reviewCommand = (messenger) => annotate(new Command("review"), {
|
|
28
|
+
examples: [`${messenger.app.command} personal review "date>2h"`],
|
|
28
29
|
effects: REMOTE_READ,
|
|
29
30
|
output: { entity: "message", view: "summary" },
|
|
30
31
|
query: REVIEW_QUERY,
|
|
@@ -39,6 +40,7 @@ export const reviewCommand = (messenger) => annotate(new Command("review"), {
|
|
|
39
40
|
.option(...TRANSCRIBE_OPTION)
|
|
40
41
|
.option(...MODEL_OPTION)
|
|
41
42
|
.option("--new", "what changed since the last `review --new`, a point per chat — for scheduled runs")
|
|
43
|
+
.addHelpText("after", "With --offline it reads the local store: only what was already synced, and --new keeps its point.")
|
|
42
44
|
.addHelpText("after", "To mark a chat read, use `chats mark-read <chat>`. The other side sees it.")
|
|
43
45
|
.action(async function (query) {
|
|
44
46
|
const options = this.opts();
|
|
@@ -99,7 +101,8 @@ export const reviewCommand = (messenger) => annotate(new Command("review"), {
|
|
|
99
101
|
.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp));
|
|
100
102
|
return read.length === 0 ? "" : renderMessages(spokenItems(read, hearing), viewOf(context, messenger));
|
|
101
103
|
});
|
|
102
|
-
|
|
104
|
+
if (!found.offline)
|
|
105
|
+
saved?.save(found.checked ?? {});
|
|
103
106
|
});
|
|
104
107
|
/** What the answer's steps do not say: a person's context for the review just shown. */
|
|
105
108
|
const notes = (found, pretty, renderer) => {
|
|
@@ -111,6 +114,8 @@ const notes = (found, pretty, renderer) => {
|
|
|
111
114
|
(found.tasks.review > 0 ? `, ${found.tasks.review} pair(s) to review — tasks duplicates` : ""));
|
|
112
115
|
if (found.partial && pretty)
|
|
113
116
|
renderer.warn(PARTIAL_NOTE);
|
|
117
|
+
if (found.offline && pretty)
|
|
118
|
+
renderer.warn(OFFLINE_REVIEW);
|
|
114
119
|
if (found.unanswered)
|
|
115
120
|
renderer.note(`questions from ${found.since} to ${found.until} still open after ${found.unanswered.olderThanHours} hours; ` +
|
|
116
121
|
"an answer after the review's end is not seen");
|
|
@@ -61,7 +61,7 @@ const withWhen = (command) => command
|
|
|
61
61
|
*/
|
|
62
62
|
export const scheduleCommand = (messenger) => {
|
|
63
63
|
const { app } = messenger;
|
|
64
|
-
const command =
|
|
64
|
+
const command = new Command("schedule").description(`run a ${app.command} command or an agent later or on a timer (systemd, launchd, Task Scheduler); an agent cannot send`);
|
|
65
65
|
const prepare = (self) => {
|
|
66
66
|
const context = messengerContext(self, messenger);
|
|
67
67
|
const system = environmentOf(self).system ?? thisMachine();
|
|
@@ -192,7 +192,7 @@ export const scheduleCommand = (messenger) => {
|
|
|
192
192
|
.join("\n");
|
|
193
193
|
});
|
|
194
194
|
});
|
|
195
|
-
annotate(command.command("run"), { effects: REMOTE_WRITE })
|
|
195
|
+
annotate(command.command("run"), { effects: REMOTE_WRITE, mcp: false })
|
|
196
196
|
.description("run a schedule now, as its timer would, and wait for it")
|
|
197
197
|
.argument("<name>")
|
|
198
198
|
.action(async function (name) {
|
|
@@ -216,7 +216,7 @@ export const scheduleCommand = (messenger) => {
|
|
|
216
216
|
rmSync(file, { force: true });
|
|
217
217
|
say({ name, removed: true }, [`Removed ${name}.`]);
|
|
218
218
|
});
|
|
219
|
-
annotate(command.command("exec"), { effects: REMOTE_WRITE })
|
|
219
|
+
annotate(command.command("exec"), { effects: REMOTE_WRITE, mcp: false })
|
|
220
220
|
.description("what a timer runs, given the schedule's file; to run one by hand, use run")
|
|
221
221
|
.argument("<file>")
|
|
222
222
|
.action(async function (file) {
|
|
@@ -36,8 +36,8 @@ const allCommand = (messenger) => {
|
|
|
36
36
|
const command = annotate(new Command("all"), { effects: REMOTE_READ, partial: true })
|
|
37
37
|
.summary("search stored messages, notes and selected meeting transcripts")
|
|
38
38
|
.description((messenger.serverSearch
|
|
39
|
-
? "search messenger messages and notes in the local store, and the messenger's server for
|
|
40
|
-
"(--backend
|
|
39
|
+
? "search messenger messages and notes in the local store, and by default the messenger's server for " +
|
|
40
|
+
"messages too (notes are local only; --backend archive or --offline keeps it to the local store)"
|
|
41
41
|
: "search messenger messages and notes in the local store") +
|
|
42
42
|
", and a meeting account's transcripts when --source names one — best match first; not mail (the separate memo CLI searches it: memo search mail), " +
|
|
43
43
|
"tasks, people, memories or projects. Use it when you do not know where something was written; search messages " +
|
|
@@ -30,7 +30,11 @@ export { lockPath, readLock, servingProfiles } from "../../background/lock.js";
|
|
|
30
30
|
* taken over. Started by a person, a service unit or `server start` — never by itself (NEED-9).
|
|
31
31
|
*/
|
|
32
32
|
export const serveCommand = (messenger) => {
|
|
33
|
-
const command = annotate(new Command("serve"), {
|
|
33
|
+
const command = annotate(new Command("serve"), {
|
|
34
|
+
effects: REMOTE_WRITE,
|
|
35
|
+
lifetime: "persistent",
|
|
36
|
+
examples: [`${messenger.app.command} personal serve`],
|
|
37
|
+
}).description("keep the local store current until stopped — what a systemd or launchd unit runs");
|
|
34
38
|
command.action(async function () {
|
|
35
39
|
const relay = messenger.connection === "exclusive" && process.platform !== "win32" ? serveRelay(this, messenger) : undefined;
|
|
36
40
|
const context = recordDiagnostics(messengerContext(this, relay?.messenger ?? messenger), messenger.app);
|
|
@@ -51,6 +51,7 @@ export declare const serveRelay: (command: Command, messenger: Messenger) => {
|
|
|
51
51
|
scheduledSends?: boolean;
|
|
52
52
|
autoReplies?: boolean;
|
|
53
53
|
lacks?: readonly (keyof MessengerAdapter)[];
|
|
54
|
+
never?: readonly (keyof MessengerAdapter)[];
|
|
54
55
|
deleteForMe?: boolean;
|
|
55
56
|
topics?: boolean;
|
|
56
57
|
topicShow?: boolean;
|
|
@@ -60,7 +60,7 @@ const lockProcess = (app, marker, serveArgv) => (context, system, logPath) => ({
|
|
|
60
60
|
*/
|
|
61
61
|
export const serverCommand = (messenger, options = {}) => {
|
|
62
62
|
const { app } = messenger;
|
|
63
|
-
const command =
|
|
63
|
+
const command = new Command("server")
|
|
64
64
|
.summary("manage this profile's background server")
|
|
65
65
|
.description(`\`${app.command} serve\` in the background: start, stop, restart, status, logs; install adds a systemd or launchd unit`);
|
|
66
66
|
const marker = (profile) => `${app.envPrefix}_SERVER=${profile}`;
|
|
@@ -183,17 +183,26 @@ export const serverCommand = (messenger, options = {}) => {
|
|
|
183
183
|
return ["--idle", idle];
|
|
184
184
|
};
|
|
185
185
|
const withIdle = (sub) => options.idle ? sub.option("--idle <duration>", "stop after this long with nobody using it — 15m, 1h") : sub;
|
|
186
|
-
withIdle(destroysNothing(annotate(command.command("start"), {
|
|
186
|
+
withIdle(destroysNothing(annotate(command.command("start"), {
|
|
187
|
+
effects: LOCAL_WRITE,
|
|
188
|
+
mcp: false,
|
|
189
|
+
examples: [`${app.command} personal server start`],
|
|
190
|
+
}))
|
|
187
191
|
.summary("start this profile's background server")
|
|
188
192
|
.description("start serve in the background — through the unit if one is installed — and answer once it connects")).action(async function () {
|
|
189
193
|
await start(prepare(this), idleArgs(this));
|
|
190
194
|
});
|
|
191
|
-
destroysNothing(annotate(command.command("stop"), {
|
|
195
|
+
destroysNothing(annotate(command.command("stop"), {
|
|
196
|
+
effects: LOCAL_WRITE,
|
|
197
|
+
mcp: false,
|
|
198
|
+
examples: [`${app.command} personal server stop`],
|
|
199
|
+
}))
|
|
192
200
|
.description("stop this profile's serve — through the unit if it runs under one")
|
|
193
201
|
.action(async function () {
|
|
194
202
|
await stop(prepare(this));
|
|
195
203
|
});
|
|
196
204
|
withIdle(destroysNothing(annotate(command.command("restart"), {
|
|
205
|
+
mcp: false,
|
|
197
206
|
effects: LOCAL_WRITE,
|
|
198
207
|
examples: [`${app.command} personal server restart`],
|
|
199
208
|
})).description("stop it and start it again")).action(async function () {
|
|
@@ -152,7 +152,7 @@ const copiesCommand = () => new Command("copies").description("the tables `store
|
|
|
152
152
|
const deleted = await reading(path, (database) => deleteCopy(database, name));
|
|
153
153
|
result(this, { path, deleted });
|
|
154
154
|
}));
|
|
155
|
-
const infoCommand = () => annotate(new Command("info"), { effects: LOCAL_READ
|
|
155
|
+
const infoCommand = () => annotate(new Command("info"), { effects: LOCAL_READ })
|
|
156
156
|
.summary("the local archive's format, size and contents")
|
|
157
157
|
.description("the store file: where it is, its size, its schema and how many rows it holds; changes nothing")
|
|
158
158
|
.action(async function () {
|
|
@@ -182,7 +182,7 @@ const infoCommand = () => annotate(new Command("info"), { effects: LOCAL_READ, m
|
|
|
182
182
|
* fetched" (NEED-399 A). Times are the chat's newest message by the messenger's list against the
|
|
183
183
|
* newest message held, not `sync_ranges`: those are in message ids, which a chat list does not give.
|
|
184
184
|
*/
|
|
185
|
-
const checkCommand = (messenger) => annotate(new Command("check"), { effects: LOCAL_READ
|
|
185
|
+
const checkCommand = (messenger) => annotate(new Command("check"), { effects: LOCAL_READ })
|
|
186
186
|
.summary("check the local archive for problems")
|
|
187
187
|
.description("whether the store is healthy — integrity, search indexes, disk, and which chats are behind")
|
|
188
188
|
.action(async function () {
|
|
@@ -431,7 +431,7 @@ const buildNoteIndex = (database, note, { reset = false } = {}) => {
|
|
|
431
431
|
note(`indexing ${pending} notes`);
|
|
432
432
|
return { notesIndexed: drainNoteIndex(database, stemmerCache()) };
|
|
433
433
|
};
|
|
434
|
-
const reindexCommand = (messenger) => destroysNothing(annotate(new Command("reindex"), { effects: LOCAL_WRITE
|
|
434
|
+
const reindexCommand = (messenger) => destroysNothing(annotate(new Command("reindex"), { effects: LOCAL_WRITE }))
|
|
435
435
|
.summary("rebuild the local archive's search indexes")
|
|
436
436
|
.description("rebuild the word index, its typo vocabulary, the stems, the files' word index, the notes' indexes and who took part in what, from what is stored; loses nothing")
|
|
437
437
|
.action(async function () {
|
|
@@ -11,7 +11,11 @@ import { messengerContext } from "./context.js";
|
|
|
11
11
|
* for a minute is a complete answer. One `MessageHit` per line with `--jsonl`; `--json` is refused,
|
|
12
12
|
* because a stream is not one value. Nothing is marked read.
|
|
13
13
|
*/
|
|
14
|
-
export const watchCommand = (messenger) => annotate(new Command("watch"), {
|
|
14
|
+
export const watchCommand = (messenger) => annotate(new Command("watch"), {
|
|
15
|
+
effects: REMOTE_READ,
|
|
16
|
+
lifetime: "persistent",
|
|
17
|
+
examples: [`${messenger.app.command} personal watch --jsonl --timeout 30s`],
|
|
18
|
+
})
|
|
15
19
|
.summary("stream new messages until interrupted or timed out")
|
|
16
20
|
.description("print new messages as they arrive, until Ctrl-C or --timeout (either ends it normally)")
|
|
17
21
|
.option("--events", "also edits, deletions, reactions, poll votes and chat events; every line then names its event")
|
package/dist/cli/runs/command.js
CHANGED
|
@@ -20,7 +20,6 @@ export const runsCommand = (app) => {
|
|
|
20
20
|
};
|
|
21
21
|
annotate(command.command("list"), {
|
|
22
22
|
effects: LOCAL_READ,
|
|
23
|
-
mcp: false,
|
|
24
23
|
examples: [`${app.command} runs list --limit 10`],
|
|
25
24
|
})
|
|
26
25
|
.description("recorded runs, newest first")
|
|
@@ -36,7 +35,7 @@ export const runsCommand = (app) => {
|
|
|
36
35
|
if (runs.length === 0)
|
|
37
36
|
renderer.note("nothing recorded — a run is kept with `--record`, or when it fails");
|
|
38
37
|
});
|
|
39
|
-
annotate(command.command("show"), { effects: LOCAL_READ,
|
|
38
|
+
annotate(command.command("show"), { effects: LOCAL_READ, examples: [`${app.command} runs show run-101`] })
|
|
40
39
|
.argument("<run-id>", `an id from \`${app.command} runs list\``)
|
|
41
40
|
.description("one run: what it was, how it ended, and every event it logged")
|
|
42
41
|
.option("--problems", "only failed responses, warnings and crashes")
|
|
@@ -86,7 +85,7 @@ export const runsCommand = (app) => {
|
|
|
86
85
|
since_time: options.sinceTime,
|
|
87
86
|
}));
|
|
88
87
|
});
|
|
89
|
-
annotate(command.command("path"), { effects: NO_EFFECTS,
|
|
88
|
+
annotate(command.command("path"), { effects: NO_EFFECTS, examples: [`${app.command} runs path run-101`] })
|
|
90
89
|
.argument("<run-id>", `an id from \`${app.command} runs list\``)
|
|
91
90
|
.description("the directory holding one run")
|
|
92
91
|
.action(function (id) {
|
|
@@ -20,7 +20,7 @@ export const skillCommand = (app, skill) => {
|
|
|
20
20
|
const show = command.commands.find((sub) => sub.name() === "show");
|
|
21
21
|
if (show)
|
|
22
22
|
annotate(show, { examples: [`${app.command} skill show`, `${app.command} skill show follow-ups`] });
|
|
23
|
-
return
|
|
23
|
+
return command;
|
|
24
24
|
};
|
|
25
25
|
/** Skills this package ships for every CLI on it, printed by `skill show <name>`: `skills/` beside `dist/` and `src/`. */
|
|
26
26
|
const SHARED_SKILLS = {
|
package/dist/domain/models.d.ts
CHANGED
|
@@ -506,6 +506,8 @@ export interface Review {
|
|
|
506
506
|
closed: number;
|
|
507
507
|
review: number;
|
|
508
508
|
};
|
|
509
|
+
/** `--offline`: read from the local store, so it holds only what was already synced. */
|
|
510
|
+
offline?: true;
|
|
509
511
|
}
|
|
510
512
|
/** One change to who is in a chat, or to the chat itself, read from a service message. */
|
|
511
513
|
export interface ChatEvent {
|
package/dist/services/deps.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ export declare const fromStore: (deps: Pick<ServiceDeps, "offline" | "reads">) =
|
|
|
70
70
|
export declare const nothingStored: (messenger: MessengerTraits) => string;
|
|
71
71
|
/** Where a store-mode messenger's history comes from, for what it cannot do. */
|
|
72
72
|
export declare const PUSHED = "this messenger's history is read from the local store";
|
|
73
|
-
export declare const OFFLINE = "--offline answers only from what is kept locally: `chats list|show`, `messages list|show|context
|
|
73
|
+
export declare const OFFLINE = "--offline answers only from what is kept locally: `chats list|show`, `messages list|show|context`, `contacts list|show` and `review`";
|
|
74
74
|
/** Over a connection that is already open — an MCP session holds one for minutes. */
|
|
75
75
|
export declare const onlineDeps: (messenger: ServiceMessenger, adapter: MessengerAdapter, guard: SendGuard, where?: {
|
|
76
76
|
profile?: string;
|
package/dist/services/deps.js
CHANGED
|
@@ -55,7 +55,7 @@ export const fromStore = (deps) => deps.offline || deps.reads === "store";
|
|
|
55
55
|
export const nothingStored = (messenger) => `nothing stored for this chat yet — keep \`${typedCommand(messenger.app.command, "serve")}\` running`;
|
|
56
56
|
/** Where a store-mode messenger's history comes from, for what it cannot do. */
|
|
57
57
|
export const PUSHED = "this messenger's history is read from the local store";
|
|
58
|
-
export const OFFLINE = "--offline answers only from what is kept locally: `chats list|show`, `messages list|show|context
|
|
58
|
+
export const OFFLINE = "--offline answers only from what is kept locally: `chats list|show`, `messages list|show|context`, `contacts list|show` and `review`";
|
|
59
59
|
/** Over a connection that is already open — an MCP session holds one for minutes. */
|
|
60
60
|
export const onlineDeps = (messenger, adapter, guard, where = {}) => ({
|
|
61
61
|
messenger,
|
package/dist/services/inbox.js
CHANGED
|
@@ -234,7 +234,7 @@ export const reviewIn = async (adapter, { since, points, chat, kinds, all = fals
|
|
|
234
234
|
};
|
|
235
235
|
export const inboxService = (deps) => {
|
|
236
236
|
const reader = async () => {
|
|
237
|
-
if (deps.reads === "store")
|
|
237
|
+
if (deps.reads === "store" || deps.offline)
|
|
238
238
|
return storeReader(deps, await deps.store(), await deps.account());
|
|
239
239
|
const connection = await deps.connection();
|
|
240
240
|
return {
|
|
@@ -256,9 +256,7 @@ export const inboxService = (deps) => {
|
|
|
256
256
|
: newIn(from, { since, limit, all, ...only, ...(points === undefined ? {} : { points }) });
|
|
257
257
|
},
|
|
258
258
|
review: async (options) => {
|
|
259
|
-
|
|
260
|
-
throw new CliError("validation_error", "`review` asks the messenger what changed; with `--offline` nothing did");
|
|
261
|
-
}
|
|
259
|
+
const synced = deps.offline && deps.reads !== "store";
|
|
262
260
|
let tasks;
|
|
263
261
|
const found = await reviewIn(await reader(), {
|
|
264
262
|
...options,
|
|
@@ -272,7 +270,9 @@ export const inboxService = (deps) => {
|
|
|
272
270
|
});
|
|
273
271
|
},
|
|
274
272
|
});
|
|
275
|
-
|
|
273
|
+
// What was never synced may sit before `until`, so the next review must not start there.
|
|
274
|
+
const offline = synced ? { complete: false, offline: true } : {};
|
|
275
|
+
return { ...found, ...offline, ...(tasks ? { tasks } : {}) };
|
|
276
276
|
},
|
|
277
277
|
};
|
|
278
278
|
};
|
|
@@ -50,7 +50,7 @@ export const accountsOfKind = (kind, chosen, held, explicit, command = undefined
|
|
|
50
50
|
throw new CliError("validation_error", `search mail reads mail only — \`${command === undefined ? "" : `${command} `}search messages\` searches ${explicit}`);
|
|
51
51
|
const mail = (listed ? chosen : held).filter(({ provider }) => kindOf(provider) === "mail");
|
|
52
52
|
if (mail.length === 0)
|
|
53
|
-
throw new CliError("not_found", "no mail in the store yet — `memo sync --mail --since-time <time>` imports it", {
|
|
53
|
+
throw new CliError("not_found", "no mail in the store yet — `memo sync --only mail --since-time <time>` imports it", {
|
|
54
54
|
reason: NO_MAIL,
|
|
55
55
|
});
|
|
56
56
|
const address = mailAccount?.trim().toLowerCase();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.398.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",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
"@anthropic-ai/sdk": "0.131.0",
|
|
166
166
|
"@bomb.sh/tab": "0.0.22",
|
|
167
167
|
"@huggingface/tokenizers": "0.2.0",
|
|
168
|
-
"@modelcontextprotocol/server": "2.
|
|
168
|
+
"@modelcontextprotocol/server": "2.3.0",
|
|
169
169
|
"@resvg/resvg-js": "2.6.2",
|
|
170
170
|
"@valibot/to-json-schema": "1.8.0",
|
|
171
171
|
"@wirecat/cli-core-onnx": "1.0.1",
|