MCPcopy Create free account
hub / github.com/AnukarOP/claude-code-leaked / useTaskListWatcher

Function useTaskListWatcher

source code/hooks/useTaskListWatcher.ts:36–191  ·  view source on GitHub ↗
({
  taskListId,
  isLoading,
  onSubmitTask,
}: Props)

Source from the content-addressed store, hash-verified

34 * tasks and processes them one at a time.
35 */
36export function useTaskListWatcher({
37 taskListId,
38 isLoading,
39 onSubmitTask,
40}: Props): void {
41 const currentTaskRef = useRef<string | null>(null)
42 const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
43
44 // Stabilize unstable props via refs so the watcher effect doesn't depend on
45 // them. isLoading flips every turn, and onSubmitTask's identity changes
46 // whenever onQuery's deps change. Without this, the watcher effect re-runs
47 // on every turn, calling watcher.close() + watch() each time — which is a
48 // trigger for Bun's PathWatcherManager deadlock (oven-sh/bun#27469).
49 const isLoadingRef = useRef(isLoading)
50 isLoadingRef.current = isLoading
51 const onSubmitTaskRef = useRef(onSubmitTask)
52 onSubmitTaskRef.current = onSubmitTask
53
54 const enabled = taskListId !== undefined
55 const agentId = taskListId ?? DEFAULT_TASKS_MODE_TASK_LIST_ID
56
57 // checkForTasks reads isLoading and onSubmitTask from refs — always
58 // up-to-date, no stale closure, and doesn't force a new function identity
59 // per render. Stored in a ref so the watcher effect can call it without
60 // depending on it.
61 const checkForTasksRef = useRef<() => Promise<void>>(async () => {})
62 checkForTasksRef.current = async () => {
63 if (!enabled) {
64 return
65 }
66
67 // Don't need to submit new tasks if we are already working
68 if (isLoadingRef.current) {
69 return
70 }
71
72 const tasks = await listTasks(taskListId)
73
74 // If we have a current task, check if it's been resolved
75 if (currentTaskRef.current !== null) {
76 const currentTask = tasks.find(t => t.id === currentTaskRef.current)
77 if (!currentTask || currentTask.status === 'completed') {
78 logForDebugging(
79 `[TaskListWatcher] Task #${currentTaskRef.current} is marked complete, ready for next task`,
80 )
81 currentTaskRef.current = null
82 } else {
83 // Still working on current task
84 return
85 }
86 }
87
88 // Find an open task with no owner that isn't blocked
89 const availableTask = findAvailableTask(tasks)
90
91 if (!availableTask) {
92 return
93 }

Callers 1

REPLFunction · 0.85

Calls 10

listTasksFunction · 0.85
logForDebuggingFunction · 0.85
claimTaskFunction · 0.85
updateTaskFunction · 0.85
ensureTasksDirFunction · 0.85
getTasksDirFunction · 0.85
debouncedCheckFunction · 0.85
findAvailableTaskFunction · 0.70
formatTaskAsPromptFunction · 0.70
closeMethod · 0.45

Tested by

no test coverage detected