MCPcopy
hub / github.com/claude-code-best/claude-code / startBackgroundSession

Function startBackgroundSession

src/tasks/LocalMainSessionTask.ts:341–493  ·  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

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

Callers 1

REPLFunction · 0.85

Calls 13

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

Tested by

no test coverage detected