@os-eco/overstory-cli 0.6.1 → 0.6.5
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/README.md +8 -7
- package/package.json +12 -4
- package/src/agents/checkpoint.test.ts +2 -2
- package/src/agents/hooks-deployer.test.ts +131 -16
- package/src/agents/hooks-deployer.ts +33 -1
- package/src/agents/identity.test.ts +27 -27
- package/src/agents/identity.ts +10 -10
- package/src/agents/lifecycle.test.ts +6 -6
- package/src/agents/lifecycle.ts +2 -2
- package/src/agents/manifest.test.ts +86 -0
- package/src/agents/overlay.test.ts +9 -9
- package/src/agents/overlay.ts +4 -4
- package/src/commands/agents.test.ts +8 -8
- package/src/commands/agents.ts +62 -91
- package/src/commands/clean.test.ts +36 -51
- package/src/commands/clean.ts +28 -49
- package/src/commands/completions.ts +14 -0
- package/src/commands/coordinator.test.ts +133 -26
- package/src/commands/coordinator.ts +101 -64
- package/src/commands/costs.test.ts +47 -47
- package/src/commands/costs.ts +96 -75
- package/src/commands/dashboard.test.ts +2 -2
- package/src/commands/dashboard.ts +75 -95
- package/src/commands/doctor.test.ts +2 -2
- package/src/commands/doctor.ts +92 -79
- package/src/commands/errors.test.ts +2 -2
- package/src/commands/errors.ts +56 -50
- package/src/commands/feed.test.ts +2 -2
- package/src/commands/feed.ts +86 -83
- package/src/commands/group.ts +167 -177
- package/src/commands/hooks.test.ts +2 -2
- package/src/commands/hooks.ts +52 -42
- package/src/commands/init.test.ts +19 -19
- package/src/commands/init.ts +7 -16
- package/src/commands/inspect.test.ts +18 -18
- package/src/commands/inspect.ts +55 -58
- package/src/commands/log.test.ts +26 -31
- package/src/commands/log.ts +97 -91
- package/src/commands/logs.test.ts +1 -1
- package/src/commands/logs.ts +101 -104
- package/src/commands/mail.test.ts +5 -5
- package/src/commands/mail.ts +157 -169
- package/src/commands/merge.test.ts +28 -66
- package/src/commands/merge.ts +21 -51
- package/src/commands/metrics.test.ts +8 -8
- package/src/commands/metrics.ts +34 -35
- package/src/commands/monitor.test.ts +3 -3
- package/src/commands/monitor.ts +57 -62
- package/src/commands/nudge.test.ts +1 -1
- package/src/commands/nudge.ts +41 -89
- package/src/commands/prime.test.ts +19 -51
- package/src/commands/prime.ts +13 -50
- package/src/commands/replay.test.ts +2 -2
- package/src/commands/replay.ts +79 -86
- package/src/commands/run.test.ts +1 -1
- package/src/commands/run.ts +97 -77
- package/src/commands/sling.test.ts +201 -5
- package/src/commands/sling.ts +37 -64
- package/src/commands/spec.test.ts +14 -40
- package/src/commands/spec.ts +32 -101
- package/src/commands/status.test.ts +97 -1
- package/src/commands/status.ts +63 -58
- package/src/commands/stop.test.ts +22 -40
- package/src/commands/stop.ts +18 -33
- package/src/commands/supervisor.test.ts +12 -14
- package/src/commands/supervisor.ts +144 -165
- package/src/commands/trace.test.ts +15 -15
- package/src/commands/trace.ts +59 -82
- package/src/commands/watch.test.ts +2 -2
- package/src/commands/watch.ts +38 -45
- package/src/commands/worktree.test.ts +213 -37
- package/src/commands/worktree.ts +110 -55
- package/src/config.test.ts +96 -0
- package/src/doctor/consistency.test.ts +14 -14
- package/src/doctor/databases.test.ts +22 -2
- package/src/doctor/databases.ts +16 -0
- package/src/doctor/dependencies.test.ts +55 -1
- package/src/doctor/dependencies.ts +113 -18
- package/src/doctor/merge-queue.test.ts +4 -4
- package/src/e2e/init-sling-lifecycle.test.ts +8 -8
- package/src/errors.ts +1 -1
- package/src/index.ts +223 -213
- package/src/logging/color.test.ts +74 -91
- package/src/logging/color.ts +52 -46
- package/src/logging/reporter.test.ts +10 -10
- package/src/logging/reporter.ts +6 -5
- package/src/mail/broadcast.test.ts +1 -1
- package/src/mail/client.test.ts +6 -6
- package/src/mail/store.test.ts +3 -3
- package/src/merge/queue.test.ts +73 -7
- package/src/merge/queue.ts +17 -2
- package/src/merge/resolver.test.ts +159 -7
- package/src/merge/resolver.ts +46 -2
- package/src/metrics/store.test.ts +44 -44
- package/src/metrics/store.ts +2 -2
- package/src/metrics/summary.test.ts +35 -35
- package/src/mulch/client.test.ts +1 -1
- package/src/schema-consistency.test.ts +239 -0
- package/src/sessions/compat.test.ts +3 -3
- package/src/sessions/compat.ts +2 -2
- package/src/sessions/store.test.ts +41 -4
- package/src/sessions/store.ts +13 -2
- package/src/types.ts +14 -14
- package/src/watchdog/daemon.test.ts +10 -10
- package/src/watchdog/daemon.ts +1 -1
- package/src/watchdog/health.test.ts +1 -1
- package/src/worktree/manager.test.ts +20 -20
- package/src/worktree/manager.ts +120 -4
- package/src/worktree/tmux.test.ts +98 -9
- package/src/worktree/tmux.ts +18 -0
package/src/commands/trace.ts
CHANGED
|
@@ -2,19 +2,21 @@
|
|
|
2
2
|
* CLI command: overstory trace <target> [--json] [--since <ts>] [--until <ts>] [--limit <n>]
|
|
3
3
|
*
|
|
4
4
|
* Shows a chronological timeline of events for an agent or bead task.
|
|
5
|
-
* Target can be an agent name or a
|
|
5
|
+
* Target can be an agent name or a task ID (resolved to agent name via SessionStore).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { join } from "node:path";
|
|
9
|
+
import { Command } from "commander";
|
|
9
10
|
import { loadConfig } from "../config.ts";
|
|
10
11
|
import { ValidationError } from "../errors.ts";
|
|
11
12
|
import { createEventStore } from "../events/store.ts";
|
|
13
|
+
import type { ColorFn } from "../logging/color.ts";
|
|
12
14
|
import { color } from "../logging/color.ts";
|
|
13
15
|
import { openSessionStore } from "../sessions/compat.ts";
|
|
14
16
|
import type { EventType, StoredEvent } from "../types.ts";
|
|
15
17
|
|
|
16
18
|
/** Labels and colors for each event type. */
|
|
17
|
-
const EVENT_LABELS: Record<EventType, { label: string; color:
|
|
19
|
+
const EVENT_LABELS: Record<EventType, { label: string; color: ColorFn }> = {
|
|
18
20
|
tool_start: { label: "TOOL START", color: color.blue },
|
|
19
21
|
tool_end: { label: "TOOL END ", color: color.blue },
|
|
20
22
|
session_start: { label: "SESSION +", color: color.green },
|
|
@@ -27,22 +29,7 @@ const EVENT_LABELS: Record<EventType, { label: string; color: string }> = {
|
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
|
-
*
|
|
31
|
-
*/
|
|
32
|
-
function getFlag(args: string[], flag: string): string | undefined {
|
|
33
|
-
const idx = args.indexOf(flag);
|
|
34
|
-
if (idx === -1 || idx + 1 >= args.length) {
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
return args[idx + 1];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function hasFlag(args: string[], flag: string): boolean {
|
|
41
|
-
return args.includes(flag);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Detect whether a target string looks like a bead ID.
|
|
32
|
+
* Detect whether a target string looks like a task ID.
|
|
46
33
|
* Bead IDs follow the pattern: word-alphanumeric (e.g., "overstory-rj1k", "myproject-abc1").
|
|
47
34
|
*/
|
|
48
35
|
function looksLikeBeadId(target: string): boolean {
|
|
@@ -142,15 +129,15 @@ function buildEventDetail(event: StoredEvent): string {
|
|
|
142
129
|
function printTimeline(events: StoredEvent[], agentName: string, useAbsoluteTime: boolean): void {
|
|
143
130
|
const w = process.stdout.write.bind(process.stdout);
|
|
144
131
|
|
|
145
|
-
w(`${color.bold
|
|
132
|
+
w(`${color.bold(`Timeline for ${agentName}`)}\n`);
|
|
146
133
|
w(`${"=".repeat(70)}\n`);
|
|
147
134
|
|
|
148
135
|
if (events.length === 0) {
|
|
149
|
-
w(`${color.dim
|
|
136
|
+
w(`${color.dim("No events found.")}\n`);
|
|
150
137
|
return;
|
|
151
138
|
}
|
|
152
139
|
|
|
153
|
-
w(`${color.dim
|
|
140
|
+
w(`${color.dim(`${events.length} event${events.length === 1 ? "" : "s"}`)}\n\n`);
|
|
154
141
|
|
|
155
142
|
let lastDate = "";
|
|
156
143
|
|
|
@@ -161,7 +148,7 @@ function printTimeline(events: StoredEvent[], agentName: string, useAbsoluteTime
|
|
|
161
148
|
if (lastDate !== "") {
|
|
162
149
|
w("\n");
|
|
163
150
|
}
|
|
164
|
-
w(`${color.dim
|
|
151
|
+
w(`${color.dim(`--- ${date} ---`)}\n`);
|
|
165
152
|
lastDate = date;
|
|
166
153
|
}
|
|
167
154
|
|
|
@@ -174,74 +161,35 @@ function printTimeline(events: StoredEvent[], agentName: string, useAbsoluteTime
|
|
|
174
161
|
color: color.gray,
|
|
175
162
|
};
|
|
176
163
|
|
|
177
|
-
const
|
|
178
|
-
event.level === "error" ? color.red : event.level === "warn" ? color.yellow :
|
|
179
|
-
const
|
|
164
|
+
const levelColorFn =
|
|
165
|
+
event.level === "error" ? color.red : event.level === "warn" ? color.yellow : null;
|
|
166
|
+
const applyLevel = (text: string) => (levelColorFn ? levelColorFn(text) : text);
|
|
180
167
|
|
|
181
168
|
const detail = buildEventDetail(event);
|
|
182
|
-
const detailSuffix = detail ? ` ${color.dim
|
|
169
|
+
const detailSuffix = detail ? ` ${color.dim(detail)}` : "";
|
|
183
170
|
|
|
184
|
-
const agentLabel =
|
|
185
|
-
event.agentName !== agentName ? ` ${color.dim}[${event.agentName}]${color.reset}` : "";
|
|
171
|
+
const agentLabel = event.agentName !== agentName ? ` ${color.dim(`[${event.agentName}]`)}` : "";
|
|
186
172
|
|
|
187
173
|
w(
|
|
188
|
-
`${color.dim
|
|
189
|
-
`${
|
|
174
|
+
`${color.dim(timeStr.padStart(10))} ` +
|
|
175
|
+
`${applyLevel(eventInfo.color(color.bold(eventInfo.label)))}` +
|
|
190
176
|
`${agentLabel}${detailSuffix}\n`,
|
|
191
177
|
);
|
|
192
178
|
}
|
|
193
179
|
}
|
|
194
180
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
Options:
|
|
203
|
-
--json Output as JSON array of StoredEvent objects
|
|
204
|
-
--since <timestamp> Start time filter (ISO 8601)
|
|
205
|
-
--until <timestamp> End time filter (ISO 8601)
|
|
206
|
-
--limit <n> Max events to show (default: 100)
|
|
207
|
-
--help, -h Show this help`;
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Entry point for `overstory trace <target> [--json] [--since] [--until] [--limit]`.
|
|
211
|
-
*/
|
|
212
|
-
export async function traceCommand(args: string[]): Promise<void> {
|
|
213
|
-
if (args.includes("--help") || args.includes("-h")) {
|
|
214
|
-
process.stdout.write(`${TRACE_HELP}\n`);
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Extract positional target: first arg that is not a flag or flag value
|
|
219
|
-
const flagsWithValues = new Set(["--since", "--until", "--limit"]);
|
|
220
|
-
const booleanFlags = new Set(["--json", "--help", "-h"]);
|
|
221
|
-
let target: string | undefined;
|
|
222
|
-
for (let i = 0; i < args.length; i++) {
|
|
223
|
-
const arg = args[i];
|
|
224
|
-
if (arg === undefined) continue;
|
|
225
|
-
if (booleanFlags.has(arg)) continue;
|
|
226
|
-
if (flagsWithValues.has(arg)) {
|
|
227
|
-
i++; // skip the value
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
if (arg.startsWith("-")) continue;
|
|
231
|
-
target = arg;
|
|
232
|
-
break;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (!target) {
|
|
236
|
-
throw new ValidationError("Missing target. Usage: overstory trace <agent-name|bead-id>", {
|
|
237
|
-
field: "target",
|
|
238
|
-
});
|
|
239
|
-
}
|
|
181
|
+
interface TraceOpts {
|
|
182
|
+
json?: boolean;
|
|
183
|
+
since?: string;
|
|
184
|
+
until?: string;
|
|
185
|
+
limit?: string;
|
|
186
|
+
}
|
|
240
187
|
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
const
|
|
244
|
-
const
|
|
188
|
+
async function executeTrace(target: string, opts: TraceOpts): Promise<void> {
|
|
189
|
+
const json = opts.json ?? false;
|
|
190
|
+
const sinceStr = opts.since;
|
|
191
|
+
const untilStr = opts.until;
|
|
192
|
+
const limitStr = opts.limit;
|
|
245
193
|
const limit = limitStr ? Number.parseInt(limitStr, 10) : 100;
|
|
246
194
|
|
|
247
195
|
if (Number.isNaN(limit) || limit < 1) {
|
|
@@ -273,15 +221,15 @@ export async function traceCommand(args: string[]): Promise<void> {
|
|
|
273
221
|
let agentName = target;
|
|
274
222
|
|
|
275
223
|
if (looksLikeBeadId(target)) {
|
|
276
|
-
// Try to resolve
|
|
224
|
+
// Try to resolve task ID to agent name via SessionStore
|
|
277
225
|
const { store: sessionStore } = openSessionStore(overstoryDir);
|
|
278
226
|
try {
|
|
279
227
|
const allSessions = sessionStore.getAll();
|
|
280
|
-
const matchingSession = allSessions.find((s) => s.
|
|
228
|
+
const matchingSession = allSessions.find((s) => s.taskId === target);
|
|
281
229
|
if (matchingSession) {
|
|
282
230
|
agentName = matchingSession.agentName;
|
|
283
231
|
} else {
|
|
284
|
-
// No session found for this
|
|
232
|
+
// No session found for this task ID; treat it as an agent name anyway
|
|
285
233
|
// (the event query will return empty results if no events match)
|
|
286
234
|
agentName = target;
|
|
287
235
|
}
|
|
@@ -323,3 +271,32 @@ export async function traceCommand(args: string[]): Promise<void> {
|
|
|
323
271
|
eventStore.close();
|
|
324
272
|
}
|
|
325
273
|
}
|
|
274
|
+
|
|
275
|
+
export function createTraceCommand(): Command {
|
|
276
|
+
return new Command("trace")
|
|
277
|
+
.description("Chronological event timeline for agent/bead")
|
|
278
|
+
.argument("<target>", "Agent name or task ID")
|
|
279
|
+
.option("--json", "Output as JSON array of StoredEvent objects")
|
|
280
|
+
.option("--since <timestamp>", "Start time filter (ISO 8601)")
|
|
281
|
+
.option("--until <timestamp>", "End time filter (ISO 8601)")
|
|
282
|
+
.option("--limit <n>", "Max events to show (default: 100)")
|
|
283
|
+
.action(async (target: string, opts: TraceOpts) => {
|
|
284
|
+
await executeTrace(target, opts);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export async function traceCommand(args: string[]): Promise<void> {
|
|
289
|
+
const cmd = createTraceCommand();
|
|
290
|
+
cmd.exitOverride();
|
|
291
|
+
try {
|
|
292
|
+
await cmd.parseAsync(args, { from: "user" });
|
|
293
|
+
} catch (err: unknown) {
|
|
294
|
+
if (err && typeof err === "object" && "code" in err) {
|
|
295
|
+
const code = (err as { code: string }).code;
|
|
296
|
+
if (code === "commander.helpDisplayed" || code === "commander.version") {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
throw err;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
@@ -81,7 +81,7 @@ describe("watchCommand", () => {
|
|
|
81
81
|
await watchCommand(["--help"]);
|
|
82
82
|
const out = output();
|
|
83
83
|
|
|
84
|
-
expect(out).toContain("
|
|
84
|
+
expect(out).toContain("watch");
|
|
85
85
|
expect(out).toContain("--interval");
|
|
86
86
|
expect(out).toContain("--background");
|
|
87
87
|
expect(out).toContain("Tier 0");
|
|
@@ -91,7 +91,7 @@ describe("watchCommand", () => {
|
|
|
91
91
|
await watchCommand(["-h"]);
|
|
92
92
|
const out = output();
|
|
93
93
|
|
|
94
|
-
expect(out).toContain("
|
|
94
|
+
expect(out).toContain("watch");
|
|
95
95
|
expect(out).toContain("Tier 0");
|
|
96
96
|
});
|
|
97
97
|
|
package/src/commands/watch.ts
CHANGED
|
@@ -7,27 +7,13 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { join } from "node:path";
|
|
10
|
+
import { Command } from "commander";
|
|
10
11
|
import { loadConfig } from "../config.ts";
|
|
11
12
|
import { OverstoryError } from "../errors.ts";
|
|
12
13
|
import type { HealthCheck } from "../types.ts";
|
|
13
14
|
import { startDaemon } from "../watchdog/daemon.ts";
|
|
14
15
|
import { isProcessRunning } from "../watchdog/health.ts";
|
|
15
16
|
|
|
16
|
-
/**
|
|
17
|
-
* Parse a named flag value from args.
|
|
18
|
-
*/
|
|
19
|
-
function getFlag(args: string[], flag: string): string | undefined {
|
|
20
|
-
const idx = args.indexOf(flag);
|
|
21
|
-
if (idx === -1 || idx + 1 >= args.length) {
|
|
22
|
-
return undefined;
|
|
23
|
-
}
|
|
24
|
-
return args[idx + 1];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function hasFlag(args: string[], flag: string): boolean {
|
|
28
|
-
return args.includes(flag);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
17
|
/**
|
|
32
18
|
* Format a health check for display.
|
|
33
19
|
*/
|
|
@@ -126,44 +112,21 @@ async function resolveOverstoryBin(): Promise<string> {
|
|
|
126
112
|
}
|
|
127
113
|
|
|
128
114
|
/**
|
|
129
|
-
*
|
|
115
|
+
* Core implementation for the watch command.
|
|
130
116
|
*/
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
Usage: overstory watch [--interval <ms>] [--background]
|
|
134
|
-
|
|
135
|
-
Tier numbering:
|
|
136
|
-
Tier 0 Mechanical daemon (heartbeat, tmux/pid liveness) — this command
|
|
137
|
-
Tier 1 Triage agent (ephemeral AI analysis of stalled agents)
|
|
138
|
-
Tier 2 Monitor agent (continuous patrol — not yet implemented)
|
|
139
|
-
Tier 3 Supervisor monitors (per-project)
|
|
140
|
-
|
|
141
|
-
Options:
|
|
142
|
-
--interval <ms> Health check interval in milliseconds (default: from config)
|
|
143
|
-
--background Daemonize (run in background)
|
|
144
|
-
--help, -h Show this help`;
|
|
145
|
-
|
|
146
|
-
export async function watchCommand(args: string[]): Promise<void> {
|
|
147
|
-
if (args.includes("--help") || args.includes("-h")) {
|
|
148
|
-
process.stdout.write(`${WATCH_HELP}\n`);
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const intervalStr = getFlag(args, "--interval");
|
|
153
|
-
const background = hasFlag(args, "--background");
|
|
154
|
-
|
|
117
|
+
async function runWatch(opts: { interval?: string; background?: boolean }): Promise<void> {
|
|
155
118
|
const cwd = process.cwd();
|
|
156
119
|
const config = await loadConfig(cwd);
|
|
157
120
|
|
|
158
|
-
const intervalMs =
|
|
159
|
-
? Number.parseInt(
|
|
121
|
+
const intervalMs = opts.interval
|
|
122
|
+
? Number.parseInt(opts.interval, 10)
|
|
160
123
|
: config.watchdog.tier0IntervalMs;
|
|
161
124
|
|
|
162
125
|
const staleThresholdMs = config.watchdog.staleThresholdMs;
|
|
163
126
|
const zombieThresholdMs = config.watchdog.zombieThresholdMs;
|
|
164
127
|
const pidFilePath = join(config.project.root, ".overstory", "watchdog.pid");
|
|
165
128
|
|
|
166
|
-
if (background) {
|
|
129
|
+
if (opts.background) {
|
|
167
130
|
// Check if a watchdog is already running
|
|
168
131
|
const existingPid = await readPidFile(pidFilePath);
|
|
169
132
|
if (existingPid !== null && isProcessRunning(existingPid)) {
|
|
@@ -182,8 +145,8 @@ export async function watchCommand(args: string[]): Promise<void> {
|
|
|
182
145
|
|
|
183
146
|
// Build the args for the child process, forwarding --interval but not --background
|
|
184
147
|
const childArgs: string[] = ["watch"];
|
|
185
|
-
if (
|
|
186
|
-
childArgs.push("--interval",
|
|
148
|
+
if (opts.interval) {
|
|
149
|
+
childArgs.push("--interval", opts.interval);
|
|
187
150
|
}
|
|
188
151
|
|
|
189
152
|
// Resolve the overstory binary path
|
|
@@ -245,3 +208,33 @@ export async function watchCommand(args: string[]): Promise<void> {
|
|
|
245
208
|
// Block forever
|
|
246
209
|
await new Promise(() => {});
|
|
247
210
|
}
|
|
211
|
+
|
|
212
|
+
export function createWatchCommand(): Command {
|
|
213
|
+
return new Command("watch")
|
|
214
|
+
.description("Start Tier 0 mechanical watchdog daemon")
|
|
215
|
+
.option("--interval <ms>", "Health check interval in milliseconds")
|
|
216
|
+
.option("--background", "Daemonize (run in background)")
|
|
217
|
+
.action(async (opts: { interval?: string; background?: boolean }) => {
|
|
218
|
+
await runWatch(opts);
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Entry point for `overstory watch [--interval <ms>] [--background]`.
|
|
224
|
+
*/
|
|
225
|
+
export async function watchCommand(args: string[]): Promise<void> {
|
|
226
|
+
const cmd = createWatchCommand();
|
|
227
|
+
cmd.exitOverride();
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
await cmd.parseAsync(args, { from: "user" });
|
|
231
|
+
} catch (err: unknown) {
|
|
232
|
+
if (err && typeof err === "object" && "code" in err) {
|
|
233
|
+
const code = (err as { code: string }).code;
|
|
234
|
+
if (code === "commander.helpDisplayed" || code === "commander.version") {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
throw err;
|
|
239
|
+
}
|
|
240
|
+
}
|