MCPcopy
hub / github.com/codeaashu/claude-code / processSessionStartHooks

Function processSessionStartHooks

src/utils/sessionStart.ts:35–175  ·  view source on GitHub ↗
(
  source: 'startup' | 'resume' | 'clear' | 'compact',
  {
    sessionId,
    agentType,
    model,
    forceSyncExecution,
  }: SessionStartHooksOptions = {},
)

Source from the content-addressed store, hash-verified

33
34// Note to CLAUDE: do not add ANY "warmup" logic. It is **CRITICAL** that you do not add extra work on startup.
35export async function processSessionStartHooks(
36 source: 'startup' | 'resume' | 'clear' | 'compact',
37 {
38 sessionId,
39 agentType,
40 model,
41 forceSyncExecution,
42 }: SessionStartHooksOptions = {},
43): Promise<HookResultMessage[]> {
44 // --bare skips all hooks. executeHooks already early-returns under --bare
45 // (hooks.ts:1861), but this skips the loadPluginHooks() await below too —
46 // no point loading plugin hooks that'll never run.
47 if (isBareMode()) {
48 return []
49 }
50 const hookMessages: HookResultMessage[] = []
51 const additionalContexts: string[] = []
52 const allWatchPaths: string[] = []
53
54 // Skip loading plugin hooks if restricted to managed hooks only
55 // Plugin hooks are untrusted external code that should be blocked by policy
56 if (shouldAllowManagedHooksOnly()) {
57 logForDebugging('Skipping plugin hooks - allowManagedHooksOnly is enabled')
58 } else {
59 // Ensure plugin hooks are loaded before executing SessionStart hooks.
60 // loadPluginHooks() may be called early during startup (fire-and-forget, non-blocking)
61 // to pre-load hooks, but we must guarantee hooks are registered before executing them.
62 // This function is memoized, so if hooks are already loaded, this returns immediately
63 // with negligible overhead (just a cache lookup).
64 try {
65 await withDiagnosticsTiming('load_plugin_hooks', () => loadPluginHooks())
66 } catch (error) {
67 // Log error but don't crash - continue with session start without plugin hooks
68 /* eslint-disable no-restricted-syntax -- both branches wrap with context, not a toError case */
69 const enhancedError =
70 error instanceof Error
71 ? new Error(
72 `Failed to load plugin hooks during ${source}: ${error.message}`,
73 )
74 : new Error(
75 `Failed to load plugin hooks during ${source}: ${String(error)}`,
76 )
77 /* eslint-enable no-restricted-syntax */
78
79 if (error instanceof Error && error.stack) {
80 enhancedError.stack = error.stack
81 }
82
83 logError(enhancedError)
84
85 // Provide specific guidance based on error type
86 const errorMessage =
87 error instanceof Error ? error.message : String(error)
88 let userGuidance = ''
89
90 if (
91 errorMessage.includes('Failed to clone') ||
92 errorMessage.includes('network') ||

Callers 8

runFunction · 0.85
clearConversationFunction · 0.85
REPLFunction · 0.85
loadInitialMessagesFunction · 0.85
compactConversationFunction · 0.85

Calls 11

isBareModeFunction · 0.85
logForDebuggingFunction · 0.85
withDiagnosticsTimingFunction · 0.85
loadPluginHooksFunction · 0.85
getMainThreadAgentTypeFunction · 0.85
executeSessionStartHooksFunction · 0.85
updateWatchPathsFunction · 0.85
createAttachmentMessageFunction · 0.85
logErrorFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected