@wirecat/cli-core 0.423.0 → 0.424.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ Notable changes to `@wirecat/cli-core` (`@wirecat/cli-messaging` up to 0.261.0,
5
5
  minor version may break callers, and says how under "Changed — may break callers". `pnpm docs:check` checks the
6
6
  shape of this file.
7
7
 
8
+ ## Unreleased
9
+
10
+ ## 0.424.0 — 25.10.2026
11
+
12
+ ### Changed — may break callers
13
+
14
+ - **A run with no profile named is recorded with no profile, not `"profile": "default"`** (WC-ACCT-1). `run.json`, `runs list`, `runs show` and `search runs` leave `profile` out for such a run — a failure kept from `tg chats list` with no profile, an MCP call with none, or a `--record` of a command that needs none. A profile the owner named, `default` included, is recorded as before. Records already on disk keep what they say. `RunMetadata.profile`, `RecordingOptions.profile` and `StartRunOptions.profile` are optional, and the `run` entity's `profile` is optional; a caller that read the field as always present checks for it first. `namedProfile(settings)` from `/cli` gives the profile a command was run for, or nothing.
15
+
16
+ ### Fixed
17
+
18
+ - **With no profile anywhere, the error suggests `setup` only to a CLI that has a `setup` command** (WC-ACCT-3). tg, max and wa still say ``create one with `tg personal setup` (any name in place of personal)``. A CLI without `setup`, such as one made from cli-template, now says ``any name works, such as `clidev personal mcp` (or set CLIDEV_PROFILE)``, naming the command that was typed. `details.profiles` stays `[]`.
19
+
8
20
  ## 0.423.0 — 25.10.2026
9
21
 
10
22
  ### Added
@@ -8,7 +8,7 @@ import type { EventSink } from "../runs/events.js";
8
8
  import type { OpenRecognizer } from "../speech/transcribe.js";
9
9
  import type { SecretInput } from "../terminal/prompt.js";
10
10
  import { type Closeable } from "./deadline.js";
11
- import type { GlobalFlags, ResolveOptions, Settings } from "./settings.js";
11
+ import { type GlobalFlags, type ResolveOptions, type Settings } from "./settings.js";
12
12
  /** What every CLI's commands write to, when it is not the real terminal. A CLI adds its own fields. */
13
13
  export interface BaseEnvironment {
14
14
  discoveryAvailability?: (command: import("./command-availability.js").AvailabilityCommand) => import("./command-availability.js").CommandAvailability | undefined;
@@ -4,6 +4,7 @@ import { recorded } from "../runs/recording.js";
4
4
  import { withDeadline } from "./deadline.js";
5
5
  import { withAbort } from "./execution.js";
6
6
  import { rootOf } from "./profile.js";
7
+ import { namedProfile } from "./settings.js";
7
8
  /** A partial answer's exit code, for this run alone. */
8
9
  export const setExitCode = (command, code) => {
9
10
  const slot = environmentOf(command).exit;
@@ -60,6 +61,7 @@ export const baseContext = (command, resolveSettings) => {
60
61
  ...(environment.tty === undefined ? {} : { tty: environment.tty }),
61
62
  });
62
63
  const closeables = [];
64
+ const ranFor = namedProfile(settings);
63
65
  return {
64
66
  settings,
65
67
  renderer,
@@ -74,7 +76,7 @@ export const baseContext = (command, resolveSettings) => {
74
76
  app: environment.app,
75
77
  // An agent's run is named `mcp <command>`, so `search runs` and `sends list` tell it from the owner's.
76
78
  command: name ?? `${environment.agent ? "mcp " : ""}${commandPath(command)}`,
77
- profile: settings.profile,
79
+ ...(ranFor === undefined ? {} : { profile: ranFor }),
78
80
  record: settings.record,
79
81
  keepFailed: settings.keepFailedRuns,
80
82
  trace: settings.trace,
@@ -103,7 +103,7 @@ export { knownBeside, knownPermissionKeys, type PermissionKeyOf, unknownPermissi
103
103
  export { asFirstWord, commandWords, liftProfile, refuseCommandName, rootOf, 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
- export { type Config, type Configuration, count, first, flag, fromFile, type GlobalFlags, NONE_NAMED, type ProfileKind, plain, type ResolveOptions, type Settings, type SettingsExtension, type SettingsExtensionContext, type Source, settingsFor, } from "./settings.js";
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";
107
107
  export { type PermissionAnswer, readSetupAnswers, type SetupAnswers, setupPermissionCeiling } from "./setup-answers.js";
108
108
  export { AGENTS, type Agent, agentFor, screenFor } from "./setup-screen.js";
109
109
  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";
package/dist/cli/index.js CHANGED
@@ -93,7 +93,7 @@ export { knownBeside, knownPermissionKeys, unknownPermissionKeys } from "./permi
93
93
  export { asFirstWord, commandWords, liftProfile, refuseCommandName, rootOf, usableProfileName } from "./profile.js";
94
94
  export { createProgram, run } from "./program.js";
95
95
  export { fieldsOf, projectFields } from "./result-fields.js";
96
- export { count, first, flag, fromFile, NONE_NAMED, plain, settingsFor, } from "./settings.js";
96
+ export { count, first, flag, fromFile, NONE_NAMED, namedProfile, plain, settingsFor, } from "./settings.js";
97
97
  export { readSetupAnswers, setupPermissionCeiling } from "./setup-answers.js";
98
98
  export { AGENTS, agentFor, screenFor } from "./setup-screen.js";
99
99
  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";
@@ -10,7 +10,7 @@ export interface ProgramDefinition {
10
10
  /** The CLI's own settings, for keeping a failure that happened before its command could; plain ones without. */
11
11
  configuration?: {
12
12
  permissionKey?: (path: readonly string[]) => string | null | undefined;
13
- resolveSettings: (flags?: GlobalFlags, options?: ResolveOptions) => Pick<Settings, "profile" | "keepFailedRuns" | "keepRunsForDays" | "skillHint"> & Partial<Pick<Settings, "permissions" | "permissionSources" | "configPath" | "savedPermissions">>;
13
+ resolveSettings: (flags?: GlobalFlags, options?: ResolveOptions) => Pick<Settings, "profile" | "keepFailedRuns" | "keepRunsForDays" | "skillHint"> & Partial<Pick<Settings, "permissions" | "permissionSources" | "configPath" | "savedPermissions" | "sources">>;
14
14
  };
15
15
  configure?: (program: Command) => void;
16
16
  /** The tool's pitch and "what you can do" lines on `--help` and a bare run. */
@@ -28,7 +28,7 @@ import { checkJson, liftJson } from "./json-fields.js";
28
28
  import { PreviewComplete, preview } from "./preview.js";
29
29
  import { commandWords, liftProfile, PROFILE_FREE, sampleCommand, valuedOptions } from "./profile.js";
30
30
  import { absolutePaths, relayTarget } from "./relay-route.js";
31
- import { settingsFor } from "./settings.js";
31
+ import { NoProfileHere, namedProfile, settingsFor, } from "./settings.js";
32
32
  import { assertSharedContracts } from "./shared-contracts.js";
33
33
  import { commandAt, lineOf, withLines } from "./steps.js";
34
34
  /**
@@ -580,7 +580,7 @@ const keepFailure = async (failure, { definition, program, rest, profile, option
580
580
  await recorded({
581
581
  app: definition.app,
582
582
  command: `${options.agent ? "mcp " : ""}${path || definition.app.command}`,
583
- profile: settings?.profile ?? profile ?? "default",
583
+ profile: settings ? namedProfile(settings) : profile,
584
584
  record: false,
585
585
  keepFailed: settings?.keepFailedRuns ?? !rest.includes("--no-record"),
586
586
  trace: false,
@@ -609,10 +609,11 @@ const commandPath = (program, rest) => {
609
609
  return words.join(" ");
610
610
  };
611
611
  const failed = ({ app }, program, rest, error, settled, debug) => {
612
- const failure = settled.settlementFailed && isCliFailure(error)
613
- ? new CliError(error.code, error.message, { ...error.details, settlement_failed: true })
614
- : error;
615
612
  const path = commandPath(program, program.args.length > 0 ? program.args : rest);
613
+ const told = error instanceof NoProfileHere && !commandAt(program, "setup") ? error.withoutSetup(path) : error;
614
+ const failure = settled.settlementFailed && isCliFailure(told)
615
+ ? new CliError(told.code, told.message, { ...told.details, settlement_failed: true })
616
+ : told;
616
617
  const effects = judgedEffects(path ? metaOf(commandAt(program, path) ?? program).effects : undefined);
617
618
  const object = errorObjectOf(failure, {
618
619
  ...failureContext(app.errors),
@@ -14,7 +14,7 @@ export declare const searchRuns: (dir: string, { query, terms, status, errorCode
14
14
  items: {
15
15
  runId: string;
16
16
  command: string;
17
- profile: string;
17
+ profile: string | undefined;
18
18
  status: "running" | import("../../runs/run.js").RunStatus;
19
19
  startedAt: string;
20
20
  completedAt: string | undefined;
@@ -1,3 +1,4 @@
1
+ import { CliError } from "@wirecat/cli-base";
1
2
  import * as v from "valibot";
2
3
  import { type AISettings } from "../analysis/settings.js";
3
4
  import { type AppIdentity } from "../ports/app.js";
@@ -161,6 +162,18 @@ export interface ResolveOptions {
161
162
  }
162
163
  /** Where `profile` came from when none was named and the command needs none. */
163
164
  export declare const NONE_NAMED = "none named";
165
+ /** The profile a run is for: none when nothing named one, even though `Settings.profile` holds a placeholder. */
166
+ export declare const namedProfile: (settings: Pick<Settings, "profile"> & Partial<Pick<Settings, "sources">>) => string | undefined;
167
+ /**
168
+ * No profile named and none on this computer. The settings cannot see the program, so the program swaps the
169
+ * `setup` this suggests for `withoutSetup` when it has no such command.
170
+ */
171
+ export declare class NoProfileHere extends CliError {
172
+ private readonly app;
173
+ constructor(app: AppIdentity);
174
+ /** `words`: the command that was typed, without its arguments, so the suggestion runs as written. */
175
+ withoutSetup(words: string): CliError;
176
+ }
164
177
  /** The first candidate that is set, and which layer it came from. */
165
178
  export declare const first: <T>(candidates: [Source, T | undefined][], fallback: T) => {
166
179
  value: T;
@@ -81,6 +81,26 @@ const SHARED_DEFAULTS_ONLY = {
81
81
  export const NONE_NAMED = "none named";
82
82
  /** A name for a command that speaks for no account; never chosen for one that does. */
83
83
  const NO_PROFILE = "default";
84
+ /** The profile a run is for: none when nothing named one, even though `Settings.profile` holds a placeholder. */
85
+ export const namedProfile = (settings) => settings.sources?.profile === NONE_NAMED ? undefined : settings.profile;
86
+ /**
87
+ * No profile named and none on this computer. The settings cannot see the program, so the program swaps the
88
+ * `setup` this suggests for `withoutSetup` when it has no such command.
89
+ */
90
+ export class NoProfileHere extends CliError {
91
+ app;
92
+ constructor(app) {
93
+ super("validation_error", `name a profile: there is none on this computer yet — create one with \`${app.command} personal setup\` ` +
94
+ "(any name in place of personal)", { profiles: [] });
95
+ this.app = app;
96
+ }
97
+ /** `words`: the command that was typed, without its arguments, so the suggestion runs as written. */
98
+ withoutSetup(words) {
99
+ const command = words ? `${this.app.command} personal ${words}` : `${this.app.command} personal …`;
100
+ return new CliError("validation_error", `name a profile: there is none on this computer yet — any name works, such as \`${command}\` ` +
101
+ `(or set ${envName(this.app, "PROFILE")})`, { profiles: [] });
102
+ }
103
+ }
84
104
  /** The first candidate that is set, and which layer it came from. */
85
105
  export const first = (candidates, fallback) => {
86
106
  for (const [from, value] of candidates)
@@ -170,10 +190,9 @@ export const settingsFor = (app, extension = {}) => {
170
190
  if (!needed)
171
191
  return { value: NO_PROFILE, from: NONE_NAMED };
172
192
  const here = profilesOf(config, env);
173
- throw new CliError("validation_error", here.length === 0
174
- ? `name a profile: there is none on this computer yet — create one with \`${app.command} personal setup\` ` +
175
- "(any name in place of personal)"
176
- : `name a profile: \`${app.command} <profile> …\` — profiles here: ${here.join(", ")} (or set ${PROFILE})`, { profiles: here });
193
+ if (here.length === 0)
194
+ throw new NoProfileHere(app);
195
+ throw new CliError("validation_error", `name a profile: \`${app.command} <profile> …\` — profiles here: ${here.join(", ")} (or set ${PROFILE})`, { profiles: here });
177
196
  };
178
197
  const profilesOf = (config, env) => profilesHere(app, [...namedProfiles(config), ...(extension.profiles?.(env) ?? [])], env);
179
198
  const resolveSettings = (flags = {}, options = {}) => {
@@ -6990,7 +6990,7 @@ export declare const ENTITIES: {
6990
6990
  readonly run: v.StrictObjectSchema<{
6991
6991
  readonly run_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
6992
6992
  readonly command: v.StringSchema<undefined>;
6993
- readonly profile: v.StringSchema<undefined>;
6993
+ readonly profile: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
6994
6994
  readonly started_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
6995
6995
  readonly completed_at: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
6996
6996
  readonly status: v.PicklistSchema<["success", "failed", "partial", "running"], undefined>;
@@ -7024,7 +7024,7 @@ export declare const ENTITIES: {
7024
7024
  readonly "run.details": v.StrictObjectSchema<{
7025
7025
  readonly run_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
7026
7026
  readonly command: v.StringSchema<undefined>;
7027
- readonly profile: v.StringSchema<undefined>;
7027
+ readonly profile: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
7028
7028
  readonly started_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
7029
7029
  readonly completed_at: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
7030
7030
  readonly status: v.PicklistSchema<["success", "failed", "partial", "running"], undefined>;
@@ -7057,7 +7057,7 @@ export declare const ENTITIES: {
7057
7057
  readonly "run.hit": v.StrictObjectSchema<{
7058
7058
  readonly run_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
7059
7059
  readonly command: v.StringSchema<undefined>;
7060
- readonly profile: v.StringSchema<undefined>;
7060
+ readonly profile: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
7061
7061
  readonly started_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
7062
7062
  readonly completed_at: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
7063
7063
  readonly status: v.PicklistSchema<["success", "failed", "partial", "running"], undefined>;
@@ -2,7 +2,7 @@ import * as v from "valibot";
2
2
  export declare const recordedRun: v.StrictObjectSchema<{
3
3
  readonly run_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
4
4
  readonly command: v.StringSchema<undefined>;
5
- readonly profile: v.StringSchema<undefined>;
5
+ readonly profile: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
6
6
  readonly started_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
7
7
  readonly completed_at: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
8
8
  readonly status: v.PicklistSchema<["success", "failed", "partial", "running"], undefined>;
@@ -36,7 +36,7 @@ export declare const recordedRun: v.StrictObjectSchema<{
36
36
  export declare const runDetails: v.StrictObjectSchema<{
37
37
  readonly run_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
38
38
  readonly command: v.StringSchema<undefined>;
39
- readonly profile: v.StringSchema<undefined>;
39
+ readonly profile: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
40
40
  readonly started_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
41
41
  readonly completed_at: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
42
42
  readonly status: v.PicklistSchema<["success", "failed", "partial", "running"], undefined>;
@@ -69,7 +69,7 @@ export declare const runDetails: v.StrictObjectSchema<{
69
69
  export declare const runHit: v.StrictObjectSchema<{
70
70
  readonly run_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
71
71
  readonly command: v.StringSchema<undefined>;
72
- readonly profile: v.StringSchema<undefined>;
72
+ readonly profile: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
73
73
  readonly started_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
74
74
  readonly completed_at: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
75
75
  readonly status: v.PicklistSchema<["success", "failed", "partial", "running"], undefined>;
@@ -4,7 +4,7 @@ const events = v.array(v.record(v.string(), v.unknown()));
4
4
  export const recordedRun = v.strictObject({
5
5
  run_id: id,
6
6
  command: text,
7
- profile: text,
7
+ profile: v.optional(text),
8
8
  started_at: time,
9
9
  completed_at: v.optional(time),
10
10
  status: v.picklist(["success", "failed", "partial", "running"]),
package/dist/mcp/tool.js CHANGED
@@ -107,7 +107,9 @@ export const entryRunner = (registration) => {
107
107
  ? startRecording({
108
108
  app,
109
109
  command,
110
- profile: registration.defaults.settings.profile ?? "default",
110
+ ...(registration.defaults.settings.profile === undefined
111
+ ? {}
112
+ : { profile: registration.defaults.settings.profile }),
111
113
  env: registration.defaults.env,
112
114
  record: false,
113
115
  keepFailed: true,
@@ -5,7 +5,8 @@ export interface RecordingOptions {
5
5
  app: AppIdentity;
6
6
  /** As typed, without the arguments: `chats list`. It names the run directory. */
7
7
  command: string;
8
- profile: string;
8
+ /** Unset when nothing named one: a run is never put down to a profile the owner did not choose. */
9
+ profile?: string;
9
10
  record: boolean;
10
11
  /** Keep the run if it fails, even though `record` is off. */
11
12
  keepFailed: boolean;
@@ -19,7 +19,7 @@ export const recorded = async (options, body) => {
19
19
  runId: recording.runId,
20
20
  command: options.command,
21
21
  startedAt: Date.now(),
22
- profile: options.profile,
22
+ ...(options.profile === undefined ? {} : { profile: options.profile }),
23
23
  ...(recording.traceId ? { traceId: recording.traceId } : {}),
24
24
  };
25
25
  if (options.processRun)
@@ -44,7 +44,7 @@ export const startRecording = (options) => {
44
44
  runsDir: options.runsDir ?? runsDirFor(options.app, options.env),
45
45
  runId,
46
46
  command: options.command,
47
- profile: options.profile,
47
+ ...(options.profile === undefined ? {} : { profile: options.profile }),
48
48
  service: options.app.command,
49
49
  cliVersion: options.app.version,
50
50
  ...(traceId === undefined ? {} : { traceId }),
@@ -10,7 +10,8 @@ export interface RunMetadata {
10
10
  runId: string;
11
11
  /** As typed, without the arguments: `chats list`, `messages send`. */
12
12
  command: string;
13
- profile: string;
13
+ /** Left out when the command named no profile. */
14
+ profile?: string;
14
15
  startedAt: string;
15
16
  completedAt?: string;
16
17
  status: RunStatus | "running";
@@ -47,7 +48,7 @@ export interface RunMetadata {
47
48
  export interface StartRunOptions {
48
49
  runsDir: string;
49
50
  command: string;
50
- profile: string;
51
+ profile?: string;
51
52
  /** The log record's `resource.service`: the program's own name, `tg` or `max`. */
52
53
  service: string;
53
54
  cliVersion: string;
package/dist/runs/run.js CHANGED
@@ -66,7 +66,7 @@ export const startRun = (options) => {
66
66
  const metadata = {
67
67
  runId: id,
68
68
  command: options.command,
69
- profile: options.profile,
69
+ ...(options.profile === undefined ? {} : { profile: options.profile }),
70
70
  startedAt: startedAt.toISOString(),
71
71
  status: "running",
72
72
  cliVersion: options.cliVersion,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-core",
3
- "version": "0.423.0",
3
+ "version": "0.424.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",