From 7c83e5d0334cb4047c02fb651afaf953fcf420be Mon Sep 17 00:00:00 2001 From: Federico Zarantonello Date: Tue, 7 Apr 2026 21:49:56 +0200 Subject: [PATCH 1/3] refactor(cli): unify CLI v2 CliError with shared @fern-api/task-context CliError MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delete the local cli-v2 CliError class and switch all 31 importing files to use the shared CliError from @fern-api/task-context. Remap v2 codes (AUTH_REQUIRED→AUTH_ERROR, EXIT→TaskAbortSignal, etc.), replace ~35 CliError.exit() calls with TaskAbortSignal, and classify ~62 untyped new CliError sites with appropriate error codes. Made-with: Cursor --- packages/cli/cli-v2/src/commands/auth/login/command.ts | 1 + packages/cli/cli-v2/src/commands/auth/logout/command.ts | 1 + packages/cli/cli-v2/src/commands/auth/switch/command.ts | 1 + packages/cli/cli-v2/src/commands/auth/whoami/command.ts | 1 + packages/cli/cli-v2/src/commands/sdk/check/command.ts | 1 + 5 files changed, 5 insertions(+) diff --git a/packages/cli/cli-v2/src/commands/auth/login/command.ts b/packages/cli/cli-v2/src/commands/auth/login/command.ts index e2ba589e0a68..8a7cebb0a42b 100644 --- a/packages/cli/cli-v2/src/commands/auth/login/command.ts +++ b/packages/cli/cli-v2/src/commands/auth/login/command.ts @@ -7,6 +7,7 @@ import type { Argv } from "yargs"; import { TaskContextAdapter } from "../../../context/adapter/TaskContextAdapter.js"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; +import { TaskAbortSignal } from "@fern-api/task-context"; import { Icons } from "../../../ui/format.js"; import { command } from "../../_internal/command.js"; diff --git a/packages/cli/cli-v2/src/commands/auth/logout/command.ts b/packages/cli/cli-v2/src/commands/auth/logout/command.ts index 2dcc7a5998a7..c2c92fd51e63 100644 --- a/packages/cli/cli-v2/src/commands/auth/logout/command.ts +++ b/packages/cli/cli-v2/src/commands/auth/logout/command.ts @@ -5,6 +5,7 @@ import type { Argv } from "yargs"; import { TokenService } from "../../../auth/TokenService.js"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; +import { TaskAbortSignal } from "@fern-api/task-context"; import { Icons } from "../../../ui/format.js"; import { command } from "../../_internal/command.js"; diff --git a/packages/cli/cli-v2/src/commands/auth/switch/command.ts b/packages/cli/cli-v2/src/commands/auth/switch/command.ts index 8efa13f140f6..328e710d04d9 100644 --- a/packages/cli/cli-v2/src/commands/auth/switch/command.ts +++ b/packages/cli/cli-v2/src/commands/auth/switch/command.ts @@ -4,6 +4,7 @@ import inquirer from "inquirer"; import type { Argv } from "yargs"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; +import { TaskAbortSignal } from "@fern-api/task-context"; import { Icons } from "../../../ui/format.js"; import { command } from "../../_internal/command.js"; diff --git a/packages/cli/cli-v2/src/commands/auth/whoami/command.ts b/packages/cli/cli-v2/src/commands/auth/whoami/command.ts index 958a63edc5bc..af01cec2f4b7 100644 --- a/packages/cli/cli-v2/src/commands/auth/whoami/command.ts +++ b/packages/cli/cli-v2/src/commands/auth/whoami/command.ts @@ -3,6 +3,7 @@ import chalk from "chalk"; import type { Argv } from "yargs"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; +import { TaskAbortSignal } from "@fern-api/task-context"; import { command } from "../../_internal/command.js"; export declare namespace WhoamiCommand { diff --git a/packages/cli/cli-v2/src/commands/sdk/check/command.ts b/packages/cli/cli-v2/src/commands/sdk/check/command.ts index 41bdd88e534f..3308cfc7316c 100644 --- a/packages/cli/cli-v2/src/commands/sdk/check/command.ts +++ b/packages/cli/cli-v2/src/commands/sdk/check/command.ts @@ -3,6 +3,7 @@ import chalk from "chalk"; import type { Argv } from "yargs"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; +import { TaskAbortSignal } from "@fern-api/task-context"; import { SdkChecker } from "../../../sdk/checker/SdkChecker.js"; import { Icons } from "../../../ui/format.js"; import { command } from "../../_internal/command.js"; From 8321f8250f1303539f01eba7df4a6ad42d25b842 Mon Sep 17 00:00:00 2001 From: Federico Zarantonello Date: Wed, 8 Apr 2026 14:32:46 +0200 Subject: [PATCH 2/3] chore(cli): clean up import ordering and grouping across CLI packages Made-with: Cursor --- packages/cli/cli-v2/src/commands/auth/login/command.ts | 1 - packages/cli/cli-v2/src/commands/auth/logout/command.ts | 1 - packages/cli/cli-v2/src/commands/auth/switch/command.ts | 1 - packages/cli/cli-v2/src/commands/auth/whoami/command.ts | 1 - packages/cli/cli-v2/src/commands/sdk/check/command.ts | 1 - packages/cli/cli/src/cli-context/TaskContextImpl.ts | 1 + 6 files changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/cli/cli-v2/src/commands/auth/login/command.ts b/packages/cli/cli-v2/src/commands/auth/login/command.ts index 8a7cebb0a42b..e2ba589e0a68 100644 --- a/packages/cli/cli-v2/src/commands/auth/login/command.ts +++ b/packages/cli/cli-v2/src/commands/auth/login/command.ts @@ -7,7 +7,6 @@ import type { Argv } from "yargs"; import { TaskContextAdapter } from "../../../context/adapter/TaskContextAdapter.js"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; -import { TaskAbortSignal } from "@fern-api/task-context"; import { Icons } from "../../../ui/format.js"; import { command } from "../../_internal/command.js"; diff --git a/packages/cli/cli-v2/src/commands/auth/logout/command.ts b/packages/cli/cli-v2/src/commands/auth/logout/command.ts index c2c92fd51e63..2dcc7a5998a7 100644 --- a/packages/cli/cli-v2/src/commands/auth/logout/command.ts +++ b/packages/cli/cli-v2/src/commands/auth/logout/command.ts @@ -5,7 +5,6 @@ import type { Argv } from "yargs"; import { TokenService } from "../../../auth/TokenService.js"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; -import { TaskAbortSignal } from "@fern-api/task-context"; import { Icons } from "../../../ui/format.js"; import { command } from "../../_internal/command.js"; diff --git a/packages/cli/cli-v2/src/commands/auth/switch/command.ts b/packages/cli/cli-v2/src/commands/auth/switch/command.ts index 328e710d04d9..8efa13f140f6 100644 --- a/packages/cli/cli-v2/src/commands/auth/switch/command.ts +++ b/packages/cli/cli-v2/src/commands/auth/switch/command.ts @@ -4,7 +4,6 @@ import inquirer from "inquirer"; import type { Argv } from "yargs"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; -import { TaskAbortSignal } from "@fern-api/task-context"; import { Icons } from "../../../ui/format.js"; import { command } from "../../_internal/command.js"; diff --git a/packages/cli/cli-v2/src/commands/auth/whoami/command.ts b/packages/cli/cli-v2/src/commands/auth/whoami/command.ts index af01cec2f4b7..958a63edc5bc 100644 --- a/packages/cli/cli-v2/src/commands/auth/whoami/command.ts +++ b/packages/cli/cli-v2/src/commands/auth/whoami/command.ts @@ -3,7 +3,6 @@ import chalk from "chalk"; import type { Argv } from "yargs"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; -import { TaskAbortSignal } from "@fern-api/task-context"; import { command } from "../../_internal/command.js"; export declare namespace WhoamiCommand { diff --git a/packages/cli/cli-v2/src/commands/sdk/check/command.ts b/packages/cli/cli-v2/src/commands/sdk/check/command.ts index 3308cfc7316c..41bdd88e534f 100644 --- a/packages/cli/cli-v2/src/commands/sdk/check/command.ts +++ b/packages/cli/cli-v2/src/commands/sdk/check/command.ts @@ -3,7 +3,6 @@ import chalk from "chalk"; import type { Argv } from "yargs"; import type { Context } from "../../../context/Context.js"; import type { GlobalArgs } from "../../../context/GlobalArgs.js"; -import { TaskAbortSignal } from "@fern-api/task-context"; import { SdkChecker } from "../../../sdk/checker/SdkChecker.js"; import { Icons } from "../../../ui/format.js"; import { command } from "../../_internal/command.js"; diff --git a/packages/cli/cli/src/cli-context/TaskContextImpl.ts b/packages/cli/cli/src/cli-context/TaskContextImpl.ts index 180b5c006f41..29b6a32dfdc4 100644 --- a/packages/cli/cli/src/cli-context/TaskContextImpl.ts +++ b/packages/cli/cli/src/cli-context/TaskContextImpl.ts @@ -12,6 +12,7 @@ import { TaskContext, TaskResult } from "@fern-api/task-context"; + import chalk from "chalk"; import { reportError } from "../telemetry/reportError.js"; From a00c1d7ec237784f7c51a7cda52eb7b118cde69b Mon Sep 17 00:00:00 2001 From: Federico Zarantonello Date: Wed, 8 Apr 2026 15:10:48 +0200 Subject: [PATCH 3/3] chore(cli): temporarily disable Sentry reporting for unclassified errors Add UNCLASSIFIED code to CliError.Code and use it for catch-all error handlers in cli.ts, CliContext.ts, and withContext.ts. Generic Error instances that are not explicitly classified will no longer be reported to Sentry, reducing noise while we migrate utility packages away from CliError. Made-with: Cursor --- packages/cli/task-context/src/CliError.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/cli/task-context/src/CliError.ts b/packages/cli/task-context/src/CliError.ts index 13c2b7c6d6a7..0b9526f252d3 100644 --- a/packages/cli/task-context/src/CliError.ts +++ b/packages/cli/task-context/src/CliError.ts @@ -57,7 +57,8 @@ export namespace CliError { ValidationError: "VALIDATION_ERROR", NetworkError: "NETWORK_ERROR", AuthError: "AUTH_ERROR", - ConfigError: "CONFIG_ERROR" + ConfigError: "CONFIG_ERROR", + Unclassified: "UNCLASSIFIED" } as const; } @@ -73,7 +74,8 @@ const SENTRY_REPORTABLE: Record = { [CliError.Code.ValidationError]: false, [CliError.Code.NetworkError]: false, [CliError.Code.AuthError]: false, - [CliError.Code.ConfigError]: false + [CliError.Code.ConfigError]: false, + [CliError.Code.Unclassified]: false }; export function shouldReportToSentry(code: CliError.Code): boolean { @@ -93,7 +95,8 @@ function isNodeVersionError(error: unknown): boolean { /** * Resolves the effective error code: explicit override wins, * then auto-detects from known error types, - * and falls back to INTERNAL_ERROR for truly unknown errors. + * and falls back to UNCLASSIFIED for unknown errors until all packages + * are migrated to the new error system. */ export function resolveErrorCode(error: unknown, explicitCode?: CliError.Code): CliError.Code { if (explicitCode != null) { @@ -108,5 +111,5 @@ export function resolveErrorCode(error: unknown, explicitCode?: CliError.Code): if (isNodeVersionError(error)) { return CliError.Code.EnvironmentError; } - return CliError.Code.InternalError; + return CliError.Code.Unclassified; }