---
title: Auto Context — auto-inject files like Claude.ai Projects
---

# Auto Context (`.claude/docs/` auto-injection)

> **Sidebar label**: surfaced as the **Auto Context (N)** group in the project sidebar — the section that lists every file this project automatically feeds the agent. The internal feature name and the on-disk folder (`.claude/docs/`) are still called "project docs" in the codebase, but the user-facing label is "Auto Context" because the section now also surfaces System Instructions (CLAUDE.md / MEMORY.md) alongside the auto-injected docs.

## What it is

A "Claude.ai Projects"-style knowledge folder per project. Drop reference files into `<project>/.claude/docs/` and they become automatically available to sessions in that project — no manual attaching, no settings UI, no per-session setup.

Omniscio folds the docs into the agent's **first user message**, invisibly. The model sees your project knowledge sitting alongside your prompt, but the chat bubble shows only what you typed — the injected block never appears in the visible conversation. Text files are inlined as content; binaries (PDFs, images, Office docs) are attached exactly the same way a user-clicked paperclip attaches them.

This is a **one-time, first-message injection done entirely by Omniscio**. There is no per-turn hook, no `<system-reminder>`, and no `CLAUDE.md` rewriting. (The old global `~/.claude/scripts/sync-claude-docs.sh` `UserPromptSubmit` hook that used to re-emit doc contents every turn was removed — see [the postmortem](../../.claude/memory/postmortems/claude-docs-auto-injection-postmortem.md) for the history.)

**Two consequences of first-message-only, worth knowing up front:**

- **Docs can age out of a long conversation.** Because the content is injected once (not refreshed every turn), after a very long session or a `/compact` the inlined text may fall out of the live context window. The agent can still `Read` any file back on demand — and the RAG bucket below is designed precisely for "fetch when needed."
- **Omniscio-only.** A plain terminal Claude Code session in the same folder no longer auto-loads `.claude/docs/` (the global hook that did that is gone). The folder still works as a normal directory the agent can `Read`, but the automatic injection happens only when Omniscio launches the session.
- **Recovery re-injects it (so it survives a long, interrupted session).** "First-message-only" governs _normal_ turns — Omniscio does not refresh the docs every time you reply. But whenever Omniscio has to **rebuild a session's context to recover or resume it** — a crash restart, a rate-limit account switch, a stale-CLI respawn — it re-injects the same auto-context (project docs **plus** your AI-Coaching profile **plus** the question-format hint) into the rebuilt prompt. A long-running session that gets recovered repeatedly therefore keeps your project knowledge and preferences instead of silently losing them after the first recovery. This matters because the injected blocks are never saved to the database (they're invisible by design), and the recovery rebuild is reconstructed from saved history — so without this re-injection the recovered session would run blind. It rides the transcript-replay envelope (appended after it) and its size is reserved out of the replay budget so it can't push the rebuilt message over the window. See [context-transfer-replay-cap-contract.md](../../.claude/memory/contracts/context-transfer-replay-cap-contract.md) (I8) and [session-auto-context.ts](../../src/main/services/session/session-auto-context.ts).

The auto-injected docs ship in **two buckets** — pick which one per file when you add it:

| Bucket   | Where on disk                 | What happens                                                                                                                                                                                                                                              | Default? |
| -------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `always` | `<project>/.claude/docs/`     | Folded into the first message — text inlined in full, binaries attached. Counts against the project's injection budget (a share of your engine's context window — see **Limits** below). This is the behavior described throughout the rest of this page. | ✅ Yes   |
| `rag`    | `<project>/.claude/docs/rag/` | Surfaced in the first message as a **Table of Contents** — filenames + sizes (+ a one-line description for text) only; the agent calls `Read` on demand. Bytes do **not** count against that budget.                                                      | No       |

**When to pick `always` vs `rag`:**

- **`always`** — small reference material the model should have in front of it from the start (style guides, glossaries, project rules). Cost: every byte burns first-message context budget.
- **`rag`** — large or rarely-needed material (full schemas, long PDFs, archived knowledge, code dumps). Cost: nothing until the agent decides it needs a file, at which point one `Read` tool call pulls just that file in.

The `always` bucket is delivered in two cooperating ways because text and binaries need different injection vehicles:

