MCPcopy Index your code
hub / github.com/codeaashu/claude-code / startBackgroundSession

Function startBackgroundSession

src/tasks/LocalMainSessionTask.ts:338–479  ·  view source on GitHub ↗
({
  messages,
  queryParams,
  description,
  setAppState,
  agentDefinition,
}: {
  messages: Message[]
  queryParams: Omit<QueryParams, 'messages'>
  description: string
  setAppState: SetAppState
  agentDefinition?: AgentDefinition
})

Source from the content-addressed store, hash-verified

336 * as a background task. The caller's foreground query continues running normally.
337 */
338export function startBackgroundSession({
339 messages,
340 queryParams,
341 description,
342 setAppState,
343 agentDefinition,
344}: {
345 messages: Message[]
346 queryParams: Omit<QueryParams, 'messages'>
347 description: string
348 setAppState: SetAppState
349 agentDefinition?: AgentDefinition
350}): string {
351 const { taskId, abortSignal } = registerMainSessionTask(
352 description,
353 setAppState,
354 agentDefinition,
355 )
356
357 // Persist the pre-backgrounding conversation to the task's isolated
358 // transcript so TaskOutput shows context immediately. Subsequent messages
359 // are written incrementally below.
360 void recordSidechainTranscript(messages, taskId).catch(err =>
361 logForDebugging(`bg-session initial transcript write failed: ${err}`),
362 )
363
364 // Wrap in agent context so skill invocations scope to this task's agentId
365 // (not null). This lets clearInvokedSkills(preservedAgentIds) selectively
366 // preserve this task's skills across /clear. AsyncLocalStorage isolates
367 // concurrent async chains — this wrapper doesn't affect the foreground.
368 const agentContext: SubagentContext = {
369 agentId: taskId,
370 agentType: 'subagent',
371 subagentName: 'main-session',
372 isBuiltIn: true,
373 }
374
375 void runWithAgentContext(agentContext, async () => {
376 try {
377 const bgMessages: Message[] = [...messages]
378 const recentActivities: ToolActivity[] = []
379 let toolCount = 0
380 let tokenCount = 0
381 let lastRecordedUuid: UUID | null = messages.at(-1)?.uuid ?? null
382
383 for await (const event of query({
384 messages: bgMessages,
385 ...queryParams,
386 })) {
387 if (abortSignal.aborted) {
388 // Aborted mid-stream — completeMainSessionTask won't be reached.
389 // chat:killAgents path already marked notified + emitted; stopTask path did not.
390 let alreadyNotified = false
391 updateTaskState(taskId, setAppState, task => {
392 alreadyNotified = task.notified === true
393 return alreadyNotified ? task : { ...task, notified: true }
394 })
395 if (!alreadyNotified) {

Callers 1

REPLFunction · 0.85

Calls 12

registerMainSessionTaskFunction · 0.85
logForDebuggingFunction · 0.85
runWithAgentContextFunction · 0.85
emitTaskTerminatedSdkFunction · 0.85
completeMainSessionTaskFunction · 0.85
shiftMethod · 0.80
queryFunction · 0.50
updateTaskStateFunction · 0.50
logErrorFunction · 0.50
pushMethod · 0.45

Tested by

no test coverage detected