@wirecat/cli-core 0.409.0 → 0.411.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 +47 -0
- package/dist/cli/bot/command.js +1 -0
- package/dist/cli/bot/port.d.ts +1 -1
- package/dist/cli/bot/setup.js +11 -5
- package/dist/cli/commands-command.js +18 -12
- package/dist/cli/contract-evidence.d.ts +26 -0
- package/dist/cli/contract-evidence.js +58 -0
- package/dist/cli/contract-templates.d.ts +4 -0
- package/dist/cli/contract-templates.js +83 -0
- package/dist/cli/discovery-descriptions.d.ts +4 -0
- package/dist/cli/discovery-descriptions.js +4 -0
- package/dist/cli/index.d.ts +22 -55
- package/dist/cli/index.js +19 -55
- package/dist/cli/messenger/chat-answers.d.ts +1 -1
- package/dist/cli/messenger/chat-answers.js +1 -1
- package/dist/cli/messenger/chat-lists.d.ts +1 -1
- package/dist/cli/messenger/chats-command.js +3 -0
- package/dist/cli/messenger/contacts-command.js +23 -15
- package/dist/cli/messenger/guard-commands.d.ts +5 -1
- package/dist/cli/messenger/guard-commands.js +5 -3
- package/dist/cli/messenger/messages-press-command.js +4 -1
- package/dist/cli/messenger/models-command.js +3 -11
- package/dist/cli/messenger/records-command.js +1 -1
- package/dist/cli/messenger/report.d.ts +21 -6
- package/dist/cli/messenger/report.js +20 -5
- package/dist/cli/messenger/tasks-command.js +14 -4
- package/dist/cli/model-catalogue-command.d.ts +15 -0
- package/dist/cli/model-catalogue-command.js +110 -0
- package/dist/cli/program.js +2 -0
- package/dist/cli/runs/search-command.js +2 -3
- package/dist/cli/runs/search-query.d.ts +1 -1
- package/dist/cli/runs/search-query.js +18 -2
- package/dist/cli/runs/search.d.ts +2 -1
- package/dist/cli/runs/search.js +4 -3
- package/dist/cli/shared-command-exports.d.ts +644 -0
- package/dist/cli/shared-command-exports.js +114 -0
- package/dist/cli/shared-contracts.d.ts +1 -0
- package/dist/cli/shared-contracts.js +1 -0
- package/dist/domain/attachments.js +1 -0
- package/dist/entities/chat.d.ts +3 -3
- package/dist/entities/chat.js +2 -2
- package/dist/entities/contact-context.d.ts +8 -8
- package/dist/entities/contact.d.ts +4 -4
- package/dist/entities/index.d.ts +11 -12
- package/dist/entities/list-results.d.ts +1 -1
- package/dist/entities/list-results.js +1 -1
- package/dist/entities/send-attempt.d.ts +0 -1
- package/dist/entities/send-attempt.js +0 -1
- package/dist/errors/reasons.d.ts +1 -1
- package/dist/errors/reasons.js +7 -0
- package/dist/meetings/cli/index.d.ts +1 -1
- package/dist/meetings/cli/index.js +25 -9
- package/dist/meetings/cli/passage.d.ts +0 -1
- package/dist/meetings/cli/passage.js +5 -3
- package/dist/meetings/cli/project-evidence.js +3 -2
- package/dist/meetings/cli/search.d.ts +2 -2
- package/dist/meetings/cli/search.js +14 -12
- package/dist/meetings/event-query.d.ts +1 -0
- package/dist/meetings/event-query.js +15 -0
- package/dist/meetings/index.d.ts +1 -0
- package/dist/meetings/index.js +1 -0
- package/dist/meetings/store.d.ts +2 -0
- package/dist/meetings/testing/memory.js +5 -0
- package/dist/services/tasks.d.ts +2 -0
- package/dist/services/tasks.js +6 -4
- package/dist/store/sqlite/events.d.ts +2 -1
- package/dist/store/sqlite/events.js +16 -1
- package/dist/store/sqlite/meetings.js +3 -0
- package/package.json +3 -3
- package/parity.json +61 -76
package/dist/cli/index.js
CHANGED
|
@@ -32,106 +32,70 @@ export { openRequestTask } from "../services/task-rules.js";
|
|
|
32
32
|
export { TASK_PAIR_QUERY, TASK_QUERY } from "../services/tasks.js";
|
|
33
33
|
export { evaluateAgent, } from "./agent-evaluation.js";
|
|
34
34
|
export { answerEntity } from "./answer-entity.js";
|
|
35
|
-
export { botAdminsCommand, botMembersCommand } from "./bot/admins.js";
|
|
36
|
-
export { generatedApiCommand } from "./bot/api.js";
|
|
37
35
|
export { apiFlagOf, apiJson, apiOptionKey, apiPlainJson, checkApiBody, checkApiParameter, parseApiJson, readApiBody, } from "./bot/api-input.js";
|
|
38
36
|
export { prepareRpcApiBody } from "./bot/api-rpc.js";
|
|
39
|
-
export { botCommand } from "./bot/command.js";
|
|
40
37
|
export { botContext, botWords } from "./bot/context.js";
|
|
41
38
|
export { botCopy } from "./bot/copy.js";
|
|
42
|
-
export {
|
|
43
|
-
export { botCan, botIdOf, botMessagesCommand } from "./bot/messages.js";
|
|
39
|
+
export { botCan, botIdOf } from "./bot/messages.js";
|
|
44
40
|
export { BOT_ACTIONS, } from "./bot/port.js";
|
|
45
41
|
export { botFiles, botsDirectory, ChatRegistry, registryProfiles } from "./bot/registry.js";
|
|
46
42
|
export { BotTokenStore } from "./bot/token.js";
|
|
47
43
|
export { PressLog, UpdatesCursor } from "./bot/updates.js";
|
|
48
44
|
export { commandContract, SCHEMA_DIALECT } from "./command-contract.js";
|
|
49
|
-
export { CONTRACT
|
|
50
|
-
export {
|
|
45
|
+
export { CONTRACT } from "./commands-command.js";
|
|
46
|
+
export { refuseUnknownKey } from "./config-command.js";
|
|
51
47
|
export { loadSnakeCaseConfig } from "./config-keys.js";
|
|
52
48
|
export { baseContext, environmentOf, outputFor, provide, secretInputOf, } from "./context.js";
|
|
49
|
+
export { addContractInfo, contractEvidence } from "./contract-evidence.js";
|
|
50
|
+
export { sharedCommandTemplate } from "./contract-templates.js";
|
|
53
51
|
export { withDeadline } from "./deadline.js";
|
|
54
52
|
export { DEFAULT_CONFIG, ensureDefaultConfig } from "./default-config.js";
|
|
53
|
+
export { DISCOVERY_DESCRIPTIONS } from "./discovery-descriptions.js";
|
|
55
54
|
export { changesAuthority, changesAuthorityAt, changesAuthorityNow, destroysNothing, FETCH, grantsAuthority, isLogin, isOtherServiceCall, isStoreChange, judgedEffects, judgedTargets, LOCAL_READ, LOCAL_WRITE, logsInOrOut, NO_EFFECTS, ownerOnlyOption, REMOTE_READ, REMOTE_WRITE, reachesOtherService, refuseUnderReadOnly, } from "./effects.js";
|
|
56
55
|
export { answerSchema, isBody, itemAnswer, itemOf, jsonlRecords, judgedAnswer, listOf, metaNow, printItem, renderAnswer, sealed, snakeKeys, snakeKeysKeeping, } from "./envelope.js";
|
|
57
56
|
export { withAbort } from "./execution.js";
|
|
58
57
|
export { askSetupQuestions, asksAtStart, LANGUAGES, setupAtStart, systemLanguage, } from "./first-run.js";
|
|
59
|
-
export { checkGuide, checkStep,
|
|
58
|
+
export { checkGuide, checkStep, loadScenarios, MEMO_SCENARIOS, shellProblems, } from "./guide.js";
|
|
60
59
|
export { commandHelp, commandHelpMarkdown, commandHelpText, exampleReport, nextUsually, } from "./help/command-help.js";
|
|
61
60
|
export { commandsText } from "./help/commands-text.js";
|
|
62
|
-
export { firstScreen, installHelp, WIRECAT_TOOLS
|
|
61
|
+
export { firstScreen, installHelp, WIRECAT_TOOLS } from "./help/first-screen.js";
|
|
63
62
|
export { inSection, SECTIONS } from "./help/sections.js";
|
|
64
63
|
export { bufferedInput, inputPolicy, MAX_BUFFERED_INPUT, MAX_SECRET_INPUT, provideInputPolicy, } from "./input-policy.js";
|
|
65
64
|
export { answerFields, checkJson, entityFields, liftJson, } from "./json-fields.js";
|
|
66
65
|
export { commandPath, LIST_QUERY_GUIDE, listQuery, nativeField, nativeTerms, pagedList, pageOf, queryArgument, queryHelp, queryTerms, searchText, termField, timeBounds, typedQuery, unfilteredQuery, withQuery, } from "./list-query.js";
|
|
67
|
-
export {
|
|
66
|
+
export { formatMeetingBatch, prepareMeetingBatch } from "./meeting-batch.js";
|
|
68
67
|
export { meetingEvidenceItem, meetingPersonContextItem } from "./meeting-evidence-answer.js";
|
|
69
68
|
export { parseEvidenceFindingsJson, parseMeetingFindingsJson } from "./meeting-findings-input.js";
|
|
70
69
|
export { meetingPreparationAnswer } from "./meeting-preparation-answer.js";
|
|
71
|
-
export { addMeetingPreparationCommand } from "./meeting-preparation-command.js";
|
|
72
70
|
export { meetingPreparationInput, readMeetingPreparation, } from "./meeting-preparation-read.js";
|
|
73
|
-
export { addMeetingProjectCandidatesCommand } from "./meeting-project-candidates-command.js";
|
|
74
71
|
export { readMeetingProjectCandidates } from "./meeting-project-candidates-read.js";
|
|
75
72
|
export { meetingResultItem } from "./meeting-results.js";
|
|
76
|
-
export { addMeetingSeriesInventoryCommand } from "./meeting-series-inventory-command.js";
|
|
77
73
|
export { readMeetingSeriesInventory } from "./meeting-series-inventory-read.js";
|
|
78
|
-
export { accountCommand } from "./messenger/account-command.js";
|
|
79
74
|
export { accountFileFor, profilesHere, rememberAccount } from "./messenger/accounts.js";
|
|
80
|
-
export { storeCommand } from "./messenger/archive-commands.js";
|
|
81
|
-
export { attachmentsCommand } from "./messenger/attachments-command.js";
|
|
82
|
-
export { chatsCommand } from "./messenger/chats-command.js";
|
|
83
|
-
export { markReadCommand } from "./messenger/chats-read-command.js";
|
|
84
|
-
export { completeCommand } from "./messenger/complete-command.js";
|
|
85
|
-
export { contactsCommand } from "./messenger/contacts-command.js";
|
|
86
75
|
export { connectFor, messengerContext, } from "./messenger/context.js";
|
|
87
|
-
export { conversationsCommand } from "./messenger/conversations-command.js";
|
|
88
|
-
export { doctorCommand } from "./messenger/doctor-command.js";
|
|
89
|
-
export { floodCommand } from "./messenger/flood-command.js";
|
|
90
|
-
export { recipientsCommand, sendsCommand } from "./messenger/guard-commands.js";
|
|
91
|
-
export { imagesCommand } from "./messenger/images-command.js";
|
|
92
|
-
export { inboxCommand } from "./messenger/inbox.js";
|
|
93
76
|
export { COMMAND_NEEDS } from "./messenger/lacks.js";
|
|
94
|
-
export { httpTokenFile,
|
|
95
|
-
export { mentionsCommand } from "./messenger/mentions-command.js";
|
|
77
|
+
export { httpTokenFile, serverEntry } from "./messenger/mcp-command.js";
|
|
96
78
|
export { messageItem } from "./messenger/message-items.js";
|
|
97
|
-
export { messagesCommand, sendCommand } from "./messenger/messages-command.js";
|
|
98
|
-
export { deleteCommand } from "./messenger/messages-delete-command.js";
|
|
99
|
-
export { editCommand } from "./messenger/messages-edit-command.js";
|
|
100
|
-
export { forwardCommand } from "./messenger/messages-forward-command.js";
|
|
101
|
-
export { pinCommand, starCommands, unpinCommand } from "./messenger/messages-pin-command.js";
|
|
102
|
-
export { metadataCommand } from "./messenger/metadata-command.js";
|
|
103
|
-
export { modelsCommand } from "./messenger/models-command.js";
|
|
104
|
-
export { pollsCommand } from "./messenger/polls-command.js";
|
|
105
79
|
export { privateFiles, withSqliteSidecars } from "./messenger/private-files.js";
|
|
106
|
-
export {
|
|
107
|
-
export { callsCommand, stickersCommand } from "./messenger/records-command.js";
|
|
108
|
-
export { repliesCommand } from "./messenger/replies-command.js";
|
|
109
|
-
export { reviewCommand } from "./messenger/review.js";
|
|
110
|
-
export { scheduleCommand } from "./messenger/schedule-command.js";
|
|
80
|
+
export { buildReport as buildDoctorReport, reportFileName as doctorReportFileName, } from "./messenger/report.js";
|
|
111
81
|
export { allAnswer, allHitItem, messageHitItem, noteHitItem, } from "./messenger/search-answers.js";
|
|
112
|
-
export {
|
|
113
|
-
export {
|
|
114
|
-
export { serveCommand, servingProfiles } from "./messenger/serve-command.js";
|
|
82
|
+
export { SEARCHES_QUERY } from "./messenger/searches-command.js";
|
|
83
|
+
export { servingProfiles } from "./messenger/serve-command.js";
|
|
115
84
|
export { DAY_MS, FIRST_FETCH_MS, memberFetches } from "./messenger/serve-members.js";
|
|
116
85
|
export { STEMS_EVERY_MS, STEMS_SLICE_MS, stemFills } from "./messenger/serve-stems.js";
|
|
117
|
-
export { serverCommand, } from "./messenger/server-command.js";
|
|
118
|
-
export { statsCommand } from "./messenger/stats-command.js";
|
|
119
86
|
export { storeSummary } from "./messenger/store-maintenance-command.js";
|
|
120
87
|
export { stored } from "./messenger/stored.js";
|
|
121
|
-
export {
|
|
122
|
-
export { tasksCommand, tasksStatsCommand } from "./messenger/tasks-command.js";
|
|
123
|
-
export { topicsCommand } from "./messenger/topics-command.js";
|
|
124
|
-
export { watchCommand } from "./messenger/watch-command.js";
|
|
88
|
+
export { MODEL_CATALOGUE_QUERY } from "./model-catalogue-command.js";
|
|
125
89
|
export { window, withPaging } from "./paging.js";
|
|
126
|
-
export { knownBeside, knownPermissionKeys, unknownPermissionKeys
|
|
127
|
-
export { asFirstWord, commandWords, liftProfile, refuseCommandName, rootOf, usableProfileName
|
|
90
|
+
export { knownBeside, knownPermissionKeys, unknownPermissionKeys } from "./permission-keys.js";
|
|
91
|
+
export { asFirstWord, commandWords, liftProfile, refuseCommandName, rootOf, usableProfileName } from "./profile.js";
|
|
128
92
|
export { createProgram, run } from "./program.js";
|
|
129
93
|
export { fieldsOf, projectFields } from "./result-fields.js";
|
|
130
|
-
export { runsCommand } from "./runs/command.js";
|
|
131
94
|
export { count, first, flag, fromFile, NONE_NAMED, plain, settingsFor, } from "./settings.js";
|
|
132
95
|
export { readSetupAnswers, setupPermissionCeiling } from "./setup-answers.js";
|
|
133
96
|
export { AGENTS, agentFor, screenFor } from "./setup-screen.js";
|
|
134
|
-
export { skillCommand } from "./
|
|
97
|
+
export { accountCommand, addMeetingBatchCommand, addMeetingPreparationCommand, addMeetingProjectCandidatesCommand, addMeetingSeriesInventoryCommand, attachmentsCommand, botAdminsCommand, botCommand, botMcpCommand, botMembersCommand, botMessagesCommand, callsCommand, chatsCommand, commandsCommand, completeCommand, configCommand, contactsCommand, conversationsCommand, deleteCommand, doctorCommand, editCommand, floodCommand, forwardCommand, generatedApiCommand, guideCommand, imagesCommand, inboxCommand, markReadCommand, mcpCommand, mentionsCommand, messagesCommand, metadataCommand, modelCatalogueCommand, modelsCommand, pinCommand, pollsCommand, reactionsCommand, recipientsCommand, repliesCommand, reviewCommand, runsCommand, scheduleCommand, searchCommand, searchesCommand, sendCommand, sendsCommand, serveCommand, serverCommand, skillCommand, starCommands, statsCommand, stickersCommand, storeCommand, tagsCommand, tasksCommand, tasksStatsCommand, topicsCommand, unpinCommand, upgradeCommand, watchCommand, } from "./shared-command-exports.js";
|
|
98
|
+
export { assertSharedContracts, customizeSharedCommand, hasSharedContract, overrideSharedContract, sharedContractOverrides, sharedContracts, } from "./shared-contracts.js";
|
|
135
99
|
export { runnable, withSafety } from "./steps.js";
|
|
136
100
|
export { changeStoreSetting, isStoreSetting, STORE_SETTINGS, storeSettings } from "./store-settings.js";
|
|
137
|
-
export { restartServers
|
|
101
|
+
export { restartServers } from "./upgrade-command.js";
|
|
@@ -101,7 +101,7 @@ export declare const chatShown: (account: AccountKey, card: Parameters<typeof ch
|
|
|
101
101
|
check?: {
|
|
102
102
|
[x: string]: unknown;
|
|
103
103
|
} | undefined;
|
|
104
|
-
}[] |
|
|
104
|
+
}[] | undefined;
|
|
105
105
|
}>;
|
|
106
106
|
/** The lowest score `score>=n` asks for; the audit's own floor when the query names none. */
|
|
107
107
|
export declare const scoreFloor: (ast: QueryAst | undefined) => number;
|
|
@@ -38,7 +38,7 @@ export const chatAnswer = (account, chat) => defined({
|
|
|
38
38
|
description: chat.description,
|
|
39
39
|
invite_link: chat.link,
|
|
40
40
|
settings: chat.settings ? settingsOf(chat.settings) : undefined,
|
|
41
|
-
members: chat.members
|
|
41
|
+
members: chat.members?.map(memberAnswer),
|
|
42
42
|
});
|
|
43
43
|
export const memberAnswer = (member) => {
|
|
44
44
|
const group = member;
|
|
@@ -61,7 +61,7 @@ export declare const chatsList: (services: Services, query: QueryWords, paging:
|
|
|
61
61
|
check?: {
|
|
62
62
|
[x: string]: unknown;
|
|
63
63
|
} | undefined;
|
|
64
|
-
}[] |
|
|
64
|
+
}[] | undefined;
|
|
65
65
|
}>>;
|
|
66
66
|
export declare const chatEvents: (services: Services, chat: string, query: QueryWords) => Promise<import("../envelope.js").ListBody<{
|
|
67
67
|
chat_id: string;
|
|
@@ -109,6 +109,8 @@ export const chatsCommand = (messenger) => {
|
|
|
109
109
|
"admins add": `"Book club" "Alex Example"${messenger.pickAdminRights === false ? "" : ` --can ${messenger.adminRights?.[0] ?? "info"}`}`,
|
|
110
110
|
"admins remove": '"Book club" "Alex Example"',
|
|
111
111
|
create: '"Book club" "Alex Example"',
|
|
112
|
+
app: '"Example Bot"',
|
|
113
|
+
start: '"Example Bot"',
|
|
112
114
|
"documents list": '"Project room" --limit 10',
|
|
113
115
|
events: '"Book club"',
|
|
114
116
|
"folders create": '"Reading" --chat "Book club"',
|
|
@@ -125,6 +127,7 @@ export const chatsCommand = (messenger) => {
|
|
|
125
127
|
"links list": '"Book club"',
|
|
126
128
|
"links reset": '"Book club"',
|
|
127
129
|
"links remove": '"Book club" https://example.com/invite/book-club',
|
|
130
|
+
"links update": '"Book club" https://example.com/invite/book-club --max-uses 25',
|
|
128
131
|
"links show": '"Book club"',
|
|
129
132
|
list: "--limit 10",
|
|
130
133
|
"mark-read": '"Book club" --until-id 101',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
2
|
import { annotate } from "@wirecat/cli-base/commands";
|
|
3
|
+
import { defineQuery } from "@wirecat/cli-base/query";
|
|
3
4
|
import { Command } from "commander";
|
|
4
5
|
import { REGISTRIES, registriesCover } from "../../botcheck/registries.js";
|
|
5
6
|
import { levelFor } from "../../sends/permissions.js";
|
|
@@ -12,7 +13,7 @@ import { readSecret } from "../../terminal/prompt.js";
|
|
|
12
13
|
import { secretInputOf } from "../context.js";
|
|
13
14
|
import { FETCH, LOCAL_WRITE, REMOTE_READ } from "../effects.js";
|
|
14
15
|
import { itemOf, listOf, renderAnswer, snakeKeys } from "../envelope.js";
|
|
15
|
-
import { listQuery, nativeTerms, typedQuery, withQuery } from "../list-query.js";
|
|
16
|
+
import { listQuery, nativeField, nativeTerms, termField, timeBounds, typedQuery, withQuery } from "../list-query.js";
|
|
16
17
|
import { positiveCount, window, withPaging } from "../paging.js";
|
|
17
18
|
import { casKey } from "../registry-keys.js";
|
|
18
19
|
import { commandAt, nextStep } from "../steps.js";
|
|
@@ -23,6 +24,19 @@ import { hideNever } from "./lacks.js";
|
|
|
23
24
|
import { CONTACTS_QUERY, notesAllowed } from "./people-queries.js";
|
|
24
25
|
import { privatePeopleCommands } from "./private-people-command.js";
|
|
25
26
|
import { syncsFirst } from "./search-sync-options.js";
|
|
27
|
+
const CONTACT_ACTIVITY_QUERY = defineQuery({
|
|
28
|
+
entity: "contact_activity",
|
|
29
|
+
backend: "native",
|
|
30
|
+
fields: [
|
|
31
|
+
termField("scope", "enum", "scope:work", { values: SCOPES }),
|
|
32
|
+
nativeField({
|
|
33
|
+
name: "at",
|
|
34
|
+
type: "time",
|
|
35
|
+
operators: ["term", "phrase", "range"],
|
|
36
|
+
example: "at:[2026-10-01 TO 2026-10-31]",
|
|
37
|
+
}),
|
|
38
|
+
],
|
|
39
|
+
});
|
|
26
40
|
/** People this account has a one-to-one chat with, as the people service counts them. */
|
|
27
41
|
const collect = (value, previous = []) => [...previous, value];
|
|
28
42
|
export const contactsCommand = (messenger) => {
|
|
@@ -173,28 +187,24 @@ export const contactsCommand = (messenger) => {
|
|
|
173
187
|
meta: { ...window.meta, ...(hasMore ? { truncated: true } : {}) },
|
|
174
188
|
}));
|
|
175
189
|
});
|
|
176
|
-
annotate(contacts.command("events"), {
|
|
190
|
+
withQuery(annotate(contacts.command("events"), {
|
|
177
191
|
effects: REMOTE_READ,
|
|
178
192
|
output: { entity: "contact_activity" },
|
|
179
193
|
})
|
|
180
194
|
.summary("one person's activity across their linked identities")
|
|
181
195
|
.description("everything one person took part in, in every messenger linked to them — messages they wrote or were " +
|
|
182
196
|
"mentioned in, chats, mail, meetings, tasks — newest first, from the store; never connects")
|
|
183
|
-
.argument("<person>", "their id, @username, or part of their name")
|
|
184
|
-
.option("--scope <scope>", "only what belongs to personal or to work accounts: personal or work")
|
|
185
|
-
.option("--since-time <time>", "nothing older than this ISO 8601 time, or 2h / 1d ago")
|
|
186
|
-
.option("--until-time <time>", "through this ISO 8601 time, or 2h / 1d ago")
|
|
197
|
+
.argument("<person>", "their id, @username, or part of their name"), CONTACT_ACTIVITY_QUERY)
|
|
187
198
|
.option("--limit <n>", `at most this many; ${TIMELINE_ITEMS} if not given`, positiveCount("--limit"))
|
|
188
199
|
.option("--cursor <cursor>", "go on from where the last page stopped; page.next gives it, with the same filters")
|
|
189
|
-
.action(async function (person) {
|
|
190
|
-
const
|
|
200
|
+
.action(async function (person, words) {
|
|
201
|
+
const terms = nativeTerms(listQuery(typedQuery(words), CONTACT_ACTIVITY_QUERY, "contacts events"), "contacts events");
|
|
202
|
+
const scope = terms.get("scope")?.value.toLowerCase();
|
|
203
|
+
const { limit, cursor } = this.opts();
|
|
191
204
|
if (scope !== undefined && !SCOPES.includes(scope))
|
|
192
205
|
throw new CliError("validation_error", `--scope is personal or work, not "${scope}"`);
|
|
193
206
|
const context = messengerContext(this, messenger);
|
|
194
|
-
const window =
|
|
195
|
-
...(sinceTime === undefined ? {} : { sinceTime }),
|
|
196
|
-
...(untilTime === undefined ? {} : { untilTime }),
|
|
197
|
-
});
|
|
207
|
+
const window = timeBounds(terms.get("at"));
|
|
198
208
|
const found = await context.withServices((services) => services.people.timeline(person, {
|
|
199
209
|
...(scope === undefined ? {} : { scope: scope }),
|
|
200
210
|
...(window.since === undefined ? {} : { since: window.since }),
|
|
@@ -211,9 +221,7 @@ export const contactsCommand = (messenger) => {
|
|
|
211
221
|
...(found.cursor === undefined ? {} : { cursor: found.cursor }),
|
|
212
222
|
args: {
|
|
213
223
|
person,
|
|
214
|
-
...(
|
|
215
|
-
...(sinceTime === undefined ? {} : { since_time: sinceTime }),
|
|
216
|
-
...(untilTime === undefined ? {} : { until_time: untilTime }),
|
|
224
|
+
...(words.length ? { query: typedQuery(words) } : {}),
|
|
217
225
|
},
|
|
218
226
|
meta: { ...window.meta, ...(pending > 0 ? { truncated: true } : {}) },
|
|
219
227
|
}));
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import { type SendEntry } from "../../sends/journal.js";
|
|
2
3
|
import { type Messenger } from "./context.js";
|
|
3
4
|
/**
|
|
4
5
|
* The chats this profile may send to. Off until the first `add`; `clear` deletes it, which turns it off again. It stops
|
|
5
6
|
* a model that a message talked into writing somewhere, not an agent set on getting around it.
|
|
6
7
|
*/
|
|
7
|
-
export declare const recipientsCommand: (messenger: Messenger
|
|
8
|
+
export declare const recipientsCommand: (messenger: Messenger, options?: {
|
|
9
|
+
resolve?: "chat-card";
|
|
10
|
+
}) => Command;
|
|
8
11
|
/** Every attempt to send from this profile, kept whatever `--record` says. Never the text. */
|
|
9
12
|
export declare const sendsCommand: (messenger: Messenger) => Command;
|
|
13
|
+
export declare const sendAttemptItem: ({ sendId, operationId, ...entry }: SendEntry) => unknown;
|
|
@@ -15,7 +15,7 @@ import { SENDS_QUERY, sendFilter } from "./sends-query.js";
|
|
|
15
15
|
* The chats this profile may send to. Off until the first `add`; `clear` deletes it, which turns it off again. It stops
|
|
16
16
|
* a model that a message talked into writing somewhere, not an agent set on getting around it.
|
|
17
17
|
*/
|
|
18
|
-
export const recipientsCommand = (messenger) => {
|
|
18
|
+
export const recipientsCommand = (messenger, options = {}) => {
|
|
19
19
|
const tool = `${messenger.app.command} personal`;
|
|
20
20
|
const listFor = (profile, env) => new RecipientList(recipientsPathFor(messenger.app, profile, env), messenger.app.command);
|
|
21
21
|
const command = new Command("recipients").description("the chats this profile may send to, when the list is on");
|
|
@@ -43,7 +43,8 @@ export const recipientsCommand = (messenger) => {
|
|
|
43
43
|
.description("allow sending to this chat; the first add turns the list on")
|
|
44
44
|
.action(async function (chat) {
|
|
45
45
|
const context = messengerContext(this, messenger);
|
|
46
|
-
|
|
46
|
+
// Some transports resolve an id without reading its title or dialog partner.
|
|
47
|
+
const found = await context.withMessenger((connection) => options.resolve === "chat-card" ? connection.chat(chat) : connection.resolve(chat));
|
|
47
48
|
const partnerId = messenger.partnerOf?.(found);
|
|
48
49
|
const added = await listFor(context.settings.profile, context.env).addAsync({
|
|
49
50
|
id: found.id,
|
|
@@ -93,10 +94,11 @@ export const sendsCommand = (messenger) => new Command("sends").description("eve
|
|
|
93
94
|
const from = settings.all ? 0 : (settings.page - 1) * settings.limit;
|
|
94
95
|
const shown = settings.all ? entries : entries.slice(from, from + settings.limit);
|
|
95
96
|
renderAnswer(this, context, pagedList("sends list", settings, {
|
|
96
|
-
items: shown.map(
|
|
97
|
+
items: shown.map(sendAttemptItem),
|
|
97
98
|
args: words.length ? { query: typedQuery(words) } : {},
|
|
98
99
|
has_more: from + shown.length < entries.length,
|
|
99
100
|
}));
|
|
100
101
|
if (entries.length === 0)
|
|
101
102
|
renderer.note(filter ? "no send attempts match the query" : `profile ${settings.profile} has not tried to send anything`);
|
|
102
103
|
}));
|
|
104
|
+
export const sendAttemptItem = ({ sendId, operationId, ...entry }) => snakeKeys({ ...entry, ...((operationId ?? sendId) === undefined ? {} : { operationId: operationId ?? sendId }) });
|
|
@@ -5,7 +5,10 @@ import { REMOTE_WRITE } from "../effects.js";
|
|
|
5
5
|
import { itemOf, renderAnswer, snakeKeys } from "../envelope.js";
|
|
6
6
|
import { messengerContext } from "./context.js";
|
|
7
7
|
/** `messages press` — one of a bot's callback buttons; the bot sees who pressed it. */
|
|
8
|
-
export const pressCommand = (messenger) => annotate(new Command("press"), {
|
|
8
|
+
export const pressCommand = (messenger) => annotate(new Command("press"), {
|
|
9
|
+
effects: REMOTE_WRITE,
|
|
10
|
+
examples: [`${messenger.app.command} personal messages press "Example Bot" 101 1`],
|
|
11
|
+
})
|
|
9
12
|
.description("press a bot's button under a message; the bot sees that you pressed it")
|
|
10
13
|
.argument("<chat>", messenger.chatArgument)
|
|
11
14
|
.argument("<message>", "the id of the message with the buttons")
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { CliError } from "@wirecat/cli-base";
|
|
3
3
|
import { annotate } from "@wirecat/cli-base/commands";
|
|
4
|
-
import { defineQuery } from "@wirecat/cli-base/query";
|
|
5
4
|
import { Command } from "commander";
|
|
6
5
|
import { isTextModelInstalled, textModelsDirectory } from "../../embeddings/embed.js";
|
|
7
6
|
import { embeddingKeys } from "../../embeddings/keys.js";
|
|
@@ -16,19 +15,12 @@ import { readSecret } from "../../terminal/prompt.js";
|
|
|
16
15
|
import { baseContext, environmentOf } from "../context.js";
|
|
17
16
|
import { FETCH, grantsAuthority, LOCAL_READ, LOCAL_WRITE, reachesOtherService } from "../effects.js";
|
|
18
17
|
import { itemOf, listOf, renderAnswer } from "../envelope.js";
|
|
19
|
-
import { listQuery, nativeTerms,
|
|
18
|
+
import { listQuery, nativeTerms, typedQuery, unfilteredQuery, withQuery } from "../list-query.js";
|
|
19
|
+
import { MODEL_CATALOGUE_QUERY } from "../model-catalogue-command.js";
|
|
20
20
|
import { nextStep } from "../steps.js";
|
|
21
21
|
/** A model list is the catalog this version ships. */
|
|
22
22
|
const MODELS_QUERY = unfilteredQuery("model", modelEntity);
|
|
23
|
-
const ROOT_MODELS_QUERY =
|
|
24
|
-
entity: "model",
|
|
25
|
-
backend: "native",
|
|
26
|
-
fields: [
|
|
27
|
-
termField("kind", "enum", "kind:audio", { values: ["audio", "text"] }),
|
|
28
|
-
termField("id", "kw", "id:e5-small"),
|
|
29
|
-
termField("downloaded", "bool", "downloaded:true"),
|
|
30
|
-
],
|
|
31
|
-
});
|
|
23
|
+
const ROOT_MODELS_QUERY = MODEL_CATALOGUE_QUERY;
|
|
32
24
|
/** Every model this version knows: a short, fixed list, never paged. */
|
|
33
25
|
const everyModel = (command, items, next = []) => listOf(command, { items, limit: Math.max(1, items.length), has_more: false, next });
|
|
34
26
|
const audioItem = (model, directory, chosen) => ({
|
|
@@ -22,7 +22,7 @@ const kindsOf = (typed) => {
|
|
|
22
22
|
export const mediaCommand = (messenger) => annotate(new Command("media"), { effects: REMOTE_READ })
|
|
23
23
|
.description("a chat's photos, videos, files, audio and links, from the messenger's server; reading marks nothing")
|
|
24
24
|
.argument("<chat>", messenger.chatArgument)
|
|
25
|
-
.option("--type <
|
|
25
|
+
.option("--type <type>", `only these kinds, comma-separated: ${MEDIA_KINDS.join(", ")}`)
|
|
26
26
|
.option("--limit <n>", "how many to show", positiveCount("--limit"))
|
|
27
27
|
.option("--cursor <cursor>", "go on from where page.next says the last page stopped")
|
|
28
28
|
.action(async function (chat) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type RunMetadata } from "../../runs/run.js";
|
|
2
2
|
import type { SendEntry } from "../../sends/journal.js";
|
|
3
|
-
export interface Report {
|
|
3
|
+
export interface Report<Doctor extends object = Record<string, unknown>> {
|
|
4
4
|
createdAt: string;
|
|
5
5
|
/** What `doctor --json` answers — versions, paths, counts and the messenger's own checks. */
|
|
6
|
-
doctor:
|
|
6
|
+
doctor: Doctor;
|
|
7
7
|
/** The run the report is about: the one asked for, or the newest that failed. */
|
|
8
8
|
run: {
|
|
9
9
|
metadata: RunMetadata;
|
|
@@ -12,13 +12,25 @@ export interface Report {
|
|
|
12
12
|
/** The newest write attempts — outcomes and ids, never text (`src/sends/journal.ts`). */
|
|
13
13
|
sends: SendEntry[];
|
|
14
14
|
}
|
|
15
|
+
/** Optional technical context supplied by a consumer; it is redacted with the rest of the report. */
|
|
16
|
+
export interface ReportContext {
|
|
17
|
+
createdAt?: never;
|
|
18
|
+
doctor?: never;
|
|
19
|
+
run?: never;
|
|
20
|
+
sends?: never;
|
|
21
|
+
version?: string;
|
|
22
|
+
runtime?: string;
|
|
23
|
+
platform?: string;
|
|
24
|
+
arch?: string;
|
|
25
|
+
profile?: string | null;
|
|
26
|
+
}
|
|
15
27
|
/**
|
|
16
28
|
* **Everything a report holds is already free of content** — the doctor, the run log and the send
|
|
17
29
|
* journal are built that way. Two things are added: every id becomes a label, and the home
|
|
18
|
-
* directory is hidden, since paths name the person's account on this machine.
|
|
30
|
+
* directory is hidden, since paths name the person's account on this machine.
|
|
19
31
|
*/
|
|
20
|
-
export declare const buildReport: ({ doctor, runsDir, runId, command, sends, now, home, }: {
|
|
21
|
-
doctor:
|
|
32
|
+
export declare const buildReport: <Doctor extends object, Context extends ReportContext = Record<never, never>>({ doctor, runsDir, runId, command, sends, now, home, context, eventFields, }: {
|
|
33
|
+
doctor: Doctor;
|
|
22
34
|
runsDir: string;
|
|
23
35
|
runId?: string;
|
|
24
36
|
/** What to type to list runs, for the error when `runId` names none. */
|
|
@@ -26,7 +38,10 @@ export declare const buildReport: ({ doctor, runsDir, runId, command, sends, now
|
|
|
26
38
|
sends: SendEntry[];
|
|
27
39
|
now?: Date;
|
|
28
40
|
home: string | undefined;
|
|
29
|
-
|
|
41
|
+
context?: Context;
|
|
42
|
+
/** Retain allowlisted recorded fields, including time and severity, for an existing consumer contract. */
|
|
43
|
+
eventFields?: "report" | "recorded";
|
|
44
|
+
}) => Report<Doctor> & Omit<Context, keyof Report>;
|
|
30
45
|
/**
|
|
31
46
|
* Every field of a journal line that names a chat, a message or a write. A send's `operationId` is
|
|
32
47
|
* its `sendId`, so one left raw would undo the other's label.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash, randomBytes } from "node:crypto";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { CliError } from "@wirecat/cli-base";
|
|
4
|
+
import { LOG_ATTRIBUTES } from "../../runs/log-attributes.js";
|
|
4
5
|
import { findRun, listRuns, readEvents } from "../../runs/run.js";
|
|
5
6
|
const RECENT_SENDS = 20;
|
|
6
7
|
/** Only these fields of a run event travel; a field added later is left out until it is named here. */
|
|
@@ -18,21 +19,22 @@ const EVENT_FIELDS = [
|
|
|
18
19
|
/**
|
|
19
20
|
* **Everything a report holds is already free of content** — the doctor, the run log and the send
|
|
20
21
|
* journal are built that way. Two things are added: every id becomes a label, and the home
|
|
21
|
-
* directory is hidden, since paths name the person's account on this machine.
|
|
22
|
+
* directory is hidden, since paths name the person's account on this machine.
|
|
22
23
|
*/
|
|
23
|
-
export const buildReport = ({ doctor, runsDir, runId, command, sends, now = new Date(), home, }) => {
|
|
24
|
+
export const buildReport = ({ doctor, runsDir, runId, command, sends, now = new Date(), home, context, eventFields = "report", }) => {
|
|
24
25
|
const chosen = runId === undefined ? newestFailed(runsDir) : findRun(runsDir, runId);
|
|
25
26
|
if (runId !== undefined && !chosen)
|
|
26
27
|
throw new CliError("not_found", `no run ${runId} — \`${command} runs list\` names them`);
|
|
27
28
|
const label = labeller();
|
|
28
29
|
const account = doctor.account;
|
|
29
30
|
const report = {
|
|
31
|
+
...context,
|
|
30
32
|
createdAt: now.toISOString(),
|
|
31
33
|
doctor: {
|
|
32
34
|
...doctor,
|
|
33
35
|
...(account?.remembered ? { account: { ...account, remembered: label(account.remembered) } } : {}),
|
|
34
36
|
},
|
|
35
|
-
run: chosen ? { metadata: chosen.metadata, events: readEvents(chosen.dir).map(eventOf(label)) } : null,
|
|
37
|
+
run: chosen ? { metadata: chosen.metadata, events: readEvents(chosen.dir).map(eventOf(label, eventFields)) } : null,
|
|
36
38
|
sends: sends.slice(-RECENT_SENDS).map((entry) => labelled(entry, label)),
|
|
37
39
|
};
|
|
38
40
|
return JSON.parse(hideHome(JSON.stringify(report), home));
|
|
@@ -85,8 +87,21 @@ const labeller = () => {
|
|
|
85
87
|
const salt = randomBytes(16);
|
|
86
88
|
return (id) => `id:${createHash("sha256").update(salt).update(id).digest("hex").slice(0, 12)}`;
|
|
87
89
|
};
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
+
const RECORDED_FIELDS = new Set([...LOG_ATTRIBUTES, "time", "severity"]);
|
|
91
|
+
const RECORDED_ID_FIELDS = new Set([
|
|
92
|
+
...SEND_ID_FIELDS.map((key) => key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)),
|
|
93
|
+
"actor_id",
|
|
94
|
+
"target_id",
|
|
95
|
+
]);
|
|
96
|
+
const eventOf = (label, fields) => (event) => {
|
|
97
|
+
const kept = Object.fromEntries(Object.entries(event)
|
|
98
|
+
.filter(([key]) => (fields === "recorded" ? RECORDED_FIELDS.has(key) : EVENT_FIELDS.includes(key)))
|
|
99
|
+
.map(([key, value]) => [
|
|
100
|
+
key,
|
|
101
|
+
fields === "recorded" && RECORDED_ID_FIELDS.has(key) && value !== undefined && value !== null
|
|
102
|
+
? label(String(value))
|
|
103
|
+
: value,
|
|
104
|
+
]));
|
|
90
105
|
const ids = kept.ids;
|
|
91
106
|
if (typeof ids !== "object" || ids === null)
|
|
92
107
|
return kept;
|
|
@@ -108,6 +108,10 @@ const holderOf = (command) => holderIn(environmentOf(command).env ?? process.env
|
|
|
108
108
|
const HOLDER_HELP = "who you are for claims: a session id or a chat id; default WIRECAT_HOLDER, else Claude Code's session, else the agent's name";
|
|
109
109
|
const planFrom = (options) => {
|
|
110
110
|
const plan = {};
|
|
111
|
+
if (options.priority !== undefined)
|
|
112
|
+
plan.priority = options.priority;
|
|
113
|
+
if (options.parent !== undefined)
|
|
114
|
+
plan.parent = options.parent;
|
|
111
115
|
if (options.category !== undefined)
|
|
112
116
|
plan.category = options.category;
|
|
113
117
|
if (options.title !== undefined)
|
|
@@ -190,15 +194,21 @@ export const tasksCommand = (messenger) => {
|
|
|
190
194
|
effects: LOCAL_WRITE,
|
|
191
195
|
examples: [`${tool} personal tasks update DOC-12 --title "Review draft"`],
|
|
192
196
|
}))
|
|
193
|
-
.summary("
|
|
194
|
-
.description("
|
|
197
|
+
.summary("update a task's text, schedule, category, assignees, priority or parent")
|
|
198
|
+
.description("update a task's text, schedule, category, assignees, priority or parent; nothing reaches the messenger")
|
|
195
199
|
.argument("<task>", "the task's id or key, as tasks list shows it")
|
|
196
|
-
.option("--category <name>", `${categoryHelp}; a change is kept in the task's history`)
|
|
200
|
+
.option("--category <name>", `${categoryHelp}; a change is kept in the task's history`)
|
|
201
|
+
.option("--priority <n>", "priority from 0 (urgent) through 4 (low)", (value) => {
|
|
202
|
+
if (!/^[0-4]$/.test(value))
|
|
203
|
+
throw new CliError("validation_error", "--priority takes 0 through 4");
|
|
204
|
+
return Number(value);
|
|
205
|
+
})
|
|
206
|
+
.option("--parent <id>", "parent task in the same project; none clears it", (value) => value === "none" ? null : value), "send Alex the API token").action(async function (id) {
|
|
197
207
|
const context = messengerContext(this, messenger);
|
|
198
208
|
refuseLocalWrite(context, messenger.app.command, "tasks.update");
|
|
199
209
|
const plan = planFrom(this.opts());
|
|
200
210
|
if (Object.keys(plan).length === 0)
|
|
201
|
-
throw new CliError("validation_error", "give at least one of --title, --description, --due, --remind-time, --category");
|
|
211
|
+
throw new CliError("validation_error", "give at least one of --title, --description, --due, --remind-time, --category, --priority, --parent");
|
|
202
212
|
const planned = await context.withServices((services) => services.tasks.plan(id, plan, writerOf(this)));
|
|
203
213
|
renderAnswer(this, context, itemOf(snakeKeys(planned)), () => `${card(planned)}\n`);
|
|
204
214
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { AppIdentity } from "../ports/app.js";
|
|
3
|
+
import { type Body } from "./envelope.js";
|
|
4
|
+
export declare const MODEL_CATALOGUE_QUERY: import("@wirecat/cli-base/query").QueryRegistry;
|
|
5
|
+
export interface ModelCatalogueOptions {
|
|
6
|
+
kinds: readonly ("audio" | "text")[];
|
|
7
|
+
env: () => NodeJS.ProcessEnv;
|
|
8
|
+
output: (answer: Body, command: Command) => void;
|
|
9
|
+
diagnostic: (line: string) => void;
|
|
10
|
+
jsonOption?: boolean;
|
|
11
|
+
offline?: () => boolean;
|
|
12
|
+
defaultAudio?: () => string;
|
|
13
|
+
}
|
|
14
|
+
/** Provider composition supplies I/O and supported kinds; parsing, receipts and download policy stay shared. */
|
|
15
|
+
export declare const modelCatalogueCommand: (app: AppIdentity, options: ModelCatalogueOptions) => Command;
|