| File type                                                          | How it gets in                                                                                              | Scope                             |
| ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | --------------------------------- |
| Text (`.md`, `.txt`, `.json`, `.yaml`, code, …)                    | Inlined as content into the first user message under a `## Injected Project Docs` heading, each file fenced | First message only, Omniscio only |
| Binary (`.pdf`, `.png/.jpg/.webp/.gif`, `.docx`, `.xlsx`, `.pptx`) | File paths prepended to the first user message via the same helper the manual attach button uses            | First message only, Omniscio only |

## Where to find it

### How to use it

1. **Find the project's folder.** Right-click the project in the sidebar → **Copy Path** (or **Show in Explorer** on Windows).
2. **Create `.claude/docs/` inside that folder** if it doesn't already exist.
3. **Drop files in.** PDFs, images, Word docs, spreadsheets, markdown, `.txt`, code — whatever you want every new session in that project to have on hand. Anything you put at the top level of `.claude/docs/` is `always`-bucketed (auto-injected). Anything you put inside `.claude/docs/rag/` is `rag`-bucketed (TOC-only, read on demand).
4. **Start a new session.** On the first message Omniscio sends to the agent, any binary files in the `always` bucket are attached (same as if you'd clicked the paperclip), and any text files in the `always` bucket are inlined as a `## Injected Project Docs` block ahead of your prompt. RAG-bucket files appear in the same first message as an `## Available Reference Docs` catalog the agent can choose to `Read`. None of this touches `CLAUDE.md`, and none of it shows in the chat bubble — the persisted operator message is exactly what you typed.
5. **Verify it ran** (optional). In the Omniscio main-process log, look for `[AutoDocs] Attached N file(s) from .claude/docs/ to first message` (the binary path). Or open the project sidebar's **Auto Context** group and confirm your file is listed with a token estimate. For RAG bucket: look for the **On-demand context** sub-group.

Limits:

- Text inline (`always` bucket): **no per-file cap** (any single text file is injected in full as long as the project-wide budget allows). The project-wide budget is **a quarter of the context window your engine actually enforces**, capped at **500 KB** of file-system bytes (~125K tokens at ~4 bytes/token). That 500 KB is a _ceiling_, not a flat allowance — it is what a 1M-window engine gets. A session on an engine the `claude` binary holds to its own ~200K default (DeepSeek, Kimi, bare GLM without `[1m]`, MiniMax, Meta, Qwen, xAI, and native Haiku 4.5 / Sonnet 4.5) gets **~200 KB (~50K tokens)** instead. The soft warning band starts at 80% of whatever your budget works out to. Docs you flagged **inject as instruction** claim their share of this same budget first (see above), so they reduce what is left for the background docs. Files iterate in sidebar order; the first file that would push the cumulative total over the budget gets a "Skipped — would push total over NNK token cap. Use Read tool on `<full path to the file>`" pointer instead of raw content — with your engine's real number in place of NN — and iteration **continues**, so a smaller file later in the order can still fit. The sidebar surfaces this directly: the top of the Auto Context group shows an "Injected: ~XX,XXX tokens" total and (when applicable) an amber skipped-count line, and each skipped row gets an inline amber **⚠ skipped** chip whose hover tooltip names the real cap reason for your engine. When you cross 80% of the budget with zero skips, an amber "approaching" hint replaces the skipped-count line so you know you are close. Both of those summary lines name **your engine's real budget**, not the ceiling: the figure is computed alongside the skip decision itself and shipped to the sidebar, so the summary line, the per-row tooltip and the injection the agent actually gets can never disagree about the cap. (Until 2026-09-12 they read a hard-coded "125K" on every engine, which was right only on the 1M lane and overstated the budget 2.5x everywhere else.) **The budget, the skipped count, and the "approaching" band apply to this always-inject docs bucket only** — RAG bytes and the natively-loaded System Instructions never count against it. **The "Injected" total itself is the _grand total_** of everything the panel feeds the agent, though: it sums the System Instructions rows (project + global `CLAUDE.md` / `MEMORY.md`, each already loaded by the CLI) **plus** the always-inject docs, so it equals the sum of the token-bearing rows shown below it — a project whose bulk is `CLAUDE.md` no longer shows a misleadingly tiny total.
- RAG bucket: **uncapped** project-wide (effectively limited only by disk). The TOC is itself capped at **100 entries** (alphabetical), with a "… and N more" overflow line so the table-of-contents token cost stays bounded even with thousands of RAG files. Per-file size limit is the same 50 MiB upload cap that applies everywhere else.
- Binary attach: first message **only**. Subsequent messages in the same session do not re-attach (the model already has the files in context). RAG-bucket binaries are **never** auto-attached — the agent must `Read` them on demand.
- Only the top level of `.claude/docs/` is scanned for the `always` bucket; the `rag/` sub-folder is scanned separately as the RAG bucket. No other subdirectories are recursed.
- Injection is computed fresh **each time a session sends its first message**. Docs you add or remove before that first message are reflected; docs you change _after_ the session has started talking are not re-injected into that session (start a new session for a fresh snapshot, or have the agent `Read` the updated file).

### Browsing the doc list in the sidebar — the Auto Context group

The project sidebar surfaces every file this project automatically feeds the agent under one collapsible group: **Auto Context (N)** (where N is the total file count across all three sub-groups). The header carries an **Add** (+) button to launch the modal and an **Auto Context** label that doubles as the collapse/expand toggle — hovering the label shows a short tooltip ("Everything this project feeds the agent automatically."). When `N > 0` and the group is collapsed, a small accent-colored dot sits to the right of the label as a "you have docs here" reminder.

When the group is expanded, a single **search input** sits between the header and the file list: type-to-filter by filename (case-insensitive, substring match). Empty search shows everything; non-empty narrows every sub-group simultaneously. A **multi-select toggle** sits at the right end of the search row (desktop only — `md:hidden` on the X for mobile parity with the rest of the sidebar). Toggling it on adds checkboxes to Always-inject + On-demand context rows (System Instructions rows stay unselectable by design) and opens the bulk action toolbar.

Below the search input, up to three sub-groups render in fixed order — each only appears when its filtered result set is non-empty:

| Sub-group               | What it contains                                                                                                                                                                                                                                               | Bulk select?                          |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| **System Instructions** | Project + global `CLAUDE.md` / `MEMORY.md` plus their synced mirrors (the agent's persistent rules and memory). View / edit-only on purpose — these are protected from accidental bulk delete sweeps because losing them resets the agent's project knowledge. | ❌ No — never selectable              |
| **Always-inject**       | `always`-bucket docs from `.claude/docs/` (the `always` bucket above). Folded into the first message — text inlined, binaries attached. The injection budget applies here.                                                                                     | ✅ Yes (when multi-select is enabled) |
| **On-demand context**   | `rag`-bucket docs from `.claude/docs/rag/` (the `rag` bucket above). Listed for the agent to `Read` on demand, never auto-injected, and never counted against the injection budget.                                                                            | ✅ Yes (when multi-select is enabled) |

Sub-group headers are only rendered when the group is one of several visible — a project with only Always-inject rows shows them flat without a sub-header to avoid one-section noise. Each row uses an icon (📦 ContextDock bundle / 📋 ContextDock list / plain file icon for hand-dropped docs) plus an approximate token count summed across the row. Long filenames are truncated with an ellipsis to fit the narrow sidebar column — **hover any row to see the full filename in a tooltip** (400 ms delay; also surfaces on keyboard focus for a11y). For ContextDock-managed rows the tooltip shows the bundle/list display name, not the on-disk filename, so you see the same title that appears on `contextdock.web.app`.

## How it behaves

### Ordering — newly-added docs go to the bottom

**To reorder:** long-press (~0.4s) anywhere on a doc row and drag it up or down — there's no separate grip handle, and a quick click still opens the file. Plain docs and ContextDock-linked rows reorder by the same whole-row gesture; reordering is paused while the panel is in multi-select mode (see [project-docs-selection.md](project-docs-selection.md)).

The order you see in the sidebar is the same order used everywhere else: the first-message inline injection, the first-message attachment list, the CLI Control `GET /project/:id/docs` response, and any future `ls`-style listing. Three guarantees:

1. **A fresh `.claude/docs/` folder you've never reordered sorts by most recently modified first.** The newest file is on top, oldest is on bottom — the typical "what did I just drop in here?" view.
2. **Once you drag-reorder anything in the sidebar, that explicit order sticks**, even if you later edit a file (mtime change does not bump a manually-positioned doc to the top).
3. **New docs you add via Upload, Paste, Google Drive import (Docs/Slides/Sheets), CLI Control upload, or a ContextDock link/bundle/list always land at the very bottom of the next listing** — _under_ every existing entry, including older docs you've never explicitly positioned. This is the predictable position requested by the design and is independent of the new file's mtime.

The third rule is the one that has historically been tricky. Before the 2026-05-11 fix, Omniscio's add sites wrote the file to disk but never updated the persisted order, so a brand-new file fell through the mtime-DESC tiebreak for unordered docs and landed at the _top_ of the unordered tail — above older user-authored docs that had never been explicitly reordered. The fix is a single shared helper, [appendNewDocsToOrder](../../src/main/services/project-docs-order.ts), that runs after every successful add: it snapshots the currently-visible order (existing order entries plus any previously-unordered docs ranked mtime-DESC) and appends the new doc(s) at the very end before persisting. The original 2026-05-11 wave wired the in-app modal handler [FILES_ADD_PROJECT_DOC in file-handlers.ts](../../src/main/ipc/file-handlers.ts) and the CLI Control dispatcher's `project.docs_upload` action in [cli-pending-dispatcher.ts](../../src/main/services/cli/cli-pending-dispatcher.ts); a 2026-05-12 recurrence (ContextDock-linked docs landing third-from-bottom) extended the wiring to `handleContextDockLink` and `handleContextDockLinkDoc` in [contextdock-handlers.ts](../../src/main/ipc/contextdock-handlers.ts). All four add sites call the helper inside a try/catch with `log.warn` so a transient `readdir` failure can never silently corrupt persisted order. The helper is idempotent: re-adding a filename already in the order is a no-op (the file keeps its existing position). The ContextDock `refresh` action deliberately does NOT touch the helper — refresh is an in-place update of an existing on-disk file, so re-anchoring on every refresh would silently override any drag-reorder you did between adds.

The "missed an add site" failure mode (the cause of the 2026-05-12 recurrence) is now blocked at CI by [tests/unit/lint/project-docs-add-coverage.test.ts](../../tests/unit/lint/project-docs-add-coverage.test.ts). The lint statically walks every `.ts` / `.tsx` file under `src/main/`, identifies every file that joins `.claude`, `docs` into a path constant, and partitions them into a `REQUIRES_HELPER` list (must call `appendNewDocsToOrder`) and a `WRITES_DOCS_SAFELY` allow-list (read-only / list / delete / rename / path-helper / snapshot sites, each with a one-line `reason:`). A new add path that's not in either list fails CI with a diagnostic that includes the canonical wiring pattern verbatim — so a future agent that adds a "import from Notion" tab can't ship without explicitly opting into the helper.

The sort itself is centralized in [applyDocOrder](../../src/main/services/project-docs-order.ts), called by all three read sites (sidebar listing, first-message inline injection, CLI listing) — so they cannot drift apart. Persistence is a JSON array of filenames on `projects.doc_order_json` (migration v134). Empty array = "no explicit order yet, fall back to mtime-DESC".

### User-visible indicator (chip on first message)

When a session sends its first message, Omniscio renders a small chip on that operator message showing exactly what Omniscio auto-attached for that session. The chip lives directly above the message body, in the same wrapper that pasted-text chips and image thumbnails use, so it sits with the message rather than floating elsewhere on screen.

- **Closed state.** A single line: `📎 N project docs applied at start · ~XK tokens` — with `+ M RAG available` appended when the project has files in the RAG bucket too. The token count rounds the snapshot's accumulated estimate (`~1K tokens`, `~12K tokens`); below 1,000 it falls back to `~Ntokens` so a tiny doc folder doesn't show as `~0K`. The RAG count is informational only — those bytes are NOT included in the token estimate (since they're not inlined). A project that uses ONLY the RAG bucket shows `0 project docs applied at start · ~0 tokens + M RAG available` so you still see the chip and the available count.
- **Click to expand.** Clicking the chip toggles an inline list of every doc in the snapshot, each row showing an icon (📦 ContextDock bundle / 📋 ContextDock list / 📄 plain hand-dropped doc), the filename (truncated with hover tooltip showing the full name), and a bucket label on the right (`applied` / `RAG available`). Clicking the chip a second time collapses the list. The list is bounded with `max-h-64` and scrolls if you have many docs.
- **Skipped-files sub-line.** When `skippedCount > 0` (the project ran out of injection budget), the chip shows an amber `⚠ N skipped (cap)` line directly under the closed-state row so you see immediately that not every doc made it into the snapshot, even when collapsed. RAG-bucket files cannot be "skipped" (they're uncapped) so they never trigger this line.

**Snapshot semantics.** The chip reflects what Omniscio saw in `.claude/docs/` **at the moment of the first message** for that session — which, because injection is also first-message-only, is exactly the moment the docs were folded into the prompt. Docs you add or remove after the session opens are NOT retroactively folded in and are NOT reflected in the chip — the chip is a record of what was injected, not a live mirror. If you want a fresh snapshot, start a new session.

**Inferred, not captured.** Omniscio builds the chip's snapshot via [buildProjectDocsSnapshot](../../src/main/services/project-docs-snapshot.ts), a sibling of the [buildProjectDocsContext](../../src/main/services/project-docs-context.ts) function that builds the actual injected block. Both are TypeScript, both enumerate the same `.claude/docs/` folder, and both read the single-source cap from [project-docs-caps.ts](../../src/main/services/project-docs-caps.ts) and the single-source text/binary classification (`TEXT_EXTENSIONS`) from [project-docs.ts](../../src/main/services/project-docs.ts) — so the chip and the injected content stay aligned by sharing those sources rather than by re-deriving the rules independently. The chip is still a separate enumeration from the literal injected string (it counts and labels rather than concatenating), so treat it as an accurate accounting of the snapshot rather than a byte-for-byte capture of the prompt.

**Scope (current).** The chip now fires on **every first-message SEND path** — Claude spawn (Quick Launch / CLI / recipe, via [session-create.ts](../../src/main/services/session/session-create.ts)), the typed `+New` first send, and all five external engines (OpenClaw / Codex / Pi / Gemini / one-shot) — because they all read `.claude/docs/` through the single [buildFirstMessageDocs](../../src/main/services/first-message-docs.ts) unit, which returns the inline text, the binary-attachment paths, and the chip snapshot together (so a path can't inject the docs while dropping the chip), and a single-source guard makes the chip impossible to build outside that unit. Two narrow cases still show no chip: **(a)** a programmatic _external_ spawn that arrives already carrying a prompt (CLI `/new`, deep-link, recipe → an external engine) persists its operator row inside the engine's own `launch`, where the snapshot isn't threaded yet (a tracked follow-up — interactive sends + all Claude Quick-Launch are covered); and **(b)** crash-recovery / rate-limit-recovery auto-replays deliberately do NOT re-stamp a chip — it is frozen at first-message time. Full invariants + the tracked gaps: [first-message-docs-contract.md](../../.claude/memory/contracts/first-message-docs-contract.md).

### Adding files by dragging them onto the section

The quickest path skips the modal entirely: drag one or more files from your OS file explorer (Finder / Explorer) and drop them **anywhere on the Auto Context section** — collapsed header or expanded body. Omniscio uploads them into the **always-inject** bucket, the section auto-expands so you watch them land, and a toast confirms the result. This is exactly what the empty-state hint — _"Drop files here to auto-attach them to every new session in this project"_ — refers to.

The drop reuses the same `FILES_ADD_PROJECT_DOC` path as the modal's Upload tab, so the same limits apply:

- **Up to `MAX_UPLOAD_FILES` (20) files per drop.** Drop more and the extras are skipped with a warning toast (`Skipped N — only 20 files per upload.`).
- **Per-file backend failures** (over the 50 MiB cap, name sanitization) surface in an error toast naming the file and reason — the files that did succeed still land.
- **A drop while a previous drop is still uploading is ignored** (re-entry guard) so two uploads can't interleave and scramble the doc list.
- The whole section tints with a dashed accent border while a file is dragged over it. A _misaimed_ drop on the surrounding sidebar does nothing — a window-level guard ([useWindowFileDropGuard](../../src/renderer/src/hooks/useWindowFileDropGuard.ts)) stops the renderer from navigating to the dropped `file://`.

Drag-and-drop always targets the **always-inject** bucket; for the **RAG** bucket, or the **Paste** / **Google Drive** / **ContextDock** sources, use the modal below.

### Collapsing the Auto Context section

Click the **Auto Context** header (its chevron) to fold or unfold the whole section; the choice is remembered per project across restarts. The section also folds and unfolds together with the session sections when you use the sessions sidebar's **Collapse-all / Expand-all** button (the double-chevron in the sidebar header) — one click tidies the entire sidebar, Auto Context included. Its smart auto-open on first visit is unaffected.

### Adding files via the in-app modal ("Add to Project Docs")

The **Add to Project Docs** modal adds to the same `.claude/docs/` folder with no Explorer round-trip, and unlocks the sources drag-and-drop can't: Paste, Google Drive import, the ContextDock picker, and the RAG-bucket choice. Open the project and expand the **Auto Context** panel, then click the **+** button on its **Always-inject** row (or use the project menu's **Add docs**).

Above the tab strip sits a `Where:` segmented control with two buttons — **Always-inject** (default) and **RAG (on-demand)** — plus an info-tooltip explaining the difference ("RAG docs aren't sent at the start — the agent fetches them on demand using its Read tool. Use for big reference material."). The selection applies to every file added in the current modal session, including drag-and-drop, paste, and Google Doc import. The toggle is hidden when you switch to the ContextDock tab (linked bundles/lists always land in the `always` bucket — they're the inlined reference material the ContextDock pipeline was designed for). The toggle does NOT migrate existing files between buckets — to move a file you'd delete it from one bucket and re-add it to the other.

The modal has three tabs. **Paste** is first and is the tab shown when the modal opens — pasting content is the most common way docs are added:

- **Paste** — opens as a single textarea block with no title field above it. The moment you type or paste any non-whitespace content, a **Title** input slides in above the textarea, pre-filled with the first non-empty line of your content (capped at 80 characters). The title keeps tracking the first line as you keep editing — until you click into the title field and type your own value, at which point your override sticks even when the textarea content changes. Clearing the title input back to empty resumes auto-derive; clearing the textarea entirely hides the title block again and wipes any override so a fresh paste starts in auto-derive mode. Saved as `<title>.md` (or an auto-generated name when no title is supplied) in `.claude/docs/`. The on-disk filename preserves the title's original capitalization and inter-word spaces — title `Humans Fundamental Concepts` saves as `Humans Fundamental Concepts.md` (NOT `humans-fundamental-concepts.md`); only filesystem-illegal characters (`/ \ : * ? < > | "` and control chars) are stripped, runs of whitespace collapse to a single space, and trailing dots/spaces are trimmed. The Add button shows a spinner while the IPC is in flight.
- **Upload** — drag files onto the drop zone or click to browse. Supports any of the binary or text formats the auto-injection pipeline understands; per-upload cap is the standard `MAX_UPLOAD_FILES` (excess are listed as failures with "Skipped — only N per upload"). While the upload is in flight the drop zone shows a spinning loader and "Uploading N file(s)…" so you know the import is working.
- **From Google Drive** — paste a Google Docs, Slides, or Sheets URL. Omniscio fetches it through the Drive API and writes the result into `.claude/docs/`: Docs are exported as markdown, Slides as PDF, Sheets as `.xlsx` (multi-sheet preserved — the auto-inject pipeline then runs the standard Office text-extract that gives every uploaded `.xlsx` a `<basename>.md` sidecar). This tab requires Google sign-in; if you're not connected the Import button is replaced by a **Connect Google** button. While the import is in flight (typically 5–15s — Drive API + format conversion + disk write) the Import button shows a spinner and an inline "Importing from Google Drive…" status line appears. Local edits that diverge from the last imported version raise a 3-button collision prompt (**Overwrite** / **Keep both** / **Cancel**) instead of silently clobbering your work.

Every successful add fires a toast — `Added "X" to project docs`, `Imported "Y" from Google Drive`, or `Added N files to project docs`. Every failure fires an error toast naming the reason (`Import failed: Drive API rate limit exceeded`, `Couldn't add note: Quota exceeded`, etc.). A partial upload (some files succeeded, some failed) fires both a success toast and a warning toast, with the per-file outcome list rendering inline below the tabs so you can see exactly which file failed and why.

The modal won't close while busy; if you have unsaved paste content or a typed Google Doc URL, closing or hitting **Cancel** prompts a "Discard changes?" confirm. After completion the modal stays open with the result list visible — close it manually when you're done.

## For agents

The machinery behind all of this is in [Auto Context (`.claude/docs/` auto-injection) (part 2)](project-docs-auto-injection-part-2.md): the builders and every per-engine first-message injection path, the injection budget and its single source of truth, the kill switch, the instruction-flag routing, the CLI Control endpoints, and why the RAG bucket deliberately ships no retrieval layer.

## Related

- [project-docs-selection.md](project-docs-selection.md) — multi-select mode + bulk copy/delete on the Auto Context sidebar panel (operates on the files this page injects).
- [contextdock.md](contextdock.md) — ContextDock bundles/lists land in `.claude/docs/` as regular `.md` files and ride this same first-message injection.
- [use-skills.md](use-skills.md) — Skills live in `~/.claude/skills/`; auto-docs live per-project in `<project>/.claude/docs/`. Different scope, different mechanism.
