@wirecat/cli-core 0.389.0 → 0.390.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
@@ -15,6 +15,11 @@ shape of this file.
15
15
  so a local transcript beside the provider's does not count twice. `meetings.meetingStats` on the store and
16
16
  `aggregateMeetingStats` for rows a host already has.
17
17
 
18
+ ### Fixed
19
+
20
+ - **A recorded one-shot command's `meta.run_id` names the run it kept**, so `runs show <run_id>` finds it. It named
21
+ the process's own run, which is never kept.
22
+
18
23
  ## 0.388.0 — 22.10.2026
19
24
 
20
25
  ### Added
@@ -79,6 +79,7 @@ export const baseContext = (command, resolveSettings) => {
79
79
  keepFailed: settings.keepFailedRuns,
80
80
  trace: settings.trace,
81
81
  keepDays: settings.keepRunsForDays,
82
+ processRun: !environment.agent,
82
83
  format,
83
84
  streams,
84
85
  env,
@@ -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 { processRun, useAsProcessRun } from "../runs/scope.js";
13
14
  import { keyForCommand } from "../sends/permissions.js";
14
15
  import { logParsedArgv, logVersion } from "./argv-log.js";
15
16
  import { commandPathOf } from "./command-contract.js";
@@ -104,6 +105,15 @@ const RELAY_MARGIN_MS = 10_000;
104
105
  * message: it tells a script nothing it can branch on, and exits 1 for every kind of failure alike.
105
106
  */
106
107
  export const run = async (argv, definition, options = {}) => {
108
+ const outer = processRun();
109
+ try {
110
+ return await runOnce(argv, definition, options);
111
+ }
112
+ finally {
113
+ useAsProcessRun(outer);
114
+ }
115
+ };
116
+ const runOnce = async (argv, definition, options) => {
107
117
  const streams = options.streams ?? processStreams;
108
118
  if (!options.streams)
109
119
  quietBrokenPipes();
@@ -19,6 +19,11 @@ export interface RecordingOptions {
19
19
  now?: () => Date;
20
20
  /** The caller's trace; otherwise the enclosing run's, otherwise `TRACEPARENT` from `env`. */
21
21
  traceId?: string;
22
+ /**
23
+ * A one-shot command prints its answer after the run ends, outside `inRun`: naming the run as the process's lets
24
+ * that answer's `meta.run_id` name the run `runs show` finds. Never in a server, where runs overlap.
25
+ */
26
+ processRun?: boolean;
22
27
  }
23
28
  /**
24
29
  * Runs one command with the diagnostics turned on, and **finalizes on every path**.
@@ -4,7 +4,7 @@ import { providerErrorKey, renderEvent } from "./events.js";
4
4
  import { DIAGNOSTIC_LOG_EVENTS } from "./log-events.js";
5
5
  import { logAttributes } from "./log-keys.js";
6
6
  import { newRunId, runsDirFor, startRun } from "./run.js";
7
- import { enclosingTraceId, inRun, traceOf } from "./scope.js";
7
+ import { enclosingTraceId, inRun, traceOf, useAsProcessRun } from "./scope.js";
8
8
  /**
9
9
  * Runs one command with the diagnostics turned on, and **finalizes on every path**.
10
10
  *
@@ -15,13 +15,16 @@ import { enclosingTraceId, inRun, traceOf } from "./scope.js";
15
15
  export const recorded = async (options, body) => {
16
16
  const recording = startRecording(options);
17
17
  try {
18
- const answer = await inRun({
18
+ const scope = {
19
19
  runId: recording.runId,
20
20
  command: options.command,
21
21
  startedAt: Date.now(),
22
22
  profile: options.profile,
23
23
  ...(recording.traceId ? { traceId: recording.traceId } : {}),
24
- }, () => body(recording.events));
24
+ };
25
+ if (options.processRun)
26
+ useAsProcessRun(scope);
27
+ const answer = await inRun(scope, () => body(recording.events));
25
28
  await recording.succeed(answer);
26
29
  return answer;
27
30
  }
@@ -23,7 +23,9 @@ export declare const typedCommand: (tool: string, words: string, profile?: strin
23
23
  * For a one-shot command whose action runs outside `inRun` — max's `max bot`, recorded from commander's hooks, which
24
24
  * cannot wrap the action — so its answers' `meta.run_id` names the run `runs show` finds. Never in a server.
25
25
  */
26
- export declare const useAsProcessRun: (scope: RunScope) => void;
26
+ export declare const useAsProcessRun: (scope: RunScope | undefined) => void;
27
+ /** The run `useAsProcessRun` named, if any: a command run in-process puts it back when it ends. */
28
+ export declare const processRun: () => RunScope | undefined;
27
29
  /** The trace of the run this one is opened inside — an MCP call's command keeps its caller's trace. */
28
30
  export declare const enclosingTraceId: () => string | undefined;
29
31
  /**
@@ -33,6 +33,8 @@ export const typedCommand = (tool, words, profile = currentRun().profile) => [to
33
33
  export const useAsProcessRun = (scope) => {
34
34
  processScope = scope;
35
35
  };
36
+ /** The run `useAsProcessRun` named, if any: a command run in-process puts it back when it ends. */
37
+ export const processRun = () => processScope;
36
38
  /** The trace of the run this one is opened inside — an MCP call's command keeps its caller's trace. */
37
39
  export const enclosingTraceId = () => scopes.getStore()?.traceId;
38
40
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-core",
3
- "version": "0.389.0",
3
+ "version": "0.390.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",