@wirecat/cli-core 0.424.0 → 0.426.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 +53 -0
- package/dist/cli/author.d.ts +5 -6
- package/dist/cli/author.js +9 -16
- package/dist/cli/commands-command.js +1 -1
- package/dist/cli/config-issues.d.ts +20 -2
- package/dist/cli/config-issues.js +111 -17
- package/dist/cli/context.d.ts +2 -0
- package/dist/cli/context.js +17 -6
- package/dist/cli/dry-run-guard.d.ts +2 -0
- package/dist/cli/dry-run-guard.js +68 -0
- package/dist/cli/effects.d.ts +4 -0
- package/dist/cli/effects.js +5 -1
- package/dist/cli/entry.js +14 -9
- package/dist/cli/guide.d.ts +1 -1
- package/dist/cli/guide.js +33 -5
- package/dist/cli/help/command-help.js +12 -7
- package/dist/cli/help/first-screen.js +2 -2
- package/dist/cli/index.d.ts +5 -5
- package/dist/cli/index.js +5 -4
- package/dist/cli/list-query.d.ts +2 -0
- package/dist/cli/list-query.js +5 -2
- package/dist/cli/meeting-preparation-command.js +2 -2
- package/dist/cli/meeting-series-inventory-command.js +2 -2
- package/dist/cli/messenger/models-command.js +3 -2
- package/dist/cli/messenger/store-maintenance-command.js +15 -5
- package/dist/cli/preview.d.ts +44 -5
- package/dist/cli/preview.js +26 -8
- package/dist/cli/profile.d.ts +7 -0
- package/dist/cli/profile.js +19 -0
- package/dist/cli/program.js +42 -29
- package/dist/cli/runs/search.js +2 -0
- package/dist/cli/settings.js +13 -12
- package/dist/cli/shared-command-exports.js +3 -1
- package/dist/entities/index.d.ts +148 -0
- package/dist/entities/recorded-run.d.ts +84 -0
- package/dist/entities/recorded-run.js +15 -0
- package/dist/entities/store-maintenance.d.ts +64 -0
- package/dist/entities/store-maintenance.js +24 -1
- package/dist/mcp/agent.js +3 -4
- package/dist/mcp/bot/server.js +1 -1
- package/dist/mcp/meeting-preparation.js +2 -2
- package/dist/mcp/meeting-project-candidates.js +2 -2
- package/dist/mcp/meeting-series-inventory.js +2 -2
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/surface.d.ts +3 -1
- package/dist/mcp/surface.js +20 -9
- package/dist/mcp/text.d.ts +1 -1
- package/dist/mcp/text.js +1 -1
- package/dist/mcp/tool.d.ts +1 -1
- package/dist/mcp/tool.js +3 -1
- package/dist/meetings/mcp/agent-text.d.ts +2 -0
- package/dist/meetings/mcp/agent-text.js +2 -0
- package/dist/meetings/mcp/index.d.ts +1 -1
- package/dist/meetings/mcp/index.js +3 -3
- package/dist/meetings/mcp/passage.js +2 -2
- package/dist/meetings/mcp/project-evidence.js +2 -2
- package/dist/meetings/mcp/search.js +2 -2
- package/dist/runs/error-detail.d.ts +42 -0
- package/dist/runs/error-detail.js +131 -0
- package/dist/runs/events.d.ts +4 -0
- package/dist/runs/events.js +2 -0
- package/dist/runs/log-attributes.js +2 -0
- package/dist/runs/recording.d.ts +5 -2
- package/dist/runs/recording.js +20 -19
- package/dist/runs/run-context.d.ts +37 -0
- package/dist/runs/run-context.js +148 -0
- package/dist/runs/run.d.ts +19 -3
- package/dist/runs/run.js +1 -0
- package/dist/store/exports.d.ts +2 -0
- package/dist/store/exports.js +2 -0
- package/dist/store/sqlite/store-contents.d.ts +47 -0
- package/dist/store/sqlite/store-contents.js +104 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import { metaOf } from "@wirecat/cli-base/commands";
|
|
|
2
2
|
import { writes } from "@wirecat/cli-base/standards";
|
|
3
3
|
import { commandPathOf, outputOf } from "../command-contract.js";
|
|
4
4
|
import { environmentOf } from "../context.js";
|
|
5
|
-
import {
|
|
5
|
+
import { takesProfile } from "../profile.js";
|
|
6
6
|
import { commandAt } from "../steps.js";
|
|
7
7
|
import { short } from "./commands-text.js";
|
|
8
8
|
/** Argument names onto the kinds `domain/references.ts` names; a plural takes the same kind. */
|
|
@@ -177,7 +177,7 @@ export const EXAMPLE_PROFILE = "personal";
|
|
|
177
177
|
const withProfile = (command, example) => {
|
|
178
178
|
const root = rootOf(command);
|
|
179
179
|
const top = commandPathOf(command)[0];
|
|
180
|
-
if (!profiled.has(root) || top === undefined ||
|
|
180
|
+
if (!profiled.has(root) || top === undefined || !takesProfile(command))
|
|
181
181
|
return example;
|
|
182
182
|
const prefix = `${root.name()} ${top}`;
|
|
183
183
|
return example === prefix || example.startsWith(`${prefix} `)
|
|
@@ -203,11 +203,16 @@ export const commandHelpText = (command) => {
|
|
|
203
203
|
...metaOf(command),
|
|
204
204
|
path: commandPathOf(command),
|
|
205
205
|
});
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
206
|
+
// "Available for this profile" says nothing where no profile is in play: a tool without profiles, or a command
|
|
207
|
+
// that reads none.
|
|
208
|
+
const profileMatters = profiled.has(rootOf(command)) && takesProfile(command);
|
|
209
|
+
const access = !availability
|
|
210
|
+
? []
|
|
211
|
+
: availability.available
|
|
212
|
+
? profileMatters
|
|
213
|
+
? rows("Availability:", ["available for this profile"])
|
|
214
|
+
: []
|
|
215
|
+
: rows("Availability:", [`unavailable — ${availability.reason}`]);
|
|
211
216
|
return [
|
|
212
217
|
"",
|
|
213
218
|
...access,
|
|
@@ -25,12 +25,12 @@ export const WIRECAT_TOOLS = [
|
|
|
25
25
|
{
|
|
26
26
|
command: "zm",
|
|
27
27
|
package: "@wirecat/zoom-cli",
|
|
28
|
-
does: "Zoom meetings: transcripts and summaries, searchable with your
|
|
28
|
+
does: "Zoom meetings: transcripts and summaries, searchable with your other WireCat data",
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
command: "drive",
|
|
32
32
|
package: "@wirecat/drive-cli",
|
|
33
|
-
does: "Google Drive and Docs as local text, searchable with your
|
|
33
|
+
does: "Google Drive and Docs as local text, searchable with your other WireCat data",
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
command: "memo",
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { callMeetingPreparationTool, meetingPreparationTool } from "../mcp/meeti
|
|
|
11
11
|
export { callMeetingProjectCandidatesTool, meetingProjectCandidatesTool } from "../mcp/meeting-project-candidates.js";
|
|
12
12
|
export { callMeetingSeriesInventoryTool, meetingSeriesInventoryTool } from "../mcp/meeting-series-inventory.js";
|
|
13
13
|
export { registerLinkConversationsPrompt } from "../mcp/prompts.js";
|
|
14
|
-
export { agentBody, agentJson, agentResult, UNTRUSTED, UNTRUSTED_INSTRUCTION } from "../mcp/text.js";
|
|
14
|
+
export { agentBody, agentJson, agentResult, UNTRUSTED, UNTRUSTED_INSTRUCTION, UNTRUSTED_NEUTRAL } from "../mcp/text.js";
|
|
15
15
|
export { MEETING_RESULT_ENTITIES } from "../meetings/index.js";
|
|
16
16
|
export { type AppIdentity, envName, readOnlyLockOf, readOnlyRefusal } from "../ports/app.js";
|
|
17
17
|
export type { AccountEditing, AccountHealth, AccountRecords, AccountSettings, AccountStanding, AccountTools, After, BotChats, ChannelComments, ChatDeletion, ChatFolders, ChatReading, ContactBook, Download, ForumControl, ForumState, GroupAdmin, GroupModeration, HistoryBatch, HistoryChatEvent, HistoryReaction, HistoryStar, HistoryVote, InviteLinks, JoinRequests, LiveUpdates, MessageButtons, MessageEditing, MessageMedia, MessagePermalinks, MessagePins, MessagePolls, MessageReactions, MessageSearch, MessageStars, MessengerAdapter, MessengerCore, NewPoll, OfficialStats, PassiveUpdates, PersonProfiles, ProfileChange, ProfilePhotos, PushedHistory, ReadState, RemoteFile, ScheduledMessages, SenderIdentities, SenderSearch, SendOptions, Sent, ServerQuery, ServerReads, ThreadAddressing, TopicEditing, TopicHistory, TopicReadState, Transcript, } from "../ports/messenger.js";
|
|
@@ -52,7 +52,7 @@ export type { CommandAvailability, DiscoveredCommand } from "./command-availabil
|
|
|
52
52
|
export { commandContract, type JsonSchema, SCHEMA_DIALECT } from "./command-contract.js";
|
|
53
53
|
export { CONTRACT } from "./commands-command.js";
|
|
54
54
|
export { refuseUnknownKey } from "./config-command.js";
|
|
55
|
-
export type
|
|
55
|
+
export { type ConfigIssue, type ConfigIssueKind, checkConfigText, issueMessage } from "./config-issues.js";
|
|
56
56
|
export { loadSnakeCaseConfig } from "./config-keys.js";
|
|
57
57
|
export { type AgentRun, type BaseContext, type BaseEnvironment, baseContext, environmentOf, outputFor, provide, secretInputOf, } from "./context.js";
|
|
58
58
|
export { addContractInfo, type ContractEvidenceOptions, contractEvidence } from "./contract-evidence.js";
|
|
@@ -60,7 +60,7 @@ export { sharedCommandTemplate } from "./contract-templates.js";
|
|
|
60
60
|
export { type Closeable, withDeadline } from "./deadline.js";
|
|
61
61
|
export { DEFAULT_CONFIG, ensureDefaultConfig } from "./default-config.js";
|
|
62
62
|
export { DISCOVERY_DESCRIPTIONS } from "./discovery-descriptions.js";
|
|
63
|
-
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";
|
|
63
|
+
export { changesAuthority, changesAuthorityAt, changesAuthorityNow, destroysNothing, FETCH, grantsAuthority, isLogin, isOtherServiceCall, isStoreChange, judgedEffects, judgedTargets, LOCAL_READ, LOCAL_WRITE, logsInOrOut, NO_EFFECTS, ownerOnlyOption, previewFlag, REMOTE_READ, REMOTE_WRITE, reachesOtherService, refuseUnderReadOnly, storeChangeRefusal, } from "./effects.js";
|
|
64
64
|
export { type CliEntry, type EntryContext, type EntryIo, startCli } from "./entry.js";
|
|
65
65
|
export { type AnswerOutput, answerSchema, type Body, type ItemBody, isBody, itemAnswer, itemOf, jsonlRecords, judgedAnswer, type ListBody, type ListInput, listOf, metaNow, printItem, renderAnswer, sealed, snakeKeys, snakeKeysKeeping, } from "./envelope.js";
|
|
66
66
|
export { withAbort } from "./execution.js";
|
|
@@ -99,8 +99,8 @@ export { storeSummary } from "./messenger/store-maintenance-command.js";
|
|
|
99
99
|
export { type Saving, stored } from "./messenger/stored.js";
|
|
100
100
|
export { MODEL_CATALOGUE_QUERY, type ModelCatalogueOptions } from "./model-catalogue-command.js";
|
|
101
101
|
export { window, withPaging } from "./paging.js";
|
|
102
|
-
export { knownBeside, knownPermissionKeys, type PermissionKeyOf, unknownPermissionKeys } from "./permission-keys.js";
|
|
103
|
-
export { asFirstWord, commandWords, liftProfile, refuseCommandName, rootOf, usableProfileName } from "./profile.js";
|
|
102
|
+
export { knownBeside, knownPermissionKeys, type PermissionKeyOf, unknownPermissionIssues, unknownPermissionKeys, } from "./permission-keys.js";
|
|
103
|
+
export { asFirstWord, commandWords, liftProfile, profileFree, refuseCommandName, rootOf, takesProfile, usableProfileName, } from "./profile.js";
|
|
104
104
|
export { createProgram, type ProgramDefinition, type ProgramOptions, type RunOptions, run } from "./program.js";
|
|
105
105
|
export { fieldsOf, projectFields } from "./result-fields.js";
|
|
106
106
|
export { type Config, type Configuration, count, first, flag, fromFile, type GlobalFlags, NONE_NAMED, namedProfile, type ProfileKind, plain, type ResolveOptions, type Settings, type SettingsExtension, type SettingsExtensionContext, type Source, settingsFor, } from "./settings.js";
|
package/dist/cli/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export { callMeetingPreparationTool, meetingPreparationTool } from "../mcp/meeti
|
|
|
9
9
|
export { callMeetingProjectCandidatesTool, meetingProjectCandidatesTool } from "../mcp/meeting-project-candidates.js";
|
|
10
10
|
export { callMeetingSeriesInventoryTool, meetingSeriesInventoryTool } from "../mcp/meeting-series-inventory.js";
|
|
11
11
|
export { registerLinkConversationsPrompt } from "../mcp/prompts.js";
|
|
12
|
-
export { agentBody, agentJson, agentResult, UNTRUSTED, UNTRUSTED_INSTRUCTION } from "../mcp/text.js";
|
|
12
|
+
export { agentBody, agentJson, agentResult, UNTRUSTED, UNTRUSTED_INSTRUCTION, UNTRUSTED_NEUTRAL } from "../mcp/text.js";
|
|
13
13
|
export { MEETING_RESULT_ENTITIES } from "../meetings/index.js";
|
|
14
14
|
export { envName, readOnlyLockOf, readOnlyRefusal } from "../ports/app.js";
|
|
15
15
|
export { senderFacts } from "../replies/dry-run.js";
|
|
@@ -45,6 +45,7 @@ export { PressLog, UpdatesCursor } from "./bot/updates.js";
|
|
|
45
45
|
export { commandContract, SCHEMA_DIALECT } from "./command-contract.js";
|
|
46
46
|
export { CONTRACT } from "./commands-command.js";
|
|
47
47
|
export { refuseUnknownKey } from "./config-command.js";
|
|
48
|
+
export { checkConfigText, issueMessage } from "./config-issues.js";
|
|
48
49
|
export { loadSnakeCaseConfig } from "./config-keys.js";
|
|
49
50
|
export { baseContext, environmentOf, outputFor, provide, secretInputOf, } from "./context.js";
|
|
50
51
|
export { addContractInfo, contractEvidence } from "./contract-evidence.js";
|
|
@@ -52,7 +53,7 @@ export { sharedCommandTemplate } from "./contract-templates.js";
|
|
|
52
53
|
export { withDeadline } from "./deadline.js";
|
|
53
54
|
export { DEFAULT_CONFIG, ensureDefaultConfig } from "./default-config.js";
|
|
54
55
|
export { DISCOVERY_DESCRIPTIONS } from "./discovery-descriptions.js";
|
|
55
|
-
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
|
+
export { changesAuthority, changesAuthorityAt, changesAuthorityNow, destroysNothing, FETCH, grantsAuthority, isLogin, isOtherServiceCall, isStoreChange, judgedEffects, judgedTargets, LOCAL_READ, LOCAL_WRITE, logsInOrOut, NO_EFFECTS, ownerOnlyOption, previewFlag, REMOTE_READ, REMOTE_WRITE, reachesOtherService, refuseUnderReadOnly, storeChangeRefusal, } from "./effects.js";
|
|
56
57
|
export { startCli } from "./entry.js";
|
|
57
58
|
export { answerSchema, isBody, itemAnswer, itemOf, jsonlRecords, judgedAnswer, listOf, metaNow, printItem, renderAnswer, sealed, snakeKeys, snakeKeysKeeping, } from "./envelope.js";
|
|
58
59
|
export { withAbort } from "./execution.js";
|
|
@@ -89,8 +90,8 @@ export { storeSummary } from "./messenger/store-maintenance-command.js";
|
|
|
89
90
|
export { stored } from "./messenger/stored.js";
|
|
90
91
|
export { MODEL_CATALOGUE_QUERY } from "./model-catalogue-command.js";
|
|
91
92
|
export { window, withPaging } from "./paging.js";
|
|
92
|
-
export { knownBeside, knownPermissionKeys, unknownPermissionKeys } from "./permission-keys.js";
|
|
93
|
-
export { asFirstWord, commandWords, liftProfile, refuseCommandName, rootOf, usableProfileName } from "./profile.js";
|
|
93
|
+
export { knownBeside, knownPermissionKeys, unknownPermissionIssues, unknownPermissionKeys, } from "./permission-keys.js";
|
|
94
|
+
export { asFirstWord, commandWords, liftProfile, profileFree, refuseCommandName, rootOf, takesProfile, usableProfileName, } from "./profile.js";
|
|
94
95
|
export { createProgram, run } from "./program.js";
|
|
95
96
|
export { fieldsOf, projectFields } from "./result-fields.js";
|
|
96
97
|
export { count, first, flag, fromFile, NONE_NAMED, namedProfile, plain, settingsFor, } from "./settings.js";
|
package/dist/cli/list-query.d.ts
CHANGED
|
@@ -47,6 +47,8 @@ export declare const queryTerms: (words: QueryWords, registry: QueryRegistry, co
|
|
|
47
47
|
/**
|
|
48
48
|
* A `time` term as epoch ms bounds: `time>=7d`, `time:[2026-10-01 TO 2026-10-07]`, `time:today`, and the `meta`
|
|
49
49
|
* an answer reports them by: the zone calendar words and bare dates were read in, and the bounds in UTC.
|
|
50
|
+
* `until` is inclusive: an exclusive end (a bare date's next midnight, `… TO …}`) comes back 1 ms inside. `since` stays
|
|
51
|
+
* as written, because the inbox reads strictly after a `date>` start.
|
|
50
52
|
*/
|
|
51
53
|
export declare const timeBounds: (term: Predicate | undefined, zone?: string) => {
|
|
52
54
|
since?: number;
|
package/dist/cli/list-query.js
CHANGED
|
@@ -133,20 +133,23 @@ export const queryTerms = (words, registry, command) => {
|
|
|
133
133
|
/**
|
|
134
134
|
* A `time` term as epoch ms bounds: `time>=7d`, `time:[2026-10-01 TO 2026-10-07]`, `time:today`, and the `meta`
|
|
135
135
|
* an answer reports them by: the zone calendar words and bare dates were read in, and the bounds in UTC.
|
|
136
|
+
* `until` is inclusive: an exclusive end (a bare date's next midnight, `… TO …}`) comes back 1 ms inside. `since` stays
|
|
137
|
+
* as written, because the inbox reads strictly after a `date>` start.
|
|
136
138
|
*/
|
|
137
139
|
export const timeBounds = (term, zone = timezoneOf()) => {
|
|
138
140
|
if (!term)
|
|
139
141
|
return {};
|
|
140
142
|
const upper = term.operator === "range" ? (term.upper ?? "*") : term.value;
|
|
141
143
|
const range = dateRange(term.value, upper, term.operator === "range" ? term.lower_inclusive !== false : true, term.operator === "range" ? term.upper_inclusive !== false : true, zone, term.span);
|
|
144
|
+
const until = range.upper === undefined ? undefined : range.upper - (range.upper_inclusive ? 0 : 1);
|
|
142
145
|
return {
|
|
143
146
|
...(range.lower === undefined ? {} : { since: range.lower }),
|
|
144
|
-
...(
|
|
147
|
+
...(until === undefined ? {} : { until }),
|
|
145
148
|
meta: {
|
|
146
149
|
timezone: zone,
|
|
147
150
|
window: {
|
|
148
151
|
...(range.lower === undefined ? {} : { since: new Date(range.lower).toISOString() }),
|
|
149
|
-
...(
|
|
152
|
+
...(until === undefined ? {} : { until: new Date(until).toISOString() }),
|
|
150
153
|
},
|
|
151
154
|
},
|
|
152
155
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
2
|
import { annotate } from "@wirecat/cli-base/commands";
|
|
3
|
-
import { REMOTE_READ } from "./effects.js";
|
|
3
|
+
import { previewFlag, REMOTE_READ } from "./effects.js";
|
|
4
4
|
import { communicationOptions } from "./meeting-communications.js";
|
|
5
5
|
import { readMeetingPreparation } from "./meeting-preparation-read.js";
|
|
6
6
|
const integer = (value) => {
|
|
@@ -48,6 +48,6 @@ export const addMeetingPreparationCommand = (program, deps) => {
|
|
|
48
48
|
origin: "handwritten",
|
|
49
49
|
effects: REMOTE_READ,
|
|
50
50
|
output: { entity: "meeting_preparation" },
|
|
51
|
-
examples: [`${program.name()} meetings prepare 123 --json`],
|
|
51
|
+
examples: [`${program.name()} meetings prepare 123${previewFlag(program)} --json`],
|
|
52
52
|
});
|
|
53
53
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
2
|
import { annotate } from "@wirecat/cli-base/commands";
|
|
3
|
-
import { REMOTE_READ } from "./effects.js";
|
|
3
|
+
import { previewFlag, REMOTE_READ } from "./effects.js";
|
|
4
4
|
import { readMeetingSeriesInventory } from "./meeting-series-inventory-read.js";
|
|
5
5
|
const integer = (value) => {
|
|
6
6
|
if (!/^[1-9]\d*$/.test(value) || !Number.isSafeInteger(Number(value)))
|
|
@@ -32,6 +32,6 @@ export const addMeetingSeriesInventoryCommand = (program, deps) => {
|
|
|
32
32
|
effects: REMOTE_READ,
|
|
33
33
|
offline: false,
|
|
34
34
|
output: { entity: "meeting_series_inventory" },
|
|
35
|
-
examples: [`${program.name()} meetings scheduled --json`],
|
|
35
|
+
examples: [`${program.name()} meetings scheduled${previewFlag(program)} --json`],
|
|
36
36
|
});
|
|
37
37
|
};
|
|
@@ -165,9 +165,10 @@ export const modelsCommand = (messenger) => {
|
|
|
165
165
|
reachesOtherService(annotate(models.command("download"), {
|
|
166
166
|
effects: FETCH,
|
|
167
167
|
output: { entity: "model" },
|
|
168
|
-
examples: [`${tool} models download
|
|
168
|
+
examples: [`${tool} models download ${DEFAULT_TEXT_MODEL}`],
|
|
169
169
|
}))
|
|
170
|
-
.
|
|
170
|
+
.summary("download and verify one speech or embedding model")
|
|
171
|
+
.description("download and verify one speech or embedding model: tens to hundreds of MB, each size in models list")
|
|
171
172
|
.argument("<model>", "a model id from models list")
|
|
172
173
|
.option("--accept-terms", "accept the model's licence terms, for a model that has its own")
|
|
173
174
|
.action(async function (id, options) {
|
|
@@ -11,7 +11,7 @@ import { MIGRATIONS, migrate } from "../../store/migrations.js";
|
|
|
11
11
|
import { openCache } from "../../store/open.js";
|
|
12
12
|
import { storePath } from "../../store/path.js";
|
|
13
13
|
import { deleteCopy, repairStore } from "../../store/repair.js";
|
|
14
|
-
import { drainNoteIndex, fillSearchIndex, fillStems, involvementStoreOver, noteIndexState, openStore, orphanPointers, pendingNormalization, resetAttachmentWords, resetNoteIndex, resetSearchIndex, resetStems, searchIndexState, stemmerCache, stemsState, } from "../../store/store.js";
|
|
14
|
+
import { drainNoteIndex, fillSearchIndex, fillStems, involvementStoreOver, noteIndexState, openSqlite, openStore, orphanPointers, pendingNormalization, resetAttachmentWords, resetNoteIndex, resetSearchIndex, resetStems, rowCounts, searchIndexState, stemmerCache, stemsState, storeContents, } from "../../store/store.js";
|
|
15
15
|
import { environmentOf, outputFor } from "../context.js";
|
|
16
16
|
import { destroysNothing, LOCAL_READ, LOCAL_WRITE } from "../effects.js";
|
|
17
17
|
import { itemOf, renderAnswer, snakeKeys } from "../envelope.js";
|
|
@@ -49,6 +49,16 @@ const reading = async (path, read) => {
|
|
|
49
49
|
database.close();
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
|
+
/** For a command that only reads: the connection refuses writes, and opening sets no journal mode. */
|
|
53
|
+
const readingOnly = async (path, read) => {
|
|
54
|
+
const { database } = await openSqlite(path, { readOnly: true });
|
|
55
|
+
try {
|
|
56
|
+
return read(database);
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
database.close();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
52
62
|
/** `doctor`'s short summary of the store. Must answer for a broken file, so an error is a field. */
|
|
53
63
|
export const storeSummary = async (env) => {
|
|
54
64
|
const path = storePath(env);
|
|
@@ -154,25 +164,25 @@ const copiesCommand = () => new Command("copies").description("the tables `store
|
|
|
154
164
|
}));
|
|
155
165
|
const infoCommand = () => annotate(new Command("info"), { output: { entity: "store_info" }, effects: LOCAL_READ })
|
|
156
166
|
.summary("the local archive's format, size and contents")
|
|
157
|
-
.description("the store file: where it is, its size, its schema and how many rows it holds; changes nothing")
|
|
167
|
+
.description("the store file: where it is, its size, its schema and how many rows it holds, by provider, chat kind, account, year (UTC) and attachment kind, over every account; changes nothing")
|
|
158
168
|
.action(async function () {
|
|
159
169
|
const path = storePath(environmentOf(this).env ?? process.env);
|
|
160
170
|
if (!existsSync(path)) {
|
|
161
171
|
result(this, { path, exists: false });
|
|
162
172
|
return;
|
|
163
173
|
}
|
|
164
|
-
const read =
|
|
174
|
+
const read = readingOnly(path, (database) => {
|
|
165
175
|
const { version, minCompatible, writable } = schemaOf(database);
|
|
166
|
-
const tables = ["accounts", "chats", "messages", "attachments", "identities"];
|
|
167
176
|
return {
|
|
168
177
|
path,
|
|
169
178
|
exists: true,
|
|
170
179
|
bytes: { file: bytesOf(path), wal: bytesOf(`${path}-wal`) },
|
|
171
180
|
schema: { version, minCompatible, speaks: SPEAKS, writable },
|
|
172
|
-
rows: version > 0 ?
|
|
181
|
+
rows: version > 0 ? rowCounts(database) : {},
|
|
173
182
|
pendingNormalization: pendingIfKnown(database),
|
|
174
183
|
wordIndex: searchIndexState(database) ?? null,
|
|
175
184
|
stemIndex: stemsState(database) ?? null,
|
|
185
|
+
...(version > 0 ? storeContents(database) : {}),
|
|
176
186
|
};
|
|
177
187
|
});
|
|
178
188
|
result(this, await read.catch((error) => ({ path, exists: true, opens: false, error: messageOf(error) })));
|
package/dist/cli/preview.d.ts
CHANGED
|
@@ -3,13 +3,51 @@ import { type PermissionKey } from "../sends/permissions.js";
|
|
|
3
3
|
import type { Settings } from "./settings.js";
|
|
4
4
|
export declare class PreviewComplete extends Error {
|
|
5
5
|
}
|
|
6
|
-
export declare const preview: (command: Command, settings: Pick<Settings, "permissions" | "permissionSources" | "configPath" | "savedPermissions" | "profile">, tool: string, keyOf?: (path: readonly string[]) => PermissionKey | null | undefined) => {
|
|
6
|
+
export declare const preview: (command: Command, settings: Pick<Settings, "permissions" | "permissionSources" | "configPath" | "savedPermissions" | "profile">, tool: string, keyOf?: (path: readonly string[]) => PermissionKey | null | undefined, messenger?: boolean) => {
|
|
7
7
|
preview: boolean;
|
|
8
8
|
path: string[];
|
|
9
|
-
permission
|
|
10
|
-
key:
|
|
11
|
-
level:
|
|
9
|
+
permission?: {
|
|
10
|
+
key: PermissionKey | null;
|
|
11
|
+
level: string;
|
|
12
|
+
} | undefined;
|
|
13
|
+
validation: {
|
|
14
|
+
arguments: string;
|
|
15
|
+
permissions: string;
|
|
16
|
+
targets: string;
|
|
17
|
+
businessRules: string;
|
|
18
|
+
};
|
|
19
|
+
effects: {
|
|
20
|
+
actionInvoked: boolean;
|
|
21
|
+
writeReserved: boolean;
|
|
22
|
+
messengerContacted?: boolean | undefined;
|
|
23
|
+
serviceContacted: boolean;
|
|
24
|
+
configurationRead: boolean;
|
|
12
25
|
};
|
|
26
|
+
arguments: ({
|
|
27
|
+
name: string;
|
|
28
|
+
reference: string;
|
|
29
|
+
} | {
|
|
30
|
+
name: string;
|
|
31
|
+
supplied: boolean;
|
|
32
|
+
bytes: number | undefined;
|
|
33
|
+
})[];
|
|
34
|
+
options: string[];
|
|
35
|
+
trust: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* `messenger_contacted` stays for the messengers, whose callers may read it; `service_contacted` says the same
|
|
39
|
+
* for every tool. Without `permission` nothing was checked: a host that is not `run` has no settings to check.
|
|
40
|
+
*/
|
|
41
|
+
export declare const previewBody: (command: Command, permission: {
|
|
42
|
+
key: PermissionKey | null;
|
|
43
|
+
level: string;
|
|
44
|
+
} | undefined, messenger: boolean) => {
|
|
45
|
+
preview: boolean;
|
|
46
|
+
path: string[];
|
|
47
|
+
permission?: {
|
|
48
|
+
key: PermissionKey | null;
|
|
49
|
+
level: string;
|
|
50
|
+
} | undefined;
|
|
13
51
|
validation: {
|
|
14
52
|
arguments: string;
|
|
15
53
|
permissions: string;
|
|
@@ -19,7 +57,8 @@ export declare const preview: (command: Command, settings: Pick<Settings, "permi
|
|
|
19
57
|
effects: {
|
|
20
58
|
actionInvoked: boolean;
|
|
21
59
|
writeReserved: boolean;
|
|
22
|
-
messengerContacted
|
|
60
|
+
messengerContacted?: boolean | undefined;
|
|
61
|
+
serviceContacted: boolean;
|
|
23
62
|
configurationRead: boolean;
|
|
24
63
|
};
|
|
25
64
|
arguments: ({
|
package/dist/cli/preview.js
CHANGED
|
@@ -6,11 +6,11 @@ import { commandPathOf } from "./command-contract.js";
|
|
|
6
6
|
import { refuseUnknownPermissionKeys } from "./permission-keys.js";
|
|
7
7
|
export class PreviewComplete extends Error {
|
|
8
8
|
}
|
|
9
|
-
export const preview = (command, settings, tool, keyOf) => {
|
|
9
|
+
export const preview = (command, settings, tool, keyOf, messenger = true) => {
|
|
10
10
|
const path = commandPathOf(command);
|
|
11
11
|
const { permissions } = settings;
|
|
12
12
|
refuseUnknownPermissionKeys(command, settings, tool, keyOf && ((one) => keyOf(commandPathOf(one))));
|
|
13
|
-
const key = keyForCommand(path);
|
|
13
|
+
const key = keyOf?.(path) ?? keyForCommand(path);
|
|
14
14
|
const level = key ? levelFor(permissions, key).level : "allow";
|
|
15
15
|
for (const source of readKeysForCommand(path)) {
|
|
16
16
|
if (levelFor(permissions, source).level === "deny")
|
|
@@ -21,18 +21,36 @@ export const preview = (command, settings, tool, keyOf) => {
|
|
|
21
21
|
(key !== null && key !== undefined && WRITE_KEYS.includes(key));
|
|
22
22
|
if (level === "deny" || (writes && level === "readonly"))
|
|
23
23
|
throw new CliError("permission_error", `this profile does not permit ${path.join(" ")}`, { permission: key });
|
|
24
|
-
|
|
24
|
+
return previewBody(command, { key: key ?? null, level }, messenger);
|
|
25
|
+
};
|
|
26
|
+
const TARGETS = new Set(["chat", "message", "person", "profile"]);
|
|
27
|
+
/**
|
|
28
|
+
* `messenger_contacted` stays for the messengers, whose callers may read it; `service_contacted` says the same
|
|
29
|
+
* for every tool. Without `permission` nothing was checked: a host that is not `run` has no settings to check.
|
|
30
|
+
*/
|
|
31
|
+
export const previewBody = (command, permission, messenger) => {
|
|
25
32
|
return {
|
|
26
33
|
preview: true,
|
|
27
|
-
path,
|
|
28
|
-
permission
|
|
29
|
-
validation: {
|
|
30
|
-
|
|
34
|
+
path: commandPathOf(command),
|
|
35
|
+
...(permission ? { permission } : {}),
|
|
36
|
+
validation: {
|
|
37
|
+
arguments: "parsed",
|
|
38
|
+
permissions: permission ? "checked" : "not-checked",
|
|
39
|
+
targets: "unresolved",
|
|
40
|
+
businessRules: "not-executed",
|
|
41
|
+
},
|
|
42
|
+
effects: {
|
|
43
|
+
actionInvoked: false,
|
|
44
|
+
writeReserved: false,
|
|
45
|
+
...(messenger ? { messengerContacted: false } : {}),
|
|
46
|
+
serviceContacted: false,
|
|
47
|
+
configurationRead: permission !== undefined,
|
|
48
|
+
},
|
|
31
49
|
arguments: command.registeredArguments.map((argument, at) => {
|
|
32
50
|
const value = command.processedArgs[at];
|
|
33
51
|
return {
|
|
34
52
|
name: argument.name(),
|
|
35
|
-
...(
|
|
53
|
+
...(TARGETS.has(argument.name()) && typeof value === "string"
|
|
36
54
|
? { reference: value }
|
|
37
55
|
: { supplied: value !== undefined, bytes: typeof value === "string" ? Buffer.byteLength(value) : undefined }),
|
|
38
56
|
};
|
package/dist/cli/profile.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ export declare const asFirstWord: (profile: string) => string;
|
|
|
4
4
|
export declare const usableProfileName: (profile: string) => string;
|
|
5
5
|
/** The top-level commands that never read a profile; every other one is `<tool> <profile> …`. */
|
|
6
6
|
export declare const PROFILE_FREE: ReadonlySet<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Marks a command, and every command under it, as one that reads no profile, so help shows it without one:
|
|
9
|
+
* `drive doctor`, not `drive personal doctor`. Which commands those are is the CLI's to say.
|
|
10
|
+
*/
|
|
11
|
+
export declare const profileFree: <T extends Command>(command: T) => T;
|
|
12
|
+
/** Whether the command line puts a profile before this command: not for `PROFILE_FREE` or a `profileFree` one. */
|
|
13
|
+
export declare const takesProfile: (command: Command) => boolean;
|
|
7
14
|
/**
|
|
8
15
|
* Every word that means a command at the top level. Taken off the built program rather than
|
|
9
16
|
* written out, because a list written out goes stale the day a command is added — and `help` is in
|
package/dist/cli/profile.js
CHANGED
|
@@ -16,6 +16,25 @@ export const usableProfileName = (profile) => {
|
|
|
16
16
|
};
|
|
17
17
|
/** The top-level commands that never read a profile; every other one is `<tool> <profile> …`. */
|
|
18
18
|
export const PROFILE_FREE = new Set(["commands", "complete", "guide", "help", "skill", "upgrade"]);
|
|
19
|
+
const freeOfProfile = new WeakSet();
|
|
20
|
+
/**
|
|
21
|
+
* Marks a command, and every command under it, as one that reads no profile, so help shows it without one:
|
|
22
|
+
* `drive doctor`, not `drive personal doctor`. Which commands those are is the CLI's to say.
|
|
23
|
+
*/
|
|
24
|
+
export const profileFree = (command) => {
|
|
25
|
+
freeOfProfile.add(command);
|
|
26
|
+
return command;
|
|
27
|
+
};
|
|
28
|
+
/** Whether the command line puts a profile before this command: not for `PROFILE_FREE` or a `profileFree` one. */
|
|
29
|
+
export const takesProfile = (command) => {
|
|
30
|
+
let top;
|
|
31
|
+
for (let at = command; at?.parent; at = at.parent) {
|
|
32
|
+
if (freeOfProfile.has(at))
|
|
33
|
+
return false;
|
|
34
|
+
top = at;
|
|
35
|
+
}
|
|
36
|
+
return top !== undefined && !PROFILE_FREE.has(top.name());
|
|
37
|
+
};
|
|
19
38
|
/**
|
|
20
39
|
* Every word that means a command at the top level. Taken off the built program rather than
|
|
21
40
|
* written out, because a list written out goes stale the day a command is added — and `help` is in
|
package/dist/cli/program.js
CHANGED
|
@@ -10,6 +10,7 @@ import { isCliFailure, isCommanderFailure } from "../errors/failures.js";
|
|
|
10
10
|
import { failureContext } from "../errors/reasons.js";
|
|
11
11
|
import { envName, readOnlyLockOf, readOnlyRefusal } from "../ports/app.js";
|
|
12
12
|
import { recorded, wasSettled } from "../runs/recording.js";
|
|
13
|
+
import { runContextOf } from "../runs/run-context.js";
|
|
13
14
|
import { processRun, useAsProcessRun } from "../runs/scope.js";
|
|
14
15
|
import { AUTHORITY_KEY, BOT_API_KEY, isBotApi, keyForCommand } from "../sends/permissions.js";
|
|
15
16
|
import { logParsedArgv, logVersion } from "./argv-log.js";
|
|
@@ -17,7 +18,7 @@ import { commandAvailability } from "./command-availability.js";
|
|
|
17
18
|
import { commandPathOf } from "./command-contract.js";
|
|
18
19
|
import { outputFor, provide } from "./context.js";
|
|
19
20
|
import { refuseWriteBeforeConnecting } from "./early-refusal.js";
|
|
20
|
-
import { changesAuthorityAt, changesAuthorityNow, isLogin, isStoreChange, judgedEffects, judgedTargets,
|
|
21
|
+
import { changesAuthorityAt, changesAuthorityNow, isLogin, isStoreChange, judgedEffects, judgedTargets, storeChangeRefusal, } from "./effects.js";
|
|
21
22
|
import { itemOf, renderAnswer, snakeKeys } from "./envelope.js";
|
|
22
23
|
import { byteCount, DEFAULT_COMMAND_MS, DEFAULT_OUTPUT_BYTES, execution } from "./execution.js";
|
|
23
24
|
import { setupAtStart } from "./first-run.js";
|
|
@@ -26,7 +27,7 @@ import { showInputFields } from "./input-fields.js";
|
|
|
26
27
|
import { MAX_BUFFERED_INPUT, provideInputPolicy } from "./input-policy.js";
|
|
27
28
|
import { checkJson, liftJson } from "./json-fields.js";
|
|
28
29
|
import { PreviewComplete, preview } from "./preview.js";
|
|
29
|
-
import { commandWords, liftProfile,
|
|
30
|
+
import { commandWords, liftProfile, sampleCommand, takesProfile, valuedOptions } from "./profile.js";
|
|
30
31
|
import { absolutePaths, relayTarget } from "./relay-route.js";
|
|
31
32
|
import { NoProfileHere, namedProfile, settingsFor, } from "./settings.js";
|
|
32
33
|
import { assertSharedContracts } from "./shared-contracts.js";
|
|
@@ -73,14 +74,15 @@ export const createProgram = ({ app, commands, configure, firstScreen }, { out,
|
|
|
73
74
|
assertSharedContracts(program);
|
|
74
75
|
installHelp(program, { pitch: app.description, ...firstScreen });
|
|
75
76
|
// Commander builds a usage line from the command tree, where the profile is not a word.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
if (firstScreen?.profile !== false)
|
|
78
|
+
for (const top of program.commands)
|
|
79
|
+
forEachCommand(top, (command) => command.configureHelp({
|
|
80
|
+
...command.configureHelp(),
|
|
81
|
+
commandUsage: (shown) => {
|
|
82
|
+
const usage = new Help().commandUsage(shown);
|
|
83
|
+
return takesProfile(shown) ? `${app.command} <profile>${usage.slice(app.command.length)}` : usage;
|
|
84
|
+
},
|
|
85
|
+
}));
|
|
84
86
|
// Depth-first: Commander does not pass `configureOutput` down to a command added with
|
|
85
87
|
// `addCommand`, so `tg messages --help` would write to the real terminal.
|
|
86
88
|
if (out || err) {
|
|
@@ -191,6 +193,7 @@ const runOnce = async (argv, definition, options) => {
|
|
|
191
193
|
const exit = {};
|
|
192
194
|
const environment = {
|
|
193
195
|
...options,
|
|
196
|
+
argv,
|
|
194
197
|
streams: control.streams,
|
|
195
198
|
signal: options.signal ? AbortSignal.any([control.signal, options.signal]) : control.signal,
|
|
196
199
|
commandSignal: control.signal,
|
|
@@ -267,20 +270,22 @@ const runOnce = async (argv, definition, options) => {
|
|
|
267
270
|
const path = commandPathOf(action);
|
|
268
271
|
const lock = readOnlyLockOf(definition.app, commandEnv);
|
|
269
272
|
const input = options.stdin ?? process.stdin;
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
273
|
+
// The first-run questions write the shared config; a dry run writes nothing.
|
|
274
|
+
if (!flags.dryRun)
|
|
275
|
+
await setupAtStart({
|
|
276
|
+
command,
|
|
277
|
+
env: commandEnv,
|
|
278
|
+
contentLanguages: definition.app.contentLanguages,
|
|
279
|
+
path,
|
|
280
|
+
headless,
|
|
281
|
+
readOnlyLock: lock,
|
|
282
|
+
input,
|
|
283
|
+
terminal: !options.streams && input.isTTY === true && process.stderr.isTTY === true,
|
|
284
|
+
});
|
|
280
285
|
if (lock && isLogin(action) && !flags.dryRun)
|
|
281
286
|
throw readOnlyRefusal(lock, "log in or out");
|
|
282
287
|
if (lock && isStoreChange(action) && !flags.dryRun)
|
|
283
|
-
throw readOnlyRefusal(lock,
|
|
288
|
+
throw readOnlyRefusal(lock, storeChangeRefusal(definition.app));
|
|
284
289
|
refuseWriteBeforeConnecting(action, {
|
|
285
290
|
app: definition.app,
|
|
286
291
|
env: commandEnv,
|
|
@@ -385,7 +390,7 @@ const runOnce = async (argv, definition, options) => {
|
|
|
385
390
|
configPath: resolved.configPath ?? "",
|
|
386
391
|
profile: resolved.profile,
|
|
387
392
|
...(resolved.savedPermissions ? { savedPermissions: resolved.savedPermissions } : {}),
|
|
388
|
-
}, command, definition.configuration?.permissionKey);
|
|
393
|
+
}, command, definition.configuration?.permissionKey, definition.app.messenger !== false);
|
|
389
394
|
renderAnswer(action, outputFor(action), itemOf(snakeKeys(previewed)));
|
|
390
395
|
throw new PreviewComplete();
|
|
391
396
|
}
|
|
@@ -412,7 +417,7 @@ const runOnce = async (argv, definition, options) => {
|
|
|
412
417
|
refuseJoinedPath(program, words.filter((word) => !word.startsWith("-")), profile !== undefined && !/\s/.test(profile) ? [profile] : []);
|
|
413
418
|
}
|
|
414
419
|
catch (failure) {
|
|
415
|
-
const settled = await settleFailure(failure, { definition, program, rest: lifted, profile, options });
|
|
420
|
+
const settled = await settleFailure(failure, { definition, program, rest: lifted, argv, profile, options });
|
|
416
421
|
return report(streams, reporting, failed(definition, program, lifted, failure, settled, debug));
|
|
417
422
|
}
|
|
418
423
|
if (profile !== undefined)
|
|
@@ -427,7 +432,7 @@ const runOnce = async (argv, definition, options) => {
|
|
|
427
432
|
const message = `"${profile}" is not a command, so it was read as a profile name — and no command followed it. ` +
|
|
428
433
|
`Run \`${command} --help\` for the commands, or \`${command} ${profile} account show\` if "${profile}" is your profile.`;
|
|
429
434
|
const failure = new CliError("validation_error", message, { param: "profile" });
|
|
430
|
-
const settled = await settleFailure(failure, { definition, program, rest, profile, options });
|
|
435
|
+
const settled = await settleFailure(failure, { definition, program, rest, argv, profile, options });
|
|
431
436
|
return report(streams, reporting, failed(definition, program, rest, failure, settled, debug));
|
|
432
437
|
}
|
|
433
438
|
try {
|
|
@@ -472,10 +477,10 @@ const runOnce = async (argv, definition, options) => {
|
|
|
472
477
|
message += ` — "${profile}" is not a command, so it was read as a profile name — which left "${rest[0]}" to be one.`;
|
|
473
478
|
}
|
|
474
479
|
const failure = new CliError("validation_error", message);
|
|
475
|
-
const settled = await settleFailure(failure, { definition, program, rest, profile, options });
|
|
480
|
+
const settled = await settleFailure(failure, { definition, program, rest, argv, profile, options });
|
|
476
481
|
return report(streams, reporting, failed(definition, program, rest, failure, settled, debug));
|
|
477
482
|
}
|
|
478
|
-
const settled = await settleFailure(error, { definition, program, rest, profile, options });
|
|
483
|
+
const settled = await settleFailure(error, { definition, program, rest, argv, profile, options });
|
|
479
484
|
const exit = report(streams, reporting, failed(definition, program, rest, error, settled, debug));
|
|
480
485
|
return signalExit ?? exit;
|
|
481
486
|
}
|
|
@@ -562,9 +567,9 @@ const settleFailure = async (failure, state) => {
|
|
|
562
567
|
/**
|
|
563
568
|
* **Every failure is kept as a run** — a usage error, a configuration that will not load, a command
|
|
564
569
|
* that never opens a run — unless recording was turned off. One its own run already kept is skipped.
|
|
565
|
-
*
|
|
570
|
+
* Its arguments are kept masked (`maskArgv`): a value that can be a message never is.
|
|
566
571
|
*/
|
|
567
|
-
const keepFailure = async (failure, { definition, program, rest, profile, options }) => {
|
|
572
|
+
const keepFailure = async (failure, { definition, program, rest, argv, profile, options }) => {
|
|
568
573
|
if (wasSettled(failure))
|
|
569
574
|
return;
|
|
570
575
|
const env = options.env ?? process.env;
|
|
@@ -577,9 +582,17 @@ const keepFailure = async (failure, { definition, program, rest, profile, option
|
|
|
577
582
|
catch {
|
|
578
583
|
// A configuration that will not load is a failure worth keeping too; the flags are all there is to go on.
|
|
579
584
|
}
|
|
585
|
+
const command = `${options.agent ? "mcp " : ""}${path || definition.app.command}`;
|
|
580
586
|
await recorded({
|
|
581
587
|
app: definition.app,
|
|
582
|
-
command
|
|
588
|
+
command,
|
|
589
|
+
context: runContextOf({
|
|
590
|
+
bin: definition.app.command,
|
|
591
|
+
command: path ? command : options.agent ? "mcp" : "",
|
|
592
|
+
program,
|
|
593
|
+
argv,
|
|
594
|
+
env,
|
|
595
|
+
}),
|
|
583
596
|
profile: settings ? namedProfile(settings) : profile,
|
|
584
597
|
record: false,
|
|
585
598
|
keepFailed: settings?.keepFailedRuns ?? !rest.includes("--no-record"),
|