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

Function handleStopHooks

src/query/stopHooks.ts:65–473  ·  view source on GitHub ↗
(
  messagesForQuery: Message[],
  assistantMessages: AssistantMessage[],
  systemPrompt: SystemPrompt,
  userContext: { [k: string]: string },
  systemContext: { [k: string]: string },
  toolUseContext: ToolUseContext,
  querySource: QuerySource,
  stopHookActive?: boolean,
)

Source from the content-addressed store, hash-verified

63}
64
65export async function* handleStopHooks(
66 messagesForQuery: Message[],
67 assistantMessages: AssistantMessage[],
68 systemPrompt: SystemPrompt,
69 userContext: { [k: string]: string },
70 systemContext: { [k: string]: string },
71 toolUseContext: ToolUseContext,
72 querySource: QuerySource,
73 stopHookActive?: boolean,
74): AsyncGenerator<
75 | StreamEvent
76 | RequestStartEvent
77 | Message
78 | TombstoneMessage
79 | ToolUseSummaryMessage,
80 StopHookResult
81> {
82 const hookStartTime = Date.now()
83
84 const stopHookContext: REPLHookContext = {
85 messages: [...messagesForQuery, ...assistantMessages],
86 systemPrompt,
87 userContext,
88 systemContext,
89 toolUseContext,
90 querySource,
91 }
92 // Only save params for main session queries — subagents must not overwrite.
93 // Outside the prompt-suggestion gate: the REPL /btw command and the
94 // side_question SDK control_request both read this snapshot, and neither
95 // depends on prompt suggestions being enabled.
96 if (querySource === 'repl_main_thread' || querySource === 'sdk') {
97 saveCacheSafeParams(createCacheSafeParams(stopHookContext))
98 }
99
100 // Template job classification: when running as a dispatched job, classify
101 // state after each turn. Gate on repl_main_thread so background forks
102 // (extract-memories, auto-dream) don't pollute the timeline with their own
103 // assistant messages. Await the classifier so state.json is written before
104 // the turn returns — otherwise `claude list` shows stale state for the gap.
105 // Env key hardcoded (vs importing JOB_ENV_KEY from jobs/state) to match the
106 // require()-gated jobs/ import pattern above; spawn.test.ts asserts the
107 // string matches.
108 if (
109 feature('TEMPLATES') &&
110 process.env.CLAUDE_JOB_DIR &&
111 querySource.startsWith('repl_main_thread') &&
112 !toolUseContext.agentId
113 ) {
114 // Full turn history — assistantMessages resets each queryLoop iteration,
115 // so tool calls from earlier iterations (Agent spawn, then summary) need
116 // messagesForQuery to be visible in the tool-call summary.
117 const turnAssistantMessages = stopHookContext.messages.filter(
118 (m): m is AssistantMessage => m.type === 'assistant',
119 )
120 const p = jobClassifierModule!
121 .classifyAndWriteState(process.env.CLAUDE_JOB_DIR, turnAssistantMessages)
122 .catch(err => {

Callers 1

queryLoopFunction · 0.85

Calls 15

saveCacheSafeParamsFunction · 0.85
createCacheSafeParamsFunction · 0.85
featureFunction · 0.85
logForDebuggingFunction · 0.85
isBareModeFunction · 0.85
isEnvDefinedFalsyFunction · 0.85
executePromptSuggestionFunction · 0.85
isExtractModeActiveFunction · 0.85
executeAutoDreamFunction · 0.85
executeStopHooksFunction · 0.85
createUserMessageFunction · 0.85

Tested by

no test coverage detected