1- import { postrun as deprecationsHook } from './deprecations.js'
2- import { reportAnalyticsEvent } from '../analytics.js'
3- import { outputDebug , outputWarn } from '../output.js'
4- import { getOutputUpdateCLIReminder , runCLIUpgrade , versionToAutoUpgrade , warnIfUpgradeAvailable } from '../upgrade.js'
5- import { inferPackageManagerForGlobalCLI } from '../is-global.js'
6- import BaseCommand from '../base-command.js'
7- import * as metadata from '../metadata.js'
8- import { runAtMinimumInterval } from '../../../private/node/conf-store.js'
9- import { CLI_KIT_VERSION } from '../../common/version.js'
10- import { isMajorVersionChange } from '../version.js'
1+ /**
2+ * Postrun hook — uses dynamic imports to avoid loading heavy modules (base-command, analytics)
3+ * at module evaluation time. These are only needed after the command has already finished.
4+ */
115import { Command , Hook } from '@oclif/core'
126
137let postRunHookCompleted = false
@@ -24,9 +18,14 @@ export function postRunHookHasCompleted(): boolean {
2418// This hook is called after each successful command run. More info: https://oclif.io/docs/hooks
2519export const hook : Hook . Postrun = async ( { config, Command} ) => {
2620 await detectStopCommand ( Command as unknown as typeof Command )
21+
22+ const { reportAnalyticsEvent} = await import ( '../analytics.js' )
2723 await reportAnalyticsEvent ( { config, exitMode : 'ok' } )
24+
25+ const { postrun : deprecationsHook } = await import ( './deprecations.js' )
2826 deprecationsHook ( Command )
2927
28+ const { outputDebug} = await import ( '../output.js' )
3029 const command = Command . id . replace ( / : / g, ' ' )
3130 outputDebug ( `Completed command ${ command } ` )
3231 postRunHookCompleted = true
@@ -48,6 +47,7 @@ export const hook: Hook.Postrun = async ({config, Command}) => {
4847 * @returns Resolves when the upgrade attempt (or fallback warning) is complete.
4948 */
5049export async function autoUpgradeIfNeeded ( ) : Promise < void > {
50+ const { versionToAutoUpgrade, warnIfUpgradeAvailable} = await import ( '../upgrade.js' )
5151 const newerVersion = versionToAutoUpgrade ( )
5252 if ( ! newerVersion ) {
5353 await warnIfUpgradeAvailable ( )
@@ -60,6 +60,7 @@ export async function autoUpgradeIfNeeded(): Promise<void> {
6060 if ( forced ) {
6161 await performAutoUpgrade ( newerVersion )
6262 } else {
63+ const { runAtMinimumInterval} = await import ( '../../../private/node/conf-store.js' )
6364 // Rate-limit the entire upgrade flow to once per day to avoid repeated attempts and major-version warnings.
6465 await runAtMinimumInterval ( 'auto-upgrade' , { days : 1 } , async ( ) => {
6566 await performAutoUpgrade ( newerVersion )
@@ -68,6 +69,18 @@ export async function autoUpgradeIfNeeded(): Promise<void> {
6869}
6970
7071async function performAutoUpgrade ( newerVersion : string ) : Promise < void > {
72+ const [
73+ { CLI_KIT_VERSION } ,
74+ { isMajorVersionChange} ,
75+ { outputWarn, outputDebug} ,
76+ { getOutputUpdateCLIReminder, runCLIUpgrade} ,
77+ ] = await Promise . all ( [
78+ import ( '../../common/version.js' ) ,
79+ import ( '../version.js' ) ,
80+ import ( '../output.js' ) ,
81+ import ( '../upgrade.js' ) ,
82+ ] )
83+
7184 if ( isMajorVersionChange ( CLI_KIT_VERSION , newerVersion ) ) {
7285 return outputWarn ( getOutputUpdateCLIReminder ( newerVersion ) )
7386 }
@@ -79,8 +92,10 @@ async function performAutoUpgrade(newerVersion: string): Promise<void> {
7992 const errorMessage = `Auto-upgrade failed: ${ error } `
8093 outputDebug ( errorMessage )
8194 outputWarn ( getOutputUpdateCLIReminder ( newerVersion ) )
82- // Report to Observe as a handled error without showing anything extra to the user
83- const { sendErrorToBugsnag} = await import ( '../error-handler.js' )
95+ const [ { sendErrorToBugsnag} , { inferPackageManagerForGlobalCLI} ] = await Promise . all ( [
96+ import ( '../error-handler.js' ) ,
97+ import ( '../is-global.js' ) ,
98+ ] )
8499 const enrichedError = Object . assign ( new Error ( errorMessage ) , {
85100 packageManager : inferPackageManagerForGlobalCLI ( ) ,
86101 platform : process . platform ,
@@ -93,13 +108,20 @@ async function performAutoUpgrade(newerVersion: string): Promise<void> {
93108/**
94109 * Override the command name with the stop one for analytics purposes.
95110 *
96- * @param commandClass - Oclif command class .
111+ * @param commandClass - Command.Class .
97112 */
98- async function detectStopCommand ( commandClass : Command . Class | typeof BaseCommand ) : Promise < void > {
113+ async function detectStopCommand ( commandClass : Command . Class ) : Promise < void > {
99114 const currentTime = new Date ( ) . getTime ( )
100- if ( commandClass && Object . prototype . hasOwnProperty . call ( commandClass , 'analyticsStopCommand' ) ) {
101- const stopCommand = ( commandClass as typeof BaseCommand ) . analyticsStopCommand ( )
115+ // Check for analyticsStopCommand without importing BaseCommand
116+ if (
117+ commandClass &&
118+ 'analyticsStopCommand' in commandClass &&
119+ typeof commandClass . analyticsStopCommand === 'function'
120+ ) {
121+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
122+ const stopCommand = ( commandClass as any ) . analyticsStopCommand ( )
102123 if ( stopCommand ) {
124+ const metadata = await import ( '../metadata.js' )
103125 const { commandStartOptions} = metadata . getAllSensitiveMetadata ( )
104126 if ( ! commandStartOptions ) return
105127 await metadata . addSensitiveMetadata ( ( ) => ( {
0 commit comments