Background Tasks
Site crawling, vault indexing, and knowledge graph extraction can take minutes. Daneel runs these operations in the background so you can close panels, switch tabs, or navigate away without losing progress.
This is what powers the task monitor in Settings > Tasks.
The problem: UI-coupled operations
Section titled “The problem: UI-coupled operations”Chrome extensions run UI code inside content scripts and popup panels. When a panel closes — because you clicked outside it, navigated to another site, or simply switched views — any JavaScript running inside that panel stops. If a crawl was in progress, it dies silently.
This is a fundamental problem: long-running operations cannot live inside short-lived UI components.
The solution: service worker ownership
Section titled “The solution: service worker ownership”Daneel inverts the relationship. Instead of the UI owning the operation, the background service worker owns it. The UI becomes a passive observer — it subscribes to progress updates, but its presence or absence does not affect execution.
When you start a site crawl from the Search overlay:
- The overlay sends a
task-enqueuemessage to the service worker - The service worker creates a task record, persists it to storage, and dispatches the work to the host tab
- The host tab (which has GPU access) does the actual crawling and embedding
- Progress broadcasts flow back through the service worker, which updates the task record
- The overlay (if still open) receives these updates and renders a progress bar
If you close the overlay at step 3, steps 3 and 4 continue unchanged. When you reopen the overlay later, it connects to the service worker and receives the current task state.
Checkpoint-resume: surviving eviction
Section titled “Checkpoint-resume: surviving eviction”Chrome’s Manifest V3 service workers are not persistent. They sleep after roughly 30 seconds of inactivity and can be terminated at any time. A naive implementation would lose all state when the service worker dies.
Daneel handles this with checkpoint-forward execution:
- After each meaningful progress update (a page crawled, a document embedded, a batch of entities extracted), the service worker writes the updated task record to
chrome.storage.local - A
chrome.alarmsheartbeat fires every 60 seconds - When the alarm wakes the service worker, it reads task records from storage and checks: is there a task marked as “running” but with no active dispatch in memory?
- If so, the service worker re-creates the host tab (if needed) and re-dispatches the operation from where it left off
For site crawls, the checkpoint includes the list of already-crawled URLs. On resume, these URLs are passed as a skipUrls parameter, so the crawler picks up where it left off without re-fetching pages.
For knowledge graph builds, the checkpoint tracks how many chunks have been processed. On resume, incremental mode detects which chunks already have entities extracted and skips them.
For vault indexing, the checkpoint tracks which documents have been ingested. The scheduler drives the per-document loop, dispatching the next un-ingested document after each one completes.
The GPU semaphore
Section titled “The GPU semaphore”All three task types need the GPU — site crawling embeds chunks via WebGPU, vault indexing does the same, and knowledge graph extraction runs NER inference plus entity embedding. Running two GPU-heavy operations simultaneously causes WebGPU context loss (the second model’s ONNX Runtime session loses its device reference).
The task scheduler enforces a simple rule: one GPU-bound task at a time. When a second task is enqueued while the first is running, it enters a pending state and waits in a FIFO queue. When the first task completes (or is cancelled), the next pending task is dispatched automatically.
This is implemented as a boolean lock (gpuBusy) with a queue of waiting task IDs. There is no priority system or preemption — tasks run in the order they were enqueued.
Task lifecycle
Section titled “Task lifecycle”A task moves through these states:
| Status | Meaning |
|---|---|
pending | Queued, waiting for the GPU lock |
running | Actively executing in the host tab |
paused | User requested pause — checkpoint saved, host stopped |
complete | All work finished successfully |
failed | An error occurred (network timeout, model crash, etc.) |
cancelled | User cancelled the task |
State transitions are guarded — a completed task cannot be paused, a pending task cannot be “completed,” and so on. Invalid transitions are silently ignored rather than throwing errors, which prevents race conditions in async code.
What the UI sees
Section titled “What the UI sees”Any UI component (the Search overlay, the Vault panel, the Settings > Tasks panel) can observe task state by connecting a chrome.runtime.Port named task-observer. On connect, the service worker sends a snapshot of all current tasks. After that, incremental task:updated events flow over the port whenever progress changes.
This means you can start a crawl from the Search overlay, close it, open Settings > Tasks, and see the same live progress bar. The data source is the same — only the rendering differs.
The existing progress messages from the host tab (like crawler-page and embedding-page) still flow through the normal relay system. The task layer intercepts these to update checkpoints, then lets them pass through to any UI that’s listening. This means the old progress indicators still work alongside the new task system.
What this enables
Section titled “What this enables”Beyond fixing the “close panel, lose progress” bug, the task layer is the foundation for:
- Concurrent awareness — even though only one GPU task runs at a time, you can see what’s queued and what’s waiting
- Crash recovery — if Chrome closes mid-crawl, the task resumes from its checkpoint on next launch
- Cross-panel visibility — any settings panel or overlay can show the same task state
- Future deep research — multi-step operations (query planning, source fetching, synthesis) that could run for 10+ minutes will use the same infrastructure
See How to Monitor Background Tasks for the practical guide to the Settings > Tasks panel.